Files

1 line
16 KiB
JSON

{"repo": "blueberrycongee/lumina-note", "files": {"electron/main/agent-v2/providers/registry.ts": {"df9fbf321263e23123ac1ae88fd3f843b9dddddb": {"t": 1785595146.346354, "n": 7601, "h": "d458563608e3bfb2", "c": "/**\n * Provider registry — 把 Vercel AI SDK 各家 provider 的 create 函数包装成统一注册表。\n *\n * 每个 entry 知道:\n * - id: 稳定字符串(用作 IPC 配置键)\n * - label / description: 给 UI 展示\n * - requiresApiKey / supportsBaseUrl: 供 AI Settings UI 决定渲染哪些输入框\n * - createModel(settings, modelId) → LanguageModel: 把 BYOK 配置 + 模型 id 实例化\n *\n * 不做动态加载。ProviderId 是静态联合类型,新增 provider 只是在本文件加一行条目。\n * Agent V2 uses this registry for settings validation and provider test calls;\n * the opencode bridge translates the same persisted settings into opencode\n * config/auth.\n */\n\nimport { createAnthropic } from '@ai-sdk/anthropic'\nimport { createDeepSeek } from '@ai-sdk/deepseek'\nimport { createGoogleGenerativeAI } from '@ai-sdk/google'\nimport { createGroq } from '@ai-sdk/groq'\nimport { createOpenAI } from '@ai-sdk/openai'\nimport { createOpenAICompatible } from '@ai-sdk/openai-compatible'\nimport { createOpenRouter } from '@openrouter/ai-sdk-provider'\nimport { createOllama } from 'ollama-ai-provider-v2'\nimport type { LanguageModel } from 'ai'\n\nexport type ProviderId =\n | 'anthropic'\n | 'openai'\n | 'google'\n | 'deepseek'\n | 'moonshot'\n | 'glm'\n | 'mimo'\n | 'groq'\n | 'openrouter'\n | 'ollama'\n | 'openai-compatible'\n\nexport interface ProviderSettings {\n apiKey?: string\n baseUrl?: string\n /** 显示名,openai-compatible 走这条路,其他 provider 忽略 */\n name?: string\n headers?: Record<string, string>\n}\n\nexport interface ProviderEntry {\n id: ProviderId\n label: string\n description: string\n /** 是否必须配置 apiKey(Ollama 本地不需要) */\n requiresApiKey: boolean\n /** 是否支持自定义 baseUrl */\n supportsBaseUrl: boolean\n defaultBaseUrl?: string\n createModel(settings: ProviderSettings, modelId: string): LanguageModel\n}\n\nconst entries: ProviderEntry[] = [\n {\n id: 'anthropic',\n label: 'Anthropic',\n description: 'Claude 系列模型(Opus / Sonnet / Haiku)',\n requiresApiKey: true,\n supportsBaseUrl: true,\n defaultBaseUrl: 'https://api.anthropic.com',\n createModel(settings, modelId) {\n const factory = createAnthropic({\n apiKey: settings.apiKey ?? '',\n baseURL: settings.baseUrl,\n headers: settings.headers,\n })\n return factory(modelId)\n },\n },\n {\n id: 'openai',\n label: 'OpenAI',\n description: 'GPT 系列模型',\n requiresApiKey: true,\n supportsBaseUrl: true,\n defaultBaseUrl: 'https://api.openai.com/v1',\n createModel(settings, modelId) {\n const factory = createOpenAI({\n apiKey: settings.apiKey ?? '',\n baseURL: settings.baseUrl,\n headers: settings.headers,\n })\n return factory(modelId)\n },\n },\n {\n id: 'google',\n label: 'Google Gemini',\n description: 'Gemini 系列模型',\n requiresApiKey: true,\n supportsBaseUrl: true,\n defaultBaseUrl: 'https://generativelanguage.googleapis.com/v1beta',\n createModel(settings, modelId) {\n const factory = createGoogleGenerativeAI({\n apiKey: settings.apiKey ?? '',\n baseURL: settings.baseUrl,\n headers: settings.headers,\n })\n return factory(modelId)\n },\n },\n {\n id: 'deepseek',\n label: 'DeepSeek',\n description: 'DeepSeek 官方原生通道(V4 + 旧版 V3.2)',\n requiresApiKey: true,\n supportsBaseUrl: true,\n defaultBaseUrl: 'https://api.deepseek.com',\n createModel(settings, modelId) {\n const factory = createDeepSeek({\n apiKey: settings.apiKey ?? '',\n baseURL: settings.baseUrl,\n headers: settings.headers,\n })\n return factory(modelId)\n },\n },\n {\n id: 'moonshot',\n label: 'Moonshot (Kimi)',\n description: 'Moonshot Kimi 系列(K2.6 / K2.5 / Thinking)',\n requiresApiKey: true,\n supportsBaseUrl: true,\n defaultBaseUrl: 'https://api.moonshot.cn/v1',\n createModel(settings, modelId) {\n const factory = createOpenAICompatible({\n name: 'moonshot',\n apiKey: settings.apiKey ?? '',\n baseURL: settings.baseUrl ?? 'https://api.moonshot.cn/v1',\n headers: settings.headers,\n })\n return factory(modelId)\n },\n },\n {\n id: 'glm',\n label: 'Zhipu (GLM)',\n description: '智谱 GLM 系列(GLM-5 / GLM-4.7 / GLM-4.5 Air)',\n requiresApiKey: true,\n supportsBaseUrl: true,\n defaultBaseUrl: 'https://open.bigmodel.cn/api/paas/v4',\n createModel(settings, modelId) {\n const factory = createOpenAICompatible({\n name: 'glm',\n apiKey: settings.apiKey ?? '',\n baseURL: settings.baseUrl ?? 'https://open.bigmodel.cn/api/paas/v4',\n headers: settings.headers,\n })\n return factory(modelId)\n },\n },\n {\n id: 'mimo',\n label: 'Xiaomi MiMo',\n description: '小米 MiMo 系列(Official API / Token Plan regional endpoints)',\n requiresApiKey: true,\n supportsBaseUrl: true,\n defaultBaseUrl: 'https://api.xiaomimimo.com/v1',\n createModel(settings, modelId) {\n const factory = createOpenAICompatible({\n name: 'mimo',\n apiKey: settings.apiKey ?? '',\n baseURL: settings.baseUrl ?? 'https://api.xiaomimimo.com/v1',\n headers: settings.headers,\n })\n return factory(modelId)\n },\n },\n {\n id: 'groq',\n label: 'Groq',\n description: '低延迟推理,支持 Llama / Kimi / GPT-OSS 等',\n requiresApiKey: true,\n supportsBaseUrl: true,\n defaultBaseUrl: 'https://api.groq.com/openai/v1',\n createModel(settings, modelId) {\n const factory = createGroq({\n apiKey: settings.apiKey ?? '',\n baseURL: settings.baseUrl,\n headers: settings.headers,\n })\n return factory(modelId)\n },\n },\n {\n id: 'openrouter',\n label: 'OpenRouter',\n description: '多模型聚合网关',\n requiresApiKey: true,\n supportsBaseUrl: true,\n defaultBaseUrl: 'https://openrouter.ai/api/v1',\n createModel(settings, modelId) {\n const factory = createOpenRouter({\n apiKey: settings.apiKey ?? '',\n baseURL: settings.baseUrl,\n headers: settings.headers,\n })\n return factory(modelId)\n },\n },\n {\n id: 'ollama',\n label: 'Ollama',\n description: '本地模型',\n requiresApiKey: false,\n supportsBaseUrl: true,\n defaultBaseUrl: 'http://localhost:11434/api',\n createModel(settings, modelId) {\n const factory = createOllama({\n baseURL: settings.baseUrl,\n headers: settings.headers,\n })\n return factory(modelId)\n },\n },\n {\n id: 'openai-compatible',\n label: 'OpenAI Compatible',\n description:\n 'OpenAI 协议兼容通配通道(Moonshot / Zhipu / Qwen / vLLM / 自建 等)',\n requiresApiKey: true,\n supportsBaseUrl: true,\n createModel(settings, modelId) {\n if (!settings.baseUrl) {\n throw new Error('openai-compatible provider requires baseUrl')\n }\n const factory = createOpenAICompatible({\n name: settings.name ?? 'custom',\n apiKey: settings.apiKey ?? '',\n baseURL: settings.baseUrl,\n headers: settings.headers,\n })\n return factory(modelId)\n },\n },\n]\n\nconst registry = new Map<ProviderId, ProviderEntry>(\n entries.map((entry) => [entry.id, entry]),\n)\n\nexport function listProviders(): ProviderEntry[] {\n return entries\n}\n\nexport function getProvider(id: ProviderId): ProviderEntry | undefined {\n return registry.get(id)\n}\n\nexport function hasProvider(id: string): id is ProviderId {\n return registry.has(id as ProviderId)\n}\n\nexport function createLanguageModel(\n id: ProviderId,\n settings: ProviderSettings,\n modelId: string,\n): LanguageModel {\n const entry = registry.get(id)\n if (!entry) {\n throw new Error(`Unknown provider: ${id}`)\n }\n if (entry.requiresApiKey && !settings.apiKey) {\n throw new Error(`Provider ${id} requires an apiKey`)\n }\n return entry.createModel(settings, modelId)\n}\n"}, "ddd4f6370753cf6288cde2876289fa3cadf639d0": {"t": 1785759010.351071, "n": 7601, "h": "d458563608e3bfb2", "c": "/**\n * Provider registry — 把 Vercel AI SDK 各家 provider 的 create 函数包装成统一注册表。\n *\n * 每个 entry 知道:\n * - id: 稳定字符串(用作 IPC 配置键)\n * - label / description: 给 UI 展示\n * - requiresApiKey / supportsBaseUrl: 供 AI Settings UI 决定渲染哪些输入框\n * - createModel(settings, modelId) → LanguageModel: 把 BYOK 配置 + 模型 id 实例化\n *\n * 不做动态加载。ProviderId 是静态联合类型,新增 provider 只是在本文件加一行条目。\n * Agent V2 uses this registry for settings validation and provider test calls;\n * the opencode bridge translates the same persisted settings into opencode\n * config/auth.\n */\n\nimport { createAnthropic } from '@ai-sdk/anthropic'\nimport { createDeepSeek } from '@ai-sdk/deepseek'\nimport { createGoogleGenerativeAI } from '@ai-sdk/google'\nimport { createGroq } from '@ai-sdk/groq'\nimport { createOpenAI } from '@ai-sdk/openai'\nimport { createOpenAICompatible } from '@ai-sdk/openai-compatible'\nimport { createOpenRouter } from '@openrouter/ai-sdk-provider'\nimport { createOllama } from 'ollama-ai-provider-v2'\nimport type { LanguageModel } from 'ai'\n\nexport type ProviderId =\n | 'anthropic'\n | 'openai'\n | 'google'\n | 'deepseek'\n | 'moonshot'\n | 'glm'\n | 'mimo'\n | 'groq'\n | 'openrouter'\n | 'ollama'\n | 'openai-compatible'\n\nexport interface ProviderSettings {\n apiKey?: string\n baseUrl?: string\n /** 显示名,openai-compatible 走这条路,其他 provider 忽略 */\n name?: string\n headers?: Record<string, string>\n}\n\nexport interface ProviderEntry {\n id: ProviderId\n label: string\n description: string\n /** 是否必须配置 apiKey(Ollama 本地不需要) */\n requiresApiKey: boolean\n /** 是否支持自定义 baseUrl */\n supportsBaseUrl: boolean\n defaultBaseUrl?: string\n createModel(settings: ProviderSettings, modelId: string): LanguageModel\n}\n\nconst entries: ProviderEntry[] = [\n {\n id: 'anthropic',\n label: 'Anthropic',\n description: 'Claude 系列模型(Opus / Sonnet / Haiku)',\n requiresApiKey: true,\n supportsBaseUrl: true,\n defaultBaseUrl: 'https://api.anthropic.com',\n createModel(settings, modelId) {\n const factory = createAnthropic({\n apiKey: settings.apiKey ?? '',\n baseURL: settings.baseUrl,\n headers: settings.headers,\n })\n return factory(modelId)\n },\n },\n {\n id: 'openai',\n label: 'OpenAI',\n description: 'GPT 系列模型',\n requiresApiKey: true,\n supportsBaseUrl: true,\n defaultBaseUrl: 'https://api.openai.com/v1',\n createModel(settings, modelId) {\n const factory = createOpenAI({\n apiKey: settings.apiKey ?? '',\n baseURL: settings.baseUrl,\n headers: settings.headers,\n })\n return factory(modelId)\n },\n },\n {\n id: 'google',\n label: 'Google Gemini',\n description: 'Gemini 系列模型',\n requiresApiKey: true,\n supportsBaseUrl: true,\n defaultBaseUrl: 'https://generativelanguage.googleapis.com/v1beta',\n createModel(settings, modelId) {\n const factory = createGoogleGenerativeAI({\n apiKey: settings.apiKey ?? '',\n baseURL: settings.baseUrl,\n headers: settings.headers,\n })\n return factory(modelId)\n },\n },\n {\n id: 'deepseek',\n label: 'DeepSeek',\n description: 'DeepSeek 官方原生通道(V4 + 旧版 V3.2)',\n requiresApiKey: true,\n supportsBaseUrl: true,\n defaultBaseUrl: 'https://api.deepseek.com',\n createModel(settings, modelId) {\n const factory = createDeepSeek({\n apiKey: settings.apiKey ?? '',\n baseURL: settings.baseUrl,\n headers: settings.headers,\n })\n return factory(modelId)\n },\n },\n {\n id: 'moonshot',\n label: 'Moonshot (Kimi)',\n description: 'Moonshot Kimi 系列(K2.6 / K2.5 / Thinking)',\n requiresApiKey: true,\n supportsBaseUrl: true,\n defaultBaseUrl: 'https://api.moonshot.cn/v1',\n createModel(settings, modelId) {\n const factory = createOpenAICompatible({\n name: 'moonshot',\n apiKey: settings.apiKey ?? '',\n baseURL: settings.baseUrl ?? 'https://api.moonshot.cn/v1',\n headers: settings.headers,\n })\n return factory(modelId)\n },\n },\n {\n id: 'glm',\n label: 'Zhipu (GLM)',\n description: '智谱 GLM 系列(GLM-5 / GLM-4.7 / GLM-4.5 Air)',\n requiresApiKey: true,\n supportsBaseUrl: true,\n defaultBaseUrl: 'https://open.bigmodel.cn/api/paas/v4',\n createModel(settings, modelId) {\n const factory = createOpenAICompatible({\n name: 'glm',\n apiKey: settings.apiKey ?? '',\n baseURL: settings.baseUrl ?? 'https://open.bigmodel.cn/api/paas/v4',\n headers: settings.headers,\n })\n return factory(modelId)\n },\n },\n {\n id: 'mimo',\n label: 'Xiaomi MiMo',\n description: '小米 MiMo 系列(Official API / Token Plan regional endpoints)',\n requiresApiKey: true,\n supportsBaseUrl: true,\n defaultBaseUrl: 'https://api.xiaomimimo.com/v1',\n createModel(settings, modelId) {\n const factory = createOpenAICompatible({\n name: 'mimo',\n apiKey: settings.apiKey ?? '',\n baseURL: settings.baseUrl ?? 'https://api.xiaomimimo.com/v1',\n headers: settings.headers,\n })\n return factory(modelId)\n },\n },\n {\n id: 'groq',\n label: 'Groq',\n description: '低延迟推理,支持 Llama / Kimi / GPT-OSS 等',\n requiresApiKey: true,\n supportsBaseUrl: true,\n defaultBaseUrl: 'https://api.groq.com/openai/v1',\n createModel(settings, modelId) {\n const factory = createGroq({\n apiKey: settings.apiKey ?? '',\n baseURL: settings.baseUrl,\n headers: settings.headers,\n })\n return factory(modelId)\n },\n },\n {\n id: 'openrouter',\n label: 'OpenRouter',\n description: '多模型聚合网关',\n requiresApiKey: true,\n supportsBaseUrl: true,\n defaultBaseUrl: 'https://openrouter.ai/api/v1',\n createModel(settings, modelId) {\n const factory = createOpenRouter({\n apiKey: settings.apiKey ?? '',\n baseURL: settings.baseUrl,\n headers: settings.headers,\n })\n return factory(modelId)\n },\n },\n {\n id: 'ollama',\n label: 'Ollama',\n description: '本地模型',\n requiresApiKey: false,\n supportsBaseUrl: true,\n defaultBaseUrl: 'http://localhost:11434/api',\n createModel(settings, modelId) {\n const factory = createOllama({\n baseURL: settings.baseUrl,\n headers: settings.headers,\n })\n return factory(modelId)\n },\n },\n {\n id: 'openai-compatible',\n label: 'OpenAI Compatible',\n description:\n 'OpenAI 协议兼容通配通道(Moonshot / Zhipu / Qwen / vLLM / 自建 等)',\n requiresApiKey: true,\n supportsBaseUrl: true,\n createModel(settings, modelId) {\n if (!settings.baseUrl) {\n throw new Error('openai-compatible provider requires baseUrl')\n }\n const factory = createOpenAICompatible({\n name: settings.name ?? 'custom',\n apiKey: settings.apiKey ?? '',\n baseURL: settings.baseUrl,\n headers: settings.headers,\n })\n return factory(modelId)\n },\n },\n]\n\nconst registry = new Map<ProviderId, ProviderEntry>(\n entries.map((entry) => [entry.id, entry]),\n)\n\nexport function listProviders(): ProviderEntry[] {\n return entries\n}\n\nexport function getProvider(id: ProviderId): ProviderEntry | undefined {\n return registry.get(id)\n}\n\nexport function hasProvider(id: string): id is ProviderId {\n return registry.has(id as ProviderId)\n}\n\nexport function createLanguageModel(\n id: ProviderId,\n settings: ProviderSettings,\n modelId: string,\n): LanguageModel {\n const entry = registry.get(id)\n if (!entry) {\n throw new Error(`Unknown provider: ${id}`)\n }\n if (entry.requiresApiKey && !settings.apiKey) {\n throw new Error(`Provider ${id} requires an apiKey`)\n }\n return entry.createModel(settings, modelId)\n}\n"}}}}