humanish 0.105.0 → 0.106.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.
- package/AGENTS.md +89 -94
- package/ARCHITECTURE.md +146 -0
- package/CHANGELOG.md +502 -0
- package/CONTEXT.md +51 -0
- package/CONTRIBUTING.md +111 -9
- package/README.md +213 -124
- package/SECURITY.md +1 -1
- package/TELEMETRY.md +112 -0
- package/dist/actors/affordance.d.ts +56 -0
- package/dist/actors/affordance.js +155 -0
- package/dist/actors/agent-session.js +42 -0
- package/dist/actors/codex/app-server-actor-trace.d.ts +11 -0
- package/dist/actors/codex/app-server-actor-trace.js +211 -0
- package/dist/actors/codex/app-server-client.d.ts +39 -0
- package/dist/actors/codex/app-server-client.js +116 -0
- package/dist/actors/codex/app-server-trace.d.ts +154 -0
- package/dist/actors/codex/app-server-trace.js +424 -0
- package/dist/actors/codex/app-server-ui.d.ts +40 -0
- package/dist/actors/codex/app-server-ui.js +328 -0
- package/dist/actors/codex/app-server.d.ts +44 -0
- package/dist/actors/codex/app-server.js +268 -0
- package/dist/actors/codex/qualified-versions.d.ts +45 -0
- package/dist/actors/codex/qualified-versions.js +87 -0
- package/dist/actors/codex/restricted-executable.d.ts +17 -0
- package/dist/actors/codex/restricted-executable.js +147 -0
- package/dist/actors/codex/restricted-launch.d.ts +116 -0
- package/dist/actors/codex/restricted-launch.js +222 -0
- package/dist/actors/codex/restricted-participant-policy.d.ts +46 -0
- package/dist/actors/codex/restricted-participant-policy.js +82 -0
- package/dist/actors/codex/restricted-participant.d.ts +20 -0
- package/dist/actors/codex/restricted-participant.js +432 -0
- package/dist/actors/codex/restricted-policy.d.ts +70 -0
- package/dist/actors/codex/restricted-policy.js +326 -0
- package/dist/actors/codex/restricted-session.d.ts +65 -0
- package/dist/actors/codex/restricted-session.js +432 -0
- package/dist/actors/codex/restricted-transport.d.ts +73 -0
- package/dist/actors/codex/restricted-transport.js +335 -0
- package/dist/actors/codex/restricted-turn.d.ts +62 -0
- package/dist/actors/codex/restricted-turn.js +284 -0
- package/dist/actors/computer-use/actor.d.ts +77 -0
- package/dist/actors/computer-use/actor.js +78 -0
- package/dist/actors/computer-use/admission-limit.d.ts +12 -0
- package/dist/actors/computer-use/admission-limit.js +19 -0
- package/dist/actors/computer-use/executor-error.js +48 -0
- package/dist/actors/computer-use/loop/actions.d.ts +26 -0
- package/dist/actors/computer-use/loop/actions.js +245 -0
- package/dist/actors/computer-use/loop/backstop.d.ts +42 -0
- package/dist/actors/computer-use/loop/backstop.js +202 -0
- package/dist/actors/computer-use/loop/debrief.d.ts +19 -0
- package/dist/actors/computer-use/loop/debrief.js +164 -0
- package/dist/actors/computer-use/loop/ending.d.ts +86 -0
- package/dist/actors/computer-use/loop/ending.js +316 -0
- package/dist/actors/computer-use/loop/observation.d.ts +55 -0
- package/dist/actors/computer-use/loop/observation.js +246 -0
- package/dist/actors/computer-use/loop/output-limit.d.ts +11 -0
- package/dist/actors/computer-use/loop/output-limit.js +21 -0
- package/dist/actors/computer-use/loop/provider-call.d.ts +19 -0
- package/dist/actors/computer-use/loop/provider-call.js +208 -0
- package/dist/actors/computer-use/loop/race.d.ts +34 -0
- package/dist/actors/computer-use/loop/race.js +79 -0
- package/dist/actors/computer-use/loop/session.d.ts +77 -0
- package/dist/actors/computer-use/loop/session.js +135 -0
- package/dist/actors/computer-use/loop/spend.d.ts +30 -0
- package/dist/actors/computer-use/loop/spend.js +85 -0
- package/dist/actors/computer-use/loop/trace.d.ts +35 -0
- package/dist/actors/computer-use/loop/trace.js +140 -0
- package/dist/actors/computer-use/loop/types.d.ts +404 -0
- package/dist/actors/computer-use/loop/types.js +1 -0
- package/dist/actors/computer-use/loop/usage.d.ts +102 -0
- package/dist/actors/computer-use/loop/usage.js +355 -0
- package/dist/actors/computer-use/loop.d.ts +11 -0
- package/dist/actors/computer-use/loop.js +248 -0
- package/dist/actors/computer-use/openai-provider.d.ts +107 -0
- package/dist/actors/computer-use/openai-provider.js +472 -0
- package/dist/actors/computer-use/openai-requests.d.ts +35 -0
- package/dist/actors/computer-use/openai-requests.js +74 -0
- package/dist/actors/computer-use/openai-wire.d.ts +67 -0
- package/dist/actors/computer-use/openai-wire.js +365 -0
- package/dist/actors/computer-use/provider-error.d.ts +27 -0
- package/dist/actors/computer-use/provider-error.js +86 -0
- package/dist/actors/computer-use/speech.js +6 -0
- package/dist/actors/contract.d.ts +315 -0
- package/dist/actors/contract.js +201 -0
- package/dist/actors/goal-source.js +38 -0
- package/dist/actors/local-agent/claude-session.d.ts +43 -0
- package/dist/actors/local-agent/claude-session.js +370 -0
- package/dist/actors/local-agent/cli.d.ts +115 -0
- package/dist/actors/local-agent/cli.js +413 -0
- package/dist/actors/local-agent/readiness.d.ts +31 -0
- package/dist/actors/local-agent/readiness.js +45 -0
- package/dist/actors/openai-endpoint.d.ts +2 -0
- package/dist/actors/openai-endpoint.js +2 -0
- package/dist/actors/output-token-limit.js +4 -0
- package/dist/actors/reasoning-effort.js +33 -0
- package/dist/actors/registry.d.ts +59 -0
- package/dist/actors/registry.js +89 -0
- package/dist/actors/scripted-browser/actor.d.ts +49 -0
- package/dist/actors/scripted-browser/actor.js +428 -0
- package/dist/actors/scripted-browser/browser-command.d.ts +1 -0
- package/dist/actors/scripted-browser/browser-command.js +48 -0
- package/dist/actors/scripted-browser/journey.d.ts +9 -0
- package/dist/actors/scripted-browser/journey.js +171 -0
- package/dist/actors/scripted-browser/steps.d.ts +60 -0
- package/dist/actors/scripted-browser/steps.js +384 -0
- package/dist/actors/scripted-browser/types.d.ts +135 -0
- package/dist/actors/scripted-browser/types.js +26 -0
- package/dist/actors/stop-cause.d.ts +9 -0
- package/dist/actors/stop-cause.js +42 -0
- package/dist/actors/stop-conditions.d.ts +40 -0
- package/dist/actors/stop-conditions.js +65 -0
- package/dist/analysis/automatic-completion.d.ts +38 -0
- package/dist/analysis/automatic-completion.js +90 -0
- package/dist/analysis/automatic-config.d.ts +41 -0
- package/dist/analysis/automatic-config.js +135 -0
- package/dist/analysis/automatic.d.ts +17 -0
- package/dist/analysis/automatic.js +279 -0
- package/dist/analysis/codex-config.d.ts +8 -0
- package/dist/analysis/codex-config.js +69 -0
- package/dist/analysis/evidence-sources.d.ts +23 -0
- package/dist/analysis/evidence-sources.js +251 -0
- package/dist/analysis/evidence.d.ts +18 -0
- package/dist/analysis/evidence.js +482 -0
- package/dist/analysis/execute.d.ts +52 -0
- package/dist/analysis/execute.js +504 -0
- package/dist/analysis/image-tokens.d.ts +1 -0
- package/dist/analysis/image-tokens.js +41 -0
- package/dist/analysis/job.d.ts +97 -0
- package/dist/analysis/job.js +311 -0
- package/dist/analysis/load.d.ts +3 -0
- package/dist/analysis/load.js +11 -0
- package/dist/analysis/provider.d.ts +57 -0
- package/dist/analysis/provider.js +227 -0
- package/dist/analysis/restricted-codex.d.ts +19 -0
- package/dist/analysis/restricted-codex.js +23 -0
- package/dist/analysis/service.d.ts +72 -0
- package/dist/analysis/service.js +399 -0
- package/dist/analysis/sharing.d.ts +11 -0
- package/dist/analysis/sharing.js +44 -0
- package/dist/analysis/store-executions.d.ts +27 -0
- package/dist/analysis/store-executions.js +224 -0
- package/dist/analysis/store.d.ts +31 -0
- package/dist/analysis/store.js +315 -0
- package/dist/analysis/types.d.ts +217 -0
- package/dist/analysis/types.js +12 -0
- package/dist/analysis/validation.d.ts +225 -0
- package/dist/analysis/validation.js +562 -0
- package/dist/browser-control/client.d.ts +18 -0
- package/dist/browser-control/client.js +239 -0
- package/dist/browser-control/dispatcher.d.ts +19 -0
- package/dist/browser-control/dispatcher.js +221 -0
- package/dist/browser-control/protocol.d.ts +492 -0
- package/dist/browser-control/protocol.js +360 -0
- package/dist/browser-control/recording-transfer.d.ts +3 -0
- package/dist/browser-control/recording-transfer.js +48 -0
- package/dist/browser-control/transport.d.ts +27 -0
- package/dist/browser-control/transport.js +189 -0
- package/dist/cli/commands/analysis-signals.d.ts +7 -0
- package/dist/cli/commands/analysis-signals.js +25 -0
- package/dist/cli/commands/analyze.d.ts +3 -0
- package/dist/cli/commands/analyze.js +212 -0
- package/dist/cli/commands/codex.d.ts +3 -0
- package/dist/cli/commands/codex.js +145 -0
- package/dist/cli/commands/comms.d.ts +3 -0
- package/dist/cli/commands/comms.js +225 -0
- package/dist/cli/commands/feedback.d.ts +3 -0
- package/dist/cli/commands/feedback.js +138 -0
- package/dist/cli/commands/lab-format.d.ts +8 -0
- package/dist/cli/commands/lab-format.js +105 -0
- package/dist/cli/commands/lab-route-computer-use.d.ts +20 -0
- package/dist/cli/commands/lab-route-computer-use.js +251 -0
- package/dist/cli/commands/lab-route-open.d.ts +27 -0
- package/dist/cli/commands/lab-route-open.js +37 -0
- package/dist/cli/commands/lab-route-preview.d.ts +20 -0
- package/dist/cli/commands/lab-route-preview.js +74 -0
- package/dist/cli/commands/lab-route-run.d.ts +17 -0
- package/dist/cli/commands/lab-route-run.js +31 -0
- package/dist/cli/commands/lab-route-scripted.d.ts +19 -0
- package/dist/cli/commands/lab-route-scripted.js +50 -0
- package/dist/cli/commands/lab-route-shared-world.d.ts +20 -0
- package/dist/cli/commands/lab-route-shared-world.js +135 -0
- package/dist/cli/commands/lab-route-terminal.d.ts +19 -0
- package/dist/cli/commands/lab-route-terminal.js +49 -0
- package/dist/cli/commands/lab-run.d.ts +9 -0
- package/dist/cli/commands/lab-run.js +166 -0
- package/dist/cli/commands/lab-scorer.d.ts +30 -0
- package/dist/cli/commands/lab-scorer.js +17 -0
- package/dist/cli/commands/lab.d.ts +3 -0
- package/dist/cli/commands/lab.js +193 -0
- package/dist/cli/commands/observe.d.ts +4 -0
- package/dist/cli/commands/observe.js +345 -0
- package/dist/cli/commands/runs.d.ts +11 -0
- package/dist/cli/commands/runs.js +314 -0
- package/dist/cli/commands/setup.d.ts +11 -0
- package/dist/cli/commands/setup.js +325 -0
- package/dist/cli/commands/tui.d.ts +32 -0
- package/dist/cli/commands/tui.js +305 -0
- package/dist/cli/commands/watch.d.ts +3 -0
- package/dist/cli/commands/watch.js +245 -0
- package/dist/cli/doctor.d.ts +39 -0
- package/dist/cli/doctor.js +263 -0
- package/dist/cli/first-run-path.d.ts +67 -0
- package/dist/cli/first-run-path.js +150 -0
- package/dist/cli/io.d.ts +85 -0
- package/dist/cli/io.js +232 -0
- package/dist/cli/observer-follow.d.ts +56 -0
- package/dist/cli/observer-follow.js +160 -0
- package/dist/cli/orientation.d.ts +30 -0
- package/dist/cli/orientation.js +114 -0
- package/dist/cli/program.d.ts +15 -0
- package/dist/cli/program.js +338 -0
- package/dist/cli/secret-prompt.js +39 -0
- package/dist/cli/telemetry.js +351 -0
- package/dist/cli.js +2 -4
- package/dist/comms/agentmail.d.ts +29 -0
- package/dist/comms/agentmail.js +568 -0
- package/dist/comms/capture-surface.d.ts +54 -0
- package/dist/comms/capture-surface.js +468 -0
- package/dist/comms/catch-host.d.ts +52 -0
- package/dist/comms/catch-host.js +192 -0
- package/dist/comms/connections.d.ts +20 -0
- package/dist/comms/connections.js +116 -0
- package/dist/comms/email-catch.d.ts +49 -0
- package/dist/comms/email-catch.js +236 -0
- package/dist/comms/extract.d.ts +7 -0
- package/dist/comms/extract.js +65 -0
- package/dist/comms/fake-inbox.d.ts +39 -0
- package/dist/comms/fake-inbox.js +136 -0
- package/dist/comms/images.d.ts +7 -0
- package/dist/comms/images.js +53 -0
- package/dist/comms/lease-store.d.ts +91 -0
- package/dist/comms/lease-store.js +600 -0
- package/dist/comms/providers.d.ts +30 -0
- package/dist/comms/providers.js +24 -0
- package/dist/comms/receiving-common.d.ts +17 -0
- package/dist/comms/receiving-common.js +82 -0
- package/dist/comms/receiving-evidence.d.ts +4 -0
- package/dist/comms/receiving-evidence.js +59 -0
- package/dist/comms/receiving-recovery.d.ts +22 -0
- package/dist/comms/receiving-recovery.js +100 -0
- package/dist/comms/receiving-render.d.ts +16 -0
- package/dist/comms/receiving-render.js +409 -0
- package/dist/comms/receiving-runtime.d.ts +41 -0
- package/dist/comms/receiving-runtime.js +66 -0
- package/dist/comms/receiving-surface.d.ts +8 -0
- package/dist/comms/receiving-surface.js +156 -0
- package/dist/comms/receiving-types.d.ts +122 -0
- package/dist/comms/receiving-types.js +3 -0
- package/dist/comms/receiving.d.ts +33 -0
- package/dist/comms/receiving.js +508 -0
- package/dist/comms/sandbox-catch-script.d.ts +16 -0
- package/dist/comms/sandbox-catch-script.js +331 -0
- package/dist/comms/sandbox-catch.d.ts +214 -0
- package/dist/comms/sandbox-catch.js +451 -0
- package/dist/comms/setup.d.ts +65 -0
- package/dist/comms/setup.js +259 -0
- package/dist/comms/thread-evidence.d.ts +28 -0
- package/dist/comms/thread-evidence.js +30 -0
- package/dist/comms/types.d.ts +76 -0
- package/dist/comms/types.js +8 -0
- package/dist/deprecated.d.ts +90 -0
- package/dist/deprecated.js +106 -0
- package/dist/evidence/browser-hygiene.js +42 -0
- package/dist/evidence/desktop-recorder.d.ts +39 -0
- package/dist/evidence/desktop-recorder.js +340 -0
- package/dist/evidence/desktop-recording-artifact.d.ts +5 -0
- package/dist/evidence/desktop-recording-artifact.js +53 -0
- package/dist/evidence/desktop-recording-types.d.ts +27 -0
- package/dist/evidence/desktop-recording-types.js +16 -0
- package/dist/evidence/encoded-text.d.ts +27 -0
- package/dist/evidence/encoded-text.js +243 -0
- package/dist/evidence/frame-signature.d.ts +17 -0
- package/dist/evidence/frame-signature.js +111 -0
- package/dist/evidence/image.d.ts +24 -0
- package/dist/evidence/image.js +170 -0
- package/dist/evidence/plain-text.d.ts +8 -0
- package/dist/evidence/plain-text.js +16 -0
- package/dist/evidence/redaction.d.ts +110 -0
- package/dist/evidence/redaction.js +329 -0
- package/dist/feedback/draft.d.ts +58 -0
- package/dist/feedback/draft.js +309 -0
- package/dist/feedback/export-bundle.d.ts +6 -0
- package/dist/feedback/export-bundle.js +585 -0
- package/dist/feedback/export.d.ts +50 -0
- package/dist/feedback/export.js +392 -0
- package/dist/feedback/feedback.d.ts +37 -0
- package/dist/feedback/feedback.js +282 -0
- package/dist/feedback/proof.d.ts +8 -0
- package/dist/feedback/proof.js +56 -0
- package/dist/guest/bootstrap.d.ts +55 -0
- package/dist/guest/bootstrap.js +348 -0
- package/dist/guest/browser-tools.d.ts +8 -0
- package/dist/guest/browser-tools.js +72 -0
- package/dist/guest/chromium-text.d.ts +62 -0
- package/dist/guest/chromium-text.js +386 -0
- package/dist/guest/desktop-executor.d.ts +57 -0
- package/dist/guest/desktop-executor.js +256 -0
- package/dist/guest/desktop-keys.d.ts +8 -0
- package/dist/guest/desktop-keys.js +89 -0
- package/dist/guest/desktop-media.d.ts +70 -0
- package/dist/guest/desktop-media.js +385 -0
- package/dist/guest/desktop-native.d.ts +14 -0
- package/dist/guest/desktop-native.js +156 -0
- package/dist/guest/media-config.d.ts +15 -0
- package/dist/guest/media-config.js +16 -0
- package/dist/guest/runtime-desktop.d.ts +45 -0
- package/dist/guest/runtime-desktop.js +420 -0
- package/dist/guest/runtime-processes.d.ts +28 -0
- package/dist/guest/runtime-processes.js +94 -0
- package/dist/guest/runtime.d.ts +31 -0
- package/dist/guest/runtime.js +124 -0
- package/dist/guest-media-worker.js +184 -48
- package/dist/guest-runtime-main.js +23 -10
- package/dist/guest-runtime-revision.js +1 -1
- package/dist/index.d.ts +32 -83
- package/dist/index.js +21 -42
- package/dist/keys/env-file.d.ts +15 -0
- package/dist/keys/env-file.js +109 -0
- package/dist/keys/key-resolution.d.ts +58 -0
- package/dist/keys/key-resolution.js +389 -0
- package/dist/lab/adapter-extension.d.ts +75 -0
- package/dist/lab/adapter-extension.js +253 -0
- package/dist/lab/adapter-scorer-loader.d.ts +43 -0
- package/dist/lab/adapter-scorer-loader.js +130 -0
- package/dist/lab/bag-overrides.d.ts +18 -0
- package/dist/lab/bag-overrides.js +121 -0
- package/dist/lab/composition-rules.d.ts +5 -0
- package/dist/lab/composition-rules.js +283 -0
- package/dist/lab/config.d.ts +7 -0
- package/dist/lab/config.js +208 -0
- package/dist/lab/device-presets.d.ts +97 -0
- package/dist/lab/device-presets.js +87 -0
- package/dist/lab/discover.d.ts +65 -0
- package/dist/lab/discover.js +422 -0
- package/dist/lab/doctor.d.ts +39 -0
- package/dist/lab/doctor.js +233 -0
- package/dist/lab/init-paths.d.ts +5 -0
- package/dist/lab/init-paths.js +89 -0
- package/dist/lab/init-plan.d.ts +20 -0
- package/dist/lab/init-plan.js +163 -0
- package/dist/lab/init-templates.d.ts +28 -0
- package/dist/lab/init-templates.js +416 -0
- package/dist/lab/init.d.ts +39 -0
- package/dist/lab/init.js +287 -0
- package/dist/lab/keys.d.ts +2 -0
- package/dist/lab/keys.js +264 -0
- package/dist/lab/parse/actors.d.ts +14 -0
- package/dist/lab/parse/actors.js +453 -0
- package/dist/lab/parse/comms.d.ts +12 -0
- package/dist/lab/parse/comms.js +246 -0
- package/dist/lab/parse/execution.d.ts +19 -0
- package/dist/lab/parse/execution.js +356 -0
- package/dist/lab/parse/subject-state.d.ts +30 -0
- package/dist/lab/parse/subject-state.js +179 -0
- package/dist/lab/parse/subject.d.ts +9 -0
- package/dist/lab/parse/subject.js +420 -0
- package/dist/lab/parse/values.d.ts +17 -0
- package/dist/lab/parse/values.js +65 -0
- package/dist/lab/participant-assignment.d.ts +12 -0
- package/dist/lab/participant-assignment.js +19 -0
- package/dist/lab/persona-resolve.d.ts +39 -0
- package/dist/lab/persona-resolve.js +118 -0
- package/dist/lab/persona.d.ts +39 -0
- package/dist/lab/persona.js +192 -0
- package/dist/lab/plan-base.d.ts +24 -0
- package/dist/lab/plan-base.js +113 -0
- package/dist/lab/plan-participants.d.ts +81 -0
- package/dist/lab/plan-participants.js +92 -0
- package/dist/lab/plan-types.d.ts +269 -0
- package/dist/lab/plan-types.js +5 -0
- package/dist/lab/plan.d.ts +27 -0
- package/dist/lab/plan.js +156 -0
- package/dist/lab/preflight-probes.d.ts +3 -0
- package/dist/lab/preflight-probes.js +312 -0
- package/dist/lab/preflight-result.d.ts +7 -0
- package/dist/lab/preflight-result.js +43 -0
- package/dist/lab/preflight.d.ts +95 -0
- package/dist/lab/preflight.js +117 -0
- package/dist/lab/route-inputs.d.ts +17 -0
- package/dist/lab/route-inputs.js +95 -0
- package/dist/lab/routing.d.ts +81 -0
- package/dist/lab/routing.js +214 -0
- package/dist/lab/run-lab-events.d.ts +69 -0
- package/dist/lab/run-lab-events.js +95 -0
- package/dist/lab/run-lab-options.d.ts +82 -0
- package/dist/lab/run-lab-options.js +399 -0
- package/dist/lab/summary.d.ts +60 -0
- package/dist/lab/summary.js +168 -0
- package/dist/lab/tasks.d.ts +91 -0
- package/dist/lab/tasks.js +139 -0
- package/dist/lab/types.d.ts +813 -0
- package/dist/lab/types.js +6 -0
- package/dist/lab/validation.d.ts +67 -0
- package/dist/lab/validation.js +387 -0
- package/dist/lab/warnings.d.ts +2 -0
- package/dist/lab/warnings.js +338 -0
- package/dist/observer/artifact.d.ts +23 -0
- package/dist/observer/artifact.js +235 -0
- package/dist/observer/data.d.ts +115 -0
- package/dist/observer/data.js +258 -0
- package/dist/observer/exposure.d.ts +64 -0
- package/dist/observer/exposure.js +143 -0
- package/dist/observer/http.js +50 -0
- package/dist/observer/library.js +190 -0
- package/dist/observer/listen.js +85 -0
- package/dist/observer/live.d.ts +9 -0
- package/dist/observer/live.js +25 -0
- package/dist/observer/pinned-files.d.ts +30 -0
- package/dist/observer/pinned-files.js +160 -0
- package/dist/observer/render.d.ts +69 -0
- package/dist/observer/render.js +350 -0
- package/dist/observer/run-inventory.d.ts +35 -0
- package/dist/observer/run-inventory.js +95 -0
- package/dist/observer/run-routes.d.ts +37 -0
- package/dist/observer/run-routes.js +373 -0
- package/dist/observer/serve.d.ts +97 -0
- package/dist/observer/serve.js +305 -0
- package/dist/observer/static.js +369 -0
- package/dist/observer/tunnel.js +112 -0
- package/dist/observer-app.html +9 -20
- package/dist/routes/computer-use/bundle-parts.d.ts +50 -0
- package/dist/routes/computer-use/bundle-parts.js +177 -0
- package/dist/routes/computer-use/bundle.d.ts +56 -0
- package/dist/routes/computer-use/bundle.js +184 -0
- package/dist/routes/computer-use/diagnostics.d.ts +38 -0
- package/dist/routes/computer-use/diagnostics.js +94 -0
- package/dist/routes/computer-use/e2b-desktop/comms.d.ts +65 -0
- package/dist/routes/computer-use/e2b-desktop/comms.js +225 -0
- package/dist/routes/computer-use/e2b-desktop/desktop.d.ts +3 -0
- package/dist/routes/computer-use/e2b-desktop/desktop.js +91 -0
- package/dist/routes/computer-use/e2b-desktop/fidelity.d.ts +65 -0
- package/dist/routes/computer-use/e2b-desktop/fidelity.js +156 -0
- package/dist/routes/computer-use/e2b-desktop/prepare.d.ts +18 -0
- package/dist/routes/computer-use/e2b-desktop/prepare.js +198 -0
- package/dist/routes/computer-use/e2b-desktop/start.d.ts +14 -0
- package/dist/routes/computer-use/e2b-desktop/start.js +193 -0
- package/dist/routes/computer-use/e2b-desktop/state.d.ts +65 -0
- package/dist/routes/computer-use/e2b-desktop/state.js +69 -0
- package/dist/routes/computer-use/e2b-desktop/teardown.d.ts +6 -0
- package/dist/routes/computer-use/e2b-desktop/teardown.js +152 -0
- package/dist/routes/computer-use/external-comms.d.ts +20 -0
- package/dist/routes/computer-use/external-comms.js +55 -0
- package/dist/routes/computer-use/fanout-bundle.d.ts +11 -0
- package/dist/routes/computer-use/fanout-bundle.js +274 -0
- package/dist/routes/computer-use/fanout-lanes.d.ts +15 -0
- package/dist/routes/computer-use/fanout-lanes.js +302 -0
- package/dist/routes/computer-use/in-process-desktop.d.ts +17 -0
- package/dist/routes/computer-use/in-process-desktop.js +40 -0
- package/dist/routes/computer-use/lanes.d.ts +35 -0
- package/dist/routes/computer-use/lanes.js +321 -0
- package/dist/routes/computer-use/legacy-lane-spec.d.ts +62 -0
- package/dist/routes/computer-use/legacy-lane-spec.js +39 -0
- package/dist/routes/computer-use/live-flush.d.ts +42 -0
- package/dist/routes/computer-use/live-flush.js +154 -0
- package/dist/routes/computer-use/local-tree-pack.d.ts +27 -0
- package/dist/routes/computer-use/local-tree-pack.js +47 -0
- package/dist/routes/computer-use/local-vm.d.ts +20 -0
- package/dist/routes/computer-use/local-vm.js +218 -0
- package/dist/routes/computer-use/participant-desktop.d.ts +63 -0
- package/dist/routes/computer-use/participant-desktop.js +33 -0
- package/dist/routes/computer-use/participant-facts.d.ts +6 -0
- package/dist/routes/computer-use/participant-facts.js +22 -0
- package/dist/routes/computer-use/participant-model.d.ts +30 -0
- package/dist/routes/computer-use/participant-model.js +222 -0
- package/dist/routes/computer-use/participant-prompt.d.ts +53 -0
- package/dist/routes/computer-use/participant-prompt.js +87 -0
- package/dist/routes/computer-use/participant-runs.d.ts +67 -0
- package/dist/routes/computer-use/participant-runs.js +255 -0
- package/dist/routes/computer-use/plan.d.ts +56 -0
- package/dist/routes/computer-use/plan.js +308 -0
- package/dist/routes/computer-use/preflight.d.ts +26 -0
- package/dist/routes/computer-use/preflight.js +85 -0
- package/dist/routes/computer-use/rerun-selection.d.ts +19 -0
- package/dist/routes/computer-use/rerun-selection.js +121 -0
- package/dist/routes/computer-use/result.d.ts +7 -0
- package/dist/routes/computer-use/result.js +292 -0
- package/dist/routes/computer-use/route.d.ts +33 -0
- package/dist/routes/computer-use/route.js +145 -0
- package/dist/routes/computer-use/run-lanes.d.ts +59 -0
- package/dist/routes/computer-use/run-lanes.js +135 -0
- package/dist/routes/computer-use/self-report.d.ts +21 -0
- package/dist/routes/computer-use/self-report.js +231 -0
- package/dist/routes/computer-use/setup.d.ts +136 -0
- package/dist/routes/computer-use/setup.js +371 -0
- package/dist/routes/computer-use/single-bundle.d.ts +97 -0
- package/dist/routes/computer-use/single-bundle.js +393 -0
- package/dist/routes/computer-use/subject-projection.d.ts +51 -0
- package/dist/routes/computer-use/subject-projection.js +159 -0
- package/dist/routes/computer-use/types.d.ts +539 -0
- package/dist/routes/computer-use/types.js +37 -0
- package/dist/routes/preview.d.ts +13 -0
- package/dist/routes/preview.js +36 -0
- package/dist/routes/scripted/bundle.d.ts +47 -0
- package/dist/routes/scripted/bundle.js +195 -0
- package/dist/routes/scripted/plan.d.ts +30 -0
- package/dist/routes/scripted/plan.js +95 -0
- package/dist/routes/scripted/result.d.ts +48 -0
- package/dist/routes/scripted/result.js +176 -0
- package/dist/routes/scripted/route.d.ts +28 -0
- package/dist/routes/scripted/route.js +218 -0
- package/dist/routes/scripted/scenario.d.ts +21 -0
- package/dist/routes/scripted/scenario.js +102 -0
- package/dist/routes/scripted/session-result.d.ts +8 -0
- package/dist/routes/scripted/session-result.js +60 -0
- package/dist/routes/scripted/setup.d.ts +45 -0
- package/dist/routes/scripted/setup.js +126 -0
- package/dist/routes/scripted/subject.d.ts +49 -0
- package/dist/routes/scripted/subject.js +156 -0
- package/dist/routes/scripted/surface-records.d.ts +26 -0
- package/dist/routes/scripted/surface-records.js +88 -0
- package/dist/routes/scripted/surface-sessions.d.ts +13 -0
- package/dist/routes/scripted/surface-sessions.js +40 -0
- package/dist/routes/scripted/types.d.ts +88 -0
- package/dist/routes/scripted/types.js +3 -0
- package/dist/routes/shared-world/bundle.d.ts +20 -0
- package/dist/routes/shared-world/bundle.js +446 -0
- package/dist/routes/shared-world/checkpoints.d.ts +25 -0
- package/dist/routes/shared-world/checkpoints.js +46 -0
- package/dist/routes/shared-world/comms.d.ts +68 -0
- package/dist/routes/shared-world/comms.js +176 -0
- package/dist/routes/shared-world/external-public.d.ts +21 -0
- package/dist/routes/shared-world/external-public.js +130 -0
- package/dist/routes/shared-world/handoff.d.ts +62 -0
- package/dist/routes/shared-world/handoff.js +348 -0
- package/dist/routes/shared-world/lobby-code.d.ts +25 -0
- package/dist/routes/shared-world/lobby-code.js +152 -0
- package/dist/routes/shared-world/plan.d.ts +27 -0
- package/dist/routes/shared-world/plan.js +174 -0
- package/dist/routes/shared-world/provenance.d.ts +27 -0
- package/dist/routes/shared-world/provenance.js +65 -0
- package/dist/routes/shared-world/provisioned.d.ts +57 -0
- package/dist/routes/shared-world/provisioned.js +505 -0
- package/dist/routes/shared-world/result.d.ts +18 -0
- package/dist/routes/shared-world/result.js +327 -0
- package/dist/routes/shared-world/route.d.ts +21 -0
- package/dist/routes/shared-world/route.js +277 -0
- package/dist/routes/shared-world/seat-records.d.ts +20 -0
- package/dist/routes/shared-world/seat-records.js +213 -0
- package/dist/routes/shared-world/seats.d.ts +38 -0
- package/dist/routes/shared-world/seats.js +208 -0
- package/dist/routes/shared-world/setup.d.ts +48 -0
- package/dist/routes/shared-world/setup.js +200 -0
- package/dist/routes/shared-world/types.d.ts +354 -0
- package/dist/routes/shared-world/types.js +29 -0
- package/dist/routes/terminal/adapter.d.ts +37 -0
- package/dist/routes/terminal/adapter.js +201 -0
- package/dist/routes/terminal/bundle.d.ts +79 -0
- package/dist/routes/terminal/bundle.js +305 -0
- package/dist/routes/terminal/credentials.d.ts +34 -0
- package/dist/routes/terminal/credentials.js +102 -0
- package/dist/routes/terminal/dry-run.d.ts +24 -0
- package/dist/routes/terminal/dry-run.js +157 -0
- package/dist/routes/terminal/encoding.js +79 -0
- package/dist/routes/terminal/ledger.d.ts +49 -0
- package/dist/routes/terminal/ledger.js +170 -0
- package/dist/routes/terminal/lifetime.d.ts +10 -0
- package/dist/routes/terminal/lifetime.js +22 -0
- package/dist/routes/terminal/live-finish.d.ts +31 -0
- package/dist/routes/terminal/live-finish.js +215 -0
- package/dist/routes/terminal/live-sandbox.d.ts +69 -0
- package/dist/routes/terminal/live-sandbox.js +452 -0
- package/dist/routes/terminal/persona.d.ts +20 -0
- package/dist/routes/terminal/persona.js +34 -0
- package/dist/routes/terminal/plan.d.ts +21 -0
- package/dist/routes/terminal/plan.js +115 -0
- package/dist/routes/terminal/recorder.d.ts +23 -0
- package/dist/routes/terminal/recorder.js +77 -0
- package/dist/routes/terminal/result.d.ts +47 -0
- package/dist/routes/terminal/result.js +114 -0
- package/dist/routes/terminal/route.d.ts +23 -0
- package/dist/routes/terminal/route.js +170 -0
- package/dist/routes/terminal/runtime-auth.d.ts +12 -0
- package/dist/routes/terminal/runtime-auth.js +23 -0
- package/dist/routes/terminal/runtime.d.ts +14 -0
- package/dist/routes/terminal/runtime.js +47 -0
- package/dist/routes/terminal/sandbox.d.ts +35 -0
- package/dist/routes/terminal/sandbox.js +126 -0
- package/dist/routes/terminal/session.d.ts +25 -0
- package/dist/routes/terminal/session.js +199 -0
- package/dist/routes/terminal/token-usage.d.ts +15 -0
- package/dist/routes/terminal/token-usage.js +93 -0
- package/dist/routes/terminal/trace.d.ts +40 -0
- package/dist/routes/terminal/trace.js +172 -0
- package/dist/routes/terminal/types.d.ts +342 -0
- package/dist/routes/terminal/types.js +31 -0
- package/dist/run/bundle-shape.d.ts +7 -0
- package/dist/run/bundle-shape.js +369 -0
- package/dist/run/bundle.d.ts +547 -0
- package/dist/run/bundle.js +44 -0
- package/dist/run/concurrency.js +24 -0
- package/dist/run/contained-output.d.ts +50 -0
- package/dist/run/contained-output.js +351 -0
- package/dist/run/cost-summary.d.ts +28 -0
- package/dist/run/cost-summary.js +213 -0
- package/dist/run/costs.js +140 -0
- package/dist/run/detail.d.ts +62 -0
- package/dist/run/detail.js +139 -0
- package/dist/run/dry-run-inputs.d.ts +9 -0
- package/dist/run/dry-run-inputs.js +90 -0
- package/dist/run/dry-run.d.ts +6 -0
- package/dist/run/dry-run.js +362 -0
- package/dist/run/feedback-shape.d.ts +7 -0
- package/dist/run/feedback-shape.js +89 -0
- package/dist/run/git-state.d.ts +35 -0
- package/dist/run/git-state.js +316 -0
- package/dist/run/git-workspace.d.ts +32 -0
- package/dist/run/git-workspace.js +450 -0
- package/dist/run/judge.d.ts +210 -0
- package/dist/run/judge.js +240 -0
- package/dist/run/locate.d.ts +22 -0
- package/dist/run/locate.js +122 -0
- package/dist/run/outcomes.d.ts +31 -0
- package/dist/run/outcomes.js +210 -0
- package/dist/run/participant-records.d.ts +28 -0
- package/dist/run/participant-records.js +63 -0
- package/dist/run/participant.d.ts +29 -0
- package/dist/run/participant.js +12 -0
- package/dist/run/paths.d.ts +79 -0
- package/dist/run/paths.js +356 -0
- package/dist/run/preflight-receipts.d.ts +46 -0
- package/dist/run/preflight-receipts.js +173 -0
- package/dist/run/pricing.d.ts +124 -0
- package/dist/run/pricing.js +298 -0
- package/dist/run/project.d.ts +8 -0
- package/dist/run/project.js +103 -0
- package/dist/run/projection.d.ts +184 -0
- package/dist/run/projection.js +356 -0
- package/dist/run/reclaim.d.ts +41 -0
- package/dist/run/reclaim.js +183 -0
- package/dist/run/results.d.ts +88 -0
- package/dist/run/results.js +3 -0
- package/dist/run/run-index.d.ts +107 -0
- package/dist/run/run-index.js +243 -0
- package/dist/run/run.d.ts +103 -0
- package/dist/run/run.js +199 -0
- package/dist/run/sandbox-receipts.d.ts +31 -0
- package/dist/run/sandbox-receipts.js +49 -0
- package/dist/run/shared-world-evidence.d.ts +220 -0
- package/dist/run/shared-world-evidence.js +49 -0
- package/dist/run/shared-world-shape.d.ts +26 -0
- package/dist/run/shared-world-shape.js +181 -0
- package/dist/run/stats.d.ts +82 -0
- package/dist/run/stats.js +258 -0
- package/dist/run/status.d.ts +111 -0
- package/dist/run/status.js +176 -0
- package/dist/run/stored-runs.d.ts +38 -0
- package/dist/run/stored-runs.js +273 -0
- package/dist/run/stream-shape.d.ts +4 -0
- package/dist/run/stream-shape.js +160 -0
- package/dist/run/streams.d.ts +257 -0
- package/dist/run/streams.js +12 -0
- package/dist/run/study-files.d.ts +35 -0
- package/dist/run/study-files.js +164 -0
- package/dist/run/terminal-contract.d.ts +25 -0
- package/dist/run/terminal-contract.js +47 -0
- package/dist/run/text.d.ts +2 -0
- package/dist/run/text.js +4 -0
- package/dist/run/transient-comms-secrets.js +72 -0
- package/dist/run/type-guards.d.ts +6 -0
- package/dist/run/type-guards.js +18 -0
- package/dist/run-lab.d.ts +110 -0
- package/dist/run-lab.js +148 -0
- package/dist/subject/clone.d.ts +37 -0
- package/dist/subject/clone.js +62 -0
- package/dist/subject/desktop-cli.d.ts +17 -0
- package/dist/subject/desktop-cli.js +51 -0
- package/dist/subject/local-tree-archive.d.ts +82 -0
- package/dist/subject/local-tree-archive.js +431 -0
- package/dist/subject/local-tree.d.ts +28 -0
- package/dist/subject/local-tree.js +58 -0
- package/dist/subject/node-bootstrap.d.ts +12 -0
- package/dist/subject/node-bootstrap.js +66 -0
- package/dist/subject/runtime.d.ts +13 -0
- package/dist/subject/runtime.js +50 -0
- package/dist/subject/serve.d.ts +39 -0
- package/dist/subject/serve.js +249 -0
- package/dist/subject/state.d.ts +23 -0
- package/dist/subject/state.js +58 -0
- package/dist/subject/steps.d.ts +37 -0
- package/dist/subject/steps.js +39 -0
- package/dist/substrates/command-failure.d.ts +23 -0
- package/dist/substrates/command-failure.js +45 -0
- package/dist/substrates/desktop-session.d.ts +41 -0
- package/dist/substrates/desktop-session.js +59 -0
- package/dist/substrates/detached.d.ts +55 -0
- package/dist/substrates/detached.js +139 -0
- package/dist/substrates/e2b/cdp-probe.d.ts +99 -0
- package/dist/substrates/e2b/cdp-probe.js +556 -0
- package/dist/substrates/e2b/desktop-browser.d.ts +81 -0
- package/dist/substrates/e2b/desktop-browser.js +410 -0
- package/dist/substrates/e2b/desktop-cdp.d.ts +77 -0
- package/dist/substrates/e2b/desktop-cdp.js +211 -0
- package/dist/substrates/e2b/desktop-executor.d.ts +92 -0
- package/dist/substrates/e2b/desktop-executor.js +302 -0
- package/dist/substrates/e2b/desktop-geometry.d.ts +83 -0
- package/dist/substrates/e2b/desktop-geometry.js +331 -0
- package/dist/substrates/e2b/desktop-media.d.ts +29 -0
- package/dist/substrates/e2b/desktop-media.js +151 -0
- package/dist/substrates/e2b/desktop-recording.d.ts +18 -0
- package/dist/substrates/e2b/desktop-recording.js +238 -0
- package/dist/substrates/e2b/desktop-resources.d.ts +11 -0
- package/dist/substrates/e2b/desktop-resources.js +35 -0
- package/dist/substrates/e2b/desktop-screenshot-cleanup.d.ts +15 -0
- package/dist/substrates/e2b/desktop-screenshot-cleanup.js +66 -0
- package/dist/substrates/e2b/lifetime.d.ts +12 -0
- package/dist/substrates/e2b/lifetime.js +18 -0
- package/dist/substrates/e2b/sandbox.d.ts +102 -0
- package/dist/substrates/e2b/sandbox.js +202 -0
- package/dist/substrates/e2b/sdk.d.ts +194 -0
- package/dist/substrates/e2b/sdk.js +168 -0
- package/dist/substrates/e2b/shell.d.ts +10 -0
- package/dist/substrates/e2b/shell.js +61 -0
- package/dist/substrates/local/captured-inbox.d.ts +6 -0
- package/dist/substrates/local/captured-inbox.js +87 -0
- package/dist/substrates/local/firecracker-desktop.d.ts +25 -0
- package/dist/substrates/local/firecracker-desktop.js +315 -0
- package/dist/substrates/local/runtime-config.d.ts +6 -0
- package/dist/substrates/local/runtime-config.js +91 -0
- package/dist/substrates/local/runtime-host.d.ts +30 -0
- package/dist/substrates/local/runtime-host.js +143 -0
- package/dist/substrates/local/runtime-release.d.ts +5 -0
- package/dist/substrates/local/runtime-release.js +32 -0
- package/dist/substrates/local/runtime-ssh.d.ts +9 -0
- package/dist/substrates/local/runtime-ssh.js +129 -0
- package/dist/substrates/local/runtime.d.ts +25 -0
- package/dist/substrates/local/runtime.js +190 -0
- package/dist/substrates/shell.d.ts +44 -0
- package/dist/substrates/shell.js +22 -0
- package/dist/tui/actions.d.ts +39 -0
- package/dist/tui/actions.js +203 -0
- package/dist/tui/contract.d.ts +144 -0
- package/dist/tui/contract.js +52 -0
- package/dist/tui/launch.js +172 -0
- package/dist/tui/project.d.ts +10 -0
- package/dist/tui/project.js +17 -0
- package/dist/tui-app.js +125 -125
- package/dist/verify/actor.d.ts +27 -0
- package/dist/verify/actor.js +292 -0
- package/dist/verify/artifacts.d.ts +47 -0
- package/dist/verify/artifacts.js +373 -0
- package/dist/verify/costs.d.ts +30 -0
- package/dist/verify/costs.js +129 -0
- package/dist/verify/liveness.d.ts +7 -0
- package/dist/verify/liveness.js +72 -0
- package/dist/verify/rerun.d.ts +3 -0
- package/dist/verify/rerun.js +46 -0
- package/dist/verify/shared-world-concurrent.d.ts +11 -0
- package/dist/verify/shared-world-concurrent.js +346 -0
- package/dist/verify/shared-world.d.ts +8 -0
- package/dist/verify/shared-world.js +295 -0
- package/dist/verify/subject.d.ts +17 -0
- package/dist/verify/subject.js +123 -0
- package/dist/verify/verify.d.ts +34 -0
- package/dist/verify/verify.js +333 -0
- package/docs/README.md +67 -0
- package/docs/architecture/actor-contract.md +215 -174
- package/docs/architecture/browser-control.md +51 -37
- package/docs/architecture/comms-inbox.md +8 -8
- package/docs/architecture/desktop-recording.md +2 -2
- package/docs/architecture/desktop-sessions.md +33 -21
- package/docs/architecture/external-public-shared-world.md +80 -64
- package/docs/architecture/github-feedback-loop.md +40 -27
- package/docs/architecture/guest-desktop.md +22 -10
- package/docs/architecture/local-browser-runtime.md +30 -21
- package/docs/architecture/observer-review.md +9 -9
- package/docs/architecture/observer.md +53 -57
- package/docs/architecture/participant-media.md +3 -3
- package/docs/architecture/project-layout.md +33 -137
- package/docs/architecture/real-email-receiving.md +7 -6
- package/docs/architecture/restricted-codex-analysis.md +211 -25
- package/docs/architecture/serve.md +89 -87
- package/docs/architecture/state-driven-executor.md +79 -64
- package/docs/architecture/task-protocol-support.md +18 -18
- package/docs/architecture/terminal-product-lane.md +92 -86
- package/docs/contracts/adapter-admission.md +8 -4
- package/docs/contracts/adapter-fixtures.md +6 -6
- package/docs/contracts/core.md +22 -24
- package/docs/contracts/feedback.md +33 -23
- package/docs/contracts/policy.md +28 -31
- package/docs/contracts/run-bundle.md +168 -82
- package/docs/contracts/schemas.md +563 -379
- package/docs/contracts/study-analysis.md +2 -2
- package/docs/contracts/study-costs.md +12 -12
- package/docs/decisions/0001-run-bundle-is-the-source-of-truth.md +36 -0
- package/docs/decisions/0002-observer-is-one-self-contained-file.md +30 -0
- package/docs/decisions/0003-contained-paths-and-cleanup-authority.md +35 -0
- package/docs/decisions/0004-participant-desktops-stay-in-the-route.md +31 -0
- package/docs/decisions/README.md +16 -0
- package/docs/goals/current.md +22 -50
- package/docs/principles/actor-fidelity.md +37 -40
- package/docs/principles/engineering.md +81 -0
- package/docs/principles/invariants-and-defaults.md +48 -45
- package/docs/principles/self-driving-harness.md +11 -10
- package/docs/principles/three-roles.md +12 -13
- package/docs/product/automatic-analysis.md +39 -9
- package/docs/product/lobby-trivia-3player-external-public.md +14 -13
- package/docs/product/open-source-install-experience.md +34 -38
- package/docs/ramp/README.md +91 -218
- package/docs/release/open-source-readiness.md +5 -2
- package/docs/release/public-readiness-standard.md +1 -1
- package/examples/README.md +11 -0
- package/examples/participant/README.md +80 -0
- package/examples/participant/app.mjs +55 -0
- package/examples/participant/run.mjs +116 -0
- package/examples/scorer/README.md +29 -0
- package/examples/scorer/run.mjs +63 -0
- package/examples/scorer/scorer.mjs +20 -0
- package/package.json +61 -57
- package/skills/humanish/SKILL.md +72 -60
- package/skills/humanish/agents/openai.yaml +2 -2
- package/dist/actor-contract.d.ts +0 -296
- package/dist/actor-contract.js +0 -340
- package/dist/actor-contract.js.map +0 -1
- package/dist/actor-goal-source.js +0 -32
- package/dist/actor-goal-source.js.map +0 -1
- package/dist/actor-registry.d.ts +0 -77
- package/dist/actor-registry.js +0 -106
- package/dist/actor-registry.js.map +0 -1
- package/dist/actor-stop-cause.d.ts +0 -9
- package/dist/actor-stop-cause.js +0 -42
- package/dist/actor-stop-cause.js.map +0 -1
- package/dist/adapter-extension.d.ts +0 -76
- package/dist/adapter-extension.js +0 -273
- package/dist/adapter-extension.js.map +0 -1
- package/dist/adapter-scorer-loader.d.ts +0 -42
- package/dist/adapter-scorer-loader.js +0 -129
- package/dist/adapter-scorer-loader.js.map +0 -1
- package/dist/affordance.d.ts +0 -53
- package/dist/affordance.js +0 -145
- package/dist/affordance.js.map +0 -1
- package/dist/agent-session.js +0 -43
- package/dist/agent-session.js.map +0 -1
- package/dist/argv.d.ts +0 -1
- package/dist/argv.js +0 -8
- package/dist/argv.js.map +0 -1
- package/dist/artifact-reference.d.ts +0 -22
- package/dist/artifact-reference.js +0 -47
- package/dist/artifact-reference.js.map +0 -1
- package/dist/automatic-analysis-completion.d.ts +0 -25
- package/dist/automatic-analysis-completion.js +0 -56
- package/dist/automatic-analysis-completion.js.map +0 -1
- package/dist/automatic-analysis-config.d.ts +0 -38
- package/dist/automatic-analysis-config.js +0 -68
- package/dist/automatic-analysis-config.js.map +0 -1
- package/dist/automatic-study-analysis.d.ts +0 -17
- package/dist/automatic-study-analysis.js +0 -195
- package/dist/automatic-study-analysis.js.map +0 -1
- package/dist/browser-control-client.d.ts +0 -18
- package/dist/browser-control-client.js +0 -176
- package/dist/browser-control-client.js.map +0 -1
- package/dist/browser-control-dispatcher.d.ts +0 -19
- package/dist/browser-control-dispatcher.js +0 -147
- package/dist/browser-control-dispatcher.js.map +0 -1
- package/dist/browser-control-protocol.d.ts +0 -472
- package/dist/browser-control-protocol.js +0 -185
- package/dist/browser-control-protocol.js.map +0 -1
- package/dist/browser-control-recording-transfer.d.ts +0 -4
- package/dist/browser-control-recording-transfer.js +0 -42
- package/dist/browser-control-recording-transfer.js.map +0 -1
- package/dist/browser-control-transport.d.ts +0 -27
- package/dist/browser-control-transport.js +0 -177
- package/dist/browser-control-transport.js.map +0 -1
- package/dist/browser-evidence-hygiene.js +0 -43
- package/dist/browser-evidence-hygiene.js.map +0 -1
- package/dist/chrome-cdp-probe.d.ts +0 -97
- package/dist/chrome-cdp-probe.js +0 -536
- package/dist/chrome-cdp-probe.js.map +0 -1
- package/dist/claude-agent-sdk.d.ts +0 -94
- package/dist/claude-agent-sdk.js +0 -367
- package/dist/claude-agent-sdk.js.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/codex-app-server-ui.d.ts +0 -39
- package/dist/codex-app-server-ui.js +0 -357
- package/dist/codex-app-server-ui.js.map +0 -1
- package/dist/codex-app-server.d.ts +0 -144
- package/dist/codex-app-server.js +0 -754
- package/dist/codex-app-server.js.map +0 -1
- package/dist/command-failure.d.ts +0 -43
- package/dist/command-failure.js +0 -73
- package/dist/command-failure.js.map +0 -1
- package/dist/comms-agentmail.d.ts +0 -25
- package/dist/comms-agentmail.js +0 -418
- package/dist/comms-agentmail.js.map +0 -1
- package/dist/comms-catch-host.d.ts +0 -52
- package/dist/comms-catch-host.js +0 -178
- package/dist/comms-catch-host.js.map +0 -1
- package/dist/comms-connections.d.ts +0 -52
- package/dist/comms-connections.js +0 -123
- package/dist/comms-connections.js.map +0 -1
- package/dist/comms-email-catch.d.ts +0 -54
- package/dist/comms-email-catch.js +0 -212
- package/dist/comms-email-catch.js.map +0 -1
- package/dist/comms-evidence.d.ts +0 -27
- package/dist/comms-evidence.js +0 -31
- package/dist/comms-evidence.js.map +0 -1
- package/dist/comms-fake-inbox.d.ts +0 -45
- package/dist/comms-fake-inbox.js +0 -184
- package/dist/comms-fake-inbox.js.map +0 -1
- package/dist/comms-images.d.ts +0 -7
- package/dist/comms-images.js +0 -39
- package/dist/comms-images.js.map +0 -1
- package/dist/comms-inbox.d.ts +0 -66
- package/dist/comms-inbox.js +0 -389
- package/dist/comms-inbox.js.map +0 -1
- package/dist/comms-lease-store.d.ts +0 -91
- package/dist/comms-lease-store.js +0 -495
- package/dist/comms-lease-store.js.map +0 -1
- package/dist/comms-receiving-evidence.d.ts +0 -46
- package/dist/comms-receiving-evidence.js +0 -35
- package/dist/comms-receiving-evidence.js.map +0 -1
- package/dist/comms-receiving-inbox.d.ts +0 -16
- package/dist/comms-receiving-inbox.js +0 -410
- package/dist/comms-receiving-inbox.js.map +0 -1
- package/dist/comms-receiving-runtime.d.ts +0 -25
- package/dist/comms-receiving-runtime.js +0 -45
- package/dist/comms-receiving-runtime.js.map +0 -1
- package/dist/comms-receiving-types.d.ts +0 -98
- package/dist/comms-receiving-types.js +0 -2
- package/dist/comms-receiving-types.js.map +0 -1
- package/dist/comms-receiving.d.ts +0 -58
- package/dist/comms-receiving.js +0 -554
- package/dist/comms-receiving.js.map +0 -1
- package/dist/comms-sandbox-catch.d.ts +0 -229
- package/dist/comms-sandbox-catch.js +0 -737
- package/dist/comms-sandbox-catch.js.map +0 -1
- package/dist/comms-setup.d.ts +0 -40
- package/dist/comms-setup.js +0 -121
- package/dist/comms-setup.js.map +0 -1
- package/dist/comms-types.d.ts +0 -72
- package/dist/comms-types.js +0 -10
- package/dist/comms-types.js.map +0 -1
- package/dist/computer-use-actor.d.ts +0 -76
- package/dist/computer-use-actor.js +0 -68
- package/dist/computer-use-actor.js.map +0 -1
- package/dist/computer-use.d.ts +0 -429
- package/dist/computer-use.js +0 -1751
- package/dist/computer-use.js.map +0 -1
- package/dist/concurrency.js +0 -27
- package/dist/concurrency.js.map +0 -1
- package/dist/concurrent-shared-world-lab.d.ts +0 -186
- package/dist/concurrent-shared-world-lab.js +0 -2181
- package/dist/concurrent-shared-world-lab.js.map +0 -1
- package/dist/core/git-state.d.ts +0 -33
- package/dist/core/git-state.js +0 -277
- package/dist/core/git-state.js.map +0 -1
- package/dist/core/git-workspace.d.ts +0 -31
- package/dist/core/git-workspace.js +0 -447
- package/dist/core/git-workspace.js.map +0 -1
- package/dist/core/index.d.ts +0 -4
- package/dist/core/index.js +0 -3
- package/dist/core/index.js.map +0 -1
- package/dist/core/run-primitives.d.ts +0 -66
- package/dist/core/run-primitives.js +0 -120
- package/dist/core/run-primitives.js.map +0 -1
- package/dist/cua-actor-lab.d.ts +0 -855
- package/dist/cua-actor-lab.js +0 -3543
- package/dist/cua-actor-lab.js.map +0 -1
- package/dist/cua-admission-limit.d.ts +0 -12
- package/dist/cua-admission-limit.js +0 -20
- package/dist/cua-admission-limit.js.map +0 -1
- package/dist/cua-desktop-lane.d.ts +0 -35
- package/dist/cua-desktop-lane.js +0 -13
- package/dist/cua-desktop-lane.js.map +0 -1
- package/dist/cua-diagnostics.d.ts +0 -38
- package/dist/cua-diagnostics.js +0 -68
- package/dist/cua-diagnostics.js.map +0 -1
- package/dist/cua-executor-error.js +0 -48
- package/dist/cua-executor-error.js.map +0 -1
- package/dist/cua-provider-error.d.ts +0 -16
- package/dist/cua-provider-error.js +0 -35
- package/dist/cua-provider-error.js.map +0 -1
- package/dist/cua-speech.js +0 -2
- package/dist/cua-speech.js.map +0 -1
- package/dist/desktop-recorder.d.ts +0 -39
- package/dist/desktop-recorder.js +0 -226
- package/dist/desktop-recorder.js.map +0 -1
- package/dist/desktop-recording-artifact.d.ts +0 -5
- package/dist/desktop-recording-artifact.js +0 -54
- package/dist/desktop-recording-artifact.js.map +0 -1
- package/dist/desktop-recording-types.d.ts +0 -24
- package/dist/desktop-recording-types.js +0 -14
- package/dist/desktop-recording-types.js.map +0 -1
- package/dist/desktop-session.d.ts +0 -41
- package/dist/desktop-session.js +0 -47
- package/dist/desktop-session.js.map +0 -1
- package/dist/device-presets.d.ts +0 -67
- package/dist/device-presets.js +0 -55
- package/dist/device-presets.js.map +0 -1
- package/dist/doctor-lab.d.ts +0 -38
- package/dist/doctor-lab.js +0 -126
- package/dist/doctor-lab.js.map +0 -1
- package/dist/e2b-cua-desktop.d.ts +0 -3
- package/dist/e2b-cua-desktop.js +0 -708
- package/dist/e2b-cua-desktop.js.map +0 -1
- package/dist/e2b-cua-provisioning.d.ts +0 -314
- package/dist/e2b-cua-provisioning.js +0 -1219
- package/dist/e2b-cua-provisioning.js.map +0 -1
- package/dist/e2b-desktop-executor.d.ts +0 -101
- package/dist/e2b-desktop-executor.js +0 -297
- package/dist/e2b-desktop-executor.js.map +0 -1
- package/dist/e2b-desktop-launch.d.ts +0 -243
- package/dist/e2b-desktop-launch.js +0 -234
- package/dist/e2b-desktop-launch.js.map +0 -1
- package/dist/e2b-desktop-media.d.ts +0 -14
- package/dist/e2b-desktop-media.js +0 -58
- package/dist/e2b-desktop-media.js.map +0 -1
- package/dist/e2b-desktop-recording.d.ts +0 -16
- package/dist/e2b-desktop-recording.js +0 -162
- package/dist/e2b-desktop-recording.js.map +0 -1
- package/dist/e2b-desktop-resources.d.ts +0 -11
- package/dist/e2b-desktop-resources.js +0 -33
- package/dist/e2b-desktop-resources.js.map +0 -1
- package/dist/e2b-desktop-screenshot-cleanup.d.ts +0 -15
- package/dist/e2b-desktop-screenshot-cleanup.js +0 -67
- package/dist/e2b-desktop-screenshot-cleanup.js.map +0 -1
- package/dist/e2b-desktop-session.d.ts +0 -7
- package/dist/e2b-desktop-session.js +0 -29
- package/dist/e2b-desktop-session.js.map +0 -1
- package/dist/e2b-detached.d.ts +0 -53
- package/dist/e2b-detached.js +0 -130
- package/dist/e2b-detached.js.map +0 -1
- package/dist/e2b-terminal-lab.d.ts +0 -383
- package/dist/e2b-terminal-lab.js +0 -2000
- package/dist/e2b-terminal-lab.js.map +0 -1
- package/dist/env-file.d.ts +0 -14
- package/dist/env-file.js +0 -108
- package/dist/env-file.js.map +0 -1
- package/dist/export-bundle.d.ts +0 -7
- package/dist/export-bundle.js +0 -441
- package/dist/export-bundle.js.map +0 -1
- package/dist/export.d.ts +0 -49
- package/dist/export.js +0 -308
- package/dist/export.js.map +0 -1
- package/dist/feedback-proof.d.ts +0 -8
- package/dist/feedback-proof.js +0 -44
- package/dist/feedback-proof.js.map +0 -1
- package/dist/feedback.d.ts +0 -76
- package/dist/feedback.js +0 -496
- package/dist/feedback.js.map +0 -1
- package/dist/first-run-path.d.ts +0 -55
- package/dist/first-run-path.js +0 -136
- package/dist/first-run-path.js.map +0 -1
- package/dist/frame-signature.d.ts +0 -24
- package/dist/frame-signature.js +0 -128
- package/dist/frame-signature.js.map +0 -1
- package/dist/guest-bootstrap.d.ts +0 -55
- package/dist/guest-bootstrap.js +0 -285
- package/dist/guest-bootstrap.js.map +0 -1
- package/dist/guest-browser-tools.d.ts +0 -8
- package/dist/guest-browser-tools.js +0 -66
- package/dist/guest-browser-tools.js.map +0 -1
- package/dist/guest-chromium-text.d.ts +0 -27
- package/dist/guest-chromium-text.js +0 -281
- package/dist/guest-chromium-text.js.map +0 -1
- package/dist/guest-desktop-executor.d.ts +0 -22
- package/dist/guest-desktop-executor.js +0 -178
- package/dist/guest-desktop-executor.js.map +0 -1
- package/dist/guest-desktop-media.d.ts +0 -33
- package/dist/guest-desktop-media.js +0 -281
- package/dist/guest-desktop-media.js.map +0 -1
- package/dist/guest-desktop-native.d.ts +0 -14
- package/dist/guest-desktop-native.js +0 -131
- package/dist/guest-desktop-native.js.map +0 -1
- package/dist/guest-media-config.d.ts +0 -15
- package/dist/guest-media-config.js +0 -8
- package/dist/guest-media-config.js.map +0 -1
- package/dist/guest-media-worker.js.map +0 -1
- package/dist/guest-runtime-desktop.d.ts +0 -42
- package/dist/guest-runtime-desktop.js +0 -314
- package/dist/guest-runtime-desktop.js.map +0 -1
- package/dist/guest-runtime-main.js.map +0 -1
- package/dist/guest-runtime-revision.js.map +0 -1
- package/dist/guest-runtime.d.ts +0 -31
- package/dist/guest-runtime.js +0 -99
- package/dist/guest-runtime.js.map +0 -1
- package/dist/image-evidence.d.ts +0 -2
- package/dist/image-evidence.js +0 -47
- package/dist/image-evidence.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/init-templates.d.ts +0 -25
- package/dist/init-templates.js +0 -541
- package/dist/init-templates.js.map +0 -1
- package/dist/init.d.ts +0 -38
- package/dist/init.js +0 -532
- package/dist/init.js.map +0 -1
- package/dist/key-resolution.d.ts +0 -67
- package/dist/key-resolution.js +0 -375
- package/dist/key-resolution.js.map +0 -1
- package/dist/lab-app-runner.d.ts +0 -78
- package/dist/lab-app-runner.js +0 -403
- package/dist/lab-app-runner.js.map +0 -1
- package/dist/lab-config.d.ts +0 -968
- package/dist/lab-config.js +0 -2714
- package/dist/lab-config.js.map +0 -1
- package/dist/lab-engine.d.ts +0 -97
- package/dist/lab-engine.js +0 -285
- package/dist/lab-engine.js.map +0 -1
- package/dist/lab-preflight.d.ts +0 -70
- package/dist/lab-preflight.js +0 -388
- package/dist/lab-preflight.js.map +0 -1
- package/dist/lab-summary.d.ts +0 -57
- package/dist/lab-summary.js +0 -126
- package/dist/lab-summary.js.map +0 -1
- package/dist/labs.d.ts +0 -66
- package/dist/labs.js +0 -401
- package/dist/labs.js.map +0 -1
- package/dist/listen.js +0 -84
- package/dist/listen.js.map +0 -1
- package/dist/local-agent-claude-session.d.ts +0 -45
- package/dist/local-agent-claude-session.js +0 -203
- package/dist/local-agent-claude-session.js.map +0 -1
- package/dist/local-agent-cli.d.ts +0 -121
- package/dist/local-agent-cli.js +0 -427
- package/dist/local-agent-cli.js.map +0 -1
- package/dist/local-captured-inbox.d.ts +0 -6
- package/dist/local-captured-inbox.js +0 -65
- package/dist/local-captured-inbox.js.map +0 -1
- package/dist/local-firecracker-desktop.d.ts +0 -23
- package/dist/local-firecracker-desktop.js +0 -191
- package/dist/local-firecracker-desktop.js.map +0 -1
- package/dist/local-firecracker-study.d.ts +0 -9
- package/dist/local-firecracker-study.js +0 -135
- package/dist/local-firecracker-study.js.map +0 -1
- package/dist/local-runtime-config.d.ts +0 -6
- package/dist/local-runtime-config.js +0 -60
- package/dist/local-runtime-config.js.map +0 -1
- package/dist/local-runtime-host.d.ts +0 -31
- package/dist/local-runtime-host.js +0 -128
- package/dist/local-runtime-host.js.map +0 -1
- package/dist/local-runtime-release.d.ts +0 -7
- package/dist/local-runtime-release.js +0 -33
- package/dist/local-runtime-release.js.map +0 -1
- package/dist/local-runtime-ssh.d.ts +0 -27
- package/dist/local-runtime-ssh.js +0 -91
- package/dist/local-runtime-ssh.js.map +0 -1
- package/dist/local-runtime.d.ts +0 -25
- package/dist/local-runtime.js +0 -133
- package/dist/local-runtime.js.map +0 -1
- package/dist/observer-data.d.ts +0 -114
- package/dist/observer-data.js +0 -224
- package/dist/observer-data.js.map +0 -1
- package/dist/observer-library.js +0 -191
- package/dist/observer-library.js.map +0 -1
- package/dist/observer-serve.d.ts +0 -99
- package/dist/observer-serve.js +0 -284
- package/dist/observer-serve.js.map +0 -1
- package/dist/observer-static.js +0 -357
- package/dist/observer-static.js.map +0 -1
- package/dist/observer.d.ts +0 -118
- package/dist/observer.js +0 -947
- package/dist/observer.js.map +0 -1
- package/dist/openai-responses-cu.d.ts +0 -158
- package/dist/openai-responses-cu.js +0 -714
- package/dist/openai-responses-cu.js.map +0 -1
- package/dist/orientation.d.ts +0 -29
- package/dist/orientation.js +0 -95
- package/dist/orientation.js.map +0 -1
- package/dist/oss-lab.d.ts +0 -55
- package/dist/oss-lab.js +0 -344
- package/dist/oss-lab.js.map +0 -1
- package/dist/oss-meta-lab-scoring.d.ts +0 -15
- package/dist/oss-meta-lab-scoring.js +0 -145
- package/dist/oss-meta-lab-scoring.js.map +0 -1
- package/dist/oss-meta-lab.d.ts +0 -287
- package/dist/oss-meta-lab.js +0 -4551
- package/dist/oss-meta-lab.js.map +0 -1
- package/dist/oss-remote-telemetry.d.ts +0 -77
- package/dist/oss-remote-telemetry.js +0 -403
- package/dist/oss-remote-telemetry.js.map +0 -1
- package/dist/output-token-limit.js +0 -5
- package/dist/output-token-limit.js.map +0 -1
- package/dist/participant-assignment.d.ts +0 -12
- package/dist/participant-assignment.js +0 -15
- package/dist/participant-assignment.js.map +0 -1
- package/dist/persona-resolve.d.ts +0 -44
- package/dist/persona-resolve.js +0 -99
- package/dist/persona-resolve.js.map +0 -1
- package/dist/persona.d.ts +0 -39
- package/dist/persona.js +0 -144
- package/dist/persona.js.map +0 -1
- package/dist/pi-agent-core.d.ts +0 -77
- package/dist/pi-agent-core.js +0 -207
- package/dist/pi-agent-core.js.map +0 -1
- package/dist/pricing.d.ts +0 -145
- package/dist/pricing.js +0 -277
- package/dist/pricing.js.map +0 -1
- package/dist/program.d.ts +0 -96
- package/dist/program.js +0 -4030
- package/dist/program.js.map +0 -1
- package/dist/reasoning-effort.js +0 -26
- package/dist/reasoning-effort.js.map +0 -1
- package/dist/reclaim.d.ts +0 -31
- package/dist/reclaim.js +0 -90
- package/dist/reclaim.js.map +0 -1
- package/dist/redaction.d.ts +0 -90
- package/dist/redaction.js +0 -294
- package/dist/redaction.js.map +0 -1
- package/dist/restricted-codex-analysis.d.ts +0 -15
- package/dist/restricted-codex-analysis.js +0 -13
- package/dist/restricted-codex-analysis.js.map +0 -1
- package/dist/restricted-codex-participant-policy.d.ts +0 -44
- package/dist/restricted-codex-participant-policy.js +0 -43
- package/dist/restricted-codex-participant-policy.js.map +0 -1
- package/dist/restricted-codex-participant-run.d.ts +0 -20
- package/dist/restricted-codex-participant-run.js +0 -79
- package/dist/restricted-codex-participant-run.js.map +0 -1
- package/dist/restricted-codex-participant.d.ts +0 -20
- package/dist/restricted-codex-participant.js +0 -250
- package/dist/restricted-codex-participant.js.map +0 -1
- package/dist/restricted-codex-policy.d.ts +0 -64
- package/dist/restricted-codex-policy.js +0 -176
- package/dist/restricted-codex-policy.js.map +0 -1
- package/dist/restricted-codex-session.d.ts +0 -44
- package/dist/restricted-codex-session.js +0 -657
- package/dist/restricted-codex-session.js.map +0 -1
- package/dist/restricted-codex-transport.d.ts +0 -69
- package/dist/restricted-codex-transport.js +0 -296
- package/dist/restricted-codex-transport.js.map +0 -1
- package/dist/run-detail.d.ts +0 -61
- package/dist/run-detail.js +0 -137
- package/dist/run-detail.js.map +0 -1
- package/dist/run-index.d.ts +0 -71
- package/dist/run-index.js +0 -206
- package/dist/run-index.js.map +0 -1
- package/dist/run-narration-secrets.js +0 -68
- package/dist/run-narration-secrets.js.map +0 -1
- package/dist/run-paths.d.ts +0 -56
- package/dist/run-paths.js +0 -355
- package/dist/run-paths.js.map +0 -1
- package/dist/run-projection.d.ts +0 -186
- package/dist/run-projection.js +0 -350
- package/dist/run-projection.js.map +0 -1
- package/dist/run-status.d.ts +0 -139
- package/dist/run-status.js +0 -218
- package/dist/run-status.js.map +0 -1
- package/dist/run.d.ts +0 -1255
- package/dist/run.js +0 -5949
- package/dist/run.js.map +0 -1
- package/dist/sandbox-receipts.d.ts +0 -19
- package/dist/sandbox-receipts.js +0 -51
- package/dist/sandbox-receipts.js.map +0 -1
- package/dist/screenshot-image.d.ts +0 -11
- package/dist/screenshot-image.js +0 -26
- package/dist/screenshot-image.js.map +0 -1
- package/dist/scripted-browser-actor.d.ts +0 -297
- package/dist/scripted-browser-actor.js +0 -1399
- package/dist/scripted-browser-actor.js.map +0 -1
- package/dist/scripted-browser-lab.d.ts +0 -121
- package/dist/scripted-browser-lab.js +0 -852
- package/dist/scripted-browser-lab.js.map +0 -1
- package/dist/secret-prompt.js +0 -36
- package/dist/secret-prompt.js.map +0 -1
- package/dist/selected-output-paths.d.ts +0 -52
- package/dist/selected-output-paths.js +0 -366
- package/dist/selected-output-paths.js.map +0 -1
- package/dist/serve-exposure.d.ts +0 -62
- package/dist/serve-exposure.js +0 -129
- package/dist/serve-exposure.js.map +0 -1
- package/dist/serve-http.js +0 -45
- package/dist/serve-http.js.map +0 -1
- package/dist/serve-tunnel.js +0 -113
- package/dist/serve-tunnel.js.map +0 -1
- package/dist/shared-world-lab.d.ts +0 -269
- package/dist/shared-world-lab.js +0 -1424
- package/dist/shared-world-lab.js.map +0 -1
- package/dist/source-archive.d.ts +0 -82
- package/dist/source-archive.js +0 -408
- package/dist/source-archive.js.map +0 -1
- package/dist/stats.d.ts +0 -82
- package/dist/stats.js +0 -219
- package/dist/stats.js.map +0 -1
- package/dist/stop-conditions.d.ts +0 -39
- package/dist/stop-conditions.js +0 -66
- package/dist/stop-conditions.js.map +0 -1
- package/dist/study-analysis-codex-config.d.ts +0 -11
- package/dist/study-analysis-codex-config.js +0 -34
- package/dist/study-analysis-codex-config.js.map +0 -1
- package/dist/study-analysis-engine.d.ts +0 -47
- package/dist/study-analysis-engine.js +0 -327
- package/dist/study-analysis-engine.js.map +0 -1
- package/dist/study-analysis-evidence.d.ts +0 -27
- package/dist/study-analysis-evidence.js +0 -660
- package/dist/study-analysis-evidence.js.map +0 -1
- package/dist/study-analysis-job.d.ts +0 -97
- package/dist/study-analysis-job.js +0 -214
- package/dist/study-analysis-job.js.map +0 -1
- package/dist/study-analysis-provider.d.ts +0 -40
- package/dist/study-analysis-provider.js +0 -170
- package/dist/study-analysis-provider.js.map +0 -1
- package/dist/study-analysis-service.d.ts +0 -59
- package/dist/study-analysis-service.js +0 -257
- package/dist/study-analysis-service.js.map +0 -1
- package/dist/study-analysis-sharing.d.ts +0 -11
- package/dist/study-analysis-sharing.js +0 -35
- package/dist/study-analysis-sharing.js.map +0 -1
- package/dist/study-analysis-store.d.ts +0 -47
- package/dist/study-analysis-store.js +0 -493
- package/dist/study-analysis-store.js.map +0 -1
- package/dist/study-analysis-validation.d.ts +0 -618
- package/dist/study-analysis-validation.js +0 -384
- package/dist/study-analysis-validation.js.map +0 -1
- package/dist/study-analysis.d.ts +0 -206
- package/dist/study-analysis.js +0 -4
- package/dist/study-analysis.js.map +0 -1
- package/dist/study-costs.js +0 -114
- package/dist/study-costs.js.map +0 -1
- package/dist/subject-runtime.d.ts +0 -23
- package/dist/subject-runtime.js +0 -70
- package/dist/subject-runtime.js.map +0 -1
- package/dist/tasks.d.ts +0 -90
- package/dist/tasks.js +0 -144
- package/dist/tasks.js.map +0 -1
- package/dist/telemetry.js +0 -324
- package/dist/telemetry.js.map +0 -1
- package/dist/terminal-agent-actor.d.ts +0 -41
- package/dist/terminal-agent-actor.js +0 -25
- package/dist/terminal-agent-actor.js.map +0 -1
- package/dist/terminal-encoding.js +0 -80
- package/dist/terminal-encoding.js.map +0 -1
- package/dist/terminal-node-bootstrap.d.ts +0 -4
- package/dist/terminal-node-bootstrap.js +0 -58
- package/dist/terminal-node-bootstrap.js.map +0 -1
- package/dist/terminal-participant-activity.d.ts +0 -6
- package/dist/terminal-participant-activity.js +0 -34
- package/dist/terminal-participant-activity.js.map +0 -1
- package/dist/terminal-runtime-auth.d.ts +0 -13
- package/dist/terminal-runtime-auth.js +0 -24
- package/dist/terminal-runtime-auth.js.map +0 -1
- package/dist/terminal-runtime.d.ts +0 -16
- package/dist/terminal-runtime.js +0 -42
- package/dist/terminal-runtime.js.map +0 -1
- package/dist/terminal-token-usage.d.ts +0 -15
- package/dist/terminal-token-usage.js +0 -94
- package/dist/terminal-token-usage.js.map +0 -1
- package/dist/tui-actions.d.ts +0 -39
- package/dist/tui-actions.js +0 -178
- package/dist/tui-actions.js.map +0 -1
- package/dist/tui-contract.d.ts +0 -141
- package/dist/tui-contract.js +0 -54
- package/dist/tui-contract.js.map +0 -1
- package/dist/tui-launch.js +0 -167
- package/dist/tui-launch.js.map +0 -1
- package/dist/tui-project.d.ts +0 -9
- package/dist/tui-project.js +0 -18
- package/dist/tui-project.js.map +0 -1
- package/docs/architecture/examples/state-driven-local-app/README.md +0 -80
- package/docs/architecture/examples/state-driven-local-app/app.mjs +0 -48
- package/docs/architecture/examples/state-driven-local-app/runner.mjs +0 -105
- package/docs/architecture/local-codex-tui-actor.md +0 -213
- package/docs/architecture/oss-lab-poc.md +0 -250
- package/docs/architecture/runtime-broker-core.md +0 -30
- package/docs/release/0.100.0-local-setup.md +0 -31
- package/docs/release/0.100.1-participant-continuity.md +0 -20
- package/docs/release/0.101.0-codex-ui-tools.md +0 -28
- package/docs/release/0.102.0-participant-media.md +0 -43
- package/docs/release/0.103.0-desktop-recording.md +0 -29
- package/docs/release/0.103.1-analysis-capture-allocation.md +0 -18
- package/docs/release/0.103.2-analysis-ending-context.md +0 -21
- package/docs/release/0.104.0-local-captured-inboxes.md +0 -29
- package/docs/release/0.104.1-recording-startup.md +0 -24
- package/docs/release/0.104.2-recording-timestamps.md +0 -32
- package/docs/release/0.104.3-local-smtp-catch.md +0 -15
- package/docs/release/0.105.0-participant-backgrounds.md +0 -50
- package/docs/release/0.20.0-external-public-shared-world.md +0 -43
- package/docs/release/0.84.0-redacted-evidence.md +0 -42
- package/docs/release/0.84.1-portable-feedback.md +0 -20
- package/docs/release/0.85.0-observer-review.md +0 -56
- package/docs/release/0.85.1-observer-continuity.md +0 -20
- package/docs/release/0.86.0-participant-evidence.md +0 -50
- package/docs/release/0.86.1-task-preflight-saved-recordings.md +0 -40
- package/docs/release/0.87.0-participant-endings-and-phone-review.md +0 -64
- package/docs/release/0.88.0-study-diagnostics.md +0 -43
- package/docs/release/0.88.1-completion-evidence-and-local-app.md +0 -79
- package/docs/release/0.88.2-sequential-study-budgets.md +0 -57
- package/docs/release/0.89.0-study-findings.md +0 -79
- package/docs/release/0.89.1-analysis-finished-notice.md +0 -24
- package/docs/release/0.90.0-automatic-analysis.md +0 -21
- package/docs/release/0.91.0-analysis-quality-and-defaults.md +0 -33
- package/docs/release/0.91.1-study-review-polish.md +0 -28
- package/docs/release/0.92.0-grid-playback.md +0 -22
- package/docs/release/0.93.0-global-playback.md +0 -26
- package/docs/release/0.93.1-observer-review-controls.md +0 -24
- package/docs/release/0.94.0-reliability.md +0 -48
- package/docs/release/0.95.0-connections-setup.md +0 -38
- package/docs/release/0.96.0-real-email-receiving.md +0 -47
- package/docs/release/0.96.1-browser-navigation.md +0 -22
- package/docs/release/0.97.0-codex-account-analysis.md +0 -45
- package/docs/release/0.98.0-local-browser-studies.md +0 -31
- package/docs/release/0.99.0-local-browser-mac.md +0 -34
- package/docs/release/0.99.1-action-recovery.md +0 -19
- /package/dist/{agent-session.d.ts → actors/agent-session.d.ts} +0 -0
- /package/dist/{cua-executor-error.d.ts → actors/computer-use/executor-error.d.ts} +0 -0
- /package/dist/{cua-speech.d.ts → actors/computer-use/speech.d.ts} +0 -0
- /package/dist/{actor-goal-source.d.ts → actors/goal-source.d.ts} +0 -0
- /package/dist/{output-token-limit.d.ts → actors/output-token-limit.d.ts} +0 -0
- /package/dist/{reasoning-effort.d.ts → actors/reasoning-effort.d.ts} +0 -0
- /package/dist/{secret-prompt.d.ts → cli/secret-prompt.d.ts} +0 -0
- /package/dist/{telemetry.d.ts → cli/telemetry.d.ts} +0 -0
- /package/dist/{browser-evidence-hygiene.d.ts → evidence/browser-hygiene.d.ts} +0 -0
- /package/dist/{serve-http.d.ts → observer/http.d.ts} +0 -0
- /package/dist/{observer-library.d.ts → observer/library.d.ts} +0 -0
- /package/dist/{listen.d.ts → observer/listen.d.ts} +0 -0
- /package/dist/{observer-static.d.ts → observer/static.d.ts} +0 -0
- /package/dist/{serve-tunnel.d.ts → observer/tunnel.d.ts} +0 -0
- /package/dist/{terminal-encoding.d.ts → routes/terminal/encoding.d.ts} +0 -0
- /package/dist/{concurrency.d.ts → run/concurrency.d.ts} +0 -0
- /package/dist/{study-costs.d.ts → run/costs.d.ts} +0 -0
- /package/dist/{run-narration-secrets.d.ts → run/transient-comms-secrets.d.ts} +0 -0
- /package/dist/{tui-launch.d.ts → tui/launch.d.ts} +0 -0
package/dist/computer-use.js
DELETED
|
@@ -1,1751 +0,0 @@
|
|
|
1
|
-
import { CUA_SPEECH_LIMITS } from "./cua-speech.js";
|
|
2
|
-
export { CUA_SPEECH_LIMITS } from "./cua-speech.js";
|
|
3
|
-
import { ACTOR_TRACE_SCHEMA } from "./actor-contract.js";
|
|
4
|
-
import { CuaProviderError, isCuaProviderError } from "./cua-provider-error.js";
|
|
5
|
-
import { classifyCuaAction, summarizeAffordanceUse } from "./affordance.js";
|
|
6
|
-
import { commandFailureInfo, isCommandExitError } from "./command-failure.js";
|
|
7
|
-
import { evaluateStopWhen } from "./stop-conditions.js";
|
|
8
|
-
import { TaskTracker } from "./tasks.js";
|
|
9
|
-
import { isCuaAdmissionLimitError } from "./cua-admission-limit.js";
|
|
10
|
-
import { CuaExecutorError, isCuaExecutorError } from "./cua-executor-error.js";
|
|
11
|
-
export const CUA_PROVIDER_CLEANUP_GRACE_MS = 5000;
|
|
12
|
-
/** Runtime validation is also required for third-party provider ports. */
|
|
13
|
-
export function validClosingReport(value) {
|
|
14
|
-
if (value === null || typeof value !== "object" || Array.isArray(value))
|
|
15
|
-
return false;
|
|
16
|
-
const report = value;
|
|
17
|
-
return Object.keys(report).length === 2
|
|
18
|
-
&& typeof report.summary === "string" && report.summary.trim().length > 0 && report.summary.length <= 4_000
|
|
19
|
-
&& Array.isArray(report.frictionReports) && report.frictionReports.length <= 8
|
|
20
|
-
&& report.frictionReports.every((item) => typeof item === "string" && item.trim().length > 0 && item.length <= 2_000);
|
|
21
|
-
}
|
|
22
|
-
function validTokenCount(value) {
|
|
23
|
-
return typeof value === "number" && Number.isSafeInteger(value) && value >= 0;
|
|
24
|
-
}
|
|
25
|
-
function normalizedUsageTurns(usage) {
|
|
26
|
-
if (!Array.isArray(usage.turns) || usage.turns.length === 0)
|
|
27
|
-
return undefined;
|
|
28
|
-
const fields = ["input", "output", "cachedInput", "cacheWriteInput"];
|
|
29
|
-
const turns = [];
|
|
30
|
-
for (const raw of usage.turns) {
|
|
31
|
-
if (!raw || typeof raw !== "object" || Array.isArray(raw))
|
|
32
|
-
return undefined;
|
|
33
|
-
if (fields.every(field => raw[field] === undefined) || fields.some(field => raw[field] !== undefined && !validTokenCount(raw[field])))
|
|
34
|
-
return undefined;
|
|
35
|
-
if ((raw.cachedInput ?? 0) + (raw.cacheWriteInput ?? 0) > (raw.input ?? 0))
|
|
36
|
-
return undefined;
|
|
37
|
-
turns.push(Object.fromEntries(fields.flatMap(field => raw[field] === undefined ? [] : [[field, raw[field]]])));
|
|
38
|
-
}
|
|
39
|
-
return fields.every(field => turns.reduce((sum, turn) => sum + (turn[field] ?? 0), 0) === (usage[field] ?? 0))
|
|
40
|
-
? turns : undefined;
|
|
41
|
-
}
|
|
42
|
-
function completeTurnUsage(usage) {
|
|
43
|
-
return usage !== undefined && validTokenCount(usage.input) && validTokenCount(usage.output)
|
|
44
|
-
&& (usage.cachedInput === undefined || validTokenCount(usage.cachedInput))
|
|
45
|
-
&& (usage.cacheWriteInput === undefined || validTokenCount(usage.cacheWriteInput))
|
|
46
|
-
&& (usage.cachedInput ?? 0) + (usage.cacheWriteInput ?? 0) <= usage.input
|
|
47
|
-
&& (usage.turns === undefined || normalizedUsageTurns(usage) !== undefined);
|
|
48
|
-
}
|
|
49
|
-
// Waiting is a legitimate strategy, not idleness. A persona told to sign up and verify by email
|
|
50
|
-
// polls its inbox — screenshot, wait, screenshot, wait — and at 6 steps that ended the session as
|
|
51
|
-
// `gave_up`/`failed` in well under a minute, before the mail could plausibly arrive. The concurrent
|
|
52
|
-
// shared-world route already overrode these to 80/40 for exactly this reason; the knowledge existed
|
|
53
|
-
// in the codebase and never reached the default every other route uses.
|
|
54
|
-
const DEFAULT_IDLE_STEPS = 24;
|
|
55
|
-
// The no-progress signal is much stronger since #383 (a stale frame alone no longer counts — the
|
|
56
|
-
// actor must also be repeating itself), so this needs less headroom than the raw idle count.
|
|
57
|
-
const DEFAULT_NO_PROGRESS_STEPS = 20;
|
|
58
|
-
const IDLE_PROGRESS_FORGIVENESS_STEPS = 2;
|
|
59
|
-
/** How many recent turns the repetition check looks back over (#383). */
|
|
60
|
-
const ACTION_REPEAT_WINDOW = 3;
|
|
61
|
-
/** Click/scroll coordinates are bucketed to this many pixels before fingerprinting, so a one-pixel
|
|
62
|
-
* jitter between two otherwise identical clicks still reads as the same attempt. */
|
|
63
|
-
const ACTION_FINGERPRINT_BUCKET = 24;
|
|
64
|
-
/**
|
|
65
|
-
* A public-safe fingerprint of ONE turn's actions, used only in memory to tell "trying the same
|
|
66
|
-
* thing again" from "trying something new" (#383).
|
|
67
|
-
*
|
|
68
|
-
* Never includes typed text or key contents — a `type` contributes its LENGTH, exactly as
|
|
69
|
-
* describeCuaAction does, so this can never become a keylogger. Coordinates are bucketed so that
|
|
70
|
-
* re-clicking the same control counts as a repeat while moving to a different control does not.
|
|
71
|
-
*/
|
|
72
|
-
export function actionFingerprint(actions) {
|
|
73
|
-
const bucket = (value) => Math.round(value / ACTION_FINGERPRINT_BUCKET);
|
|
74
|
-
return actions
|
|
75
|
-
.map((action) => {
|
|
76
|
-
switch (action.kind) {
|
|
77
|
-
case "click":
|
|
78
|
-
case "double_click":
|
|
79
|
-
case "move":
|
|
80
|
-
return `${action.kind}@${bucket(action.x)},${bucket(action.y)}`;
|
|
81
|
-
case "scroll":
|
|
82
|
-
return `scroll@${bucket(action.x)},${bucket(action.y)}:${Math.sign(action.dx)},${Math.sign(action.dy)}`;
|
|
83
|
-
case "type":
|
|
84
|
-
return `type:${action.text.length}`;
|
|
85
|
-
case "speak":
|
|
86
|
-
return `speak:${action.text.length}`;
|
|
87
|
-
case "keypress":
|
|
88
|
-
return `keypress:${action.keys.join("+")}`;
|
|
89
|
-
case "drag":
|
|
90
|
-
return `drag:${action.path.length}`;
|
|
91
|
-
case "wait":
|
|
92
|
-
return "wait";
|
|
93
|
-
case "screenshot":
|
|
94
|
-
return "screenshot";
|
|
95
|
-
}
|
|
96
|
-
})
|
|
97
|
-
.join("|");
|
|
98
|
-
}
|
|
99
|
-
function isIdleAction(action) {
|
|
100
|
-
return action.kind === "screenshot" || action.kind === "wait";
|
|
101
|
-
}
|
|
102
|
-
function isIdleTurn(actions) {
|
|
103
|
-
return actions.length === 0 || actions.every(isIdleAction);
|
|
104
|
-
}
|
|
105
|
-
// Caps for stableProgressKey. The progress key is a coarse turn-over-turn comparison input,
|
|
106
|
-
// not a faithful serialization, so it bounds depth, breadth, string length, and total output —
|
|
107
|
-
// a huge or deeply nested appState can never blow up the comparison or the trace logging in
|
|
108
|
-
// tests. The values are deliberately generous (real route/turn/modal projections are tiny) but
|
|
109
|
-
// finite.
|
|
110
|
-
const STABLE_KEY_MAX_DEPTH = 6;
|
|
111
|
-
const STABLE_KEY_MAX_KEYS = 64;
|
|
112
|
-
const STABLE_KEY_MAX_ARRAY = 64;
|
|
113
|
-
const STABLE_KEY_MAX_STRING = 256;
|
|
114
|
-
const STABLE_KEY_MAX_TOTAL = 8192;
|
|
115
|
-
/**
|
|
116
|
-
* A deterministic, bounded, sorted-key projection of an appState object, used as the friction
|
|
117
|
-
* loop's progress key. Two structurally-equal states (regardless of key insertion order) map
|
|
118
|
-
* to the SAME string, so key reordering can never fabricate a progress delta; two different
|
|
119
|
-
* states map to different strings (within the caps).
|
|
120
|
-
*
|
|
121
|
-
* Correctness-load-bearing: it MUST NOT throw on a cyclic or huge input. Cycles are detected
|
|
122
|
-
* with a seen-set (a back-edge degrades to the marker "[Circular]"); depth, key count, array
|
|
123
|
-
* length, string length, and total output length are all capped so an adversarial or merely
|
|
124
|
-
* large appState degrades to a bounded value rather than crashing the loop. Pure: it never
|
|
125
|
-
* mutates the input. (See docs/architecture/state-driven-executor.md.)
|
|
126
|
-
*/
|
|
127
|
-
export function stableProgressKey(appState) {
|
|
128
|
-
const seen = new Set();
|
|
129
|
-
let truncated = false;
|
|
130
|
-
const encode = (value, depth) => {
|
|
131
|
-
if (truncated)
|
|
132
|
-
return '"…"';
|
|
133
|
-
if (value === null)
|
|
134
|
-
return "null";
|
|
135
|
-
const type = typeof value;
|
|
136
|
-
if (type === "number")
|
|
137
|
-
return Number.isFinite(value) ? JSON.stringify(value) : `"${String(value)}"`;
|
|
138
|
-
if (type === "boolean")
|
|
139
|
-
return value ? "true" : "false";
|
|
140
|
-
if (type === "bigint")
|
|
141
|
-
return `"${value.toString()}"`;
|
|
142
|
-
if (type === "string") {
|
|
143
|
-
const s = value;
|
|
144
|
-
return JSON.stringify(s.length > STABLE_KEY_MAX_STRING ? `${s.slice(0, STABLE_KEY_MAX_STRING)}…` : s);
|
|
145
|
-
}
|
|
146
|
-
if (type === "function" || type === "symbol" || type === "undefined")
|
|
147
|
-
return `"[${type}]"`;
|
|
148
|
-
// object or array
|
|
149
|
-
if (depth >= STABLE_KEY_MAX_DEPTH)
|
|
150
|
-
return '"[MaxDepth]"';
|
|
151
|
-
if (seen.has(value))
|
|
152
|
-
return '"[Circular]"';
|
|
153
|
-
seen.add(value);
|
|
154
|
-
try {
|
|
155
|
-
if (Array.isArray(value)) {
|
|
156
|
-
const cap = Math.min(value.length, STABLE_KEY_MAX_ARRAY);
|
|
157
|
-
const parts = [];
|
|
158
|
-
for (let i = 0; i < cap; i += 1) {
|
|
159
|
-
parts.push(encode(value[i], depth + 1));
|
|
160
|
-
if (truncated)
|
|
161
|
-
break;
|
|
162
|
-
}
|
|
163
|
-
if (value.length > STABLE_KEY_MAX_ARRAY)
|
|
164
|
-
parts.push('"…"');
|
|
165
|
-
return `[${parts.join(",")}]`;
|
|
166
|
-
}
|
|
167
|
-
const record = value;
|
|
168
|
-
const keys = Object.keys(record).sort();
|
|
169
|
-
const cap = Math.min(keys.length, STABLE_KEY_MAX_KEYS);
|
|
170
|
-
const parts = [];
|
|
171
|
-
for (let i = 0; i < cap; i += 1) {
|
|
172
|
-
const key = keys[i];
|
|
173
|
-
parts.push(`${JSON.stringify(key)}:${encode(record[key], depth + 1)}`);
|
|
174
|
-
if (truncated)
|
|
175
|
-
break;
|
|
176
|
-
}
|
|
177
|
-
if (keys.length > STABLE_KEY_MAX_KEYS)
|
|
178
|
-
parts.push('"…":"…"');
|
|
179
|
-
return `{${parts.join(",")}}`;
|
|
180
|
-
}
|
|
181
|
-
finally {
|
|
182
|
-
// Leave the set so sibling subtrees that legitimately repeat a shared reference still
|
|
183
|
-
// serialize once per occurrence-path without false "Circular" hits across siblings.
|
|
184
|
-
seen.delete(value);
|
|
185
|
-
}
|
|
186
|
-
};
|
|
187
|
-
let out = encode(appState, 0);
|
|
188
|
-
if (out.length > STABLE_KEY_MAX_TOTAL) {
|
|
189
|
-
truncated = true;
|
|
190
|
-
out = `${out.slice(0, STABLE_KEY_MAX_TOTAL)}…`;
|
|
191
|
-
}
|
|
192
|
-
return out;
|
|
193
|
-
}
|
|
194
|
-
/** The friction progress key: a stable projection of appState when present, else stateSignature. */
|
|
195
|
-
/** Pixels of vertical scroll per progress bucket (#393): a real scroll step (typically >=100px)
|
|
196
|
-
* crosses a bucket and counts as progress; sub-bucket jiggle does not, so an actor nudging the
|
|
197
|
-
* same dead panel cannot stay "progressing" forever. */
|
|
198
|
-
const SCROLL_PROGRESS_BUCKET_PX = 200;
|
|
199
|
-
function progressKeyOf(observation) {
|
|
200
|
-
const base = observation.appState !== undefined ? stableProgressKey(observation.appState) : observation.stateSignature;
|
|
201
|
-
// Scroll position is state (#393): a scroll-pinned section keeps the frame hash constant while
|
|
202
|
-
// the participant genuinely advances, so the offset rides the key — bucketed, never raw.
|
|
203
|
-
return observation.scrollY === undefined
|
|
204
|
-
? base
|
|
205
|
-
: `${base}#s${Math.round(observation.scrollY / SCROLL_PROGRESS_BUCKET_PX)}`;
|
|
206
|
-
}
|
|
207
|
-
/** A public-safe one-line action label. Never includes raw typed text. */
|
|
208
|
-
export function describeCuaAction(action) {
|
|
209
|
-
switch (action.kind) {
|
|
210
|
-
case "click":
|
|
211
|
-
return `click (${action.x}, ${action.y})`;
|
|
212
|
-
case "double_click":
|
|
213
|
-
return `double-click (${action.x}, ${action.y})`;
|
|
214
|
-
case "move":
|
|
215
|
-
return `move (${action.x}, ${action.y})`;
|
|
216
|
-
case "scroll":
|
|
217
|
-
return `scroll (${action.dx}, ${action.dy}) at (${action.x}, ${action.y})`;
|
|
218
|
-
case "type":
|
|
219
|
-
return `type [${action.text.length} chars]`;
|
|
220
|
-
case "speak":
|
|
221
|
-
return `speak [${action.text.length} chars]`;
|
|
222
|
-
case "keypress":
|
|
223
|
-
return `keypress ${action.keys.join("+")}`;
|
|
224
|
-
case "drag":
|
|
225
|
-
return `drag ${action.path.length} points`;
|
|
226
|
-
case "wait":
|
|
227
|
-
return action.ms === undefined ? "wait" : `wait ${action.ms}ms`;
|
|
228
|
-
case "screenshot":
|
|
229
|
-
return "screenshot";
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
/** Exported so the participant-vs-harness distinction is pinned directly, not inferred from a run. */
|
|
233
|
-
export function statusForCompletionReason(reason) {
|
|
234
|
-
switch (reason) {
|
|
235
|
-
case "goal_satisfied":
|
|
236
|
-
case "turn_completed": // turn_completed is a Codex-lane reason; this loop emits goal_satisfied
|
|
237
|
-
return "passed";
|
|
238
|
-
// A session that ran out of time or budget did not reach its goal, whatever it achieved along
|
|
239
|
-
// the way. Calling that `passed` is how a truncated study came to be reported as a green one —
|
|
240
|
-
// and why "raise the timeout" kept landing on the operator instead of on the tool. This switch
|
|
241
|
-
// is exhaustive with no default, so a new completion reason forces a compile error here.
|
|
242
|
-
case "budget_reached":
|
|
243
|
-
return "incomplete";
|
|
244
|
-
case "timed_out":
|
|
245
|
-
return "timed_out";
|
|
246
|
-
case "blocked_approval":
|
|
247
|
-
return "blocked";
|
|
248
|
-
// A participant who stopped trying is the single most valuable thing a usability study
|
|
249
|
-
// produces. Recording it as `failed` said the instrument broke, which is a different claim and
|
|
250
|
-
// a false one — see docs/principles/three-roles.md.
|
|
251
|
-
case "gave_up":
|
|
252
|
-
return "abandoned";
|
|
253
|
-
// Only the harness failing is a harness failure.
|
|
254
|
-
case "actor_error":
|
|
255
|
-
case "step_failed": // step_failed is the scripted-browser lane's reason; this loop never emits it
|
|
256
|
-
case "harness_error":
|
|
257
|
-
return "failed";
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
// Distinct error classes so the loop can tell a deadline/abort apart from a real
|
|
261
|
-
// adapter failure when raceSettle rejects.
|
|
262
|
-
/**
|
|
263
|
-
* Read the fixed closing line the prompt asks for (#570): the FIRST non-empty line of the
|
|
264
|
-
* participant's last message, exactly one of three phrases, punctuation and case forgiven. Anything
|
|
265
|
-
* else is absence, never a guess. Exported for tests.
|
|
266
|
-
*/
|
|
267
|
-
export function declaredOutcomeFromClosingLine(message) {
|
|
268
|
-
if (message === undefined)
|
|
269
|
-
return undefined;
|
|
270
|
-
const first = message.split(/\r?\n/).map((line) => line.trim()).find((line) => line.length > 0);
|
|
271
|
-
if (first === undefined)
|
|
272
|
-
return undefined;
|
|
273
|
-
const normalized = first.replace(/^[*_#>\s-]+|[*_.!\s]+$/g, "").toLowerCase();
|
|
274
|
-
if (normalized === "reached the goal")
|
|
275
|
-
return "reached";
|
|
276
|
-
if (normalized === "did not reach the goal")
|
|
277
|
-
return "not_reached";
|
|
278
|
-
if (normalized === "blocked")
|
|
279
|
-
return "blocked";
|
|
280
|
-
return undefined;
|
|
281
|
-
}
|
|
282
|
-
class CuaDeadlineError extends Error {
|
|
283
|
-
}
|
|
284
|
-
class CuaAbortError extends Error {
|
|
285
|
-
}
|
|
286
|
-
/** A single call outlived its own bound while the session still had budget: a stall, not a deadline. */
|
|
287
|
-
class CuaStallError extends Error {
|
|
288
|
-
what;
|
|
289
|
-
afterMs;
|
|
290
|
-
constructor(what, afterMs) {
|
|
291
|
-
super(`${what} produced nothing within ${afterMs}ms`);
|
|
292
|
-
this.what = what;
|
|
293
|
-
this.afterMs = afterMs;
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
export const DEFAULT_TURN_TIMEOUT_MS = 180_000;
|
|
297
|
-
export const DEFAULT_OBSERVATION_TIMEOUT_MS = 60_000;
|
|
298
|
-
// Internal control-flow signal: the per-turn frame guard already set completionReason/reason
|
|
299
|
-
// to a structured harness_error; this just unwinds the loop without being misread as an adapter
|
|
300
|
-
// failure in the catch block (it carries no message to persist).
|
|
301
|
-
class CuaFrameGuardStop extends Error {
|
|
302
|
-
}
|
|
303
|
-
// Internal control-flow signal for deterministic harness stop conditions that match before the
|
|
304
|
-
// model is asked for another turn. completionReason/reason are already set by the caller.
|
|
305
|
-
class CuaStopWhenStop extends Error {
|
|
306
|
-
}
|
|
307
|
-
const neverAbort = new AbortController().signal;
|
|
308
|
-
/**
|
|
309
|
-
* Wait on a port promise, but stop waiting if the wall-clock budget runs out or
|
|
310
|
-
* the caller aborts. The underlying promise may still settle later (a promise
|
|
311
|
-
* cannot be force-cancelled); we simply stop blocking the loop on it. An
|
|
312
|
-
* already-settled promise always wins, so a fast op is never spuriously failed.
|
|
313
|
-
*/
|
|
314
|
-
/**
|
|
315
|
-
* raceSettle with a second, tighter clock: the call's own bound. When the tighter clock wins the
|
|
316
|
-
* result is a CuaStallError (the caller decides whether to retry); when the session clock wins it
|
|
317
|
-
* stays a CuaDeadlineError, so the existing budget_reached / timed_out reading is untouched.
|
|
318
|
-
*/
|
|
319
|
-
async function raceBounded(what, promise, remainingMs, boundMs, signal) {
|
|
320
|
-
const cap = Math.min(remainingMs, boundMs);
|
|
321
|
-
const boundWins = boundMs < remainingMs;
|
|
322
|
-
try {
|
|
323
|
-
return await raceSettle(promise, cap, signal);
|
|
324
|
-
}
|
|
325
|
-
catch (error) {
|
|
326
|
-
if (error instanceof CuaDeadlineError && boundWins)
|
|
327
|
-
throw new CuaStallError(what, cap);
|
|
328
|
-
throw error;
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
function raceSettle(promise, remainingMs, signal) {
|
|
332
|
-
if (signal?.aborted) {
|
|
333
|
-
return Promise.reject(new CuaAbortError());
|
|
334
|
-
}
|
|
335
|
-
return new Promise((resolve, reject) => {
|
|
336
|
-
let settled = false;
|
|
337
|
-
const finish = (apply) => {
|
|
338
|
-
if (settled)
|
|
339
|
-
return;
|
|
340
|
-
settled = true;
|
|
341
|
-
clearTimeout(timer);
|
|
342
|
-
signal?.removeEventListener("abort", onAbort);
|
|
343
|
-
apply();
|
|
344
|
-
};
|
|
345
|
-
const onAbort = () => finish(() => reject(new CuaAbortError()));
|
|
346
|
-
const timer = setTimeout(() => finish(() => reject(new CuaDeadlineError())), Math.max(0, remainingMs));
|
|
347
|
-
if (typeof timer.unref === "function")
|
|
348
|
-
timer.unref();
|
|
349
|
-
signal?.addEventListener("abort", onAbort, { once: true });
|
|
350
|
-
promise.then((value) => finish(() => resolve(value)), (error) => finish(() => reject(error)));
|
|
351
|
-
});
|
|
352
|
-
}
|
|
353
|
-
/**
|
|
354
|
-
* Drive the computer-use loop to a single explicit completion and return an
|
|
355
|
-
* ActorTrace. Every screenshot is redacted through the injected RedactionHooks
|
|
356
|
-
* before its ref is recorded, so the trace is public-safe by construction.
|
|
357
|
-
*/
|
|
358
|
-
export async function runComputerUseLoop(options) {
|
|
359
|
-
if (options.provider.executionProfile?.billing === "account-unknown" &&
|
|
360
|
-
(options.maxUsd !== undefined || options.overRunBudget !== undefined || options.estimateTurnCostUsd !== undefined ||
|
|
361
|
-
options.provider.modelSettings?.maxOutputTokens !== undefined)) {
|
|
362
|
-
throw new CuaProviderError("request_rejected", { dispatched: false, usageComplete: false, cleanup: "confirmed" });
|
|
363
|
-
}
|
|
364
|
-
const { instructions, provider, executor, persona, redaction, timeoutMs, now, signal, idleSteps = DEFAULT_IDLE_STEPS, noProgressSteps = DEFAULT_NO_PROGRESS_STEPS, acknowledgeSafetyChecks = () => null, redactScreenshots = false, scrubText = (text) => text, writeScreenshot = async (name) => `screenshots/${name}`, stopWhen, dwell, sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)), tasks, maxUsd, overRunBudget, estimateTurnCostUsd, requireReportedUsageForSpendCap = false, onObservedUrl, onMessage, onScreenshot, onTrace } = options;
|
|
365
|
-
const noProgressRecoverySteps = Math.min(Math.max(1, noProgressSteps - 1), 3);
|
|
366
|
-
const idleRecoverySteps = Math.min(Math.max(1, idleSteps - 1), 3);
|
|
367
|
-
// Model-authored narration: literal-scrub known provisioned values, THEN pattern-redact.
|
|
368
|
-
// A value the model transcribes (a DB password it read on screen) has no shape, so redactText
|
|
369
|
-
// alone cannot catch it — the lab's scrubKnownValues, injected as scrubText, closes that.
|
|
370
|
-
const redactNarration = (text) => redaction.redactText(scrubText(text));
|
|
371
|
-
const startedAtMs = now();
|
|
372
|
-
const remaining = () => timeoutMs - (now() - startedAtMs);
|
|
373
|
-
const turnTimeoutMs = options.turnTimeoutMs ?? DEFAULT_TURN_TIMEOUT_MS;
|
|
374
|
-
const observationTimeoutMs = options.observationTimeoutMs ?? DEFAULT_OBSERVATION_TIMEOUT_MS;
|
|
375
|
-
const items = [];
|
|
376
|
-
const providerRequests = [];
|
|
377
|
-
let providerCleanupUnconfirmed = false;
|
|
378
|
-
const liveMetadata = () => ({
|
|
379
|
-
...(provider.executionProfile === undefined ? {} : { executionProfile: provider.executionProfile }),
|
|
380
|
-
...(provider.requestPolicy === "fail_closed" ? { providerRequests: providerRequests.map(row => ({ ...row })),
|
|
381
|
-
historyTurnsOmitted: provider.historyTurnsOmitted ?? 0 } : {})
|
|
382
|
-
});
|
|
383
|
-
const flushTrace = () => onTrace?.(items.slice(), runningUsage(), liveMetadata());
|
|
384
|
-
// The ONE recording choke point (#441): every trace item is stamped `at` from the
|
|
385
|
-
// loop's injected clock as it is recorded, so timed playback reads recorded facts
|
|
386
|
-
// (deterministic in tests via the injected `now`).
|
|
387
|
-
const record = (item) => {
|
|
388
|
-
items.push({ ...item, at: new Date(now()).toISOString() });
|
|
389
|
-
};
|
|
390
|
-
// Affordance classification (#369): WHICH route the actor took, recorded per dispatched action.
|
|
391
|
-
// Collected here because the typed text exists only at dispatch — describeCuaAction deliberately
|
|
392
|
-
// destroys it before it can reach the trace. Only the CLASS (and a scheme-shaped signal) is kept.
|
|
393
|
-
const affordanceObservations = [];
|
|
394
|
-
const counts = {
|
|
395
|
-
turns: 0,
|
|
396
|
-
actions: 0,
|
|
397
|
-
materialActions: 0,
|
|
398
|
-
screenshots: 0,
|
|
399
|
-
reasonings: 0,
|
|
400
|
-
messages: 0,
|
|
401
|
-
idleTurns: 0,
|
|
402
|
-
noProgressTurns: 0
|
|
403
|
-
};
|
|
404
|
-
// The last few turns' action fingerprints, in memory only, for the #383 corroboration rule.
|
|
405
|
-
const recentFingerprints = [];
|
|
406
|
-
// Productivity signal for the wall-clock deadline: a session that took at least one material
|
|
407
|
-
// (non-idle) action before the cap reached its BUDGET rather than stalling. A deadline hit with
|
|
408
|
-
// zero material actions is still an honest failure (timed_out). Kept beside counts.materialActions
|
|
409
|
-
// so the evidence self-describes the distinction.
|
|
410
|
-
let materialActions = 0;
|
|
411
|
-
let interruptedActionOutcome = false;
|
|
412
|
-
let seq = 0;
|
|
413
|
-
let usageInput = 0;
|
|
414
|
-
let usageCachedInput = 0;
|
|
415
|
-
let usageCacheWriteInput = 0;
|
|
416
|
-
let usageOutput = 0;
|
|
417
|
-
let sawUsage = false;
|
|
418
|
-
let incompleteInteractionUsage = false;
|
|
419
|
-
let unreportedInteractionUsage = false;
|
|
420
|
-
let interactionRequestPending = false;
|
|
421
|
-
// Per model-inference usage, in order (#334): the recorded fact long-context pricing tiers
|
|
422
|
-
// need. A continuing native tool interaction may contain several inference requests.
|
|
423
|
-
const usageTurns = [];
|
|
424
|
-
const knownPendingUsage = () => {
|
|
425
|
-
const usage = interactionRequestPending ? provider.pendingRequestUsage : undefined;
|
|
426
|
-
if (!completeTurnUsage(usage))
|
|
427
|
-
return undefined;
|
|
428
|
-
const turns = usage.turns === undefined ? undefined : normalizedUsageTurns(usage);
|
|
429
|
-
return { input: usage.input, output: usage.output,
|
|
430
|
-
...(usage.cachedInput === undefined ? {} : { cachedInput: usage.cachedInput }),
|
|
431
|
-
...(usage.cacheWriteInput === undefined ? {} : { cacheWriteInput: usage.cacheWriteInput }),
|
|
432
|
-
...(turns === undefined ? {} : { turns }) };
|
|
433
|
-
};
|
|
434
|
-
const withPendingUsage = (settled) => {
|
|
435
|
-
const pendingUsage = knownPendingUsage();
|
|
436
|
-
if (pendingUsage === undefined)
|
|
437
|
-
return settled;
|
|
438
|
-
const input = (settled.input ?? 0) + pendingUsage.input;
|
|
439
|
-
const output = (settled.output ?? 0) + pendingUsage.output;
|
|
440
|
-
return {
|
|
441
|
-
...settled,
|
|
442
|
-
input,
|
|
443
|
-
output,
|
|
444
|
-
...((settled.cachedInput !== undefined || pendingUsage.cachedInput !== undefined)
|
|
445
|
-
? { cachedInput: (settled.cachedInput ?? 0) + (pendingUsage.cachedInput ?? 0) } : {}),
|
|
446
|
-
...((settled.cacheWriteInput !== undefined || pendingUsage.cacheWriteInput !== undefined)
|
|
447
|
-
? { cacheWriteInput: (settled.cacheWriteInput ?? 0) + (pendingUsage.cacheWriteInput ?? 0) } : {}),
|
|
448
|
-
turns: [...(settled.turns ?? []), ...(pendingUsage.turns ?? [{ input: pendingUsage.input, output: pendingUsage.output,
|
|
449
|
-
...(pendingUsage.cachedInput === undefined ? {} : { cachedInput: pendingUsage.cachedInput }),
|
|
450
|
-
...(pendingUsage.cacheWriteInput === undefined ? {} : { cacheWriteInput: pendingUsage.cacheWriteInput }) }])],
|
|
451
|
-
...(settled.total === undefined ? {} : { total: input + output })
|
|
452
|
-
};
|
|
453
|
-
};
|
|
454
|
-
// The running usage snapshot both spend guards consume: totals plus the per-request ledger,
|
|
455
|
-
// shaped exactly like the trace's final tokenUsage so one estimator prices both identically.
|
|
456
|
-
// Unlike the persisted trace (where absent means "unreported"), this runtime callback arg
|
|
457
|
-
// ALWAYS carries numeric cache fields: pre-#334 guards received an object whose cachedInput
|
|
458
|
-
// was always a number (0 included), and arithmetic on a suddenly-undefined field yields NaN —
|
|
459
|
-
// which comparison operators swallow silently (red-team finding: a stale study-budget guard
|
|
460
|
-
// would run uncapped without a sound).
|
|
461
|
-
const accountUsage = () => ({
|
|
462
|
-
...(usageTurns.some(t => t.input !== undefined) ? { input: usageInput } : {}),
|
|
463
|
-
...(usageTurns.some(t => t.output !== undefined) ? { output: usageOutput } : {}),
|
|
464
|
-
...(usageTurns.some(t => t.cachedInput !== undefined) ? { cachedInput: usageCachedInput } : {}),
|
|
465
|
-
...(usageTurns.some(t => t.cacheWriteInput !== undefined) ? { cacheWriteInput: usageCacheWriteInput } : {}),
|
|
466
|
-
...(usageTurns.length > 0 ? { turns: usageTurns.map(t => ({ ...t })) } : {}),
|
|
467
|
-
...(providerRequests.length > 0 && providerRequests.every(r => r.usageComplete && completeTurnUsage(r.usage))
|
|
468
|
-
? { total: usageInput + usageOutput } : {})
|
|
469
|
-
});
|
|
470
|
-
const runningUsage = () => withPendingUsage(provider.executionProfile?.billing === "account-unknown" ? accountUsage() : ({
|
|
471
|
-
input: usageInput,
|
|
472
|
-
output: usageOutput,
|
|
473
|
-
cachedInput: usageCachedInput,
|
|
474
|
-
cacheWriteInput: usageCacheWriteInput,
|
|
475
|
-
...(usageTurns.length > 0 ? { turns: usageTurns } : {})
|
|
476
|
-
}));
|
|
477
|
-
const hasUnreportedInteractionUsage = () => unreportedInteractionUsage || provider.interactionUsageIncomplete === true;
|
|
478
|
-
const usageUnavailableForCap = () => incompleteInteractionUsage || unreportedInteractionUsage ||
|
|
479
|
-
(interactionRequestPending ? knownPendingUsage() === undefined : provider.interactionUsageIncomplete === true);
|
|
480
|
-
let lastResponseId;
|
|
481
|
-
let currentPhase = "initializing computer-use loop";
|
|
482
|
-
let lastActionTitle;
|
|
483
|
-
let lastMaterialActionTitle;
|
|
484
|
-
let lastScreenshotRef;
|
|
485
|
-
const recentActionTitles = [];
|
|
486
|
-
const nextId = (kind) => `${kind}-${(seq += 1).toString().padStart(3, "0")}`;
|
|
487
|
-
const bump = (key) => {
|
|
488
|
-
counts[key] = (counts[key] ?? 0) + 1;
|
|
489
|
-
};
|
|
490
|
-
const recordUsage = (turn, interaction = true) => {
|
|
491
|
-
if (turn.providerRequestPending === true)
|
|
492
|
-
return;
|
|
493
|
-
const raw = turn.usage;
|
|
494
|
-
const turns = raw?.turns === undefined ? undefined : normalizedUsageTurns(raw);
|
|
495
|
-
if (interaction && (!completeTurnUsage(raw) || turn.providerRequest?.usageComplete === false))
|
|
496
|
-
incompleteInteractionUsage = true;
|
|
497
|
-
if (interaction && raw?.turns !== undefined && turns === undefined)
|
|
498
|
-
unreportedInteractionUsage = true;
|
|
499
|
-
if (raw === undefined)
|
|
500
|
-
return;
|
|
501
|
-
const usage = {
|
|
502
|
-
...(validTokenCount(raw.input) ? { input: raw.input } : {}),
|
|
503
|
-
...(validTokenCount(raw.output) ? { output: raw.output } : {}),
|
|
504
|
-
...(validTokenCount(raw.cachedInput) ? { cachedInput: raw.cachedInput } : {}),
|
|
505
|
-
...(validTokenCount(raw.cacheWriteInput) ? { cacheWriteInput: raw.cacheWriteInput } : {})
|
|
506
|
-
};
|
|
507
|
-
if (Object.keys(usage).length === 0)
|
|
508
|
-
return;
|
|
509
|
-
sawUsage = true;
|
|
510
|
-
usageInput += usage.input ?? 0;
|
|
511
|
-
usageCachedInput += usage.cachedInput ?? 0;
|
|
512
|
-
usageCacheWriteInput += usage.cacheWriteInput ?? 0;
|
|
513
|
-
usageOutput += usage.output ?? 0;
|
|
514
|
-
if (raw.turns === undefined)
|
|
515
|
-
usageTurns.push(usage);
|
|
516
|
-
else if (turns !== undefined)
|
|
517
|
-
usageTurns.push(...turns);
|
|
518
|
-
};
|
|
519
|
-
/** Marked providers own one attempt through settlement; an outer race never retries it. */
|
|
520
|
-
const markedRequest = async (request, kind, capMs) => {
|
|
521
|
-
const controller = new AbortController();
|
|
522
|
-
const onAbort = () => controller.abort();
|
|
523
|
-
if (signal?.aborted)
|
|
524
|
-
controller.abort();
|
|
525
|
-
else
|
|
526
|
-
signal?.addEventListener("abort", onAbort, { once: true });
|
|
527
|
-
let settlement;
|
|
528
|
-
let failure;
|
|
529
|
-
let failed = false;
|
|
530
|
-
let accepted;
|
|
531
|
-
let pendingYield = false;
|
|
532
|
-
const pending = Promise.resolve().then(() => {
|
|
533
|
-
if (controller.signal.aborted)
|
|
534
|
-
throw new CuaProviderError("cancelled", { dispatched: false, usageComplete: false, cleanup: "confirmed" });
|
|
535
|
-
return kind === "debrief" ? provider.debrief(request, controller.signal) : provider.nextTurn(request, controller.signal);
|
|
536
|
-
}).then(turn => { settlement = { turn }; return turn; }, (error) => { settlement = { error }; throw error; });
|
|
537
|
-
void pending.catch(() => undefined);
|
|
538
|
-
try {
|
|
539
|
-
accepted = await raceBounded(`participant ${kind}`, pending, remaining(), capMs, signal);
|
|
540
|
-
if (accepted.providerRequestPending === true) {
|
|
541
|
-
if (kind !== "interaction" || accepted.done || accepted.actions.length === 0 || accepted.pendingSafetyChecks.length > 0 ||
|
|
542
|
-
accepted.providerRequest !== undefined || accepted.usage !== undefined || accepted.interruption !== undefined || accepted.closingReport !== undefined) {
|
|
543
|
-
throw new CuaProviderError("invalid_response", { dispatched: "unknown", usageComplete: false, cleanup: "unconfirmed" });
|
|
544
|
-
}
|
|
545
|
-
pendingYield = true;
|
|
546
|
-
}
|
|
547
|
-
else {
|
|
548
|
-
const r = accepted.providerRequest;
|
|
549
|
-
if (!r || r.dispatched !== true || typeof r.usageComplete !== "boolean" || r.cleanup !== "confirmed") {
|
|
550
|
-
throw new CuaProviderError("invalid_response", { dispatched: "unknown", usageComplete: false, cleanup: "unconfirmed" }, accepted.usage);
|
|
551
|
-
}
|
|
552
|
-
}
|
|
553
|
-
}
|
|
554
|
-
catch (error) {
|
|
555
|
-
failed = true;
|
|
556
|
-
failure = error;
|
|
557
|
-
}
|
|
558
|
-
finally {
|
|
559
|
-
controller.abort();
|
|
560
|
-
signal?.removeEventListener("abort", onAbort);
|
|
561
|
-
if (settlement === undefined) {
|
|
562
|
-
let timer;
|
|
563
|
-
try {
|
|
564
|
-
await Promise.race([pending.catch(() => undefined), new Promise(resolve => {
|
|
565
|
-
timer = setTimeout(resolve, CUA_PROVIDER_CLEANUP_GRACE_MS);
|
|
566
|
-
})]);
|
|
567
|
-
}
|
|
568
|
-
finally {
|
|
569
|
-
clearTimeout(timer);
|
|
570
|
-
}
|
|
571
|
-
}
|
|
572
|
-
}
|
|
573
|
-
if (!failed && pendingYield) {
|
|
574
|
-
interactionRequestPending = true;
|
|
575
|
-
return accepted;
|
|
576
|
-
}
|
|
577
|
-
const final = settlement;
|
|
578
|
-
const typed = isCuaProviderError(failure) ? failure : final && "error" in final && isCuaProviderError(final.error) ? final.error : undefined;
|
|
579
|
-
const turn = final && "turn" in final ? final.turn : undefined;
|
|
580
|
-
const raw = typed?.receipt ?? turn?.providerRequest;
|
|
581
|
-
const receipt = raw && (typeof raw.dispatched === "boolean" || raw.dispatched === "unknown") &&
|
|
582
|
-
typeof raw.usageComplete === "boolean" && ["confirmed", "unconfirmed"].includes(raw.cleanup) ? { dispatched: raw.dispatched, usageComplete: raw.usageComplete, cleanup: raw.cleanup }
|
|
583
|
-
: { dispatched: "unknown", usageComplete: false, cleanup: "unconfirmed" };
|
|
584
|
-
const rawUsage = typed?.usage ?? (turn?.providerRequestPending === true ? undefined : turn?.usage);
|
|
585
|
-
const usage = rawUsage === undefined ? undefined : Object.fromEntries(["input", "output", "cachedInput", "cacheWriteInput", "total"].flatMap(key => {
|
|
586
|
-
const value = rawUsage[key];
|
|
587
|
-
return validTokenCount(value) ? [[key, value]] : [];
|
|
588
|
-
}));
|
|
589
|
-
// restricted-codex-session sets dispatched only after initialize/config/account/
|
|
590
|
-
// thread/MCP admission, immediately before turn/start; it is not a success claim.
|
|
591
|
-
const settledKind = interactionRequestPending ? "interaction" : kind;
|
|
592
|
-
providerRequests.push({ ordinal: providerRequests.length + 1, kind: settledKind, ...receipt,
|
|
593
|
-
profileVerified: provider.executionProfile !== undefined && receipt.dispatched === true,
|
|
594
|
-
...(typed ? { errorCode: typed.code, ...(typed.failurePhase === undefined ? {} : { failurePhase: typed.failurePhase }) } : {}),
|
|
595
|
-
...(usage === undefined ? {} : { usage: { ...usage } }) });
|
|
596
|
-
if (receipt.cleanup !== "confirmed") {
|
|
597
|
-
providerCleanupUnconfirmed = true;
|
|
598
|
-
record({ id: nextId("notice"), kind: "notice", lifecycle: "completed", status: "error",
|
|
599
|
-
title: "participant request cleanup unconfirmed", text: "The request did not confirm cleanup within the settlement boundary. No further participant request or action is admitted." });
|
|
600
|
-
}
|
|
601
|
-
if (settledKind === "interaction" && receipt.dispatched !== false && (!receipt.usageComplete || !completeTurnUsage(usage)))
|
|
602
|
-
unreportedInteractionUsage = true;
|
|
603
|
-
interactionRequestPending = false;
|
|
604
|
-
if (failed) {
|
|
605
|
-
if (usage)
|
|
606
|
-
recordUsage({ actions: [], pendingSafetyChecks: [], done: false, usage, providerRequest: receipt }, settledKind === "interaction");
|
|
607
|
-
if (failure instanceof CuaAbortError || failure instanceof CuaDeadlineError)
|
|
608
|
-
throw failure;
|
|
609
|
-
if (failure instanceof CuaStallError)
|
|
610
|
-
throw new CuaProviderError("timeout", receipt, usage, typed?.failurePhase);
|
|
611
|
-
throw typed ?? new CuaProviderError("process_failed", receipt, usage);
|
|
612
|
-
}
|
|
613
|
-
return accepted;
|
|
614
|
-
};
|
|
615
|
-
// Whether any observation this run surfaced structured appState (a non-vision/state executor).
|
|
616
|
-
// RUNTIME-ONLY signal: used solely to self-describe in redaction.notes that app state drove
|
|
617
|
-
// progress detection and was NOT written to the trace — the appState itself never persists.
|
|
618
|
-
let observedAppState = false;
|
|
619
|
-
// Guarded screenshot persistence: a non-vision executor returns an observation with no
|
|
620
|
-
// screenshot, and the loop persists none that turn (counts.screenshots stays 0 → the existing
|
|
621
|
-
// "n/a" branch resolves redaction.screenshots). No Buffer.alloc(0) ever reaches disk.
|
|
622
|
-
const maybeRecordScreenshot = async (observation, label) => {
|
|
623
|
-
const frame = observation.screenshot;
|
|
624
|
-
if (frame === undefined)
|
|
625
|
-
return;
|
|
626
|
-
currentPhase = `writing screenshot ${label}`;
|
|
627
|
-
// Default: persist the raw frame (full fidelity, local-only). redactScreenshots flips to the
|
|
628
|
-
// publish-safe blurred thumbnail. Either way the bytes the model already saw were raw.
|
|
629
|
-
const { bytes, method } = redactScreenshots
|
|
630
|
-
? await redaction.redactScreenshot(frame, { label }).then((r) => ({ bytes: r.buffer, method: r.method }))
|
|
631
|
-
: { bytes: frame, method: "none" };
|
|
632
|
-
const path = await writeScreenshot(`${label}.png`, bytes);
|
|
633
|
-
const screenshotRef = { path, redaction: method };
|
|
634
|
-
lastScreenshotRef = screenshotRef;
|
|
635
|
-
record({
|
|
636
|
-
id: nextId("screenshot"),
|
|
637
|
-
kind: "screenshot",
|
|
638
|
-
lifecycle: "completed",
|
|
639
|
-
title: label,
|
|
640
|
-
screenshotRef
|
|
641
|
-
});
|
|
642
|
-
bump("screenshots");
|
|
643
|
-
};
|
|
644
|
-
// One projection feeds BOTH the stop guard and the task tracker, so a criterion that would stop
|
|
645
|
-
// the run and a criterion that completes a task can never see different evidence for one turn.
|
|
646
|
-
const stopObservationOf = (observation) => ({
|
|
647
|
-
...(observation.url === undefined ? {} : { url: observation.url }),
|
|
648
|
-
...(observation.text === undefined ? {} : { text: observation.text }),
|
|
649
|
-
...(observation.appState === undefined ? {} : { appState: observation.appState })
|
|
650
|
-
});
|
|
651
|
-
const matchedStopWhen = (observation) => evaluateStopWhen(stopWhen, stopObservationOf(observation));
|
|
652
|
-
// The funnel is recorded, never consulted: task completion does not steer the loop. Evaluated
|
|
653
|
-
// BEFORE the stopWhen check each turn so a final task whose criterion coincides with the stop
|
|
654
|
-
// condition still lands in the funnel of the very turn that ends the session.
|
|
655
|
-
const taskTracker = tasks !== undefined && tasks.length > 0 ? new TaskTracker(tasks) : undefined;
|
|
656
|
-
const observeTasks = (observation, turn) => {
|
|
657
|
-
if (taskTracker === undefined)
|
|
658
|
-
return;
|
|
659
|
-
for (const completion of taskTracker.observe(stopObservationOf(observation), turn)) {
|
|
660
|
-
// The id is researcher-authored config and the kinds are rule-type names; the matched VALUES
|
|
661
|
-
// (a URL, page text) never appear here — the same discipline as stopWhenTraceItem.
|
|
662
|
-
record({
|
|
663
|
-
id: nextId("notice"),
|
|
664
|
-
kind: "notice",
|
|
665
|
-
lifecycle: "completed",
|
|
666
|
-
status: "matched",
|
|
667
|
-
title: `task completed: ${redactNarration(completion.id)}`,
|
|
668
|
-
text: redactNarration(`turn ${turn}; matched rule ${completion.matchedRuleIndex} (${completion.matchedKinds.join("+")})`)
|
|
669
|
-
});
|
|
670
|
-
}
|
|
671
|
-
};
|
|
672
|
-
let completionReason = "goal_satisfied";
|
|
673
|
-
let stopCause;
|
|
674
|
-
let declaredOutcome;
|
|
675
|
-
let reason = "computer-use loop completed";
|
|
676
|
-
let stopConditionMatch;
|
|
677
|
-
const stopForAdmissionLimit = () => {
|
|
678
|
-
completionReason = "budget_reached";
|
|
679
|
-
stopCause = "adapter_limit";
|
|
680
|
-
reason = "the adapter reported a local admission limit before provider dispatch; the participant did not report completion. No actions or closing request followed the refusal.";
|
|
681
|
-
record({ id: nextId("notice"), kind: "notice", lifecycle: "completed", status: "warn",
|
|
682
|
-
title: "adapter admission limit reached", text: reason });
|
|
683
|
-
};
|
|
684
|
-
const requiresUsage = requireReportedUsageForSpendCap && (maxUsd !== undefined || overRunBudget !== undefined);
|
|
685
|
-
const stopForUnreportedUsage = () => {
|
|
686
|
-
unreportedInteractionUsage = true;
|
|
687
|
-
completionReason = "harness_error";
|
|
688
|
-
stopCause = "usage_unreported";
|
|
689
|
-
reason = "provider usage is unavailable for a request, so the declared model-spend cap cannot be established; no further participant or closing request was dispatched";
|
|
690
|
-
record({ id: nextId("notice"), kind: "notice", lifecycle: "completed", status: "error",
|
|
691
|
-
title: "provider usage unavailable", text: reason });
|
|
692
|
-
};
|
|
693
|
-
// A vision provider against a screenshot-less observation is a fail-closed harness error, not
|
|
694
|
-
// a silent crash: record it and break. Returns true when the run must stop. (The provider sets
|
|
695
|
-
// requiresFrame; a state-reasoning provider omits it.)
|
|
696
|
-
const frameGuardTripped = (observation) => {
|
|
697
|
-
if (provider.requiresFrame === true && observation.screenshot === undefined) {
|
|
698
|
-
completionReason = "harness_error";
|
|
699
|
-
reason = `provider ${provider.id} requires a screenshot frame but the executor returned an observation with no screenshot (vision provider against a state-only executor)`;
|
|
700
|
-
return true;
|
|
701
|
-
}
|
|
702
|
-
return false;
|
|
703
|
-
};
|
|
704
|
-
// Loop-local state. Declared here (before the try) so the initial observe + the per-turn
|
|
705
|
-
// frame guard can fail closed cleanly while these still scope across the loop.
|
|
706
|
-
let previousResponseId;
|
|
707
|
-
let previousExecution;
|
|
708
|
-
let closingObservation;
|
|
709
|
-
let closingTrigger;
|
|
710
|
-
let debrief;
|
|
711
|
-
let consecutiveIdle = 0;
|
|
712
|
-
// One canonical "no progress" signal: turns that did not change the UI state
|
|
713
|
-
// signature (idle or not). The nudge, the stop threshold, and the reason all
|
|
714
|
-
// key off this counter, and it catches alternating idle/no-progress stalls
|
|
715
|
-
// that two separate counters would let slip past every backstop but the clock.
|
|
716
|
-
let consecutiveNoProgress = 0;
|
|
717
|
-
let lastSignature = "";
|
|
718
|
-
let contextHint;
|
|
719
|
-
let idleProgressForgivenessUsed = 0;
|
|
720
|
-
// Acks granted for the previous turn's safety checks. They must ride the
|
|
721
|
-
// NEXT request (the one carrying that call's computer_call_output), so they
|
|
722
|
-
// are staged here rather than written onto the request already sent.
|
|
723
|
-
let pendingAcks;
|
|
724
|
-
try {
|
|
725
|
-
currentPhase = "observing initial UI state";
|
|
726
|
-
// Legacy executors retry a stalled observe once (#480). A transport that cannot safely
|
|
727
|
-
// replay pending requests opts out, so even a shorter outer bound stops without retrying.
|
|
728
|
-
const observeBounded = async (label) => {
|
|
729
|
-
try {
|
|
730
|
-
return await raceBounded(`observe (${label})`, executor.observe(), remaining(), observationTimeoutMs, signal);
|
|
731
|
-
}
|
|
732
|
-
catch (error) {
|
|
733
|
-
if (!(error instanceof CuaStallError))
|
|
734
|
-
throw error;
|
|
735
|
-
if (executor.stallRecovery === "fail_closed") {
|
|
736
|
-
// The outer bound says nothing about whether the still-pending request completed.
|
|
737
|
-
// The owning session will close it; this loop must not send a replacement request.
|
|
738
|
-
throw new CuaExecutorError("deadline_exceeded", "outcome_uncertain");
|
|
739
|
-
}
|
|
740
|
-
record({
|
|
741
|
-
id: nextId("notice"),
|
|
742
|
-
kind: "notice",
|
|
743
|
-
lifecycle: "completed",
|
|
744
|
-
status: "warn",
|
|
745
|
-
title: "observation stalled; retrying once",
|
|
746
|
-
text: `${error.what} produced nothing within ${error.afterMs}ms; asking the desktop again`
|
|
747
|
-
});
|
|
748
|
-
return await raceBounded(`observe (${label}, retry)`, executor.observe(), remaining(), observationTimeoutMs, signal);
|
|
749
|
-
}
|
|
750
|
-
};
|
|
751
|
-
const seenSpeechIds = new Set();
|
|
752
|
-
let pendingHeardSpeech = [];
|
|
753
|
-
let heardSpeechChanged = false;
|
|
754
|
-
const collectHeardSpeech = (value) => {
|
|
755
|
-
for (const utterance of value.heardSpeech ?? []) {
|
|
756
|
-
if (seenSpeechIds.has(utterance.id))
|
|
757
|
-
continue;
|
|
758
|
-
seenSpeechIds.add(utterance.id);
|
|
759
|
-
pendingHeardSpeech.push(utterance);
|
|
760
|
-
heardSpeechChanged = true;
|
|
761
|
-
record({ id: nextId("notice"), kind: "notice", lifecycle: "completed", status: "ok",
|
|
762
|
-
title: "speech heard", text: redactNarration(utterance.text) });
|
|
763
|
-
}
|
|
764
|
-
if (pendingHeardSpeech.length > CUA_SPEECH_LIMITS.utterances) {
|
|
765
|
-
throw new CuaExecutorError("invalid_response", "outcome_uncertain");
|
|
766
|
-
}
|
|
767
|
-
return pendingHeardSpeech.length === 0 ? value : { ...value, heardSpeech: pendingHeardSpeech.slice() };
|
|
768
|
-
};
|
|
769
|
-
// The declared observation window (#510). The harness holds, looks, and takes nothing back to
|
|
770
|
-
// the model: no action, no turn, no tokens. It runs once, cut to whatever session budget is
|
|
771
|
-
// left, and says in the trace that the time was deliberate.
|
|
772
|
-
let dwellDone = false;
|
|
773
|
-
let dwellHeldMs = 0;
|
|
774
|
-
const dwellIfDue = async (observation, turnNumber) => {
|
|
775
|
-
if (dwell === undefined || dwellDone)
|
|
776
|
-
return undefined;
|
|
777
|
-
if (dwell.when !== undefined && evaluateStopWhen(dwell.when, stopObservationOf(observation)) === undefined)
|
|
778
|
-
return undefined;
|
|
779
|
-
dwellDone = true;
|
|
780
|
-
const trigger = dwell.when === undefined ? "at the start" : "its condition matched";
|
|
781
|
-
const budget = Math.min(dwell.ms, Math.max(0, remaining() - dwell.everyMs));
|
|
782
|
-
if (budget < dwell.everyMs) {
|
|
783
|
-
record({
|
|
784
|
-
id: nextId("notice"),
|
|
785
|
-
kind: "notice",
|
|
786
|
-
lifecycle: "completed",
|
|
787
|
-
status: "warn",
|
|
788
|
-
title: "dwell window skipped",
|
|
789
|
-
text: `${trigger} at turn ${turnNumber}, but only ${Math.max(0, remaining())}ms of session budget remained for a ${dwell.ms}ms window`
|
|
790
|
-
});
|
|
791
|
-
return undefined;
|
|
792
|
-
}
|
|
793
|
-
const dwellStartedAtMs = now();
|
|
794
|
-
record({
|
|
795
|
-
id: nextId("notice"),
|
|
796
|
-
kind: "notice",
|
|
797
|
-
lifecycle: "started",
|
|
798
|
-
title: "dwell window started",
|
|
799
|
-
text: `${trigger} at turn ${turnNumber}: holding ${budget}ms, a frame every ${dwell.everyMs}ms, no actions, no model turns`
|
|
800
|
-
});
|
|
801
|
-
let frames = 0;
|
|
802
|
-
while (now() - dwellStartedAtMs < budget) {
|
|
803
|
-
if (signal?.aborted)
|
|
804
|
-
throw new CuaAbortError();
|
|
805
|
-
await sleep(Math.min(dwell.everyMs, budget - (now() - dwellStartedAtMs)));
|
|
806
|
-
currentPhase = `dwell frame ${frames + 1}`;
|
|
807
|
-
const frameObservation = collectHeardSpeech(await observeBounded(`dwell frame ${frames + 1}`));
|
|
808
|
-
frames += 1;
|
|
809
|
-
if (frameObservation.screenshot !== undefined)
|
|
810
|
-
onScreenshot?.(frameObservation.screenshot);
|
|
811
|
-
await maybeRecordScreenshot(frameObservation, `dwell-${frames.toString().padStart(2, "0")}`);
|
|
812
|
-
flushTrace();
|
|
813
|
-
observeTasks(frameObservation, turnNumber);
|
|
814
|
-
}
|
|
815
|
-
dwellHeldMs = now() - dwellStartedAtMs;
|
|
816
|
-
record({
|
|
817
|
-
id: nextId("notice"),
|
|
818
|
-
kind: "notice",
|
|
819
|
-
lifecycle: "completed",
|
|
820
|
-
// A window that ENDS the session is structured, harness-owned completion evidence, the
|
|
821
|
-
// same class as a matched stopWhen, and the verdict resolver reads it that way.
|
|
822
|
-
status: dwell.then === "stop" ? "matched" : "ok",
|
|
823
|
-
title: "dwell window complete",
|
|
824
|
-
text: `${frames} frame(s) over ${dwellHeldMs}ms; no model turn was requested during the window`
|
|
825
|
-
});
|
|
826
|
-
if (dwell.then === "stop")
|
|
827
|
-
return "stop";
|
|
828
|
-
contextHint = `The study held this page under observation for ${Math.round(dwellHeldMs / 1000)} seconds (a declared dwell window; you took no actions in that time). Continue the mission from the current state of the page.`;
|
|
829
|
-
return "continue";
|
|
830
|
-
};
|
|
831
|
-
let observation = collectHeardSpeech(await observeBounded("initial"));
|
|
832
|
-
// Runtime-only: hand the seat's live location.href back to the orchestrator (never persisted).
|
|
833
|
-
onObservedUrl?.(observation.url);
|
|
834
|
-
if (observation.screenshot !== undefined)
|
|
835
|
-
onScreenshot?.(observation.screenshot);
|
|
836
|
-
if (observation.appState !== undefined)
|
|
837
|
-
observedAppState = true;
|
|
838
|
-
// Fail closed BEFORE the first turn if a vision provider got a screenshot-less observation.
|
|
839
|
-
if (frameGuardTripped(observation))
|
|
840
|
-
throw new CuaFrameGuardStop();
|
|
841
|
-
await maybeRecordScreenshot(observation, "turn-00-start");
|
|
842
|
-
flushTrace();
|
|
843
|
-
observeTasks(observation, 0);
|
|
844
|
-
const initialDwell = await dwellIfDue(observation, 0);
|
|
845
|
-
if (initialDwell !== undefined) {
|
|
846
|
-
observation = collectHeardSpeech(await observeBounded("after dwell"));
|
|
847
|
-
onObservedUrl?.(observation.url);
|
|
848
|
-
if (observation.screenshot !== undefined)
|
|
849
|
-
onScreenshot?.(observation.screenshot);
|
|
850
|
-
await maybeRecordScreenshot(observation, "turn-00-after-dwell");
|
|
851
|
-
observeTasks(observation, 0);
|
|
852
|
-
if (initialDwell === "stop") {
|
|
853
|
-
completionReason = "goal_satisfied";
|
|
854
|
-
reason = `dwell window complete (${dwellHeldMs}ms held at the start)`;
|
|
855
|
-
closingObservation = observation;
|
|
856
|
-
closingTrigger = "dwell";
|
|
857
|
-
throw new CuaStopWhenStop();
|
|
858
|
-
}
|
|
859
|
-
}
|
|
860
|
-
stopConditionMatch = matchedStopWhen(observation);
|
|
861
|
-
if (stopConditionMatch) {
|
|
862
|
-
completionReason = "goal_satisfied";
|
|
863
|
-
reason = stopWhenReason(stopConditionMatch);
|
|
864
|
-
closingObservation = observation;
|
|
865
|
-
closingTrigger = "stop_when";
|
|
866
|
-
record(stopWhenTraceItem(nextId("notice"), stopConditionMatch, redactNarration));
|
|
867
|
-
throw new CuaStopWhenStop();
|
|
868
|
-
}
|
|
869
|
-
// The progress key prefers a stable appState projection (route/turn/modal deltas drive
|
|
870
|
-
// progress) and falls back to the executor's stateSignature — so a state executor with a
|
|
871
|
-
// constant signature still registers progress, and a vision executor behaves exactly as before.
|
|
872
|
-
lastSignature = progressKeyOf(observation);
|
|
873
|
-
// Bounded by wall-clock and the friction backstops, never a turn count.
|
|
874
|
-
for (;;) {
|
|
875
|
-
if (signal?.aborted) {
|
|
876
|
-
completionReason = "harness_error";
|
|
877
|
-
reason = "run aborted by the harness";
|
|
878
|
-
stopCause = "harness_aborted";
|
|
879
|
-
break;
|
|
880
|
-
}
|
|
881
|
-
if (now() - startedAtMs > timeoutMs) {
|
|
882
|
-
stopCause = "time_limit";
|
|
883
|
-
if (materialActions > 0) {
|
|
884
|
-
completionReason = "budget_reached";
|
|
885
|
-
reason = `reached the ${timeoutMs}ms time budget after productive activity (${materialActions} material action(s), ${counts.turns} turn(s))`;
|
|
886
|
-
}
|
|
887
|
-
else {
|
|
888
|
-
completionReason = "timed_out";
|
|
889
|
-
reason = `wall-clock deadline reached after ${timeoutMs}ms with no material progress`;
|
|
890
|
-
}
|
|
891
|
-
break;
|
|
892
|
-
}
|
|
893
|
-
const turnNumber = (counts.turns ?? 0) + 1;
|
|
894
|
-
const request = { instructions, observation, ...(provider.requestPolicy !== "fail_closed" || previousExecution === undefined ? {} : { previousExecution }) };
|
|
895
|
-
if (previousResponseId !== undefined)
|
|
896
|
-
request.previousResponseId = previousResponseId;
|
|
897
|
-
if (contextHint !== undefined)
|
|
898
|
-
request.contextHint = contextHint;
|
|
899
|
-
if (pendingAcks !== undefined)
|
|
900
|
-
request.acknowledgedSafetyChecks = pendingAcks;
|
|
901
|
-
contextHint = undefined;
|
|
902
|
-
pendingAcks = undefined;
|
|
903
|
-
currentPhase = `requesting provider turn ${turnNumber}`;
|
|
904
|
-
// Bounded per call (#469): one hung request used to be indistinguishable from thinking
|
|
905
|
-
// and cost the lane its whole remaining budget. One retry with a notice; then the lane ends
|
|
906
|
-
// as harness_error, named, instead of thirty silent minutes.
|
|
907
|
-
let turn;
|
|
908
|
-
// A timeout race alone does not cancel its losing provider promise. Strict accounting
|
|
909
|
-
// owns this signal so a delayed transport failure cannot retry after the loop has ended.
|
|
910
|
-
if (provider.requestPolicy === "fail_closed") {
|
|
911
|
-
turn = await markedRequest(request, "interaction", turnTimeoutMs);
|
|
912
|
-
}
|
|
913
|
-
else {
|
|
914
|
-
const requestController = requiresUsage ? new AbortController() : undefined;
|
|
915
|
-
const onRequestAbort = () => requestController?.abort();
|
|
916
|
-
if (requestController) {
|
|
917
|
-
if (signal?.aborted)
|
|
918
|
-
requestController.abort();
|
|
919
|
-
else
|
|
920
|
-
signal?.addEventListener("abort", onRequestAbort, { once: true });
|
|
921
|
-
}
|
|
922
|
-
const requestSignal = requestController?.signal ?? signal ?? neverAbort;
|
|
923
|
-
try {
|
|
924
|
-
turn = await raceBounded(`provider turn ${turnNumber}`, provider.nextTurn(request, requestSignal), remaining(), turnTimeoutMs, signal);
|
|
925
|
-
}
|
|
926
|
-
catch (error) {
|
|
927
|
-
if (isCuaAdmissionLimitError(error)) {
|
|
928
|
-
stopForAdmissionLimit();
|
|
929
|
-
break;
|
|
930
|
-
}
|
|
931
|
-
// A thrown request may have been billed without returning usage. Admission refusal is
|
|
932
|
-
// the explicit no-dispatch exception above; strict capped routes cannot safely retry.
|
|
933
|
-
if (requiresUsage) {
|
|
934
|
-
stopForUnreportedUsage();
|
|
935
|
-
break;
|
|
936
|
-
}
|
|
937
|
-
if (!(error instanceof CuaStallError))
|
|
938
|
-
throw error;
|
|
939
|
-
unreportedInteractionUsage = true;
|
|
940
|
-
record({
|
|
941
|
-
id: nextId("notice"),
|
|
942
|
-
kind: "notice",
|
|
943
|
-
lifecycle: "completed",
|
|
944
|
-
status: "warn",
|
|
945
|
-
title: "provider turn stalled; retrying once",
|
|
946
|
-
text: `${error.what} produced nothing within ${error.afterMs}ms; sending the same observation again`
|
|
947
|
-
});
|
|
948
|
-
try {
|
|
949
|
-
turn = await raceBounded(`provider turn ${turnNumber} (retry)`, provider.nextTurn(request, signal ?? neverAbort), remaining(), turnTimeoutMs, signal);
|
|
950
|
-
}
|
|
951
|
-
catch (retryError) {
|
|
952
|
-
if (isCuaAdmissionLimitError(retryError)) {
|
|
953
|
-
stopForAdmissionLimit();
|
|
954
|
-
break;
|
|
955
|
-
}
|
|
956
|
-
if (!(retryError instanceof CuaStallError))
|
|
957
|
-
throw retryError;
|
|
958
|
-
unreportedInteractionUsage = true;
|
|
959
|
-
completionReason = "harness_error";
|
|
960
|
-
reason = `provider turn ${turnNumber} stalled twice (${retryError.afterMs}ms each); the model produced no turn and the lane was ended rather than left to run out its budget`;
|
|
961
|
-
record({
|
|
962
|
-
id: nextId("notice"),
|
|
963
|
-
kind: "notice",
|
|
964
|
-
lifecycle: "completed",
|
|
965
|
-
status: "error",
|
|
966
|
-
title: "provider turn stalled twice",
|
|
967
|
-
text: reason
|
|
968
|
-
});
|
|
969
|
-
break;
|
|
970
|
-
}
|
|
971
|
-
}
|
|
972
|
-
finally {
|
|
973
|
-
if (requestController)
|
|
974
|
-
signal?.removeEventListener("abort", onRequestAbort);
|
|
975
|
-
requestController?.abort();
|
|
976
|
-
}
|
|
977
|
-
}
|
|
978
|
-
if (request.contextHint)
|
|
979
|
-
record({ id: nextId("notice"), kind: "notice", title: "Participant context hint", text: redactNarration(request.contextHint), lifecycle: "completed" });
|
|
980
|
-
bump("turns");
|
|
981
|
-
pendingHeardSpeech = [];
|
|
982
|
-
heardSpeechChanged = false;
|
|
983
|
-
previousResponseId = turn.responseId ?? previousResponseId;
|
|
984
|
-
lastResponseId = turn.responseId ?? lastResponseId;
|
|
985
|
-
recordUsage(turn);
|
|
986
|
-
// A host-authenticated provider may learn its account billing class during
|
|
987
|
-
// startup. Never price that account usage from an API model rate.
|
|
988
|
-
if (provider.executionProfile?.billing === "account-unknown" &&
|
|
989
|
-
(maxUsd !== undefined || overRunBudget !== undefined || estimateTurnCostUsd !== undefined)) {
|
|
990
|
-
completionReason = "harness_error";
|
|
991
|
-
reason = "Codex is using a ChatGPT account; API dollar caps cannot bound account usage. Use a finite timeout or the OpenAI API participant.";
|
|
992
|
-
break;
|
|
993
|
-
}
|
|
994
|
-
if (turn.interruption !== undefined) {
|
|
995
|
-
// A provider can exhaust its response budget before producing visible text, or midway
|
|
996
|
-
// through an action. Preserve usage and partial narration, but never interpret either as
|
|
997
|
-
// participant completion or dispatch actions from an explicitly incomplete response.
|
|
998
|
-
overRunBudget?.(runningUsage());
|
|
999
|
-
if (turn.reasoning) {
|
|
1000
|
-
record({ id: nextId("reasoning"), kind: "reasoning", lifecycle: "completed", status: "warn",
|
|
1001
|
-
title: `incomplete reasoning turn ${turnNumber}`, text: redactNarration(turn.reasoning) });
|
|
1002
|
-
bump("reasonings");
|
|
1003
|
-
}
|
|
1004
|
-
if (turn.message) {
|
|
1005
|
-
record({ id: nextId("message"), kind: "message", lifecycle: "completed", status: "warn",
|
|
1006
|
-
title: `incomplete message turn ${turnNumber}`, text: redactNarration(turn.message) });
|
|
1007
|
-
bump("messages");
|
|
1008
|
-
}
|
|
1009
|
-
const tokenLimit = turn.interruption === "token_limit" || turn.interruption === "output_limit";
|
|
1010
|
-
stopCause = turn.interruption === "output_limit" ? "provider_output_limit"
|
|
1011
|
-
: tokenLimit ? "provider_token_limit" : turn.interruption === "unexpected_status" ? "provider_status" : "provider_incomplete";
|
|
1012
|
-
const unexpectedStatus = turn.interruption === "unexpected_status";
|
|
1013
|
-
completionReason = tokenLimit ? "budget_reached" : "harness_error";
|
|
1014
|
-
reason = tokenLimit
|
|
1015
|
-
? "the provider's output/context token limit interrupted this response; the participant did not report completion. No actions or closing request followed the incomplete response."
|
|
1016
|
-
: unexpectedStatus
|
|
1017
|
-
? "the provider returned an unexpected noncompleted response status; the participant did not report completion. No actions or closing request followed this response."
|
|
1018
|
-
: "the provider returned an explicitly incomplete response; the participant did not report completion. No actions or closing request followed the incomplete response.";
|
|
1019
|
-
record({ id: nextId("notice"), kind: "notice", lifecycle: "completed", status: tokenLimit ? "warn" : "error",
|
|
1020
|
-
title: tokenLimit ? "provider token limit reached" : unexpectedStatus ? "unexpected provider response status" : "provider response incomplete", text: reason });
|
|
1021
|
-
break;
|
|
1022
|
-
}
|
|
1023
|
-
if (requiresUsage && usageUnavailableForCap()) {
|
|
1024
|
-
stopForUnreportedUsage();
|
|
1025
|
-
break;
|
|
1026
|
-
}
|
|
1027
|
-
// RUNTIME-ONLY: hand the model's narration back so the concurrent host-first barrier can read
|
|
1028
|
-
// the lobby code the host states after creating the lobby (CDP url-read is unreliable). Raw
|
|
1029
|
-
// text stays in memory; only an extracted code is used (and only as a digest).
|
|
1030
|
-
{
|
|
1031
|
-
const narration = [turn.reasoning, turn.message]
|
|
1032
|
-
.filter((t) => typeof t === "string" && t.length > 0)
|
|
1033
|
-
.join("\n");
|
|
1034
|
-
if (narration.length > 0)
|
|
1035
|
-
onMessage?.(narration);
|
|
1036
|
-
}
|
|
1037
|
-
// FAIL-CLOSED spend cap (runaway-retry guard). Placed alongside the wall-clock runaway stop
|
|
1038
|
-
// above and BEFORE the next provider.nextTurn request, so a model stuck retrying cannot keep
|
|
1039
|
-
// spending: the moment the running estimate crosses maxUsd the loop breaks with a terminal,
|
|
1040
|
-
// non-harness-error stop. A null estimate cannot trip it (preflight guaranteed a rate).
|
|
1041
|
-
//
|
|
1042
|
-
// A harness spend cap interrupts the session regardless of prior activity. budget_reached
|
|
1043
|
-
// maps to incomplete; zero executed actions do not establish that the participant gave up.
|
|
1044
|
-
// Cite the running estimate, cap, and progress so the operator can inspect the interruption.
|
|
1045
|
-
if (maxUsd !== undefined && estimateTurnCostUsd) {
|
|
1046
|
-
const running = estimateTurnCostUsd(runningUsage());
|
|
1047
|
-
// Fail CLOSED and LOUD on a non-finite estimate: a stale positional estimator (the
|
|
1048
|
-
// pre-#334 (input, output, cachedInput) signature) arithmetics the usage OBJECT into
|
|
1049
|
-
// NaN, and NaN > maxUsd is false forever — a spend cap that silently never trips is
|
|
1050
|
-
// the one failure mode this guard exists to prevent (red-team finding).
|
|
1051
|
-
if (running !== null && !Number.isFinite(running)) {
|
|
1052
|
-
completionReason = "harness_error";
|
|
1053
|
-
reason = "the injected estimateTurnCostUsd returned a non-finite estimate while execution.caps.maxUsd is set — likely a stale pre-#334 positional (input, output, cachedInput) callback; it now receives one ActorTokenUsage object. Failing closed instead of running uncapped.";
|
|
1054
|
-
break;
|
|
1055
|
-
}
|
|
1056
|
-
if (running !== null && running > maxUsd) {
|
|
1057
|
-
stopCause = "spend_limit";
|
|
1058
|
-
if (materialActions > 0) {
|
|
1059
|
-
completionReason = "budget_reached";
|
|
1060
|
-
reason = `estimated spend $${running} crossed execution.caps.maxUsd=$${maxUsd} after productive activity (${materialActions} material action(s), ${counts.turns} turn(s)); aborted fail-closed before the next model turn`;
|
|
1061
|
-
}
|
|
1062
|
-
else {
|
|
1063
|
-
completionReason = "budget_reached";
|
|
1064
|
-
reason = `estimated spend $${running} crossed execution.caps.maxUsd=$${maxUsd} with no material progress; aborted fail-closed before the next model turn`;
|
|
1065
|
-
}
|
|
1066
|
-
break;
|
|
1067
|
-
}
|
|
1068
|
-
}
|
|
1069
|
-
// The STUDY budget (#299), beside the per-lane cap above and before any further model turn.
|
|
1070
|
-
if (overRunBudget) {
|
|
1071
|
-
const runStop = overRunBudget(runningUsage());
|
|
1072
|
-
if (runStop !== null) {
|
|
1073
|
-
stopCause = "study_spend_limit";
|
|
1074
|
-
completionReason = "budget_reached";
|
|
1075
|
-
reason = runStop;
|
|
1076
|
-
break;
|
|
1077
|
-
}
|
|
1078
|
-
}
|
|
1079
|
-
if (turn.reasoning) {
|
|
1080
|
-
record({
|
|
1081
|
-
id: nextId("reasoning"),
|
|
1082
|
-
kind: "reasoning",
|
|
1083
|
-
lifecycle: "completed",
|
|
1084
|
-
title: `reasoning turn ${turnNumber}`,
|
|
1085
|
-
text: redactNarration(turn.reasoning)
|
|
1086
|
-
});
|
|
1087
|
-
bump("reasonings");
|
|
1088
|
-
}
|
|
1089
|
-
if (turn.message) {
|
|
1090
|
-
record({
|
|
1091
|
-
id: nextId("message"),
|
|
1092
|
-
kind: "message",
|
|
1093
|
-
lifecycle: "completed",
|
|
1094
|
-
title: `message turn ${turnNumber}`,
|
|
1095
|
-
text: redactNarration(turn.message)
|
|
1096
|
-
});
|
|
1097
|
-
bump("messages");
|
|
1098
|
-
}
|
|
1099
|
-
if (turn.pendingSafetyChecks.length > 0) {
|
|
1100
|
-
const acks = acknowledgeSafetyChecks(turn.pendingSafetyChecks);
|
|
1101
|
-
if (acks === null || acks.length === 0) {
|
|
1102
|
-
// Safety-check categories are provider-defined enums (e.g.
|
|
1103
|
-
// "malicious_instructions"), not free text; record them (redacted for
|
|
1104
|
-
// defense-in-depth) so the evidence shows WHY the run paused.
|
|
1105
|
-
const checks = redaction.redactText(turn.pendingSafetyChecks.map((check) => check.code).join(", "));
|
|
1106
|
-
record({
|
|
1107
|
-
id: nextId("approval"),
|
|
1108
|
-
kind: "approval",
|
|
1109
|
-
lifecycle: "completed",
|
|
1110
|
-
status: "blocked",
|
|
1111
|
-
title: `safety check: ${checks}`
|
|
1112
|
-
});
|
|
1113
|
-
completionReason = "blocked_approval";
|
|
1114
|
-
reason = `paused on model safety check(s): ${checks}; not acknowledged`;
|
|
1115
|
-
break;
|
|
1116
|
-
}
|
|
1117
|
-
pendingAcks = acks;
|
|
1118
|
-
}
|
|
1119
|
-
if (turn.done || turn.actions.length === 0) {
|
|
1120
|
-
// The participant's own word, when its reply format has one (#570). "not_reached" is a
|
|
1121
|
-
// participant who stopped without finishing: gave_up, which tallies as abandoned. "blocked"
|
|
1122
|
-
// keeps goal_satisfied here (the actor did stop on purpose) and the lane's credibility read
|
|
1123
|
-
// turns it into a blocked participant, the same path a narrated blocker takes.
|
|
1124
|
-
// A schema field first; failing that, the fixed first line the prompt asks for (#570).
|
|
1125
|
-
const outcome = turn.outcome ?? declaredOutcomeFromClosingLine(turn.message);
|
|
1126
|
-
if (outcome !== undefined)
|
|
1127
|
-
declaredOutcome = outcome;
|
|
1128
|
-
completionReason = outcome === "not_reached" ? "gave_up" : "goal_satisfied";
|
|
1129
|
-
const summary = turn.message?.trim();
|
|
1130
|
-
reason = summary
|
|
1131
|
-
? redactNarration(summary)
|
|
1132
|
-
: "model reported a natural endpoint with no further action";
|
|
1133
|
-
// A done turn takes no actions, so the cadence above never observes the participant's
|
|
1134
|
-
// FINAL state — and a task completed by that state read as incomplete. The first live
|
|
1135
|
-
// study caught it: both participants reached the dashboard, said so, and the funnel
|
|
1136
|
-
// reported 0/2. One guarded closing observation feeds the tracker; a failed observe
|
|
1137
|
-
// ordinarily changes nothing (the funnel stays honest about what it saw), and no
|
|
1138
|
-
// screenshot or stop evaluation rides it — the session is already over. An explicit
|
|
1139
|
-
// executor failure still fails the harness instead of disappearing behind completion.
|
|
1140
|
-
if (taskTracker !== undefined) {
|
|
1141
|
-
try {
|
|
1142
|
-
currentPhase = "observing closing task state";
|
|
1143
|
-
const closing = collectHeardSpeech(await observeBounded("closing"));
|
|
1144
|
-
observeTasks(closing, turnNumber);
|
|
1145
|
-
}
|
|
1146
|
-
catch (error) {
|
|
1147
|
-
// Ordinary closing observations remain best-effort. A declared executor failure
|
|
1148
|
-
// must not disappear behind a participant's reported success.
|
|
1149
|
-
if (isCuaExecutorError(error))
|
|
1150
|
-
throw error;
|
|
1151
|
-
}
|
|
1152
|
-
}
|
|
1153
|
-
break;
|
|
1154
|
-
}
|
|
1155
|
-
const idleThisTurn = isIdleTurn(turn.actions);
|
|
1156
|
-
previousExecution = { actions: [] };
|
|
1157
|
-
let rejectedActionTitle;
|
|
1158
|
-
for (const [actionIndex, action] of turn.actions.entries()) {
|
|
1159
|
-
if (signal?.aborted)
|
|
1160
|
-
throw new CuaAbortError();
|
|
1161
|
-
const actionTitle = describeCuaAction(action);
|
|
1162
|
-
lastActionTitle = actionTitle;
|
|
1163
|
-
recentActionTitles.push(actionTitle);
|
|
1164
|
-
if (recentActionTitles.length > 8)
|
|
1165
|
-
recentActionTitles.shift();
|
|
1166
|
-
// Captured so a recovered (skipped) material action can restore it: a
|
|
1167
|
-
// skipped action must not leave its title as the "last material action".
|
|
1168
|
-
const priorMaterialActionTitle = lastMaterialActionTitle;
|
|
1169
|
-
if (!isIdleAction(action)) {
|
|
1170
|
-
lastMaterialActionTitle = actionTitle;
|
|
1171
|
-
materialActions += 1;
|
|
1172
|
-
counts.materialActions = materialActions;
|
|
1173
|
-
}
|
|
1174
|
-
bump("actions");
|
|
1175
|
-
// Classify BEFORE execute, mirroring counts.actions: the record is of what the actor
|
|
1176
|
-
// CHOSE, so an action that then fails to actuate is still an honest record of the route
|
|
1177
|
-
// it reached for.
|
|
1178
|
-
affordanceObservations.push(classifyCuaAction(action));
|
|
1179
|
-
currentPhase = `executing ${actionTitle}`;
|
|
1180
|
-
// Record the action as completed only AFTER execute() resolves: a failed
|
|
1181
|
-
// action must not appear as a plainly-completed ui_action (#248). On
|
|
1182
|
-
// failure the error notice below captures the failing action + phase.
|
|
1183
|
-
const executeAction = async (idleBound) => {
|
|
1184
|
-
const actionController = new AbortController();
|
|
1185
|
-
const onAbort = () => actionController.abort();
|
|
1186
|
-
if (signal?.aborted)
|
|
1187
|
-
actionController.abort();
|
|
1188
|
-
else
|
|
1189
|
-
signal?.addEventListener("abort", onAbort, { once: true });
|
|
1190
|
-
try {
|
|
1191
|
-
const pending = executor.execute(action, actionController.signal);
|
|
1192
|
-
if (idleBound === undefined)
|
|
1193
|
-
await raceSettle(pending, remaining(), signal);
|
|
1194
|
-
else
|
|
1195
|
-
await raceBounded(`idle action ${actionTitle}`, pending, remaining(), idleBound, signal);
|
|
1196
|
-
}
|
|
1197
|
-
catch (error) {
|
|
1198
|
-
if (error instanceof CuaStallError && executor.stallRecovery === "fail_closed") {
|
|
1199
|
-
throw new CuaExecutorError("deadline_exceeded", "outcome_uncertain");
|
|
1200
|
-
}
|
|
1201
|
-
if (error instanceof CuaDeadlineError || error instanceof CuaAbortError) {
|
|
1202
|
-
// The loop's deadline/abort may win before the executor can report whether its
|
|
1203
|
-
// write reached the desktop. Cancellation alone does not establish rollback.
|
|
1204
|
-
interruptedActionOutcome = true;
|
|
1205
|
-
record({
|
|
1206
|
-
id: nextId("notice"), kind: "notice", lifecycle: "completed", status: "warn",
|
|
1207
|
-
title: "action outcome uncertain",
|
|
1208
|
-
text: redactNarration(`action: ${actionTitle}; disposition: outcome_uncertain; the loop stopped waiting before execution was acknowledged; the action was not retried`)
|
|
1209
|
-
});
|
|
1210
|
-
}
|
|
1211
|
-
throw error;
|
|
1212
|
-
}
|
|
1213
|
-
finally {
|
|
1214
|
-
signal?.removeEventListener("abort", onAbort);
|
|
1215
|
-
// A deadline also closes async executor preparation, so a late pointer read
|
|
1216
|
-
// cannot actuate after the loop stopped waiting for this action.
|
|
1217
|
-
actionController.abort();
|
|
1218
|
-
}
|
|
1219
|
-
};
|
|
1220
|
-
let actionSkipped = false;
|
|
1221
|
-
try {
|
|
1222
|
-
if (isIdleAction(action)) {
|
|
1223
|
-
// Observation actions only look (#480). A `wait` that hangs inside the SDK has, by
|
|
1224
|
-
// definition, waited; skipping it with a notice loses nothing the participant chose.
|
|
1225
|
-
const idleBound = observationTimeoutMs + (action.kind === "wait" ? (action.ms ?? 0) : 0);
|
|
1226
|
-
try {
|
|
1227
|
-
await executeAction(idleBound);
|
|
1228
|
-
}
|
|
1229
|
-
catch (error) {
|
|
1230
|
-
if (!(error instanceof CuaStallError))
|
|
1231
|
-
throw error;
|
|
1232
|
-
actionSkipped = true;
|
|
1233
|
-
record({
|
|
1234
|
-
id: nextId("notice"),
|
|
1235
|
-
kind: "notice",
|
|
1236
|
-
lifecycle: "completed",
|
|
1237
|
-
status: "warn",
|
|
1238
|
-
title: "observation action stalled; skipped",
|
|
1239
|
-
text: `${error.what} produced nothing within ${error.afterMs}ms; the desktop was not asked again and the next screenshot decides`
|
|
1240
|
-
});
|
|
1241
|
-
}
|
|
1242
|
-
}
|
|
1243
|
-
else {
|
|
1244
|
-
await executeAction();
|
|
1245
|
-
}
|
|
1246
|
-
}
|
|
1247
|
-
catch (error) {
|
|
1248
|
-
// A declared pre-dispatch action rejection leaves the desktop usable.
|
|
1249
|
-
// Other typed failures retain their terminal handling, independently of
|
|
1250
|
-
// the legacy E2B CommandExitError recovery below.
|
|
1251
|
-
if (isCuaExecutorError(error)) {
|
|
1252
|
-
previousExecution.actions.push({ index: actionIndex, status: error.disposition });
|
|
1253
|
-
if (error.disposition === "not_dispatched" && !isIdleAction(action)) {
|
|
1254
|
-
materialActions -= 1;
|
|
1255
|
-
counts.materialActions = materialActions;
|
|
1256
|
-
lastMaterialActionTitle = priorMaterialActionTitle;
|
|
1257
|
-
}
|
|
1258
|
-
if (error.code === "action_rejected" && error.disposition === "not_dispatched") {
|
|
1259
|
-
rejectedActionTitle = actionTitle;
|
|
1260
|
-
// Later actions may depend on this one (type, then submit). Return
|
|
1261
|
-
// their full acknowledgement list and let a fresh observation decide.
|
|
1262
|
-
for (let index = actionIndex + 1; index < turn.actions.length; index++) {
|
|
1263
|
-
previousExecution.actions.push({ index, status: "not_dispatched" });
|
|
1264
|
-
}
|
|
1265
|
-
record({
|
|
1266
|
-
id: nextId("notice"), kind: "notice", lifecycle: "completed", status: "warn",
|
|
1267
|
-
title: "action rejected before dispatch",
|
|
1268
|
-
text: redactNarration(`action: ${actionTitle}; code: action_rejected; disposition: not_dispatched; remaining batch actions not dispatched: ${turn.actions.length - actionIndex - 1}`)
|
|
1269
|
-
});
|
|
1270
|
-
break;
|
|
1271
|
-
}
|
|
1272
|
-
throw error;
|
|
1273
|
-
}
|
|
1274
|
-
if (!isCommandExitError(error))
|
|
1275
|
-
throw error;
|
|
1276
|
-
if (!isIdleAction(action)) {
|
|
1277
|
-
// The material count was applied above assuming the action would
|
|
1278
|
-
// actuate; it did not, so roll it back — a failed action is not
|
|
1279
|
-
// progress. The next observe() hands the model a fresh screenshot to
|
|
1280
|
-
// adapt, and because a skipped action changes nothing on screen a
|
|
1281
|
-
// persistently-failing run makes no progress and still terminates
|
|
1282
|
-
// honestly via the idle/no-progress backstop (gave_up), never a
|
|
1283
|
-
// silent actor_error and never an infinite loop.
|
|
1284
|
-
materialActions -= 1;
|
|
1285
|
-
counts.materialActions = materialActions;
|
|
1286
|
-
// Roll back the title too, so a later gave_up backstop notice never
|
|
1287
|
-
// cites a never-actuated action as the "last material action" while
|
|
1288
|
-
// counts.materialActions is 0 (honest-evidence invariant).
|
|
1289
|
-
lastMaterialActionTitle = priorMaterialActionTitle;
|
|
1290
|
-
}
|
|
1291
|
-
previousExecution.actions.push({ index: actionIndex, status: "skipped" });
|
|
1292
|
-
const { exitCode, stderrTail } = commandFailureInfo(error);
|
|
1293
|
-
record({
|
|
1294
|
-
id: nextId("notice"),
|
|
1295
|
-
kind: "notice",
|
|
1296
|
-
lifecycle: "completed",
|
|
1297
|
-
status: "error",
|
|
1298
|
-
title: "action skipped: desktop command failed",
|
|
1299
|
-
// Public-safe: describeCuaAction never includes raw typed text, the
|
|
1300
|
-
// exit code is a number, and the tail is only the substrate's own
|
|
1301
|
-
// stderr (tailed+whitespace-collapsed); the whole line is still run
|
|
1302
|
-
// through redactNarration (scrubKnownValues + pattern redaction).
|
|
1303
|
-
text: redactNarration([
|
|
1304
|
-
`action: ${actionTitle}`,
|
|
1305
|
-
exitCode === undefined ? undefined : `exit code: ${exitCode}`,
|
|
1306
|
-
stderrTail.length > 0 ? `stderr: ${stderrTail}` : undefined
|
|
1307
|
-
].filter(Boolean).join("; "))
|
|
1308
|
-
});
|
|
1309
|
-
continue;
|
|
1310
|
-
}
|
|
1311
|
-
previousExecution.actions.push({ index: actionIndex, status: actionSkipped ? "skipped" : "completed" });
|
|
1312
|
-
record({
|
|
1313
|
-
id: nextId("ui_action"),
|
|
1314
|
-
kind: "ui_action",
|
|
1315
|
-
lifecycle: "completed",
|
|
1316
|
-
title: actionTitle,
|
|
1317
|
-
...(action.kind === "speak" ? { text: redactNarration(action.text) } : {}),
|
|
1318
|
-
// Structured pin coordinates (#441), exactly the click classes the Observer
|
|
1319
|
-
// pins render — recorded fact instead of a title re-parse downstream.
|
|
1320
|
-
...(action.kind === "click" || action.kind === "double_click"
|
|
1321
|
-
? { coord: { x: action.x, y: action.y } }
|
|
1322
|
-
: {})
|
|
1323
|
-
});
|
|
1324
|
-
}
|
|
1325
|
-
if (signal?.aborted)
|
|
1326
|
-
throw new CuaAbortError();
|
|
1327
|
-
currentPhase = `observing UI state after turn ${turnNumber}`;
|
|
1328
|
-
observation = collectHeardSpeech(await observeBounded(`after turn ${turnNumber}`));
|
|
1329
|
-
// Runtime-only: hand the seat's live location.href back to the orchestrator (never persisted).
|
|
1330
|
-
onObservedUrl?.(observation.url);
|
|
1331
|
-
if (observation.screenshot !== undefined)
|
|
1332
|
-
onScreenshot?.(observation.screenshot);
|
|
1333
|
-
if (observation.appState !== undefined)
|
|
1334
|
-
observedAppState = true;
|
|
1335
|
-
// Per-turn fail-closed vision guard: a vision provider can never reason over a missing frame.
|
|
1336
|
-
if (frameGuardTripped(observation))
|
|
1337
|
-
break;
|
|
1338
|
-
await maybeRecordScreenshot(observation, `turn-${turnNumber.toString().padStart(2, "0")}`);
|
|
1339
|
-
flushTrace();
|
|
1340
|
-
observeTasks(observation, turnNumber);
|
|
1341
|
-
const dwellOutcome = await dwellIfDue(observation, turnNumber);
|
|
1342
|
-
if (dwellOutcome !== undefined) {
|
|
1343
|
-
observation = collectHeardSpeech(await observeBounded("after dwell"));
|
|
1344
|
-
onObservedUrl?.(observation.url);
|
|
1345
|
-
if (observation.screenshot !== undefined)
|
|
1346
|
-
onScreenshot?.(observation.screenshot);
|
|
1347
|
-
await maybeRecordScreenshot(observation, `turn-${turnNumber.toString().padStart(2, "0")}-after-dwell`);
|
|
1348
|
-
observeTasks(observation, turnNumber);
|
|
1349
|
-
if (dwellOutcome === "stop") {
|
|
1350
|
-
completionReason = "goal_satisfied";
|
|
1351
|
-
reason = `dwell window complete (${dwellHeldMs}ms held after turn ${turnNumber})`;
|
|
1352
|
-
closingObservation = observation;
|
|
1353
|
-
closingTrigger = "dwell";
|
|
1354
|
-
break;
|
|
1355
|
-
}
|
|
1356
|
-
}
|
|
1357
|
-
stopConditionMatch = matchedStopWhen(observation);
|
|
1358
|
-
if (stopConditionMatch) {
|
|
1359
|
-
completionReason = "goal_satisfied";
|
|
1360
|
-
reason = stopWhenReason(stopConditionMatch);
|
|
1361
|
-
closingObservation = observation;
|
|
1362
|
-
closingTrigger = "stop_when";
|
|
1363
|
-
record(stopWhenTraceItem(nextId("notice"), stopConditionMatch, redactNarration));
|
|
1364
|
-
break;
|
|
1365
|
-
}
|
|
1366
|
-
// Progress prefers the stable appState projection; a state executor with a constant
|
|
1367
|
-
// stateSignature still registers progress when its appState changed (and vice versa).
|
|
1368
|
-
const progressKey = progressKeyOf(observation);
|
|
1369
|
-
const frameChanged = progressKey !== lastSignature;
|
|
1370
|
-
lastSignature = progressKey;
|
|
1371
|
-
// CORROBORATION (#383). A stale frame alone is NOT evidence of a stuck agent. The frame hash is
|
|
1372
|
-
// a coarse whole-screen measure, and on a light-themed web app it can miss a renamed row, a new
|
|
1373
|
-
// list item, or an opened panel — a measured run had 9 visibly different consecutive frames hash
|
|
1374
|
-
// identically while the agent was a foreign key away from finishing. Ending a lane on that
|
|
1375
|
-
// signal alone recorded working sessions as `gave_up`, capping every browser run at roughly
|
|
1376
|
-
// noProgressSteps turns and writing harness artifacts into evidence as actor behavior.
|
|
1377
|
-
//
|
|
1378
|
-
// So a no-progress turn now requires BOTH a stale frame AND the agent repeating something it
|
|
1379
|
-
// just tried. An agent doing varied work is never counted stuck, however blind the hash is;
|
|
1380
|
-
// an agent re-clicking the same dead control trips it as fast as it did before — arguably
|
|
1381
|
-
// faster, since that is the actual signature of being stuck.
|
|
1382
|
-
const fingerprint = actionFingerprint(turn.actions);
|
|
1383
|
-
const repeatingRecentAction = fingerprint.length > 0 && recentFingerprints.includes(fingerprint);
|
|
1384
|
-
recentFingerprints.push(fingerprint);
|
|
1385
|
-
if (recentFingerprints.length > ACTION_REPEAT_WINDOW)
|
|
1386
|
-
recentFingerprints.shift();
|
|
1387
|
-
// Corroboration governs the FRAME-STALENESS backstop only. The idle backstop below is a direct
|
|
1388
|
-
// behavioral signal already (the agent took nothing but screenshots and waits), so it keeps
|
|
1389
|
-
// reading the frame on its own — a repeated screenshot is exactly what an idle streak IS, and
|
|
1390
|
-
// feeding repetition into it would grant an extra forgiveness step for being idle.
|
|
1391
|
-
const observedProgress = frameChanged || heardSpeechChanged;
|
|
1392
|
-
const progressed = observedProgress || !repeatingRecentAction;
|
|
1393
|
-
// A screenshot/wait turn while the UI visibly changes may be patience through loading or a
|
|
1394
|
-
// transition, so grant a bounded recovery window. Do not grant infinite immunity: animated
|
|
1395
|
-
// pixels or state-executor turn counters can otherwise keep a screenshot/wait loop alive
|
|
1396
|
-
// until the wall-clock timeout.
|
|
1397
|
-
if (idleThisTurn) {
|
|
1398
|
-
if (observedProgress && idleProgressForgivenessUsed < IDLE_PROGRESS_FORGIVENESS_STEPS) {
|
|
1399
|
-
idleProgressForgivenessUsed += 1;
|
|
1400
|
-
consecutiveIdle = 0;
|
|
1401
|
-
}
|
|
1402
|
-
else {
|
|
1403
|
-
consecutiveIdle += 1;
|
|
1404
|
-
}
|
|
1405
|
-
}
|
|
1406
|
-
else {
|
|
1407
|
-
idleProgressForgivenessUsed = 0;
|
|
1408
|
-
consecutiveIdle = 0;
|
|
1409
|
-
}
|
|
1410
|
-
if (idleThisTurn)
|
|
1411
|
-
bump("idleTurns");
|
|
1412
|
-
consecutiveNoProgress = progressed ? 0 : consecutiveNoProgress + 1;
|
|
1413
|
-
if (!progressed)
|
|
1414
|
-
bump("noProgressTurns");
|
|
1415
|
-
// An unchanged screen can be legitimate waiting (for example, a shared-world lobby).
|
|
1416
|
-
// Recovery may suggest another approach, but must not instruct early abandonment while
|
|
1417
|
-
// the task still calls for waiting. The counters, time and spend guards own hard stops.
|
|
1418
|
-
const contextHints = [];
|
|
1419
|
-
if (rejectedActionTitle !== undefined) {
|
|
1420
|
-
contextHints.push(`Your action (${rejectedActionTitle}) was rejected before dispatch. No input from that action or the rest of its batch was sent. Choose your next action from the fresh screenshot; do not assume the rejected action succeeded.`);
|
|
1421
|
-
}
|
|
1422
|
-
if (consecutiveNoProgress >= noProgressRecoverySteps && consecutiveNoProgress < noProgressSteps) {
|
|
1423
|
-
contextHints.push(`No visible progress for ${consecutiveNoProgress} step(s). ` +
|
|
1424
|
-
"If your task calls for waiting for another participant or a pending transition, you may continue waiting. " +
|
|
1425
|
-
"Choose whether to continue or stop based on your situation and what you observe.");
|
|
1426
|
-
}
|
|
1427
|
-
if (consecutiveIdle >= idleRecoverySteps && consecutiveIdle < idleSteps) {
|
|
1428
|
-
contextHints.push(`You are only waiting or taking screenshots for ${consecutiveIdle} step(s). ` +
|
|
1429
|
-
"If your task calls for waiting, you may continue within the remaining session time. " +
|
|
1430
|
-
"When the relevant controls become actionable, continue your task; describe any blocker you actually encounter.");
|
|
1431
|
-
}
|
|
1432
|
-
if (contextHints.length > 0)
|
|
1433
|
-
contextHint = contextHints.join(" ");
|
|
1434
|
-
if (consecutiveIdle >= idleSteps) {
|
|
1435
|
-
completionReason = "gave_up";
|
|
1436
|
-
reason = `gave up: ${consecutiveIdle} consecutive turns with no material UI action (only screenshot/wait)`;
|
|
1437
|
-
record(backstopTraceItem({
|
|
1438
|
-
id: nextId("notice"),
|
|
1439
|
-
reason,
|
|
1440
|
-
lastMaterialActionTitle,
|
|
1441
|
-
recentActionTitles,
|
|
1442
|
-
screenshotRef: lastScreenshotRef,
|
|
1443
|
-
redactNarration
|
|
1444
|
-
}));
|
|
1445
|
-
break;
|
|
1446
|
-
}
|
|
1447
|
-
if (consecutiveNoProgress >= noProgressSteps) {
|
|
1448
|
-
completionReason = "gave_up";
|
|
1449
|
-
reason = `gave up: ${consecutiveNoProgress} consecutive turns with no change to the UI state`;
|
|
1450
|
-
record(backstopTraceItem({
|
|
1451
|
-
id: nextId("notice"),
|
|
1452
|
-
reason,
|
|
1453
|
-
lastMaterialActionTitle,
|
|
1454
|
-
recentActionTitles,
|
|
1455
|
-
screenshotRef: lastScreenshotRef,
|
|
1456
|
-
redactNarration
|
|
1457
|
-
}));
|
|
1458
|
-
break;
|
|
1459
|
-
}
|
|
1460
|
-
}
|
|
1461
|
-
}
|
|
1462
|
-
catch (error) {
|
|
1463
|
-
if (error instanceof CuaFrameGuardStop || error instanceof CuaStopWhenStop) {
|
|
1464
|
-
// completionReason/reason were already set by the frame guard or stopWhen guard.
|
|
1465
|
-
}
|
|
1466
|
-
else if (error instanceof CuaDeadlineError) {
|
|
1467
|
-
stopCause = "time_limit";
|
|
1468
|
-
if (materialActions > 0) {
|
|
1469
|
-
completionReason = "budget_reached";
|
|
1470
|
-
reason = interruptedActionOutcome
|
|
1471
|
-
? `reached the ${timeoutMs}ms time budget with ${materialActions} material action attempt(s), ${counts.turns} turn(s); the latest action outcome is uncertain`
|
|
1472
|
-
: `reached the ${timeoutMs}ms time budget after productive activity (${materialActions} material action(s), ${counts.turns} turn(s))`;
|
|
1473
|
-
}
|
|
1474
|
-
else {
|
|
1475
|
-
completionReason = "timed_out";
|
|
1476
|
-
reason = `wall-clock deadline reached after ${timeoutMs}ms with no material progress`;
|
|
1477
|
-
}
|
|
1478
|
-
}
|
|
1479
|
-
else if (error instanceof CuaAbortError) {
|
|
1480
|
-
completionReason = "harness_error";
|
|
1481
|
-
reason = "run aborted by the harness";
|
|
1482
|
-
stopCause = "harness_aborted";
|
|
1483
|
-
}
|
|
1484
|
-
else if (isCuaProviderError(error)) {
|
|
1485
|
-
completionReason = "harness_error";
|
|
1486
|
-
reason = `participant provider error: ${error.code}${error.failurePhase ? ` during ${error.failurePhase}` : ""}; cleanup: ${error.receipt.cleanup}`;
|
|
1487
|
-
record({ id: nextId("notice"), kind: "notice", lifecycle: "completed", status: "error",
|
|
1488
|
-
title: "participant provider error", text: reason });
|
|
1489
|
-
}
|
|
1490
|
-
else if (isCuaExecutorError(error)) {
|
|
1491
|
-
completionReason = "harness_error";
|
|
1492
|
-
reason = `desktop executor error: ${error.code}; disposition: ${error.disposition}`;
|
|
1493
|
-
record({
|
|
1494
|
-
id: nextId("notice"), kind: "notice", lifecycle: "completed", status: "error",
|
|
1495
|
-
title: "desktop executor error",
|
|
1496
|
-
text: [
|
|
1497
|
-
`phase: ${redactNarration(currentPhase)}`,
|
|
1498
|
-
`code: ${error.code}`,
|
|
1499
|
-
`disposition: ${error.disposition}`,
|
|
1500
|
-
lastActionTitle === undefined ? undefined : `last action: ${redactNarration(lastActionTitle)}`
|
|
1501
|
-
].filter(Boolean).join("; "),
|
|
1502
|
-
...(lastScreenshotRef === undefined ? {} : { screenshotRef: lastScreenshotRef })
|
|
1503
|
-
});
|
|
1504
|
-
}
|
|
1505
|
-
else {
|
|
1506
|
-
completionReason = "actor_error";
|
|
1507
|
-
const rawMessage = error instanceof Error ? error.message : String(error);
|
|
1508
|
-
const message = redactNarration(rawMessage);
|
|
1509
|
-
reason = redactNarration(`computer-use loop error: ${rawMessage}`);
|
|
1510
|
-
record({
|
|
1511
|
-
id: nextId("notice"),
|
|
1512
|
-
kind: "notice",
|
|
1513
|
-
lifecycle: "completed",
|
|
1514
|
-
status: "error",
|
|
1515
|
-
title: "computer-use loop error",
|
|
1516
|
-
text: [
|
|
1517
|
-
`phase: ${redactNarration(currentPhase)}`,
|
|
1518
|
-
error instanceof Error && error.name ? `error: ${redactNarration(error.name)}` : undefined,
|
|
1519
|
-
`message: ${message}`,
|
|
1520
|
-
lastActionTitle === undefined ? undefined : `last action: ${redactNarration(lastActionTitle)}`
|
|
1521
|
-
].filter(Boolean).join("; "),
|
|
1522
|
-
...(lastScreenshotRef === undefined ? {} : { screenshotRef: lastScreenshotRef })
|
|
1523
|
-
});
|
|
1524
|
-
}
|
|
1525
|
-
}
|
|
1526
|
-
// Structured completion must stop interaction immediately, but the participant may not yet
|
|
1527
|
-
// have spoken. Request one read-only account using the already captured final observation.
|
|
1528
|
-
// No callbacks that coordinate live participants and no executor calls occur after this point.
|
|
1529
|
-
if (closingTrigger !== undefined && closingObservation !== undefined) {
|
|
1530
|
-
const note = (status, detail, usageReported) => {
|
|
1531
|
-
debrief = { trigger: closingTrigger, status, reason: redactNarration(detail),
|
|
1532
|
-
...(usageReported === undefined ? {} : { usageReported }) };
|
|
1533
|
-
record({ id: nextId("notice"), kind: "notice", lifecycle: "completed",
|
|
1534
|
-
status: status === "completed" ? "ok" : "warn", title: `participant debrief ${status}`,
|
|
1535
|
-
text: redactNarration(detail) });
|
|
1536
|
-
};
|
|
1537
|
-
let skip;
|
|
1538
|
-
if ((counts.turns ?? 0) === 0)
|
|
1539
|
-
skip = "the study stopped before any participant turn";
|
|
1540
|
-
else if (provider.debrief === undefined)
|
|
1541
|
-
skip = "this provider does not support read-only closing reports";
|
|
1542
|
-
else if (providerCleanupUnconfirmed)
|
|
1543
|
-
skip = "participant request cleanup is unconfirmed";
|
|
1544
|
-
else if (signal?.aborted)
|
|
1545
|
-
skip = "the study was cancelled";
|
|
1546
|
-
else if (remaining() <= 0)
|
|
1547
|
-
skip = "the session deadline was reached";
|
|
1548
|
-
else if (provider.requiresFrame && closingObservation.screenshot === undefined)
|
|
1549
|
-
skip = "the final observation has no required frame";
|
|
1550
|
-
if (skip === undefined && (maxUsd !== undefined || overRunBudget !== undefined) && usageUnavailableForCap()) {
|
|
1551
|
-
skip = "remaining model budget is unknown because an earlier participant turn did not report complete usage";
|
|
1552
|
-
}
|
|
1553
|
-
if (skip === undefined && maxUsd !== undefined) {
|
|
1554
|
-
const estimate = sawUsage || knownPendingUsage() !== undefined ? estimateTurnCostUsd?.(runningUsage()) : undefined;
|
|
1555
|
-
if (estimate === undefined || estimate === null || !Number.isFinite(estimate))
|
|
1556
|
-
skip = "remaining model budget could not be established";
|
|
1557
|
-
else if (estimate >= maxUsd)
|
|
1558
|
-
skip = "the estimated model budget was reached";
|
|
1559
|
-
}
|
|
1560
|
-
if (skip === undefined && overRunBudget?.(runningUsage()) != null)
|
|
1561
|
-
skip = "the study model budget was reached";
|
|
1562
|
-
if (skip !== undefined) {
|
|
1563
|
-
note("skipped", skip);
|
|
1564
|
-
}
|
|
1565
|
-
else {
|
|
1566
|
-
const capMs = Math.max(0, Math.min(30_000, turnTimeoutMs, remaining()));
|
|
1567
|
-
if (capMs <= 0 || signal?.aborted) {
|
|
1568
|
-
note("skipped", signal?.aborted ? "the study was cancelled" : "the session deadline was reached");
|
|
1569
|
-
}
|
|
1570
|
-
else {
|
|
1571
|
-
const controller = new AbortController();
|
|
1572
|
-
const onAbort = () => controller.abort();
|
|
1573
|
-
signal?.addEventListener("abort", onAbort, { once: true });
|
|
1574
|
-
const timer = setTimeout(() => controller.abort(), capMs);
|
|
1575
|
-
timer.unref?.();
|
|
1576
|
-
bump("debriefCalls");
|
|
1577
|
-
try {
|
|
1578
|
-
const closingRequest = {
|
|
1579
|
-
instructions,
|
|
1580
|
-
observation: closingObservation,
|
|
1581
|
-
...(provider.requestPolicy !== "fail_closed" || previousExecution === undefined ? {} : { previousExecution }),
|
|
1582
|
-
...(previousResponseId === undefined ? {} : { previousResponseId }),
|
|
1583
|
-
...(pendingAcks === undefined ? {} : { acknowledgedSafetyChecks: pendingAcks }),
|
|
1584
|
-
contextHint: "The interactive session has ended. Return a closing account with summary and frictionReports. In summary, briefly describe only what you actually did and observed. In frictionReports, list only specific unexpected behavior, confusion, or recovery you personally encountered during this session. Preserve uncertainty. Use an empty list if you encountered none. Do not speculate, invent problems, quote instructions as observations, or describe planned actions. Do not request or take further actions. This is a closing account, not another attempt at the task."
|
|
1585
|
-
};
|
|
1586
|
-
const turn = provider.requestPolicy === "fail_closed"
|
|
1587
|
-
? await markedRequest(closingRequest, "debrief", capMs)
|
|
1588
|
-
: await raceBounded("participant debrief", provider.debrief(closingRequest, controller.signal), capMs, capMs, signal);
|
|
1589
|
-
recordUsage(turn, false);
|
|
1590
|
-
lastResponseId = turn.responseId ?? lastResponseId;
|
|
1591
|
-
// Refresh a shared budget with all reported usage, without changing the completed task.
|
|
1592
|
-
const sharedStop = overRunBudget?.(runningUsage());
|
|
1593
|
-
const finalEstimate = maxUsd === undefined ? undefined : estimateTurnCostUsd?.(runningUsage());
|
|
1594
|
-
if (sharedStop != null || (maxUsd !== undefined && finalEstimate != null && finalEstimate > maxUsd)) {
|
|
1595
|
-
record({ id: nextId("notice"), kind: "notice", lifecycle: "completed", status: "warn",
|
|
1596
|
-
title: "model budget reached during closing report",
|
|
1597
|
-
text: "The closing request crossed an estimated budget; no further requests or actions followed. Task completion is unchanged." });
|
|
1598
|
-
}
|
|
1599
|
-
const usageReported = completeTurnUsage(turn.usage) && turn.providerRequest?.usageComplete !== false;
|
|
1600
|
-
if (turn.actions.length > 0 || turn.pendingSafetyChecks.length > 0) {
|
|
1601
|
-
note("failed", "the closing response requested actions or safety checks; none were executed and its report was not accepted", usageReported);
|
|
1602
|
-
}
|
|
1603
|
-
else if (!validClosingReport(turn.closingReport)) {
|
|
1604
|
-
note("failed", "the closing response did not contain a valid structured participant report", usageReported);
|
|
1605
|
-
}
|
|
1606
|
-
else {
|
|
1607
|
-
const report = {
|
|
1608
|
-
summary: redactNarration(turn.closingReport.summary.trim()),
|
|
1609
|
-
frictionReports: [...new Set(turn.closingReport.frictionReports.map((text) => redactNarration(text.trim())))]
|
|
1610
|
-
};
|
|
1611
|
-
const messageId = nextId("message");
|
|
1612
|
-
record({ id: messageId, kind: "message", lifecycle: "completed",
|
|
1613
|
-
title: "participant closing report", text: [report.summary, ...report.frictionReports].join("\n\n") });
|
|
1614
|
-
bump("messages");
|
|
1615
|
-
note("completed", "one read-only report; no additional desktop actions; original stop and task outcomes preserved", usageReported);
|
|
1616
|
-
debrief = { ...debrief, report, messageId };
|
|
1617
|
-
}
|
|
1618
|
-
}
|
|
1619
|
-
catch (error) {
|
|
1620
|
-
// A failed optional report cannot rewrite the already observed structured completion.
|
|
1621
|
-
if (isCuaAdmissionLimitError(error)) {
|
|
1622
|
-
note("skipped", "the adapter reported a local admission limit before provider dispatch; no closing request was sent");
|
|
1623
|
-
}
|
|
1624
|
-
else {
|
|
1625
|
-
const detail = signal?.aborted ? "cancelled" : controller.signal.aborted || error instanceof CuaDeadlineError || error instanceof CuaStallError
|
|
1626
|
-
? "closing report deadline reached" : error instanceof Error ? error.message : String(error);
|
|
1627
|
-
const closingReceipt = provider.requestPolicy === "fail_closed" ? providerRequests.at(-1) : undefined;
|
|
1628
|
-
const usageReported = closingReceipt?.usageComplete === true && completeTurnUsage(closingReceipt.usage);
|
|
1629
|
-
note("failed", `${detail}; closing request usage is ${usageReported ? "reported" : "unreported"}`, usageReported);
|
|
1630
|
-
}
|
|
1631
|
-
}
|
|
1632
|
-
finally {
|
|
1633
|
-
clearTimeout(timer);
|
|
1634
|
-
signal?.removeEventListener("abort", onAbort);
|
|
1635
|
-
controller.abort();
|
|
1636
|
-
}
|
|
1637
|
-
}
|
|
1638
|
-
}
|
|
1639
|
-
flushTrace();
|
|
1640
|
-
}
|
|
1641
|
-
const completedAtMs = now();
|
|
1642
|
-
const status = statusForCompletionReason(completionReason);
|
|
1643
|
-
const ids = {};
|
|
1644
|
-
if (provider.version !== undefined)
|
|
1645
|
-
ids.model = provider.version;
|
|
1646
|
-
// responseId is provider-authored and opaque; redact for defense-in-depth.
|
|
1647
|
-
if (lastResponseId !== undefined)
|
|
1648
|
-
ids.turnId = redaction.redactText(lastResponseId);
|
|
1649
|
-
const screenshotNote = !(counts.screenshots && counts.screenshots > 0)
|
|
1650
|
-
? "no screenshots captured"
|
|
1651
|
-
: redactScreenshots
|
|
1652
|
-
? `${counts.screenshots} screenshot(s) redacted to blurred thumbnails via RedactionHooks`
|
|
1653
|
-
: `${counts.screenshots} full-fidelity screenshot(s) retained for local use — NOT redacted for publishing; set redactScreenshots to blur a share-as-is bundle`;
|
|
1654
|
-
// Self-describing artifact (invariant 6): when a non-vision executor surfaced structured app
|
|
1655
|
-
// state, the trace declares HOW it handled that surface — app state drove progress detection
|
|
1656
|
-
// each turn and was NOT written to the trace (it is a runtime-only progress input, like
|
|
1657
|
-
// stateSignature). The appState itself never appears anywhere in this bundle.
|
|
1658
|
-
const notes = observedAppState
|
|
1659
|
-
? `${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.`
|
|
1660
|
-
: screenshotNote;
|
|
1661
|
-
const trace = {
|
|
1662
|
-
schema: ACTOR_TRACE_SCHEMA,
|
|
1663
|
-
provider: provider.id,
|
|
1664
|
-
...liveMetadata(),
|
|
1665
|
-
...(provider.version === undefined ? {} : { providerVersion: provider.version }),
|
|
1666
|
-
protocol: "cua-loop",
|
|
1667
|
-
lane: "computer-use",
|
|
1668
|
-
persona,
|
|
1669
|
-
redaction: {
|
|
1670
|
-
status: "passed",
|
|
1671
|
-
screenshots: !(counts.screenshots && counts.screenshots > 0)
|
|
1672
|
-
? "n/a"
|
|
1673
|
-
: redactScreenshots
|
|
1674
|
-
? "blurred"
|
|
1675
|
-
: "raw",
|
|
1676
|
-
notes
|
|
1677
|
-
},
|
|
1678
|
-
startedAt: new Date(startedAtMs).toISOString(),
|
|
1679
|
-
completedAt: new Date(completedAtMs).toISOString(),
|
|
1680
|
-
durationMs: completedAtMs - startedAtMs,
|
|
1681
|
-
status,
|
|
1682
|
-
completionReason,
|
|
1683
|
-
...(stopCause === undefined ? {} : { stopCause }),
|
|
1684
|
-
reason,
|
|
1685
|
-
ids,
|
|
1686
|
-
...(provider.modelSettings === undefined
|
|
1687
|
-
? {}
|
|
1688
|
-
: { modelSettings: { reasoningEffort: provider.modelSettings.reasoningEffort,
|
|
1689
|
-
...(provider.modelSettings.maxOutputTokens === undefined ? {} : { maxOutputTokens: provider.modelSettings.maxOutputTokens }) } }),
|
|
1690
|
-
counts,
|
|
1691
|
-
items,
|
|
1692
|
-
...(affordanceObservations.length > 0 ? { affordanceUse: summarizeAffordanceUse(affordanceObservations) } : {}),
|
|
1693
|
-
...(declaredOutcome === undefined ? {} : { declaredOutcome }),
|
|
1694
|
-
...(debrief === undefined ? {} : { debrief }),
|
|
1695
|
-
...(interactionRequestPending || hasUnreportedInteractionUsage() || (requiresUsage && incompleteInteractionUsage)
|
|
1696
|
-
? { interactionUsageIncomplete: true } : {}),
|
|
1697
|
-
// The funnel is present exactly when a protocol was declared — including a session that ended
|
|
1698
|
-
// on turn 0, whose funnel honestly reads 0/N. No tasks declared means no funnel, not an empty one.
|
|
1699
|
-
...(taskTracker === undefined ? {} : { taskFunnel: taskTracker.funnel() }),
|
|
1700
|
-
...(sawUsage
|
|
1701
|
-
? {
|
|
1702
|
-
tokenUsage: provider.executionProfile?.billing === "account-unknown" ? accountUsage() : {
|
|
1703
|
-
input: usageInput,
|
|
1704
|
-
output: usageOutput,
|
|
1705
|
-
// Recorded only when the provider actually reported it, so a reader can tell "no cache
|
|
1706
|
-
// hits" from "this provider does not say" (#391); same for cache writes (#334).
|
|
1707
|
-
...(usageCachedInput > 0 ? { cachedInput: usageCachedInput } : {}),
|
|
1708
|
-
...(usageCacheWriteInput > 0 ? { cacheWriteInput: usageCacheWriteInput } : {}),
|
|
1709
|
-
...(usageTurns.length > 0 ? { turns: usageTurns.map((turn) => ({ ...turn })) } : {}),
|
|
1710
|
-
total: usageInput + usageOutput
|
|
1711
|
-
}
|
|
1712
|
-
}
|
|
1713
|
-
: {}),
|
|
1714
|
-
capabilities: provider.capabilities
|
|
1715
|
-
};
|
|
1716
|
-
return { status, completionReason, reason, trace };
|
|
1717
|
-
}
|
|
1718
|
-
function stopWhenReason(match) {
|
|
1719
|
-
return `stopWhen matched ${match.id} (${match.kinds.join("+")})`;
|
|
1720
|
-
}
|
|
1721
|
-
function stopWhenTraceItem(id, match, redactNarration) {
|
|
1722
|
-
return {
|
|
1723
|
-
id,
|
|
1724
|
-
kind: "notice",
|
|
1725
|
-
lifecycle: "completed",
|
|
1726
|
-
status: "matched",
|
|
1727
|
-
title: `stopWhen matched: ${match.id}`,
|
|
1728
|
-
text: redactNarration(`Harness stop condition matched rule ${match.id} using ${match.kinds.join(", ")}. Raw observed URL/text/appState were runtime-only and were not persisted; when a screenshot was available, the immediately preceding screenshot item is the visual evidence for the matched surface.`)
|
|
1729
|
-
};
|
|
1730
|
-
}
|
|
1731
|
-
function backstopTraceItem(args) {
|
|
1732
|
-
const details = [
|
|
1733
|
-
`reason: ${args.reason}`,
|
|
1734
|
-
args.lastMaterialActionTitle === undefined
|
|
1735
|
-
? "last material action: none"
|
|
1736
|
-
: `last material action: ${args.lastMaterialActionTitle}`,
|
|
1737
|
-
args.recentActionTitles.length === 0
|
|
1738
|
-
? "recent actions: none"
|
|
1739
|
-
: `recent actions: ${args.recentActionTitles.join(" -> ")}`
|
|
1740
|
-
];
|
|
1741
|
-
return {
|
|
1742
|
-
id: args.id,
|
|
1743
|
-
kind: "notice",
|
|
1744
|
-
lifecycle: "completed",
|
|
1745
|
-
status: "blocked",
|
|
1746
|
-
title: "computer-use backstop gave up",
|
|
1747
|
-
text: args.redactNarration(details.join("; ")),
|
|
1748
|
-
...(args.screenshotRef === undefined ? {} : { screenshotRef: args.screenshotRef })
|
|
1749
|
-
};
|
|
1750
|
-
}
|
|
1751
|
-
//# sourceMappingURL=computer-use.js.map
|