Files
agentlens/packages/sdk-ts/src/models.ts
Vectry 6bed493275 feat: TypeScript SDK (agentlens-sdk) and OpenCode plugin (opencode-agentlens)
- 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)
2026-02-10 03:08:51 +00:00

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();
}