Skip to content

Commit 8562ccc

Browse files
committed
refactor isIgnoredUserMessage contract
Move the user-role guard into the helper so callers can use it consistently across message flows. Add a regression test to keep non-user messages from being treated as ignored.
1 parent ee9ac10 commit 8562ccc

File tree

10 files changed

+57
-11
lines changed

10 files changed

+57
-11
lines changed

lib/commands/context.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ function analyzeTokens(state: SessionState, messages: WithParts[]): TokenBreakdo
134134
const isCompacted = isMessageCompacted(state, msg)
135135
const pruneEntry = state.prune.messages.byMessageId.get(msg.info.id)
136136
const isMessagePruned = !!pruneEntry && pruneEntry.activeBlockIds.length > 0
137-
const isIgnoredUser = msg.info.role === "user" && isIgnoredUserMessage(msg)
137+
const isIgnoredUser = isIgnoredUserMessage(msg)
138138

139139
for (const part of parts) {
140140
if (part.type === "tool") {

lib/compress/message-utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ function resolveMessage(
142142
!!rawMessage &&
143143
!!messageId &&
144144
searchContext.rawIndexById.has(messageId) &&
145-
!(rawMessage.info.role === "user" && isIgnoredUserMessage(rawMessage))
145+
!isIgnoredUserMessage(rawMessage)
146146
if (!hasBoundary) {
147147
throw new SoftIssue(
148148
`messageId ${parsed.ref} is not available in the current conversation context. Choose an injected mNNNN ID visible in context.`,

lib/compress/pipeline.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ export async function finalizeSession(
8888
const params = getCurrentParams(ctx.state, rawMessages, ctx.logger)
8989
const totalSessionTokens = getCurrentTokenUsage(ctx.state, rawMessages)
9090
const sessionMessageIds = rawMessages
91-
.filter((msg) => !(msg.info.role === "user" && isIgnoredUserMessage(msg)))
91+
.filter((msg) => !isIgnoredUserMessage(msg))
9292
.map((msg) => msg.info.id)
9393

9494
await sendCompressNotification(

lib/compress/search.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ export function resolveSelection(
126126
if (!rawMessage) {
127127
continue
128128
}
129-
if (rawMessage.info.role === "user" && isIgnoredUserMessage(rawMessage)) {
129+
if (isIgnoredUserMessage(rawMessage)) {
130130
continue
131131
}
132132

@@ -221,7 +221,7 @@ function buildBoundaryLookup(
221221
if (!rawMessage) {
222222
continue
223223
}
224-
if (rawMessage.info.role === "user" && isIgnoredUserMessage(rawMessage)) {
224+
if (isIgnoredUserMessage(rawMessage)) {
225225
continue
226226
}
227227

@@ -244,7 +244,7 @@ function buildBoundaryLookup(
244244
if (!anchorMessage) {
245245
continue
246246
}
247-
if (anchorMessage.info.role === "user" && isIgnoredUserMessage(anchorMessage)) {
247+
if (isIgnoredUserMessage(anchorMessage)) {
248248
continue
249249
}
250250

lib/message-ids.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ export function assignMessageRefs(state: SessionState, messages: WithParts[]): n
121121
let skippedSubAgentPrompt = false
122122

123123
for (const message of messages) {
124-
if (message.info.role === "user" && isIgnoredUserMessage(message)) {
124+
if (isIgnoredUserMessage(message)) {
125125
continue
126126
}
127127

lib/messages/inject/inject.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ export const injectMessageIds = (
147147
}
148148

149149
for (const message of messages) {
150-
if (message.info.role === "user" && isIgnoredUserMessage(message)) {
150+
if (isIgnoredUserMessage(message)) {
151151
continue
152152
}
153153

lib/messages/inject/utils.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ export function getIterationNudgeThreshold(config: PluginConfig): number {
3535
export function findLastNonIgnoredMessage(messages: WithParts[]): LastNonIgnoredMessage | null {
3636
for (let i = messages.length - 1; i >= 0; i--) {
3737
const message = messages[i]
38-
if (message.info.role === "user" && isIgnoredUserMessage(message)) {
38+
if (isIgnoredUserMessage(message)) {
3939
continue
4040
}
4141
return { message, index: i }
@@ -49,7 +49,7 @@ export function countMessagesAfterIndex(messages: WithParts[], index: number): n
4949

5050
for (let i = index + 1; i < messages.length; i++) {
5151
const message = messages[i]
52-
if (message.info.role === "user" && isIgnoredUserMessage(message)) {
52+
if (isIgnoredUserMessage(message)) {
5353
continue
5454
}
5555
count++

lib/messages/priority.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export function buildPriorityMap(
2828
const priorities: CompressionPriorityMap = new Map()
2929

3030
for (const message of messages) {
31-
if (message.info.role === "user" && isIgnoredUserMessage(message)) {
31+
if (isIgnoredUserMessage(message)) {
3232
continue
3333
}
3434

lib/messages/utils.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,10 @@ export function buildToolIdList(state: SessionState, messages: WithParts[]): str
142142
}
143143

144144
export const isIgnoredUserMessage = (message: WithParts): boolean => {
145+
if (message.info.role !== "user") {
146+
return false
147+
}
148+
145149
const parts = Array.isArray(message.parts) ? message.parts : []
146150
if (parts.length === 0) {
147151
return true

tests/message-utils.test.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import assert from "node:assert/strict"
2+
import test from "node:test"
3+
import { isIgnoredUserMessage } from "../lib/messages/utils"
4+
import type { WithParts } from "../lib/state"
5+
6+
function buildMessage(role: "user" | "assistant", parts: WithParts["parts"]): WithParts {
7+
const sessionID = "ses_message_utils"
8+
9+
const info =
10+
role === "user"
11+
? {
12+
id: `msg-${role}`,
13+
role,
14+
sessionID,
15+
agent: "assistant",
16+
model: {
17+
providerID: "anthropic",
18+
modelID: "claude-test",
19+
},
20+
time: { created: 1 },
21+
}
22+
: {
23+
id: `msg-${role}`,
24+
role,
25+
sessionID,
26+
agent: "assistant",
27+
time: { created: 1 },
28+
}
29+
30+
return {
31+
info: info as WithParts["info"],
32+
parts,
33+
}
34+
}
35+
36+
test("isIgnoredUserMessage only ignores user messages", () => {
37+
const ignoredUserMessage = buildMessage("user", [])
38+
const assistantMessage = buildMessage("assistant", [])
39+
40+
assert.equal(isIgnoredUserMessage(ignoredUserMessage), true)
41+
assert.equal(isIgnoredUserMessage(assistantMessage), false)
42+
})

0 commit comments

Comments
 (0)