import test from "node:test"; import assert from "node:assert/strict"; const { BlackboxWebExecutor, normalizeBlackboxCookieHeader } = await import("../../open-sse/executors/blackbox-web.ts"); const { getExecutor, hasSpecializedExecutor } = await import("../../open-sse/executors/index.ts"); function mockTextStream(text: string) { const encoder = new TextEncoder(); return new ReadableStream({ start(controller) { controller.enqueue(encoder.encode(text)); controller.close(); }, }); } function mockFetch(status: number, text: string) { const original = globalThis.fetch; globalThis.fetch = async () => new Response(mockTextStream(text), { status, headers: { "Content-Type": "text/plain; charset=utf-8" }, }); return () => { globalThis.fetch = original; }; } function mockFetchCapture(status = 200, text = "Hello from Blackbox") { const original = globalThis.fetch; let capturedUrl: string | null = null; let capturedHeaders: Record = {}; let capturedBody: Record = {}; globalThis.fetch = async (url: any, opts: any) => { capturedUrl = String(url); capturedHeaders = opts?.headers || {}; capturedBody = JSON.parse(opts?.body || "{}"); return new Response(mockTextStream(text), { status, headers: { "Content-Type": "text/plain; charset=utf-8" }, }); }; return { restore: () => { globalThis.fetch = original; }, get url() { return capturedUrl; }, get headers() { return capturedHeaders; }, get body() { return capturedBody; }, }; } test("BlackboxWebExecutor is registered in executor index", () => { assert.ok(hasSpecializedExecutor("blackbox-web")); assert.ok(hasSpecializedExecutor("bb-web")); const executor = getExecutor("blackbox-web"); const alias = getExecutor("bb-web"); assert.ok(executor instanceof BlackboxWebExecutor); assert.ok(alias instanceof BlackboxWebExecutor); }); test("BlackboxWebExecutor sets correct provider name", () => { const executor = new BlackboxWebExecutor(); assert.equal(executor.getProvider(), "blackbox-web"); }); test("Non-streaming: plain text response becomes OpenAI completion", async () => { const restore = mockFetch(200, "Hello from Blackbox"); try { const executor = new BlackboxWebExecutor(); const result = await executor.execute({ model: "openai/gpt-5.4", body: { messages: [{ role: "user", content: "hi" }], stream: false }, stream: false, credentials: { apiKey: "bb-session-token" }, signal: AbortSignal.timeout(10000), log: null, }); assert.equal(result.response.status, 200); const json = (await result.response.json()) as any; assert.equal(json.object, "chat.completion"); assert.equal(json.choices[0].message.role, "assistant"); assert.equal(json.choices[0].message.content, "Hello from Blackbox"); assert.equal(json.choices[0].finish_reason, "stop"); assert.ok(json.id.startsWith("chatcmpl-blackbox-")); assert.ok(json.usage.total_tokens > 0); } finally { restore(); } }); test("Streaming: produces valid SSE chunks", async () => { const restore = mockFetch(200, "streamed answer"); try { const executor = new BlackboxWebExecutor(); const result = await executor.execute({ model: "openai/gpt-5.4", body: { messages: [{ role: "user", content: "hello" }], stream: true }, stream: true, credentials: { apiKey: "bb-session-token" }, signal: AbortSignal.timeout(10000), log: null, }); assert.equal(result.response.status, 200); assert.equal(result.response.headers.get("Content-Type"), "text/event-stream"); const text = await result.response.text(); const lines = text.split("\n").filter((line) => line.startsWith("data: ")); assert.ok(lines.length >= 3, `Expected at least 3 SSE data lines, got ${lines.length}`); const first = JSON.parse(lines[0].slice(6)); assert.equal(first.choices[0].delta.role, "assistant"); const second = JSON.parse(lines[1].slice(6)); assert.equal(second.choices[0].delta.content, "streamed answer"); const lastLine = text.trim().split("\n").filter(Boolean).pop(); assert.equal(lastLine, "data: [DONE]"); } finally { restore(); } }); test("Error: 401 returns auth error", async () => { const restore = mockFetch(401, "unauthorized"); try { const executor = new BlackboxWebExecutor(); const result = await executor.execute({ model: "openai/gpt-5.4", body: { messages: [{ role: "user", content: "hi" }] }, stream: false, credentials: { apiKey: "expired-cookie" }, signal: AbortSignal.timeout(10000), log: null, }); assert.equal(result.response.status, 401); const json = (await result.response.json()) as any; assert.match(json.error.message, /auth failed/i); assert.match(json.error.message, /session/i); } finally { restore(); } }); test("In-band subscription error in response body returns 402", async () => { const upgradeMessage = "You have not upgraded your account. " + "[Please upgrade to a premium plan to continue](https://app.blackbox.ai/pricing?ref=upgrade-required)."; const restore = mockFetch(200, upgradeMessage); try { const executor = new BlackboxWebExecutor(); const result = await executor.execute({ model: "anthropic/claude-sonnet-4", body: { messages: [{ role: "user", content: "hi" }], stream: false }, stream: false, credentials: { apiKey: "bb-session-token" }, signal: AbortSignal.timeout(10000), log: null, }); assert.equal(result.response.status, 402); const json = (await result.response.json()) as any; assert.equal(json.error.code, "BLACKBOX_SUBSCRIPTION_REQUIRED"); assert.match(json.error.message, /premium subscription/i); } finally { restore(); } }); test("In-band auth error in response body returns 401", async () => { const restore = mockFetch(200, "Please login to continue."); try { const executor = new BlackboxWebExecutor(); const result = await executor.execute({ model: "openai/gpt-5.4", body: { messages: [{ role: "user", content: "hi" }], stream: false }, stream: false, credentials: { apiKey: "bb-session-token" }, signal: AbortSignal.timeout(10000), log: null, }); assert.equal(result.response.status, 401); const json = (await result.response.json()) as any; assert.equal(json.error.code, "BLACKBOX_AUTH_REQUIRED"); assert.match(json.error.message, /session/i); } finally { restore(); } }); test("In-band rate limit error in response body returns 429", async () => { const restore = mockFetch(200, "Rate limit exceeded. Try again later."); try { const executor = new BlackboxWebExecutor(); const result = await executor.execute({ model: "openai/gpt-5.4", body: { messages: [{ role: "user", content: "hi" }], stream: false }, stream: false, credentials: { apiKey: "bb-session-token" }, signal: AbortSignal.timeout(10000), log: null, }); assert.equal(result.response.status, 429); const json = (await result.response.json()) as any; assert.equal(json.error.code, "BLACKBOX_RATE_LIMIT"); assert.match(json.error.message, /rate limited/i); } finally { restore(); } }); test("Error: 429 returns rate limit message", async () => { const restore = mockFetch(429, "rate limited"); try { const executor = new BlackboxWebExecutor(); const result = await executor.execute({ model: "openai/gpt-5.4", body: { messages: [{ role: "user", content: "hi" }] }, stream: false, credentials: { apiKey: "bb-session-token" }, signal: AbortSignal.timeout(10000), log: null, }); assert.equal(result.response.status, 429); const json = (await result.response.json()) as any; assert.match(json.error.message, /rate limited/i); } finally { restore(); } }); test("Error: empty messages returns 400", async () => { const executor = new BlackboxWebExecutor(); const result = await executor.execute({ model: "openai/gpt-5.4", body: { messages: [] }, stream: false, credentials: { apiKey: "bb-session-token" }, signal: AbortSignal.timeout(10000), log: null, }); assert.equal(result.response.status, 400); }); test("Cookie normalization supports raw tokens, prefixed tokens and full headers", () => { assert.equal( normalizeBlackboxCookieHeader("raw-session-token"), "next-auth.session-token=raw-session-token" ); assert.equal( normalizeBlackboxCookieHeader("cookie:raw-session-token"), "next-auth.session-token=raw-session-token" ); assert.equal( normalizeBlackboxCookieHeader("__Secure-authjs.session-token=token; other=value"), "__Secure-authjs.session-token=token; other=value" ); }); test("Request: posts to correct Blackbox endpoint with normalized cookie", async () => { const cap = mockFetchCapture(); try { const executor = new BlackboxWebExecutor(); await executor.execute({ model: "openai/gpt-5.4", body: { messages: [{ role: "user", content: "test" }], stream: false }, stream: false, credentials: { apiKey: "raw-session-token" }, signal: AbortSignal.timeout(10000), log: null, }); assert.equal(cap.url, "https://app.blackbox.ai/api/chat"); assert.equal(cap.headers.Cookie, "next-auth.session-token=raw-session-token"); assert.equal(cap.headers.Origin, "https://app.blackbox.ai"); assert.match(String(cap.headers.Referer), /^https:\/\/app\.blackbox\.ai\/chat\//); } finally { cap.restore(); } }); test("Request: payload carries model selection and web app defaults", async () => { const cap = mockFetchCapture(); try { const executor = new BlackboxWebExecutor(); await executor.execute({ model: "anthropic/claude-opus-4.7", body: { messages: [ { role: "system", content: "Be concise" }, { role: "user", content: "Implement this" }, ], max_tokens: 2048, stream: false, }, stream: false, credentials: { apiKey: "__Secure-authjs.session-token=token" }, signal: AbortSignal.timeout(10000), log: null, }); assert.equal(cap.body.userSelectedModel, "anthropic/claude-opus-4.7"); assert.equal(cap.body.userSelectedAgent, "VscodeAgent"); assert.equal(cap.body.codeModelMode, true); assert.equal(cap.body.maxTokens, 2048); assert.equal(Array.isArray(cap.body.messages), true); assert.match(String((cap.body.messages as any[])[0].content), /System instructions:/); } finally { cap.restore(); } }); test("Provider registry: blackbox-web models are exposed", async () => { const { getModelsByProviderId } = await import("../../open-sse/config/providerModels.ts"); const models = getModelsByProviderId("blackbox-web"); // blackbox-web was removed from the registry in v3.7.0 merge // If it gets re-added, also add: assert.equal(PROVIDER_ID_TO_ALIAS["blackbox-web"], "bb-web"); if (models && models.length > 0) { const ids = models.map((model: any) => model.id); assert.ok(ids.includes("gpt-4")); assert.ok(ids.includes("claude-3-opus")); } // If not present, skip assertions - provider may have been temporarily removed });