Commit 3df90ff
## Summary
- Adds a blocking confirmation popup in the Agent UI before
`run_shell_command` executes, so users can Allow, Deny, or Always Allow
each shell command the agent wants to run
- CLI path (`gaia chat`) is unaffected — auto-approves as before
- Reuses the existing `PermissionPrompt.tsx` / `GaiaNotification` /
`notificationStore` infrastructure already in the codebase
## Architecture
```
Agent thread (sync) SSE consumer (async) Frontend
──────────────────── ──────────────────── ────────
_execute_tool("run_shell_command")
→ console.confirm_tool_execution()
→ emit {"type":"tool_confirm"} ──→ yields SSE event ──→ ChatView.onAgentEvent
→ threading.Event.wait(60s) → checks localStorage
↑ → shows PermissionPrompt
│ POST /api/chat/confirm ←── → user clicks Allow/Deny
└── Event.set() ─────────── resolve_confirmation()
→ execute or return denial
```
## Files Changed
| File | Change |
|------|--------|
| `agents/base/console.py` | `confirm_tool_execution()` on
`OutputHandler` (default `True`) |
| `agents/base/agent.py` | `TOOLS_REQUIRING_CONFIRMATION` + guardrail in
`_execute_tool()` |
| `ui/sse_handler.py` | Blocking `confirm_tool_execution()` +
`resolve_confirmation()` |
| `ui/server.py` | `app.state.active_sse_handlers` registry |
| `ui/_chat_helpers.py` | Register/unregister handler; pass
`http_request` |
| `ui/routers/chat.py` | `POST /api/chat/confirm` endpoint |
| `ui/models.py` | `ToolConfirmRequest` model |
| `webui/src/types/index.ts` | `tool_confirm` event type + fields |
| `webui/src/services/api.ts` | `confirmToolExecution()` + event routing
|
| `webui/src/components/ChatView.tsx` | Handle `tool_confirm`,
localStorage auto-approve |
| `webui/src/stores/notificationStore.ts` | HTTP fallback, Always Allow
persistence |
## Files Reused (no changes)
- `PermissionPrompt.tsx` — full modal UI with countdown,
Allow/Deny/Always Allow, keyboard shortcuts
- `GaiaNotification` type — already has `tool`, `toolArgs`,
`timeoutSeconds` fields
## Test plan
Manual (Agent UI):
1. `gaia chat --ui` → ask "run ls /tmp" → confirm popup appears with
command shown
2. Click **Allow** → command executes, output visible in chat
3. Click **Deny** → agent responds gracefully without executing
4. Check **Remember** + **Allow** → reload page → same prompt skips
popup
5. Do nothing for 60 s → popup auto-closes, command denied with warning
CLI regression:
- `gaia chat` → same shell command prompt → no popup, executes
immediately
Fixes #438
---------
Co-authored-by: kovtcharov <kalin@extropolis.ai>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 8c2d24a commit 3df90ff
15 files changed
Lines changed: 640 additions & 52 deletions
File tree
- docs
- guides
- sdk/sdks
- src/gaia
- agents/base
- apps/webui/src
- components
- services
- stores
- styles
- types
- ui
- routers
- tests/unit/chat/ui
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
10 | 10 | | |
11 | 11 | | |
12 | 12 | | |
13 | | - | |
14 | | - | |
15 | | - | |
16 | | - | |
17 | | - | |
18 | | - | |
19 | | - | |
20 | | - | |
21 | | - | |
22 | | - | |
23 | | - | |
24 | 13 | | |
25 | 14 | | |
26 | 15 | | |
| |||
85 | 74 | | |
86 | 75 | | |
87 | 76 | | |
88 | | - | |
89 | | - | |
90 | | - | |
91 | | - | |
92 | | - | |
| 77 | + | |
93 | 78 | | |
94 | 79 | | |
95 | 80 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
19 | 19 | | |
20 | 20 | | |
21 | 21 | | |
22 | | - | |
23 | | - | |
24 | | - | |
25 | | - | |
26 | 22 | | |
27 | 23 | | |
28 | 24 | | |
| |||
350 | 346 | | |
351 | 347 | | |
352 | 348 | | |
353 | | - | |
354 | 349 | | |
355 | 350 | | |
356 | 351 | | |
| |||
370 | 365 | | |
371 | 366 | | |
372 | 367 | | |
373 | | - | |
374 | 368 | | |
375 | 369 | | |
376 | 370 | | |
| |||
865 | 859 | | |
866 | 860 | | |
867 | 861 | | |
868 | | - | |
869 | | - | |
| 862 | + | |
| 863 | + | |
870 | 864 | | |
871 | 865 | | |
872 | 866 | | |
| |||
879 | 873 | | |
880 | 874 | | |
881 | 875 | | |
882 | | - | |
| 876 | + | |
883 | 877 | | |
884 | 878 | | |
885 | | - | |
886 | | - | |
887 | | - | |
888 | | - | |
| 879 | + | |
| 880 | + | |
| 881 | + | |
| 882 | + | |
889 | 883 | | |
890 | 884 | | |
891 | | - | |
| 885 | + | |
892 | 886 | | |
893 | 887 | | |
894 | 888 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
31 | 31 | | |
32 | 32 | | |
33 | 33 | | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
34 | 39 | | |
35 | 40 | | |
36 | 41 | | |
| |||
1148 | 1153 | | |
1149 | 1154 | | |
1150 | 1155 | | |
| 1156 | + | |
| 1157 | + | |
| 1158 | + | |
| 1159 | + | |
| 1160 | + | |
| 1161 | + | |
| 1162 | + | |
| 1163 | + | |
| 1164 | + | |
| 1165 | + | |
1151 | 1166 | | |
1152 | 1167 | | |
1153 | 1168 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
205 | 205 | | |
206 | 206 | | |
207 | 207 | | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
208 | 216 | | |
209 | 217 | | |
210 | 218 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
| 8 | + | |
| 9 | + | |
8 | 10 | | |
9 | 11 | | |
10 | 12 | | |
| |||
129 | 131 | | |
130 | 132 | | |
131 | 133 | | |
| 134 | + | |
| 135 | + | |
132 | 136 | | |
133 | 137 | | |
134 | 138 | | |
| |||
598 | 602 | | |
599 | 603 | | |
600 | 604 | | |
| 605 | + | |
| 606 | + | |
| 607 | + | |
| 608 | + | |
| 609 | + | |
| 610 | + | |
| 611 | + | |
| 612 | + | |
| 613 | + | |
| 614 | + | |
| 615 | + | |
| 616 | + | |
| 617 | + | |
| 618 | + | |
| 619 | + | |
| 620 | + | |
| 621 | + | |
| 622 | + | |
| 623 | + | |
| 624 | + | |
| 625 | + | |
| 626 | + | |
| 627 | + | |
| 628 | + | |
| 629 | + | |
| 630 | + | |
| 631 | + | |
| 632 | + | |
| 633 | + | |
| 634 | + | |
| 635 | + | |
| 636 | + | |
| 637 | + | |
| 638 | + | |
| 639 | + | |
| 640 | + | |
| 641 | + | |
601 | 642 | | |
602 | 643 | | |
603 | 644 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
143 | 143 | | |
144 | 144 | | |
145 | 145 | | |
146 | | - | |
| 146 | + | |
147 | 147 | | |
148 | 148 | | |
149 | 149 | | |
| |||
277 | 277 | | |
278 | 278 | | |
279 | 279 | | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
| 288 | + | |
| 289 | + | |
| 290 | + | |
| 291 | + | |
280 | 292 | | |
281 | 293 | | |
282 | 294 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
11 | 11 | | |
12 | 12 | | |
13 | 13 | | |
| 14 | + | |
| 15 | + | |
14 | 16 | | |
15 | 17 | | |
16 | 18 | | |
17 | 19 | | |
18 | 20 | | |
19 | 21 | | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
20 | 25 | | |
21 | 26 | | |
22 | 27 | | |
| |||
78 | 83 | | |
79 | 84 | | |
80 | 85 | | |
81 | | - | |
82 | | - | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
83 | 89 | | |
84 | | - | |
| 90 | + | |
85 | 91 | | |
86 | 92 | | |
87 | 93 | | |
88 | 94 | | |
89 | 95 | | |
90 | 96 | | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
91 | 119 | | |
92 | | - | |
| 120 | + | |
93 | 121 | | |
94 | 122 | | |
95 | 123 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
348 | 348 | | |
349 | 349 | | |
350 | 350 | | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
| 355 | + | |
| 356 | + | |
| 357 | + | |
| 358 | + | |
| 359 | + | |
| 360 | + | |
| 361 | + | |
| 362 | + | |
| 363 | + | |
| 364 | + | |
| 365 | + | |
| 366 | + | |
| 367 | + | |
351 | 368 | | |
352 | 369 | | |
353 | 370 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
197 | 197 | | |
198 | 198 | | |
199 | 199 | | |
200 | | - | |
201 | | - | |
202 | | - | |
203 | | - | |
204 | | - | |
205 | | - | |
206 | | - | |
207 | | - | |
208 | | - | |
209 | | - | |
210 | | - | |
211 | | - | |
212 | | - | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
213 | 214 | | |
214 | 215 | | |
215 | 216 | | |
| |||
243 | 244 | | |
244 | 245 | | |
245 | 246 | | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
246 | 251 | | |
247 | 252 | | |
248 | 253 | | |
| |||
0 commit comments