perf(commands): trim sessions cold-path imports

This commit is contained in:
Vincent Koc
2026-04-14 23:59:03 +01:00
parent 1769fb2aa1
commit ed1dfe23d4
4 changed files with 159 additions and 54 deletions

View File

@@ -19,13 +19,15 @@ import {
resolveSessionStoreTargetsOrExit,
type SessionStoreTarget,
} from "./session-store-targets.js";
import {
resolveSessionDisplayDefaults,
resolveSessionDisplayModel,
} from "./sessions-display-model.js";
import {
formatSessionAgeCell,
formatSessionFlagsCell,
formatSessionKeyCell,
formatSessionModelCell,
resolveSessionDisplayDefaults,
resolveSessionDisplayModel,
SESSION_AGE_PAD,
SESSION_KEY_PAD,
SESSION_MODEL_PAD,
@@ -280,7 +282,7 @@ function renderStoreDryRunPlan(params: {
].join(" ");
params.runtime.log(rich ? theme.heading(header) : header);
for (const actionRow of params.actionRows) {
const model = resolveSessionDisplayModel(params.cfg, actionRow, params.displayDefaults);
const model = resolveSessionDisplayModel(params.cfg, actionRow);
const line = [
formatCleanupActionCell(actionRow.action, rich),
formatSessionKeyCell(actionRow.key, rich),

View File

@@ -0,0 +1,103 @@
import { DEFAULT_MODEL, DEFAULT_PROVIDER } from "../agents/defaults.js";
import { resolveAgentModelPrimaryValue } from "../config/model-input.js";
import type { OpenClawConfig } from "../config/types.openclaw.js";
type SessionDisplayModelRow = {
key: string;
model?: string;
modelProvider?: string;
modelOverride?: string;
providerOverride?: string;
};
type SessionDisplayDefaults = {
model: string;
};
function parseModelRef(raw: string, defaultProvider: string): { provider: string; model: string } {
const trimmed = raw.trim();
if (!trimmed) {
return { provider: defaultProvider, model: DEFAULT_MODEL };
}
const slashIndex = trimmed.indexOf("/");
if (slashIndex <= 0 || slashIndex === trimmed.length - 1) {
return { provider: defaultProvider, model: trimmed };
}
return {
provider: trimmed.slice(0, slashIndex).trim() || defaultProvider,
model: trimmed.slice(slashIndex + 1).trim() || DEFAULT_MODEL,
};
}
function resolveAgentPrimaryModel(
cfg: OpenClawConfig,
agentId: string | undefined,
): string | undefined {
if (!agentId) {
return undefined;
}
const agentConfig = cfg.agents?.list?.find((agent) => agent.id === agentId);
return resolveAgentModelPrimaryValue(agentConfig?.model);
}
function normalizeStoredOverrideModel(params: {
providerOverride?: string;
modelOverride?: string;
}): { providerOverride?: string; modelOverride?: string } {
const providerOverride = params.providerOverride?.trim();
const modelOverride = params.modelOverride?.trim();
if (!providerOverride || !modelOverride) {
return { providerOverride, modelOverride };
}
const providerPrefix = `${providerOverride.toLowerCase()}/`;
return {
providerOverride,
modelOverride: modelOverride.toLowerCase().startsWith(providerPrefix)
? modelOverride.slice(providerOverride.length + 1).trim() || modelOverride
: modelOverride,
};
}
function resolveDefaultModelRef(
cfg: OpenClawConfig,
agentId?: string,
): { provider: string; model: string } {
const primary =
resolveAgentPrimaryModel(cfg, agentId) ??
resolveAgentModelPrimaryValue(cfg.agents?.defaults?.model) ??
DEFAULT_MODEL;
return parseModelRef(primary, DEFAULT_PROVIDER);
}
export function resolveSessionDisplayDefaults(
cfg: OpenClawConfig,
agentId?: string,
): SessionDisplayDefaults {
return {
model: resolveDefaultModelRef(cfg, agentId).model,
};
}
export function resolveSessionDisplayModel(
cfg: OpenClawConfig,
row: SessionDisplayModelRow,
): string {
const agentId = row.key.startsWith("agent:") ? row.key.split(":")[1] : undefined;
const defaultRef = resolveDefaultModelRef(cfg, agentId);
const normalizedOverride = normalizeStoredOverrideModel({
providerOverride: row.providerOverride,
modelOverride: row.modelOverride,
});
if (normalizedOverride.modelOverride) {
return parseModelRef(
normalizedOverride.modelOverride,
normalizedOverride.providerOverride ?? defaultRef.provider,
).model;
}
if (row.model) {
return parseModelRef(row.model, row.modelProvider ?? defaultRef.provider).model;
}
return defaultRef.model;
}

View File

@@ -1,10 +1,5 @@
import { DEFAULT_MODEL, DEFAULT_PROVIDER } from "../agents/defaults.js";
import { resolveConfiguredModelRef } from "../agents/model-selection.js";
import type { SessionEntry } from "../config/sessions.js";
import type { OpenClawConfig } from "../config/types.openclaw.js";
import { resolveSessionModelRef } from "../gateway/session-utils.js";
import { formatTimeAgo } from "../infra/format-time/format-relative.ts";
import { parseAgentSessionKey } from "../routing/session-key.js";
import { theme } from "../terminal/theme.js";
export type SessionDisplayRow = {
@@ -72,29 +67,6 @@ export function toSessionDisplayRows(store: Record<string, SessionEntry>): Sessi
.toSorted((a, b) => (b.updatedAt ?? 0) - (a.updatedAt ?? 0));
}
export function resolveSessionDisplayDefaults(cfg: OpenClawConfig): SessionDisplayDefaults {
const resolved = resolveConfiguredModelRef({
cfg,
defaultProvider: DEFAULT_PROVIDER,
defaultModel: DEFAULT_MODEL,
});
return {
model: resolved.model ?? DEFAULT_MODEL,
};
}
export function resolveSessionDisplayModel(
cfg: OpenClawConfig,
row: Pick<
SessionDisplayRow,
"key" | "model" | "modelProvider" | "modelOverride" | "providerOverride"
>,
defaults: SessionDisplayDefaults,
): string {
const resolved = resolveSessionModelRef(cfg, row, parseAgentSessionKey(row.key)?.agentId);
return resolved.model ?? defaults.model;
}
function truncateSessionKey(key: string): string {
if (key.length <= SESSION_KEY_PAD) {
return key;

View File

@@ -1,20 +1,20 @@
import { lookupContextTokens } from "../agents/context.js";
import { DEFAULT_CONTEXT_TOKENS } from "../agents/defaults.js";
import { loadConfig } from "../config/config.js";
import { loadSessionStore, resolveFreshSessionTotalTokens } from "../config/sessions.js";
import { classifySessionKey } from "../gateway/session-utils.js";
import { info } from "../globals.js";
import { parseAgentSessionKey } from "../routing/session-key.js";
import { type RuntimeEnv, writeRuntimeJson } from "../runtime.js";
import { isRich, theme } from "../terminal/theme.js";
import { resolveSessionStoreTargetsOrExit } from "./session-store-targets.js";
import {
resolveSessionDisplayDefaults,
resolveSessionDisplayModel,
} from "./sessions-display-model.js";
import {
formatSessionAgeCell,
formatSessionFlagsCell,
formatSessionKeyCell,
formatSessionModelCell,
resolveSessionDisplayDefaults,
resolveSessionDisplayModel,
SESSION_AGE_PAD,
SESSION_KEY_PAD,
SESSION_MODEL_PAD,
@@ -30,6 +30,7 @@ type SessionRow = SessionDisplayRow & {
const AGENT_PAD = 10;
const KIND_PAD = 6;
const TOKENS_PAD = 20;
let contextLookupRuntimePromise: Promise<typeof import("../agents/context.js")> | null = null;
const formatKTokens = (value: number) => `${(value / 1000).toFixed(value >= 10_000 ? 0 : 1)}k`;
@@ -67,6 +68,28 @@ const formatTokensCell = (
return colorByPct(padded, pct, rich);
};
async function lookupContextTokensForDisplay(model: string): Promise<number | undefined> {
contextLookupRuntimePromise ??= import("../agents/context.js");
const { lookupContextTokens } = await contextLookupRuntimePromise;
return lookupContextTokens(model, { allowAsyncLoad: false });
}
function classifySessionKey(key: string, entry?: { chatType?: string | null }): SessionRow["kind"] {
if (key === "global") {
return "global";
}
if (key === "unknown") {
return "unknown";
}
if (entry?.chatType === "group" || entry?.chatType === "channel") {
return "group";
}
if (key.includes(":group:") || key.includes(":channel:")) {
return "group";
}
return "direct";
}
const formatKindCell = (kind: SessionRow["kind"], rich: boolean) => {
const label = kind.padEnd(KIND_PAD);
if (!rich) {
@@ -91,9 +114,10 @@ export async function sessionsCommand(
const aggregateAgents = opts.allAgents === true;
const cfg = loadConfig();
const displayDefaults = resolveSessionDisplayDefaults(cfg);
const configuredContextTokens = cfg.agents?.defaults?.contextTokens;
const configContextTokens =
cfg.agents?.defaults?.contextTokens ??
lookupContextTokens(displayDefaults.model, { allowAsyncLoad: false }) ??
configuredContextTokens ??
(await lookupContextTokensForDisplay(displayDefaults.model)) ??
DEFAULT_CONTEXT_TOKENS;
const targets = resolveSessionStoreTargetsOrExit({
cfg,
@@ -153,21 +177,24 @@ export async function sessionsCommand(
allAgents: aggregateAgents ? true : undefined,
count: rows.length,
activeMinutes: activeMinutes ?? null,
sessions: rows.map((r) => {
const model = resolveSessionDisplayModel(cfg, r, displayDefaults);
return {
...r,
totalTokens: resolveFreshSessionTotalTokens(r) ?? null,
totalTokensFresh:
typeof r.totalTokens === "number" ? r.totalTokensFresh !== false : false,
contextTokens:
r.contextTokens ??
lookupContextTokens(model, { allowAsyncLoad: false }) ??
configContextTokens ??
null,
model,
};
}),
sessions: await Promise.all(
rows.map(async (r) => {
const model = resolveSessionDisplayModel(cfg, r);
return {
...r,
totalTokens: resolveFreshSessionTotalTokens(r) ?? null,
totalTokensFresh:
typeof r.totalTokens === "number" ? r.totalTokensFresh !== false : false,
contextTokens:
r.contextTokens ??
configuredContextTokens ??
(await lookupContextTokensForDisplay(model)) ??
configContextTokens ??
null,
model,
};
}),
),
});
return;
}
@@ -203,10 +230,11 @@ export async function sessionsCommand(
runtime.log(rich ? theme.heading(header) : header);
for (const row of rows) {
const model = resolveSessionDisplayModel(cfg, row, displayDefaults);
const model = resolveSessionDisplayModel(cfg, row);
const contextTokens =
row.contextTokens ??
lookupContextTokens(model, { allowAsyncLoad: false }) ??
configuredContextTokens ??
(await lookupContextTokensForDisplay(model)) ??
configContextTokens;
const total = resolveFreshSessionTotalTokens(row);