@namzu/sdk 46.0.0 → 48.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (768) hide show
  1. package/CHANGELOG.md +351 -8
  2. package/README.md +7 -8
  3. package/dist/advisory/history.d.ts.map +1 -1
  4. package/dist/advisory/history.js +21 -1
  5. package/dist/advisory/history.js.map +1 -1
  6. package/dist/advisory/index.d.ts +1 -1
  7. package/dist/advisory/index.d.ts.map +1 -1
  8. package/dist/advisory/index.js +1 -1
  9. package/dist/advisory/index.js.map +1 -1
  10. package/dist/advisory/registry.d.ts +17 -0
  11. package/dist/advisory/registry.d.ts.map +1 -1
  12. package/dist/advisory/registry.js +26 -0
  13. package/dist/advisory/registry.js.map +1 -1
  14. package/dist/agents/PipelineAgent.d.ts +2 -46
  15. package/dist/agents/PipelineAgent.d.ts.map +1 -1
  16. package/dist/agents/PipelineAgent.js +2 -242
  17. package/dist/agents/PipelineAgent.js.map +1 -1
  18. package/dist/agents/QueryAgent.d.ts +21 -0
  19. package/dist/agents/QueryAgent.d.ts.map +1 -0
  20. package/dist/agents/QueryAgent.js +214 -0
  21. package/dist/agents/QueryAgent.js.map +1 -0
  22. package/dist/agents/ReactiveAgent.d.ts +4 -16
  23. package/dist/agents/ReactiveAgent.d.ts.map +1 -1
  24. package/dist/agents/ReactiveAgent.js +4 -183
  25. package/dist/agents/ReactiveAgent.js.map +1 -1
  26. package/dist/agents/RouterAgent.d.ts +2 -20
  27. package/dist/agents/RouterAgent.d.ts.map +1 -1
  28. package/dist/agents/RouterAgent.js +2 -266
  29. package/dist/agents/RouterAgent.js.map +1 -1
  30. package/dist/agents/SupervisorAgent.d.ts +3 -43
  31. package/dist/agents/SupervisorAgent.d.ts.map +1 -1
  32. package/dist/agents/SupervisorAgent.js +3 -418
  33. package/dist/agents/SupervisorAgent.js.map +1 -1
  34. package/dist/agents/defineAgent.d.ts +2 -1
  35. package/dist/agents/defineAgent.d.ts.map +1 -1
  36. package/dist/agents/defineAgent.js +6 -1
  37. package/dist/agents/defineAgent.js.map +1 -1
  38. package/dist/agents/examples/PipelineAgent.d.ts +46 -0
  39. package/dist/agents/examples/PipelineAgent.d.ts.map +1 -0
  40. package/dist/agents/examples/PipelineAgent.js +242 -0
  41. package/dist/agents/examples/PipelineAgent.js.map +1 -0
  42. package/dist/agents/examples/RouterAgent.d.ts +22 -0
  43. package/dist/agents/examples/RouterAgent.d.ts.map +1 -0
  44. package/dist/agents/examples/RouterAgent.js +268 -0
  45. package/dist/agents/examples/RouterAgent.js.map +1 -0
  46. package/dist/agents/examples/SupervisorAgent.d.ts +45 -0
  47. package/dist/agents/examples/SupervisorAgent.d.ts.map +1 -0
  48. package/dist/agents/examples/SupervisorAgent.js +406 -0
  49. package/dist/agents/examples/SupervisorAgent.js.map +1 -0
  50. package/dist/agents/explore.d.ts +6 -3
  51. package/dist/agents/explore.d.ts.map +1 -1
  52. package/dist/agents/explore.js +6 -3
  53. package/dist/agents/explore.js.map +1 -1
  54. package/dist/agents/forward-options.d.ts +11 -0
  55. package/dist/agents/forward-options.d.ts.map +1 -0
  56. package/dist/agents/forward-options.js +15 -0
  57. package/dist/agents/forward-options.js.map +1 -0
  58. package/dist/agents/index.d.ts +1 -0
  59. package/dist/agents/index.d.ts.map +1 -1
  60. package/dist/agents/index.js +2 -0
  61. package/dist/agents/index.js.map +1 -1
  62. package/dist/agents/runAgent.d.ts +19 -8
  63. package/dist/agents/runAgent.d.ts.map +1 -1
  64. package/dist/agents/runAgent.js +99 -29
  65. package/dist/agents/runAgent.js.map +1 -1
  66. package/dist/authorization/command-line.d.ts +2 -0
  67. package/dist/authorization/command-line.d.ts.map +1 -1
  68. package/dist/authorization/command-line.js +2 -2
  69. package/dist/authorization/command-line.js.map +1 -1
  70. package/dist/authorization/gate.d.ts +8 -0
  71. package/dist/authorization/gate.d.ts.map +1 -1
  72. package/dist/authorization/gate.js +12 -1
  73. package/dist/authorization/gate.js.map +1 -1
  74. package/dist/authorization/program.d.ts +151 -0
  75. package/dist/authorization/program.d.ts.map +1 -0
  76. package/dist/authorization/program.js +713 -0
  77. package/dist/authorization/program.js.map +1 -0
  78. package/dist/authorization/reexec-wrapper.d.ts +106 -0
  79. package/dist/authorization/reexec-wrapper.d.ts.map +1 -0
  80. package/dist/authorization/reexec-wrapper.js +532 -0
  81. package/dist/authorization/reexec-wrapper.js.map +1 -0
  82. package/dist/authorization/rules.d.ts +9 -0
  83. package/dist/authorization/rules.d.ts.map +1 -1
  84. package/dist/authorization/rules.js +8 -1
  85. package/dist/authorization/rules.js.map +1 -1
  86. package/dist/authorization/shell-lexer.d.ts +19 -4
  87. package/dist/authorization/shell-lexer.d.ts.map +1 -1
  88. package/dist/authorization/shell-lexer.js +91 -65
  89. package/dist/authorization/shell-lexer.js.map +1 -1
  90. package/dist/bridge/sse/mapper.d.ts.map +1 -1
  91. package/dist/bridge/sse/mapper.js +6 -0
  92. package/dist/bridge/sse/mapper.js.map +1 -1
  93. package/dist/capabilities/index.d.ts +54 -0
  94. package/dist/capabilities/index.d.ts.map +1 -0
  95. package/dist/capabilities/index.js +92 -0
  96. package/dist/capabilities/index.js.map +1 -0
  97. package/dist/config/registry.d.ts +2 -1
  98. package/dist/config/registry.d.ts.map +1 -1
  99. package/dist/config/registry.js +3 -2
  100. package/dist/config/registry.js.map +1 -1
  101. package/dist/connector/index.d.ts +4 -4
  102. package/dist/connector/index.d.ts.map +1 -1
  103. package/dist/connector/index.js +3 -3
  104. package/dist/connector/index.js.map +1 -1
  105. package/dist/connector/mcp/adapter.d.ts +16 -1
  106. package/dist/connector/mcp/adapter.d.ts.map +1 -1
  107. package/dist/connector/mcp/adapter.js +71 -4
  108. package/dist/connector/mcp/adapter.js.map +1 -1
  109. package/dist/connector/mcp/client.d.ts +32 -4
  110. package/dist/connector/mcp/client.d.ts.map +1 -1
  111. package/dist/connector/mcp/client.js +383 -5
  112. package/dist/connector/mcp/client.js.map +1 -1
  113. package/dist/connector/mcp/discovery.d.ts +24 -1
  114. package/dist/connector/mcp/discovery.d.ts.map +1 -1
  115. package/dist/connector/mcp/discovery.js +44 -0
  116. package/dist/connector/mcp/discovery.js.map +1 -1
  117. package/dist/connector/mcp/era.d.ts.map +1 -1
  118. package/dist/connector/mcp/era.js +7 -0
  119. package/dist/connector/mcp/era.js.map +1 -1
  120. package/dist/connector/mcp/index.d.ts +2 -0
  121. package/dist/connector/mcp/index.d.ts.map +1 -1
  122. package/dist/connector/mcp/index.js +11 -0
  123. package/dist/connector/mcp/index.js.map +1 -1
  124. package/dist/connector/mcp/mcp-toolset.d.ts +133 -0
  125. package/dist/connector/mcp/mcp-toolset.d.ts.map +1 -0
  126. package/dist/connector/mcp/mcp-toolset.js +399 -0
  127. package/dist/connector/mcp/mcp-toolset.js.map +1 -0
  128. package/dist/connector/mcp/streamable-http.d.ts +15 -0
  129. package/dist/connector/mcp/streamable-http.d.ts.map +1 -1
  130. package/dist/connector/mcp/streamable-http.js +281 -6
  131. package/dist/connector/mcp/streamable-http.js.map +1 -1
  132. package/dist/connector/tools/index.d.ts +2 -2
  133. package/dist/connector/tools/index.d.ts.map +1 -1
  134. package/dist/connector/tools/index.js +1 -1
  135. package/dist/connector/tools/index.js.map +1 -1
  136. package/dist/connector/tools/router.d.ts +15 -13
  137. package/dist/connector/tools/router.d.ts.map +1 -1
  138. package/dist/connector/tools/router.js +30 -51
  139. package/dist/connector/tools/router.js.map +1 -1
  140. package/dist/contracts/a2a.d.ts +2 -2
  141. package/dist/directory/derive-supervisor.d.ts +2 -2
  142. package/dist/directory/derive-supervisor.d.ts.map +1 -1
  143. package/dist/directory/derive-supervisor.js +6 -7
  144. package/dist/directory/derive-supervisor.js.map +1 -1
  145. package/dist/directory/derive.d.ts.map +1 -1
  146. package/dist/directory/derive.js +5 -5
  147. package/dist/directory/derive.js.map +1 -1
  148. package/dist/execution/code-runtime/types.d.ts +2 -2
  149. package/dist/execution/code-runtime/types.js +1 -1
  150. package/dist/invariants/index.d.ts +2 -1
  151. package/dist/invariants/index.d.ts.map +1 -1
  152. package/dist/invariants/index.js +3 -2
  153. package/dist/invariants/index.js.map +1 -1
  154. package/dist/manager/agent/lifecycle.d.ts +1 -0
  155. package/dist/manager/agent/lifecycle.d.ts.map +1 -1
  156. package/dist/manager/agent/lifecycle.js +146 -18
  157. package/dist/manager/agent/lifecycle.js.map +1 -1
  158. package/dist/manager/connector/environment.d.ts +6 -0
  159. package/dist/manager/connector/environment.d.ts.map +1 -1
  160. package/dist/manager/connector/environment.js +11 -4
  161. package/dist/manager/connector/environment.js.map +1 -1
  162. package/dist/manager/connector/index.d.ts +2 -2
  163. package/dist/manager/connector/index.d.ts.map +1 -1
  164. package/dist/manager/connector/index.js +2 -2
  165. package/dist/manager/connector/index.js.map +1 -1
  166. package/dist/manager/connector/tenant.d.ts +6 -0
  167. package/dist/manager/connector/tenant.d.ts.map +1 -1
  168. package/dist/manager/connector/tenant.js +11 -4
  169. package/dist/manager/connector/tenant.js.map +1 -1
  170. package/dist/manager/index.d.ts +2 -2
  171. package/dist/manager/index.d.ts.map +1 -1
  172. package/dist/manager/index.js +2 -2
  173. package/dist/manager/index.js.map +1 -1
  174. package/dist/manager/resident/initiative.d.ts +6 -6
  175. package/dist/manager/resident/learning-observation.d.ts +4 -4
  176. package/dist/manager/resident/learning.d.ts +36 -36
  177. package/dist/manager/resident/outbox.d.ts +4 -4
  178. package/dist/manager/session/attribution.d.ts +22 -0
  179. package/dist/manager/session/attribution.d.ts.map +1 -0
  180. package/dist/manager/session/attribution.js +64 -0
  181. package/dist/manager/session/attribution.js.map +1 -0
  182. package/dist/manager/session/turn-recorder.d.ts +14 -0
  183. package/dist/manager/session/turn-recorder.d.ts.map +1 -1
  184. package/dist/manager/session/turn-recorder.js +208 -55
  185. package/dist/manager/session/turn-recorder.js.map +1 -1
  186. package/dist/peers/address.d.ts +36 -0
  187. package/dist/peers/address.d.ts.map +1 -0
  188. package/dist/peers/address.js +52 -0
  189. package/dist/peers/address.js.map +1 -0
  190. package/dist/peers/client.d.ts +47 -0
  191. package/dist/peers/client.d.ts.map +1 -0
  192. package/dist/peers/client.js +132 -0
  193. package/dist/peers/client.js.map +1 -0
  194. package/dist/peers/dir.d.ts +88 -0
  195. package/dist/peers/dir.d.ts.map +1 -0
  196. package/dist/peers/dir.js +139 -0
  197. package/dist/peers/dir.js.map +1 -0
  198. package/dist/peers/endpoint.d.ts +144 -0
  199. package/dist/peers/endpoint.d.ts.map +1 -0
  200. package/dist/peers/endpoint.js +420 -0
  201. package/dist/peers/endpoint.js.map +1 -0
  202. package/dist/peers/envelope.d.ts +42 -0
  203. package/dist/peers/envelope.d.ts.map +1 -0
  204. package/dist/peers/envelope.js +110 -0
  205. package/dist/peers/envelope.js.map +1 -0
  206. package/dist/peers/index.d.ts +30 -0
  207. package/dist/peers/index.d.ts.map +1 -0
  208. package/dist/peers/index.js +22 -0
  209. package/dist/peers/index.js.map +1 -0
  210. package/dist/peers/protocol.d.ts +645 -0
  211. package/dist/peers/protocol.d.ts.map +1 -0
  212. package/dist/peers/protocol.js +151 -0
  213. package/dist/peers/protocol.js.map +1 -0
  214. package/dist/peers/record.d.ts +71 -0
  215. package/dist/peers/record.d.ts.map +1 -0
  216. package/dist/peers/record.js +45 -0
  217. package/dist/peers/record.js.map +1 -0
  218. package/dist/peers/registry.d.ts +54 -0
  219. package/dist/peers/registry.d.ts.map +1 -0
  220. package/dist/peers/registry.js +213 -0
  221. package/dist/peers/registry.js.map +1 -0
  222. package/dist/plugin/define.d.ts +24 -0
  223. package/dist/plugin/define.d.ts.map +1 -0
  224. package/dist/plugin/define.js +42 -0
  225. package/dist/plugin/define.js.map +1 -0
  226. package/dist/plugin/index.d.ts +2 -0
  227. package/dist/plugin/index.d.ts.map +1 -1
  228. package/dist/plugin/index.js +1 -0
  229. package/dist/plugin/index.js.map +1 -1
  230. package/dist/plugin/lifecycle.d.ts +27 -3
  231. package/dist/plugin/lifecycle.d.ts.map +1 -1
  232. package/dist/plugin/lifecycle.js +242 -92
  233. package/dist/plugin/lifecycle.js.map +1 -1
  234. package/dist/plugin/resolver.d.ts +2 -2
  235. package/dist/plugin/resolver.d.ts.map +1 -1
  236. package/dist/plugin/resolver.js.map +1 -1
  237. package/dist/plugin/shell-hook.d.ts.map +1 -1
  238. package/dist/plugin/shell-hook.js +17 -3
  239. package/dist/plugin/shell-hook.js.map +1 -1
  240. package/dist/probe/errors.d.ts +2 -1
  241. package/dist/probe/errors.d.ts.map +1 -1
  242. package/dist/probe/errors.js +3 -2
  243. package/dist/probe/errors.js.map +1 -1
  244. package/dist/prompt/coding-agent-doctrine.d.ts +18 -7
  245. package/dist/prompt/coding-agent-doctrine.d.ts.map +1 -1
  246. package/dist/prompt/coding-agent-doctrine.js +11 -6
  247. package/dist/prompt/coding-agent-doctrine.js.map +1 -1
  248. package/dist/prompt/contributions.d.ts +4 -1
  249. package/dist/prompt/contributions.d.ts.map +1 -1
  250. package/dist/prompt/contributions.js +7 -2
  251. package/dist/prompt/contributions.js.map +1 -1
  252. package/dist/prompt/index.d.ts +1 -1
  253. package/dist/prompt/index.d.ts.map +1 -1
  254. package/dist/prompt/index.js +1 -1
  255. package/dist/prompt/index.js.map +1 -1
  256. package/dist/provider/collect-chat-completion.d.ts +6 -1
  257. package/dist/provider/collect-chat-completion.d.ts.map +1 -1
  258. package/dist/provider/collect-chat-completion.js +88 -10
  259. package/dist/provider/collect-chat-completion.js.map +1 -1
  260. package/dist/provider/mock.d.ts.map +1 -1
  261. package/dist/provider/mock.js +23 -6
  262. package/dist/provider/mock.js.map +1 -1
  263. package/dist/provider/registry.d.ts +2 -1
  264. package/dist/provider/registry.d.ts.map +1 -1
  265. package/dist/provider/registry.js +3 -2
  266. package/dist/provider/registry.js.map +1 -1
  267. package/dist/provider/tool-call-framing.d.ts +164 -0
  268. package/dist/provider/tool-call-framing.d.ts.map +1 -0
  269. package/dist/provider/tool-call-framing.js +163 -0
  270. package/dist/provider/tool-call-framing.js.map +1 -0
  271. package/dist/public-runtime.d.ts +24 -11
  272. package/dist/public-runtime.d.ts.map +1 -1
  273. package/dist/public-runtime.js +45 -9
  274. package/dist/public-runtime.js.map +1 -1
  275. package/dist/public-tools.d.ts +6 -4
  276. package/dist/public-tools.d.ts.map +1 -1
  277. package/dist/public-tools.js +8 -3
  278. package/dist/public-tools.js.map +1 -1
  279. package/dist/public-types.d.ts +13 -2
  280. package/dist/public-types.d.ts.map +1 -1
  281. package/dist/read-model/registry.d.ts +2 -1
  282. package/dist/read-model/registry.d.ts.map +1 -1
  283. package/dist/read-model/registry.js +3 -2
  284. package/dist/read-model/registry.js.map +1 -1
  285. package/dist/registry/ManagedRegistry.d.ts +30 -0
  286. package/dist/registry/ManagedRegistry.d.ts.map +1 -1
  287. package/dist/registry/ManagedRegistry.js +45 -6
  288. package/dist/registry/ManagedRegistry.js.map +1 -1
  289. package/dist/registry/collision.d.ts +57 -0
  290. package/dist/registry/collision.d.ts.map +1 -0
  291. package/dist/registry/collision.js +41 -0
  292. package/dist/registry/collision.js.map +1 -0
  293. package/dist/registry/command/index.d.ts +5 -3
  294. package/dist/registry/command/index.d.ts.map +1 -1
  295. package/dist/registry/command/index.js +6 -4
  296. package/dist/registry/command/index.js.map +1 -1
  297. package/dist/registry/index.d.ts +3 -4
  298. package/dist/registry/index.d.ts.map +1 -1
  299. package/dist/registry/index.js +2 -2
  300. package/dist/registry/index.js.map +1 -1
  301. package/dist/registry/plugin/index.d.ts.map +1 -1
  302. package/dist/registry/plugin/index.js +14 -1
  303. package/dist/registry/plugin/index.js.map +1 -1
  304. package/dist/registry/tool/callable.d.ts +7 -7
  305. package/dist/registry/tool/callable.d.ts.map +1 -1
  306. package/dist/registry/tool/callable.js +6 -7
  307. package/dist/registry/tool/callable.js.map +1 -1
  308. package/dist/registry/tool/execute.d.ts +14 -77
  309. package/dist/registry/tool/execute.d.ts.map +1 -1
  310. package/dist/registry/tool/execute.js +15 -727
  311. package/dist/registry/tool/execute.js.map +1 -1
  312. package/dist/registry/tool/portable.d.ts +25 -0
  313. package/dist/registry/tool/portable.d.ts.map +1 -1
  314. package/dist/registry/tool/portable.js +50 -0
  315. package/dist/registry/tool/portable.js.map +1 -1
  316. package/dist/registry/tool/presentation.d.ts +6 -5
  317. package/dist/registry/tool/presentation.d.ts.map +1 -1
  318. package/dist/registry/tool/presentation.js +3 -3
  319. package/dist/registry/tool/presentation.js.map +1 -1
  320. package/dist/runtime/bidi/session.d.ts +5 -4
  321. package/dist/runtime/bidi/session.d.ts.map +1 -1
  322. package/dist/runtime/bidi/session.js +18 -1
  323. package/dist/runtime/bidi/session.js.map +1 -1
  324. package/dist/runtime/query/executor/tool-call-admission.d.ts +45 -2
  325. package/dist/runtime/query/executor/tool-call-admission.d.ts.map +1 -1
  326. package/dist/runtime/query/executor/tool-call-admission.js +189 -5
  327. package/dist/runtime/query/executor/tool-call-admission.js.map +1 -1
  328. package/dist/runtime/query/executor.d.ts +33 -3
  329. package/dist/runtime/query/executor.d.ts.map +1 -1
  330. package/dist/runtime/query/executor.js +86 -10
  331. package/dist/runtime/query/executor.js.map +1 -1
  332. package/dist/runtime/query/file-evidence-replay.d.ts +1 -1
  333. package/dist/runtime/query/file-evidence-replay.d.ts.map +1 -1
  334. package/dist/runtime/query/file-evidence-replay.js +8 -7
  335. package/dist/runtime/query/file-evidence-replay.js.map +1 -1
  336. package/dist/runtime/query/fork/prepare.d.ts +4 -1
  337. package/dist/runtime/query/fork/prepare.d.ts.map +1 -1
  338. package/dist/runtime/query/fork/prepare.js +4 -0
  339. package/dist/runtime/query/fork/prepare.js.map +1 -1
  340. package/dist/runtime/query/guardrail-presets.d.ts +4 -3
  341. package/dist/runtime/query/guardrail-presets.d.ts.map +1 -1
  342. package/dist/runtime/query/guardrail-presets.js +4 -3
  343. package/dist/runtime/query/guardrail-presets.js.map +1 -1
  344. package/dist/runtime/query/index.d.ts +23 -10
  345. package/dist/runtime/query/index.d.ts.map +1 -1
  346. package/dist/runtime/query/index.js +149 -70
  347. package/dist/runtime/query/index.js.map +1 -1
  348. package/dist/runtime/query/iteration/index.d.ts.map +1 -1
  349. package/dist/runtime/query/iteration/index.js +8 -1
  350. package/dist/runtime/query/iteration/index.js.map +1 -1
  351. package/dist/runtime/query/iteration/phases/compaction.js +1 -1
  352. package/dist/runtime/query/iteration/phases/compaction.js.map +1 -1
  353. package/dist/runtime/query/iteration/phases/context.d.ts +2 -2
  354. package/dist/runtime/query/iteration/phases/context.d.ts.map +1 -1
  355. package/dist/runtime/query/iteration/phases/tool-review.d.ts.map +1 -1
  356. package/dist/runtime/query/iteration/phases/tool-review.js +55 -2
  357. package/dist/runtime/query/iteration/phases/tool-review.js.map +1 -1
  358. package/dist/runtime/query/iteration/stream-turn.d.ts.map +1 -1
  359. package/dist/runtime/query/iteration/stream-turn.js +342 -116
  360. package/dist/runtime/query/iteration/stream-turn.js.map +1 -1
  361. package/dist/runtime/query/iteration/tool-input.d.ts +79 -0
  362. package/dist/runtime/query/iteration/tool-input.d.ts.map +1 -0
  363. package/dist/runtime/query/iteration/tool-input.js +291 -0
  364. package/dist/runtime/query/iteration/tool-input.js.map +1 -0
  365. package/dist/runtime/query/observation-context.d.ts +2 -2
  366. package/dist/runtime/query/observation-context.d.ts.map +1 -1
  367. package/dist/runtime/query/observation-context.js.map +1 -1
  368. package/dist/runtime/query/prelude-lease.d.ts +18 -0
  369. package/dist/runtime/query/prelude-lease.d.ts.map +1 -0
  370. package/dist/runtime/query/prelude-lease.js +121 -0
  371. package/dist/runtime/query/prelude-lease.js.map +1 -0
  372. package/dist/runtime/query/prepare-turn.d.ts.map +1 -1
  373. package/dist/runtime/query/prepare-turn.js +386 -187
  374. package/dist/runtime/query/prepare-turn.js.map +1 -1
  375. package/dist/runtime/query/prompt-cache.d.ts +2 -2
  376. package/dist/runtime/query/prompt-cache.d.ts.map +1 -1
  377. package/dist/runtime/query/prompt.d.ts +2 -2
  378. package/dist/runtime/query/prompt.d.ts.map +1 -1
  379. package/dist/runtime/query/prompt.js +1 -1
  380. package/dist/runtime/query/prompt.js.map +1 -1
  381. package/dist/runtime/query/resume-session.d.ts.map +1 -1
  382. package/dist/runtime/query/resume-session.js +37 -2
  383. package/dist/runtime/query/resume-session.js.map +1 -1
  384. package/dist/runtime/query/review-policy.d.ts +22 -3
  385. package/dist/runtime/query/review-policy.d.ts.map +1 -1
  386. package/dist/runtime/query/review-policy.js +84 -6
  387. package/dist/runtime/query/review-policy.js.map +1 -1
  388. package/dist/runtime/query/tooling.d.ts +3 -2
  389. package/dist/runtime/query/tooling.d.ts.map +1 -1
  390. package/dist/runtime/query/tooling.js.map +1 -1
  391. package/dist/runtime/query/turn-state.d.ts.map +1 -1
  392. package/dist/runtime/query/turn-state.js +5 -0
  393. package/dist/runtime/query/turn-state.js.map +1 -1
  394. package/dist/runtime/system-events.d.ts +112 -0
  395. package/dist/runtime/system-events.d.ts.map +1 -0
  396. package/dist/runtime/system-events.js +183 -0
  397. package/dist/runtime/system-events.js.map +1 -0
  398. package/dist/scheduler/delegating.d.ts +2 -1
  399. package/dist/scheduler/delegating.d.ts.map +1 -1
  400. package/dist/scheduler/delegating.js +3 -2
  401. package/dist/scheduler/delegating.js.map +1 -1
  402. package/dist/scheduler/local.d.ts.map +1 -1
  403. package/dist/scheduler/local.js +2 -0
  404. package/dist/scheduler/local.js.map +1 -1
  405. package/dist/session/retention/archive.js +1 -1
  406. package/dist/session/retention/archive.js.map +1 -1
  407. package/dist/skills/index.d.ts +1 -1
  408. package/dist/skills/index.d.ts.map +1 -1
  409. package/dist/skills/index.js +1 -1
  410. package/dist/skills/index.js.map +1 -1
  411. package/dist/skills/registry.d.ts +12 -0
  412. package/dist/skills/registry.d.ts.map +1 -1
  413. package/dist/skills/registry.js +19 -0
  414. package/dist/skills/registry.js.map +1 -1
  415. package/dist/store/evidence/index-page.d.ts +2 -2
  416. package/dist/store/session/disk.d.ts.map +1 -1
  417. package/dist/store/session/disk.js +2 -0
  418. package/dist/store/session/disk.js.map +1 -1
  419. package/dist/store/session-log/conformance.d.ts +1 -1
  420. package/dist/store/session-log/conformance.d.ts.map +1 -1
  421. package/dist/store/session-log/conformance.js +49 -8
  422. package/dist/store/session-log/conformance.js.map +1 -1
  423. package/dist/store/session-log/core.d.ts +8 -3
  424. package/dist/store/session-log/core.d.ts.map +1 -1
  425. package/dist/store/session-log/core.js +2 -1
  426. package/dist/store/session-log/core.js.map +1 -1
  427. package/dist/store/session-log/fold.d.ts +12 -0
  428. package/dist/store/session-log/fold.d.ts.map +1 -1
  429. package/dist/store/session-log/fold.js +57 -7
  430. package/dist/store/session-log/fold.js.map +1 -1
  431. package/dist/store/session-log/index.d.ts +2 -2
  432. package/dist/store/session-log/index.d.ts.map +1 -1
  433. package/dist/store/session-log/index.js +1 -1
  434. package/dist/store/session-log/index.js.map +1 -1
  435. package/dist/test-support/toolset.d.ts +19 -0
  436. package/dist/test-support/toolset.d.ts.map +1 -0
  437. package/dist/test-support/toolset.js +20 -0
  438. package/dist/test-support/toolset.js.map +1 -0
  439. package/dist/tools/builtins/bash.d.ts +29 -0
  440. package/dist/tools/builtins/bash.d.ts.map +1 -1
  441. package/dist/tools/builtins/bash.js +19 -9
  442. package/dist/tools/builtins/bash.js.map +1 -1
  443. package/dist/tools/builtins/browser-url.d.ts +1 -1
  444. package/dist/tools/builtins/browser-url.js +1 -1
  445. package/dist/tools/builtins/browser.d.ts +6 -6
  446. package/dist/tools/builtins/browser.js +2 -2
  447. package/dist/tools/builtins/browser.js.map +1 -1
  448. package/dist/tools/builtins/computer-use.d.ts.map +1 -1
  449. package/dist/tools/builtins/computer-use.js +19 -11
  450. package/dist/tools/builtins/computer-use.js.map +1 -1
  451. package/dist/tools/builtins/edit.d.ts.map +1 -1
  452. package/dist/tools/builtins/edit.js +9 -1
  453. package/dist/tools/builtins/edit.js.map +1 -1
  454. package/dist/tools/builtins/json-string-hint.d.ts +15 -0
  455. package/dist/tools/builtins/json-string-hint.d.ts.map +1 -0
  456. package/dist/tools/builtins/json-string-hint.js +17 -0
  457. package/dist/tools/builtins/json-string-hint.js.map +1 -0
  458. package/dist/tools/builtins/search-tools.d.ts.map +1 -1
  459. package/dist/tools/builtins/search-tools.js +7 -15
  460. package/dist/tools/builtins/search-tools.js.map +1 -1
  461. package/dist/tools/builtins/write-file.d.ts.map +1 -1
  462. package/dist/tools/builtins/write-file.js +11 -0
  463. package/dist/tools/builtins/write-file.js.map +1 -1
  464. package/dist/tools/command-shell.d.ts +10 -0
  465. package/dist/tools/command-shell.d.ts.map +1 -1
  466. package/dist/tools/command-shell.js +45 -1
  467. package/dist/tools/command-shell.js.map +1 -1
  468. package/dist/tools/coordinator/agent.d.ts.map +1 -1
  469. package/dist/tools/coordinator/agent.js +5 -0
  470. package/dist/tools/coordinator/agent.js.map +1 -1
  471. package/dist/tools/coordinator/ask-user-question.d.ts.map +1 -1
  472. package/dist/tools/coordinator/ask-user-question.js +26 -13
  473. package/dist/tools/coordinator/ask-user-question.js.map +1 -1
  474. package/dist/tools/coordinator/index.d.ts.map +1 -1
  475. package/dist/tools/coordinator/index.js +5 -0
  476. package/dist/tools/coordinator/index.js.map +1 -1
  477. package/dist/tools/coordinator/question-options.d.ts +78 -0
  478. package/dist/tools/coordinator/question-options.d.ts.map +1 -0
  479. package/dist/tools/coordinator/question-options.js +153 -0
  480. package/dist/tools/coordinator/question-options.js.map +1 -0
  481. package/dist/tools/defineTool.d.ts +10 -0
  482. package/dist/tools/defineTool.d.ts.map +1 -1
  483. package/dist/tools/defineTool.js +17 -0
  484. package/dist/tools/defineTool.js.map +1 -1
  485. package/dist/tools/memory/search.d.ts.map +1 -1
  486. package/dist/tools/memory/search.js +4 -1
  487. package/dist/tools/memory/search.js.map +1 -1
  488. package/dist/tools/memory/update.d.ts.map +1 -1
  489. package/dist/tools/memory/update.js +8 -5
  490. package/dist/tools/memory/update.js.map +1 -1
  491. package/dist/tools/render-nonce.d.ts +47 -0
  492. package/dist/tools/render-nonce.d.ts.map +1 -0
  493. package/dist/tools/render-nonce.js +63 -0
  494. package/dist/tools/render-nonce.js.map +1 -0
  495. package/dist/tools/roster.d.ts +46 -19
  496. package/dist/tools/roster.d.ts.map +1 -1
  497. package/dist/tools/roster.js +63 -33
  498. package/dist/tools/roster.js.map +1 -1
  499. package/dist/tools/schedules/schedule-tool.d.ts.map +1 -1
  500. package/dist/tools/schedules/schedule-tool.js +94 -14
  501. package/dist/tools/schedules/schedule-tool.js.map +1 -1
  502. package/dist/tools/schedules/types.d.ts +52 -6
  503. package/dist/tools/schedules/types.d.ts.map +1 -1
  504. package/dist/tools/trusted-read-only.d.ts +9 -5
  505. package/dist/tools/trusted-read-only.d.ts.map +1 -1
  506. package/dist/tools/trusted-read-only.js +14 -10
  507. package/dist/tools/trusted-read-only.js.map +1 -1
  508. package/dist/tools/untrusted-envelope.d.ts +67 -28
  509. package/dist/tools/untrusted-envelope.d.ts.map +1 -1
  510. package/dist/tools/untrusted-envelope.js +108 -59
  511. package/dist/tools/untrusted-envelope.js.map +1 -1
  512. package/dist/toolsets/combine.d.ts +44 -0
  513. package/dist/toolsets/combine.d.ts.map +1 -0
  514. package/dist/toolsets/combine.js +153 -0
  515. package/dist/toolsets/combine.js.map +1 -0
  516. package/dist/toolsets/manager.d.ts +201 -0
  517. package/dist/toolsets/manager.d.ts.map +1 -0
  518. package/dist/toolsets/manager.js +837 -0
  519. package/dist/toolsets/manager.js.map +1 -0
  520. package/dist/toolsets/source-glob.d.ts +15 -0
  521. package/dist/toolsets/source-glob.d.ts.map +1 -0
  522. package/dist/toolsets/source-glob.js +23 -0
  523. package/dist/toolsets/source-glob.js.map +1 -0
  524. package/dist/toolsets/toolset.d.ts +20 -0
  525. package/dist/toolsets/toolset.d.ts.map +1 -0
  526. package/dist/toolsets/toolset.js +28 -0
  527. package/dist/toolsets/toolset.js.map +1 -0
  528. package/dist/toolsets/types.d.ts +128 -0
  529. package/dist/toolsets/types.d.ts.map +1 -0
  530. package/dist/toolsets/types.js +33 -0
  531. package/dist/toolsets/types.js.map +1 -0
  532. package/dist/toolsets/wrappers.d.ts +59 -0
  533. package/dist/toolsets/wrappers.d.ts.map +1 -0
  534. package/dist/toolsets/wrappers.js +165 -0
  535. package/dist/toolsets/wrappers.js.map +1 -0
  536. package/dist/types/agent/base.d.ts +27 -16
  537. package/dist/types/agent/base.d.ts.map +1 -1
  538. package/dist/types/agent/index.d.ts +1 -0
  539. package/dist/types/agent/index.d.ts.map +1 -1
  540. package/dist/types/agent/index.js +1 -0
  541. package/dist/types/agent/index.js.map +1 -1
  542. package/dist/types/agent/pipeline.d.ts +2 -0
  543. package/dist/types/agent/pipeline.d.ts.map +1 -1
  544. package/dist/types/agent/query.d.ts +117 -0
  545. package/dist/types/agent/query.d.ts.map +1 -0
  546. package/dist/types/agent/query.js +2 -0
  547. package/dist/types/agent/query.js.map +1 -0
  548. package/dist/types/agent/reactive.d.ts +2 -129
  549. package/dist/types/agent/reactive.d.ts.map +1 -1
  550. package/dist/types/agent/router.d.ts +2 -0
  551. package/dist/types/agent/router.d.ts.map +1 -1
  552. package/dist/types/agent/scheduler.d.ts +6 -1
  553. package/dist/types/agent/scheduler.d.ts.map +1 -1
  554. package/dist/types/agent/supervisor.d.ts +5 -2
  555. package/dist/types/agent/supervisor.d.ts.map +1 -1
  556. package/dist/types/agent/task.d.ts +19 -1
  557. package/dist/types/agent/task.d.ts.map +1 -1
  558. package/dist/types/agent/task.js.map +1 -1
  559. package/dist/types/authorization/index.d.ts +49 -12
  560. package/dist/types/authorization/index.d.ts.map +1 -1
  561. package/dist/types/authorization/index.js +6 -0
  562. package/dist/types/authorization/index.js.map +1 -1
  563. package/dist/types/connector/mcp.d.ts +45 -0
  564. package/dist/types/connector/mcp.d.ts.map +1 -1
  565. package/dist/types/errors/index.d.ts +15 -0
  566. package/dist/types/errors/index.d.ts.map +1 -1
  567. package/dist/types/errors/index.js.map +1 -1
  568. package/dist/types/hitl/index.d.ts +57 -0
  569. package/dist/types/hitl/index.d.ts.map +1 -1
  570. package/dist/types/hitl/index.js.map +1 -1
  571. package/dist/types/message/index.d.ts +130 -9
  572. package/dist/types/message/index.d.ts.map +1 -1
  573. package/dist/types/message/index.js +4 -1
  574. package/dist/types/message/index.js.map +1 -1
  575. package/dist/types/plugin/index.d.ts +22 -4
  576. package/dist/types/plugin/index.d.ts.map +1 -1
  577. package/dist/types/plugin/index.js +1 -0
  578. package/dist/types/plugin/index.js.map +1 -1
  579. package/dist/types/provider/chat.d.ts +5 -0
  580. package/dist/types/provider/chat.d.ts.map +1 -1
  581. package/dist/types/provider/config.d.ts +8 -3
  582. package/dist/types/provider/config.d.ts.map +1 -1
  583. package/dist/types/provider/stream.d.ts +39 -0
  584. package/dist/types/provider/stream.d.ts.map +1 -1
  585. package/dist/types/sandbox/index.d.ts +1 -1
  586. package/dist/types/session/events.d.ts +14 -3
  587. package/dist/types/session/events.d.ts.map +1 -1
  588. package/dist/types/session/events.js.map +1 -1
  589. package/dist/types/session/sub-session.d.ts +2 -0
  590. package/dist/types/session/sub-session.d.ts.map +1 -1
  591. package/dist/types/tool/index.d.ts +152 -91
  592. package/dist/types/tool/index.d.ts.map +1 -1
  593. package/dist/types/tool/index.js.map +1 -1
  594. package/dist/types/toolset/index.d.ts +10 -40
  595. package/dist/types/toolset/index.d.ts.map +1 -1
  596. package/package.json +1 -1
  597. package/src/advisory/history.ts +27 -2
  598. package/src/advisory/index.ts +1 -1
  599. package/src/advisory/registry.ts +33 -0
  600. package/src/agents/AGENTS.md +14 -7
  601. package/src/agents/PipelineAgent.ts +2 -303
  602. package/src/agents/QueryAgent.ts +269 -0
  603. package/src/agents/ReactiveAgent.ts +6 -216
  604. package/src/agents/RouterAgent.ts +2 -337
  605. package/src/agents/SupervisorAgent.ts +3 -476
  606. package/src/agents/defineAgent.ts +13 -2
  607. package/src/agents/examples/PipelineAgent.ts +302 -0
  608. package/src/agents/examples/RouterAgent.ts +338 -0
  609. package/src/agents/examples/SupervisorAgent.ts +472 -0
  610. package/src/agents/explore.ts +6 -3
  611. package/src/agents/forward-options.ts +37 -0
  612. package/src/agents/index.ts +2 -0
  613. package/src/agents/runAgent.ts +144 -37
  614. package/src/authorization/command-line.ts +2 -2
  615. package/src/authorization/gate.ts +21 -1
  616. package/src/authorization/program.ts +773 -0
  617. package/src/authorization/reexec-wrapper.ts +589 -0
  618. package/src/authorization/rules.ts +18 -1
  619. package/src/authorization/shell-lexer.ts +104 -59
  620. package/src/bridge/sse/mapper.ts +6 -0
  621. package/src/capabilities/index.ts +157 -0
  622. package/src/config/registry.ts +4 -1
  623. package/src/connector/index.ts +9 -2
  624. package/src/connector/mcp/adapter.ts +73 -3
  625. package/src/connector/mcp/client.ts +425 -6
  626. package/src/connector/mcp/discovery.ts +60 -0
  627. package/src/connector/mcp/era.ts +7 -0
  628. package/src/connector/mcp/index.ts +13 -0
  629. package/src/connector/mcp/mcp-toolset.ts +515 -0
  630. package/src/connector/mcp/streamable-http.ts +302 -5
  631. package/src/connector/tools/index.ts +2 -2
  632. package/src/connector/tools/router.ts +35 -58
  633. package/src/directory/derive-supervisor.ts +12 -8
  634. package/src/directory/derive.ts +8 -5
  635. package/src/execution/code-runtime/types.ts +2 -2
  636. package/src/invariants/index.ts +4 -1
  637. package/src/manager/agent/lifecycle.ts +167 -19
  638. package/src/manager/connector/environment.ts +17 -4
  639. package/src/manager/connector/index.ts +2 -2
  640. package/src/manager/connector/tenant.ts +17 -4
  641. package/src/manager/index.ts +2 -2
  642. package/src/manager/session/attribution.ts +79 -0
  643. package/src/manager/session/turn-recorder.ts +211 -55
  644. package/src/peers/address.ts +58 -0
  645. package/src/peers/client.ts +202 -0
  646. package/src/peers/dir.ts +176 -0
  647. package/src/peers/endpoint.ts +564 -0
  648. package/src/peers/envelope.ts +121 -0
  649. package/src/peers/index.ts +96 -0
  650. package/src/peers/protocol.ts +196 -0
  651. package/src/peers/record.ts +56 -0
  652. package/src/peers/registry.ts +241 -0
  653. package/src/plugin/define.ts +68 -0
  654. package/src/plugin/index.ts +2 -0
  655. package/src/plugin/lifecycle.ts +286 -106
  656. package/src/plugin/resolver.ts +6 -3
  657. package/src/plugin/shell-hook.ts +21 -5
  658. package/src/probe/errors.ts +4 -1
  659. package/src/prompt/coding-agent-doctrine.ts +22 -10
  660. package/src/prompt/contributions.ts +12 -2
  661. package/src/prompt/index.ts +1 -0
  662. package/src/provider/collect-chat-completion.ts +96 -11
  663. package/src/provider/mock.ts +24 -6
  664. package/src/provider/registry.ts +4 -1
  665. package/src/provider/tool-call-framing.ts +226 -0
  666. package/src/public-runtime.ts +136 -7
  667. package/src/public-tools.ts +24 -4
  668. package/src/public-types.ts +60 -6
  669. package/src/read-model/registry.ts +7 -2
  670. package/src/registry/ManagedRegistry.ts +57 -6
  671. package/src/registry/collision.ts +64 -0
  672. package/src/registry/command/index.ts +7 -3
  673. package/src/registry/index.ts +3 -9
  674. package/src/registry/plugin/index.ts +14 -1
  675. package/src/registry/tool/callable.ts +8 -9
  676. package/src/registry/tool/execute.ts +16 -846
  677. package/src/registry/tool/portable.ts +59 -0
  678. package/src/registry/tool/presentation.ts +6 -5
  679. package/src/runtime/bidi/session.ts +24 -5
  680. package/src/runtime/query/executor/tool-call-admission.ts +228 -6
  681. package/src/runtime/query/executor.ts +110 -12
  682. package/src/runtime/query/file-evidence-replay.ts +8 -7
  683. package/src/runtime/query/fork/prepare.ts +6 -1
  684. package/src/runtime/query/guardrail-presets.ts +4 -3
  685. package/src/runtime/query/index.ts +199 -101
  686. package/src/runtime/query/iteration/index.ts +13 -3
  687. package/src/runtime/query/iteration/phases/compaction.ts +1 -1
  688. package/src/runtime/query/iteration/phases/context.ts +2 -2
  689. package/src/runtime/query/iteration/phases/tool-review.ts +59 -2
  690. package/src/runtime/query/iteration/stream-turn.ts +390 -136
  691. package/src/runtime/query/iteration/tool-input.ts +284 -0
  692. package/src/runtime/query/observation-context.ts +2 -2
  693. package/src/runtime/query/prelude-lease.ts +132 -0
  694. package/src/runtime/query/prepare-turn.ts +477 -198
  695. package/src/runtime/query/prompt-cache.ts +2 -2
  696. package/src/runtime/query/prompt.ts +4 -4
  697. package/src/runtime/query/resume-session.ts +42 -3
  698. package/src/runtime/query/review-policy.ts +87 -9
  699. package/src/runtime/query/tooling.ts +3 -6
  700. package/src/runtime/query/turn-state.ts +4 -0
  701. package/src/runtime/system-events.ts +246 -0
  702. package/src/scheduler/delegating.ts +7 -2
  703. package/src/scheduler/local.ts +2 -0
  704. package/src/session/retention/archive.ts +1 -1
  705. package/src/skills/index.ts +1 -1
  706. package/src/skills/registry.ts +25 -0
  707. package/src/store/session/disk.ts +3 -0
  708. package/src/store/session-log/conformance.ts +51 -8
  709. package/src/store/session-log/core.ts +10 -4
  710. package/src/store/session-log/fold.ts +33 -7
  711. package/src/store/session-log/index.ts +2 -0
  712. package/src/test-support/toolset.ts +23 -0
  713. package/src/tools/builtins/bash.ts +27 -10
  714. package/src/tools/builtins/browser-url.ts +1 -1
  715. package/src/tools/builtins/browser.ts +2 -2
  716. package/src/tools/builtins/computer-use.ts +21 -11
  717. package/src/tools/builtins/edit.ts +12 -2
  718. package/src/tools/builtins/json-string-hint.ts +16 -0
  719. package/src/tools/builtins/search-tools.ts +7 -20
  720. package/src/tools/builtins/write-file.ts +12 -0
  721. package/src/tools/command-shell.ts +46 -1
  722. package/src/tools/coordinator/agent.ts +6 -0
  723. package/src/tools/coordinator/ask-user-question.ts +29 -15
  724. package/src/tools/coordinator/index.ts +6 -0
  725. package/src/tools/coordinator/question-options.ts +195 -0
  726. package/src/tools/defineTool.ts +28 -0
  727. package/src/tools/memory/search.ts +4 -1
  728. package/src/tools/memory/update.ts +8 -5
  729. package/src/tools/render-nonce.ts +69 -0
  730. package/src/tools/roster.ts +84 -33
  731. package/src/tools/schedules/schedule-tool.ts +107 -14
  732. package/src/tools/schedules/types.ts +52 -6
  733. package/src/tools/trusted-read-only.ts +19 -10
  734. package/src/tools/untrusted-envelope.ts +121 -57
  735. package/src/toolsets/combine.ts +181 -0
  736. package/src/toolsets/manager.ts +996 -0
  737. package/src/toolsets/source-glob.ts +22 -0
  738. package/src/toolsets/toolset.ts +31 -0
  739. package/src/toolsets/types.ts +154 -0
  740. package/src/toolsets/wrappers.ts +191 -0
  741. package/src/types/agent/base.ts +29 -16
  742. package/src/types/agent/index.ts +1 -0
  743. package/src/types/agent/pipeline.ts +2 -0
  744. package/src/types/agent/query.ts +129 -0
  745. package/src/types/agent/reactive.ts +5 -142
  746. package/src/types/agent/router.ts +2 -0
  747. package/src/types/agent/scheduler.ts +6 -1
  748. package/src/types/agent/supervisor.ts +5 -2
  749. package/src/types/agent/task.ts +21 -1
  750. package/src/types/authorization/index.ts +12 -0
  751. package/src/types/connector/mcp.ts +46 -0
  752. package/src/types/errors/index.ts +15 -0
  753. package/src/types/hitl/index.ts +57 -0
  754. package/src/types/message/index.ts +135 -7
  755. package/src/types/plugin/index.ts +44 -21
  756. package/src/types/provider/chat.ts +5 -0
  757. package/src/types/provider/config.ts +8 -3
  758. package/src/types/provider/stream.ts +39 -0
  759. package/src/types/sandbox/index.ts +1 -1
  760. package/src/types/session/events.ts +14 -3
  761. package/src/types/session/sub-session.ts +2 -0
  762. package/src/types/tool/index.ts +154 -105
  763. package/src/types/toolset/index.ts +10 -47
  764. package/dist/registry/toolset/catalog.d.ts +0 -42
  765. package/dist/registry/toolset/catalog.d.ts.map +0 -1
  766. package/dist/registry/toolset/catalog.js +0 -234
  767. package/dist/registry/toolset/catalog.js.map +0 -1
  768. package/src/registry/toolset/catalog.ts +0 -308
@@ -10,6 +10,7 @@ import {
10
10
  type SessionLogEntry,
11
11
  type SessionLogHead,
12
12
  SessionMessageFold,
13
+ withMessageId,
13
14
  } from '../../store/session-log/index.js'
14
15
  import type { SpillRef } from '../../store/session-log/spill.js'
15
16
  import { getActiveSpanContext } from '../../telemetry/runtime-accessors.js'
@@ -52,6 +53,7 @@ import {
52
53
  } from '../../utils/cost.js'
53
54
  import { asCheckpointId, generateAuditEventId, generateMessageId } from '../../utils/id.js'
54
55
  import { childSessionEnded } from '../agent/child-session.js'
56
+ import { assertSessionLogAttribution } from './attribution.js'
55
57
 
56
58
  /** Which provider and model a cost is priced against. */
57
59
  export interface PricingSubject {
@@ -66,10 +68,29 @@ export interface RecordedMessage {
66
68
  readonly messageId?: MessageId
67
69
  }
68
70
 
71
+ /**
72
+ * Stamp (or clear) `id` on a message already living in `recorder.messages`,
73
+ * in place — the recorder's own bookkeeping (`#ids`, `#recorded`, `#view`)
74
+ * is keyed by object IDENTITY, so replacing the array element the way
75
+ * `withMessageId` does would desync it. `recorder.messages`/`Turn.messages`
76
+ * is the one place a message a HOST passed in is allowed to change under
77
+ * it: once the kernel records that exact object, it is stamped with the id
78
+ * its record was given, which is the id `BaseMessage.id` documents. A
79
+ * message read from the log for a DIFFERENT purpose (a fold a host did not
80
+ * hand in, a checkpoint restore) is never this function's object — it goes
81
+ * through `withMessageId`, a copy, because nothing here owns it to mutate.
82
+ */
83
+ function stampMessageId(message: Message, id: MessageId | undefined): void {
84
+ if (id === undefined) delete (message as { id?: MessageId }).id
85
+ else (message as { id?: MessageId }).id = id
86
+ }
87
+
69
88
  /** How {@link TurnRecorder.open} takes the session's writer lease and starts an empty log. */
70
89
  export interface TurnRecorderOpenOptions {
71
90
  /** A lease the caller already holds. Absent: the recorder claims one and releases it at the end. */
72
91
  readonly lease?: SessionLease
92
+ /** A lease claimed by the query prelude, transferred to the recorder for release. */
93
+ readonly ownLease?: boolean
73
94
  /** The holder name for a lease the recorder claims. */
74
95
  readonly holder?: string
75
96
  /** Lease time-to-live for a lease the recorder claims. Renewed while the turn runs. */
@@ -197,6 +218,9 @@ export class TurnRecorder {
197
218
  #released = false
198
219
  #leaseHolder = ''
199
220
  #leaseTtlMs = DEFAULT_TURN_LEASE_TTL_MS
221
+ #leaseHeartbeat: ReturnType<typeof setInterval> | undefined
222
+ #leaseRenewal: Promise<void> = Promise.resolve()
223
+ #leaseRenewalError: unknown
200
224
  #chain: Promise<void> = Promise.resolve()
201
225
  #failure: unknown = undefined
202
226
  #view: ViewEntry[] = []
@@ -233,7 +257,10 @@ export class TurnRecorder {
233
257
  throw new NamzuError({
234
258
  code: 'invalid_config',
235
259
  message: `The session log belongs to session ${config.sessionLog.sessionId}, not ${config.sessionId}.`,
236
- details: { sessionId: config.sessionId, logSessionId: config.sessionLog.sessionId },
260
+ details: {
261
+ sessionId: config.sessionId,
262
+ logSessionId: config.sessionLog.sessionId,
263
+ },
237
264
  })
238
265
  }
239
266
  this.#turn = {
@@ -344,7 +371,10 @@ export class TurnRecorder {
344
371
  get costInfo(): CostInfo {
345
372
  const unpriced = Math.max(0, this.tokenUsage.totalTokens - this.#turn.tokenUsage.totalTokens)
346
373
  return unpriced > 0
347
- ? { ...this.#turn.costInfo, unpricedTokens: this.#turn.costInfo.unpricedTokens + unpriced }
374
+ ? {
375
+ ...this.#turn.costInfo,
376
+ unpricedTokens: this.#turn.costInfo.unpricedTokens + unpriced,
377
+ }
348
378
  : this.#turn.costInfo
349
379
  }
350
380
 
@@ -570,60 +600,114 @@ export class TurnRecorder {
570
600
  async open(options: TurnRecorderOpenOptions): Promise<RecordedMessage[]> {
571
601
  if (this.#phase !== 'new') throw new Error('TurnRecorder.open was already called.')
572
602
  this.#leaseTtlMs = options.leaseTtlMs ?? DEFAULT_TURN_LEASE_TTL_MS
573
- this.#leaseHolder = options.holder ?? `namzu:${process.pid}:${this.turnId}`
574
- if (options.lease) {
575
- this.#lease = options.lease
576
- } else {
577
- const lease = await this.log.claim({ holder: this.#leaseHolder, ttlMs: this.#leaseTtlMs })
578
- if (lease === null) {
579
- const active = await this.log.activeTurn()
580
- if (active) {
581
- throw new TurnInProgressError({
582
- sessionId: this.sessionId,
583
- activeTurnId: active.turnId,
584
- state: 'running',
603
+ this.#leaseHolder =
604
+ options.holder ?? options.lease?.holder ?? `namzu:${process.pid}:${this.turnId}`
605
+ try {
606
+ if (options.lease) {
607
+ this.#lease = options.lease
608
+ this.#ownsLease = options.ownLease === true
609
+ }
610
+ // Claiming a log may repair a torn tail. Refuse a foreign owner
611
+ // before that mutation, then recheck under the lease below.
612
+ await assertSessionLogAttribution(this.log, this.#config)
613
+ if (!options.lease) {
614
+ const lease = await this.log.claim({
615
+ holder: this.#leaseHolder,
616
+ ttlMs: this.#leaseTtlMs,
617
+ repairTornTail: false,
618
+ })
619
+ if (lease === null) {
620
+ const active = await this.log.activeTurn()
621
+ if (active) {
622
+ throw new TurnInProgressError({
623
+ sessionId: this.sessionId,
624
+ activeTurnId: active.turnId,
625
+ state: 'running',
626
+ })
627
+ }
628
+ throw new NamzuError({
629
+ code: 'invalid_config',
630
+ message: `Session ${this.sessionId} is leased by another writer; wait for it to finish or pass the lease you hold.`,
631
+ details: { sessionId: this.sessionId },
585
632
  })
586
633
  }
587
- throw new NamzuError({
588
- code: 'invalid_config',
589
- message: `Session ${this.sessionId} is leased by another writer; wait for it to finish or pass the lease you hold.`,
590
- details: { sessionId: this.sessionId },
634
+ this.#lease = lease
635
+ this.#ownsLease = true
636
+ }
637
+ const lease = this.#lease
638
+ if (!lease) throw new Error('TurnRecorder.open did not acquire a writer lease.')
639
+ if (this.#ownsLease) {
640
+ this.#leaseHeartbeat = setInterval(() => this.#queueLeaseRenewal(), this.#leaseTtlMs / 2)
641
+ this.#leaseHeartbeat.unref()
642
+ }
643
+ const head = await this.log.head()
644
+ if (head === null) {
645
+ this.#lastEntry = await this.log.append(lease, {
646
+ type: 'session_started',
647
+ projectId: this.projectId,
648
+ tenantId: this.tenantId,
649
+ topicId: this.topicId,
650
+ cwd: options.session.cwd,
651
+ agent: {
652
+ id: this.#config.agentId,
653
+ name: this.#config.agentName,
654
+ ...(options.session.agentType ? { type: options.session.agentType } : {}),
655
+ },
656
+ ...(options.session.origin ? { origin: options.session.origin } : {}),
657
+ ...(options.session.forkedFrom ? { forkedFrom: options.session.forkedFrom } : {}),
591
658
  })
659
+ } else {
660
+ await assertSessionLogAttribution(this.log, this.#config)
592
661
  }
593
- this.#lease = lease
594
- this.#ownsLease = true
662
+ if (options.session.forkedFrom) {
663
+ this.#turn.forkedFrom = options.session.forkedFrom
664
+ }
665
+ this.#phase = 'open'
666
+ return await readFoldedHistory(this.log)
667
+ } catch (error) {
668
+ await this.release()
669
+ throw error
595
670
  }
596
- const head = await this.log.head()
597
- if (head === null) {
598
- this.#lastEntry = await this.log.append(this.#lease, {
599
- type: 'session_started',
600
- projectId: this.projectId,
601
- tenantId: this.tenantId,
602
- topicId: this.topicId,
603
- cwd: options.session.cwd,
604
- agent: {
605
- id: this.#config.agentId,
606
- name: this.#config.agentName,
607
- ...(options.session.agentType ? { type: options.session.agentType } : {}),
608
- },
609
- ...(options.session.origin ? { origin: options.session.origin } : {}),
610
- ...(options.session.forkedFrom ? { forkedFrom: options.session.forkedFrom } : {}),
671
+ }
672
+
673
+ /** Serialize timer and write-triggered renewals so release uses the latest token. */
674
+ #queueLeaseRenewal(): void {
675
+ this.#leaseRenewal = this.#leaseRenewal
676
+ .then(async () => {
677
+ if (!this.#ownsLease || this.#released || this.#leaseRenewalError !== undefined) return
678
+ const current = this.#lease
679
+ if (!current) return
680
+ const renewed = await this.log.claim({
681
+ holder: this.#leaseHolder,
682
+ ttlMs: this.#leaseTtlMs,
683
+ repairTornTail: false,
684
+ })
685
+ if (renewed === null || renewed.fence !== current.fence) {
686
+ if (renewed !== null) await this.log.release(renewed).catch(() => undefined)
687
+ throw new NamzuError({
688
+ code: 'invalid_config',
689
+ message: `Session ${this.sessionId} lost its writer lease during the turn.`,
690
+ details: { sessionId: this.sessionId },
691
+ })
692
+ }
693
+ this.#lease = renewed
694
+ })
695
+ .catch((error: unknown) => {
696
+ this.#leaseRenewalError ??= error
611
697
  })
612
- }
613
- if (options.session.forkedFrom) {
614
- this.#turn.forkedFrom = options.session.forkedFrom
615
- }
616
- this.#phase = 'open'
617
- return readFoldedHistory(this.log)
618
698
  }
619
699
 
620
700
  /** Renew a lease this recorder claimed when it is past half its life. */
621
701
  async #leaseForWrite(): Promise<SessionLease> {
622
- const lease = this.#lease
623
- if (!lease) throw new Error('TurnRecorder.open must run before the turn writes.')
624
- if (this.#ownsLease && lease.expiresAt - Date.now() < this.#leaseTtlMs / 2) {
625
- const renewed = await this.log.claim({ holder: this.#leaseHolder, ttlMs: this.#leaseTtlMs })
626
- if (renewed) this.#lease = renewed
702
+ if (!this.#lease) throw new Error('TurnRecorder.open must run before the turn writes.')
703
+ if (this.#ownsLease) {
704
+ await this.#leaseRenewal
705
+ if (this.#leaseRenewalError !== undefined) throw this.#leaseRenewalError
706
+ if (this.#lease.expiresAt - Date.now() < this.#leaseTtlMs / 2) {
707
+ this.#queueLeaseRenewal()
708
+ await this.#leaseRenewal
709
+ if (this.#leaseRenewalError !== undefined) throw this.#leaseRenewalError
710
+ }
627
711
  }
628
712
  return this.#lease as SessionLease
629
713
  }
@@ -631,10 +715,12 @@ export class TurnRecorder {
631
715
  /** Give up a lease the recorder claimed. Never throws. */
632
716
  async release(): Promise<void> {
633
717
  if (!this.#ownsLease || !this.#lease) return
634
- const lease = this.#lease
635
- this.#ownsLease = false
636
718
  this.#released = true
637
- await this.log.release(lease).catch(() => undefined)
719
+ if (this.#leaseHeartbeat !== undefined) clearInterval(this.#leaseHeartbeat)
720
+ this.#leaseHeartbeat = undefined
721
+ await this.#leaseRenewal
722
+ this.#ownsLease = false
723
+ await this.log.release(this.#lease).catch(() => undefined)
638
724
  }
639
725
 
640
726
  #enqueue<T>(operation: () => Promise<T>): Promise<T> {
@@ -842,7 +928,9 @@ export class TurnRecorder {
842
928
  recordChildSessionEvent(
843
929
  event: Extract<
844
930
  SessionEvent,
845
- { type: 'child_session_spawned' | 'child_session_messaged' | 'child_session_idled' }
931
+ {
932
+ type: 'child_session_spawned' | 'child_session_messaged' | 'child_session_idled'
933
+ }
846
934
  >,
847
935
  childLog?: SessionLog,
848
936
  ): Promise<SessionLogEntry | undefined> {
@@ -877,8 +965,12 @@ export class TurnRecorder {
877
965
  if (!target?.id) return
878
966
  const current = target.message as AssistantMessage
879
967
  if (current.content === result) return
880
- const replacement: AssistantMessage = { ...current, content: result }
881
968
  const targetMessageId = target.id
969
+ const replacement: AssistantMessage = {
970
+ ...current,
971
+ content: result,
972
+ id: targetMessageId,
973
+ }
882
974
  await this.#enqueue(() =>
883
975
  this.#append({
884
976
  type: 'message_replaced',
@@ -911,11 +1003,15 @@ export class TurnRecorder {
911
1003
  */
912
1004
  pushMessage(
913
1005
  message: Message,
914
- options: { readonly messageId?: MessageId; readonly transient?: boolean } = {},
1006
+ options: {
1007
+ readonly messageId?: MessageId
1008
+ readonly transient?: boolean
1009
+ } = {},
915
1010
  ): void {
916
1011
  if (options.messageId) {
917
1012
  this.#ids.set(message, options.messageId)
918
1013
  this.#recorded.set(message, options.messageId)
1014
+ stampMessageId(message, options.messageId)
919
1015
  }
920
1016
  if (options.transient) this.#transient.add(message)
921
1017
  this.#turn.messages.push(message)
@@ -965,6 +1061,7 @@ export class TurnRecorder {
965
1061
  this.#ids.set(message, id)
966
1062
  }
967
1063
  this.#recorded.set(message, id)
1064
+ stampMessageId(message, id)
968
1065
  return id
969
1066
  }
970
1067
 
@@ -1054,6 +1151,11 @@ export class TurnRecorder {
1054
1151
  for (const entry of summaryEntries) {
1055
1152
  entry.id = undefined
1056
1153
  this.#ids.delete(entry.message)
1154
+ // A summary member is no longer individually recorded — a fresh
1155
+ // fold would show it with no id, so its object stops claiming one
1156
+ // too. `entry.message` is the same object `live` holds at this
1157
+ // position (built from it, above), so this is what a caller sees.
1158
+ stampMessageId(entry.message, undefined)
1057
1159
  }
1058
1160
  const summary = summaryEntries.map((entry) => entry.message)
1059
1161
  const keptMessageIds = keptEntries.map((entry) => entry.id as MessageId)
@@ -1129,7 +1231,11 @@ export class TurnRecorder {
1129
1231
  type: 'audit',
1130
1232
  ...(event.turnId ? { turnId: event.turnId } : {}),
1131
1233
  auditId: event.id,
1132
- actor: { kind: 'agent', agentId: this.#turn.metadata.agentId, tenantId: this.tenantId },
1234
+ actor: {
1235
+ kind: 'agent',
1236
+ agentId: this.#turn.metadata.agentId,
1237
+ tenantId: this.tenantId,
1238
+ },
1133
1239
  ...(input.persona !== undefined ? { persona: input.persona } : {}),
1134
1240
  action: input.what.action,
1135
1241
  ...(input.what.tool !== undefined ? { tool: input.what.tool } : {}),
@@ -1241,19 +1347,69 @@ export async function readFoldedHistory(
1241
1347
  const out: RecordedMessage[] = []
1242
1348
  const spilled = fold.spilledSummary
1243
1349
  if (spilled) {
1350
+ // `withMessageId(message, undefined)` strips any id already embedded in
1351
+ // the spilled JSON — same as the inline branch below, and for the same
1352
+ // reason `readEverRecordedMessages`'s doc comment gives: a summary
1353
+ // member has no record of its own. A synthesized summary never had an
1354
+ // id, so this is invisible there; a fork's seeded summary IS the
1355
+ // source session's own already-id'd messages, and without this a
1356
+ // spilled (large) fork's first live turn reads its fold back carrying
1357
+ // a DIFFERENT session's ids and fails reconciliation as foreign.
1244
1358
  for (const message of JSON.parse(await log.readSpill(spilled.spill)) as Message[]) {
1245
- out.push({ message })
1359
+ out.push({ message: withMessageId(message, undefined) })
1246
1360
  }
1247
1361
  }
1248
1362
  for (const entry of fold.entries()) {
1249
1363
  const message = entry.spill
1250
1364
  ? (JSON.parse(await log.readSpill(entry.spill as SpillRef)) as Message)
1251
1365
  : entry.message
1252
- out.push({ message, ...(entry.messageId ? { messageId: entry.messageId } : {}) })
1366
+ out.push({
1367
+ message: withMessageId(message, entry.messageId),
1368
+ ...(entry.messageId ? { messageId: entry.messageId } : {}),
1369
+ })
1253
1370
  }
1254
1371
  return out
1255
1372
  }
1256
1373
 
1374
+ /**
1375
+ * Every message this session's log has ever recorded, keyed by the durable
1376
+ * id its `message` record gave it — including one a compaction has since
1377
+ * folded into a summary and dropped from {@link readFoldedHistory}'s
1378
+ * current fold. A `message_replaced` record's content wins over the message
1379
+ * it targets, the log's own precedence for "what this id means now."
1380
+ *
1381
+ * A compaction summary member has no entry here: it was never its own
1382
+ * `message` record (see {@link RecordedMessage.messageId}), so nothing can
1383
+ * recognise it by id — a caller's copy of it is reconciled by value instead.
1384
+ */
1385
+ export async function readEverRecordedMessages(
1386
+ log: SessionLog,
1387
+ ): Promise<ReadonlyMap<MessageId, Message>> {
1388
+ const latest = new Map<MessageId, { readonly content: Message; readonly spill?: SpillRef }>()
1389
+ for await (const entry of log.read()) {
1390
+ const record = entry.record as SessionRecord
1391
+ if (record.type === 'message') {
1392
+ latest.set(record.messageId, {
1393
+ content: record.content,
1394
+ ...(record.spill ? { spill: record.spill } : {}),
1395
+ })
1396
+ } else if (record.type === 'message_replaced') {
1397
+ latest.set(record.targetMessageId, {
1398
+ content: record.content,
1399
+ ...(record.spill ? { spill: record.spill } : {}),
1400
+ })
1401
+ }
1402
+ }
1403
+ const resolved = new Map<MessageId, Message>()
1404
+ for (const [id, entry] of latest) {
1405
+ const content = entry.spill
1406
+ ? (JSON.parse(await log.readSpill(entry.spill)) as Message)
1407
+ : entry.content
1408
+ resolved.set(id, withMessageId(content, id))
1409
+ }
1410
+ return resolved
1411
+ }
1412
+
1257
1413
  /**
1258
1414
  * A session's audit trail: its `audit` records as {@link AuditEvent}s, in log
1259
1415
  * order, each numbered among the session's audit entries. What
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Peer addresses are URIs so a later cross-machine transport can be added
3
+ * without redesigning the registry or the protocol: `uds:<path>` and
4
+ * `pipe:<name>` today, `a2a:https://…` later (design §1.1). Only the two
5
+ * local schemes are ever SERVED or DIALED by this package; `a2a:` addresses
6
+ * are recognised so a reader can tell them apart, not connected to.
7
+ *
8
+ * @experimental
9
+ */
10
+
11
+ import { join } from 'node:path'
12
+ import { peerSocketFileName } from './dir.js'
13
+
14
+ export type PeerAddress =
15
+ | { readonly scheme: 'uds'; readonly path: string }
16
+ | { readonly scheme: 'pipe'; readonly path: string }
17
+ | { readonly scheme: 'a2a'; readonly url: string }
18
+
19
+ export class PeerAddressError extends Error {
20
+ override readonly name = 'PeerAddressError'
21
+ }
22
+
23
+ /** The `uds:<path>` address for a session's socket inside a hardened runtime directory. */
24
+ export function udsPeerAddress(runtimeDir: string, sessionId: string): string {
25
+ return `uds:${join(runtimeDir, peerSocketFileName(sessionId))}`
26
+ }
27
+
28
+ /**
29
+ * The `pipe:<name>` address for a session's Windows named pipe.
30
+ *
31
+ * `<name>` is the full pipe path Node's `net` module dials directly
32
+ * (`\\.\pipe\namzu-<uid-hash>-<session-short>`, design §1.1) — coded here for
33
+ * completeness; this package does not run its tests on win32, so the shape
34
+ * is reviewed rather than exercised.
35
+ */
36
+ export function pipePeerAddress(uidHash: string, sessionShort: string): string {
37
+ return `pipe:\\\\.\\pipe\\namzu-${uidHash}-${sessionShort}`
38
+ }
39
+
40
+ /** Parse a peer address URI. Throws {@link PeerAddressError} on an unrecognised or empty scheme. */
41
+ export function parsePeerAddress(address: string): PeerAddress {
42
+ if (address.startsWith('uds:')) {
43
+ const path = address.slice('uds:'.length)
44
+ if (path.length === 0) throw new PeerAddressError(`Empty uds: address: ${address}`)
45
+ return { scheme: 'uds', path }
46
+ }
47
+ if (address.startsWith('pipe:')) {
48
+ const path = address.slice('pipe:'.length)
49
+ if (path.length === 0) throw new PeerAddressError(`Empty pipe: address: ${address}`)
50
+ return { scheme: 'pipe', path }
51
+ }
52
+ if (address.startsWith('a2a:')) {
53
+ const url = address.slice('a2a:'.length)
54
+ if (url.length === 0) throw new PeerAddressError(`Empty a2a: address: ${address}`)
55
+ return { scheme: 'a2a', url }
56
+ }
57
+ throw new PeerAddressError(`Unrecognised peer address scheme: ${address}`)
58
+ }
@@ -0,0 +1,202 @@
1
+ /**
2
+ * A client for one connection of `namzu-peer/1`: connect, write one request
3
+ * line, read one response line, close. Mirrors the shape of this
4
+ * repository's other local control clients (`queryRunner` in
5
+ * `packages/cli/src/integrations/resident/runner-control.ts`,
6
+ * `callEndpoint` in `packages/cli/src/schedule/daemon/endpoint.ts`): an
7
+ * authenticated response PROVES responsiveness, and its absence never proves
8
+ * the peer is dead — only that this attempt could not reach it.
9
+ *
10
+ * @experimental
11
+ */
12
+
13
+ import { createConnection } from 'node:net'
14
+ import { parsePeerAddress } from './address.js'
15
+ import {
16
+ type DeliverRequest,
17
+ type DeliverResponse,
18
+ DeliverResponseSchema,
19
+ MAX_PEER_REQUEST_BYTES,
20
+ type NoticeRequest,
21
+ type NoticeResponse,
22
+ NoticeResponseSchema,
23
+ PEER_PROTOCOL_VERSION,
24
+ type PingRequest,
25
+ type PingResponse,
26
+ PingResponseSchema,
27
+ type SubscribeIdleRequest,
28
+ type SubscribeIdleResponse,
29
+ SubscribeIdleResponseSchema,
30
+ } from './protocol.js'
31
+ import type { PeerRecord } from './record.js'
32
+
33
+ const DEFAULT_TIMEOUT_MS = 2_000
34
+
35
+ export class PeerClientError extends Error {
36
+ override readonly name = 'PeerClientError'
37
+ }
38
+
39
+ /** An authenticated reply proves responsiveness; every other outcome names why none arrived. */
40
+ export type PeerClientResult<T> =
41
+ | ({ readonly kind: 'responded' } & T)
42
+ | { readonly kind: 'unreachable'; readonly reason: string }
43
+
44
+ function connectPath(address: string): string {
45
+ const parsed = parsePeerAddress(address)
46
+ if (parsed.scheme === 'a2a') {
47
+ throw new PeerClientError(`PeerClient cannot dial an a2a: address directly: ${address}`)
48
+ }
49
+ return parsed.path
50
+ }
51
+
52
+ /** One request, one response, one connection. */
53
+ function sendPeerRequest<T>(
54
+ address: string,
55
+ request: unknown,
56
+ parseResponse: (value: unknown) => T,
57
+ timeoutMs: number,
58
+ ): Promise<PeerClientResult<T>> {
59
+ return new Promise((resolve) => {
60
+ let settled = false
61
+ const finish = (result: PeerClientResult<T>): void => {
62
+ if (settled) return
63
+ settled = true
64
+ clearTimeout(timer)
65
+ socket.destroy()
66
+ resolve(result)
67
+ }
68
+ const unreachable = (error: unknown): void =>
69
+ finish({
70
+ kind: 'unreachable',
71
+ reason: error instanceof Error ? error.message : String(error),
72
+ })
73
+ const timer = setTimeout(() => unreachable(new Error('Peer request timed out.')), timeoutMs)
74
+ let path: string
75
+ try {
76
+ path = connectPath(address)
77
+ } catch (error) {
78
+ clearTimeout(timer)
79
+ resolve({
80
+ kind: 'unreachable',
81
+ reason: error instanceof Error ? error.message : String(error),
82
+ })
83
+ return
84
+ }
85
+ const socket = createConnection({ path })
86
+ let buffered = Buffer.alloc(0)
87
+ socket.once('error', unreachable)
88
+ socket.once('close', () =>
89
+ unreachable(new Error('Peer connection closed before a response arrived.')),
90
+ )
91
+ socket.once('connect', () => {
92
+ socket.write(`${JSON.stringify(request)}\n`)
93
+ })
94
+ socket.on('data', (chunk: Buffer) => {
95
+ if (buffered.length + chunk.length > MAX_PEER_REQUEST_BYTES) {
96
+ unreachable(new Error('Peer response exceeded the size limit.'))
97
+ return
98
+ }
99
+ buffered = Buffer.concat([buffered, chunk])
100
+ const newline = buffered.indexOf(10)
101
+ if (newline < 0) return
102
+ try {
103
+ const parsed: unknown = JSON.parse(buffered.subarray(0, newline).toString('utf8'))
104
+ finish({ kind: 'responded', ...parseResponse(parsed) })
105
+ } catch (error) {
106
+ unreachable(error)
107
+ }
108
+ })
109
+ })
110
+ }
111
+
112
+ export interface PeerClientOptions {
113
+ /** Default 2000ms. */
114
+ readonly timeoutMs?: number
115
+ }
116
+
117
+ /**
118
+ * `ping`, `deliver`, `subscribe_idle` and `notice` over `namzu-peer/1`.
119
+ *
120
+ * `deliver`/`subscribeIdle`/`notice` read the RECIPIENT's token from the
121
+ * `PeerRecord` passed in — the wire's token is always the recipient's own,
122
+ * asserted by the caller and verified by the server (design §1.1, §1.3).
123
+ * `ping` takes a bare address and carries no token; see the file header for
124
+ * why.
125
+ */
126
+ export class PeerClient {
127
+ private readonly timeoutMs: number
128
+
129
+ constructor(options: PeerClientOptions = {}) {
130
+ this.timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS
131
+ }
132
+
133
+ ping(address: string, timeoutMs = this.timeoutMs): Promise<PeerClientResult<PingResponse>> {
134
+ const request: PingRequest = { protocol: PEER_PROTOCOL_VERSION, op: 'ping' }
135
+ return sendPeerRequest(address, request, (value) => PingResponseSchema.parse(value), timeoutMs)
136
+ }
137
+
138
+ deliver(
139
+ record: Pick<PeerRecord, 'address' | 'token'>,
140
+ message: Omit<DeliverRequest, 'protocol' | 'op' | 'token'>,
141
+ ): Promise<PeerClientResult<DeliverResponse>> {
142
+ const request: DeliverRequest = {
143
+ protocol: PEER_PROTOCOL_VERSION,
144
+ op: 'deliver',
145
+ token: record.token,
146
+ ...message,
147
+ }
148
+ return sendPeerRequest(
149
+ record.address,
150
+ request,
151
+ (value) => DeliverResponseSchema.parse(value),
152
+ this.timeoutMs,
153
+ )
154
+ }
155
+
156
+ subscribeIdle(
157
+ record: Pick<PeerRecord, 'address' | 'token'>,
158
+ message: Omit<SubscribeIdleRequest, 'protocol' | 'op' | 'token'>,
159
+ ): Promise<PeerClientResult<SubscribeIdleResponse>> {
160
+ const request: SubscribeIdleRequest = {
161
+ protocol: PEER_PROTOCOL_VERSION,
162
+ op: 'subscribe_idle',
163
+ token: record.token,
164
+ ...message,
165
+ }
166
+ return sendPeerRequest(
167
+ record.address,
168
+ request,
169
+ (value) => SubscribeIdleResponseSchema.parse(value),
170
+ this.timeoutMs,
171
+ )
172
+ }
173
+
174
+ notice(
175
+ record: Pick<PeerRecord, 'address' | 'token'>,
176
+ message: Omit<NoticeRequest, 'protocol' | 'op' | 'token'>,
177
+ ): Promise<PeerClientResult<NoticeResponse>> {
178
+ const request: NoticeRequest = {
179
+ protocol: PEER_PROTOCOL_VERSION,
180
+ op: 'notice',
181
+ token: record.token,
182
+ ...message,
183
+ }
184
+ return sendPeerRequest(
185
+ record.address,
186
+ request,
187
+ (value) => NoticeResponseSchema.parse(value),
188
+ this.timeoutMs,
189
+ )
190
+ }
191
+ }
192
+
193
+ /** A bare liveness probe: `true` iff an unauthenticated `ping` answers within `timeoutMs`. Used by `listLivePeers`. */
194
+ export function pingPeer(address: string, timeoutMs = DEFAULT_TIMEOUT_MS): Promise<boolean> {
195
+ const request: PingRequest = { protocol: PEER_PROTOCOL_VERSION, op: 'ping' }
196
+ return sendPeerRequest(
197
+ address,
198
+ request,
199
+ (value) => PingResponseSchema.parse(value),
200
+ timeoutMs,
201
+ ).then((result) => result.kind === 'responded')
202
+ }