humanish 0.107.0 → 0.109.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ARCHITECTURE.md +73 -69
- package/CHANGELOG.md +27 -0
- package/CONTEXT.md +51 -44
- package/README.md +148 -175
- package/SECURITY.md +16 -26
- package/TELEMETRY.md +8 -6
- package/dist/actors/affordance.d.ts +4 -4
- package/dist/actors/affordance.js +12 -12
- package/dist/actors/agent-session.d.ts +2 -2
- package/dist/actors/agent-session.js +7 -7
- package/dist/actors/codex/app-server-actor-trace.d.ts +1 -1
- package/dist/actors/codex/app-server-actor-trace.js +1 -1
- package/dist/actors/codex/app-server-trace.js +2 -1
- package/dist/actors/codex/app-server-ui.js +1 -1
- package/dist/actors/codex/codex-admission.d.ts +91 -0
- package/dist/actors/codex/codex-admission.js +150 -0
- package/dist/actors/codex/restricted-executable.d.ts +4 -4
- package/dist/actors/codex/restricted-executable.js +8 -8
- package/dist/actors/codex/restricted-launch.d.ts +2 -1
- package/dist/actors/codex/restricted-launch.js +1 -1
- package/dist/actors/codex/restricted-participant.js +20 -18
- package/dist/actors/codex/restricted-policy.d.ts +2 -2
- package/dist/actors/codex/restricted-policy.js +2 -2
- package/dist/actors/codex/restricted-session.d.ts +3 -3
- package/dist/actors/codex/restricted-session.js +10 -5
- package/dist/actors/computer-use/actor.d.ts +18 -18
- package/dist/actors/computer-use/actor.js +4 -4
- package/dist/actors/computer-use/admission-limit.d.ts +3 -3
- package/dist/actors/computer-use/admission-limit.js +4 -4
- package/dist/actors/computer-use/executor-error.d.ts +2 -2
- package/dist/actors/computer-use/executor-error.js +3 -3
- package/dist/actors/computer-use/loop/actions.d.ts +3 -3
- package/dist/actors/computer-use/loop/actions.js +15 -15
- package/dist/actors/computer-use/loop/backstop.d.ts +3 -3
- package/dist/actors/computer-use/loop/backstop.js +14 -12
- package/dist/actors/computer-use/loop/debrief.js +2 -2
- package/dist/actors/computer-use/loop/ending.d.ts +6 -6
- package/dist/actors/computer-use/loop/ending.js +18 -17
- package/dist/actors/computer-use/loop/observation.d.ts +2 -2
- package/dist/actors/computer-use/loop/observation.js +15 -14
- package/dist/actors/computer-use/loop/provider-call.d.ts +1 -1
- package/dist/actors/computer-use/loop/provider-call.js +12 -12
- package/dist/actors/computer-use/loop/session.d.ts +4 -4
- package/dist/actors/computer-use/loop/session.js +4 -4
- package/dist/actors/computer-use/loop/spend.d.ts +1 -1
- package/dist/actors/computer-use/loop/spend.js +1 -1
- package/dist/actors/computer-use/loop/trace.js +11 -9
- package/dist/actors/computer-use/loop/types.d.ts +47 -45
- package/dist/actors/computer-use/loop/usage.d.ts +2 -2
- package/dist/actors/computer-use/loop/usage.js +2 -2
- package/dist/actors/computer-use/loop.d.ts +6 -1
- package/dist/actors/computer-use/loop.js +26 -4
- package/dist/actors/computer-use/openai-context.d.ts +37 -0
- package/dist/actors/computer-use/openai-context.js +214 -0
- package/dist/actors/computer-use/openai-provider.d.ts +13 -10
- package/dist/actors/computer-use/openai-provider.js +52 -41
- package/dist/actors/computer-use/openai-requests.d.ts +36 -10
- package/dist/actors/computer-use/openai-requests.js +82 -15
- package/dist/actors/computer-use/openai-wire.d.ts +19 -7
- package/dist/actors/computer-use/openai-wire.js +36 -34
- package/dist/actors/computer-use/provider-error.d.ts +4 -4
- package/dist/actors/computer-use/provider-error.js +6 -6
- package/dist/actors/contract.d.ts +82 -47
- package/dist/actors/contract.js +30 -24
- package/dist/actors/local-agent/claude-session.d.ts +1 -1
- package/dist/actors/local-agent/claude-session.js +13 -12
- package/dist/actors/local-agent/cli.d.ts +9 -7
- package/dist/actors/local-agent/cli.js +24 -28
- package/dist/actors/local-agent/readiness.d.ts +2 -2
- package/dist/actors/local-agent/readiness.js +4 -4
- package/dist/actors/reasoning-effort.js +8 -8
- package/dist/actors/registry.d.ts +12 -12
- package/dist/actors/registry.js +21 -20
- package/dist/actors/scripted-browser/actor.d.ts +10 -10
- package/dist/actors/scripted-browser/actor.js +17 -17
- package/dist/actors/scripted-browser/browser-command.js +1 -1
- package/dist/actors/scripted-browser/steps.js +1 -1
- package/dist/actors/scripted-browser/types.d.ts +1 -1
- package/dist/actors/stop-conditions.d.ts +1 -1
- package/dist/analysis/automatic-completion.d.ts +7 -7
- package/dist/analysis/automatic-completion.js +1 -1
- package/dist/analysis/automatic-config.d.ts +6 -6
- package/dist/analysis/automatic-config.js +1 -1
- package/dist/analysis/codex-config.d.ts +6 -2
- package/dist/analysis/codex-config.js +22 -14
- package/dist/analysis/execute.d.ts +1 -1
- package/dist/analysis/execute.js +1 -1
- package/dist/analysis/service.js +5 -5
- package/dist/analysis/types.d.ts +6 -0
- package/dist/browser-control/client.js +16 -16
- package/dist/browser-control/dispatcher.js +4 -4
- package/dist/browser-control/protocol.js +14 -14
- package/dist/browser-control/recording-transfer.js +4 -4
- package/dist/browser-control/transport.js +7 -7
- package/dist/cli/commands/analysis-signals.d.ts +2 -2
- package/dist/cli/commands/analyze.js +19 -16
- package/dist/cli/commands/codex.js +9 -9
- package/dist/cli/commands/comms.js +48 -35
- package/dist/cli/commands/feedback.js +20 -21
- package/dist/cli/commands/migrate.d.ts +4 -0
- package/dist/cli/commands/migrate.js +65 -0
- package/dist/cli/commands/observe.d.ts +0 -1
- package/dist/cli/commands/observe.js +136 -112
- package/dist/cli/commands/run-command.d.ts +10 -0
- package/dist/cli/commands/run-command.js +85 -0
- package/dist/cli/commands/runs.js +136 -139
- package/dist/cli/commands/setup.d.ts +2 -2
- package/dist/cli/commands/setup.js +27 -24
- package/dist/cli/commands/study-format.d.ts +9 -0
- package/dist/cli/commands/{lab-format.js → study-format.js} +39 -27
- package/dist/cli/commands/{lab-route-computer-use.d.ts → study-route-computer-use.d.ts} +6 -6
- package/dist/cli/commands/{lab-route-computer-use.js → study-route-computer-use.js} +17 -18
- package/dist/cli/commands/{lab-route-open.d.ts → study-route-open.d.ts} +4 -4
- package/dist/cli/commands/{lab-route-open.js → study-route-open.js} +2 -2
- package/dist/cli/commands/{lab-route-preview.d.ts → study-route-preview.d.ts} +7 -7
- package/dist/cli/commands/{lab-route-preview.js → study-route-preview.js} +7 -6
- package/dist/cli/commands/study-route-run.d.ts +19 -0
- package/dist/cli/commands/{lab-route-run.js → study-route-run.js} +6 -6
- package/dist/cli/commands/study-route-scripted.d.ts +17 -0
- package/dist/cli/commands/{lab-route-scripted.js → study-route-scripted.js} +4 -4
- package/dist/cli/commands/{lab-route-shared-world.d.ts → study-route-shared-world.d.ts} +5 -5
- package/dist/cli/commands/{lab-route-shared-world.js → study-route-shared-world.js} +10 -10
- package/dist/cli/commands/study-route-terminal.d.ts +17 -0
- package/dist/cli/commands/{lab-route-terminal.js → study-route-terminal.js} +4 -4
- package/dist/cli/commands/study-run.d.ts +9 -0
- package/dist/cli/commands/{lab-run.js → study-run.js} +44 -45
- package/dist/cli/commands/{lab-scorer.d.ts → study-scorer.d.ts} +7 -7
- package/dist/cli/commands/{lab-scorer.js → study-scorer.js} +2 -2
- package/dist/cli/commands/study.d.ts +3 -0
- package/dist/cli/commands/study.js +146 -0
- package/dist/cli/commands/tui.d.ts +4 -4
- package/dist/cli/commands/tui.js +31 -31
- package/dist/cli/commands/watch.js +71 -121
- package/dist/cli/deprecations.d.ts +6 -0
- package/dist/cli/deprecations.js +18 -0
- package/dist/cli/doctor.d.ts +18 -8
- package/dist/cli/doctor.js +114 -59
- package/dist/cli/first-run-path.d.ts +15 -13
- package/dist/cli/first-run-path.js +35 -33
- package/dist/cli/io.d.ts +44 -9
- package/dist/cli/io.js +98 -23
- package/dist/cli/observer-follow.d.ts +3 -3
- package/dist/cli/observer-follow.js +6 -7
- package/dist/cli/orientation.d.ts +10 -7
- package/dist/cli/orientation.js +89 -47
- package/dist/cli/product-sentence.d.ts +6 -0
- package/dist/cli/product-sentence.js +6 -0
- package/dist/cli/program.d.ts +6 -1
- package/dist/cli/program.js +111 -43
- package/dist/cli/telemetry.d.ts +16 -16
- package/dist/cli/telemetry.js +46 -44
- package/dist/cli.js +1 -1
- package/dist/comms/capture-surface.d.ts +13 -12
- package/dist/comms/capture-surface.js +23 -22
- package/dist/comms/catch-host.d.ts +7 -7
- package/dist/comms/catch-host.js +17 -17
- package/dist/comms/connections.d.ts +1 -1
- package/dist/comms/connections.js +2 -2
- package/dist/comms/email-catch.d.ts +3 -3
- package/dist/comms/email-catch.js +8 -8
- package/dist/comms/external-evidence.d.ts +5 -5
- package/dist/comms/external-evidence.js +5 -4
- package/dist/comms/extract.js +2 -2
- package/dist/comms/fake-inbox.d.ts +3 -3
- package/dist/comms/fake-inbox.js +3 -3
- package/dist/comms/receiving-render.d.ts +1 -1
- package/dist/comms/receiving-render.js +2 -2
- package/dist/comms/receiving-runtime.d.ts +4 -4
- package/dist/comms/sandbox-catch-script.d.ts +6 -6
- package/dist/comms/sandbox-catch-script.js +6 -6
- package/dist/comms/sandbox-catch.d.ts +38 -39
- package/dist/comms/sandbox-catch.js +36 -37
- package/dist/comms/setup.d.ts +2 -2
- package/dist/comms/setup.js +56 -25
- package/dist/comms/thread-evidence.d.ts +1 -1
- package/dist/comms/thread-evidence.js +6 -6
- package/dist/comms/types.d.ts +6 -6
- package/dist/comms/types.js +3 -3
- package/dist/evidence/frame-signature.d.ts +1 -1
- package/dist/evidence/frame-signature.js +4 -4
- package/dist/evidence/redaction.d.ts +3 -3
- package/dist/evidence/redaction.js +4 -4
- package/dist/feedback/draft.js +38 -80
- package/dist/feedback/export-bundle.js +1 -1
- package/dist/feedback/export.d.ts +5 -1
- package/dist/feedback/export.js +10 -10
- package/dist/feedback/feedback.d.ts +2 -2
- package/dist/feedback/feedback.js +21 -3
- package/dist/feedback/proof.d.ts +1 -1
- package/dist/feedback/proof.js +2 -2
- package/dist/guest/bootstrap.js +6 -6
- package/dist/guest/browser-tools.js +8 -8
- package/dist/guest/chromium-text.js +19 -19
- package/dist/guest/desktop-executor.d.ts +2 -2
- package/dist/guest/desktop-executor.js +20 -20
- package/dist/guest/desktop-keys.js +4 -4
- package/dist/guest/desktop-media.d.ts +2 -2
- package/dist/guest/desktop-media.js +16 -16
- package/dist/guest/desktop-native.d.ts +1 -1
- package/dist/guest/desktop-native.js +10 -10
- package/dist/guest/runtime-desktop.js +2 -2
- package/dist/guest/runtime-processes.d.ts +2 -2
- package/dist/guest/runtime-processes.js +2 -2
- package/dist/guest/runtime.js +6 -6
- package/dist/index.d.ts +14 -14
- package/dist/index.js +8 -8
- package/dist/keys/key-resolution.d.ts +5 -5
- package/dist/keys/key-resolution.js +23 -23
- package/dist/observer/artifact.d.ts +2 -2
- package/dist/observer/artifact.js +7 -7
- package/dist/observer/data.d.ts +6 -6
- package/dist/observer/data.js +5 -4
- package/dist/observer/exposure.d.ts +1 -1
- package/dist/observer/exposure.js +11 -11
- package/dist/observer/http.js +1 -1
- package/dist/observer/library.d.ts +3 -1
- package/dist/observer/library.js +8 -3
- package/dist/observer/listen.js +5 -4
- package/dist/observer/render.d.ts +1 -1
- package/dist/observer/render.js +17 -6
- package/dist/observer/run-routes.d.ts +4 -3
- package/dist/observer/run-routes.js +38 -13
- package/dist/observer/serve.d.ts +1 -1
- package/dist/observer/serve.js +7 -3
- package/dist/observer/tunnel.js +1 -1
- package/dist/observer-app.html +4 -4
- package/dist/routes/computer-use/bundle-parts.d.ts +9 -9
- package/dist/routes/computer-use/bundle-parts.js +18 -17
- package/dist/routes/computer-use/bundle.d.ts +2 -2
- package/dist/routes/computer-use/bundle.js +10 -9
- package/dist/routes/computer-use/e2b-desktop/comms.d.ts +6 -6
- package/dist/routes/computer-use/e2b-desktop/comms.js +18 -17
- package/dist/routes/computer-use/e2b-desktop/desktop.js +4 -4
- package/dist/routes/computer-use/e2b-desktop/fidelity.d.ts +5 -4
- package/dist/routes/computer-use/e2b-desktop/fidelity.js +11 -10
- package/dist/routes/computer-use/e2b-desktop/prepare.d.ts +1 -1
- package/dist/routes/computer-use/e2b-desktop/prepare.js +10 -10
- package/dist/routes/computer-use/e2b-desktop/start.js +7 -7
- package/dist/routes/computer-use/e2b-desktop/state.d.ts +2 -2
- package/dist/routes/computer-use/e2b-desktop/teardown.js +2 -2
- package/dist/routes/computer-use/external-comms.d.ts +4 -4
- package/dist/routes/computer-use/external-comms.js +1 -1
- package/dist/routes/computer-use/fanout-bundle.js +27 -26
- package/dist/routes/computer-use/fanout-records.js +12 -13
- package/dist/routes/computer-use/live-flush.d.ts +4 -4
- package/dist/routes/computer-use/live-flush.js +6 -6
- package/dist/routes/computer-use/live-phase.d.ts +5 -4
- package/dist/routes/computer-use/live-phase.js +8 -8
- package/dist/routes/computer-use/local-tree-pack.d.ts +5 -5
- package/dist/routes/computer-use/local-tree-pack.js +1 -1
- package/dist/routes/computer-use/local-vm.d.ts +8 -8
- package/dist/routes/computer-use/local-vm.js +3 -3
- package/dist/routes/computer-use/participant-desktop.d.ts +7 -7
- package/dist/routes/computer-use/participant-desktop.js +5 -5
- package/dist/routes/computer-use/participant-execution.d.ts +4 -4
- package/dist/routes/computer-use/participant-execution.js +10 -10
- package/dist/routes/computer-use/participant-model.d.ts +6 -0
- package/dist/routes/computer-use/participant-model.js +33 -15
- package/dist/routes/computer-use/participant-prompt.d.ts +15 -15
- package/dist/routes/computer-use/participant-prompt.js +9 -9
- package/dist/routes/computer-use/participant-runs.d.ts +16 -16
- package/dist/routes/computer-use/participant-runs.js +26 -25
- package/dist/routes/computer-use/plan.d.ts +12 -12
- package/dist/routes/computer-use/plan.js +42 -42
- package/dist/routes/computer-use/preflight.d.ts +5 -5
- package/dist/routes/computer-use/preflight.js +25 -25
- package/dist/routes/computer-use/rerun-selection.d.ts +1 -1
- package/dist/routes/computer-use/rerun-selection.js +4 -3
- package/dist/routes/computer-use/result.d.ts +4 -4
- package/dist/routes/computer-use/result.js +22 -21
- package/dist/routes/computer-use/route.d.ts +12 -11
- package/dist/routes/computer-use/route.js +31 -30
- package/dist/routes/computer-use/self-report.d.ts +7 -7
- package/dist/routes/computer-use/self-report.js +32 -32
- package/dist/routes/computer-use/setup.d.ts +23 -23
- package/dist/routes/computer-use/setup.js +28 -29
- package/dist/routes/computer-use/single-bundle.d.ts +11 -11
- package/dist/routes/computer-use/single-bundle.js +40 -41
- package/dist/routes/computer-use/subject-projection.d.ts +4 -4
- package/dist/routes/computer-use/subject-projection.js +6 -6
- package/dist/routes/computer-use/types.d.ts +71 -73
- package/dist/routes/computer-use/types.js +12 -12
- package/dist/routes/preview.d.ts +13 -7
- package/dist/routes/preview.js +11 -7
- package/dist/routes/scripted/bundle.d.ts +7 -7
- package/dist/routes/scripted/bundle.js +20 -18
- package/dist/routes/scripted/plan.d.ts +8 -8
- package/dist/routes/scripted/plan.js +13 -13
- package/dist/routes/scripted/result.d.ts +3 -3
- package/dist/routes/scripted/result.js +13 -13
- package/dist/routes/scripted/route.d.ts +9 -9
- package/dist/routes/scripted/route.js +15 -16
- package/dist/routes/scripted/scenario.d.ts +1 -1
- package/dist/routes/scripted/scenario.js +5 -5
- package/dist/routes/scripted/setup.d.ts +6 -6
- package/dist/routes/scripted/setup.js +8 -8
- package/dist/routes/scripted/subject.d.ts +5 -5
- package/dist/routes/scripted/subject.js +4 -4
- package/dist/routes/scripted/surface-records.d.ts +1 -1
- package/dist/routes/scripted/surface-records.js +4 -4
- package/dist/routes/scripted/surface-sessions.d.ts +3 -3
- package/dist/routes/scripted/types.d.ts +18 -20
- package/dist/routes/scripted/types.js +2 -2
- package/dist/routes/shared-world/bundle-records.js +11 -10
- package/dist/routes/shared-world/bundle.d.ts +5 -5
- package/dist/routes/shared-world/bundle.js +46 -43
- package/dist/routes/shared-world/checkpoints.d.ts +4 -4
- package/dist/routes/shared-world/checkpoints.js +2 -2
- package/dist/routes/shared-world/comms.d.ts +14 -14
- package/dist/routes/shared-world/comms.js +19 -18
- package/dist/routes/shared-world/external-public.d.ts +4 -3
- package/dist/routes/shared-world/external-public.js +16 -12
- package/dist/routes/shared-world/handoff.d.ts +7 -6
- package/dist/routes/shared-world/handoff.js +65 -57
- package/dist/routes/shared-world/lobby-code.d.ts +2 -2
- package/dist/routes/shared-world/lobby-code.js +9 -9
- package/dist/routes/shared-world/participant-specs.d.ts +10 -9
- package/dist/routes/shared-world/participant-specs.js +38 -31
- package/dist/routes/shared-world/plan.d.ts +9 -9
- package/dist/routes/shared-world/plan.js +16 -16
- package/dist/routes/shared-world/provenance.d.ts +2 -2
- package/dist/routes/shared-world/provenance.js +2 -2
- package/dist/routes/shared-world/provisioned.d.ts +8 -8
- package/dist/routes/shared-world/provisioned.js +18 -17
- package/dist/routes/shared-world/result.d.ts +6 -6
- package/dist/routes/shared-world/result.js +29 -29
- package/dist/routes/shared-world/route.d.ts +11 -11
- package/dist/routes/shared-world/route.js +40 -39
- package/dist/routes/shared-world/setup.d.ts +16 -16
- package/dist/routes/shared-world/setup.js +23 -23
- package/dist/routes/shared-world/types.d.ts +55 -53
- package/dist/routes/shared-world/types.js +4 -4
- package/dist/routes/terminal/adapter.d.ts +5 -5
- package/dist/routes/terminal/adapter.js +9 -9
- package/dist/routes/terminal/bundle.d.ts +13 -13
- package/dist/routes/terminal/bundle.js +28 -27
- package/dist/routes/terminal/credentials.d.ts +8 -8
- package/dist/routes/terminal/credentials.js +12 -12
- package/dist/routes/terminal/dry-run.d.ts +4 -4
- package/dist/routes/terminal/dry-run.js +12 -12
- package/dist/routes/terminal/encoding.js +2 -2
- package/dist/routes/terminal/ledger.d.ts +5 -5
- package/dist/routes/terminal/ledger.js +14 -14
- package/dist/routes/terminal/lifetime.d.ts +1 -1
- package/dist/routes/terminal/lifetime.js +1 -1
- package/dist/routes/terminal/live-finish.d.ts +2 -2
- package/dist/routes/terminal/live-finish.js +10 -10
- package/dist/routes/terminal/live-sandbox.d.ts +2 -2
- package/dist/routes/terminal/live-sandbox.js +15 -15
- package/dist/routes/terminal/participant-text.js +2 -1
- package/dist/routes/terminal/persona.d.ts +2 -2
- package/dist/routes/terminal/persona.js +3 -3
- package/dist/routes/terminal/plan.d.ts +7 -7
- package/dist/routes/terminal/plan.js +15 -15
- package/dist/routes/terminal/recorder.js +2 -2
- package/dist/routes/terminal/result.d.ts +5 -5
- package/dist/routes/terminal/result.js +14 -14
- package/dist/routes/terminal/route.d.ts +9 -9
- package/dist/routes/terminal/route.js +19 -20
- package/dist/routes/terminal/sandbox.d.ts +1 -1
- package/dist/routes/terminal/sandbox.js +1 -1
- package/dist/routes/terminal/session.d.ts +5 -5
- package/dist/routes/terminal/session.js +14 -13
- package/dist/routes/terminal/token-usage.d.ts +1 -1
- package/dist/routes/terminal/token-usage.js +7 -8
- package/dist/routes/terminal/trace.d.ts +4 -4
- package/dist/routes/terminal/trace.js +2 -2
- package/dist/routes/terminal/types.d.ts +48 -50
- package/dist/routes/terminal/types.js +5 -5
- package/dist/run/bundle-shape.js +3 -3
- package/dist/run/bundle.d.ts +49 -49
- package/dist/run/bundle.js +3 -2
- package/dist/run/cost-summary.js +3 -3
- package/dist/run/costs.d.ts +23 -0
- package/dist/run/costs.js +79 -44
- package/dist/run/detail.d.ts +6 -6
- package/dist/run/detail.js +4 -4
- package/dist/run/dry-run-inputs.d.ts +1 -1
- package/dist/run/dry-run-inputs.js +2 -2
- package/dist/run/dry-run.js +20 -20
- package/dist/run/judge.d.ts +19 -13
- package/dist/run/judge.js +18 -8
- package/dist/run/outcomes.d.ts +1 -1
- package/dist/run/participant.d.ts +1 -1
- package/dist/run/paths.d.ts +1 -1
- package/dist/run/paths.js +1 -1
- package/dist/run/preflight-receipts.js +1 -1
- package/dist/run/pricing.d.ts +11 -6
- package/dist/run/pricing.js +22 -15
- package/dist/run/projection.d.ts +46 -46
- package/dist/run/projection.js +57 -57
- package/dist/run/reclaim.d.ts +1 -1
- package/dist/run/reclaim.js +3 -3
- package/dist/run/results.d.ts +5 -5
- package/dist/run/run-cost.d.ts +53 -0
- package/dist/run/run-cost.js +105 -0
- package/dist/run/run-index-analysis.d.ts +15 -0
- package/dist/run/run-index-analysis.js +77 -0
- package/dist/run/run-index.d.ts +19 -7
- package/dist/run/run-index.js +77 -64
- package/dist/run/run-not-found.d.ts +5 -0
- package/dist/run/run-not-found.js +15 -0
- package/dist/run/run.d.ts +6 -5
- package/dist/run/run.js +3 -3
- package/dist/run/sandbox-receipts.d.ts +2 -2
- package/dist/run/sandbox-receipts.js +3 -3
- package/dist/run/shared-world-evidence.d.ts +37 -36
- package/dist/run/shared-world-evidence.js +4 -4
- package/dist/run/shared-world-shape.d.ts +1 -1
- package/dist/run/shared-world-shape.js +7 -7
- package/dist/run/stats.d.ts +14 -8
- package/dist/run/stats.js +121 -63
- package/dist/run/status.d.ts +16 -29
- package/dist/run/status.js +10 -29
- package/dist/run/stored-runs.js +2 -1
- package/dist/run/stream-shape.js +1 -1
- package/dist/run/streams.d.ts +7 -7
- package/dist/run/study-provenance.d.ts +49 -0
- package/dist/run/study-provenance.js +66 -0
- package/dist/run/study-result.d.ts +11 -0
- package/dist/run/study-result.js +9 -0
- package/dist/run/text.d.ts +2 -0
- package/dist/run/text.js +4 -0
- package/dist/run-study.d.ts +112 -0
- package/dist/{run-lab.js → run-study.js} +52 -47
- package/dist/{lab → study}/adapter-extension.d.ts +15 -27
- package/dist/{lab → study}/adapter-extension.js +10 -45
- package/dist/{lab → study}/adapter-scorer-loader.d.ts +17 -17
- package/dist/{lab → study}/adapter-scorer-loader.js +34 -34
- package/dist/study/composition-rules.d.ts +7 -0
- package/dist/{lab → study}/composition-rules.js +53 -53
- package/dist/study/config.d.ts +15 -0
- package/dist/{lab → study}/config.js +98 -41
- package/dist/study/convert.d.ts +33 -0
- package/dist/study/convert.js +432 -0
- package/dist/{lab → study}/device-presets.d.ts +10 -10
- package/dist/{lab → study}/device-presets.js +11 -11
- package/dist/study/discover.d.ts +75 -0
- package/dist/{lab → study}/discover.js +134 -95
- package/dist/{lab → study}/doctor.d.ts +19 -12
- package/dist/{lab → study}/doctor.js +58 -20
- package/dist/study/field-paths.d.ts +12 -0
- package/dist/study/field-paths.js +126 -0
- package/dist/study/files.d.ts +26 -0
- package/dist/study/files.js +44 -0
- package/dist/{lab → study}/init-templates.d.ts +2 -2
- package/dist/study/init-templates.js +421 -0
- package/dist/{lab → study}/init.d.ts +2 -2
- package/dist/{lab → study}/init.js +46 -11
- package/dist/study/keys.d.ts +4 -0
- package/dist/{lab → study}/keys.js +46 -12
- package/dist/study/migrate.d.ts +48 -0
- package/dist/study/migrate.js +408 -0
- package/dist/study/owned-files.d.ts +38 -0
- package/dist/study/owned-files.js +182 -0
- package/dist/{lab → study}/parse/actors.d.ts +5 -5
- package/dist/{lab → study}/parse/actors.js +14 -14
- package/dist/study/parse/comms.d.ts +12 -0
- package/dist/{lab → study}/parse/comms.js +5 -5
- package/dist/study/parse/execution.d.ts +19 -0
- package/dist/{lab → study}/parse/execution.js +13 -13
- package/dist/study/parse/study-v3.d.ts +21 -0
- package/dist/study/parse/study-v3.js +259 -0
- package/dist/study/parse/subject-state.d.ts +30 -0
- package/dist/{lab → study}/parse/subject-state.js +19 -19
- package/dist/{lab → study}/parse/subject.d.ts +3 -3
- package/dist/{lab → study}/parse/subject.js +34 -34
- package/dist/{lab → study}/parse/values.d.ts +3 -3
- package/dist/{lab → study}/parse/values.js +3 -3
- package/dist/{lab → study}/persona-resolve.d.ts +8 -8
- package/dist/{lab → study}/persona-resolve.js +6 -6
- package/dist/{lab → study}/plan-base.d.ts +7 -7
- package/dist/{lab → study}/plan-base.js +1 -1
- package/dist/{lab → study}/plan-participants.d.ts +12 -12
- package/dist/{lab → study}/plan-participants.js +4 -4
- package/dist/{lab → study}/plan-types.d.ts +31 -31
- package/dist/{lab → study}/plan-types.js +2 -2
- package/dist/study/plan.d.ts +13 -0
- package/dist/study/plan.js +101 -0
- package/dist/study/preflight-probes.d.ts +3 -0
- package/dist/{lab → study}/preflight-probes.js +20 -19
- package/dist/study/preflight-result.d.ts +8 -0
- package/dist/{lab → study}/preflight-result.js +5 -4
- package/dist/study/preflight.d.ts +94 -0
- package/dist/{lab → study}/preflight.js +12 -12
- package/dist/{lab → study}/requirements.d.ts +3 -3
- package/dist/{lab → study}/requirements.js +1 -1
- package/dist/study/route-inputs.d.ts +28 -0
- package/dist/{lab → study}/route-inputs.js +1 -1
- package/dist/{lab → study}/routing.d.ts +39 -33
- package/dist/{lab → study}/routing.js +60 -29
- package/dist/{lab/run-lab-events.d.ts → study/run-study-events.d.ts} +10 -13
- package/dist/{lab/run-lab-events.js → study/run-study-events.js} +3 -9
- package/dist/{lab/run-lab-homes.d.ts → study/run-study-homes.d.ts} +21 -18
- package/dist/{lab/run-lab-homes.js → study/run-study-homes.js} +1 -1
- package/dist/study/run-study-options.d.ts +28 -0
- package/dist/{lab/run-lab-options.js → study/run-study-options.js} +29 -25
- package/dist/{lab/lab-deps.d.ts → study/study-deps.d.ts} +8 -13
- package/dist/{lab/lab-deps.js → study/study-deps.js} +2 -2
- package/dist/{lab → study}/summary.d.ts +16 -15
- package/dist/{lab → study}/summary.js +21 -21
- package/dist/{lab → study}/tasks.d.ts +18 -18
- package/dist/{lab → study}/tasks.js +14 -14
- package/dist/{lab → study}/types.d.ts +202 -196
- package/dist/{lab → study}/types.js +3 -1
- package/dist/{lab → study}/validation.d.ts +27 -27
- package/dist/{lab → study}/validation.js +53 -51
- package/dist/study/warnings.d.ts +12 -0
- package/dist/{lab → study}/warnings.js +62 -34
- package/dist/subject/clone.d.ts +7 -7
- package/dist/subject/clone.js +2 -2
- package/dist/subject/desktop-cli.d.ts +1 -1
- package/dist/subject/desktop-cli.js +2 -2
- package/dist/subject/local-tree-archive.d.ts +2 -2
- package/dist/subject/local-tree-archive.js +4 -4
- package/dist/subject/local-tree.d.ts +4 -4
- package/dist/subject/node-bootstrap.js +1 -1
- package/dist/subject/runtime.js +9 -10
- package/dist/subject/serve.d.ts +5 -5
- package/dist/subject/serve.js +3 -3
- package/dist/subject/state.d.ts +4 -4
- package/dist/subject/state.js +1 -1
- package/dist/subject/steps.d.ts +6 -6
- package/dist/subject/steps.js +5 -5
- package/dist/substrates/command-failure.d.ts +3 -3
- package/dist/substrates/command-failure.js +3 -3
- package/dist/substrates/desktop-session.js +2 -2
- package/dist/substrates/detached.d.ts +6 -6
- package/dist/substrates/detached.js +7 -7
- package/dist/substrates/e2b/cdp-probe.d.ts +9 -9
- package/dist/substrates/e2b/cdp-probe.js +14 -17
- package/dist/substrates/e2b/desktop-browser.d.ts +6 -6
- package/dist/substrates/e2b/desktop-browser.js +9 -9
- package/dist/substrates/e2b/desktop-cdp.d.ts +10 -10
- package/dist/substrates/e2b/desktop-cdp.js +9 -9
- package/dist/substrates/e2b/desktop-executor.d.ts +2 -2
- package/dist/substrates/e2b/desktop-executor.js +13 -13
- package/dist/substrates/e2b/desktop-geometry.d.ts +4 -4
- package/dist/substrates/e2b/desktop-geometry.js +8 -8
- package/dist/substrates/e2b/desktop-media.d.ts +4 -4
- package/dist/substrates/e2b/desktop-media.js +1 -1
- package/dist/substrates/e2b/desktop-screenshot-cleanup.d.ts +3 -3
- package/dist/substrates/e2b/desktop-screenshot-cleanup.js +3 -3
- package/dist/substrates/e2b/lifetime.js +1 -1
- package/dist/substrates/e2b/sandbox.d.ts +4 -4
- package/dist/substrates/e2b/sandbox.js +2 -2
- package/dist/substrates/e2b/sdk.d.ts +12 -12
- package/dist/substrates/e2b/sdk.js +7 -7
- package/dist/substrates/local/runtime-config.d.ts +4 -4
- package/dist/substrates/local/runtime-config.js +4 -4
- package/dist/tui/actions.d.ts +1 -1
- package/dist/tui/actions.js +13 -13
- package/dist/tui/contract.d.ts +23 -23
- package/dist/tui/contract.js +11 -11
- package/dist/tui/launch.d.ts +7 -7
- package/dist/tui/launch.js +36 -31
- package/dist/tui/project.js +5 -5
- package/dist/tui-app.js +139 -139
- package/dist/verify/actor.d.ts +8 -8
- package/dist/verify/actor.js +36 -36
- package/dist/verify/artifacts.d.ts +2 -2
- package/dist/verify/artifacts.js +3 -3
- package/dist/verify/context-growth.d.ts +9 -0
- package/dist/verify/context-growth.js +62 -0
- package/dist/verify/costs.d.ts +6 -6
- package/dist/verify/costs.js +8 -8
- package/dist/verify/shared-world-concurrent.d.ts +2 -2
- package/dist/verify/shared-world-concurrent.js +79 -76
- package/dist/verify/shared-world.d.ts +2 -2
- package/dist/verify/shared-world.js +16 -16
- package/dist/verify/subject.d.ts +5 -5
- package/dist/verify/subject.js +19 -19
- package/dist/verify/verify.js +94 -44
- package/docs/README.md +25 -32
- package/docs/architecture/actor-contract.md +60 -91
- package/docs/architecture/browser-control.md +1 -1
- package/docs/architecture/desktop-sessions.md +7 -7
- package/docs/architecture/external-public-shared-world.md +68 -65
- package/docs/architecture/github-feedback-loop.md +2 -5
- package/docs/architecture/guest-desktop.md +2 -2
- package/docs/architecture/observer.md +34 -34
- package/docs/architecture/restricted-codex-analysis.md +34 -28
- package/docs/architecture/serve.md +34 -37
- package/docs/architecture/state-driven-executor.md +55 -58
- package/docs/architecture/task-protocol-support.md +6 -6
- package/docs/architecture/terminal-product-route.md +70 -110
- package/docs/contracts/README.md +24 -0
- package/docs/contracts/adapter-admission.md +3 -3
- package/docs/contracts/adapter-fixtures.md +4 -7
- package/docs/contracts/core.md +1 -3
- package/docs/contracts/errors.md +62 -0
- package/docs/contracts/feedback.md +8 -9
- package/docs/contracts/policy.md +7 -12
- package/docs/contracts/run-bundle.md +42 -44
- package/docs/contracts/schemas.md +446 -368
- package/docs/contracts/study-analysis.md +7 -4
- package/docs/contracts/study-costs.md +28 -9
- package/docs/decisions/0001-run-bundle-is-the-source-of-truth.md +1 -1
- package/docs/decisions/0002-observer-is-one-self-contained-file.md +2 -2
- package/docs/decisions/0003-contained-paths-and-cleanup-authority.md +3 -3
- package/docs/principles/actor-fidelity.md +4 -4
- package/docs/principles/engineering.md +3 -3
- package/docs/principles/invariants-and-defaults.md +38 -38
- package/docs/principles/self-driving-harness.md +1 -5
- package/docs/principles/three-roles.md +1 -1
- package/docs/product/automatic-analysis.md +7 -7
- package/examples/README.md +1 -1
- package/examples/participant/README.md +5 -5
- package/examples/participant/run.mjs +11 -10
- package/examples/scorer/README.md +3 -3
- package/examples/scorer/run.mjs +11 -12
- package/examples/scorer/scorer.mjs +3 -3
- package/package.json +16 -17
- package/skills/humanish/SKILL.md +64 -60
- package/skills/humanish/agents/openai.yaml +1 -1
- package/AGENTS.md +0 -99
- package/CONTRIBUTING.md +0 -148
- package/dist/actors/codex/qualified-versions.d.ts +0 -72
- package/dist/actors/codex/qualified-versions.js +0 -132
- package/dist/cli/commands/lab-format.d.ts +0 -8
- package/dist/cli/commands/lab-route-run.d.ts +0 -19
- package/dist/cli/commands/lab-route-scripted.d.ts +0 -17
- package/dist/cli/commands/lab-route-terminal.d.ts +0 -17
- package/dist/cli/commands/lab-run.d.ts +0 -9
- package/dist/cli/commands/lab.d.ts +0 -3
- package/dist/cli/commands/lab.js +0 -199
- package/dist/cli/renamed-options.d.ts +0 -11
- package/dist/cli/renamed-options.js +0 -18
- package/dist/lab/composition-rules.d.ts +0 -7
- package/dist/lab/config.d.ts +0 -7
- package/dist/lab/discover.d.ts +0 -65
- package/dist/lab/init-templates.js +0 -416
- package/dist/lab/keys.d.ts +0 -2
- package/dist/lab/parse/comms.d.ts +0 -12
- package/dist/lab/parse/execution.d.ts +0 -19
- package/dist/lab/parse/subject-state.d.ts +0 -30
- package/dist/lab/plan.d.ts +0 -19
- package/dist/lab/plan.js +0 -132
- package/dist/lab/preflight-probes.d.ts +0 -3
- package/dist/lab/preflight-result.d.ts +0 -7
- package/dist/lab/preflight.d.ts +0 -92
- package/dist/lab/route-inputs.d.ts +0 -28
- package/dist/lab/run-lab-options.d.ts +0 -28
- package/dist/lab/warnings.d.ts +0 -2
- package/dist/observer/static.d.ts +0 -39
- package/dist/observer/static.js +0 -369
- package/dist/run-lab.d.ts +0 -112
- package/docs/architecture/comms-inbox.md +0 -122
- package/docs/architecture/desktop-recording.md +0 -80
- package/docs/architecture/local-browser-runtime.md +0 -178
- package/docs/architecture/observer-review.md +0 -144
- package/docs/architecture/participant-media.md +0 -90
- package/docs/architecture/project-layout.md +0 -62
- package/docs/architecture/real-email-receiving.md +0 -136
- package/docs/assets/humanish-drawdb-hero.png +0 -0
- package/docs/assets/humanish-observer-hero.png +0 -0
- package/docs/goals/current.md +0 -207
- package/docs/product/lobby-trivia-3player-external-public.md +0 -77
- package/docs/product/open-source-install-experience.md +0 -240
- package/docs/ramp/README.md +0 -295
- package/docs/release/open-source-readiness.md +0 -222
- package/docs/release/public-readiness-standard.md +0 -210
- package/docs/roadmap/world-class-open-source-v0.md +0 -311
- /package/dist/{lab → study}/init-paths.d.ts +0 -0
- /package/dist/{lab → study}/init-paths.js +0 -0
- /package/dist/{lab → study}/init-plan.d.ts +0 -0
- /package/dist/{lab → study}/init-plan.js +0 -0
- /package/dist/{lab → study}/participant-assignment.d.ts +0 -0
- /package/dist/{lab → study}/participant-assignment.js +0 -0
- /package/dist/{lab → study}/persona.d.ts +0 -0
- /package/dist/{lab → study}/persona.js +0 -0
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
//
|
|
1
|
+
// One Claude Code process as the computer-use brain, instead of a fresh `claude -p` per turn.
|
|
2
2
|
//
|
|
3
|
-
//
|
|
4
|
-
// so the participant remembers what it tried. `claude` spawned `claude -p` per turn, so
|
|
5
|
-
// turn started cold. Measured on the same
|
|
3
|
+
// Why: `actors[].localAgent: codex` already runs through a persistent app-server thread,
|
|
4
|
+
// so the participant remembers what it tried. `claude` spawned `claude -p` per turn, so every
|
|
5
|
+
// turn started cold. Measured on the same study with the same credentials (n=1 each): one-shot,
|
|
6
6
|
// 188 actions over 90 turns and never finished; a thread that remembers, 21 actions over 8 turns
|
|
7
7
|
// and goal_satisfied in 103 s. A participant that cannot remember trying the menu tries the menu
|
|
8
8
|
// again. Until this existed, comparing the two agents measured the transport, not the model.
|
|
9
9
|
//
|
|
10
|
-
//
|
|
10
|
+
// The mechanism, checked on this machine before it was written: `claude -p --input-format
|
|
11
11
|
// stream-json --output-format stream-json --verbose` is a bidirectional session over stdio. One
|
|
12
12
|
// NDJSON `user` message in, a stream of `system` / `assistant` / `result` messages out, then it
|
|
13
13
|
// waits for the next `user` message with the conversation intact. Two messages, one session id,
|
|
14
14
|
// and a codeword given in the first turn was recalled in the second. `--allowedTools Read` keeps
|
|
15
15
|
// the bound the one-shot version had: it looks at a picture, and that is all it can do.
|
|
16
16
|
//
|
|
17
|
-
// What this is
|
|
17
|
+
// What this is not: a change to the loop, the executor, the trace, or the Observer. Only where
|
|
18
18
|
// the next action comes from.
|
|
19
19
|
import { spawn } from "node:child_process";
|
|
20
20
|
import { randomUUID } from "node:crypto";
|
|
@@ -22,7 +22,7 @@ import { mkdtemp, rm, unlink, writeFile } from "node:fs/promises";
|
|
|
22
22
|
import { tmpdir } from "node:os";
|
|
23
23
|
import path from "node:path";
|
|
24
24
|
import readline from "node:readline";
|
|
25
|
-
import {
|
|
25
|
+
import { ComputerUseProviderError } from "../computer-use/provider-error.js";
|
|
26
26
|
import { declaredOutcomeOf, parseAgentJson, promptFor, toCuaActions, LOCAL_AGENT_CAPABILITIES, } from "./cli.js";
|
|
27
27
|
/** How long Claude Code may take to acknowledge an interrupt before the session is ended. */
|
|
28
28
|
const INTERRUPT_RECEIPT_TIMEOUT_MS = 5_000;
|
|
@@ -221,7 +221,7 @@ export function userMessage(text) {
|
|
|
221
221
|
}
|
|
222
222
|
/**
|
|
223
223
|
* Start one Claude Code session and return a provider that spends it, one user message per
|
|
224
|
-
* computer-use turn. Started
|
|
224
|
+
* computer-use turn. Started eagerly (before the first screenshot) so the CLI's own boot is paid
|
|
225
225
|
* while the sandbox is still settling rather than inside turn one.
|
|
226
226
|
*/
|
|
227
227
|
export async function startClaudeSession(options = {}) {
|
|
@@ -240,7 +240,7 @@ export async function startClaudeSession(options = {}) {
|
|
|
240
240
|
"stream-json",
|
|
241
241
|
// Required for stream-json output in -p mode; it is what makes the per-turn `result` visible.
|
|
242
242
|
"--verbose",
|
|
243
|
-
// Read is the only tool it needs
|
|
243
|
+
// Read is the only tool it needs (the screenshot) and the only one it gets.
|
|
244
244
|
"--allowedTools",
|
|
245
245
|
"Read",
|
|
246
246
|
...(options.model === undefined ? [] : ["--model", options.model]),
|
|
@@ -274,6 +274,7 @@ export async function startClaudeSession(options = {}) {
|
|
|
274
274
|
: `\n\nNote from the harness: ${request.contextHint}`;
|
|
275
275
|
// The persona and the reply shape are in the conversation after turn one; re-sending them
|
|
276
276
|
// every turn is what the one-shot version had to do, and it is most of what it cost.
|
|
277
|
+
// prose-check: model prompt (the participant model reads this, not a person)
|
|
277
278
|
const text = turnIndex === 1
|
|
278
279
|
? promptFor(request, shot)
|
|
279
280
|
: `Read the image file ${shot}. That is the CURRENT SCREEN, after your last actions took effect. ` +
|
|
@@ -288,7 +289,7 @@ export async function startClaudeSession(options = {}) {
|
|
|
288
289
|
usageIncomplete = true;
|
|
289
290
|
if (error instanceof ClaudeSessionDesyncError) {
|
|
290
291
|
// The stream no longer pairs results with turns, so no later turn can trust it.
|
|
291
|
-
throw new
|
|
292
|
+
throw new ComputerUseProviderError("protocol_error", {
|
|
292
293
|
dispatched: "unknown",
|
|
293
294
|
usageComplete: false,
|
|
294
295
|
cleanup: "unconfirmed",
|
|
@@ -316,7 +317,7 @@ export async function startClaudeSession(options = {}) {
|
|
|
316
317
|
export function turnFromResult(result) {
|
|
317
318
|
if (result.is_error === true ||
|
|
318
319
|
(typeof result.subtype === "string" && result.subtype !== "success")) {
|
|
319
|
-
// A turn that errored is a
|
|
320
|
+
// A turn that errored is a broken turn, never an empty one: an empty turn reads to the loop
|
|
320
321
|
// as "the participant chose to do nothing".
|
|
321
322
|
throw new Error(`Claude Code turn ended ${String(result.subtype ?? "in error")}: ${String(result.result ?? "").slice(0, 160)}`);
|
|
322
323
|
}
|
|
@@ -354,7 +355,7 @@ export function turnFromResult(result) {
|
|
|
354
355
|
...(typeof parsed.message === "string" && parsed.message.length > 0
|
|
355
356
|
? { message: parsed.message }
|
|
356
357
|
: {}),
|
|
357
|
-
// Claude Code reports its token counts per turn
|
|
358
|
+
// Claude Code reports its token counts per turn. They are recorded as counts; the
|
|
358
359
|
// run's cost line stays "not priced", because a subscription is not a rate card.
|
|
359
360
|
...(input === undefined && output === undefined
|
|
360
361
|
? {}
|
|
@@ -20,7 +20,7 @@ interface RawAction {
|
|
|
20
20
|
ms?: number | null;
|
|
21
21
|
}
|
|
22
22
|
/**
|
|
23
|
-
* Map the agent's answer onto the harness action vocabulary. Anything unrecognized is
|
|
23
|
+
* Map the agent's answer onto the harness action vocabulary. Anything unrecognized is dropped
|
|
24
24
|
* rather than guessed at: a coordinate we invented would be recorded as the participant's choice.
|
|
25
25
|
*/
|
|
26
26
|
export declare function toCuaActions(raw: readonly RawAction[]): CuaAction[];
|
|
@@ -29,7 +29,7 @@ export declare function declaredOutcomeOf(value: unknown): ParticipantDeclaredOu
|
|
|
29
29
|
/**
|
|
30
30
|
* Pull the JSON object out of whatever the CLI printed: clean JSON, a Claude Code envelope, or an
|
|
31
31
|
* answer wrapped in a ```json fence. A response with no object at all is a turn error, never an
|
|
32
|
-
* empty turn
|
|
32
|
+
* empty turn: an empty turn would read to the loop as "the participant chose to do nothing".
|
|
33
33
|
*/
|
|
34
34
|
export declare function parseAgentJson(text: string): Record<string, unknown>;
|
|
35
35
|
export interface SpawnResult {
|
|
@@ -49,7 +49,7 @@ export interface LocalAgentProviderOptions {
|
|
|
49
49
|
timeoutMs?: number;
|
|
50
50
|
/**
|
|
51
51
|
* Recorded in the trace's model settings. Low by default: a computer-use run is sixty turns, and
|
|
52
|
-
* a high-effort answer per turn costs minutes. The
|
|
52
|
+
* a high-effort answer per turn costs minutes. The study can raise it.
|
|
53
53
|
*/
|
|
54
54
|
reasoningEffort?: ReasoningEffort;
|
|
55
55
|
/** Model override passed to the CLI (`--model`). Absent = the CLI's own default. */
|
|
@@ -74,7 +74,7 @@ export interface DetectedLocalAgent extends LocalAgentDescriptor {
|
|
|
74
74
|
/** Resolved path to the binary. */
|
|
75
75
|
binPath: string;
|
|
76
76
|
/**
|
|
77
|
-
* Whether a credential file exists for it.
|
|
77
|
+
* Whether a credential file exists for it. Existence only: never read, never parsed, never
|
|
78
78
|
* reported beyond this boolean. Keyring storage may have no file at all.
|
|
79
79
|
*/
|
|
80
80
|
credentialsPresent: boolean;
|
|
@@ -106,10 +106,12 @@ export declare function checkHostedCodexCompatibility(binPath: string, options?:
|
|
|
106
106
|
*
|
|
107
107
|
* This is the whole point of the feature at the surface: someone new does not have to go and make
|
|
108
108
|
* an API key if the thing that can drive the study is already on their laptop. `doctor` says so,
|
|
109
|
-
* and says it as a capability rather than a gate
|
|
109
|
+
* and says it as a capability rather than a gate: a machine with no local agent is not broken,
|
|
110
110
|
* it just needs a key.
|
|
111
111
|
*/
|
|
112
112
|
export declare function detectLocalAgents(options?: DetectLocalAgentsOptions): Promise<DetectedLocalAgent[]>;
|
|
113
|
-
/**
|
|
114
|
-
export declare
|
|
113
|
+
/** Doctor's row when neither Codex nor Claude Code is installed. */
|
|
114
|
+
export declare const NO_LOCAL_AGENT_MESSAGE = "no local coding agent found. openai-computer-use needs OPENAI_API_KEY; local-agent needs Codex or Claude Code installed and signed in. Hosted desktops also need E2B_API_KEY.";
|
|
115
|
+
/** Doctor's row for one installed agent, in the register the other rows use. */
|
|
116
|
+
export declare function localAgentDoctorMessage(agent: DetectedLocalAgent): string;
|
|
115
117
|
export {};
|
|
@@ -11,22 +11,22 @@
|
|
|
11
11
|
// The design started from a measurement: with every OPENAI_* variable unset, `codex exec --image`
|
|
12
12
|
// returned a correct click on a real desktop screenshot and `claude -p` agreed within three pixels.
|
|
13
13
|
//
|
|
14
|
-
//
|
|
15
|
-
// which is why the cost line for these runs says "not priced"
|
|
14
|
+
// What this is not: a way to avoid paying. Subscription usage consumes the operator's own plan,
|
|
15
|
+
// which is why the cost line for these runs says "not priced": $0 would be a lie.
|
|
16
16
|
// It is also not marketed as free API access, and it fails closed on a rate limit rather than
|
|
17
17
|
// hammering a plan that was sold for interactive coding.
|
|
18
18
|
//
|
|
19
|
-
//
|
|
19
|
+
// Where it is safe, and this inverts the intuitive reading: the local agent only decides. humanish
|
|
20
20
|
// executes the action inside the desktop sandbox, so nothing the persona chooses ever runs on the
|
|
21
|
-
// operator's machine. The same trick on the
|
|
22
|
-
// code execution out of the sandbox and onto a real disk
|
|
21
|
+
// operator's machine. The same trick on the terminal route would be the opposite: it would move
|
|
22
|
+
// code execution out of the sandbox and onto a real disk, which is why this is a computer-use
|
|
23
23
|
// provider and nothing else. Even so, these are coding agents with their own shell and file tools,
|
|
24
24
|
// so each one is spawned tool-restricted, in a scratch directory, with a per-turn timeout.
|
|
25
25
|
import { spawn } from "node:child_process";
|
|
26
26
|
import { mkdtemp, rm, writeFile } from "node:fs/promises";
|
|
27
27
|
import { tmpdir } from "node:os";
|
|
28
28
|
import path from "node:path";
|
|
29
|
-
import {
|
|
29
|
+
import { admitsCodexCliVersion, parseCodexCliVersion } from "../codex/codex-admission.js";
|
|
30
30
|
import { restrictedCodexNpmTarget } from "../codex/restricted-executable.js";
|
|
31
31
|
const LOCAL_AGENTS = [
|
|
32
32
|
{ id: "codex", bin: "codex", label: "Codex", credentialPath: ".codex/auth.json" },
|
|
@@ -38,7 +38,7 @@ const LOCAL_AGENTS = [
|
|
|
38
38
|
},
|
|
39
39
|
];
|
|
40
40
|
/**
|
|
41
|
-
* Map the agent's answer onto the harness action vocabulary. Anything unrecognized is
|
|
41
|
+
* Map the agent's answer onto the harness action vocabulary. Anything unrecognized is dropped
|
|
42
42
|
* rather than guessed at: a coordinate we invented would be recorded as the participant's choice.
|
|
43
43
|
*/
|
|
44
44
|
export function toCuaActions(raw) {
|
|
@@ -90,11 +90,11 @@ export function declaredOutcomeOf(value) {
|
|
|
90
90
|
/**
|
|
91
91
|
* Pull the JSON object out of whatever the CLI printed: clean JSON, a Claude Code envelope, or an
|
|
92
92
|
* answer wrapped in a ```json fence. A response with no object at all is a turn error, never an
|
|
93
|
-
* empty turn
|
|
93
|
+
* empty turn: an empty turn would read to the loop as "the participant chose to do nothing".
|
|
94
94
|
*/
|
|
95
95
|
export function parseAgentJson(text) {
|
|
96
|
-
//
|
|
97
|
-
//
|
|
96
|
+
// Order matters, and a test caught it: Claude Code's envelope is valid JSON whose `result`
|
|
97
|
+
// string contains a ```json fence. Stripping fences first reached inside that string and
|
|
98
98
|
// mangled the envelope. So: parse what we were given, and only go fence-hunting if it is not
|
|
99
99
|
// already JSON.
|
|
100
100
|
const attempts = [text.trim()];
|
|
@@ -167,6 +167,7 @@ export function promptFor(request, screenshotPath) {
|
|
|
167
167
|
const shape = '{"reasoning":string,"done":boolean,"message":string|null,"outcome":"reached"|"not_reached"|"blocked"|null,' +
|
|
168
168
|
'"actions":[{"kind":"click|double_click|type|keypress|scroll|wait|done",' +
|
|
169
169
|
'"x":int|null,"y":int|null,"text":string|null,"keys":[string]|null,"ms":int|null}]}';
|
|
170
|
+
// prose-check: model prompt (the participant model reads this, not a person)
|
|
170
171
|
return [
|
|
171
172
|
request.instructions,
|
|
172
173
|
"",
|
|
@@ -217,7 +218,7 @@ export function createLocalAgentProvider(options) {
|
|
|
217
218
|
"-p",
|
|
218
219
|
"--output-format",
|
|
219
220
|
"json",
|
|
220
|
-
// Read is the only tool it needs
|
|
221
|
+
// Read is the only tool it needs (the screenshot) and the only one it gets.
|
|
221
222
|
"--allowedTools",
|
|
222
223
|
"Read",
|
|
223
224
|
...(options.model === undefined ? [] : ["--model", options.model]),
|
|
@@ -339,9 +340,7 @@ export async function checkHostedCodexCompatibility(binPath, options = {}) {
|
|
|
339
340
|
return "unsupported_platform";
|
|
340
341
|
const result = await (options.probe ?? authProbe)(binPath, ["--version"], options.env ?? process.env).catch(() => ({ code: null, stdout: "", stderr: "" }));
|
|
341
342
|
const version = parseCodexCliVersion(result.stdout);
|
|
342
|
-
return result.code === 0 &&
|
|
343
|
-
version !== undefined &&
|
|
344
|
-
admittedCodexCliVersions(platform, arch).some((admitted) => admitted === version)
|
|
343
|
+
return result.code === 0 && version !== undefined && admitsCodexCliVersion(version)
|
|
345
344
|
? "supported"
|
|
346
345
|
: "unsupported_version";
|
|
347
346
|
}
|
|
@@ -350,7 +349,7 @@ export async function checkHostedCodexCompatibility(binPath, options = {}) {
|
|
|
350
349
|
*
|
|
351
350
|
* This is the whole point of the feature at the surface: someone new does not have to go and make
|
|
352
351
|
* an API key if the thing that can drive the study is already on their laptop. `doctor` says so,
|
|
353
|
-
* and says it as a capability rather than a gate
|
|
352
|
+
* and says it as a capability rather than a gate: a machine with no local agent is not broken,
|
|
354
353
|
* it just needs a key.
|
|
355
354
|
*/
|
|
356
355
|
export async function detectLocalAgents(options = {}) {
|
|
@@ -397,17 +396,14 @@ export async function detectLocalAgents(options = {}) {
|
|
|
397
396
|
}
|
|
398
397
|
return found;
|
|
399
398
|
}
|
|
400
|
-
/**
|
|
401
|
-
export
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
: `${agent.label} installed; authentication status could not be checked — run \`${agent.id === "codex" ? "codex login status" : "claude auth status"}\` and update the CLI if needed`)
|
|
411
|
-
.join(". ") +
|
|
412
|
-
". Desktop and analysis requirements depend on the selected lab; run doctor --lab <lab> for its setup checks.");
|
|
399
|
+
/** Doctor's row when neither Codex nor Claude Code is installed. */
|
|
400
|
+
export const NO_LOCAL_AGENT_MESSAGE = "no local coding agent found. openai-computer-use needs OPENAI_API_KEY; local-agent needs Codex or Claude Code installed and signed in. Hosted desktops also need E2B_API_KEY.";
|
|
401
|
+
/** Doctor's row for one installed agent, in the register the other rows use. */
|
|
402
|
+
export function localAgentDoctorMessage(agent) {
|
|
403
|
+
if (agent.authStatus === "authenticated")
|
|
404
|
+
return `${agent.label} reports signed in; a study with actors[0].type: local-agent can use it instead of a provider API key. Account access and limits are untested.`;
|
|
405
|
+
const status = agent.id === "codex" ? "codex login status" : "claude auth status";
|
|
406
|
+
return agent.authStatus === "unauthenticated"
|
|
407
|
+
? `${agent.label} is installed and reports not signed in; run \`${agent.id === "codex" ? "codex login" : "claude auth login"}\``
|
|
408
|
+
: `${agent.label} is installed; its sign-in status could not be checked. Run \`${status}\`, and update the CLI if needed.`;
|
|
413
409
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type LocalAgentId } from "./cli.js";
|
|
2
2
|
/** Why a local-agent participant cannot run here. */
|
|
3
3
|
export type LocalAgentRefusal =
|
|
4
|
-
/** The CLI is not on PATH
|
|
4
|
+
/** The CLI is not on `PATH`. */
|
|
5
5
|
{
|
|
6
6
|
kind: "agent-missing";
|
|
7
7
|
message: string;
|
|
@@ -11,7 +11,7 @@ export type LocalAgentRefusal =
|
|
|
11
11
|
kind: "signin-required";
|
|
12
12
|
message: string;
|
|
13
13
|
}
|
|
14
|
-
/** Hosted Codex on an unsupported platform or
|
|
14
|
+
/** Hosted Codex on an unsupported platform or a CLI release the launcher refuses. */
|
|
15
15
|
| {
|
|
16
16
|
kind: "unsupported";
|
|
17
17
|
message: string;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// Whether a local-agent participant can run on this machine before anything is acquired: its CLI
|
|
2
|
-
// is on PATH and signed in, a hosted Codex CLI is a qualified release on a supported platform, and
|
|
2
|
+
// is on `PATH` and signed in, a hosted Codex CLI is a qualified release on a supported platform, and
|
|
3
3
|
// a ChatGPT-account Codex is not asked to enforce a dollar cap it has no price for. Each route maps
|
|
4
4
|
// the refusal's kind to its own error code.
|
|
5
|
-
import {
|
|
5
|
+
import { describeCodexCliAdmission } from "../codex/codex-admission.js";
|
|
6
6
|
import { checkHostedCodexCompatibility, detectLocalAgents } from "./cli.js";
|
|
7
7
|
export async function localAgentRefusal(args) {
|
|
8
8
|
const { agent, env, caps } = args;
|
|
@@ -19,7 +19,7 @@ export async function localAgentRefusal(args) {
|
|
|
19
19
|
return {
|
|
20
20
|
kind: "signin-required",
|
|
21
21
|
message: chosen.authStatus === "unauthenticated"
|
|
22
|
-
? `${chosen.label} reports not signed in
|
|
22
|
+
? `${chosen.label} reports it is not signed in; run \`${chosen.id === "codex" ? "codex login" : "claude auth login"}\`, then retry.`
|
|
23
23
|
: `${chosen.label} authentication status could not be checked. Run \`${chosen.id === "codex" ? "codex login status" : "claude auth status"}\` and update the CLI if needed. No desktop was launched.`,
|
|
24
24
|
};
|
|
25
25
|
}
|
|
@@ -31,7 +31,7 @@ export async function localAgentRefusal(args) {
|
|
|
31
31
|
kind: "unsupported",
|
|
32
32
|
message: compatibility === "unsupported_platform"
|
|
33
33
|
? `Hosted Codex participants require Linux or macOS on x64 or arm64. This host is ${process.platform}/${process.arch}; no desktop was launched.`
|
|
34
|
-
: `Hosted Codex participants
|
|
34
|
+
: `Hosted Codex participants need a Codex CLI release humanish runs: ${describeCodexCliAdmission()}. Run \`humanish doctor\` for the release it found and the command that replaces it; no desktop was launched.`,
|
|
35
35
|
};
|
|
36
36
|
}
|
|
37
37
|
if (chosen.billing === "account-unknown" &&
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
// The provider-declared reasoning-effort vocabulary, kept in its own module so the
|
|
1
|
+
// The provider-declared reasoning-effort vocabulary, kept in its own module so the study schema and
|
|
2
2
|
// the OpenAI provider can share it without the schema depending on a provider.
|
|
3
3
|
//
|
|
4
|
-
//
|
|
5
|
-
// computer-use run humanish had ever done was therefore the provider default
|
|
6
|
-
// by omission
|
|
4
|
+
// Why this exists: effort was reachable in the provider and unreachable from a study. Every
|
|
5
|
+
// computer-use run humanish had ever done was therefore the provider default, not by decision but
|
|
6
|
+
// by omission. Effort changes who the participant is, the same way a persona prompt does
|
|
7
7
|
// (docs/principles/actor-fidelity.md: capability settings are recruiting decisions), so pinning it
|
|
8
8
|
// invisibly meant every persona finding was really a finding about that persona at medium, with the
|
|
9
9
|
// second half unsaid.
|
|
10
10
|
//
|
|
11
|
-
//
|
|
11
|
+
// Support is model-dependent. OpenAI documents the vocabulary below as the union across models and
|
|
12
12
|
// states plainly that "supported values are model-dependent"; there is no offline way to know which
|
|
13
|
-
// subset a given model id accepts. So this module refuses to pretend: it validates that a
|
|
14
|
-
// for a
|
|
13
|
+
// subset a given model id accepts. So this module refuses to pretend: it validates that a study asked
|
|
14
|
+
// for a real effort level, and a model that does not support the one it was asked for fails on the
|
|
15
15
|
// first turn with the provider's own message rather than being silently downgraded. Silent
|
|
16
|
-
// downgrade is the worse failure
|
|
16
|
+
// downgrade is the worse failure: it would record an effort the run did not actually use.
|
|
17
17
|
/** The documented vocabulary, ordered from least to most reasoning. */
|
|
18
18
|
export const REASONING_EFFORTS = [
|
|
19
19
|
"none",
|
|
@@ -27,27 +27,27 @@ export interface TerminalActorDescriptor extends ActorDescriptorBase {
|
|
|
27
27
|
}
|
|
28
28
|
export type ActorDescriptor = CodexActorDescriptor | CuaActorDescriptor | ScriptedBrowserActorDescriptor | TerminalActorDescriptor;
|
|
29
29
|
/**
|
|
30
|
-
*
|
|
31
|
-
* CuaActorDescriptor
|
|
30
|
+
* Registry contract: an actor whose capabilities include the "computer-use" run kind is a
|
|
31
|
+
* CuaActorDescriptor: its runSession takes CuaActorSessionOptions and returns a CuaLoopResult.
|
|
32
32
|
* Any future computer-use provider (e.g. stagehand-cua) must keep that session signature and add
|
|
33
33
|
* its id to CuaActorDescriptor["id"], so code narrowed by this guard can still tell the ids apart.
|
|
34
|
-
* This guard is what lets
|
|
34
|
+
* This guard is what lets humanish dispatch on capabilities rather than on hardcoded actor ids.
|
|
35
35
|
*/
|
|
36
36
|
export declare function isCuaActorDescriptor(descriptor: ActorDescriptor): descriptor is CuaActorDescriptor;
|
|
37
37
|
/**
|
|
38
|
-
*
|
|
39
|
-
* "scripted-browser"
|
|
38
|
+
* Registry contract (mirror of isCuaActorDescriptor): an actor whose capabilities include the
|
|
39
|
+
* "scripted-browser" run kind is a ScriptedBrowserActorDescriptor; runSession takes
|
|
40
40
|
* ScriptedBrowserSessionOptions and returns ScriptedBrowserSessionResult (trace fully formed,
|
|
41
|
-
* like the CUA shape
|
|
42
|
-
* replayer) must keep this signature; it is what lets
|
|
41
|
+
* like the CUA shape; no separate toActorTrace). Any future scripted driver (e.g. a HAR
|
|
42
|
+
* replayer) must keep this signature; it is what lets humanish dispatch on capabilities.
|
|
43
43
|
*/
|
|
44
44
|
export declare function isScriptedBrowserActorDescriptor(descriptor: ActorDescriptor): descriptor is ScriptedBrowserActorDescriptor;
|
|
45
45
|
/**
|
|
46
|
-
*
|
|
47
|
-
* whose capabilities include the "terminal"
|
|
48
|
-
* the terminal-product
|
|
49
|
-
* descriptor's direct runSession is intentionally unsupported; live execution is route-owned.
|
|
50
|
-
*
|
|
46
|
+
* Registry contract (mirror of isCuaActorDescriptor / isScriptedBrowserActorDescriptor): an actor
|
|
47
|
+
* whose capabilities include the "terminal" run kind is a TerminalActorDescriptor. This is the
|
|
48
|
+
* guard the terminal-product route uses for route selection and capability enforcement. The current
|
|
49
|
+
* descriptor's direct runSession is intentionally unsupported; live execution is route-owned. Any
|
|
50
|
+
* future terminal actor must declare the keyPlacement it uses and integrate with that lifecycle.
|
|
51
51
|
*/
|
|
52
52
|
export declare function isTerminalActorDescriptor(descriptor: ActorDescriptor): descriptor is TerminalActorDescriptor;
|
|
53
53
|
export declare const actorRegistry: Record<ActorId, ActorDescriptor>;
|
package/dist/actors/registry.js
CHANGED
|
@@ -6,31 +6,31 @@ import { LOCAL_AGENT_CAPABILITIES } from "./local-agent/cli.js";
|
|
|
6
6
|
import { OPENAI_RESPONSES_CU_CAPABILITIES } from "./computer-use/openai-provider.js";
|
|
7
7
|
import { runScriptedBrowserSession, } from "./scripted-browser/actor.js";
|
|
8
8
|
/**
|
|
9
|
-
*
|
|
10
|
-
* CuaActorDescriptor
|
|
9
|
+
* Registry contract: an actor whose capabilities include the "computer-use" run kind is a
|
|
10
|
+
* CuaActorDescriptor: its runSession takes CuaActorSessionOptions and returns a CuaLoopResult.
|
|
11
11
|
* Any future computer-use provider (e.g. stagehand-cua) must keep that session signature and add
|
|
12
12
|
* its id to CuaActorDescriptor["id"], so code narrowed by this guard can still tell the ids apart.
|
|
13
|
-
* This guard is what lets
|
|
13
|
+
* This guard is what lets humanish dispatch on capabilities rather than on hardcoded actor ids.
|
|
14
14
|
*/
|
|
15
15
|
export function isCuaActorDescriptor(descriptor) {
|
|
16
16
|
return descriptor.capabilities.lanes.includes("computer-use");
|
|
17
17
|
}
|
|
18
18
|
/**
|
|
19
|
-
*
|
|
20
|
-
* "scripted-browser"
|
|
19
|
+
* Registry contract (mirror of isCuaActorDescriptor): an actor whose capabilities include the
|
|
20
|
+
* "scripted-browser" run kind is a ScriptedBrowserActorDescriptor; runSession takes
|
|
21
21
|
* ScriptedBrowserSessionOptions and returns ScriptedBrowserSessionResult (trace fully formed,
|
|
22
|
-
* like the CUA shape
|
|
23
|
-
* replayer) must keep this signature; it is what lets
|
|
22
|
+
* like the CUA shape; no separate toActorTrace). Any future scripted driver (e.g. a HAR
|
|
23
|
+
* replayer) must keep this signature; it is what lets humanish dispatch on capabilities.
|
|
24
24
|
*/
|
|
25
25
|
export function isScriptedBrowserActorDescriptor(descriptor) {
|
|
26
26
|
return descriptor.capabilities.lanes.includes("scripted-browser");
|
|
27
27
|
}
|
|
28
28
|
/**
|
|
29
|
-
*
|
|
30
|
-
* whose capabilities include the "terminal"
|
|
31
|
-
* the terminal-product
|
|
32
|
-
* descriptor's direct runSession is intentionally unsupported; live execution is route-owned.
|
|
33
|
-
*
|
|
29
|
+
* Registry contract (mirror of isCuaActorDescriptor / isScriptedBrowserActorDescriptor): an actor
|
|
30
|
+
* whose capabilities include the "terminal" run kind is a TerminalActorDescriptor. This is the
|
|
31
|
+
* guard the terminal-product route uses for route selection and capability enforcement. The current
|
|
32
|
+
* descriptor's direct runSession is intentionally unsupported; live execution is route-owned. Any
|
|
33
|
+
* future terminal actor must declare the keyPlacement it uses and integrate with that lifecycle.
|
|
34
34
|
*/
|
|
35
35
|
export function isTerminalActorDescriptor(descriptor) {
|
|
36
36
|
return descriptor.capabilities.lanes.includes("terminal");
|
|
@@ -43,13 +43,14 @@ export const actorRegistry = {
|
|
|
43
43
|
runSession: runCodexAppServerSession,
|
|
44
44
|
toActorTrace: codexResultToActorTrace,
|
|
45
45
|
},
|
|
46
|
-
// The ActorId names the actor slot (keeps the
|
|
47
|
-
// the trace's `provider` string stays "openai-responses-cu" (the concrete model
|
|
48
|
-
// The operator's own signed-in coding agent as the computer-use brain (Codex on a
|
|
49
|
-
// Claude Code on a Max plan). Same
|
|
50
|
-
// the next action comes from, which is exactly why it is a provider swap and
|
|
51
|
-
// It exists so someone new can watch a persona drive a real desktop
|
|
52
|
-
// an API key; the machine they are on very often already has one of
|
|
46
|
+
// The ActorId names the actor slot (keeps the slot open for a future stagehand-cua
|
|
47
|
+
// provider); the trace's `provider` string stays "openai-responses-cu" (the concrete model
|
|
48
|
+
// adapter). The operator's own signed-in coding agent as the computer-use brain (Codex on a
|
|
49
|
+
// ChatGPT plan, Claude Code on a Max plan). Same run kind, same loop, same evidence; the only
|
|
50
|
+
// difference is where the next action comes from, which is exactly why it is a provider swap and
|
|
51
|
+
// not a new run kind. It exists so someone new can watch a persona drive a real desktop
|
|
52
|
+
// without first going to find an API key; the machine they are on very often already has one of
|
|
53
|
+
// these signed in.
|
|
53
54
|
"local-agent": {
|
|
54
55
|
id: "local-agent",
|
|
55
56
|
label: "Local coding agent (operator-authenticated)",
|
|
@@ -73,7 +74,7 @@ export const actorRegistry = {
|
|
|
73
74
|
},
|
|
74
75
|
// The ActorId names the terminal-product dispatch slot; the live route records the concrete
|
|
75
76
|
// provider as "codex". keyPlacement "in-sandbox-command-scoped" is registry-declared and
|
|
76
|
-
// enforced by
|
|
77
|
+
// enforced by runTerminalProductStudy before it creates a sandbox, which is where this actor runs.
|
|
77
78
|
"codex-exec": {
|
|
78
79
|
id: "codex-exec",
|
|
79
80
|
label: "Codex Exec (autonomous terminal agent, in-sandbox)",
|
|
@@ -10,12 +10,12 @@ export interface ScriptedBrowserSessionOptions {
|
|
|
10
10
|
urlPolicy?: ScriptedBrowserEvidenceUrlPolicy;
|
|
11
11
|
/** Parsed + validated by the backend (scenario.ref is consumed there, fail-closed). */
|
|
12
12
|
journey: BrowserPersonaJourney;
|
|
13
|
-
/**
|
|
13
|
+
/** One session per surface. */
|
|
14
14
|
surface: BrowserSurface;
|
|
15
15
|
/** id = actors[0].persona ?? "scripted-journey"; promptDigest = journey.sourceDigest prefix
|
|
16
|
-
* (the step manifest
|
|
16
|
+
* (the step manifest is the "prompt"; no model prompt exists on this route). */
|
|
17
17
|
persona: ActorPersonaRef;
|
|
18
|
-
/** Journey wall-clock budget in ms; the
|
|
18
|
+
/** Journey wall-clock budget in ms; the route passes execution.timeoutMs or 300_000. */
|
|
19
19
|
timeoutMs: number;
|
|
20
20
|
/** Absolute; the session writes screenshots/ and traces/<surface>.json beneath it. */
|
|
21
21
|
artifactRoot: string;
|
|
@@ -30,20 +30,20 @@ export interface ScriptedBrowserSessionResult extends ActorSessionResult {
|
|
|
30
30
|
capture: BrowserSurfaceCapture;
|
|
31
31
|
}
|
|
32
32
|
/**
|
|
33
|
-
* Run the scripted journey for
|
|
33
|
+
* Run the scripted journey for one surface and return native capture + ActorTrace projection.
|
|
34
34
|
*
|
|
35
35
|
* Completion semantics (the contract the projection tests pin):
|
|
36
36
|
* - every step executed, every assertion passed, HTTP probe ok -> passed / goal_satisfied
|
|
37
|
-
* (the scenario's expect blocks
|
|
37
|
+
* (the scenario's expect blocks are the success predicate; a pass claims "the app still
|
|
38
38
|
* affords this exact journey", nothing about user behavior);
|
|
39
39
|
* - a step's expectation evaluated false, a step target missing/unactionable, or an
|
|
40
|
-
* unreachable subject -> failed / step_failed (the harness executed faithfully; the
|
|
41
|
-
* did not satisfy the script
|
|
40
|
+
* unreachable subject -> failed / step_failed (the harness executed faithfully; the subject
|
|
41
|
+
* did not satisfy the script, distinct from actor_error/harness_error);
|
|
42
42
|
* - journey exceeded timeoutMs -> timed_out / timed_out;
|
|
43
43
|
* - browser launch/import crash -> failed / harness_error;
|
|
44
|
-
* - gave_up / blocked_approval are
|
|
45
|
-
* approvals exist on a deterministic replay)
|
|
44
|
+
* - gave_up / blocked_approval are unreachable from this actor (no persona patience, no
|
|
45
|
+
* approvals exist on a deterministic replay), asserted in tests.
|
|
46
46
|
*/
|
|
47
47
|
export declare function runScriptedBrowserSession(options: ScriptedBrowserSessionOptions): Promise<ScriptedBrowserSessionResult>;
|
|
48
|
-
/** Internal
|
|
48
|
+
/** Internal route seam: the run root is already prepared and must stay bound to that identity. */
|
|
49
49
|
export declare function runScriptedBrowserSessionInPreparedRoot(options: ScriptedBrowserSessionOptions, preparedArtifactRoot: PreparedOutputRoot): Promise<ScriptedBrowserSessionResult>;
|
|
@@ -9,12 +9,12 @@
|
|
|
9
9
|
// The step executor's `page` is typed as the narrow structural ScriptedPageLike instead of
|
|
10
10
|
// playwright's Page (browserPersonaPageState already took { evaluate, url }; E2BDesktopLike is
|
|
11
11
|
// the same seam pattern). playwright's real Page satisfies it; tests inject fakes and run
|
|
12
|
-
// the
|
|
12
|
+
// the real step executor at $0 with zero browser dependence. playwright-core stays the lazy
|
|
13
13
|
// production default behind launchPlaywrightChromium.
|
|
14
14
|
//
|
|
15
|
-
// Spend posture: nothing in this module can spend provider money
|
|
15
|
+
// Spend posture: nothing in this module can spend provider money: no provider client is
|
|
16
16
|
// importable from this code path. tokenUsage on every projected trace records zeros as an
|
|
17
|
-
// affirmative $0 declaration that is
|
|
17
|
+
// affirmative $0 declaration that is true by mechanism.
|
|
18
18
|
import { stat } from "node:fs/promises";
|
|
19
19
|
import path from "node:path";
|
|
20
20
|
import { CHROMIUM_EVIDENCE_HYGIENE_FLAGS } from "../../evidence/browser-hygiene.js";
|
|
@@ -24,7 +24,7 @@ import { ACTOR_TRACE_SCHEMA, SCRIPTED_BROWSER_CAPABILITIES, } from "../contract.
|
|
|
24
24
|
import { buildBlockedBrowserPersonaSteps, buildBrowserTrace, captureBlockedStepScreenshot, compactBrowserError, executeBrowserPersonaStep, probeAppUrl, sanitizeBrowserEvidenceUrl, screenshotPathForBrowserStep, surfaceScreenshotPath, tracePathForBrowserSurface, } from "./steps.js";
|
|
25
25
|
import { LOOPBACK_EVIDENCE_URL_POLICY, } from "./types.js";
|
|
26
26
|
/** Production default: lazy playwright-core import + chromium.launch, exactly as the driver
|
|
27
|
-
* always did. Kept in
|
|
27
|
+
* always did. Kept in one place so the optional peer is touched by exactly one code path. */
|
|
28
28
|
async function launchPlaywrightChromium(args) {
|
|
29
29
|
const { chromium } = await import("playwright-core");
|
|
30
30
|
const browser = await chromium.launch({
|
|
@@ -50,26 +50,26 @@ class ScriptedJourneyTimeoutError extends Error {
|
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
52
|
/**
|
|
53
|
-
* Run the scripted journey for
|
|
53
|
+
* Run the scripted journey for one surface and return native capture + ActorTrace projection.
|
|
54
54
|
*
|
|
55
55
|
* Completion semantics (the contract the projection tests pin):
|
|
56
56
|
* - every step executed, every assertion passed, HTTP probe ok -> passed / goal_satisfied
|
|
57
|
-
* (the scenario's expect blocks
|
|
57
|
+
* (the scenario's expect blocks are the success predicate; a pass claims "the app still
|
|
58
58
|
* affords this exact journey", nothing about user behavior);
|
|
59
59
|
* - a step's expectation evaluated false, a step target missing/unactionable, or an
|
|
60
|
-
* unreachable subject -> failed / step_failed (the harness executed faithfully; the
|
|
61
|
-
* did not satisfy the script
|
|
60
|
+
* unreachable subject -> failed / step_failed (the harness executed faithfully; the subject
|
|
61
|
+
* did not satisfy the script, distinct from actor_error/harness_error);
|
|
62
62
|
* - journey exceeded timeoutMs -> timed_out / timed_out;
|
|
63
63
|
* - browser launch/import crash -> failed / harness_error;
|
|
64
|
-
* - gave_up / blocked_approval are
|
|
65
|
-
* approvals exist on a deterministic replay)
|
|
64
|
+
* - gave_up / blocked_approval are unreachable from this actor (no persona patience, no
|
|
65
|
+
* approvals exist on a deterministic replay), asserted in tests.
|
|
66
66
|
*/
|
|
67
67
|
export async function runScriptedBrowserSession(options) {
|
|
68
68
|
assertScriptedSessionPathIds(options);
|
|
69
69
|
const preparedArtifactRoot = await prepareSelectedOutputDirectory(process.cwd(), options.artifactRoot);
|
|
70
70
|
return runScriptedBrowserSessionInPreparedRoot(options, preparedArtifactRoot);
|
|
71
71
|
}
|
|
72
|
-
/** Internal
|
|
72
|
+
/** Internal route seam: the run root is already prepared and must stay bound to that identity. */
|
|
73
73
|
export async function runScriptedBrowserSessionInPreparedRoot(options, preparedArtifactRoot) {
|
|
74
74
|
assertScriptedSessionPathIds(options);
|
|
75
75
|
await prepareContainedOutputDirectory(preparedArtifactRoot, "screenshots");
|
|
@@ -107,7 +107,7 @@ export async function runScriptedBrowserSessionInPreparedRoot(options, preparedA
|
|
|
107
107
|
trace,
|
|
108
108
|
};
|
|
109
109
|
};
|
|
110
|
-
// Launch
|
|
110
|
+
// Launch first: a browser that cannot start is a harness failure, never subject evidence.
|
|
111
111
|
let browser;
|
|
112
112
|
try {
|
|
113
113
|
browser = await launch({ browserCommand, timeoutMs: options.timeoutMs });
|
|
@@ -289,7 +289,7 @@ async function runScriptedJourney(args) {
|
|
|
289
289
|
};
|
|
290
290
|
}
|
|
291
291
|
/** Race one step against the journey's remaining wall-clock budget. A hanging step rejects
|
|
292
|
-
* with the timeout error; the journey's catch path then records
|
|
292
|
+
* with the timeout error; the journey's catch path then records the remaining steps as blocked. */
|
|
293
293
|
async function withJourneyDeadline(promise, deadline, timeoutMs) {
|
|
294
294
|
const remaining = deadline - Date.now();
|
|
295
295
|
if (remaining <= 0) {
|
|
@@ -353,7 +353,7 @@ async function persistScriptedFailureCapture(args) {
|
|
|
353
353
|
};
|
|
354
354
|
}
|
|
355
355
|
/** Project one surface capture into humanish.actor-trace.v1. screenshotRefs are attached only
|
|
356
|
-
* for frames that actually exist on disk (
|
|
356
|
+
* for frames that actually exist on disk (so counts match disk; blocked-not-executed steps name a
|
|
357
357
|
* path that was never written). */
|
|
358
358
|
async function projectScriptedActorTrace(args) {
|
|
359
359
|
const writtenScreenshots = new Set();
|
|
@@ -371,7 +371,7 @@ async function projectScriptedActorTrace(args) {
|
|
|
371
371
|
const items = args.capture.steps.map((step) => {
|
|
372
372
|
const assertions = step.assertions ?? [];
|
|
373
373
|
assertionCount += assertions.length;
|
|
374
|
-
const assertionLines = assertions.map((assertion) => `${assertion.id}: ${assertion.status}
|
|
374
|
+
const assertionLines = assertions.map((assertion) => `${assertion.id}: ${assertion.status} (${assertion.reason})`);
|
|
375
375
|
return {
|
|
376
376
|
id: step.id,
|
|
377
377
|
kind: "ui_action",
|
|
@@ -401,7 +401,7 @@ async function projectScriptedActorTrace(args) {
|
|
|
401
401
|
status: args.status,
|
|
402
402
|
completionReason: args.completionReason,
|
|
403
403
|
reason: redactText(args.reason),
|
|
404
|
-
// No session/model ids exist on a deterministic replay
|
|
404
|
+
// No session/model ids exist on a deterministic replay; absence declared by omission.
|
|
405
405
|
ids: {},
|
|
406
406
|
counts: {
|
|
407
407
|
steps: args.journey.steps.length,
|
|
@@ -412,7 +412,7 @@ async function projectScriptedActorTrace(args) {
|
|
|
412
412
|
screenshots: writtenScreenshots.size,
|
|
413
413
|
},
|
|
414
414
|
items,
|
|
415
|
-
// Affirmative $0 declaration,
|
|
415
|
+
// Affirmative $0 declaration, true by mechanism: no provider client is importable from
|
|
416
416
|
// this code path, so zeros are a recorded fact, not an estimate.
|
|
417
417
|
tokenUsage: { input: 0, output: 0, total: 0, costUsd: 0 },
|
|
418
418
|
capabilities: SCRIPTED_BROWSER_CAPABILITIES,
|