test(openai): cover route timeout wiring
This commit is contained in:
parent
f64319366f
commit
e4a9538289
3 changed files with 34 additions and 9 deletions
|
|
@ -36,6 +36,12 @@ const OPENAI_HEADER_TIMEOUT_DEFAULT = 10_000
|
|||
// Custom fetch adapters can opt out when they apply route-specific header timing internally.
|
||||
const HEADER_TIMEOUT = Symbol.for("opencode.provider.header-timeout")
|
||||
|
||||
export function headerTimeoutForFetch(fetch: unknown, timeout: number | false | undefined) {
|
||||
if (timeout === false) return undefined
|
||||
if (typeof fetch === "function" && fetch[HEADER_TIMEOUT] === false) return undefined
|
||||
return timeout
|
||||
}
|
||||
|
||||
function wrapSSE(res: Response, ms: number, ctl: AbortController) {
|
||||
if (typeof ms !== "number" || ms <= 0) return res
|
||||
if (!res.body) return res
|
||||
|
|
@ -1605,8 +1611,7 @@ export const layer = Layer.effect(
|
|||
const fetchFn = customFetch ?? fetch
|
||||
const opts = init ?? {}
|
||||
const chunkAbortCtl = typeof chunkTimeout === "number" && chunkTimeout > 0 ? new AbortController() : undefined
|
||||
const headerTimeoutMs =
|
||||
headerTimeout === false || customFetch?.[HEADER_TIMEOUT] === false ? undefined : headerTimeout
|
||||
const headerTimeoutMs = headerTimeoutForFetch(customFetch, headerTimeout)
|
||||
const headerTimeoutCtl = typeof headerTimeoutMs === "number" ? timeoutController(headerTimeoutMs) : undefined
|
||||
const signals: AbortSignal[] = []
|
||||
|
||||
|
|
|
|||
|
|
@ -176,14 +176,24 @@ describe("plugin.codex", () => {
|
|||
})
|
||||
|
||||
test("can disable websocket HTTP fallback header timeout", async () => {
|
||||
const response = await fetchWithHeaderTimeout(
|
||||
async () => new Response("http"),
|
||||
"https://example.com/v1/responses",
|
||||
undefined,
|
||||
false,
|
||||
)
|
||||
using server = Bun.serve({
|
||||
port: 0,
|
||||
async fetch() {
|
||||
await Bun.sleep(30)
|
||||
return new Response("http")
|
||||
},
|
||||
})
|
||||
const hooks = await CodexAuthPlugin({} as never, { experimentalWebSockets: true })
|
||||
await hooks.config!({ provider: { openai: { options: { headerTimeout: false } } } } as never)
|
||||
const loaded = await hooks.auth!.loader!(async () => ({ type: "api", key: "sk-test" }) as never, {} as never)
|
||||
|
||||
const response = await loaded.fetch!(new URL("/v1/responses", server.url), {
|
||||
method: "POST",
|
||||
body: JSON.stringify({ stream: true }),
|
||||
})
|
||||
|
||||
expect(await response.text()).toBe("http")
|
||||
await hooks.dispose?.()
|
||||
})
|
||||
|
||||
test("deduplicates concurrent Codex token refreshes", async () => {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { afterEach, expect } from "bun:test"
|
||||
import { afterEach, expect, test } from "bun:test"
|
||||
import { createServer, type Server } from "node:http"
|
||||
import { streamText } from "ai"
|
||||
import { Effect, Layer } from "effect"
|
||||
|
|
@ -20,6 +20,16 @@ const it = testEffect(
|
|||
Layer.mergeAll(Provider.defaultLayer, Env.defaultLayer, Plugin.defaultLayer, CrossSpawnSpawner.defaultLayer),
|
||||
)
|
||||
|
||||
test("marked custom fetch adapters opt out of outer header timeout", () => {
|
||||
const fetch = Object.assign(() => Promise.resolve(new Response()), {
|
||||
[Symbol.for("opencode.provider.header-timeout")]: false,
|
||||
})
|
||||
|
||||
expect(Provider.headerTimeoutForFetch(fetch, 10_000)).toBeUndefined()
|
||||
expect(Provider.headerTimeoutForFetch(() => Promise.resolve(new Response()), 10_000)).toBe(10_000)
|
||||
expect(Provider.headerTimeoutForFetch(fetch, false)).toBeUndefined()
|
||||
})
|
||||
|
||||
it.live("headerTimeout does not abort delayed SSE body after headers arrive", () =>
|
||||
Effect.gen(function* () {
|
||||
const server = yield* Effect.acquireRelease(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue