humanish 0.106.0 → 0.107.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +4 -2
- package/ARCHITECTURE.md +17 -16
- package/CHANGELOG.md +24 -0
- package/CONTEXT.md +42 -39
- package/CONTRIBUTING.md +8 -6
- package/README.md +8 -3
- 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.js +2 -1
- 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/qualified-versions.d.ts +31 -4
- package/dist/actors/codex/qualified-versions.js +51 -6
- package/dist/actors/codex/restricted-executable.d.ts +24 -0
- package/dist/actors/codex/restricted-executable.js +97 -22
- package/dist/actors/codex/restricted-launch.d.ts +7 -1
- package/dist/actors/codex/restricted-launch.js +42 -3
- 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 +60 -2
- package/dist/actors/codex/restricted-policy.d.ts +9 -1
- package/dist/actors/codex/restricted-session.d.ts +14 -1
- package/dist/actors/codex/restricted-session.js +50 -17
- 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 +1 -1
- package/dist/actors/computer-use/actor.js +4 -4
- package/dist/actors/computer-use/loop/backstop.js +1 -1
- package/dist/actors/computer-use/loop/ending.d.ts +2 -2
- package/dist/actors/computer-use/loop/ending.js +2 -2
- package/dist/actors/computer-use/loop/spend.d.ts +1 -1
- package/dist/actors/computer-use/loop/spend.js +3 -3
- package/dist/actors/computer-use/loop/trace.js +2 -2
- package/dist/actors/computer-use/loop/types.d.ts +14 -5
- package/dist/actors/computer-use/loop.js +4 -4
- package/dist/actors/computer-use/openai-provider.d.ts +1 -1
- package/dist/actors/computer-use/openai-provider.js +2 -2
- package/dist/actors/contract.d.ts +10 -8
- package/dist/actors/contract.js +7 -1
- package/dist/actors/local-agent/cli.js +1 -1
- package/dist/actors/scripted-browser/actor.d.ts +2 -2
- package/dist/actors/scripted-browser/journey.js +15 -4
- package/dist/actors/scripted-browser/steps.js +18 -0
- package/dist/actors/scripted-browser/types.d.ts +11 -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/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 +31 -12
- 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 +4 -2
- package/dist/cli/commands/comms.js +8 -1
- package/dist/cli/commands/lab-route-computer-use.d.ts +0 -2
- package/dist/cli/commands/lab-route-computer-use.js +26 -14
- package/dist/cli/commands/lab-route-preview.d.ts +1 -3
- package/dist/cli/commands/lab-route-preview.js +3 -4
- 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 +0 -1
- 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 +76 -45
- package/dist/cli/commands/lab-scorer.d.ts +0 -2
- package/dist/cli/commands/lab.js +12 -6
- package/dist/cli/commands/observe.js +22 -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 +10 -8
- package/dist/cli/commands/watch.js +12 -10
- package/dist/cli/doctor.d.ts +3 -0
- package/dist/cli/doctor.js +10 -2
- package/dist/cli/io.d.ts +5 -4
- package/dist/cli/io.js +12 -8
- package/dist/cli/program.js +3 -3
- package/dist/cli/renamed-options.d.ts +11 -0
- package/dist/cli/renamed-options.js +18 -0
- package/dist/cli/telemetry.d.ts +2 -2
- package/dist/cli/telemetry.js +1 -1
- package/dist/comms/capture-surface.d.ts +1 -1
- package/dist/comms/catch-host.d.ts +1 -1
- package/dist/comms/connections.js +4 -4
- package/dist/comms/external-evidence.d.ts +27 -0
- package/dist/comms/external-evidence.js +93 -0
- package/dist/comms/lease-store.js +7 -7
- package/dist/comms/types.js +1 -1
- package/dist/evidence/browser-hygiene.d.ts +1 -1
- package/dist/evidence/browser-hygiene.js +1 -1
- package/dist/evidence/redaction.js +1 -1
- package/dist/evidence/secret-scrub.d.ts +9 -0
- package/dist/evidence/secret-scrub.js +96 -0
- package/dist/feedback/draft.js +7 -9
- package/dist/feedback/export-bundle.js +4 -4
- package/dist/feedback/export.js +9 -9
- package/dist/feedback/feedback.d.ts +1 -1
- package/dist/index.d.ts +3 -6
- package/dist/index.js +3 -6
- package/dist/keys/key-resolution.d.ts +3 -1
- package/dist/keys/key-resolution.js +18 -16
- package/dist/lab/adapter-extension.d.ts +28 -6
- package/dist/lab/adapter-extension.js +65 -126
- package/dist/lab/adapter-scorer-loader.d.ts +25 -5
- package/dist/lab/adapter-scorer-loader.js +24 -0
- package/dist/lab/composition-rules.d.ts +2 -0
- package/dist/lab/composition-rules.js +35 -26
- package/dist/lab/config.js +28 -26
- package/dist/lab/device-presets.d.ts +2 -2
- package/dist/lab/discover.js +1 -3
- package/dist/lab/doctor.d.ts +44 -9
- package/dist/lab/doctor.js +149 -41
- package/dist/lab/init-plan.js +1 -3
- package/dist/lab/keys.js +1 -1
- package/dist/lab/lab-deps.d.ts +85 -0
- package/dist/lab/lab-deps.js +4 -0
- package/dist/lab/parse/actors.js +8 -7
- package/dist/lab/parse/comms.js +3 -2
- package/dist/lab/parse/execution.js +3 -2
- package/dist/lab/parse/subject-state.js +2 -1
- package/dist/lab/parse/subject.js +2 -1
- package/dist/lab/parse/values.d.ts +0 -1
- package/dist/lab/parse/values.js +0 -3
- package/dist/lab/persona-resolve.d.ts +3 -3
- package/dist/lab/persona-resolve.js +4 -4
- package/dist/lab/persona.js +1 -3
- package/dist/lab/plan-base.d.ts +6 -2
- package/dist/lab/plan-base.js +22 -7
- package/dist/lab/plan-participants.d.ts +5 -5
- package/dist/lab/plan-participants.js +2 -2
- package/dist/lab/plan-types.d.ts +33 -7
- package/dist/lab/plan.d.ts +3 -11
- package/dist/lab/plan.js +18 -42
- package/dist/lab/preflight-result.js +0 -2
- package/dist/lab/preflight.d.ts +0 -3
- package/dist/lab/preflight.js +1 -1
- 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 +19 -24
- package/dist/lab/routing.js +14 -47
- package/dist/lab/run-lab-events.d.ts +6 -11
- package/dist/lab/run-lab-events.js +3 -11
- package/dist/lab/run-lab-homes.d.ts +64 -0
- package/dist/lab/run-lab-homes.js +3 -0
- package/dist/lab/run-lab-options.d.ts +12 -66
- package/dist/lab/run-lab-options.js +45 -275
- package/dist/lab/summary.d.ts +9 -4
- package/dist/lab/summary.js +15 -8
- package/dist/lab/types.d.ts +132 -132
- package/dist/lab/validation.d.ts +15 -15
- package/dist/lab/validation.js +28 -28
- package/dist/lab/warnings.js +20 -19
- package/dist/observer/artifact.d.ts +1 -1
- package/dist/observer/artifact.js +3 -3
- package/dist/observer/data.js +2 -2
- package/dist/observer/render.js +2 -2
- package/dist/observer/run-routes.d.ts +1 -1
- package/dist/observer/run-routes.js +5 -5
- package/dist/observer/serve.d.ts +17 -0
- package/dist/observer/serve.js +34 -3
- package/dist/observer-app.html +1 -1
- package/dist/routes/computer-use/bundle-parts.d.ts +1 -1
- package/dist/routes/computer-use/bundle-parts.js +10 -3
- package/dist/routes/computer-use/bundle.d.ts +4 -11
- package/dist/routes/computer-use/bundle.js +9 -15
- 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 +10 -10
- package/dist/routes/computer-use/e2b-desktop/comms.js +11 -14
- package/dist/routes/computer-use/e2b-desktop/desktop.d.ts +2 -2
- package/dist/routes/computer-use/e2b-desktop/desktop.js +4 -7
- package/dist/routes/computer-use/e2b-desktop/fidelity.d.ts +13 -13
- package/dist/routes/computer-use/e2b-desktop/fidelity.js +11 -11
- package/dist/routes/computer-use/e2b-desktop/prepare.d.ts +3 -3
- package/dist/routes/computer-use/e2b-desktop/prepare.js +33 -36
- package/dist/routes/computer-use/e2b-desktop/start.d.ts +1 -1
- package/dist/routes/computer-use/e2b-desktop/start.js +24 -23
- 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 +29 -17
- 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 +25 -29
- package/dist/routes/computer-use/{fanout-lanes.js → fanout-records.js} +25 -19
- 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 +19 -27
- package/dist/routes/computer-use/{run-lanes.js → live-phase.js} +14 -13
- 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 +39 -66
- 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} +10 -10
- package/dist/routes/computer-use/{lanes.js → participant-execution.js} +35 -22
- 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 +19 -11
- package/dist/routes/computer-use/participant-model.js +58 -33
- package/dist/routes/computer-use/participant-prompt.d.ts +3 -3
- package/dist/routes/computer-use/participant-prompt.js +4 -4
- package/dist/routes/computer-use/participant-runs.d.ts +6 -6
- package/dist/routes/computer-use/participant-runs.js +8 -8
- package/dist/routes/computer-use/plan.d.ts +21 -29
- package/dist/routes/computer-use/plan.js +59 -65
- package/dist/routes/computer-use/preflight.d.ts +6 -11
- package/dist/routes/computer-use/preflight.js +26 -18
- package/dist/routes/computer-use/rerun-selection.js +10 -6
- package/dist/routes/computer-use/result.d.ts +1 -1
- package/dist/routes/computer-use/result.js +40 -30
- package/dist/routes/computer-use/route.d.ts +3 -4
- package/dist/routes/computer-use/route.js +21 -19
- package/dist/routes/computer-use/self-report.d.ts +2 -2
- package/dist/routes/computer-use/self-report.js +4 -4
- package/dist/routes/computer-use/setup.d.ts +8 -17
- package/dist/routes/computer-use/setup.js +98 -86
- package/dist/routes/computer-use/single-bundle.d.ts +8 -11
- package/dist/routes/computer-use/single-bundle.js +20 -25
- package/dist/routes/computer-use/subject-projection.d.ts +5 -7
- package/dist/routes/computer-use/subject-projection.js +20 -19
- package/dist/routes/computer-use/types.d.ts +169 -211
- package/dist/routes/computer-use/types.js +13 -6
- package/dist/routes/preview.js +0 -1
- package/dist/routes/scripted/bundle.d.ts +3 -6
- package/dist/routes/scripted/bundle.js +11 -16
- package/dist/routes/scripted/plan.d.ts +5 -7
- package/dist/routes/scripted/plan.js +6 -4
- package/dist/routes/scripted/result.d.ts +4 -1
- package/dist/routes/scripted/result.js +10 -6
- package/dist/routes/scripted/route.js +10 -11
- package/dist/routes/scripted/scenario.d.ts +1 -1
- package/dist/routes/scripted/scenario.js +1 -1
- package/dist/routes/scripted/setup.d.ts +3 -2
- package/dist/routes/scripted/setup.js +22 -21
- package/dist/routes/scripted/subject.d.ts +8 -3
- package/dist/routes/scripted/subject.js +11 -6
- package/dist/routes/scripted/surface-records.js +1 -1
- 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 +19 -36
- package/dist/routes/scripted/types.js +1 -2
- package/dist/routes/shared-world/{seat-records.js → bundle-records.js} +8 -8
- package/dist/routes/shared-world/bundle.d.ts +2 -2
- package/dist/routes/shared-world/bundle.js +22 -26
- package/dist/routes/shared-world/checkpoints.d.ts +4 -4
- package/dist/routes/shared-world/checkpoints.js +4 -4
- package/dist/routes/shared-world/comms.d.ts +5 -4
- package/dist/routes/shared-world/comms.js +28 -41
- package/dist/routes/shared-world/external-public.d.ts +5 -5
- package/dist/routes/shared-world/external-public.js +19 -20
- package/dist/routes/shared-world/handoff.d.ts +4 -4
- package/dist/routes/shared-world/handoff.js +50 -50
- package/dist/routes/shared-world/lobby-code.d.ts +5 -5
- package/dist/routes/shared-world/lobby-code.js +13 -13
- package/dist/routes/shared-world/{seats.d.ts → participant-specs.d.ts} +8 -6
- package/dist/routes/shared-world/{seats.js → participant-specs.js} +46 -51
- package/dist/routes/shared-world/plan.d.ts +2 -6
- package/dist/routes/shared-world/plan.js +1 -2
- 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 +48 -41
- package/dist/routes/shared-world/result.js +31 -19
- package/dist/routes/shared-world/route.js +37 -41
- package/dist/routes/shared-world/setup.d.ts +5 -4
- package/dist/routes/shared-world/setup.js +12 -14
- package/dist/routes/shared-world/types.d.ts +53 -126
- package/dist/routes/shared-world/types.js +2 -2
- package/dist/routes/terminal/adapter.d.ts +8 -8
- package/dist/routes/terminal/adapter.js +28 -125
- package/dist/routes/terminal/bundle.d.ts +7 -12
- package/dist/routes/terminal/bundle.js +24 -34
- package/dist/routes/terminal/credentials.d.ts +2 -2
- package/dist/routes/terminal/credentials.js +16 -16
- package/dist/routes/terminal/dry-run.d.ts +1 -1
- package/dist/routes/terminal/dry-run.js +9 -11
- package/dist/routes/terminal/encoding.d.ts +1 -1
- package/dist/routes/terminal/encoding.js +2 -2
- package/dist/routes/terminal/ledger.d.ts +6 -6
- package/dist/routes/terminal/ledger.js +9 -9
- package/dist/routes/terminal/live-finish.d.ts +1 -2
- package/dist/routes/terminal/live-finish.js +21 -20
- package/dist/routes/terminal/live-sandbox.d.ts +4 -2
- package/dist/routes/terminal/live-sandbox.js +25 -21
- package/dist/routes/terminal/participant-text.d.ts +23 -0
- package/dist/routes/terminal/participant-text.js +165 -0
- package/dist/routes/terminal/plan.d.ts +2 -6
- package/dist/routes/terminal/plan.js +13 -9
- package/dist/routes/terminal/recorder.d.ts +6 -1
- package/dist/routes/terminal/recorder.js +12 -4
- package/dist/routes/terminal/result.js +4 -4
- package/dist/routes/terminal/route.js +26 -26
- package/dist/routes/terminal/runtime.d.ts +3 -2
- package/dist/routes/terminal/runtime.js +3 -3
- package/dist/routes/terminal/sandbox.d.ts +5 -3
- package/dist/routes/terminal/sandbox.js +13 -16
- package/dist/routes/terminal/session.js +16 -14
- package/dist/routes/terminal/token-usage.js +5 -5
- package/dist/routes/terminal/trace.d.ts +5 -8
- package/dist/routes/terminal/trace.js +9 -64
- package/dist/routes/terminal/types.d.ts +85 -93
- package/dist/routes/terminal/types.js +9 -4
- 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 +4 -4
- package/dist/run/bundle.d.ts +63 -56
- package/dist/run/bundle.js +9 -8
- package/dist/run/cost-summary.js +3 -2
- package/dist/run/costs.d.ts +6 -6
- package/dist/run/costs.js +10 -10
- package/dist/run/detail.d.ts +5 -5
- package/dist/run/detail.js +6 -6
- package/dist/run/dry-run.js +5 -12
- 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 +16 -4
- package/dist/run/judge.js +24 -7
- 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.js +1 -1
- package/dist/run/pricing.d.ts +19 -9
- package/dist/run/pricing.js +30 -18
- package/dist/run/projection.d.ts +13 -13
- package/dist/run/projection.js +8 -8
- package/dist/run/reclaim.d.ts +7 -1
- package/dist/run/reclaim.js +24 -4
- package/dist/run/results.d.ts +1 -1
- package/dist/run/run-index.d.ts +1 -1
- package/dist/run/run-index.js +11 -11
- package/dist/run/run.d.ts +4 -2
- package/dist/run/run.js +9 -5
- package/dist/run/sandbox-receipts.d.ts +4 -4
- package/dist/run/sandbox-receipts.js +4 -4
- package/dist/run/shared-world-evidence.d.ts +47 -47
- package/dist/run/shared-world-shape.d.ts +3 -3
- package/dist/run/shared-world-shape.js +11 -11
- package/dist/run/stats.d.ts +5 -5
- package/dist/run/stats.js +8 -8
- package/dist/run/status.d.ts +16 -6
- package/dist/run/status.js +31 -8
- package/dist/run/streams.d.ts +26 -19
- package/dist/run/terminal-contract.d.ts +5 -5
- package/dist/run/terminal-contract.js +4 -4
- 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 +36 -34
- package/dist/run-lab.js +41 -37
- package/dist/subject/desktop-cli.d.ts +1 -1
- package/dist/subject/desktop-cli.js +1 -1
- package/dist/subject/local-tree-archive.d.ts +1 -1
- package/dist/subject/local-tree-archive.js +4 -4
- package/dist/subject/local-tree.d.ts +2 -2
- 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 +5 -5
- package/dist/subject/serve.js +1 -1
- package/dist/subject/steps.d.ts +4 -4
- package/dist/subject/steps.js +5 -5
- package/dist/substrates/desktop-session.d.ts +2 -0
- package/dist/substrates/e2b/cdp-probe.d.ts +2 -2
- package/dist/substrates/e2b/cdp-probe.js +1 -1
- package/dist/substrates/e2b/desktop-browser.d.ts +3 -3
- package/dist/substrates/e2b/desktop-browser.js +4 -4
- package/dist/substrates/e2b/desktop-cdp.d.ts +7 -7
- package/dist/substrates/e2b/desktop-cdp.js +4 -4
- package/dist/substrates/e2b/desktop-geometry.d.ts +4 -4
- package/dist/substrates/e2b/desktop-geometry.js +3 -3
- package/dist/substrates/e2b/desktop-media.js +2 -2
- package/dist/substrates/e2b/sandbox.d.ts +2 -0
- package/dist/substrates/e2b/sandbox.js +22 -8
- package/dist/substrates/e2b/sdk.d.ts +12 -1
- package/dist/substrates/e2b/sdk.js +30 -9
- 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 +7 -5
- package/dist/tui/actions.js +18 -9
- package/dist/tui-app.js +42 -42
- package/dist/verify/actor.d.ts +10 -10
- package/dist/verify/actor.js +15 -15
- package/dist/verify/artifacts.d.ts +1 -1
- package/dist/verify/artifacts.js +3 -3
- package/dist/verify/costs.d.ts +2 -2
- package/dist/verify/costs.js +2 -2
- 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.js +2 -2
- package/dist/verify/verify.js +6 -6
- package/docs/README.md +1 -1
- package/docs/architecture/actor-contract.md +60 -22
- package/docs/architecture/desktop-sessions.md +9 -9
- package/docs/architecture/external-public-shared-world.md +5 -0
- package/docs/architecture/observer.md +4 -4
- package/docs/architecture/restricted-codex-analysis.md +40 -4
- package/docs/architecture/state-driven-executor.md +4 -5
- package/docs/architecture/task-protocol-support.md +3 -5
- package/docs/architecture/{terminal-product-lane.md → terminal-product-route.md} +24 -16
- package/docs/contracts/run-bundle.md +10 -8
- package/docs/contracts/schemas.md +109 -53
- package/docs/contracts/study-analysis.md +24 -0
- package/docs/decisions/0004-participant-desktops-stay-in-the-route.md +2 -1
- package/docs/product/automatic-analysis.md +1 -0
- package/docs/ramp/README.md +2 -1
- package/package.json +4 -4
- package/skills/humanish/SKILL.md +3 -2
- package/skills/humanish/agents/openai.yaml +1 -1
- 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/routes/computer-use/legacy-lane-spec.d.ts +0 -62
- package/dist/routes/computer-use/legacy-lane-spec.js +0 -39
- /package/dist/routes/computer-use/{fanout-lanes.d.ts → fanout-records.d.ts} +0 -0
- /package/dist/routes/computer-use/{run-lanes.d.ts → live-phase.d.ts} +0 -0
- /package/dist/routes/shared-world/{seat-records.d.ts → bundle-records.d.ts} +0 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// Builds each participant's actor spec and mission, resolves its entry URL, derives the session
|
|
2
2
|
// and sandbox time budgets, and records a follower that never received the host's lobby code.
|
|
3
|
-
import {
|
|
3
|
+
import { defaultSubjectPhaseSink } from "../../subject/steps.js";
|
|
4
|
+
import { pricedModel } from "../../lab/plan-base.js";
|
|
4
5
|
import { scrubPersonaBrief } from "../../lab/persona.js";
|
|
5
6
|
import { resolveParticipant } from "../../run/participant.js";
|
|
6
7
|
import { attachObserverRuntimeStreamUrls } from "../../observer/render.js";
|
|
@@ -11,11 +12,11 @@ import { participantAssignment } from "../../lab/participant-assignment.js";
|
|
|
11
12
|
import { redactText } from "../../evidence/redaction.js";
|
|
12
13
|
import { MAX_SANDBOX_MS, SANDBOX_TIMEOUT_BUFFER_MS, SUBJECT_PROVISION_BUDGET_MS, } from "../../substrates/e2b/lifetime.js";
|
|
13
14
|
import { DEFAULT_STATE_STEP_TIMEOUT_MS } from "../../subject/state.js";
|
|
14
|
-
// The
|
|
15
|
-
// constraint is the
|
|
15
|
+
// The default per-seat session budget is derived from the route. On a provisioned route the binding
|
|
16
|
+
// constraint is the subject sandbox (it must outlive every seat: timeoutMs + provisioning +
|
|
16
17
|
// seeding + teardown buffer, and E2B refuses a sandbox over one hour), so the derivation hands
|
|
17
18
|
// each seat the most that cap allows — capped at 15 minutes, floored at the historical 300s so a
|
|
18
|
-
// seed-heavy lab never gets
|
|
19
|
+
// seed-heavy lab never gets less room than it always had. App-url seats have no subject sandbox
|
|
19
20
|
// and default to 30 minutes (seat sandbox: 30m + 10m buffer stays well under the hour). An
|
|
20
21
|
// explicit execution.timeoutMs is never adjusted. The handoff latch scales off this (40%).
|
|
21
22
|
const MAX_DERIVED_SESSION_MS = 15 * 60_000;
|
|
@@ -74,9 +75,9 @@ function buildActorSpec(participant, personas) {
|
|
|
74
75
|
traceArtifactPath: `actors/${run.streamId}.json`,
|
|
75
76
|
};
|
|
76
77
|
}
|
|
77
|
-
/** Thread the host-yielded lobby
|
|
78
|
-
* The
|
|
79
|
-
* the model reads (never a raw bundle field), and the lab scrubs the
|
|
78
|
+
/** Thread the host-yielded lobby code into a follower's mission at runtime (external-public route).
|
|
79
|
+
* The code flows into the follower's join instruction; it is persisted only as the composed prompt
|
|
80
|
+
* the model reads (never a raw bundle field), and the lab scrubs the code from all narration. The
|
|
80
81
|
* follower joins through the real UI (a direct /lobby/CODE visit does not auto-join a non-member). */
|
|
81
82
|
export function withLobbyCodeMission(spec, code) {
|
|
82
83
|
return {
|
|
@@ -111,58 +112,46 @@ export function startParticipantFlush(ctx, live, bundle) {
|
|
|
111
112
|
live.flush = startLiveTraceFlush({
|
|
112
113
|
bundle,
|
|
113
114
|
participantRuns: ctx.actorSpecs,
|
|
114
|
-
model: ctx.
|
|
115
|
+
model: pricedModel(ctx.plan.brain),
|
|
115
116
|
write: (snapshot) => ctx.run.writeSnapshot(snapshot),
|
|
116
117
|
});
|
|
117
118
|
}
|
|
118
119
|
/**
|
|
119
|
-
* The
|
|
120
|
-
*
|
|
120
|
+
* The runtime stream URLs each seat reports to the live Observer. The Observer learns of a stream
|
|
121
|
+
* before the caller's onStream runs.
|
|
121
122
|
*/
|
|
122
|
-
function
|
|
123
|
-
return {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
}
|
|
131
|
-
: {}),
|
|
132
|
-
onRuntimeStreamReady: (stream) => {
|
|
133
|
-
live.streamUrls.push({ streamId: stream.streamId, url: stream.url });
|
|
134
|
-
if (live.observer) {
|
|
135
|
-
attachObserverRuntimeStreamUrls(live.observer, live.streamUrls);
|
|
136
|
-
}
|
|
137
|
-
return hooks.onRuntimeStreamReady?.(stream);
|
|
138
|
-
},
|
|
139
|
-
onRuntimeStreamEnded: (stream) => {
|
|
140
|
-
// Mark, never remove (#357): the tile falls back to recorded evidence and says why.
|
|
141
|
-
for (const entry of live.streamUrls) {
|
|
142
|
-
if (entry.streamId === stream.streamId)
|
|
123
|
+
function participantStreams(onStream, live) {
|
|
124
|
+
return (event) => {
|
|
125
|
+
if (event.type === "ready")
|
|
126
|
+
live.streamUrls.push({ streamId: event.streamId, url: event.url });
|
|
127
|
+
// Mark, never remove (#357): the tile falls back to recorded evidence and says why.
|
|
128
|
+
else
|
|
129
|
+
for (const entry of live.streamUrls)
|
|
130
|
+
if (entry.streamId === event.streamId)
|
|
143
131
|
entry.ended = true;
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
}
|
|
148
|
-
return hooks.onRuntimeStreamEnded?.(stream);
|
|
149
|
-
},
|
|
132
|
+
if (live.observer)
|
|
133
|
+
attachObserverRuntimeStreamUrls(live.observer, live.streamUrls);
|
|
134
|
+
return onStream?.(event);
|
|
150
135
|
};
|
|
151
136
|
}
|
|
152
137
|
/**
|
|
153
|
-
* The runner deps both planes give every participant.
|
|
154
|
-
*
|
|
155
|
-
*
|
|
138
|
+
* The runner deps both planes give every participant. The `shared-app` subject keeps three things
|
|
139
|
+
* out of every actor sandbox: the subject env names' values, the GitHub token, and clone
|
|
140
|
+
* or local-tree provisioning. The committed subject.envValues still reach it, non-secret by parse.
|
|
141
|
+
* `scrubKnownValues` is the plane's scrub: the external-public plane also scrubs the latched lobby
|
|
142
|
+
* code.
|
|
156
143
|
*/
|
|
157
144
|
export function participantRunDeps(ctx, live, scrubKnownValues) {
|
|
158
|
-
const { config,
|
|
145
|
+
const { config, env, receiving, runBudget } = ctx;
|
|
159
146
|
return {
|
|
160
147
|
onTrace: (participantId, items, usage, metadata) => live.flush?.flush(participantId, items, usage, metadata),
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
148
|
+
residual: ctx.plan.residual,
|
|
149
|
+
labId: ctx.plan.labId,
|
|
150
|
+
caps: ctx.plan.caps,
|
|
151
|
+
subject: {
|
|
152
|
+
kind: "shared-app",
|
|
153
|
+
...(config.subject.serve?.url === undefined ? {} : { serveUrl: config.subject.serve.url }),
|
|
154
|
+
},
|
|
166
155
|
env,
|
|
167
156
|
openaiApiKey: ctx.openaiApiKey,
|
|
168
157
|
e2bApiKey: ctx.e2bApiKey,
|
|
@@ -176,15 +165,21 @@ export function participantRunDeps(ctx, live, scrubKnownValues) {
|
|
|
176
165
|
scrubKnownValues,
|
|
177
166
|
runSession: ctx.runSession,
|
|
178
167
|
// A local-agent brain runs each seat on the operator's signed-in agent, as on computer use.
|
|
179
|
-
|
|
168
|
+
brain: ctx.plan.brain,
|
|
180
169
|
...(receiving ? { receiving } : {}),
|
|
181
170
|
now: ctx.now,
|
|
182
|
-
|
|
171
|
+
// The seat's desktop seams, and the caller's prepareDesktop with the seat as its target.
|
|
172
|
+
...(ctx.deps.desktopModule === undefined ? {} : { desktopModule: ctx.deps.desktopModule }),
|
|
173
|
+
...(ctx.deps.detachedTimers === undefined ? {} : { detachedTimers: ctx.deps.detachedTimers }),
|
|
174
|
+
...(ctx.input.prepareDesktop === undefined ? {} : { prepareDesktop: ctx.input.prepareDesktop }),
|
|
175
|
+
onStream: participantStreams(ctx.input.onStream, live),
|
|
176
|
+
// A seat visits the shared app and provisions no subject, so it reports no phase of its own.
|
|
177
|
+
reportSubjectPhase: defaultSubjectPhaseSink,
|
|
183
178
|
...(runBudget === undefined ? {} : { runBudget }),
|
|
184
|
-
// Concurrent
|
|
185
|
-
// mismatch is recorded as separate facts + a warning instead of failing the
|
|
179
|
+
// Concurrent participants are independent evidence seats: a requested-vs-verified screen
|
|
180
|
+
// mismatch is recorded as separate facts + a warning instead of failing the participant's
|
|
186
181
|
// device claim closed, so one seat's window-manager drift cannot abort the whole
|
|
187
|
-
// live multi-actor world (the single-
|
|
182
|
+
// live multi-actor world (the single-participant/fan-out routes keep fail-closed).
|
|
188
183
|
screenMismatchPolicy: "record-evidence",
|
|
189
184
|
};
|
|
190
185
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { type CuaActorDescriptor } from "../../actors/registry.js";
|
|
2
2
|
import type { RoutePlanResult, RouteRefusal, SharedWorldPlan } from "../../lab/plan-types.js";
|
|
3
3
|
import type { LabConfig, LabSubjectState } from "../../lab/types.js";
|
|
4
|
-
import type { RunLabProvenance } from "../../run/status.js";
|
|
5
4
|
import type { ConcurrentSharedWorldLabErrorCode } from "./types.js";
|
|
6
5
|
/** The error a shared-world lab returns before a run starts. */
|
|
7
6
|
export interface SharedWorldRefusal extends RouteRefusal<"shared-world", ConcurrentSharedWorldLabErrorCode> {
|
|
@@ -17,11 +16,8 @@ export declare function sharedWorldDescriptorOf(actorType: string): CuaActorDesc
|
|
|
17
16
|
*/
|
|
18
17
|
export declare function planSharedWorldLab(config: LabConfig, input: {
|
|
19
18
|
readonly dryRun: boolean;
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
readonly hooks?: {
|
|
23
|
-
readonly runSession?: unknown;
|
|
24
|
-
};
|
|
19
|
+
/** Whether deps.runSession is set: a caller's session runner cannot enforce maxOutputTokens. */
|
|
20
|
+
readonly hasRunSession?: boolean;
|
|
25
21
|
}): SharedWorldPlanResult;
|
|
26
22
|
/** The provisioned plane's declared subject state. The external-public plane declares none. */
|
|
27
23
|
export declare function planeStateOf(plan: SharedWorldPlan): LabSubjectState | undefined;
|
|
@@ -55,7 +55,7 @@ export function planSharedWorldLab(config, input) {
|
|
|
55
55
|
: concurrentSharedWorldValidationReason(config));
|
|
56
56
|
if (invalidReason)
|
|
57
57
|
return refuse(invalid, invalidReason, actor);
|
|
58
|
-
if (config.actors[0]?.maxOutputTokens !== undefined && input.
|
|
58
|
+
if (config.actors[0]?.maxOutputTokens !== undefined && input.hasRunSession === true)
|
|
59
59
|
return refuse(invalid, "maxOutputTokens cannot be enforced by a custom runSession.", actor);
|
|
60
60
|
const caps = config.execution?.caps;
|
|
61
61
|
if (!input.dryRun && (caps?.maxUsd !== undefined || caps?.maxTotalUsd !== undefined)) {
|
|
@@ -88,7 +88,6 @@ export function planSharedWorldLab(config, input) {
|
|
|
88
88
|
throw new Error("a shared-world participant has no caller brain");
|
|
89
89
|
const base = planBase(config, {
|
|
90
90
|
dryRun: input.dryRun,
|
|
91
|
-
...(input.lab === undefined ? {} : { lab: input.lab }),
|
|
92
91
|
analysis,
|
|
93
92
|
});
|
|
94
93
|
return {
|
|
@@ -2,18 +2,18 @@ import type { RunSubjectProvenance } from "../../run/bundle.js";
|
|
|
2
2
|
import type { LocalTreeArchive } from "../../subject/local-tree-archive.js";
|
|
3
3
|
/** Extract the in-sandbox port from the (loopback) serve.url so getHost can expose it. */
|
|
4
4
|
export declare function servePort(serveUrl: string): number;
|
|
5
|
-
/** A getHost URL must be
|
|
5
|
+
/** A getHost URL must be tokenless (no userinfo and no query, so no authKey; invariant 1). */
|
|
6
6
|
export declare function isTokenlessHost(value: string): boolean;
|
|
7
|
-
/** sha256-16 of a URL's
|
|
7
|
+
/** sha256-16 of a URL's origin: the publish-safe host identity persisted in the bundle (the raw
|
|
8
8
|
* getHost URL embeds the live sandbox id + matches the e2b-URL redaction, so it never lands raw). */
|
|
9
9
|
export declare function hostOriginDigest(url: string): string;
|
|
10
10
|
/** A public-safe, human-readable route label for the bundle (host redacted to a placeholder; the
|
|
11
11
|
* entry path kept). Never contains the raw getHost URL. */
|
|
12
12
|
export declare function publicSafeRouteLabel(entry: string | undefined): string;
|
|
13
13
|
/**
|
|
14
|
-
* Build the
|
|
14
|
+
* Build the one subject sandbox's provenance (invariant 5): clone (repo + optional commit) or
|
|
15
15
|
* local-tree (archiveSha256 + optional commit/dirty from the once-per-run host-packed archive -
|
|
16
|
-
* archiveSha256
|
|
16
|
+
* archiveSha256 is the pin; there is only one archive, so no per-participant unanimity math applies,
|
|
17
17
|
* unlike the cua fan-out route). Used for both the in-progress and final bundle: the archive
|
|
18
18
|
* never changes mid-run (packed before any sandbox exists).
|
|
19
19
|
*/
|
|
@@ -8,7 +8,7 @@ export function servePort(serveUrl) {
|
|
|
8
8
|
return Number(url.port);
|
|
9
9
|
return url.protocol === "https:" ? 443 : 80;
|
|
10
10
|
}
|
|
11
|
-
/** A getHost URL must be
|
|
11
|
+
/** A getHost URL must be tokenless (no userinfo and no query, so no authKey; invariant 1). */
|
|
12
12
|
export function isTokenlessHost(value) {
|
|
13
13
|
try {
|
|
14
14
|
const url = new URL(value);
|
|
@@ -18,7 +18,7 @@ export function isTokenlessHost(value) {
|
|
|
18
18
|
return false;
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
|
-
/** sha256-16 of a URL's
|
|
21
|
+
/** sha256-16 of a URL's origin: the publish-safe host identity persisted in the bundle (the raw
|
|
22
22
|
* getHost URL embeds the live sandbox id + matches the e2b-URL redaction, so it never lands raw). */
|
|
23
23
|
export function hostOriginDigest(url) {
|
|
24
24
|
try {
|
|
@@ -34,9 +34,9 @@ export function publicSafeRouteLabel(entry) {
|
|
|
34
34
|
return `[provisioned-subject]${entry ?? "/"}`;
|
|
35
35
|
}
|
|
36
36
|
/**
|
|
37
|
-
* Build the
|
|
37
|
+
* Build the one subject sandbox's provenance (invariant 5): clone (repo + optional commit) or
|
|
38
38
|
* local-tree (archiveSha256 + optional commit/dirty from the once-per-run host-packed archive -
|
|
39
|
-
* archiveSha256
|
|
39
|
+
* archiveSha256 is the pin; there is only one archive, so no per-participant unanimity math applies,
|
|
40
40
|
* unlike the cua fan-out route). Used for both the in-progress and final bundle: the archive
|
|
41
41
|
* never changes mid-run (packed before any sandbox exists).
|
|
42
42
|
*/
|
|
@@ -3,7 +3,7 @@ import type { RunSubjectStateStepRecord } from "../../run/bundle.js";
|
|
|
3
3
|
import type { SharedWorldStateSnapshot } from "../../run/shared-world-evidence.js";
|
|
4
4
|
import type { LocalTreeArchive } from "../../subject/local-tree-archive.js";
|
|
5
5
|
import type { DetachedTimers } from "../../substrates/detached.js";
|
|
6
|
-
import type {
|
|
6
|
+
import type { LabDeps } from "../../lab/lab-deps.js";
|
|
7
7
|
import { type ActorRunResult, type SubjectDesktopUsage, type LiveParticipants, type PlaneContext } from "./types.js";
|
|
8
8
|
/** What the provisioned plane needs besides the shared plane context. */
|
|
9
9
|
export interface ProvisionedPlaneSetup {
|
|
@@ -35,6 +35,7 @@ export interface ProvisionedPlaneOutcome {
|
|
|
35
35
|
subjectCommit: string | undefined;
|
|
36
36
|
subjectSandboxId: string | undefined;
|
|
37
37
|
subjectKilled: boolean;
|
|
38
|
+
subjectReleaseWarning: string | undefined;
|
|
38
39
|
subjectDesktop: SubjectDesktopUsage | undefined;
|
|
39
40
|
getHostUrl: string | undefined;
|
|
40
41
|
/** Set when the teardown drain wrote a comms thread. */
|
|
@@ -47,7 +48,7 @@ export declare function runProvisionedPlane(ctx: PlaneContext, live: LivePartici
|
|
|
47
48
|
*/
|
|
48
49
|
export declare function packSubjectTree(cwd: string, config: {
|
|
49
50
|
readonly subject: Pick<LabConfig["subject"], "localTree">;
|
|
50
|
-
},
|
|
51
|
+
}, deps: LabDeps, scrubKnownValues: (text: string) => string): Promise<{
|
|
51
52
|
ok: true;
|
|
52
53
|
archive: LocalTreeArchive;
|
|
53
54
|
buffer: ArrayBuffer;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// The
|
|
1
|
+
// The provisioned-getHost plane: the harness provisions one subject sandbox (clone or local-tree,
|
|
2
2
|
// install/build, seed, serve on 0.0.0.0), exposes it through getHost, probes its state on a
|
|
3
3
|
// cadence, and runs every seat against that one shared plane. All sandboxes are torn down by exact
|
|
4
4
|
// id in the plane's finally, never through Sandbox.list.
|
|
@@ -10,6 +10,7 @@ import { mapWithConcurrency } from "../../run/concurrency.js";
|
|
|
10
10
|
import { provisionCloneSubject } from "../../subject/clone.js";
|
|
11
11
|
import { provisionLocalTreeSubject } from "../../subject/local-tree.js";
|
|
12
12
|
import { defaultSharedWorldPhaseSink } from "../../subject/steps.js";
|
|
13
|
+
import { phaseEvent } from "../../lab/run-lab-events.js";
|
|
13
14
|
import { loadE2BDesktopModule } from "../../substrates/e2b/sdk.js";
|
|
14
15
|
import { observeDesktopResources, } from "../../substrates/e2b/desktop-resources.js";
|
|
15
16
|
import { acquireE2BDesktopSandbox, readE2BRelease } from "../../substrates/e2b/sandbox.js";
|
|
@@ -19,14 +20,14 @@ import { inboxRecipientFor, participantHasInboxRecipient, } from "../computer-us
|
|
|
19
20
|
import { resolveSubjectState } from "../computer-use/subject-projection.js";
|
|
20
21
|
import { withInboxMission } from "../computer-use/participant-prompt.js";
|
|
21
22
|
import { planeStateOf } from "./plan.js";
|
|
22
|
-
import { runCuaParticipant } from "../computer-use/
|
|
23
|
+
import { runCuaParticipant } from "../computer-use/participant-execution.js";
|
|
23
24
|
import { buildConcurrentSharedWorldBundle, judgeSharedWorldRun } from "./bundle.js";
|
|
24
25
|
import { runCheckpointSnapshot } from "./checkpoints.js";
|
|
25
26
|
import { drainSubjectComms } from "./comms.js";
|
|
26
27
|
import { buildSubjectProvenance, hostOriginDigest, isTokenlessHost, servePort, } from "./provenance.js";
|
|
27
28
|
import { SANDBOX_TIMEOUT_BUFFER_MS, SUBJECT_PROVISION_BUDGET_MS, } from "../../substrates/e2b/lifetime.js";
|
|
28
29
|
import { DEFAULT_STATE_STEP_TIMEOUT_MS } from "../../subject/state.js";
|
|
29
|
-
import { resolveActorEntryUrl, participantRunDeps, startParticipantFlush } from "./
|
|
30
|
+
import { resolveActorEntryUrl, participantRunDeps, startParticipantFlush, } from "./participant-specs.js";
|
|
30
31
|
import { CONCURRENT_SHARED_WORLD_PROVIDER_METADATA, } from "./types.js";
|
|
31
32
|
import { addressedRecipients } from "../../lab/parse/comms.js";
|
|
32
33
|
/**
|
|
@@ -41,12 +42,13 @@ class ObserverGateError extends Error {
|
|
|
41
42
|
this.name = "ObserverGateError";
|
|
42
43
|
}
|
|
43
44
|
}
|
|
44
|
-
/** The
|
|
45
|
+
/** The one subject sandbox and the loops that run against it until teardown. */
|
|
45
46
|
class SubjectPlane {
|
|
46
47
|
commsInboxUrl;
|
|
47
48
|
subjectCommit;
|
|
48
49
|
subjectSandboxId;
|
|
49
50
|
subjectKilled = false;
|
|
51
|
+
subjectReleaseWarning;
|
|
50
52
|
getHostUrl;
|
|
51
53
|
// The subject desktop's host-side span and size, priced in the run's cost estimate.
|
|
52
54
|
subjectCreatedAtMs;
|
|
@@ -57,17 +59,17 @@ class SubjectPlane {
|
|
|
57
59
|
subjectAllocation;
|
|
58
60
|
subjectDesktop;
|
|
59
61
|
subjectShell;
|
|
60
|
-
// The in-sandbox email catch on the
|
|
62
|
+
// The in-sandbox email catch on the one subject sandbox (#297); drained at teardown. Undefined
|
|
61
63
|
// unless a comms lab declared it.
|
|
62
64
|
deployedComms;
|
|
63
|
-
// Background prober dispose signal
|
|
65
|
+
// Background prober dispose signal, cleared in teardown.
|
|
64
66
|
proberDisposed = false;
|
|
65
67
|
releaseDispose = () => { };
|
|
66
68
|
disposeSignal;
|
|
67
69
|
proberLoop;
|
|
68
70
|
snapshotIndex = 0;
|
|
69
|
-
// Persona inbox
|
|
70
|
-
// (
|
|
71
|
+
// Persona inbox surface (#297 slice B, shared-world): the serve->getHost origin-rewrite map
|
|
72
|
+
// (required here so the app's loopback verify links resolve to a reachable host), and the
|
|
71
73
|
// dedicated surface render loop.
|
|
72
74
|
commsOriginMap = [];
|
|
73
75
|
surfaceRenderedCount = 0;
|
|
@@ -98,12 +100,12 @@ class SubjectPlane {
|
|
|
98
100
|
this.setup.stateSnapshots.push({ timestamp, digest: snapshot.digest });
|
|
99
101
|
}
|
|
100
102
|
async acquire() {
|
|
101
|
-
const { plan,
|
|
103
|
+
const { plan, deps, env, requestTimeoutMs, timeoutMs } = this.ctx;
|
|
102
104
|
const { subjectEnvNames, commsEnv } = this.setup;
|
|
103
|
-
const subjectModule = await (
|
|
104
|
-
// The
|
|
105
|
-
//
|
|
106
|
-
// honored on
|
|
105
|
+
const subjectModule = await (deps.desktopModule ?? loadE2BDesktopModule)();
|
|
106
|
+
// The one subject sandbox: headless service host (no GUI seat). The subject env is provisioned
|
|
107
|
+
// here; the actor sandboxes get none of it. A custom desktop template (image) is
|
|
108
|
+
// honored on both the subject sandbox (here) and every actor sandbox (via runCuaParticipant, which
|
|
107
109
|
// reads the same config); absent keeps the byte-stable Sandbox.create(opts) default. The
|
|
108
110
|
// receipt is on disk before any work, so `humanish reclaim` can kill it by exact id.
|
|
109
111
|
const subject = await acquireE2BDesktopSandbox({
|
|
@@ -143,18 +145,16 @@ class SubjectPlane {
|
|
|
143
145
|
this.subjectSandboxId = subject.allocation.resourceId;
|
|
144
146
|
this.subjectCreatedAtMs = this.ctx.now();
|
|
145
147
|
this.subjectResources = await observeDesktopResources(this.subjectDesktop);
|
|
146
|
-
|
|
147
|
-
await hooks.prepareDesktop(this.subjectDesktop);
|
|
148
|
-
}
|
|
148
|
+
await this.ctx.input.prepareDesktop?.(this.subjectDesktop, { kind: "subject" });
|
|
149
149
|
}
|
|
150
|
-
// Start the in-sandbox email catch
|
|
150
|
+
// Start the in-sandbox email catch before the subject serve, so the app's send-API base URL
|
|
151
151
|
// (injected into its env at create) resolves the moment it boots. Fail closed if the catch can't
|
|
152
152
|
// stand up rather than let a comms-declared app silently send real mail to the internet.
|
|
153
153
|
async deployCatch() {
|
|
154
154
|
const { commsEmail, commsPort } = this.setup;
|
|
155
155
|
if (commsEmail && commsPort !== undefined) {
|
|
156
|
-
// A
|
|
157
|
-
//
|
|
156
|
+
// A second (0.0.0.0) read-only inbox listener on commsPort+1 so the persona, which lives in
|
|
157
|
+
// another sandbox here, can reach the inbox surface via getHost; capture stays loopback.
|
|
158
158
|
this.deployedComms = await deployCommsCatch(this.subjectShell, {
|
|
159
159
|
port: commsPort,
|
|
160
160
|
inboxPort: commsPort + 1,
|
|
@@ -166,15 +166,19 @@ class SubjectPlane {
|
|
|
166
166
|
}
|
|
167
167
|
}
|
|
168
168
|
}
|
|
169
|
-
// Provision the
|
|
170
|
-
// (clone route), or upload/extract the once-per-run packed archive + the
|
|
169
|
+
// Provision the one shared plane: clone + install/build + seed + serve on 0.0.0.0 + probe
|
|
170
|
+
// (clone route), or upload/extract the once-per-run packed archive + the same shared serve
|
|
171
171
|
// pipeline (local-tree route).
|
|
172
172
|
async provision() {
|
|
173
|
-
const { plan,
|
|
173
|
+
const { plan, requestTimeoutMs, scrubKnownValues } = this.ctx;
|
|
174
174
|
const { serve, timers, stateStepRecords } = this.setup;
|
|
175
175
|
const state = planeStateOf(plan);
|
|
176
176
|
const subjectShell = this.subjectShell;
|
|
177
|
-
const
|
|
177
|
+
const sink = this.ctx.input.deps?.subjectPhaseSink ?? defaultSharedWorldPhaseSink;
|
|
178
|
+
const onSubjectPhase = (event) => {
|
|
179
|
+
sink(event);
|
|
180
|
+
this.ctx.input.emit?.(phaseEvent(event, { kind: "subject" }));
|
|
181
|
+
};
|
|
178
182
|
if (this.setup.localTreeRoute) {
|
|
179
183
|
await provisionLocalTreeSubject(subjectShell, {
|
|
180
184
|
archiveBuffer: this.setup.localTreeArchiveBuffer,
|
|
@@ -209,13 +213,13 @@ class SubjectPlane {
|
|
|
209
213
|
});
|
|
210
214
|
}
|
|
211
215
|
}
|
|
212
|
-
// Expose the served port via getHost
|
|
216
|
+
// Expose the served port via getHost. Fail closed if the SDK lacks it.
|
|
213
217
|
exposeHost() {
|
|
214
218
|
const subjectDesktop = this.subjectDesktop;
|
|
215
219
|
if (typeof subjectDesktop.getHost !== "function") {
|
|
216
220
|
throw new Error("the installed @e2b/desktop SDK does not expose getHost(port); the concurrent shared-world route requires it to reach the subject plane");
|
|
217
221
|
}
|
|
218
|
-
// getHost returns a
|
|
222
|
+
// getHost returns a bare host (e.g. "3000-<sandboxId>.e2b.app", no scheme); e2b exposes the
|
|
219
223
|
// port over https. Normalize to a full URL before the tokenless check + before persisting.
|
|
220
224
|
const rawHost = subjectDesktop.getHost(servePort(this.setup.serve.url));
|
|
221
225
|
const hostUrl = /^https?:\/\//i.test(rawHost) ? rawHost : `https://${rawHost}`;
|
|
@@ -224,12 +228,12 @@ class SubjectPlane {
|
|
|
224
228
|
}
|
|
225
229
|
this.getHostUrl = hostUrl;
|
|
226
230
|
}
|
|
227
|
-
// Persona inbox
|
|
228
|
-
// a persona in
|
|
231
|
+
// Persona inbox surface (#297 slice B, shared-world): getHost-expose the read-only inbox listener so
|
|
232
|
+
// a persona in another sandbox can open it; build the serve->getHost origin map (required here:
|
|
229
233
|
// the app's loopback verify links must be rewritten to a reachable host); provision the surface
|
|
230
|
-
// channel; write the
|
|
234
|
+
// channel; write the empty inbox up front (so /inbox never 404s); and start a render loop that drains
|
|
231
235
|
// + re-renders on a cadence. The loop shares the prober's dispose signal (disposed together, before
|
|
232
|
-
// the teardown evidence drain), and uses a
|
|
236
|
+
// the teardown evidence drain), and uses a dedicated FakeInbox + cursor (independent of that drain).
|
|
233
237
|
async startInboxSurface() {
|
|
234
238
|
const { commsEmail } = this.setup;
|
|
235
239
|
const { requestTimeoutMs } = this.ctx;
|
|
@@ -303,7 +307,7 @@ class SubjectPlane {
|
|
|
303
307
|
this.disposeSignal,
|
|
304
308
|
]);
|
|
305
309
|
if (timer)
|
|
306
|
-
clearTimeout(timer); //
|
|
310
|
+
clearTimeout(timer); // No dangling prober timer.
|
|
307
311
|
if (this.proberDisposed)
|
|
308
312
|
break;
|
|
309
313
|
await this.snapshot().catch(() => undefined);
|
|
@@ -311,8 +315,8 @@ class SubjectPlane {
|
|
|
311
315
|
})();
|
|
312
316
|
}
|
|
313
317
|
/**
|
|
314
|
-
*
|
|
315
|
-
* down the
|
|
318
|
+
* Stop the prober, take a final snapshot while the subject is still alive, then tear
|
|
319
|
+
* down the one subject sandbox by id (the actor sandboxes are torn down inside runCuaParticipant).
|
|
316
320
|
* Returns the comms thread's path when the drain wrote one.
|
|
317
321
|
*/
|
|
318
322
|
async teardown() {
|
|
@@ -345,7 +349,10 @@ class SubjectPlane {
|
|
|
345
349
|
this.subjectKilled = reading.released;
|
|
346
350
|
if (reading.warning)
|
|
347
351
|
warnings.push(reading.warning);
|
|
348
|
-
|
|
352
|
+
if (!reading.released)
|
|
353
|
+
this.subjectReleaseWarning = reading.warning ?? "Subject sandbox release is unconfirmed.";
|
|
354
|
+
// Without a kill method, or in E2B debug mode, no kill reached E2B, so there is no teardown
|
|
355
|
+
// time to record.
|
|
349
356
|
if (released.status !== "unconfirmed" || released.reason !== "release_unavailable")
|
|
350
357
|
this.subjectTornDownAtMs = this.ctx.now();
|
|
351
358
|
}
|
|
@@ -384,11 +391,10 @@ async function publishInProgress(plane, ctx, live, setup) {
|
|
|
384
391
|
});
|
|
385
392
|
const snapshotArgs = {
|
|
386
393
|
plan,
|
|
394
|
+
run: ctx.run,
|
|
387
395
|
descriptor: ctx.descriptor,
|
|
388
|
-
createdAt: ctx.createdAt,
|
|
389
396
|
dryRun: false,
|
|
390
397
|
inProgress: true,
|
|
391
|
-
runId: ctx.runId,
|
|
392
398
|
source: ctx.source,
|
|
393
399
|
actorSpecs: ctx.actorSpecs,
|
|
394
400
|
actorResults: [],
|
|
@@ -416,9 +422,9 @@ async function publishInProgress(plane, ctx, live, setup) {
|
|
|
416
422
|
}
|
|
417
423
|
startParticipantFlush(ctx, live, inProgressBundle);
|
|
418
424
|
}
|
|
419
|
-
// Launch N actor sandboxes
|
|
420
|
-
//
|
|
421
|
-
// orchestrator clock
|
|
425
|
+
// Launch N actor sandboxes concurrently and independently (runCuaParticipant + mapWithConcurrency;
|
|
426
|
+
// runCuaParticipants would add a pipeline gate and fail-fast). Each actor's window is measured on the
|
|
427
|
+
// one orchestrator clock.
|
|
422
428
|
function runParticipants(plane, ctx, live, setup) {
|
|
423
429
|
const { now } = ctx;
|
|
424
430
|
const participants = ctx.plan.plane.participants;
|
|
@@ -426,7 +432,7 @@ function runParticipants(plane, ctx, live, setup) {
|
|
|
426
432
|
const baseActorDeps = participantRunDeps(ctx, live, ctx.scrubKnownValues);
|
|
427
433
|
return mapWithConcurrency(ctx.actorSpecs, Math.max(1, ctx.concurrency), async (spec, i) => {
|
|
428
434
|
const route = resolveActorEntryUrl(plane.getHostUrl, participants[i]?.entry);
|
|
429
|
-
// Tell this persona its (getHost-reachable) inbox URL
|
|
435
|
+
// Tell this persona its (getHost-reachable) inbox URL, but only when comms is live and this participant
|
|
430
436
|
// has a declared recipient it can actually receive mail into (else it would stall on an empty
|
|
431
437
|
// inbox). Only the in-sandbox catch exists on this plane; the adopter-hosted catch is the
|
|
432
438
|
// external-public plane's (#387).
|
|
@@ -471,6 +477,7 @@ export async function runProvisionedPlane(ctx, live, setup) {
|
|
|
471
477
|
subjectCommit: plane.subjectCommit,
|
|
472
478
|
subjectSandboxId: plane.subjectSandboxId,
|
|
473
479
|
subjectKilled: plane.subjectKilled,
|
|
480
|
+
subjectReleaseWarning: plane.subjectReleaseWarning,
|
|
474
481
|
subjectDesktop: plane.desktopUsage(),
|
|
475
482
|
getHostUrl: plane.getHostUrl,
|
|
476
483
|
commsArtifactPath,
|
|
@@ -480,8 +487,8 @@ export async function runProvisionedPlane(ctx, live, setup) {
|
|
|
480
487
|
* Packs the working tree once per run, on the host, for a local-tree subject. Returns the archive,
|
|
481
488
|
* or the message the run fails with.
|
|
482
489
|
*/
|
|
483
|
-
export async function packSubjectTree(cwd, config,
|
|
484
|
-
const packLocalTree =
|
|
490
|
+
export async function packSubjectTree(cwd, config, deps, scrubKnownValues) {
|
|
491
|
+
const packLocalTree = deps.packLocalTree ?? defaultPackLocalTree;
|
|
485
492
|
try {
|
|
486
493
|
const packed = await packLocalTree({
|
|
487
494
|
root: cwd,
|