|
104 | 104 |
|
105 | 105 | [:check-approval :auto-approve] |
106 | 106 | {:status :execution-approved |
107 | | - :actions [:deliver-approval-true]} |
| 107 | + :actions [:deliver-default-approval]} |
108 | 108 |
|
109 | 109 | [:waiting-approval :user-approve] |
110 | 110 | {:status :execution-approved |
|
169 | 169 | :id tool-call-id |
170 | 170 | :name (:name event-data) |
171 | 171 | :origin (:origin event-data) |
172 | | - :arguments-text (:arguments-text event-data) |
173 | | - :manual-approval (:manual-approval event-data)} |
| 172 | + :arguments-text (:arguments-text event-data)} |
174 | 173 | :summary (:summary event-data))) |
175 | 174 |
|
176 | 175 | :send-toolCallRun |
|
223 | 222 | (deliver (get-in @db* [:chats (:chat-id chat-ctx) :tool-calls tool-call-id :approved?*]) |
224 | 223 | true) |
225 | 224 |
|
| 225 | + :deliver-default-approval |
| 226 | + (deliver (get-in @db* [:chats (:chat-id chat-ctx) :tool-calls tool-call-id :approved?*]) |
| 227 | + (:default-approval event-data)) |
| 228 | + |
226 | 229 | ;; Logging/metrics actions |
227 | 230 | :log-rejection |
228 | 231 | (logger/info logger-tag "Tool call rejected" |
|
410 | 413 | {:name name |
411 | 414 | :origin (tool-name->origin name all-tools) |
412 | 415 | :arguments-text arguments-text |
413 | | - :manual-approval (f.tools/manual-approval? name config) |
414 | 416 | :summary (f.tools/tool-call-summary all-tools name nil)})) |
415 | 417 | ;; TODO: Should this be :on-tool-called instead for consistency? |
416 | 418 | :on-tools-called (fn [tool-calls] |
|
425 | 427 | details (f.tools/tool-call-details-before-invocation name arguments) |
426 | 428 | summary (f.tools/tool-call-summary all-tools name arguments) |
427 | 429 | origin (tool-name->origin name all-tools) |
428 | | - manual-approval? (f.tools/manual-approval? name config)] |
429 | | - ;; Inform UI the tool is about to run and store approval promise |
| 430 | + approval (f.tools/approval all-tools name arguments db config) |
| 431 | + ask? (= :ask approval)] |
| 432 | + ;; Inform client the tool is about to run and store approval promise |
430 | 433 | (transition-tool-call! db* chat-ctx id :tool-run |
431 | 434 | {:approved?* approved?* |
432 | 435 | :name name |
433 | 436 | :origin (tool-name->origin name all-tools) |
434 | 437 | :arguments arguments |
435 | | - :manual-approval manual-approval? |
| 438 | + :manual-approval ask? |
436 | 439 | :details details |
437 | 440 | :summary summary}) |
438 | | - (if manual-approval? |
| 441 | + (if ask? |
439 | 442 | (transition-tool-call! db* chat-ctx id :manual-approve |
440 | 443 | {:state :running |
441 | 444 | :text "Waiting for tool call approval"}) |
442 | | - (transition-tool-call! db* chat-ctx id :auto-approve)) |
443 | | - ;; Execute each tool call concurrently - this should be the return value of let |
| 445 | + (transition-tool-call! db* chat-ctx id :auto-approve |
| 446 | + {:default-approval (= :allow approval)})) |
| 447 | + ;; Execute each tool call concurrently |
444 | 448 | (future |
445 | 449 | (if @approved?* ;TODO: Should there be a timeout here? If so, what would be the state transitions? |
446 | 450 | ;; assert: In :execution-approved state |
447 | 451 | (do |
448 | 452 | (assert-chat-not-stopped! chat-ctx) |
449 | 453 | (transition-tool-call! db* chat-ctx id :execution-start) |
450 | | - (let [result (f.tools/call-tool! name arguments @db* config messenger)] |
| 454 | + (let [result (f.tools/call-tool! name arguments @db* config messenger behavior) |
| 455 | + details (f.tools/tool-call-details-after-invocation name arguments details result)] |
451 | 456 | (add-to-history! {:role "tool_call" :content (assoc tool-call |
452 | 457 | :details details |
453 | 458 | :summary summary |
|
467 | 472 | :details details |
468 | 473 | :summary summary}))) |
469 | 474 | ;; assert: In :rejected state |
470 | | - (do |
| 475 | + (let [[reject-reason reject-text] (if (= :deny approval) |
| 476 | + [:user-config "Tool call denied by user config"] |
| 477 | + [:user-choice "Tool call rejected by user choice"])] |
471 | 478 | (add-to-history! {:role "tool_call" :content tool-call}) |
472 | 479 | (add-to-history! {:role "tool_call_output" |
473 | 480 | :content (assoc tool-call :output {:error true |
474 | 481 | :contents [{:text reject-text |
475 | 482 | :type :text}]})}) |
476 | 483 | (transition-tool-call! db* chat-ctx id :send-reject |
477 | | - {:origin origin |
478 | | - :name name |
479 | | - :arguments arguments |
480 | | - :reason :user |
481 | | - :details details |
482 | | - :summary summary})))))))] |
| 484 | + {:origin origin |
| 485 | + :name name |
| 486 | + :arguments arguments |
| 487 | + :reason reject-reason |
| 488 | + :details details |
| 489 | + :summary summary})))))))] |
483 | 490 | (assert-chat-not-stopped! chat-ctx) |
484 | 491 | ;; Wait for all tool calls to complete before returning |
485 | 492 | (run! deref calls) |
|
0 commit comments