humanish 0.107.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 +73 -69
- package/CHANGELOG.md +27 -0
- package/CONTEXT.md +51 -44
- package/README.md +148 -175
- package/SECURITY.md +16 -26
- package/TELEMETRY.md +8 -6
- package/dist/actors/affordance.d.ts +4 -4
- package/dist/actors/affordance.js +12 -12
- package/dist/actors/agent-session.d.ts +2 -2
- package/dist/actors/agent-session.js +7 -7
- package/dist/actors/codex/app-server-actor-trace.d.ts +1 -1
- package/dist/actors/codex/app-server-actor-trace.js +1 -1
- package/dist/actors/codex/app-server-trace.js +2 -1
- package/dist/actors/codex/app-server-ui.js +1 -1
- package/dist/actors/codex/codex-admission.d.ts +91 -0
- package/dist/actors/codex/codex-admission.js +150 -0
- package/dist/actors/codex/restricted-executable.d.ts +4 -4
- package/dist/actors/codex/restricted-executable.js +8 -8
- package/dist/actors/codex/restricted-launch.d.ts +2 -1
- package/dist/actors/codex/restricted-launch.js +1 -1
- package/dist/actors/codex/restricted-participant.js +20 -18
- package/dist/actors/codex/restricted-policy.d.ts +2 -2
- package/dist/actors/codex/restricted-policy.js +2 -2
- package/dist/actors/codex/restricted-session.d.ts +3 -3
- package/dist/actors/codex/restricted-session.js +10 -5
- package/dist/actors/computer-use/actor.d.ts +18 -18
- package/dist/actors/computer-use/actor.js +4 -4
- package/dist/actors/computer-use/admission-limit.d.ts +3 -3
- package/dist/actors/computer-use/admission-limit.js +4 -4
- 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.d.ts +3 -3
- package/dist/actors/computer-use/loop/actions.js +15 -15
- package/dist/actors/computer-use/loop/backstop.d.ts +3 -3
- package/dist/actors/computer-use/loop/backstop.js +14 -12
- package/dist/actors/computer-use/loop/debrief.js +2 -2
- package/dist/actors/computer-use/loop/ending.d.ts +6 -6
- package/dist/actors/computer-use/loop/ending.js +18 -17
- package/dist/actors/computer-use/loop/observation.d.ts +2 -2
- package/dist/actors/computer-use/loop/observation.js +15 -14
- package/dist/actors/computer-use/loop/provider-call.d.ts +1 -1
- package/dist/actors/computer-use/loop/provider-call.js +12 -12
- package/dist/actors/computer-use/loop/session.d.ts +4 -4
- package/dist/actors/computer-use/loop/session.js +4 -4
- package/dist/actors/computer-use/loop/spend.d.ts +1 -1
- package/dist/actors/computer-use/loop/spend.js +1 -1
- package/dist/actors/computer-use/loop/trace.js +11 -9
- package/dist/actors/computer-use/loop/types.d.ts +47 -45
- package/dist/actors/computer-use/loop/usage.d.ts +2 -2
- package/dist/actors/computer-use/loop/usage.js +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-context.d.ts +37 -0
- package/dist/actors/computer-use/openai-context.js +214 -0
- package/dist/actors/computer-use/openai-provider.d.ts +13 -10
- package/dist/actors/computer-use/openai-provider.js +52 -41
- package/dist/actors/computer-use/openai-requests.d.ts +36 -10
- package/dist/actors/computer-use/openai-requests.js +82 -15
- package/dist/actors/computer-use/openai-wire.d.ts +19 -7
- package/dist/actors/computer-use/openai-wire.js +36 -34
- 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 +82 -47
- package/dist/actors/contract.js +30 -24
- package/dist/actors/local-agent/claude-session.d.ts +1 -1
- package/dist/actors/local-agent/claude-session.js +13 -12
- package/dist/actors/local-agent/cli.d.ts +9 -7
- package/dist/actors/local-agent/cli.js +24 -28
- package/dist/actors/local-agent/readiness.d.ts +2 -2
- package/dist/actors/local-agent/readiness.js +4 -4
- package/dist/actors/reasoning-effort.js +8 -8
- package/dist/actors/registry.d.ts +12 -12
- package/dist/actors/registry.js +21 -20
- package/dist/actors/scripted-browser/actor.d.ts +10 -10
- package/dist/actors/scripted-browser/actor.js +17 -17
- package/dist/actors/scripted-browser/browser-command.js +1 -1
- package/dist/actors/scripted-browser/steps.js +1 -1
- package/dist/actors/scripted-browser/types.d.ts +1 -1
- package/dist/actors/stop-conditions.d.ts +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/codex-config.d.ts +6 -2
- package/dist/analysis/codex-config.js +22 -14
- package/dist/analysis/execute.d.ts +1 -1
- package/dist/analysis/execute.js +1 -1
- package/dist/analysis/service.js +5 -5
- 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/analyze.js +19 -16
- package/dist/cli/commands/codex.js +9 -9
- package/dist/cli/commands/comms.js +48 -35
- package/dist/cli/commands/feedback.js +20 -21
- package/dist/cli/commands/migrate.d.ts +4 -0
- package/dist/cli/commands/migrate.js +65 -0
- package/dist/cli/commands/observe.d.ts +0 -1
- package/dist/cli/commands/observe.js +136 -112
- package/dist/cli/commands/run-command.d.ts +10 -0
- package/dist/cli/commands/run-command.js +85 -0
- package/dist/cli/commands/runs.js +136 -139
- package/dist/cli/commands/setup.d.ts +2 -2
- package/dist/cli/commands/setup.js +27 -24
- package/dist/cli/commands/study-format.d.ts +9 -0
- package/dist/cli/commands/{lab-format.js → study-format.js} +39 -27
- 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} +17 -18
- 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} +7 -6
- 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} +10 -10
- 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} +44 -45
- package/dist/cli/commands/{lab-scorer.d.ts → study-scorer.d.ts} +7 -7
- package/dist/cli/commands/{lab-scorer.js → study-scorer.js} +2 -2
- package/dist/cli/commands/study.d.ts +3 -0
- package/dist/cli/commands/study.js +146 -0
- package/dist/cli/commands/tui.d.ts +4 -4
- package/dist/cli/commands/tui.js +31 -31
- package/dist/cli/commands/watch.js +71 -121
- package/dist/cli/deprecations.d.ts +6 -0
- package/dist/cli/deprecations.js +18 -0
- package/dist/cli/doctor.d.ts +18 -8
- package/dist/cli/doctor.js +114 -59
- package/dist/cli/first-run-path.d.ts +15 -13
- package/dist/cli/first-run-path.js +35 -33
- package/dist/cli/io.d.ts +44 -9
- package/dist/cli/io.js +98 -23
- package/dist/cli/observer-follow.d.ts +3 -3
- package/dist/cli/observer-follow.js +6 -7
- package/dist/cli/orientation.d.ts +10 -7
- package/dist/cli/orientation.js +89 -47
- package/dist/cli/product-sentence.d.ts +6 -0
- package/dist/cli/product-sentence.js +6 -0
- package/dist/cli/program.d.ts +6 -1
- package/dist/cli/program.js +111 -43
- package/dist/cli/telemetry.d.ts +16 -16
- package/dist/cli/telemetry.js +46 -44
- package/dist/cli.js +1 -1
- package/dist/comms/capture-surface.d.ts +13 -12
- package/dist/comms/capture-surface.js +23 -22
- package/dist/comms/catch-host.d.ts +7 -7
- package/dist/comms/catch-host.js +17 -17
- package/dist/comms/connections.d.ts +1 -1
- package/dist/comms/connections.js +2 -2
- package/dist/comms/email-catch.d.ts +3 -3
- package/dist/comms/email-catch.js +8 -8
- package/dist/comms/external-evidence.d.ts +5 -5
- package/dist/comms/external-evidence.js +5 -4
- package/dist/comms/extract.js +2 -2
- package/dist/comms/fake-inbox.d.ts +3 -3
- package/dist/comms/fake-inbox.js +3 -3
- package/dist/comms/receiving-render.d.ts +1 -1
- package/dist/comms/receiving-render.js +2 -2
- package/dist/comms/receiving-runtime.d.ts +4 -4
- package/dist/comms/sandbox-catch-script.d.ts +6 -6
- package/dist/comms/sandbox-catch-script.js +6 -6
- package/dist/comms/sandbox-catch.d.ts +38 -39
- package/dist/comms/sandbox-catch.js +36 -37
- package/dist/comms/setup.d.ts +2 -2
- package/dist/comms/setup.js +56 -25
- package/dist/comms/thread-evidence.d.ts +1 -1
- package/dist/comms/thread-evidence.js +6 -6
- package/dist/comms/types.d.ts +6 -6
- package/dist/comms/types.js +3 -3
- package/dist/evidence/frame-signature.d.ts +1 -1
- package/dist/evidence/frame-signature.js +4 -4
- package/dist/evidence/redaction.d.ts +3 -3
- package/dist/evidence/redaction.js +4 -4
- package/dist/feedback/draft.js +38 -80
- package/dist/feedback/export-bundle.js +1 -1
- package/dist/feedback/export.d.ts +5 -1
- package/dist/feedback/export.js +10 -10
- package/dist/feedback/feedback.d.ts +2 -2
- package/dist/feedback/feedback.js +21 -3
- 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 +19 -19
- 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.d.ts +1 -1
- 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 +6 -6
- package/dist/index.d.ts +14 -14
- package/dist/index.js +8 -8
- package/dist/keys/key-resolution.d.ts +5 -5
- package/dist/keys/key-resolution.js +23 -23
- package/dist/observer/artifact.d.ts +2 -2
- package/dist/observer/artifact.js +7 -7
- package/dist/observer/data.d.ts +6 -6
- package/dist/observer/data.js +5 -4
- package/dist/observer/exposure.d.ts +1 -1
- package/dist/observer/exposure.js +11 -11
- package/dist/observer/http.js +1 -1
- package/dist/observer/library.d.ts +3 -1
- package/dist/observer/library.js +8 -3
- package/dist/observer/listen.js +5 -4
- package/dist/observer/render.d.ts +1 -1
- package/dist/observer/render.js +17 -6
- package/dist/observer/run-routes.d.ts +4 -3
- package/dist/observer/run-routes.js +38 -13
- package/dist/observer/serve.d.ts +1 -1
- package/dist/observer/serve.js +7 -3
- package/dist/observer/tunnel.js +1 -1
- package/dist/observer-app.html +4 -4
- package/dist/routes/computer-use/bundle-parts.d.ts +9 -9
- package/dist/routes/computer-use/bundle-parts.js +18 -17
- package/dist/routes/computer-use/bundle.d.ts +2 -2
- package/dist/routes/computer-use/bundle.js +10 -9
- package/dist/routes/computer-use/e2b-desktop/comms.d.ts +6 -6
- package/dist/routes/computer-use/e2b-desktop/comms.js +18 -17
- package/dist/routes/computer-use/e2b-desktop/desktop.js +4 -4
- package/dist/routes/computer-use/e2b-desktop/fidelity.d.ts +5 -4
- package/dist/routes/computer-use/e2b-desktop/fidelity.js +11 -10
- package/dist/routes/computer-use/e2b-desktop/prepare.d.ts +1 -1
- package/dist/routes/computer-use/e2b-desktop/prepare.js +10 -10
- package/dist/routes/computer-use/e2b-desktop/start.js +7 -7
- package/dist/routes/computer-use/e2b-desktop/state.d.ts +2 -2
- package/dist/routes/computer-use/e2b-desktop/teardown.js +2 -2
- package/dist/routes/computer-use/external-comms.d.ts +4 -4
- package/dist/routes/computer-use/external-comms.js +1 -1
- package/dist/routes/computer-use/fanout-bundle.js +27 -26
- package/dist/routes/computer-use/fanout-records.js +12 -13
- package/dist/routes/computer-use/live-flush.d.ts +4 -4
- package/dist/routes/computer-use/live-flush.js +6 -6
- package/dist/routes/computer-use/live-phase.d.ts +5 -4
- package/dist/routes/computer-use/live-phase.js +8 -8
- 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 +3 -3
- package/dist/routes/computer-use/participant-desktop.d.ts +7 -7
- package/dist/routes/computer-use/participant-desktop.js +5 -5
- package/dist/routes/computer-use/participant-execution.d.ts +4 -4
- package/dist/routes/computer-use/participant-execution.js +10 -10
- package/dist/routes/computer-use/participant-model.d.ts +6 -0
- package/dist/routes/computer-use/participant-model.js +33 -15
- package/dist/routes/computer-use/participant-prompt.d.ts +15 -15
- package/dist/routes/computer-use/participant-prompt.js +9 -9
- package/dist/routes/computer-use/participant-runs.d.ts +16 -16
- package/dist/routes/computer-use/participant-runs.js +26 -25
- package/dist/routes/computer-use/plan.d.ts +12 -12
- package/dist/routes/computer-use/plan.js +42 -42
- package/dist/routes/computer-use/preflight.d.ts +5 -5
- package/dist/routes/computer-use/preflight.js +25 -25
- package/dist/routes/computer-use/rerun-selection.d.ts +1 -1
- package/dist/routes/computer-use/rerun-selection.js +4 -3
- package/dist/routes/computer-use/result.d.ts +4 -4
- package/dist/routes/computer-use/result.js +22 -21
- package/dist/routes/computer-use/route.d.ts +12 -11
- package/dist/routes/computer-use/route.js +31 -30
- package/dist/routes/computer-use/self-report.d.ts +7 -7
- package/dist/routes/computer-use/self-report.js +32 -32
- package/dist/routes/computer-use/setup.d.ts +23 -23
- package/dist/routes/computer-use/setup.js +28 -29
- package/dist/routes/computer-use/single-bundle.d.ts +11 -11
- package/dist/routes/computer-use/single-bundle.js +40 -41
- package/dist/routes/computer-use/subject-projection.d.ts +4 -4
- package/dist/routes/computer-use/subject-projection.js +6 -6
- package/dist/routes/computer-use/types.d.ts +71 -73
- package/dist/routes/computer-use/types.js +12 -12
- package/dist/routes/preview.d.ts +13 -7
- package/dist/routes/preview.js +11 -7
- package/dist/routes/scripted/bundle.d.ts +7 -7
- package/dist/routes/scripted/bundle.js +20 -18
- package/dist/routes/scripted/plan.d.ts +8 -8
- package/dist/routes/scripted/plan.js +13 -13
- package/dist/routes/scripted/result.d.ts +3 -3
- package/dist/routes/scripted/result.js +13 -13
- package/dist/routes/scripted/route.d.ts +9 -9
- package/dist/routes/scripted/route.js +15 -16
- package/dist/routes/scripted/scenario.d.ts +1 -1
- package/dist/routes/scripted/scenario.js +5 -5
- package/dist/routes/scripted/setup.d.ts +6 -6
- package/dist/routes/scripted/setup.js +8 -8
- package/dist/routes/scripted/subject.d.ts +5 -5
- package/dist/routes/scripted/subject.js +4 -4
- package/dist/routes/scripted/surface-records.d.ts +1 -1
- package/dist/routes/scripted/surface-records.js +4 -4
- package/dist/routes/scripted/surface-sessions.d.ts +3 -3
- package/dist/routes/scripted/types.d.ts +18 -20
- package/dist/routes/scripted/types.js +2 -2
- package/dist/routes/shared-world/bundle-records.js +11 -10
- package/dist/routes/shared-world/bundle.d.ts +5 -5
- package/dist/routes/shared-world/bundle.js +46 -43
- package/dist/routes/shared-world/checkpoints.d.ts +4 -4
- package/dist/routes/shared-world/checkpoints.js +2 -2
- package/dist/routes/shared-world/comms.d.ts +14 -14
- package/dist/routes/shared-world/comms.js +19 -18
- package/dist/routes/shared-world/external-public.d.ts +4 -3
- package/dist/routes/shared-world/external-public.js +16 -12
- package/dist/routes/shared-world/handoff.d.ts +7 -6
- package/dist/routes/shared-world/handoff.js +65 -57
- package/dist/routes/shared-world/lobby-code.d.ts +2 -2
- package/dist/routes/shared-world/lobby-code.js +9 -9
- package/dist/routes/shared-world/participant-specs.d.ts +10 -9
- package/dist/routes/shared-world/participant-specs.js +38 -31
- package/dist/routes/shared-world/plan.d.ts +9 -9
- package/dist/routes/shared-world/plan.js +16 -16
- package/dist/routes/shared-world/provenance.d.ts +2 -2
- package/dist/routes/shared-world/provenance.js +2 -2
- package/dist/routes/shared-world/provisioned.d.ts +8 -8
- package/dist/routes/shared-world/provisioned.js +18 -17
- package/dist/routes/shared-world/result.d.ts +6 -6
- package/dist/routes/shared-world/result.js +29 -29
- package/dist/routes/shared-world/route.d.ts +11 -11
- package/dist/routes/shared-world/route.js +40 -39
- package/dist/routes/shared-world/setup.d.ts +16 -16
- package/dist/routes/shared-world/setup.js +23 -23
- package/dist/routes/shared-world/types.d.ts +55 -53
- package/dist/routes/shared-world/types.js +4 -4
- package/dist/routes/terminal/adapter.d.ts +5 -5
- package/dist/routes/terminal/adapter.js +9 -9
- package/dist/routes/terminal/bundle.d.ts +13 -13
- package/dist/routes/terminal/bundle.js +28 -27
- package/dist/routes/terminal/credentials.d.ts +8 -8
- package/dist/routes/terminal/credentials.js +12 -12
- package/dist/routes/terminal/dry-run.d.ts +4 -4
- package/dist/routes/terminal/dry-run.js +12 -12
- package/dist/routes/terminal/encoding.js +2 -2
- package/dist/routes/terminal/ledger.d.ts +5 -5
- package/dist/routes/terminal/ledger.js +14 -14
- 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 +10 -10
- package/dist/routes/terminal/live-sandbox.d.ts +2 -2
- package/dist/routes/terminal/live-sandbox.js +15 -15
- package/dist/routes/terminal/participant-text.js +2 -1
- package/dist/routes/terminal/persona.d.ts +2 -2
- package/dist/routes/terminal/persona.js +3 -3
- package/dist/routes/terminal/plan.d.ts +7 -7
- package/dist/routes/terminal/plan.js +15 -15
- package/dist/routes/terminal/recorder.js +2 -2
- package/dist/routes/terminal/result.d.ts +5 -5
- package/dist/routes/terminal/result.js +14 -14
- package/dist/routes/terminal/route.d.ts +9 -9
- package/dist/routes/terminal/route.js +19 -20
- package/dist/routes/terminal/sandbox.d.ts +1 -1
- package/dist/routes/terminal/sandbox.js +1 -1
- package/dist/routes/terminal/session.d.ts +5 -5
- package/dist/routes/terminal/session.js +14 -13
- package/dist/routes/terminal/token-usage.d.ts +1 -1
- package/dist/routes/terminal/token-usage.js +7 -8
- package/dist/routes/terminal/trace.d.ts +4 -4
- package/dist/routes/terminal/trace.js +2 -2
- package/dist/routes/terminal/types.d.ts +48 -50
- package/dist/routes/terminal/types.js +5 -5
- package/dist/run/bundle-shape.js +3 -3
- package/dist/run/bundle.d.ts +49 -49
- package/dist/run/bundle.js +3 -2
- package/dist/run/cost-summary.js +3 -3
- package/dist/run/costs.d.ts +23 -0
- package/dist/run/costs.js +79 -44
- package/dist/run/detail.d.ts +6 -6
- package/dist/run/detail.js +4 -4
- package/dist/run/dry-run-inputs.d.ts +1 -1
- package/dist/run/dry-run-inputs.js +2 -2
- package/dist/run/dry-run.js +20 -20
- package/dist/run/judge.d.ts +19 -13
- package/dist/run/judge.js +18 -8
- package/dist/run/outcomes.d.ts +1 -1
- package/dist/run/participant.d.ts +1 -1
- package/dist/run/paths.d.ts +1 -1
- package/dist/run/paths.js +1 -1
- package/dist/run/preflight-receipts.js +1 -1
- package/dist/run/pricing.d.ts +11 -6
- package/dist/run/pricing.js +22 -15
- package/dist/run/projection.d.ts +46 -46
- package/dist/run/projection.js +57 -57
- package/dist/run/reclaim.d.ts +1 -1
- package/dist/run/reclaim.js +3 -3
- package/dist/run/results.d.ts +5 -5
- 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 +19 -7
- package/dist/run/run-index.js +77 -64
- package/dist/run/run-not-found.d.ts +5 -0
- package/dist/run/run-not-found.js +15 -0
- package/dist/run/run.d.ts +6 -5
- package/dist/run/run.js +3 -3
- package/dist/run/sandbox-receipts.d.ts +2 -2
- package/dist/run/sandbox-receipts.js +3 -3
- package/dist/run/shared-world-evidence.d.ts +37 -36
- package/dist/run/shared-world-evidence.js +4 -4
- package/dist/run/shared-world-shape.d.ts +1 -1
- package/dist/run/shared-world-shape.js +7 -7
- package/dist/run/stats.d.ts +14 -8
- package/dist/run/stats.js +121 -63
- package/dist/run/status.d.ts +16 -29
- package/dist/run/status.js +10 -29
- package/dist/run/stored-runs.js +2 -1
- package/dist/run/stream-shape.js +1 -1
- package/dist/run/streams.d.ts +7 -7
- package/dist/run/study-provenance.d.ts +49 -0
- package/dist/run/study-provenance.js +66 -0
- package/dist/run/study-result.d.ts +11 -0
- package/dist/run/study-result.js +9 -0
- package/dist/run/text.d.ts +2 -0
- package/dist/run/text.js +4 -0
- package/dist/run-study.d.ts +112 -0
- package/dist/{run-lab.js → run-study.js} +52 -47
- package/dist/{lab → study}/adapter-extension.d.ts +15 -27
- package/dist/{lab → study}/adapter-extension.js +10 -45
- package/dist/{lab → study}/adapter-scorer-loader.d.ts +17 -17
- package/dist/{lab → study}/adapter-scorer-loader.js +34 -34
- package/dist/study/composition-rules.d.ts +7 -0
- package/dist/{lab → study}/composition-rules.js +53 -53
- package/dist/study/config.d.ts +15 -0
- package/dist/{lab → study}/config.js +98 -41
- package/dist/study/convert.d.ts +33 -0
- package/dist/study/convert.js +432 -0
- package/dist/{lab → study}/device-presets.d.ts +10 -10
- package/dist/{lab → study}/device-presets.js +11 -11
- package/dist/study/discover.d.ts +75 -0
- package/dist/{lab → study}/discover.js +134 -95
- package/dist/{lab → study}/doctor.d.ts +19 -12
- package/dist/{lab → study}/doctor.js +58 -20
- package/dist/study/field-paths.d.ts +12 -0
- package/dist/study/field-paths.js +126 -0
- package/dist/study/files.d.ts +26 -0
- package/dist/study/files.js +44 -0
- package/dist/{lab → study}/init-templates.d.ts +2 -2
- package/dist/study/init-templates.js +421 -0
- package/dist/{lab → study}/init.d.ts +2 -2
- package/dist/{lab → study}/init.js +46 -11
- package/dist/study/keys.d.ts +4 -0
- package/dist/{lab → study}/keys.js +46 -12
- package/dist/study/migrate.d.ts +48 -0
- package/dist/study/migrate.js +408 -0
- package/dist/study/owned-files.d.ts +38 -0
- package/dist/study/owned-files.js +182 -0
- package/dist/{lab → study}/parse/actors.d.ts +5 -5
- package/dist/{lab → study}/parse/actors.js +14 -14
- package/dist/study/parse/comms.d.ts +12 -0
- package/dist/{lab → study}/parse/comms.js +5 -5
- package/dist/study/parse/execution.d.ts +19 -0
- package/dist/{lab → study}/parse/execution.js +13 -13
- package/dist/study/parse/study-v3.d.ts +21 -0
- package/dist/study/parse/study-v3.js +259 -0
- package/dist/study/parse/subject-state.d.ts +30 -0
- package/dist/{lab → study}/parse/subject-state.js +19 -19
- package/dist/{lab → study}/parse/subject.d.ts +3 -3
- package/dist/{lab → study}/parse/subject.js +34 -34
- package/dist/{lab → study}/parse/values.d.ts +3 -3
- package/dist/{lab → study}/parse/values.js +3 -3
- package/dist/{lab → study}/persona-resolve.d.ts +8 -8
- package/dist/{lab → study}/persona-resolve.js +6 -6
- 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 +12 -12
- package/dist/{lab → study}/plan-participants.js +4 -4
- package/dist/{lab → study}/plan-types.d.ts +31 -31
- package/dist/{lab → study}/plan-types.js +2 -2
- package/dist/study/plan.d.ts +13 -0
- package/dist/study/plan.js +101 -0
- package/dist/study/preflight-probes.d.ts +3 -0
- package/dist/{lab → study}/preflight-probes.js +20 -19
- package/dist/study/preflight-result.d.ts +8 -0
- package/dist/{lab → study}/preflight-result.js +5 -4
- package/dist/study/preflight.d.ts +94 -0
- package/dist/{lab → study}/preflight.js +12 -12
- 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 +39 -33
- package/dist/{lab → study}/routing.js +60 -29
- package/dist/{lab/run-lab-events.d.ts → study/run-study-events.d.ts} +10 -13
- package/dist/{lab/run-lab-events.js → study/run-study-events.js} +3 -9
- package/dist/{lab/run-lab-homes.d.ts → study/run-study-homes.d.ts} +21 -18
- package/dist/{lab/run-lab-homes.js → study/run-study-homes.js} +1 -1
- package/dist/study/run-study-options.d.ts +28 -0
- package/dist/{lab/run-lab-options.js → study/run-study-options.js} +29 -25
- package/dist/{lab/lab-deps.d.ts → study/study-deps.d.ts} +8 -13
- package/dist/{lab/lab-deps.js → study/study-deps.js} +2 -2
- package/dist/{lab → study}/summary.d.ts +16 -15
- package/dist/{lab → study}/summary.js +21 -21
- package/dist/{lab → study}/tasks.d.ts +18 -18
- package/dist/{lab → study}/tasks.js +14 -14
- package/dist/{lab → study}/types.d.ts +202 -196
- package/dist/{lab → study}/types.js +3 -1
- package/dist/{lab → study}/validation.d.ts +27 -27
- package/dist/{lab → study}/validation.js +53 -51
- package/dist/study/warnings.d.ts +12 -0
- package/dist/{lab → study}/warnings.js +62 -34
- package/dist/subject/clone.d.ts +7 -7
- package/dist/subject/clone.js +2 -2
- package/dist/subject/desktop-cli.d.ts +1 -1
- package/dist/subject/desktop-cli.js +2 -2
- package/dist/subject/local-tree-archive.d.ts +2 -2
- package/dist/subject/local-tree-archive.js +4 -4
- package/dist/subject/local-tree.d.ts +4 -4
- package/dist/subject/node-bootstrap.js +1 -1
- package/dist/subject/runtime.js +9 -10
- package/dist/subject/serve.d.ts +5 -5
- package/dist/subject/serve.js +3 -3
- package/dist/subject/state.d.ts +4 -4
- package/dist/subject/state.js +1 -1
- package/dist/subject/steps.d.ts +6 -6
- package/dist/subject/steps.js +5 -5
- package/dist/substrates/command-failure.d.ts +3 -3
- package/dist/substrates/command-failure.js +3 -3
- package/dist/substrates/desktop-session.js +2 -2
- package/dist/substrates/detached.d.ts +6 -6
- package/dist/substrates/detached.js +7 -7
- package/dist/substrates/e2b/cdp-probe.d.ts +9 -9
- package/dist/substrates/e2b/cdp-probe.js +14 -17
- package/dist/substrates/e2b/desktop-browser.d.ts +6 -6
- package/dist/substrates/e2b/desktop-browser.js +9 -9
- package/dist/substrates/e2b/desktop-cdp.d.ts +10 -10
- package/dist/substrates/e2b/desktop-cdp.js +9 -9
- package/dist/substrates/e2b/desktop-executor.d.ts +2 -2
- package/dist/substrates/e2b/desktop-executor.js +13 -13
- package/dist/substrates/e2b/desktop-geometry.d.ts +4 -4
- package/dist/substrates/e2b/desktop-geometry.js +8 -8
- package/dist/substrates/e2b/desktop-media.d.ts +4 -4
- package/dist/substrates/e2b/desktop-media.js +1 -1
- package/dist/substrates/e2b/desktop-screenshot-cleanup.d.ts +3 -3
- package/dist/substrates/e2b/desktop-screenshot-cleanup.js +3 -3
- package/dist/substrates/e2b/lifetime.js +1 -1
- package/dist/substrates/e2b/sandbox.d.ts +4 -4
- package/dist/substrates/e2b/sandbox.js +2 -2
- package/dist/substrates/e2b/sdk.d.ts +12 -12
- package/dist/substrates/e2b/sdk.js +7 -7
- package/dist/substrates/local/runtime-config.d.ts +4 -4
- package/dist/substrates/local/runtime-config.js +4 -4
- package/dist/tui/actions.d.ts +1 -1
- package/dist/tui/actions.js +13 -13
- package/dist/tui/contract.d.ts +23 -23
- package/dist/tui/contract.js +11 -11
- package/dist/tui/launch.d.ts +7 -7
- package/dist/tui/launch.js +36 -31
- package/dist/tui/project.js +5 -5
- package/dist/tui-app.js +139 -139
- package/dist/verify/actor.d.ts +8 -8
- package/dist/verify/actor.js +36 -36
- package/dist/verify/artifacts.d.ts +2 -2
- package/dist/verify/artifacts.js +3 -3
- package/dist/verify/context-growth.d.ts +9 -0
- package/dist/verify/context-growth.js +62 -0
- package/dist/verify/costs.d.ts +6 -6
- package/dist/verify/costs.js +8 -8
- package/dist/verify/shared-world-concurrent.d.ts +2 -2
- package/dist/verify/shared-world-concurrent.js +79 -76
- package/dist/verify/shared-world.d.ts +2 -2
- package/dist/verify/shared-world.js +16 -16
- package/dist/verify/subject.d.ts +5 -5
- package/dist/verify/subject.js +19 -19
- package/dist/verify/verify.js +94 -44
- package/docs/README.md +25 -32
- package/docs/architecture/actor-contract.md +60 -91
- package/docs/architecture/browser-control.md +1 -1
- package/docs/architecture/desktop-sessions.md +7 -7
- package/docs/architecture/external-public-shared-world.md +68 -65
- package/docs/architecture/github-feedback-loop.md +2 -5
- package/docs/architecture/guest-desktop.md +2 -2
- package/docs/architecture/observer.md +34 -34
- package/docs/architecture/restricted-codex-analysis.md +34 -28
- package/docs/architecture/serve.md +34 -37
- package/docs/architecture/state-driven-executor.md +55 -58
- package/docs/architecture/task-protocol-support.md +6 -6
- package/docs/architecture/terminal-product-route.md +70 -110
- package/docs/contracts/README.md +24 -0
- package/docs/contracts/adapter-admission.md +3 -3
- package/docs/contracts/adapter-fixtures.md +4 -7
- package/docs/contracts/core.md +1 -3
- package/docs/contracts/errors.md +62 -0
- package/docs/contracts/feedback.md +8 -9
- package/docs/contracts/policy.md +7 -12
- package/docs/contracts/run-bundle.md +42 -44
- package/docs/contracts/schemas.md +446 -368
- package/docs/contracts/study-analysis.md +7 -4
- package/docs/contracts/study-costs.md +28 -9
- package/docs/decisions/0001-run-bundle-is-the-source-of-truth.md +1 -1
- package/docs/decisions/0002-observer-is-one-self-contained-file.md +2 -2
- package/docs/decisions/0003-contained-paths-and-cleanup-authority.md +3 -3
- package/docs/principles/actor-fidelity.md +4 -4
- package/docs/principles/engineering.md +3 -3
- package/docs/principles/invariants-and-defaults.md +38 -38
- package/docs/principles/self-driving-harness.md +1 -5
- package/docs/principles/three-roles.md +1 -1
- package/docs/product/automatic-analysis.md +7 -7
- package/examples/README.md +1 -1
- package/examples/participant/README.md +5 -5
- package/examples/participant/run.mjs +11 -10
- package/examples/scorer/README.md +3 -3
- package/examples/scorer/run.mjs +11 -12
- package/examples/scorer/scorer.mjs +3 -3
- package/package.json +16 -17
- package/skills/humanish/SKILL.md +64 -60
- package/skills/humanish/agents/openai.yaml +1 -1
- package/AGENTS.md +0 -99
- package/CONTRIBUTING.md +0 -148
- package/dist/actors/codex/qualified-versions.d.ts +0 -72
- package/dist/actors/codex/qualified-versions.js +0 -132
- package/dist/cli/commands/lab-format.d.ts +0 -8
- 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/cli/commands/lab.d.ts +0 -3
- package/dist/cli/commands/lab.js +0 -199
- package/dist/cli/renamed-options.d.ts +0 -11
- package/dist/cli/renamed-options.js +0 -18
- package/dist/lab/composition-rules.d.ts +0 -7
- package/dist/lab/config.d.ts +0 -7
- package/dist/lab/discover.d.ts +0 -65
- package/dist/lab/init-templates.js +0 -416
- package/dist/lab/keys.d.ts +0 -2
- package/dist/lab/parse/comms.d.ts +0 -12
- package/dist/lab/parse/execution.d.ts +0 -19
- package/dist/lab/parse/subject-state.d.ts +0 -30
- package/dist/lab/plan.d.ts +0 -19
- package/dist/lab/plan.js +0 -132
- package/dist/lab/preflight-probes.d.ts +0 -3
- package/dist/lab/preflight-result.d.ts +0 -7
- package/dist/lab/preflight.d.ts +0 -92
- package/dist/lab/route-inputs.d.ts +0 -28
- package/dist/lab/run-lab-options.d.ts +0 -28
- package/dist/lab/warnings.d.ts +0 -2
- package/dist/observer/static.d.ts +0 -39
- package/dist/observer/static.js +0 -369
- package/dist/run-lab.d.ts +0 -112
- package/docs/architecture/comms-inbox.md +0 -122
- package/docs/architecture/desktop-recording.md +0 -80
- package/docs/architecture/local-browser-runtime.md +0 -178
- package/docs/architecture/observer-review.md +0 -144
- package/docs/architecture/participant-media.md +0 -90
- package/docs/architecture/project-layout.md +0 -62
- package/docs/architecture/real-email-receiving.md +0 -136
- package/docs/assets/humanish-drawdb-hero.png +0 -0
- package/docs/assets/humanish-observer-hero.png +0 -0
- package/docs/goals/current.md +0 -207
- package/docs/product/lobby-trivia-3player-external-public.md +0 -77
- package/docs/product/open-source-install-experience.md +0 -240
- package/docs/ramp/README.md +0 -295
- package/docs/release/open-source-readiness.md +0 -222
- package/docs/release/public-readiness-standard.md +0 -210
- package/docs/roadmap/world-class-open-source-v0.md +0 -311
- /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}/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
|
@@ -5,16 +5,16 @@ import { type CuaSubjectProvenanceArg, type ParticipantRunOutcome } from "./type
|
|
|
5
5
|
/** The human-readable state story appended to the provenance event (and review.md via it). */
|
|
6
6
|
export declare function describeSubjectState(state: RunSubjectProvenance["state"], dryRun: boolean): string;
|
|
7
7
|
/**
|
|
8
|
-
* Feedback candidates derived from what
|
|
8
|
+
* Feedback candidates derived from what live participants actually reported.
|
|
9
9
|
*
|
|
10
|
-
* A live run's feedback draft
|
|
11
|
-
*
|
|
10
|
+
* A live run's feedback draft comes from these candidates, never from a dry-run template. The
|
|
11
|
+
* candidate worth filing is the one the study produced: a participant
|
|
12
12
|
* who reported friction on the way (the most valuable thing a run captures), or one who stopped
|
|
13
|
-
* trying. A clean pass files nothing here
|
|
14
|
-
* any falls back to
|
|
13
|
+
* trying. A clean pass files nothing here: feedback exists to carry findings, and a run without
|
|
14
|
+
* any falls back to a live summary in the draft layer instead of a template.
|
|
15
15
|
*
|
|
16
|
-
* Everything quoted is already scrub+redacted
|
|
17
|
-
* through redactNarration in the loop
|
|
16
|
+
* Everything quoted is already scrub+redacted (participant messages and `session.reason` pass
|
|
17
|
+
* through redactNarration in the loop) and passes redactText again here as defense-in-depth.
|
|
18
18
|
*/
|
|
19
19
|
export declare function participantFeedbackCandidates(args: {
|
|
20
20
|
runId: string;
|
|
@@ -34,8 +34,8 @@ export declare function participantFeedbackCandidates(args: {
|
|
|
34
34
|
commsArtifactPath?: string;
|
|
35
35
|
}>;
|
|
36
36
|
}): RunFeedbackCandidate[];
|
|
37
|
-
/** Human-readable provenance line for the single-participant subject.provenance event
|
|
38
|
-
* claims "cloned/packed and served"
|
|
37
|
+
/** Human-readable provenance line for the single-participant subject.provenance event:
|
|
38
|
+
* claims "cloned/packed and served" only when it actually happened. */
|
|
39
39
|
export declare function subjectProvenanceMessage(provenance: CuaSubjectProvenanceArg, publicAppUrl: string, dryRun: boolean, hasSession: boolean): string;
|
|
40
40
|
export declare function providerResourcesForOutcome(args: {
|
|
41
41
|
outcome: ParticipantRunOutcome | undefined;
|
|
@@ -8,15 +8,16 @@ import {} from "../../run/bundle.js";
|
|
|
8
8
|
import { participantResourceIds } from "../../run/participant-records.js";
|
|
9
9
|
import { resolveSelfReportedFriction } from "./self-report.js";
|
|
10
10
|
import {} from "./types.js";
|
|
11
|
+
import { plural } from "../../run/text.js";
|
|
11
12
|
/** The human-readable state story appended to the provenance event (and review.md via it). */
|
|
12
13
|
export function describeSubjectState(state, dryRun) {
|
|
13
14
|
switch (state.provenance) {
|
|
14
15
|
case "seeded":
|
|
15
|
-
return `seeded (${state.seed?.length ?? 0
|
|
16
|
+
return `seeded (${plural(state.seed?.length ?? 0, "step")}: ${(state.seed ?? []).map((record) => record.name).join(", ")})`;
|
|
16
17
|
case "unpinned":
|
|
17
|
-
return `
|
|
18
|
+
return `unpinned (external: ${(state.externalEnvNames ?? []).join(", ")})`;
|
|
18
19
|
case "declared-not-run":
|
|
19
|
-
return `declared, not run (${dryRun ? "dry
|
|
20
|
+
return `declared, not run (${dryRun ? "dry run" : "provisioning did not complete"})`;
|
|
20
21
|
case "undeclared":
|
|
21
22
|
return "undeclared";
|
|
22
23
|
case "external-public":
|
|
@@ -24,16 +25,16 @@ export function describeSubjectState(state, dryRun) {
|
|
|
24
25
|
}
|
|
25
26
|
}
|
|
26
27
|
/**
|
|
27
|
-
* Feedback candidates derived from what
|
|
28
|
+
* Feedback candidates derived from what live participants actually reported.
|
|
28
29
|
*
|
|
29
|
-
* A live run's feedback draft
|
|
30
|
-
*
|
|
30
|
+
* A live run's feedback draft comes from these candidates, never from a dry-run template. The
|
|
31
|
+
* candidate worth filing is the one the study produced: a participant
|
|
31
32
|
* who reported friction on the way (the most valuable thing a run captures), or one who stopped
|
|
32
|
-
* trying. A clean pass files nothing here
|
|
33
|
-
* any falls back to
|
|
33
|
+
* trying. A clean pass files nothing here: feedback exists to carry findings, and a run without
|
|
34
|
+
* any falls back to a live summary in the draft layer instead of a template.
|
|
34
35
|
*
|
|
35
|
-
* Everything quoted is already scrub+redacted
|
|
36
|
-
* through redactNarration in the loop
|
|
36
|
+
* Everything quoted is already scrub+redacted (participant messages and `session.reason` pass
|
|
37
|
+
* through redactNarration in the loop) and passes redactText again here as defense-in-depth.
|
|
37
38
|
*/
|
|
38
39
|
export function participantFeedbackCandidates(args) {
|
|
39
40
|
const candidates = [];
|
|
@@ -59,8 +60,8 @@ export function participantFeedbackCandidates(args) {
|
|
|
59
60
|
persona_id: participant.personaId,
|
|
60
61
|
actor: "computer-use",
|
|
61
62
|
substrate: args.substrate,
|
|
62
|
-
// The participant is reporting on the
|
|
63
|
-
// findings by the three-roles rule. A harness failure never reaches this builder
|
|
63
|
+
// The participant is reporting on the product: friction and abandonment are target-app
|
|
64
|
+
// findings by the three-roles rule. A harness failure never reaches this builder; it is
|
|
64
65
|
// not a participant report.
|
|
65
66
|
failure_owner: "target-app",
|
|
66
67
|
summary,
|
|
@@ -103,18 +104,18 @@ export function participantFeedbackCandidates(args) {
|
|
|
103
104
|
proposed_next_state: "study-quality-review",
|
|
104
105
|
acceptance_proof: [
|
|
105
106
|
feedbackProofCommands(args.runId).verify,
|
|
106
|
-
feedbackProofCommands(args.runId).
|
|
107
|
+
feedbackProofCommands(args.runId).observe,
|
|
107
108
|
],
|
|
108
109
|
});
|
|
109
110
|
}
|
|
110
111
|
return candidates;
|
|
111
112
|
}
|
|
112
|
-
/** Human-readable provenance line for the single-participant subject.provenance event
|
|
113
|
-
* claims "cloned/packed and served"
|
|
113
|
+
/** Human-readable provenance line for the single-participant subject.provenance event:
|
|
114
|
+
* claims "cloned/packed and served" only when it actually happened. */
|
|
114
115
|
export function subjectProvenanceMessage(provenance, publicAppUrl, dryRun, hasSession) {
|
|
115
116
|
if (provenance.source === "clone") {
|
|
116
117
|
if (dryRun) {
|
|
117
|
-
return `Subject declared: clone of ${provenance.repo}, to be served at ${publicAppUrl} in-sandbox (dry
|
|
118
|
+
return `Subject declared: clone of ${provenance.repo}, to be served at ${publicAppUrl} in-sandbox (dry run; nothing cloned)`;
|
|
118
119
|
}
|
|
119
120
|
if (provenance.commit) {
|
|
120
121
|
return hasSession
|
|
@@ -124,7 +125,7 @@ export function subjectProvenanceMessage(provenance, publicAppUrl, dryRun, hasSe
|
|
|
124
125
|
return `Subject clone attempted from ${provenance.repo}; commit unresolved (provisioning failed before resolution)`;
|
|
125
126
|
}
|
|
126
127
|
if (dryRun) {
|
|
127
|
-
return `Subject declared: local working tree, to be packed and served at ${publicAppUrl} in-sandbox (dry
|
|
128
|
+
return `Subject declared: local working tree, to be packed and served at ${publicAppUrl} in-sandbox (dry run; nothing packed)`;
|
|
128
129
|
}
|
|
129
130
|
if (provenance.archiveSha256) {
|
|
130
131
|
const dirtyLabel = provenance.dirty === true
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { CuaActorDescriptor } from "../../actors/registry.js";
|
|
2
|
-
import type { ComputerUsePlan } from "../../
|
|
2
|
+
import type { ComputerUsePlan } from "../../study/plan-types.js";
|
|
3
3
|
import type { BundleRun, RunBundle, RunRerunLineage } from "../../run/bundle.js";
|
|
4
4
|
import { type Judgment } from "../../run/judge.js";
|
|
5
5
|
import type { CuaParticipantPlan, DesktopParticipantRun, CuaSubjectProjection, CuaSubjectProvenanceArg, ParticipantRunOutcome } from "./types.js";
|
|
@@ -20,7 +20,7 @@ export interface CuaRunBundleBase {
|
|
|
20
20
|
/**
|
|
21
21
|
* The judgment for the current state of a computer-use run, by the rule for its shape: one
|
|
22
22
|
* participant (its tallied status is the verdict) or several (every participant must pass). The bundle's
|
|
23
|
-
* verdict and the
|
|
23
|
+
* verdict and the study result's ok both come from it.
|
|
24
24
|
*/
|
|
25
25
|
export declare function judgeComputerUseRun(base: Pick<CuaRunBundleBase, "participantRuns" | "rerun">, state: {
|
|
26
26
|
dryRun: boolean;
|
|
@@ -2,13 +2,14 @@
|
|
|
2
2
|
// and buildCuaRunBundle sends it to the single-participant or the fan-out builder with that
|
|
3
3
|
// shape's arguments. renderCuaReviewMarkdown writes review.md. shared-world/bundle.ts holds the
|
|
4
4
|
// same for that route.
|
|
5
|
-
import { judgeOneParticipant, judgeParticipants } from "../../run/judge.js";
|
|
5
|
+
import { judgeOneParticipant, judgeParticipants, verdictText, } from "../../run/judge.js";
|
|
6
6
|
import { desktopSpanToMinutes } from "../../run/cost-summary.js";
|
|
7
7
|
import { e2bDesktopTemplate } from "../../substrates/e2b/sandbox.js";
|
|
8
8
|
import { providerResourcesForOutcome } from "./bundle-parts.js";
|
|
9
9
|
import { participantFactsOf } from "./participant-facts.js";
|
|
10
10
|
import { buildCuaFanoutBundle } from "./fanout-bundle.js";
|
|
11
11
|
import { buildSingleParticipantBundle } from "./single-bundle.js";
|
|
12
|
+
import { plural } from "../../run/text.js";
|
|
12
13
|
/** One participant without a rerun keeps the single-participant bundle shape and its rule. */
|
|
13
14
|
function isOneParticipantRun(base) {
|
|
14
15
|
return base.participantRuns.length === 1 && base.rerun === undefined;
|
|
@@ -16,7 +17,7 @@ function isOneParticipantRun(base) {
|
|
|
16
17
|
/**
|
|
17
18
|
* The judgment for the current state of a computer-use run, by the rule for its shape: one
|
|
18
19
|
* participant (its tallied status is the verdict) or several (every participant must pass). The bundle's
|
|
19
|
-
* verdict and the
|
|
20
|
+
* verdict and the study result's ok both come from it.
|
|
20
21
|
*/
|
|
21
22
|
export function judgeComputerUseRun(base, state) {
|
|
22
23
|
const inProgress = state.inProgress === true;
|
|
@@ -84,8 +85,8 @@ function singleParticipantArgs(base, state) {
|
|
|
84
85
|
? {}
|
|
85
86
|
: { caseGroup: spec.planned.labels.caseGroup }),
|
|
86
87
|
dryRun: state.dryRun,
|
|
87
|
-
|
|
88
|
-
...(plan.title ? {
|
|
88
|
+
studyId: plan.studyId,
|
|
89
|
+
...(plan.title ? { studyTitle: plan.title } : {}),
|
|
89
90
|
mission: spec.evidenceInstructions ?? spec.instructions,
|
|
90
91
|
...(spec.evidenceAssignment === undefined ? {} : { assignment: spec.evidenceAssignment }),
|
|
91
92
|
persona: spec.persona,
|
|
@@ -157,17 +158,17 @@ export function renderCuaReviewMarkdown(bundle) {
|
|
|
157
158
|
"",
|
|
158
159
|
`- run: ${bundle.runId}`,
|
|
159
160
|
`- mode: ${bundle.mode}`,
|
|
160
|
-
`- run gate: ${bundle.review.verdict}`,
|
|
161
|
+
`- run gate: ${verdictText(bundle.review.verdict, bundle.mode)}`,
|
|
161
162
|
`- summary: ${bundle.review.summary}`,
|
|
162
163
|
...(provenance ? [`- subject: ${provenance.message}`] : []),
|
|
163
164
|
...(trace
|
|
164
165
|
? [
|
|
165
166
|
`- actor: ${trace.provider} (${trace.lane}/${trace.protocol})`,
|
|
166
|
-
//
|
|
167
|
+
// Name the trace's actual screenshot mode ("raw" | "blurred"); say
|
|
167
168
|
// nothing when no frames exist ("n/a") rather than claim a redaction that never ran.
|
|
168
|
-
`- evidence: ${trace.items.length
|
|
169
|
-
? `${trace.redaction.screenshots} screenshot
|
|
170
|
-
: "screenshot
|
|
169
|
+
`- evidence: ${plural(trace.items.length, "trace item")}, ${plural(trace.counts.screenshots ?? 0, trace.redaction.screenshots === "raw" || trace.redaction.screenshots === "blurred"
|
|
170
|
+
? `${trace.redaction.screenshots} screenshot`
|
|
171
|
+
: "screenshot")}`,
|
|
171
172
|
]
|
|
172
173
|
: []),
|
|
173
174
|
...(bundle.review.gaps.length > 0
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { type OriginMap } from "../../../comms/capture-surface.js";
|
|
2
2
|
import { type DeployedCommsCatch } from "../../../comms/sandbox-catch.js";
|
|
3
|
-
import type {
|
|
3
|
+
import type { StudyCommsEmail, StudyConfig } from "../../../study/types.js";
|
|
4
4
|
import type { Shell } from "../../../substrates/shell.js";
|
|
5
5
|
import type { ReadyParticipantDesktop } from "../participant-desktop.js";
|
|
6
6
|
import { type E2BDesktopDeps, type DesktopParticipantRun } from "../types.js";
|
|
7
7
|
/** A participant's captured-email wiring, decided from config before the sandbox exists. */
|
|
8
8
|
export interface ParticipantComms {
|
|
9
|
-
readonly email:
|
|
9
|
+
readonly email: StudyCommsEmail;
|
|
10
10
|
readonly port: number;
|
|
11
11
|
readonly smtpPort: number | undefined;
|
|
12
12
|
/** The loopback URL the persona opens to read captured mail. */
|
|
@@ -19,10 +19,10 @@ export interface ParticipantComms {
|
|
|
19
19
|
}
|
|
20
20
|
/**
|
|
21
21
|
* On an in-sandbox subject route, redirect the app's email-API sends into an in-sandbox catch
|
|
22
|
-
* (loopback) so its verification mail is
|
|
23
|
-
*
|
|
22
|
+
* (loopback) so its verification mail is captured instead of sent to the internet. Undefined when the
|
|
23
|
+
* study declares no fake email, which leaves the participant unchanged.
|
|
24
24
|
*/
|
|
25
|
-
export declare function planParticipantComms(comms:
|
|
25
|
+
export declare function planParticipantComms(comms: StudyConfig["comms"], serveUrl: string | undefined, targetUrl: string, inSandboxSubject: boolean): ParticipantComms | undefined;
|
|
26
26
|
/** The env the subject app reads to reach the catch, injected at sandbox create so it boots with it. */
|
|
27
27
|
export declare function participantCommsEnv(comms: ParticipantComms | undefined): Record<string, string>;
|
|
28
28
|
/** A started catch and the stop for its inbox-surface loop. */
|
|
@@ -33,7 +33,7 @@ export interface RunningCommsCatch {
|
|
|
33
33
|
}
|
|
34
34
|
/**
|
|
35
35
|
* Start the in-sandbox email catch before the subject serve, so the app's send-API base URL
|
|
36
|
-
* resolves the moment it boots. A comms-declared
|
|
36
|
+
* resolves the moment it boots. A comms-declared study that cannot stand the catch up fails closed
|
|
37
37
|
* rather than silently sending real mail.
|
|
38
38
|
*/
|
|
39
39
|
export declare function startCommsCatch(shell: Shell, comms: ParticipantComms, requestTimeoutMs: number): Promise<RunningCommsCatch>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Off-app email for one E2B desktop participant
|
|
1
|
+
// Off-app email for one E2B desktop participant: the in-sandbox catch the subject app sends to, the
|
|
2
2
|
// persona's inbox surface, the real-email receiving surface, and the evidence drained at teardown.
|
|
3
3
|
import { setTimeout as delay } from "node:timers/promises";
|
|
4
4
|
import { buildOriginMap } from "../../../comms/capture-surface.js";
|
|
@@ -9,14 +9,15 @@ import { redactText, toErrorMessage } from "../../../evidence/redaction.js";
|
|
|
9
9
|
import { writeContainedOutputFile } from "../../../run/contained-output.js";
|
|
10
10
|
import { inboxRecipientFor, participantHasInboxRecipient } from "../participant-desktop.js";
|
|
11
11
|
import { participantServeUrl } from "../types.js";
|
|
12
|
-
import { addressedRecipients } from "../../../
|
|
12
|
+
import { addressedRecipients } from "../../../study/parse/comms.js";
|
|
13
|
+
import { plural } from "../../../run/text.js";
|
|
13
14
|
/** Mid-run inbox-surface render cadence (ms). Coarse enough that the per-tick `cat` + file writes stay
|
|
14
15
|
* cheap; fine enough that a verification email is visible seconds after the app sends it. */
|
|
15
16
|
const INBOX_SURFACE_CADENCE_MS = 2500;
|
|
16
17
|
/**
|
|
17
18
|
* On an in-sandbox subject route, redirect the app's email-API sends into an in-sandbox catch
|
|
18
|
-
* (loopback) so its verification mail is
|
|
19
|
-
*
|
|
19
|
+
* (loopback) so its verification mail is captured instead of sent to the internet. Undefined when the
|
|
20
|
+
* study declares no fake email, which leaves the participant unchanged.
|
|
20
21
|
*/
|
|
21
22
|
export function planParticipantComms(comms, serveUrl, targetUrl, inSandboxSubject) {
|
|
22
23
|
const email = inSandboxSubject && comms?.email?.kind === "fake" ? comms.email : undefined;
|
|
@@ -42,7 +43,7 @@ export function planParticipantComms(comms, serveUrl, targetUrl, inSandboxSubjec
|
|
|
42
43
|
export function participantCommsEnv(comms) {
|
|
43
44
|
if (comms === undefined)
|
|
44
45
|
return {};
|
|
45
|
-
// injectEnv is absent on an adopter-hosted plane
|
|
46
|
+
// injectEnv is absent on an adopter-hosted plane: there is no subject env to inject
|
|
46
47
|
// because the operator points their own app at their own catch.
|
|
47
48
|
const env = comms.email.injectEnv === undefined
|
|
48
49
|
? {}
|
|
@@ -63,7 +64,7 @@ export function participantCommsEnv(comms) {
|
|
|
63
64
|
}
|
|
64
65
|
/**
|
|
65
66
|
* Start the in-sandbox email catch before the subject serve, so the app's send-API base URL
|
|
66
|
-
* resolves the moment it boots. A comms-declared
|
|
67
|
+
* resolves the moment it boots. A comms-declared study that cannot stand the catch up fails closed
|
|
67
68
|
* rather than silently sending real mail.
|
|
68
69
|
*/
|
|
69
70
|
export async function startCommsCatch(shell, comms, requestTimeoutMs) {
|
|
@@ -75,23 +76,23 @@ export async function startCommsCatch(shell, comms, requestTimeoutMs) {
|
|
|
75
76
|
if (!deployed.ready) {
|
|
76
77
|
throw new Error(`comms email catch did not become ready on 127.0.0.1:${comms.port} in the subject sandbox`);
|
|
77
78
|
}
|
|
78
|
-
// Write the
|
|
79
|
-
// yet." page
|
|
79
|
+
// Write the empty inbox once up front so the persona's /inbox always resolves to the "No messages
|
|
80
|
+
// yet." page (never a bare 404) the instant it navigates there, even before any mail arrives or if
|
|
80
81
|
// the app sends to an address no declared recipient matches (the loop only re-renders on new mail).
|
|
81
82
|
await writeInboxSurface(shell, deployed.surfaceDir, [], {
|
|
82
83
|
originMap: comms.originMap,
|
|
83
84
|
requestTimeoutMs,
|
|
84
85
|
});
|
|
85
|
-
// The surface uses its
|
|
86
|
-
// readers of the append-only NDJSON
|
|
86
|
+
// The surface uses its own FakeInbox + cursor, independent of the teardown evidence drain (two
|
|
87
|
+
// readers of the append-only NDJSON, so no double-count).
|
|
87
88
|
const stop = new AbortController();
|
|
88
89
|
let renderedCount = 0;
|
|
89
90
|
const loop = (async () => {
|
|
90
91
|
// Render-first (so even a short session gets a populated inbox), then refresh on a cadence. The
|
|
91
|
-
// cadence uses a
|
|
92
|
+
// cadence uses a real timer instead of the injected instant clock: this loop is unbounded, so an instant
|
|
92
93
|
// sleep would busy-spin and starve the session's own timers. `stop` interrupts the wait
|
|
93
94
|
// (and clears the timer) so teardown never blocks for a full cadence. Each refresh
|
|
94
|
-
// is a full, idempotent rebuild; `renderedCount` only advances on a
|
|
95
|
+
// is a full, idempotent rebuild; `renderedCount` only advances on a successful render so a
|
|
95
96
|
// transient failure retries cleanly (no duplicate emails).
|
|
96
97
|
for (;;) {
|
|
97
98
|
try {
|
|
@@ -200,19 +201,19 @@ export async function drainCommsEvidence(args) {
|
|
|
200
201
|
return path;
|
|
201
202
|
}
|
|
202
203
|
if (collected.captured > 0) {
|
|
203
|
-
// Captured mail that matched no declared recipient must not vanish silently
|
|
204
|
-
//
|
|
204
|
+
// Captured mail that matched no declared recipient must not vanish silently: tell the
|
|
205
|
+
// operator to declare comms.email.recipients[].address to match
|
|
205
206
|
// the address the app actually sends to (e.g. the one the persona surface will sign up with).
|
|
206
|
-
warnings.push(`
|
|
207
|
+
warnings.push(`The email catch captured ${plural(collected.captured, "email send")}, but none matched a declared recipient inbox, so no email evidence was written. Set comms.email.recipients[].address to the address the app sends to.`);
|
|
207
208
|
}
|
|
208
209
|
else {
|
|
209
|
-
// Zero captures is the silent-broken shape
|
|
210
|
+
// Zero captures is the silent-broken shape: the app never posted to the catch at
|
|
210
211
|
// all, so the personas stared at an empty inbox. Most common cause: the app does not
|
|
211
212
|
// actually read the declared injectEnv var for its email API base URL.
|
|
212
213
|
const transportHint = comms.email.smtp
|
|
213
214
|
? `Verify the app reads ${comms.email.smtp.hostEnv}/${comms.email.smtp.portEnv} for its SMTP host and port`
|
|
214
215
|
: `Verify the app reads ${comms.email.injectEnv} for its email API base URL (an SDK that ignores it sends real mail or throws)`;
|
|
215
|
-
warnings.push(`
|
|
216
|
+
warnings.push(`The email catch captured no email sends: the app never delivered mail through it. ${transportHint} and that the flow reached an email step.`);
|
|
216
217
|
}
|
|
217
218
|
}
|
|
218
219
|
catch (error) {
|
|
@@ -15,7 +15,7 @@ export function createE2BParticipantDesktop(spec, deps, warnings) {
|
|
|
15
15
|
warnings,
|
|
16
16
|
targetUrl,
|
|
17
17
|
desktopCliRoute: deps.subject.kind === "desktop-cli",
|
|
18
|
-
// Off-app comms
|
|
18
|
+
// Off-app comms: gated entirely on config.comms; no comms declared, no change.
|
|
19
19
|
comms: planParticipantComms(deps.residual.comms, participantServeUrl(deps.subject), targetUrl, deps.subject.kind === "clone" || deps.subject.kind === "local-tree"),
|
|
20
20
|
// The default or injected sink sees every event, started and completed alike, so an operator
|
|
21
21
|
// watching stderr sees both halves of each phase; the state keeps only completed ones.
|
|
@@ -23,9 +23,9 @@ export function createE2BParticipantDesktop(spec, deps, warnings) {
|
|
|
23
23
|
if (event.ok !== undefined)
|
|
24
24
|
state.phaseRecords.push(event);
|
|
25
25
|
deps.reportSubjectPhase(event, {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
id: spec.planned.id,
|
|
27
|
+
index: spec.planned.index,
|
|
28
|
+
count: deps.participantCount,
|
|
29
29
|
});
|
|
30
30
|
},
|
|
31
31
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ResidualConfig } from "../../../
|
|
1
|
+
import type { ResidualConfig } from "../../../study/plan-types.js";
|
|
2
2
|
import type { RunDesktopGeometry } from "../../../run/streams.js";
|
|
3
3
|
import type { DesktopBrowserFamily, DesktopBrowserLaunchIdentity } from "../../../substrates/e2b/desktop-browser.js";
|
|
4
4
|
import { makeChromeBrowserStateObserver } from "../../../substrates/e2b/desktop-cdp.js";
|
|
@@ -19,7 +19,8 @@ export declare function mobileLaunchFlags(residual: Readonly<ResidualConfig>, sp
|
|
|
19
19
|
* observation. A request that cannot be applied fails the participant closed with the reason. Only
|
|
20
20
|
* participants on a mobile preset are emulated: a run-wide flag must not hand a desktop or tablet
|
|
21
21
|
* participant an iPhone user agent (the first live proof did exactly that to the desktop newcomer
|
|
22
|
-
* beside the phone participant). Those participants carry no fidelity block,
|
|
22
|
+
* beside the phone participant). Those participants carry no fidelity block, since nothing was
|
|
23
|
+
* emulated.
|
|
23
24
|
*/
|
|
24
25
|
export declare function applyParticipantMobileFidelity(args: {
|
|
25
26
|
desktop: E2BDesktopSandbox;
|
|
@@ -44,8 +45,8 @@ export declare function participantBrowserStateObserver(args: {
|
|
|
44
45
|
}): ReturnType<typeof makeChromeBrowserStateObserver>;
|
|
45
46
|
/**
|
|
46
47
|
* The participant's final browser geometry, measured while the sandbox is alive. A final capture that
|
|
47
|
-
* measured
|
|
48
|
-
* had
|
|
48
|
+
* measured either field wins whole, so a partial final capture omits fields the launch-time capture
|
|
49
|
+
* had; only a final capture that measured nothing falls back to the launch-time
|
|
49
50
|
* capture. Also reads the emulation holder's log into the fidelity block.
|
|
50
51
|
*/
|
|
51
52
|
export declare function finalParticipantGeometry(args: {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
// Device fidelity for one E2B desktop participant: mobile emulation beyond viewport size
|
|
2
|
-
// browser-state observer that watches it for drift
|
|
1
|
+
// Device fidelity for one E2B desktop participant: mobile emulation beyond viewport size, the
|
|
2
|
+
// browser-state observer that watches it for drift, and the final browser geometry.
|
|
3
3
|
import { redactText, toErrorMessage } from "../../../evidence/redaction.js";
|
|
4
4
|
import { readDetachedLog } from "../../../substrates/detached.js";
|
|
5
5
|
import { applyMobileEmulation, DEFAULT_MOBILE_USER_AGENT, makeChromeBrowserStateObserver, } from "../../../substrates/e2b/desktop-cdp.js";
|
|
@@ -28,7 +28,8 @@ function cdpEndpoint(identity, targetUrl) {
|
|
|
28
28
|
* observation. A request that cannot be applied fails the participant closed with the reason. Only
|
|
29
29
|
* participants on a mobile preset are emulated: a run-wide flag must not hand a desktop or tablet
|
|
30
30
|
* participant an iPhone user agent (the first live proof did exactly that to the desktop newcomer
|
|
31
|
-
* beside the phone participant). Those participants carry no fidelity block,
|
|
31
|
+
* beside the phone participant). Those participants carry no fidelity block, since nothing was
|
|
32
|
+
* emulated.
|
|
32
33
|
*/
|
|
33
34
|
export async function applyParticipantMobileFidelity(args) {
|
|
34
35
|
const { spec, deps } = args;
|
|
@@ -63,10 +64,10 @@ export function participantBrowserStateObserver(args) {
|
|
|
63
64
|
return makeChromeBrowserStateObserver(args.desktop, deps.requestTimeoutMs, cdpEndpoint(args.launchIdentity, args.targetUrl), {
|
|
64
65
|
targetId: args.targetId,
|
|
65
66
|
// Once per participant: a dark observation channel is a gap in the instrument, and the
|
|
66
|
-
// funnel's
|
|
67
|
+
// funnel's "never measured" count needs this line to explain itself.
|
|
67
68
|
onUnavailable: (reason) => {
|
|
68
69
|
warnings.push(`Browser-state observer unavailable for participant ${spec.planned.id} (${redactText(deps.scrubKnownValues(reason))}); ` +
|
|
69
|
-
"urlIncludes
|
|
70
|
+
"urlIncludes, urlPathEquals and textIncludes stop conditions and task criteria are not measured in this session.");
|
|
70
71
|
},
|
|
71
72
|
drift: fidelity.emulatedTargetId === undefined
|
|
72
73
|
? undefined
|
|
@@ -75,11 +76,11 @@ export function participantBrowserStateObserver(args) {
|
|
|
75
76
|
expectedWidth: spec.planned.device.preset.width,
|
|
76
77
|
expectTouch: fidelity.applied?.requested.touch === true,
|
|
77
78
|
onDrift: (reason) => {
|
|
78
|
-
warnings.push(`Mobile emulation drift for participant ${spec.planned.id}: ${reason}
|
|
79
|
+
warnings.push(`Mobile emulation drift for participant ${spec.planned.id}: ${reason}.`);
|
|
79
80
|
},
|
|
80
81
|
onCovered: (coveredTargetId, read) => {
|
|
81
82
|
// A later tab the page itself reported at the phone width: evidence that
|
|
82
|
-
// the emulation followed the participant
|
|
83
|
+
// the emulation followed the participant, kept on the bundle.
|
|
83
84
|
if (fidelity.applied === undefined)
|
|
84
85
|
return;
|
|
85
86
|
fidelity.applied = {
|
|
@@ -95,8 +96,8 @@ export function participantBrowserStateObserver(args) {
|
|
|
95
96
|
}
|
|
96
97
|
/**
|
|
97
98
|
* The participant's final browser geometry, measured while the sandbox is alive. A final capture that
|
|
98
|
-
* measured
|
|
99
|
-
* had
|
|
99
|
+
* measured either field wins whole, so a partial final capture omits fields the launch-time capture
|
|
100
|
+
* had; only a final capture that measured nothing falls back to the launch-time
|
|
100
101
|
* capture. Also reads the emulation holder's log into the fidelity block.
|
|
101
102
|
*/
|
|
102
103
|
export async function finalParticipantGeometry(args) {
|
|
@@ -126,7 +127,7 @@ export async function finalParticipantGeometry(args) {
|
|
|
126
127
|
];
|
|
127
128
|
warnings.push(...geometryWarnings);
|
|
128
129
|
// The emulation holder's own log, after its announce line: which later targets it
|
|
129
|
-
// attached to, what it sent, and any reply that came back as an error
|
|
130
|
+
// attached to, what it sent, and any reply that came back as an error. Read while
|
|
130
131
|
// the sandbox is alive; the first live proof had no way to say what the holder did.
|
|
131
132
|
if (fidelity.applied !== undefined && fidelity.holderName !== undefined) {
|
|
132
133
|
const holderLog = await readDetachedLog(e2bShell(desktop), fidelity.holderName, deps.requestTimeoutMs).catch(() => "");
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type E2BDesktopSandbox } from "../../../substrates/e2b/sdk.js";
|
|
2
2
|
import type { E2BParticipantContext, E2BParticipantState } from "./state.js";
|
|
3
|
-
export declare const
|
|
3
|
+
export declare const CUA_ACTOR_STUDY_PROVIDER_METADATA: {
|
|
4
4
|
readonly mode: "cua-actor-lab";
|
|
5
5
|
readonly tool: "humanish";
|
|
6
6
|
};
|
|
@@ -11,7 +11,7 @@ import { loadE2BDesktopModule } from "../../../substrates/e2b/sdk.js";
|
|
|
11
11
|
import { e2bShell } from "../../../substrates/e2b/shell.js";
|
|
12
12
|
import { attachReceivingInbox, participantCommsEnv, startCommsCatch } from "./comms.js";
|
|
13
13
|
import { participantSubjectEnv } from "../types.js";
|
|
14
|
-
export const
|
|
14
|
+
export const CUA_ACTOR_STUDY_PROVIDER_METADATA = {
|
|
15
15
|
mode: "cua-actor-lab",
|
|
16
16
|
tool: "humanish",
|
|
17
17
|
};
|
|
@@ -24,7 +24,7 @@ export async function acquireParticipantDesktop(ctx, state) {
|
|
|
24
24
|
const { residual, env } = deps;
|
|
25
25
|
const subjectEnvNames = participantSubjectEnv(deps.subject);
|
|
26
26
|
const subjectEnvValues = residual.subject.envValues ?? {};
|
|
27
|
-
// Off-app comms
|
|
27
|
+
// Off-app comms: the base-URL env is injected at sandbox create, so the app reads it at
|
|
28
28
|
// boot; the catch starts right after create.
|
|
29
29
|
const commsEnv = participantCommsEnv(ctx.comms);
|
|
30
30
|
const desktopModule = await (deps.desktopModule ?? loadE2BDesktopModule)();
|
|
@@ -37,12 +37,12 @@ export async function acquireParticipantDesktop(ctx, state) {
|
|
|
37
37
|
requestTimeoutMs: deps.requestTimeoutMs,
|
|
38
38
|
timeoutMs: deps.sandboxMs,
|
|
39
39
|
metadata: {
|
|
40
|
-
...
|
|
41
|
-
labId: deps.
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
40
|
+
...CUA_ACTOR_STUDY_PROVIDER_METADATA,
|
|
41
|
+
labId: deps.studyId,
|
|
42
|
+
recordId: spec.recordId,
|
|
43
|
+
participantId: spec.planned.id,
|
|
44
|
+
participantIndex: String(spec.planned.index),
|
|
45
|
+
participantCount: String(deps.participantCount),
|
|
46
46
|
},
|
|
47
47
|
// The participant's model key never enters the sandbox (the model drives from outside).
|
|
48
48
|
// The subject's declared env names are provisioned here on the clone route.
|
|
@@ -129,7 +129,7 @@ export async function verifyParticipantScreen(ctx, state, desktop) {
|
|
|
129
129
|
state.desktopGeometry = { ...state.desktopGeometry, warnings: [screenGeometry.warning] };
|
|
130
130
|
}
|
|
131
131
|
if (screenGeometry.error && deps.screenMismatchPolicy !== "record-evidence") {
|
|
132
|
-
state.failureCode = "
|
|
132
|
+
state.failureCode = "HUMANISH_COMPUTER_USE_DEVICE_GEOMETRY";
|
|
133
133
|
throw new Error(screenGeometry.error);
|
|
134
134
|
}
|
|
135
135
|
if (screenGeometry.error && screenGeometry.verified) {
|
|
@@ -149,7 +149,7 @@ export async function provisionParticipantSubject(ctx, state, desktop) {
|
|
|
149
149
|
const { residual, subject } = deps;
|
|
150
150
|
const shell = e2bShell(desktop);
|
|
151
151
|
if (subject.kind === "desktop-cli") {
|
|
152
|
-
// Prepare the runtime and any declared product install,
|
|
152
|
+
// Prepare the runtime and any declared product install, with no keys. With install omitted,
|
|
153
153
|
// the participant discovers and installs the product from its public surfaces.
|
|
154
154
|
await provisionDesktopCli(shell, {
|
|
155
155
|
product: subject.product.name,
|
|
@@ -47,17 +47,17 @@ export async function openParticipantSurface(ctx, state, desktop) {
|
|
|
47
47
|
if (subject.kind === "desktop-cli") {
|
|
48
48
|
// A terminal window, opened the way the browser is opened on every other route: the
|
|
49
49
|
// participant arrives at a desktop with the thing they were asked to use already in front
|
|
50
|
-
// of them. They can still open another from the dock
|
|
50
|
+
// of them. They can still open another from the dock; that is the point of a desktop.
|
|
51
51
|
await openDesktopTerminal(desktop, deps.requestTimeoutMs, subject.product.workdir);
|
|
52
52
|
await desktop.wait(DESKTOP_SETTLE_MS).catch(() => undefined);
|
|
53
53
|
return;
|
|
54
54
|
}
|
|
55
55
|
const requestedMedia = residual.execution?.desktop?.media;
|
|
56
|
-
// A declared camera
|
|
56
|
+
// A declared camera is in place before the browser starts: the feed is generated or
|
|
57
57
|
// uploaded first, and a feed that cannot be produced fails the participant closed here.
|
|
58
58
|
const mediaEvidence = requestedMedia === undefined
|
|
59
59
|
? undefined
|
|
60
|
-
: await prepareDesktopMedia(desktop, requestedMedia, residual.policies?.mediaPermission ?? "prompt", deps.
|
|
60
|
+
: await prepareDesktopMedia(desktop, requestedMedia, residual.policies?.mediaPermission ?? "prompt", deps.studyCwd, deps.requestTimeoutMs);
|
|
61
61
|
const emulationFlags = mobileLaunchFlags(residual, spec);
|
|
62
62
|
const browserLaunch = await openDesktopBrowserTarget(desktop, targetUrl, deps.requestTimeoutMs, residual.execution?.desktop?.browser, [...emulationFlags, ...(mediaEvidence?.flags ?? [])], state.speech?.env ?? state.recording?.env);
|
|
63
63
|
state.desktopBrowser =
|
|
@@ -76,7 +76,7 @@ export async function openParticipantSurface(ctx, state, desktop) {
|
|
|
76
76
|
state.browserLaunched = true;
|
|
77
77
|
noteDevToolsReadiness(ctx, browserLaunch.devTools, emulationFlags.length > 0);
|
|
78
78
|
await desktop.wait(DESKTOP_SETTLE_MS).catch(() => undefined);
|
|
79
|
-
// Mobile fidelity
|
|
79
|
+
// Mobile fidelity is applied outside startParticipantStream's best-effort catch, so a request
|
|
80
80
|
// that cannot be applied fails the participant closed.
|
|
81
81
|
state.fidelity = await applyParticipantMobileFidelity({
|
|
82
82
|
desktop,
|
|
@@ -91,7 +91,7 @@ export async function openParticipantSurface(ctx, state, desktop) {
|
|
|
91
91
|
}
|
|
92
92
|
/**
|
|
93
93
|
* DevTools answering later than this after launch is recorded as a warning on the participant. Six live
|
|
94
|
-
* launches answered in 4.8-7.7 s;
|
|
94
|
+
* launches answered in 4.8-7.7 s; without this wait the reads it guards give up at about 11 s.
|
|
95
95
|
*/
|
|
96
96
|
const SLOW_DEVTOOLS_MS = 10_000;
|
|
97
97
|
/**
|
|
@@ -172,7 +172,7 @@ export async function startParticipantStream(ctx, state, desktop) {
|
|
|
172
172
|
type: "ready",
|
|
173
173
|
participantId: spec.planned.id,
|
|
174
174
|
sandboxId: desktop.sandboxId,
|
|
175
|
-
|
|
175
|
+
recordId: spec.recordId,
|
|
176
176
|
streamId: spec.streamId,
|
|
177
177
|
url: candidateStreamUrl,
|
|
178
178
|
});
|
|
@@ -188,7 +188,7 @@ export async function startParticipantStream(ctx, state, desktop) {
|
|
|
188
188
|
// never a participant finding about missing controls. Both computer-use and shared-world participants
|
|
189
189
|
// use this route.
|
|
190
190
|
if (state.initialBrowserGeometry?.unusable !== undefined) {
|
|
191
|
-
state.failureCode = "
|
|
191
|
+
state.failureCode = "HUMANISH_COMPUTER_USE_DEVICE_GEOMETRY";
|
|
192
192
|
throw new Error(`${state.failureCode}: ${state.initialBrowserGeometry.unusable} Participant actions were not started.`);
|
|
193
193
|
}
|
|
194
194
|
}
|
|
@@ -12,7 +12,7 @@ import type { E2BDesktopSandbox } from "../../../substrates/e2b/sdk.js";
|
|
|
12
12
|
import type { ParticipantDesktopEvidence } from "../participant-desktop.js";
|
|
13
13
|
import type { ParticipantComms, RunningCommsCatch } from "./comms.js";
|
|
14
14
|
import type { ParticipantFidelity } from "./fidelity.js";
|
|
15
|
-
import type {
|
|
15
|
+
import type { CuaActorStudyErrorCode, E2BDesktopDeps, DesktopParticipantRun, SandboxReleaseFact } from "../types.js";
|
|
16
16
|
/** What every step of one participant reads: its spec, the run's dependencies and where it points. */
|
|
17
17
|
export interface E2BParticipantContext {
|
|
18
18
|
readonly spec: DesktopParticipantRun;
|
|
@@ -38,7 +38,7 @@ export interface E2BParticipantState {
|
|
|
38
38
|
desktopResources: DesktopResourceObservation | undefined;
|
|
39
39
|
released: boolean;
|
|
40
40
|
sandboxRelease: SandboxReleaseFact | undefined;
|
|
41
|
-
failureCode:
|
|
41
|
+
failureCode: CuaActorStudyErrorCode | undefined;
|
|
42
42
|
commsCatch: RunningCommsCatch | undefined;
|
|
43
43
|
commsArtifactPath: string | undefined;
|
|
44
44
|
receivingInboxUrl: string | undefined;
|
|
@@ -145,14 +145,14 @@ export async function finishE2BDesktop(ctx, state, failed) {
|
|
|
145
145
|
state.sandboxTornDownAtMs = deps.now();
|
|
146
146
|
// The participant's live stream is now a dead page whichever teardown path ran (released, kept, or
|
|
147
147
|
// release-failed-awaiting-TTL); tell the watch overlay so the tile falls back to recorded
|
|
148
|
-
// evidence instead of "sandbox not found"
|
|
148
|
+
// evidence instead of "sandbox not found". Guarded: a viewer callback must never
|
|
149
149
|
// break teardown.
|
|
150
150
|
if (state.streamUrl !== undefined) {
|
|
151
151
|
try {
|
|
152
152
|
await deps.onStream({
|
|
153
153
|
type: "ended",
|
|
154
154
|
participantId: spec.planned.id,
|
|
155
|
-
|
|
155
|
+
recordId: spec.recordId,
|
|
156
156
|
streamId: spec.streamId,
|
|
157
157
|
});
|
|
158
158
|
}
|