


























@@ -7,7 +7,10 @@ const mocks = vi.hoisted(() => ({
77loadAuthProfileStoreWithoutExternalProfiles: vi.fn(),
88resolveAuthProfileOrder: vi.fn(),
99resolveAuthProfileDisplayLabel: vi.fn(),
10-resolveUsableCustomProviderApiKey: vi.fn(() => null),
10+resolveProviderEntryApiKeyProfileReference: vi.fn<() => unknown>(() => ({ kind: "none" })),
11+resolveUsableCustomProviderApiKey: vi.fn<() => { apiKey: string; source: string } | null>(
12+() => null,
13+),
1114resolveEnvApiKey: vi.fn<() => { apiKey: string; source: string } | null>(() => null),
1215readClaudeCliCredentialsCached: vi.fn<(options?: unknown) => unknown>(() => null),
1316readCodexCliCredentialsCached: vi.fn<(options?: unknown) => unknown>(() => null),
@@ -22,6 +25,7 @@ vi.mock("./auth-profiles.js", () => ({
2225}));
23262427vi.mock("./model-auth.js", () => ({
28+resolveProviderEntryApiKeyProfileReference: mocks.resolveProviderEntryApiKeyProfileReference,
2529resolveUsableCustomProviderApiKey: mocks.resolveUsableCustomProviderApiKey,
2630resolveEnvApiKey: mocks.resolveEnvApiKey,
2731}));
@@ -39,6 +43,8 @@ describe("resolveModelAuthLabel", () => {
3943mocks.loadAuthProfileStoreWithoutExternalProfiles.mockReset();
4044mocks.resolveAuthProfileOrder.mockReset();
4145mocks.resolveAuthProfileDisplayLabel.mockReset();
46+mocks.resolveProviderEntryApiKeyProfileReference.mockReset();
47+mocks.resolveProviderEntryApiKeyProfileReference.mockReturnValue({ kind: "none" });
4248mocks.resolveUsableCustomProviderApiKey.mockReset();
4349mocks.resolveUsableCustomProviderApiKey.mockReturnValue(null);
4450mocks.resolveEnvApiKey.mockReset();
@@ -255,4 +261,65 @@ describe("resolveModelAuthLabel", () => {
255261workspaceDir: "/tmp/workspace",
256262});
257263});
264+265+it("shows per-entry apiKey profile-reference labels before literal models.json fallback", () => {
266+const store = {
267+version: 1,
268+profiles: {
269+"openrouter:key-b": {
270+type: "api_key",
271+provider: "openrouter",
272+key: "sk-or-actual-key-b",
273+},
274+},
275+};
276+mocks.ensureAuthProfileStore.mockReturnValue(store as never);
277+mocks.resolveAuthProfileOrder.mockReturnValue([]);
278+mocks.resolveAuthProfileDisplayLabel.mockReturnValue("openrouter:key-b");
279+mocks.resolveProviderEntryApiKeyProfileReference.mockReturnValue({
280+kind: "profile",
281+profileId: "openrouter:key-b",
282+credential: store.profiles["openrouter:key-b"],
283+mode: "api-key",
284+});
285+mocks.resolveUsableCustomProviderApiKey.mockReturnValue({
286+apiKey: "openrouter:key-b",
287+source: "models.json",
288+});
289+290+const label = resolveModelAuthLabel({
291+provider: "openrouter-minimax",
292+cfg: {},
293+});
294+295+expect(label).toBe("api-key (openrouter:key-b)");
296+expect(mocks.resolveUsableCustomProviderApiKey).not.toHaveBeenCalled();
297+});
298+299+it("does not report incompatible per-entry profile references as literal models.json keys", () => {
300+mocks.ensureAuthProfileStore.mockReturnValue({
301+version: 1,
302+profiles: {},
303+} as never);
304+mocks.resolveAuthProfileOrder.mockReturnValue([]);
305+mocks.resolveProviderEntryApiKeyProfileReference.mockReturnValue({
306+kind: "profile-incompatible",
307+profileId: "google:oauth-a",
308+credentialProvider: "google",
309+credentialType: "oauth",
310+reason: "credential-class",
311+});
312+mocks.resolveUsableCustomProviderApiKey.mockReturnValue({
313+apiKey: "google:oauth-a",
314+source: "models.json",
315+});
316+317+const label = resolveModelAuthLabel({
318+provider: "openrouter-minimax",
319+cfg: {},
320+});
321+322+expect(label).toBe("unknown");
323+expect(mocks.resolveUsableCustomProviderApiKey).not.toHaveBeenCalled();
324+});
258325});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。