contaigents
Version:
Modular AI Content Ecosystem with Audio Generation
169 lines (168 loc) ⢠5.92 kB
JavaScript
import fs from 'fs/promises';
export class DebugLogger {
constructor(enabled = false, logFilePath) {
this.enabled = false;
this.logToFile = false;
this.logs = [];
this.enabled = enabled;
this.logToFile = !!logFilePath;
this.logFilePath = logFilePath;
}
setEnabled(enabled) {
this.enabled = enabled;
}
setLogFile(filePath) {
this.logFilePath = filePath;
this.logToFile = true;
}
async log(entry) {
if (!this.enabled)
return;
const logEntry = {
...entry,
timestamp: new Date().toISOString()
};
this.logs.push(logEntry);
// Console logging with colors and formatting
this.logToConsole(logEntry);
// File logging if enabled
if (this.logToFile && this.logFilePath) {
await this.logToFileSystem(logEntry);
}
}
logToConsole(entry) {
const timestamp = new Date(entry.timestamp).toLocaleTimeString();
const sessionInfo = entry.sessionId ? ` [${entry.sessionId.substring(0, 8)}]` : '';
const providerInfo = entry.provider ? ` (${entry.provider}${entry.model ? `/${entry.model}` : ''})` : '';
switch (entry.type) {
case 'prompt':
console.log(`\nš [${timestamp}] PROMPT${sessionInfo}${providerInfo}`);
console.log('ā'.repeat(80));
console.log(this.truncateForDisplay(entry.data.prompt));
console.log('ā'.repeat(80));
if (entry.data.options) {
console.log(`š Options: ${JSON.stringify(entry.data.options, null, 2)}`);
}
break;
case 'response':
console.log(`\nš¬ [${timestamp}] RESPONSE${sessionInfo}${providerInfo}`);
console.log('ā'.repeat(80));
console.log(this.truncateForDisplay(entry.data.content));
console.log('ā'.repeat(80));
if (entry.data.usage) {
console.log(`š Usage: ${JSON.stringify(entry.data.usage, null, 2)}`);
}
break;
case 'tool_call':
console.log(`\nš§ [${timestamp}] TOOL CALL${sessionInfo}`);
console.log(` Tool: ${entry.data.name}`);
console.log(` Args: ${JSON.stringify(entry.data.arguments, null, 2)}`);
break;
case 'tool_response':
console.log(`\nāļø [${timestamp}] TOOL RESPONSE${sessionInfo}`);
console.log(` Tool: ${entry.data.name}`);
console.log(` Success: ${entry.data.success}`);
if (entry.data.result) {
console.log(` Result: ${this.truncateForDisplay(entry.data.result)}`);
}
if (entry.data.error) {
console.log(` Error: ${entry.data.error}`);
}
break;
case 'error':
console.log(`\nā [${timestamp}] ERROR${sessionInfo}`);
console.log(` ${entry.data.message}`);
if (entry.data.stack) {
console.log(` Stack: ${entry.data.stack}`);
}
break;
case 'info':
console.log(`\nš” [${timestamp}] INFO${sessionInfo}`);
console.log(` ${entry.data.message}`);
break;
}
}
async logToFileSystem(entry) {
if (!this.logFilePath)
return;
try {
const logLine = JSON.stringify(entry) + '\n';
await fs.appendFile(this.logFilePath, logLine, 'utf-8');
}
catch (error) {
console.error('Failed to write to debug log file:', error);
}
}
truncateForDisplay(text, maxLength = 500) {
if (text.length <= maxLength)
return text;
return text.substring(0, maxLength) + '\n... [truncated]';
}
async dumpLogs() {
return [...this.logs];
}
async saveDumpToFile(filePath) {
try {
const dump = {
generatedAt: new Date().toISOString(),
totalEntries: this.logs.length,
logs: this.logs
};
await fs.writeFile(filePath, JSON.stringify(dump, null, 2), 'utf-8');
console.log(`š Debug logs saved to: ${filePath}`);
}
catch (error) {
console.error('Failed to save debug dump:', error);
}
}
clear() {
this.logs = [];
}
// Helper methods for common log types
async logPrompt(prompt, options, sessionId, provider, model) {
await this.log({
type: 'prompt',
sessionId,
provider,
model,
data: { prompt, options }
});
}
async logResponse(content, usage, sessionId, provider, model) {
await this.log({
type: 'response',
sessionId,
provider,
model,
data: { content, usage }
});
}
async logToolCall(name, parameters, sessionId) {
await this.log({
type: 'tool_call',
sessionId,
data: { name, parameters }
});
}
async logToolResponse(name, success, result, error, sessionId) {
await this.log({
type: 'tool_response',
sessionId,
data: { name, success, result, error }
});
}
async logError(message, stack, sessionId) {
await this.log({
type: 'error',
sessionId,
data: { message, stack }
});
}
async logInfo(message, sessionId) {
await this.log({
type: 'info',
sessionId,
data: { message }
});
}
}