MCPcopy Index your code
hub / github.com/codehamr/codehamr / Pack

Function Pack

internal/ctx/ctx.go:140–188  ·  view source on GitHub ↗

Pack keeps whole messages newest-first until the budget is full, then returns them chronologically. The newest message is always kept, even if it alone exceeds the budget. Two clean-up passes then keep the wire well-formed: dropDanglingToolCalls drops an assistant whose tool_calls weren't all answer

(history []Message, budget int)

Source from the content-addressed store, hash-verified

138// last, rewriting any surviving system note to a user message: the wire is always
139// prefixed by the embedded system prompt, so a fourth shape (a second, non-leading
140// system message) 400s strict backends, and that note is only ever a soft-nudge.
141func Pack(history []Message, budget int) PackResult {
142 kept := make([]Message, 0, len(history))
143 used := 0
144 // walk newest to oldest
145 for i := len(history) - 1; i >= 0; i-- {
146 cost := history[i].Tokens()
147 if len(kept) > 0 && used+cost > budget {
148 break
149 }
150 kept = append(kept, history[i])
151 used += cost
152 }
153 slices.Reverse(kept)
154 // Dangling assistant first: dropping it can orphan its partial tool results,
155 // which the following dropOrphanTools pass then cleans up.
156 kept = dropDanglingToolCalls(kept)
157 kept = dropOrphanTools(kept)
158 // The cleanup passes can lose the current turn's tool exchange when the
159 // newest tool result's owning assistant fell just past the budget cut: the
160 // budget walk keeps the lone tool result (plus any trailing system nudge),
161 // then the orphan drop removes it, so the next request would silently lose
162 // the whole conversation mid-turn (reachable on small-ctx profiles after a
163 // big tool output). Keyed on "nothing substantive survived", NOT on
164 // len(kept)==0: a failure/runaway nudge (or the empty assistant reply the
165 // empty-reply nudge answers) survives the cleanup as the sole keeper and
166 // would otherwise mask exactly this loss - and nothing substantive
167 // surviving already implies the newest tool result didn't. A surviving
168 // user message or real assistant reply instead means the conversation
169 // moved past the exchange, ordinary budget trimming, no over-budget
170 // resurrection. Recover the newest assistant+tool-results group whole,
171 // over budget if need be, with the same deliberately-over-budget
172 // guarantee a newest user message already gets.
173 if i := newestToolIndex(history); i >= 0 && onlyNonSubstantive(kept) {
174 // Recover the group over budget, then re-run the same two passes the
175 // normal path uses: a partially-answered parallel set (owner issued c1,c2
176 // but only c1 came back before an abort) would otherwise reach the wire as
177 // a dangling assistant and 400 every backend. Fully-answered groups pass
178 // through untouched; an unpairable partial empties to nothing. Survivors
179 // in kept are all newer than the recovered group (the budget walk keeps a
180 // suffix), so prepending keeps the order chronological.
181 group := newestToolGroup(history[:i+1])
182 group = dropDanglingToolCalls(group)
183 group = dropOrphanTools(group)
184 kept = append(group, kept...)
185 }
186 kept = anchorUserMessage(kept, history)
187 kept = demoteSystemMessages(kept)
188 return PackResult{Messages: kept}
189}
190
191// anchorUserMessage guarantees the packed window carries a user-role message

Calls 8

dropDanglingToolCallsFunction · 0.85
dropOrphanToolsFunction · 0.85
newestToolIndexFunction · 0.85
onlyNonSubstantiveFunction · 0.85
newestToolGroupFunction · 0.85
anchorUserMessageFunction · 0.85
demoteSystemMessagesFunction · 0.85
TokensMethod · 0.80