@gajae-code/ai 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +2644 -0
- package/README.md +1181 -0
- package/dist/types/api-registry.d.ts +30 -0
- package/dist/types/auth-broker/client.d.ts +66 -0
- package/dist/types/auth-broker/index.d.ts +5 -0
- package/dist/types/auth-broker/refresher.d.ts +25 -0
- package/dist/types/auth-broker/remote-store.d.ts +96 -0
- package/dist/types/auth-broker/server.d.ts +32 -0
- package/dist/types/auth-broker/types.d.ts +105 -0
- package/dist/types/auth-broker/wire-schemas.d.ts +412 -0
- package/dist/types/auth-gateway/http.d.ts +39 -0
- package/dist/types/auth-gateway/index.d.ts +3 -0
- package/dist/types/auth-gateway/server.d.ts +17 -0
- package/dist/types/auth-gateway/types.d.ts +115 -0
- package/dist/types/auth-storage.d.ts +641 -0
- package/dist/types/cli.d.ts +2 -0
- package/dist/types/index.d.ts +49 -0
- package/dist/types/model-cache.d.ts +17 -0
- package/dist/types/model-manager.d.ts +62 -0
- package/dist/types/model-thinking.d.ts +71 -0
- package/dist/types/models.d.ts +12 -0
- package/dist/types/provider-details.d.ts +24 -0
- package/dist/types/provider-models/bundled-references.d.ts +4 -0
- package/dist/types/provider-models/descriptors.d.ts +48 -0
- package/dist/types/provider-models/google.d.ts +20 -0
- package/dist/types/provider-models/index.d.ts +5 -0
- package/dist/types/provider-models/ollama.d.ts +7 -0
- package/dist/types/provider-models/openai-compat.d.ts +237 -0
- package/dist/types/provider-models/special.d.ts +16 -0
- package/dist/types/providers/amazon-bedrock.d.ts +36 -0
- package/dist/types/providers/anthropic-messages-server-schema.d.ts +450 -0
- package/dist/types/providers/anthropic-messages-server.d.ts +17 -0
- package/dist/types/providers/anthropic.d.ts +188 -0
- package/dist/types/providers/aws-credentials.d.ts +43 -0
- package/dist/types/providers/aws-eventstream.d.ts +38 -0
- package/dist/types/providers/aws-sigv4.d.ts +55 -0
- package/dist/types/providers/azure-openai-responses.d.ts +15 -0
- package/dist/types/providers/cursor/gen/agent_pb.d.ts +13022 -0
- package/dist/types/providers/cursor.d.ts +42 -0
- package/dist/types/providers/error-message.d.ts +27 -0
- package/dist/types/providers/github-copilot-headers.d.ts +40 -0
- package/dist/types/providers/gitlab-duo.d.ts +27 -0
- package/dist/types/providers/google-auth.d.ts +24 -0
- package/dist/types/providers/google-gemini-cli.d.ts +72 -0
- package/dist/types/providers/google-gemini-headers.d.ts +18 -0
- package/dist/types/providers/google-shared.d.ts +163 -0
- package/dist/types/providers/google-types.d.ts +138 -0
- package/dist/types/providers/google-vertex.d.ts +7 -0
- package/dist/types/providers/google.d.ts +4 -0
- package/dist/types/providers/grammar.d.ts +1 -0
- package/dist/types/providers/kimi.d.ts +27 -0
- package/dist/types/providers/mock.d.ts +175 -0
- package/dist/types/providers/ollama.d.ts +6 -0
- package/dist/types/providers/openai-anthropic-shim.d.ts +31 -0
- package/dist/types/providers/openai-chat-server-schema.d.ts +814 -0
- package/dist/types/providers/openai-chat-server.d.ts +16 -0
- package/dist/types/providers/openai-codex/constants.d.ts +26 -0
- package/dist/types/providers/openai-codex/request-transformer.d.ts +49 -0
- package/dist/types/providers/openai-codex/response-handler.d.ts +17 -0
- package/dist/types/providers/openai-codex-responses.d.ts +67 -0
- package/dist/types/providers/openai-completions-compat.d.ts +25 -0
- package/dist/types/providers/openai-completions.d.ts +33 -0
- package/dist/types/providers/openai-responses-server-schema.d.ts +392 -0
- package/dist/types/providers/openai-responses-server.d.ts +17 -0
- package/dist/types/providers/openai-responses-shared.d.ts +89 -0
- package/dist/types/providers/openai-responses.d.ts +32 -0
- package/dist/types/providers/pi-native-client.d.ts +13 -0
- package/dist/types/providers/pi-native-server.d.ts +68 -0
- package/dist/types/providers/register-builtins.d.ts +31 -0
- package/dist/types/providers/synthetic.d.ts +26 -0
- package/dist/types/providers/transform-messages.d.ts +12 -0
- package/dist/types/providers/vision-guard.d.ts +8 -0
- package/dist/types/rate-limit-utils.d.ts +19 -0
- package/dist/types/stream.d.ts +24 -0
- package/dist/types/types.d.ts +746 -0
- package/dist/types/usage/claude.d.ts +3 -0
- package/dist/types/usage/gemini.d.ts +2 -0
- package/dist/types/usage/github-copilot.d.ts +7 -0
- package/dist/types/usage/google-antigravity.d.ts +2 -0
- package/dist/types/usage/kimi.d.ts +2 -0
- package/dist/types/usage/minimax-code.d.ts +2 -0
- package/dist/types/usage/openai-codex.d.ts +3 -0
- package/dist/types/usage/shared.d.ts +1 -0
- package/dist/types/usage/zai.d.ts +2 -0
- package/dist/types/usage.d.ts +258 -0
- package/dist/types/utils/abort.d.ts +19 -0
- package/dist/types/utils/anthropic-auth.d.ts +31 -0
- package/dist/types/utils/discovery/antigravity.d.ts +61 -0
- package/dist/types/utils/discovery/codex.d.ts +38 -0
- package/dist/types/utils/discovery/cursor.d.ts +23 -0
- package/dist/types/utils/discovery/gemini.d.ts +25 -0
- package/dist/types/utils/discovery/index.d.ts +4 -0
- package/dist/types/utils/discovery/openai-compatible.d.ts +72 -0
- package/dist/types/utils/event-stream.d.ts +28 -0
- package/dist/types/utils/fireworks-model-id.d.ts +10 -0
- package/dist/types/utils/foundry.d.ts +1 -0
- package/dist/types/utils/h2-fetch.d.ts +22 -0
- package/dist/types/utils/http-inspector.d.ts +31 -0
- package/dist/types/utils/idle-iterator.d.ts +67 -0
- package/dist/types/utils/json-parse.d.ts +10 -0
- package/dist/types/utils/oauth/alibaba-coding-plan.d.ts +18 -0
- package/dist/types/utils/oauth/anthropic.d.ts +22 -0
- package/dist/types/utils/oauth/api-key-login.d.ts +35 -0
- package/dist/types/utils/oauth/api-key-validation.d.ts +27 -0
- package/dist/types/utils/oauth/callback-server.d.ts +57 -0
- package/dist/types/utils/oauth/cerebras.d.ts +1 -0
- package/dist/types/utils/oauth/cloudflare-ai-gateway.d.ts +18 -0
- package/dist/types/utils/oauth/cursor.d.ts +15 -0
- package/dist/types/utils/oauth/deepseek.d.ts +10 -0
- package/dist/types/utils/oauth/firepass.d.ts +1 -0
- package/dist/types/utils/oauth/fireworks.d.ts +1 -0
- package/dist/types/utils/oauth/github-copilot.d.ts +38 -0
- package/dist/types/utils/oauth/gitlab-duo.d.ts +3 -0
- package/dist/types/utils/oauth/google-antigravity.d.ts +11 -0
- package/dist/types/utils/oauth/google-gemini-cli.d.ts +10 -0
- package/dist/types/utils/oauth/google-oauth-shared.d.ts +28 -0
- package/dist/types/utils/oauth/huggingface.d.ts +19 -0
- package/dist/types/utils/oauth/index.d.ts +38 -0
- package/dist/types/utils/oauth/kagi.d.ts +17 -0
- package/dist/types/utils/oauth/kilo.d.ts +5 -0
- package/dist/types/utils/oauth/kimi.d.ts +21 -0
- package/dist/types/utils/oauth/litellm.d.ts +18 -0
- package/dist/types/utils/oauth/lm-studio.d.ts +17 -0
- package/dist/types/utils/oauth/minimax-code.d.ts +28 -0
- package/dist/types/utils/oauth/moonshot.d.ts +1 -0
- package/dist/types/utils/oauth/nanogpt.d.ts +1 -0
- package/dist/types/utils/oauth/nvidia.d.ts +18 -0
- package/dist/types/utils/oauth/ollama-cloud.d.ts +2 -0
- package/dist/types/utils/oauth/ollama.d.ts +18 -0
- package/dist/types/utils/oauth/openai-codex.d.ts +21 -0
- package/dist/types/utils/oauth/opencode.d.ts +18 -0
- package/dist/types/utils/oauth/parallel.d.ts +17 -0
- package/dist/types/utils/oauth/perplexity.d.ts +9 -0
- package/dist/types/utils/oauth/pkce.d.ts +8 -0
- package/dist/types/utils/oauth/qianfan.d.ts +17 -0
- package/dist/types/utils/oauth/qwen-portal.d.ts +19 -0
- package/dist/types/utils/oauth/synthetic.d.ts +1 -0
- package/dist/types/utils/oauth/tavily.d.ts +17 -0
- package/dist/types/utils/oauth/together.d.ts +1 -0
- package/dist/types/utils/oauth/types.d.ts +44 -0
- package/dist/types/utils/oauth/venice.d.ts +18 -0
- package/dist/types/utils/oauth/vercel-ai-gateway.d.ts +18 -0
- package/dist/types/utils/oauth/vllm.d.ts +16 -0
- package/dist/types/utils/oauth/xiaomi.d.ts +19 -0
- package/dist/types/utils/oauth/zai.d.ts +18 -0
- package/dist/types/utils/oauth/zenmux.d.ts +1 -0
- package/dist/types/utils/overflow.d.ts +54 -0
- package/dist/types/utils/parse-bind.d.ts +23 -0
- package/dist/types/utils/provider-response.d.ts +3 -0
- package/dist/types/utils/retry-after.d.ts +3 -0
- package/dist/types/utils/retry.d.ts +26 -0
- package/dist/types/utils/schema/adapt.d.ts +24 -0
- package/dist/types/utils/schema/compatibility.d.ts +30 -0
- package/dist/types/utils/schema/dereference.d.ts +11 -0
- package/dist/types/utils/schema/draft.d.ts +10 -0
- package/dist/types/utils/schema/equality.d.ts +4 -0
- package/dist/types/utils/schema/fields.d.ts +49 -0
- package/dist/types/utils/schema/index.d.ts +13 -0
- package/dist/types/utils/schema/json-schema-validator.d.ts +12 -0
- package/dist/types/utils/schema/meta-validator.d.ts +2 -0
- package/dist/types/utils/schema/normalize.d.ts +93 -0
- package/dist/types/utils/schema/spill.d.ts +8 -0
- package/dist/types/utils/schema/stamps.d.ts +25 -0
- package/dist/types/utils/schema/types.d.ts +4 -0
- package/dist/types/utils/schema/wire.d.ts +54 -0
- package/dist/types/utils/schema/zod-decontaminate.d.ts +31 -0
- package/dist/types/utils/sse-debug.d.ts +10 -0
- package/dist/types/utils/tool-call-healing.d.ts +71 -0
- package/dist/types/utils/tool-choice.d.ts +50 -0
- package/dist/types/utils/validation.d.ts +17 -0
- package/dist/types/utils.d.ts +28 -0
- package/package.json +146 -0
- package/src/api-registry.ts +96 -0
- package/src/auth-broker/client.ts +358 -0
- package/src/auth-broker/index.ts +5 -0
- package/src/auth-broker/refresher.ts +127 -0
- package/src/auth-broker/remote-store.ts +623 -0
- package/src/auth-broker/server.ts +644 -0
- package/src/auth-broker/types.ts +127 -0
- package/src/auth-broker/wire-schemas.ts +200 -0
- package/src/auth-gateway/http.ts +194 -0
- package/src/auth-gateway/index.ts +3 -0
- package/src/auth-gateway/server.ts +717 -0
- package/src/auth-gateway/types.ts +134 -0
- package/src/auth-storage.ts +4104 -0
- package/src/cli.ts +262 -0
- package/src/index.ts +54 -0
- package/src/model-cache.ts +129 -0
- package/src/model-manager.ts +450 -0
- package/src/model-thinking.ts +691 -0
- package/src/models.json +73853 -0
- package/src/models.json.d.ts +9 -0
- package/src/models.ts +56 -0
- package/src/prompts/turn-aborted-guidance.md +4 -0
- package/src/provider-details.ts +90 -0
- package/src/provider-models/bundled-references.ts +38 -0
- package/src/provider-models/descriptors.ts +308 -0
- package/src/provider-models/google.ts +91 -0
- package/src/provider-models/index.ts +5 -0
- package/src/provider-models/ollama.ts +153 -0
- package/src/provider-models/openai-compat.ts +2275 -0
- package/src/provider-models/special.ts +67 -0
- package/src/providers/amazon-bedrock.ts +849 -0
- package/src/providers/anthropic-messages-server-schema.ts +229 -0
- package/src/providers/anthropic-messages-server.ts +677 -0
- package/src/providers/anthropic.ts +2696 -0
- package/src/providers/aws-credentials.ts +501 -0
- package/src/providers/aws-eventstream.ts +185 -0
- package/src/providers/aws-sigv4.ts +218 -0
- package/src/providers/azure-openai-responses.ts +337 -0
- package/src/providers/cursor/gen/agent_pb.ts +15274 -0
- package/src/providers/cursor/proto/agent.proto +3526 -0
- package/src/providers/cursor/proto/buf.gen.yaml +6 -0
- package/src/providers/cursor/proto/buf.yaml +17 -0
- package/src/providers/cursor.ts +2561 -0
- package/src/providers/error-message.ts +21 -0
- package/src/providers/github-copilot-headers.ts +140 -0
- package/src/providers/gitlab-duo.ts +372 -0
- package/src/providers/google-auth.ts +252 -0
- package/src/providers/google-gemini-cli.ts +795 -0
- package/src/providers/google-gemini-headers.ts +41 -0
- package/src/providers/google-shared.ts +902 -0
- package/src/providers/google-types.ts +167 -0
- package/src/providers/google-vertex.ts +88 -0
- package/src/providers/google.ts +41 -0
- package/src/providers/grammar.ts +70 -0
- package/src/providers/kimi.ts +52 -0
- package/src/providers/mock.ts +500 -0
- package/src/providers/ollama.ts +544 -0
- package/src/providers/openai-anthropic-shim.ts +138 -0
- package/src/providers/openai-chat-server-schema.ts +243 -0
- package/src/providers/openai-chat-server.ts +628 -0
- package/src/providers/openai-codex/constants.ts +43 -0
- package/src/providers/openai-codex/request-transformer.ts +161 -0
- package/src/providers/openai-codex/response-handler.ts +81 -0
- package/src/providers/openai-codex-responses.ts +2598 -0
- package/src/providers/openai-completions-compat.ts +279 -0
- package/src/providers/openai-completions.ts +1853 -0
- package/src/providers/openai-responses-server-schema.ts +290 -0
- package/src/providers/openai-responses-server.ts +1183 -0
- package/src/providers/openai-responses-shared.ts +800 -0
- package/src/providers/openai-responses.ts +621 -0
- package/src/providers/pi-native-client.ts +228 -0
- package/src/providers/pi-native-server.ts +210 -0
- package/src/providers/register-builtins.ts +412 -0
- package/src/providers/synthetic.ts +50 -0
- package/src/providers/transform-messages.ts +309 -0
- package/src/providers/vision-guard.ts +31 -0
- package/src/rate-limit-utils.ts +84 -0
- package/src/stream.ts +895 -0
- package/src/types.ts +884 -0
- package/src/usage/claude.ts +431 -0
- package/src/usage/gemini.ts +250 -0
- package/src/usage/github-copilot.ts +421 -0
- package/src/usage/google-antigravity.ts +201 -0
- package/src/usage/kimi.ts +271 -0
- package/src/usage/minimax-code.ts +31 -0
- package/src/usage/openai-codex.ts +503 -0
- package/src/usage/shared.ts +10 -0
- package/src/usage/zai.ts +247 -0
- package/src/usage.ts +183 -0
- package/src/utils/abort.ts +51 -0
- package/src/utils/anthropic-auth.ts +87 -0
- package/src/utils/discovery/antigravity.ts +261 -0
- package/src/utils/discovery/codex.ts +371 -0
- package/src/utils/discovery/cursor.ts +306 -0
- package/src/utils/discovery/gemini.ts +248 -0
- package/src/utils/discovery/index.ts +4 -0
- package/src/utils/discovery/openai-compatible.ts +224 -0
- package/src/utils/event-stream.ts +142 -0
- package/src/utils/fireworks-model-id.ts +30 -0
- package/src/utils/foundry.ts +8 -0
- package/src/utils/h2-fetch.ts +60 -0
- package/src/utils/http-inspector.ts +176 -0
- package/src/utils/idle-iterator.ts +250 -0
- package/src/utils/json-parse.ts +148 -0
- package/src/utils/oauth/alibaba-coding-plan.ts +59 -0
- package/src/utils/oauth/anthropic.ts +200 -0
- package/src/utils/oauth/api-key-login.ts +87 -0
- package/src/utils/oauth/api-key-validation.ts +92 -0
- package/src/utils/oauth/callback-server.ts +276 -0
- package/src/utils/oauth/cerebras.ts +16 -0
- package/src/utils/oauth/cloudflare-ai-gateway.ts +48 -0
- package/src/utils/oauth/cursor.ts +157 -0
- package/src/utils/oauth/deepseek.ts +53 -0
- package/src/utils/oauth/firepass.ts +24 -0
- package/src/utils/oauth/fireworks.ts +15 -0
- package/src/utils/oauth/github-copilot.ts +362 -0
- package/src/utils/oauth/gitlab-duo.ts +123 -0
- package/src/utils/oauth/google-antigravity.ts +200 -0
- package/src/utils/oauth/google-gemini-cli.ts +256 -0
- package/src/utils/oauth/google-oauth-shared.ts +110 -0
- package/src/utils/oauth/huggingface.ts +62 -0
- package/src/utils/oauth/index.ts +444 -0
- package/src/utils/oauth/kagi.ts +47 -0
- package/src/utils/oauth/kilo.ts +87 -0
- package/src/utils/oauth/kimi.ts +254 -0
- package/src/utils/oauth/litellm.ts +47 -0
- package/src/utils/oauth/lm-studio.ts +38 -0
- package/src/utils/oauth/minimax-code.ts +78 -0
- package/src/utils/oauth/moonshot.ts +16 -0
- package/src/utils/oauth/nanogpt.ts +15 -0
- package/src/utils/oauth/nvidia.ts +70 -0
- package/src/utils/oauth/oauth.html +199 -0
- package/src/utils/oauth/ollama-cloud.ts +28 -0
- package/src/utils/oauth/ollama.ts +47 -0
- package/src/utils/oauth/openai-codex.ts +299 -0
- package/src/utils/oauth/opencode.ts +49 -0
- package/src/utils/oauth/parallel.ts +46 -0
- package/src/utils/oauth/perplexity.ts +206 -0
- package/src/utils/oauth/pkce.ts +18 -0
- package/src/utils/oauth/qianfan.ts +58 -0
- package/src/utils/oauth/qwen-portal.ts +60 -0
- package/src/utils/oauth/synthetic.ts +16 -0
- package/src/utils/oauth/tavily.ts +46 -0
- package/src/utils/oauth/together.ts +16 -0
- package/src/utils/oauth/types.ts +94 -0
- package/src/utils/oauth/venice.ts +59 -0
- package/src/utils/oauth/vercel-ai-gateway.ts +47 -0
- package/src/utils/oauth/vllm.ts +40 -0
- package/src/utils/oauth/xiaomi.ts +137 -0
- package/src/utils/oauth/zai.ts +60 -0
- package/src/utils/oauth/zenmux.ts +15 -0
- package/src/utils/overflow.ts +137 -0
- package/src/utils/parse-bind.ts +54 -0
- package/src/utils/provider-response.ts +30 -0
- package/src/utils/retry-after.ts +110 -0
- package/src/utils/retry.ts +54 -0
- package/src/utils/schema/CONSTRAINTS.md +164 -0
- package/src/utils/schema/adapt.ts +36 -0
- package/src/utils/schema/compatibility.ts +435 -0
- package/src/utils/schema/dereference.ts +98 -0
- package/src/utils/schema/draft.ts +341 -0
- package/src/utils/schema/equality.ts +97 -0
- package/src/utils/schema/fields.ts +190 -0
- package/src/utils/schema/index.ts +13 -0
- package/src/utils/schema/json-schema-validator.ts +577 -0
- package/src/utils/schema/meta-validator.ts +167 -0
- package/src/utils/schema/normalize.ts +1588 -0
- package/src/utils/schema/spill.ts +43 -0
- package/src/utils/schema/stamps.ts +97 -0
- package/src/utils/schema/types.ts +11 -0
- package/src/utils/schema/wire.ts +213 -0
- package/src/utils/schema/zod-decontaminate.ts +331 -0
- package/src/utils/sse-debug.ts +289 -0
- package/src/utils/tool-call-healing.ts +271 -0
- package/src/utils/tool-choice.ts +99 -0
- package/src/utils/validation.ts +1019 -0
- package/src/utils.ts +166 -0
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
import type { Model, OpenAICompat } from "../types";
|
|
2
|
+
|
|
3
|
+
type OpenAIReasoningEffort = "minimal" | "low" | "medium" | "high" | "xhigh";
|
|
4
|
+
type ResolvedToolStrictMode = NonNullable<OpenAICompat["toolStrictMode"]> | "mixed";
|
|
5
|
+
|
|
6
|
+
export type ResolvedOpenAICompat = Required<
|
|
7
|
+
Omit<OpenAICompat, "openRouterRouting" | "vercelGatewayRouting" | "extraBody" | "toolStrictMode">
|
|
8
|
+
> & {
|
|
9
|
+
openRouterRouting?: OpenAICompat["openRouterRouting"];
|
|
10
|
+
vercelGatewayRouting?: OpenAICompat["vercelGatewayRouting"];
|
|
11
|
+
extraBody?: OpenAICompat["extraBody"];
|
|
12
|
+
toolStrictMode: ResolvedToolStrictMode;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
function detectStrictModeSupport(provider: string, baseUrl: string): boolean {
|
|
16
|
+
if (
|
|
17
|
+
provider === "openai" ||
|
|
18
|
+
provider === "openrouter" ||
|
|
19
|
+
provider === "cerebras" ||
|
|
20
|
+
provider === "together" ||
|
|
21
|
+
provider === "github-copilot" ||
|
|
22
|
+
provider === "zenmux"
|
|
23
|
+
) {
|
|
24
|
+
return true;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const normalizedBaseUrl = baseUrl.toLowerCase();
|
|
28
|
+
return (
|
|
29
|
+
normalizedBaseUrl.includes("api.openai.com") ||
|
|
30
|
+
normalizedBaseUrl.includes(".openai.azure.com") ||
|
|
31
|
+
normalizedBaseUrl.includes("models.inference.ai.azure.com") ||
|
|
32
|
+
normalizedBaseUrl.includes("api.cerebras.ai") ||
|
|
33
|
+
normalizedBaseUrl.includes("api.together.xyz") ||
|
|
34
|
+
normalizedBaseUrl.includes("openrouter.ai") ||
|
|
35
|
+
normalizedBaseUrl.includes("api.deepseek.com") ||
|
|
36
|
+
normalizedBaseUrl.includes("deepseek.com")
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Detect compatibility settings from provider and baseUrl for known providers.
|
|
42
|
+
* Provider takes precedence over URL-based detection since it's explicitly configured.
|
|
43
|
+
* @param model - The model configuration
|
|
44
|
+
* @param resolvedBaseUrl - Optional resolved base URL (e.g., after GitHub Copilot proxy-ep resolution).
|
|
45
|
+
* If provided, this takes precedence over model.baseUrl for URL-based checks.
|
|
46
|
+
*/
|
|
47
|
+
export function detectOpenAICompat(model: Model<"openai-completions">, resolvedBaseUrl?: string): ResolvedOpenAICompat {
|
|
48
|
+
const provider = model.provider;
|
|
49
|
+
// Use resolvedBaseUrl if provided (e.g., after GitHub Copilot proxy-ep resolution)
|
|
50
|
+
const baseUrl = resolvedBaseUrl ?? model.baseUrl;
|
|
51
|
+
|
|
52
|
+
const isCerebras = provider === "cerebras" || baseUrl.includes("cerebras.ai");
|
|
53
|
+
const isZai = provider === "zai" || baseUrl.includes("api.z.ai");
|
|
54
|
+
const isKilo = provider === "kilo" || baseUrl.includes("api.kilo.ai");
|
|
55
|
+
const isKimiModel = model.id.includes("moonshotai/kimi") || /(^|\/)kimi[-.]/i.test(model.id);
|
|
56
|
+
const isMoonshotKimi =
|
|
57
|
+
isKimiModel &&
|
|
58
|
+
(provider === "moonshot" ||
|
|
59
|
+
provider === "kimi-code" ||
|
|
60
|
+
baseUrl.includes("api.moonshot.ai") ||
|
|
61
|
+
baseUrl.includes("api.kimi.com"));
|
|
62
|
+
const isAnthropicModel =
|
|
63
|
+
provider === "anthropic" ||
|
|
64
|
+
baseUrl.includes("api.anthropic.com") ||
|
|
65
|
+
/(^|\/)claude[-.]/i.test(model.id) ||
|
|
66
|
+
/(^|\/)anthropic\//i.test(model.id);
|
|
67
|
+
const isAlibaba = provider === "alibaba-coding-plan" || baseUrl.includes("dashscope");
|
|
68
|
+
const isQwen = model.id.toLowerCase().includes("qwen");
|
|
69
|
+
// DeepSeek V4 (and other reasoning-capable DeepSeek models) reject follow-up requests in
|
|
70
|
+
// thinking mode unless prior assistant tool-call turns include `reasoning_content`. The
|
|
71
|
+
// upstream model is reachable through many OpenAI-compat hosts (api.deepseek.com, Deepinfra,
|
|
72
|
+
// Kilo, NVIDIA NIM, Zenmux, OpenRouter, …), so we match by model id/name as well as by
|
|
73
|
+
// provider/baseUrl. The flag is gated by `model.reasoning` because the invariant only
|
|
74
|
+
// applies when thinking mode is actually engaged.
|
|
75
|
+
const lowerId = model.id.toLowerCase();
|
|
76
|
+
const lowerName = (model.name ?? "").toLowerCase();
|
|
77
|
+
const isDeepseekFamily =
|
|
78
|
+
provider === "deepseek" ||
|
|
79
|
+
baseUrl.includes("deepseek.com") ||
|
|
80
|
+
lowerId.includes("deepseek") ||
|
|
81
|
+
lowerName.includes("deepseek");
|
|
82
|
+
const isDirectDeepseekApi = provider === "deepseek" || baseUrl.includes("api.deepseek.com");
|
|
83
|
+
const isDirectDeepseekReasoning = isDirectDeepseekApi && isDeepseekFamily && Boolean(model.reasoning);
|
|
84
|
+
const isNonStandard =
|
|
85
|
+
isCerebras ||
|
|
86
|
+
provider === "xai" ||
|
|
87
|
+
baseUrl.includes("api.x.ai") ||
|
|
88
|
+
provider === "mistral" ||
|
|
89
|
+
baseUrl.includes("mistral.ai") ||
|
|
90
|
+
baseUrl.includes("chutes.ai") ||
|
|
91
|
+
baseUrl.includes("deepseek.com") ||
|
|
92
|
+
baseUrl.includes("fireworks.ai") ||
|
|
93
|
+
isAlibaba ||
|
|
94
|
+
isZai ||
|
|
95
|
+
isKilo ||
|
|
96
|
+
isQwen ||
|
|
97
|
+
provider === "opencode-zen" ||
|
|
98
|
+
provider === "opencode-go" ||
|
|
99
|
+
baseUrl.includes("opencode.ai");
|
|
100
|
+
const isOpenCodeProvider = provider === "opencode-go" || provider === "opencode-zen";
|
|
101
|
+
|
|
102
|
+
const useMaxTokens =
|
|
103
|
+
provider === "mistral" ||
|
|
104
|
+
baseUrl.includes("mistral.ai") ||
|
|
105
|
+
baseUrl.includes("chutes.ai") ||
|
|
106
|
+
baseUrl.includes("fireworks.ai") ||
|
|
107
|
+
isDirectDeepseekApi;
|
|
108
|
+
const isGrok = provider === "xai" || baseUrl.includes("api.x.ai");
|
|
109
|
+
const isMistral = provider === "mistral" || baseUrl.includes("mistral.ai");
|
|
110
|
+
|
|
111
|
+
// Hosts whose chat-completions endpoints are known to accept multiple
|
|
112
|
+
// leading `system`/`developer` messages (preferred for KV-cache reuse).
|
|
113
|
+
// Anything outside this allowlist defaults to coalescing because
|
|
114
|
+
// strict chat templates (Qwen 3.5+ via vLLM, MiniMax, etc.) reject
|
|
115
|
+
// follow-up system messages with a 400.
|
|
116
|
+
const isOpenAIHost = provider === "openai" || baseUrl.includes("api.openai.com");
|
|
117
|
+
const isAzureHost =
|
|
118
|
+
provider === "azure" ||
|
|
119
|
+
baseUrl.includes(".openai.azure.com") ||
|
|
120
|
+
baseUrl.includes("models.inference.ai.azure.com") ||
|
|
121
|
+
baseUrl.includes("azure.com/openai");
|
|
122
|
+
const isOpenRouter = provider === "openrouter" || baseUrl.includes("openrouter.ai");
|
|
123
|
+
const isTogether = provider === "together" || baseUrl.includes("api.together.xyz");
|
|
124
|
+
const isFireworks = baseUrl.includes("fireworks.ai");
|
|
125
|
+
const isGroqHost = provider === "groq" || baseUrl.includes("api.groq.com");
|
|
126
|
+
const isCopilotHost = provider === "github-copilot";
|
|
127
|
+
const isZenmuxHost = provider === "zenmux";
|
|
128
|
+
// Endpoints that MUST receive a single system block. MiniMax's OpenAI
|
|
129
|
+
// endpoint returns error 2013 on multiple system messages; Alibaba's
|
|
130
|
+
// Dashscope and Qwen Portal serve Qwen models whose chat template
|
|
131
|
+
// raises "System message must be at the beginning" if any system
|
|
132
|
+
// message appears past index 0.
|
|
133
|
+
const isMiniMaxHost =
|
|
134
|
+
provider === "minimax-code" ||
|
|
135
|
+
provider === "minimax-code-cn" ||
|
|
136
|
+
baseUrl.includes("api.minimax.io") ||
|
|
137
|
+
baseUrl.includes("api.minimaxi.com");
|
|
138
|
+
const isQwenPortal = provider === "qwen-portal" || baseUrl.includes("portal.qwen.ai");
|
|
139
|
+
const supportsMultipleSystemMessagesDefault =
|
|
140
|
+
!isMiniMaxHost &&
|
|
141
|
+
!isAlibaba &&
|
|
142
|
+
!isQwenPortal &&
|
|
143
|
+
(isOpenAIHost ||
|
|
144
|
+
isAzureHost ||
|
|
145
|
+
isOpenRouter ||
|
|
146
|
+
isCerebras ||
|
|
147
|
+
isTogether ||
|
|
148
|
+
isFireworks ||
|
|
149
|
+
isGroqHost ||
|
|
150
|
+
isDeepseekFamily ||
|
|
151
|
+
isMistral ||
|
|
152
|
+
isGrok ||
|
|
153
|
+
isZai ||
|
|
154
|
+
isCopilotHost ||
|
|
155
|
+
isZenmuxHost);
|
|
156
|
+
|
|
157
|
+
const reasoningEffortMap: NonNullable<OpenAICompat["reasoningEffortMap"]> =
|
|
158
|
+
provider === "groq" && model.id === "qwen/qwen3-32b"
|
|
159
|
+
? ({
|
|
160
|
+
minimal: "default",
|
|
161
|
+
low: "default",
|
|
162
|
+
medium: "default",
|
|
163
|
+
high: "default",
|
|
164
|
+
xhigh: "default",
|
|
165
|
+
} satisfies Partial<Record<OpenAIReasoningEffort, string>>)
|
|
166
|
+
: isDeepseekFamily && model.reasoning
|
|
167
|
+
? ({
|
|
168
|
+
minimal: "high",
|
|
169
|
+
low: "high",
|
|
170
|
+
medium: "high",
|
|
171
|
+
high: "high",
|
|
172
|
+
xhigh: "max",
|
|
173
|
+
} satisfies Partial<Record<OpenAIReasoningEffort, string>>)
|
|
174
|
+
: isFireworks
|
|
175
|
+
? ({
|
|
176
|
+
// Fireworks' OpenAI-compatible endpoint rejects OpenAI's
|
|
177
|
+
// `minimal` literal but accepts `none` for the lowest setting.
|
|
178
|
+
minimal: "none",
|
|
179
|
+
} satisfies Partial<Record<OpenAIReasoningEffort, string>>)
|
|
180
|
+
: {};
|
|
181
|
+
|
|
182
|
+
return {
|
|
183
|
+
supportsStore: !isNonStandard,
|
|
184
|
+
supportsDeveloperRole: !isNonStandard,
|
|
185
|
+
supportsMultipleSystemMessages: supportsMultipleSystemMessagesDefault,
|
|
186
|
+
supportsReasoningEffort: !isGrok && !isZai,
|
|
187
|
+
reasoningEffortMap,
|
|
188
|
+
supportsUsageInStreaming: !isCerebras,
|
|
189
|
+
disableReasoningOnForcedToolChoice: isKimiModel || isAnthropicModel,
|
|
190
|
+
disableReasoningOnToolChoice: isDeepseekFamily && Boolean(model.reasoning) && !isOpenRouter,
|
|
191
|
+
supportsToolChoice: !isDirectDeepseekReasoning,
|
|
192
|
+
maxTokensField: useMaxTokens ? "max_tokens" : "max_completion_tokens",
|
|
193
|
+
requiresToolResultName: isMistral,
|
|
194
|
+
requiresAssistantAfterToolResult: false,
|
|
195
|
+
requiresThinkingAsText: isMistral,
|
|
196
|
+
requiresMistralToolIds: isMistral,
|
|
197
|
+
thinkingFormat:
|
|
198
|
+
isZai || isMoonshotKimi
|
|
199
|
+
? "zai"
|
|
200
|
+
: provider === "openrouter" || baseUrl.includes("openrouter.ai")
|
|
201
|
+
? "openrouter"
|
|
202
|
+
: isAlibaba || isQwen
|
|
203
|
+
? "qwen"
|
|
204
|
+
: "openai",
|
|
205
|
+
reasoningContentField: "reasoning_content",
|
|
206
|
+
// Backends that 400 follow-up requests when prior assistant tool-call turns lack `reasoning_content`:
|
|
207
|
+
// - Kimi: documented invariant on its native API.
|
|
208
|
+
// - Any reasoning-capable model reached through OpenRouter: DeepSeek V4 Pro and similar enforce
|
|
209
|
+
// this server-side whenever the request is in thinking mode. We can't translate Anthropic's
|
|
210
|
+
// redacted/encrypted reasoning into DeepSeek's plaintext form, so cross-provider continuations
|
|
211
|
+
// rely on a placeholder — see `convertMessages` for the placeholder injection.
|
|
212
|
+
// - OpenCode-Go and OpenCode-Zen handle reasoning content internally and reject
|
|
213
|
+
// `reasoning_content` in client-sent messages — exclude them even for Kimi models.
|
|
214
|
+
requiresReasoningContentForToolCalls:
|
|
215
|
+
(isKimiModel && !isOpenCodeProvider) ||
|
|
216
|
+
(isDeepseekFamily && Boolean(model.reasoning)) ||
|
|
217
|
+
((provider === "openrouter" || baseUrl.includes("openrouter.ai")) && Boolean(model.reasoning)),
|
|
218
|
+
// DeepSeek V4 rejects synthetic reasoning_content placeholders (".") on tool-call turns.
|
|
219
|
+
// Kimi and OpenRouter accept them when actual reasoning is unavailable.
|
|
220
|
+
allowsSyntheticReasoningContentForToolCalls: !isDeepseekFamily || !model.reasoning,
|
|
221
|
+
requiresAssistantContentForToolCalls: isKimiModel || isDirectDeepseekReasoning,
|
|
222
|
+
openRouterRouting: undefined,
|
|
223
|
+
vercelGatewayRouting: undefined,
|
|
224
|
+
supportsStrictMode: detectStrictModeSupport(provider, baseUrl),
|
|
225
|
+
extraBody: isDirectDeepseekReasoning ? { thinking: { type: "enabled" } } : undefined,
|
|
226
|
+
toolStrictMode: isCerebras ? "all_strict" : "mixed",
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Resolve compatibility settings by layering explicit model.compat overrides onto
|
|
232
|
+
* the detected defaults. This is the canonical compat view for both metadata and transport.
|
|
233
|
+
* @param model - The model configuration
|
|
234
|
+
* @param resolvedBaseUrl - Optional resolved base URL (e.g., after GitHub Copilot proxy-ep resolution).
|
|
235
|
+
* If provided, this takes precedence over model.baseUrl for URL-based checks.
|
|
236
|
+
*/
|
|
237
|
+
export function resolveOpenAICompat(
|
|
238
|
+
model: Model<"openai-completions">,
|
|
239
|
+
resolvedBaseUrl?: string,
|
|
240
|
+
): ResolvedOpenAICompat {
|
|
241
|
+
const detected = detectOpenAICompat(model, resolvedBaseUrl);
|
|
242
|
+
if (!model.compat) {
|
|
243
|
+
return detected;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
return {
|
|
247
|
+
supportsStore: model.compat.supportsStore ?? detected.supportsStore,
|
|
248
|
+
supportsDeveloperRole: model.compat.supportsDeveloperRole ?? detected.supportsDeveloperRole,
|
|
249
|
+
supportsMultipleSystemMessages:
|
|
250
|
+
model.compat.supportsMultipleSystemMessages ?? detected.supportsMultipleSystemMessages,
|
|
251
|
+
supportsReasoningEffort: model.compat.supportsReasoningEffort ?? detected.supportsReasoningEffort,
|
|
252
|
+
reasoningEffortMap: { ...detected.reasoningEffortMap, ...(model.compat.reasoningEffortMap ?? {}) },
|
|
253
|
+
supportsUsageInStreaming: model.compat.supportsUsageInStreaming ?? detected.supportsUsageInStreaming,
|
|
254
|
+
supportsToolChoice: model.compat.supportsToolChoice ?? detected.supportsToolChoice,
|
|
255
|
+
maxTokensField: model.compat.maxTokensField ?? detected.maxTokensField,
|
|
256
|
+
requiresToolResultName: model.compat.requiresToolResultName ?? detected.requiresToolResultName,
|
|
257
|
+
requiresAssistantAfterToolResult:
|
|
258
|
+
model.compat.requiresAssistantAfterToolResult ?? detected.requiresAssistantAfterToolResult,
|
|
259
|
+
requiresThinkingAsText: model.compat.requiresThinkingAsText ?? detected.requiresThinkingAsText,
|
|
260
|
+
requiresMistralToolIds: model.compat.requiresMistralToolIds ?? detected.requiresMistralToolIds,
|
|
261
|
+
thinkingFormat: model.compat.thinkingFormat ?? detected.thinkingFormat,
|
|
262
|
+
reasoningContentField: model.compat.reasoningContentField ?? detected.reasoningContentField,
|
|
263
|
+
requiresReasoningContentForToolCalls:
|
|
264
|
+
model.compat.requiresReasoningContentForToolCalls ?? detected.requiresReasoningContentForToolCalls,
|
|
265
|
+
allowsSyntheticReasoningContentForToolCalls:
|
|
266
|
+
model.compat.allowsSyntheticReasoningContentForToolCalls ??
|
|
267
|
+
detected.allowsSyntheticReasoningContentForToolCalls,
|
|
268
|
+
requiresAssistantContentForToolCalls:
|
|
269
|
+
model.compat.requiresAssistantContentForToolCalls ?? detected.requiresAssistantContentForToolCalls,
|
|
270
|
+
disableReasoningOnForcedToolChoice:
|
|
271
|
+
model.compat.disableReasoningOnForcedToolChoice ?? detected.disableReasoningOnForcedToolChoice,
|
|
272
|
+
disableReasoningOnToolChoice: model.compat.disableReasoningOnToolChoice ?? detected.disableReasoningOnToolChoice,
|
|
273
|
+
openRouterRouting: model.compat.openRouterRouting ?? detected.openRouterRouting,
|
|
274
|
+
vercelGatewayRouting: model.compat.vercelGatewayRouting ?? detected.vercelGatewayRouting,
|
|
275
|
+
supportsStrictMode: model.compat.supportsStrictMode ?? detected.supportsStrictMode,
|
|
276
|
+
extraBody: model.compat.extraBody ?? detected.extraBody,
|
|
277
|
+
toolStrictMode: model.compat.toolStrictMode ?? detected.toolStrictMode,
|
|
278
|
+
};
|
|
279
|
+
}
|