@ninebix/nmt-system 1.0.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 (639) hide show
  1. package/LICENSE +70 -0
  2. package/README.md +465 -0
  3. package/dist/api/cli-server.d.ts +83 -0
  4. package/dist/api/cli-server.d.ts.map +1 -0
  5. package/dist/api/cli-server.js +597 -0
  6. package/dist/api/cli-server.js.map +1 -0
  7. package/dist/api/index.d.ts +6 -0
  8. package/dist/api/index.d.ts.map +1 -0
  9. package/dist/api/index.js +6 -0
  10. package/dist/api/index.js.map +1 -0
  11. package/dist/api/middleware/index.d.ts +12 -0
  12. package/dist/api/middleware/index.d.ts.map +1 -0
  13. package/dist/api/middleware/index.js +13 -0
  14. package/dist/api/middleware/index.js.map +1 -0
  15. package/dist/api/middleware/logger.d.ts +21 -0
  16. package/dist/api/middleware/logger.d.ts.map +1 -0
  17. package/dist/api/middleware/logger.js +134 -0
  18. package/dist/api/middleware/logger.js.map +1 -0
  19. package/dist/api/middleware/rate-limit.d.ts +26 -0
  20. package/dist/api/middleware/rate-limit.d.ts.map +1 -0
  21. package/dist/api/middleware/rate-limit.js +107 -0
  22. package/dist/api/middleware/rate-limit.js.map +1 -0
  23. package/dist/api/middleware/response.d.ts +61 -0
  24. package/dist/api/middleware/response.d.ts.map +1 -0
  25. package/dist/api/middleware/response.js +86 -0
  26. package/dist/api/middleware/response.js.map +1 -0
  27. package/dist/api/middleware/validation.d.ts +43 -0
  28. package/dist/api/middleware/validation.d.ts.map +1 -0
  29. package/dist/api/middleware/validation.js +257 -0
  30. package/dist/api/middleware/validation.js.map +1 -0
  31. package/dist/api/server.d.ts +79 -0
  32. package/dist/api/server.d.ts.map +1 -0
  33. package/dist/api/server.js +2011 -0
  34. package/dist/api/server.js.map +1 -0
  35. package/dist/bin/nmt.d.ts +9 -0
  36. package/dist/bin/nmt.d.ts.map +1 -0
  37. package/dist/bin/nmt.js +1142 -0
  38. package/dist/bin/nmt.js.map +1 -0
  39. package/dist/cli/commands/attractor.d.ts +6 -0
  40. package/dist/cli/commands/attractor.d.ts.map +1 -0
  41. package/dist/cli/commands/attractor.js +167 -0
  42. package/dist/cli/commands/attractor.js.map +1 -0
  43. package/dist/cli/commands/dimension.d.ts +6 -0
  44. package/dist/cli/commands/dimension.d.ts.map +1 -0
  45. package/dist/cli/commands/dimension.js +85 -0
  46. package/dist/cli/commands/dimension.js.map +1 -0
  47. package/dist/cli/commands/index.d.ts +11 -0
  48. package/dist/cli/commands/index.d.ts.map +1 -0
  49. package/dist/cli/commands/index.js +11 -0
  50. package/dist/cli/commands/index.js.map +1 -0
  51. package/dist/cli/commands/infer.d.ts +6 -0
  52. package/dist/cli/commands/infer.d.ts.map +1 -0
  53. package/dist/cli/commands/infer.js +139 -0
  54. package/dist/cli/commands/infer.js.map +1 -0
  55. package/dist/cli/commands/learn.d.ts +6 -0
  56. package/dist/cli/commands/learn.d.ts.map +1 -0
  57. package/dist/cli/commands/learn.js +87 -0
  58. package/dist/cli/commands/learn.js.map +1 -0
  59. package/dist/cli/commands/orchestrate.d.ts +6 -0
  60. package/dist/cli/commands/orchestrate.d.ts.map +1 -0
  61. package/dist/cli/commands/orchestrate.js +279 -0
  62. package/dist/cli/commands/orchestrate.js.map +1 -0
  63. package/dist/cli/commands/prob.d.ts +6 -0
  64. package/dist/cli/commands/prob.d.ts.map +1 -0
  65. package/dist/cli/commands/prob.js +256 -0
  66. package/dist/cli/commands/prob.js.map +1 -0
  67. package/dist/cli/commands/quantum.d.ts +6 -0
  68. package/dist/cli/commands/quantum.d.ts.map +1 -0
  69. package/dist/cli/commands/quantum.js +150 -0
  70. package/dist/cli/commands/quantum.js.map +1 -0
  71. package/dist/cli/commands/sync.d.ts +65 -0
  72. package/dist/cli/commands/sync.d.ts.map +1 -0
  73. package/dist/cli/commands/sync.js +338 -0
  74. package/dist/cli/commands/sync.js.map +1 -0
  75. package/dist/cli/index.d.ts +9 -0
  76. package/dist/cli/index.d.ts.map +1 -0
  77. package/dist/cli/index.js +9 -0
  78. package/dist/cli/index.js.map +1 -0
  79. package/dist/cli/probabilistic-commands.d.ts +39 -0
  80. package/dist/cli/probabilistic-commands.d.ts.map +1 -0
  81. package/dist/cli/probabilistic-commands.js +112 -0
  82. package/dist/cli/probabilistic-commands.js.map +1 -0
  83. package/dist/cli/types.d.ts +69 -0
  84. package/dist/cli/types.d.ts.map +1 -0
  85. package/dist/cli/types.js +5 -0
  86. package/dist/cli/types.js.map +1 -0
  87. package/dist/cli/utils/formatters.d.ts +51 -0
  88. package/dist/cli/utils/formatters.d.ts.map +1 -0
  89. package/dist/cli/utils/formatters.js +79 -0
  90. package/dist/cli/utils/formatters.js.map +1 -0
  91. package/dist/cli/utils/helpers.d.ts +21 -0
  92. package/dist/cli/utils/helpers.d.ts.map +1 -0
  93. package/dist/cli/utils/helpers.js +51 -0
  94. package/dist/cli/utils/helpers.js.map +1 -0
  95. package/dist/cli/utils/index.d.ts +7 -0
  96. package/dist/cli/utils/index.d.ts.map +1 -0
  97. package/dist/cli/utils/index.js +13 -0
  98. package/dist/cli/utils/index.js.map +1 -0
  99. package/dist/cli/utils/validators.d.ts +162 -0
  100. package/dist/cli/utils/validators.d.ts.map +1 -0
  101. package/dist/cli/utils/validators.js +351 -0
  102. package/dist/cli/utils/validators.js.map +1 -0
  103. package/dist/core/advanced-embedding.d.ts +154 -0
  104. package/dist/core/advanced-embedding.d.ts.map +1 -0
  105. package/dist/core/advanced-embedding.js +367 -0
  106. package/dist/core/advanced-embedding.js.map +1 -0
  107. package/dist/core/attractor-model.d.ts +381 -0
  108. package/dist/core/attractor-model.d.ts.map +1 -0
  109. package/dist/core/attractor-model.js +821 -0
  110. package/dist/core/attractor-model.js.map +1 -0
  111. package/dist/core/bidirectional-inference.d.ts +143 -0
  112. package/dist/core/bidirectional-inference.d.ts.map +1 -0
  113. package/dist/core/bidirectional-inference.js +501 -0
  114. package/dist/core/bidirectional-inference.js.map +1 -0
  115. package/dist/core/chunk-engine.d.ts +78 -0
  116. package/dist/core/chunk-engine.d.ts.map +1 -0
  117. package/dist/core/chunk-engine.js +192 -0
  118. package/dist/core/chunk-engine.js.map +1 -0
  119. package/dist/core/dynamic-embedding.d.ts +327 -0
  120. package/dist/core/dynamic-embedding.d.ts.map +1 -0
  121. package/dist/core/dynamic-embedding.js +527 -0
  122. package/dist/core/dynamic-embedding.js.map +1 -0
  123. package/dist/core/embedding-similarity.d.ts +68 -0
  124. package/dist/core/embedding-similarity.d.ts.map +1 -0
  125. package/dist/core/embedding-similarity.js +291 -0
  126. package/dist/core/embedding-similarity.js.map +1 -0
  127. package/dist/core/evolution-scheduler.d.ts +101 -0
  128. package/dist/core/evolution-scheduler.d.ts.map +1 -0
  129. package/dist/core/evolution-scheduler.js +235 -0
  130. package/dist/core/evolution-scheduler.js.map +1 -0
  131. package/dist/core/hierarchical-chunker.d.ts +108 -0
  132. package/dist/core/hierarchical-chunker.d.ts.map +1 -0
  133. package/dist/core/hierarchical-chunker.js +296 -0
  134. package/dist/core/hierarchical-chunker.js.map +1 -0
  135. package/dist/core/hnsw-index.d.ts +111 -0
  136. package/dist/core/hnsw-index.d.ts.map +1 -0
  137. package/dist/core/hnsw-index.js +466 -0
  138. package/dist/core/hnsw-index.js.map +1 -0
  139. package/dist/core/index.d.ts +23 -0
  140. package/dist/core/index.d.ts.map +1 -0
  141. package/dist/core/index.js +25 -0
  142. package/dist/core/index.js.map +1 -0
  143. package/dist/core/language-analyzers.d.ts +124 -0
  144. package/dist/core/language-analyzers.d.ts.map +1 -0
  145. package/dist/core/language-analyzers.js +365 -0
  146. package/dist/core/language-analyzers.js.map +1 -0
  147. package/dist/core/local-embedding.d.ts +109 -0
  148. package/dist/core/local-embedding.d.ts.map +1 -0
  149. package/dist/core/local-embedding.js +222 -0
  150. package/dist/core/local-embedding.js.map +1 -0
  151. package/dist/core/merkle-engine.d.ts +263 -0
  152. package/dist/core/merkle-engine.d.ts.map +1 -0
  153. package/dist/core/merkle-engine.js +528 -0
  154. package/dist/core/merkle-engine.js.map +1 -0
  155. package/dist/core/multi-layer-reasoning.d.ts +178 -0
  156. package/dist/core/multi-layer-reasoning.d.ts.map +1 -0
  157. package/dist/core/multi-layer-reasoning.js +607 -0
  158. package/dist/core/multi-layer-reasoning.js.map +1 -0
  159. package/dist/core/neuron-graph.d.ts +134 -0
  160. package/dist/core/neuron-graph.d.ts.map +1 -0
  161. package/dist/core/neuron-graph.js +436 -0
  162. package/dist/core/neuron-graph.js.map +1 -0
  163. package/dist/core/probabilistic-neuron.d.ts +251 -0
  164. package/dist/core/probabilistic-neuron.d.ts.map +1 -0
  165. package/dist/core/probabilistic-neuron.js +618 -0
  166. package/dist/core/probabilistic-neuron.js.map +1 -0
  167. package/dist/core/probabilistic-orchestrator.d.ts +408 -0
  168. package/dist/core/probabilistic-orchestrator.d.ts.map +1 -0
  169. package/dist/core/probabilistic-orchestrator.js +798 -0
  170. package/dist/core/probabilistic-orchestrator.js.map +1 -0
  171. package/dist/core/semantic-chunker.d.ts +117 -0
  172. package/dist/core/semantic-chunker.d.ts.map +1 -0
  173. package/dist/core/semantic-chunker.js +464 -0
  174. package/dist/core/semantic-chunker.js.map +1 -0
  175. package/dist/events/event-bus.d.ts +166 -0
  176. package/dist/events/event-bus.d.ts.map +1 -0
  177. package/dist/events/event-bus.js +228 -0
  178. package/dist/events/event-bus.js.map +1 -0
  179. package/dist/events/index.d.ts +7 -0
  180. package/dist/events/index.d.ts.map +1 -0
  181. package/dist/events/index.js +7 -0
  182. package/dist/events/index.js.map +1 -0
  183. package/dist/events/progress-tracker.d.ts +150 -0
  184. package/dist/events/progress-tracker.d.ts.map +1 -0
  185. package/dist/events/progress-tracker.js +290 -0
  186. package/dist/events/progress-tracker.js.map +1 -0
  187. package/dist/extensions/clustering/community-detection.d.ts +90 -0
  188. package/dist/extensions/clustering/community-detection.d.ts.map +1 -0
  189. package/dist/extensions/clustering/community-detection.js +470 -0
  190. package/dist/extensions/clustering/community-detection.js.map +1 -0
  191. package/dist/extensions/clustering/index.d.ts +114 -0
  192. package/dist/extensions/clustering/index.d.ts.map +1 -0
  193. package/dist/extensions/clustering/index.js +468 -0
  194. package/dist/extensions/clustering/index.js.map +1 -0
  195. package/dist/extensions/clustering/topic-modeling.d.ts +86 -0
  196. package/dist/extensions/clustering/topic-modeling.d.ts.map +1 -0
  197. package/dist/extensions/clustering/topic-modeling.js +355 -0
  198. package/dist/extensions/clustering/topic-modeling.js.map +1 -0
  199. package/dist/extensions/distributed/coordinator.d.ts +114 -0
  200. package/dist/extensions/distributed/coordinator.d.ts.map +1 -0
  201. package/dist/extensions/distributed/coordinator.js +319 -0
  202. package/dist/extensions/distributed/coordinator.js.map +1 -0
  203. package/dist/extensions/distributed/index.d.ts +10 -0
  204. package/dist/extensions/distributed/index.d.ts.map +1 -0
  205. package/dist/extensions/distributed/index.js +10 -0
  206. package/dist/extensions/distributed/index.js.map +1 -0
  207. package/dist/extensions/distributed/queue.d.ts +157 -0
  208. package/dist/extensions/distributed/queue.d.ts.map +1 -0
  209. package/dist/extensions/distributed/queue.js +326 -0
  210. package/dist/extensions/distributed/queue.js.map +1 -0
  211. package/dist/extensions/distributed/scheduler.d.ts +107 -0
  212. package/dist/extensions/distributed/scheduler.d.ts.map +1 -0
  213. package/dist/extensions/distributed/scheduler.js +301 -0
  214. package/dist/extensions/distributed/scheduler.js.map +1 -0
  215. package/dist/extensions/distributed/worker.d.ts +112 -0
  216. package/dist/extensions/distributed/worker.d.ts.map +1 -0
  217. package/dist/extensions/distributed/worker.js +260 -0
  218. package/dist/extensions/distributed/worker.js.map +1 -0
  219. package/dist/index.d.ts +14 -0
  220. package/dist/index.d.ts.map +1 -0
  221. package/dist/index.js +20 -0
  222. package/dist/index.js.map +1 -0
  223. package/dist/mcp/server.d.ts +43 -0
  224. package/dist/mcp/server.d.ts.map +1 -0
  225. package/dist/mcp/server.js +494 -0
  226. package/dist/mcp/server.js.map +1 -0
  227. package/dist/services/adaptive-fallback.d.ts +140 -0
  228. package/dist/services/adaptive-fallback.d.ts.map +1 -0
  229. package/dist/services/adaptive-fallback.js +273 -0
  230. package/dist/services/adaptive-fallback.js.map +1 -0
  231. package/dist/services/answer-gate.d.ts +112 -0
  232. package/dist/services/answer-gate.d.ts.map +1 -0
  233. package/dist/services/answer-gate.js +299 -0
  234. package/dist/services/answer-gate.js.map +1 -0
  235. package/dist/services/auto-learning.d.ts +135 -0
  236. package/dist/services/auto-learning.d.ts.map +1 -0
  237. package/dist/services/auto-learning.js +413 -0
  238. package/dist/services/auto-learning.js.map +1 -0
  239. package/dist/services/context-compressor.d.ts +77 -0
  240. package/dist/services/context-compressor.d.ts.map +1 -0
  241. package/dist/services/context-compressor.js +234 -0
  242. package/dist/services/context-compressor.js.map +1 -0
  243. package/dist/services/efficient-rag.d.ts +140 -0
  244. package/dist/services/efficient-rag.d.ts.map +1 -0
  245. package/dist/services/efficient-rag.js +311 -0
  246. package/dist/services/efficient-rag.js.map +1 -0
  247. package/dist/services/embedding-provider.d.ts +72 -0
  248. package/dist/services/embedding-provider.d.ts.map +1 -0
  249. package/dist/services/embedding-provider.js +176 -0
  250. package/dist/services/embedding-provider.js.map +1 -0
  251. package/dist/services/file-ingestion.d.ts +72 -0
  252. package/dist/services/file-ingestion.d.ts.map +1 -0
  253. package/dist/services/file-ingestion.js +237 -0
  254. package/dist/services/file-ingestion.js.map +1 -0
  255. package/dist/services/four-stage-learning.d.ts +552 -0
  256. package/dist/services/four-stage-learning.d.ts.map +1 -0
  257. package/dist/services/four-stage-learning.js +1110 -0
  258. package/dist/services/four-stage-learning.js.map +1 -0
  259. package/dist/services/graph.d.ts +94 -0
  260. package/dist/services/graph.d.ts.map +1 -0
  261. package/dist/services/graph.js +292 -0
  262. package/dist/services/graph.js.map +1 -0
  263. package/dist/services/index.d.ts +15 -0
  264. package/dist/services/index.d.ts.map +1 -0
  265. package/dist/services/index.js +18 -0
  266. package/dist/services/index.js.map +1 -0
  267. package/dist/services/ingestion.d.ts +98 -0
  268. package/dist/services/ingestion.d.ts.map +1 -0
  269. package/dist/services/ingestion.js +259 -0
  270. package/dist/services/ingestion.js.map +1 -0
  271. package/dist/services/learning.d.ts +67 -0
  272. package/dist/services/learning.d.ts.map +1 -0
  273. package/dist/services/learning.js +262 -0
  274. package/dist/services/learning.js.map +1 -0
  275. package/dist/services/llm-router.d.ts +143 -0
  276. package/dist/services/llm-router.d.ts.map +1 -0
  277. package/dist/services/llm-router.js +284 -0
  278. package/dist/services/llm-router.js.map +1 -0
  279. package/dist/services/llm.d.ts +86 -0
  280. package/dist/services/llm.d.ts.map +1 -0
  281. package/dist/services/llm.js +283 -0
  282. package/dist/services/llm.js.map +1 -0
  283. package/dist/services/metrics-dashboard.d.ts +262 -0
  284. package/dist/services/metrics-dashboard.d.ts.map +1 -0
  285. package/dist/services/metrics-dashboard.js +417 -0
  286. package/dist/services/metrics-dashboard.js.map +1 -0
  287. package/dist/services/neuron-lifecycle.d.ts +137 -0
  288. package/dist/services/neuron-lifecycle.d.ts.map +1 -0
  289. package/dist/services/neuron-lifecycle.js +422 -0
  290. package/dist/services/neuron-lifecycle.js.map +1 -0
  291. package/dist/services/nmt-pipeline.d.ts +219 -0
  292. package/dist/services/nmt-pipeline.d.ts.map +1 -0
  293. package/dist/services/nmt-pipeline.js +449 -0
  294. package/dist/services/nmt-pipeline.js.map +1 -0
  295. package/dist/services/query-cache.d.ts +136 -0
  296. package/dist/services/query-cache.d.ts.map +1 -0
  297. package/dist/services/query-cache.js +255 -0
  298. package/dist/services/query-cache.js.map +1 -0
  299. package/dist/services/query-normalize.d.ts +107 -0
  300. package/dist/services/query-normalize.d.ts.map +1 -0
  301. package/dist/services/query-normalize.js +366 -0
  302. package/dist/services/query-normalize.js.map +1 -0
  303. package/dist/services/query.d.ts +102 -0
  304. package/dist/services/query.d.ts.map +1 -0
  305. package/dist/services/query.js +227 -0
  306. package/dist/services/query.js.map +1 -0
  307. package/dist/services/text-embedding.d.ts +183 -0
  308. package/dist/services/text-embedding.d.ts.map +1 -0
  309. package/dist/services/text-embedding.js +633 -0
  310. package/dist/services/text-embedding.js.map +1 -0
  311. package/dist/services/verification-gate.d.ts +147 -0
  312. package/dist/services/verification-gate.d.ts.map +1 -0
  313. package/dist/services/verification-gate.js +344 -0
  314. package/dist/services/verification-gate.js.map +1 -0
  315. package/dist/services/verify.d.ts +114 -0
  316. package/dist/services/verify.d.ts.map +1 -0
  317. package/dist/services/verify.js +237 -0
  318. package/dist/services/verify.js.map +1 -0
  319. package/dist/services/web-search.d.ts +145 -0
  320. package/dist/services/web-search.d.ts.map +1 -0
  321. package/dist/services/web-search.js +534 -0
  322. package/dist/services/web-search.js.map +1 -0
  323. package/dist/src/api/cli-server.d.ts +83 -0
  324. package/dist/src/api/cli-server.d.ts.map +1 -0
  325. package/dist/src/api/cli-server.js +597 -0
  326. package/dist/src/api/cli-server.js.map +1 -0
  327. package/dist/src/api/index.d.ts +6 -0
  328. package/dist/src/api/index.d.ts.map +1 -0
  329. package/dist/src/api/index.js +6 -0
  330. package/dist/src/api/index.js.map +1 -0
  331. package/dist/src/cli/commands/attractor.d.ts +6 -0
  332. package/dist/src/cli/commands/attractor.d.ts.map +1 -0
  333. package/dist/src/cli/commands/attractor.js +167 -0
  334. package/dist/src/cli/commands/attractor.js.map +1 -0
  335. package/dist/src/cli/commands/dimension.d.ts +6 -0
  336. package/dist/src/cli/commands/dimension.d.ts.map +1 -0
  337. package/dist/src/cli/commands/dimension.js +85 -0
  338. package/dist/src/cli/commands/dimension.js.map +1 -0
  339. package/dist/src/cli/commands/index.d.ts +11 -0
  340. package/dist/src/cli/commands/index.d.ts.map +1 -0
  341. package/dist/src/cli/commands/index.js +11 -0
  342. package/dist/src/cli/commands/index.js.map +1 -0
  343. package/dist/src/cli/commands/infer.d.ts +6 -0
  344. package/dist/src/cli/commands/infer.d.ts.map +1 -0
  345. package/dist/src/cli/commands/infer.js +139 -0
  346. package/dist/src/cli/commands/infer.js.map +1 -0
  347. package/dist/src/cli/commands/learn.d.ts +6 -0
  348. package/dist/src/cli/commands/learn.d.ts.map +1 -0
  349. package/dist/src/cli/commands/learn.js +87 -0
  350. package/dist/src/cli/commands/learn.js.map +1 -0
  351. package/dist/src/cli/commands/orchestrate.d.ts +6 -0
  352. package/dist/src/cli/commands/orchestrate.d.ts.map +1 -0
  353. package/dist/src/cli/commands/orchestrate.js +279 -0
  354. package/dist/src/cli/commands/orchestrate.js.map +1 -0
  355. package/dist/src/cli/commands/prob.d.ts +6 -0
  356. package/dist/src/cli/commands/prob.d.ts.map +1 -0
  357. package/dist/src/cli/commands/prob.js +256 -0
  358. package/dist/src/cli/commands/prob.js.map +1 -0
  359. package/dist/src/cli/commands/sync.d.ts +65 -0
  360. package/dist/src/cli/commands/sync.d.ts.map +1 -0
  361. package/dist/src/cli/commands/sync.js +338 -0
  362. package/dist/src/cli/commands/sync.js.map +1 -0
  363. package/dist/src/cli/index.d.ts +9 -0
  364. package/dist/src/cli/index.d.ts.map +1 -0
  365. package/dist/src/cli/index.js +9 -0
  366. package/dist/src/cli/index.js.map +1 -0
  367. package/dist/src/cli/probabilistic-commands.d.ts +39 -0
  368. package/dist/src/cli/probabilistic-commands.d.ts.map +1 -0
  369. package/dist/src/cli/probabilistic-commands.js +112 -0
  370. package/dist/src/cli/probabilistic-commands.js.map +1 -0
  371. package/dist/src/cli/types.d.ts +69 -0
  372. package/dist/src/cli/types.d.ts.map +1 -0
  373. package/dist/src/cli/types.js +5 -0
  374. package/dist/src/cli/types.js.map +1 -0
  375. package/dist/src/cli/utils/formatters.d.ts +51 -0
  376. package/dist/src/cli/utils/formatters.d.ts.map +1 -0
  377. package/dist/src/cli/utils/formatters.js +79 -0
  378. package/dist/src/cli/utils/formatters.js.map +1 -0
  379. package/dist/src/cli/utils/helpers.d.ts +21 -0
  380. package/dist/src/cli/utils/helpers.d.ts.map +1 -0
  381. package/dist/src/cli/utils/helpers.js +51 -0
  382. package/dist/src/cli/utils/helpers.js.map +1 -0
  383. package/dist/src/cli/utils/index.d.ts +7 -0
  384. package/dist/src/cli/utils/index.d.ts.map +1 -0
  385. package/dist/src/cli/utils/index.js +13 -0
  386. package/dist/src/cli/utils/index.js.map +1 -0
  387. package/dist/src/cli/utils/validators.d.ts +162 -0
  388. package/dist/src/cli/utils/validators.d.ts.map +1 -0
  389. package/dist/src/cli/utils/validators.js +351 -0
  390. package/dist/src/cli/utils/validators.js.map +1 -0
  391. package/dist/src/core/attractor-model.d.ts +381 -0
  392. package/dist/src/core/attractor-model.d.ts.map +1 -0
  393. package/dist/src/core/attractor-model.js +821 -0
  394. package/dist/src/core/attractor-model.js.map +1 -0
  395. package/dist/src/core/bidirectional-inference.d.ts +143 -0
  396. package/dist/src/core/bidirectional-inference.d.ts.map +1 -0
  397. package/dist/src/core/bidirectional-inference.js +501 -0
  398. package/dist/src/core/bidirectional-inference.js.map +1 -0
  399. package/dist/src/core/chunk-engine.d.ts +78 -0
  400. package/dist/src/core/chunk-engine.d.ts.map +1 -0
  401. package/dist/src/core/chunk-engine.js +192 -0
  402. package/dist/src/core/chunk-engine.js.map +1 -0
  403. package/dist/src/core/dynamic-embedding.d.ts +327 -0
  404. package/dist/src/core/dynamic-embedding.d.ts.map +1 -0
  405. package/dist/src/core/dynamic-embedding.js +527 -0
  406. package/dist/src/core/dynamic-embedding.js.map +1 -0
  407. package/dist/src/core/evolution-scheduler.d.ts +101 -0
  408. package/dist/src/core/evolution-scheduler.d.ts.map +1 -0
  409. package/dist/src/core/evolution-scheduler.js +235 -0
  410. package/dist/src/core/evolution-scheduler.js.map +1 -0
  411. package/dist/src/core/hnsw-index.d.ts +111 -0
  412. package/dist/src/core/hnsw-index.d.ts.map +1 -0
  413. package/dist/src/core/hnsw-index.js +466 -0
  414. package/dist/src/core/hnsw-index.js.map +1 -0
  415. package/dist/src/core/index.d.ts +23 -0
  416. package/dist/src/core/index.d.ts.map +1 -0
  417. package/dist/src/core/index.js +25 -0
  418. package/dist/src/core/index.js.map +1 -0
  419. package/dist/src/core/merkle-engine.d.ts +263 -0
  420. package/dist/src/core/merkle-engine.d.ts.map +1 -0
  421. package/dist/src/core/merkle-engine.js +528 -0
  422. package/dist/src/core/merkle-engine.js.map +1 -0
  423. package/dist/src/core/neuron-graph.d.ts +134 -0
  424. package/dist/src/core/neuron-graph.d.ts.map +1 -0
  425. package/dist/src/core/neuron-graph.js +436 -0
  426. package/dist/src/core/neuron-graph.js.map +1 -0
  427. package/dist/src/core/probabilistic-neuron.d.ts +251 -0
  428. package/dist/src/core/probabilistic-neuron.d.ts.map +1 -0
  429. package/dist/src/core/probabilistic-neuron.js +618 -0
  430. package/dist/src/core/probabilistic-neuron.js.map +1 -0
  431. package/dist/src/core/probabilistic-orchestrator.d.ts +408 -0
  432. package/dist/src/core/probabilistic-orchestrator.d.ts.map +1 -0
  433. package/dist/src/core/probabilistic-orchestrator.js +798 -0
  434. package/dist/src/core/probabilistic-orchestrator.js.map +1 -0
  435. package/dist/src/events/event-bus.d.ts +166 -0
  436. package/dist/src/events/event-bus.d.ts.map +1 -0
  437. package/dist/src/events/event-bus.js +228 -0
  438. package/dist/src/events/event-bus.js.map +1 -0
  439. package/dist/src/events/index.d.ts +7 -0
  440. package/dist/src/events/index.d.ts.map +1 -0
  441. package/dist/src/events/index.js +7 -0
  442. package/dist/src/events/index.js.map +1 -0
  443. package/dist/src/events/progress-tracker.d.ts +150 -0
  444. package/dist/src/events/progress-tracker.d.ts.map +1 -0
  445. package/dist/src/events/progress-tracker.js +290 -0
  446. package/dist/src/events/progress-tracker.js.map +1 -0
  447. package/dist/src/extensions/clustering/index.d.ts +114 -0
  448. package/dist/src/extensions/clustering/index.d.ts.map +1 -0
  449. package/dist/src/extensions/clustering/index.js +468 -0
  450. package/dist/src/extensions/clustering/index.js.map +1 -0
  451. package/dist/src/index.d.ts +14 -0
  452. package/dist/src/index.d.ts.map +1 -0
  453. package/dist/src/index.js +20 -0
  454. package/dist/src/index.js.map +1 -0
  455. package/dist/src/mcp/server.d.ts +43 -0
  456. package/dist/src/mcp/server.d.ts.map +1 -0
  457. package/dist/src/mcp/server.js +494 -0
  458. package/dist/src/mcp/server.js.map +1 -0
  459. package/dist/src/services/embedding-provider.d.ts +72 -0
  460. package/dist/src/services/embedding-provider.d.ts.map +1 -0
  461. package/dist/src/services/embedding-provider.js +176 -0
  462. package/dist/src/services/embedding-provider.js.map +1 -0
  463. package/dist/src/services/four-stage-learning.d.ts +552 -0
  464. package/dist/src/services/four-stage-learning.d.ts.map +1 -0
  465. package/dist/src/services/four-stage-learning.js +1110 -0
  466. package/dist/src/services/four-stage-learning.js.map +1 -0
  467. package/dist/src/services/index.d.ts +15 -0
  468. package/dist/src/services/index.d.ts.map +1 -0
  469. package/dist/src/services/index.js +18 -0
  470. package/dist/src/services/index.js.map +1 -0
  471. package/dist/src/services/ingestion.d.ts +98 -0
  472. package/dist/src/services/ingestion.d.ts.map +1 -0
  473. package/dist/src/services/ingestion.js +259 -0
  474. package/dist/src/services/ingestion.js.map +1 -0
  475. package/dist/src/services/query.d.ts +102 -0
  476. package/dist/src/services/query.d.ts.map +1 -0
  477. package/dist/src/services/query.js +227 -0
  478. package/dist/src/services/query.js.map +1 -0
  479. package/dist/src/services/text-embedding.d.ts +183 -0
  480. package/dist/src/services/text-embedding.d.ts.map +1 -0
  481. package/dist/src/services/text-embedding.js +633 -0
  482. package/dist/src/services/text-embedding.js.map +1 -0
  483. package/dist/src/services/verify.d.ts +114 -0
  484. package/dist/src/services/verify.d.ts.map +1 -0
  485. package/dist/src/services/verify.js +237 -0
  486. package/dist/src/services/verify.js.map +1 -0
  487. package/dist/src/storage/chunk-store.d.ts +107 -0
  488. package/dist/src/storage/chunk-store.d.ts.map +1 -0
  489. package/dist/src/storage/chunk-store.js +293 -0
  490. package/dist/src/storage/chunk-store.js.map +1 -0
  491. package/dist/src/storage/index-store.d.ts +126 -0
  492. package/dist/src/storage/index-store.d.ts.map +1 -0
  493. package/dist/src/storage/index-store.js +316 -0
  494. package/dist/src/storage/index-store.js.map +1 -0
  495. package/dist/src/storage/index.d.ts +45 -0
  496. package/dist/src/storage/index.d.ts.map +1 -0
  497. package/dist/src/storage/index.js +52 -0
  498. package/dist/src/storage/index.js.map +1 -0
  499. package/dist/src/storage/neuron-store.d.ts +121 -0
  500. package/dist/src/storage/neuron-store.d.ts.map +1 -0
  501. package/dist/src/storage/neuron-store.js +466 -0
  502. package/dist/src/storage/neuron-store.js.map +1 -0
  503. package/dist/src/storage/probabilistic-store.d.ts +104 -0
  504. package/dist/src/storage/probabilistic-store.d.ts.map +1 -0
  505. package/dist/src/storage/probabilistic-store.js +257 -0
  506. package/dist/src/storage/probabilistic-store.js.map +1 -0
  507. package/dist/src/sync/change-journal.d.ts +171 -0
  508. package/dist/src/sync/change-journal.d.ts.map +1 -0
  509. package/dist/src/sync/change-journal.js +362 -0
  510. package/dist/src/sync/change-journal.js.map +1 -0
  511. package/dist/src/sync/index.d.ts +8 -0
  512. package/dist/src/sync/index.d.ts.map +1 -0
  513. package/dist/src/sync/index.js +8 -0
  514. package/dist/src/sync/index.js.map +1 -0
  515. package/dist/src/sync/state-sync.d.ts +241 -0
  516. package/dist/src/sync/state-sync.d.ts.map +1 -0
  517. package/dist/src/sync/state-sync.js +396 -0
  518. package/dist/src/sync/state-sync.js.map +1 -0
  519. package/dist/src/sync/vector-clock.d.ts +144 -0
  520. package/dist/src/sync/vector-clock.d.ts.map +1 -0
  521. package/dist/src/sync/vector-clock.js +266 -0
  522. package/dist/src/sync/vector-clock.js.map +1 -0
  523. package/dist/src/types/index.d.ts +224 -0
  524. package/dist/src/types/index.d.ts.map +1 -0
  525. package/dist/src/types/index.js +24 -0
  526. package/dist/src/types/index.js.map +1 -0
  527. package/dist/src/utils/hash.d.ts +39 -0
  528. package/dist/src/utils/hash.d.ts.map +1 -0
  529. package/dist/src/utils/hash.js +56 -0
  530. package/dist/src/utils/hash.js.map +1 -0
  531. package/dist/src/utils/index.d.ts +26 -0
  532. package/dist/src/utils/index.d.ts.map +1 -0
  533. package/dist/src/utils/index.js +50 -0
  534. package/dist/src/utils/index.js.map +1 -0
  535. package/dist/src/utils/logger.d.ts +88 -0
  536. package/dist/src/utils/logger.d.ts.map +1 -0
  537. package/dist/src/utils/logger.js +157 -0
  538. package/dist/src/utils/logger.js.map +1 -0
  539. package/dist/src/utils/metrics.d.ts +232 -0
  540. package/dist/src/utils/metrics.d.ts.map +1 -0
  541. package/dist/src/utils/metrics.js +387 -0
  542. package/dist/src/utils/metrics.js.map +1 -0
  543. package/dist/src/utils/similarity.d.ts +64 -0
  544. package/dist/src/utils/similarity.d.ts.map +1 -0
  545. package/dist/src/utils/similarity.js +151 -0
  546. package/dist/src/utils/similarity.js.map +1 -0
  547. package/dist/src/utils/uuid.d.ts +23 -0
  548. package/dist/src/utils/uuid.d.ts.map +1 -0
  549. package/dist/src/utils/uuid.js +29 -0
  550. package/dist/src/utils/uuid.js.map +1 -0
  551. package/dist/storage/chunk-store.d.ts +107 -0
  552. package/dist/storage/chunk-store.d.ts.map +1 -0
  553. package/dist/storage/chunk-store.js +293 -0
  554. package/dist/storage/chunk-store.js.map +1 -0
  555. package/dist/storage/hybrid-adapters.d.ts +111 -0
  556. package/dist/storage/hybrid-adapters.d.ts.map +1 -0
  557. package/dist/storage/hybrid-adapters.js +223 -0
  558. package/dist/storage/hybrid-adapters.js.map +1 -0
  559. package/dist/storage/hybrid-store.d.ts +125 -0
  560. package/dist/storage/hybrid-store.d.ts.map +1 -0
  561. package/dist/storage/hybrid-store.js +655 -0
  562. package/dist/storage/hybrid-store.js.map +1 -0
  563. package/dist/storage/index-store.d.ts +126 -0
  564. package/dist/storage/index-store.d.ts.map +1 -0
  565. package/dist/storage/index-store.js +316 -0
  566. package/dist/storage/index-store.js.map +1 -0
  567. package/dist/storage/index.d.ts +45 -0
  568. package/dist/storage/index.d.ts.map +1 -0
  569. package/dist/storage/index.js +52 -0
  570. package/dist/storage/index.js.map +1 -0
  571. package/dist/storage/neuron-store.d.ts +121 -0
  572. package/dist/storage/neuron-store.d.ts.map +1 -0
  573. package/dist/storage/neuron-store.js +466 -0
  574. package/dist/storage/neuron-store.js.map +1 -0
  575. package/dist/storage/ontology-store.d.ts +132 -0
  576. package/dist/storage/ontology-store.d.ts.map +1 -0
  577. package/dist/storage/ontology-store.js +319 -0
  578. package/dist/storage/ontology-store.js.map +1 -0
  579. package/dist/storage/probabilistic-store.d.ts +104 -0
  580. package/dist/storage/probabilistic-store.d.ts.map +1 -0
  581. package/dist/storage/probabilistic-store.js +257 -0
  582. package/dist/storage/probabilistic-store.js.map +1 -0
  583. package/dist/storage/redis-adapters.d.ts +102 -0
  584. package/dist/storage/redis-adapters.d.ts.map +1 -0
  585. package/dist/storage/redis-adapters.js +205 -0
  586. package/dist/storage/redis-adapters.js.map +1 -0
  587. package/dist/storage/redis-ontology-store.d.ts +146 -0
  588. package/dist/storage/redis-ontology-store.d.ts.map +1 -0
  589. package/dist/storage/redis-ontology-store.js +384 -0
  590. package/dist/storage/redis-ontology-store.js.map +1 -0
  591. package/dist/storage/redis-store.d.ts +174 -0
  592. package/dist/storage/redis-store.d.ts.map +1 -0
  593. package/dist/storage/redis-store.js +506 -0
  594. package/dist/storage/redis-store.js.map +1 -0
  595. package/dist/sync/change-journal.d.ts +171 -0
  596. package/dist/sync/change-journal.d.ts.map +1 -0
  597. package/dist/sync/change-journal.js +362 -0
  598. package/dist/sync/change-journal.js.map +1 -0
  599. package/dist/sync/index.d.ts +8 -0
  600. package/dist/sync/index.d.ts.map +1 -0
  601. package/dist/sync/index.js +8 -0
  602. package/dist/sync/index.js.map +1 -0
  603. package/dist/sync/state-sync.d.ts +241 -0
  604. package/dist/sync/state-sync.d.ts.map +1 -0
  605. package/dist/sync/state-sync.js +396 -0
  606. package/dist/sync/state-sync.js.map +1 -0
  607. package/dist/sync/vector-clock.d.ts +144 -0
  608. package/dist/sync/vector-clock.d.ts.map +1 -0
  609. package/dist/sync/vector-clock.js +266 -0
  610. package/dist/sync/vector-clock.js.map +1 -0
  611. package/dist/types/index.d.ts +224 -0
  612. package/dist/types/index.d.ts.map +1 -0
  613. package/dist/types/index.js +24 -0
  614. package/dist/types/index.js.map +1 -0
  615. package/dist/utils/hash.d.ts +39 -0
  616. package/dist/utils/hash.d.ts.map +1 -0
  617. package/dist/utils/hash.js +56 -0
  618. package/dist/utils/hash.js.map +1 -0
  619. package/dist/utils/index.d.ts +26 -0
  620. package/dist/utils/index.d.ts.map +1 -0
  621. package/dist/utils/index.js +50 -0
  622. package/dist/utils/index.js.map +1 -0
  623. package/dist/utils/logger.d.ts +88 -0
  624. package/dist/utils/logger.d.ts.map +1 -0
  625. package/dist/utils/logger.js +157 -0
  626. package/dist/utils/logger.js.map +1 -0
  627. package/dist/utils/metrics.d.ts +232 -0
  628. package/dist/utils/metrics.d.ts.map +1 -0
  629. package/dist/utils/metrics.js +387 -0
  630. package/dist/utils/metrics.js.map +1 -0
  631. package/dist/utils/similarity.d.ts +64 -0
  632. package/dist/utils/similarity.d.ts.map +1 -0
  633. package/dist/utils/similarity.js +151 -0
  634. package/dist/utils/similarity.js.map +1 -0
  635. package/dist/utils/uuid.d.ts +23 -0
  636. package/dist/utils/uuid.d.ts.map +1 -0
  637. package/dist/utils/uuid.js +29 -0
  638. package/dist/utils/uuid.js.map +1 -0
  639. package/package.json +72 -0
@@ -0,0 +1,2011 @@
1
+ /**
2
+ * REST API Server
3
+ * @module api/server
4
+ */
5
+ import express from 'express';
6
+ import cors from 'cors';
7
+ import fs from 'fs';
8
+ import multer from 'multer';
9
+ import { fileIngestion } from '../services/file-ingestion.js';
10
+ import { llmService } from '../services/llm.js';
11
+ import { validateIngestBody, validateSearchBody, validateBatchIngestBody, validateUUIDParam, validateSynapseBody, validateLLMConfig, } from './middleware/validation.js';
12
+ import { rateLimiters } from './middleware/rate-limit.js';
13
+ import { logger, requestLogger, errorLogger } from './middleware/logger.js';
14
+ import { ChunkEngine } from '../core/chunk-engine.js';
15
+ import { MerkleEngine } from '../core/merkle-engine.js';
16
+ import { HNSWIndex } from '../core/hnsw-index.js';
17
+ import { NeuronGraphManager } from '../core/neuron-graph.js';
18
+ import { ChunkStore, NeuronStore, IndexStore } from '../storage/redis-adapters.js';
19
+ import { IngestionService } from '../services/ingestion.js';
20
+ import { QueryService } from '../services/query.js';
21
+ import { VerificationService } from '../services/verify.js';
22
+ import { GraphService } from '../services/graph.js';
23
+ import { ClusteringService } from '../extensions/clustering/index.js';
24
+ import { TopicModelingService } from '../extensions/clustering/topic-modeling.js';
25
+ import { CommunityDetectionService } from '../extensions/clustering/community-detection.js';
26
+ import { SemanticChunker, createSemanticSynapses } from '../core/semantic-chunker.js';
27
+ import { HierarchicalChunker } from '../core/hierarchical-chunker.js';
28
+ import { multiLangTokenizer, detectLanguage } from '../core/language-analyzers.js';
29
+ import { RedisOntologyStore } from '../storage/redis-ontology-store.js';
30
+ import { DynamicLearningService } from '../services/learning.js';
31
+ import { AutoLearningService } from '../services/auto-learning.js';
32
+ import { WebSearchService } from '../services/web-search.js';
33
+ import { localEmbedding } from '../core/local-embedding.js';
34
+ import { advancedEmbedding } from '../core/advanced-embedding.js';
35
+ import { MultiLayerReasoningEngine } from '../core/multi-layer-reasoning.js';
36
+ import { embeddingSimilarity, calculateSimilarity, findSynonyms as findEmbeddingSynonyms } from '../core/embedding-similarity.js';
37
+ import path from 'path';
38
+ import { fileURLToPath } from 'url';
39
+ const __filename = fileURLToPath(import.meta.url);
40
+ const __dirname = path.dirname(__filename);
41
+ /**
42
+ * NMT API Server
43
+ */
44
+ export class NMTServer {
45
+ app;
46
+ port;
47
+ dataDir;
48
+ // Core components
49
+ chunkEngine;
50
+ merkleEngine;
51
+ hnswIndex;
52
+ // Storage (Redis-based adapters)
53
+ chunkStore;
54
+ neuronStore;
55
+ indexStore;
56
+ // Services
57
+ graphManager;
58
+ ingestionService;
59
+ queryService;
60
+ verifyService;
61
+ graphService;
62
+ clusteringService;
63
+ topicModeling;
64
+ communityDetection;
65
+ semanticChunker;
66
+ hierarchicalChunker;
67
+ // Learning & Ontology (Redis-based)
68
+ ontologyStore;
69
+ learningService;
70
+ autoLearningService;
71
+ webSearchService;
72
+ localEmbeddingService;
73
+ advancedEmbeddingService;
74
+ reasoningEngine;
75
+ initialized = false;
76
+ constructor(options = {}) {
77
+ this.port = options.port ?? 3000;
78
+ this.dataDir = options.dataDir ?? './data';
79
+ this.app = express();
80
+ // Middleware
81
+ this.app.use(express.json({ limit: '10mb' }));
82
+ this.app.use(express.urlencoded({ extended: true }));
83
+ // CORS configuration - secure for production
84
+ const corsOrigins = options.corsOrigins ?? (process.env.NODE_ENV === 'production'
85
+ ? (process.env.CORS_ORIGINS?.split(',') || ['http://localhost:3000'])
86
+ : '*');
87
+ this.app.use(cors({
88
+ origin: corsOrigins,
89
+ methods: ['GET', 'POST', 'PUT', 'DELETE'],
90
+ allowedHeaders: ['Content-Type', 'Authorization'],
91
+ credentials: true,
92
+ }));
93
+ // Request logging
94
+ this.app.use(requestLogger);
95
+ // Global rate limiter
96
+ this.app.use('/api/', rateLimiters.general);
97
+ this.setupRoutes();
98
+ this.setupErrorHandling();
99
+ }
100
+ /**
101
+ * Initialize all components
102
+ */
103
+ async init() {
104
+ if (this.initialized)
105
+ return;
106
+ // Initialize core engines
107
+ this.chunkEngine = new ChunkEngine();
108
+ this.merkleEngine = new MerkleEngine();
109
+ this.hnswIndex = new HNSWIndex();
110
+ // Initialize storage
111
+ this.chunkStore = new ChunkStore({ dataDir: this.dataDir });
112
+ this.neuronStore = new NeuronStore({ dataDir: this.dataDir });
113
+ this.indexStore = new IndexStore({ dataDir: this.dataDir });
114
+ await this.chunkStore.init();
115
+ await this.neuronStore.init();
116
+ await this.indexStore.init();
117
+ // Try to load existing index
118
+ const existingIndex = await this.indexStore.load('main');
119
+ if (existingIndex) {
120
+ this.hnswIndex = existingIndex;
121
+ }
122
+ // Initialize graph manager
123
+ this.graphManager = new NeuronGraphManager({
124
+ neuronStore: this.neuronStore,
125
+ hnswIndex: this.hnswIndex
126
+ });
127
+ // Initialize services
128
+ this.ingestionService = new IngestionService(this.chunkEngine, this.merkleEngine, this.graphManager, this.chunkStore);
129
+ this.queryService = new QueryService(this.graphManager, this.merkleEngine, this.chunkStore, this.neuronStore);
130
+ this.verifyService = new VerificationService(this.merkleEngine, this.chunkStore, this.neuronStore);
131
+ this.graphService = new GraphService(this.graphManager, this.neuronStore);
132
+ // Initialize clustering extensions
133
+ this.clusteringService = new ClusteringService(this.neuronStore);
134
+ this.topicModeling = new TopicModelingService(this.neuronStore);
135
+ this.communityDetection = new CommunityDetectionService(this.neuronStore);
136
+ // Initialize chunkers
137
+ this.semanticChunker = new SemanticChunker();
138
+ this.hierarchicalChunker = new HierarchicalChunker();
139
+ // Initialize Redis-based ontology store
140
+ this.ontologyStore = new RedisOntologyStore({
141
+ host: process.env.REDIS_HOST || 'localhost',
142
+ port: parseInt(process.env.REDIS_PORT || '6379'),
143
+ password: process.env.REDIS_PASSWORD,
144
+ db: parseInt(process.env.REDIS_DB || '0'),
145
+ keyPrefix: 'nmt:'
146
+ });
147
+ await this.ontologyStore.init();
148
+ // Import default data if empty
149
+ const imported = await this.ontologyStore.importDefaultData();
150
+ if (imported > 0) {
151
+ console.log(`Imported ${imported} default semantic groups`);
152
+ }
153
+ this.learningService = new DynamicLearningService(this.ontologyStore);
154
+ // Initialize Local Embedding Service
155
+ this.localEmbeddingService = localEmbedding;
156
+ try {
157
+ await this.localEmbeddingService.init();
158
+ console.log('Local embedding model loaded');
159
+ }
160
+ catch (error) {
161
+ console.warn('Local embedding model failed to load, will use fallback:', error);
162
+ }
163
+ // Initialize Auto Learning Service
164
+ this.autoLearningService = new AutoLearningService(this.ontologyStore, this.localEmbeddingService);
165
+ await this.autoLearningService.init();
166
+ console.log('Auto Learning Service initialized');
167
+ // Initialize Web Search Service
168
+ this.webSearchService = new WebSearchService(this.ontologyStore, this.localEmbeddingService);
169
+ console.log('Web Search Service initialized');
170
+ // Initialize Advanced Embedding Service (bge-m3 1024d)
171
+ this.advancedEmbeddingService = advancedEmbedding;
172
+ // Note: bge-m3 loads in background, uses fallback initially
173
+ this.advancedEmbeddingService.init(true).then(() => {
174
+ console.log('Advanced embedding model (bge-m3) loaded');
175
+ }).catch(err => {
176
+ console.warn('Advanced embedding load deferred:', err.message);
177
+ });
178
+ // Initialize Multi-Layer Reasoning Engine
179
+ this.reasoningEngine = new MultiLayerReasoningEngine(this.ontologyStore, this.advancedEmbeddingService);
180
+ console.log('Multi-Layer Reasoning Engine initialized');
181
+ this.initialized = true;
182
+ }
183
+ /**
184
+ * Start the server
185
+ */
186
+ async start() {
187
+ await this.init();
188
+ return new Promise((resolve) => {
189
+ this.app.listen(this.port, () => {
190
+ console.log(`NMT Server running on http://localhost:${this.port}`);
191
+ resolve();
192
+ });
193
+ });
194
+ }
195
+ /**
196
+ * Stop the server and cleanup
197
+ */
198
+ async stop() {
199
+ // Save index
200
+ await this.indexStore.save('main', this.hnswIndex);
201
+ // Close storage
202
+ await this.chunkStore.close();
203
+ await this.neuronStore.close();
204
+ await this.indexStore.close();
205
+ await this.ontologyStore.close();
206
+ this.initialized = false;
207
+ }
208
+ /**
209
+ * Setup API routes
210
+ */
211
+ setupRoutes() {
212
+ const api = express.Router();
213
+ // Health check
214
+ api.get('/health', (req, res) => {
215
+ res.json({
216
+ status: 'healthy',
217
+ initialized: this.initialized,
218
+ timestamp: new Date().toISOString()
219
+ });
220
+ });
221
+ // ==================== Ingestion Routes ====================
222
+ // Ingest text
223
+ api.post('/ingest', rateLimiters.ingest, validateIngestBody, async (req, res, next) => {
224
+ try {
225
+ this.ensureInitialized();
226
+ const { text, sourceType, tags, useCDC, autoConnect } = req.body;
227
+ if (!text) {
228
+ res.status(400).json({ error: 'Text is required' });
229
+ return;
230
+ }
231
+ const neuron = await this.ingestionService.ingestText(text, {
232
+ sourceType,
233
+ tags,
234
+ useCDC,
235
+ autoConnect
236
+ });
237
+ res.status(201).json({
238
+ id: neuron.id,
239
+ merkleRoot: neuron.merkleRoot,
240
+ chunkCount: neuron.chunkHashes.length
241
+ });
242
+ }
243
+ catch (err) {
244
+ next(err);
245
+ }
246
+ });
247
+ // Batch ingest
248
+ api.post('/ingest/batch', rateLimiters.ingest, validateBatchIngestBody, async (req, res, next) => {
249
+ try {
250
+ this.ensureInitialized();
251
+ const { texts, sourceType, tags } = req.body;
252
+ if (!texts || !Array.isArray(texts)) {
253
+ res.status(400).json({ error: 'Texts array is required' });
254
+ return;
255
+ }
256
+ const neurons = await this.ingestionService.ingestBatch(texts, {
257
+ sourceType,
258
+ tags
259
+ });
260
+ res.status(201).json({
261
+ count: neurons.length,
262
+ neurons: neurons.map(n => ({
263
+ id: n.id,
264
+ merkleRoot: n.merkleRoot
265
+ }))
266
+ });
267
+ }
268
+ catch (err) {
269
+ next(err);
270
+ }
271
+ });
272
+ // Get job status
273
+ api.get('/ingest/jobs/:jobId', (req, res) => {
274
+ this.ensureInitialized();
275
+ const job = this.ingestionService.getJobStatus(req.params.jobId);
276
+ if (!job) {
277
+ res.status(404).json({ error: 'Job not found' });
278
+ return;
279
+ }
280
+ res.json(job);
281
+ });
282
+ // ==================== Query Routes ====================
283
+ // Search by text
284
+ api.post('/search', rateLimiters.search, validateSearchBody, async (req, res, next) => {
285
+ try {
286
+ this.ensureInitialized();
287
+ const { query, k, threshold, includeContent, includeProof, tags, sourceType } = req.body;
288
+ if (!query) {
289
+ res.status(400).json({ error: 'Query is required' });
290
+ return;
291
+ }
292
+ const results = await this.queryService.search(query, {
293
+ k,
294
+ threshold,
295
+ includeContent,
296
+ includeProof,
297
+ tags,
298
+ sourceType
299
+ });
300
+ // Auto-learn from query (non-blocking)
301
+ this.autoLearningService.learnFromQuery(query, results.map(r => ({
302
+ id: r.neuron.id,
303
+ content: r.content,
304
+ score: r.score
305
+ }))).catch(err => console.error('Auto-learn error:', err));
306
+ res.json({
307
+ count: results.length,
308
+ results: results.map(r => ({
309
+ id: r.neuron.id,
310
+ score: r.score,
311
+ merkleRoot: r.neuron.merkleRoot,
312
+ tags: r.neuron.metadata.tags,
313
+ content: r.content,
314
+ proof: r.proof
315
+ }))
316
+ });
317
+ }
318
+ catch (err) {
319
+ next(err);
320
+ }
321
+ });
322
+ // Search similar to neuron
323
+ api.get('/search/similar/:neuronId', async (req, res, next) => {
324
+ try {
325
+ this.ensureInitialized();
326
+ const { neuronId } = req.params;
327
+ const k = parseInt(req.query.k) || 10;
328
+ const results = await this.queryService.searchSimilarTo(neuronId, { k });
329
+ res.json({
330
+ count: results.length,
331
+ results: results.map(r => ({
332
+ id: r.neuron.id,
333
+ score: r.score,
334
+ merkleRoot: r.neuron.merkleRoot
335
+ }))
336
+ });
337
+ }
338
+ catch (err) {
339
+ next(err);
340
+ }
341
+ });
342
+ // ==================== Neuron Routes ====================
343
+ // Get neuron by ID
344
+ api.get('/neurons/:id', validateUUIDParam('id'), async (req, res, next) => {
345
+ try {
346
+ this.ensureInitialized();
347
+ const id = Array.isArray(req.params.id) ? req.params.id[0] : req.params.id;
348
+ const neuron = await this.queryService.getNeuron(id);
349
+ if (!neuron) {
350
+ res.status(404).json({ error: 'Neuron not found' });
351
+ return;
352
+ }
353
+ res.json({
354
+ id: neuron.id,
355
+ merkleRoot: neuron.merkleRoot,
356
+ chunkCount: neuron.chunkHashes.length,
357
+ metadata: neuron.metadata,
358
+ synapses: {
359
+ outgoing: neuron.outgoingSynapses.length,
360
+ incoming: neuron.incomingSynapses.length
361
+ }
362
+ });
363
+ }
364
+ catch (err) {
365
+ next(err);
366
+ }
367
+ });
368
+ // Get neuron content
369
+ api.get('/neurons/:id/content', async (req, res, next) => {
370
+ try {
371
+ this.ensureInitialized();
372
+ const neuron = await this.queryService.getNeuron(req.params.id);
373
+ if (!neuron) {
374
+ res.status(404).json({ error: 'Neuron not found' });
375
+ return;
376
+ }
377
+ const content = await this.queryService.getContent(neuron);
378
+ res.json({ id: neuron.id, content });
379
+ }
380
+ catch (err) {
381
+ next(err);
382
+ }
383
+ });
384
+ // Delete neuron
385
+ api.delete('/neurons/:id', async (req, res, next) => {
386
+ try {
387
+ this.ensureInitialized();
388
+ const deleted = await this.graphManager.deleteNeuron(req.params.id);
389
+ if (!deleted) {
390
+ res.status(404).json({ error: 'Neuron not found' });
391
+ return;
392
+ }
393
+ res.json({ deleted: true });
394
+ }
395
+ catch (err) {
396
+ next(err);
397
+ }
398
+ });
399
+ // Get neurons by tags
400
+ api.get('/neurons', async (req, res, next) => {
401
+ try {
402
+ this.ensureInitialized();
403
+ const tags = req.query.tags?.split(',');
404
+ const sourceType = req.query.sourceType;
405
+ let neurons;
406
+ if (tags) {
407
+ neurons = await this.queryService.getNeuronsByTags(tags);
408
+ }
409
+ else if (sourceType) {
410
+ neurons = await this.queryService.getNeuronsBySourceType(sourceType);
411
+ }
412
+ else {
413
+ neurons = await this.queryService.getRecentlyAccessed(100);
414
+ }
415
+ res.json({
416
+ count: neurons.length,
417
+ neurons: neurons.map(n => ({
418
+ id: n.id,
419
+ merkleRoot: n.merkleRoot,
420
+ tags: n.metadata.tags,
421
+ sourceType: n.metadata.sourceType
422
+ }))
423
+ });
424
+ }
425
+ catch (err) {
426
+ next(err);
427
+ }
428
+ });
429
+ // ==================== Synapse Routes ====================
430
+ // Create synapse
431
+ api.post('/synapses', validateSynapseBody, async (req, res, next) => {
432
+ try {
433
+ this.ensureInitialized();
434
+ const { sourceId, targetId, type, weight, bidirectional } = req.body;
435
+ if (!sourceId || !targetId || !type) {
436
+ res.status(400).json({ error: 'sourceId, targetId, and type are required' });
437
+ return;
438
+ }
439
+ const synapse = await this.graphManager.connect(sourceId, targetId, type, weight, bidirectional);
440
+ if (!synapse) {
441
+ res.status(400).json({ error: 'Failed to create synapse' });
442
+ return;
443
+ }
444
+ res.status(201).json({
445
+ id: synapse.id,
446
+ sourceId: synapse.sourceId,
447
+ targetId: synapse.targetId,
448
+ type: synapse.type,
449
+ weight: synapse.weight
450
+ });
451
+ }
452
+ catch (err) {
453
+ next(err);
454
+ }
455
+ });
456
+ // Delete synapse
457
+ api.delete('/synapses/:id', async (req, res, next) => {
458
+ try {
459
+ this.ensureInitialized();
460
+ const deleted = await this.graphManager.disconnect(req.params.id);
461
+ if (!deleted) {
462
+ res.status(404).json({ error: 'Synapse not found' });
463
+ return;
464
+ }
465
+ res.json({ deleted: true });
466
+ }
467
+ catch (err) {
468
+ next(err);
469
+ }
470
+ });
471
+ // ==================== Verification Routes ====================
472
+ // Verify neuron
473
+ api.get('/verify/:neuronId', async (req, res, next) => {
474
+ try {
475
+ this.ensureInitialized();
476
+ const result = await this.verifyService.verifyNeuron(req.params.neuronId);
477
+ res.json(result);
478
+ }
479
+ catch (err) {
480
+ next(err);
481
+ }
482
+ });
483
+ // Generate proof
484
+ api.get('/verify/:neuronId/proof/:chunkIndex', async (req, res, next) => {
485
+ try {
486
+ this.ensureInitialized();
487
+ const chunkIndex = parseInt(req.params.chunkIndex);
488
+ const result = await this.verifyService.generateAndVerifyProof(req.params.neuronId, chunkIndex, { verifyChunkData: true });
489
+ if (!result.proof) {
490
+ res.status(404).json({ error: 'Could not generate proof' });
491
+ return;
492
+ }
493
+ res.json({
494
+ proof: result.proof,
495
+ valid: result.valid,
496
+ chunkValid: result.chunkValid
497
+ });
498
+ }
499
+ catch (err) {
500
+ next(err);
501
+ }
502
+ });
503
+ // Verify all
504
+ api.get('/verify', async (req, res, next) => {
505
+ try {
506
+ this.ensureInitialized();
507
+ const result = await this.verifyService.verifyAll();
508
+ res.json(result);
509
+ }
510
+ catch (err) {
511
+ next(err);
512
+ }
513
+ });
514
+ // ==================== Graph Routes ====================
515
+ // Traverse graph
516
+ api.post('/graph/traverse', async (req, res, next) => {
517
+ try {
518
+ this.ensureInitialized();
519
+ const { startId, strategy, maxDepth } = req.body;
520
+ if (!startId) {
521
+ res.status(400).json({ error: 'startId is required' });
522
+ return;
523
+ }
524
+ const result = await this.graphService.traverse(startId, strategy, maxDepth);
525
+ res.json({
526
+ pathCount: result.paths.length,
527
+ visitedCount: result.visited.size,
528
+ totalWeight: result.totalWeight,
529
+ paths: result.paths.map(p => ({
530
+ neurons: p.neurons.map(n => n.id),
531
+ synapseCount: p.synapses.length,
532
+ weight: p.totalWeight
533
+ }))
534
+ });
535
+ }
536
+ catch (err) {
537
+ next(err);
538
+ }
539
+ });
540
+ // Find path
541
+ api.post('/graph/path', async (req, res, next) => {
542
+ try {
543
+ this.ensureInitialized();
544
+ const { sourceId, targetId, maxDepth } = req.body;
545
+ if (!sourceId || !targetId) {
546
+ res.status(400).json({ error: 'sourceId and targetId are required' });
547
+ return;
548
+ }
549
+ const path = await this.graphService.findPath(sourceId, targetId, { maxDepth });
550
+ if (!path) {
551
+ res.json({ found: false });
552
+ return;
553
+ }
554
+ res.json({
555
+ found: true,
556
+ path: {
557
+ neurons: path.neurons.map(n => n.id),
558
+ synapses: path.synapses.map(s => s.id),
559
+ weight: path.totalWeight
560
+ }
561
+ });
562
+ }
563
+ catch (err) {
564
+ next(err);
565
+ }
566
+ });
567
+ // Get subgraph
568
+ api.get('/graph/subgraph/:centerId', async (req, res, next) => {
569
+ try {
570
+ this.ensureInitialized();
571
+ const radius = parseInt(req.query.radius) || 2;
572
+ const result = await this.graphService.getSubgraph(req.params.centerId, radius);
573
+ res.json({
574
+ neuronCount: result.neurons.length,
575
+ synapseCount: result.synapses.length,
576
+ neurons: result.neurons.map(n => ({
577
+ id: n.id,
578
+ merkleRoot: n.merkleRoot
579
+ })),
580
+ synapses: result.synapses.map(s => ({
581
+ id: s.id,
582
+ source: s.sourceId,
583
+ target: s.targetId,
584
+ type: s.type,
585
+ weight: s.weight
586
+ }))
587
+ });
588
+ }
589
+ catch (err) {
590
+ next(err);
591
+ }
592
+ });
593
+ // Analyze graph
594
+ api.get('/graph/analyze', async (req, res, next) => {
595
+ try {
596
+ this.ensureInitialized();
597
+ const analysis = await this.graphService.analyze();
598
+ res.json(analysis);
599
+ }
600
+ catch (err) {
601
+ next(err);
602
+ }
603
+ });
604
+ // Get full graph data for visualization
605
+ api.get('/graph/full', async (req, res, next) => {
606
+ try {
607
+ this.ensureInitialized();
608
+ const limit = parseInt(req.query.limit) || 100;
609
+ // Get all neurons
610
+ const neuronIds = await this.neuronStore.getAllNeuronIds();
611
+ const neurons = [];
612
+ for (const id of neuronIds.slice(0, limit)) {
613
+ const neuron = await this.neuronStore.getNeuron(id);
614
+ if (neuron) {
615
+ neurons.push({
616
+ id: neuron.id,
617
+ merkleRoot: neuron.merkleRoot,
618
+ tags: neuron.metadata.tags || [],
619
+ accessCount: neuron.metadata.accessCount || 0,
620
+ });
621
+ }
622
+ }
623
+ // Get all synapses for these neurons
624
+ const synapses = [];
625
+ const neuronIdSet = new Set(neurons.map(n => n.id));
626
+ for (const neuron of neurons) {
627
+ const outgoing = await this.neuronStore.getOutgoingSynapses(neuron.id);
628
+ for (const synapse of outgoing) {
629
+ if (neuronIdSet.has(synapse.targetId)) {
630
+ synapses.push({
631
+ id: synapse.id,
632
+ source: synapse.sourceId,
633
+ target: synapse.targetId,
634
+ type: synapse.type,
635
+ weight: synapse.weight,
636
+ });
637
+ }
638
+ }
639
+ }
640
+ res.json({
641
+ nodes: neurons,
642
+ links: synapses,
643
+ totalNeurons: neuronIds.length,
644
+ totalDisplayed: neurons.length,
645
+ });
646
+ }
647
+ catch (err) {
648
+ next(err);
649
+ }
650
+ });
651
+ // ==================== Clustering Routes ====================
652
+ // K-means clustering
653
+ api.post('/clusters/kmeans', async (req, res, next) => {
654
+ try {
655
+ this.ensureInitialized();
656
+ const { k, maxIterations, tolerance, initMethod } = req.body;
657
+ if (!k || k < 2) {
658
+ res.status(400).json({ error: 'k must be at least 2' });
659
+ return;
660
+ }
661
+ const result = await this.clusteringService.kmeans({
662
+ k,
663
+ maxIterations,
664
+ tolerance,
665
+ initMethod
666
+ });
667
+ res.json({
668
+ clusterCount: result.clusters.length,
669
+ iterations: result.iterations,
670
+ silhouetteScore: result.silhouetteScore,
671
+ clusters: result.clusters.map(c => ({
672
+ id: c.id,
673
+ memberCount: c.members.length,
674
+ avgSimilarity: c.avgSimilarity
675
+ }))
676
+ });
677
+ }
678
+ catch (err) {
679
+ next(err);
680
+ }
681
+ });
682
+ // DBSCAN clustering
683
+ api.post('/clusters/dbscan', async (req, res, next) => {
684
+ try {
685
+ this.ensureInitialized();
686
+ const { eps = 0.3, minPts = 3 } = req.body;
687
+ const result = await this.clusteringService.dbscan({ eps, minPts });
688
+ res.json({
689
+ clusterCount: result.clusters.length,
690
+ noiseCount: result.noise?.length || 0,
691
+ clusters: result.clusters.map(c => ({
692
+ id: c.id,
693
+ memberCount: c.members.length,
694
+ avgSimilarity: c.avgSimilarity
695
+ })),
696
+ noise: result.noise
697
+ });
698
+ }
699
+ catch (err) {
700
+ next(err);
701
+ }
702
+ });
703
+ // Hierarchical clustering
704
+ api.post('/clusters/hierarchical', async (req, res, next) => {
705
+ try {
706
+ this.ensureInitialized();
707
+ const { targetClusters = 5, linkage = 'average' } = req.body;
708
+ const result = await this.clusteringService.hierarchical(targetClusters, linkage);
709
+ res.json({
710
+ clusterCount: result.clusters.length,
711
+ clusters: result.clusters.map(c => ({
712
+ id: c.id,
713
+ memberCount: c.members.length,
714
+ avgSimilarity: c.avgSimilarity
715
+ }))
716
+ });
717
+ }
718
+ catch (err) {
719
+ next(err);
720
+ }
721
+ });
722
+ // Get all clusters
723
+ api.get('/clusters', (req, res) => {
724
+ this.ensureInitialized();
725
+ const clusters = this.clusteringService.getAllClusters();
726
+ res.json({
727
+ count: clusters.length,
728
+ clusters: clusters.map(c => ({
729
+ id: c.id,
730
+ name: c.name,
731
+ memberCount: c.members.length,
732
+ avgSimilarity: c.avgSimilarity,
733
+ algorithm: c.metadata.algorithmUsed
734
+ }))
735
+ });
736
+ });
737
+ // Get cluster by ID
738
+ api.get('/clusters/:id', (req, res) => {
739
+ this.ensureInitialized();
740
+ const cluster = this.clusteringService.getCluster(req.params.id);
741
+ if (!cluster) {
742
+ res.status(404).json({ error: 'Cluster not found' });
743
+ return;
744
+ }
745
+ res.json(cluster);
746
+ });
747
+ // Get cluster stats
748
+ api.get('/clusters/stats/summary', (req, res) => {
749
+ this.ensureInitialized();
750
+ const stats = this.clusteringService.getStats();
751
+ res.json(stats);
752
+ });
753
+ // Topic modeling
754
+ api.post('/topics/extract', async (req, res, next) => {
755
+ try {
756
+ this.ensureInitialized();
757
+ const { numTopics = 10, topTermsPerTopic = 10 } = req.body;
758
+ const result = await this.topicModeling.extractTopics({
759
+ numTopics,
760
+ topTermsPerTopic
761
+ });
762
+ res.json(result);
763
+ }
764
+ catch (err) {
765
+ next(err);
766
+ }
767
+ });
768
+ // Community detection - Louvain
769
+ api.post('/communities/louvain', async (req, res, next) => {
770
+ try {
771
+ this.ensureInitialized();
772
+ const { resolution = 1.0, minCommunitySize = 2 } = req.body;
773
+ const result = await this.communityDetection.louvain({
774
+ resolution,
775
+ minCommunitySize
776
+ });
777
+ res.json({
778
+ communityCount: result.communities.length,
779
+ modularity: result.modularity,
780
+ coverage: result.coverage,
781
+ communities: result.communities.map(c => ({
782
+ id: c.id,
783
+ memberCount: c.members.length,
784
+ modularity: c.modularity,
785
+ density: c.density
786
+ }))
787
+ });
788
+ }
789
+ catch (err) {
790
+ next(err);
791
+ }
792
+ });
793
+ // Community detection - Label Propagation
794
+ api.post('/communities/label-propagation', async (req, res, next) => {
795
+ try {
796
+ this.ensureInitialized();
797
+ const { maxIterations = 100, minCommunitySize = 2 } = req.body;
798
+ const result = await this.communityDetection.labelPropagation({
799
+ maxIterations,
800
+ minCommunitySize
801
+ });
802
+ res.json({
803
+ communityCount: result.communities.length,
804
+ modularity: result.modularity,
805
+ coverage: result.coverage,
806
+ communities: result.communities.map(c => ({
807
+ id: c.id,
808
+ memberCount: c.members.length,
809
+ density: c.density
810
+ }))
811
+ });
812
+ }
813
+ catch (err) {
814
+ next(err);
815
+ }
816
+ });
817
+ // ==================== Stats Routes ====================
818
+ api.get('/stats', async (req, res, next) => {
819
+ try {
820
+ this.ensureInitialized();
821
+ const graphStats = await this.graphManager.getStats();
822
+ const chunkStats = await this.chunkStore.getStats();
823
+ res.json({
824
+ neurons: graphStats.neuronCount,
825
+ synapses: graphStats.synapseCount,
826
+ chunks: chunkStats.totalChunks,
827
+ totalChunkSize: chunkStats.totalSize,
828
+ indexNodes: graphStats.indexStats.totalNodes,
829
+ indexMaxLayer: graphStats.indexStats.maxLayer
830
+ });
831
+ }
832
+ catch (err) {
833
+ next(err);
834
+ }
835
+ });
836
+ // ==================== Config Routes ====================
837
+ // Get current configuration
838
+ api.get('/config', (_req, res) => {
839
+ res.json({
840
+ hnsw: {
841
+ M: 16,
842
+ efConstruction: 200,
843
+ efSearch: 50
844
+ },
845
+ storage: {
846
+ dataDir: this.dataDir,
847
+ chunkSize: 4096,
848
+ chunkingMode: 'fixed'
849
+ },
850
+ connection: {
851
+ semanticThreshold: 0.7,
852
+ maxConnections: 20,
853
+ autoConnect: true
854
+ },
855
+ verification: {
856
+ verifyOnRead: true,
857
+ autoProof: true,
858
+ periodicCheck: false
859
+ }
860
+ });
861
+ });
862
+ // Update configuration (placeholder - some settings require restart)
863
+ api.put('/config', async (req, res, next) => {
864
+ try {
865
+ // For now, just acknowledge the update
866
+ // In a real implementation, we'd persist these settings and apply them
867
+ const config = req.body;
868
+ console.log('Config update requested:', config);
869
+ res.json({
870
+ success: true,
871
+ message: 'Configuration updated (note: some settings require restart)'
872
+ });
873
+ }
874
+ catch (err) {
875
+ next(err);
876
+ }
877
+ });
878
+ // ==================== File Upload Routes ====================
879
+ // Configure multer for file uploads
880
+ const upload = multer({
881
+ storage: multer.memoryStorage(),
882
+ limits: { fileSize: 50 * 1024 * 1024 }, // 50MB limit
883
+ fileFilter: (_req, file, cb) => {
884
+ const allowedTypes = [
885
+ 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', // xlsx
886
+ 'application/vnd.ms-excel', // xls
887
+ 'text/csv',
888
+ 'application/csv',
889
+ ];
890
+ const allowedExts = ['.xlsx', '.xls', '.csv'];
891
+ const ext = file.originalname.toLowerCase().slice(file.originalname.lastIndexOf('.'));
892
+ if (allowedTypes.includes(file.mimetype) || allowedExts.includes(ext)) {
893
+ cb(null, true);
894
+ }
895
+ else {
896
+ cb(new Error(`Unsupported file type: ${file.mimetype}`));
897
+ }
898
+ },
899
+ });
900
+ // Upload and preview file
901
+ api.post('/files/preview', upload.single('file'), async (req, res, next) => {
902
+ try {
903
+ this.ensureInitialized();
904
+ if (!req.file) {
905
+ res.status(400).json({ error: 'No file uploaded' });
906
+ return;
907
+ }
908
+ const maxRows = parseInt(req.body.maxRows) || 10;
909
+ const preview = fileIngestion.previewFile(req.file.buffer, req.file.originalname, maxRows);
910
+ res.json({
911
+ fileName: req.file.originalname,
912
+ fileSize: req.file.size,
913
+ fileType: preview.fileType,
914
+ sheetName: preview.sheetName,
915
+ headers: preview.headers,
916
+ totalRows: preview.totalRows,
917
+ previewRows: preview.rows.map(r => ({
918
+ rowIndex: r.rowIndex,
919
+ data: r.data,
920
+ textPreview: r.text.slice(0, 200),
921
+ })),
922
+ });
923
+ }
924
+ catch (err) {
925
+ next(err);
926
+ }
927
+ });
928
+ // Get sheet names from Excel file
929
+ api.post('/files/sheets', upload.single('file'), async (req, res, next) => {
930
+ try {
931
+ if (!req.file) {
932
+ res.status(400).json({ error: 'No file uploaded' });
933
+ return;
934
+ }
935
+ const sheets = fileIngestion.getSheetNames(req.file.buffer);
936
+ res.json({ sheets });
937
+ }
938
+ catch (err) {
939
+ next(err);
940
+ }
941
+ });
942
+ // Upload and ingest file
943
+ api.post('/files/ingest', rateLimiters.upload, upload.single('file'), async (req, res, next) => {
944
+ try {
945
+ this.ensureInitialized();
946
+ if (!req.file) {
947
+ res.status(400).json({ error: 'No file uploaded' });
948
+ return;
949
+ }
950
+ const options = {
951
+ headerRow: req.body.headerRow ? parseInt(req.body.headerRow) : undefined,
952
+ startRow: req.body.startRow ? parseInt(req.body.startRow) : undefined,
953
+ sheetName: req.body.sheetName,
954
+ sheetIndex: req.body.sheetIndex ? parseInt(req.body.sheetIndex) : undefined,
955
+ columns: req.body.columns ? JSON.parse(req.body.columns) : undefined,
956
+ excludeColumns: req.body.excludeColumns ? JSON.parse(req.body.excludeColumns) : undefined,
957
+ textTemplate: req.body.textTemplate,
958
+ sourceType: req.body.sourceType || 'file-upload',
959
+ tags: req.body.tags ? JSON.parse(req.body.tags) : [req.file.originalname],
960
+ maxRows: req.body.maxRows ? parseInt(req.body.maxRows) : undefined,
961
+ };
962
+ const parsed = fileIngestion.parseFile(req.file.buffer, req.file.originalname, options);
963
+ // Create neurons for each row
964
+ const neurons = [];
965
+ const errors = [];
966
+ for (const row of parsed.rows) {
967
+ try {
968
+ const neuron = await this.ingestionService.ingestText(row.text, {
969
+ sourceType: options.sourceType,
970
+ tags: [...(options.tags || []), `row-${row.rowIndex}`],
971
+ });
972
+ neurons.push({
973
+ id: neuron.id,
974
+ rowIndex: row.rowIndex,
975
+ preview: row.text.slice(0, 100),
976
+ });
977
+ }
978
+ catch (err) {
979
+ errors.push(`Row ${row.rowIndex}: ${err.message}`);
980
+ }
981
+ }
982
+ res.json({
983
+ fileName: req.file.originalname,
984
+ fileType: parsed.fileType,
985
+ totalRows: parsed.totalRows,
986
+ neuronsCreated: neurons.length,
987
+ neurons,
988
+ errors,
989
+ });
990
+ }
991
+ catch (err) {
992
+ next(err);
993
+ }
994
+ });
995
+ // ==================== LLM Routes ====================
996
+ // Configure LLM
997
+ api.post('/llm/configure', rateLimiters.config, validateLLMConfig, (req, res, next) => {
998
+ try {
999
+ const { provider, apiKey, model, maxTokens, temperature } = req.body;
1000
+ if (!provider || !apiKey) {
1001
+ res.status(400).json({ error: 'provider and apiKey are required' });
1002
+ return;
1003
+ }
1004
+ const validProviders = ['openai', 'huggingface', 'grok'];
1005
+ if (!validProviders.includes(provider)) {
1006
+ res.status(400).json({
1007
+ error: `Invalid provider. Must be one of: ${validProviders.join(', ')}`
1008
+ });
1009
+ return;
1010
+ }
1011
+ llmService.configure({
1012
+ provider,
1013
+ apiKey,
1014
+ model,
1015
+ maxTokens,
1016
+ temperature,
1017
+ });
1018
+ res.json({
1019
+ success: true,
1020
+ message: `LLM configured with ${provider}`,
1021
+ config: llmService.getConfig(),
1022
+ });
1023
+ }
1024
+ catch (err) {
1025
+ next(err);
1026
+ }
1027
+ });
1028
+ // Get LLM config (without API key)
1029
+ api.get('/llm/config', (_req, res) => {
1030
+ const config = llmService.getConfig();
1031
+ res.json({
1032
+ configured: llmService.isConfigured(),
1033
+ config,
1034
+ });
1035
+ });
1036
+ // Get available models for a provider
1037
+ api.get('/llm/models/:provider', (req, res) => {
1038
+ const provider = req.params.provider;
1039
+ const models = llmService.getAvailableModels(provider);
1040
+ res.json({ provider, models });
1041
+ });
1042
+ // Simple chat completion
1043
+ api.post('/llm/chat', rateLimiters.llm, async (req, res, next) => {
1044
+ try {
1045
+ const { messages, provider, apiKey, model, maxTokens, temperature } = req.body;
1046
+ if (!messages || !Array.isArray(messages)) {
1047
+ res.status(400).json({ error: 'messages array is required' });
1048
+ return;
1049
+ }
1050
+ // Allow per-request config override
1051
+ const config = apiKey ? { provider, apiKey, model, maxTokens, temperature } : undefined;
1052
+ const response = await llmService.chat(messages, config);
1053
+ res.json(response);
1054
+ }
1055
+ catch (err) {
1056
+ next(err);
1057
+ }
1058
+ });
1059
+ // RAG query - search + LLM
1060
+ api.post('/rag/query', rateLimiters.llm, async (req, res, next) => {
1061
+ try {
1062
+ this.ensureInitialized();
1063
+ const { query, k = 5, threshold = 0.3, systemPrompt, maxContextLength, provider, apiKey, model } = req.body;
1064
+ if (!query) {
1065
+ res.status(400).json({ error: 'query is required' });
1066
+ return;
1067
+ }
1068
+ // Check if LLM is configured
1069
+ const config = apiKey ? { provider, apiKey, model } : undefined;
1070
+ if (!config && !llmService.isConfigured()) {
1071
+ res.status(400).json({
1072
+ error: 'LLM not configured. Please provide API key or configure LLM first.'
1073
+ });
1074
+ return;
1075
+ }
1076
+ // Step 1: Retrieve relevant contexts
1077
+ const searchResults = await this.queryService.search(query, {
1078
+ k,
1079
+ threshold,
1080
+ includeContent: true,
1081
+ });
1082
+ const contexts = searchResults.map(r => ({
1083
+ id: r.neuron.id,
1084
+ content: r.content || '',
1085
+ score: r.score,
1086
+ metadata: {
1087
+ tags: r.neuron.metadata.tags,
1088
+ sourceType: r.neuron.metadata.sourceType,
1089
+ },
1090
+ }));
1091
+ // Step 2: Generate response with LLM
1092
+ const llmResponse = await llmService.ragQuery({
1093
+ query,
1094
+ contexts,
1095
+ systemPrompt,
1096
+ maxContextLength,
1097
+ }, config);
1098
+ res.json({
1099
+ query,
1100
+ answer: llmResponse.content,
1101
+ contexts: contexts.map(c => ({
1102
+ id: c.id,
1103
+ score: c.score,
1104
+ preview: c.content.slice(0, 200),
1105
+ metadata: c.metadata,
1106
+ })),
1107
+ llm: {
1108
+ model: llmResponse.model,
1109
+ provider: llmResponse.provider,
1110
+ usage: llmResponse.usage,
1111
+ processingTime: llmResponse.processingTime,
1112
+ },
1113
+ });
1114
+ }
1115
+ catch (err) {
1116
+ next(err);
1117
+ }
1118
+ });
1119
+ // ==================== Semantic Chunking Routes ====================
1120
+ // Semantic chunk - build semantic tree
1121
+ api.post('/semantic/chunk', (req, res, next) => {
1122
+ try {
1123
+ this.ensureInitialized();
1124
+ const { text, addConcepts } = req.body;
1125
+ if (!text) {
1126
+ res.status(400).json({ error: 'Text is required' });
1127
+ return;
1128
+ }
1129
+ // Add custom concepts if provided
1130
+ if (addConcepts && Array.isArray(addConcepts)) {
1131
+ for (const c of addConcepts) {
1132
+ if (c.concept && c.parents) {
1133
+ this.semanticChunker.addConcept(c.concept, c.parents, c.type || 'is-a');
1134
+ }
1135
+ }
1136
+ }
1137
+ const tree = this.semanticChunker.chunk(text);
1138
+ const synapses = createSemanticSynapses(tree);
1139
+ // Build visualization
1140
+ const visualization = this.semanticChunker.visualize(tree);
1141
+ res.json({
1142
+ concepts: tree.nodes.size,
1143
+ roots: tree.roots.map(r => r.concept),
1144
+ maxDepth: Math.max(...[...tree.byDepth.keys()]),
1145
+ synapses: synapses.length,
1146
+ tree: [...tree.nodes.values()].map(n => ({
1147
+ id: n.id,
1148
+ concept: n.concept,
1149
+ depth: n.depth,
1150
+ parentId: n.parentId,
1151
+ childIds: n.childIds,
1152
+ relations: n.relations.map(r => ({
1153
+ target: r.targetConcept,
1154
+ type: r.type,
1155
+ weight: r.weight
1156
+ }))
1157
+ })),
1158
+ visualization
1159
+ });
1160
+ }
1161
+ catch (err) {
1162
+ next(err);
1163
+ }
1164
+ });
1165
+ // Get semantic chain for a concept
1166
+ api.get('/semantic/chain/:concept', (req, res, next) => {
1167
+ try {
1168
+ this.ensureInitialized();
1169
+ const chain = this.semanticChunker.buildSemanticChain(req.params.concept);
1170
+ res.json({
1171
+ concept: req.params.concept,
1172
+ chain,
1173
+ depth: chain.length - 1
1174
+ });
1175
+ }
1176
+ catch (err) {
1177
+ next(err);
1178
+ }
1179
+ });
1180
+ // Find relation between two concepts
1181
+ api.get('/semantic/relation', (req, res, next) => {
1182
+ try {
1183
+ this.ensureInitialized();
1184
+ const { concept1, concept2 } = req.query;
1185
+ if (!concept1 || !concept2) {
1186
+ res.status(400).json({ error: 'concept1 and concept2 are required' });
1187
+ return;
1188
+ }
1189
+ const relation = this.semanticChunker.findRelation(concept1, concept2);
1190
+ res.json({
1191
+ concept1,
1192
+ concept2,
1193
+ relation: relation ? {
1194
+ type: relation.type,
1195
+ weight: relation.weight,
1196
+ bidirectional: relation.bidirectional
1197
+ } : null
1198
+ });
1199
+ }
1200
+ catch (err) {
1201
+ next(err);
1202
+ }
1203
+ });
1204
+ // Find descendants of a concept
1205
+ api.get('/semantic/descendants/:concept', (req, res, next) => {
1206
+ try {
1207
+ this.ensureInitialized();
1208
+ const descendants = this.semanticChunker.findDescendants(req.params.concept);
1209
+ res.json({
1210
+ concept: req.params.concept,
1211
+ descendants,
1212
+ count: descendants.length
1213
+ });
1214
+ }
1215
+ catch (err) {
1216
+ next(err);
1217
+ }
1218
+ });
1219
+ // Find ancestors of a concept
1220
+ api.get('/semantic/ancestors/:concept', (req, res, next) => {
1221
+ try {
1222
+ this.ensureInitialized();
1223
+ const ancestors = this.semanticChunker.findAncestors(req.params.concept);
1224
+ res.json({
1225
+ concept: req.params.concept,
1226
+ ancestors,
1227
+ count: ancestors.length
1228
+ });
1229
+ }
1230
+ catch (err) {
1231
+ next(err);
1232
+ }
1233
+ });
1234
+ // Find siblings of a concept
1235
+ api.get('/semantic/siblings/:concept', (req, res, next) => {
1236
+ try {
1237
+ this.ensureInitialized();
1238
+ const siblings = this.semanticChunker.findSiblings(req.params.concept);
1239
+ res.json({
1240
+ concept: req.params.concept,
1241
+ siblings,
1242
+ count: siblings.length
1243
+ });
1244
+ }
1245
+ catch (err) {
1246
+ next(err);
1247
+ }
1248
+ });
1249
+ // Get ontology stats
1250
+ api.get('/semantic/stats', (req, res, next) => {
1251
+ try {
1252
+ this.ensureInitialized();
1253
+ const stats = this.semanticChunker.getStats();
1254
+ res.json(stats);
1255
+ }
1256
+ catch (err) {
1257
+ next(err);
1258
+ }
1259
+ });
1260
+ // ==================== Learning & Ontology Routes ====================
1261
+ // Learn from text (auto-extract relations)
1262
+ api.post('/learning/text', async (req, res, next) => {
1263
+ try {
1264
+ this.ensureInitialized();
1265
+ const { text, source } = req.body;
1266
+ if (!text) {
1267
+ res.status(400).json({ error: 'Text is required' });
1268
+ return;
1269
+ }
1270
+ const results = await this.learningService.learnFromText(text, source || 'api');
1271
+ res.json({
1272
+ text: text.slice(0, 100) + (text.length > 100 ? '...' : ''),
1273
+ learned: results.filter(r => r.learned).length,
1274
+ results: results.map(r => ({
1275
+ learned: r.learned,
1276
+ type: r.type,
1277
+ concept1: r.concept1,
1278
+ concept2: r.concept2,
1279
+ confidence: r.confidence,
1280
+ message: r.message
1281
+ }))
1282
+ });
1283
+ }
1284
+ catch (err) {
1285
+ next(err);
1286
+ }
1287
+ });
1288
+ // Learn synonym explicitly
1289
+ api.post('/learning/synonym', async (req, res, next) => {
1290
+ try {
1291
+ this.ensureInitialized();
1292
+ const { word, synonym, source } = req.body;
1293
+ if (!word || !synonym) {
1294
+ res.status(400).json({ error: 'word and synonym are required' });
1295
+ return;
1296
+ }
1297
+ const result = await this.learningService.learnSynonym(word, synonym, source || 'api');
1298
+ res.json({
1299
+ learned: result.learned,
1300
+ word,
1301
+ synonym,
1302
+ message: result.message
1303
+ });
1304
+ }
1305
+ catch (err) {
1306
+ next(err);
1307
+ }
1308
+ });
1309
+ // Learn relation explicitly
1310
+ api.post('/learning/relation', async (req, res, next) => {
1311
+ try {
1312
+ this.ensureInitialized();
1313
+ const { concept1, concept2, type, source } = req.body;
1314
+ if (!concept1 || !concept2 || !type) {
1315
+ res.status(400).json({ error: 'concept1, concept2, and type are required' });
1316
+ return;
1317
+ }
1318
+ const validTypes = ['is-a', 'part-of', 'has-a', 'related-to'];
1319
+ if (!validTypes.includes(type)) {
1320
+ res.status(400).json({
1321
+ error: `Invalid type. Must be one of: ${validTypes.join(', ')}`
1322
+ });
1323
+ return;
1324
+ }
1325
+ const result = await this.learningService.learnRelation(concept1, concept2, type, source || 'api');
1326
+ res.json({
1327
+ learned: result.learned,
1328
+ concept1,
1329
+ concept2,
1330
+ type,
1331
+ message: result.message
1332
+ });
1333
+ }
1334
+ catch (err) {
1335
+ next(err);
1336
+ }
1337
+ });
1338
+ // Batch learn from conversation
1339
+ api.post('/learning/conversation', async (req, res, next) => {
1340
+ try {
1341
+ this.ensureInitialized();
1342
+ const { messages, source } = req.body;
1343
+ if (!messages || !Array.isArray(messages)) {
1344
+ res.status(400).json({ error: 'messages array is required' });
1345
+ return;
1346
+ }
1347
+ const result = await this.learningService.learnFromConversation(messages, source || 'conversation');
1348
+ res.json({
1349
+ totalMessages: result.totalMessages,
1350
+ learnedCount: result.learnedCount,
1351
+ results: result.results.filter(r => r.learned).map(r => ({
1352
+ type: r.type,
1353
+ concept1: r.concept1,
1354
+ concept2: r.concept2,
1355
+ message: r.message
1356
+ }))
1357
+ });
1358
+ }
1359
+ catch (err) {
1360
+ next(err);
1361
+ }
1362
+ });
1363
+ // ==================== Auto Learning Routes ====================
1364
+ // Get auto-learning stats
1365
+ api.get('/auto-learning/stats', (req, res, next) => {
1366
+ try {
1367
+ this.ensureInitialized();
1368
+ const stats = this.autoLearningService.getStats();
1369
+ const embeddingStats = this.localEmbeddingService.getStats();
1370
+ res.json({
1371
+ autoLearning: stats,
1372
+ embedding: embeddingStats
1373
+ });
1374
+ }
1375
+ catch (err) {
1376
+ next(err);
1377
+ }
1378
+ });
1379
+ // Manual feedback for auto-learning
1380
+ api.post('/auto-learning/feedback', async (req, res, next) => {
1381
+ try {
1382
+ this.ensureInitialized();
1383
+ const { query, resultId, resultContent, isPositive } = req.body;
1384
+ if (!query || !resultId) {
1385
+ res.status(400).json({ error: 'query and resultId are required' });
1386
+ return;
1387
+ }
1388
+ await this.autoLearningService.learnFromFeedback(query, { id: resultId, content: resultContent }, isPositive !== false);
1389
+ res.json({
1390
+ success: true,
1391
+ message: isPositive !== false ? 'Positive feedback recorded' : 'Negative feedback recorded'
1392
+ });
1393
+ }
1394
+ catch (err) {
1395
+ next(err);
1396
+ }
1397
+ });
1398
+ // Manual click tracking
1399
+ api.post('/auto-learning/click', async (req, res, next) => {
1400
+ try {
1401
+ this.ensureInitialized();
1402
+ const { query, resultId, resultContent } = req.body;
1403
+ if (!query || !resultId) {
1404
+ res.status(400).json({ error: 'query and resultId are required' });
1405
+ return;
1406
+ }
1407
+ await this.autoLearningService.learnFromClick(query, {
1408
+ id: resultId,
1409
+ content: resultContent
1410
+ });
1411
+ res.json({
1412
+ success: true,
1413
+ message: 'Click recorded for learning'
1414
+ });
1415
+ }
1416
+ catch (err) {
1417
+ next(err);
1418
+ }
1419
+ });
1420
+ // Get query history
1421
+ api.get('/auto-learning/history', (req, res, next) => {
1422
+ try {
1423
+ this.ensureInitialized();
1424
+ const limit = parseInt(req.query.limit) || 20;
1425
+ const history = this.autoLearningService.getQueryHistory(limit);
1426
+ res.json({
1427
+ count: history.length,
1428
+ queries: history
1429
+ });
1430
+ }
1431
+ catch (err) {
1432
+ next(err);
1433
+ }
1434
+ });
1435
+ // ==================== Local Embedding Routes ====================
1436
+ // Embed text using local model
1437
+ api.post('/embedding/embed', async (req, res, next) => {
1438
+ try {
1439
+ this.ensureInitialized();
1440
+ const { text } = req.body;
1441
+ if (!text) {
1442
+ res.status(400).json({ error: 'text is required' });
1443
+ return;
1444
+ }
1445
+ const result = await this.localEmbeddingService.embed(text);
1446
+ res.json({
1447
+ text: result.text,
1448
+ dimension: result.embedding.length,
1449
+ embedding: result.embedding.slice(0, 10), // First 10 for preview
1450
+ model: result.model,
1451
+ processingTime: result.processingTime
1452
+ });
1453
+ }
1454
+ catch (err) {
1455
+ next(err);
1456
+ }
1457
+ });
1458
+ // Calculate similarity
1459
+ api.post('/embedding/similarity', async (req, res, next) => {
1460
+ try {
1461
+ this.ensureInitialized();
1462
+ const { text1, text2, method } = req.body;
1463
+ if (!text1 || !text2) {
1464
+ res.status(400).json({ error: 'text1 and text2 are required' });
1465
+ return;
1466
+ }
1467
+ const result = await this.localEmbeddingService.similarity(text1, text2, method || 'cosine');
1468
+ res.json(result);
1469
+ }
1470
+ catch (err) {
1471
+ next(err);
1472
+ }
1473
+ });
1474
+ // Find most similar texts
1475
+ api.post('/embedding/find-similar', async (req, res, next) => {
1476
+ try {
1477
+ this.ensureInitialized();
1478
+ const { query, candidates, topK } = req.body;
1479
+ if (!query || !candidates || !Array.isArray(candidates)) {
1480
+ res.status(400).json({ error: 'query and candidates array are required' });
1481
+ return;
1482
+ }
1483
+ const results = await this.localEmbeddingService.findMostSimilar(query, candidates, topK || 5);
1484
+ res.json({
1485
+ query,
1486
+ results
1487
+ });
1488
+ }
1489
+ catch (err) {
1490
+ next(err);
1491
+ }
1492
+ });
1493
+ // ==================== Web Search Routes ====================
1494
+ // Search and learn from DuckDuckGo
1495
+ api.post('/web-search/search', async (req, res, next) => {
1496
+ try {
1497
+ this.ensureInitialized();
1498
+ const { query, maxResults, learnConcepts, learnRelations, updateCategories } = req.body;
1499
+ if (!query) {
1500
+ res.status(400).json({ error: 'query is required' });
1501
+ return;
1502
+ }
1503
+ const result = await this.webSearchService.searchAndLearn(query, {
1504
+ maxResults: maxResults || 10,
1505
+ learnConcepts: learnConcepts !== false,
1506
+ learnRelations: learnRelations !== false,
1507
+ updateCategories: updateCategories !== false,
1508
+ });
1509
+ res.json(result);
1510
+ }
1511
+ catch (err) {
1512
+ next(err);
1513
+ }
1514
+ });
1515
+ // Get category statistics
1516
+ api.get('/web-search/categories', async (req, res, next) => {
1517
+ try {
1518
+ this.ensureInitialized();
1519
+ const stats = await this.webSearchService.getCategoryStats();
1520
+ res.json({
1521
+ count: stats.length,
1522
+ categories: stats
1523
+ });
1524
+ }
1525
+ catch (err) {
1526
+ next(err);
1527
+ }
1528
+ });
1529
+ // Get concepts by category
1530
+ api.get('/web-search/categories/:category/concepts', async (req, res, next) => {
1531
+ try {
1532
+ this.ensureInitialized();
1533
+ const { category } = req.params;
1534
+ const limit = parseInt(req.query.limit) || 50;
1535
+ const concepts = await this.webSearchService.getConceptsByCategory(category, limit);
1536
+ res.json({
1537
+ category,
1538
+ count: concepts.length,
1539
+ concepts
1540
+ });
1541
+ }
1542
+ catch (err) {
1543
+ next(err);
1544
+ }
1545
+ });
1546
+ // Find similar with web search augmentation
1547
+ api.post('/web-search/find-similar', async (req, res, next) => {
1548
+ try {
1549
+ this.ensureInitialized();
1550
+ const { concept, topK } = req.body;
1551
+ if (!concept) {
1552
+ res.status(400).json({ error: 'concept is required' });
1553
+ return;
1554
+ }
1555
+ const result = await this.webSearchService.findSimilarWithWebSearch(concept, topK || 5);
1556
+ res.json(result);
1557
+ }
1558
+ catch (err) {
1559
+ next(err);
1560
+ }
1561
+ });
1562
+ // Get web search stats
1563
+ api.get('/web-search/stats', (req, res, next) => {
1564
+ try {
1565
+ this.ensureInitialized();
1566
+ const stats = this.webSearchService.getStats();
1567
+ res.json(stats);
1568
+ }
1569
+ catch (err) {
1570
+ next(err);
1571
+ }
1572
+ });
1573
+ // ==================== Multi-Layer Reasoning Routes ====================
1574
+ // Execute multi-layer reasoning
1575
+ api.post('/reasoning/query', async (req, res, next) => {
1576
+ try {
1577
+ this.ensureInitialized();
1578
+ const { query, maxDepth, minConfidence, useCache } = req.body;
1579
+ if (!query) {
1580
+ res.status(400).json({ error: 'query is required' });
1581
+ return;
1582
+ }
1583
+ const result = await this.reasoningEngine.reason(query, {
1584
+ maxDepth: maxDepth || 3,
1585
+ minConfidence: minConfidence || 0.5,
1586
+ useCache: useCache !== false,
1587
+ });
1588
+ res.json(result);
1589
+ }
1590
+ catch (err) {
1591
+ next(err);
1592
+ }
1593
+ });
1594
+ // Get reasoning stats
1595
+ api.get('/reasoning/stats', (req, res, next) => {
1596
+ try {
1597
+ this.ensureInitialized();
1598
+ const stats = this.reasoningEngine.getStats();
1599
+ res.json(stats);
1600
+ }
1601
+ catch (err) {
1602
+ next(err);
1603
+ }
1604
+ });
1605
+ // ==================== Advanced Embedding Routes ====================
1606
+ // Generate advanced embedding (1024d + quantization + PCA)
1607
+ api.post('/advanced-embedding/embed', async (req, res, next) => {
1608
+ try {
1609
+ this.ensureInitialized();
1610
+ const { text, quantize, pca } = req.body;
1611
+ if (!text) {
1612
+ res.status(400).json({ error: 'text is required' });
1613
+ return;
1614
+ }
1615
+ const result = await this.advancedEmbeddingService.embed(text, {
1616
+ quantize: quantize !== false,
1617
+ pca: pca !== false,
1618
+ });
1619
+ res.json({
1620
+ text: result.text,
1621
+ dimension: result.dimension,
1622
+ embedding: result.embedding.slice(0, 10), // Preview
1623
+ hasQuantized: !!result.quantized,
1624
+ hasPCA: !!result.pcaEmbedding,
1625
+ pcaDimension: result.pcaEmbedding?.length,
1626
+ model: result.model,
1627
+ processingTime: result.processingTime,
1628
+ });
1629
+ }
1630
+ catch (err) {
1631
+ next(err);
1632
+ }
1633
+ });
1634
+ // 2-stage search: coarse + fine
1635
+ api.post('/advanced-embedding/search', async (req, res, next) => {
1636
+ try {
1637
+ this.ensureInitialized();
1638
+ const { query, candidates, topK } = req.body;
1639
+ if (!query) {
1640
+ res.status(400).json({ error: 'query is required' });
1641
+ return;
1642
+ }
1643
+ // If candidates provided, use them; otherwise use empty array
1644
+ const searchCandidates = candidates || [];
1645
+ if (searchCandidates.length === 0) {
1646
+ res.json({
1647
+ message: 'No candidates provided for search',
1648
+ results: []
1649
+ });
1650
+ return;
1651
+ }
1652
+ // Coarse search
1653
+ const coarseResults = await this.advancedEmbeddingService.coarseSearch(query, searchCandidates, Math.min(100, searchCandidates.length));
1654
+ // Fine rerank top candidates
1655
+ const topCandidates = coarseResults.slice(0, 20).map(r => {
1656
+ const candidate = searchCandidates.find((c) => c.id === r.id);
1657
+ return {
1658
+ id: r.id,
1659
+ embedding: Array.isArray(candidate?.embedding) ? candidate.embedding : []
1660
+ };
1661
+ }).filter(c => c.embedding.length > 0);
1662
+ const fineResults = await this.advancedEmbeddingService.fineRerank(query, topCandidates, topK || 10);
1663
+ res.json({
1664
+ query,
1665
+ coarseCount: coarseResults.length,
1666
+ results: fineResults,
1667
+ });
1668
+ }
1669
+ catch (err) {
1670
+ next(err);
1671
+ }
1672
+ });
1673
+ // Get advanced embedding stats
1674
+ api.get('/advanced-embedding/stats', (req, res, next) => {
1675
+ try {
1676
+ this.ensureInitialized();
1677
+ const stats = this.advancedEmbeddingService.getStats();
1678
+ res.json(stats);
1679
+ }
1680
+ catch (err) {
1681
+ next(err);
1682
+ }
1683
+ });
1684
+ // Find synonyms from DB
1685
+ api.get('/ontology/synonyms/:word', async (req, res, next) => {
1686
+ try {
1687
+ this.ensureInitialized();
1688
+ const word = req.params.word;
1689
+ // DB-based synonyms
1690
+ const dbSynonyms = await this.ontologyStore.findSynonyms(word);
1691
+ // Embedding-based synonyms (fallback)
1692
+ const embeddingSynonyms = findEmbeddingSynonyms(word);
1693
+ // Combine and deduplicate
1694
+ const allSynonyms = [...new Set([...dbSynonyms, ...embeddingSynonyms])];
1695
+ res.json({
1696
+ word,
1697
+ synonyms: allSynonyms,
1698
+ sources: {
1699
+ db: dbSynonyms.length,
1700
+ embedding: embeddingSynonyms.length
1701
+ }
1702
+ });
1703
+ }
1704
+ catch (err) {
1705
+ next(err);
1706
+ }
1707
+ });
1708
+ // Get semantic group by word
1709
+ api.get('/ontology/group/:word', async (req, res, next) => {
1710
+ try {
1711
+ this.ensureInitialized();
1712
+ const group = await this.ontologyStore.findGroupByWord(req.params.word);
1713
+ if (!group) {
1714
+ res.status(404).json({ error: 'Group not found' });
1715
+ return;
1716
+ }
1717
+ res.json({
1718
+ id: group.id,
1719
+ primaryConcept: group.primaryConcept,
1720
+ synonyms: group.synonyms,
1721
+ language: group.language,
1722
+ category: group.category,
1723
+ frequency: group.frequency,
1724
+ learnedFrom: group.learnedFrom
1725
+ });
1726
+ }
1727
+ catch (err) {
1728
+ next(err);
1729
+ }
1730
+ });
1731
+ // Get relations for a concept
1732
+ api.get('/ontology/relations/:concept', async (req, res, next) => {
1733
+ try {
1734
+ this.ensureInitialized();
1735
+ const relations = await this.ontologyStore.getRelations(req.params.concept);
1736
+ res.json({
1737
+ concept: req.params.concept,
1738
+ relations: relations.map(r => ({
1739
+ id: r.id,
1740
+ source: r.sourceConcept,
1741
+ target: r.targetConcept,
1742
+ type: r.type,
1743
+ weight: r.weight,
1744
+ learnedFrom: r.learnedFrom
1745
+ }))
1746
+ });
1747
+ }
1748
+ catch (err) {
1749
+ next(err);
1750
+ }
1751
+ });
1752
+ // Get all groups
1753
+ api.get('/ontology/groups', async (req, res, next) => {
1754
+ try {
1755
+ this.ensureInitialized();
1756
+ const category = req.query.category;
1757
+ let groups;
1758
+ if (category) {
1759
+ groups = await this.ontologyStore.getGroupsByCategory(category);
1760
+ }
1761
+ else {
1762
+ groups = await this.ontologyStore.getAllGroups();
1763
+ }
1764
+ res.json({
1765
+ count: groups.length,
1766
+ groups: groups.map(g => ({
1767
+ id: g.id,
1768
+ primary: g.primaryConcept,
1769
+ synonyms: g.synonyms,
1770
+ category: g.category,
1771
+ language: g.language
1772
+ }))
1773
+ });
1774
+ }
1775
+ catch (err) {
1776
+ next(err);
1777
+ }
1778
+ });
1779
+ // Calculate similarity between two words
1780
+ api.get('/ontology/similarity', (req, res, next) => {
1781
+ try {
1782
+ const { word1, word2 } = req.query;
1783
+ if (!word1 || !word2) {
1784
+ res.status(400).json({ error: 'word1 and word2 are required' });
1785
+ return;
1786
+ }
1787
+ const similarity = calculateSimilarity(word1, word2);
1788
+ res.json({
1789
+ word1,
1790
+ word2,
1791
+ similarity,
1792
+ level: similarity >= 0.9 ? 'synonym' :
1793
+ similarity >= 0.7 ? 'very similar' :
1794
+ similarity >= 0.5 ? 'similar' :
1795
+ similarity >= 0.3 ? 'somewhat similar' : 'different'
1796
+ });
1797
+ }
1798
+ catch (err) {
1799
+ next(err);
1800
+ }
1801
+ });
1802
+ // Find similar concepts
1803
+ api.post('/ontology/search', async (req, res, next) => {
1804
+ try {
1805
+ this.ensureInitialized();
1806
+ const { query, threshold = 0.3, topK = 10 } = req.body;
1807
+ if (!query) {
1808
+ res.status(400).json({ error: 'query is required' });
1809
+ return;
1810
+ }
1811
+ // Search in embedding similarity
1812
+ const results = embeddingSimilarity.search(query, threshold, topK);
1813
+ res.json({
1814
+ query,
1815
+ count: results.length,
1816
+ results: results.map(r => ({
1817
+ concept: r.concept,
1818
+ similarity: r.similarity
1819
+ }))
1820
+ });
1821
+ }
1822
+ catch (err) {
1823
+ next(err);
1824
+ }
1825
+ });
1826
+ // Ontology stats
1827
+ api.get('/ontology/stats', async (req, res, next) => {
1828
+ try {
1829
+ this.ensureInitialized();
1830
+ const stats = await this.ontologyStore.getStats();
1831
+ res.json({
1832
+ totalGroups: stats.totalGroups,
1833
+ totalWords: stats.totalWords,
1834
+ totalRelations: stats.totalRelations,
1835
+ totalLearnings: stats.totalLearnings,
1836
+ byCategory: stats.byCategory,
1837
+ byLanguage: stats.byLanguage
1838
+ });
1839
+ }
1840
+ catch (err) {
1841
+ next(err);
1842
+ }
1843
+ });
1844
+ // ==================== Hierarchical Chunking Routes ====================
1845
+ // Hierarchical chunk - text structure
1846
+ api.post('/hierarchical/chunk', (req, res, next) => {
1847
+ try {
1848
+ this.ensureInitialized();
1849
+ const { text, language } = req.body;
1850
+ if (!text) {
1851
+ res.status(400).json({ error: 'Text is required' });
1852
+ return;
1853
+ }
1854
+ const tree = this.hierarchicalChunker.chunk(text, undefined, language || 'auto');
1855
+ const detectedLang = this.hierarchicalChunker.getDetectedLanguage();
1856
+ res.json({
1857
+ language: detectedLang,
1858
+ levels: {
1859
+ document: (tree.levels.get('document') || []).length,
1860
+ paragraph: (tree.levels.get('paragraph') || []).length,
1861
+ sentence: (tree.levels.get('sentence') || []).length,
1862
+ phrase: (tree.levels.get('phrase') || []).length,
1863
+ word: (tree.levels.get('word') || []).length,
1864
+ syllable: (tree.levels.get('syllable') || []).length
1865
+ },
1866
+ chunks: {
1867
+ sentences: (tree.levels.get('sentence') || []).map(c => c.text),
1868
+ phrases: (tree.levels.get('phrase') || []).map(c => c.text),
1869
+ words: (tree.levels.get('word') || []).map(c => c.text),
1870
+ syllables: (tree.levels.get('syllable') || []).map(c => c.text)
1871
+ }
1872
+ });
1873
+ }
1874
+ catch (err) {
1875
+ next(err);
1876
+ }
1877
+ });
1878
+ // Analyze text with multi-lang tokenizer
1879
+ api.post('/hierarchical/analyze', (req, res, next) => {
1880
+ try {
1881
+ this.ensureInitialized();
1882
+ const { text } = req.body;
1883
+ if (!text) {
1884
+ res.status(400).json({ error: 'Text is required' });
1885
+ return;
1886
+ }
1887
+ const analysis = multiLangTokenizer.analyze(text);
1888
+ res.json({
1889
+ language: analysis.language,
1890
+ sentences: analysis.sentences,
1891
+ phrases: analysis.phrases,
1892
+ words: analysis.words,
1893
+ morphemes: analysis.morphemes,
1894
+ tokens: analysis.tokens.map(t => ({
1895
+ text: t.text,
1896
+ type: t.type
1897
+ }))
1898
+ });
1899
+ }
1900
+ catch (err) {
1901
+ next(err);
1902
+ }
1903
+ });
1904
+ // Detect language
1905
+ api.post('/hierarchical/detect-language', (req, res, next) => {
1906
+ try {
1907
+ const { text } = req.body;
1908
+ if (!text) {
1909
+ res.status(400).json({ error: 'Text is required' });
1910
+ return;
1911
+ }
1912
+ const language = detectLanguage(text);
1913
+ const languageNames = {
1914
+ ko: '한국어',
1915
+ en: 'English',
1916
+ ja: '日本語',
1917
+ zh: '中文',
1918
+ auto: 'Auto-detected'
1919
+ };
1920
+ res.json({
1921
+ text: text.slice(0, 100),
1922
+ language,
1923
+ languageName: languageNames[language] || language
1924
+ });
1925
+ }
1926
+ catch (err) {
1927
+ next(err);
1928
+ }
1929
+ });
1930
+ // Mount API routes
1931
+ this.app.use('/api/v1', api);
1932
+ // Serve React dashboard build
1933
+ const dashboardPath = path.join(__dirname, '../../dashboard/dist');
1934
+ const publicPath = path.join(__dirname, '../../public');
1935
+ // Try dashboard build first, fallback to public
1936
+ this.app.use(express.static(dashboardPath));
1937
+ this.app.use(express.static(publicPath));
1938
+ // SPA fallback - serve index.html for non-API routes
1939
+ this.app.get('*', (req, res, next) => {
1940
+ // Skip API routes
1941
+ if (req.path.startsWith('/api/')) {
1942
+ return next();
1943
+ }
1944
+ // Try dashboard build first
1945
+ const dashboardIndex = path.join(dashboardPath, 'index.html');
1946
+ const publicIndex = path.join(publicPath, 'index.html');
1947
+ if (fs.existsSync(dashboardIndex)) {
1948
+ res.sendFile(dashboardIndex);
1949
+ }
1950
+ else if (fs.existsSync(publicIndex)) {
1951
+ res.sendFile(publicIndex);
1952
+ }
1953
+ else {
1954
+ next();
1955
+ }
1956
+ });
1957
+ }
1958
+ /**
1959
+ * Setup error handling
1960
+ */
1961
+ setupErrorHandling() {
1962
+ // Error logger middleware
1963
+ this.app.use(errorLogger);
1964
+ // 404 handler for API routes
1965
+ this.app.use((_req, res) => {
1966
+ res.status(404).json({
1967
+ error: 'Not Found',
1968
+ message: 'The requested resource was not found',
1969
+ });
1970
+ });
1971
+ // Error handler - hide details in production
1972
+ this.app.use((err, _req, res, _next) => {
1973
+ const isProduction = process.env.NODE_ENV === 'production';
1974
+ // Log full error internally
1975
+ logger.error('Unhandled error', {
1976
+ message: err.message,
1977
+ stack: isProduction ? undefined : err.stack,
1978
+ });
1979
+ // Send sanitized response
1980
+ res.status(500).json({
1981
+ error: 'Internal Server Error',
1982
+ message: isProduction
1983
+ ? 'An unexpected error occurred. Please try again later.'
1984
+ : err.message,
1985
+ });
1986
+ });
1987
+ }
1988
+ /**
1989
+ * Ensure server is initialized
1990
+ */
1991
+ ensureInitialized() {
1992
+ if (!this.initialized) {
1993
+ throw new Error('Server not initialized');
1994
+ }
1995
+ }
1996
+ /**
1997
+ * Get Express app instance
1998
+ */
1999
+ getApp() {
2000
+ return this.app;
2001
+ }
2002
+ }
2003
+ /**
2004
+ * Create and start NMT server
2005
+ */
2006
+ export async function createServer(options) {
2007
+ const server = new NMTServer(options);
2008
+ await server.start();
2009
+ return server;
2010
+ }
2011
+ //# sourceMappingURL=server.js.map