ai-providers 0.2.0 → 0.3.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.
@@ -0,0 +1,136 @@
1
+ /**
2
+ * Unified AI Provider Registry
3
+ *
4
+ * Centralizes access to multiple AI providers via simple string identifiers.
5
+ *
6
+ * Smart routing:
7
+ * - openai/* models → OpenAI SDK (via gateway)
8
+ * - anthropic/* models → Anthropic SDK (via gateway)
9
+ * - google/* models → Google AI SDK (via gateway)
10
+ * - All other models → OpenRouter (via gateway)
11
+ *
12
+ * Supports simple aliases: 'opus' → anthropic/claude-opus-4.5
13
+ *
14
+ * @packageDocumentation
15
+ */
16
+ import { type ProviderRegistryProvider, type LanguageModel, type EmbeddingModel } from 'ai';
17
+ /**
18
+ * Available provider IDs
19
+ */
20
+ export type ProviderId = 'openai' | 'anthropic' | 'google' | 'openrouter' | 'cloudflare' | 'bedrock';
21
+ /**
22
+ * Providers that get direct SDK access (not via openrouter)
23
+ * These support special capabilities like MCP, structured outputs, etc.
24
+ * Re-exported from language-models for consistency.
25
+ */
26
+ export { DIRECT_PROVIDERS, type DirectProvider } from 'language-models';
27
+ /**
28
+ * Provider configuration options
29
+ */
30
+ export interface ProviderConfig {
31
+ /** Cloudflare AI Gateway URL (e.g., https://gateway.ai.cloudflare.com/v1/{account_id}/{gateway_name}) */
32
+ gatewayUrl?: string;
33
+ /** AI Gateway auth token */
34
+ gatewayToken?: string;
35
+ /** Use llm.do WebSocket transport instead of HTTP (persistent connection) */
36
+ useWebSocket?: boolean;
37
+ /** llm.do WebSocket URL (default: wss://llm.do/ws) */
38
+ llmUrl?: string;
39
+ /** OpenAI API key (fallback if no gateway) */
40
+ openaiApiKey?: string;
41
+ /** Anthropic API key (fallback if no gateway) */
42
+ anthropicApiKey?: string;
43
+ /** Google AI API key (fallback if no gateway) */
44
+ googleApiKey?: string;
45
+ /** OpenRouter API key (fallback if no gateway) */
46
+ openrouterApiKey?: string;
47
+ /** Cloudflare Account ID */
48
+ cloudflareAccountId?: string;
49
+ /** Cloudflare API Token (fallback if no gateway) */
50
+ cloudflareApiToken?: string;
51
+ /** Custom base URLs (overrides gateway) */
52
+ baseUrls?: Partial<Record<ProviderId, string>>;
53
+ }
54
+ /**
55
+ * Create a unified provider registry with all configured providers
56
+ *
57
+ * @example
58
+ * ```ts
59
+ * import { createRegistry } from 'ai-providers'
60
+ * import { generateText, embed } from 'ai'
61
+ *
62
+ * // With Cloudflare AI Gateway (recommended)
63
+ * // Set AI_GATEWAY_URL and AI_GATEWAY_TOKEN env vars
64
+ *
65
+ * const registry = await createRegistry()
66
+ *
67
+ * // Use any provider with simple string IDs
68
+ * const { text } = await generateText({
69
+ * model: registry.languageModel('openai:gpt-4o'),
70
+ * prompt: 'Hello!'
71
+ * })
72
+ *
73
+ * const { text: claude } = await generateText({
74
+ * model: registry.languageModel('anthropic:claude-3-5-sonnet-latest'),
75
+ * prompt: 'Hello!'
76
+ * })
77
+ *
78
+ * const { embedding } = await embed({
79
+ * model: registry.textEmbeddingModel('cloudflare:@cf/baai/bge-m3'),
80
+ * value: 'Hello!'
81
+ * })
82
+ * ```
83
+ */
84
+ export declare function createRegistry(config?: ProviderConfig, options?: {
85
+ providers?: ProviderId[];
86
+ }): Promise<ProviderRegistryProvider>;
87
+ /**
88
+ * Get or create the default provider registry
89
+ */
90
+ export declare function getRegistry(): Promise<ProviderRegistryProvider>;
91
+ /**
92
+ * Configure the default registry with custom settings
93
+ */
94
+ export declare function configureRegistry(config: ProviderConfig): Promise<void>;
95
+ /**
96
+ * Get a language model with smart routing
97
+ *
98
+ * Resolves aliases and routes to the appropriate provider:
99
+ * - openai/* → OpenAI SDK (via gateway) when provider_model_id is available
100
+ * - anthropic/* → Anthropic SDK (via gateway) when provider_model_id is available
101
+ * - google/* → Google AI SDK (via gateway) when provider_model_id is available
102
+ * - All others → OpenRouter (via gateway)
103
+ *
104
+ * Direct routing to native SDKs enables provider-specific features like:
105
+ * - Anthropic: MCP (Model Context Protocol), extended thinking
106
+ * - OpenAI: Function calling, JSON mode, vision
107
+ * - Google: Grounding, code execution
108
+ *
109
+ * @example
110
+ * ```ts
111
+ * import { model } from 'ai-providers'
112
+ *
113
+ * // Simple aliases
114
+ * const opus = await model('opus') // → anthropic:claude-opus-4-5-20251101
115
+ * const gpt = await model('gpt-4o') // → openai:gpt-4o
116
+ * const llama = await model('llama-70b') // → openrouter:meta-llama/llama-3.3-70b-instruct
117
+ *
118
+ * // Full IDs also work
119
+ * const claude = await model('anthropic/claude-sonnet-4.5')
120
+ * const mistral = await model('mistralai/mistral-large-2411')
121
+ * ```
122
+ */
123
+ export declare function model(id: string): Promise<LanguageModel>;
124
+ /**
125
+ * Shorthand to get an embedding model from the default registry
126
+ *
127
+ * @example
128
+ * ```ts
129
+ * import { embeddingModel } from 'ai-providers'
130
+ *
131
+ * const openaiEmbed = await embeddingModel('openai:text-embedding-3-small')
132
+ * const cfEmbed = await embeddingModel('cloudflare:@cf/baai/bge-m3')
133
+ * ```
134
+ */
135
+ export declare function embeddingModel(id: string): Promise<EmbeddingModel<string>>;
136
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAyC,KAAK,wBAAwB,EAAE,KAAK,aAAa,EAAE,KAAK,cAAc,EAAE,MAAM,IAAI,CAAA;AAElI;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,WAAW,GAAG,QAAQ,GAAG,YAAY,GAAG,YAAY,GAAG,SAAS,CAAA;AAEpG;;;;GAIG;AACH,OAAO,EAAE,gBAAgB,EAAE,KAAK,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAEvE;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,yGAAyG;IACzG,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,4BAA4B;IAC5B,YAAY,CAAC,EAAE,MAAM,CAAA;IAErB,6EAA6E;IAC7E,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,sDAAsD;IACtD,MAAM,CAAC,EAAE,MAAM,CAAA;IAEf,8CAA8C;IAC9C,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,iDAAiD;IACjD,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,iDAAiD;IACjD,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,kDAAkD;IAClD,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,4BAA4B;IAC5B,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,oDAAoD;IACpD,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAE3B,2CAA2C;IAC3C,QAAQ,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAA;CAC/C;AAkOD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAsB,cAAc,CAClC,MAAM,GAAE,cAAmB,EAC3B,OAAO,GAAE;IAAE,SAAS,CAAC,EAAE,UAAU,EAAE,CAAA;CAAO,GACzC,OAAO,CAAC,wBAAwB,CAAC,CAqBnC;AAMD;;GAEG;AACH,wBAAsB,WAAW,IAAI,OAAO,CAAC,wBAAwB,CAAC,CAWrE;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAG7E;AAoBD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAsB,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAgD9D;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAGhF"}
@@ -0,0 +1,393 @@
1
+ /**
2
+ * Unified AI Provider Registry
3
+ *
4
+ * Centralizes access to multiple AI providers via simple string identifiers.
5
+ *
6
+ * Smart routing:
7
+ * - openai/* models → OpenAI SDK (via gateway)
8
+ * - anthropic/* models → Anthropic SDK (via gateway)
9
+ * - google/* models → Google AI SDK (via gateway)
10
+ * - All other models → OpenRouter (via gateway)
11
+ *
12
+ * Supports simple aliases: 'opus' → anthropic/claude-opus-4.5
13
+ *
14
+ * @packageDocumentation
15
+ */
16
+ import { createProviderRegistry } from 'ai';
17
+ /**
18
+ * Providers that get direct SDK access (not via openrouter)
19
+ * These support special capabilities like MCP, structured outputs, etc.
20
+ * Re-exported from language-models for consistency.
21
+ */
22
+ export { DIRECT_PROVIDERS } from 'language-models';
23
+ /**
24
+ * Cloudflare AI Gateway provider endpoint mapping
25
+ */
26
+ const GATEWAY_PROVIDER_PATHS = {
27
+ openai: 'openai',
28
+ anthropic: 'anthropic',
29
+ google: 'google-ai-studio',
30
+ openrouter: 'openrouter',
31
+ cloudflare: 'workers-ai',
32
+ bedrock: 'aws-bedrock'
33
+ };
34
+ /**
35
+ * Get provider configuration from environment variables
36
+ */
37
+ function getEnvConfig() {
38
+ if (typeof process === 'undefined')
39
+ return {};
40
+ return {
41
+ // Cloudflare AI Gateway
42
+ gatewayUrl: process.env.AI_GATEWAY_URL,
43
+ gatewayToken: process.env.AI_GATEWAY_TOKEN || process.env.DO_TOKEN,
44
+ // llm.do WebSocket transport
45
+ useWebSocket: process.env.LLM_WEBSOCKET === 'true' || process.env.USE_LLM_WEBSOCKET === 'true',
46
+ llmUrl: process.env.LLM_URL,
47
+ // Individual provider keys (fallbacks)
48
+ openaiApiKey: process.env.OPENAI_API_KEY,
49
+ anthropicApiKey: process.env.ANTHROPIC_API_KEY,
50
+ googleApiKey: process.env.GOOGLE_GENERATIVE_AI_API_KEY || process.env.GOOGLE_AI_API_KEY,
51
+ openrouterApiKey: process.env.OPENROUTER_API_KEY,
52
+ cloudflareAccountId: process.env.CLOUDFLARE_ACCOUNT_ID,
53
+ cloudflareApiToken: process.env.CLOUDFLARE_API_TOKEN
54
+ };
55
+ }
56
+ /**
57
+ * Get the base URL for a provider, using Cloudflare AI Gateway if configured
58
+ */
59
+ function getBaseUrl(providerId, config, defaultUrl) {
60
+ // Custom URL takes priority
61
+ if (config.baseUrls?.[providerId]) {
62
+ return config.baseUrls[providerId];
63
+ }
64
+ // Use Cloudflare AI Gateway if configured
65
+ if (config.gatewayUrl) {
66
+ const gatewayPath = GATEWAY_PROVIDER_PATHS[providerId];
67
+ return `${config.gatewayUrl}/${gatewayPath}`;
68
+ }
69
+ return defaultUrl;
70
+ }
71
+ // Lazy-loaded WebSocket fetch (to avoid circular imports)
72
+ let llmFetchInstance = null;
73
+ /**
74
+ * Create a custom fetch that handles gateway authentication
75
+ * Supports both HTTP (Cloudflare AI Gateway) and WebSocket (llm.do) transports
76
+ */
77
+ function createGatewayFetch(config) {
78
+ // Use llm.do WebSocket transport if enabled
79
+ if (config.useWebSocket && config.gatewayToken) {
80
+ // Return a lazy-initializing fetch that creates the WebSocket connection on first use
81
+ return async (url, init) => {
82
+ if (!llmFetchInstance) {
83
+ const { createLLMFetch } = await import('./llm.do.js');
84
+ llmFetchInstance = createLLMFetch({
85
+ url: config.llmUrl,
86
+ token: config.gatewayToken
87
+ });
88
+ }
89
+ return llmFetchInstance(url, init);
90
+ };
91
+ }
92
+ // Use HTTP gateway
93
+ if (!config.gatewayUrl || !config.gatewayToken) {
94
+ return undefined;
95
+ }
96
+ return async (url, init) => {
97
+ const headers = new Headers(init?.headers);
98
+ // Remove SDK's API key headers - gateway will inject from its secrets
99
+ headers.delete('x-api-key');
100
+ headers.delete('authorization');
101
+ headers.delete('x-goog-api-key');
102
+ // Add gateway authentication
103
+ headers.set('cf-aig-authorization', `Bearer ${config.gatewayToken}`);
104
+ return fetch(url, { ...init, headers });
105
+ };
106
+ }
107
+ /**
108
+ * Check if using gateway with secrets (token configured)
109
+ */
110
+ function useGatewaySecrets(config) {
111
+ return !!(config.gatewayUrl && config.gatewayToken);
112
+ }
113
+ /**
114
+ * Get API key - when using gateway secrets, use a placeholder
115
+ */
116
+ function getApiKey(config, providerApiKey) {
117
+ if (useGatewaySecrets(config)) {
118
+ return 'gateway'; // Placeholder - will be stripped by gatewayFetch
119
+ }
120
+ return providerApiKey;
121
+ }
122
+ /**
123
+ * Create OpenAI provider
124
+ */
125
+ async function createOpenAIProvider(config) {
126
+ const { createOpenAI } = await import('@ai-sdk/openai');
127
+ return createOpenAI({
128
+ apiKey: getApiKey(config, config.openaiApiKey),
129
+ baseURL: getBaseUrl('openai', config),
130
+ fetch: createGatewayFetch(config),
131
+ });
132
+ }
133
+ /**
134
+ * Create Anthropic provider
135
+ */
136
+ async function createAnthropicProvider(config) {
137
+ const { createAnthropic } = await import('@ai-sdk/anthropic');
138
+ return createAnthropic({
139
+ apiKey: getApiKey(config, config.anthropicApiKey),
140
+ baseURL: getBaseUrl('anthropic', config),
141
+ fetch: createGatewayFetch(config),
142
+ });
143
+ }
144
+ /**
145
+ * Create Google AI provider
146
+ */
147
+ async function createGoogleProvider(config) {
148
+ const { createGoogleGenerativeAI } = await import('@ai-sdk/google');
149
+ return createGoogleGenerativeAI({
150
+ apiKey: getApiKey(config, config.googleApiKey),
151
+ baseURL: getBaseUrl('google', config),
152
+ fetch: createGatewayFetch(config),
153
+ });
154
+ }
155
+ /**
156
+ * Create OpenRouter provider (OpenAI-compatible)
157
+ */
158
+ async function createOpenRouterProvider(config) {
159
+ const { createOpenAI } = await import('@ai-sdk/openai');
160
+ return createOpenAI({
161
+ apiKey: getApiKey(config, config.openrouterApiKey),
162
+ baseURL: getBaseUrl('openrouter', config, 'https://openrouter.ai/api/v1'),
163
+ fetch: createGatewayFetch(config),
164
+ });
165
+ }
166
+ /**
167
+ * Create Amazon Bedrock provider
168
+ * Supports two authentication modes:
169
+ * 1. Bearer token (AWS_BEARER_TOKEN_BEDROCK) - simpler, recommended, bypasses gateway
170
+ * 2. SigV4 signing (AWS_ACCESS_KEY_ID/SECRET) - standard AWS auth, can use gateway
171
+ */
172
+ async function createBedrockProvider(config) {
173
+ const { createAmazonBedrock } = await import('@ai-sdk/amazon-bedrock');
174
+ const bearerToken = process.env.AWS_BEARER_TOKEN_BEDROCK;
175
+ // When using bearer token, go directly to AWS (skip gateway)
176
+ // Gateway doesn't support bearer token auth for Bedrock
177
+ if (bearerToken) {
178
+ return createAmazonBedrock({
179
+ region: process.env.AWS_REGION || 'us-east-1',
180
+ apiKey: bearerToken,
181
+ });
182
+ }
183
+ // For SigV4 auth, can optionally route through gateway
184
+ const baseURL = getBaseUrl('bedrock', config);
185
+ return createAmazonBedrock({
186
+ ...(baseURL && { baseURL }),
187
+ region: process.env.AWS_REGION || 'us-east-1',
188
+ });
189
+ }
190
+ /**
191
+ * Create Cloudflare Workers AI provider
192
+ */
193
+ async function createCloudflareProvider(config) {
194
+ const { cloudflare } = await import('./providers/cloudflare.js');
195
+ return {
196
+ languageModel: (modelId) => {
197
+ throw new Error(`Cloudflare language models not yet supported via registry. Use embedding models like: cloudflare:@cf/baai/bge-m3`);
198
+ },
199
+ textEmbeddingModel: (modelId) => {
200
+ return cloudflare.embedding(modelId, {
201
+ accountId: config.cloudflareAccountId,
202
+ apiToken: getApiKey(config, config.cloudflareApiToken),
203
+ baseUrl: getBaseUrl('cloudflare', config)
204
+ });
205
+ }
206
+ };
207
+ }
208
+ /**
209
+ * Provider factories map
210
+ */
211
+ const providerFactories = {
212
+ openai: createOpenAIProvider,
213
+ anthropic: createAnthropicProvider,
214
+ google: createGoogleProvider,
215
+ openrouter: createOpenRouterProvider,
216
+ cloudflare: createCloudflareProvider,
217
+ bedrock: createBedrockProvider
218
+ };
219
+ /**
220
+ * Create a unified provider registry with all configured providers
221
+ *
222
+ * @example
223
+ * ```ts
224
+ * import { createRegistry } from 'ai-providers'
225
+ * import { generateText, embed } from 'ai'
226
+ *
227
+ * // With Cloudflare AI Gateway (recommended)
228
+ * // Set AI_GATEWAY_URL and AI_GATEWAY_TOKEN env vars
229
+ *
230
+ * const registry = await createRegistry()
231
+ *
232
+ * // Use any provider with simple string IDs
233
+ * const { text } = await generateText({
234
+ * model: registry.languageModel('openai:gpt-4o'),
235
+ * prompt: 'Hello!'
236
+ * })
237
+ *
238
+ * const { text: claude } = await generateText({
239
+ * model: registry.languageModel('anthropic:claude-3-5-sonnet-latest'),
240
+ * prompt: 'Hello!'
241
+ * })
242
+ *
243
+ * const { embedding } = await embed({
244
+ * model: registry.textEmbeddingModel('cloudflare:@cf/baai/bge-m3'),
245
+ * value: 'Hello!'
246
+ * })
247
+ * ```
248
+ */
249
+ export async function createRegistry(config = {}, options = {}) {
250
+ const mergedConfig = { ...getEnvConfig(), ...config };
251
+ const providerIds = options.providers || ['openai', 'anthropic', 'google', 'openrouter', 'cloudflare', 'bedrock'];
252
+ const providers = {};
253
+ // Load providers in parallel
254
+ await Promise.all(providerIds.map(async (id) => {
255
+ try {
256
+ providers[id] = await providerFactories[id](mergedConfig);
257
+ }
258
+ catch (error) {
259
+ // Provider SDK not installed - skip silently
260
+ if (process.env.DEBUG) {
261
+ console.warn(`Provider ${id} not available:`, error);
262
+ }
263
+ }
264
+ }));
265
+ return createProviderRegistry(providers);
266
+ }
267
+ // Default registry management
268
+ let defaultRegistry = null;
269
+ let defaultRegistryPromise = null;
270
+ /**
271
+ * Get or create the default provider registry
272
+ */
273
+ export async function getRegistry() {
274
+ if (defaultRegistry)
275
+ return defaultRegistry;
276
+ if (!defaultRegistryPromise) {
277
+ defaultRegistryPromise = createRegistry().then(registry => {
278
+ defaultRegistry = registry;
279
+ return registry;
280
+ });
281
+ }
282
+ return defaultRegistryPromise;
283
+ }
284
+ /**
285
+ * Configure the default registry with custom settings
286
+ */
287
+ export async function configureRegistry(config) {
288
+ defaultRegistry = await createRegistry(config);
289
+ defaultRegistryPromise = null;
290
+ }
291
+ /**
292
+ * Parse a model ID into provider and model name
293
+ *
294
+ * @example
295
+ * parseModelId('openai/gpt-4o') // { provider: 'openai', model: 'gpt-4o' }
296
+ * parseModelId('meta-llama/llama-3.3-70b') // { provider: 'meta-llama', model: 'llama-3.3-70b' }
297
+ */
298
+ function parseModelId(id) {
299
+ const slashIndex = id.indexOf('/');
300
+ if (slashIndex === -1) {
301
+ return { provider: 'openrouter', model: id };
302
+ }
303
+ return {
304
+ provider: id.substring(0, slashIndex),
305
+ model: id.substring(slashIndex + 1)
306
+ };
307
+ }
308
+ /**
309
+ * Get a language model with smart routing
310
+ *
311
+ * Resolves aliases and routes to the appropriate provider:
312
+ * - openai/* → OpenAI SDK (via gateway) when provider_model_id is available
313
+ * - anthropic/* → Anthropic SDK (via gateway) when provider_model_id is available
314
+ * - google/* → Google AI SDK (via gateway) when provider_model_id is available
315
+ * - All others → OpenRouter (via gateway)
316
+ *
317
+ * Direct routing to native SDKs enables provider-specific features like:
318
+ * - Anthropic: MCP (Model Context Protocol), extended thinking
319
+ * - OpenAI: Function calling, JSON mode, vision
320
+ * - Google: Grounding, code execution
321
+ *
322
+ * @example
323
+ * ```ts
324
+ * import { model } from 'ai-providers'
325
+ *
326
+ * // Simple aliases
327
+ * const opus = await model('opus') // → anthropic:claude-opus-4-5-20251101
328
+ * const gpt = await model('gpt-4o') // → openai:gpt-4o
329
+ * const llama = await model('llama-70b') // → openrouter:meta-llama/llama-3.3-70b-instruct
330
+ *
331
+ * // Full IDs also work
332
+ * const claude = await model('anthropic/claude-sonnet-4.5')
333
+ * const mistral = await model('mistralai/mistral-large-2411')
334
+ * ```
335
+ */
336
+ export async function model(id) {
337
+ const registry = await getRegistry();
338
+ // Check for direct provider:model format (e.g., bedrock:us.anthropic.claude-*)
339
+ // This bypasses language-models resolution and routes directly to the provider
340
+ const colonIndex = id.indexOf(':');
341
+ if (colonIndex > 0) {
342
+ const provider = id.substring(0, colonIndex);
343
+ // Known providers that support direct routing
344
+ if (['bedrock', 'openai', 'anthropic', 'google', 'openrouter'].includes(provider)) {
345
+ return registry.languageModel(id);
346
+ }
347
+ }
348
+ // Try to resolve with provider routing info
349
+ try {
350
+ const { resolveWithProvider, DIRECT_PROVIDERS } = await import('language-models');
351
+ const resolved = resolveWithProvider(id);
352
+ // Extract expected provider from the model ID (e.g., 'anthropic' from 'anthropic/claude-sonnet-4.5')
353
+ const slashIndex = resolved.id.indexOf('/');
354
+ const expectedProvider = slashIndex > 0 ? resolved.id.substring(0, slashIndex) : null;
355
+ // Use direct routing if:
356
+ // 1. Provider supports direct SDK access (openai, anthropic, google)
357
+ // 2. We have the provider's native model ID
358
+ // 3. The data's provider matches the expected provider from the model ID
359
+ // (OpenRouter may return different top providers like google-vertex for anthropic models)
360
+ const dataProvider = resolved.model?.provider;
361
+ const providerMatches = expectedProvider && dataProvider === expectedProvider;
362
+ if (resolved.supportsDirectRouting &&
363
+ resolved.providerModelId &&
364
+ providerMatches &&
365
+ DIRECT_PROVIDERS.includes(expectedProvider)) {
366
+ // Route directly to provider SDK with native model ID
367
+ const modelSpec = `${expectedProvider}:${resolved.providerModelId}`;
368
+ return registry.languageModel(modelSpec);
369
+ }
370
+ // Fall back to OpenRouter for all other models
371
+ return registry.languageModel(`openrouter:${resolved.id}`);
372
+ }
373
+ catch {
374
+ // language-models not available, route through OpenRouter as-is
375
+ return registry.languageModel(`openrouter:${id}`);
376
+ }
377
+ }
378
+ /**
379
+ * Shorthand to get an embedding model from the default registry
380
+ *
381
+ * @example
382
+ * ```ts
383
+ * import { embeddingModel } from 'ai-providers'
384
+ *
385
+ * const openaiEmbed = await embeddingModel('openai:text-embedding-3-small')
386
+ * const cfEmbed = await embeddingModel('cloudflare:@cf/baai/bge-m3')
387
+ * ```
388
+ */
389
+ export async function embeddingModel(id) {
390
+ const registry = await getRegistry();
391
+ return registry.textEmbeddingModel(id);
392
+ }
393
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,38 +1,53 @@
1
1
  {
2
2
  "name": "ai-providers",
3
- "version": "0.2.0",
4
- "description": "Provider router for AI models including OpenAI, Anthropic, and Google",
5
- "main": "./dist/index.js",
6
- "module": "./dist/index.js",
7
- "types": "./dist/index.d.ts",
8
- "files": [
9
- "dist"
10
- ],
3
+ "version": "0.3.0",
4
+ "description": "Unified AI provider registry with Cloudflare AI Gateway support",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.js",
11
+ "types": "./dist/index.d.ts"
12
+ },
13
+ "./cloudflare": {
14
+ "import": "./dist/providers/cloudflare.js",
15
+ "types": "./dist/providers/cloudflare.d.ts"
16
+ }
17
+ },
11
18
  "scripts": {
12
- "dev": "dotenvx run -- npx tsx watch src/demo.ts",
13
- "build": "rimraf dist && tsc",
14
- "clean": "rimraf dist",
15
- "lint": "tsc --noEmit",
16
- "prepublishOnly": "pnpm clean && pnpm build",
17
- "typecheck": "tsc --noEmit"
19
+ "build": "tsc -p tsconfig.json",
20
+ "dev": "tsc -p tsconfig.json --watch",
21
+ "test": "vitest",
22
+ "typecheck": "tsc --noEmit",
23
+ "lint": "eslint .",
24
+ "clean": "rm -rf dist"
18
25
  },
19
- "type": "module",
20
- "packageManager": "pnpm@10.6.5",
21
26
  "dependencies": {
22
- "@ai-sdk/anthropic": "^1.2.0",
23
- "@ai-sdk/google": "^1.2.1",
24
- "@ai-sdk/google-vertex": "^2.2.14",
25
- "@ai-sdk/openai": "^1.3.16",
26
- "ai": "^4.3.9",
27
- "composio-core": "^0.5.31",
28
- "language-models": "0.1.0"
27
+ "ai": "^5.0.0",
28
+ "language-models": "workspace:*",
29
+ "rpc.do": "^0.1.0"
30
+ },
31
+ "optionalDependencies": {
32
+ "@ai-sdk/amazon-bedrock": "^3.0.0",
33
+ "@ai-sdk/anthropic": "^2.0.0",
34
+ "@ai-sdk/google": "^2.0.0",
35
+ "@ai-sdk/openai": "^2.0.0"
29
36
  },
30
37
  "devDependencies": {
31
- "@types/node": "^22.13.10",
32
- "eslint-config": "0.1.0",
33
- "rimraf": "^6.0.1",
34
- "tsconfig": "0.0.0",
35
- "typescript": "^5.8.2",
36
- "vitest": "^3.0.9"
37
- }
38
+ "dotenv": "^16.0.0",
39
+ "vitest": "^2.0.0"
40
+ },
41
+ "keywords": [
42
+ "ai",
43
+ "providers",
44
+ "llm",
45
+ "openai",
46
+ "anthropic",
47
+ "google",
48
+ "cloudflare",
49
+ "gateway",
50
+ "primitives"
51
+ ],
52
+ "license": "MIT"
38
53
  }