diff --git a/.changeset/spotty-suits-reply.md b/.changeset/spotty-suits-reply.md new file mode 100644 index 000000000000..df64a040fca6 --- /dev/null +++ b/.changeset/spotty-suits-reply.md @@ -0,0 +1,5 @@ +--- +'ai': patch +--- + +chore (ai/core): move custom provider to stable diff --git a/content/docs/03-ai-sdk-core/40-provider-management.mdx b/content/docs/03-ai-sdk-core/40-provider-management.mdx index 8145f7bfc9f0..e31d5ff6b42d 100644 --- a/content/docs/03-ai-sdk-core/40-provider-management.mdx +++ b/content/docs/03-ai-sdk-core/40-provider-management.mdx @@ -5,8 +5,6 @@ description: Learn how to work with multiple providers # Provider Management -Provider management is an experimental feature. - When you work with multiple providers and models, it is often desirable to manage them in a central place and access the models through simple string ids. @@ -18,7 +16,7 @@ The provider registry lets you mix **multiple providers** and access them throug ## Custom Providers -You can create a [custom provider](/docs/reference/ai-sdk-core/custom-provider) using `experimental_customProvider`. +You can create a [custom provider](/docs/reference/ai-sdk-core/custom-provider) using `customProvider`. ### Example: custom model settings @@ -27,7 +25,7 @@ with pre-configured settings. ```ts import { openai as originalOpenAI } from '@ai-sdk/openai'; -import { experimental_customProvider as customProvider } from 'ai'; +import { customProvider } from 'ai'; // custom provider with different model settings: export const openai = customProvider({ @@ -49,7 +47,7 @@ You can also provide model name aliases, so you can update the model version in ```ts import { anthropic as originalAnthropic } from '@ai-sdk/anthropic'; -import { experimental_customProvider as customProvider } from 'ai'; +import { customProvider } from 'ai'; // custom provider with alias names: export const anthropic = customProvider({ @@ -69,7 +67,7 @@ You can limit the available models in the system, even if you have multiple prov ```ts import { anthropic } from '@ai-sdk/anthropic'; import { openai } from '@ai-sdk/openai'; -import { experimental_customProvider as customProvider } from 'ai'; +import { customProvider } from 'ai'; export const myProvider = customProvider({ languageModels: { @@ -87,6 +85,8 @@ export const myProvider = customProvider({ ## Provider Registry +The provider registry is an experimental feature. + You can create a [provider registry](/docs/reference/ai-sdk-core/provider-registry) with multiple providers and models using `experimental_createProviderRegistry`. ### Example: Setup diff --git a/content/docs/07-reference/01-ai-sdk-core/40-provider-registry.mdx b/content/docs/07-reference/01-ai-sdk-core/40-provider-registry.mdx index d77aaf6c05b4..b23ddc7b10a7 100644 --- a/content/docs/07-reference/01-ai-sdk-core/40-provider-registry.mdx +++ b/content/docs/07-reference/01-ai-sdk-core/40-provider-registry.mdx @@ -5,7 +5,7 @@ description: Registry for managing multiple providers and models (API Reference) # `createProviderRegistry()` -Provider management is an experimental feature. +The provider registry is an experimental feature. When you work with multiple providers and models, it is often desirable to manage them in a central place and access the models through simple string ids. diff --git a/content/docs/07-reference/01-ai-sdk-core/42-custom-provider.mdx b/content/docs/07-reference/01-ai-sdk-core/42-custom-provider.mdx index af7d886a2052..517e2e9d200a 100644 --- a/content/docs/07-reference/01-ai-sdk-core/42-custom-provider.mdx +++ b/content/docs/07-reference/01-ai-sdk-core/42-custom-provider.mdx @@ -5,8 +5,6 @@ description: Custom provider that uses models from a different provider (API Ref # `customProvider()` -Provider management is an experimental feature. - With a custom provider, you can map ids to any model. This allows you to set up custom model configurations, alias names, and more. The custom provider also supports a fallback provider, which is useful for @@ -18,7 +16,7 @@ You can create a custom provider using `experiental_createCustomProvider`. ```ts import { openai } from '@ai-sdk/openai'; -import { experimental_customProvider as customProvider } from 'ai'; +import { customProvider } from 'ai'; // custom provider with different model settings: export const myOpenAI = customProvider({ @@ -34,10 +32,7 @@ export const myOpenAI = customProvider({ ## Import - + ## API Signature diff --git a/examples/ai-core/src/registry/setup-registry.ts b/examples/ai-core/src/registry/setup-registry.ts index 6f4779b9773c..d0f30a6f33e8 100644 --- a/examples/ai-core/src/registry/setup-registry.ts +++ b/examples/ai-core/src/registry/setup-registry.ts @@ -8,7 +8,7 @@ import { replicate } from '@ai-sdk/replicate'; import { xai } from '@ai-sdk/xai'; import { experimental_createProviderRegistry as createProviderRegistry, - experimental_customProvider as customProvider, + customProvider, } from 'ai'; import 'dotenv/config'; diff --git a/packages/ai/core/registry/custom-provider.test.ts b/packages/ai/core/registry/custom-provider.test.ts index 06d3ec42b3da..a41f813dba2a 100644 --- a/packages/ai/core/registry/custom-provider.test.ts +++ b/packages/ai/core/registry/custom-provider.test.ts @@ -1,10 +1,9 @@ import { NoSuchModelError } from '@ai-sdk/provider'; import { describe, expect, it, vi } from 'vitest'; -import { experimental_customProvider } from './custom-provider'; - import { MockEmbeddingModelV1 } from '../test/mock-embedding-model-v1'; import { MockImageModelV1 } from '../test/mock-image-model-v1'; import { MockLanguageModelV1 } from '../test/mock-language-model-v1'; +import { customProvider } from './custom-provider'; const mockLanguageModel = new MockLanguageModelV1(); const mockEmbeddingModel = new MockEmbeddingModelV1(); @@ -16,7 +15,7 @@ const mockFallbackProvider = { describe('languageModel', () => { it('should return the language model if it exists', () => { - const provider = experimental_customProvider({ + const provider = customProvider({ languageModels: { 'test-model': mockLanguageModel }, }); @@ -26,7 +25,7 @@ describe('languageModel', () => { it('should use fallback provider if model not found and fallback exists', () => { mockFallbackProvider.languageModel.mockReturnValue(mockLanguageModel); - const provider = experimental_customProvider({ + const provider = customProvider({ fallbackProvider: mockFallbackProvider, }); @@ -37,7 +36,7 @@ describe('languageModel', () => { }); it('should throw NoSuchModelError if model not found and no fallback', () => { - const provider = experimental_customProvider({}); + const provider = customProvider({}); expect(() => provider.languageModel('test-model')).toThrow( NoSuchModelError, ); @@ -46,7 +45,7 @@ describe('languageModel', () => { describe('textEmbeddingModel', () => { it('should return the embedding model if it exists', () => { - const provider = experimental_customProvider({ + const provider = customProvider({ textEmbeddingModels: { 'test-model': mockEmbeddingModel }, }); @@ -56,7 +55,7 @@ describe('textEmbeddingModel', () => { it('should use fallback provider if model not found and fallback exists', () => { mockFallbackProvider.textEmbeddingModel.mockReturnValue(mockEmbeddingModel); - const provider = experimental_customProvider({ + const provider = customProvider({ fallbackProvider: mockFallbackProvider, }); @@ -67,7 +66,7 @@ describe('textEmbeddingModel', () => { }); it('should throw NoSuchModelError if model not found and no fallback', () => { - const provider = experimental_customProvider({}); + const provider = customProvider({}); expect(() => provider.textEmbeddingModel('test-model')).toThrow( NoSuchModelError, @@ -79,7 +78,7 @@ describe('imageModel', () => { const mockImageModel = new MockImageModelV1(); it('should return the image model if it exists', () => { - const provider = experimental_customProvider({ + const provider = customProvider({ imageModels: { 'test-model': mockImageModel }, }); @@ -89,7 +88,7 @@ describe('imageModel', () => { it('should use fallback provider if model not found and fallback exists', () => { mockFallbackProvider.imageModel = vi.fn().mockReturnValue(mockImageModel); - const provider = experimental_customProvider({ + const provider = customProvider({ fallbackProvider: mockFallbackProvider, }); @@ -98,7 +97,7 @@ describe('imageModel', () => { }); it('should throw NoSuchModelError if model not found and no fallback', () => { - const provider = experimental_customProvider({}); + const provider = customProvider({}); expect(() => provider.imageModel('test-model')).toThrow(NoSuchModelError); }); diff --git a/packages/ai/core/registry/custom-provider.ts b/packages/ai/core/registry/custom-provider.ts index 205ed2d8b7e7..e0774a14556b 100644 --- a/packages/ai/core/registry/custom-provider.ts +++ b/packages/ai/core/registry/custom-provider.ts @@ -18,7 +18,7 @@ import { NoSuchModelError } from '@ai-sdk/provider'; * * @throws {NoSuchModelError} Throws when a requested model is not found and no fallback provider is available. */ -export function experimental_customProvider< +export function customProvider< LANGUAGE_MODELS extends Record, EMBEDDING_MODELS extends Record>, IMAGE_MODELS extends Record, @@ -80,6 +80,11 @@ export function experimental_customProvider< }; } +/** + * @deprecated Use `customProvider` instead. + */ +export const experimental_customProvider = customProvider; + type ExtractModelId> = Extract< keyof MODELS, string diff --git a/packages/ai/core/registry/index.ts b/packages/ai/core/registry/index.ts index 6dbb02fee572..73384da6293d 100644 --- a/packages/ai/core/registry/index.ts +++ b/packages/ai/core/registry/index.ts @@ -1,3 +1,3 @@ -export { experimental_customProvider } from './custom-provider'; -export * from './no-such-provider-error'; -export * from './provider-registry'; +export { customProvider, experimental_customProvider } from './custom-provider'; +export { NoSuchProviderError } from './no-such-provider-error'; +export { experimental_createProviderRegistry } from './provider-registry';