humanish 0.108.0 → 0.109.1
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/ARCHITECTURE.md +58 -59
- package/CHANGELOG.md +22 -0
- package/CONTEXT.md +44 -44
- package/README.md +3 -3
- package/TELEMETRY.md +2 -2
- package/dist/actors/codex/app-server-trace.js +2 -1
- package/dist/actors/codex/restricted-participant.js +12 -12
- package/dist/actors/codex/restricted-session.d.ts +2 -2
- package/dist/actors/computer-use/actor.d.ts +6 -6
- package/dist/actors/computer-use/actor.js +2 -2
- package/dist/actors/computer-use/admission-limit.d.ts +2 -2
- package/dist/actors/computer-use/admission-limit.js +3 -3
- package/dist/actors/computer-use/executor-error.d.ts +2 -2
- package/dist/actors/computer-use/executor-error.js +3 -3
- package/dist/actors/computer-use/loop/actions.js +5 -5
- package/dist/actors/computer-use/loop/debrief.js +2 -2
- package/dist/actors/computer-use/loop/ending.d.ts +1 -1
- package/dist/actors/computer-use/loop/ending.js +12 -11
- package/dist/actors/computer-use/loop/observation.js +6 -5
- package/dist/actors/computer-use/loop/provider-call.js +11 -11
- package/dist/actors/computer-use/loop/session.d.ts +4 -4
- package/dist/actors/computer-use/loop/session.js +2 -2
- package/dist/actors/computer-use/loop/trace.js +3 -2
- package/dist/actors/computer-use/loop/types.d.ts +24 -24
- package/dist/actors/computer-use/loop/usage.d.ts +2 -2
- package/dist/actors/computer-use/loop.d.ts +6 -1
- package/dist/actors/computer-use/loop.js +26 -4
- package/dist/actors/computer-use/openai-provider.d.ts +2 -2
- package/dist/actors/computer-use/openai-provider.js +8 -8
- package/dist/actors/computer-use/provider-error.d.ts +4 -4
- package/dist/actors/computer-use/provider-error.js +6 -6
- package/dist/actors/contract.d.ts +4 -4
- package/dist/actors/contract.js +1 -1
- package/dist/actors/local-agent/claude-session.js +3 -3
- package/dist/actors/local-agent/cli.d.ts +1 -1
- package/dist/actors/local-agent/cli.js +1 -1
- package/dist/actors/reasoning-effort.js +3 -3
- package/dist/actors/registry.d.ts +2 -2
- package/dist/actors/registry.js +3 -3
- package/dist/actors/scripted-browser/actor.d.ts +2 -2
- package/dist/actors/scripted-browser/actor.js +1 -1
- package/dist/analysis/automatic-completion.d.ts +7 -7
- package/dist/analysis/automatic-completion.js +1 -1
- package/dist/analysis/automatic-config.d.ts +6 -6
- package/dist/analysis/automatic-config.js +1 -1
- package/dist/analysis/execute.d.ts +1 -1
- package/dist/analysis/execute.js +1 -1
- package/dist/analysis/types.d.ts +6 -0
- package/dist/browser-control/client.js +16 -16
- package/dist/browser-control/dispatcher.js +4 -4
- package/dist/browser-control/protocol.js +14 -14
- package/dist/browser-control/recording-transfer.js +4 -4
- package/dist/browser-control/transport.js +7 -7
- package/dist/cli/commands/analysis-signals.d.ts +2 -2
- package/dist/cli/commands/comms.js +14 -22
- package/dist/cli/commands/migrate.js +15 -4
- package/dist/cli/commands/observe.d.ts +0 -1
- package/dist/cli/commands/observe.js +0 -15
- package/dist/cli/commands/run-command.d.ts +2 -2
- package/dist/cli/commands/run-command.js +3 -3
- package/dist/cli/commands/runs.js +9 -7
- package/dist/cli/commands/setup.js +5 -7
- package/dist/cli/commands/study-format.d.ts +9 -0
- package/dist/cli/commands/{lab-format.js → study-format.js} +5 -5
- package/dist/cli/commands/{lab-route-computer-use.d.ts → study-route-computer-use.d.ts} +6 -6
- package/dist/cli/commands/{lab-route-computer-use.js → study-route-computer-use.js} +12 -12
- package/dist/cli/commands/{lab-route-open.d.ts → study-route-open.d.ts} +4 -4
- package/dist/cli/commands/{lab-route-open.js → study-route-open.js} +2 -2
- package/dist/cli/commands/{lab-route-preview.d.ts → study-route-preview.d.ts} +7 -7
- package/dist/cli/commands/{lab-route-preview.js → study-route-preview.js} +3 -3
- package/dist/cli/commands/study-route-run.d.ts +19 -0
- package/dist/cli/commands/{lab-route-run.js → study-route-run.js} +6 -6
- package/dist/cli/commands/study-route-scripted.d.ts +17 -0
- package/dist/cli/commands/{lab-route-scripted.js → study-route-scripted.js} +4 -4
- package/dist/cli/commands/{lab-route-shared-world.d.ts → study-route-shared-world.d.ts} +5 -5
- package/dist/cli/commands/{lab-route-shared-world.js → study-route-shared-world.js} +7 -7
- package/dist/cli/commands/study-route-terminal.d.ts +17 -0
- package/dist/cli/commands/{lab-route-terminal.js → study-route-terminal.js} +4 -4
- package/dist/cli/commands/study-run.d.ts +9 -0
- package/dist/cli/commands/{lab-run.js → study-run.js} +34 -34
- package/dist/cli/commands/{lab-scorer.d.ts → study-scorer.d.ts} +5 -5
- package/dist/cli/commands/{lab-scorer.js → study-scorer.js} +1 -1
- package/dist/cli/commands/study.js +13 -49
- package/dist/cli/commands/tui.js +12 -12
- package/dist/cli/commands/watch.js +30 -65
- package/dist/cli/deprecations.d.ts +1 -13
- package/dist/cli/deprecations.js +0 -30
- package/dist/cli/doctor.d.ts +3 -3
- package/dist/cli/doctor.js +16 -16
- package/dist/cli/first-run-path.d.ts +4 -4
- package/dist/cli/first-run-path.js +7 -7
- package/dist/cli/io.d.ts +3 -3
- package/dist/cli/io.js +2 -2
- package/dist/cli/observer-follow.d.ts +2 -2
- package/dist/cli/observer-follow.js +2 -2
- package/dist/cli/orientation.d.ts +4 -4
- package/dist/cli/orientation.js +58 -20
- package/dist/cli/program.js +3 -4
- package/dist/cli/telemetry.d.ts +1 -1
- package/dist/cli/telemetry.js +14 -20
- package/dist/comms/catch-host.d.ts +1 -1
- package/dist/comms/catch-host.js +3 -3
- package/dist/comms/connections.d.ts +1 -1
- package/dist/comms/connections.js +2 -2
- package/dist/comms/external-evidence.d.ts +5 -5
- package/dist/comms/external-evidence.js +4 -3
- package/dist/comms/fake-inbox.d.ts +2 -2
- package/dist/comms/fake-inbox.js +2 -2
- package/dist/comms/receiving-runtime.d.ts +4 -4
- package/dist/comms/sandbox-catch.d.ts +2 -2
- package/dist/comms/sandbox-catch.js +2 -2
- package/dist/comms/setup.d.ts +2 -2
- package/dist/comms/setup.js +29 -32
- package/dist/evidence/redaction.d.ts +11 -0
- package/dist/evidence/redaction.js +43 -0
- package/dist/feedback/draft.js +2 -2
- package/dist/feedback/export-bundle.js +5 -4
- package/dist/feedback/export.js +3 -2
- package/dist/feedback/proof.d.ts +1 -1
- package/dist/feedback/proof.js +2 -2
- package/dist/guest/bootstrap.js +6 -6
- package/dist/guest/browser-tools.js +8 -8
- package/dist/guest/chromium-text.js +17 -17
- package/dist/guest/desktop-executor.d.ts +2 -2
- package/dist/guest/desktop-executor.js +20 -20
- package/dist/guest/desktop-keys.js +4 -4
- package/dist/guest/desktop-media.d.ts +2 -2
- package/dist/guest/desktop-media.js +16 -16
- package/dist/guest/desktop-native.js +10 -10
- package/dist/guest/runtime-desktop.js +2 -2
- package/dist/guest/runtime-processes.d.ts +2 -2
- package/dist/guest/runtime-processes.js +2 -2
- package/dist/guest/runtime.js +5 -5
- package/dist/index.d.ts +13 -15
- package/dist/index.js +6 -8
- package/dist/observer/artifact.d.ts +1 -1
- package/dist/observer/artifact.js +1 -1
- package/dist/observer/data.d.ts +1 -1
- package/dist/observer/library.d.ts +2 -0
- package/dist/observer/library.js +4 -1
- package/dist/observer/render.js +7 -1
- package/dist/observer/run-routes.d.ts +1 -0
- package/dist/observer/run-routes.js +37 -12
- package/dist/observer/serve.d.ts +1 -1
- package/dist/observer-app.html +1 -1
- package/dist/routes/computer-use/bundle-parts.js +3 -2
- package/dist/routes/computer-use/bundle.d.ts +2 -2
- package/dist/routes/computer-use/bundle.js +7 -6
- package/dist/routes/computer-use/e2b-desktop/comms.d.ts +5 -5
- package/dist/routes/computer-use/e2b-desktop/comms.js +5 -4
- package/dist/routes/computer-use/e2b-desktop/fidelity.d.ts +1 -1
- package/dist/routes/computer-use/e2b-desktop/prepare.d.ts +1 -1
- package/dist/routes/computer-use/e2b-desktop/prepare.js +3 -3
- package/dist/routes/computer-use/e2b-desktop/start.js +3 -4
- package/dist/routes/computer-use/e2b-desktop/state.d.ts +2 -2
- package/dist/routes/computer-use/e2b-desktop/teardown.js +2 -3
- package/dist/routes/computer-use/external-comms.d.ts +3 -3
- package/dist/routes/computer-use/fanout-bundle.js +11 -10
- package/dist/routes/computer-use/fanout-records.js +2 -2
- package/dist/routes/computer-use/in-process-desktop.js +1 -1
- package/dist/routes/computer-use/live-flush.d.ts +3 -3
- package/dist/routes/computer-use/live-phase.d.ts +2 -3
- package/dist/routes/computer-use/live-phase.js +3 -3
- package/dist/routes/computer-use/local-tree-pack.d.ts +5 -5
- package/dist/routes/computer-use/local-tree-pack.js +1 -1
- package/dist/routes/computer-use/local-vm.d.ts +8 -8
- package/dist/routes/computer-use/local-vm.js +2 -2
- package/dist/routes/computer-use/participant-desktop.d.ts +3 -3
- package/dist/routes/computer-use/participant-desktop.js +1 -1
- package/dist/routes/computer-use/participant-execution.js +1 -1
- package/dist/routes/computer-use/participant-model.js +3 -3
- package/dist/routes/computer-use/participant-prompt.d.ts +5 -5
- package/dist/routes/computer-use/participant-prompt.js +3 -3
- package/dist/routes/computer-use/participant-runs.d.ts +10 -10
- package/dist/routes/computer-use/participant-runs.js +14 -13
- package/dist/routes/computer-use/plan.d.ts +12 -12
- package/dist/routes/computer-use/plan.js +27 -27
- package/dist/routes/computer-use/preflight.d.ts +5 -5
- package/dist/routes/computer-use/preflight.js +5 -5
- package/dist/routes/computer-use/rerun-selection.d.ts +1 -1
- package/dist/routes/computer-use/rerun-selection.js +3 -2
- package/dist/routes/computer-use/result.d.ts +4 -4
- package/dist/routes/computer-use/result.js +13 -12
- package/dist/routes/computer-use/route.d.ts +12 -12
- package/dist/routes/computer-use/route.js +19 -19
- package/dist/routes/computer-use/self-report.js +1 -1
- package/dist/routes/computer-use/setup.d.ts +22 -22
- package/dist/routes/computer-use/setup.js +15 -15
- package/dist/routes/computer-use/single-bundle.d.ts +4 -4
- package/dist/routes/computer-use/single-bundle.js +14 -13
- package/dist/routes/computer-use/subject-projection.d.ts +3 -3
- package/dist/routes/computer-use/types.d.ts +34 -34
- package/dist/routes/computer-use/types.js +3 -3
- package/dist/routes/preview.d.ts +6 -6
- package/dist/routes/preview.js +5 -5
- package/dist/routes/scripted/bundle.d.ts +6 -6
- package/dist/routes/scripted/bundle.js +10 -9
- package/dist/routes/scripted/plan.d.ts +7 -7
- package/dist/routes/scripted/plan.js +6 -6
- package/dist/routes/scripted/result.d.ts +3 -3
- package/dist/routes/scripted/result.js +9 -9
- package/dist/routes/scripted/route.d.ts +9 -9
- package/dist/routes/scripted/route.js +11 -11
- package/dist/routes/scripted/scenario.d.ts +1 -1
- package/dist/routes/scripted/scenario.js +3 -3
- package/dist/routes/scripted/setup.d.ts +6 -6
- package/dist/routes/scripted/setup.js +4 -4
- package/dist/routes/scripted/subject.d.ts +5 -5
- package/dist/routes/scripted/subject.js +3 -3
- package/dist/routes/scripted/surface-records.d.ts +1 -1
- package/dist/routes/scripted/surface-records.js +2 -2
- package/dist/routes/scripted/surface-sessions.d.ts +3 -3
- package/dist/routes/scripted/types.d.ts +17 -17
- package/dist/routes/scripted/types.js +1 -1
- package/dist/routes/shared-world/bundle-records.js +3 -3
- package/dist/routes/shared-world/bundle.js +15 -14
- package/dist/routes/shared-world/checkpoints.d.ts +3 -3
- package/dist/routes/shared-world/checkpoints.js +1 -1
- package/dist/routes/shared-world/comms.d.ts +9 -9
- package/dist/routes/shared-world/comms.js +6 -5
- package/dist/routes/shared-world/participant-specs.d.ts +3 -3
- package/dist/routes/shared-world/participant-specs.js +7 -7
- package/dist/routes/shared-world/plan.d.ts +9 -9
- package/dist/routes/shared-world/plan.js +9 -9
- package/dist/routes/shared-world/provisioned.d.ts +8 -8
- package/dist/routes/shared-world/provisioned.js +4 -4
- package/dist/routes/shared-world/result.d.ts +6 -6
- package/dist/routes/shared-world/result.js +11 -10
- package/dist/routes/shared-world/route.d.ts +11 -11
- package/dist/routes/shared-world/route.js +19 -19
- package/dist/routes/shared-world/setup.d.ts +13 -13
- package/dist/routes/shared-world/setup.js +19 -19
- package/dist/routes/shared-world/types.d.ts +27 -27
- package/dist/routes/terminal/adapter.d.ts +2 -2
- package/dist/routes/terminal/adapter.js +4 -4
- package/dist/routes/terminal/bundle.d.ts +11 -11
- package/dist/routes/terminal/bundle.js +12 -12
- package/dist/routes/terminal/credentials.d.ts +4 -4
- package/dist/routes/terminal/credentials.js +5 -5
- package/dist/routes/terminal/dry-run.d.ts +4 -4
- package/dist/routes/terminal/dry-run.js +9 -9
- package/dist/routes/terminal/ledger.d.ts +2 -2
- package/dist/routes/terminal/lifetime.d.ts +1 -1
- package/dist/routes/terminal/lifetime.js +1 -1
- package/dist/routes/terminal/live-finish.d.ts +2 -2
- package/dist/routes/terminal/live-finish.js +7 -7
- package/dist/routes/terminal/live-sandbox.d.ts +2 -2
- package/dist/routes/terminal/live-sandbox.js +3 -2
- package/dist/routes/terminal/participant-text.js +2 -1
- package/dist/routes/terminal/persona.d.ts +2 -2
- package/dist/routes/terminal/persona.js +2 -2
- package/dist/routes/terminal/plan.d.ts +7 -7
- package/dist/routes/terminal/plan.js +5 -5
- package/dist/routes/terminal/result.d.ts +5 -5
- package/dist/routes/terminal/result.js +7 -7
- package/dist/routes/terminal/route.d.ts +9 -9
- package/dist/routes/terminal/route.js +14 -14
- package/dist/routes/terminal/session.d.ts +5 -5
- package/dist/routes/terminal/session.js +7 -7
- package/dist/routes/terminal/trace.d.ts +2 -2
- package/dist/routes/terminal/types.d.ts +24 -24
- package/dist/routes/terminal/types.js +2 -2
- package/dist/run/bundle.d.ts +7 -7
- package/dist/run/bundle.js +2 -2
- package/dist/run/costs.d.ts +23 -0
- package/dist/run/costs.js +72 -43
- package/dist/run/dry-run-inputs.d.ts +1 -1
- package/dist/run/dry-run-inputs.js +1 -1
- package/dist/run/dry-run.js +2 -2
- package/dist/run/outcomes.d.ts +1 -1
- package/dist/run/participant.d.ts +1 -1
- package/dist/run/preflight-receipts.js +1 -1
- package/dist/run/pricing.js +2 -2
- package/dist/run/projection.d.ts +32 -32
- package/dist/run/projection.js +44 -44
- package/dist/run/reclaim.d.ts +1 -1
- package/dist/run/reclaim.js +1 -1
- package/dist/run/results.d.ts +2 -2
- package/dist/run/run-cost.d.ts +53 -0
- package/dist/run/run-cost.js +105 -0
- package/dist/run/run-index-analysis.d.ts +15 -0
- package/dist/run/run-index-analysis.js +77 -0
- package/dist/run/run-index.d.ts +11 -1
- package/dist/run/run-index.js +63 -49
- package/dist/run/run.d.ts +3 -3
- package/dist/run/run.js +2 -2
- package/dist/run/shared-world-evidence.d.ts +1 -1
- package/dist/run/shared-world-shape.js +1 -1
- package/dist/run/stats.d.ts +3 -3
- package/dist/run/stats.js +14 -14
- package/dist/run/status.d.ts +10 -2
- package/dist/run/status.js +6 -3
- package/dist/run/streams.d.ts +2 -2
- package/dist/run/study-provenance.d.ts +4 -2
- package/dist/run/study-provenance.js +7 -4
- package/dist/run/study-result.d.ts +0 -5
- package/dist/run/study-result.js +1 -1
- package/dist/run-study.d.ts +112 -0
- package/dist/{run-lab.js → run-study.js} +52 -45
- package/dist/{lab → study}/adapter-extension.d.ts +8 -20
- package/dist/{lab → study}/adapter-extension.js +2 -14
- package/dist/{lab → study}/adapter-scorer-loader.d.ts +10 -10
- package/dist/{lab → study}/adapter-scorer-loader.js +3 -3
- package/dist/study/composition-rules.d.ts +7 -0
- package/dist/{lab → study}/composition-rules.js +12 -12
- package/dist/study/config.d.ts +15 -0
- package/dist/{lab → study}/config.js +37 -20
- package/dist/study/convert.d.ts +1 -1
- package/dist/study/convert.js +15 -15
- package/dist/{lab → study}/device-presets.d.ts +2 -2
- package/dist/{lab → study}/discover.d.ts +29 -23
- package/dist/{lab → study}/discover.js +97 -118
- package/dist/{lab → study}/doctor.d.ts +11 -11
- package/dist/{lab → study}/doctor.js +18 -18
- package/dist/study/files.d.ts +2 -2
- package/dist/study/files.js +6 -5
- package/dist/{lab → study}/init-templates.d.ts +2 -2
- package/dist/{lab → study}/init-templates.js +16 -11
- package/dist/{lab → study}/init.d.ts +1 -1
- package/dist/{lab → study}/init.js +7 -4
- package/dist/{lab → study}/keys.d.ts +2 -2
- package/dist/{lab → study}/keys.js +10 -10
- package/dist/study/migrate.d.ts +8 -3
- package/dist/study/migrate.js +60 -4
- package/dist/{lab → study}/parse/actors.d.ts +5 -5
- package/dist/{lab → study}/parse/actors.js +5 -5
- package/dist/study/parse/comms.d.ts +12 -0
- package/dist/study/parse/execution.d.ts +19 -0
- package/dist/{lab → study}/parse/study-v3.d.ts +3 -5
- package/dist/{lab → study}/parse/study-v3.js +3 -3
- package/dist/{lab → study}/parse/subject-state.d.ts +8 -8
- package/dist/{lab → study}/parse/subject-state.js +4 -4
- package/dist/{lab → study}/parse/subject.d.ts +3 -3
- package/dist/{lab → study}/parse/subject.js +8 -8
- package/dist/{lab → study}/parse/values.d.ts +2 -2
- package/dist/{lab → study}/persona-resolve.d.ts +4 -4
- package/dist/{lab → study}/persona-resolve.js +2 -2
- package/dist/{lab → study}/plan-base.d.ts +7 -7
- package/dist/{lab → study}/plan-base.js +1 -1
- package/dist/{lab → study}/plan-participants.d.ts +10 -10
- package/dist/{lab → study}/plan-participants.js +4 -4
- package/dist/{lab → study}/plan-types.d.ts +28 -28
- package/dist/{lab → study}/plan-types.js +2 -2
- package/dist/study/plan.d.ts +13 -0
- package/dist/{lab → study}/plan.js +20 -20
- package/dist/study/preflight-probes.d.ts +3 -0
- package/dist/{lab → study}/preflight-probes.js +9 -8
- package/dist/study/preflight-result.d.ts +8 -0
- package/dist/{lab → study}/preflight-result.js +3 -3
- package/dist/{lab → study}/preflight.d.ts +31 -31
- package/dist/{lab → study}/preflight.js +8 -8
- package/dist/{lab → study}/requirements.d.ts +3 -3
- package/dist/{lab → study}/requirements.js +1 -1
- package/dist/study/route-inputs.d.ts +28 -0
- package/dist/{lab → study}/route-inputs.js +1 -1
- package/dist/{lab → study}/routing.d.ts +12 -12
- package/dist/{lab/run-lab-events.d.ts → study/run-study-events.d.ts} +10 -10
- package/dist/{lab/run-lab-events.js → study/run-study-events.js} +4 -4
- package/dist/{lab/run-lab-homes.d.ts → study/run-study-homes.d.ts} +8 -17
- package/dist/study/run-study-homes.js +3 -0
- package/dist/study/run-study-options.d.ts +28 -0
- package/dist/{lab/run-lab-options.js → study/run-study-options.js} +16 -15
- package/dist/{lab/lab-deps.d.ts → study/study-deps.d.ts} +2 -2
- package/dist/{lab/lab-deps.js → study/study-deps.js} +2 -2
- package/dist/{lab → study}/summary.d.ts +10 -10
- package/dist/{lab → study}/summary.js +15 -15
- package/dist/{lab → study}/tasks.d.ts +3 -3
- package/dist/{lab → study}/tasks.js +1 -1
- package/dist/{lab → study}/types.d.ts +104 -104
- package/dist/{lab → study}/types.js +1 -1
- package/dist/{lab → study}/validation.d.ts +19 -19
- package/dist/{lab → study}/validation.js +13 -13
- package/dist/{lab → study}/warnings.d.ts +4 -4
- package/dist/{lab → study}/warnings.js +1 -1
- package/dist/subject/clone.d.ts +6 -6
- package/dist/subject/clone.js +2 -2
- package/dist/subject/local-tree-archive.d.ts +2 -2
- package/dist/subject/local-tree-archive.js +3 -3
- package/dist/subject/local-tree.d.ts +3 -3
- package/dist/subject/runtime.js +2 -2
- package/dist/subject/serve.d.ts +4 -4
- package/dist/subject/state.d.ts +3 -3
- package/dist/subject/state.js +1 -1
- package/dist/subject/steps.d.ts +1 -1
- package/dist/subject/steps.js +1 -1
- package/dist/substrates/desktop-session.js +2 -2
- package/dist/substrates/detached.d.ts +1 -1
- package/dist/substrates/e2b/desktop-browser.d.ts +4 -4
- package/dist/substrates/e2b/desktop-browser.js +1 -1
- package/dist/substrates/e2b/desktop-cdp.d.ts +1 -1
- package/dist/substrates/e2b/desktop-cdp.js +1 -1
- package/dist/substrates/e2b/desktop-executor.d.ts +1 -1
- package/dist/substrates/e2b/desktop-executor.js +12 -12
- package/dist/substrates/e2b/desktop-geometry.d.ts +1 -1
- package/dist/substrates/e2b/desktop-geometry.js +1 -1
- package/dist/substrates/e2b/desktop-media.d.ts +3 -3
- package/dist/substrates/e2b/lifetime.js +1 -1
- package/dist/substrates/e2b/sandbox.d.ts +3 -3
- package/dist/substrates/e2b/sandbox.js +1 -1
- package/dist/substrates/e2b/sdk.d.ts +1 -1
- package/dist/substrates/e2b/sdk.js +1 -1
- package/dist/substrates/local/runtime-config.d.ts +4 -4
- package/dist/substrates/local/runtime-config.js +4 -4
- package/dist/tui/contract.d.ts +8 -8
- package/dist/tui/contract.js +2 -2
- package/dist/tui/launch.d.ts +3 -3
- package/dist/tui/launch.js +22 -16
- package/dist/tui-app.js +139 -139
- package/dist/verify/subject.d.ts +1 -1
- package/dist/verify/subject.js +1 -1
- package/dist/verify/verify.js +2 -1
- package/docs/architecture/actor-contract.md +5 -5
- package/docs/architecture/browser-control.md +1 -1
- package/docs/architecture/external-public-shared-world.md +8 -7
- package/docs/architecture/github-feedback-loop.md +1 -1
- package/docs/architecture/task-protocol-support.md +1 -1
- package/docs/architecture/terminal-product-route.md +18 -18
- package/docs/contracts/adapter-fixtures.md +2 -2
- package/docs/contracts/errors.md +8 -8
- package/docs/contracts/run-bundle.md +6 -4
- package/docs/contracts/schemas.md +61 -42
- package/docs/contracts/study-analysis.md +4 -1
- package/docs/contracts/study-costs.md +17 -2
- package/examples/README.md +1 -1
- package/examples/scorer/scorer.mjs +3 -3
- package/package.json +2 -1
- package/skills/humanish/SKILL.md +8 -6
- package/skills/humanish/agents/openai.yaml +1 -1
- package/dist/cli/commands/lab-format.d.ts +0 -9
- package/dist/cli/commands/lab-route-run.d.ts +0 -19
- package/dist/cli/commands/lab-route-scripted.d.ts +0 -17
- package/dist/cli/commands/lab-route-terminal.d.ts +0 -17
- package/dist/cli/commands/lab-run.d.ts +0 -9
- package/dist/lab/composition-rules.d.ts +0 -7
- package/dist/lab/config.d.ts +0 -7
- package/dist/lab/deprecated-fields.d.ts +0 -10
- package/dist/lab/deprecated-fields.js +0 -24
- package/dist/lab/parse/comms.d.ts +0 -12
- package/dist/lab/parse/execution.d.ts +0 -19
- package/dist/lab/plan.d.ts +0 -13
- package/dist/lab/preflight-probes.d.ts +0 -3
- package/dist/lab/preflight-result.d.ts +0 -8
- package/dist/lab/route-inputs.d.ts +0 -28
- package/dist/lab/run-lab-homes.js +0 -7
- package/dist/lab/run-lab-options.d.ts +0 -28
- package/dist/library-aliases.d.ts +0 -56
- package/dist/library-aliases.js +0 -22
- package/dist/run-lab.d.ts +0 -112
- /package/dist/{lab → study}/device-presets.js +0 -0
- /package/dist/{lab → study}/init-paths.d.ts +0 -0
- /package/dist/{lab → study}/init-paths.js +0 -0
- /package/dist/{lab → study}/init-plan.d.ts +0 -0
- /package/dist/{lab → study}/init-plan.js +0 -0
- /package/dist/{lab → study}/parse/comms.js +0 -0
- /package/dist/{lab → study}/parse/execution.js +0 -0
- /package/dist/{lab → study}/parse/values.js +0 -0
- /package/dist/{lab → study}/participant-assignment.d.ts +0 -0
- /package/dist/{lab → study}/participant-assignment.js +0 -0
- /package/dist/{lab → study}/persona.d.ts +0 -0
- /package/dist/{lab → study}/persona.js +0 -0
- /package/dist/{lab → study}/routing.js +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
|
-
import {
|
|
2
|
+
import { ComputerUseExecutorError, isComputerUseExecutorError, } from "../actors/computer-use/executor-error.js";
|
|
3
3
|
const DEADLINE_MS = 5_000;
|
|
4
4
|
// These expressions execute only in this port's isolated world. Actor text is
|
|
5
5
|
// never interpolated into JavaScript, a selector, a world name, or a CDP method.
|
|
@@ -103,16 +103,16 @@ function unwatchTargetEvents(settings, handlers) {
|
|
|
103
103
|
function checkScope(settings, state, expected) {
|
|
104
104
|
const { context, page } = settings;
|
|
105
105
|
if (state.closed || state.unusable)
|
|
106
|
-
throw new
|
|
106
|
+
throw new ComputerUseExecutorError("executor_closed", "not_dispatched");
|
|
107
107
|
if (state.generation !== expected)
|
|
108
|
-
throw new
|
|
108
|
+
throw new ComputerUseExecutorError("session_revoked", "not_dispatched");
|
|
109
109
|
const pages = context.pages();
|
|
110
110
|
if (state.dialogSeen ||
|
|
111
111
|
page.isClosed() ||
|
|
112
112
|
page.context() !== context ||
|
|
113
113
|
pages.length !== 1 ||
|
|
114
114
|
pages[0] !== page)
|
|
115
|
-
throw new
|
|
115
|
+
throw new ComputerUseExecutorError("action_rejected", "not_dispatched");
|
|
116
116
|
}
|
|
117
117
|
/**
|
|
118
118
|
* One bounded operation: a 5 s deadline, the caller's abort, and any interrupt race every step.
|
|
@@ -133,7 +133,7 @@ async function runOperation(settings, state, signal, expected, body) {
|
|
|
133
133
|
return;
|
|
134
134
|
stopped = code;
|
|
135
135
|
controller.abort();
|
|
136
|
-
rejectStop(new
|
|
136
|
+
rejectStop(new ComputerUseExecutorError(code, dispatched ? "outcome_uncertain" : "not_dispatched"));
|
|
137
137
|
};
|
|
138
138
|
const abort = () => interrupt("cancelled");
|
|
139
139
|
const timer = setTimeout(() => interrupt("deadline_exceeded"), DEADLINE_MS);
|
|
@@ -143,7 +143,7 @@ async function runOperation(settings, state, signal, expected, body) {
|
|
|
143
143
|
if (signal.aborted)
|
|
144
144
|
abort();
|
|
145
145
|
if (stopped)
|
|
146
|
-
throw new
|
|
146
|
+
throw new ComputerUseExecutorError(stopped, dispatched ? "outcome_uncertain" : "not_dispatched");
|
|
147
147
|
checkScope(settings, state, expected);
|
|
148
148
|
};
|
|
149
149
|
try {
|
|
@@ -165,8 +165,8 @@ async function runOperation(settings, state, signal, expected, body) {
|
|
|
165
165
|
controller.abort();
|
|
166
166
|
if (dispatched)
|
|
167
167
|
state.unusable = true;
|
|
168
|
-
const code = stopped ?? (
|
|
169
|
-
throw new
|
|
168
|
+
const code = stopped ?? (isComputerUseExecutorError(error) ? error.code : "transport_failed");
|
|
169
|
+
throw new ComputerUseExecutorError(code, dispatched ? "outcome_uncertain" : "not_dispatched");
|
|
170
170
|
}
|
|
171
171
|
finally {
|
|
172
172
|
clearTimeout(timer);
|
|
@@ -187,13 +187,13 @@ function sessionDetacher(state) {
|
|
|
187
187
|
await Promise.race([
|
|
188
188
|
session.detach(),
|
|
189
189
|
new Promise((_resolve, reject) => {
|
|
190
|
-
timer = setTimeout(() => reject(new
|
|
190
|
+
timer = setTimeout(() => reject(new ComputerUseExecutorError("deadline_exceeded", "not_dispatched")), DEADLINE_MS);
|
|
191
191
|
}),
|
|
192
192
|
]);
|
|
193
193
|
}
|
|
194
194
|
catch {
|
|
195
195
|
state.unusable = true;
|
|
196
|
-
throw new
|
|
196
|
+
throw new ComputerUseExecutorError("transport_failed", "not_dispatched");
|
|
197
197
|
}
|
|
198
198
|
finally {
|
|
199
199
|
clearTimeout(timer);
|
|
@@ -215,7 +215,7 @@ async function assertOwnerReady(settings, op) {
|
|
|
215
215
|
async function probeElement(op, session, contextId, expression) {
|
|
216
216
|
const result = await op.step(() => session.send("Runtime.evaluate", evaluateParams(expression, contextId)));
|
|
217
217
|
if (!probeAccepted(result))
|
|
218
|
-
throw new
|
|
218
|
+
throw new ComputerUseExecutorError("action_rejected", "not_dispatched");
|
|
219
219
|
}
|
|
220
220
|
/**
|
|
221
221
|
* Preparation: the owner check, a CDP session (recorded on the handle as soon as it exists, so
|
|
@@ -233,14 +233,14 @@ async function acquireIsolatedWorld(settings, state, detach, prepared, op) {
|
|
|
233
233
|
const tree = await op.step(() => prepared.session.send("Page.getFrameTree"));
|
|
234
234
|
const frameId = ownedFrameId(tree);
|
|
235
235
|
if (frameId === undefined)
|
|
236
|
-
throw new
|
|
236
|
+
throw new ComputerUseExecutorError("invalid_response", "not_dispatched");
|
|
237
237
|
const world = await op.step(() => prepared.session.send("Page.createIsolatedWorld", {
|
|
238
238
|
frameId,
|
|
239
239
|
worldName: settings.worldName,
|
|
240
240
|
}));
|
|
241
241
|
prepared.contextId = world.executionContextId;
|
|
242
242
|
if (!isExecutionContextId(prepared.contextId))
|
|
243
|
-
throw new
|
|
243
|
+
throw new ComputerUseExecutorError("invalid_response", "not_dispatched");
|
|
244
244
|
await probeElement(op, prepared.session, prepared.contextId, PREPARE);
|
|
245
245
|
}
|
|
246
246
|
/** Disposes a prepared handle once: aborts its lifetime, detaches its session, releases busy. */
|
|
@@ -255,7 +255,7 @@ function disposePrepared(state, detach, prepared, self) {
|
|
|
255
255
|
await detach(prepared.session);
|
|
256
256
|
}
|
|
257
257
|
catch (error) {
|
|
258
|
-
throw new
|
|
258
|
+
throw new ComputerUseExecutorError(isComputerUseExecutorError(error) ? error.code : "transport_failed", prepared.dispatchedText ? "outcome_uncertain" : "not_dispatched");
|
|
259
259
|
}
|
|
260
260
|
finally {
|
|
261
261
|
state.busy = false;
|
|
@@ -274,7 +274,7 @@ function preparedHandle(settings, state, prepared, dispose) {
|
|
|
274
274
|
return {
|
|
275
275
|
async paste() {
|
|
276
276
|
if (prepared.used || prepared.disposed)
|
|
277
|
-
throw new
|
|
277
|
+
throw new ComputerUseExecutorError("action_rejected", "not_dispatched");
|
|
278
278
|
prepared.used = true; // A failed attempt cannot be retried through this handle.
|
|
279
279
|
await runOperation(settings, state, prepared.lifetime.signal, prepared.expected, async (op) => {
|
|
280
280
|
await assertOwnerReady(settings, op);
|
|
@@ -345,10 +345,10 @@ export function createGuestChromiumText(options) {
|
|
|
345
345
|
},
|
|
346
346
|
async prepareText(text, signal) {
|
|
347
347
|
if (!isAdmissibleText(text))
|
|
348
|
-
throw new
|
|
348
|
+
throw new ComputerUseExecutorError("invalid_request", "not_dispatched");
|
|
349
349
|
checkScope(settings, state, state.generation);
|
|
350
350
|
if (state.busy)
|
|
351
|
-
throw new
|
|
351
|
+
throw new ComputerUseExecutorError("executor_busy", "not_dispatched");
|
|
352
352
|
state.busy = true;
|
|
353
353
|
const expected = state.generation;
|
|
354
354
|
const lifetime = new AbortController();
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { CuaAction, CuaExecutor } from "../actors/computer-use/loop.js";
|
|
2
|
-
import {
|
|
2
|
+
import { ComputerUseExecutorError } from "../actors/computer-use/executor-error.js";
|
|
3
3
|
/** Internal guest port. Implementations recheck signal synchronously before native dispatch. */
|
|
4
4
|
export interface GuestDesktopTools {
|
|
5
5
|
capture(signal: AbortSignal): Promise<Buffer>;
|
|
@@ -48,7 +48,7 @@ export declare function failureEndsSession(progress: Pick<ActionProgress, "prepa
|
|
|
48
48
|
* session_revoked when the signal aborted, then the executor's own error or execution_failed. It
|
|
49
49
|
* reads signal.aborted only for an undispatched failure, as the inline mapping did.
|
|
50
50
|
*/
|
|
51
|
-
export declare function failureError(dispatched: boolean, error: unknown, signal: Pick<AbortSignal, "aborted">):
|
|
51
|
+
export declare function failureError(dispatched: boolean, error: unknown, signal: Pick<AbortSignal, "aborted">): ComputerUseExecutorError;
|
|
52
52
|
/**
|
|
53
53
|
* The native commands for an action, wrapped in keydown/keyup when it holds modifiers. It throws
|
|
54
54
|
* the refusal for an action the desktop cannot take, before anything is sent.
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { perceptualSignature } from "../evidence/frame-signature.js";
|
|
2
2
|
import { setTimeout as delay } from "node:timers/promises";
|
|
3
3
|
import { BROWSER_CONTROL_LIMITS, validateBrowserControlAction, validateBrowserControlPng, } from "../browser-control/protocol.js";
|
|
4
|
-
import {
|
|
4
|
+
import { ComputerUseExecutorError, isComputerUseExecutorError, } from "../actors/computer-use/executor-error.js";
|
|
5
5
|
import { xdotoolChord, xdotoolHeldModifiers } from "./desktop-keys.js";
|
|
6
6
|
/** Headed X11 input and full-frame captures. Browser metadata is deliberately absent. */
|
|
7
7
|
export function createGuestDesktopExecutor(options) {
|
|
8
8
|
const { width, height, tools, authoritySignal } = options;
|
|
9
9
|
if (!isValidFrameSize(width, height))
|
|
10
|
-
throw new
|
|
10
|
+
throw new ComputerUseExecutorError("invalid_request", "not_dispatched");
|
|
11
11
|
const context = {
|
|
12
12
|
width,
|
|
13
13
|
height,
|
|
@@ -40,12 +40,12 @@ function terminate(state, context) {
|
|
|
40
40
|
}
|
|
41
41
|
function assertOpen(state, signal, dispatched = false) {
|
|
42
42
|
if (state.terminal || signal.aborted)
|
|
43
|
-
throw new
|
|
43
|
+
throw new ComputerUseExecutorError("session_revoked", dispatched ? "outcome_uncertain" : "not_dispatched");
|
|
44
44
|
}
|
|
45
45
|
function begin(state, signal) {
|
|
46
46
|
assertOpen(state, signal);
|
|
47
47
|
if (state.busy)
|
|
48
|
-
throw new
|
|
48
|
+
throw new ComputerUseExecutorError("executor_busy", "not_dispatched");
|
|
49
49
|
state.busy = true;
|
|
50
50
|
}
|
|
51
51
|
/** Captures one full frame and checks it is a PNG of the executor's size. */
|
|
@@ -57,15 +57,15 @@ async function observeFrame(context, state) {
|
|
|
57
57
|
assertOpen(state, authoritySignal);
|
|
58
58
|
validateBrowserControlPng(screenshot);
|
|
59
59
|
if (screenshot.readUInt32BE(16) !== width || screenshot.readUInt32BE(20) !== height) {
|
|
60
|
-
throw new
|
|
60
|
+
throw new ComputerUseExecutorError("invalid_response", "not_dispatched");
|
|
61
61
|
}
|
|
62
62
|
return { screenshot, stateSignature: perceptualSignature(screenshot) };
|
|
63
63
|
}
|
|
64
64
|
catch (error) {
|
|
65
65
|
terminate(state, context);
|
|
66
|
-
throw
|
|
66
|
+
throw isComputerUseExecutorError(error)
|
|
67
67
|
? error
|
|
68
|
-
: new
|
|
68
|
+
: new ComputerUseExecutorError("execution_failed", "not_dispatched");
|
|
69
69
|
}
|
|
70
70
|
finally {
|
|
71
71
|
state.busy = false;
|
|
@@ -99,7 +99,7 @@ async function executeAction(context, state, value, callerSignal) {
|
|
|
99
99
|
catch (error) {
|
|
100
100
|
// This transaction has no earlier input. Its private bridge can
|
|
101
101
|
// prove that no insertion or native input was sent.
|
|
102
|
-
if (
|
|
102
|
+
if (isComputerUseExecutorError(error) && error.disposition === "not_dispatched")
|
|
103
103
|
progress.dispatched = false;
|
|
104
104
|
throw error;
|
|
105
105
|
}
|
|
@@ -143,7 +143,7 @@ async function executeAction(context, state, value, callerSignal) {
|
|
|
143
143
|
catch {
|
|
144
144
|
terminate(state, context);
|
|
145
145
|
// oxlint-disable-next-line no-unsafe-finally -- a text channel that fails to close makes the action outcome unknowable
|
|
146
|
-
throw new
|
|
146
|
+
throw new ComputerUseExecutorError("execution_failed", progress.dispatched ? "outcome_uncertain" : "not_dispatched");
|
|
147
147
|
}
|
|
148
148
|
finally {
|
|
149
149
|
state.busy = false;
|
|
@@ -157,12 +157,12 @@ async function executeAction(context, state, value, callerSignal) {
|
|
|
157
157
|
*/
|
|
158
158
|
export function failureEndsSession(progress, error, signal) {
|
|
159
159
|
return ((progress.preparing &&
|
|
160
|
-
!(
|
|
160
|
+
!(isComputerUseExecutorError(error) &&
|
|
161
161
|
error.code === "action_rejected" &&
|
|
162
162
|
error.disposition === "not_dispatched")) ||
|
|
163
163
|
progress.dispatched ||
|
|
164
164
|
signal.aborted ||
|
|
165
|
-
!
|
|
165
|
+
!isComputerUseExecutorError(error));
|
|
166
166
|
}
|
|
167
167
|
/**
|
|
168
168
|
* The error a failed action throws: outcome_uncertain once anything was dispatched, then
|
|
@@ -171,12 +171,12 @@ export function failureEndsSession(progress, error, signal) {
|
|
|
171
171
|
*/
|
|
172
172
|
export function failureError(dispatched, error, signal) {
|
|
173
173
|
if (dispatched)
|
|
174
|
-
return new
|
|
174
|
+
return new ComputerUseExecutorError(isComputerUseExecutorError(error) ? error.code : "execution_failed", "outcome_uncertain");
|
|
175
175
|
if (signal.aborted)
|
|
176
|
-
return new
|
|
177
|
-
return
|
|
176
|
+
return new ComputerUseExecutorError("session_revoked", "not_dispatched");
|
|
177
|
+
return isComputerUseExecutorError(error)
|
|
178
178
|
? error
|
|
179
|
-
: new
|
|
179
|
+
: new ComputerUseExecutorError("execution_failed", "not_dispatched");
|
|
180
180
|
}
|
|
181
181
|
/**
|
|
182
182
|
* The native commands for an action, wrapped in keydown/keyup when it holds modifiers. It throws
|
|
@@ -194,7 +194,7 @@ function framePoint(frame, x, y) {
|
|
|
194
194
|
const { width, height } = frame;
|
|
195
195
|
// Reject out-of-frame input instead of clicking a clamped, unintended target.
|
|
196
196
|
if (x < 0 || y < 0 || x >= width || y >= height)
|
|
197
|
-
throw new
|
|
197
|
+
throw new ComputerUseExecutorError("action_rejected", "not_dispatched");
|
|
198
198
|
return [String(Math.min(width - 1, Math.round(x))), String(Math.min(height - 1, Math.round(y)))];
|
|
199
199
|
}
|
|
200
200
|
/** The native commands for an action, before any held modifiers. */
|
|
@@ -219,13 +219,13 @@ function actionCommands(frame, action) {
|
|
|
219
219
|
// must be refused instead of silently changing the requested text.
|
|
220
220
|
if (action.text.includes("\0") ||
|
|
221
221
|
Buffer.from(action.text, "utf8").toString("utf8") !== action.text)
|
|
222
|
-
throw new
|
|
222
|
+
throw new ComputerUseExecutorError("action_rejected", "not_dispatched");
|
|
223
223
|
return [];
|
|
224
224
|
}
|
|
225
225
|
case "drag": {
|
|
226
226
|
const points = action.path.map((p) => framePoint(frame, p.x, p.y));
|
|
227
227
|
if (points.length < 2)
|
|
228
|
-
throw new
|
|
228
|
+
throw new ComputerUseExecutorError("action_rejected", "not_dispatched");
|
|
229
229
|
return [
|
|
230
230
|
["mousemove", ...points[0]],
|
|
231
231
|
["mousedown", "1"],
|
|
@@ -238,7 +238,7 @@ function actionCommands(frame, action) {
|
|
|
238
238
|
// Native X11 wheel steps do not promise exact pixel scroll distances.
|
|
239
239
|
const horizontal = Math.ceil(Math.abs(action.dx) / 120), vertical = Math.ceil(Math.abs(action.dy) / 120);
|
|
240
240
|
if (horizontal + vertical > 100)
|
|
241
|
-
throw new
|
|
241
|
+
throw new ComputerUseExecutorError("action_rejected", "not_dispatched");
|
|
242
242
|
return horizontal + vertical === 0
|
|
243
243
|
? []
|
|
244
244
|
: [
|
|
@@ -251,6 +251,6 @@ function actionCommands(frame, action) {
|
|
|
251
251
|
case "screenshot":
|
|
252
252
|
return [];
|
|
253
253
|
case "speak":
|
|
254
|
-
throw new
|
|
254
|
+
throw new ComputerUseExecutorError("action_rejected", "not_dispatched");
|
|
255
255
|
}
|
|
256
256
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ComputerUseExecutorError } from "../actors/computer-use/executor-error.js";
|
|
2
2
|
// Key names for the xdotool-driven desktops: the guest's headed display and the E2B sandbox. Both
|
|
3
3
|
// hand these strings to xdotool, which has a command language, so only names from these tables
|
|
4
4
|
// ever reach it. The guest runtime ships this module, so it lives in src/guest/, which CI's
|
|
@@ -56,7 +56,7 @@ function lookup(table, key) {
|
|
|
56
56
|
}
|
|
57
57
|
function chord(names) {
|
|
58
58
|
if (new Set(names).size !== names.length)
|
|
59
|
-
throw new
|
|
59
|
+
throw new ComputerUseExecutorError("action_rejected", "not_dispatched");
|
|
60
60
|
return names.join("+");
|
|
61
61
|
}
|
|
62
62
|
/** A keypress chord in xdotool syntax. Unknown or repeated keys are refused before dispatch. */
|
|
@@ -68,7 +68,7 @@ export function xdotoolChord(keys) {
|
|
|
68
68
|
return key.toUpperCase();
|
|
69
69
|
const name = lookup(keyNames, key);
|
|
70
70
|
if (!name)
|
|
71
|
-
throw new
|
|
71
|
+
throw new ComputerUseExecutorError("action_rejected", "not_dispatched");
|
|
72
72
|
return name;
|
|
73
73
|
}));
|
|
74
74
|
}
|
|
@@ -83,7 +83,7 @@ export function xdotoolHeldModifiers(keys) {
|
|
|
83
83
|
return chord(keys.map((key) => {
|
|
84
84
|
const name = lookup(modifierNames, key);
|
|
85
85
|
if (!name)
|
|
86
|
-
throw new
|
|
86
|
+
throw new ComputerUseExecutorError("action_rejected", "not_dispatched");
|
|
87
87
|
return name;
|
|
88
88
|
}));
|
|
89
89
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { CuaExecutor } from "../actors/computer-use/loop.js";
|
|
2
2
|
import { type HeardSpeech } from "../actors/computer-use/speech.js";
|
|
3
|
-
import {
|
|
3
|
+
import { ComputerUseExecutorError } from "../actors/computer-use/executor-error.js";
|
|
4
4
|
interface GuestDesktopMediaDeclaration {
|
|
5
5
|
camera?: {
|
|
6
6
|
source: string;
|
|
@@ -64,7 +64,7 @@ export declare function classifyWorkerMessage(value: unknown, ready: boolean): W
|
|
|
64
64
|
/** Once a speak command is written, its outcome is unknown unless the worker replies. */
|
|
65
65
|
export declare function dispositionAfterWrite(written: boolean): "outcome_uncertain" | "not_dispatched";
|
|
66
66
|
/** A failed speak keeps its own executor error; anything else is an execution failure. */
|
|
67
|
-
export declare function speakFailure(error: unknown, written: boolean):
|
|
67
|
+
export declare function speakFailure(error: unknown, written: boolean): ComputerUseExecutorError;
|
|
68
68
|
/** Starts optional native guest media before Chromium and later decorates its finite executor. */
|
|
69
69
|
export declare function startDesktopMedia(options: GuestDesktopMediaOptions): Promise<GuestDesktopMedia>;
|
|
70
70
|
export {};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
2
|
import { CUA_SPEECH_LIMITS } from "../actors/computer-use/speech.js";
|
|
3
|
-
import {
|
|
3
|
+
import { ComputerUseExecutorError } from "../actors/computer-use/executor-error.js";
|
|
4
4
|
const WORKER_LINE_BYTES = 8_192;
|
|
5
5
|
const READY_TIMEOUT_MS = 35_000;
|
|
6
6
|
const SPEAK_TIMEOUT_MS = 30_000;
|
|
@@ -131,9 +131,9 @@ export function dispositionAfterWrite(written) {
|
|
|
131
131
|
}
|
|
132
132
|
/** A failed speak keeps its own executor error; anything else is an execution failure. */
|
|
133
133
|
export function speakFailure(error, written) {
|
|
134
|
-
return error instanceof
|
|
134
|
+
return error instanceof ComputerUseExecutorError
|
|
135
135
|
? error
|
|
136
|
-
: new
|
|
136
|
+
: new ComputerUseExecutorError("execution_failed", dispositionAfterWrite(written));
|
|
137
137
|
}
|
|
138
138
|
function rejectPending(state, error) {
|
|
139
139
|
for (const command of state.pending.values()) {
|
|
@@ -147,7 +147,7 @@ function terminateMedia(state, readiness, onTerminal) {
|
|
|
147
147
|
if (state.closed || state.expectedExit)
|
|
148
148
|
return;
|
|
149
149
|
state.closed = true;
|
|
150
|
-
const error = new
|
|
150
|
+
const error = new ComputerUseExecutorError("execution_failed", "outcome_uncertain");
|
|
151
151
|
readiness.reject(error);
|
|
152
152
|
rejectPending(state, error);
|
|
153
153
|
try {
|
|
@@ -182,7 +182,7 @@ function applyWorkerMessage(state, value, readiness, terminate) {
|
|
|
182
182
|
if (message.ok)
|
|
183
183
|
command.resolve();
|
|
184
184
|
else
|
|
185
|
-
command.reject(new
|
|
185
|
+
command.reject(new ComputerUseExecutorError("execution_failed", "outcome_uncertain"));
|
|
186
186
|
return;
|
|
187
187
|
}
|
|
188
188
|
case "terminal":
|
|
@@ -223,13 +223,13 @@ async function closeDesktopMedia(state, transport, detach) {
|
|
|
223
223
|
state.expectedExit = true;
|
|
224
224
|
state.closed = true;
|
|
225
225
|
detach();
|
|
226
|
-
rejectPending(state, new
|
|
226
|
+
rejectPending(state, new ComputerUseExecutorError("session_revoked", "outcome_uncertain"));
|
|
227
227
|
state.closing = Promise.resolve().then(() => transport.close());
|
|
228
228
|
return state.closing;
|
|
229
229
|
}
|
|
230
230
|
async function awaitWorkerReady(readiness, signal, close, readyTimer) {
|
|
231
231
|
const readinessAbort = () => {
|
|
232
|
-
readiness.reject(new
|
|
232
|
+
readiness.reject(new ComputerUseExecutorError("session_revoked", "not_dispatched"));
|
|
233
233
|
};
|
|
234
234
|
signal.addEventListener("abort", readinessAbort, { once: true });
|
|
235
235
|
try {
|
|
@@ -247,17 +247,17 @@ async function awaitWorkerReady(readiness, signal, close, readyTimer) {
|
|
|
247
247
|
/** Adds queued heard speech to each observation, at most HEARD_PER_OBSERVATION at a time. */
|
|
248
248
|
async function observeWithHeardSpeech(state, executor) {
|
|
249
249
|
if (state.closed)
|
|
250
|
-
throw new
|
|
250
|
+
throw new ComputerUseExecutorError("execution_failed", "not_dispatched");
|
|
251
251
|
const observation = await executor.observe();
|
|
252
252
|
if (state.closed)
|
|
253
|
-
throw new
|
|
253
|
+
throw new ComputerUseExecutorError("execution_failed", "not_dispatched");
|
|
254
254
|
const items = state.heard.splice(0, HEARD_PER_OBSERVATION);
|
|
255
255
|
return items.length ? { ...observation, heardSpeech: items } : observation;
|
|
256
256
|
}
|
|
257
257
|
/** Passes every action but `speak` to the executor; `speak` goes to the worker and waits for its reply. */
|
|
258
258
|
async function executeWithSpeech(state, executor, channel, action, signal) {
|
|
259
259
|
if (state.closed)
|
|
260
|
-
throw new
|
|
260
|
+
throw new ComputerUseExecutorError("execution_failed", "not_dispatched");
|
|
261
261
|
const candidate = action;
|
|
262
262
|
if (candidate.kind !== "speak")
|
|
263
263
|
return executor.execute(action, signal);
|
|
@@ -266,7 +266,7 @@ async function executeWithSpeech(state, executor, channel, action, signal) {
|
|
|
266
266
|
state.closed ||
|
|
267
267
|
channel.ownerSignal.aborted ||
|
|
268
268
|
signal?.aborted) {
|
|
269
|
-
throw new
|
|
269
|
+
throw new ComputerUseExecutorError("action_rejected", "not_dispatched");
|
|
270
270
|
}
|
|
271
271
|
const id = `speak-${state.nextCommand++}`;
|
|
272
272
|
const combined = signal ? AbortSignal.any([channel.ownerSignal, signal]) : channel.ownerSignal;
|
|
@@ -274,7 +274,7 @@ async function executeWithSpeech(state, executor, channel, action, signal) {
|
|
|
274
274
|
const operation = new Promise((resolve, reject) => {
|
|
275
275
|
const timer = setTimeout(() => {
|
|
276
276
|
state.pending.delete(id);
|
|
277
|
-
reject(new
|
|
277
|
+
reject(new ComputerUseExecutorError("deadline_exceeded", dispositionAfterWrite(written)));
|
|
278
278
|
void channel.close().catch(() => { });
|
|
279
279
|
}, SPEAK_TIMEOUT_MS);
|
|
280
280
|
state.pending.set(id, { resolve, reject, timer });
|
|
@@ -286,7 +286,7 @@ async function executeWithSpeech(state, executor, channel, action, signal) {
|
|
|
286
286
|
return;
|
|
287
287
|
state.pending.delete(id);
|
|
288
288
|
clearTimeout(command.timer);
|
|
289
|
-
command.reject(new
|
|
289
|
+
command.reject(new ComputerUseExecutorError("session_revoked", dispositionAfterWrite(written)));
|
|
290
290
|
void channel.close().catch(() => { });
|
|
291
291
|
};
|
|
292
292
|
combined.addEventListener("abort", cancelled, { once: true });
|
|
@@ -311,7 +311,7 @@ async function executeWithSpeech(state, executor, channel, action, signal) {
|
|
|
311
311
|
}
|
|
312
312
|
function wrapMediaExecutor(state, executor, channel) {
|
|
313
313
|
if (state.wrapped)
|
|
314
|
-
throw new
|
|
314
|
+
throw new ComputerUseExecutorError("invalid_request", "not_dispatched");
|
|
315
315
|
state.wrapped = true;
|
|
316
316
|
const wrapped = {
|
|
317
317
|
...executor,
|
|
@@ -324,7 +324,7 @@ function wrapMediaExecutor(state, executor, channel) {
|
|
|
324
324
|
/** Starts optional native guest media before Chromium and later decorates its finite executor. */
|
|
325
325
|
export async function startDesktopMedia(options) {
|
|
326
326
|
if (!isSupportedMediaDeclaration(options.media))
|
|
327
|
-
throw new
|
|
327
|
+
throw new ComputerUseExecutorError("invalid_request", "not_dispatched");
|
|
328
328
|
options.signal.throwIfAborted();
|
|
329
329
|
const env = desktopMediaEnv(options.env, options.media);
|
|
330
330
|
const transport = options.transport ??
|
|
@@ -365,7 +365,7 @@ export async function startDesktopMedia(options) {
|
|
|
365
365
|
await transport.close().catch(() => { });
|
|
366
366
|
throw error;
|
|
367
367
|
}
|
|
368
|
-
const readyTimer = setTimeout(() => readiness.reject(new
|
|
368
|
+
const readyTimer = setTimeout(() => readiness.reject(new ComputerUseExecutorError("deadline_exceeded", "not_dispatched")), READY_TIMEOUT_MS);
|
|
369
369
|
const abort = () => {
|
|
370
370
|
void close();
|
|
371
371
|
};
|
|
@@ -2,9 +2,9 @@ import { spawn } from "node:child_process";
|
|
|
2
2
|
import { constants } from "node:fs";
|
|
3
3
|
import { mkdtemp, open, rm } from "node:fs/promises";
|
|
4
4
|
import { join } from "node:path";
|
|
5
|
-
import {
|
|
5
|
+
import { ComputerUseExecutorError } from "../actors/computer-use/executor-error.js";
|
|
6
6
|
import { BROWSER_CONTROL_LIMITS } from "../browser-control/protocol.js";
|
|
7
|
-
class UnconfirmedHelperExit extends
|
|
7
|
+
class UnconfirmedHelperExit extends ComputerUseExecutorError {
|
|
8
8
|
constructor() {
|
|
9
9
|
super("execution_failed", "outcome_uncertain");
|
|
10
10
|
}
|
|
@@ -14,7 +14,7 @@ export function createGuestDesktopNativeTools(options) {
|
|
|
14
14
|
if (!/^:[0-9]{1,3}(?:\.[0-9])?$/.test(options.display) ||
|
|
15
15
|
!options.temporaryDirectory.startsWith("/") ||
|
|
16
16
|
!options.xauthority.startsWith("/")) {
|
|
17
|
-
throw new
|
|
17
|
+
throw new ComputerUseExecutorError("invalid_request", "not_dispatched");
|
|
18
18
|
}
|
|
19
19
|
const environment = {
|
|
20
20
|
PATH: "/usr/bin:/bin",
|
|
@@ -28,7 +28,7 @@ export function createGuestDesktopNativeTools(options) {
|
|
|
28
28
|
// stderr can contain user text; consume it with a bound, never return or log it.
|
|
29
29
|
async function helper(binary, args, signal, text) {
|
|
30
30
|
if (signal.aborted)
|
|
31
|
-
throw new
|
|
31
|
+
throw new ComputerUseExecutorError("session_revoked", "not_dispatched");
|
|
32
32
|
return await new Promise((resolve, reject) => {
|
|
33
33
|
const child = spawn(`/usr/bin/${binary}`, [...args], {
|
|
34
34
|
cwd: options.temporaryDirectory,
|
|
@@ -81,7 +81,7 @@ export function createGuestDesktopNativeTools(options) {
|
|
|
81
81
|
clearTimeout(killDeadline);
|
|
82
82
|
signal.removeEventListener("abort", abort);
|
|
83
83
|
if (failed || code !== 0)
|
|
84
|
-
reject(new
|
|
84
|
+
reject(new ComputerUseExecutorError(failureCode, "outcome_uncertain"));
|
|
85
85
|
else
|
|
86
86
|
resolve(Buffer.concat(stdout));
|
|
87
87
|
});
|
|
@@ -97,19 +97,19 @@ export function createGuestDesktopNativeTools(options) {
|
|
|
97
97
|
async activeWindowId(signal) {
|
|
98
98
|
const value = (await helper("xdotool", ["getactivewindow"], signal)).toString("utf8");
|
|
99
99
|
if (!/^[1-9][0-9]{0,9}\n?$/.test(value) || Number(value.trim()) > 0xffffffff)
|
|
100
|
-
throw new
|
|
100
|
+
throw new ComputerUseExecutorError("action_rejected", "not_dispatched");
|
|
101
101
|
return value.trim();
|
|
102
102
|
},
|
|
103
103
|
async typeAscii(text, signal) {
|
|
104
104
|
if (!/^[\x20-\x7e]+$/.test(text) ||
|
|
105
105
|
Buffer.byteLength(text) > BROWSER_CONTROL_LIMITS.textBytes) {
|
|
106
|
-
throw new
|
|
106
|
+
throw new ComputerUseExecutorError("action_rejected", "not_dispatched");
|
|
107
107
|
}
|
|
108
108
|
await helper("xdotool", ["type", "--clearmodifiers", "--delay", "0", "--file", "-"], signal, text);
|
|
109
109
|
},
|
|
110
110
|
async capture(signal) {
|
|
111
111
|
if (signal.aborted)
|
|
112
|
-
throw new
|
|
112
|
+
throw new ComputerUseExecutorError("session_revoked", "not_dispatched");
|
|
113
113
|
const directory = await mkdtemp(join(options.temporaryDirectory, "capture-"));
|
|
114
114
|
const path = join(directory, "frame.png");
|
|
115
115
|
let reclaim = true;
|
|
@@ -122,7 +122,7 @@ export function createGuestDesktopNativeTools(options) {
|
|
|
122
122
|
stat.nlink !== 1 ||
|
|
123
123
|
stat.size <= 0 ||
|
|
124
124
|
stat.size > BROWSER_CONTROL_LIMITS.pngBytes) {
|
|
125
|
-
throw new
|
|
125
|
+
throw new ComputerUseExecutorError("invalid_response", "not_dispatched");
|
|
126
126
|
}
|
|
127
127
|
const buffer = Buffer.alloc(stat.size + 1);
|
|
128
128
|
let offset = 0;
|
|
@@ -133,7 +133,7 @@ export function createGuestDesktopNativeTools(options) {
|
|
|
133
133
|
offset += bytesRead;
|
|
134
134
|
}
|
|
135
135
|
if (offset !== stat.size)
|
|
136
|
-
throw new
|
|
136
|
+
throw new ComputerUseExecutorError("invalid_response", "not_dispatched");
|
|
137
137
|
return buffer.subarray(0, offset);
|
|
138
138
|
}
|
|
139
139
|
finally {
|
|
@@ -7,7 +7,7 @@ import { createGuestDesktopNativeTools } from "./desktop-native.js";
|
|
|
7
7
|
import { createGuestChromiumText } from "./chromium-text.js";
|
|
8
8
|
import { createGuestBrowserTools } from "./browser-tools.js";
|
|
9
9
|
import { createGuestDesktopExecutor } from "./desktop-executor.js";
|
|
10
|
-
import {
|
|
10
|
+
import { ComputerUseExecutorError } from "../actors/computer-use/executor-error.js";
|
|
11
11
|
import { GUEST_BOOTSTRAP_LIMITS, validateGuestInitialUrl } from "./bootstrap.js";
|
|
12
12
|
import { startDesktopMedia, } from "./desktop-media.js";
|
|
13
13
|
import { startDesktopRecorder } from "../evidence/desktop-recorder.js";
|
|
@@ -220,7 +220,7 @@ async function verifyBrowserSandbox(context, page, check) {
|
|
|
220
220
|
function focusGuard(native, window) {
|
|
221
221
|
return async (actionSignal) => {
|
|
222
222
|
if ((await native.activeWindowId(actionSignal)) !== window)
|
|
223
|
-
throw new
|
|
223
|
+
throw new ComputerUseExecutorError("action_rejected", "not_dispatched");
|
|
224
224
|
};
|
|
225
225
|
}
|
|
226
226
|
async function createGuestExecutorFor(state, browser, signal, onTerminal, check) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type ChildProcess } from "node:child_process";
|
|
2
|
-
import {
|
|
3
|
-
export declare const setupFailed: () =>
|
|
2
|
+
import { ComputerUseExecutorError } from "../actors/computer-use/executor-error.js";
|
|
3
|
+
export declare const setupFailed: () => ComputerUseExecutorError;
|
|
4
4
|
export interface GuestProcesses {
|
|
5
5
|
/** `done` resolves when the child exits 0 within its bounds and rejects otherwise. */
|
|
6
6
|
spawn(binary: string, args: readonly string[], input?: string, persistent?: boolean): {
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
|
-
import {
|
|
2
|
+
import { ComputerUseExecutorError } from "../actors/computer-use/executor-error.js";
|
|
3
3
|
/** A short-lived helper that has not exited by then is killed. Persistent children have no bound. */
|
|
4
4
|
const HELPER_TIMEOUT_MS = 2000;
|
|
5
5
|
/** Helpers report success through exit status, so stderr past this budget is a failure. */
|
|
6
6
|
const STDERR_LIMIT_BYTES = 16_384;
|
|
7
|
-
export const setupFailed = () => new
|
|
7
|
+
export const setupFailed = () => new ComputerUseExecutorError("execution_failed", "not_dispatched");
|
|
8
8
|
/**
|
|
9
9
|
* The guest desktop's fixed child processes. A persistent child (the display server, the window
|
|
10
10
|
* manager) that exits, fails or is killed by the owner's abort reports `onTerminal` unless the
|
package/dist/guest/runtime.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { attachBrowserControlDispatcher } from "../browser-control/dispatcher.js";
|
|
2
2
|
import { encodeGuestBootstrap, GuestBootstrapReader, GUEST_BOOTSTRAP_LIMITS, guestReadyTimeoutMs, } from "./bootstrap.js";
|
|
3
|
-
import {
|
|
3
|
+
import { ComputerUseExecutorError } from "../actors/computer-use/executor-error.js";
|
|
4
4
|
/** One admitted desktop and one dispatcher. The owner retains physical teardown. */
|
|
5
5
|
export async function runGuestRuntime(options) {
|
|
6
6
|
const owner = new AbortController();
|
|
@@ -77,7 +77,7 @@ export async function runGuestRuntime(options) {
|
|
|
77
77
|
reader = new GuestBootstrapReader(options.transport, options.revision, authority, false, terminal);
|
|
78
78
|
const identity = await reader.identity;
|
|
79
79
|
if (authority.aborted)
|
|
80
|
-
throw new
|
|
80
|
+
throw new ComputerUseExecutorError("session_revoked", "not_dispatched");
|
|
81
81
|
clearTimeout(timer);
|
|
82
82
|
timer = setTimeout(() => {
|
|
83
83
|
void close();
|
|
@@ -87,7 +87,7 @@ export async function runGuestRuntime(options) {
|
|
|
87
87
|
desktop = await Promise.race([
|
|
88
88
|
preparing,
|
|
89
89
|
new Promise((_, reject) => {
|
|
90
|
-
const stop = () => reject(new
|
|
90
|
+
const stop = () => reject(new ComputerUseExecutorError("session_revoked", "not_dispatched"));
|
|
91
91
|
authority.addEventListener("abort", stop, { once: true });
|
|
92
92
|
void preparing.finally(() => authority.removeEventListener("abort", stop)).catch(() => { });
|
|
93
93
|
if (authority.aborted)
|
|
@@ -95,7 +95,7 @@ export async function runGuestRuntime(options) {
|
|
|
95
95
|
}),
|
|
96
96
|
]);
|
|
97
97
|
if (authority.aborted)
|
|
98
|
-
throw new
|
|
98
|
+
throw new ComputerUseExecutorError("session_revoked", "not_dispatched");
|
|
99
99
|
reader.handoff();
|
|
100
100
|
dispatcher = attachBrowserControlDispatcher({
|
|
101
101
|
transport: options.transport,
|
|
@@ -112,7 +112,7 @@ export async function runGuestRuntime(options) {
|
|
|
112
112
|
});
|
|
113
113
|
options.transport.resume();
|
|
114
114
|
if (authority.aborted || options.transport.destroyed)
|
|
115
|
-
throw new
|
|
115
|
+
throw new ComputerUseExecutorError("session_revoked", "not_dispatched");
|
|
116
116
|
options.marker("R");
|
|
117
117
|
clearTimeout(timer);
|
|
118
118
|
return { close, closed };
|