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
|
@@ -3,27 +3,27 @@ import { receivingPublication } from "../../comms/receiving-runtime.js";
|
|
|
3
3
|
import { actorEnding } from "../../actors/stop-cause.js";
|
|
4
4
|
import { redactText } from "../../evidence/redaction.js";
|
|
5
5
|
import { REVIEW_SCHEMA, bundleArtifacts, bundleHead, } from "../../run/bundle.js";
|
|
6
|
-
import { aggregateTaskFunnels, formatParticipantOutcomes,
|
|
6
|
+
import { aggregateTaskFunnels, formatParticipantOutcomes, formatRunTaskFunnel, tallyParticipantOutcomes, withCuaReviewProvenance, } from "../../run/outcomes.js";
|
|
7
7
|
import { participantFeedbackCandidates, providerResourcesForOutcome } from "./bundle-parts.js";
|
|
8
8
|
import { participantFactsOf } from "./participant-facts.js";
|
|
9
9
|
import { participantPassed, participantStatus } from "../../run/judge.js";
|
|
10
10
|
import { buildRunCostSummary, desktopSpanToMinutes } from "../../run/cost-summary.js";
|
|
11
11
|
import { formatParticipantPlanEntry } from "./participant-runs.js";
|
|
12
|
-
import { fanoutParticipantRecords } from "./fanout-
|
|
12
|
+
import { fanoutParticipantRecords } from "./fanout-records.js";
|
|
13
13
|
/** The run's first two events: its creation and the fan-out plan. */
|
|
14
14
|
function fanoutPlanEvents(args) {
|
|
15
15
|
const { specs, plan } = args;
|
|
16
16
|
const events = [];
|
|
17
17
|
events.push({
|
|
18
18
|
id: "event-000-created",
|
|
19
|
-
at: args.createdAt,
|
|
19
|
+
at: args.run.createdAt,
|
|
20
20
|
level: "info",
|
|
21
21
|
type: "cua-lab.run.created",
|
|
22
22
|
message: `Created computer-use fan-out run for ${plan.labId} (actor ${args.descriptor.id}, ${specs.length} participants, one world each).`,
|
|
23
23
|
});
|
|
24
24
|
events.push({
|
|
25
25
|
id: "event-001-fanout-plan",
|
|
26
|
-
at: args.createdAt,
|
|
26
|
+
at: args.run.createdAt,
|
|
27
27
|
level: "info",
|
|
28
28
|
type: "cua-lab.fanout.plan",
|
|
29
29
|
message: `Fan-out plan: ${args.participantPlan.laneCount} participant(s) (${args.participantPlan.strategy}), concurrency ${args.participantPlan.concurrency}, ${args.participantPlan.waves} wave(s); session budget ${Math.round(args.participantPlan.perLaneSessionBudgetMs / 1000)}s per participant; worst-case ~${args.participantPlan.worstCaseSandboxMinutes} sandbox-minutes${args.dryRun ? " (dry-run: $0)" : ""}. Participants: ${args.participantPlan.lanes.map(formatParticipantPlanEntry).join(", ")}.`,
|
|
@@ -32,7 +32,7 @@ function fanoutPlanEvents(args) {
|
|
|
32
32
|
}
|
|
33
33
|
function fanoutReview(args, streams) {
|
|
34
34
|
const { specs, outcomes } = args;
|
|
35
|
-
// The judge's verdict: live fan-out must prove every
|
|
35
|
+
// The judge's verdict: live fan-out must prove every participant (judgeParticipants).
|
|
36
36
|
const verdict = args.verdict;
|
|
37
37
|
const passedParticipants = (outcomes ?? []).filter((outcome) => participantPassed(participantFactsOf(outcome))).length;
|
|
38
38
|
// What happened to the PARTICIPANTS, with the denominator attached. The verdict above has to
|
|
@@ -40,10 +40,10 @@ function fanoutReview(args, streams) {
|
|
|
40
40
|
const terminalOutcomes = (outcomes ?? []).filter((outcome) => outcome?.session?.status !== undefined);
|
|
41
41
|
const participants = terminalOutcomes.length > 0
|
|
42
42
|
? tallyParticipantOutcomes(
|
|
43
|
-
// A NO-ENGAGEMENT
|
|
43
|
+
// A NO-ENGAGEMENT participant is not one who reached the goal. It said "done" having
|
|
44
44
|
// taken zero actions and said nothing, and `passedParticipants` above already refuses to
|
|
45
45
|
// count it — but `reachedGoal` was reading the trace status directly, so one run could be both
|
|
46
|
-
// "not a passed
|
|
46
|
+
// "not a passed participant" AND "1/1 reached the goal". The headline number a researcher reads
|
|
47
47
|
// first was the dishonest one. Found by a provider bug that ended a study on turn one.
|
|
48
48
|
terminalOutcomes.map((outcome) => participantStatus(outcome.session.status, {
|
|
49
49
|
noEngagement: outcome.noEngagement === true,
|
|
@@ -58,7 +58,7 @@ function fanoutReview(args, streams) {
|
|
|
58
58
|
const participantFunnels = (outcomes ?? [])
|
|
59
59
|
.map((outcome) => outcome?.session?.trace.taskFunnel)
|
|
60
60
|
.filter((funnel) => funnel !== undefined);
|
|
61
|
-
const
|
|
61
|
+
const runTasks = args.inProgress === true ? undefined : aggregateTaskFunnels(participantFunnels);
|
|
62
62
|
const participantEndings = terminalOutcomes.map((outcome) => {
|
|
63
63
|
const ending = actorEnding(outcome.session.trace);
|
|
64
64
|
return {
|
|
@@ -70,12 +70,12 @@ function fanoutReview(args, streams) {
|
|
|
70
70
|
schema: REVIEW_SCHEMA,
|
|
71
71
|
verdict,
|
|
72
72
|
...(participants === undefined ? {} : { participants }),
|
|
73
|
-
...(
|
|
73
|
+
...(runTasks === undefined ? {} : { tasks: runTasks }),
|
|
74
74
|
summary: args.inProgress === true
|
|
75
75
|
? `Live computer-use fan-out is running (${specs.length} participants, one world each); terminal participant evidence has not been written yet.`
|
|
76
76
|
: args.dryRun
|
|
77
77
|
? `${args.rerun ? `Rerun contract from ${args.rerun.sourceRunId}: ` : ""}Dry-run fan-out contract: ${specs.length} participants composed for ${args.descriptor.id} against ${args.appUrl}, one world each; no desktops launched, $0 spend.`
|
|
78
|
-
: `${args.rerun ? `Rerun from ${args.rerun.sourceRunId}: ` : ""}Computer-use fan-out (${specs.length} participants, one world each): ${passedParticipants}/${specs.length} participant(s) reached a terminal, engaged verdict${participants ? `: ${formatParticipantOutcomes(participants, participantEndings)}` : ""}${
|
|
78
|
+
: `${args.rerun ? `Rerun from ${args.rerun.sourceRunId}: ` : ""}Computer-use fan-out (${specs.length} participants, one world each): ${passedParticipants}/${specs.length} participant(s) reached a terminal, engaged verdict${participants ? `: ${formatParticipantOutcomes(participants, participantEndings)}` : ""}${runTasks ? `; tasks: ${formatRunTaskFunnel(runTasks)}` : ""}.`,
|
|
79
79
|
gaps: args.inProgress === true
|
|
80
80
|
? ["Live fan-out session is still running."]
|
|
81
81
|
: args.dryRun
|
|
@@ -93,7 +93,7 @@ function fanoutReview(args, streams) {
|
|
|
93
93
|
}, streams);
|
|
94
94
|
return review;
|
|
95
95
|
}
|
|
96
|
-
/** The configured browser and, when every
|
|
96
|
+
/** The configured browser and, when every participant resolved the same one, that browser. */
|
|
97
97
|
function fanoutDesktopBrowser(args) {
|
|
98
98
|
const { outcomes, plan } = args;
|
|
99
99
|
const configuredBrowser = plan.residual.execution?.desktop?.browser;
|
|
@@ -112,9 +112,9 @@ function fanoutDesktopBrowser(args) {
|
|
|
112
112
|
}
|
|
113
113
|
function fanoutCost(args) {
|
|
114
114
|
const { specs, outcomes } = args;
|
|
115
|
-
// Run-level cost ESTIMATE: one model-token line per
|
|
115
|
+
// Run-level cost ESTIMATE: one model-token line per participant that ran a session (from its persisted
|
|
116
116
|
// trace.estimatedCost) + a desktop line per owned allocation, priced at its observed resources.
|
|
117
|
-
//
|
|
117
|
+
// `per-lane-worlds` participants have no shared provisioning to double-count. Omitted on a pure dry-run.
|
|
118
118
|
const costTraces = specs
|
|
119
119
|
.map((spec, index) => ({ participantId: spec.planned.id, outcome: outcomes?.[index] }))
|
|
120
120
|
.filter((entry) => entry.outcome?.session !== undefined)
|
|
@@ -135,7 +135,7 @@ function fanoutFeedbackCandidates(args) {
|
|
|
135
135
|
return args.dryRun || args.inProgress === true
|
|
136
136
|
? []
|
|
137
137
|
: participantFeedbackCandidates({
|
|
138
|
-
runId: args.runId,
|
|
138
|
+
runId: args.run.runId,
|
|
139
139
|
scenarioId: `cua-${plan.labId}`,
|
|
140
140
|
adapterId: plan.labId,
|
|
141
141
|
goal: redactText(specs[0].evidenceInstructions ?? specs[0].instructions),
|
|
@@ -159,10 +159,10 @@ function fanoutFeedbackCandidates(args) {
|
|
|
159
159
|
});
|
|
160
160
|
}
|
|
161
161
|
/**
|
|
162
|
-
* Project N>1 fan-out
|
|
163
|
-
* is a new producer for the multi-stream shape). One sim + one stream per
|
|
162
|
+
* Project N>1 fan-out participants into a humanish.run-bundle.v1 (the evidence schema is unchanged; this
|
|
163
|
+
* is a new producer for the multi-stream shape). One sim + one stream per participant; per-participant
|
|
164
164
|
* provenance/session events; a recorded `cua-lab.fanout.plan` event (and a `cua-lab.fanout.fail-fast`
|
|
165
|
-
* event when a harness error skipped queued
|
|
165
|
+
* event when a harness error skipped queued participants). N-ary verify/Observer already handle multiple
|
|
166
166
|
* streams. A single-participant run without a rerun never reaches here: buildCuaRunBundle
|
|
167
167
|
* (bundle.ts) sends it to buildSingleParticipantBundle (single-bundle.ts).
|
|
168
168
|
*/
|
|
@@ -176,7 +176,7 @@ export function buildCuaFanoutBundle(args) {
|
|
|
176
176
|
if (args.rerun) {
|
|
177
177
|
events.push({
|
|
178
178
|
id: nextEventId("fanout-rerun"),
|
|
179
|
-
at: args.createdAt,
|
|
179
|
+
at: args.run.createdAt,
|
|
180
180
|
level: "info",
|
|
181
181
|
type: "cua-lab.fanout.rerun",
|
|
182
182
|
message: `Rerun selected ${args.rerun.selectedLaneIds.length} participant(s) from ${args.rerun.sourceRunId}: ${args.rerun.previous.map((prior) => `${prior.laneId} was ${prior.status}${prior.completionReason ? `/${prior.completionReason}` : ""}`).join(", ")}. This is a new linked run; the source run verdict is unchanged.`,
|
|
@@ -191,7 +191,7 @@ export function buildCuaFanoutBundle(args) {
|
|
|
191
191
|
if (args.failFastReason) {
|
|
192
192
|
events.push({
|
|
193
193
|
id: nextEventId("fanout-fail-fast"),
|
|
194
|
-
at: args.createdAt,
|
|
194
|
+
at: args.run.createdAt,
|
|
195
195
|
level: "warn",
|
|
196
196
|
type: "cua-lab.fanout.fail-fast",
|
|
197
197
|
message: `Fan-out fail-fast: ${args.failFastReason}. In-flight participants finished; queued participants were skipped (blocked); completed evidence is retained.`,
|
|
@@ -204,19 +204,15 @@ export function buildCuaFanoutBundle(args) {
|
|
|
204
204
|
const desktopBrowser = fanoutDesktopBrowser(args);
|
|
205
205
|
const providerResources = (outcomes ?? []).flatMap((outcome) => providerResourcesForOutcome({
|
|
206
206
|
outcome,
|
|
207
|
-
createdAt: args.createdAt,
|
|
207
|
+
createdAt: args.run.createdAt,
|
|
208
208
|
ids: outcome.spec,
|
|
209
209
|
participantId: outcome.spec.planned.id,
|
|
210
210
|
}));
|
|
211
211
|
const cost = fanoutCost(args);
|
|
212
212
|
return {
|
|
213
|
-
...bundleHead({
|
|
213
|
+
...bundleHead(args.run, {
|
|
214
214
|
...receivingPublication(args.plan.residual, args.dryRun),
|
|
215
|
-
runId: args.runId,
|
|
216
|
-
mode: args.dryRun ? "dry-run" : "live",
|
|
217
215
|
participants: specs.length,
|
|
218
|
-
createdAt: args.createdAt,
|
|
219
|
-
...(args.lab === undefined ? {} : { lab: args.lab }),
|
|
220
216
|
source: args.source,
|
|
221
217
|
}),
|
|
222
218
|
persona: {
|
|
@@ -228,9 +224,9 @@ export function buildCuaFanoutBundle(args) {
|
|
|
228
224
|
scenario: {
|
|
229
225
|
id: `cua-${plan.labId}`,
|
|
230
226
|
title: plan.title ?? `Computer-use fan-out: ${plan.labId}`,
|
|
231
|
-
// Redacted at WRITE time, like every other raw-text surface in the bundle.
|
|
232
|
-
// digest-only by design, but scenario.goal keeps one
|
|
233
|
-
// and an adopter whose authored
|
|
227
|
+
// Redacted at WRITE time, like every other raw-text surface in the bundle. Participant records are
|
|
228
|
+
// digest-only by design, but scenario.goal keeps one participant's composed instructions verbatim —
|
|
229
|
+
// and an adopter whose authored participant text must name a runtime world URL (an inbox on a route
|
|
234
230
|
// where the harness does not inject one) put an *.e2b.app address in it. That landed raw here
|
|
235
231
|
// and in observer-data.json, the sensitive-text scanner matched it, and verify failed a bundle
|
|
236
232
|
// this writer produced. The only adopter-side workaround was scanner evasion (#412).
|
|
@@ -242,7 +238,7 @@ export function buildCuaFanoutBundle(args) {
|
|
|
242
238
|
},
|
|
243
239
|
lifecycle: [
|
|
244
240
|
{
|
|
245
|
-
at: args.createdAt,
|
|
241
|
+
at: args.run.createdAt,
|
|
246
242
|
event: "cua-lab.run.created",
|
|
247
243
|
message: `Created computer-use fan-out run with ${specs.length} participants, each in its own desktop browser (actor ${args.descriptor.id}).`,
|
|
248
244
|
},
|
|
@@ -4,6 +4,10 @@ import { participantAssignment } from "../../lab/participant-assignment.js";
|
|
|
4
4
|
import { participantEvent, participantRecord, participantStream, } from "../../run/participant-records.js";
|
|
5
5
|
import { declaredScreenForRender } from "../../substrates/e2b/desktop-geometry.js";
|
|
6
6
|
import { describeSubjectState, phaseEventIdSuffix, publicSafeAppUrlLabel } from "./bundle-parts.js";
|
|
7
|
+
import { judgedStatus } from "../../run/judge.js";
|
|
8
|
+
import { participantFactsOf } from "./participant-facts.js";
|
|
9
|
+
import { participantSubjectEnv } from "./types.js";
|
|
10
|
+
const describeEnvNames = (names) => names.length > 0 ? names.join(", ") : "none";
|
|
7
11
|
function fanoutParticipantView(args, spec, index) {
|
|
8
12
|
const { outcomes, plan } = args;
|
|
9
13
|
const outcome = outcomes?.[index];
|
|
@@ -77,14 +81,15 @@ function fanoutParticipantRecord(args, spec, index, view) {
|
|
|
77
81
|
: outcome?.sessionError !== undefined
|
|
78
82
|
? `Participant ${spec.planned.id} failed before a terminal session verdict: ${outcome.sessionError}`
|
|
79
83
|
: `Contract participant ${spec.planned.id} (${spec.persona.id}/${spec.planned.device.name}) for ${args.descriptor.id} against ${publicTargetUrl}.`,
|
|
80
|
-
startedAt: args.createdAt,
|
|
81
|
-
updatedAt: args.createdAt,
|
|
84
|
+
startedAt: args.run.createdAt,
|
|
85
|
+
updatedAt: args.run.createdAt,
|
|
82
86
|
});
|
|
83
87
|
}
|
|
84
88
|
function fanoutParticipantStream(args, spec, view) {
|
|
85
89
|
const { plan } = args;
|
|
86
90
|
const { outcome, publicTargetUrl, session, desktopGeometry, screenshots } = view;
|
|
87
91
|
const { lastScreenshot, status, reason, screenshotMode } = view;
|
|
92
|
+
const judged = outcome === undefined ? undefined : judgedStatus(participantFactsOf(outcome));
|
|
88
93
|
return participantStream(spec, {
|
|
89
94
|
...(spec.evidenceAssignment === undefined
|
|
90
95
|
? {}
|
|
@@ -101,8 +106,9 @@ function fanoutParticipantStream(args, spec, view) {
|
|
|
101
106
|
kind: "browser",
|
|
102
107
|
label: `CUA participant ${spec.planned.id}: ${plan.labId}`,
|
|
103
108
|
status,
|
|
109
|
+
...(judged === undefined ? {} : { judgedStatus: judged }),
|
|
104
110
|
transport: "snapshot",
|
|
105
|
-
updatedAt: args.createdAt,
|
|
111
|
+
updatedAt: args.run.createdAt,
|
|
106
112
|
embed: lastScreenshot
|
|
107
113
|
? {
|
|
108
114
|
kind: "screenshot",
|
|
@@ -174,11 +180,11 @@ function fanoutSubjectEvents(ctx, spec, view) {
|
|
|
174
180
|
const { publicTargetUrl, subject, session } = view;
|
|
175
181
|
const events = [];
|
|
176
182
|
const record = (event) => events.push(participantEvent(spec, event));
|
|
177
|
-
// Per-
|
|
178
|
-
if (args.
|
|
183
|
+
// Per-participant subject provenance (invariant 5).
|
|
184
|
+
if (args.plan.runner.subject.kind === "clone" && args.publicRepo) {
|
|
179
185
|
record({
|
|
180
186
|
id: nextEventId(`subject-${spec.planned.id}`),
|
|
181
|
-
at: args.createdAt,
|
|
187
|
+
at: args.run.createdAt,
|
|
182
188
|
level: "info",
|
|
183
189
|
type: "cua-lab.subject.provenance",
|
|
184
190
|
message: `Participant ${spec.planned.id}: ${args.dryRun
|
|
@@ -187,13 +193,13 @@ function fanoutSubjectEvents(ctx, spec, view) {
|
|
|
187
193
|
? session
|
|
188
194
|
? `subject cloned from ${args.publicRepo}@${subject.commit} and served at ${publicTargetUrl} in-sandbox`
|
|
189
195
|
: `subject cloned from ${args.publicRepo}@${subject.commit}; serving did not complete (see session error)`
|
|
190
|
-
: `subject clone attempted from ${args.publicRepo}; commit unresolved`} (subject env names: ${args.
|
|
196
|
+
: `subject clone attempted from ${args.publicRepo}; commit unresolved`} (subject env names: ${describeEnvNames(participantSubjectEnv(args.plan.runner.subject))}; values never persisted); state: ${describeSubjectState(subject.state, args.dryRun)}.`,
|
|
191
197
|
});
|
|
192
198
|
}
|
|
193
199
|
else if (subject.source === "local-tree") {
|
|
194
200
|
record({
|
|
195
201
|
id: nextEventId(`subject-${spec.planned.id}`),
|
|
196
|
-
at: args.createdAt,
|
|
202
|
+
at: args.run.createdAt,
|
|
197
203
|
level: "info",
|
|
198
204
|
type: "cua-lab.subject.provenance",
|
|
199
205
|
message: `Participant ${spec.planned.id}: ${args.dryRun
|
|
@@ -202,13 +208,13 @@ function fanoutSubjectEvents(ctx, spec, view) {
|
|
|
202
208
|
? session
|
|
203
209
|
? `subject packed (archiveSha256 ${subject.archiveSha256}${subject.dirty === true ? ", dirty working tree" : subject.dirty === false ? ", clean working tree" : ""}) and served at ${publicTargetUrl} in-sandbox`
|
|
204
210
|
: `subject packed (archiveSha256 ${subject.archiveSha256}); serving did not complete (see session error)`
|
|
205
|
-
: "subject local-tree packing attempted; archive digest unresolved"} (subject env names: ${args.
|
|
211
|
+
: "subject local-tree packing attempted; archive digest unresolved"} (subject env names: ${describeEnvNames(participantSubjectEnv(args.plan.runner.subject))}; values never persisted); state: ${describeSubjectState(subject.state, args.dryRun)}.`,
|
|
206
212
|
});
|
|
207
213
|
}
|
|
208
214
|
else {
|
|
209
215
|
record({
|
|
210
216
|
id: nextEventId(`subject-${spec.planned.id}`),
|
|
211
|
-
at: args.createdAt,
|
|
217
|
+
at: args.run.createdAt,
|
|
212
218
|
level: "info",
|
|
213
219
|
type: "cua-lab.subject.declared",
|
|
214
220
|
message: `Participant ${spec.planned.id}: subject app declared at ${publicTargetUrl} (loopback inside the participant's own desktop sandbox).`,
|
|
@@ -221,11 +227,11 @@ function fanoutOutcomeEvents(ctx, spec, view) {
|
|
|
221
227
|
const { outcome, session, desktopGeometry } = view;
|
|
222
228
|
const events = [];
|
|
223
229
|
const record = (event) => events.push(participantEvent(spec, event));
|
|
224
|
-
// Per-
|
|
230
|
+
// Per-participant session event.
|
|
225
231
|
if (session) {
|
|
226
232
|
record({
|
|
227
233
|
id: nextEventId(`session-${spec.planned.id}`),
|
|
228
|
-
at: args.createdAt,
|
|
234
|
+
at: args.run.createdAt,
|
|
229
235
|
level: session.status === "passed" ? "info" : "warn",
|
|
230
236
|
type: `cua-lab.session.${session.completionReason}`,
|
|
231
237
|
message: `Participant ${spec.planned.id} ${session.status}: ${session.reason}`,
|
|
@@ -234,7 +240,7 @@ function fanoutOutcomeEvents(ctx, spec, view) {
|
|
|
234
240
|
else if (args.inProgress === true && outcome === undefined) {
|
|
235
241
|
record({
|
|
236
242
|
id: nextEventId(`running-${spec.planned.id}`),
|
|
237
|
-
at: args.createdAt,
|
|
243
|
+
at: args.run.createdAt,
|
|
238
244
|
level: "info",
|
|
239
245
|
type: "cua-lab.session.running",
|
|
240
246
|
message: `Participant ${spec.planned.id}: live computer-use session is running; terminal evidence has not been written yet.`,
|
|
@@ -243,7 +249,7 @@ function fanoutOutcomeEvents(ctx, spec, view) {
|
|
|
243
249
|
else if (outcome?.skippedReason !== undefined) {
|
|
244
250
|
record({
|
|
245
251
|
id: nextEventId(`blocked-${spec.planned.id}`),
|
|
246
|
-
at: args.createdAt,
|
|
252
|
+
at: args.run.createdAt,
|
|
247
253
|
level: "warn",
|
|
248
254
|
type: "cua-lab.session.blocked",
|
|
249
255
|
message: `Participant ${spec.planned.id} ${outcome.skippedReason}.`,
|
|
@@ -252,7 +258,7 @@ function fanoutOutcomeEvents(ctx, spec, view) {
|
|
|
252
258
|
else if (outcome?.sessionError !== undefined) {
|
|
253
259
|
record({
|
|
254
260
|
id: nextEventId(`session-error-${spec.planned.id}`),
|
|
255
|
-
at: args.createdAt,
|
|
261
|
+
at: args.run.createdAt,
|
|
256
262
|
level: "error",
|
|
257
263
|
type: "cua-lab.session.error",
|
|
258
264
|
message: `Participant ${spec.planned.id}: ${outcome.sessionError}`,
|
|
@@ -261,7 +267,7 @@ function fanoutOutcomeEvents(ctx, spec, view) {
|
|
|
261
267
|
else {
|
|
262
268
|
record({
|
|
263
269
|
id: nextEventId(`contract-${spec.planned.id}`),
|
|
264
|
-
at: args.createdAt,
|
|
270
|
+
at: args.run.createdAt,
|
|
265
271
|
level: "info",
|
|
266
272
|
type: "cua-lab.contract.ready",
|
|
267
273
|
message: `Participant ${spec.planned.id}: dry-run contract participant ready; switch scenario.mode to live for a real desktop session.`,
|
|
@@ -270,14 +276,14 @@ function fanoutOutcomeEvents(ctx, spec, view) {
|
|
|
270
276
|
for (const warning of desktopGeometry.warnings ?? []) {
|
|
271
277
|
record({
|
|
272
278
|
id: nextEventId(`geometry-warning-${spec.planned.id}`),
|
|
273
|
-
at: args.createdAt,
|
|
279
|
+
at: args.run.createdAt,
|
|
274
280
|
level: "warn",
|
|
275
281
|
type: "cua-lab.geometry.warning",
|
|
276
282
|
message: warning,
|
|
277
283
|
});
|
|
278
284
|
}
|
|
279
|
-
// Persisted per-
|
|
280
|
-
// boundary this
|
|
285
|
+
// Persisted per-participant phase trail (real boot timing): one RunEvent per COMPLETED phase
|
|
286
|
+
// boundary this participant recorded (started events never persist here; they carry no durationMs).
|
|
281
287
|
for (const phase of outcome?.phaseRecords ?? []) {
|
|
282
288
|
record({
|
|
283
289
|
id: nextEventId(`phase-${spec.planned.id}-${phaseEventIdSuffix(phase.type)}`),
|
|
@@ -1,14 +1,7 @@
|
|
|
1
|
-
import type { CuaActorDescriptor } from "../../actors/registry.js";
|
|
2
|
-
import type { LabConfig } from "../../lab/types.js";
|
|
3
1
|
import type { ParticipantDesktop } from "./participant-desktop.js";
|
|
4
|
-
import type {
|
|
5
|
-
/** What an in-process desktop reads: the caller's executor
|
|
6
|
-
|
|
7
|
-
config: LabConfig;
|
|
8
|
-
descriptor: CuaActorDescriptor;
|
|
9
|
-
appUrl: string;
|
|
10
|
-
hooks: Pick<CuaActorLabHooks, "buildExecutor">;
|
|
11
|
-
}
|
|
2
|
+
import type { CuaParticipantDeps } from "./types.js";
|
|
3
|
+
/** What an in-process desktop reads: the caller's executor and the app it drives. */
|
|
4
|
+
type InProcessDesktopDeps = Pick<CuaParticipantDeps, "appUrl" | "inProcessExecutor">;
|
|
12
5
|
/**
|
|
13
6
|
* The caller's executor as a participant desktop. prepare acquires nothing; openSession builds the
|
|
14
7
|
* executor once; finalize is idempotent and has nothing to release; snapshot records no sandbox.
|
|
@@ -19,15 +19,9 @@ export function createInProcessDesktop(deps) {
|
|
|
19
19
|
if (!preparationStarted || opened || finalization)
|
|
20
20
|
throw new Error("The participant desktop must be prepared and may only be opened once, before finalization.");
|
|
21
21
|
opened = true;
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
const executor = await buildExecutor({
|
|
26
|
-
config: deps.config,
|
|
27
|
-
actor: deps.descriptor,
|
|
28
|
-
appUrl: deps.appUrl,
|
|
29
|
-
});
|
|
30
|
-
return { executor };
|
|
22
|
+
if (deps.inProcessExecutor === undefined)
|
|
23
|
+
throw new Error("The in-process route needs RunLabOptions.inProcess.");
|
|
24
|
+
return { executor: await deps.inProcessExecutor(deps.appUrl) };
|
|
31
25
|
},
|
|
32
26
|
finalize() {
|
|
33
27
|
return (finalization ??= Promise.resolve());
|
|
@@ -2,7 +2,8 @@ import type { ActorTokenUsage, ActorTraceItem } from "../../actors/contract.js";
|
|
|
2
2
|
import type { CuaLiveMetadata } from "../../actors/computer-use/loop.js";
|
|
3
3
|
import { type ObserverResult } from "../../observer/render.js";
|
|
4
4
|
import type { RunBundle } from "../../run/bundle.js";
|
|
5
|
-
import type {
|
|
5
|
+
import type { RunLabHomes } from "../../lab/run-lab-homes.js";
|
|
6
|
+
import type { DesktopParticipantRun } from "./types.js";
|
|
6
7
|
export interface LiveTraceFlush {
|
|
7
8
|
/** Record a participant's recorded-so-far items; the bundle rewrite follows on the flush
|
|
8
9
|
* schedule. */
|
|
@@ -11,7 +12,7 @@ export interface LiveTraceFlush {
|
|
|
11
12
|
stop: () => Promise<void>;
|
|
12
13
|
}
|
|
13
14
|
/**
|
|
14
|
-
* Incremental live flush (#441): as each
|
|
15
|
+
* Incremental live flush (#441): as each participant's loop reports its recorded-so-far items,
|
|
15
16
|
* rewrite the in-progress bundle with per-stream `liveActor` partials so the attached
|
|
16
17
|
* Observer's 5s poll sees the timeline grow. Throttled (one write per interval, trailing
|
|
17
18
|
* write guaranteed). `write` is the run's `writeSnapshot`, which serializes writes and refuses
|
|
@@ -27,12 +28,13 @@ export declare function startLiveTraceFlush(args: {
|
|
|
27
28
|
write: (bundle: RunBundle) => Promise<void>;
|
|
28
29
|
}): LiveTraceFlush;
|
|
29
30
|
/**
|
|
30
|
-
* The live desktop views (runtime stream URLs)
|
|
31
|
+
* The live desktop views (runtime stream URLs) participants report, attached to whichever Observer shows
|
|
31
32
|
* the run. The URLs carry auth, so they live in memory and on the Observer result, never in run
|
|
32
33
|
* artifacts.
|
|
33
34
|
*/
|
|
34
|
-
export declare function trackRuntimeStreams(
|
|
35
|
-
|
|
35
|
+
export declare function trackRuntimeStreams(onStream: RunLabHomes["onStream"] | undefined): {
|
|
36
|
+
/** Records each stream for the Observer, after the caller's onStream. */
|
|
37
|
+
onStream: NonNullable<RunLabHomes["onStream"]>;
|
|
36
38
|
/** From now on, keep this live Observer's stream list current. */
|
|
37
39
|
showIn: (observer: ObserverResult & {
|
|
38
40
|
ok: true;
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { attachObserverRuntimeStreamUrls } from "../../observer/render.js";
|
|
2
2
|
import {} from "../../observer/run-routes.js";
|
|
3
|
-
import { HOOK_MEMBERS, withHookOverrides } from "../../lab/bag-overrides.js";
|
|
4
3
|
/**
|
|
5
|
-
* Incremental live flush (#441): as each
|
|
4
|
+
* Incremental live flush (#441): as each participant's loop reports its recorded-so-far items,
|
|
6
5
|
* rewrite the in-progress bundle with per-stream `liveActor` partials so the attached
|
|
7
6
|
* Observer's 5s poll sees the timeline grow. Throttled (one write per interval, trailing
|
|
8
7
|
* write guaranteed). `write` is the run's `writeSnapshot`, which serializes writes and refuses
|
|
@@ -12,12 +11,12 @@ import { HOOK_MEMBERS, withHookOverrides } from "../../lab/bag-overrides.js";
|
|
|
12
11
|
export function startLiveTraceFlush(args) {
|
|
13
12
|
const { bundle, participantRuns, model, write } = args;
|
|
14
13
|
const streamIdByParticipant = new Map(participantRuns.map((spec) => [spec.planned.id, spec.streamId]));
|
|
15
|
-
// The persona each
|
|
14
|
+
// The persona each participant is running, so the live flush can say who is in it.
|
|
16
15
|
const personaByStream = new Map(participantRuns
|
|
17
16
|
.map((spec) => [spec.streamId, spec.persona?.id])
|
|
18
17
|
.filter((entry) => typeof entry[1] === "string"));
|
|
19
18
|
const liveItemsByStream = new Map();
|
|
20
|
-
// Running token usage per
|
|
19
|
+
// Running token usage per participant, so a run in flight can price itself instead of reporting the
|
|
21
20
|
// cost as unknown until the moment it ends.
|
|
22
21
|
const liveUsageByStream = new Map();
|
|
23
22
|
const liveMetadataByStream = new Map();
|
|
@@ -43,8 +42,8 @@ export function startLiveTraceFlush(args) {
|
|
|
43
42
|
liveActor: {
|
|
44
43
|
schema: "humanish.live-actor.v1",
|
|
45
44
|
updatedAt,
|
|
46
|
-
// WHO
|
|
47
|
-
// watching a live run can only name the
|
|
45
|
+
// WHO this participant is, carried while the run is live. Without it a
|
|
46
|
+
// surface watching a live run can only name the participant id, and "CUA browser — observer-live-
|
|
48
47
|
// check" is the harness talking about itself where the participant should be.
|
|
49
48
|
...(personaByStream.get(stream.id) === undefined
|
|
50
49
|
? {}
|
|
@@ -114,34 +113,27 @@ export function startLiveTraceFlush(args) {
|
|
|
114
113
|
return { flush, stop };
|
|
115
114
|
}
|
|
116
115
|
/**
|
|
117
|
-
* The live desktop views (runtime stream URLs)
|
|
116
|
+
* The live desktop views (runtime stream URLs) participants report, attached to whichever Observer shows
|
|
118
117
|
* the run. The URLs carry auth, so they live in memory and on the Observer result, never in run
|
|
119
118
|
* artifacts.
|
|
120
119
|
*/
|
|
121
|
-
export function trackRuntimeStreams(
|
|
120
|
+
export function trackRuntimeStreams(onStream) {
|
|
122
121
|
let liveObserver;
|
|
123
122
|
const urls = [];
|
|
124
123
|
return {
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
await hooks.onRuntimeStreamEnded?.(stream);
|
|
135
|
-
// Mark, never remove: the tile needs to KNOW the live view ended (and say so) rather than
|
|
136
|
-
// have the stream silently vanish from the overlay (#357).
|
|
137
|
-
for (const entry of urls) {
|
|
138
|
-
if (entry.streamId === stream.streamId)
|
|
124
|
+
onStream: async (event) => {
|
|
125
|
+
await onStream?.(event);
|
|
126
|
+
if (event.type === "ready")
|
|
127
|
+
urls.push({ streamId: event.streamId, url: event.url });
|
|
128
|
+
// Mark, never remove: the tile needs to KNOW the live view ended (and say so) rather than
|
|
129
|
+
// have the stream silently vanish from the overlay (#357).
|
|
130
|
+
else
|
|
131
|
+
for (const entry of urls)
|
|
132
|
+
if (entry.streamId === event.streamId)
|
|
139
133
|
entry.ended = true;
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
},
|
|
144
|
-
}),
|
|
134
|
+
if (liveObserver)
|
|
135
|
+
attachObserverRuntimeStreamUrls(liveObserver, urls);
|
|
136
|
+
},
|
|
145
137
|
showIn: (observer) => {
|
|
146
138
|
liveObserver = observer;
|
|
147
139
|
},
|
|
@@ -1,23 +1,24 @@
|
|
|
1
1
|
// The computer-use run's live phase: the in-progress bundle and its live-trace flush, email
|
|
2
|
-
// receiving, the
|
|
2
|
+
// receiving, the participants themselves, and the drain of an operator-hosted inbox.
|
|
3
3
|
import { prepareReceivingRun } from "../../comms/receiving-runtime.js";
|
|
4
4
|
import { liveObserverResult } from "../../observer/live.js";
|
|
5
|
-
import {
|
|
6
|
-
import { runAllCuaParticipants } from "./
|
|
5
|
+
import { pricedModel } from "../../lab/plan-base.js";
|
|
6
|
+
import { runAllCuaParticipants } from "./participant-execution.js";
|
|
7
7
|
import { startLiveTraceFlush } from "./live-flush.js";
|
|
8
8
|
import { drainExternalComms } from "./external-comms.js";
|
|
9
9
|
import { buildCuaRunBundle, judgeComputerUseRun } from "./bundle.js";
|
|
10
|
-
import {} from "./types.js";
|
|
10
|
+
import { participantSubjectEnv } from "./types.js";
|
|
11
11
|
/**
|
|
12
12
|
* Runs the participants (a dry run runs none). Returns the refusal when real email setup fails, or
|
|
13
13
|
* the participant outcomes and the warnings the finish records.
|
|
14
14
|
*/
|
|
15
15
|
export async function runLabParticipants(setup, participants) {
|
|
16
|
-
const { plan, input,
|
|
17
|
-
const { participantRuns, participantPlan,
|
|
16
|
+
const { plan, input, cwd, streams, descriptor, run } = setup;
|
|
17
|
+
const { participantRuns, participantPlan, bundleBase } = setup;
|
|
18
18
|
const { env, knownSecretValues, deps, liveTrace, externalComms, inProgress, fail } = participants;
|
|
19
19
|
const { dryRun } = plan;
|
|
20
|
-
const
|
|
20
|
+
const inProcess = plan.runner.desktop === "in-process";
|
|
21
|
+
const subjectEnvNames = [...participantSubjectEnv(plan.runner.subject)];
|
|
21
22
|
const { runId, paths: runPaths } = run;
|
|
22
23
|
// A live run writes what it is doing AS IT DOES IT, whether or not anyone is currently watching.
|
|
23
24
|
// This used to be gated on `options.onObserverReady` — the interactive Observer callback — so a
|
|
@@ -46,14 +47,14 @@ export async function runLabParticipants(setup, participants) {
|
|
|
46
47
|
streams.showIn(liveObserver);
|
|
47
48
|
if (input.onObserverReady)
|
|
48
49
|
await input.onObserverReady(liveObserver);
|
|
49
|
-
// Incremental live flush (#441): as each
|
|
50
|
+
// Incremental live flush (#441): as each participant's loop reports its recorded-so-far items,
|
|
50
51
|
// rewrite the in-progress bundle with per-stream `liveActor` partials so the attached
|
|
51
52
|
// Observer's 5s poll sees the timeline grow. The run refuses any snapshot once the final
|
|
52
53
|
// write began; the route stops the flush timer on every exit below.
|
|
53
54
|
const liveFlush = startLiveTraceFlush({
|
|
54
55
|
bundle: inProgressBundle,
|
|
55
56
|
participantRuns: participantRuns,
|
|
56
|
-
model:
|
|
57
|
+
model: pricedModel(plan.runner.brain),
|
|
57
58
|
write: (bundle) => run.writeSnapshot(bundle),
|
|
58
59
|
});
|
|
59
60
|
liveTrace.flush = liveFlush.flush;
|
|
@@ -96,12 +97,12 @@ export async function runLabParticipants(setup, participants) {
|
|
|
96
97
|
};
|
|
97
98
|
}
|
|
98
99
|
}
|
|
99
|
-
// Run
|
|
100
|
+
// Run the participants (dry-run runs none). In-process is always one.
|
|
100
101
|
let outcomes;
|
|
101
102
|
let failFastReason;
|
|
102
103
|
try {
|
|
103
104
|
if (!dryRun)
|
|
104
|
-
({ outcomes, failFastReason } = await runAllCuaParticipants(participantRuns, deps, participantPlan,
|
|
105
|
+
({ outcomes, failFastReason } = await runAllCuaParticipants(participantRuns, deps, participantPlan, inProcess));
|
|
105
106
|
}
|
|
106
107
|
finally {
|
|
107
108
|
try {
|
|
@@ -110,7 +111,7 @@ export async function runLabParticipants(setup, participants) {
|
|
|
110
111
|
catch {
|
|
111
112
|
receivingWarnings.push("Email finalization could not complete. Inspect humanish comms recover; provider cleanup remains unresolved.");
|
|
112
113
|
}
|
|
113
|
-
// Stop the flush timer on every exit, including a throw from the
|
|
114
|
+
// Stop the flush timer on every exit, including a throw from the participants.
|
|
114
115
|
await liveTrace.stop?.();
|
|
115
116
|
}
|
|
116
117
|
const externalCommsWarnings = !dryRun && externalComms && outcomes !== undefined
|
|
@@ -121,7 +122,7 @@ export async function runLabParticipants(setup, participants) {
|
|
|
121
122
|
runPaths,
|
|
122
123
|
participantRuns: participantRuns,
|
|
123
124
|
outcomes,
|
|
124
|
-
|
|
125
|
+
knownSecretValues,
|
|
125
126
|
})
|
|
126
127
|
: [];
|
|
127
128
|
return {
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type { LabConfig } from "../../lab/types.js";
|
|
2
2
|
import { type LocalTreeArchive } from "../../subject/local-tree-archive.js";
|
|
3
|
-
import {
|
|
3
|
+
import type { LabDeps } from "../../lab/lab-deps.js";
|
|
4
4
|
/**
|
|
5
5
|
* Pack the working tree for a local-tree run and report what left the host on stderr, by counts
|
|
6
6
|
* and digest only, never paths or file names.
|
|
7
7
|
*/
|
|
8
|
-
export declare function packRunLocalTree(
|
|
8
|
+
export declare function packRunLocalTree(deps: LabDeps, config: {
|
|
9
9
|
readonly subject: Pick<LabConfig["subject"], "localTree">;
|
|
10
10
|
}, cwd: string): Promise<{
|
|
11
11
|
archive: LocalTreeArchive;
|
|
@@ -14,7 +14,7 @@ export declare function packRunLocalTree(hooks: CuaActorLabHooks, config: {
|
|
|
14
14
|
/**
|
|
15
15
|
* Default local-tree packing implementation: createLocalTreeArchive(root, opts) on the host,
|
|
16
16
|
* then a single read of the produced archive file into an ArrayBuffer for upload. The DI seam
|
|
17
|
-
* (
|
|
17
|
+
* (LabDeps.packLocalTree) overrides this in deterministic tests so they never require
|
|
18
18
|
* tar/git.
|
|
19
19
|
*/
|
|
20
20
|
export declare function defaultPackLocalTree(args: {
|
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
// Packing the project's working tree once per local-tree run, on the host, for every
|
|
1
|
+
// Packing the project's working tree once per local-tree run, on the host, for every participant to upload.
|
|
2
2
|
import { readFile, rm } from "node:fs/promises";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { createLocalTreeArchive } from "../../subject/local-tree-archive.js";
|
|
5
|
-
import {} from "./types.js";
|
|
6
5
|
/**
|
|
7
6
|
* Pack the working tree for a local-tree run and report what left the host on stderr, by counts
|
|
8
7
|
* and digest only, never paths or file names.
|
|
9
8
|
*/
|
|
10
|
-
export async function packRunLocalTree(
|
|
11
|
-
const packLocalTree =
|
|
9
|
+
export async function packRunLocalTree(deps, config, cwd) {
|
|
10
|
+
const packLocalTree = deps.packLocalTree ?? defaultPackLocalTree;
|
|
12
11
|
const packed = await packLocalTree({
|
|
13
12
|
root: cwd,
|
|
14
13
|
...(config.subject.localTree?.exclude === undefined
|
|
@@ -25,7 +24,7 @@ export async function packRunLocalTree(hooks, config, cwd) {
|
|
|
25
24
|
/**
|
|
26
25
|
* Default local-tree packing implementation: createLocalTreeArchive(root, opts) on the host,
|
|
27
26
|
* then a single read of the produced archive file into an ArrayBuffer for upload. The DI seam
|
|
28
|
-
* (
|
|
27
|
+
* (LabDeps.packLocalTree) overrides this in deterministic tests so they never require
|
|
29
28
|
* tar/git.
|
|
30
29
|
*/
|
|
31
30
|
export async function defaultPackLocalTree(args) {
|