onboard: support custom provider in non-interactive flow (#14223)

Merged via /review-pr -> /prepare-pr -> /merge-pr.

Prepared head SHA: 5b98d6514e73f7ee934a350f3b38619c70f49aed
Co-authored-by: ENCHIGO <38551565+ENCHIGO@users.noreply.github.com>
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Reviewed-by: @gumadeiras
This commit is contained in:
ENCHIGO
2026-02-12 03:48:45 +08:00
committed by GitHub
parent c8d9733e41
commit 029b77c85b
13 changed files with 791 additions and 90 deletions
+36
View File
@@ -228,6 +228,42 @@ describe("cli program (smoke)", () => {
}
});
it("passes custom provider flags to onboard", async () => {
const program = buildProgram();
await program.parseAsync(
[
"onboard",
"--non-interactive",
"--auth-choice",
"custom-api-key",
"--custom-base-url",
"https://llm.example.com/v1",
"--custom-api-key",
"sk-custom-test",
"--custom-model-id",
"foo-large",
"--custom-provider-id",
"my-custom",
"--custom-compatibility",
"anthropic",
],
{ from: "user" },
);
expect(onboardCommand).toHaveBeenCalledWith(
expect.objectContaining({
nonInteractive: true,
authChoice: "custom-api-key",
customBaseUrl: "https://llm.example.com/v1",
customApiKey: "sk-custom-test",
customModelId: "foo-large",
customProviderId: "my-custom",
customCompatibility: "anthropic",
}),
runtime,
);
});
it("runs channels login", async () => {
const program = buildProgram();
await program.parseAsync(["channels", "login", "--account", "work"], {
+14 -1
View File
@@ -58,7 +58,7 @@ export function registerOnboardCommand(program: Command) {
.option("--mode <mode>", "Wizard mode: local|remote")
.option(
"--auth-choice <choice>",
"Auth: setup-token|token|chutes|openai-codex|openai-api-key|xai-api-key|qianfan-api-key|openrouter-api-key|litellm-api-key|ai-gateway-api-key|cloudflare-ai-gateway-api-key|moonshot-api-key|moonshot-api-key-cn|kimi-code-api-key|synthetic-api-key|venice-api-key|gemini-api-key|zai-api-key|xiaomi-api-key|apiKey|minimax-api|minimax-api-lightning|opencode-zen|skip|together-api-key",
"Auth: setup-token|token|chutes|openai-codex|openai-api-key|xai-api-key|qianfan-api-key|openrouter-api-key|litellm-api-key|ai-gateway-api-key|cloudflare-ai-gateway-api-key|moonshot-api-key|moonshot-api-key-cn|kimi-code-api-key|synthetic-api-key|venice-api-key|gemini-api-key|zai-api-key|xiaomi-api-key|apiKey|minimax-api|minimax-api-lightning|opencode-zen|custom-api-key|skip|together-api-key",
)
.option(
"--token-provider <id>",
@@ -90,6 +90,14 @@ export function registerOnboardCommand(program: Command) {
.option("--xai-api-key <key>", "xAI API key")
.option("--litellm-api-key <key>", "LiteLLM API key")
.option("--qianfan-api-key <key>", "QIANFAN API key")
.option("--custom-base-url <url>", "Custom provider base URL")
.option("--custom-api-key <key>", "Custom provider API key (optional)")
.option("--custom-model-id <id>", "Custom provider model ID")
.option("--custom-provider-id <id>", "Custom provider ID (optional; auto-derived by default)")
.option(
"--custom-compatibility <mode>",
"Custom provider API compatibility: openai|anthropic (default: openai)",
)
.option("--gateway-port <port>", "Gateway port")
.option("--gateway-bind <mode>", "Gateway bind: loopback|tailnet|lan|auto|custom")
.option("--gateway-auth <mode>", "Gateway auth: token|password")
@@ -148,6 +156,11 @@ export function registerOnboardCommand(program: Command) {
opencodeZenApiKey: opts.opencodeZenApiKey as string | undefined,
xaiApiKey: opts.xaiApiKey as string | undefined,
litellmApiKey: opts.litellmApiKey as string | undefined,
customBaseUrl: opts.customBaseUrl as string | undefined,
customApiKey: opts.customApiKey as string | undefined,
customModelId: opts.customModelId as string | undefined,
customProviderId: opts.customProviderId as string | undefined,
customCompatibility: opts.customCompatibility as "openai" | "anthropic" | undefined,
gatewayPort:
typeof gatewayPort === "number" && Number.isFinite(gatewayPort)
? gatewayPort