Skip to content

Commit 8c3e3d4

Browse files
committed
fix(agents): keep partial auth warm cache
1 parent 1b32038 commit 8c3e3d4

3 files changed

Lines changed: 49 additions & 17 deletions

File tree

src/agents/model-provider-auth.test.ts

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -477,8 +477,9 @@ describe("prepared provider auth state", () => {
477477
});
478478
});
479479

480-
it("skips off-main-thread warm when plugin synthetic auth lookup is incomplete", async () => {
480+
it("keeps off-main-thread warm partial when plugin synthetic auth lookup is incomplete", async () => {
481481
const cfg = {} as OpenClawConfig;
482+
authProfilesMocks.getRuntimeAuthProfileStoreSnapshot.mockReturnValue(undefined);
482483
modelAuthMocks.createRuntimeProviderAuthLookup.mockReturnValueOnce({
483484
envApiKey: {
484485
aliasMap: {},
@@ -492,7 +493,27 @@ describe("prepared provider auth state", () => {
492493

493494
await warmCurrentProviderAuthStateOffMainThread(cfg, { runWorker });
494495

495-
expect(runWorker).not.toHaveBeenCalled();
496+
expect(runWorker).toHaveBeenCalledWith({
497+
cfg,
498+
runtimeAuthLookups: [
499+
{
500+
agentId: "default",
501+
lookup: {
502+
envApiKey: {
503+
aliasMap: {},
504+
candidateMap: {},
505+
authEvidenceMap: {},
506+
},
507+
syntheticAuthProviderRefs: [],
508+
syntheticAuthProviderRefsComplete: false,
509+
},
510+
},
511+
],
512+
omitFalseProviderAuth: true,
513+
timeoutMs: 120_000,
514+
isCancelled: expect.any(Function),
515+
workerUrl: undefined,
516+
});
496517
});
497518

498519
it("terminates the off-main-thread warm worker when cancellation fires", async () => {

src/agents/model-provider-auth.ts

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ type ProviderAuthWarmWorkerRunner = (params: {
7171
cfg: OpenClawConfig;
7272
runtimeAuthStores?: ProviderAuthWarmRuntimeAuthStore[];
7373
runtimeAuthLookups?: ProviderAuthWarmRuntimeAuthLookup[];
74+
omitFalseProviderAuth?: boolean;
7475
timeoutMs: number;
7576
isCancelled: () => boolean;
7677
workerUrl?: URL;
@@ -319,6 +320,7 @@ export async function buildCurrentProviderAuthStateSnapshot(
319320
isCancelled?: () => boolean;
320321
readOnlyAuthStore?: boolean;
321322
runtimeAuthLookups?: ReadonlyMap<string, RuntimeProviderAuthLookup>;
323+
omitFalseProviderAuth?: boolean;
322324
} = {},
323325
): Promise<ProviderAuthWarmSnapshot> {
324326
const isWarmStale = () => options.isCancelled?.() === true;
@@ -380,11 +382,12 @@ export async function buildCurrentProviderAuthStateSnapshot(
380382
});
381383
if (
382384
!value &&
383-
shouldOmitFalsePreparedAuthForProcessSyntheticProvider({
384-
cfg,
385-
provider,
386-
runtimeAuthLookup,
387-
})
385+
(options.omitFalseProviderAuth ||
386+
shouldOmitFalsePreparedAuthForProcessSyntheticProvider({
387+
cfg,
388+
provider,
389+
runtimeAuthLookup,
390+
}))
388391
) {
389392
continue;
390393
}
@@ -510,27 +513,30 @@ function collectProviderAuthWarmRuntimeAuthStores(
510513
return entries;
511514
}
512515

513-
function collectProviderAuthWarmRuntimeAuthLookups(
514-
cfg: OpenClawConfig,
515-
): ProviderAuthWarmRuntimeAuthLookup[] | null {
516+
function collectProviderAuthWarmRuntimeAuthLookups(cfg: OpenClawConfig): {
517+
entries: ProviderAuthWarmRuntimeAuthLookup[];
518+
omitFalseProviderAuth: boolean;
519+
} {
516520
const entries: ProviderAuthWarmRuntimeAuthLookup[] = [];
521+
let omitFalseProviderAuth = false;
517522
for (const agentId of listAgentIds(cfg)) {
518523
const lookup = createRuntimeProviderAuthLookup({
519524
cfg,
520525
workspaceDir: resolveAgentWorkspaceDir(cfg, agentId),
521526
});
522527
if (lookup.syntheticAuthProviderRefsComplete === false) {
523-
return null;
528+
omitFalseProviderAuth = true;
524529
}
525530
entries.push({ agentId, lookup });
526531
}
527-
return entries;
532+
return { entries, omitFalseProviderAuth };
528533
}
529534

530535
function runProviderAuthWarmWorker(params: {
531536
cfg: OpenClawConfig;
532537
runtimeAuthStores?: ProviderAuthWarmRuntimeAuthStore[];
533538
runtimeAuthLookups?: ProviderAuthWarmRuntimeAuthLookup[];
539+
omitFalseProviderAuth?: boolean;
534540
timeoutMs: number;
535541
isCancelled: () => boolean;
536542
workerUrl?: URL;
@@ -542,6 +548,7 @@ function runProviderAuthWarmWorker(params: {
542548
...(params.runtimeAuthLookups?.length
543549
? { runtimeAuthLookups: params.runtimeAuthLookups }
544550
: {}),
551+
...(params.omitFalseProviderAuth ? { omitFalseProviderAuth: true } : {}),
545552
},
546553
});
547554
worker.unref?.();
@@ -651,13 +658,13 @@ export async function warmCurrentProviderAuthStateOffMainThread(
651658
}
652659
const runtimeAuthStores = collectProviderAuthWarmRuntimeAuthStores(cfg);
653660
const runtimeAuthLookups = collectProviderAuthWarmRuntimeAuthLookups(cfg);
654-
if (runtimeAuthLookups === null) {
655-
return;
656-
}
657661
const snapshot = await (options.runWorker ?? runProviderAuthWarmWorker)({
658662
cfg,
659663
...(runtimeAuthStores.length ? { runtimeAuthStores } : {}),
660-
...(runtimeAuthLookups.length ? { runtimeAuthLookups } : {}),
664+
...(runtimeAuthLookups.entries.length
665+
? { runtimeAuthLookups: runtimeAuthLookups.entries }
666+
: {}),
667+
...(runtimeAuthLookups.omitFalseProviderAuth ? { omitFalseProviderAuth: true } : {}),
661668
timeoutMs: options.timeoutMs ?? PROVIDER_AUTH_WARM_WORKER_TIMEOUT_MS,
662669
isCancelled: isWarmStale,
663670
workerUrl: options.workerUrl,

src/agents/model-provider-auth.worker.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ type ProviderAuthWarmWorkerInput = {
1616
agentId: string;
1717
lookup: RuntimeProviderAuthLookup;
1818
}>;
19+
omitFalseProviderAuth?: boolean;
1920
};
2021

2122
type ProviderAuthWarmWorkerResult =
@@ -36,7 +37,9 @@ function isWorkerInput(value: unknown): value is ProviderAuthWarmWorkerInput {
3637
(!("runtimeAuthStores" in value) ||
3738
Array.isArray((value as { runtimeAuthStores?: unknown }).runtimeAuthStores)) &&
3839
(!("runtimeAuthLookups" in value) ||
39-
Array.isArray((value as { runtimeAuthLookups?: unknown }).runtimeAuthLookups))
40+
Array.isArray((value as { runtimeAuthLookups?: unknown }).runtimeAuthLookups)) &&
41+
(!("omitFalseProviderAuth" in value) ||
42+
typeof (value as { omitFalseProviderAuth?: unknown }).omitFalseProviderAuth === "boolean")
4043
);
4144
}
4245

@@ -58,6 +61,7 @@ export async function runProviderAuthWarmWorkerInput(
5861
runtimeAuthLookups: new Map(
5962
input.runtimeAuthLookups?.map(({ agentId, lookup }) => [agentId, lookup]),
6063
),
64+
omitFalseProviderAuth: input.omitFalseProviderAuth,
6165
});
6266
return {
6367
status: "ok",

0 commit comments

Comments
 (0)