@ponythewhite/base-context 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +37 -0
- package/NOTICE +0 -5
- package/README.md +44 -27
- package/dist/NOTICE +0 -5
- package/dist/base-context-runtime/pyproject.toml +1 -1
- package/dist/base-context-runtime/src/rlm/__init__.py +7 -5
- package/dist/base-context-runtime/test/test_subagent_registry.py +28 -1
- package/dist/base-context-runtime/uv.lock +1 -1
- package/dist/build-info.json +1 -1
- package/dist/bundle/amazon-bedrock.js +21 -0
- package/dist/bundle/{anthropic-YY4S534V.js → anthropic-UV5GZDGU.js} +5 -5
- package/dist/bundle/{azure-openai-responses-JRP6MIM3.js → azure-openai-responses-WSNPXLYC.js} +6 -6
- package/dist/bundle/{bundled-modules-P5HARVZA.js → bundled-modules-PWOGKUQQ.js} +71 -16
- package/dist/bundle/chunk-27QCJ2AZ.js +2578 -0
- package/dist/bundle/{chunk-BYVP7LWV.js → chunk-44PEHPOG.js} +1916 -4689
- package/dist/bundle/{chunk-MZHTNNVA.js → chunk-4GXPNXOJ.js} +8 -0
- package/dist/bundle/{chunk-SC5KG5R4.js → chunk-DGNX7HQ3.js} +1 -7
- package/dist/bundle/{chunk-A53O363M.js → chunk-GRJFXLBM.js} +0 -1
- package/dist/bundle/chunk-HKINIBP4.js +29 -0
- package/dist/bundle/{chunk-73DCPU3D.js → chunk-IADCPVEI.js} +1019 -3427
- package/dist/bundle/{chunk-UDSW6FNG.js → chunk-KTNETTHI.js} +1 -1
- package/dist/bundle/{chunk-U7AUVG3B.js → chunk-VSIYFWYI.js} +24 -6
- package/dist/bundle/{chunk-IW77OXFS.js → chunk-W46VZFI6.js} +0 -2099
- package/dist/bundle/{cli-main-O4X7GFGY.js → cli-main-4DS7Y3PI.js} +8 -6
- package/dist/bundle/cli.js +2 -2
- package/dist/bundle/{google-AUTVGDGZ.js → google-T32FMD4G.js} +6 -6
- package/dist/bundle/{google-vertex-Q75D7RKS.js → google-vertex-56KP6I3B.js} +3 -3
- package/dist/bundle/{main-XKOW2BV6.js → main-SV7JLVEB.js} +7 -5
- package/dist/bundle/{mistral-7ESB7QUD.js → mistral-WGBMYIVU.js} +5 -5
- package/dist/bundle/{openai-codex-responses-LV3QRPN4.js → openai-codex-responses-PIV2RQ3G.js} +6 -6
- package/dist/bundle/{openai-completions-OJECLPXJ.js → openai-completions-64C3JPR4.js} +11 -22
- package/dist/bundle/{openai-responses-FN6HZMBC.js → openai-responses-UI7RSTDV.js} +6 -6
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +108 -59
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/daemon-ps.d.ts +4 -3
- package/dist/cli/daemon-ps.d.ts.map +1 -1
- package/dist/cli/daemon-ps.js +6 -1
- package/dist/cli/daemon-ps.js.map +1 -1
- package/dist/cli/product-doctor.d.ts +0 -1
- package/dist/cli/product-doctor.d.ts.map +1 -1
- package/dist/cli/product-doctor.js +6 -3
- package/dist/cli/product-doctor.js.map +1 -1
- package/dist/config.d.ts +0 -3
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +0 -8
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session-config.d.ts +1 -2
- package/dist/core/agent-session-config.d.ts.map +1 -1
- package/dist/core/agent-session-config.js +0 -3
- package/dist/core/agent-session-config.js.map +1 -1
- package/dist/core/agent-session-runtime.d.ts.map +1 -1
- package/dist/core/agent-session-runtime.js +5 -4
- package/dist/core/agent-session-runtime.js.map +1 -1
- package/dist/core/agent-session-services.d.ts +5 -3
- package/dist/core/agent-session-services.d.ts.map +1 -1
- package/dist/core/agent-session-services.js +2 -27
- package/dist/core/agent-session-services.js.map +1 -1
- package/dist/core/agent-session.d.ts +10 -6
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +107 -107
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/auth-storage.d.ts +8 -35
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +33 -243
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/cron-jobs.d.ts.map +1 -1
- package/dist/core/cron-jobs.js +7 -1
- package/dist/core/cron-jobs.js.map +1 -1
- package/dist/core/inference-coordinator.d.ts +6 -1
- package/dist/core/inference-coordinator.d.ts.map +1 -1
- package/dist/core/inference-coordinator.js +18 -2
- package/dist/core/inference-coordinator.js.map +1 -1
- package/dist/core/kernel/bootstrap.d.ts.map +1 -1
- package/dist/core/kernel/bootstrap.js +2 -2
- package/dist/core/kernel/bootstrap.js.map +1 -1
- package/dist/core/kernel/repl-manager.d.ts +2 -0
- package/dist/core/kernel/repl-manager.d.ts.map +1 -1
- package/dist/core/kernel/repl-manager.js +44 -1
- package/dist/core/kernel/repl-manager.js.map +1 -1
- package/dist/core/logging.d.ts +4 -3
- package/dist/core/logging.d.ts.map +1 -1
- package/dist/core/logging.js +6 -6
- package/dist/core/logging.js.map +1 -1
- package/dist/core/mcp/mcp-manager.d.ts.map +1 -1
- package/dist/core/mcp/mcp-manager.js +3 -3
- package/dist/core/mcp/mcp-manager.js.map +1 -1
- package/dist/core/model-registry.d.ts +1 -16
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +88 -196
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/model-resolver.d.ts +2 -19
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +36 -266
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/provider-contracts.d.ts +5 -6
- package/dist/core/provider-contracts.d.ts.map +1 -1
- package/dist/core/provider-contracts.js +25 -36
- package/dist/core/provider-contracts.js.map +1 -1
- package/dist/core/provider-display-names.d.ts.map +1 -1
- package/dist/core/provider-display-names.js +0 -2
- package/dist/core/provider-display-names.js.map +1 -1
- package/dist/core/rlm-max-subagents.d.ts +32 -0
- package/dist/core/rlm-max-subagents.d.ts.map +1 -0
- package/dist/core/rlm-max-subagents.js +50 -0
- package/dist/core/rlm-max-subagents.js.map +1 -0
- package/dist/core/rlm-runtime.d.ts +3 -3
- package/dist/core/rlm-runtime.d.ts.map +1 -1
- package/dist/core/rlm-runtime.js.map +1 -1
- package/dist/core/sdk.d.ts +4 -3
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +27 -14
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/settings-manager.d.ts +3 -16
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +12 -44
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +6 -6
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/installer.mjs +2 -3
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +39 -34
- package/dist/main.js.map +1 -1
- package/dist/modes/acp/acp-mode.d.ts.map +1 -1
- package/dist/modes/acp/acp-mode.js +1 -1
- package/dist/modes/acp/acp-mode.js.map +1 -1
- package/dist/modes/agent-connection/daemon-agent-connection.d.ts +6 -2
- package/dist/modes/agent-connection/daemon-agent-connection.d.ts.map +1 -1
- package/dist/modes/agent-connection/daemon-agent-connection.js +13 -2
- package/dist/modes/agent-connection/daemon-agent-connection.js.map +1 -1
- package/dist/modes/agent-connection/in-process-agent-connection.d.ts +2 -0
- package/dist/modes/agent-connection/in-process-agent-connection.d.ts.map +1 -1
- package/dist/modes/agent-connection/in-process-agent-connection.js +6 -0
- package/dist/modes/agent-connection/in-process-agent-connection.js.map +1 -1
- package/dist/modes/agent-connection/types.d.ts +3 -0
- package/dist/modes/agent-connection/types.d.ts.map +1 -1
- package/dist/modes/agent-connection/types.js.map +1 -1
- package/dist/modes/agents-view/agents-view-mode.d.ts.map +1 -1
- package/dist/modes/agents-view/agents-view-mode.js +2 -19
- package/dist/modes/agents-view/agents-view-mode.js.map +1 -1
- package/dist/modes/daemon/daemon-mode.d.ts +5 -0
- package/dist/modes/daemon/daemon-mode.d.ts.map +1 -1
- package/dist/modes/daemon/daemon-mode.js +107 -12
- package/dist/modes/daemon/daemon-mode.js.map +1 -1
- package/dist/modes/daemon/daemon-protocol.d.ts +194 -165
- package/dist/modes/daemon/daemon-protocol.d.ts.map +1 -1
- package/dist/modes/daemon/daemon-protocol.js +16 -11
- package/dist/modes/daemon/daemon-protocol.js.map +1 -1
- package/dist/modes/daemon/daemon-rlm-capacity-coordinator.d.ts +19 -0
- package/dist/modes/daemon/daemon-rlm-capacity-coordinator.d.ts.map +1 -0
- package/dist/modes/daemon/daemon-rlm-capacity-coordinator.js +74 -0
- package/dist/modes/daemon/daemon-rlm-capacity-coordinator.js.map +1 -0
- package/dist/modes/daemon/daemon-rlm-capacity.d.ts +19 -0
- package/dist/modes/daemon/daemon-rlm-capacity.d.ts.map +1 -0
- package/dist/modes/daemon/daemon-rlm-capacity.js +85 -0
- package/dist/modes/daemon/daemon-rlm-capacity.js.map +1 -0
- package/dist/modes/daemon/daemon-session-summarizer.d.ts +2 -3
- package/dist/modes/daemon/daemon-session-summarizer.d.ts.map +1 -1
- package/dist/modes/daemon/daemon-session-summarizer.js +32 -23
- package/dist/modes/daemon/daemon-session-summarizer.js.map +1 -1
- package/dist/modes/daemon/daemon-state-root.d.ts +15 -0
- package/dist/modes/daemon/daemon-state-root.d.ts.map +1 -0
- package/dist/modes/daemon/daemon-state-root.js +40 -0
- package/dist/modes/daemon/daemon-state-root.js.map +1 -0
- package/dist/modes/daemon/daemon-supervisor-ownership.d.ts +2 -0
- package/dist/modes/daemon/daemon-supervisor-ownership.d.ts.map +1 -1
- package/dist/modes/daemon/daemon-supervisor-ownership.js +27 -0
- package/dist/modes/daemon/daemon-supervisor-ownership.js.map +1 -1
- package/dist/modes/daemon/daemon-supervisor.d.ts +10 -1
- package/dist/modes/daemon/daemon-supervisor.d.ts.map +1 -1
- package/dist/modes/daemon/daemon-supervisor.js +213 -20
- package/dist/modes/daemon/daemon-supervisor.js.map +1 -1
- package/dist/modes/daemon/daemon-worker-protocol.d.ts +28 -1
- package/dist/modes/daemon/daemon-worker-protocol.d.ts.map +1 -1
- package/dist/modes/daemon/daemon-worker-protocol.js +16 -2
- package/dist/modes/daemon/daemon-worker-protocol.js.map +1 -1
- package/dist/modes/daemon/saved-session-catalog.d.ts.map +1 -1
- package/dist/modes/daemon/saved-session-catalog.js +2 -0
- package/dist/modes/daemon/saved-session-catalog.js.map +1 -1
- package/dist/modes/interactive/auth-flows.d.ts +0 -6
- package/dist/modes/interactive/auth-flows.d.ts.map +1 -1
- package/dist/modes/interactive/auth-flows.js +6 -126
- package/dist/modes/interactive/auth-flows.js.map +1 -1
- package/dist/modes/interactive/components/configuration-menu.d.ts +3 -0
- package/dist/modes/interactive/components/configuration-menu.d.ts.map +1 -1
- package/dist/modes/interactive/components/configuration-menu.js +13 -2
- package/dist/modes/interactive/components/configuration-menu.js.map +1 -1
- package/dist/modes/interactive/components/footer.d.ts +1 -1
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +2 -2
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/index.d.ts +0 -1
- package/dist/modes/interactive/components/index.d.ts.map +1 -1
- package/dist/modes/interactive/components/index.js +0 -1
- package/dist/modes/interactive/components/index.js.map +1 -1
- package/dist/modes/interactive/components/login-dialog.d.ts +0 -1
- package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
- package/dist/modes/interactive/components/login-dialog.js +3 -40
- package/dist/modes/interactive/components/login-dialog.js.map +1 -1
- package/dist/modes/interactive/components/model-selector.d.ts +2 -0
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js +13 -2
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/oauth-selector.js +2 -11
- package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
- package/dist/modes/interactive/feature-hints.d.ts.map +1 -1
- package/dist/modes/interactive/feature-hints.js +0 -4
- package/dist/modes/interactive/feature-hints.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +3 -12
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +81 -507
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/onboarding.d.ts +0 -3
- package/dist/modes/interactive/onboarding.d.ts.map +1 -1
- package/dist/modes/interactive/onboarding.js +0 -17
- package/dist/modes/interactive/onboarding.js.map +1 -1
- package/dist/modes/rpc/rpc-client.d.ts +4 -1
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js +82 -42
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/node/amazon-bedrock.d.ts +2 -0
- package/dist/node/amazon-bedrock.d.ts.map +1 -0
- package/dist/node/amazon-bedrock.js +6 -0
- package/dist/node/amazon-bedrock.js.map +1 -0
- package/dist/product-identity.d.ts +0 -1
- package/dist/product-identity.d.ts.map +1 -1
- package/dist/product-identity.js +0 -1
- package/dist/product-identity.js.map +1 -1
- package/docs/development.md +1 -1
- package/docs/fork-philosophy.md +4 -8
- package/docs/installation.md +83 -62
- package/docs/providers.md +23 -25
- package/docs/quickstart.md +19 -10
- package/docs/rlm-runtime.md +13 -5
- package/docs/rpc.md +4 -4
- package/docs/sdk.md +20 -11
- package/docs/sessions.md +0 -1
- package/docs/settings.md +9 -42
- package/docs/skills.md +0 -1
- package/docs/upstream-0.9.5.md +171 -0
- package/docs/usage.md +14 -10
- package/package.json +4 -4
- package/dist/core/agent-traces.d.ts +0 -149
- package/dist/core/agent-traces.d.ts.map +0 -1
- package/dist/core/agent-traces.js +0 -904
- package/dist/core/agent-traces.js.map +0 -1
- package/dist/core/prime-inference-auth.d.ts +0 -70
- package/dist/core/prime-inference-auth.d.ts.map +0 -1
- package/dist/core/prime-inference-auth.js +0 -352
- package/dist/core/prime-inference-auth.js.map +0 -1
- package/dist/core/prime-inference-model-selection.d.ts +0 -16
- package/dist/core/prime-inference-model-selection.d.ts.map +0 -1
- package/dist/core/prime-inference-model-selection.js +0 -16
- package/dist/core/prime-inference-model-selection.js.map +0 -1
- package/dist/core/prime-inference-models.d.ts +0 -6
- package/dist/core/prime-inference-models.d.ts.map +0 -1
- package/dist/core/prime-inference-models.js +0 -62
- package/dist/core/prime-inference-models.js.map +0 -1
- package/dist/core/telemetry.d.ts +0 -95
- package/dist/core/telemetry.d.ts.map +0 -1
- package/dist/core/telemetry.js +0 -637
- package/dist/core/telemetry.js.map +0 -1
- package/dist/modes/interactive/components/prime-onboarding-splash.d.ts +0 -39
- package/dist/modes/interactive/components/prime-onboarding-splash.d.ts.map +0 -1
- package/dist/modes/interactive/components/prime-onboarding-splash.js +0 -286
- package/dist/modes/interactive/components/prime-onboarding-splash.js.map +0 -1
- package/dist/modes/interactive/components/prime-team-selector.d.ts +0 -30
- package/dist/modes/interactive/components/prime-team-selector.d.ts.map +0 -1
- package/dist/modes/interactive/components/prime-team-selector.js +0 -166
- package/dist/modes/interactive/components/prime-team-selector.js.map +0 -1
- package/dist/skills/prime-intellect/SKILL.md +0 -87
- package/dist/skills/prime-intellect/references/compute.md +0 -45
- package/dist/skills/prime-intellect/references/environments.md +0 -73
- package/dist/skills/prime-intellect/references/inference.md +0 -47
- package/dist/skills/prime-intellect/references/sandboxes.md +0 -75
- package/skills/prime-intellect/SKILL.md +0 -87
- package/skills/prime-intellect/references/compute.md +0 -45
- package/skills/prime-intellect/references/environments.md +0 -73
- package/skills/prime-intellect/references/inference.md +0 -47
- package/skills/prime-intellect/references/sandboxes.md +0 -75
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import * as path from "node:path";
|
|
2
|
-
import {
|
|
2
|
+
import { getProviders } from "@ponythewhite/base-context-ai";
|
|
3
3
|
import { getAuthPath, getDocsPath } from "../../config.js";
|
|
4
|
-
import { BASE_CONTEXT_TRACES_PROVIDER_NAME, checkPrimeInferenceAccess, fetchPrimeTeams, loadPrimeCliConfig, PRIME_INFERENCE_PROVIDER_ID, PRIME_INFERENCE_PROVIDER_NAME, } from "../../core/prime-inference-auth.js";
|
|
5
4
|
import { getProviderAuthContract } from "../../core/provider-contracts.js";
|
|
6
5
|
import { BUILT_IN_PROVIDER_DISPLAY_NAMES } from "../../core/provider-display-names.js";
|
|
7
6
|
import { SERPER_CREDENTIAL_ID, SERPER_CREDENTIAL_NAME } from "../../core/websearch-credential.js";
|
|
@@ -9,7 +8,6 @@ import { showFullPaneOverlay } from "./components/centered-overlay.js";
|
|
|
9
8
|
import { ExtensionSelectorComponent } from "./components/extension-selector.js";
|
|
10
9
|
import { LoginDialogComponent } from "./components/login-dialog.js";
|
|
11
10
|
import { compareAuthSelectorProviders, OAuthSelectorComponent, } from "./components/oauth-selector.js";
|
|
12
|
-
import { PrimeTeamSelectorComponent } from "./components/prime-team-selector.js";
|
|
13
11
|
import { theme } from "./theme/theme.js";
|
|
14
12
|
export const BEDROCK_PROVIDER_ID = "amazon-bedrock";
|
|
15
13
|
export const ANTHROPIC_SUBSCRIPTION_AUTH_WARNING = "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.";
|
|
@@ -17,7 +15,7 @@ function isAnthropicSubscriptionAuthKey(apiKey) {
|
|
|
17
15
|
return typeof apiKey === "string" && apiKey.startsWith("sk-ant-oat");
|
|
18
16
|
}
|
|
19
17
|
export async function getAnthropicSubscriptionAuthWarning(modelRegistry, model) {
|
|
20
|
-
if (!model || model.provider !== "anthropic" || getProviderAuthContract(model.provider).oauth !== "
|
|
18
|
+
if (!model || model.provider !== "anthropic" || getProviderAuthContract(model.provider).oauth !== "supported") {
|
|
21
19
|
return undefined;
|
|
22
20
|
}
|
|
23
21
|
const storedCredential = modelRegistry.authStorage.get("anthropic");
|
|
@@ -61,7 +59,7 @@ export class ProviderAuthFlows {
|
|
|
61
59
|
runMcpLogin(server, label) {
|
|
62
60
|
const providerId = `mcp:${server}`;
|
|
63
61
|
const contract = getProviderAuthContract(providerId);
|
|
64
|
-
if (contract.oauth !== "
|
|
62
|
+
if (contract.oauth !== "supported") {
|
|
65
63
|
this.host.showError(contract.guidance);
|
|
66
64
|
return Promise.resolve({ status: "failed" });
|
|
67
65
|
}
|
|
@@ -77,7 +75,7 @@ export class ProviderAuthFlows {
|
|
|
77
75
|
const providerOptions = this.getLoginProviderOptions(authType);
|
|
78
76
|
if (providerOptions.length === 0) {
|
|
79
77
|
this.host.showStatus(authType === "oauth"
|
|
80
|
-
? "
|
|
78
|
+
? "No supported OAuth providers are registered. Use /login to configure an API-key provider."
|
|
81
79
|
: authType === "api_key"
|
|
82
80
|
? "No API key providers available."
|
|
83
81
|
: "No providers available.");
|
|
@@ -104,9 +102,6 @@ export class ProviderAuthFlows {
|
|
|
104
102
|
if (providerOption.authType === "oauth") {
|
|
105
103
|
return this.showLoginDialog(providerOption.id, providerOption.name, kind);
|
|
106
104
|
}
|
|
107
|
-
if (providerOption.id === PRIME_INFERENCE_PROVIDER_ID) {
|
|
108
|
-
return this.runPrimeInferenceLogin();
|
|
109
|
-
}
|
|
110
105
|
if (providerOption.id === BEDROCK_PROVIDER_ID) {
|
|
111
106
|
return this.showBedrockSetupDialog(providerOption.id, providerOption.name);
|
|
112
107
|
}
|
|
@@ -202,16 +197,6 @@ export class ProviderAuthFlows {
|
|
|
202
197
|
category: isSerper || isMcp ? "service" : "provider",
|
|
203
198
|
});
|
|
204
199
|
}
|
|
205
|
-
if (!options.some((option) => option.id === PRIME_INFERENCE_PROVIDER_ID)) {
|
|
206
|
-
const primeInferenceStatus = authStorage.getAuthStatus(PRIME_INFERENCE_PROVIDER_ID);
|
|
207
|
-
if (primeInferenceStatus.source === "prime_cli") {
|
|
208
|
-
options.push({
|
|
209
|
-
id: PRIME_INFERENCE_PROVIDER_ID,
|
|
210
|
-
name: PRIME_INFERENCE_PROVIDER_NAME,
|
|
211
|
-
authType: "api_key",
|
|
212
|
-
});
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
200
|
return options.sort((a, b) => a.name.localeCompare(b.name));
|
|
216
201
|
}
|
|
217
202
|
async completeProviderAuthentication(providerId, providerName, authType, statusSuffix, kind = "provider", credentialPath = getAuthPath()) {
|
|
@@ -274,111 +259,6 @@ export class ProviderAuthFlows {
|
|
|
274
259
|
return { status: "cancelled" };
|
|
275
260
|
}
|
|
276
261
|
}
|
|
277
|
-
showPrimeTeamSelector(teams, currentTeamId) {
|
|
278
|
-
return new Promise((resolve) => {
|
|
279
|
-
let handle;
|
|
280
|
-
const close = () => {
|
|
281
|
-
handle?.hide();
|
|
282
|
-
this.host.ui.requestRender();
|
|
283
|
-
};
|
|
284
|
-
const selector = new PrimeTeamSelectorComponent(teams, currentTeamId, (team) => {
|
|
285
|
-
close();
|
|
286
|
-
resolve(team);
|
|
287
|
-
}, () => {
|
|
288
|
-
close();
|
|
289
|
-
resolve(undefined);
|
|
290
|
-
}, { getRows: () => this.host.ui.terminal.rows });
|
|
291
|
-
handle = showFullPaneOverlay(this.host.ui, selector, 78);
|
|
292
|
-
});
|
|
293
|
-
}
|
|
294
|
-
getPrimeInferenceDefaultTeamStatus() {
|
|
295
|
-
if (getPrimeTeamId()) {
|
|
296
|
-
return "Using team from PRIME_TEAM_ID.";
|
|
297
|
-
}
|
|
298
|
-
const storedTeam = this.host.modelRegistry.authStorage.getPrimeInferenceTeamSelection();
|
|
299
|
-
return storedTeam ? `Using team "${storedTeam.name}".` : "Using personal account.";
|
|
300
|
-
}
|
|
301
|
-
async selectPrimeInferenceTeam(apiKey, dialog) {
|
|
302
|
-
try {
|
|
303
|
-
if (getPrimeTeamId()) {
|
|
304
|
-
this.host.modelRegistry.authStorage.reload();
|
|
305
|
-
return "Using team from PRIME_TEAM_ID.";
|
|
306
|
-
}
|
|
307
|
-
const config = loadPrimeCliConfig(this.host.modelRegistry.authStorage.getPrimeCliConfigPath());
|
|
308
|
-
dialog.showProgress("Loading Prime teams...");
|
|
309
|
-
const teams = await fetchPrimeTeams(apiKey, config.baseUrl, { signal: dialog.signal });
|
|
310
|
-
if (dialog.signal.aborted) {
|
|
311
|
-
return this.getPrimeInferenceDefaultTeamStatus();
|
|
312
|
-
}
|
|
313
|
-
if (teams.length === 0) {
|
|
314
|
-
this.host.modelRegistry.authStorage.setPrimeInferenceTeamSelection(null);
|
|
315
|
-
return "Using personal account.";
|
|
316
|
-
}
|
|
317
|
-
const storedTeam = this.host.modelRegistry.authStorage.getPrimeInferenceTeamSelection();
|
|
318
|
-
const currentTeamId = storedTeam === null ? undefined : (storedTeam?.teamId ?? config.teamId);
|
|
319
|
-
const selectedTeam = await this.showPrimeTeamSelector(teams, currentTeamId);
|
|
320
|
-
if (selectedTeam !== undefined) {
|
|
321
|
-
this.host.modelRegistry.authStorage.setPrimeInferenceTeamSelection(selectedTeam);
|
|
322
|
-
}
|
|
323
|
-
return selectedTeam
|
|
324
|
-
? `Using team "${selectedTeam.name}".`
|
|
325
|
-
: selectedTeam === null
|
|
326
|
-
? "Using personal account."
|
|
327
|
-
: this.getPrimeInferenceDefaultTeamStatus();
|
|
328
|
-
}
|
|
329
|
-
catch {
|
|
330
|
-
this.host.modelRegistry.authStorage.reload();
|
|
331
|
-
return this.getPrimeInferenceDefaultTeamStatus();
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
async completePrimeInferenceLogin(apiKey, dialog, closeDialog) {
|
|
335
|
-
this.host.modelRegistry.authStorage.setPrimeInferenceApiKey(apiKey);
|
|
336
|
-
const teamStatus = await this.selectPrimeInferenceTeam(apiKey, dialog);
|
|
337
|
-
closeDialog();
|
|
338
|
-
return await this.completeProviderAuthentication(PRIME_INFERENCE_PROVIDER_ID, PRIME_INFERENCE_PROVIDER_NAME, "api_key", teamStatus, "provider", this.host.modelRegistry.authStorage.getPrimeCliConfigPath() ?? getAuthPath());
|
|
339
|
-
}
|
|
340
|
-
async runPrimeInferenceLogin() {
|
|
341
|
-
const dialog = new LoginDialogComponent(this.host.ui, PRIME_INFERENCE_PROVIDER_ID, (_success, _message) => { }, PRIME_INFERENCE_PROVIDER_NAME);
|
|
342
|
-
const handle = showFullPaneOverlay(this.host.ui, dialog, {
|
|
343
|
-
maxContentWidth: 88,
|
|
344
|
-
suspendFullscreenMouse: true,
|
|
345
|
-
});
|
|
346
|
-
const closeDialog = () => {
|
|
347
|
-
handle.hide();
|
|
348
|
-
this.host.ui.requestRender();
|
|
349
|
-
};
|
|
350
|
-
try {
|
|
351
|
-
const apiKey = (await dialog.showPrompt("Enter Prime Inference API key:")).trim();
|
|
352
|
-
if (!apiKey) {
|
|
353
|
-
throw new Error("API key cannot be empty.");
|
|
354
|
-
}
|
|
355
|
-
dialog.showProgress("Checking Prime Inference access...");
|
|
356
|
-
const config = loadPrimeCliConfig(this.host.modelRegistry.authStorage.getPrimeCliConfigPath());
|
|
357
|
-
const access = await checkPrimeInferenceAccess(apiKey, config.baseUrl, { signal: dialog.signal });
|
|
358
|
-
if (dialog.signal.aborted) {
|
|
359
|
-
closeDialog();
|
|
360
|
-
return { status: "cancelled" };
|
|
361
|
-
}
|
|
362
|
-
if (!access.ok) {
|
|
363
|
-
const status = access.status === undefined ? "" : `HTTP ${access.status}: `;
|
|
364
|
-
throw new Error(`Prime API key does not have Prime Inference access (${status}${access.message})`);
|
|
365
|
-
}
|
|
366
|
-
return await this.completePrimeInferenceLogin(apiKey, dialog, closeDialog);
|
|
367
|
-
}
|
|
368
|
-
catch (error) {
|
|
369
|
-
closeDialog();
|
|
370
|
-
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
371
|
-
if (!dialog.signal.aborted && errorMsg !== "Login cancelled") {
|
|
372
|
-
this.host.showError(`Failed to login to ${PRIME_INFERENCE_PROVIDER_NAME}: ${errorMsg}`);
|
|
373
|
-
return { status: "failed" };
|
|
374
|
-
}
|
|
375
|
-
return { status: "cancelled" };
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
async runPrimeAgentTracesLogin() {
|
|
379
|
-
this.host.showError(`${BASE_CONTEXT_TRACES_PROVIDER_NAME} login is not configured. Set BASE_CONTEXT_TRACES_BASE_URL and a dedicated BASE_CONTEXT_TRACES_API_KEY; Prime Inference credentials are not used for traces.`);
|
|
380
|
-
return { status: "failed" };
|
|
381
|
-
}
|
|
382
262
|
async showApiKeyLoginDialog(providerId, providerName, kind = "provider") {
|
|
383
263
|
const dialog = new LoginDialogComponent(this.host.ui, providerId, (_success, _message) => { }, providerName);
|
|
384
264
|
const handle = showFullPaneOverlay(this.host.ui, dialog, 88);
|
|
@@ -428,7 +308,7 @@ export class ProviderAuthFlows {
|
|
|
428
308
|
}
|
|
429
309
|
async showLoginDialog(providerId, providerName, kind = "provider") {
|
|
430
310
|
const contract = getProviderAuthContract(providerId);
|
|
431
|
-
if (contract.oauth !== "
|
|
311
|
+
if (contract.oauth !== "supported") {
|
|
432
312
|
this.host.showError(contract.guidance);
|
|
433
313
|
return { status: "failed" };
|
|
434
314
|
}
|
|
@@ -486,7 +366,7 @@ export class ProviderAuthFlows {
|
|
|
486
366
|
signal: dialog.signal,
|
|
487
367
|
});
|
|
488
368
|
closeDialog();
|
|
489
|
-
return await this.completeProviderAuthentication(providerId, providerName, "oauth", undefined, kind);
|
|
369
|
+
return await this.completeProviderAuthentication(providerId, providerName, "oauth", kind === "provider" ? "Use /model to select a model" : undefined, kind);
|
|
490
370
|
}
|
|
491
371
|
catch (error) {
|
|
492
372
|
closeDialog();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-flows.js","sourceRoot":"","sources":["../../../src/modes/interactive/auth-flows.ts"],"names":[],"mappings":"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","sourcesContent":["import * as path from \"node:path\";\nimport {\n\tgetPrimeTeamId,\n\tgetProviders,\n\ttype OAuthProviderId,\n\ttype OAuthSelectPrompt,\n} from \"@ponythewhite/base-context-ai\";\nimport type { OverlayHandle, TUI } from \"@ponythewhite/base-context-tui\";\nimport { getAuthPath, getDocsPath } from \"../../config.js\";\nimport type { ModelRegistry } from \"../../core/model-registry.js\";\nimport {\n\tBASE_CONTEXT_TRACES_PROVIDER_NAME,\n\tcheckPrimeInferenceAccess,\n\tfetchPrimeTeams,\n\tloadPrimeCliConfig,\n\tPRIME_INFERENCE_PROVIDER_ID,\n\tPRIME_INFERENCE_PROVIDER_NAME,\n\ttype PrimeTeam,\n} from \"../../core/prime-inference-auth.js\";\nimport { getProviderAuthContract } from \"../../core/provider-contracts.js\";\nimport { BUILT_IN_PROVIDER_DISPLAY_NAMES } from \"../../core/provider-display-names.js\";\nimport { SERPER_CREDENTIAL_ID, SERPER_CREDENTIAL_NAME } from \"../../core/websearch-credential.js\";\nimport { showFullPaneOverlay } from \"./components/centered-overlay.js\";\nimport { ExtensionSelectorComponent } from \"./components/extension-selector.js\";\nimport { LoginDialogComponent } from \"./components/login-dialog.js\";\nimport {\n\ttype AuthSelectorCategory,\n\ttype AuthSelectorProvider,\n\tcompareAuthSelectorProviders,\n\tOAuthSelectorComponent,\n} from \"./components/oauth-selector.js\";\nimport { PrimeTeamSelectorComponent } from \"./components/prime-team-selector.js\";\nimport { theme } from \"./theme/theme.js\";\n\nexport type AuthenticationResult =\n\t| {\n\t\t\tstatus: \"success\";\n\t\t\tproviderId: string;\n\t\t\tproviderName: string;\n\t\t\tauthType: \"oauth\" | \"api_key\";\n\t\t\t/** \"service\" credentials (e.g. web search) don't affect model selection. */\n\t\t\tkind?: \"provider\" | \"service\";\n\t }\n\t| { status: \"cancelled\" }\n\t| { status: \"failed\" };\n\nexport const BEDROCK_PROVIDER_ID = \"amazon-bedrock\";\n\nexport const ANTHROPIC_SUBSCRIPTION_AUTH_WARNING =\n\t\"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.\";\n\nfunction isAnthropicSubscriptionAuthKey(apiKey: string | undefined): boolean {\n\treturn typeof apiKey === \"string\" && apiKey.startsWith(\"sk-ant-oat\");\n}\n\nexport async function getAnthropicSubscriptionAuthWarning(\n\tmodelRegistry: ModelRegistry,\n\tmodel: { provider: string } | undefined,\n): Promise<string | undefined> {\n\tif (!model || model.provider !== \"anthropic\" || getProviderAuthContract(model.provider).oauth !== \"validated\") {\n\t\treturn undefined;\n\t}\n\n\tconst storedCredential = modelRegistry.authStorage.get(\"anthropic\");\n\tif (storedCredential?.type === \"oauth\") {\n\t\treturn ANTHROPIC_SUBSCRIPTION_AUTH_WARNING;\n\t}\n\n\ttry {\n\t\tconst apiKey = await modelRegistry.getApiKeyForProvider(model.provider);\n\t\tif (isAnthropicSubscriptionAuthKey(apiKey)) {\n\t\t\treturn ANTHROPIC_SUBSCRIPTION_AUTH_WARNING;\n\t\t}\n\t} catch {\n\t\t// Ignore auth lookup failures for warning-only checks.\n\t}\n\treturn undefined;\n}\n\nconst BUILT_IN_MODEL_PROVIDERS = new Set<string>(getProviders());\n\nexport function isApiKeyLoginProvider(\n\tproviderId: string,\n\toauthProviderIds: ReadonlySet<string>,\n\tbuiltInProviderIds: ReadonlySet<string> = BUILT_IN_MODEL_PROVIDERS,\n): boolean {\n\tif (BUILT_IN_PROVIDER_DISPLAY_NAMES[providerId]) {\n\t\treturn true;\n\t}\n\tif (builtInProviderIds.has(providerId)) {\n\t\treturn false;\n\t}\n\treturn !oauthProviderIds.has(providerId);\n}\n\nexport interface ProviderAuthFlowsHost {\n\treadonly ui: TUI;\n\treadonly modelRegistry: ModelRegistry;\n\tshowStatus(message: string): void;\n\tshowError(message: string): void;\n\t/** Models currently visible to the host; used to detect providers configured via external credentials. */\n\tgetAvailableModels(): Promise<ReadonlyArray<{ provider: string }>>;\n\t/** Invoked after stored credentials change so the host can refresh dependent UI. */\n\tonAuthChanged?(): void | Promise<void>;\n\t/** Invoked after a successful login (e.g. to surface billing warnings). */\n\tonLoginCompleted?(): void;\n}\n\nexport interface ProviderLoginOptions {\n\tauthType?: \"oauth\" | \"api_key\";\n\tinitialCategory?: AuthSelectorCategory;\n}\n\n/** Shared auth dialogs: host-specific refresh and billing effects remain outside the flow. */\nexport class ProviderAuthFlows {\n\tconstructor(private readonly host: ProviderAuthFlowsHost) {}\n\n\t/**\n\t * Run the OAuth login flow for an MCP integration server.\n\t *\n\t * The provider must already be registered (the McpManager does this as\n\t * `mcp:<server>`). On success the credentials land in auth.json and the\n\t * caller should reload resources so the integration's skill enables.\n\t */\n\trunMcpLogin(server: string, label?: string): Promise<AuthenticationResult> {\n\t\tconst providerId = `mcp:${server}`;\n\t\tconst contract = getProviderAuthContract(providerId);\n\t\tif (contract.oauth !== \"validated\") {\n\t\t\tthis.host.showError(contract.guidance);\n\t\t\treturn Promise.resolve({ status: \"failed\" });\n\t\t}\n\t\tconst provider = this.host.modelRegistry.authStorage.getOAuthProviders().find((p) => p.id === providerId);\n\t\tif (!provider) {\n\t\t\tthis.host.showError(`Unknown MCP integration: ${server}`);\n\t\t\treturn Promise.resolve({ status: \"failed\" });\n\t\t}\n\t\treturn this.showLoginDialog(providerId, label ?? provider.name, \"service\");\n\t}\n\n\trunLogin(options: ProviderLoginOptions = {}): Promise<AuthenticationResult> {\n\t\tconst { authType, initialCategory } = options;\n\t\tconst providerOptions = this.getLoginProviderOptions(authType);\n\t\tif (providerOptions.length === 0) {\n\t\t\tthis.host.showStatus(\n\t\t\t\tauthType === \"oauth\"\n\t\t\t\t\t? \"Subscription OAuth is unavailable in Base Context until provider client contracts are validated. Use /login API Keys instead.\"\n\t\t\t\t\t: authType === \"api_key\"\n\t\t\t\t\t\t? \"No API key providers available.\"\n\t\t\t\t\t\t: \"No providers available.\",\n\t\t\t);\n\t\t\treturn Promise.resolve({ status: \"failed\" });\n\t\t}\n\n\t\treturn new Promise((resolve) => {\n\t\t\tlet handle: OverlayHandle | undefined;\n\t\t\tconst close = () => {\n\t\t\t\thandle?.hide();\n\t\t\t\tthis.host.ui.requestRender();\n\t\t\t};\n\t\t\tconst selector = new OAuthSelectorComponent(\n\t\t\t\t\"login\",\n\t\t\t\tthis.host.modelRegistry.authStorage,\n\t\t\t\tproviderOptions,\n\t\t\t\tasync (providerOption: AuthSelectorProvider) => {\n\t\t\t\t\tclose();\n\t\t\t\t\tresolve(await this.loginProvider(providerOption));\n\t\t\t\t},\n\t\t\t\t() => {\n\t\t\t\t\tclose();\n\t\t\t\t\tresolve({ status: \"cancelled\" });\n\t\t\t\t},\n\t\t\t\t(providerId) => this.host.modelRegistry.getProviderAuthStatus(providerId),\n\t\t\t\t{ getRows: () => this.host.ui.terminal.rows, initialCategory },\n\t\t\t);\n\t\t\thandle = showFullPaneOverlay(this.host.ui, selector, 78);\n\t\t});\n\t}\n\n\tloginProvider(providerOption: AuthSelectorProvider): Promise<AuthenticationResult> {\n\t\tconst kind = providerOption.category === \"service\" ? \"service\" : \"provider\";\n\t\tif (providerOption.authType === \"oauth\") {\n\t\t\treturn this.showLoginDialog(providerOption.id, providerOption.name, kind);\n\t\t}\n\t\tif (providerOption.id === PRIME_INFERENCE_PROVIDER_ID) {\n\t\t\treturn this.runPrimeInferenceLogin();\n\t\t}\n\t\tif (providerOption.id === BEDROCK_PROVIDER_ID) {\n\t\t\treturn this.showBedrockSetupDialog(providerOption.id, providerOption.name);\n\t\t}\n\t\treturn this.showApiKeyLoginDialog(providerOption.id, providerOption.name, kind);\n\t}\n\n\trunLogout(): Promise<string | null> {\n\t\tconst providerOptions = this.getLogoutProviderOptions();\n\t\tif (providerOptions.length === 0) {\n\t\t\tthis.host.showStatus(\n\t\t\t\t\"No stored credentials to remove. /logout only removes credentials saved by /login; environment variables and models.json config are unchanged.\",\n\t\t\t);\n\t\t\treturn Promise.resolve(null);\n\t\t}\n\n\t\treturn new Promise((resolve) => {\n\t\t\tlet handle: OverlayHandle | undefined;\n\t\t\tconst close = () => {\n\t\t\t\thandle?.hide();\n\t\t\t\tthis.host.ui.requestRender();\n\t\t\t};\n\t\t\tconst selector = new OAuthSelectorComponent(\n\t\t\t\t\"logout\",\n\t\t\t\tthis.host.modelRegistry.authStorage,\n\t\t\t\tproviderOptions,\n\t\t\t\tasync (providerOption: AuthSelectorProvider) => {\n\t\t\t\t\tclose();\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tthis.host.modelRegistry.authStorage.logout(providerOption.id);\n\t\t\t\t\t\tthis.host.modelRegistry.refresh();\n\t\t\t\t\t\tawait this.host.onAuthChanged?.();\n\t\t\t\t\t\tconst message =\n\t\t\t\t\t\t\tproviderOption.authType === \"oauth\"\n\t\t\t\t\t\t\t\t? `Logged out of ${providerOption.name}`\n\t\t\t\t\t\t\t\t: `Removed stored API key for ${providerOption.name}. Environment variables and models.json config are unchanged.`;\n\t\t\t\t\t\tthis.host.showStatus(message);\n\t\t\t\t\t\tresolve(providerOption.id);\n\t\t\t\t\t} catch (error: unknown) {\n\t\t\t\t\t\tthis.host.showError(`Logout failed: ${error instanceof Error ? error.message : String(error)}`);\n\t\t\t\t\t\tresolve(null);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t() => {\n\t\t\t\t\tclose();\n\t\t\t\t\tresolve(null);\n\t\t\t\t},\n\t\t\t\tundefined,\n\t\t\t\t{ getRows: () => this.host.ui.terminal.rows },\n\t\t\t);\n\t\t\thandle = showFullPaneOverlay(this.host.ui, selector, 78);\n\t\t});\n\t}\n\n\tgetLoginProviderOptions(authType?: \"oauth\" | \"api_key\"): AuthSelectorProvider[] {\n\t\tconst authStorage = this.host.modelRegistry.authStorage;\n\t\tconst oauthProviders = authStorage.getOAuthProviders();\n\t\tconst oauthProviderIds = new Set(oauthProviders.map((provider) => provider.id));\n\t\tconst options: AuthSelectorProvider[] = oauthProviders.map((provider) => ({\n\t\t\tid: provider.id,\n\t\t\tname: provider.name,\n\t\t\tauthType: \"oauth\",\n\t\t\t// MCP integrations (mcp:<server>) are services, not model providers.\n\t\t\t...(provider.id.startsWith(\"mcp:\") ? { category: \"service\" as const } : {}),\n\t\t}));\n\n\t\tconst modelProviders = new Set(this.host.modelRegistry.getAll().map((model) => model.provider));\n\t\tfor (const providerId of modelProviders) {\n\t\t\tif (!isApiKeyLoginProvider(providerId, oauthProviderIds)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\toptions.push({\n\t\t\t\tid: providerId,\n\t\t\t\tname: this.host.modelRegistry.getProviderDisplayName(providerId),\n\t\t\t\tauthType: \"api_key\",\n\t\t\t});\n\t\t}\n\n\t\t// Serper is a skill credential, not a model provider, so add it manually.\n\t\toptions.push({\n\t\t\tid: SERPER_CREDENTIAL_ID,\n\t\t\tname: SERPER_CREDENTIAL_NAME,\n\t\t\tauthType: \"api_key\",\n\t\t\tcategory: \"service\",\n\t\t});\n\n\t\tconst filteredOptions = authType ? options.filter((option) => option.authType === authType) : options;\n\t\treturn filteredOptions.sort(compareAuthSelectorProviders);\n\t}\n\n\tprivate getLogoutProviderOptions(): AuthSelectorProvider[] {\n\t\tconst authStorage = this.host.modelRegistry.authStorage;\n\t\tconst options: AuthSelectorProvider[] = [];\n\n\t\tconst oauthProvidersById = new Map(authStorage.getOAuthProviders().map((p) => [p.id, p]));\n\t\tfor (const providerId of authStorage.list()) {\n\t\t\tconst credential = authStorage.get(providerId);\n\t\t\tif (!credential) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst isSerper = providerId === SERPER_CREDENTIAL_ID;\n\t\t\tconst isMcp = providerId.startsWith(\"mcp:\");\n\t\t\tconst name = isSerper\n\t\t\t\t? SERPER_CREDENTIAL_NAME\n\t\t\t\t: isMcp\n\t\t\t\t\t? (oauthProvidersById.get(providerId)?.name ?? providerId.slice(\"mcp:\".length))\n\t\t\t\t\t: this.host.modelRegistry.getProviderDisplayName(providerId);\n\t\t\toptions.push({\n\t\t\t\tid: providerId,\n\t\t\t\tname,\n\t\t\t\tauthType: credential.type,\n\t\t\t\tcategory: isSerper || isMcp ? \"service\" : \"provider\",\n\t\t\t});\n\t\t}\n\n\t\tif (!options.some((option) => option.id === PRIME_INFERENCE_PROVIDER_ID)) {\n\t\t\tconst primeInferenceStatus = authStorage.getAuthStatus(PRIME_INFERENCE_PROVIDER_ID);\n\t\t\tif (primeInferenceStatus.source === \"prime_cli\") {\n\t\t\t\toptions.push({\n\t\t\t\t\tid: PRIME_INFERENCE_PROVIDER_ID,\n\t\t\t\t\tname: PRIME_INFERENCE_PROVIDER_NAME,\n\t\t\t\t\tauthType: \"api_key\",\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\treturn options.sort((a, b) => a.name.localeCompare(b.name));\n\t}\n\n\tprivate async completeProviderAuthentication(\n\t\tproviderId: string,\n\t\tproviderName: string,\n\t\tauthType: \"oauth\" | \"api_key\",\n\t\tstatusSuffix?: string,\n\t\tkind: \"provider\" | \"service\" = \"provider\",\n\t\tcredentialPath: string = getAuthPath(),\n\t): Promise<AuthenticationResult> {\n\t\tthis.host.modelRegistry.refresh();\n\n\t\tconst actionLabel = authType === \"oauth\" ? `Logged in to ${providerName}` : `Saved API key for ${providerName}`;\n\t\tawait this.host.onAuthChanged?.();\n\t\tthis.host.showStatus(\n\t\t\t`${actionLabel}. Credentials saved to ${credentialPath}${statusSuffix ? `. ${statusSuffix}` : \"\"}`,\n\t\t);\n\t\tthis.host.onLoginCompleted?.();\n\t\treturn {\n\t\t\tstatus: \"success\",\n\t\t\tproviderId,\n\t\t\tproviderName,\n\t\t\tauthType,\n\t\t\tkind,\n\t\t};\n\t}\n\n\tprivate async completeExternalProviderSetup(\n\t\tproviderId: string,\n\t\tproviderName: string,\n\t): Promise<AuthenticationResult> {\n\t\tthis.host.modelRegistry.refresh();\n\t\tawait this.host.onAuthChanged?.();\n\t\tthis.host.showStatus(`${providerName} uses external credentials. Select a model after configuring them.`);\n\t\treturn {\n\t\t\tstatus: \"success\",\n\t\t\tproviderId,\n\t\t\tproviderName,\n\t\t\tauthType: \"api_key\",\n\t\t};\n\t}\n\n\tprivate async hasAvailableProviderModels(providerId: string): Promise<boolean> {\n\t\tconst models = await this.host.getAvailableModels();\n\t\treturn models.some((model) => model.provider === providerId);\n\t}\n\n\tprivate async showBedrockSetupDialog(providerId: string, providerName: string): Promise<AuthenticationResult> {\n\t\tconst dialog = new LoginDialogComponent(this.host.ui, providerId, () => {}, providerName, \"Amazon Bedrock setup\");\n\t\tconst handle = showFullPaneOverlay(this.host.ui, dialog, 88);\n\t\tconst closeDialog = () => {\n\t\t\thandle.hide();\n\t\t\tthis.host.ui.requestRender();\n\t\t};\n\n\t\ttry {\n\t\t\tawait dialog.showContinueInfo([\n\t\t\t\ttheme.fg(\"text\", \"Amazon Bedrock uses AWS credentials instead of a single API key.\"),\n\t\t\t\ttheme.fg(\"text\", \"Configure an AWS profile, IAM keys, bearer token, or role-based credentials.\"),\n\t\t\t\ttheme.fg(\"muted\", \"See:\"),\n\t\t\t\ttheme.fg(\"accent\", ` ${path.join(getDocsPath(), \"providers.md\")}`),\n\t\t\t]);\n\t\t\tcloseDialog();\n\t\t\tif (!(await this.hasAvailableProviderModels(providerId))) {\n\t\t\t\tthis.host.showStatus(`${providerName} credentials were not detected. Configure them, then reopen /model.`);\n\t\t\t\treturn { status: \"cancelled\" };\n\t\t\t}\n\t\t\treturn await this.completeExternalProviderSetup(providerId, providerName);\n\t\t} catch (error: unknown) {\n\t\t\tcloseDialog();\n\t\t\tconst errorMsg = error instanceof Error ? error.message : String(error);\n\t\t\tif (errorMsg !== \"Login cancelled\") {\n\t\t\t\tthis.host.showError(`Failed to set up ${providerName}: ${errorMsg}`);\n\t\t\t\treturn { status: \"failed\" };\n\t\t\t}\n\t\t\treturn { status: \"cancelled\" };\n\t\t}\n\t}\n\n\tprivate showPrimeTeamSelector(\n\t\tteams: PrimeTeam[],\n\t\tcurrentTeamId: string | undefined,\n\t): Promise<PrimeTeam | null | undefined> {\n\t\treturn new Promise((resolve) => {\n\t\t\tlet handle: OverlayHandle | undefined;\n\t\t\tconst close = () => {\n\t\t\t\thandle?.hide();\n\t\t\t\tthis.host.ui.requestRender();\n\t\t\t};\n\t\t\tconst selector = new PrimeTeamSelectorComponent(\n\t\t\t\tteams,\n\t\t\t\tcurrentTeamId,\n\t\t\t\t(team) => {\n\t\t\t\t\tclose();\n\t\t\t\t\tresolve(team);\n\t\t\t\t},\n\t\t\t\t() => {\n\t\t\t\t\tclose();\n\t\t\t\t\tresolve(undefined);\n\t\t\t\t},\n\t\t\t\t{ getRows: () => this.host.ui.terminal.rows },\n\t\t\t);\n\t\t\thandle = showFullPaneOverlay(this.host.ui, selector, 78);\n\t\t});\n\t}\n\n\tprivate getPrimeInferenceDefaultTeamStatus(): string {\n\t\tif (getPrimeTeamId()) {\n\t\t\treturn \"Using team from PRIME_TEAM_ID.\";\n\t\t}\n\t\tconst storedTeam = this.host.modelRegistry.authStorage.getPrimeInferenceTeamSelection();\n\t\treturn storedTeam ? `Using team \"${storedTeam.name}\".` : \"Using personal account.\";\n\t}\n\n\tprivate async selectPrimeInferenceTeam(apiKey: string, dialog: LoginDialogComponent): Promise<string | undefined> {\n\t\ttry {\n\t\t\tif (getPrimeTeamId()) {\n\t\t\t\tthis.host.modelRegistry.authStorage.reload();\n\t\t\t\treturn \"Using team from PRIME_TEAM_ID.\";\n\t\t\t}\n\n\t\t\tconst config = loadPrimeCliConfig(this.host.modelRegistry.authStorage.getPrimeCliConfigPath());\n\t\t\tdialog.showProgress(\"Loading Prime teams...\");\n\t\t\tconst teams = await fetchPrimeTeams(apiKey, config.baseUrl, { signal: dialog.signal });\n\t\t\tif (dialog.signal.aborted) {\n\t\t\t\treturn this.getPrimeInferenceDefaultTeamStatus();\n\t\t\t}\n\t\t\tif (teams.length === 0) {\n\t\t\t\tthis.host.modelRegistry.authStorage.setPrimeInferenceTeamSelection(null);\n\t\t\t\treturn \"Using personal account.\";\n\t\t\t}\n\n\t\t\tconst storedTeam = this.host.modelRegistry.authStorage.getPrimeInferenceTeamSelection();\n\t\t\tconst currentTeamId = storedTeam === null ? undefined : (storedTeam?.teamId ?? config.teamId);\n\t\t\tconst selectedTeam = await this.showPrimeTeamSelector(teams, currentTeamId);\n\t\t\tif (selectedTeam !== undefined) {\n\t\t\t\tthis.host.modelRegistry.authStorage.setPrimeInferenceTeamSelection(selectedTeam);\n\t\t\t}\n\t\t\treturn selectedTeam\n\t\t\t\t? `Using team \"${selectedTeam.name}\".`\n\t\t\t\t: selectedTeam === null\n\t\t\t\t\t? \"Using personal account.\"\n\t\t\t\t\t: this.getPrimeInferenceDefaultTeamStatus();\n\t\t} catch {\n\t\t\tthis.host.modelRegistry.authStorage.reload();\n\t\t\treturn this.getPrimeInferenceDefaultTeamStatus();\n\t\t}\n\t}\n\n\tprivate async completePrimeInferenceLogin(\n\t\tapiKey: string,\n\t\tdialog: LoginDialogComponent,\n\t\tcloseDialog: () => void,\n\t): Promise<AuthenticationResult> {\n\t\tthis.host.modelRegistry.authStorage.setPrimeInferenceApiKey(apiKey);\n\t\tconst teamStatus = await this.selectPrimeInferenceTeam(apiKey, dialog);\n\n\t\tcloseDialog();\n\t\treturn await this.completeProviderAuthentication(\n\t\t\tPRIME_INFERENCE_PROVIDER_ID,\n\t\t\tPRIME_INFERENCE_PROVIDER_NAME,\n\t\t\t\"api_key\",\n\t\t\tteamStatus,\n\t\t\t\"provider\",\n\t\t\tthis.host.modelRegistry.authStorage.getPrimeCliConfigPath() ?? getAuthPath(),\n\t\t);\n\t}\n\n\tasync runPrimeInferenceLogin(): Promise<AuthenticationResult> {\n\t\tconst dialog = new LoginDialogComponent(\n\t\t\tthis.host.ui,\n\t\t\tPRIME_INFERENCE_PROVIDER_ID,\n\t\t\t(_success, _message) => {},\n\t\t\tPRIME_INFERENCE_PROVIDER_NAME,\n\t\t);\n\t\tconst handle = showFullPaneOverlay(this.host.ui, dialog, {\n\t\t\tmaxContentWidth: 88,\n\t\t\tsuspendFullscreenMouse: true,\n\t\t});\n\t\tconst closeDialog = () => {\n\t\t\thandle.hide();\n\t\t\tthis.host.ui.requestRender();\n\t\t};\n\n\t\ttry {\n\t\t\tconst apiKey = (await dialog.showPrompt(\"Enter Prime Inference API key:\")).trim();\n\t\t\tif (!apiKey) {\n\t\t\t\tthrow new Error(\"API key cannot be empty.\");\n\t\t\t}\n\t\t\tdialog.showProgress(\"Checking Prime Inference access...\");\n\t\t\tconst config = loadPrimeCliConfig(this.host.modelRegistry.authStorage.getPrimeCliConfigPath());\n\t\t\tconst access = await checkPrimeInferenceAccess(apiKey, config.baseUrl, { signal: dialog.signal });\n\t\t\tif (dialog.signal.aborted) {\n\t\t\t\tcloseDialog();\n\t\t\t\treturn { status: \"cancelled\" };\n\t\t\t}\n\t\t\tif (!access.ok) {\n\t\t\t\tconst status = access.status === undefined ? \"\" : `HTTP ${access.status}: `;\n\t\t\t\tthrow new Error(`Prime API key does not have Prime Inference access (${status}${access.message})`);\n\t\t\t}\n\t\t\treturn await this.completePrimeInferenceLogin(apiKey, dialog, closeDialog);\n\t\t} catch (error: unknown) {\n\t\t\tcloseDialog();\n\t\t\tconst errorMsg = error instanceof Error ? error.message : String(error);\n\t\t\tif (!dialog.signal.aborted && errorMsg !== \"Login cancelled\") {\n\t\t\t\tthis.host.showError(`Failed to login to ${PRIME_INFERENCE_PROVIDER_NAME}: ${errorMsg}`);\n\t\t\t\treturn { status: \"failed\" };\n\t\t\t}\n\t\t\treturn { status: \"cancelled\" };\n\t\t}\n\t}\n\n\tasync runPrimeAgentTracesLogin(): Promise<AuthenticationResult> {\n\t\tthis.host.showError(\n\t\t\t`${BASE_CONTEXT_TRACES_PROVIDER_NAME} login is not configured. Set BASE_CONTEXT_TRACES_BASE_URL and a dedicated BASE_CONTEXT_TRACES_API_KEY; Prime Inference credentials are not used for traces.`,\n\t\t);\n\t\treturn { status: \"failed\" };\n\t}\n\n\tprivate async showApiKeyLoginDialog(\n\t\tproviderId: string,\n\t\tproviderName: string,\n\t\tkind: \"provider\" | \"service\" = \"provider\",\n\t): Promise<AuthenticationResult> {\n\t\tconst dialog = new LoginDialogComponent(this.host.ui, providerId, (_success, _message) => {}, providerName);\n\n\t\tconst handle = showFullPaneOverlay(this.host.ui, dialog, 88);\n\n\t\tconst closeDialog = () => {\n\t\t\thandle.hide();\n\t\t\tthis.host.ui.requestRender();\n\t\t};\n\n\t\ttry {\n\t\t\tconst apiKey = (await dialog.showPrompt(\"Enter API key:\")).trim();\n\t\t\tif (!apiKey) {\n\t\t\t\tthrow new Error(\"API key cannot be empty.\");\n\t\t\t}\n\n\t\t\tthis.host.modelRegistry.authStorage.set(providerId, { type: \"api_key\", key: apiKey });\n\n\t\t\tcloseDialog();\n\t\t\treturn await this.completeProviderAuthentication(providerId, providerName, \"api_key\", undefined, kind);\n\t\t} catch (error: unknown) {\n\t\t\tcloseDialog();\n\t\t\tconst errorMsg = error instanceof Error ? error.message : String(error);\n\t\t\tif (errorMsg !== \"Login cancelled\") {\n\t\t\t\tthis.host.showError(`Failed to save API key for ${providerName}: ${errorMsg}`);\n\t\t\t\treturn { status: \"failed\" };\n\t\t\t}\n\t\t\treturn { status: \"cancelled\" };\n\t\t}\n\t}\n\n\tprivate showOAuthLoginSelect(dialogHandle: OverlayHandle, prompt: OAuthSelectPrompt): Promise<string | undefined> {\n\t\treturn new Promise((resolve) => {\n\t\t\tdialogHandle.setHidden(true);\n\t\t\tlet selectorHandle: OverlayHandle | undefined;\n\t\t\tconst restoreDialog = () => {\n\t\t\t\tselectorHandle?.hide();\n\t\t\t\tdialogHandle.setHidden(false);\n\t\t\t\tdialogHandle.focus();\n\t\t\t\tthis.host.ui.requestRender();\n\t\t\t};\n\t\t\tconst labels = prompt.options.map((option) => option.label);\n\t\t\tconst selector = new ExtensionSelectorComponent(\n\t\t\t\tprompt.message,\n\t\t\t\tlabels,\n\t\t\t\t(optionLabel) => {\n\t\t\t\t\trestoreDialog();\n\t\t\t\t\tresolve(prompt.options.find((option) => option.label === optionLabel)?.id);\n\t\t\t\t},\n\t\t\t\t() => {\n\t\t\t\t\trestoreDialog();\n\t\t\t\t\tresolve(undefined);\n\t\t\t\t},\n\t\t\t\t{ getRows: () => this.host.ui.terminal.rows },\n\t\t\t);\n\t\t\tselectorHandle = showFullPaneOverlay(this.host.ui, selector, 76);\n\t\t});\n\t}\n\n\tprivate async showLoginDialog(\n\t\tproviderId: string,\n\t\tproviderName: string,\n\t\tkind: \"provider\" | \"service\" = \"provider\",\n\t): Promise<AuthenticationResult> {\n\t\tconst contract = getProviderAuthContract(providerId);\n\t\tif (contract.oauth !== \"validated\") {\n\t\t\tthis.host.showError(contract.guidance);\n\t\t\treturn { status: \"failed\" };\n\t\t}\n\t\tconst providerInfo = this.host.modelRegistry.authStorage\n\t\t\t.getOAuthProviders()\n\t\t\t.find((provider) => provider.id === providerId);\n\n\t\tconst usesCallbackServer = providerInfo?.usesCallbackServer ?? false;\n\n\t\tconst dialog = new LoginDialogComponent(this.host.ui, providerId, (_success, _message) => {}, providerName);\n\n\t\tconst dialogHandle = showFullPaneOverlay(this.host.ui, dialog, {\n\t\t\tmaxContentWidth: 88,\n\t\t\tsuspendFullscreenMouse: true,\n\t\t});\n\n\t\tlet manualCodeResolve: ((code: string) => void) | undefined;\n\t\tlet manualCodeReject: ((err: Error) => void) | undefined;\n\t\tconst manualCodePromise = new Promise<string>((resolve, reject) => {\n\t\t\tmanualCodeResolve = resolve;\n\t\t\tmanualCodeReject = reject;\n\t\t});\n\n\t\tconst closeDialog = () => {\n\t\t\tdialogHandle.hide();\n\t\t\tthis.host.ui.requestRender();\n\t\t};\n\n\t\ttry {\n\t\t\tawait this.host.modelRegistry.authStorage.login(providerId as OAuthProviderId, {\n\t\t\t\tonAuth: (info: { url: string; instructions?: string }) => {\n\t\t\t\t\tdialog.showAuth(info.url, info.instructions);\n\n\t\t\t\t\tif (usesCallbackServer) {\n\t\t\t\t\t\tdialog\n\t\t\t\t\t\t\t.showManualInput(\"Paste redirect URL below, or complete login in browser:\")\n\t\t\t\t\t\t\t.then((value) => {\n\t\t\t\t\t\t\t\tif (value && manualCodeResolve) {\n\t\t\t\t\t\t\t\t\tmanualCodeResolve(value);\n\t\t\t\t\t\t\t\t\tmanualCodeResolve = undefined;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t.catch(() => {\n\t\t\t\t\t\t\t\tif (manualCodeReject) {\n\t\t\t\t\t\t\t\t\tmanualCodeReject(new Error(\"Login cancelled\"));\n\t\t\t\t\t\t\t\t\tmanualCodeReject = undefined;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\t\t\t\t\t} else if (providerId === \"github-copilot\") {\n\t\t\t\t\t\tdialog.showWaiting(\"Waiting for browser authentication...\");\n\t\t\t\t\t}\n\t\t\t\t},\n\n\t\t\t\tonPrompt: async (prompt: { message: string; placeholder?: string }) => {\n\t\t\t\t\treturn dialog.showPrompt(prompt.message, prompt.placeholder);\n\t\t\t\t},\n\n\t\t\t\tonProgress: (message: string) => {\n\t\t\t\t\tdialog.showProgress(message);\n\t\t\t\t},\n\n\t\t\t\tonSelect: (prompt: OAuthSelectPrompt) => this.showOAuthLoginSelect(dialogHandle, prompt),\n\n\t\t\t\tonManualCodeInput: () => manualCodePromise,\n\n\t\t\t\tsignal: dialog.signal,\n\t\t\t});\n\n\t\t\tcloseDialog();\n\t\t\treturn await this.completeProviderAuthentication(providerId, providerName, \"oauth\", undefined, kind);\n\t\t} catch (error: unknown) {\n\t\t\tcloseDialog();\n\t\t\tconst errorMsg = error instanceof Error ? error.message : String(error);\n\t\t\tif (errorMsg !== \"Login cancelled\") {\n\t\t\t\tthis.host.showError(`Failed to login to ${providerName}: ${errorMsg}`);\n\t\t\t\treturn { status: \"failed\" };\n\t\t\t}\n\t\t\treturn { status: \"cancelled\" };\n\t\t}\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"auth-flows.js","sourceRoot":"","sources":["../../../src/modes/interactive/auth-flows.ts"],"names":[],"mappings":"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","sourcesContent":["import * as path from \"node:path\";\nimport { getProviders, type OAuthProviderId, type OAuthSelectPrompt } from \"@ponythewhite/base-context-ai\";\nimport type { OverlayHandle, TUI } from \"@ponythewhite/base-context-tui\";\nimport { getAuthPath, getDocsPath } from \"../../config.js\";\nimport type { ModelRegistry } from \"../../core/model-registry.js\";\nimport { getProviderAuthContract } from \"../../core/provider-contracts.js\";\nimport { BUILT_IN_PROVIDER_DISPLAY_NAMES } from \"../../core/provider-display-names.js\";\nimport { SERPER_CREDENTIAL_ID, SERPER_CREDENTIAL_NAME } from \"../../core/websearch-credential.js\";\nimport { showFullPaneOverlay } from \"./components/centered-overlay.js\";\nimport { ExtensionSelectorComponent } from \"./components/extension-selector.js\";\nimport { LoginDialogComponent } from \"./components/login-dialog.js\";\nimport {\n\ttype AuthSelectorCategory,\n\ttype AuthSelectorProvider,\n\tcompareAuthSelectorProviders,\n\tOAuthSelectorComponent,\n} from \"./components/oauth-selector.js\";\nimport { theme } from \"./theme/theme.js\";\n\nexport type AuthenticationResult =\n\t| {\n\t\t\tstatus: \"success\";\n\t\t\tproviderId: string;\n\t\t\tproviderName: string;\n\t\t\tauthType: \"oauth\" | \"api_key\";\n\t\t\t/** \"service\" credentials (e.g. web search) don't affect model selection. */\n\t\t\tkind?: \"provider\" | \"service\";\n\t }\n\t| { status: \"cancelled\" }\n\t| { status: \"failed\" };\n\nexport const BEDROCK_PROVIDER_ID = \"amazon-bedrock\";\n\nexport const ANTHROPIC_SUBSCRIPTION_AUTH_WARNING =\n\t\"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.\";\n\nfunction isAnthropicSubscriptionAuthKey(apiKey: string | undefined): boolean {\n\treturn typeof apiKey === \"string\" && apiKey.startsWith(\"sk-ant-oat\");\n}\n\nexport async function getAnthropicSubscriptionAuthWarning(\n\tmodelRegistry: ModelRegistry,\n\tmodel: { provider: string } | undefined,\n): Promise<string | undefined> {\n\tif (!model || model.provider !== \"anthropic\" || getProviderAuthContract(model.provider).oauth !== \"supported\") {\n\t\treturn undefined;\n\t}\n\n\tconst storedCredential = modelRegistry.authStorage.get(\"anthropic\");\n\tif (storedCredential?.type === \"oauth\") {\n\t\treturn ANTHROPIC_SUBSCRIPTION_AUTH_WARNING;\n\t}\n\n\ttry {\n\t\tconst apiKey = await modelRegistry.getApiKeyForProvider(model.provider);\n\t\tif (isAnthropicSubscriptionAuthKey(apiKey)) {\n\t\t\treturn ANTHROPIC_SUBSCRIPTION_AUTH_WARNING;\n\t\t}\n\t} catch {\n\t\t// Ignore auth lookup failures for warning-only checks.\n\t}\n\treturn undefined;\n}\n\nconst BUILT_IN_MODEL_PROVIDERS = new Set<string>(getProviders());\n\nexport function isApiKeyLoginProvider(\n\tproviderId: string,\n\toauthProviderIds: ReadonlySet<string>,\n\tbuiltInProviderIds: ReadonlySet<string> = BUILT_IN_MODEL_PROVIDERS,\n): boolean {\n\tif (BUILT_IN_PROVIDER_DISPLAY_NAMES[providerId]) {\n\t\treturn true;\n\t}\n\tif (builtInProviderIds.has(providerId)) {\n\t\treturn false;\n\t}\n\treturn !oauthProviderIds.has(providerId);\n}\n\nexport interface ProviderAuthFlowsHost {\n\treadonly ui: TUI;\n\treadonly modelRegistry: ModelRegistry;\n\tshowStatus(message: string): void;\n\tshowError(message: string): void;\n\t/** Models currently visible to the host; used to detect providers configured via external credentials. */\n\tgetAvailableModels(): Promise<ReadonlyArray<{ provider: string }>>;\n\t/** Invoked after stored credentials change so the host can refresh dependent UI. */\n\tonAuthChanged?(): void | Promise<void>;\n\t/** Invoked after a successful login (e.g. to surface billing warnings). */\n\tonLoginCompleted?(): void;\n}\n\nexport interface ProviderLoginOptions {\n\tauthType?: \"oauth\" | \"api_key\";\n\tinitialCategory?: AuthSelectorCategory;\n}\n\n/** Shared auth dialogs: host-specific refresh and billing effects remain outside the flow. */\nexport class ProviderAuthFlows {\n\tconstructor(private readonly host: ProviderAuthFlowsHost) {}\n\n\t/**\n\t * Run the OAuth login flow for an MCP integration server.\n\t *\n\t * The provider must already be registered (the McpManager does this as\n\t * `mcp:<server>`). On success the credentials land in auth.json and the\n\t * caller should reload resources so the integration's skill enables.\n\t */\n\trunMcpLogin(server: string, label?: string): Promise<AuthenticationResult> {\n\t\tconst providerId = `mcp:${server}`;\n\t\tconst contract = getProviderAuthContract(providerId);\n\t\tif (contract.oauth !== \"supported\") {\n\t\t\tthis.host.showError(contract.guidance);\n\t\t\treturn Promise.resolve({ status: \"failed\" });\n\t\t}\n\t\tconst provider = this.host.modelRegistry.authStorage.getOAuthProviders().find((p) => p.id === providerId);\n\t\tif (!provider) {\n\t\t\tthis.host.showError(`Unknown MCP integration: ${server}`);\n\t\t\treturn Promise.resolve({ status: \"failed\" });\n\t\t}\n\t\treturn this.showLoginDialog(providerId, label ?? provider.name, \"service\");\n\t}\n\n\trunLogin(options: ProviderLoginOptions = {}): Promise<AuthenticationResult> {\n\t\tconst { authType, initialCategory } = options;\n\t\tconst providerOptions = this.getLoginProviderOptions(authType);\n\t\tif (providerOptions.length === 0) {\n\t\t\tthis.host.showStatus(\n\t\t\t\tauthType === \"oauth\"\n\t\t\t\t\t? \"No supported OAuth providers are registered. Use /login to configure an API-key provider.\"\n\t\t\t\t\t: authType === \"api_key\"\n\t\t\t\t\t\t? \"No API key providers available.\"\n\t\t\t\t\t\t: \"No providers available.\",\n\t\t\t);\n\t\t\treturn Promise.resolve({ status: \"failed\" });\n\t\t}\n\n\t\treturn new Promise((resolve) => {\n\t\t\tlet handle: OverlayHandle | undefined;\n\t\t\tconst close = () => {\n\t\t\t\thandle?.hide();\n\t\t\t\tthis.host.ui.requestRender();\n\t\t\t};\n\t\t\tconst selector = new OAuthSelectorComponent(\n\t\t\t\t\"login\",\n\t\t\t\tthis.host.modelRegistry.authStorage,\n\t\t\t\tproviderOptions,\n\t\t\t\tasync (providerOption: AuthSelectorProvider) => {\n\t\t\t\t\tclose();\n\t\t\t\t\tresolve(await this.loginProvider(providerOption));\n\t\t\t\t},\n\t\t\t\t() => {\n\t\t\t\t\tclose();\n\t\t\t\t\tresolve({ status: \"cancelled\" });\n\t\t\t\t},\n\t\t\t\t(providerId) => this.host.modelRegistry.getProviderAuthStatus(providerId),\n\t\t\t\t{ getRows: () => this.host.ui.terminal.rows, initialCategory },\n\t\t\t);\n\t\t\thandle = showFullPaneOverlay(this.host.ui, selector, 78);\n\t\t});\n\t}\n\n\tloginProvider(providerOption: AuthSelectorProvider): Promise<AuthenticationResult> {\n\t\tconst kind = providerOption.category === \"service\" ? \"service\" : \"provider\";\n\t\tif (providerOption.authType === \"oauth\") {\n\t\t\treturn this.showLoginDialog(providerOption.id, providerOption.name, kind);\n\t\t}\n\t\tif (providerOption.id === BEDROCK_PROVIDER_ID) {\n\t\t\treturn this.showBedrockSetupDialog(providerOption.id, providerOption.name);\n\t\t}\n\t\treturn this.showApiKeyLoginDialog(providerOption.id, providerOption.name, kind);\n\t}\n\n\trunLogout(): Promise<string | null> {\n\t\tconst providerOptions = this.getLogoutProviderOptions();\n\t\tif (providerOptions.length === 0) {\n\t\t\tthis.host.showStatus(\n\t\t\t\t\"No stored credentials to remove. /logout only removes credentials saved by /login; environment variables and models.json config are unchanged.\",\n\t\t\t);\n\t\t\treturn Promise.resolve(null);\n\t\t}\n\n\t\treturn new Promise((resolve) => {\n\t\t\tlet handle: OverlayHandle | undefined;\n\t\t\tconst close = () => {\n\t\t\t\thandle?.hide();\n\t\t\t\tthis.host.ui.requestRender();\n\t\t\t};\n\t\t\tconst selector = new OAuthSelectorComponent(\n\t\t\t\t\"logout\",\n\t\t\t\tthis.host.modelRegistry.authStorage,\n\t\t\t\tproviderOptions,\n\t\t\t\tasync (providerOption: AuthSelectorProvider) => {\n\t\t\t\t\tclose();\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tthis.host.modelRegistry.authStorage.logout(providerOption.id);\n\t\t\t\t\t\tthis.host.modelRegistry.refresh();\n\t\t\t\t\t\tawait this.host.onAuthChanged?.();\n\t\t\t\t\t\tconst message =\n\t\t\t\t\t\t\tproviderOption.authType === \"oauth\"\n\t\t\t\t\t\t\t\t? `Logged out of ${providerOption.name}`\n\t\t\t\t\t\t\t\t: `Removed stored API key for ${providerOption.name}. Environment variables and models.json config are unchanged.`;\n\t\t\t\t\t\tthis.host.showStatus(message);\n\t\t\t\t\t\tresolve(providerOption.id);\n\t\t\t\t\t} catch (error: unknown) {\n\t\t\t\t\t\tthis.host.showError(`Logout failed: ${error instanceof Error ? error.message : String(error)}`);\n\t\t\t\t\t\tresolve(null);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t() => {\n\t\t\t\t\tclose();\n\t\t\t\t\tresolve(null);\n\t\t\t\t},\n\t\t\t\tundefined,\n\t\t\t\t{ getRows: () => this.host.ui.terminal.rows },\n\t\t\t);\n\t\t\thandle = showFullPaneOverlay(this.host.ui, selector, 78);\n\t\t});\n\t}\n\n\tgetLoginProviderOptions(authType?: \"oauth\" | \"api_key\"): AuthSelectorProvider[] {\n\t\tconst authStorage = this.host.modelRegistry.authStorage;\n\t\tconst oauthProviders = authStorage.getOAuthProviders();\n\t\tconst oauthProviderIds = new Set(oauthProviders.map((provider) => provider.id));\n\t\tconst options: AuthSelectorProvider[] = oauthProviders.map((provider) => ({\n\t\t\tid: provider.id,\n\t\t\tname: provider.name,\n\t\t\tauthType: \"oauth\",\n\t\t\t// MCP integrations (mcp:<server>) are services, not model providers.\n\t\t\t...(provider.id.startsWith(\"mcp:\") ? { category: \"service\" as const } : {}),\n\t\t}));\n\n\t\tconst modelProviders = new Set(this.host.modelRegistry.getAll().map((model) => model.provider));\n\t\tfor (const providerId of modelProviders) {\n\t\t\tif (!isApiKeyLoginProvider(providerId, oauthProviderIds)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\toptions.push({\n\t\t\t\tid: providerId,\n\t\t\t\tname: this.host.modelRegistry.getProviderDisplayName(providerId),\n\t\t\t\tauthType: \"api_key\",\n\t\t\t});\n\t\t}\n\n\t\t// Serper is a skill credential, not a model provider, so add it manually.\n\t\toptions.push({\n\t\t\tid: SERPER_CREDENTIAL_ID,\n\t\t\tname: SERPER_CREDENTIAL_NAME,\n\t\t\tauthType: \"api_key\",\n\t\t\tcategory: \"service\",\n\t\t});\n\n\t\tconst filteredOptions = authType ? options.filter((option) => option.authType === authType) : options;\n\t\treturn filteredOptions.sort(compareAuthSelectorProviders);\n\t}\n\n\tprivate getLogoutProviderOptions(): AuthSelectorProvider[] {\n\t\tconst authStorage = this.host.modelRegistry.authStorage;\n\t\tconst options: AuthSelectorProvider[] = [];\n\n\t\tconst oauthProvidersById = new Map(authStorage.getOAuthProviders().map((p) => [p.id, p]));\n\t\tfor (const providerId of authStorage.list()) {\n\t\t\tconst credential = authStorage.get(providerId);\n\t\t\tif (!credential) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst isSerper = providerId === SERPER_CREDENTIAL_ID;\n\t\t\tconst isMcp = providerId.startsWith(\"mcp:\");\n\t\t\tconst name = isSerper\n\t\t\t\t? SERPER_CREDENTIAL_NAME\n\t\t\t\t: isMcp\n\t\t\t\t\t? (oauthProvidersById.get(providerId)?.name ?? providerId.slice(\"mcp:\".length))\n\t\t\t\t\t: this.host.modelRegistry.getProviderDisplayName(providerId);\n\t\t\toptions.push({\n\t\t\t\tid: providerId,\n\t\t\t\tname,\n\t\t\t\tauthType: credential.type,\n\t\t\t\tcategory: isSerper || isMcp ? \"service\" : \"provider\",\n\t\t\t});\n\t\t}\n\n\t\treturn options.sort((a, b) => a.name.localeCompare(b.name));\n\t}\n\n\tprivate async completeProviderAuthentication(\n\t\tproviderId: string,\n\t\tproviderName: string,\n\t\tauthType: \"oauth\" | \"api_key\",\n\t\tstatusSuffix?: string,\n\t\tkind: \"provider\" | \"service\" = \"provider\",\n\t\tcredentialPath: string = getAuthPath(),\n\t): Promise<AuthenticationResult> {\n\t\tthis.host.modelRegistry.refresh();\n\n\t\tconst actionLabel = authType === \"oauth\" ? `Logged in to ${providerName}` : `Saved API key for ${providerName}`;\n\t\tawait this.host.onAuthChanged?.();\n\t\tthis.host.showStatus(\n\t\t\t`${actionLabel}. Credentials saved to ${credentialPath}${statusSuffix ? `. ${statusSuffix}` : \"\"}`,\n\t\t);\n\t\tthis.host.onLoginCompleted?.();\n\t\treturn {\n\t\t\tstatus: \"success\",\n\t\t\tproviderId,\n\t\t\tproviderName,\n\t\t\tauthType,\n\t\t\tkind,\n\t\t};\n\t}\n\n\tprivate async completeExternalProviderSetup(\n\t\tproviderId: string,\n\t\tproviderName: string,\n\t): Promise<AuthenticationResult> {\n\t\tthis.host.modelRegistry.refresh();\n\t\tawait this.host.onAuthChanged?.();\n\t\tthis.host.showStatus(`${providerName} uses external credentials. Select a model after configuring them.`);\n\t\treturn {\n\t\t\tstatus: \"success\",\n\t\t\tproviderId,\n\t\t\tproviderName,\n\t\t\tauthType: \"api_key\",\n\t\t};\n\t}\n\n\tprivate async hasAvailableProviderModels(providerId: string): Promise<boolean> {\n\t\tconst models = await this.host.getAvailableModels();\n\t\treturn models.some((model) => model.provider === providerId);\n\t}\n\n\tprivate async showBedrockSetupDialog(providerId: string, providerName: string): Promise<AuthenticationResult> {\n\t\tconst dialog = new LoginDialogComponent(this.host.ui, providerId, () => {}, providerName, \"Amazon Bedrock setup\");\n\t\tconst handle = showFullPaneOverlay(this.host.ui, dialog, 88);\n\t\tconst closeDialog = () => {\n\t\t\thandle.hide();\n\t\t\tthis.host.ui.requestRender();\n\t\t};\n\n\t\ttry {\n\t\t\tawait dialog.showContinueInfo([\n\t\t\t\ttheme.fg(\"text\", \"Amazon Bedrock uses AWS credentials instead of a single API key.\"),\n\t\t\t\ttheme.fg(\"text\", \"Configure an AWS profile, IAM keys, bearer token, or role-based credentials.\"),\n\t\t\t\ttheme.fg(\"muted\", \"See:\"),\n\t\t\t\ttheme.fg(\"accent\", ` ${path.join(getDocsPath(), \"providers.md\")}`),\n\t\t\t]);\n\t\t\tcloseDialog();\n\t\t\tif (!(await this.hasAvailableProviderModels(providerId))) {\n\t\t\t\tthis.host.showStatus(`${providerName} credentials were not detected. Configure them, then reopen /model.`);\n\t\t\t\treturn { status: \"cancelled\" };\n\t\t\t}\n\t\t\treturn await this.completeExternalProviderSetup(providerId, providerName);\n\t\t} catch (error: unknown) {\n\t\t\tcloseDialog();\n\t\t\tconst errorMsg = error instanceof Error ? error.message : String(error);\n\t\t\tif (errorMsg !== \"Login cancelled\") {\n\t\t\t\tthis.host.showError(`Failed to set up ${providerName}: ${errorMsg}`);\n\t\t\t\treturn { status: \"failed\" };\n\t\t\t}\n\t\t\treturn { status: \"cancelled\" };\n\t\t}\n\t}\n\n\tprivate async showApiKeyLoginDialog(\n\t\tproviderId: string,\n\t\tproviderName: string,\n\t\tkind: \"provider\" | \"service\" = \"provider\",\n\t): Promise<AuthenticationResult> {\n\t\tconst dialog = new LoginDialogComponent(this.host.ui, providerId, (_success, _message) => {}, providerName);\n\n\t\tconst handle = showFullPaneOverlay(this.host.ui, dialog, 88);\n\n\t\tconst closeDialog = () => {\n\t\t\thandle.hide();\n\t\t\tthis.host.ui.requestRender();\n\t\t};\n\n\t\ttry {\n\t\t\tconst apiKey = (await dialog.showPrompt(\"Enter API key:\")).trim();\n\t\t\tif (!apiKey) {\n\t\t\t\tthrow new Error(\"API key cannot be empty.\");\n\t\t\t}\n\n\t\t\tthis.host.modelRegistry.authStorage.set(providerId, { type: \"api_key\", key: apiKey });\n\n\t\t\tcloseDialog();\n\t\t\treturn await this.completeProviderAuthentication(providerId, providerName, \"api_key\", undefined, kind);\n\t\t} catch (error: unknown) {\n\t\t\tcloseDialog();\n\t\t\tconst errorMsg = error instanceof Error ? error.message : String(error);\n\t\t\tif (errorMsg !== \"Login cancelled\") {\n\t\t\t\tthis.host.showError(`Failed to save API key for ${providerName}: ${errorMsg}`);\n\t\t\t\treturn { status: \"failed\" };\n\t\t\t}\n\t\t\treturn { status: \"cancelled\" };\n\t\t}\n\t}\n\n\tprivate showOAuthLoginSelect(dialogHandle: OverlayHandle, prompt: OAuthSelectPrompt): Promise<string | undefined> {\n\t\treturn new Promise((resolve) => {\n\t\t\tdialogHandle.setHidden(true);\n\t\t\tlet selectorHandle: OverlayHandle | undefined;\n\t\t\tconst restoreDialog = () => {\n\t\t\t\tselectorHandle?.hide();\n\t\t\t\tdialogHandle.setHidden(false);\n\t\t\t\tdialogHandle.focus();\n\t\t\t\tthis.host.ui.requestRender();\n\t\t\t};\n\t\t\tconst labels = prompt.options.map((option) => option.label);\n\t\t\tconst selector = new ExtensionSelectorComponent(\n\t\t\t\tprompt.message,\n\t\t\t\tlabels,\n\t\t\t\t(optionLabel) => {\n\t\t\t\t\trestoreDialog();\n\t\t\t\t\tresolve(prompt.options.find((option) => option.label === optionLabel)?.id);\n\t\t\t\t},\n\t\t\t\t() => {\n\t\t\t\t\trestoreDialog();\n\t\t\t\t\tresolve(undefined);\n\t\t\t\t},\n\t\t\t\t{ getRows: () => this.host.ui.terminal.rows },\n\t\t\t);\n\t\t\tselectorHandle = showFullPaneOverlay(this.host.ui, selector, 76);\n\t\t});\n\t}\n\n\tprivate async showLoginDialog(\n\t\tproviderId: string,\n\t\tproviderName: string,\n\t\tkind: \"provider\" | \"service\" = \"provider\",\n\t): Promise<AuthenticationResult> {\n\t\tconst contract = getProviderAuthContract(providerId);\n\t\tif (contract.oauth !== \"supported\") {\n\t\t\tthis.host.showError(contract.guidance);\n\t\t\treturn { status: \"failed\" };\n\t\t}\n\t\tconst providerInfo = this.host.modelRegistry.authStorage\n\t\t\t.getOAuthProviders()\n\t\t\t.find((provider) => provider.id === providerId);\n\n\t\tconst usesCallbackServer = providerInfo?.usesCallbackServer ?? false;\n\n\t\tconst dialog = new LoginDialogComponent(this.host.ui, providerId, (_success, _message) => {}, providerName);\n\n\t\tconst dialogHandle = showFullPaneOverlay(this.host.ui, dialog, {\n\t\t\tmaxContentWidth: 88,\n\t\t\tsuspendFullscreenMouse: true,\n\t\t});\n\n\t\tlet manualCodeResolve: ((code: string) => void) | undefined;\n\t\tlet manualCodeReject: ((err: Error) => void) | undefined;\n\t\tconst manualCodePromise = new Promise<string>((resolve, reject) => {\n\t\t\tmanualCodeResolve = resolve;\n\t\t\tmanualCodeReject = reject;\n\t\t});\n\n\t\tconst closeDialog = () => {\n\t\t\tdialogHandle.hide();\n\t\t\tthis.host.ui.requestRender();\n\t\t};\n\n\t\ttry {\n\t\t\tawait this.host.modelRegistry.authStorage.login(providerId as OAuthProviderId, {\n\t\t\t\tonAuth: (info: { url: string; instructions?: string }) => {\n\t\t\t\t\tdialog.showAuth(info.url, info.instructions);\n\n\t\t\t\t\tif (usesCallbackServer) {\n\t\t\t\t\t\tdialog\n\t\t\t\t\t\t\t.showManualInput(\"Paste redirect URL below, or complete login in browser:\")\n\t\t\t\t\t\t\t.then((value) => {\n\t\t\t\t\t\t\t\tif (value && manualCodeResolve) {\n\t\t\t\t\t\t\t\t\tmanualCodeResolve(value);\n\t\t\t\t\t\t\t\t\tmanualCodeResolve = undefined;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t.catch(() => {\n\t\t\t\t\t\t\t\tif (manualCodeReject) {\n\t\t\t\t\t\t\t\t\tmanualCodeReject(new Error(\"Login cancelled\"));\n\t\t\t\t\t\t\t\t\tmanualCodeReject = undefined;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\t\t\t\t\t} else if (providerId === \"github-copilot\") {\n\t\t\t\t\t\tdialog.showWaiting(\"Waiting for browser authentication...\");\n\t\t\t\t\t}\n\t\t\t\t},\n\n\t\t\t\tonPrompt: async (prompt: { message: string; placeholder?: string }) => {\n\t\t\t\t\treturn dialog.showPrompt(prompt.message, prompt.placeholder);\n\t\t\t\t},\n\n\t\t\t\tonProgress: (message: string) => {\n\t\t\t\t\tdialog.showProgress(message);\n\t\t\t\t},\n\n\t\t\t\tonSelect: (prompt: OAuthSelectPrompt) => this.showOAuthLoginSelect(dialogHandle, prompt),\n\n\t\t\t\tonManualCodeInput: () => manualCodePromise,\n\n\t\t\t\tsignal: dialog.signal,\n\t\t\t});\n\n\t\t\tcloseDialog();\n\t\t\treturn await this.completeProviderAuthentication(\n\t\t\t\tproviderId,\n\t\t\t\tproviderName,\n\t\t\t\t\"oauth\",\n\t\t\t\tkind === \"provider\" ? \"Use /model to select a model\" : undefined,\n\t\t\t\tkind,\n\t\t\t);\n\t\t} catch (error: unknown) {\n\t\t\tcloseDialog();\n\t\t\tconst errorMsg = error instanceof Error ? error.message : String(error);\n\t\t\tif (errorMsg !== \"Login cancelled\") {\n\t\t\t\tthis.host.showError(`Failed to login to ${providerName}: ${errorMsg}`);\n\t\t\t\treturn { status: \"failed\" };\n\t\t\t}\n\t\t\treturn { status: \"cancelled\" };\n\t\t}\n\t}\n}\n"]}
|
|
@@ -11,6 +11,7 @@ export interface ConfigurationMenuScopedModel {
|
|
|
11
11
|
}
|
|
12
12
|
export interface ConfigurationMenuOptions {
|
|
13
13
|
initialTab: ConfigurationMenuTab;
|
|
14
|
+
providerFirst?: boolean;
|
|
14
15
|
tui: TUI;
|
|
15
16
|
authStorage: AuthStorage;
|
|
16
17
|
providerOptions: ReadonlyArray<AuthSelectorProvider>;
|
|
@@ -32,6 +33,7 @@ export declare class ConfigurationMenuComponent extends Container implements Foc
|
|
|
32
33
|
private readonly options;
|
|
33
34
|
private readonly bodies;
|
|
34
35
|
private activeTab;
|
|
36
|
+
private selectedProvider?;
|
|
35
37
|
private _focused;
|
|
36
38
|
private renderWidth;
|
|
37
39
|
constructor(options: ConfigurationMenuOptions);
|
|
@@ -40,6 +42,7 @@ export declare class ConfigurationMenuComponent extends Container implements Foc
|
|
|
40
42
|
render(width: number): string[];
|
|
41
43
|
getActiveTab(): ConfigurationMenuTab;
|
|
42
44
|
getSearchValue(tab?: ConfigurationMenuTab): string;
|
|
45
|
+
showProviderModels(providerId: string): void;
|
|
43
46
|
setActiveTab(tab: ConfigurationMenuTab): void;
|
|
44
47
|
refreshAuthentication(): void;
|
|
45
48
|
updateModels(currentModel: Model<Api> | undefined, models?: ReadonlyArray<Model<Api>>, configuredProviders?: ReadonlySet<string>): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"configuration-menu.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/configuration-menu.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,EAEN,SAAS,EACT,KAAK,SAAS,EAEd,KAAK,GAAG,EAGR,MAAM,gCAAgC,CAAC;AACxC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAKrE,OAAO,EAAE,KAAK,oBAAoB,EAA0B,MAAM,qBAAqB,CAAC;AAExF,eAAO,MAAM,uBAAuB,qDAAsD,CAAC;AAE3F,MAAM,MAAM,oBAAoB,GAAG,CAAC,OAAO,uBAAuB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE5E,MAAM,WAAW,4BAA4B;IAC5C,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,wBAAwB;IACxC,UAAU,EAAE,oBAAoB,CAAC;IACjC,GAAG,EAAE,GAAG,CAAC;IACT,WAAW,EAAE,WAAW,CAAC;IACzB,eAAe,EAAE,aAAa,CAAC,oBAAoB,CAAC,CAAC;IACrD,aAAa,EAAE,aAAa,CAAC;IAC7B,YAAY,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC;IACrC,YAAY,EAAE,aAAa,CAAC,4BAA4B,CAAC,CAAC;IAC1D,eAAe,EAAE,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3C,mBAAmB,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACzC,YAAY,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACrC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B,gBAAgB,EAAE,CAAC,QAAQ,EAAE,oBAAoB,KAAK,IAAI,CAAC;IAC3D,qBAAqB,EAAE,CAAC,QAAQ,EAAE,oBAAoB,KAAK,IAAI,CAAC;IAChE,aAAa,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC;IAC3C,QAAQ,EAAE,MAAM,IAAI,CAAC;CACrB;AA2DD,qBAAa,0BAA2B,SAAQ,SAAU,YAAW,SAAS;IAUjE,OAAO,CAAC,QAAQ,CAAC,OAAO;IATpC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAIrB;IACF,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,WAAW,CAAM;IAEzB,YAA6B,OAAO,EAAE,wBAAwB,EAkE7D;IAED,IAAI,OAAO,IAAI,OAAO,CAErB;IAED,IAAI,OAAO,CAAC,KAAK,EAAE,OAAO,EAGzB;IAEQ,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAGvC;IAED,YAAY,IAAI,oBAAoB,CAEnC;IAED,cAAc,CAAC,GAAG,GAAE,oBAAqC,GAAG,MAAM,CAEjE;IAED,YAAY,CAAC,GAAG,EAAE,oBAAoB,GAAG,IAAI,CAQ5C;IAED,qBAAqB,IAAI,IAAI,CAI5B;IAED,YAAY,CACX,YAAY,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,SAAS,EACpC,MAAM,CAAC,EAAE,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAClC,mBAAmB,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,GACvC,IAAI,CAEN;IAED,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAkBjC;IAED,OAAO,KAAK,UAAU,GAErB;IAED,OAAO,CAAC,SAAS;CAKjB","sourcesContent":["import type { Api, Model } from \"@ponythewhite/base-context-ai\";\nimport {\n\ttype Component,\n\tContainer,\n\ttype Focusable,\n\tgetKeybindings,\n\ttype TUI,\n\tvisibleWidth,\n\twrapTextWithAnsi,\n} from \"@ponythewhite/base-context-tui\";\nimport type { AuthStorage } from \"../../../core/auth-storage.js\";\nimport type { ModelRegistry } from \"../../../core/model-registry.js\";\nimport { theme } from \"../theme/theme.js\";\nimport { keyText } from \"./keybinding-hints.js\";\nimport { getMenuPanelInnerWidth } from \"./menu-panel.js\";\nimport { ModelSelectorComponent } from \"./model-selector.js\";\nimport { type AuthSelectorProvider, OAuthSelectorComponent } from \"./oauth-selector.js\";\n\nexport const CONFIGURATION_MENU_TABS = [\"providers\", \"models\", \"mcp-connections\"] as const;\n\nexport type ConfigurationMenuTab = (typeof CONFIGURATION_MENU_TABS)[number];\n\nexport interface ConfigurationMenuScopedModel {\n\tmodel: Model<Api>;\n\tthinkingLevel?: string;\n}\n\nexport interface ConfigurationMenuOptions {\n\tinitialTab: ConfigurationMenuTab;\n\ttui: TUI;\n\tauthStorage: AuthStorage;\n\tproviderOptions: ReadonlyArray<AuthSelectorProvider>;\n\tmodelRegistry: ModelRegistry;\n\tcurrentModel: Model<Api> | undefined;\n\tscopedModels: ReadonlyArray<ConfigurationMenuScopedModel>;\n\tavailableModels: ReadonlyArray<Model<Api>>;\n\tconfiguredProviders: ReadonlySet<string>;\n\trecentModels?: ReadonlyArray<string>;\n\tinitialModelSearch?: string;\n\tgetRows?: () => number;\n\trequestRender: () => void;\n\tonSelectProvider: (provider: AuthSelectorProvider) => void;\n\tonSelectMcpConnection: (provider: AuthSelectorProvider) => void;\n\tonSelectModel: (model: Model<Api>) => void;\n\tonCancel: () => void;\n}\n\nconst TAB_LABELS: Record<ConfigurationMenuTab, string> = {\n\tproviders: \"Providers\",\n\tmodels: \"Models\",\n\t\"mcp-connections\": \"MCP Connections\",\n};\n\nclass ConfigurationMenuTabBar implements Component {\n\tconstructor(private readonly getActiveTab: () => ConfigurationMenuTab) {}\n\n\trender(width: number): string[] {\n\t\treturn this.getLines(width);\n\t}\n\n\tgetRowCount(width: number): number {\n\t\treturn this.getLines(width).length;\n\t}\n\n\tprivate getLines(width: number): string[] {\n\t\tconst safeWidth = Math.max(1, width);\n\t\tconst activeTab = this.getActiveTab();\n\t\tconst labels = CONFIGURATION_MENU_TABS.map((tab) => {\n\t\t\tconst label = `[${tab === activeTab ? \"▶\" : \" \"} ${TAB_LABELS[tab]}]`;\n\t\t\treturn tab === activeTab ? theme.bold(theme.fg(\"accent\", label)) : theme.fg(\"text\", label);\n\t\t});\n\t\tconst lines = this.wrapItems(\n\t\t\t[theme.bold(theme.fg(\"muted\", \"Tabs:\")), ...labels],\n\t\t\ttheme.fg(\"muted\", \" \"),\n\t\t\tsafeWidth,\n\t\t);\n\t\tconst tabKey = keyText(\"tui.input.tab\", { primaryOnly: true });\n\t\tconst shiftTabKey = keyText(\"app.configuration.previousTab\", { primaryOnly: true });\n\t\tconst closeKey = keyText(\"tui.select.cancel\", { primaryOnly: true });\n\t\tconst hint = `${theme.fg(\"dim\", `${tabKey}/${shiftTabKey}`)}${theme.fg(\"muted\", \" switch tabs · \")}${theme.fg(\"dim\", closeKey)}${theme.fg(\"muted\", \" close\")}`;\n\t\treturn [...lines, ...wrapTextWithAnsi(hint, safeWidth)];\n\t}\n\n\tprivate wrapItems(items: string[], separator: string, width: number): string[] {\n\t\tconst lines: string[] = [];\n\t\tlet line = \"\";\n\t\tfor (const item of items) {\n\t\t\tconst candidate = line ? `${line}${separator}${item}` : item;\n\t\t\tif (line && visibleWidth(candidate) > width) {\n\t\t\t\tlines.push(...wrapTextWithAnsi(line, width));\n\t\t\t\tline = item;\n\t\t\t} else {\n\t\t\t\tline = candidate;\n\t\t\t}\n\t\t}\n\t\tif (line) {\n\t\t\tlines.push(...wrapTextWithAnsi(line, width));\n\t\t}\n\t\treturn lines;\n\t}\n\n\tinvalidate(): void {}\n}\n\nexport class ConfigurationMenuComponent extends Container implements Focusable {\n\tprivate readonly bodies: {\n\t\tproviders: OAuthSelectorComponent;\n\t\tmodels: ModelSelectorComponent;\n\t\t\"mcp-connections\": OAuthSelectorComponent;\n\t};\n\tprivate activeTab: ConfigurationMenuTab;\n\tprivate _focused = false;\n\tprivate renderWidth = 78;\n\n\tconstructor(private readonly options: ConfigurationMenuOptions) {\n\t\tsuper();\n\t\tthis.activeTab = options.initialTab;\n\t\tconst tabBar = new ConfigurationMenuTabBar(() => this.activeTab);\n\t\tconst getHeaderRows = () => tabBar.getRowCount(getMenuPanelInnerWidth(this.renderWidth)) + 1;\n\t\tconst providerOptions = options.providerOptions.filter(\n\t\t\t(provider) => (provider.category ?? \"provider\") === \"provider\",\n\t\t);\n\t\tconst mcpOptions = options.providerOptions.filter((provider) => provider.category === \"service\");\n\n\t\tconst providers = new OAuthSelectorComponent(\n\t\t\t\"login\",\n\t\t\toptions.authStorage,\n\t\t\tproviderOptions,\n\t\t\toptions.onSelectProvider,\n\t\t\toptions.onCancel,\n\t\t\t(providerId) => options.modelRegistry.getProviderAuthStatus(providerId),\n\t\t\t{\n\t\t\t\tgetRows: options.getRows,\n\t\t\t\theader: tabBar,\n\t\t\t\tgetHeaderRows,\n\t\t\t\ttitle: \"Providers\",\n\t\t\t\tsubtitle: \"Connect with a subscription or API key.\",\n\t\t\t\tsearchPlaceholder: \"Search providers\",\n\t\t\t},\n\t\t);\n\t\tconst models = new ModelSelectorComponent(\n\t\t\toptions.tui,\n\t\t\toptions.currentModel,\n\t\t\toptions.modelRegistry,\n\t\t\toptions.scopedModels,\n\t\t\toptions.onSelectModel,\n\t\t\toptions.onCancel,\n\t\t\toptions.initialModelSearch,\n\t\t\t{\n\t\t\t\tavailableModels: options.availableModels,\n\t\t\t\tconfiguredProviders: options.configuredProviders,\n\t\t\t\theader: tabBar,\n\t\t\t\tgetHeaderRows,\n\t\t\t\tgetRows: options.getRows,\n\t\t\t\trecentModels: options.recentModels,\n\t\t\t},\n\t\t);\n\t\tconst mcpConnections = new OAuthSelectorComponent(\n\t\t\t\"login\",\n\t\t\toptions.authStorage,\n\t\t\tmcpOptions,\n\t\t\toptions.onSelectMcpConnection,\n\t\t\toptions.onCancel,\n\t\t\t(providerId) => options.modelRegistry.getProviderAuthStatus(providerId),\n\t\t\t{\n\t\t\t\tgetRows: options.getRows,\n\t\t\t\theader: tabBar,\n\t\t\t\tgetHeaderRows,\n\t\t\t\ttitle: \"MCP Connections\",\n\t\t\t\tsubtitle: \"Connect MCP integrations and service credentials.\",\n\t\t\t\tsearchPlaceholder: \"Search MCP connections\",\n\t\t\t},\n\t\t);\n\n\t\tthis.bodies = {\n\t\t\tproviders,\n\t\t\tmodels,\n\t\t\t\"mcp-connections\": mcpConnections,\n\t\t};\n\t\tthis.addChild(this.activeBody);\n\t}\n\n\tget focused(): boolean {\n\t\treturn this._focused;\n\t}\n\n\tset focused(value: boolean) {\n\t\tthis._focused = value;\n\t\tthis.activeBody.focused = value;\n\t}\n\n\toverride render(width: number): string[] {\n\t\tthis.renderWidth = width;\n\t\treturn super.render(width);\n\t}\n\n\tgetActiveTab(): ConfigurationMenuTab {\n\t\treturn this.activeTab;\n\t}\n\n\tgetSearchValue(tab: ConfigurationMenuTab = this.activeTab): string {\n\t\treturn this.bodies[tab].getSearchInput().getValue();\n\t}\n\n\tsetActiveTab(tab: ConfigurationMenuTab): void {\n\t\tif (tab === this.activeTab) return;\n\t\tthis.activeBody.focused = false;\n\t\tthis.activeTab = tab;\n\t\tthis.clear();\n\t\tthis.addChild(this.activeBody);\n\t\tthis.activeBody.focused = this._focused;\n\t\tthis.options.requestRender();\n\t}\n\n\trefreshAuthentication(): void {\n\t\tthis.bodies.providers.refresh();\n\t\tthis.bodies[\"mcp-connections\"].refresh();\n\t\tthis.options.requestRender();\n\t}\n\n\tupdateModels(\n\t\tcurrentModel: Model<Api> | undefined,\n\t\tmodels?: ReadonlyArray<Model<Api>>,\n\t\tconfiguredProviders?: ReadonlySet<string>,\n\t): void {\n\t\tthis.bodies.models.updateState(currentModel, models, configuredProviders);\n\t}\n\n\thandleInput(keyData: string): void {\n\t\tconst kb = getKeybindings();\n\t\tif (kb.matches(keyData, \"tui.input.tab\")) {\n\t\t\tthis.switchTab(1);\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(keyData, \"app.configuration.previousTab\")) {\n\t\t\tthis.switchTab(-1);\n\t\t\treturn;\n\t\t}\n\t\tif (\n\t\t\tthis.activeTab === \"models\" &&\n\t\t\t(kb.matches(keyData, \"tui.editor.cursorLeft\") || kb.matches(keyData, \"tui.editor.cursorRight\"))\n\t\t) {\n\t\t\tthis.activeBody.getSearchInput().handleInput(keyData);\n\t\t\treturn;\n\t\t}\n\t\tthis.activeBody.handleInput(keyData);\n\t}\n\n\tprivate get activeBody(): OAuthSelectorComponent | ModelSelectorComponent {\n\t\treturn this.bodies[this.activeTab];\n\t}\n\n\tprivate switchTab(direction: 1 | -1): void {\n\t\tconst currentIndex = CONFIGURATION_MENU_TABS.indexOf(this.activeTab);\n\t\tconst nextIndex = (currentIndex + direction + CONFIGURATION_MENU_TABS.length) % CONFIGURATION_MENU_TABS.length;\n\t\tthis.setActiveTab(CONFIGURATION_MENU_TABS[nextIndex] ?? \"providers\");\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"configuration-menu.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/configuration-menu.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Api, Model } from \"@ponythewhite/base-context-ai\";\nimport {\n\ttype Component,\n\tContainer,\n\ttype Focusable,\n\tgetKeybindings,\n\ttype TUI,\n\tvisibleWidth,\n\twrapTextWithAnsi,\n} from \"@ponythewhite/base-context-tui\";\nimport type { AuthStorage } from \"../../../core/auth-storage.js\";\nimport type { ModelRegistry } from \"../../../core/model-registry.js\";\nimport { theme } from \"../theme/theme.js\";\nimport { keyText } from \"./keybinding-hints.js\";\nimport { getMenuPanelInnerWidth } from \"./menu-panel.js\";\nimport { ModelSelectorComponent } from \"./model-selector.js\";\nimport { type AuthSelectorProvider, OAuthSelectorComponent } from \"./oauth-selector.js\";\n\nexport const CONFIGURATION_MENU_TABS = [\"providers\", \"models\", \"mcp-connections\"] as const;\n\nexport type ConfigurationMenuTab = (typeof CONFIGURATION_MENU_TABS)[number];\n\nexport interface ConfigurationMenuScopedModel {\n\tmodel: Model<Api>;\n\tthinkingLevel?: string;\n}\n\nexport interface ConfigurationMenuOptions {\n\tinitialTab: ConfigurationMenuTab;\n\tproviderFirst?: boolean;\n\ttui: TUI;\n\tauthStorage: AuthStorage;\n\tproviderOptions: ReadonlyArray<AuthSelectorProvider>;\n\tmodelRegistry: ModelRegistry;\n\tcurrentModel: Model<Api> | undefined;\n\tscopedModels: ReadonlyArray<ConfigurationMenuScopedModel>;\n\tavailableModels: ReadonlyArray<Model<Api>>;\n\tconfiguredProviders: ReadonlySet<string>;\n\trecentModels?: ReadonlyArray<string>;\n\tinitialModelSearch?: string;\n\tgetRows?: () => number;\n\trequestRender: () => void;\n\tonSelectProvider: (provider: AuthSelectorProvider) => void;\n\tonSelectMcpConnection: (provider: AuthSelectorProvider) => void;\n\tonSelectModel: (model: Model<Api>) => void;\n\tonCancel: () => void;\n}\n\nconst TAB_LABELS: Record<ConfigurationMenuTab, string> = {\n\tproviders: \"Providers\",\n\tmodels: \"Models\",\n\t\"mcp-connections\": \"MCP Connections\",\n};\n\nclass ConfigurationMenuTabBar implements Component {\n\tconstructor(private readonly getActiveTab: () => ConfigurationMenuTab) {}\n\n\trender(width: number): string[] {\n\t\treturn this.getLines(width);\n\t}\n\n\tgetRowCount(width: number): number {\n\t\treturn this.getLines(width).length;\n\t}\n\n\tprivate getLines(width: number): string[] {\n\t\tconst safeWidth = Math.max(1, width);\n\t\tconst activeTab = this.getActiveTab();\n\t\tconst labels = CONFIGURATION_MENU_TABS.map((tab) => {\n\t\t\tconst label = `[${tab === activeTab ? \"▶\" : \" \"} ${TAB_LABELS[tab]}]`;\n\t\t\treturn tab === activeTab ? theme.bold(theme.fg(\"accent\", label)) : theme.fg(\"text\", label);\n\t\t});\n\t\tconst lines = this.wrapItems(\n\t\t\t[theme.bold(theme.fg(\"muted\", \"Tabs:\")), ...labels],\n\t\t\ttheme.fg(\"muted\", \" \"),\n\t\t\tsafeWidth,\n\t\t);\n\t\tconst tabKey = keyText(\"tui.input.tab\", { primaryOnly: true });\n\t\tconst shiftTabKey = keyText(\"app.configuration.previousTab\", { primaryOnly: true });\n\t\tconst closeKey = keyText(\"tui.select.cancel\", { primaryOnly: true });\n\t\tconst hint = `${theme.fg(\"dim\", `${tabKey}/${shiftTabKey}`)}${theme.fg(\"muted\", \" switch tabs · \")}${theme.fg(\"dim\", closeKey)}${theme.fg(\"muted\", \" close\")}`;\n\t\treturn [...lines, ...wrapTextWithAnsi(hint, safeWidth)];\n\t}\n\n\tprivate wrapItems(items: string[], separator: string, width: number): string[] {\n\t\tconst lines: string[] = [];\n\t\tlet line = \"\";\n\t\tfor (const item of items) {\n\t\t\tconst candidate = line ? `${line}${separator}${item}` : item;\n\t\t\tif (line && visibleWidth(candidate) > width) {\n\t\t\t\tlines.push(...wrapTextWithAnsi(line, width));\n\t\t\t\tline = item;\n\t\t\t} else {\n\t\t\t\tline = candidate;\n\t\t\t}\n\t\t}\n\t\tif (line) {\n\t\t\tlines.push(...wrapTextWithAnsi(line, width));\n\t\t}\n\t\treturn lines;\n\t}\n\n\tinvalidate(): void {}\n}\n\nexport class ConfigurationMenuComponent extends Container implements Focusable {\n\tprivate readonly bodies: {\n\t\tproviders: OAuthSelectorComponent;\n\t\tmodels: ModelSelectorComponent;\n\t\t\"mcp-connections\": OAuthSelectorComponent;\n\t};\n\tprivate activeTab: ConfigurationMenuTab;\n\tprivate selectedProvider?: string;\n\tprivate _focused = false;\n\tprivate renderWidth = 78;\n\n\tconstructor(private readonly options: ConfigurationMenuOptions) {\n\t\tsuper();\n\t\tthis.activeTab = options.providerFirst && options.initialTab === \"models\" ? \"providers\" : options.initialTab;\n\t\tconst tabBar = new ConfigurationMenuTabBar(() => this.activeTab);\n\t\tconst getHeaderRows = () => tabBar.getRowCount(getMenuPanelInnerWidth(this.renderWidth)) + 1;\n\t\tconst providerOptions = options.providerOptions.filter(\n\t\t\t(provider) => (provider.category ?? \"provider\") === \"provider\",\n\t\t);\n\t\tconst mcpOptions = options.providerOptions.filter((provider) => provider.category === \"service\");\n\n\t\tconst providers = new OAuthSelectorComponent(\n\t\t\t\"login\",\n\t\t\toptions.authStorage,\n\t\t\tproviderOptions,\n\t\t\toptions.onSelectProvider,\n\t\t\toptions.onCancel,\n\t\t\t(providerId) => options.modelRegistry.getProviderAuthStatus(providerId),\n\t\t\t{\n\t\t\t\tgetRows: options.getRows,\n\t\t\t\theader: tabBar,\n\t\t\t\tgetHeaderRows,\n\t\t\t\ttitle: \"Providers\",\n\t\t\t\tsubtitle: options.providerFirst\n\t\t\t\t\t? \"Select a provider, then choose one of its models.\"\n\t\t\t\t\t: \"Connect with a subscription or API key.\",\n\t\t\t\tsearchPlaceholder: \"Search providers\",\n\t\t\t},\n\t\t);\n\t\tconst models = new ModelSelectorComponent(\n\t\t\toptions.tui,\n\t\t\toptions.currentModel,\n\t\t\toptions.modelRegistry,\n\t\t\toptions.scopedModels,\n\t\t\toptions.onSelectModel,\n\t\t\toptions.onCancel,\n\t\t\toptions.initialModelSearch,\n\t\t\t{\n\t\t\t\tavailableModels: options.availableModels,\n\t\t\t\tconfiguredProviders: options.configuredProviders,\n\t\t\t\tsubtitle: options.providerFirst ? \"Choose a model from the selected provider.\" : undefined,\n\t\t\t\theader: tabBar,\n\t\t\t\tgetHeaderRows,\n\t\t\t\tgetRows: options.getRows,\n\t\t\t\trecentModels: options.recentModels,\n\t\t\t},\n\t\t);\n\t\tconst mcpConnections = new OAuthSelectorComponent(\n\t\t\t\"login\",\n\t\t\toptions.authStorage,\n\t\t\tmcpOptions,\n\t\t\toptions.onSelectMcpConnection,\n\t\t\toptions.onCancel,\n\t\t\t(providerId) => options.modelRegistry.getProviderAuthStatus(providerId),\n\t\t\t{\n\t\t\t\tgetRows: options.getRows,\n\t\t\t\theader: tabBar,\n\t\t\t\tgetHeaderRows,\n\t\t\t\ttitle: \"MCP Connections\",\n\t\t\t\tsubtitle: \"Connect MCP integrations and service credentials.\",\n\t\t\t\tsearchPlaceholder: \"Search MCP connections\",\n\t\t\t},\n\t\t);\n\n\t\tthis.bodies = {\n\t\t\tproviders,\n\t\t\tmodels,\n\t\t\t\"mcp-connections\": mcpConnections,\n\t\t};\n\t\tthis.addChild(this.activeBody);\n\t}\n\n\tget focused(): boolean {\n\t\treturn this._focused;\n\t}\n\n\tset focused(value: boolean) {\n\t\tthis._focused = value;\n\t\tthis.activeBody.focused = value;\n\t}\n\n\toverride render(width: number): string[] {\n\t\tthis.renderWidth = width;\n\t\treturn super.render(width);\n\t}\n\n\tgetActiveTab(): ConfigurationMenuTab {\n\t\treturn this.activeTab;\n\t}\n\n\tgetSearchValue(tab: ConfigurationMenuTab = this.activeTab): string {\n\t\treturn this.bodies[tab].getSearchInput().getValue();\n\t}\n\n\tshowProviderModels(providerId: string): void {\n\t\tthis.selectedProvider = providerId;\n\t\tthis.bodies.models.setProviderFilter(providerId);\n\t\tthis.setActiveTab(\"models\");\n\t}\n\n\tsetActiveTab(tab: ConfigurationMenuTab): void {\n\t\tif (this.options.providerFirst && tab === \"models\" && !this.selectedProvider) return;\n\t\tif (tab === this.activeTab) return;\n\t\tthis.activeBody.focused = false;\n\t\tthis.activeTab = tab;\n\t\tthis.clear();\n\t\tthis.addChild(this.activeBody);\n\t\tthis.activeBody.focused = this._focused;\n\t\tthis.options.requestRender();\n\t}\n\n\trefreshAuthentication(): void {\n\t\tthis.bodies.providers.refresh();\n\t\tthis.bodies[\"mcp-connections\"].refresh();\n\t\tthis.options.requestRender();\n\t}\n\n\tupdateModels(\n\t\tcurrentModel: Model<Api> | undefined,\n\t\tmodels?: ReadonlyArray<Model<Api>>,\n\t\tconfiguredProviders?: ReadonlySet<string>,\n\t): void {\n\t\tthis.bodies.models.updateState(currentModel, models, configuredProviders);\n\t}\n\n\thandleInput(keyData: string): void {\n\t\tconst kb = getKeybindings();\n\t\tif (kb.matches(keyData, \"tui.input.tab\")) {\n\t\t\tthis.switchTab(1);\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(keyData, \"app.configuration.previousTab\")) {\n\t\t\tthis.switchTab(-1);\n\t\t\treturn;\n\t\t}\n\t\tif (\n\t\t\tthis.activeTab === \"models\" &&\n\t\t\t(kb.matches(keyData, \"tui.editor.cursorLeft\") || kb.matches(keyData, \"tui.editor.cursorRight\"))\n\t\t) {\n\t\t\tthis.activeBody.getSearchInput().handleInput(keyData);\n\t\t\treturn;\n\t\t}\n\t\tthis.activeBody.handleInput(keyData);\n\t}\n\n\tprivate get activeBody(): OAuthSelectorComponent | ModelSelectorComponent {\n\t\treturn this.bodies[this.activeTab];\n\t}\n\n\tprivate switchTab(direction: 1 | -1): void {\n\t\tconst currentIndex = CONFIGURATION_MENU_TABS.indexOf(this.activeTab);\n\t\tconst nextIndex = (currentIndex + direction + CONFIGURATION_MENU_TABS.length) % CONFIGURATION_MENU_TABS.length;\n\t\tthis.setActiveTab(CONFIGURATION_MENU_TABS[nextIndex] ?? \"providers\");\n\t}\n}\n"]}
|
|
@@ -59,12 +59,13 @@ export class ConfigurationMenuComponent extends Container {
|
|
|
59
59
|
options;
|
|
60
60
|
bodies;
|
|
61
61
|
activeTab;
|
|
62
|
+
selectedProvider;
|
|
62
63
|
_focused = false;
|
|
63
64
|
renderWidth = 78;
|
|
64
65
|
constructor(options) {
|
|
65
66
|
super();
|
|
66
67
|
this.options = options;
|
|
67
|
-
this.activeTab = options.initialTab;
|
|
68
|
+
this.activeTab = options.providerFirst && options.initialTab === "models" ? "providers" : options.initialTab;
|
|
68
69
|
const tabBar = new ConfigurationMenuTabBar(() => this.activeTab);
|
|
69
70
|
const getHeaderRows = () => tabBar.getRowCount(getMenuPanelInnerWidth(this.renderWidth)) + 1;
|
|
70
71
|
const providerOptions = options.providerOptions.filter((provider) => (provider.category ?? "provider") === "provider");
|
|
@@ -74,12 +75,15 @@ export class ConfigurationMenuComponent extends Container {
|
|
|
74
75
|
header: tabBar,
|
|
75
76
|
getHeaderRows,
|
|
76
77
|
title: "Providers",
|
|
77
|
-
subtitle:
|
|
78
|
+
subtitle: options.providerFirst
|
|
79
|
+
? "Select a provider, then choose one of its models."
|
|
80
|
+
: "Connect with a subscription or API key.",
|
|
78
81
|
searchPlaceholder: "Search providers",
|
|
79
82
|
});
|
|
80
83
|
const models = new ModelSelectorComponent(options.tui, options.currentModel, options.modelRegistry, options.scopedModels, options.onSelectModel, options.onCancel, options.initialModelSearch, {
|
|
81
84
|
availableModels: options.availableModels,
|
|
82
85
|
configuredProviders: options.configuredProviders,
|
|
86
|
+
subtitle: options.providerFirst ? "Choose a model from the selected provider." : undefined,
|
|
83
87
|
header: tabBar,
|
|
84
88
|
getHeaderRows,
|
|
85
89
|
getRows: options.getRows,
|
|
@@ -117,7 +121,14 @@ export class ConfigurationMenuComponent extends Container {
|
|
|
117
121
|
getSearchValue(tab = this.activeTab) {
|
|
118
122
|
return this.bodies[tab].getSearchInput().getValue();
|
|
119
123
|
}
|
|
124
|
+
showProviderModels(providerId) {
|
|
125
|
+
this.selectedProvider = providerId;
|
|
126
|
+
this.bodies.models.setProviderFilter(providerId);
|
|
127
|
+
this.setActiveTab("models");
|
|
128
|
+
}
|
|
120
129
|
setActiveTab(tab) {
|
|
130
|
+
if (this.options.providerFirst && tab === "models" && !this.selectedProvider)
|
|
131
|
+
return;
|
|
121
132
|
if (tab === this.activeTab)
|
|
122
133
|
return;
|
|
123
134
|
this.activeBody.focused = false;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"configuration-menu.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/configuration-menu.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Api, Model } from \"@ponythewhite/base-context-ai\";\nimport {\n\ttype Component,\n\tContainer,\n\ttype Focusable,\n\tgetKeybindings,\n\ttype TUI,\n\tvisibleWidth,\n\twrapTextWithAnsi,\n} from \"@ponythewhite/base-context-tui\";\nimport type { AuthStorage } from \"../../../core/auth-storage.js\";\nimport type { ModelRegistry } from \"../../../core/model-registry.js\";\nimport { theme } from \"../theme/theme.js\";\nimport { keyText } from \"./keybinding-hints.js\";\nimport { getMenuPanelInnerWidth } from \"./menu-panel.js\";\nimport { ModelSelectorComponent } from \"./model-selector.js\";\nimport { type AuthSelectorProvider, OAuthSelectorComponent } from \"./oauth-selector.js\";\n\nexport const CONFIGURATION_MENU_TABS = [\"providers\", \"models\", \"mcp-connections\"] as const;\n\nexport type ConfigurationMenuTab = (typeof CONFIGURATION_MENU_TABS)[number];\n\nexport interface ConfigurationMenuScopedModel {\n\tmodel: Model<Api>;\n\tthinkingLevel?: string;\n}\n\nexport interface ConfigurationMenuOptions {\n\tinitialTab: ConfigurationMenuTab;\n\ttui: TUI;\n\tauthStorage: AuthStorage;\n\tproviderOptions: ReadonlyArray<AuthSelectorProvider>;\n\tmodelRegistry: ModelRegistry;\n\tcurrentModel: Model<Api> | undefined;\n\tscopedModels: ReadonlyArray<ConfigurationMenuScopedModel>;\n\tavailableModels: ReadonlyArray<Model<Api>>;\n\tconfiguredProviders: ReadonlySet<string>;\n\trecentModels?: ReadonlyArray<string>;\n\tinitialModelSearch?: string;\n\tgetRows?: () => number;\n\trequestRender: () => void;\n\tonSelectProvider: (provider: AuthSelectorProvider) => void;\n\tonSelectMcpConnection: (provider: AuthSelectorProvider) => void;\n\tonSelectModel: (model: Model<Api>) => void;\n\tonCancel: () => void;\n}\n\nconst TAB_LABELS: Record<ConfigurationMenuTab, string> = {\n\tproviders: \"Providers\",\n\tmodels: \"Models\",\n\t\"mcp-connections\": \"MCP Connections\",\n};\n\nclass ConfigurationMenuTabBar implements Component {\n\tconstructor(private readonly getActiveTab: () => ConfigurationMenuTab) {}\n\n\trender(width: number): string[] {\n\t\treturn this.getLines(width);\n\t}\n\n\tgetRowCount(width: number): number {\n\t\treturn this.getLines(width).length;\n\t}\n\n\tprivate getLines(width: number): string[] {\n\t\tconst safeWidth = Math.max(1, width);\n\t\tconst activeTab = this.getActiveTab();\n\t\tconst labels = CONFIGURATION_MENU_TABS.map((tab) => {\n\t\t\tconst label = `[${tab === activeTab ? \"▶\" : \" \"} ${TAB_LABELS[tab]}]`;\n\t\t\treturn tab === activeTab ? theme.bold(theme.fg(\"accent\", label)) : theme.fg(\"text\", label);\n\t\t});\n\t\tconst lines = this.wrapItems(\n\t\t\t[theme.bold(theme.fg(\"muted\", \"Tabs:\")), ...labels],\n\t\t\ttheme.fg(\"muted\", \" \"),\n\t\t\tsafeWidth,\n\t\t);\n\t\tconst tabKey = keyText(\"tui.input.tab\", { primaryOnly: true });\n\t\tconst shiftTabKey = keyText(\"app.configuration.previousTab\", { primaryOnly: true });\n\t\tconst closeKey = keyText(\"tui.select.cancel\", { primaryOnly: true });\n\t\tconst hint = `${theme.fg(\"dim\", `${tabKey}/${shiftTabKey}`)}${theme.fg(\"muted\", \" switch tabs · \")}${theme.fg(\"dim\", closeKey)}${theme.fg(\"muted\", \" close\")}`;\n\t\treturn [...lines, ...wrapTextWithAnsi(hint, safeWidth)];\n\t}\n\n\tprivate wrapItems(items: string[], separator: string, width: number): string[] {\n\t\tconst lines: string[] = [];\n\t\tlet line = \"\";\n\t\tfor (const item of items) {\n\t\t\tconst candidate = line ? `${line}${separator}${item}` : item;\n\t\t\tif (line && visibleWidth(candidate) > width) {\n\t\t\t\tlines.push(...wrapTextWithAnsi(line, width));\n\t\t\t\tline = item;\n\t\t\t} else {\n\t\t\t\tline = candidate;\n\t\t\t}\n\t\t}\n\t\tif (line) {\n\t\t\tlines.push(...wrapTextWithAnsi(line, width));\n\t\t}\n\t\treturn lines;\n\t}\n\n\tinvalidate(): void {}\n}\n\nexport class ConfigurationMenuComponent extends Container implements Focusable {\n\tprivate readonly bodies: {\n\t\tproviders: OAuthSelectorComponent;\n\t\tmodels: ModelSelectorComponent;\n\t\t\"mcp-connections\": OAuthSelectorComponent;\n\t};\n\tprivate activeTab: ConfigurationMenuTab;\n\tprivate _focused = false;\n\tprivate renderWidth = 78;\n\n\tconstructor(private readonly options: ConfigurationMenuOptions) {\n\t\tsuper();\n\t\tthis.activeTab = options.initialTab;\n\t\tconst tabBar = new ConfigurationMenuTabBar(() => this.activeTab);\n\t\tconst getHeaderRows = () => tabBar.getRowCount(getMenuPanelInnerWidth(this.renderWidth)) + 1;\n\t\tconst providerOptions = options.providerOptions.filter(\n\t\t\t(provider) => (provider.category ?? \"provider\") === \"provider\",\n\t\t);\n\t\tconst mcpOptions = options.providerOptions.filter((provider) => provider.category === \"service\");\n\n\t\tconst providers = new OAuthSelectorComponent(\n\t\t\t\"login\",\n\t\t\toptions.authStorage,\n\t\t\tproviderOptions,\n\t\t\toptions.onSelectProvider,\n\t\t\toptions.onCancel,\n\t\t\t(providerId) => options.modelRegistry.getProviderAuthStatus(providerId),\n\t\t\t{\n\t\t\t\tgetRows: options.getRows,\n\t\t\t\theader: tabBar,\n\t\t\t\tgetHeaderRows,\n\t\t\t\ttitle: \"Providers\",\n\t\t\t\tsubtitle: \"Connect with a subscription or API key.\",\n\t\t\t\tsearchPlaceholder: \"Search providers\",\n\t\t\t},\n\t\t);\n\t\tconst models = new ModelSelectorComponent(\n\t\t\toptions.tui,\n\t\t\toptions.currentModel,\n\t\t\toptions.modelRegistry,\n\t\t\toptions.scopedModels,\n\t\t\toptions.onSelectModel,\n\t\t\toptions.onCancel,\n\t\t\toptions.initialModelSearch,\n\t\t\t{\n\t\t\t\tavailableModels: options.availableModels,\n\t\t\t\tconfiguredProviders: options.configuredProviders,\n\t\t\t\theader: tabBar,\n\t\t\t\tgetHeaderRows,\n\t\t\t\tgetRows: options.getRows,\n\t\t\t\trecentModels: options.recentModels,\n\t\t\t},\n\t\t);\n\t\tconst mcpConnections = new OAuthSelectorComponent(\n\t\t\t\"login\",\n\t\t\toptions.authStorage,\n\t\t\tmcpOptions,\n\t\t\toptions.onSelectMcpConnection,\n\t\t\toptions.onCancel,\n\t\t\t(providerId) => options.modelRegistry.getProviderAuthStatus(providerId),\n\t\t\t{\n\t\t\t\tgetRows: options.getRows,\n\t\t\t\theader: tabBar,\n\t\t\t\tgetHeaderRows,\n\t\t\t\ttitle: \"MCP Connections\",\n\t\t\t\tsubtitle: \"Connect MCP integrations and service credentials.\",\n\t\t\t\tsearchPlaceholder: \"Search MCP connections\",\n\t\t\t},\n\t\t);\n\n\t\tthis.bodies = {\n\t\t\tproviders,\n\t\t\tmodels,\n\t\t\t\"mcp-connections\": mcpConnections,\n\t\t};\n\t\tthis.addChild(this.activeBody);\n\t}\n\n\tget focused(): boolean {\n\t\treturn this._focused;\n\t}\n\n\tset focused(value: boolean) {\n\t\tthis._focused = value;\n\t\tthis.activeBody.focused = value;\n\t}\n\n\toverride render(width: number): string[] {\n\t\tthis.renderWidth = width;\n\t\treturn super.render(width);\n\t}\n\n\tgetActiveTab(): ConfigurationMenuTab {\n\t\treturn this.activeTab;\n\t}\n\n\tgetSearchValue(tab: ConfigurationMenuTab = this.activeTab): string {\n\t\treturn this.bodies[tab].getSearchInput().getValue();\n\t}\n\n\tsetActiveTab(tab: ConfigurationMenuTab): void {\n\t\tif (tab === this.activeTab) return;\n\t\tthis.activeBody.focused = false;\n\t\tthis.activeTab = tab;\n\t\tthis.clear();\n\t\tthis.addChild(this.activeBody);\n\t\tthis.activeBody.focused = this._focused;\n\t\tthis.options.requestRender();\n\t}\n\n\trefreshAuthentication(): void {\n\t\tthis.bodies.providers.refresh();\n\t\tthis.bodies[\"mcp-connections\"].refresh();\n\t\tthis.options.requestRender();\n\t}\n\n\tupdateModels(\n\t\tcurrentModel: Model<Api> | undefined,\n\t\tmodels?: ReadonlyArray<Model<Api>>,\n\t\tconfiguredProviders?: ReadonlySet<string>,\n\t): void {\n\t\tthis.bodies.models.updateState(currentModel, models, configuredProviders);\n\t}\n\n\thandleInput(keyData: string): void {\n\t\tconst kb = getKeybindings();\n\t\tif (kb.matches(keyData, \"tui.input.tab\")) {\n\t\t\tthis.switchTab(1);\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(keyData, \"app.configuration.previousTab\")) {\n\t\t\tthis.switchTab(-1);\n\t\t\treturn;\n\t\t}\n\t\tif (\n\t\t\tthis.activeTab === \"models\" &&\n\t\t\t(kb.matches(keyData, \"tui.editor.cursorLeft\") || kb.matches(keyData, \"tui.editor.cursorRight\"))\n\t\t) {\n\t\t\tthis.activeBody.getSearchInput().handleInput(keyData);\n\t\t\treturn;\n\t\t}\n\t\tthis.activeBody.handleInput(keyData);\n\t}\n\n\tprivate get activeBody(): OAuthSelectorComponent | ModelSelectorComponent {\n\t\treturn this.bodies[this.activeTab];\n\t}\n\n\tprivate switchTab(direction: 1 | -1): void {\n\t\tconst currentIndex = CONFIGURATION_MENU_TABS.indexOf(this.activeTab);\n\t\tconst nextIndex = (currentIndex + direction + CONFIGURATION_MENU_TABS.length) % CONFIGURATION_MENU_TABS.length;\n\t\tthis.setActiveTab(CONFIGURATION_MENU_TABS[nextIndex] ?? \"providers\");\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"configuration-menu.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/configuration-menu.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Api, Model } from \"@ponythewhite/base-context-ai\";\nimport {\n\ttype Component,\n\tContainer,\n\ttype Focusable,\n\tgetKeybindings,\n\ttype TUI,\n\tvisibleWidth,\n\twrapTextWithAnsi,\n} from \"@ponythewhite/base-context-tui\";\nimport type { AuthStorage } from \"../../../core/auth-storage.js\";\nimport type { ModelRegistry } from \"../../../core/model-registry.js\";\nimport { theme } from \"../theme/theme.js\";\nimport { keyText } from \"./keybinding-hints.js\";\nimport { getMenuPanelInnerWidth } from \"./menu-panel.js\";\nimport { ModelSelectorComponent } from \"./model-selector.js\";\nimport { type AuthSelectorProvider, OAuthSelectorComponent } from \"./oauth-selector.js\";\n\nexport const CONFIGURATION_MENU_TABS = [\"providers\", \"models\", \"mcp-connections\"] as const;\n\nexport type ConfigurationMenuTab = (typeof CONFIGURATION_MENU_TABS)[number];\n\nexport interface ConfigurationMenuScopedModel {\n\tmodel: Model<Api>;\n\tthinkingLevel?: string;\n}\n\nexport interface ConfigurationMenuOptions {\n\tinitialTab: ConfigurationMenuTab;\n\tproviderFirst?: boolean;\n\ttui: TUI;\n\tauthStorage: AuthStorage;\n\tproviderOptions: ReadonlyArray<AuthSelectorProvider>;\n\tmodelRegistry: ModelRegistry;\n\tcurrentModel: Model<Api> | undefined;\n\tscopedModels: ReadonlyArray<ConfigurationMenuScopedModel>;\n\tavailableModels: ReadonlyArray<Model<Api>>;\n\tconfiguredProviders: ReadonlySet<string>;\n\trecentModels?: ReadonlyArray<string>;\n\tinitialModelSearch?: string;\n\tgetRows?: () => number;\n\trequestRender: () => void;\n\tonSelectProvider: (provider: AuthSelectorProvider) => void;\n\tonSelectMcpConnection: (provider: AuthSelectorProvider) => void;\n\tonSelectModel: (model: Model<Api>) => void;\n\tonCancel: () => void;\n}\n\nconst TAB_LABELS: Record<ConfigurationMenuTab, string> = {\n\tproviders: \"Providers\",\n\tmodels: \"Models\",\n\t\"mcp-connections\": \"MCP Connections\",\n};\n\nclass ConfigurationMenuTabBar implements Component {\n\tconstructor(private readonly getActiveTab: () => ConfigurationMenuTab) {}\n\n\trender(width: number): string[] {\n\t\treturn this.getLines(width);\n\t}\n\n\tgetRowCount(width: number): number {\n\t\treturn this.getLines(width).length;\n\t}\n\n\tprivate getLines(width: number): string[] {\n\t\tconst safeWidth = Math.max(1, width);\n\t\tconst activeTab = this.getActiveTab();\n\t\tconst labels = CONFIGURATION_MENU_TABS.map((tab) => {\n\t\t\tconst label = `[${tab === activeTab ? \"▶\" : \" \"} ${TAB_LABELS[tab]}]`;\n\t\t\treturn tab === activeTab ? theme.bold(theme.fg(\"accent\", label)) : theme.fg(\"text\", label);\n\t\t});\n\t\tconst lines = this.wrapItems(\n\t\t\t[theme.bold(theme.fg(\"muted\", \"Tabs:\")), ...labels],\n\t\t\ttheme.fg(\"muted\", \" \"),\n\t\t\tsafeWidth,\n\t\t);\n\t\tconst tabKey = keyText(\"tui.input.tab\", { primaryOnly: true });\n\t\tconst shiftTabKey = keyText(\"app.configuration.previousTab\", { primaryOnly: true });\n\t\tconst closeKey = keyText(\"tui.select.cancel\", { primaryOnly: true });\n\t\tconst hint = `${theme.fg(\"dim\", `${tabKey}/${shiftTabKey}`)}${theme.fg(\"muted\", \" switch tabs · \")}${theme.fg(\"dim\", closeKey)}${theme.fg(\"muted\", \" close\")}`;\n\t\treturn [...lines, ...wrapTextWithAnsi(hint, safeWidth)];\n\t}\n\n\tprivate wrapItems(items: string[], separator: string, width: number): string[] {\n\t\tconst lines: string[] = [];\n\t\tlet line = \"\";\n\t\tfor (const item of items) {\n\t\t\tconst candidate = line ? `${line}${separator}${item}` : item;\n\t\t\tif (line && visibleWidth(candidate) > width) {\n\t\t\t\tlines.push(...wrapTextWithAnsi(line, width));\n\t\t\t\tline = item;\n\t\t\t} else {\n\t\t\t\tline = candidate;\n\t\t\t}\n\t\t}\n\t\tif (line) {\n\t\t\tlines.push(...wrapTextWithAnsi(line, width));\n\t\t}\n\t\treturn lines;\n\t}\n\n\tinvalidate(): void {}\n}\n\nexport class ConfigurationMenuComponent extends Container implements Focusable {\n\tprivate readonly bodies: {\n\t\tproviders: OAuthSelectorComponent;\n\t\tmodels: ModelSelectorComponent;\n\t\t\"mcp-connections\": OAuthSelectorComponent;\n\t};\n\tprivate activeTab: ConfigurationMenuTab;\n\tprivate selectedProvider?: string;\n\tprivate _focused = false;\n\tprivate renderWidth = 78;\n\n\tconstructor(private readonly options: ConfigurationMenuOptions) {\n\t\tsuper();\n\t\tthis.activeTab = options.providerFirst && options.initialTab === \"models\" ? \"providers\" : options.initialTab;\n\t\tconst tabBar = new ConfigurationMenuTabBar(() => this.activeTab);\n\t\tconst getHeaderRows = () => tabBar.getRowCount(getMenuPanelInnerWidth(this.renderWidth)) + 1;\n\t\tconst providerOptions = options.providerOptions.filter(\n\t\t\t(provider) => (provider.category ?? \"provider\") === \"provider\",\n\t\t);\n\t\tconst mcpOptions = options.providerOptions.filter((provider) => provider.category === \"service\");\n\n\t\tconst providers = new OAuthSelectorComponent(\n\t\t\t\"login\",\n\t\t\toptions.authStorage,\n\t\t\tproviderOptions,\n\t\t\toptions.onSelectProvider,\n\t\t\toptions.onCancel,\n\t\t\t(providerId) => options.modelRegistry.getProviderAuthStatus(providerId),\n\t\t\t{\n\t\t\t\tgetRows: options.getRows,\n\t\t\t\theader: tabBar,\n\t\t\t\tgetHeaderRows,\n\t\t\t\ttitle: \"Providers\",\n\t\t\t\tsubtitle: options.providerFirst\n\t\t\t\t\t? \"Select a provider, then choose one of its models.\"\n\t\t\t\t\t: \"Connect with a subscription or API key.\",\n\t\t\t\tsearchPlaceholder: \"Search providers\",\n\t\t\t},\n\t\t);\n\t\tconst models = new ModelSelectorComponent(\n\t\t\toptions.tui,\n\t\t\toptions.currentModel,\n\t\t\toptions.modelRegistry,\n\t\t\toptions.scopedModels,\n\t\t\toptions.onSelectModel,\n\t\t\toptions.onCancel,\n\t\t\toptions.initialModelSearch,\n\t\t\t{\n\t\t\t\tavailableModels: options.availableModels,\n\t\t\t\tconfiguredProviders: options.configuredProviders,\n\t\t\t\tsubtitle: options.providerFirst ? \"Choose a model from the selected provider.\" : undefined,\n\t\t\t\theader: tabBar,\n\t\t\t\tgetHeaderRows,\n\t\t\t\tgetRows: options.getRows,\n\t\t\t\trecentModels: options.recentModels,\n\t\t\t},\n\t\t);\n\t\tconst mcpConnections = new OAuthSelectorComponent(\n\t\t\t\"login\",\n\t\t\toptions.authStorage,\n\t\t\tmcpOptions,\n\t\t\toptions.onSelectMcpConnection,\n\t\t\toptions.onCancel,\n\t\t\t(providerId) => options.modelRegistry.getProviderAuthStatus(providerId),\n\t\t\t{\n\t\t\t\tgetRows: options.getRows,\n\t\t\t\theader: tabBar,\n\t\t\t\tgetHeaderRows,\n\t\t\t\ttitle: \"MCP Connections\",\n\t\t\t\tsubtitle: \"Connect MCP integrations and service credentials.\",\n\t\t\t\tsearchPlaceholder: \"Search MCP connections\",\n\t\t\t},\n\t\t);\n\n\t\tthis.bodies = {\n\t\t\tproviders,\n\t\t\tmodels,\n\t\t\t\"mcp-connections\": mcpConnections,\n\t\t};\n\t\tthis.addChild(this.activeBody);\n\t}\n\n\tget focused(): boolean {\n\t\treturn this._focused;\n\t}\n\n\tset focused(value: boolean) {\n\t\tthis._focused = value;\n\t\tthis.activeBody.focused = value;\n\t}\n\n\toverride render(width: number): string[] {\n\t\tthis.renderWidth = width;\n\t\treturn super.render(width);\n\t}\n\n\tgetActiveTab(): ConfigurationMenuTab {\n\t\treturn this.activeTab;\n\t}\n\n\tgetSearchValue(tab: ConfigurationMenuTab = this.activeTab): string {\n\t\treturn this.bodies[tab].getSearchInput().getValue();\n\t}\n\n\tshowProviderModels(providerId: string): void {\n\t\tthis.selectedProvider = providerId;\n\t\tthis.bodies.models.setProviderFilter(providerId);\n\t\tthis.setActiveTab(\"models\");\n\t}\n\n\tsetActiveTab(tab: ConfigurationMenuTab): void {\n\t\tif (this.options.providerFirst && tab === \"models\" && !this.selectedProvider) return;\n\t\tif (tab === this.activeTab) return;\n\t\tthis.activeBody.focused = false;\n\t\tthis.activeTab = tab;\n\t\tthis.clear();\n\t\tthis.addChild(this.activeBody);\n\t\tthis.activeBody.focused = this._focused;\n\t\tthis.options.requestRender();\n\t}\n\n\trefreshAuthentication(): void {\n\t\tthis.bodies.providers.refresh();\n\t\tthis.bodies[\"mcp-connections\"].refresh();\n\t\tthis.options.requestRender();\n\t}\n\n\tupdateModels(\n\t\tcurrentModel: Model<Api> | undefined,\n\t\tmodels?: ReadonlyArray<Model<Api>>,\n\t\tconfiguredProviders?: ReadonlySet<string>,\n\t): void {\n\t\tthis.bodies.models.updateState(currentModel, models, configuredProviders);\n\t}\n\n\thandleInput(keyData: string): void {\n\t\tconst kb = getKeybindings();\n\t\tif (kb.matches(keyData, \"tui.input.tab\")) {\n\t\t\tthis.switchTab(1);\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(keyData, \"app.configuration.previousTab\")) {\n\t\t\tthis.switchTab(-1);\n\t\t\treturn;\n\t\t}\n\t\tif (\n\t\t\tthis.activeTab === \"models\" &&\n\t\t\t(kb.matches(keyData, \"tui.editor.cursorLeft\") || kb.matches(keyData, \"tui.editor.cursorRight\"))\n\t\t) {\n\t\t\tthis.activeBody.getSearchInput().handleInput(keyData);\n\t\t\treturn;\n\t\t}\n\t\tthis.activeBody.handleInput(keyData);\n\t}\n\n\tprivate get activeBody(): OAuthSelectorComponent | ModelSelectorComponent {\n\t\treturn this.bodies[this.activeTab];\n\t}\n\n\tprivate switchTab(direction: 1 | -1): void {\n\t\tconst currentIndex = CONFIGURATION_MENU_TABS.indexOf(this.activeTab);\n\t\tconst nextIndex = (currentIndex + direction + CONFIGURATION_MENU_TABS.length) % CONFIGURATION_MENU_TABS.length;\n\t\tthis.setActiveTab(CONFIGURATION_MENU_TABS[nextIndex] ?? \"providers\");\n\t}\n}\n"]}
|
|
@@ -6,7 +6,7 @@ import type { ReadonlyFooterDataProvider } from "../../../core/footer-data-provi
|
|
|
6
6
|
* Renders nothing by default — token counters, cost, model name, cwd, and context %
|
|
7
7
|
* are intentionally hidden. The setters and invalidate/dispose hooks are kept so the
|
|
8
8
|
* existing call sites in interactive-mode keep working without modification, and so
|
|
9
|
-
* `/usage` can expose
|
|
9
|
+
* `/usage` can expose local usage statistics without re-plumbing.
|
|
10
10
|
*/
|
|
11
11
|
export declare class FooterComponent implements Component {
|
|
12
12
|
private footerData;
|