- packages/sdk-ts: BatchTransport, TraceBuilder, models, decision helpers Zero external deps, native fetch, ESM+CJS output - packages/opencode-plugin: OpenCode plugin with hooks for: - Session lifecycle (create/idle/error/delete/diff) - Tool execution capture (before/after -> TOOL_CALL spans + TOOL_SELECTION decisions) - LLM call tracking (chat.message -> LLM_CALL spans with model/provider) - Permission flow (permission.ask -> ESCALATION decisions) - File edit events - Model cost estimation (Claude, GPT-4o, o3-mini pricing)
137 lines
3.4 KiB
TypeScript
137 lines
3.4 KiB
TypeScript
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();
|
|
}
|