@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.
Files changed (219) hide show
  1. package/README.md +198 -0
  2. package/dist/config-browser.d.ts +3 -0
  3. package/dist/config.d.ts +3 -0
  4. package/dist/index.browser.d.ts +4 -0
  5. package/dist/index.browser.js +1 -0
  6. package/dist/index.d.ts +5 -0
  7. package/dist/index.js +7 -0
  8. package/dist/models/generated-access.d.ts +4 -0
  9. package/dist/models/generated-provider-loaders.d.ts +13 -0
  10. package/dist/models/generated.d.ts +14 -0
  11. package/dist/models/index.d.ts +43 -0
  12. package/dist/models/models-dev-catalog.d.ts +32 -0
  13. package/dist/models/providers/aihubmix.d.ts +5 -0
  14. package/dist/models/providers/anthropic.d.ts +53 -0
  15. package/dist/models/providers/asksage.d.ts +5 -0
  16. package/dist/models/providers/baseten.d.ts +5 -0
  17. package/dist/models/providers/bedrock.d.ts +7 -0
  18. package/dist/models/providers/cerebras.d.ts +7 -0
  19. package/dist/models/providers/claude-code.d.ts +4 -0
  20. package/dist/models/providers/cline.d.ts +34 -0
  21. package/dist/models/providers/deepseek.d.ts +8 -0
  22. package/dist/models/providers/dify.d.ts +5 -0
  23. package/dist/models/providers/doubao.d.ts +7 -0
  24. package/dist/models/providers/fireworks.d.ts +8 -0
  25. package/dist/models/providers/gemini.d.ts +9 -0
  26. package/dist/models/providers/groq.d.ts +8 -0
  27. package/dist/models/providers/hicap.d.ts +5 -0
  28. package/dist/models/providers/huawei-cloud-maas.d.ts +5 -0
  29. package/dist/models/providers/huggingface.d.ts +6 -0
  30. package/dist/models/providers/index.d.ts +45 -0
  31. package/dist/models/providers/litellm.d.ts +5 -0
  32. package/dist/models/providers/lmstudio.d.ts +5 -0
  33. package/dist/models/providers/minimax.d.ts +7 -0
  34. package/dist/models/providers/mistral.d.ts +5 -0
  35. package/dist/models/providers/moonshot.d.ts +7 -0
  36. package/dist/models/providers/nebius.d.ts +7 -0
  37. package/dist/models/providers/nous-research.d.ts +7 -0
  38. package/dist/models/providers/oca.d.ts +9 -0
  39. package/dist/models/providers/ollama.d.ts +5 -0
  40. package/dist/models/providers/openai-codex.d.ts +10 -0
  41. package/dist/models/providers/openai.d.ts +9 -0
  42. package/dist/models/providers/opencode.d.ts +10 -0
  43. package/dist/models/providers/openrouter.d.ts +7 -0
  44. package/dist/models/providers/qwen-code.d.ts +7 -0
  45. package/dist/models/providers/qwen.d.ts +7 -0
  46. package/dist/models/providers/requesty.d.ts +6 -0
  47. package/dist/models/providers/sambanova.d.ts +7 -0
  48. package/dist/models/providers/sapaicore.d.ts +7 -0
  49. package/dist/models/providers/together.d.ts +8 -0
  50. package/dist/models/providers/vercel-ai-gateway.d.ts +5 -0
  51. package/dist/models/providers/vertex.d.ts +7 -0
  52. package/dist/models/providers/xai.d.ts +8 -0
  53. package/dist/models/providers/zai.d.ts +7 -0
  54. package/dist/models/query.d.ts +181 -0
  55. package/dist/models/registry.d.ts +123 -0
  56. package/dist/models/schemas/index.d.ts +7 -0
  57. package/dist/models/schemas/model.d.ts +340 -0
  58. package/dist/models/schemas/query.d.ts +191 -0
  59. package/dist/providers/handlers/ai-sdk-community.d.ts +46 -0
  60. package/dist/providers/handlers/ai-sdk-provider-base.d.ts +32 -0
  61. package/dist/providers/handlers/anthropic-base.d.ts +26 -0
  62. package/dist/providers/handlers/asksage.d.ts +12 -0
  63. package/dist/providers/handlers/auth.d.ts +5 -0
  64. package/dist/providers/handlers/base.d.ts +55 -0
  65. package/dist/providers/handlers/bedrock-base.d.ts +23 -0
  66. package/dist/providers/handlers/bedrock-client.d.ts +4 -0
  67. package/dist/providers/handlers/community-sdk.d.ts +97 -0
  68. package/dist/providers/handlers/fetch-base.d.ts +18 -0
  69. package/dist/providers/handlers/gemini-base.d.ts +25 -0
  70. package/dist/providers/handlers/index.d.ts +19 -0
  71. package/dist/providers/handlers/openai-base.d.ts +54 -0
  72. package/dist/providers/handlers/openai-responses.d.ts +64 -0
  73. package/dist/providers/handlers/providers.d.ts +43 -0
  74. package/dist/providers/handlers/r1-base.d.ts +62 -0
  75. package/dist/providers/handlers/registry.d.ts +106 -0
  76. package/dist/providers/handlers/vertex.d.ts +32 -0
  77. package/dist/providers/index.d.ts +100 -0
  78. package/dist/providers/public.browser.d.ts +2 -0
  79. package/dist/providers/public.d.ts +3 -0
  80. package/dist/providers/shared/openai-compatible.d.ts +10 -0
  81. package/dist/providers/transform/ai-sdk-community-format.d.ts +9 -0
  82. package/dist/providers/transform/anthropic-format.d.ts +24 -0
  83. package/dist/providers/transform/content-format.d.ts +3 -0
  84. package/dist/providers/transform/gemini-format.d.ts +19 -0
  85. package/dist/providers/transform/index.d.ts +10 -0
  86. package/dist/providers/transform/openai-format.d.ts +36 -0
  87. package/dist/providers/transform/r1-format.d.ts +26 -0
  88. package/dist/providers/types/config.d.ts +261 -0
  89. package/dist/providers/types/handler.d.ts +71 -0
  90. package/dist/providers/types/index.d.ts +11 -0
  91. package/dist/providers/types/messages.d.ts +139 -0
  92. package/dist/providers/types/model-info.d.ts +32 -0
  93. package/dist/providers/types/provider-ids.d.ts +63 -0
  94. package/dist/providers/types/settings.d.ts +308 -0
  95. package/dist/providers/types/stream.d.ts +106 -0
  96. package/dist/providers/utils/index.d.ts +7 -0
  97. package/dist/providers/utils/retry.d.ts +38 -0
  98. package/dist/providers/utils/stream-processor.d.ts +110 -0
  99. package/dist/providers/utils/tool-processor.d.ts +34 -0
  100. package/dist/sdk.d.ts +18 -0
  101. package/dist/types.d.ts +60 -0
  102. package/package.json +66 -0
  103. package/src/catalog.ts +20 -0
  104. package/src/config-browser.ts +11 -0
  105. package/src/config.ts +49 -0
  106. package/src/index.browser.ts +9 -0
  107. package/src/index.ts +10 -0
  108. package/src/live-providers.test.ts +137 -0
  109. package/src/models/generated-access.ts +41 -0
  110. package/src/models/generated-provider-loaders.ts +166 -0
  111. package/src/models/generated.ts +11997 -0
  112. package/src/models/index.ts +271 -0
  113. package/src/models/models-dev-catalog.test.ts +161 -0
  114. package/src/models/models-dev-catalog.ts +161 -0
  115. package/src/models/providers/aihubmix.ts +19 -0
  116. package/src/models/providers/anthropic.ts +60 -0
  117. package/src/models/providers/asksage.ts +19 -0
  118. package/src/models/providers/baseten.ts +21 -0
  119. package/src/models/providers/bedrock.ts +30 -0
  120. package/src/models/providers/cerebras.ts +24 -0
  121. package/src/models/providers/claude-code.ts +51 -0
  122. package/src/models/providers/cline.ts +25 -0
  123. package/src/models/providers/deepseek.ts +33 -0
  124. package/src/models/providers/dify.ts +17 -0
  125. package/src/models/providers/doubao.ts +33 -0
  126. package/src/models/providers/fireworks.ts +34 -0
  127. package/src/models/providers/gemini.ts +43 -0
  128. package/src/models/providers/groq.ts +33 -0
  129. package/src/models/providers/hicap.ts +18 -0
  130. package/src/models/providers/huawei-cloud-maas.ts +18 -0
  131. package/src/models/providers/huggingface.ts +22 -0
  132. package/src/models/providers/index.ts +162 -0
  133. package/src/models/providers/litellm.ts +19 -0
  134. package/src/models/providers/lmstudio.ts +22 -0
  135. package/src/models/providers/minimax.ts +34 -0
  136. package/src/models/providers/mistral.ts +19 -0
  137. package/src/models/providers/moonshot.ts +34 -0
  138. package/src/models/providers/nebius.ts +24 -0
  139. package/src/models/providers/nous-research.ts +21 -0
  140. package/src/models/providers/oca.ts +30 -0
  141. package/src/models/providers/ollama.ts +18 -0
  142. package/src/models/providers/openai-codex.ts +30 -0
  143. package/src/models/providers/openai.ts +43 -0
  144. package/src/models/providers/opencode.ts +28 -0
  145. package/src/models/providers/openrouter.ts +24 -0
  146. package/src/models/providers/qwen-code.ts +33 -0
  147. package/src/models/providers/qwen.ts +34 -0
  148. package/src/models/providers/requesty.ts +23 -0
  149. package/src/models/providers/sambanova.ts +23 -0
  150. package/src/models/providers/sapaicore.ts +34 -0
  151. package/src/models/providers/together.ts +35 -0
  152. package/src/models/providers/vercel-ai-gateway.ts +23 -0
  153. package/src/models/providers/vertex.ts +36 -0
  154. package/src/models/providers/xai.ts +34 -0
  155. package/src/models/providers/zai.ts +25 -0
  156. package/src/models/query.ts +407 -0
  157. package/src/models/registry.ts +511 -0
  158. package/src/models/schemas/index.ts +62 -0
  159. package/src/models/schemas/model.ts +308 -0
  160. package/src/models/schemas/query.ts +336 -0
  161. package/src/providers/browser.ts +4 -0
  162. package/src/providers/handlers/ai-sdk-community.ts +226 -0
  163. package/src/providers/handlers/ai-sdk-provider-base.ts +193 -0
  164. package/src/providers/handlers/anthropic-base.ts +372 -0
  165. package/src/providers/handlers/asksage.test.ts +103 -0
  166. package/src/providers/handlers/asksage.ts +138 -0
  167. package/src/providers/handlers/auth.test.ts +19 -0
  168. package/src/providers/handlers/auth.ts +121 -0
  169. package/src/providers/handlers/base.test.ts +46 -0
  170. package/src/providers/handlers/base.ts +160 -0
  171. package/src/providers/handlers/bedrock-base.ts +390 -0
  172. package/src/providers/handlers/bedrock-client.ts +100 -0
  173. package/src/providers/handlers/codex.test.ts +123 -0
  174. package/src/providers/handlers/community-sdk.test.ts +288 -0
  175. package/src/providers/handlers/community-sdk.ts +392 -0
  176. package/src/providers/handlers/fetch-base.ts +68 -0
  177. package/src/providers/handlers/gemini-base.ts +302 -0
  178. package/src/providers/handlers/index.ts +67 -0
  179. package/src/providers/handlers/openai-base.ts +277 -0
  180. package/src/providers/handlers/openai-responses.ts +598 -0
  181. package/src/providers/handlers/providers.test.ts +120 -0
  182. package/src/providers/handlers/providers.ts +563 -0
  183. package/src/providers/handlers/r1-base.ts +280 -0
  184. package/src/providers/handlers/registry.ts +185 -0
  185. package/src/providers/handlers/vertex.test.ts +124 -0
  186. package/src/providers/handlers/vertex.ts +292 -0
  187. package/src/providers/index.ts +534 -0
  188. package/src/providers/public.browser.ts +20 -0
  189. package/src/providers/public.ts +51 -0
  190. package/src/providers/shared/openai-compatible.ts +63 -0
  191. package/src/providers/transform/ai-sdk-community-format.test.ts +73 -0
  192. package/src/providers/transform/ai-sdk-community-format.ts +115 -0
  193. package/src/providers/transform/anthropic-format.ts +218 -0
  194. package/src/providers/transform/content-format.ts +34 -0
  195. package/src/providers/transform/format-conversion.test.ts +310 -0
  196. package/src/providers/transform/gemini-format.ts +167 -0
  197. package/src/providers/transform/index.ts +22 -0
  198. package/src/providers/transform/openai-format.ts +247 -0
  199. package/src/providers/transform/r1-format.ts +287 -0
  200. package/src/providers/types/config.ts +388 -0
  201. package/src/providers/types/handler.ts +87 -0
  202. package/src/providers/types/index.ts +120 -0
  203. package/src/providers/types/messages.ts +158 -0
  204. package/src/providers/types/model-info.test.ts +57 -0
  205. package/src/providers/types/model-info.ts +65 -0
  206. package/src/providers/types/provider-ids.test.ts +12 -0
  207. package/src/providers/types/provider-ids.ts +89 -0
  208. package/src/providers/types/settings.test.ts +49 -0
  209. package/src/providers/types/settings.ts +533 -0
  210. package/src/providers/types/stream.ts +117 -0
  211. package/src/providers/utils/index.ts +27 -0
  212. package/src/providers/utils/retry.test.ts +140 -0
  213. package/src/providers/utils/retry.ts +188 -0
  214. package/src/providers/utils/stream-processor.test.ts +232 -0
  215. package/src/providers/utils/stream-processor.ts +472 -0
  216. package/src/providers/utils/tool-processor.test.ts +34 -0
  217. package/src/providers/utils/tool-processor.ts +111 -0
  218. package/src/sdk.ts +264 -0
  219. package/src/types.ts +79 -0
@@ -0,0 +1,226 @@
1
+ import type { ApiStream } from "../types";
2
+
3
+ export type {
4
+ AiSdkMessage,
5
+ AiSdkMessagePart,
6
+ } from "../transform/ai-sdk-community-format";
7
+ export { toAiSdkMessages } from "../transform/ai-sdk-community-format";
8
+
9
+ type AiSdkStreamPart = {
10
+ type?: string;
11
+ [key: string]: unknown;
12
+ };
13
+
14
+ type AiSdkUsage = {
15
+ inputTokens?: unknown;
16
+ outputTokens?: unknown;
17
+ reasoningTokens?: unknown;
18
+ thoughtsTokenCount?: unknown;
19
+ cachedInputTokens?: unknown;
20
+ };
21
+
22
+ export type AiSdkStream = {
23
+ fullStream?: AsyncIterable<AiSdkStreamPart>;
24
+ textStream?: AsyncIterable<string>;
25
+ text?: Promise<string> | string;
26
+ usage?: Promise<Record<string, unknown>>;
27
+ };
28
+
29
+ type AiSdkUsageMetrics = {
30
+ inputTokens: number;
31
+ outputTokens: number;
32
+ thoughtsTokenCount: number;
33
+ cacheReadTokens: number;
34
+ cacheWriteTokens?: number;
35
+ };
36
+
37
+ export type EmitAiSdkStreamOptions = {
38
+ responseId: string;
39
+ errorMessage: string;
40
+ calculateCost: (
41
+ inputTokens: number,
42
+ outputTokens: number,
43
+ cacheReadTokens: number,
44
+ ) => number | undefined;
45
+ reasoningTypes?: string[];
46
+ enableToolCalls?: boolean;
47
+ toolCallArgsOrder?: Array<"args" | "input">;
48
+ toolCallFunctionIncludeId?: boolean;
49
+ enableTextFallback?: boolean;
50
+ resolveUsageMetrics?: (
51
+ usage: AiSdkUsage,
52
+ part?: AiSdkStreamPart,
53
+ ) => AiSdkUsageMetrics;
54
+ };
55
+
56
+ let cachedAiModule: {
57
+ streamText: (input: Record<string, unknown>) => AiSdkStream;
58
+ } | null = null;
59
+
60
+ export type LoadAiSdkOptions = {
61
+ beforeImport?: () => void;
62
+ };
63
+
64
+ export async function loadAiSdkModule(options?: LoadAiSdkOptions): Promise<{
65
+ streamText: (input: Record<string, unknown>) => AiSdkStream;
66
+ }> {
67
+ if (cachedAiModule) {
68
+ return cachedAiModule;
69
+ }
70
+ options?.beforeImport?.();
71
+ cachedAiModule = (await import("ai")) as unknown as {
72
+ streamText: (input: Record<string, unknown>) => AiSdkStream;
73
+ };
74
+ return cachedAiModule;
75
+ }
76
+
77
+ export function numberOrZero(value: unknown): number {
78
+ return typeof value === "number" && Number.isFinite(value) ? value : 0;
79
+ }
80
+
81
+ function defaultResolveUsageMetrics(usage: AiSdkUsage): AiSdkUsageMetrics {
82
+ return {
83
+ inputTokens: numberOrZero(usage.inputTokens),
84
+ outputTokens: numberOrZero(usage.outputTokens),
85
+ thoughtsTokenCount: numberOrZero(
86
+ usage.reasoningTokens ?? usage.thoughtsTokenCount,
87
+ ),
88
+ cacheReadTokens: numberOrZero(usage.cachedInputTokens),
89
+ };
90
+ }
91
+
92
+ export async function* emitAiSdkStream(
93
+ stream: AiSdkStream,
94
+ options: EmitAiSdkStreamOptions,
95
+ ): ApiStream {
96
+ const resolveUsageMetrics =
97
+ options.resolveUsageMetrics ?? defaultResolveUsageMetrics;
98
+ const reasoningTypes = new Set(options.reasoningTypes ?? ["reasoning-delta"]);
99
+ const toolCallArgsOrder = options.toolCallArgsOrder ?? ["args", "input"];
100
+ const responseId = options.responseId;
101
+
102
+ let usageEmitted = false;
103
+ let textEmitted = false;
104
+
105
+ if (stream.fullStream) {
106
+ for await (const part of stream.fullStream) {
107
+ const partType = part.type;
108
+
109
+ if (partType === "text-delta") {
110
+ const text =
111
+ (part.textDelta as string | undefined) ??
112
+ (part.text as string | undefined) ??
113
+ (part.delta as string | undefined);
114
+ if (text) {
115
+ yield { type: "text", text, id: responseId };
116
+ textEmitted = true;
117
+ }
118
+ continue;
119
+ }
120
+
121
+ if (partType && reasoningTypes.has(partType)) {
122
+ const reasoning =
123
+ (part.textDelta as string | undefined) ??
124
+ (part.reasoning as string | undefined) ??
125
+ (part.text as string | undefined);
126
+ if (reasoning) {
127
+ yield { type: "reasoning", reasoning, id: responseId };
128
+ }
129
+ continue;
130
+ }
131
+
132
+ if (partType === "tool-call" && options.enableToolCalls) {
133
+ const toolCallId =
134
+ (part.toolCallId as string | undefined) ??
135
+ (part.id as string | undefined);
136
+ const toolName =
137
+ (part.toolName as string | undefined) ??
138
+ (part.name as string | undefined);
139
+ const args =
140
+ toolCallArgsOrder
141
+ .map((key) => part[key] as Record<string, unknown> | undefined)
142
+ .find((candidate) => candidate !== undefined) ?? {};
143
+
144
+ yield {
145
+ type: "tool_calls",
146
+ id: responseId,
147
+ tool_call: {
148
+ call_id: toolCallId,
149
+ function: {
150
+ id: options.toolCallFunctionIncludeId ? toolCallId : undefined,
151
+ name: toolName,
152
+ arguments: args,
153
+ },
154
+ },
155
+ };
156
+ continue;
157
+ }
158
+
159
+ if (partType === "error") {
160
+ const message =
161
+ (part.error as Error | undefined)?.message ?? options.errorMessage;
162
+ throw new Error(message);
163
+ }
164
+
165
+ if (partType === "finish") {
166
+ const usage = (part.totalUsage ?? part.usage ?? {}) as AiSdkUsage;
167
+ const usageMetrics = resolveUsageMetrics(usage, part);
168
+
169
+ yield {
170
+ type: "usage",
171
+ inputTokens: Math.max(
172
+ 0,
173
+ usageMetrics.inputTokens - usageMetrics.cacheReadTokens,
174
+ ),
175
+ outputTokens: usageMetrics.outputTokens,
176
+ thoughtsTokenCount: usageMetrics.thoughtsTokenCount,
177
+ cacheReadTokens: usageMetrics.cacheReadTokens,
178
+ cacheWriteTokens: usageMetrics.cacheWriteTokens,
179
+ totalCost: options.calculateCost(
180
+ usageMetrics.inputTokens,
181
+ usageMetrics.outputTokens,
182
+ usageMetrics.cacheReadTokens,
183
+ ),
184
+ id: responseId,
185
+ };
186
+ usageEmitted = true;
187
+ }
188
+ }
189
+ } else if (stream.textStream) {
190
+ for await (const text of stream.textStream) {
191
+ yield { type: "text", text, id: responseId };
192
+ textEmitted = true;
193
+ }
194
+ }
195
+
196
+ if (!textEmitted && options.enableTextFallback && stream.text) {
197
+ const text = await stream.text;
198
+ if (typeof text === "string" && text.length > 0) {
199
+ yield { type: "text", text, id: responseId };
200
+ }
201
+ }
202
+
203
+ if (!usageEmitted && stream.usage) {
204
+ const usage = (await stream.usage) as AiSdkUsage;
205
+ const usageMetrics = resolveUsageMetrics(usage);
206
+ yield {
207
+ type: "usage",
208
+ inputTokens: Math.max(
209
+ 0,
210
+ usageMetrics.inputTokens - usageMetrics.cacheReadTokens,
211
+ ),
212
+ outputTokens: usageMetrics.outputTokens,
213
+ thoughtsTokenCount: usageMetrics.thoughtsTokenCount,
214
+ cacheReadTokens: usageMetrics.cacheReadTokens,
215
+ cacheWriteTokens: usageMetrics.cacheWriteTokens,
216
+ totalCost: options.calculateCost(
217
+ usageMetrics.inputTokens,
218
+ usageMetrics.outputTokens,
219
+ usageMetrics.cacheReadTokens,
220
+ ),
221
+ id: responseId,
222
+ };
223
+ }
224
+
225
+ yield { type: "done", success: true, id: responseId };
226
+ }
@@ -0,0 +1,193 @@
1
+ import { toAiSdkMessages } from "../transform/ai-sdk-community-format";
2
+ import type { ApiStream, HandlerModelInfo, ProviderConfig } from "../types";
3
+ import type { Message, ToolDefinition } from "../types/messages";
4
+ import { retryStream } from "../utils/retry";
5
+ import {
6
+ type EmitAiSdkStreamOptions,
7
+ emitAiSdkStream,
8
+ type LoadAiSdkOptions,
9
+ loadAiSdkModule,
10
+ } from "./ai-sdk-community";
11
+ import { BaseHandler } from "./base";
12
+
13
+ type AiSdkCommunityProvider = (
14
+ modelId: string,
15
+ settings?: Record<string, unknown>,
16
+ ) => unknown;
17
+
18
+ type ProviderModule = Record<string, unknown>;
19
+
20
+ const providerModuleCache = new Map<string, ProviderModule>();
21
+
22
+ type CommunityProviderDefinition = {
23
+ moduleName: string;
24
+ createExportName: string;
25
+ providerExportName: string;
26
+ missingDependencyError: string;
27
+ };
28
+
29
+ export function resolveHandlerModel(
30
+ config: ProviderConfig,
31
+ defaultModelId?: string,
32
+ ): HandlerModelInfo {
33
+ const configuredModelId = config.modelId?.trim();
34
+ const modelId =
35
+ configuredModelId && configuredModelId.length > 0
36
+ ? configuredModelId
37
+ : (defaultModelId ?? "");
38
+ const knownModels = config.knownModels ?? {};
39
+ const fallbackModel = knownModels[modelId] ?? {};
40
+ const modelInfo = config.modelInfo ?? fallbackModel;
41
+ return { id: modelId, info: { ...modelInfo, id: modelId } };
42
+ }
43
+
44
+ async function loadProviderModule(moduleName: string): Promise<ProviderModule> {
45
+ const cached = providerModuleCache.get(moduleName);
46
+ if (cached) {
47
+ return cached;
48
+ }
49
+ const loaded = (await import(moduleName)) as ProviderModule;
50
+ providerModuleCache.set(moduleName, loaded);
51
+ return loaded;
52
+ }
53
+
54
+ export abstract class AiSdkProviderHandler extends BaseHandler {
55
+ private provider: AiSdkCommunityProvider | undefined;
56
+ private providerPromise: Promise<AiSdkCommunityProvider> | undefined;
57
+
58
+ protected abstract getProviderDefinition(): CommunityProviderDefinition;
59
+ protected abstract getDefaultModelId(): string;
60
+
61
+ protected getProviderCreateOptions(): Record<string, unknown> | undefined {
62
+ return undefined;
63
+ }
64
+
65
+ protected async beforeLoadProviderModule(): Promise<void> {}
66
+
67
+ protected getProviderModelSettings(): Record<string, unknown> | undefined {
68
+ return undefined;
69
+ }
70
+
71
+ protected getLoadAiSdkOptions(): LoadAiSdkOptions | undefined {
72
+ return undefined;
73
+ }
74
+
75
+ protected getStreamErrorMessage(): string {
76
+ return "AI SDK stream failed";
77
+ }
78
+
79
+ protected getEmitStreamOptions(): Omit<
80
+ EmitAiSdkStreamOptions,
81
+ "responseId" | "errorMessage" | "calculateCost"
82
+ > {
83
+ return {};
84
+ }
85
+
86
+ protected getAssistantToolCallArgKey(): "args" | "input" {
87
+ return "args";
88
+ }
89
+
90
+ protected normalizeModelId(modelId: string): string {
91
+ return modelId;
92
+ }
93
+
94
+ protected async ensureProvider(): Promise<AiSdkCommunityProvider> {
95
+ if (this.provider) {
96
+ return this.provider;
97
+ }
98
+ if (!this.providerPromise) {
99
+ this.providerPromise = (async () => {
100
+ const definition = this.getProviderDefinition();
101
+ await this.beforeLoadProviderModule();
102
+ const module = await loadProviderModule(definition.moduleName);
103
+
104
+ const createProvider = module[definition.createExportName] as
105
+ | ((options?: Record<string, unknown>) => AiSdkCommunityProvider)
106
+ | undefined;
107
+ const provider = module[definition.providerExportName] as
108
+ | AiSdkCommunityProvider
109
+ | undefined;
110
+
111
+ if (createProvider) {
112
+ const created = createProvider(this.getProviderCreateOptions());
113
+ this.provider = created;
114
+ return created;
115
+ }
116
+
117
+ if (provider) {
118
+ this.provider = provider;
119
+ return provider;
120
+ }
121
+
122
+ throw new Error(
123
+ `${definition.moduleName} did not export \`${definition.providerExportName}\` or \`${definition.createExportName}\`.`,
124
+ );
125
+ })();
126
+ }
127
+
128
+ try {
129
+ return await this.providerPromise;
130
+ } catch (error) {
131
+ this.providerPromise = undefined;
132
+ const moduleName = this.getProviderDefinition().moduleName;
133
+ if (error instanceof Error && error.message.includes(moduleName)) {
134
+ throw new Error(this.getProviderDefinition().missingDependencyError, {
135
+ cause: error,
136
+ });
137
+ }
138
+ throw error;
139
+ }
140
+ }
141
+
142
+ getModel(): HandlerModelInfo {
143
+ return resolveHandlerModel(this.config, this.getDefaultModelId());
144
+ }
145
+
146
+ getMessages(systemPrompt: string, messages: Message[]) {
147
+ return toAiSdkMessages(systemPrompt, messages, {
148
+ assistantToolCallArgKey: this.getAssistantToolCallArgKey(),
149
+ });
150
+ }
151
+
152
+ async *createMessage(
153
+ systemPrompt: string,
154
+ messages: Message[],
155
+ tools?: ToolDefinition[],
156
+ ): ApiStream {
157
+ yield* retryStream(() =>
158
+ this.createMessageInternal(systemPrompt, messages, tools),
159
+ );
160
+ }
161
+
162
+ private async *createMessageInternal(
163
+ systemPrompt: string,
164
+ messages: Message[],
165
+ tools?: ToolDefinition[],
166
+ ): ApiStream {
167
+ void tools;
168
+
169
+ const ai = await loadAiSdkModule(this.getLoadAiSdkOptions());
170
+ const provider = await this.ensureProvider();
171
+ const { id: modelId, info } = this.getModel();
172
+ const responseId = this.createResponseId();
173
+
174
+ const stream = ai.streamText({
175
+ model: provider(
176
+ this.normalizeModelId(modelId),
177
+ this.getProviderModelSettings(),
178
+ ),
179
+ messages: this.getMessages(systemPrompt, messages),
180
+ maxTokens: info.maxTokens ?? undefined,
181
+ temperature: info.temperature ?? undefined,
182
+ abortSignal: this.getAbortSignal(),
183
+ });
184
+
185
+ yield* emitAiSdkStream(stream, {
186
+ responseId,
187
+ errorMessage: this.getStreamErrorMessage(),
188
+ calculateCost: (inputTokens, outputTokens, cacheReadTokens) =>
189
+ this.calculateCost(inputTokens, outputTokens, cacheReadTokens),
190
+ ...this.getEmitStreamOptions(),
191
+ });
192
+ }
193
+ }