Skip to content

Commit 858e14d

Browse files
committed
Support "accept and remember" tool call per session and name.
1 parent 2faaf30 commit 858e14d

File tree

5 files changed

+24
-12
lines changed

5 files changed

+24
-12
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
## Unreleased
44

5+
- Support "accept and remember" tool call per session and name.
6+
57
## 0.62.1
68

79
- Add `claude-sonnet-4.5` for github-copilot provider.

docs/protocol.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -929,6 +929,11 @@ interface ChatToolCallApproveParams {
929929
*/
930930
chatId: string;
931931

932+
/**
933+
* The approach to save this tool call.
934+
*/
935+
save?: 'session';
936+
932937
/**
933938
* The tool call identifier to approve.
934939
*/

src/eca/features/chat.clj

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -530,7 +530,7 @@
530530
details (f.tools/tool-call-details-before-invocation name arguments)
531531
summary (f.tools/tool-call-summary all-tools name arguments config)
532532
origin (tool-name->origin name all-tools)
533-
approval (f.tools/approval all-tools name arguments db config behavior)
533+
approval (f.tools/approval all-tools name arguments @db* config behavior)
534534
ask? (= :ask approval)]
535535
;; assert: In :preparing or :stopping or :stopped
536536
;; Inform client the tool is about to run and store approval promise
@@ -799,22 +799,21 @@
799799
:model full-model
800800
:status :prompting}))
801801

802-
(defn tool-call-approve [{:keys [chat-id tool-call-id request-id]} db* messenger metrics]
803-
(let [chat-ctx {;; What else is needed?
804-
:chat-id chat-id
802+
(defn tool-call-approve [{:keys [chat-id tool-call-id save]} db* messenger metrics]
803+
(let [chat-ctx {:chat-id chat-id
805804
:db* db*
806805
:metrics metrics
807-
:request-id request-id
808806
:messenger messenger}]
809807
(transition-tool-call! db* chat-ctx tool-call-id :user-approve
810808
{:reason {:code :user-choice-allow
811-
:text "Tool call allowed by user choice"}})))
809+
:text "Tool call allowed by user choice"}})
810+
(when (= "session" save)
811+
(let [tool-call-name (get-in @db* [:chats chat-id :tool-calls tool-call-id :name])]
812+
(swap! db* assoc-in [:tool-calls tool-call-name :remember-to-approve?] true)))))
812813

813-
(defn tool-call-reject [{:keys [chat-id tool-call-id request-id]} db* messenger metrics]
814-
(let [chat-ctx {;; What else is needed?
815-
:chat-id chat-id
814+
(defn tool-call-reject [{:keys [chat-id tool-call-id]} db* messenger metrics]
815+
(let [chat-ctx {:chat-id chat-id
816816
:db* db*
817-
:request-id request-id
818817
:metrics metrics
819818
:messenger messenger}]
820819
(transition-tool-call! db* chat-ctx tool-call-id :user-reject

src/eca/features/tools.clj

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,14 +189,18 @@
189189
"Return the approval keyword for the specific tool call: ask, allow or deny.
190190
Behavior parameter is required - pass nil for global-only approval rules."
191191
[all-tools tool-call-name args db config behavior]
192-
(let [{:keys [server require-approval-fn]} (first (filter #(= tool-call-name (:name %))
192+
(let [remember-to-approve? (get-in db [:tool-calls tool-call-name :remember-to-approve?])
193+
{:keys [server require-approval-fn]} (first (filter #(= tool-call-name (:name %))
193194
all-tools))
194195
{:keys [allow ask deny byDefault]} (merge (get-in config [:toolCall :approval])
195196
(get-in config [:behavior behavior :toolCall :approval]))]
196197
(cond
197198
(and require-approval-fn (require-approval-fn args {:db db}))
198199
:ask
199200

201+
remember-to-approve?
202+
:allow
203+
200204
(some #(approval-matches? % server tool-call-name args) deny)
201205
:deny
202206

test/eca/features/tools_test.clj

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@
8888
(is (= #{"plan_tool"}
8989
(#'f.tools/get-disabled-tools config "plan"))))))
9090

91-
(deftest manual-approval?-test
91+
(deftest approval-test
9292
(let [all-tools [{:name "eca_read" :server "eca"}
9393
{:name "eca_write" :server "eca"}
9494
{:name "eca_shell" :server "eca" :require-approval-fn (constantly true)}
@@ -99,6 +99,8 @@
9999
(is (= :ask (f.tools/approval all-tools "eca_shell" {} {} {} nil))))
100100
(testing "tool has require-approval-fn which returns false we ignore it"
101101
(is (= :ask (f.tools/approval all-tools "eca_plan" {} {} {} nil))))
102+
(testing "tool was remembered to approve by user"
103+
(is (= :allow (f.tools/approval all-tools "eca_plan" {} {:tool-calls {"eca_plan" {:remember-to-approve? true}}} {} nil))))
102104
(testing "if legacy-manual-approval present, considers it"
103105
(is (= :ask (f.tools/approval all-tools "request" {} {} {:toolCall {:manualApproval true}} nil))))
104106
(testing "if approval config is provided"

0 commit comments

Comments
 (0)