(text: string, maxLen: number)
| 531 | }; |
| 532 | |
| 533 | const truncateBySections = (text: string, maxLen: number): { text: string; dropped: number } => { |
| 534 | if (text.length <= maxLen) return { text, dropped: 0 }; |
| 535 | const sections = splitMarkdownSections(text); |
| 536 | if (sections.length === 1) { |
| 537 | const slice = text.slice(0, maxLen - 1).trimEnd() + "…"; |
| 538 | return { text: slice, dropped: 0 }; |
| 539 | } |
| 540 | |
| 541 | const kept: string[] = []; |
| 542 | let total = 0; |
| 543 | let dropped = 0; |
| 544 | for (const sec of sections) { |
| 545 | const cost = (kept.length ? 2 : 0) + sec.length; |
| 546 | if (total + cost > maxLen) { |
| 547 | dropped += 1; |
| 548 | continue; |
| 549 | } |
| 550 | kept.push(sec); |
| 551 | total += cost; |
| 552 | } |
| 553 | const out = kept.join("\n\n").trim(); |
| 554 | return { text: out || text.slice(0, maxLen - 1).trimEnd() + "…", dropped }; |
| 555 | }; |
| 556 | |
| 557 | const buildQuestionWithContext = (turns: ContextTurn[], userQuestion: string): { finalQuestion: string; dropped: number } => { |
| 558 | if (!turns.length) return { finalQuestion: userQuestion, dropped: 0 }; |
no test coverage detected