MusePi

添加 Provider

English | 中文 一个 provider 由两半组成:

Scope。 本文适用于复用一个既有 wire API(openai-completionsanthropic-messagesgoogle-generative-ai,……)的 provider——这是 gateway 和 API-key provider 的常见情况,因为 stream dispatch keys 作用于 model.api,而非 model.provider。添加一个新的 wire protocol(新的 KnownApi)是独立任务,还需改动 stream.ts dispatch、api-registry.ts 和 catalog types.ts

Shape

针对常见情况,一个 provider 是一条 catalog entry + 一个 def file + 一条 registry line

  1. packages/catalog/src/provider-models/descriptors.ts 中为 CATALOG_PROVIDERS 添加一条 entry,包含 iddefaultModel、plain API-key env var(s) 作为 envVars,以及(通常)createModelManagerOptions factory。对于简单的 OpenAI-compatible gateway,可在 packages/catalog/src/provider-models/openai-compat.ts 中构建 factory,或以内联方式使用导出的 createSimpleOpenAICompletionsOptions(providerId, baseUrl, config)
  2. 创建 packages/ai/src/registry/<id>.ts,导出 export const <camelId>Provider = { … } as const satisfies ProviderDefinition; 并填 auth 字段(login,……)。Plain env-var 名放在 catalog entry 的 envVars;仅在需要计算式 resolver(Foundry/ADC/Bedrock-style probes)时才设置 envKeys
  3. 将该 provider 加入 packages/ai/src/registry/registry.tsALL 数组(一条 import + 一条数组 entry)。ALL 顺序即为 /login 中可登录 provider 的显示顺序。

以上即为以下场景的完整改动:

对于非 trivial 的 provider-local OAuth flow,把实现放在 packages/ai/src/registry/oauth/<vendor>.ts,并让 def file 做 lazy import。其复用的共享 OAuth flow infrastructure 位于同一 registry/oauth/ 目录。

Descriptors、default-model map、env-key map、login 列表和 refresh dispatch 均自动更新;KnownProvider union 从 catalog table 获得新的 id,OAuthProvider 从 registry 获得。

Field reference

Catalog table entryProviderCatalogEntry,JSDoc 见 packages/catalog/src/provider-models/descriptor-types.ts):

字段 效果
id 必填。KnownProvider 成员。
defaultModel 必填。未显式选择时的首选模型。
envVars 按顺序排列的 env var 名,供 runtime API-key fallback(getEnvApiKey)使用。
createModelManagerOptions Runtime model-discovery factory。存在且不等于 specialModelManager ⇒ 出现在 PROVIDER_DESCRIPTORS 中。
allowUnauthenticated Runtime 在无 key 时也创建 model manager。
dynamicModelsAuthoritative 成功的 discovery 替换 bundled models。
catalogDiscovery 用于离线 catalog generation(generate-models.ts)的 { label, envVars?, oauthProvider?, allowUnauthenticated? }。此处的 envVars 在 generation 使用不同凭据时覆盖 entry-level 列表(如 cursor)。
specialModelManager 定制 runtime factory(google-antigravity / google-gemini-cli / openai-codex);从 PROVIDER_DESCRIPTORS 中排除。

Registry definitionProviderDefinition,类型见 packages/ai/src/registry/types.ts):

字段 效果
idname 必填。name 显示在 /login 列表。
envKeys getEnvApiKey 的计算式 env fallback,覆盖 catalog entry 的 envVars:可为 var name 字符串或 () => string \| undefined resolver。若 envVars 已覆盖则省略。
login 交互式登录。存在 ⇒ 成为 OAuthProvider 成员,显示在 /login 中,可通过 AuthStorage.login dispatch。返回 api-key stringOAuthCredentials
refreshToken OAuth refresher;静态 token provider 省略(dispatch 原样返回 credentials)。
storeCredentialsAs 将凭据存储到不同 provider id 下(如 openai-codex-deviceopenai-codex)。
callbackPort 存在 ⇒ 加入 auth-broker 的 CALLBACK_PORTS map。
pasteCodeFlow OAuth flow 需要粘贴 code/redirect URL ⇒ 加入 PASTE_CODE_LOGIN_PROVIDERS

Conventions