MCPcopy
hub / github.com/codeaashu/claude-code / groupMessagesByApiRound

Function groupMessagesByApiRound

src/services/compact/grouping.ts:22–63  ·  view source on GitHub ↗
(messages: Message[])

Source from the content-addressed store, hash-verified

20 * a latent ws CJS/ESM resolution race in CI shard-2.
21 */
22export function groupMessagesByApiRound(messages: Message[]): Message[][] {
23 const groups: Message[][] = []
24 let current: Message[] = []
25 // message.id of the most recently seen assistant. This is the sole
26 // boundary gate: streaming chunks from the same API response share an
27 // id, so boundaries only fire at the start of a genuinely new round.
28 // normalizeMessages yields one AssistantMessage per content block, and
29 // StreamingToolExecutor interleaves tool_results between chunks live
30 // (yield order, not concat order — see query.ts:613). The id check
31 // correctly keeps `[tu_A(id=X), result_A, tu_B(id=X)]` in one group.
32 let lastAssistantId: string | undefined
33
34 // In a well-formed conversation the API contract guarantees every
35 // tool_use is resolved before the next assistant turn, so lastAssistantId
36 // alone is a sufficient boundary gate. Tracking unresolved tool_use IDs
37 // would only do work when the conversation is malformed (dangling tool_use
38 // after resume-from-partial-batch or max_tokens truncation) — and in that
39 // case it pins the gate shut forever, merging all subsequent rounds into
40 // one group. We let those boundaries fire; the summarizer fork's own
41 // ensureToolResultPairing at claude.ts:1136 repairs the dangling tu at
42 // API time.
43 for (const msg of messages) {
44 if (
45 msg.type === 'assistant' &&
46 msg.message.id !== lastAssistantId &&
47 current.length > 0
48 ) {
49 groups.push(current)
50 current = [msg]
51 } else {
52 current.push(msg)
53 }
54 if (msg.type === 'assistant') {
55 lastAssistantId = msg.message.id
56 }
57 }
58
59 if (current.length > 0) {
60 groups.push(current)
61 }
62 return groups
63}
64

Callers 1

truncateHeadForPTLRetryFunction · 0.85

Calls 1

pushMethod · 0.45

Tested by

no test coverage detected