@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,511 @@
1
+ /**
2
+ * Model Registry
3
+ *
4
+ * Central registry for all model definitions across providers.
5
+ * Provides methods to access, query, and manage models.
6
+ *
7
+ * Uses lazy loading - providers are only loaded when first accessed.
8
+ */
9
+ import { GENERATED_PROVIDER_LOADER_ENTRIES } from "./generated-provider-loaders";
10
+ import type { ModelCollection, ModelInfo, ProviderInfo } from "./schemas/index";
11
+
12
+ // =============================================================================
13
+ // Types
14
+ // =============================================================================
15
+
16
+ interface ProviderLoaderConfig {
17
+ load: () => Promise<ModelCollection>;
18
+ }
19
+
20
+ type ProviderLoaderEntry = readonly [
21
+ providerId: string,
22
+ load: () => Promise<ModelCollection>,
23
+ ];
24
+
25
+ // =============================================================================
26
+ // Registry Storage
27
+ // =============================================================================
28
+
29
+ /**
30
+ * Loaded provider collections (cache)
31
+ */
32
+ const PROVIDER_CACHE: Map<string, ModelCollection> = new Map();
33
+
34
+ /**
35
+ * Provider loader configurations - maps provider ID to how to load it
36
+ */
37
+ const PROVIDER_LOADERS: Map<string, ProviderLoaderConfig> = new Map();
38
+
39
+ /**
40
+ * Custom models added at runtime
41
+ */
42
+ const CUSTOM_MODELS: Map<string, Map<string, ModelInfo>> = new Map();
43
+
44
+ /**
45
+ * Custom providers registered at runtime (not lazy loaded)
46
+ */
47
+ const CUSTOM_PROVIDERS: Map<string, ModelCollection> = new Map();
48
+
49
+ // =============================================================================
50
+ // Provider Loader Registration
51
+ // =============================================================================
52
+
53
+ /**
54
+ * Register built-in provider loaders (does not load the providers)
55
+ *
56
+ * Generated from provider module metadata at build time.
57
+ */
58
+ const BUILT_IN_PROVIDER_LOADER_ENTRIES: ProviderLoaderEntry[] =
59
+ GENERATED_PROVIDER_LOADER_ENTRIES;
60
+
61
+ function registerBuiltInProviderLoaders(): void {
62
+ for (const [providerId, load] of BUILT_IN_PROVIDER_LOADER_ENTRIES) {
63
+ PROVIDER_LOADERS.set(providerId, { load });
64
+ }
65
+ }
66
+
67
+ // Initialize loaders on module load (but not the actual providers)
68
+ registerBuiltInProviderLoaders();
69
+
70
+ // =============================================================================
71
+ // Lazy Loading
72
+ // =============================================================================
73
+
74
+ /**
75
+ * Dynamically load a provider module
76
+ */
77
+ async function loadProviderModule(
78
+ config: ProviderLoaderConfig,
79
+ ): Promise<ModelCollection> {
80
+ return config.load();
81
+ }
82
+
83
+ /**
84
+ * Get or load a provider collection (async)
85
+ */
86
+ async function getOrLoadProvider(
87
+ providerId: string,
88
+ ): Promise<ModelCollection | undefined> {
89
+ // Check custom providers first
90
+ if (CUSTOM_PROVIDERS.has(providerId)) {
91
+ return CUSTOM_PROVIDERS.get(providerId);
92
+ }
93
+
94
+ // Check cache
95
+ if (PROVIDER_CACHE.has(providerId)) {
96
+ return PROVIDER_CACHE.get(providerId);
97
+ }
98
+
99
+ // Check if we have a loader
100
+ const config = PROVIDER_LOADERS.get(providerId);
101
+ if (!config) {
102
+ return undefined;
103
+ }
104
+
105
+ // Load and cache
106
+ const collection = await loadProviderModule(config);
107
+ PROVIDER_CACHE.set(providerId, collection);
108
+ return collection;
109
+ }
110
+
111
+ /**
112
+ * Get provider from cache only (sync) - returns undefined if not loaded
113
+ */
114
+ function getProviderFromCache(providerId: string): ModelCollection | undefined {
115
+ return CUSTOM_PROVIDERS.get(providerId) ?? PROVIDER_CACHE.get(providerId);
116
+ }
117
+
118
+ // =============================================================================
119
+ // Provider Access
120
+ // =============================================================================
121
+
122
+ /**
123
+ * Get all registered provider IDs (does not load providers)
124
+ */
125
+ export function getProviderIds(): string[] {
126
+ const builtInIds = Array.from(PROVIDER_LOADERS.keys());
127
+ const customIds = Array.from(CUSTOM_PROVIDERS.keys()).filter(
128
+ (id) => !PROVIDER_LOADERS.has(id),
129
+ );
130
+ return [...builtInIds, ...customIds];
131
+ }
132
+
133
+ /**
134
+ * Check if a provider is registered (does not load it)
135
+ */
136
+ export function hasProvider(providerId: string): boolean {
137
+ return PROVIDER_LOADERS.has(providerId) || CUSTOM_PROVIDERS.has(providerId);
138
+ }
139
+
140
+ /**
141
+ * Get provider by ID (async - loads if needed)
142
+ */
143
+ export async function getProvider(
144
+ providerId: string,
145
+ ): Promise<ProviderInfo | undefined> {
146
+ const collection = await getOrLoadProvider(providerId);
147
+ return collection?.provider;
148
+ }
149
+
150
+ /**
151
+ * Get provider collection by ID (async - loads if needed)
152
+ */
153
+ export async function getProviderCollection(
154
+ providerId: string,
155
+ ): Promise<ModelCollection | undefined> {
156
+ return getOrLoadProvider(providerId);
157
+ }
158
+
159
+ /**
160
+ * Get all providers (async - loads all providers)
161
+ */
162
+ export async function getAllProviders(): Promise<ProviderInfo[]> {
163
+ const ids = getProviderIds();
164
+ const collections = await Promise.all(ids.map((id) => getOrLoadProvider(id)));
165
+ return collections
166
+ .filter((c): c is ModelCollection => c !== undefined)
167
+ .map((c) => c.provider);
168
+ }
169
+
170
+ /**
171
+ * Preload specific providers into cache
172
+ */
173
+ export async function preloadProviders(providerIds: string[]): Promise<void> {
174
+ await Promise.all(providerIds.map((id) => getOrLoadProvider(id)));
175
+ }
176
+
177
+ /**
178
+ * Preload all providers into cache
179
+ */
180
+ export async function preloadAllProviders(): Promise<void> {
181
+ await preloadProviders(getProviderIds());
182
+ }
183
+
184
+ // =============================================================================
185
+ // Sync Access (for already-loaded providers)
186
+ // =============================================================================
187
+
188
+ /**
189
+ * Get provider from cache (sync) - returns undefined if not loaded yet
190
+ * Use this when you know the provider has been preloaded
191
+ */
192
+ export function getProviderSync(providerId: string): ProviderInfo | undefined {
193
+ return getProviderFromCache(providerId)?.provider;
194
+ }
195
+
196
+ /**
197
+ * Get provider collection from cache (sync) - returns undefined if not loaded yet
198
+ * Use this when you know the provider has been preloaded
199
+ */
200
+ export function getProviderCollectionSync(
201
+ providerId: string,
202
+ ): ModelCollection | undefined {
203
+ return getProviderFromCache(providerId);
204
+ }
205
+
206
+ /**
207
+ * Get all loaded providers (sync) - only returns already-loaded providers
208
+ */
209
+ export function getLoadedProviders(): ProviderInfo[] {
210
+ const loaded: ProviderInfo[] = [];
211
+ for (const collection of PROVIDER_CACHE.values()) {
212
+ loaded.push(collection.provider);
213
+ }
214
+ for (const collection of CUSTOM_PROVIDERS.values()) {
215
+ loaded.push(collection.provider);
216
+ }
217
+ return loaded;
218
+ }
219
+
220
+ /**
221
+ * Check if a provider is loaded in cache
222
+ */
223
+ export function isProviderLoaded(providerId: string): boolean {
224
+ return PROVIDER_CACHE.has(providerId) || CUSTOM_PROVIDERS.has(providerId);
225
+ }
226
+
227
+ // =============================================================================
228
+ // Model Access
229
+ // =============================================================================
230
+
231
+ /**
232
+ * Get all models for a provider (async - loads provider if needed)
233
+ */
234
+ export async function getModelsForProvider(
235
+ providerId: string,
236
+ ): Promise<Record<string, ModelInfo>> {
237
+ const collection = await getOrLoadProvider(providerId);
238
+ const builtInModels = collection?.models ?? {};
239
+ const customModels = CUSTOM_MODELS.get(providerId);
240
+
241
+ if (customModels) {
242
+ return { ...builtInModels, ...Object.fromEntries(customModels) };
243
+ }
244
+
245
+ return builtInModels;
246
+ }
247
+
248
+ /**
249
+ * Get a specific model by provider and model ID (async)
250
+ */
251
+ export async function getModel(
252
+ providerId: string,
253
+ modelId: string,
254
+ ): Promise<ModelInfo | undefined> {
255
+ // Check custom models first
256
+ const customModels = CUSTOM_MODELS.get(providerId);
257
+ if (customModels?.has(modelId)) {
258
+ return customModels.get(modelId);
259
+ }
260
+
261
+ // Fall back to built-in models
262
+ const collection = await getOrLoadProvider(providerId);
263
+ return collection?.models[modelId];
264
+ }
265
+
266
+ /**
267
+ * Get the default model for a provider (async)
268
+ */
269
+ export async function getDefaultModel(
270
+ providerId: string,
271
+ ): Promise<{ id: string; info: ModelInfo } | undefined> {
272
+ const collection = await getOrLoadProvider(providerId);
273
+ if (!collection) {
274
+ return undefined;
275
+ }
276
+
277
+ const defaultId = collection.provider.defaultModelId;
278
+ const info = await getModel(providerId, defaultId);
279
+
280
+ if (!info) {
281
+ return undefined;
282
+ }
283
+
284
+ return { id: defaultId, info };
285
+ }
286
+
287
+ /**
288
+ * Get all models across all providers (async - loads all providers)
289
+ */
290
+ export async function getAllModels(): Promise<
291
+ Array<{ providerId: string; modelId: string; info: ModelInfo }>
292
+ > {
293
+ const result: Array<{
294
+ providerId: string;
295
+ modelId: string;
296
+ info: ModelInfo;
297
+ }> = [];
298
+ const providerIds = getProviderIds();
299
+
300
+ await Promise.all(
301
+ providerIds.map(async (providerId) => {
302
+ const collection = await getOrLoadProvider(providerId);
303
+ if (!collection) return;
304
+
305
+ // Add built-in models
306
+ for (const [modelId, info] of Object.entries(collection.models)) {
307
+ result.push({ providerId, modelId, info });
308
+ }
309
+
310
+ // Add custom models
311
+ const customModels = CUSTOM_MODELS.get(providerId);
312
+ if (customModels) {
313
+ for (const [modelId, info] of customModels) {
314
+ // Skip if already added from built-in (custom overrides built-in)
315
+ if (!collection.models[modelId]) {
316
+ result.push({ providerId, modelId, info });
317
+ }
318
+ }
319
+ }
320
+ }),
321
+ );
322
+
323
+ return result;
324
+ }
325
+
326
+ /**
327
+ * Get total count of registered models (async - loads all providers)
328
+ */
329
+ export async function getModelCount(): Promise<number> {
330
+ let count = 0;
331
+ const providerIds = getProviderIds();
332
+
333
+ await Promise.all(
334
+ providerIds.map(async (providerId) => {
335
+ const collection = await getOrLoadProvider(providerId);
336
+ if (!collection) return;
337
+
338
+ count += Object.keys(collection.models).length;
339
+
340
+ const customModels = CUSTOM_MODELS.get(providerId);
341
+ if (customModels) {
342
+ // Only count custom models not already in built-in
343
+ for (const modelId of customModels.keys()) {
344
+ if (!collection.models[modelId]) {
345
+ count++;
346
+ }
347
+ }
348
+ }
349
+ }),
350
+ );
351
+
352
+ return count;
353
+ }
354
+
355
+ // =============================================================================
356
+ // Sync Model Access (for already-loaded providers)
357
+ // =============================================================================
358
+
359
+ /**
360
+ * Get models for an already-loaded provider (sync)
361
+ * Returns empty object if provider is not loaded
362
+ */
363
+ export function getModelsForProviderSync(
364
+ providerId: string,
365
+ ): Record<string, ModelInfo> {
366
+ const collection = getProviderFromCache(providerId);
367
+ const builtInModels = collection?.models ?? {};
368
+ const customModels = CUSTOM_MODELS.get(providerId);
369
+
370
+ if (customModels) {
371
+ return { ...builtInModels, ...Object.fromEntries(customModels) };
372
+ }
373
+
374
+ return builtInModels;
375
+ }
376
+
377
+ /**
378
+ * Get a specific model from an already-loaded provider (sync)
379
+ */
380
+ export function getModelSync(
381
+ providerId: string,
382
+ modelId: string,
383
+ ): ModelInfo | undefined {
384
+ // Check custom models first
385
+ const customModels = CUSTOM_MODELS.get(providerId);
386
+ if (customModels?.has(modelId)) {
387
+ return customModels.get(modelId);
388
+ }
389
+
390
+ // Fall back to built-in models
391
+ const collection = getProviderFromCache(providerId);
392
+ return collection?.models[modelId];
393
+ }
394
+
395
+ // =============================================================================
396
+ // Custom Model Management
397
+ // =============================================================================
398
+
399
+ /**
400
+ * Register a custom provider (immediately available, not lazy loaded)
401
+ */
402
+ export function registerProvider(collection: ModelCollection): void {
403
+ CUSTOM_PROVIDERS.set(collection.provider.id, collection);
404
+ }
405
+
406
+ /**
407
+ * Register a custom model for a provider
408
+ */
409
+ export function registerModel(
410
+ providerId: string,
411
+ modelId: string,
412
+ info: ModelInfo,
413
+ ): void {
414
+ if (!CUSTOM_MODELS.has(providerId)) {
415
+ CUSTOM_MODELS.set(providerId, new Map());
416
+ }
417
+ CUSTOM_MODELS.get(providerId)?.set(modelId, { ...info, id: modelId });
418
+ }
419
+
420
+ /**
421
+ * Unregister a custom model
422
+ */
423
+ export function unregisterModel(providerId: string, modelId: string): boolean {
424
+ const customModels = CUSTOM_MODELS.get(providerId);
425
+ if (customModels) {
426
+ return customModels.delete(modelId);
427
+ }
428
+ return false;
429
+ }
430
+
431
+ /**
432
+ * Unregister a provider
433
+ */
434
+ export function unregisterProvider(providerId: string): boolean {
435
+ CUSTOM_MODELS.delete(providerId);
436
+ PROVIDER_CACHE.delete(providerId);
437
+ return (
438
+ CUSTOM_PROVIDERS.delete(providerId) || PROVIDER_LOADERS.delete(providerId)
439
+ );
440
+ }
441
+
442
+ /**
443
+ * Clear all custom models (keeps built-in)
444
+ */
445
+ export function clearCustomModels(): void {
446
+ CUSTOM_MODELS.clear();
447
+ }
448
+
449
+ /**
450
+ * Reset registry to initial state (clears cache, keeps loaders)
451
+ */
452
+ export function resetRegistry(): void {
453
+ PROVIDER_CACHE.clear();
454
+ CUSTOM_MODELS.clear();
455
+ CUSTOM_PROVIDERS.clear();
456
+ }
457
+
458
+ // =============================================================================
459
+ // Batch Operations
460
+ // =============================================================================
461
+
462
+ /**
463
+ * Register multiple models at once
464
+ */
465
+ export function registerModels(
466
+ providerId: string,
467
+ models: Record<string, ModelInfo>,
468
+ ): void {
469
+ for (const [modelId, info] of Object.entries(models)) {
470
+ registerModel(providerId, modelId, info);
471
+ }
472
+ }
473
+
474
+ /**
475
+ * Update model info (merges with existing) - async
476
+ */
477
+ export async function updateModel(
478
+ providerId: string,
479
+ modelId: string,
480
+ updates: Partial<ModelInfo>,
481
+ ): Promise<ModelInfo | undefined> {
482
+ const existing = await getModel(providerId, modelId);
483
+ if (!existing) {
484
+ return undefined;
485
+ }
486
+
487
+ const updated: ModelInfo = { ...existing, ...updates };
488
+ registerModel(providerId, modelId, updated);
489
+
490
+ return updated;
491
+ }
492
+
493
+ /**
494
+ * Mark a model as deprecated - async
495
+ */
496
+ export async function deprecateModel(
497
+ providerId: string,
498
+ modelId: string,
499
+ options?: {
500
+ notice?: string;
501
+ replacedBy?: string;
502
+ deprecationDate?: string;
503
+ },
504
+ ): Promise<ModelInfo | undefined> {
505
+ return updateModel(providerId, modelId, {
506
+ status: "deprecated",
507
+ deprecationNotice: options?.notice,
508
+ replacedBy: options?.replacedBy,
509
+ deprecationDate: options?.deprecationDate,
510
+ });
511
+ }
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Schema Exports
3
+ *
4
+ * Re-exports all Zod schemas and types for model definitions.
5
+ */
6
+
7
+ export {
8
+ // API Format
9
+ ApiFormat,
10
+ type ApiFormat as ApiFormatType,
11
+ ApiFormatSchema,
12
+ getPricing,
13
+ // Helpers
14
+ hasCapability,
15
+ isActive,
16
+ isDeprecated,
17
+ type ModelCapability,
18
+ // Capabilities
19
+ ModelCapabilitySchema,
20
+ type ModelCollection,
21
+ ModelCollectionSchema,
22
+ type ModelEntry,
23
+ // Model Entry
24
+ ModelEntrySchema,
25
+ type ModelInfo,
26
+ // Model Info
27
+ ModelInfoSchema,
28
+ type ModelPricing,
29
+ // Pricing
30
+ ModelPricingSchema,
31
+ type ModelStatus,
32
+ // Status
33
+ ModelStatusSchema,
34
+ type ProviderCapability,
35
+ // Provider
36
+ ProviderCapabilitySchema,
37
+ type ProviderInfo,
38
+ ProviderInfoSchema,
39
+ type ProviderProtocol,
40
+ ProviderProtocolSchema,
41
+ safeValidateModelInfo,
42
+ type ThinkingConfig,
43
+ // Thinking Config
44
+ ThinkingConfigSchema,
45
+ validateModelInfo,
46
+ } from "./model";
47
+
48
+ export {
49
+ // Query Match
50
+ type ModelMatch,
51
+ type ModelQueryConfig,
52
+ // Query Config
53
+ ModelQueryConfigSchema,
54
+ type ModelQueryResult,
55
+ // Query Result
56
+ ModelQueryResultSchema,
57
+ // Query Functions
58
+ matchesQuery,
59
+ safeValidateQueryConfig,
60
+ sortModels,
61
+ validateQueryConfig,
62
+ } from "./query";