@tangle-network/agent-runtime 0.44.0 → 0.46.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 (88) hide show
  1. package/README.md +95 -203
  2. package/dist/agent.d.ts +3 -2
  3. package/dist/agent.js +5 -7
  4. package/dist/agent.js.map +1 -1
  5. package/dist/analyst-loop.d.ts +28 -2
  6. package/dist/analyst-loop.js +4 -1
  7. package/dist/audit.d.ts +93 -0
  8. package/dist/audit.js +312 -0
  9. package/dist/audit.js.map +1 -0
  10. package/dist/chunk-4B6U4CVQ.js +15 -0
  11. package/dist/chunk-4B6U4CVQ.js.map +1 -0
  12. package/dist/chunk-65FQLI4V.js +4089 -0
  13. package/dist/chunk-65FQLI4V.js.map +1 -0
  14. package/dist/{chunk-GFKVVRQ7.js → chunk-GN75RGM6.js} +13 -12
  15. package/dist/chunk-GN75RGM6.js.map +1 -0
  16. package/dist/chunk-GSUO5QS6.js +146 -0
  17. package/dist/chunk-GSUO5QS6.js.map +1 -0
  18. package/dist/chunk-HNUXAZIJ.js +580 -0
  19. package/dist/chunk-HNUXAZIJ.js.map +1 -0
  20. package/dist/{chunk-SKUZZCHE.js → chunk-I42NHLKX.js} +5 -5
  21. package/dist/chunk-I42NHLKX.js.map +1 -0
  22. package/dist/{chunk-HVYOHJHK.js → chunk-JNPK46YH.js} +2 -2
  23. package/dist/chunk-JNPK46YH.js.map +1 -0
  24. package/dist/{chunk-3HMHSN22.js → chunk-KADIJAD4.js} +38 -24
  25. package/dist/chunk-KADIJAD4.js.map +1 -0
  26. package/dist/{chunk-KDMRUD2P.js → chunk-KPN7OQ64.js} +296 -8
  27. package/dist/chunk-KPN7OQ64.js.map +1 -0
  28. package/dist/{chunk-NRZOXCJK.js → chunk-VR4JIC5H.js} +2 -2
  29. package/dist/chunk-WIR4HOOJ.js +27 -0
  30. package/dist/chunk-WIR4HOOJ.js.map +1 -0
  31. package/dist/coder-DCWFQpmJ.d.ts +114 -0
  32. package/dist/driver-C-mtBo7h.d.ts +221 -0
  33. package/dist/improvement.d.ts +0 -1
  34. package/dist/improvement.js +0 -5
  35. package/dist/improvement.js.map +1 -1
  36. package/dist/index.d.ts +122 -9
  37. package/dist/index.js +398 -10
  38. package/dist/index.js.map +1 -1
  39. package/dist/{kb-gate-D0ZIhFOU.d.ts → kb-gate-2Gwpz_27.d.ts} +86 -9
  40. package/dist/{loop-runner-bin-BLMa8He3.d.ts → loop-runner-bin-D-K6bRp3.d.ts} +17 -13
  41. package/dist/loop-runner-bin.d.ts +8 -6
  42. package/dist/loop-runner-bin.js +6 -8
  43. package/dist/loops.d.ts +7 -393
  44. package/dist/loops.js +96 -27
  45. package/dist/mcp/bin.js +7 -7
  46. package/dist/mcp/bin.js.map +1 -1
  47. package/dist/mcp/index.d.ts +286 -13
  48. package/dist/mcp/index.js +341 -9
  49. package/dist/mcp/index.js.map +1 -1
  50. package/dist/{otel-export-wFDmmurL.d.ts → otel-export-nurzFwuJ.d.ts} +1 -1
  51. package/dist/profiles.d.ts +385 -86
  52. package/dist/profiles.js +549 -4
  53. package/dist/profiles.js.map +1 -1
  54. package/dist/{run-loop-C4L1Sted.d.ts → run-loop-CU2Y00Si.d.ts} +36 -13
  55. package/dist/runtime-hooks-C7JwKb9E.d.ts +70 -0
  56. package/dist/runtime.d.ts +1964 -0
  57. package/dist/runtime.js +114 -0
  58. package/dist/runtime.js.map +1 -0
  59. package/dist/substrate-CUgk7F7s.d.ts +77 -0
  60. package/dist/topology.d.ts +73 -0
  61. package/dist/topology.js +111 -0
  62. package/dist/topology.js.map +1 -0
  63. package/dist/types-BfoeiQRZ.d.ts +438 -0
  64. package/dist/{types-DbJzz2uf.d.ts → types-DnYoHvvZ.d.ts} +110 -4
  65. package/dist/workflow.d.ts +4 -3
  66. package/dist/workflow.js +4 -5
  67. package/dist/workflow.js.map +1 -1
  68. package/package.json +37 -28
  69. package/skills/agent-runtime-adoption/SKILL.md +32 -29
  70. package/skills/generate-eval/SKILL.md +60 -0
  71. package/dist/chunk-3HMHSN22.js.map +0 -1
  72. package/dist/chunk-GFKVVRQ7.js.map +0 -1
  73. package/dist/chunk-HVYOHJHK.js.map +0 -1
  74. package/dist/chunk-KDMRUD2P.js.map +0 -1
  75. package/dist/chunk-PY6NMZYX.js +0 -52
  76. package/dist/chunk-PY6NMZYX.js.map +0 -1
  77. package/dist/chunk-S7JXV32P.js +0 -947
  78. package/dist/chunk-S7JXV32P.js.map +0 -1
  79. package/dist/chunk-SKUZZCHE.js.map +0 -1
  80. package/dist/chunk-SQSCRJ7U.js +0 -65
  81. package/dist/chunk-SQSCRJ7U.js.map +0 -1
  82. package/dist/chunk-VOX6Z3II.js +0 -90
  83. package/dist/chunk-VOX6Z3II.js.map +0 -1
  84. package/dist/chunk-XBUG326M.js +0 -261
  85. package/dist/chunk-XBUG326M.js.map +0 -1
  86. package/dist/dynamic-wUgp6UKs.d.ts +0 -108
  87. package/dist/optimize-prompt-D-urF2wW.d.ts +0 -129
  88. /package/dist/{chunk-NRZOXCJK.js.map → chunk-VR4JIC5H.js.map} +0 -0
@@ -0,0 +1,114 @@
1
+ import {
2
+ FileCorpus,
3
+ FileResultBlobStore,
4
+ FileSpawnJournal,
5
+ InMemoryCorpus,
6
+ InMemoryResultBlobStore,
7
+ InMemorySpawnJournal,
8
+ acquireSandbox,
9
+ assertTraceDerivedFindings,
10
+ buildSteerContext,
11
+ builtinShapes,
12
+ completionAuthorizes,
13
+ contentAddress,
14
+ createBudgetPool,
15
+ createDriver,
16
+ createExecutor,
17
+ createExecutorRegistry,
18
+ createRootHandle,
19
+ createSandboxForSpec,
20
+ createSandboxLineage,
21
+ createScope,
22
+ createScopeAnalyst,
23
+ createShapeRegistry,
24
+ createSupervisor,
25
+ defaultSelectWinner,
26
+ definePersona,
27
+ deterministicCompletion,
28
+ equalKOnCost,
29
+ fanout,
30
+ flatWidenGate,
31
+ inlineSandboxClient,
32
+ loopDispatch,
33
+ loopUntil,
34
+ materializeTreeView,
35
+ openSandboxRun,
36
+ panel,
37
+ pipeline,
38
+ probeSandboxCapabilities,
39
+ registerShape,
40
+ renderAnalyses,
41
+ renderCorpusToInstructions,
42
+ replaySpawnTree,
43
+ reportLoopUsage,
44
+ runLoop,
45
+ runPersonified,
46
+ sentinelCompletion,
47
+ settledToIteration,
48
+ spendFromUsageEvents,
49
+ stopSentinel,
50
+ trajectoryReport,
51
+ verify,
52
+ widen
53
+ } from "./chunk-65FQLI4V.js";
54
+ import {
55
+ extractLlmCallEvent,
56
+ mapSandboxEvent
57
+ } from "./chunk-GSUO5QS6.js";
58
+ import "./chunk-DGUM43GV.js";
59
+ export {
60
+ FileCorpus,
61
+ FileResultBlobStore,
62
+ FileSpawnJournal,
63
+ InMemoryCorpus,
64
+ InMemoryResultBlobStore,
65
+ InMemorySpawnJournal,
66
+ acquireSandbox,
67
+ assertTraceDerivedFindings,
68
+ buildSteerContext,
69
+ builtinShapes,
70
+ completionAuthorizes,
71
+ contentAddress,
72
+ createBudgetPool,
73
+ createDriver,
74
+ createExecutor,
75
+ createExecutorRegistry,
76
+ createRootHandle,
77
+ createSandboxForSpec,
78
+ createSandboxLineage,
79
+ createScope,
80
+ createScopeAnalyst,
81
+ createShapeRegistry,
82
+ createSupervisor,
83
+ defaultSelectWinner,
84
+ definePersona,
85
+ deterministicCompletion,
86
+ equalKOnCost,
87
+ extractLlmCallEvent,
88
+ fanout,
89
+ flatWidenGate,
90
+ inlineSandboxClient,
91
+ loopDispatch,
92
+ loopUntil,
93
+ mapSandboxEvent,
94
+ materializeTreeView,
95
+ openSandboxRun,
96
+ panel,
97
+ pipeline,
98
+ probeSandboxCapabilities,
99
+ registerShape,
100
+ renderAnalyses,
101
+ renderCorpusToInstructions,
102
+ replaySpawnTree,
103
+ reportLoopUsage,
104
+ runLoop,
105
+ runPersonified,
106
+ sentinelCompletion,
107
+ settledToIteration,
108
+ spendFromUsageEvents,
109
+ stopSentinel,
110
+ trajectoryReport,
111
+ verify,
112
+ widen
113
+ };
114
+ //# sourceMappingURL=runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,77 @@
1
+ /**
2
+ * @experimental
3
+ *
4
+ * UI audit finding shapes — the unit of evidence a contributor can act on.
5
+ *
6
+ * A finding describes a single, actionable UI problem: lens, severity,
7
+ * route, observation, impact, suggested fix, and screenshot evidence.
8
+ * Findings are produced by the auditor profile, persisted by the issue
9
+ * writer as self-contained GitHub-issue Markdown, and surfaced over MCP.
10
+ *
11
+ * The shapes are deliberately constraining — the validator + writer
12
+ * hard-fail on missing screenshot evidence, missing lens, missing title.
13
+ */
14
+ /**
15
+ * Canonical audit lenses. Each lens scopes a finding to a single class of
16
+ * problem so a single audit pass can iterate them without pile-on findings
17
+ * under a generic label.
18
+ */
19
+ type UiLens = 'consistency' | 'hierarchy' | 'layout' | 'ux-flow' | 'duplication' | 'accessibility' | 'responsive' | 'states' | 'content' | 'interaction' | 'performance-perceived' | 'other';
20
+ /** Frozen tuple of lenses for validation + iteration. */
21
+ declare const UI_LENSES: readonly UiLens[];
22
+ /**
23
+ * Severity scale.
24
+ * - `critical` — blocks a core task or is an accessibility blocker.
25
+ * - `high` — confusing, broken-looking, or noticeable friction.
26
+ * - `med` — visible polish issue, would be caught in code review.
27
+ * - `low` — nitpick worth fixing eventually.
28
+ */
29
+ type UiFindingSeverity = 'low' | 'med' | 'high' | 'critical';
30
+ /** Frozen severity tuple, ordered worst → least bad for sort/report. */
31
+ declare const UI_FINDING_SEVERITIES: readonly UiFindingSeverity[];
32
+ /** Pointer to a screenshot referenced by a finding (workspace-relative path). */
33
+ interface UiFindingScreenshot {
34
+ path: string;
35
+ viewport?: string;
36
+ label?: string;
37
+ }
38
+ /**
39
+ * A single UI audit finding — the unit of work a contributor can act on.
40
+ *
41
+ * Every field except the documented optionals is required. The auditor
42
+ * validator + writer hard-fail on missing screenshot evidence, missing
43
+ * lens, missing title, etc.
44
+ */
45
+ interface UiFinding {
46
+ /** Monotonic id assigned by the writer when persisting. Optional in-transit. */
47
+ id?: number;
48
+ title: string;
49
+ lens: UiLens;
50
+ severity: UiFindingSeverity;
51
+ /** Logical route the finding was observed on (e.g. `home`, `checkout-step-2`). */
52
+ route: string;
53
+ /** Fully qualified URL the finding was observed at. */
54
+ url?: string;
55
+ /** Viewport string the offending capture was taken at (e.g. `1280x800`). */
56
+ viewport?: string;
57
+ /** CSS selector pinning the offending element, when one can be identified. */
58
+ selector?: string;
59
+ /** 1–3 sentences describing what the screenshot shows that is wrong. */
60
+ observation: string;
61
+ /** Who is affected and how. */
62
+ impact: string;
63
+ /** A specific change a contributor could apply without asking back. */
64
+ suggestedFix: string;
65
+ /** Optional explicit reproduction steps. Writer synthesizes from route/url/selector when omitted. */
66
+ reproSteps?: string;
67
+ /** Free-form tags. */
68
+ tags?: readonly string[];
69
+ /** Screenshot references — must be non-empty for actionable findings. */
70
+ screenshots: readonly UiFindingScreenshot[];
71
+ /** Cross-references to similar findings already on file, by id. */
72
+ similarTo?: readonly number[];
73
+ /** ISO-8601 creation timestamp set by the writer when persisted. */
74
+ createdAt?: string;
75
+ }
76
+
77
+ export { type UiFinding as U, type UiLens as a, UI_FINDING_SEVERITIES as b, UI_LENSES as c, type UiFindingScreenshot as d, type UiFindingSeverity as e };
@@ -0,0 +1,73 @@
1
+ import { R as RuntimeHooks, a as RuntimeHookEvent } from './runtime-hooks-C7JwKb9E.js';
2
+
3
+ /**
4
+ * @experimental
5
+ *
6
+ * TOPOLOGY VIEW — the live recursive agent tree, folded from the ONE lifecycle stream
7
+ * (`src/runtime-hooks.ts`). It is a pure projection: feed it the `RuntimeHookEvent`s that
8
+ * `runLoop`, `toolLoop`, and the keystone `Scope` already emit, and it maintains the tree of
9
+ * agents + renders it. Attach `view.hooks` to a `Supervisor`/`runLoop` and the tree updates live.
10
+ *
11
+ * Two node sources, ONE stream:
12
+ * - an agent node is born from `agent.spawn` (id = `childId`, parent = the spawner) or the root
13
+ * `agent.run` (id = `runId`); `agent.child`/`agent.run:after` settle it (status + score/reason).
14
+ * - a STEP (`agent.{turn,tool_call,plan,decision}`) is not a node — it advances the step count of
15
+ * the agent it belongs to (matched by `runId`/`parentId`).
16
+ *
17
+ * No I/O, no timers, no backend coupling — the same projection drives a CLI render, a TUI, or a
18
+ * web tree. Rendering is deterministic given the event order (the stream is the source of truth).
19
+ */
20
+
21
+ type TopologyStatus = 'running' | 'done' | 'down';
22
+ /** One agent in the tree. A leaf never spawns; a driver's `childIds` is non-empty. */
23
+ interface TopologyNode {
24
+ readonly id: string;
25
+ /** Display label (spawn `label`, or the driver name on the root). */
26
+ label: string;
27
+ /** Leaf runtime (`router`/`sandbox`/`cli`) when known. */
28
+ runtime?: string;
29
+ /** Parent agent id; undefined ⇒ a root. */
30
+ parentId?: string;
31
+ /** Recursion depth (root = 0). */
32
+ depth: number;
33
+ status: TopologyStatus;
34
+ /** Count of in-agent steps (turns + tool calls + plan/decision rounds) folded so far. */
35
+ steps: number;
36
+ /** Deployable score in [0,1] once settled `done`. */
37
+ score?: number;
38
+ /** Failure reason once settled `down`. */
39
+ reason?: string;
40
+ /** Children in spawn order. */
41
+ readonly childIds: string[];
42
+ }
43
+ interface RenderOptions {
44
+ /** Cap the rendered depth (deeper nodes collapse to a `… N more` line). Default: no cap. */
45
+ readonly maxDepth?: number;
46
+ /** Drop the per-node detail suffix (steps/children/score) — labels only. Default: false. */
47
+ readonly compact?: boolean;
48
+ }
49
+ interface TopologyView {
50
+ /** The `RuntimeHooks` sink — attach to `SupervisorOpts.hooks` / `runLoop` options. */
51
+ readonly hooks: RuntimeHooks;
52
+ /** Fold one event into the tree (the same call `hooks.onEvent` makes — exposed for replay). */
53
+ ingest(event: RuntimeHookEvent): void;
54
+ /** Every node, insertion order. */
55
+ nodes(): TopologyNode[];
56
+ /** Nodes with no in-tree parent (the run roots). */
57
+ roots(): TopologyNode[];
58
+ /** One node by id. */
59
+ node(id: string): TopologyNode | undefined;
60
+ /** Render the tree as an aligned ASCII forest. */
61
+ render(opts?: RenderOptions): string;
62
+ }
63
+ /** Build a live topology view. Stateful — one per run (or per replay). */
64
+ declare function createTopologyView(): TopologyView;
65
+ /** Render a forest of `TopologyNode`s to an aligned ASCII tree. Pure — given the same roots +
66
+ * node lookup it returns the same string. Exposed so a caller can render a tree it folded
67
+ * itself (e.g. from a journal replay) without the live view. */
68
+ declare function renderTopologyTree(tree: {
69
+ roots: TopologyNode[];
70
+ node: (id: string) => TopologyNode | undefined;
71
+ }, opts?: RenderOptions): string;
72
+
73
+ export { type RenderOptions, type TopologyNode, type TopologyStatus, type TopologyView, createTopologyView, renderTopologyTree };
@@ -0,0 +1,111 @@
1
+ import "./chunk-DGUM43GV.js";
2
+
3
+ // src/topology/tree.ts
4
+ var stepTargets = /* @__PURE__ */ new Set(["agent.turn", "agent.tool_call", "agent.plan", "agent.decision"]);
5
+ function createTopologyView() {
6
+ const byId = /* @__PURE__ */ new Map();
7
+ const ensure = (id, seed = {}) => {
8
+ const existing = byId.get(id);
9
+ if (existing) return existing;
10
+ const node = {
11
+ id,
12
+ label: seed.label ?? id,
13
+ depth: seed.depth ?? 0,
14
+ status: "running",
15
+ steps: 0,
16
+ childIds: [],
17
+ ...seed
18
+ };
19
+ byId.set(id, node);
20
+ return node;
21
+ };
22
+ const str = (v) => typeof v === "string" ? v : void 0;
23
+ const num = (v) => typeof v === "number" ? v : void 0;
24
+ const ingest = (event) => {
25
+ const p = event.payload ?? {};
26
+ if (event.target === "agent.spawn" && event.phase === "after") {
27
+ const id = str(p.childId);
28
+ if (!id) return;
29
+ const parent = event.parentId ? ensure(event.parentId) : void 0;
30
+ const node = ensure(id, {
31
+ label: str(p.label) ?? id,
32
+ runtime: str(p.runtime),
33
+ parentId: event.parentId,
34
+ depth: num(p.depth) ?? (parent ? parent.depth + 1 : 0)
35
+ });
36
+ if (parent && !parent.childIds.includes(id)) parent.childIds.push(id);
37
+ node.status = "running";
38
+ return;
39
+ }
40
+ if (event.target === "agent.child" && event.phase === "after") {
41
+ const id = str(p.childId);
42
+ if (!id) return;
43
+ const node = ensure(id, { parentId: event.parentId });
44
+ node.status = str(p.status) === "down" ? "down" : "done";
45
+ node.score = num(p.score);
46
+ node.reason = str(p.reason);
47
+ return;
48
+ }
49
+ if (event.target === "agent.run") {
50
+ const node = ensure(event.runId, {
51
+ label: str(p.driver) ?? event.runId,
52
+ parentId: event.parentId
53
+ });
54
+ if (event.phase === "before") node.status = "running";
55
+ else if (event.phase === "error") node.status = "down";
56
+ else if (event.phase === "after" && node.status === "running") node.status = "done";
57
+ return;
58
+ }
59
+ if (stepTargets.has(event.target) && (event.phase === "after" || event.phase === "event")) {
60
+ const owner = event.parentId && byId.get(event.parentId) || byId.get(event.runId) || void 0;
61
+ if (owner) owner.steps += 1;
62
+ }
63
+ };
64
+ const nodes = () => [...byId.values()];
65
+ const roots = () => nodes().filter((n) => n.parentId === void 0 || !byId.has(n.parentId));
66
+ return {
67
+ hooks: { onEvent: (e) => ingest(e) },
68
+ ingest,
69
+ nodes,
70
+ roots,
71
+ node: (id) => byId.get(id),
72
+ render: (opts) => renderTopologyTree({ roots: roots(), node: (id) => byId.get(id) }, opts)
73
+ };
74
+ }
75
+ var glyph = { running: "\u25D0", done: "\u2713", down: "\u2717" };
76
+ function renderTopologyTree(tree, opts = {}) {
77
+ const lines = [];
78
+ const detail = (n) => {
79
+ if (opts.compact) return "";
80
+ const parts = [];
81
+ if (n.runtime) parts.push(n.runtime);
82
+ if (n.steps > 0) parts.push(`${n.steps} ${n.steps === 1 ? "step" : "steps"}`);
83
+ if (n.childIds.length > 0) parts.push(`${n.childIds.length} children`);
84
+ if (n.status === "done" && n.score !== void 0) parts.push(`score ${n.score.toFixed(2)}`);
85
+ if (n.status === "down" && n.reason) parts.push(`down: ${n.reason}`);
86
+ return parts.length ? ` (${parts.join(" \xB7 ")})` : "";
87
+ };
88
+ const walk = (n, prefix, isLast, depth) => {
89
+ const branch = depth === 0 ? "" : isLast ? "\u2514\u2500 " : "\u251C\u2500 ";
90
+ lines.push(`${prefix}${branch}${glyph[n.status]} ${n.label}${detail(n)}`);
91
+ if (opts.maxDepth !== void 0 && depth >= opts.maxDepth && n.childIds.length > 0) {
92
+ const childPrefix2 = prefix + (depth === 0 ? "" : isLast ? " " : "\u2502 ");
93
+ lines.push(`${childPrefix2}\u2514\u2500 \u2026 ${n.childIds.length} more`);
94
+ return;
95
+ }
96
+ const childPrefix = prefix + (depth === 0 ? "" : isLast ? " " : "\u2502 ");
97
+ const kids = n.childIds.map((id) => tree.node(id)).filter((c) => !!c);
98
+ kids.forEach((c, i) => {
99
+ walk(c, childPrefix, i === kids.length - 1, depth + 1);
100
+ });
101
+ };
102
+ tree.roots.forEach((r, i) => {
103
+ walk(r, "", i === tree.roots.length - 1, 0);
104
+ });
105
+ return lines.join("\n");
106
+ }
107
+ export {
108
+ createTopologyView,
109
+ renderTopologyTree
110
+ };
111
+ //# sourceMappingURL=topology.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/topology/tree.ts"],"sourcesContent":["/**\n * @experimental\n *\n * TOPOLOGY VIEW — the live recursive agent tree, folded from the ONE lifecycle stream\n * (`src/runtime-hooks.ts`). It is a pure projection: feed it the `RuntimeHookEvent`s that\n * `runLoop`, `toolLoop`, and the keystone `Scope` already emit, and it maintains the tree of\n * agents + renders it. Attach `view.hooks` to a `Supervisor`/`runLoop` and the tree updates live.\n *\n * Two node sources, ONE stream:\n * - an agent node is born from `agent.spawn` (id = `childId`, parent = the spawner) or the root\n * `agent.run` (id = `runId`); `agent.child`/`agent.run:after` settle it (status + score/reason).\n * - a STEP (`agent.{turn,tool_call,plan,decision}`) is not a node — it advances the step count of\n * the agent it belongs to (matched by `runId`/`parentId`).\n *\n * No I/O, no timers, no backend coupling — the same projection drives a CLI render, a TUI, or a\n * web tree. Rendering is deterministic given the event order (the stream is the source of truth).\n */\n\nimport type { RuntimeHookEvent, RuntimeHooks } from '../runtime-hooks'\n\nexport type TopologyStatus = 'running' | 'done' | 'down'\n\n/** One agent in the tree. A leaf never spawns; a driver's `childIds` is non-empty. */\nexport interface TopologyNode {\n readonly id: string\n /** Display label (spawn `label`, or the driver name on the root). */\n label: string\n /** Leaf runtime (`router`/`sandbox`/`cli`) when known. */\n runtime?: string\n /** Parent agent id; undefined ⇒ a root. */\n parentId?: string\n /** Recursion depth (root = 0). */\n depth: number\n status: TopologyStatus\n /** Count of in-agent steps (turns + tool calls + plan/decision rounds) folded so far. */\n steps: number\n /** Deployable score in [0,1] once settled `done`. */\n score?: number\n /** Failure reason once settled `down`. */\n reason?: string\n /** Children in spawn order. */\n readonly childIds: string[]\n}\n\nexport interface RenderOptions {\n /** Cap the rendered depth (deeper nodes collapse to a `… N more` line). Default: no cap. */\n readonly maxDepth?: number\n /** Drop the per-node detail suffix (steps/children/score) — labels only. Default: false. */\n readonly compact?: boolean\n}\n\nexport interface TopologyView {\n /** The `RuntimeHooks` sink — attach to `SupervisorOpts.hooks` / `runLoop` options. */\n readonly hooks: RuntimeHooks\n /** Fold one event into the tree (the same call `hooks.onEvent` makes — exposed for replay). */\n ingest(event: RuntimeHookEvent): void\n /** Every node, insertion order. */\n nodes(): TopologyNode[]\n /** Nodes with no in-tree parent (the run roots). */\n roots(): TopologyNode[]\n /** One node by id. */\n node(id: string): TopologyNode | undefined\n /** Render the tree as an aligned ASCII forest. */\n render(opts?: RenderOptions): string\n}\n\nconst stepTargets = new Set(['agent.turn', 'agent.tool_call', 'agent.plan', 'agent.decision'])\n\n/** Build a live topology view. Stateful — one per run (or per replay). */\nexport function createTopologyView(): TopologyView {\n // Insertion-ordered so render is stable and roots() reflects spawn order.\n const byId = new Map<string, TopologyNode>()\n\n const ensure = (id: string, seed: Partial<TopologyNode> = {}): TopologyNode => {\n const existing = byId.get(id)\n if (existing) return existing\n const node: TopologyNode = {\n id,\n label: seed.label ?? id,\n depth: seed.depth ?? 0,\n status: 'running',\n steps: 0,\n childIds: [],\n ...seed,\n }\n byId.set(id, node)\n return node\n }\n\n const str = (v: unknown): string | undefined => (typeof v === 'string' ? v : undefined)\n const num = (v: unknown): number | undefined => (typeof v === 'number' ? v : undefined)\n\n const ingest = (event: RuntimeHookEvent): void => {\n const p = (event.payload ?? {}) as Record<string, unknown>\n\n if (event.target === 'agent.spawn' && event.phase === 'after') {\n const id = str(p.childId)\n if (!id) return\n const parent = event.parentId ? ensure(event.parentId) : undefined\n const node = ensure(id, {\n label: str(p.label) ?? id,\n runtime: str(p.runtime),\n parentId: event.parentId,\n depth: num(p.depth) ?? (parent ? parent.depth + 1 : 0),\n })\n if (parent && !parent.childIds.includes(id)) parent.childIds.push(id)\n node.status = 'running'\n return\n }\n\n if (event.target === 'agent.child' && event.phase === 'after') {\n const id = str(p.childId)\n if (!id) return\n const node = ensure(id, { parentId: event.parentId })\n node.status = str(p.status) === 'down' ? 'down' : 'done'\n node.score = num(p.score)\n node.reason = str(p.reason)\n return\n }\n\n if (event.target === 'agent.run') {\n const node = ensure(event.runId, {\n label: str(p.driver) ?? event.runId,\n parentId: event.parentId,\n })\n if (event.phase === 'before') node.status = 'running'\n else if (event.phase === 'error') node.status = 'down'\n else if (event.phase === 'after' && node.status === 'running') node.status = 'done'\n return\n }\n\n // A step advances the agent it belongs to: tool-loop/run-loop key the agent by `runId`,\n // a within-agent sub-event names it via `parentId`. Only count `after`/`event` phases so a\n // before/after pair is one step, not two. An unknown owner is dropped (no phantom node).\n if (stepTargets.has(event.target) && (event.phase === 'after' || event.phase === 'event')) {\n const owner =\n (event.parentId && byId.get(event.parentId)) || byId.get(event.runId) || undefined\n if (owner) owner.steps += 1\n }\n }\n\n const nodes = (): TopologyNode[] => [...byId.values()]\n const roots = (): TopologyNode[] =>\n nodes().filter((n) => n.parentId === undefined || !byId.has(n.parentId))\n\n return {\n hooks: { onEvent: (e) => ingest(e) },\n ingest,\n nodes,\n roots,\n node: (id) => byId.get(id),\n render: (opts) => renderTopologyTree({ roots: roots(), node: (id) => byId.get(id) }, opts),\n }\n}\n\nconst glyph: Record<TopologyStatus, string> = { running: '◐', done: '✓', down: '✗' }\n\n/** Render a forest of `TopologyNode`s to an aligned ASCII tree. Pure — given the same roots +\n * node lookup it returns the same string. Exposed so a caller can render a tree it folded\n * itself (e.g. from a journal replay) without the live view. */\nexport function renderTopologyTree(\n tree: { roots: TopologyNode[]; node: (id: string) => TopologyNode | undefined },\n opts: RenderOptions = {},\n): string {\n const lines: string[] = []\n\n const detail = (n: TopologyNode): string => {\n if (opts.compact) return ''\n const parts: string[] = []\n if (n.runtime) parts.push(n.runtime)\n if (n.steps > 0) parts.push(`${n.steps} ${n.steps === 1 ? 'step' : 'steps'}`)\n if (n.childIds.length > 0) parts.push(`${n.childIds.length} children`)\n if (n.status === 'done' && n.score !== undefined) parts.push(`score ${n.score.toFixed(2)}`)\n if (n.status === 'down' && n.reason) parts.push(`down: ${n.reason}`)\n return parts.length ? ` (${parts.join(' · ')})` : ''\n }\n\n const walk = (n: TopologyNode, prefix: string, isLast: boolean, depth: number): void => {\n const branch = depth === 0 ? '' : isLast ? '└─ ' : '├─ '\n lines.push(`${prefix}${branch}${glyph[n.status]} ${n.label}${detail(n)}`)\n\n if (opts.maxDepth !== undefined && depth >= opts.maxDepth && n.childIds.length > 0) {\n const childPrefix = prefix + (depth === 0 ? '' : isLast ? ' ' : '│ ')\n lines.push(`${childPrefix}└─ … ${n.childIds.length} more`)\n return\n }\n const childPrefix = prefix + (depth === 0 ? '' : isLast ? ' ' : '│ ')\n const kids = n.childIds.map((id) => tree.node(id)).filter((c): c is TopologyNode => !!c)\n kids.forEach((c, i) => {\n walk(c, childPrefix, i === kids.length - 1, depth + 1)\n })\n }\n\n tree.roots.forEach((r, i) => {\n walk(r, '', i === tree.roots.length - 1, 0)\n })\n return lines.join('\\n')\n}\n"],"mappings":"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","names":["childPrefix"]}