@directive-run/knowledge 1.13.0 → 1.15.0

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 (43) hide show
  1. package/README.md +50 -15
  2. package/ai/ai-adapters.md +2 -0
  3. package/ai/ai-agents-streaming.md +182 -149
  4. package/ai/ai-budget-resilience.md +299 -132
  5. package/ai/ai-communication.md +215 -197
  6. package/ai/ai-debug-observability.md +253 -173
  7. package/ai/ai-guardrails-memory.md +185 -153
  8. package/ai/ai-mcp-rag.md +199 -199
  9. package/ai/ai-multi-agent.md +247 -153
  10. package/ai/ai-orchestrator.md +344 -114
  11. package/ai/ai-security.md +282 -180
  12. package/ai/ai-tasks.md +3 -1
  13. package/ai/ai-testing-evals.md +357 -256
  14. package/core/anti-patterns.md +9 -2
  15. package/core/constraints.md +6 -2
  16. package/core/core-patterns.md +2 -0
  17. package/core/error-boundaries.md +2 -0
  18. package/core/history.md +2 -0
  19. package/core/multi-module.md +8 -3
  20. package/core/naming.md +15 -6
  21. package/core/plugins.md +2 -0
  22. package/core/react-adapter.md +250 -174
  23. package/core/resolvers.md +2 -0
  24. package/core/schema-types.md +2 -0
  25. package/core/system-api.md +2 -0
  26. package/core/testing.md +251 -143
  27. package/examples/checkers.ts +15 -16
  28. package/examples/contact-form.ts +2 -2
  29. package/examples/counter-react.ts +1 -1
  30. package/examples/counter-svelte.ts +1 -1
  31. package/examples/counter-vue.ts +1 -1
  32. package/examples/counter.ts +1 -1
  33. package/examples/data-triggers.ts +4 -4
  34. package/examples/feature-flags.ts +2 -2
  35. package/examples/form-wizard.ts +2 -2
  36. package/examples/newsletter.ts +2 -2
  37. package/examples/server.ts +2 -2
  38. package/examples/shopping-cart.ts +1 -1
  39. package/examples/topic-guard.ts +1 -1
  40. package/package.json +3 -3
  41. package/sitemap.md +26 -3
  42. package/examples/debounce-constraints.ts +0 -95
  43. package/examples/multi-module.ts +0 -58
@@ -1,243 +1,323 @@
1
- # AI Debug and Observability
1
+ # AI debug + observability
2
2
 
3
- Debug timeline with 25+ event types, breakpoints, checkpoints, and OpenTelemetry integration for AI orchestrators.
3
+ > Covers `@directive-run/ai/devtools` and `@directive-run/core/plugins` `createDebugTimeline`, breakpoints, `createOtelPlugin`, `createOTLPExporter`.
4
4
 
5
- ## Decision Tree: "How do I observe what's happening?"
5
+ Debug timeline with typed event recording, breakpoints, checkpoints, an OTel plugin for span emission, and an OTLP exporter for sending metrics/traces to any OTel-compatible backend.
6
+
7
+ ## Decision tree
6
8
 
7
9
  ```
8
10
  What do you need?
9
- ├── Event stream of all AI activity → createDebugTimeline()
10
- ├── Pause execution at specific points → breakpoints config
11
- ├── Save/restore orchestrator state → checkpoint() / restore
12
- ├── Export traces to observability platform createOTLPExporter()
13
-
14
- Which events to watch?
15
- ├── Agent lifecycle → agent_start, agent_complete, agent_error, agent_retry
16
- ├── Guardrails → guardrail_check
17
- ├── Constraints/Resolvers → constraint_evaluate, resolver_start, resolver_complete
18
- ├── Approval workflow → approval_request, approval_response
19
- ├── Multi-agent patterns pattern_start, pattern_complete, dag_node_update
20
- ├── Composition patterns → race_start, race_winner, race_cancelled,
21
- │ debate_round, reflection_iteration
22
- ├── Handoffs → handoff_start, handoff_complete, reroute
23
- ├── Tasks → task_start, task_complete, task_error, task_progress, goal_step
24
- ├── Checkpoints → checkpoint_save, checkpoint_restore
25
- └── Breakpoints → breakpoint_hit, breakpoint_resumed
26
- ```
27
-
28
- ## Debug Timeline
29
-
30
- Subscribe to a real-time event stream of all orchestrator activity:
11
+ ├── Event stream of all AI activity → createDebugTimeline()
12
+ ├── Pause execution at specific points → breakpoints (top-level option on orchestrator)
13
+ ├── Save / restore orchestrator state → orchestrator.checkpoint() / restore()
14
+ ├── Span emission to OTel → createOtelPlugin({ serviceName })
15
+ ├── Ship metrics + traces to backend → createOTLPExporter({ endpoint })
16
+ └── DevTools panel + websocket export → createDevtoolsServer + createDevtoolsExport
17
+ ```
18
+
19
+ ## `createDebugTimeline(options?)`
20
+
21
+ Returns a `DebugTimeline` with typed event recording, multi-axis querying, snapshot-aware forking, and JSON import/export. Import from `@directive-run/ai/devtools` — the main `@directive-run/ai` barrel re-exports it with `@deprecated` notices for v2.
31
22
 
32
23
  ```typescript
33
- import { createDebugTimeline } from "@directive-run/ai";
24
+ import { createDebugTimeline, type DebugTimelineListener } from "@directive-run/ai/devtools";
34
25
 
35
26
  const timeline = createDebugTimeline({
36
- maxEvents: 2000, // Ring buffer size (oldest evicted first)
27
+ maxEvents: 2000, // default 2000 — ring buffer, oldest evicted first
28
+ getSnapshotId: () => system.history?.currentId ?? null, // for snapshot-aware querying
29
+ goToSnapshot: (id) => system.history?.goTo(id), // for forkFrom
37
30
  });
38
31
 
39
- // Subscribe to all events
40
- const unsubscribe = timeline.subscribe((event) => {
32
+ // Subscribe listener takes a single DebugEvent. There is NO options arg / filter shape.
33
+ const unsubscribe: () => void = timeline.subscribe((event) => {
41
34
  console.log(`[${event.timestamp}] ${event.type}`, event);
42
35
  });
43
36
 
44
- // Filter by event type
45
- const agentEvents = timeline.subscribe(
46
- (event) => {
47
- console.log(`Agent: ${event.agentName} → ${event.type}`);
48
- },
49
- { filter: (event) => event.type.startsWith("agent_") },
50
- );
37
+ // Filter at the listener — the API has no built-in filter option
38
+ const unsubAgents = timeline.subscribe((event) => {
39
+ if (event.type.startsWith("agent_")) {
40
+ console.log(`agent: ${event.type}`);
41
+ }
42
+ });
51
43
 
52
- // Query past events
53
- const errors = timeline.query({ type: "agent_error" });
54
- const recentAgentStarts = timeline.query({
44
+ // Record an event manually
45
+ timeline.record({
55
46
  type: "agent_start",
56
- since: Date.now() - 60000,
47
+ timestamp: Date.now(),
48
+ agentId: "researcher",
49
+ snapshotId: null,
50
+ inputLength: 42,
57
51
  });
52
+
53
+ // Length
54
+ console.log(timeline.length);
58
55
  ```
59
56
 
60
- ## Event Types Reference
57
+ ### Querying past events
61
58
 
62
- All 25+ event types emitted by the timeline:
59
+ The query surface is method-based there is no `timeline.query({ type, since })`. Use the typed helpers:
63
60
 
64
61
  ```typescript
65
- // Agent lifecycle
66
- type AgentEvents =
67
- | { type: "agent_start"; agentName: string; prompt: string }
68
- | { type: "agent_complete"; agentName: string; output: string; tokens: number; duration: number }
69
- | { type: "agent_error"; agentName: string; error: Error }
70
- | { type: "agent_retry"; agentName: string; attempt: number; maxRetries: number; error: Error };
71
-
72
- // Guardrails
73
- type GuardrailEvents =
74
- | { type: "guardrail_check"; guardrailName: string; phase: "input" | "output"; passed: boolean; reason?: string };
75
-
76
- // Constraints and resolvers
77
- type ConstraintEvents =
78
- | { type: "constraint_evaluate"; constraintId: string; result: boolean }
79
- | { type: "resolver_start"; resolverType: string; requirementKey: string }
80
- | { type: "resolver_complete"; resolverType: string; duration: number };
81
-
82
- // Approval workflow
83
- type ApprovalEvents =
84
- | { type: "approval_request"; agentName: string; prompt: string }
85
- | { type: "approval_response"; agentName: string; approved: boolean; reason?: string };
86
-
87
- // Multi-agent patterns
88
- type PatternEvents =
89
- | { type: "pattern_start"; patternName: string; agents: string[] }
90
- | { type: "pattern_complete"; patternName: string; duration: number }
91
- | { type: "dag_node_update"; nodeId: string; status: "pending" | "running" | "complete" | "error" };
92
-
93
- // Composition patterns
94
- type CompositionEvents =
95
- | { type: "race_start"; agents: string[] }
96
- | { type: "race_winner"; agentName: string; duration: number }
97
- | { type: "race_cancelled"; agentName: string; reason: string }
98
- | { type: "debate_round"; round: number; agentName: string; position: string }
99
- | { type: "reflection_iteration"; iteration: number; agentName: string };
100
-
101
- // Handoffs and routing
102
- type HandoffEvents =
103
- | { type: "handoff_start"; from: string; to: string }
104
- | { type: "handoff_complete"; from: string; to: string; duration: number }
105
- | { type: "reroute"; from: string; to: string; reason: string };
106
-
107
- // Checkpoints and breakpoints
108
- type CheckpointEvents =
109
- | { type: "checkpoint_save"; checkpointId: string }
110
- | { type: "checkpoint_restore"; checkpointId: string }
111
- | { type: "breakpoint_hit"; breakpointId: string; agentName: string }
112
- | { type: "breakpoint_resumed"; breakpointId: string };
113
-
114
- // Tasks
115
- type TaskEvents =
116
- | { type: "task_start"; taskId: string; label?: string }
117
- | { type: "task_complete"; taskId: string; duration: number }
118
- | { type: "task_error"; taskId: string; error: Error }
119
- | { type: "task_progress"; taskId: string; percent: number; message?: string }
120
- | { type: "goal_step"; iteration: number; goalMet: boolean };
121
- ```
122
-
123
- ## Attaching Timeline to Orchestrator
62
+ const all = timeline.getEvents(); // DebugEvent[]
63
+ const agentErrors = timeline.getEventsByType("agent_error"); // typed-narrowed
64
+ const recentSpan = timeline.getEventsInRange(Date.now() - 60_000, Date.now());
65
+ const researcher = timeline.getEventsForAgent("researcher");
66
+ const atSnapshot = timeline.getEventsAtSnapshot(7);
67
+ ```
68
+
69
+ `getEventsByType<T>(type)` narrows the union — `agentErrors` above is typed as `Extract<DebugEvent, { type: "agent_error" }>[]`, so `err.error.message` autocompletes.
70
+
71
+ ### Persistence + fork
124
72
 
125
73
  ```typescript
126
- import { createAgentOrchestrator, createDebugTimeline } from "@directive-run/ai";
74
+ const json = timeline.export(); // string full JSON dump
75
+ timeline.clear();
76
+ timeline.import(json); // re-hydrate
77
+
78
+ timeline.forkFrom(snapshotId); // truncate post-snapshot events + call goToSnapshot
79
+ ```
127
80
 
128
- const timeline = createDebugTimeline({ maxEvents: 2000 });
81
+ ## Attaching the timeline to an orchestrator
82
+
83
+ `OrchestratorDebugConfig` has exactly one option: `verboseTimeline?: boolean`. There is NO `timeline:` / `breakpoints:` / `exporter:` field inside `debug:` — `breakpoints` and `onBreakpoint` are top-level options on the orchestrator, and the timeline is *read off* the orchestrator via `orchestrator.timeline` after construction.
84
+
85
+ ```typescript
86
+ import { createAgentOrchestrator } from "@directive-run/ai";
129
87
 
130
88
  const orchestrator = createAgentOrchestrator({
131
89
  runner,
132
- debug: {
133
- timeline,
134
- verbose: true, // Log all events to console
90
+ debug: { verboseTimeline: true }, // or just `debug: true`
91
+ // Top-level — NOT inside debug
92
+ breakpoints: [
93
+ { id: "before-write", before: "agent_start" },
94
+ ],
95
+ onBreakpoint: (req) => {
96
+ console.log("breakpoint hit", req.id);
97
+ orchestrator.resumeBreakpoint(req.id);
135
98
  },
136
99
  });
100
+
101
+ // Timeline is exposed on the orchestrator (null when debug: false)
102
+ const timeline = orchestrator.timeline;
103
+ timeline?.subscribe((event) => console.log(event));
137
104
  ```
138
105
 
139
106
  ## Breakpoints
140
107
 
141
- Pause execution at specific points for human inspection:
108
+ Configure breakpoints as a top-level option on the orchestrator. Each entry pauses execution before/after a specific event type; `onBreakpoint` fires with a `BreakpointRequest` you resume via `orchestrator.resumeBreakpoint(id)` (with optional input modifications) or cancel via `orchestrator.cancelBreakpoint(id, reason?)`.
142
109
 
143
110
  ```typescript
111
+ import type { BreakpointConfig, BreakpointModifications } from "@directive-run/ai";
112
+
144
113
  const orchestrator = createMultiAgentOrchestrator({
145
114
  agents: { researcher, writer, editor },
146
115
  runner,
147
- debug: {
148
- timeline,
149
- breakpoints: [
150
- {
151
- id: "before-write",
152
- // Pause before the writer agent runs
153
- when: (event) => {
154
- return event.type === "agent_start" && event.agentName === "writer";
155
- },
156
- onHit: async (event, resume) => {
157
- console.log("Paused before writer. Review researcher output.");
158
- console.log("Press enter to continue...");
159
-
160
- await waitForInput();
161
- resume();
162
- },
163
- },
164
- {
165
- id: "on-error",
166
- when: (event) => {
167
- return event.type === "agent_error";
168
- },
169
- onHit: async (event, resume) => {
170
- console.error("Agent error:", event.error);
171
- // Decide whether to continue or abort
172
- resume();
173
- },
174
- },
175
- ],
116
+ breakpoints: [
117
+ { id: "before-write", before: "agent_start", filter: (e) => e.agentName === "writer" },
118
+ { id: "on-error", after: "agent_error" },
119
+ ],
120
+ onBreakpoint: async (req) => {
121
+ if (req.id === "on-error") {
122
+ // Log + cancel
123
+ console.error("breakpoint on error:", req.event);
124
+ orchestrator.cancelBreakpoint(req.id, "aborting on error");
125
+
126
+ return;
127
+ }
128
+
129
+ await waitForUserClick();
130
+ orchestrator.resumeBreakpoint(req.id);
176
131
  },
132
+ breakpointTimeoutMs: 5 * 60 * 1000,
177
133
  });
178
134
  ```
179
135
 
136
+ There is NO `breakpoint.when(event)` / `breakpoint.onHit(event, resume)` shape — those don't exist. Filter on a typed `before:` / `after:` event-type key plus an optional `filter:` predicate; resume/cancel via the orchestrator's methods.
137
+
180
138
  ## Checkpoints
181
139
 
182
- Save and restore full orchestrator state for debugging or recovery:
140
+ See `ai-orchestrator.md` and `ai-multi-agent.md` for the full checkpoint surface. Quick form:
183
141
 
184
142
  ```typescript
185
- // Save checkpoint
186
- const checkpoint = orchestrator.checkpoint();
187
- const serialized = JSON.stringify(checkpoint);
143
+ const cp = await orchestrator.checkpoint({ label: "before-risky-op" }); // async!
144
+ const serialized = JSON.stringify(cp);
188
145
 
189
- // Store to disk, database, etc.
190
- await fs.writeFile("checkpoint.json", serialized);
146
+ // Restore on an EXISTING instance — there is no `checkpoint` constructor option
147
+ const fresh = createAgentOrchestrator({ runner /* same config */ });
148
+ fresh.restore(JSON.parse(serialized));
149
+ ```
150
+
151
+ ## OpenTelemetry plugin
152
+
153
+ `createOtelPlugin({ serviceName, … })` returns a Directive plugin you pass to `createSystem({ plugins: [otel] })` (or to the orchestrator via its `plugins:` option). It emits spans for agent runs, resolver execution, guardrails, and pattern boundaries — mapped to GenAI semantic conventions.
154
+
155
+ ```typescript
156
+ import { createOtelPlugin, OtelStatusCode } from "@directive-run/ai";
191
157
 
192
- // Restore from checkpoint
193
- const saved = JSON.parse(await fs.readFile("checkpoint.json", "utf-8"));
194
- const restored = createMultiAgentOrchestrator({
195
- agents,
158
+ const otel = createOtelPlugin({
159
+ serviceName: "my-ai-app",
160
+ serviceVersion: "1.0.0",
161
+ // Optional: a custom OtelTracer. Defaults to an in-memory tracer suitable for the OTLP exporter.
162
+ tracer: customTracer,
163
+ });
164
+
165
+ const orchestrator = createAgentOrchestrator({
196
166
  runner,
197
- checkpoint: saved,
167
+ plugins: [otel],
198
168
  });
199
- restored.start();
200
169
  ```
201
170
 
202
- ## OpenTelemetry Integration
171
+ ## OTLP exporter
203
172
 
204
- Export traces to any OpenTelemetry-compatible backend:
173
+ `createOTLPExporter({ endpoint, … })` returns `{ exportMetrics, exportTraces }` — paired with an observability config that streams collected data to any OTel-compatible backend (Jaeger, Tempo, Grafana Cloud, Honeycomb, etc.).
205
174
 
206
175
  ```typescript
207
176
  import { createOTLPExporter } from "@directive-run/ai";
177
+ // (re-exported from @directive-run/core/plugins)
208
178
 
209
179
  const exporter = createOTLPExporter({
210
- endpoint: "http://localhost:4318/v1/traces",
180
+ endpoint: "http://localhost:4318",
211
181
  serviceName: "my-ai-app",
212
- // Uses GenAI semantic conventions
213
- // https://opentelemetry.io/docs/specs/semconv/gen-ai/
182
+ serviceVersion: "1.0.0",
183
+ headers: { Authorization: `Bearer ${process.env.OTEL_TOKEN}` },
184
+ timeoutMs: 10_000,
185
+ onError: (err, kind) => console.error(`[otlp] ${kind} export failed:`, err),
186
+ });
187
+
188
+ // Wire into the observability plugin (see core observability docs)
189
+ const obs = createObservabilityPlugin({
190
+ metrics: { exporter: { export: exporter.exportMetrics } },
191
+ tracing: { exporter: { export: exporter.exportTraces } },
214
192
  });
215
193
 
216
194
  const orchestrator = createAgentOrchestrator({
217
195
  runner,
218
- debug: {
219
- timeline,
220
- exporter, // Automatically exports spans
221
- },
196
+ plugins: [obs, otel],
197
+ });
198
+ ```
199
+
200
+ The exporter maps Directive events to GenAI semantic conventions. The exact mapping (gen_ai.chat, gen_ai.tool, gen_ai.guardrail, gen_ai.orchestration) lives in `@directive-run/core/plugins/otlp-exporter.ts` and tracks the OpenTelemetry GenAI spec.
201
+
202
+ ## DevTools server (live websocket export)
203
+
204
+ For browser-based devtools panels, pair `createDebugTimeline` with `createDevtoolsServer` (also from `@directive-run/ai/devtools`) — same data the in-process listener gets, streamed over a WebSocket.
205
+
206
+ ```typescript
207
+ import { createDebugTimeline, createDevtoolsServer } from "@directive-run/ai/devtools";
208
+
209
+ const timeline = createDebugTimeline({ maxEvents: 5000 });
210
+ const server = createDevtoolsServer({ timeline, port: 9229 });
211
+
212
+ server.start();
213
+ // Connect a devtools UI to ws://localhost:9229
214
+ ```
215
+
216
+ ## Anti-patterns
217
+
218
+ ### `timeline.subscribe(listener, { filter })`
219
+
220
+ ```typescript
221
+ // WRONG — subscribe takes only a listener
222
+ timeline.subscribe((e) => console.log(e), { filter: (e) => e.type === "agent_error" })
223
+
224
+ // CORRECT — filter inside the listener
225
+ timeline.subscribe((e) => {
226
+ if (e.type === "agent_error") console.log(e);
227
+ });
228
+ ```
229
+
230
+ ### `timeline.query({ type, since })`
231
+
232
+ ```typescript
233
+ // WRONG — there is no .query() method
234
+ timeline.query({ type: "agent_error", since: Date.now() - 60_000 })
235
+
236
+ // CORRECT — typed getters
237
+ timeline.getEventsByType("agent_error")
238
+ .filter((e) => e.timestamp >= Date.now() - 60_000);
239
+
240
+ // Or use range directly
241
+ timeline.getEventsInRange(Date.now() - 60_000, Date.now());
242
+ ```
243
+
244
+ ### Nesting timeline / breakpoints inside `debug:`
245
+
246
+ ```typescript
247
+ // WRONG — only verboseTimeline lives inside debug; breakpoints + timeline are top-level
248
+ createAgentOrchestrator({
249
+ runner,
250
+ debug: { timeline, verbose: true, breakpoints: [...] },
251
+ })
252
+
253
+ // CORRECT
254
+ createAgentOrchestrator({
255
+ runner,
256
+ debug: { verboseTimeline: true }, // OR just `debug: true`
257
+ breakpoints: [...], // top-level
258
+ onBreakpoint: (req) => orchestrator.resumeBreakpoint(req.id),
222
259
  });
260
+ // timeline is read off `orchestrator.timeline` after construction
261
+ ```
262
+
263
+ ### `breakpoint.when(event)` / `breakpoint.onHit(event, resume)`
264
+
265
+ ```typescript
266
+ // WRONG — these shapes don't exist
267
+ breakpoints: [
268
+ { id: "x", when: (e) => e.type === "agent_start", onHit: (e, resume) => resume() },
269
+ ]
270
+
271
+ // CORRECT — declarative before:/after: + typed filter, then orchestrator.resumeBreakpoint()
272
+ breakpoints: [
273
+ { id: "x", before: "agent_start", filter: (e) => e.agentName === "writer" },
274
+ ],
275
+ onBreakpoint: (req) => orchestrator.resumeBreakpoint(req.id),
223
276
  ```
224
277
 
225
- The exporter maps Directive events to GenAI semantic conventions:
278
+ ### Restoring a checkpoint via the constructor
226
279
 
227
- | Directive Event | OTel Span | GenAI Attribute |
228
- |---|---|---|
229
- | `agent_start` `agent_complete` | `gen_ai.chat` | `gen_ai.system`, `gen_ai.request.model` |
230
- | `resolver_start` → `resolver_complete` | `gen_ai.tool` | `gen_ai.tool.name` |
231
- | `guardrail_check` | `gen_ai.guardrail` | `gen_ai.guardrail.name`, `gen_ai.guardrail.passed` |
232
- | `pattern_start` `pattern_complete` | `gen_ai.orchestration` | `gen_ai.orchestration.pattern` |
280
+ ```typescript
281
+ // WRONG — there is no `checkpoint:` constructor option
282
+ createMultiAgentOrchestrator({ agents, patterns, runner, checkpoint: saved })
283
+
284
+ // CORRECT orch.restore() on an existing instance
285
+ const orch = createMultiAgentOrchestrator({ agents, patterns, runner });
286
+ orch.restore(saved);
287
+ orch.start();
288
+ ```
233
289
 
234
- ## Quick Reference
290
+ ### Assuming `agent_complete.output` is `string`
291
+
292
+ ```typescript
293
+ // WRONG — output is unknown, not string
294
+ timeline.subscribe((e) => {
295
+ if (e.type === "agent_complete") console.log(e.output.length); // type error
296
+ });
297
+
298
+ // CORRECT — narrow before reading
299
+ timeline.subscribe((e) => {
300
+ if (e.type === "agent_complete" && typeof e.output === "string") {
301
+ console.log(e.output.length);
302
+ }
303
+ });
304
+ ```
235
305
 
236
- | API | Purpose | Key Options |
237
- |---|---|---|
238
- | `createDebugTimeline()` | Event stream for all activity | `maxEvents` |
239
- | `timeline.subscribe()` | Listen to events in real time | callback, filter |
240
- | `timeline.query()` | Search past events | type, since |
241
- | `orchestrator.checkpoint()` | Serialize full state | returns JSON-safe object |
242
- | `createOTLPExporter()` | Export traces to OTel backend | `endpoint`, `serviceName` |
243
- | breakpoints config | Pause at specific events | `when`, `onHit`, `resume` |
306
+ ## Quick reference
307
+
308
+ | API | Purpose |
309
+ |---|---|
310
+ | `createDebugTimeline(options?)` | Typed event recorder + queryable history |
311
+ | `timeline.subscribe(listener)` | Live event stream (no filter option) |
312
+ | `timeline.getEventsByType<T>(type)` | Typed-narrowed query |
313
+ | `timeline.getEventsInRange(start, end)` | Time-bounded query |
314
+ | `timeline.getEventsForAgent(agentId)` | Per-agent stream |
315
+ | `timeline.getEventsAtSnapshot(id)` | Snapshot-aware stream |
316
+ | `timeline.forkFrom(id)` | Truncate post-snapshot + reroute |
317
+ | `timeline.export()` / `import(json)` | JSON round-trip |
318
+ | `orchestrator.timeline` | Read the timeline back off the orchestrator (`null` when `debug: false`) |
319
+ | `breakpoints: [...]` + `onBreakpoint` | Top-level orchestrator options for pause points |
320
+ | `orchestrator.resumeBreakpoint(id, mods?)` / `cancelBreakpoint(id, reason?)` | Resolve a paused breakpoint |
321
+ | `createOtelPlugin(config)` | Plugin that emits spans for orchestrator activity |
322
+ | `createOTLPExporter(config)` | Returns `{ exportMetrics, exportTraces }` for OTel backends |
323
+ | `createDevtoolsServer({ timeline, port })` | WebSocket-bridged timeline for browser devtools |