import { randomUUID } from "crypto"; // --------------------------------------------------------------------------- // JSON value type (replaces Prisma.JsonValue for the SDK) // --------------------------------------------------------------------------- export type JsonValue = | string | number | boolean | null | JsonValue[] | { [key: string]: JsonValue }; // --------------------------------------------------------------------------- // Enums (as const + type union pattern — NO TypeScript enum keyword) // --------------------------------------------------------------------------- export const TraceStatus = { RUNNING: "RUNNING", COMPLETED: "COMPLETED", ERROR: "ERROR", } as const; export type TraceStatus = (typeof TraceStatus)[keyof typeof TraceStatus]; export const DecisionType = { TOOL_SELECTION: "TOOL_SELECTION", ROUTING: "ROUTING", RETRY: "RETRY", ESCALATION: "ESCALATION", MEMORY_RETRIEVAL: "MEMORY_RETRIEVAL", PLANNING: "PLANNING", CUSTOM: "CUSTOM", } as const; export type DecisionType = (typeof DecisionType)[keyof typeof DecisionType]; export const SpanType = { LLM_CALL: "LLM_CALL", TOOL_CALL: "TOOL_CALL", MEMORY_OP: "MEMORY_OP", CHAIN: "CHAIN", AGENT: "AGENT", CUSTOM: "CUSTOM", } as const; export type SpanType = (typeof SpanType)[keyof typeof SpanType]; export const SpanStatus = { RUNNING: "RUNNING", COMPLETED: "COMPLETED", ERROR: "ERROR", } as const; export type SpanStatus = (typeof SpanStatus)[keyof typeof SpanStatus]; export const EventType = { ERROR: "ERROR", RETRY: "RETRY", FALLBACK: "FALLBACK", CONTEXT_OVERFLOW: "CONTEXT_OVERFLOW", USER_FEEDBACK: "USER_FEEDBACK", CUSTOM: "CUSTOM", } as const; export type EventType = (typeof EventType)[keyof typeof EventType]; // --------------------------------------------------------------------------- // Wire-format interfaces (camelCase, matching POST /api/traces contract) // --------------------------------------------------------------------------- export interface DecisionPointPayload { id: string; type: DecisionType; chosen: JsonValue; alternatives: JsonValue[]; reasoning?: string; contextSnapshot?: JsonValue; durationMs?: number; costUsd?: number; parentSpanId?: string; timestamp: string; } export interface SpanPayload { id: string; parentSpanId?: string; name: string; type: SpanType; input?: JsonValue; output?: JsonValue; tokenCount?: number; costUsd?: number; durationMs?: number; status: SpanStatus; statusMessage?: string; startedAt: string; endedAt?: string; metadata?: JsonValue; } export interface EventPayload { id: string; spanId?: string; type: EventType; name: string; metadata?: JsonValue; timestamp: string; } export interface TracePayload { id: string; name: string; sessionId?: string; status: TraceStatus; tags: string[]; metadata?: JsonValue; totalCost?: number; totalTokens?: number; totalDuration?: number; startedAt: string; endedAt?: string; decisionPoints: DecisionPointPayload[]; spans: SpanPayload[]; events: EventPayload[]; } // --------------------------------------------------------------------------- // Helper functions // --------------------------------------------------------------------------- /** Generate a v4 UUID. */ export function generateId(): string { return randomUUID(); } /** Return the current time as an ISO-8601 string. */ export function nowISO(): string { return new Date().toISOString(); }