diff --git a/packages/opencode/src/cli/cmd/providers.ts b/packages/opencode/src/cli/cmd/providers.ts index 0d890cc21..b99e7863a 100644 --- a/packages/opencode/src/cli/cmd/providers.ts +++ b/packages/opencode/src/cli/cmd/providers.ts @@ -8,6 +8,7 @@ import { ModelsDev } from "@opencode-ai/core/models-dev" import { map, pipe, sortBy, values } from "remeda" import path from "path" import os from "os" +import fsNode from "node:fs" import { Config } from "@/config/config" import { Global } from "@opencode-ai/core/global" import { Plugin } from "../../plugin" @@ -481,6 +482,38 @@ export const ProvidersLoginCommand = effectCmd({ const apiKey = yield* promptValue(key) yield* Effect.orDie(authSvc.set(provider, { type: "api", key: apiKey })) + // zmo: 询问自定义 base URL(中转地址),留空则用官方默认。 + // baseURL 不存 auth.json,写入 config 文件的 provider..options.baseURL。 + const baseURLInput = yield* Prompt.text({ + message: "Base URL (中转地址,留空使用官方默认)", + placeholder: "https://your-proxy.example.com/v1", + }) + const baseURL = (yield* promptValue(baseURLInput))?.trim() + if (baseURL) { + try { + const configDir = Global.Path.config + fsNode.mkdirSync(configDir, { recursive: true }) + const file = path.join(configDir, "zmo.json") + let data: any = {} + if (fsNode.existsSync(file)) { + try { + data = JSON.parse(fsNode.readFileSync(file, "utf8")) ?? {} + } catch { + data = {} + } + } + if (!data.$schema) data.$schema = "https://zmo.dev/config.json" + data.provider ??= {} + data.provider[provider] ??= {} + data.provider[provider].options ??= {} + data.provider[provider].options.baseURL = baseURL + fsNode.writeFileSync(file, JSON.stringify(data, null, 2)) + yield* Prompt.log.info(`Base URL 已保存到 ${file}`) + } catch { + yield* Prompt.log.warn("Base URL 保存失败,请手动写入 zmo.json") + } + } + yield* Prompt.outro("Done") }), })