From e87eb14a7d9a66d6663bd15e3bac9a68a9edea56 Mon Sep 17 00:00:00 2001 From: Ryan Schmukler Date: Wed, 15 Jul 2026 18:36:20 -0400 Subject: [PATCH] Isolate mutable chat state per buffer Ensure finishing one chat cannot clear another chat's running subagent timer or related tool state. --- eca-chat.el | 14 ++++++++++++++ test/eca-chat-test.el | 26 ++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/eca-chat.el b/eca-chat.el index 711304b..1ff95e7 100644 --- a/eca-chat.el +++ b/eca-chat.el @@ -3249,6 +3249,20 @@ CHILD, NAME, DOCSTRING and BODY are passed down." (setq-local eca-chat--history '()) (setq-local eca-chat--history-index -1) + ;; Mutable defaults would otherwise be shared until locally assigned. + (setq-local eca-chat-expandable--id->ov + (make-hash-table :test 'equal)) + (setq-local eca-chat--tool-call-prepare-counters + (make-hash-table :test 'equal)) + (setq-local eca-chat--tool-call-prepare-content-cache + (make-hash-table :test 'equal)) + (setq-local eca-chat--tool-call-elapsed-times + (make-hash-table :test 'equal)) + (setq-local eca-chat--subagent-chat-id->tool-call-id + (make-hash-table :test 'equal)) + (setq-local eca-chat--subagent-usage + (make-hash-table :test 'equal)) + ;; Show diff blocks in markdown-mode with colors. (setq-local markdown-fontify-code-blocks-natively t) ;; Enable gfm-view-mode-like rendering without read-only. diff --git a/test/eca-chat-test.el b/test/eca-chat-test.el index 82d6d2b..4885242 100644 --- a/test/eca-chat-test.el +++ b/test/eca-chat-test.el @@ -1370,4 +1370,30 @@ does not treat the first line as metadata. Returns FN's value." (delete-window win))) (kill-buffer buf)))))) +(describe "eca-chat subagent elapsed time" + (it "keeps elapsed tracking isolated when another chat finishes" + (spy-on 'eca-chat--force-tab-line-update) + (let ((session (make-eca--session)) + chat-a chat-b) + (unwind-protect + (progn + (eca-chat-opened session '(:chatId "chat-A" :title "A")) + (eca-chat-opened session '(:chatId "chat-B" :title "B")) + (setq chat-a (eca-get (eca--session-chats session) "chat-A") + chat-b (eca-get (eca--session-chats session) "chat-B")) + (with-current-buffer chat-a + (puthash "subagent-tool-call" (current-time) + eca-chat--tool-call-elapsed-times)) + (with-current-buffer chat-b + (eca-chat--tool-call-elapsed-stop-all)) + (with-current-buffer chat-a + (expect (gethash "subagent-tool-call" + eca-chat--tool-call-elapsed-times) + :to-be-truthy))) + (dolist (buffer (list chat-a chat-b)) + (when (buffer-live-p buffer) + (with-current-buffer buffer + (setq-local eca-chat--closed t)) + (kill-buffer buffer))))))) + ;;; eca-chat-test.el ends here