agents 0.26.0 → 0.28.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 (301) hide show
  1. package/README.md +8 -9
  2. package/dist/abortable-C1SpfVoi.js +21 -0
  3. package/dist/abortable-C1SpfVoi.js.map +1 -0
  4. package/dist/{agent-routing-0DR0Tk2v.d.ts → agent-routing-QDcchcQP.d.ts} +16 -16
  5. package/dist/agent-routing.d.ts +1 -1
  6. package/dist/agent-tool-types.d.ts +1 -1
  7. package/dist/{agent-tools-YrATZJu2.d.ts → agent-tools-DHL2XI7u.d.ts} +2 -2
  8. package/dist/agent-tools.d.ts +1 -1
  9. package/dist/ai-ahruGw7e.d.ts +239 -0
  10. package/dist/ai-sdk-Bdsf6mSA.js +2444 -0
  11. package/dist/ai-sdk-Bdsf6mSA.js.map +1 -0
  12. package/dist/apply-chunks-1FheRb9W.js +99 -0
  13. package/dist/apply-chunks-1FheRb9W.js.map +1 -0
  14. package/dist/broadcast-state-CEyI4uAK.js +69 -0
  15. package/dist/broadcast-state-CEyI4uAK.js.map +1 -0
  16. package/dist/browser/ai.d.ts +8 -227
  17. package/dist/browser/ai.js +259 -1
  18. package/dist/browser/ai.js.map +1 -0
  19. package/dist/browser/index.d.ts +56 -46
  20. package/dist/browser/index.js +4 -361
  21. package/dist/browser/{ai-sdk.d.ts → tools/ai-sdk.d.ts} +7 -7
  22. package/dist/browser/{ai-sdk.js → tools/ai-sdk.js} +6 -5
  23. package/dist/browser/tools/ai-sdk.js.map +1 -0
  24. package/dist/browser/tools/pi.d.ts +111 -0
  25. package/dist/browser/tools/pi.js +119 -0
  26. package/dist/browser/tools/pi.js.map +1 -0
  27. package/dist/browser/{tanstack-ai.d.ts → tools/tanstack-ai.d.ts} +39 -37
  28. package/dist/browser/{tanstack-ai.js → tools/tanstack-ai.js} +73 -59
  29. package/dist/browser/tools/tanstack-ai.js.map +1 -0
  30. package/dist/browser-CEdNlsaD.js +481 -0
  31. package/dist/browser-CEdNlsaD.js.map +1 -0
  32. package/dist/{browser-DE3d-RLk.d.ts → browser-D30VlpcA.d.ts} +63 -37
  33. package/dist/{browser-tool-CQ10e6Kj.js → browser-tool-4iomavs_.js} +198 -62
  34. package/dist/browser-tool-4iomavs_.js.map +1 -0
  35. package/dist/{browser-tool-DuNdlwZ9.d.ts → browser-tool-vtrPOV8e.d.ts} +25 -6
  36. package/dist/{capability-B4WbF81e.js → capability-DBAKc6UZ.js} +1 -3
  37. package/dist/capability-DBAKc6UZ.js.map +1 -0
  38. package/dist/{capability-runner-DBAnGr6L.d.ts → capability-runner-BiVUtjqC.d.ts} +9 -7
  39. package/dist/channel-Bak_6zDP.d.ts +333 -0
  40. package/dist/chat/index.d.ts +11 -9
  41. package/dist/chat/index.js +5 -194
  42. package/dist/chat/index.js.map +1 -1
  43. package/dist/chat/react.d.ts +2 -4
  44. package/dist/chat/react.js +3 -1
  45. package/dist/chat/react.js.map +1 -1
  46. package/dist/chat-sdk/index.d.ts +1 -1
  47. package/dist/chat-sdk/index.js +1 -1
  48. package/dist/cli.js +144 -0
  49. package/dist/{client-je3koD9Z.d.ts → client-BGIQKJhX.d.ts} +2 -2
  50. package/dist/{client-fyQrLGkD.js → client-BnYbNT3z.js} +29 -5
  51. package/dist/client-BnYbNT3z.js.map +1 -0
  52. package/dist/client-tools-aIBO0Fk7.d.ts +53 -0
  53. package/dist/client.d.ts +1 -1
  54. package/dist/{connector-58XDGvc3.js → connector-CtZylXdk.js} +3 -603
  55. package/dist/connector-CtZylXdk.js.map +1 -0
  56. package/dist/{connector-Cl-VqPmA.d.ts → connector-DEXzVoaY.d.ts} +9 -374
  57. package/dist/conversations-FjHDRZyD.d.ts +192 -0
  58. package/dist/{current-agent-vAk_5JMt.d.ts → current-agent-CKgT5d1O.d.ts} +3 -5
  59. package/dist/current-agent-DhoDkSnH.js.map +1 -1
  60. package/dist/daemon-core-Buubj-y1.js +481 -0
  61. package/dist/daemon-core-Buubj-y1.js.map +1 -0
  62. package/dist/daemon-core-CbohVPAu.d.ts +132 -0
  63. package/dist/{do-oauth-client-provider-Tmf1vgKz.d.ts → do-oauth-client-provider-DfsUcpc3.d.ts} +7 -1
  64. package/dist/{durable-object-lifecycle-HhgOMWq9.d.ts → durable-object-lifecycle-DOI_bzCH.d.ts} +2 -2
  65. package/dist/{channels/email.d.ts → experimental/channels/email/index.d.ts} +25 -12
  66. package/dist/{channels/email.js → experimental/channels/email/index.js} +13 -35
  67. package/dist/experimental/channels/email/index.js.map +1 -0
  68. package/dist/experimental/channels/index.d.ts +270 -0
  69. package/dist/experimental/channels/index.js +1186 -0
  70. package/dist/experimental/channels/index.js.map +1 -0
  71. package/dist/{channels/slack.d.ts → experimental/channels/slack/index.d.ts} +19 -9
  72. package/dist/experimental/channels/slack/index.js +267 -0
  73. package/dist/experimental/channels/slack/index.js.map +1 -0
  74. package/dist/{channels/telegram.d.ts → experimental/channels/telegram/index.d.ts} +19 -9
  75. package/dist/experimental/channels/telegram/index.js +198 -0
  76. package/dist/experimental/channels/telegram/index.js.map +1 -0
  77. package/dist/experimental/channels/web/ai-sdk.d.ts +55 -0
  78. package/dist/experimental/channels/web/ai-sdk.js +266 -0
  79. package/dist/experimental/channels/web/ai-sdk.js.map +1 -0
  80. package/dist/experimental/channels/web/client.d.ts +97 -0
  81. package/dist/experimental/channels/web/client.js +349 -0
  82. package/dist/experimental/channels/web/client.js.map +1 -0
  83. package/dist/experimental/channels/web/index.d.ts +189 -0
  84. package/dist/experimental/channels/web/index.js +332 -0
  85. package/dist/experimental/channels/web/index.js.map +1 -0
  86. package/dist/gateway-BFO6vRDn.d.ts +100 -0
  87. package/dist/handle-zAzh0UW2.d.ts +460 -0
  88. package/dist/harness/ai-sdk/index.d.ts +175 -0
  89. package/dist/harness/ai-sdk/index.js +605 -0
  90. package/dist/harness/ai-sdk/index.js.map +1 -0
  91. package/dist/harness/container/daemon/index.d.ts +76 -0
  92. package/dist/harness/container/daemon/index.js +3 -0
  93. package/dist/harness/container/index.d.ts +740 -0
  94. package/dist/harness/container/index.js +2152 -0
  95. package/dist/harness/container/index.js.map +1 -0
  96. package/dist/harness/container/runtime/index.d.ts +144 -0
  97. package/dist/harness/container/runtime/index.js +1082 -0
  98. package/dist/harness/container/runtime/index.js.map +1 -0
  99. package/dist/harness/opencode/index.d.ts +369 -0
  100. package/dist/harness/opencode/index.js +1072 -0
  101. package/dist/harness/opencode/index.js.map +1 -0
  102. package/dist/harness/pi/index.d.ts +3 -2
  103. package/dist/harness/pi/index.js +3 -3
  104. package/dist/harness/store/index.d.ts +24 -0
  105. package/dist/harness/store/index.js +2 -0
  106. package/dist/harness/think/index.d.ts +821 -0
  107. package/dist/harness/think/index.js +2721 -0
  108. package/dist/harness/think/index.js.map +1 -0
  109. package/dist/harness-B6B9S3rb.d.ts +203 -0
  110. package/dist/{images-iiTDSyRu.js → images-Ce9SCu3X.js} +2 -248
  111. package/dist/images-Ce9SCu3X.js.map +1 -0
  112. package/dist/{index-BreL0YrQ.d.ts → index-BEL3ZV-s.d.ts} +2 -6
  113. package/dist/index-CBt8oRJt.d.ts +198 -0
  114. package/dist/index.d.ts +5 -5
  115. package/dist/index.js +2 -2
  116. package/dist/ingress-EFbrS547.js +9 -0
  117. package/dist/ingress-EFbrS547.js.map +1 -0
  118. package/dist/input-schema-BQykTEp_.js +20 -0
  119. package/dist/input-schema-BQykTEp_.js.map +1 -0
  120. package/dist/input-schema-D2QAtHZH.js +23 -0
  121. package/dist/input-schema-D2QAtHZH.js.map +1 -0
  122. package/dist/internal-kmw70xwR.js +46 -0
  123. package/dist/internal-kmw70xwR.js.map +1 -0
  124. package/dist/internal_context.d.ts +1 -1
  125. package/dist/lifecycle/index.d.ts +3 -3
  126. package/dist/lifecycle/index.js +2 -2
  127. package/dist/{lifecycle-CFu6OV03.js → lifecycle-DGorpAmA.js} +2 -4
  128. package/dist/lifecycle-DGorpAmA.js.map +1 -0
  129. package/dist/mcp/client/do-oauth-client-provider.d.ts +1 -1
  130. package/dist/mcp/client/do-oauth-client-provider.js +9 -0
  131. package/dist/mcp/client/do-oauth-client-provider.js.map +1 -1
  132. package/dist/mcp/client/index.d.ts +1 -1
  133. package/dist/mcp/client/index.js +1 -1
  134. package/dist/mcp/client/x402.d.ts +35 -4
  135. package/dist/mcp/client/x402.js +24 -3
  136. package/dist/mcp/client/x402.js.map +1 -1
  137. package/dist/mcp/index.d.ts +1 -1
  138. package/dist/mcp/index.js +2 -2
  139. package/dist/models/ai-sdk/index.d.ts +16 -14
  140. package/dist/models/ai-sdk/index.js +1 -2442
  141. package/dist/models/opencode/index.d.ts +65 -0
  142. package/dist/models/opencode/index.js +285 -0
  143. package/dist/models/opencode/index.js.map +1 -0
  144. package/dist/models/pi-ai/index.d.ts +9 -7
  145. package/dist/models/pi-ai/index.js +2 -1
  146. package/dist/models/pi-ai/index.js.map +1 -1
  147. package/dist/options-CiIsJHXR.d.ts +130 -0
  148. package/dist/protocol-BEgrJYC5.d.ts +331 -0
  149. package/dist/protocol-CukuI73M.d.ts +386 -0
  150. package/dist/protocol-cOklVBBD.js +227 -0
  151. package/dist/protocol-cOklVBBD.js.map +1 -0
  152. package/dist/{protocol-kHsr-f0X.js → protocol-eXeJxhgu.js} +2 -67
  153. package/dist/protocol-eXeJxhgu.js.map +1 -0
  154. package/dist/protocol-y2sSY584.js +148 -0
  155. package/dist/protocol-y2sSY584.js.map +1 -0
  156. package/dist/queue/index.d.ts +1 -1
  157. package/dist/queue/index.js +1 -1
  158. package/dist/{queue-BB-zfIYF.js → queue-CcIjVYTE.js} +2 -2
  159. package/dist/{queue-BB-zfIYF.js.map → queue-CcIjVYTE.js.map} +1 -1
  160. package/dist/react.d.ts +2 -2
  161. package/dist/routing/index.d.ts +2 -2
  162. package/dist/routing/index.js +1 -1
  163. package/dist/{scheduler-RdACNXDP.d.ts → scheduler-BCLESHSC.d.ts} +2 -12
  164. package/dist/{scheduler-DZ3xQfeK.js → scheduler-FIHv2-kJ.js} +2 -4
  165. package/dist/scheduler-FIHv2-kJ.js.map +1 -0
  166. package/dist/schedules/index.d.ts +1 -1
  167. package/dist/schedules/index.js +1 -1
  168. package/dist/serializable.d.ts +1 -1
  169. package/dist/session-store-Do4xkDcf.js +606 -0
  170. package/dist/session-store-Do4xkDcf.js.map +1 -0
  171. package/dist/session-store-DoPY12xM.d.ts +383 -0
  172. package/dist/sessions/index.d.ts +11 -434
  173. package/dist/sessions/index.js +1 -2271
  174. package/dist/sessions-_vN5BEZX.js +2272 -0
  175. package/dist/sessions-_vN5BEZX.js.map +1 -0
  176. package/dist/settings-C45hDliX.js +253 -0
  177. package/dist/settings-C45hDliX.js.map +1 -0
  178. package/dist/{transport-PfFnt-Ld.d.ts → settings-NgGwF7Qt.d.ts} +14 -208
  179. package/dist/{src-BZeu-SCD.js → src-CQxJFv4l.js} +8 -8
  180. package/dist/src-CQxJFv4l.js.map +1 -0
  181. package/dist/stall-watchdog-BpRF2uwG.js +195 -0
  182. package/dist/stall-watchdog-BpRF2uwG.js.map +1 -0
  183. package/dist/state/index.d.ts +1 -1
  184. package/dist/state/index.js +1 -3
  185. package/dist/state/index.js.map +1 -1
  186. package/dist/store-BKM4Xm9M.d.ts +332 -0
  187. package/dist/store-CslVzfN7.js +458 -0
  188. package/dist/store-CslVzfN7.js.map +1 -0
  189. package/dist/streams/index.d.ts +1 -1
  190. package/dist/streams/index.js +1 -1
  191. package/dist/{streams-DW-UCOUc.js → streams-lsHMJhRW.js} +17 -4
  192. package/dist/streams-lsHMJhRW.js.map +1 -0
  193. package/dist/{streams-Cmkj9QfW.d.ts → streams-vrCtbUIn.d.ts} +2 -2
  194. package/dist/sub-routing.d.ts +1 -1
  195. package/dist/tasks/index.d.ts +1 -1
  196. package/dist/tasks/index.js +1 -1
  197. package/dist/{tasks-68DESxf0.js → tasks-BN_5AWqI.js} +3 -2
  198. package/dist/tasks-BN_5AWqI.js.map +1 -0
  199. package/dist/{tasks-9YxYtByh.d.ts → tasks-E89KdwkS.d.ts} +2 -2
  200. package/dist/tool-CTp72Jb_.d.ts +278 -0
  201. package/dist/tool-CxKsvxjm.js +1126 -0
  202. package/dist/tool-CxKsvxjm.js.map +1 -0
  203. package/dist/tool-DoVberpN.d.ts +301 -0
  204. package/dist/tool-cQRkwSZZ.js +410 -0
  205. package/dist/tool-cQRkwSZZ.js.map +1 -0
  206. package/dist/tool-helpers-O5BDVEAY.js +58 -0
  207. package/dist/tool-helpers-O5BDVEAY.js.map +1 -0
  208. package/dist/transport-k2mFrtL8.d.ts +200 -0
  209. package/dist/turns-DCV3ycDl.js +317 -0
  210. package/dist/turns-DCV3ycDl.js.map +1 -0
  211. package/dist/voice/client.js +1 -1
  212. package/dist/voice/index.d.ts +2 -2
  213. package/dist/voice/index.js +1 -1
  214. package/dist/web/fetch/index.d.ts +89 -0
  215. package/dist/web/fetch/index.js +20 -0
  216. package/dist/web/fetch/index.js.map +1 -0
  217. package/dist/web/fetch/tools/ai-sdk.d.ts +80 -0
  218. package/dist/web/fetch/tools/ai-sdk.js +47 -0
  219. package/dist/web/fetch/tools/ai-sdk.js.map +1 -0
  220. package/dist/web/fetch/tools/pi.d.ts +84 -0
  221. package/dist/web/fetch/tools/pi.js +88 -0
  222. package/dist/web/fetch/tools/pi.js.map +1 -0
  223. package/dist/web/fetch/tools/tanstack-ai.d.ts +78 -0
  224. package/dist/web/fetch/tools/tanstack-ai.js +45 -0
  225. package/dist/web/fetch/tools/tanstack-ai.js.map +1 -0
  226. package/dist/web/search/index.d.ts +58 -0
  227. package/dist/web/search/index.js +2 -0
  228. package/dist/web/search/tools/ai-sdk.d.ts +77 -0
  229. package/dist/web/search/tools/ai-sdk.js +46 -0
  230. package/dist/web/search/tools/ai-sdk.js.map +1 -0
  231. package/dist/web/search/tools/pi.d.ts +82 -0
  232. package/dist/web/search/tools/pi.js +89 -0
  233. package/dist/web/search/tools/pi.js.map +1 -0
  234. package/dist/web/search/tools/tanstack-ai.d.ts +71 -0
  235. package/dist/web/search/tools/tanstack-ai.js +46 -0
  236. package/dist/web/search/tools/tanstack-ai.js.map +1 -0
  237. package/dist/websockets/index.d.ts +12 -296
  238. package/dist/websockets/index.js +1 -1
  239. package/dist/{websockets-Ci-LZFHH.js → websockets-C3zy8YR0.js} +20 -8
  240. package/dist/websockets-C3zy8YR0.js.map +1 -0
  241. package/dist/{wire-types-CrjKvDyi.d.ts → wire-types-Cv0iwjk5.d.ts} +3 -51
  242. package/dist/workflow-types.d.ts +1 -1
  243. package/dist/workflows.d.ts +1 -1
  244. package/dist/workflows.js +1 -1
  245. package/docs/browse-the-web.md +29 -1
  246. package/docs/fetch-the-web.md +276 -0
  247. package/docs/harnesses/pi.md +25 -0
  248. package/docs/harnesses/think.md +215 -0
  249. package/docs/index.md +99 -75
  250. package/docs/lifecycle.md +42 -3
  251. package/docs/queue.md +2 -3
  252. package/docs/scheduling.md +2 -6
  253. package/docs/search-the-web.md +135 -0
  254. package/package.json +148 -44
  255. package/dist/ai-fm7xx1BK.js +0 -312
  256. package/dist/ai-fm7xx1BK.js.map +0 -1
  257. package/dist/browser/ai-sdk.js.map +0 -1
  258. package/dist/browser/index.js.map +0 -1
  259. package/dist/browser/tanstack-ai.js.map +0 -1
  260. package/dist/browser-tool-CQ10e6Kj.js.map +0 -1
  261. package/dist/capability-B4WbF81e.js.map +0 -1
  262. package/dist/channel-Bnm4S7T2.d.ts +0 -491
  263. package/dist/channels/ai-sdk.d.ts +0 -46
  264. package/dist/channels/ai-sdk.js +0 -120
  265. package/dist/channels/ai-sdk.js.map +0 -1
  266. package/dist/channels/email.js.map +0 -1
  267. package/dist/channels/index.d.ts +0 -233
  268. package/dist/channels/index.js +0 -608
  269. package/dist/channels/index.js.map +0 -1
  270. package/dist/channels/slack.js +0 -614
  271. package/dist/channels/slack.js.map +0 -1
  272. package/dist/channels/tanstack-ai.d.ts +0 -39
  273. package/dist/channels/tanstack-ai.js +0 -17
  274. package/dist/channels/tanstack-ai.js.map +0 -1
  275. package/dist/channels/telegram.js +0 -427
  276. package/dist/channels/telegram.js.map +0 -1
  277. package/dist/channels/voice.d.ts +0 -45
  278. package/dist/channels/voice.js +0 -122
  279. package/dist/channels/voice.js.map +0 -1
  280. package/dist/client-fyQrLGkD.js.map +0 -1
  281. package/dist/connector-58XDGvc3.js.map +0 -1
  282. package/dist/images-iiTDSyRu.js.map +0 -1
  283. package/dist/index-BB0kqhIz.d.ts +0 -101
  284. package/dist/ingress-BfetZbMO.js +0 -83
  285. package/dist/ingress-BfetZbMO.js.map +0 -1
  286. package/dist/internal-CYlgHl1l.js +0 -59
  287. package/dist/internal-CYlgHl1l.js.map +0 -1
  288. package/dist/lifecycle-CFu6OV03.js.map +0 -1
  289. package/dist/models/ai-sdk/index.js.map +0 -1
  290. package/dist/protocol-kHsr-f0X.js.map +0 -1
  291. package/dist/scheduler-DZ3xQfeK.js.map +0 -1
  292. package/dist/sessions/index.js.map +0 -1
  293. package/dist/src-BZeu-SCD.js.map +0 -1
  294. package/dist/streams-DW-UCOUc.js.map +0 -1
  295. package/dist/surface-bZZJqBka.js +0 -17
  296. package/dist/surface-bZZJqBka.js.map +0 -1
  297. package/dist/tasks-68DESxf0.js.map +0 -1
  298. package/dist/tool-schema-CBjGPrsQ.js +0 -31
  299. package/dist/tool-schema-CBjGPrsQ.js.map +0 -1
  300. package/dist/websockets-Ci-LZFHH.js.map +0 -1
  301. package/docs/channels.md +0 -323
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["errorText"],"sources":["../../../src/harness/container/link.ts","../../../src/harness/container/daemon-source.generated.ts","../../../src/harness/container/managed-image.ts","../../../src/harness/container/harness.ts","../../../src/harness/container/agents.ts","../../../src/harness/container/egress.ts"],"sourcesContent":["/**\n * The object's side of one session socket: dial the daemon through the\n * container's TCP port, read its `hello`, then hand every later frame to\n * the harness. Failures to reach the daemon are values, so the harness can\n * decide between retrying and giving up.\n */\n\nimport {\n CONTAINER_HEALTH_PATH,\n CONTAINER_PROTOCOL_VERSION,\n CONTAINER_SESSION_PATH,\n CONTAINER_TOKEN_HEADER,\n parseDaemonMessage,\n type DaemonFrame,\n type DaemonMessage,\n type HostMessage\n} from \"./protocol\";\n\n/** The daemon's greeting. */\nexport type Hello = Extract<DaemonMessage, { type: \"hello\" }>;\n\n/** Why a link could not be opened. */\nexport type LinkError =\n | { readonly _tag: \"unreachable\"; readonly message: string }\n | { readonly _tag: \"protocol\"; readonly message: string }\n /** Not a failure: the harness stopped a container to try a better start. */\n | { readonly _tag: \"retry\"; readonly message: string };\n\n/** A link result. */\nexport type LinkResult<T> =\n | { readonly _tag: \"ok\"; readonly value: T }\n | { readonly _tag: \"err\"; readonly error: LinkError };\n\n/** What the link reports after `hello`. */\nexport type LinkHandlers = {\n frame(seq: number, frame: DaemonFrame): void;\n /** The daemon has sent every frame it kept after the replay cursor. */\n caughtUp(): void;\n /** The socket closed, from either side. Called once. */\n closed(): void;\n};\n\nconst HELLO_TIMEOUT_MS = 10_000;\nconst CONNECT_TIMEOUT_MS = 10_000;\nconst HEALTH_TIMEOUT_MS = 2_000;\n\nfunction unreachable(message: string): LinkResult<never> {\n return { _tag: \"err\", error: { _tag: \"unreachable\", message } };\n}\n\nfunction errorText(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\n/**\n * Wait until the daemon answers its health check.\n *\n * @param port - The container's TCP port.\n * @param timeoutMs - How long to keep trying.\n * @param running - Whether the container still runs; waiting stops early\n * once it does not.\n * @returns `ok`, or `unreachable` after the timeout or once it stops.\n */\nexport async function waitHealthy(\n port: Fetcher,\n timeoutMs: number,\n running: () => boolean\n): Promise<LinkResult<void>> {\n const deadline = Date.now() + timeoutMs;\n let delay = 250;\n let last = \"no answer\";\n for (;;) {\n try {\n const response = await port.fetch(\n `http://container${CONTAINER_HEALTH_PATH}`,\n { signal: AbortSignal.timeout(HEALTH_TIMEOUT_MS) }\n );\n await response.body?.cancel();\n if (response.ok) return { _tag: \"ok\", value: undefined };\n last = `health check answered ${response.status}`;\n } catch (error) {\n last = errorText(error);\n }\n if (!running()) return unreachable(\"the container stopped\");\n if (Date.now() + delay > deadline) return unreachable(last);\n await new Promise((resolve) => setTimeout(resolve, delay));\n delay = Math.min(delay * 2, 2_000);\n }\n}\n\n/** One open session socket. */\nexport class DaemonLink {\n readonly #socket: WebSocket;\n #open = true;\n\n private constructor(socket: WebSocket) {\n this.#socket = socket;\n }\n\n /**\n * Dial the daemon for one session and wait for its `hello`.\n *\n * @param port - The container's TCP port.\n * @param session - The session id.\n * @param token - The shared secret the container was started with.\n * @param handlers - Called for frames after `hello`, and on close.\n * @returns The link and the greeting, or why it failed.\n */\n static async open(\n port: Fetcher,\n session: string,\n token: string,\n handlers: LinkHandlers\n ): Promise<LinkResult<{ readonly link: DaemonLink; readonly hello: Hello }>> {\n let response: Response;\n try {\n response = await port.fetch(\n `http://container${CONTAINER_SESSION_PATH}${encodeURIComponent(session)}`,\n {\n headers: { Upgrade: \"websocket\", [CONTAINER_TOKEN_HEADER]: token },\n signal: AbortSignal.timeout(CONNECT_TIMEOUT_MS)\n }\n );\n } catch (error) {\n return unreachable(errorText(error));\n }\n const socket = response.webSocket;\n if (!socket) {\n await response.body?.cancel();\n return unreachable(`upgrade refused with ${response.status}`);\n }\n socket.accept();\n const link = new DaemonLink(socket);\n return new Promise((resolve) => {\n let greeted = false;\n const timer = setTimeout(() => {\n if (greeted) return;\n link.close();\n resolve(unreachable(\"no hello from the daemon\"));\n }, HELLO_TIMEOUT_MS);\n socket.addEventListener(\"message\", (event) => {\n const text =\n typeof event.data === \"string\"\n ? event.data\n : new TextDecoder().decode(event.data);\n const message = parseDaemonMessage(text);\n if (!message) return;\n if (!greeted) {\n if (message.type !== \"hello\") return;\n greeted = true;\n clearTimeout(timer);\n if (message.protocol !== CONTAINER_PROTOCOL_VERSION) {\n link.close();\n resolve({\n _tag: \"err\",\n error: {\n _tag: \"protocol\",\n message: `daemon speaks protocol ${message.protocol}, the harness ${CONTAINER_PROTOCOL_VERSION}`\n }\n });\n return;\n }\n resolve({ _tag: \"ok\", value: { link, hello: message } });\n return;\n }\n if (message.type === \"frame\")\n handlers.frame(message.seq, message.frame);\n else if (message.type === \"caught-up\") handlers.caughtUp();\n });\n const onClose = () => {\n if (!link.#open) return;\n link.#open = false;\n clearTimeout(timer);\n if (!greeted) resolve(unreachable(\"socket closed before hello\"));\n else handlers.closed();\n };\n socket.addEventListener(\"close\", onClose);\n socket.addEventListener(\"error\", onClose);\n });\n }\n\n /** Whether the socket is still open. */\n get open(): boolean {\n return this.#open;\n }\n\n /**\n * Send one message. Returns false when the socket has closed.\n *\n * @param message - The message.\n * @returns Whether it was handed to the socket.\n */\n send(message: HostMessage): boolean {\n if (!this.#open) return false;\n try {\n this.#socket.send(JSON.stringify(message));\n return true;\n } catch {\n return false;\n }\n }\n\n /** Close the socket. Does not call `closed`. */\n close(): void {\n if (!this.#open) return;\n this.#open = false;\n try {\n this.#socket.close(1000, \"closed by the harness\");\n } catch {\n // Already closing.\n }\n }\n}\n","// Generated by scripts/build-daemon.ts. Do not edit.\n\n/** The harness daemon, bundled: one Node ES module. */\nexport const DAEMON_SOURCE: string = \"var $=\\\"/healthz\\\",M=\\\"/sessions/\\\",z=\\\"x-cf-harness-token\\\",x={token:\\\"CF_HARNESS_TOKEN\\\",runtimeId:\\\"CF_HARNESS_RUNTIME_ID\\\",port:\\\"CF_HARNESS_PORT\\\"},K=4001,W=4003,xe=256*1024;function B(n){return typeof n==\\\"object\\\"&&n!==null&&!Array.isArray(n)}function k(n){return typeof n==\\\"string\\\"}function E(n){return typeof n==\\\"number\\\"&&Number.isSafeInteger(n)&&n>=0}function A(n){if(n===null)return!0;switch(typeof n){case\\\"string\\\":case\\\"boolean\\\":return!0;case\\\"number\\\":return Number.isFinite(n);case\\\"object\\\":return Array.isArray(n)?n.every(A):Object.values(n).every(A);default:return!1}}function be(n){return k(n)?!0:Array.isArray(n)&&n.every(e=>B(e)&&(e.type===\\\"text\\\"&&k(e.text)||e.type===\\\"image\\\"&&k(e.mediaType)&&k(e.data)))}function U(n){return B(n)&&(n.model===void 0||k(n.model))&&(n.options===void 0||A(n.options))}function Ie(n){try{return JSON.parse(n)}catch{return}}function G(n){let e=Ie(n);if(B(e))switch(e.type){case\\\"restore\\\":return E(e.generation)&&Array.isArray(e.entries)&&e.entries.every(A)?{type:\\\"restore\\\",generation:e.generation,entries:e.entries}:void 0;case\\\"open\\\":return E(e.generation)&&U(e.settings)&&Array.isArray(e.restore)&&e.restore.every(A)?{type:\\\"open\\\",generation:e.generation,settings:e.settings,restore:e.restore}:void 0;case\\\"replay\\\":return E(e.after)?{type:\\\"replay\\\",after:e.after}:void 0;case\\\"prompt\\\":return k(e.operationId)&&be(e.input)&&(e.whenBusy===\\\"followUp\\\"||e.whenBusy===\\\"steer\\\")?{type:\\\"prompt\\\",operationId:e.operationId,input:e.input,whenBusy:e.whenBusy}:void 0;case\\\"abort\\\":return e.operationId===void 0?{type:\\\"abort\\\"}:k(e.operationId)?{type:\\\"abort\\\",operationId:e.operationId}:void 0;case\\\"configure\\\":return U(e.settings)?{type:\\\"configure\\\",settings:e.settings}:void 0;case\\\"ack\\\":return E(e.seq)?{type:\\\"ack\\\",seq:e.seq}:void 0;default:return}}function _(n){return typeof n==\\\"string\\\"?n:n.map(e=>e.type===\\\"text\\\"?e.text:\\\"\\\").join(`\\n`)}function Y(n){let e=[],t=[],r=0;for(let o of n){let s=JSON.stringify(o).length;t.length>0&&r+s>xe&&(e.push(t),t=[],r=0),t.push(o),r+=s}return t.length>0&&e.push(t),e}var X=1e3,T=class{#e;#n;#s;#i=new Map;constructor(e){this.#e=e.adapter,this.#n=e.runtimeId,this.#s=e.maxKeptFrames??1e4}connect(e,t){let r=this.#i.get(e);return r||(r=new J(e,this.#e,this.#n,this.#s),this.#i.set(e,r)),r.attach(t)}async close(){await Promise.all([...this.#i.values()].map(e=>e.shutdown()))}},J=class{#e;#n;#s;#i;#a=0;#r=[];#t=new Map;#l=[];#o;#d;#y;#u;#f=!1;#h=Promise.resolve();constructor(e,t,r,o){this.#e=e,this.#n=t,this.#s=r,this.#i=o}attach(e){let t=this.#u;return this.#u=e,this.#f=!1,t?.close(K,\\\"replaced by a newer connection\\\"),this.#c(e,this.#w()),{receive:r=>{if(this.#u!==e)return;let o=G(r);if(!o){this.#c(e,{type:\\\"error\\\",message:\\\"unparseable message\\\"});return}this.#h=this.#h.then(()=>this.#C(o)).catch(s=>{this.#c(e,{type:\\\"error\\\",message:Z(s)})})},closed:()=>{this.#u===e&&(this.#u=void 0,this.#f=!1)}}}async shutdown(){this.#o?.controller.abort();let e=this.#d;this.#d=void 0,await e?.session.close().catch(()=>{})}#w(){let e=[];for(let t of this.#t.values()){let r=t.state;e.push(r.tag===\\\"settled\\\"?{operationId:t.id,status:\\\"settled\\\",outcome:r.outcome}:{operationId:t.id,status:r.tag})}return{type:\\\"hello\\\",protocol:1,runtimeId:this.#s,session:this.#e,adapter:{id:this.#n.id,version:this.#n.version,capabilities:[...this.#n.capabilities??[]]},open:this.#d?.generation??null,lastSeq:this.#a,operations:e}}async#C(e){switch(e.type){case\\\"restore\\\":this.#y?.generation!==e.generation&&(this.#y={generation:e.generation,entries:[]}),this.#y.entries.push(...e.entries);return;case\\\"open\\\":await this.#x(e);return;case\\\"replay\\\":this.#b(e.after);return;case\\\"prompt\\\":await this.#I(e.operationId,e.input,e.whenBusy);return;case\\\"abort\\\":this.#S(e.operationId);return;case\\\"configure\\\":await this.#d?.session.configure?.(e.settings);return;case\\\"ack\\\":this.#r=this.#r.filter(t=>t.seq>e.seq);return}}async#x(e){let t=this.#y;if(this.#y=void 0,this.#d?.generation===e.generation)return;let r=t?.generation===e.generation?[...t.entries,...e.restore]:e.restore;this.#d&&(this.#o?.controller.abort(),await this.#d.session.close().catch(()=>{}),this.#d=void 0);let o=await this.#n.open({session:this.#e,settings:e.settings,restore:r,emit:s=>this.#p({kind:\\\"event\\\",operationId:this.#o?.id??null,event:s}),persist:s=>{for(let i of Y(s))this.#p({kind:\\\"persist\\\",entries:i})},log:(s,i)=>this.#p({kind:\\\"event\\\",operationId:this.#o?.id??null,event:{type:\\\"log\\\",level:s,message:i}})});this.#d={generation:e.generation,session:o},this.#g()}#b(e){let t=this.#u;if(t){for(let r of this.#r)r.seq>e&&this.#c(t,{type:\\\"frame\\\",seq:r.seq,frame:r.frame});this.#c(t,{type:\\\"caught-up\\\",lastSeq:this.#a}),this.#f=!0}}async#I(e,t,r){if(this.#t.has(e))return;let o={id:e,input:t,whenBusy:r,state:{tag:\\\"queued\\\"}};this.#t.set(e,o),this.#A();let s=this.#o,i=this.#d?.session.steer;if(r===\\\"steer\\\"&&s&&i&&await i.call(this.#d?.session,t)&&this.#o===s){o.state={tag:\\\"running\\\"},s.folded.push(e),this.#p({kind:\\\"start\\\",operationId:e});return}this.#l.push(e),this.#g()}#S(e){let t=e===void 0?[...this.#t.keys()]:this.#t.has(e)?[e]:[];for(let r of t){let o=this.#t.get(r);if(o)if(o.state.tag===\\\"queued\\\"){let s=this.#l.indexOf(r);s>=0&&this.#l.splice(s,1),this.#m(o,{status:\\\"unanswered\\\",reason:\\\"aborted\\\"})}else o.state.tag===\\\"running\\\"&&this.#o?.controller.abort()}}#g(){let e=this.#d;if(this.#o||!e)return;let t=this.#l.shift();if(t===void 0)return;let r=this.#t.get(t);if(!r||r.state.tag!==\\\"queued\\\"){this.#g();return}let o={id:t,folded:[],controller:new AbortController};this.#o=o,r.state={tag:\\\"running\\\"},this.#p({kind:\\\"start\\\",operationId:t}),this.#k(e,r,o)}async#k(e,t,r){let o;try{o=await e.session.run({operationId:t.id,input:t.input,signal:r.controller.signal}),r.controller.signal.aborted&&o.status===\\\"done\\\"&&(o={status:\\\"unanswered\\\",reason:\\\"aborted\\\"})}catch(s){o={status:\\\"unanswered\\\",reason:r.controller.signal.aborted?\\\"aborted\\\":Z(s)}}this.#o===r&&(this.#o=void 0),this.#m(t,o);for(let s of r.folded){let i=this.#t.get(s);i&&this.#m(i,o)}this.#g()}#m(e,t){e.state.tag!==\\\"settled\\\"&&(e.state={tag:\\\"settled\\\",outcome:t},this.#p({kind:\\\"settle\\\",operationId:e.id,outcome:t}))}#p(e){this.#a+=1;let t=this.#a;this.#r.push({seq:t,frame:e}),this.#r.length>this.#i&&this.#r.splice(0,this.#r.length-this.#i);let r=this.#u;r&&this.#f&&this.#c(r,{type:\\\"frame\\\",seq:t,frame:e})}#c(e,t){try{e.send(JSON.stringify(t))}catch{}}#A(){if(!(this.#t.size<=X))for(let[e,t]of this.#t){if(this.#t.size<=X)return;t.state.tag===\\\"settled\\\"&&this.#t.delete(e)}}};function Z(n){return n instanceof Error?n.message:String(n)}var Q={id:\\\"echo\\\",version:\\\"1\\\",capabilities:[\\\"steer\\\"],open(n){let e=n.restore.length,t=[];return{async run(r){let o=_(r.input),s=/^slow (\\\\d+) ?(.*)$/s.exec(o);s&&await ke(Number(s[1]),r.signal);let i=/^fail ?(.*)$/s.exec(o);if(i)return{status:\\\"unanswered\\\",reason:i[1]||\\\"failed\\\"};e+=1;let d=s?s[2]??\\\"\\\":o,a=t.splice(0).map(u=>` + ${u}`).join(\\\"\\\"),l=`echo: ${d}${a} (turn ${e})`,c=`${r.operationId}:assistant`;return n.emit({type:\\\"text-delta\\\",messageId:c,delta:l}),n.emit({type:\\\"message\\\",message:{id:c,role:\\\"assistant\\\",parts:[{type:\\\"text\\\",text:l}],operationId:r.operationId,createdAt:Date.now()}}),n.persist([{turn:e,text:d}]),{status:\\\"done\\\",text:l}},steer(r){return t.push(_(r)),!0},async close(){}}}};function ke(n,e){return new Promise((t,r)=>{if(e.aborted){r(new Error(\\\"aborted\\\"));return}let o=setTimeout(()=>{e.removeEventListener(\\\"abort\\\",s),t()},n),s=()=>{clearTimeout(o),r(new Error(\\\"aborted\\\"))};e.addEventListener(\\\"abort\\\",s,{once:!0})})}import{spawn as Ne}from\\\"node:child_process\\\";import{createHash as De}from\\\"node:crypto\\\";import{constants as Me}from\\\"node:fs\\\";import{chown as re,copyFile as Be,mkdir as oe,readdir as se,readlink as Je,symlink as Re}from\\\"node:fs/promises\\\";import{homedir as Le}from\\\"node:os\\\";import{join as O,resolve as L,sep as Ve}from\\\"node:path\\\";import{createInterface as Fe}from\\\"node:readline\\\";import{mkdir as Ae,open as P,readdir as _e,rm as ve,stat as ee}from\\\"node:fs/promises\\\";import{dirname as Oe,join as Ee,relative as Te,resolve as te,sep as ne}from\\\"node:path\\\";function w(n){return typeof n==\\\"object\\\"&&n!==null&&!Array.isArray(n)}function v(n){if(Array.isArray(n))return n.filter(e=>typeof e==\\\"string\\\")}var R=128*1024;function Pe(n){return w(n)&&n.kind===\\\"file\\\"&&typeof n.path==\\\"string\\\"&&typeof n.offset==\\\"number\\\"&&typeof n.data==\\\"string\\\"}var N=class{#e;#n;#s=new Map;constructor(e,t){this.#e=te(e),this.#n=t}async restore(e){for(let t of this.#n){let r=this.#t(t);r!==void 0&&r!==this.#e&&await ve(r,{recursive:!0,force:!0})}for(let t of e){if(!Pe(t))continue;let r=this.#t(t.path);if(r===void 0)continue;await Ae(Oe(r),{recursive:!0});let o=t.offset===0?await P(r,\\\"w\\\"):await P(r,\\\"r+\\\").catch(()=>P(r,\\\"w\\\"));try{t.offset>0&&await o.truncate(t.offset),await o.write(Buffer.from(t.data,\\\"base64\\\"),0,void 0,t.offset)}finally{await o.close()}}for(let t of await this.#r()){let r=await ee(t);this.#s.set(t,{size:r.size,mtimeMs:r.mtimeMs})}}async collect(){let e=[];for(let t of await this.#r()){let r=await ee(t).catch(()=>{});if(!r)continue;let o=this.#s.get(t);if(o&&o.size===r.size&&o.mtimeMs===r.mtimeMs)continue;let s=o&&r.size>o.size?o.size:0,i=await this.#a(t,s,r.size),d=[];for(let a=0;a<i.length;a+=R)d.push(i.subarray(a,a+R));d.length===0&&d.push(i),d.forEach((a,l)=>{e.push(this.#i(t,s+l*R,a))}),this.#s.set(t,{size:s+i.length,mtimeMs:r.mtimeMs})}return e}#i(e,t,r){return{kind:\\\"file\\\",path:Te(this.#e,e).split(ne).join(\\\"/\\\"),offset:t,data:r.toString(\\\"base64\\\")}}async#a(e,t,r){let o=await P(e,\\\"r\\\");try{let s=Buffer.alloc(Math.max(0,r-t)),{bytesRead:i}=await o.read(s,0,s.length,t);return s.subarray(0,i)}finally{await o.close()}}async#r(){let e=[],t=async r=>{let o=await _e(r,{withFileTypes:!0}).catch(()=>[]);for(let s of o){let i=Ee(r,s.name);s.isDirectory()?await t(i):s.isFile()&&e.push(i)}};for(let r of this.#n){let o=this.#t(r);o!==void 0&&await t(o)}return e.sort()}#t(e){let t=te(this.#e,e);return t===this.#e||t.startsWith(this.#e+ne)?t:void 0}};var He=5e3,je=4096;function qe(n){let e={};for(let t of n){if(!w(t)||t.kind!==\\\"state\\\")continue;let r=t.values;if(w(r))for(let[o,s]of Object.entries(r))typeof s==\\\"string\\\"&&(e[o]=s)}return e}async function ie(n,e){await re(n,e.uid,e.gid);let t=await se(n,{withFileTypes:!0}).catch(()=>[]);for(let r of t){let o=O(n,r.name);r.isDirectory()?await ie(o,e):await re(o,e.uid,e.gid).catch(()=>{})}}async function Ue(n,e,t){let r=L(t),o=async(s,i)=>{let d=await se(s,{withFileTypes:!0}).catch(()=>[]);for(let a of d){let l=O(s,a.name),c=L(l);if(c===r||c.startsWith(r+Ve))continue;let u=O(i,a.name);a.isDirectory()?(await oe(u,{recursive:!0}),await o(l,u)):a.isSymbolicLink()?await Re(await Je(l),u).catch(()=>{}):a.isFile()&&await Be(l,u,Me.COPYFILE_EXCL).catch(()=>{})}};await o(L(n),e)}function $e(n,e){return O(n,De(\\\"sha256\\\").update(e).digest(\\\"hex\\\").slice(0,32))}var V=class{#e;#n;#s;#i;#a;#r;#t=Promise.resolve();constructor(e,t,r,o){this.#e=e,this.#n=t,this.#s=r,this.#i=o,this.#a=qe(t.restore),this.#r=t.settings}async run(e){let t={operationId:e.operationId,prompt:_(e.input),settings:this.#r,state:this.#a},r=this.#e.command(t),o=this.#e.parser(t),[s,...i]=r.argv;if(s===void 0)throw new Error(\\\"The CLI command is empty\\\");let d=this.#e.user,a=Ne(s,i,{cwd:this.#e.cwd??\\\"/workspace\\\",env:{...process.env,...r.env,HOME:this.#s},stdio:[\\\"pipe\\\",\\\"pipe\\\",\\\"pipe\\\"],...d?{uid:d.uid,gid:d.gid}:{}});a.stdin.on(\\\"error\\\",()=>{}),a.stdin.end(r.stdin??\\\"\\\");let l=\\\"\\\";a.stderr.setEncoding(\\\"utf8\\\"),a.stderr.on(\\\"data\\\",p=>{l=(l+p).slice(-je)});let c;Fe({input:a.stdout}).on(\\\"line\\\",p=>{if(p.trim()===\\\"\\\")return;let y;try{y=o.line(p)}catch(h){this.#n.log(\\\"warn\\\",`unreadable CLI output: ${String(h)}`);return}for(let h of y.events??[])this.#n.emit(h);y.state&&this.#l(y.state),y.outcome&&(c=y.outcome)});let b=()=>{a.kill(\\\"SIGINT\\\"),setTimeout(()=>a.kill(\\\"SIGKILL\\\"),He).unref()};e.signal.addEventListener(\\\"abort\\\",b,{once:!0});let m=setInterval(()=>{this.#o()},this.#e.syncIntervalMs??5e3),f=await new Promise(p=>{a.on(\\\"error\\\",y=>{l+=`\\n${y.message}`,p(null)}),a.on(\\\"close\\\",y=>p(y))});return clearInterval(m),e.signal.removeEventListener(\\\"abort\\\",b),await this.#o(),e.signal.aborted?{status:\\\"unanswered\\\",reason:\\\"aborted\\\"}:c??o.end({code:f,stderr:l})}configure(e){this.#r=e}async close(){await this.#t}#l(e){Object.entries(e).some(([r,o])=>this.#a[r]!==o)&&(this.#a={...this.#a,...e},this.#n.persist([{kind:\\\"state\\\",values:{...e}}]))}#o(){return this.#t=this.#t.then(async()=>{try{let e=await this.#i.collect();e.length>0&&this.#n.persist(e)}catch(e){this.#n.log(\\\"warn\\\",`state sync failed: ${String(e)}`)}}),this.#t}};function ae(n){let e=n.homes??O(Le(),\\\".harness\\\",\\\"sessions\\\");return{id:n.id,version:n.version??\\\"1\\\",capabilities:[\\\"resume\\\",\\\"fork\\\",\\\"model\\\"],async open(t){let r=$e(e,t.session);await oe(r,{recursive:!0}),n.skeleton&&await Ue(n.skeleton,r,e);let o=new N(r,n.stateDirs??[]);return await o.restore(t.restore),n.user&&await ie(r,n.user),new V(n,t,r,o)}}}function de(n){if(n===void 0)return null;try{return JSON.parse(JSON.stringify(n))}catch{return String(n)}}function ze(n){if(typeof n==\\\"string\\\")return n;if(Array.isArray(n)){let e=n.map(t=>typeof t==\\\"object\\\"&&t!==null&&\\\"type\\\"in t&&t.type===\\\"text\\\"&&\\\"text\\\"in t&&typeof t.text==\\\"string\\\"?t.text:void 0).filter(t=>t!==void 0);if(e.length===n.length)return e.join(`\\n`)}return de(n)}var D=class{#e=new Map;#n=new Map;#s=new Set;#i;#a;constructor(e=Date.now){this.#a=e}project(e,t){if(e.parent_tool_use_id)return[];switch(e.type){case\\\"stream_event\\\":return this.#r(e);case\\\"assistant\\\":return this.#t(e,t);case\\\"user\\\":return this.#l(e);case\\\"result\\\":return this.#o(e);default:return[]}}outcome(e,t){if(t)return{status:\\\"unanswered\\\",reason:\\\"aborted\\\"};if(e.subtype===\\\"success\\\"&&e.is_error!==!0)return{status:\\\"done\\\",text:e.result??\\\"\\\"};let r=e.errors?.join(\\\"; \\\")||e.result;return{status:\\\"unanswered\\\",reason:[e.subtype&&e.subtype!==\\\"success\\\"?e.subtype:\\\"\\\",r].filter(s=>s).join(\\\": \\\")||\\\"error\\\"}}#r(e){let t=e.event;if(!t)return[];if(t.type===\\\"message_start\\\")return this.#i=t.message?.id,[];let r=this.#i;return t.type!==\\\"content_block_delta\\\"||!r||!t.delta?[]:t.delta.type===\\\"text_delta\\\"&&t.delta.text?[{type:\\\"text-delta\\\",messageId:r,delta:t.delta.text}]:t.delta.type===\\\"thinking_delta\\\"&&t.delta.thinking?[{type:\\\"reasoning-delta\\\",messageId:r,delta:t.delta.thinking}]:[]}#t(e,t){let r=e.message?.id,o=e.message?.content;if(!r||!Array.isArray(o))return[];if(e.uuid!==void 0){if(this.#s.has(e.uuid))return[];this.#s.add(e.uuid)}let s=this.#e.get(r);s||(s={id:r,operationId:t,createdAt:this.#a(),parts:[]},this.#e.set(r,s));for(let i of o)i.type===\\\"text\\\"&&i.text?s.parts.push({type:\\\"text\\\",text:i.text}):i.type===\\\"thinking\\\"&&i.thinking?s.parts.push({type:\\\"reasoning\\\",text:i.thinking}):i.type===\\\"tool_use\\\"&&i.id&&(s.parts.push({type:\\\"tool\\\",toolCallId:i.id,toolName:i.name??\\\"tool\\\",input:de(i.input),state:\\\"running\\\"}),this.#n.set(i.id,r));return[{type:\\\"message\\\",message:this.#d(s)}]}#l(e){let t=e.message?.content;if(!Array.isArray(t))return[];let r=new Set;for(let o of t){if(o.type!==\\\"tool_result\\\"||!o.tool_use_id)continue;let s=this.#n.get(o.tool_use_id),i=s===void 0?void 0:this.#e.get(s);i&&(i.parts=i.parts.map(d=>d.type===\\\"tool\\\"&&d.toolCallId===o.tool_use_id?{...d,state:o.is_error?\\\"error\\\":\\\"done\\\",output:ze(o.content)}:d),r.add(i))}return[...r].map(o=>({type:\\\"message\\\",message:this.#d(o)}))}#o(e){return[{type:\\\"usage\\\",...e.usage?.input_tokens===void 0?{}:{inputTokens:e.usage.input_tokens},...e.usage?.output_tokens===void 0?{}:{outputTokens:e.usage.output_tokens},...e.total_cost_usd===void 0?{}:{costUsd:e.total_cost_usd}}]}#d(e){return{id:e.id,role:\\\"assistant\\\",parts:[...e.parts],...e.operationId===void 0?{}:{operationId:e.operationId},createdAt:e.createdAt}}};function Ke(n){if(!w(n))return{};let e=v(n.allowedTools),t=v(n.disallowedTools);return{...typeof n.appendSystemPrompt==\\\"string\\\"?{appendSystemPrompt:n.appendSystemPrompt}:{},...e?{allowedTools:e}:{},...t?{disallowedTools:t}:{},...typeof n.maxTurns==\\\"number\\\"?{maxTurns:n.maxTurns}:{}}}function We(n){let e=JSON.parse(n);if(!(typeof e!=\\\"object\\\"||e===null||!(\\\"type\\\"in e)))return e}var le={id:\\\"claude-code\\\",stateDirs:[\\\".claude/projects\\\"],command(n){let e=Ke(n.settings.options),t=[\\\"claude\\\",\\\"-p\\\",\\\"--output-format\\\",\\\"stream-json\\\",\\\"--verbose\\\",\\\"--include-partial-messages\\\",\\\"--dangerously-skip-permissions\\\"];return n.settings.model&&t.push(\\\"--model\\\",n.settings.model),n.state.sessionId&&t.push(\\\"--resume\\\",n.state.sessionId),e.appendSystemPrompt&&t.push(\\\"--append-system-prompt\\\",e.appendSystemPrompt),e.allowedTools?.length&&t.push(\\\"--allowedTools\\\",e.allowedTools.join(\\\",\\\")),e.disallowedTools?.length&&t.push(\\\"--disallowedTools\\\",e.disallowedTools.join(\\\",\\\")),e.maxTurns!==void 0&&t.push(\\\"--max-turns\\\",String(e.maxTurns)),{argv:t,stdin:n.prompt,env:{DISABLE_AUTOUPDATER:\\\"1\\\"}}},parser(n){let e=new D;return{line(t){let r=We(t);return r?{events:e.project(r,n.operationId),...r.session_id?{state:{sessionId:r.session_id}}:{},...r.type===\\\"result\\\"?{outcome:e.outcome(r,!1)}:{}}:{}},end({code:t,stderr:r}){return{status:\\\"unanswered\\\",reason:`claude exited with ${t??\\\"a signal\\\"}: ${r.trim()||\\\"no output\\\"}`}}}}};function Ge(n){let e=JSON.parse(n);if(!(typeof e!=\\\"object\\\"||e===null))return e}function Ye(n){return n===\\\"completed\\\"?\\\"done\\\":n===\\\"failed\\\"||n===\\\"declined\\\"?\\\"error\\\":\\\"running\\\"}function Xe(n){let e=n.id??\\\"item\\\",t=Ye(n.status);switch(n.type){case\\\"agent_message\\\":return{type:\\\"text\\\",text:n.text??\\\"\\\"};case\\\"reasoning\\\":return{type:\\\"reasoning\\\",text:n.text??\\\"\\\"};case\\\"command_execution\\\":return{type:\\\"tool\\\",toolCallId:e,toolName:\\\"shell\\\",input:{command:n.command??\\\"\\\"},state:t===\\\"done\\\"&&n.exit_code!==0&&n.exit_code!=null?\\\"error\\\":t,...n.aggregated_output?{output:n.aggregated_output}:{}};case\\\"file_change\\\":return{type:\\\"tool\\\",toolCallId:e,toolName:\\\"file_change\\\",input:n.changes??null,state:t};case\\\"mcp_tool_call\\\":return{type:\\\"tool\\\",toolCallId:e,toolName:`${n.server??\\\"mcp\\\"}.${n.tool??\\\"tool\\\"}`,input:n.arguments??null,state:t,...n.result!==void 0||n.error!==void 0?{output:n.result??n.error??null}:{}};case\\\"web_search\\\":return{type:\\\"tool\\\",toolCallId:e,toolName:\\\"web_search\\\",input:{query:n.query??\\\"\\\"},state:t};case\\\"todo_list\\\":return{type:\\\"tool\\\",toolCallId:e,toolName:\\\"todo_list\\\",input:n.items??null,state:t};default:return}}function Ze(n){if(!w(n))return{};let e=v(n.config);return e?{config:e}:{}}var ue={id:\\\"codex\\\",stateDirs:[\\\".codex/sessions\\\"],command(n){let e=[\\\"codex\\\",\\\"exec\\\"];n.state.threadId&&e.push(\\\"resume\\\",n.state.threadId),e.push(\\\"--json\\\",\\\"--skip-git-repo-check\\\",\\\"--dangerously-bypass-approvals-and-sandbox\\\");let t=process.env.OPENAI_BASE_URL;t&&e.push(\\\"-c\\\",\\\"model_provider=gateway\\\",\\\"-c\\\",`model_providers.gateway={name=\\\"AI Gateway\\\",base_url=${JSON.stringify(t)},env_key=\\\"OPENAI_API_KEY\\\",wire_api=\\\"responses\\\"}`);for(let r of Ze(n.settings.options).config??[])e.push(\\\"-c\\\",r);return n.settings.model&&e.push(\\\"-m\\\",n.settings.model),e.push(\\\"-\\\"),{argv:e,stdin:n.prompt}},parser(n){let e=`${n.operationId}:assistant`,t=Date.now(),r=new Map,o=\\\"\\\",s,i=()=>({type:\\\"message\\\",message:{id:e,role:\\\"assistant\\\",parts:[...r.values()],operationId:n.operationId,createdAt:t}});return{line(d){let a=Ge(d);if(!a)return{};switch(a.type){case\\\"thread.started\\\":return a.thread_id?{state:{threadId:a.thread_id}}:{};case\\\"item.started\\\":case\\\"item.updated\\\":case\\\"item.completed\\\":{let l=a.item;if(!l)return{};if(l.type===\\\"error\\\")return{events:[{type:\\\"log\\\",level:\\\"warn\\\",message:l.message??\\\"error\\\"}]};let c=Xe(l);return c?(r.set(l.id??String(r.size),c),c.type===\\\"text\\\"&&a.type===\\\"item.completed\\\"&&(o=c.text),{events:[i()]}):{}}case\\\"turn.completed\\\":return{events:[{type:\\\"usage\\\",...a.usage?.input_tokens===void 0?{}:{inputTokens:a.usage.input_tokens},...a.usage?.output_tokens===void 0?{}:{outputTokens:a.usage.output_tokens}}],outcome:{status:\\\"done\\\",text:o}};case\\\"turn.failed\\\":return{outcome:{status:\\\"unanswered\\\",reason:a.error?.message??\\\"turn failed\\\"}};case\\\"error\\\":return s=a.message,{events:[{type:\\\"log\\\",level:\\\"warn\\\",message:a.message??\\\"error\\\"}]};default:return{}}},end({code:d,stderr:a}){return{status:\\\"unanswered\\\",reason:`codex exited with ${d??\\\"a signal\\\"}: ${s??(a.trim()||\\\"no output\\\")}`}}}}};import{timingSafeEqual as st}from\\\"node:crypto\\\";import{createServer as it}from\\\"node:http\\\";import{createHash as Qe}from\\\"node:crypto\\\";var et=\\\"258EAFA5-E914-47DA-95CA-C5AB0DC85B11\\\",pe=64*1024*1024,tt=0,ce=1,nt=2,F=8,rt=9,ye=10;function ot(n,e){let t=e.length,r=t<126?Buffer.from([128|n,t]):t<65536?Buffer.from([128|n,126,t>>8,t&255]):Buffer.concat([Buffer.from([128|n,127]),(()=>{let o=Buffer.alloc(8);return o.writeBigUInt64BE(BigInt(t)),o})()]);return Buffer.concat([r,e])}function H(n,e,t,r){let o=n.headers[\\\"sec-websocket-key\\\"];if(typeof o!=\\\"string\\\"||n.headers.upgrade?.toLowerCase()!==\\\"websocket\\\"){e.destroy();return}let s=Qe(\\\"sha1\\\").update(o+et).digest(\\\"base64\\\");e.write(`HTTP/1.1 101 Switching Protocols\\\\r\\nUpgrade: websocket\\\\r\\nConnection: Upgrade\\\\r\\nSec-WebSocket-Accept: ${s}\\\\r\\n\\\\r\\n`);let i=!0,d=!1,a=()=>{d||(d=!0,i=!1,r.closed())},l=(p,y)=>{i&&e.write(ot(p,y))},c={send:p=>l(ce,Buffer.from(p,\\\"utf8\\\")),close:(p,y)=>{if(!i)return;let h=Buffer.alloc(2+Buffer.byteLength(y));h.writeUInt16BE(p),h.write(y,2),l(F,h),i=!1,e.end()}},u=t.length>0?Buffer.from(t):Buffer.alloc(0),b=[],m=0,f=()=>{for(;;){if(u.length<2)return;let p=u[0]??0,y=u[1]??0,h=(p&128)!==0,we=p&15,q=(y&128)!==0,I=y&127,C=2;if(I===126){if(u.length<4)return;I=u.readUInt16BE(2),C=4}else if(I===127){if(u.length<10)return;let g=u.readBigUInt64BE(2);if(g>BigInt(pe)){c.close(1009,\\\"message too big\\\");return}I=Number(g),C=10}let Ce=C;if(q&&(C+=4),u.length<C+I)return;let S=Buffer.from(u.subarray(C,C+I));if(q)for(let g=0;g<S.length;g++)S[g]=(S[g]??0)^(u[Ce+g%4]??0);switch(u=u.subarray(C+I),we){case ce:case nt:case tt:{if(b.push(S),m+=S.length,m>pe){c.close(1009,\\\"message too big\\\");return}if(h){let g=Buffer.concat(b).toString(\\\"utf8\\\");b=[],m=0,r.message(g)}break}case rt:l(ye,S);break;case ye:break;case F:i&&(l(F,S.subarray(0,2)),i=!1),e.end(),a();return;default:c.close(1002,\\\"unsupported opcode\\\");return}}};return e.on(\\\"data\\\",p=>{u=u.length===0?p:Buffer.concat([u,p]),f()}),e.on(\\\"close\\\",a),e.on(\\\"error\\\",a),u.length>0&&queueMicrotask(f),c}function at(n,e){if(e===void 0)return!1;let t=Buffer.from(n),r=Buffer.from(e);return t.length===r.length&&st(t,r)}async function dt(n){let e=new T({adapter:n.adapter,runtimeId:n.runtimeId}),t=new Set,r=it((i,d)=>{if(i.url===$){d.writeHead(200,{\\\"content-type\\\":\\\"text/plain\\\"}),d.end(\\\"ok\\\");return}d.writeHead(404),d.end()});r.on(\\\"upgrade\\\",(i,d,a)=>{let l=new URL(i.url??\\\"/\\\",\\\"http://container\\\");if(!l.pathname.startsWith(M)){d.destroy();return}let c=decodeURIComponent(l.pathname.slice(M.length)),u=i.headers[z];if(!at(n.token,Array.isArray(u)?u[0]:u)||c.length===0){H(i,d,a,{message:()=>{},closed:()=>{}})?.close(W,\\\"unauthorized\\\");return}let m,f=H(i,d,a,{message:p=>m?.receive(p),closed:()=>{f&&t.delete(f),m?.closed()}});f&&(t.add(f),m=e.connect(c,f))}),await new Promise(i=>{r.listen(n.port,n.host??\\\"0.0.0.0\\\",i)});let o=r.address();return{port:typeof o==\\\"object\\\"&&o?o.port:0,async close(){for(let i of t)i.close(1001,\\\"shutting down\\\");await new Promise(i=>r.close(()=>i())),await e.close()}}}async function fe(n,e=process.env){let t=e[x.token],r=e[x.runtimeId],o=Number(e[x.port]??\\\"8080\\\");if(!t||!r||!Number.isInteger(o)||o<=0)throw new Error(`${x.token}, ${x.runtimeId} and ${x.port} must be set; ContainerHarness sets them`);delete e[x.token];let s=await dt({adapter:n,runtimeId:r,token:t,port:o});console.log(`harness-daemon: ${n.id} on ${s.port} (${r})`);let i=()=>{s.close().finally(()=>process.exit(0))};return process.once(\\\"SIGTERM\\\",i),process.once(\\\"SIGINT\\\",i),s}var lt={\\\"claude-code\\\":le,codex:ue};function ut(n){let e=n?/^(\\\\d+):(\\\\d+)$/.exec(n):null;return e?{uid:Number(e[1]),gid:Number(e[2])}:void 0}var j=process.env.CF_HARNESS_ADAPTER??\\\"claude-code\\\",ge=ut(process.env.CF_HARNESS_USER),me=lt[j],he=j===\\\"echo\\\"?Q:me?ae({...me,...ge?{user:ge,homes:\\\"/home/agent/.harness/sessions\\\",skeleton:\\\"/home/agent\\\"}:{}}):void 0;he||(console.error(`harness-daemon: unknown CF_HARNESS_ADAPTER ${j}`),process.exit(1));await fe(he).catch(n=>{console.error(`harness-daemon: ${String(n)}`),process.exit(1)});\\n\";\n\n/** A hash of `DAEMON_SOURCE`, to tell daemon builds apart. */\nexport const DAEMON_VERSION = \"d45c6a8182ef9070\";\n","/**\n * Containers built at runtime from `cloudflare/debian-trixie`, with no\n * image of your own.\n *\n * The first start of a setup runs its steps with `exec()` (create the\n * unprivileged user, install the CLI), writes the bundled daemon, and\n * snapshots the filesystem. Later starts restore the snapshot and are\n * ready as soon as the daemon boots. A snapshot is keyed by the image, the\n * steps, and the daemon build, so changing any of them sets up afresh.\n *\n * The container's entrypoint waits for the daemon to be written and then\n * runs it, so the same entrypoint serves a fresh container (where setup\n * writes the daemon) and a restored one (where it is already there).\n */\n\nimport { DAEMON_SOURCE, DAEMON_VERSION } from \"./daemon-source.generated\";\n\n/** The managed system image: Debian Trixie with Node.js. */\nexport const MANAGED_IMAGE = \"cloudflare/debian-trixie\";\n\n/** The unprivileged user CLIs run as, `uid:gid`. */\nexport const AGENT_USER = \"10001:10001\";\n\nconst DAEMON_DIR = \"/opt/harness\";\n\n/** Waits for setup to write the daemon, then becomes it. */\nexport const MANAGED_ENTRYPOINT: readonly string[] = [\n \"sh\",\n \"-c\",\n `while [ ! -f ${DAEMON_DIR}/ready ]; do sleep 0.1; done; exec node ${DAEMON_DIR}/daemon.mjs`\n];\n\n/**\n * One setup command, run once in the fresh container and kept in its\n * snapshot.\n *\n * Steps run as root by default. A step with `user: \"agent\"` runs as the\n * user the CLI runs as, with `HOME=/home/agent`: anything it puts in that\n * home (installed plugins and mods, `~/.claude/settings.json`, skills,\n * `~/.codex/config.toml`) is in every session's home, because each session\n * home starts as a copy of it.\n */\nexport type SetupStep = {\n /** What the step does, for error messages. */\n readonly name: string;\n readonly command: readonly string[];\n /** Who runs it. Default `root`. */\n readonly user?: \"root\" | \"agent\";\n};\n\n/** The agent user's home, which every session home starts as a copy of. */\nexport const AGENT_HOME = \"/home/agent\";\n\n/** Steps every managed agent needs before its own. */\nexport const BASE_STEPS: readonly SetupStep[] = [\n {\n name: \"create the agent user and workspace\",\n command: [\n \"sh\",\n \"-c\",\n \"id -u agent >/dev/null 2>&1 || useradd --create-home --uid 10001 --shell /bin/sh agent; \" +\n `mkdir -p /workspace ${DAEMON_DIR} && chown 10001:10001 /workspace`\n ]\n },\n {\n name: \"install git\",\n command: [\n \"sh\",\n \"-c\",\n \"command -v git >/dev/null || (apt-get update -qq && apt-get install -y -qq --no-install-recommends git ca-certificates)\"\n ]\n }\n];\n\n/** A stored snapshot and the setup it captured. */\nexport type SetupSnapshot = {\n readonly key: string;\n readonly snapshot: { readonly id: string };\n};\n\n/** Why setup failed. */\nexport type SetupError = { readonly _tag: \"setup\"; readonly message: string };\n\n/** How long one setup step may run. */\nconst STEP_TIMEOUT_MS = 10 * 60_000;\n/** How much of a failed step's output is reported. */\nconst OUTPUT_KEPT = 2_000;\n\n/**\n * The key a snapshot of this setup is stored under.\n *\n * @param steps - The setup steps.\n * @returns A stable key for the image, the steps, and the daemon build.\n */\nexport async function setupKey(steps: readonly SetupStep[]): Promise<string> {\n const text = JSON.stringify({\n image: MANAGED_IMAGE,\n steps: steps.map((step) => [step.user ?? \"root\", ...step.command]),\n daemon: DAEMON_VERSION\n });\n const digest = await crypto.subtle.digest(\n \"SHA-256\",\n new TextEncoder().encode(text)\n );\n return [...new Uint8Array(digest)]\n .slice(0, 16)\n .map((byte) => byte.toString(16).padStart(2, \"0\"))\n .join(\"\");\n}\n\nasync function run(\n container: Container,\n step: SetupStep,\n stdin?: string\n): Promise<SetupError | undefined> {\n const asAgent = step.user === \"agent\";\n const process = await container.exec([...step.command], {\n env: {\n HOME: asAgent ? AGENT_HOME : \"/root\",\n DEBIAN_FRONTEND: \"noninteractive\"\n },\n ...(asAgent ? { user: AGENT_USER, cwd: AGENT_HOME } : {}),\n stderr: \"combined\",\n ...(stdin === undefined ? {} : { stdin: new Blob([stdin]).stream() })\n });\n // Kill a step that hangs, but never one that exited: signalling an\n // exited process is an error in the object.\n let exited = false;\n void process.exitCode.then(\n () => (exited = true),\n () => (exited = true)\n );\n const timer = setTimeout(() => {\n if (!exited) process.kill(9);\n }, STEP_TIMEOUT_MS);\n try {\n const output = await process.output();\n if (output.exitCode === 0) return undefined;\n const text = new TextDecoder().decode(output.stdout).slice(-OUTPUT_KEPT);\n return {\n _tag: \"setup\",\n message: `${step.name} exited with ${output.exitCode}: ${text.trim()}`\n };\n } finally {\n clearTimeout(timer);\n }\n}\n\n/**\n * Set a fresh managed container up: run the steps, install the daemon, and\n * snapshot the result. A failed snapshot is not an error: the container\n * still works, and the next start sets up again.\n *\n * @param container - The running container, started from `MANAGED_IMAGE`\n * with `MANAGED_ENTRYPOINT`.\n * @param steps - The agent's setup, after `BASE_STEPS`.\n * @param key - The setup's key, from `setupKey`.\n * @returns The snapshot to store, `undefined` when none was taken, or why\n * setup failed.\n */\nexport async function setUp(\n container: Container,\n steps: readonly SetupStep[],\n key: string\n): Promise<\n | { readonly _tag: \"ok\"; readonly snapshot: SetupSnapshot | undefined }\n | { readonly _tag: \"err\"; readonly error: SetupError }\n> {\n for (const step of [...BASE_STEPS, ...steps]) {\n const failed = await run(container, step).catch(\n (error: unknown): SetupError => ({\n _tag: \"setup\",\n message: `${step.name} failed: ${error instanceof Error ? error.message : String(error)}`\n })\n );\n if (failed) return { _tag: \"err\", error: failed };\n }\n const installed = await run(\n container,\n {\n name: \"install the daemon\",\n command: [\n \"sh\",\n \"-c\",\n `cat > ${DAEMON_DIR}/daemon.mjs && touch ${DAEMON_DIR}/ready`\n ]\n },\n DAEMON_SOURCE\n );\n if (installed) return { _tag: \"err\", error: installed };\n try {\n const snapshot = await container.snapshotContainer({\n name: `harness-${key}`\n });\n return { _tag: \"ok\", snapshot: { key, snapshot: { id: snapshot.id } } };\n } catch {\n return { _tag: \"ok\", snapshot: undefined };\n }\n}\n","import {\n LifecycleCapability,\n type CapabilityStartContext,\n type LifecycleJobContext,\n type LifecycleJobOutcome\n} from \"../../lifecycle\";\nimport {\n openHarnessStore,\n type HarnessStore,\n type JsonValue,\n type OperationRecord\n} from \"../store/store\";\nimport type { ContainerAgent } from \"./agents\";\nimport type { ContainerEgressBinding } from \"./egress\";\nimport { DaemonLink, waitHealthy, type Hello, type LinkError } from \"./link\";\nimport {\n AGENT_USER,\n MANAGED_ENTRYPOINT,\n MANAGED_IMAGE,\n setUp,\n setupKey\n} from \"./managed-image\";\nimport {\n chunkEntries,\n CONTAINER_ENV,\n type ContainerInput,\n type ContainerMessage,\n type ContainerOutcome,\n type ContainerPart,\n type ContainerSettings,\n type ContainerWhenBusy,\n type DaemonFrame\n} from \"./protocol\";\nimport type {\n ContainerEventStream,\n ContainerOperationResult,\n ContainerPendingOperation,\n ContainerPromptResponse,\n ContainerReceipt,\n ContainerSessionEvent,\n ContainerSessionId,\n ContainerSessionInfo,\n ContainerSessionOptions,\n ContainerSessionSnapshot,\n ContainerSubmitOptions\n} from \"./types\";\n\n/** The root session's id. */\nexport const ROOT_SESSION: ContainerSessionId = \"root\";\n\n/** Default `idleTimeoutMs`: the container stops five minutes after its last work. */\nconst IDLE_TIMEOUT_MS = 5 * 60_000;\n\n/** Default `startTimeoutMs`: how long a new container may take to answer. */\nconst START_TIMEOUT_MS = 60_000;\n\n/** How long a container that already runs may take to answer before it is replaced. */\nconst ADOPT_TIMEOUT_MS = 10_000;\n\n/** Default `port`: where the daemon listens in the container. */\nconst DAEMON_PORT = 8080;\n\n/**\n * Longest one wake waits on the container. It waits inside an alarm\n * invocation, which has a 15 minute wall-time limit, so a longer run is\n * waited on across several alarms.\n */\nconst WAIT_BUDGET_MS = 10 * 60_000;\n\n/**\n * The wake job's heartbeat while it waits. If the object is evicted, the\n * job is still due and its alarm restarts the object, which reattaches.\n */\nconst HEARTBEAT_MS = 30_000;\n\n/** Consecutive failed starts before a session's open work is given up. */\nconst MAX_START_FAILURES = 5;\n\n/** How often a wait checks that the container still runs. */\nconst CONTAINER_CHECK_MS = 2_000;\n\n/** How often `wait()` re-reads the store while it waits. */\nconst SETTLE_POLL_MS = 1_000;\n\n/** Frames between acknowledgements, so the daemon can forget them. */\nconst ACK_EVERY = 32;\n\nconst WAKE_FN = \"wake\";\nconst IDLE_FN = \"idle\";\nconst IDLE_JOB = \"container-idle\";\nconst RUNTIME_KEY = \"container-harness:runtime\";\nconst SNAPSHOT_KEY = \"container-harness:snapshot\";\nconst WORKSPACE_KEY = \"container-harness:workspace\";\n\n/**\n * How much longer than `idleTimeoutMs` the platform keeps an inactive\n * object's container. The harness's own idle stop runs first, so it can\n * snapshot the workspace before the container goes.\n */\nconst IDLE_GRACE_MS = 2 * 60_000;\n\n/** The longest inactivity timeout the platform accepts. */\nconst MAX_INACTIVITY_MS = 6 * 60 * 60_000;\n\n/**\n * A stored snapshot to start containers from: the workspace one (the\n * whole filesystem as the harness last stopped it) or the setup one.\n */\ntype SnapshotRecord = {\n /** The setup key (managed) or image (custom) the snapshot was taken on. */\n readonly key: string;\n readonly snapshot: { readonly id: string };\n /** When it was taken or last restored: its 30-day lifetime runs from here. */\n readonly usedAt?: number;\n /** Consecutive starts from it that failed, and since when. */\n readonly failures?: { readonly count: number; readonly since: number };\n /**\n * Skipped after failing, while a fallback then started: try it once more\n * now the platform has shown it can start containers. Failing again\n * means the snapshot itself is broken.\n */\n readonly probe?: true;\n};\n\n/**\n * Snapshots live 30 days from their last restore. One unused for nearly\n * that long is treated as gone rather than tried.\n */\nconst SNAPSHOT_STALE_MS = 29 * 24 * 60 * 60_000;\n\n/**\n * The platform does not say why a start failed. A snapshot that fails this\n * many starts in a row is skipped (not deleted) in favour of the next\n * source: whether that one works decides whether the snapshot was at fault.\n */\nconst SKIP_AFTER_FAILURES = 2;\n\n/** Snapshot sources, most preferred first. */\nconst SNAPSHOT_SOURCES = [\n { from: \"workspace\", storageKey: WORKSPACE_KEY },\n { from: \"snapshot\", storageKey: SNAPSHOT_KEY }\n] as const;\n\nconst MESSAGES = \"messages\";\nconst ENGINE = \"engine\";\nconst OPEN: readonly (\"queued\" | \"running\")[] = [\"queued\", \"running\"];\n\n/** How long the wake waits, for tests. */\ntype WakeTiming = {\n readonly waitBudgetMs?: number;\n readonly heartbeatMs?: number;\n /** First retry delay after a failed start; doubles per failure. */\n readonly retryBaseMs?: number;\n /** Delay of the idle stop. Default: `idleTimeoutMs`. */\n readonly idleStopMs?: number;\n};\n\nlet setWakeTiming: (harness: ContainerHarness, timing: WakeTiming) => void;\n\n/**\n * @internal Shorten a harness's wake timings, so a test suite does not sit\n * on the real heartbeat. Not exported from `agents/harness/container`.\n */\nexport function setWakeTimingForTests(\n harness: ContainerHarness,\n timing: WakeTiming\n): void {\n setWakeTiming(harness, timing);\n}\n\nfunction wakeJobId(session: ContainerSessionId): string {\n return `container-wake:${session}`;\n}\n\n/**\n * A wake job's payload: its session, and the consecutive failed starts so\n * far. The count lives in the job, not in memory, so an object evicted\n * between attempts still gives up after `MAX_START_FAILURES`.\n */\ntype WakePayload = {\n readonly session: ContainerSessionId;\n readonly failures: number;\n};\n\nfunction parseWakePayload(payload: unknown): WakePayload | undefined {\n if (\n typeof payload !== \"object\" ||\n payload === null ||\n !(\"session\" in payload) ||\n typeof payload.session !== \"string\"\n ) {\n return undefined;\n }\n const failures =\n \"failures\" in payload && typeof payload.failures === \"number\"\n ? payload.failures\n : 0;\n return { session: payload.session, failures };\n}\n\n/** A container instance size: a named type or a custom shape. */\nexport type ContainerInstance =\n | \"lite\"\n | \"standard-1\"\n | \"standard-2\"\n | \"standard-3\"\n | \"standard-4\"\n | {\n readonly vcpu: number;\n readonly memoryMib: number;\n readonly diskMb: number;\n };\n\n/** Applied to a session the first time it is created. */\nexport type ContainerSessionDefaults = {\n /** The adapter's model name. Change one session's with `session.setModel`. */\n readonly model?: string;\n /** Adapter options, passed through to the adapter untouched. */\n readonly options?: JsonValue;\n};\n\n/** `ContainerHarness`'s options. */\nexport type ContainerHarnessOptions = {\n /** The object's container: `ctx.container`. */\n readonly container: Container;\n /** What runs in it: `claudeCode()`, `codex()`, or `containerAgent()`. */\n readonly agent: ContainerAgent;\n /**\n * `ctx.exports.ContainerEgress`, which adds the agent's credentials to\n * its requests outside the container. Required when the agent has egress\n * routes (every preset does). Export `ContainerEgress` from\n * your Worker's main module.\n */\n readonly egress?: ContainerEgressBinding;\n /** Instance size. Default `standard-1`. */\n readonly instance?: ContainerInstance;\n /**\n * Whether the container may reach the Internet beyond its egress routes.\n * Default true: managed images need it to install their CLI in setup.\n * Commands the agent runs can then reach any host (credentials still\n * stay outside: only the egress routes carry them). Set false, with a\n * `containerAgent()` image that has its CLI installed, to allow nothing\n * but the egress routes.\n */\n readonly enableInternet?: boolean;\n /** Where the daemon listens. Default 8080. */\n readonly port?: number;\n /**\n * How long the container keeps running after its last work, in\n * milliseconds. The harness then snapshots its filesystem (workspace\n * included) and stops it; the next prompt starts a new one from that\n * snapshot and resumes the session in it. Default five minutes; at most\n * six hours less two minutes (the platform's own stop comes two minutes\n * later, and the harness must snapshot first).\n */\n readonly idleTimeoutMs?: number;\n /** How long a new container may take to answer. Default 60 seconds. */\n readonly startTimeoutMs?: number;\n /** What a new session starts with. Default: the agent's model and options. */\n readonly defaults?: ContainerSessionDefaults;\n /**\n * What happens to an operation whose container stopped while it ran.\n *\n * - `fail` (default): it settles `unanswered` with `container_lost`. The\n * session itself survives: the next prompt resumes it in a new\n * container, from everything the adapter persisted.\n * - `retry`: it runs again from the start in the new container. Only safe\n * when the agent's tools can be repeated.\n */\n readonly onContainerLost?: \"fail\" | \"retry\";\n /** Table prefix for the session store. Default `container_`. */\n readonly storePrefix?: string;\n};\n\n/** What the harness keeps per session, in the store's session state. */\ntype SessionState = {\n readonly model: string | undefined;\n /** The newest frame stored, by container. */\n readonly cursor: { readonly runtimeId: string; readonly seq: number } | null;\n /** Bumped on reset: a new adapter session, without the old history. */\n readonly generation: number;\n /** Messages before this log position belong to an earlier context. */\n readonly messagesFrom: number;\n /** A note prepended to the first prompt after a reset. */\n readonly handoff: string | undefined;\n};\n\n/** What the harness keeps per operation, in the store's operation meta. */\ntype OperationMeta = {\n readonly whenBusy: ContainerWhenBusy;\n /** The container the operation was handed to, if any. */\n readonly delivered: string | null;\n};\n\ntype Runtime = { readonly runtimeId: string; readonly token: string };\n\ntype Attached = {\n readonly link: DaemonLink;\n readonly runtimeId: string;\n sinceAck: number;\n /** Settled in the container per `hello`; applied once the replay is done. */\n readonly settledThere: {\n readonly operationId: string;\n readonly outcome: ContainerOutcome;\n }[];\n};\n\nfunction isRecord(\n value: JsonValue | undefined\n): value is { readonly [key: string]: JsonValue } {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction parseSessionState(value: JsonValue): SessionState {\n const fields = isRecord(value) ? value : {};\n const cursor = fields.cursor;\n return {\n model: typeof fields.model === \"string\" ? fields.model : undefined,\n cursor:\n isRecord(cursor) &&\n typeof cursor.runtimeId === \"string\" &&\n typeof cursor.seq === \"number\"\n ? { runtimeId: cursor.runtimeId, seq: cursor.seq }\n : null,\n generation: typeof fields.generation === \"number\" ? fields.generation : 1,\n messagesFrom:\n typeof fields.messagesFrom === \"number\" ? fields.messagesFrom : 0,\n handoff: typeof fields.handoff === \"string\" ? fields.handoff : undefined\n };\n}\n\nfunction sessionStateJson(state: SessionState): JsonValue {\n return {\n ...(state.model === undefined ? {} : { model: state.model }),\n cursor: state.cursor,\n generation: state.generation,\n messagesFrom: state.messagesFrom,\n ...(state.handoff === undefined ? {} : { handoff: state.handoff })\n };\n}\n\nfunction parseMeta(value: JsonValue): OperationMeta {\n const fields = isRecord(value) ? value : {};\n return {\n whenBusy: fields.whenBusy === \"steer\" ? \"steer\" : \"followUp\",\n delivered: typeof fields.delivered === \"string\" ? fields.delivered : null\n };\n}\n\nfunction metaJson(meta: OperationMeta): JsonValue {\n return { whenBusy: meta.whenBusy, delivered: meta.delivered };\n}\n\nfunction parseInput(value: JsonValue): ContainerInput {\n if (typeof value === \"string\") return value;\n // SAFETY: inputs are stored only by `enqueue`, from a `ContainerInput`.\n return value as unknown as ContainerInput;\n}\n\nfunction inputJson(input: ContainerInput): JsonValue {\n // SAFETY: a `ContainerInput` is plain JSON (strings and part objects).\n return input as unknown as JsonValue;\n}\n\nfunction parseMessage(value: JsonValue): ContainerMessage {\n // SAFETY: the messages log is written only by `#onFrame`, from parsed\n // `ContainerMessage`s.\n return value as unknown as ContainerMessage;\n}\n\nfunction messageJson(message: ContainerMessage): JsonValue {\n // SAFETY: a `ContainerMessage` is plain JSON.\n return message as unknown as JsonValue;\n}\n\nfunction userParts(input: ContainerInput): ContainerPart[] {\n if (typeof input === \"string\") return [{ type: \"text\", text: input }];\n return input.map((part) =>\n part.type === \"text\"\n ? { type: \"text\", text: part.text }\n : { type: \"image\", mediaType: part.mediaType, data: part.data }\n );\n}\n\nfunction withHandoff(input: ContainerInput, handoff: string): ContainerInput {\n const note = { type: \"text\", text: handoff } as const;\n if (typeof input === \"string\") return [note, { type: \"text\", text: input }];\n return [note, ...input];\n}\n\nfunction errorText(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\n/**\n * An agent CLI running in a Cloudflare Container, driven from a Durable\n * Object, behind the same interface as `PiHarness`: `harness.prompt()`,\n * `harness.sessions`, `harness.session(id)`.\n *\n * The harness does not know which agent runs in the container. A preset\n * (`claudeCode()`, `codex()`) says what to install and which adapter the\n * daemon runs; the harness builds the container from\n * `cloudflare/debian-trixie` on first use, installs the bundled daemon, and\n * snapshots the result, so there is no image to build. Credentials stay\n * outside: the CLI calls a placeholder host, and `ContainerEgress` adds the\n * real key. Any adapter that produces `ContainerEvent`s works, including\n * one in an image of your own (`containerAgent()`).\n *\n * The object owns the durable record, in a `HarnessStore`: sessions,\n * operations, the transcript, and the adapter's resume state. The container\n * is disposable. It is started on demand with `ctx.container.start()`, kept\n * for `idleTimeoutMs` after its last work, and then stopped. The next\n * prompt starts a new container and hands the adapter everything it\n * persisted, so the agent resumes its own session there.\n *\n * Each session has one Lifecycle wake job. It runs while the session has\n * open operations: it starts or reattaches to the container, reconciles\n * what the container knows with what the object stored, delivers queued\n * operations, and waits for them, rescheduling itself as a heartbeat. An\n * eviction mid-run leaves the job due, so its alarm restarts the object,\n * which reattaches and replays the frames it missed from its cursor.\n *\n * Recovery, by what was lost:\n *\n * - **The object** (eviction, deploy): the container keeps running for\n * `idleTimeoutMs`. The wake reattaches and replays from the cursor.\n * - **The socket**: the same, on the next heartbeat.\n * - **The container** (idle stop, crash, platform restart): a new one\n * answers with a different runtime id. The session is reopened in it\n * from the persisted resume state; queued operations run there; an\n * operation that was running is settled `container_lost` or run again,\n * per `onContainerLost`.\n *\n * @experimental The API may change before it stabilizes.\n */\nexport class ContainerHarness extends LifecycleCapability {\n /** Every session in this object. */\n readonly sessions: ContainerSessions;\n readonly #options: ContainerHarnessOptions;\n readonly #idleTimeoutMs: number;\n readonly #startTimeoutMs: number;\n #waitBudgetMs = WAIT_BUDGET_MS;\n #heartbeatMs = HEARTBEAT_MS;\n #retryBaseMs = 1_000;\n #idleStopMs: number;\n #store: HarnessStore | undefined;\n #runtime: Runtime | undefined;\n #starting: Promise<RuntimeResult> | undefined;\n #timeoutSet = false;\n readonly #attached = new Map<ContainerSessionId, Attached>();\n readonly #attaching = new Map<ContainerSessionId, Promise<AttachResult>>();\n /** In-memory waits on the container, per session, inside an alarm's work. */\n readonly #waits = new Map<ContainerSessionId, Promise<void>>();\n /** Wakes `wait()` callers when an operation settles. */\n readonly #settleWaiters = new Map<string, Set<() => void>>();\n /** Wakes the wake job when a session's work or link changes. */\n readonly #changeWaiters = new Map<ContainerSessionId, Set<() => void>>();\n readonly #listeners = new Map<\n ContainerSessionId,\n Set<(events: readonly ContainerSessionEvent[]) => void>\n >();\n\n static {\n setWakeTiming = (harness, timing) => harness.#setWakeTiming(timing);\n }\n\n /**\n * @param options - The container, the agent, and session defaults.\n */\n constructor(options: ContainerHarnessOptions) {\n super(\"container-harness\");\n const idle = options.idleTimeoutMs ?? IDLE_TIMEOUT_MS;\n // The platform stops an inactive container at most six hours after\n // its object goes quiet; the harness must stop (and snapshot) it first.\n if (\n !Number.isFinite(idle) ||\n idle <= 0 ||\n idle > MAX_INACTIVITY_MS - IDLE_GRACE_MS\n ) {\n throw new Error(\n \"ContainerHarness idleTimeoutMs must be positive and at most six hours less two minutes\"\n );\n }\n for (const route of options.agent.egress) {\n // Credentials ride these requests: never send them in the clear.\n if (\n !URL.canParse(route.upstream) ||\n new URL(route.upstream).protocol !== \"https:\"\n ) {\n throw new Error(\n `ContainerHarness: egress upstream for ${route.host} must be an https URL, got ${JSON.stringify(route.upstream)}`\n );\n }\n }\n if (options.agent.egress.length > 0 && options.egress === undefined) {\n throw new Error(\n \"ContainerHarness: the agent's credentials need `egress: ctx.exports.ContainerEgress`, \" +\n 'and `export { ContainerEgress } from \"agents/harness/container\"` in your main module'\n );\n }\n this.#options = options;\n this.#idleTimeoutMs = idle;\n this.#startTimeoutMs = options.startTimeoutMs ?? START_TIMEOUT_MS;\n this.#idleStopMs = idle;\n this.sessions = new ContainerSessions(this);\n }\n\n #setWakeTiming(timing: WakeTiming): void {\n for (const [name, value] of Object.entries(timing)) {\n if (!Number.isFinite(value) || value <= 0) {\n throw new Error(\n `ContainerHarness timing.${name} must be a positive number`\n );\n }\n }\n this.#waitBudgetMs = timing.waitBudgetMs ?? this.#waitBudgetMs;\n this.#heartbeatMs = timing.heartbeatMs ?? this.#heartbeatMs;\n this.#retryBaseMs = timing.retryBaseMs ?? this.#retryBaseMs;\n this.#idleStopMs = timing.idleStopMs ?? this.#idleStopMs;\n }\n\n // ── Lifecycle ────────────────────────────────────────────────────────────\n\n /** Reopen the store, re-arm the container's idle timeout, and wake open sessions. */\n override async onStart(_context: CapabilityStartContext): Promise<void> {\n const store = await this.#openStore();\n const container = this.#options.container;\n if (container.running) {\n // A restarted object starts without the container's inactivity\n // timeout; without it, the container stops shortly after the object\n // goes quiet.\n await container.setInactivityTimeout(this.#inactivityTimeoutMs());\n this.#timeoutSet = true;\n }\n const open = store.operations({ status: OPEN });\n const sessions = new Set(open.map((operation) => operation.session));\n for (const session of sessions) {\n // A wake job that is already queued carries its failure count: keep\n // it. Only a session that lost its job gets a new one.\n if (!this.lifecycle.jobs.get(wakeJobId(session))) {\n await this.#wake(session);\n }\n }\n if (sessions.size === 0 && container.running) await this.#scheduleIdle();\n }\n\n /** Dispatch the harness's jobs: one wake per session, and the idle stop. */\n async onJob(\n context: LifecycleJobContext\n ): Promise<LifecycleJobOutcome | void> {\n if (context.job.fn === IDLE_FN) return this.#idleStep();\n if (context.job.fn !== WAKE_FN) return;\n const wake = parseWakePayload(context.job.payload);\n if (wake !== undefined) return this.#wakeStep(wake);\n }\n\n /** Close the session sockets. Durable state and the container are untouched. */\n async dispose(): Promise<void> {\n for (const session of [...this.#attached.keys()]) this.#detach(session);\n }\n\n // ── The harness interface ────────────────────────────────────────────────\n\n /**\n * A handle on one session. No I/O until you call it.\n *\n * @param id - The session. Default: the root session.\n * @returns The handle.\n */\n session(id: ContainerSessionId = ROOT_SESSION): ContainerSession {\n return new ContainerSession(this, id);\n }\n\n /**\n * Submit a prompt and wait for its answer.\n *\n * @param input - The prompt.\n * @param options - Session, idempotency key, and busy behaviour.\n * @returns The result, with the session's transcript after it.\n */\n prompt(\n input: ContainerInput,\n options: ContainerSubmitOptions = {}\n ): Promise<ContainerPromptResponse> {\n return this.session(options.session).prompt(input, options);\n }\n\n /**\n * Durably submit a prompt. Resolves before the agent runs.\n *\n * @param input - The prompt.\n * @param options - Session, idempotency key, and busy behaviour.\n * @returns The receipt.\n */\n submit(\n input: ContainerInput,\n options: ContainerSubmitOptions = {}\n ): Promise<ContainerReceipt> {\n return this.session(options.session).submit(input, options);\n }\n\n /**\n * Stop one operation, or everything running in a session.\n *\n * @param options - The session, and optionally one operation.\n * @returns Whether anything was stopped.\n */\n abort(\n options: ContainerSessionOptions & { readonly operationId?: string } = {}\n ): Promise<boolean> {\n return this.session(options.session).abort(options.operationId);\n }\n\n /**\n * Wait for an operation to settle.\n *\n * @param operationId - The operation.\n * @param options - The session, and a signal that stops only the wait.\n * @returns How it ended.\n */\n wait(\n operationId: string,\n options: ContainerSessionOptions & { readonly signal?: AbortSignal } = {}\n ): Promise<ContainerOperationResult> {\n return this.session(options.session).wait(operationId, options.signal);\n }\n\n /**\n * The session's active transcript.\n *\n * @param options - The session.\n * @returns Its messages since the newest reset.\n */\n messages(options: ContainerSessionOptions = {}): Promise<ContainerMessage[]> {\n return this.session(options.session).messages();\n }\n\n /**\n * Submissions that have not settled yet, oldest first.\n *\n * @param options - Narrow to one session. Default: every session.\n * @returns The open operations.\n */\n async pending(\n options: ContainerSessionOptions = {}\n ): Promise<ContainerPendingOperation[]> {\n const store = await this.#openStore();\n return store\n .operations({\n ...(options.session === undefined ? {} : { session: options.session }),\n status: OPEN\n })\n .map((operation) => ({\n operationId: operation.id,\n session: operation.session,\n status: operation.status === \"running\" ? \"running\" : \"queued\"\n }));\n }\n\n /**\n * The container, as the harness sees it.\n *\n * @returns Whether it runs, and the id the harness started it with.\n */\n async container(): Promise<{\n readonly running: boolean;\n readonly runtimeId: string | undefined;\n }> {\n const runtime = await this.#runtimeRecord();\n return {\n running: this.#options.container.running,\n runtimeId: runtime?.runtimeId\n };\n }\n\n /**\n * Stop the container now. Sessions survive: the next prompt starts a new\n * container and resumes them in it. Running operations are reconciled as\n * if the container had died.\n */\n async stop(): Promise<void> {\n await this.dispose();\n const container = this.#options.container;\n if (container.running) {\n await this.#saveWorkspace(container);\n await container.destroy();\n }\n this.#broadcast({ type: \"container\", status: \"stopped\" });\n const store = await this.#openStore();\n const sessions = new Set(\n store.operations({ status: OPEN }).map((operation) => operation.session)\n );\n for (const session of sessions) await this.#wake(session);\n }\n\n // ── Used by ContainerSession and ContainerSessions ───────────────────────\n\n /** @internal */\n async store(): Promise<HarnessStore> {\n return this.#openStore();\n }\n\n /** @internal Create a session with the defaults, or fork one. */\n async createSession(\n id: ContainerSessionId,\n from?: ContainerSessionId\n ): Promise<void> {\n const store = await this.#openStore();\n store.transaction(() => {\n if (from === undefined) {\n store.createSession({ id, state: sessionStateJson(this.#initial()) });\n return;\n }\n const parent = store.session(from);\n if (!parent) throw new Error(`Unknown container session ${from}`);\n const parentState = parseSessionState(parent.state);\n store.createSession({\n id,\n parent: from,\n state: sessionStateJson({\n ...this.#initial(),\n model: parentState.model\n })\n });\n // The fork sees the parent's active transcript, and its adapter is\n // restored from a copy of the parent's state, so it resumes the\n // parent's agent session on a branch of its own.\n store.append(\n id,\n MESSAGES,\n store\n .read(from, MESSAGES, { after: parentState.messagesFrom })\n .map((entry) =>\n entry.id === undefined\n ? { data: entry.data }\n : { id: entry.id, data: entry.data }\n )\n );\n store.copy(from, id, ENGINE);\n });\n }\n\n /** @internal */\n async enqueue(\n session: ContainerSessionId,\n input: ContainerInput,\n options: ContainerSubmitOptions\n ): Promise<ContainerReceipt> {\n const store = await this.#openStore();\n this.#requireSession(store, session);\n const operationId = options.operationId ?? crypto.randomUUID();\n const meta: OperationMeta = {\n whenBusy: options.whenBusy ?? \"followUp\",\n delivered: null\n };\n const { accepted } = store.enqueue({\n session,\n id: operationId,\n input: inputJson(input),\n meta: metaJson(meta)\n });\n // Hand it over now if a socket is open; the wake does it otherwise.\n if (accepted) this.#deliver(store, session);\n // A new submission starts the failure count over.\n await this.#wake(session);\n return { operationId, session, accepted };\n }\n\n /** @internal Withdraw or abort one operation, or all of a session's. */\n async withdraw(\n session: ContainerSessionId,\n operationId: string | undefined\n ): Promise<boolean> {\n const store = await this.#openStore();\n const targets =\n operationId === undefined\n ? store.operations({ session, status: OPEN })\n : [store.operation(session, operationId)].filter(\n (operation): operation is OperationRecord =>\n operation !== undefined &&\n (operation.status === \"queued\" || operation.status === \"running\")\n );\n if (targets.length === 0) return operationId === undefined;\n // The container stops it too; if the socket is closed, the next\n // reconcile aborts whatever the container still runs for it. A\n // session-wide abort is one message, so the container cannot start a\n // queued operation between two per-operation aborts.\n const attached = this.#attached.get(session);\n if (operationId === undefined) {\n attached?.link.send({ type: \"abort\" });\n } else if (\n targets.some((each) => parseMeta(each.meta).delivered !== null)\n ) {\n attached?.link.send({ type: \"abort\", operationId });\n }\n for (const operation of targets) {\n this.#settle(store, session, operation.id, {\n status: \"unanswered\",\n reason: \"aborted\"\n });\n }\n return true;\n }\n\n /** @internal Wait for an operation to settle. */\n async settled(\n session: ContainerSessionId,\n operationId: string,\n signal?: AbortSignal\n ): Promise<ContainerOperationResult> {\n const store = await this.#openStore();\n for (;;) {\n const operation = store.operation(session, operationId);\n if (!operation) {\n return {\n operationId,\n session,\n status: \"unanswered\",\n reason: \"not_found\"\n };\n }\n const result = resultOf(operation);\n if (result) return result;\n if (signal?.aborted) throw signal.reason;\n await this.#until(\n this.#settleWaiters,\n `${session}\\0${operationId}`,\n signal,\n SETTLE_POLL_MS\n );\n }\n }\n\n /** @internal The active transcript. */\n async transcript(session: ContainerSessionId): Promise<ContainerMessage[]> {\n const store = await this.#openStore();\n const record = this.#requireSession(store, session);\n const state = parseSessionState(record.state);\n return store\n .read(session, MESSAGES, { after: state.messagesFrom })\n .map((entry) => parseMessage(entry.data));\n }\n\n /** @internal */\n async busy(session: ContainerSessionId): Promise<boolean> {\n const store = await this.#openStore();\n return store.operations({ session, status: OPEN }).length > 0;\n }\n\n /** @internal Start a new context: a new agent session, without history. */\n async resetSession(\n session: ContainerSessionId,\n handoff: string | undefined\n ): Promise<void> {\n const store = await this.#openStore();\n if (store.operations({ session, status: OPEN }).length > 0) {\n throw new Error(`Container session ${session} is busy; abort it first`);\n }\n store.transaction(() => {\n const state = parseSessionState(\n this.#requireSession(store, session).state\n );\n store.clear(session, ENGINE);\n store.setSessionState(\n session,\n sessionStateJson({\n ...state,\n generation: state.generation + 1,\n messagesFrom: store.end(session, MESSAGES),\n handoff\n })\n );\n });\n // The next attach opens the new generation.\n this.#detach(session);\n }\n\n /** @internal */\n async setModel(session: ContainerSessionId, model: string): Promise<void> {\n const store = await this.#openStore();\n const state = parseSessionState(this.#requireSession(store, session).state);\n store.setSessionState(session, sessionStateJson({ ...state, model }));\n this.#attached.get(session)?.link.send({\n type: \"configure\",\n settings: this.#settings({ ...state, model })\n });\n }\n\n /** @internal */\n async events(session: ContainerSessionId): Promise<ContainerEventStream> {\n // Listen before taking the snapshot, and hold what arrives until\n // `start()`: nothing between the snapshot and the first listener is\n // lost. An event may repeat what the snapshot already shows (messages\n // are keyed by id, so applying one twice is harmless).\n let buffered: ContainerSessionEvent[] | undefined = [];\n let listener:\n | ((events: readonly ContainerSessionEvent[]) => void)\n | undefined;\n let stopped = false;\n const relay = (events: readonly ContainerSessionEvent[]) => {\n if (buffered) buffered.push(...events);\n else listener?.(events);\n };\n let set = this.#listeners.get(session);\n if (!set) {\n set = new Set();\n this.#listeners.set(session, set);\n }\n set.add(relay);\n let snapshot: ContainerSessionSnapshot;\n try {\n snapshot = {\n session,\n messages: await this.transcript(session),\n pending: await this.pending({ session }),\n busy: await this.busy(session)\n };\n } catch (error) {\n // No stream to stop: drop the relay here (an unknown session, say).\n set.delete(relay);\n throw error;\n }\n return {\n snapshot,\n start: (next) => {\n if (listener || stopped) {\n throw new Error(\"The event stream has already started\");\n }\n listener = next;\n const held = buffered ?? [];\n buffered = undefined;\n if (held.length > 0) next(held);\n },\n stop: async () => {\n stopped = true;\n buffered = undefined;\n listener = undefined;\n this.#listeners.get(session)?.delete(relay);\n }\n };\n }\n\n // ── The wake ─────────────────────────────────────────────────────────────\n\n /** Schedule the session's wake job now, or pull it forward. */\n #wake(\n session: ContainerSessionId,\n time = Date.now(),\n failures = 0\n ): Promise<unknown> {\n const payload: WakePayload = { session, failures };\n return this.lifecycle.jobs.push({\n id: wakeJobId(session),\n fn: WAKE_FN,\n time,\n payload,\n singleflight: true,\n recoveryLoop: true\n });\n }\n\n /**\n * One run of a session's wake job. It never blocks on the container: it\n * hands the drive (start or attach, reconcile, deliver, wait) to the\n * alarm's tracked work and returns a heartbeat. It completes when the\n * session has no open operations.\n */\n async #wakeStep(wake: WakePayload): Promise<LifecycleJobOutcome> {\n const { session } = wake;\n const heartbeat = { rescheduleAt: Date.now() + this.#heartbeatMs };\n if (this.#waits.has(session)) return heartbeat;\n const store = await this.#openStore();\n if (!store.session(session)) return undefined;\n if (store.operations({ session, status: OPEN }).length === 0) {\n this.#detach(session);\n return undefined;\n }\n const drive = this.#drive(store, wake)\n .catch((error: unknown) => {\n const detail = { session, error: errorText(error) };\n console.error(\"[container-harness] drive failed\", detail);\n this.lifecycle.events.emit(\"container:drive_error\", detail);\n return { at: Date.now() + this.#retryBaseMs, failures: wake.failures };\n })\n .then((next) => {\n this.#waits.delete(session);\n // Re-check at `next.at`: more work may have arrived, the socket may\n // have closed, or a failed start backs off.\n void this.#wake(session, next.at, next.failures);\n });\n this.#waits.set(session, drive);\n // The drive runs past this dispatch, inside the alarm's work, so the\n // object stays alive for it. The heartbeat covers an eviction.\n this.lifecycle.trackAlarmWork(drive);\n return heartbeat;\n }\n\n /**\n * Attach, deliver, and wait while the session has open work and a live\n * socket. Resolves with when the wake should look again.\n */\n async #drive(\n store: HarnessStore,\n wake: WakePayload\n ): Promise<{ readonly at: number; readonly failures: number }> {\n const { session } = wake;\n // Count the attempt before making it: an eviction in the middle of a\n // start must still count towards giving up.\n const failures = wake.failures + 1;\n await this.#wake(session, Date.now() + this.#heartbeatMs, failures);\n const attached = await this.#attach(session);\n if (attached._tag === \"err\" && attached.error._tag === \"retry\") {\n // Not a failure: try again at once, with the count as it was.\n await this.#wake(session, Date.now() + this.#heartbeatMs, wake.failures);\n return { at: Date.now(), failures: wake.failures };\n }\n if (attached._tag === \"err\") {\n const detail = { session, failures, error: attached.error.message };\n console.warn(\"[container-harness] attach failed\", detail);\n this.lifecycle.events.emit(\"container:attach_error\", detail);\n if (failures < MAX_START_FAILURES) {\n const backoff = Math.min(\n this.#retryBaseMs * 2 ** (failures - 1),\n 30_000\n );\n return { at: Date.now() + backoff, failures };\n }\n // Give the work up rather than retry forever; the next submit tries\n // again, from the preferred snapshot: every source failed, so no\n // snapshot is to blame.\n await this.#clearAllFailures();\n for (const operation of store.operations({ session, status: OPEN })) {\n this.#settle(store, session, operation.id, {\n status: \"unanswered\",\n reason: \"container_unavailable\"\n });\n }\n return { at: Date.now(), failures: 0 };\n }\n await this.#wake(session, Date.now() + this.#heartbeatMs, 0);\n this.#deliver(store, session);\n await this.#waitForWork(store, session);\n return { at: Date.now(), failures: 0 };\n }\n\n /**\n * Resolves when the session has no open work, its socket closed, the\n * container stopped, or the budget ran out.\n */\n async #waitForWork(\n store: HarnessStore,\n session: ContainerSessionId\n ): Promise<void> {\n const budget = new AbortController();\n const timer = setTimeout(() => budget.abort(), this.#waitBudgetMs);\n // A container that dies does not always close its sockets promptly;\n // check that it still runs while waiting.\n const watch = setInterval(() => {\n if (!this.#options.container.running) this.#detach(session);\n }, CONTAINER_CHECK_MS);\n try {\n while (\n !budget.signal.aborted &&\n this.#attached.get(session)?.link.open === true &&\n store.operations({ session, status: OPEN }).length > 0\n ) {\n await this.#until(this.#changeWaiters, session, budget.signal);\n }\n } catch {\n // The budget ran out; the heartbeat waits again.\n } finally {\n clearTimeout(timer);\n clearInterval(watch);\n }\n }\n\n /** The platform's inactivity timeout: past the harness's own idle stop. */\n #inactivityTimeoutMs(): number {\n return this.#idleTimeoutMs + IDLE_GRACE_MS;\n }\n\n /** The idle stop: destroy the container once nothing has used it for `idleTimeoutMs`. */\n async #idleStep(): Promise<LifecycleJobOutcome> {\n const store = await this.#openStore();\n if (store.operations({ status: OPEN }).length > 0) return undefined;\n const container = this.#options.container;\n if (!container.running) return undefined;\n await this.dispose();\n await this.#saveWorkspace(container);\n await container.destroy();\n this.#broadcast({ type: \"container\", status: \"stopped\" });\n return undefined;\n }\n\n async #scheduleIdle(): Promise<void> {\n await this.lifecycle.jobs.push({\n id: IDLE_JOB,\n fn: IDLE_FN,\n time: Date.now() + this.#idleStopMs\n });\n }\n\n // ── The container ────────────────────────────────────────────────────────\n\n async #runtimeRecord(): Promise<Runtime | undefined> {\n if (this.#runtime) return this.#runtime;\n await this.lifecycle.ready();\n const stored = await this.lifecycle.storage.get<Runtime>(RUNTIME_KEY);\n this.#runtime = stored;\n return stored;\n }\n\n /** The running container, started if it is not. Single-flight. */\n #ensureRuntime(): Promise<RuntimeResult> {\n this.#starting ??= this.#doEnsureRuntime().finally(() => {\n this.#starting = undefined;\n });\n return this.#starting;\n }\n\n async #doEnsureRuntime(): Promise<RuntimeResult> {\n const container = this.#options.container;\n const known = await this.#runtimeRecord();\n if (container.running && known) {\n if (!this.#timeoutSet) {\n await container.setInactivityTimeout(this.#inactivityTimeoutMs());\n this.#timeoutSet = true;\n }\n // A container that already runs has had time to boot; one that does\n // not answer soon is replaced rather than waited on for a full start.\n const healthy = await waitHealthy(\n this.#port(),\n Math.min(this.#startTimeoutMs, ADOPT_TIMEOUT_MS),\n () => container.running\n );\n if (healthy._tag === \"ok\") return { _tag: \"ok\", value: known };\n // Running but not answering: replace it.\n await container.destroy().catch(() => undefined);\n } else if (container.running) {\n // A container this object has no record of cannot be authenticated.\n await container.destroy().catch(() => undefined);\n }\n return this.#launch(container);\n }\n\n /**\n * The daemon's port on the container that runs now. Taken fresh each\n * time: a port taken before `start()` stays bound to no instance.\n */\n #port(): Fetcher {\n return this.#options.container.getTcpPort(\n this.#options.port ?? DAEMON_PORT\n );\n }\n\n /**\n * Start the agent's container and route its egress. A managed image is\n * restored from this setup's snapshot when there is one, and set up (and\n * snapshotted) when there is not.\n */\n async #start(\n container: Container,\n runtime: Runtime\n ): Promise<\n | { readonly _tag: \"ok\"; readonly value: StartedFrom }\n | { readonly _tag: \"err\"; readonly error: LinkError }\n > {\n const agent = this.#options.agent;\n const image = agent.image;\n const env: Record<string, string> = {\n ...agent.env,\n CF_HARNESS_ADAPTER: agent.adapter,\n [CONTAINER_ENV.token]: runtime.token,\n [CONTAINER_ENV.runtimeId]: runtime.runtimeId,\n [CONTAINER_ENV.port]: String(this.#options.port ?? DAEMON_PORT)\n };\n const base = {\n enableInternet: this.#options.enableInternet ?? true,\n instance: this.#options.instance ?? \"standard-1\"\n };\n let from: StartedFrom = \"image\";\n let key: string | undefined;\n let options: Record<string, unknown>;\n const baseKey = await this.#baseKey();\n const workspace = await this.#usableSnapshot(WORKSPACE_KEY, baseKey);\n if (image.kind === \"custom\") {\n if (workspace) {\n from = \"workspace\";\n options = { ...base, env, containerSnapshot: workspace.snapshot };\n } else {\n options = { ...base, env, image: image.image };\n }\n } else {\n key = baseKey;\n const stored = await this.#usableSnapshot(SNAPSHOT_KEY, key);\n const managed = {\n ...base,\n env: { ...env, CF_HARNESS_USER: AGENT_USER },\n entrypoint: [...MANAGED_ENTRYPOINT]\n };\n if (workspace) {\n // The filesystem as the last container left it: the workspace,\n // the CLI and its setup, all in one.\n from = \"workspace\";\n options = { ...managed, containerSnapshot: workspace.snapshot };\n } else if (stored) {\n from = \"snapshot\";\n options = { ...managed, containerSnapshot: stored.snapshot };\n } else {\n from = \"setup\";\n options = { ...managed, image: MANAGED_IMAGE };\n }\n }\n try {\n // SAFETY: `image`, `instance` and `containerSnapshot` are start\n // options of the `durable_object` scheduling policy that this\n // workers-types version does not declare yet; the rest is\n // `ContainerStartupOptions` as is.\n container.start(options as unknown as ContainerStartupOptions);\n } catch (error) {\n await this.#snapshotFailed(from);\n return {\n _tag: \"err\",\n error: { _tag: \"unreachable\", message: errorText(error) }\n };\n }\n try {\n await container.setInactivityTimeout(this.#inactivityTimeoutMs());\n this.#timeoutSet = true;\n // Intercepts last for one container: route them on every start,\n // before the CLI can make a request.\n const egress = this.#options.egress;\n if (egress && agent.egress.length > 0) {\n const binding = egress({ props: { routes: agent.egress } });\n for (const route of agent.egress) {\n await container.interceptOutboundHttp(route.host, binding);\n }\n }\n } catch (error) {\n // The container started; what failed says nothing about the snapshot.\n return {\n _tag: \"err\",\n error: { _tag: \"unreachable\", message: errorText(error) }\n };\n }\n if (from === \"setup\" && image.kind === \"managed\" && key !== undefined) {\n const setup = await setUp(container, image.setup, key);\n if (setup._tag === \"err\") {\n return {\n _tag: \"err\",\n error: { _tag: \"unreachable\", message: setup.error.message }\n };\n }\n if (setup.snapshot) {\n const record: SnapshotRecord = {\n ...setup.snapshot,\n usedAt: Date.now()\n };\n await this.lifecycle.storage.put(SNAPSHOT_KEY, record);\n }\n }\n return { _tag: \"ok\", value: from };\n }\n\n /**\n * The stored snapshot for `key`, unless it is for another setup, too old\n * to restore (deleted), or failing (skipped for now, kept).\n */\n async #usableSnapshot(\n storageKey: string,\n key: string\n ): Promise<SnapshotRecord | undefined> {\n const record = await this.lifecycle.storage.get<SnapshotRecord>(storageKey);\n if (!record || record.key !== key) return undefined;\n if (Date.now() - (record.usedAt ?? Date.now()) > SNAPSHOT_STALE_MS) {\n await this.lifecycle.storage.delete(storageKey);\n return undefined;\n }\n if (record.probe) return record;\n if ((record.failures?.count ?? 0) >= SKIP_AFTER_FAILURES) return undefined;\n return record;\n }\n\n /** Index of a start source in `SNAPSHOT_SOURCES`; the image or setup is last. */\n #rank(from: StartedFrom): number {\n const index = SNAPSHOT_SOURCES.findIndex((source) => source.from === from);\n return index === -1 ? SNAPSHOT_SOURCES.length : index;\n }\n\n /**\n * A start failed. Count it against the snapshot it came from. A\n * preferred snapshot being skipped is not to blame when its fallback\n * fails too (no capacity, say): its count is cleared, so it is tried\n * again.\n */\n async #snapshotFailed(from: StartedFrom): Promise<void> {\n const rank = this.#rank(from);\n for (const [index, source] of SNAPSHOT_SOURCES.entries()) {\n const record = await this.lifecycle.storage.get<SnapshotRecord>(\n source.storageKey\n );\n if (!record) continue;\n if (index === rank && record.probe) {\n // It failed right after another source started: it is broken.\n console.warn(\n `[container-harness] dropping the ${source.from} snapshot: it no longer starts`\n );\n await this.lifecycle.storage.delete(source.storageKey);\n } else if (index === rank) {\n const now = Date.now();\n const failed: SnapshotRecord = {\n ...record,\n failures: {\n count: (record.failures?.count ?? 0) + 1,\n since: record.failures?.since ?? now\n }\n };\n await this.lifecycle.storage.put(source.storageKey, failed);\n } else if (index < rank && record.failures) {\n await this.#clearFailures(source.storageKey, record);\n }\n }\n }\n\n /**\n * A start came up. Its snapshot's lifetime restarts and its failures\n * clear. A preferred snapshot that was being skipped is not proven\n * broken by this (the failures may have been an outage that has just\n * ended): it is marked to be tried once more, and the caller stops this\n * container to do so. Returns whether it should.\n */\n async #snapshotWorked(from: StartedFrom): Promise<boolean> {\n const rank = this.#rank(from);\n let retry = false;\n for (const [index, source] of SNAPSHOT_SOURCES.entries()) {\n const record = await this.lifecycle.storage.get<SnapshotRecord>(\n source.storageKey\n );\n if (!record) continue;\n if (index === rank) {\n const worked: SnapshotRecord = {\n key: record.key,\n snapshot: record.snapshot,\n usedAt: Date.now()\n };\n await this.lifecycle.storage.put(source.storageKey, worked);\n } else if (\n index < rank &&\n !record.probe &&\n (record.failures?.count ?? 0) >= SKIP_AFTER_FAILURES\n ) {\n const probe: SnapshotRecord = {\n key: record.key,\n snapshot: record.snapshot,\n ...(record.usedAt === undefined ? {} : { usedAt: record.usedAt }),\n probe: true\n };\n await this.lifecycle.storage.put(source.storageKey, probe);\n retry = true;\n }\n }\n return retry;\n }\n\n /** Forget every snapshot's failures: nothing could be concluded from them. */\n async #clearAllFailures(): Promise<void> {\n for (const source of SNAPSHOT_SOURCES) {\n const record = await this.lifecycle.storage.get<SnapshotRecord>(\n source.storageKey\n );\n if (record?.failures || record?.probe) {\n await this.#clearFailures(source.storageKey, record);\n }\n }\n }\n\n async #clearFailures(\n storageKey: string,\n record: SnapshotRecord\n ): Promise<void> {\n const cleared: SnapshotRecord = {\n key: record.key,\n snapshot: record.snapshot,\n ...(record.usedAt === undefined ? {} : { usedAt: record.usedAt })\n };\n await this.lifecycle.storage.put(storageKey, cleared);\n }\n\n /** What a container's filesystem is built from: the setup, or the image. */\n async #baseKey(): Promise<string> {\n const image = this.#options.agent.image;\n return image.kind === \"managed\"\n ? setupKey(image.setup)\n : `image:${image.image}`;\n }\n\n /**\n * Snapshot the container's filesystem before the harness stops it, so the\n * next container starts with the workspace as this one left it. A failed\n * snapshot costs the workspace edits, never the stop.\n */\n async #saveWorkspace(container: Container): Promise<void> {\n try {\n const snapshot = await container.snapshotContainer({\n name: `workspace-${Date.now()}`\n });\n const saved: SnapshotRecord = {\n key: await this.#baseKey(),\n snapshot: { id: snapshot.id },\n usedAt: Date.now()\n };\n await this.lifecycle.storage.put(WORKSPACE_KEY, saved);\n } catch (error) {\n // An older workspace snapshot would roll the workspace back past what\n // the conversation has seen: start the next container from the clean\n // setup instead.\n await this.lifecycle.storage.delete(WORKSPACE_KEY);\n console.warn(\n \"[container-harness] workspace snapshot failed; the next container starts without this workspace\",\n { error: errorText(error) }\n );\n }\n }\n\n async #launch(container: Container): Promise<RuntimeResult> {\n const runtime: Runtime = {\n runtimeId: crypto.randomUUID(),\n token: `${crypto.randomUUID()}${crypto.randomUUID()}`.replaceAll(\"-\", \"\")\n };\n // Recorded before the start: a container can outlive this isolate, and\n // its environment cannot be changed once it runs.\n await this.lifecycle.storage.put(RUNTIME_KEY, runtime);\n this.#runtime = runtime;\n this.#broadcast({ type: \"container\", status: \"starting\" });\n const started = await this.#start(container, runtime);\n if (started._tag === \"err\") {\n await container.destroy().catch(() => undefined);\n return started;\n }\n const healthy = await waitHealthy(\n this.#port(),\n this.#startTimeoutMs,\n () => container.running\n );\n if (healthy._tag === \"err\") {\n await this.#snapshotFailed(started.value);\n await container.destroy().catch(() => undefined);\n return healthy;\n }\n if (await this.#snapshotWorked(started.value)) {\n // A preferred snapshot was skipped after failing; the platform has\n // just started a container, so try that snapshot once more.\n await container.destroy().catch(() => undefined);\n return {\n _tag: \"err\",\n error: {\n _tag: \"retry\",\n message: \"retrying a snapshot skipped after failed starts\"\n }\n };\n }\n this.#broadcast({ type: \"container\", status: \"ready\" });\n return { _tag: \"ok\", value: runtime };\n }\n\n // ── Attaching and reconciling ────────────────────────────────────────────\n\n /** The session's socket, opened and reconciled if it is not. Single-flight. */\n #attach(session: ContainerSessionId): Promise<AttachResult> {\n const attached = this.#attached.get(session);\n if (attached?.link.open)\n return Promise.resolve({ _tag: \"ok\", value: attached });\n let attaching = this.#attaching.get(session);\n if (!attaching) {\n attaching = this.#doAttach(session).finally(() => {\n this.#attaching.delete(session);\n });\n this.#attaching.set(session, attaching);\n }\n return attaching;\n }\n\n async #doAttach(session: ContainerSessionId): Promise<AttachResult> {\n const runtime = await this.#ensureRuntime();\n if (runtime._tag === \"err\") return runtime;\n const port = this.#port();\n // Frames can arrive while the link is being set up; they are applied\n // once the reconcile has fixed the cursor.\n let ready: Attached | undefined;\n const early: { seq: number; frame: DaemonFrame }[] = [];\n let caughtUpEarly = false;\n const opened = await DaemonLink.open(port, session, runtime.value.token, {\n frame: (seq, frame) => {\n if (ready) this.#onFrame(session, ready, seq, frame);\n else early.push({ seq, frame });\n },\n caughtUp: () => {\n if (ready) this.#onCaughtUp(session, ready);\n else caughtUpEarly = true;\n },\n closed: () => this.#onClosed(session, ready)\n });\n if (opened._tag === \"err\") return opened;\n const { link, hello } = opened.value;\n const attached: Attached = {\n link,\n runtimeId: hello.runtimeId,\n sinceAck: 0,\n settledThere: []\n };\n if (hello.runtimeId !== runtime.value.runtimeId) {\n // The token matched, so this is a container this object started; its\n // record was lost or superseded. Adopt the id it reports.\n const adopted = { ...runtime.value, runtimeId: hello.runtimeId };\n await this.lifecycle.storage.put(RUNTIME_KEY, adopted);\n this.#runtime = adopted;\n }\n const store = await this.#openStore();\n this.#reconcile(store, session, attached, hello);\n this.#attached.get(session)?.link.close();\n this.#attached.set(session, attached);\n ready = attached;\n for (const each of early)\n this.#onFrame(session, attached, each.seq, each.frame);\n if (caughtUpEarly) this.#onCaughtUp(session, attached);\n return { _tag: \"ok\", value: attached };\n }\n\n /**\n * The replay is complete. Operations the container reported settled in\n * `hello` whose frames it no longer kept are settled from the report now,\n * after every frame it did keep, so their messages land first.\n */\n #onCaughtUp(session: ContainerSessionId, attached: Attached): void {\n const store = this.#store;\n if (!store) return;\n for (const { operationId, outcome } of attached.settledThere.splice(0)) {\n this.#settle(store, session, operationId, outcome);\n }\n }\n\n /**\n * Make the container's view of a session and the object's agree, before\n * anything is delivered: open the adapter session if the container does\n * not hold it, settle what the container already settled, decide what to\n * do with work a lost container took with it, abort what the container\n * still runs but the object has given up on, and replay missed frames.\n */\n #reconcile(\n store: HarnessStore,\n session: ContainerSessionId,\n attached: Attached,\n hello: Hello\n ): void {\n const { link } = attached;\n let state = parseSessionState(this.#requireSession(store, session).state);\n const sameRuntime = state.cursor?.runtimeId === hello.runtimeId;\n let lostAny = false;\n\n if (hello.open !== state.generation) {\n const groups = chunkEntries(\n store.read(session, ENGINE).map((entry) => entry.data)\n );\n const last = groups.pop() ?? [];\n for (const entries of groups) {\n link.send({ type: \"restore\", generation: state.generation, entries });\n }\n link.send({\n type: \"open\",\n generation: state.generation,\n settings: this.#settings(state),\n restore: last\n });\n }\n\n const known = new Map(\n hello.operations.map((operation) => [operation.operationId, operation])\n );\n for (const operation of store.operations({ session, status: OPEN })) {\n const there = known.get(operation.id);\n if (there?.status === \"settled\") {\n attached.settledThere.push({\n operationId: operation.id,\n outcome: there.outcome\n });\n continue;\n }\n if (there) continue;\n const meta = parseMeta(operation.meta);\n // Only a run that started is lost with its container. One that was\n // handed over but never started is handed to this container instead.\n const lost =\n operation.status === \"running\" && meta.delivered !== hello.runtimeId;\n if (!lost) {\n // Never started, or handed to this container but it never got it\n // (the socket closed under the send): hand it over again.\n if (meta.delivered !== null) {\n store.setOperationMeta(\n session,\n operation.id,\n metaJson({ ...meta, delivered: null })\n );\n }\n continue;\n }\n lostAny = true;\n if (this.#options.onContainerLost === \"retry\") {\n store.transaction(() => {\n store.requeue(session, operation.id);\n store.setOperationMeta(\n session,\n operation.id,\n metaJson({ ...meta, delivered: null })\n );\n });\n } else {\n this.#settle(store, session, operation.id, {\n status: \"unanswered\",\n reason: \"container_lost\"\n });\n }\n }\n for (const there of hello.operations) {\n if (there.status === \"settled\") continue;\n const operation = store.operation(session, there.operationId);\n if (\n !operation ||\n operation.status === \"done\" ||\n operation.status === \"unanswered\"\n ) {\n link.send({ type: \"abort\", operationId: there.operationId });\n }\n }\n\n if (lostAny) this.#emit(session, [{ type: \"container\", status: \"lost\" }]);\n if (!sameRuntime) {\n state = { ...state, cursor: { runtimeId: hello.runtimeId, seq: 0 } };\n store.setSessionState(session, sessionStateJson(state));\n }\n link.send({ type: \"replay\", after: state.cursor?.seq ?? 0 });\n }\n\n /** Hand every undelivered open operation of the session to the container. */\n #deliver(store: HarnessStore, session: ContainerSessionId): void {\n const attached = this.#attached.get(session);\n if (!attached?.link.open) return;\n for (const operation of store.operations({ session, status: OPEN })) {\n const meta = parseMeta(operation.meta);\n if (meta.delivered === attached.runtimeId) continue;\n let input = parseInput(operation.input);\n const state = parseSessionState(\n this.#requireSession(store, session).state\n );\n if (state.handoff !== undefined)\n input = withHandoff(input, state.handoff);\n const sent = attached.link.send({\n type: \"prompt\",\n operationId: operation.id,\n input,\n whenBusy: meta.whenBusy\n });\n if (!sent) return;\n store.transaction(() => {\n store.setOperationMeta(\n session,\n operation.id,\n metaJson({ ...meta, delivered: attached.runtimeId })\n );\n if (state.handoff !== undefined) {\n store.setSessionState(\n session,\n sessionStateJson({ ...state, handoff: undefined })\n );\n }\n });\n }\n }\n\n /** Apply one frame from the container. */\n #onFrame(\n session: ContainerSessionId,\n attached: Attached,\n seq: number,\n frame: DaemonFrame\n ): void {\n const store = this.#store;\n if (!store) return;\n const events: ContainerSessionEvent[] = [];\n let settled: ContainerOperationResult | undefined;\n store.transaction(() => {\n const record = store.session(session);\n if (!record) return;\n let state = parseSessionState(record.state);\n if (\n state.cursor?.runtimeId === attached.runtimeId &&\n seq <= state.cursor.seq\n ) {\n return;\n }\n switch (frame.kind) {\n case \"start\": {\n if (store.start(session, frame.operationId)) {\n const operation = store.operation(session, frame.operationId);\n if (operation) {\n const message: ContainerMessage = {\n id: `${operation.id}:user`,\n role: \"user\",\n parts: userParts(parseInput(operation.input)),\n operationId: operation.id,\n createdAt: operation.createdAt\n };\n store.append(session, MESSAGES, [\n { id: message.id, data: messageJson(message) }\n ]);\n events.push({\n type: \"message\",\n message,\n operationId: operation.id\n });\n }\n events.push({\n type: \"operation-start\",\n operationId: frame.operationId\n });\n }\n break;\n }\n case \"event\":\n events.push({ ...frame.event, operationId: frame.operationId });\n if (frame.event.type === \"message\") {\n store.append(session, MESSAGES, [\n {\n id: frame.event.message.id,\n data: messageJson(frame.event.message)\n }\n ]);\n }\n break;\n case \"persist\":\n store.append(\n session,\n ENGINE,\n frame.entries.map((data) => ({ data }))\n );\n break;\n case \"settle\":\n settled = this.#settleInStore(\n store,\n session,\n frame.operationId,\n frame.outcome\n );\n break;\n }\n state = { ...state, cursor: { runtimeId: attached.runtimeId, seq } };\n store.setSessionState(session, sessionStateJson(state));\n });\n if (settled) events.push({ type: \"operation-end\", result: settled });\n this.#emit(session, events);\n attached.sinceAck += 1;\n if (settled || attached.sinceAck >= ACK_EVERY) {\n attached.sinceAck = 0;\n attached.link.send({ type: \"ack\", seq });\n }\n if (settled) this.#afterSettle(store, session, settled);\n }\n\n #onClosed(session: ContainerSessionId, attached: Attached | undefined): void {\n if (attached && this.#attached.get(session) === attached) {\n this.#attached.delete(session);\n }\n this.#notify(this.#changeWaiters, session);\n }\n\n #detach(session: ContainerSessionId): void {\n const attached = this.#attached.get(session);\n this.#attached.delete(session);\n attached?.link.close();\n this.#notify(this.#changeWaiters, session);\n }\n\n // ── Settling ─────────────────────────────────────────────────────────────\n\n #settleInStore(\n store: HarnessStore,\n session: ContainerSessionId,\n operationId: string,\n outcome: ContainerOutcome\n ): ContainerOperationResult | undefined {\n const changed = store.settle(\n session,\n operationId,\n outcome.status === \"done\"\n ? { status: \"done\", result: { text: outcome.text } }\n : outcome\n );\n if (!changed) return undefined;\n const operation = store.operation(session, operationId);\n return operation ? resultOf(operation) : undefined;\n }\n\n /** Settle outside a frame, and tell everyone. */\n #settle(\n store: HarnessStore,\n session: ContainerSessionId,\n operationId: string,\n outcome: ContainerOutcome\n ): void {\n const result = this.#settleInStore(store, session, operationId, outcome);\n if (!result) return;\n this.#emit(session, [{ type: \"operation-end\", result }]);\n this.#afterSettle(store, session, result);\n }\n\n #afterSettle(\n store: HarnessStore,\n session: ContainerSessionId,\n result: ContainerOperationResult\n ): void {\n this.#notify(this.#settleWaiters, `${session}\\0${result.operationId}`);\n this.#notify(this.#changeWaiters, session);\n if (store.operations({ status: OPEN }).length === 0) {\n void this.#scheduleIdle().catch(() => undefined);\n }\n }\n\n // ── Small pieces ─────────────────────────────────────────────────────────\n\n async #openStore(): Promise<HarnessStore> {\n if (this.#store) return this.#store;\n await this.lifecycle.ready();\n if (this.#store) return this.#store;\n const store = openHarnessStore(this.lifecycle.storage, {\n prefix: this.#options.storePrefix ?? \"container_\"\n });\n store.createSession({\n id: ROOT_SESSION,\n state: sessionStateJson(this.#initial())\n });\n this.#store = store;\n return store;\n }\n\n #initial(): SessionState {\n return {\n model: this.#options.defaults?.model ?? this.#options.agent.model,\n cursor: null,\n generation: 1,\n messagesFrom: 0,\n handoff: undefined\n };\n }\n\n #settings(state: SessionState): ContainerSettings {\n const options =\n this.#options.defaults?.options ?? this.#options.agent.options;\n return {\n ...(state.model === undefined ? {} : { model: state.model }),\n ...(options === undefined ? {} : { options })\n };\n }\n\n #requireSession(store: HarnessStore, session: ContainerSessionId) {\n const record = store.session(session);\n if (!record) throw new Error(`Unknown container session ${session}`);\n return record;\n }\n\n #emit(session: ContainerSessionId, events: readonly ContainerSessionEvent[]) {\n if (events.length === 0) return;\n const listeners = this.#listeners.get(session);\n if (!listeners) return;\n for (const listener of listeners) {\n try {\n listener(events);\n } catch {\n // A listener's failure is its own.\n }\n }\n }\n\n #broadcast(event: ContainerSessionEvent): void {\n for (const session of this.#listeners.keys()) this.#emit(session, [event]);\n }\n\n #notify<K>(waiters: Map<K, Set<() => void>>, key: K): void {\n const set = waiters.get(key);\n waiters.delete(key);\n if (set) for (const wake of set) wake();\n }\n\n /**\n * Resolve on the next notify for `key`, after `pollMs` if given, or\n * reject when `signal` aborts.\n *\n * The poll matters for waits in a request: the notify comes from the\n * alarm that drives the container, a different request context, and a\n * request whose only pending work is a promise another context resolves\n * is cancelled by the runtime as hung. A timer of its own keeps it alive,\n * and the caller re-reads the store when it fires.\n */\n #until<K>(\n waiters: Map<K, Set<() => void>>,\n key: K,\n signal: AbortSignal | undefined,\n pollMs?: number\n ): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n let set = waiters.get(key);\n if (!set) {\n set = new Set();\n waiters.set(key, set);\n }\n let timer: ReturnType<typeof setTimeout> | undefined;\n const done = () => {\n clearTimeout(timer);\n set?.delete(wake);\n signal?.removeEventListener(\"abort\", onAbort);\n };\n const onAbort = () => {\n done();\n reject(signal?.reason);\n };\n const wake = () => {\n done();\n resolve();\n };\n if (signal?.aborted) {\n onAbort();\n return;\n }\n signal?.addEventListener(\"abort\", onAbort, { once: true });\n set.add(wake);\n if (pollMs !== undefined) timer = setTimeout(wake, pollMs);\n });\n }\n}\n\n/** Where a container started from. */\ntype StartedFrom = \"image\" | \"workspace\" | \"snapshot\" | \"setup\";\n\ntype RuntimeResult =\n | { readonly _tag: \"ok\"; readonly value: Runtime }\n | { readonly _tag: \"err\"; readonly error: LinkError };\n\ntype AttachResult =\n | { readonly _tag: \"ok\"; readonly value: Attached }\n | { readonly _tag: \"err\"; readonly error: LinkError };\n\nfunction resultOf(\n operation: OperationRecord\n): ContainerOperationResult | undefined {\n const base = { operationId: operation.id, session: operation.session };\n if (operation.status === \"done\") {\n const result = operation.result;\n const text =\n isRecord(result) && typeof result.text === \"string\" ? result.text : \"\";\n return { ...base, status: \"done\", text };\n }\n if (operation.status === \"unanswered\") {\n return {\n ...base,\n status: \"unanswered\",\n reason: operation.reason ?? \"unanswered\"\n };\n }\n return undefined;\n}\n\n/**\n * One session, addressed through the harness.\n *\n * @experimental The API may change before it stabilizes.\n */\nexport class ContainerSession {\n readonly #harness: ContainerHarness;\n /** The session id. */\n readonly id: ContainerSessionId;\n\n /**\n * @param harness - The harness.\n * @param id - The session id.\n */\n constructor(harness: ContainerHarness, id: ContainerSessionId) {\n this.#harness = harness;\n this.id = id;\n }\n\n /**\n * Durably submit a prompt. Resolves before the agent runs.\n *\n * @param input - The prompt.\n * @param options - Idempotency key and busy behaviour.\n * @returns The receipt.\n */\n submit(\n input: ContainerInput,\n options: ContainerSubmitOptions = {}\n ): Promise<ContainerReceipt> {\n return this.#harness.enqueue(this.id, input, options);\n }\n\n /**\n * Submit and wait for the answer and the updated transcript.\n *\n * @param input - The prompt.\n * @param options - Idempotency key and busy behaviour.\n * @returns The result, with the transcript after it.\n */\n async prompt(\n input: ContainerInput,\n options: ContainerSubmitOptions = {}\n ): Promise<ContainerPromptResponse> {\n const receipt = await this.submit(input, options);\n const result = await this.wait(receipt.operationId);\n return { ...result, messages: await this.messages() };\n }\n\n /**\n * Join the running turn, when the adapter can steer; otherwise queue.\n *\n * @param input - The prompt.\n * @param options - Idempotency key.\n * @returns The receipt.\n */\n steer(\n input: ContainerInput,\n options: Omit<ContainerSubmitOptions, \"whenBusy\"> = {}\n ): Promise<ContainerReceipt> {\n return this.submit(input, { ...options, whenBusy: \"steer\" });\n }\n\n /**\n * Wait for an operation to settle. Aborting `signal` stops only the wait.\n *\n * @param operationId - The operation.\n * @param signal - Stops the wait.\n * @returns How it ended.\n */\n wait(\n operationId: string,\n signal?: AbortSignal\n ): Promise<ContainerOperationResult> {\n return this.#harness.settled(this.id, operationId, signal);\n }\n\n /**\n * Withdraw or abort one operation, or, with no id, every open operation\n * of the session. Aborted operations settle `unanswered` with `aborted`.\n *\n * @param operationId - The operation. Default: all of them.\n * @returns Whether anything was open to abort (always true with no id).\n */\n abort(operationId?: string): Promise<boolean> {\n return this.#harness.withdraw(this.id, operationId);\n }\n\n /**\n * Start a new context: a new agent session without the old history,\n * optionally seeded with a handoff note prepended to the next prompt.\n * Throws while the session is busy.\n *\n * @param handoff - The note.\n */\n reset(handoff?: string): Promise<void> {\n return this.#harness.resetSession(this.id, handoff);\n }\n\n /**\n * Change this session's model, by the adapter's model name.\n *\n * @param model - The model.\n */\n setModel(model: string): Promise<void> {\n return this.#harness.setModel(this.id, model);\n }\n\n /**\n * The active transcript, since the newest reset.\n *\n * @returns The messages, oldest first.\n */\n messages(): Promise<ContainerMessage[]> {\n return this.#harness.transcript(this.id);\n }\n\n /**\n * This session's events: a snapshot, then live batches.\n *\n * @returns The stream.\n */\n events(): Promise<ContainerEventStream> {\n return this.#harness.events(this.id);\n }\n\n /**\n * Whether the session has open operations.\n *\n * @returns True while anything is queued or running.\n */\n busy(): Promise<boolean> {\n return this.#harness.busy(this.id);\n }\n}\n\n/**\n * Every session in this object.\n *\n * @experimental The API may change before it stabilizes.\n */\nexport class ContainerSessions {\n readonly #harness: ContainerHarness;\n\n /**\n * @param harness - The harness.\n */\n constructor(harness: ContainerHarness) {\n this.#harness = harness;\n }\n\n /**\n * A handle on one session.\n *\n * @param id - The session id.\n * @returns The handle.\n */\n get(id: ContainerSessionId): ContainerSession {\n return this.#harness.session(id);\n }\n\n /**\n * A new top-level session, with the harness's defaults.\n *\n * @returns The new session.\n */\n async create(): Promise<ContainerSession> {\n const id = crypto.randomUUID();\n await this.#harness.createSession(id);\n return this.#harness.session(id);\n }\n\n /**\n * A new session that continues `from`'s history as a branch.\n *\n * @param from - The session to fork.\n * @returns The new session.\n */\n async fork(from: ContainerSessionId): Promise<ContainerSession> {\n const id = crypto.randomUUID();\n await this.#harness.createSession(id, from);\n return this.#harness.session(id);\n }\n\n /**\n * Every session, oldest first.\n *\n * @returns Each session's id, parent, and whether it is busy.\n */\n async list(): Promise<ContainerSessionInfo[]> {\n const store = await this.#harness.store();\n const busy = new Set(\n store.operations({ status: OPEN }).map((operation) => operation.session)\n );\n return store.sessions().map((record) => ({\n id: record.id,\n ...(record.parent === undefined ? {} : { parent: record.parent }),\n busy: busy.has(record.id)\n }));\n }\n}\n","/**\n * What runs in the container, as typed presets: `claudeCode()`, `codex()`,\n * or `containerAgent()` for an image of your own.\n *\n * A preset is data: the adapter the daemon runs, how the container is\n * built, the environment the CLI sees, and the egress routes that carry\n * its credentials. Credentials (`apiKey`, `headers`) never go into the\n * container: the CLI calls a placeholder host, and `ContainerEgress`\n * forwards to `baseUrl` with the real credentials (see `./egress`).\n */\n\nimport type { EgressRoute } from \"./egress\";\nimport type { SetupStep } from \"./managed-image\";\nimport type { JsonValue } from \"./protocol\";\n\n/**\n * Where a CLI's model requests go, and the credentials they carry. Added\n * outside the container, by `ContainerEgress`.\n *\n * - Straight to the provider: `{ apiKey }`.\n * - AI Gateway with Unified Billing: `{ baseUrl: `${gateway}/anthropic`,\n * apiKey: gatewayToken }`; the gateway takes its token as the key.\n * - AI Gateway with BYOK: `{ baseUrl, headers: { \"cf-aig-authorization\":\n * `Bearer ${gatewayToken}` } }`; the gateway holds the provider key.\n */\nexport type ProviderConnection = {\n /** Sent the way the provider expects: `x-api-key`, or `Authorization: Bearer`. */\n readonly apiKey?: string;\n /**\n * The provider's base URL, as its SDK names it (`ANTHROPIC_BASE_URL`,\n * `OPENAI_BASE_URL`). Default: the provider's own API.\n */\n readonly baseUrl?: string;\n /** More headers on every model request, such as gateway metadata. */\n readonly headers?: { readonly [name: string]: string };\n};\n\n/** How the container is built. */\nexport type ContainerImage =\n /**\n * `cloudflare/debian-trixie`, set up at runtime by the harness: the\n * steps run once and the result is snapshotted. The harness installs the\n * daemon.\n */\n | { readonly kind: \"managed\"; readonly setup: readonly SetupStep[] }\n /** An image you built, whose entrypoint runs the daemon itself. */\n | { readonly kind: \"custom\"; readonly image: string };\n\n/** What runs in the container. Build one with a preset. */\nexport type ContainerAgent = {\n /** The daemon adapter: `claude-code`, `codex`, `echo`, or your own. */\n readonly adapter: string;\n readonly image: ContainerImage;\n /** Environment for the daemon and the CLI. Never put secrets here. */\n readonly env: { readonly [name: string]: string };\n /** Hosts the harness intercepts to add credentials. */\n readonly egress: readonly EgressRoute[];\n /** The model and adapter options new sessions start with. */\n readonly model?: string;\n readonly options?: JsonValue;\n};\n\n/** What the CLI sends instead of a key; egress replaces it. */\nconst PLACEHOLDER_KEY = \"harness-egress\";\n\nconst CREDENTIAL_HEADERS = [\n \"authorization\",\n \"x-api-key\",\n \"cf-aig-authorization\"\n];\n\nfunction npmInstall(name: string, pkg: string): SetupStep {\n return {\n name: `install ${name}`,\n command: [\"npm\", \"install\", \"--global\", \"--no-fund\", \"--no-audit\", pkg]\n };\n}\n\n/** The egress route for one provider. */\nfunction route(\n host: string,\n connection: ProviderConnection,\n provider: {\n readonly baseUrl: string;\n readonly keyHeader: (key: string) => { readonly [name: string]: string };\n }\n): EgressRoute {\n return {\n host,\n upstream: connection.baseUrl ?? provider.baseUrl,\n headers: {\n ...(connection.apiKey === undefined\n ? {}\n : provider.keyHeader(connection.apiKey)),\n ...connection.headers\n },\n strip: CREDENTIAL_HEADERS\n };\n}\n\n/** `claudeCode()`'s options: its provider connection and settings. */\nexport type ClaudeCodeAgentOptions = ProviderConnection & {\n /** Default `claude-sonnet-4-5`. Change one session's with `setModel`. */\n readonly model?: string;\n /** The `@anthropic-ai/claude-code` version. Default `2.1.289`. */\n readonly version?: string;\n readonly appendSystemPrompt?: string;\n readonly allowedTools?: readonly string[];\n readonly disallowedTools?: readonly string[];\n readonly maxTurns?: number;\n /**\n * More setup steps, run after the install and kept in the snapshot. Use\n * `user: \"agent\"` to install plugins, mods or settings in the agent's\n * home, which every session home starts from.\n */\n readonly setup?: readonly SetupStep[];\n};\n\n/**\n * Claude Code, installed at runtime on `cloudflare/debian-trixie`.\n *\n * @param options - Its provider connection (`apiKey`, `baseUrl`,\n * `headers`) and settings.\n * @returns The agent, for `ContainerHarness`'s `agent`.\n *\n * @experimental The API may change before it stabilizes.\n */\nexport function claudeCode(options: ClaudeCodeAgentOptions): ContainerAgent {\n const host = \"anthropic.harness.internal\";\n return {\n adapter: \"claude-code\",\n image: {\n kind: \"managed\",\n setup: [\n npmInstall(\n \"Claude Code\",\n `@anthropic-ai/claude-code@${options.version ?? \"2.1.289\"}`\n ),\n ...(options.setup ?? [])\n ]\n },\n env: {\n ANTHROPIC_BASE_URL: `http://${host}`,\n ANTHROPIC_API_KEY: PLACEHOLDER_KEY,\n DISABLE_AUTOUPDATER: \"1\"\n },\n egress: [\n route(host, options, {\n baseUrl: \"https://api.anthropic.com\",\n keyHeader: (key) => ({ \"x-api-key\": key })\n })\n ],\n model: options.model ?? \"claude-sonnet-4-5\",\n options: {\n ...(options.appendSystemPrompt === undefined\n ? {}\n : { appendSystemPrompt: options.appendSystemPrompt }),\n ...(options.allowedTools === undefined\n ? {}\n : { allowedTools: [...options.allowedTools] }),\n ...(options.disallowedTools === undefined\n ? {}\n : { disallowedTools: [...options.disallowedTools] }),\n ...(options.maxTurns === undefined ? {} : { maxTurns: options.maxTurns })\n }\n };\n}\n\n/** `codex()`'s options: its provider connection and settings. */\nexport type CodexAgentOptions = ProviderConnection & {\n /** Default `gpt-5.1`. Change one session's with `setModel`. */\n readonly model?: string;\n /** The `@openai/codex` version. Default `0.157.0`. */\n readonly version?: string;\n /** Extra `-c key=value` config overrides. */\n readonly config?: readonly string[];\n /**\n * More setup steps, run after the install and kept in the snapshot. Use\n * `user: \"agent\"` to install plugins, mods or settings in the agent's\n * home, which every session home starts from.\n */\n readonly setup?: readonly SetupStep[];\n};\n\n/**\n * Codex, installed at runtime on `cloudflare/debian-trixie`.\n *\n * @param options - Its provider connection (`apiKey`, `baseUrl`,\n * `headers`) and settings.\n * @returns The agent, for `ContainerHarness`'s `agent`.\n *\n * @experimental The API may change before it stabilizes.\n */\nexport function codex(options: CodexAgentOptions): ContainerAgent {\n const host = \"openai.harness.internal\";\n return {\n adapter: \"codex\",\n image: {\n kind: \"managed\",\n setup: [\n npmInstall(\"Codex\", `@openai/codex@${options.version ?? \"0.157.0\"}`),\n ...(options.setup ?? [])\n ]\n },\n env: {\n OPENAI_BASE_URL: `http://${host}`,\n OPENAI_API_KEY: PLACEHOLDER_KEY\n },\n egress: [\n route(host, options, {\n baseUrl: \"https://api.openai.com/v1\",\n keyHeader: (key) => ({ authorization: `Bearer ${key}` })\n })\n ],\n model: options.model ?? \"gpt-5.1\",\n options: options.config === undefined ? {} : { config: [...options.config] }\n };\n}\n\n/** `containerAgent()`'s options. */\nexport type CustomAgentOptions = {\n /** Your image, such as `ctx.container.images.agent`. Its entrypoint runs the daemon. */\n readonly image: string;\n /** The adapter its daemon runs. */\n readonly adapter: string;\n readonly env?: { readonly [name: string]: string };\n readonly egress?: readonly EgressRoute[];\n readonly model?: string;\n readonly options?: JsonValue;\n};\n\n/**\n * An agent in an image you built, whose entrypoint serves the daemon\n * (`serveFromEnv` from `agents/harness/container/runtime`).\n *\n * @param options - The image, the adapter, and its environment.\n * @returns The agent, for `ContainerHarness`'s `agent`.\n *\n * @experimental The API may change before it stabilizes.\n */\nexport function containerAgent(options: CustomAgentOptions): ContainerAgent {\n return {\n adapter: options.adapter,\n image: { kind: \"custom\", image: options.image },\n env: options.env ?? {},\n egress: options.egress ?? [],\n ...(options.model === undefined ? {} : { model: options.model }),\n ...(options.options === undefined ? {} : { options: options.options })\n };\n}\n\n/**\n * The echo adapter on `cloudflare/debian-trixie`: no CLI, no model, no\n * credentials. For smoke tests of the whole path.\n *\n * @returns The agent, for `ContainerHarness`'s `agent`.\n *\n * @experimental The API may change before it stabilizes.\n */\nexport function echoAgent(): ContainerAgent {\n return {\n adapter: \"echo\",\n image: { kind: \"managed\", setup: [] },\n env: {},\n egress: []\n };\n}\n","/**\n * Credentials that never enter the container.\n *\n * The CLI in the container is pointed at a placeholder host over plain\n * HTTP (`http://anthropic.harness.internal`) with a placeholder key. The\n * harness intercepts that host with `ctx.container.interceptOutboundHttp()`\n * and hands each request to `ContainerEgress`, a `WorkerEntrypoint` running\n * in your Worker, which drops the placeholder credentials, adds the real\n * ones, and forwards the request to the real upstream (an AI Gateway, or\n * the provider). The container can run any command it likes and still has\n * nothing to steal.\n *\n * Plain HTTP inside the container means no certificate to trust: the\n * connection to the intercept never leaves Cloudflare, and the request to\n * the upstream is HTTPS.\n */\n\nimport { WorkerEntrypoint } from \"cloudflare:workers\";\n\n/** One intercepted host and where its requests go. */\nexport type EgressRoute = {\n /** The placeholder hostname the CLI calls, such as `anthropic.harness.internal`. */\n readonly host: string;\n /** The real base URL. The request's path and query are appended. */\n readonly upstream: string;\n /** Headers to set on the forwarded request, such as credentials. */\n readonly headers: { readonly [name: string]: string };\n /** Headers to drop from the CLI's request, such as its placeholder key. */\n readonly strip: readonly string[];\n};\n\n/** What `ContainerEgress` is given, as its props. */\nexport type ContainerEgressProps = {\n readonly routes: readonly EgressRoute[];\n};\n\n/**\n * The `ctx.exports` entry for `ContainerEgress`: called with props, it\n * returns the `Fetcher` an intercept hands requests to.\n */\nexport type ContainerEgressBinding = (init: {\n readonly props: ContainerEgressProps;\n}) => Fetcher;\n\n/**\n * Forward one intercepted request to its route's upstream.\n *\n * @param request - The request the container made.\n * @param routes - The routes, by placeholder host.\n * @param fetcher - How to make the upstream request. Default `fetch`.\n * @returns The upstream's response, or 403 for a host without a route.\n */\nexport async function forwardEgress(\n request: Request,\n routes: readonly EgressRoute[],\n fetcher: typeof fetch = fetch\n): Promise<Response> {\n const url = new URL(request.url);\n const route = routes.find((each) => each.host === url.hostname);\n if (!route) {\n return new Response(`No egress route for ${url.hostname}`, { status: 403 });\n }\n const target = `${route.upstream.replace(/\\/+$/, \"\")}${url.pathname}${url.search}`;\n const headers = new Headers(request.headers);\n headers.delete(\"host\");\n for (const name of route.strip) headers.delete(name);\n for (const [name, value] of Object.entries(route.headers)) {\n headers.set(name, value);\n }\n const hasBody = request.method !== \"GET\" && request.method !== \"HEAD\";\n return fetcher(target, {\n method: request.method,\n headers,\n ...(hasBody ? { body: request.body } : {}),\n // Never follow a redirect with the credentials attached.\n redirect: \"manual\"\n });\n}\n\n/**\n * The egress for a `ContainerHarness`'s credentials. Export it from your\n * Worker's main module so `ctx.exports.ContainerEgress` exists:\n *\n * ```ts\n * export { ContainerEgress } from \"agents/harness/container\";\n * ```\n *\n * @experimental The API may change before it stabilizes.\n */\nexport class ContainerEgress extends WorkerEntrypoint<\n unknown,\n ContainerEgressProps\n> {\n /**\n * Forward one request the container made.\n *\n * @param request - The intercepted request.\n * @returns The upstream's response.\n */\n override fetch(request: Request): Promise<Response> {\n return forwardEgress(request, this.ctx.props.routes);\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,144 @@
1
+ import {
2
+ h as ContainerSettings,
3
+ l as ContainerEvent,
4
+ p as ContainerOutcome
5
+ } from "../../../protocol-BEgrJYC5.js";
6
+ import { i as ContainerAdapter } from "../../../daemon-core-CbohVPAu.js";
7
+
8
+ //#region src/harness/container/runtime/server.d.ts
9
+ /** `serve`'s options. */
10
+ type ServeOptions = {
11
+ readonly adapter: ContainerAdapter /** This container's id, from `CF_HARNESS_RUNTIME_ID`. */;
12
+ readonly runtimeId: string /** The shared secret, from `CF_HARNESS_TOKEN`. */;
13
+ readonly token: string /** Port to listen on; 0 picks one. */;
14
+ readonly port: number /** Interface to bind. Default all interfaces. */;
15
+ readonly host?: string;
16
+ };
17
+ /** A running daemon. */
18
+ type DaemonServer = {
19
+ /** The port it listens on. */ readonly port: number /** Stop accepting connections and close every adapter session. */;
20
+ close(): Promise<void>;
21
+ };
22
+ /**
23
+ * Start the daemon.
24
+ *
25
+ * @param options - The adapter, identity, secret, and port.
26
+ * @returns The running server, once it listens.
27
+ *
28
+ * @experimental The API may change before it stabilizes.
29
+ */
30
+ declare function serve(options: ServeOptions): Promise<DaemonServer>;
31
+ /**
32
+ * Start the daemon with the identity, secret, and port the Durable Object
33
+ * started the container with, and stop it on SIGTERM. The entrypoint of an
34
+ * image: `serveFromEnv(cliAdapter({ ... }))`.
35
+ *
36
+ * @param adapter - The agent to run.
37
+ * @param env - The environment. Default `process.env`.
38
+ * @returns The running server.
39
+ *
40
+ * @experimental The API may change before it stabilizes.
41
+ */
42
+ declare function serveFromEnv(
43
+ adapter: ContainerAdapter,
44
+ env?: NodeJS.ProcessEnv
45
+ ): Promise<DaemonServer>;
46
+ //#endregion
47
+ //#region src/harness/container/runtime/cli-adapter.d.ts
48
+ /** String values a CLI reported in earlier turns, such as its session id. */
49
+ type CliState = {
50
+ readonly [key: string]: string;
51
+ };
52
+ /** What a command and a parser are given for one turn. */
53
+ type CliTurn = {
54
+ readonly operationId: string /** The prompt's text. Image parts are not passed to CLIs. */;
55
+ readonly prompt: string;
56
+ readonly settings: ContainerSettings;
57
+ readonly state: CliState;
58
+ };
59
+ /** How to start one turn. */
60
+ type CliCommand = {
61
+ readonly argv: readonly string[] /** Written to the process's stdin, which is then closed. */;
62
+ readonly stdin?: string /** Added to the environment. */;
63
+ readonly env?: {
64
+ readonly [name: string]: string;
65
+ };
66
+ };
67
+ /** What one stdout line meant. */
68
+ type CliUpdate = {
69
+ readonly events?: readonly ContainerEvent[] /** Merged into the session's state and persisted. */;
70
+ readonly state?: CliState /** The turn's outcome, when the line reports it. */;
71
+ readonly outcome?: ContainerOutcome;
72
+ };
73
+ /** Reads one turn's output. */
74
+ type CliParser = {
75
+ line(
76
+ text: string
77
+ ): CliUpdate /** The outcome when no line reported one, from how the process exited. */;
78
+ end(exit: {
79
+ readonly code: number | null;
80
+ readonly stderr: string;
81
+ }): ContainerOutcome;
82
+ };
83
+ /** `cliAdapter`'s options. */
84
+ type CliAdapterOptions = {
85
+ /** Reported in `hello`, such as `"codex"`. */ readonly id: string;
86
+ readonly version?: string;
87
+ readonly command: (turn: CliTurn) => CliCommand;
88
+ readonly parser: (
89
+ turn: CliTurn
90
+ ) => CliParser /** Directories under `$HOME` where the CLI keeps its sessions. */;
91
+ readonly stateDirs?: readonly string[] /** Working directory. Default `/workspace`. */;
92
+ readonly cwd?: string /** Where session homes are created. Default `~/.harness/sessions`. */;
93
+ readonly homes?: string /** How often a running turn's state is persisted. Default 5 seconds. */;
94
+ readonly syncIntervalMs?: number;
95
+ /**
96
+ * A home to start every session home from: whatever setup installed
97
+ * there (plugins, mods, settings, skills) is in each session's home. The
98
+ * session files under `stateDirs` are then restored on top. Default: none.
99
+ */
100
+ readonly skeleton?: string;
101
+ /**
102
+ * Run the CLI as this user, and give it its home. For a daemon running
103
+ * as root: Claude Code, for one, refuses to skip permission prompts as
104
+ * root. Default: the daemon's own user.
105
+ */
106
+ readonly user?: {
107
+ readonly uid: number;
108
+ readonly gid: number;
109
+ };
110
+ };
111
+ /**
112
+ * An adapter for an agent CLI.
113
+ *
114
+ * @param options - The CLI's command, parser, and state directories.
115
+ * @returns The adapter.
116
+ *
117
+ * @experimental The API may change before it stabilizes.
118
+ */
119
+ declare function cliAdapter(options: CliAdapterOptions): ContainerAdapter;
120
+ //#endregion
121
+ //#region src/harness/container/runtime/presets/claude-code.d.ts
122
+ /** The Claude Code preset's description, for `cliAdapter`. */
123
+ declare const claudeCodeCli: CliAdapterOptions;
124
+ //#endregion
125
+ //#region src/harness/container/runtime/presets/codex.d.ts
126
+ /** The Codex preset's description, for `cliAdapter`. */
127
+ declare const codexCli: CliAdapterOptions;
128
+ //#endregion
129
+ export {
130
+ type CliAdapterOptions,
131
+ type CliCommand,
132
+ type CliParser,
133
+ type CliState,
134
+ type CliTurn,
135
+ type CliUpdate,
136
+ type DaemonServer,
137
+ type ServeOptions,
138
+ claudeCodeCli,
139
+ cliAdapter,
140
+ codexCli,
141
+ serve,
142
+ serveFromEnv
143
+ };
144
+ //# sourceMappingURL=index.d.ts.map