Spaces:
Sleeping
Sleeping
File size: 4,205 Bytes
dbeb746 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 | import { randomUUID } from 'node:crypto';
import { appendFile, mkdir } from 'node:fs/promises';
import { dirname, join } from 'node:path';
import { homedir, hostname } from 'node:os';
import { TEMPLATE_AGENT_ID, TEMPLATE_AGENT_NAME, TEMPLATE_AGENT_NAMESPACE } from '../../metadata.js';
import { getSupabaseClient } from '../../supabase.js';
export type TemplateLogLevel = 'info' | 'warn' | 'error' | 'debug';
export type TemplateLogStatus = 'started' | 'accepted' | 'completed' | 'failed';
export type TemplateLogEntry = {
agentId: string;
agentName: string;
namespace: string;
runId: string;
requestId: string;
surface: string;
event: string;
action?: string;
level: TemplateLogLevel;
status: TemplateLogStatus;
details?: Record<string, unknown>;
durationMs?: number;
createdAt: string;
};
export const TEMPLATE_LOG_PATH = join(homedir(), '.config', 'sin', TEMPLATE_AGENT_ID, 'events.ndjson');
export const TEMPLATE_TELEMETRY_TABLE = 'fleet_telemetry';
export class TemplateLogger {
readonly runId: string;
constructor(runId: string = randomUUID()) {
this.runId = runId;
}
async log(input: {
surface: string;
event: string;
level?: TemplateLogLevel;
status?: TemplateLogStatus;
action?: string;
details?: Record<string, unknown>;
durationMs?: number;
requestId?: string;
}) {
const entry: TemplateLogEntry = {
agentId: TEMPLATE_AGENT_ID,
agentName: TEMPLATE_AGENT_NAME,
namespace: TEMPLATE_AGENT_NAMESPACE,
runId: this.runId,
requestId: input.requestId || randomUUID(),
surface: input.surface,
event: input.event,
action: input.action,
level: input.level || 'info',
status: input.status || 'completed',
details: input.details,
durationMs: input.durationMs,
createdAt: new Date().toISOString(),
};
await mkdir(dirname(TEMPLATE_LOG_PATH), { recursive: true });
await appendFile(TEMPLATE_LOG_PATH, `${JSON.stringify(entry)}\n`, 'utf8');
try {
await getSupabaseClient().from(TEMPLATE_TELEMETRY_TABLE).insert({
agent_id: entry.agentId,
run_id: entry.runId,
level: entry.level,
event: entry.event,
details: {
...(entry.details || {}),
action: entry.action,
requestId: entry.requestId,
surface: entry.surface,
status: entry.status,
hostname: hostname(),
},
duration_ms: entry.durationMs,
created_at: entry.createdAt,
});
} catch {}
const line = `[${entry.createdAt}] [${entry.agentId}] [${entry.surface}] [${entry.level.toUpperCase()}] ${entry.event}`;
if (entry.level === 'error') {
console.error(line, entry.details || '');
} else if (entry.level === 'warn') {
console.warn(line, entry.details || '');
} else {
console.log(line, entry.details || '');
}
return entry;
}
started(surface: string, event: string, details?: Record<string, unknown>, requestId?: string, action?: string) {
return this.log({ surface, event, details, requestId, action, level: 'info', status: 'started' });
}
accepted(surface: string, event: string, details?: Record<string, unknown>, requestId?: string, action?: string) {
return this.log({ surface, event, details, requestId, action, level: 'info', status: 'accepted' });
}
succeeded(
surface: string,
event: string,
details?: Record<string, unknown>,
durationMs?: number,
requestId?: string,
action?: string,
) {
return this.log({
surface,
event,
details,
durationMs,
requestId,
action,
level: 'info',
status: 'completed',
});
}
failed(surface: string, event: string, error: unknown, durationMs?: number, requestId?: string, action?: string) {
const details = error instanceof Error ? { error: error.message } : { error: String(error) };
return this.log({
surface,
event,
details,
durationMs,
requestId,
action,
level: 'error',
status: 'failed',
});
}
}
export function createTemplateLogger(runId?: string) {
return new TemplateLogger(runId);
}
|