Merge remote-tracking branch 'origin/main'

# Conflicts:
#	packages/ai/CHANGELOG.md
This commit is contained in:
Mario Zechner
2026-06-23 13:52:09 +02:00
14 changed files with 263 additions and 88 deletions
+5 -1
View File
@@ -69,7 +69,11 @@ describe.sequential("OAuthAuth adapters", () => {
it("github-copilot refresh preserves the enterprise domain", async () => {
const fetchedUrls: string[] = [];
const fetchMock = vi.fn(async (input: unknown) => {
fetchedUrls.push(typeof input === "string" ? input : String(input));
const url = typeof input === "string" ? input : String(input);
fetchedUrls.push(url);
if (url.endsWith("/models")) {
return jsonResponse({ data: [] });
}
return jsonResponse({ token: "new-token", expires_at: 9999999999 });
});
vi.stubGlobal("fetch", fetchMock);
@@ -1195,6 +1195,68 @@ describe("openai-codex streaming", () => {
});
});
it("reconnects once when the websocket connection limit is reached before output starts", async () => {
const token = mockToken();
let connections = 0;
const fetchMock = vi.fn();
vi.stubGlobal("fetch", fetchMock);
class MockWebSocket extends EventTarget {
private readonly limitReached = connections++ === 0;
constructor() {
super();
queueMicrotask(() => this.dispatchEvent(new Event("open")));
}
send(): void {
const event = this.limitReached
? { type: "error", error: { code: "websocket_connection_limit_reached" } }
: {
type: "response.completed",
response: {
id: "resp_1",
status: "completed",
usage: { input_tokens: 5, output_tokens: 3, total_tokens: 8 },
},
};
queueMicrotask(() => {
this.dispatchEvent(Object.assign(new Event("message"), { data: JSON.stringify(event) }));
});
}
close(): void {}
}
vi.stubGlobal("WebSocket", MockWebSocket);
const model: Model<"openai-codex-responses"> = {
id: "gpt-5.1-codex",
name: "GPT-5.1 Codex",
api: "openai-codex-responses",
provider: "openai-codex",
baseUrl: "https://chatgpt.com/backend-api",
reasoning: true,
input: ["text"],
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
contextWindow: 400000,
maxTokens: 128000,
};
const result = await streamOpenAICodexResponses(
model,
{ systemPrompt: "", messages: [] },
{
apiKey: token,
},
).result();
expect(result.stopReason).toBe("stop");
expect(connections).toBe(2);
expect(fetchMock).not.toHaveBeenCalled();
});
it("falls back to SSE when a websocket is idle before the first event", async () => {
vi.useFakeTimers();
const token = mockToken();