network-ai 4.15.3 → 5.1.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 (282) hide show
  1. package/INTEGRATION_GUIDE.md +12 -5
  2. package/QUICKSTART.md +32 -5
  3. package/README.md +42 -17
  4. package/bin/dashboard.ts +146 -0
  5. package/bin/mcp-server.ts +3 -2
  6. package/dist/adapters/adapter-registry.d.ts +33 -1
  7. package/dist/adapters/adapter-registry.d.ts.map +1 -1
  8. package/dist/adapters/adapter-registry.js +49 -0
  9. package/dist/adapters/adapter-registry.js.map +1 -1
  10. package/dist/adapters/anthropic-computer-use-adapter.d.ts +132 -0
  11. package/dist/adapters/anthropic-computer-use-adapter.d.ts.map +1 -0
  12. package/dist/adapters/anthropic-computer-use-adapter.js +180 -0
  13. package/dist/adapters/anthropic-computer-use-adapter.js.map +1 -0
  14. package/dist/adapters/browser-agent-adapter.d.ts +121 -0
  15. package/dist/adapters/browser-agent-adapter.d.ts.map +1 -0
  16. package/dist/adapters/browser-agent-adapter.js +219 -0
  17. package/dist/adapters/browser-agent-adapter.js.map +1 -0
  18. package/dist/adapters/copilot-adapter.d.ts +59 -0
  19. package/dist/adapters/copilot-adapter.d.ts.map +1 -0
  20. package/dist/adapters/copilot-adapter.js +132 -0
  21. package/dist/adapters/copilot-adapter.js.map +1 -0
  22. package/dist/adapters/custom-adapter.d.ts +1 -1
  23. package/dist/adapters/custom-adapter.js +1 -1
  24. package/dist/adapters/index.d.ts +17 -1
  25. package/dist/adapters/index.d.ts.map +1 -1
  26. package/dist/adapters/index.js +25 -1
  27. package/dist/adapters/index.js.map +1 -1
  28. package/dist/adapters/langchain-adapter.js +1 -1
  29. package/dist/adapters/langchain-adapter.js.map +1 -1
  30. package/dist/adapters/langgraph-adapter.d.ts +70 -0
  31. package/dist/adapters/langgraph-adapter.d.ts.map +1 -0
  32. package/dist/adapters/langgraph-adapter.js +119 -0
  33. package/dist/adapters/langgraph-adapter.js.map +1 -0
  34. package/dist/adapters/mcp-adapter.d.ts +1 -1
  35. package/dist/adapters/mcp-adapter.js +3 -3
  36. package/dist/adapters/mcp-adapter.js.map +1 -1
  37. package/dist/adapters/openai-agents-adapter.d.ts +100 -0
  38. package/dist/adapters/openai-agents-adapter.d.ts.map +1 -0
  39. package/dist/adapters/openai-agents-adapter.js +118 -0
  40. package/dist/adapters/openai-agents-adapter.js.map +1 -0
  41. package/dist/adapters/openclaw-adapter.d.ts +1 -1
  42. package/dist/adapters/openclaw-adapter.js +3 -3
  43. package/dist/adapters/openclaw-adapter.js.map +1 -1
  44. package/dist/adapters/orchestrator-adapter.d.ts +118 -0
  45. package/dist/adapters/orchestrator-adapter.d.ts.map +1 -0
  46. package/dist/adapters/orchestrator-adapter.js +219 -0
  47. package/dist/adapters/orchestrator-adapter.js.map +1 -0
  48. package/dist/adapters/pydantic-ai-adapter.d.ts +104 -0
  49. package/dist/adapters/pydantic-ai-adapter.d.ts.map +1 -0
  50. package/dist/adapters/pydantic-ai-adapter.js +163 -0
  51. package/dist/adapters/pydantic-ai-adapter.js.map +1 -0
  52. package/dist/adapters/vertex-ai-adapter.d.ts +122 -0
  53. package/dist/adapters/vertex-ai-adapter.d.ts.map +1 -0
  54. package/dist/adapters/vertex-ai-adapter.js +166 -0
  55. package/dist/adapters/vertex-ai-adapter.js.map +1 -0
  56. package/dist/bin/dashboard.d.ts +11 -0
  57. package/dist/bin/dashboard.d.ts.map +1 -0
  58. package/dist/bin/dashboard.js +135 -0
  59. package/dist/bin/dashboard.js.map +1 -0
  60. package/dist/bin/mcp-server.js +3 -2
  61. package/dist/bin/mcp-server.js.map +1 -1
  62. package/dist/demo-control-plane.d.ts +12 -0
  63. package/dist/demo-control-plane.d.ts.map +1 -0
  64. package/dist/demo-control-plane.js +147 -0
  65. package/dist/demo-control-plane.js.map +1 -0
  66. package/dist/demo-worktree-dashboard.d.ts +2 -0
  67. package/dist/demo-worktree-dashboard.d.ts.map +1 -0
  68. package/dist/demo-worktree-dashboard.js +131 -0
  69. package/dist/demo-worktree-dashboard.js.map +1 -0
  70. package/dist/examples/01-hello-swarm.d.ts +13 -0
  71. package/dist/examples/01-hello-swarm.d.ts.map +1 -0
  72. package/dist/examples/01-hello-swarm.js +165 -0
  73. package/dist/examples/01-hello-swarm.js.map +1 -0
  74. package/dist/examples/02-fsm-pipeline.d.ts +20 -0
  75. package/dist/examples/02-fsm-pipeline.d.ts.map +1 -0
  76. package/dist/examples/02-fsm-pipeline.js +189 -0
  77. package/dist/examples/02-fsm-pipeline.js.map +1 -0
  78. package/dist/examples/03-parallel-agents.d.ts +21 -0
  79. package/dist/examples/03-parallel-agents.d.ts.map +1 -0
  80. package/dist/examples/03-parallel-agents.js +192 -0
  81. package/dist/examples/03-parallel-agents.js.map +1 -0
  82. package/dist/examples/05-code-review-swarm.d.ts +21 -0
  83. package/dist/examples/05-code-review-swarm.d.ts.map +1 -0
  84. package/dist/examples/05-code-review-swarm.js +1177 -0
  85. package/dist/examples/05-code-review-swarm.js.map +1 -0
  86. package/dist/examples/06-ai-pipeline-demo.d.ts +24 -0
  87. package/dist/examples/06-ai-pipeline-demo.d.ts.map +1 -0
  88. package/dist/examples/06-ai-pipeline-demo.js +263 -0
  89. package/dist/examples/06-ai-pipeline-demo.js.map +1 -0
  90. package/dist/examples/07-full-showcase.d.ts +27 -0
  91. package/dist/examples/07-full-showcase.d.ts.map +1 -0
  92. package/dist/examples/07-full-showcase.js +946 -0
  93. package/dist/examples/07-full-showcase.js.map +1 -0
  94. package/dist/examples/08-control-plane-stress-demo.d.ts +19 -0
  95. package/dist/examples/08-control-plane-stress-demo.d.ts.map +1 -0
  96. package/dist/examples/08-control-plane-stress-demo.js +186 -0
  97. package/dist/examples/08-control-plane-stress-demo.js.map +1 -0
  98. package/dist/examples/09-real-langchain.d.ts +19 -0
  99. package/dist/examples/09-real-langchain.d.ts.map +1 -0
  100. package/dist/examples/09-real-langchain.js +231 -0
  101. package/dist/examples/09-real-langchain.js.map +1 -0
  102. package/dist/examples/10-nemoclaw-sandbox-swarm.d.ts +16 -0
  103. package/dist/examples/10-nemoclaw-sandbox-swarm.d.ts.map +1 -0
  104. package/dist/examples/10-nemoclaw-sandbox-swarm.js +270 -0
  105. package/dist/examples/10-nemoclaw-sandbox-swarm.js.map +1 -0
  106. package/dist/examples/demo-runner.d.ts +2 -0
  107. package/dist/examples/demo-runner.d.ts.map +1 -0
  108. package/dist/examples/demo-runner.js +119 -0
  109. package/dist/examples/demo-runner.js.map +1 -0
  110. package/dist/index.d.ts +113 -559
  111. package/dist/index.d.ts.map +1 -1
  112. package/dist/index.js +310 -1074
  113. package/dist/index.js.map +1 -1
  114. package/dist/lib/adapter-test-harness.d.ts +88 -0
  115. package/dist/lib/adapter-test-harness.d.ts.map +1 -0
  116. package/dist/lib/adapter-test-harness.js +118 -0
  117. package/dist/lib/adapter-test-harness.js.map +1 -0
  118. package/dist/lib/agent-conversation.d.ts +115 -0
  119. package/dist/lib/agent-conversation.d.ts.map +1 -0
  120. package/dist/lib/agent-conversation.js +155 -0
  121. package/dist/lib/agent-conversation.js.map +1 -0
  122. package/dist/lib/agent-debate.d.ts +115 -0
  123. package/dist/lib/agent-debate.d.ts.map +1 -0
  124. package/dist/lib/agent-debate.js +146 -0
  125. package/dist/lib/agent-debate.js.map +1 -0
  126. package/dist/lib/agent-memory.d.ts +157 -0
  127. package/dist/lib/agent-memory.d.ts.map +1 -0
  128. package/dist/lib/agent-memory.js +336 -0
  129. package/dist/lib/agent-memory.js.map +1 -0
  130. package/dist/lib/agent-vcr.d.ts +133 -0
  131. package/dist/lib/agent-vcr.d.ts.map +1 -0
  132. package/dist/lib/agent-vcr.js +218 -0
  133. package/dist/lib/agent-vcr.js.map +1 -0
  134. package/dist/lib/anomaly-detector.d.ts +112 -0
  135. package/dist/lib/anomaly-detector.d.ts.map +1 -0
  136. package/dist/lib/anomaly-detector.js +178 -0
  137. package/dist/lib/anomaly-detector.js.map +1 -0
  138. package/dist/lib/approval-inbox.d.ts +147 -0
  139. package/dist/lib/approval-inbox.d.ts.map +1 -0
  140. package/dist/lib/approval-inbox.js +385 -0
  141. package/dist/lib/approval-inbox.js.map +1 -0
  142. package/dist/lib/auth-guardian.d.ts +170 -0
  143. package/dist/lib/auth-guardian.d.ts.map +1 -0
  144. package/dist/lib/auth-guardian.js +604 -0
  145. package/dist/lib/auth-guardian.js.map +1 -0
  146. package/dist/lib/auth-validator.d.ts +70 -0
  147. package/dist/lib/auth-validator.d.ts.map +1 -0
  148. package/dist/lib/auth-validator.js +32 -0
  149. package/dist/lib/auth-validator.js.map +1 -0
  150. package/dist/lib/blackboard-validator.d.ts +56 -0
  151. package/dist/lib/blackboard-validator.d.ts.map +1 -1
  152. package/dist/lib/blackboard-validator.js +181 -4
  153. package/dist/lib/blackboard-validator.js.map +1 -1
  154. package/dist/lib/comparison-runner.d.ts +99 -0
  155. package/dist/lib/comparison-runner.d.ts.map +1 -0
  156. package/dist/lib/comparison-runner.js +138 -0
  157. package/dist/lib/comparison-runner.js.map +1 -0
  158. package/dist/lib/config-watcher.d.ts +109 -0
  159. package/dist/lib/config-watcher.d.ts.map +1 -0
  160. package/dist/lib/config-watcher.js +215 -0
  161. package/dist/lib/config-watcher.js.map +1 -0
  162. package/dist/lib/control-plane.d.ts +128 -0
  163. package/dist/lib/control-plane.d.ts.map +1 -0
  164. package/dist/lib/control-plane.js +527 -0
  165. package/dist/lib/control-plane.js.map +1 -0
  166. package/dist/lib/cost-governor.d.ts +105 -0
  167. package/dist/lib/cost-governor.d.ts.map +1 -0
  168. package/dist/lib/cost-governor.js +128 -0
  169. package/dist/lib/cost-governor.js.map +1 -0
  170. package/dist/lib/cost-heatmap.d.ts +104 -0
  171. package/dist/lib/cost-heatmap.d.ts.map +1 -0
  172. package/dist/lib/cost-heatmap.js +161 -0
  173. package/dist/lib/cost-heatmap.js.map +1 -0
  174. package/dist/lib/coverage-reporter.d.ts +92 -0
  175. package/dist/lib/coverage-reporter.d.ts.map +1 -0
  176. package/dist/lib/coverage-reporter.js +177 -0
  177. package/dist/lib/coverage-reporter.js.map +1 -0
  178. package/dist/lib/dashboard-server.d.ts +71 -0
  179. package/dist/lib/dashboard-server.d.ts.map +1 -0
  180. package/dist/lib/dashboard-server.js +403 -0
  181. package/dist/lib/dashboard-server.js.map +1 -0
  182. package/dist/lib/dry-run.d.ts +73 -0
  183. package/dist/lib/dry-run.d.ts.map +1 -0
  184. package/dist/lib/dry-run.js +130 -0
  185. package/dist/lib/dry-run.js.map +1 -0
  186. package/dist/lib/errors.d.ts +15 -0
  187. package/dist/lib/errors.d.ts.map +1 -1
  188. package/dist/lib/errors.js +38 -0
  189. package/dist/lib/errors.js.map +1 -1
  190. package/dist/lib/event-bus.d.ts +167 -0
  191. package/dist/lib/event-bus.d.ts.map +1 -0
  192. package/dist/lib/event-bus.js +229 -0
  193. package/dist/lib/event-bus.js.map +1 -0
  194. package/dist/lib/explainability.d.ts +85 -0
  195. package/dist/lib/explainability.d.ts.map +1 -0
  196. package/dist/lib/explainability.js +102 -0
  197. package/dist/lib/explainability.js.map +1 -0
  198. package/dist/lib/goal-dsl.d.ts +157 -0
  199. package/dist/lib/goal-dsl.d.ts.map +1 -0
  200. package/dist/lib/goal-dsl.js +391 -0
  201. package/dist/lib/goal-dsl.js.map +1 -0
  202. package/dist/lib/job-queue.d.ts +183 -0
  203. package/dist/lib/job-queue.d.ts.map +1 -0
  204. package/dist/lib/job-queue.js +310 -0
  205. package/dist/lib/job-queue.js.map +1 -0
  206. package/dist/lib/learning-loop.d.ts +113 -0
  207. package/dist/lib/learning-loop.d.ts.map +1 -0
  208. package/dist/lib/learning-loop.js +181 -0
  209. package/dist/lib/learning-loop.js.map +1 -0
  210. package/dist/lib/lifecycle-hooks.d.ts +116 -0
  211. package/dist/lib/lifecycle-hooks.d.ts.map +1 -0
  212. package/dist/lib/lifecycle-hooks.js +148 -0
  213. package/dist/lib/lifecycle-hooks.js.map +1 -0
  214. package/dist/lib/locked-blackboard.d.ts.map +1 -1
  215. package/dist/lib/locked-blackboard.js +9 -5
  216. package/dist/lib/locked-blackboard.js.map +1 -1
  217. package/dist/lib/mcp-tool-consumer.d.ts +153 -0
  218. package/dist/lib/mcp-tool-consumer.d.ts.map +1 -0
  219. package/dist/lib/mcp-tool-consumer.js +320 -0
  220. package/dist/lib/mcp-tool-consumer.js.map +1 -0
  221. package/dist/lib/metrics.d.ts +119 -0
  222. package/dist/lib/metrics.d.ts.map +1 -0
  223. package/dist/lib/metrics.js +284 -0
  224. package/dist/lib/metrics.js.map +1 -0
  225. package/dist/lib/orchestrator-types.d.ts +309 -0
  226. package/dist/lib/orchestrator-types.d.ts.map +1 -0
  227. package/dist/lib/orchestrator-types.js +61 -0
  228. package/dist/lib/orchestrator-types.js.map +1 -0
  229. package/dist/lib/otel-bridge.d.ts +74 -0
  230. package/dist/lib/otel-bridge.d.ts.map +1 -0
  231. package/dist/lib/otel-bridge.js +167 -0
  232. package/dist/lib/otel-bridge.js.map +1 -0
  233. package/dist/lib/playground.d.ts +76 -0
  234. package/dist/lib/playground.d.ts.map +1 -0
  235. package/dist/lib/playground.js +224 -0
  236. package/dist/lib/playground.js.map +1 -0
  237. package/dist/lib/quadtree.d.ts +114 -0
  238. package/dist/lib/quadtree.d.ts.map +1 -0
  239. package/dist/lib/quadtree.js +259 -0
  240. package/dist/lib/quadtree.js.map +1 -0
  241. package/dist/lib/shared-blackboard.d.ts +101 -0
  242. package/dist/lib/shared-blackboard.d.ts.map +1 -0
  243. package/dist/lib/shared-blackboard.js +249 -0
  244. package/dist/lib/shared-blackboard.js.map +1 -0
  245. package/dist/lib/speculative-executor.d.ts +89 -0
  246. package/dist/lib/speculative-executor.d.ts.map +1 -0
  247. package/dist/lib/speculative-executor.js +107 -0
  248. package/dist/lib/speculative-executor.js.map +1 -0
  249. package/dist/lib/swarm-transport.d.ts +150 -0
  250. package/dist/lib/swarm-transport.d.ts.map +1 -0
  251. package/dist/lib/swarm-transport.js +307 -0
  252. package/dist/lib/swarm-transport.js.map +1 -0
  253. package/dist/lib/task-decomposer.d.ts +41 -0
  254. package/dist/lib/task-decomposer.d.ts.map +1 -0
  255. package/dist/lib/task-decomposer.js +272 -0
  256. package/dist/lib/task-decomposer.js.map +1 -0
  257. package/dist/lib/timeline-scrubber.d.ts +84 -0
  258. package/dist/lib/timeline-scrubber.d.ts.map +1 -0
  259. package/dist/lib/timeline-scrubber.js +173 -0
  260. package/dist/lib/timeline-scrubber.js.map +1 -0
  261. package/dist/lib/topology.d.ts +361 -0
  262. package/dist/lib/topology.d.ts.map +1 -0
  263. package/dist/lib/topology.js +591 -0
  264. package/dist/lib/topology.js.map +1 -0
  265. package/dist/lib/work-tree-dashboard.d.ts +130 -0
  266. package/dist/lib/work-tree-dashboard.d.ts.map +1 -0
  267. package/dist/lib/work-tree-dashboard.js +583 -0
  268. package/dist/lib/work-tree-dashboard.js.map +1 -0
  269. package/dist/lib/work-tree-ui.d.ts +107 -0
  270. package/dist/lib/work-tree-ui.d.ts.map +1 -0
  271. package/dist/lib/work-tree-ui.js +333 -0
  272. package/dist/lib/work-tree-ui.js.map +1 -0
  273. package/dist/lib/work-tree.d.ts +184 -0
  274. package/dist/lib/work-tree.d.ts.map +1 -0
  275. package/dist/lib/work-tree.js +480 -0
  276. package/dist/lib/work-tree.js.map +1 -0
  277. package/dist/security.d.ts +95 -0
  278. package/dist/security.d.ts.map +1 -1
  279. package/dist/security.js +267 -4
  280. package/dist/security.js.map +1 -1
  281. package/package.json +8 -6
  282. package/types/agent-adapter.d.ts +5 -0
@@ -0,0 +1,218 @@
1
+ "use strict";
2
+ /**
3
+ * VCR — Record and replay LLM/agent interactions for testing
4
+ *
5
+ * Provides a VCR (Video Cassette Recorder) pattern for capturing
6
+ * agent execution calls and replaying them deterministically in tests.
7
+ *
8
+ * Modes:
9
+ * - `record` — Intercepts calls, forwards to real handler, saves cassette
10
+ * - `replay` — Matches calls to recorded cassettes, returns saved results
11
+ * - `passthrough` — Disabled, all calls go to real handler
12
+ *
13
+ * Features:
14
+ * - Cassettes stored as JSON files
15
+ * - Request matching by agent ID + action + params hash
16
+ * - Configurable matching strictness
17
+ * - Call ordering enforcement (optional)
18
+ * - Missing cassette detection with helpful errors
19
+ *
20
+ * Usage:
21
+ * const vcr = new AgentVCR({ mode: 'record', cassettePath: './fixtures' });
22
+ * const result = await vcr.execute('agent-1', payload, realHandler);
23
+ * await vcr.save('my-test'); // Saves cassette to ./fixtures/my-test.json
24
+ *
25
+ * // Later in tests:
26
+ * const vcr2 = new AgentVCR({ mode: 'replay', cassettePath: './fixtures' });
27
+ * await vcr2.load('my-test');
28
+ * const result2 = await vcr2.execute('agent-1', payload); // Returns recorded result
29
+ *
30
+ * @module AgentVCR
31
+ * @version 1.0.0
32
+ */
33
+ Object.defineProperty(exports, "__esModule", { value: true });
34
+ exports.AgentVCR = void 0;
35
+ const promises_1 = require("fs/promises");
36
+ const path_1 = require("path");
37
+ const crypto_1 = require("crypto");
38
+ // ============================================================================
39
+ // VCR
40
+ // ============================================================================
41
+ /**
42
+ * Agent VCR — Record and replay agent execution calls.
43
+ *
44
+ * In `record` mode, calls are forwarded to the real handler and saved.
45
+ * In `replay` mode, calls are matched to saved cassettes.
46
+ */
47
+ class AgentVCR {
48
+ cassette = null;
49
+ replayIndex = 0;
50
+ config;
51
+ constructor(config) {
52
+ this.config = {
53
+ mode: config.mode,
54
+ cassettePath: config.cassettePath,
55
+ matchMode: config.matchMode ?? 'exact',
56
+ ordered: config.ordered ?? false,
57
+ throwOnMissing: config.throwOnMissing ?? true,
58
+ };
59
+ }
60
+ /** Get current mode */
61
+ get mode() {
62
+ return this.config.mode;
63
+ }
64
+ /** Set mode at runtime */
65
+ setMode(mode) {
66
+ this.config.mode = mode;
67
+ }
68
+ /**
69
+ * Execute an agent call through the VCR.
70
+ *
71
+ * @param agentId - The agent to call
72
+ * @param payload - The request payload
73
+ * @param handler - Real handler (required in record/passthrough mode)
74
+ */
75
+ async execute(agentId, payload, handler) {
76
+ switch (this.config.mode) {
77
+ case 'passthrough':
78
+ if (!handler)
79
+ throw new Error('VCR passthrough mode requires a handler');
80
+ return handler(agentId, payload);
81
+ case 'record':
82
+ return this.recordExecution(agentId, payload, handler);
83
+ case 'replay':
84
+ return this.replayExecution(agentId, payload);
85
+ default:
86
+ throw new Error(`Unknown VCR mode: ${this.config.mode}`);
87
+ }
88
+ }
89
+ /**
90
+ * Load a cassette from disk.
91
+ */
92
+ async load(name) {
93
+ const filePath = (0, path_1.join)(this.config.cassettePath, `${name}.json`);
94
+ const raw = await (0, promises_1.readFile)(filePath, 'utf-8');
95
+ this.cassette = JSON.parse(raw);
96
+ this.replayIndex = 0;
97
+ return this.cassette;
98
+ }
99
+ /**
100
+ * Save the current recording as a named cassette.
101
+ */
102
+ async save(name) {
103
+ if (!this.cassette) {
104
+ this.cassette = { name, createdAt: Date.now(), interactions: [] };
105
+ }
106
+ this.cassette.name = name;
107
+ try {
108
+ await (0, promises_1.stat)(this.config.cassettePath);
109
+ }
110
+ catch {
111
+ await (0, promises_1.mkdir)(this.config.cassettePath, { recursive: true });
112
+ }
113
+ const filePath = (0, path_1.join)(this.config.cassettePath, `${name}.json`);
114
+ await (0, promises_1.writeFile)(filePath, JSON.stringify(this.cassette, null, 2), 'utf-8');
115
+ }
116
+ /** Get the current cassette */
117
+ getCassette() {
118
+ return this.cassette;
119
+ }
120
+ /** Reset the VCR (clear cassette and replay index) */
121
+ reset() {
122
+ this.cassette = null;
123
+ this.replayIndex = 0;
124
+ }
125
+ /** Get number of recorded interactions */
126
+ get interactionCount() {
127
+ return this.cassette?.interactions.length ?? 0;
128
+ }
129
+ /**
130
+ * Try to match a request to a recorded interaction.
131
+ * Useful for debugging match failures.
132
+ */
133
+ findMatch(agentId, payload) {
134
+ const fingerprint = this.computeFingerprint(agentId, payload);
135
+ if (!this.cassette) {
136
+ return { matched: false, fingerprint, candidates: 0 };
137
+ }
138
+ const candidates = this.cassette.interactions.filter((i) => {
139
+ if (this.config.matchMode === 'fuzzy') {
140
+ return i.agentId === agentId;
141
+ }
142
+ return i.fingerprint === fingerprint;
143
+ });
144
+ return {
145
+ matched: candidates.length > 0,
146
+ fingerprint,
147
+ candidates: candidates.length,
148
+ bestMatch: candidates[0],
149
+ };
150
+ }
151
+ // --------------------------------------------------------------------------
152
+ // Internal
153
+ // --------------------------------------------------------------------------
154
+ async recordExecution(agentId, payload, handler) {
155
+ if (!handler)
156
+ throw new Error('VCR record mode requires a handler');
157
+ if (!this.cassette) {
158
+ this.cassette = { name: 'recording', createdAt: Date.now(), interactions: [] };
159
+ }
160
+ const start = Date.now();
161
+ const response = await handler(agentId, payload);
162
+ const durationMs = Date.now() - start;
163
+ const action = payload['action'] ?? '';
164
+ const paramsHash = this.hashParams(payload);
165
+ const fingerprint = this.computeFingerprint(agentId, payload);
166
+ this.cassette.interactions.push({
167
+ fingerprint,
168
+ agentId,
169
+ action,
170
+ paramsHash,
171
+ request: payload,
172
+ response,
173
+ recordedAt: Date.now(),
174
+ durationMs,
175
+ });
176
+ return response;
177
+ }
178
+ replayExecution(agentId, payload) {
179
+ if (!this.cassette || this.cassette.interactions.length === 0) {
180
+ throw new Error('No cassette loaded for replay. Call load() first.');
181
+ }
182
+ // Ordered mode: use sequential index
183
+ if (this.config.ordered) {
184
+ if (this.replayIndex >= this.cassette.interactions.length) {
185
+ throw new Error(`VCR replay exhausted: ${this.replayIndex} calls made but only ${this.cassette.interactions.length} recorded`);
186
+ }
187
+ const interaction = this.cassette.interactions[this.replayIndex++];
188
+ return interaction.response;
189
+ }
190
+ // Unordered: match by fingerprint
191
+ const fingerprint = this.computeFingerprint(agentId, payload);
192
+ const match = this.cassette.interactions.find((i) => {
193
+ if (this.config.matchMode === 'fuzzy') {
194
+ return i.agentId === agentId;
195
+ }
196
+ return i.fingerprint === fingerprint;
197
+ });
198
+ if (match) {
199
+ return match.response;
200
+ }
201
+ if (this.config.throwOnMissing) {
202
+ throw new Error(`VCR replay: no matching interaction for agent='${agentId}' fingerprint='${fingerprint}'. ` +
203
+ `Cassette has ${this.cassette.interactions.length} interactions.`);
204
+ }
205
+ return { error: 'VCR: no matching interaction', agentId };
206
+ }
207
+ computeFingerprint(agentId, payload) {
208
+ const action = payload['action'] ?? '';
209
+ const paramsHash = this.hashParams(payload);
210
+ return `${agentId}:${action}:${paramsHash}`;
211
+ }
212
+ hashParams(payload) {
213
+ const sorted = JSON.stringify(payload, Object.keys(payload).sort());
214
+ return (0, crypto_1.createHash)('sha256').update(sorted).digest('hex').slice(0, 12);
215
+ }
216
+ }
217
+ exports.AgentVCR = AgentVCR;
218
+ //# sourceMappingURL=agent-vcr.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-vcr.js","sourceRoot":"","sources":["../../lib/agent-vcr.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,112 @@
1
+ /**
2
+ * AnomalyDetector — Baseline agent behavior and flag statistical outliers.
3
+ *
4
+ * Maintains rolling statistics (mean, stddev) per agent for latency, token
5
+ * usage, and error rate. New observations are checked against the baseline
6
+ * and flagged as anomalies when they exceed a configurable z-score threshold.
7
+ *
8
+ * Uses Welford's online algorithm for numerically stable incremental
9
+ * mean/variance — no batch recomputation needed.
10
+ *
11
+ * @module AnomalyDetector
12
+ */
13
+ /** A detected anomaly */
14
+ export interface Anomaly {
15
+ /** ISO 8601 timestamp */
16
+ timestamp: string;
17
+ /** Agent that triggered the anomaly */
18
+ agentId: string;
19
+ /** Which metric is anomalous */
20
+ metric: AnomalyMetric;
21
+ /** Observed value */
22
+ observed: number;
23
+ /** Baseline mean for this agent + metric */
24
+ baselineMean: number;
25
+ /** Baseline standard deviation */
26
+ baselineStddev: number;
27
+ /** Z-score of the observation */
28
+ zScore: number;
29
+ /** Severity based on z-score magnitude */
30
+ severity: 'warning' | 'critical';
31
+ }
32
+ /** Metrics that are monitored for anomalies */
33
+ export type AnomalyMetric = 'latency' | 'tokens' | 'errorRate';
34
+ /** Summary of an agent's baseline */
35
+ export interface BaselineSummary {
36
+ agentId: string;
37
+ latency: {
38
+ mean: number;
39
+ stddev: number;
40
+ samples: number;
41
+ };
42
+ tokens: {
43
+ mean: number;
44
+ stddev: number;
45
+ samples: number;
46
+ };
47
+ errorRate: {
48
+ mean: number;
49
+ stddev: number;
50
+ samples: number;
51
+ };
52
+ }
53
+ /**
54
+ * Monitors agent behavior and flags statistical anomalies.
55
+ *
56
+ * @example
57
+ * ```ts
58
+ * const detector = new AnomalyDetector();
59
+ *
60
+ * // Feed observations as they occur:
61
+ * detector.observe('agent-1', { latencyMs: 200, tokens: 500, success: true });
62
+ * detector.observe('agent-1', { latencyMs: 15000, tokens: 500, success: true });
63
+ * // ^ second call may flag latency anomaly if baseline is ~200ms
64
+ *
65
+ * const anomalies = detector.getAnomalies();
66
+ * const baseline = detector.getBaseline('agent-1');
67
+ * ```
68
+ */
69
+ export declare class AnomalyDetector {
70
+ private baselines;
71
+ private anomalies;
72
+ private maxAnomalies;
73
+ private warningThreshold;
74
+ private criticalThreshold;
75
+ private minSamples;
76
+ private errorWindow;
77
+ constructor(options?: {
78
+ /** Z-score threshold for 'warning' level. Default 2.0 */
79
+ warningThreshold?: number;
80
+ /** Z-score threshold for 'critical' level. Default 3.0 */
81
+ criticalThreshold?: number;
82
+ /** Minimum samples before anomaly detection activates. Default 10 */
83
+ minSamples?: number;
84
+ /** Max anomalies to retain. Default 1000 */
85
+ maxAnomalies?: number;
86
+ });
87
+ /**
88
+ * Record an observation for an agent and check for anomalies.
89
+ * Returns any anomalies detected from this observation.
90
+ */
91
+ observe(agentId: string, obs: {
92
+ latencyMs: number;
93
+ tokens: number;
94
+ success: boolean;
95
+ }): Anomaly[];
96
+ /** Get all recorded anomalies, optionally filtered by agent */
97
+ getAnomalies(agentId?: string): Anomaly[];
98
+ /** Get recent anomalies (last N) */
99
+ getRecentAnomalies(count: number): Anomaly[];
100
+ /** Get the baseline summary for an agent */
101
+ getBaseline(agentId: string): BaselineSummary | null;
102
+ /** List all agents with baselines */
103
+ listAgents(): string[];
104
+ /** Total anomalies recorded */
105
+ get anomalyCount(): number;
106
+ /** Clear all baselines and anomalies */
107
+ clear(): void;
108
+ /** Clear data for a specific agent */
109
+ clearAgent(agentId: string): void;
110
+ private checkMetric;
111
+ }
112
+ //# sourceMappingURL=anomaly-detector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anomaly-detector.d.ts","sourceRoot":"","sources":["../../lib/anomaly-detector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAMH,yBAAyB;AACzB,MAAM,WAAW,OAAO;IACtB,yBAAyB;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,uCAAuC;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,gCAAgC;IAChC,MAAM,EAAE,aAAa,CAAC;IACtB,qBAAqB;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,4CAA4C;IAC5C,YAAY,EAAE,MAAM,CAAC;IACrB,kCAAkC;IAClC,cAAc,EAAE,MAAM,CAAC;IACvB,iCAAiC;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,0CAA0C;IAC1C,QAAQ,EAAE,SAAS,GAAG,UAAU,CAAC;CAClC;AAED,+CAA+C;AAC/C,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,QAAQ,GAAG,WAAW,CAAC;AAgB/D,qCAAqC;AACrC,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3D,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1D,SAAS,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;CAC9D;AAiCD;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,SAAS,CAAyC;IAC1D,OAAO,CAAC,SAAS,CAAiB;IAClC,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,gBAAgB,CAAS;IACjC,OAAO,CAAC,iBAAiB,CAAS;IAClC,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,WAAW,CAA6D;gBAEpE,OAAO,CAAC,EAAE;QACpB,yDAAyD;QACzD,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,0DAA0D;QAC1D,iBAAiB,CAAC,EAAE,MAAM,CAAC;QAC3B,qEAAqE;QACrE,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,4CAA4C;QAC5C,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB;IAOD;;;OAGG;IACH,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE;QAC5B,SAAS,EAAE,MAAM,CAAC;QAClB,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,OAAO,CAAC;KAClB,GAAG,OAAO,EAAE;IA+Cb,+DAA+D;IAC/D,YAAY,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,EAAE;IAKzC,oCAAoC;IACpC,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,EAAE;IAI5C,4CAA4C;IAC5C,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI;IAWpD,qCAAqC;IACrC,UAAU,IAAI,MAAM,EAAE;IAItB,+BAA+B;IAC/B,IAAI,YAAY,IAAI,MAAM,CAEzB;IAED,wCAAwC;IACxC,KAAK,IAAI,IAAI;IAMb,sCAAsC;IACtC,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAMjC,OAAO,CAAC,WAAW;CA0BpB"}
@@ -0,0 +1,178 @@
1
+ "use strict";
2
+ /**
3
+ * AnomalyDetector — Baseline agent behavior and flag statistical outliers.
4
+ *
5
+ * Maintains rolling statistics (mean, stddev) per agent for latency, token
6
+ * usage, and error rate. New observations are checked against the baseline
7
+ * and flagged as anomalies when they exceed a configurable z-score threshold.
8
+ *
9
+ * Uses Welford's online algorithm for numerically stable incremental
10
+ * mean/variance — no batch recomputation needed.
11
+ *
12
+ * @module AnomalyDetector
13
+ */
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.AnomalyDetector = void 0;
16
+ // ============================================================================
17
+ // WELFORD HELPERS
18
+ // ============================================================================
19
+ function welfordInit() {
20
+ return { count: 0, mean: 0, m2: 0 };
21
+ }
22
+ function welfordUpdate(state, value) {
23
+ state.count++;
24
+ const delta = value - state.mean;
25
+ state.mean += delta / state.count;
26
+ const delta2 = value - state.mean;
27
+ state.m2 += delta * delta2;
28
+ }
29
+ function welfordStddev(state) {
30
+ if (state.count < 2)
31
+ return 0;
32
+ return Math.sqrt(state.m2 / (state.count - 1));
33
+ }
34
+ function welfordZScore(state, value) {
35
+ const std = welfordStddev(state);
36
+ if (std === 0 || state.count < 5)
37
+ return 0; // Need minimum samples
38
+ return (value - state.mean) / std;
39
+ }
40
+ // ============================================================================
41
+ // DETECTOR
42
+ // ============================================================================
43
+ /**
44
+ * Monitors agent behavior and flags statistical anomalies.
45
+ *
46
+ * @example
47
+ * ```ts
48
+ * const detector = new AnomalyDetector();
49
+ *
50
+ * // Feed observations as they occur:
51
+ * detector.observe('agent-1', { latencyMs: 200, tokens: 500, success: true });
52
+ * detector.observe('agent-1', { latencyMs: 15000, tokens: 500, success: true });
53
+ * // ^ second call may flag latency anomaly if baseline is ~200ms
54
+ *
55
+ * const anomalies = detector.getAnomalies();
56
+ * const baseline = detector.getBaseline('agent-1');
57
+ * ```
58
+ */
59
+ class AnomalyDetector {
60
+ baselines = new Map();
61
+ anomalies = [];
62
+ maxAnomalies;
63
+ warningThreshold;
64
+ criticalThreshold;
65
+ minSamples;
66
+ errorWindow = new Map();
67
+ constructor(options) {
68
+ this.warningThreshold = options?.warningThreshold ?? 2.0;
69
+ this.criticalThreshold = options?.criticalThreshold ?? 3.0;
70
+ this.minSamples = options?.minSamples ?? 10;
71
+ this.maxAnomalies = options?.maxAnomalies ?? 1000;
72
+ }
73
+ /**
74
+ * Record an observation for an agent and check for anomalies.
75
+ * Returns any anomalies detected from this observation.
76
+ */
77
+ observe(agentId, obs) {
78
+ let baseline = this.baselines.get(agentId);
79
+ if (!baseline) {
80
+ baseline = {
81
+ latency: welfordInit(),
82
+ tokens: welfordInit(),
83
+ errorRate: welfordInit(),
84
+ };
85
+ this.baselines.set(agentId, baseline);
86
+ }
87
+ // Update error rate tracking
88
+ let errWin = this.errorWindow.get(agentId);
89
+ if (!errWin) {
90
+ errWin = { total: 0, errors: 0 };
91
+ this.errorWindow.set(agentId, errWin);
92
+ }
93
+ errWin.total++;
94
+ if (!obs.success)
95
+ errWin.errors++;
96
+ const currentErrorRate = errWin.total > 0 ? errWin.errors / errWin.total : 0;
97
+ const detected = [];
98
+ // Check before updating baseline (compare against historical)
99
+ detected.push(...this.checkMetric(agentId, 'latency', baseline.latency, obs.latencyMs));
100
+ detected.push(...this.checkMetric(agentId, 'tokens', baseline.tokens, obs.tokens));
101
+ detected.push(...this.checkMetric(agentId, 'errorRate', baseline.errorRate, currentErrorRate));
102
+ // Now update baselines
103
+ welfordUpdate(baseline.latency, obs.latencyMs);
104
+ welfordUpdate(baseline.tokens, obs.tokens);
105
+ welfordUpdate(baseline.errorRate, currentErrorRate);
106
+ // Store detected anomalies
107
+ for (const a of detected) {
108
+ this.anomalies.push(a);
109
+ }
110
+ if (this.anomalies.length > this.maxAnomalies) {
111
+ this.anomalies.splice(0, this.anomalies.length - this.maxAnomalies);
112
+ }
113
+ return detected;
114
+ }
115
+ /** Get all recorded anomalies, optionally filtered by agent */
116
+ getAnomalies(agentId) {
117
+ if (agentId)
118
+ return this.anomalies.filter(a => a.agentId === agentId);
119
+ return [...this.anomalies];
120
+ }
121
+ /** Get recent anomalies (last N) */
122
+ getRecentAnomalies(count) {
123
+ return this.anomalies.slice(-count);
124
+ }
125
+ /** Get the baseline summary for an agent */
126
+ getBaseline(agentId) {
127
+ const b = this.baselines.get(agentId);
128
+ if (!b)
129
+ return null;
130
+ return {
131
+ agentId,
132
+ latency: { mean: b.latency.mean, stddev: welfordStddev(b.latency), samples: b.latency.count },
133
+ tokens: { mean: b.tokens.mean, stddev: welfordStddev(b.tokens), samples: b.tokens.count },
134
+ errorRate: { mean: b.errorRate.mean, stddev: welfordStddev(b.errorRate), samples: b.errorRate.count },
135
+ };
136
+ }
137
+ /** List all agents with baselines */
138
+ listAgents() {
139
+ return [...this.baselines.keys()];
140
+ }
141
+ /** Total anomalies recorded */
142
+ get anomalyCount() {
143
+ return this.anomalies.length;
144
+ }
145
+ /** Clear all baselines and anomalies */
146
+ clear() {
147
+ this.baselines.clear();
148
+ this.anomalies.length = 0;
149
+ this.errorWindow.clear();
150
+ }
151
+ /** Clear data for a specific agent */
152
+ clearAgent(agentId) {
153
+ this.baselines.delete(agentId);
154
+ this.errorWindow.delete(agentId);
155
+ this.anomalies = this.anomalies.filter(a => a.agentId !== agentId);
156
+ }
157
+ checkMetric(agentId, metric, state, value) {
158
+ if (state.count < this.minSamples)
159
+ return [];
160
+ const z = welfordZScore(state, value);
161
+ const absZ = Math.abs(z);
162
+ if (absZ >= this.warningThreshold) {
163
+ return [{
164
+ timestamp: new Date().toISOString(),
165
+ agentId,
166
+ metric,
167
+ observed: value,
168
+ baselineMean: state.mean,
169
+ baselineStddev: welfordStddev(state),
170
+ zScore: z,
171
+ severity: absZ >= this.criticalThreshold ? 'critical' : 'warning',
172
+ }];
173
+ }
174
+ return [];
175
+ }
176
+ }
177
+ exports.AnomalyDetector = AnomalyDetector;
178
+ //# sourceMappingURL=anomaly-detector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anomaly-detector.js","sourceRoot":"","sources":["../../lib/anomaly-detector.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,147 @@
1
+ /**
2
+ * ApprovalInbox — Web-accessible human-in-the-loop approval system
3
+ *
4
+ * Provides an HTTP API and SSE streaming for managing approval requests
5
+ * from AI agents. Designed to work as an ApprovalCallback for ApprovalGate
6
+ * while also exposing a REST-like HTTP interface.
7
+ *
8
+ * Features:
9
+ * - Queues approval requests with unique IDs and optional timeouts
10
+ * - REST API: list, get, approve, deny, stats
11
+ * - SSE stream for real-time notifications
12
+ * - Auto-expiry for stale requests
13
+ * - Standalone HTTP server or mountable handler
14
+ *
15
+ * @module ApprovalInbox
16
+ * @version 1.0.0
17
+ */
18
+ import { EventEmitter } from 'events';
19
+ import { IncomingMessage, ServerResponse, Server } from 'http';
20
+ import type { ApprovalRequest, ApprovalDecision, ApprovalCallback } from './agent-runtime';
21
+ /** Status of an approval entry */
22
+ export type ApprovalStatus = 'pending' | 'approved' | 'denied' | 'expired';
23
+ /** A queued approval entry */
24
+ export interface ApprovalEntry {
25
+ /** Unique identifier for this approval */
26
+ id: string;
27
+ /** The original approval request */
28
+ request: ApprovalRequest;
29
+ /** Current status */
30
+ status: ApprovalStatus;
31
+ /** Decision if resolved */
32
+ decision?: ApprovalDecision;
33
+ /** When the request was created */
34
+ createdAt: number;
35
+ /** When the request was resolved */
36
+ resolvedAt?: number;
37
+ /** Timeout for this specific request (ms) */
38
+ timeoutMs: number;
39
+ }
40
+ /** Options for the ApprovalInbox */
41
+ export interface ApprovalInboxOptions {
42
+ /** Default timeout for approval requests in ms (default: 300000 = 5 min) */
43
+ defaultTimeoutMs?: number;
44
+ /** Maximum number of pending approvals (default: 100) */
45
+ maxPending?: number;
46
+ /** Maximum history entries to keep (default: 1000) */
47
+ maxHistory?: number;
48
+ /** URL path prefix for HTTP handler (default: '/approvals') */
49
+ pathPrefix?: string;
50
+ }
51
+ /** SSE event types */
52
+ export type InboxEventType = 'new' | 'approved' | 'denied' | 'expired';
53
+ /** SSE event payload */
54
+ export interface InboxEvent {
55
+ type: InboxEventType;
56
+ entry: ApprovalEntry;
57
+ }
58
+ /** Stats snapshot */
59
+ export interface InboxStats {
60
+ pending: number;
61
+ approved: number;
62
+ denied: number;
63
+ expired: number;
64
+ total: number;
65
+ }
66
+ /**
67
+ * Web-accessible approval inbox for human-in-the-loop agent workflows.
68
+ *
69
+ * Use `inbox.callback()` to get an ApprovalCallback for ApprovalGate,
70
+ * and `inbox.httpHandler()` to mount the HTTP API on a server.
71
+ *
72
+ * @example
73
+ * ```ts
74
+ * const inbox = new ApprovalInbox();
75
+ * const gate = new ApprovalGate(inbox.callback());
76
+ * const server = inbox.createServer(3002);
77
+ * ```
78
+ */
79
+ export declare class ApprovalInbox extends EventEmitter {
80
+ private readonly pending;
81
+ private readonly history;
82
+ private readonly sseClients;
83
+ private readonly defaultTimeoutMs;
84
+ private readonly maxPending;
85
+ private readonly maxHistory;
86
+ private readonly pathPrefix;
87
+ private approvedCount;
88
+ private deniedCount;
89
+ private expiredCount;
90
+ constructor(options?: ApprovalInboxOptions);
91
+ /**
92
+ * Returns an ApprovalCallback suitable for ApprovalGate.
93
+ * Each call enqueues a pending approval and waits for resolution.
94
+ */
95
+ callback(): ApprovalCallback;
96
+ /**
97
+ * Enqueue an approval request. Returns a promise that resolves when
98
+ * the request is approved, denied, or expires.
99
+ */
100
+ enqueue(request: ApprovalRequest, timeoutMs?: number): Promise<ApprovalDecision>;
101
+ /**
102
+ * Approve a pending request.
103
+ * @returns The resolved entry, or undefined if not found/already resolved.
104
+ */
105
+ approve(id: string, approvedBy: string, reason?: string): ApprovalEntry | undefined;
106
+ /**
107
+ * Deny a pending request.
108
+ * @returns The resolved entry, or undefined if not found/already resolved.
109
+ */
110
+ deny(id: string, deniedBy?: string, reason?: string): ApprovalEntry | undefined;
111
+ /** Get a single entry by ID (pending or historical) */
112
+ get(id: string): ApprovalEntry | undefined;
113
+ /** List entries by status (default: 'pending') */
114
+ list(status?: ApprovalStatus | 'all'): ApprovalEntry[];
115
+ /** Get aggregate stats */
116
+ stats(): InboxStats;
117
+ /** Number of pending approvals */
118
+ get pendingCount(): number;
119
+ /**
120
+ * Returns an HTTP request handler for the approval inbox API.
121
+ *
122
+ * Routes (relative to pathPrefix):
123
+ * GET / — List approvals (?status=pending|approved|denied|expired|all)
124
+ * GET /stats — Aggregate stats
125
+ * GET /sse — SSE event stream
126
+ * GET /:id — Get single entry
127
+ * POST /:id/approve — Approve (body: { approvedBy, reason? })
128
+ * POST /:id/deny — Deny (body: { deniedBy?, reason? })
129
+ */
130
+ httpHandler(): (req: IncomingMessage, res: ServerResponse) => void;
131
+ /**
132
+ * Create a standalone HTTP server for the inbox.
133
+ * @returns The HTTP server instance (already listening).
134
+ */
135
+ startServer(port: number, hostname?: string): Server;
136
+ /** Broadcast an event to all connected SSE clients */
137
+ private broadcastSSE;
138
+ /** Register an SSE client */
139
+ private addSSEClient;
140
+ private resolve;
141
+ private expire;
142
+ private addToHistory;
143
+ private routeRequest;
144
+ private sendJson;
145
+ private readBody;
146
+ }
147
+ //# sourceMappingURL=approval-inbox.d.ts.map