fix(compaction): inject workspace context into summarization
The compaction system was creating context-blind summaries because the summarization LLM never saw the workspace context files (AGENTS.md, TOOLS.md, MEMORY.md, etc.). While contextFiles were correctly resolved during session creation, they were not passed through to the summarization call chain. This fix: - Extends CompactionSafeguardRuntimeValue type to include workspaceContext - Serializes contextFiles in compact.ts and stores them in the runtime - Retrieves and injects workspace context into summarization instructions in compaction-safeguard.ts The summarizing LLM now receives the actual workspace file contents, allowing it to generate summaries that preserve: - User identity and preferences - Agent identity and capabilities - Tool configurations and infrastructure - Ongoing work items and project context This is a proper architectural fix replacing the previous heuristic approach that only added generic hints to the instructions. Fixes context loss after compaction in workspace-aware sessions.
This commit is contained in:
parent
5f4715acfc
commit
5ca0224fed
@ -69,6 +69,7 @@ import type { EmbeddedPiCompactResult } from "./types.js";
|
||||
import { formatUserTime, resolveUserTimeFormat, resolveUserTimezone } from "../date-time.js";
|
||||
import { describeUnknownError, mapThinkingLevel, resolveExecToolDefaults } from "./utils.js";
|
||||
import { buildTtsSystemPromptHint } from "../../tts/tts.js";
|
||||
import { setCompactionSafeguardRuntime } from "../pi-extensions/compaction-safeguard-runtime.js";
|
||||
|
||||
export type CompactEmbeddedPiSessionParams = {
|
||||
sessionId: string;
|
||||
@ -210,6 +211,12 @@ export async function compactEmbeddedPiSessionDirect(
|
||||
sessionId: params.sessionId,
|
||||
warn: makeBootstrapWarn({ sessionLabel, warn: (message) => log.warn(message) }),
|
||||
});
|
||||
|
||||
const workspaceContextForCompaction = contextFiles
|
||||
.filter((f) => f.content?.trim())
|
||||
.map((f) => `## ${f.path}\n${f.content}`)
|
||||
.join("\n\n---\n\n");
|
||||
|
||||
const runAbortController = new AbortController();
|
||||
const toolsRaw = createMoltbotCodingTools({
|
||||
exec: {
|
||||
@ -365,6 +372,10 @@ export async function compactEmbeddedPiSessionDirect(
|
||||
allowSyntheticToolResults: transcriptPolicy.allowSyntheticToolResults,
|
||||
});
|
||||
trackSessionManagerAccess(params.sessionFile);
|
||||
|
||||
setCompactionSafeguardRuntime(sessionManager, {
|
||||
workspaceContext: workspaceContextForCompaction || undefined,
|
||||
});
|
||||
const settingsManager = SettingsManager.create(effectiveWorkspace, agentDir);
|
||||
ensurePiCompactionReserveTokens({
|
||||
settingsManager,
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
export type CompactionSafeguardRuntimeValue = {
|
||||
maxHistoryShare?: number;
|
||||
workspaceContext?: string;
|
||||
};
|
||||
|
||||
// Session-scoped runtime registry keyed by object identity.
|
||||
|
||||
@ -177,6 +177,31 @@ export default function compactionSafeguardExtension(api: ExtensionAPI): void {
|
||||
|
||||
const runtime = getCompactionSafeguardRuntime(ctx.sessionManager);
|
||||
const maxHistoryShare = runtime?.maxHistoryShare ?? 0.5;
|
||||
const workspaceContext = runtime?.workspaceContext;
|
||||
|
||||
const buildEnhancedInstructions = (baseInstructions?: string): string | undefined => {
|
||||
if (!workspaceContext) {
|
||||
return baseInstructions;
|
||||
}
|
||||
const contextSection = `
|
||||
## Workspace Context Files
|
||||
The following files define this workspace's identity, user, and configuration:
|
||||
|
||||
${workspaceContext}
|
||||
|
||||
IMPORTANT: Your summary MUST preserve:
|
||||
- References to projects, tasks, and goals mentioned in these context files
|
||||
- User identity and preferences from USER.md
|
||||
- Agent identity and capabilities from SOUL.md or AGENTS.md
|
||||
- Tool configurations and infrastructure from TOOLS.md
|
||||
- Any ongoing work items referenced in MEMORY.md
|
||||
|
||||
The summary will be used to continue this work - ensure the next agent session understands WHO the user is, WHAT they're working on, and WHY.`;
|
||||
|
||||
return baseInstructions ? `${baseInstructions}\n\n${contextSection}` : contextSection;
|
||||
};
|
||||
|
||||
const enhancedCustomInstructions = buildEnhancedInstructions(customInstructions);
|
||||
|
||||
const tokensBefore =
|
||||
typeof preparation.tokensBefore === "number" && Number.isFinite(preparation.tokensBefore)
|
||||
@ -228,7 +253,7 @@ export default function compactionSafeguardExtension(api: ExtensionAPI): void {
|
||||
reserveTokens: Math.max(1, Math.floor(preparation.settings.reserveTokens)),
|
||||
maxChunkTokens: droppedMaxChunkTokens,
|
||||
contextWindow: contextWindowTokens,
|
||||
customInstructions,
|
||||
customInstructions: enhancedCustomInstructions,
|
||||
previousSummary: preparation.previousSummary,
|
||||
});
|
||||
} catch (droppedError) {
|
||||
@ -261,7 +286,7 @@ export default function compactionSafeguardExtension(api: ExtensionAPI): void {
|
||||
reserveTokens,
|
||||
maxChunkTokens,
|
||||
contextWindow: contextWindowTokens,
|
||||
customInstructions,
|
||||
customInstructions: enhancedCustomInstructions,
|
||||
previousSummary: effectivePreviousSummary,
|
||||
});
|
||||
|
||||
@ -275,7 +300,7 @@ export default function compactionSafeguardExtension(api: ExtensionAPI): void {
|
||||
reserveTokens,
|
||||
maxChunkTokens,
|
||||
contextWindow: contextWindowTokens,
|
||||
customInstructions: TURN_PREFIX_INSTRUCTIONS,
|
||||
customInstructions: buildEnhancedInstructions(TURN_PREFIX_INSTRUCTIONS),
|
||||
previousSummary: undefined,
|
||||
});
|
||||
summary = `${historySummary}\n\n---\n\n**Turn Context (split turn):**\n\n${prefixSummary}`;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user