fix: refresh Pi credential readiness
This commit is contained in:
@@ -117,7 +117,7 @@ export function createPiManagement(config: AppConfig, deps: PiManagementDeps): P
|
||||
return piProviderCredentialStatus({
|
||||
provider,
|
||||
authProviders: loadPiAuthProviders(),
|
||||
credentialValue: secretValue(config, "THT_MODEL_API_KEY"),
|
||||
resolveCredentialValue: () => secretValue(config, "THT_MODEL_API_KEY"),
|
||||
credentialFile: config.modelApiKeyFile,
|
||||
});
|
||||
} catch {
|
||||
|
||||
@@ -179,7 +179,7 @@ export function buildPiChildEnv(opts: {
|
||||
export function piProviderCredentialStatus(opts: {
|
||||
provider?: string;
|
||||
credentialFile?: string;
|
||||
credentialValue?: string;
|
||||
resolveCredentialValue?: () => string | undefined;
|
||||
authProviders?: ReadonlySet<string>;
|
||||
fsOps?: CredentialFsOps;
|
||||
}): PiCredentialStatus {
|
||||
@@ -187,7 +187,14 @@ export function piProviderCredentialStatus(opts: {
|
||||
if (!provider || LOCAL_PROVIDERS.has(provider)) return "missing";
|
||||
if (opts.authProviders?.has(provider)) return "present";
|
||||
try {
|
||||
buildPiChildEnv({ ...opts, ambient: {} });
|
||||
buildPiChildEnv({
|
||||
ambient: {},
|
||||
provider,
|
||||
credentialFile: opts.credentialFile,
|
||||
credentialValue: opts.resolveCredentialValue?.(),
|
||||
authProviders: opts.authProviders,
|
||||
fsOps: opts.fsOps,
|
||||
});
|
||||
return "present";
|
||||
} catch {
|
||||
return "missing";
|
||||
|
||||
@@ -135,15 +135,70 @@ test("credential status reports only present or missing without treating local p
|
||||
expect(piProviderCredentialStatus({
|
||||
provider: "deepseek",
|
||||
authProviders: new Set(["deepseek"]),
|
||||
credentialValue: "must-not-be-returned",
|
||||
resolveCredentialValue: () => "must-not-be-returned",
|
||||
})).toBe("present");
|
||||
expect(piProviderCredentialStatus({ provider: "deepseek" })).toBe("missing");
|
||||
expect(piProviderCredentialStatus({
|
||||
provider: "local-qwen",
|
||||
credentialValue: "must-not-be-returned",
|
||||
resolveCredentialValue: () => "must-not-be-returned",
|
||||
})).toBe("missing");
|
||||
});
|
||||
|
||||
// Catches the generic managed secret being read before providers that self-authenticate or need
|
||||
// no credential have been classified.
|
||||
test("credential status never resolves the generic secret for auth-store or local providers", () => {
|
||||
let secretReads = 0;
|
||||
const unreadableSecret = () => {
|
||||
secretReads += 1;
|
||||
throw new Error("unrelated generic secret is unreadable");
|
||||
};
|
||||
|
||||
expect(piProviderCredentialStatus({
|
||||
provider: "deepseek",
|
||||
authProviders: new Set(["deepseek"]),
|
||||
resolveCredentialValue: unreadableSecret,
|
||||
})).toBe("present");
|
||||
expect(piProviderCredentialStatus({
|
||||
provider: "local-qwen",
|
||||
resolveCredentialValue: unreadableSecret,
|
||||
})).toBe("missing");
|
||||
expect(secretReads).toBe(0);
|
||||
});
|
||||
|
||||
// Catches generic hosted providers skipping their managed-secret source or treating an absent or
|
||||
// unreadable source as credentialed.
|
||||
test("credential status resolves the generic secret only for providers that require it", () => {
|
||||
let presentReads = 0;
|
||||
expect(piProviderCredentialStatus({
|
||||
provider: "openai",
|
||||
resolveCredentialValue: () => {
|
||||
presentReads += 1;
|
||||
return "managed-openai-key";
|
||||
},
|
||||
})).toBe("present");
|
||||
expect(presentReads).toBe(1);
|
||||
|
||||
let missingReads = 0;
|
||||
expect(piProviderCredentialStatus({
|
||||
provider: "openai",
|
||||
resolveCredentialValue: () => {
|
||||
missingReads += 1;
|
||||
return undefined;
|
||||
},
|
||||
})).toBe("missing");
|
||||
expect(missingReads).toBe(1);
|
||||
|
||||
let unreadableReads = 0;
|
||||
expect(piProviderCredentialStatus({
|
||||
provider: "openai",
|
||||
resolveCredentialValue: () => {
|
||||
unreadableReads += 1;
|
||||
throw new Error("generic secret is unreadable");
|
||||
},
|
||||
})).toBe("missing");
|
||||
expect(unreadableReads).toBe(1);
|
||||
});
|
||||
|
||||
test("bundle value is injected without exposing bundle metadata to Pi", () => {
|
||||
const env = buildPiChildEnv({
|
||||
ambient: {
|
||||
|
||||
Reference in New Issue
Block a user