Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
1 change: 1 addition & 0 deletions packages/cea/src/tools/execute/shell-execute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ export async function executeCommand(

export const shellExecuteTool = tool({
description: SHELL_EXECUTE_DESCRIPTION,
needsApproval: true,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Handle approval responses before enabling tool approvals

With needsApproval: true, AI SDK does not execute the tool on the first stream; it returns a tool-approval-request and requires the caller to append a tool-approval-response before calling the model again. The current render/stream paths ignore approval requests and never collect or append that response, so any shell_execute request now stops before running the command and leaves the conversation with an unresolved approval instead of a tool result. The same pattern applies to the other tools changed in this patch, which blocks the normal code-editing workflow until an approval UI/headless policy is wired in.

Useful? React with 👍 / 👎.


inputSchema: z.object({
command: z.string().describe("Shell command to execute"),
Expand Down
1 change: 1 addition & 0 deletions packages/cea/src/tools/execute/shell-interact.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ function hasCtrlC(parsedKeys: string[]): boolean {

export const shellInteractTool = tool({
description: SHELL_INTERACT_DESCRIPTION,
needsApproval: true,

inputSchema: z.object({
keystrokes: z
Expand Down
1 change: 1 addition & 0 deletions packages/cea/src/tools/modify/delete-file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ export async function executeDeleteFile(

export const deleteFileTool = tool({
description: DELETE_FILE_DESCRIPTION,
needsApproval: true,
inputSchema,
execute: (input) => executeDeleteFile(input),
});
1 change: 1 addition & 0 deletions packages/cea/src/tools/modify/edit-file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,7 @@ export async function executeEditFile(

export const editFileTool = tool({
description: EDIT_FILE_DESCRIPTION,
needsApproval: true,
inputSchema,
execute: (input) => executeEditFile(input),
});
1 change: 1 addition & 0 deletions packages/cea/src/tools/modify/write-file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ export async function executeWriteFile(

export const writeFileTool = tool({
description: WRITE_FILE_DESCRIPTION,
needsApproval: true,
inputSchema,
execute: (input) => executeWriteFile(input),
});
16 changes: 16 additions & 0 deletions packages/cea/src/tools/tool-approval.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { describe, expect, it } from "vitest";
import { shellExecuteTool } from "./execute/shell-execute";
import { shellInteractTool } from "./execute/shell-interact";
import { deleteFileTool } from "./modify/delete-file";
import { editFileTool } from "./modify/edit-file";
import { writeFileTool } from "./modify/write-file";

describe("high-risk tools", () => {
it("require explicit approval before execution", () => {
expect(shellExecuteTool.needsApproval).toBe(true);
expect(shellInteractTool.needsApproval).toBe(true);
expect(writeFileTool.needsApproval).toBe(true);
expect(editFileTool.needsApproval).toBe(true);
expect(deleteFileTool.needsApproval).toBe(true);
});
});