@m4ike1/ion-agent-core 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (370) hide show
  1. package/README.md +622 -0
  2. package/dist/agent-loop.d.ts +24 -0
  3. package/dist/agent-loop.d.ts.map +1 -0
  4. package/dist/agent-loop.js +560 -0
  5. package/dist/agent-loop.js.map +1 -0
  6. package/dist/agent.d.ts +122 -0
  7. package/dist/agent.d.ts.map +1 -0
  8. package/dist/agent.js +422 -0
  9. package/dist/agent.js.map +1 -0
  10. package/dist/harness/agent-harness.d.ts +716 -0
  11. package/dist/harness/agent-harness.d.ts.map +1 -0
  12. package/dist/harness/agent-harness.js +6 -0
  13. package/dist/harness/agent-harness.js.map +1 -0
  14. package/dist/harness/compaction/branch-summarization.d.ts +68 -0
  15. package/dist/harness/compaction/branch-summarization.d.ts.map +1 -0
  16. package/dist/harness/compaction/branch-summarization.js +176 -0
  17. package/dist/harness/compaction/branch-summarization.js.map +1 -0
  18. package/dist/harness/compaction/compaction.d.ts +126 -0
  19. package/dist/harness/compaction/compaction.d.ts.map +1 -0
  20. package/dist/harness/compaction/compaction.js +560 -0
  21. package/dist/harness/compaction/compaction.js.map +1 -0
  22. package/dist/harness/compaction/utils.d.ts +25 -0
  23. package/dist/harness/compaction/utils.d.ts.map +1 -0
  24. package/dist/harness/compaction/utils.js +120 -0
  25. package/dist/harness/compaction/utils.js.map +1 -0
  26. package/dist/harness/config.d.ts +9 -0
  27. package/dist/harness/config.d.ts.map +1 -0
  28. package/dist/harness/config.js +35 -0
  29. package/dist/harness/config.js.map +1 -0
  30. package/dist/harness/context.d.ts +9 -0
  31. package/dist/harness/context.d.ts.map +1 -0
  32. package/dist/harness/context.js +13 -0
  33. package/dist/harness/context.js.map +1 -0
  34. package/dist/harness/env/nodejs.d.ts +43 -0
  35. package/dist/harness/env/nodejs.d.ts.map +1 -0
  36. package/dist/harness/env/nodejs.js +865 -0
  37. package/dist/harness/env/nodejs.js.map +1 -0
  38. package/dist/harness/events.d.ts +25 -0
  39. package/dist/harness/events.d.ts.map +1 -0
  40. package/dist/harness/events.js +250 -0
  41. package/dist/harness/events.js.map +1 -0
  42. package/dist/harness/execution/assistant.d.ts +42 -0
  43. package/dist/harness/execution/assistant.d.ts.map +1 -0
  44. package/dist/harness/execution/assistant.js +82 -0
  45. package/dist/harness/execution/assistant.js.map +1 -0
  46. package/dist/harness/execution/effect-gate.d.ts +22 -0
  47. package/dist/harness/execution/effect-gate.d.ts.map +1 -0
  48. package/dist/harness/execution/effect-gate.js +49 -0
  49. package/dist/harness/execution/effect-gate.js.map +1 -0
  50. package/dist/harness/execution/tools.d.ts +67 -0
  51. package/dist/harness/execution/tools.d.ts.map +1 -0
  52. package/dist/harness/execution/tools.js +121 -0
  53. package/dist/harness/execution/tools.js.map +1 -0
  54. package/dist/harness/hooks.d.ts +38 -0
  55. package/dist/harness/hooks.d.ts.map +1 -0
  56. package/dist/harness/hooks.js +406 -0
  57. package/dist/harness/hooks.js.map +1 -0
  58. package/dist/harness/messages.d.ts +51 -0
  59. package/dist/harness/messages.d.ts.map +1 -0
  60. package/dist/harness/messages.js +102 -0
  61. package/dist/harness/messages.js.map +1 -0
  62. package/dist/harness/prompt-templates.d.ts +49 -0
  63. package/dist/harness/prompt-templates.d.ts.map +1 -0
  64. package/dist/harness/prompt-templates.js +225 -0
  65. package/dist/harness/prompt-templates.js.map +1 -0
  66. package/dist/harness/result.d.ts +133 -0
  67. package/dist/harness/result.d.ts.map +1 -0
  68. package/dist/harness/result.js +81 -0
  69. package/dist/harness/result.js.map +1 -0
  70. package/dist/harness/runtime/drive/boundary.d.ts +28 -0
  71. package/dist/harness/runtime/drive/boundary.d.ts.map +1 -0
  72. package/dist/harness/runtime/drive/boundary.js +173 -0
  73. package/dist/harness/runtime/drive/boundary.js.map +1 -0
  74. package/dist/harness/runtime/drive/checkpoint.d.ts +8 -0
  75. package/dist/harness/runtime/drive/checkpoint.d.ts.map +1 -0
  76. package/dist/harness/runtime/drive/checkpoint.js +133 -0
  77. package/dist/harness/runtime/drive/checkpoint.js.map +1 -0
  78. package/dist/harness/runtime/drive/deferred.d.ts +15 -0
  79. package/dist/harness/runtime/drive/deferred.d.ts.map +1 -0
  80. package/dist/harness/runtime/drive/deferred.js +179 -0
  81. package/dist/harness/runtime/drive/deferred.js.map +1 -0
  82. package/dist/harness/runtime/drive/generation.d.ts +8 -0
  83. package/dist/harness/runtime/drive/generation.d.ts.map +1 -0
  84. package/dist/harness/runtime/drive/generation.js +205 -0
  85. package/dist/harness/runtime/drive/generation.js.map +1 -0
  86. package/dist/harness/runtime/drive/reconcile.d.ts +5 -0
  87. package/dist/harness/runtime/drive/reconcile.d.ts.map +1 -0
  88. package/dist/harness/runtime/drive/reconcile.js +140 -0
  89. package/dist/harness/runtime/drive/reconcile.js.map +1 -0
  90. package/dist/harness/runtime/drive/recovery.d.ts +8 -0
  91. package/dist/harness/runtime/drive/recovery.d.ts.map +1 -0
  92. package/dist/harness/runtime/drive/recovery.js +85 -0
  93. package/dist/harness/runtime/drive/recovery.js.map +1 -0
  94. package/dist/harness/runtime/drive/response.d.ts +23 -0
  95. package/dist/harness/runtime/drive/response.d.ts.map +1 -0
  96. package/dist/harness/runtime/drive/response.js +394 -0
  97. package/dist/harness/runtime/drive/response.js.map +1 -0
  98. package/dist/harness/runtime/drive/retry.d.ts +4 -0
  99. package/dist/harness/runtime/drive/retry.d.ts.map +1 -0
  100. package/dist/harness/runtime/drive/retry.js +34 -0
  101. package/dist/harness/runtime/drive/retry.js.map +1 -0
  102. package/dist/harness/runtime/drive/structural.d.ts +32 -0
  103. package/dist/harness/runtime/drive/structural.d.ts.map +1 -0
  104. package/dist/harness/runtime/drive/structural.js +929 -0
  105. package/dist/harness/runtime/drive/structural.js.map +1 -0
  106. package/dist/harness/runtime/drive/terminal.d.ts +7 -0
  107. package/dist/harness/runtime/drive/terminal.d.ts.map +1 -0
  108. package/dist/harness/runtime/drive/terminal.js +49 -0
  109. package/dist/harness/runtime/drive/terminal.js.map +1 -0
  110. package/dist/harness/runtime/drive/tool-placement.d.ts +14 -0
  111. package/dist/harness/runtime/drive/tool-placement.d.ts.map +1 -0
  112. package/dist/harness/runtime/drive/tool-placement.js +244 -0
  113. package/dist/harness/runtime/drive/tool-placement.js.map +1 -0
  114. package/dist/harness/runtime/drive/tools.d.ts +6 -0
  115. package/dist/harness/runtime/drive/tools.d.ts.map +1 -0
  116. package/dist/harness/runtime/drive/tools.js +449 -0
  117. package/dist/harness/runtime/drive/tools.js.map +1 -0
  118. package/dist/harness/runtime/drive.d.ts +6 -0
  119. package/dist/harness/runtime/drive.d.ts.map +1 -0
  120. package/dist/harness/runtime/drive.js +93 -0
  121. package/dist/harness/runtime/drive.js.map +1 -0
  122. package/dist/harness/runtime/harness.d.ts +59 -0
  123. package/dist/harness/runtime/harness.d.ts.map +1 -0
  124. package/dist/harness/runtime/harness.js +311 -0
  125. package/dist/harness/runtime/harness.js.map +1 -0
  126. package/dist/harness/runtime/index.d.ts +2 -0
  127. package/dist/harness/runtime/index.d.ts.map +1 -0
  128. package/dist/harness/runtime/index.js +2 -0
  129. package/dist/harness/runtime/index.js.map +1 -0
  130. package/dist/harness/runtime/lane.d.ts +101 -0
  131. package/dist/harness/runtime/lane.d.ts.map +1 -0
  132. package/dist/harness/runtime/lane.js +1575 -0
  133. package/dist/harness/runtime/lane.js.map +1 -0
  134. package/dist/harness/runtime/progress.d.ts +15 -0
  135. package/dist/harness/runtime/progress.d.ts.map +1 -0
  136. package/dist/harness/runtime/progress.js +66 -0
  137. package/dist/harness/runtime/progress.js.map +1 -0
  138. package/dist/harness/runtime/reducer.d.ts +5 -0
  139. package/dist/harness/runtime/reducer.d.ts.map +1 -0
  140. package/dist/harness/runtime/reducer.js +240 -0
  141. package/dist/harness/runtime/reducer.js.map +1 -0
  142. package/dist/harness/runtime/restore.d.ts +24 -0
  143. package/dist/harness/runtime/restore.d.ts.map +1 -0
  144. package/dist/harness/runtime/restore.js +117 -0
  145. package/dist/harness/runtime/restore.js.map +1 -0
  146. package/dist/harness/runtime/transcript.d.ts +21 -0
  147. package/dist/harness/runtime/transcript.d.ts.map +1 -0
  148. package/dist/harness/runtime/transcript.js +72 -0
  149. package/dist/harness/runtime/transcript.js.map +1 -0
  150. package/dist/harness/runtime/types.d.ts +105 -0
  151. package/dist/harness/runtime/types.d.ts.map +1 -0
  152. package/dist/harness/runtime/types.js +61 -0
  153. package/dist/harness/runtime/types.js.map +1 -0
  154. package/dist/harness/session/commit.d.ts +53 -0
  155. package/dist/harness/session/commit.d.ts.map +1 -0
  156. package/dist/harness/session/commit.js +57 -0
  157. package/dist/harness/session/commit.js.map +1 -0
  158. package/dist/harness/session/context.d.ts +10 -0
  159. package/dist/harness/session/context.d.ts.map +1 -0
  160. package/dist/harness/session/context.js +49 -0
  161. package/dist/harness/session/context.js.map +1 -0
  162. package/dist/harness/session/fork-policy.d.ts +21 -0
  163. package/dist/harness/session/fork-policy.d.ts.map +1 -0
  164. package/dist/harness/session/fork-policy.js +55 -0
  165. package/dist/harness/session/fork-policy.js.map +1 -0
  166. package/dist/harness/session/fork.d.ts +16 -0
  167. package/dist/harness/session/fork.d.ts.map +1 -0
  168. package/dist/harness/session/fork.js +79 -0
  169. package/dist/harness/session/fork.js.map +1 -0
  170. package/dist/harness/session/in-memory-storage-state.d.ts +39 -0
  171. package/dist/harness/session/in-memory-storage-state.d.ts.map +1 -0
  172. package/dist/harness/session/in-memory-storage-state.js +276 -0
  173. package/dist/harness/session/in-memory-storage-state.js.map +1 -0
  174. package/dist/harness/session/index.d.ts +11 -0
  175. package/dist/harness/session/index.d.ts.map +1 -0
  176. package/dist/harness/session/index.js +9 -0
  177. package/dist/harness/session/index.js.map +1 -0
  178. package/dist/harness/session/jsonl/codec.d.ts +21 -0
  179. package/dist/harness/session/jsonl/codec.d.ts.map +1 -0
  180. package/dist/harness/session/jsonl/codec.js +45 -0
  181. package/dist/harness/session/jsonl/codec.js.map +1 -0
  182. package/dist/harness/session/jsonl/fork.d.ts +38 -0
  183. package/dist/harness/session/jsonl/fork.d.ts.map +1 -0
  184. package/dist/harness/session/jsonl/fork.js +264 -0
  185. package/dist/harness/session/jsonl/fork.js.map +1 -0
  186. package/dist/harness/session/jsonl/index.d.ts +4 -0
  187. package/dist/harness/session/jsonl/index.d.ts.map +1 -0
  188. package/dist/harness/session/jsonl/index.js +4 -0
  189. package/dist/harness/session/jsonl/index.js.map +1 -0
  190. package/dist/harness/session/jsonl/io.d.ts +14 -0
  191. package/dist/harness/session/jsonl/io.d.ts.map +1 -0
  192. package/dist/harness/session/jsonl/io.js +86 -0
  193. package/dist/harness/session/jsonl/io.js.map +1 -0
  194. package/dist/harness/session/jsonl/legacy-v3.d.ts +43 -0
  195. package/dist/harness/session/jsonl/legacy-v3.d.ts.map +1 -0
  196. package/dist/harness/session/jsonl/legacy-v3.js +462 -0
  197. package/dist/harness/session/jsonl/legacy-v3.js.map +1 -0
  198. package/dist/harness/session/jsonl/repo.d.ts +35 -0
  199. package/dist/harness/session/jsonl/repo.d.ts.map +1 -0
  200. package/dist/harness/session/jsonl/repo.js +301 -0
  201. package/dist/harness/session/jsonl/repo.js.map +1 -0
  202. package/dist/harness/session/jsonl/storage.d.ts +40 -0
  203. package/dist/harness/session/jsonl/storage.d.ts.map +1 -0
  204. package/dist/harness/session/jsonl/storage.js +200 -0
  205. package/dist/harness/session/jsonl/storage.js.map +1 -0
  206. package/dist/harness/session/jsonl/types.d.ts +39 -0
  207. package/dist/harness/session/jsonl/types.d.ts.map +1 -0
  208. package/dist/harness/session/jsonl/types.js +3 -0
  209. package/dist/harness/session/jsonl/types.js.map +1 -0
  210. package/dist/harness/session/memory.d.ts +48 -0
  211. package/dist/harness/session/memory.d.ts.map +1 -0
  212. package/dist/harness/session/memory.js +369 -0
  213. package/dist/harness/session/memory.js.map +1 -0
  214. package/dist/harness/session/mutation-line.d.ts +8 -0
  215. package/dist/harness/session/mutation-line.d.ts.map +1 -0
  216. package/dist/harness/session/mutation-line.js +21 -0
  217. package/dist/harness/session/mutation-line.js.map +1 -0
  218. package/dist/harness/session/session.d.ts +82 -0
  219. package/dist/harness/session/session.d.ts.map +1 -0
  220. package/dist/harness/session/session.js +361 -0
  221. package/dist/harness/session/session.js.map +1 -0
  222. package/dist/harness/session/testing/benchmark/datasets.d.ts +12 -0
  223. package/dist/harness/session/testing/benchmark/datasets.d.ts.map +1 -0
  224. package/dist/harness/session/testing/benchmark/datasets.js +24 -0
  225. package/dist/harness/session/testing/benchmark/datasets.js.map +1 -0
  226. package/dist/harness/session/testing/benchmark/session-repo.d.ts +42 -0
  227. package/dist/harness/session/testing/benchmark/session-repo.d.ts.map +1 -0
  228. package/dist/harness/session/testing/benchmark/session-repo.js +127 -0
  229. package/dist/harness/session/testing/benchmark/session-repo.js.map +1 -0
  230. package/dist/harness/session/testing/benchmark/storage.d.ts +25 -0
  231. package/dist/harness/session/testing/benchmark/storage.d.ts.map +1 -0
  232. package/dist/harness/session/testing/benchmark/storage.js +114 -0
  233. package/dist/harness/session/testing/benchmark/storage.js.map +1 -0
  234. package/dist/harness/session/testing/conformance/session-repo.d.ts +23 -0
  235. package/dist/harness/session/testing/conformance/session-repo.d.ts.map +1 -0
  236. package/dist/harness/session/testing/conformance/session-repo.js +809 -0
  237. package/dist/harness/session/testing/conformance/session-repo.js.map +1 -0
  238. package/dist/harness/session/testing/conformance/storage.d.ts +4 -0
  239. package/dist/harness/session/testing/conformance/storage.d.ts.map +1 -0
  240. package/dist/harness/session/testing/conformance/storage.js +600 -0
  241. package/dist/harness/session/testing/conformance/storage.js.map +1 -0
  242. package/dist/harness/session/testing/gating-storage.d.ts +26 -0
  243. package/dist/harness/session/testing/gating-storage.d.ts.map +1 -0
  244. package/dist/harness/session/testing/gating-storage.js +100 -0
  245. package/dist/harness/session/testing/gating-storage.js.map +1 -0
  246. package/dist/harness/session/testing/index.d.ts +10 -0
  247. package/dist/harness/session/testing/index.d.ts.map +1 -0
  248. package/dist/harness/session/testing/index.js +9 -0
  249. package/dist/harness/session/testing/index.js.map +1 -0
  250. package/dist/harness/session/testing/instrumented-storage.d.ts +11 -0
  251. package/dist/harness/session/testing/instrumented-storage.d.ts.map +1 -0
  252. package/dist/harness/session/testing/instrumented-storage.js +16 -0
  253. package/dist/harness/session/testing/instrumented-storage.js.map +1 -0
  254. package/dist/harness/session/testing/storage-decorator.d.ts +20 -0
  255. package/dist/harness/session/testing/storage-decorator.d.ts.map +1 -0
  256. package/dist/harness/session/testing/storage-decorator.js +41 -0
  257. package/dist/harness/session/testing/storage-decorator.js.map +1 -0
  258. package/dist/harness/session/testing/types.d.ts +12 -0
  259. package/dist/harness/session/testing/types.d.ts.map +1 -0
  260. package/dist/harness/session/testing/types.js +2 -0
  261. package/dist/harness/session/testing/types.js.map +1 -0
  262. package/dist/harness/session/types.d.ts +512 -0
  263. package/dist/harness/session/types.d.ts.map +1 -0
  264. package/dist/harness/session/types.js +9 -0
  265. package/dist/harness/session/types.js.map +1 -0
  266. package/dist/harness/session/values.d.ts +95 -0
  267. package/dist/harness/session/values.d.ts.map +1 -0
  268. package/dist/harness/session/values.js +81 -0
  269. package/dist/harness/session/values.js.map +1 -0
  270. package/dist/harness/skills.d.ts +46 -0
  271. package/dist/harness/skills.d.ts.map +1 -0
  272. package/dist/harness/skills.js +326 -0
  273. package/dist/harness/skills.js.map +1 -0
  274. package/dist/harness/system-prompt.d.ts +3 -0
  275. package/dist/harness/system-prompt.d.ts.map +1 -0
  276. package/dist/harness/system-prompt.js +30 -0
  277. package/dist/harness/system-prompt.js.map +1 -0
  278. package/dist/harness/telemetry.d.ts +1242 -0
  279. package/dist/harness/telemetry.d.ts.map +1 -0
  280. package/dist/harness/telemetry.js +527 -0
  281. package/dist/harness/telemetry.js.map +1 -0
  282. package/dist/harness/tools/bash.d.ts +27 -0
  283. package/dist/harness/tools/bash.d.ts.map +1 -0
  284. package/dist/harness/tools/bash.js +105 -0
  285. package/dist/harness/tools/bash.js.map +1 -0
  286. package/dist/harness/tools/edit-diff.d.ts +89 -0
  287. package/dist/harness/tools/edit-diff.d.ts.map +1 -0
  288. package/dist/harness/tools/edit-diff.js +386 -0
  289. package/dist/harness/tools/edit-diff.js.map +1 -0
  290. package/dist/harness/tools/edit.d.ts +19 -0
  291. package/dist/harness/tools/edit.d.ts.map +1 -0
  292. package/dist/harness/tools/edit.js +108 -0
  293. package/dist/harness/tools/edit.js.map +1 -0
  294. package/dist/harness/tools/file-mutation-queue.d.ts +5 -0
  295. package/dist/harness/tools/file-mutation-queue.d.ts.map +1 -0
  296. package/dist/harness/tools/file-mutation-queue.js +46 -0
  297. package/dist/harness/tools/file-mutation-queue.js.map +1 -0
  298. package/dist/harness/tools/image.d.ts +3 -0
  299. package/dist/harness/tools/image.d.ts.map +1 -0
  300. package/dist/harness/tools/image.js +106 -0
  301. package/dist/harness/tools/image.js.map +1 -0
  302. package/dist/harness/tools/index.d.ts +6 -0
  303. package/dist/harness/tools/index.d.ts.map +1 -0
  304. package/dist/harness/tools/index.js +5 -0
  305. package/dist/harness/tools/index.js.map +1 -0
  306. package/dist/harness/tools/path-utils.d.ts +5 -0
  307. package/dist/harness/tools/path-utils.d.ts.map +1 -0
  308. package/dist/harness/tools/path-utils.js +26 -0
  309. package/dist/harness/tools/path-utils.js.map +1 -0
  310. package/dist/harness/tools/read.d.ts +35 -0
  311. package/dist/harness/tools/read.d.ts.map +1 -0
  312. package/dist/harness/tools/read.js +108 -0
  313. package/dist/harness/tools/read.js.map +1 -0
  314. package/dist/harness/tools/tool-context.d.ts +6 -0
  315. package/dist/harness/tools/tool-context.d.ts.map +1 -0
  316. package/dist/harness/tools/tool-context.js +2 -0
  317. package/dist/harness/tools/tool-context.js.map +1 -0
  318. package/dist/harness/tools/write.d.ts +11 -0
  319. package/dist/harness/tools/write.d.ts.map +1 -0
  320. package/dist/harness/tools/write.js +31 -0
  321. package/dist/harness/tools/write.js.map +1 -0
  322. package/dist/harness/types.d.ts +305 -0
  323. package/dist/harness/types.d.ts.map +1 -0
  324. package/dist/harness/types.js +75 -0
  325. package/dist/harness/types.js.map +1 -0
  326. package/dist/harness/utils/adaptive-publisher.d.ts +24 -0
  327. package/dist/harness/utils/adaptive-publisher.d.ts.map +1 -0
  328. package/dist/harness/utils/adaptive-publisher.js +79 -0
  329. package/dist/harness/utils/adaptive-publisher.js.map +1 -0
  330. package/dist/harness/utils/output-capture.d.ts +31 -0
  331. package/dist/harness/utils/output-capture.d.ts.map +1 -0
  332. package/dist/harness/utils/output-capture.js +217 -0
  333. package/dist/harness/utils/output-capture.js.map +1 -0
  334. package/dist/harness/utils/shell-output.d.ts +29 -0
  335. package/dist/harness/utils/shell-output.d.ts.map +1 -0
  336. package/dist/harness/utils/shell-output.js +71 -0
  337. package/dist/harness/utils/shell-output.js.map +1 -0
  338. package/dist/harness/utils/truncate.d.ts +71 -0
  339. package/dist/harness/utils/truncate.d.ts.map +1 -0
  340. package/dist/harness/utils/truncate.js +296 -0
  341. package/dist/harness/utils/truncate.js.map +1 -0
  342. package/dist/harness/utils/usage.d.ts +4 -0
  343. package/dist/harness/utils/usage.d.ts.map +1 -0
  344. package/dist/harness/utils/usage.js +33 -0
  345. package/dist/harness/utils/usage.js.map +1 -0
  346. package/dist/index.d.ts +28 -0
  347. package/dist/index.d.ts.map +1 -0
  348. package/dist/index.js +26 -0
  349. package/dist/index.js.map +1 -0
  350. package/dist/node.d.ts +3 -0
  351. package/dist/node.d.ts.map +1 -0
  352. package/dist/node.js +3 -0
  353. package/dist/node.js.map +1 -0
  354. package/dist/proxy.d.ts +72 -0
  355. package/dist/proxy.d.ts.map +1 -0
  356. package/dist/proxy.js +310 -0
  357. package/dist/proxy.js.map +1 -0
  358. package/dist/search/index.d.ts +29 -0
  359. package/dist/search/index.d.ts.map +1 -0
  360. package/dist/search/index.js +2 -0
  361. package/dist/search/index.js.map +1 -0
  362. package/dist/stream-fn.d.ts +10 -0
  363. package/dist/stream-fn.d.ts.map +1 -0
  364. package/dist/stream-fn.js +17 -0
  365. package/dist/stream-fn.js.map +1 -0
  366. package/dist/types.d.ts +416 -0
  367. package/dist/types.d.ts.map +1 -0
  368. package/dist/types.js +2 -0
  369. package/dist/types.js.map +1 -0
  370. package/package.json +89 -0
@@ -0,0 +1,369 @@
1
+ import { uuidv7 } from "@m4ike1/ion-ai/utils/uuid";
2
+ import { InMemoryStorageState } from "./in-memory-storage-state.js";
3
+ import { StorageBackedSession } from "./session.js";
4
+ export class MemoryStorage {
5
+ now;
6
+ storageState = new InMemoryStorageState();
7
+ commitQueue = Promise.resolve();
8
+ state = "open";
9
+ closePromise;
10
+ constructor(options = {}) {
11
+ this.now = options.now ?? Date.now;
12
+ }
13
+ async commit(writes, _context) {
14
+ if (this.state !== "open")
15
+ throw new Error("MemoryStorage is closed");
16
+ const result = this.commitQueue.then(() => {
17
+ const prepared = this.storageState.prepareCommit(writes, this.now());
18
+ const stats = this.storageState.applyValidated(prepared.writes);
19
+ return { ...prepared.result, stats };
20
+ });
21
+ this.commitQueue = result.then(() => undefined, () => undefined);
22
+ return result;
23
+ }
24
+ getEntries(ids, _context) {
25
+ if (this.state !== "open")
26
+ return Promise.reject(new Error("MemoryStorage is closed"));
27
+ return Promise.resolve(this.storageState.getEntries(ids));
28
+ }
29
+ getValue(address, _context) {
30
+ if (this.state !== "open")
31
+ return Promise.reject(new Error("MemoryStorage is closed"));
32
+ return Promise.resolve(this.storageState.getValue(address));
33
+ }
34
+ scanValues(prefix, _context) {
35
+ if (this.state !== "open")
36
+ return Promise.reject(new Error("MemoryStorage is closed"));
37
+ return Promise.resolve(this.storageState.scanValues(prefix));
38
+ }
39
+ async readList(address, options, _context) {
40
+ if (this.state !== "open")
41
+ throw new Error("MemoryStorage is closed");
42
+ return this.storageState.readList(address, options);
43
+ }
44
+ async scanBranch(query, _context) {
45
+ if (this.state !== "open")
46
+ throw new Error("MemoryStorage is closed");
47
+ return this.storageState.scanBranch(query);
48
+ }
49
+ async scanBranchStructure(query, _context) {
50
+ if (this.state !== "open")
51
+ throw new Error("MemoryStorage is closed");
52
+ return this.storageState.scanBranchStructure(query);
53
+ }
54
+ scanEntries(query, _context) {
55
+ if (this.state !== "open")
56
+ return Promise.reject(new Error("MemoryStorage is closed"));
57
+ return Promise.resolve(this.storageState.scanEntries(query));
58
+ }
59
+ scanUsage(query, _context) {
60
+ if (this.state !== "open")
61
+ return Promise.reject(new Error("MemoryStorage is closed"));
62
+ return Promise.resolve(this.storageState.scanUsage(query));
63
+ }
64
+ getStats(_context) {
65
+ if (this.state !== "open")
66
+ return Promise.reject(new Error("MemoryStorage is closed"));
67
+ return Promise.resolve(this.storageState.getStats());
68
+ }
69
+ /** Construct a destination storage at one serialized boundary between source commits. */
70
+ fork(options) {
71
+ if (this.state !== "open")
72
+ return Promise.reject(new Error("MemoryStorage is closed"));
73
+ const result = this.commitQueue.then(() => {
74
+ const destination = new MemoryStorage({ now: this.now });
75
+ destination.storageState = this.storageState.createFork(options);
76
+ return destination;
77
+ });
78
+ this.commitQueue = result.then(() => undefined, () => undefined);
79
+ return result;
80
+ }
81
+ close(_context) {
82
+ if (this.closePromise !== undefined)
83
+ return this.closePromise;
84
+ this.state = "closing";
85
+ this.closePromise = this.commitQueue.then(() => {
86
+ this.state = "closed";
87
+ });
88
+ return this.closePromise;
89
+ }
90
+ }
91
+ const MEMORY_STORAGE_VERSION = 1;
92
+ class MemorySessionFacade {
93
+ metadata;
94
+ idGenerator;
95
+ session;
96
+ onClose;
97
+ admitted = new Set();
98
+ closedError = new Error("Session is closed");
99
+ state = "open";
100
+ closePromise;
101
+ constructor(session, onClose) {
102
+ this.session = session;
103
+ this.metadata = session.metadata;
104
+ this.idGenerator = session.idGenerator;
105
+ this.onClose = onClose;
106
+ }
107
+ async beginMutation(context) {
108
+ let resolveFinished;
109
+ const finished = new Promise((resolve) => {
110
+ resolveFinished = resolve;
111
+ });
112
+ this.admitted.add(finished);
113
+ let source;
114
+ try {
115
+ source = await this.admit(() => this.session.beginMutation(context));
116
+ }
117
+ catch (error) {
118
+ this.admitted.delete(finished);
119
+ resolveFinished();
120
+ throw error;
121
+ }
122
+ if (this.state !== "open") {
123
+ await source.end(context);
124
+ this.admitted.delete(finished);
125
+ resolveFinished();
126
+ throw this.closedError;
127
+ }
128
+ let ended = false;
129
+ return {
130
+ commit: (writes, commitContext) => source.commit(writes, commitContext),
131
+ end: async (endContext) => {
132
+ try {
133
+ await source.end(endContext);
134
+ }
135
+ finally {
136
+ if (!ended) {
137
+ ended = true;
138
+ this.admitted.delete(finished);
139
+ resolveFinished();
140
+ }
141
+ }
142
+ },
143
+ getEntries: (ids, readContext) => source.getEntries(ids, readContext),
144
+ getStats: (readContext) => source.getStats(readContext),
145
+ getValue: (address, readContext) => source.getValue(address, readContext),
146
+ scanValues: (prefix, readContext) => source.scanValues(prefix, readContext),
147
+ readList: (address, options, readContext) => source.readList(address, options, readContext),
148
+ scanBranch: (query, readContext) => source.scanBranch(query, readContext),
149
+ };
150
+ }
151
+ mutate(mutation, context) {
152
+ return this.admit(() => this.session.mutate((mutator, mutationContext) => {
153
+ if (this.state !== "open")
154
+ throw this.closedError;
155
+ return mutation(mutator, mutationContext);
156
+ }, context));
157
+ }
158
+ getEntries(ids, context) {
159
+ return this.admit(() => this.session.getEntries(ids, context));
160
+ }
161
+ getEntry(id, context) {
162
+ return this.admit(() => this.session.getEntry(id, context));
163
+ }
164
+ getValue(address, context) {
165
+ return this.admit(() => this.session.getValue(address, context));
166
+ }
167
+ scanValues(prefix, context) {
168
+ return this.admit(() => this.session.scanValues(prefix, context));
169
+ }
170
+ readList(address, options, context) {
171
+ return this.admit(() => this.session.readList(address, options, context));
172
+ }
173
+ scanBranch(query, context) {
174
+ return this.admit(() => this.session.scanBranch(query, context));
175
+ }
176
+ getStats(context) {
177
+ return this.admit(() => this.session.getStats(context));
178
+ }
179
+ getName(context) {
180
+ return this.admit(() => this.session.getName(context));
181
+ }
182
+ getLabel(targetId, context) {
183
+ return this.admit(() => this.session.getLabel(targetId, context));
184
+ }
185
+ findEntries(query, context) {
186
+ return this.admit(() => this.session.findEntries(query, context));
187
+ }
188
+ findEntry(query, context) {
189
+ return this.admit(() => this.session.findEntry(query, context));
190
+ }
191
+ async branch(name, context) {
192
+ const branch = await this.admit(() => this.session.branch(name, context));
193
+ return branch === undefined ? undefined : this.wrapBranch(branch);
194
+ }
195
+ async createBranch(name, at, context) {
196
+ return this.wrapBranch(await this.admit(() => this.session.createBranch(name, at, context)));
197
+ }
198
+ setValue(address, next, context) {
199
+ return this.admit(() => this.session.setValue(address, next, context));
200
+ }
201
+ deleteValue(address, context) {
202
+ return this.admit(() => this.session.deleteValue(address, context));
203
+ }
204
+ appendList(address, element, context) {
205
+ return this.admit(() => this.session.appendList(address, element, context));
206
+ }
207
+ deleteList(address, context) {
208
+ return this.admit(() => this.session.deleteList(address, context));
209
+ }
210
+ setName(name, context) {
211
+ return this.admit(() => this.session.setName(name, context));
212
+ }
213
+ setLabel(targetId, label, context) {
214
+ return this.admit(() => this.session.setLabel(targetId, label, context));
215
+ }
216
+ close(_context) {
217
+ if (this.closePromise !== undefined)
218
+ return this.closePromise;
219
+ this.state = "closing";
220
+ this.closePromise = Promise.allSettled([...this.admitted]).then(() => {
221
+ this.state = "closed";
222
+ this.onClose();
223
+ });
224
+ return this.closePromise;
225
+ }
226
+ wrapBranch(branch) {
227
+ return {
228
+ name: branch.name,
229
+ getTipId: (context) => this.admit(() => branch.getTipId(context)),
230
+ findEntries: (query, context) => this.admit(() => branch.findEntries(query, context)),
231
+ findEntry: (query, context) => this.admit(() => branch.findEntry(query, context)),
232
+ appendMessage: (message, context) => this.admit(() => branch.appendMessage(message, context)),
233
+ appendCustomEntry: (customType, data, context) => this.admit(() => branch.appendCustomEntry(customType, data, context)),
234
+ };
235
+ }
236
+ admit(operation) {
237
+ if (this.state !== "open")
238
+ return Promise.reject(this.closedError);
239
+ let result;
240
+ try {
241
+ result = operation();
242
+ }
243
+ catch (error) {
244
+ result = Promise.reject(error);
245
+ }
246
+ this.admitted.add(result);
247
+ void result.then(() => this.admitted.delete(result), () => this.admitted.delete(result));
248
+ return result;
249
+ }
250
+ }
251
+ export class MemorySessionRepo {
252
+ now;
253
+ sessions = new Map();
254
+ pendingIds = new Set();
255
+ closed = false;
256
+ closePromise;
257
+ constructor(options = {}) {
258
+ this.now = options.now ?? Date.now;
259
+ }
260
+ async create(options, context) {
261
+ this.assertOpen();
262
+ const createdAt = this.now();
263
+ const id = options.id ?? uuidv7(createdAt);
264
+ this.reserveId(id);
265
+ const metadata = {
266
+ id,
267
+ createdAt,
268
+ storageVersion: MEMORY_STORAGE_VERSION,
269
+ ...(options.parentSessionId === undefined ? {} : { parentSessionId: options.parentSessionId }),
270
+ };
271
+ const storage = new MemoryStorage({ now: this.now });
272
+ const session = new StorageBackedSession(metadata, storage);
273
+ try {
274
+ const record = {
275
+ metadata,
276
+ storage,
277
+ session,
278
+ open: true,
279
+ };
280
+ this.sessions.set(id, record);
281
+ return this.openRecord(record);
282
+ }
283
+ catch (error) {
284
+ await session.close(context);
285
+ throw error;
286
+ }
287
+ finally {
288
+ this.pendingIds.delete(id);
289
+ }
290
+ }
291
+ open(metadata, _context) {
292
+ // Memory sessions are always created at the current storage version, so
293
+ // persistent-backend version gating does not apply here.
294
+ this.assertOpen();
295
+ const record = this.sessions.get(metadata.id);
296
+ if (record === undefined)
297
+ return Promise.reject(new Error(`Unknown session: ${metadata.id}`));
298
+ if (record.open)
299
+ return Promise.reject(new Error(`Session is already open: ${metadata.id}`));
300
+ record.open = true;
301
+ return Promise.resolve(this.openRecord(record));
302
+ }
303
+ list(_options, _context) {
304
+ this.assertOpen();
305
+ return Promise.resolve([...this.sessions.values()].map(({ metadata }) => metadata));
306
+ }
307
+ async delete(metadata, context) {
308
+ this.assertOpen();
309
+ const record = this.sessions.get(metadata.id);
310
+ if (record === undefined)
311
+ throw new Error(`Unknown session: ${metadata.id}`);
312
+ if (record.open)
313
+ throw new Error(`Session is open: ${metadata.id}`);
314
+ await record.session.close(context);
315
+ this.sessions.delete(metadata.id);
316
+ }
317
+ async fork(source, options, _context) {
318
+ this.assertOpen();
319
+ const sourceRecord = this.sessions.get(source.id);
320
+ if (sourceRecord === undefined)
321
+ throw new Error(`Unknown session: ${source.id}`);
322
+ const createdAt = this.now();
323
+ const id = options.id ?? uuidv7(createdAt);
324
+ this.reserveId(id);
325
+ try {
326
+ const storage = await sourceRecord.storage.fork(options);
327
+ const metadata = {
328
+ id,
329
+ createdAt,
330
+ storageVersion: MEMORY_STORAGE_VERSION,
331
+ parentSessionId: sourceRecord.metadata.id,
332
+ };
333
+ const session = new StorageBackedSession(metadata, storage);
334
+ const record = {
335
+ metadata,
336
+ storage,
337
+ session,
338
+ open: true,
339
+ };
340
+ this.sessions.set(id, record);
341
+ return this.openRecord(record);
342
+ }
343
+ finally {
344
+ this.pendingIds.delete(id);
345
+ }
346
+ }
347
+ close(context) {
348
+ if (this.closePromise !== undefined)
349
+ return this.closePromise;
350
+ this.closed = true;
351
+ this.closePromise = Promise.all([...this.sessions.values()].map(({ session }) => session.close(context))).then(() => undefined);
352
+ return this.closePromise;
353
+ }
354
+ openRecord(record) {
355
+ return new MemorySessionFacade(record.session, () => {
356
+ record.open = false;
357
+ });
358
+ }
359
+ reserveId(id) {
360
+ if (this.sessions.has(id) || this.pendingIds.has(id))
361
+ throw new Error(`Session already exists: ${id}`);
362
+ this.pendingIds.add(id);
363
+ }
364
+ assertOpen() {
365
+ if (this.closed)
366
+ throw new Error("MemorySessionRepo is closed");
367
+ }
368
+ }
369
+ //# sourceMappingURL=memory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory.js","sourceRoot":"","sources":["../../../src/harness/session/memory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAC;AAEnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAiCpD,MAAM,OAAO,aAAa;IACR,GAAG,CAAe;IAC3B,YAAY,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC1C,WAAW,GAAkB,OAAO,CAAC,OAAO,EAAE,CAAC;IAC/C,KAAK,GAAkC,MAAM,CAAC;IAC9C,YAAY,CAA4B;IAEhD,YAAY,OAAO,GAAyB,EAAE,EAAE;QAC/C,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC;IAAA,CACnC;IAED,KAAK,CAAC,MAAM,CAAC,MAAe,EAAE,QAAiB,EAAyB;QACvE,IAAI,IAAI,CAAC,KAAK,KAAK,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;QACtE,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;YAC1C,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,CAAC,aAAa,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;YACrE,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;YAChE,OAAO,EAAE,GAAG,QAAQ,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC;QAAA,CACrC,CAAC,CAAC;QACH,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,IAAI,CAC7B,GAAG,EAAE,CAAC,SAAS,EACf,GAAG,EAAE,CAAC,SAAS,CACf,CAAC;QACF,OAAO,MAAM,CAAC;IAAA,CACd;IAED,UAAU,CAAC,GAAa,EAAE,QAAiB,EAA+B;QACzE,IAAI,IAAI,CAAC,KAAK,KAAK,MAAM;YAAE,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC,CAAC;QACvF,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;IAAA,CAC1D;IAED,QAAQ,CAAI,OAAiB,EAAE,QAAiB,EAAuC;QACtF,IAAI,IAAI,CAAC,KAAK,KAAK,MAAM;YAAE,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC,CAAC;QACvF,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;IAAA,CAC5D;IAED,UAAU,CAAI,MAAgB,EAAE,QAAiB,EAA6B;QAC7E,IAAI,IAAI,CAAC,KAAK,KAAK,MAAM;YAAE,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC,CAAC;QACvF,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;IAAA,CAC7D;IAED,KAAK,CAAC,QAAQ,CACb,OAAqB,EACrB,OAAoC,EACpC,QAAiB,EACW;QAC5B,IAAI,IAAI,CAAC,KAAK,KAAK,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;QACtE,OAAO,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAAA,CACpD;IAED,KAAK,CAAC,UAAU,CAAC,KAAwB,EAAE,QAAiB,EAAoB;QAC/E,IAAI,IAAI,CAAC,KAAK,KAAK,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;QACtE,OAAO,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;IAAA,CAC3C;IAED,KAAK,CAAC,mBAAmB,CAAC,KAAwB,EAAE,QAAiB,EAA6B;QACjG,IAAI,IAAI,CAAC,KAAK,KAAK,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;QACtE,OAAO,IAAI,CAAC,YAAY,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC;IAAA,CACpD;IAED,WAAW,CAAC,KAAgB,EAAE,QAAiB,EAAoB;QAClE,IAAI,IAAI,CAAC,KAAK,KAAK,MAAM;YAAE,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC,CAAC;QACvF,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;IAAA,CAC7D;IAED,SAAS,CAAC,KAAgB,EAAE,QAAiB,EAAuB;QACnE,IAAI,IAAI,CAAC,KAAK,KAAK,MAAM;YAAE,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC,CAAC;QACvF,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;IAAA,CAC3D;IAED,QAAQ,CAAC,QAAiB,EAAyB;QAClD,IAAI,IAAI,CAAC,KAAK,KAAK,MAAM;YAAE,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC,CAAC;QACvF,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,CAAC,CAAC;IAAA,CACrD;IAED,yFAAyF;IACzF,IAAI,CAAC,OAAoB,EAA0B;QAClD,IAAI,IAAI,CAAC,KAAK,KAAK,MAAM;YAAE,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC,CAAC;QACvF,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;YAC1C,MAAM,WAAW,GAAG,IAAI,aAAa,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;YACzD,WAAW,CAAC,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;YACjE,OAAO,WAAW,CAAC;QAAA,CACnB,CAAC,CAAC;QACH,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,IAAI,CAC7B,GAAG,EAAE,CAAC,SAAS,EACf,GAAG,EAAE,CAAC,SAAS,CACf,CAAC;QACF,OAAO,MAAM,CAAC;IAAA,CACd;IAED,KAAK,CAAC,QAAiB,EAAiB;QACvC,IAAI,IAAI,CAAC,YAAY,KAAK,SAAS;YAAE,OAAO,IAAI,CAAC,YAAY,CAAC;QAC9D,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC;QACvB,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;YAC/C,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAC;QAAA,CACtB,CAAC,CAAC;QACH,OAAO,IAAI,CAAC,YAAY,CAAC;IAAA,CACzB;CACD;AAED,MAAM,sBAAsB,GAAG,CAAC,CAAC;AASjC,MAAM,mBAAmB;IACf,QAAQ,CAAkB;IAC1B,WAAW,CAAc;IACjB,OAAO,CAAuB;IAC9B,OAAO,CAAa;IACpB,QAAQ,GAAG,IAAI,GAAG,EAAoB,CAAC;IACvC,WAAW,GAAG,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;IACtD,KAAK,GAAkC,MAAM,CAAC;IAC9C,YAAY,CAA4B;IAEhD,YAAY,OAA6B,EAAE,OAAmB,EAAE;QAC/D,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;QACjC,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;QACvC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IAAA,CACvB;IAED,KAAK,CAAC,aAAa,CAAC,OAAgB,EAA4B;QAC/D,IAAI,eAA4B,CAAC;QACjC,MAAM,QAAQ,GAAG,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC;YAC/C,eAAe,GAAG,OAAO,CAAC;QAAA,CAC1B,CAAC,CAAC;QACH,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC5B,IAAI,MAAuB,CAAC;QAC5B,IAAI,CAAC;YACJ,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC;QACtE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAC/B,eAAe,EAAE,CAAC;YAClB,MAAM,KAAK,CAAC;QACb,CAAC;QACD,IAAI,IAAI,CAAC,KAAK,KAAK,MAAM,EAAE,CAAC;YAC3B,MAAM,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YAC1B,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAC/B,eAAe,EAAE,CAAC;YAClB,MAAM,IAAI,CAAC,WAAW,CAAC;QACxB,CAAC;QACD,IAAI,KAAK,GAAG,KAAK,CAAC;QAClB,OAAO;YACN,MAAM,EAAE,CAAC,MAAM,EAAE,aAAa,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC;YACvE,GAAG,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE,CAAC;gBAC1B,IAAI,CAAC;oBACJ,MAAM,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;gBAC9B,CAAC;wBAAS,CAAC;oBACV,IAAI,CAAC,KAAK,EAAE,CAAC;wBACZ,KAAK,GAAG,IAAI,CAAC;wBACb,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;wBAC/B,eAAe,EAAE,CAAC;oBACnB,CAAC;gBACF,CAAC;YAAA,CACD;YACD,UAAU,EAAE,CAAC,GAAG,EAAE,WAAW,EAAE,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,WAAW,CAAC;YACrE,QAAQ,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC;YACvD,QAAQ,EAAE,CAAC,OAAO,EAAE,WAAW,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;YACzE,UAAU,EAAE,CAAC,MAAM,EAAE,WAAW,EAAE,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,WAAW,CAAC;YAC3E,QAAQ,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,EAAE,WAAW,CAAC;YAC3F,UAAU,EAAE,CAAC,KAAK,EAAE,WAAW,EAAE,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,WAAW,CAAC;SACzE,CAAC;IAAA,CACF;IAED,MAAM,CAAI,QAAoC,EAAE,OAAgB,EAAc;QAC7E,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CACtB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,eAAe,EAAE,EAAE,CAAC;YACjD,IAAI,IAAI,CAAC,KAAK,KAAK,MAAM;gBAAE,MAAM,IAAI,CAAC,WAAW,CAAC;YAClD,OAAO,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;QAAA,CAC1C,EAAE,OAAO,CAAC,CACX,CAAC;IAAA,CACF;IAED,UAAU,CAAC,GAAa,EAAE,OAAgB,EAA+B;QACxE,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC;IAAA,CAC/D;IAED,QAAQ,CAAC,EAAU,EAAE,OAAgB,EAA8B;QAClE,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC;IAAA,CAC5D;IAED,QAAQ,CAAI,OAAiB,EAAE,OAAgB,EAAuC;QACrF,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;IAAA,CACjE;IAED,UAAU,CAAI,MAAgB,EAAE,OAAgB,EAA6B;QAC5E,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAAA,CAClE;IAED,QAAQ,CACP,OAAqB,EACrB,OAAoC,EACpC,OAAgB,EACY;QAC5B,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;IAAA,CAC1E;IAED,UAAU,CAAC,KAAwB,EAAE,OAAgB,EAAoB;QACxE,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC;IAAA,CACjE;IAED,QAAQ,CAAC,OAAgB,EAAyB;QACjD,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;IAAA,CACxD;IAED,OAAO,CAAC,OAAgB,EAA+B;QACtD,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;IAAA,CACvD;IAED,QAAQ,CAAC,QAAgB,EAAE,OAAgB,EAA+B;QACzE,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;IAAA,CAClE;IAED,WAAW,CAAC,KAA6B,EAAE,OAAgB,EAAoB;QAC9E,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC;IAAA,CAClE;IAED,SAAS,CAAC,KAA6B,EAAE,OAAgB,EAA8B;QACtF,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC;IAAA,CAChE;IAED,KAAK,CAAC,MAAM,CAAC,IAAY,EAAE,OAAgB,EAA+B;QACzE,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;QAC1E,OAAO,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IAAA,CAClE;IAED,KAAK,CAAC,YAAY,CAAC,IAAY,EAAE,EAAiB,EAAE,OAAgB,EAAmB;QACtF,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,IAAI,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IAAA,CAC7F;IAED,QAAQ,CAAI,OAAiB,EAAE,IAAgB,EAAE,OAAgB,EAAiB;QACjF,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;IAAA,CACvE;IAED,WAAW,CAAI,OAAiB,EAAE,OAAgB,EAAiB;QAClE,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;IAAA,CACpE;IAED,UAAU,CAAI,OAAqB,EAAE,OAAmB,EAAE,OAAgB,EAAiB;QAC1F,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;IAAA,CAC5E;IAED,UAAU,CAAI,OAAqB,EAAE,OAAgB,EAAiB;QACrE,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;IAAA,CACnE;IAED,OAAO,CAAC,IAAwB,EAAE,OAAgB,EAAiB;QAClE,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;IAAA,CAC7D;IAED,QAAQ,CAAC,QAAgB,EAAE,KAAyB,EAAE,OAAgB,EAAiB;QACtF,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC;IAAA,CACzE;IAED,KAAK,CAAC,QAAiB,EAAiB;QACvC,IAAI,IAAI,CAAC,YAAY,KAAK,SAAS;YAAE,OAAO,IAAI,CAAC,YAAY,CAAC;QAC9D,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC;QACvB,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;YACrE,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAC;YACtB,IAAI,CAAC,OAAO,EAAE,CAAC;QAAA,CACf,CAAC,CAAC;QACH,OAAO,IAAI,CAAC,YAAY,CAAC;IAAA,CACzB;IAEO,UAAU,CAAC,MAAc,EAAU;QAC1C,OAAO;YACN,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,QAAQ,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YACjE,WAAW,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;YACrF,SAAS,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;YACjF,aAAa,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC7F,iBAAiB,EAAE,CAAC,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,CAChD,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,iBAAiB,CAAC,UAAU,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;SACtE,CAAC;IAAA,CACF;IAEO,KAAK,CAAI,SAA2B,EAAc;QACzD,IAAI,IAAI,CAAC,KAAK,KAAK,MAAM;YAAE,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACnE,IAAI,MAAkB,CAAC;QACvB,IAAI,CAAC;YACJ,MAAM,GAAG,SAAS,EAAE,CAAC;QACtB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC;QACD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAC1B,KAAK,MAAM,CAAC,IAAI,CACf,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,EAClC,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAClC,CAAC;QACF,OAAO,MAAM,CAAC;IAAA,CACd;CACD;AAED,MAAM,OAAO,iBAAiB;IACZ,GAAG,CAAe;IAClB,QAAQ,GAAG,IAAI,GAAG,EAA+B,CAAC;IAClD,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;IACxC,MAAM,GAAG,KAAK,CAAC;IACf,YAAY,CAA4B;IAEhD,YAAY,OAAO,GAA6B,EAAE,EAAE;QACnD,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC;IAAA,CACnC;IAED,KAAK,CAAC,MAAM,CAAC,OAA6B,EAAE,OAAgB,EAAoB;QAC/E,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC7B,MAAM,EAAE,GAAG,OAAO,CAAC,EAAE,IAAI,MAAM,CAAC,SAAS,CAAC,CAAC;QAC3C,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;QACnB,MAAM,QAAQ,GAAoB;YACjC,EAAE;YACF,SAAS;YACT,cAAc,EAAE,sBAAsB;YACtC,GAAG,CAAC,OAAO,CAAC,eAAe,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,OAAO,CAAC,eAAe,EAAE,CAAC;SAC9F,CAAC;QACF,MAAM,OAAO,GAAG,IAAI,aAAa,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;QACrD,MAAM,OAAO,GAAG,IAAI,oBAAoB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAC5D,IAAI,CAAC;YACJ,MAAM,MAAM,GAAwB;gBACnC,QAAQ;gBACR,OAAO;gBACP,OAAO;gBACP,IAAI,EAAE,IAAI;aACV,CAAC;YACF,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;YAC9B,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QAChC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,MAAM,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAC7B,MAAM,KAAK,CAAC;QACb,CAAC;gBAAS,CAAC;YACV,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC5B,CAAC;IAAA,CACD;IAED,IAAI,CAAC,QAAyB,EAAE,QAAiB,EAAoB;QACpE,wEAAwE;QACxE,yDAAyD;QACzD,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QAC9C,IAAI,MAAM,KAAK,SAAS;YAAE,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,oBAAoB,QAAQ,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;QAC9F,IAAI,MAAM,CAAC,IAAI;YAAE,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,4BAA4B,QAAQ,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;QAC7F,MAAM,CAAC,IAAI,GAAG,IAAI,CAAC;QACnB,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;IAAA,CAChD;IAED,IAAI,CAAC,QAAmB,EAAE,QAAiB,EAA8B;QACxE,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,OAAO,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;IAAA,CACpF;IAED,KAAK,CAAC,MAAM,CAAC,QAAyB,EAAE,OAAgB,EAAiB;QACxE,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QAC9C,IAAI,MAAM,KAAK,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,oBAAoB,QAAQ,CAAC,EAAE,EAAE,CAAC,CAAC;QAC7E,IAAI,MAAM,CAAC,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,oBAAoB,QAAQ,CAAC,EAAE,EAAE,CAAC,CAAC;QACpE,MAAM,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACpC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IAAA,CAClC;IAED,KAAK,CAAC,IAAI,CAAC,MAAuB,EAAE,OAAoB,EAAE,QAAiB,EAAoB;QAC9F,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAClD,IAAI,YAAY,KAAK,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,oBAAoB,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC;QACjF,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC7B,MAAM,EAAE,GAAG,OAAO,CAAC,EAAE,IAAI,MAAM,CAAC,SAAS,CAAC,CAAC;QAC3C,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;QAEnB,IAAI,CAAC;YACJ,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACzD,MAAM,QAAQ,GAAoB;gBACjC,EAAE;gBACF,SAAS;gBACT,cAAc,EAAE,sBAAsB;gBACtC,eAAe,EAAE,YAAY,CAAC,QAAQ,CAAC,EAAE;aACzC,CAAC;YACF,MAAM,OAAO,GAAG,IAAI,oBAAoB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YAC5D,MAAM,MAAM,GAAwB;gBACnC,QAAQ;gBACR,OAAO;gBACP,OAAO;gBACP,IAAI,EAAE,IAAI;aACV,CAAC;YACF,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;YAC9B,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QAChC,CAAC;gBAAS,CAAC;YACV,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC5B,CAAC;IAAA,CACD;IAED,KAAK,CAAC,OAAgB,EAAiB;QACtC,IAAI,IAAI,CAAC,YAAY,KAAK,SAAS;YAAE,OAAO,IAAI,CAAC,YAAY,CAAC;QAC9D,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACnB,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAC7G,GAAG,EAAE,CAAC,SAAS,CACf,CAAC;QACF,OAAO,IAAI,CAAC,YAAY,CAAC;IAAA,CACzB;IAEO,UAAU,CAAC,MAA2B,EAAW;QACxD,OAAO,IAAI,mBAAmB,CAAC,MAAM,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC;YACpD,MAAM,CAAC,IAAI,GAAG,KAAK,CAAC;QAAA,CACpB,CAAC,CAAC;IAAA,CACH;IAEO,SAAS,CAAC,EAAU,EAAQ;QACnC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,EAAE,EAAE,CAAC,CAAC;QACvG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAAA,CACxB;IAEO,UAAU,GAAS;QAC1B,IAAI,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;IAAA,CAChE;CACD","sourcesContent":["import { uuidv7 } from \"@m4ike1/ion-ai/utils/uuid\";\nimport type { Context } from \"../context.ts\";\nimport { InMemoryStorageState } from \"./in-memory-storage-state.ts\";\nimport { StorageBackedSession } from \"./session.ts\";\nimport type {\n\tBranch,\n\tCommitResult,\n\tEntry,\n\tEntryQuery,\n\tEntryScan,\n\tEntryStructure,\n\tForkOptions,\n\tIdGenerator,\n\tSession,\n\tSessionCreateOptions,\n\tSessionMetadata,\n\tSessionMutation,\n\tSessionMutationCallback,\n\tSessionRepo,\n\tSessionStats,\n\tStorage,\n\tStorageBranchScan,\n\tUsageRow,\n\tUsageScan,\n\tWrite,\n} from \"./types.ts\";\nimport type { ListElement, ListReadOptions, StoredValue, Value, ValueList } from \"./values.ts\";\n\nexport interface MemoryStorageOptions {\n\tnow?: () => number;\n}\n\nexport interface MemorySessionRepoOptions {\n\tnow?: () => number;\n}\n\nexport class MemoryStorage implements Storage {\n\tprivate readonly now: () => number;\n\tprivate storageState = new InMemoryStorageState();\n\tprivate commitQueue: Promise<void> = Promise.resolve();\n\tprivate state: \"open\" | \"closing\" | \"closed\" = \"open\";\n\tprivate closePromise: Promise<void> | undefined;\n\n\tconstructor(options: MemoryStorageOptions = {}) {\n\t\tthis.now = options.now ?? Date.now;\n\t}\n\n\tasync commit(writes: Write[], _context: Context): Promise<CommitResult> {\n\t\tif (this.state !== \"open\") throw new Error(\"MemoryStorage is closed\");\n\t\tconst result = this.commitQueue.then(() => {\n\t\t\tconst prepared = this.storageState.prepareCommit(writes, this.now());\n\t\t\tconst stats = this.storageState.applyValidated(prepared.writes);\n\t\t\treturn { ...prepared.result, stats };\n\t\t});\n\t\tthis.commitQueue = result.then(\n\t\t\t() => undefined,\n\t\t\t() => undefined,\n\t\t);\n\t\treturn result;\n\t}\n\n\tgetEntries(ids: string[], _context: Context): Promise<Map<string, Entry>> {\n\t\tif (this.state !== \"open\") return Promise.reject(new Error(\"MemoryStorage is closed\"));\n\t\treturn Promise.resolve(this.storageState.getEntries(ids));\n\t}\n\n\tgetValue<T>(address: Value<T>, _context: Context): Promise<StoredValue<T> | undefined> {\n\t\tif (this.state !== \"open\") return Promise.reject(new Error(\"MemoryStorage is closed\"));\n\t\treturn Promise.resolve(this.storageState.getValue(address));\n\t}\n\n\tscanValues<T>(prefix: Value<T>, _context: Context): Promise<StoredValue<T>[]> {\n\t\tif (this.state !== \"open\") return Promise.reject(new Error(\"MemoryStorage is closed\"));\n\t\treturn Promise.resolve(this.storageState.scanValues(prefix));\n\t}\n\n\tasync readList<T>(\n\t\taddress: ValueList<T>,\n\t\toptions: ListReadOptions | undefined,\n\t\t_context: Context,\n\t): Promise<ListElement<T>[]> {\n\t\tif (this.state !== \"open\") throw new Error(\"MemoryStorage is closed\");\n\t\treturn this.storageState.readList(address, options);\n\t}\n\n\tasync scanBranch(query: StorageBranchScan, _context: Context): Promise<Entry[]> {\n\t\tif (this.state !== \"open\") throw new Error(\"MemoryStorage is closed\");\n\t\treturn this.storageState.scanBranch(query);\n\t}\n\n\tasync scanBranchStructure(query: StorageBranchScan, _context: Context): Promise<EntryStructure[]> {\n\t\tif (this.state !== \"open\") throw new Error(\"MemoryStorage is closed\");\n\t\treturn this.storageState.scanBranchStructure(query);\n\t}\n\n\tscanEntries(query: EntryScan, _context: Context): Promise<Entry[]> {\n\t\tif (this.state !== \"open\") return Promise.reject(new Error(\"MemoryStorage is closed\"));\n\t\treturn Promise.resolve(this.storageState.scanEntries(query));\n\t}\n\n\tscanUsage(query: UsageScan, _context: Context): Promise<UsageRow[]> {\n\t\tif (this.state !== \"open\") return Promise.reject(new Error(\"MemoryStorage is closed\"));\n\t\treturn Promise.resolve(this.storageState.scanUsage(query));\n\t}\n\n\tgetStats(_context: Context): Promise<SessionStats> {\n\t\tif (this.state !== \"open\") return Promise.reject(new Error(\"MemoryStorage is closed\"));\n\t\treturn Promise.resolve(this.storageState.getStats());\n\t}\n\n\t/** Construct a destination storage at one serialized boundary between source commits. */\n\tfork(options: ForkOptions): Promise<MemoryStorage> {\n\t\tif (this.state !== \"open\") return Promise.reject(new Error(\"MemoryStorage is closed\"));\n\t\tconst result = this.commitQueue.then(() => {\n\t\t\tconst destination = new MemoryStorage({ now: this.now });\n\t\t\tdestination.storageState = this.storageState.createFork(options);\n\t\t\treturn destination;\n\t\t});\n\t\tthis.commitQueue = result.then(\n\t\t\t() => undefined,\n\t\t\t() => undefined,\n\t\t);\n\t\treturn result;\n\t}\n\n\tclose(_context: Context): Promise<void> {\n\t\tif (this.closePromise !== undefined) return this.closePromise;\n\t\tthis.state = \"closing\";\n\t\tthis.closePromise = this.commitQueue.then(() => {\n\t\t\tthis.state = \"closed\";\n\t\t});\n\t\treturn this.closePromise;\n\t}\n}\n\nconst MEMORY_STORAGE_VERSION = 1;\n\ninterface MemorySessionRecord {\n\tmetadata: SessionMetadata;\n\tstorage: MemoryStorage;\n\tsession: StorageBackedSession;\n\topen: boolean;\n}\n\nclass MemorySessionFacade implements Session {\n\treadonly metadata: SessionMetadata;\n\treadonly idGenerator: IdGenerator;\n\tprivate readonly session: StorageBackedSession;\n\tprivate readonly onClose: () => void;\n\tprivate readonly admitted = new Set<Promise<unknown>>();\n\tprivate readonly closedError = new Error(\"Session is closed\");\n\tprivate state: \"open\" | \"closing\" | \"closed\" = \"open\";\n\tprivate closePromise: Promise<void> | undefined;\n\n\tconstructor(session: StorageBackedSession, onClose: () => void) {\n\t\tthis.session = session;\n\t\tthis.metadata = session.metadata;\n\t\tthis.idGenerator = session.idGenerator;\n\t\tthis.onClose = onClose;\n\t}\n\n\tasync beginMutation(context: Context): Promise<SessionMutation> {\n\t\tlet resolveFinished!: () => void;\n\t\tconst finished = new Promise<void>((resolve) => {\n\t\t\tresolveFinished = resolve;\n\t\t});\n\t\tthis.admitted.add(finished);\n\t\tlet source: SessionMutation;\n\t\ttry {\n\t\t\tsource = await this.admit(() => this.session.beginMutation(context));\n\t\t} catch (error) {\n\t\t\tthis.admitted.delete(finished);\n\t\t\tresolveFinished();\n\t\t\tthrow error;\n\t\t}\n\t\tif (this.state !== \"open\") {\n\t\t\tawait source.end(context);\n\t\t\tthis.admitted.delete(finished);\n\t\t\tresolveFinished();\n\t\t\tthrow this.closedError;\n\t\t}\n\t\tlet ended = false;\n\t\treturn {\n\t\t\tcommit: (writes, commitContext) => source.commit(writes, commitContext),\n\t\t\tend: async (endContext) => {\n\t\t\t\ttry {\n\t\t\t\t\tawait source.end(endContext);\n\t\t\t\t} finally {\n\t\t\t\t\tif (!ended) {\n\t\t\t\t\t\tended = true;\n\t\t\t\t\t\tthis.admitted.delete(finished);\n\t\t\t\t\t\tresolveFinished();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\tgetEntries: (ids, readContext) => source.getEntries(ids, readContext),\n\t\t\tgetStats: (readContext) => source.getStats(readContext),\n\t\t\tgetValue: (address, readContext) => source.getValue(address, readContext),\n\t\t\tscanValues: (prefix, readContext) => source.scanValues(prefix, readContext),\n\t\t\treadList: (address, options, readContext) => source.readList(address, options, readContext),\n\t\t\tscanBranch: (query, readContext) => source.scanBranch(query, readContext),\n\t\t};\n\t}\n\n\tmutate<T>(mutation: SessionMutationCallback<T>, context: Context): Promise<T> {\n\t\treturn this.admit(() =>\n\t\t\tthis.session.mutate((mutator, mutationContext) => {\n\t\t\t\tif (this.state !== \"open\") throw this.closedError;\n\t\t\t\treturn mutation(mutator, mutationContext);\n\t\t\t}, context),\n\t\t);\n\t}\n\n\tgetEntries(ids: string[], context: Context): Promise<Map<string, Entry>> {\n\t\treturn this.admit(() => this.session.getEntries(ids, context));\n\t}\n\n\tgetEntry(id: string, context: Context): Promise<Entry | undefined> {\n\t\treturn this.admit(() => this.session.getEntry(id, context));\n\t}\n\n\tgetValue<T>(address: Value<T>, context: Context): Promise<StoredValue<T> | undefined> {\n\t\treturn this.admit(() => this.session.getValue(address, context));\n\t}\n\n\tscanValues<T>(prefix: Value<T>, context: Context): Promise<StoredValue<T>[]> {\n\t\treturn this.admit(() => this.session.scanValues(prefix, context));\n\t}\n\n\treadList<T>(\n\t\taddress: ValueList<T>,\n\t\toptions: ListReadOptions | undefined,\n\t\tcontext: Context,\n\t): Promise<ListElement<T>[]> {\n\t\treturn this.admit(() => this.session.readList(address, options, context));\n\t}\n\n\tscanBranch(query: StorageBranchScan, context: Context): Promise<Entry[]> {\n\t\treturn this.admit(() => this.session.scanBranch(query, context));\n\t}\n\n\tgetStats(context: Context): Promise<SessionStats> {\n\t\treturn this.admit(() => this.session.getStats(context));\n\t}\n\n\tgetName(context: Context): Promise<string | undefined> {\n\t\treturn this.admit(() => this.session.getName(context));\n\t}\n\n\tgetLabel(targetId: string, context: Context): Promise<string | undefined> {\n\t\treturn this.admit(() => this.session.getLabel(targetId, context));\n\t}\n\n\tfindEntries(query: EntryQuery | undefined, context: Context): Promise<Entry[]> {\n\t\treturn this.admit(() => this.session.findEntries(query, context));\n\t}\n\n\tfindEntry(query: EntryQuery | undefined, context: Context): Promise<Entry | undefined> {\n\t\treturn this.admit(() => this.session.findEntry(query, context));\n\t}\n\n\tasync branch(name: string, context: Context): Promise<Branch | undefined> {\n\t\tconst branch = await this.admit(() => this.session.branch(name, context));\n\t\treturn branch === undefined ? undefined : this.wrapBranch(branch);\n\t}\n\n\tasync createBranch(name: string, at: string | null, context: Context): Promise<Branch> {\n\t\treturn this.wrapBranch(await this.admit(() => this.session.createBranch(name, at, context)));\n\t}\n\n\tsetValue<T>(address: Value<T>, next: NoInfer<T>, context: Context): Promise<void> {\n\t\treturn this.admit(() => this.session.setValue(address, next, context));\n\t}\n\n\tdeleteValue<T>(address: Value<T>, context: Context): Promise<void> {\n\t\treturn this.admit(() => this.session.deleteValue(address, context));\n\t}\n\n\tappendList<T>(address: ValueList<T>, element: NoInfer<T>, context: Context): Promise<void> {\n\t\treturn this.admit(() => this.session.appendList(address, element, context));\n\t}\n\n\tdeleteList<T>(address: ValueList<T>, context: Context): Promise<void> {\n\t\treturn this.admit(() => this.session.deleteList(address, context));\n\t}\n\n\tsetName(name: string | undefined, context: Context): Promise<void> {\n\t\treturn this.admit(() => this.session.setName(name, context));\n\t}\n\n\tsetLabel(targetId: string, label: string | undefined, context: Context): Promise<void> {\n\t\treturn this.admit(() => this.session.setLabel(targetId, label, context));\n\t}\n\n\tclose(_context: Context): Promise<void> {\n\t\tif (this.closePromise !== undefined) return this.closePromise;\n\t\tthis.state = \"closing\";\n\t\tthis.closePromise = Promise.allSettled([...this.admitted]).then(() => {\n\t\t\tthis.state = \"closed\";\n\t\t\tthis.onClose();\n\t\t});\n\t\treturn this.closePromise;\n\t}\n\n\tprivate wrapBranch(branch: Branch): Branch {\n\t\treturn {\n\t\t\tname: branch.name,\n\t\t\tgetTipId: (context) => this.admit(() => branch.getTipId(context)),\n\t\t\tfindEntries: (query, context) => this.admit(() => branch.findEntries(query, context)),\n\t\t\tfindEntry: (query, context) => this.admit(() => branch.findEntry(query, context)),\n\t\t\tappendMessage: (message, context) => this.admit(() => branch.appendMessage(message, context)),\n\t\t\tappendCustomEntry: (customType, data, context) =>\n\t\t\t\tthis.admit(() => branch.appendCustomEntry(customType, data, context)),\n\t\t};\n\t}\n\n\tprivate admit<T>(operation: () => Promise<T>): Promise<T> {\n\t\tif (this.state !== \"open\") return Promise.reject(this.closedError);\n\t\tlet result: Promise<T>;\n\t\ttry {\n\t\t\tresult = operation();\n\t\t} catch (error) {\n\t\t\tresult = Promise.reject(error);\n\t\t}\n\t\tthis.admitted.add(result);\n\t\tvoid result.then(\n\t\t\t() => this.admitted.delete(result),\n\t\t\t() => this.admitted.delete(result),\n\t\t);\n\t\treturn result;\n\t}\n}\n\nexport class MemorySessionRepo implements SessionRepo {\n\tprivate readonly now: () => number;\n\tprivate readonly sessions = new Map<string, MemorySessionRecord>();\n\tprivate readonly pendingIds = new Set<string>();\n\tprivate closed = false;\n\tprivate closePromise: Promise<void> | undefined;\n\n\tconstructor(options: MemorySessionRepoOptions = {}) {\n\t\tthis.now = options.now ?? Date.now;\n\t}\n\n\tasync create(options: SessionCreateOptions, context: Context): Promise<Session> {\n\t\tthis.assertOpen();\n\t\tconst createdAt = this.now();\n\t\tconst id = options.id ?? uuidv7(createdAt);\n\t\tthis.reserveId(id);\n\t\tconst metadata: SessionMetadata = {\n\t\t\tid,\n\t\t\tcreatedAt,\n\t\t\tstorageVersion: MEMORY_STORAGE_VERSION,\n\t\t\t...(options.parentSessionId === undefined ? {} : { parentSessionId: options.parentSessionId }),\n\t\t};\n\t\tconst storage = new MemoryStorage({ now: this.now });\n\t\tconst session = new StorageBackedSession(metadata, storage);\n\t\ttry {\n\t\t\tconst record: MemorySessionRecord = {\n\t\t\t\tmetadata,\n\t\t\t\tstorage,\n\t\t\t\tsession,\n\t\t\t\topen: true,\n\t\t\t};\n\t\t\tthis.sessions.set(id, record);\n\t\t\treturn this.openRecord(record);\n\t\t} catch (error) {\n\t\t\tawait session.close(context);\n\t\t\tthrow error;\n\t\t} finally {\n\t\t\tthis.pendingIds.delete(id);\n\t\t}\n\t}\n\n\topen(metadata: SessionMetadata, _context: Context): Promise<Session> {\n\t\t// Memory sessions are always created at the current storage version, so\n\t\t// persistent-backend version gating does not apply here.\n\t\tthis.assertOpen();\n\t\tconst record = this.sessions.get(metadata.id);\n\t\tif (record === undefined) return Promise.reject(new Error(`Unknown session: ${metadata.id}`));\n\t\tif (record.open) return Promise.reject(new Error(`Session is already open: ${metadata.id}`));\n\t\trecord.open = true;\n\t\treturn Promise.resolve(this.openRecord(record));\n\t}\n\n\tlist(_options: undefined, _context: Context): Promise<SessionMetadata[]> {\n\t\tthis.assertOpen();\n\t\treturn Promise.resolve([...this.sessions.values()].map(({ metadata }) => metadata));\n\t}\n\n\tasync delete(metadata: SessionMetadata, context: Context): Promise<void> {\n\t\tthis.assertOpen();\n\t\tconst record = this.sessions.get(metadata.id);\n\t\tif (record === undefined) throw new Error(`Unknown session: ${metadata.id}`);\n\t\tif (record.open) throw new Error(`Session is open: ${metadata.id}`);\n\t\tawait record.session.close(context);\n\t\tthis.sessions.delete(metadata.id);\n\t}\n\n\tasync fork(source: SessionMetadata, options: ForkOptions, _context: Context): Promise<Session> {\n\t\tthis.assertOpen();\n\t\tconst sourceRecord = this.sessions.get(source.id);\n\t\tif (sourceRecord === undefined) throw new Error(`Unknown session: ${source.id}`);\n\t\tconst createdAt = this.now();\n\t\tconst id = options.id ?? uuidv7(createdAt);\n\t\tthis.reserveId(id);\n\n\t\ttry {\n\t\t\tconst storage = await sourceRecord.storage.fork(options);\n\t\t\tconst metadata: SessionMetadata = {\n\t\t\t\tid,\n\t\t\t\tcreatedAt,\n\t\t\t\tstorageVersion: MEMORY_STORAGE_VERSION,\n\t\t\t\tparentSessionId: sourceRecord.metadata.id,\n\t\t\t};\n\t\t\tconst session = new StorageBackedSession(metadata, storage);\n\t\t\tconst record: MemorySessionRecord = {\n\t\t\t\tmetadata,\n\t\t\t\tstorage,\n\t\t\t\tsession,\n\t\t\t\topen: true,\n\t\t\t};\n\t\t\tthis.sessions.set(id, record);\n\t\t\treturn this.openRecord(record);\n\t\t} finally {\n\t\t\tthis.pendingIds.delete(id);\n\t\t}\n\t}\n\n\tclose(context: Context): Promise<void> {\n\t\tif (this.closePromise !== undefined) return this.closePromise;\n\t\tthis.closed = true;\n\t\tthis.closePromise = Promise.all([...this.sessions.values()].map(({ session }) => session.close(context))).then(\n\t\t\t() => undefined,\n\t\t);\n\t\treturn this.closePromise;\n\t}\n\n\tprivate openRecord(record: MemorySessionRecord): Session {\n\t\treturn new MemorySessionFacade(record.session, () => {\n\t\t\trecord.open = false;\n\t\t});\n\t}\n\n\tprivate reserveId(id: string): void {\n\t\tif (this.sessions.has(id) || this.pendingIds.has(id)) throw new Error(`Session already exists: ${id}`);\n\t\tthis.pendingIds.add(id);\n\t}\n\n\tprivate assertOpen(): void {\n\t\tif (this.closed) throw new Error(\"MemorySessionRepo is closed\");\n\t}\n}\n"]}
@@ -0,0 +1,8 @@
1
+ /** Serializes complete read-modify-write jobs for one Session. */
2
+ export declare class MutationLine {
3
+ private tail;
4
+ private sealedError;
5
+ run<T>(operation: () => T | Promise<T>): Promise<T>;
6
+ seal(error: Error): Promise<void>;
7
+ }
8
+ //# sourceMappingURL=mutation-line.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mutation-line.d.ts","sourceRoot":"","sources":["../../../src/harness/session/mutation-line.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,qBAAa,YAAY;IACxB,OAAO,CAAC,IAAI,CAAoC;IAChD,OAAO,CAAC,WAAW,CAAoB;IAEvC,GAAG,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAWlD;IAED,IAAI,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAGhC;CACD","sourcesContent":["/** Serializes complete read-modify-write jobs for one Session. */\nexport class MutationLine {\n\tprivate tail: Promise<void> = Promise.resolve();\n\tprivate sealedError: Error | undefined;\n\n\trun<T>(operation: () => T | Promise<T>): Promise<T> {\n\t\tif (this.sealedError !== undefined) return Promise.reject(this.sealedError);\n\t\tconst result = this.tail.then(() => {\n\t\t\tif (this.sealedError !== undefined) throw this.sealedError;\n\t\t\treturn operation();\n\t\t});\n\t\tthis.tail = result.then(\n\t\t\t() => undefined,\n\t\t\t() => undefined,\n\t\t);\n\t\treturn result;\n\t}\n\n\tseal(error: Error): Promise<void> {\n\t\tthis.sealedError ??= error;\n\t\treturn this.tail;\n\t}\n}\n"]}
@@ -0,0 +1,21 @@
1
+ /** Serializes complete read-modify-write jobs for one Session. */
2
+ export class MutationLine {
3
+ tail = Promise.resolve();
4
+ sealedError;
5
+ run(operation) {
6
+ if (this.sealedError !== undefined)
7
+ return Promise.reject(this.sealedError);
8
+ const result = this.tail.then(() => {
9
+ if (this.sealedError !== undefined)
10
+ throw this.sealedError;
11
+ return operation();
12
+ });
13
+ this.tail = result.then(() => undefined, () => undefined);
14
+ return result;
15
+ }
16
+ seal(error) {
17
+ this.sealedError ??= error;
18
+ return this.tail;
19
+ }
20
+ }
21
+ //# sourceMappingURL=mutation-line.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mutation-line.js","sourceRoot":"","sources":["../../../src/harness/session/mutation-line.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,MAAM,OAAO,YAAY;IAChB,IAAI,GAAkB,OAAO,CAAC,OAAO,EAAE,CAAC;IACxC,WAAW,CAAoB;IAEvC,GAAG,CAAI,SAA+B,EAAc;QACnD,IAAI,IAAI,CAAC,WAAW,KAAK,SAAS;YAAE,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAC5E,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;YACnC,IAAI,IAAI,CAAC,WAAW,KAAK,SAAS;gBAAE,MAAM,IAAI,CAAC,WAAW,CAAC;YAC3D,OAAO,SAAS,EAAE,CAAC;QAAA,CACnB,CAAC,CAAC;QACH,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CACtB,GAAG,EAAE,CAAC,SAAS,EACf,GAAG,EAAE,CAAC,SAAS,CACf,CAAC;QACF,OAAO,MAAM,CAAC;IAAA,CACd;IAED,IAAI,CAAC,KAAY,EAAiB;QACjC,IAAI,CAAC,WAAW,KAAK,KAAK,CAAC;QAC3B,OAAO,IAAI,CAAC,IAAI,CAAC;IAAA,CACjB;CACD","sourcesContent":["/** Serializes complete read-modify-write jobs for one Session. */\nexport class MutationLine {\n\tprivate tail: Promise<void> = Promise.resolve();\n\tprivate sealedError: Error | undefined;\n\n\trun<T>(operation: () => T | Promise<T>): Promise<T> {\n\t\tif (this.sealedError !== undefined) return Promise.reject(this.sealedError);\n\t\tconst result = this.tail.then(() => {\n\t\t\tif (this.sealedError !== undefined) throw this.sealedError;\n\t\t\treturn operation();\n\t\t});\n\t\tthis.tail = result.then(\n\t\t\t() => undefined,\n\t\t\t() => undefined,\n\t\t);\n\t\treturn result;\n\t}\n\n\tseal(error: Error): Promise<void> {\n\t\tthis.sealedError ??= error;\n\t\treturn this.tail;\n\t}\n}\n"]}
@@ -0,0 +1,82 @@
1
+ import type { AgentMessage } from "../../types.ts";
2
+ import type { Context } from "../context.ts";
3
+ import { MutationLine } from "./mutation-line.ts";
4
+ import type { Branch, Entry, EntryQuery, IdGenerator, JsonValue, Session, SessionMetadata, SessionMutation, SessionMutationCallback, SessionStats, Storage, StorageBranchScan } from "./types.ts";
5
+ import { type ListElement, type ListReadOptions, type StoredValue, type Value, type ValueList } from "./values.ts";
6
+ export interface StorageBackedSessionOptions {
7
+ mutationLine?: MutationLine;
8
+ idGenerator?: IdGenerator;
9
+ onClose?: () => void;
10
+ }
11
+ /** Durable session state is internally inconsistent and cannot be safely advanced. */
12
+ export declare class SessionInvariantError extends Error {
13
+ constructor(message: string);
14
+ }
15
+ /** A requested Branch name is invalid. */
16
+ export declare class SessionInvalidBranchError extends Error {
17
+ readonly branch: string;
18
+ readonly reason: string;
19
+ constructor(branch: string, reason: string);
20
+ }
21
+ /** A requested branch already exists. */
22
+ export declare class SessionBranchExistsError extends Error {
23
+ readonly branch: string;
24
+ constructor(branch: string);
25
+ }
26
+ /** A pending assistant message cannot be persisted as a session entry. */
27
+ export declare class SessionPendingAssistantMessageError extends Error {
28
+ constructor();
29
+ }
30
+ /** A requested session entry target does not exist. */
31
+ export declare class SessionUnknownTargetError extends Error {
32
+ readonly targetId: string;
33
+ constructor(targetId: string);
34
+ }
35
+ /** Package-internal typed boundary shared by concrete session repositories. */
36
+ export declare class StorageBackedSession<TMetadata extends SessionMetadata = SessionMetadata> implements Session<TMetadata> {
37
+ readonly metadata: TMetadata;
38
+ readonly idGenerator: IdGenerator;
39
+ private readonly storage;
40
+ private readonly mutationLine;
41
+ private readonly onClose;
42
+ private readonly branches;
43
+ private readonly closedError;
44
+ private state;
45
+ private closePromise;
46
+ constructor(metadata: TMetadata, storage: Storage, options?: StorageBackedSessionOptions);
47
+ beginMutation(_context: Context): Promise<SessionMutation>;
48
+ mutate<T>(mutation: SessionMutationCallback<T>, context: Context): Promise<T>;
49
+ getEntries(ids: string[], context: Context): Promise<Map<string, Entry>>;
50
+ getEntry(id: string, context: Context): Promise<Entry | undefined>;
51
+ getValue<T>(address: Value<T>, context: Context): Promise<StoredValue<T> | undefined>;
52
+ scanValues<T>(prefix: Value<T>, context: Context): Promise<StoredValue<T>[]>;
53
+ readList<T>(address: ValueList<T>, options: ListReadOptions | undefined, context: Context): Promise<ListElement<T>[]>;
54
+ scanBranch(query: StorageBranchScan, context: Context): Promise<Entry[]>;
55
+ getStats(context: Context): Promise<SessionStats>;
56
+ getName(context: Context): Promise<string | undefined>;
57
+ getLabel(targetId: string, context: Context): Promise<string | undefined>;
58
+ findEntries(query: EntryQuery | undefined, context: Context): Promise<Entry[]>;
59
+ findEntry(query: EntryQuery | undefined, context: Context): Promise<Entry | undefined>;
60
+ branch(name: string, context: Context): Promise<Branch | undefined>;
61
+ createBranch(name: string, at: string | null, context: Context): Promise<Branch>;
62
+ setValue<T>(address: Value<T>, next: NoInfer<T>, context: Context): Promise<void>;
63
+ deleteValue<T>(address: Value<T>, context: Context): Promise<void>;
64
+ appendList<T>(address: ValueList<T>, element: NoInfer<T>, context: Context): Promise<void>;
65
+ deleteList<T>(address: ValueList<T>, context: Context): Promise<void>;
66
+ setName(name: string | undefined, context: Context): Promise<void>;
67
+ setLabel(targetId: string, label: string | undefined, context: Context): Promise<void>;
68
+ close(context: Context): Promise<void>;
69
+ getBranchTip(name: string, context: Context): Promise<string | null>;
70
+ appendToBranch(name: string, entry: {
71
+ type: "message";
72
+ message: AgentMessage;
73
+ } | {
74
+ type: "custom";
75
+ customType: string;
76
+ data?: JsonValue;
77
+ }, context: Context): Promise<string>;
78
+ private getOrCreateBranchObject;
79
+ private assertValidBranchName;
80
+ private assertOpen;
81
+ }
82
+ //# sourceMappingURL=session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../../src/harness/session/session.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAE7C,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,KAAK,EACX,MAAM,EAGN,KAAK,EACL,UAAU,EACV,WAAW,EACX,SAAS,EACT,OAAO,EACP,eAAe,EACf,eAAe,EACf,uBAAuB,EACvB,YAAY,EACZ,OAAO,EACP,iBAAiB,EAEjB,MAAM,YAAY,CAAC;AACpB,OAAO,EAMN,KAAK,WAAW,EAChB,KAAK,eAAe,EACpB,KAAK,WAAW,EAGhB,KAAK,KAAK,EACV,KAAK,SAAS,EACd,MAAM,aAAa,CAAC;AAErB,MAAM,WAAW,2BAA2B;IAC3C,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,sFAAsF;AACtF,qBAAa,qBAAsB,SAAQ,KAAK;IAC/C,YAAY,OAAO,EAAE,MAAM,EAG1B;CACD;AAED,0CAA0C;AAC1C,qBAAa,yBAA0B,SAAQ,KAAK;IACnD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAExB,YAAY,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAKzC;CACD;AAED,yCAAyC;AACzC,qBAAa,wBAAyB,SAAQ,KAAK;IAClD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAExB,YAAY,MAAM,EAAE,MAAM,EAIzB;CACD;AAED,0EAA0E;AAC1E,qBAAa,mCAAoC,SAAQ,KAAK;IAC7D,cAGC;CACD;AAED,uDAAuD;AACvD,qBAAa,yBAA0B,SAAQ,KAAK;IACnD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAE1B,YAAY,QAAQ,EAAE,MAAM,EAI3B;CACD;AAkID,+EAA+E;AAC/E,qBAAa,oBAAoB,CAAC,SAAS,SAAS,eAAe,GAAG,eAAe,CAAE,YAAW,OAAO,CAAC,SAAS,CAAC;IACnH,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;IAClC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;IAClC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAe;IAC5C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA2B;IACnD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA0C;IACnE,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAkC;IAC9D,OAAO,CAAC,KAAK,CAAyC;IACtD,OAAO,CAAC,YAAY,CAA4B;IAEhD,YAAY,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,GAAE,2BAAgC,EAM3F;IAEK,aAAa,CAAC,QAAQ,EAAE,OAAO,GAAG,OAAO,CAAC,eAAe,CAAC,CAkB/D;IAEK,MAAM,CAAC,CAAC,EAAE,QAAQ,EAAE,uBAAuB,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,CAOlF;IAEK,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAG7E;IAEK,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,KAAK,GAAG,SAAS,CAAC,CAEvE;IAEK,QAAQ,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAG1F;IAEK,UAAU,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,CAGjF;IAEK,QAAQ,CAAC,CAAC,EACf,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC,EACrB,OAAO,EAAE,eAAe,GAAG,SAAS,EACpC,OAAO,EAAE,OAAO,GACd,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,CAG3B;IAEK,UAAU,CAAC,KAAK,EAAE,iBAAiB,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC,CAG7E;IAEK,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,YAAY,CAAC,CAGtD;IAEK,OAAO,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAE3D;IAEK,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAE9E;IAEK,WAAW,CAAC,KAAK,EAAE,UAAU,GAAG,SAAS,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC,CAsBnF;IAEK,SAAS,CAAC,KAAK,EAAE,UAAU,GAAG,SAAS,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,KAAK,GAAG,SAAS,CAAC,CAK3F;IAEK,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAIxE;IAEK,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAarF;IAED,QAAQ,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAIhF;IAED,WAAW,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAIjE;IAED,UAAU,CAAC,CAAC,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAIzF;IAED,UAAU,CAAC,CAAC,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAIpE;IAED,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAEjE;IAED,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAGrF;IAED,KAAK,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAWrC;IAEK,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAIzE;IAEK,cAAc,CACnB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE;QAAE,IAAI,EAAE,SAAS,CAAC;QAAC,OAAO,EAAE,YAAY,CAAA;KAAE,GAAG;QAAE,IAAI,EAAE,QAAQ,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,SAAS,CAAA;KAAE,EAC5G,OAAO,EAAE,OAAO,GACd,OAAO,CAAC,MAAM,CAAC,CA4BjB;IAED,OAAO,CAAC,uBAAuB;IAS/B,OAAO,CAAC,qBAAqB;IAO7B,OAAO,CAAC,UAAU;CAGlB","sourcesContent":["import { uuidv7 } from \"@m4ike1/ion-ai/utils/uuid\";\nimport type { AgentMessage } from \"../../types.ts\";\nimport type { Context } from \"../context.ts\";\nimport { insertEntry } from \"./commit.ts\";\nimport { MutationLine } from \"./mutation-line.ts\";\nimport type {\n\tBranch,\n\tBranchScan,\n\tCommitResult,\n\tEntry,\n\tEntryQuery,\n\tIdGenerator,\n\tJsonValue,\n\tSession,\n\tSessionMetadata,\n\tSessionMutation,\n\tSessionMutationCallback,\n\tSessionStats,\n\tStorage,\n\tStorageBranchScan,\n\tWrite,\n} from \"./types.ts\";\nimport {\n\tappendList as appendListWrite,\n\tbranchTip,\n\tdeleteList as deleteListWrite,\n\tdeleteValue as deleteValueWrite,\n\tentryLabel,\n\ttype ListElement,\n\ttype ListReadOptions,\n\ttype StoredValue,\n\tsessionName,\n\tsetValue as setValueWrite,\n\ttype Value,\n\ttype ValueList,\n} from \"./values.ts\";\n\nexport interface StorageBackedSessionOptions {\n\tmutationLine?: MutationLine;\n\tidGenerator?: IdGenerator;\n\tonClose?: () => void;\n}\n\n/** Durable session state is internally inconsistent and cannot be safely advanced. */\nexport class SessionInvariantError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"SessionInvariantError\";\n\t}\n}\n\n/** A requested Branch name is invalid. */\nexport class SessionInvalidBranchError extends Error {\n\treadonly branch: string;\n\treadonly reason: string;\n\n\tconstructor(branch: string, reason: string) {\n\t\tsuper(`Invalid branch ${JSON.stringify(branch)}: ${reason}`);\n\t\tthis.name = \"SessionInvalidBranchError\";\n\t\tthis.branch = branch;\n\t\tthis.reason = reason;\n\t}\n}\n\n/** A requested branch already exists. */\nexport class SessionBranchExistsError extends Error {\n\treadonly branch: string;\n\n\tconstructor(branch: string) {\n\t\tsuper(`Branch already exists: ${branch}`);\n\t\tthis.name = \"SessionBranchExistsError\";\n\t\tthis.branch = branch;\n\t}\n}\n\n/** A pending assistant message cannot be persisted as a session entry. */\nexport class SessionPendingAssistantMessageError extends Error {\n\tconstructor() {\n\t\tsuper(\"Cannot persist a pending assistant message\");\n\t\tthis.name = \"SessionPendingAssistantMessageError\";\n\t}\n}\n\n/** A requested session entry target does not exist. */\nexport class SessionUnknownTargetError extends Error {\n\treadonly targetId: string;\n\n\tconstructor(targetId: string) {\n\t\tsuper(`Unknown target: ${targetId}`);\n\t\tthis.name = \"SessionUnknownTargetError\";\n\t\tthis.targetId = targetId;\n\t}\n}\n\nclass StorageBackedSessionMutation implements SessionMutation {\n\tprivate readonly storage: Storage;\n\tprivate readonly release: () => void;\n\tprivate active = true;\n\tprivate commitResult: Promise<CommitResult> | undefined;\n\tprivate endPromise: Promise<void> | undefined;\n\n\tconstructor(storage: Storage, release: () => void) {\n\t\tthis.storage = storage;\n\t\tthis.release = release;\n\t}\n\n\tcommit(writes: Write[], context: Context): Promise<CommitResult> {\n\t\tthis.assertActive();\n\t\tif (this.commitResult !== undefined) return Promise.reject(new Error(\"SessionMutator commit already attempted\"));\n\t\ttry {\n\t\t\tfor (const write of writes) {\n\t\t\t\tif (\n\t\t\t\t\twrite.kind === \"entry\" &&\n\t\t\t\t\twrite.entry.type === \"message\" &&\n\t\t\t\t\twrite.entry.message.role === \"assistant\" &&\n\t\t\t\t\twrite.entry.message.stopReason === \"pending\"\n\t\t\t\t) {\n\t\t\t\t\tthrow new SessionPendingAssistantMessageError();\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.commitResult = this.storage.commit(writes, context);\n\t\t} catch (error) {\n\t\t\tthis.commitResult = Promise.reject(error);\n\t\t}\n\t\treturn this.commitResult;\n\t}\n\n\tend(_context: Context): Promise<void> {\n\t\tif (this.endPromise !== undefined) return this.endPromise;\n\t\tthis.active = false;\n\t\tthis.endPromise = this.settle().finally(this.release);\n\t\treturn this.endPromise;\n\t}\n\n\tgetEntries(ids: string[], context: Context): Promise<Map<string, Entry>> {\n\t\tthis.assertActive();\n\t\treturn this.storage.getEntries(ids, context);\n\t}\n\n\tgetStats(context: Context): Promise<SessionStats> {\n\t\tthis.assertActive();\n\t\treturn this.storage.getStats(context);\n\t}\n\n\tgetValue<T>(address: Value<T>, context: Context): Promise<StoredValue<T> | undefined> {\n\t\tthis.assertActive();\n\t\treturn this.storage.getValue(address, context);\n\t}\n\n\tscanValues<T>(prefix: Value<T>, context: Context): Promise<StoredValue<T>[]> {\n\t\tthis.assertActive();\n\t\treturn this.storage.scanValues(prefix, context);\n\t}\n\n\treadList<T>(\n\t\taddress: ValueList<T>,\n\t\toptions: ListReadOptions | undefined,\n\t\tcontext: Context,\n\t): Promise<ListElement<T>[]> {\n\t\tthis.assertActive();\n\t\treturn this.storage.readList(address, options, context);\n\t}\n\n\tscanBranch(query: StorageBranchScan, context: Context): Promise<Entry[]> {\n\t\tthis.assertActive();\n\t\treturn this.storage.scanBranch(query, context);\n\t}\n\n\tprivate settle(): Promise<void> {\n\t\treturn (\n\t\t\tthis.commitResult?.then(\n\t\t\t\t() => undefined,\n\t\t\t\t() => undefined,\n\t\t\t) ?? Promise.resolve()\n\t\t);\n\t}\n\n\tprivate assertActive(): void {\n\t\tif (!this.active) throw new Error(\"SessionMutator cannot be used outside its mutation callback\");\n\t}\n}\n\nclass StorageBackedBranch implements Branch {\n\treadonly name: string;\n\tprivate readonly session: StorageBackedSession;\n\n\tconstructor(name: string, session: StorageBackedSession) {\n\t\tthis.name = name;\n\t\tthis.session = session;\n\t}\n\n\tgetTipId(context: Context): Promise<string | null> {\n\t\treturn this.session.getBranchTip(this.name, context);\n\t}\n\n\tasync findEntries(query: BranchScan | undefined, context: Context): Promise<Entry[]> {\n\t\tquery ??= {};\n\t\tconst start = query.start ?? (await this.getTipId(context));\n\t\tif (start === null) return [];\n\t\treturn this.session.scanBranch({ ...query, start, order: query.order ?? \"newestFirst\" }, context);\n\t}\n\n\tasync findEntry(query: BranchScan | undefined, context: Context): Promise<Entry | undefined> {\n\t\tquery ??= {};\n\t\treturn (\n\t\t\tawait this.findEntries({ ...query, limit: query.limit === undefined ? 1 : Math.min(query.limit, 1) }, context)\n\t\t)[0];\n\t}\n\n\tappendMessage(message: AgentMessage, context: Context): Promise<string> {\n\t\treturn this.session.appendToBranch(this.name, { type: \"message\", message }, context);\n\t}\n\n\tappendCustomEntry(customType: string, data: JsonValue | undefined, context: Context): Promise<string> {\n\t\treturn this.session.appendToBranch(\n\t\t\tthis.name,\n\t\t\t{ type: \"custom\", customType, ...(data === undefined ? {} : { data }) },\n\t\t\tcontext,\n\t\t);\n\t}\n}\n\n/** Package-internal typed boundary shared by concrete session repositories. */\nexport class StorageBackedSession<TMetadata extends SessionMetadata = SessionMetadata> implements Session<TMetadata> {\n\treadonly metadata: TMetadata;\n\treadonly idGenerator: IdGenerator;\n\tprivate readonly storage: Storage;\n\tprivate readonly mutationLine: MutationLine;\n\tprivate readonly onClose: (() => void) | undefined;\n\tprivate readonly branches = new Map<string, StorageBackedBranch>();\n\tprivate readonly closedError = new Error(\"Session is closed\");\n\tprivate state: \"open\" | \"closing\" | \"closed\" = \"open\";\n\tprivate closePromise: Promise<void> | undefined;\n\n\tconstructor(metadata: TMetadata, storage: Storage, options: StorageBackedSessionOptions = {}) {\n\t\tthis.metadata = metadata;\n\t\tthis.idGenerator = options.idGenerator ?? { next: uuidv7 };\n\t\tthis.storage = storage;\n\t\tthis.mutationLine = options.mutationLine ?? new MutationLine();\n\t\tthis.onClose = options.onClose;\n\t}\n\n\tasync beginMutation(_context: Context): Promise<SessionMutation> {\n\t\tthis.assertOpen();\n\t\tlet grant!: (mutation: SessionMutation) => void;\n\t\tlet rejectGrant!: (error: unknown) => void;\n\t\tconst granted = new Promise<SessionMutation>((resolve, reject) => {\n\t\t\tgrant = resolve;\n\t\t\trejectGrant = reject;\n\t\t});\n\t\tlet release!: () => void;\n\t\tconst finished = new Promise<void>((resolve) => {\n\t\t\trelease = resolve;\n\t\t});\n\t\tconst line = this.mutationLine.run(async () => {\n\t\t\tgrant(new StorageBackedSessionMutation(this.storage, release));\n\t\t\tawait finished;\n\t\t});\n\t\tvoid line.catch(rejectGrant);\n\t\treturn granted;\n\t}\n\n\tasync mutate<T>(mutation: SessionMutationCallback<T>, context: Context): Promise<T> {\n\t\tconst mutator = await this.beginMutation(context);\n\t\ttry {\n\t\t\treturn await mutation(mutator, context);\n\t\t} finally {\n\t\t\tawait mutator.end(context);\n\t\t}\n\t}\n\n\tasync getEntries(ids: string[], context: Context): Promise<Map<string, Entry>> {\n\t\tthis.assertOpen();\n\t\treturn this.storage.getEntries(ids, context);\n\t}\n\n\tasync getEntry(id: string, context: Context): Promise<Entry | undefined> {\n\t\treturn (await this.getEntries([id], context)).get(id);\n\t}\n\n\tasync getValue<T>(address: Value<T>, context: Context): Promise<StoredValue<T> | undefined> {\n\t\tthis.assertOpen();\n\t\treturn this.storage.getValue(address, context);\n\t}\n\n\tasync scanValues<T>(prefix: Value<T>, context: Context): Promise<StoredValue<T>[]> {\n\t\tthis.assertOpen();\n\t\treturn this.storage.scanValues(prefix, context);\n\t}\n\n\tasync readList<T>(\n\t\taddress: ValueList<T>,\n\t\toptions: ListReadOptions | undefined,\n\t\tcontext: Context,\n\t): Promise<ListElement<T>[]> {\n\t\tthis.assertOpen();\n\t\treturn this.storage.readList(address, options, context);\n\t}\n\n\tasync scanBranch(query: StorageBranchScan, context: Context): Promise<Entry[]> {\n\t\tthis.assertOpen();\n\t\treturn this.storage.scanBranch(query, context);\n\t}\n\n\tasync getStats(context: Context): Promise<SessionStats> {\n\t\tthis.assertOpen();\n\t\treturn this.storage.getStats(context);\n\t}\n\n\tasync getName(context: Context): Promise<string | undefined> {\n\t\treturn (await this.getValue(sessionName, context))?.value;\n\t}\n\n\tasync getLabel(targetId: string, context: Context): Promise<string | undefined> {\n\t\treturn (await this.getValue(entryLabel(targetId), context))?.value;\n\t}\n\n\tasync findEntries(query: EntryQuery | undefined, context: Context): Promise<Entry[]> {\n\t\tquery ??= {};\n\t\tthis.assertOpen();\n\t\tconst order = query.order ?? \"desc\";\n\t\tif (query.cursor !== undefined) {\n\t\t\tif (order === \"asc\" && query.cursor.seq === Number.MAX_SAFE_INTEGER) return [];\n\t\t\tif (order === \"desc\" && query.cursor.seq <= 1) return [];\n\t\t}\n\t\treturn this.storage.scanEntries(\n\t\t\t{\n\t\t\t\ttype: query.type,\n\t\t\t\tcustomType: query.customType,\n\t\t\t\torder,\n\t\t\t\tlimit: query.limit,\n\t\t\t\t...(query.cursor === undefined\n\t\t\t\t\t? {}\n\t\t\t\t\t: order === \"asc\"\n\t\t\t\t\t\t? { fromSeq: query.cursor.seq + 1 }\n\t\t\t\t\t\t: { toSeq: query.cursor.seq - 1 }),\n\t\t\t},\n\t\t\tcontext,\n\t\t);\n\t}\n\n\tasync findEntry(query: EntryQuery | undefined, context: Context): Promise<Entry | undefined> {\n\t\tquery ??= {};\n\t\treturn (\n\t\t\tawait this.findEntries({ ...query, limit: query.limit === undefined ? 1 : Math.min(query.limit, 1) }, context)\n\t\t)[0];\n\t}\n\n\tasync branch(name: string, context: Context): Promise<Branch | undefined> {\n\t\tthis.assertValidBranchName(name);\n\t\tif ((await this.getValue(branchTip(name), context)) === undefined) return undefined;\n\t\treturn this.getOrCreateBranchObject(name);\n\t}\n\n\tasync createBranch(name: string, at: string | null, context: Context): Promise<Branch> {\n\t\tthis.assertOpen();\n\t\tthis.assertValidBranchName(name);\n\t\tawait this.mutate(async (mutator) => {\n\t\t\tif ((await mutator.getValue(branchTip(name), context)) !== undefined) {\n\t\t\t\tthrow new SessionBranchExistsError(name);\n\t\t\t}\n\t\t\tif (at !== null && !(await mutator.getEntries([at], context)).has(at)) {\n\t\t\t\tthrow new SessionUnknownTargetError(at);\n\t\t\t}\n\t\t\tawait mutator.commit([setValueWrite(branchTip(name), at)], context);\n\t\t}, context);\n\t\treturn this.getOrCreateBranchObject(name);\n\t}\n\n\tsetValue<T>(address: Value<T>, next: NoInfer<T>, context: Context): Promise<void> {\n\t\treturn this.mutate(async (mutator) => {\n\t\t\tawait mutator.commit([setValueWrite(address, next)], context);\n\t\t}, context);\n\t}\n\n\tdeleteValue<T>(address: Value<T>, context: Context): Promise<void> {\n\t\treturn this.mutate(async (mutator) => {\n\t\t\tawait mutator.commit([deleteValueWrite(address)], context);\n\t\t}, context);\n\t}\n\n\tappendList<T>(address: ValueList<T>, element: NoInfer<T>, context: Context): Promise<void> {\n\t\treturn this.mutate(async (mutator) => {\n\t\t\tawait mutator.commit([appendListWrite(address, element)], context);\n\t\t}, context);\n\t}\n\n\tdeleteList<T>(address: ValueList<T>, context: Context): Promise<void> {\n\t\treturn this.mutate(async (mutator) => {\n\t\t\tawait mutator.commit([deleteListWrite(address)], context);\n\t\t}, context);\n\t}\n\n\tsetName(name: string | undefined, context: Context): Promise<void> {\n\t\treturn name === undefined ? this.deleteValue(sessionName, context) : this.setValue(sessionName, name, context);\n\t}\n\n\tsetLabel(targetId: string, label: string | undefined, context: Context): Promise<void> {\n\t\tconst address = entryLabel(targetId);\n\t\treturn label === undefined ? this.deleteValue(address, context) : this.setValue(address, label, context);\n\t}\n\n\tclose(context: Context): Promise<void> {\n\t\tif (this.closePromise !== undefined) return this.closePromise;\n\t\tthis.state = \"closing\";\n\t\tthis.closePromise = this.mutationLine\n\t\t\t.seal(this.closedError)\n\t\t\t.then(() => this.storage.close(context))\n\t\t\t.finally(() => {\n\t\t\t\tthis.state = \"closed\";\n\t\t\t\tthis.onClose?.();\n\t\t\t});\n\t\treturn this.closePromise;\n\t}\n\n\tasync getBranchTip(name: string, context: Context): Promise<string | null> {\n\t\tconst stored = await this.getValue(branchTip(name), context);\n\t\tif (stored === undefined) throw new SessionInvariantError(`Unknown branch: ${name}`);\n\t\treturn stored.value;\n\t}\n\n\tasync appendToBranch(\n\t\tname: string,\n\t\tentry: { type: \"message\"; message: AgentMessage } | { type: \"custom\"; customType: string; data?: JsonValue },\n\t\tcontext: Context,\n\t): Promise<string> {\n\t\tthis.assertOpen();\n\t\tif (entry.type === \"message\" && entry.message.role === \"assistant\" && entry.message.stopReason === \"pending\") {\n\t\t\tthrow new SessionPendingAssistantMessageError();\n\t\t}\n\t\tconst id = this.idGenerator.next();\n\t\tawait this.mutate(async (mutator) => {\n\t\t\tconst tip = await mutator.getValue(branchTip(name), context);\n\t\t\tif (tip === undefined) throw new SessionInvariantError(`Unknown branch: ${name}`);\n\t\t\tawait mutator.commit(\n\t\t\t\t[\n\t\t\t\t\tinsertEntry(\n\t\t\t\t\t\tentry.type === \"message\"\n\t\t\t\t\t\t\t? { id, parentId: tip.value, type: \"message\", message: entry.message }\n\t\t\t\t\t\t\t: {\n\t\t\t\t\t\t\t\t\tid,\n\t\t\t\t\t\t\t\t\tparentId: tip.value,\n\t\t\t\t\t\t\t\t\ttype: \"custom\",\n\t\t\t\t\t\t\t\t\tcustomType: entry.customType,\n\t\t\t\t\t\t\t\t\t...(entry.data === undefined ? {} : { data: entry.data }),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t),\n\t\t\t\t\tsetValueWrite(branchTip(name), id),\n\t\t\t\t],\n\t\t\t\tcontext,\n\t\t\t);\n\t\t}, context);\n\t\treturn id;\n\t}\n\n\tprivate getOrCreateBranchObject(name: string): Branch {\n\t\tlet branch = this.branches.get(name);\n\t\tif (branch === undefined) {\n\t\t\tbranch = new StorageBackedBranch(name, this);\n\t\t\tthis.branches.set(name, branch);\n\t\t}\n\t\treturn branch;\n\t}\n\n\tprivate assertValidBranchName(name: string): void {\n\t\tif (name.length === 0) throw new SessionInvalidBranchError(name, \"branch name must not be empty\");\n\t\tif (name.includes(\"\\u0000\")) {\n\t\t\tthrow new SessionInvalidBranchError(name, \"branch name must not contain \\\\u0000\");\n\t\t}\n\t}\n\n\tprivate assertOpen(): void {\n\t\tif (this.state !== \"open\") throw this.closedError;\n\t}\n}\n"]}