UNPKG

@adonis-agora/agent

Version:

Governed, durable-backed AI agent (chat + tool-calling + governance) for AdonisJS — part of the Agora ecosystem.

45 lines • 1.86 kB
/** * Split `text` into messages of at most `maxLength` characters, cutting where a reader would: at a * paragraph break, else a line break, else the end of a sentence, else a space — and only when * none of those falls past the first third of the window, mid-word. Whitespace at the cut is dropped; * empty pieces are never returned. */ export function splitMessage(text, maxLength) { if (!Number.isInteger(maxLength) || maxLength < 1) { throw new RangeError('maxLength must be a positive integer'); } const pieces = []; let rest = text.trim(); while (rest.length > maxLength) { const window = rest.slice(0, maxLength + 1); const floor = Math.floor(maxLength / 3); const cut = lastBreak(window, /\n\s*\n/g, floor) ?? lastBreak(window, /\n/g, floor) ?? lastBreak(window, /[.!?…](?=\s)/g, floor, true) ?? lastBreak(window, /\s/g, floor) ?? maxLength; const piece = rest.slice(0, cut).trimEnd(); if (piece.length > 0) pieces.push(piece); rest = rest.slice(cut).trimStart(); } if (rest.length > 0) pieces.push(rest); return pieces; } /** * Where the last match of `pattern` in `window` lets the text be cut, if that is past `floor`: * before the match, or after it (`keep` — a sentence keeps its full stop). `null` when there is none. */ function lastBreak(window, pattern, floor, keep = false) { let found = null; for (const match of window.matchAll(pattern)) { const index = match.index ?? 0; const at = keep ? index + match[0].length : index; // A cut must leave the piece within the limit (the window is one character longer). if (at > floor && at <= window.length - 1) found = at; } return found; } //# sourceMappingURL=split.js.map