Files
openclaw/src/commands/onboard-non-interactive/local/auth-choice-inference.ts
Gustavo Madeira Santana 22927b0834 fix: infer --auth-choice from API key flags during non-interactive onboarding (#9241)
* fix: infer --auth-choice from API key flags during non-interactive onboarding

When --anthropic-api-key (or other provider key flags) is passed without
an explicit --auth-choice, the auth choice defaults to "skip", silently
discarding the API key. This means the gateway starts without credentials
and fails on every inbound message with "No API key found for provider".

Add inferAuthChoiceFromFlags() to derive the correct auth choice from
whichever provider API key flag was supplied, so credentials are persisted
to auth-profiles.json as expected.

Fixes #8481

* fix: infer auth choice from API key flags (#8484) (thanks @f-trycua)

* refactor: centralize auth choice inference flags (#8484) (thanks @f-trycua)

---------

Co-authored-by: f-trycua <f@trycua.com>
2026-02-04 20:38:46 -05:00

68 lines
2.4 KiB
TypeScript

import type { AuthChoice, OnboardOptions } from "../../onboard-types.js";
type AuthChoiceFlag = {
flag: keyof AuthChoiceFlagOptions;
authChoice: AuthChoice;
label: string;
};
type AuthChoiceFlagOptions = Pick<
OnboardOptions,
| "anthropicApiKey"
| "geminiApiKey"
| "openaiApiKey"
| "openrouterApiKey"
| "aiGatewayApiKey"
| "cloudflareAiGatewayApiKey"
| "moonshotApiKey"
| "kimiCodeApiKey"
| "syntheticApiKey"
| "veniceApiKey"
| "zaiApiKey"
| "xiaomiApiKey"
| "minimaxApiKey"
| "opencodeZenApiKey"
>;
const AUTH_CHOICE_FLAG_MAP = [
{ flag: "anthropicApiKey", authChoice: "apiKey", label: "--anthropic-api-key" },
{ flag: "geminiApiKey", authChoice: "gemini-api-key", label: "--gemini-api-key" },
{ flag: "openaiApiKey", authChoice: "openai-api-key", label: "--openai-api-key" },
{ flag: "openrouterApiKey", authChoice: "openrouter-api-key", label: "--openrouter-api-key" },
{ flag: "aiGatewayApiKey", authChoice: "ai-gateway-api-key", label: "--ai-gateway-api-key" },
{
flag: "cloudflareAiGatewayApiKey",
authChoice: "cloudflare-ai-gateway-api-key",
label: "--cloudflare-ai-gateway-api-key",
},
{ flag: "moonshotApiKey", authChoice: "moonshot-api-key", label: "--moonshot-api-key" },
{ flag: "kimiCodeApiKey", authChoice: "kimi-code-api-key", label: "--kimi-code-api-key" },
{ flag: "syntheticApiKey", authChoice: "synthetic-api-key", label: "--synthetic-api-key" },
{ flag: "veniceApiKey", authChoice: "venice-api-key", label: "--venice-api-key" },
{ flag: "zaiApiKey", authChoice: "zai-api-key", label: "--zai-api-key" },
{ flag: "xiaomiApiKey", authChoice: "xiaomi-api-key", label: "--xiaomi-api-key" },
{ flag: "minimaxApiKey", authChoice: "minimax-api", label: "--minimax-api-key" },
{ flag: "opencodeZenApiKey", authChoice: "opencode-zen", label: "--opencode-zen-api-key" },
] satisfies ReadonlyArray<AuthChoiceFlag>;
export type AuthChoiceInference = {
choice?: AuthChoice;
matches: AuthChoiceFlag[];
};
// Infer auth choice from explicit provider API key flags.
export function inferAuthChoiceFromFlags(opts: OnboardOptions): AuthChoiceInference {
const matches = AUTH_CHOICE_FLAG_MAP.filter(({ flag }) => {
const value = opts[flag];
if (typeof value === "string") {
return value.trim().length > 0;
}
return Boolean(value);
});
return {
choice: matches[0]?.authChoice,
matches,
};
}