refactor(providers): share openai compat defaults

This commit is contained in:
Vincent Koc
2026-04-04 02:06:34 +09:00
parent c5a45eb274
commit 50d85dcd59
3 changed files with 108 additions and 37 deletions

View File

@@ -0,0 +1,58 @@
import type { ProviderEndpointClass, ProviderRequestCapabilities } from "./provider-attribution.js";
type OpenAICompletionsCompatDefaultsInput = {
provider?: string;
endpointClass: ProviderEndpointClass;
knownProviderFamily: string;
};
export type OpenAICompletionsCompatDefaults = {
supportsDeveloperRole: boolean;
supportsUsageInStreaming: boolean;
supportsStrictMode: boolean;
};
function isDefaultRouteProvider(provider: string | undefined, ...ids: string[]) {
return provider !== undefined && ids.includes(provider);
}
export function resolveOpenAICompletionsCompatDefaults(
input: OpenAICompletionsCompatDefaultsInput,
): OpenAICompletionsCompatDefaults {
const { endpointClass, knownProviderFamily } = input;
const isDefaultRoute = endpointClass === "default";
const usesConfiguredNonOpenAIEndpoint =
endpointClass !== "default" && endpointClass !== "openai-public";
const isMoonshotLike =
knownProviderFamily === "moonshot" ||
knownProviderFamily === "modelstudio" ||
endpointClass === "moonshot-native" ||
endpointClass === "modelstudio-native";
const isZai =
endpointClass === "zai-native" ||
(isDefaultRoute && isDefaultRouteProvider(input.provider, "zai"));
const isNonStandard =
endpointClass === "cerebras-native" ||
endpointClass === "chutes-native" ||
endpointClass === "deepseek-native" ||
endpointClass === "mistral-public" ||
endpointClass === "opencode-native" ||
endpointClass === "xai-native" ||
isZai ||
(isDefaultRoute &&
isDefaultRouteProvider(input.provider, "cerebras", "chutes", "deepseek", "opencode", "xai"));
return {
supportsDeveloperRole: !isNonStandard && !isMoonshotLike && !usesConfiguredNonOpenAIEndpoint,
supportsUsageInStreaming: !isNonStandard && !usesConfiguredNonOpenAIEndpoint,
supportsStrictMode: !isZai && !usesConfiguredNonOpenAIEndpoint,
};
}
export function resolveOpenAICompletionsCompatDefaultsFromCapabilities(
input: Pick<ProviderRequestCapabilities, "endpointClass" | "knownProviderFamily"> & {
provider?: string;
},
): OpenAICompletionsCompatDefaults {
return resolveOpenAICompletionsCompatDefaults(input);
}

View File

@@ -19,6 +19,7 @@ import type {
ResponseInputMessageContentList,
} from "openai/resources/responses/responses.js";
import { fetchWithSsrFGuard } from "../infra/net/fetch-guard.js";
import { resolveOpenAICompletionsCompatDefaultsFromCapabilities } from "./openai-completions-compat.js";
import { resolveProviderRequestCapabilities } from "./provider-attribution.js";
import {
buildProviderRequestDispatcherPolicy,
@@ -1341,30 +1342,13 @@ function detectCompat(model: OpenAIModeModel) {
});
const endpointClass = capabilities.endpointClass;
const isDefaultRoute = endpointClass === "default";
const usesConfiguredNonOpenAIEndpoint =
endpointClass !== "default" && endpointClass !== "openai-public";
const compatDefaults = resolveOpenAICompletionsCompatDefaultsFromCapabilities({
provider,
...capabilities,
});
const isMistral =
capabilities.knownProviderFamily === "mistral" || endpointClass === "mistral-public";
const isMoonshotLike =
capabilities.knownProviderFamily === "moonshot" ||
capabilities.knownProviderFamily === "modelstudio" ||
endpointClass === "moonshot-native" ||
endpointClass === "modelstudio-native";
const isZai = endpointClass === "zai-native" || (isDefaultRoute && provider === "zai");
const isNonStandard =
endpointClass === "cerebras-native" ||
endpointClass === "chutes-native" ||
endpointClass === "deepseek-native" ||
isMistral ||
endpointClass === "opencode-native" ||
endpointClass === "xai-native" ||
isZai ||
(isDefaultRoute &&
(provider === "cerebras" ||
provider === "chutes" ||
provider === "deepseek" ||
provider === "opencode" ||
provider === "xai"));
const useMaxTokens =
endpointClass === "chutes-native" || (isDefaultRoute && provider === "chutes") || isMistral;
const isGrok = endpointClass === "xai-native" || (isDefaultRoute && provider === "xai");
@@ -1380,11 +1364,26 @@ function detectCompat(model: OpenAIModeModel) {
}
: {};
return {
supportsStore: !isNonStandard,
supportsDeveloperRole: !isNonStandard && !isMoonshotLike && !usesConfiguredNonOpenAIEndpoint,
supportsStore:
endpointClass !== "cerebras-native" &&
endpointClass !== "chutes-native" &&
endpointClass !== "deepseek-native" &&
!isMistral &&
endpointClass !== "opencode-native" &&
endpointClass !== "xai-native" &&
!isZai &&
!(
isDefaultRoute &&
(provider === "cerebras" ||
provider === "chutes" ||
provider === "deepseek" ||
provider === "opencode" ||
provider === "xai")
),
supportsDeveloperRole: compatDefaults.supportsDeveloperRole,
supportsReasoningEffort: !isGrok && !isMistral && !isZai,
reasoningEffortMap,
supportsUsageInStreaming: !isNonStandard && !usesConfiguredNonOpenAIEndpoint,
supportsUsageInStreaming: compatDefaults.supportsUsageInStreaming,
maxTokensField: useMaxTokens ? "max_tokens" : "max_completion_tokens",
requiresToolResultName: false,
requiresAssistantAfterToolResult: false,
@@ -1398,7 +1397,7 @@ function detectCompat(model: OpenAIModeModel) {
: "openai",
openRouterRouting: {},
vercelGatewayRouting: {},
supportsStrictMode: !isZai && !usesConfiguredNonOpenAIEndpoint,
supportsStrictMode: compatDefaults.supportsStrictMode,
};
}

View File

@@ -1,4 +1,5 @@
import type { Api, Model } from "@mariozechner/pi-ai";
import { resolveOpenAICompletionsCompatDefaultsFromCapabilities } from "../agents/openai-completions-compat.js";
import { resolveProviderRequestCapabilities } from "../agents/provider-attribution.js";
import type { ModelCompatConfig } from "../config/types.models.js";
@@ -92,21 +93,30 @@ export function normalizeModelCompat(model: Model<Api>): Model<Api> {
}
const compat = model.compat ?? undefined;
const needsForce = baseUrl
? resolveProviderRequestCapabilities({
const detectedCompatDefaults = baseUrl
? resolveOpenAICompletionsCompatDefaultsFromCapabilities({
provider: typeof model.provider === "string" ? model.provider : undefined,
api: model.api,
baseUrl,
capability: "llm",
transport: "stream",
}).endpointClass !== "openai-public"
: false;
...resolveProviderRequestCapabilities({
provider: typeof model.provider === "string" ? model.provider : undefined,
api: model.api,
baseUrl,
capability: "llm",
transport: "stream",
}),
})
: undefined;
const needsForce = Boolean(
detectedCompatDefaults &&
(!detectedCompatDefaults.supportsDeveloperRole ||
!detectedCompatDefaults.supportsUsageInStreaming ||
!detectedCompatDefaults.supportsStrictMode),
);
if (!needsForce) {
return model;
}
const forcedDeveloperRole = compat?.supportsDeveloperRole === true;
const hasStreamingUsageOverride = compat?.supportsUsageInStreaming !== undefined;
const targetStrictMode = compat?.supportsStrictMode ?? false;
const targetStrictMode = compat?.supportsStrictMode ?? detectedCompatDefaults?.supportsStrictMode;
if (
compat?.supportsDeveloperRole !== undefined &&
hasStreamingUsageOverride &&
@@ -121,13 +131,17 @@ export function normalizeModelCompat(model: Model<Api>): Model<Api> {
? {
...compat,
supportsDeveloperRole: forcedDeveloperRole || false,
...(hasStreamingUsageOverride ? {} : { supportsUsageInStreaming: false }),
...(hasStreamingUsageOverride
? {}
: {
supportsUsageInStreaming: detectedCompatDefaults?.supportsUsageInStreaming ?? false,
}),
supportsStrictMode: targetStrictMode,
}
: {
supportsDeveloperRole: false,
supportsUsageInStreaming: false,
supportsStrictMode: false,
supportsUsageInStreaming: detectedCompatDefaults?.supportsUsageInStreaming ?? false,
supportsStrictMode: detectedCompatDefaults?.supportsStrictMode ?? false,
},
} as typeof model;
}