refactor(providers): share completions format defaults

This commit is contained in:
Vincent Koc
2026-04-04 02:17:52 +09:00
parent 39a16c600f
commit ff68fd3060
3 changed files with 25 additions and 13 deletions

View File

@@ -157,6 +157,19 @@ describe("normalizeModelCompat", () => {
});
});
it("keeps supportsUsageInStreaming on for native ModelStudio endpoints", () => {
const model = {
...baseModel(),
provider: "modelstudio",
baseUrl: "https://dashscope-intl.aliyuncs.com/compatible-mode/v1",
};
delete (model as { compat?: unknown }).compat;
const normalized = normalizeModelCompat(model);
expect(supportsDeveloperRole(normalized)).toBe(false);
expect(supportsUsageInStreaming(normalized)).toBe(true);
expect(supportsStrictMode(normalized)).toBe(false);
});
it("leaves native api.openai.com model untouched", () => {
const model = {
...baseModel(),

View File

@@ -13,6 +13,8 @@ export type OpenAICompletionsCompatDefaults = {
supportsDeveloperRole: boolean;
supportsReasoningEffort: boolean;
supportsUsageInStreaming: boolean;
maxTokensField: "max_completion_tokens" | "max_tokens";
thinkingFormat: "openai" | "openrouter" | "zai";
supportsStrictMode: boolean;
};
@@ -50,6 +52,12 @@ export function resolveOpenAICompletionsCompatDefaults(
isZai ||
(isDefaultRoute &&
isDefaultRouteProvider(input.provider, "cerebras", "chutes", "deepseek", "opencode", "xai"));
const isOpenRouterLike = input.provider === "openrouter" || endpointClass === "openrouter";
const usesMaxTokens =
endpointClass === "chutes-native" ||
endpointClass === "mistral-public" ||
knownProviderFamily === "mistral" ||
(isDefaultRoute && isDefaultRouteProvider(input.provider, "chutes"));
return {
supportsStore:
@@ -62,6 +70,8 @@ export function resolveOpenAICompletionsCompatDefaults(
!usesExplicitProxyLikeEndpoint,
supportsUsageInStreaming:
!isNonStandard && (!usesConfiguredNonOpenAIEndpoint || supportsNativeStreamingUsageCompat),
maxTokensField: usesMaxTokens ? "max_tokens" : "max_completion_tokens",
thinkingFormat: isZai ? "zai" : isOpenRouterLike ? "openrouter" : "openai",
supportsStrictMode: !isZai && !usesConfiguredNonOpenAIEndpoint,
};
}

View File

@@ -1346,11 +1346,6 @@ function detectCompat(model: OpenAIModeModel) {
provider,
...capabilities,
});
const isMistral =
capabilities.knownProviderFamily === "mistral" || endpointClass === "mistral-public";
const isZai = endpointClass === "zai-native" || (isDefaultRoute && provider === "zai");
const useMaxTokens =
endpointClass === "chutes-native" || (isDefaultRoute && provider === "chutes") || isMistral;
const isGroq = endpointClass === "groq-native" || (isDefaultRoute && provider === "groq");
const reasoningEffortMap: Record<string, string> =
isGroq && model.id === "qwen/qwen3-32b"
@@ -1368,17 +1363,11 @@ function detectCompat(model: OpenAIModeModel) {
supportsReasoningEffort: compatDefaults.supportsReasoningEffort,
reasoningEffortMap,
supportsUsageInStreaming: compatDefaults.supportsUsageInStreaming,
maxTokensField: useMaxTokens ? "max_tokens" : "max_completion_tokens",
maxTokensField: compatDefaults.maxTokensField,
requiresToolResultName: false,
requiresAssistantAfterToolResult: false,
requiresThinkingAsText: false,
thinkingFormat: isZai
? "zai"
: provider === "openrouter" ||
capabilities.endpointClass === "openrouter" ||
capabilities.attributionProvider === "openrouter"
? "openrouter"
: "openai",
thinkingFormat: compatDefaults.thinkingFormat,
openRouterRouting: {},
vercelGatewayRouting: {},
supportsStrictMode: compatDefaults.supportsStrictMode,