|
171 | 171 | :request-id request-id |
172 | 172 | :headers response-headers))) |
173 | 173 |
|
174 | | -(defn ^:private base-responses-request! [{:keys [rid body api-url auth-type url-relative-path api-key account-id on-error on-stream http-client extra-headers]}] |
| 174 | +(defn ^:private base-responses-request! [{:keys [rid body api-url auth-type url-relative-path api-key account-id on-error on-stream http-client extra-headers cancelled? stream-idle-timeout-seconds]}] |
175 | 175 | (let [oauth? (= :auth/oauth auth-type) |
176 | 176 | stream? (and on-stream (not= false (:stream body))) |
177 | 177 | url (if oauth? |
|
213 | 213 | :body body-str |
214 | 214 | :headers resp-headers})) |
215 | 215 | (if stream? |
216 | | - (let [stream-error |
217 | | - (with-open [rdr (io/reader body)] |
218 | | - (loop [events (seq (llm-util/event-data-seq rdr))] |
219 | | - (when-let [[event data] (first events)] |
220 | | - (llm-util/log-response logger-tag rid event data) |
221 | | - (if (= "response.failed" event) |
222 | | - (response-failed->error-data data resp-headers) |
223 | | - (do |
224 | | - (on-stream event data resp-headers) |
225 | | - (recur (next events)))))))] |
226 | | - (when stream-error |
227 | | - (on-error stream-error))) |
| 216 | + (let [{:keys [touch-fn set-reading-fn stop-fn reason*]} |
| 217 | + (llm-util/start-stream-watchdog! body cancelled? |
| 218 | + (when stream-idle-timeout-seconds |
| 219 | + {:idle-timeout-ms (* 1000 stream-idle-timeout-seconds)}))] |
| 220 | + (try |
| 221 | + (let [stream-error |
| 222 | + (with-open [rdr (io/reader body)] |
| 223 | + (loop [events (seq (llm-util/event-data-seq rdr))] |
| 224 | + (when-let [[event data] (first events)] |
| 225 | + (set-reading-fn false) |
| 226 | + (touch-fn) |
| 227 | + (llm-util/log-response logger-tag rid event data) |
| 228 | + (if (= "response.failed" event) |
| 229 | + (response-failed->error-data data resp-headers) |
| 230 | + (do |
| 231 | + (on-stream event data resp-headers) |
| 232 | + (set-reading-fn true) |
| 233 | + (recur (next events)))))))] |
| 234 | + (when stream-error |
| 235 | + (on-error stream-error))) |
| 236 | + (catch java.io.IOException e |
| 237 | + (let [reason @reason*] |
| 238 | + (cond |
| 239 | + (= :cancelled reason) |
| 240 | + (throw (ex-info "Stream cancelled" {:silent? true})) |
| 241 | + |
| 242 | + (= :idle-timeout reason) |
| 243 | + (on-error {:message (format "Stream idle timeout: no data received for %d seconds" |
| 244 | + (or stream-idle-timeout-seconds 120)) |
| 245 | + :exception e}) |
| 246 | + |
| 247 | + :else |
| 248 | + (throw e)))) |
| 249 | + (finally |
| 250 | + (stop-fn)))) |
228 | 251 | (do |
229 | 252 | (llm-util/log-response logger-tag rid "response" body) |
230 | 253 | (if (= "failed" (:status body)) |
|
335 | 358 |
|
336 | 359 | (defn create-response! [{:keys [model user-messages instructions reason? supports-image? api-key api-url url-relative-path |
337 | 360 | max-output-tokens past-messages tools web-search image-generation extra-payload extra-headers |
338 | | - auth-type account-id http-client prompt-cache-key]} |
| 361 | + auth-type account-id http-client prompt-cache-key cancelled? stream-idle-timeout-seconds]} |
339 | 362 | {:keys [on-message-received on-error on-prepare-tool-call on-tools-called on-reason on-usage-updated |
340 | 363 | on-server-web-search on-server-image-generation] :as callbacks}] |
341 | 364 | (let [oauth? (= :auth/oauth auth-type) |
|
501 | 524 | :http-client http-client |
502 | 525 | :extra-headers extra-headers |
503 | 526 | :auth-type auth-type |
| 527 | + :cancelled? cancelled? |
| 528 | + :stream-idle-timeout-seconds stream-idle-timeout-seconds |
504 | 529 | :on-error on-error |
505 | 530 | :on-stream handle-stream}))) |
506 | 531 | (on-message-received {:type :finish |
|
525 | 550 | :http-client http-client |
526 | 551 | :extra-headers extra-headers |
527 | 552 | :auth-type auth-type |
| 553 | + :cancelled? cancelled? |
| 554 | + :stream-idle-timeout-seconds stream-idle-timeout-seconds |
528 | 555 | :on-error on-error |
529 | 556 | :on-stream on-stream-fn})] |
530 | 557 | (if callbacks |
|
0 commit comments