@indexnetwork/protocol 22.0.0-rc.498.1 → 64.0.0-rc.604.2

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 (561) hide show
  1. package/CHANGELOG.md +1841 -0
  2. package/IMPLEMENTATION.md +140 -181
  3. package/README.md +16 -20
  4. package/STABILITY.md +16 -11
  5. package/dist/{intents/intent.module.d.ts → capabilities/intents.d.ts} +182 -192
  6. package/dist/capabilities/intents.js +88 -0
  7. package/dist/capabilities/negotiations.d.ts +17 -0
  8. package/dist/capabilities/negotiations.js +16 -0
  9. package/dist/{networks/network.module.d.ts → capabilities/networks.d.ts} +33 -169
  10. package/dist/{networks/network.module.js → capabilities/networks.js} +6 -17
  11. package/dist/index.d.ts +57 -132
  12. package/dist/index.js +41 -100
  13. package/dist/internal/agents/agent.repository.port.d.ts +59 -0
  14. package/dist/internal/agents/agent.repository.port.js +7 -0
  15. package/dist/internal/agents/agent.types.d.ts +35 -0
  16. package/dist/{agents → internal/agents}/agent.types.js +1 -6
  17. package/dist/{intents → internal/intents}/graph/intent.graph.d.ts +142 -151
  18. package/dist/{intents → internal/intents}/graph/intent.graph.execute.d.ts +5 -1
  19. package/dist/{intents → internal/intents}/graph/intent.graph.execute.js +165 -46
  20. package/dist/internal/intents/graph/intent.graph.infer.d.ts +78 -0
  21. package/dist/internal/intents/graph/intent.graph.infer.js +122 -0
  22. package/dist/internal/intents/graph/intent.graph.js +108 -0
  23. package/dist/{intents → internal/intents}/graph/intent.graph.reconcile.d.ts +18 -9
  24. package/dist/internal/intents/graph/intent.graph.reconcile.js +173 -0
  25. package/dist/internal/intents/graph/intent.graph.shared.d.ts +55 -0
  26. package/dist/{intents → internal/intents}/graph/intent.graph.shared.js +25 -70
  27. package/dist/{intents → internal/intents}/graph/intent.graph.state.d.ts +96 -32
  28. package/dist/{intents → internal/intents}/graph/intent.graph.state.js +42 -31
  29. package/dist/internal/intents/intent.admission.d.ts +16 -0
  30. package/dist/internal/intents/intent.admission.js +30 -0
  31. package/dist/{intents → internal/intents}/intent.inferrer.d.ts +1 -40
  32. package/dist/{intents → internal/intents}/intent.inferrer.js +13 -49
  33. package/dist/internal/intents/intent.preparer.d.ts +52 -0
  34. package/dist/internal/intents/intent.preparer.js +87 -0
  35. package/dist/{intents → internal/intents}/intent.verifier.d.ts +3 -36
  36. package/dist/{intents → internal/intents}/intent.verifier.js +0 -17
  37. package/dist/{networks → internal/networks}/indexer.graph.d.ts +15 -200
  38. package/dist/{networks → internal/networks}/indexer.graph.js +19 -128
  39. package/dist/{networks → internal/networks}/indexer.state.d.ts +8 -63
  40. package/dist/internal/networks/indexer.state.js +70 -0
  41. package/dist/{networks → internal/networks}/membership.graph.d.ts +6 -6
  42. package/dist/{networks → internal/networks}/membership.graph.js +3 -3
  43. package/dist/{networks → internal/networks}/membership.state.d.ts +2 -2
  44. package/dist/{networks → internal/networks}/membership.state.js +2 -2
  45. package/dist/{networks → internal/networks}/network.graph.d.ts +9 -22
  46. package/dist/{networks → internal/networks}/network.graph.js +13 -27
  47. package/dist/{networks → internal/networks}/network.recommender.d.ts +2 -2
  48. package/dist/{networks → internal/networks}/network.recommender.js +2 -2
  49. package/dist/{networks → internal/networks}/network.state.d.ts +4 -7
  50. package/dist/{networks → internal/networks}/network.state.js +4 -4
  51. package/dist/internal/opportunities/negotiation-context.loader.d.ts +26 -0
  52. package/dist/internal/opportunities/negotiation-context.loader.js +36 -0
  53. package/dist/{opportunities → internal/opportunities}/opportunity.actor.d.ts +1 -1
  54. package/dist/{opportunities → internal/opportunities}/opportunity.actor.js +7 -1
  55. package/dist/internal/opportunities/opportunity.counterparties.d.ts +17 -0
  56. package/dist/internal/opportunities/opportunity.counterparties.js +19 -0
  57. package/dist/internal/opportunities/opportunity.events.d.ts +38 -0
  58. package/dist/internal/opportunities/opportunity.events.js +94 -0
  59. package/dist/{opportunities → internal/opportunities}/opportunity.feed-selection.d.ts +3 -9
  60. package/dist/internal/opportunities/opportunity.feed-selection.js +40 -0
  61. package/dist/internal/opportunities/opportunity.graph.modes.d.ts +39 -0
  62. package/dist/internal/opportunities/opportunity.graph.modes.js +138 -0
  63. package/dist/{opportunities → internal/opportunities}/opportunity.labels.d.ts +2 -3
  64. package/dist/internal/opportunities/opportunity.labels.js +9 -0
  65. package/dist/{opportunities → internal/opportunities}/opportunity.presentation.d.ts +17 -86
  66. package/dist/{opportunities → internal/opportunities}/opportunity.presentation.js +54 -447
  67. package/dist/{opportunities → internal/opportunities}/opportunity.update-admission.d.ts +2 -2
  68. package/dist/internal/opportunities/opportunity.utils.d.ts +105 -0
  69. package/dist/internal/opportunities/opportunity.utils.js +165 -0
  70. package/dist/{opportunities → internal/opportunities}/radar/radar.graph.d.ts +17 -17
  71. package/dist/{opportunities → internal/opportunities}/radar/radar.graph.js +41 -161
  72. package/dist/{opportunities → internal/opportunities}/radar/radar.state.d.ts +4 -11
  73. package/dist/{shared → internal/shared}/agent/model-signal.d.ts +1 -1
  74. package/dist/{shared → internal/shared}/agent/model-signal.js +1 -1
  75. package/dist/{shared → internal/shared}/agent/model.config.d.ts +28 -86
  76. package/dist/{shared → internal/shared}/agent/model.config.js +58 -69
  77. package/dist/internal/shared/agent/model.resolver.d.ts +33 -0
  78. package/dist/{shared → internal/shared}/agent/model.resolver.js +18 -33
  79. package/dist/internal/shared/agent/scope.d.ts +20 -0
  80. package/dist/internal/shared/agent/scope.js +24 -0
  81. package/dist/internal/shared/assignment/network-assignment.policy.d.ts +23 -0
  82. package/dist/internal/shared/assignment/network-assignment.policy.js +28 -0
  83. package/dist/{shared → internal/shared}/observability/log.d.ts +3 -6
  84. package/dist/{shared → internal/shared}/observability/log.js +9 -18
  85. package/dist/{shared → internal/shared}/observability/protocol.logger.d.ts +1 -1
  86. package/dist/{shared → internal/shared}/observability/protocol.logger.js +1 -1
  87. package/dist/internal/shared/observability/request-context.d.ts +29 -0
  88. package/dist/internal/shared/observability/request-context.js +17 -0
  89. package/dist/{shared → internal/shared}/utils/social-label.d.ts +2 -2
  90. package/dist/{shared → internal/shared}/utils/social-label.js +1 -1
  91. package/dist/platform/database/capabilities.d.ts +59 -0
  92. package/dist/{shared/interfaces/database.entities.d.ts → platform/database/entities.d.ts} +81 -121
  93. package/dist/{shared/interfaces/database.identity-queries.d.ts → platform/database/identity-queries.d.ts} +55 -20
  94. package/dist/platform/database/member-queries.d.ts +55 -0
  95. package/dist/platform/database/member-queries.js +4 -0
  96. package/dist/platform/database/negotiation.d.ts +38 -0
  97. package/dist/{shared/interfaces/database.network-queries.d.ts → platform/database/network-queries.d.ts} +66 -67
  98. package/dist/platform/database/network-queries.js +4 -0
  99. package/dist/{shared/interfaces/database.opportunity-queries.d.ts → platform/database/opportunity-queries.d.ts} +25 -109
  100. package/dist/{shared/interfaces/database.port.d.ts → platform/database/port.d.ts} +52 -117
  101. package/dist/{shared/interfaces/database.port.js → platform/database/port.js} +3 -5
  102. package/dist/platform/database.d.ts +23 -0
  103. package/dist/{shared/interfaces/database.interface.js → platform/database.js} +1 -1
  104. package/dist/{shared/interfaces/cache.interface.d.ts → platform/discovery/cache.d.ts} +2 -4
  105. package/dist/{shared/interfaces/cache.interface.js → platform/discovery/cache.js} +1 -1
  106. package/dist/platform/discovery/embedder.d.ts +31 -0
  107. package/dist/platform/runtime/errors.d.ts +6 -0
  108. package/dist/platform/runtime/errors.js +9 -0
  109. package/dist/platform/runtime/follow-up.d.ts +36 -0
  110. package/dist/platform/runtime/follow-up.js +4 -0
  111. package/dist/platform/runtime/observability.d.ts +34 -0
  112. package/dist/protocol/core.d.ts +11 -0
  113. package/dist/protocol/discovery.rules.d.ts +21 -0
  114. package/dist/protocol/discovery.rules.js +29 -0
  115. package/dist/protocol/negotiation.constants.d.ts +3 -0
  116. package/dist/protocol/negotiation.constants.js +3 -0
  117. package/dist/protocol/negotiation.rules.d.ts +73 -0
  118. package/dist/protocol/negotiation.rules.js +68 -0
  119. package/dist/protocol/protocol.prompt.d.ts +13 -0
  120. package/dist/protocol/protocol.prompt.js +190 -0
  121. package/dist/{shared → protocol}/schemas/discovery-question.schema.d.ts +13 -13
  122. package/dist/{shared → protocol}/schemas/discovery-question.schema.js +2 -2
  123. package/dist/{shared → protocol}/schemas/identity.schema.d.ts +4 -4
  124. package/dist/{shared → protocol}/schemas/identity.schema.js +4 -4
  125. package/dist/{shared → protocol}/schemas/network-assignment.schema.d.ts +11 -20
  126. package/dist/{shared → protocol}/schemas/network-assignment.schema.js +2 -9
  127. package/dist/protocol/schemas/underspecification.schema.d.ts +9 -0
  128. package/dist/protocol/schemas/underspecification.schema.js +12 -0
  129. package/package.json +7 -15
  130. package/dist/agents/agent.dispatcher.port.d.ts +0 -25
  131. package/dist/agents/agent.module.d.ts +0 -19
  132. package/dist/agents/agent.module.js +0 -11
  133. package/dist/agents/agent.repository.port.d.ts +0 -118
  134. package/dist/agents/agent.repository.port.js +0 -10
  135. package/dist/agents/agent.tools.d.ts +0 -16
  136. package/dist/agents/agent.tools.js +0 -351
  137. package/dist/agents/agent.tools.port.d.ts +0 -22
  138. package/dist/agents/agent.tools.port.js +0 -18
  139. package/dist/agents/agent.types.d.ts +0 -76
  140. package/dist/chat/chat-streaming.types.d.ts +0 -618
  141. package/dist/chat/chat-streaming.types.js +0 -297
  142. package/dist/chat/chat.agent.d.ts +0 -292
  143. package/dist/chat/chat.agent.js +0 -1010
  144. package/dist/chat/chat.graph.d.ts +0 -424
  145. package/dist/chat/chat.graph.js +0 -257
  146. package/dist/chat/chat.interrupt.classifier.d.ts +0 -25
  147. package/dist/chat/chat.interrupt.classifier.js +0 -64
  148. package/dist/chat/chat.persona.d.ts +0 -39
  149. package/dist/chat/chat.prompt.d.ts +0 -4
  150. package/dist/chat/chat.prompt.js +0 -12
  151. package/dist/chat/chat.prompt.modules.d.ts +0 -30
  152. package/dist/chat/chat.prompt.modules.js +0 -40
  153. package/dist/chat/chat.question-dedup.d.ts +0 -14
  154. package/dist/chat/chat.question-dedup.js +0 -17
  155. package/dist/chat/chat.state.d.ts +0 -135
  156. package/dist/chat/chat.state.js +0 -120
  157. package/dist/chat/chat.streamer.d.ts +0 -64
  158. package/dist/chat/chat.streamer.js +0 -217
  159. package/dist/chat/chat.suggester.d.ts +0 -23
  160. package/dist/chat/chat.suggester.js +0 -95
  161. package/dist/chat/chat.summarizer.d.ts +0 -20
  162. package/dist/chat/chat.summarizer.js +0 -97
  163. package/dist/chat/chat.title.generator.d.ts +0 -19
  164. package/dist/chat/chat.title.generator.js +0 -66
  165. package/dist/chat/chat.tools.d.ts +0 -5
  166. package/dist/chat/chat.tools.js +0 -62
  167. package/dist/chat/chat.utils.d.ts +0 -41
  168. package/dist/chat/chat.utils.js +0 -88
  169. package/dist/chat/negotiator.persona.d.ts +0 -74
  170. package/dist/chat/negotiator.persona.js +0 -154
  171. package/dist/chat/negotiator.prompt.d.ts +0 -45
  172. package/dist/chat/negotiator.prompt.js +0 -160
  173. package/dist/chat/negotiator.tools.d.ts +0 -42
  174. package/dist/chat/negotiator.tools.js +0 -134
  175. package/dist/chat/onboarding.persona.d.ts +0 -28
  176. package/dist/chat/onboarding.persona.js +0 -86
  177. package/dist/chat/onboarding.prompt.d.ts +0 -6
  178. package/dist/chat/onboarding.prompt.js +0 -63
  179. package/dist/chat/signal.persona.d.ts +0 -47
  180. package/dist/chat/signal.persona.js +0 -319
  181. package/dist/chat/signal.prompt.d.ts +0 -39
  182. package/dist/chat/signal.prompt.js +0 -136
  183. package/dist/contacts/contact.module.d.ts +0 -8
  184. package/dist/contacts/contact.module.js +0 -6
  185. package/dist/contacts/contact.repository.port.d.ts +0 -21
  186. package/dist/contacts/contact.repository.port.js +0 -12
  187. package/dist/contacts/contact.tools.d.ts +0 -17
  188. package/dist/contacts/contact.tools.js +0 -108
  189. package/dist/contacts/contact.tools.port.d.ts +0 -20
  190. package/dist/contacts/contact.tools.port.js +0 -16
  191. package/dist/contacts/contact.types.d.ts +0 -24
  192. package/dist/contacts/contact.types.js +0 -8
  193. package/dist/contexts/context.generator.d.ts +0 -95
  194. package/dist/contexts/context.generator.js +0 -127
  195. package/dist/contexts/context.module.d.ts +0 -13
  196. package/dist/contexts/context.module.js +0 -12
  197. package/dist/contexts/context.tools.port.d.ts +0 -9
  198. package/dist/discovery/hyde.documents.d.ts +0 -9
  199. package/dist/discovery/hyde.documents.js +0 -49
  200. package/dist/discovery/hyde.env.d.ts +0 -8
  201. package/dist/discovery/hyde.env.js +0 -9
  202. package/dist/discovery/hyde.frame.d.ts +0 -150
  203. package/dist/discovery/hyde.frame.js +0 -107
  204. package/dist/discovery/hyde.generator.d.ts +0 -38
  205. package/dist/discovery/hyde.generator.js +0 -103
  206. package/dist/discovery/hyde.graph.d.ts +0 -209
  207. package/dist/discovery/hyde.graph.js +0 -482
  208. package/dist/discovery/hyde.state.d.ts +0 -70
  209. package/dist/discovery/hyde.state.js +0 -85
  210. package/dist/discovery/hyde.strategies.d.ts +0 -17
  211. package/dist/discovery/hyde.strategies.js +0 -34
  212. package/dist/discovery/hyde.validator.d.ts +0 -78
  213. package/dist/discovery/hyde.validator.js +0 -48
  214. package/dist/discovery/index.d.ts +0 -26
  215. package/dist/discovery/index.js +0 -19
  216. package/dist/discovery/lens.inferrer.d.ts +0 -214
  217. package/dist/discovery/lens.inferrer.js +0 -152
  218. package/dist/enrichment/enrichment.generator.d.ts +0 -68
  219. package/dist/enrichment/enrichment.generator.js +0 -95
  220. package/dist/enrichment/enrichment.graph.d.ts +0 -544
  221. package/dist/enrichment/enrichment.graph.js +0 -695
  222. package/dist/enrichment/enrichment.state.d.ts +0 -141
  223. package/dist/enrichment/enrichment.state.js +0 -115
  224. package/dist/enrichment/enrichment.tools.context-read.d.ts +0 -10
  225. package/dist/enrichment/enrichment.tools.context-read.js +0 -353
  226. package/dist/enrichment/enrichment.tools.context-write.d.ts +0 -9
  227. package/dist/enrichment/enrichment.tools.context-write.js +0 -417
  228. package/dist/enrichment/enrichment.tools.d.ts +0 -13
  229. package/dist/enrichment/enrichment.tools.helpers.d.ts +0 -139
  230. package/dist/enrichment/enrichment.tools.helpers.js +0 -234
  231. package/dist/enrichment/enrichment.tools.js +0 -153
  232. package/dist/intents/graph/intent.graph.infer.d.ts +0 -44
  233. package/dist/intents/graph/intent.graph.infer.js +0 -97
  234. package/dist/intents/graph/intent.graph.js +0 -134
  235. package/dist/intents/graph/intent.graph.reconcile.js +0 -274
  236. package/dist/intents/graph/intent.graph.shared.d.ts +0 -68
  237. package/dist/intents/intake/intake.orchestrator.d.ts +0 -203
  238. package/dist/intents/intake/intake.orchestrator.js +0 -255
  239. package/dist/intents/intake/intake.pack.generator.d.ts +0 -57
  240. package/dist/intents/intake/intake.pack.generator.js +0 -90
  241. package/dist/intents/intent.clarifier.d.ts +0 -51
  242. package/dist/intents/intent.clarifier.js +0 -201
  243. package/dist/intents/intent.indexer.d.ts +0 -82
  244. package/dist/intents/intent.indexer.js +0 -170
  245. package/dist/intents/intent.module.js +0 -103
  246. package/dist/intents/intent.proposal.d.ts +0 -37
  247. package/dist/intents/intent.proposal.js +0 -14
  248. package/dist/intents/intent.reconciler.d.ts +0 -105
  249. package/dist/intents/intent.reconciler.js +0 -186
  250. package/dist/intents/intent.tools.d.ts +0 -27
  251. package/dist/intents/intent.tools.js +0 -808
  252. package/dist/maintenance/maintenance.graph.d.ts +0 -239
  253. package/dist/maintenance/maintenance.graph.js +0 -199
  254. package/dist/maintenance/maintenance.state.d.ts +0 -35
  255. package/dist/maintenance/maintenance.state.js +0 -55
  256. package/dist/mcp/elicitation.builder.d.ts +0 -53
  257. package/dist/mcp/elicitation.builder.js +0 -74
  258. package/dist/mcp/elicitation.dispatcher.d.ts +0 -36
  259. package/dist/mcp/elicitation.dispatcher.js +0 -86
  260. package/dist/mcp/mcp.authorization-policy.d.ts +0 -252
  261. package/dist/mcp/mcp.authorization-policy.js +0 -535
  262. package/dist/mcp/mcp.server.d.ts +0 -90
  263. package/dist/mcp/mcp.server.js +0 -631
  264. package/dist/negotiations/insight.generator.d.ts +0 -31
  265. package/dist/negotiations/insight.generator.js +0 -105
  266. package/dist/negotiations/negotiation.agent.d.ts +0 -130
  267. package/dist/negotiations/negotiation.agent.js +0 -396
  268. package/dist/negotiations/negotiation.answer-consumption.d.ts +0 -223
  269. package/dist/negotiations/negotiation.answer-consumption.js +0 -275
  270. package/dist/negotiations/negotiation.attribution.d.ts +0 -91
  271. package/dist/negotiations/negotiation.attribution.js +0 -109
  272. package/dist/negotiations/negotiation.candidates.d.ts +0 -83
  273. package/dist/negotiations/negotiation.candidates.js +0 -162
  274. package/dist/negotiations/negotiation.client-dm.d.ts +0 -50
  275. package/dist/negotiations/negotiation.client-dm.js +0 -66
  276. package/dist/negotiations/negotiation.consultation-policy.d.ts +0 -95
  277. package/dist/negotiations/negotiation.consultation-policy.js +0 -159
  278. package/dist/negotiations/negotiation.deadlock.contracts.d.ts +0 -10
  279. package/dist/negotiations/negotiation.deadlock.d.ts +0 -87
  280. package/dist/negotiations/negotiation.deadlock.js +0 -150
  281. package/dist/negotiations/negotiation.detail-reader.d.ts +0 -94
  282. package/dist/negotiations/negotiation.detail-reader.js +0 -91
  283. package/dist/negotiations/negotiation.expected-speaker.d.ts +0 -33
  284. package/dist/negotiations/negotiation.expected-speaker.js +0 -59
  285. package/dist/negotiations/negotiation.graph.d.ts +0 -694
  286. package/dist/negotiations/negotiation.graph.finalize.d.ts +0 -5
  287. package/dist/negotiations/negotiation.graph.finalize.js +0 -403
  288. package/dist/negotiations/negotiation.graph.init.d.ts +0 -54
  289. package/dist/negotiations/negotiation.graph.init.js +0 -256
  290. package/dist/negotiations/negotiation.graph.js +0 -94
  291. package/dist/negotiations/negotiation.graph.screen.d.ts +0 -23
  292. package/dist/negotiations/negotiation.graph.screen.js +0 -108
  293. package/dist/negotiations/negotiation.graph.shared.d.ts +0 -111
  294. package/dist/negotiations/negotiation.graph.shared.js +0 -168
  295. package/dist/negotiations/negotiation.graph.turn.d.ts +0 -134
  296. package/dist/negotiations/negotiation.graph.turn.js +0 -662
  297. package/dist/negotiations/negotiation.hermes-contract.d.ts +0 -31
  298. package/dist/negotiations/negotiation.hermes-contract.js +0 -72
  299. package/dist/negotiations/negotiation.intent-snapshot-provenance.d.ts +0 -21
  300. package/dist/negotiations/negotiation.intent-snapshot-provenance.js +0 -28
  301. package/dist/negotiations/negotiation.lifecycle-narration.d.ts +0 -18
  302. package/dist/negotiations/negotiation.lifecycle-narration.js +0 -87
  303. package/dist/negotiations/negotiation.memory.d.ts +0 -65
  304. package/dist/negotiations/negotiation.memory.js +0 -83
  305. package/dist/negotiations/negotiation.module.d.ts +0 -36
  306. package/dist/negotiations/negotiation.module.js +0 -23
  307. package/dist/negotiations/negotiation.protocol.d.ts +0 -1018
  308. package/dist/negotiations/negotiation.protocol.js +0 -224
  309. package/dist/negotiations/negotiation.question-safety.d.ts +0 -52
  310. package/dist/negotiations/negotiation.question-safety.js +0 -119
  311. package/dist/negotiations/negotiation.reflect.d.ts +0 -194
  312. package/dist/negotiations/negotiation.reflect.js +0 -145
  313. package/dist/negotiations/negotiation.scope.d.ts +0 -41
  314. package/dist/negotiations/negotiation.scope.js +0 -39
  315. package/dist/negotiations/negotiation.screen.contracts.d.ts +0 -88
  316. package/dist/negotiations/negotiation.screen.contracts.js +0 -58
  317. package/dist/negotiations/negotiation.screen.d.ts +0 -78
  318. package/dist/negotiations/negotiation.screen.js +0 -112
  319. package/dist/negotiations/negotiation.stall-gap.d.ts +0 -83
  320. package/dist/negotiations/negotiation.stall-gap.js +0 -152
  321. package/dist/negotiations/negotiation.stance.contracts.d.ts +0 -123
  322. package/dist/negotiations/negotiation.stance.contracts.js +0 -317
  323. package/dist/negotiations/negotiation.state.d.ts +0 -597
  324. package/dist/negotiations/negotiation.state.js +0 -286
  325. package/dist/negotiations/negotiation.summarizer.d.ts +0 -25
  326. package/dist/negotiations/negotiation.summarizer.js +0 -101
  327. package/dist/negotiations/negotiation.task-lock-policy.d.ts +0 -10
  328. package/dist/negotiations/negotiation.task-lock-policy.js +0 -22
  329. package/dist/negotiations/negotiation.tools.d.ts +0 -18
  330. package/dist/negotiations/negotiation.tools.js +0 -842
  331. package/dist/negotiations/negotiation.tools.port.d.ts +0 -17
  332. package/dist/negotiations/negotiation.turn-cap.d.ts +0 -9
  333. package/dist/negotiations/negotiation.turn-cap.js +0 -12
  334. package/dist/networks/indexer.state.js +0 -112
  335. package/dist/networks/network.tools.d.ts +0 -36
  336. package/dist/networks/network.tools.js +0 -594
  337. package/dist/opportunities/delivery-card.cache.d.ts +0 -25
  338. package/dist/opportunities/delivery-card.cache.js +0 -43
  339. package/dist/opportunities/discovery.env.d.ts +0 -20
  340. package/dist/opportunities/discovery.env.js +0 -109
  341. package/dist/opportunities/discriminator/discriminator.adjustments.d.ts +0 -90
  342. package/dist/opportunities/discriminator/discriminator.adjustments.js +0 -141
  343. package/dist/opportunities/discriminator/discriminator.assigner.d.ts +0 -78
  344. package/dist/opportunities/discriminator/discriminator.assigner.js +0 -153
  345. package/dist/opportunities/discriminator/discriminator.env.d.ts +0 -103
  346. package/dist/opportunities/discriminator/discriminator.env.js +0 -103
  347. package/dist/opportunities/discriminator/discriminator.miner.d.ts +0 -114
  348. package/dist/opportunities/discriminator/discriminator.miner.js +0 -228
  349. package/dist/opportunities/discriminator/discriminator.push.d.ts +0 -13
  350. package/dist/opportunities/discriminator/discriminator.push.js +0 -19
  351. package/dist/opportunities/discriminator/discriminator.question.d.ts +0 -58
  352. package/dist/opportunities/discriminator/discriminator.question.js +0 -155
  353. package/dist/opportunities/discriminator/discriminator.scorer.d.ts +0 -32
  354. package/dist/opportunities/discriminator/discriminator.scorer.js +0 -105
  355. package/dist/opportunities/discriminator/discriminator.shadow.d.ts +0 -32
  356. package/dist/opportunities/discriminator/discriminator.shadow.js +0 -90
  357. package/dist/opportunities/discriminator/discriminator.types.d.ts +0 -93
  358. package/dist/opportunities/discriminator/discriminator.types.js +0 -18
  359. package/dist/opportunities/negotiation-context.loader.d.ts +0 -59
  360. package/dist/opportunities/negotiation-context.loader.js +0 -90
  361. package/dist/opportunities/negotiation-evidence/negotiation-evidence.env.d.ts +0 -43
  362. package/dist/opportunities/negotiation-evidence/negotiation-evidence.env.js +0 -44
  363. package/dist/opportunities/negotiation-evidence/negotiation-evidence.extractor.d.ts +0 -24
  364. package/dist/opportunities/negotiation-evidence/negotiation-evidence.extractor.js +0 -188
  365. package/dist/opportunities/negotiation-evidence/negotiation-evidence.miner.d.ts +0 -26
  366. package/dist/opportunities/negotiation-evidence/negotiation-evidence.miner.js +0 -112
  367. package/dist/opportunities/negotiation-evidence/negotiation-evidence.shadow.d.ts +0 -19
  368. package/dist/opportunities/negotiation-evidence/negotiation-evidence.shadow.js +0 -61
  369. package/dist/opportunities/negotiation-evidence/negotiation-evidence.types.d.ts +0 -191
  370. package/dist/opportunities/negotiation-evidence/negotiation-evidence.types.js +0 -18
  371. package/dist/opportunities/negotiation-evidence/negotiation-evidence.verifier.d.ts +0 -34
  372. package/dist/opportunities/negotiation-evidence/negotiation-evidence.verifier.js +0 -91
  373. package/dist/opportunities/negotiation-summary.builder.d.ts +0 -37
  374. package/dist/opportunities/negotiation-summary.builder.js +0 -66
  375. package/dist/opportunities/opportunity.discovery-negotiation-summary.d.ts +0 -14
  376. package/dist/opportunities/opportunity.discovery-negotiation-summary.js +0 -46
  377. package/dist/opportunities/opportunity.enricher.d.ts +0 -71
  378. package/dist/opportunities/opportunity.enricher.js +0 -280
  379. package/dist/opportunities/opportunity.evaluator.d.ts +0 -289
  380. package/dist/opportunities/opportunity.evaluator.js +0 -516
  381. package/dist/opportunities/opportunity.evidence.d.ts +0 -22
  382. package/dist/opportunities/opportunity.evidence.js +0 -87
  383. package/dist/opportunities/opportunity.existing-negotiation.d.ts +0 -79
  384. package/dist/opportunities/opportunity.existing-negotiation.js +0 -118
  385. package/dist/opportunities/opportunity.feed-selection.js +0 -96
  386. package/dist/opportunities/opportunity.graph.d.ts +0 -1611
  387. package/dist/opportunities/opportunity.graph.discovery-strategies.d.ts +0 -109
  388. package/dist/opportunities/opportunity.graph.discovery-strategies.js +0 -451
  389. package/dist/opportunities/opportunity.graph.discovery.d.ts +0 -69
  390. package/dist/opportunities/opportunity.graph.discovery.js +0 -397
  391. package/dist/opportunities/opportunity.graph.evaluation.d.ts +0 -82
  392. package/dist/opportunities/opportunity.graph.evaluation.js +0 -608
  393. package/dist/opportunities/opportunity.graph.js +0 -193
  394. package/dist/opportunities/opportunity.graph.modes.d.ts +0 -538
  395. package/dist/opportunities/opportunity.graph.modes.js +0 -538
  396. package/dist/opportunities/opportunity.graph.negotiate.d.ts +0 -109
  397. package/dist/opportunities/opportunity.graph.negotiate.js +0 -392
  398. package/dist/opportunities/opportunity.graph.persist-node.d.ts +0 -93
  399. package/dist/opportunities/opportunity.graph.persist-node.js +0 -765
  400. package/dist/opportunities/opportunity.graph.prep.d.ts +0 -150
  401. package/dist/opportunities/opportunity.graph.prep.js +0 -381
  402. package/dist/opportunities/opportunity.graph.shared.d.ts +0 -173
  403. package/dist/opportunities/opportunity.graph.shared.js +0 -199
  404. package/dist/opportunities/opportunity.introducer-feature.d.ts +0 -2
  405. package/dist/opportunities/opportunity.introducer-feature.js +0 -4
  406. package/dist/opportunities/opportunity.introducer.d.ts +0 -77
  407. package/dist/opportunities/opportunity.introducer.js +0 -99
  408. package/dist/opportunities/opportunity.labels.js +0 -10
  409. package/dist/opportunities/opportunity.lifecycle.d.ts +0 -63
  410. package/dist/opportunities/opportunity.lifecycle.js +0 -181
  411. package/dist/opportunities/opportunity.module.d.ts +0 -54
  412. package/dist/opportunities/opportunity.module.js +0 -39
  413. package/dist/opportunities/opportunity.newborn-stamping.d.ts +0 -41
  414. package/dist/opportunities/opportunity.newborn-stamping.js +0 -81
  415. package/dist/opportunities/opportunity.owner-approval.d.ts +0 -118
  416. package/dist/opportunities/opportunity.owner-approval.js +0 -34
  417. package/dist/opportunities/opportunity.owner-provenance.d.ts +0 -6
  418. package/dist/opportunities/opportunity.owner-provenance.js +0 -28
  419. package/dist/opportunities/opportunity.persist.d.ts +0 -58
  420. package/dist/opportunities/opportunity.persist.js +0 -145
  421. package/dist/opportunities/opportunity.persistence-admission.d.ts +0 -39
  422. package/dist/opportunities/opportunity.persistence-admission.js +0 -59
  423. package/dist/opportunities/opportunity.state.d.ts +0 -451
  424. package/dist/opportunities/opportunity.state.js +0 -256
  425. package/dist/opportunities/opportunity.tools.cards.d.ts +0 -138
  426. package/dist/opportunities/opportunity.tools.cards.js +0 -212
  427. package/dist/opportunities/opportunity.tools.d.ts +0 -12
  428. package/dist/opportunities/opportunity.tools.js +0 -236
  429. package/dist/opportunities/opportunity.tools.list.d.ts +0 -10
  430. package/dist/opportunities/opportunity.tools.list.js +0 -489
  431. package/dist/opportunities/opportunity.tools.port.d.ts +0 -16
  432. package/dist/opportunities/opportunity.utils.d.ts +0 -217
  433. package/dist/opportunities/opportunity.utils.js +0 -395
  434. package/dist/opportunities/outcome/outcome.env.d.ts +0 -60
  435. package/dist/opportunities/outcome/outcome.env.js +0 -63
  436. package/dist/opportunities/outcome/outcome.hypotheses.d.ts +0 -29
  437. package/dist/opportunities/outcome/outcome.hypotheses.js +0 -117
  438. package/dist/opportunities/outcome/outcome.shadow.d.ts +0 -56
  439. package/dist/opportunities/outcome/outcome.shadow.js +0 -87
  440. package/dist/opportunities/outcome/outcome.types.d.ts +0 -110
  441. package/dist/opportunities/outcome/outcome.types.js +0 -26
  442. package/dist/opportunities/radar/radar.health.d.ts +0 -31
  443. package/dist/opportunities/radar/radar.health.js +0 -75
  444. package/dist/premises/premise.analyzer.d.ts +0 -35
  445. package/dist/premises/premise.analyzer.js +0 -115
  446. package/dist/premises/premise.decomposer.d.ts +0 -69
  447. package/dist/premises/premise.decomposer.js +0 -213
  448. package/dist/premises/premise.graph.d.ts +0 -345
  449. package/dist/premises/premise.graph.js +0 -278
  450. package/dist/premises/premise.indexer.d.ts +0 -35
  451. package/dist/premises/premise.indexer.js +0 -86
  452. package/dist/premises/premise.state.d.ts +0 -67
  453. package/dist/premises/premise.state.js +0 -94
  454. package/dist/premises/premise.tools.d.ts +0 -3
  455. package/dist/premises/premise.tools.js +0 -248
  456. package/dist/questions/question.env.d.ts +0 -27
  457. package/dist/questions/question.env.js +0 -27
  458. package/dist/questions/question.input.d.ts +0 -107
  459. package/dist/questions/question.module.d.ts +0 -30
  460. package/dist/questions/question.module.js +0 -28
  461. package/dist/questions/question.schema.d.ts +0 -1529
  462. package/dist/questions/question.schema.js +0 -420
  463. package/dist/shared/agent/activity-projection.d.ts +0 -271
  464. package/dist/shared/agent/activity-projection.js +0 -254
  465. package/dist/shared/agent/canonical-guidance.d.ts +0 -30
  466. package/dist/shared/agent/canonical-guidance.js +0 -246
  467. package/dist/shared/agent/model.resolver.d.ts +0 -48
  468. package/dist/shared/agent/tool.factory.d.ts +0 -17
  469. package/dist/shared/agent/tool.factory.js +0 -221
  470. package/dist/shared/agent/tool.helpers.d.ts +0 -482
  471. package/dist/shared/agent/tool.helpers.js +0 -232
  472. package/dist/shared/agent/tool.registry.d.ts +0 -25
  473. package/dist/shared/agent/tool.registry.js +0 -76
  474. package/dist/shared/agent/tool.runtime.d.ts +0 -28
  475. package/dist/shared/agent/tool.runtime.js +0 -194
  476. package/dist/shared/agent/tool.scope.d.ts +0 -44
  477. package/dist/shared/agent/tool.scope.js +0 -50
  478. package/dist/shared/agent/utility.tools.d.ts +0 -15
  479. package/dist/shared/agent/utility.tools.js +0 -322
  480. package/dist/shared/assignment/network-assignment.policy.d.ts +0 -61
  481. package/dist/shared/assignment/network-assignment.policy.js +0 -105
  482. package/dist/shared/interfaces/agent-dispatcher.interface.d.ts +0 -100
  483. package/dist/shared/interfaces/agent-dispatcher.interface.js +0 -12
  484. package/dist/shared/interfaces/auth.interface.d.ts +0 -37
  485. package/dist/shared/interfaces/auth.interface.js +0 -1
  486. package/dist/shared/interfaces/chat-message-writer.interface.d.ts +0 -18
  487. package/dist/shared/interfaces/chat-message-writer.interface.js +0 -1
  488. package/dist/shared/interfaces/chat-session.interface.d.ts +0 -23
  489. package/dist/shared/interfaces/chat-session.interface.js +0 -18
  490. package/dist/shared/interfaces/chat-summary.interface.d.ts +0 -16
  491. package/dist/shared/interfaces/chat-summary.interface.js +0 -1
  492. package/dist/shared/interfaces/database.capabilities.d.ts +0 -100
  493. package/dist/shared/interfaces/database.interface.d.ts +0 -16
  494. package/dist/shared/interfaces/database.member-queries.d.ts +0 -219
  495. package/dist/shared/interfaces/database.member-queries.js +0 -4
  496. package/dist/shared/interfaces/database.negotiation.d.ts +0 -329
  497. package/dist/shared/interfaces/database.negotiation.js +0 -26
  498. package/dist/shared/interfaces/database.network-queries.js +0 -4
  499. package/dist/shared/interfaces/database.opportunity-queries.js +0 -4
  500. package/dist/shared/interfaces/delivery-ledger.interface.d.ts +0 -40
  501. package/dist/shared/interfaces/delivery-ledger.interface.js +0 -5
  502. package/dist/shared/interfaces/embedder.interface.d.ts +0 -92
  503. package/dist/shared/interfaces/embedder.interface.js +0 -4
  504. package/dist/shared/interfaces/enrichment-run.interface.d.ts +0 -62
  505. package/dist/shared/interfaces/enrichment-run.interface.js +0 -1
  506. package/dist/shared/interfaces/enrichment.interface.js +0 -1
  507. package/dist/shared/interfaces/negotiation-events.interface.d.ts +0 -77
  508. package/dist/shared/interfaces/negotiation-events.interface.js +0 -6
  509. package/dist/shared/interfaces/negotiation-summary.interface.d.ts +0 -25
  510. package/dist/shared/interfaces/negotiation-summary.interface.js +0 -1
  511. package/dist/shared/interfaces/negotiator-memory.interface.d.ts +0 -58
  512. package/dist/shared/interfaces/negotiator-memory.interface.js +0 -11
  513. package/dist/shared/interfaces/queue.interface.d.ts +0 -23
  514. package/dist/shared/interfaces/queue.interface.js +0 -4
  515. package/dist/shared/interfaces/scraper.interface.js +0 -1
  516. package/dist/shared/interfaces/tool-request-context.interface.d.ts +0 -11
  517. package/dist/shared/interfaces/tool-request-context.interface.js +0 -1
  518. package/dist/shared/observability/request-context.d.ts +0 -27
  519. package/dist/shared/observability/request-context.js +0 -6
  520. package/dist/shared/schemas/mcp-auth.schema.d.ts +0 -87
  521. package/dist/shared/schemas/mcp-auth.schema.js +0 -56
  522. package/dist/shared/schemas/negotiation-digest.schema.d.ts +0 -58
  523. package/dist/shared/schemas/negotiation-digest.schema.js +0 -38
  524. package/dist/shared/schemas/negotiation-state.schema.d.ts +0 -343
  525. package/dist/shared/schemas/negotiation-state.schema.js +0 -81
  526. package/dist/shared/schemas/question-block.fixture.d.ts +0 -12
  527. package/dist/shared/schemas/question-block.fixture.js +0 -39
  528. package/dist/shared/schemas/question-block.schema.d.ts +0 -111
  529. package/dist/shared/schemas/question-block.schema.js +0 -124
  530. package/dist/shared/schemas/structured-question.schema.d.ts +0 -66
  531. package/dist/shared/schemas/structured-question.schema.js +0 -31
  532. package/dist/shared/schemas/underspecification.schema.d.ts +0 -13
  533. package/dist/shared/schemas/underspecification.schema.js +0 -16
  534. /package/dist/{opportunities → internal/opportunities}/opportunity.update-admission.js +0 -0
  535. /package/dist/{opportunities → internal/opportunities}/radar/radar.state.js +0 -0
  536. /package/dist/{shared → internal/shared}/network/metadata.renderer.d.ts +0 -0
  537. /package/dist/{shared → internal/shared}/network/metadata.renderer.js +0 -0
  538. /package/dist/{shared → internal/shared}/observability/debug-meta.sanitizer.d.ts +0 -0
  539. /package/dist/{shared → internal/shared}/observability/debug-meta.sanitizer.js +0 -0
  540. /package/dist/{shared → internal/shared}/observability/performance.d.ts +0 -0
  541. /package/dist/{shared → internal/shared}/observability/performance.js +0 -0
  542. /package/dist/{shared → internal/shared}/observability/trace.d.ts +0 -0
  543. /package/dist/{shared → internal/shared}/observability/trace.js +0 -0
  544. /package/dist/{shared → internal/shared}/utils/claim-safety.d.ts +0 -0
  545. /package/dist/{shared → internal/shared}/utils/claim-safety.js +0 -0
  546. /package/dist/{shared → internal/shared}/utils/telegram-handle.d.ts +0 -0
  547. /package/dist/{shared → internal/shared}/utils/telegram-handle.js +0 -0
  548. /package/dist/{shared/interfaces/database.capabilities.js → platform/database/capabilities.js} +0 -0
  549. /package/dist/{shared/interfaces/database.entities.js → platform/database/entities.js} +0 -0
  550. /package/dist/{shared/interfaces/database.identity-queries.js → platform/database/identity-queries.js} +0 -0
  551. /package/dist/{agents/agent.dispatcher.port.js → platform/database/negotiation.js} +0 -0
  552. /package/dist/{chat/chat.persona.js → platform/database/opportunity-queries.js} +0 -0
  553. /package/dist/{contexts/context.tools.port.js → platform/discovery/embedder.js} +0 -0
  554. /package/dist/{shared/interfaces/scraper.interface.d.ts → platform/discovery/scraper.d.ts} +0 -0
  555. /package/dist/{negotiations/negotiation.deadlock.contracts.js → platform/discovery/scraper.js} +0 -0
  556. /package/dist/{shared/interfaces/enrichment.interface.d.ts → platform/enrichment/ports.d.ts} +0 -0
  557. /package/dist/{negotiations/negotiation.tools.port.js → platform/enrichment/ports.js} +0 -0
  558. /package/dist/{opportunities/opportunity.tools.port.js → platform/runtime/observability.js} +0 -0
  559. /package/dist/{questions/question.input.js → protocol/core.js} +0 -0
  560. /package/dist/{shared → protocol}/schemas/chat-context.schema.d.ts +0 -0
  561. /package/dist/{shared → protocol}/schemas/chat-context.schema.js +0 -0
@@ -1,808 +0,0 @@
1
- import { z } from "zod";
2
- import { IntentClarifier } from "./intent.clarifier.js";
3
- import { DEFAULT_SPECIFICITY_WARNING, normalizeIntentDescription } from "./intent.proposal.js";
4
- import { protocolLogger } from "../shared/observability/protocol.logger.js";
5
- import { traceGraph } from "../shared/observability/trace.js";
6
- import { success, error, UUID_REGEX } from "../shared/agent/tool.helpers.js";
7
- import { invokeWithAbortSignal } from "../shared/agent/model-signal.js";
8
- import { deriveAllowedNetworkIds, focusedIntentId, focusedNetworkId, focusedNetworkLabel } from "../shared/agent/tool.scope.js";
9
- const logger = protocolLogger("ChatTools:Intent");
10
- let intentClarifier;
11
- function getIntentClarifier() {
12
- intentClarifier ?? (intentClarifier = new IntentClarifier());
13
- return intentClarifier;
14
- }
15
- async function buildTypedClarificationResult(params) {
16
- const clarification = await getIntentClarifier().invoke(params.description, params.userProfile, params.activeIntentsContext ?? "");
17
- if (!clarification.needsClarification)
18
- return null;
19
- return JSON.stringify({
20
- success: false,
21
- needsClarification: true,
22
- underspecificationType: clarification.underspecificationType,
23
- suggestedDescription: clarification.suggestedDescription,
24
- clarificationMessage: clarification.clarificationMessage,
25
- missingFields: [clarification.underspecificationType],
26
- message: clarification.clarificationMessage,
27
- debugSteps: params.debugSteps,
28
- });
29
- }
30
- /** Replace the lazy clarifier in deterministic tool tests. */
31
- export function setIntentClarifierForTesting(clarifier) {
32
- intentClarifier = clarifier ?? undefined;
33
- }
34
- /**
35
- * Sanitize JSON string for use inside a markdown code fence (```). Escapes backticks
36
- * so embedded ``` cannot close the fence prematurely.
37
- */
38
- function sanitizeJsonForCodeFence(json) {
39
- return json.replace(/`/g, "\\u0060");
40
- }
41
- /** When context is network-scoped, verifies the caller is still a member of that index. Returns error message or null. */
42
- async function ensureScopedMembership(context, systemDb) {
43
- const scopedNetworkId = focusedNetworkId(context);
44
- if (!scopedNetworkId)
45
- return null;
46
- const isMember = await systemDb.isNetworkMember(scopedNetworkId, context.userId);
47
- if (!isMember) {
48
- return `This chat is scoped to ${focusedNetworkLabel(context)}. You are no longer a member of this community.`;
49
- }
50
- return null;
51
- }
52
- function buildApprovedProfileFallback(user) {
53
- const bio = user?.intro?.trim();
54
- if (!user || !bio)
55
- return "";
56
- return JSON.stringify({
57
- userId: user.id,
58
- identity: {
59
- name: user.name ?? "",
60
- bio,
61
- location: user.location?.trim() ?? "",
62
- },
63
- narrative: { context: bio },
64
- attributes: { skills: [], interests: [] },
65
- });
66
- }
67
- function isBroadAttributiveIntent(intent) {
68
- return intent.verification?.referential_breadth === "broad";
69
- }
70
- const NULL_LIKE_SPECIFICITY_WARNING_VALUES = new Set(["null", "undefined"]);
71
- function normalizeSpecificityWarning(value) {
72
- const warning = value?.trim();
73
- if (!warning)
74
- return null;
75
- return NULL_LIKE_SPECIFICITY_WARNING_VALUES.has(warning.toLowerCase()) ? null : warning;
76
- }
77
- function specificityWarningFor(intent) {
78
- return normalizeSpecificityWarning(intent.verification?.specificity_warning) ?? DEFAULT_SPECIFICITY_WARNING;
79
- }
80
- /** Convert graph failures into an accurate, machine-readable update-tool error. */
81
- export function describeIntentUpdateFailure(result) {
82
- const persistenceFailure = result.executionResults?.find((execution) => !execution.success);
83
- if (persistenceFailure) {
84
- return {
85
- failureCategory: 'persistence_failure',
86
- error: 'Intent update could not be persisted.',
87
- ...(persistenceFailure.error ? { details: persistenceFailure.error } : {}),
88
- };
89
- }
90
- const failure = result.validationFailures?.[0];
91
- if (failure) {
92
- const broadnessNote = failure.referentialBreadth === 'broad'
93
- ? ' Referential breadth was recorded as a warning; it was not the blocking reason.'
94
- : '';
95
- return {
96
- failureCategory: failure.category,
97
- error: `${failure.message}${broadnessNote}`,
98
- ...(failure.classification ? { details: `Speech act: ${failure.classification}.` } : {}),
99
- };
100
- }
101
- return {
102
- failureCategory: 'reconciliation_boundary',
103
- error: 'Intent update produced no executable action after target-boundary enforcement.',
104
- };
105
- }
106
- export function createIntentTools(defineTool, deps) {
107
- const { graphs, userDb } = deps;
108
- // ─────────────────────────────────────────────────────────────────────────────
109
- // INTENT CRUD
110
- // ─────────────────────────────────────────────────────────────────────────────
111
- const readIntents = defineTool({
112
- name: "read_intents",
113
- description: "Retrieves intents (signals of interest/need, e.g. 'Looking for a React developer in Berlin'). " +
114
- "Intents are the core unit of discovery — they represent what users are seeking and drive semantic matching for opportunities.\n\n" +
115
- "**Usage modes:**\n" +
116
- "- No parameters: returns the **caller's own** active intents. In an network-scoped chat the result is clamped to the reachable networks (the bound network plus the user's personal network). In an unscoped chat the result spans all of the user's active intents. There is no implicit default to the scoped network — to browse the bound community's intents, pass `networkId` explicitly.\n" +
117
- "- With networkId: returns **all members'** intents in that index (community browse path). Add userId to filter to one member.\n" +
118
- "- With userId in an network-scoped chat: reads that member's intents in the bound network. The target user must be a member of that index.\n" +
119
- "- With userId in an unscoped chat: only works for the current user (cannot read another user's global intents without an network scope).\n\n" +
120
- "**Workflow:** To explore what members of a network are looking for, first call read_network_memberships(networkId) to list members, " +
121
- "then read_intents(networkId) to see all intents in that community. " +
122
- "Each intent includes: id, description (payload), summary, confidence (0-1), inferenceType (explicit/implicit), status, and linked indexes.\n\n" +
123
- "**Returns:** Paginated list of intents with count. Use the intent IDs in subsequent calls to update_intent, delete_intent, or create_intent_index.",
124
- querySchema: z.object({
125
- networkId: z.string().optional().describe("Network UUID — filters intents to this network (community browse path: returns all members' intents). There is no implicit default in network-scoped chats; omit to get caller-owned intents across the reachable networks, or pass the scoped network UUID to browse community members. Get network IDs from read_networks."),
126
- userId: z.string().optional().describe("User ID — filters to this user's intents. In an network-scoped chat, this reads that member's intents in the bound network (no networkId required). In an unscoped chat, only the current user is allowed without networkId; cross-user reads require an network scope. Omit for caller-owned intents."),
127
- limit: z.number().int().min(1).max(100).optional().describe("Page size (1-100). Defaults to returning all results if omitted."),
128
- page: z.number().int().min(1).optional().describe("Page number (1-based). Only used when limit is also provided."),
129
- }),
130
- handler: async ({ context, query }) => {
131
- const scopeErr = await ensureScopedMembership(context, deps.systemDb);
132
- if (scopeErr)
133
- return error(scopeErr);
134
- // Distinguish "explicit network browse" from "implicit scope-aware read"
135
- const scopedNetworkId = focusedNetworkId(context);
136
- const scopedIntentId = focusedIntentId(context);
137
- const scopedIndexLabel = focusedNetworkLabel(context);
138
- const explicitNetworkId = query.networkId?.trim();
139
- const explicitUserId = query.userId?.trim();
140
- if (scopedIntentId && (explicitNetworkId || (explicitUserId && explicitUserId !== context.userId))) {
141
- return error("This chat is scoped to one selected intent. Only that intent is available here.");
142
- }
143
- // Validate explicit networkId format
144
- if (explicitNetworkId && !UUID_REGEX.test(explicitNetworkId)) {
145
- return error("Invalid network ID format.");
146
- }
147
- // Strict scope enforcement: in a scoped chat, the only allowed explicit
148
- // networkId is the envelope's scoped network. Cross-network browse must
149
- // happen in a separate unscoped chat or a chat scoped to that network.
150
- if (scopedNetworkId && explicitNetworkId && explicitNetworkId !== scopedNetworkId) {
151
- return error(`This chat is scoped to ${scopedIndexLabel}. You can only read intents from this community.`);
152
- }
153
- // Cross-user read in scoped chat: target user must be a member of the scoped network
154
- if (scopedNetworkId && explicitUserId && explicitUserId !== context.userId) {
155
- const isInScopedIndex = await deps.systemDb.isNetworkMember(scopedNetworkId, explicitUserId);
156
- if (!isInScopedIndex) {
157
- return error(`This chat is scoped to ${scopedIndexLabel}. You can only read intents from members of this community.`);
158
- }
159
- }
160
- // Cross-user global read is disallowed without an network scope
161
- if (!explicitNetworkId && !scopedNetworkId && explicitUserId && explicitUserId !== context.userId) {
162
- return error("Cannot read another user's global intents. Use networkId to scope to a shared network.");
163
- }
164
- // Membership check for explicit cross-network reads in unscoped chats
165
- if (!scopedNetworkId && explicitNetworkId) {
166
- const callerIsMember = await deps.systemDb.isNetworkMember(explicitNetworkId, context.userId);
167
- if (!callerIsMember) {
168
- return error("You can only read intents from indexes you are a member of.");
169
- }
170
- }
171
- // ── Choose the read mode ──
172
- // 1. Explicit networkId (browse all members in that index) — pass networkId, optionally + queryUserId.
173
- // 2. Explicit userId in a scoped chat — read that user's intents in the bound network.
174
- // 3. Explicit userId in an unscoped chat — only self (cross-user rejected above); global "my intents".
175
- // 4. Implicit (no explicit network/user) in scoped chat — pass indexScope, no networkId.
176
- // 5. Implicit in unscoped chat — global getActiveIntents (caller's own).
177
- const graphInput = {
178
- userId: context.userId,
179
- userProfile: "",
180
- operationMode: 'read',
181
- };
182
- if (scopedIntentId) {
183
- const intent = await deps.systemDb.getIntent(scopedIntentId);
184
- if (!intent || intent.userId !== context.userId || intent.archivedAt) {
185
- return error("This selected intent is no longer available.");
186
- }
187
- return success({
188
- count: 1,
189
- totalCount: 1,
190
- intents: [{
191
- id: intent.id,
192
- description: intent.payload,
193
- summary: intent.summary,
194
- createdAt: intent.createdAt,
195
- }],
196
- scopeRestriction: {
197
- isScoped: true,
198
- scopedToIntent: scopedIntentId,
199
- message: "Results are restricted to the selected intent.",
200
- },
201
- });
202
- }
203
- if (explicitNetworkId) {
204
- graphInput.networkId = explicitNetworkId;
205
- if (explicitUserId)
206
- graphInput.queryUserId = explicitUserId;
207
- }
208
- else if (explicitUserId && scopedNetworkId) {
209
- // Scoped chat + userId: implicit network is the chat's bound network.
210
- // Membership of the target user was verified above.
211
- graphInput.networkId = scopedNetworkId;
212
- graphInput.queryUserId = explicitUserId;
213
- }
214
- else if (explicitUserId) {
215
- // Unscoped chat + userId: only allowed for self (others rejected above).
216
- graphInput.queryUserId = explicitUserId;
217
- graphInput.allUserIntents = true;
218
- }
219
- else if (scopedNetworkId) {
220
- // Scoped chat, implicit read: caller-only across reachable networks.
221
- graphInput.indexScope = deriveAllowedNetworkIds({
222
- memberships: context.userNetworks,
223
- scopeType: 'network',
224
- scopeId: scopedNetworkId,
225
- });
226
- }
227
- else {
228
- // Unscoped, implicit read: caller's global intents.
229
- graphInput.allUserIntents = true;
230
- }
231
- const _readIntentGraphStart = Date.now();
232
- const result = await traceGraph("intent", () => invokeWithAbortSignal(graphs.intent, graphInput));
233
- const _readIntentGraphMs = Date.now() - _readIntentGraphStart;
234
- if (result.readResult) {
235
- if (result.readResult.count === 0 && result.readResult.message && /not a member|Network not found/i.test(result.readResult.message)) {
236
- return error(result.readResult.message);
237
- }
238
- const shouldPaginate = query.limit !== undefined || query.page !== undefined;
239
- if (shouldPaginate && Array.isArray(result.readResult.intents)) {
240
- const limit = query.limit ?? 20;
241
- const page = query.page ?? 1;
242
- const offset = (page - 1) * limit;
243
- const pagedIntents = result.readResult.intents.slice(offset, offset + limit);
244
- return success({
245
- ...result.readResult,
246
- count: pagedIntents.length,
247
- totalCount: result.readResult.intents.length,
248
- limit,
249
- page,
250
- totalPages: Math.ceil(result.readResult.intents.length / limit),
251
- intents: pagedIntents,
252
- _graphTimings: [{ name: 'intent', durationMs: _readIntentGraphMs, agents: result.agentTimings ?? [] }],
253
- });
254
- }
255
- return success({ ...result.readResult, _graphTimings: [{ name: 'intent', durationMs: _readIntentGraphMs, agents: result.agentTimings ?? [] }] });
256
- }
257
- return error("Failed to fetch intents.");
258
- },
259
- });
260
- const createIntent = defineTool({
261
- name: "create_intent",
262
- description: "Creates a new intent (signal of interest/need) for the authenticated user. Intents drive the discovery engine — once created, " +
263
- "the system automatically evaluates them against indexes the user belongs to, links them to relevant communities, and begins " +
264
- "searching for matching opportunities (complementary intents from other users).\n\n" +
265
- "**What to pass:** A clear, concept-based description of what the user is looking for (e.g. 'Looking for an AI/ML co-founder in Berlin', " +
266
- "'Need a designer for a mobile app project'). If the user provided a URL, scrape it with scrape_url first and synthesize the content into a description.\n\n" +
267
- "**What happens:** The system runs inference (extracting structured intents), verification (checking specificity and speech-act type), " +
268
- "and durably stores an owner-scoped proposal containing the exact normalized description, optional network scope, and complete verifier output before returning a proposal widget. The intent itself is NOT yet persisted — the user must approve the proposal first.\n\n" +
269
- "**Returns:** An intent_proposal code block that MUST be included verbatim in the response. The frontend renders it as an interactive " +
270
- "card the user can approve or skip. On approval, the intent is persisted, indexed, and discovery begins.\n\n" +
271
- "**Next steps after approval:** The intent is automatically linked to relevant indexes and becomes eligible for background matching. " +
272
- "Background processing creates opportunities when matches are found; use list_opportunities only to review persisted results.\n\n" +
273
- "**Specificity gate.** Before calling this tool, judge whether the description is concrete enough to be " +
274
- "useful for matching. If the user says \"find a job\", \"meet people\", or \"learn something\", that's too " +
275
- "vague — FIRST call read_user_contexts() + read_intents() to understand their context, THEN propose a " +
276
- "refined version (\"Based on your background in X, did you mean 'Y'?\") and wait for confirmation before " +
277
- "calling create_intent. Specific asks (\"senior UX design role at a tech company in Berlin\") can go " +
278
- "directly to create_intent.\n\n" +
279
- "**URL handling.** If the user pastes a URL describing the intent (e.g. a job posting), call scrape_url " +
280
- "first with objective=\"Extract key details for an intent\", synthesize a conceptual description from the " +
281
- "content, then call create_intent with the synthesis. Exception: profile URLs (LinkedIn, GitHub, X) passed " +
282
- "to create_user_context are handled by that tool directly — do not scrape first.",
283
- querySchema: z.object({
284
- description: z.string().describe("A clear, specific description of what the user is looking for. Should be concept-based, not a raw URL. If the user shared a URL, scrape it first with scrape_url and pass the synthesized content here. Vague descriptions will be rejected — include what kind, what for, and/or timeframe."),
285
- networkId: z.string().optional().describe("Network UUID to link the intent to upon creation. Defaults to the scoped network in network-scoped chats. Get network IDs from read_networks. If omitted, the system auto-assigns to relevant networks based on their prompts."),
286
- autoApprove: z.boolean().optional().describe("When true, automatically persists all verified intents without returning proposal cards for manual approval. MCP agents SHOULD set this to true since there is no UI for card-based approval. Web chat agents should omit or set to false to get interactive proposal cards."),
287
- }),
288
- handler: async ({ context, query }) => {
289
- const scopeErr = await ensureScopedMembership(context, deps.systemDb);
290
- if (scopeErr)
291
- return error(scopeErr);
292
- if (!query.description?.trim()) {
293
- return error("Description is required.");
294
- }
295
- const scopedNetworkId = focusedNetworkId(context);
296
- const scopedIntentId = focusedIntentId(context);
297
- const scopedIndexLabel = focusedNetworkLabel(context);
298
- if (scopedIntentId) {
299
- return error("This chat is scoped to an existing selected intent. Update that intent instead of creating a different one here.");
300
- }
301
- // Strict scope enforcement
302
- if (scopedNetworkId && query.networkId?.trim() && query.networkId.trim() !== scopedNetworkId) {
303
- return error(`This chat is scoped to ${scopedIndexLabel}. You can only create intents in this community.`);
304
- }
305
- const effectiveIndexId = scopedNetworkId || query.networkId?.trim() || undefined;
306
- const scopeEnvelope = scopedNetworkId
307
- ? { scopeType: 'network', scopeId: scopedNetworkId }
308
- : {};
309
- // Fetch profile (the intent graph needs it for inference)
310
- const _profileGraphStart1 = Date.now();
311
- const profileResult = await traceGraph("profile", () => invokeWithAbortSignal(graphs.profile, { userId: context.userId, operationMode: 'query' }));
312
- const _profileGraphMs1 = Date.now() - _profileGraphStart1;
313
- const latestUser = profileResult.profile ? undefined : typeof userDb.getUser === "function" ? await userDb.getUser() : context.user;
314
- const approvedProfileFallback = profileResult.profile ? "" : buildApprovedProfileFallback(latestUser);
315
- const userProfile = profileResult.profile ? JSON.stringify(profileResult.profile) : approvedProfileFallback;
316
- // Run inference + verification only (propose mode — no DB persistence)
317
- const _intentGraphStart1 = Date.now();
318
- const result = await traceGraph("intent", () => invokeWithAbortSignal(graphs.intent, {
319
- userId: context.userId,
320
- userProfile,
321
- inputContent: query.description,
322
- operationMode: 'propose',
323
- ...(effectiveIndexId ? { networkId: effectiveIndexId } : {}),
324
- ...scopeEnvelope,
325
- }));
326
- const _intentGraphMs1 = Date.now() - _intentGraphStart1;
327
- logger.debug("Intent graph propose response", { result });
328
- const verified = result.verifiedIntents || [];
329
- // MCP contexts have no interactive UI for proposal cards — default to auto-approve
330
- const shouldAutoApprove = query.autoApprove ?? context.isMcp ?? false;
331
- // Extract trace from graph and convert to debugSteps
332
- const trace = Array.isArray(result.trace) ? result.trace : [];
333
- const debugSteps = trace.map((t) => ({
334
- step: t.node,
335
- detail: t.detail,
336
- ...(t.data ? { data: t.data } : {}),
337
- }));
338
- if (verified.length === 0) {
339
- // Build a descriptive rejection reason from the trace so the ReACT agent
340
- // can retry with a better description or ask the user for clarification.
341
- // When inference produces 0 intents, propose mode exits before verification
342
- // runs — so we check inference trace first.
343
- const verificationTrace = debugSteps.find((s) => s.step === "verification");
344
- const typedClarification = await buildTypedClarificationResult({
345
- description: query.description,
346
- userProfile,
347
- activeIntentsContext: result.activeIntents,
348
- debugSteps,
349
- });
350
- if (typedClarification)
351
- return typedClarification;
352
- if (!verificationTrace) {
353
- const inferenceHint = debugSteps.find((s) => s.step === "inference")?.detail
354
- ?? "no intents extracted";
355
- return error(`No actionable intent was extracted (${inferenceHint}). ` +
356
- `Please retry with an explicit goal or ask the user what outcome they want.`, debugSteps);
357
- }
358
- const rejectionHint = verificationTrace.detail ?? "all candidate intents were filtered as invalid or too vague";
359
- return error(`Intent verification failed (${rejectionHint}). ` +
360
- `The description may have been classified as a statement rather than a goal. ` +
361
- `Retry with an explicit goal or ask the user what outcome they want.`, debugSteps);
362
- }
363
- // ── Auto-approve path (for MCP agents or explicit opt-in) ──
364
- if (shouldAutoApprove) {
365
- const broadIntents = verified.filter(isBroadAttributiveIntent);
366
- if (broadIntents.length > 0) {
367
- const typedClarification = await buildTypedClarificationResult({
368
- description: broadIntents[0].description,
369
- userProfile,
370
- activeIntentsContext: result.activeIntents,
371
- debugSteps,
372
- });
373
- if (typedClarification)
374
- return typedClarification;
375
- const first = broadIntents[0];
376
- const missing = first.verification?.missing_selectional_constraints ?? [];
377
- const missingHint = missing.length > 0
378
- ? ` Missing specifics: ${missing.map((m) => m.replace(/_/g, " ")).join(", ")}.`
379
- : "";
380
- return error(`${specificityWarningFor(first)}${missingHint} ` +
381
- `Please ask the user to clarify before creating this signal, or retry with a narrower description.`, debugSteps);
382
- }
383
- const createdIntents = [];
384
- const createTimings = [];
385
- for (const v of verified) {
386
- const _createGraphStart = Date.now();
387
- const createResult = await traceGraph("intent", () => invokeWithAbortSignal(graphs.intent, {
388
- userId: context.userId,
389
- userProfile,
390
- inputContent: v.description,
391
- operationMode: 'create',
392
- ...(effectiveIndexId ? { networkId: effectiveIndexId } : {}),
393
- ...scopeEnvelope,
394
- }));
395
- const _createGraphMs = Date.now() - _createGraphStart;
396
- createTimings.push({ name: 'intent-create', durationMs: _createGraphMs, agents: createResult.agentTimings ?? [] });
397
- const succeeded = createResult.executionResults?.some((r) => r.success);
398
- if (succeeded) {
399
- createdIntents.push({
400
- description: v.description,
401
- confidence: v.score != null ? Math.round(v.score * 100) / 100 : null,
402
- speechActType: v.verification?.classification ?? null,
403
- });
404
- }
405
- }
406
- return success({
407
- created: createdIntents.length > 0,
408
- count: createdIntents.length,
409
- intents: createdIntents,
410
- message: createdIntents.length > 0
411
- ? `Created ${createdIntents.length} intent${createdIntents.length > 1 ? 's' : ''} successfully. The system will automatically index them and begin searching for matching opportunities.`
412
- : 'Intent creation failed — the intents could not be persisted.',
413
- debugSteps,
414
- _graphTimings: [
415
- { name: 'enrichment', durationMs: _profileGraphMs1, agents: profileResult.agentTimings ?? [] },
416
- { name: 'intent-propose', durationMs: _intentGraphMs1, agents: result.agentTimings ?? [] },
417
- ...createTimings,
418
- ],
419
- });
420
- }
421
- // ── Proposal path (for web chat with interactive cards) ──
422
- // Persist complete verifier output before emitting any usable card.
423
- if (!deps.intentProposalStore) {
424
- return error("Verified intent proposals are unavailable because durable proposal storage is not configured.");
425
- }
426
- const proposals = [];
427
- const proposalBlocks = [];
428
- for (const v of verified) {
429
- if (!v.verification) {
430
- return error("Intent verification produced no authoritative analysis; no proposal was created.", debugSteps);
431
- }
432
- const proposalId = crypto.randomUUID();
433
- const normalizedDescription = normalizeIntentDescription(v.description);
434
- const isBroad = isBroadAttributiveIntent(v);
435
- proposals.push({
436
- proposalId,
437
- userId: context.userId,
438
- description: normalizedDescription,
439
- ...(effectiveIndexId ? { networkId: effectiveIndexId } : {}),
440
- analysis: {
441
- verifierOutput: v.verification,
442
- combinedScore: v.score ?? null,
443
- },
444
- });
445
- const data = {
446
- proposalId,
447
- description: normalizedDescription,
448
- ...(effectiveIndexId ? { networkId: effectiveIndexId } : {}),
449
- confidence: v.score != null ? Math.round(v.score * 100) / 100 : null,
450
- speechActType: v.verification?.classification ?? null,
451
- semanticEntropy: v.verification?.semantic_entropy ?? null,
452
- referentialBreadth: v.verification?.referential_breadth ?? null,
453
- missingSelectionalConstraints: v.verification?.missing_selectional_constraints ?? [],
454
- specificityWarning: isBroad ? specificityWarningFor(v) : normalizeSpecificityWarning(v.verification?.specificity_warning),
455
- };
456
- proposalBlocks.push("```intent_proposal\n" +
457
- sanitizeJsonForCodeFence(JSON.stringify(data)) +
458
- "\n```");
459
- }
460
- await deps.intentProposalStore.createProposals(proposals);
461
- const blocksText = proposalBlocks.join("\n\n");
462
- return success({
463
- proposed: true,
464
- count: verified.length,
465
- message: `IMPORTANT: Include the following \`\`\`intent_proposal code blocks EXACTLY as-is in your response (they render as interactive cards for the user to approve or skip):\n\n${blocksText}`,
466
- debugSteps,
467
- _graphTimings: [
468
- { name: 'enrichment', durationMs: _profileGraphMs1, agents: profileResult.agentTimings ?? [] },
469
- { name: 'intent', durationMs: _intentGraphMs1, agents: result.agentTimings ?? [] },
470
- ],
471
- });
472
- },
473
- });
474
- const updateIntent = defineTool({
475
- name: "update_intent",
476
- description: "Updates an existing intent's description. After updating, the system re-processes it through inference and verification, " +
477
- "re-evaluates its index assignments, and makes the approved signal eligible for background matching.\n\n" +
478
- "**When to use:** When the user wants to refine or change what they're looking for — e.g. narrowing scope, adding specificity, " +
479
- "or pivoting to a different need. Prefer updating over delete+create to preserve the intent's history and existing index links.\n\n" +
480
- "**Returns:** Updated `intentId` and `description`, plus a confirmation message. The intent's embeddings and index relevancy scores are recalculated automatically.",
481
- querySchema: z.object({
482
- intentId: z.string().describe("The UUID of the intent to update. Get this from read_intents results."),
483
- description: z.string().describe("The updated description of what the user is looking for. Same guidelines as create_intent — should be clear and specific."),
484
- }),
485
- handler: async ({ context, query }) => {
486
- const scopeErr = await ensureScopedMembership(context, deps.systemDb);
487
- if (scopeErr)
488
- return error(scopeErr);
489
- const intentId = query.intentId?.trim() ?? "";
490
- if (!UUID_REGEX.test(intentId)) {
491
- return error("Invalid intent ID format.");
492
- }
493
- const scopedIntentId = focusedIntentId(context);
494
- if (scopedIntentId && scopedIntentId !== intentId) {
495
- return error("This chat is scoped to one selected intent. You can only update that intent here.");
496
- }
497
- // Ownership guard: caller must own the intent
498
- const intent = await deps.systemDb.getIntent(intentId);
499
- if (!intent || intent.userId !== context.userId) {
500
- return error("Intent not found or you can only update your own intents.");
501
- }
502
- if (intent.archivedAt) {
503
- return error("This intent is archived and cannot be updated. Create a new intent instead.");
504
- }
505
- const scopedNetworkId = focusedNetworkId(context);
506
- const scopedIndexLabel = focusedNetworkLabel(context);
507
- // Strict scope enforcement: when chat is network-scoped, verify intent is linked to that index
508
- if (scopedNetworkId) {
509
- const db = deps.userDb;
510
- const intentNetworks = await db.getNetworkIdsForIntent(intentId);
511
- if (!intentNetworks.includes(scopedNetworkId)) {
512
- return error(`This chat is scoped to ${scopedIndexLabel}. You can only update intents linked to this community.`);
513
- }
514
- }
515
- const _profileGraphStart2 = Date.now();
516
- const profileResult = await traceGraph("profile", () => invokeWithAbortSignal(graphs.profile, { userId: context.userId, operationMode: 'query' }));
517
- const _profileGraphMs2 = Date.now() - _profileGraphStart2;
518
- const latestUser = profileResult.profile ? undefined : typeof userDb.getUser === "function" ? await userDb.getUser() : context.user;
519
- const approvedProfileFallback = profileResult.profile ? "" : buildApprovedProfileFallback(latestUser);
520
- const userProfile = profileResult.profile ? JSON.stringify(profileResult.profile) : approvedProfileFallback;
521
- const _intentGraphStart2 = Date.now();
522
- const result = await traceGraph("intent", () => invokeWithAbortSignal(graphs.intent, {
523
- userId: context.userId,
524
- userProfile,
525
- operationMode: 'update',
526
- inputContent: query.description,
527
- targetIntentIds: [intentId],
528
- ...(scopedNetworkId && { networkId: scopedNetworkId, scopeType: 'network', scopeId: scopedNetworkId }),
529
- }));
530
- const _intentGraphMs2 = Date.now() - _intentGraphStart2;
531
- if (!result.executionResults?.some((r) => r.success)) {
532
- return JSON.stringify({
533
- success: false,
534
- ...describeIntentUpdateFailure(result),
535
- });
536
- }
537
- return success({
538
- message: "Intent updated.",
539
- intentId,
540
- description: query.description,
541
- _graphTimings: [
542
- { name: 'enrichment', durationMs: _profileGraphMs2, agents: profileResult.agentTimings ?? [] },
543
- { name: 'intent', durationMs: _intentGraphMs2, agents: result.agentTimings ?? [] },
544
- ],
545
- });
546
- },
547
- });
548
- const deleteIntent = defineTool({
549
- name: "delete_intent",
550
- description: "Archives (soft-deletes) an intent, removing it from active discovery. The intent is not permanently deleted — it is marked as archived " +
551
- "and no longer participates in opportunity matching or index evaluation.\n\n" +
552
- "**When to use:** When the user's need has been fulfilled, is no longer relevant, or was created by mistake. " +
553
- "If the user wants to change the description instead, use update_intent to preserve history.\n\n" +
554
- "**Returns:** Confirmation that the intent was archived. Previously created opportunities from this intent remain but won't generate new ones.",
555
- querySchema: z.object({
556
- intentId: z.string().describe("The UUID of the intent to archive. Get this from read_intents results."),
557
- }),
558
- handler: async ({ context, query }) => {
559
- const scopeErr = await ensureScopedMembership(context, deps.systemDb);
560
- if (scopeErr)
561
- return error(scopeErr);
562
- const intentId = query.intentId?.trim() ?? "";
563
- if (!UUID_REGEX.test(intentId)) {
564
- return error("Invalid intent ID format.");
565
- }
566
- // Ownership guard: caller must own the intent
567
- const intent = await deps.systemDb.getIntent(intentId);
568
- if (!intent || intent.userId !== context.userId) {
569
- return error("Intent not found or you can only delete your own intents.");
570
- }
571
- const scopedNetworkId = focusedNetworkId(context);
572
- const scopedIntentId = focusedIntentId(context);
573
- const scopedIndexLabel = focusedNetworkLabel(context);
574
- if (scopedIntentId && scopedIntentId !== intentId) {
575
- return error("This chat is scoped to one selected intent. You can only delete that intent here.");
576
- }
577
- // Strict scope enforcement: when chat is network-scoped, verify intent is linked to that index
578
- if (scopedNetworkId) {
579
- const db = deps.userDb;
580
- const intentNetworks = await db.getNetworkIdsForIntent(intentId);
581
- if (!intentNetworks.includes(scopedNetworkId)) {
582
- return error(`This chat is scoped to ${scopedIndexLabel}. You can only delete intents linked to this community.`);
583
- }
584
- }
585
- const _deleteIntentGraphStart = Date.now();
586
- const result = await traceGraph("intent", () => invokeWithAbortSignal(graphs.intent, {
587
- userId: context.userId,
588
- userProfile: "",
589
- operationMode: 'delete',
590
- targetIntentIds: [intentId],
591
- ...(scopedNetworkId && { networkId: scopedNetworkId, scopeType: 'network', scopeId: scopedNetworkId }),
592
- }));
593
- const _deleteIntentGraphMs = Date.now() - _deleteIntentGraphStart;
594
- if (result.executionResults?.some((r) => !r.success)) {
595
- return error("Failed to delete intent.");
596
- }
597
- return success({
598
- message: "Intent archived successfully.",
599
- _graphTimings: [{ name: 'intent', durationMs: _deleteIntentGraphMs, agents: result.agentTimings ?? [] }],
600
- });
601
- },
602
- });
603
- // ─────────────────────────────────────────────────────────────────────────────
604
- // INTENT–INDEX JUNCTION (link / list / unlink)
605
- // ─────────────────────────────────────────────────────────────────────────────
606
- const createIntentIndex = defineTool({
607
- name: "create_intent_index",
608
- description: "Manually links an intent to a network (community), making the approved signal eligible for background matching within that index. " +
609
- "Normally intents are auto-assigned to relevant indexes on creation, but use this to explicitly add an intent to an additional index.\n\n" +
610
- "**When to use:** When the user wants to share an existing intent with a specific community they belong to, " +
611
- "or when auto-assignment missed a network the user considers relevant.\n\n" +
612
- "**Returns:** Confirmation that the link was created. The intent will now appear in that index's intent list and participate in discovery within that community.",
613
- querySchema: z.object({
614
- intentId: z.string().describe("The UUID of the intent to link. Get this from read_intents results."),
615
- networkId: z.string().optional().describe("The UUID of the network to link the intent to. Get this from read_networks. Defaults to the scoped network in network-scoped chats."),
616
- }),
617
- handler: async ({ context, query }) => {
618
- const scopeErr = await ensureScopedMembership(context, deps.systemDb);
619
- if (scopeErr)
620
- return error(scopeErr);
621
- const scopedNetworkId = focusedNetworkId(context);
622
- const scopedIntentId = focusedIntentId(context);
623
- const scopedIndexLabel = focusedNetworkLabel(context);
624
- const intentId = query.intentId?.trim() ?? "";
625
- const networkId = query.networkId?.trim() || scopedNetworkId || "";
626
- if (scopedIntentId && intentId !== scopedIntentId) {
627
- return error("This chat is scoped to one selected intent. You can only link that intent here.");
628
- }
629
- if (!UUID_REGEX.test(intentId) || !UUID_REGEX.test(networkId)) {
630
- return error("Invalid ID format. Both must be UUIDs.");
631
- }
632
- // Strict scope enforcement: when chat is network-scoped, only allow linking to that index
633
- if (scopedNetworkId && networkId !== scopedNetworkId) {
634
- return error(`This chat is scoped to ${scopedIndexLabel}. You can only link intents to this community.`);
635
- }
636
- const _createIntentIndexGraphStart = Date.now();
637
- const result = await traceGraph("intent_network", () => invokeWithAbortSignal(graphs.intentIndex, {
638
- userId: context.userId,
639
- networkId,
640
- intentId,
641
- operationMode: 'create',
642
- skipEvaluation: true,
643
- }));
644
- const _createIntentIndexGraphMs = Date.now() - _createIntentIndexGraphStart;
645
- if (result.mutationResult) {
646
- if (result.mutationResult.success) {
647
- const alreadyExisted = result.mutationResult.message?.includes('already in this network') ?? false;
648
- return success({
649
- created: !alreadyExisted,
650
- message: result.mutationResult.message,
651
- _graphTimings: [{ name: 'intent_network', durationMs: _createIntentIndexGraphMs, agents: result.agentTimings ?? [] }],
652
- });
653
- }
654
- return error(result.mutationResult.error || "Failed to link intent to network.");
655
- }
656
- return error("Failed to link intent to network.");
657
- },
658
- });
659
- const readIntentIndexes = defineTool({
660
- name: "read_intent_indexes",
661
- description: "Reads the many-to-many links between intents and indexes. Use this to understand which intents are shared in which communities, " +
662
- "and which indexes a specific intent belongs to.\n\n" +
663
- "**Usage modes:**\n" +
664
- "- With networkId: lists all intents linked to that index. Add userId to filter to one member's intents in that index.\n" +
665
- "- With intentId + networkId: checks whether a specific intent is linked to a specific index.\n" +
666
- "- intentId alone requires a networkId (the system won't reveal all networks an intent is in).\n\n" +
667
- "**When to use:** To audit which intents are active in a community, verify an intent's index assignment before unlinking, " +
668
- "or check if a newly created intent was auto-assigned to the expected index.\n\n" +
669
- "**Returns:** List of intent-network links with relevancy scores (0-1, how well the intent fits the network's purpose).",
670
- querySchema: z.object({
671
- intentId: z.string().optional().describe("Intent UUID — check if this specific intent is linked to the specified index. Must be combined with networkId."),
672
- networkId: z.string().optional().describe("Network UUID — list all intents linked to this network. Get this from read_networks. Defaults to scoped network in network-scoped chats."),
673
- userId: z.string().optional().describe("Filter results to this user's intents within the specified index. Omit to see all members' intents."),
674
- }),
675
- handler: async ({ context, query }) => {
676
- const scopeErr = await ensureScopedMembership(context, deps.systemDb);
677
- if (scopeErr)
678
- return error(scopeErr);
679
- const scopedNetworkId = focusedNetworkId(context);
680
- const scopedIntentId = focusedIntentId(context);
681
- const scopedIndexLabel = focusedNetworkLabel(context);
682
- const intentId = query.intentId?.trim() || scopedIntentId || undefined;
683
- let networkId = query.networkId?.trim() || scopedNetworkId || undefined;
684
- const queryUserId = query.userId?.trim() || undefined;
685
- if (scopedIntentId && query.intentId?.trim() && query.intentId.trim() !== scopedIntentId) {
686
- return error("This chat is scoped to one selected intent. You can only read links for that intent here.");
687
- }
688
- if (scopedIntentId && queryUserId && queryUserId !== context.userId) {
689
- return error("This chat is scoped to one selected intent. Other users' intent links are not available here.");
690
- }
691
- if (intentId && !UUID_REGEX.test(intentId)) {
692
- return error("Invalid intent ID format.");
693
- }
694
- if (networkId && !UUID_REGEX.test(networkId)) {
695
- return error("Invalid network ID format.");
696
- }
697
- if (!intentId && !networkId) {
698
- return error("Provide networkId or intentId.");
699
- }
700
- // Strict scope enforcement: when chat is network-scoped, only allow querying that index
701
- if (scopedNetworkId && networkId && networkId !== scopedNetworkId) {
702
- return error(`This chat is scoped to ${scopedIndexLabel}. You can only read intent links from this community.`);
703
- }
704
- // When only intentId is provided, enforce scope - don't reveal all linked indexes
705
- if (intentId && !networkId) {
706
- if (scopedNetworkId) {
707
- // When scoped, only check if intent is linked to the scoped network
708
- networkId = scopedNetworkId;
709
- }
710
- else {
711
- // When unscoped, still don't reveal all networks - require explicit networkId
712
- return error("Please provide a networkId to check if the intent is linked to a specific network. Listing all linked networks is not supported.");
713
- }
714
- }
715
- const _readIntentIndexGraphStart = Date.now();
716
- const result = await traceGraph("intent_network", () => invokeWithAbortSignal(graphs.intentIndex, {
717
- userId: context.userId,
718
- networkId,
719
- intentId,
720
- operationMode: 'read',
721
- queryUserId,
722
- }));
723
- const _readIntentIndexGraphMs = Date.now() - _readIntentIndexGraphStart;
724
- if (result.error) {
725
- return error(result.error);
726
- }
727
- if (result.readResult) {
728
- return success({ ...result.readResult, _graphTimings: [{ name: 'intent_network', durationMs: _readIntentIndexGraphMs, agents: result.agentTimings ?? [] }] });
729
- }
730
- return error("Failed to fetch intent-network links.");
731
- },
732
- });
733
- const deleteIntentIndex = defineTool({
734
- name: "delete_intent_index",
735
- description: "Removes the link between an intent and a network. The intent itself is NOT deleted — it just stops being visible in that community " +
736
- "and is no longer eligible for background matching within that index. The intent may still be linked to other indexes.\n\n" +
737
- "**When to use:** When the user wants to withdraw an intent from a specific community without archiving it entirely. " +
738
- "Use read_intent_indexes first to verify the link exists.\n\n" +
739
- "**Returns:** Confirmation that the link was removed. To fully remove an intent, use delete_intent instead.",
740
- querySchema: z.object({
741
- intentId: z.string().describe("The UUID of the intent to unlink. Get this from read_intents or read_intent_indexes."),
742
- networkId: z.string().optional().describe("The UUID of the network to unlink from. Get this from read_networks. Defaults to the scoped network in network-scoped chats."),
743
- }),
744
- handler: async ({ context, query }) => {
745
- const scopeErr = await ensureScopedMembership(context, deps.systemDb);
746
- if (scopeErr)
747
- return error(scopeErr);
748
- const scopedNetworkId = focusedNetworkId(context);
749
- const scopedIntentId = focusedIntentId(context);
750
- const scopedIndexLabel = focusedNetworkLabel(context);
751
- const intentId = query.intentId?.trim() ?? "";
752
- const networkId = query.networkId?.trim() || scopedNetworkId || "";
753
- if (scopedIntentId && intentId !== scopedIntentId) {
754
- return error("This chat is scoped to one selected intent. You can only unlink that intent here.");
755
- }
756
- if (!UUID_REGEX.test(intentId) || !UUID_REGEX.test(networkId)) {
757
- return error("Invalid ID format. Both must be UUIDs.");
758
- }
759
- // Strict scope enforcement: when chat is network-scoped, only allow unlinking from that index
760
- if (scopedNetworkId && networkId !== scopedNetworkId) {
761
- return error(`This chat is scoped to ${scopedIndexLabel}. You can only unlink intents from this community.`);
762
- }
763
- const _deleteIntentIndexGraphStart = Date.now();
764
- const result = await traceGraph("intent_network", () => invokeWithAbortSignal(graphs.intentIndex, {
765
- userId: context.userId,
766
- networkId,
767
- intentId,
768
- operationMode: 'delete',
769
- }));
770
- const _deleteIntentIndexGraphMs = Date.now() - _deleteIntentIndexGraphStart;
771
- if (result.mutationResult) {
772
- if (result.mutationResult.success) {
773
- return success({
774
- deleted: true,
775
- message: result.mutationResult.message,
776
- _graphTimings: [{ name: 'intent_network', durationMs: _deleteIntentIndexGraphMs, agents: result.agentTimings ?? [] }],
777
- });
778
- }
779
- return error(result.mutationResult.error || "Failed to unlink.");
780
- }
781
- return error("Failed to unlink intent from network.");
782
- },
783
- });
784
- const searchIntents = defineTool({
785
- name: "search_intents",
786
- description: "Text-searches the authenticated user's own active signals by description. Case-insensitive substring " +
787
- "match over the signal's payload and summary. Use when the user references a past signal they wrote " +
788
- '("find my signal about React mentorship") or wants to audit what they\'ve posted.\n\n' +
789
- "Approved signals are matched in the background. Use list_opportunities only to review persisted opportunities after background matching has produced them.\n\n" +
790
- "**Returns:** `intents: [{ id, payload, summary, createdAt }]`, most recent first, up to `limit` (default 25).",
791
- querySchema: z.object({
792
- query: z.string().min(1).describe("Text to match against payload and summary (case-insensitive)."),
793
- limit: z
794
- .number()
795
- .int()
796
- .positive()
797
- .max(100)
798
- .optional()
799
- .describe("Maximum intents to return (default 25, max 100)."),
800
- }),
801
- handler: async ({ context, query }) => {
802
- const rows = await userDb.searchOwnIntents(query.query, query.limit ?? 25);
803
- logger.verbose("search_intents", { userId: context.userId, query: query.query, matched: rows.length });
804
- return success({ intents: rows });
805
- },
806
- });
807
- return [readIntents, createIntent, updateIntent, deleteIntent, createIntentIndex, readIntentIndexes, deleteIntentIndex, searchIntents];
808
- }