mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 07:10:43 +00:00
perf(commands): trim sessions cold-path imports
This commit is contained in:
@@ -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),
|
||||
|
||||
103
src/commands/sessions-display-model.ts
Normal file
103
src/commands/sessions-display-model.ts
Normal 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;
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user