Skip to content

Commit 2dc15e1

Browse files
committed
prioritize compress tool messages
Keep completed compress calls visible as high-priority message targets so message-mode guidance preserves them consistently.
1 parent 592a5dd commit 2dc15e1

File tree

6 files changed

+64
-26
lines changed

6 files changed

+64
-26
lines changed

lib/messages/inject/inject.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import type { PluginConfig } from "../../config"
44
import type { RuntimePrompts } from "../../prompts/store"
55
import { formatMessageIdTag } from "../../message-ids"
66
import type { CompressionPriorityMap } from "../priority"
7-
import { compressPermission, getLastUserMessage } from "../../shared-utils"
7+
import { compressPermission, getLastUserMessage, messageHasCompress } from "../../shared-utils"
88
import { saveSessionState } from "../../state/persistence"
99
import {
1010
appendToTextPart,
@@ -22,7 +22,6 @@ import {
2222
getNudgeFrequency,
2323
getModelInfo,
2424
isContextOverLimits,
25-
messageHasCompress,
2625
} from "./utils"
2726

2827
export const injectCompressNudges = (

lib/messages/inject/utils.ts

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -58,14 +58,6 @@ export function countMessagesAfterIndex(messages: WithParts[], index: number): n
5858
return count
5959
}
6060

61-
export function messageHasCompress(message: WithParts): boolean {
62-
const parts = Array.isArray(message.parts) ? message.parts : []
63-
return parts.some(
64-
(part) =>
65-
part.type === "tool" && part.state.status === "completed" && part.tool === "compress",
66-
)
67-
}
68-
6961
export function getModelInfo(messages: WithParts[]): LastUserModelContext {
7062
const lastUserMessage = getLastUserMessage(messages)
7163
if (!lastUserMessage) {

lib/messages/priority.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { PluginConfig } from "../config"
22
import { countAllMessageTokens } from "../strategies/utils"
3-
import { isMessageCompacted } from "../shared-utils"
3+
import { isMessageCompacted, messageHasCompress } from "../shared-utils"
44
import type { SessionState, WithParts } from "../state"
55
import { isIgnoredUserMessage, isProtectedUserMessage } from "./utils"
66

@@ -54,7 +54,7 @@ export function buildPriorityMap(
5454
priorities.set(rawMessageId, {
5555
ref,
5656
tokenCount,
57-
priority: classifyMessagePriority(tokenCount),
57+
priority: messageHasCompress(message) ? "high" : classifyMessagePriority(tokenCount),
5858
})
5959
}
6060

lib/shared-utils.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,18 @@ export const getLastUserMessage = (
2828
return null
2929
}
3030

31+
export const messageHasCompress = (message: WithParts): boolean => {
32+
if (message.info.role !== "assistant") {
33+
return false
34+
}
35+
36+
const parts = Array.isArray(message.parts) ? message.parts : []
37+
return parts.some(
38+
(part) =>
39+
part.type === "tool" && part.tool === "compress" && part.state?.status === "completed",
40+
)
41+
}
42+
3143
export const compressPermission = (
3244
state: SessionState,
3345
config: PluginConfig,

lib/state/utils.ts

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import type {
55
SessionState,
66
WithParts,
77
} from "./types"
8-
import { isMessageCompacted } from "../shared-utils"
8+
import { isMessageCompacted, messageHasCompress } from "../shared-utils"
99
import { isIgnoredUserMessage } from "../messages/utils"
1010

1111
interface PersistedPruneMessagesState {
@@ -236,26 +236,14 @@ export function loadPruneMessagesState(
236236
return state
237237
}
238238

239-
function hasCompletedCompress(message: WithParts): boolean {
240-
if (message.info.role !== "assistant") {
241-
return false
242-
}
243-
244-
const parts = Array.isArray(message.parts) ? message.parts : []
245-
return parts.some(
246-
(part) =>
247-
part.type === "tool" && part.tool === "compress" && part.state?.status === "completed",
248-
)
249-
}
250-
251239
export function collectTurnNudgeAnchors(messages: WithParts[]): Set<string> {
252240
const anchors = new Set<string>()
253241
let pendingUserMessageId: string | null = null
254242

255243
for (let i = messages.length - 1; i >= 0; i--) {
256244
const message = messages[i]
257245

258-
if (hasCompletedCompress(message)) {
246+
if (messageHasCompress(message)) {
259247
break
260248
}
261249

tests/message-priority.test.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,53 @@ test("injectMessageIds tags every text part and tool output in range mode", () =
333333
assert.match((assistantToolTwo as any).state.output, /<dcp-message-id>m0002<\/dcp-message-id>/)
334334
})
335335

336+
test("message mode marks compress tool messages as high priority even when short", () => {
337+
const sessionID = "ses_message_compress_high_priority"
338+
const messages: WithParts[] = [
339+
buildMessage("msg-user-1", "user", sessionID, "Please compress this chunk.", 1),
340+
{
341+
info: {
342+
id: "msg-assistant-1",
343+
role: "assistant",
344+
sessionID,
345+
agent: "assistant",
346+
time: { created: 2 },
347+
} as WithParts["info"],
348+
parts: [
349+
textPart("msg-assistant-1", sessionID, "msg-assistant-1-part-1", "Done."),
350+
toolPart(
351+
"msg-assistant-1",
352+
sessionID,
353+
"call-compress-1",
354+
"compress",
355+
"[Compressed conversation section]",
356+
),
357+
],
358+
},
359+
]
360+
const state = createSessionState()
361+
const config = buildConfig()
362+
363+
assignMessageRefs(state, messages)
364+
const compressionPriorities = buildPriorityMap(config, state, messages)
365+
366+
assert.equal(compressionPriorities.get("msg-assistant-1")?.priority, "high")
367+
368+
injectMessageIds(state, config, messages, compressionPriorities)
369+
370+
const assistantText = messages[1]?.parts[0]
371+
const assistantTool = messages[1]?.parts[1]
372+
373+
assert.match(
374+
(assistantText as any).text,
375+
/\n\n<dcp-message-id priority="high">m0002<\/dcp-message-id>/,
376+
)
377+
assert.match(
378+
(assistantTool as any).state.output,
379+
/<dcp-message-id priority="high">m0002<\/dcp-message-id>/,
380+
)
381+
})
382+
336383
test("message-mode nudges append to existing text parts and list only earlier visible high-priority message IDs", () => {
337384
const sessionID = "ses_message_priority_nudges"
338385
const messages: WithParts[] = [

0 commit comments

Comments
 (0)