fix: Found one regression in model-list availability heuristics for pr (#74524)

Co-authored-by: openclaw-clawsweeper[bot] <280122609+openclaw-clawsweeper[bot]@users.noreply.github.com>
This commit is contained in:
clawsweeper[bot]
2026-04-29 14:07:42 -07:00
committed by GitHub
parent 22ea08997e
commit e4edefd0fc
2 changed files with 44 additions and 9 deletions

View File

@@ -1,4 +1,4 @@
import { describe, expect, it, vi } from "vitest";
import { beforeEach, describe, expect, it, vi } from "vitest";
import type { AuthProfileStore } from "../../agents/auth-profiles/types.js";
import { createModelListAuthIndex } from "./list.auth-index.js";
@@ -20,6 +20,21 @@ const pluginRegistryMocks = vi.hoisted(() => ({
),
}));
const envCandidateMocks = vi.hoisted(() => ({
resolveProviderEnvApiKeyCandidates: vi.fn(),
}));
vi.mock("../../agents/model-auth-env-vars.js", async (importOriginal) => {
const actual = await importOriginal<typeof import("../../agents/model-auth-env-vars.js")>();
envCandidateMocks.resolveProviderEnvApiKeyCandidates.mockImplementation(
actual.resolveProviderEnvApiKeyCandidates,
);
return {
...actual,
resolveProviderEnvApiKeyCandidates: envCandidateMocks.resolveProviderEnvApiKeyCandidates,
};
});
vi.mock("../../plugins/plugin-registry.js", async (importOriginal) => {
const actual = await importOriginal<typeof import("../../plugins/plugin-registry.js")>();
return {
@@ -47,6 +62,11 @@ function modelConfig(id: string) {
}
describe("createModelListAuthIndex", () => {
beforeEach(() => {
envCandidateMocks.resolveProviderEnvApiKeyCandidates.mockClear();
pluginRegistryMocks.loadPluginRegistrySnapshotWithMetadata.mockClear();
});
it("normalizes auth aliases from profiles", () => {
const index = createModelListAuthIndex({
cfg: {},
@@ -80,7 +100,8 @@ describe("createModelListAuthIndex", () => {
expect(index.hasProviderAuth("openai")).toBe(false);
});
it("uses manifest env metadata for google vertex auth", () => {
it("checks resolver-only env auth on demand", () => {
envCandidateMocks.resolveProviderEnvApiKeyCandidates.mockReturnValueOnce({});
const index = createModelListAuthIndex({
cfg: {},
authStore: emptyStore,

View File

@@ -58,6 +58,7 @@ export function createModelListAuthIndex(
const envCandidateMap = resolveProviderEnvApiKeyCandidates({ config: params.cfg, env });
const authenticatedProviders = new Set<string>();
const syntheticAuthProviders = new Set<string>();
const envProviderAuthCache = new Map<string, boolean>();
const addProvider = (provider: string | undefined) => {
if (!provider?.trim()) {
return;
@@ -81,11 +82,6 @@ export function createModelListAuthIndex(
addProvider(provider);
}
}
// Google Vertex ADC is still represented by resolveEnvApiKey's compatibility
// path. Move this into manifest auth signals once that contract exists.
if (resolveEnvApiKey("google-vertex", env, { aliasMap, candidateMap: envCandidateMap })) {
addProvider("google-vertex");
}
if (resolveAwsSdkEnvVarName(env)) {
addProvider("amazon-bedrock");
@@ -105,11 +101,29 @@ export function createModelListAuthIndex(
addSyntheticProvider(provider);
}
const hasEnvProviderAuth = (provider: string): boolean => {
const normalized = normalizeAuthProvider(provider, aliasMap);
const cached = envProviderAuthCache.get(normalized);
if (cached !== undefined) {
return cached;
}
const hasAuth = Boolean(
resolveEnvApiKey(provider, env, { aliasMap, candidateMap: envCandidateMap }),
);
envProviderAuthCache.set(normalized, hasAuth);
if (hasAuth) {
authenticatedProviders.add(normalized);
}
return hasAuth;
};
return {
hasProviderAuth(provider: string): boolean {
const normalizedProvider = normalizeAuthProvider(provider, aliasMap);
return (
authenticatedProviders.has(normalizeAuthProvider(provider, aliasMap)) ||
syntheticAuthProviders.has(normalizeProviderIdForAuth(provider))
authenticatedProviders.has(normalizedProvider) ||
syntheticAuthProviders.has(normalizeProviderIdForAuth(provider)) ||
hasEnvProviderAuth(provider)
);
},
};