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)
This commit is contained in:
136
packages/sdk-ts/src/models.ts
Normal file
136
packages/sdk-ts/src/models.ts
Normal file
@@ -0,0 +1,136 @@
|
||||
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();
|
||||
}
|
||||
Reference in New Issue
Block a user