-
Notifications
You must be signed in to change notification settings - Fork 62
Open
Labels
enhancementNew feature or requestNew feature or request
Milestone
Description
Summary
Add a confirmation mechanism so the Chat UI can ask the user for permission before the agent executes potentially dangerous tools (e.g., run_shell_command). The user should see the exact command, and can choose Allow, Deny, or Always Allow.
Motivation
Currently, when a user asks the agent a question like "what files are in this folder?", the agent calls run_shell_command with no user visibility or consent. This is a safety gap — shell commands can have side effects and users should be aware of what's running on their machine.
Design
Agent Framework (src/gaia/agents/base/)
-
OutputHandlerbase class — Add a new method:def confirm_tool_execution(self, tool_name: str, tool_args: dict) -> bool: """Request confirmation before executing a tool. Returns True to proceed.""" return True # Default: auto-approve (backward compatible)
-
agent.py— Before_execute_tool(), check if the tool requires confirmation:TOOLS_REQUIRING_CONFIRMATION = {"run_shell_command"} if tool_name in TOOLS_REQUIRING_CONFIRMATION: approved = self.console.confirm_tool_execution(tool_name, tool_args) if not approved: tool_result = {"status": "denied", "error": "User denied execution"} # skip _execute_tool, continue to next step
-
AgentConsole(CLI) — Could prompt in terminal or auto-approve.
SSE Handler (src/gaia/chat/ui/sse_handler.py)
SSEOutputHandler.confirm_tool_execution()— Emits atool_confirmevent and blocks on athreading.Event:def confirm_tool_execution(self, tool_name, tool_args): confirm_id = str(uuid4()) self._confirm_event = threading.Event() self._confirm_result = None self._emit({ "type": "tool_confirm", "confirm_id": confirm_id, "tool": tool_name, "args": tool_args, "command": tool_args.get("command", ""), }) self._confirm_event.wait(timeout=60) # 60s timeout return self._confirm_result == "allow"
Server (src/gaia/chat/ui/server.py)
POST /api/chat/confirmendpoint:@app.post("/api/chat/confirm") async def confirm_tool(request: ConfirmRequest): # Sets the threading.Event on the SSE handler sse_handler.set_confirmation(request.confirm_id, request.decision)
Frontend (src/gaia/apps/chat/webui/)
ToolConfirmModalcomponent — Shows command details with Allow/Deny/Always Allow buttonsapi.ts—confirmToolExecution(confirmId, decision)function- localStorage —
gaia-chat-allowed-commandsstores the "Always Allow" list. Frontend auto-responds totool_confirmevents for matching commands without showing the popup.
Acceptance Criteria
-
run_shell_commandtriggers a confirmation popup in the Chat UI - Popup shows the exact command to be executed
- "Allow" executes once, "Deny" skips, "Always Allow" persists
- "Always Allow" list survives page reloads (localStorage)
- CLI agent is unaffected (auto-approves by default)
- 60-second timeout if user doesn't respond
- Agent handles denial gracefully (continues to next step or answers)
Files to Modify
src/gaia/agents/base/console.py—OutputHandler.confirm_tool_execution()src/gaia/agents/base/agent.py— Confirmation check before_execute_tool()src/gaia/chat/ui/sse_handler.py— Blocking confirm with threading.Eventsrc/gaia/chat/ui/server.py—/api/chat/confirmendpointsrc/gaia/chat/ui/models.py—ConfirmRequestmodelsrc/gaia/apps/chat/webui/src/components/ToolConfirmModal.tsx— New componentsrc/gaia/apps/chat/webui/src/services/api.ts—confirmToolExecution()src/gaia/apps/chat/webui/src/components/ChatView.tsx— Handletool_confirmevents
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or request