humanish 0.107.0 → 0.108.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 (521) hide show
  1. package/ARCHITECTURE.md +22 -17
  2. package/CHANGELOG.md +14 -0
  3. package/CONTEXT.md +51 -44
  4. package/README.md +145 -172
  5. package/SECURITY.md +16 -26
  6. package/TELEMETRY.md +8 -6
  7. package/dist/actors/affordance.d.ts +4 -4
  8. package/dist/actors/affordance.js +12 -12
  9. package/dist/actors/agent-session.d.ts +2 -2
  10. package/dist/actors/agent-session.js +7 -7
  11. package/dist/actors/codex/app-server-actor-trace.d.ts +1 -1
  12. package/dist/actors/codex/app-server-actor-trace.js +1 -1
  13. package/dist/actors/codex/app-server-ui.js +1 -1
  14. package/dist/actors/codex/codex-admission.d.ts +91 -0
  15. package/dist/actors/codex/codex-admission.js +150 -0
  16. package/dist/actors/codex/restricted-executable.d.ts +4 -4
  17. package/dist/actors/codex/restricted-executable.js +8 -8
  18. package/dist/actors/codex/restricted-launch.d.ts +2 -1
  19. package/dist/actors/codex/restricted-launch.js +1 -1
  20. package/dist/actors/codex/restricted-participant.js +8 -6
  21. package/dist/actors/codex/restricted-policy.d.ts +2 -2
  22. package/dist/actors/codex/restricted-policy.js +2 -2
  23. package/dist/actors/codex/restricted-session.d.ts +2 -2
  24. package/dist/actors/codex/restricted-session.js +10 -5
  25. package/dist/actors/computer-use/actor.d.ts +16 -16
  26. package/dist/actors/computer-use/actor.js +2 -2
  27. package/dist/actors/computer-use/admission-limit.d.ts +1 -1
  28. package/dist/actors/computer-use/admission-limit.js +1 -1
  29. package/dist/actors/computer-use/loop/actions.d.ts +3 -3
  30. package/dist/actors/computer-use/loop/actions.js +10 -10
  31. package/dist/actors/computer-use/loop/backstop.d.ts +3 -3
  32. package/dist/actors/computer-use/loop/backstop.js +14 -12
  33. package/dist/actors/computer-use/loop/ending.d.ts +5 -5
  34. package/dist/actors/computer-use/loop/ending.js +7 -7
  35. package/dist/actors/computer-use/loop/observation.d.ts +2 -2
  36. package/dist/actors/computer-use/loop/observation.js +9 -9
  37. package/dist/actors/computer-use/loop/provider-call.d.ts +1 -1
  38. package/dist/actors/computer-use/loop/provider-call.js +1 -1
  39. package/dist/actors/computer-use/loop/session.js +3 -3
  40. package/dist/actors/computer-use/loop/spend.d.ts +1 -1
  41. package/dist/actors/computer-use/loop/spend.js +1 -1
  42. package/dist/actors/computer-use/loop/trace.js +9 -8
  43. package/dist/actors/computer-use/loop/types.d.ts +25 -23
  44. package/dist/actors/computer-use/loop/usage.js +2 -2
  45. package/dist/actors/computer-use/openai-context.d.ts +37 -0
  46. package/dist/actors/computer-use/openai-context.js +214 -0
  47. package/dist/actors/computer-use/openai-provider.d.ts +11 -8
  48. package/dist/actors/computer-use/openai-provider.js +45 -34
  49. package/dist/actors/computer-use/openai-requests.d.ts +36 -10
  50. package/dist/actors/computer-use/openai-requests.js +82 -15
  51. package/dist/actors/computer-use/openai-wire.d.ts +19 -7
  52. package/dist/actors/computer-use/openai-wire.js +36 -34
  53. package/dist/actors/contract.d.ts +78 -43
  54. package/dist/actors/contract.js +29 -23
  55. package/dist/actors/local-agent/claude-session.d.ts +1 -1
  56. package/dist/actors/local-agent/claude-session.js +10 -9
  57. package/dist/actors/local-agent/cli.d.ts +8 -6
  58. package/dist/actors/local-agent/cli.js +24 -28
  59. package/dist/actors/local-agent/readiness.d.ts +2 -2
  60. package/dist/actors/local-agent/readiness.js +4 -4
  61. package/dist/actors/reasoning-effort.js +6 -6
  62. package/dist/actors/registry.d.ts +10 -10
  63. package/dist/actors/registry.js +18 -17
  64. package/dist/actors/scripted-browser/actor.d.ts +8 -8
  65. package/dist/actors/scripted-browser/actor.js +16 -16
  66. package/dist/actors/scripted-browser/browser-command.js +1 -1
  67. package/dist/actors/scripted-browser/steps.js +1 -1
  68. package/dist/actors/scripted-browser/types.d.ts +1 -1
  69. package/dist/actors/stop-conditions.d.ts +1 -1
  70. package/dist/analysis/codex-config.d.ts +6 -2
  71. package/dist/analysis/codex-config.js +22 -14
  72. package/dist/analysis/service.js +5 -5
  73. package/dist/cli/commands/analyze.js +19 -16
  74. package/dist/cli/commands/codex.js +9 -9
  75. package/dist/cli/commands/comms.js +54 -33
  76. package/dist/cli/commands/feedback.js +20 -21
  77. package/dist/cli/commands/lab-format.d.ts +5 -4
  78. package/dist/cli/commands/lab-format.js +35 -23
  79. package/dist/cli/commands/lab-route-computer-use.js +6 -7
  80. package/dist/cli/commands/lab-route-preview.js +4 -3
  81. package/dist/cli/commands/lab-route-shared-world.js +3 -3
  82. package/dist/cli/commands/lab-run.js +10 -11
  83. package/dist/cli/commands/lab-scorer.d.ts +2 -2
  84. package/dist/cli/commands/lab-scorer.js +1 -1
  85. package/dist/cli/commands/migrate.d.ts +4 -0
  86. package/dist/cli/commands/migrate.js +65 -0
  87. package/dist/cli/commands/observe.js +147 -108
  88. package/dist/cli/commands/run-command.d.ts +10 -0
  89. package/dist/cli/commands/run-command.js +85 -0
  90. package/dist/cli/commands/runs.js +137 -138
  91. package/dist/cli/commands/setup.d.ts +2 -2
  92. package/dist/cli/commands/setup.js +26 -21
  93. package/dist/cli/commands/study.d.ts +3 -0
  94. package/dist/cli/commands/study.js +182 -0
  95. package/dist/cli/commands/tui.d.ts +4 -4
  96. package/dist/cli/commands/tui.js +21 -21
  97. package/dist/cli/commands/watch.js +60 -75
  98. package/dist/cli/deprecations.d.ts +18 -0
  99. package/dist/cli/deprecations.js +48 -0
  100. package/dist/cli/doctor.d.ts +15 -5
  101. package/dist/cli/doctor.js +103 -48
  102. package/dist/cli/first-run-path.d.ts +12 -10
  103. package/dist/cli/first-run-path.js +30 -28
  104. package/dist/cli/io.d.ts +41 -6
  105. package/dist/cli/io.js +97 -22
  106. package/dist/cli/observer-follow.d.ts +2 -2
  107. package/dist/cli/observer-follow.js +5 -6
  108. package/dist/cli/orientation.d.ts +6 -3
  109. package/dist/cli/orientation.js +43 -39
  110. package/dist/cli/product-sentence.d.ts +6 -0
  111. package/dist/cli/product-sentence.js +6 -0
  112. package/dist/cli/program.d.ts +6 -1
  113. package/dist/cli/program.js +109 -40
  114. package/dist/cli/telemetry.d.ts +15 -15
  115. package/dist/cli/telemetry.js +48 -40
  116. package/dist/cli.js +1 -1
  117. package/dist/comms/capture-surface.d.ts +13 -12
  118. package/dist/comms/capture-surface.js +23 -22
  119. package/dist/comms/catch-host.d.ts +7 -7
  120. package/dist/comms/catch-host.js +14 -14
  121. package/dist/comms/email-catch.d.ts +3 -3
  122. package/dist/comms/email-catch.js +8 -8
  123. package/dist/comms/external-evidence.js +2 -2
  124. package/dist/comms/extract.js +2 -2
  125. package/dist/comms/fake-inbox.d.ts +2 -2
  126. package/dist/comms/fake-inbox.js +2 -2
  127. package/dist/comms/receiving-render.d.ts +1 -1
  128. package/dist/comms/receiving-render.js +2 -2
  129. package/dist/comms/sandbox-catch-script.d.ts +6 -6
  130. package/dist/comms/sandbox-catch-script.js +6 -6
  131. package/dist/comms/sandbox-catch.d.ts +36 -37
  132. package/dist/comms/sandbox-catch.js +34 -35
  133. package/dist/comms/setup.js +42 -8
  134. package/dist/comms/thread-evidence.d.ts +1 -1
  135. package/dist/comms/thread-evidence.js +6 -6
  136. package/dist/comms/types.d.ts +6 -6
  137. package/dist/comms/types.js +3 -3
  138. package/dist/evidence/frame-signature.d.ts +1 -1
  139. package/dist/evidence/frame-signature.js +4 -4
  140. package/dist/evidence/redaction.d.ts +3 -3
  141. package/dist/evidence/redaction.js +4 -4
  142. package/dist/feedback/draft.js +36 -78
  143. package/dist/feedback/export-bundle.js +1 -1
  144. package/dist/feedback/export.d.ts +5 -1
  145. package/dist/feedback/export.js +7 -8
  146. package/dist/feedback/feedback.d.ts +2 -2
  147. package/dist/feedback/feedback.js +21 -3
  148. package/dist/guest/chromium-text.js +2 -2
  149. package/dist/guest/desktop-native.d.ts +1 -1
  150. package/dist/guest/runtime.js +1 -1
  151. package/dist/index.d.ts +12 -10
  152. package/dist/index.js +8 -6
  153. package/dist/keys/key-resolution.d.ts +5 -5
  154. package/dist/keys/key-resolution.js +23 -23
  155. package/dist/lab/adapter-extension.d.ts +7 -7
  156. package/dist/lab/adapter-extension.js +13 -36
  157. package/dist/lab/adapter-scorer-loader.d.ts +7 -7
  158. package/dist/lab/adapter-scorer-loader.js +32 -32
  159. package/dist/lab/composition-rules.js +42 -42
  160. package/dist/lab/config.js +65 -25
  161. package/dist/lab/deprecated-fields.d.ts +10 -0
  162. package/dist/lab/deprecated-fields.js +24 -0
  163. package/dist/lab/device-presets.d.ts +8 -8
  164. package/dist/lab/device-presets.js +11 -11
  165. package/dist/lab/discover.d.ts +13 -9
  166. package/dist/lab/discover.js +117 -57
  167. package/dist/lab/doctor.d.ts +10 -3
  168. package/dist/lab/doctor.js +47 -9
  169. package/dist/lab/init-templates.js +147 -147
  170. package/dist/lab/init.d.ts +1 -1
  171. package/dist/lab/init.js +41 -9
  172. package/dist/lab/keys.d.ts +2 -0
  173. package/dist/lab/keys.js +42 -8
  174. package/dist/lab/lab-deps.d.ts +7 -12
  175. package/dist/lab/parse/actors.js +9 -9
  176. package/dist/lab/parse/comms.js +5 -5
  177. package/dist/lab/parse/execution.js +13 -13
  178. package/dist/lab/parse/study-v3.d.ts +23 -0
  179. package/dist/lab/parse/study-v3.js +259 -0
  180. package/dist/lab/parse/subject-state.d.ts +7 -7
  181. package/dist/lab/parse/subject-state.js +16 -16
  182. package/dist/lab/parse/subject.js +28 -28
  183. package/dist/lab/parse/values.d.ts +1 -1
  184. package/dist/lab/parse/values.js +3 -3
  185. package/dist/lab/persona-resolve.d.ts +4 -4
  186. package/dist/lab/persona-resolve.js +4 -4
  187. package/dist/lab/plan-participants.d.ts +2 -2
  188. package/dist/lab/plan-types.d.ts +4 -4
  189. package/dist/lab/plan.d.ts +1 -7
  190. package/dist/lab/plan.js +10 -41
  191. package/dist/lab/preflight-probes.js +11 -11
  192. package/dist/lab/preflight-result.d.ts +2 -1
  193. package/dist/lab/preflight-result.js +5 -4
  194. package/dist/lab/preflight.d.ts +7 -5
  195. package/dist/lab/preflight.js +5 -5
  196. package/dist/lab/routing.d.ts +31 -25
  197. package/dist/lab/routing.js +60 -29
  198. package/dist/lab/run-lab-events.d.ts +0 -3
  199. package/dist/lab/run-lab-events.js +0 -6
  200. package/dist/lab/run-lab-homes.d.ts +22 -10
  201. package/dist/lab/run-lab-homes.js +5 -1
  202. package/dist/lab/run-lab-options.d.ts +1 -1
  203. package/dist/lab/run-lab-options.js +16 -13
  204. package/dist/lab/summary.d.ts +7 -6
  205. package/dist/lab/summary.js +10 -10
  206. package/dist/lab/tasks.d.ts +15 -15
  207. package/dist/lab/tasks.js +14 -14
  208. package/dist/lab/types.d.ts +101 -95
  209. package/dist/lab/types.js +2 -0
  210. package/dist/lab/validation.d.ts +13 -13
  211. package/dist/lab/validation.js +44 -42
  212. package/dist/lab/warnings.d.ts +10 -0
  213. package/dist/lab/warnings.js +61 -33
  214. package/dist/library-aliases.d.ts +56 -0
  215. package/dist/library-aliases.js +22 -0
  216. package/dist/observer/artifact.d.ts +1 -1
  217. package/dist/observer/artifact.js +6 -6
  218. package/dist/observer/data.d.ts +6 -6
  219. package/dist/observer/data.js +5 -4
  220. package/dist/observer/exposure.d.ts +1 -1
  221. package/dist/observer/exposure.js +11 -11
  222. package/dist/observer/http.js +1 -1
  223. package/dist/observer/library.d.ts +1 -1
  224. package/dist/observer/library.js +4 -2
  225. package/dist/observer/listen.js +5 -4
  226. package/dist/observer/render.d.ts +1 -1
  227. package/dist/observer/render.js +10 -5
  228. package/dist/observer/run-routes.d.ts +3 -3
  229. package/dist/observer/run-routes.js +1 -1
  230. package/dist/observer/serve.js +7 -3
  231. package/dist/observer/tunnel.js +1 -1
  232. package/dist/observer-app.html +4 -4
  233. package/dist/routes/computer-use/bundle-parts.d.ts +9 -9
  234. package/dist/routes/computer-use/bundle-parts.js +15 -15
  235. package/dist/routes/computer-use/bundle.js +3 -3
  236. package/dist/routes/computer-use/e2b-desktop/comms.d.ts +1 -1
  237. package/dist/routes/computer-use/e2b-desktop/comms.js +14 -14
  238. package/dist/routes/computer-use/e2b-desktop/desktop.js +4 -4
  239. package/dist/routes/computer-use/e2b-desktop/fidelity.d.ts +4 -3
  240. package/dist/routes/computer-use/e2b-desktop/fidelity.js +11 -10
  241. package/dist/routes/computer-use/e2b-desktop/prepare.js +7 -7
  242. package/dist/routes/computer-use/e2b-desktop/start.js +9 -8
  243. package/dist/routes/computer-use/e2b-desktop/teardown.js +5 -4
  244. package/dist/routes/computer-use/external-comms.d.ts +1 -1
  245. package/dist/routes/computer-use/external-comms.js +1 -1
  246. package/dist/routes/computer-use/fanout-bundle.js +18 -18
  247. package/dist/routes/computer-use/fanout-records.js +10 -11
  248. package/dist/routes/computer-use/live-flush.d.ts +1 -1
  249. package/dist/routes/computer-use/live-flush.js +6 -6
  250. package/dist/routes/computer-use/live-phase.d.ts +4 -2
  251. package/dist/routes/computer-use/live-phase.js +6 -6
  252. package/dist/routes/computer-use/local-vm.js +1 -1
  253. package/dist/routes/computer-use/participant-desktop.d.ts +4 -4
  254. package/dist/routes/computer-use/participant-desktop.js +4 -4
  255. package/dist/routes/computer-use/participant-execution.d.ts +4 -4
  256. package/dist/routes/computer-use/participant-execution.js +9 -9
  257. package/dist/routes/computer-use/participant-model.d.ts +6 -0
  258. package/dist/routes/computer-use/participant-model.js +31 -13
  259. package/dist/routes/computer-use/participant-prompt.d.ts +11 -11
  260. package/dist/routes/computer-use/participant-prompt.js +6 -6
  261. package/dist/routes/computer-use/participant-runs.d.ts +7 -7
  262. package/dist/routes/computer-use/participant-runs.js +13 -13
  263. package/dist/routes/computer-use/plan.js +22 -22
  264. package/dist/routes/computer-use/preflight.js +21 -21
  265. package/dist/routes/computer-use/rerun-selection.js +1 -1
  266. package/dist/routes/computer-use/result.js +11 -11
  267. package/dist/routes/computer-use/route.d.ts +2 -1
  268. package/dist/routes/computer-use/route.js +15 -14
  269. package/dist/routes/computer-use/self-report.d.ts +7 -7
  270. package/dist/routes/computer-use/self-report.js +31 -31
  271. package/dist/routes/computer-use/setup.d.ts +1 -1
  272. package/dist/routes/computer-use/setup.js +17 -18
  273. package/dist/routes/computer-use/single-bundle.d.ts +7 -7
  274. package/dist/routes/computer-use/single-bundle.js +28 -30
  275. package/dist/routes/computer-use/subject-projection.d.ts +1 -1
  276. package/dist/routes/computer-use/subject-projection.js +6 -6
  277. package/dist/routes/computer-use/types.d.ts +40 -42
  278. package/dist/routes/computer-use/types.js +10 -10
  279. package/dist/routes/preview.d.ts +8 -2
  280. package/dist/routes/preview.js +8 -4
  281. package/dist/routes/scripted/bundle.d.ts +2 -2
  282. package/dist/routes/scripted/bundle.js +13 -12
  283. package/dist/routes/scripted/plan.d.ts +1 -1
  284. package/dist/routes/scripted/plan.js +9 -9
  285. package/dist/routes/scripted/result.js +5 -5
  286. package/dist/routes/scripted/route.js +5 -6
  287. package/dist/routes/scripted/scenario.js +2 -2
  288. package/dist/routes/scripted/setup.js +7 -7
  289. package/dist/routes/scripted/subject.js +1 -1
  290. package/dist/routes/scripted/surface-records.js +3 -3
  291. package/dist/routes/scripted/types.d.ts +3 -5
  292. package/dist/routes/scripted/types.js +1 -1
  293. package/dist/routes/shared-world/bundle-records.js +9 -8
  294. package/dist/routes/shared-world/bundle.d.ts +5 -5
  295. package/dist/routes/shared-world/bundle.js +40 -38
  296. package/dist/routes/shared-world/checkpoints.d.ts +1 -1
  297. package/dist/routes/shared-world/checkpoints.js +1 -1
  298. package/dist/routes/shared-world/comms.d.ts +5 -5
  299. package/dist/routes/shared-world/comms.js +14 -14
  300. package/dist/routes/shared-world/external-public.d.ts +4 -3
  301. package/dist/routes/shared-world/external-public.js +16 -12
  302. package/dist/routes/shared-world/handoff.d.ts +7 -6
  303. package/dist/routes/shared-world/handoff.js +65 -57
  304. package/dist/routes/shared-world/lobby-code.d.ts +2 -2
  305. package/dist/routes/shared-world/lobby-code.js +9 -9
  306. package/dist/routes/shared-world/participant-specs.d.ts +7 -6
  307. package/dist/routes/shared-world/participant-specs.js +31 -24
  308. package/dist/routes/shared-world/plan.js +7 -7
  309. package/dist/routes/shared-world/provenance.d.ts +2 -2
  310. package/dist/routes/shared-world/provenance.js +2 -2
  311. package/dist/routes/shared-world/provisioned.js +14 -13
  312. package/dist/routes/shared-world/result.js +20 -21
  313. package/dist/routes/shared-world/route.js +23 -22
  314. package/dist/routes/shared-world/setup.d.ts +3 -3
  315. package/dist/routes/shared-world/setup.js +4 -4
  316. package/dist/routes/shared-world/types.d.ts +30 -28
  317. package/dist/routes/shared-world/types.js +4 -4
  318. package/dist/routes/terminal/adapter.d.ts +3 -3
  319. package/dist/routes/terminal/adapter.js +5 -5
  320. package/dist/routes/terminal/bundle.d.ts +3 -3
  321. package/dist/routes/terminal/bundle.js +22 -21
  322. package/dist/routes/terminal/credentials.d.ts +4 -4
  323. package/dist/routes/terminal/credentials.js +7 -7
  324. package/dist/routes/terminal/dry-run.js +4 -4
  325. package/dist/routes/terminal/encoding.js +2 -2
  326. package/dist/routes/terminal/ledger.d.ts +3 -3
  327. package/dist/routes/terminal/ledger.js +14 -14
  328. package/dist/routes/terminal/live-finish.js +3 -3
  329. package/dist/routes/terminal/live-sandbox.js +12 -13
  330. package/dist/routes/terminal/persona.js +1 -1
  331. package/dist/routes/terminal/plan.js +11 -11
  332. package/dist/routes/terminal/recorder.js +2 -2
  333. package/dist/routes/terminal/result.js +8 -8
  334. package/dist/routes/terminal/route.js +6 -7
  335. package/dist/routes/terminal/sandbox.d.ts +1 -1
  336. package/dist/routes/terminal/sandbox.js +1 -1
  337. package/dist/routes/terminal/session.js +8 -7
  338. package/dist/routes/terminal/token-usage.d.ts +1 -1
  339. package/dist/routes/terminal/token-usage.js +7 -8
  340. package/dist/routes/terminal/trace.d.ts +2 -2
  341. package/dist/routes/terminal/trace.js +2 -2
  342. package/dist/routes/terminal/types.d.ts +26 -28
  343. package/dist/routes/terminal/types.js +3 -3
  344. package/dist/run/bundle-shape.js +3 -3
  345. package/dist/run/bundle.d.ts +46 -46
  346. package/dist/run/bundle.js +2 -1
  347. package/dist/run/cost-summary.js +3 -3
  348. package/dist/run/costs.js +7 -1
  349. package/dist/run/detail.d.ts +6 -6
  350. package/dist/run/detail.js +4 -4
  351. package/dist/run/dry-run-inputs.js +1 -1
  352. package/dist/run/dry-run.js +18 -18
  353. package/dist/run/judge.d.ts +19 -13
  354. package/dist/run/judge.js +18 -8
  355. package/dist/run/paths.d.ts +1 -1
  356. package/dist/run/paths.js +1 -1
  357. package/dist/run/pricing.d.ts +11 -6
  358. package/dist/run/pricing.js +20 -13
  359. package/dist/run/projection.d.ts +14 -14
  360. package/dist/run/projection.js +15 -15
  361. package/dist/run/reclaim.js +2 -2
  362. package/dist/run/results.d.ts +5 -5
  363. package/dist/run/run-index.d.ts +8 -6
  364. package/dist/run/run-index.js +15 -16
  365. package/dist/run/run-not-found.d.ts +5 -0
  366. package/dist/run/run-not-found.js +15 -0
  367. package/dist/run/run.d.ts +5 -4
  368. package/dist/run/run.js +1 -1
  369. package/dist/run/sandbox-receipts.d.ts +2 -2
  370. package/dist/run/sandbox-receipts.js +3 -3
  371. package/dist/run/shared-world-evidence.d.ts +36 -35
  372. package/dist/run/shared-world-evidence.js +4 -4
  373. package/dist/run/shared-world-shape.d.ts +1 -1
  374. package/dist/run/shared-world-shape.js +6 -6
  375. package/dist/run/stats.d.ts +12 -6
  376. package/dist/run/stats.js +116 -58
  377. package/dist/run/status.d.ts +8 -29
  378. package/dist/run/status.js +5 -27
  379. package/dist/run/stored-runs.js +2 -1
  380. package/dist/run/stream-shape.js +1 -1
  381. package/dist/run/streams.d.ts +6 -6
  382. package/dist/run/study-provenance.d.ts +47 -0
  383. package/dist/run/study-provenance.js +63 -0
  384. package/dist/run/study-result.d.ts +16 -0
  385. package/dist/run/study-result.js +9 -0
  386. package/dist/run/text.d.ts +2 -0
  387. package/dist/run/text.js +4 -0
  388. package/dist/run-lab.d.ts +7 -7
  389. package/dist/run-lab.js +1 -3
  390. package/dist/study/convert.d.ts +33 -0
  391. package/dist/study/convert.js +432 -0
  392. package/dist/study/field-paths.d.ts +12 -0
  393. package/dist/study/field-paths.js +126 -0
  394. package/dist/study/files.d.ts +26 -0
  395. package/dist/study/files.js +43 -0
  396. package/dist/study/migrate.d.ts +48 -0
  397. package/dist/study/migrate.js +408 -0
  398. package/dist/study/owned-files.d.ts +38 -0
  399. package/dist/study/owned-files.js +182 -0
  400. package/dist/subject/clone.d.ts +1 -1
  401. package/dist/subject/desktop-cli.d.ts +1 -1
  402. package/dist/subject/desktop-cli.js +2 -2
  403. package/dist/subject/local-tree-archive.js +1 -1
  404. package/dist/subject/local-tree.d.ts +1 -1
  405. package/dist/subject/node-bootstrap.js +1 -1
  406. package/dist/subject/runtime.js +8 -9
  407. package/dist/subject/serve.d.ts +1 -1
  408. package/dist/subject/serve.js +3 -3
  409. package/dist/subject/state.d.ts +1 -1
  410. package/dist/subject/steps.d.ts +5 -5
  411. package/dist/subject/steps.js +4 -4
  412. package/dist/substrates/command-failure.d.ts +3 -3
  413. package/dist/substrates/command-failure.js +3 -3
  414. package/dist/substrates/detached.d.ts +6 -6
  415. package/dist/substrates/detached.js +7 -7
  416. package/dist/substrates/e2b/cdp-probe.d.ts +9 -9
  417. package/dist/substrates/e2b/cdp-probe.js +14 -17
  418. package/dist/substrates/e2b/desktop-browser.d.ts +2 -2
  419. package/dist/substrates/e2b/desktop-browser.js +8 -8
  420. package/dist/substrates/e2b/desktop-cdp.d.ts +9 -9
  421. package/dist/substrates/e2b/desktop-cdp.js +8 -8
  422. package/dist/substrates/e2b/desktop-executor.d.ts +1 -1
  423. package/dist/substrates/e2b/desktop-executor.js +1 -1
  424. package/dist/substrates/e2b/desktop-geometry.d.ts +3 -3
  425. package/dist/substrates/e2b/desktop-geometry.js +7 -7
  426. package/dist/substrates/e2b/desktop-media.d.ts +1 -1
  427. package/dist/substrates/e2b/desktop-media.js +1 -1
  428. package/dist/substrates/e2b/desktop-screenshot-cleanup.d.ts +3 -3
  429. package/dist/substrates/e2b/desktop-screenshot-cleanup.js +3 -3
  430. package/dist/substrates/e2b/sandbox.d.ts +1 -1
  431. package/dist/substrates/e2b/sandbox.js +1 -1
  432. package/dist/substrates/e2b/sdk.d.ts +11 -11
  433. package/dist/substrates/e2b/sdk.js +6 -6
  434. package/dist/tui/actions.d.ts +1 -1
  435. package/dist/tui/actions.js +13 -13
  436. package/dist/tui/contract.d.ts +16 -16
  437. package/dist/tui/contract.js +10 -10
  438. package/dist/tui/launch.d.ts +4 -4
  439. package/dist/tui/launch.js +18 -19
  440. package/dist/tui/project.js +5 -5
  441. package/dist/tui-app.js +82 -82
  442. package/dist/verify/actor.d.ts +8 -8
  443. package/dist/verify/actor.js +36 -36
  444. package/dist/verify/artifacts.d.ts +2 -2
  445. package/dist/verify/artifacts.js +3 -3
  446. package/dist/verify/context-growth.d.ts +9 -0
  447. package/dist/verify/context-growth.js +62 -0
  448. package/dist/verify/costs.d.ts +6 -6
  449. package/dist/verify/costs.js +8 -8
  450. package/dist/verify/shared-world-concurrent.d.ts +2 -2
  451. package/dist/verify/shared-world-concurrent.js +79 -76
  452. package/dist/verify/shared-world.d.ts +2 -2
  453. package/dist/verify/shared-world.js +16 -16
  454. package/dist/verify/subject.d.ts +4 -4
  455. package/dist/verify/subject.js +18 -18
  456. package/dist/verify/verify.js +92 -43
  457. package/docs/README.md +25 -32
  458. package/docs/architecture/actor-contract.md +56 -87
  459. package/docs/architecture/desktop-sessions.md +7 -7
  460. package/docs/architecture/external-public-shared-world.md +61 -59
  461. package/docs/architecture/github-feedback-loop.md +1 -4
  462. package/docs/architecture/guest-desktop.md +2 -2
  463. package/docs/architecture/observer.md +34 -34
  464. package/docs/architecture/restricted-codex-analysis.md +34 -28
  465. package/docs/architecture/serve.md +34 -37
  466. package/docs/architecture/state-driven-executor.md +55 -58
  467. package/docs/architecture/task-protocol-support.md +5 -5
  468. package/docs/architecture/terminal-product-route.md +67 -107
  469. package/docs/contracts/README.md +24 -0
  470. package/docs/contracts/adapter-admission.md +3 -3
  471. package/docs/contracts/adapter-fixtures.md +2 -5
  472. package/docs/contracts/core.md +1 -3
  473. package/docs/contracts/errors.md +62 -0
  474. package/docs/contracts/feedback.md +8 -9
  475. package/docs/contracts/policy.md +7 -12
  476. package/docs/contracts/run-bundle.md +45 -44
  477. package/docs/contracts/schemas.md +421 -362
  478. package/docs/contracts/study-analysis.md +3 -3
  479. package/docs/contracts/study-costs.md +11 -7
  480. package/docs/decisions/0001-run-bundle-is-the-source-of-truth.md +1 -1
  481. package/docs/decisions/0002-observer-is-one-self-contained-file.md +2 -2
  482. package/docs/decisions/0003-contained-paths-and-cleanup-authority.md +3 -3
  483. package/docs/principles/actor-fidelity.md +4 -4
  484. package/docs/principles/engineering.md +3 -3
  485. package/docs/principles/invariants-and-defaults.md +38 -38
  486. package/docs/principles/self-driving-harness.md +1 -5
  487. package/docs/principles/three-roles.md +1 -1
  488. package/docs/product/automatic-analysis.md +7 -7
  489. package/examples/participant/README.md +5 -5
  490. package/examples/participant/run.mjs +11 -10
  491. package/examples/scorer/README.md +3 -3
  492. package/examples/scorer/run.mjs +11 -12
  493. package/package.json +16 -17
  494. package/skills/humanish/SKILL.md +60 -58
  495. package/skills/humanish/agents/openai.yaml +1 -1
  496. package/AGENTS.md +0 -99
  497. package/CONTRIBUTING.md +0 -148
  498. package/dist/actors/codex/qualified-versions.d.ts +0 -72
  499. package/dist/actors/codex/qualified-versions.js +0 -132
  500. package/dist/cli/commands/lab.d.ts +0 -3
  501. package/dist/cli/commands/lab.js +0 -199
  502. package/dist/cli/renamed-options.d.ts +0 -11
  503. package/dist/cli/renamed-options.js +0 -18
  504. package/dist/observer/static.d.ts +0 -39
  505. package/dist/observer/static.js +0 -369
  506. package/docs/architecture/comms-inbox.md +0 -122
  507. package/docs/architecture/desktop-recording.md +0 -80
  508. package/docs/architecture/local-browser-runtime.md +0 -178
  509. package/docs/architecture/observer-review.md +0 -144
  510. package/docs/architecture/participant-media.md +0 -90
  511. package/docs/architecture/project-layout.md +0 -62
  512. package/docs/architecture/real-email-receiving.md +0 -136
  513. package/docs/assets/humanish-drawdb-hero.png +0 -0
  514. package/docs/assets/humanish-observer-hero.png +0 -0
  515. package/docs/goals/current.md +0 -207
  516. package/docs/product/lobby-trivia-3player-external-public.md +0 -77
  517. package/docs/product/open-source-install-experience.md +0 -240
  518. package/docs/ramp/README.md +0 -295
  519. package/docs/release/open-source-readiness.md +0 -222
  520. package/docs/release/public-readiness-standard.md +0 -210
  521. package/docs/roadmap/world-class-open-source-v0.md +0 -311
@@ -20,7 +20,7 @@ export class TraceRecorder {
20
20
  constructor(now) {
21
21
  this.now = now;
22
22
  }
23
- // The ONE recording choke point (#441): every trace item is stamped `at` from the
23
+ // The single recording choke point: every trace item is stamped `at` from the
24
24
  // loop's injected clock as it is recorded, so timed playback reads recorded facts
25
25
  // (deterministic in tests via the injected `now`). The id is allocated before the body is
26
26
  // built, so a body that fails to build (a redaction error) still consumes its id.
@@ -40,7 +40,7 @@ export function statusForCompletionReason(reason) {
40
40
  case "turn_completed": // turn_completed is a Codex reason; this loop emits goal_satisfied
41
41
  return "passed";
42
42
  // A session that ran out of time or budget did not reach its goal, whatever it achieved along
43
- // the way. Calling that `passed` is how a truncated study came to be reported as a green one —
43
+ // the way. Calling that `passed` is how a truncated study came to be reported as a green one,
44
44
  // and why "raise the timeout" kept landing on the operator instead of on the tool. This switch
45
45
  // is exhaustive with no default, so a new completion reason forces a compile error here.
46
46
  case "budget_reached":
@@ -51,7 +51,7 @@ export function statusForCompletionReason(reason) {
51
51
  return "blocked";
52
52
  // A participant who stopped trying is the single most valuable thing a usability study
53
53
  // produces. Recording it as `failed` said the instrument broke, which is a different claim and
54
- // a false one — see docs/principles/three-roles.md.
54
+ // a false one; see docs/principles/three-roles.md.
55
55
  case "gave_up":
56
56
  return "abandoned";
57
57
  // Only the harness failing is a harness failure.
@@ -77,12 +77,12 @@ export function loopResult(session, stop, debrief) {
77
77
  ? "no screenshots captured"
78
78
  : session.redactScreenshots
79
79
  ? `${counts.screenshots} screenshot(s) redacted to blurred thumbnails via RedactionHooks`
80
- : `${counts.screenshots} full-fidelity screenshot(s) retained for local use — NOT redacted for publishing; set redactScreenshots to blur a share-as-is bundle`;
81
- // Self-describing artifact (invariant 6): when any observation carried structured app state,
80
+ : `${counts.screenshots} unblurred screenshot(s) kept for local use and not redacted for publishing; set redactScreenshots to blur screenshots in a bundle you plan to share`;
81
+ // Self-describing artifact: when any observation carried structured app state,
82
82
  // the trace says how the loop handled it: it fed progress and task checks and was not written to
83
83
  // the trace. The appState itself never appears in this bundle.
84
84
  const notes = session.observedAppState
85
- ? `${screenshotNote}. App state was observed each turn to drive progress detection (a state-driven executor) and was NOT written to the trace — it is a runtime-only progress input, never persisted as evidence in this slice.`
85
+ ? `${screenshotNote}. App state was read each turn to detect progress (an in-process executor) and was not written to the trace: it is used only while the run is live and is never stored as evidence.`
86
86
  : screenshotNote;
87
87
  const tokenUsage = usage.tokenUsage();
88
88
  const trace = {
@@ -90,6 +90,7 @@ export function loopResult(session, stop, debrief) {
90
90
  provider: provider.id,
91
91
  ...usage.liveMetadata(),
92
92
  ...(provider.version === undefined ? {} : { providerVersion: provider.version }),
93
+ ...(provider.conversation === undefined ? {} : { conversation: provider.conversation }),
93
94
  protocol: "cua-loop",
94
95
  lane: "computer-use",
95
96
  persona: settings.persona,
@@ -130,8 +131,8 @@ export function loopResult(session, stop, debrief) {
130
131
  ...(usage.interactionUsageIncomplete(session.capDeclared)
131
132
  ? { interactionUsageIncomplete: true }
132
133
  : {}),
133
- // The funnel is present exactly when a protocol was declared — including a session that ended
134
- // on turn 0, whose funnel honestly reads 0/N. No tasks declared means no funnel, not an empty one.
134
+ // The funnel is present exactly when a protocol was declared, including a session that ended
135
+ // on turn 0, whose funnel reads 0/N. No tasks declared means no funnel, not an empty one.
135
136
  ...(session.taskTracker === undefined ? {} : { taskFunnel: session.taskTracker.funnel() }),
136
137
  ...(tokenUsage === undefined ? {} : { tokenUsage }),
137
138
  capabilities: provider.capabilities,
@@ -1,5 +1,5 @@
1
1
  import type { HeardSpeech } from "../speech.js";
2
- import type { ActorCapabilities, ActorExecutionProfile, ActorPersonaRef, ActorSessionResult, ActorTokenUsage, ActorTrace, ActorTraceItem, ParticipantClosingReport, ParticipantDeclaredOutcome, ProviderRequestReceipt } from "../../contract.js";
2
+ import type { ActorCapabilities, ActorConversation, ActorExecutionProfile, ActorPersonaRef, ActorSessionResult, ActorTokenUsage, ActorTrace, ActorTraceItem, ParticipantClosingReport, ParticipantDeclaredOutcome, ProviderRequestReceipt } from "../../contract.js";
3
3
  import type { RedactionHooks } from "../../../evidence/redaction.js";
4
4
  import type { DwellWindow, StopWhen } from "../../stop-conditions.js";
5
5
  import type { LabTask } from "../../../lab/tasks.js";
@@ -93,7 +93,7 @@ export interface CuaObservation {
93
93
  url?: string;
94
94
  /**
95
95
  * The page's vertical scroll offset (window.scrollY), when the executor can read it. Scroll
96
- * position is state (#393): inside a scroll-pinned section the viewport stays visually fixed
96
+ * position is state: inside a scroll-pinned section the viewport stays visually fixed
97
97
  * while the participant advances, so the frame hash alone reads "no change". Runtime-only like
98
98
  * url and text: it feeds the progress key, bucketed, and is never persisted.
99
99
  */
@@ -182,7 +182,7 @@ export interface CuaTurn {
182
182
  done: boolean;
183
183
  /** Explicit provider interruption, independent of actions or participant intent. */
184
184
  interruption?: "output_limit" | "token_limit" | "incomplete" | "unexpected_status";
185
- /** The participant's own word for how it ended, when its reply format carries one (#570). */
185
+ /** The participant's own word for how it ended, when its reply format carries one. */
186
186
  outcome?: ParticipantDeclaredOutcome;
187
187
  /** Present only for an accepted structured closing account. */
188
188
  closingReport?: ParticipantClosingReport;
@@ -193,11 +193,13 @@ export interface CuaProvider {
193
193
  readonly requestPolicy?: "fail_closed";
194
194
  readonly executionProfile?: ActorExecutionProfile | undefined;
195
195
  readonly historyTurnsOmitted?: number;
196
+ /** How the conversation was carried between requests, for the trace. */
197
+ readonly conversation?: ActorConversation;
196
198
  readonly id: string;
197
199
  readonly version?: string | undefined;
198
200
  /**
199
201
  * The request settings this provider will actually send, for the trace to record. `version` says
200
- * WHICH model; this says how it was asked to run. Optional: a provider with no such settings
202
+ * which model; this says how it was asked to run. Optional: a provider with no such settings
201
203
  * records none, and absence stays absence rather than becoming a default nobody chose.
202
204
  */
203
205
  readonly modelSettings?: {
@@ -259,13 +261,13 @@ export interface CuaLoopOptions {
259
261
  /** Hard wall-clock runaway guard. The only count-free hard stop. */
260
262
  timeoutMs: number;
261
263
  /**
262
- * Per-attempt bound on the provider call (#469), so a hung request is told apart from a
264
+ * Per-attempt bound on the provider call, so a hung request is told apart from a
263
265
  * participant still thinking. A stalled turn is retried once with a notice; a second stall ends
264
266
  * the participant as harness_error.
265
267
  */
266
268
  turnTimeoutMs?: number;
267
269
  /**
268
- * Per-call bound on observation work (#480): executor.observe() and the idle actions (`wait`,
270
+ * Per-call bound on observation work: executor.observe() and the idle actions (`wait`,
269
271
  * `screenshot`), whose only job is to look. A `wait` adds its own ms to the bound. A stalled
270
272
  * observe is retried once; a stalled idle action is skipped with a notice.
271
273
  */
@@ -288,19 +290,19 @@ export interface CuaLoopOptions {
288
290
  */
289
291
  acknowledgeSafetyChecks?: (checks: CuaSafetyCheck[]) => CuaSafetyCheck[] | null;
290
292
  /**
291
- * Redact (blur+downscale) persisted screenshots. Default FALSE — full-fidelity frames are
292
- * retained, because the common case is a developer watching a sim of their OWN app locally
293
+ * Redact (blur+downscale) persisted screenshots. Default `false`: full-fidelity frames are
294
+ * retained, because the common case is a developer watching a sim of their own app locally
293
295
  * (gitignored .humanish), where blur destroys the core deliverable. Set true for unowned
294
- * subjects or when the bundle is meant to be shared as-is. The frame sent to the PROVIDER is
296
+ * subjects or when the bundle is meant to be shared as-is. The frame sent to the provider is
295
297
  * always full-resolution regardless (the model must see the screen to act); this flag only
296
- * governs what is PERSISTED. Publish-safety belongs at the publish boundary (commit scan / redactScreenshots), not capture.
298
+ * governs what is persisted. Publish-safety belongs at the publish boundary (commit scan / redactScreenshots), not capture.
297
299
  */
298
300
  redactScreenshots?: boolean;
299
301
  /**
300
- * Extra literal scrub for KNOWN provisioned values (which have no detectable "shape", so
301
- * pattern redaction cannot catch them), composed BEFORE redactText on every model-authored
302
+ * Extra literal scrub for known provisioned values (which have no detectable "shape", so
303
+ * pattern redaction cannot catch them), composed before redactText on every model-authored
302
304
  * text item (reasoning, message, completion summary) and the loop error. The lab passes the
303
- * env-value scrubber here so a value the MODEL narrates can never land raw in the trace.
305
+ * env-value scrubber here so a value the model narrates can never land raw in the trace.
304
306
  * Default: identity (the loop is shape-only on its own).
305
307
  */
306
308
  scrubText?: (text: string) => string;
@@ -313,7 +315,7 @@ export interface CuaLoopOptions {
313
315
  */
314
316
  stopWhen?: StopWhen;
315
317
  /**
316
- * A declared observation window (#510): once its condition matches (or after the first
318
+ * A declared observation window: once its condition matches (or after the first
317
319
  * observation when it has none) the loop holds the page for the window, captures a frame on the
318
320
  * cadence, takes no action and requests no model turn, then hands control back or ends. Runs at
319
321
  * most once per session and never past the session budget.
@@ -322,11 +324,11 @@ export interface CuaLoopOptions {
322
324
  /** Injected pause for the dwell window's cadence; tests advance their clock through it. */
323
325
  sleep?: (ms: number) => Promise<void>;
324
326
  /**
325
- * The lab's declared protocol (#414): discrete tasks whose completion is corroborated by the
327
+ * The lab's declared protocol: discrete tasks whose completion is corroborated by the
326
328
  * same observations stopWhen reads, on the same cadence. The tracker never influences the loop's
327
- * control flow — a completed task list does not stop a session (that is stopWhen's job); it only
329
+ * control flow: a completed task list does not stop a session (that is stopWhen's job); it only
328
330
  * records the funnel that lands on the trace. The participant-facing halves of these tasks are
329
- * already IN `instructions` (composed upstream); the loop reads only the `success` criteria,
331
+ * already in `instructions` (composed upstream); the loop reads only the `success` criteria,
330
332
  * which never reach the prompt.
331
333
  */
332
334
  tasks?: readonly LabTask[];
@@ -338,18 +340,18 @@ export interface CuaLoopOptions {
338
340
  */
339
341
  maxUsd?: number;
340
342
  /**
341
- * Injected PURE per-turn cost estimator (keeps the loop free of the operator rate table and
343
+ * Injected pure per-turn cost estimator (keeps the loop free of the operator rate table and
342
344
  * makes the cap deterministic in tests). Given running (input, output) token totals, returns the
343
345
  * estimated USD, or null when unpriceable. Only consulted when `maxUsd` is set. A null estimate
344
- * mid-run cannot trip the cap — preflight already guaranteed a rate exists, so a null here is a
346
+ * mid-run cannot trip the cap; preflight already guaranteed a rate exists, so a null here is a
345
347
  * vanished-rate harness condition, not a silent uncapped pass.
346
348
  */
347
349
  estimateTurnCostUsd?: (usage: ActorTokenUsage) => number | null;
348
350
  /**
349
- * RUN-LEVEL spend guard (#299): called with this participant's running usage each turn, at the same
350
- * point the per-participant cap is checked. Returns a human-readable reason when the STUDY's shared
351
+ * Run-level spend guard: called with this participant's running usage each turn, at the same
352
+ * point the per-participant cap is checked. Returns a human-readable reason when the study's shared
351
353
  * budget is exhausted, else null. On a non-null return the loop stops with `budget_reached`
352
- * regardless of material progress — a study-level stop is a recruiting decision hitting its
354
+ * regardless of material progress: a study-level stop is a recruiting decision hitting its
353
355
  * limit, not this participant's runaway, so it never reads as `gave_up`.
354
356
  */
355
357
  overRunBudget?: (usage: ActorTokenUsage) => string | null;
@@ -399,7 +401,7 @@ export interface CuaLoopOptions {
399
401
  */
400
402
  onScreenshot?: (frame: Buffer) => void;
401
403
  /**
402
- * Trace snapshot for a watcher (#441): the redacted items recorded so far, with the running
404
+ * Trace snapshot for a watcher: the redacted items recorded so far, with the running
403
405
  * usage so a run can be priced in flight. Called after each checkpoint's screenshot (the initial
404
406
  * observation and every acted turn, so a flush never shows an action without the frame before
405
407
  * it), after each dwell frame, and after a closing request. The array is a fresh copy; its items
@@ -80,7 +80,7 @@ export class UsageLedger {
80
80
  cachedInput = 0;
81
81
  cacheWriteInput = 0;
82
82
  output = 0;
83
- // Per model-inference usage, in order (#334): the recorded fact long-context pricing tiers
83
+ // Per model-inference usage, in order: the recorded fact long-context pricing tiers
84
84
  // need. A continuing native tool interaction may contain several inference requests.
85
85
  turns = [];
86
86
  /** An interaction turn arrived without complete usage, or its receipt said usage is incomplete. */
@@ -245,7 +245,7 @@ export class UsageLedger {
245
245
  input: this.input,
246
246
  output: this.output,
247
247
  // Recorded only when the provider actually reported it, so a reader can tell "no cache
248
- // hits" from "this provider does not say" (#391); same for cache writes (#334).
248
+ // hits" from "this provider does not say"; same for cache writes.
249
249
  ...(this.cachedInput > 0 ? { cachedInput: this.cachedInput } : {}),
250
250
  ...(this.cacheWriteInput > 0 ? { cacheWriteInput: this.cacheWriteInput } : {}),
251
251
  ...(this.turns.length > 0 ? { turns: this.turns.map((turn) => ({ ...turn })) } : {}),
@@ -0,0 +1,37 @@
1
+ /** The estimated input a carried conversation may reach before its oldest turns are summarized. */
2
+ export declare const CONTEXT_TOKEN_BUDGET = 64000;
3
+ /** What the next request would carry, for the trace. */
4
+ export interface CarriedContextSize {
5
+ readonly exchanges: number;
6
+ readonly screenshots: number;
7
+ readonly notedTurns: number;
8
+ readonly estimatedTokens: number;
9
+ }
10
+ export declare class CarriedConversation {
11
+ private readonly budget;
12
+ private opening;
13
+ private readonly exchanges;
14
+ /** The latest accepted reply's output items, which the next request answers. */
15
+ private pending;
16
+ private readonly notes;
17
+ private notesDropped;
18
+ private collapsedTurns;
19
+ constructor(budget?: number);
20
+ /**
21
+ * Record an accepted reply. `sent` is what that request added after the carried items: the
22
+ * opening message on the first request, then the call outputs and any hint.
23
+ */
24
+ accept(turn: number, sent: readonly unknown[], output: readonly unknown[]): void;
25
+ /** The items to send ahead of a request's own new items. */
26
+ carried(): unknown[];
27
+ /** The carried context's size, for the trace. */
28
+ size(): CarriedContextSize;
29
+ private trim;
30
+ private noteItem;
31
+ }
32
+ /**
33
+ * A rough input-token estimate: images by their size in 32-pixel patches, everything else at four
34
+ * characters a token. It decides when to trim, not what is billed; the trace records the billed
35
+ * input per request beside it.
36
+ */
37
+ export declare function estimateTokens(items: readonly unknown[]): number;
@@ -0,0 +1,214 @@
1
+ import { asArray, asRecord, inputMessage, openAiActionToCua } from "./openai-wire.js";
2
+ // The conversation an explicit-context request carries, kept on the client because the server
3
+ // keeps none (a zero-data-retention org, or zeroDataRetention set). Requests made while the
4
+ // provider still threads on previous_response_id feed it too, so a switch partway through a
5
+ // session keeps everything before the switch.
6
+ //
7
+ // The Responses API pairs items: every computer_call needs its computer_call_output, and a
8
+ // reasoning item travels with the item it preceded. The conversation is therefore cut only at
9
+ // exchange boundaries: one reply's output items together with the items that answered them.
10
+ // When the estimate passes the budget, the opening screenshot goes first, then the oldest
11
+ // exchanges become lines of a progress note that keeps their reasoning summaries, messages and
12
+ // actions as text. The note is an assistant message, so text the model wrote (which can quote a
13
+ // web page) keeps the trust it had when the model wrote it. The newest MIN_KEPT_EXCHANGES
14
+ // exchanges are never collapsed, so a request passes the budget when they alone exceed it; the
15
+ // trace's per-request estimate shows when that happens.
16
+ /** The estimated input a carried conversation may reach before its oldest turns are summarized. */
17
+ export const CONTEXT_TOKEN_BUDGET = 64_000;
18
+ /** Exchanges always carried whole, so the model sees its latest actions with their screens. */
19
+ const MIN_KEPT_EXCHANGES = 2;
20
+ /** The progress note's length cap; past it, the oldest lines are counted instead of shown. */
21
+ const NOTE_CHAR_LIMIT = 16_000;
22
+ /** One note line's cap, so a reply with many actions cannot push the note past its own cap. */
23
+ const LINE_CHAR_LIMIT = 1_200;
24
+ /**
25
+ * Image input tokens per 32-pixel patch. The gpt-5.x and gpt-6 models bill 1.2 per patch, and at
26
+ * the default (auto) detail gpt-5.6 and gpt-6 keep the screenshot's own size. Models that resize
27
+ * to a lower patch budget bill less, so the estimate errs high for them.
28
+ */
29
+ const TOKENS_PER_PATCH = 1.2;
30
+ /** A screenshot whose size cannot be read is estimated as a 2,500-patch image. */
31
+ const UNKNOWN_IMAGE_TOKENS = 3_000;
32
+ export class CarriedConversation {
33
+ budget;
34
+ opening;
35
+ exchanges = [];
36
+ /** The latest accepted reply's output items, which the next request answers. */
37
+ pending;
38
+ notes = [];
39
+ notesDropped = 0;
40
+ collapsedTurns = 0;
41
+ constructor(budget = CONTEXT_TOKEN_BUDGET) {
42
+ this.budget = budget;
43
+ }
44
+ /**
45
+ * Record an accepted reply. `sent` is what that request added after the carried items: the
46
+ * opening message on the first request, then the call outputs and any hint.
47
+ */
48
+ accept(turn, sent, output) {
49
+ if (this.pending === undefined) {
50
+ this.opening = asRecord(sent[0]);
51
+ }
52
+ else {
53
+ this.exchanges.push({ turn: this.pending.turn, output: this.pending.output, answers: sent });
54
+ }
55
+ this.pending = { turn, output };
56
+ this.trim();
57
+ }
58
+ /** The items to send ahead of a request's own new items. */
59
+ carried() {
60
+ const note = this.noteItem();
61
+ return [
62
+ ...(this.opening === undefined ? [] : [this.opening]),
63
+ ...(note === undefined ? [] : [note]),
64
+ ...this.exchanges.flatMap((exchange) => [...exchange.output, ...exchange.answers]),
65
+ ...(this.pending?.output ?? []),
66
+ ];
67
+ }
68
+ /** The carried context's size, for the trace. */
69
+ size() {
70
+ const items = this.carried();
71
+ return {
72
+ exchanges: this.exchanges.length + (this.pending === undefined ? 0 : 1),
73
+ screenshots: items.reduce((count, item) => count + imagesOf(item).length, 0),
74
+ notedTurns: this.collapsedTurns,
75
+ estimatedTokens: estimateTokens(items),
76
+ };
77
+ }
78
+ trim() {
79
+ while (estimateTokens(this.carried()) > this.budget) {
80
+ if (this.opening !== undefined && imagesOf(this.opening).length > 0) {
81
+ this.opening = withoutImages(this.opening);
82
+ continue;
83
+ }
84
+ if (this.exchanges.length <= MIN_KEPT_EXCHANGES)
85
+ return;
86
+ const oldest = this.exchanges.shift();
87
+ this.notes.push(describeExchange(oldest));
88
+ this.collapsedTurns += 1;
89
+ while (this.notes.join("\n").length > NOTE_CHAR_LIMIT && this.notes.length > 1) {
90
+ this.notes.shift();
91
+ this.notesDropped += 1;
92
+ }
93
+ }
94
+ }
95
+ noteItem() {
96
+ if (this.notes.length === 0)
97
+ return undefined;
98
+ const lead = `My notes on my earlier turns in this session, oldest first. Their screenshots are no ` +
99
+ `longer shown; this is what I thought, said and did.` +
100
+ (this.notesDropped === 0 ? "" : ` (${this.notesDropped} earlier turns are not listed.)`);
101
+ return inputMessage("assistant", [
102
+ { type: "output_text", text: `${lead}\n${this.notes.join("\n")}` },
103
+ ]);
104
+ }
105
+ }
106
+ /** One exchange as a progress-note line: its reasoning summary, message and actions. */
107
+ function describeExchange(exchange) {
108
+ const thought = [];
109
+ const said = [];
110
+ const did = [];
111
+ for (const raw of exchange.output) {
112
+ const item = asRecord(raw);
113
+ if (item.type === "reasoning")
114
+ for (const entry of asArray(item.summary)) {
115
+ const text = asRecord(entry).text;
116
+ if (typeof text === "string" && text.length > 0)
117
+ thought.push(text);
118
+ }
119
+ if (item.type === "message")
120
+ for (const entry of asArray(item.content)) {
121
+ const text = asRecord(entry).text;
122
+ if (typeof text === "string" && text.length > 0)
123
+ said.push(text);
124
+ }
125
+ if (item.type === "computer_call") {
126
+ const actions = Array.isArray(item.actions) ? item.actions : [item.action];
127
+ for (const action of actions) {
128
+ const mapped = openAiActionToCua(action);
129
+ if (mapped !== null)
130
+ did.push(describeAction(mapped));
131
+ }
132
+ }
133
+ }
134
+ const parts = [
135
+ thought.length > 0 ? `thought: ${clip(thought.join(" "), 400)}` : undefined,
136
+ said.length > 0 ? `said: ${clip(said.join(" "), 300)}` : undefined,
137
+ did.length > 0 ? `did: ${did.join(", ")}` : undefined,
138
+ ].filter((part) => part !== undefined);
139
+ const line = `Turn ${exchange.turn}: ${parts.length > 0 ? parts.join("; ") : "no recorded output"}`;
140
+ return `${clip(line, LINE_CHAR_LIMIT - 1)}.`;
141
+ }
142
+ function describeAction(action) {
143
+ switch (action.kind) {
144
+ case "click":
145
+ case "double_click":
146
+ case "move":
147
+ return `${action.kind} (${action.x}, ${action.y})`;
148
+ case "scroll":
149
+ return `scroll at (${action.x}, ${action.y}) by (${action.dx}, ${action.dy})`;
150
+ case "type":
151
+ return `type ${JSON.stringify(clip(action.text, 120))}`;
152
+ case "keypress":
153
+ return `keypress ${action.keys.join("+")}`;
154
+ default:
155
+ return action.kind;
156
+ }
157
+ }
158
+ function clip(text, limit) {
159
+ const flat = text.replace(/\s+/g, " ").trim();
160
+ return flat.length <= limit ? flat : `${flat.slice(0, limit - 3)}...`;
161
+ }
162
+ /** The data URLs of the images an input item carries. */
163
+ function imagesOf(item) {
164
+ const record = asRecord(item);
165
+ const output = asRecord(record.output);
166
+ const urls = [];
167
+ if (typeof output.image_url === "string")
168
+ urls.push(output.image_url);
169
+ for (const part of asArray(record.content)) {
170
+ const url = asRecord(part).image_url;
171
+ if (typeof url === "string")
172
+ urls.push(url);
173
+ }
174
+ return urls;
175
+ }
176
+ function withoutImages(item) {
177
+ return {
178
+ ...item,
179
+ content: asArray(item.content).filter((part) => asRecord(part).type !== "input_image"),
180
+ };
181
+ }
182
+ /**
183
+ * A rough input-token estimate: images by their size in 32-pixel patches, everything else at four
184
+ * characters a token. It decides when to trim, not what is billed; the trace records the billed
185
+ * input per request beside it.
186
+ */
187
+ export function estimateTokens(items) {
188
+ let tokens = 0;
189
+ for (const item of items) {
190
+ const images = imagesOf(item);
191
+ for (const url of images)
192
+ tokens += imageTokens(url);
193
+ const text = JSON.stringify(item, (key, value) => (key === "image_url" ? "" : value));
194
+ tokens += Math.ceil(text.length / 4);
195
+ }
196
+ return tokens;
197
+ }
198
+ function imageTokens(dataUrl) {
199
+ const size = pngSize(dataUrl);
200
+ if (size === undefined)
201
+ return UNKNOWN_IMAGE_TOKENS;
202
+ const patches = Math.ceil(size.width / 32) * Math.ceil(size.height / 32);
203
+ return Math.ceil(patches * TOKENS_PER_PATCH);
204
+ }
205
+ /** A PNG's width and height, from the IHDR chunk at the start of its data URL. */
206
+ function pngSize(dataUrl) {
207
+ const prefix = "data:image/png;base64,";
208
+ if (!dataUrl.startsWith(prefix))
209
+ return undefined;
210
+ const head = Buffer.from(dataUrl.slice(prefix.length, prefix.length + 32), "base64");
211
+ if (head.length < 24 || head.toString("ascii", 12, 16) !== "IHDR")
212
+ return undefined;
213
+ return { width: head.readUInt32BE(16), height: head.readUInt32BE(20) };
214
+ }
@@ -7,13 +7,13 @@ export declare const DEFAULT_OPENAI_CU_MODEL = "gpt-5.6-sol";
7
7
  /**
8
8
  * The effort a request carries when a lab declares none. Exported because a default that only
9
9
  * exists as a literal inside the provider is exactly how it stayed invisible: the lab surface has
10
- * to be able to say what will actually run (#497).
10
+ * to be able to say what will actually run.
11
11
  */
12
12
  export declare const DEFAULT_OPENAI_CU_REASONING_EFFORT: ReasoningEffort;
13
13
  /** The opt-in gate for response wire capture: a directory path, or unset for off. */
14
14
  export declare const WIRE_CAPTURE_ENV = "HUMANISH_CUA_WIRE_CAPTURE_DIR";
15
15
  /**
16
- * Deep-copy a captured wire value with every string — object keys included —
16
+ * Deep-copy a captured wire value with every string (object keys included)
17
17
  * passed through the shared redactText, so a secret-shaped echo in a response
18
18
  * can never persist to disk. Pure; non-string primitives pass through unchanged.
19
19
  */
@@ -61,7 +61,7 @@ export interface OpenAiResponsesProviderOptions {
61
61
  model?: string;
62
62
  /**
63
63
  * How hard the model is asked to think per turn. Absent = the provider default below.
64
- * The vocabulary is the documented union across models; SUPPORT IS MODEL-DEPENDENT, so an
64
+ * The vocabulary is the documented union across models; support is model-dependent, so an
65
65
  * unsupported level surfaces as the provider's own first-turn error rather than a silent
66
66
  * downgrade to something the trace would then misreport. See src/actors/reasoning-effort.ts.
67
67
  */
@@ -69,11 +69,11 @@ export interface OpenAiResponsesProviderOptions {
69
69
  /** Optional positive integer output limit per response, including reasoning. Not a spend cap. */
70
70
  maxOutputTokens?: number;
71
71
  /**
72
- * Reasoning-summary capture (#427). Defaults to "auto" (the provider picks the best
72
+ * Reasoning-summary capture. Defaults to "auto" (the provider picks the best
73
73
  * summarizer the model supports); "off" never asks. If the account/model rejects the
74
74
  * request (e.g. an org not verified for reasoning summaries), the provider latches
75
- * summaries off for the session and retries the same turn — the run degrades to
76
- * exactly the pre-#427 behavior instead of failing after spend. Absence stays honest:
75
+ * summaries off for the session and retries the same turn; the run degrades to
76
+ * a run without summaries instead of failing after spend. The trace records the absence:
77
77
  * no summary means no `reasoning` trace items and `counts.reasonings` stays 0.
78
78
  */
79
79
  reasoningSummary?: OpenAiReasoningSummary | "off";
@@ -86,9 +86,12 @@ export interface OpenAiResponsesProviderOptions {
86
86
  * paid request. */
87
87
  singleDispatch?: boolean;
88
88
  delayFn?: (ms: number) => Promise<void>;
89
+ /** Carry the conversation on the client from the first request (explicit_context). */
89
90
  zeroDataRetention?: boolean;
91
+ /** The clock the trace's conversation record reads. Defaults to Date.now. */
92
+ now?: () => number;
90
93
  /**
91
- * Environment for the wire-capture gate (HUMANISH_CUA_WIRE_CAPTURE_DIR — see the
94
+ * Environment for the wire-capture gate (HUMANISH_CUA_WIRE_CAPTURE_DIR; see the
92
95
  * module header). Injectable so deterministic tests control the gate without
93
96
  * mutating process.env. Defaults to process.env.
94
97
  */
@@ -100,7 +103,7 @@ export interface OpenAiResponsesProviderOptions {
100
103
  * call outputs (with the latest screenshot) and thread state via
101
104
  * previous_response_id, transparently falling back to explicit-context mode if
102
105
  * the account rejects server-side retention. Transient HTTP failures are retried
103
- * with exponential backoff. Returns ONLY a CuaTurn from nextTurn; nothing
106
+ * with exponential backoff. Returns only a CuaTurn from nextTurn; nothing
104
107
  * sensitive (the key, the request body, the screenshot, the raw response body)
105
108
  * is ever returned or logged.
106
109
  */