@moltzap/client 2026.811.0 → 2026.902.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 (429) hide show
  1. package/LICENSE +202 -21
  2. package/NOTICE +19 -0
  3. package/README.md +50 -0
  4. package/bin/moltzapd +9 -0
  5. package/dist/client-runtime.d.ts +10 -0
  6. package/dist/client-runtime.d.ts.map +1 -0
  7. package/dist/client-runtime.js +218 -0
  8. package/dist/client-runtime.js.map +1 -0
  9. package/dist/contract.d.ts +338 -0
  10. package/dist/contract.d.ts.map +1 -0
  11. package/dist/contract.js +213 -0
  12. package/dist/contract.js.map +1 -0
  13. package/dist/contract.types-check.d.ts +99 -0
  14. package/dist/contract.types-check.d.ts.map +1 -0
  15. package/dist/contract.types-check.js +7 -0
  16. package/dist/contract.types-check.js.map +1 -0
  17. package/dist/daemon/configuration.d.ts +46 -0
  18. package/dist/daemon/configuration.d.ts.map +1 -0
  19. package/dist/daemon/configuration.js +69 -0
  20. package/dist/daemon/configuration.js.map +1 -0
  21. package/dist/daemon/management.d.ts +23 -0
  22. package/dist/daemon/management.d.ts.map +1 -0
  23. package/dist/daemon/management.js +489 -0
  24. package/dist/daemon/management.js.map +1 -0
  25. package/dist/daemon/registration.d.ts +72 -0
  26. package/dist/daemon/registration.d.ts.map +1 -0
  27. package/dist/daemon/registration.js +109 -0
  28. package/dist/daemon/registration.js.map +1 -0
  29. package/dist/daemon/runtime/activation.d.ts +95 -0
  30. package/dist/daemon/runtime/activation.d.ts.map +1 -0
  31. package/dist/daemon/runtime/activation.js +99 -0
  32. package/dist/daemon/runtime/activation.js.map +1 -0
  33. package/dist/daemon/runtime/controller.d.ts +34 -0
  34. package/dist/daemon/runtime/controller.d.ts.map +1 -0
  35. package/dist/daemon/runtime/controller.js +106 -0
  36. package/dist/daemon/runtime/controller.js.map +1 -0
  37. package/dist/daemon/runtime/history-export.d.ts +23 -0
  38. package/dist/daemon/runtime/history-export.d.ts.map +1 -0
  39. package/dist/daemon/runtime/history-export.js +47 -0
  40. package/dist/daemon/runtime/history-export.js.map +1 -0
  41. package/dist/daemon/runtime/index.d.ts +24 -0
  42. package/dist/daemon/runtime/index.d.ts.map +1 -0
  43. package/dist/daemon/runtime/index.js +65 -0
  44. package/dist/daemon/runtime/index.js.map +1 -0
  45. package/dist/daemon/runtime/protocol.d.ts +63 -0
  46. package/dist/daemon/runtime/protocol.d.ts.map +1 -0
  47. package/dist/daemon/runtime/protocol.js +133 -0
  48. package/dist/daemon/runtime/protocol.js.map +1 -0
  49. package/dist/endpoint/addressing/index.d.ts +39 -0
  50. package/dist/endpoint/addressing/index.d.ts.map +1 -0
  51. package/dist/endpoint/addressing/index.js +114 -0
  52. package/dist/endpoint/addressing/index.js.map +1 -0
  53. package/dist/endpoint/engine-dissemination.d.ts +11 -0
  54. package/dist/endpoint/engine-dissemination.d.ts.map +1 -0
  55. package/dist/endpoint/engine-dissemination.js +71 -0
  56. package/dist/endpoint/engine-dissemination.js.map +1 -0
  57. package/dist/endpoint/engine-durability.d.ts +69 -0
  58. package/dist/endpoint/engine-durability.d.ts.map +1 -0
  59. package/dist/endpoint/engine-durability.js +210 -0
  60. package/dist/endpoint/engine-durability.js.map +1 -0
  61. package/dist/endpoint/engine-send.d.ts +50 -0
  62. package/dist/endpoint/engine-send.d.ts.map +1 -0
  63. package/dist/endpoint/engine-send.js +422 -0
  64. package/dist/endpoint/engine-send.js.map +1 -0
  65. package/dist/endpoint/engine-types.d.ts +132 -0
  66. package/dist/endpoint/engine-types.d.ts.map +1 -0
  67. package/dist/endpoint/engine-types.js +13 -0
  68. package/dist/endpoint/engine-types.js.map +1 -0
  69. package/dist/endpoint/engine.d.ts +14 -0
  70. package/dist/endpoint/engine.d.ts.map +1 -0
  71. package/dist/endpoint/engine.js +280 -0
  72. package/dist/endpoint/engine.js.map +1 -0
  73. package/dist/endpoint/protocol/evidence.d.ts +37 -0
  74. package/dist/endpoint/protocol/evidence.d.ts.map +1 -0
  75. package/dist/endpoint/protocol/evidence.js +80 -0
  76. package/dist/endpoint/protocol/evidence.js.map +1 -0
  77. package/dist/endpoint/protocol/index.d.ts +26 -0
  78. package/dist/endpoint/protocol/index.d.ts.map +1 -0
  79. package/dist/endpoint/protocol/index.js +543 -0
  80. package/dist/endpoint/protocol/index.js.map +1 -0
  81. package/dist/endpoint/recovery/barrier.d.ts +23 -0
  82. package/dist/endpoint/recovery/barrier.d.ts.map +1 -0
  83. package/dist/endpoint/recovery/barrier.js +47 -0
  84. package/dist/endpoint/recovery/barrier.js.map +1 -0
  85. package/dist/endpoint/recovery/index.d.ts +29 -0
  86. package/dist/endpoint/recovery/index.d.ts.map +1 -0
  87. package/dist/endpoint/recovery/index.js +489 -0
  88. package/dist/endpoint/recovery/index.js.map +1 -0
  89. package/dist/endpoint/recovery/reanchor/empty.d.ts +22 -0
  90. package/dist/endpoint/recovery/reanchor/empty.d.ts.map +1 -0
  91. package/dist/endpoint/recovery/reanchor/empty.js +163 -0
  92. package/dist/endpoint/recovery/reanchor/empty.js.map +1 -0
  93. package/dist/endpoint/recovery/reanchor/index.d.ts +30 -0
  94. package/dist/endpoint/recovery/reanchor/index.d.ts.map +1 -0
  95. package/dist/endpoint/recovery/reanchor/index.js +479 -0
  96. package/dist/endpoint/recovery/reanchor/index.js.map +1 -0
  97. package/dist/endpoint/recovery/state.d.ts +130 -0
  98. package/dist/endpoint/recovery/state.d.ts.map +1 -0
  99. package/dist/endpoint/recovery/state.js +296 -0
  100. package/dist/endpoint/recovery/state.js.map +1 -0
  101. package/dist/endpoint/recovery/store-evidence.d.ts +17 -0
  102. package/dist/endpoint/recovery/store-evidence.d.ts.map +1 -0
  103. package/dist/endpoint/recovery/store-evidence.js +79 -0
  104. package/dist/endpoint/recovery/store-evidence.js.map +1 -0
  105. package/dist/endpoint/recovery/store.d.ts +56 -0
  106. package/dist/endpoint/recovery/store.d.ts.map +1 -0
  107. package/dist/endpoint/recovery/store.js +499 -0
  108. package/dist/endpoint/recovery/store.js.map +1 -0
  109. package/dist/endpoint/representation-canonical.d.ts +17 -0
  110. package/dist/endpoint/representation-canonical.d.ts.map +1 -0
  111. package/dist/endpoint/representation-canonical.js +48 -0
  112. package/dist/endpoint/representation-canonical.js.map +1 -0
  113. package/dist/endpoint/representation-codec.d.ts +51 -0
  114. package/dist/endpoint/representation-codec.d.ts.map +1 -0
  115. package/dist/endpoint/representation-codec.js +159 -0
  116. package/dist/endpoint/representation-codec.js.map +1 -0
  117. package/dist/endpoint/representation-schemas.d.ts +1831 -0
  118. package/dist/endpoint/representation-schemas.d.ts.map +1 -0
  119. package/dist/endpoint/representation-schemas.js +195 -0
  120. package/dist/endpoint/representation-schemas.js.map +1 -0
  121. package/dist/endpoint/representation-verification.d.ts +79 -0
  122. package/dist/endpoint/representation-verification.d.ts.map +1 -0
  123. package/dist/endpoint/representation-verification.js +420 -0
  124. package/dist/endpoint/representation-verification.js.map +1 -0
  125. package/dist/endpoint/representation.d.ts +6 -0
  126. package/dist/endpoint/representation.d.ts.map +1 -0
  127. package/dist/endpoint/representation.js +8 -0
  128. package/dist/endpoint/representation.js.map +1 -0
  129. package/dist/endpoint/router-worker/index.d.ts +16 -0
  130. package/dist/endpoint/router-worker/index.d.ts.map +1 -0
  131. package/dist/endpoint/router-worker/index.js +547 -0
  132. package/dist/endpoint/router-worker/index.js.map +1 -0
  133. package/dist/endpoint/router-worker/types.d.ts +183 -0
  134. package/dist/endpoint/router-worker/types.d.ts.map +1 -0
  135. package/dist/endpoint/router-worker/types.js +31 -0
  136. package/dist/endpoint/router-worker/types.js.map +1 -0
  137. package/dist/endpoint/store/anchors.d.ts +83 -0
  138. package/dist/endpoint/store/anchors.d.ts.map +1 -0
  139. package/dist/endpoint/store/anchors.js +471 -0
  140. package/dist/endpoint/store/anchors.js.map +1 -0
  141. package/dist/endpoint/store/database/index.d.ts +6 -0
  142. package/dist/endpoint/store/database/index.d.ts.map +1 -0
  143. package/dist/endpoint/store/database/index.js +6 -0
  144. package/dist/endpoint/store/database/index.js.map +1 -0
  145. package/dist/endpoint/store/database/schema.d.ts +44 -0
  146. package/dist/endpoint/store/database/schema.d.ts.map +1 -0
  147. package/dist/endpoint/store/database/schema.js +345 -0
  148. package/dist/endpoint/store/database/schema.js.map +1 -0
  149. package/dist/endpoint/store/database/values.d.ts +119 -0
  150. package/dist/endpoint/store/database/values.d.ts.map +1 -0
  151. package/dist/endpoint/store/database/values.js +194 -0
  152. package/dist/endpoint/store/database/values.js.map +1 -0
  153. package/dist/endpoint/store/deliveries.d.ts +38 -0
  154. package/dist/endpoint/store/deliveries.d.ts.map +1 -0
  155. package/dist/endpoint/store/deliveries.js +124 -0
  156. package/dist/endpoint/store/deliveries.js.map +1 -0
  157. package/dist/endpoint/store/dissemination.d.ts +27 -0
  158. package/dist/endpoint/store/dissemination.d.ts.map +1 -0
  159. package/dist/endpoint/store/dissemination.js +139 -0
  160. package/dist/endpoint/store/dissemination.js.map +1 -0
  161. package/dist/endpoint/store/index.d.ts +15 -0
  162. package/dist/endpoint/store/index.d.ts.map +1 -0
  163. package/dist/endpoint/store/index.js +76 -0
  164. package/dist/endpoint/store/index.js.map +1 -0
  165. package/dist/endpoint/store/management.d.ts +42 -0
  166. package/dist/endpoint/store/management.d.ts.map +1 -0
  167. package/dist/endpoint/store/management.js +259 -0
  168. package/dist/endpoint/store/management.js.map +1 -0
  169. package/dist/endpoint/store/outbound.d.ts +62 -0
  170. package/dist/endpoint/store/outbound.d.ts.map +1 -0
  171. package/dist/endpoint/store/outbound.js +278 -0
  172. package/dist/endpoint/store/outbound.js.map +1 -0
  173. package/dist/endpoint/store/records.d.ts +56 -0
  174. package/dist/endpoint/store/records.d.ts.map +1 -0
  175. package/dist/endpoint/store/records.js +352 -0
  176. package/dist/endpoint/store/records.js.map +1 -0
  177. package/dist/endpoint/store/rows/index.d.ts +138 -0
  178. package/dist/endpoint/store/rows/index.d.ts.map +1 -0
  179. package/dist/endpoint/store/rows/index.js +307 -0
  180. package/dist/endpoint/store/rows/index.js.map +1 -0
  181. package/dist/endpoint/store/types.d.ts +223 -0
  182. package/dist/endpoint/store/types.d.ts.map +1 -0
  183. package/dist/endpoint/store/types.js +15 -0
  184. package/dist/endpoint/store/types.js.map +1 -0
  185. package/dist/endpoint/store.d.ts +10 -0
  186. package/dist/endpoint/store.d.ts.map +1 -0
  187. package/dist/endpoint/store.js +6 -0
  188. package/dist/endpoint/store.js.map +1 -0
  189. package/dist/harness-mcp-contract.d.ts +101 -0
  190. package/dist/harness-mcp-contract.d.ts.map +1 -0
  191. package/dist/harness-mcp-contract.js +61 -0
  192. package/dist/harness-mcp-contract.js.map +1 -0
  193. package/dist/harness-mcp-http.d.ts +19 -0
  194. package/dist/harness-mcp-http.d.ts.map +1 -0
  195. package/dist/{harness-mcp-server.js → harness-mcp-http.js} +43 -71
  196. package/dist/harness-mcp-http.js.map +1 -0
  197. package/dist/harness-mcp-subscription.d.ts +12 -7
  198. package/dist/harness-mcp-subscription.d.ts.map +1 -1
  199. package/dist/harness-mcp-subscription.js +113 -100
  200. package/dist/harness-mcp-subscription.js.map +1 -1
  201. package/dist/harness-mcp-wire.d.ts +26 -19
  202. package/dist/harness-mcp-wire.d.ts.map +1 -1
  203. package/dist/harness-mcp-wire.js +380 -67
  204. package/dist/harness-mcp-wire.js.map +1 -1
  205. package/dist/index.d.ts +4 -8
  206. package/dist/index.d.ts.map +1 -1
  207. package/dist/index.js +6 -8
  208. package/dist/index.js.map +1 -1
  209. package/dist/management-runtime.d.ts +217 -0
  210. package/dist/management-runtime.d.ts.map +1 -0
  211. package/dist/management-runtime.js +127 -0
  212. package/dist/management-runtime.js.map +1 -0
  213. package/dist/server.d.ts +16 -0
  214. package/dist/server.d.ts.map +1 -0
  215. package/dist/server.js +46 -0
  216. package/dist/server.js.map +1 -0
  217. package/dist/server.types-check.d.ts +23 -0
  218. package/dist/server.types-check.d.ts.map +1 -0
  219. package/dist/server.types-check.js +7 -0
  220. package/dist/server.types-check.js.map +1 -0
  221. package/package.json +45 -47
  222. package/dist/agent-client.d.ts +0 -5
  223. package/dist/agent-client.d.ts.map +0 -1
  224. package/dist/agent-client.js +0 -3
  225. package/dist/agent-client.js.map +0 -1
  226. package/dist/auth.d.ts +0 -37
  227. package/dist/auth.d.ts.map +0 -1
  228. package/dist/auth.js +0 -79
  229. package/dist/auth.js.map +0 -1
  230. package/dist/bounded-map.d.ts +0 -32
  231. package/dist/bounded-map.d.ts.map +0 -1
  232. package/dist/bounded-map.js +0 -79
  233. package/dist/bounded-map.js.map +0 -1
  234. package/dist/channel-base/format-cross-conv.d.ts +0 -43
  235. package/dist/channel-base/format-cross-conv.d.ts.map +0 -1
  236. package/dist/channel-base/format-cross-conv.js +0 -65
  237. package/dist/channel-base/format-cross-conv.js.map +0 -1
  238. package/dist/channel-base/format-group-block.d.ts +0 -48
  239. package/dist/channel-base/format-group-block.d.ts.map +0 -1
  240. package/dist/channel-base/format-group-block.js +0 -62
  241. package/dist/channel-base/format-group-block.js.map +0 -1
  242. package/dist/channel-base/index.d.ts +0 -12
  243. package/dist/channel-base/index.d.ts.map +0 -1
  244. package/dist/channel-base/index.js +0 -13
  245. package/dist/channel-base/index.js.map +0 -1
  246. package/dist/channel-core-enrichment.d.ts +0 -14
  247. package/dist/channel-core-enrichment.d.ts.map +0 -1
  248. package/dist/channel-core-enrichment.js +0 -143
  249. package/dist/channel-core-enrichment.js.map +0 -1
  250. package/dist/channel-core-test-support.d.ts +0 -75
  251. package/dist/channel-core-test-support.d.ts.map +0 -1
  252. package/dist/channel-core-test-support.js +0 -74
  253. package/dist/channel-core-test-support.js.map +0 -1
  254. package/dist/channel-core.d.ts +0 -304
  255. package/dist/channel-core.d.ts.map +0 -1
  256. package/dist/channel-core.js +0 -363
  257. package/dist/channel-core.js.map +0 -1
  258. package/dist/cli/adapters.d.ts +0 -21
  259. package/dist/cli/adapters.d.ts.map +0 -1
  260. package/dist/cli/adapters.js +0 -111
  261. package/dist/cli/adapters.js.map +0 -1
  262. package/dist/cli/commands/agents.d.ts +0 -11
  263. package/dist/cli/commands/agents.d.ts.map +0 -1
  264. package/dist/cli/commands/agents.js +0 -27
  265. package/dist/cli/commands/agents.js.map +0 -1
  266. package/dist/cli/commands/conversations.d.ts +0 -18
  267. package/dist/cli/commands/conversations.d.ts.map +0 -1
  268. package/dist/cli/commands/conversations.js +0 -33
  269. package/dist/cli/commands/conversations.js.map +0 -1
  270. package/dist/cli/commands/messages.d.ts +0 -41
  271. package/dist/cli/commands/messages.d.ts.map +0 -1
  272. package/dist/cli/commands/messages.js +0 -39
  273. package/dist/cli/commands/messages.js.map +0 -1
  274. package/dist/cli/commands/register.d.ts +0 -46
  275. package/dist/cli/commands/register.d.ts.map +0 -1
  276. package/dist/cli/commands/register.js +0 -103
  277. package/dist/cli/commands/register.js.map +0 -1
  278. package/dist/cli/commands/send.d.ts +0 -53
  279. package/dist/cli/commands/send.d.ts.map +0 -1
  280. package/dist/cli/commands/send.js +0 -57
  281. package/dist/cli/commands/send.js.map +0 -1
  282. package/dist/cli/commands/start.d.ts +0 -34
  283. package/dist/cli/commands/start.d.ts.map +0 -1
  284. package/dist/cli/commands/start.js +0 -59
  285. package/dist/cli/commands/start.js.map +0 -1
  286. package/dist/cli/commands/status.d.ts +0 -7
  287. package/dist/cli/commands/status.d.ts.map +0 -1
  288. package/dist/cli/commands/status.js +0 -16
  289. package/dist/cli/commands/status.js.map +0 -1
  290. package/dist/cli/commands/test-transport.d.ts +0 -28
  291. package/dist/cli/commands/test-transport.d.ts.map +0 -1
  292. package/dist/cli/commands/test-transport.js +0 -40
  293. package/dist/cli/commands/test-transport.js.map +0 -1
  294. package/dist/cli/index.d.ts +0 -3
  295. package/dist/cli/index.d.ts.map +0 -1
  296. package/dist/cli/index.js +0 -105
  297. package/dist/cli/index.js.map +0 -1
  298. package/dist/cli/output.d.ts +0 -14
  299. package/dist/cli/output.d.ts.map +0 -1
  300. package/dist/cli/output.js +0 -19
  301. package/dist/cli/output.js.map +0 -1
  302. package/dist/cli/socket-client.d.ts +0 -28
  303. package/dist/cli/socket-client.d.ts.map +0 -1
  304. package/dist/cli/socket-client.js +0 -63
  305. package/dist/cli/socket-client.js.map +0 -1
  306. package/dist/cli/transport.d.ts +0 -132
  307. package/dist/cli/transport.d.ts.map +0 -1
  308. package/dist/cli/transport.js +0 -127
  309. package/dist/cli/transport.js.map +0 -1
  310. package/dist/config.d.ts +0 -33
  311. package/dist/config.d.ts.map +0 -1
  312. package/dist/config.js +0 -45
  313. package/dist/config.js.map +0 -1
  314. package/dist/config.test-utils.d.ts +0 -18
  315. package/dist/config.test-utils.d.ts.map +0 -1
  316. package/dist/config.test-utils.js +0 -53
  317. package/dist/config.test-utils.js.map +0 -1
  318. package/dist/harness/client-runtime.d.ts +0 -24
  319. package/dist/harness/client-runtime.d.ts.map +0 -1
  320. package/dist/harness/client-runtime.js +0 -107
  321. package/dist/harness/client-runtime.js.map +0 -1
  322. package/dist/harness/index.d.ts +0 -5
  323. package/dist/harness/index.d.ts.map +0 -1
  324. package/dist/harness/index.js +0 -5
  325. package/dist/harness/index.js.map +0 -1
  326. package/dist/harness/runtime.d.ts +0 -149
  327. package/dist/harness/runtime.d.ts.map +0 -1
  328. package/dist/harness/runtime.js +0 -68
  329. package/dist/harness/runtime.js.map +0 -1
  330. package/dist/harness-client.d.ts +0 -43
  331. package/dist/harness-client.d.ts.map +0 -1
  332. package/dist/harness-client.js +0 -21
  333. package/dist/harness-client.js.map +0 -1
  334. package/dist/harness-mcp-server.d.ts +0 -19
  335. package/dist/harness-mcp-server.d.ts.map +0 -1
  336. package/dist/harness-mcp-server.js.map +0 -1
  337. package/dist/local-daemon-rpc.d.ts +0 -1170
  338. package/dist/local-daemon-rpc.d.ts.map +0 -1
  339. package/dist/local-daemon-rpc.js +0 -178
  340. package/dist/local-daemon-rpc.js.map +0 -1
  341. package/dist/local-history.d.ts +0 -75
  342. package/dist/local-history.d.ts.map +0 -1
  343. package/dist/local-history.js +0 -82
  344. package/dist/local-history.js.map +0 -1
  345. package/dist/local-paths.d.ts +0 -22
  346. package/dist/local-paths.d.ts.map +0 -1
  347. package/dist/local-paths.js +0 -33
  348. package/dist/local-paths.js.map +0 -1
  349. package/dist/local-socket-server.d.ts +0 -33
  350. package/dist/local-socket-server.d.ts.map +0 -1
  351. package/dist/local-socket-server.js +0 -100
  352. package/dist/local-socket-server.js.map +0 -1
  353. package/dist/message-rendering.d.ts +0 -4
  354. package/dist/message-rendering.d.ts.map +0 -1
  355. package/dist/message-rendering.js +0 -8
  356. package/dist/message-rendering.js.map +0 -1
  357. package/dist/moltzapd.d.ts +0 -38
  358. package/dist/moltzapd.d.ts.map +0 -1
  359. package/dist/moltzapd.js +0 -78
  360. package/dist/moltzapd.js.map +0 -1
  361. package/dist/notification/__tests__/subscribe-signatures.types-check.d.ts +0 -53
  362. package/dist/notification/__tests__/subscribe-signatures.types-check.d.ts.map +0 -1
  363. package/dist/notification/__tests__/subscribe-signatures.types-check.js +0 -29
  364. package/dist/notification/__tests__/subscribe-signatures.types-check.js.map +0 -1
  365. package/dist/notification/errors.d.ts +0 -41
  366. package/dist/notification/errors.d.ts.map +0 -1
  367. package/dist/notification/errors.js +0 -24
  368. package/dist/notification/errors.js.map +0 -1
  369. package/dist/notification/index.d.ts +0 -6
  370. package/dist/notification/index.d.ts.map +0 -1
  371. package/dist/notification/index.js +0 -6
  372. package/dist/notification/index.js.map +0 -1
  373. package/dist/notification/stream.d.ts +0 -75
  374. package/dist/notification/stream.d.ts.map +0 -1
  375. package/dist/notification/stream.js +0 -30
  376. package/dist/notification/stream.js.map +0 -1
  377. package/dist/pagination.d.ts +0 -52
  378. package/dist/pagination.d.ts.map +0 -1
  379. package/dist/pagination.js +0 -51
  380. package/dist/pagination.js.map +0 -1
  381. package/dist/profile.d.ts +0 -104
  382. package/dist/profile.d.ts.map +0 -1
  383. package/dist/profile.js +0 -163
  384. package/dist/profile.js.map +0 -1
  385. package/dist/refs.d.ts +0 -18
  386. package/dist/refs.d.ts.map +0 -1
  387. package/dist/refs.js +0 -18
  388. package/dist/refs.js.map +0 -1
  389. package/dist/service-event-trace.d.ts +0 -15
  390. package/dist/service-event-trace.d.ts.map +0 -1
  391. package/dist/service-event-trace.js +0 -35
  392. package/dist/service-event-trace.js.map +0 -1
  393. package/dist/service-helpers.d.ts +0 -55
  394. package/dist/service-helpers.d.ts.map +0 -1
  395. package/dist/service-helpers.js +0 -108
  396. package/dist/service-helpers.js.map +0 -1
  397. package/dist/service-local-daemon.d.ts +0 -32
  398. package/dist/service-local-daemon.d.ts.map +0 -1
  399. package/dist/service-local-daemon.js +0 -153
  400. package/dist/service-local-daemon.js.map +0 -1
  401. package/dist/service.d.ts +0 -299
  402. package/dist/service.d.ts.map +0 -1
  403. package/dist/service.js +0 -789
  404. package/dist/service.js.map +0 -1
  405. package/dist/test-utils/channel-service-fixture.d.ts +0 -53
  406. package/dist/test-utils/channel-service-fixture.d.ts.map +0 -1
  407. package/dist/test-utils/channel-service-fixture.js +0 -178
  408. package/dist/test-utils/channel-service-fixture.js.map +0 -1
  409. package/dist/test-utils/fake-service.d.ts +0 -84
  410. package/dist/test-utils/fake-service.d.ts.map +0 -1
  411. package/dist/test-utils/fake-service.js +0 -108
  412. package/dist/test-utils/fake-service.js.map +0 -1
  413. package/dist/test-utils/harness.d.ts +0 -27
  414. package/dist/test-utils/harness.d.ts.map +0 -1
  415. package/dist/test-utils/harness.js +0 -33
  416. package/dist/test-utils/harness.js.map +0 -1
  417. package/dist/test-utils/ids.d.ts +0 -21
  418. package/dist/test-utils/ids.d.ts.map +0 -1
  419. package/dist/test-utils/ids.js +0 -68
  420. package/dist/test-utils/ids.js.map +0 -1
  421. package/dist/test-utils/index.d.ts +0 -54
  422. package/dist/test-utils/index.d.ts.map +0 -1
  423. package/dist/test-utils/index.js +0 -65
  424. package/dist/test-utils/index.js.map +0 -1
  425. package/dist/test-utils/standalone-provisioning.d.ts +0 -22
  426. package/dist/test-utils/standalone-provisioning.d.ts.map +0 -1
  427. package/dist/test-utils/standalone-provisioning.js +0 -17
  428. package/dist/test-utils/standalone-provisioning.js.map +0 -1
  429. package/dist/tsconfig.tsbuildinfo +0 -1
package/dist/service.js DELETED
@@ -1,789 +0,0 @@
1
- import { agentId as AgentIdSchema, AgentNotFoundError, agentsList, } from "@moltzap/protocol/identity";
2
- import { agentConversationCreate, conversationCreatedNotificationDefinition, conversationList, } from "@moltzap/protocol/conversation";
3
- import { messageReceivedNotificationDefinition, messagesList, messagesSend, } from "@moltzap/protocol/message";
4
- import { NotConnectedError, isNotificationDeliveryFor, } from "@moltzap/protocol/rpc";
5
- import { BoundedMap } from "./bounded-map.js";
6
- import { Deferred, Effect, Exit, HashMap, Option, Ref, Schema, Scope, Stream, } from "effect";
7
- import { MoltZapAgentClient } from "./agent-client.js";
8
- import { loadServiceConfig, } from "./config.js";
9
- import { getOr, snapshot } from "./refs.js";
10
- import { getMoltZapAgentServiceSocketPath, getMoltZapServiceSocketPath, } from "./local-paths.js";
11
- import { makeLocalDaemonHandlers } from "./service-local-daemon.js";
12
- import { startLocalSocketServer, stopLocalSocketServer, } from "./local-socket-server.js";
13
- import { buildContextEntries, makeContextCandidate, newMessagesForConversation, notificationTraceRecord, } from "./service-helpers.js";
14
- import { renderPart } from "./message-rendering.js";
15
- import { formatHistoryMessage, lastReadIdsForSession, } from "./local-history.js";
16
- import { appendClientEventTrace } from "./service-event-trace.js";
17
- const CROSS_CONTEXT_TEXT_LIMIT = 120;
18
- const DEFAULT_MAX_CONTEXT_CONVERSATIONS = 5;
19
- const DEFAULT_MAX_MESSAGES_PER_CONVERSATION = 3;
20
- const HISTORY_LOOKUP_CONCURRENCY = 2;
21
- const AGENT_LOOKUP_PAGE_SIZE = 100;
22
- const AGENT_LOOKUP_MAX_PAGES = 20;
23
- const decodeAgentId = Schema.decodeUnknownOption(AgentIdSchema);
24
- const agentNotFound = (agentName) => new AgentNotFoundError({
25
- message: `Agent not found: ${agentName}`,
26
- data: { agentName },
27
- });
28
- /**
29
- * Escape `<`, `>`, `&` so sender content can't escape a `<system-reminder>` block.
30
- * @param s Value supplied to the operation.
31
- * @returns The sanitize for system reminder result.
32
- */
33
- export function sanitizeForSystemReminder(s) {
34
- return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
35
- }
36
- /**
37
- * Format CrossConversationEntry[] as a `&lt;system-reminder>` block. Adapters
38
- * that inline context into prompt text (nanoclaw) and `MoltZapService.getContext`
39
- * share this formatter so sanitization and line shape stay in one place.
40
- * @param entries Value supplied to the operation.
41
- * @param opts Value supplied to the operation.
42
- * @param opts.header Value supplied to the operation.
43
- * @returns The format cross conversation block result.
44
- */
45
- function formatCrossConversationBlock(entries, opts) {
46
- if (entries.length === 0) {
47
- return null;
48
- }
49
- const lines = entries.map((e) => {
50
- const safeSender = sanitizeForSystemReminder(e.senderName);
51
- const safeText = sanitizeForSystemReminder(e.text.slice(0, CROSS_CONTEXT_TEXT_LIMIT));
52
- return `@${safeSender} (${e.minutesAgo}m ago): (${e.count} new) "${safeText}"`;
53
- });
54
- return [
55
- "<system-reminder>",
56
- opts.header,
57
- ...lines,
58
- "</system-reminder>",
59
- ].join("\n");
60
- }
61
- /**
62
- * Per-conversation message cap. Older messages are evicted FIFO; the
63
- * on-disk history remains the source of truth. Sized for typical CLI
64
- * display windows — `conversations get` shows at most a few hundred.
65
- */
66
- const MAX_MESSAGES_PER_CONV = 1000;
67
- /**
68
- * Per-conversation dedup window. `BoundedMap` evicts the oldest message id
69
- * when a new id arrives at capacity. 1000 × 36 bytes per UUID ≈ 36 KB per
70
- * conversation, which keeps replay protection negligible at the expected
71
- * conversation count.
72
- */
73
- const DEDUP_WINDOW_PER_CONV = 1000;
74
- /**
75
- * Invoke every handler with `arg`, isolating throws so one bad handler
76
- * doesn't abort the remaining fanout.
77
- * @param handlers Value supplied to the operation.
78
- * @param arg Value supplied to the operation.
79
- */
80
- function fanout(handlers, arg) {
81
- for (const h of handlers) {
82
- try {
83
- h(arg);
84
- }
85
- catch (err) {
86
- Effect.runFork(Effect.logError("notification handler threw", err));
87
- }
88
- }
89
- }
90
- /**
91
- * Stateful MoltZap client that manages connection, conversation tracking,
92
- * agent name resolution, and cross-conversation context generation.
93
- *
94
- * API contract: **every fallible method returns `Effect`.** No `*Async`
95
- * Promise siblings — async/await consumers run the Effect at the edge
96
- * with `Effect.runPromise`. Keep this class Effect-only so downstream
97
- * callers compose failures and cancellation explicitly.
98
- */
99
- export class MoltZapService {
100
- client = null;
101
- connectedValue = false;
102
- shutdownCompletion = null;
103
- /**
104
- * Service-owned scope. Opened in `connect()`, owns the
105
- * `subscribeAll → Stream.runForEach` fan-out fiber. Closed in `close()` so
106
- * the fiber terminates with the service.
107
- *
108
- * Held off the public `connect()` signature so callers do not need to
109
- * thread a `Scope` requirement.
110
- */
111
- serviceScope = null;
112
- conversationsRef = Effect.runSync(Ref.make(HashMap.empty()));
113
- messagesRef = Effect.runSync(Ref.make(HashMap.empty()));
114
- agentNamesRef = Effect.runSync(Ref.make(HashMap.empty()));
115
- agentConversationCacheRef = Effect.runSync(Ref.make(HashMap.empty()));
116
- lastNotifiedRef = Effect.runSync(Ref.make(HashMap.empty()));
117
- lastReadRef = Effect.runSync(Ref.make(HashMap.empty()));
118
- /**
119
- * The branded outer and inner keys keep conversation and message ids from
120
- * crossing accidentally while each conversation owns its eviction window.
121
- */
122
- seenMessageIds = new Map();
123
- handlers = {
124
- message: [],
125
- rawNotification: [],
126
- disconnect: [],
127
- };
128
- ownAgentIdValue;
129
- opts;
130
- constructor(opts) {
131
- this.opts = opts;
132
- // The empty HelloOk carries no identity; `ownAgentId` is the client's
133
- // registered/stored id, available before the handshake.
134
- this.ownAgentIdValue = opts.agentId;
135
- }
136
- static fromConfig(config) {
137
- return new MoltZapService(config);
138
- }
139
- static make(profileName) {
140
- return loadServiceConfig(profileName).pipe(Effect.map((config) => MoltZapService.fromConfig(config)));
141
- }
142
- static startDaemon(profileName) {
143
- return Effect.gen(function* () {
144
- const service = yield* MoltZapService.make(profileName);
145
- yield* service.connect();
146
- yield* service.startSocketServer();
147
- return service;
148
- }).pipe(Effect.withSpan("MoltZapService.startDaemon"));
149
- }
150
- get connected() {
151
- return this.connectedValue;
152
- }
153
- get ownAgentId() {
154
- return this.ownAgentIdValue;
155
- }
156
- /**
157
- * Effect-native: compose via `yield*` or bridge at the edge via `Effect.runPromise`.
158
- * @returns The client result.
159
- */
160
- connect() {
161
- return Effect.gen(function* () {
162
- // A new connection never takes ownership while resources from the
163
- // preceding lifecycle are still closing.
164
- while (this.shutdownCompletion !== null) {
165
- const priorShutdown = this.shutdownCompletion;
166
- yield* Deferred.await(priorShutdown);
167
- if (this.shutdownCompletion === priorShutdown) {
168
- this.shutdownCompletion = null;
169
- }
170
- }
171
- const client = new MoltZapAgentClient({
172
- serverUrl: this.opts.serverUrl,
173
- agentKey: this.opts.agentKey,
174
- // The body doesn't branch on close metadata today; the signature is
175
- // kept explicit so a future disconnect-handler chain can plumb
176
- // code/reason through.
177
- onDisconnect: () => {
178
- this.connectedValue = false;
179
- fanout(this.handlers.disconnect, undefined);
180
- },
181
- });
182
- this.client = client;
183
- // `subscribeAll().pipe(Stream.runForEach, …)` is forked into a
184
- // service-owned scope. The Stream is materialized BEFORE `connect()` so
185
- // subscriptions are registered with the registry pre-handshake (a
186
- // pre-connect-legal operation).
187
- //
188
- // Stream errors of type `NotConnectedError` are surfaced on the
189
- // fiber's failure channel only when the client transitions to
190
- // terminal closed state (close() path); `Effect.catchAll` here
191
- // would swallow them silently, so we route through `Effect.logError`
192
- // before the fiber exits.
193
- const serviceScope = yield* Scope.make();
194
- this.serviceScope = serviceScope;
195
- const fanoutEffect = client.subscribeAll().pipe(Stream.runForEach((notification) => Effect.sync(() => {
196
- this.handleNotification(notification);
197
- })), Effect.catchAll((cause) => Effect.logWarning("MoltZapService notification fan-out terminated", cause)), Effect.asVoid);
198
- yield* Effect.forkIn(fanoutEffect, serviceScope);
199
- const helloOk = yield* client.connect();
200
- this.connectedValue = true;
201
- return helloOk;
202
- }.bind(this));
203
- }
204
- /**
205
- * Returns a lazy teardown effect that resolves after the service's owned
206
- * transports and notification scope close.
207
- *
208
- * @returns Completion of the service-owned cleanup.
209
- * @internal
210
- */
211
- shutdown() {
212
- return Effect.suspend(() => this.beginShutdown());
213
- }
214
- beginShutdown() {
215
- if (this.shutdownCompletion !== null) {
216
- return Deferred.await(this.shutdownCompletion);
217
- }
218
- const shutdownCompletion = Effect.runSync(Deferred.make());
219
- this.shutdownCompletion = shutdownCompletion;
220
- this.connectedValue = false;
221
- const stopSocketServer = this.stopSocketServer();
222
- const scopeToClose = this.serviceScope;
223
- const clientToClose = this.client;
224
- this.serviceScope = null;
225
- this.client = null;
226
- const closeScope = scopeToClose === null
227
- ? Effect.void
228
- : Scope.close(scopeToClose, Exit.void);
229
- const closeClient = clientToClose === null ? Effect.void : clientToClose.close();
230
- Effect.runSync(Effect.all([
231
- Ref.set(this.conversationsRef, HashMap.empty()),
232
- Ref.set(this.messagesRef, HashMap.empty()),
233
- Ref.set(this.agentNamesRef, HashMap.empty()),
234
- Ref.set(this.agentConversationCacheRef, HashMap.empty()),
235
- Ref.set(this.lastNotifiedRef, HashMap.empty()),
236
- Ref.set(this.lastReadRef, HashMap.empty()),
237
- ]));
238
- this.seenMessageIds.clear();
239
- // Handlers are preserved across explicit close()/connect() cycles.
240
- // MoltZapChannelCore subscribes once in its constructor; clearing handlers
241
- // here would silently drop inbound dispatch after the next connect.
242
- return Effect.uninterruptible(Effect.all([stopSocketServer, closeScope.pipe(Effect.zipRight(closeClient))], { concurrency: 2, discard: true }).pipe(Effect.ensuring(Deferred.succeed(shutdownCompletion, undefined).pipe(Effect.asVoid))));
243
- }
244
- /**
245
- * Starts service teardown for callers that use the legacy synchronous
246
- * lifecycle boundary.
247
- */
248
- close() {
249
- Effect.runFork(this.beginShutdown());
250
- }
251
- // --- Socket Server ---
252
- socketServerScope = null;
253
- activeSocketPath = null;
254
- /** Default socket path for CLI discovery. Per-instance path uses agentId. */
255
- static SOCKET_PATH = getMoltZapServiceSocketPath();
256
- /**
257
- * `agentId` is a server-assigned string. Treat it as untrusted: if a
258
- * compromised or malicious server returns an id containing `..` or a
259
- * path separator, a naive `path.join(... , agentId)` escapes `~/.moltzap`.
260
- * Reject anything that isn't a safe identifier.
261
- * @param id Value supplied to the operation.
262
- * @returns The id result.
263
- */
264
- static safeAgentIdSegment(id) {
265
- return /^[A-Za-z0-9_-]+$/.test(id) ? id : "default";
266
- }
267
- /**
268
- * Per-instance socket path based on connected agentId.
269
- * @returns The id result.
270
- */
271
- get socketPath() {
272
- const id = MoltZapService.safeAgentIdSegment(this.ownAgentId ?? "default");
273
- return getMoltZapAgentServiceSocketPath(id);
274
- }
275
- startSocketServer() {
276
- return Effect.gen(function* () {
277
- const previous = this.resetSocketServerState();
278
- yield* stopLocalSocketServer({
279
- socketScope: previous.socketScope,
280
- socketPath: previous.sockPath,
281
- defaultSocketPath: MoltZapService.SOCKET_PATH,
282
- });
283
- const running = yield* startLocalSocketServer({
284
- socketPath: this.socketPath,
285
- defaultSocketPath: MoltZapService.SOCKET_PATH,
286
- handlers: this.localDaemonHandlers(),
287
- });
288
- this.socketServerScope = running.socketScope;
289
- this.activeSocketPath = running.socketPath;
290
- }.bind(this)).pipe(Effect.withSpan("MoltZapService.startSocketServer"));
291
- }
292
- resetSocketServerState() {
293
- const socketScope = this.socketServerScope;
294
- this.socketServerScope = null;
295
- const sockPath = this.activeSocketPath ?? this.socketPath;
296
- this.activeSocketPath = null;
297
- return { socketScope, sockPath };
298
- }
299
- stopSocketServer() {
300
- const { socketScope, sockPath } = this.resetSocketServerState();
301
- return stopLocalSocketServer({
302
- socketScope,
303
- socketPath: sockPath,
304
- defaultSocketPath: MoltZapService.SOCKET_PATH,
305
- }).pipe(Effect.withSpan("MoltZapService.stopSocketServer"));
306
- }
307
- localDaemonHandlers() {
308
- return makeLocalDaemonHandlers({
309
- ownAgentId: this.ownAgentIdValue,
310
- // A live thunk, not a snapshot: the handler table outlives connection
311
- // cycles, and daemon/status must report the same liveness the MCP
312
- // status tool reads.
313
- connected: () => this.connectedValue,
314
- conversationCount: () => this.getConversations().length,
315
- call: this.call.bind(this),
316
- handleHistoryRequest: (request) => this.handleHistoryRequest(request),
317
- });
318
- }
319
- handleHistoryRequest(request) {
320
- return Effect.gen(function* () {
321
- const result = yield* this.call(messagesList.name, {
322
- conversationId: request.conversationId,
323
- limit: request.limit,
324
- });
325
- const convMeta = yield* this.loadHistorySupportData(request.conversationId, result.messages);
326
- const agentNames = yield* Ref.get(this.agentNamesRef);
327
- const lastReadMap = yield* Ref.get(this.lastReadRef);
328
- const lastReadIds = lastReadIdsForSession(lastReadMap, request);
329
- const messages = result.messages.map((message) => formatHistoryMessage(message, {
330
- agentNames,
331
- ownAgentId: this.ownAgentId,
332
- lastReadIds,
333
- hasSessionKey: request.sessionKey !== undefined,
334
- }));
335
- yield* this.advanceHistoryLastRead(request, result.messages);
336
- return {
337
- messages,
338
- conversationMeta: convMeta,
339
- newCount: messages.filter((message) => message.isNew).length,
340
- };
341
- }.bind(this));
342
- }
343
- loadHistorySupportData(convId, messages) {
344
- return Effect.gen(function* () {
345
- const [, convMeta] = yield* Effect.all([
346
- this.refreshHistoryAgentNames(messages),
347
- this.fetchHistoryConversationMeta(convId),
348
- ], {
349
- concurrency: HISTORY_LOOKUP_CONCURRENCY,
350
- });
351
- return convMeta;
352
- }.bind(this));
353
- }
354
- refreshHistoryAgentNames(messages) {
355
- return Effect.gen(function* () {
356
- const knownNames = yield* Ref.get(this.agentNamesRef);
357
- const unknownAgentIds = [
358
- ...new Set(messages.map((message) => message.senderId)),
359
- ].filter((id) => !HashMap.has(knownNames, id));
360
- if (unknownAgentIds.length === 0) {
361
- return;
362
- }
363
- yield* this.cacheVisibleAgentNamesForIds(new Set(unknownAgentIds)).pipe(Effect.asVoid, Effect.catchAll(() => Effect.void));
364
- }.bind(this));
365
- }
366
- fetchHistoryConversationMeta(convId) {
367
- // The client filters `ConversationList` output for the matching
368
- // conversation id (there is no per-conversation get RPC).
369
- return this.call(conversationList.name, {}).pipe(Effect.map((result) => {
370
- const hit = result.items.find((item) => item.conversation.id === convId);
371
- return hit?.conversation;
372
- }), Effect.orElseSucceed(() => undefined));
373
- }
374
- advanceHistoryLastRead(request, messages) {
375
- if (request.sessionKey === undefined || messages.length === 0) {
376
- return Effect.void;
377
- }
378
- const { conversationId, sessionKey } = request;
379
- return Ref.update(this.lastReadRef, (outer) => {
380
- const perSession = getOr(outer, sessionKey, () => HashMap.empty());
381
- const existing = getOr(perSession, conversationId, () =>
382
- /* Safe because the surrounding invariant establishes this asserted shape. */ new Set());
383
- if (messages.every((message) => existing.has(message.id))) {
384
- return outer;
385
- }
386
- const nextSet = new Set(existing);
387
- for (const message of messages) {
388
- nextSet.add(message.id);
389
- }
390
- return HashMap.set(outer, sessionKey, HashMap.set(perSession, conversationId, nextSet));
391
- });
392
- }
393
- // --- Conversations ---
394
- getConversation(convId) {
395
- return Option.getOrUndefined(HashMap.get(snapshot(this.conversationsRef), convId));
396
- }
397
- getConversations() {
398
- return [...HashMap.values(snapshot(this.conversationsRef))];
399
- }
400
- // --- Messages ---
401
- getHistory(convId, limit) {
402
- const msgs = getOr(snapshot(this.messagesRef), convId, () => []);
403
- return limit ? msgs.slice(-limit) : [...msgs];
404
- }
405
- // --- Agent Names ---
406
- getAgentName(agentId) {
407
- return Option.getOrUndefined(HashMap.get(snapshot(this.agentNamesRef), agentId));
408
- }
409
- /**
410
- * Cache-first agent-name lookup. Never fails: falls back to `agentId`
411
- * when the RPC errors or the server has no record. The error path logs
412
- * so ops can see repeated lookup failures; the empty-response path is
413
- * silent (a cold agent is an expected transient state).
414
- * @param agentId Identifier of the agent targeted by the operation.
415
- * @returns The decoded d agent id.
416
- */
417
- resolveAgentName(agentId) {
418
- return Effect.gen(function* () {
419
- const decodedAgentId = Option.getOrUndefined(decodeAgentId(agentId));
420
- if (decodedAgentId === undefined) {
421
- return agentId;
422
- }
423
- const cached = Option.getOrUndefined(HashMap.get(snapshot(this.agentNamesRef), agentId));
424
- if (cached !== undefined) {
425
- return cached;
426
- }
427
- return yield* this.cacheVisibleAgentNamesForIds(new Set([decodedAgentId])).pipe(Effect.map(() => {
428
- const resolved = Option.getOrUndefined(HashMap.get(snapshot(this.agentNamesRef), agentId));
429
- return resolved ?? agentId;
430
- }), Effect.catchAll((err) => Effect.logWarning("agent/identity/agents/list failed; falling back to agentId").pipe(Effect.annotateLogs({ agentId, err: String(err) }), Effect.as(agentId))));
431
- }.bind(this));
432
- }
433
- // --- Messaging ---
434
- /**
435
- * Send a text message into a conversation.
436
- *
437
- * ```mermaid
438
- * sequenceDiagram
439
- * participant caller
440
- * participant svc as MoltZapService
441
- * participant ws as MoltZapAgentClient
442
- * participant server
443
- *
444
- * caller->>svc: send(convId, text, opts?)
445
- * svc->>ws: sendRpc(MessagesSend, params)
446
- * Note over ws: stateRef None → fail NotConnectedError; otherwise allocate request id, encode frame
447
- * ws->>server: {jsonrpc, method agent/message/send, id, params}
448
- * Note over ws: Deferred raced against 30s timeout
449
- * server-->>ws: {result, id} or {error, id}
450
- * Note over ws: reader fiber decodes, resolves the Deferred
451
- * ws-->>svc: result or RpcServerError or RpcTimeoutError
452
- * svc-->>caller: Effect.void
453
- * ```
454
- *
455
- * @param conversationId Value supplied to the operation.
456
- * @param text Text to process.
457
- * @returns The send result.
458
- */
459
- send(conversationId, text) {
460
- return Effect.asVoid(this.call(messagesSend.name, {
461
- conversationId,
462
- parts: [{ type: "text", text }],
463
- }));
464
- }
465
- /**
466
- * Send to a named agent, minting the DM conversation on first use and
467
- * reusing it afterwards. The per-name cache is what makes the DM stable:
468
- * `agent/conversation/create` mints a fresh conversation on every call.
469
- * @param agentName Name of the agent to reach.
470
- * @param text Text to process.
471
- * @returns The send result.
472
- */
473
- sendToAgent(agentName, text) {
474
- return Effect.gen(function* () {
475
- const cache = yield* Ref.get(this.agentConversationCacheRef);
476
- let conversationId = Option.getOrUndefined(HashMap.get(cache, agentName));
477
- if (conversationId === undefined) {
478
- const agent = yield* this.findVisibleAgentByName(agentName);
479
- if (!agent) {
480
- return yield* agentNotFound(agentName);
481
- }
482
- const created = yield* this.call(agentConversationCreate.name, {
483
- participants: [agent.id],
484
- });
485
- conversationId = created.conversation.id;
486
- const cached = conversationId;
487
- yield* Ref.update(this.agentConversationCacheRef, (m) => HashMap.set(m, agentName, cached));
488
- }
489
- yield* this.send(conversationId, text);
490
- }.bind(this));
491
- }
492
- cacheAgentNames(agents) {
493
- if (agents.length === 0) {
494
- return Effect.void;
495
- }
496
- return Ref.update(this.agentNamesRef, (names) => {
497
- let next = names;
498
- for (const agent of agents) {
499
- next = HashMap.set(next, agent.id, agent.name);
500
- }
501
- return next;
502
- });
503
- }
504
- agentListParams(cursor) {
505
- return cursor === undefined
506
- ? { limit: AGENT_LOOKUP_PAGE_SIZE }
507
- : { limit: AGENT_LOOKUP_PAGE_SIZE, cursor };
508
- }
509
- cacheVisibleAgentNamesForIds(agentIds) {
510
- return Effect.gen(function* () {
511
- const missing = new Set(agentIds);
512
- let cursor = undefined;
513
- for (let page = 0; page < AGENT_LOOKUP_MAX_PAGES; page++) {
514
- const params = this.agentListParams(cursor);
515
- const result = yield* this.call(agentsList.name, params);
516
- yield* this.cacheAgentNames(result.agents);
517
- for (const agent of result.agents) {
518
- missing.delete(agent.id);
519
- }
520
- if (missing.size === 0 || result.nextCursor === undefined) {
521
- return;
522
- }
523
- cursor = result.nextCursor;
524
- }
525
- }.bind(this));
526
- }
527
- findVisibleAgentByName(agentName) {
528
- return Effect.gen(function* () {
529
- let cursor = undefined;
530
- for (let page = 0; page < AGENT_LOOKUP_MAX_PAGES; page++) {
531
- const params = this.agentListParams(cursor);
532
- const result = yield* this.call(agentsList.name, params);
533
- yield* this.cacheAgentNames(result.agents);
534
- const hit = result.agents.find((agent) => agent.name === agentName);
535
- if (hit !== undefined || result.nextCursor === undefined) {
536
- return hit;
537
- }
538
- cursor = result.nextCursor;
539
- }
540
- return undefined;
541
- }.bind(this));
542
- }
543
- // --- Cross-Conversation Context ---
544
- /**
545
- * Generate a system reminder with updates from other conversations.
546
- * Each conversation has its own view of what's "new" — markers are tracked
547
- * per viewing conversation and advanced after notification.
548
- * @param currentConvId Value supplied to the operation.
549
- * @param opts Value supplied to the operation.
550
- * @returns The context options result.
551
- */
552
- getContext(currentConvId, opts) {
553
- const contextOptions = opts ?? {};
554
- const { entries, commit } = this.peekContextEntries(currentConvId, contextOptions);
555
- if (entries.length === 0) {
556
- return null;
557
- }
558
- commit();
559
- return formatCrossConversationBlock(entries, {
560
- header: `Recent updates (you are in conv:${currentConvId}):`,
561
- });
562
- }
563
- /**
564
- * Return recent activity in other conversations without advancing any state.
565
- * Call `commit()` on the result to mark the returned messages as seen so
566
- * subsequent peeks return only what's new. A caller that reads without
567
- * committing can re-peek idempotently.
568
- * @param currentConvId Value supplied to the operation.
569
- * @param opts Value supplied to the operation.
570
- * @param opts.maxConversations Value supplied to the operation.
571
- * @param opts.maxMessagesPerConv Value supplied to the operation.
572
- * @returns The max convs result.
573
- */
574
- peekContextEntries(currentConvId, opts) {
575
- const maxConvs = opts?.maxConversations ?? DEFAULT_MAX_CONTEXT_CONVERSATIONS;
576
- const maxMsgsPerConv = opts?.maxMessagesPerConv ?? DEFAULT_MAX_MESSAGES_PER_CONVERSATION;
577
- const state = this.readCrossConvState(currentConvId);
578
- const candidates = this.collectContextCandidates(state, currentConvId);
579
- const { entries, pendingAdvances } = buildContextEntries(candidates.slice(0, maxConvs), state, maxMsgsPerConv);
580
- return {
581
- entries,
582
- commit: () => {
583
- this.advanceLastNotified(currentConvId, pendingAdvances);
584
- },
585
- };
586
- }
587
- /**
588
- * Return all new messages from all other conversations as full transcripts,
589
- * sorted chronologically. Uses the same lastNotified markers as
590
- * peekContextEntries. Call commit() to advance markers.
591
- * @param currentConvId Value supplied to the operation.
592
- * @returns The all messages result.
593
- */
594
- peekFullMessages(currentConvId) {
595
- const { messagesMap, conversationsMap, agentNamesMap, viewMarkers } = this.readCrossConvState(currentConvId);
596
- const allMessages = [];
597
- const pendingAdvances = [];
598
- for (const [convId, newMsgs] of this.iterNewMessagesByConv(messagesMap, viewMarkers, currentConvId)) {
599
- const convName = Option.getOrUndefined(HashMap.get(conversationsMap, convId))?.name;
600
- for (const m of newMsgs) {
601
- allMessages.push({
602
- conversationId: convId,
603
- conversationName: convName,
604
- senderName: getOr(agentNamesMap, m.senderId, () => m.senderId),
605
- senderId: m.senderId,
606
- text: m.parts.map(renderPart).join(" "),
607
- timestamp: m.createdAt,
608
- });
609
- }
610
- pendingAdvances.push([
611
- convId,
612
- /* Safe because the surrounding invariant establishes this asserted shape. */ newMsgs[newMsgs.length - 1].id,
613
- ]);
614
- }
615
- allMessages.sort((a, b) => a.timestamp.localeCompare(b.timestamp));
616
- return {
617
- messages: allMessages,
618
- commit: () => {
619
- this.advanceLastNotified(currentConvId, pendingAdvances);
620
- },
621
- };
622
- }
623
- readCrossConvState(currentConvId) {
624
- const lastNotifiedMap = snapshot(this.lastNotifiedRef);
625
- return {
626
- messagesMap: snapshot(this.messagesRef),
627
- conversationsMap: snapshot(this.conversationsRef),
628
- agentNamesMap: snapshot(this.agentNamesRef),
629
- viewMarkers: getOr(lastNotifiedMap, currentConvId, () => HashMap.empty()),
630
- };
631
- }
632
- collectContextCandidates(state, currentConvId) {
633
- const candidates = [];
634
- for (const [convId, newMsgs] of this.iterNewMessagesByConv(state.messagesMap, state.viewMarkers, currentConvId)) {
635
- candidates.push(makeContextCandidate(convId, newMsgs));
636
- }
637
- candidates.sort((a, b) => b.lastTs - a.lastTs);
638
- return candidates;
639
- }
640
- *iterNewMessagesByConv(messagesMap, viewMarkers, currentConvId) {
641
- for (const [convId, msgs] of messagesMap) {
642
- const newMsgs = newMessagesForConversation(convId, msgs, viewMarkers, currentConvId);
643
- if (newMsgs.length > 0) {
644
- yield [convId, newMsgs];
645
- }
646
- }
647
- }
648
- advanceLastNotified(currentConvId, pendingAdvances) {
649
- if (pendingAdvances.length === 0) {
650
- return;
651
- }
652
- Effect.runSync(Ref.update(this.lastNotifiedRef, (outer) => {
653
- let markers = getOr(outer, currentConvId, () => HashMap.empty());
654
- for (const [convId, msgId] of pendingAdvances) {
655
- markers = HashMap.set(markers, convId, msgId);
656
- }
657
- return HashMap.set(outer, currentConvId, markers);
658
- }));
659
- }
660
- // --- Notifications ---
661
- on(notification, handler) {
662
- this.handlers[notification].push(handler);
663
- }
664
- // --- RPC passthrough ---
665
- /**
666
- * Outbound RPC, typed per method — delegates to the agent client's typed
667
- * `call`. `call("agent/identity/agents/list", payload)` recovers the result and that
668
- * method's tagged-error union; an app-only method does not typecheck.
669
- * @param tag Value supplied to the operation.
670
- * @param payload Value supplied to the operation.
671
- * @param opts Value supplied to the operation.
672
- * @returns The client result.
673
- */
674
- call(tag, payload, opts) {
675
- return Effect.suspend(() => {
676
- const client = this.client;
677
- if (!client) {
678
- return Effect.fail(new NotConnectedError({ message: "Not connected" }));
679
- }
680
- return client.call(tag, payload, opts);
681
- });
682
- }
683
- callDefinition(definition, payload, opts) {
684
- return Effect.suspend(() => {
685
- const client = this.client;
686
- if (!client) {
687
- return Effect.fail(new NotConnectedError({ message: "Not connected" }));
688
- }
689
- return client.callDefinition(definition, payload, opts);
690
- });
691
- }
692
- // --- Internals ---
693
- handleNotification(notification) {
694
- this.recordNotificationTrace(notification);
695
- fanout(this.handlers.rawNotification, notification);
696
- this.dispatchTypedNotification(notification);
697
- }
698
- recordNotificationTrace(notification) {
699
- Effect.runFork(appendClientEventTrace(notificationTraceRecord(notification, this.ownAgentIdValue)));
700
- }
701
- dispatchTypedNotification(notification) {
702
- if (this.dispatchMessageNotification(notification)) {
703
- return;
704
- }
705
- this.dispatchConversationNotification(notification);
706
- }
707
- dispatchMessageNotification(notification) {
708
- if (isNotificationDeliveryFor(notification, messageReceivedNotificationDefinition)) {
709
- this.handleMessageReceivedNotification(notification.params);
710
- return true;
711
- }
712
- return false;
713
- }
714
- dispatchConversationNotification(notification) {
715
- if (isNotificationDeliveryFor(notification, conversationCreatedNotificationDefinition)) {
716
- this.handleConversationCreatedNotification(notification.params);
717
- return true;
718
- }
719
- return false;
720
- }
721
- /**
722
- * Record `messageId` in the per-conversation dedup window. Returns
723
- * `true` when the id is new (caller proceeds), `false` when the id is
724
- * a duplicate within the window (caller drops). On a new id, evicts
725
- * the oldest entry if the window is full.
726
- *
727
- * Bound to the live `agent/message/received` notification path: a single
728
- * server-side broadcast that surfaces the same id twice (network
729
- * replay, dual subscription) is suppressed to one
730
- * `on("message", ...)` event. `agent/message/list` returns raw history
731
- * unfiltered; consumers that combine both feeds dedup themselves.
732
- * @param convId Value supplied to the operation.
733
- * @param msgId Value supplied to the operation.
734
- * @returns The dedup window result.
735
- */
736
- recordMessageIdIfNew(convId, msgId) {
737
- let dedupWindow = this.seenMessageIds.get(convId);
738
- if (dedupWindow === undefined) {
739
- dedupWindow = new BoundedMap(DEDUP_WINDOW_PER_CONV);
740
- this.seenMessageIds.set(convId, dedupWindow);
741
- }
742
- if (dedupWindow.has(msgId)) {
743
- // Replays retain their original FIFO age so repeated delivery cannot
744
- // keep an old id resident forever.
745
- return false;
746
- }
747
- dedupWindow.set(msgId, true);
748
- return true;
749
- }
750
- handleMessageReceivedNotification(notification) {
751
- const msg = notification.message;
752
- const convId = msg.conversationId;
753
- if (!this.recordMessageIdIfNew(convId, msg.id)) {
754
- return;
755
- }
756
- this.storeMessage(msg);
757
- // Name resolution is driven lazily by channel-core's serialized consumer
758
- // via resolveAgentName(), which populates agentNamesRef on first miss and
759
- // hits the cache on every subsequent message.
760
- if (msg.senderId !== this.ownAgentIdValue) {
761
- fanout(this.handlers.message, { message: msg });
762
- }
763
- }
764
- handleConversationCreatedNotification(notification) {
765
- const { conversationId, name, participants } = notification;
766
- Effect.runSync(Ref.update(this.conversationsRef, (m) => {
767
- // The notification carries the full membership, this agent included,
768
- // so anything past two members is a group.
769
- const inferredType = participants.length <= 2 ? "dm" : "group";
770
- return HashMap.set(m, conversationId, {
771
- id: conversationId,
772
- type: inferredType,
773
- participants: participants.map((p) => `agent:${p}`),
774
- ...(name !== undefined ? { name } : {}),
775
- });
776
- }));
777
- }
778
- storeMessage(msg) {
779
- Effect.runSync(Ref.update(this.messagesRef, (m) => {
780
- const existing = getOr(m, msg.conversationId, () => []);
781
- const appended = [...existing, msg];
782
- const capped = appended.length > MAX_MESSAGES_PER_CONV
783
- ? appended.slice(-MAX_MESSAGES_PER_CONV)
784
- : appended;
785
- return HashMap.set(m, msg.conversationId, capped);
786
- }));
787
- }
788
- }
789
- //# sourceMappingURL=service.js.map