返回 DeepSeek-Reasonix
toolPayloadPreview.ts
根目录 / desktop / frontend / src / lib / toolPayloadPreview.ts
1 import { RESOURCE_BUDGETS } from "./resourceBudgets";
2
3 export const TOOL_PREVIEW_MAX_BYTES = RESOURCE_BUDGETS.toolPreviewBytes;
4 export const TOOL_PREVIEW_MAX_BLOCKS = RESOURCE_BUDGETS.toolPreviewBlocks;
5
6 const encoder = new TextEncoder();
7
8 export function utf8Prefix(text: string, maxBytes: number): string {
9 if (maxBytes <= 0) return "";
10 if (encoder.encode(text).byteLength <= maxBytes) return text;
11 let low = 0, high = text.length;
12 while (low < high) {
13 const middle = Math.ceil((low + high) / 2);
14 if (encoder.encode(text.slice(0, middle)).byteLength <= maxBytes) low = middle;
15 else high = middle - 1;
16 }
17 if (low > 0 && /[\uD800-\uDBFF]/.test(text[low - 1])) low -= 1;
18 return text.slice(0, low);
19 }
20
21 export function boundedPayloadSections(value: Record<string, unknown>): Array<{ key: string; body: string }> {
22 let remaining = TOOL_PREVIEW_MAX_BYTES;
23 const sections: Array<{ key: string; body: string }> = [];
24 for (const [key, content] of Object.entries(value).slice(0, TOOL_PREVIEW_MAX_BLOCKS)) {
25 if (content == null || remaining <= 0) continue;
26 const body = typeof content === "string" ? content : JSON.stringify(content, null, 2);
27 const shown = utf8Prefix(body, remaining);
28 remaining -= encoder.encode(shown).byteLength;
29 sections.push({ key, body: shown });
30 }
31 return sections;
32 }
33
33 lines TYPESCRIPT