network-ai 5.10.1 → 5.11.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 (272) hide show
  1. package/INTEGRATION_GUIDE.md +2 -2
  2. package/README.md +5 -3
  3. package/SKILL.md +3 -3
  4. package/dist/esm/adapters/a2a-adapter.js +235 -0
  5. package/dist/esm/adapters/a2a-adapter.js.map +1 -0
  6. package/dist/esm/adapters/adapter-registry.js +613 -0
  7. package/dist/esm/adapters/adapter-registry.js.map +1 -0
  8. package/dist/esm/adapters/agno-adapter.js +140 -0
  9. package/dist/esm/adapters/agno-adapter.js.map +1 -0
  10. package/dist/esm/adapters/anthropic-computer-use-adapter.js +180 -0
  11. package/dist/esm/adapters/anthropic-computer-use-adapter.js.map +1 -0
  12. package/dist/esm/adapters/aps-adapter.js +289 -0
  13. package/dist/esm/adapters/aps-adapter.js.map +1 -0
  14. package/dist/esm/adapters/autogen-adapter.js +141 -0
  15. package/dist/esm/adapters/autogen-adapter.js.map +1 -0
  16. package/dist/esm/adapters/base-adapter.js +104 -0
  17. package/dist/esm/adapters/base-adapter.js.map +1 -0
  18. package/dist/esm/adapters/browser-agent-adapter.js +219 -0
  19. package/dist/esm/adapters/browser-agent-adapter.js.map +1 -0
  20. package/dist/esm/adapters/codex-adapter.js +318 -0
  21. package/dist/esm/adapters/codex-adapter.js.map +1 -0
  22. package/dist/esm/adapters/copilot-adapter.js +132 -0
  23. package/dist/esm/adapters/copilot-adapter.js.map +1 -0
  24. package/dist/esm/adapters/crewai-adapter.js +148 -0
  25. package/dist/esm/adapters/crewai-adapter.js.map +1 -0
  26. package/dist/esm/adapters/custom-adapter.js +142 -0
  27. package/dist/esm/adapters/custom-adapter.js.map +1 -0
  28. package/dist/esm/adapters/custom-streaming-adapter.js +181 -0
  29. package/dist/esm/adapters/custom-streaming-adapter.js.map +1 -0
  30. package/dist/esm/adapters/dspy-adapter.js +127 -0
  31. package/dist/esm/adapters/dspy-adapter.js.map +1 -0
  32. package/dist/esm/adapters/haystack-adapter.js +149 -0
  33. package/dist/esm/adapters/haystack-adapter.js.map +1 -0
  34. package/dist/esm/adapters/hermes-adapter.js +217 -0
  35. package/dist/esm/adapters/hermes-adapter.js.map +1 -0
  36. package/dist/esm/adapters/index.js +109 -0
  37. package/dist/esm/adapters/index.js.map +1 -0
  38. package/dist/esm/adapters/langchain-adapter.js +134 -0
  39. package/dist/esm/adapters/langchain-adapter.js.map +1 -0
  40. package/dist/esm/adapters/langchain-streaming-adapter.js +161 -0
  41. package/dist/esm/adapters/langchain-streaming-adapter.js.map +1 -0
  42. package/dist/esm/adapters/langgraph-adapter.js +119 -0
  43. package/dist/esm/adapters/langgraph-adapter.js.map +1 -0
  44. package/dist/esm/adapters/llamaindex-adapter.js +135 -0
  45. package/dist/esm/adapters/llamaindex-adapter.js.map +1 -0
  46. package/dist/esm/adapters/mcp-adapter.js +200 -0
  47. package/dist/esm/adapters/mcp-adapter.js.map +1 -0
  48. package/dist/esm/adapters/minimax-adapter.js +233 -0
  49. package/dist/esm/adapters/minimax-adapter.js.map +1 -0
  50. package/dist/esm/adapters/nemoclaw-adapter.js +465 -0
  51. package/dist/esm/adapters/nemoclaw-adapter.js.map +1 -0
  52. package/dist/esm/adapters/openai-agents-adapter.js +118 -0
  53. package/dist/esm/adapters/openai-agents-adapter.js.map +1 -0
  54. package/dist/esm/adapters/openai-assistants-adapter.js +130 -0
  55. package/dist/esm/adapters/openai-assistants-adapter.js.map +1 -0
  56. package/dist/esm/adapters/openclaw-adapter.js +107 -0
  57. package/dist/esm/adapters/openclaw-adapter.js.map +1 -0
  58. package/dist/esm/adapters/orchestrator-adapter.js +218 -0
  59. package/dist/esm/adapters/orchestrator-adapter.js.map +1 -0
  60. package/dist/esm/adapters/pydantic-ai-adapter.js +163 -0
  61. package/dist/esm/adapters/pydantic-ai-adapter.js.map +1 -0
  62. package/dist/esm/adapters/rlm-adapter.js +167 -0
  63. package/dist/esm/adapters/rlm-adapter.js.map +1 -0
  64. package/dist/esm/adapters/semantic-kernel-adapter.js +123 -0
  65. package/dist/esm/adapters/semantic-kernel-adapter.js.map +1 -0
  66. package/dist/esm/adapters/streaming-base-adapter.js +74 -0
  67. package/dist/esm/adapters/streaming-base-adapter.js.map +1 -0
  68. package/dist/esm/adapters/vertex-ai-adapter.js +166 -0
  69. package/dist/esm/adapters/vertex-ai-adapter.js.map +1 -0
  70. package/dist/esm/demo-control-plane.js +147 -0
  71. package/dist/esm/demo-control-plane.js.map +1 -0
  72. package/dist/esm/demo-worktree-dashboard.js +131 -0
  73. package/dist/esm/demo-worktree-dashboard.js.map +1 -0
  74. package/dist/esm/examples/01-hello-swarm.js +165 -0
  75. package/dist/esm/examples/01-hello-swarm.js.map +1 -0
  76. package/dist/esm/examples/02-fsm-pipeline.js +189 -0
  77. package/dist/esm/examples/02-fsm-pipeline.js.map +1 -0
  78. package/dist/esm/examples/03-parallel-agents.js +192 -0
  79. package/dist/esm/examples/03-parallel-agents.js.map +1 -0
  80. package/dist/esm/examples/05-code-review-swarm.js +1177 -0
  81. package/dist/esm/examples/05-code-review-swarm.js.map +1 -0
  82. package/dist/esm/examples/06-ai-pipeline-demo.js +263 -0
  83. package/dist/esm/examples/06-ai-pipeline-demo.js.map +1 -0
  84. package/dist/esm/examples/07-full-showcase.js +946 -0
  85. package/dist/esm/examples/07-full-showcase.js.map +1 -0
  86. package/dist/esm/examples/08-control-plane-stress-demo.js +186 -0
  87. package/dist/esm/examples/08-control-plane-stress-demo.js.map +1 -0
  88. package/dist/esm/examples/09-real-langchain.js +231 -0
  89. package/dist/esm/examples/09-real-langchain.js.map +1 -0
  90. package/dist/esm/examples/10-nemoclaw-sandbox-swarm.js +270 -0
  91. package/dist/esm/examples/10-nemoclaw-sandbox-swarm.js.map +1 -0
  92. package/dist/esm/examples/demo-runner.js +119 -0
  93. package/dist/esm/examples/demo-runner.js.map +1 -0
  94. package/dist/esm/index.js +1352 -0
  95. package/dist/esm/index.js.map +1 -0
  96. package/dist/esm/lib/adapter-hooks.js +216 -0
  97. package/dist/esm/lib/adapter-hooks.js.map +1 -0
  98. package/dist/esm/lib/adapter-test-harness.js +118 -0
  99. package/dist/esm/lib/adapter-test-harness.js.map +1 -0
  100. package/dist/esm/lib/agent-conversation.js +155 -0
  101. package/dist/esm/lib/agent-conversation.js.map +1 -0
  102. package/dist/esm/lib/agent-debate.js +146 -0
  103. package/dist/esm/lib/agent-debate.js.map +1 -0
  104. package/dist/esm/lib/agent-memory.js +336 -0
  105. package/dist/esm/lib/agent-memory.js.map +1 -0
  106. package/dist/esm/lib/agent-runtime.js +818 -0
  107. package/dist/esm/lib/agent-runtime.js.map +1 -0
  108. package/dist/esm/lib/agent-vcr.js +218 -0
  109. package/dist/esm/lib/agent-vcr.js.map +1 -0
  110. package/dist/esm/lib/anomaly-detector.js +178 -0
  111. package/dist/esm/lib/anomaly-detector.js.map +1 -0
  112. package/dist/esm/lib/approval-inbox.js +385 -0
  113. package/dist/esm/lib/approval-inbox.js.map +1 -0
  114. package/dist/esm/lib/auth-guardian.js +692 -0
  115. package/dist/esm/lib/auth-guardian.js.map +1 -0
  116. package/dist/esm/lib/auth-validator.js +32 -0
  117. package/dist/esm/lib/auth-validator.js.map +1 -0
  118. package/dist/esm/lib/blackboard-backend-crdt.js +251 -0
  119. package/dist/esm/lib/blackboard-backend-crdt.js.map +1 -0
  120. package/dist/esm/lib/blackboard-backend-redis.js +244 -0
  121. package/dist/esm/lib/blackboard-backend-redis.js.map +1 -0
  122. package/dist/esm/lib/blackboard-backend.js +141 -0
  123. package/dist/esm/lib/blackboard-backend.js.map +1 -0
  124. package/dist/esm/lib/blackboard-validator.js +985 -0
  125. package/dist/esm/lib/blackboard-validator.js.map +1 -0
  126. package/dist/esm/lib/circuit-breaker.js +164 -0
  127. package/dist/esm/lib/circuit-breaker.js.map +1 -0
  128. package/dist/esm/lib/claim-verifier.js +173 -0
  129. package/dist/esm/lib/claim-verifier.js.map +1 -0
  130. package/dist/esm/lib/comparison-runner.js +138 -0
  131. package/dist/esm/lib/comparison-runner.js.map +1 -0
  132. package/dist/esm/lib/compliance-monitor.js +261 -0
  133. package/dist/esm/lib/compliance-monitor.js.map +1 -0
  134. package/dist/esm/lib/confidence-filter.js +210 -0
  135. package/dist/esm/lib/confidence-filter.js.map +1 -0
  136. package/dist/esm/lib/config-watcher.js +215 -0
  137. package/dist/esm/lib/config-watcher.js.map +1 -0
  138. package/dist/esm/lib/consistency.js +274 -0
  139. package/dist/esm/lib/consistency.js.map +1 -0
  140. package/dist/esm/lib/console-ui.js +276 -0
  141. package/dist/esm/lib/console-ui.js.map +1 -0
  142. package/dist/esm/lib/context-throttler.js +171 -0
  143. package/dist/esm/lib/context-throttler.js.map +1 -0
  144. package/dist/esm/lib/control-plane.js +527 -0
  145. package/dist/esm/lib/control-plane.js.map +1 -0
  146. package/dist/esm/lib/cost-governor.js +128 -0
  147. package/dist/esm/lib/cost-governor.js.map +1 -0
  148. package/dist/esm/lib/cost-heatmap.js +161 -0
  149. package/dist/esm/lib/cost-heatmap.js.map +1 -0
  150. package/dist/esm/lib/coverage-gate.js +213 -0
  151. package/dist/esm/lib/coverage-gate.js.map +1 -0
  152. package/dist/esm/lib/coverage-reporter.js +177 -0
  153. package/dist/esm/lib/coverage-reporter.js.map +1 -0
  154. package/dist/esm/lib/crdt.js +141 -0
  155. package/dist/esm/lib/crdt.js.map +1 -0
  156. package/dist/esm/lib/dashboard-server.js +403 -0
  157. package/dist/esm/lib/dashboard-server.js.map +1 -0
  158. package/dist/esm/lib/dry-run.js +130 -0
  159. package/dist/esm/lib/dry-run.js.map +1 -0
  160. package/dist/esm/lib/env-manager.js +518 -0
  161. package/dist/esm/lib/env-manager.js.map +1 -0
  162. package/dist/esm/lib/errors.js +201 -0
  163. package/dist/esm/lib/errors.js.map +1 -0
  164. package/dist/esm/lib/event-bus.js +229 -0
  165. package/dist/esm/lib/event-bus.js.map +1 -0
  166. package/dist/esm/lib/explainability.js +102 -0
  167. package/dist/esm/lib/explainability.js.map +1 -0
  168. package/dist/esm/lib/fan-out.js +237 -0
  169. package/dist/esm/lib/fan-out.js.map +1 -0
  170. package/dist/esm/lib/federated-budget.js +322 -0
  171. package/dist/esm/lib/federated-budget.js.map +1 -0
  172. package/dist/esm/lib/fsm-journey.js +478 -0
  173. package/dist/esm/lib/fsm-journey.js.map +1 -0
  174. package/dist/esm/lib/goal-decomposer.js +698 -0
  175. package/dist/esm/lib/goal-decomposer.js.map +1 -0
  176. package/dist/esm/lib/goal-dsl.js +391 -0
  177. package/dist/esm/lib/goal-dsl.js.map +1 -0
  178. package/dist/esm/lib/job-queue.js +310 -0
  179. package/dist/esm/lib/job-queue.js.map +1 -0
  180. package/dist/esm/lib/landscape-agent.js +134 -0
  181. package/dist/esm/lib/landscape-agent.js.map +1 -0
  182. package/dist/esm/lib/learning-loop.js +181 -0
  183. package/dist/esm/lib/learning-loop.js.map +1 -0
  184. package/dist/esm/lib/lifecycle-hooks.js +148 -0
  185. package/dist/esm/lib/lifecycle-hooks.js.map +1 -0
  186. package/dist/esm/lib/locked-blackboard.js +1295 -0
  187. package/dist/esm/lib/locked-blackboard.js.map +1 -0
  188. package/dist/esm/lib/logger.js +150 -0
  189. package/dist/esm/lib/logger.js.map +1 -0
  190. package/dist/esm/lib/mcp-blackboard-tools.js +298 -0
  191. package/dist/esm/lib/mcp-blackboard-tools.js.map +1 -0
  192. package/dist/esm/lib/mcp-bridge.js +357 -0
  193. package/dist/esm/lib/mcp-bridge.js.map +1 -0
  194. package/dist/esm/lib/mcp-tool-consumer.js +287 -0
  195. package/dist/esm/lib/mcp-tool-consumer.js.map +1 -0
  196. package/dist/esm/lib/mcp-tools-control.js +392 -0
  197. package/dist/esm/lib/mcp-tools-control.js.map +1 -0
  198. package/dist/esm/lib/mcp-tools-extended.js +371 -0
  199. package/dist/esm/lib/mcp-tools-extended.js.map +1 -0
  200. package/dist/esm/lib/mcp-transport-http.js +528 -0
  201. package/dist/esm/lib/mcp-transport-http.js.map +1 -0
  202. package/dist/esm/lib/mcp-transport-sse.js +503 -0
  203. package/dist/esm/lib/mcp-transport-sse.js.map +1 -0
  204. package/dist/esm/lib/metrics.js +284 -0
  205. package/dist/esm/lib/metrics.js.map +1 -0
  206. package/dist/esm/lib/orchestrator-types.js +66 -0
  207. package/dist/esm/lib/orchestrator-types.js.map +1 -0
  208. package/dist/esm/lib/otel-bridge.js +167 -0
  209. package/dist/esm/lib/otel-bridge.js.map +1 -0
  210. package/dist/esm/lib/partition-planner.js +246 -0
  211. package/dist/esm/lib/partition-planner.js.map +1 -0
  212. package/dist/esm/lib/phase-pipeline.js +367 -0
  213. package/dist/esm/lib/phase-pipeline.js.map +1 -0
  214. package/dist/esm/lib/playground.js +224 -0
  215. package/dist/esm/lib/playground.js.map +1 -0
  216. package/dist/esm/lib/qa-orchestrator.js +296 -0
  217. package/dist/esm/lib/qa-orchestrator.js.map +1 -0
  218. package/dist/esm/lib/quadtree.js +259 -0
  219. package/dist/esm/lib/quadtree.js.map +1 -0
  220. package/dist/esm/lib/route-classifier.js +217 -0
  221. package/dist/esm/lib/route-classifier.js.map +1 -0
  222. package/dist/esm/lib/semantic-search.js +235 -0
  223. package/dist/esm/lib/semantic-search.js.map +1 -0
  224. package/dist/esm/lib/shared-blackboard.js +249 -0
  225. package/dist/esm/lib/shared-blackboard.js.map +1 -0
  226. package/dist/esm/lib/skill-composer.js +190 -0
  227. package/dist/esm/lib/skill-composer.js.map +1 -0
  228. package/dist/esm/lib/speculative-executor.js +107 -0
  229. package/dist/esm/lib/speculative-executor.js.map +1 -0
  230. package/dist/esm/lib/strategy-agent.js +626 -0
  231. package/dist/esm/lib/strategy-agent.js.map +1 -0
  232. package/dist/esm/lib/swarm-transport.js +307 -0
  233. package/dist/esm/lib/swarm-transport.js.map +1 -0
  234. package/dist/esm/lib/swarm-utils.js +510 -0
  235. package/dist/esm/lib/swarm-utils.js.map +1 -0
  236. package/dist/esm/lib/task-decomposer.js +272 -0
  237. package/dist/esm/lib/task-decomposer.js.map +1 -0
  238. package/dist/esm/lib/telemetry-provider.js +207 -0
  239. package/dist/esm/lib/telemetry-provider.js.map +1 -0
  240. package/dist/esm/lib/timeline-scrubber.js +173 -0
  241. package/dist/esm/lib/timeline-scrubber.js.map +1 -0
  242. package/dist/esm/lib/topology.js +591 -0
  243. package/dist/esm/lib/topology.js.map +1 -0
  244. package/dist/esm/lib/transport-agent.js +366 -0
  245. package/dist/esm/lib/transport-agent.js.map +1 -0
  246. package/dist/esm/lib/work-tree-dashboard.js +583 -0
  247. package/dist/esm/lib/work-tree-dashboard.js.map +1 -0
  248. package/dist/esm/lib/work-tree-ui.js +333 -0
  249. package/dist/esm/lib/work-tree-ui.js.map +1 -0
  250. package/dist/esm/lib/work-tree.js +480 -0
  251. package/dist/esm/lib/work-tree.js.map +1 -0
  252. package/dist/esm/run.js +144 -0
  253. package/dist/esm/run.js.map +1 -0
  254. package/dist/esm/security.js +1122 -0
  255. package/dist/esm/security.js.map +1 -0
  256. package/dist/index.d.ts +2 -0
  257. package/dist/index.d.ts.map +1 -1
  258. package/dist/index.js +6 -1
  259. package/dist/index.js.map +1 -1
  260. package/dist/lib/mcp-transport-http.d.ts +203 -0
  261. package/dist/lib/mcp-transport-http.d.ts.map +1 -0
  262. package/dist/lib/mcp-transport-http.js +528 -0
  263. package/dist/lib/mcp-transport-http.js.map +1 -0
  264. package/dist/lib/phase-pipeline.d.ts +31 -0
  265. package/dist/lib/phase-pipeline.d.ts.map +1 -1
  266. package/dist/lib/phase-pipeline.js +93 -1
  267. package/dist/lib/phase-pipeline.js.map +1 -1
  268. package/dist/lib/semantic-search.d.ts +42 -6
  269. package/dist/lib/semantic-search.d.ts.map +1 -1
  270. package/dist/lib/semantic-search.js +87 -6
  271. package/dist/lib/semantic-search.js.map +1 -1
  272. package/package.json +24 -4
@@ -0,0 +1,272 @@
1
+ "use strict";
2
+ /**
3
+ * Task decomposition engine for parallel multi-agent execution.
4
+ *
5
+ * Breaks complex tasks into parallel sub-agent calls, routes them through
6
+ * the adapter registry, caches results on the blackboard, and synthesizes
7
+ * outputs using configurable strategies (merge, vote, chain, first-success).
8
+ *
9
+ * @module TaskDecomposer
10
+ */
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.TaskDecomposer = void 0;
13
+ const crypto_1 = require("crypto");
14
+ const adapter_registry_1 = require("../adapters/adapter-registry");
15
+ const security_1 = require("../security");
16
+ const errors_1 = require("./errors");
17
+ const shared_blackboard_1 = require("./shared-blackboard");
18
+ const auth_guardian_1 = require("./auth-guardian");
19
+ const orchestrator_types_1 = require("./orchestrator-types");
20
+ class TaskDecomposer {
21
+ blackboard;
22
+ authGuardian;
23
+ adapterRegistry;
24
+ /** Maximum number of tasks to run concurrently (0 = unlimited). */
25
+ maxConcurrency;
26
+ constructor(blackboard, authGuardian, adapterRegistry, options) {
27
+ if (!blackboard || !(blackboard instanceof shared_blackboard_1.SharedBlackboard)) {
28
+ throw new errors_1.ValidationError('blackboard must be an instance of SharedBlackboard');
29
+ }
30
+ if (!authGuardian || !(authGuardian instanceof auth_guardian_1.AuthGuardian)) {
31
+ throw new errors_1.ValidationError('authGuardian must be an instance of AuthGuardian');
32
+ }
33
+ if (!adapterRegistry || !(adapterRegistry instanceof adapter_registry_1.AdapterRegistry)) {
34
+ throw new errors_1.ValidationError('adapterRegistry must be an instance of AdapterRegistry');
35
+ }
36
+ this.blackboard = blackboard;
37
+ this.authGuardian = authGuardian;
38
+ this.adapterRegistry = adapterRegistry;
39
+ this.maxConcurrency = options?.maxConcurrency ?? 5;
40
+ }
41
+ /**
42
+ * Decomposes a complex task into parallel sub-agent calls
43
+ * This is the "Wall Breaker" - transforms impossible monolithic tasks
44
+ * into manageable parallel executions
45
+ */
46
+ async executeParallel(tasks, synthesisStrategy = 'merge', context) {
47
+ if (!tasks || !Array.isArray(tasks)) {
48
+ throw new errors_1.ValidationError('tasks must be an array');
49
+ }
50
+ if (tasks.length === 0) {
51
+ throw new errors_1.ValidationError('tasks array must not be empty');
52
+ }
53
+ if (!context || typeof context !== 'object' || !context.agentId) {
54
+ throw new errors_1.ValidationError('context is required and must include agentId');
55
+ }
56
+ // No hard parallel limit — caller controls concurrency via task count
57
+ const startTime = Date.now();
58
+ const individualResults = [];
59
+ // Check blackboard for cached results first
60
+ const cachedTasks = [];
61
+ const uncachedTasks = [];
62
+ for (const task of tasks) {
63
+ const cacheKey = `task:${task.agentType}:${this.hashPayload(task.taskPayload)}`;
64
+ const cached = this.blackboard.read(cacheKey);
65
+ if (cached) {
66
+ individualResults.push({
67
+ agentType: task.agentType,
68
+ success: true,
69
+ result: cached.value,
70
+ executionTime: 0, // From cache
71
+ });
72
+ cachedTasks.push(task);
73
+ }
74
+ else {
75
+ uncachedTasks.push(task);
76
+ }
77
+ }
78
+ // Execute uncached tasks with concurrency cap
79
+ if (uncachedTasks.length > 0) {
80
+ const results = await this.runWithConcurrencyLimit(uncachedTasks, task => this.executeSingleTask(task, context), this.maxConcurrency);
81
+ for (let i = 0; i < results.length; i++) {
82
+ const task = uncachedTasks[i];
83
+ const result = results[i];
84
+ individualResults.push(result);
85
+ // Cache successful results
86
+ if (result.success) {
87
+ const cacheKey = `task:${task.agentType}:${this.hashPayload(task.taskPayload)}`;
88
+ this.blackboard.write(cacheKey, result.result, context.agentId, 3600, 'system-orchestrator-token'); // 1 hour TTL
89
+ }
90
+ }
91
+ }
92
+ // Synthesize results based on strategy
93
+ const synthesizedResult = this.synthesize(individualResults, synthesisStrategy);
94
+ const totalTime = Date.now() - startTime;
95
+ const successCount = individualResults.filter(r => r.success).length;
96
+ return {
97
+ synthesizedResult,
98
+ individualResults,
99
+ executionMetrics: {
100
+ totalTime,
101
+ successRate: successCount / individualResults.length,
102
+ synthesisStrategy,
103
+ },
104
+ };
105
+ }
106
+ async executeSingleTask(task, context) {
107
+ const taskStart = Date.now();
108
+ try {
109
+ // Build the handoff message
110
+ const handoff = {
111
+ handoffId: (0, crypto_1.randomUUID)(),
112
+ sourceAgent: context.agentId,
113
+ targetAgent: task.agentType,
114
+ taskType: 'delegate',
115
+ payload: task.taskPayload,
116
+ metadata: {
117
+ priority: 1,
118
+ deadline: Date.now() + orchestrator_types_1.CONFIG.defaultTimeout,
119
+ parentTaskId: context.taskId ?? null,
120
+ },
121
+ };
122
+ // Sanitize the instruction before sending to adapter
123
+ let sanitizedInstruction = task.taskPayload.instruction;
124
+ try {
125
+ sanitizedInstruction = security_1.InputSanitizer.sanitizeString(task.taskPayload.instruction, 10000);
126
+ }
127
+ catch { /* use original if sanitization fails */ }
128
+ // Use namespace-scoped snapshot -- target agent only sees keys it's allowed to see
129
+ const scopedSnapshot = this.blackboard.getScopedSnapshot(task.agentType);
130
+ // Route through the adapter registry (framework-agnostic)
131
+ const agentPayload = {
132
+ action: 'execute',
133
+ params: {},
134
+ handoff: {
135
+ handoffId: handoff.handoffId,
136
+ sourceAgent: handoff.sourceAgent,
137
+ targetAgent: handoff.targetAgent,
138
+ taskType: handoff.taskType,
139
+ instruction: sanitizedInstruction,
140
+ context: handoff.payload.context,
141
+ constraints: handoff.payload.constraints,
142
+ expectedOutput: handoff.payload.expectedOutput,
143
+ metadata: handoff.metadata,
144
+ },
145
+ blackboardSnapshot: scopedSnapshot,
146
+ };
147
+ const agentContext = {
148
+ agentId: context.agentId,
149
+ taskId: context.taskId,
150
+ sessionId: context.sessionId,
151
+ };
152
+ const result = await this.adapterRegistry.executeAgent(task.agentType, agentPayload, agentContext);
153
+ // Sanitize adapter output before returning/caching
154
+ let sanitizedData = result.data;
155
+ try {
156
+ sanitizedData = security_1.InputSanitizer.sanitizeObject(result.data);
157
+ }
158
+ catch { /* use raw if sanitization fails */ }
159
+ return {
160
+ agentType: task.agentType,
161
+ success: true,
162
+ result: sanitizedData,
163
+ executionTime: Date.now() - taskStart,
164
+ };
165
+ }
166
+ catch (error) {
167
+ return {
168
+ agentType: task.agentType,
169
+ success: false,
170
+ result: {
171
+ error: error instanceof Error ? error.message : 'Unknown error',
172
+ recoverable: true,
173
+ },
174
+ executionTime: Date.now() - taskStart,
175
+ };
176
+ }
177
+ }
178
+ synthesize(results, strategy) {
179
+ const successfulResults = results.filter(r => r.success);
180
+ if (successfulResults.length === 0) {
181
+ return {
182
+ error: 'All parallel tasks failed',
183
+ individualErrors: results.map(r => ({
184
+ agent: r.agentType,
185
+ error: r.result,
186
+ })),
187
+ };
188
+ }
189
+ switch (strategy) {
190
+ case 'merge':
191
+ // Combine all results into a unified object
192
+ return {
193
+ merged: true,
194
+ contributions: successfulResults.map(r => ({
195
+ source: r.agentType,
196
+ data: r.result,
197
+ })),
198
+ summary: this.generateMergeSummary(successfulResults),
199
+ };
200
+ case 'vote':
201
+ // Return the result with highest "confidence" (simplified: most data)
202
+ const scored = successfulResults.map(r => ({
203
+ result: r,
204
+ score: JSON.stringify(r.result).length,
205
+ }));
206
+ scored.sort((a, b) => b.score - a.score);
207
+ return {
208
+ voted: true,
209
+ winner: scored[0].result.agentType,
210
+ result: scored[0].result.result,
211
+ };
212
+ case 'chain':
213
+ // Results should already be ordered; return the final one
214
+ return {
215
+ chained: true,
216
+ finalResult: successfulResults[successfulResults.length - 1].result,
217
+ chainLength: successfulResults.length,
218
+ };
219
+ case 'first-success':
220
+ // Return the first successful result
221
+ return {
222
+ firstSuccess: true,
223
+ source: successfulResults[0].agentType,
224
+ result: successfulResults[0].result,
225
+ };
226
+ default:
227
+ return successfulResults.map(r => r.result);
228
+ }
229
+ }
230
+ generateMergeSummary(results) {
231
+ const agents = results.map(r => r.agentType).join(', ');
232
+ return `Synthesized from ${results.length} agents: ${agents}`;
233
+ }
234
+ hashPayload(payload) {
235
+ // Simple hash for cache key generation
236
+ const str = JSON.stringify(payload);
237
+ let hash = 0;
238
+ for (let i = 0; i < str.length; i++) {
239
+ const char = str.charCodeAt(i);
240
+ hash = ((hash << 5) - hash) + char;
241
+ hash = hash & hash;
242
+ }
243
+ return Math.abs(hash).toString(16);
244
+ }
245
+ /**
246
+ * Execute async functions with a bounded concurrency pool.
247
+ * @param items Items to process
248
+ * @param fn Async function to apply to each item
249
+ * @param limit Max concurrent executions (0 = unlimited)
250
+ */
251
+ async runWithConcurrencyLimit(items, fn, limit) {
252
+ if (limit <= 0 || items.length <= limit) {
253
+ return Promise.all(items.map(fn));
254
+ }
255
+ const results = new Array(items.length);
256
+ let nextIndex = 0;
257
+ async function worker() {
258
+ while (nextIndex < items.length) {
259
+ const idx = nextIndex++;
260
+ results[idx] = await fn(items[idx]);
261
+ }
262
+ }
263
+ const workers = [];
264
+ for (let i = 0; i < Math.min(limit, items.length); i++) {
265
+ workers.push(worker());
266
+ }
267
+ await Promise.all(workers);
268
+ return results;
269
+ }
270
+ }
271
+ exports.TaskDecomposer = TaskDecomposer;
272
+ //# sourceMappingURL=task-decomposer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-decomposer.js","sourceRoot":"","sources":["../../../lib/task-decomposer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,207 @@
1
+ "use strict";
2
+ /**
3
+ * Telemetry Provider — BYOT (Bring Your Own Telemetry) abstraction.
4
+ *
5
+ * Defines a minimal interface over distributed tracing providers such as
6
+ * OpenTelemetry, Datadog APM, Honeycomb, etc. Network-AI core never imports
7
+ * a concrete telemetry SDK — only this interface — preserving the zero-
8
+ * dependency BYOC design.
9
+ *
10
+ * ## Wiring into adapter lifecycle hooks
11
+ *
12
+ * ```typescript
13
+ * import { createOtelHooks, CapturingTelemetryProvider } from 'network-ai';
14
+ * import { AdapterHookManager } from 'network-ai';
15
+ *
16
+ * const provider = new CapturingTelemetryProvider(); // or your own impl
17
+ * const hookManager = new AdapterHookManager();
18
+ * createOtelHooks(provider).forEach(h => hookManager.register(h));
19
+ * ```
20
+ *
21
+ * ## Implementing for OpenTelemetry
22
+ *
23
+ * ```typescript
24
+ * import { trace, SpanStatusCode } from '@opentelemetry/api';
25
+ * import type { ITelemetryProvider, SpanAttributes } from 'network-ai';
26
+ *
27
+ * class OtelProvider implements ITelemetryProvider {
28
+ * private tracer = trace.getTracer('network-ai');
29
+ * private spans = new Map<string, Span>();
30
+ *
31
+ * startSpan(name: string, attrs: SpanAttributes = {}): string {
32
+ * const span = this.tracer.startSpan(name, { attributes: attrs as Attributes });
33
+ * const id = `span_${Date.now()}`;
34
+ * this.spans.set(id, span);
35
+ * return id;
36
+ * }
37
+ * endSpan(id: string, status: 'ok' | 'error'): void {
38
+ * const span = this.spans.get(id);
39
+ * if (!span) return;
40
+ * span.setStatus({ code: status === 'ok' ? SpanStatusCode.OK : SpanStatusCode.ERROR });
41
+ * span.end();
42
+ * this.spans.delete(id);
43
+ * }
44
+ * recordEvent(id: string, name: string, attrs: SpanAttributes = {}): void {
45
+ * this.spans.get(id)?.addEvent(name, attrs as Attributes);
46
+ * }
47
+ * }
48
+ * ```
49
+ */
50
+ Object.defineProperty(exports, "__esModule", { value: true });
51
+ exports.CapturingTelemetryProvider = exports.NullTelemetryProvider = void 0;
52
+ exports.createOtelHooks = createOtelHooks;
53
+ // ============================================================================
54
+ // NULL PROVIDER (default — zero overhead when no telemetry is configured)
55
+ // ============================================================================
56
+ /**
57
+ * No-op implementation. Used as the default when no telemetry provider is
58
+ * supplied so the instrumentation path compiles to a handful of dead calls
59
+ * that the JIT eliminates.
60
+ */
61
+ class NullTelemetryProvider {
62
+ /** @inheritdoc */
63
+ startSpan(_name, _attributes) { return ''; }
64
+ /** @inheritdoc */
65
+ endSpan(_spanId, _status, _attributes) { }
66
+ /** @inheritdoc */
67
+ recordEvent(_spanId, _name, _attributes) { }
68
+ }
69
+ exports.NullTelemetryProvider = NullTelemetryProvider;
70
+ // ============================================================================
71
+ // CAPTURING PROVIDER (for testing)
72
+ // ============================================================================
73
+ /**
74
+ * In-memory provider that stores every span and event for test assertions.
75
+ *
76
+ * @example
77
+ * ```typescript
78
+ * const provider = new CapturingTelemetryProvider();
79
+ * createOtelHooks(provider).forEach(h => hookManager.register(h));
80
+ *
81
+ * await registry.executeAgent('agent:foo', payload, ctx);
82
+ *
83
+ * const span = provider.spans.find(s => s.name === 'adapter.execute');
84
+ * expect(span?.status).toBe('ok');
85
+ * ```
86
+ */
87
+ class CapturingTelemetryProvider {
88
+ /** All spans created since construction or last `clear()`. */
89
+ spans = [];
90
+ counter = 0;
91
+ /** @inheritdoc */
92
+ startSpan(name, attributes = {}) {
93
+ const spanId = `span_${++this.counter}`;
94
+ this.spans.push({ spanId, name, attributes: { ...attributes }, startedAt: Date.now(), events: [] });
95
+ return spanId;
96
+ }
97
+ /** @inheritdoc */
98
+ endSpan(spanId, status, attributes = {}) {
99
+ const span = this.spans.find(s => s.spanId === spanId);
100
+ if (!span)
101
+ return;
102
+ span.endedAt = Date.now();
103
+ span.status = status;
104
+ Object.assign(span.attributes, attributes);
105
+ }
106
+ /** @inheritdoc */
107
+ recordEvent(spanId, name, attributes = {}) {
108
+ const span = this.spans.find(s => s.spanId === spanId);
109
+ if (!span)
110
+ return;
111
+ span.events.push({ name, attributes: { ...attributes }, ts: Date.now() });
112
+ }
113
+ /** Clear all captured data and reset span counter. */
114
+ clear() {
115
+ this.spans.length = 0;
116
+ this.counter = 0;
117
+ }
118
+ }
119
+ exports.CapturingTelemetryProvider = CapturingTelemetryProvider;
120
+ // ============================================================================
121
+ // HOOK FACTORY
122
+ // ============================================================================
123
+ /** Metadata key used to propagate spanId through `HookContext`. @internal */
124
+ const SPAN_ID_META_KEY = '_otelSpanId';
125
+ /**
126
+ * Create a set of `ExecutionHook` objects that emit traces to `provider`.
127
+ *
128
+ * Register the returned hooks with an `AdapterHookManager`:
129
+ * ```typescript
130
+ * createOtelHooks(provider).forEach(h => hookManager.register(h));
131
+ * ```
132
+ *
133
+ * Three hooks are created — one per `HookPhase`:
134
+ * - `otel:beforeExecute` — calls `provider.startSpan('adapter.execute', {...})`
135
+ * - `otel:afterExecute` — calls `provider.endSpan(spanId, 'ok')`
136
+ * - `otel:onError` — calls `provider.endSpan(spanId, 'error')`
137
+ *
138
+ * Each hook has `priority: 100` so it runs before most user-defined hooks.
139
+ * The spanId is stored in `ctx.metadata._otelSpanId` for downstream hooks
140
+ * that wish to add their own `recordEvent` calls.
141
+ *
142
+ * **Permission check semantics:** `beforeExecute` fires once when execution
143
+ * begins — not per streaming chunk — matching the documented "once at start"
144
+ * semantics of `StreamingBaseAdapter`.
145
+ */
146
+ function createOtelHooks(provider) {
147
+ return [
148
+ {
149
+ name: 'otel:beforeExecute',
150
+ phase: 'beforeExecute',
151
+ priority: 100,
152
+ handler(ctx) {
153
+ try {
154
+ const spanId = provider.startSpan('adapter.execute', {
155
+ agentId: ctx.agentId,
156
+ action: ctx.payload.action ?? '',
157
+ depth: ctx.depth,
158
+ });
159
+ ctx.metadata[SPAN_ID_META_KEY] = spanId;
160
+ }
161
+ catch {
162
+ // Telemetry must never break execution
163
+ }
164
+ return ctx;
165
+ },
166
+ },
167
+ {
168
+ name: 'otel:afterExecute',
169
+ phase: 'afterExecute',
170
+ priority: 100,
171
+ handler(ctx) {
172
+ try {
173
+ const spanId = ctx.metadata[SPAN_ID_META_KEY];
174
+ if (spanId) {
175
+ provider.endSpan(spanId, 'ok', {
176
+ success: ctx.result?.success === true,
177
+ });
178
+ }
179
+ }
180
+ catch {
181
+ // no-op
182
+ }
183
+ return ctx;
184
+ },
185
+ },
186
+ {
187
+ name: 'otel:onError',
188
+ phase: 'onError',
189
+ priority: 100,
190
+ handler(ctx) {
191
+ try {
192
+ const spanId = ctx.metadata[SPAN_ID_META_KEY];
193
+ if (spanId) {
194
+ provider.endSpan(spanId, 'error', {
195
+ errorMessage: ctx.error?.message ?? 'unknown',
196
+ });
197
+ }
198
+ }
199
+ catch {
200
+ // no-op
201
+ }
202
+ return ctx;
203
+ },
204
+ },
205
+ ];
206
+ }
207
+ //# sourceMappingURL=telemetry-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telemetry-provider.js","sourceRoot":"","sources":["../../../lib/telemetry-provider.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,173 @@
1
+ "use strict";
2
+ /**
3
+ * TimelineScrubber — Step through orchestrator history at any sequence point.
4
+ *
5
+ * Wraps an OrchestratorEventBus and reconstructs state at any point by
6
+ * loading the nearest snapshot and replaying events forward. Dashboard
7
+ * clients can "drag a slider" to any sequence and get the state at that
8
+ * moment.
9
+ *
10
+ * @module TimelineScrubber
11
+ */
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.TimelineScrubber = void 0;
14
+ // ============================================================================
15
+ // STATE REDUCER
16
+ // ============================================================================
17
+ /** Apply a single bus event to mutable state. */
18
+ function applyEvent(state, event) {
19
+ switch (event.source) {
20
+ case 'blackboard': {
21
+ if (event.type === 'write' || event.type === 'commit') {
22
+ const key = event.data.key;
23
+ if (key)
24
+ state.blackboard[key] = event.data.value;
25
+ }
26
+ else if (event.type === 'delete') {
27
+ const key = event.data.key;
28
+ if (key)
29
+ delete state.blackboard[key];
30
+ }
31
+ break;
32
+ }
33
+ case 'orchestrator': {
34
+ if (event.type === 'delegation_start' && event.agentId) {
35
+ const target = event.data.targetAgent;
36
+ if (target && !state.agents[target]) {
37
+ state.agents[target] = { status: 'running', tokensUsed: 0 };
38
+ }
39
+ else if (target && state.agents[target]) {
40
+ state.agents[target].status = 'running';
41
+ }
42
+ }
43
+ if (event.type === 'delegation_failed' && event.data.targetAgent) {
44
+ const target = event.data.targetAgent;
45
+ if (state.agents[target])
46
+ state.agents[target].status = 'failed';
47
+ }
48
+ break;
49
+ }
50
+ case 'adapter': {
51
+ if (event.type === 'agent:execution:complete' && event.agentId) {
52
+ if (state.agents[event.agentId]) {
53
+ state.agents[event.agentId].status = 'completed';
54
+ }
55
+ }
56
+ break;
57
+ }
58
+ case 'quality': {
59
+ if (event.type === 'reject' && event.agentId) {
60
+ if (state.agents[event.agentId]) {
61
+ state.agents[event.agentId].status = 'failed';
62
+ }
63
+ }
64
+ break;
65
+ }
66
+ // Other sources: no state mutation needed for reconstruction
67
+ default:
68
+ break;
69
+ }
70
+ }
71
+ // ============================================================================
72
+ // SCRUBBER
73
+ // ============================================================================
74
+ /**
75
+ * Reconstructs state at any point in the event stream.
76
+ *
77
+ * @example
78
+ * ```ts
79
+ * const scrubber = new TimelineScrubber(orchestrator.eventBus);
80
+ * const frame = scrubber.frameAt(42);
81
+ * // frame.blackboard — state of blackboard at seq 42
82
+ * // frame.agents — agent statuses at seq 42
83
+ *
84
+ * const range = scrubber.getRange();
85
+ * // range.minSeq, range.maxSeq — slider bounds
86
+ * ```
87
+ */
88
+ class TimelineScrubber {
89
+ bus;
90
+ constructor(bus) {
91
+ this.bus = bus;
92
+ }
93
+ /**
94
+ * Reconstruct state at a specific sequence number.
95
+ */
96
+ frameAt(seq) {
97
+ // Find nearest snapshot at or before seq
98
+ const snapshot = this.bus.snapshotAt(seq);
99
+ // Determine replay start
100
+ const fromSeq = snapshot ? snapshot.atSeq + 1 : 0;
101
+ // Get events from snapshot to target seq
102
+ const replay = this.bus.replay({ fromSeq, toSeq: seq });
103
+ const appliedEvents = replay.events;
104
+ // Initialize state from snapshot or empty
105
+ const blackboard = snapshot
106
+ ? { ...snapshot.blackboard }
107
+ : {};
108
+ const agents = snapshot
109
+ ? Object.fromEntries(Object.entries(snapshot.agents).map(([k, v]) => [k, { ...v }]))
110
+ : {};
111
+ // Apply events forward
112
+ for (const event of appliedEvents) {
113
+ applyEvent({ blackboard, agents }, event);
114
+ }
115
+ // Find the event timestamp at this seq
116
+ const targetEvent = this.bus.getEvent(seq);
117
+ const timestamp = targetEvent?.timestamp ?? snapshot?.timestamp ?? new Date().toISOString();
118
+ return {
119
+ seq,
120
+ timestamp,
121
+ baseSnapshotSeq: snapshot?.atSeq ?? null,
122
+ appliedEvents,
123
+ blackboard,
124
+ agents,
125
+ budget: snapshot?.budget,
126
+ };
127
+ }
128
+ /**
129
+ * Get a range of frames (e.g. for scrubbing a window).
130
+ * Returns frames at evenly-spaced sequence numbers.
131
+ */
132
+ frameRange(fromSeq, toSeq, maxFrames = 50) {
133
+ const range = toSeq - fromSeq;
134
+ const step = Math.max(1, Math.floor(range / maxFrames));
135
+ const frames = [];
136
+ for (let s = fromSeq; s <= toSeq; s += step) {
137
+ frames.push(this.frameAt(s));
138
+ }
139
+ // Always include the last frame
140
+ if (frames.length === 0 || frames[frames.length - 1].seq !== toSeq) {
141
+ frames.push(this.frameAt(toSeq));
142
+ }
143
+ return frames;
144
+ }
145
+ /**
146
+ * Get the timeline range info (slider bounds).
147
+ */
148
+ getRange() {
149
+ const snapshots = this.bus.getSnapshots();
150
+ const replay = this.bus.replay();
151
+ return {
152
+ minSeq: replay.events.length > 0 ? replay.events[0].seq : 0,
153
+ maxSeq: this.bus.currentSeq - 1,
154
+ totalEvents: replay.totalEvents,
155
+ snapshotCount: snapshots.length,
156
+ snapshotSeqs: snapshots.map(s => s.atSeq),
157
+ };
158
+ }
159
+ /**
160
+ * Step forward from a given frame by N events.
161
+ */
162
+ stepForward(currentSeq, steps = 1) {
163
+ return this.frameAt(Math.min(currentSeq + steps, this.bus.currentSeq - 1));
164
+ }
165
+ /**
166
+ * Step backward from a given frame by N events.
167
+ */
168
+ stepBackward(currentSeq, steps = 1) {
169
+ return this.frameAt(Math.max(currentSeq - steps, 0));
170
+ }
171
+ }
172
+ exports.TimelineScrubber = TimelineScrubber;
173
+ //# sourceMappingURL=timeline-scrubber.js.map