Skip to content

Commit 44da7d8

Browse files
committed
fix(vscode): stop reporting a managed provider as missing its key
A provider that authenticates over OAuth is required by the config schema to carry no apiKey at all, so the providers list flagged it in red as "No key configured" — a warning about a provider that is working. It now reads as signed in, and each row shows the provider's API host rather than only its wire type, which is what identifies a managed provider at a glance.
1 parent 4b10a69 commit 44da7d8

3 files changed

Lines changed: 26 additions & 8 deletions

File tree

apps/vscode/shared/types.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,9 @@ export interface ConfiguredProvider {
7575
id: string;
7676
type: string;
7777
baseUrl?: string;
78-
keySource: "config" | "env" | "none";
78+
keySource: "config" | "env" | "oauth" | "none";
79+
/** Host of the provider's base URL, shown so a managed provider is identifiable. */
80+
host?: string;
7981
apiKeyEnvVar?: string;
8082
catalogUrl?: string;
8183
models: string[];

apps/vscode/src/handlers/provider.handler.ts

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,18 @@ function toConfiguredProvider(id: string, provider: any, config: any): Configure
4747
id,
4848
type: provider.type ?? "unknown",
4949
baseUrl: provider.baseUrl,
50+
host: hostOf(provider.baseUrl),
5051
// Never send the key itself to the Webview; only whether one is configured
51-
// and where it comes from.
52+
// and where it comes from. A managed provider authenticates over OAuth and
53+
// is required by the schema to carry no key at all, so it is not missing one.
5254
keySource:
53-
typeof provider.apiKey === "string" && provider.apiKey.length > 0
54-
? "config"
55-
: typeof provider.apiKeyEnvVar === "string" && provider.apiKeyEnvVar.length > 0
56-
? "env"
57-
: "none",
55+
provider.oauth !== undefined
56+
? "oauth"
57+
: typeof provider.apiKey === "string" && provider.apiKey.length > 0
58+
? "config"
59+
: typeof provider.apiKeyEnvVar === "string" && provider.apiKeyEnvVar.length > 0
60+
? "env"
61+
: "none",
5862
apiKeyEnvVar: provider.apiKeyEnvVar,
5963
catalogUrl: provider.source?.kind === "modelsDev" ? provider.source.url : undefined,
6064
models: models.toSorted((left, right) => left.localeCompare(right)),
@@ -113,6 +117,15 @@ export const providerHandlers: Record<string, Handler<any, any>> = {
113117
},
114118
};
115119

120+
function hostOf(baseUrl: unknown): string | undefined {
121+
if (typeof baseUrl !== "string" || baseUrl.length === 0) return undefined;
122+
try {
123+
return new URL(baseUrl).host;
124+
} catch {
125+
return undefined;
126+
}
127+
}
128+
116129
function toCatalogSummary(id: string, entry: any): CatalogProviderSummary {
117130
const wire = catalogConnectionWire(entry);
118131
return {

apps/vscode/webview-ui/src/components/ProvidersModal.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import type {
3636
const KEY_SOURCE_LABEL: Record<ConfiguredProvider["keySource"], string> = {
3737
config: "Key in config.toml",
3838
env: "Key from environment",
39+
oauth: "Signed in",
3940
none: "No key configured",
4041
};
4142

@@ -179,7 +180,9 @@ function ProviderRow({
179180
>
180181
<IconChevronDown className={cn("size-3 text-muted-foreground transition-transform", !expanded && "-rotate-90")} />
181182
<span className="text-xs font-medium truncate">{provider.id}</span>
182-
<span className="text-[10px] text-muted-foreground shrink-0">{provider.type}</span>
183+
<span className="text-[10px] text-muted-foreground shrink-0 truncate">
184+
{provider.host ?? provider.type}
185+
</span>
183186
<span className="text-[10px] text-muted-foreground tabular-nums shrink-0">
184187
{provider.models.length} model{provider.models.length === 1 ? "" : "s"}
185188
</span>

0 commit comments

Comments
 (0)