UNPKG

@sema-agent/core

Version:

Stateless, task-oriented AI agent core

40 lines (39 loc) • 2.58 kB
/** * Code-point-boundary-safe head/tail slicing — the one arithmetic every head+tail-with-marker truncator in * this repo needs (`truncateError`, `clipWithFilePointer`, `truncateMcpErrorText`, `boundedString`, * `truncateForSummary`). * * Why this exists as its own module: cutting a string at a UTF-16 code-unit index can land BETWEEN the two * halves of an astral code point, and the result is a lone surrogate — a string that still satisfies the * length bound but can no longer round-trip through UTF-8 (JSON frames, log files, prompt assembly). The * same defect has been found and fixed one site at a time (RB-122 in `clipWithFilePointer`, then * `truncateError`, then the three siblings above), which is exactly the shape a shared primitive prevents. * * Anchored on CC 2.1.220 `A7e`'s helpers `ma` (head) / `_W` (tail): drop the straddling code point WHOLE * rather than emit half of it. Zero imports, so any module in the repo may depend on it without risking an * import cycle. * * NOTE for whoever next touches `src/core/tool-errors.ts`: that file still declares a byte-identical private * pair (`sliceHeadSafe`/`sliceTailSafe`, added by the earlier car in this class). Collapsing it onto this * module — delete the two private copies plus `isHighSurrogate`/`isLowSurrogate` and import from here — is * the remaining step to "one construction point"; it is outside this car's edit surface and is reported * rather than done here. */ /** High half of a surrogate pair (U+D800–U+DBFF): valid only when immediately FOLLOWED by a low half. */ export declare const isHighSurrogate: (c: number) => boolean; /** Low half of a surrogate pair (U+DC00–U+DFFF): valid only when immediately PRECEDED by a high half. */ export declare const isLowSurrogate: (c: number) => boolean; /** * Head-keep of at most `keep` code UNITS that never ends on a lone high surrogate — a code point straddling * the cut is dropped whole (CC 2.1.220 `ma`). * * Callers must derive any "how much was dropped" count from the RETURNED length, never from `keep`: when * the rollback fires the result is one unit SHORTER than the budget, and a count computed from `keep` * under-reports by that unit. */ export declare function sliceHeadSafe(s: string, keep: number): string; /** * Tail-keep counterpart: at most `keep` code units, never STARTING on a lone low surrogate (CC 2.1.220 * `_W`). Same rule for the caller's dropped-count arithmetic — read it off the returned length. */ export declare function sliceTailSafe(s: string, keep: number): string;