Skip to content

Commit a78ee8b

Browse files
committed
Improve tool call approval UX
1 parent 578e078 commit a78ee8b

File tree

1 file changed

+74
-37
lines changed

1 file changed

+74
-37
lines changed

eca-chat.el

Lines changed: 74 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,10 @@ Must be a positive integer."
169169
(defvar-local eca-chat--tool-call-prepare-metadata-cache (make-hash-table :test 'equal)
170170
"Hash table mapping toolCall ID to tool metadata (name, summary, etc).")
171171

172+
(defcustom eca-chat-tool-call-approval-content-size 0.9
173+
"The size of font of tool call approval."
174+
:type 'number
175+
:group 'eca)
172176

173177
;; Faces
174178

@@ -182,16 +186,31 @@ Must be a positive integer."
182186
"Face for the stop action when loading."
183187
:group 'eca)
184188

185-
(defface eca-chat-tool-call-run-face
186-
'((t (:inherit success :underline t :weight bold)))
187-
"Face for the run tool call action."
189+
(defface eca-chat-tool-call-accept-face
190+
`((t (:inherit success :height ,eca-chat-tool-call-approval-content-size :underline t :weight bold)))
191+
"Face for the accept tool call action."
188192
:group 'eca)
189193

190-
(defface eca-chat-tool-call-cancel-face
191-
'((t (:inherit error :underline t :weight bold)))
194+
(defface eca-chat-tool-call-accept-and-remember-face
195+
`((t (:inherit success :height ,eca-chat-tool-call-approval-content-size :underline t :weight bold)))
196+
"Face for the accept and remember tool call action."
197+
:group 'eca)
198+
199+
(defface eca-chat-tool-call-reject-face
200+
`((t (:inherit error :height ,eca-chat-tool-call-approval-content-size :underline t :weight bold)))
192201
"Face for the cancel tool call action."
193202
:group 'eca)
194203

204+
(defface eca-chat-tool-call-keybinding-face
205+
`((t :inherit font-lock-comment-face :height ,eca-chat-tool-call-approval-content-size))
206+
"Face for the tool call keybinding in chat."
207+
:group 'eca)
208+
209+
(defface eca-chat-tool-call-spacing-face
210+
`((t :height ,eca-chat-tool-call-approval-content-size))
211+
"Face for the tool call spacing in chat."
212+
:group 'eca)
213+
195214
(defface eca-chat-diff-view-face
196215
'((t (:foreground "dodger blue" :underline t :weight bold)))
197216
"Face for the diff view button."
@@ -441,6 +460,42 @@ Must be a positive integer."
441460
(funcall propertize-fn starting 'warning (> running 0))
442461
(funcall propertize-fn running 'success))))))
443462

463+
(defun eca-chat--build-tool-call-approval-str-content (session id spacing-line-prefix)
464+
"Build the tool call approval string for SESSION, ID and SPACING-LINE-PREFIX."
465+
(let ((keybinding-for (lambda (command)
466+
(concat "("
467+
(key-description (car (where-is-internal command eca-chat-mode-map)))
468+
")"))))
469+
(concat (propertize "\n" 'font-lock-face 'eca-chat-tool-call-spacing-face)
470+
(eca-buttonize
471+
(propertize "Accept"
472+
'eca-tool-call-pending-approval-accept t
473+
'line-prefix spacing-line-prefix
474+
'font-lock-face 'eca-chat-tool-call-accept-face)
475+
(lambda ()
476+
(eca-api-notify session
477+
:method "chat/toolCallApprove"
478+
:params (list :chatId eca-chat--id
479+
:toolCallId id))))
480+
(propertize " " 'font-lock-face 'eca-chat-tool-call-content-face)
481+
(propertize (funcall keybinding-for #'eca-chat-tool-call-accept-next)
482+
'font-lock-face 'eca-chat-tool-call-keybinding-face)
483+
(propertize "\n" 'font-lock-face 'eca-chat-tool-call-spacing-face)
484+
(eca-buttonize
485+
(propertize "Reject"
486+
'eca-tool-call-pending-approval-reject t
487+
'line-prefix spacing-line-prefix
488+
'font-lock-face 'eca-chat-tool-call-reject-face)
489+
(lambda ()
490+
(eca-api-notify session
491+
:method "chat/toolCallReject"
492+
:params (list :chatId eca-chat--id
493+
:toolCallId id))))
494+
(propertize " and tell ECA what to do differently "
495+
'font-lock-face 'eca-chat-tool-call-content-face)
496+
(propertize (funcall keybinding-for #'eca-chat-tool-call-reject-next)
497+
'font-lock-face 'eca-chat-tool-call-keybinding-face))))
498+
444499
(defun eca-chat--insert-prompt-string ()
445500
"Insert the prompt and context string adding overlay metadatas."
446501
(let ((prompt-area-ov (make-overlay (line-beginning-position) (1+ (line-beginning-position)) (current-buffer))))
@@ -1497,55 +1552,37 @@ string."
14971552
(format "Calling tool: %s" name)))
14981553
(manual? (plist-get content :manualApproval))
14991554
(status eca-chat-mcp-tool-call-loading-symbol)
1500-
(approvalText (when manual?
1501-
(concat (eca-buttonize
1502-
(propertize "reject"
1503-
'eca-tool-call-pending-approval-reject t
1504-
'line-prefix tool-call-next-line-spacing
1505-
'font-lock-face 'eca-chat-tool-call-cancel-face)
1506-
(lambda ()
1507-
(eca-api-notify session
1508-
:method "chat/toolCallReject"
1509-
:params (list :chatId eca-chat--id
1510-
:toolCallId id))))
1511-
" "
1512-
(eca-buttonize
1513-
(propertize "accept"
1514-
'eca-tool-call-pending-approval-accept t
1515-
'font-lock-face 'eca-chat-tool-call-run-face)
1516-
(lambda ()
1517-
(eca-api-notify session
1518-
:method "chat/toolCallApprove"
1519-
:params (list :chatId eca-chat--id
1520-
:toolCallId id)))))))
1555+
(approval-text (when manual?
1556+
(eca-chat--build-tool-call-approval-str-content session id tool-call-next-line-spacing)))
15211557
(details (plist-get content :details)))
15221558
(when manual?
15231559
(eca-assoc eca-chat--tool-call-pending-approval-accept-point-by-id id (point)))
15241560
(if (and (stringp (plist-get details :type))
15251561
(string= "fileChange" (plist-get details :type)))
15261562
(let* ((path (plist-get details :path))
15271563
(diff (plist-get details :diff))
1528-
(view-btn (eca-buttonize
1529-
(propertize "view_diff" 'font-lock-face 'eca-chat-diff-view-face)
1530-
`(lambda ()
1531-
(interactive)
1532-
(eca-chat--show-diff ,path ,diff)))))
1564+
(view-diff-btn (eca-buttonize
1565+
(propertize "view_diff" 'font-lock-face 'eca-chat-diff-view-face)
1566+
(lambda ()
1567+
(interactive)
1568+
(eca-chat--show-diff path diff)))))
15331569
(eca-chat--update-expandable-content
15341570
id
15351571
(concat (propertize summary 'font-lock-face 'eca-chat-mcp-tool-call-label-face)
15361572
" "
15371573
(eca-chat--file-change-details-label details)
15381574
" " status
15391575
"\n"
1540-
approvalText " " view-btn)
1576+
view-diff-btn
1577+
approval-text)
15411578
(concat "Tool: `" name "`\n"
15421579
(eca-chat--file-change-diff path diff roots))))
15431580
(eca-chat--update-expandable-content
15441581
id
15451582
(concat (propertize summary 'font-lock-face 'eca-chat-mcp-tool-call-label-face)
15461583
" " status
15471584
"\n"
1548-
approvalText)
1585+
approval-text)
15491586
(eca-chat--content-table
15501587
`(("Tool" . ,name)
15511588
("Arguments" . ,args)))))))
@@ -1564,7 +1601,7 @@ string."
15641601
(string= "fileChange" (plist-get details :type)))
15651602
(let* ((path (plist-get details :path))
15661603
(diff (plist-get details :diff))
1567-
(view-btn
1604+
(view-diff-btn
15681605
(eca-buttonize
15691606
(propertize "view_diff" 'font-lock-face 'eca-chat-diff-view-face)
15701607
`(lambda ()
@@ -1577,7 +1614,7 @@ string."
15771614
(eca-chat--file-change-details-label details)
15781615
" " status
15791616
"\n"
1580-
(propertize view-btn 'line-prefix tool-call-next-line-spacing))
1617+
(propertize view-diff-btn 'line-prefix tool-call-next-line-spacing))
15811618
(concat "Tool: `" name "`\n"
15821619
(eca-chat--file-change-diff path diff roots))))
15831620
(eca-chat--update-expandable-content
@@ -1609,7 +1646,7 @@ string."
16091646
(string= "fileChange" (plist-get details :type)))
16101647
(let* ((path (plist-get details :path))
16111648
(diff (plist-get details :diff))
1612-
(view-btn
1649+
(view-diff-btn
16131650
(eca-buttonize
16141651
(propertize "view_diff" 'font-lock-face 'eca-chat-diff-view-face)
16151652
`(lambda ()
@@ -1621,7 +1658,7 @@ string."
16211658
" " (eca-chat--file-change-details-label details)
16221659
" " status
16231660
"\n"
1624-
(propertize view-btn 'line-prefix tool-call-next-line-spacing))
1661+
(propertize view-diff-btn 'line-prefix tool-call-next-line-spacing))
16251662
(concat "Tool: `" name "`\n"
16261663
(eca-chat--file-change-diff path diff roots))))
16271664
(eca-chat--update-expandable-content

0 commit comments

Comments
 (0)