@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,534 @@
1
+ /**
2
+ * @clinebot/providers
3
+ *
4
+ * SDK-like package for creating and managing LLM provider handlers.
5
+ *
6
+ * This package provides a unified interface for interacting with various LLM providers.
7
+ * It standardizes configuration, message formats, and streaming responses.
8
+ *
9
+ * ## Quick Start
10
+ *
11
+ * ```typescript
12
+ * import { createHandler, type ProviderConfig } from "@clinebot/providers"
13
+ *
14
+ * const config: ProviderConfig = {
15
+ * providerId: "anthropic",
16
+ * apiKey: process.env.ANTHROPIC_API_KEY,
17
+ * modelId: "claude-sonnet-4-20250514",
18
+ * }
19
+ *
20
+ * const handler = createHandler(config)
21
+ * const stream = handler.createMessage("You are a helpful assistant.", messages)
22
+ *
23
+ * for await (const chunk of stream) {
24
+ * if (chunk.type === "text") {
25
+ * process.stdout.write(chunk.text)
26
+ * }
27
+ * }
28
+ * ```
29
+ *
30
+ * ## Supported Providers
31
+ *
32
+ * - **anthropic**: Anthropic's Claude models
33
+ * - **claude-code**: Claude Code local subscription provider
34
+ * - **gemini**: Google's Gemini models (including Vertex AI)
35
+ * - **openai**: OpenAI's GPT models
36
+ * - **openai-compat**: Any OpenAI-compatible API (DeepSeek, xAI, Together, etc.)
37
+ *
38
+ * @module
39
+ */
40
+
41
+ // =============================================================================
42
+ // Types
43
+ // =============================================================================
44
+
45
+ export {
46
+ ApiFormat,
47
+ // Handler types
48
+ type ApiHandler,
49
+ // Stream types
50
+ type ApiStream,
51
+ type ApiStreamChunk,
52
+ type ApiStreamReasoningChunk,
53
+ type ApiStreamTextChunk,
54
+ type ApiStreamToolCall,
55
+ type ApiStreamToolCallsChunk,
56
+ type ApiStreamUsageChunk,
57
+ type AuthConfig,
58
+ type AuthSettings,
59
+ AuthSettingsSchema,
60
+ type AwsConfig,
61
+ type AwsSettings,
62
+ AwsSettingsSchema,
63
+ type AzureConfig,
64
+ type AzureSettings,
65
+ AzureSettingsSchema,
66
+ type BuiltInProviderId,
67
+ type CloudConfig,
68
+ type ContentBlock,
69
+ createConfig,
70
+ createProviderConfig,
71
+ type EndpointConfig,
72
+ type FileContent,
73
+ type GcpConfig,
74
+ type GcpSettings,
75
+ GcpSettingsSchema,
76
+ getModelPricing,
77
+ type HandlerFactory,
78
+ type HandlerModelInfo,
79
+ hasCapability,
80
+ hasModelCapability,
81
+ type ImageContent,
82
+ type LazyHandlerFactory,
83
+ // Message types
84
+ type Message,
85
+ type MessageRole,
86
+ type MessageWithMetadata,
87
+ type ModelCapability,
88
+ type ModelCatalogConfig,
89
+ type ModelCatalogSettings,
90
+ ModelCatalogSettingsSchema,
91
+ type ModelConfig,
92
+ // Model types
93
+ type ModelInfo,
94
+ type ModelPricing,
95
+ type ModelWithId,
96
+ type OcaConfig,
97
+ type OcaSettings,
98
+ OcaSettingsSchema,
99
+ type OpenAICompatibleModelInfo,
100
+ type ProviderCapability,
101
+ type ProviderCategory,
102
+ type ProviderConfig,
103
+ type ProviderDefaultsConfig,
104
+ // Config types
105
+ type ProviderId,
106
+ // Settings types and functions (Zod-based validation)
107
+ ProviderIdSchema,
108
+ type ProviderOptions,
109
+ type ProviderSettings,
110
+ ProviderSettingsSchema,
111
+ type ProviderSpecificConfig,
112
+ parseSettings,
113
+ type ReasoningConfig,
114
+ type ReasoningSettings,
115
+ ReasoningSettingsSchema,
116
+ type RedactedThinkingContent,
117
+ type RegionConfig,
118
+ type SapConfig,
119
+ type SapSettings,
120
+ SapSettingsSchema,
121
+ type SimpleProviderConfig,
122
+ type SingleCompletionHandler,
123
+ safeCreateProviderConfig,
124
+ safeParseSettings,
125
+ supportsPromptCache,
126
+ supportsReasoning,
127
+ type TextContent,
128
+ type ThinkingConfig,
129
+ type ThinkingContent,
130
+ type TokenConfig,
131
+ type ToolDefinition,
132
+ type ToolResultContent,
133
+ type ToolUseContent,
134
+ toProviderConfig,
135
+ } from "./types";
136
+
137
+ // =============================================================================
138
+ // Handlers
139
+ // =============================================================================
140
+
141
+ export {
142
+ // Provider-specific handlers
143
+ AnthropicHandler,
144
+ AskSageHandler,
145
+ // Base classes (for extension)
146
+ BaseHandler,
147
+ ClaudeCodeHandler,
148
+ CodexHandler,
149
+ clearLiveModelsCatalogCache,
150
+ clearPrivateModelsCatalogCache,
151
+ // Custom handler registry
152
+ clearRegistry,
153
+ createAnthropicHandler,
154
+ createAskSageHandler,
155
+ createClaudeCodeHandler,
156
+ createCodexHandler,
157
+ createDifyHandler,
158
+ createGeminiHandler,
159
+ createMistralHandler,
160
+ createOpenAIHandler,
161
+ createOpenAIResponsesHandler,
162
+ createOpenCodeHandler,
163
+ createR1Handler,
164
+ createSapAiCoreHandler,
165
+ createVertexHandler,
166
+ DEFAULT_MODELS_CATALOG_URL,
167
+ DifyHandler,
168
+ GeminiHandler,
169
+ getLiveModelsCatalog,
170
+ getMissingApiKeyError,
171
+ getProviderConfig,
172
+ getRegisteredHandler,
173
+ getRegisteredHandlerAsync,
174
+ getRegisteredProviderIds,
175
+ hasRegisteredHandler,
176
+ isOpenAICompatibleProvider,
177
+ isRegisteredHandlerAsync,
178
+ MistralHandler,
179
+ normalizeProviderId,
180
+ // Provider configs
181
+ OPENAI_COMPATIBLE_PROVIDERS,
182
+ // OpenAI Chat Completions API handler
183
+ OpenAIBaseHandler,
184
+ // OpenAI Responses API handler
185
+ OpenAIResponsesHandler,
186
+ OpenCodeHandler,
187
+ // R1-based handlers (DeepSeek Reasoner, etc.)
188
+ R1BaseHandler,
189
+ registerAsyncHandler,
190
+ registerHandler,
191
+ resolveProviderConfig,
192
+ SapAiCoreHandler,
193
+ unregisterHandler,
194
+ // Vertex AI handler
195
+ VertexHandler,
196
+ } from "./handlers";
197
+
198
+ // =============================================================================
199
+ // Transform utilities
200
+ // =============================================================================
201
+
202
+ export {
203
+ convertToAnthropicMessages,
204
+ convertToGeminiMessages,
205
+ convertToOpenAIMessages,
206
+ convertToolsToAnthropic,
207
+ convertToolsToGemini,
208
+ convertToolsToOpenAI,
209
+ // R1 format (DeepSeek Reasoner, etc.)
210
+ convertToR1Messages,
211
+ getOpenAIToolParams,
212
+ type R1Message,
213
+ } from "./transform";
214
+
215
+ // =============================================================================
216
+ // Utilities
217
+ // =============================================================================
218
+
219
+ export {
220
+ type AssistantContentBlock,
221
+ type AssistantRedactedThinkingBlock,
222
+ type AssistantTextBlock,
223
+ type AssistantThinkingBlock,
224
+ type AssistantToolUseBlock,
225
+ calculateRetryDelay,
226
+ isRetriableError,
227
+ type ProcessedResponse,
228
+ type ReasoningDetailParam,
229
+ RetriableError,
230
+ type RetryOptions,
231
+ retryAsync,
232
+ retryStream,
233
+ // Stream processor
234
+ StreamResponseProcessor,
235
+ sleep,
236
+ ToolCallProcessor,
237
+ type UsageInfo,
238
+ } from "./utils";
239
+
240
+ import { CLINE_PROVIDER } from "../models";
241
+ import {
242
+ DEFAULT_EXTERNAL_OCA_BASE_URL,
243
+ DEFAULT_INTERNAL_OCA_BASE_URL,
244
+ } from "../models/providers/oca";
245
+ // =============================================================================
246
+ // Main Factory Function
247
+ // =============================================================================
248
+
249
+ import { AnthropicHandler } from "./handlers/anthropic-base";
250
+ import { AskSageHandler } from "./handlers/asksage";
251
+ import { BedrockHandler } from "./handlers/bedrock-base";
252
+ import {
253
+ ClaudeCodeHandler,
254
+ CodexHandler,
255
+ DifyHandler,
256
+ MistralHandler,
257
+ OpenCodeHandler,
258
+ SapAiCoreHandler,
259
+ } from "./handlers/community-sdk";
260
+ import { GeminiHandler } from "./handlers/gemini-base";
261
+ import { OpenAIBaseHandler } from "./handlers/openai-base";
262
+ import { OpenAIResponsesHandler } from "./handlers/openai-responses";
263
+ import {
264
+ isOpenAICompatibleProvider,
265
+ OPENAI_COMPATIBLE_PROVIDERS,
266
+ type ProviderDefaults,
267
+ resolveProviderConfig,
268
+ } from "./handlers/providers";
269
+ import {
270
+ getRegisteredHandler,
271
+ getRegisteredHandlerAsync,
272
+ hasRegisteredHandler,
273
+ isRegisteredHandlerAsync,
274
+ } from "./handlers/registry";
275
+ import { VertexHandler } from "./handlers/vertex";
276
+ import {
277
+ ApiFormat,
278
+ type ApiHandler,
279
+ BUILT_IN_PROVIDER,
280
+ normalizeProviderId,
281
+ type ProviderConfig,
282
+ type ProviderId,
283
+ } from "./types";
284
+
285
+ function withNormalizedProviderId(config: ProviderConfig): ProviderConfig {
286
+ const normalizedProviderId = normalizeProviderId(config.providerId);
287
+ if (normalizedProviderId === config.providerId) {
288
+ return config;
289
+ }
290
+ return {
291
+ ...config,
292
+ providerId: normalizedProviderId,
293
+ };
294
+ }
295
+
296
+ function resolveOcaBaseUrl(
297
+ config: ProviderConfig,
298
+ providerDefaults?: { baseUrl: string },
299
+ ): string {
300
+ if (config.baseUrl) {
301
+ return config.baseUrl;
302
+ }
303
+ if (config.oca?.mode === "internal") {
304
+ return DEFAULT_INTERNAL_OCA_BASE_URL;
305
+ }
306
+ return providerDefaults?.baseUrl ?? DEFAULT_EXTERNAL_OCA_BASE_URL;
307
+ }
308
+
309
+ function resolveOcaApiFormat(config: ProviderConfig): string | undefined {
310
+ const modelId = config.modelId;
311
+ return (
312
+ config.modelInfo?.apiFormat ??
313
+ (modelId ? config.knownModels?.[modelId]?.apiFormat : undefined)
314
+ );
315
+ }
316
+
317
+ function createOcaHandler(config: ProviderConfig): ApiHandler {
318
+ const apiFormat = resolveOcaApiFormat(config);
319
+ if (apiFormat === ApiFormat.OPENAI_RESPONSES) {
320
+ return new OpenAIResponsesHandler(config);
321
+ }
322
+ return new OpenAIBaseHandler(config);
323
+ }
324
+
325
+ function mergeProviderDefaults(
326
+ config: ProviderConfig,
327
+ defaults: ProviderDefaults,
328
+ ): ProviderConfig {
329
+ return {
330
+ ...config,
331
+ baseUrl:
332
+ config.providerId === BUILT_IN_PROVIDER.OCA
333
+ ? resolveOcaBaseUrl(config, defaults)
334
+ : (config.baseUrl ?? defaults.baseUrl),
335
+ modelId: config.modelId ?? defaults.modelId,
336
+ knownModels: config.knownModels ?? defaults.knownModels,
337
+ capabilities: config.capabilities ?? defaults.capabilities,
338
+ };
339
+ }
340
+
341
+ type HandlerFactory = (config: ProviderConfig) => ApiHandler;
342
+
343
+ const BUILT_IN_HANDLER_FACTORIES: Record<string, HandlerFactory> = {
344
+ [BUILT_IN_PROVIDER.ASKSAGE]: (config) => new AskSageHandler(config),
345
+ [BUILT_IN_PROVIDER.ANTHROPIC]: (config) => new AnthropicHandler(config),
346
+ [BUILT_IN_PROVIDER.BEDROCK]: (config) => new BedrockHandler(config),
347
+ [BUILT_IN_PROVIDER.CLAUDE_CODE]: (config) => new ClaudeCodeHandler(config),
348
+ [BUILT_IN_PROVIDER.GEMINI]: (config) => new GeminiHandler(config),
349
+ [BUILT_IN_PROVIDER.VERTEX]: (config) => new VertexHandler(config),
350
+ [BUILT_IN_PROVIDER.OPENCODE]: (config) => new OpenCodeHandler(config),
351
+ [BUILT_IN_PROVIDER.OPENAI_NATIVE]: (config) =>
352
+ new OpenAIResponsesHandler(config),
353
+ [BUILT_IN_PROVIDER.MISTRAL]: (config) => new MistralHandler(config),
354
+ [BUILT_IN_PROVIDER.DIFY]: (config) => new DifyHandler(config),
355
+ };
356
+
357
+ function createOpenAICompatibleHandler(config: ProviderConfig): ApiHandler {
358
+ if (config.providerId === BUILT_IN_PROVIDER.OPENAI_CODEX) {
359
+ return new CodexHandler(config);
360
+ }
361
+ if (config.providerId === BUILT_IN_PROVIDER.SAPAICORE) {
362
+ return new SapAiCoreHandler(config);
363
+ }
364
+ if (config.providerId === BUILT_IN_PROVIDER.OCA) {
365
+ return createOcaHandler(config);
366
+ }
367
+ return new OpenAIBaseHandler(config);
368
+ }
369
+
370
+ function createBuiltInHandler(config: ProviderConfig): ApiHandler | undefined {
371
+ const factory = BUILT_IN_HANDLER_FACTORIES[config.providerId];
372
+ return factory ? factory(config) : undefined;
373
+ }
374
+
375
+ /**
376
+ * Create an API handler for the specified provider
377
+ *
378
+ * This is the main entry point for creating handlers. It automatically
379
+ * selects the appropriate handler class based on the provider ID.
380
+ *
381
+ * Custom handlers registered via `registerHandler()` take precedence over
382
+ * built-in handlers.
383
+ *
384
+ * @param config - Provider configuration
385
+ * @returns An API handler instance
386
+ * @throws Error if the provider has an async handler - use `createHandlerAsync()` instead
387
+ *
388
+ * @example
389
+ * ```typescript
390
+ * const handler = createHandler({
391
+ * providerId: "anthropic",
392
+ * apiKey: "sk-...",
393
+ * modelId: "claude-sonnet-4-20250514",
394
+ * })
395
+ * ```
396
+ */
397
+ export function createHandler(config: ProviderConfig): ApiHandler {
398
+ const normalizedConfig = withNormalizedProviderId(config);
399
+ const { providerId } = normalizedConfig;
400
+
401
+ // Check custom registry first (allows overriding built-in handlers)
402
+ if (hasRegisteredHandler(providerId)) {
403
+ if (isRegisteredHandlerAsync(providerId)) {
404
+ throw new Error(
405
+ `Handler for "${providerId}" is registered as async. Use createHandlerAsync() instead.`,
406
+ );
407
+ }
408
+ const handler = getRegisteredHandler(providerId, normalizedConfig);
409
+ if (handler) {
410
+ return handler;
411
+ }
412
+ }
413
+
414
+ const builtInHandler = createBuiltInHandler(normalizedConfig);
415
+ if (builtInHandler) {
416
+ return builtInHandler;
417
+ }
418
+
419
+ // Check if it's an OpenAI-compatible provider
420
+ if (isOpenAICompatibleProvider(providerId)) {
421
+ if (
422
+ normalizedConfig.modelCatalog?.loadLatestOnInit ||
423
+ normalizedConfig.modelCatalog?.loadPrivateOnAuth
424
+ ) {
425
+ throw new Error(
426
+ `Provider "${providerId}" has runtime model refresh enabled. Use createHandlerAsync() to allow async model refresh.`,
427
+ );
428
+ }
429
+ const providerDefaults = OPENAI_COMPATIBLE_PROVIDERS[providerId];
430
+ return createOpenAICompatibleHandler(
431
+ mergeProviderDefaults(normalizedConfig, providerDefaults),
432
+ );
433
+ }
434
+
435
+ // Fall back to OpenAI-compatible with custom base URL
436
+ return normalizedConfig.baseUrl
437
+ ? new OpenAIBaseHandler(normalizedConfig)
438
+ : new OpenAIResponsesHandler({
439
+ ...normalizedConfig,
440
+ baseUrl: "https://api.openai.com/v1",
441
+ });
442
+ }
443
+
444
+ /**
445
+ * Create an API handler asynchronously
446
+ *
447
+ * Use this when you have handlers registered with `registerAsyncHandler()`.
448
+ * This function works with both sync and async registered handlers.
449
+ *
450
+ * @param config - Provider configuration
451
+ * @returns Promise resolving to an API handler instance
452
+ *
453
+ * @example
454
+ * ```typescript
455
+ * // Register an async handler for lazy loading
456
+ * registerAsyncHandler("my-provider", async (config) => {
457
+ * const { MyHandler } = await import("./my-handler")
458
+ * return new MyHandler(config)
459
+ * })
460
+ *
461
+ * // Use createHandlerAsync to get the handler
462
+ * const handler = await createHandlerAsync({
463
+ * providerId: "my-provider",
464
+ * modelId: "my-model",
465
+ * })
466
+ * ```
467
+ */
468
+ export async function createHandlerAsync(
469
+ config: ProviderConfig,
470
+ ): Promise<ApiHandler> {
471
+ const normalizedConfig = withNormalizedProviderId(config);
472
+ const { providerId } = normalizedConfig;
473
+
474
+ // Check custom registry first (allows overriding built-in handlers)
475
+ if (hasRegisteredHandler(providerId)) {
476
+ const handler = await getRegisteredHandlerAsync(
477
+ providerId,
478
+ normalizedConfig,
479
+ );
480
+ if (handler) {
481
+ return handler;
482
+ }
483
+ }
484
+
485
+ if (isOpenAICompatibleProvider(providerId)) {
486
+ const providerDefaults = await resolveProviderConfig(
487
+ providerId,
488
+ normalizedConfig.modelCatalog,
489
+ normalizedConfig,
490
+ );
491
+ if (providerDefaults) {
492
+ return createOpenAICompatibleHandler(
493
+ mergeProviderDefaults(normalizedConfig, providerDefaults),
494
+ );
495
+ }
496
+ }
497
+
498
+ // Fall back to sync handler creation for built-in providers
499
+ return createHandler(normalizedConfig);
500
+ }
501
+
502
+ /**
503
+ * List of all built-in provider IDs
504
+ */
505
+ export const BUILT_IN_PROVIDERS: ProviderId[] = [
506
+ ...new Set<ProviderId>([
507
+ CLINE_PROVIDER.provider.id,
508
+ BUILT_IN_PROVIDER.ANTHROPIC,
509
+ BUILT_IN_PROVIDER.ASKSAGE,
510
+ BUILT_IN_PROVIDER.BEDROCK,
511
+ BUILT_IN_PROVIDER.CLAUDE_CODE,
512
+ BUILT_IN_PROVIDER.OPENCODE,
513
+ BUILT_IN_PROVIDER.MISTRAL,
514
+ BUILT_IN_PROVIDER.DIFY,
515
+ BUILT_IN_PROVIDER.OPENAI_NATIVE,
516
+ BUILT_IN_PROVIDER.GEMINI,
517
+ BUILT_IN_PROVIDER.VERTEX,
518
+ ...(Object.keys(OPENAI_COMPATIBLE_PROVIDERS) as ProviderId[]),
519
+ ]),
520
+ ];
521
+
522
+ const BUILT_IN_PROVIDER_SET = new Set<string>(BUILT_IN_PROVIDERS);
523
+
524
+ /**
525
+ * Check if a provider ID is supported (built-in or registered)
526
+ */
527
+ export function isProviderSupported(providerId: string): boolean {
528
+ const normalizedProviderId = normalizeProviderId(providerId);
529
+ return (
530
+ BUILT_IN_PROVIDER_SET.has(normalizedProviderId) ||
531
+ hasRegisteredHandler(normalizedProviderId) ||
532
+ hasRegisteredHandler(providerId)
533
+ );
534
+ }
@@ -0,0 +1,20 @@
1
+ export {
2
+ OPENAI_COMPATIBLE_PROVIDERS,
3
+ type ProviderDefaults,
4
+ } from "./handlers/providers";
5
+
6
+ export {
7
+ getModelPricing,
8
+ hasModelCapability,
9
+ type ModelCapability,
10
+ type ModelInfo,
11
+ type ModelPricing,
12
+ normalizeProviderId,
13
+ type ProviderCapability,
14
+ type ProviderId,
15
+ type ProviderSettings,
16
+ ProviderSettingsSchema,
17
+ parseSettings,
18
+ supportsModelThinking,
19
+ toProviderConfig,
20
+ } from "./types/index";
@@ -0,0 +1,51 @@
1
+ export {
2
+ OPENAI_COMPATIBLE_PROVIDERS,
3
+ type ProviderDefaults,
4
+ resolveProviderConfig,
5
+ } from "./handlers/providers";
6
+ export {
7
+ BUILT_IN_PROVIDERS,
8
+ createHandler,
9
+ createHandlerAsync,
10
+ isProviderSupported,
11
+ } from "./index";
12
+
13
+ export {
14
+ type ApiHandler,
15
+ type ApiStream,
16
+ type ApiStreamChunk,
17
+ type ApiStreamReasoningChunk,
18
+ type ApiStreamTextChunk,
19
+ type ApiStreamToolCall,
20
+ type ApiStreamToolCallsChunk,
21
+ type ApiStreamUsageChunk,
22
+ type ContentBlock,
23
+ type FileContent,
24
+ getModelPricing,
25
+ type HandlerFactory,
26
+ type HandlerModelInfo,
27
+ hasModelCapability,
28
+ type ImageContent,
29
+ type LazyHandlerFactory,
30
+ type Message,
31
+ type MessageRole,
32
+ type MessageWithMetadata,
33
+ type ModelCapability,
34
+ type ModelInfo,
35
+ type ModelPricing,
36
+ normalizeProviderId,
37
+ type ProviderCapability,
38
+ type ProviderConfig,
39
+ type ProviderId,
40
+ type ProviderSettings,
41
+ ProviderSettingsSchema,
42
+ parseSettings,
43
+ type RedactedThinkingContent,
44
+ supportsModelThinking,
45
+ type TextContent,
46
+ type ThinkingContent,
47
+ type ToolDefinition,
48
+ type ToolResultContent,
49
+ type ToolUseContent,
50
+ toProviderConfig,
51
+ } from "./types/index";
@@ -0,0 +1,63 @@
1
+ import * as modelProviderExports from "../../models/providers/index";
2
+ import type {
3
+ ModelCollection,
4
+ ModelInfo,
5
+ ProviderCapability,
6
+ ProviderProtocol,
7
+ } from "../../models/schemas/index";
8
+
9
+ export interface OpenAICompatibleProviderDefaults {
10
+ baseUrl: string;
11
+ modelId: string;
12
+ knownModels?: Record<string, ModelInfo>;
13
+ capabilities?: ProviderCapability[];
14
+ }
15
+
16
+ function isModelCollection(value: unknown): value is ModelCollection {
17
+ if (!value || typeof value !== "object") {
18
+ return false;
19
+ }
20
+
21
+ const maybeCollection = value as Partial<ModelCollection>;
22
+ return (
23
+ typeof maybeCollection.provider === "object" &&
24
+ typeof maybeCollection.models === "object"
25
+ );
26
+ }
27
+
28
+ function isOpenAICompatibleProtocol(
29
+ protocol: ProviderProtocol | undefined,
30
+ ): boolean {
31
+ return (
32
+ protocol === "openai-chat" ||
33
+ protocol === "openai-responses" ||
34
+ protocol === "openai-r1"
35
+ );
36
+ }
37
+
38
+ export function buildOpenAICompatibleProviderDefaults(options?: {
39
+ includeKnownModels?: boolean;
40
+ }): Record<string, OpenAICompatibleProviderDefaults> {
41
+ const defaults: Record<string, OpenAICompatibleProviderDefaults> = {};
42
+ const includeKnownModels = options?.includeKnownModels ?? false;
43
+
44
+ for (const value of Object.values(modelProviderExports)) {
45
+ if (!isModelCollection(value)) {
46
+ continue;
47
+ }
48
+
49
+ const provider = value.provider;
50
+ if (!isOpenAICompatibleProtocol(provider.protocol) || !provider.baseUrl) {
51
+ continue;
52
+ }
53
+
54
+ defaults[provider.id] = {
55
+ baseUrl: provider.baseUrl,
56
+ modelId: provider.defaultModelId,
57
+ knownModels: includeKnownModels ? value.models : undefined,
58
+ capabilities: provider.capabilities,
59
+ };
60
+ }
61
+
62
+ return defaults;
63
+ }