Skip to content

Commit 029933e

Browse files
authored
Merge pull request #452 from itkonen/fix/openai-oauth-web-search
Fix OpenAI OAuth web search and image generation
2 parents abc59a2 + f3ea437 commit 029933e

3 files changed

Lines changed: 51 additions & 18 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
## Unreleased
44

55
- Fix subagent spawning being rejected by reserved server-managed chat ids.
6+
- Fix OpenAI OAuth requests dropping built-in web search and image generation tools, and avoid replaying web search history artifacts on follow-up turns.
67

78
## 0.133.1
89

src/eca/llm_providers/openai.clj

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,8 @@
152152
[{:type "summary_text"
153153
:text (:text content)}])
154154
:encrypted_content (:external-id content)}]
155+
"server_tool_use" []
156+
"server_tool_result" []
155157
[(-> msg
156158
(dissoc :content-id)
157159
(update :content (fn [c]
@@ -175,30 +177,30 @@
175177
c)))))]))
176178
messages))
177179

178-
(defn ^:private ->tools [tools web-search image-generation codex?]
180+
(defn ^:private ->tools [tools web-search image-generation]
179181
(cond->
180182
(mapv (fn [tool]
181183
{:type "function"
182184
:name (:full-name tool)
183185
:description (:description tool)
184186
:parameters (:parameters tool)})
185187
tools)
186-
(and web-search (not codex?)) (conj {:type "web_search_preview"})
187-
(and image-generation (not codex?)) (conj {:type "image_generation" :output_format "png"})))
188+
web-search (conj {:type "web_search"})
189+
image-generation (conj {:type "image_generation" :output_format "png"})))
188190

189191
(defn create-response! [{:keys [model user-messages instructions reason? supports-image? api-key api-url url-relative-path
190192
max-output-tokens past-messages tools web-search image-generation extra-payload extra-headers
191193
auth-type account-id http-client prompt-cache-key]}
192194
{:keys [on-message-received on-error on-prepare-tool-call on-tools-called on-reason on-usage-updated
193195
on-server-web-search on-server-image-generation] :as callbacks}]
194-
(let [codex? (= :auth/oauth auth-type)
196+
(let [oauth? (= :auth/oauth auth-type)
195197
input (concat (normalize-messages past-messages supports-image?)
196198
(normalize-messages user-messages supports-image?))
197-
tools (->tools tools web-search image-generation codex?)
199+
tools (->tools tools web-search image-generation)
198200
body (merge
199201
(assoc-some
200202
{:model model
201-
:input (if codex?
203+
:input (if oauth?
202204
(concat [{:role "system" :content instructions}] input)
203205
input)
204206
:prompt_cache_key (or prompt-cache-key
@@ -212,7 +214,7 @@
212214
{:effort "medium"
213215
:summary "auto"})
214216
:stream true}
215-
:max_output_tokens (when-not codex? max-output-tokens)
217+
:max_output_tokens (when-not oauth? max-output-tokens)
216218
:parallel_tool_calls (:parallel_tool_calls extra-payload))
217219
extra-payload)
218220
tool-call-by-item-id* (atom {})
@@ -345,7 +347,7 @@
345347
{:rid (llm-util/gen-rid)
346348
:body (assoc body
347349
:input (normalize-messages new-messages supports-image?)
348-
:tools (->tools tools web-search image-generation codex?))
350+
:tools (->tools tools web-search image-generation))
349351
:api-url api-url
350352
:url-relative-path url-relative-path
351353
:api-key (or fresh-api-key api-key)

test/eca/llm_providers/openai_test.clj

Lines changed: 40 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,19 @@
257257
(is (= []
258258
(#'llm-providers.openai/normalize-messages
259259
[{:role "image_generation_call" :content {:base64 "DDD"}}]
260-
false)))))
260+
false))))
261+
(testing "server web search history artifacts are skipped on replay"
262+
(is (match?
263+
[{:role "assistant"
264+
:content [{:type "output_text" :text "Found the answer."}]}]
265+
(#'llm-providers.openai/normalize-messages
266+
[{:role "server_tool_use"
267+
:content {:id "ws_1" :name "web_search" :input {:query "latest news"}}}
268+
{:role "server_tool_result"
269+
:content {:tool-use-id "ws_1" :raw-content nil}}
270+
{:role "assistant"
271+
:content [{:type :text :text "Found the answer."}]}]
272+
true)))))
261273

262274
(defn- base-provider-params []
263275
{:model "gpt-test"
@@ -382,25 +394,43 @@
382394
:output "ok\n"}
383395
(first out)))))))
384396

385-
(deftest ->tools-image-generation-test
386-
(testing "image_generation tool is appended when flag is on and not on codex path"
397+
(deftest ->tools-built-in-tools-test
398+
(testing "image_generation tool is appended when flag is on"
387399
(is (match?
388400
[{:type "image_generation" :output_format "png"}]
389-
(#'llm-providers.openai/->tools [] false true false))))
401+
(#'llm-providers.openai/->tools [] false true))))
390402
(testing "image_generation tool is NOT appended when flag is off"
391403
(is (= []
392-
(#'llm-providers.openai/->tools [] false false false))))
393-
(testing "image_generation tool is NOT appended on codex path even if flag is on"
394-
(is (= []
395-
(#'llm-providers.openai/->tools [] false true true))))
404+
(#'llm-providers.openai/->tools [] false false))))
396405
(testing "image_generation tool sits alongside web_search and function tools"
397406
(is (match?
398407
[{:type "function" :name "eca__foo"}
399-
{:type "web_search_preview"}
408+
{:type "web_search"}
400409
{:type "image_generation" :output_format "png"}]
401410
(#'llm-providers.openai/->tools
402411
[{:full-name "eca__foo" :description "d" :parameters {}}]
403-
true true false)))))
412+
true true)))))
413+
414+
(deftest create-response-oauth-preserves-built-in-tools-test
415+
(testing "OAuth requests keep web_search and image_generation when capabilities are enabled"
416+
(let [requests* (atom [])]
417+
(with-redefs [llm-providers.openai/base-responses-request!
418+
(fn [{:keys [on-stream] :as opts}]
419+
(swap! requests* conj opts)
420+
(on-stream "response.completed"
421+
{:response {:output []
422+
:usage {:input_tokens 0 :output_tokens 0}
423+
:status "completed"}}))]
424+
(llm-providers.openai/create-response!
425+
(assoc (base-provider-params)
426+
:auth-type :auth/oauth
427+
:web-search true
428+
:image-generation true)
429+
(base-callbacks {}))
430+
(is (match? [{:type "function"}
431+
{:type "web_search"}
432+
{:type "image_generation" :output_format "png"}]
433+
(get-in (first @requests*) [:body :tools])))))))
404434

405435
(deftest create-response-image-generation-tool-on-request-test
406436
(testing "request body includes image_generation tool when :image-generation is true"

0 commit comments

Comments
 (0)