Skip to content

Commit 012cd7f

Browse files
committed
fix: cache session list model resolution (#77650) (thanks @ragesaq)
1 parent 24bd0b2 commit 012cd7f

2 files changed

Lines changed: 39 additions & 3 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,7 @@ Docs: https://docs.openclaw.ai
306306
- Security/Windows: route the `.cmd`/`.bat` process wrapper through the shared Windows install-root resolver instead of `process.env.ComSpec`, so workspace dotenv-blocked `SystemRoot`/`WINDIR` overrides and unsafe values like UNC paths or path-lists cannot redirect `cmd.exe` selection on Windows. (#77472) Thanks @drobison00.
307307
- Agents/bootstrap: honor `BOOTSTRAP.md` content injected by `agent:bootstrap` hooks when deciding whether bootstrap is pending, so hook-provided required setup instructions are included in the system prompt. (#77501) Thanks @ificator.
308308
- Agents/replay-history: drop trailing assistant turns whose content is empty or carries only the stream-error sentinel before sending the transcript to the provider, so prefill-strict providers (such as github-copilot/claude-opus-4.6) no longer reject the request with `400 The conversation must end with a user message` after a session whose last turn errored before producing content. Refs #77228. (#77287) Thanks @openperf.
309+
- Gateway/sessions: cache selected model override resolution while building session-list rows so `openclaw sessions` and Control UI session lists stay responsive on model-heavy stores. (#77650) Thanks @ragesaq.
309310

310311
## 2026.5.3-1
311312

src/gateway/session-utils.ts

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,7 @@ function shouldKeepStoreOnlyChildLink(entry: SessionEntry, now: number): boolean
372372
type SessionListRowContext = {
373373
subagentRuns: ReturnType<typeof buildSubagentRunReadIndex>;
374374
storeChildSessionsByKey: Map<string, string[]>;
375+
selectedModelByOverrideRef: Map<string, ReturnType<typeof resolveSessionModelRef>>;
375376
thinkingLevelsByModelRef: Map<string, ReturnType<typeof listThinkingLevelOptions>>;
376377
};
377378

@@ -489,6 +490,7 @@ function buildSessionListRowContext(params: {
489490
return {
490491
subagentRuns,
491492
storeChildSessionsByKey: buildStoreChildSessionIndex(params.store, params.now, subagentRuns),
493+
selectedModelByOverrideRef: new Map(),
492494
thinkingLevelsByModelRef: new Map(),
493495
};
494496
}
@@ -497,6 +499,36 @@ function createSessionRowModelCacheKey(provider: string | undefined, model: stri
497499
return `${normalizeLowercaseStringOrEmpty(provider)}\0${normalizeOptionalString(model) ?? ""}`;
498500
}
499501

502+
function resolveSessionSelectedModelRef(params: {
503+
cfg: OpenClawConfig;
504+
entry?: SessionEntry;
505+
agentId: string;
506+
rowContext?: SessionListRowContext;
507+
}): ReturnType<typeof resolveSessionModelRef> | null {
508+
const override = normalizeStoredOverrideModel({
509+
providerOverride: params.entry?.providerOverride,
510+
modelOverride: params.entry?.modelOverride,
511+
});
512+
if (!override.modelOverride) {
513+
return null;
514+
}
515+
if (!params.rowContext) {
516+
return resolveSessionModelRef(params.cfg, params.entry, params.agentId);
517+
}
518+
const key = [
519+
normalizeAgentId(params.agentId),
520+
override.providerOverride ?? "",
521+
override.modelOverride,
522+
].join("\0");
523+
const cached = params.rowContext.selectedModelByOverrideRef.get(key);
524+
if (cached) {
525+
return cached;
526+
}
527+
const selected = resolveSessionModelRef(params.cfg, params.entry, params.agentId);
528+
params.rowContext.selectedModelByOverrideRef.set(key, selected);
529+
return selected;
530+
}
531+
500532
function resolveSessionRowThinkingLevels(params: {
501533
provider: string;
502534
model: string;
@@ -1540,9 +1572,12 @@ export function buildGatewaySessionRow(params: {
15401572
? resolveSessionRuntimeMs(subagentRun, now)
15411573
: undefined))
15421574
: undefined;
1543-
const selectedModel = entry?.modelOverride?.trim()
1544-
? resolveSessionModelRef(cfg, entry, sessionAgentId)
1545-
: null;
1575+
const selectedModel = resolveSessionSelectedModelRef({
1576+
cfg,
1577+
entry,
1578+
agentId: sessionAgentId,
1579+
rowContext,
1580+
});
15461581
const resolvedModel = resolveSessionModelIdentityRef(
15471582
cfg,
15481583
entry,

0 commit comments

Comments
 (0)