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,259 @@
1
+ "use strict";
2
+ /**
3
+ * Barnes-Hut QuadTree — Spatial indexing for O(n log n) force simulation
4
+ *
5
+ * Used by the topology dashboard to replace the naive O(n²) all-pairs
6
+ * repulsion with Barnes-Hut approximation. Also provides viewport queries
7
+ * for culling off-screen nodes.
8
+ *
9
+ * @module QuadTree
10
+ * @version 1.0.0
11
+ */
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.QuadTree = void 0;
14
+ // ============================================================================
15
+ // QUADTREE NODE
16
+ // ============================================================================
17
+ const QT_CAPACITY = 8; // Points per leaf before subdividing
18
+ /**
19
+ * A QuadTree for 2D spatial indexing with Barnes-Hut mass summaries.
20
+ *
21
+ * Usage:
22
+ * ```typescript
23
+ * const qt = new QuadTree({ x: 500, y: 400, halfW: 500, halfH: 400 });
24
+ * qt.insert({ id: 'a', x: 100, y: 200 });
25
+ * qt.insert({ id: 'b', x: 300, y: 150 });
26
+ *
27
+ * // Barnes-Hut force query (theta = 0.5)
28
+ * qt.forceOnPoint(100, 200, 0.5, (cx, cy, mass, dx, dy, distSq) => {
29
+ * // Apply repulsion force from (cx, cy) with given mass
30
+ * });
31
+ *
32
+ * // Viewport query
33
+ * const visible = qt.queryRange({ x: 250, y: 250, halfW: 250, halfH: 250 });
34
+ * ```
35
+ */
36
+ class QuadTree {
37
+ bounds;
38
+ points = [];
39
+ divided = false;
40
+ nw = null;
41
+ ne = null;
42
+ sw = null;
43
+ se = null;
44
+ mass = { count: 0, cx: 0, cy: 0 };
45
+ constructor(bounds) {
46
+ this.bounds = bounds;
47
+ }
48
+ // --------------------------------------------------------------------------
49
+ // INSERTION
50
+ // --------------------------------------------------------------------------
51
+ /**
52
+ * Insert a point into the tree.
53
+ * @returns true if inserted, false if out of bounds
54
+ */
55
+ insert(point) {
56
+ if (!this.containsPoint(point.x, point.y))
57
+ return false;
58
+ // Update mass center incrementally
59
+ const prev = this.mass.count;
60
+ this.mass.cx = (this.mass.cx * prev + point.x) / (prev + 1);
61
+ this.mass.cy = (this.mass.cy * prev + point.y) / (prev + 1);
62
+ this.mass.count = prev + 1;
63
+ if (!this.divided && this.points.length < QT_CAPACITY) {
64
+ this.points.push(point);
65
+ return true;
66
+ }
67
+ if (!this.divided) {
68
+ this.subdivide();
69
+ }
70
+ if (this.nw.insert(point))
71
+ return true;
72
+ if (this.ne.insert(point))
73
+ return true;
74
+ if (this.sw.insert(point))
75
+ return true;
76
+ if (this.se.insert(point))
77
+ return true;
78
+ // Shouldn't happen if containsPoint passed, but safety fallback
79
+ return false;
80
+ }
81
+ /**
82
+ * Build the tree from an array of points (faster than individual inserts).
83
+ */
84
+ static build(points, bounds) {
85
+ const tree = new QuadTree(bounds);
86
+ for (const p of points) {
87
+ tree.insert(p);
88
+ }
89
+ return tree;
90
+ }
91
+ // --------------------------------------------------------------------------
92
+ // QUERIES
93
+ // --------------------------------------------------------------------------
94
+ /**
95
+ * Find all points within a rectangular viewport.
96
+ */
97
+ queryRange(range) {
98
+ const found = [];
99
+ this.queryRangeInto(range, found);
100
+ return found;
101
+ }
102
+ queryRangeInto(range, found) {
103
+ if (!this.intersects(range))
104
+ return;
105
+ for (const p of this.points) {
106
+ if (p.x >= range.x - range.halfW &&
107
+ p.x <= range.x + range.halfW &&
108
+ p.y >= range.y - range.halfH &&
109
+ p.y <= range.y + range.halfH) {
110
+ found.push(p);
111
+ }
112
+ }
113
+ if (this.divided) {
114
+ this.nw.queryRangeInto(range, found);
115
+ this.ne.queryRangeInto(range, found);
116
+ this.sw.queryRangeInto(range, found);
117
+ this.se.queryRangeInto(range, found);
118
+ }
119
+ }
120
+ // --------------------------------------------------------------------------
121
+ // BARNES-HUT FORCE TRAVERSAL
122
+ // --------------------------------------------------------------------------
123
+ /**
124
+ * Traverse the tree with Barnes-Hut approximation for a single point.
125
+ *
126
+ * For each region, if the region is "far enough" (width/distance < theta),
127
+ * treat it as a point mass at the center of mass. Otherwise recurse.
128
+ *
129
+ * @param px - Query point x
130
+ * @param py - Query point y
131
+ * @param theta - Opening angle threshold (0.5 is common, higher = faster but less accurate)
132
+ * @param callback - Called for each mass interaction: (cx, cy, mass, dx, dy, distSq)
133
+ */
134
+ forceOnPoint(px, py, theta, callback) {
135
+ if (this.mass.count === 0)
136
+ return;
137
+ const dx = this.mass.cx - px;
138
+ const dy = this.mass.cy - py;
139
+ const distSq = dx * dx + dy * dy;
140
+ // If this is a leaf with points, interact directly
141
+ if (!this.divided) {
142
+ if (distSq > 0.01) {
143
+ callback(this.mass.cx, this.mass.cy, this.mass.count, dx, dy, distSq);
144
+ }
145
+ return;
146
+ }
147
+ // Barnes-Hut criterion: region width / distance < theta → approximate
148
+ const regionWidth = this.bounds.halfW * 2;
149
+ if (regionWidth * regionWidth < theta * theta * distSq) {
150
+ callback(this.mass.cx, this.mass.cy, this.mass.count, dx, dy, distSq);
151
+ return;
152
+ }
153
+ // Recurse into children
154
+ this.nw.forceOnPoint(px, py, theta, callback);
155
+ this.ne.forceOnPoint(px, py, theta, callback);
156
+ this.sw.forceOnPoint(px, py, theta, callback);
157
+ this.se.forceOnPoint(px, py, theta, callback);
158
+ }
159
+ // --------------------------------------------------------------------------
160
+ // ACCESSORS
161
+ // --------------------------------------------------------------------------
162
+ /** Total point count in this subtree */
163
+ get count() {
164
+ return this.mass.count;
165
+ }
166
+ /** The mass summary of this subtree */
167
+ getMass() {
168
+ return { ...this.mass };
169
+ }
170
+ /** The bounds of this node */
171
+ getBounds() {
172
+ return { ...this.bounds };
173
+ }
174
+ /** Whether this node has been subdivided */
175
+ get isSubdivided() {
176
+ return this.divided;
177
+ }
178
+ // --------------------------------------------------------------------------
179
+ // CLUSTERING SUPPORT
180
+ // --------------------------------------------------------------------------
181
+ /**
182
+ * Get cluster summaries at a given depth or size threshold.
183
+ * Returns groups of points that share a QuadTree cell below the given size.
184
+ *
185
+ * @param maxCellSize - Maximum cell width to stop recursing (in world units)
186
+ * @returns Array of clusters, each with center, count, and contained point ids
187
+ */
188
+ getClusters(maxCellSize) {
189
+ const clusters = [];
190
+ this.collectClusters(maxCellSize, clusters);
191
+ return clusters;
192
+ }
193
+ collectClusters(maxCellSize, out) {
194
+ if (this.mass.count === 0)
195
+ return;
196
+ const cellSize = this.bounds.halfW * 2;
197
+ // If this cell is small enough OR is a leaf, emit as cluster
198
+ if (cellSize <= maxCellSize || !this.divided) {
199
+ const ids = this.collectAllIds();
200
+ if (ids.length > 0) {
201
+ out.push({
202
+ cx: this.mass.cx,
203
+ cy: this.mass.cy,
204
+ count: this.mass.count,
205
+ ids,
206
+ });
207
+ }
208
+ return;
209
+ }
210
+ this.nw.collectClusters(maxCellSize, out);
211
+ this.ne.collectClusters(maxCellSize, out);
212
+ this.sw.collectClusters(maxCellSize, out);
213
+ this.se.collectClusters(maxCellSize, out);
214
+ }
215
+ collectAllIds() {
216
+ const ids = [];
217
+ for (const p of this.points)
218
+ ids.push(p.id);
219
+ if (this.divided) {
220
+ ids.push(...this.nw.collectAllIds());
221
+ ids.push(...this.ne.collectAllIds());
222
+ ids.push(...this.sw.collectAllIds());
223
+ ids.push(...this.se.collectAllIds());
224
+ }
225
+ return ids;
226
+ }
227
+ // --------------------------------------------------------------------------
228
+ // INTERNALS
229
+ // --------------------------------------------------------------------------
230
+ subdivide() {
231
+ const { x, y, halfW, halfH } = this.bounds;
232
+ const qW = halfW / 2;
233
+ const qH = halfH / 2;
234
+ this.nw = new QuadTree({ x: x - qW, y: y - qH, halfW: qW, halfH: qH });
235
+ this.ne = new QuadTree({ x: x + qW, y: y - qH, halfW: qW, halfH: qH });
236
+ this.sw = new QuadTree({ x: x - qW, y: y + qH, halfW: qW, halfH: qH });
237
+ this.se = new QuadTree({ x: x + qW, y: y + qH, halfW: qW, halfH: qH });
238
+ // Re-insert existing points into children
239
+ for (const p of this.points) {
240
+ this.nw.insert(p) || this.ne.insert(p) || this.sw.insert(p) || this.se.insert(p);
241
+ }
242
+ this.points = [];
243
+ this.divided = true;
244
+ }
245
+ containsPoint(x, y) {
246
+ return (x >= this.bounds.x - this.bounds.halfW &&
247
+ x <= this.bounds.x + this.bounds.halfW &&
248
+ y >= this.bounds.y - this.bounds.halfH &&
249
+ y <= this.bounds.y + this.bounds.halfH);
250
+ }
251
+ intersects(range) {
252
+ return !(range.x - range.halfW > this.bounds.x + this.bounds.halfW ||
253
+ range.x + range.halfW < this.bounds.x - this.bounds.halfW ||
254
+ range.y - range.halfH > this.bounds.y + this.bounds.halfH ||
255
+ range.y + range.halfH < this.bounds.y - this.bounds.halfH);
256
+ }
257
+ }
258
+ exports.QuadTree = QuadTree;
259
+ //# sourceMappingURL=quadtree.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quadtree.js","sourceRoot":"","sources":["../../../lib/quadtree.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,217 @@
1
+ "use strict";
2
+ /**
3
+ * Route Classifier — Short-Circuit Routing for Network-AI
4
+ *
5
+ * Classifies an incoming goal into one of three categories before any
6
+ * DAG planning occurs. Simple factual lookups are routed directly to a
7
+ * single agent, bypassing the Blackboard/locking layer entirely to save
8
+ * latency and token cost. Complex synthesis uses the full DAG pipeline.
9
+ * System failures are surfaced immediately.
10
+ *
11
+ * Zero external dependencies — the classifier function is pluggable so
12
+ * callers can use any model (Haiku, Llama-3-8B, rule-based heuristic, …).
13
+ *
14
+ * @module RouteClassifier
15
+ * @version 1.0.0
16
+ */
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.RouteClassifier = void 0;
19
+ exports.createHeuristicClassifier = createHeuristicClassifier;
20
+ exports.createLLMClassifier = createLLMClassifier;
21
+ // ============================================================================
22
+ // RULE-BASED HEURISTIC CLASSIFIER (built-in, zero model cost)
23
+ // ============================================================================
24
+ /**
25
+ * A simple keyword / length heuristic classifier for when you don't want to
26
+ * spend tokens on a model call for every request.
27
+ *
28
+ * Treats goals of ≤ 15 words with question-like phrasing as FACTUAL_LOOKUP
29
+ * and everything else as COMPLEX_SYNTHESIS.
30
+ */
31
+ function createHeuristicClassifier() {
32
+ const LOOKUP_STARTERS = [
33
+ 'what is', 'what are', 'who is', 'who are', 'when is', 'when was',
34
+ 'where is', 'where was', 'how many', 'how much', 'define ', 'list ',
35
+ 'name ', 'tell me', 'give me', 'show me',
36
+ ];
37
+ return async (goal) => {
38
+ const normalized = goal.trim().toLowerCase();
39
+ if (!normalized) {
40
+ return {
41
+ category: 'SYSTEM_FAILURE',
42
+ rationale: 'Goal is empty',
43
+ confidence: 1,
44
+ classifiedAt: Date.now(),
45
+ };
46
+ }
47
+ const wordCount = normalized.split(/\s+/).length;
48
+ const isShort = wordCount <= 15;
49
+ const startsLikeQuestion = LOOKUP_STARTERS.some((s) => normalized.startsWith(s));
50
+ const endsWithQuestion = normalized.endsWith('?');
51
+ if (isShort && (startsLikeQuestion || endsWithQuestion)) {
52
+ return {
53
+ category: 'FACTUAL_LOOKUP',
54
+ rationale: `Short goal (${wordCount} words) with question-like phrasing.`,
55
+ confidence: 0.8,
56
+ classifiedAt: Date.now(),
57
+ };
58
+ }
59
+ return {
60
+ category: 'COMPLEX_SYNTHESIS',
61
+ rationale: `Goal requires multi-step reasoning (${wordCount} words).`,
62
+ confidence: 0.75,
63
+ classifiedAt: Date.now(),
64
+ };
65
+ };
66
+ }
67
+ /**
68
+ * Build a classifier backed by an LLM via the Network-AI executor API.
69
+ *
70
+ * @param executor - The executor function from the adapter system
71
+ * @param classifierAgentId - Agent ID for the fast classification model
72
+ */
73
+ function createLLMClassifier(executor, classifierAgentId) {
74
+ return async (goal) => {
75
+ const prompt = [
76
+ 'Classify the following goal into exactly one category:',
77
+ ' FACTUAL_LOOKUP — simple factual question answerable in one step',
78
+ ' COMPLEX_SYNTHESIS — requires multi-step research/reasoning/execution',
79
+ ' SYSTEM_FAILURE — invalid, malformed, or unclassifiable input',
80
+ '',
81
+ `GOAL: ${goal}`,
82
+ '',
83
+ 'Respond with ONLY valid JSON matching this schema:',
84
+ '{"category":"FACTUAL_LOOKUP|COMPLEX_SYNTHESIS|SYSTEM_FAILURE","rationale":"...","confidence":0.0-1.0}',
85
+ ].join('\n');
86
+ try {
87
+ const result = await executor(classifierAgentId, { action: 'classify', params: { prompt } }, { agentId: classifierAgentId, taskId: `classify-${Date.now()}`, metadata: { type: 'route-classification' } });
88
+ if (!result.success || !result.data) {
89
+ return {
90
+ category: 'COMPLEX_SYNTHESIS',
91
+ rationale: 'Classifier returned no data — defaulting to COMPLEX_SYNTHESIS',
92
+ confidence: 0.5,
93
+ classifiedAt: Date.now(),
94
+ };
95
+ }
96
+ // Parse response
97
+ let parsed;
98
+ const raw = typeof result.data === 'string' ? result.data : JSON.stringify(result.data);
99
+ try {
100
+ // Strip markdown fences
101
+ const cleaned = raw.replace(/```[a-z]*\n?/g, '').replace(/```/g, '').trim();
102
+ const start = cleaned.indexOf('{');
103
+ const end = cleaned.lastIndexOf('}');
104
+ parsed = JSON.parse(cleaned.substring(start, end + 1));
105
+ }
106
+ catch {
107
+ return {
108
+ category: 'COMPLEX_SYNTHESIS',
109
+ rationale: 'Classifier response parse failed — defaulting to COMPLEX_SYNTHESIS',
110
+ confidence: 0.4,
111
+ classifiedAt: Date.now(),
112
+ };
113
+ }
114
+ const validCategories = ['FACTUAL_LOOKUP', 'COMPLEX_SYNTHESIS', 'SYSTEM_FAILURE'];
115
+ const category = validCategories.includes(parsed.category) ? parsed.category : 'COMPLEX_SYNTHESIS';
116
+ return {
117
+ category,
118
+ rationale: parsed.rationale ?? '',
119
+ confidence: typeof parsed.confidence === 'number' ? Math.min(1, Math.max(0, parsed.confidence)) : undefined,
120
+ classifiedAt: Date.now(),
121
+ };
122
+ }
123
+ catch (err) {
124
+ return {
125
+ category: 'COMPLEX_SYNTHESIS',
126
+ rationale: `Classifier error (${err.message}) — defaulting to COMPLEX_SYNTHESIS`,
127
+ confidence: 0.3,
128
+ classifiedAt: Date.now(),
129
+ };
130
+ }
131
+ };
132
+ }
133
+ // ============================================================================
134
+ // ROUTE CLASSIFIER
135
+ // ============================================================================
136
+ /**
137
+ * RouteClassifier evaluates a goal before DAG planning begins and decides
138
+ * whether to short-circuit to a single agent (FACTUAL_LOOKUP) or proceed
139
+ * with the full multi-agent pipeline (COMPLEX_SYNTHESIS).
140
+ *
141
+ * @example
142
+ * ```typescript
143
+ * const classifier = new RouteClassifier(createHeuristicClassifier());
144
+ * const { category } = await classifier.classify('What is the capital of France?');
145
+ * // category === 'FACTUAL_LOOKUP'
146
+ * ```
147
+ */
148
+ class RouteClassifier {
149
+ classifierFn;
150
+ options;
151
+ constructor(classifierFn, options = {}) {
152
+ this.classifierFn = classifierFn;
153
+ this.options = options;
154
+ }
155
+ /**
156
+ * Classify a goal.
157
+ */
158
+ async classify(goal) {
159
+ if (!goal || typeof goal !== 'string') {
160
+ return {
161
+ category: 'SYSTEM_FAILURE',
162
+ rationale: 'Goal must be a non-empty string',
163
+ confidence: 1,
164
+ classifiedAt: Date.now(),
165
+ };
166
+ }
167
+ return this.classifierFn(goal);
168
+ }
169
+ /**
170
+ * Classify a goal and, if FACTUAL_LOOKUP, short-circuit to a single agent.
171
+ *
172
+ * Returns the classification result and, when short-circuited, the agent's
173
+ * direct answer. The caller should check `result.shortCircuited` — if false,
174
+ * proceed with the normal DAG pipeline.
175
+ *
176
+ * @param goal - Natural language goal
177
+ * @param executor - Agent executor (required for FACTUAL_LOOKUP short-circuit)
178
+ * @param fallbackAgentId - Agent to call on FACTUAL_LOOKUP (overrides options.lookupAgentId)
179
+ */
180
+ async route(goal, executor, fallbackAgentId) {
181
+ const classification = await this.classify(goal);
182
+ if (classification.category === 'SYSTEM_FAILURE') {
183
+ return {
184
+ classification,
185
+ shortCircuited: true,
186
+ error: `System failure: ${classification.rationale}`,
187
+ };
188
+ }
189
+ if (classification.category === 'FACTUAL_LOOKUP') {
190
+ const agentId = fallbackAgentId ?? this.options.lookupAgentId;
191
+ if (!executor || !agentId) {
192
+ // No executor configured — fall through to DAG pipeline
193
+ return { classification, shortCircuited: false };
194
+ }
195
+ try {
196
+ const result = await executor(agentId, { action: 'answer', params: { goal } }, { agentId, taskId: `lookup-${Date.now()}`, metadata: { type: 'factual-lookup' } });
197
+ return {
198
+ classification,
199
+ shortCircuited: true,
200
+ answer: result.data,
201
+ error: result.success ? undefined : result.error?.message,
202
+ };
203
+ }
204
+ catch (err) {
205
+ return {
206
+ classification,
207
+ shortCircuited: true,
208
+ error: err.message,
209
+ };
210
+ }
211
+ }
212
+ // COMPLEX_SYNTHESIS — proceed with DAG
213
+ return { classification, shortCircuited: false };
214
+ }
215
+ }
216
+ exports.RouteClassifier = RouteClassifier;
217
+ //# sourceMappingURL=route-classifier.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route-classifier.js","sourceRoot":"","sources":["../../../lib/route-classifier.ts"],"names":[],"mappings":"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"}