Files
openclaw/src/commands/auth-choice-options.ts
2026-01-31 08:02:45 +01:00

229 lines
5.7 KiB
TypeScript

import type { AuthProfileStore } from "../agents/auth-profiles.js";
import type { AuthChoice } from "./onboard-types.js";
export type AuthChoiceOption = {
value: AuthChoice;
label: string;
hint?: string;
};
export type AuthChoiceGroupId =
| "openai"
| "anthropic"
| "google"
| "copilot"
| "openrouter"
| "ai-gateway"
| "moonshot"
| "zai"
| "xiaomi"
| "opencode-zen"
| "minimax"
| "synthetic"
| "venice"
| "qwen";
export type AuthChoiceGroup = {
value: AuthChoiceGroupId;
label: string;
hint?: string;
options: AuthChoiceOption[];
};
const AUTH_CHOICE_GROUP_DEFS: {
value: AuthChoiceGroupId;
label: string;
hint?: string;
choices: AuthChoice[];
}[] = [
{
value: "openai",
label: "OpenAI",
hint: "Codex OAuth + API key",
choices: ["openai-codex", "openai-api-key"],
},
{
value: "anthropic",
label: "Anthropic",
hint: "setup-token + API key",
choices: ["token", "apiKey"],
},
{
value: "minimax",
label: "MiniMax",
hint: "M2.1 (recommended)",
choices: ["minimax-api", "minimax-api-lightning"],
},
{
value: "moonshot",
label: "Moonshot AI",
hint: "Kimi K2 + Kimi Coding",
choices: ["moonshot-api-key", "kimi-code-api-key"],
},
{
value: "google",
label: "Google",
hint: "Gemini API key + OAuth",
choices: ["gemini-api-key", "google-antigravity", "google-gemini-cli"],
},
{
value: "openrouter",
label: "OpenRouter",
hint: "API key",
choices: ["openrouter-api-key"],
},
{
value: "qwen",
label: "Qwen",
hint: "OAuth",
choices: ["qwen-portal"],
},
{
value: "zai",
label: "Z.AI (GLM 4.7)",
hint: "API key",
choices: ["zai-api-key"],
},
{
value: "copilot",
label: "Copilot",
hint: "GitHub + local proxy",
choices: ["github-copilot", "copilot-proxy"],
},
{
value: "ai-gateway",
label: "Vercel AI Gateway",
hint: "API key",
choices: ["ai-gateway-api-key"],
},
{
value: "opencode-zen",
label: "OpenCode Zen",
hint: "API key",
choices: ["opencode-zen"],
},
{
value: "xiaomi",
label: "Xiaomi",
hint: "API key",
choices: ["xiaomi-api-key"],
},
{
value: "synthetic",
label: "Synthetic",
hint: "Anthropic-compatible (multi-model)",
choices: ["synthetic-api-key"],
},
{
value: "venice",
label: "Venice AI",
hint: "Privacy-focused (uncensored models)",
choices: ["venice-api-key"],
},
];
export function buildAuthChoiceOptions(params: {
store: AuthProfileStore;
includeSkip: boolean;
}): AuthChoiceOption[] {
void params.store;
const options: AuthChoiceOption[] = [];
options.push({
value: "token",
label: "Anthropic token (paste setup-token)",
hint: "run `claude setup-token` elsewhere, then paste the token here",
});
options.push({
value: "openai-codex",
label: "OpenAI Codex (ChatGPT OAuth)",
});
options.push({ value: "chutes", label: "Chutes (OAuth)" });
options.push({ value: "openai-api-key", label: "OpenAI API key" });
options.push({ value: "openrouter-api-key", label: "OpenRouter API key" });
options.push({
value: "ai-gateway-api-key",
label: "Vercel AI Gateway API key",
});
options.push({ value: "moonshot-api-key", label: "Moonshot AI API key" });
options.push({ value: "kimi-code-api-key", label: "Kimi Coding API key" });
options.push({ value: "synthetic-api-key", label: "Synthetic API key" });
options.push({
value: "venice-api-key",
label: "Venice AI API key",
hint: "Privacy-focused inference (uncensored models)",
});
options.push({
value: "github-copilot",
label: "GitHub Copilot (GitHub device login)",
hint: "Uses GitHub device flow",
});
options.push({ value: "gemini-api-key", label: "Google Gemini API key" });
options.push({
value: "google-antigravity",
label: "Google Antigravity OAuth",
hint: "Uses the bundled Antigravity auth plugin",
});
options.push({
value: "google-gemini-cli",
label: "Google Gemini CLI OAuth",
hint: "Uses the bundled Gemini CLI auth plugin",
});
options.push({ value: "zai-api-key", label: "Z.AI (GLM 4.7) API key" });
options.push({
value: "xiaomi-api-key",
label: "Xiaomi API key",
});
options.push({ value: "qwen-portal", label: "Qwen OAuth" });
options.push({
value: "copilot-proxy",
label: "Copilot Proxy (local)",
hint: "Local proxy for VS Code Copilot models",
});
options.push({ value: "apiKey", label: "Anthropic API key" });
// Token flow is currently Anthropic-only; use CLI for advanced providers.
options.push({
value: "opencode-zen",
label: "OpenCode Zen (multi-model proxy)",
hint: "Claude, GPT, Gemini via opencode.ai/zen",
});
options.push({ value: "minimax-api", label: "MiniMax M2.1" });
options.push({
value: "minimax-api-lightning",
label: "MiniMax M2.1 Lightning",
hint: "Faster, higher output cost",
});
if (params.includeSkip) {
options.push({ value: "skip", label: "Skip for now" });
}
return options;
}
export function buildAuthChoiceGroups(params: { store: AuthProfileStore; includeSkip: boolean }): {
groups: AuthChoiceGroup[];
skipOption?: AuthChoiceOption;
} {
const options = buildAuthChoiceOptions({
...params,
includeSkip: false,
});
const optionByValue = new Map<AuthChoice, AuthChoiceOption>(
options.map((opt) => [opt.value, opt]),
);
const groups = AUTH_CHOICE_GROUP_DEFS.map((group) => ({
...group,
options: group.choices
.map((choice) => optionByValue.get(choice))
.filter((opt): opt is AuthChoiceOption => Boolean(opt)),
}));
const skipOption = params.includeSkip
? ({ value: "skip", label: "Skip for now" } satisfies AuthChoiceOption)
: undefined;
return { groups, skipOption };
}