Skip to content

Commit e5389f3

Browse files
committed
Fix tool call approval thread lock.
1 parent b23ffc9 commit e5389f3

File tree

3 files changed

+125
-120
lines changed

3 files changed

+125
-120
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+
- Fix tool call approval thread lock.
6+
57
## 0.73.1
68

79
- Improve chat title generation.

src/eca/llm_api.clj

Lines changed: 122 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -94,126 +94,129 @@
9494
:on-tools-called on-tools-called
9595
:on-reason on-reason
9696
:on-usage-updated on-usage-updated})]
97-
(try
98-
(when-not api-url (throw (ex-info (format "API url not found.\nMake sure you have provider '%s' configured properly." provider) {})))
99-
(cond
100-
(= "openai" provider)
101-
(llm-providers.openai/create-response!
102-
{:model real-model
103-
:instructions instructions
104-
:user-messages user-messages
105-
:max-output-tokens max-output-tokens
106-
:reason? reason?
107-
:supports-image? supports-image?
108-
:past-messages past-messages
109-
:tools tools
110-
:web-search web-search
111-
:extra-payload (merge {:parallel_tool_calls true}
112-
extra-payload)
113-
:api-url api-url
114-
:api-key api-key
115-
:auth-type provider-auth-type}
116-
callbacks)
117-
118-
(= "anthropic" provider)
119-
(llm-providers.anthropic/chat!
120-
{:model real-model
121-
:instructions instructions
122-
:user-messages user-messages
123-
:max-output-tokens max-output-tokens
124-
:reason? reason?
125-
:supports-image? supports-image?
126-
:past-messages past-messages
127-
:tools tools
128-
:web-search web-search
129-
:extra-payload extra-payload
130-
:api-url api-url
131-
:api-key api-key
132-
:auth-type provider-auth-type}
133-
callbacks)
134-
135-
(= "github-copilot" provider)
136-
(llm-providers.openai-chat/chat-completion!
137-
{:model real-model
138-
:instructions instructions
139-
:user-messages user-messages
140-
:max-output-tokens max-output-tokens
141-
:reason? reason?
142-
:supports-image? supports-image?
143-
:past-messages past-messages
144-
:tools tools
145-
:extra-payload (merge {:parallel_tool_calls true}
146-
extra-payload)
147-
:api-url api-url
148-
:api-key api-key
149-
:extra-headers {"openai-intent" "conversation-panel"
150-
"x-request-id" (str (random-uuid))
151-
"vscode-sessionid" ""
152-
"vscode-machineid" ""
153-
"Copilot-Vision-Request" "true"
154-
"copilot-integration-id" "vscode-chat"}}
155-
callbacks)
97+
;; We spawn a new future to not block the lsp4clj thread
98+
;; in case a tool call approval is needed
99+
(future
100+
(try
101+
(when-not api-url (throw (ex-info (format "API url not found.\nMake sure you have provider '%s' configured properly." provider) {})))
102+
(cond
103+
(= "openai" provider)
104+
(llm-providers.openai/create-response!
105+
{:model real-model
106+
:instructions instructions
107+
:user-messages user-messages
108+
:max-output-tokens max-output-tokens
109+
:reason? reason?
110+
:supports-image? supports-image?
111+
:past-messages past-messages
112+
:tools tools
113+
:web-search web-search
114+
:extra-payload (merge {:parallel_tool_calls true}
115+
extra-payload)
116+
:api-url api-url
117+
:api-key api-key
118+
:auth-type provider-auth-type}
119+
callbacks)
156120

157-
(= "google" provider)
158-
(llm-providers.openai-chat/chat-completion!
159-
{:model real-model
160-
:instructions instructions
161-
:user-messages user-messages
162-
:max-output-tokens max-output-tokens
163-
:reason? reason?
164-
:supports-image? supports-image?
165-
:past-messages past-messages
166-
:tools tools
167-
:thinking-tag "thought"
168-
:extra-payload (merge {:parallel_tool_calls false}
169-
(when reason?
170-
{:extra_body {:google {:thinking_config {:include_thoughts true}}}})
171-
extra-payload)
172-
:api-url api-url
173-
:api-key api-key}
174-
callbacks)
121+
(= "anthropic" provider)
122+
(llm-providers.anthropic/chat!
123+
{:model real-model
124+
:instructions instructions
125+
:user-messages user-messages
126+
:max-output-tokens max-output-tokens
127+
:reason? reason?
128+
:supports-image? supports-image?
129+
:past-messages past-messages
130+
:tools tools
131+
:web-search web-search
132+
:extra-payload extra-payload
133+
:api-url api-url
134+
:api-key api-key
135+
:auth-type provider-auth-type}
136+
callbacks)
175137

176-
(= "ollama" provider)
177-
(llm-providers.ollama/chat!
178-
{:api-url api-url
179-
:reason? (:reason? model-capabilities)
180-
:supports-image? supports-image?
181-
:model real-model
182-
:instructions instructions
183-
:user-messages user-messages
184-
:past-messages past-messages
185-
:tools tools
186-
:extra-payload extra-payload}
187-
callbacks)
138+
(= "github-copilot" provider)
139+
(llm-providers.openai-chat/chat-completion!
140+
{:model real-model
141+
:instructions instructions
142+
:user-messages user-messages
143+
:max-output-tokens max-output-tokens
144+
:reason? reason?
145+
:supports-image? supports-image?
146+
:past-messages past-messages
147+
:tools tools
148+
:extra-payload (merge {:parallel_tool_calls true}
149+
extra-payload)
150+
:api-url api-url
151+
:api-key api-key
152+
:extra-headers {"openai-intent" "conversation-panel"
153+
"x-request-id" (str (random-uuid))
154+
"vscode-sessionid" ""
155+
"vscode-machineid" ""
156+
"Copilot-Vision-Request" "true"
157+
"copilot-integration-id" "vscode-chat"}}
158+
callbacks)
188159

189-
model-config
190-
(let [provider-fn (case (:api provider-config)
191-
("openai-responses"
192-
"openai") llm-providers.openai/create-response!
193-
"anthropic" llm-providers.anthropic/chat!
194-
"openai-chat" llm-providers.openai-chat/chat-completion!
195-
(on-error {:message (format "Unknown model %s for provider %s" (:api provider-config) provider)}))
196-
url-relative-path (:completionUrlRelativePath provider-config)]
197-
(provider-fn
160+
(= "google" provider)
161+
(llm-providers.openai-chat/chat-completion!
198162
{:model real-model
199163
:instructions instructions
200164
:user-messages user-messages
201165
:max-output-tokens max-output-tokens
202-
:web-search web-search
203166
:reason? reason?
204167
:supports-image? supports-image?
205168
:past-messages past-messages
206169
:tools tools
207-
:extra-payload extra-payload
208-
:url-relative-path url-relative-path
170+
:thinking-tag "thought"
171+
:extra-payload (merge {:parallel_tool_calls false}
172+
(when reason?
173+
{:extra_body {:google {:thinking_config {:include_thoughts true}}}})
174+
extra-payload)
209175
:api-url api-url
210176
:api-key api-key}
211-
callbacks))
177+
callbacks)
178+
179+
(= "ollama" provider)
180+
(llm-providers.ollama/chat!
181+
{:api-url api-url
182+
:reason? (:reason? model-capabilities)
183+
:supports-image? supports-image?
184+
:model real-model
185+
:instructions instructions
186+
:user-messages user-messages
187+
:past-messages past-messages
188+
:tools tools
189+
:extra-payload extra-payload}
190+
callbacks)
191+
192+
model-config
193+
(let [provider-fn (case (:api provider-config)
194+
("openai-responses"
195+
"openai") llm-providers.openai/create-response!
196+
"anthropic" llm-providers.anthropic/chat!
197+
"openai-chat" llm-providers.openai-chat/chat-completion!
198+
(on-error {:message (format "Unknown model %s for provider %s" (:api provider-config) provider)}))
199+
url-relative-path (:completionUrlRelativePath provider-config)]
200+
(provider-fn
201+
{:model real-model
202+
:instructions instructions
203+
:user-messages user-messages
204+
:max-output-tokens max-output-tokens
205+
:web-search web-search
206+
:reason? reason?
207+
:supports-image? supports-image?
208+
:past-messages past-messages
209+
:tools tools
210+
:extra-payload extra-payload
211+
:url-relative-path url-relative-path
212+
:api-url api-url
213+
:api-key api-key}
214+
callbacks))
212215

213-
:else
214-
(on-error {:message (format "ECA Unsupported model %s for provider %s" real-model provider)}))
215-
(catch Exception e
216-
(on-error {:exception e})))))
216+
:else
217+
(on-error {:message (format "ECA Unsupported model %s for provider %s" real-model provider)}))
218+
(catch Exception e
219+
(on-error {:exception e}))))))
217220

218221
(defn async-prompt! [{:keys [provider model model-capabilities instructions user-messages config on-first-response-received
219222
on-message-received on-error on-prepare-tool-call on-tools-called on-reason on-usage-updated
@@ -264,16 +267,16 @@
264267
(defn sync-prompt!
265268
[{:keys [provider model model-capabilities instructions
266269
prompt past-messages user-messages config tools provider-auth]}]
267-
(prompt!
268-
{:sync? true
269-
:provider provider
270-
:model model
271-
:model-capabilities model-capabilities
272-
:instructions instructions
273-
:tools tools
274-
:provider-auth provider-auth
275-
:past-messages past-messages
276-
:user-messages (or user-messages
277-
[{:role "user" :content [{:type :text :text prompt}]}])
278-
:config config
279-
:on-error (fn [error] {:error error})}))
270+
@(prompt!
271+
{:sync? true
272+
:provider provider
273+
:model model
274+
:model-capabilities model-capabilities
275+
:instructions instructions
276+
:tools tools
277+
:provider-auth provider-auth
278+
:past-messages past-messages
279+
:user-messages (or user-messages
280+
[{:role "user" :content [{:type :text :text prompt}]}])
281+
:config config
282+
:on-error (fn [error] {:error error})}))

src/eca/llm_providers/anthropic.clj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@
9999
(doseq [[event data] (llm-util/event-data-seq rdr)]
100100
(llm-util/log-response logger-tag rid event data)
101101
(on-stream event data content-block* reason-id)))
102-
102+
103103
(do
104104
(llm-util/log-response logger-tag rid "response" body)
105105
(reset! response*

0 commit comments

Comments
 (0)