Config/Compaction: expose safeguard preserve and quality settings

This commit is contained in:
Rodrigo Uroz
2026-02-24 16:32:36 +00:00
parent d783ffb44d
commit 45a95d344e
6 changed files with 74 additions and 0 deletions

View File

@@ -82,6 +82,9 @@ export function buildEmbeddedExtensionFactories(params: {
maxHistoryShare: compactionCfg?.maxHistoryShare,
contextWindowTokens: contextWindowInfo.tokens,
model: params.model,
recentTurnsPreserve: compactionCfg?.recentTurnsPreserve,
qualityGuardEnabled: compactionCfg?.qualityGuard?.enabled,
qualityGuardMaxRetries: compactionCfg?.qualityGuard?.maxRetries,
});
factories.push(compactionSafeguardExtension);
}

View File

@@ -2,6 +2,8 @@ import type { AgentMessage } from "@mariozechner/pi-agent-core";
import type { Api, Model } from "@mariozechner/pi-ai";
import type { ExtensionAPI, ExtensionContext } from "@mariozechner/pi-coding-agent";
import { describe, expect, it, vi } from "vitest";
import type { OpenClawConfig } from "../../config/config.js";
import { buildEmbeddedExtensionFactories } from "../pi-embedded-runner/extensions.js";
import {
getCompactionSafeguardRuntime,
setCompactionSafeguardRuntime,
@@ -368,6 +370,39 @@ describe("compaction-safeguard runtime registry", () => {
model,
});
});
it("wires quality guard retries from config and clamps safeguard runtime usage", () => {
const sessionManager = {} as unknown as Parameters<
typeof buildEmbeddedExtensionFactories
>[0]["sessionManager"];
const cfg = {
agents: {
defaults: {
compaction: {
mode: "safeguard",
recentTurnsPreserve: 99,
qualityGuard: { maxRetries: 99 },
},
},
},
} as OpenClawConfig;
buildEmbeddedExtensionFactories({
cfg,
sessionManager,
provider: "anthropic",
modelId: "claude-3-opus",
model: {
contextWindow: 200_000,
} as Parameters<typeof buildEmbeddedExtensionFactories>[0]["model"],
});
const runtime = getCompactionSafeguardRuntime(sessionManager);
expect(runtime?.qualityGuardMaxRetries).toBe(99);
expect(runtime?.recentTurnsPreserve).toBe(99);
expect(resolveQualityGuardMaxRetries(runtime?.qualityGuardMaxRetries)).toBe(3);
expect(resolveRecentTurnsPreserve(runtime?.recentTurnsPreserve)).toBe(12);
});
});
describe("compaction-safeguard recent-turn preservation", () => {

View File

@@ -842,6 +842,14 @@ export const FIELD_HELP: Record<string, string> = {
"Requires at least this many newly appended bytes before session transcript changes trigger reindex (default: 100000). Increase to reduce frequent small reindexes, or lower for faster transcript freshness.",
"agents.defaults.memorySearch.sync.sessions.deltaMessages":
"Requires at least this many appended transcript messages before reindex is triggered (default: 50). Lower this for near-real-time transcript recall, or raise it to reduce indexing churn.",
"agents.defaults.compaction.recentTurnsPreserve":
"Number of most recent user/assistant turns kept verbatim outside safeguard summarization (default: 3). Raise this to preserve exact recent dialogue context, or lower it to maximize compaction savings.",
"agents.defaults.compaction.postIndexSync":
'Controls post-compaction session index sync mode: "off", "async", or "await" (default: "async"). Use "await" for strongest consistency, "async" for lower latency, and "off" only when downstream indexing is externally managed.',
"agents.defaults.compaction.qualityGuard.enabled":
"Enables safeguard summary quality validation and retry logic (default: true). Keep enabled to reduce malformed summaries; disable only when minimizing compaction latency is more important than summary structure checks.",
"agents.defaults.compaction.qualityGuard.maxRetries":
"Maximum additional safeguard summarization attempts after a failed quality audit (default: 1). Increase cautiously for better summary compliance at the cost of extra token usage and latency.",
ui: "UI presentation settings for accenting and assistant identity shown in control surfaces. Use this for branding and readability customization without changing runtime behavior.",
"ui.seamColor":
"Primary accent/seam color used by UI surfaces for emphasis, badges, and visual identity cues. Use high-contrast values that remain readable across light/dark themes.",

View File

@@ -311,6 +311,10 @@ export const FIELD_LABELS: Record<string, string> = {
"agents.defaults.memorySearch.sync.watchDebounceMs": "Memory Watch Debounce (ms)",
"agents.defaults.memorySearch.sync.sessions.deltaBytes": "Session Delta Bytes",
"agents.defaults.memorySearch.sync.sessions.deltaMessages": "Session Delta Messages",
"agents.defaults.compaction.recentTurnsPreserve": "Compaction Preserve Recent Turns",
"agents.defaults.compaction.postIndexSync": "Compaction Post-Index Sync",
"agents.defaults.compaction.qualityGuard.enabled": "Compaction Quality Guard",
"agents.defaults.compaction.qualityGuard.maxRetries": "Compaction Quality Guard Retries",
"agents.defaults.memorySearch.query.maxResults": "Memory Search Max Results",
"agents.defaults.memorySearch.query.minScore": "Memory Search Min Score",
"agents.defaults.memorySearch.query.hybrid.enabled": "Memory Search Hybrid",

View File

@@ -271,6 +271,12 @@ export type AgentCompactionConfig = {
reserveTokensFloor?: number;
/** Max share of context window for history during safeguard pruning (0.10.9, default 0.5). */
maxHistoryShare?: number;
/** Preserve this many most-recent user/assistant turns verbatim in compaction summary context. */
recentTurnsPreserve?: number;
/** Post-compaction memory session-index sync behavior. */
postIndexSync?: "off" | "async" | "await";
/** Post-compaction quality guard settings (safeguard mode). */
qualityGuard?: AgentCompactionQualityGuardConfig;
/** Pre-compaction memory flush (agentic turn). Default: enabled. */
memoryFlush?: AgentCompactionMemoryFlushConfig;
};
@@ -285,3 +291,10 @@ export type AgentCompactionMemoryFlushConfig = {
/** System prompt appended for the memory flush turn. */
systemPrompt?: string;
};
export type AgentCompactionQualityGuardConfig = {
/** Enable summary quality checks and automatic retry (default: true). */
enabled?: boolean;
/** Maximum retries when summary quality checks fail (default: 1). */
maxRetries?: number;
};

View File

@@ -84,6 +84,17 @@ export const AgentDefaultsSchema = z
keepRecentTokens: z.number().int().positive().optional(),
reserveTokensFloor: z.number().int().nonnegative().optional(),
maxHistoryShare: z.number().min(0.1).max(0.9).optional(),
recentTurnsPreserve: z.number().int().min(0).max(12).optional(),
postIndexSync: z
.union([z.literal("off"), z.literal("async"), z.literal("await")])
.optional(),
qualityGuard: z
.object({
enabled: z.boolean().optional(),
maxRetries: z.number().int().min(0).max(3).optional(),
})
.strict()
.optional(),
memoryFlush: z
.object({
enabled: z.boolean().optional(),