@sema-agent/core
Version:
Stateless, task-oriented AI agent core
40 lines (39 loc) • 2.58 kB
TypeScript
/**
* 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;