Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/auto-approval-allow-deny.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@roomote/web": patch
---

Auto mode for integration tool approvals now runs routine calls automatically and asks before anything risky when the session owner is present. If the owner is away, the call is blocked with a tool error and recorded as an automatic rejection; unavailable checks follow the same present-to-ask, absent-to-block behavior. Chat-originated sessions are treated as present because their approval card is linked from the conversation.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ import {
} from '@/components/system';
import {
MCP_INTEGRATIONS,
type IntegrationToolApprovalMetadata,
type IntegrationToolAutoEvaluation,
type IntegrationToolApprovalMetadata,
} from '@roomote/types';

const integrationNames = new Map(
Expand Down Expand Up @@ -65,19 +65,15 @@ function approvalPrompt(item: IntegrationToolApprovalMetadata): string {
return `Let ${name} use this tool?`;
}

/**
* One line on what Auto made of the call, so the person deciding knows
* why they are being asked. Auto never rejects, so this only ever explains
* why it did not run the call on its own.
*/
/** Explain why Auto handed a call to the Session owner. */
function describeAutoEvaluation(
evaluation: IntegrationToolAutoEvaluation,
): string {
if (evaluation.unavailable === 'no_model') {
return 'Auto couldn’t check this call because no decision model is available.';
return "Auto couldn't check this call because an automatic check wasn't available, so it asked you.";
}
if (evaluation.unavailable === 'error') {
return 'Auto couldn’t check this call.';
return "Auto couldn't check this call, so it asked you.";
}
return evaluation.recommendation === 'approve'
? 'Auto would have run this call.'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,16 @@ export function IntegrationToolApprovalsExperimentalSetting() {
tools dialog in Settings → Integrations offers Auto (default, shown
with no choice selected), Always allow, Always ask, and Disable per
tool. Set up Auto mode in Settings → Integrations to handle routine
work automatically and ask before anything risky. Always ask pauses
each call until the session owner allows it once, stops the asks for
the rest of that session, or declines it; Disable hides the tool and
blocks it outright. A task asks the owner of its session the same way,
and a task nobody can answer for, such as one an automation started,
cannot run an Always ask tool. Session owners can also ask to be asked
about any tool from its call in the transcript. Tools left on Auto
with Auto mode off run exactly as before. Policies are deployment-wide
and apply from the next session turn.
work automatically and ask before anything risky. If the session owner
is away, risky calls are blocked. Always ask pauses each call until
the session owner allows it once, stops the asks for the rest of that
session, or declines it; Disable hides the tool and blocks it
outright. A task asks the owner of its session the same way, and a
task nobody can answer for, such as one an automation started, cannot
run an Always ask tool. Session owners can also ask to be asked about
any tool from its call in the transcript. Tools left on Auto with Auto
mode off run exactly as before. Policies are deployment-wide and apply
from the next session turn.
</p>
</div>
</Section>
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ import {
/** Customer-facing copy: what Auto mode does for the person, no mechanics. */
const COPY = {
description:
'Let Roomote handle routine work and ask before anything risky. Your other tool choices stay the same.',
"Let Roomote handle routine work and ask before anything risky. When you're away, risky calls are blocked. Your other tool choices stay the same.",
off: 'Keep each tool’s current choice.',
on: 'Handle routine work automatically and ask before anything risky.',
on: "Handle routine work automatically and ask before anything risky. Risky calls are blocked when you're away.",
disclosure: 'Additional instructions',
guidanceLabel: 'Additional instructions',
guidanceHelp:
Expand All @@ -45,8 +45,8 @@ const MODES: { mode: IntegrationToolAutoMode; label: string; hint: string }[] =

/**
* Deployment-wide Auto mode for tool approvals. Rendered on the
* Integrations page, only while the experiment is on. Reject is never affected, and the model can only ever run a call
* or ask; it never rejects one.
* Integrations page, only while the experiment is on. Reject is never
* affected, and Auto only runs routine calls; it asks about anything risky.
*/
export function IntegrationToolAutoModeSetting() {
const trpc = useTRPC();
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,14 @@ export function createTaskToolApprovalRelay(options: {
await reply(ask, 'once');
return;
}
if (result.outcome === 'denied') {
await reply(
ask,
'reject',
`Auto mode blocked this tool call because ${result.reason} and the session owner was away. The call was not run. The session owner can allow this tool from its call in the transcript.`,
);
return;
}
if (result.outcome === 'unavailable') {
await reply(
ask,
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading