@clinebot/llms 0.0.0
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/README.md +198 -0
- package/dist/config-browser.d.ts +3 -0
- package/dist/config.d.ts +3 -0
- package/dist/index.browser.d.ts +4 -0
- package/dist/index.browser.js +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +7 -0
- package/dist/models/generated-access.d.ts +4 -0
- package/dist/models/generated-provider-loaders.d.ts +13 -0
- package/dist/models/generated.d.ts +14 -0
- package/dist/models/index.d.ts +43 -0
- package/dist/models/models-dev-catalog.d.ts +32 -0
- package/dist/models/providers/aihubmix.d.ts +5 -0
- package/dist/models/providers/anthropic.d.ts +53 -0
- package/dist/models/providers/asksage.d.ts +5 -0
- package/dist/models/providers/baseten.d.ts +5 -0
- package/dist/models/providers/bedrock.d.ts +7 -0
- package/dist/models/providers/cerebras.d.ts +7 -0
- package/dist/models/providers/claude-code.d.ts +4 -0
- package/dist/models/providers/cline.d.ts +34 -0
- package/dist/models/providers/deepseek.d.ts +8 -0
- package/dist/models/providers/dify.d.ts +5 -0
- package/dist/models/providers/doubao.d.ts +7 -0
- package/dist/models/providers/fireworks.d.ts +8 -0
- package/dist/models/providers/gemini.d.ts +9 -0
- package/dist/models/providers/groq.d.ts +8 -0
- package/dist/models/providers/hicap.d.ts +5 -0
- package/dist/models/providers/huawei-cloud-maas.d.ts +5 -0
- package/dist/models/providers/huggingface.d.ts +6 -0
- package/dist/models/providers/index.d.ts +45 -0
- package/dist/models/providers/litellm.d.ts +5 -0
- package/dist/models/providers/lmstudio.d.ts +5 -0
- package/dist/models/providers/minimax.d.ts +7 -0
- package/dist/models/providers/mistral.d.ts +5 -0
- package/dist/models/providers/moonshot.d.ts +7 -0
- package/dist/models/providers/nebius.d.ts +7 -0
- package/dist/models/providers/nous-research.d.ts +7 -0
- package/dist/models/providers/oca.d.ts +9 -0
- package/dist/models/providers/ollama.d.ts +5 -0
- package/dist/models/providers/openai-codex.d.ts +10 -0
- package/dist/models/providers/openai.d.ts +9 -0
- package/dist/models/providers/opencode.d.ts +10 -0
- package/dist/models/providers/openrouter.d.ts +7 -0
- package/dist/models/providers/qwen-code.d.ts +7 -0
- package/dist/models/providers/qwen.d.ts +7 -0
- package/dist/models/providers/requesty.d.ts +6 -0
- package/dist/models/providers/sambanova.d.ts +7 -0
- package/dist/models/providers/sapaicore.d.ts +7 -0
- package/dist/models/providers/together.d.ts +8 -0
- package/dist/models/providers/vercel-ai-gateway.d.ts +5 -0
- package/dist/models/providers/vertex.d.ts +7 -0
- package/dist/models/providers/xai.d.ts +8 -0
- package/dist/models/providers/zai.d.ts +7 -0
- package/dist/models/query.d.ts +181 -0
- package/dist/models/registry.d.ts +123 -0
- package/dist/models/schemas/index.d.ts +7 -0
- package/dist/models/schemas/model.d.ts +340 -0
- package/dist/models/schemas/query.d.ts +191 -0
- package/dist/providers/handlers/ai-sdk-community.d.ts +46 -0
- package/dist/providers/handlers/ai-sdk-provider-base.d.ts +32 -0
- package/dist/providers/handlers/anthropic-base.d.ts +26 -0
- package/dist/providers/handlers/asksage.d.ts +12 -0
- package/dist/providers/handlers/auth.d.ts +5 -0
- package/dist/providers/handlers/base.d.ts +55 -0
- package/dist/providers/handlers/bedrock-base.d.ts +23 -0
- package/dist/providers/handlers/bedrock-client.d.ts +4 -0
- package/dist/providers/handlers/community-sdk.d.ts +97 -0
- package/dist/providers/handlers/fetch-base.d.ts +18 -0
- package/dist/providers/handlers/gemini-base.d.ts +25 -0
- package/dist/providers/handlers/index.d.ts +19 -0
- package/dist/providers/handlers/openai-base.d.ts +54 -0
- package/dist/providers/handlers/openai-responses.d.ts +64 -0
- package/dist/providers/handlers/providers.d.ts +43 -0
- package/dist/providers/handlers/r1-base.d.ts +62 -0
- package/dist/providers/handlers/registry.d.ts +106 -0
- package/dist/providers/handlers/vertex.d.ts +32 -0
- package/dist/providers/index.d.ts +100 -0
- package/dist/providers/public.browser.d.ts +2 -0
- package/dist/providers/public.d.ts +3 -0
- package/dist/providers/shared/openai-compatible.d.ts +10 -0
- package/dist/providers/transform/ai-sdk-community-format.d.ts +9 -0
- package/dist/providers/transform/anthropic-format.d.ts +24 -0
- package/dist/providers/transform/content-format.d.ts +3 -0
- package/dist/providers/transform/gemini-format.d.ts +19 -0
- package/dist/providers/transform/index.d.ts +10 -0
- package/dist/providers/transform/openai-format.d.ts +36 -0
- package/dist/providers/transform/r1-format.d.ts +26 -0
- package/dist/providers/types/config.d.ts +261 -0
- package/dist/providers/types/handler.d.ts +71 -0
- package/dist/providers/types/index.d.ts +11 -0
- package/dist/providers/types/messages.d.ts +139 -0
- package/dist/providers/types/model-info.d.ts +32 -0
- package/dist/providers/types/provider-ids.d.ts +63 -0
- package/dist/providers/types/settings.d.ts +308 -0
- package/dist/providers/types/stream.d.ts +106 -0
- package/dist/providers/utils/index.d.ts +7 -0
- package/dist/providers/utils/retry.d.ts +38 -0
- package/dist/providers/utils/stream-processor.d.ts +110 -0
- package/dist/providers/utils/tool-processor.d.ts +34 -0
- package/dist/sdk.d.ts +18 -0
- package/dist/types.d.ts +60 -0
- package/package.json +66 -0
- package/src/catalog.ts +20 -0
- package/src/config-browser.ts +11 -0
- package/src/config.ts +49 -0
- package/src/index.browser.ts +9 -0
- package/src/index.ts +10 -0
- package/src/live-providers.test.ts +137 -0
- package/src/models/generated-access.ts +41 -0
- package/src/models/generated-provider-loaders.ts +166 -0
- package/src/models/generated.ts +11997 -0
- package/src/models/index.ts +271 -0
- package/src/models/models-dev-catalog.test.ts +161 -0
- package/src/models/models-dev-catalog.ts +161 -0
- package/src/models/providers/aihubmix.ts +19 -0
- package/src/models/providers/anthropic.ts +60 -0
- package/src/models/providers/asksage.ts +19 -0
- package/src/models/providers/baseten.ts +21 -0
- package/src/models/providers/bedrock.ts +30 -0
- package/src/models/providers/cerebras.ts +24 -0
- package/src/models/providers/claude-code.ts +51 -0
- package/src/models/providers/cline.ts +25 -0
- package/src/models/providers/deepseek.ts +33 -0
- package/src/models/providers/dify.ts +17 -0
- package/src/models/providers/doubao.ts +33 -0
- package/src/models/providers/fireworks.ts +34 -0
- package/src/models/providers/gemini.ts +43 -0
- package/src/models/providers/groq.ts +33 -0
- package/src/models/providers/hicap.ts +18 -0
- package/src/models/providers/huawei-cloud-maas.ts +18 -0
- package/src/models/providers/huggingface.ts +22 -0
- package/src/models/providers/index.ts +162 -0
- package/src/models/providers/litellm.ts +19 -0
- package/src/models/providers/lmstudio.ts +22 -0
- package/src/models/providers/minimax.ts +34 -0
- package/src/models/providers/mistral.ts +19 -0
- package/src/models/providers/moonshot.ts +34 -0
- package/src/models/providers/nebius.ts +24 -0
- package/src/models/providers/nous-research.ts +21 -0
- package/src/models/providers/oca.ts +30 -0
- package/src/models/providers/ollama.ts +18 -0
- package/src/models/providers/openai-codex.ts +30 -0
- package/src/models/providers/openai.ts +43 -0
- package/src/models/providers/opencode.ts +28 -0
- package/src/models/providers/openrouter.ts +24 -0
- package/src/models/providers/qwen-code.ts +33 -0
- package/src/models/providers/qwen.ts +34 -0
- package/src/models/providers/requesty.ts +23 -0
- package/src/models/providers/sambanova.ts +23 -0
- package/src/models/providers/sapaicore.ts +34 -0
- package/src/models/providers/together.ts +35 -0
- package/src/models/providers/vercel-ai-gateway.ts +23 -0
- package/src/models/providers/vertex.ts +36 -0
- package/src/models/providers/xai.ts +34 -0
- package/src/models/providers/zai.ts +25 -0
- package/src/models/query.ts +407 -0
- package/src/models/registry.ts +511 -0
- package/src/models/schemas/index.ts +62 -0
- package/src/models/schemas/model.ts +308 -0
- package/src/models/schemas/query.ts +336 -0
- package/src/providers/browser.ts +4 -0
- package/src/providers/handlers/ai-sdk-community.ts +226 -0
- package/src/providers/handlers/ai-sdk-provider-base.ts +193 -0
- package/src/providers/handlers/anthropic-base.ts +372 -0
- package/src/providers/handlers/asksage.test.ts +103 -0
- package/src/providers/handlers/asksage.ts +138 -0
- package/src/providers/handlers/auth.test.ts +19 -0
- package/src/providers/handlers/auth.ts +121 -0
- package/src/providers/handlers/base.test.ts +46 -0
- package/src/providers/handlers/base.ts +160 -0
- package/src/providers/handlers/bedrock-base.ts +390 -0
- package/src/providers/handlers/bedrock-client.ts +100 -0
- package/src/providers/handlers/codex.test.ts +123 -0
- package/src/providers/handlers/community-sdk.test.ts +288 -0
- package/src/providers/handlers/community-sdk.ts +392 -0
- package/src/providers/handlers/fetch-base.ts +68 -0
- package/src/providers/handlers/gemini-base.ts +302 -0
- package/src/providers/handlers/index.ts +67 -0
- package/src/providers/handlers/openai-base.ts +277 -0
- package/src/providers/handlers/openai-responses.ts +598 -0
- package/src/providers/handlers/providers.test.ts +120 -0
- package/src/providers/handlers/providers.ts +563 -0
- package/src/providers/handlers/r1-base.ts +280 -0
- package/src/providers/handlers/registry.ts +185 -0
- package/src/providers/handlers/vertex.test.ts +124 -0
- package/src/providers/handlers/vertex.ts +292 -0
- package/src/providers/index.ts +534 -0
- package/src/providers/public.browser.ts +20 -0
- package/src/providers/public.ts +51 -0
- package/src/providers/shared/openai-compatible.ts +63 -0
- package/src/providers/transform/ai-sdk-community-format.test.ts +73 -0
- package/src/providers/transform/ai-sdk-community-format.ts +115 -0
- package/src/providers/transform/anthropic-format.ts +218 -0
- package/src/providers/transform/content-format.ts +34 -0
- package/src/providers/transform/format-conversion.test.ts +310 -0
- package/src/providers/transform/gemini-format.ts +167 -0
- package/src/providers/transform/index.ts +22 -0
- package/src/providers/transform/openai-format.ts +247 -0
- package/src/providers/transform/r1-format.ts +287 -0
- package/src/providers/types/config.ts +388 -0
- package/src/providers/types/handler.ts +87 -0
- package/src/providers/types/index.ts +120 -0
- package/src/providers/types/messages.ts +158 -0
- package/src/providers/types/model-info.test.ts +57 -0
- package/src/providers/types/model-info.ts +65 -0
- package/src/providers/types/provider-ids.test.ts +12 -0
- package/src/providers/types/provider-ids.ts +89 -0
- package/src/providers/types/settings.test.ts +49 -0
- package/src/providers/types/settings.ts +533 -0
- package/src/providers/types/stream.ts +117 -0
- package/src/providers/utils/index.ts +27 -0
- package/src/providers/utils/retry.test.ts +140 -0
- package/src/providers/utils/retry.ts +188 -0
- package/src/providers/utils/stream-processor.test.ts +232 -0
- package/src/providers/utils/stream-processor.ts +472 -0
- package/src/providers/utils/tool-processor.test.ts +34 -0
- package/src/providers/utils/tool-processor.ts +111 -0
- package/src/sdk.ts +264 -0
- package/src/types.ts +79 -0
|
@@ -0,0 +1,392 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Community SDK Handlers
|
|
3
|
+
*
|
|
4
|
+
* Consolidated handlers for:
|
|
5
|
+
* - Codex CLI (`openai-codex`)
|
|
6
|
+
* - Claude Code (`claude-code`)
|
|
7
|
+
* - OpenCode (`opencode`)
|
|
8
|
+
* - Mistral (`mistral`)
|
|
9
|
+
* - Dify (`dify`)
|
|
10
|
+
* - SAP AI Core (`sapaicore`)
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import type { ProviderConfig } from "../types";
|
|
14
|
+
import type { EmitAiSdkStreamOptions } from "./ai-sdk-community";
|
|
15
|
+
import { AiSdkProviderHandler } from "./ai-sdk-provider-base";
|
|
16
|
+
|
|
17
|
+
let zodCompatPatched = false;
|
|
18
|
+
|
|
19
|
+
async function ensureCodexZodCompatibility(): Promise<void> {
|
|
20
|
+
if (zodCompatPatched) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
zodCompatPatched = true;
|
|
24
|
+
|
|
25
|
+
try {
|
|
26
|
+
const zodModule = (await import("zod")) as Record<string, unknown>;
|
|
27
|
+
const z = (zodModule.z ?? zodModule) as Record<string, unknown>;
|
|
28
|
+
const objectFactory = z.object as
|
|
29
|
+
| ((shape?: Record<string, unknown>) => {
|
|
30
|
+
refine?: (check: (value: unknown) => boolean) => unknown;
|
|
31
|
+
})
|
|
32
|
+
| undefined;
|
|
33
|
+
if (typeof objectFactory !== "function") {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const refined = objectFactory({}).refine?.(() => true) as
|
|
38
|
+
| { passthrough?: unknown }
|
|
39
|
+
| undefined;
|
|
40
|
+
if (!refined || typeof refined.passthrough === "function") {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const proto = Object.getPrototypeOf(refined) as
|
|
45
|
+
| { passthrough?: unknown }
|
|
46
|
+
| undefined;
|
|
47
|
+
if (!proto || typeof proto.passthrough === "function") {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
Object.defineProperty(proto, "passthrough", {
|
|
52
|
+
value(this: unknown) {
|
|
53
|
+
return this;
|
|
54
|
+
},
|
|
55
|
+
configurable: true,
|
|
56
|
+
enumerable: false,
|
|
57
|
+
writable: true,
|
|
58
|
+
});
|
|
59
|
+
} catch {
|
|
60
|
+
// Best-effort compatibility shim for codex-cli provider with zod v3.
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function isLikelyOpenAIApiKey(value: string): boolean {
|
|
65
|
+
return value.startsWith("sk-");
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function shouldDisableAiSdkWarnings(): boolean {
|
|
69
|
+
const raw = process.env.AI_SDK_LOG_WARNINGS?.trim().toLowerCase();
|
|
70
|
+
return raw === "0" || raw === "false" || raw === "off";
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function resolveOpenCodeModelId(modelId: string): string {
|
|
74
|
+
if (modelId.includes("/")) {
|
|
75
|
+
return modelId;
|
|
76
|
+
}
|
|
77
|
+
return `openai/${modelId}`;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export class CodexHandler extends AiSdkProviderHandler {
|
|
81
|
+
protected getProviderDefinition() {
|
|
82
|
+
return {
|
|
83
|
+
moduleName: "ai-sdk-provider-codex-cli",
|
|
84
|
+
createExportName: "createCodexCli",
|
|
85
|
+
providerExportName: "codexCli",
|
|
86
|
+
missingDependencyError:
|
|
87
|
+
"Codex provider requires `ai-sdk-provider-codex-cli` and the Codex CLI at runtime. Install dependencies and run `codex` to authenticate.",
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
protected getDefaultModelId(): string {
|
|
92
|
+
return "gpt-5.3-codex";
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
protected async beforeLoadProviderModule(): Promise<void> {
|
|
96
|
+
await ensureCodexZodCompatibility();
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
protected getProviderCreateOptions(): Record<string, unknown> {
|
|
100
|
+
const codexOptions = this.config.codex ?? {};
|
|
101
|
+
const defaultSettings: Record<string, unknown> = {
|
|
102
|
+
...(codexOptions.defaultSettings ?? {}),
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
if (
|
|
106
|
+
this.config.reasoningEffort &&
|
|
107
|
+
defaultSettings.reasoningEffort === undefined
|
|
108
|
+
) {
|
|
109
|
+
defaultSettings.reasoningEffort = this.config.reasoningEffort;
|
|
110
|
+
} else if (
|
|
111
|
+
this.config.thinking &&
|
|
112
|
+
defaultSettings.reasoningEffort === undefined
|
|
113
|
+
) {
|
|
114
|
+
defaultSettings.reasoningEffort = "medium";
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const apiKey = this.config.apiKey?.trim();
|
|
118
|
+
const hasOAuthAccessToken =
|
|
119
|
+
typeof this.config.accessToken === "string" &&
|
|
120
|
+
this.config.accessToken.trim().length > 0;
|
|
121
|
+
if (apiKey && !hasOAuthAccessToken && isLikelyOpenAIApiKey(apiKey)) {
|
|
122
|
+
defaultSettings.env = {
|
|
123
|
+
...((defaultSettings.env as Record<string, string> | undefined) ?? {}),
|
|
124
|
+
OPENAI_API_KEY: apiKey,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return {
|
|
129
|
+
defaultSettings:
|
|
130
|
+
Object.keys(defaultSettings).length > 0 ? defaultSettings : undefined,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
protected getProviderModelSettings(): Record<string, unknown> | undefined {
|
|
135
|
+
return this.config.codex?.modelSettings;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
protected getStreamErrorMessage(): string {
|
|
139
|
+
return "Codex stream failed";
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
protected getEmitStreamOptions(): Omit<
|
|
143
|
+
EmitAiSdkStreamOptions,
|
|
144
|
+
"responseId" | "errorMessage" | "calculateCost"
|
|
145
|
+
> {
|
|
146
|
+
return {
|
|
147
|
+
reasoningTypes: ["reasoning-delta", "reasoning"],
|
|
148
|
+
enableToolCalls: true,
|
|
149
|
+
toolCallArgsOrder: ["args", "input"],
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export class ClaudeCodeHandler extends AiSdkProviderHandler {
|
|
155
|
+
protected getProviderDefinition() {
|
|
156
|
+
return {
|
|
157
|
+
moduleName: "ai-sdk-provider-claude-code",
|
|
158
|
+
createExportName: "createClaudeCode",
|
|
159
|
+
providerExportName: "claudeCode",
|
|
160
|
+
missingDependencyError:
|
|
161
|
+
"Claude Code provider requires `ai-sdk-provider-claude-code` at runtime. Install dependencies and run `claude login`.",
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
protected getDefaultModelId(): string {
|
|
166
|
+
return "sonnet";
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
protected getProviderCreateOptions(): Record<string, unknown> | undefined {
|
|
170
|
+
return this.config.claudeCode ?? {};
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
protected getLoadAiSdkOptions() {
|
|
174
|
+
return {
|
|
175
|
+
beforeImport: () => {
|
|
176
|
+
if (shouldDisableAiSdkWarnings()) {
|
|
177
|
+
(globalThis as Record<string, unknown>).AI_SDK_LOG_WARNINGS = false;
|
|
178
|
+
}
|
|
179
|
+
},
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
protected getStreamErrorMessage(): string {
|
|
184
|
+
return "Claude Code stream failed";
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
protected getEmitStreamOptions(): Omit<
|
|
188
|
+
EmitAiSdkStreamOptions,
|
|
189
|
+
"responseId" | "errorMessage" | "calculateCost"
|
|
190
|
+
> {
|
|
191
|
+
return {
|
|
192
|
+
reasoningTypes: ["reasoning-delta"],
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
export class OpenCodeHandler extends AiSdkProviderHandler {
|
|
198
|
+
protected getProviderDefinition() {
|
|
199
|
+
return {
|
|
200
|
+
moduleName: "ai-sdk-provider-opencode-sdk",
|
|
201
|
+
createExportName: "createOpencode",
|
|
202
|
+
providerExportName: "opencode",
|
|
203
|
+
missingDependencyError:
|
|
204
|
+
"OpenCode provider requires `ai-sdk-provider-opencode-sdk` and OpenCode at runtime.",
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
protected getDefaultModelId(): string {
|
|
209
|
+
return "openai/gpt-5.3-codex";
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
protected getProviderCreateOptions(): Record<string, unknown> {
|
|
213
|
+
const opencodeOptions = this.config.opencode ?? {};
|
|
214
|
+
const defaultSettings = {
|
|
215
|
+
...(opencodeOptions.defaultSettings ?? {}),
|
|
216
|
+
};
|
|
217
|
+
if ((defaultSettings as Record<string, unknown>).agent === undefined) {
|
|
218
|
+
(defaultSettings as Record<string, unknown>).agent = "general";
|
|
219
|
+
}
|
|
220
|
+
return {
|
|
221
|
+
hostname: opencodeOptions.hostname,
|
|
222
|
+
port: opencodeOptions.port,
|
|
223
|
+
autoStartServer: opencodeOptions.autoStartServer,
|
|
224
|
+
serverTimeout: opencodeOptions.serverTimeout,
|
|
225
|
+
defaultSettings:
|
|
226
|
+
Object.keys(defaultSettings).length > 0 ? defaultSettings : undefined,
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
protected getProviderModelSettings(): Record<string, unknown> | undefined {
|
|
231
|
+
return this.config.opencode?.modelSettings;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
protected normalizeModelId(modelId: string): string {
|
|
235
|
+
return resolveOpenCodeModelId(modelId);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
protected getStreamErrorMessage(): string {
|
|
239
|
+
return "OpenCode stream failed";
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
protected getEmitStreamOptions(): Omit<
|
|
243
|
+
EmitAiSdkStreamOptions,
|
|
244
|
+
"responseId" | "errorMessage" | "calculateCost"
|
|
245
|
+
> {
|
|
246
|
+
return {
|
|
247
|
+
reasoningTypes: ["reasoning-delta", "reasoning"],
|
|
248
|
+
enableTextFallback: true,
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
export class SapAiCoreHandler extends AiSdkProviderHandler {
|
|
254
|
+
protected getProviderDefinition() {
|
|
255
|
+
return {
|
|
256
|
+
moduleName: "@jerome-benoit/sap-ai-provider",
|
|
257
|
+
createExportName: "createSAPAIProvider",
|
|
258
|
+
providerExportName: "sapai",
|
|
259
|
+
missingDependencyError:
|
|
260
|
+
"SAP AI Core provider requires `@jerome-benoit/sap-ai-provider` at runtime.",
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
protected getDefaultModelId(): string {
|
|
265
|
+
return "anthropic--claude-3.5-sonnet";
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
protected getProviderCreateOptions(): Record<string, unknown> | undefined {
|
|
269
|
+
const sapOptions = this.config.sap ?? {};
|
|
270
|
+
const api =
|
|
271
|
+
sapOptions.api ??
|
|
272
|
+
(sapOptions.useOrchestrationMode === undefined
|
|
273
|
+
? undefined
|
|
274
|
+
: sapOptions.useOrchestrationMode
|
|
275
|
+
? "orchestration"
|
|
276
|
+
: "foundation-models");
|
|
277
|
+
|
|
278
|
+
const createOptions: Record<string, unknown> = {
|
|
279
|
+
resourceGroup: sapOptions.resourceGroup,
|
|
280
|
+
deploymentId: sapOptions.deploymentId,
|
|
281
|
+
api,
|
|
282
|
+
defaultSettings: sapOptions.defaultSettings,
|
|
283
|
+
};
|
|
284
|
+
|
|
285
|
+
const cleaned = Object.fromEntries(
|
|
286
|
+
Object.entries(createOptions).filter(([, value]) => value !== undefined),
|
|
287
|
+
);
|
|
288
|
+
return Object.keys(cleaned).length > 0 ? cleaned : undefined;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
protected getStreamErrorMessage(): string {
|
|
292
|
+
return "SAP AI Core stream failed";
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
protected getEmitStreamOptions(): Omit<
|
|
296
|
+
EmitAiSdkStreamOptions,
|
|
297
|
+
"responseId" | "errorMessage" | "calculateCost"
|
|
298
|
+
> {
|
|
299
|
+
return {
|
|
300
|
+
reasoningTypes: ["reasoning-delta", "reasoning"],
|
|
301
|
+
enableToolCalls: true,
|
|
302
|
+
toolCallArgsOrder: ["args", "input"],
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
export class MistralHandler extends AiSdkProviderHandler {
|
|
308
|
+
protected getProviderDefinition() {
|
|
309
|
+
return {
|
|
310
|
+
moduleName: "@ai-sdk/mistral",
|
|
311
|
+
createExportName: "createMistral",
|
|
312
|
+
providerExportName: "mistral",
|
|
313
|
+
missingDependencyError:
|
|
314
|
+
"Mistral provider requires `@ai-sdk/mistral` at runtime.",
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
protected getDefaultModelId(): string {
|
|
319
|
+
return "mistral-medium-latest";
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
protected getStreamErrorMessage(): string {
|
|
323
|
+
return "Mistral stream failed";
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
export class DifyHandler extends AiSdkProviderHandler {
|
|
328
|
+
protected getProviderDefinition() {
|
|
329
|
+
return {
|
|
330
|
+
moduleName: "dify-ai-provider",
|
|
331
|
+
createExportName: "createDifyProvider",
|
|
332
|
+
providerExportName: "difyProvider",
|
|
333
|
+
missingDependencyError:
|
|
334
|
+
"Dify provider requires `dify-ai-provider` at runtime.",
|
|
335
|
+
};
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
protected getDefaultModelId(): string {
|
|
339
|
+
return "default";
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
protected getProviderCreateOptions(): Record<string, unknown> | undefined {
|
|
343
|
+
if (!this.config.baseUrl) {
|
|
344
|
+
return undefined;
|
|
345
|
+
}
|
|
346
|
+
return {
|
|
347
|
+
baseURL: this.config.baseUrl,
|
|
348
|
+
};
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
protected getProviderModelSettings(): Record<string, unknown> | undefined {
|
|
352
|
+
const modelSettings: Record<string, unknown> = {
|
|
353
|
+
responseMode: "blocking",
|
|
354
|
+
};
|
|
355
|
+
if (this.config.apiKey) {
|
|
356
|
+
modelSettings.apiKey = this.config.apiKey;
|
|
357
|
+
}
|
|
358
|
+
return modelSettings;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
protected getStreamErrorMessage(): string {
|
|
362
|
+
return "Dify stream failed";
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
export function createCodexHandler(config: ProviderConfig): CodexHandler {
|
|
367
|
+
return new CodexHandler(config);
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
export function createClaudeCodeHandler(
|
|
371
|
+
config: ProviderConfig,
|
|
372
|
+
): ClaudeCodeHandler {
|
|
373
|
+
return new ClaudeCodeHandler(config);
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
export function createOpenCodeHandler(config: ProviderConfig): OpenCodeHandler {
|
|
377
|
+
return new OpenCodeHandler(config);
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
export function createSapAiCoreHandler(
|
|
381
|
+
config: ProviderConfig,
|
|
382
|
+
): SapAiCoreHandler {
|
|
383
|
+
return new SapAiCoreHandler(config);
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
export function createMistralHandler(config: ProviderConfig): MistralHandler {
|
|
387
|
+
return new MistralHandler(config);
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
export function createDifyHandler(config: ProviderConfig): DifyHandler {
|
|
391
|
+
return new DifyHandler(config);
|
|
392
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { ApiStream } from "../types";
|
|
2
|
+
import type { Message, ToolDefinition } from "../types/messages";
|
|
3
|
+
import { retryStream } from "../utils/retry";
|
|
4
|
+
import { BaseHandler } from "./base";
|
|
5
|
+
|
|
6
|
+
type JsonRecord = Record<string, unknown>;
|
|
7
|
+
|
|
8
|
+
export abstract class FetchBaseHandler extends BaseHandler {
|
|
9
|
+
protected abstract getDefaultBaseUrl(): string;
|
|
10
|
+
|
|
11
|
+
getMessages(systemPrompt: string, messages: Message[]): unknown {
|
|
12
|
+
return {
|
|
13
|
+
systemPrompt,
|
|
14
|
+
messages,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
protected getBaseUrl(): string {
|
|
19
|
+
return this.config.baseUrl?.trim() || this.getDefaultBaseUrl();
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
protected getJsonHeaders(
|
|
23
|
+
extra?: Record<string, string>,
|
|
24
|
+
): Record<string, string> {
|
|
25
|
+
return {
|
|
26
|
+
"Content-Type": "application/json",
|
|
27
|
+
...this.getRequestHeaders(),
|
|
28
|
+
...(extra ?? {}),
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
protected async fetchJson<T>(
|
|
33
|
+
path: string,
|
|
34
|
+
init: {
|
|
35
|
+
method?: string;
|
|
36
|
+
body?: JsonRecord;
|
|
37
|
+
headers?: Record<string, string>;
|
|
38
|
+
},
|
|
39
|
+
): Promise<T> {
|
|
40
|
+
const response = await fetch(`${this.getBaseUrl()}${path}`, {
|
|
41
|
+
method: init.method ?? "POST",
|
|
42
|
+
headers: this.getJsonHeaders(init.headers),
|
|
43
|
+
body: init.body ? JSON.stringify(init.body) : undefined,
|
|
44
|
+
signal: this.getAbortSignal(),
|
|
45
|
+
});
|
|
46
|
+
if (!response.ok) {
|
|
47
|
+
const details = await response.text();
|
|
48
|
+
throw new Error(`HTTP ${response.status}: ${details}`);
|
|
49
|
+
}
|
|
50
|
+
return (await response.json()) as T;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
async *createMessage(
|
|
54
|
+
systemPrompt: string,
|
|
55
|
+
messages: Message[],
|
|
56
|
+
tools?: ToolDefinition[],
|
|
57
|
+
): ApiStream {
|
|
58
|
+
void tools;
|
|
59
|
+
yield* retryStream(() =>
|
|
60
|
+
this.createMessageWithFetch(systemPrompt, messages),
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
protected abstract createMessageWithFetch(
|
|
65
|
+
systemPrompt: string,
|
|
66
|
+
messages: Message[],
|
|
67
|
+
): ApiStream;
|
|
68
|
+
}
|