humanish 0.106.1 → 0.108.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ARCHITECTURE.md +38 -32
- package/CHANGELOG.md +28 -0
- package/CONTEXT.md +51 -41
- package/README.md +152 -174
- 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-client.js +2 -1
- package/dist/actors/codex/app-server-trace.d.ts +0 -1
- package/dist/actors/codex/app-server-trace.js +1 -3
- package/dist/actors/codex/app-server-ui.js +1 -1
- package/dist/actors/codex/app-server.js +2 -1
- package/dist/actors/codex/codex-admission.d.ts +91 -0
- package/dist/actors/codex/codex-admission.js +150 -0
- package/dist/actors/codex/protocol-compat.d.ts +27 -0
- package/dist/actors/codex/protocol-compat.js +357 -0
- package/dist/actors/codex/protocol-contract.d.ts +61 -0
- package/dist/actors/codex/protocol-contract.js +471 -0
- package/dist/actors/codex/restricted-executable.d.ts +28 -4
- package/dist/actors/codex/restricted-executable.js +104 -29
- package/dist/actors/codex/restricted-launch.d.ts +9 -2
- package/dist/actors/codex/restricted-launch.js +43 -4
- package/dist/actors/codex/restricted-notifications.d.ts +101 -0
- package/dist/actors/codex/restricted-notifications.js +277 -0
- package/dist/actors/codex/restricted-participant.d.ts +30 -0
- package/dist/actors/codex/restricted-participant.js +66 -6
- package/dist/actors/codex/restricted-policy.d.ts +11 -3
- package/dist/actors/codex/restricted-policy.js +2 -2
- package/dist/actors/codex/restricted-session.d.ts +16 -3
- package/dist/actors/codex/restricted-session.js +60 -22
- package/dist/actors/codex/restricted-transport.d.ts +29 -0
- package/dist/actors/codex/restricted-transport.js +139 -27
- package/dist/actors/codex/restricted-turn.d.ts +19 -4
- package/dist/actors/codex/restricted-turn.js +43 -30
- package/dist/actors/computer-use/actor.d.ts +17 -17
- package/dist/actors/computer-use/actor.js +6 -6
- package/dist/actors/computer-use/admission-limit.d.ts +1 -1
- package/dist/actors/computer-use/admission-limit.js +1 -1
- package/dist/actors/computer-use/loop/actions.d.ts +3 -3
- package/dist/actors/computer-use/loop/actions.js +10 -10
- package/dist/actors/computer-use/loop/backstop.d.ts +3 -3
- package/dist/actors/computer-use/loop/backstop.js +15 -13
- package/dist/actors/computer-use/loop/ending.d.ts +7 -7
- package/dist/actors/computer-use/loop/ending.js +9 -9
- package/dist/actors/computer-use/loop/observation.d.ts +2 -2
- package/dist/actors/computer-use/loop/observation.js +9 -9
- package/dist/actors/computer-use/loop/provider-call.d.ts +1 -1
- package/dist/actors/computer-use/loop/provider-call.js +1 -1
- package/dist/actors/computer-use/loop/session.js +3 -3
- package/dist/actors/computer-use/loop/spend.d.ts +2 -2
- package/dist/actors/computer-use/loop/spend.js +4 -4
- package/dist/actors/computer-use/loop/trace.js +11 -10
- package/dist/actors/computer-use/loop/types.d.ts +37 -26
- package/dist/actors/computer-use/loop/usage.js +2 -2
- package/dist/actors/computer-use/loop.js +4 -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 +12 -9
- package/dist/actors/computer-use/openai-provider.js +47 -36
- 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/contract.d.ts +86 -49
- package/dist/actors/contract.js +29 -23
- package/dist/actors/local-agent/claude-session.d.ts +1 -1
- package/dist/actors/local-agent/claude-session.js +10 -9
- package/dist/actors/local-agent/cli.d.ts +8 -6
- 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 +6 -6
- package/dist/actors/registry.d.ts +10 -10
- package/dist/actors/registry.js +18 -17
- package/dist/actors/scripted-browser/actor.d.ts +8 -8
- package/dist/actors/scripted-browser/actor.js +16 -16
- package/dist/actors/scripted-browser/browser-command.js +1 -1
- package/dist/actors/scripted-browser/journey.js +15 -4
- package/dist/actors/scripted-browser/steps.js +19 -1
- package/dist/actors/scripted-browser/types.d.ts +12 -2
- package/dist/actors/stop-conditions.d.ts +1 -1
- package/dist/actors/stop-conditions.js +1 -3
- package/dist/analysis/automatic-completion.d.ts +13 -8
- package/dist/analysis/automatic-completion.js +14 -8
- package/dist/analysis/automatic-config.d.ts +1 -1
- package/dist/analysis/automatic-config.js +2 -2
- package/dist/analysis/automatic.d.ts +10 -4
- package/dist/analysis/automatic.js +17 -13
- package/dist/analysis/codex-config.d.ts +6 -2
- package/dist/analysis/codex-config.js +22 -14
- package/dist/analysis/diagnostics.d.ts +23 -0
- package/dist/analysis/diagnostics.js +112 -0
- package/dist/analysis/evidence-sources.js +2 -2
- package/dist/analysis/evidence.js +6 -6
- package/dist/analysis/execute.d.ts +7 -1
- package/dist/analysis/execute.js +39 -12
- package/dist/analysis/job.d.ts +8 -5
- package/dist/analysis/job.js +15 -14
- package/dist/analysis/load.d.ts +1 -1
- package/dist/analysis/load.js +5 -5
- package/dist/analysis/provider.d.ts +9 -1
- package/dist/analysis/restricted-codex.d.ts +2 -0
- package/dist/analysis/restricted-codex.js +10 -1
- package/dist/analysis/service.d.ts +2 -0
- package/dist/analysis/service.js +35 -16
- package/dist/analysis/sharing.d.ts +2 -2
- package/dist/analysis/sharing.js +5 -5
- package/dist/analysis/store-executions.d.ts +5 -5
- package/dist/analysis/store-executions.js +12 -12
- package/dist/analysis/store.d.ts +4 -4
- package/dist/analysis/store.js +13 -13
- package/dist/cli/commands/analysis-signals.d.ts +2 -1
- package/dist/cli/commands/analysis-signals.js +4 -1
- package/dist/cli/commands/analyze.js +23 -18
- package/dist/cli/commands/codex.js +9 -9
- package/dist/cli/commands/comms.js +62 -34
- package/dist/cli/commands/feedback.js +20 -21
- package/dist/cli/commands/lab-format.d.ts +5 -4
- package/dist/cli/commands/lab-format.js +35 -23
- package/dist/cli/commands/lab-route-computer-use.d.ts +0 -2
- package/dist/cli/commands/lab-route-computer-use.js +32 -21
- package/dist/cli/commands/lab-route-preview.d.ts +1 -3
- package/dist/cli/commands/lab-route-preview.js +7 -7
- package/dist/cli/commands/lab-route-run.d.ts +6 -4
- package/dist/cli/commands/lab-route-run.js +6 -2
- package/dist/cli/commands/lab-route-scripted.d.ts +0 -2
- package/dist/cli/commands/lab-route-scripted.js +0 -1
- package/dist/cli/commands/lab-route-shared-world.d.ts +0 -2
- package/dist/cli/commands/lab-route-shared-world.js +3 -4
- package/dist/cli/commands/lab-route-terminal.d.ts +0 -2
- package/dist/cli/commands/lab-route-terminal.js +0 -1
- package/dist/cli/commands/lab-run.js +84 -54
- package/dist/cli/commands/lab-scorer.d.ts +2 -4
- package/dist/cli/commands/lab-scorer.js +1 -1
- package/dist/cli/commands/migrate.d.ts +4 -0
- package/dist/cli/commands/migrate.js +65 -0
- package/dist/cli/commands/observe.js +168 -107
- package/dist/cli/commands/run-command.d.ts +10 -0
- package/dist/cli/commands/run-command.js +85 -0
- package/dist/cli/commands/run-signals.d.ts +30 -0
- package/dist/cli/commands/run-signals.js +146 -0
- package/dist/cli/commands/runs.js +137 -136
- package/dist/cli/commands/setup.d.ts +2 -2
- package/dist/cli/commands/setup.js +26 -21
- package/dist/cli/commands/study.d.ts +3 -0
- package/dist/cli/commands/study.js +182 -0
- package/dist/cli/commands/tui.d.ts +4 -4
- package/dist/cli/commands/tui.js +21 -21
- package/dist/cli/commands/watch.js +64 -77
- package/dist/cli/deprecations.d.ts +18 -0
- package/dist/cli/deprecations.js +48 -0
- package/dist/cli/doctor.d.ts +18 -5
- package/dist/cli/doctor.js +111 -48
- package/dist/cli/first-run-path.d.ts +12 -10
- package/dist/cli/first-run-path.js +30 -28
- package/dist/cli/io.d.ts +46 -10
- package/dist/cli/io.js +109 -30
- package/dist/cli/observer-follow.d.ts +2 -2
- package/dist/cli/observer-follow.js +5 -6
- package/dist/cli/orientation.d.ts +6 -3
- package/dist/cli/orientation.js +43 -39
- 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 +112 -43
- package/dist/cli/telemetry.d.ts +17 -17
- package/dist/cli/telemetry.js +49 -41
- package/dist/cli.js +1 -1
- package/dist/comms/capture-surface.d.ts +14 -13
- package/dist/comms/capture-surface.js +23 -22
- package/dist/comms/catch-host.d.ts +8 -8
- package/dist/comms/catch-host.js +14 -14
- package/dist/comms/connections.js +4 -4
- package/dist/comms/email-catch.d.ts +3 -3
- package/dist/comms/email-catch.js +8 -8
- package/dist/comms/external-evidence.d.ts +27 -0
- package/dist/comms/external-evidence.js +93 -0
- package/dist/comms/extract.js +2 -2
- package/dist/comms/fake-inbox.d.ts +2 -2
- package/dist/comms/fake-inbox.js +2 -2
- package/dist/comms/lease-store.js +7 -7
- package/dist/comms/receiving-render.d.ts +1 -1
- package/dist/comms/receiving-render.js +2 -2
- 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 +36 -37
- package/dist/comms/sandbox-catch.js +34 -35
- package/dist/comms/setup.js +42 -8
- 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 +4 -4
- package/dist/evidence/browser-hygiene.d.ts +1 -1
- package/dist/evidence/browser-hygiene.js +1 -1
- 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 +5 -5
- package/dist/evidence/secret-scrub.d.ts +9 -0
- package/dist/evidence/secret-scrub.js +96 -0
- package/dist/feedback/draft.js +41 -85
- package/dist/feedback/export-bundle.js +5 -5
- package/dist/feedback/export.d.ts +5 -1
- package/dist/feedback/export.js +16 -17
- package/dist/feedback/feedback.d.ts +3 -3
- package/dist/feedback/feedback.js +21 -3
- package/dist/guest/chromium-text.js +2 -2
- package/dist/guest/desktop-native.d.ts +1 -1
- package/dist/guest/runtime.js +1 -1
- package/dist/index.d.ts +14 -15
- package/dist/index.js +10 -11
- package/dist/keys/key-resolution.d.ts +7 -5
- package/dist/keys/key-resolution.js +40 -38
- package/dist/lab/adapter-extension.d.ts +35 -13
- package/dist/lab/adapter-extension.js +50 -134
- package/dist/lab/adapter-scorer-loader.d.ts +32 -12
- package/dist/lab/adapter-scorer-loader.js +56 -32
- package/dist/lab/composition-rules.js +58 -58
- package/dist/lab/config.js +85 -43
- package/dist/lab/deprecated-fields.d.ts +10 -0
- package/dist/lab/deprecated-fields.js +24 -0
- package/dist/lab/device-presets.d.ts +10 -10
- package/dist/lab/device-presets.js +11 -11
- package/dist/lab/discover.d.ts +13 -9
- package/dist/lab/discover.js +118 -60
- package/dist/lab/doctor.d.ts +53 -11
- package/dist/lab/doctor.js +193 -47
- package/dist/lab/init-plan.js +1 -3
- package/dist/lab/init-templates.js +147 -147
- package/dist/lab/init.d.ts +1 -1
- package/dist/lab/init.js +41 -9
- package/dist/lab/keys.d.ts +2 -0
- package/dist/lab/keys.js +43 -9
- package/dist/lab/lab-deps.d.ts +80 -0
- package/dist/lab/lab-deps.js +4 -0
- package/dist/lab/parse/actors.js +17 -16
- package/dist/lab/parse/comms.js +8 -7
- package/dist/lab/parse/execution.js +15 -14
- package/dist/lab/parse/study-v3.d.ts +23 -0
- package/dist/lab/parse/study-v3.js +259 -0
- package/dist/lab/parse/subject-state.d.ts +7 -7
- package/dist/lab/parse/subject-state.js +18 -17
- package/dist/lab/parse/subject.js +30 -29
- package/dist/lab/parse/values.d.ts +1 -2
- package/dist/lab/parse/values.js +3 -6
- package/dist/lab/persona-resolve.d.ts +7 -7
- package/dist/lab/persona-resolve.js +8 -8
- package/dist/lab/persona.js +1 -3
- package/dist/lab/plan-base.d.ts +0 -2
- package/dist/lab/plan-base.js +6 -4
- package/dist/lab/plan-participants.d.ts +7 -7
- package/dist/lab/plan-participants.js +2 -2
- package/dist/lab/plan-types.d.ts +26 -8
- package/dist/lab/plan.d.ts +4 -18
- package/dist/lab/plan.js +24 -79
- package/dist/lab/preflight-probes.js +11 -11
- package/dist/lab/preflight-result.d.ts +2 -1
- package/dist/lab/preflight-result.js +5 -6
- package/dist/lab/preflight.d.ts +7 -8
- package/dist/lab/preflight.js +6 -6
- package/dist/lab/requirements.d.ts +20 -0
- package/dist/lab/requirements.js +54 -0
- package/dist/lab/route-inputs.d.ts +23 -12
- package/dist/lab/route-inputs.js +48 -51
- package/dist/lab/routing.d.ts +42 -41
- package/dist/lab/routing.js +66 -68
- package/dist/lab/run-lab-events.d.ts +3 -11
- package/dist/lab/run-lab-events.js +2 -16
- package/dist/lab/run-lab-homes.d.ts +76 -0
- package/dist/lab/run-lab-homes.js +7 -0
- package/dist/lab/run-lab-options.d.ts +12 -66
- package/dist/lab/run-lab-options.js +58 -285
- package/dist/lab/summary.d.ts +15 -9
- package/dist/lab/summary.js +24 -17
- package/dist/lab/tasks.d.ts +15 -15
- package/dist/lab/tasks.js +14 -14
- package/dist/lab/types.d.ts +201 -195
- package/dist/lab/types.js +2 -0
- package/dist/lab/validation.d.ts +21 -21
- package/dist/lab/validation.js +61 -59
- package/dist/lab/warnings.d.ts +10 -0
- package/dist/lab/warnings.js +70 -41
- package/dist/library-aliases.d.ts +56 -0
- package/dist/library-aliases.js +22 -0
- package/dist/observer/artifact.d.ts +2 -2
- package/dist/observer/artifact.js +9 -9
- package/dist/observer/data.d.ts +6 -6
- package/dist/observer/data.js +7 -6
- 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 +1 -1
- package/dist/observer/library.js +4 -2
- package/dist/observer/listen.js +5 -4
- package/dist/observer/render.d.ts +1 -1
- package/dist/observer/render.js +12 -7
- package/dist/observer/run-routes.d.ts +4 -4
- package/dist/observer/run-routes.js +6 -6
- package/dist/observer/serve.d.ts +17 -0
- package/dist/observer/serve.js +41 -6
- 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 +24 -17
- package/dist/routes/computer-use/bundle.d.ts +4 -11
- package/dist/routes/computer-use/bundle.js +12 -18
- package/dist/routes/computer-use/diagnostics.d.ts +1 -1
- package/dist/routes/computer-use/diagnostics.js +1 -1
- package/dist/routes/computer-use/e2b-desktop/comms.d.ts +11 -11
- package/dist/routes/computer-use/e2b-desktop/comms.js +24 -27
- package/dist/routes/computer-use/e2b-desktop/desktop.d.ts +2 -2
- package/dist/routes/computer-use/e2b-desktop/desktop.js +8 -11
- package/dist/routes/computer-use/e2b-desktop/fidelity.d.ts +16 -15
- package/dist/routes/computer-use/e2b-desktop/fidelity.js +20 -19
- package/dist/routes/computer-use/e2b-desktop/prepare.d.ts +3 -3
- package/dist/routes/computer-use/e2b-desktop/prepare.js +40 -43
- package/dist/routes/computer-use/e2b-desktop/start.d.ts +1 -1
- package/dist/routes/computer-use/e2b-desktop/start.js +32 -30
- package/dist/routes/computer-use/e2b-desktop/state.d.ts +5 -4
- package/dist/routes/computer-use/e2b-desktop/state.js +5 -3
- package/dist/routes/computer-use/e2b-desktop/teardown.d.ts +1 -1
- package/dist/routes/computer-use/e2b-desktop/teardown.js +33 -20
- package/dist/routes/computer-use/external-comms.d.ts +4 -4
- package/dist/routes/computer-use/external-comms.js +19 -43
- package/dist/routes/computer-use/fanout-bundle.d.ts +3 -3
- package/dist/routes/computer-use/fanout-bundle.js +38 -42
- package/dist/routes/computer-use/{fanout-lanes.js → fanout-records.js} +33 -28
- package/dist/routes/computer-use/in-process-desktop.d.ts +3 -10
- package/dist/routes/computer-use/in-process-desktop.js +3 -9
- package/dist/routes/computer-use/live-flush.d.ts +7 -5
- package/dist/routes/computer-use/live-flush.js +20 -28
- package/dist/routes/computer-use/{run-lanes.d.ts → live-phase.d.ts} +4 -2
- package/dist/routes/computer-use/{run-lanes.js → live-phase.js} +17 -16
- package/dist/routes/computer-use/local-tree-pack.d.ts +3 -3
- package/dist/routes/computer-use/local-tree-pack.js +4 -5
- package/dist/routes/computer-use/local-vm.d.ts +11 -8
- package/dist/routes/computer-use/local-vm.js +40 -67
- package/dist/routes/computer-use/participant-desktop.d.ts +8 -23
- package/dist/routes/computer-use/participant-desktop.js +5 -25
- package/dist/routes/computer-use/{lanes.d.ts → participant-execution.d.ts} +11 -11
- package/dist/routes/computer-use/{lanes.js → participant-execution.js} +39 -26
- package/dist/routes/computer-use/participant-facts.d.ts +7 -1
- package/dist/routes/computer-use/participant-facts.js +12 -1
- package/dist/routes/computer-use/participant-model.d.ts +25 -11
- package/dist/routes/computer-use/participant-model.js +76 -34
- package/dist/routes/computer-use/participant-prompt.d.ts +13 -13
- package/dist/routes/computer-use/participant-prompt.js +8 -8
- package/dist/routes/computer-use/participant-runs.d.ts +11 -11
- package/dist/routes/computer-use/participant-runs.js +18 -18
- package/dist/routes/computer-use/plan.d.ts +21 -29
- package/dist/routes/computer-use/plan.js +70 -78
- package/dist/routes/computer-use/preflight.d.ts +3 -5
- package/dist/routes/computer-use/preflight.js +40 -36
- package/dist/routes/computer-use/rerun-selection.js +11 -7
- package/dist/routes/computer-use/result.d.ts +1 -1
- package/dist/routes/computer-use/result.js +48 -38
- package/dist/routes/computer-use/route.d.ts +5 -5
- package/dist/routes/computer-use/route.js +36 -33
- package/dist/routes/computer-use/self-report.d.ts +8 -8
- package/dist/routes/computer-use/self-report.js +33 -33
- package/dist/routes/computer-use/setup.d.ts +9 -15
- package/dist/routes/computer-use/setup.js +106 -83
- package/dist/routes/computer-use/single-bundle.d.ts +13 -16
- package/dist/routes/computer-use/single-bundle.js +46 -53
- package/dist/routes/computer-use/subject-projection.d.ts +6 -8
- package/dist/routes/computer-use/subject-projection.js +24 -23
- package/dist/routes/computer-use/types.d.ts +195 -238
- package/dist/routes/computer-use/types.js +21 -13
- package/dist/routes/preview.d.ts +8 -2
- package/dist/routes/preview.js +8 -5
- package/dist/routes/scripted/bundle.d.ts +5 -8
- package/dist/routes/scripted/bundle.js +23 -27
- package/dist/routes/scripted/plan.d.ts +6 -8
- package/dist/routes/scripted/plan.js +15 -13
- package/dist/routes/scripted/result.d.ts +4 -1
- package/dist/routes/scripted/result.js +15 -11
- package/dist/routes/scripted/route.js +15 -17
- package/dist/routes/scripted/scenario.d.ts +1 -1
- package/dist/routes/scripted/scenario.js +3 -3
- package/dist/routes/scripted/setup.d.ts +3 -2
- package/dist/routes/scripted/setup.js +27 -26
- package/dist/routes/scripted/subject.d.ts +8 -3
- package/dist/routes/scripted/subject.js +10 -6
- package/dist/routes/scripted/surface-records.js +4 -4
- package/dist/routes/scripted/surface-sessions.d.ts +2 -2
- package/dist/routes/scripted/surface-sessions.js +4 -4
- package/dist/routes/scripted/types.d.ts +21 -40
- package/dist/routes/scripted/types.js +2 -3
- package/dist/routes/shared-world/{seat-records.js → bundle-records.js} +17 -16
- package/dist/routes/shared-world/bundle.d.ts +7 -7
- package/dist/routes/shared-world/bundle.js +60 -62
- package/dist/routes/shared-world/checkpoints.d.ts +5 -5
- package/dist/routes/shared-world/checkpoints.js +5 -5
- package/dist/routes/shared-world/comms.d.ts +8 -7
- package/dist/routes/shared-world/comms.js +38 -51
- package/dist/routes/shared-world/external-public.d.ts +6 -5
- package/dist/routes/shared-world/external-public.js +28 -25
- package/dist/routes/shared-world/handoff.d.ts +10 -9
- package/dist/routes/shared-world/handoff.js +89 -81
- package/dist/routes/shared-world/lobby-code.d.ts +7 -7
- package/dist/routes/shared-world/lobby-code.js +22 -22
- package/dist/routes/shared-world/{seats.d.ts → participant-specs.d.ts} +15 -12
- package/dist/routes/shared-world/{seats.js → participant-specs.js} +65 -63
- package/dist/routes/shared-world/plan.d.ts +2 -6
- package/dist/routes/shared-world/plan.js +8 -9
- package/dist/routes/shared-world/provenance.d.ts +4 -4
- package/dist/routes/shared-world/provenance.js +4 -4
- package/dist/routes/shared-world/provisioned.d.ts +3 -2
- package/dist/routes/shared-world/provisioned.js +55 -48
- package/dist/routes/shared-world/result.js +47 -36
- package/dist/routes/shared-world/route.js +54 -57
- package/dist/routes/shared-world/setup.d.ts +6 -5
- package/dist/routes/shared-world/setup.js +16 -18
- package/dist/routes/shared-world/types.d.ts +70 -141
- package/dist/routes/shared-world/types.js +5 -5
- package/dist/routes/terminal/adapter.d.ts +10 -10
- package/dist/routes/terminal/adapter.js +32 -129
- package/dist/routes/terminal/bundle.d.ts +10 -15
- package/dist/routes/terminal/bundle.js +43 -52
- package/dist/routes/terminal/credentials.d.ts +4 -4
- package/dist/routes/terminal/credentials.js +20 -20
- package/dist/routes/terminal/dry-run.d.ts +1 -1
- package/dist/routes/terminal/dry-run.js +13 -15
- package/dist/routes/terminal/encoding.d.ts +1 -1
- package/dist/routes/terminal/encoding.js +4 -4
- package/dist/routes/terminal/ledger.d.ts +8 -8
- package/dist/routes/terminal/ledger.js +22 -22
- package/dist/routes/terminal/live-finish.d.ts +1 -2
- package/dist/routes/terminal/live-finish.js +24 -23
- package/dist/routes/terminal/live-sandbox.d.ts +3 -2
- package/dist/routes/terminal/live-sandbox.js +31 -32
- package/dist/routes/terminal/participant-text.d.ts +23 -0
- package/dist/routes/terminal/participant-text.js +165 -0
- package/dist/routes/terminal/persona.js +1 -1
- package/dist/routes/terminal/plan.d.ts +2 -6
- package/dist/routes/terminal/plan.js +23 -19
- package/dist/routes/terminal/recorder.d.ts +6 -1
- package/dist/routes/terminal/recorder.js +12 -4
- package/dist/routes/terminal/result.js +12 -12
- package/dist/routes/terminal/route.js +30 -31
- package/dist/routes/terminal/runtime.d.ts +3 -2
- package/dist/routes/terminal/runtime.js +3 -3
- package/dist/routes/terminal/sandbox.d.ts +4 -4
- package/dist/routes/terminal/sandbox.js +10 -10
- package/dist/routes/terminal/session.js +22 -19
- package/dist/routes/terminal/token-usage.d.ts +1 -1
- package/dist/routes/terminal/token-usage.js +10 -11
- package/dist/routes/terminal/trace.d.ts +7 -10
- package/dist/routes/terminal/trace.js +11 -66
- package/dist/routes/terminal/types.d.ts +104 -114
- package/dist/routes/terminal/types.js +12 -7
- package/dist/run/active-runs.d.ts +13 -0
- package/dist/run/active-runs.js +12 -0
- package/dist/run/bundle-shape.d.ts +2 -1
- package/dist/run/bundle-shape.js +7 -7
- package/dist/run/bundle.d.ts +99 -92
- package/dist/run/bundle.js +10 -8
- package/dist/run/cost-summary.js +6 -5
- package/dist/run/costs.d.ts +6 -6
- package/dist/run/costs.js +17 -11
- package/dist/run/detail.d.ts +9 -9
- package/dist/run/detail.js +10 -10
- package/dist/run/dry-run-inputs.js +1 -1
- package/dist/run/dry-run.js +23 -30
- package/dist/run/{study-files.d.ts → evidence-files.d.ts} +4 -4
- package/dist/run/{study-files.js → evidence-files.js} +5 -5
- package/dist/run/feedback-shape.js +1 -1
- package/dist/run/judge.d.ts +34 -16
- package/dist/run/judge.js +41 -14
- package/dist/run/locate.d.ts +2 -0
- package/dist/run/locate.js +3 -1
- package/dist/run/outcomes.d.ts +3 -3
- package/dist/run/outcomes.js +3 -3
- package/dist/run/participant-records.d.ts +2 -2
- package/dist/run/participant-records.js +2 -2
- package/dist/run/paths.d.ts +1 -1
- package/dist/run/paths.js +2 -2
- package/dist/run/pricing.d.ts +30 -15
- package/dist/run/pricing.js +49 -30
- package/dist/run/projection.d.ts +27 -27
- package/dist/run/projection.js +23 -23
- package/dist/run/reclaim.d.ts +6 -0
- package/dist/run/reclaim.js +15 -5
- package/dist/run/results.d.ts +5 -5
- package/dist/run/run-index.d.ts +9 -7
- package/dist/run/run-index.js +24 -25
- 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 +7 -4
- package/dist/run/run.js +10 -6
- package/dist/run/sandbox-receipts.d.ts +5 -5
- package/dist/run/sandbox-receipts.js +6 -6
- package/dist/run/shared-world-evidence.d.ts +67 -66
- package/dist/run/shared-world-evidence.js +4 -4
- package/dist/run/shared-world-shape.d.ts +3 -3
- package/dist/run/shared-world-shape.js +16 -16
- package/dist/run/stats.d.ts +17 -11
- package/dist/run/stats.js +124 -66
- package/dist/run/status.d.ts +21 -32
- package/dist/run/status.js +34 -33
- package/dist/run/stored-runs.js +2 -1
- package/dist/run/stream-shape.js +1 -1
- package/dist/run/streams.d.ts +29 -22
- package/dist/run/study-provenance.d.ts +47 -0
- package/dist/run/study-provenance.js +63 -0
- package/dist/run/study-result.d.ts +16 -0
- package/dist/run/study-result.js +9 -0
- package/dist/run/terminal-contract.d.ts +5 -5
- package/dist/run/terminal-contract.js +4 -4
- package/dist/run/text.d.ts +2 -0
- package/dist/run/text.js +4 -0
- package/dist/run/transient-comms-secrets.d.ts +5 -0
- package/dist/run/transient-comms-secrets.js +12 -0
- package/dist/run-lab.d.ts +40 -38
- package/dist/run-lab.js +42 -40
- package/dist/study/convert.d.ts +33 -0
- package/dist/study/convert.js +432 -0
- 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 +43 -0
- 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/subject/clone.d.ts +1 -1
- package/dist/subject/desktop-cli.d.ts +2 -2
- package/dist/subject/desktop-cli.js +3 -3
- package/dist/subject/local-tree-archive.d.ts +1 -1
- package/dist/subject/local-tree-archive.js +5 -5
- package/dist/subject/local-tree.d.ts +3 -3
- package/dist/subject/local-tree.js +1 -1
- package/dist/subject/node-bootstrap.d.ts +1 -1
- package/dist/subject/node-bootstrap.js +4 -4
- package/dist/subject/runtime.js +10 -11
- package/dist/subject/serve.d.ts +1 -1
- package/dist/subject/serve.js +4 -4
- package/dist/subject/state.d.ts +1 -1
- package/dist/subject/steps.d.ts +8 -8
- package/dist/subject/steps.js +7 -7
- package/dist/substrates/command-failure.d.ts +3 -3
- package/dist/substrates/command-failure.js +3 -3
- package/dist/substrates/detached.d.ts +6 -6
- package/dist/substrates/detached.js +7 -7
- package/dist/substrates/e2b/cdp-probe.d.ts +11 -11
- package/dist/substrates/e2b/cdp-probe.js +15 -18
- package/dist/substrates/e2b/desktop-browser.d.ts +5 -5
- package/dist/substrates/e2b/desktop-browser.js +12 -12
- package/dist/substrates/e2b/desktop-cdp.d.ts +15 -15
- package/dist/substrates/e2b/desktop-cdp.js +11 -11
- package/dist/substrates/e2b/desktop-executor.d.ts +1 -1
- package/dist/substrates/e2b/desktop-executor.js +1 -1
- package/dist/substrates/e2b/desktop-geometry.d.ts +6 -6
- package/dist/substrates/e2b/desktop-geometry.js +9 -9
- package/dist/substrates/e2b/desktop-media.d.ts +1 -1
- package/dist/substrates/e2b/desktop-media.js +3 -3
- 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/sandbox.d.ts +1 -1
- package/dist/substrates/e2b/sandbox.js +2 -2
- package/dist/substrates/e2b/sdk.d.ts +11 -11
- package/dist/substrates/e2b/sdk.js +8 -8
- package/dist/substrates/local/runtime-host.d.ts +2 -0
- package/dist/substrates/local/runtime-host.js +6 -0
- package/dist/tui/actions.d.ts +8 -6
- package/dist/tui/actions.js +31 -22
- package/dist/tui/contract.d.ts +16 -16
- package/dist/tui/contract.js +10 -10
- package/dist/tui/launch.d.ts +4 -4
- package/dist/tui/launch.js +18 -19
- package/dist/tui/project.js +5 -5
- package/dist/tui-app.js +83 -83
- package/dist/verify/actor.d.ts +14 -14
- package/dist/verify/actor.js +45 -45
- package/dist/verify/artifacts.d.ts +3 -3
- package/dist/verify/artifacts.js +6 -6
- package/dist/verify/context-growth.d.ts +9 -0
- package/dist/verify/context-growth.js +62 -0
- package/dist/verify/costs.d.ts +7 -7
- package/dist/verify/costs.js +9 -9
- package/dist/verify/liveness.d.ts +1 -1
- package/dist/verify/liveness.js +4 -1
- package/dist/verify/rerun.d.ts +1 -1
- package/dist/verify/rerun.js +1 -1
- 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 +18 -18
- package/dist/verify/subject.d.ts +4 -4
- package/dist/verify/subject.js +18 -18
- package/dist/verify/verify.js +98 -49
- package/docs/README.md +26 -33
- package/docs/architecture/actor-contract.md +105 -98
- package/docs/architecture/desktop-sessions.md +14 -14
- package/docs/architecture/external-public-shared-world.md +66 -59
- package/docs/architecture/github-feedback-loop.md +1 -4
- package/docs/architecture/guest-desktop.md +2 -2
- package/docs/architecture/observer.md +37 -37
- package/docs/architecture/restricted-codex-analysis.md +70 -30
- package/docs/architecture/serve.md +34 -37
- package/docs/architecture/state-driven-executor.md +55 -59
- package/docs/architecture/task-protocol-support.md +7 -9
- package/docs/architecture/{terminal-product-lane.md → terminal-product-route.md} +83 -115
- package/docs/contracts/README.md +24 -0
- package/docs/contracts/adapter-admission.md +3 -3
- package/docs/contracts/adapter-fixtures.md +2 -5
- 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 +54 -51
- package/docs/contracts/schemas.md +505 -390
- package/docs/contracts/study-analysis.md +26 -2
- package/docs/contracts/study-costs.md +11 -7
- 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/decisions/0004-participant-desktops-stay-in-the-route.md +2 -1
- 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 +8 -7
- 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/package.json +16 -17
- package/skills/humanish/SKILL.md +63 -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 -45
- package/dist/actors/codex/qualified-versions.js +0 -87
- package/dist/cli/commands/lab.d.ts +0 -3
- package/dist/cli/commands/lab.js +0 -193
- package/dist/deprecated.d.ts +0 -90
- package/dist/deprecated.js +0 -106
- package/dist/lab/bag-overrides.d.ts +0 -18
- package/dist/lab/bag-overrides.js +0 -121
- package/dist/observer/static.d.ts +0 -39
- package/dist/observer/static.js +0 -369
- package/dist/routes/computer-use/legacy-lane-spec.d.ts +0 -62
- package/dist/routes/computer-use/legacy-lane-spec.js +0 -39
- 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 -294
- 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/routes/computer-use/{fanout-lanes.d.ts → fanout-records.d.ts} +0 -0
- /package/dist/routes/shared-world/{seat-records.d.ts → bundle-records.d.ts} +0 -0
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
// Device fidelity for one E2B desktop
|
|
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";
|
|
6
6
|
import { captureDesktopBrowserGeometry } from "../../../substrates/e2b/desktop-geometry.js";
|
|
7
7
|
import { e2bShell } from "../../../substrates/e2b/shell.js";
|
|
8
|
-
/** Only
|
|
9
|
-
export function mobileLaunchFlags(
|
|
10
|
-
const requested =
|
|
8
|
+
/** Only participants on a mobile preset are emulated; the flags go on the browser command line. */
|
|
9
|
+
export function mobileLaunchFlags(residual, spec) {
|
|
10
|
+
const requested = residual.execution?.desktop?.fidelity;
|
|
11
11
|
if (!requested?.mobileEmulation || !spec.planned.device.preset.isMobile)
|
|
12
12
|
return [];
|
|
13
13
|
return [
|
|
@@ -25,14 +25,15 @@ function cdpEndpoint(identity, targetUrl) {
|
|
|
25
25
|
}
|
|
26
26
|
/**
|
|
27
27
|
* Apply mobile fidelity to the launch page before the geometry capture and the participant's first
|
|
28
|
-
* observation. A request that cannot be applied fails the
|
|
29
|
-
* a mobile preset are emulated: a run-wide flag must not hand a desktop or tablet
|
|
30
|
-
* user agent (the first live proof did exactly that to the desktop newcomer
|
|
31
|
-
* Those
|
|
28
|
+
* observation. A request that cannot be applied fails the participant closed with the reason. Only
|
|
29
|
+
* participants on a mobile preset are emulated: a run-wide flag must not hand a desktop or tablet
|
|
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, since nothing was
|
|
32
|
+
* emulated.
|
|
32
33
|
*/
|
|
33
34
|
export async function applyParticipantMobileFidelity(args) {
|
|
34
35
|
const { spec, deps } = args;
|
|
35
|
-
const request = deps.
|
|
36
|
+
const request = deps.residual.execution?.desktop?.fidelity;
|
|
36
37
|
const none = {
|
|
37
38
|
applied: undefined,
|
|
38
39
|
emulatedTargetId: undefined,
|
|
@@ -62,11 +63,11 @@ export function participantBrowserStateObserver(args) {
|
|
|
62
63
|
const { spec, deps, fidelity, warnings } = args;
|
|
63
64
|
return makeChromeBrowserStateObserver(args.desktop, deps.requestTimeoutMs, cdpEndpoint(args.launchIdentity, args.targetUrl), {
|
|
64
65
|
targetId: args.targetId,
|
|
65
|
-
// Once per
|
|
66
|
-
// funnel's
|
|
66
|
+
// Once per participant: a dark observation channel is a gap in the instrument, and the
|
|
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 = {
|
|
@@ -94,9 +95,9 @@ export function participantBrowserStateObserver(args) {
|
|
|
94
95
|
});
|
|
95
96
|
}
|
|
96
97
|
/**
|
|
97
|
-
* The
|
|
98
|
-
* measured
|
|
99
|
-
* had
|
|
98
|
+
* The participant's final browser geometry, measured while the sandbox is alive. A final capture that
|
|
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(() => "");
|
|
@@ -5,12 +5,12 @@ export declare const CUA_ACTOR_LAB_PROVIDER_METADATA: {
|
|
|
5
5
|
readonly tool: "humanish";
|
|
6
6
|
};
|
|
7
7
|
/**
|
|
8
|
-
* Create the
|
|
9
|
-
*
|
|
8
|
+
* Create the participant's sandbox, record its resources, run the adopter's prepare hook, and attach the
|
|
9
|
+
* participant's inbox and comms catch. Returns the sandbox, which the later steps drive.
|
|
10
10
|
*/
|
|
11
11
|
export declare function acquireParticipantDesktop(ctx: E2BParticipantContext, state: E2BParticipantState): Promise<E2BDesktopSandbox>;
|
|
12
12
|
/**
|
|
13
|
-
* Verify the
|
|
13
|
+
* Verify the participant's screen in the sandbox. A mismatch fails the participant closed unless the run records
|
|
14
14
|
* requested and verified geometry side by side.
|
|
15
15
|
*/
|
|
16
16
|
export declare function verifyParticipantScreen(ctx: E2BParticipantContext, state: E2BParticipantState, desktop: E2BDesktopSandbox): Promise<void>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
// The first half of an E2B desktop
|
|
2
|
-
// provision the subject. Each step fills the
|
|
1
|
+
// The first half of an E2B desktop participant's preparation: acquire the sandbox, verify its screen, and
|
|
2
|
+
// provision the subject. Each step fills the participant's state; a step that cannot proceed throws.
|
|
3
3
|
import { redactText } from "../../../evidence/redaction.js";
|
|
4
4
|
import { provisionCloneSubject } from "../../../subject/clone.js";
|
|
5
5
|
import { provisionDesktopCli } from "../../../subject/desktop-cli.js";
|
|
@@ -10,22 +10,24 @@ import { acquireE2BDesktopSandbox, e2bDesktopTemplate } from "../../../substrate
|
|
|
10
10
|
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
|
+
import { participantSubjectEnv } from "../types.js";
|
|
13
14
|
export const CUA_ACTOR_LAB_PROVIDER_METADATA = {
|
|
14
15
|
mode: "cua-actor-lab",
|
|
15
16
|
tool: "humanish",
|
|
16
17
|
};
|
|
17
18
|
/**
|
|
18
|
-
* Create the
|
|
19
|
-
*
|
|
19
|
+
* Create the participant's sandbox, record its resources, run the adopter's prepare hook, and attach the
|
|
20
|
+
* participant's inbox and comms catch. Returns the sandbox, which the later steps drive.
|
|
20
21
|
*/
|
|
21
22
|
export async function acquireParticipantDesktop(ctx, state) {
|
|
22
23
|
const { spec, deps, warnings } = ctx;
|
|
23
|
-
const {
|
|
24
|
-
const
|
|
25
|
-
|
|
24
|
+
const { residual, env } = deps;
|
|
25
|
+
const subjectEnvNames = participantSubjectEnv(deps.subject);
|
|
26
|
+
const subjectEnvValues = residual.subject.envValues ?? {};
|
|
27
|
+
// Off-app comms: the base-URL env is injected at sandbox create, so the app reads it at
|
|
26
28
|
// boot; the catch starts right after create.
|
|
27
29
|
const commsEnv = participantCommsEnv(ctx.comms);
|
|
28
|
-
const desktopModule = await (deps.
|
|
30
|
+
const desktopModule = await (deps.desktopModule ?? loadE2BDesktopModule)();
|
|
29
31
|
// An explicit template wins. Speech gets the versioned media image; ordinary
|
|
30
32
|
// browser studies retain the SDK default desktop.
|
|
31
33
|
const acquired = await acquireE2BDesktopSandbox({
|
|
@@ -36,11 +38,11 @@ export async function acquireParticipantDesktop(ctx, state) {
|
|
|
36
38
|
timeoutMs: deps.sandboxMs,
|
|
37
39
|
metadata: {
|
|
38
40
|
...CUA_ACTOR_LAB_PROVIDER_METADATA,
|
|
39
|
-
labId:
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
41
|
+
labId: deps.labId,
|
|
42
|
+
recordId: spec.recordId,
|
|
43
|
+
participantId: spec.planned.id,
|
|
44
|
+
participantIndex: String(spec.planned.index),
|
|
45
|
+
participantCount: String(deps.participantCount),
|
|
44
46
|
},
|
|
45
47
|
// The participant's model key never enters the sandbox (the model drives from outside).
|
|
46
48
|
// The subject's declared env names are provisioned here on the clone route.
|
|
@@ -62,7 +64,7 @@ export async function acquireParticipantDesktop(ctx, state) {
|
|
|
62
64
|
dpi: 96,
|
|
63
65
|
lifecycle: { onTimeout: "kill" },
|
|
64
66
|
},
|
|
65
|
-
template: e2bDesktopTemplate(
|
|
67
|
+
template: e2bDesktopTemplate(residual),
|
|
66
68
|
retry: {
|
|
67
69
|
// The default loader reclaims an acquired handle before retrying failed desktop startup.
|
|
68
70
|
// Its error names the cleanup outcome; pre-construction allocation failures remain unowned.
|
|
@@ -76,7 +78,7 @@ export async function acquireParticipantDesktop(ctx, state) {
|
|
|
76
78
|
});
|
|
77
79
|
},
|
|
78
80
|
},
|
|
79
|
-
// The receipt is on disk before any work, so `humanish reclaim` can kill this
|
|
81
|
+
// The receipt is on disk before any work, so `humanish reclaim` can kill this participant's
|
|
80
82
|
// sandbox by exact id after an interrupt.
|
|
81
83
|
receipt: { root: deps.artifactRoot, participantId: spec.planned.id, now: deps.now },
|
|
82
84
|
});
|
|
@@ -92,13 +94,10 @@ export async function acquireParticipantDesktop(ctx, state) {
|
|
|
92
94
|
if ("reason" in desktopResources) {
|
|
93
95
|
warnings.push(`Desktop resource size unavailable (${desktopResources.reason}); compute cost remains unpriced.`);
|
|
94
96
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
laneCount: deps.participantCount,
|
|
100
|
-
});
|
|
101
|
-
}
|
|
97
|
+
await deps.prepareDesktop?.(desktop, {
|
|
98
|
+
kind: "participant",
|
|
99
|
+
participant: { id: spec.planned.id, index: spec.planned.index, count: deps.participantCount },
|
|
100
|
+
});
|
|
102
101
|
if (deps.receiving) {
|
|
103
102
|
state.receivingInboxUrl = await attachReceivingInbox(shell, spec, { ...deps, receiving: deps.receiving }, ctx.targetUrl);
|
|
104
103
|
state.commsArtifactPath = "comms/receiving.json";
|
|
@@ -108,7 +107,7 @@ export async function acquireParticipantDesktop(ctx, state) {
|
|
|
108
107
|
return desktop;
|
|
109
108
|
}
|
|
110
109
|
/**
|
|
111
|
-
* Verify the
|
|
110
|
+
* Verify the participant's screen in the sandbox. A mismatch fails the participant closed unless the run records
|
|
112
111
|
* requested and verified geometry side by side.
|
|
113
112
|
*/
|
|
114
113
|
export async function verifyParticipantScreen(ctx, state, desktop) {
|
|
@@ -130,12 +129,12 @@ export async function verifyParticipantScreen(ctx, state, desktop) {
|
|
|
130
129
|
state.desktopGeometry = { ...state.desktopGeometry, warnings: [screenGeometry.warning] };
|
|
131
130
|
}
|
|
132
131
|
if (screenGeometry.error && deps.screenMismatchPolicy !== "record-evidence") {
|
|
133
|
-
state.failureCode = "
|
|
132
|
+
state.failureCode = "HUMANISH_COMPUTER_USE_DEVICE_GEOMETRY";
|
|
134
133
|
throw new Error(screenGeometry.error);
|
|
135
134
|
}
|
|
136
135
|
if (screenGeometry.error && screenGeometry.verified) {
|
|
137
136
|
// record-evidence policy: the bundle keeps requested vs verified as separate facts and
|
|
138
|
-
// discloses the divergence instead of failing this
|
|
137
|
+
// discloses the divergence instead of failing this participant's world mid-flight.
|
|
139
138
|
const mismatchWarning = deps.scrubKnownValues(`Participant ${spec.planned.id} requested a ${spec.planned.device.resolution[0]}x${spec.planned.device.resolution[1]} screen but xdpyinfo reports ${screenGeometry.verified.width}x${screenGeometry.verified.height}; recording requested vs verified separately instead of failing the participant closed.`);
|
|
140
139
|
warnings.push(mismatchWarning);
|
|
141
140
|
state.desktopGeometry = {
|
|
@@ -147,28 +146,26 @@ export async function verifyParticipantScreen(ctx, state, desktop) {
|
|
|
147
146
|
/** Install a desktop CLI, or clone or unpack the subject and serve it, in the sandbox. */
|
|
148
147
|
export async function provisionParticipantSubject(ctx, state, desktop) {
|
|
149
148
|
const { deps } = ctx;
|
|
150
|
-
const {
|
|
149
|
+
const { residual, subject } = deps;
|
|
151
150
|
const shell = e2bShell(desktop);
|
|
152
|
-
if (
|
|
153
|
-
// Prepare the runtime and any declared product install,
|
|
151
|
+
if (subject.kind === "desktop-cli") {
|
|
152
|
+
// Prepare the runtime and any declared product install, with no keys. With install omitted,
|
|
154
153
|
// the participant discovers and installs the product from its public surfaces.
|
|
155
154
|
await provisionDesktopCli(shell, {
|
|
156
|
-
product:
|
|
157
|
-
...(
|
|
158
|
-
? {}
|
|
159
|
-
: { install: config.subject.product.install }),
|
|
155
|
+
product: subject.product.name,
|
|
156
|
+
...(subject.product.install === undefined ? {} : { install: subject.product.install }),
|
|
160
157
|
requestTimeoutMs: deps.requestTimeoutMs,
|
|
161
158
|
scrub: deps.scrubKnownValues,
|
|
162
159
|
onPhase: ctx.onSubjectPhase,
|
|
163
160
|
});
|
|
164
161
|
}
|
|
165
|
-
if (
|
|
162
|
+
if (subject.kind === "clone") {
|
|
166
163
|
state.subjectCommit = await provisionCloneSubject(shell, {
|
|
167
|
-
repo:
|
|
168
|
-
depth:
|
|
169
|
-
serve,
|
|
170
|
-
...(
|
|
171
|
-
hasGithubToken:
|
|
164
|
+
repo: subject.repo,
|
|
165
|
+
depth: residual.subject.clone?.depth ?? 1,
|
|
166
|
+
serve: subject.serve,
|
|
167
|
+
...(subject.state === undefined ? {} : { state: subject.state }),
|
|
168
|
+
hasGithubToken: subject.env.includes("GITHUB_TOKEN"),
|
|
172
169
|
requestTimeoutMs: deps.requestTimeoutMs,
|
|
173
170
|
scrub: deps.scrubKnownValues,
|
|
174
171
|
onCommit: (commit) => {
|
|
@@ -178,21 +175,21 @@ export async function provisionParticipantSubject(ctx, state, desktop) {
|
|
|
178
175
|
state.stateStepRecords.push(record);
|
|
179
176
|
},
|
|
180
177
|
onPhase: ctx.onSubjectPhase,
|
|
181
|
-
...deps.
|
|
178
|
+
...deps.detachedTimers,
|
|
182
179
|
});
|
|
183
180
|
}
|
|
184
|
-
else if (
|
|
181
|
+
else if (subject.kind === "local-tree" && deps.localTreeArchiveBuffer) {
|
|
185
182
|
await provisionLocalTreeSubject(shell, {
|
|
186
183
|
archiveBuffer: deps.localTreeArchiveBuffer,
|
|
187
|
-
serve,
|
|
188
|
-
...(
|
|
184
|
+
serve: subject.serve,
|
|
185
|
+
...(subject.state === undefined ? {} : { state: subject.state }),
|
|
189
186
|
requestTimeoutMs: deps.requestTimeoutMs,
|
|
190
187
|
scrub: deps.scrubKnownValues,
|
|
191
188
|
onStateStep: (record) => {
|
|
192
189
|
state.stateStepRecords.push(record);
|
|
193
190
|
},
|
|
194
191
|
onPhase: ctx.onSubjectPhase,
|
|
195
|
-
...deps.
|
|
192
|
+
...deps.detachedTimers,
|
|
196
193
|
});
|
|
197
194
|
}
|
|
198
195
|
}
|
|
@@ -9,6 +9,6 @@ export declare function startParticipantMedia(ctx: E2BParticipantContext, state:
|
|
|
9
9
|
export declare function openParticipantSurface(ctx: E2BParticipantContext, state: E2BParticipantState, desktop: E2BDesktopSandbox): Promise<void>;
|
|
10
10
|
/**
|
|
11
11
|
* Measure the browser window and start the live stream. A stream that cannot start is a warning;
|
|
12
|
-
* unusable browser geometry fails the
|
|
12
|
+
* unusable browser geometry fails the participant before any action.
|
|
13
13
|
*/
|
|
14
14
|
export declare function startParticipantStream(ctx: E2BParticipantContext, state: E2BParticipantState, desktop: E2BDesktopSandbox): Promise<void>;
|
|
@@ -1,16 +1,17 @@
|
|
|
1
|
-
// The second half of an E2B desktop
|
|
1
|
+
// The second half of an E2B desktop participant's preparation, and the start of its session: speech and
|
|
2
2
|
// recording, then the browser or terminal the participant sees, then the live stream. Each step
|
|
3
|
-
// fills the
|
|
3
|
+
// fills the participant's state.
|
|
4
4
|
import { redactText, toErrorMessage } from "../../../evidence/redaction.js";
|
|
5
5
|
import { CHROME_DEVTOOLS_PORT, DESKTOP_SETTLE_MS, openDesktopBrowserTarget, openDesktopTerminal, startDesktopStream, } from "../../../substrates/e2b/desktop-browser.js";
|
|
6
6
|
import { captureDesktopBrowserGeometry } from "../../../substrates/e2b/desktop-geometry.js";
|
|
7
7
|
import { prepareDesktopMedia, startE2BDesktopMedia, } from "../../../substrates/e2b/desktop-media.js";
|
|
8
8
|
import { startE2BDesktopRecording } from "../../../substrates/e2b/desktop-recording.js";
|
|
9
9
|
import { applyParticipantMobileFidelity, mobileLaunchFlags } from "./fidelity.js";
|
|
10
|
+
import { streamEvent } from "../../../lab/run-lab-homes.js";
|
|
10
11
|
/** Start the declared speech worker and screen recording. A recording that cannot start is a warning. */
|
|
11
12
|
export async function startParticipantMedia(ctx, state, desktop) {
|
|
12
13
|
const { spec, deps, warnings } = ctx;
|
|
13
|
-
const requestedMedia = deps.
|
|
14
|
+
const requestedMedia = deps.residual.execution?.desktop?.media;
|
|
14
15
|
if (!ctx.desktopCliRoute && requestedMedia?.microphone?.source === "speech") {
|
|
15
16
|
state.speech = await startE2BDesktopMedia({
|
|
16
17
|
desktop,
|
|
@@ -20,7 +21,7 @@ export async function startParticipantMedia(ctx, state, desktop) {
|
|
|
20
21
|
requestTimeoutMs: deps.requestTimeoutMs,
|
|
21
22
|
});
|
|
22
23
|
}
|
|
23
|
-
const requestedRecording = deps.
|
|
24
|
+
const requestedRecording = deps.residual.execution?.desktop?.recording;
|
|
24
25
|
if (requestedRecording) {
|
|
25
26
|
try {
|
|
26
27
|
state.recording = await startE2BDesktopRecording({
|
|
@@ -43,28 +44,28 @@ export async function startParticipantMedia(ctx, state, desktop) {
|
|
|
43
44
|
*/
|
|
44
45
|
export async function openParticipantSurface(ctx, state, desktop) {
|
|
45
46
|
const { spec, deps, warnings, targetUrl } = ctx;
|
|
46
|
-
const {
|
|
47
|
-
if (
|
|
47
|
+
const { residual, subject } = deps;
|
|
48
|
+
if (subject.kind === "desktop-cli") {
|
|
48
49
|
// A terminal window, opened the way the browser is opened on every other route: the
|
|
49
50
|
// 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
|
|
51
|
-
await openDesktopTerminal(desktop, deps.requestTimeoutMs,
|
|
51
|
+
// of them. They can still open another from the dock; that is the point of a desktop.
|
|
52
|
+
await openDesktopTerminal(desktop, deps.requestTimeoutMs, subject.product.workdir);
|
|
52
53
|
await desktop.wait(DESKTOP_SETTLE_MS).catch(() => undefined);
|
|
53
54
|
return;
|
|
54
55
|
}
|
|
55
|
-
const requestedMedia =
|
|
56
|
-
// A declared camera
|
|
57
|
-
// uploaded first, and a feed that cannot be produced fails the
|
|
56
|
+
const requestedMedia = residual.execution?.desktop?.media;
|
|
57
|
+
// A declared camera is in place before the browser starts: the feed is generated or
|
|
58
|
+
// uploaded first, and a feed that cannot be produced fails the participant closed here.
|
|
58
59
|
const mediaEvidence = requestedMedia === undefined
|
|
59
60
|
? undefined
|
|
60
|
-
: await prepareDesktopMedia(desktop, requestedMedia,
|
|
61
|
-
const emulationFlags = mobileLaunchFlags(
|
|
62
|
-
const browserLaunch = await openDesktopBrowserTarget(desktop, targetUrl, deps.requestTimeoutMs,
|
|
61
|
+
: await prepareDesktopMedia(desktop, requestedMedia, residual.policies?.mediaPermission ?? "prompt", deps.labCwd, deps.requestTimeoutMs);
|
|
62
|
+
const emulationFlags = mobileLaunchFlags(residual, spec);
|
|
63
|
+
const browserLaunch = await openDesktopBrowserTarget(desktop, targetUrl, deps.requestTimeoutMs, residual.execution?.desktop?.browser, [...emulationFlags, ...(mediaEvidence?.flags ?? [])], state.speech?.env ?? state.recording?.env);
|
|
63
64
|
state.desktopBrowser =
|
|
64
65
|
mediaEvidence === undefined
|
|
65
66
|
? browserLaunch.evidence
|
|
66
67
|
: {
|
|
67
|
-
requested:
|
|
68
|
+
requested: residual.execution?.desktop?.browser ?? "default",
|
|
68
69
|
...browserLaunch.evidence,
|
|
69
70
|
media: mediaEvidence,
|
|
70
71
|
};
|
|
@@ -76,8 +77,8 @@ export async function openParticipantSurface(ctx, state, desktop) {
|
|
|
76
77
|
state.browserLaunched = true;
|
|
77
78
|
noteDevToolsReadiness(ctx, browserLaunch.devTools, emulationFlags.length > 0);
|
|
78
79
|
await desktop.wait(DESKTOP_SETTLE_MS).catch(() => undefined);
|
|
79
|
-
// Mobile fidelity
|
|
80
|
-
// that cannot be applied fails the
|
|
80
|
+
// Mobile fidelity is applied outside startParticipantStream's best-effort catch, so a request
|
|
81
|
+
// that cannot be applied fails the participant closed.
|
|
81
82
|
state.fidelity = await applyParticipantMobileFidelity({
|
|
82
83
|
desktop,
|
|
83
84
|
spec,
|
|
@@ -90,14 +91,14 @@ export async function openParticipantSurface(ctx, state, desktop) {
|
|
|
90
91
|
});
|
|
91
92
|
}
|
|
92
93
|
/**
|
|
93
|
-
* DevTools answering later than this after launch is recorded as a warning on the
|
|
94
|
-
* launches answered in 4.8-7.7 s;
|
|
94
|
+
* DevTools answering later than this after launch is recorded as a warning on the participant. Six live
|
|
95
|
+
* launches answered in 4.8-7.7 s; without this wait the reads it guards give up at about 11 s.
|
|
95
96
|
*/
|
|
96
97
|
const SLOW_DEVTOOLS_MS = 10_000;
|
|
97
98
|
/**
|
|
98
99
|
* Records how Chrome's DevTools port answered after launch, as a timed phase in the bundle. A
|
|
99
|
-
* device-emulated
|
|
100
|
-
* over DevTools. Other
|
|
100
|
+
* device-emulated participant fails closed when the port never answered, because emulation is applied
|
|
101
|
+
* over DevTools. Other participants continue with a warning: their DevTools reads already degrade to
|
|
101
102
|
* warnings of their own.
|
|
102
103
|
*/
|
|
103
104
|
function noteDevToolsReadiness(ctx, devTools, emulated) {
|
|
@@ -132,7 +133,7 @@ function noteDevToolsReadiness(ctx, devTools, emulated) {
|
|
|
132
133
|
}
|
|
133
134
|
/**
|
|
134
135
|
* Measure the browser window and start the live stream. A stream that cannot start is a warning;
|
|
135
|
-
* unusable browser geometry fails the
|
|
136
|
+
* unusable browser geometry fails the participant before any action.
|
|
136
137
|
*/
|
|
137
138
|
export async function startParticipantStream(ctx, state, desktop) {
|
|
138
139
|
const { spec, deps, warnings } = ctx;
|
|
@@ -156,8 +157,8 @@ export async function startParticipantStream(ctx, state, desktop) {
|
|
|
156
157
|
state.browserWindowId = browserGeometry.browserWindowId;
|
|
157
158
|
state.browserTargetId = browserGeometry.browserTargetId;
|
|
158
159
|
}
|
|
159
|
-
// A browser
|
|
160
|
-
// and streams the whole desktop: a person studying a terminal app opens other windows, and
|
|
160
|
+
// A browser participant streams its browser window when one was found. A CLI participant has
|
|
161
|
+
// no window id and streams the whole desktop: a person studying a terminal app opens other windows, and
|
|
161
162
|
// a stream bound to the first one would quietly stop being evidence.
|
|
162
163
|
await startDesktopStream(desktop, state.browserWindowId);
|
|
163
164
|
const candidateStreamUrl = desktop.stream.getUrl({
|
|
@@ -168,13 +169,14 @@ export async function startParticipantStream(ctx, state, desktop) {
|
|
|
168
169
|
});
|
|
169
170
|
if (typeof candidateStreamUrl === "string" && candidateStreamUrl.trim().length > 0) {
|
|
170
171
|
state.streamUrl = candidateStreamUrl;
|
|
171
|
-
await deps.
|
|
172
|
-
|
|
172
|
+
await deps.onStream(streamEvent({
|
|
173
|
+
type: "ready",
|
|
174
|
+
participantId: spec.planned.id,
|
|
173
175
|
sandboxId: desktop.sandboxId,
|
|
174
|
-
|
|
176
|
+
recordId: spec.recordId,
|
|
175
177
|
streamId: spec.streamId,
|
|
176
178
|
url: candidateStreamUrl,
|
|
177
|
-
});
|
|
179
|
+
}));
|
|
178
180
|
}
|
|
179
181
|
else {
|
|
180
182
|
warnings.push("Live desktop stream started but did not return a usable watch URL; Observer will fall back to screenshots.");
|
|
@@ -184,10 +186,10 @@ export async function startParticipantStream(ctx, state, desktop) {
|
|
|
184
186
|
warnings.push(`Live desktop stream unavailable (run continues; evidence still captured): ${redactText(deps.scrubKnownValues(toErrorMessage(error)))}`);
|
|
185
187
|
}
|
|
186
188
|
// This is outside the stream's best-effort catch: unusable geometry is a harness failure,
|
|
187
|
-
// never a participant finding about missing controls. Both
|
|
189
|
+
// never a participant finding about missing controls. Both computer-use and shared-world participants
|
|
188
190
|
// use this route.
|
|
189
191
|
if (state.initialBrowserGeometry?.unusable !== undefined) {
|
|
190
|
-
state.failureCode = "
|
|
192
|
+
state.failureCode = "HUMANISH_COMPUTER_USE_DEVICE_GEOMETRY";
|
|
191
193
|
throw new Error(`${state.failureCode}: ${state.initialBrowserGeometry.unusable} Participant actions were not started.`);
|
|
192
194
|
}
|
|
193
195
|
}
|
|
@@ -12,11 +12,11 @@ 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 { CuaActorLabErrorCode,
|
|
16
|
-
/** What every step of one
|
|
15
|
+
import type { CuaActorLabErrorCode, E2BDesktopDeps, DesktopParticipantRun, SandboxReleaseFact } from "../types.js";
|
|
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;
|
|
19
|
-
readonly deps:
|
|
19
|
+
readonly deps: E2BDesktopDeps;
|
|
20
20
|
readonly warnings: string[];
|
|
21
21
|
readonly targetUrl: string;
|
|
22
22
|
readonly desktopCliRoute: boolean;
|
|
@@ -37,6 +37,7 @@ export interface E2BParticipantState {
|
|
|
37
37
|
sandboxTornDownAtMs: number | undefined;
|
|
38
38
|
desktopResources: DesktopResourceObservation | undefined;
|
|
39
39
|
released: boolean;
|
|
40
|
+
sandboxRelease: SandboxReleaseFact | undefined;
|
|
40
41
|
failureCode: CuaActorLabErrorCode | undefined;
|
|
41
42
|
commsCatch: RunningCommsCatch | undefined;
|
|
42
43
|
commsArtifactPath: string | undefined;
|
|
@@ -61,5 +62,5 @@ export interface E2BParticipantState {
|
|
|
61
62
|
streamUrl: string | undefined;
|
|
62
63
|
}
|
|
63
64
|
export declare function newParticipantState(spec: DesktopParticipantRun): E2BParticipantState;
|
|
64
|
-
/** The
|
|
65
|
+
/** The participant's outcome evidence, read from its state. */
|
|
65
66
|
export declare function desktopEvidenceOf(state: E2BParticipantState): ParticipantDesktopEvidence;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
// What one E2B desktop
|
|
2
|
-
// record in order, and desktopEvidenceOf reads it for the
|
|
1
|
+
// What one E2B desktop participant records as it runs. The prepare, start and teardown steps fill one
|
|
2
|
+
// record in order, and desktopEvidenceOf reads it for the participant's outcome.
|
|
3
3
|
import { declaredScreenForRender, } from "../../../substrates/e2b/desktop-geometry.js";
|
|
4
4
|
export function newParticipantState(spec) {
|
|
5
5
|
const declaredScreen = declaredScreenForRender(spec.planned.device.preset, spec.planned.device.name, spec.planned.device.resolution);
|
|
@@ -11,6 +11,7 @@ export function newParticipantState(spec) {
|
|
|
11
11
|
sandboxTornDownAtMs: undefined,
|
|
12
12
|
desktopResources: undefined,
|
|
13
13
|
released: false,
|
|
14
|
+
sandboxRelease: undefined,
|
|
14
15
|
failureCode: undefined,
|
|
15
16
|
commsCatch: undefined,
|
|
16
17
|
commsArtifactPath: undefined,
|
|
@@ -42,7 +43,7 @@ export function newParticipantState(spec) {
|
|
|
42
43
|
streamUrl: undefined,
|
|
43
44
|
};
|
|
44
45
|
}
|
|
45
|
-
/** The
|
|
46
|
+
/** The participant's outcome evidence, read from its state. */
|
|
46
47
|
export function desktopEvidenceOf(state) {
|
|
47
48
|
// Host-side approximation of the E2B desktop's billed lifetime; feeds the desktop-minute cost
|
|
48
49
|
// estimate. Never negative.
|
|
@@ -54,6 +55,7 @@ export function desktopEvidenceOf(state) {
|
|
|
54
55
|
...(desktopDurationMs === undefined ? {} : { desktopDurationMs }),
|
|
55
56
|
...(state.desktopResources === undefined ? {} : { desktopResources: state.desktopResources }),
|
|
56
57
|
released: state.released,
|
|
58
|
+
...(state.sandboxRelease === undefined ? {} : { sandboxRelease: state.sandboxRelease }),
|
|
57
59
|
streamUrlPresent: state.streamUrl !== undefined,
|
|
58
60
|
...(state.subjectCommit === undefined ? {} : { subjectCommit: state.subjectCommit }),
|
|
59
61
|
...(state.desktopBrowser === undefined ? {} : { desktopBrowser: state.desktopBrowser }),
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { E2BParticipantContext, E2BParticipantState } from "./state.js";
|
|
2
2
|
/**
|
|
3
|
-
* Finish a
|
|
3
|
+
* Finish a participant: collect its final geometry and comms evidence, then stop its media and release
|
|
4
4
|
* its sandbox. Evidence failures are warnings; the release always runs.
|
|
5
5
|
*/
|
|
6
6
|
export declare function finishE2BDesktop(ctx: E2BParticipantContext, state: E2BParticipantState, failed: boolean): Promise<void>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Teardown for one E2B desktop
|
|
1
|
+
// Teardown for one E2B desktop participant: its final geometry and comms evidence are collected, then the
|
|
2
2
|
// recording and speech worker, then the sandbox is released by id (or kept for debugging), with a
|
|
3
3
|
// warning for every outcome that is not a confirmed release.
|
|
4
4
|
import { collectDesktopRecording } from "../../../evidence/desktop-recording-artifact.js";
|
|
@@ -7,15 +7,16 @@ import { readE2BRelease } from "../../../substrates/e2b/sandbox.js";
|
|
|
7
7
|
import { e2bShell } from "../../../substrates/e2b/shell.js";
|
|
8
8
|
import { drainCommsEvidence } from "./comms.js";
|
|
9
9
|
import { finalParticipantGeometry } from "./fidelity.js";
|
|
10
|
+
import { streamEvent } from "../../../lab/run-lab-homes.js";
|
|
10
11
|
/**
|
|
11
|
-
* Each route's own keep flag gates its own
|
|
12
|
-
*
|
|
12
|
+
* Each route's own keep flag gates its own participants only: a clone.keep can never leak into a
|
|
13
|
+
* local-tree participant's teardown decision, and vice versa.
|
|
13
14
|
*/
|
|
14
15
|
function participantKeepReason(deps) {
|
|
15
|
-
const {
|
|
16
|
-
if (
|
|
16
|
+
const { residual, subject } = deps;
|
|
17
|
+
if (subject.kind === "clone" && residual.subject.clone?.keep === true)
|
|
17
18
|
return "subject.clone.keep";
|
|
18
|
-
if (
|
|
19
|
+
if (subject.kind === "local-tree" && residual.subject.localTree?.keep === true)
|
|
19
20
|
return "subject.localTree.keep";
|
|
20
21
|
return undefined;
|
|
21
22
|
}
|
|
@@ -38,17 +39,18 @@ async function stopParticipantMedia(args) {
|
|
|
38
39
|
return evidence;
|
|
39
40
|
}
|
|
40
41
|
/**
|
|
41
|
-
* Release the
|
|
42
|
-
* only when the release is confirmed. A kept or
|
|
43
|
-
* which the warnings say.
|
|
42
|
+
* Release the participant's sandbox, or keep it when a keep flag is set and the participant failed. `released`
|
|
43
|
+
* is true only when the release is confirmed; otherwise `sandboxRelease` says why. A kept or
|
|
44
|
+
* unconfirmed sandbox can still accrue compute cost, which the warnings say.
|
|
44
45
|
*/
|
|
45
46
|
async function releaseParticipantDesktop(args) {
|
|
46
47
|
const { allocation, keepReason, deps, warnings } = args;
|
|
47
48
|
const keepForDebug = keepReason !== undefined && args.failed;
|
|
48
49
|
const released = await allocation.close({ retainForDebug: keepForDebug });
|
|
49
50
|
if (released.status === "retained") {
|
|
50
|
-
|
|
51
|
-
|
|
51
|
+
const warning = `Sandbox ${allocation.resourceId} kept for debugging (${keepReason} on failure); reclaim it via E2B or it will be killed on its server-side timeout.`;
|
|
52
|
+
warnings.push(warning);
|
|
53
|
+
return { released: false, sandboxRelease: { state: "retained", warning } };
|
|
52
54
|
}
|
|
53
55
|
const reading = readE2BRelease(released, {
|
|
54
56
|
label: "Sandbox",
|
|
@@ -57,10 +59,18 @@ async function releaseParticipantDesktop(args) {
|
|
|
57
59
|
});
|
|
58
60
|
if (reading.warning)
|
|
59
61
|
warnings.push(reading.warning);
|
|
60
|
-
|
|
62
|
+
if (reading.released)
|
|
63
|
+
return { released: true };
|
|
64
|
+
return {
|
|
65
|
+
released: false,
|
|
66
|
+
sandboxRelease: {
|
|
67
|
+
state: "unconfirmed",
|
|
68
|
+
warning: reading.warning ?? "Sandbox release is unconfirmed.",
|
|
69
|
+
},
|
|
70
|
+
};
|
|
61
71
|
}
|
|
62
72
|
/**
|
|
63
|
-
* Finish a
|
|
73
|
+
* Finish a participant: collect its final geometry and comms evidence, then stop its media and release
|
|
64
74
|
* its sandbox. Evidence failures are warnings; the release always runs.
|
|
65
75
|
*/
|
|
66
76
|
export async function finishE2BDesktop(ctx, state, failed) {
|
|
@@ -122,27 +132,30 @@ export async function finishE2BDesktop(ctx, state, failed) {
|
|
|
122
132
|
mediaStop: state.mediaStop,
|
|
123
133
|
warnings,
|
|
124
134
|
});
|
|
125
|
-
|
|
135
|
+
const release = await releaseParticipantDesktop({
|
|
126
136
|
allocation,
|
|
127
137
|
keepReason: participantKeepReason(deps),
|
|
128
138
|
failed,
|
|
129
139
|
deps,
|
|
130
140
|
warnings,
|
|
131
141
|
});
|
|
142
|
+
state.released = release.released;
|
|
143
|
+
state.sandboxRelease = release.sandboxRelease;
|
|
132
144
|
// Close the observed span. A kept or unconfirmed sandbox can still accrue compute cost; the
|
|
133
145
|
// summary records that remaining lifetime as unknown instead of calling this complete.
|
|
134
146
|
state.sandboxTornDownAtMs = deps.now();
|
|
135
|
-
// The
|
|
147
|
+
// The participant's live stream is now a dead page whichever teardown path ran (released, kept, or
|
|
136
148
|
// release-failed-awaiting-TTL); tell the watch overlay so the tile falls back to recorded
|
|
137
|
-
// evidence instead of "sandbox not found"
|
|
149
|
+
// evidence instead of "sandbox not found". Guarded: a viewer callback must never
|
|
138
150
|
// break teardown.
|
|
139
151
|
if (state.streamUrl !== undefined) {
|
|
140
152
|
try {
|
|
141
|
-
await deps.
|
|
142
|
-
|
|
143
|
-
|
|
153
|
+
await deps.onStream(streamEvent({
|
|
154
|
+
type: "ended",
|
|
155
|
+
participantId: spec.planned.id,
|
|
156
|
+
recordId: spec.recordId,
|
|
144
157
|
streamId: spec.streamId,
|
|
145
|
-
});
|
|
158
|
+
}));
|
|
146
159
|
}
|
|
147
160
|
catch {
|
|
148
161
|
// viewer-side only; nothing to record
|