agentflow-core 0.1.1 → 0.1.3
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-DGLK6IBP.js +402 -0
- package/dist/cli.cjs +542 -0
- package/dist/cli.d.cts +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +142 -0
- package/dist/index.cjs +257 -3
- package/dist/index.d.cts +79 -1
- package/dist/index.d.ts +79 -1
- package/dist/index.js +65 -208
- package/package.json +6 -3
package/dist/index.cjs
CHANGED
|
@@ -31,11 +31,16 @@ __export(index_exports, {
|
|
|
31
31
|
getNode: () => getNode,
|
|
32
32
|
getParent: () => getParent,
|
|
33
33
|
getStats: () => getStats,
|
|
34
|
-
getSubtree: () => getSubtree
|
|
34
|
+
getSubtree: () => getSubtree,
|
|
35
|
+
getTraceTree: () => getTraceTree,
|
|
36
|
+
groupByTraceId: () => groupByTraceId,
|
|
37
|
+
runTraced: () => runTraced,
|
|
38
|
+
stitchTrace: () => stitchTrace
|
|
35
39
|
});
|
|
36
40
|
module.exports = __toCommonJS(index_exports);
|
|
37
41
|
|
|
38
42
|
// src/graph-builder.ts
|
|
43
|
+
var import_crypto = require("crypto");
|
|
39
44
|
function deepFreeze(obj) {
|
|
40
45
|
if (obj === null || typeof obj !== "object") return obj;
|
|
41
46
|
if (obj instanceof Map) {
|
|
@@ -66,6 +71,9 @@ function createGraphBuilder(config) {
|
|
|
66
71
|
const generateId = config?.idGenerator ?? createCounterIdGenerator();
|
|
67
72
|
const agentId = config?.agentId ?? "unknown";
|
|
68
73
|
const trigger = config?.trigger ?? "manual";
|
|
74
|
+
const spanId = (0, import_crypto.randomUUID)();
|
|
75
|
+
const traceId = config?.traceId ?? (typeof process !== "undefined" ? process.env?.AGENTFLOW_TRACE_ID : void 0) ?? (0, import_crypto.randomUUID)();
|
|
76
|
+
const parentSpanId = config?.parentSpanId ?? (typeof process !== "undefined" ? process.env?.AGENTFLOW_PARENT_SPAN_ID : void 0) ?? null;
|
|
69
77
|
const graphId = generateId();
|
|
70
78
|
const startTime = Date.now();
|
|
71
79
|
const nodes = /* @__PURE__ */ new Map();
|
|
@@ -136,7 +144,10 @@ function createGraphBuilder(config) {
|
|
|
136
144
|
status: graphStatus,
|
|
137
145
|
trigger,
|
|
138
146
|
agentId,
|
|
139
|
-
events: [...events]
|
|
147
|
+
events: [...events],
|
|
148
|
+
traceId,
|
|
149
|
+
spanId,
|
|
150
|
+
parentSpanId
|
|
140
151
|
};
|
|
141
152
|
return deepFreeze(graph);
|
|
142
153
|
}
|
|
@@ -144,6 +155,9 @@ function createGraphBuilder(config) {
|
|
|
144
155
|
get graphId() {
|
|
145
156
|
return graphId;
|
|
146
157
|
},
|
|
158
|
+
get traceContext() {
|
|
159
|
+
return { traceId, spanId };
|
|
160
|
+
},
|
|
147
161
|
startNode(opts) {
|
|
148
162
|
assertNotBuilt();
|
|
149
163
|
const id = generateId();
|
|
@@ -251,6 +265,242 @@ function createGraphBuilder(config) {
|
|
|
251
265
|
return builder;
|
|
252
266
|
}
|
|
253
267
|
|
|
268
|
+
// src/runner.ts
|
|
269
|
+
var import_node_child_process = require("child_process");
|
|
270
|
+
var import_node_fs = require("fs");
|
|
271
|
+
var import_node_path = require("path");
|
|
272
|
+
function globToRegex(pattern) {
|
|
273
|
+
const escaped = pattern.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*").replace(/\?/g, ".");
|
|
274
|
+
return new RegExp(`^${escaped}$`);
|
|
275
|
+
}
|
|
276
|
+
function snapshotDir(dir, patterns) {
|
|
277
|
+
const result = /* @__PURE__ */ new Map();
|
|
278
|
+
if (!(0, import_node_fs.existsSync)(dir)) return result;
|
|
279
|
+
for (const entry of (0, import_node_fs.readdirSync)(dir)) {
|
|
280
|
+
if (!patterns.some((re) => re.test(entry))) continue;
|
|
281
|
+
const full = (0, import_node_path.join)(dir, entry);
|
|
282
|
+
try {
|
|
283
|
+
const stat = (0, import_node_fs.statSync)(full);
|
|
284
|
+
if (stat.isFile()) {
|
|
285
|
+
result.set(full, stat.mtimeMs);
|
|
286
|
+
}
|
|
287
|
+
} catch {
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
return result;
|
|
291
|
+
}
|
|
292
|
+
function agentIdFromFilename(filePath) {
|
|
293
|
+
const base = (0, import_node_path.basename)(filePath, ".json");
|
|
294
|
+
const cleaned = base.replace(/-state$/, "");
|
|
295
|
+
return `alfred-${cleaned}`;
|
|
296
|
+
}
|
|
297
|
+
function deriveAgentId(command) {
|
|
298
|
+
return "orchestrator";
|
|
299
|
+
}
|
|
300
|
+
function fileTimestamp() {
|
|
301
|
+
return (/* @__PURE__ */ new Date()).toISOString().replace(/:/g, "-").replace(/\.\d+Z$/, "");
|
|
302
|
+
}
|
|
303
|
+
function graphToJson(graph) {
|
|
304
|
+
const nodesObj = {};
|
|
305
|
+
for (const [id, node] of graph.nodes) {
|
|
306
|
+
nodesObj[id] = node;
|
|
307
|
+
}
|
|
308
|
+
return {
|
|
309
|
+
id: graph.id,
|
|
310
|
+
rootNodeId: graph.rootNodeId,
|
|
311
|
+
nodes: nodesObj,
|
|
312
|
+
edges: graph.edges,
|
|
313
|
+
startTime: graph.startTime,
|
|
314
|
+
endTime: graph.endTime,
|
|
315
|
+
status: graph.status,
|
|
316
|
+
trigger: graph.trigger,
|
|
317
|
+
agentId: graph.agentId,
|
|
318
|
+
events: graph.events,
|
|
319
|
+
traceId: graph.traceId,
|
|
320
|
+
spanId: graph.spanId,
|
|
321
|
+
parentSpanId: graph.parentSpanId
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
async function runTraced(config) {
|
|
325
|
+
const {
|
|
326
|
+
command,
|
|
327
|
+
agentId = deriveAgentId(command),
|
|
328
|
+
trigger = "cli",
|
|
329
|
+
tracesDir = "./traces",
|
|
330
|
+
watchDirs = [],
|
|
331
|
+
watchPatterns = ["*.json"]
|
|
332
|
+
} = config;
|
|
333
|
+
if (command.length === 0) {
|
|
334
|
+
throw new Error("runTraced: command must not be empty");
|
|
335
|
+
}
|
|
336
|
+
const resolvedTracesDir = (0, import_node_path.resolve)(tracesDir);
|
|
337
|
+
const patterns = watchPatterns.map(globToRegex);
|
|
338
|
+
const orchestrator = createGraphBuilder({ agentId, trigger });
|
|
339
|
+
const { traceId, spanId } = orchestrator.traceContext;
|
|
340
|
+
const beforeSnapshots = /* @__PURE__ */ new Map();
|
|
341
|
+
for (const dir of watchDirs) {
|
|
342
|
+
beforeSnapshots.set(dir, snapshotDir(dir, patterns));
|
|
343
|
+
}
|
|
344
|
+
const rootId = orchestrator.startNode({ type: "agent", name: agentId });
|
|
345
|
+
const dispatchId = orchestrator.startNode({
|
|
346
|
+
type: "tool",
|
|
347
|
+
name: "dispatch-command",
|
|
348
|
+
parentId: rootId
|
|
349
|
+
});
|
|
350
|
+
orchestrator.updateState(dispatchId, { command: command.join(" ") });
|
|
351
|
+
const monitorId = orchestrator.startNode({
|
|
352
|
+
type: "tool",
|
|
353
|
+
name: "state-monitor",
|
|
354
|
+
parentId: rootId
|
|
355
|
+
});
|
|
356
|
+
orchestrator.updateState(monitorId, {
|
|
357
|
+
watchDirs,
|
|
358
|
+
watchPatterns
|
|
359
|
+
});
|
|
360
|
+
const startMs = Date.now();
|
|
361
|
+
const execCmd = command[0] ?? "";
|
|
362
|
+
const execArgs = command.slice(1);
|
|
363
|
+
process.env.AGENTFLOW_TRACE_ID = traceId;
|
|
364
|
+
process.env.AGENTFLOW_PARENT_SPAN_ID = spanId;
|
|
365
|
+
const result = (0, import_node_child_process.spawnSync)(execCmd, execArgs, { stdio: "inherit" });
|
|
366
|
+
delete process.env.AGENTFLOW_TRACE_ID;
|
|
367
|
+
delete process.env.AGENTFLOW_PARENT_SPAN_ID;
|
|
368
|
+
const exitCode = result.status ?? 1;
|
|
369
|
+
const duration = (Date.now() - startMs) / 1e3;
|
|
370
|
+
const stateChanges = [];
|
|
371
|
+
for (const dir of watchDirs) {
|
|
372
|
+
const before = beforeSnapshots.get(dir) ?? /* @__PURE__ */ new Map();
|
|
373
|
+
const after = snapshotDir(dir, patterns);
|
|
374
|
+
for (const [filePath, mtime] of after) {
|
|
375
|
+
const prevMtime = before.get(filePath);
|
|
376
|
+
if (prevMtime === void 0 || mtime > prevMtime) {
|
|
377
|
+
stateChanges.push(filePath);
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
orchestrator.updateState(monitorId, { stateChanges });
|
|
382
|
+
orchestrator.endNode(monitorId);
|
|
383
|
+
if (exitCode === 0) {
|
|
384
|
+
orchestrator.endNode(dispatchId);
|
|
385
|
+
} else {
|
|
386
|
+
orchestrator.failNode(dispatchId, `Command exited with code ${exitCode}`);
|
|
387
|
+
}
|
|
388
|
+
orchestrator.updateState(rootId, {
|
|
389
|
+
exitCode,
|
|
390
|
+
duration,
|
|
391
|
+
stateChanges
|
|
392
|
+
});
|
|
393
|
+
if (exitCode === 0) {
|
|
394
|
+
orchestrator.endNode(rootId);
|
|
395
|
+
} else {
|
|
396
|
+
orchestrator.failNode(rootId, `Command exited with code ${exitCode}`);
|
|
397
|
+
}
|
|
398
|
+
const orchestratorGraph = orchestrator.build();
|
|
399
|
+
const allGraphs = [orchestratorGraph];
|
|
400
|
+
for (const filePath of stateChanges) {
|
|
401
|
+
const childAgentId = agentIdFromFilename(filePath);
|
|
402
|
+
const childBuilder = createGraphBuilder({
|
|
403
|
+
agentId: childAgentId,
|
|
404
|
+
trigger: "state-change",
|
|
405
|
+
traceId,
|
|
406
|
+
parentSpanId: spanId
|
|
407
|
+
});
|
|
408
|
+
const childRootId = childBuilder.startNode({
|
|
409
|
+
type: "agent",
|
|
410
|
+
name: childAgentId
|
|
411
|
+
});
|
|
412
|
+
childBuilder.updateState(childRootId, {
|
|
413
|
+
stateFile: filePath,
|
|
414
|
+
detectedBy: "runner-state-monitor"
|
|
415
|
+
});
|
|
416
|
+
childBuilder.endNode(childRootId);
|
|
417
|
+
allGraphs.push(childBuilder.build());
|
|
418
|
+
}
|
|
419
|
+
if (!(0, import_node_fs.existsSync)(resolvedTracesDir)) {
|
|
420
|
+
(0, import_node_fs.mkdirSync)(resolvedTracesDir, { recursive: true });
|
|
421
|
+
}
|
|
422
|
+
const ts = fileTimestamp();
|
|
423
|
+
const tracePaths = [];
|
|
424
|
+
for (const graph of allGraphs) {
|
|
425
|
+
const filename = `${graph.agentId}-${ts}.json`;
|
|
426
|
+
const outPath = (0, import_node_path.join)(resolvedTracesDir, filename);
|
|
427
|
+
(0, import_node_fs.writeFileSync)(outPath, JSON.stringify(graphToJson(graph), null, 2), "utf-8");
|
|
428
|
+
tracePaths.push(outPath);
|
|
429
|
+
}
|
|
430
|
+
return {
|
|
431
|
+
exitCode,
|
|
432
|
+
traceId,
|
|
433
|
+
spanId,
|
|
434
|
+
tracePaths,
|
|
435
|
+
stateChanges,
|
|
436
|
+
duration
|
|
437
|
+
};
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
// src/graph-stitch.ts
|
|
441
|
+
function groupByTraceId(graphs) {
|
|
442
|
+
const groups = /* @__PURE__ */ new Map();
|
|
443
|
+
for (const g of graphs) {
|
|
444
|
+
if (!g.traceId) continue;
|
|
445
|
+
const arr = groups.get(g.traceId) ?? [];
|
|
446
|
+
arr.push(g);
|
|
447
|
+
groups.set(g.traceId, arr);
|
|
448
|
+
}
|
|
449
|
+
return groups;
|
|
450
|
+
}
|
|
451
|
+
function stitchTrace(graphs) {
|
|
452
|
+
if (graphs.length === 0) throw new Error("No graphs to stitch");
|
|
453
|
+
const traceId = graphs[0].traceId ?? "";
|
|
454
|
+
const graphsBySpan = /* @__PURE__ */ new Map();
|
|
455
|
+
const childMap = /* @__PURE__ */ new Map();
|
|
456
|
+
let rootGraph = null;
|
|
457
|
+
for (const g of graphs) {
|
|
458
|
+
if (g.spanId) graphsBySpan.set(g.spanId, g);
|
|
459
|
+
if (!g.parentSpanId) {
|
|
460
|
+
if (!rootGraph || g.startTime < rootGraph.startTime) rootGraph = g;
|
|
461
|
+
}
|
|
462
|
+
if (g.parentSpanId) {
|
|
463
|
+
const siblings = childMap.get(g.parentSpanId) ?? [];
|
|
464
|
+
if (g.spanId) siblings.push(g.spanId);
|
|
465
|
+
childMap.set(g.parentSpanId, siblings);
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
if (!rootGraph) rootGraph = graphs[0];
|
|
469
|
+
let status = "completed";
|
|
470
|
+
let endTime = 0;
|
|
471
|
+
let startTime = Infinity;
|
|
472
|
+
for (const g of graphs) {
|
|
473
|
+
startTime = Math.min(startTime, g.startTime);
|
|
474
|
+
if (g.status === "failed") status = "failed";
|
|
475
|
+
else if (g.status === "running" && status !== "failed") status = "running";
|
|
476
|
+
if (g.endTime === null) endTime = null;
|
|
477
|
+
else if (endTime !== null) endTime = Math.max(endTime, g.endTime);
|
|
478
|
+
}
|
|
479
|
+
const frozenChildMap = /* @__PURE__ */ new Map();
|
|
480
|
+
for (const [k, v] of childMap) frozenChildMap.set(k, Object.freeze([...v]));
|
|
481
|
+
return Object.freeze({
|
|
482
|
+
traceId,
|
|
483
|
+
graphs: graphsBySpan,
|
|
484
|
+
rootGraph,
|
|
485
|
+
childMap: frozenChildMap,
|
|
486
|
+
startTime,
|
|
487
|
+
endTime,
|
|
488
|
+
status
|
|
489
|
+
});
|
|
490
|
+
}
|
|
491
|
+
function getTraceTree(trace) {
|
|
492
|
+
const result = [];
|
|
493
|
+
function walk(spanId) {
|
|
494
|
+
const graph = trace.graphs.get(spanId);
|
|
495
|
+
if (graph) result.push(graph);
|
|
496
|
+
const children = trace.childMap.get(spanId) ?? [];
|
|
497
|
+
for (const childSpan of children) walk(childSpan);
|
|
498
|
+
}
|
|
499
|
+
if (trace.rootGraph.spanId) walk(trace.rootGraph.spanId);
|
|
500
|
+
else result.push(trace.rootGraph);
|
|
501
|
+
return result;
|
|
502
|
+
}
|
|
503
|
+
|
|
254
504
|
// src/graph-query.ts
|
|
255
505
|
function getNode(graph, nodeId) {
|
|
256
506
|
return graph.nodes.get(nodeId);
|
|
@@ -402,5 +652,9 @@ function getStats(graph) {
|
|
|
402
652
|
getNode,
|
|
403
653
|
getParent,
|
|
404
654
|
getStats,
|
|
405
|
-
getSubtree
|
|
655
|
+
getSubtree,
|
|
656
|
+
getTraceTree,
|
|
657
|
+
groupByTraceId,
|
|
658
|
+
runTraced,
|
|
659
|
+
stitchTrace
|
|
406
660
|
});
|
package/dist/index.d.cts
CHANGED
|
@@ -65,6 +65,12 @@ interface ExecutionGraph {
|
|
|
65
65
|
readonly agentId: string;
|
|
66
66
|
/** Full ordered event log for auditability. */
|
|
67
67
|
readonly events: readonly TraceEvent[];
|
|
68
|
+
/** Distributed trace ID linking graphs across services. */
|
|
69
|
+
readonly traceId?: string;
|
|
70
|
+
/** Unique span ID for this graph within the trace. */
|
|
71
|
+
readonly spanId?: string;
|
|
72
|
+
/** Parent span ID, or null if this is the root span. */
|
|
73
|
+
readonly parentSpanId?: string | null;
|
|
68
74
|
}
|
|
69
75
|
/**
|
|
70
76
|
* Configuration for AgentFlow.
|
|
@@ -100,6 +106,10 @@ interface AgentFlowConfig {
|
|
|
100
106
|
readonly logger?: (message: string) => void;
|
|
101
107
|
/** Error callback for internal failures. */
|
|
102
108
|
readonly onError?: (error: unknown) => void;
|
|
109
|
+
/** Distributed trace ID to join an existing trace. */
|
|
110
|
+
readonly traceId?: string;
|
|
111
|
+
/** Parent span ID for linking to an upstream graph. */
|
|
112
|
+
readonly parentSpanId?: string;
|
|
103
113
|
}
|
|
104
114
|
/**
|
|
105
115
|
* Output adapter interface. Writers receive the completed execution graph
|
|
@@ -161,6 +171,11 @@ interface StartNodeOptions {
|
|
|
161
171
|
interface GraphBuilder {
|
|
162
172
|
/** The graph's ID, available before `build()`. */
|
|
163
173
|
readonly graphId: string;
|
|
174
|
+
/** Trace context for propagating distributed trace information. */
|
|
175
|
+
readonly traceContext: {
|
|
176
|
+
traceId: string;
|
|
177
|
+
spanId: string;
|
|
178
|
+
};
|
|
164
179
|
/** Start a new execution node. Returns the generated node ID. */
|
|
165
180
|
startNode(opts: StartNodeOptions): string;
|
|
166
181
|
/** End a node. Status defaults to `'completed'`. */
|
|
@@ -204,6 +219,16 @@ interface GraphStats {
|
|
|
204
219
|
readonly failureCount: number;
|
|
205
220
|
readonly hungCount: number;
|
|
206
221
|
}
|
|
222
|
+
/** A stitched distributed trace spanning multiple execution graphs. */
|
|
223
|
+
interface DistributedTrace {
|
|
224
|
+
readonly traceId: string;
|
|
225
|
+
readonly graphs: ReadonlyMap<string, ExecutionGraph>;
|
|
226
|
+
readonly rootGraph: ExecutionGraph;
|
|
227
|
+
readonly childMap: ReadonlyMap<string, readonly string[]>;
|
|
228
|
+
readonly startTime: number;
|
|
229
|
+
readonly endTime: number | null;
|
|
230
|
+
readonly status: GraphStatus;
|
|
231
|
+
}
|
|
207
232
|
/** @internal Mutable version of ExecutionNode used during graph construction. */
|
|
208
233
|
interface MutableExecutionNode {
|
|
209
234
|
id: string;
|
|
@@ -251,6 +276,59 @@ interface MutableExecutionNode {
|
|
|
251
276
|
*/
|
|
252
277
|
declare function createGraphBuilder(config?: AgentFlowConfig): GraphBuilder;
|
|
253
278
|
|
|
279
|
+
/**
|
|
280
|
+
* CLI runner that wraps any command with automatic AgentFlow tracing.
|
|
281
|
+
*
|
|
282
|
+
* No code changes needed in the target application — the runner sets
|
|
283
|
+
* AGENTFLOW_TRACE_ID and AGENTFLOW_PARENT_SPAN_ID env vars so any child
|
|
284
|
+
* process using AgentFlow auto-joins the distributed trace.
|
|
285
|
+
*
|
|
286
|
+
* @example
|
|
287
|
+
* ```ts
|
|
288
|
+
* const result = await runTraced({
|
|
289
|
+
* command: ['python', '-m', 'alfred', 'process'],
|
|
290
|
+
* watchDirs: ['/home/trader/.alfred/data'],
|
|
291
|
+
* });
|
|
292
|
+
* ```
|
|
293
|
+
* @module
|
|
294
|
+
*/
|
|
295
|
+
interface RunConfig {
|
|
296
|
+
/** Command to execute (e.g. ['python', '-m', 'alfred', 'process']). */
|
|
297
|
+
command: string[];
|
|
298
|
+
/** Agent ID for the orchestrator trace (default: derived from command). */
|
|
299
|
+
agentId?: string;
|
|
300
|
+
/** Trigger label (default: "cli"). */
|
|
301
|
+
trigger?: string;
|
|
302
|
+
/** Directory to save trace files (default: ./traces). */
|
|
303
|
+
tracesDir?: string;
|
|
304
|
+
/** Directories to watch for state file changes during execution. */
|
|
305
|
+
watchDirs?: string[];
|
|
306
|
+
/** File patterns to watch (default: ["*.json"]). */
|
|
307
|
+
watchPatterns?: string[];
|
|
308
|
+
}
|
|
309
|
+
interface RunResult {
|
|
310
|
+
exitCode: number;
|
|
311
|
+
traceId: string;
|
|
312
|
+
spanId: string;
|
|
313
|
+
tracePaths: string[];
|
|
314
|
+
stateChanges: string[];
|
|
315
|
+
duration: number;
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* Run a command with automatic AgentFlow tracing.
|
|
319
|
+
*
|
|
320
|
+
* 1. Creates an orchestrator (parent) trace.
|
|
321
|
+
* 2. Snapshots watched directories.
|
|
322
|
+
* 3. Spawns the command with trace env vars.
|
|
323
|
+
* 4. After exit, detects state file changes and creates child traces.
|
|
324
|
+
* 5. Saves all trace JSON files.
|
|
325
|
+
*/
|
|
326
|
+
declare function runTraced(config: RunConfig): Promise<RunResult>;
|
|
327
|
+
|
|
328
|
+
declare function groupByTraceId(graphs: ExecutionGraph[]): Map<string, ExecutionGraph[]>;
|
|
329
|
+
declare function stitchTrace(graphs: ExecutionGraph[]): DistributedTrace;
|
|
330
|
+
declare function getTraceTree(trace: DistributedTrace): ExecutionGraph[];
|
|
331
|
+
|
|
254
332
|
/**
|
|
255
333
|
* Pure query functions for interrogating a built `ExecutionGraph`.
|
|
256
334
|
* Every function takes a frozen graph and returns derived data without mutation.
|
|
@@ -367,4 +445,4 @@ declare function getDepth(graph: ExecutionGraph): number;
|
|
|
367
445
|
*/
|
|
368
446
|
declare function getStats(graph: ExecutionGraph): GraphStats;
|
|
369
447
|
|
|
370
|
-
export { type Adapter, type AgentFlowConfig, type EdgeType, type ExecutionEdge, type ExecutionGraph, type ExecutionNode, type GraphBuilder, type GraphStats, type GraphStatus, type MutableExecutionNode, type NodeStatus, type NodeType, type StartNodeOptions, type TraceEvent, type TraceEventType, type Writer, createGraphBuilder, findWaitingOn, getChildren, getCriticalPath, getDepth, getDuration, getFailures, getHungNodes, getNode, getParent, getStats, getSubtree };
|
|
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 };
|
package/dist/index.d.ts
CHANGED
|
@@ -65,6 +65,12 @@ interface ExecutionGraph {
|
|
|
65
65
|
readonly agentId: string;
|
|
66
66
|
/** Full ordered event log for auditability. */
|
|
67
67
|
readonly events: readonly TraceEvent[];
|
|
68
|
+
/** Distributed trace ID linking graphs across services. */
|
|
69
|
+
readonly traceId?: string;
|
|
70
|
+
/** Unique span ID for this graph within the trace. */
|
|
71
|
+
readonly spanId?: string;
|
|
72
|
+
/** Parent span ID, or null if this is the root span. */
|
|
73
|
+
readonly parentSpanId?: string | null;
|
|
68
74
|
}
|
|
69
75
|
/**
|
|
70
76
|
* Configuration for AgentFlow.
|
|
@@ -100,6 +106,10 @@ interface AgentFlowConfig {
|
|
|
100
106
|
readonly logger?: (message: string) => void;
|
|
101
107
|
/** Error callback for internal failures. */
|
|
102
108
|
readonly onError?: (error: unknown) => void;
|
|
109
|
+
/** Distributed trace ID to join an existing trace. */
|
|
110
|
+
readonly traceId?: string;
|
|
111
|
+
/** Parent span ID for linking to an upstream graph. */
|
|
112
|
+
readonly parentSpanId?: string;
|
|
103
113
|
}
|
|
104
114
|
/**
|
|
105
115
|
* Output adapter interface. Writers receive the completed execution graph
|
|
@@ -161,6 +171,11 @@ interface StartNodeOptions {
|
|
|
161
171
|
interface GraphBuilder {
|
|
162
172
|
/** The graph's ID, available before `build()`. */
|
|
163
173
|
readonly graphId: string;
|
|
174
|
+
/** Trace context for propagating distributed trace information. */
|
|
175
|
+
readonly traceContext: {
|
|
176
|
+
traceId: string;
|
|
177
|
+
spanId: string;
|
|
178
|
+
};
|
|
164
179
|
/** Start a new execution node. Returns the generated node ID. */
|
|
165
180
|
startNode(opts: StartNodeOptions): string;
|
|
166
181
|
/** End a node. Status defaults to `'completed'`. */
|
|
@@ -204,6 +219,16 @@ interface GraphStats {
|
|
|
204
219
|
readonly failureCount: number;
|
|
205
220
|
readonly hungCount: number;
|
|
206
221
|
}
|
|
222
|
+
/** A stitched distributed trace spanning multiple execution graphs. */
|
|
223
|
+
interface DistributedTrace {
|
|
224
|
+
readonly traceId: string;
|
|
225
|
+
readonly graphs: ReadonlyMap<string, ExecutionGraph>;
|
|
226
|
+
readonly rootGraph: ExecutionGraph;
|
|
227
|
+
readonly childMap: ReadonlyMap<string, readonly string[]>;
|
|
228
|
+
readonly startTime: number;
|
|
229
|
+
readonly endTime: number | null;
|
|
230
|
+
readonly status: GraphStatus;
|
|
231
|
+
}
|
|
207
232
|
/** @internal Mutable version of ExecutionNode used during graph construction. */
|
|
208
233
|
interface MutableExecutionNode {
|
|
209
234
|
id: string;
|
|
@@ -251,6 +276,59 @@ interface MutableExecutionNode {
|
|
|
251
276
|
*/
|
|
252
277
|
declare function createGraphBuilder(config?: AgentFlowConfig): GraphBuilder;
|
|
253
278
|
|
|
279
|
+
/**
|
|
280
|
+
* CLI runner that wraps any command with automatic AgentFlow tracing.
|
|
281
|
+
*
|
|
282
|
+
* No code changes needed in the target application — the runner sets
|
|
283
|
+
* AGENTFLOW_TRACE_ID and AGENTFLOW_PARENT_SPAN_ID env vars so any child
|
|
284
|
+
* process using AgentFlow auto-joins the distributed trace.
|
|
285
|
+
*
|
|
286
|
+
* @example
|
|
287
|
+
* ```ts
|
|
288
|
+
* const result = await runTraced({
|
|
289
|
+
* command: ['python', '-m', 'alfred', 'process'],
|
|
290
|
+
* watchDirs: ['/home/trader/.alfred/data'],
|
|
291
|
+
* });
|
|
292
|
+
* ```
|
|
293
|
+
* @module
|
|
294
|
+
*/
|
|
295
|
+
interface RunConfig {
|
|
296
|
+
/** Command to execute (e.g. ['python', '-m', 'alfred', 'process']). */
|
|
297
|
+
command: string[];
|
|
298
|
+
/** Agent ID for the orchestrator trace (default: derived from command). */
|
|
299
|
+
agentId?: string;
|
|
300
|
+
/** Trigger label (default: "cli"). */
|
|
301
|
+
trigger?: string;
|
|
302
|
+
/** Directory to save trace files (default: ./traces). */
|
|
303
|
+
tracesDir?: string;
|
|
304
|
+
/** Directories to watch for state file changes during execution. */
|
|
305
|
+
watchDirs?: string[];
|
|
306
|
+
/** File patterns to watch (default: ["*.json"]). */
|
|
307
|
+
watchPatterns?: string[];
|
|
308
|
+
}
|
|
309
|
+
interface RunResult {
|
|
310
|
+
exitCode: number;
|
|
311
|
+
traceId: string;
|
|
312
|
+
spanId: string;
|
|
313
|
+
tracePaths: string[];
|
|
314
|
+
stateChanges: string[];
|
|
315
|
+
duration: number;
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* Run a command with automatic AgentFlow tracing.
|
|
319
|
+
*
|
|
320
|
+
* 1. Creates an orchestrator (parent) trace.
|
|
321
|
+
* 2. Snapshots watched directories.
|
|
322
|
+
* 3. Spawns the command with trace env vars.
|
|
323
|
+
* 4. After exit, detects state file changes and creates child traces.
|
|
324
|
+
* 5. Saves all trace JSON files.
|
|
325
|
+
*/
|
|
326
|
+
declare function runTraced(config: RunConfig): Promise<RunResult>;
|
|
327
|
+
|
|
328
|
+
declare function groupByTraceId(graphs: ExecutionGraph[]): Map<string, ExecutionGraph[]>;
|
|
329
|
+
declare function stitchTrace(graphs: ExecutionGraph[]): DistributedTrace;
|
|
330
|
+
declare function getTraceTree(trace: DistributedTrace): ExecutionGraph[];
|
|
331
|
+
|
|
254
332
|
/**
|
|
255
333
|
* Pure query functions for interrogating a built `ExecutionGraph`.
|
|
256
334
|
* Every function takes a frozen graph and returns derived data without mutation.
|
|
@@ -367,4 +445,4 @@ declare function getDepth(graph: ExecutionGraph): number;
|
|
|
367
445
|
*/
|
|
368
446
|
declare function getStats(graph: ExecutionGraph): GraphStats;
|
|
369
447
|
|
|
370
|
-
export { type Adapter, type AgentFlowConfig, type EdgeType, type ExecutionEdge, type ExecutionGraph, type ExecutionNode, type GraphBuilder, type GraphStats, type GraphStatus, type MutableExecutionNode, type NodeStatus, type NodeType, type StartNodeOptions, type TraceEvent, type TraceEventType, type Writer, createGraphBuilder, findWaitingOn, getChildren, getCriticalPath, getDepth, getDuration, getFailures, getHungNodes, getNode, getParent, getStats, getSubtree };
|
|
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 };
|