Skip to content

Commit d8da98b

Browse files
committed
feat(plugin): depth-aware compressor prompt for progressive U: line handling
Compressor prompt now adapts based on average compression depth: - depth < 2: preserve all U: lines exactly - depth 2-3: condense U: lines to core intent - depth 3+: fold U: intent into narrative prose System prompt updated to defer U: handling to per-request instructions. Logs now show depth tier alongside selection details.
1 parent 913f9b7 commit d8da98b

File tree

2 files changed

+44
-3
lines changed

2 files changed

+44
-3
lines changed

packages/plugin/src/hooks/magic-context/compartment-prompt.ts

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ You receive a set of compartments that are over budget. Your job is to merge and
102102
Rules:
103103
- You have full authority over which compartments to merge and which to keep separate.
104104
- Merged compartments must cover the same start-to-end range as the originals they replace.
105-
- Drop verbatim U: (user message) lines from merged compartments. Instead, summarize the user's key intent in the prose: "User directed X. Implemented Y."
105+
- Follow the U: line handling instructions in each request — they vary based on how many times these compartments have already been compressed.
106106
- Keep summaries outcome-focused. Mention file paths, function names, commit hashes, and config keys only when they matter conceptually.
107107
- You may merge 2-5 adjacent compartments into one broader compartment when they share a theme or phase of work.
108108
- You may keep a compartment separate but shorten its summary.
@@ -126,12 +126,39 @@ export function buildCompressorPrompt(
126126
}>,
127127
currentTokens: number,
128128
targetTokens: number,
129+
averageDepth = 0,
129130
): string {
130131
const lines: string[] = [];
131132
lines.push(
132133
`These ${compartments.length} compartments use approximately ${currentTokens} tokens. Compress them to approximately ${targetTokens} tokens.`,
133134
);
134135
lines.push("");
136+
137+
// Depth-aware U: message handling instructions
138+
if (averageDepth < 2) {
139+
lines.push(
140+
"These compartments contain U: lines showing what the user asked. Preserve ALL U: lines exactly as they are. Focus compression on the narrative prose — merge compartments, remove redundancy, condense descriptions. Do not modify or remove U: lines.",
141+
);
142+
} else if (averageDepth < 3) {
143+
lines.push(
144+
"These compartments have already been compressed multiple times. Condense each U: line to its core intent in one sentence, but keep them as separate U: lines. Focus aggressive compression on the narrative prose.",
145+
);
146+
} else {
147+
lines.push(
148+
"These compartments have been heavily compressed. Fold any remaining U: user intent into the narrative prose — do not keep separate U: lines. Write fluent summary paragraphs that naturally capture both what was asked and what was done.",
149+
);
150+
}
151+
lines.push("");
152+
153+
lines.push("Rules:");
154+
lines.push("- Merge adjacent compartments when they cover related work.");
155+
lines.push(
156+
"- Each output compartment must use the exact start/end ordinals from the input compartments it covers.",
157+
);
158+
lines.push("- Do not invent new ordinal boundaries that don't exist in the input.");
159+
lines.push("- Preserve commit hashes and key technical details where possible.");
160+
lines.push("");
161+
135162
for (const c of compartments) {
136163
lines.push(
137164
`<compartment start="${c.startMessage}" end="${c.endMessage}" title="${escapeXmlAttr(c.title)}">`,

packages/plugin/src/hooks/magic-context/compartment-runner-compressor.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,9 +171,20 @@ export async function runCompressionPassIfNeeded(deps: CompressorDeps): Promise<
171171
sessionId,
172172
`compressor: scored ${compartments.length} compartments, selected ${selectedCompartments.length} (avg_depth range: ${minAverageDepth.toFixed(1)}-${maxAverageDepth.toFixed(1)}, score range: ${minScore.toFixed(1)}-${maxScore.toFixed(1)})`,
173173
);
174+
// Compute overall average depth for the selected range (used for U: line handling)
175+
const overallAverageDepth =
176+
selectedScoredCompartments.reduce((sum, c) => sum + c.averageDepth, 0) /
177+
selectedScoredCompartments.length;
178+
const depthTier =
179+
overallAverageDepth < 2
180+
? "preserve U: lines"
181+
: overallAverageDepth < 3
182+
? "condense U: lines"
183+
: "fold U: into prose";
184+
174185
sessionLog(
175186
sessionId,
176-
`compressor: selected contiguous range ${selectedCompartments[0].startMessage}-${selectedCompartments[selectedCompartments.length - 1].endMessage} (~${selectedTokens} tokens), target ~${targetTokens} tokens`,
187+
`compressor: selected contiguous range ${selectedCompartments[0].startMessage}-${selectedCompartments[selectedCompartments.length - 1].endMessage} (~${selectedTokens} tokens), target ~${targetTokens} tokens, avg_depth=${overallAverageDepth.toFixed(1)} (${depthTier})`,
177188
);
178189

179190
try {
@@ -182,6 +193,7 @@ export async function runCompressionPassIfNeeded(deps: CompressorDeps): Promise<
182193
compartments: selectedCompartments,
183194
currentTokens: selectedTokens,
184195
targetTokens,
196+
averageDepth: overallAverageDepth,
185197
});
186198

187199
if (!compressed) {
@@ -290,6 +302,7 @@ interface CompressorPassArgs {
290302
compartments: Compartment[];
291303
currentTokens: number;
292304
targetTokens: number;
305+
averageDepth: number;
293306
historianTimeoutMs?: number;
294307
}
295308

@@ -308,10 +321,11 @@ async function runCompressorPass(args: CompressorPassArgs): Promise<Array<{
308321
compartments,
309322
currentTokens,
310323
targetTokens,
324+
averageDepth,
311325
historianTimeoutMs,
312326
} = args;
313327

314-
const prompt = buildCompressorPrompt(compartments, currentTokens, targetTokens);
328+
const prompt = buildCompressorPrompt(compartments, currentTokens, targetTokens, averageDepth);
315329

316330
let agentSessionId: string | null = null;
317331
try {

0 commit comments

Comments
 (0)