fix(coding-agent): update provider auth guidance and defaults
This commit is contained in:
@@ -31,18 +31,20 @@ export class LoginDialogComponent extends Container implements Focusable {
|
||||
providerId: string,
|
||||
private onComplete: (success: boolean, message?: string) => void,
|
||||
providerNameOverride?: string,
|
||||
titleOverride?: string,
|
||||
) {
|
||||
super();
|
||||
this.tui = tui;
|
||||
|
||||
const providerInfo = getOAuthProviders().find((p) => p.id === providerId);
|
||||
const providerName = providerNameOverride || providerInfo?.name || providerId;
|
||||
const title = titleOverride ?? `Login to ${providerName}`;
|
||||
|
||||
// Top border
|
||||
this.addChild(new DynamicBorder());
|
||||
|
||||
// Title
|
||||
this.addChild(new Text(theme.fg("accent", theme.bold(`Login to ${providerName}`)), 1, 0));
|
||||
this.addChild(new Text(theme.fg("accent", theme.bold(title)), 1, 0));
|
||||
|
||||
// Dynamic content area
|
||||
this.contentContainer = new Container();
|
||||
@@ -147,6 +149,20 @@ export class LoginDialogComponent extends Container implements Focusable {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Show informational text without prompting for input.
|
||||
*/
|
||||
showInfo(lines: string[]): void {
|
||||
this.contentContainer.clear();
|
||||
this.contentContainer.addChild(new Spacer(1));
|
||||
for (const line of lines) {
|
||||
this.contentContainer.addChild(new Text(line, 1, 0));
|
||||
}
|
||||
this.contentContainer.addChild(new Spacer(1));
|
||||
this.contentContainer.addChild(new Text(`(${keyHint("tui.select.cancel", "to close")})`, 1, 0));
|
||||
this.tui.requestRender();
|
||||
}
|
||||
|
||||
/**
|
||||
* Show waiting message (for polling flows like GitHub Copilot)
|
||||
*/
|
||||
|
||||
@@ -93,7 +93,7 @@ export class ModelSelectorComponent extends Container implements Focusable {
|
||||
this.scopeHintText = new Text(this.getScopeHintText(), 0, 0);
|
||||
this.addChild(this.scopeHintText);
|
||||
} else {
|
||||
const hintText = "Only showing models with configured API keys (see README for details)";
|
||||
const hintText = "Only showing models from configured providers. Use /login to add providers.";
|
||||
this.addChild(new Text(theme.fg("warning", hintText), 0, 0));
|
||||
}
|
||||
this.addChild(new Spacer(1));
|
||||
|
||||
@@ -52,6 +52,7 @@ import {
|
||||
getAgentDir,
|
||||
getAuthPath,
|
||||
getDebugLogPath,
|
||||
getDocsPath,
|
||||
getShareViewerUrl,
|
||||
getUpdateInstruction,
|
||||
VERSION,
|
||||
@@ -161,7 +162,7 @@ type CompactionQueuedMessage = {
|
||||
};
|
||||
|
||||
const ANTHROPIC_SUBSCRIPTION_AUTH_WARNING =
|
||||
"Anthropic subscription auth is active. Third-party usage now draws from extra usage and is billed per token, not your Claude plan limits. Manage extra usage at https://claude.ai/settings/usage.";
|
||||
"Anthropic subscription auth is active. Third-party harness usage draws from extra usage and is billed per token, not your Claude plan limits. Manage extra usage at https://claude.ai/settings/usage.";
|
||||
|
||||
function isAnthropicSubscriptionAuthKey(apiKey: string | undefined): boolean {
|
||||
return typeof apiKey === "string" && apiKey.startsWith("sk-ant-oat");
|
||||
@@ -175,8 +176,11 @@ function hasDefaultModelProvider(providerId: string): providerId is keyof typeof
|
||||
return providerId in defaultModelPerProvider;
|
||||
}
|
||||
|
||||
const BEDROCK_PROVIDER_ID = "amazon-bedrock";
|
||||
|
||||
const API_KEY_LOGIN_PROVIDERS: Record<string, string> = {
|
||||
anthropic: "Anthropic",
|
||||
[BEDROCK_PROVIDER_ID]: "Amazon Bedrock",
|
||||
"azure-openai-responses": "Azure OpenAI Responses",
|
||||
cerebras: "Cerebras",
|
||||
fireworks: "Fireworks",
|
||||
@@ -4423,6 +4427,8 @@ export class InteractiveMode {
|
||||
|
||||
if (providerOption.authType === "oauth") {
|
||||
await this.showLoginDialog(providerOption.id, providerOption.name);
|
||||
} else if (providerOption.id === BEDROCK_PROVIDER_ID) {
|
||||
this.showBedrockSetupDialog(providerOption.id, providerOption.name);
|
||||
} else {
|
||||
await this.showApiKeyLoginDialog(providerOption.id, providerOption.name);
|
||||
}
|
||||
@@ -4536,6 +4542,34 @@ export class InteractiveMode {
|
||||
}
|
||||
}
|
||||
|
||||
private showBedrockSetupDialog(providerId: string, providerName: string): void {
|
||||
const restoreEditor = () => {
|
||||
this.editorContainer.clear();
|
||||
this.editorContainer.addChild(this.editor);
|
||||
this.ui.setFocus(this.editor);
|
||||
this.ui.requestRender();
|
||||
};
|
||||
|
||||
const dialog = new LoginDialogComponent(
|
||||
this.ui,
|
||||
providerId,
|
||||
() => restoreEditor(),
|
||||
providerName,
|
||||
"Amazon Bedrock setup",
|
||||
);
|
||||
dialog.showInfo([
|
||||
theme.fg("text", "Amazon Bedrock uses AWS credentials instead of a single API key."),
|
||||
theme.fg("text", "Configure an AWS profile, IAM keys, bearer token, or role-based credentials."),
|
||||
theme.fg("muted", "See:"),
|
||||
theme.fg("accent", ` ${path.join(getDocsPath(), "providers.md")}`),
|
||||
]);
|
||||
|
||||
this.editorContainer.clear();
|
||||
this.editorContainer.addChild(dialog);
|
||||
this.ui.setFocus(dialog);
|
||||
this.ui.requestRender();
|
||||
}
|
||||
|
||||
private async showApiKeyLoginDialog(providerId: string, providerName: string): Promise<void> {
|
||||
const previousModel = this.session.model;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user