diff --git a/.changeset/approval-allow-cancel.md b/.changeset/approval-allow-cancel.md new file mode 100644 index 000000000..30de64ad4 --- /dev/null +++ b/.changeset/approval-allow-cancel.md @@ -0,0 +1,5 @@ +--- +"eve": minor +--- + +Tool approval responses now use `cancel` instead of `deny`, while retaining `approve` for the positive response, aligning the public protocol with the user-facing flow-control semantics. diff --git a/docs/concepts/sessions-runs-and-streaming.md b/docs/concepts/sessions-runs-and-streaming.md index 0859c5163..08cfba7a4 100644 --- a/docs/concepts/sessions-runs-and-streaming.md +++ b/docs/concepts/sessions-runs-and-streaming.md @@ -144,7 +144,7 @@ curl -X POST http://127.0.0.1:2000/eve/v1/session/ \ The follow-up reuses the same durable session: same history, same state. -If the session is waiting on a human-in-the-loop approval, a matching text reply such as `approve` or `deny` answers the approval. Other follow-up text is held until the approval is answered, so an unrelated message does not implicitly deny the pending tool call. +If the session is waiting on a human-in-the-loop approval, a matching text reply such as `approve` or `cancel` answers the approval. Other follow-up text is held until the approval is answered, so an unrelated message does not implicitly deny the pending tool call. If the session is waiting on `ask_question`, a follow-up message clears that pending request before the model continues. An exact option match or permitted freeform response answers the question; any other message marks the question unanswered and starts the follow-up turn. diff --git a/docs/guides/frontend/overview.mdx b/docs/guides/frontend/overview.mdx index 209339c20..9d02c62d9 100644 --- a/docs/guides/frontend/overview.mdx +++ b/docs/guides/frontend/overview.mdx @@ -123,7 +123,7 @@ if (request) { } ``` -`request.prompt` and `request.options` give you what you need to render the approve and deny UI. The default reducer marks the part as responded immediately, then updates it again once eve streams the resumed result. +`request.prompt` and `request.options` give you what you need to render the approve and cancel UI. The default reducer marks the part as responded immediately, then updates it again once eve streams the resumed result. ## Authorization prompts diff --git a/docs/tools/human-in-the-loop.md b/docs/tools/human-in-the-loop.md index 019be2bc4..8ab890bdc 100644 --- a/docs/tools/human-in-the-loop.md +++ b/docs/tools/human-in-the-loop.md @@ -100,7 +100,7 @@ Approvals and questions share one protocol: 1. The model requests input (an approval, or an `ask_question`). 2. eve emits an `input.requested` stream event carrying the pending requests. 3. The turn parks at `session.waiting`, durably, for as long as it takes. -4. The client answers with `inputResponses` (structured, keyed by `requestId`) or a normal follow-up `message`. A follow-up whose text matches an option ID, option label, or numeric option index resolves automatically, including approval options such as `approve` and `deny`. +4. The client answers with `inputResponses` (structured, keyed by `requestId`) or a normal follow-up `message`. A follow-up whose text matches an option ID, option label, or numeric option index resolves automatically, including approval options such as `approve` and `cancel`. Each request includes a `kind` discriminator: `tool-approval`, `question`, or `session-limit`. Clients should use `kind` to choose behavior and presentation; diff --git a/docs/tutorial/ship-it.mdx b/docs/tutorial/ship-it.mdx index 6f6fd36a9..eb0a50782 100644 --- a/docs/tutorial/ship-it.mdx +++ b/docs/tutorial/ship-it.mdx @@ -73,7 +73,7 @@ export default function Page() { } ``` -`agent.data.messages` and `agent.status` cover most chat UIs. The hook also surfaces HITL prompts (the spend approval from [Step 8](./guard-the-spend)), so the dashboard can render approve/deny controls. For the full API, see [Frontend](../guides/frontend/overview). +`agent.data.messages` and `agent.status` cover most chat UIs. The hook also surfaces HITL prompts (the spend approval from [Step 8](./guard-the-spend)), so the dashboard can render approve/cancel controls. For the full API, see [Frontend](../guides/frontend/overview). ## Replace `placeholderAuth` diff --git a/e2e/fixtures/agent-openapi-swagger/evals/tfl-swagger-approval.eval.ts b/e2e/fixtures/agent-openapi-swagger/evals/tfl-swagger-approval.eval.ts index 07991fcd0..2527cd89a 100644 --- a/e2e/fixtures/agent-openapi-swagger/evals/tfl-swagger-approval.eval.ts +++ b/e2e/fixtures/agent-openapi-swagger/evals/tfl-swagger-approval.eval.ts @@ -21,7 +21,7 @@ export default defineEval({ t.requireInputRequest({ display: "confirmation", - optionIds: ["approve", "deny"], + optionIds: ["approve", "cancel"], toolName: TFL_APPROVAL_JOURNEY_MODES_TOOL, }); parked.calledTool(TFL_APPROVAL_JOURNEY_MODES_TOOL, { status: "pending", count: 1 }); diff --git a/e2e/fixtures/agent-tools-hitl/evals/hitl/deny-then-regate.eval.ts b/e2e/fixtures/agent-tools-hitl/evals/hitl/deny-then-regate.eval.ts index 9db60b964..8980f210e 100644 --- a/e2e/fixtures/agent-tools-hitl/evals/hitl/deny-then-regate.eval.ts +++ b/e2e/fixtures/agent-tools-hitl/evals/hitl/deny-then-regate.eval.ts @@ -12,7 +12,7 @@ export default defineEval({ await t.send('Call the guarded-echo tool with note "denied-call".'); const request = t.requireInputRequest({ toolName: "guarded-echo" }); - const denied = await t.respondAll("deny"); + const denied = await t.respondAll("cancel"); denied.expectOk(); denied.event("action.result", { data: { diff --git a/packages/eve/src/channel/resolve-text.test.ts b/packages/eve/src/channel/resolve-text.test.ts index 2f836ebf8..49fef8370 100644 --- a/packages/eve/src/channel/resolve-text.test.ts +++ b/packages/eve/src/channel/resolve-text.test.ts @@ -9,7 +9,7 @@ const APPROVAL_REQUEST: InputRequest = { kind: "tool-approval", options: [ { id: "approve", label: "Approve", style: "primary" }, - { id: "deny", label: "Deny", style: "danger" }, + { id: "cancel", label: "Cancel", style: "danger" }, ], prompt: 'Approve tool "bash"?', requestId: "req-1", diff --git a/packages/eve/src/cli/dev/tui/runner.test.ts b/packages/eve/src/cli/dev/tui/runner.test.ts index a9e18debf..661e9adc7 100644 --- a/packages/eve/src/cli/dev/tui/runner.test.ts +++ b/packages/eve/src/cli/dev/tui/runner.test.ts @@ -928,7 +928,7 @@ describe("EveTUIRunner native continuation state", () => { kind: "tool-approval", options: [ { id: "approve", label: "Approve" }, - { id: "deny", label: "Deny" }, + { id: "cancel", label: "Cancel" }, ], prompt: "Approve get_weather?", requestId: "request-1", diff --git a/packages/eve/src/cli/dev/tui/runner.ts b/packages/eve/src/cli/dev/tui/runner.ts index 70281a0d1..8c90b0459 100644 --- a/packages/eve/src/cli/dev/tui/runner.ts +++ b/packages/eve/src/cli/dev/tui/runner.ts @@ -874,7 +874,7 @@ export class EveTUIRunner { const response = await this.#renderer.readToolApproval(request, { title }); responses.push({ requestId: request.approvalId, - optionId: response.approved ? "approve" : "deny", + optionId: response.approved ? "approve" : "cancel", }); this.#pendingInputRequests.delete(request.approvalId); } diff --git a/packages/eve/src/client/message-reducer.test.ts b/packages/eve/src/client/message-reducer.test.ts index fe0886a1c..f8131f9b0 100644 --- a/packages/eve/src/client/message-reducer.test.ts +++ b/packages/eve/src/client/message-reducer.test.ts @@ -371,7 +371,7 @@ describe("defaultMessageReducer", () => { kind: "tool-approval", options: [ { id: "approve", label: "Yes", style: "primary" }, - { id: "deny", label: "No", style: "danger" }, + { id: "cancel", label: "No", style: "danger" }, ], prompt: "Approve tool call: bash", requestId: "approval_1", @@ -408,7 +408,7 @@ describe("defaultMessageReducer", () => { kind: "tool-approval", options: [ { id: "approve", label: "Yes", style: "primary" }, - { id: "deny", label: "No", style: "danger" }, + { id: "cancel", label: "No", style: "danger" }, ], prompt: "Approve tool call: bash", requestId: "approval_1", @@ -442,7 +442,7 @@ describe("defaultMessageReducer", () => { kind: "tool-approval", options: [ { id: "approve", label: "Yes", style: "primary" }, - { id: "deny", label: "No", style: "danger" }, + { id: "cancel", label: "No", style: "danger" }, ], prompt: "Approve tool call: bash", requestId: "approval_1", @@ -457,7 +457,7 @@ describe("defaultMessageReducer", () => { data = reducer.reduce(data, { data: { createdAt: 1, - responses: [{ optionId: "deny", requestId: "approval_1" }], + responses: [{ optionId: "cancel", requestId: "approval_1" }], }, type: "client.input.responded", }); @@ -487,12 +487,12 @@ describe("defaultMessageReducer", () => { kind: "tool-approval", options: [ { id: "approve", label: "Yes", style: "primary" }, - { id: "deny", label: "No", style: "danger" }, + { id: "cancel", label: "No", style: "danger" }, ], prompt: "Approve tool call: bash", requestId: "approval_1", }, - inputResponse: { optionId: "deny", requestId: "approval_1" }, + inputResponse: { optionId: "cancel", requestId: "approval_1" }, kind: "tool-call", name: "bash", }, @@ -522,7 +522,7 @@ describe("defaultMessageReducer", () => { kind: "tool-approval", options: [ { id: "approve", label: "Yes", style: "primary" }, - { id: "deny", label: "No", style: "danger" }, + { id: "cancel", label: "No", style: "danger" }, ], prompt: "Approve tool call: bash", requestId: "approval_1", diff --git a/packages/eve/src/evals/runner/execute-task.test.ts b/packages/eve/src/evals/runner/execute-task.test.ts index 15b1dc3a9..35adbd727 100644 --- a/packages/eve/src/evals/runner/execute-task.test.ts +++ b/packages/eve/src/evals/runner/execute-task.test.ts @@ -82,7 +82,7 @@ describe("executeTask", () => { const request = t.requireInputRequest({ display: "confirmation", input: { command: "pwd" }, - optionIds: ["approve", "deny"], + optionIds: ["approve", "cancel"], prompt: /Approve/, toolName: "bash", }); @@ -722,7 +722,7 @@ function inputRequested( kind: "tool-approval", options: [ { id: "approve", label: "Approve" }, - { id: "deny", label: "Deny" }, + { id: "cancel", label: "Cancel" }, ], prompt: "Approve?", requestId, diff --git a/packages/eve/src/execution/subagent-adapter.test.ts b/packages/eve/src/execution/subagent-adapter.test.ts index 7aea8f7b9..00483a4a1 100644 --- a/packages/eve/src/execution/subagent-adapter.test.ts +++ b/packages/eve/src/execution/subagent-adapter.test.ts @@ -56,7 +56,7 @@ function sampleRequest(): InputRequest { kind: "tool-approval", options: [ { id: "approve", label: "Approve" }, - { id: "deny", label: "Deny" }, + { id: "cancel", label: "Cancel" }, ], prompt: "Approve?", requestId: "req-1", diff --git a/packages/eve/src/execution/subagent-hitl-proxy.integration.test.ts b/packages/eve/src/execution/subagent-hitl-proxy.integration.test.ts index 4ad5e9d50..bedae319b 100644 --- a/packages/eve/src/execution/subagent-hitl-proxy.integration.test.ts +++ b/packages/eve/src/execution/subagent-hitl-proxy.integration.test.ts @@ -143,7 +143,7 @@ function buildApprovalRequest(requestId: string): InputRequest { kind: "tool-approval", options: [ { id: "approve", label: "Approve", style: "primary" }, - { id: "deny", label: "Deny", style: "danger" }, + { id: "cancel", label: "Cancel", style: "danger" }, ], prompt: "Approve?", requestId, @@ -430,7 +430,7 @@ describe("subagent HITL proxy → concurrent-descendant routing", () => { payload: { inputResponses: [ { optionId: "approve", requestId: "req-a" }, - { optionId: "deny", requestId: "req-b" }, + { optionId: "cancel", requestId: "req-b" }, ], }, state: parkedSession.state, @@ -449,7 +449,7 @@ describe("subagent HITL proxy → concurrent-descendant routing", () => { inputResponses: [{ optionId: "approve", requestId: "req-a" }], }); expect(byChild.get("subagent:parent:call-b")).toEqual({ - inputResponses: [{ optionId: "deny", requestId: "req-b" }], + inputResponses: [{ optionId: "cancel", requestId: "req-b" }], }); // A response whose requestId does not match any proxy entry diff --git a/packages/eve/src/execution/subagent-hitl-proxy.test.ts b/packages/eve/src/execution/subagent-hitl-proxy.test.ts index c6af68016..72eff5413 100644 --- a/packages/eve/src/execution/subagent-hitl-proxy.test.ts +++ b/packages/eve/src/execution/subagent-hitl-proxy.test.ts @@ -35,7 +35,7 @@ describe("routeDeliverPayload", () => { payload: { inputResponses: [ { optionId: "approve", requestId: "req-a" }, - { optionId: "deny", requestId: "req-b" }, + { optionId: "cancel", requestId: "req-b" }, { optionId: "ignore", requestId: "req-parent" }, ], }, @@ -46,7 +46,7 @@ describe("routeDeliverPayload", () => { const childA = routed.forChildren.find((c) => c.childContinuationToken === "child-a"); const childB = routed.forChildren.find((c) => c.childContinuationToken === "child-b"); expect(childA?.payload.inputResponses).toEqual([{ optionId: "approve", requestId: "req-a" }]); - expect(childB?.payload.inputResponses).toEqual([{ optionId: "deny", requestId: "req-b" }]); + expect(childB?.payload.inputResponses).toEqual([{ optionId: "cancel", requestId: "req-b" }]); expect(routed.forSelf?.inputResponses).toEqual([ { optionId: "ignore", requestId: "req-parent" }, diff --git a/packages/eve/src/execution/workflow-steps.test.ts b/packages/eve/src/execution/workflow-steps.test.ts index d51c084e3..ab471dea0 100644 --- a/packages/eve/src/execution/workflow-steps.test.ts +++ b/packages/eve/src/execution/workflow-steps.test.ts @@ -1516,7 +1516,7 @@ describe("runProxySubagentEventStep", () => { kind: "tool-approval", options: [ { id: "approve", label: "Approve" }, - { id: "deny", label: "Deny" }, + { id: "cancel", label: "Cancel" }, ], prompt: "Approve?", requestId: "req-1", diff --git a/packages/eve/src/harness/input-extraction.test.ts b/packages/eve/src/harness/input-extraction.test.ts index 8c745d90b..2714aab76 100644 --- a/packages/eve/src/harness/input-extraction.test.ts +++ b/packages/eve/src/harness/input-extraction.test.ts @@ -12,7 +12,7 @@ describe("extractQuestionInputRequests", () => { toolCalls: [ { input: { - options: [{ id: "yes", label: "Yes" }], + options: [{ id: "yes", label: "Approve" }], prompt: "Continue?", }, toolCallId: "call-1", @@ -27,7 +27,7 @@ describe("extractQuestionInputRequests", () => { action: { callId: "call-1", input: { - options: [{ id: "yes", label: "Yes" }], + options: [{ id: "yes", label: "Approve" }], prompt: "Continue?", }, kind: "tool-call", @@ -120,8 +120,8 @@ describe("extractToolApprovalInputRequests", () => { display: "confirmation", kind: "tool-approval", options: [ - { id: "approve", label: "Yes" }, - { id: "deny", label: "No" }, + { id: "approve", label: "Approve" }, + { id: "cancel", label: "Cancel" }, ], prompt: "Approve tool call: bash", requestId: "approval-1", @@ -158,8 +158,8 @@ describe("extractToolApprovalInputRequests", () => { display: "confirmation", kind: "tool-approval", options: [ - { id: "approve", label: "Yes" }, - { id: "deny", label: "No" }, + { id: "approve", label: "Approve" }, + { id: "cancel", label: "Cancel" }, ], prompt: "Approve tool call: bash", requestId: "approval-1", diff --git a/packages/eve/src/harness/input-extraction.ts b/packages/eve/src/harness/input-extraction.ts index d0e68cb7a..2bdc48a6a 100644 --- a/packages/eve/src/harness/input-extraction.ts +++ b/packages/eve/src/harness/input-extraction.ts @@ -160,8 +160,8 @@ function extractApprovalRequests(input: { display: "confirmation", kind: "tool-approval", options: [ - { id: "approve", label: "Yes" }, - { id: "deny", label: "No" }, + { id: "approve", label: "Approve" }, + { id: "cancel", label: "Cancel" }, ], prompt: `Approve tool call: ${toolCall.toolName}`, requestId: approval.approvalId, diff --git a/packages/eve/src/harness/input-requests.test.ts b/packages/eve/src/harness/input-requests.test.ts index 7d59002ba..d4a36c44f 100644 --- a/packages/eve/src/harness/input-requests.test.ts +++ b/packages/eve/src/harness/input-requests.test.ts @@ -145,7 +145,7 @@ describe("resolvePendingInput", () => { kind: "tool-approval", options: [ { id: "approve", label: "Yes" }, - { id: "deny", label: "No" }, + { id: "cancel", label: "No" }, ], prompt: "Approve tool call: bash", requestId: "approval-1", @@ -271,7 +271,7 @@ describe("resolvePendingInput", () => { kind: "tool-approval", options: [ { id: "approve", label: "Yes" }, - { id: "deny", label: "No" }, + { id: "cancel", label: "No" }, ], prompt: "Approve tool call: bash", requestId: "approval-1", @@ -301,7 +301,7 @@ describe("resolvePendingInput", () => { // Deliver an approval response AND a message simultaneously. const result = resolvePendingInput({ stepInput: { - inputResponses: [{ requestId: "approval-1", optionId: "deny" }], + inputResponses: [{ requestId: "approval-1", optionId: "cancel" }], message: "Ignore that and say hi instead.", }, session, @@ -339,7 +339,7 @@ describe("resolvePendingInput", () => { kind: "tool-approval", options: [ { id: "approve", label: "Yes" }, - { id: "deny", label: "No" }, + { id: "cancel", label: "No" }, ], prompt: "Approve tool call: bash", requestId: "approval-1", @@ -399,7 +399,7 @@ describe("resolvePendingInput", () => { kind: "tool-approval", options: [ { id: "approve", label: "Yes" }, - { id: "deny", label: "No" }, + { id: "cancel", label: "No" }, ], prompt: "Approve tool call: bash", requestId: "approval-1", @@ -464,7 +464,7 @@ describe("resolvePendingInput", () => { kind: "tool-approval", options: [ { id: "approve", label: "Yes" }, - { id: "deny", label: "No" }, + { id: "cancel", label: "No" }, ], prompt: "Approve tool call: vercel__list_projects", requestId: "approval-1", @@ -531,7 +531,7 @@ describe("resolvePendingInput", () => { kind: "tool-approval", options: [ { id: "approve", label: "Yes" }, - { id: "deny", label: "No" }, + { id: "cancel", label: "No" }, ], prompt: "Approve tool call: bash", requestId: "approval-1", @@ -560,7 +560,7 @@ describe("resolvePendingInput", () => { const result = resolvePendingInput({ stepInput: { - inputResponses: [{ requestId: "approval-1", optionId: "deny" }], + inputResponses: [{ requestId: "approval-1", optionId: "cancel" }], }, session, }); @@ -601,7 +601,7 @@ describe("resolvePendingInput", () => { kind: "tool-approval", options: [ { id: "approve", label: "Yes" }, - { id: "deny", label: "No" }, + { id: "cancel", label: "No" }, ], prompt: "Approve tool call: bash", requestId: "approval-1", @@ -613,7 +613,7 @@ describe("resolvePendingInput", () => { const result = resolvePendingInput({ stepInput: { - inputResponses: [{ requestId: "approval-1", optionId: "deny" }], + inputResponses: [{ requestId: "approval-1", optionId: "cancel" }], }, session, }); @@ -659,7 +659,7 @@ describe("resolvePendingInput", () => { kind: "tool-approval", options: [ { id: "approve", label: "Yes" }, - { id: "deny", label: "No" }, + { id: "cancel", label: "No" }, ], prompt: "Approve tool call: bash", requestId: "approval-1", @@ -696,7 +696,7 @@ describe("resolvePendingInput", () => { kind: "tool-approval", options: [ { id: "approve", label: "Yes" }, - { id: "deny", label: "No" }, + { id: "cancel", label: "No" }, ], prompt: "Approve tool call: bash", requestId: "approval-1", @@ -737,7 +737,7 @@ describe("resolvePendingInput", () => { kind: "tool-approval", options: [ { id: "approve", label: "Yes" }, - { id: "deny", label: "No" }, + { id: "cancel", label: "No" }, ], prompt: "Approve tool call: bash", requestId: "approval-1", @@ -797,7 +797,7 @@ describe("resolvePendingInput", () => { kind: "tool-approval", options: [ { id: "approve", label: "Yes" }, - { id: "deny", label: "No" }, + { id: "cancel", label: "No" }, ], prompt: "Approve tool call: linear_whoami", requestId: "approval-1", diff --git a/packages/eve/src/harness/input-requests.ts b/packages/eve/src/harness/input-requests.ts index d9a61541b..786b8ec44 100644 --- a/packages/eve/src/harness/input-requests.ts +++ b/packages/eve/src/harness/input-requests.ts @@ -530,7 +530,7 @@ function resolveApprovalOutcome(response: InputResponse | undefined): { }; } - if (response.optionId === "deny") { + if (response.optionId === "cancel") { return { approved: false, reason: TOOL_EXECUTION_DENIED_MESSAGE, @@ -629,7 +629,7 @@ function buildToolResponsePartsForRequest( }, ]; /* - * On denial (explicit "deny" or auto-deny when the user continues + * On denial (explicit "cancel" or auto-deny when the user continues * without responding), splice in the matching `execution-denied` * tool-result. AI SDK's `streamText` synthesizes this for the * current turn's `initialResponseMessages`, but that synthesis is diff --git a/packages/eve/src/harness/stale-input-responses.test.ts b/packages/eve/src/harness/stale-input-responses.test.ts index b0575e568..c51829025 100644 --- a/packages/eve/src/harness/stale-input-responses.test.ts +++ b/packages/eve/src/harness/stale-input-responses.test.ts @@ -61,10 +61,10 @@ it("converts a stale approval into a non-authorizing user message", () => { throw new Error("Expected the stale response to be converted."); } - expect(result.displayMessage).toBe("Yes"); + expect(result.displayMessage).toBe("Approve"); expect(result.stepInput.inputResponses).toBeUndefined(); expect(result.stepInput.message).toEqual(expect.stringContaining("Approve tool call: bash")); - expect(result.stepInput.message).toEqual(expect.stringContaining('"label": "Yes"')); + expect(result.stepInput.message).toEqual(expect.stringContaining('"label": "Approve"')); expect(result.stepInput.message).toEqual( expect.stringContaining("This does not authorize an earlier action"), ); diff --git a/packages/eve/src/harness/tool-loop-generate-approval-resume.integration.test.ts b/packages/eve/src/harness/tool-loop-generate-approval-resume.integration.test.ts index 7fa1ba4d3..325a9ae52 100644 --- a/packages/eve/src/harness/tool-loop-generate-approval-resume.integration.test.ts +++ b/packages/eve/src/harness/tool-loop-generate-approval-resume.integration.test.ts @@ -66,7 +66,7 @@ function createPendingApprovalSession(): HarnessSession { kind: "tool-approval", options: [ { id: "approve", label: "Yes" }, - { id: "deny", label: "No" }, + { id: "cancel", label: "No" }, ], prompt: "Approve tool call: bash", requestId: approvalRequest.approvalId, diff --git a/packages/eve/src/harness/tool-loop.test.ts b/packages/eve/src/harness/tool-loop.test.ts index 13a20284d..1c971d54c 100644 --- a/packages/eve/src/harness/tool-loop.test.ts +++ b/packages/eve/src/harness/tool-loop.test.ts @@ -443,8 +443,8 @@ function createPendingBashApprovalSession(): HarnessSession { display: "confirmation", kind: "tool-approval", options: [ - { id: "approve", label: "Yes" }, - { id: "deny", label: "No" }, + { id: "approve", label: "Approve" }, + { id: "cancel", label: "Cancel" }, ], prompt: "Approve tool call: bash", requestId: "approval-1", @@ -494,8 +494,8 @@ function createPendingProtectedActionApprovalSession(): HarnessSession { display: "confirmation", kind: "tool-approval", options: [ - { id: "approve", label: "Yes" }, - { id: "deny", label: "No" }, + { id: "approve", label: "Approve" }, + { id: "cancel", label: "Cancel" }, ], prompt: "Approve tool call: protected_action", requestId: "approval-1", @@ -2337,8 +2337,8 @@ describe("createToolLoopHarness", () => { display: "confirmation", kind: "tool-approval", options: [ - { id: "approve", label: "Yes" }, - { id: "deny", label: "No" }, + { id: "approve", label: "Approve" }, + { id: "cancel", label: "Cancel" }, ], prompt: "Approve tool call: bash", requestId: "approval-1", @@ -6523,8 +6523,8 @@ describe("createToolLoopHarness", () => { display: "confirmation", kind: "tool-approval", options: [ - { id: "approve", label: "Yes" }, - { id: "deny", label: "No" }, + { id: "approve", label: "Approve" }, + { id: "cancel", label: "Cancel" }, ], prompt: "Approve tool call: bash", requestId: "approval-1", @@ -6711,8 +6711,8 @@ describe("createToolLoopHarness", () => { display: "confirmation", kind: "tool-approval", options: [ - { id: "approve", label: "Yes" }, - { id: "deny", label: "No" }, + { id: "approve", label: "Approve" }, + { id: "cancel", label: "Cancel" }, ], prompt: "Approve tool call: bash", requestId: "approval-1", @@ -6769,7 +6769,7 @@ describe("createToolLoopHarness", () => { expect(hasDeferredStepInput(firstResult.session)).toBe(true); const deniedResult = await createToolLoopHarness(config)(firstResult.session, { - inputResponses: [{ requestId: "approval-1", optionId: "deny" }], + inputResponses: [{ requestId: "approval-1", optionId: "cancel" }], }); expect(typeof deniedResult.next).toBe("function"); @@ -6876,8 +6876,8 @@ describe("createToolLoopHarness", () => { display: "confirmation", kind: "tool-approval", options: [ - { id: "approve", label: "Yes" }, - { id: "deny", label: "No" }, + { id: "approve", label: "Approve" }, + { id: "cancel", label: "Cancel" }, ], prompt: "Approve tool call: guarded_echo", requestId: "approval-1", @@ -7124,8 +7124,8 @@ describe("createToolLoopHarness", () => { display: "confirmation", kind: "tool-approval", options: [ - { id: "approve", label: "Yes" }, - { id: "deny", label: "No" }, + { id: "approve", label: "Approve" }, + { id: "cancel", label: "Cancel" }, ], prompt: "Approve tool call: bash", requestId: "approval-1", @@ -7184,7 +7184,7 @@ describe("createToolLoopHarness", () => { // Step 2: user denies the approval; the deferred message is NOT in this call. const deniedResult = await createToolLoopHarness(config)(firstResult.session, { - inputResponses: [{ requestId: "approval-1", optionId: "deny" }], + inputResponses: [{ requestId: "approval-1", optionId: "cancel" }], }); expect(typeof deniedResult.next).toBe("function"); const step2Last = generateCalls[0]?.at(-1); diff --git a/packages/eve/src/public/channels/chat-sdk/chatSdkChannel.test.ts b/packages/eve/src/public/channels/chat-sdk/chatSdkChannel.test.ts index ef4aaf71e..8c1e843a4 100644 --- a/packages/eve/src/public/channels/chat-sdk/chatSdkChannel.test.ts +++ b/packages/eve/src/public/channels/chat-sdk/chatSdkChannel.test.ts @@ -507,7 +507,7 @@ describe("chatSdkChannel", () => { display: "confirmation", options: [ { id: "approve", label: "Approve", style: "primary" }, - { id: "deny", label: "Deny", style: "danger" }, + { id: "cancel", label: "Cancel", style: "danger" }, ], prompt: "Deploy?", requestId: "request-1", @@ -534,11 +534,11 @@ describe("chatSdkChannel", () => { value: "approve", }, { - id: "eve_input:request-1:deny", - label: "Deny", + id: "eve_input:request-1:cancel", + label: "Cancel", style: "danger", type: "button", - value: "deny", + value: "cancel", }, ], type: "actions", diff --git a/packages/eve/src/public/channels/discord/hitl.test.ts b/packages/eve/src/public/channels/discord/hitl.test.ts index 37becc273..74e51974d 100644 --- a/packages/eve/src/public/channels/discord/hitl.test.ts +++ b/packages/eve/src/public/channels/discord/hitl.test.ts @@ -43,7 +43,7 @@ describe("renderInputRequestComponents", () => { display: "confirmation", options: [ { id: "approve", label: "Approve", style: "primary" }, - { id: "deny", label: "Deny", style: "danger" }, + { id: "cancel", label: "Cancel", style: "danger" }, ], }), ); diff --git a/packages/eve/src/public/channels/eve.test.ts b/packages/eve/src/public/channels/eve.test.ts index 909fcf753..9beffca28 100644 --- a/packages/eve/src/public/channels/eve.test.ts +++ b/packages/eve/src/public/channels/eve.test.ts @@ -642,7 +642,7 @@ describe("eveChannel — onMessage", () => { const response = await handler.fetch( createJsonMessageRequest({ continuationToken: "http:existing", - inputResponses: [{ requestId: "req-1", optionId: "deny" }], + inputResponses: [{ requestId: "req-1", optionId: "cancel" }], }), ); @@ -1284,7 +1284,7 @@ describe("eveChannel — continue session HITL (inputResponses)", () => { const response = await handler.fetch( createJsonMessageRequest({ continuationToken: "http:existing", - inputResponses: [{ requestId: "req-1", optionId: "deny" }], + inputResponses: [{ requestId: "req-1", optionId: "cancel" }], }), ); @@ -1292,7 +1292,7 @@ describe("eveChannel — continue session HITL (inputResponses)", () => { expect(handler.send).toHaveBeenCalledTimes(1); const payload = handler.send.mock.calls[0]?.[0] as SendPayload; expect(payload.message).toBeUndefined(); - expect(payload.inputResponses).toEqual([{ requestId: "req-1", optionId: "deny" }]); + expect(payload.inputResponses).toEqual([{ requestId: "req-1", optionId: "cancel" }]); }); }); diff --git a/packages/eve/src/public/channels/linear/hitl.test.ts b/packages/eve/src/public/channels/linear/hitl.test.ts index 074b98d1f..8c7e0d84a 100644 --- a/packages/eve/src/public/channels/linear/hitl.test.ts +++ b/packages/eve/src/public/channels/linear/hitl.test.ts @@ -22,14 +22,14 @@ describe("Linear HITL helpers", () => { makeRequest({ options: [ { id: "approve", label: "Approve" }, - { id: "deny", label: "Deny", description: "Stop the deployment" }, + { id: "cancel", label: "Cancel", description: "Stop the deployment" }, ], }), ]); expect(rendered).toContain("Approve deployment?"); expect(rendered).toContain("1. Approve"); - expect(rendered).toContain("2. Deny - Stop the deployment"); + expect(rendered).toContain("2. Cancel - Stop the deployment"); expect(rendered).not.toContain("eve-input"); expect(rendered).not.toContain("