@nextsparkjs/plugin-langchain 0.1.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/.env.example +41 -0
  2. package/api/observability/metrics/route.ts +110 -0
  3. package/api/observability/traces/[traceId]/route.ts +398 -0
  4. package/api/observability/traces/route.ts +205 -0
  5. package/api/sessions/route.ts +332 -0
  6. package/components/observability/CollapsibleJson.tsx +71 -0
  7. package/components/observability/CompactTimeline.tsx +75 -0
  8. package/components/observability/ConversationFlow.tsx +271 -0
  9. package/components/observability/DisabledMessage.tsx +21 -0
  10. package/components/observability/FiltersPanel.tsx +82 -0
  11. package/components/observability/ObservabilityDashboard.tsx +230 -0
  12. package/components/observability/SpansList.tsx +210 -0
  13. package/components/observability/TraceDetail.tsx +335 -0
  14. package/components/observability/TraceStatusBadge.tsx +39 -0
  15. package/components/observability/TracesTable.tsx +97 -0
  16. package/components/observability/index.ts +7 -0
  17. package/docs/01-getting-started/01-overview.md +196 -0
  18. package/docs/01-getting-started/02-installation.md +368 -0
  19. package/docs/01-getting-started/03-configuration.md +794 -0
  20. package/docs/02-core-concepts/01-architecture.md +566 -0
  21. package/docs/02-core-concepts/02-agents.md +597 -0
  22. package/docs/02-core-concepts/03-tools.md +689 -0
  23. package/docs/03-orchestration/01-graph-orchestrator.md +809 -0
  24. package/docs/03-orchestration/02-legacy-react.md +650 -0
  25. package/docs/04-advanced/01-observability.md +645 -0
  26. package/docs/04-advanced/02-token-tracking.md +469 -0
  27. package/docs/04-advanced/03-streaming.md +476 -0
  28. package/docs/04-advanced/04-guardrails.md +597 -0
  29. package/docs/05-reference/01-api-reference.md +1403 -0
  30. package/docs/05-reference/02-customization.md +646 -0
  31. package/docs/05-reference/03-examples.md +881 -0
  32. package/docs/index.md +85 -0
  33. package/hooks/observability/useMetrics.ts +31 -0
  34. package/hooks/observability/useTraceDetail.ts +48 -0
  35. package/hooks/observability/useTraces.ts +59 -0
  36. package/lib/agent-factory.ts +354 -0
  37. package/lib/agent-helpers.ts +201 -0
  38. package/lib/db-memory-store.ts +417 -0
  39. package/lib/graph/index.ts +58 -0
  40. package/lib/graph/nodes/combiner.ts +399 -0
  41. package/lib/graph/nodes/router.ts +440 -0
  42. package/lib/graph/orchestrator-graph.ts +386 -0
  43. package/lib/graph/prompts/combiner.md +131 -0
  44. package/lib/graph/prompts/router.md +193 -0
  45. package/lib/graph/types.ts +365 -0
  46. package/lib/guardrails.ts +230 -0
  47. package/lib/index.ts +44 -0
  48. package/lib/logger.ts +70 -0
  49. package/lib/memory-store.ts +168 -0
  50. package/lib/message-serializer.ts +110 -0
  51. package/lib/prompt-renderer.ts +94 -0
  52. package/lib/providers.ts +226 -0
  53. package/lib/streaming.ts +232 -0
  54. package/lib/token-tracker.ts +298 -0
  55. package/lib/tools-builder.ts +192 -0
  56. package/lib/tracer-callbacks.ts +342 -0
  57. package/lib/tracer.ts +350 -0
  58. package/migrations/001_langchain_memory.sql +83 -0
  59. package/migrations/002_token_usage.sql +127 -0
  60. package/migrations/003_observability.sql +257 -0
  61. package/package.json +28 -0
  62. package/plugin.config.ts +170 -0
  63. package/presets/lib/langchain.config.ts.preset +142 -0
  64. package/presets/templates/sector7/ai-observability/[traceId]/page.tsx +91 -0
  65. package/presets/templates/sector7/ai-observability/page.tsx +54 -0
  66. package/types/langchain.types.ts +274 -0
  67. package/types/observability.types.ts +270 -0
@@ -0,0 +1,91 @@
1
+ 'use client'
2
+
3
+ /**
4
+ * AI Observability Trace Detail Page Preset
5
+ *
6
+ * Shows detailed view of a specific trace with its spans.
7
+ * Configurable basePath allows use at any URL (e.g., /superadmin/ai-observability/{traceId})
8
+ */
9
+
10
+ import { useRouter } from 'next/navigation'
11
+ import { useTraceDetail } from '@/plugins/langchain/hooks/observability/useTraceDetail'
12
+ import { TraceDetail } from '@/plugins/langchain/components/observability/TraceDetail'
13
+
14
+ interface TraceDetailPagePresetProps {
15
+ traceId: string
16
+ enabled?: boolean
17
+ /** Base path for navigation (e.g., '/superadmin/ai-observability') */
18
+ basePath?: string
19
+ }
20
+
21
+ export function TraceDetailPagePreset({
22
+ traceId,
23
+ enabled = true,
24
+ basePath = '/superadmin/ai-observability'
25
+ }: TraceDetailPagePresetProps) {
26
+ const router = useRouter()
27
+ const { data, isLoading, isError } = useTraceDetail(traceId)
28
+
29
+ const handleBack = () => {
30
+ router.push(basePath)
31
+ }
32
+
33
+ const handleSelectChildTrace = (childTraceId: string) => {
34
+ router.push(`${basePath}/${childTraceId}`)
35
+ }
36
+
37
+ const handleSelectParentTrace = (parentTraceId: string) => {
38
+ router.push(`${basePath}/${parentTraceId}`)
39
+ }
40
+
41
+ if (!enabled) {
42
+ return (
43
+ <div className="container py-6">
44
+ <p className="text-muted-foreground">Observability is disabled.</p>
45
+ </div>
46
+ )
47
+ }
48
+
49
+ if (isLoading) {
50
+ return (
51
+ <div className="container py-6">
52
+ <div className="text-center py-12">
53
+ <p className="text-muted-foreground">Loading trace...</p>
54
+ </div>
55
+ </div>
56
+ )
57
+ }
58
+
59
+ if (isError || !data) {
60
+ return (
61
+ <div className="container py-6">
62
+ <div className="text-center py-12">
63
+ <p className="text-destructive">Failed to load trace</p>
64
+ <button
65
+ onClick={handleBack}
66
+ className="mt-4 text-primary hover:underline"
67
+ >
68
+ Back to traces
69
+ </button>
70
+ </div>
71
+ </div>
72
+ )
73
+ }
74
+
75
+ return (
76
+ <div className="container py-6">
77
+ <TraceDetail
78
+ trace={data.trace}
79
+ spans={data.spans}
80
+ childTraces={data.childTraces}
81
+ childSpansMap={data.childSpansMap}
82
+ parentTrace={data.parentTrace}
83
+ onBack={handleBack}
84
+ onSelectChildTrace={handleSelectChildTrace}
85
+ onSelectParentTrace={handleSelectParentTrace}
86
+ />
87
+ </div>
88
+ )
89
+ }
90
+
91
+ export default TraceDetailPagePreset
@@ -0,0 +1,54 @@
1
+ 'use client'
2
+
3
+ /**
4
+ * AI Observability Dashboard Page Preset
5
+ *
6
+ * Client component preset for the observability dashboard.
7
+ * The theme template should define its own metadata since this is a client component.
8
+ *
9
+ * Usage in theme template:
10
+ * ```tsx
11
+ * // In your theme, import the langchain config from lib/langchain/langchain.config
12
+ * // import { AIObservabilityPagePreset } from '@/plugins/langchain/presets/templates/sector7/ai-observability/page'
13
+ *
14
+ * export const metadata = {
15
+ * title: 'AI Observability',
16
+ * description: 'Monitor LangChain agent invocations and traces',
17
+ * }
18
+ *
19
+ * export default function AIObservabilityPage() {
20
+ * // Pass observability.enabled prop from your theme's langchain config
21
+ * return <AIObservabilityPagePreset enabled={true} />
22
+ * }
23
+ * ```
24
+ */
25
+
26
+ import { ObservabilityDashboard } from '@/plugins/langchain/components/observability/ObservabilityDashboard'
27
+ import { DisabledMessage } from '@/plugins/langchain/components/observability/DisabledMessage'
28
+
29
+ interface AIObservabilityPagePresetProps {
30
+ enabled?: boolean
31
+ /** Base path for trace detail navigation (e.g., '/superadmin/ai-observability') */
32
+ basePath?: string
33
+ }
34
+
35
+ export function AIObservabilityPagePreset({
36
+ enabled = true,
37
+ basePath = '/superadmin/ai-observability'
38
+ }: AIObservabilityPagePresetProps) {
39
+ if (!enabled) {
40
+ return (
41
+ <div className="container py-6">
42
+ <DisabledMessage />
43
+ </div>
44
+ )
45
+ }
46
+
47
+ return (
48
+ <div className="container py-6">
49
+ <ObservabilityDashboard basePath={basePath} />
50
+ </div>
51
+ )
52
+ }
53
+
54
+ export default AIObservabilityPagePreset
@@ -0,0 +1,274 @@
1
+ import { z } from 'zod'
2
+ import { BaseMessage } from '@langchain/core/messages'
3
+ import type { GuardrailsConfig } from '../lib/guardrails'
4
+ import type { ObservabilityConfig } from './observability.types'
5
+
6
+ /**
7
+ * Configuration for creating an agent
8
+ */
9
+ export interface AgentConfig {
10
+ sessionId: string
11
+ systemPrompt?: string
12
+ tools?: ToolDefinition<z.ZodObject<z.ZodRawShape>>[]
13
+ }
14
+
15
+ /**
16
+ * Response from an agent chat invocation
17
+ */
18
+ export interface AgentResponse {
19
+ content: string
20
+ sessionId: string
21
+ }
22
+
23
+ /**
24
+ * Chat message structure for UI
25
+ */
26
+ export interface ChatMessage {
27
+ id: string
28
+ role: 'user' | 'assistant'
29
+ content: string
30
+ timestamp: number
31
+ }
32
+
33
+ /**
34
+ * Tool definition for creating LangChain tools
35
+ */
36
+ export interface ToolDefinition<T extends z.ZodObject<z.ZodRawShape>> {
37
+ name: string
38
+ description: string
39
+ schema: T
40
+ func: (input: z.infer<T>) => Promise<string>
41
+ }
42
+
43
+ /**
44
+ * Tool call result
45
+ */
46
+ export interface ToolCall {
47
+ toolName: string
48
+ input: Record<string, unknown>
49
+ output: unknown
50
+ }
51
+
52
+ /**
53
+ * Supported LLM providers
54
+ */
55
+ export type LLMProvider = 'openai' | 'anthropic' | 'ollama'
56
+
57
+ /**
58
+ * Model configuration for creating LLM instances
59
+ * Can be used to override default provider settings
60
+ */
61
+ export interface ModelConfig {
62
+ /** LLM provider to use */
63
+ provider: LLMProvider
64
+ /** Model name (e.g., 'gpt-4o-mini', 'claude-3-5-sonnet-20241022', 'llama3.2:3b') */
65
+ model: string
66
+ /** Temperature for response generation (0-1) */
67
+ temperature?: number
68
+ /** Maximum tokens in response */
69
+ maxTokens?: number
70
+ /** Provider-specific options */
71
+ options?: {
72
+ /** API key override (uses env var if not provided) */
73
+ apiKey?: string
74
+ /** Base URL override (for Ollama or custom endpoints) */
75
+ baseUrl?: string
76
+ }
77
+ }
78
+
79
+ /**
80
+ * Session configuration options for memory customization
81
+ */
82
+ export interface SessionConfig {
83
+ /** Maximum number of messages to keep in conversation (sliding window) */
84
+ maxMessages?: number
85
+ /** TTL in hours. null = no expiration (default) */
86
+ ttlHours?: number | null
87
+ }
88
+
89
+ /**
90
+ * Context passed to agents, tools, and memory operations
91
+ * Required: userId + teamId for multi-tenancy
92
+ * Flexible: Themes can add any additional properties for prompt injection
93
+ */
94
+ export interface AgentContext {
95
+ /** User identifier (required for RLS) */
96
+ userId: string
97
+ /** Team identifier (required for RLS) */
98
+ teamId: string
99
+ /** Flexible: Theme defines any additional context */
100
+ [key: string]: unknown
101
+ }
102
+
103
+ /**
104
+ * Complete agent configuration
105
+ * Centralizes all settings for an agent in one place
106
+ */
107
+ export interface AgentDefinition {
108
+ /** LLM provider */
109
+ provider: LLMProvider
110
+ /** Model name */
111
+ model?: string
112
+ /** Temperature (0-1) */
113
+ temperature?: number
114
+ /** Factory function to create tools with runtime context */
115
+ createTools?: (context: AgentContext) => ToolDefinition<z.ZodObject<z.ZodRawShape>>[]
116
+ /** System prompt - either filename (e.g., 'task-assistant') or inline string */
117
+ systemPrompt?: string
118
+ /** Description of what this agent does (for documentation) */
119
+ description?: string
120
+ /** Memory customization per agent (TTL, maxMessages) */
121
+ sessionConfig?: SessionConfig
122
+ /** Guardrails configuration for security and safety */
123
+ guardrails?: GuardrailsConfig
124
+ /**
125
+ * Enrich base context with runtime data for prompt templates
126
+ * Called before creating agent to inject business data into prompts
127
+ * @param baseContext - Base context with userId + teamId
128
+ * @returns Enhanced context with additional data for Handlebars templates
129
+ */
130
+ enrichContext?: (baseContext: AgentContext) => Promise<AgentContext>
131
+ }
132
+
133
+ /**
134
+ * Theme-level LangChain configuration
135
+ * Allows themes to specify different models for different agents
136
+ */
137
+ export interface ThemeLangChainConfig {
138
+ /** Default provider when not specified per-agent */
139
+ defaultProvider: LLMProvider
140
+ /** Default model when not specified per-agent */
141
+ defaultModel?: string
142
+ /** Default temperature when not specified per-agent */
143
+ defaultTemperature?: number
144
+ /** Per-agent complete configuration */
145
+ agents?: Record<string, AgentDefinition>
146
+ /** Model pricing per 1M tokens (USD) */
147
+ pricing?: Record<string, { input: number; output: number }>
148
+ /** Default guardrails for all agents */
149
+ defaultGuardrails?: GuardrailsConfig
150
+ /** Observability configuration */
151
+ observability?: ObservabilityConfig
152
+ }
153
+
154
+ /**
155
+ * Provider configuration (legacy, kept for backwards compatibility)
156
+ * @deprecated Use ModelConfig instead
157
+ */
158
+ export interface ProviderConfig {
159
+ type: LLMProvider
160
+ baseUrl?: string
161
+ model: string
162
+ }
163
+
164
+ /**
165
+ * Session data stored in memory
166
+ */
167
+ export interface SessionData {
168
+ messages: BaseMessage[]
169
+ lastUpdated: number
170
+ }
171
+
172
+ // ============================================
173
+ // CONVERSATION / SESSION TYPES
174
+ // ============================================
175
+
176
+ /**
177
+ * Conversation limits
178
+ */
179
+ export const CONVERSATION_LIMITS = {
180
+ MAX_CONVERSATIONS: 50,
181
+ MAX_MESSAGES_PER_CONVERSATION: 50,
182
+ } as const
183
+
184
+ /**
185
+ * Conversation/Session information for API responses
186
+ */
187
+ export interface ConversationInfo {
188
+ /** Unique session identifier: {userId}-{timestamp} */
189
+ sessionId: string
190
+ /** User-defined name or auto-generated from first message */
191
+ name: string | null
192
+ /** Number of messages in conversation */
193
+ messageCount: number
194
+ /** First user message (truncated to 100 chars) for display */
195
+ firstMessage: string | null
196
+ /** Whether conversation is pinned */
197
+ isPinned: boolean
198
+ /** ISO timestamp of creation */
199
+ createdAt: string
200
+ /** ISO timestamp of last update */
201
+ updatedAt: string
202
+ }
203
+
204
+ /**
205
+ * Request to create a new conversation
206
+ */
207
+ export interface CreateConversationRequest {
208
+ /** Optional name for the conversation */
209
+ name?: string
210
+ }
211
+
212
+ /**
213
+ * Request to update an existing conversation
214
+ */
215
+ export interface UpdateConversationRequest {
216
+ /** Session ID to update */
217
+ sessionId: string
218
+ /** New name (optional) */
219
+ name?: string
220
+ /** New pin status (optional) */
221
+ isPinned?: boolean
222
+ }
223
+
224
+ /**
225
+ * Response for listing conversations
226
+ */
227
+ export interface ListConversationsResponse {
228
+ success: true
229
+ data: {
230
+ sessions: ConversationInfo[]
231
+ count: number
232
+ maxAllowed: number
233
+ }
234
+ }
235
+
236
+ /**
237
+ * Response for creating a conversation
238
+ */
239
+ export interface CreateConversationResponse {
240
+ success: true
241
+ data: {
242
+ sessionId: string
243
+ name: string | null
244
+ createdAt: string
245
+ }
246
+ }
247
+
248
+ /**
249
+ * Response for getting conversation with messages
250
+ */
251
+ export interface GetConversationResponse {
252
+ success: true
253
+ data: ConversationInfo & {
254
+ messages: ChatMessage[]
255
+ }
256
+ }
257
+
258
+ /**
259
+ * Error response when limit is reached
260
+ */
261
+ export interface ConversationLimitError {
262
+ success: false
263
+ error: 'CONVERSATION_LIMIT_REACHED'
264
+ message: string
265
+ data: {
266
+ currentCount: number
267
+ maxAllowed: number
268
+ oldestSession: {
269
+ sessionId: string
270
+ name: string | null
271
+ updatedAt: string
272
+ } | null
273
+ }
274
+ }
@@ -0,0 +1,270 @@
1
+ /**
2
+ * LangChain Observability Types
3
+ *
4
+ * Type definitions for trace and span tracking in LangChain agents.
5
+ */
6
+
7
+ /**
8
+ * Trace status
9
+ */
10
+ export type TraceStatus = 'running' | 'success' | 'error'
11
+
12
+ /**
13
+ * Span type
14
+ */
15
+ export type SpanType = 'llm' | 'tool' | 'chain' | 'retriever'
16
+
17
+ /**
18
+ * Full trace record with all observability data
19
+ */
20
+ export interface Trace {
21
+ /** Unique trace identifier */
22
+ traceId: string
23
+ /** User who triggered the invocation */
24
+ userId: string
25
+ /** Team context */
26
+ teamId: string
27
+ /** Optional session identifier */
28
+ sessionId?: string
29
+ /** Name of the agent */
30
+ agentName: string
31
+ /** Type/category of agent */
32
+ agentType?: string
33
+ /** Parent trace ID for nested calls */
34
+ parentId?: string
35
+ /** Agent input (truncated) */
36
+ input: string
37
+ /** Agent output (truncated) */
38
+ output?: string
39
+ /** Trace status */
40
+ status: TraceStatus
41
+ /** Error message if failed */
42
+ error?: string
43
+ /** Error type/category */
44
+ errorType?: string
45
+ /** Error stack trace */
46
+ errorStack?: string
47
+ /** Trace start timestamp */
48
+ startedAt: string
49
+ /** Trace end timestamp */
50
+ endedAt?: string
51
+ /** Total duration in milliseconds */
52
+ durationMs?: number
53
+ /** Total input tokens */
54
+ inputTokens: number
55
+ /** Total output tokens */
56
+ outputTokens: number
57
+ /** Total tokens (input + output) */
58
+ totalTokens: number
59
+ /** Total cost in USD */
60
+ totalCost: number
61
+ /** Number of LLM calls */
62
+ llmCalls: number
63
+ /** Number of tool calls */
64
+ toolCalls: number
65
+ /** Additional metadata */
66
+ metadata?: Record<string, unknown>
67
+ /** Tags for filtering */
68
+ tags?: string[]
69
+ /** Record creation timestamp */
70
+ createdAt: string
71
+ }
72
+
73
+ /**
74
+ * Individual operation (span) within a trace
75
+ */
76
+ export interface Span {
77
+ /** Unique span identifier */
78
+ spanId: string
79
+ /** Parent trace identifier */
80
+ traceId: string
81
+ /** Parent span ID for nested operations */
82
+ parentSpanId?: string
83
+ /** Span name/description */
84
+ name: string
85
+ /** Span type */
86
+ type: SpanType
87
+ /** LLM provider (openai, anthropic, etc) */
88
+ provider?: string
89
+ /** LLM model name */
90
+ model?: string
91
+ /** Input tokens (LLM spans) */
92
+ inputTokens?: number
93
+ /** Output tokens (LLM spans) */
94
+ outputTokens?: number
95
+ /** Tool name (tool spans) */
96
+ toolName?: string
97
+ /** Tool input data (tool spans) */
98
+ toolInput?: unknown
99
+ /** Tool output data (tool spans) */
100
+ toolOutput?: unknown
101
+ /** Generic span input */
102
+ input?: unknown
103
+ /** Generic span output */
104
+ output?: unknown
105
+ /** Span status */
106
+ status: TraceStatus
107
+ /** Error message if failed */
108
+ error?: string
109
+ /** Span start timestamp */
110
+ startedAt: string
111
+ /** Span end timestamp */
112
+ endedAt?: string
113
+ /** Span duration in milliseconds */
114
+ durationMs?: number
115
+ /** Nesting depth in span tree */
116
+ depth: number
117
+ /** Record creation timestamp */
118
+ createdAt: string
119
+ }
120
+
121
+ /**
122
+ * Observability configuration
123
+ */
124
+ export interface ObservabilityConfig {
125
+ /** Whether observability is enabled */
126
+ enabled: boolean
127
+ /** Data retention settings */
128
+ retention: {
129
+ /** Days to keep trace data */
130
+ traces: number
131
+ }
132
+ /** Sampling configuration */
133
+ sampling: {
134
+ /** Sample rate (0.0-1.0) */
135
+ rate: number
136
+ /** Always trace errors regardless of sample rate */
137
+ alwaysTraceErrors: boolean
138
+ }
139
+ /** PII and content processing */
140
+ pii: {
141
+ /** Mask inputs for PII */
142
+ maskInputs: boolean
143
+ /** Mask outputs for PII */
144
+ maskOutputs: boolean
145
+ /** Truncate content at this length */
146
+ truncateAt: number
147
+ }
148
+ }
149
+
150
+ /**
151
+ * Runtime trace context
152
+ */
153
+ export interface TraceContext {
154
+ /** Trace identifier */
155
+ traceId: string
156
+ /** User ID */
157
+ userId: string
158
+ /** Team ID */
159
+ teamId: string
160
+ /** Optional session ID */
161
+ sessionId?: string
162
+ /** Agent name */
163
+ agentName: string
164
+ }
165
+
166
+ /**
167
+ * Runtime span context
168
+ */
169
+ export interface SpanContext {
170
+ /** Span identifier */
171
+ spanId: string
172
+ /** Parent trace ID */
173
+ traceId: string
174
+ /** Parent span ID (if nested) */
175
+ parentSpanId?: string
176
+ /** Span name */
177
+ name: string
178
+ /** Span type */
179
+ type: SpanType
180
+ /** Nesting depth */
181
+ depth: number
182
+ /** Start timestamp */
183
+ startedAt: Date
184
+ }
185
+
186
+ /**
187
+ * Options for starting a trace
188
+ */
189
+ export interface StartTraceOptions {
190
+ /** Agent type/category */
191
+ agentType?: string
192
+ /** Parent trace ID for nested calls */
193
+ parentId?: string
194
+ /** Session ID */
195
+ sessionId?: string
196
+ /** Initial metadata */
197
+ metadata?: Record<string, unknown>
198
+ /** Initial tags */
199
+ tags?: string[]
200
+ }
201
+
202
+ /**
203
+ * Options for ending a trace
204
+ */
205
+ export interface EndTraceOptions {
206
+ /** Output content */
207
+ output?: string
208
+ /** Error if trace failed */
209
+ error?: Error | string
210
+ /** Token usage */
211
+ tokens?: {
212
+ input: number
213
+ output: number
214
+ total: number
215
+ }
216
+ /** Cost in USD */
217
+ cost?: number
218
+ /** LLM call count */
219
+ llmCalls?: number
220
+ /** Tool call count */
221
+ toolCalls?: number
222
+ /** Additional metadata */
223
+ metadata?: Record<string, unknown>
224
+ }
225
+
226
+ /**
227
+ * Options for starting a span
228
+ */
229
+ export interface StartSpanOptions {
230
+ /** Span name */
231
+ name: string
232
+ /** Span type */
233
+ type: SpanType
234
+ /** Parent span ID (if nested) */
235
+ parentSpanId?: string
236
+ /** Nesting depth */
237
+ depth?: number
238
+ /** LLM provider */
239
+ provider?: string
240
+ /** LLM model */
241
+ model?: string
242
+ /** Tool name */
243
+ toolName?: string
244
+ /** Span input */
245
+ input?: unknown
246
+ }
247
+
248
+ /**
249
+ * Options for ending a span
250
+ */
251
+ export interface EndSpanOptions {
252
+ /** Span output */
253
+ output?: unknown
254
+ /** Error if span failed */
255
+ error?: Error | string
256
+ /** Token usage (LLM spans) */
257
+ tokens?: {
258
+ input: number
259
+ output: number
260
+ }
261
+ /** Tool input (tool spans) */
262
+ toolInput?: unknown
263
+ /** Tool output (tool spans) */
264
+ toolOutput?: unknown
265
+ }
266
+
267
+ /**
268
+ * Content type for processing
269
+ */
270
+ export type ContentType = 'input' | 'output'