fix(llm): let an interrogation use the credential its route already stored
A configuration surface never holds a stored secret — it edits a redacted descriptor — so once a key is saved, the draft it sends carries the route and the endpoint and no credential at all. The interrogation went out unauthenticated and the endpoint's 401 came back as "check the API key", pointing at the one thing that was fine. A named route now supplies its own credential, resolved exactly as a request to it would be. A key typed into the form still wins: it is the one under test, and may be the replacement for the stored one that is failing. Resolution is a callback the probe invokes past the catalog short-circuit and the protocol check, so a route answered from the installed registry costs no credential lookup — and cannot fail over a credential the question never needed.
This commit is contained in:
@@ -177,10 +177,26 @@ export function apply(ctx: Context, config: Config): void {
|
||||
directoryFacts = entries
|
||||
}
|
||||
ensureDirectory()
|
||||
/**
|
||||
* The credential a named route already resolves, for an interrogation whose
|
||||
* draft carries none. A route being declared for the first time names no
|
||||
* profile yet, and a profile that names no credential defers to pi-ai's own
|
||||
* discovery, so both answer `undefined` and the endpoint is asked
|
||||
* unauthenticated — the same posture a request to that route would take.
|
||||
*/
|
||||
const storedApiKey = async (provider: string | undefined): Promise<string | undefined> => {
|
||||
if (provider === undefined) return undefined
|
||||
const profile = profiles().get(provider)
|
||||
if (profile === undefined) return undefined
|
||||
return resolveApiKey(provider, profile)
|
||||
}
|
||||
// Interrogating an endpoint is a configuration-time action over a draft, so
|
||||
// it is offered for the whole namespace rather than per route: the provider
|
||||
// a surface is adding does not exist yet.
|
||||
ctx.llm.registerModelDiscovery(NS, discoverModels)
|
||||
// a surface is adding does not exist yet. The draft is the whole request
|
||||
// except the credential: a configuration surface edits a redacted descriptor
|
||||
// and never holds a stored secret, so an already-configured route supplies
|
||||
// its own here rather than being interrogated unauthenticated.
|
||||
ctx.llm.registerModelDiscovery(NS, request => discoverModels(request, () => storedApiKey(request.provider)))
|
||||
// Route effects bind to this apply fiber via the stable `ctx` reference,
|
||||
// even when a swap runs inside the scoped settings callback below. A bare
|
||||
// mount (zero routes) is the dormant posture: nothing registers until a
|
||||
|
||||
Reference in New Issue
Block a user