Skip to content

Commit 9d1f053

Browse files
committed
batch compress tool inputs
1 parent 08c7fcd commit 9d1f053

File tree

10 files changed

+450
-238
lines changed

10 files changed

+450
-238
lines changed

lib/config.ts

Lines changed: 0 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ export interface CompressConfig {
2323
nudgeFrequency: number
2424
iterationNudgeThreshold: number
2525
nudgeForce: "strong" | "soft"
26-
flatSchema: boolean
2726
protectedTools: string[]
2827
protectUserMessages: boolean
2928
}
@@ -38,10 +37,6 @@ export interface ManualModeConfig {
3837
automaticStrategies: boolean
3938
}
4039

41-
export interface SupersedeWrites {
42-
enabled: boolean
43-
}
44-
4540
export interface PurgeErrors {
4641
enabled: boolean
4742
turns: number
@@ -71,7 +66,6 @@ export interface PluginConfig {
7166
compress: CompressConfig
7267
strategies: {
7368
deduplication: Deduplication
74-
supersedeWrites: SupersedeWrites
7569
purgeErrors: PurgeErrors
7670
}
7771
}
@@ -124,15 +118,12 @@ export const VALID_CONFIG_KEYS = new Set([
124118
"compress.nudgeFrequency",
125119
"compress.iterationNudgeThreshold",
126120
"compress.nudgeForce",
127-
"compress.flatSchema",
128121
"compress.protectedTools",
129122
"compress.protectUserMessages",
130123
"strategies",
131124
"strategies.deduplication",
132125
"strategies.deduplication.enabled",
133126
"strategies.deduplication.protectedTools",
134-
"strategies.supersedeWrites",
135-
"strategies.supersedeWrites.enabled",
136127
"strategies.purgeErrors",
137128
"strategies.purgeErrors.enabled",
138129
"strategies.purgeErrors.turns",
@@ -404,14 +395,6 @@ export function validateConfigTypes(config: Record<string, any>): ValidationErro
404395
})
405396
}
406397

407-
if (compress.flatSchema !== undefined && typeof compress.flatSchema !== "boolean") {
408-
errors.push({
409-
key: "compress.flatSchema",
410-
expected: "boolean",
411-
actual: typeof compress.flatSchema,
412-
})
413-
}
414-
415398
if (compress.protectedTools !== undefined && !Array.isArray(compress.protectedTools)) {
416399
errors.push({
417400
key: "compress.protectedTools",
@@ -547,19 +530,6 @@ export function validateConfigTypes(config: Record<string, any>): ValidationErro
547530
})
548531
}
549532

550-
if (strategies.supersedeWrites) {
551-
if (
552-
strategies.supersedeWrites.enabled !== undefined &&
553-
typeof strategies.supersedeWrites.enabled !== "boolean"
554-
) {
555-
errors.push({
556-
key: "strategies.supersedeWrites.enabled",
557-
expected: "boolean",
558-
actual: typeof strategies.supersedeWrites.enabled,
559-
})
560-
}
561-
}
562-
563533
if (strategies.purgeErrors) {
564534
if (
565535
strategies.purgeErrors.enabled !== undefined &&
@@ -685,7 +655,6 @@ const defaultConfig: PluginConfig = {
685655
nudgeFrequency: 5,
686656
iterationNudgeThreshold: 15,
687657
nudgeForce: "soft",
688-
flatSchema: false,
689658
protectedTools: [...COMPRESS_DEFAULT_PROTECTED_TOOLS],
690659
protectUserMessages: false,
691660
},
@@ -694,9 +663,6 @@ const defaultConfig: PluginConfig = {
694663
enabled: true,
695664
protectedTools: [],
696665
},
697-
supersedeWrites: {
698-
enabled: true,
699-
},
700666
purgeErrors: {
701667
enabled: true,
702668
turns: 4,
@@ -821,9 +787,6 @@ function mergeStrategies(
821787
]),
822788
],
823789
},
824-
supersedeWrites: {
825-
enabled: override.supersedeWrites?.enabled ?? base.supersedeWrites.enabled,
826-
},
827790
purgeErrors: {
828791
enabled: override.purgeErrors?.enabled ?? base.purgeErrors.enabled,
829792
turns: override.purgeErrors?.turns ?? base.purgeErrors.turns,
@@ -856,7 +819,6 @@ function mergeCompress(
856819
nudgeFrequency: override.nudgeFrequency ?? base.nudgeFrequency,
857820
iterationNudgeThreshold: override.iterationNudgeThreshold ?? base.iterationNudgeThreshold,
858821
nudgeForce: override.nudgeForce ?? base.nudgeForce,
859-
flatSchema: override.flatSchema ?? base.flatSchema,
860822
protectedTools: [...new Set([...base.protectedTools, ...(override.protectedTools ?? [])])],
861823
protectUserMessages: override.protectUserMessages ?? base.protectUserMessages,
862824
}
@@ -925,7 +887,6 @@ function deepCloneConfig(config: PluginConfig): PluginConfig {
925887
...config.strategies.deduplication,
926888
protectedTools: [...config.strategies.deduplication.protectedTools],
927889
},
928-
supersedeWrites: { ...config.strategies.supersedeWrites },
929890
purgeErrors: {
930891
...config.strategies.purgeErrors,
931892
protectedTools: [...config.strategies.purgeErrors.protectedTools],

lib/prompts/compress-message.ts

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -48,21 +48,6 @@ BATCHING
4848
Do not call the tool once per message. Select MANY messages in a single tool call when they are independently safe to compress.
4949
Each entry should summarize exactly one message, and the tool can receive as many entries as needed in one batch.
5050
51-
THE FORMAT OF MESSAGE COMPRESS
52-
53-
~~~json
54-
{
55-
"topic": "overall batch label",
56-
"content": [
57-
{
58-
"messageId": "m0001",
59-
"topic": "short message label",
60-
"summary": "Complete technical summary replacing that one message"
61-
}
62-
]
63-
}
64-
~~~
65-
6651
Because each message is compressed independently:
6752
6853
- Do not describe ranges

lib/prompts/compress-range.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,6 @@ Rules:
7979
- Prefer boundaries that produce short, closed ranges.
8080
- Do not invent IDs. Use only IDs that are present in context.
8181
82-
PARALLEL COMPRESS EXECUTION
83-
When multiple independent ranges are ready and their boundaries do not overlap, launch MULTIPLE \`compress\` calls in parallel in a single response. This is the PREFERRED pattern over a single large-range compression when the work can be safely split. Run compression sequentially only when ranges overlap or when a later range depends on the result of an earlier compression.
82+
BATCHING
83+
Do not call the tool once per range. When multiple independent ranges are ready and their boundaries do not overlap, include all of them as separate entries in the \`content\` array of a single tool call. Each entry should have its own \`startId\`, \`endId\`, and \`summary\`.
8484
`

lib/prompts/internal-overlays.ts

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,28 +18,34 @@ All subsequent messages in the session will have IDs.
1818
</dcp-system-reminder>
1919
`
2020

21-
export const NESTED_FORMAT_OVERLAY = `
21+
export const RANGE_FORMAT_OVERLAY = `
2222
THE FORMAT OF COMPRESS
2323
2424
\`\`\`
2525
{
2626
topic: string, // Short label (3-5 words) - e.g., "Auth System Exploration"
27-
content: {
28-
startId: string, // Boundary ID at range start: mNNNN or bN
29-
endId: string, // Boundary ID at range end: mNNNN or bN
30-
summary: string // Complete technical summary replacing all content in range
31-
}
27+
content: [ // One or more ranges to compress
28+
{
29+
startId: string, // Boundary ID at range start: mNNNN or bN
30+
endId: string, // Boundary ID at range end: mNNNN or bN
31+
summary: string // Complete technical summary replacing all content in range
32+
}
33+
]
3234
}
3335
\`\`\``
3436

35-
export const FLAT_FORMAT_OVERLAY = `
37+
export const MESSAGE_FORMAT_OVERLAY = `
3638
THE FORMAT OF COMPRESS
3739
3840
\`\`\`
3941
{
40-
topic: string, // Short label (3-5 words) - e.g., "Auth System Exploration"
41-
startId: string, // Boundary ID at range start: mNNNN or bN
42-
endId: string, // Boundary ID at range end: mNNNN or bN
43-
summary: string // Complete technical summary replacing all content in range
42+
topic: string, // Short label (3-5 words) for the overall batch
43+
content: [ // One or more messages to compress independently
44+
{
45+
messageId: string, // Raw message ID only: mNNNN
46+
topic: string, // Short label (3-5 words) for this one message summary
47+
summary: string // Complete technical summary replacing that one message
48+
}
49+
]
4450
}
4551
\`\`\``

lib/tools/compress-message.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import {
1010
fetchSessionMessages,
1111
formatCompressMessageIssues,
1212
formatCompressMessageResult,
13-
COMPRESSED_BLOCK_HEADER,
1413
resolveMessageCompressions,
1514
validateCompressMessageArgs,
1615
type CompressMessageToolArgs,
@@ -21,8 +20,8 @@ import { getCurrentParams, getCurrentTokenUsage, countTokens } from "../strategi
2120
import { deduplicate, purgeErrors } from "../strategies"
2221
import { saveSessionState } from "../state/persistence"
2322
import { sendCompressNotification } from "../ui/notification"
23+
import { MESSAGE_FORMAT_OVERLAY } from "../prompts/internal-overlays"
2424

25-
// Non-primitive arrays are hidden in the TUI, so keep the schema simple and explicit.
2625
function buildSchema() {
2726
return {
2827
topic: tool.schema
@@ -53,7 +52,7 @@ export function createCompressMessageTool(ctx: ToolContext): ReturnType<typeof t
5352
const runtimePrompts = ctx.prompts.getRuntimePrompts()
5453

5554
return tool({
56-
description: runtimePrompts.compressMessage,
55+
description: runtimePrompts.compressMessage + MESSAGE_FORMAT_OVERLAY,
5756
args: buildSchema(),
5857
async execute(args, toolCtx) {
5958
if (ctx.state.manualMode && ctx.state.manualMode !== "compress-pending") {
@@ -109,6 +108,11 @@ export function createCompressMessageTool(ctx: ToolContext): ReturnType<typeof t
109108
summaryTokens: number
110109
}> = []
111110

111+
const preparedPlans: Array<{
112+
plan: (typeof plans)[number]
113+
summaryWithProtectedTools: string
114+
}> = []
115+
112116
for (const plan of plans) {
113117
const summaryWithProtectedTools = await appendProtectedTools(
114118
ctx.client,
@@ -121,6 +125,13 @@ export function createCompressMessageTool(ctx: ToolContext): ReturnType<typeof t
121125
ctx.config.protectedFilePatterns,
122126
)
123127

128+
preparedPlans.push({
129+
plan,
130+
summaryWithProtectedTools,
131+
})
132+
}
133+
134+
for (const { plan, summaryWithProtectedTools } of preparedPlans) {
124135
const blockId = allocateBlockId(ctx.state)
125136
const storedSummary = wrapCompressedSummary(blockId, summaryWithProtectedTools)
126137
const summaryTokens = countTokens(storedSummary)

0 commit comments

Comments
 (0)