@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,884 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ import { AIMessage, SystemMessage, ToolMessage, } from "@langchain/core/messages";
11
+ import { createChatTools, } from "../tools/index.js";
12
+ import { resolveChatContext } from "../tools/tool.helpers.js";
13
+ import { ITERATION_NUDGE, buildSystemContent } from "./chat.prompt.js";
14
+ import { extractRecentToolCalls, } from "./chat.prompt.modules.js";
15
+ import { protocolLogger } from "../support/protocol.logger.js";
16
+ import { createModel } from "./model.config.js";
17
+ import { sanitizeForDebugMeta } from "../support/debug-meta.sanitizer.js";
18
+ import { Timed } from "../support/performance.js";
19
+ import { requestContext } from "../support/request-context.js";
20
+ const logger = protocolLogger("ChatAgent");
21
+ // Re-export for external consumers
22
+ export { ITERATION_NUDGE } from "./chat.prompt.js";
23
+ // ═══════════════════════════════════════════════════════════════════════════════
24
+ // CONFIGURATION
25
+ // ═══════════════════════════════════════════════════════════════════════════════
26
+ /**
27
+ * Soft limit: After this many iterations, inject a nudge message.
28
+ */
29
+ export const SOFT_ITERATION_LIMIT = 8;
30
+ /**
31
+ * Hard limit: Force exit after this many iterations to prevent infinite loops.
32
+ */
33
+ export const HARD_ITERATION_LIMIT = 12;
34
+ /**
35
+ * Extract plain text from message content (string or structured block array).
36
+ * Filters to only `type: "text"` blocks, discarding tool metadata.
37
+ */
38
+ function extractTextContent(content) {
39
+ if (typeof content === "string")
40
+ return content;
41
+ if (Array.isArray(content)) {
42
+ return content
43
+ .filter((b) => b.type === "text")
44
+ .map((b) => b.text ?? "")
45
+ .join("");
46
+ }
47
+ return "";
48
+ }
49
+ /**
50
+ * Extract plain text from an AIMessageChunk (string content or text blocks).
51
+ */
52
+ function extractTextFromChunk(chunk) {
53
+ return extractTextContent(chunk.content);
54
+ }
55
+ /**
56
+ * ChatAgent: ReAct-style agent that uses tools to help users.
57
+ *
58
+ * The agent operates in a loop:
59
+ * 1. Receive messages (conversation history + tool results)
60
+ * 2. Decide: call tools OR respond to user
61
+ * 3. If tools called: execute them, add results, loop back
62
+ * 4. If response: return final text
63
+ *
64
+ * Use `ChatAgent.create(context)` to construct (async factory).
65
+ */
66
+ export class ChatAgent {
67
+ /**
68
+ * Private constructor — use `ChatAgent.create()` instead.
69
+ */
70
+ constructor(resolvedContext, tools) {
71
+ this.resolvedContext = resolvedContext;
72
+ this.model = createModel("chat");
73
+ // Store tools and index by name
74
+ this.tools = tools;
75
+ this.toolsByName = new Map();
76
+ for (const tool of this.tools) {
77
+ this.toolsByName.set(tool.name, tool);
78
+ }
79
+ // Bind tools to model
80
+ this.model = this.model.bindTools(this.tools);
81
+ }
82
+ /**
83
+ * Extracts the text content of the most recent HumanMessage.
84
+ */
85
+ static getCurrentUserMessage(messages) {
86
+ for (let i = messages.length - 1; i >= 0; i--) {
87
+ if (messages[i]._getType() === "human") {
88
+ const content = messages[i].content;
89
+ return typeof content === "string" ? content : undefined;
90
+ }
91
+ }
92
+ return undefined;
93
+ }
94
+ /**
95
+ * Async factory: creates a ChatAgent with resolved user/index context.
96
+ * Resolves user/index identity from DB during tool initialization.
97
+ */
98
+ static async create(context) {
99
+ const resolved = await resolveChatContext({
100
+ database: context.database,
101
+ userId: context.userId,
102
+ indexId: context.indexId,
103
+ sessionId: context.sessionId,
104
+ });
105
+ const tools = await createChatTools(context, resolved);
106
+ return new ChatAgent(resolved, tools);
107
+ }
108
+ /**
109
+ * Run a single iteration of the agent loop.
110
+ *
111
+ * @param messages - Current conversation including any tool results
112
+ * @param iterationCount - Current iteration number (for soft limit)
113
+ * @returns Result indicating whether to continue and any tool calls/response
114
+ */
115
+ async runIteration(messages, iterationCount) {
116
+ const iterCtx = {
117
+ recentTools: extractRecentToolCalls(messages),
118
+ currentMessage: ChatAgent.getCurrentUserMessage(messages),
119
+ ctx: this.resolvedContext,
120
+ };
121
+ const systemContent = buildSystemContent(this.resolvedContext, iterCtx);
122
+ const fullMessages = [
123
+ new SystemMessage(systemContent),
124
+ ...messages,
125
+ ];
126
+ // Add nudge if past soft limit
127
+ if (iterationCount >= SOFT_ITERATION_LIMIT) {
128
+ fullMessages.push(new SystemMessage(ITERATION_NUDGE));
129
+ }
130
+ logger.verbose("Agent iteration", {
131
+ iteration: iterationCount,
132
+ messageCount: messages.length,
133
+ pastSoftLimit: iterationCount >= SOFT_ITERATION_LIMIT,
134
+ });
135
+ // Invoke model
136
+ const response = await this.model.invoke(fullMessages);
137
+ logger.debug("Chat model response", {
138
+ content: typeof response.content === "string"
139
+ ? response.content
140
+ : JSON.stringify(response.content),
141
+ toolCalls: response.tool_calls?.length ?? 0,
142
+ toolCallNames: response.tool_calls?.map((tc) => tc.name) ?? [],
143
+ });
144
+ // Check if model made tool calls
145
+ const toolCalls = response.tool_calls || [];
146
+ if (toolCalls.length > 0) {
147
+ logger.verbose("Agent made tool calls", {
148
+ iteration: iterationCount,
149
+ toolCount: toolCalls.length,
150
+ tools: toolCalls.map((tc) => tc.name),
151
+ });
152
+ // Execute tools (can be parallelized if independent)
153
+ const toolResults = await this.executeToolCalls(toolCalls);
154
+ // Build updated messages
155
+ const updatedMessages = [
156
+ ...messages,
157
+ response, // AIMessage with tool_calls
158
+ ...toolResults.map((tr) => new ToolMessage({
159
+ tool_call_id: tr.toolCallId,
160
+ content: tr.result,
161
+ name: tr.name,
162
+ })),
163
+ ];
164
+ return {
165
+ shouldContinue: true,
166
+ toolCalls: toolCalls.map((tc) => ({
167
+ id: tc.id,
168
+ name: tc.name,
169
+ args: tc.args,
170
+ })),
171
+ toolResults,
172
+ messages: updatedMessages,
173
+ };
174
+ }
175
+ // No tool calls - agent is responding
176
+ const responseText = extractTextContent(response.content);
177
+ logger.debug("Agent produced response (raw)", {
178
+ iteration: iterationCount,
179
+ responseText,
180
+ });
181
+ logger.verbose("Agent produced response", {
182
+ iteration: iterationCount,
183
+ responseLength: responseText.length,
184
+ });
185
+ return {
186
+ shouldContinue: false,
187
+ responseText,
188
+ messages: [...messages, response],
189
+ };
190
+ }
191
+ /**
192
+ * Execute tool calls, potentially in parallel.
193
+ */
194
+ async executeToolCalls(toolCalls) {
195
+ // Execute all tool calls in parallel
196
+ const results = await Promise.all(toolCalls.map(async (tc) => {
197
+ const tool = this.toolsByName.get(tc.name);
198
+ if (!tool) {
199
+ logger.error("Unknown tool", { name: tc.name });
200
+ return {
201
+ toolCallId: tc.id || `unknown-${Date.now()}`,
202
+ name: tc.name,
203
+ result: JSON.stringify({
204
+ success: false,
205
+ error: `Unknown tool: ${tc.name}`,
206
+ }),
207
+ };
208
+ }
209
+ try {
210
+ logger.verbose("Executing tool", { name: tc.name, args: tc.args });
211
+ let result = await tool.invoke(tc.args);
212
+ let resultStr = typeof result === "string" ? result : JSON.stringify(result);
213
+ if (tc.name === "create_opportunities") {
214
+ const newResult = await this.handleCreateIntentCallback(resultStr, tc.args);
215
+ if (newResult !== null) {
216
+ resultStr = newResult;
217
+ result = newResult;
218
+ }
219
+ }
220
+ logger.debug("Tool response", { name: tc.name, result: resultStr });
221
+ logger.verbose("Tool completed", {
222
+ name: tc.name,
223
+ resultLength: resultStr.length,
224
+ });
225
+ return {
226
+ toolCallId: tc.id || `${tc.name}-${Date.now()}`,
227
+ name: tc.name,
228
+ result: resultStr,
229
+ };
230
+ }
231
+ catch (error) {
232
+ logger.error("Tool execution failed", {
233
+ name: tc.name,
234
+ error: error instanceof Error ? error.message : String(error),
235
+ });
236
+ return {
237
+ toolCallId: tc.id || `${tc.name}-${Date.now()}`,
238
+ name: tc.name,
239
+ result: JSON.stringify({
240
+ success: false,
241
+ error: `Tool execution failed: ${error instanceof Error ? error.message : "Unknown error"}`,
242
+ }),
243
+ };
244
+ }
245
+ }));
246
+ return results;
247
+ }
248
+ /**
249
+ * When create_opportunities returned createIntentSuggested, call create_intent then create_opportunities.
250
+ * Returns the new create_opportunities result string or null if no callback / create_intent failed.
251
+ */
252
+ async handleCreateIntentCallback(resultStr, originalArgs) {
253
+ let parsed;
254
+ try {
255
+ parsed = JSON.parse(resultStr);
256
+ }
257
+ catch {
258
+ return null;
259
+ }
260
+ if (!parsed?.data?.createIntentSuggested ||
261
+ typeof parsed.data.suggestedIntentDescription !== "string") {
262
+ return null;
263
+ }
264
+ // Never auto-create intents during introducer flows — signals are personal
265
+ if (originalArgs.introTargetUserId) {
266
+ return null;
267
+ }
268
+ const createIntentTool = this.toolsByName.get("create_intent");
269
+ const createOpportunitiesTool = this.toolsByName.get("create_opportunities");
270
+ if (!createIntentTool || !createOpportunitiesTool)
271
+ return null;
272
+ logger.verbose("Create-intent signal: auto-calling create_intent then create_opportunities");
273
+ const createIntentResult = await createIntentTool.invoke({
274
+ description: parsed.data.suggestedIntentDescription,
275
+ indexId: originalArgs.indexId,
276
+ });
277
+ const createIntentStr = typeof createIntentResult === "string" ? createIntentResult : JSON.stringify(createIntentResult);
278
+ let createIntentParsed;
279
+ try {
280
+ createIntentParsed = JSON.parse(createIntentStr);
281
+ }
282
+ catch {
283
+ createIntentParsed = {};
284
+ }
285
+ if (createIntentParsed.success === false) {
286
+ logger.warn("Create-intent failed; not re-running create_opportunities", {
287
+ error: createIntentParsed.error,
288
+ });
289
+ return null;
290
+ }
291
+ const newResult = await createOpportunitiesTool.invoke(originalArgs);
292
+ return typeof newResult === "string" ? newResult : JSON.stringify(newResult);
293
+ }
294
+ /**
295
+ * Detect hallucinated ```intent_proposal or ```opportunity blocks in model text
296
+ * that were NOT generated by the corresponding tool call.
297
+ *
298
+ * A tool call that returned 0 cards (e.g. "Found 0 match(es)") counts as
299
+ * NOT having produced valid blocks — the LLM must not fabricate them.
300
+ *
301
+ * @returns Block info if hallucination detected, null otherwise
302
+ */
303
+ detectHallucinatedBlock(text, toolsUsed) {
304
+ // Only trust successful tool calls that actually returned results.
305
+ // A call that returned "Found 0 match(es)" doesn't produce valid blocks.
306
+ const hasSuccessfulCreateIntent = toolsUsed.some((t) => t.name === "create_intent" && t.success);
307
+ const hasSuccessfulCreateOpportunities = toolsUsed.some((t) => t.name === "create_opportunities" &&
308
+ t.success &&
309
+ !t.resultSummary?.startsWith("Found 0") &&
310
+ !t.resultSummary?.startsWith("No matches"));
311
+ // Check for hallucinated intent_proposal
312
+ if (text.includes("```intent_proposal") && !hasSuccessfulCreateIntent) {
313
+ const match = text.match(/```intent_proposal\s*\n\s*\{[^}]*"description"\s*:\s*"([^"]+)"/);
314
+ if (match) {
315
+ return { type: "intent_proposal", tool: "create_intent", description: match[1] };
316
+ }
317
+ }
318
+ // Check for hallucinated opportunity blocks
319
+ if (text.includes("```opportunity") && !hasSuccessfulCreateOpportunities) {
320
+ // Extract a search query from the hallucinated block for the correction call
321
+ const nameMatch = text.match(/```opportunity\s*\n\s*\{[^}]*"name"\s*:\s*"([^"]+)"/);
322
+ const reasoningMatch = text.match(/```opportunity\s*\n\s*\{[^}]*"reasoning"\s*:\s*"([^"]+)"/);
323
+ const description = nameMatch?.[1] || reasoningMatch?.[1] || "find connections";
324
+ return { type: "opportunity", tool: "create_opportunities", description };
325
+ }
326
+ return null;
327
+ }
328
+ /**
329
+ * Strip ```opportunity and ```intent_proposal code blocks from text
330
+ * when no corresponding successful tool call was made.
331
+ * Defense-in-depth: catches hallucinated blocks that slip past detectHallucinatedBlock
332
+ * (e.g. after a correction iteration that still hallucinates).
333
+ *
334
+ * @param text - The response text to sanitize
335
+ * @param toolsUsed - Tool call records from the agent loop
336
+ * @returns Sanitized text with unbacked blocks removed
337
+ */
338
+ stripUnbackedBlocks(text, toolsUsed) {
339
+ let result = text;
340
+ let removedBlock = false;
341
+ const hasSuccessfulCreateOpportunities = toolsUsed.some((t) => t.name === "create_opportunities" &&
342
+ t.success &&
343
+ !t.resultSummary?.startsWith("Found 0") &&
344
+ !t.resultSummary?.startsWith("No matches"));
345
+ const hasSuccessfulCreateIntent = toolsUsed.some((t) => t.name === "create_intent" && t.success);
346
+ if (!hasSuccessfulCreateOpportunities && result.includes("```opportunity")) {
347
+ const next = result.replace(/```opportunity\s*\n[\s\S]*?```/g, "");
348
+ removedBlock || (removedBlock = next !== result);
349
+ result = next;
350
+ }
351
+ if (!hasSuccessfulCreateIntent && result.includes("```intent_proposal")) {
352
+ const next = result.replace(/```intent_proposal\s*\n[\s\S]*?```/g, "");
353
+ removedBlock || (removedBlock = next !== result);
354
+ result = next;
355
+ }
356
+ // Clean up leftover double blank lines only when a block was actually removed
357
+ if (removedBlock) {
358
+ result = result.replace(/\n{3,}/g, "\n\n").trim();
359
+ }
360
+ return result;
361
+ }
362
+ /**
363
+ * Post-process a tool result: strip _graphTimings, extract summary/debugSteps,
364
+ * and optionally run create_opportunities → create_intent callback.
365
+ *
366
+ * Returns the normalized result string and extracted debug metadata so both
367
+ * the normal streaming tool loop and the hallucination-recovery branch
368
+ * produce identical LLM-facing payloads.
369
+ */
370
+ async normalizeToolResult(toolName, resultStr, toolArgs) {
371
+ let normalized = resultStr;
372
+ // Run create_intent callback for create_opportunities results
373
+ if (toolName === "create_opportunities") {
374
+ const callbackResult = await this.handleCreateIntentCallback(normalized, toolArgs);
375
+ if (callbackResult !== null) {
376
+ normalized = callbackResult;
377
+ }
378
+ }
379
+ let summary = "Done";
380
+ let debugSteps;
381
+ let graphTimings;
382
+ try {
383
+ const parsed = JSON.parse(normalized);
384
+ const payload = parsed.success && parsed.data != null ? parsed.data : parsed;
385
+ summary = payload.summary ?? parsed.summary ?? "Done";
386
+ const rawSteps = payload.debugSteps ?? parsed.debugSteps;
387
+ if (Array.isArray(rawSteps) && rawSteps.length > 0) {
388
+ debugSteps = rawSteps.map((s) => ({
389
+ step: String(s.step ?? "").slice(0, ChatAgent.STEP_NAME_MAX),
390
+ detail: s.detail != null
391
+ ? String(s.detail).slice(0, ChatAgent.STEP_DETAIL_MAX)
392
+ : undefined,
393
+ ...(s.data && typeof s.data === "object" ? { data: s.data } : {}),
394
+ }));
395
+ }
396
+ const rawGraphTimings = payload._graphTimings ?? parsed._graphTimings;
397
+ if (Array.isArray(rawGraphTimings) && rawGraphTimings.length > 0) {
398
+ graphTimings = rawGraphTimings;
399
+ // Strip _graphTimings from the result string sent back to the LLM
400
+ try {
401
+ const cleanedResult = JSON.parse(normalized);
402
+ delete cleanedResult._graphTimings;
403
+ if (cleanedResult.data && typeof cleanedResult.data === "object") {
404
+ delete cleanedResult.data._graphTimings;
405
+ }
406
+ normalized = JSON.stringify(cleanedResult);
407
+ }
408
+ catch { /* keep original if can't clean */ }
409
+ }
410
+ }
411
+ catch {
412
+ /* not JSON, keep default */
413
+ }
414
+ return { resultStr: normalized, summary, debugSteps, graphTimings };
415
+ }
416
+ /**
417
+ * Run the full agent loop until completion or hard limit.
418
+ *
419
+ * @param initialMessages - Starting conversation messages
420
+ * @returns Final response text and full message history
421
+ */
422
+ async run(initialMessages) {
423
+ let messages = initialMessages;
424
+ let iterationCount = 0;
425
+ while (iterationCount < HARD_ITERATION_LIMIT) {
426
+ const result = await this.runIteration(messages, iterationCount);
427
+ iterationCount++;
428
+ messages = result.messages;
429
+ if (!result.shouldContinue) {
430
+ const responseText = result.responseText ||
431
+ "I apologize, but I couldn't generate a response.";
432
+ logger.debug("Agent final response", { responseText });
433
+ return {
434
+ responseText,
435
+ messages,
436
+ iterationCount,
437
+ };
438
+ }
439
+ }
440
+ // Hit hard limit - force a response
441
+ logger.warn("Hit hard iteration limit", { iterationCount });
442
+ const forceResponseMessages = [
443
+ ...messages,
444
+ new SystemMessage("You have reached the maximum number of tool calls. You MUST provide a final response now. Summarize what you've accomplished and what might still be needed."),
445
+ ];
446
+ const forcedResponse = await this.model.invoke(forceResponseMessages);
447
+ const responseText = extractTextContent(forcedResponse.content);
448
+ logger.debug("Agent forced response", { responseText });
449
+ return {
450
+ responseText,
451
+ messages: [...messages, forcedResponse],
452
+ iterationCount,
453
+ };
454
+ }
455
+ // ═══════════════════════════════════════════════════════════════════════════
456
+ // STREAMING RUN (for narration-style output)
457
+ // ═══════════════════════════════════════════════════════════════════════════
458
+ /**
459
+ * Run the full agent loop with streaming narration.
460
+ *
461
+ * Instead of returning a single blob at the end, this method calls
462
+ * `writer()` for every text token and tool-activity event so the
463
+ * consumer (graph node) can push them out via `config.writer`.
464
+ *
465
+ * @param initialMessages - Starting conversation messages
466
+ * @param writer - Callback to emit streaming events (from `config.writer`)
467
+ * @param signal - Optional AbortSignal to cancel the streaming LLM call and tool execution
468
+ * @returns Final response metadata (same shape as `run()`)
469
+ */
470
+ async streamRun(initialMessages, writer, signal) {
471
+ const emit = (event) => {
472
+ try {
473
+ writer?.(event);
474
+ }
475
+ catch {
476
+ /* swallow if writer is gone */
477
+ }
478
+ };
479
+ let messages = initialMessages;
480
+ let iterationCount = 0;
481
+ const toolsDebug = [];
482
+ while (iterationCount < HARD_ITERATION_LIMIT) {
483
+ if (signal?.aborted) {
484
+ logger.verbose("Stream aborted by client", { iterationCount });
485
+ break;
486
+ }
487
+ emit({ type: "iteration_start", iteration: iterationCount });
488
+ const iterCtx = {
489
+ recentTools: extractRecentToolCalls(messages),
490
+ currentMessage: ChatAgent.getCurrentUserMessage(messages),
491
+ ctx: this.resolvedContext,
492
+ };
493
+ const systemContent = buildSystemContent(this.resolvedContext, iterCtx);
494
+ const fullMessages = [
495
+ new SystemMessage(systemContent),
496
+ ...messages,
497
+ ];
498
+ if (iterationCount >= SOFT_ITERATION_LIMIT) {
499
+ fullMessages.push(new SystemMessage(ITERATION_NUDGE));
500
+ }
501
+ logger.verbose("Streaming iteration", {
502
+ iteration: iterationCount,
503
+ messageCount: messages.length,
504
+ pastSoftLimit: iterationCount >= SOFT_ITERATION_LIMIT,
505
+ });
506
+ // ── Stream the model response token-by-token ──────────────────────
507
+ emit({ type: "llm_start", iteration: iterationCount });
508
+ let accumulated;
509
+ let iterationText = "";
510
+ try {
511
+ const stream = await this.model.stream(fullMessages, { signal });
512
+ for await (const chunk of stream) {
513
+ // Accumulate using AIMessageChunk.concat() so tool_call_chunks merge and tool_calls is populated
514
+ accumulated = accumulated ? accumulated.concat(chunk) : chunk;
515
+ // Emit text content tokens to the user immediately
516
+ const textPart = extractTextFromChunk(chunk);
517
+ if (textPart) {
518
+ emit({ type: "text_chunk", content: textPart });
519
+ iterationText += textPart;
520
+ }
521
+ }
522
+ }
523
+ catch (err) {
524
+ if (err instanceof Error && err.name === "AbortError") {
525
+ logger.verbose("LLM stream aborted by client", { iterationCount });
526
+ break; // breaks the outer while loop
527
+ }
528
+ throw err; // re-throw non-abort errors
529
+ }
530
+ if (!accumulated) {
531
+ logger.warn("Empty model response in streaming iteration", {
532
+ iterationCount,
533
+ });
534
+ iterationCount++;
535
+ continue;
536
+ }
537
+ // ── Check for tool calls ──────────────────────────────────────────
538
+ const toolCalls = accumulated.tool_calls || [];
539
+ emit({
540
+ type: "llm_end",
541
+ iteration: iterationCount,
542
+ hasToolCalls: toolCalls.length > 0,
543
+ toolNames: toolCalls.length > 0 ? toolCalls.map((tc) => tc.name) : undefined,
544
+ });
545
+ if (toolCalls.length > 0) {
546
+ logger.verbose("Streaming: agent made tool calls", {
547
+ iteration: iterationCount,
548
+ tools: toolCalls.map((tc) => tc.name),
549
+ });
550
+ // Strip ```shell (or ```bash, ```plaintext, etc.) code fences that some models
551
+ // (e.g. Gemini) wrap around narration text during tool-calling iterations.
552
+ // Keep the narration content itself — only remove the fence markers.
553
+ if (iterationText) {
554
+ const cleaned = iterationText
555
+ .replace(/```(?:shell|bash|plaintext|text|)\s*\n?/g, "")
556
+ .replace(/```\s*$/gm, "");
557
+ if (cleaned !== iterationText) {
558
+ emit({ type: "response_reset", reason: "Stripped code fence markers from tool-calling narration" });
559
+ if (cleaned.trim()) {
560
+ emit({ type: "text_chunk", content: cleaned });
561
+ }
562
+ iterationText = cleaned;
563
+ }
564
+ }
565
+ // Execute tools one-by-one.
566
+ const toolResults = [];
567
+ for (const tc of toolCalls) {
568
+ if (signal?.aborted) {
569
+ logger.verbose("Stream aborted by client during tool execution");
570
+ break;
571
+ }
572
+ emit({ type: "tool_activity", phase: "start", name: tc.name });
573
+ const tool = this.toolsByName.get(tc.name);
574
+ if (!tool) {
575
+ const errResult = JSON.stringify({
576
+ success: false,
577
+ error: `Unknown tool: ${tc.name}`,
578
+ });
579
+ toolsDebug.push({
580
+ name: tc.name,
581
+ args: sanitizeForDebugMeta(tc.args),
582
+ resultSummary: "Unknown tool",
583
+ success: false,
584
+ durationMs: 0,
585
+ });
586
+ emit({
587
+ type: "tool_activity",
588
+ phase: "end",
589
+ name: tc.name,
590
+ success: false,
591
+ summary: "Unknown tool",
592
+ });
593
+ toolResults.push({
594
+ toolCallId: tc.id || `unknown-${Date.now()}`,
595
+ name: tc.name,
596
+ result: errResult,
597
+ });
598
+ continue;
599
+ }
600
+ const toolStart = Date.now();
601
+ try {
602
+ logger.verbose("Streaming: executing tool", { name: tc.name });
603
+ const currentCtx = requestContext.getStore() ?? {};
604
+ let result = await requestContext.run({ ...currentCtx, traceEmitter: (e) => emit({ type: e.type, name: e.name, durationMs: e.durationMs, summary: e.summary }) }, () => tool.invoke(tc.args));
605
+ const toolDurationMs = Date.now() - toolStart;
606
+ let resultStr = typeof result === "string" ? result : JSON.stringify(result);
607
+ const normalized = await this.normalizeToolResult(tc.name, resultStr, tc.args);
608
+ resultStr = normalized.resultStr;
609
+ result = resultStr;
610
+ logger.verbose("Streaming: tool completed", {
611
+ name: tc.name,
612
+ resultLength: resultStr.length,
613
+ });
614
+ toolsDebug.push({
615
+ name: tc.name,
616
+ args: sanitizeForDebugMeta(tc.args),
617
+ resultSummary: normalized.summary,
618
+ success: true,
619
+ durationMs: toolDurationMs,
620
+ ...(normalized.debugSteps?.length ? { steps: normalized.debugSteps } : {}),
621
+ ...(normalized.graphTimings?.length ? { graphs: normalized.graphTimings } : {}),
622
+ });
623
+ emit({
624
+ type: "tool_activity",
625
+ phase: "end",
626
+ name: tc.name,
627
+ success: true,
628
+ summary: normalized.summary,
629
+ steps: normalized.debugSteps,
630
+ });
631
+ toolResults.push({
632
+ toolCallId: tc.id || `${tc.name}-${Date.now()}`,
633
+ name: tc.name,
634
+ result: resultStr,
635
+ });
636
+ }
637
+ catch (error) {
638
+ const errMsg = error instanceof Error ? error.message : "Unknown error";
639
+ logger.error("Streaming: tool failed", {
640
+ name: tc.name,
641
+ error: errMsg,
642
+ });
643
+ toolsDebug.push({
644
+ name: tc.name,
645
+ args: sanitizeForDebugMeta(tc.args),
646
+ resultSummary: errMsg,
647
+ success: false,
648
+ durationMs: Date.now() - toolStart,
649
+ });
650
+ emit({
651
+ type: "tool_activity",
652
+ phase: "end",
653
+ name: tc.name,
654
+ success: false,
655
+ summary: errMsg,
656
+ });
657
+ toolResults.push({
658
+ toolCallId: tc.id || `${tc.name}-${Date.now()}`,
659
+ name: tc.name,
660
+ result: JSON.stringify({
661
+ success: false,
662
+ error: `Tool execution failed: ${errMsg}`,
663
+ }),
664
+ });
665
+ }
666
+ }
667
+ // If aborted during tool execution, discard partial results
668
+ if (signal?.aborted) {
669
+ logger.verbose("Stream aborted after partial tool execution, discarding results");
670
+ break; // break outer while loop — don't append partial toolResults to messages
671
+ }
672
+ // Build updated messages and loop
673
+ messages = [
674
+ ...messages,
675
+ accumulated, // AIMessage with tool_calls
676
+ ...toolResults.map((tr) => new ToolMessage({
677
+ tool_call_id: tr.toolCallId,
678
+ content: tr.result,
679
+ name: tr.name,
680
+ })),
681
+ ];
682
+ iterationCount++;
683
+ continue;
684
+ }
685
+ // ── No tool calls → check for hallucinated code blocks ──────────
686
+ // LLMs sometimes write ```intent_proposal or ```opportunity blocks
687
+ // directly instead of calling the corresponding tool. These blocks
688
+ // lack valid proposalIds / data and won't work in the frontend.
689
+ // Auto-invoke the correct tool directly instead of re-asking the LLM.
690
+ const hallucinatedBlock = this.detectHallucinatedBlock(iterationText, toolsDebug);
691
+ if (hallucinatedBlock && iterationCount < HARD_ITERATION_LIMIT - 1) {
692
+ logger.warn("Streaming: detected hallucinated block, auto-invoking tool", {
693
+ iteration: iterationCount,
694
+ blockType: hallucinatedBlock.type,
695
+ tool: hallucinatedBlock.tool,
696
+ extractedDescription: hallucinatedBlock.description,
697
+ });
698
+ // Tell the frontend to discard all streamed tokens from this iteration
699
+ emit({ type: "response_reset", reason: `Hallucinated ${hallucinatedBlock.type} block detected` });
700
+ emit({ type: "hallucination_detected", blockType: hallucinatedBlock.type, tool: hallucinatedBlock.tool });
701
+ const tool = this.toolsByName.get(hallucinatedBlock.tool);
702
+ if (tool) {
703
+ const toolCallId = `auto-${hallucinatedBlock.tool}-${Date.now()}`;
704
+ const toolArgs = hallucinatedBlock.type === "opportunity"
705
+ ? { searchQuery: hallucinatedBlock.description }
706
+ : { description: hallucinatedBlock.description };
707
+ emit({ type: "tool_activity", phase: "start", name: hallucinatedBlock.tool });
708
+ const toolStart = Date.now();
709
+ try {
710
+ const currentCtx = requestContext.getStore() ?? {};
711
+ const result = await requestContext.run({ ...currentCtx, traceEmitter: (e) => emit({ type: e.type, name: e.name, durationMs: e.durationMs, summary: e.summary }) }, () => tool.invoke(toolArgs));
712
+ const rawResultStr = typeof result === "string" ? result : JSON.stringify(result);
713
+ const toolDurationMs = Date.now() - toolStart;
714
+ // Same normalization as the main tool loop: callback + _graphTimings strip
715
+ const normalized = await this.normalizeToolResult(hallucinatedBlock.tool, rawResultStr, toolArgs);
716
+ toolsDebug.push({
717
+ name: hallucinatedBlock.tool,
718
+ args: sanitizeForDebugMeta(toolArgs),
719
+ resultSummary: normalized.summary,
720
+ success: true,
721
+ durationMs: toolDurationMs,
722
+ ...(normalized.debugSteps?.length ? { steps: normalized.debugSteps } : {}),
723
+ ...(normalized.graphTimings?.length ? { graphs: normalized.graphTimings } : {}),
724
+ });
725
+ emit({
726
+ type: "tool_activity",
727
+ phase: "end",
728
+ name: hallucinatedBlock.tool,
729
+ success: true,
730
+ summary: normalized.summary,
731
+ steps: normalized.debugSteps,
732
+ });
733
+ // Build synthetic tool call message + tool result so the next LLM
734
+ // iteration can narrate around real data instead of hallucinated blocks.
735
+ const syntheticAIMessage = new AIMessage({
736
+ content: "",
737
+ tool_calls: [{ id: toolCallId, name: hallucinatedBlock.tool, args: toolArgs }],
738
+ });
739
+ messages = [
740
+ ...messages,
741
+ syntheticAIMessage,
742
+ new ToolMessage({ tool_call_id: toolCallId, content: normalized.resultStr, name: hallucinatedBlock.tool }),
743
+ ];
744
+ }
745
+ catch (error) {
746
+ const errMsg = error instanceof Error ? error.message : "Unknown error";
747
+ logger.error("Streaming: auto-invoked tool failed after hallucination", {
748
+ tool: hallucinatedBlock.tool,
749
+ error: errMsg,
750
+ });
751
+ toolsDebug.push({
752
+ name: hallucinatedBlock.tool,
753
+ args: sanitizeForDebugMeta(toolArgs),
754
+ resultSummary: errMsg,
755
+ success: false,
756
+ durationMs: Date.now() - toolStart,
757
+ });
758
+ emit({ type: "tool_activity", phase: "end", name: hallucinatedBlock.tool, success: false, summary: errMsg });
759
+ // Fall back to correction message if tool invocation fails
760
+ messages = [
761
+ ...messages,
762
+ accumulated,
763
+ new SystemMessage(`CORRECTION: You wrote a \`\`\`${hallucinatedBlock.type} block without calling ${hallucinatedBlock.tool}. ` +
764
+ `The auto-retry failed (${errMsg}). Please try calling the tool directly.`),
765
+ ];
766
+ }
767
+ }
768
+ else {
769
+ // Tool not found — fall back to correction message
770
+ messages = [
771
+ ...messages,
772
+ accumulated,
773
+ new SystemMessage(`CORRECTION: You wrote a \`\`\`${hallucinatedBlock.type} block without calling ${hallucinatedBlock.tool}. ` +
774
+ `That block is INVALID. Call the tool directly instead.`),
775
+ ];
776
+ }
777
+ iterationCount++;
778
+ continue;
779
+ }
780
+ // ── Final response already streamed ─────────────────────────────
781
+ // Defense-in-depth: strip any code blocks that require tool backing
782
+ // but slipped through without a successful tool call.
783
+ const sanitizedText = this.stripUnbackedBlocks(iterationText, toolsDebug);
784
+ if (sanitizedText !== iterationText) {
785
+ logger.warn("Streaming: stripped unbacked code blocks from final response", {
786
+ originalLength: iterationText.length,
787
+ sanitizedLength: sanitizedText.length,
788
+ });
789
+ emit({ type: "response_reset", reason: "Sanitized unbacked blocks from response" });
790
+ // Re-emit the sanitized text so the frontend displays clean content
791
+ if (sanitizedText.trim()) {
792
+ emit({ type: "text_chunk", content: sanitizedText });
793
+ }
794
+ // If stripping removed ALL content, force a recovery iteration so the
795
+ // user sees an actual response instead of a blank message.
796
+ if (!sanitizedText.trim() && iterationCount < HARD_ITERATION_LIMIT - 1) {
797
+ logger.warn("Streaming: sanitized text is empty, forcing recovery iteration", {
798
+ iteration: iterationCount,
799
+ });
800
+ messages = [
801
+ ...messages,
802
+ accumulated,
803
+ new SystemMessage("Your previous response only contained invalid code blocks that were removed. " +
804
+ "Write a plain text response now — summarize the results of the tools you used. " +
805
+ "Do NOT include ```opportunity or ```intent_proposal blocks."),
806
+ ];
807
+ iterationCount++;
808
+ continue;
809
+ }
810
+ }
811
+ logger.verbose("Streaming: agent produced response", {
812
+ iteration: iterationCount,
813
+ responseLength: sanitizedText.length,
814
+ });
815
+ messages = [...messages, accumulated];
816
+ iterationCount++;
817
+ return {
818
+ responseText: sanitizedText,
819
+ messages,
820
+ iterationCount,
821
+ debugMeta: { graph: "agent_loop", iterations: iterationCount, tools: toolsDebug },
822
+ };
823
+ }
824
+ // If aborted, return immediately without making another LLM call
825
+ if (signal?.aborted) {
826
+ return {
827
+ responseText: "",
828
+ messages,
829
+ iterationCount,
830
+ debugMeta: { graph: "agent_loop", iterations: iterationCount, tools: toolsDebug },
831
+ };
832
+ }
833
+ // ── Hard limit: force a response ──────────────────────────────────────
834
+ logger.warn("Streaming: hit hard iteration limit", { iterationCount });
835
+ const forceMessages = [
836
+ ...messages,
837
+ new SystemMessage("You have reached the maximum number of tool calls. You MUST provide a final response now. Summarize what you've accomplished and what might still be needed."),
838
+ ];
839
+ let forcedAccumulated;
840
+ let forcedResponseText = "";
841
+ const forceStream = await this.model.stream(forceMessages);
842
+ for await (const chunk of forceStream) {
843
+ forcedAccumulated = forcedAccumulated
844
+ ? forcedAccumulated.concat(chunk)
845
+ : chunk;
846
+ const textPart = extractTextFromChunk(chunk);
847
+ if (textPart) {
848
+ emit({ type: "text_chunk", content: textPart });
849
+ forcedResponseText += textPart;
850
+ }
851
+ }
852
+ return {
853
+ responseText: forcedResponseText,
854
+ messages: [
855
+ ...messages,
856
+ ...(forcedAccumulated ? [forcedAccumulated] : []),
857
+ ],
858
+ iterationCount,
859
+ debugMeta: { graph: "agent_loop", iterations: iterationCount, tools: toolsDebug },
860
+ };
861
+ }
862
+ }
863
+ // ─── Shared tool-result post-processing types ─────────────────────────────
864
+ ChatAgent.STEP_DETAIL_MAX = 300;
865
+ ChatAgent.STEP_NAME_MAX = 100;
866
+ __decorate([
867
+ Timed(),
868
+ __metadata("design:type", Function),
869
+ __metadata("design:paramtypes", [Array, Number]),
870
+ __metadata("design:returntype", Promise)
871
+ ], ChatAgent.prototype, "runIteration", null);
872
+ __decorate([
873
+ Timed(),
874
+ __metadata("design:type", Function),
875
+ __metadata("design:paramtypes", [Array]),
876
+ __metadata("design:returntype", Promise)
877
+ ], ChatAgent.prototype, "run", null);
878
+ __decorate([
879
+ Timed(),
880
+ __metadata("design:type", Function),
881
+ __metadata("design:paramtypes", [Array, Function, AbortSignal]),
882
+ __metadata("design:returntype", Promise)
883
+ ], ChatAgent.prototype, "streamRun", null);
884
+ //# sourceMappingURL=chat.agent.js.map