@namzu/sdk 49.0.0 → 50.0.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 (737) hide show
  1. package/CHANGELOG.md +507 -0
  2. package/README.md +137 -125
  3. package/dist/agents/QueryAgent.d.ts.map +1 -1
  4. package/dist/agents/QueryAgent.js +1 -0
  5. package/dist/agents/QueryAgent.js.map +1 -1
  6. package/dist/agents/examples/SupervisorAgent.d.ts.map +1 -1
  7. package/dist/agents/examples/SupervisorAgent.js +1 -0
  8. package/dist/agents/examples/SupervisorAgent.js.map +1 -1
  9. package/dist/agents/runAgent.d.ts +2 -0
  10. package/dist/agents/runAgent.d.ts.map +1 -1
  11. package/dist/agents/runAgent.js +1 -0
  12. package/dist/agents/runAgent.js.map +1 -1
  13. package/dist/authorization/shell-lexer.d.ts.map +1 -1
  14. package/dist/authorization/shell-lexer.js +16 -1
  15. package/dist/authorization/shell-lexer.js.map +1 -1
  16. package/dist/bridge/acp/permission.d.ts +8 -2
  17. package/dist/bridge/acp/permission.d.ts.map +1 -1
  18. package/dist/bridge/acp/permission.js +1 -0
  19. package/dist/bridge/acp/permission.js.map +1 -1
  20. package/dist/bridge/acp/server.d.ts +25 -1
  21. package/dist/bridge/acp/server.d.ts.map +1 -1
  22. package/dist/bridge/acp/server.js +205 -21
  23. package/dist/bridge/acp/server.js.map +1 -1
  24. package/dist/bridge/acp/tasks.d.ts +5 -0
  25. package/dist/bridge/acp/tasks.d.ts.map +1 -0
  26. package/dist/bridge/acp/tasks.js +19 -0
  27. package/dist/bridge/acp/tasks.js.map +1 -0
  28. package/dist/bridge/acp/update.d.ts.map +1 -1
  29. package/dist/bridge/acp/update.js +148 -13
  30. package/dist/bridge/acp/update.js.map +1 -1
  31. package/dist/config/runtime.d.ts +31 -31
  32. package/dist/connector/mcp/adapter.d.ts.map +1 -1
  33. package/dist/connector/mcp/adapter.js +11 -4
  34. package/dist/connector/mcp/adapter.js.map +1 -1
  35. package/dist/connector/mcp/client.d.ts.map +1 -1
  36. package/dist/connector/mcp/client.js +6 -3
  37. package/dist/connector/mcp/client.js.map +1 -1
  38. package/dist/constants/acp/index.d.ts +3 -0
  39. package/dist/constants/acp/index.d.ts.map +1 -1
  40. package/dist/constants/acp/index.js +3 -0
  41. package/dist/constants/acp/index.js.map +1 -1
  42. package/dist/contracts/a2a.d.ts +80 -80
  43. package/dist/contracts/schemas.d.ts +2 -2
  44. package/dist/contracts/session/schemas.d.ts +10 -10
  45. package/dist/manager/agent/lifecycle.d.ts +11 -0
  46. package/dist/manager/agent/lifecycle.d.ts.map +1 -1
  47. package/dist/manager/agent/lifecycle.js +178 -3
  48. package/dist/manager/agent/lifecycle.js.map +1 -1
  49. package/dist/manager/plan/lifecycle.d.ts +7 -8
  50. package/dist/manager/plan/lifecycle.d.ts.map +1 -1
  51. package/dist/manager/plan/lifecycle.js +7 -8
  52. package/dist/manager/plan/lifecycle.js.map +1 -1
  53. package/dist/manager/resident/consumption.d.ts +8 -8
  54. package/dist/manager/resident/learning-cycle.d.ts +2 -2
  55. package/dist/manager/resident/learning-observation.d.ts +12 -12
  56. package/dist/manager/resident/learning.d.ts +82 -82
  57. package/dist/manager/resident/outbox.d.ts +8 -8
  58. package/dist/manager/resident/proposal.d.ts +2 -2
  59. package/dist/manager/resident/store.d.ts +10 -10
  60. package/dist/manager/session/attribution.d.ts +1 -0
  61. package/dist/manager/session/attribution.d.ts.map +1 -1
  62. package/dist/manager/session/attribution.js +9 -1
  63. package/dist/manager/session/attribution.js.map +1 -1
  64. package/dist/manager/session/streamed-message-identity.d.ts +6 -0
  65. package/dist/manager/session/streamed-message-identity.d.ts.map +1 -0
  66. package/dist/manager/session/streamed-message-identity.js +14 -0
  67. package/dist/manager/session/streamed-message-identity.js.map +1 -0
  68. package/dist/manager/session/turn-recorder.d.ts.map +1 -1
  69. package/dist/manager/session/turn-recorder.js +4 -3
  70. package/dist/manager/session/turn-recorder.js.map +1 -1
  71. package/dist/pals/activity/causality.d.ts +23 -0
  72. package/dist/pals/activity/causality.d.ts.map +1 -0
  73. package/dist/pals/activity/causality.js +205 -0
  74. package/dist/pals/activity/causality.js.map +1 -0
  75. package/dist/pals/activity/projection.d.ts +5 -0
  76. package/dist/pals/activity/projection.d.ts.map +1 -0
  77. package/dist/pals/activity/projection.js +79 -0
  78. package/dist/pals/activity/projection.js.map +1 -0
  79. package/dist/pals/activity/source.d.ts +16 -0
  80. package/dist/pals/activity/source.d.ts.map +1 -0
  81. package/dist/pals/activity/source.js +235 -0
  82. package/dist/pals/activity/source.js.map +1 -0
  83. package/dist/pals/activity/subscription-policy.d.ts +38 -0
  84. package/dist/pals/activity/subscription-policy.d.ts.map +1 -0
  85. package/dist/pals/activity/subscription-policy.js +183 -0
  86. package/dist/pals/activity/subscription-policy.js.map +1 -0
  87. package/dist/pals/activity/subscription-schema.d.ts +353 -0
  88. package/dist/pals/activity/subscription-schema.d.ts.map +1 -0
  89. package/dist/pals/activity/subscription-schema.js +24 -0
  90. package/dist/pals/activity/subscription-schema.js.map +1 -0
  91. package/dist/pals/activity/subscription-store.d.ts +25 -0
  92. package/dist/pals/activity/subscription-store.d.ts.map +1 -0
  93. package/dist/pals/activity/subscription-store.js +152 -0
  94. package/dist/pals/activity/subscription-store.js.map +1 -0
  95. package/dist/pals/activity/subscription-types.d.ts +42 -0
  96. package/dist/pals/activity/subscription-types.d.ts.map +1 -0
  97. package/dist/pals/activity/subscription-types.js +2 -0
  98. package/dist/pals/activity/subscription-types.js.map +1 -0
  99. package/dist/pals/activity/subscriptions.d.ts +32 -0
  100. package/dist/pals/activity/subscriptions.d.ts.map +1 -0
  101. package/dist/pals/activity/subscriptions.js +151 -0
  102. package/dist/pals/activity/subscriptions.js.map +1 -0
  103. package/dist/pals/activity/types.d.ts +77 -0
  104. package/dist/pals/activity/types.d.ts.map +1 -0
  105. package/dist/pals/activity/types.js +2 -0
  106. package/dist/pals/activity/types.js.map +1 -0
  107. package/dist/pals/channels/ingress.d.ts +9 -0
  108. package/dist/pals/channels/ingress.d.ts.map +1 -0
  109. package/dist/pals/channels/ingress.js +131 -0
  110. package/dist/pals/channels/ingress.js.map +1 -0
  111. package/dist/pals/channels/routes.d.ts +20 -0
  112. package/dist/pals/channels/routes.d.ts.map +1 -0
  113. package/dist/pals/channels/routes.js +111 -0
  114. package/dist/pals/channels/routes.js.map +1 -0
  115. package/dist/pals/channels/routing.d.ts +37 -0
  116. package/dist/pals/channels/routing.d.ts.map +1 -0
  117. package/dist/pals/channels/routing.js +150 -0
  118. package/dist/pals/channels/routing.js.map +1 -0
  119. package/dist/pals/channels/schema.d.ts +234 -0
  120. package/dist/pals/channels/schema.d.ts.map +1 -0
  121. package/dist/pals/channels/schema.js +94 -0
  122. package/dist/pals/channels/schema.js.map +1 -0
  123. package/dist/pals/channels/types.d.ts +115 -0
  124. package/dist/pals/channels/types.d.ts.map +1 -0
  125. package/dist/pals/channels/types.js +2 -0
  126. package/dist/pals/channels/types.js.map +1 -0
  127. package/dist/pals/communication/broker.d.ts +8 -0
  128. package/dist/pals/communication/broker.d.ts.map +1 -0
  129. package/dist/pals/communication/broker.js +121 -0
  130. package/dist/pals/communication/broker.js.map +1 -0
  131. package/dist/pals/communication/dispatch.d.ts +4 -0
  132. package/dist/pals/communication/dispatch.d.ts.map +1 -0
  133. package/dist/pals/communication/dispatch.js +57 -0
  134. package/dist/pals/communication/dispatch.js.map +1 -0
  135. package/dist/pals/communication/inbound.d.ts +9 -0
  136. package/dist/pals/communication/inbound.d.ts.map +1 -0
  137. package/dist/pals/communication/inbound.js +155 -0
  138. package/dist/pals/communication/inbound.js.map +1 -0
  139. package/dist/pals/communication/ingress-dispatch.d.ts +5 -0
  140. package/dist/pals/communication/ingress-dispatch.d.ts.map +1 -0
  141. package/dist/pals/communication/ingress-dispatch.js +51 -0
  142. package/dist/pals/communication/ingress-dispatch.js.map +1 -0
  143. package/dist/pals/communication/ingress-inbound.d.ts +9 -0
  144. package/dist/pals/communication/ingress-inbound.d.ts.map +1 -0
  145. package/dist/pals/communication/ingress-inbound.js +222 -0
  146. package/dist/pals/communication/ingress-inbound.js.map +1 -0
  147. package/dist/pals/communication/ingress-schema.d.ts +7829 -0
  148. package/dist/pals/communication/ingress-schema.d.ts.map +1 -0
  149. package/dist/pals/communication/ingress-schema.js +479 -0
  150. package/dist/pals/communication/ingress-schema.js.map +1 -0
  151. package/dist/pals/communication/ingress-types.d.ts +187 -0
  152. package/dist/pals/communication/ingress-types.d.ts.map +1 -0
  153. package/dist/pals/communication/ingress-types.js +73 -0
  154. package/dist/pals/communication/ingress-types.js.map +1 -0
  155. package/dist/pals/communication/operator.d.ts +75 -0
  156. package/dist/pals/communication/operator.d.ts.map +1 -0
  157. package/dist/pals/communication/operator.js +217 -0
  158. package/dist/pals/communication/operator.js.map +1 -0
  159. package/dist/pals/communication/policy.d.ts +41 -0
  160. package/dist/pals/communication/policy.d.ts.map +1 -0
  161. package/dist/pals/communication/policy.js +138 -0
  162. package/dist/pals/communication/policy.js.map +1 -0
  163. package/dist/pals/communication/schema.d.ts +2000 -0
  164. package/dist/pals/communication/schema.d.ts.map +1 -0
  165. package/dist/pals/communication/schema.js +170 -0
  166. package/dist/pals/communication/schema.js.map +1 -0
  167. package/dist/pals/communication/store.d.ts +61 -0
  168. package/dist/pals/communication/store.d.ts.map +1 -0
  169. package/dist/pals/communication/store.js +450 -0
  170. package/dist/pals/communication/store.js.map +1 -0
  171. package/dist/pals/communication/tools.d.ts +23 -0
  172. package/dist/pals/communication/tools.d.ts.map +1 -0
  173. package/dist/pals/communication/tools.js +107 -0
  174. package/dist/pals/communication/tools.js.map +1 -0
  175. package/dist/pals/communication/types.d.ts +168 -0
  176. package/dist/pals/communication/types.d.ts.map +1 -0
  177. package/dist/pals/communication/types.js +24 -0
  178. package/dist/pals/communication/types.js.map +1 -0
  179. package/dist/pals/communication/verify.d.ts +22 -0
  180. package/dist/pals/communication/verify.d.ts.map +1 -0
  181. package/dist/pals/communication/verify.js +142 -0
  182. package/dist/pals/communication/verify.js.map +1 -0
  183. package/dist/pals/lifecycle.d.ts +37 -0
  184. package/dist/pals/lifecycle.d.ts.map +1 -0
  185. package/dist/pals/lifecycle.js +22 -0
  186. package/dist/pals/lifecycle.js.map +1 -0
  187. package/dist/pals/prompt.d.ts +30 -0
  188. package/dist/pals/prompt.d.ts.map +1 -0
  189. package/dist/pals/prompt.js +65 -0
  190. package/dist/pals/prompt.js.map +1 -0
  191. package/dist/pals/reference-images.d.ts +44 -0
  192. package/dist/pals/reference-images.d.ts.map +1 -0
  193. package/dist/pals/reference-images.js +248 -0
  194. package/dist/pals/reference-images.js.map +1 -0
  195. package/dist/pals/runtime.d.ts +46 -0
  196. package/dist/pals/runtime.d.ts.map +1 -0
  197. package/dist/pals/runtime.js +624 -0
  198. package/dist/pals/runtime.js.map +1 -0
  199. package/dist/pals/store.d.ts +26 -0
  200. package/dist/pals/store.d.ts.map +1 -0
  201. package/dist/pals/store.js +334 -0
  202. package/dist/pals/store.js.map +1 -0
  203. package/dist/pals/types.d.ts +145 -0
  204. package/dist/pals/types.d.ts.map +1 -0
  205. package/dist/pals/types.js +2 -0
  206. package/dist/pals/types.js.map +1 -0
  207. package/dist/peers/envelope.js +1 -1
  208. package/dist/peers/envelope.js.map +1 -1
  209. package/dist/peers/protocol.d.ts +83 -83
  210. package/dist/peers/record.d.ts +10 -10
  211. package/dist/plugin/shell-hook.d.ts.map +1 -1
  212. package/dist/plugin/shell-hook.js +7 -2
  213. package/dist/plugin/shell-hook.js.map +1 -1
  214. package/dist/process/kill-tree.d.ts.map +1 -1
  215. package/dist/process/kill-tree.js +9 -1
  216. package/dist/process/kill-tree.js.map +1 -1
  217. package/dist/provider/errors.d.ts +19 -0
  218. package/dist/provider/errors.d.ts.map +1 -1
  219. package/dist/provider/errors.js +123 -2
  220. package/dist/provider/errors.js.map +1 -1
  221. package/dist/public-runtime.d.ts +41 -13
  222. package/dist/public-runtime.d.ts.map +1 -1
  223. package/dist/public-runtime.js +35 -7
  224. package/dist/public-runtime.js.map +1 -1
  225. package/dist/public-tools.d.ts +8 -3
  226. package/dist/public-tools.d.ts.map +1 -1
  227. package/dist/public-tools.js +8 -3
  228. package/dist/public-tools.js.map +1 -1
  229. package/dist/public-types.d.ts +27 -7
  230. package/dist/public-types.d.ts.map +1 -1
  231. package/dist/registry/tool/presentation.d.ts +1 -0
  232. package/dist/registry/tool/presentation.d.ts.map +1 -1
  233. package/dist/registry/tool/presentation.js +9 -7
  234. package/dist/registry/tool/presentation.js.map +1 -1
  235. package/dist/runtime/harness-session/index.d.ts +5 -0
  236. package/dist/runtime/harness-session/index.d.ts.map +1 -0
  237. package/dist/runtime/harness-session/index.js +928 -0
  238. package/dist/runtime/harness-session/index.js.map +1 -0
  239. package/dist/runtime/harness-session/journal.d.ts +37 -0
  240. package/dist/runtime/harness-session/journal.d.ts.map +1 -0
  241. package/dist/runtime/harness-session/journal.js +177 -0
  242. package/dist/runtime/harness-session/journal.js.map +1 -0
  243. package/dist/runtime/harness-session/saved-view.d.ts +8 -0
  244. package/dist/runtime/harness-session/saved-view.d.ts.map +1 -0
  245. package/dist/runtime/harness-session/saved-view.js +112 -0
  246. package/dist/runtime/harness-session/saved-view.js.map +1 -0
  247. package/dist/runtime/jobs/awaited-jobs.d.ts +2 -1
  248. package/dist/runtime/jobs/awaited-jobs.d.ts.map +1 -1
  249. package/dist/runtime/jobs/awaited-jobs.js +2 -1
  250. package/dist/runtime/jobs/awaited-jobs.js.map +1 -1
  251. package/dist/runtime/jobs/registry.d.ts +56 -1
  252. package/dist/runtime/jobs/registry.d.ts.map +1 -1
  253. package/dist/runtime/jobs/registry.js +351 -34
  254. package/dist/runtime/jobs/registry.js.map +1 -1
  255. package/dist/runtime/query/abandon-turn.d.ts +12 -1
  256. package/dist/runtime/query/abandon-turn.d.ts.map +1 -1
  257. package/dist/runtime/query/abandon-turn.js +3 -1
  258. package/dist/runtime/query/abandon-turn.js.map +1 -1
  259. package/dist/runtime/query/checkpoint.d.ts +4 -0
  260. package/dist/runtime/query/checkpoint.d.ts.map +1 -1
  261. package/dist/runtime/query/checkpoint.js +10 -0
  262. package/dist/runtime/query/checkpoint.js.map +1 -1
  263. package/dist/runtime/query/durable-inbound.d.ts +5 -0
  264. package/dist/runtime/query/durable-inbound.d.ts.map +1 -0
  265. package/dist/runtime/query/durable-inbound.js +89 -0
  266. package/dist/runtime/query/durable-inbound.js.map +1 -0
  267. package/dist/runtime/query/events.d.ts +4 -0
  268. package/dist/runtime/query/events.d.ts.map +1 -1
  269. package/dist/runtime/query/events.js +22 -5
  270. package/dist/runtime/query/events.js.map +1 -1
  271. package/dist/runtime/query/executor/tool-call-admission.d.ts +5 -1
  272. package/dist/runtime/query/executor/tool-call-admission.d.ts.map +1 -1
  273. package/dist/runtime/query/executor/tool-call-admission.js +85 -13
  274. package/dist/runtime/query/executor/tool-call-admission.js.map +1 -1
  275. package/dist/runtime/query/executor.d.ts +41 -18
  276. package/dist/runtime/query/executor.d.ts.map +1 -1
  277. package/dist/runtime/query/executor.js +227 -114
  278. package/dist/runtime/query/executor.js.map +1 -1
  279. package/dist/runtime/query/index.d.ts +3 -0
  280. package/dist/runtime/query/index.d.ts.map +1 -1
  281. package/dist/runtime/query/index.js +21 -4
  282. package/dist/runtime/query/index.js.map +1 -1
  283. package/dist/runtime/query/iteration/index.d.ts +18 -6
  284. package/dist/runtime/query/iteration/index.d.ts.map +1 -1
  285. package/dist/runtime/query/iteration/index.js +144 -67
  286. package/dist/runtime/query/iteration/index.js.map +1 -1
  287. package/dist/runtime/query/iteration/outstanding-work.d.ts +9 -5
  288. package/dist/runtime/query/iteration/outstanding-work.d.ts.map +1 -1
  289. package/dist/runtime/query/iteration/outstanding-work.js +61 -6
  290. package/dist/runtime/query/iteration/outstanding-work.js.map +1 -1
  291. package/dist/runtime/query/iteration/phases/context.d.ts +4 -0
  292. package/dist/runtime/query/iteration/phases/context.d.ts.map +1 -1
  293. package/dist/runtime/query/iteration/phases/context.js.map +1 -1
  294. package/dist/runtime/query/iteration/phases/tool-review.d.ts.map +1 -1
  295. package/dist/runtime/query/iteration/phases/tool-review.js +99 -16
  296. package/dist/runtime/query/iteration/phases/tool-review.js.map +1 -1
  297. package/dist/runtime/query/observation-context.d.ts +2 -2
  298. package/dist/runtime/query/observation-context.d.ts.map +1 -1
  299. package/dist/runtime/query/observation-context.js +20 -13
  300. package/dist/runtime/query/observation-context.js.map +1 -1
  301. package/dist/runtime/query/prepare-turn.js +2 -2
  302. package/dist/runtime/query/prepare-turn.js.map +1 -1
  303. package/dist/runtime/query/prompt-cache.d.ts +1 -0
  304. package/dist/runtime/query/prompt-cache.d.ts.map +1 -1
  305. package/dist/runtime/query/prompt-cache.js +2 -0
  306. package/dist/runtime/query/prompt-cache.js.map +1 -1
  307. package/dist/runtime/query/prompt.d.ts +2 -0
  308. package/dist/runtime/query/prompt.d.ts.map +1 -1
  309. package/dist/runtime/query/prompt.js +23 -1
  310. package/dist/runtime/query/prompt.js.map +1 -1
  311. package/dist/runtime/query/repeat-call.d.ts +12 -3
  312. package/dist/runtime/query/repeat-call.d.ts.map +1 -1
  313. package/dist/runtime/query/repeat-call.js +33 -10
  314. package/dist/runtime/query/repeat-call.js.map +1 -1
  315. package/dist/runtime/query/resume-pending.d.ts +5 -6
  316. package/dist/runtime/query/resume-pending.d.ts.map +1 -1
  317. package/dist/runtime/query/resume-pending.js +30 -3
  318. package/dist/runtime/query/resume-pending.js.map +1 -1
  319. package/dist/runtime/query/resume-session.js +1 -1
  320. package/dist/runtime/query/resume-session.js.map +1 -1
  321. package/dist/runtime/query/review-policy.d.ts +8 -1
  322. package/dist/runtime/query/review-policy.d.ts.map +1 -1
  323. package/dist/runtime/query/review-policy.js +6 -0
  324. package/dist/runtime/query/review-policy.js.map +1 -1
  325. package/dist/runtime/query/saved-presentation.d.ts +13 -0
  326. package/dist/runtime/query/saved-presentation.d.ts.map +1 -0
  327. package/dist/runtime/query/saved-presentation.js +63 -0
  328. package/dist/runtime/query/saved-presentation.js.map +1 -0
  329. package/dist/runtime/query/steering.d.ts +6 -9
  330. package/dist/runtime/query/steering.d.ts.map +1 -1
  331. package/dist/runtime/query/steering.js.map +1 -1
  332. package/dist/runtime/query/tool-executions.d.ts +7 -3
  333. package/dist/runtime/query/tool-executions.d.ts.map +1 -1
  334. package/dist/runtime/query/tool-executions.js +89 -9
  335. package/dist/runtime/query/tool-executions.js.map +1 -1
  336. package/dist/runtime/query/tooling.d.ts +3 -1
  337. package/dist/runtime/query/tooling.d.ts.map +1 -1
  338. package/dist/runtime/query/tooling.js +3 -0
  339. package/dist/runtime/query/tooling.js.map +1 -1
  340. package/dist/scheduler/completion-inbox.d.ts +25 -1
  341. package/dist/scheduler/completion-inbox.d.ts.map +1 -1
  342. package/dist/scheduler/completion-inbox.js +102 -8
  343. package/dist/scheduler/completion-inbox.js.map +1 -1
  344. package/dist/scheduler/delegating.d.ts.map +1 -1
  345. package/dist/scheduler/delegating.js +5 -0
  346. package/dist/scheduler/delegating.js.map +1 -1
  347. package/dist/scheduler/local.d.ts.map +1 -1
  348. package/dist/scheduler/local.js +2 -0
  349. package/dist/scheduler/local.js.map +1 -1
  350. package/dist/session/summary/materialize.d.ts +10 -6
  351. package/dist/session/summary/materialize.d.ts.map +1 -1
  352. package/dist/session/summary/materialize.js +41 -8
  353. package/dist/session/summary/materialize.js.map +1 -1
  354. package/dist/store/budget/ledger.d.ts +9 -0
  355. package/dist/store/budget/ledger.d.ts.map +1 -1
  356. package/dist/store/budget/ledger.js +58 -6
  357. package/dist/store/budget/ledger.js.map +1 -1
  358. package/dist/store/evidence/index-page.d.ts +12 -12
  359. package/dist/store/evidence/source-text.d.ts +4 -4
  360. package/dist/store/session/disk.d.ts +9 -4
  361. package/dist/store/session/disk.d.ts.map +1 -1
  362. package/dist/store/session/disk.js +57 -11
  363. package/dist/store/session/disk.js.map +1 -1
  364. package/dist/store/session/memory.d.ts +5 -3
  365. package/dist/store/session/memory.d.ts.map +1 -1
  366. package/dist/store/session/memory.js +24 -7
  367. package/dist/store/session/memory.js.map +1 -1
  368. package/dist/store/session-log/core.d.ts +26 -6
  369. package/dist/store/session-log/core.d.ts.map +1 -1
  370. package/dist/store/session-log/core.js +61 -8
  371. package/dist/store/session-log/core.js.map +1 -1
  372. package/dist/store/session-log/disk.d.ts +2 -2
  373. package/dist/store/session-log/disk.d.ts.map +1 -1
  374. package/dist/store/session-log/disk.js +1 -0
  375. package/dist/store/session-log/disk.js.map +1 -1
  376. package/dist/store/session-log/fold.d.ts +7 -0
  377. package/dist/store/session-log/fold.d.ts.map +1 -1
  378. package/dist/store/session-log/fold.js +21 -0
  379. package/dist/store/session-log/fold.js.map +1 -1
  380. package/dist/store/session-log/index.d.ts +5 -3
  381. package/dist/store/session-log/index.d.ts.map +1 -1
  382. package/dist/store/session-log/index.js +3 -1
  383. package/dist/store/session-log/index.js.map +1 -1
  384. package/dist/store/session-log/memory.d.ts +1 -1
  385. package/dist/store/session-log/memory.d.ts.map +1 -1
  386. package/dist/store/session-log/memory.js +1 -0
  387. package/dist/store/session-log/memory.js.map +1 -1
  388. package/dist/store/session-log/spill.d.ts +10 -3
  389. package/dist/store/session-log/spill.d.ts.map +1 -1
  390. package/dist/store/session-log/spill.js +70 -5
  391. package/dist/store/session-log/spill.js.map +1 -1
  392. package/dist/store/session-log/structured-result.d.ts +21 -0
  393. package/dist/store/session-log/structured-result.d.ts.map +1 -0
  394. package/dist/store/session-log/structured-result.js +67 -0
  395. package/dist/store/session-log/structured-result.js.map +1 -0
  396. package/dist/store/task/disk.d.ts +11 -0
  397. package/dist/store/task/disk.d.ts.map +1 -1
  398. package/dist/store/task/disk.js +41 -2
  399. package/dist/store/task/disk.js.map +1 -1
  400. package/dist/store/task/memory.d.ts.map +1 -1
  401. package/dist/store/task/memory.js +15 -3
  402. package/dist/store/task/memory.js.map +1 -1
  403. package/dist/tools/admit-facts.d.ts +13 -0
  404. package/dist/tools/admit-facts.d.ts.map +1 -0
  405. package/dist/tools/admit-facts.js +142 -0
  406. package/dist/tools/admit-facts.js.map +1 -0
  407. package/dist/tools/builtins/bash.d.ts +4 -1
  408. package/dist/tools/builtins/bash.d.ts.map +1 -1
  409. package/dist/tools/builtins/bash.js +108 -22
  410. package/dist/tools/builtins/bash.js.map +1 -1
  411. package/dist/tools/builtins/browser.d.ts +10 -10
  412. package/dist/tools/builtins/computer-use.d.ts +90 -90
  413. package/dist/tools/builtins/edit.d.ts +17 -0
  414. package/dist/tools/builtins/edit.d.ts.map +1 -1
  415. package/dist/tools/builtins/edit.js +34 -0
  416. package/dist/tools/builtins/edit.js.map +1 -1
  417. package/dist/tools/builtins/file-write-result.d.ts.map +1 -1
  418. package/dist/tools/builtins/file-write-result.js +13 -0
  419. package/dist/tools/builtins/file-write-result.js.map +1 -1
  420. package/dist/tools/builtins/glob.d.ts.map +1 -1
  421. package/dist/tools/builtins/glob.js +12 -0
  422. package/dist/tools/builtins/glob.js.map +1 -1
  423. package/dist/tools/builtins/grep.d.ts.map +1 -1
  424. package/dist/tools/builtins/grep.js +14 -0
  425. package/dist/tools/builtins/grep.js.map +1 -1
  426. package/dist/tools/builtins/index.d.ts +2 -0
  427. package/dist/tools/builtins/index.d.ts.map +1 -1
  428. package/dist/tools/builtins/index.js +1 -0
  429. package/dist/tools/builtins/index.js.map +1 -1
  430. package/dist/tools/builtins/job.d.ts.map +1 -1
  431. package/dist/tools/builtins/job.js +4 -1
  432. package/dist/tools/builtins/job.js.map +1 -1
  433. package/dist/tools/builtins/lsp.d.ts +2 -2
  434. package/dist/tools/builtins/read-file.d.ts.map +1 -1
  435. package/dist/tools/builtins/read-file.js +49 -0
  436. package/dist/tools/builtins/read-file.js.map +1 -1
  437. package/dist/tools/builtins/view-image.d.ts +24 -0
  438. package/dist/tools/builtins/view-image.d.ts.map +1 -0
  439. package/dist/tools/builtins/view-image.js +385 -0
  440. package/dist/tools/builtins/view-image.js.map +1 -0
  441. package/dist/tools/builtins/wait-for-job-bounds.d.ts +2 -0
  442. package/dist/tools/builtins/wait-for-job-bounds.d.ts.map +1 -1
  443. package/dist/tools/builtins/wait-for-job-bounds.js +1 -0
  444. package/dist/tools/builtins/wait-for-job-bounds.js.map +1 -1
  445. package/dist/tools/builtins/wait-for-job.d.ts +2 -0
  446. package/dist/tools/builtins/wait-for-job.d.ts.map +1 -1
  447. package/dist/tools/builtins/wait-for-job.js +104 -6
  448. package/dist/tools/builtins/wait-for-job.js.map +1 -1
  449. package/dist/tools/builtins/write-file.d.ts.map +1 -1
  450. package/dist/tools/builtins/write-file.js +1 -0
  451. package/dist/tools/builtins/write-file.js.map +1 -1
  452. package/dist/tools/command-shell.d.ts +37 -2
  453. package/dist/tools/command-shell.d.ts.map +1 -1
  454. package/dist/tools/command-shell.js +100 -3
  455. package/dist/tools/command-shell.js.map +1 -1
  456. package/dist/tools/coordinator/agent.d.ts +9 -19
  457. package/dist/tools/coordinator/agent.d.ts.map +1 -1
  458. package/dist/tools/coordinator/agent.js.map +1 -1
  459. package/dist/tools/coordinator/index.d.ts.map +1 -1
  460. package/dist/tools/coordinator/index.js +127 -67
  461. package/dist/tools/coordinator/index.js.map +1 -1
  462. package/dist/tools/coordinator/wait-with-idle-bound.d.ts +2 -0
  463. package/dist/tools/coordinator/wait-with-idle-bound.d.ts.map +1 -1
  464. package/dist/tools/coordinator/wait-with-idle-bound.js +1 -1
  465. package/dist/tools/coordinator/wait-with-idle-bound.js.map +1 -1
  466. package/dist/tools/defineTool.d.ts.map +1 -1
  467. package/dist/tools/defineTool.js +4 -0
  468. package/dist/tools/defineTool.js.map +1 -1
  469. package/dist/tools/failure-facts.d.ts +8 -0
  470. package/dist/tools/failure-facts.d.ts.map +1 -0
  471. package/dist/tools/failure-facts.js +24 -0
  472. package/dist/tools/failure-facts.js.map +1 -0
  473. package/dist/tools/host-output.d.ts +24 -0
  474. package/dist/tools/host-output.d.ts.map +1 -0
  475. package/dist/tools/host-output.js +117 -0
  476. package/dist/tools/host-output.js.map +1 -0
  477. package/dist/tools/oem-code-pages.d.ts +8 -0
  478. package/dist/tools/oem-code-pages.d.ts.map +1 -0
  479. package/dist/tools/oem-code-pages.js +23 -0
  480. package/dist/tools/oem-code-pages.js.map +1 -0
  481. package/dist/tools/schedules/schedule-tool.d.ts.map +1 -1
  482. package/dist/tools/schedules/schedule-tool.js +35 -6
  483. package/dist/tools/schedules/schedule-tool.js.map +1 -1
  484. package/dist/tools/schedules/types.d.ts +23 -3
  485. package/dist/tools/schedules/types.d.ts.map +1 -1
  486. package/dist/tools/task/list.d.ts.map +1 -1
  487. package/dist/tools/task/list.js +14 -6
  488. package/dist/tools/task/list.js.map +1 -1
  489. package/dist/tools/task/present.d.ts.map +1 -1
  490. package/dist/tools/task/present.js +26 -6
  491. package/dist/tools/task/present.js.map +1 -1
  492. package/dist/tools/task/update.d.ts.map +1 -1
  493. package/dist/tools/task/update.js +12 -5
  494. package/dist/tools/task/update.js.map +1 -1
  495. package/dist/tools/text-window.d.ts +19 -0
  496. package/dist/tools/text-window.d.ts.map +1 -0
  497. package/dist/tools/text-window.js +83 -0
  498. package/dist/tools/text-window.js.map +1 -0
  499. package/dist/toolsets/manager.d.ts +11 -0
  500. package/dist/toolsets/manager.d.ts.map +1 -1
  501. package/dist/toolsets/manager.js +45 -1
  502. package/dist/toolsets/manager.js.map +1 -1
  503. package/dist/types/acp/index.d.ts +137 -1
  504. package/dist/types/acp/index.d.ts.map +1 -1
  505. package/dist/types/agent/base.d.ts +3 -0
  506. package/dist/types/agent/base.d.ts.map +1 -1
  507. package/dist/types/agent/manager.d.ts +8 -23
  508. package/dist/types/agent/manager.d.ts.map +1 -1
  509. package/dist/types/agent/scheduler.d.ts +10 -1
  510. package/dist/types/agent/scheduler.d.ts.map +1 -1
  511. package/dist/types/agent/task.d.ts +4 -0
  512. package/dist/types/agent/task.d.ts.map +1 -1
  513. package/dist/types/authorization/index.d.ts +30 -30
  514. package/dist/types/connector/mcp.d.ts +7 -0
  515. package/dist/types/connector/mcp.d.ts.map +1 -1
  516. package/dist/types/errors/catalog.d.ts.map +1 -1
  517. package/dist/types/errors/catalog.js +4 -2
  518. package/dist/types/errors/catalog.js.map +1 -1
  519. package/dist/types/harness/schema.d.ts +354 -0
  520. package/dist/types/harness/schema.d.ts.map +1 -0
  521. package/dist/types/harness/schema.js +203 -0
  522. package/dist/types/harness/schema.js.map +1 -0
  523. package/dist/types/harness/session.d.ts +278 -0
  524. package/dist/types/harness/session.d.ts.map +1 -0
  525. package/dist/types/harness/session.js +2 -0
  526. package/dist/types/harness/session.js.map +1 -0
  527. package/dist/types/hitl/index.d.ts +12 -0
  528. package/dist/types/hitl/index.d.ts.map +1 -1
  529. package/dist/types/hitl/index.js.map +1 -1
  530. package/dist/types/job/index.d.ts +47 -0
  531. package/dist/types/job/index.d.ts.map +1 -0
  532. package/dist/types/job/index.js +2 -0
  533. package/dist/types/job/index.js.map +1 -0
  534. package/dist/types/message/inbound-delivery.d.ts +44 -0
  535. package/dist/types/message/inbound-delivery.d.ts.map +1 -0
  536. package/dist/types/message/inbound-delivery.js +14 -0
  537. package/dist/types/message/inbound-delivery.js.map +1 -0
  538. package/dist/types/message/index.d.ts +4 -1
  539. package/dist/types/message/index.d.ts.map +1 -1
  540. package/dist/types/message/index.js +5 -1
  541. package/dist/types/message/index.js.map +1 -1
  542. package/dist/types/plugin/index.d.ts +6 -6
  543. package/dist/types/sandbox/index.d.ts +39 -2
  544. package/dist/types/sandbox/index.d.ts.map +1 -1
  545. package/dist/types/sandbox/index.js.map +1 -1
  546. package/dist/types/session/checkpoint.d.ts +24 -17
  547. package/dist/types/session/checkpoint.d.ts.map +1 -1
  548. package/dist/types/session/checkpoint.js +1 -0
  549. package/dist/types/session/checkpoint.js.map +1 -1
  550. package/dist/types/session/events.d.ts +23 -1
  551. package/dist/types/session/events.d.ts.map +1 -1
  552. package/dist/types/session/events.js.map +1 -1
  553. package/dist/types/session/records.d.ts +1514 -565
  554. package/dist/types/session/records.d.ts.map +1 -1
  555. package/dist/types/session/records.js +89 -1
  556. package/dist/types/session/records.js.map +1 -1
  557. package/dist/types/session/step.d.ts +2 -0
  558. package/dist/types/session/step.d.ts.map +1 -1
  559. package/dist/types/session/step.js.map +1 -1
  560. package/dist/types/session/store.d.ts +19 -10
  561. package/dist/types/session/store.d.ts.map +1 -1
  562. package/dist/types/session/tool-execution.d.ts +6 -0
  563. package/dist/types/session/tool-execution.d.ts.map +1 -1
  564. package/dist/types/structured-output/index.d.ts +12 -2
  565. package/dist/types/structured-output/index.d.ts.map +1 -1
  566. package/dist/types/summary/ref.d.ts +3 -1
  567. package/dist/types/summary/ref.d.ts.map +1 -1
  568. package/dist/types/tool/index.d.ts +32 -4
  569. package/dist/types/tool/index.d.ts.map +1 -1
  570. package/dist/types/tool/index.js.map +1 -1
  571. package/dist/types/tool/presentation.d.ts +106 -0
  572. package/dist/types/tool/presentation.d.ts.map +1 -1
  573. package/dist/utils/json-snapshot.d.ts +6 -2
  574. package/dist/utils/json-snapshot.d.ts.map +1 -1
  575. package/dist/utils/json-snapshot.js +19 -9
  576. package/dist/utils/json-snapshot.js.map +1 -1
  577. package/dist/utils/structured-result-json.d.ts +5 -0
  578. package/dist/utils/structured-result-json.d.ts.map +1 -0
  579. package/dist/utils/structured-result-json.js +10 -0
  580. package/dist/utils/structured-result-json.js.map +1 -0
  581. package/package.json +1 -1
  582. package/src/agents/QueryAgent.ts +1 -0
  583. package/src/agents/examples/SupervisorAgent.ts +1 -0
  584. package/src/agents/runAgent.ts +3 -0
  585. package/src/authorization/shell-lexer.ts +16 -1
  586. package/src/bridge/acp/permission.ts +17 -3
  587. package/src/bridge/acp/server.ts +271 -25
  588. package/src/bridge/acp/tasks.ts +23 -0
  589. package/src/bridge/acp/update.ts +167 -13
  590. package/src/connector/mcp/adapter.ts +16 -4
  591. package/src/connector/mcp/client.ts +6 -2
  592. package/src/constants/acp/index.ts +4 -0
  593. package/src/manager/agent/lifecycle.ts +230 -3
  594. package/src/manager/plan/lifecycle.ts +11 -9
  595. package/src/manager/session/attribution.ts +12 -2
  596. package/src/manager/session/streamed-message-identity.ts +21 -0
  597. package/src/manager/session/turn-recorder.ts +4 -3
  598. package/src/pals/activity/causality.ts +261 -0
  599. package/src/pals/activity/projection.ts +89 -0
  600. package/src/pals/activity/source.ts +240 -0
  601. package/src/pals/activity/subscription-policy.ts +230 -0
  602. package/src/pals/activity/subscription-schema.ts +27 -0
  603. package/src/pals/activity/subscription-store.ts +172 -0
  604. package/src/pals/activity/subscription-types.ts +48 -0
  605. package/src/pals/activity/subscriptions.ts +209 -0
  606. package/src/pals/activity/types.ts +108 -0
  607. package/src/pals/channels/ingress.ts +153 -0
  608. package/src/pals/channels/routes.ts +118 -0
  609. package/src/pals/channels/routing.ts +197 -0
  610. package/src/pals/channels/schema.ts +108 -0
  611. package/src/pals/channels/types.ts +156 -0
  612. package/src/pals/communication/broker.ts +131 -0
  613. package/src/pals/communication/dispatch.ts +66 -0
  614. package/src/pals/communication/inbound.ts +193 -0
  615. package/src/pals/communication/ingress-dispatch.ts +63 -0
  616. package/src/pals/communication/ingress-inbound.ts +269 -0
  617. package/src/pals/communication/ingress-schema.ts +526 -0
  618. package/src/pals/communication/ingress-types.ts +336 -0
  619. package/src/pals/communication/operator.ts +315 -0
  620. package/src/pals/communication/policy.ts +174 -0
  621. package/src/pals/communication/schema.ts +173 -0
  622. package/src/pals/communication/store.ts +577 -0
  623. package/src/pals/communication/tools.ts +139 -0
  624. package/src/pals/communication/types.ts +227 -0
  625. package/src/pals/communication/verify.ts +220 -0
  626. package/src/pals/lifecycle.ts +54 -0
  627. package/src/pals/prompt.ts +101 -0
  628. package/src/pals/reference-images.ts +322 -0
  629. package/src/pals/runtime.ts +670 -0
  630. package/src/pals/store.ts +369 -0
  631. package/src/pals/types.ts +157 -0
  632. package/src/peers/envelope.ts +1 -1
  633. package/src/plugin/shell-hook.ts +8 -2
  634. package/src/process/kill-tree.ts +10 -1
  635. package/src/provider/errors.ts +135 -2
  636. package/src/public-runtime.ts +117 -12
  637. package/src/public-tools.ts +13 -1
  638. package/src/public-types.ts +69 -7
  639. package/src/registry/tool/presentation.ts +9 -4
  640. package/src/runtime/harness-session/index.ts +1125 -0
  641. package/src/runtime/harness-session/journal.ts +209 -0
  642. package/src/runtime/harness-session/saved-view.ts +122 -0
  643. package/src/runtime/jobs/awaited-jobs.ts +2 -1
  644. package/src/runtime/jobs/registry.ts +397 -41
  645. package/src/runtime/query/abandon-turn.ts +18 -2
  646. package/src/runtime/query/checkpoint.ts +11 -0
  647. package/src/runtime/query/durable-inbound.ts +101 -0
  648. package/src/runtime/query/events.ts +22 -5
  649. package/src/runtime/query/executor/tool-call-admission.ts +125 -32
  650. package/src/runtime/query/executor.ts +316 -130
  651. package/src/runtime/query/index.ts +24 -4
  652. package/src/runtime/query/iteration/index.ts +218 -104
  653. package/src/runtime/query/iteration/outstanding-work.ts +55 -7
  654. package/src/runtime/query/iteration/phases/context.ts +4 -0
  655. package/src/runtime/query/iteration/phases/tool-review.ts +118 -21
  656. package/src/runtime/query/observation-context.ts +22 -16
  657. package/src/runtime/query/prepare-turn.ts +2 -2
  658. package/src/runtime/query/prompt-cache.ts +3 -0
  659. package/src/runtime/query/prompt.ts +32 -1
  660. package/src/runtime/query/repeat-call.ts +40 -10
  661. package/src/runtime/query/resume-pending.ts +60 -7
  662. package/src/runtime/query/resume-session.ts +1 -1
  663. package/src/runtime/query/review-policy.ts +23 -2
  664. package/src/runtime/query/saved-presentation.ts +70 -0
  665. package/src/runtime/query/steering.ts +6 -9
  666. package/src/runtime/query/tool-executions.ts +108 -9
  667. package/src/runtime/query/tooling.ts +6 -1
  668. package/src/scheduler/completion-inbox.ts +108 -7
  669. package/src/scheduler/delegating.ts +5 -0
  670. package/src/scheduler/local.ts +2 -0
  671. package/src/session/summary/materialize.ts +51 -9
  672. package/src/store/budget/ledger.ts +60 -5
  673. package/src/store/session/disk.ts +77 -10
  674. package/src/store/session/memory.ts +32 -7
  675. package/src/store/session-log/core.ts +118 -11
  676. package/src/store/session-log/disk.ts +9 -2
  677. package/src/store/session-log/fold.ts +22 -0
  678. package/src/store/session-log/index.ts +5 -0
  679. package/src/store/session-log/memory.ts +2 -1
  680. package/src/store/session-log/spill.ts +89 -6
  681. package/src/store/session-log/structured-result.ts +96 -0
  682. package/src/store/task/disk.ts +46 -2
  683. package/src/store/task/memory.ts +13 -3
  684. package/src/tools/admit-facts.ts +145 -0
  685. package/src/tools/builtins/bash.ts +132 -24
  686. package/src/tools/builtins/edit.ts +42 -0
  687. package/src/tools/builtins/file-write-result.ts +14 -0
  688. package/src/tools/builtins/glob.ts +12 -0
  689. package/src/tools/builtins/grep.ts +14 -0
  690. package/src/tools/builtins/index.ts +2 -0
  691. package/src/tools/builtins/job.ts +4 -1
  692. package/src/tools/builtins/read-file.ts +57 -0
  693. package/src/tools/builtins/view-image.ts +409 -0
  694. package/src/tools/builtins/wait-for-job-bounds.ts +3 -0
  695. package/src/tools/builtins/wait-for-job.ts +141 -32
  696. package/src/tools/builtins/write-file.ts +4 -2
  697. package/src/tools/command-shell.ts +132 -5
  698. package/src/tools/coordinator/agent.ts +9 -19
  699. package/src/tools/coordinator/index.ts +150 -75
  700. package/src/tools/coordinator/wait-with-idle-bound.ts +3 -1
  701. package/src/tools/defineTool.ts +4 -0
  702. package/src/tools/failure-facts.ts +24 -0
  703. package/src/tools/host-output.ts +136 -0
  704. package/src/tools/oem-code-pages.ts +22 -0
  705. package/src/tools/schedules/schedule-tool.ts +38 -5
  706. package/src/tools/schedules/types.ts +23 -3
  707. package/src/tools/task/list.ts +15 -7
  708. package/src/tools/task/present.ts +37 -7
  709. package/src/tools/task/update.ts +12 -5
  710. package/src/tools/text-window.ts +87 -0
  711. package/src/toolsets/manager.ts +58 -1
  712. package/src/types/acp/index.ts +150 -4
  713. package/src/types/agent/base.ts +3 -0
  714. package/src/types/agent/manager.ts +8 -23
  715. package/src/types/agent/scheduler.ts +10 -1
  716. package/src/types/agent/task.ts +4 -0
  717. package/src/types/connector/mcp.ts +7 -0
  718. package/src/types/errors/catalog.ts +4 -2
  719. package/src/types/harness/schema.ts +203 -0
  720. package/src/types/harness/session.ts +306 -0
  721. package/src/types/hitl/index.ts +17 -1
  722. package/src/types/job/index.ts +42 -0
  723. package/src/types/message/inbound-delivery.ts +63 -0
  724. package/src/types/message/index.ts +8 -1
  725. package/src/types/sandbox/index.ts +46 -0
  726. package/src/types/session/checkpoint.ts +4 -1
  727. package/src/types/session/events.ts +23 -1
  728. package/src/types/session/records.ts +114 -2
  729. package/src/types/session/step.ts +2 -0
  730. package/src/types/session/store.ts +23 -9
  731. package/src/types/session/tool-execution.ts +6 -0
  732. package/src/types/structured-output/index.ts +13 -2
  733. package/src/types/summary/ref.ts +3 -1
  734. package/src/types/tool/index.ts +39 -5
  735. package/src/types/tool/presentation.ts +121 -0
  736. package/src/utils/json-snapshot.ts +26 -9
  737. package/src/utils/structured-result-json.ts +10 -0
@@ -0,0 +1,1125 @@
1
+ import { posix, win32 } from 'node:path'
2
+ import {
3
+ HarnessBindingSchema,
4
+ HarnessDecisionSchema,
5
+ HarnessEventSchema,
6
+ HarnessNativeTurnSchema,
7
+ HarnessReviewRequestSchema,
8
+ harnessSnapshot,
9
+ } from '../../types/harness/schema.js'
10
+ import type {
11
+ HarnessAdmissionRequest,
12
+ HarnessBinding,
13
+ HarnessConnection,
14
+ HarnessDecision,
15
+ HarnessEvent,
16
+ HarnessHistorySnapshot,
17
+ HarnessJournalTransition,
18
+ HarnessNativeItem,
19
+ HarnessNativeTurn,
20
+ HarnessPrompt,
21
+ HarnessReviewRequest,
22
+ HarnessSession,
23
+ HarnessSessionOptions,
24
+ HarnessTurnOutcome,
25
+ } from '../../types/harness/session.js'
26
+ import type { MessageId, TurnId } from '../../types/ids/index.js'
27
+ import type { AssistantMessage, Message } from '../../types/message/index.js'
28
+ import type { SessionEvent } from '../../types/session/events.js'
29
+ import type { TurnSettlement } from '../../types/session/turn.js'
30
+ import {
31
+ generateMessageId,
32
+ generateToolCallId,
33
+ generateTurnId,
34
+ isEntityId,
35
+ } from '../../utils/id.js'
36
+ import { HarnessJournal, HarnessSessionError, harnessDigest } from './journal.js'
37
+ import { engineSavedView } from './saved-view.js'
38
+
39
+ type Payload<E> = E extends unknown ? Omit<E, 'sessionId' | 'turnId'> : never
40
+ type EventPayload = Payload<SessionEvent>
41
+
42
+ interface Item {
43
+ messageId?: MessageId
44
+ toolUseId?: string
45
+ started: boolean
46
+ completed?: string
47
+ content: string
48
+ blocks: Map<string, number>
49
+ /** What the call was started with, for the label a saved conversation keeps. */
50
+ input?: unknown
51
+ }
52
+ interface Active {
53
+ turnId: TurnId
54
+ operationId: string
55
+ startedAt: number
56
+ nativeTurn?: HarnessNativeTurn
57
+ items: Map<string, Item>
58
+ reviews: Map<
59
+ string,
60
+ {
61
+ request: HarnessReviewRequest
62
+ digest: string
63
+ decision?: string
64
+ resolved: boolean
65
+ presented?: boolean
66
+ }
67
+ >
68
+ resolve: (outcome: HarnessTurnOutcome) => void
69
+ reject: (error: unknown) => void
70
+ done: Promise<HarnessTurnOutcome>
71
+ abortRequested?: boolean
72
+ removeAbort?: () => void
73
+ }
74
+
75
+ /** Vendor execution remains outside the Namzu query kernel and tool executor. */
76
+ export function createHarnessSession(options: HarnessSessionOptions): HarnessSession {
77
+ return new ExternalHarnessSession(options)
78
+ }
79
+ export { HarnessSessionError } from './journal.js'
80
+
81
+ class ExternalHarnessSession implements HarnessSession {
82
+ readonly scope: HarnessSession['scope']
83
+ private readonly journal: HarnessJournal
84
+ private readonly openAdapter: HarnessSessionOptions['adapter']['open']
85
+ private readonly admit: HarnessSessionOptions['assertAdmission']
86
+ private readonly publish: HarnessSessionOptions['onEvent']
87
+ private readonly review: HarnessSessionOptions['onReview']
88
+ private currentBinding?: HarnessBinding
89
+ private connection?: HarnessConnection
90
+ private active?: Active
91
+ private phase: HarnessSession['status'] = 'disconnected'
92
+ private operation = false
93
+ private cancelling = false
94
+ private epoch = 0
95
+ private events: Promise<void> = Promise.resolve()
96
+ private eventError?: unknown
97
+
98
+ constructor(options: HarnessSessionOptions) {
99
+ this.scope = harnessSnapshot(options.scope)
100
+ if (
101
+ !isEntityId(this.scope.sessionId, 'session') ||
102
+ !isEntityId(this.scope.projectId, 'project') ||
103
+ !isEntityId(this.scope.tenantId, 'tenant') ||
104
+ !isEntityId(this.scope.topicId, 'topic') ||
105
+ !(posix.isAbsolute(this.scope.cwd) || win32.isAbsolute(this.scope.cwd)) ||
106
+ Array.from(this.scope.cwd).some((c) => c.charCodeAt(0) < 32)
107
+ )
108
+ throw new HarnessSessionError(
109
+ 'invalid-scope',
110
+ 'An exact owner scope and canonical absolute native directory are required.',
111
+ )
112
+ if (
113
+ typeof options.assertAdmission !== 'function' ||
114
+ typeof options.onEvent !== 'function' ||
115
+ typeof options.onReview !== 'function'
116
+ )
117
+ throw new HarnessSessionError(
118
+ 'invalid-host',
119
+ 'Explicit admission, event and review host ports are required.',
120
+ )
121
+ this.journal = new HarnessJournal(
122
+ options.sessionLog,
123
+ this.scope,
124
+ options.adapter.engineId,
125
+ options.adapter.profileRef,
126
+ )
127
+ this.openAdapter = options.adapter.open.bind(options.adapter)
128
+ this.admit = options.assertAdmission
129
+ this.publish = options.onEvent
130
+ this.review = options.onReview
131
+ }
132
+ get binding() {
133
+ return this.currentBinding
134
+ }
135
+ get currentTurnId() {
136
+ return this.active?.turnId
137
+ }
138
+ get status() {
139
+ return this.phase
140
+ }
141
+
142
+ private hasUnresolved(): boolean {
143
+ return (
144
+ !!this.active || this.phase === 'reconciliation-required' || this.eventError !== undefined
145
+ )
146
+ }
147
+ private reserve(): () => void {
148
+ if (this.phase === 'closed')
149
+ throw new HarnessSessionError('closed', 'This harness session is closed.')
150
+ if (this.operation || this.cancelling)
151
+ throw new HarnessSessionError('busy', 'Another harness operation is pending.')
152
+ this.operation = true
153
+ let released = false
154
+ return () => {
155
+ if (released) return
156
+ released = true
157
+ this.operation = false
158
+ }
159
+ }
160
+ private async authorize(
161
+ kind: HarnessAdmissionRequest['kind'],
162
+ signal?: AbortSignal,
163
+ request?: HarnessReviewRequest,
164
+ ): Promise<void> {
165
+ if (signal?.aborted)
166
+ throw new HarnessSessionError('aborted', 'The operation was aborted before dispatch.')
167
+ await this.admit(
168
+ harnessSnapshot({
169
+ kind,
170
+ scope: this.scope,
171
+ ...(this.currentBinding ? { binding: this.currentBinding } : {}),
172
+ ...(this.active?.nativeTurn ? { nativeTurn: this.active.nativeTurn } : {}),
173
+ ...(request ? { review: request } : {}),
174
+ }),
175
+ signal,
176
+ )
177
+ if (signal?.aborted)
178
+ throw new HarnessSessionError('aborted', 'The operation was aborted before dispatch.')
179
+ }
180
+ async history(): Promise<readonly Message[]> {
181
+ const state = await this.journal.inspect()
182
+ this.currentBinding ??= state.binding
183
+ return harnessSnapshot(await this.journal.log.messages())
184
+ }
185
+
186
+ private requireConnection(): HarnessConnection {
187
+ if (!this.connection)
188
+ throw new HarnessSessionError('disconnected', 'The native connection is not ready.')
189
+ return this.connection
190
+ }
191
+ private capture(connection: HarnessConnection): HarnessConnection {
192
+ const binding = harnessSnapshot(HarnessBindingSchema.parse(connection.binding))
193
+ this.journal.validateBinding(binding)
194
+ if (this.currentBinding && harnessDigest(this.currentBinding) !== harnessDigest(binding))
195
+ throw new HarnessSessionError(
196
+ 'binding-mismatch',
197
+ 'The adapter resumed a different native session.',
198
+ )
199
+ return Object.freeze({
200
+ binding,
201
+ capabilities: harnessSnapshot(connection.capabilities),
202
+ models: connection.models.bind(connection),
203
+ dispatch: connection.dispatch.bind(connection),
204
+ interrupt: connection.interrupt.bind(connection),
205
+ respond: connection.respond.bind(connection),
206
+ readHistory: connection.readHistory.bind(connection),
207
+ close: connection.close.bind(connection),
208
+ })
209
+ }
210
+ private async connect(model?: string, signal?: AbortSignal): Promise<void> {
211
+ if (this.connection) return
212
+ const stored = await this.journal.inspect()
213
+ this.currentBinding = stored.binding
214
+ await this.authorize(stored.binding ? 'reconnect' : 'open', signal)
215
+ await this.journal.claim()
216
+ await this.authorize(stored.binding ? 'reconnect' : 'open', signal)
217
+ const epoch = ++this.epoch
218
+ let accepting = false
219
+ const early: HarnessEvent[] = []
220
+ let earlyBytes = 0
221
+ const sink = (input: HarnessEvent): Promise<void> => {
222
+ if (epoch !== this.epoch || this.phase === 'closed') return Promise.resolve()
223
+ let event: HarnessEvent
224
+ try {
225
+ event = harnessSnapshot(HarnessEventSchema.parse(input))
226
+ } catch (error) {
227
+ return this.enqueueTask(() => Promise.reject(error), epoch)
228
+ }
229
+ if (!accepting) {
230
+ earlyBytes += JSON.stringify(event).length
231
+ if (early.length >= 256 || earlyBytes > 1024 * 1024)
232
+ return this.enqueueTask(
233
+ () =>
234
+ Promise.reject(
235
+ new HarnessSessionError(
236
+ 'early-events-overflow',
237
+ 'The adapter exceeded the bounded pre-binding event queue.',
238
+ ),
239
+ ),
240
+ epoch,
241
+ )
242
+ early.push(event)
243
+ return Promise.resolve()
244
+ }
245
+ return this.enqueue(event, epoch)
246
+ }
247
+ try {
248
+ const opened = await this.openAdapter(
249
+ {
250
+ cwd: this.scope.cwd,
251
+ ...(model ? { model } : {}),
252
+ ...(stored.binding ? { resume: stored.binding } : {}),
253
+ ...(signal ? { signal } : {}),
254
+ },
255
+ sink,
256
+ )
257
+ // Retain even an invalid returned handle until owned cleanup is confirmed.
258
+ this.connection = opened
259
+ this.connection = this.capture(opened)
260
+ this.currentBinding = this.connection.binding
261
+ await this.authorize(stored.binding ? 'reconnect' : 'open', signal)
262
+ await this.journal.start(this.currentBinding)
263
+ await this.restoreActive(stored.transitions)
264
+ accepting = true
265
+ for (const event of early) await this.enqueue(event, epoch)
266
+ if (stored.binding && !this.active && this.connection.capabilities.history === 'snapshot') {
267
+ const snapshot = harnessSnapshot(await this.connection.readHistory(signal))
268
+ if (
269
+ !snapshot.complete ||
270
+ harnessDigest(snapshot.binding) !== harnessDigest(this.currentBinding) ||
271
+ snapshot.activeTurn ||
272
+ snapshot.pendingReviews.length
273
+ )
274
+ throw new HarnessSessionError(
275
+ 'reconciliation-required',
276
+ 'Native session history did not confirm an idle exact binding.',
277
+ )
278
+ }
279
+ if (!this.active && this.phase !== 'reconciliation-required') this.phase = 'idle'
280
+ } catch (error) {
281
+ if (this.connection) {
282
+ try {
283
+ await this.connection.close()
284
+ this.connection = undefined
285
+ ++this.epoch
286
+ await this.journal.release()
287
+ } catch (cleanup) {
288
+ this.phase = 'reconciliation-required'
289
+ throw new AggregateError(
290
+ [error, cleanup],
291
+ 'Harness open failed and its process could not be confirmed stopped.',
292
+ )
293
+ }
294
+ } else await this.journal.release()
295
+ throw error
296
+ }
297
+ }
298
+ private makeActive(turnId: TurnId, operationId: string, startedAt: number): Active {
299
+ let resolve!: Active['resolve']
300
+ let reject!: Active['reject']
301
+ const done = new Promise<HarnessTurnOutcome>((yes, no) => {
302
+ resolve = yes
303
+ reject = no
304
+ })
305
+ void done.catch(() => undefined)
306
+ return {
307
+ turnId,
308
+ operationId,
309
+ startedAt,
310
+ items: new Map(),
311
+ reviews: new Map(),
312
+ resolve,
313
+ reject,
314
+ done,
315
+ }
316
+ }
317
+ private async restoreActive(transitions: readonly HarnessJournalTransition[]): Promise<void> {
318
+ const pending = await this.journal.log.activeTurn({ lease: await this.journal.current() })
319
+ if (!pending) {
320
+ this.active?.removeAbort?.()
321
+ this.active = undefined
322
+ return
323
+ }
324
+ const prepared = [...transitions]
325
+ .reverse()
326
+ .find((e) => e.kind === 'dispatch-prepared' && e.turnId === pending.turnId)
327
+ if (!prepared || prepared.kind !== 'dispatch-prepared')
328
+ throw new HarnessSessionError(
329
+ 'invalid-journal',
330
+ 'The active harness turn has no prepared dispatch receipt.',
331
+ )
332
+ const active = this.makeActive(pending.turnId, prepared.operationId, Date.now())
333
+ for (const entry of transitions) {
334
+ if (!('turnId' in entry) || entry.turnId !== pending.turnId) continue
335
+ if (entry.kind === 'dispatch-accepted') {
336
+ if (entry.operationId !== active.operationId)
337
+ throw new HarnessSessionError(
338
+ 'invalid-journal',
339
+ 'Dispatch receipt does not match the prepared operation.',
340
+ )
341
+ this.validateNative(entry.nativeTurn, active)
342
+ active.nativeTurn = harnessSnapshot(entry.nativeTurn)
343
+ } else if (entry.kind === 'item-bound') {
344
+ this.validateNative(entry.nativeItem, active)
345
+ active.items.set(entry.nativeItem.nativeItemId, {
346
+ messageId: entry.messageId,
347
+ toolUseId: entry.toolUseId,
348
+ started: false,
349
+ content: '',
350
+ blocks: new Map(),
351
+ })
352
+ } else if (entry.kind === 'review-requested') {
353
+ this.validateNative(entry.request, active)
354
+ if (harnessDigest(entry.request) !== entry.digest)
355
+ throw new HarnessSessionError(
356
+ 'invalid-journal',
357
+ 'The native review digest does not match its captured request.',
358
+ )
359
+ active.reviews.set(entry.request.requestId, {
360
+ request: harnessSnapshot(entry.request),
361
+ digest: entry.digest,
362
+ resolved: false,
363
+ })
364
+ } else if (entry.kind === 'review-decided') {
365
+ const review = active.reviews.get(entry.requestId)
366
+ if (
367
+ !review ||
368
+ review.digest !== entry.requestDigest ||
369
+ harnessDigest(entry.decision) !== entry.decisionDigest
370
+ )
371
+ throw new HarnessSessionError(
372
+ 'invalid-journal',
373
+ 'The native decision does not match its recorded request.',
374
+ )
375
+ review.decision = entry.decisionDigest
376
+ } else if (entry.kind === 'review-resolved') {
377
+ const review = active.reviews.get(entry.requestId)
378
+ if (review) review.resolved = true
379
+ }
380
+ }
381
+ const { entries } = await this.journal.log.readAll()
382
+ for (const { record } of entries) {
383
+ if (record.turnId !== active.turnId) continue
384
+ if (record.type === 'turn_started') active.startedAt = Date.parse(record.ts)
385
+ if (record.type === 'message')
386
+ for (const item of active.items.values())
387
+ if (item.messageId === record.messageId && record.role === 'assistant') {
388
+ item.started = true
389
+ item.completed = harnessDigest(record.content)
390
+ item.content = typeof record.content.content === 'string' ? record.content.content : ''
391
+ }
392
+ }
393
+ this.active = active
394
+ this.phase = 'reconciliation-required'
395
+ }
396
+
397
+ async run(input: Omit<HarnessPrompt, 'operationId'>): Promise<HarnessTurnOutcome> {
398
+ const signal = input.signal
399
+ const prompt = harnessSnapshot({
400
+ prompt: input.prompt,
401
+ model: input.model,
402
+ permissionMode: input.permissionMode,
403
+ ...(input.effort ? { effort: input.effort } : {}),
404
+ })
405
+ const release = this.reserve()
406
+ if (
407
+ !prompt.prompt ||
408
+ prompt.prompt.length > 1024 * 1024 ||
409
+ !prompt.model ||
410
+ prompt.model.length > 4096
411
+ ) {
412
+ release()
413
+ throw new HarnessSessionError(
414
+ 'invalid-prompt',
415
+ 'A bounded prompt and explicit model are required.',
416
+ )
417
+ }
418
+ let active: Active | undefined
419
+ let dispatchInvoked = false
420
+ try {
421
+ if (this.hasUnresolved())
422
+ throw new HarnessSessionError(
423
+ 'reconciliation-required',
424
+ 'A previous turn must be reconciled before sending another prompt.',
425
+ )
426
+ await this.connect(prompt.model, signal)
427
+ if (this.hasUnresolved())
428
+ throw new HarnessSessionError(
429
+ 'reconciliation-required',
430
+ 'The journal contains an unresolved native dispatch; it will not be resent.',
431
+ )
432
+ const connection = this.connection as HarnessConnection
433
+ if (!connection.capabilities.reviewModes.includes(prompt.permissionMode))
434
+ throw new HarnessSessionError(
435
+ 'unsupported-mode',
436
+ 'This harness does not support the selected review mode.',
437
+ )
438
+ if (prompt.effort && !connection.capabilities.effortLevels?.includes(prompt.effort))
439
+ throw new HarnessSessionError(
440
+ 'unsupported-effort',
441
+ 'This harness does not support the selected effort.',
442
+ )
443
+ await this.authorize('run', signal)
444
+ const lease = await this.journal.current()
445
+ const turnId = generateTurnId()
446
+ const promptId = generateMessageId()
447
+ const operationId = `${turnId}:${promptId}`
448
+ active = this.makeActive(turnId, operationId, Date.now())
449
+ this.active = active
450
+ const entry = await this.journal.log.beginTurn(lease, {
451
+ turnId,
452
+ userMessageId: promptId,
453
+ config: { model: prompt.model, tokenBudget: 0, timeoutMs: 0 },
454
+ origin: { protocol: 'sdk', kind: 'prompt' },
455
+ })
456
+ await this.journal.append({
457
+ type: 'message',
458
+ turnId,
459
+ messageId: promptId,
460
+ role: 'user',
461
+ kind: 'prompt',
462
+ content: { role: 'user', content: prompt.prompt },
463
+ })
464
+ await this.journal.transition({
465
+ kind: 'dispatch-prepared',
466
+ model: prompt.model,
467
+ permissionMode: prompt.permissionMode,
468
+ ...(prompt.effort ? { effort: prompt.effort } : {}),
469
+ operationId,
470
+ turnId,
471
+ promptId,
472
+ digest: harnessDigest(prompt),
473
+ })
474
+ this.phase = 'running'
475
+ await this.publish({
476
+ type: 'turn_started',
477
+ sessionId: this.scope.sessionId,
478
+ turnId,
479
+ userMessageId: promptId,
480
+ config: { model: prompt.model, tokenBudget: 0, timeoutMs: 0 },
481
+ v: 1,
482
+ seq: entry.record.seq,
483
+ generation: entry.record.gen,
484
+ })
485
+ // Recheck current host authority and writer immediately before the external effect.
486
+ await this.authorize('run', signal)
487
+ await this.journal.current()
488
+ if (signal) {
489
+ const ownTurn = active
490
+ const abort = () => {
491
+ ownTurn.abortRequested = true
492
+ if (ownTurn.nativeTurn)
493
+ void this.cancel(ownTurn.turnId).catch((error: unknown) => ownTurn.reject(error))
494
+ }
495
+ signal.addEventListener('abort', abort, { once: true })
496
+ active.removeAbort = () => signal.removeEventListener('abort', abort)
497
+ }
498
+ release() // cancellation/review is admitted while the durable native turn runs
499
+ dispatchInvoked = true
500
+ const nativeTurn = harnessSnapshot(
501
+ HarnessNativeTurnSchema.parse(
502
+ await connection.dispatch({ ...prompt, operationId, ...(signal ? { signal } : {}) }),
503
+ ),
504
+ )
505
+ await this.events
506
+ if (this.eventError) throw this.eventError
507
+ if (this.active === active) await this.bindNative(nativeTurn, active)
508
+ else this.validateNative(nativeTurn, active) // terminal before ACK must not reactivate
509
+ return await active.done
510
+ } catch (error) {
511
+ if (active && this.active === active) {
512
+ if (dispatchInvoked) await this.uncertain('dispatch-unconfirmed', error)
513
+ else await this.failBeforeDispatch(active)
514
+ }
515
+ throw error
516
+ } finally {
517
+ release()
518
+ }
519
+ }
520
+ private async failBeforeDispatch(active: Active): Promise<void> {
521
+ const settlement = this.settlement(active, 'failed')
522
+ await this.emit(active, {
523
+ type: 'turn_failed',
524
+ error: 'The host refused this prompt before native dispatch.',
525
+ settlement,
526
+ })
527
+ active.removeAbort?.()
528
+ active.reject(new HarnessSessionError('dispatch-refused', 'No native dispatch occurred.'))
529
+ this.active = undefined
530
+ this.phase = 'idle'
531
+ }
532
+
533
+ private validateNative(native: HarnessNativeTurn, active: Active): void {
534
+ if (
535
+ native.nativeSessionId !== this.currentBinding?.nativeSessionId ||
536
+ (native.turnIdSource === 'operation' && native.nativeTurnId !== active.operationId)
537
+ )
538
+ throw new HarnessSessionError(
539
+ 'native-owner-mismatch',
540
+ 'Native event does not belong to this session and dispatch operation.',
541
+ )
542
+ if (
543
+ active.nativeTurn &&
544
+ (active.nativeTurn.nativeSessionId !== native.nativeSessionId ||
545
+ active.nativeTurn.nativeTurnId !== native.nativeTurnId ||
546
+ (active.nativeTurn.turnIdSource ?? 'engine') !== (native.turnIdSource ?? 'engine'))
547
+ )
548
+ throw new HarnessSessionError('native-turn-mismatch', 'Native event names a different turn.')
549
+ }
550
+ private async bindNative(native: HarnessNativeTurn, active: Active): Promise<void> {
551
+ this.validateNative(native, active)
552
+ if (active.nativeTurn) return
553
+ active.nativeTurn = harnessSnapshot({
554
+ nativeSessionId: native.nativeSessionId,
555
+ nativeTurnId: native.nativeTurnId,
556
+ ...(native.turnIdSource ? { turnIdSource: native.turnIdSource } : {}),
557
+ })
558
+ await this.journal.transition({
559
+ kind: 'dispatch-accepted',
560
+ operationId: active.operationId,
561
+ turnId: active.turnId,
562
+ nativeTurn: active.nativeTurn,
563
+ })
564
+ if (active.abortRequested)
565
+ void this.cancel(active.turnId).catch((error: unknown) => active.reject(error))
566
+ }
567
+ private enqueue(event: HarnessEvent, epoch: number): Promise<void> {
568
+ return this.enqueueTask(() => this.consume(event), epoch)
569
+ }
570
+ private enqueueTask(operation: () => Promise<void>, epoch: number): Promise<void> {
571
+ const next = this.events.then(async () => {
572
+ if (epoch !== this.epoch) return
573
+ if (this.eventError !== undefined) throw this.eventError
574
+ await operation()
575
+ })
576
+ this.events = next.catch(async (error: unknown) => {
577
+ if (this.eventError === undefined) {
578
+ this.eventError = error
579
+ await this.uncertain('event-rejected', error)
580
+ }
581
+ })
582
+ return next
583
+ }
584
+ private async uncertain(code: string, error: unknown): Promise<void> {
585
+ this.phase = 'reconciliation-required'
586
+ const active = this.active
587
+ active?.removeAbort?.()
588
+ active?.reject(error)
589
+ try {
590
+ await this.journal.transition({
591
+ kind: 'connection-lost',
592
+ ...(active ? { turnId: active.turnId } : {}),
593
+ code,
594
+ })
595
+ } catch {
596
+ /* writer failure remains retained; never report confirmed stop */
597
+ }
598
+ }
599
+ private async item(
600
+ native: HarnessNativeItem,
601
+ active: Active,
602
+ kind: 'message' | 'tool',
603
+ ): Promise<Item> {
604
+ let item = active.items.get(native.nativeItemId)
605
+ if (!item) {
606
+ item = { started: false, content: '', blocks: new Map() }
607
+ active.items.set(native.nativeItemId, item)
608
+ }
609
+ if (kind === 'message' && !item.messageId) item.messageId = generateMessageId()
610
+ else if (kind === 'tool' && !item.toolUseId) item.toolUseId = generateToolCallId()
611
+ else return item
612
+ await this.journal.transition({
613
+ kind: 'item-bound',
614
+ turnId: active.turnId,
615
+ nativeItem: {
616
+ nativeSessionId: native.nativeSessionId,
617
+ nativeTurnId: native.nativeTurnId,
618
+ nativeItemId: native.nativeItemId,
619
+ ...(native.turnIdSource ? { turnIdSource: native.turnIdSource } : {}),
620
+ },
621
+ ...(item.messageId ? { messageId: item.messageId } : {}),
622
+ ...(item.toolUseId ? { toolUseId: item.toolUseId } : {}),
623
+ })
624
+ return item
625
+ }
626
+ private async emit(active: Active, event: EventPayload): Promise<void> {
627
+ await this.journal.event(
628
+ { ...event, sessionId: this.scope.sessionId, turnId: active.turnId } as SessionEvent,
629
+ this.publish,
630
+ )
631
+ }
632
+ private async consume(event: HarnessEvent): Promise<void> {
633
+ if (event.kind === 'connection-lost') {
634
+ const error = new HarnessSessionError(
635
+ 'connection-lost',
636
+ 'Native connection was lost; dispatch recovery is required.',
637
+ )
638
+ this.eventError = error
639
+ await this.uncertain(event.code, error)
640
+ return
641
+ }
642
+ const active = this.active
643
+ if (!active) return // never revive a terminal turn from transport tails
644
+ const native = event.kind === 'review-requested' ? event.request : event
645
+ await this.bindNative(native, active)
646
+ switch (event.kind) {
647
+ case 'turn-started':
648
+ return
649
+ case 'review-requested': {
650
+ const digest = harnessDigest(event.request)
651
+ const old = active.reviews.get(event.request.requestId)
652
+ if (old) {
653
+ if (old.digest !== digest)
654
+ throw new HarnessSessionError(
655
+ 'review-conflict',
656
+ 'Native request ID was reused with different input.',
657
+ )
658
+ return
659
+ }
660
+ active.reviews.set(event.request.requestId, {
661
+ request: event.request,
662
+ digest,
663
+ resolved: false,
664
+ })
665
+ await this.journal.transition({
666
+ kind: 'review-requested',
667
+ turnId: active.turnId,
668
+ request: event.request,
669
+ digest,
670
+ })
671
+ this.phase = 'waiting'
672
+ await this.review(event.request)
673
+ const presented = active.reviews.get(event.request.requestId)
674
+ if (presented) presented.presented = true
675
+ return
676
+ }
677
+ case 'review-resolved': {
678
+ const review = active.reviews.get(event.requestId)
679
+ if (!review || review.resolved) return
680
+ review.resolved = true
681
+ await this.journal.transition({
682
+ kind: 'review-resolved',
683
+ turnId: active.turnId,
684
+ requestId: event.requestId,
685
+ })
686
+ if (![...active.reviews.values()].some((r) => !r.resolved)) this.phase = 'running'
687
+ return
688
+ }
689
+ case 'turn-completed':
690
+ await this.finish(active, event)
691
+ return
692
+ case 'tool-started': {
693
+ const item = await this.item(event, active, 'tool')
694
+ if (item.started) return
695
+ item.started = true
696
+ item.input = event.input
697
+ await this.emit(active, {
698
+ type: 'tool_executing',
699
+ toolUseId: item.toolUseId as string,
700
+ toolName: `${this.currentBinding?.engineId}:${event.name}`,
701
+ input: event.input,
702
+ })
703
+ return
704
+ }
705
+ case 'tool-output': {
706
+ const item = await this.item(event, active, 'tool')
707
+ await this.emit(active, {
708
+ type: 'tool_progress',
709
+ toolUseId: item.toolUseId as string,
710
+ toolName: this.currentBinding?.engineId ?? 'harness',
711
+ message: event.text,
712
+ })
713
+ return
714
+ }
715
+ case 'tool-completed': {
716
+ const item = await this.item(event, active, 'tool')
717
+ const digest = harnessDigest(event)
718
+ if (item.completed === digest) return
719
+ if (item.completed)
720
+ throw new HarnessSessionError(
721
+ 'item-conflict',
722
+ 'Native tool completion changed after settlement.',
723
+ )
724
+ item.completed = digest
725
+ await this.emit(active, {
726
+ type: 'tool_completed',
727
+ toolUseId: item.toolUseId as string,
728
+ toolName: `${this.currentBinding?.engineId}:${event.name}`,
729
+ result: event.result,
730
+ isError: event.status !== 'completed',
731
+ savedPresentation: engineSavedView(event.name, item.input),
732
+ ...(event.durationMs === undefined ? {} : { durationMs: event.durationMs }),
733
+ })
734
+ return
735
+ }
736
+ case 'message-started':
737
+ case 'text-delta':
738
+ case 'message-completed':
739
+ case 'reasoning': {
740
+ const item = await this.item(event, active, 'message')
741
+ const messageId = item.messageId as MessageId
742
+ if (!item.started) {
743
+ item.started = true
744
+ await this.emit(active, { type: 'message_started', iteration: 0, messageId })
745
+ }
746
+ if (event.kind === 'text-delta') {
747
+ if (item.completed) return
748
+ item.content += event.text
749
+ await this.emit(active, {
750
+ type: 'text_delta',
751
+ iteration: 0,
752
+ messageId,
753
+ text: event.text,
754
+ ...(event.part ? { textPart: event.part } : {}),
755
+ })
756
+ } else if (event.kind === 'message-completed') {
757
+ await this.completeMessage(active, item, event.content, event.parts, event.stopReason)
758
+ } else if (event.kind === 'reasoning') {
759
+ let index = item.blocks.get(event.blockId)
760
+ if (index === undefined) {
761
+ index = item.blocks.size
762
+ item.blocks.set(event.blockId, index)
763
+ await this.emit(active, {
764
+ type: 'reasoning_started',
765
+ iteration: 0,
766
+ messageId,
767
+ blockIndex: index,
768
+ reasoningType: event.text === undefined ? 'redacted_thinking' : 'thinking',
769
+ })
770
+ }
771
+ if (event.status === 'pending' && event.text)
772
+ await this.emit(active, {
773
+ type: 'reasoning_delta',
774
+ iteration: 0,
775
+ messageId,
776
+ blockIndex: index,
777
+ text: event.text,
778
+ })
779
+ if (event.status === 'completed')
780
+ await this.emit(active, {
781
+ type: 'reasoning_completed',
782
+ iteration: 0,
783
+ messageId,
784
+ blockIndex: index,
785
+ signed: false,
786
+ ...(event.text === undefined ? {} : { text: event.text }),
787
+ })
788
+ }
789
+ return
790
+ }
791
+ }
792
+ }
793
+ private async completeMessage(
794
+ active: Active,
795
+ item: Item,
796
+ content: string,
797
+ parts: readonly import('../../types/harness/session.js').HarnessPublicTextPart[] | undefined,
798
+ stopReason: import('../../types/session/stop-reason.js').MessageStopReason,
799
+ ): Promise<void> {
800
+ const message: AssistantMessage = {
801
+ role: 'assistant',
802
+ content,
803
+ ...(parts ? { textParts: parts } : {}),
804
+ }
805
+ const digest = harnessDigest(message)
806
+ if (item.completed === digest) return
807
+ if (item.completed)
808
+ await this.journal.append({
809
+ type: 'message_replaced',
810
+ turnId: active.turnId,
811
+ targetMessageId: item.messageId as MessageId,
812
+ content: message,
813
+ reason: 'history-repair',
814
+ })
815
+ else
816
+ await this.journal.append({
817
+ type: 'message',
818
+ turnId: active.turnId,
819
+ messageId: item.messageId as MessageId,
820
+ role: 'assistant',
821
+ content: message,
822
+ })
823
+ item.completed = digest
824
+ item.content = content
825
+ await this.emit(active, {
826
+ type: 'message_completed',
827
+ iteration: 0,
828
+ messageId: item.messageId as MessageId,
829
+ content,
830
+ ...(parts ? { textParts: parts } : {}),
831
+ stopReason,
832
+ })
833
+ }
834
+ private async finish(
835
+ active: Active,
836
+ event: Extract<HarnessEvent, { kind: 'turn-completed' }>,
837
+ ): Promise<void> {
838
+ let final = event.finalItemId ? active.items.get(event.finalItemId) : undefined
839
+ if (event.result !== undefined) {
840
+ if (!final && event.finalItemId)
841
+ final = await this.item({ ...event, nativeItemId: event.finalItemId }, active, 'message')
842
+ if (final?.messageId && (final.content !== event.result || !final.completed))
843
+ await this.completeMessage(
844
+ active,
845
+ final,
846
+ event.result,
847
+ undefined,
848
+ event.status === 'cancelled' ? 'cancelled' : 'end_turn',
849
+ )
850
+ }
851
+ const result = event.result ?? final?.content ?? ''
852
+ const settlement: TurnSettlement = this.settlement(active, event.status, final?.messageId)
853
+ if (event.status === 'failed')
854
+ await this.emit(active, {
855
+ type: 'turn_failed',
856
+ error: event.error?.message ?? 'External harness turn failed.',
857
+ settlement,
858
+ })
859
+ else
860
+ await this.emit(active, {
861
+ type: 'turn_completed',
862
+ result,
863
+ stopReason: event.status === 'cancelled' ? 'cancelled' : 'end_turn',
864
+ settlement,
865
+ })
866
+ active.removeAbort?.()
867
+ this.active = undefined
868
+ this.phase = 'idle'
869
+ active.resolve({
870
+ turnId: active.turnId,
871
+ nativeTurn: active.nativeTurn as HarnessNativeTurn,
872
+ status: event.status,
873
+ messages: harnessSnapshot(await this.journal.log.messages()),
874
+ })
875
+ }
876
+ private settlement(
877
+ active: Active,
878
+ status: HarnessTurnOutcome['status'],
879
+ resultMessageId?: MessageId,
880
+ ): TurnSettlement {
881
+ return {
882
+ status,
883
+ iterations: 0,
884
+ usage: {
885
+ promptTokens: 0,
886
+ completionTokens: 0,
887
+ totalTokens: 0,
888
+ cachedTokens: 0,
889
+ cacheWriteTokens: 0,
890
+ },
891
+ cost: { totalCost: 0, cacheDiscount: 0, unpricedTokens: 0 },
892
+ durationMs: Math.max(0, Date.now() - active.startedAt),
893
+ resultSource: 'model',
894
+ ...(resultMessageId ? { resultMessageId } : {}),
895
+ abandonedJobIds: [],
896
+ abandonedTaskIds: [],
897
+ }
898
+ }
899
+
900
+ async respond(input: HarnessReviewRequest, value: HarnessDecision): Promise<void> {
901
+ const request = harnessSnapshot(HarnessReviewRequestSchema.parse(input))
902
+ const decision = harnessSnapshot(HarnessDecisionSchema.parse(value))
903
+ const release = this.reserve()
904
+ let reserved = false
905
+ try {
906
+ const active = this.active
907
+ const review = active?.reviews.get(request.requestId)
908
+ if (
909
+ !active ||
910
+ !review ||
911
+ review.resolved ||
912
+ review.decision ||
913
+ this.phase !== 'waiting' ||
914
+ review.digest !== harnessDigest(request)
915
+ )
916
+ throw new HarnessSessionError(
917
+ 'stale-review',
918
+ 'This native review request is stale, altered or already decided.',
919
+ )
920
+ if (!request.decisions.includes(decision.kind))
921
+ throw new HarnessSessionError(
922
+ 'unsupported-decision',
923
+ 'The native request does not permit this decision.',
924
+ )
925
+ await this.authorize('approval', undefined, request)
926
+ await this.journal.current()
927
+ if (this.active !== active || review.resolved || review.decision)
928
+ throw new HarnessSessionError(
929
+ 'stale-review',
930
+ 'The native request ended while authorization was pending.',
931
+ )
932
+ const digest = harnessDigest(decision)
933
+ await this.journal.transition({
934
+ kind: 'review-decided',
935
+ turnId: active.turnId,
936
+ requestId: request.requestId,
937
+ requestDigest: review.digest,
938
+ decisionDigest: digest,
939
+ decision,
940
+ })
941
+ reserved = true
942
+ review.decision = digest // durable reservation precedes native answer; unknown ACK is not retried
943
+ await this.authorize('approval', undefined, request)
944
+ await this.journal.current()
945
+ if (this.active !== active || review.resolved)
946
+ throw new HarnessSessionError(
947
+ 'stale-review',
948
+ 'The request ended before its decision could be sent.',
949
+ )
950
+ await (this.connection as HarnessConnection).respond(request, decision)
951
+ } catch (error) {
952
+ if (reserved) await this.uncertain('decision-unconfirmed', error)
953
+ throw error
954
+ } finally {
955
+ release()
956
+ }
957
+ }
958
+ async cancel(expectedTurnId: TurnId): Promise<{ stopped: true; turnId: TurnId }> {
959
+ if (this.operation || this.cancelling)
960
+ throw new HarnessSessionError('busy', 'Another harness operation is pending.')
961
+ const active = this.active
962
+ if (!active || active.turnId !== expectedTurnId)
963
+ throw new HarnessSessionError('stale-turn', 'Stop does not name the current admitted turn.')
964
+ if (!active.nativeTurn || !this.connection)
965
+ throw new HarnessSessionError(
966
+ 'dispatch-unconfirmed',
967
+ 'The native dispatch is not confirmed; reconcile or close this session.',
968
+ )
969
+ this.cancelling = true
970
+ try {
971
+ await this.journal.current()
972
+ if (this.connection.capabilities.interrupt === 'unavailable')
973
+ throw new HarnessSessionError(
974
+ 'unsupported-cancel',
975
+ 'The native engine cannot confirm interruption.',
976
+ )
977
+ if (this.connection.capabilities.interrupt === 'process-stop') {
978
+ await this.connection.close()
979
+ this.connection = undefined
980
+ ++this.epoch
981
+ if (this.active === active)
982
+ await this.finish(active, {
983
+ kind: 'turn-completed',
984
+ ...active.nativeTurn,
985
+ status: 'cancelled',
986
+ })
987
+ } else {
988
+ await this.connection.interrupt(active.nativeTurn)
989
+ await active.done // ACK is not completion; exact terminal event is required
990
+ }
991
+ return { stopped: true, turnId: expectedTurnId }
992
+ } finally {
993
+ this.cancelling = false
994
+ }
995
+ }
996
+ async reconnect(signal?: AbortSignal): Promise<void> {
997
+ const release = this.reserve()
998
+ try {
999
+ if (this.active && this.phase !== 'reconciliation-required')
1000
+ throw new HarnessSessionError('busy', 'A native turn is still running.')
1001
+ await this.authorize('reconnect', signal)
1002
+ if (this.connection) {
1003
+ await this.connection.close()
1004
+ this.connection = undefined
1005
+ ++this.epoch
1006
+ }
1007
+ await this.events
1008
+ this.eventError = undefined
1009
+ await this.connect(undefined, signal)
1010
+ if (!this.active) {
1011
+ this.phase = 'idle'
1012
+ return
1013
+ }
1014
+ await this.authorize('reconnect', signal)
1015
+ const snapshot = harnessSnapshot(await this.requireConnection().readHistory(signal))
1016
+ await this.reconcile(snapshot)
1017
+ } finally {
1018
+ release()
1019
+ }
1020
+ }
1021
+ private async reconcile(snapshot: HarnessHistorySnapshot): Promise<void> {
1022
+ if (
1023
+ !snapshot.complete ||
1024
+ harnessDigest(snapshot.binding) !== harnessDigest(this.currentBinding)
1025
+ )
1026
+ throw new HarnessSessionError(
1027
+ 'reconciliation-required',
1028
+ 'This engine cannot provide a complete history for the uncertain dispatch.',
1029
+ )
1030
+ const active = this.active
1031
+ if (!active?.nativeTurn)
1032
+ throw new HarnessSessionError(
1033
+ 'reconciliation-required',
1034
+ 'An unacknowledged dispatch has no trustworthy native turn correlation; it will not be resent.',
1035
+ )
1036
+ if (snapshot.activeTurn) this.validateNative(snapshot.activeTurn, active)
1037
+ for (const input of snapshot.events) {
1038
+ const event = harnessSnapshot(HarnessEventSchema.parse(input))
1039
+ if (event.kind === 'connection-lost') continue
1040
+ const native = event.kind === 'review-requested' ? event.request : event
1041
+ if (native.nativeTurnId !== active.nativeTurn.nativeTurnId) continue
1042
+ await this.consume(event)
1043
+ }
1044
+ if (!this.active) return
1045
+ if (!snapshot.activeTurn)
1046
+ throw new HarnessSessionError(
1047
+ 'reconciliation-required',
1048
+ 'Native history did not prove a terminal or an active exact turn.',
1049
+ )
1050
+ for (const input of snapshot.pendingReviews) {
1051
+ const request = harnessSnapshot(HarnessReviewRequestSchema.parse(input))
1052
+ this.validateNative(request, active)
1053
+ const pending = active.reviews.get(request.requestId)
1054
+ if (pending?.decision)
1055
+ throw new HarnessSessionError(
1056
+ 'reconciliation-required',
1057
+ 'A durable decision has no confirmed native resolution; it will not be sent again.',
1058
+ )
1059
+ if (pending) {
1060
+ if (pending.resolved || pending.digest !== harnessDigest(request))
1061
+ throw new HarnessSessionError(
1062
+ 'reconciliation-required',
1063
+ 'Native pending review contradicts its recorded request or resolution.',
1064
+ )
1065
+ if (!pending.presented) {
1066
+ await this.review(pending.request)
1067
+ pending.presented = true
1068
+ }
1069
+ } else await this.consume({ kind: 'review-requested', request })
1070
+ }
1071
+ const pendingIds = new Set(snapshot.pendingReviews.map((request) => request.requestId))
1072
+ if (
1073
+ [...active.reviews.values()].some(
1074
+ (request) => !request.resolved && !pendingIds.has(request.request.requestId),
1075
+ )
1076
+ )
1077
+ throw new HarnessSessionError(
1078
+ 'reconciliation-required',
1079
+ 'Native history did not prove the resolution of a recorded pending review.',
1080
+ )
1081
+ this.phase = [...active.reviews.values()].some((r) => !r.resolved) ? 'waiting' : 'running'
1082
+ }
1083
+ async close(): Promise<void> {
1084
+ if (this.phase === 'closed') return
1085
+ const release = this.reserve()
1086
+ try {
1087
+ if (this.connection) {
1088
+ await this.connection.close() // failure retains the exact cleanup authority and writer
1089
+ this.connection = undefined
1090
+ ++this.epoch
1091
+ }
1092
+ await this.events
1093
+ if (this.active && !(await this.journal.log.activeTurn())) {
1094
+ this.active.removeAbort?.()
1095
+ this.active.reject(
1096
+ new HarnessSessionError(
1097
+ 'terminal-recorded',
1098
+ 'The native terminal was recorded before its live notification failed.',
1099
+ ),
1100
+ )
1101
+ this.active = undefined
1102
+ }
1103
+ if (this.active?.nativeTurn)
1104
+ await this.finish(this.active, {
1105
+ kind: 'turn-completed',
1106
+ ...this.active.nativeTurn,
1107
+ status: 'cancelled',
1108
+ })
1109
+ else if (this.active) {
1110
+ this.active.removeAbort?.()
1111
+ this.active.reject(
1112
+ new HarnessSessionError(
1113
+ 'reconciliation-required',
1114
+ 'Unacknowledged dispatch remains unresolved in the durable log.',
1115
+ ),
1116
+ )
1117
+ this.active = undefined
1118
+ }
1119
+ await this.journal.release()
1120
+ this.phase = 'closed'
1121
+ } finally {
1122
+ release()
1123
+ }
1124
+ }
1125
+ }