const PREVIEW_KEYS = [ "command", "cmd", "path", "file_path", "filePath", "pattern", "query", "url", ] as const; const MAX_PREVIEW_LENGTH = 160; const MAX_DETAIL_LENGTH = 6000; /** Single-line summary of tool call arguments, e.g. the bash command or file path. */ export function toolArgsPreview(args: unknown): string | undefined { if (!args || typeof args !== "object" || Array.isArray(args)) { return undefined; } const record = args as Record; let preview: string | undefined; for (const key of PREVIEW_KEYS) { const value = record[key]; if (typeof value === "string" && value.trim()) { preview = value.trim(); break; } } if (!preview) { const entries = Object.entries(record).filter(([, value]) => value !== undefined); if (entries.length === 0) { return undefined; } preview = entries .map(([key, value]) => `${key}: ${typeof value === "string" ? value : safeStringify(value)}`) .join(", "); } const lines = preview.split("\n"); let line = lines[0].trim(); if (lines.length > 1) { line += " …"; } return line.length > MAX_PREVIEW_LENGTH ? `${line.slice(0, MAX_PREVIEW_LENGTH)}…` : line; } /** Pulls readable text out of a tool result / partial result of unknown shape. */ export function extractResultText(result: unknown): string { if (result == null) { return ""; } if (typeof result === "string") { return result; } if (Array.isArray(result)) { return result.map(blockText).join(""); } if (typeof result === "object") { const record = result as Record; if (Array.isArray(record.content)) { return record.content.map(blockText).join(""); } if (typeof record.output === "string") { return record.output; } if (typeof record.text === "string") { return record.text; } return safeStringify(record); } return String(result); } /** Caps tool output length so a huge result doesn't bloat list state. */ export function truncateDetail(text: string): string { const trimmed = text.trim(); if (trimmed.length <= MAX_DETAIL_LENGTH) { return trimmed; } return `${trimmed.slice(0, MAX_DETAIL_LENGTH)}\n… (output truncated)`; } function blockText(block: unknown): string { if (typeof block === "string") { return block; } if (typeof block === "object" && block && "text" in block) { return String((block as { text?: string }).text ?? ""); } return ""; } function safeStringify(value: unknown): string { try { return JSON.stringify(value) ?? ""; } catch { return ""; } }