| 1210 | } |
| 1211 | |
| 1212 | func (b *blastOutputBuilder) Append(text, label string) bool { |
| 1213 | if b.remaining <= 0 { |
| 1214 | return false |
| 1215 | } |
| 1216 | if runeLen(text) <= b.remaining { |
| 1217 | b.builder.WriteString(text) |
| 1218 | b.remaining -= runeLen(text) |
| 1219 | return true |
| 1220 | } |
| 1221 | marker := fmt.Sprintf("\n... [%s omitted after total budget %d chars]\n", label, b.total) |
| 1222 | // Reserve room to close a code fence if truncation lands mid-block, so the |
| 1223 | // emitted markdown never has a dangling ``` opener. |
| 1224 | fenceClose := "\n```\n" |
| 1225 | fenceReserve := 0 |
| 1226 | if strings.Contains(text, "```") { |
| 1227 | fenceReserve = runeLen(fenceClose) |
| 1228 | } |
| 1229 | keep := b.remaining - runeLen(marker) - fenceReserve |
| 1230 | if keep < 0 { |
| 1231 | keep = 0 |
| 1232 | } |
| 1233 | kept := firstRunes(text, keep) |
| 1234 | b.builder.WriteString(kept) |
| 1235 | if strings.Count(kept, "```")%2 == 1 { |
| 1236 | b.builder.WriteString(fenceClose) |
| 1237 | } |
| 1238 | b.builder.WriteString(marker) |
| 1239 | b.remaining = 0 |
| 1240 | return false |
| 1241 | } |
| 1242 | |
| 1243 | func (b *blastOutputBuilder) String() string { |
| 1244 | return b.builder.String() |