humanish 0.106.1 → 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 -4
- package/ARCHITECTURE.md +17 -16
- package/CHANGELOG.md +14 -0
- package/CONTEXT.md +42 -39
- package/CONTRIBUTING.md +8 -8
- 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 +30 -3
- package/dist/actors/codex/qualified-versions.js +50 -5
- 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 +9 -7
- 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.js +20 -20
- 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 +0 -2
- package/dist/lab/plan-base.js +6 -4
- package/dist/lab/plan-participants.d.ts +5 -5
- package/dist/lab/plan-participants.js +2 -2
- package/dist/lab/plan-types.d.ts +22 -4
- 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/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} +12 -11
- 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 +49 -25
- 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 +52 -60
- package/dist/routes/computer-use/preflight.d.ts +3 -5
- package/dist/routes/computer-use/preflight.js +20 -16
- 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 -14
- package/dist/routes/computer-use/setup.js +96 -72
- 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 -210
- package/dist/routes/computer-use/types.js +13 -5
- 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 +9 -5
- 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} +43 -48
- 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 +46 -40
- 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 +3 -2
- package/dist/routes/terminal/live-sandbox.js +20 -20
- 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 +3 -3
- package/dist/routes/terminal/sandbox.js +9 -9
- 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 +6 -0
- package/dist/run/reclaim.js +13 -3
- 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/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.js +1 -1
- package/dist/substrates/e2b/sdk.js +2 -2
- 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 +36 -2
- 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
package/dist/lab/doctor.d.ts
CHANGED
|
@@ -1,21 +1,48 @@
|
|
|
1
1
|
import { type LocalRuntimeStatus } from "../substrates/local/runtime.js";
|
|
2
2
|
import type { LabConfig } from "./types.js";
|
|
3
|
-
import type {
|
|
3
|
+
import type { PlanResult } from "./plan-types.js";
|
|
4
4
|
import type { DetectedLocalAgent } from "../actors/local-agent/cli.js";
|
|
5
|
+
import type { ReasoningEffort } from "../actors/reasoning-effort.js";
|
|
5
6
|
import type { DoctorResult } from "../cli/doctor.js";
|
|
7
|
+
import { type CodexInstallation } from "../actors/codex/qualified-versions.js";
|
|
8
|
+
import type { RefusedCodexExecutable } from "../actors/codex/restricted-executable.js";
|
|
6
9
|
type Check = DoctorResult["checks"][number];
|
|
7
|
-
/**
|
|
10
|
+
/**
|
|
11
|
+
* Read-only Codex account readiness. An unadmitted CLI also reports the release it found, and an
|
|
12
|
+
* unavailable one the file humanish found and turned down.
|
|
13
|
+
*/
|
|
8
14
|
type CodexReadiness = {
|
|
9
15
|
ready: boolean;
|
|
10
16
|
errorCode: string | null;
|
|
11
17
|
detectedCliVersion?: string;
|
|
18
|
+
refusedExecutable?: RefusedCodexExecutable;
|
|
19
|
+
/** Where the `codex` on `PATH` was installed, for the command that replaces it. */
|
|
20
|
+
installation?: CodexInstallation;
|
|
21
|
+
/** How the release's app-server schema differs from the fields humanish reads. */
|
|
22
|
+
protocolIncompatibilities?: readonly string[];
|
|
23
|
+
/** Schema values beyond the baseline, recorded by a launch that passed. */
|
|
24
|
+
protocolAdditions?: readonly string[];
|
|
12
25
|
};
|
|
26
|
+
/** What doctor's hosted Codex participant check found: a readiness result and what it admitted. */
|
|
27
|
+
type HostedCodexReadiness = CodexReadiness & {
|
|
28
|
+
cliVersion?: string;
|
|
29
|
+
resolvedModel?: string;
|
|
30
|
+
authentication?: "chatgpt-account" | "api-key";
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* The hosted participant check: the operator-auth launch to an ephemeral thread, with no turn,
|
|
34
|
+
* using the lab's declared model and reasoning effort as a run would.
|
|
35
|
+
*/
|
|
36
|
+
declare function hostedCodexReadiness(env: NodeJS.ProcessEnv, actor: {
|
|
37
|
+
model?: string;
|
|
38
|
+
reasoningEffort?: ReasoningEffort;
|
|
39
|
+
}): Promise<HostedCodexReadiness>;
|
|
13
40
|
/** Shared read-only Codex account check for local participants in doctor and the TUI. */
|
|
14
41
|
export declare function localCodexParticipantCheck(args: {
|
|
15
42
|
env: NodeJS.ProcessEnv;
|
|
16
43
|
readiness?: (env: NodeJS.ProcessEnv) => Promise<CodexReadiness>;
|
|
17
44
|
}): Promise<Check>;
|
|
18
|
-
interface LabSetupCheckArgs {
|
|
45
|
+
export interface LabSetupCheckArgs {
|
|
19
46
|
cwd: string;
|
|
20
47
|
lab: string;
|
|
21
48
|
env: NodeJS.ProcessEnv;
|
|
@@ -24,16 +51,24 @@ interface LabSetupCheckArgs {
|
|
|
24
51
|
/** Internal read-only qualification seam; never a participant/model request. */
|
|
25
52
|
localRuntimeReadiness?: () => Promise<LocalRuntimeStatus>;
|
|
26
53
|
codexAnalysisReadiness?: (env: NodeJS.ProcessEnv) => Promise<CodexReadiness>;
|
|
54
|
+
/** The hosted Codex participant's operator handshake; tests replace it. */
|
|
55
|
+
codexParticipantReadiness?: typeof hostedCodexReadiness;
|
|
27
56
|
}
|
|
28
|
-
/**
|
|
57
|
+
/**
|
|
58
|
+
* Setup checks only: no model turn, browser or desktop creation. CLI startup may use the network.
|
|
59
|
+
* `keys` are the keys a live run requires. `reads` are the provider keys the lab is known to read,
|
|
60
|
+
* required or not; it is undefined when that is unknown: the lab does not plan, or a declared
|
|
61
|
+
* scorer's host code may read any key.
|
|
62
|
+
*/
|
|
29
63
|
export declare function labSetupChecks(args: LabSetupCheckArgs): Promise<{
|
|
30
64
|
desktop: boolean;
|
|
31
65
|
keys: string[];
|
|
66
|
+
reads?: ReadonlySet<string>;
|
|
32
67
|
checks: Check[];
|
|
33
68
|
}>;
|
|
34
|
-
/**
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
69
|
+
/**
|
|
70
|
+
* The lab planned with no run options, so its own scenario mode decides dry or live. Doctor and the
|
|
71
|
+
* TUI read a live run's keys and subject env from this plan's requirements.
|
|
72
|
+
*/
|
|
73
|
+
export declare function planCliRun(config: LabConfig, cwd: string): Promise<PlanResult>;
|
|
39
74
|
export {};
|
package/dist/lab/doctor.js
CHANGED
|
@@ -1,25 +1,107 @@
|
|
|
1
|
+
import path from "node:path";
|
|
1
2
|
import { isLocalBrowserLab } from "../substrates/local/runtime-config.js";
|
|
2
3
|
import { localRuntimeStatus } from "../substrates/local/runtime.js";
|
|
4
|
+
import { keyNamesOf, requiredKeys, requiredSubjectEnv } from "./requirements.js";
|
|
5
|
+
import { protocolAdditionsWarning, protocolIncompatibilityMessage, } from "../actors/codex/protocol-compat.js";
|
|
3
6
|
import { automaticAnalysisBudget } from "../analysis/automatic-config.js";
|
|
4
7
|
import { externalCatchHealthy } from "../comms/sandbox-catch.js";
|
|
5
8
|
import { receivingRequiredKey } from "../comms/setup.js";
|
|
6
|
-
import { codexVersionRecovery } from "../actors/codex/qualified-versions.js";
|
|
7
|
-
/**
|
|
9
|
+
import { classifyCodexInstallation, codexInstallAdvice, codexVersionRecovery, } from "../actors/codex/qualified-versions.js";
|
|
10
|
+
/** A ready row's message, with the schema values the launch recorded. */
|
|
11
|
+
function readyMessage(message, readiness) {
|
|
12
|
+
const additions = protocolAdditionsWarning(readiness.cliVersion, readiness.protocolAdditions);
|
|
13
|
+
return additions === undefined ? message : `${message} ${additions}`;
|
|
14
|
+
}
|
|
15
|
+
/** npm's global prefix (`npm prefix -g`), or undefined when npm does not answer. */
|
|
16
|
+
async function npmGlobalPrefix(env) {
|
|
17
|
+
const { execFile } = await import("node:child_process");
|
|
18
|
+
return new Promise((resolve) => {
|
|
19
|
+
execFile("npm", ["prefix", "-g"], { env, timeout: 5000 }, (error, stdout) => {
|
|
20
|
+
const prefix = String(stdout).trim();
|
|
21
|
+
resolve(error === null && path.isAbsolute(prefix) ? prefix : undefined);
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
/** Where the `codex` on `PATH` was installed; npm's prefix is read only when not project-local. */
|
|
26
|
+
async function codexInstallation(env) {
|
|
27
|
+
const { foundCodexExecutable } = await import("../actors/codex/restricted-executable.js");
|
|
28
|
+
const found = await foundCodexExecutable(env).catch(() => undefined);
|
|
29
|
+
if (found === undefined)
|
|
30
|
+
return undefined;
|
|
31
|
+
const local = classifyCodexInstallation(found, undefined);
|
|
32
|
+
return local.kind === "project"
|
|
33
|
+
? local
|
|
34
|
+
: classifyCodexInstallation(found, await npmGlobalPrefix(env));
|
|
35
|
+
}
|
|
36
|
+
/** The account check doctor and the TUI share: the isolated launch, with recovery details. */
|
|
8
37
|
async function codexAccountReadiness(env) {
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
38
|
+
const checked = await (await import("../analysis/restricted-codex.js")).checkRestrictedCodexAnalysisReadiness({ timeoutMs: 5000 }, { env });
|
|
39
|
+
return withCodexRecoveryDetails(env, checked);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* The hosted participant check: the operator-auth launch to an ephemeral thread, with no turn,
|
|
43
|
+
* using the lab's declared model and reasoning effort as a run would.
|
|
44
|
+
*/
|
|
45
|
+
async function hostedCodexReadiness(env, actor) {
|
|
46
|
+
const { checkRestrictedCodexParticipantReadiness } = await import("../actors/codex/restricted-participant.js");
|
|
47
|
+
const checked = await checkRestrictedCodexParticipantReadiness({
|
|
48
|
+
session: { env },
|
|
49
|
+
...(actor.model === undefined ? {} : { model: actor.model }),
|
|
50
|
+
...(actor.reasoningEffort === undefined ? {} : { reasoningEffort: actor.reasoningEffort }),
|
|
51
|
+
});
|
|
52
|
+
return checked.ready
|
|
53
|
+
? checked
|
|
54
|
+
: { ...checked, ...(await withCodexRecoveryDetails(env, checked)) };
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Adds what the recovery line names to a failed check. An unadmitted CLI gets its release, an
|
|
58
|
+
* unavailable one the file humanish turned down, and both where the binary came from.
|
|
59
|
+
*/
|
|
60
|
+
async function withCodexRecoveryDetails(env, checked) {
|
|
61
|
+
if (checked.errorCode !== "codex_unavailable" &&
|
|
62
|
+
checked.errorCode !== "codex_unsupported_version" &&
|
|
63
|
+
checked.errorCode !== "codex_incompatible_release")
|
|
64
|
+
return checked;
|
|
65
|
+
const installation = await codexInstallation(env);
|
|
66
|
+
const readiness = installation === undefined ? checked : { ...checked, installation };
|
|
67
|
+
if (readiness.errorCode === "codex_unavailable") {
|
|
68
|
+
const { refusedCodexExecutable } = await import("../actors/codex/restricted-executable.js");
|
|
69
|
+
const refused = await refusedCodexExecutable(env).catch(() => undefined);
|
|
70
|
+
return refused === undefined ? readiness : { ...readiness, refusedExecutable: refused };
|
|
71
|
+
}
|
|
12
72
|
const { detectRestrictedCodexCliVersion } = await import("../actors/codex/restricted-session.js");
|
|
13
73
|
const detected = await detectRestrictedCodexCliVersion({ timeoutMs: 5000 }, { env }).catch(() => undefined);
|
|
14
74
|
// An admitted release here means app-server reported a different one; name what --version says.
|
|
15
75
|
const version = detected?.cliVersion ?? detected?.detectedVersion;
|
|
16
76
|
return version === undefined ? readiness : { ...readiness, detectedCliVersion: version };
|
|
17
77
|
}
|
|
18
|
-
/**
|
|
78
|
+
/**
|
|
79
|
+
* What to do about a Codex readiness failure, one line per code: an unadmitted CLI gets its exact
|
|
80
|
+
* install command, a missing login `codex login`, and an unavailable CLI the file humanish turned
|
|
81
|
+
* down and why. Other codes get `fallback`.
|
|
82
|
+
*/
|
|
19
83
|
function codexRecovery(readiness, fallback) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
84
|
+
switch (readiness.errorCode) {
|
|
85
|
+
case "codex_unsupported_version":
|
|
86
|
+
return codexVersionRecovery(readiness.detectedCliVersion, readiness.installation);
|
|
87
|
+
case "codex_incompatible_release":
|
|
88
|
+
return `${protocolIncompatibilityMessage(readiness.detectedCliVersion, readiness.protocolIncompatibilities ?? [])} ${codexInstallAdvice(readiness.installation)} Then sign in with a ChatGPT account (\`codex login\`).`;
|
|
89
|
+
case "codex_login_required":
|
|
90
|
+
return "Codex is installed but not signed in. Run `codex login` and sign in with a ChatGPT account.";
|
|
91
|
+
case "codex_unsupported_auth":
|
|
92
|
+
return "Codex is signed in without a ChatGPT account, for example with an API key. Run `codex logout`, then `codex login` with a ChatGPT account.";
|
|
93
|
+
case "codex_unavailable": {
|
|
94
|
+
const refused = readiness.refusedExecutable;
|
|
95
|
+
const found = refused === undefined
|
|
96
|
+
? "humanish could not start the Codex CLI."
|
|
97
|
+
: refused.path === undefined
|
|
98
|
+
? `Codex is unavailable: ${refused.reason}.`
|
|
99
|
+
: `humanish found \`${refused.path}\` and cannot run it: ${refused.reason}.`;
|
|
100
|
+
return `${found} ${codexInstallAdvice(readiness.installation)} Then sign in with a ChatGPT account (\`codex login\`).`;
|
|
101
|
+
}
|
|
102
|
+
default:
|
|
103
|
+
return fallback;
|
|
104
|
+
}
|
|
23
105
|
}
|
|
24
106
|
/** Shared read-only Codex account check for local participants in doctor and the TUI. */
|
|
25
107
|
export async function localCodexParticipantCheck(args) {
|
|
@@ -28,11 +110,16 @@ export async function localCodexParticipantCheck(args) {
|
|
|
28
110
|
name: "local participant authentication",
|
|
29
111
|
ok: readiness.ready,
|
|
30
112
|
message: readiness.ready
|
|
31
|
-
? "Qualified Codex CLI and ChatGPT login are ready for restricted local browser participants. No E2B or model API key is required; inference is remote, and model access and account quota remain untested."
|
|
113
|
+
? readyMessage("Qualified Codex CLI and ChatGPT login are ready for restricted local browser participants. No E2B or model API key is required; inference is remote, and model access and account quota remain untested.", readiness)
|
|
32
114
|
: `Local Codex participant setup is unavailable (${readiness.errorCode}). ${codexRecovery(readiness, "Install the supported Codex CLI version and sign in with a ChatGPT account.")} No API fallback is used.`,
|
|
33
115
|
};
|
|
34
116
|
}
|
|
35
|
-
/**
|
|
117
|
+
/**
|
|
118
|
+
* Setup checks only: no model turn, browser or desktop creation. CLI startup may use the network.
|
|
119
|
+
* `keys` are the keys a live run requires. `reads` are the provider keys the lab is known to read,
|
|
120
|
+
* required or not; it is undefined when that is unknown: the lab does not plan, or a declared
|
|
121
|
+
* scorer's host code may read any key.
|
|
122
|
+
*/
|
|
36
123
|
export async function labSetupChecks(args) {
|
|
37
124
|
const { resolveLabManifest } = await import("./discover.js");
|
|
38
125
|
const { resolveLabDryRun, routeOf } = await import("./plan.js");
|
|
@@ -53,7 +140,7 @@ export async function labSetupChecks(args) {
|
|
|
53
140
|
},
|
|
54
141
|
];
|
|
55
142
|
if (dryRun)
|
|
56
|
-
return { desktop: false, keys: [], checks };
|
|
143
|
+
return { desktop: false, keys: [], reads: new Set(), checks };
|
|
57
144
|
const unsupported = unsupportedCliRoute(config, route);
|
|
58
145
|
if (unsupported)
|
|
59
146
|
return {
|
|
@@ -61,7 +148,17 @@ export async function labSetupChecks(args) {
|
|
|
61
148
|
keys: [],
|
|
62
149
|
checks: [...checks, { name: "live route", ok: false, message: unsupported }],
|
|
63
150
|
};
|
|
64
|
-
const
|
|
151
|
+
const planned = await planCliRun(config, args.cwd);
|
|
152
|
+
if (!planned.ok)
|
|
153
|
+
return {
|
|
154
|
+
desktop: false,
|
|
155
|
+
keys: [],
|
|
156
|
+
checks: [...checks, { name: "live route", ok: false, message: planned.refusal.message }],
|
|
157
|
+
};
|
|
158
|
+
const requirements = planned.planned.plan.requirements;
|
|
159
|
+
const keys = requiredKeys(requirements, args.keyPresent);
|
|
160
|
+
// This flag controls the hosted desktop SDK check as well as its API key.
|
|
161
|
+
const desktop = keys.includes("E2B_API_KEY");
|
|
65
162
|
const local = isLocalBrowserLab(config);
|
|
66
163
|
// One account check, shared by the local participant row and the Codex analysis row.
|
|
67
164
|
let accountReadiness;
|
|
@@ -73,12 +170,15 @@ export async function labSetupChecks(args) {
|
|
|
73
170
|
checks.push(...(await participantChecks(config, route, keys, local, args, checkAccount)));
|
|
74
171
|
if (route === "scripted")
|
|
75
172
|
checks.push(await scriptedBrowserCheck());
|
|
76
|
-
checks.push(...subjectEnvChecks(
|
|
173
|
+
checks.push(...subjectEnvChecks(requiredSubjectEnv(requirements), args));
|
|
77
174
|
const analysis = automaticAnalysisBudget(config.review?.analysis, route);
|
|
78
175
|
if (analysis)
|
|
79
176
|
checks.push(await analysisCheck(analysis, args, checkAccount));
|
|
80
177
|
checks.push(checkScope(analysis));
|
|
81
|
-
|
|
178
|
+
const reads = config.review?.scorer === undefined
|
|
179
|
+
? new Set([...keyNamesOf(planned.planned.plan), ...keys])
|
|
180
|
+
: undefined;
|
|
181
|
+
return { desktop, keys, ...(reads === undefined ? {} : { reads }), checks };
|
|
82
182
|
}
|
|
83
183
|
/** A local browser study's runtime and, with an external catch, its captured inbox. */
|
|
84
184
|
async function localBrowserChecks(config, args) {
|
|
@@ -137,6 +237,10 @@ async function participantChecks(config, route, keys, local, args, checkAccount)
|
|
|
137
237
|
const agent = args.agents.find((entry) => entry.id === choice);
|
|
138
238
|
if (local)
|
|
139
239
|
return [await localCodexParticipantCheck({ env: args.env, readiness: checkAccount })];
|
|
240
|
+
// A signed-in hosted Codex gets the operator handshake; its sign-in status alone does not show
|
|
241
|
+
// that the operator's config, release and model admit a launch.
|
|
242
|
+
if (choice === "codex" && agent?.authStatus === "authenticated")
|
|
243
|
+
return [await hostedCodexParticipantCheck(args, config.actors[0])];
|
|
140
244
|
return [
|
|
141
245
|
{
|
|
142
246
|
name: "local participant authentication",
|
|
@@ -149,6 +253,24 @@ async function participantChecks(config, route, keys, local, args, checkAccount)
|
|
|
149
253
|
},
|
|
150
254
|
];
|
|
151
255
|
}
|
|
256
|
+
/** The hosted Codex participant row: what the operator handshake admitted, or how to fix it. */
|
|
257
|
+
async function hostedCodexParticipantCheck(args, actor) {
|
|
258
|
+
const declared = {
|
|
259
|
+
...(actor?.model === undefined ? {} : { model: actor.model }),
|
|
260
|
+
...(actor?.reasoningEffort === undefined ? {} : { reasoningEffort: actor.reasoningEffort }),
|
|
261
|
+
};
|
|
262
|
+
const readiness = await (args.codexParticipantReadiness ?? hostedCodexReadiness)(args.env, declared).catch(() => ({ ready: false, errorCode: "codex_unavailable" }));
|
|
263
|
+
const account = readiness.authentication === "api-key"
|
|
264
|
+
? "an API key, which bills its usage to that key"
|
|
265
|
+
: "a ChatGPT account";
|
|
266
|
+
return {
|
|
267
|
+
name: "local participant authentication",
|
|
268
|
+
ok: readiness.ready,
|
|
269
|
+
message: readiness.ready
|
|
270
|
+
? readyMessage(`Codex CLI ${readiness.cliVersion ?? "(unknown release)"} passed the operator handshake without a turn (initialize, config/read, account/read and an ephemeral thread/start): model ${readiness.resolvedModel ?? "(not reported)"} on ${account}. E2B supplies the desktop; no OpenAI API key is required for this participant.`, readiness)
|
|
271
|
+
: `Hosted Codex participant setup is unavailable (${readiness.errorCode}). ${codexRecovery(readiness, "Check `codex login status` and the operator's Codex configuration, then rerun doctor.")} No API fallback is used.`,
|
|
272
|
+
};
|
|
273
|
+
}
|
|
152
274
|
/** The local Chrome/Chromium the scripted-browser route drives. */
|
|
153
275
|
async function scriptedBrowserCheck() {
|
|
154
276
|
const { resolveBrowserCommand } = await import("../actors/scripted-browser/browser-command.js");
|
|
@@ -158,9 +280,9 @@ async function scriptedBrowserCheck() {
|
|
|
158
280
|
message: "Scripted-browser uses local Chrome/Chromium and no participant model. Install Chrome/Chromium or set HUMANISH_BROWSER_COMMAND; a clone subject additionally needs E2B.",
|
|
159
281
|
};
|
|
160
282
|
}
|
|
161
|
-
/** One row per
|
|
162
|
-
function subjectEnvChecks(
|
|
163
|
-
return
|
|
283
|
+
/** One row per subject env name the plan requires: present or missing, never the value. */
|
|
284
|
+
function subjectEnvChecks(names, args) {
|
|
285
|
+
return names.map((name) => ({
|
|
164
286
|
name: `subject env ${name}`,
|
|
165
287
|
ok: !!args.env[name]?.trim() || args.keyPresent(name),
|
|
166
288
|
message: args.env[name]?.trim() || args.keyPresent(name)
|
|
@@ -168,7 +290,7 @@ function subjectEnvChecks(config, args) {
|
|
|
168
290
|
: "missing declared subject environment variable; provide it with --env-file",
|
|
169
291
|
}));
|
|
170
292
|
}
|
|
171
|
-
/** The post-run analysis: the Codex account, or the OpenAI key and the
|
|
293
|
+
/** The post-run analysis: the Codex account, or the OpenAI key and the analysis cost limit. */
|
|
172
294
|
async function analysisCheck(analysis, args, checkAccount) {
|
|
173
295
|
if (analysis.provider === "codex") {
|
|
174
296
|
const readiness = await checkAccount();
|
|
@@ -181,7 +303,7 @@ async function analysisCheck(analysis, args, checkAccount) {
|
|
|
181
303
|
name: "post-run analysis",
|
|
182
304
|
ok: readiness.ready,
|
|
183
305
|
message: readiness.ready
|
|
184
|
-
? "Qualified Codex CLI and ChatGPT account login are ready for a separate restricted analyst. Analysis sends selected evidence to remote inference; model access and account allowance remain untested. Dollar cost and output-token ceilings are unavailable."
|
|
306
|
+
? readyMessage("Qualified Codex CLI and ChatGPT account login are ready for a separate restricted analyst. Analysis sends selected evidence to remote inference; model access and account allowance remain untested. Dollar cost and output-token ceilings are unavailable.", readiness)
|
|
185
307
|
: `Codex account analysis is unavailable (${readiness.errorCode ?? "codex_unavailable"}). ${recovery} No API fallback is used; participant readiness is independent.`,
|
|
186
308
|
};
|
|
187
309
|
}
|
|
@@ -189,7 +311,7 @@ async function analysisCheck(analysis, args, checkAccount) {
|
|
|
189
311
|
name: "post-run analysis",
|
|
190
312
|
ok: true,
|
|
191
313
|
message: args.keyPresent("OPENAI_API_KEY")
|
|
192
|
-
? `OPENAI_API_KEY is present for the separate automatic analysis request; model access and quota are not tested.
|
|
314
|
+
? `OPENAI_API_KEY is present for the separate automatic analysis request; model access and quota are not tested. The analysis is refused before it starts if its estimate is over $${analysis.maxCostUsd}; this is not a billing cap. Participant readiness is independent.`
|
|
193
315
|
: "Will be skipped: OPENAI_API_KEY is missing. The participant may run, but there will be no automatic findings report. Add an OpenAI API key or set review.analysis: false deliberately.",
|
|
194
316
|
};
|
|
195
317
|
}
|
|
@@ -203,26 +325,12 @@ function checkScope(analysis) {
|
|
|
203
325
|
: "Local setup only. Provider credentials are not validated, model access/quota and target reachability are untested, and no paid resources were created.",
|
|
204
326
|
};
|
|
205
327
|
}
|
|
206
|
-
/**
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
(route === "computer-use" ||
|
|
213
|
-
route === "terminal" ||
|
|
214
|
-
route === "shared-world" ||
|
|
215
|
-
(route === "scripted" && config.subject.source === "clone"));
|
|
216
|
-
const keys = desktop ? ["E2B_API_KEY"] : [];
|
|
217
|
-
const openaiBrain = config.actors[0]?.type !== "local-agent";
|
|
218
|
-
if (route === "terminal")
|
|
219
|
-
keys.push(keyPresent("CODEX_API_KEY") ? "CODEX_API_KEY" : "OPENAI_API_KEY");
|
|
220
|
-
// Shared world's external-public plane reads the host's lobby code with the OpenAI API,
|
|
221
|
-
// whatever brain drives the participants (routes/shared-world/plan.ts).
|
|
222
|
-
else if ((route === "computer-use" && openaiBrain) ||
|
|
223
|
-
(route === "shared-world" && (openaiBrain || config.subject.source === "app-url")))
|
|
224
|
-
keys.push("OPENAI_API_KEY");
|
|
225
|
-
return { desktop, keys };
|
|
328
|
+
/**
|
|
329
|
+
* The lab planned with no run options, so its own scenario mode decides dry or live. Doctor and the
|
|
330
|
+
* TUI read a live run's keys and subject env from this plan's requirements.
|
|
331
|
+
*/
|
|
332
|
+
export async function planCliRun(config, cwd) {
|
|
333
|
+
return (await import("./plan.js")).planLab(config, { cwd });
|
|
226
334
|
}
|
|
227
335
|
function unsupportedCliRoute(config, route) {
|
|
228
336
|
if (config.subject.source === "local-app")
|
package/dist/lab/init-plan.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
// here; runInit applies the plan.
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import { humanishScripts } from "./init-templates.js";
|
|
6
|
+
import { isRecord } from "../run/type-guards.js";
|
|
6
7
|
import { readTextIfExists } from "./init-paths.js";
|
|
7
8
|
export async function planGitignore(projectRoot, cwd) {
|
|
8
9
|
const relativePath = ".gitignore";
|
|
@@ -158,6 +159,3 @@ export async function planPackageJson(projectRoot, cwd) {
|
|
|
158
159
|
function trimTrailingNewlines(text) {
|
|
159
160
|
return text.replace(/\n+$/, "");
|
|
160
161
|
}
|
|
161
|
-
function isRecord(value) {
|
|
162
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
163
|
-
}
|
package/dist/lab/keys.js
CHANGED
|
@@ -92,7 +92,7 @@ const ACTOR = {
|
|
|
92
92
|
type: true,
|
|
93
93
|
count: true,
|
|
94
94
|
lanes: PARTICIPANT_ENTRY,
|
|
95
|
-
// Roster groups are
|
|
95
|
+
// Roster groups are participants with a count; the parser expands them into `lanes[]`.
|
|
96
96
|
roster: { ...PARTICIPANT_ENTRY, count: true },
|
|
97
97
|
persona: true,
|
|
98
98
|
mission: true,
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import type { ScriptedBrowserSessionOptions, ScriptedBrowserSessionResult } from "../actors/scripted-browser/actor.js";
|
|
2
|
+
import type { ScriptedBrowserLaunchArgs, ScriptedBrowserLike } from "../actors/scripted-browser/types.js";
|
|
3
|
+
import type { CuaActorSessionOptions } from "../actors/computer-use/actor.js";
|
|
4
|
+
import type { AutomaticAnalysisDeps, runAutomaticAnalysis } from "../analysis/automatic.js";
|
|
5
|
+
import type { CuaLoopResult } from "../actors/computer-use/loop.js";
|
|
6
|
+
import type { renderObserver } from "../observer/render.js";
|
|
7
|
+
import type { TerminalCostProbe } from "../routes/terminal/types.js";
|
|
8
|
+
import type { DetachedTimers } from "../substrates/detached.js";
|
|
9
|
+
import type { E2BDesktopModule } from "../substrates/e2b/sdk.js";
|
|
10
|
+
import type { LocalTreeArchive } from "../subject/local-tree-archive.js";
|
|
11
|
+
import type { SubjectPhaseEvent } from "../subject/steps.js";
|
|
12
|
+
/** The participant a computer-use subject phase belongs to, with the route's field names. */
|
|
13
|
+
export interface PhaseParticipant {
|
|
14
|
+
readonly laneId: string;
|
|
15
|
+
readonly laneIndex: number;
|
|
16
|
+
readonly laneCount: number;
|
|
17
|
+
}
|
|
18
|
+
export interface LabDeps {
|
|
19
|
+
/** Loads the E2B SDK. Defaults to loadE2BDesktopModule. */
|
|
20
|
+
readonly desktopModule?: () => Promise<E2BDesktopModule>;
|
|
21
|
+
/** Renders the Observer. Defaults to renderObserver. */
|
|
22
|
+
readonly renderObserver?: typeof renderObserver;
|
|
23
|
+
/** The clock, in epoch milliseconds. Defaults to Date.now. */
|
|
24
|
+
readonly now?: () => number;
|
|
25
|
+
/** Clock and sleep for detached provisioning steps. */
|
|
26
|
+
readonly detachedTimers?: DetachedTimers;
|
|
27
|
+
/**
|
|
28
|
+
* Computer use and shared world: where subject-provisioning phases go in place of stderr. A
|
|
29
|
+
* computer-use phase names its participant; a shared-world plane's names none. onEvent still
|
|
30
|
+
* receives every phase.
|
|
31
|
+
*/
|
|
32
|
+
readonly subjectPhaseSink?: (event: SubjectPhaseEvent, participant?: PhaseParticipant) => void;
|
|
33
|
+
/**
|
|
34
|
+
* Shared world: runs each seat's computer-use session in place of the actor's own. The planner
|
|
35
|
+
* reads whether it is set: a custom runner cannot enforce actors[0].maxOutputTokens.
|
|
36
|
+
*/
|
|
37
|
+
readonly runSession?: (options: CuaActorSessionOptions) => Promise<CuaLoopResult>;
|
|
38
|
+
/**
|
|
39
|
+
* Shared world: packs a local-tree subject on the host. Defaults to createLocalTreeArchive and a
|
|
40
|
+
* read of the archive it writes. Called once per run, before the subject sandbox exists.
|
|
41
|
+
*/
|
|
42
|
+
readonly packLocalTree?: (args: {
|
|
43
|
+
root: string;
|
|
44
|
+
extraExclude?: string[];
|
|
45
|
+
maxArchiveBytes?: number;
|
|
46
|
+
}) => Promise<{
|
|
47
|
+
archive: LocalTreeArchive;
|
|
48
|
+
buffer: ArrayBuffer;
|
|
49
|
+
}>;
|
|
50
|
+
/** Shared world: the background stateSeries prober's cadence in milliseconds. Defaults to 1000. */
|
|
51
|
+
readonly proberCadenceMs?: number;
|
|
52
|
+
/**
|
|
53
|
+
* Shared world, external-public plane: how long the host seat has to surface a /lobby/CODE URL
|
|
54
|
+
* before the run fails closed. Defaults to 120000, capped by execution.timeoutMs.
|
|
55
|
+
*/
|
|
56
|
+
readonly handoffDeadlineMs?: number;
|
|
57
|
+
/**
|
|
58
|
+
* Shared world, external-public plane: reads a /lobby/CODE off a seat's screenshot. Defaults to
|
|
59
|
+
* the single-frame OpenAI read.
|
|
60
|
+
*/
|
|
61
|
+
readonly readLobbyCodeFromFrame?: (frame: Buffer, apiKey: string) => Promise<string | undefined>;
|
|
62
|
+
/**
|
|
63
|
+
* Every route: post-run analysis in place of the real one. `run` replaces
|
|
64
|
+
* the real analysis runner, and `deps` (provider fetch, keys, clock) reach the analysis only,
|
|
65
|
+
* never a participant.
|
|
66
|
+
*/
|
|
67
|
+
readonly analysis?: {
|
|
68
|
+
readonly run?: typeof runAutomaticAnalysis;
|
|
69
|
+
readonly deps?: AutomaticAnalysisDeps;
|
|
70
|
+
};
|
|
71
|
+
/** Scripted: runs one surface's session in place of the scripted-browser actor. */
|
|
72
|
+
readonly runScriptedSession?: (options: ScriptedBrowserSessionOptions) => Promise<ScriptedBrowserSessionResult>;
|
|
73
|
+
/**
|
|
74
|
+
* Scripted: launches the browser each session drives, so no browser binary is resolved. The
|
|
75
|
+
* planner reads whether it, or browserCommand, is set: a live run then needs no host browser.
|
|
76
|
+
*/
|
|
77
|
+
readonly launchBrowser?: (args: ScriptedBrowserLaunchArgs) => Promise<ScriptedBrowserLike>;
|
|
78
|
+
/** Scripted: the browser binary to launch; operators use HUMANISH_BROWSER_COMMAND. */
|
|
79
|
+
readonly browserCommand?: string;
|
|
80
|
+
/**
|
|
81
|
+
* Terminal: known spend lines for the cost ledger. The planner reads whether it is set, since
|
|
82
|
+
* only a measured line can trip a positive maxUsd.
|
|
83
|
+
*/
|
|
84
|
+
readonly costProbe?: TerminalCostProbe;
|
|
85
|
+
}
|
package/dist/lab/parse/actors.js
CHANGED
|
@@ -3,8 +3,9 @@ import { isReasoningEffort, reasoningEffortNames } from "../../actors/reasoning-
|
|
|
3
3
|
import { isMaxOutputTokens } from "../../actors/output-token-limit.js";
|
|
4
4
|
import { isHttpUrl } from "./subject.js";
|
|
5
5
|
import { registeredComputerUseActors, registeredScriptedBrowserActors, registeredTerminalActors, } from "../routing.js";
|
|
6
|
-
import { invalid,
|
|
7
|
-
|
|
6
|
+
import { invalid, posInt, str } from "./values.js";
|
|
7
|
+
import { isRecord } from "../../run/type-guards.js";
|
|
8
|
+
// A participant id interpolates into its evidence paths (screenshots/<id>/, actors/<id>.json), so
|
|
8
9
|
// it must be a public-safe path token, same shape as a lab id.
|
|
9
10
|
export const PARTICIPANT_ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9_.-]*$/;
|
|
10
11
|
export const PARTICIPANT_ID_MAX_CHARS = 40;
|
|
@@ -138,7 +139,7 @@ function parseFocus(raw) {
|
|
|
138
139
|
return Object.keys(focus).length > 0 ? focus : undefined;
|
|
139
140
|
}
|
|
140
141
|
/**
|
|
141
|
-
* Parse `actors[index].roster` compact groups into concrete lanes. This is authoring sugar for
|
|
142
|
+
* Parse `actors[index].roster` compact groups into concrete `lanes[]` entries. This is authoring sugar for
|
|
142
143
|
* "N users of M adapter-owned types across S surfaces"; the runtime receives only `lanes[]`.
|
|
143
144
|
*/
|
|
144
145
|
function parseRosterGroups(raw, actorIndex) {
|
|
@@ -183,11 +184,11 @@ function parseRosterGroups(raw, actorIndex) {
|
|
|
183
184
|
}
|
|
184
185
|
/**
|
|
185
186
|
* Parse `actors[index].lanes` into a fan-out roster (computer-use E2B route). Structural only:
|
|
186
|
-
* each
|
|
187
|
+
* each entry is `{ id?, actorType?, surface?, caseGroup?, persona?, device?, instruction?, target?,
|
|
187
188
|
* entry?, host?, reasoningEffort?, stopWhen?, dwell? }`.
|
|
188
|
-
*
|
|
189
|
-
* must be public-safe tokens; a
|
|
190
|
-
* route-scoped cross-validation (lanes XOR count
|
|
189
|
+
* Participant ids (when declared) must be public-safe path tokens and unique; grouping metadata
|
|
190
|
+
* must be public-safe tokens; a device must be a known preset name. The
|
|
191
|
+
* route-scoped cross-validation (`lanes` XOR `count`/`laneFocus`, device XOR raw resolution, cap 16)
|
|
191
192
|
* runs in parseLabConfig where the route is known.
|
|
192
193
|
*/
|
|
193
194
|
function parseParticipantEntries(raw, actorIndex) {
|
package/dist/lab/parse/comms.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { invalid,
|
|
1
|
+
import { invalid, posInt, str } from "./values.js";
|
|
2
|
+
import { isRecord } from "../../run/type-guards.js";
|
|
2
3
|
// Fail-loud (never silently swallow a comms setting): a malformed `comms` block returns a parse
|
|
3
4
|
// failure rather than being dropped.
|
|
4
5
|
export function parseComms(raw) {
|
|
@@ -226,7 +227,7 @@ export function addressedRecipients(email) {
|
|
|
226
227
|
? []
|
|
227
228
|
: [{ participantId: recipient.lane, address: recipient.address }]);
|
|
228
229
|
}
|
|
229
|
-
/** `comms.email.recipients`: which
|
|
230
|
+
/** `comms.email.recipients`: which participant each captured address belongs to. */
|
|
230
231
|
function parseRecipients(raw) {
|
|
231
232
|
if (raw === undefined)
|
|
232
233
|
return { ok: true, value: undefined };
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { resolveAutomaticAnalysis } from "../../analysis/automatic-config.js";
|
|
2
2
|
import { DEVICE_PRESET_NAMES, isDevicePresetName } from "../device-presets.js";
|
|
3
3
|
import { isExactRuntimeVersion } from "../../routes/terminal/runtime.js";
|
|
4
|
-
import { invalid,
|
|
4
|
+
import { invalid, nonNegNumber, posInt, str } from "./values.js";
|
|
5
|
+
import { isRecord } from "../../run/type-guards.js";
|
|
5
6
|
export function parseExecution(raw) {
|
|
6
7
|
if (raw === undefined) {
|
|
7
8
|
return { ok: true, value: undefined };
|
|
@@ -32,7 +33,7 @@ export function parseExecution(raw) {
|
|
|
32
33
|
}
|
|
33
34
|
if (desktopResult.value)
|
|
34
35
|
execution.desktop = desktopResult.value;
|
|
35
|
-
// Reuse the terminal
|
|
36
|
+
// Reuse the terminal route's caps parser (same shape, not a fork) — a malformed budget is a hard
|
|
36
37
|
// error, never silently dropped (a cap that silently does nothing would be a safety lie).
|
|
37
38
|
const capsResult = parseCaps(raw.caps);
|
|
38
39
|
if (!capsResult.ok) {
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
// the structural parse of `subject.state`, and subjectStateInvalidReason, the semantic check
|
|
3
3
|
// parseLabConfig and the computer-use route share.
|
|
4
4
|
import { containsSensitive } from "../../evidence/redaction.js";
|
|
5
|
-
import { ENV_NAME_PATTERN, invalid,
|
|
5
|
+
import { ENV_NAME_PATTERN, invalid, posInt, str, strList } from "./values.js";
|
|
6
|
+
import { isRecord } from "../../run/type-guards.js";
|
|
6
7
|
/**
|
|
7
8
|
* LITERAL non-secret subject env. Real apps need configuration before they will boot — a public base
|
|
8
9
|
* URL, a transport selector, a feature flag — and none of that is secret. Routing it through
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { normalizeExtraExcludeEntry } from "../../subject/local-tree-archive.js";
|
|
2
|
-
import { ENV_NAME_PATTERN, invalid,
|
|
2
|
+
import { ENV_NAME_PATTERN, invalid, posInt, str, strList } from "./values.js";
|
|
3
3
|
import { parseEnvValues, parseState, subjectStateInvalidReason } from "./subject-state.js";
|
|
4
|
+
import { isRecord } from "../../run/type-guards.js";
|
|
4
5
|
export function parseSubject(raw) {
|
|
5
6
|
if (!isRecord(raw)) {
|
|
6
7
|
return invalid("Lab `subject` is required and must be an object.");
|
|
@@ -2,7 +2,6 @@ import type { LabConfigParseFailure } from "../types.js";
|
|
|
2
2
|
export declare const REPO_SLUG_PATTERN: RegExp;
|
|
3
3
|
export declare const ENV_NAME_PATTERN: RegExp;
|
|
4
4
|
export declare function invalid(message: string): LabConfigParseFailure;
|
|
5
|
-
export declare function isRecord(value: unknown): value is Record<string, unknown>;
|
|
6
5
|
export declare function str(value: unknown): string | undefined;
|
|
7
6
|
export declare function optionalStr(key: string, value: unknown): Record<string, string>;
|
|
8
7
|
export declare function strList(value: unknown): string[] | undefined;
|
package/dist/lab/parse/values.js
CHANGED
|
@@ -4,9 +4,6 @@ export const ENV_NAME_PATTERN = /^[A-Z][A-Z0-9_]*$/;
|
|
|
4
4
|
export function invalid(message) {
|
|
5
5
|
return { ok: false, error: { code: "HUMANISH_LAB_INVALID", message } };
|
|
6
6
|
}
|
|
7
|
-
export function isRecord(value) {
|
|
8
|
-
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
9
|
-
}
|
|
10
7
|
export function str(value) {
|
|
11
8
|
return typeof value === "string" && value.trim() ? value.trim() : undefined;
|
|
12
9
|
}
|
|
@@ -13,7 +13,7 @@ export declare function resolveCommittedPersona(projectRoot: PreparedSelectedOut
|
|
|
13
13
|
warnings: string[];
|
|
14
14
|
}>;
|
|
15
15
|
/**
|
|
16
|
-
* Resolve every distinct persona id a run will use, once, before
|
|
16
|
+
* Resolve every distinct persona id a run will use, once, before participant specs are built. Returning a
|
|
17
17
|
* map keeps the plan builder PURE (it is exported npm surface and asserted pure by tests): the
|
|
18
18
|
* async file reads happen here, and the composer only does a lookup.
|
|
19
19
|
*/
|
|
@@ -22,8 +22,8 @@ export declare function resolveCommittedPersonas(projectRoot: PreparedSelectedOu
|
|
|
22
22
|
warnings: string[];
|
|
23
23
|
}>;
|
|
24
24
|
/**
|
|
25
|
-
* Every persona id a lab config could put on a browser
|
|
26
|
-
* declared, otherwise the actor-level persona that every fan-out
|
|
25
|
+
* Every persona id a lab config could put on a browser participant: the roster when one is
|
|
26
|
+
* declared, otherwise the actor-level persona that every fan-out participant inherits.
|
|
27
27
|
*/
|
|
28
28
|
export declare function labPersonaIds(config: {
|
|
29
29
|
actors?: readonly Pick<LabActor, "persona" | "lanes">[];
|