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/chunk-TRKBUPIN.js +933 -0
- package/dist/cli.cjs +521 -33
- package/dist/cli.js +57 -14
- package/dist/index.cjs +403 -84
- package/dist/index.d.cts +72 -1
- package/dist/index.d.ts +72 -1
- package/dist/index.js +22 -205
- package/package.json +1 -1
- package/dist/chunk-DGLK6IBP.js +0 -402
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
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
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
|
};
|