37 lines
1.1 KiB
JavaScript
37 lines
1.1 KiB
JavaScript
/**
|
|
* Head+tail truncation with a recovery marker. No Bare imports.
|
|
*/
|
|
|
|
const CHAR_PER_TOKEN = 4;
|
|
|
|
function estimateTokens(s) {
|
|
return Math.ceil(String(s || '').length / CHAR_PER_TOKEN);
|
|
}
|
|
|
|
function truncateWithMarker(text, maxChars) {
|
|
const s = text == null ? '' : typeof text === 'string' ? text : JSON.stringify(text);
|
|
const max = maxChars > 0 ? maxChars : 12000;
|
|
if (s.length <= max) return s;
|
|
const keep = Math.max(80, Math.floor((max - 80) / 2));
|
|
const omitted = s.length - keep * 2;
|
|
return (
|
|
s.slice(0, keep) +
|
|
'\n\n[truncated ' +
|
|
omitted +
|
|
' chars; use offset/limit or a narrower path to read the middle]\n\n' +
|
|
s.slice(-keep)
|
|
);
|
|
}
|
|
|
|
function renderToolResult(out, maxChars) {
|
|
let payload = out;
|
|
if (out && typeof out === 'object' && !Array.isArray(out) && Array.isArray(out.images)) {
|
|
payload = Object.assign({}, out);
|
|
delete payload.images;
|
|
}
|
|
const raw = typeof payload === 'string' ? payload : JSON.stringify(payload);
|
|
return truncateWithMarker(raw, maxChars != null ? maxChars : 12000);
|
|
}
|
|
|
|
module.exports = { CHAR_PER_TOKEN, estimateTokens, truncateWithMarker, renderToolResult };
|