fix: address codex review round 2
- spill-policy reserves the spill notice's byte cost inside maxInlineBytes, so the replacement (preview + notice) never exceeds the documented model-facing cap. When the notice alone fills the budget the preview is empty; when even a notice-only replacement is not smaller than the original, the inline result is kept (spilling would only add bytes). - retention TextRetainer trims an oversized single suffix chunk to the last suffixCap bytes on push, so tail/headTail retention stays bounded by suffixCap instead of retaining and re-copying the whole chunk in finish() — this is the spill preview path, which pushes the whole result as one chunk.
This commit is contained in:
@@ -355,6 +355,19 @@ export class TextRetainer {
|
||||
this.suffixHeld -= head.length
|
||||
head = this.suffixChunks[0]
|
||||
}
|
||||
// The head chunk can still hold leading bytes beyond the last `suffixCap`
|
||||
// — a single chunk LARGER than the window is retained whole by the loop
|
||||
// above (dropping the only chunk would leave < cap). Trim those leading
|
||||
// bytes so the accumulator (and finish()'s concat) stays bounded by
|
||||
// `suffixCap` instead of allocating/copying the full chunk again;
|
||||
// finish() only ever reads the last `suffixLen ≤ suffixCap` bytes, so this
|
||||
// drops nothing it would return. (head.length > excess by the loop
|
||||
// invariant `suffixHeld - head.length < suffixCap`, so the slice is non-empty.)
|
||||
if (head !== undefined && this.suffixHeld > this.suffixCap) {
|
||||
const excess = this.suffixHeld - this.suffixCap
|
||||
this.suffixChunks[0] = head.subarray(excess)
|
||||
this.suffixHeld -= excess
|
||||
}
|
||||
}
|
||||
|
||||
// Dropped = bytes that no side can keep. Compute cumulative omission the
|
||||
|
||||
Reference in New Issue
Block a user