@indexnetwork/protocol 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (365) hide show
  1. package/dist/agents/chat.agent.d.ts +218 -0
  2. package/dist/agents/chat.agent.d.ts.map +1 -0
  3. package/dist/agents/chat.agent.js +884 -0
  4. package/dist/agents/chat.agent.js.map +1 -0
  5. package/dist/agents/chat.prompt.d.ts +18 -0
  6. package/dist/agents/chat.prompt.d.ts.map +1 -0
  7. package/dist/agents/chat.prompt.js +372 -0
  8. package/dist/agents/chat.prompt.js.map +1 -0
  9. package/dist/agents/chat.prompt.modules.d.ts +61 -0
  10. package/dist/agents/chat.prompt.modules.d.ts.map +1 -0
  11. package/dist/agents/chat.prompt.modules.js +366 -0
  12. package/dist/agents/chat.prompt.modules.js.map +1 -0
  13. package/dist/agents/chat.title.generator.d.ts +20 -0
  14. package/dist/agents/chat.title.generator.d.ts.map +1 -0
  15. package/dist/agents/chat.title.generator.js +66 -0
  16. package/dist/agents/chat.title.generator.js.map +1 -0
  17. package/dist/agents/home.categorizer.d.ts +28 -0
  18. package/dist/agents/home.categorizer.d.ts.map +1 -0
  19. package/dist/agents/home.categorizer.js +170 -0
  20. package/dist/agents/home.categorizer.js.map +1 -0
  21. package/dist/agents/hyde.generator.d.ts +27 -0
  22. package/dist/agents/hyde.generator.d.ts.map +1 -0
  23. package/dist/agents/hyde.generator.js +75 -0
  24. package/dist/agents/hyde.generator.js.map +1 -0
  25. package/dist/agents/hyde.strategies.d.ts +17 -0
  26. package/dist/agents/hyde.strategies.d.ts.map +1 -0
  27. package/dist/agents/hyde.strategies.js +29 -0
  28. package/dist/agents/hyde.strategies.js.map +1 -0
  29. package/dist/agents/intent.clarifier.d.ts +29 -0
  30. package/dist/agents/intent.clarifier.d.ts.map +1 -0
  31. package/dist/agents/intent.clarifier.js +186 -0
  32. package/dist/agents/intent.clarifier.js.map +1 -0
  33. package/dist/agents/intent.indexer.d.ts +77 -0
  34. package/dist/agents/intent.indexer.d.ts.map +1 -0
  35. package/dist/agents/intent.indexer.js +164 -0
  36. package/dist/agents/intent.indexer.js.map +1 -0
  37. package/dist/agents/intent.inferrer.d.ts +95 -0
  38. package/dist/agents/intent.inferrer.d.ts.map +1 -0
  39. package/dist/agents/intent.inferrer.js +238 -0
  40. package/dist/agents/intent.inferrer.js.map +1 -0
  41. package/dist/agents/intent.reconciler.d.ts +106 -0
  42. package/dist/agents/intent.reconciler.d.ts.map +1 -0
  43. package/dist/agents/intent.reconciler.js +184 -0
  44. package/dist/agents/intent.reconciler.js.map +1 -0
  45. package/dist/agents/intent.verifier.d.ts +97 -0
  46. package/dist/agents/intent.verifier.d.ts.map +1 -0
  47. package/dist/agents/intent.verifier.js +234 -0
  48. package/dist/agents/intent.verifier.js.map +1 -0
  49. package/dist/agents/invite.generator.d.ts +47 -0
  50. package/dist/agents/invite.generator.d.ts.map +1 -0
  51. package/dist/agents/invite.generator.js +56 -0
  52. package/dist/agents/invite.generator.js.map +1 -0
  53. package/dist/agents/lens.inferrer.d.ts +37 -0
  54. package/dist/agents/lens.inferrer.d.ts.map +1 -0
  55. package/dist/agents/lens.inferrer.js +98 -0
  56. package/dist/agents/lens.inferrer.js.map +1 -0
  57. package/dist/agents/model.config.d.ts +120 -0
  58. package/dist/agents/model.config.d.ts.map +1 -0
  59. package/dist/agents/model.config.js +76 -0
  60. package/dist/agents/model.config.js.map +1 -0
  61. package/dist/agents/negotiation.insights.generator.d.ts +32 -0
  62. package/dist/agents/negotiation.insights.generator.d.ts.map +1 -0
  63. package/dist/agents/negotiation.insights.generator.js +105 -0
  64. package/dist/agents/negotiation.insights.generator.js.map +1 -0
  65. package/dist/agents/negotiation.proposer.d.ts +26 -0
  66. package/dist/agents/negotiation.proposer.d.ts.map +1 -0
  67. package/dist/agents/negotiation.proposer.js +67 -0
  68. package/dist/agents/negotiation.proposer.js.map +1 -0
  69. package/dist/agents/negotiation.responder.d.ts +26 -0
  70. package/dist/agents/negotiation.responder.d.ts.map +1 -0
  71. package/dist/agents/negotiation.responder.js +71 -0
  72. package/dist/agents/negotiation.responder.js.map +1 -0
  73. package/dist/agents/opportunity.evaluator.d.ts +253 -0
  74. package/dist/agents/opportunity.evaluator.d.ts.map +1 -0
  75. package/dist/agents/opportunity.evaluator.js +413 -0
  76. package/dist/agents/opportunity.evaluator.js.map +1 -0
  77. package/dist/agents/opportunity.presenter.d.ts +115 -0
  78. package/dist/agents/opportunity.presenter.d.ts.map +1 -0
  79. package/dist/agents/opportunity.presenter.js +524 -0
  80. package/dist/agents/opportunity.presenter.js.map +1 -0
  81. package/dist/agents/profile.generator.d.ts +67 -0
  82. package/dist/agents/profile.generator.d.ts.map +1 -0
  83. package/dist/agents/profile.generator.js +97 -0
  84. package/dist/agents/profile.generator.js.map +1 -0
  85. package/dist/agents/profile.hyde.generator.d.ts +43 -0
  86. package/dist/agents/profile.hyde.generator.d.ts.map +1 -0
  87. package/dist/agents/profile.hyde.generator.js +113 -0
  88. package/dist/agents/profile.hyde.generator.js.map +1 -0
  89. package/dist/agents/suggestion.generator.d.ts +24 -0
  90. package/dist/agents/suggestion.generator.d.ts.map +1 -0
  91. package/dist/agents/suggestion.generator.js +96 -0
  92. package/dist/agents/suggestion.generator.js.map +1 -0
  93. package/dist/graphs/chat.graph.d.ts +312 -0
  94. package/dist/graphs/chat.graph.d.ts.map +1 -0
  95. package/dist/graphs/chat.graph.js +267 -0
  96. package/dist/graphs/chat.graph.js.map +1 -0
  97. package/dist/graphs/home.graph.d.ts +180 -0
  98. package/dist/graphs/home.graph.d.ts.map +1 -0
  99. package/dist/graphs/home.graph.js +598 -0
  100. package/dist/graphs/home.graph.js.map +1 -0
  101. package/dist/graphs/hyde.graph.d.ts +110 -0
  102. package/dist/graphs/hyde.graph.d.ts.map +1 -0
  103. package/dist/graphs/hyde.graph.js +235 -0
  104. package/dist/graphs/hyde.graph.js.map +1 -0
  105. package/dist/graphs/index.graph.d.ts +620 -0
  106. package/dist/graphs/index.graph.d.ts.map +1 -0
  107. package/dist/graphs/index.graph.js +226 -0
  108. package/dist/graphs/index.graph.js.map +1 -0
  109. package/dist/graphs/index_membership.graph.d.ts +250 -0
  110. package/dist/graphs/index_membership.graph.d.ts.map +1 -0
  111. package/dist/graphs/index_membership.graph.js +204 -0
  112. package/dist/graphs/index_membership.graph.js.map +1 -0
  113. package/dist/graphs/intent.graph.d.ts +490 -0
  114. package/dist/graphs/intent.graph.d.ts.map +1 -0
  115. package/dist/graphs/intent.graph.js +787 -0
  116. package/dist/graphs/intent.graph.js.map +1 -0
  117. package/dist/graphs/intent_index.graph.d.ts +396 -0
  118. package/dist/graphs/intent_index.graph.d.ts.map +1 -0
  119. package/dist/graphs/intent_index.graph.js +331 -0
  120. package/dist/graphs/intent_index.graph.js.map +1 -0
  121. package/dist/graphs/maintenance.graph.d.ts +177 -0
  122. package/dist/graphs/maintenance.graph.d.ts.map +1 -0
  123. package/dist/graphs/maintenance.graph.js +173 -0
  124. package/dist/graphs/maintenance.graph.js.map +1 -0
  125. package/dist/graphs/negotiation.graph.d.ts +819 -0
  126. package/dist/graphs/negotiation.graph.d.ts.map +1 -0
  127. package/dist/graphs/negotiation.graph.js +255 -0
  128. package/dist/graphs/negotiation.graph.js.map +1 -0
  129. package/dist/graphs/opportunity.graph.d.ts +1082 -0
  130. package/dist/graphs/opportunity.graph.d.ts.map +1 -0
  131. package/dist/graphs/opportunity.graph.js +2534 -0
  132. package/dist/graphs/opportunity.graph.js.map +1 -0
  133. package/dist/graphs/profile.graph.d.ts +617 -0
  134. package/dist/graphs/profile.graph.d.ts.map +1 -0
  135. package/dist/graphs/profile.graph.js +839 -0
  136. package/dist/graphs/profile.graph.js.map +1 -0
  137. package/dist/graphs/tests/chat.graph.mocks.d.ts +104 -0
  138. package/dist/graphs/tests/chat.graph.mocks.d.ts.map +1 -0
  139. package/dist/graphs/tests/chat.graph.mocks.js +225 -0
  140. package/dist/graphs/tests/chat.graph.mocks.js.map +1 -0
  141. package/dist/index.d.ts +62 -0
  142. package/dist/index.d.ts.map +1 -0
  143. package/dist/index.js +44 -0
  144. package/dist/index.js.map +1 -0
  145. package/dist/interfaces/auth.interface.d.ts +15 -0
  146. package/dist/interfaces/auth.interface.d.ts.map +1 -0
  147. package/dist/interfaces/auth.interface.js +2 -0
  148. package/dist/interfaces/auth.interface.js.map +1 -0
  149. package/dist/interfaces/cache.interface.d.ts +43 -0
  150. package/dist/interfaces/cache.interface.d.ts.map +1 -0
  151. package/dist/interfaces/cache.interface.js +6 -0
  152. package/dist/interfaces/cache.interface.js.map +1 -0
  153. package/dist/interfaces/chat-session.interface.d.ts +11 -0
  154. package/dist/interfaces/chat-session.interface.d.ts.map +1 -0
  155. package/dist/interfaces/chat-session.interface.js +2 -0
  156. package/dist/interfaces/chat-session.interface.js.map +1 -0
  157. package/dist/interfaces/contact.interface.d.ts +48 -0
  158. package/dist/interfaces/contact.interface.d.ts.map +1 -0
  159. package/dist/interfaces/contact.interface.js +2 -0
  160. package/dist/interfaces/contact.interface.js.map +1 -0
  161. package/dist/interfaces/database.interface.d.ts +1495 -0
  162. package/dist/interfaces/database.interface.d.ts.map +1 -0
  163. package/dist/interfaces/database.interface.js +2 -0
  164. package/dist/interfaces/database.interface.js.map +1 -0
  165. package/dist/interfaces/embedder.interface.d.ts +85 -0
  166. package/dist/interfaces/embedder.interface.d.ts.map +1 -0
  167. package/dist/interfaces/embedder.interface.js +5 -0
  168. package/dist/interfaces/embedder.interface.js.map +1 -0
  169. package/dist/interfaces/enrichment.interface.d.ts +40 -0
  170. package/dist/interfaces/enrichment.interface.d.ts.map +1 -0
  171. package/dist/interfaces/enrichment.interface.js +2 -0
  172. package/dist/interfaces/enrichment.interface.js.map +1 -0
  173. package/dist/interfaces/integration.interface.d.ts +91 -0
  174. package/dist/interfaces/integration.interface.d.ts.map +1 -0
  175. package/dist/interfaces/integration.interface.js +2 -0
  176. package/dist/interfaces/integration.interface.js.map +1 -0
  177. package/dist/interfaces/queue.interface.d.ts +17 -0
  178. package/dist/interfaces/queue.interface.d.ts.map +1 -0
  179. package/dist/interfaces/queue.interface.js +5 -0
  180. package/dist/interfaces/queue.interface.js.map +1 -0
  181. package/dist/interfaces/scraper.interface.d.ts +31 -0
  182. package/dist/interfaces/scraper.interface.d.ts.map +1 -0
  183. package/dist/interfaces/scraper.interface.js +2 -0
  184. package/dist/interfaces/scraper.interface.js.map +1 -0
  185. package/dist/interfaces/storage.interface.d.ts +46 -0
  186. package/dist/interfaces/storage.interface.d.ts.map +1 -0
  187. package/dist/interfaces/storage.interface.js +6 -0
  188. package/dist/interfaces/storage.interface.js.map +1 -0
  189. package/dist/mcp/mcp.server.d.ts +29 -0
  190. package/dist/mcp/mcp.server.d.ts.map +1 -0
  191. package/dist/mcp/mcp.server.js +171 -0
  192. package/dist/mcp/mcp.server.js.map +1 -0
  193. package/dist/states/chat.state.d.ts +126 -0
  194. package/dist/states/chat.state.d.ts.map +1 -0
  195. package/dist/states/chat.state.js +112 -0
  196. package/dist/states/chat.state.js.map +1 -0
  197. package/dist/states/home.state.d.ts +100 -0
  198. package/dist/states/home.state.d.ts.map +1 -0
  199. package/dist/states/home.state.js +74 -0
  200. package/dist/states/home.state.js.map +1 -0
  201. package/dist/states/hyde.state.d.ts +54 -0
  202. package/dist/states/hyde.state.d.ts.map +1 -0
  203. package/dist/states/hyde.state.js +66 -0
  204. package/dist/states/hyde.state.js.map +1 -0
  205. package/dist/states/index.state.d.ts +179 -0
  206. package/dist/states/index.state.d.ts.map +1 -0
  207. package/dist/states/index.state.js +56 -0
  208. package/dist/states/index.state.js.map +1 -0
  209. package/dist/states/index_membership.state.d.ts +77 -0
  210. package/dist/states/index_membership.state.d.ts.map +1 -0
  211. package/dist/states/index_membership.state.js +43 -0
  212. package/dist/states/index_membership.state.js.map +1 -0
  213. package/dist/states/intent.state.d.ts +203 -0
  214. package/dist/states/intent.state.d.ts.map +1 -0
  215. package/dist/states/intent.state.js +153 -0
  216. package/dist/states/intent.state.js.map +1 -0
  217. package/dist/states/intent_index.state.d.ts +148 -0
  218. package/dist/states/intent_index.state.d.ts.map +1 -0
  219. package/dist/states/intent_index.state.js +100 -0
  220. package/dist/states/intent_index.state.js.map +1 -0
  221. package/dist/states/maintenance.state.d.ts +36 -0
  222. package/dist/states/maintenance.state.d.ts.map +1 -0
  223. package/dist/states/maintenance.state.js +56 -0
  224. package/dist/states/maintenance.state.js.map +1 -0
  225. package/dist/states/negotiation.state.d.ts +230 -0
  226. package/dist/states/negotiation.state.d.ts.map +1 -0
  227. package/dist/states/negotiation.state.js +82 -0
  228. package/dist/states/negotiation.state.js.map +1 -0
  229. package/dist/states/opportunity.state.d.ts +300 -0
  230. package/dist/states/opportunity.state.d.ts.map +1 -0
  231. package/dist/states/opportunity.state.js +207 -0
  232. package/dist/states/opportunity.state.js.map +1 -0
  233. package/dist/states/profile.state.d.ts +172 -0
  234. package/dist/states/profile.state.d.ts.map +1 -0
  235. package/dist/states/profile.state.js +133 -0
  236. package/dist/states/profile.state.js.map +1 -0
  237. package/dist/streamers/chat.streamer.d.ts +55 -0
  238. package/dist/streamers/chat.streamer.d.ts.map +1 -0
  239. package/dist/streamers/chat.streamer.js +186 -0
  240. package/dist/streamers/chat.streamer.js.map +1 -0
  241. package/dist/streamers/index.d.ts +3 -0
  242. package/dist/streamers/index.d.ts.map +1 -0
  243. package/dist/streamers/index.js +3 -0
  244. package/dist/streamers/index.js.map +1 -0
  245. package/dist/streamers/response.streamer.d.ts +36 -0
  246. package/dist/streamers/response.streamer.d.ts.map +1 -0
  247. package/dist/streamers/response.streamer.js +46 -0
  248. package/dist/streamers/response.streamer.js.map +1 -0
  249. package/dist/support/chat.utils.d.ts +42 -0
  250. package/dist/support/chat.utils.d.ts.map +1 -0
  251. package/dist/support/chat.utils.js +89 -0
  252. package/dist/support/chat.utils.js.map +1 -0
  253. package/dist/support/debug-meta.sanitizer.d.ts +18 -0
  254. package/dist/support/debug-meta.sanitizer.d.ts.map +1 -0
  255. package/dist/support/debug-meta.sanitizer.js +82 -0
  256. package/dist/support/debug-meta.sanitizer.js.map +1 -0
  257. package/dist/support/feed.health.d.ts +32 -0
  258. package/dist/support/feed.health.d.ts.map +1 -0
  259. package/dist/support/feed.health.js +76 -0
  260. package/dist/support/feed.health.js.map +1 -0
  261. package/dist/support/introducer.discovery.d.ts +78 -0
  262. package/dist/support/introducer.discovery.d.ts.map +1 -0
  263. package/dist/support/introducer.discovery.js +101 -0
  264. package/dist/support/introducer.discovery.js.map +1 -0
  265. package/dist/support/log.d.ts +65 -0
  266. package/dist/support/log.d.ts.map +1 -0
  267. package/dist/support/log.js +76 -0
  268. package/dist/support/log.js.map +1 -0
  269. package/dist/support/lucide.icon-catalog.d.ts +22 -0
  270. package/dist/support/lucide.icon-catalog.d.ts.map +1 -0
  271. package/dist/support/lucide.icon-catalog.js +101 -0
  272. package/dist/support/lucide.icon-catalog.js.map +1 -0
  273. package/dist/support/opportunity.card-text.d.ts +39 -0
  274. package/dist/support/opportunity.card-text.d.ts.map +1 -0
  275. package/dist/support/opportunity.card-text.js +333 -0
  276. package/dist/support/opportunity.card-text.js.map +1 -0
  277. package/dist/support/opportunity.constants.d.ts +9 -0
  278. package/dist/support/opportunity.constants.d.ts.map +1 -0
  279. package/dist/support/opportunity.constants.js +11 -0
  280. package/dist/support/opportunity.constants.js.map +1 -0
  281. package/dist/support/opportunity.discover.d.ts +144 -0
  282. package/dist/support/opportunity.discover.d.ts.map +1 -0
  283. package/dist/support/opportunity.discover.js +610 -0
  284. package/dist/support/opportunity.discover.js.map +1 -0
  285. package/dist/support/opportunity.enricher.d.ts +44 -0
  286. package/dist/support/opportunity.enricher.d.ts.map +1 -0
  287. package/dist/support/opportunity.enricher.js +245 -0
  288. package/dist/support/opportunity.enricher.js.map +1 -0
  289. package/dist/support/opportunity.persist.d.ts +39 -0
  290. package/dist/support/opportunity.persist.d.ts.map +1 -0
  291. package/dist/support/opportunity.persist.js +63 -0
  292. package/dist/support/opportunity.persist.js.map +1 -0
  293. package/dist/support/opportunity.presentation.d.ts +21 -0
  294. package/dist/support/opportunity.presentation.d.ts.map +1 -0
  295. package/dist/support/opportunity.presentation.js +75 -0
  296. package/dist/support/opportunity.presentation.js.map +1 -0
  297. package/dist/support/opportunity.sanitize.d.ts +18 -0
  298. package/dist/support/opportunity.sanitize.d.ts.map +1 -0
  299. package/dist/support/opportunity.sanitize.js +89 -0
  300. package/dist/support/opportunity.sanitize.js.map +1 -0
  301. package/dist/support/opportunity.utils.d.ts +99 -0
  302. package/dist/support/opportunity.utils.d.ts.map +1 -0
  303. package/dist/support/opportunity.utils.js +184 -0
  304. package/dist/support/opportunity.utils.js.map +1 -0
  305. package/dist/support/performance.d.ts +19 -0
  306. package/dist/support/performance.d.ts.map +1 -0
  307. package/dist/support/performance.js +43 -0
  308. package/dist/support/performance.js.map +1 -0
  309. package/dist/support/profile.enrichment-display-name.d.ts +16 -0
  310. package/dist/support/profile.enrichment-display-name.d.ts.map +1 -0
  311. package/dist/support/profile.enrichment-display-name.js +22 -0
  312. package/dist/support/profile.enrichment-display-name.js.map +1 -0
  313. package/dist/support/protocol.logger.d.ts +22 -0
  314. package/dist/support/protocol.logger.d.ts.map +1 -0
  315. package/dist/support/protocol.logger.js +44 -0
  316. package/dist/support/protocol.logger.js.map +1 -0
  317. package/dist/support/request-context.d.ts +19 -0
  318. package/dist/support/request-context.d.ts.map +1 -0
  319. package/dist/support/request-context.js +7 -0
  320. package/dist/support/request-context.js.map +1 -0
  321. package/dist/tools/contact.tools.d.ts +7 -0
  322. package/dist/tools/contact.tools.d.ts.map +1 -0
  323. package/dist/tools/contact.tools.js +115 -0
  324. package/dist/tools/contact.tools.js.map +1 -0
  325. package/dist/tools/index.d.ts +17 -0
  326. package/dist/tools/index.d.ts.map +1 -0
  327. package/dist/tools/index.js +140 -0
  328. package/dist/tools/index.js.map +1 -0
  329. package/dist/tools/index.tools.d.ts +3 -0
  330. package/dist/tools/index.tools.d.ts.map +1 -0
  331. package/dist/tools/index.tools.js +423 -0
  332. package/dist/tools/index.tools.js.map +1 -0
  333. package/dist/tools/integration.tools.d.ts +13 -0
  334. package/dist/tools/integration.tools.d.ts.map +1 -0
  335. package/dist/tools/integration.tools.js +77 -0
  336. package/dist/tools/integration.tools.js.map +1 -0
  337. package/dist/tools/intent.tools.d.ts +3 -0
  338. package/dist/tools/intent.tools.d.ts.map +1 -0
  339. package/dist/tools/intent.tools.js +458 -0
  340. package/dist/tools/intent.tools.js.map +1 -0
  341. package/dist/tools/opportunity.tools.d.ts +44 -0
  342. package/dist/tools/opportunity.tools.d.ts.map +1 -0
  343. package/dist/tools/opportunity.tools.js +814 -0
  344. package/dist/tools/opportunity.tools.js.map +1 -0
  345. package/dist/tools/profile.tools.d.ts +3 -0
  346. package/dist/tools/profile.tools.d.ts.map +1 -0
  347. package/dist/tools/profile.tools.js +513 -0
  348. package/dist/tools/profile.tools.js.map +1 -0
  349. package/dist/tools/tool.helpers.d.ts +225 -0
  350. package/dist/tools/tool.helpers.d.ts.map +1 -0
  351. package/dist/tools/tool.helpers.js +172 -0
  352. package/dist/tools/tool.helpers.js.map +1 -0
  353. package/dist/tools/tool.registry.d.ts +12 -0
  354. package/dist/tools/tool.registry.d.ts.map +1 -0
  355. package/dist/tools/tool.registry.js +62 -0
  356. package/dist/tools/tool.registry.js.map +1 -0
  357. package/dist/tools/utility.tools.d.ts +3 -0
  358. package/dist/tools/utility.tools.d.ts.map +1 -0
  359. package/dist/tools/utility.tools.js +107 -0
  360. package/dist/tools/utility.tools.js.map +1 -0
  361. package/dist/types/chat-streaming.types.d.ts +472 -0
  362. package/dist/types/chat-streaming.types.d.ts.map +1 -0
  363. package/dist/types/chat-streaming.types.js +260 -0
  364. package/dist/types/chat-streaming.types.js.map +1 -0
  365. package/package.json +32 -0
@@ -0,0 +1,46 @@
1
+ import { createTokenEvent, createErrorEvent, } from "../types/chat-streaming.types.js";
2
+ import { protocolLogger } from "../support/protocol.logger.js";
3
+ const logger = protocolLogger("ResponseStreamer");
4
+ // ══════════════════════════════════════════════════════════════════════════════
5
+ // RESPONSE STREAMER
6
+ // ══════════════════════════════════════════════════════════════════════════════
7
+ /**
8
+ * Streams the final response from the chat agent.
9
+ *
10
+ * Processes the `on_chain_end` event emitted by the `agent_loop` node and
11
+ * yields either a token event (with the full response text) or an error event.
12
+ *
13
+ * Note on token streaming:
14
+ * We do NOT emit from `on_chat_model_stream` because `streamEvents` yields
15
+ * events from ALL model invocations, including nested ones
16
+ * (ExplicitIntentInferrer, SemanticVerifier, IntentReconciler, IntentIndexer)
17
+ * inside tools. Those emit structured JSON that must not reach the user. The
18
+ * chat agent uses `model.invoke()` so we don't get token-by-token streaming
19
+ * anyway. We only emit the clean final response from `on_chain_end`.
20
+ */
21
+ export class ResponseStreamer {
22
+ /**
23
+ * Processes an `on_chain_end` event whose name is `agent_loop`.
24
+ *
25
+ * @returns An array of stream events to yield (token and/or error), plus
26
+ * metadata for the caller to log.
27
+ */
28
+ handleAgentLoopEnd(sessionId, event) {
29
+ const output = event.data?.output;
30
+ const responseText = typeof output?.responseText === "string" ? output.responseText : "";
31
+ const agentError = typeof output?.error === "string" ? output.error : undefined;
32
+ logger.debug("Agent loop output", { output, responseText, agentError });
33
+ const events = [];
34
+ if (agentError) {
35
+ logger.warn("Agent loop returned error", { agentError });
36
+ events.push(createErrorEvent(sessionId, agentError === "JSON error injected into SSE stream"
37
+ ? "The response could not be sent correctly. Please try again."
38
+ : agentError, "AGENT_ERROR"));
39
+ }
40
+ if (responseText) {
41
+ events.push(createTokenEvent(sessionId, responseText));
42
+ }
43
+ return { events, responseText, hadError: !!agentError };
44
+ }
45
+ }
46
+ //# sourceMappingURL=response.streamer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"response.streamer.js","sourceRoot":"","sources":["../../src/streamers/response.streamer.ts"],"names":[],"mappings":"AACA,OAAO,EACL,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAE/D,MAAM,MAAM,GAAG,cAAc,CAAC,kBAAkB,CAAC,CAAC;AAElD,iFAAiF;AACjF,oBAAoB;AACpB,iFAAiF;AAEjF;;;;;;;;;;;;;GAaG;AACH,MAAM,OAAO,gBAAgB;IAC3B;;;;;OAKG;IACH,kBAAkB,CAChB,SAAiB,EACjB,KAAwE;QAExE,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC;QAClC,MAAM,YAAY,GAAG,OAAO,MAAM,EAAE,YAAY,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;QACzF,MAAM,UAAU,GAAG,OAAO,MAAM,EAAE,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;QAEhF,MAAM,CAAC,KAAK,CAAC,mBAAmB,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE,UAAU,EAAE,CAAC,CAAC;QAExE,MAAM,MAAM,GAAsB,EAAE,CAAC;QAErC,IAAI,UAAU,EAAE,CAAC;YACf,MAAM,CAAC,IAAI,CAAC,2BAA2B,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC;YACzD,MAAM,CAAC,IAAI,CACT,gBAAgB,CACd,SAAS,EACT,UAAU,KAAK,qCAAqC;gBAClD,CAAC,CAAC,6DAA6D;gBAC/D,CAAC,CAAC,UAAU,EACd,aAAa,CACd,CACF,CAAC;QACJ,CAAC;QAED,IAAI,YAAY,EAAE,CAAC;YACjB,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC,CAAC;QACzD,CAAC;QAED,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC,CAAC,UAAU,EAAE,CAAC;IAC1D,CAAC;CACF"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Token utilities for context window management.
3
+ * Estimates token counts and truncates message arrays to fit within model limits.
4
+ * Uses a simple heuristic (~4 chars per token for English).
5
+ */
6
+ import { BaseMessage } from "@langchain/core/messages";
7
+ /**
8
+ * Default maximum tokens to allow for context.
9
+ * Reserves space for system prompt and response generation.
10
+ */
11
+ export declare const MAX_CONTEXT_TOKENS = 8000;
12
+ /**
13
+ * Estimate token count for a string using a simple heuristic.
14
+ *
15
+ * This uses a rough estimate of ~4 characters per token, which works
16
+ * reasonably well for English text. For more accuracy with specific
17
+ * models, use tiktoken or the model's native tokenizer.
18
+ *
19
+ * @param text - The text to estimate tokens for
20
+ * @returns Estimated token count
21
+ */
22
+ export declare function estimateTokenCount(text: string): number;
23
+ /**
24
+ * Estimate token count for a message, including role overhead.
25
+ *
26
+ * @param message - The LangChain message to estimate
27
+ * @returns Estimated token count including message overhead
28
+ */
29
+ export declare function estimateMessageTokens(message: BaseMessage): number;
30
+ /**
31
+ * Truncate messages to fit within token limit, keeping most recent messages.
32
+ *
33
+ * Messages are processed from newest to oldest, accumulating until the
34
+ * token limit is reached. The first message (usually system) is always
35
+ * kept if present.
36
+ *
37
+ * @param messages - Array of messages to truncate
38
+ * @param maxTokens - Maximum total tokens allowed (default: MAX_CONTEXT_TOKENS)
39
+ * @returns Array of messages that fit within the token limit
40
+ */
41
+ export declare function truncateToTokenLimit(messages: BaseMessage[], maxTokens?: number): BaseMessage[];
42
+ //# sourceMappingURL=chat.utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat.utils.d.ts","sourceRoot":"","sources":["../../src/support/chat.utils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAEvD;;;GAGG;AACH,eAAO,MAAM,kBAAkB,OAAO,CAAC;AAKvC;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKvD;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAQlE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,WAAW,EAAE,EACvB,SAAS,GAAE,MAA2B,GACrC,WAAW,EAAE,CA2Cf"}
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Token utilities for context window management.
3
+ * Estimates token counts and truncates message arrays to fit within model limits.
4
+ * Uses a simple heuristic (~4 chars per token for English).
5
+ */
6
+ /**
7
+ * Default maximum tokens to allow for context.
8
+ * Reserves space for system prompt and response generation.
9
+ */
10
+ export const MAX_CONTEXT_TOKENS = 8000;
11
+ /** Minimum tokens to reserve for the model's response (internal use in truncateToTokenLimit). */
12
+ const RESERVED_RESPONSE_TOKENS = 2000;
13
+ /**
14
+ * Estimate token count for a string using a simple heuristic.
15
+ *
16
+ * This uses a rough estimate of ~4 characters per token, which works
17
+ * reasonably well for English text. For more accuracy with specific
18
+ * models, use tiktoken or the model's native tokenizer.
19
+ *
20
+ * @param text - The text to estimate tokens for
21
+ * @returns Estimated token count
22
+ */
23
+ export function estimateTokenCount(text) {
24
+ if (!text)
25
+ return 0;
26
+ // Rough estimate: ~4 characters per token for English
27
+ // This tends to slightly overestimate, which is safer for truncation
28
+ return Math.ceil(text.length / 4);
29
+ }
30
+ /**
31
+ * Estimate token count for a message, including role overhead.
32
+ *
33
+ * @param message - The LangChain message to estimate
34
+ * @returns Estimated token count including message overhead
35
+ */
36
+ export function estimateMessageTokens(message) {
37
+ const content = typeof message.content === "string"
38
+ ? message.content
39
+ : JSON.stringify(message.content);
40
+ // Add ~4 tokens overhead per message for role and formatting
41
+ return estimateTokenCount(content) + 4;
42
+ }
43
+ /**
44
+ * Truncate messages to fit within token limit, keeping most recent messages.
45
+ *
46
+ * Messages are processed from newest to oldest, accumulating until the
47
+ * token limit is reached. The first message (usually system) is always
48
+ * kept if present.
49
+ *
50
+ * @param messages - Array of messages to truncate
51
+ * @param maxTokens - Maximum total tokens allowed (default: MAX_CONTEXT_TOKENS)
52
+ * @returns Array of messages that fit within the token limit
53
+ */
54
+ export function truncateToTokenLimit(messages, maxTokens = MAX_CONTEXT_TOKENS) {
55
+ if (messages.length === 0)
56
+ return [];
57
+ // Calculate available tokens (reserve space for response)
58
+ const availableTokens = maxTokens - RESERVED_RESPONSE_TOKENS;
59
+ // If only one message, return it (truncation within message not supported)
60
+ if (messages.length === 1) {
61
+ return messages;
62
+ }
63
+ let totalTokens = 0;
64
+ const result = [];
65
+ // Check if first message is a system message (should always be kept)
66
+ const firstMessage = messages[0];
67
+ const hasSystemMessage = firstMessage._getType() === "system";
68
+ if (hasSystemMessage) {
69
+ const systemTokens = estimateMessageTokens(firstMessage);
70
+ totalTokens += systemTokens;
71
+ result.push(firstMessage);
72
+ }
73
+ // Process remaining messages from newest to oldest
74
+ const remainingMessages = hasSystemMessage ? messages.slice(1) : messages;
75
+ const recentMessages = [];
76
+ for (let i = remainingMessages.length - 1; i >= 0; i--) {
77
+ const msg = remainingMessages[i];
78
+ const msgTokens = estimateMessageTokens(msg);
79
+ if (totalTokens + msgTokens > availableTokens) {
80
+ // Stop adding more messages
81
+ break;
82
+ }
83
+ recentMessages.unshift(msg);
84
+ totalTokens += msgTokens;
85
+ }
86
+ // Combine system message (if any) with recent messages
87
+ return hasSystemMessage ? [firstMessage, ...recentMessages] : recentMessages;
88
+ }
89
+ //# sourceMappingURL=chat.utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat.utils.js","sourceRoot":"","sources":["../../src/support/chat.utils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,IAAI,CAAC;AAEvC,iGAAiG;AACjG,MAAM,wBAAwB,GAAG,IAAI,CAAC;AAEtC;;;;;;;;;GASG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAY;IAC7C,IAAI,CAAC,IAAI;QAAE,OAAO,CAAC,CAAC;IACpB,sDAAsD;IACtD,qEAAqE;IACrE,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AACpC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CAAC,OAAoB;IACxD,MAAM,OAAO,GACX,OAAO,OAAO,CAAC,OAAO,KAAK,QAAQ;QACjC,CAAC,CAAC,OAAO,CAAC,OAAO;QACjB,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAEtC,6DAA6D;IAC7D,OAAO,kBAAkB,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;AACzC,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,oBAAoB,CAClC,QAAuB,EACvB,YAAoB,kBAAkB;IAEtC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAErC,0DAA0D;IAC1D,MAAM,eAAe,GAAG,SAAS,GAAG,wBAAwB,CAAC;IAE7D,2EAA2E;IAC3E,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,MAAM,MAAM,GAAkB,EAAE,CAAC;IAEjC,qEAAqE;IACrE,MAAM,YAAY,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IACjC,MAAM,gBAAgB,GAAG,YAAY,CAAC,QAAQ,EAAE,KAAK,QAAQ,CAAC;IAE9D,IAAI,gBAAgB,EAAE,CAAC;QACrB,MAAM,YAAY,GAAG,qBAAqB,CAAC,YAAY,CAAC,CAAC;QACzD,WAAW,IAAI,YAAY,CAAC;QAC5B,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAC5B,CAAC;IAED,mDAAmD;IACnD,MAAM,iBAAiB,GAAG,gBAAgB,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;IAC1E,MAAM,cAAc,GAAkB,EAAE,CAAC;IAEzC,KAAK,IAAI,CAAC,GAAG,iBAAiB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QACvD,MAAM,GAAG,GAAG,iBAAiB,CAAC,CAAC,CAAC,CAAC;QACjC,MAAM,SAAS,GAAG,qBAAqB,CAAC,GAAG,CAAC,CAAC;QAE7C,IAAI,WAAW,GAAG,SAAS,GAAG,eAAe,EAAE,CAAC;YAC9C,4BAA4B;YAC5B,MAAM;QACR,CAAC;QAED,cAAc,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAC5B,WAAW,IAAI,SAAS,CAAC;IAC3B,CAAC;IAED,uDAAuD;IACvD,OAAO,gBAAgB,CAAC,CAAC,CAAC,CAAC,YAAY,EAAE,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC;AAC/E,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Sanitizes objects for inclusion in chat debug meta.
3
+ * Strips embeddings, truncates long strings, and handles circular refs.
4
+ */
5
+ /** Exported for tests that assert on circular-ref placeholder. */
6
+ export declare const SANITIZATION_ERROR_PLACEHOLDER = "[sanitization error]";
7
+ /**
8
+ * Sanitizes an object for safe inclusion in debug meta.
9
+ * - Replaces embedding/vector keys and long number arrays with placeholders.
10
+ * - Truncates strings over maxStringLength.
11
+ * - On circular reference or error, returns a placeholder string.
12
+ *
13
+ * @param obj - Value to sanitize (object, array, or primitive)
14
+ * @param maxStringLength - Max string length before truncation (default 2048)
15
+ * @returns Sanitized copy or "[sanitization error]" on failure
16
+ */
17
+ export declare function sanitizeForDebugMeta(obj: unknown, maxStringLength?: number): unknown;
18
+ //# sourceMappingURL=debug-meta.sanitizer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debug-meta.sanitizer.d.ts","sourceRoot":"","sources":["../../src/support/debug-meta.sanitizer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAUH,kEAAkE;AAClE,eAAO,MAAM,8BAA8B,yBAAyB,CAAC;AAwDrE;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,OAAO,EACZ,eAAe,GAAE,MAAkC,GAClD,OAAO,CAOT"}
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Sanitizes objects for inclusion in chat debug meta.
3
+ * Strips embeddings, truncates long strings, and handles circular refs.
4
+ */
5
+ const BLOCKLIST_KEYS = new Set([
6
+ "embedding",
7
+ "embeddingVector",
8
+ "vector",
9
+ ]);
10
+ const BLOCKLIST_SUFFIXES = ["Embedding", "Vector"];
11
+ const EMBEDDING_ARRAY_THRESHOLD = 100;
12
+ const DEFAULT_MAX_STRING_LENGTH = 2048;
13
+ /** Exported for tests that assert on circular-ref placeholder. */
14
+ export const SANITIZATION_ERROR_PLACEHOLDER = "[sanitization error]";
15
+ function isBlocklistedKey(key) {
16
+ if (BLOCKLIST_KEYS.has(key))
17
+ return true;
18
+ return BLOCKLIST_SUFFIXES.some((s) => key.endsWith(s));
19
+ }
20
+ function isNumberArray(arr) {
21
+ return Array.isArray(arr) && arr.length > 0 && typeof arr[0] === "number";
22
+ }
23
+ function truncateString(str, maxLen) {
24
+ if (str.length <= maxLen)
25
+ return str;
26
+ return `[truncated, ${str.length} chars]`;
27
+ }
28
+ function sanitizeValue(value, maxStringLength, seen) {
29
+ if (value === null || value === undefined)
30
+ return value;
31
+ if (typeof value === "number" || typeof value === "boolean")
32
+ return value;
33
+ if (typeof value === "string")
34
+ return truncateString(value, maxStringLength);
35
+ if (typeof value === "object") {
36
+ if (seen.has(value))
37
+ return SANITIZATION_ERROR_PLACEHOLDER;
38
+ seen.add(value);
39
+ if (Array.isArray(value)) {
40
+ if (isNumberArray(value) && value.length > EMBEDDING_ARRAY_THRESHOLD)
41
+ return `[embedding, length ${value.length}]`;
42
+ return value.map((item) => sanitizeValue(item, maxStringLength, seen));
43
+ }
44
+ const obj = value;
45
+ const out = {};
46
+ for (const [k, v] of Object.entries(obj)) {
47
+ if (isBlocklistedKey(k)) {
48
+ if (Array.isArray(v) && isNumberArray(v))
49
+ out[k] = `[embedding, length ${v.length}]`;
50
+ else if (Array.isArray(v))
51
+ out[k] = `[array, length ${v.length}]`;
52
+ else
53
+ out[k] = "[redacted]";
54
+ }
55
+ else {
56
+ out[k] = sanitizeValue(v, maxStringLength, seen);
57
+ }
58
+ }
59
+ return out;
60
+ }
61
+ return value;
62
+ }
63
+ /**
64
+ * Sanitizes an object for safe inclusion in debug meta.
65
+ * - Replaces embedding/vector keys and long number arrays with placeholders.
66
+ * - Truncates strings over maxStringLength.
67
+ * - On circular reference or error, returns a placeholder string.
68
+ *
69
+ * @param obj - Value to sanitize (object, array, or primitive)
70
+ * @param maxStringLength - Max string length before truncation (default 2048)
71
+ * @returns Sanitized copy or "[sanitization error]" on failure
72
+ */
73
+ export function sanitizeForDebugMeta(obj, maxStringLength = DEFAULT_MAX_STRING_LENGTH) {
74
+ try {
75
+ const seen = new WeakSet();
76
+ return sanitizeValue(obj, maxStringLength, seen);
77
+ }
78
+ catch {
79
+ return SANITIZATION_ERROR_PLACEHOLDER;
80
+ }
81
+ }
82
+ //# sourceMappingURL=debug-meta.sanitizer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debug-meta.sanitizer.js","sourceRoot":"","sources":["../../src/support/debug-meta.sanitizer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ /** Input for computing feed health score. */
2
+ export interface FeedHealthInput {
3
+ connectionCount: number;
4
+ connectorFlowCount: number;
5
+ expiredCount: number;
6
+ totalActionable: number;
7
+ /** Unix ms timestamp of last rediscovery, or null if never. */
8
+ lastRediscoveryAt: number | null;
9
+ /** Window in ms over which freshness decays from 1 → 0 (e.g. 12h). */
10
+ freshnessWindowMs: number;
11
+ /** Score threshold below which shouldMaintain is true. Default 0.5. */
12
+ threshold?: number;
13
+ }
14
+ /** Output of feed health computation. */
15
+ export interface FeedHealthResult {
16
+ score: number;
17
+ breakdown: {
18
+ composition: number;
19
+ freshness: number;
20
+ expirationRatio: number;
21
+ };
22
+ shouldMaintain: boolean;
23
+ }
24
+ /**
25
+ * Compute feed health score (0–1) from current feed state.
26
+ * Pure function, no side effects.
27
+ *
28
+ * @param input - Current feed composition and timing data
29
+ * @returns Health score with breakdown and maintenance recommendation
30
+ */
31
+ export declare function computeFeedHealth(input: FeedHealthInput): FeedHealthResult;
32
+ //# sourceMappingURL=feed.health.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feed.health.d.ts","sourceRoot":"","sources":["../../src/support/feed.health.ts"],"names":[],"mappings":"AAEA,6CAA6C;AAC7C,MAAM,WAAW,eAAe;IAC9B,eAAe,EAAE,MAAM,CAAC;IACxB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,+DAA+D;IAC/D,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,sEAAsE;IACtE,iBAAiB,EAAE,MAAM,CAAC;IAC1B,uEAAuE;IACvE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,yCAAyC;AACzC,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE;QACT,WAAW,EAAE,MAAM,CAAC;QACpB,SAAS,EAAE,MAAM,CAAC;QAClB,eAAe,EAAE,MAAM,CAAC;KACzB,CAAC;IACF,cAAc,EAAE,OAAO,CAAC;CACzB;AAiDD;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,eAAe,GAAG,gBAAgB,CAkC1E"}
@@ -0,0 +1,76 @@
1
+ import { FEED_SOFT_TARGETS } from './opportunity.utils.js';
2
+ const WEIGHT_COMPOSITION = 0.4;
3
+ const WEIGHT_FRESHNESS = 0.3;
4
+ const WEIGHT_EXPIRATION = 0.3;
5
+ const DEFAULT_THRESHOLD = 0.5;
6
+ /**
7
+ * Compute composition sub-score: how close current counts are to soft targets.
8
+ * Uses normalized distance: 1 - (|actual - target| / max(target, actual, 1)) per category,
9
+ * then averages across categories.
10
+ */
11
+ function scoreComposition(connectionCount, connectorFlowCount, expiredCount) {
12
+ const categories = [
13
+ { actual: connectionCount, target: FEED_SOFT_TARGETS.connection },
14
+ { actual: connectorFlowCount, target: FEED_SOFT_TARGETS.connectorFlow },
15
+ { actual: expiredCount, target: FEED_SOFT_TARGETS.expired },
16
+ ];
17
+ let totalScore = 0;
18
+ for (const { actual, target } of categories) {
19
+ const diff = Math.abs(actual - target);
20
+ const denom = Math.max(target, actual, 1);
21
+ totalScore += 1 - diff / denom;
22
+ }
23
+ return totalScore / categories.length;
24
+ }
25
+ /**
26
+ * Compute freshness sub-score: linear decay from 1 → 0 over freshnessWindowMs.
27
+ */
28
+ function scoreFreshness(lastRediscoveryAt, freshnessWindowMs) {
29
+ if (lastRediscoveryAt == null)
30
+ return 0;
31
+ const elapsed = Date.now() - lastRediscoveryAt;
32
+ if (elapsed <= 0)
33
+ return 1;
34
+ if (elapsed >= freshnessWindowMs)
35
+ return 0;
36
+ return 1 - elapsed / freshnessWindowMs;
37
+ }
38
+ /**
39
+ * Compute expiration ratio sub-score: 1 - (expired / total).
40
+ */
41
+ function scoreExpirationRatio(expiredCount, totalActionable) {
42
+ const total = totalActionable + expiredCount;
43
+ if (total === 0)
44
+ return 0;
45
+ return 1 - expiredCount / total;
46
+ }
47
+ /**
48
+ * Compute feed health score (0–1) from current feed state.
49
+ * Pure function, no side effects.
50
+ *
51
+ * @param input - Current feed composition and timing data
52
+ * @returns Health score with breakdown and maintenance recommendation
53
+ */
54
+ export function computeFeedHealth(input) {
55
+ const { connectionCount, connectorFlowCount, expiredCount, totalActionable, lastRediscoveryAt, freshnessWindowMs, threshold = DEFAULT_THRESHOLD, } = input;
56
+ // Empty feed is always unhealthy
57
+ if (totalActionable === 0 && expiredCount === 0) {
58
+ return {
59
+ score: 0,
60
+ breakdown: { composition: 0, freshness: 0, expirationRatio: 0 },
61
+ shouldMaintain: true,
62
+ };
63
+ }
64
+ const composition = scoreComposition(connectionCount, connectorFlowCount, expiredCount);
65
+ const freshness = scoreFreshness(lastRediscoveryAt, freshnessWindowMs);
66
+ const expirationRatio = scoreExpirationRatio(expiredCount, totalActionable);
67
+ const score = WEIGHT_COMPOSITION * composition +
68
+ WEIGHT_FRESHNESS * freshness +
69
+ WEIGHT_EXPIRATION * expirationRatio;
70
+ return {
71
+ score,
72
+ breakdown: { composition, freshness, expirationRatio },
73
+ shouldMaintain: score < threshold,
74
+ };
75
+ }
76
+ //# sourceMappingURL=feed.health.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feed.health.js","sourceRoot":"","sources":["../../src/support/feed.health.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Introducer Discovery: proactive discovery of connector-flow opportunities
3
+ * between a user's contacts.
4
+ *
5
+ * Selects top-N contacts from the user's personal index and runs scoped
6
+ * HyDE discovery for each, creating latent introducer opportunities that
7
+ * the user (as introducer) must approve before parties see them.
8
+ */
9
+ /** Maximum contacts to evaluate per maintenance cycle. */
10
+ export declare const MAX_CONTACTS_PER_CYCLE = 5;
11
+ /** Maximum candidate opportunities per contact. */
12
+ export declare const MAX_CANDIDATES_PER_CONTACT = 3;
13
+ /** Detection source value for introducer-discovered opportunities. */
14
+ export declare const INTRODUCER_DISCOVERY_SOURCE: "introducer_discovery";
15
+ /** A contact with their active intents, used for introducer discovery selection. */
16
+ export interface ContactWithIntents {
17
+ userId: string;
18
+ /** Most recent intent updatedAt timestamp (ISO string or null). */
19
+ latestIntentAt: string | null;
20
+ /** Number of active intents this contact has. */
21
+ intentCount: number;
22
+ }
23
+ /** Database methods needed for introducer discovery contact selection. */
24
+ export interface IntroducerDiscoveryDatabase {
25
+ /** Get the user's personal index ID. */
26
+ getPersonalIndexId(userId: string): Promise<string | null>;
27
+ /** Get contacts from a personal index with their intent freshness data. */
28
+ getContactsWithIntentFreshness(personalIndexId: string, ownerId: string, limit: number): Promise<ContactWithIntents[]>;
29
+ }
30
+ /** Queue interface for enqueuing introducer discovery jobs. */
31
+ export interface IntroducerDiscoveryQueue {
32
+ addJob(data: {
33
+ intentId: string;
34
+ userId: string;
35
+ indexIds?: string[];
36
+ contactUserId?: string;
37
+ }, options?: {
38
+ priority?: number;
39
+ jobId?: string;
40
+ }): Promise<unknown>;
41
+ }
42
+ /** Result of a single introducer discovery cycle. */
43
+ export interface IntroducerDiscoveryResult {
44
+ contactsEvaluated: number;
45
+ jobsEnqueued: number;
46
+ skippedReason?: string;
47
+ }
48
+ /**
49
+ * Select top-N contacts for introducer discovery, sorted by intent freshness.
50
+ * Contacts with no active intents are excluded.
51
+ *
52
+ * @param database - Database adapter with contact/intent queries
53
+ * @param userId - The introducer user
54
+ * @param limit - Max contacts to return (default MAX_CONTACTS_PER_CYCLE)
55
+ * @returns Sorted contacts with intent data
56
+ */
57
+ export declare function selectContactsForDiscovery(database: IntroducerDiscoveryDatabase, userId: string, limit?: number): Promise<ContactWithIntents[]>;
58
+ /**
59
+ * Determine whether introducer discovery should run based on the current
60
+ * connector-flow composition. Triggers when connector-flow count is below
61
+ * the soft target.
62
+ *
63
+ * @param connectorFlowCount - Current number of connector-flow opportunities
64
+ * @param connectorFlowTarget - Soft target (default 2)
65
+ * @returns Whether introducer discovery should run
66
+ */
67
+ export declare function shouldRunIntroducerDiscovery(connectorFlowCount: number, connectorFlowTarget?: number): boolean;
68
+ /**
69
+ * Run introducer discovery for a user: select contacts, enqueue discovery jobs.
70
+ * Each job uses onBehalfOfUserId so the opportunity graph treats the user as introducer.
71
+ *
72
+ * @param database - Database adapter for contact queries
73
+ * @param queue - Queue for enqueuing discovery jobs
74
+ * @param userId - The introducer user
75
+ * @returns Summary of the discovery cycle
76
+ */
77
+ export declare function runIntroducerDiscovery(database: IntroducerDiscoveryDatabase, queue: IntroducerDiscoveryQueue, userId: string): Promise<IntroducerDiscoveryResult>;
78
+ //# sourceMappingURL=introducer.discovery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"introducer.discovery.d.ts","sourceRoot":"","sources":["../../src/support/introducer.discovery.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,0DAA0D;AAC1D,eAAO,MAAM,sBAAsB,IAAI,CAAC;AAExC,mDAAmD;AACnD,eAAO,MAAM,0BAA0B,IAAI,CAAC;AAE5C,sEAAsE;AACtE,eAAO,MAAM,2BAA2B,EAAG,sBAA+B,CAAC;AAE3E,oFAAoF;AACpF,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,mEAAmE;IACnE,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,iDAAiD;IACjD,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,0EAA0E;AAC1E,MAAM,WAAW,2BAA2B;IAC1C,wCAAwC;IACxC,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC3D,2EAA2E;IAC3E,8BAA8B,CAC5B,eAAe,EAAE,MAAM,EACvB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAAC;CAClC;AAED,+DAA+D;AAC/D,MAAM,WAAW,wBAAwB;IACvC,MAAM,CACJ,IAAI,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,aAAa,CAAC,EAAE,MAAM,CAAA;KAAE,EACvF,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAC9C,OAAO,CAAC,OAAO,CAAC,CAAC;CACrB;AAED,qDAAqD;AACrD,MAAM,WAAW,yBAAyB;IACxC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;;GAQG;AACH,wBAAsB,0BAA0B,CAC9C,QAAQ,EAAE,2BAA2B,EACrC,MAAM,EAAE,MAAM,EACd,KAAK,GAAE,MAA+B,GACrC,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAgB/B;AAED;;;;;;;;GAQG;AACH,wBAAgB,4BAA4B,CAC1C,kBAAkB,EAAE,MAAM,EAC1B,mBAAmB,GAAE,MAAU,GAC9B,OAAO,CAET;AAED;;;;;;;;GAQG;AACH,wBAAsB,sBAAsB,CAC1C,QAAQ,EAAE,2BAA2B,EACrC,KAAK,EAAE,wBAAwB,EAC/B,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,yBAAyB,CAAC,CAqDpC"}
@@ -0,0 +1,101 @@
1
+ /**
2
+ * Introducer Discovery: proactive discovery of connector-flow opportunities
3
+ * between a user's contacts.
4
+ *
5
+ * Selects top-N contacts from the user's personal index and runs scoped
6
+ * HyDE discovery for each, creating latent introducer opportunities that
7
+ * the user (as introducer) must approve before parties see them.
8
+ */
9
+ import { protocolLogger } from './protocol.logger.js';
10
+ const logger = protocolLogger('IntroducerDiscovery');
11
+ /** Maximum contacts to evaluate per maintenance cycle. */
12
+ export const MAX_CONTACTS_PER_CYCLE = 5;
13
+ /** Maximum candidate opportunities per contact. */
14
+ export const MAX_CANDIDATES_PER_CONTACT = 3;
15
+ /** Detection source value for introducer-discovered opportunities. */
16
+ export const INTRODUCER_DISCOVERY_SOURCE = 'introducer_discovery';
17
+ /**
18
+ * Select top-N contacts for introducer discovery, sorted by intent freshness.
19
+ * Contacts with no active intents are excluded.
20
+ *
21
+ * @param database - Database adapter with contact/intent queries
22
+ * @param userId - The introducer user
23
+ * @param limit - Max contacts to return (default MAX_CONTACTS_PER_CYCLE)
24
+ * @returns Sorted contacts with intent data
25
+ */
26
+ export async function selectContactsForDiscovery(database, userId, limit = MAX_CONTACTS_PER_CYCLE) {
27
+ const personalIndexId = await database.getPersonalIndexId(userId);
28
+ if (!personalIndexId) {
29
+ logger.verbose(`[IntroducerDiscovery] No personal index found — userId=${userId}`);
30
+ return [];
31
+ }
32
+ const contacts = await database.getContactsWithIntentFreshness(personalIndexId, userId, limit);
33
+ logger.verbose(`[IntroducerDiscovery] Selected contacts for discovery — userId=${userId} totalContacts=${contacts.length} limit=${limit}`);
34
+ return contacts;
35
+ }
36
+ /**
37
+ * Determine whether introducer discovery should run based on the current
38
+ * connector-flow composition. Triggers when connector-flow count is below
39
+ * the soft target.
40
+ *
41
+ * @param connectorFlowCount - Current number of connector-flow opportunities
42
+ * @param connectorFlowTarget - Soft target (default 2)
43
+ * @returns Whether introducer discovery should run
44
+ */
45
+ export function shouldRunIntroducerDiscovery(connectorFlowCount, connectorFlowTarget = 2) {
46
+ return connectorFlowCount < connectorFlowTarget;
47
+ }
48
+ /**
49
+ * Run introducer discovery for a user: select contacts, enqueue discovery jobs.
50
+ * Each job uses onBehalfOfUserId so the opportunity graph treats the user as introducer.
51
+ *
52
+ * @param database - Database adapter for contact queries
53
+ * @param queue - Queue for enqueuing discovery jobs
54
+ * @param userId - The introducer user
55
+ * @returns Summary of the discovery cycle
56
+ */
57
+ export async function runIntroducerDiscovery(database, queue, userId) {
58
+ const personalIndexId = await database.getPersonalIndexId(userId);
59
+ if (!personalIndexId) {
60
+ return { contactsEvaluated: 0, jobsEnqueued: 0, skippedReason: 'no_personal_index' };
61
+ }
62
+ const contacts = await selectContactsForDiscovery(database, userId);
63
+ if (contacts.length === 0) {
64
+ return { contactsEvaluated: 0, jobsEnqueued: 0, skippedReason: 'no_contacts' };
65
+ }
66
+ const bucket = Math.floor(Date.now() / (12 * 60 * 60 * 1000)); // 12h dedup bucket
67
+ let jobsEnqueued = 0;
68
+ const results = await Promise.allSettled(contacts.map(async (contact) => {
69
+ // For each contact, we enqueue a discovery job using one of their intents
70
+ // The opportunity graph will use onBehalfOfUserId to discover on behalf of the contact
71
+ // while the userId (introducer) gets the introducer role
72
+ const jobId = `introducer-discovery-${userId}-${contact.userId}-${bucket}`;
73
+ try {
74
+ await queue.addJob({
75
+ intentId: `introducer:${contact.userId}`,
76
+ userId,
77
+ indexIds: [personalIndexId],
78
+ contactUserId: contact.userId,
79
+ }, { priority: 15, jobId });
80
+ return true;
81
+ }
82
+ catch (err) {
83
+ const message = err instanceof Error ? err.message : String(err);
84
+ if (/duplicate|already exists|job.*id/i.test(message)) {
85
+ logger.verbose(`[IntroducerDiscovery] Job skipped (duplicate) — userId=${userId} contactUserId=${contact.userId} error=${message}`);
86
+ return false;
87
+ }
88
+ throw err;
89
+ }
90
+ }));
91
+ for (const r of results) {
92
+ if (r.status === 'rejected') {
93
+ const errMsg = r.reason instanceof Error ? r.reason.message : String(r.reason);
94
+ logger.error(`[IntroducerDiscovery] Job enqueue failed: ${errMsg}`);
95
+ }
96
+ }
97
+ jobsEnqueued = results.filter((r) => r.status === 'fulfilled' && r.value).length;
98
+ logger.info(`[IntroducerDiscovery] Discovery cycle complete — userId=${userId} contactsEvaluated=${contacts.length} jobsEnqueued=${jobsEnqueued}`);
99
+ return { contactsEvaluated: contacts.length, jobsEnqueued };
100
+ }
101
+ //# sourceMappingURL=introducer.discovery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"introducer.discovery.js","sourceRoot":"","sources":["../../src/support/introducer.discovery.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,MAAM,MAAM,GAAG,cAAc,CAAC,qBAAqB,CAAC,CAAC;AAErD,0DAA0D;AAC1D,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC;AAExC,mDAAmD;AACnD,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,CAAC;AAE5C,sEAAsE;AACtE,MAAM,CAAC,MAAM,2BAA2B,GAAG,sBAA+B,CAAC;AAsC3E;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAC9C,QAAqC,EACrC,MAAc,EACd,QAAgB,sBAAsB;IAEtC,MAAM,eAAe,GAAG,MAAM,QAAQ,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAClE,IAAI,CAAC,eAAe,EAAE,CAAC;QACrB,MAAM,CAAC,OAAO,CAAC,0DAA0D,MAAM,EAAE,CAAC,CAAC;QACnF,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,8BAA8B,CAC5D,eAAe,EACf,MAAM,EACN,KAAK,CACN,CAAC;IAEF,MAAM,CAAC,OAAO,CAAC,kEAAkE,MAAM,kBAAkB,QAAQ,CAAC,MAAM,UAAU,KAAK,EAAE,CAAC,CAAC;IAE3I,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,4BAA4B,CAC1C,kBAA0B,EAC1B,sBAA8B,CAAC;IAE/B,OAAO,kBAAkB,GAAG,mBAAmB,CAAC;AAClD,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,QAAqC,EACrC,KAA+B,EAC/B,MAAc;IAEd,MAAM,eAAe,GAAG,MAAM,QAAQ,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAClE,IAAI,CAAC,eAAe,EAAE,CAAC;QACrB,OAAO,EAAE,iBAAiB,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,aAAa,EAAE,mBAAmB,EAAE,CAAC;IACvF,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,0BAA0B,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACpE,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,EAAE,iBAAiB,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,aAAa,EAAE,aAAa,EAAE,CAAC;IACjF,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,mBAAmB;IAClF,IAAI,YAAY,GAAG,CAAC,CAAC;IAErB,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,CACtC,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;QAC7B,0EAA0E;QAC1E,uFAAuF;QACvF,yDAAyD;QACzD,MAAM,KAAK,GAAG,wBAAwB,MAAM,IAAI,OAAO,CAAC,MAAM,IAAI,MAAM,EAAE,CAAC;QAC3E,IAAI,CAAC;YACH,MAAM,KAAK,CAAC,MAAM,CAChB;gBACE,QAAQ,EAAE,cAAc,OAAO,CAAC,MAAM,EAAE;gBACxC,MAAM;gBACN,QAAQ,EAAE,CAAC,eAAe,CAAC;gBAC3B,aAAa,EAAE,OAAO,CAAC,MAAM;aAC9B,EACD,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,CACxB,CAAC;YACF,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjE,IAAI,mCAAmC,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;gBACtD,MAAM,CAAC,OAAO,CAAC,0DAA0D,MAAM,kBAAkB,OAAO,CAAC,MAAM,UAAU,OAAO,EAAE,CAAC,CAAC;gBACpI,OAAO,KAAK,CAAC;YACf,CAAC;YACD,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC,CAAC,CACH,CAAC;IAEF,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,IAAI,CAAC,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;YAC5B,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;YAC/E,MAAM,CAAC,KAAK,CAAC,6CAA6C,MAAM,EAAE,CAAC,CAAC;QACtE,CAAC;IACH,CAAC;IACD,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,WAAW,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC;IAEjF,MAAM,CAAC,IAAI,CAAC,2DAA2D,MAAM,sBAAsB,QAAQ,CAAC,MAAM,iBAAiB,YAAY,EAAE,CAAC,CAAC;IAEnJ,OAAO,EAAE,iBAAiB,EAAE,QAAQ,CAAC,MAAM,EAAE,YAAY,EAAE,CAAC;AAC9D,CAAC"}