limits.ts
1 export const BASH_TOOL_DEFAULT_TIMEOUT_MS = 8_000 2 export const BASH_TOOL_MAX_TIMEOUT_MS = 30_000 3 export const BASH_TOOL_MIN_TIMEOUT_MS = 500 4 export const BASH_TOOL_MAX_COMMAND_CHARS = 4_000 5 export const BASH_TOOL_MAX_OUTPUT_CHARS = 12_000 6 export const BASH_TOOL_PREFLIGHT_MAX_SCRIPT_BYTES = 512 * 1024 7 8 export function appendTruncatedText( 9 current: string, 10 chunk: string, 11 maxChars: number, 12 ): { value: string; truncated: boolean } { 13 if (!chunk) return { value: current, truncated: false } 14 if (current.length >= maxChars) { 15 return { value: current, truncated: true } 16 } 17 const next = current + chunk 18 if (next.length <= maxChars) { 19 return { value: next, truncated: false } 20 } 21 return { 22 value: next.slice(0, maxChars), 23 truncated: true, 24 } 25 } 26 27 export function clampBashToolTimeout(value: number | null): number { 28 if (value == null) return BASH_TOOL_DEFAULT_TIMEOUT_MS 29 return Math.max( 30 BASH_TOOL_MIN_TIMEOUT_MS, 31 Math.min(BASH_TOOL_MAX_TIMEOUT_MS, Math.round(value)), 32 ) 33 } 34 35 export function sanitizeCommandOutput(value: string): string { 36 if (!value) return '' 37 const scrubbed = value.replace(/[\p{Format}\p{Surrogate}]/gu, '') 38 if (!scrubbed) return '' 39 40 const chunks: string[] = [] 41 for (const char of scrubbed) { 42 const code = char.codePointAt(0) 43 if (code == null) continue 44 if (code === 0x09 || code === 0x0a || code === 0x0d) { 45 chunks.push(char) 46 continue 47 } 48 if (code < 0x20) continue 49 chunks.push(char) 50 } 51 return chunks.join('') 52 }