From c31e366af9fe899d3d76c1310871e6ed7baefa2c Mon Sep 17 00:00:00 2001 From: LIlGG <1103069291@qq.com> Date: Mon, 29 Sep 2025 16:28:56 +0800 Subject: [PATCH] feat: add support for DouBao, Ernie, Kimi, Qwen, ZhiPu LLM providers Introduces new provider modules for DouBao, Ernie, Kimi, Qwen, and ZhiPu, and registers them in the LLM registry. Updates documentation and .env.example to include configuration instructions for these providers. Refactors OpenAI provider to support OpenAI-compatible endpoints. Adds @ai-sdk/openai-compatible and node-fetch dependencies. --- .env.example | 5 +- app/lib/.server/logger.server.ts | 2 +- app/lib/.server/logger.ts | 2 +- app/lib/modules/llm/providers/doubao.ts | 57 +++++++++++++++++++++ app/lib/modules/llm/providers/ernie.ts | 57 +++++++++++++++++++++ app/lib/modules/llm/providers/kimi.ts | 57 +++++++++++++++++++++ app/lib/modules/llm/providers/openai.ts | 15 ++++-- app/lib/modules/llm/providers/qwen.ts | 57 +++++++++++++++++++++ app/lib/modules/llm/providers/zhipu.ts | 57 +++++++++++++++++++++ app/lib/modules/llm/registry.ts | 10 ++++ docs/content/configuration.md | 68 +++++++++++++++++++++++-- package.json | 5 +- pnpm-lock.yaml | 28 ++++++++++ 13 files changed, 407 insertions(+), 13 deletions(-) create mode 100644 app/lib/modules/llm/providers/doubao.ts create mode 100644 app/lib/modules/llm/providers/ernie.ts create mode 100644 app/lib/modules/llm/providers/kimi.ts create mode 100644 app/lib/modules/llm/providers/qwen.ts create mode 100644 app/lib/modules/llm/providers/zhipu.ts diff --git a/.env.example b/.env.example index ed061ff..966983a 100644 --- a/.env.example +++ b/.env.example @@ -19,8 +19,9 @@ MAX_UPLOAD_SIZE_MB=5 # DEFAULT_NUM_CTX=6144 # Consumes 24GB of VRAM DEFAULT_NUM_CTX= -# LLM Configuration Options -# Enabled model providers, currently supporting Anthropic, Cohere, DeepSeek, Google, Groq, HuggingFace, Hyperbolic, Mistral, Ollama, OpenAI, OpenRouter, Perplexity, xAI, Together, LMStudio, AmazonBedrock, Github +# Enabled model providers, currently supporting Anthropic, Cohere, Deepseek, DouBao, Ernie, Google, Groq, +# HuggingFace, Hyperbolic, Kimi, Mistral, Ollama, OpenAI, OpenRouter, OpenAILike, Perplexity, Qwen, xAI, +# ZhiPu, Together, LMStudio, AmazonBedrock, Github LLM_PROVIDER= # BASE URL of the current model provider, some providers require this to be set, such as OpenAI, Ollama, LMStudio diff --git a/app/lib/.server/logger.server.ts b/app/lib/.server/logger.server.ts index 5dd6be9..7e150b4 100644 --- a/app/lib/.server/logger.server.ts +++ b/app/lib/.server/logger.server.ts @@ -22,7 +22,7 @@ let currentLevel: DebugLevel = (process.env.LOG_LEVEL as DebugLevel | undefined) || (import.meta.env.DEV ? 'debug' : 'info'); // 文件日志配置 -const enableFileLogging = process.env.USAGE_LOG_FILE === 'true' || import.meta.env.DEV; +const enableFileLogging = process.env.USAGE_LOG_FILE !== 'false'; const logDir = path.join(process.cwd(), 'logs'); // 确保日志目录存在 diff --git a/app/lib/.server/logger.ts b/app/lib/.server/logger.ts index 5dd6be9..7e150b4 100644 --- a/app/lib/.server/logger.ts +++ b/app/lib/.server/logger.ts @@ -22,7 +22,7 @@ let currentLevel: DebugLevel = (process.env.LOG_LEVEL as DebugLevel | undefined) || (import.meta.env.DEV ? 'debug' : 'info'); // 文件日志配置 -const enableFileLogging = process.env.USAGE_LOG_FILE === 'true' || import.meta.env.DEV; +const enableFileLogging = process.env.USAGE_LOG_FILE !== 'false'; const logDir = path.join(process.cwd(), 'logs'); // 确保日志目录存在 diff --git a/app/lib/modules/llm/providers/doubao.ts b/app/lib/modules/llm/providers/doubao.ts new file mode 100644 index 0000000..afcd64c --- /dev/null +++ b/app/lib/modules/llm/providers/doubao.ts @@ -0,0 +1,57 @@ +import { createOpenAICompatible } from '@ai-sdk/openai-compatible'; +import type { LanguageModel } from 'ai'; +import { BaseProvider } from '~/lib/modules/llm/base-provider'; +import type { ModelInfo } from '~/lib/modules/llm/types'; +import type { IProviderSetting } from '~/types/model'; + +export default class DouBaoProvider extends BaseProvider { + name = 'DouBao'; + getApiKeyLink = undefined; + + staticModels: ModelInfo[] = []; + + async getDynamicModels(settings?: IProviderSetting): Promise { + const { baseUrl: fetchBaseUrl, apiKey } = this.getProviderBaseUrlAndKey(settings); + const baseUrl = fetchBaseUrl || 'https://ark.cn-beijing.volces.com/api/v3'; + + if (!apiKey) { + throw `Missing Api Key configuration for ${this.name} provider`; + } + + const response = await fetch(`${baseUrl}/models`, { + headers: { + Authorization: `Bearer ${apiKey}`, + }, + }); + + const res = (await response.json()) as any; + + const data = res.data.filter((model: any) => model.object === 'model' && model.supports_chat); + + return data.map((m: any) => ({ + name: m.id, + label: `${m.id} - context ${m.context_length ? Math.floor(m.context_length / 1000) + 'k' : 'N/A'}`, + provider: this.name, + maxTokenAllowed: m.context_length || 8000, + })); + } + + getModelInstance(options: { model: string; providerSettings?: Record }): LanguageModel { + const { model, providerSettings } = options; + + const { apiKey } = this.getProviderBaseUrlAndKey(providerSettings?.[this.name]); + + if (!apiKey) { + throw `Missing Api Key configuration for ${this.name} provider`; + } + + const provider = createOpenAICompatible({ + name: this.name, + baseURL: 'https://ark.cn-beijing.volces.com/api/v3', + apiKey, + includeUsage: true, + }); + + return provider(model); + } +} diff --git a/app/lib/modules/llm/providers/ernie.ts b/app/lib/modules/llm/providers/ernie.ts new file mode 100644 index 0000000..d111f02 --- /dev/null +++ b/app/lib/modules/llm/providers/ernie.ts @@ -0,0 +1,57 @@ +import { createOpenAICompatible } from '@ai-sdk/openai-compatible'; +import type { LanguageModel } from 'ai'; +import { BaseProvider } from '~/lib/modules/llm/base-provider'; +import type { ModelInfo } from '~/lib/modules/llm/types'; +import type { IProviderSetting } from '~/types/model'; + +export default class ErnieProvider extends BaseProvider { + name = 'Ernie'; + getApiKeyLink = undefined; + + staticModels: ModelInfo[] = []; + + async getDynamicModels(settings?: IProviderSetting): Promise { + const { baseUrl: fetchBaseUrl, apiKey } = this.getProviderBaseUrlAndKey(settings); + const baseUrl = fetchBaseUrl || 'https://qianfan.baidubce.com/v2'; + + if (!apiKey) { + throw `Missing Api Key configuration for ${this.name} provider`; + } + + const response = await fetch(`${baseUrl}/models`, { + headers: { + Authorization: `Bearer ${apiKey}`, + }, + }); + + const res = (await response.json()) as any; + + const data = res.data.filter((model: any) => model.object === 'model' && model.supports_chat); + + return data.map((m: any) => ({ + name: m.id, + label: `${m.id} - context ${m.context_length ? Math.floor(m.context_length / 1000) + 'k' : 'N/A'}`, + provider: this.name, + maxTokenAllowed: m.context_length || 8000, + })); + } + + getModelInstance(options: { model: string; providerSettings?: Record }): LanguageModel { + const { model, providerSettings } = options; + + const { apiKey } = this.getProviderBaseUrlAndKey(providerSettings?.[this.name]); + + if (!apiKey) { + throw `Missing Api Key configuration for ${this.name} provider`; + } + + const provider = createOpenAICompatible({ + name: this.name, + baseURL: 'https://qianfan.baidubce.com/v2', + apiKey, + includeUsage: true, + }); + + return provider(model); + } +} diff --git a/app/lib/modules/llm/providers/kimi.ts b/app/lib/modules/llm/providers/kimi.ts new file mode 100644 index 0000000..03c1f45 --- /dev/null +++ b/app/lib/modules/llm/providers/kimi.ts @@ -0,0 +1,57 @@ +import { createOpenAICompatible } from '@ai-sdk/openai-compatible'; +import type { LanguageModel } from 'ai'; +import { BaseProvider } from '~/lib/modules/llm/base-provider'; +import type { ModelInfo } from '~/lib/modules/llm/types'; +import type { IProviderSetting } from '~/types/model'; + +export default class KimiProvider extends BaseProvider { + name = 'Kimi'; + getApiKeyLink = undefined; + + staticModels: ModelInfo[] = []; + + async getDynamicModels(settings?: IProviderSetting): Promise { + const { baseUrl: fetchBaseUrl, apiKey } = this.getProviderBaseUrlAndKey(settings); + const baseUrl = fetchBaseUrl || 'https://api.moonshot.cn/v1'; + + if (!apiKey) { + throw `Missing Api Key configuration for ${this.name} provider`; + } + + const response = await fetch(`${baseUrl}/models`, { + headers: { + Authorization: `Bearer ${apiKey}`, + }, + }); + + const res = (await response.json()) as any; + + const data = res.data.filter((model: any) => model.object === 'model' && model.supports_chat); + + return data.map((m: any) => ({ + name: m.id, + label: `${m.id} - context ${m.context_length ? Math.floor(m.context_length / 1000) + 'k' : 'N/A'}`, + provider: this.name, + maxTokenAllowed: m.context_length || 8000, + })); + } + + getModelInstance(options: { model: string; providerSettings?: Record }): LanguageModel { + const { model, providerSettings } = options; + + const { apiKey } = this.getProviderBaseUrlAndKey(providerSettings?.[this.name]); + + if (!apiKey) { + throw `Missing Api Key configuration for ${this.name} provider`; + } + + const provider = createOpenAICompatible({ + name: this.name, + baseURL: 'https://api.moonshot.cn/v1', + apiKey, + includeUsage: true, + }); + + return provider(model); + } +} diff --git a/app/lib/modules/llm/providers/openai.ts b/app/lib/modules/llm/providers/openai.ts index 731de82..83c0dcc 100644 --- a/app/lib/modules/llm/providers/openai.ts +++ b/app/lib/modules/llm/providers/openai.ts @@ -1,4 +1,5 @@ import { createOpenAI } from '@ai-sdk/openai'; +import { createOpenAICompatible } from '@ai-sdk/openai-compatible'; import type { LanguageModel } from 'ai'; import { BaseProvider } from '~/lib/modules/llm/base-provider'; import type { ModelInfo } from '~/lib/modules/llm/types'; @@ -42,13 +43,19 @@ export default class OpenAILikeProvider extends BaseProvider { throw new Error(`Missing configuration for ${this.name} provider`); } - let openaiBaseUrl = baseUrl; - if (!baseUrl) { - openaiBaseUrl = undefined; + if (!!baseUrl) { + const provider = createOpenAICompatible({ + name: this.name, + baseURL: baseUrl, + apiKey, + includeUsage: true, + }); + + return provider(model); } const openai = createOpenAI({ - baseURL: openaiBaseUrl, + baseURL: baseUrl, apiKey, }); diff --git a/app/lib/modules/llm/providers/qwen.ts b/app/lib/modules/llm/providers/qwen.ts new file mode 100644 index 0000000..5b436f6 --- /dev/null +++ b/app/lib/modules/llm/providers/qwen.ts @@ -0,0 +1,57 @@ +import { createOpenAICompatible } from '@ai-sdk/openai-compatible'; +import type { LanguageModel } from 'ai'; +import { BaseProvider } from '~/lib/modules/llm/base-provider'; +import type { ModelInfo } from '~/lib/modules/llm/types'; +import type { IProviderSetting } from '~/types/model'; + +export default class QwenProvider extends BaseProvider { + name = 'Qwen'; + getApiKeyLink = undefined; + + staticModels: ModelInfo[] = []; + + async getDynamicModels(settings?: IProviderSetting): Promise { + const { baseUrl: fetchBaseUrl, apiKey } = this.getProviderBaseUrlAndKey(settings); + const baseUrl = fetchBaseUrl || 'https://dashscope.aliyuncs.com/compatible-mode/v1'; + + if (!apiKey) { + throw `Missing Api Key configuration for ${this.name} provider`; + } + + const response = await fetch(`${baseUrl}/models`, { + headers: { + Authorization: `Bearer ${apiKey}`, + }, + }); + + const res = (await response.json()) as any; + + const data = res.data.filter((model: any) => model.object === 'model' && model.supports_chat); + + return data.map((m: any) => ({ + name: m.id, + label: `${m.id} - context ${m.context_length ? Math.floor(m.context_length / 1000) + 'k' : 'N/A'}`, + provider: this.name, + maxTokenAllowed: m.context_length || 8000, + })); + } + + getModelInstance(options: { model: string; providerSettings?: Record }): LanguageModel { + const { model, providerSettings } = options; + + const { apiKey } = this.getProviderBaseUrlAndKey(providerSettings?.[this.name]); + + if (!apiKey) { + throw `Missing Api Key configuration for ${this.name} provider`; + } + + const provider = createOpenAICompatible({ + name: this.name, + baseURL: 'https://dashscope.aliyuncs.com/compatible-mode/v1', + apiKey, + includeUsage: true, + }); + + return provider(model); + } +} diff --git a/app/lib/modules/llm/providers/zhipu.ts b/app/lib/modules/llm/providers/zhipu.ts new file mode 100644 index 0000000..49b9525 --- /dev/null +++ b/app/lib/modules/llm/providers/zhipu.ts @@ -0,0 +1,57 @@ +import { createOpenAICompatible } from '@ai-sdk/openai-compatible'; +import type { LanguageModel } from 'ai'; +import { BaseProvider } from '~/lib/modules/llm/base-provider'; +import type { ModelInfo } from '~/lib/modules/llm/types'; +import type { IProviderSetting } from '~/types/model'; + +export default class ZhiPuProvider extends BaseProvider { + name = 'ZhiPu'; + getApiKeyLink = undefined; + + staticModels: ModelInfo[] = []; + + async getDynamicModels(settings?: IProviderSetting): Promise { + const { baseUrl: fetchBaseUrl, apiKey } = this.getProviderBaseUrlAndKey(settings); + const baseUrl = fetchBaseUrl || 'https://open.bigmodel.cn/api/paas/v4'; + + if (!apiKey) { + throw `Missing Api Key configuration for ${this.name} provider`; + } + + const response = await fetch(`${baseUrl}/models`, { + headers: { + Authorization: `Bearer ${apiKey}`, + }, + }); + + const res = (await response.json()) as any; + + const data = res.data.filter((model: any) => model.object === 'model' && model.supports_chat); + + return data.map((m: any) => ({ + name: m.id, + label: `${m.id} - context ${m.context_length ? Math.floor(m.context_length / 1000) + 'k' : 'N/A'}`, + provider: this.name, + maxTokenAllowed: m.context_length || 8000, + })); + } + + getModelInstance(options: { model: string; providerSettings?: Record }): LanguageModel { + const { model, providerSettings } = options; + + const { apiKey } = this.getProviderBaseUrlAndKey(providerSettings?.[this.name]); + + if (!apiKey) { + throw `Missing Api Key configuration for ${this.name} provider`; + } + + const openai = createOpenAICompatible({ + name: this.name, + baseURL: 'https://open.bigmodel.cn/api/paas/v4', + apiKey, + includeUsage: true, + }); + + return openai(model); + } +} diff --git a/app/lib/modules/llm/registry.ts b/app/lib/modules/llm/registry.ts index 8d1122d..ceb33ad 100644 --- a/app/lib/modules/llm/registry.ts +++ b/app/lib/modules/llm/registry.ts @@ -2,24 +2,34 @@ import AmazonBedrockProvider from './providers/amazon-bedrock'; import AnthropicProvider from './providers/anthropic'; import CohereProvider from './providers/cohere'; import DeepseekProvider from './providers/deepseek'; +import DouBaoProvider from './providers/doubao'; +import ErnieProvider from './providers/ernie'; import GithubProvider from './providers/github'; import GoogleProvider from './providers/google'; import GroqProvider from './providers/groq'; import HuggingFaceProvider from './providers/huggingface'; import HyperbolicProvider from './providers/hyperbolic'; +import KimiProvider from './providers/kimi'; import LMStudioProvider from './providers/lmstudio'; import MistralProvider from './providers/mistral'; import OllamaProvider from './providers/ollama'; import OpenRouterProvider from './providers/open-router'; import OpenAIProvider from './providers/openai'; import PerplexityProvider from './providers/perplexity'; +import QwenProvider from './providers/qwen'; import TogetherProvider from './providers/together'; import XAIProvider from './providers/xai'; +import ZhiPuProvider from './providers/zhipu'; export { AnthropicProvider, CohereProvider, DeepseekProvider, + DouBaoProvider, + ErnieProvider, + KimiProvider, + QwenProvider, + ZhiPuProvider, GoogleProvider, GroqProvider, HuggingFaceProvider, diff --git a/docs/content/configuration.md b/docs/content/configuration.md index 270cbca..beef18d 100644 --- a/docs/content/configuration.md +++ b/docs/content/configuration.md @@ -37,7 +37,7 @@ UPage 支持多种 AI 提供商,您需要配置一个 AI 提供商才能使用 | 环境变量 | 描述 | 默认值 | 必填 | | --- | --- | --- | --- | -| `LLM_PROVIDER` | LLM 提供商,按照下述配置项配置一个 | - | 是 | +| `LLM_PROVIDER` | LLM 提供商,**按照下述配置项配置一个** | - | 是 | | `PROVIDER_BASE_URL` | LLM 提供商的 API 基础 URL,部分提供商需要设置此项,例如 Ollama, LMStudio。 OpenAI 可选此项 | - | 否,部分提供商不需要设置此项 | | `PROVIDER_API_KEY` | LLM 提供商的 API 密钥,大部分提供商需要设置此项 | - | 否,部分提供商不需要设置此项 | | `LLM_DEFAULT_MODEL` | 生成页面所使用的模型 | - | 是 | @@ -45,6 +45,61 @@ UPage 支持多种 AI 提供商,您需要配置一个 AI 提供商才能使用 以下是常见的 AI 提供商配置: +### 豆包(DouBao) + +| 环境变量 | 描述 | 默认值 | 必填 | +| --- | --- | --- | --- | +| `LLM_PROVIDER` | DouBao 提供商名称 | DouBao | 是 | +| `PROVIDER_API_KEY` | DouBao API 密钥 | - | 是(如果使用 DouBao) | + +:::info +前往 [DouBao](https://console.volcengine.com/ark/region:ark+cn-beijing/apiKey) 获取 API 密钥。 +::: + +### 文心一言(Ernie) + +| 环境变量 | 描述 | 默认值 | 必填 | +| --- | --- | --- | --- | +| `LLM_PROVIDER` | Ernie 提供商名称 | Ernie | 是 | +| `PROVIDER_API_KEY` | Ernie API 密钥 | - | 是(如果使用 Ernie) | + +:::info +前往 [Ernie](https://cloud.baidu.com/doc/WENXINWORKSHOP/s/wm9cvs292) 获取 API 密钥。 +::: + +### 月之暗面(Kimi) + +| 环境变量 | 描述 | 默认值 | 必填 | +| --- | --- | --- | --- | +| `LLM_PROVIDER` | Kimi 提供商名称 | Kimi | 是 | +| `PROVIDER_API_KEY` | Kimi API 密钥 | - | 是(如果使用 Kimi) | + +:::info +前往 [Kimi](https://platform.moonshot.cn/console/api-keys) 获取 API 密钥。 +::: + +### 通义千问(Qwen) + +| 环境变量 | 描述 | 默认值 | 必填 | +| --- | --- | --- | --- | +| `LLM_PROVIDER` | Qwen 提供商名称 | Qwen | 是 | +| `PROVIDER_API_KEY` | Qwen API 密钥 | - | 是(如果使用 Qwen) | + +:::info +前往 [Qwen](https://bailian.console.aliyun.com/?spm=5176.29597918.J_SEsSjsNv72yRuRFS2VknO.2.624f7b08yj3vyX&tab=api#/api/?type=model&url=2712195) 获取 API 密钥。 +::: + +### 智谱 AI(ZhiPu) + +| 环境变量 | 描述 | 默认值 | 必填 | +| --- | --- | --- | --- | +| `LLM_PROVIDER` | ZhiPu 提供商名称 | ZhiPu | 是 | +| `PROVIDER_API_KEY` | ZhiPu API 密钥 | - | 是(如果使用 ZhiPu) | + +:::info +前往 [ZhiPu](https://bigmodel.cn/usercenter/proj-mgmt/apikeys) 获取 API 密钥。 +::: + ### Amazon Bedrock | 环境变量 | 描述 | 默认值 | 必填 | @@ -206,11 +261,18 @@ UPage 支持多种 AI 提供商,您需要配置一个 AI 提供商才能使用 | 环境变量 | 描述 | 默认值 | 必填 | | --- | --- | --- | --- | | `LLM_PROVIDER` | OpenAI 提供商名称 | OpenAI | 是 | -| `PROVIDER_BASE_URL` | API 基础 URL | - | 否(不填写时,使用 OpenAI 官方 API) | +| `PROVIDER_BASE_URL` | 兼容 OpenAI 的 API 接口的地址 | - | 否(不填写时,使用 OpenAI 官方 API) | | `PROVIDER_API_KEY` | OpenAI API 密钥 | - | 是(如果使用 OpenAI) | :::info -前往 [OpenAI](https://help.openai.com/en/articles/4936850-where-do-i-find-my-openai-api-key) 获取 API 密钥。 +此供应商也支持任何 OpenAI 兼容的 API 接口,只需要额外配置 `PROVIDER_BASE_URL` 为兼容 OpenAI 的 API 接口的地址。 + +在一些第三方软件或平台输入自定义 URL 时,可能需要追加 /v1 或 /v1/chat/completions 等后缀。 + +如: +- https://your-api-base-url +- https://your-api-base-url/v1 (目前最常见) +- https://your-api-base-url/v1/chat/completions ::: ### Perplexity diff --git a/package.json b/package.json index 1da8636..15a3afb 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,7 @@ "@ai-sdk/google": "^2.0.15", "@ai-sdk/mistral": "^2.0.15", "@ai-sdk/openai": "^2.0.32", + "@ai-sdk/openai-compatible": "^1.0.19", "@ai-sdk/react": "^2.0.49", "@floating-ui/react": "^0.27.16", "@headlessui/react": "^2.2.8", @@ -84,6 +85,7 @@ "lodash": "^4.17.21", "morgan": "^1.10.1", "nanostores": "^1.0.1", + "node-fetch": "^3.3.2", "ollama-ai-provider-v2": "^1.3.1", "path-browserify": "^1.0.1", "prettier": "^3.6.2", @@ -108,8 +110,7 @@ "unist-util-visit": "^5.0.0", "winston": "^3.17.0", "winston-daily-rotate-file": "^5.0.0", - "zod": "^4.1.11", - "node-fetch": "^3.3.2" + "zod": "^4.1.11" }, "devDependencies": { "@biomejs/biome": "2.2.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2afe6ee..e077036 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -38,6 +38,9 @@ importers: '@ai-sdk/openai': specifier: ^2.0.32 version: 2.0.32(zod@4.1.11) + '@ai-sdk/openai-compatible': + specifier: ^1.0.19 + version: 1.0.19(zod@4.1.11) '@ai-sdk/react': specifier: ^2.0.49 version: 2.0.49(react@18.3.1)(zod@4.1.11) @@ -481,12 +484,24 @@ packages: peerDependencies: zod: ^3.25.76 || ^4 + '@ai-sdk/openai-compatible@1.0.19': + resolution: {integrity: sha512-hnsqPCCSNKgpZRNDOAIXZs7OcUDM4ut5ggWxj2sjB4tNL/aBn/xrM7pJkqu+WuPowyrE60wPVSlw0LvtXAlMXQ==} + engines: {node: '>=18'} + peerDependencies: + zod: ^3.25.76 || ^4.1.8 + '@ai-sdk/openai@2.0.32': resolution: {integrity: sha512-p7giSkCs66Q1qYO/NPYI41CrSg65mcm8R2uAdF86+Y1D1/q4mUrWMyf5UTOJ0bx/z4jIPiNgGDCg2Kabi5zrKQ==} engines: {node: '>=18'} peerDependencies: zod: ^3.25.76 || ^4 + '@ai-sdk/provider-utils@3.0.10': + resolution: {integrity: sha512-T1gZ76gEIwffep6MWI0QNy9jgoybUHE7TRaHB5k54K8mF91ciGFlbtCGxDYhMH3nCRergKwYFIDeFF0hJSIQHQ==} + engines: {node: '>=18'} + peerDependencies: + zod: ^3.25.76 || ^4.1.8 + '@ai-sdk/provider-utils@3.0.9': resolution: {integrity: sha512-Pm571x5efqaI4hf9yW4KsVlDBDme8++UepZRnq+kqVBWWjgvGhQlzU8glaFq0YJEB9kkxZHbRRyVeHoV2sRYaQ==} engines: {node: '>=18'} @@ -9990,12 +10005,25 @@ snapshots: '@ai-sdk/provider-utils': 3.0.9(zod@4.1.11) zod: 4.1.11 + '@ai-sdk/openai-compatible@1.0.19(zod@4.1.11)': + dependencies: + '@ai-sdk/provider': 2.0.0 + '@ai-sdk/provider-utils': 3.0.10(zod@4.1.11) + zod: 4.1.11 + '@ai-sdk/openai@2.0.32(zod@4.1.11)': dependencies: '@ai-sdk/provider': 2.0.0 '@ai-sdk/provider-utils': 3.0.9(zod@4.1.11) zod: 4.1.11 + '@ai-sdk/provider-utils@3.0.10(zod@4.1.11)': + dependencies: + '@ai-sdk/provider': 2.0.0 + '@standard-schema/spec': 1.0.0 + eventsource-parser: 3.0.6 + zod: 4.1.11 + '@ai-sdk/provider-utils@3.0.9(zod@4.1.11)': dependencies: '@ai-sdk/provider': 2.0.0