perf(agents): keep fallback auth store cold without sources

This commit is contained in:
Vincent Koc
2026-04-13 15:58:09 +01:00
parent 01d49cf32f
commit bfc77b0f45
2 changed files with 36 additions and 4 deletions

View File

@@ -7,6 +7,7 @@ import type { OpenClawConfig } from "../config/config.js";
import { resetLogger, setLoggerOverride } from "../logging/logger.js";
import { createWarnLogCapture } from "../logging/test-helpers/warn-log-capture.js";
import { AUTH_STORE_VERSION } from "./auth-profiles/constants.js";
import * as authProfileStoreModule from "./auth-profiles/store.js";
import { saveAuthProfileStore } from "./auth-profiles/store.js";
import type { AuthProfileStore } from "./auth-profiles/types.js";
import { isAnthropicBillingError } from "./live-auth-keys.js";
@@ -197,6 +198,32 @@ const MODEL_COOLDOWN_MESSAGE = "model_cooldown: All credentials for model gpt-5
const CONNECTION_ERROR_MESSAGE = "Connection error.";
describe("runWithModelFallback", () => {
it("skips auth store bootstrap when no auth profile sources exist", async () => {
const hasSourcesSpy = vi
.spyOn(authProfileStoreModule, "hasAnyAuthProfileStoreSource")
.mockReturnValue(false);
const ensureStoreSpy = vi.spyOn(authProfileStoreModule, "ensureAuthProfileStore");
const run = vi.fn().mockResolvedValueOnce("ok");
try {
const result = await runWithModelFallback({
cfg: makeCfg(),
provider: "openai",
model: "gpt-4.1-mini",
agentDir: "/tmp/openclaw-no-auth-profiles",
run,
});
expect(result.result).toBe("ok");
expect(hasSourcesSpy).toHaveBeenCalledWith("/tmp/openclaw-no-auth-profiles");
expect(ensureStoreSpy).not.toHaveBeenCalled();
expect(run).toHaveBeenCalledWith("openai", "gpt-4.1-mini");
} finally {
hasSourcesSpy.mockRestore();
ensureStoreSpy.mockRestore();
}
});
it("keeps openai gpt-5.3 codex on the openai provider before running", async () => {
const cfg = makeCfg();
const run = vi.fn().mockResolvedValueOnce("ok");

View File

@@ -8,7 +8,11 @@ import { createSubsystemLogger } from "../logging/subsystem.js";
import { normalizeOptionalString } from "../shared/string-coerce.js";
import { sanitizeForLog } from "../terminal/ansi.js";
import { resolveAuthProfileOrder } from "./auth-profiles/order.js";
import { ensureAuthProfileStore, loadAuthProfileStoreForRuntime } from "./auth-profiles/store.js";
import {
ensureAuthProfileStore,
hasAnyAuthProfileStoreSource,
loadAuthProfileStoreForRuntime,
} from "./auth-profiles/store.js";
import {
getSoonestCooldownExpiry,
isProfileInCooldown,
@@ -640,9 +644,10 @@ export async function runWithModelFallback<T>(params: {
model: params.model,
fallbacksOverride: params.fallbacksOverride,
});
const authStore = params.cfg
? ensureAuthProfileStore(params.agentDir, { allowKeychainPrompt: false })
: null;
const authStore =
params.cfg && hasAnyAuthProfileStoreSource(params.agentDir)
? ensureAuthProfileStore(params.agentDir, { allowKeychainPrompt: false })
: null;
const attempts: FallbackAttempt[] = [];
let lastError: unknown;
const cooldownProbeUsedProviders = new Set<string>();