agentflow-core 0.1.3 → 0.2.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.
package/dist/index.d.ts CHANGED
@@ -276,6 +276,58 @@ interface MutableExecutionNode {
276
276
  */
277
277
  declare function createGraphBuilder(config?: AgentFlowConfig): GraphBuilder;
278
278
 
279
+ /**
280
+ * Load and deserialize execution graphs from JSON.
281
+ *
282
+ * Handles all serialization formats produced by the runner, graph-builder,
283
+ * and third-party tools:
284
+ * - `nodes` as a plain object `{ "node_001": { ... } }` (runner.ts output)
285
+ * - `nodes` as an array of `[id, node]` pairs (Map JSON serialization)
286
+ * - `nodes` already a Map (in-memory passthrough)
287
+ *
288
+ * @module
289
+ */
290
+
291
+ /**
292
+ * Deserialize a JSON object (or JSON string) into a valid `ExecutionGraph`.
293
+ *
294
+ * Use this whenever you read a trace file from disk or receive one over the
295
+ * network. It normalizes `nodes` into a proper `Map` regardless of the
296
+ * serialization format.
297
+ *
298
+ * @param input - A parsed JSON object, or a JSON string to be parsed.
299
+ * @returns A valid `ExecutionGraph` ready for use with query functions.
300
+ * @throws {Error} If the input cannot be parsed or is missing required fields.
301
+ *
302
+ * @example
303
+ * ```ts
304
+ * import { readFileSync } from 'fs';
305
+ * import { loadGraph, getStats } from 'agentflow-core';
306
+ *
307
+ * const graph = loadGraph(readFileSync('trace.json', 'utf8'));
308
+ * console.log(getStats(graph));
309
+ * ```
310
+ */
311
+ declare function loadGraph(input: string | Record<string, unknown>): ExecutionGraph;
312
+ /**
313
+ * Serialize an `ExecutionGraph` to a plain JSON-safe object.
314
+ *
315
+ * The inverse of `loadGraph`. `nodes` is written as a plain object keyed by
316
+ * node ID, which is the most readable format for trace files on disk.
317
+ *
318
+ * @param graph - The execution graph to serialize.
319
+ * @returns A plain object safe to pass to `JSON.stringify`.
320
+ *
321
+ * @example
322
+ * ```ts
323
+ * import { writeFileSync } from 'fs';
324
+ * import { graphToJson } from 'agentflow-core';
325
+ *
326
+ * writeFileSync('trace.json', JSON.stringify(graphToJson(graph), null, 2));
327
+ * ```
328
+ */
329
+ declare function graphToJson(graph: ExecutionGraph): Record<string, unknown>;
330
+
279
331
  /**
280
332
  * CLI runner that wraps any command with automatic AgentFlow tracing.
281
333
  *
@@ -325,6 +377,25 @@ interface RunResult {
325
377
  */
326
378
  declare function runTraced(config: RunConfig): Promise<RunResult>;
327
379
 
380
+ /**
381
+ * AgentFlow Live Monitor — real-time terminal dashboard for any agent system.
382
+ *
383
+ * Usage:
384
+ * agentflow live [traces-dir] [options]
385
+ * agentflow live ./traces --refresh 5
386
+ *
387
+ * Features:
388
+ * - Auto-discovers agents from trace files
389
+ * - Sparkline activity graph (1 hour)
390
+ * - Per-agent success/failure table
391
+ * - Distributed trace tree view
392
+ * - Recent execution feed
393
+ * - fs.watch auto-refresh on new traces
394
+ *
395
+ * @module
396
+ */
397
+ declare function startLive(argv: string[]): void;
398
+
328
399
  declare function groupByTraceId(graphs: ExecutionGraph[]): Map<string, ExecutionGraph[]>;
329
400
  declare function stitchTrace(graphs: ExecutionGraph[]): DistributedTrace;
330
401
  declare function getTraceTree(trace: DistributedTrace): ExecutionGraph[];
@@ -445,4 +516,4 @@ declare function getDepth(graph: ExecutionGraph): number;
445
516
  */
446
517
  declare function getStats(graph: ExecutionGraph): GraphStats;
447
518
 
448
- export { type Adapter, type AgentFlowConfig, type DistributedTrace, type EdgeType, type ExecutionEdge, type ExecutionGraph, type ExecutionNode, type GraphBuilder, type GraphStats, type GraphStatus, type MutableExecutionNode, type NodeStatus, type NodeType, type RunConfig, type RunResult, type StartNodeOptions, type TraceEvent, type TraceEventType, type Writer, createGraphBuilder, findWaitingOn, getChildren, getCriticalPath, getDepth, getDuration, getFailures, getHungNodes, getNode, getParent, getStats, getSubtree, getTraceTree, groupByTraceId, runTraced, stitchTrace };
519
+ export { type Adapter, type AgentFlowConfig, type DistributedTrace, type EdgeType, type ExecutionEdge, type ExecutionGraph, type ExecutionNode, type GraphBuilder, type GraphStats, type GraphStatus, type MutableExecutionNode, type NodeStatus, type NodeType, type RunConfig, type RunResult, type StartNodeOptions, type TraceEvent, type TraceEventType, type Writer, createGraphBuilder, findWaitingOn, getChildren, getCriticalPath, getDepth, getDuration, getFailures, getHungNodes, getNode, getParent, getStats, getSubtree, getTraceTree, graphToJson, groupByTraceId, loadGraph, runTraced, startLive, stitchTrace };
package/dist/index.js CHANGED
@@ -1,210 +1,24 @@
1
1
  import {
2
2
  createGraphBuilder,
3
- runTraced
4
- } from "./chunk-DGLK6IBP.js";
5
-
6
- // src/graph-stitch.ts
7
- function groupByTraceId(graphs) {
8
- const groups = /* @__PURE__ */ new Map();
9
- for (const g of graphs) {
10
- if (!g.traceId) continue;
11
- const arr = groups.get(g.traceId) ?? [];
12
- arr.push(g);
13
- groups.set(g.traceId, arr);
14
- }
15
- return groups;
16
- }
17
- function stitchTrace(graphs) {
18
- if (graphs.length === 0) throw new Error("No graphs to stitch");
19
- const traceId = graphs[0].traceId ?? "";
20
- const graphsBySpan = /* @__PURE__ */ new Map();
21
- const childMap = /* @__PURE__ */ new Map();
22
- let rootGraph = null;
23
- for (const g of graphs) {
24
- if (g.spanId) graphsBySpan.set(g.spanId, g);
25
- if (!g.parentSpanId) {
26
- if (!rootGraph || g.startTime < rootGraph.startTime) rootGraph = g;
27
- }
28
- if (g.parentSpanId) {
29
- const siblings = childMap.get(g.parentSpanId) ?? [];
30
- if (g.spanId) siblings.push(g.spanId);
31
- childMap.set(g.parentSpanId, siblings);
32
- }
33
- }
34
- if (!rootGraph) rootGraph = graphs[0];
35
- let status = "completed";
36
- let endTime = 0;
37
- let startTime = Infinity;
38
- for (const g of graphs) {
39
- startTime = Math.min(startTime, g.startTime);
40
- if (g.status === "failed") status = "failed";
41
- else if (g.status === "running" && status !== "failed") status = "running";
42
- if (g.endTime === null) endTime = null;
43
- else if (endTime !== null) endTime = Math.max(endTime, g.endTime);
44
- }
45
- const frozenChildMap = /* @__PURE__ */ new Map();
46
- for (const [k, v] of childMap) frozenChildMap.set(k, Object.freeze([...v]));
47
- return Object.freeze({
48
- traceId,
49
- graphs: graphsBySpan,
50
- rootGraph,
51
- childMap: frozenChildMap,
52
- startTime,
53
- endTime,
54
- status
55
- });
56
- }
57
- function getTraceTree(trace) {
58
- const result = [];
59
- function walk(spanId) {
60
- const graph = trace.graphs.get(spanId);
61
- if (graph) result.push(graph);
62
- const children = trace.childMap.get(spanId) ?? [];
63
- for (const childSpan of children) walk(childSpan);
64
- }
65
- if (trace.rootGraph.spanId) walk(trace.rootGraph.spanId);
66
- else result.push(trace.rootGraph);
67
- return result;
68
- }
69
-
70
- // src/graph-query.ts
71
- function getNode(graph, nodeId) {
72
- return graph.nodes.get(nodeId);
73
- }
74
- function getChildren(graph, nodeId) {
75
- const node = graph.nodes.get(nodeId);
76
- if (!node) return [];
77
- const result = [];
78
- for (const childId of node.children) {
79
- const child = graph.nodes.get(childId);
80
- if (child) result.push(child);
81
- }
82
- return result;
83
- }
84
- function getParent(graph, nodeId) {
85
- const node = graph.nodes.get(nodeId);
86
- if (!node || node.parentId === null) return void 0;
87
- return graph.nodes.get(node.parentId);
88
- }
89
- function getFailures(graph) {
90
- const failureStatuses = /* @__PURE__ */ new Set(["failed", "hung", "timeout"]);
91
- return [...graph.nodes.values()].filter((node) => failureStatuses.has(node.status));
92
- }
93
- function getHungNodes(graph) {
94
- return [...graph.nodes.values()].filter(
95
- (node) => node.status === "running" && node.endTime === null
96
- );
97
- }
98
- function getCriticalPath(graph) {
99
- const root = graph.nodes.get(graph.rootNodeId);
100
- if (!root) return [];
101
- function nodeDuration(node) {
102
- const end = node.endTime ?? Date.now();
103
- return end - node.startTime;
104
- }
105
- function dfs(node) {
106
- if (node.children.length === 0) {
107
- return { duration: nodeDuration(node), path: [node] };
108
- }
109
- let bestChild = { duration: -1, path: [] };
110
- for (const childId of node.children) {
111
- const child = graph.nodes.get(childId);
112
- if (!child) continue;
113
- const result = dfs(child);
114
- if (result.duration > bestChild.duration) {
115
- bestChild = result;
116
- }
117
- }
118
- return {
119
- duration: nodeDuration(node) + bestChild.duration,
120
- path: [node, ...bestChild.path]
121
- };
122
- }
123
- return dfs(root).path;
124
- }
125
- function findWaitingOn(graph, nodeId) {
126
- const results = [];
127
- for (const edge of graph.edges) {
128
- if (edge.from === nodeId && edge.type === "waited_on") {
129
- const node = graph.nodes.get(edge.to);
130
- if (node) results.push(node);
131
- }
132
- }
133
- return results;
134
- }
135
- function getSubtree(graph, nodeId) {
136
- const startNode = graph.nodes.get(nodeId);
137
- if (!startNode) return [];
138
- const result = [];
139
- const queue = [...startNode.children];
140
- while (queue.length > 0) {
141
- const currentId = queue.shift();
142
- if (currentId === void 0) break;
143
- const current = graph.nodes.get(currentId);
144
- if (!current) continue;
145
- result.push(current);
146
- queue.push(...current.children);
147
- }
148
- return result;
149
- }
150
- function getDuration(graph) {
151
- const end = graph.endTime ?? Date.now();
152
- return end - graph.startTime;
153
- }
154
- function getDepth(graph) {
155
- const root = graph.nodes.get(graph.rootNodeId);
156
- if (!root) return -1;
157
- function dfs(node, depth) {
158
- if (node.children.length === 0) return depth;
159
- let maxDepth = depth;
160
- for (const childId of node.children) {
161
- const child = graph.nodes.get(childId);
162
- if (!child) continue;
163
- const childDepth = dfs(child, depth + 1);
164
- if (childDepth > maxDepth) maxDepth = childDepth;
165
- }
166
- return maxDepth;
167
- }
168
- return dfs(root, 0);
169
- }
170
- function getStats(graph) {
171
- const byStatus = {
172
- running: 0,
173
- completed: 0,
174
- failed: 0,
175
- hung: 0,
176
- timeout: 0
177
- };
178
- const byType = {
179
- agent: 0,
180
- tool: 0,
181
- subagent: 0,
182
- wait: 0,
183
- decision: 0,
184
- custom: 0
185
- };
186
- let failureCount = 0;
187
- let hungCount = 0;
188
- for (const node of graph.nodes.values()) {
189
- byStatus[node.status]++;
190
- byType[node.type]++;
191
- if (node.status === "failed" || node.status === "timeout" || node.status === "hung") {
192
- failureCount++;
193
- }
194
- if (node.status === "running" && node.endTime === null) {
195
- hungCount++;
196
- }
197
- }
198
- return {
199
- totalNodes: graph.nodes.size,
200
- byStatus,
201
- byType,
202
- depth: getDepth(graph),
203
- duration: getDuration(graph),
204
- failureCount,
205
- hungCount
206
- };
207
- }
3
+ findWaitingOn,
4
+ getChildren,
5
+ getCriticalPath,
6
+ getDepth,
7
+ getDuration,
8
+ getFailures,
9
+ getHungNodes,
10
+ getNode,
11
+ getParent,
12
+ getStats,
13
+ getSubtree,
14
+ getTraceTree,
15
+ graphToJson,
16
+ groupByTraceId,
17
+ loadGraph,
18
+ runTraced,
19
+ startLive,
20
+ stitchTrace
21
+ } from "./chunk-TRKBUPIN.js";
208
22
  export {
209
23
  createGraphBuilder,
210
24
  findWaitingOn,
@@ -219,7 +33,10 @@ export {
219
33
  getStats,
220
34
  getSubtree,
221
35
  getTraceTree,
36
+ graphToJson,
222
37
  groupByTraceId,
38
+ loadGraph,
223
39
  runTraced,
40
+ startLive,
224
41
  stitchTrace
225
42
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentflow-core",
3
- "version": "0.1.3",
3
+ "version": "0.2.0",
4
4
  "description": "Universal execution tracing for AI agent systems",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",