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
|
@@ -26,10 +26,11 @@ import path from "node:path";
|
|
|
26
26
|
import { completeAutomaticAnalysis } from "../../analysis/automatic-completion.js";
|
|
27
27
|
import { runScope } from "../../run/run.js";
|
|
28
28
|
import { resolveAutomaticAnalysis } from "../../analysis/automatic-config.js";
|
|
29
|
-
import {
|
|
30
|
-
import {
|
|
29
|
+
import { browserRouteScorer } from "../../lab/adapter-scorer-loader.js";
|
|
30
|
+
import { withLateScorer } from "../../lab/route-inputs.js";
|
|
31
|
+
import { callerDrivingOf, planComputerUseLab } from "./plan.js";
|
|
31
32
|
import { finishCuaRun } from "./result.js";
|
|
32
|
-
import { runLabParticipants } from "./
|
|
33
|
+
import { runLabParticipants } from "./live-phase.js";
|
|
33
34
|
import { admitCuaRun, refuseCuaLab, startCuaRun } from "./setup.js";
|
|
34
35
|
import { CUA_ACTOR_LAB_SCHEMA, } from "./types.js";
|
|
35
36
|
/**
|
|
@@ -38,12 +39,12 @@ import { CUA_ACTOR_LAB_SCHEMA, } from "./types.js";
|
|
|
38
39
|
* run and its analysis.
|
|
39
40
|
*/
|
|
40
41
|
export async function runCuaActorLab(options) {
|
|
41
|
-
const { config, dryRun,
|
|
42
|
+
const { config, dryRun, ...input } = options;
|
|
42
43
|
// planComputerUseLab makes every configuration refusal, in the order this route always has.
|
|
43
44
|
const planned = planComputerUseLab(config, {
|
|
44
45
|
dryRun,
|
|
45
|
-
|
|
46
|
-
|
|
46
|
+
hasRunSession: input.deps?.runSession !== undefined,
|
|
47
|
+
driving: callerDrivingOf(input),
|
|
47
48
|
...(input.countOverride === undefined ? {} : { countOverride: input.countOverride }),
|
|
48
49
|
...(input.rerun === undefined ? {} : { rerun: input.rerun }),
|
|
49
50
|
});
|
|
@@ -53,7 +54,7 @@ export async function runCuaActorLab(options) {
|
|
|
53
54
|
}
|
|
54
55
|
/**
|
|
55
56
|
* A refused computer-use lab's result, at the refusal's stage: a before-scope refusal has its own
|
|
56
|
-
* envelope and no analysis record; the others come after the cwd checks, and the
|
|
57
|
+
* envelope and no analysis record; the others come after the cwd checks, and the participant cap after
|
|
57
58
|
* the personas are read.
|
|
58
59
|
*/
|
|
59
60
|
export async function computerUseLabRefusal(options, refusal) {
|
|
@@ -72,9 +73,9 @@ export async function computerUseLabRefusal(options, refusal) {
|
|
|
72
73
|
warnings: [],
|
|
73
74
|
error: { code: refusal.code, message: refusal.message },
|
|
74
75
|
};
|
|
75
|
-
// The other refusals come after the cwd checks, and the
|
|
76
|
+
// The other refusals come after the cwd checks, and the participant cap after the personas are read.
|
|
76
77
|
const analysis = resolveAutomaticAnalysis(config.review?.analysis);
|
|
77
|
-
return completeAutomaticAnalysis(await refuseCuaLab(options, refusal), undefined, analysis.ok ? analysis.config : undefined, options
|
|
78
|
+
return completeAutomaticAnalysis(await refuseCuaLab(options, refusal), undefined, analysis.ok ? analysis.config : undefined, options, { trigger: config.review?.analysis === undefined ? "default" : "explicit" });
|
|
78
79
|
}
|
|
79
80
|
/**
|
|
80
81
|
* runLab's step for a computer-use plan. It runs the plan's local checks (admitCuaRun: the
|
|
@@ -92,24 +93,22 @@ export async function admitComputerUsePlan(plan, input, config) {
|
|
|
92
93
|
return {
|
|
93
94
|
ok: true,
|
|
94
95
|
run: async (scorer) => {
|
|
95
|
-
|
|
96
|
-
//
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
return cuaOutcome(await runAdmittedCuaRun(plan, running, admitted));
|
|
96
|
+
// The scorer joins the input only; the runSession, provider and desktop the checks admitted
|
|
97
|
+
// stay the ones the run uses.
|
|
98
|
+
const running = withLateScorer(input, scorer, browserRouteScorer);
|
|
99
|
+
return cuaOutcome(await runAdmittedCuaRun(plan, running, admission.admitted));
|
|
100
100
|
},
|
|
101
101
|
};
|
|
102
102
|
}
|
|
103
103
|
function cuaOutcome(result) {
|
|
104
|
-
return { route: "computer-use",
|
|
104
|
+
return { route: "computer-use", result };
|
|
105
105
|
}
|
|
106
106
|
/**
|
|
107
107
|
* Run a computer-use plan: its local checks, then the run. The run scope in runAdmittedCuaRun
|
|
108
108
|
* finalizes any status record the run opened, on every exit, so a test or library caller does not
|
|
109
109
|
* leave the 5 s status cadence writing into a directory something else is deleting (an unrelated
|
|
110
|
-
* ENOTEMPTY). Participants
|
|
111
|
-
*
|
|
112
|
-
* cap) and by the compatibility hooks, which take the whole config.
|
|
110
|
+
* ENOTEMPTY). Participants, the brain, the subject, the caps and the residual config come from the
|
|
111
|
+
* plan. `config` is what the caller's createProvider and inProcess executor receive.
|
|
113
112
|
*/
|
|
114
113
|
export async function runComputerUsePlan(plan, input, config) {
|
|
115
114
|
const admission = await admitCuaRun(plan, input, config);
|
|
@@ -129,9 +128,12 @@ function runAdmittedCuaRun(plan, input, admitted) {
|
|
|
129
128
|
});
|
|
130
129
|
}
|
|
131
130
|
function completeCuaAnalysis(plan, input, result, finished) {
|
|
132
|
-
|
|
131
|
+
// A local VM study whose cleanup is unconfirmed records a skip instead of analyzing.
|
|
132
|
+
const refusal = input.localVm?.analysisRefusal;
|
|
133
|
+
return completeAutomaticAnalysis(result, finished, plan.analysis?.config, input, {
|
|
133
134
|
...(plan.analysis === undefined ? {} : { trigger: plan.analysis.trigger }),
|
|
134
135
|
preferLargerOutput: plan.analysis?.preferLargerOutput === true,
|
|
136
|
+
...(refusal === undefined ? {} : { refusal }),
|
|
135
137
|
});
|
|
136
138
|
}
|
|
137
139
|
async function runPlanInScope(plan, input, admitted, scope) {
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import type { CuaLoopResult } from "../../actors/computer-use/loop.js";
|
|
2
2
|
import { type SessionEnding } from "../../run/judge.js";
|
|
3
3
|
/**
|
|
4
|
-
* A goal_satisfied
|
|
4
|
+
* A goal_satisfied participant counts as a self-reported blocker ONLY when its final narrative contradicts
|
|
5
5
|
* the goal AND the run's own stop predicate did NOT fire. A matched stopWhen is independent,
|
|
6
6
|
* structured completion evidence, so it overrides a text scan of the free-form narrative — which can
|
|
7
7
|
* otherwise trip on the subject app's OWN quoted copy (e.g. a relayed "cannot be undone" banner).
|
|
8
8
|
* Resolved-arc segments never block the verdict (#453). Returns the offending reason, or undefined
|
|
9
|
-
* when the
|
|
9
|
+
* when the participant is a clean pass. Exported for testing.
|
|
10
10
|
*/
|
|
11
11
|
export declare function resolveSelfReportedBlocker(session: CuaLoopResult | undefined): string | undefined;
|
|
12
12
|
/** A session's ending, reduced to what the judge's engagement and blocker rules read. */
|
|
@@ -20,7 +20,7 @@ function hasBlockerLanguage(text) {
|
|
|
20
20
|
// Report-shaped language: what a participant writes when it finished AND has something to say.
|
|
21
21
|
// Every one of the day's eleven drawDB reports (2026-09-01) opened a section "What confused me"
|
|
22
22
|
// or "Accessibility defects:"; none contained a blocker word, so none became a feedback candidate
|
|
23
|
-
// and a
|
|
23
|
+
// and a participant that had just replicated a keyboard-accessibility defect three times drafted "Live
|
|
24
24
|
// study completed without a participant-reported finding". Friction is the INCLUSIVE scan; a
|
|
25
25
|
// false positive here adds a candidate a person then reads, which is the cheap direction.
|
|
26
26
|
const REPORTED_DEFECT_LANGUAGE = /\b(defects?|bugs?|accessibilit(y|ies)|inaccessible|not (keyboard|screen.?reader)[- ]?accessible|confus(ed|ing)|hesitat(ed|ion)|unexpected(ly)?|unclear|hard to (find|tell|see|read|reach)|no (visible )?focus|overlap(ped|ping|s)?|truncat(ed|es|ion)|cut off|did nothing|nothing happened|no effect)\b/;
|
|
@@ -94,7 +94,7 @@ function completionReasonBlocksVerdict(reason) {
|
|
|
94
94
|
// with a parser error. A simpler SQL import succeeded."). The lookahead demands the retry flavor
|
|
95
95
|
// on purpose: unrelated praise ("Separately, the search box worked") must never launder an
|
|
96
96
|
// unresolved failure. "Login failed so I gave up" has no recovery anywhere and stays a blocker.
|
|
97
|
-
// (#453 — the run-1 false negative: a defect report after demonstrated success failed the
|
|
97
|
+
// (#453 — the run-1 false negative: a defect report after demonstrated success failed the participant,
|
|
98
98
|
// an incentive inversion against exactly the participant behavior a study wants most.)
|
|
99
99
|
const RESOLUTION_TERMS = /\b(succeed(?:ed|s)?|success(?:ful|fully)?|worked|works around|then worked|now works?|resolved|fixed|recovered|got it working|went through)\b/;
|
|
100
100
|
const RETRY_RESOLUTION = /\b(simpler|simplified|retry(?:ing)?|retried|second (?:attempt|try)|another (?:attempt|try|approach)|different (?:approach|way|route)|instead|then|eventually|after that)\b[^.!?\n]{0,80}\b(succeed(?:ed|s)?|success(?:ful|fully)?|worked|went through|completed|passed)\b/;
|
|
@@ -152,12 +152,12 @@ function traceHasStopWhenMatch(session) {
|
|
|
152
152
|
(item.title.startsWith("stopWhen matched") || item.title === "dwell window complete"));
|
|
153
153
|
}
|
|
154
154
|
/**
|
|
155
|
-
* A goal_satisfied
|
|
155
|
+
* A goal_satisfied participant counts as a self-reported blocker ONLY when its final narrative contradicts
|
|
156
156
|
* the goal AND the run's own stop predicate did NOT fire. A matched stopWhen is independent,
|
|
157
157
|
* structured completion evidence, so it overrides a text scan of the free-form narrative — which can
|
|
158
158
|
* otherwise trip on the subject app's OWN quoted copy (e.g. a relayed "cannot be undone" banner).
|
|
159
159
|
* Resolved-arc segments never block the verdict (#453). Returns the offending reason, or undefined
|
|
160
|
-
* when the
|
|
160
|
+
* when the participant is a clean pass. Exported for testing.
|
|
161
161
|
*/
|
|
162
162
|
export function resolveSelfReportedBlocker(session) {
|
|
163
163
|
return session !== undefined && selfReportedBlocker(blockerFacts(session))
|
|
@@ -1,18 +1,17 @@
|
|
|
1
1
|
import { type RunScope } from "../../run/run.js";
|
|
2
|
-
import { type LocalAgentId } from "../../actors/local-agent/cli.js";
|
|
3
2
|
import type { CuaActorDescriptor } from "../../actors/registry.js";
|
|
4
3
|
import type { LabCommsEmail, LabCommsExternal, LabConfig } from "../../lab/types.js";
|
|
5
4
|
import { type RunRerunLineage } from "../../run/bundle.js";
|
|
6
5
|
import { type LocalTreeArchive } from "../../subject/local-tree-archive.js";
|
|
7
|
-
import { type ComputerUseRefusal
|
|
6
|
+
import { type ComputerUseRefusal } from "./plan.js";
|
|
8
7
|
import type { ComputerUsePlan } from "../../lab/plan-types.js";
|
|
9
8
|
import { trackRuntimeStreams, type LiveTraceFlush } from "./live-flush.js";
|
|
10
9
|
import { type CuaRunBundleBase } from "./bundle.js";
|
|
11
10
|
import { projectParticipantSubjects } from "./subject-projection.js";
|
|
12
|
-
import { type CuaActorLabErrorCode, type
|
|
11
|
+
import { type CuaActorLabErrorCode, type CuaActorLabResult, type CuaParticipantDeps, type CuaParticipantPlan, type DesktopParticipantRun, type CuaSubjectProjection, type CuaSubjectProvenanceArg, type ComputerUseRunInput, type RunCuaActorLabOptions } from "./types.js";
|
|
13
12
|
/**
|
|
14
|
-
* The envelope of a refusal the plan left for after the cwd checks. The
|
|
15
|
-
* fan-out refusals come after the committed personas are read, so a persona-file error still wins.
|
|
13
|
+
* The envelope of a refusal the plan left for after the cwd checks. The participant cap and
|
|
14
|
+
* in-process fan-out refusals come after the committed personas are read, so a persona-file error still wins.
|
|
16
15
|
*/
|
|
17
16
|
export declare function refuseCuaLab(options: RunCuaActorLabOptions, refusal: ComputerUseRefusal): Promise<CuaActorLabResult>;
|
|
18
17
|
export type AdmittedCuaRun = Extract<Awaited<ReturnType<typeof admitCuaRun>>, {
|
|
@@ -25,13 +24,9 @@ type StartedRun = Extract<Awaited<ReturnType<RunScope["startRun"]>>, {
|
|
|
25
24
|
export interface CuaRunSetup {
|
|
26
25
|
plan: ComputerUsePlan;
|
|
27
26
|
input: ComputerUseRunInput;
|
|
28
|
-
/** Read for values the plan does not carry yet, and by the compatibility hooks, which take the
|
|
29
|
-
* whole config. Participants come from the plan. */
|
|
30
|
-
config: LabConfig;
|
|
31
27
|
/** The physical project root. */
|
|
32
28
|
cwd: string;
|
|
33
29
|
descriptor: CuaActorDescriptor;
|
|
34
|
-
subjectRoute: CuaSubjectRoute;
|
|
35
30
|
run: StartedRun;
|
|
36
31
|
streams: ReturnType<typeof trackRuntimeStreams>;
|
|
37
32
|
participantRuns: DesktopParticipantRun[];
|
|
@@ -67,7 +62,6 @@ export interface CuaParticipantsSetup {
|
|
|
67
62
|
}
|
|
68
63
|
/** What only finishCuaRun reads besides the participants' outcomes. */
|
|
69
64
|
export interface CuaFinishFacts {
|
|
70
|
-
hooks: CuaActorLabHooks;
|
|
71
65
|
rerunLineage: RunRerunLineage | undefined;
|
|
72
66
|
publicRepo: string | undefined;
|
|
73
67
|
subjectArgs: Omit<Parameters<typeof projectParticipantSubjects>[0], "outcomes" | "dryRun">;
|
|
@@ -96,16 +90,16 @@ export declare function admitCuaRun(plan: ComputerUsePlan, input: ComputerUseRun
|
|
|
96
90
|
config: LabConfig;
|
|
97
91
|
dryRun: boolean;
|
|
98
92
|
cwd: string;
|
|
99
|
-
|
|
93
|
+
seams: import("../../lab/lab-deps.js").LabDeps;
|
|
100
94
|
streams: {
|
|
101
|
-
|
|
95
|
+
onStream: NonNullable<import("../../lab/run-lab-homes.js").RunLabHomes["onStream"]>;
|
|
102
96
|
showIn: (observer: import("../../index.js").ObserverResult & {
|
|
103
97
|
ok: true;
|
|
104
98
|
}) => void;
|
|
105
99
|
attachFinal: (observer: import("../../index.js").ObserverResult) => void;
|
|
106
100
|
};
|
|
107
|
-
env:
|
|
108
|
-
|
|
101
|
+
env: Record<string, string | undefined>;
|
|
102
|
+
appUrl: string;
|
|
109
103
|
fail: (code: CuaActorLabErrorCode, message: string, actorLabel?: string) => CuaActorLabResult;
|
|
110
104
|
refuse: (code: CuaActorLabErrorCode, message: string, actorLabel?: string | undefined) => {
|
|
111
105
|
ok: false;
|
|
@@ -124,9 +118,6 @@ export declare function admitCuaRun(plan: ComputerUsePlan, input: ComputerUseRun
|
|
|
124
118
|
knownSecretValues: string[];
|
|
125
119
|
scrubKnownValues: (text: string) => string;
|
|
126
120
|
publicRepo: string | undefined;
|
|
127
|
-
hasGithubToken: boolean;
|
|
128
|
-
localAgentRoute: boolean;
|
|
129
|
-
preferredLocalAgent: LocalAgentId;
|
|
130
121
|
localTreeArchive: LocalTreeArchive | undefined;
|
|
131
122
|
localTreeArchiveBuffer: ArrayBuffer | undefined;
|
|
132
123
|
};
|
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
// The computer-use run's setup: resolve the project and route, plan the
|
|
2
|
-
// checks that need no sandbox, pack a local tree, then start the run and build the
|
|
3
|
-
// bundle base that the
|
|
1
|
+
// The computer-use run's setup: resolve the project and route, plan the participants, make the
|
|
2
|
+
// live checks that need no sandbox, pack a local tree, then start the run and build the
|
|
3
|
+
// participant deps and bundle base that the participants and the finish share.
|
|
4
4
|
import { randomBytes } from "node:crypto";
|
|
5
5
|
import { realpath } from "node:fs/promises";
|
|
6
6
|
import path from "node:path";
|
|
7
7
|
import {} from "../../run/run.js";
|
|
8
8
|
import { externalInboxUrl } from "../../comms/sandbox-catch.js";
|
|
9
|
-
import {} from "../../actors/local-agent/cli.js";
|
|
10
9
|
import { redactText, scrubLiterals, toErrorMessage } from "../../evidence/redaction.js";
|
|
11
10
|
import { buildRunSource } from "../../run/bundle.js";
|
|
12
11
|
import { assertPreparedSelectedOutputDirectory, prepareContainedOutputDirectory, prepareSelectedOutputDirectory, } from "../../run/contained-output.js";
|
|
@@ -16,14 +15,15 @@ import { emitPreflightPlan, compileParticipantPersonas, loadCuaParticipants, san
|
|
|
16
15
|
import { makeCuaRunBudget } from "./participant-model.js";
|
|
17
16
|
import { e2bRequestTimeoutMs } from "../../substrates/e2b/lifetime.js";
|
|
18
17
|
import { liveCuaRejection } from "./preflight.js";
|
|
19
|
-
import { cuaDescriptorOf,
|
|
18
|
+
import { cuaDescriptorOf, declaredAppUrl, plannedAppUrl } from "./plan.js";
|
|
20
19
|
import { trackRuntimeStreams } from "./live-flush.js";
|
|
20
|
+
import { participantOf, phaseEvent, planEvent } from "../../lab/run-lab-events.js";
|
|
21
|
+
import { defaultSubjectPhaseSink } from "../../subject/steps.js";
|
|
21
22
|
import {} from "./bundle.js";
|
|
22
23
|
import { packRunLocalTree } from "./local-tree-pack.js";
|
|
23
24
|
import { projectParticipantSubjects, subjectProvenanceArg } from "./subject-projection.js";
|
|
24
|
-
import { CUA_ACTOR_LAB_SCHEMA, } from "./types.js";
|
|
25
|
+
import { CUA_ACTOR_LAB_SCHEMA, participantSubjectEnv, } from "./types.js";
|
|
25
26
|
import { labPersonaIds } from "../../lab/persona-resolve.js";
|
|
26
|
-
import { participantDesktopOf } from "./participant-desktop.js";
|
|
27
27
|
/** The physical project, bound before any caller hook runs. */
|
|
28
28
|
async function bindProject(cwd) {
|
|
29
29
|
// Capture the physical project before reading or invoking any caller hook. A supported
|
|
@@ -33,13 +33,12 @@ async function bindProject(cwd) {
|
|
|
33
33
|
return prepareSelectedOutputDirectory(path.dirname(physicalCwd), physicalCwd);
|
|
34
34
|
}
|
|
35
35
|
/**
|
|
36
|
-
* The envelope of a refusal the plan left for after the cwd checks. The
|
|
37
|
-
* fan-out refusals come after the committed personas are read, so a persona-file error still wins.
|
|
36
|
+
* The envelope of a refusal the plan left for after the cwd checks. The participant cap and
|
|
37
|
+
* in-process fan-out refusals come after the committed personas are read, so a persona-file error still wins.
|
|
38
38
|
*/
|
|
39
39
|
export async function refuseCuaLab(options, refusal) {
|
|
40
40
|
const { config, dryRun } = options;
|
|
41
41
|
const projectRoot = await bindProject(options.cwd);
|
|
42
|
-
const hooks = options.hooks ?? {};
|
|
43
42
|
// The committed personas are read before the refusal returns, so a persona-file error wins.
|
|
44
43
|
if (refusal.stage === "after-personas")
|
|
45
44
|
await compileParticipantPersonas(projectRoot, labPersonaIds(config));
|
|
@@ -49,7 +48,7 @@ export async function refuseCuaLab(options, refusal) {
|
|
|
49
48
|
cwd: projectRoot.physicalPath,
|
|
50
49
|
labId: config.id,
|
|
51
50
|
actor: refusal.actor ?? config.actors[0]?.type ?? "",
|
|
52
|
-
appUrl:
|
|
51
|
+
appUrl: declaredAppUrl(config),
|
|
53
52
|
dryRun,
|
|
54
53
|
runId: options.runId ?? "not-created",
|
|
55
54
|
lanes: [],
|
|
@@ -67,11 +66,13 @@ export async function admitCuaRun(plan, input, config) {
|
|
|
67
66
|
const { dryRun } = plan;
|
|
68
67
|
const projectRoot = await bindProject(input.cwd);
|
|
69
68
|
const cwd = projectRoot.physicalPath;
|
|
70
|
-
const
|
|
71
|
-
const streams = trackRuntimeStreams(
|
|
72
|
-
const env =
|
|
73
|
-
const
|
|
74
|
-
const
|
|
69
|
+
const seams = input.deps ?? {};
|
|
70
|
+
const streams = trackRuntimeStreams(input.onStream);
|
|
71
|
+
const env = input.env ?? process.env;
|
|
72
|
+
const { subject, desktop } = plan.runner;
|
|
73
|
+
const inProcess = desktop === "in-process";
|
|
74
|
+
const appUrl = plannedAppUrl(subject);
|
|
75
|
+
const subjectEnvNames = [...participantSubjectEnv(subject)];
|
|
75
76
|
const fail = (code, message, actorLabel) => ({
|
|
76
77
|
schema: CUA_ACTOR_LAB_SCHEMA,
|
|
77
78
|
ok: false,
|
|
@@ -89,15 +90,29 @@ export async function admitCuaRun(plan, input, config) {
|
|
|
89
90
|
ok: false,
|
|
90
91
|
result: fail(...args),
|
|
91
92
|
});
|
|
93
|
+
// runLab's local VM study supplies a local-target app-url lab's desktop; a direct route call or
|
|
94
|
+
// an in-process executor on the same lab has none. It reads the declared source, as the planner
|
|
95
|
+
// did: a library config the parser never saw can plan to an app-url subject from another source.
|
|
96
|
+
if (config.subject.source === "app-url" &&
|
|
97
|
+
config.execution?.target === "local" &&
|
|
98
|
+
input.localVm === undefined)
|
|
99
|
+
return refuse("HUMANISH_CUA_LAB_LOCAL_DESKTOP_MISSING", "An app-url lab with execution.target: local needs a local desktop. runLab starts one; a direct route call or an in-process executor does not.");
|
|
92
100
|
const descriptor = cuaDescriptorOf(plan.actor);
|
|
93
|
-
const
|
|
101
|
+
const baseRunSession = seams.runSession ?? descriptor.runSession;
|
|
102
|
+
// A local VM study's sessions abort on its signal.
|
|
103
|
+
const localVmSignal = input.localVm?.signal;
|
|
104
|
+
const runSession = localVmSignal === undefined
|
|
105
|
+
? baseRunSession
|
|
106
|
+
: (options) => baseRunSession({ ...options, signal: localVmSignal });
|
|
94
107
|
// Adopter-hosted comms plane on the app-url route (#380): humanish provisions no subject here,
|
|
95
108
|
// so it cannot host a catch — the OPERATOR runs one, and humanish still does every other part
|
|
96
109
|
// of the funnel: tells each persona its address and inbox URL, drains the catch over HTTP after
|
|
97
|
-
// the
|
|
110
|
+
// the participants, and writes the same digest-only evidence. Declaring `external` previously did
|
|
98
111
|
// nothing on this route (and, per #387, on every other) while its docs said otherwise.
|
|
99
112
|
const comms = plan.residual.comms;
|
|
100
|
-
const externalCommsConfig =
|
|
113
|
+
const externalCommsConfig = subject.kind !== "clone" && subject.kind !== "local-tree" && !inProcess
|
|
114
|
+
? comms?.email?.external
|
|
115
|
+
: undefined;
|
|
101
116
|
const externalCommsEmail = externalCommsConfig ? comms?.email : undefined;
|
|
102
117
|
const participants = await loadCuaParticipants({ plan, cwd, projectRoot, env });
|
|
103
118
|
if (!participants.ok) {
|
|
@@ -105,13 +120,13 @@ export async function admitCuaRun(plan, input, config) {
|
|
|
105
120
|
}
|
|
106
121
|
const { participantRuns, participantPlan, rerunLineage } = participants;
|
|
107
122
|
const participantCount = participantRuns.length;
|
|
108
|
-
// Pre-flight plan: BEFORE any sandbox or provider call (dry-run AND live).
|
|
109
|
-
// every N
|
|
110
|
-
//
|
|
123
|
+
// Pre-flight plan: BEFORE any sandbox or provider call (dry-run AND live). onEvent gets it for
|
|
124
|
+
// every N; the stderr table prints for fan-out (N>1) so single-participant runs stay as quiet as they
|
|
125
|
+
// always were.
|
|
111
126
|
if (participantCount > 1) {
|
|
112
127
|
emitPreflightPlan(participantPlan, plan.labId);
|
|
113
128
|
}
|
|
114
|
-
|
|
129
|
+
input.emit?.(planEvent(participantPlan));
|
|
115
130
|
await assertPreparedSelectedOutputDirectory(projectRoot);
|
|
116
131
|
// Read keys once into locals (names only; values never logged or persisted).
|
|
117
132
|
const openaiApiKey = env.OPENAI_API_KEY?.trim() ?? "";
|
|
@@ -125,43 +140,30 @@ export async function admitCuaRun(plan, input, config) {
|
|
|
125
140
|
const scrubKnownValues = scrubLiterals(knownSecretValues);
|
|
126
141
|
sanitizeParticipantRuns(participantRuns, scrubKnownValues);
|
|
127
142
|
const redactRepoLabel = plan.residual.policies?.redactRepos ?? subjectEnvNames.includes("GITHUB_TOKEN");
|
|
128
|
-
const publicRepo =
|
|
129
|
-
const hasGithubToken = subjectEnvNames.includes("GITHUB_TOKEN");
|
|
130
|
-
// The operator's own signed-in coding agent is the brain, so there is no provider key to ask
|
|
131
|
-
// for — the entire point of the actor. E2B is still required: the persona needs a machine.
|
|
132
|
-
const localAgentRoute = descriptor.id === "local-agent";
|
|
133
|
-
// Which local CLI, from its OWN field: `model` means the model, so that "Claude Code running
|
|
134
|
-
// Opus" is sayable. Preflight below refuses when the chosen one is missing or signed out — that
|
|
135
|
-
// news is worthless after a sandbox is paid for.
|
|
136
|
-
const preferredLocalAgent = config.actors[0]?.localAgent ?? "codex";
|
|
143
|
+
const publicRepo = subject.kind === "clone" ? (redactRepoLabel ? "repo-01" : subject.repo) : undefined;
|
|
137
144
|
// Key-gating is route-aware: the in-process route uses the caller's OWN model + executor, and
|
|
138
145
|
// the local-agent route uses a CLI the operator has already signed in to.
|
|
139
|
-
if (!dryRun && !
|
|
146
|
+
if (!dryRun && !inProcess) {
|
|
140
147
|
const rejection = await liveCuaRejection({
|
|
141
148
|
caps: plan.caps,
|
|
142
|
-
|
|
143
|
-
hooks,
|
|
149
|
+
brain: plan.runner.brain,
|
|
144
150
|
env,
|
|
145
|
-
|
|
146
|
-
e2bApiKey,
|
|
147
|
-
localAgentRoute,
|
|
148
|
-
preferredLocalAgent,
|
|
149
|
-
subjectEnvNames,
|
|
151
|
+
requirements: plan.requirements,
|
|
150
152
|
externalCommsConfig,
|
|
151
153
|
});
|
|
152
154
|
if (rejection)
|
|
153
155
|
return refuse(rejection.code, rejection.message, descriptor.id);
|
|
154
156
|
}
|
|
155
157
|
// Pack the working tree ONCE per run, on the host, BEFORE any sandbox or provider call: every
|
|
156
|
-
// fan-out
|
|
157
|
-
// digest. Dry-run packs nothing (no fs side effects; the contract bundle carries no
|
|
158
|
+
// fan-out participant below uploads this SAME archive, so one archiveSha256 describes every
|
|
159
|
+
// participant's digest. Dry-run packs nothing (no fs side effects; the contract bundle carries no
|
|
158
160
|
// archiveSha256). A packing failure fails the run closed here, before any sandbox is
|
|
159
161
|
// created and before the run directory exists.
|
|
160
162
|
let localTreeArchive;
|
|
161
163
|
let localTreeArchiveBuffer;
|
|
162
|
-
if (
|
|
164
|
+
if (subject.kind === "local-tree" && !dryRun) {
|
|
163
165
|
try {
|
|
164
|
-
const packed = await packRunLocalTree(
|
|
166
|
+
const packed = await packRunLocalTree(seams, plan.residual, cwd);
|
|
165
167
|
localTreeArchive = packed.archive;
|
|
166
168
|
localTreeArchiveBuffer = packed.buffer;
|
|
167
169
|
}
|
|
@@ -175,10 +177,10 @@ export async function admitCuaRun(plan, input, config) {
|
|
|
175
177
|
config,
|
|
176
178
|
dryRun,
|
|
177
179
|
cwd,
|
|
178
|
-
|
|
180
|
+
seams,
|
|
179
181
|
streams,
|
|
180
182
|
env,
|
|
181
|
-
|
|
183
|
+
appUrl,
|
|
182
184
|
fail,
|
|
183
185
|
refuse,
|
|
184
186
|
descriptor,
|
|
@@ -194,9 +196,6 @@ export async function admitCuaRun(plan, input, config) {
|
|
|
194
196
|
knownSecretValues,
|
|
195
197
|
scrubKnownValues,
|
|
196
198
|
publicRepo,
|
|
197
|
-
hasGithubToken,
|
|
198
|
-
localAgentRoute,
|
|
199
|
-
preferredLocalAgent,
|
|
200
199
|
localTreeArchive,
|
|
201
200
|
localTreeArchiveBuffer,
|
|
202
201
|
},
|
|
@@ -204,8 +203,8 @@ export async function admitCuaRun(plan, input, config) {
|
|
|
204
203
|
}
|
|
205
204
|
/** Starts the run and builds what the participants and the finish read: the deps and the bundle base. */
|
|
206
205
|
export async function startCuaRun(plan, input, admitted, scope) {
|
|
207
|
-
const {
|
|
208
|
-
const { appUrl
|
|
206
|
+
const { dryRun, cwd, seams, descriptor, participantRuns, participantPlan, publicRepo } = admitted;
|
|
207
|
+
const { appUrl } = admitted;
|
|
209
208
|
// The run's status record exists from here on, so anything watching the runs directory can
|
|
210
209
|
// tell which lab this is and that it is alive. The fail-closed returns below leave it finished
|
|
211
210
|
// with no outcome when the scope closes; a crash leaves it stale, which reads as interrupted.
|
|
@@ -216,12 +215,12 @@ export async function startCuaRun(plan, input, admitted, scope) {
|
|
|
216
215
|
mode: dryRun ? "dry-run" : "live",
|
|
217
216
|
lab: plan.lab,
|
|
218
217
|
renderReview: renderCuaReviewMarkdown,
|
|
219
|
-
observer: { open: input.open === true, render:
|
|
218
|
+
observer: { open: input.open === true, render: seams.renderObserver },
|
|
220
219
|
});
|
|
221
220
|
if (!started.ok)
|
|
222
221
|
return admitted.refuse(started.code, started.message, descriptor.id);
|
|
223
222
|
const { run } = started;
|
|
224
|
-
const {
|
|
223
|
+
const { createdAt, paths: runPaths } = run;
|
|
225
224
|
const redactScreenshots = plan.residual.policies?.redactScreenshots === true;
|
|
226
225
|
await prepareContainedOutputDirectory(runPaths, "screenshots");
|
|
227
226
|
const source = await buildRunSource({
|
|
@@ -231,7 +230,7 @@ export async function startCuaRun(plan, input, admitted, scope) {
|
|
|
231
230
|
packageName: "humanish",
|
|
232
231
|
});
|
|
233
232
|
// Live-trace flush seam (#441): runLabParticipants fills it when a live run has an in-progress bundle
|
|
234
|
-
// to grow;
|
|
233
|
+
// to grow; participants call it through deps.onTrace. It exists before deps so deps can reference it as
|
|
235
234
|
// a stable indirection.
|
|
236
235
|
const liveTrace = {};
|
|
237
236
|
const deps = cuaParticipantDeps(plan, input, admitted, {
|
|
@@ -241,7 +240,6 @@ export async function startCuaRun(plan, input, admitted, scope) {
|
|
|
241
240
|
});
|
|
242
241
|
const subjectArgs = {
|
|
243
242
|
plan,
|
|
244
|
-
subjectRoute: admitted.subjectRoute,
|
|
245
243
|
...(publicRepo === undefined ? {} : { publicRepo }),
|
|
246
244
|
...(admitted.localTreeArchive === undefined
|
|
247
245
|
? {}
|
|
@@ -254,25 +252,20 @@ export async function startCuaRun(plan, input, admitted, scope) {
|
|
|
254
252
|
dryRun: false,
|
|
255
253
|
});
|
|
256
254
|
const inProgressAggregateSubject = inProgressSubjects[0];
|
|
257
|
-
const inProgressProvenance = subjectProvenanceArg(inProgressAggregateSubject, publicRepo,
|
|
255
|
+
const inProgressProvenance = subjectProvenanceArg(inProgressAggregateSubject, publicRepo, [
|
|
256
|
+
...participantSubjectEnv(plan.runner.subject),
|
|
257
|
+
]);
|
|
258
258
|
const bundleBase = {
|
|
259
|
-
|
|
259
|
+
run,
|
|
260
260
|
participantRuns,
|
|
261
261
|
descriptor,
|
|
262
262
|
appUrl,
|
|
263
|
-
createdAt,
|
|
264
263
|
plan,
|
|
265
|
-
runId,
|
|
266
264
|
source,
|
|
267
265
|
participantPlan,
|
|
268
266
|
...(admitted.rerunLineage === undefined ? {} : { rerun: admitted.rerunLineage }),
|
|
269
267
|
redactScreenshots,
|
|
270
|
-
inProcessRoute,
|
|
271
|
-
localAppSubject,
|
|
272
|
-
cloneRoute,
|
|
273
|
-
localTreeRoute,
|
|
274
268
|
...(publicRepo === undefined ? {} : { publicRepo }),
|
|
275
|
-
subjectEnvNames,
|
|
276
269
|
};
|
|
277
270
|
const { externalCommsConfig, externalCommsEmail } = admitted;
|
|
278
271
|
return {
|
|
@@ -280,10 +273,8 @@ export async function startCuaRun(plan, input, admitted, scope) {
|
|
|
280
273
|
setup: {
|
|
281
274
|
plan,
|
|
282
275
|
input,
|
|
283
|
-
config,
|
|
284
276
|
cwd,
|
|
285
277
|
descriptor,
|
|
286
|
-
subjectRoute: admitted.subjectRoute,
|
|
287
278
|
run,
|
|
288
279
|
streams: admitted.streams,
|
|
289
280
|
participantRuns,
|
|
@@ -306,35 +297,30 @@ export async function startCuaRun(plan, input, admitted, scope) {
|
|
|
306
297
|
},
|
|
307
298
|
fail: admitted.fail,
|
|
308
299
|
},
|
|
309
|
-
finish: {
|
|
300
|
+
finish: { rerunLineage: admitted.rerunLineage, publicRepo, subjectArgs },
|
|
310
301
|
};
|
|
311
302
|
}
|
|
312
|
-
/** The
|
|
303
|
+
/** The participant deps every participant reads: the route, keys, timeouts, scrubber, budget and seams. */
|
|
313
304
|
function cuaParticipantDeps(plan, input, admitted, run) {
|
|
314
|
-
const { config, dryRun,
|
|
315
|
-
const {
|
|
305
|
+
const { config, dryRun, seams, streams, env, runSession, participantCount } = admitted;
|
|
306
|
+
const { localTreeArchiveBuffer } = admitted;
|
|
316
307
|
const { openaiApiKey, e2bApiKey, scrubKnownValues } = admitted;
|
|
317
308
|
const { externalCommsConfig, externalCommsEmail } = admitted;
|
|
318
|
-
const { appUrl
|
|
319
|
-
const { subjectEnvNames } = admitted.subjectRoute;
|
|
309
|
+
const { appUrl } = admitted;
|
|
320
310
|
const { runPaths, redactScreenshots, liveTrace } = run;
|
|
321
|
-
const createDesktop =
|
|
311
|
+
const createDesktop = input.localVm?.desktop;
|
|
322
312
|
const timeoutMs = plan.sessionBudgetMs;
|
|
323
313
|
const requestTimeoutMs = e2bRequestTimeoutMs(env);
|
|
324
314
|
return {
|
|
325
315
|
...(createDesktop === undefined ? {} : { createDesktop }),
|
|
326
316
|
onTrace: (participantId, items, usage, metadata) => liveTrace.flush?.(participantId, items, usage, metadata),
|
|
327
|
-
config,
|
|
328
|
-
|
|
317
|
+
...callerDriving(input, config),
|
|
318
|
+
residual: plan.residual,
|
|
319
|
+
labId: plan.labId,
|
|
320
|
+
caps: plan.caps,
|
|
329
321
|
appUrl,
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
desktopCliRoute,
|
|
333
|
-
localTreeRoute,
|
|
334
|
-
...(serve === undefined ? {} : { serve }),
|
|
335
|
-
...(subjectRepo === undefined ? {} : { subjectRepo }),
|
|
336
|
-
subjectEnvNames,
|
|
337
|
-
hasGithubToken,
|
|
322
|
+
brain: plan.runner.brain,
|
|
323
|
+
subject: plan.runner.subject,
|
|
338
324
|
...(localTreeArchiveBuffer === undefined ? {} : { localTreeArchiveBuffer }),
|
|
339
325
|
env,
|
|
340
326
|
openaiApiKey,
|
|
@@ -348,7 +334,7 @@ function cuaParticipantDeps(plan, input, admitted, run) {
|
|
|
348
334
|
redactScreenshots,
|
|
349
335
|
scrubKnownValues,
|
|
350
336
|
runSession,
|
|
351
|
-
// The study-level ledger exists once per RUN, shared by every
|
|
337
|
+
// The study-level ledger exists once per RUN, shared by every participant (#299). Dry runs never
|
|
352
338
|
// spend, so they carry none.
|
|
353
339
|
...(dryRun || plan.caps.maxTotalUsd === undefined
|
|
354
340
|
? {}
|
|
@@ -361,8 +347,34 @@ function cuaParticipantDeps(plan, input, admitted, run) {
|
|
|
361
347
|
inboxUrl: externalInboxUrl(externalCommsConfig),
|
|
362
348
|
},
|
|
363
349
|
}),
|
|
364
|
-
now:
|
|
365
|
-
|
|
350
|
+
now: seams.now ?? Date.now,
|
|
351
|
+
...(seams.desktopModule === undefined ? {} : { desktopModule: seams.desktopModule }),
|
|
352
|
+
...(input.prepareDesktop === undefined ? {} : { prepareDesktop: input.prepareDesktop }),
|
|
353
|
+
...(seams.detachedTimers === undefined ? {} : { detachedTimers: seams.detachedTimers }),
|
|
354
|
+
onStream: streams.onStream,
|
|
355
|
+
reportSubjectPhase: subjectPhaseReporter(input),
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
/** The caller's createProvider and inProcess executor, with the run's config bound. */
|
|
359
|
+
function callerDriving(input, config) {
|
|
360
|
+
const { createProvider, inProcess } = input;
|
|
361
|
+
return {
|
|
362
|
+
...(createProvider === undefined
|
|
363
|
+
? {}
|
|
364
|
+
: {
|
|
365
|
+
createProvider: (participant, executor) => createProvider({ config, participant, executor }),
|
|
366
|
+
}),
|
|
367
|
+
...(inProcess === undefined
|
|
368
|
+
? {}
|
|
369
|
+
: { inProcessExecutor: (appUrl) => inProcess.executor({ config, appUrl }) }),
|
|
370
|
+
};
|
|
371
|
+
}
|
|
372
|
+
/** Each subject phase goes to the phase sink, stderr by default, and to onEvent. */
|
|
373
|
+
function subjectPhaseReporter(input) {
|
|
374
|
+
const sink = input.deps?.subjectPhaseSink ?? defaultSubjectPhaseSink;
|
|
375
|
+
return (event, participant) => {
|
|
376
|
+
sink(event, participant);
|
|
377
|
+
input.emit?.(phaseEvent(event, { kind: "participant", participant: participantOf(participant) }));
|
|
366
378
|
};
|
|
367
379
|
}
|
|
368
380
|
function makeCuaRunId() {
|