refactor(open-sse): D1c — forceStream hardcode → PROVIDERS schema (#5)
chatCore providerRequiresStreaming: switch provider-name → PROVIDERS[provider].forceStream. Thêm forceStream:true vào registry openai/codex/commandcode. verify-providers allowlist added-fields (forceStream/urlSuffix verified bằng golden + runtime test riêng). Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -7,6 +7,7 @@ import { createStreamController } from "../utils/streamHandler.js";
|
|||||||
import { refreshWithRetry } from "../services/tokenRefresh.js";
|
import { refreshWithRetry } from "../services/tokenRefresh.js";
|
||||||
import { createRequestLogger } from "../utils/requestLogger.js";
|
import { createRequestLogger } from "../utils/requestLogger.js";
|
||||||
import { getModelTargetFormat, getModelStrip, getModelUpstreamId, getModelType, PROVIDER_ID_TO_ALIAS } from "../config/providerModels.js";
|
import { getModelTargetFormat, getModelStrip, getModelUpstreamId, getModelType, PROVIDER_ID_TO_ALIAS } from "../config/providerModels.js";
|
||||||
|
import { PROVIDERS } from "../config/providers.js";
|
||||||
import { createErrorResult, parseUpstreamError, formatProviderError } from "../utils/error.js";
|
import { createErrorResult, parseUpstreamError, formatProviderError } from "../utils/error.js";
|
||||||
import { HTTP_STATUS } from "../config/runtimeConfig.js";
|
import { HTTP_STATUS } from "../config/runtimeConfig.js";
|
||||||
import { handleBypassRequest } from "../utils/bypassHandler.js";
|
import { handleBypassRequest } from "../utils/bypassHandler.js";
|
||||||
@@ -59,7 +60,7 @@ export async function handleChatCore({ body, modelInfo, credentials, log, onCred
|
|||||||
}
|
}
|
||||||
|
|
||||||
const clientRequestedStreaming = body.stream === true || sourceFormat === FORMATS.ANTIGRAVITY || sourceFormat === FORMATS.GEMINI || sourceFormat === FORMATS.GEMINI_CLI;
|
const clientRequestedStreaming = body.stream === true || sourceFormat === FORMATS.ANTIGRAVITY || sourceFormat === FORMATS.GEMINI || sourceFormat === FORMATS.GEMINI_CLI;
|
||||||
const providerRequiresStreaming = provider === "openai" || provider === "codex" || provider === "commandcode";
|
const providerRequiresStreaming = PROVIDERS[provider]?.forceStream === true;
|
||||||
let stream = providerRequiresStreaming ? true : (body.stream !== false);
|
let stream = providerRequiresStreaming ? true : (body.stream !== false);
|
||||||
|
|
||||||
// DeepSeek-TUI: interactive TUI panel sends stream:true and needs SSE.
|
// DeepSeek-TUI: interactive TUI panel sends stream:true and needs SSE.
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ export default {
|
|||||||
transport: {
|
transport: {
|
||||||
baseUrl: "https://chatgpt.com/backend-api/codex/responses",
|
baseUrl: "https://chatgpt.com/backend-api/codex/responses",
|
||||||
format: "openai-responses",
|
format: "openai-responses",
|
||||||
|
forceStream: true,
|
||||||
headers: {
|
headers: {
|
||||||
"originator": "codex_cli_rs",
|
"originator": "codex_cli_rs",
|
||||||
"User-Agent": "codex_cli_rs/0.136.0"
|
"User-Agent": "codex_cli_rs/0.136.0"
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ export default {
|
|||||||
"transport": {
|
"transport": {
|
||||||
"baseUrl": "https://api.commandcode.ai/alpha/generate",
|
"baseUrl": "https://api.commandcode.ai/alpha/generate",
|
||||||
"format": "commandcode",
|
"format": "commandcode",
|
||||||
|
"forceStream": true,
|
||||||
"headers": {
|
"headers": {
|
||||||
"x-command-code-version": "0.25.7",
|
"x-command-code-version": "0.25.7",
|
||||||
"x-cli-environment": "cli"
|
"x-cli-environment": "cli"
|
||||||
|
|||||||
@@ -2,7 +2,8 @@ export default {
|
|||||||
"id": "openai",
|
"id": "openai",
|
||||||
"alias": "openai",
|
"alias": "openai",
|
||||||
"transport": {
|
"transport": {
|
||||||
"baseUrl": "https://api.openai.com/v1/chat/completions"
|
"baseUrl": "https://api.openai.com/v1/chat/completions",
|
||||||
|
"forceStream": true
|
||||||
},
|
},
|
||||||
"models": [
|
"models": [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -8,8 +8,14 @@ import { PROVIDERS } from "../../open-sse/config/providers.js";
|
|||||||
const here = dirname(fileURLToPath(import.meta.url));
|
const here = dirname(fileURLToPath(import.meta.url));
|
||||||
const baseline = JSON.parse(readFileSync(join(here, "providers-baseline.json"), "utf8"));
|
const baseline = JSON.parse(readFileSync(join(here, "providers-baseline.json"), "utf8"));
|
||||||
|
|
||||||
// Normalize via JSON roundtrip so function/undefined are dropped identically.
|
// Fields intentionally added during refactor (verified by dedicated runtime tests, not byte-baseline).
|
||||||
|
const ADDED_FIELDS = new Set(["forceStream", "urlSuffix"]);
|
||||||
|
|
||||||
|
// Normalize via JSON roundtrip so function/undefined are dropped identically; drop added fields.
|
||||||
const current = JSON.parse(JSON.stringify(PROVIDERS));
|
const current = JSON.parse(JSON.stringify(PROVIDERS));
|
||||||
|
for (const id of Object.keys(current)) {
|
||||||
|
for (const f of ADDED_FIELDS) delete current[id][f];
|
||||||
|
}
|
||||||
|
|
||||||
const diffs = [];
|
const diffs = [];
|
||||||
const allIds = new Set([...Object.keys(baseline), ...Object.keys(current)]);
|
const allIds = new Set([...Object.keys(baseline), ...Object.keys(current)]);
|
||||||
|
|||||||
17
tests/unit/force-stream-config.test.js
Normal file
17
tests/unit/force-stream-config.test.js
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
// Guards forceStream moved from chatCore hardcode → PROVIDERS schema (#5).
|
||||||
|
import { describe, it, expect } from "vitest";
|
||||||
|
|
||||||
|
const FORCED = ["openai", "codex", "commandcode"];
|
||||||
|
|
||||||
|
describe("forceStream provider config", () => {
|
||||||
|
it("only openai/codex/commandcode force streaming", async () => {
|
||||||
|
const { PROVIDERS } = await import("../../open-sse/config/providers.js");
|
||||||
|
for (const id of FORCED) {
|
||||||
|
expect(PROVIDERS[id]?.forceStream, `${id} forced`).toBe(true);
|
||||||
|
}
|
||||||
|
// a sample of others must NOT force
|
||||||
|
for (const id of ["deepseek", "claude", "gemini", "openrouter"]) {
|
||||||
|
expect(PROVIDERS[id]?.forceStream, `${id} not forced`).not.toBe(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user