feat: append workspace critical rules to compaction summary

- Add readWorkspaceContextForSummary() to extract Session Startup + Red Lines from AGENTS.md
- Inject workspace context into compaction summary (limited to 2000 chars)
- Export extractSections() from post-compaction-context.ts for reuse
- Ensures compaction summary includes core rules needed for recovery

Part 1 of post-compaction context injection feature.
This commit is contained in:
康熙
2026-02-16 21:06:08 +08:00
committed by Peter Steinberger
parent d0b33f23eb
commit c4f829411f
2 changed files with 44 additions and 1 deletions

View File

@@ -1,3 +1,5 @@
import fs from "node:fs";
import path from "node:path";
import type { AgentMessage } from "@mariozechner/pi-agent-core";
import type { ExtensionAPI, FileOperations } from "@mariozechner/pi-coding-agent";
import {
@@ -11,6 +13,7 @@ import {
resolveContextWindowTokens,
summarizeInStages,
} from "../compaction.js";
import { extractSections } from "../../auto-reply/reply/post-compaction-context.js";
import { getCompactionSafeguardRuntime } from "./compaction-safeguard-runtime.js";
const FALLBACK_SUMMARY =
"Summary unavailable due to context limits. Older messages were truncated.";
@@ -158,6 +161,40 @@ function formatFileOperations(readFiles: string[], modifiedFiles: string[]): str
return `\n\n${sections.join("\n\n")}`;
}
/**
* Read and format critical workspace context for compaction summary.
* Extracts "Session Startup" and "Red Lines" from AGENTS.md.
* Limited to 2000 chars to avoid bloating the summary.
*/
async function readWorkspaceContextForSummary(): Promise<string> {
const MAX_SUMMARY_CONTEXT_CHARS = 2000;
const workspaceDir = process.cwd();
const agentsPath = path.join(workspaceDir, "AGENTS.md");
try {
if (!fs.existsSync(agentsPath)) {
return "";
}
const content = await fs.promises.readFile(agentsPath, "utf-8");
const sections = extractSections(content, ["Session Startup", "Red Lines"]);
if (sections.length === 0) {
return "";
}
const combined = sections.join("\n\n");
const safeContent =
combined.length > MAX_SUMMARY_CONTEXT_CHARS
? combined.slice(0, MAX_SUMMARY_CONTEXT_CHARS) + "\n...[truncated]..."
: combined;
return `\n\n<workspace-critical-rules>\n${safeContent}\n</workspace-critical-rules>`;
} catch {
return "";
}
}
export default function compactionSafeguardExtension(api: ExtensionAPI): void {
api.on("session_before_compact", async (event, ctx) => {
const { preparation, customInstructions, signal } = event;
@@ -309,6 +346,12 @@ export default function compactionSafeguardExtension(api: ExtensionAPI): void {
summary += toolFailureSection;
summary += fileOpsSummary;
// Append workspace critical context (Session Startup + Red Lines from AGENTS.md)
const workspaceContext = await readWorkspaceContextForSummary();
if (workspaceContext) {
summary += workspaceContext;
}
return {
compaction: {
summary,