fix(session): harden usage accounting and memory flush recovery

This commit is contained in:
Peter Steinberger
2026-03-02 00:06:52 +00:00
parent ee96e1751e
commit d729ab2150
9 changed files with 285 additions and 33 deletions

View File

@@ -2,11 +2,13 @@ import { lookupContextTokens } from "../../agents/context.js";
import { resolveCronStyleNow } from "../../agents/current-time.js";
import { DEFAULT_CONTEXT_TOKENS } from "../../agents/defaults.js";
import { DEFAULT_PI_COMPACTION_RESERVE_TOKENS_FLOOR } from "../../agents/pi-settings.js";
import { parseByteSize } from "../../cli/parse-bytes.js";
import type { OpenClawConfig } from "../../config/config.js";
import { resolveFreshSessionTotalTokens, type SessionEntry } from "../../config/sessions.js";
import { SILENT_REPLY_TOKEN } from "../tokens.js";
export const DEFAULT_MEMORY_FLUSH_SOFT_TOKENS = 4000;
export const DEFAULT_MEMORY_FLUSH_FORCE_TRANSCRIPT_BYTES = 2 * 1024 * 1024;
export const DEFAULT_MEMORY_FLUSH_PROMPT = [
"Pre-compaction memory flush.",
@@ -58,6 +60,11 @@ export function resolveMemoryFlushPromptForRun(params: {
export type MemoryFlushSettings = {
enabled: boolean;
softThresholdTokens: number;
/**
* Force a pre-compaction memory flush when the session transcript reaches this
* size. Set to 0 to disable byte-size based triggering.
*/
forceFlushTranscriptBytes: number;
prompt: string;
systemPrompt: string;
reserveTokensFloor: number;
@@ -71,6 +78,26 @@ const normalizeNonNegativeInt = (value: unknown): number | null => {
return int >= 0 ? int : null;
};
const normalizeOptionalByteSize = (value: unknown): number | null => {
if (typeof value === "number" && Number.isFinite(value)) {
const int = Math.floor(value);
return int >= 0 ? int : null;
}
if (typeof value === "string") {
const trimmed = value.trim();
if (!trimmed) {
return null;
}
try {
const bytes = parseByteSize(trimmed, { defaultUnit: "b" });
return bytes >= 0 ? bytes : null;
} catch {
return null;
}
}
return null;
};
export function resolveMemoryFlushSettings(cfg?: OpenClawConfig): MemoryFlushSettings | null {
const defaults = cfg?.agents?.defaults?.compaction?.memoryFlush;
const enabled = defaults?.enabled ?? true;
@@ -79,6 +106,9 @@ export function resolveMemoryFlushSettings(cfg?: OpenClawConfig): MemoryFlushSet
}
const softThresholdTokens =
normalizeNonNegativeInt(defaults?.softThresholdTokens) ?? DEFAULT_MEMORY_FLUSH_SOFT_TOKENS;
const forceFlushTranscriptBytes =
normalizeOptionalByteSize(defaults?.forceFlushTranscriptBytes) ??
DEFAULT_MEMORY_FLUSH_FORCE_TRANSCRIPT_BYTES;
const prompt = defaults?.prompt?.trim() || DEFAULT_MEMORY_FLUSH_PROMPT;
const systemPrompt = defaults?.systemPrompt?.trim() || DEFAULT_MEMORY_FLUSH_SYSTEM_PROMPT;
const reserveTokensFloor =
@@ -88,6 +118,7 @@ export function resolveMemoryFlushSettings(cfg?: OpenClawConfig): MemoryFlushSet
return {
enabled,
softThresholdTokens,
forceFlushTranscriptBytes,
prompt: ensureNoReplyHint(prompt),
systemPrompt: ensureNoReplyHint(systemPrompt),
reserveTokensFloor,