koneck 2.49.4 → 2.51.0

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.
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Keys that survive closing the terminal.
3
+ *
4
+ * KONECK held a typed key in memory and said so proudly: "the key is held in memory only — KONECK
5
+ * has not written it anywhere", followed by advice to put an export line in a shell profile. That
6
+ * is a defensible position for a tool nobody has to use twice. In practice it meant entering the
7
+ * same key on every launch of the web UI, and a key that works in the terminal while the browser
8
+ * on the same machine reports none — because the two were keeping separate copies of something the
9
+ * user reasonably thought they had configured once.
10
+ *
11
+ * Every comparable tool persists. Claude Code keeps credentials under its own home directory or
12
+ * the OS keychain, Codex writes auth.json, the Gemini CLI keeps a file too. So this writes one as
13
+ * well, with the properties that make it defensible rather than merely convenient:
14
+ *
15
+ * - one file, `~/.koneck/credentials.json`, mode 0600 inside a 0700 directory, so a permissive
16
+ * umask on a shared machine cannot leave it group-readable;
17
+ * - written atomically through a temporary file and a rename, so a crash cannot leave half a
18
+ * credential behind and a symlink planted at the path is not followed;
19
+ * - keyed by provider, because a key belongs to the endpoint that issued it and there are
20
+ * several — the older single global apiKey could not express "OpenRouter but not OpenCode";
21
+ * - and never consulted ahead of the environment, so an exported variable still wins and a
22
+ * rotated key does not have to be hunted down in a file first.
23
+ *
24
+ * An environment variable fed from a password manager is still the better answer, and the notices
25
+ * keep saying so. This is the answer for the case where somebody has decided otherwise.
26
+ */
27
+ /** Where the file lives. `home` is for tests, which must never touch the real one. */
28
+ export declare function credentialsPath(home?: string): string;
29
+ /** Which providers have a key stored. Names only — callers that want a value ask for one. */
30
+ export declare function storedProviders(home?: string): string[];
31
+ /** The stored key for a provider, if there is one. */
32
+ export declare function storedKeyFor(provider: string, home?: string): string | undefined;
33
+ /** Writes a key for one provider, leaving the others alone. Returns the file it went into. */
34
+ export declare function rememberKey(provider: string, key: string, home?: string): string;
35
+ /** Removes one provider's key. Returns whether there was one to remove. */
36
+ export declare function forgetKey(provider: string, home?: string): boolean;
37
+ /** Removes every stored key. What /logout means once there is more than one. */
38
+ export declare function forgetAllKeys(home?: string): string[];
39
+ /**
40
+ * The same key remembered for two different providers.
41
+ *
42
+ * Found on a real machine: one key stored under both `openrouter` and `agentrouter`, identical
43
+ * fingerprints. Whichever of the two was intended, the other entry means a credential issued by
44
+ * one company is sent to another company's endpoint the moment that provider is used — not a key
45
+ * that fails, a key that is disclosed. The usual cause is entering it while a different provider
46
+ * was selected, which is exactly the mis-filing that used to happen silently.
47
+ *
48
+ * Reported, not repaired: only the person who owns the key knows which entry was meant.
49
+ */
50
+ export declare function crossFiledKeys(home?: string): Array<{
51
+ providers: string[];
52
+ }>;
53
+ //# sourceMappingURL=credentials.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../src/credentials.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAOH,sFAAsF;AACtF,wBAAgB,eAAe,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAErD;AAqBD,6FAA6F;AAC7F,wBAAgB,eAAe,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAEvD;AAED,sDAAsD;AACtD,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAGhF;AAwBD,8FAA8F;AAC9F,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAOhF;AAED,2EAA2E;AAC3E,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAOlE;AAED,gFAAgF;AAChF,wBAAgB,aAAa,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAIrD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IAAE,SAAS,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAW5E"}
@@ -0,0 +1,137 @@
1
+ /**
2
+ * Keys that survive closing the terminal.
3
+ *
4
+ * KONECK held a typed key in memory and said so proudly: "the key is held in memory only — KONECK
5
+ * has not written it anywhere", followed by advice to put an export line in a shell profile. That
6
+ * is a defensible position for a tool nobody has to use twice. In practice it meant entering the
7
+ * same key on every launch of the web UI, and a key that works in the terminal while the browser
8
+ * on the same machine reports none — because the two were keeping separate copies of something the
9
+ * user reasonably thought they had configured once.
10
+ *
11
+ * Every comparable tool persists. Claude Code keeps credentials under its own home directory or
12
+ * the OS keychain, Codex writes auth.json, the Gemini CLI keeps a file too. So this writes one as
13
+ * well, with the properties that make it defensible rather than merely convenient:
14
+ *
15
+ * - one file, `~/.koneck/credentials.json`, mode 0600 inside a 0700 directory, so a permissive
16
+ * umask on a shared machine cannot leave it group-readable;
17
+ * - written atomically through a temporary file and a rename, so a crash cannot leave half a
18
+ * credential behind and a symlink planted at the path is not followed;
19
+ * - keyed by provider, because a key belongs to the endpoint that issued it and there are
20
+ * several — the older single global apiKey could not express "OpenRouter but not OpenCode";
21
+ * - and never consulted ahead of the environment, so an exported variable still wins and a
22
+ * rotated key does not have to be hunted down in a file first.
23
+ *
24
+ * An environment variable fed from a password manager is still the better answer, and the notices
25
+ * keep saying so. This is the answer for the case where somebody has decided otherwise.
26
+ */
27
+ import { readFileSync, writeFileSync, mkdirSync, existsSync, renameSync, chmodSync, rmSync } from 'fs';
28
+ import os from 'os';
29
+ import path from 'path';
30
+ import { randomUUID } from 'crypto';
31
+ /** Where the file lives. `home` is for tests, which must never touch the real one. */
32
+ export function credentialsPath(home) {
33
+ return path.join(home ?? os.homedir(), '.koneck', 'credentials.json');
34
+ }
35
+ function readFile(home) {
36
+ const file = credentialsPath(home);
37
+ if (!existsSync(file))
38
+ return {};
39
+ try {
40
+ const parsed = JSON.parse(readFileSync(file, 'utf-8'));
41
+ if (!parsed || typeof parsed !== 'object')
42
+ return {};
43
+ const keys = parsed.keys;
44
+ return keys && typeof keys === 'object' ? { keys } : {};
45
+ }
46
+ catch {
47
+ // A corrupt credential file must not stop a run that has a working environment variable.
48
+ return {};
49
+ }
50
+ }
51
+ /** Which providers have a key stored. Names only — callers that want a value ask for one. */
52
+ export function storedProviders(home) {
53
+ return Object.keys(readFile(home).keys ?? {}).sort();
54
+ }
55
+ /** The stored key for a provider, if there is one. */
56
+ export function storedKeyFor(provider, home) {
57
+ const key = (readFile(home).keys ?? {})[provider.trim().toLowerCase()];
58
+ return typeof key === 'string' && key.trim() !== '' ? key : undefined;
59
+ }
60
+ function write(all, home) {
61
+ const file = credentialsPath(home);
62
+ const directory = path.dirname(file);
63
+ // 0700, so the directory itself does not advertise what is in it.
64
+ mkdirSync(directory, { recursive: true, mode: 0o700 });
65
+ try {
66
+ chmodSync(directory, 0o700);
67
+ }
68
+ catch { /* pre-existing directory owned as it is */ }
69
+ const temporary = path.join(directory, `.credentials.${randomUUID()}.tmp`);
70
+ try {
71
+ // `wx` fails rather than following anything already at that path.
72
+ writeFileSync(temporary, JSON.stringify(all, null, 2) + '\n', { encoding: 'utf-8', mode: 0o600, flag: 'wx' });
73
+ chmodSync(temporary, 0o600);
74
+ renameSync(temporary, file);
75
+ chmodSync(file, 0o600);
76
+ }
77
+ catch (error) {
78
+ try {
79
+ rmSync(temporary, { force: true });
80
+ }
81
+ catch { /* nothing to undo */ }
82
+ throw error;
83
+ }
84
+ return file;
85
+ }
86
+ /** Writes a key for one provider, leaving the others alone. Returns the file it went into. */
87
+ export function rememberKey(provider, key, home) {
88
+ const name = provider.trim().toLowerCase();
89
+ const value = key.trim();
90
+ if (!name)
91
+ throw new Error('which provider is this key for?');
92
+ if (!value)
93
+ throw new Error('no key given');
94
+ const all = readFile(home);
95
+ return write({ ...all, keys: { ...(all.keys ?? {}), [name]: value } }, home);
96
+ }
97
+ /** Removes one provider's key. Returns whether there was one to remove. */
98
+ export function forgetKey(provider, home) {
99
+ const name = provider.trim().toLowerCase();
100
+ const all = readFile(home);
101
+ if (!all.keys || !(name in all.keys))
102
+ return false;
103
+ const { [name]: _gone, ...rest } = all.keys;
104
+ write({ ...all, keys: rest }, home);
105
+ return true;
106
+ }
107
+ /** Removes every stored key. What /logout means once there is more than one. */
108
+ export function forgetAllKeys(home) {
109
+ const had = storedProviders(home);
110
+ if (had.length > 0)
111
+ write({ keys: {} }, home);
112
+ return had;
113
+ }
114
+ /**
115
+ * The same key remembered for two different providers.
116
+ *
117
+ * Found on a real machine: one key stored under both `openrouter` and `agentrouter`, identical
118
+ * fingerprints. Whichever of the two was intended, the other entry means a credential issued by
119
+ * one company is sent to another company's endpoint the moment that provider is used — not a key
120
+ * that fails, a key that is disclosed. The usual cause is entering it while a different provider
121
+ * was selected, which is exactly the mis-filing that used to happen silently.
122
+ *
123
+ * Reported, not repaired: only the person who owns the key knows which entry was meant.
124
+ */
125
+ export function crossFiledKeys(home) {
126
+ const keys = readFile(home).keys ?? {};
127
+ const byValue = new Map();
128
+ for (const [provider, value] of Object.entries(keys)) {
129
+ const seen = byValue.get(value) ?? [];
130
+ seen.push(provider);
131
+ byValue.set(value, seen);
132
+ }
133
+ return [...byValue.values()]
134
+ .filter(providers => providers.length > 1)
135
+ .map(providers => ({ providers: providers.sort() }));
136
+ }
137
+ //# sourceMappingURL=credentials.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credentials.js","sourceRoot":"","sources":["../src/credentials.ts"],"names":[],"mappings":"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"}
package/dist/doctor.d.ts CHANGED
@@ -15,6 +15,11 @@ type FetchLike = (input: string, init?: RequestInit) => Promise<{
15
15
  * distinguishes a reachable-but-misconfigured endpoint from a dead network.
16
16
  */
17
17
  export declare function providerConnectionCheck(def: ProviderDef, apiKey?: string, fetcher?: FetchLike): Promise<DoctorCheck>;
18
+ /**
19
+ * One key remembered for two providers, which means one of them is receiving somebody else's
20
+ * credential. Reported rather than repaired: only the owner knows which entry was intended.
21
+ */
22
+ export declare function credentialCrossFilingCheck(stateHome?: string): DoctorCheck;
18
23
  /**
19
24
  * Inspect the environment needed for a useful coding session.
20
25
  *
@@ -1 +1 @@
1
- {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../src/doctor.ts"],"names":[],"mappings":"AAKA,OAAO,EAAyC,KAAK,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAGzF,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAEpD,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,YAAY,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,KAAK,SAAS,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAEjG;;;;GAIG;AACH,wBAAsB,uBAAuB,CAC3C,GAAG,EAAE,WAAW,EAChB,MAAM,CAAC,EAAE,MAAM,EACf,OAAO,GAAE,SAAiB,GACzB,OAAO,CAAC,WAAW,CAAC,CAoBtB;AAYD;;;;;GAKG;AACH,wBAAsB,YAAY,CAChC,GAAG,EAAE,MAAM,EACX,cAAc,CAAC,EAAE,MAAM,EACvB,aAAa,CAAC,EAAE,MAAM,EACtB,YAAY,CAAC,EAAE,MAAM,EACrB,OAAO,CAAC,EAAE,SAAS,GAClB,OAAO,CAAC,WAAW,EAAE,CAAC,CA0FxB;AAED,2FAA2F;AAC3F,wBAAgB,YAAY,CAAC,OAAO,EAAE,SAAS,WAAW,EAAE,GAAG,MAAM,CASpE;AAED,wBAAsB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAc1D"}
1
+ {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../src/doctor.ts"],"names":[],"mappings":"AAKA,OAAO,EAAwD,KAAK,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAIxG,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAEpD,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,YAAY,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,KAAK,SAAS,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAEjG;;;;GAIG;AACH,wBAAsB,uBAAuB,CAC3C,GAAG,EAAE,WAAW,EAChB,MAAM,CAAC,EAAE,MAAM,EACf,OAAO,GAAE,SAAiB,GACzB,OAAO,CAAC,WAAW,CAAC,CAgCtB;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,WAAW,CAa1E;AAYD;;;;;GAKG;AACH,wBAAsB,YAAY,CAChC,GAAG,EAAE,MAAM,EACX,cAAc,CAAC,EAAE,MAAM,EACvB,aAAa,CAAC,EAAE,MAAM,EACtB,YAAY,CAAC,EAAE,MAAM,EACrB,OAAO,CAAC,EAAE,SAAS,GAClB,OAAO,CAAC,WAAW,EAAE,CAAC,CA6FxB;AAED,2FAA2F;AAC3F,wBAAgB,YAAY,CAAC,OAAO,EAAE,SAAS,WAAW,EAAE,GAAG,MAAM,CASpE;AAED,wBAAsB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAc1D"}
package/dist/doctor.js CHANGED
@@ -3,7 +3,8 @@ import { execa } from 'execa';
3
3
  import fs from 'fs/promises';
4
4
  import os from 'os';
5
5
  import path from 'path';
6
- import { PROVIDERS, getApiKey, resolveProvider } from './providers.js';
6
+ import { PROVIDERS, getApiKey, keyProvenance, resolveProvider } from './providers.js';
7
+ import { crossFiledKeys, credentialsPath } from './credentials.js';
7
8
  import { loadGlobalConfig } from './config.js';
8
9
  /**
9
10
  * Verify that an OpenAI-compatible endpoint is reachable without spending tokens or changing
@@ -18,6 +19,15 @@ export async function providerConnectionCheck(def, apiKey, fetcher = fetch) {
18
19
  catch {
19
20
  return { status: 'warn', name: 'Provider connection', reason: 'not checked — no API key available' };
20
21
  }
22
+ /*
23
+ * Which key, and from where — a fingerprint, never the key.
24
+ *
25
+ * The terminal and the browser once disagreed about whether a model worked, with identical
26
+ * requests on both sides. The difference was the credential, and neither side would say which
27
+ * one it held; comparing two fingerprints answers in a glance what took a request capture.
28
+ */
29
+ const seen = keyProvenance(def, apiKey);
30
+ const using = seen.found ? ` · key ${seen.fingerprint}, from ${seen.source}` : '';
21
31
  const url = def.baseURL.replace(/\/+$/, '') + '/models';
22
32
  try {
23
33
  const response = await fetcher(url, {
@@ -25,10 +35,12 @@ export async function providerConnectionCheck(def, apiKey, fetcher = fetch) {
25
35
  headers: { ...def.extraHeaders, Authorization: `Bearer ${key}` },
26
36
  signal: AbortSignal.timeout(5_000),
27
37
  });
28
- if (response.ok)
29
- return { status: 'pass', name: 'Provider connection', reason: def.baseURL };
38
+ if (response.ok) {
39
+ return { status: 'pass', name: 'Provider connection', reason: def.baseURL + using };
40
+ }
30
41
  if (response.status === 401 || response.status === 403) {
31
- return { status: 'fail', name: 'Provider connection', reason: `endpoint rejected the credential (HTTP ${response.status})` };
42
+ return { status: 'fail', name: 'Provider connection',
43
+ reason: `endpoint rejected the credential (HTTP ${response.status})${using}` };
32
44
  }
33
45
  return { status: 'warn', name: 'Provider connection', reason: `endpoint responded HTTP ${response.status} at ${def.baseURL}` };
34
46
  }
@@ -37,6 +49,24 @@ export async function providerConnectionCheck(def, apiKey, fetcher = fetch) {
37
49
  return { status: 'fail', name: 'Provider connection', reason: `could not reach ${def.baseURL} — ${message}` };
38
50
  }
39
51
  }
52
+ /**
53
+ * One key remembered for two providers, which means one of them is receiving somebody else's
54
+ * credential. Reported rather than repaired: only the owner knows which entry was intended.
55
+ */
56
+ export function credentialCrossFilingCheck(stateHome) {
57
+ const shared = crossFiledKeys(stateHome);
58
+ if (shared.length === 0) {
59
+ return { status: 'pass', name: 'Remembered keys', reason: 'no key is shared between providers' };
60
+ }
61
+ const pairs = shared.map(s => s.providers.join(' and ')).join('; ');
62
+ return {
63
+ status: 'fail',
64
+ name: 'Remembered keys',
65
+ reason: `the same key is remembered for ${pairs} — one of those endpoints is being sent a `
66
+ + `credential issued by the other. Forget whichever is wrong: /logout, or delete the `
67
+ + `entry from ${credentialsPath(stateHome)}`,
68
+ };
69
+ }
40
70
  function printResult(r) {
41
71
  if (r.status === 'pass') {
42
72
  console.log(chalk.green(` ✔ ${r.name}`));
@@ -97,6 +127,8 @@ export async function doctorChecks(cwd, activeProvider, activeBaseURL, activeApi
97
127
  else if (provider) {
98
128
  results.push({ status: 'warn', name: 'Provider connection', reason: `cannot probe unknown provider "${provider}"` });
99
129
  }
130
+ // Cheap, local, and the one credential problem that is a disclosure rather than a failure.
131
+ results.push(credentialCrossFilingCheck());
100
132
  try {
101
133
  await execa('git', ['--version']);
102
134
  results.push({ status: 'pass', name: 'git available' });
@@ -1 +1 @@
1
- {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../src/doctor.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../src/doctor.ts"],"names":[],"mappings":"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"}
package/dist/engine.d.ts CHANGED
@@ -24,6 +24,7 @@ export declare function describeProviderError(err: unknown, provider: string, mo
24
24
  */
25
25
  about?: {
26
26
  hadImage?: boolean;
27
+ credential?: string;
27
28
  }): string;
28
29
  /** Session totals as they stood before a request, so its usage can be added rather than assigned. */
29
30
  export interface UsageBaseline {
@@ -178,6 +179,8 @@ export declare function mapWithLimit<T, R>(items: readonly T[], limit: number, f
178
179
  * then advised removing the attachment — to people whose request contained no image at all. The
179
180
  * cheapest way to stop asserting it was to be able to check it.
180
181
  */
182
+ /** The key a run will use, as a fingerprint and a source. Never the key. Never throws. */
183
+ export declare function describeCredential(config: AgentConfig): string | undefined;
181
184
  export declare function carriesImage(messages: readonly Message[]): boolean;
182
185
  export declare function stripImages(messages: Message[]): number;
183
186
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"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"}
package/dist/engine.js CHANGED
@@ -7,7 +7,7 @@ import { execa } from 'execa';
7
7
  import { TOOL_DEFINITIONS, dispatchTool, describeShell, unknownToolError, resolveToolAlias, aliasNotice, isToolFailure, } from './tools.js';
8
8
  import { tui } from './tui.js';
9
9
  import { hasWorkspaceOwnedGitRepo, gitScope, createWorktree, mergeWorktree, preservedWorktreeNotice } from './worktree.js';
10
- import { resolveProvider, getApiKey, servesLocally, servesOwnWeights, isPrivateHost } from './providers.js';
10
+ import { resolveProvider, getApiKey, keyProvenance, servesLocally, servesOwnWeights, isPrivateHost } from './providers.js';
11
11
  import { compressIfNeeded } from './compressor.js';
12
12
  import { contextLimitFor, looksLikeContextOverflow, parseContextLimit, fetchModelContextLimit, ollamaServingLimit, fixedRequestTokens, overheadIsCrowded, crowdedWindowAdvice, probeOllamaContext, detectWindowPlateau, truncationNotice, } from './context-limit.js';
13
13
  import { generateSessionId, saveSession } from './session.js';
@@ -85,7 +85,9 @@ about = {}) {
85
85
  const hint = status === 429
86
86
  ? `Rate limited or out of quota on ${provider}. Check the plan and billing for that account.`
87
87
  : status === 401 || status === 403
88
- ? `${provider} rejected the credential. Check the API key, and that it is enabled for this endpoint.`
88
+ ? `${provider} rejected the credential. Check the API key, and that it is enabled for this `
89
+ + `endpoint.`
90
+ + (about.credential ? `\nThe key used: ${about.credential}` : '')
89
91
  : status === 404
90
92
  ? `${provider} does not recognise model "${model}". Use /models to pick one it offers.`
91
93
  : status === 400
@@ -119,7 +121,9 @@ about = {}) {
119
121
  */
120
122
  const rerouted = readReroutedFailure(`${e?.message ?? ''}${detail ? '\n' + detail : ''}`, { model, ...(about.hadImage === undefined ? {} : { hadImage: about.hadImage }) });
121
123
  if (rerouted) {
122
- return [`${provider} could not serve this request.`, rerouted.advice].join('\n');
124
+ return [`${provider} could not serve this request.`, rerouted.advice,
125
+ about.credential ? `\nThe key used: ${about.credential}` : undefined]
126
+ .filter(Boolean).join('\n');
123
127
  }
124
128
  const router = readRouterFailure(`${e?.message ?? ''}`);
125
129
  if (router) {
@@ -380,7 +384,7 @@ export function announcesMoreWork(text) {
380
384
  // ─── Client ──────────────────────────────────────────────────────────────────
381
385
  export function buildClient(config) {
382
386
  const provider = resolveProvider(config.provider, config.baseURL);
383
- const apiKey = getApiKey(provider, config.apiKey);
387
+ const apiKey = getApiKey(provider, config.apiKey, config.stateHome);
384
388
  return new OpenAI({
385
389
  baseURL: provider.baseURL,
386
390
  apiKey,
@@ -838,6 +842,17 @@ parentStats) {
838
842
  * then advised removing the attachment — to people whose request contained no image at all. The
839
843
  * cheapest way to stop asserting it was to be able to check it.
840
844
  */
845
+ /** The key a run will use, as a fingerprint and a source. Never the key. Never throws. */
846
+ export function describeCredential(config) {
847
+ try {
848
+ const provider = resolveProvider(config.provider, config.baseURL);
849
+ const seen = keyProvenance(provider, config.apiKey, config.stateHome);
850
+ return seen.found ? `${seen.fingerprint}, from ${seen.source}` : seen.source;
851
+ }
852
+ catch {
853
+ return undefined;
854
+ }
855
+ }
841
856
  export function carriesImage(messages) {
842
857
  return messages.some(m => Array.isArray(m.content)
843
858
  && m.content.some(part => part?.type === 'image_url'));
@@ -1569,7 +1584,15 @@ detectedContext = { current: 0 }) {
1569
1584
  }
1570
1585
  if (spinner)
1571
1586
  spinner.fail('API error on turn ' + stats.turns);
1572
- throw new Error(describeProviderError(err, config.provider, config.model, { hadImage: carriesImage(messages) }), { cause: err });
1587
+ /*
1588
+ * Which credential this run used, said only when the failure is about credentials.
1589
+ *
1590
+ * A fingerprint, never the key. The failure that prompted it looked like a gateway problem
1591
+ * and was a question about which of two keys was in play — unanswerable from anything that
1592
+ * was printed, on either side.
1593
+ */
1594
+ const credential = describeCredential(config);
1595
+ throw new Error(describeProviderError(err, config.provider, config.model, { hadImage: carriesImage(messages), ...(credential ? { credential } : {}) }), { cause: err });
1573
1596
  }
1574
1597
  if (spinner && !spinnerStopped)
1575
1598
  spinner.stop();
@@ -2336,7 +2359,7 @@ initialPlan) {
2336
2359
  const detectedContext = { current: 0 };
2337
2360
  if (!config.contextTokens) {
2338
2361
  const provider = resolveProvider(config.provider, config.baseURL);
2339
- void fetchModelContextLimit(provider.baseURL, config.apiKey ?? getApiKey(provider), config.model)
2362
+ void fetchModelContextLimit(provider.baseURL, config.apiKey ?? getApiKey(provider, undefined, config.stateHome), config.model)
2340
2363
  .then(reported => {
2341
2364
  if (!reported)
2342
2365
  return;