| 94 | } |
| 95 | |
| 96 | private writeLog(level: LogLevel, category: string, message: string, data?: unknown): void { |
| 97 | const timestamp = new Date().toISOString() |
| 98 | let logLine = `[${timestamp}] [${level}] [${category}] ${message}` |
| 99 | |
| 100 | if (data !== undefined) { |
| 101 | try { |
| 102 | const dataStr = typeof data === 'string' ? data : JSON.stringify(data, null, 2) |
| 103 | if (!this.debugMode && dataStr.length > 2000) { |
| 104 | logLine += `\n${dataStr.slice(0, 2000)}...[truncated, ${dataStr.length} chars total]` |
| 105 | } else { |
| 106 | logLine += `\n${dataStr}` |
| 107 | } |
| 108 | } catch { |
| 109 | logLine += `\n[unserializable data]` |
| 110 | } |
| 111 | } |
| 112 | |
| 113 | logLine += '\n' |
| 114 | |
| 115 | try { |
| 116 | const stream = this.getLogStream() |
| 117 | stream.write(logLine) |
| 118 | } catch (error) { |
| 119 | console.error('[AiLogger] Failed to write log:', error) |
| 120 | } |
| 121 | |
| 122 | if (level === 'WARN' || level === 'ERROR') { |
| 123 | console.log(`[AI] ${message}`) |
| 124 | } |
| 125 | } |
| 126 | } |
| 127 | |
| 128 | export function extractErrorInfo(error: unknown): Record<string, unknown> { |