fix(openai): share responses stream hook family

This commit is contained in:
Vincent Koc
2026-04-14 16:28:58 +01:00
parent 60961a7f55
commit a14f7c5c6d
4 changed files with 13 additions and 6 deletions

View File

@@ -17,7 +17,6 @@ import {
normalizeProviderId,
type ProviderPlugin,
} from "openclaw/plugin-sdk/provider-model-shared";
import { buildProviderStreamFamilyHooks } from "openclaw/plugin-sdk/provider-stream-family";
import { fetchCodexUsage } from "openclaw/plugin-sdk/provider-usage";
import { normalizeLowercaseStringOrEmpty, readStringValue } from "openclaw/plugin-sdk/text-runtime";
import { OPENAI_CODEX_DEFAULT_MODEL } from "./default-models.js";
@@ -33,6 +32,7 @@ import {
isOpenAIApiBaseUrl,
isOpenAICodexBaseUrl,
matchesExactOrPrefix,
OPENAI_RESPONSES_STREAM_HOOKS,
} from "./shared.js";
import {
resolveOpenAITransportTurnState,
@@ -101,8 +101,6 @@ const OPENAI_CODEX_MODERN_MODEL_IDS = [
OPENAI_CODEX_GPT_53_MODEL_ID,
OPENAI_CODEX_GPT_53_SPARK_MODEL_ID,
] as const;
const OPENAI_RESPONSES_STREAM_HOOKS = buildProviderStreamFamilyHooks("openai-responses-defaults");
function normalizeCodexTransport(model: ProviderRuntimeModel): ProviderRuntimeModel {
const lowerModelId = normalizeLowercaseStringOrEmpty(model.id);
const canonicalModelId =

View File

@@ -398,6 +398,13 @@ describe("buildOpenAIProvider", () => {
).toBe(explicit);
});
it("shares OpenAI responses wrapper composition across provider variants", () => {
const provider = buildOpenAIProvider();
const codexProvider = buildOpenAICodexProviderPlugin();
expect(provider.wrapStreamFn).toBe(codexProvider.wrapStreamFn);
});
it("owns Azure OpenAI reasoning compatibility without forcing OpenAI transport defaults", () => {
const provider = buildOpenAIProvider();
const wrap = provider.wrapStreamFn;

View File

@@ -9,7 +9,6 @@ import {
normalizeProviderId,
type ProviderPlugin,
} from "openclaw/plugin-sdk/provider-model-shared";
import { buildProviderStreamFamilyHooks } from "openclaw/plugin-sdk/provider-stream-family";
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime";
import { applyOpenAIConfig, OPENAI_DEFAULT_MODEL } from "./default-models.js";
import { buildOpenAIReplayPolicy } from "./replay-policy.js";
@@ -20,6 +19,7 @@ import {
findCatalogTemplate,
isOpenAIApiBaseUrl,
matchesExactOrPrefix,
OPENAI_RESPONSES_STREAM_HOOKS,
} from "./shared.js";
import {
resolveOpenAITransportTurnState,
@@ -70,8 +70,6 @@ const OPENAI_MODERN_MODEL_IDS = [
] as const;
const OPENAI_DIRECT_SPARK_MODEL_ID = "gpt-5.3-codex-spark";
const SUPPRESSED_SPARK_PROVIDERS = new Set(["openai", "azure-openai-responses"]);
const OPENAI_RESPONSES_STREAM_HOOKS = buildProviderStreamFamilyHooks("openai-responses-defaults");
function shouldUseOpenAIResponsesTransport(params: {
provider: string;
api?: string | null;

View File

@@ -4,6 +4,7 @@ import {
cloneFirstTemplateModel,
matchesExactOrPrefix,
} from "openclaw/plugin-sdk/provider-model-shared";
import { buildProviderStreamFamilyHooks } from "openclaw/plugin-sdk/provider-stream-family";
import { normalizeOptionalString } from "openclaw/plugin-sdk/text-runtime";
type SyntheticOpenAIModelCatalogCost = {
@@ -25,6 +26,9 @@ type SyntheticOpenAIModelCatalogEntry = {
};
export const OPENAI_API_BASE_URL = "https://api.openai.com/v1";
export const OPENAI_RESPONSES_STREAM_HOOKS = buildProviderStreamFamilyHooks(
"openai-responses-defaults",
);
export function toOpenAIDataUrl(buffer: Buffer, mimeType: string): string {
return `data:${mimeType};base64,${buffer.toString("base64")}`;