fix(litellm): handle AUTH_CHOICE_CANCELLED to retry auth selection

- Add retry loops in configure.gateway-auth and agents.commands.add
- Catch AUTH_CHOICE_CANCELLED error and re-prompt for auth method
- Users can now go back to auth method selection when LiteLLM setup fails
- Import AuthChoice type for proper typing

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Charles-Henri ROBICHE 2026-01-29 10:59:30 +01:00
parent d531f7d9a4
commit ce8fd694ae
No known key found for this signature in database
2 changed files with 75 additions and 44 deletions

View File

@ -254,27 +254,41 @@ export async function agentsAddCommand(
const authStore = ensureAuthProfileStore(agentDir, {
allowKeychainPrompt: false,
});
const authChoice = await promptAuthChoiceGrouped({
prompter,
store: authStore,
includeSkip: true,
});
const authResult = await applyAuthChoice({
authChoice,
config: nextConfig,
prompter,
runtime,
agentDir,
setDefaultModel: false,
agentId,
});
nextConfig = authResult.config;
if (authResult.agentModelOverride) {
nextConfig = applyAgentConfig(nextConfig, {
agentId,
model: authResult.agentModelOverride,
// Loop to allow retrying auth choice if user cancels during configuration
while (true) {
const authChoice = await promptAuthChoiceGrouped({
prompter,
store: authStore,
includeSkip: true,
});
try {
const authResult = await applyAuthChoice({
authChoice,
config: nextConfig,
prompter,
runtime,
agentDir,
setDefaultModel: false,
agentId,
});
nextConfig = authResult.config;
if (authResult.agentModelOverride) {
nextConfig = applyAgentConfig(nextConfig, {
agentId,
model: authResult.agentModelOverride,
});
}
break; // Success - exit the loop
} catch (error) {
// If user cancelled to go back to auth selection, loop again
if (error instanceof Error && error.message === "AUTH_CHOICE_CANCELLED") {
continue;
}
// Re-throw other errors
throw error;
}
}
}

View File

@ -4,6 +4,7 @@ import type { RuntimeEnv } from "../runtime.js";
import type { WizardPrompter } from "../wizard/prompts.js";
import { applyAuthChoice, resolvePreferredProviderForAuthChoice } from "./auth-choice.js";
import { promptAuthChoiceGrouped } from "./auth-choice-prompt.js";
import type { AuthChoice } from "./onboard-types.js";
import {
applyModelAllowlist,
applyModelFallbacksFromSelection,
@ -41,34 +42,50 @@ export async function promptAuthConfig(
runtime: RuntimeEnv,
prompter: WizardPrompter,
): Promise<MoltbotConfig> {
const authChoice = await promptAuthChoiceGrouped({
prompter,
store: ensureAuthProfileStore(undefined, {
allowKeychainPrompt: false,
}),
includeSkip: true,
});
let next = cfg;
if (authChoice !== "skip") {
const applied = await applyAuthChoice({
authChoice,
config: next,
let authChoice: AuthChoice;
// Loop to allow retrying auth choice if user cancels during configuration
while (true) {
authChoice = await promptAuthChoiceGrouped({
prompter,
runtime,
setDefaultModel: true,
store: ensureAuthProfileStore(undefined, {
allowKeychainPrompt: false,
}),
includeSkip: true,
});
next = applied.config;
} else {
const modelSelection = await promptDefaultModel({
config: next,
prompter,
allowKeep: true,
ignoreAllowlist: true,
preferredProvider: resolvePreferredProviderForAuthChoice(authChoice),
});
if (modelSelection.model) {
next = applyPrimaryModel(next, modelSelection.model);
if (authChoice !== "skip") {
try {
const applied = await applyAuthChoice({
authChoice,
config: next,
prompter,
runtime,
setDefaultModel: true,
});
next = applied.config;
break; // Success - exit the loop
} catch (error) {
// If user cancelled to go back to auth selection, loop again
if (error instanceof Error && error.message === "AUTH_CHOICE_CANCELLED") {
continue;
}
// Re-throw other errors
throw error;
}
} else {
const modelSelection = await promptDefaultModel({
config: next,
prompter,
allowKeep: true,
ignoreAllowlist: true,
preferredProvider: resolvePreferredProviderForAuthChoice(authChoice),
});
if (modelSelection.model) {
next = applyPrimaryModel(next, modelSelection.model);
}
break; // Skip selected - exit the loop
}
}