1414 [eca.shared :as shared :refer [assoc-some]]
1515 [jsonrpc4clj.io-server :as io-server]
1616 [jsonrpc4clj.liveness-probe :as liveness-probe]
17- [jsonrpc4clj.server :as jsonrpc.server]))
17+ [jsonrpc4clj.server :as jsonrpc.server]
18+ [promesa.core :as p]))
1819
1920(set! *warn-on-reflection* true )
2021
3738(defn ^:private with-config [components]
3839 (assoc components :config (config/all @(:db* components))))
3940
41+ (defmacro ^:private eventually
42+ " Dispatches handler body to a background thread, returning a promise.
43+ Releases the protocol thread immediately. jsonrpc4clj resolves the promise
44+ and sends the JSON-RPC response when the work completes."
45+ [& body]
46+ `(p/thread ~@body))
47+
48+ (defmacro ^:private async-notify
49+ " Dispatches notification handler body to a background thread.
50+ Releases the protocol thread immediately. Exceptions are logged since
51+ notification handlers have no response channel."
52+ [& body]
53+ `(p/thread
54+ (try
55+ ~@body
56+ (catch Throwable e#
57+ (logger/error e# " [server] Error in async notification handler" )))))
58+
4059(defmethod jsonrpc.server /receive-request " initialize" [_ {:keys [server] :as components} params]
4160 (when-let [parent-process-id (:process-id params)]
4261 (liveness-probe/start! parent-process-id log-wrapper-fn #(exit server)))
4362 (handlers/initialize components params))
4463
4564(defmethod jsonrpc.server /receive-notification " initialized" [_ components _params]
46- (handlers/initialized (with-config components)))
65+ (async-notify ( handlers/initialized (with-config components) )))
4766
4867(defmethod jsonrpc.server /receive-request " shutdown" [_ components _params]
4968 (handlers/shutdown (with-config components)))
5271 (exit server))
5372
5473(defmethod jsonrpc.server /receive-notification " workspace/didChangeWorkspaceFolders" [_ components params]
55- (handlers/workspace-did-change-folders (with-config components) params))
74+ (async-notify ( handlers/workspace-did-change-folders (with-config components) params) ))
5675
5776(defmethod jsonrpc.server /receive-request " chat/prompt" [_ components params]
58- (handlers/chat-prompt (with-config components) params))
77+ (eventually ( handlers/chat-prompt (with-config components) params) ))
5978
6079(defmethod jsonrpc.server /receive-request " chat/queryContext" [_ components params]
61- (handlers/chat-query-context (with-config components) params))
80+ (eventually ( handlers/chat-query-context (with-config components) params) ))
6281
6382(defmethod jsonrpc.server /receive-request " chat/queryFiles" [_ components params]
64- (handlers/chat-query-files (with-config components) params))
83+ (eventually ( handlers/chat-query-files (with-config components) params) ))
6584
6685(defmethod jsonrpc.server /receive-request " chat/queryCommands" [_ components params]
67- (handlers/chat-query-commands (with-config components) params))
86+ (eventually ( handlers/chat-query-commands (with-config components) params) ))
6887
6988(defmethod jsonrpc.server /receive-notification " chat/toolCallApprove" [_ components params]
7089 (handlers/chat-tool-call-approve (with-config components) params))
7695 (handlers/chat-prompt-stop (with-config components) params))
7796
7897(defmethod jsonrpc.server /receive-request " chat/delete" [_ components params]
79- (handlers/chat-delete (with-config components) params))
98+ (eventually ( handlers/chat-delete (with-config components) params) ))
8099
81100(defmethod jsonrpc.server /receive-request " chat/clear" [_ components params]
82- (handlers/chat-clear (with-config components) params))
101+ (eventually ( handlers/chat-clear (with-config components) params) ))
83102
84103(defmethod jsonrpc.server /receive-request " chat/rollback" [_ components params]
85- (handlers/chat-rollback (with-config components) params))
104+ (eventually ( handlers/chat-rollback (with-config components) params) ))
86105
87106(defmethod jsonrpc.server /receive-notification " mcp/stopServer" [_ components params]
88- (handlers/mcp-stop-server (with-config components) params))
107+ (async-notify ( handlers/mcp-stop-server (with-config components) params) ))
89108
90109(defmethod jsonrpc.server /receive-notification " mcp/startServer" [_ components params]
91- (handlers/mcp-start-server (with-config components) params))
110+ (async-notify ( handlers/mcp-start-server (with-config components) params) ))
92111
93112(defmethod jsonrpc.server /receive-notification " mcp/connectServer" [_ components params]
94- (handlers/mcp-connect-server (with-config components) params))
113+ (async-notify ( handlers/mcp-connect-server (with-config components) params) ))
95114
96115(defmethod jsonrpc.server /receive-notification " mcp/logoutServer" [_ components params]
97- (handlers/mcp-logout-server (with-config components) params))
116+ (async-notify ( handlers/mcp-logout-server (with-config components) params) ))
98117
99118(defmethod jsonrpc.server /receive-notification " mcp/disableServer" [_ components params]
100- (handlers/mcp-disable-server (with-config components) params))
119+ (async-notify ( handlers/mcp-disable-server (with-config components) params) ))
101120
102121(defmethod jsonrpc.server /receive-notification " mcp/enableServer" [_ components params]
103- (handlers/mcp-enable-server (with-config components) params))
122+ (async-notify ( handlers/mcp-enable-server (with-config components) params) ))
104123
105124(defmethod jsonrpc.server /receive-request " mcp/updateServer" [_ components params]
106- (handlers/mcp-update-server (with-config components) params))
125+ (eventually ( handlers/mcp-update-server (with-config components) params) ))
107126
108127(defmethod jsonrpc.server /receive-notification " chat/selectedAgentChanged" [_ components params]
109- (handlers/chat-selected-agent-changed (with-config components) params))
128+ (async-notify ( handlers/chat-selected-agent-changed (with-config components) params) ))
110129
111130; ; Legacy: backward compat for clients using old method name
112131(defmethod jsonrpc.server /receive-notification " chat/selectedBehaviorChanged" [_ components params]
113- (handlers/chat-selected-agent-changed (with-config components) params))
132+ (async-notify ( handlers/chat-selected-agent-changed (with-config components) params) ))
114133
115134(defmethod jsonrpc.server /receive-notification " chat/selectedModelChanged" [_ components params]
116- (handlers/chat-selected-model-changed (with-config components) params))
135+ (async-notify ( handlers/chat-selected-model-changed (with-config components) params) ))
117136
118137(defmethod jsonrpc.server /receive-request " providers/list" [_ components params]
119- (handlers/providers-list (with-config components) params))
138+ (eventually ( handlers/providers-list (with-config components) params) ))
120139
121140(defmethod jsonrpc.server /receive-request " providers/login" [_ components params]
122- (handlers/providers-login (with-config components) params))
141+ (eventually ( handlers/providers-login (with-config components) params) ))
123142
124143(defmethod jsonrpc.server /receive-request " providers/loginInput" [_ components params]
125- (handlers/providers-login-input (with-config components) params))
144+ (eventually ( handlers/providers-login-input (with-config components) params) ))
126145
127146(defmethod jsonrpc.server /receive-request " providers/logout" [_ components params]
128- (handlers/providers-logout (with-config components) params))
147+ (eventually ( handlers/providers-logout (with-config components) params) ))
129148
130149(defmethod jsonrpc.server /receive-request " completion/inline" [_ components params]
131- (handlers/completion-inline (with-config components) params))
150+ (eventually ( handlers/completion-inline (with-config components) params) ))
132151
133152(defmethod jsonrpc.server /receive-request " rewrite/prompt" [_ components params]
134- (handlers/rewrite-prompt (with-config components) params))
153+ (eventually ( handlers/rewrite-prompt (with-config components) params) ))
135154
136155(defn ^:private monitor-server-logs [log-ch]
137156 ; ; NOTE: if this were moved to `initialize`, after timbre has been configured,
236255 server (io-server/stdio-server {:log-ch log-ch
237256 :trace-ch log-ch
238257 :trace-level (if verbose? " verbose" " off" )})]
239- (start-server! server))))
258+ (start-server! server))))
0 commit comments