humanish 0.108.0 → 0.109.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/ARCHITECTURE.md +58 -59
- package/CHANGELOG.md +13 -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/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 +3 -5
- 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/feedback/draft.js +2 -2
- 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/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 +24 -24
- 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 +1 -1
- 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} +3 -3
- 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} +13 -12
- 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 +1 -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 +1 -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
package/dist/comms/setup.js
CHANGED
|
@@ -8,11 +8,10 @@ import { discoverProviderKeys, listUserKeys, probeKeySources, } from "../keys/ke
|
|
|
8
8
|
import { COMMS_PROVIDERS, commsProviderLabel, DEFAULT_COMMS_PROVIDER, } from "./providers.js";
|
|
9
9
|
import { createReceivingAdapter } from "./receiving-runtime.js";
|
|
10
10
|
import { RECEIVING_SCOPE_UNSUPPORTED } from "./receiving-types.js";
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
11
|
+
import { parseStudy } from "../study/config.js";
|
|
12
|
+
import { resolveStudyManifest } from "../study/discover.js";
|
|
13
13
|
import { assertPreparedSelectedOutputDirectory, prepareManagedHumanishOutputDirectory, prepareSelectedOutputDirectory, readContainedRegularFile, writeContainedOutputFile, } from "../run/contained-output.js";
|
|
14
14
|
import { otherStudyFiles } from "../study/files.js";
|
|
15
|
-
import { convertStudyText, isStudyV3 } from "../study/convert.js";
|
|
16
15
|
import { isNodeError } from "../run/type-guards.js";
|
|
17
16
|
export async function checkCommsConnection(args) {
|
|
18
17
|
const base = {
|
|
@@ -109,65 +108,63 @@ export async function receivingRequiredKey(cwd, connectionName) {
|
|
|
109
108
|
}
|
|
110
109
|
}
|
|
111
110
|
/** Save a local copy, never rewrite a committed manifest or silently shadow it by handle. */
|
|
112
|
-
export async function
|
|
111
|
+
export async function configureCommsStudy(args) {
|
|
113
112
|
const base = { schema: "humanish.comms-configure.v1", ok: false, applied: false };
|
|
114
113
|
try {
|
|
115
114
|
const connection = (await readCommsConnections(args.cwd)).connections[args.connection];
|
|
116
115
|
if (!connection)
|
|
117
116
|
return { ...base, message: "Save the selected connection first." };
|
|
118
|
-
const source = await
|
|
119
|
-
if (!source.ok)
|
|
120
|
-
|
|
117
|
+
const source = await resolveStudyManifest(args.cwd, args.study);
|
|
118
|
+
if (!source.ok) {
|
|
119
|
+
// A v2 source or a labs/ file gets discovery's refusal, which names the fix.
|
|
120
|
+
const named = source.error.code === "HUMANISH_STUDY_V2_UNSUPPORTED" ||
|
|
121
|
+
source.error.code === "HUMANISH_STUDY_RETIRED_DIRECTORY";
|
|
122
|
+
return {
|
|
123
|
+
...base,
|
|
124
|
+
message: named ? source.error.message : "The selected study could not be read safely.",
|
|
125
|
+
};
|
|
126
|
+
}
|
|
121
127
|
const root = await prepareSelectedOutputDirectory(args.cwd, args.cwd);
|
|
122
128
|
const rel = path
|
|
123
129
|
.relative(root.requestedPath, path.resolve(args.cwd, source.path))
|
|
124
130
|
.replace(/\\/g, "/");
|
|
125
131
|
const bytes = await readContainedRegularFile(root, rel);
|
|
126
132
|
if (!bytes || bytes.length > 1024 * 1024)
|
|
127
|
-
return { ...base, message: "The
|
|
133
|
+
return { ...base, message: "The study file is missing or too large." };
|
|
128
134
|
const text = bytes.toString("utf8");
|
|
129
135
|
const raw = parse(text);
|
|
130
136
|
if (!raw || typeof raw !== "object" || Array.isArray(raw))
|
|
131
|
-
return { ...base, message: "The
|
|
132
|
-
const
|
|
133
|
-
const existing =
|
|
137
|
+
return { ...base, message: "The study file must be a mapping." };
|
|
138
|
+
const studyRecord = raw;
|
|
139
|
+
const existing = studyRecord.comms;
|
|
134
140
|
if (existing?.email && existing.email.connection === undefined)
|
|
135
141
|
return {
|
|
136
142
|
...base,
|
|
137
|
-
message: "This
|
|
143
|
+
message: "This study uses local capture. Preserve it or make a separate study before selecting real email.",
|
|
138
144
|
};
|
|
139
|
-
//
|
|
140
|
-
|
|
141
|
-
if (!isStudyV3(raw)) {
|
|
142
|
-
const converted = convertStudyText(text, args.cwd);
|
|
143
|
-
if (!converted.ok)
|
|
144
|
-
return {
|
|
145
|
-
...base,
|
|
146
|
-
message: `This lab could not be converted to a v3 study: ${converted.reason}`,
|
|
147
|
-
};
|
|
148
|
-
studyText = converted.conversion.text;
|
|
149
|
-
}
|
|
150
|
-
const study = parseDocument(studyText);
|
|
145
|
+
// Discovery resolved the source, so it is a v3 study, and the copy keeps its comments.
|
|
146
|
+
const study = parseDocument(text);
|
|
151
147
|
study.setIn(["comms", "email", "connection"], args.connection);
|
|
152
|
-
const validated =
|
|
148
|
+
const validated = parseStudy(study.toJS());
|
|
153
149
|
if (!validated.ok)
|
|
154
150
|
return {
|
|
155
151
|
...base,
|
|
156
|
-
message: "This
|
|
152
|
+
message: "This study does not support real email receiving. Use a hosted computer-use app-url, clone or local-tree route; shared-world must be concurrent.",
|
|
157
153
|
};
|
|
158
154
|
const filename = path
|
|
159
155
|
.basename(source.path)
|
|
160
156
|
.replace(/\.ya?ml$/, "")
|
|
161
157
|
.replace(/-receiving$/, "") + "-receiving.yaml";
|
|
162
158
|
if (!/^[A-Za-z0-9_][A-Za-z0-9._-]{0,110}\.yaml$/.test(filename))
|
|
163
|
-
return { ...base, message: "Use a simple
|
|
159
|
+
return { ...base, message: "Use a simple study filename before configuring email." };
|
|
164
160
|
const destination = `.humanish/local/studies/${filename}`;
|
|
165
161
|
if (path.basename(rel) === filename)
|
|
166
162
|
return {
|
|
167
163
|
...base,
|
|
168
|
-
message: "This is already the local receiving copy. Select its original
|
|
164
|
+
message: "This is already the local receiving copy. Select its original study to configure a separate copy, or edit this study file directly.",
|
|
169
165
|
};
|
|
170
|
-
// A second file with this name in another study directory would
|
|
166
|
+
// A second file with this name in another study directory would shadow it, or take the name
|
|
167
|
+
// migrate needs to move a labs/ file.
|
|
171
168
|
const stem = filename.replace(/\.yaml$/, "");
|
|
172
169
|
const others = await otherStudyFiles(stem,
|
|
173
170
|
// Any directory entry counts, a dangling symbolic link included: discovery would see it too.
|
|
@@ -215,7 +212,7 @@ export async function configureCommsLab(args) {
|
|
|
215
212
|
if (args.planToken !== undefined && args.planToken !== token)
|
|
216
213
|
return {
|
|
217
214
|
...base,
|
|
218
|
-
message: "The
|
|
215
|
+
message: "The study or destination changed since preview. Preview again before saving.",
|
|
219
216
|
};
|
|
220
217
|
const directory = await prepareManagedHumanishOutputDirectory(args.cwd, "local", "studies");
|
|
221
218
|
const lockPath = path.join(directory.physicalPath, ".comms-configure.lock");
|
|
@@ -239,13 +236,13 @@ export async function configureCommsLab(args) {
|
|
|
239
236
|
return {
|
|
240
237
|
...plan,
|
|
241
238
|
applied: true,
|
|
242
|
-
message: `Saved ${destination}. Start that exact
|
|
239
|
+
message: `Saved ${destination}. Start that exact study path; the original file was preserved.`,
|
|
243
240
|
};
|
|
244
241
|
}
|
|
245
242
|
catch {
|
|
246
243
|
return {
|
|
247
244
|
...base,
|
|
248
|
-
message: "Could not configure this
|
|
245
|
+
message: "Could not configure this study safely. Check configuration, paths and permissions; no provider resources were created.",
|
|
249
246
|
};
|
|
250
247
|
}
|
|
251
248
|
}
|
package/dist/feedback/draft.js
CHANGED
|
@@ -100,7 +100,7 @@ export function buildDraft(bundle, bundlePath, candidateId) {
|
|
|
100
100
|
proposed_next_state: "study-quality-review",
|
|
101
101
|
acceptance_proof: [
|
|
102
102
|
feedbackProofCommands(bundle.runId).verify,
|
|
103
|
-
feedbackProofCommands(bundle.runId).
|
|
103
|
+
feedbackProofCommands(bundle.runId).observe,
|
|
104
104
|
],
|
|
105
105
|
};
|
|
106
106
|
}
|
|
@@ -192,7 +192,7 @@ export async function buildAnalysisDraft(context, options) {
|
|
|
192
192
|
proposed_next_state: "study-quality-review",
|
|
193
193
|
acceptance_proof: [
|
|
194
194
|
feedbackProofCommands(bundle.runId).verify,
|
|
195
|
-
feedbackProofCommands(bundle.runId).
|
|
195
|
+
feedbackProofCommands(bundle.runId).observe,
|
|
196
196
|
],
|
|
197
197
|
};
|
|
198
198
|
}
|
package/dist/feedback/export.js
CHANGED
|
@@ -23,6 +23,7 @@ import { analysisSharingProblems } from "../analysis/sharing.js";
|
|
|
23
23
|
import { EVIDENCE_LIMITS, validateAnalysisEvidence } from "../analysis/evidence.js";
|
|
24
24
|
import { readBoundedFile } from "../run/evidence-files.js";
|
|
25
25
|
import { shellQuote } from "../substrates/shell.js";
|
|
26
|
+
import { plural } from "../run/text.js";
|
|
26
27
|
const EXPORT_SCHEMA = "humanish.export-result.v1";
|
|
27
28
|
/** Past this the file stops being a thing you attach to an email. Declared, never silent. */
|
|
28
29
|
export const DEFAULT_EXPORT_MAX_BYTES = 25 * 1024 * 1024;
|
|
@@ -361,7 +362,7 @@ export function formatExportHuman(result) {
|
|
|
361
362
|
if (result.format === "bundle") {
|
|
362
363
|
return [
|
|
363
364
|
`humanish export ${result.runId}`,
|
|
364
|
-
`workspace: ${result.path} (${(result.bytes / 1024).toFixed(0)} KB, ${result.embeddedImages
|
|
365
|
+
`workspace: ${result.path} (${(result.bytes / 1024).toFixed(0)} KB, ${plural(result.embeddedImages, "blurred image")})`,
|
|
365
366
|
`share safety: ${result.shareSafety.status}`,
|
|
366
367
|
`verify: humanish verify --cwd ${shellQuote(result.path)} --run ${shellQuote(result.runId)}`,
|
|
367
368
|
`feedback: humanish feedback draft --cwd ${shellQuote(result.path)} --run ${shellQuote(result.runId)}`,
|
|
@@ -371,7 +372,7 @@ export function formatExportHuman(result) {
|
|
|
371
372
|
}
|
|
372
373
|
const lines = [
|
|
373
374
|
`humanish export ${result.runId}`,
|
|
374
|
-
`file: ${result.path} (${(result.bytes / 1024).toFixed(0)} KB, ${result.embeddedImages
|
|
375
|
+
`file: ${result.path} (${(result.bytes / 1024).toFixed(0)} KB, ${plural(result.embeddedImages, "image")} embedded)`,
|
|
375
376
|
`share safety: ${result.shareSafety.status}${result.watermarked ? " (watermarked: local only)" : ""}`,
|
|
376
377
|
...result.warnings.map((warning) => `warning: ${warning}`),
|
|
377
378
|
];
|
package/dist/feedback/proof.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import type { RunBundle, RunFeedbackCandidate } from "../run/bundle.js";
|
|
|
2
2
|
/** Commands run from the evidence workspace using an installed humanish CLI. */
|
|
3
3
|
export declare function feedbackProofCommands(runId: string): {
|
|
4
4
|
verify: string;
|
|
5
|
-
|
|
5
|
+
observe: string;
|
|
6
6
|
};
|
|
7
7
|
/** Legacy command compatibility belongs in the draft, never in the source receipt. */
|
|
8
8
|
export declare function projectFeedbackAcceptanceProof(bundle: RunBundle, candidate: RunFeedbackCandidate): string[];
|
package/dist/feedback/proof.js
CHANGED
|
@@ -5,7 +5,7 @@ export function feedbackProofCommands(runId) {
|
|
|
5
5
|
const argument = /^[a-z0-9][a-z0-9._-]*$/i.test(runId) ? runId : shellQuote(runId);
|
|
6
6
|
return {
|
|
7
7
|
verify: `humanish verify --run ${argument} --json`,
|
|
8
|
-
|
|
8
|
+
observe: `humanish observe --run ${argument} --no-open`,
|
|
9
9
|
};
|
|
10
10
|
}
|
|
11
11
|
/** Legacy command compatibility belongs in the draft, never in the source receipt. */
|
|
@@ -17,7 +17,7 @@ export function projectFeedbackAcceptanceProof(bundle, candidate) {
|
|
|
17
17
|
if (instruction === `pnpm humanish -- verify --run ${bundle.runId} --json`)
|
|
18
18
|
return commands.verify;
|
|
19
19
|
if (instruction === `pnpm humanish -- watch --run ${bundle.runId} --no-open`)
|
|
20
|
-
return commands.
|
|
20
|
+
return commands.observe;
|
|
21
21
|
return instruction;
|
|
22
22
|
});
|
|
23
23
|
}
|
package/dist/guest/bootstrap.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { desktopRecordingConfigSchema, } from "../evidence/desktop-recording-types.js";
|
|
2
2
|
import { validateBrowserControlIdentity, sameBrowserControlIdentity, } from "../browser-control/protocol.js";
|
|
3
|
-
import {
|
|
3
|
+
import { ComputerUseExecutorError } from "../actors/computer-use/executor-error.js";
|
|
4
4
|
import { createBrowserControlClient } from "../browser-control/client.js";
|
|
5
5
|
import { guestMediaConfigSchema } from "./media-config.js";
|
|
6
6
|
export const GUEST_BOOTSTRAP_VERSION = 1;
|
|
@@ -15,7 +15,7 @@ export const GUEST_BOOTSTRAP_LIMITS = Object.freeze({
|
|
|
15
15
|
connectMs: 3000,
|
|
16
16
|
port: 5251,
|
|
17
17
|
});
|
|
18
|
-
const refused = () => new
|
|
18
|
+
const refused = () => new ComputerUseExecutorError("protocol_mismatch", "not_dispatched");
|
|
19
19
|
/** Same entry authority as the local desktop's opaque app-port forward. */
|
|
20
20
|
export function validateGuestInitialUrl(value) {
|
|
21
21
|
try {
|
|
@@ -223,7 +223,7 @@ export class GuestBootstrapReader {
|
|
|
223
223
|
return;
|
|
224
224
|
this.terminal = true;
|
|
225
225
|
this.release();
|
|
226
|
-
this.reject(new
|
|
226
|
+
this.reject(new ComputerUseExecutorError(code, "not_dispatched"));
|
|
227
227
|
this.stream.destroy();
|
|
228
228
|
this.onFailure();
|
|
229
229
|
}
|
|
@@ -249,7 +249,7 @@ export async function connectGuestBootstrap(stream, identity, signal, initialUrl
|
|
|
249
249
|
const request = encodeGuestBootstrap(identity, false, initialUrl, media, recording);
|
|
250
250
|
await new Promise((resolve, reject) => {
|
|
251
251
|
let bytes = Buffer.alloc(0), done = false;
|
|
252
|
-
const timer = setTimeout(() => finish(new
|
|
252
|
+
const timer = setTimeout(() => finish(new ComputerUseExecutorError("deadline_exceeded", "not_dispatched")), GUEST_BOOTSTRAP_LIMITS.connectMs);
|
|
253
253
|
const finish = (error) => {
|
|
254
254
|
if (done)
|
|
255
255
|
return;
|
|
@@ -277,9 +277,9 @@ export async function connectGuestBootstrap(stream, identity, signal, initialUrl
|
|
|
277
277
|
const end = () => {
|
|
278
278
|
if (done)
|
|
279
279
|
stream.destroy();
|
|
280
|
-
finish(new
|
|
280
|
+
finish(new ComputerUseExecutorError("transport_failed", "not_dispatched"));
|
|
281
281
|
};
|
|
282
|
-
const abort = () => finish(new
|
|
282
|
+
const abort = () => finish(new ComputerUseExecutorError("session_revoked", "not_dispatched"));
|
|
283
283
|
const data = (chunk) => {
|
|
284
284
|
if (!Buffer.isBuffer(chunk) || bytes.length + chunk.length > 64 + 1028) {
|
|
285
285
|
finish(refused());
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BROWSER_CONTROL_LIMITS } from "../browser-control/protocol.js";
|
|
2
|
-
import {
|
|
2
|
+
import { ComputerUseExecutorError, isComputerUseExecutorError, } from "../actors/computer-use/executor-error.js";
|
|
3
3
|
/** Owner-only composition for a single headed Chromium page. Never an actor API. */
|
|
4
4
|
export function createGuestBrowserTools(native, content) {
|
|
5
5
|
let addressBarArmed = false;
|
|
@@ -11,7 +11,7 @@ export function createGuestBrowserTools(native, content) {
|
|
|
11
11
|
const inputGeneration = ++generation;
|
|
12
12
|
await native.input(args, signal);
|
|
13
13
|
if (signal.aborted || inputGeneration !== generation)
|
|
14
|
-
throw new
|
|
14
|
+
throw new ComputerUseExecutorError("session_revoked", "outcome_uncertain");
|
|
15
15
|
// Positive navigation intent, not an inference from document.hasFocus().
|
|
16
16
|
addressBarArmed =
|
|
17
17
|
args.length === 3 &&
|
|
@@ -28,15 +28,15 @@ export function createGuestBrowserTools(native, content) {
|
|
|
28
28
|
// separate qualification. Do not silently switch routes or transliterate.
|
|
29
29
|
if (!/^[\x20-\x7e]+$/.test(text) ||
|
|
30
30
|
Buffer.byteLength(text) > BROWSER_CONTROL_LIMITS.textBytes) {
|
|
31
|
-
throw new
|
|
31
|
+
throw new ComputerUseExecutorError("action_rejected", "not_dispatched");
|
|
32
32
|
}
|
|
33
33
|
const preparedGeneration = generation;
|
|
34
34
|
let used = false;
|
|
35
35
|
function check() {
|
|
36
36
|
if (signal.aborted)
|
|
37
|
-
throw new
|
|
37
|
+
throw new ComputerUseExecutorError("session_revoked", "not_dispatched");
|
|
38
38
|
if (used || preparedGeneration !== generation)
|
|
39
|
-
throw new
|
|
39
|
+
throw new ComputerUseExecutorError("action_rejected", "not_dispatched");
|
|
40
40
|
}
|
|
41
41
|
check();
|
|
42
42
|
await content.assertReady(signal);
|
|
@@ -52,15 +52,15 @@ export function createGuestBrowserTools(native, content) {
|
|
|
52
52
|
try {
|
|
53
53
|
await native.input(["key", "--clearmodifiers", "ctrl+l"], signal);
|
|
54
54
|
if (signal.aborted)
|
|
55
|
-
throw new
|
|
55
|
+
throw new ComputerUseExecutorError("session_revoked", "outcome_uncertain");
|
|
56
56
|
await content.assertReady(signal);
|
|
57
57
|
if (signal.aborted || preparedGeneration !== generation)
|
|
58
|
-
throw new
|
|
58
|
+
throw new ComputerUseExecutorError("session_revoked", "outcome_uncertain");
|
|
59
59
|
await native.typeAscii(text, signal);
|
|
60
60
|
}
|
|
61
61
|
catch (error) {
|
|
62
62
|
// Ctrl+L itself is input. No content fallback after that dispatch.
|
|
63
|
-
throw new
|
|
63
|
+
throw new ComputerUseExecutorError(isComputerUseExecutorError(error) ? error.code : "execution_failed", "outcome_uncertain");
|
|
64
64
|
}
|
|
65
65
|
},
|
|
66
66
|
async close() {
|
|
@@ -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 {};
|