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/run/detail.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// What
|
|
1
|
+
// What one run is doing right now: who is in it, what they are thinking, how far they have got.
|
|
2
2
|
// Unlike the run index, it opens the bundle, which is affordable for the one run someone is
|
|
3
3
|
// looking at.
|
|
4
4
|
//
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
// - `stream.actor` once it has finished.
|
|
8
8
|
// Reading both means the same screen renders a run the whole way through rather than going blank
|
|
9
9
|
// at the moment it completes.
|
|
10
|
-
import {
|
|
10
|
+
import { readAutomaticAnalysis } from "../analysis/automatic.js";
|
|
11
11
|
import path from "node:path";
|
|
12
12
|
import { estimateActorCostForExecution } from "./pricing.js";
|
|
13
13
|
import { resolveRunPath } from "./locate.js";
|
|
@@ -18,7 +18,7 @@ const RUN_DETAIL_SCHEMA = "humanish.run-detail.v1";
|
|
|
18
18
|
/**
|
|
19
19
|
* The latest reasoning a participant has recorded.
|
|
20
20
|
*
|
|
21
|
-
* Takes the
|
|
21
|
+
* Takes the last reasoning item rather than the newest by timestamp: the trace is append-ordered by
|
|
22
22
|
* construction, and half of a live flush may not carry `at` yet. An item still in flight is skipped
|
|
23
23
|
* — a partial thought read mid-write would be quoted as though the participant had finished it.
|
|
24
24
|
*/
|
|
@@ -68,7 +68,7 @@ function participantFrom(stream, index) {
|
|
|
68
68
|
/**
|
|
69
69
|
* What a participant has spent, priced the same way whether the run is finished or in flight.
|
|
70
70
|
*
|
|
71
|
-
* A finished trace carries its own `estimatedCost`. A live one carries the
|
|
71
|
+
* A finished trace carries its own `estimatedCost`. A live one carries the running usage and the
|
|
72
72
|
* model it prices at, so the same estimator gives a figure mid-run instead of the screen reporting
|
|
73
73
|
* the cost as unknown until the moment the run ends — which is the half of a run where knowing what
|
|
74
74
|
* it is costing actually changes what you do.
|
|
@@ -98,7 +98,7 @@ function costOf(trace) {
|
|
|
98
98
|
* Read one run's participants. Returns null when the run has no readable bundle yet — an ordinary
|
|
99
99
|
* state for a run that has just started, not a failure.
|
|
100
100
|
*
|
|
101
|
-
* Reads the bundle
|
|
101
|
+
* Reads the bundle narrowly rather than through `loadRunBundle`, which applies the strict
|
|
102
102
|
* evidence-of-record guard. That guard is right for verification and wrong here: a mid-run flush is
|
|
103
103
|
* a partial document by definition, so validating it as a complete bundle would make the live view
|
|
104
104
|
* — the only view that needs this — the one case that never renders. Nothing read here is treated
|
|
@@ -126,7 +126,7 @@ export async function readRunDetail(cwdInput, runId) {
|
|
|
126
126
|
}
|
|
127
127
|
const streams = Array.isArray(bundle.streams) ? bundle.streams : [];
|
|
128
128
|
const observerAbsolute = path.join(runPaths.absoluteRunRoot, "observer", "index.html");
|
|
129
|
-
const automaticAnalysis = await
|
|
129
|
+
const automaticAnalysis = await readAutomaticAnalysis(cwd, runId);
|
|
130
130
|
return {
|
|
131
131
|
...(automaticAnalysis === undefined ? {} : { automaticAnalysis }),
|
|
132
132
|
schema: RUN_DETAIL_SCHEMA,
|
package/dist/run/dry-run.js
CHANGED
|
@@ -37,7 +37,7 @@ async function runDryRunInScope(options, scope) {
|
|
|
37
37
|
if (participants === null) {
|
|
38
38
|
return refused(requestedCwd, warnings, {
|
|
39
39
|
code: "HUMANISH_INVALID_SIM_COUNT",
|
|
40
|
-
message: "--
|
|
40
|
+
message: "--count must be a positive integer.",
|
|
41
41
|
});
|
|
42
42
|
}
|
|
43
43
|
// Bind the physical project, as the lab routes do: a symlinked cwd retargeted mid-run cannot
|
|
@@ -66,6 +66,8 @@ async function runDryRunInScope(options, scope) {
|
|
|
66
66
|
mode: options.dryRun ? "dry-run" : "live",
|
|
67
67
|
lab: options.lab,
|
|
68
68
|
renderReview: renderReviewMarkdown,
|
|
69
|
+
// The run starts at the time its id and source were stamped with.
|
|
70
|
+
now: () => Date.parse(createdAt),
|
|
69
71
|
...(options.observer === undefined ? {} : { observer: { open: options.observer.open } }),
|
|
70
72
|
});
|
|
71
73
|
if (!started.ok)
|
|
@@ -85,16 +87,7 @@ async function runDryRunInScope(options, scope) {
|
|
|
85
87
|
});
|
|
86
88
|
const judgment = judgePreview();
|
|
87
89
|
const bundle = {
|
|
88
|
-
...bundleHead({
|
|
89
|
-
runId,
|
|
90
|
-
mode: "dry-run",
|
|
91
|
-
participants,
|
|
92
|
-
createdAt,
|
|
93
|
-
cwd,
|
|
94
|
-
artifactRoot,
|
|
95
|
-
...(options.lab === undefined ? {} : { lab: options.lab }),
|
|
96
|
-
source,
|
|
97
|
-
}),
|
|
90
|
+
...bundleHead(run, { participants, cwd, artifactRoot, source }),
|
|
98
91
|
persona: inputs.persona,
|
|
99
92
|
scenario: inputs.scenario,
|
|
100
93
|
lifecycle: [
|
|
@@ -211,7 +204,7 @@ async function renderPreviewObserver(finished, warnings) {
|
|
|
211
204
|
return undefined;
|
|
212
205
|
}
|
|
213
206
|
}
|
|
214
|
-
/** One synthetic stream per
|
|
207
|
+
/** One synthetic stream per stream kind (UI, terminal and the rest); the preview cycles through them. */
|
|
215
208
|
const SYNTHETIC_STREAM_TEMPLATES = [
|
|
216
209
|
{
|
|
217
210
|
kind: "ui",
|
|
@@ -4,7 +4,7 @@ import { type PreparedOutputRoot } from "./contained-output.js";
|
|
|
4
4
|
* percent-decoded up to five times, and each round must still be a plain relative path, so an
|
|
5
5
|
* encoded `..` or separator cannot survive into a later decode.
|
|
6
6
|
*/
|
|
7
|
-
export declare function
|
|
7
|
+
export declare function isEvidencePath(value: string): boolean;
|
|
8
8
|
/**
|
|
9
9
|
* True when `value` (at most `maxLength` characters) stays a plain relative path through up to five
|
|
10
10
|
* rounds of percent-decoding: no round may match `unsafe`, have an empty, `.` or `..` segment, or
|
|
@@ -16,13 +16,13 @@ export declare function decodesToPlainRelativePath(value: string, maxLength: num
|
|
|
16
16
|
* not turn an analysis budget into an unbounded read. No returned bytes have
|
|
17
17
|
* authority to select another file or initiate a network request.
|
|
18
18
|
*/
|
|
19
|
-
export declare function
|
|
19
|
+
export declare function readBoundedFile(root: PreparedOutputRoot, relativePath: string, maxBytes: number): Promise<Buffer | null>;
|
|
20
20
|
/**
|
|
21
21
|
* After a bounded read returned nothing: true when the file is absent, false when something is
|
|
22
22
|
* there that could not be read. Errors other than ENOENT propagate.
|
|
23
23
|
*/
|
|
24
24
|
export declare function pathMissing(filePath: string): Promise<boolean>;
|
|
25
|
-
export type
|
|
25
|
+
export type BoundedFileResult = {
|
|
26
26
|
state: "read";
|
|
27
27
|
bytes: Buffer;
|
|
28
28
|
} | {
|
|
@@ -32,4 +32,4 @@ export type BoundedStudyFileResult = {
|
|
|
32
32
|
state: "unavailable";
|
|
33
33
|
};
|
|
34
34
|
/** Size refusals are distinguished only after the same contained regular-file checks. */
|
|
35
|
-
export declare function
|
|
35
|
+
export declare function readBoundedFileResult(root: PreparedOutputRoot, relativePath: string, maxBytes: number): Promise<BoundedFileResult>;
|
|
@@ -12,7 +12,7 @@ import { isNodeError } from "./type-guards.js";
|
|
|
12
12
|
* percent-decoded up to five times, and each round must still be a plain relative path, so an
|
|
13
13
|
* encoded `..` or separator cannot survive into a later decode.
|
|
14
14
|
*/
|
|
15
|
-
export function
|
|
15
|
+
export function isEvidencePath(value) {
|
|
16
16
|
return decodesToPlainRelativePath(value, 1024, /[\\:\x00-\x1f\x7f]|^\//);
|
|
17
17
|
}
|
|
18
18
|
/**
|
|
@@ -54,8 +54,8 @@ export function decodesToPlainRelativePath(value, maxLength, unsafe) {
|
|
|
54
54
|
* not turn an analysis budget into an unbounded read. No returned bytes have
|
|
55
55
|
* authority to select another file or initiate a network request.
|
|
56
56
|
*/
|
|
57
|
-
export async function
|
|
58
|
-
const result = await
|
|
57
|
+
export async function readBoundedFile(root, relativePath, maxBytes) {
|
|
58
|
+
const result = await readBoundedFileResult(root, relativePath, maxBytes);
|
|
59
59
|
return result.state === "read" ? result.bytes : null;
|
|
60
60
|
}
|
|
61
61
|
/**
|
|
@@ -89,8 +89,8 @@ export async function pathMissing(filePath) {
|
|
|
89
89
|
}
|
|
90
90
|
const unavailable = { state: "unavailable" };
|
|
91
91
|
/** Size refusals are distinguished only after the same contained regular-file checks. */
|
|
92
|
-
export async function
|
|
93
|
-
if (!
|
|
92
|
+
export async function readBoundedFileResult(root, relativePath, maxBytes) {
|
|
93
|
+
if (!isEvidencePath(relativePath) || !Number.isSafeInteger(maxBytes) || maxBytes < 1)
|
|
94
94
|
return unavailable;
|
|
95
95
|
const validateRoot = async () => {
|
|
96
96
|
if ("physicalRunRoot" in root) {
|
|
@@ -31,7 +31,7 @@ export function isRunFeedbackCandidate(value) {
|
|
|
31
31
|
isFeedbackNextState(value.proposed_next_state) &&
|
|
32
32
|
Array.isArray(value.acceptance_proof) &&
|
|
33
33
|
value.acceptance_proof.every((item) => typeof item === "string") &&
|
|
34
|
-
// Optional, adapter-namespaced product-noun block: when present, validate only its
|
|
34
|
+
// Optional, adapter-namespaced product-noun block: when present, validate only its shape
|
|
35
35
|
// (a non-empty namespace + a data record). Core never inspects the keys inside `data`.
|
|
36
36
|
(value.adapter === undefined || isFeedbackAdapterBlock(value.adapter)));
|
|
37
37
|
}
|
package/dist/run/judge.d.ts
CHANGED
|
@@ -60,7 +60,7 @@ export declare function participantHarnessFailed(participant: ParticipantFacts):
|
|
|
60
60
|
* goal_satisfied claim with zero engagement is a session that ran out before anything happened;
|
|
61
61
|
* one whose final message describes a blocker is a participant who could not proceed and said so.
|
|
62
62
|
* Both keep their trace status (the claim is evidence); neither is a participant who reached the
|
|
63
|
-
* goal. One rule for the single
|
|
63
|
+
* goal. One rule for the single participant and the fan-out roll-up (#476).
|
|
64
64
|
*/
|
|
65
65
|
export declare function participantStatus(status: ActorStatus, judgments: {
|
|
66
66
|
noEngagement: boolean;
|
|
@@ -86,7 +86,7 @@ export interface Judgment {
|
|
|
86
86
|
/** The judgment for a verdict: a run passes when its verdict is pass, and a dry run passes. */
|
|
87
87
|
export declare function judgmentOf(verdict: Verdict, dryRun: boolean): Judgment;
|
|
88
88
|
/** What kind of execution failure a run recorded. */
|
|
89
|
-
type ExecutionFailureKind = "harness" | "provider-cleanup" | "sandbox-cleanup" | "evidence" | "cap" | "run";
|
|
89
|
+
type ExecutionFailureKind = "harness" | "provider-cleanup" | "provider-policy" | "sandbox-cleanup" | "evidence" | "cap" | "run";
|
|
90
90
|
/** One way the run failed as an execution. The message is scrubbed; status.json shows it. */
|
|
91
91
|
export interface ExecutionFailure {
|
|
92
92
|
kind: ExecutionFailureKind;
|
|
@@ -98,7 +98,19 @@ export interface ExecutionOutcome {
|
|
|
98
98
|
succeeded: boolean;
|
|
99
99
|
/** The failures the policy counts, in the order the route recorded them. */
|
|
100
100
|
failures: ExecutionFailure[];
|
|
101
|
+
/**
|
|
102
|
+
* The failures the policy lets warn, such as a sandbox whose release is unconfirmed on a route
|
|
103
|
+
* whose evidence stands. They leave `succeeded` and the result's ok alone but stay visible in
|
|
104
|
+
* status.json. Omitted when there are none.
|
|
105
|
+
*/
|
|
106
|
+
warnings?: ExecutionFailure[];
|
|
101
107
|
}
|
|
108
|
+
/**
|
|
109
|
+
* The execution failure for one sandbox whose release is unconfirmed. `warning` is the route's
|
|
110
|
+
* release warning, already scrubbed. `recovery` says how to release it by hand; without one,
|
|
111
|
+
* reclaim kills by the id the run recorded at create time.
|
|
112
|
+
*/
|
|
113
|
+
export declare function sandboxCleanupFailure(owner: string, warning: string | undefined, runId: string, recovery?: string): ExecutionFailure;
|
|
102
114
|
/**
|
|
103
115
|
* How a route turns the facts into its result's ok. A gate route needs every participant to
|
|
104
116
|
* pass. On an evidence route a participant that failed, was blocked or timed out is captured
|
|
@@ -131,7 +143,7 @@ export interface SharedWorldJudgment extends Judgment {
|
|
|
131
143
|
* A run with one participant: its tallied status is the verdict, so a hollow pass fails and a
|
|
132
144
|
* self-reported blocker reads as blocked. Without a session, a harness failure fails the run and
|
|
133
145
|
* a dry run is a contract. A run still in progress is a contract until it finishes. Computer-use
|
|
134
|
-
* calls it for one
|
|
146
|
+
* calls it for one participant with no rerun, and terminal calls it through judgeTerminal.
|
|
135
147
|
*/
|
|
136
148
|
export declare function judgeOneParticipant(args: {
|
|
137
149
|
dryRun: boolean;
|
|
@@ -195,7 +207,7 @@ export declare function judgePreview(): Judgment;
|
|
|
195
207
|
* stays as it was, so scoring can never improve a verdict. No failures returns the review as is.
|
|
196
208
|
*/
|
|
197
209
|
export declare function foldScorerFailures(review: ReviewSummary, failures: readonly string[]): ReviewSummary;
|
|
198
|
-
/** The run's execution outcome under its route's policy. A failure of a kind the policy lets warn is
|
|
210
|
+
/** The run's execution outcome under its route's policy. A failure of a kind the policy lets warn is a warning. */
|
|
199
211
|
export declare function judgeExecution(failures: readonly ExecutionFailure[], policy: OutcomePolicy): ExecutionOutcome;
|
|
200
212
|
/**
|
|
201
213
|
* The result's ok: the run worked as an execution, no scorer failed it, and on a gate route every
|
package/dist/run/judge.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
// participantPassed, participantHarnessFailed);
|
|
7
7
|
// 2. the judgment shapes (Judgment and judgmentOf, SharedWorldJudgment, ExecutionOutcome,
|
|
8
8
|
// OutcomePolicy);
|
|
9
|
-
// 3. one judge per route: computer-use calls judgeOneParticipant (one
|
|
9
|
+
// 3. one judge per route: computer-use calls judgeOneParticipant (one participant, no rerun) or
|
|
10
10
|
// judgeParticipants, shared-world calls judgeSharedWorld, terminal calls judgeTerminal,
|
|
11
11
|
// scripted calls judgeScripted and preview calls judgePreview;
|
|
12
12
|
// 4. foldScorerFailures, which every route with a scorer applies before the run finishes;
|
|
@@ -65,7 +65,7 @@ export function participantHarnessFailed(participant) {
|
|
|
65
65
|
* goal_satisfied claim with zero engagement is a session that ran out before anything happened;
|
|
66
66
|
* one whose final message describes a blocker is a participant who could not proceed and said so.
|
|
67
67
|
* Both keep their trace status (the claim is evidence); neither is a participant who reached the
|
|
68
|
-
* goal. One rule for the single
|
|
68
|
+
* goal. One rule for the single participant and the fan-out roll-up (#476).
|
|
69
69
|
*/
|
|
70
70
|
export function participantStatus(status, judgments) {
|
|
71
71
|
if (status !== "passed" || judgments === undefined)
|
|
@@ -98,6 +98,17 @@ export function verdictForStatus(status) {
|
|
|
98
98
|
export function judgmentOf(verdict, dryRun) {
|
|
99
99
|
return { verdict, passed: dryRun || verdict === "pass" };
|
|
100
100
|
}
|
|
101
|
+
/**
|
|
102
|
+
* The execution failure for one sandbox whose release is unconfirmed. `warning` is the route's
|
|
103
|
+
* release warning, already scrubbed. `recovery` says how to release it by hand; without one,
|
|
104
|
+
* reclaim kills by the id the run recorded at create time.
|
|
105
|
+
*/
|
|
106
|
+
export function sandboxCleanupFailure(owner, warning, runId, recovery) {
|
|
107
|
+
return {
|
|
108
|
+
kind: "sandbox-cleanup",
|
|
109
|
+
message: `${owner}: ${warning ?? "Sandbox release is unconfirmed."} ${recovery ?? `Reclaim it by recorded id with \`humanish reclaim --run ${runId}\`.`}`,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
101
112
|
/** Each route's outcome policy, in one place. */
|
|
102
113
|
export const OUTCOME_POLICIES = {
|
|
103
114
|
"computer-use": { participants: "gate", sandboxCleanup: "warns", evidence: "fails" },
|
|
@@ -111,7 +122,7 @@ export const OUTCOME_POLICIES = {
|
|
|
111
122
|
* A run with one participant: its tallied status is the verdict, so a hollow pass fails and a
|
|
112
123
|
* self-reported blocker reads as blocked. Without a session, a harness failure fails the run and
|
|
113
124
|
* a dry run is a contract. A run still in progress is a contract until it finishes. Computer-use
|
|
114
|
-
* calls it for one
|
|
125
|
+
* calls it for one participant with no rerun, and terminal calls it through judgeTerminal.
|
|
115
126
|
*/
|
|
116
127
|
export function judgeOneParticipant(args) {
|
|
117
128
|
const status = args.participant === undefined ? undefined : judgedStatus(args.participant);
|
|
@@ -220,14 +231,20 @@ export function foldScorerFailures(review, failures) {
|
|
|
220
231
|
}
|
|
221
232
|
return folded;
|
|
222
233
|
}
|
|
223
|
-
/** The run's execution outcome under its route's policy. A failure of a kind the policy lets warn is
|
|
234
|
+
/** The run's execution outcome under its route's policy. A failure of a kind the policy lets warn is a warning. */
|
|
224
235
|
export function judgeExecution(failures, policy) {
|
|
225
|
-
const
|
|
236
|
+
const counts = (failure) => failure.kind === "sandbox-cleanup"
|
|
226
237
|
? policy.sandboxCleanup === "fails"
|
|
227
238
|
: failure.kind === "evidence"
|
|
228
239
|
? policy.evidence === "fails"
|
|
229
|
-
: true
|
|
230
|
-
|
|
240
|
+
: true;
|
|
241
|
+
const counted = failures.filter(counts);
|
|
242
|
+
const warnings = failures.filter((failure) => !counts(failure));
|
|
243
|
+
return {
|
|
244
|
+
succeeded: counted.length === 0,
|
|
245
|
+
failures: counted,
|
|
246
|
+
...(warnings.length === 0 ? {} : { warnings }),
|
|
247
|
+
};
|
|
231
248
|
}
|
|
232
249
|
/**
|
|
233
250
|
* The result's ok: the run worked as an execution, no scorer failed it, and on a gate route every
|
package/dist/run/locate.d.ts
CHANGED
|
@@ -2,6 +2,8 @@ import { type PreparedRunArtifactPaths } from "./paths.js";
|
|
|
2
2
|
import { type PreparedSelectedOutputDirectory } from "./contained-output.js";
|
|
3
3
|
import type { RunPointer } from "./results.js";
|
|
4
4
|
import { type RunBundle } from "./bundle.js";
|
|
5
|
+
/** The run input that resolves through latest.json rather than naming a run directory. */
|
|
6
|
+
export declare const LATEST_RUN_ALIAS = "latest";
|
|
5
7
|
/** Resolve "latest" or an explicit run id to its prepared artifact paths. */
|
|
6
8
|
export declare function resolveRunPath(cwd: string, runInput: string): Promise<PreparedRunArtifactPaths | null>;
|
|
7
9
|
export declare function readLatest(runsRoot: PreparedSelectedOutputDirectory): Promise<RunPointer | null>;
|
package/dist/run/locate.js
CHANGED
|
@@ -5,9 +5,11 @@ import { assertPreparedSelectedOutputDirectory, bindExistingManagedHumanishOutpu
|
|
|
5
5
|
import { RUN_BUNDLE_FILE } from "./bundle.js";
|
|
6
6
|
import { isRunBundle, isRunPointer } from "./bundle-shape.js";
|
|
7
7
|
import { isNodeError } from "./type-guards.js";
|
|
8
|
+
/** The run input that resolves through latest.json rather than naming a run directory. */
|
|
9
|
+
export const LATEST_RUN_ALIAS = "latest";
|
|
8
10
|
/** Resolve "latest" or an explicit run id to its prepared artifact paths. */
|
|
9
11
|
export async function resolveRunPath(cwd, runInput) {
|
|
10
|
-
if (runInput ===
|
|
12
|
+
if (runInput === LATEST_RUN_ALIAS) {
|
|
11
13
|
const runsRoot = await bindExistingManagedHumanishOutputDirectory(cwd, "runs");
|
|
12
14
|
if (!runsRoot) {
|
|
13
15
|
return null;
|
package/dist/run/outcomes.d.ts
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import { type ActorStatus } from "../actors/contract.js";
|
|
2
2
|
import { type CuaGoalSource } from "../actors/goal-source.js";
|
|
3
3
|
import type { TaskFunnel } from "../lab/tasks.js";
|
|
4
|
-
import type { ParticipantOutcomes, ReviewSummary,
|
|
4
|
+
import type { ParticipantOutcomes, ReviewSummary, RunTaskFunnel } from "./bundle.js";
|
|
5
5
|
/** Tally participant outcomes from actor statuses. Statuses this does not recognise are counted in
|
|
6
6
|
* `total` but nowhere else, so the parts can never exceed the whole. */
|
|
7
7
|
export declare function tallyParticipantOutcomes(statuses: readonly ActorStatus[],
|
|
8
8
|
/** Per-participant: did this one report friction or a defect? Same order as `statuses`. */
|
|
9
9
|
reportedFriction?: readonly boolean[]): ParticipantOutcomes;
|
|
10
10
|
/** Roll per-participant funnels up into the study funnel. Undefined when nothing measured one. */
|
|
11
|
-
export declare function aggregateTaskFunnels(funnels: readonly TaskFunnel[]):
|
|
11
|
+
export declare function aggregateTaskFunnels(funnels: readonly TaskFunnel[]): RunTaskFunnel | undefined;
|
|
12
12
|
/** The funnel as one line, denominator on every number: `signup 2/2 · verify-email 1/2`. */
|
|
13
|
-
export declare function
|
|
13
|
+
export declare function formatRunTaskFunnel(funnel: RunTaskFunnel): string;
|
|
14
14
|
type ParticipantOutcomeDetail = {
|
|
15
15
|
status: ActorStatus;
|
|
16
16
|
label?: string;
|
package/dist/run/outcomes.js
CHANGED
|
@@ -68,7 +68,7 @@ export function aggregateTaskFunnels(funnels) {
|
|
|
68
68
|
};
|
|
69
69
|
}
|
|
70
70
|
/** The funnel as one line, denominator on every number: `signup 2/2 · verify-email 1/2`. */
|
|
71
|
-
export function
|
|
71
|
+
export function formatRunTaskFunnel(funnel) {
|
|
72
72
|
if (funnel.tasks.length === 0)
|
|
73
73
|
return "no tasks declared";
|
|
74
74
|
return funnel.tasks
|
|
@@ -138,7 +138,7 @@ export function formatParticipantOutcomes(outcomes, terminalCauses = []) {
|
|
|
138
138
|
};
|
|
139
139
|
append(outcomes.abandoned, ["abandoned"], "gave up");
|
|
140
140
|
append(outcomes.ranOut, ["incomplete", "timed_out"], "interrupted (stop details unavailable)");
|
|
141
|
-
// "blocked" covers an approval the run could not give
|
|
141
|
+
// "blocked" covers an approval the run could not give and a blocker the participant reported in
|
|
142
142
|
// its own words, so the label names no cause.
|
|
143
143
|
if (outcomes.blocked > 0)
|
|
144
144
|
parts.push(`${outcomes.blocked} blocked`);
|
|
@@ -191,7 +191,7 @@ export function withCuaReviewProvenance(review, streams) {
|
|
|
191
191
|
const outcomes = formatParticipantOutcomes(review.participants, details);
|
|
192
192
|
// Preserve rerun context, participant narration and adapter-specific findings. Refreshing a
|
|
193
193
|
// historical summary qualifies its old tally instead of silently discarding that context.
|
|
194
|
-
const header = `Run gate: ${review.verdict}. Participants: ${outcomes}.${review.tasks ? ` Tasks: ${
|
|
194
|
+
const header = `Run gate: ${review.verdict}. Participants: ${outcomes}.${review.tasks ? ` Tasks: ${formatRunTaskFunnel(review.tasks)}.` : ""}`;
|
|
195
195
|
const prefix = `${header} Recorded summary: `;
|
|
196
196
|
const recorded = review.summary.startsWith(prefix)
|
|
197
197
|
? review.summary.slice(prefix.length)
|
|
@@ -12,7 +12,7 @@ export declare function participantIds(position: number): ParticipantIds;
|
|
|
12
12
|
/** A participant's record, at its 1-based place in the bundle, with its one stream. */
|
|
13
13
|
export declare function participantRecord(ids: ParticipantIds, place: number, fields: Omit<RunSimulation, "id" | "index" | "streamIds">): RunSimulation;
|
|
14
14
|
/**
|
|
15
|
-
* A participant's stream. `participantId` is the route's own participant id (a fan-out
|
|
15
|
+
* A participant's stream. `participantId` is the route's own participant id (a fan-out entry's `lane-NN` id),
|
|
16
16
|
* saved right after the record id when the route has one.
|
|
17
17
|
*/
|
|
18
18
|
export declare function participantStream(ids: ParticipantIds, fields: Omit<RunStream, "id" | "simId" | "laneId">, participantId?: string): RunStream;
|
|
@@ -24,5 +24,5 @@ export declare function participantResourceIds(ids: ParticipantIds, participantI
|
|
|
24
24
|
export declare function recordIdOf(stream: RunStream): string;
|
|
25
25
|
/** The record id a saved event names, when it names one. */
|
|
26
26
|
export declare function eventRecordIdOf(event: RunEvent): string | undefined;
|
|
27
|
-
/** The participant id an adapter recorded on a saved stream (a fan-out lane id), when it has one. */
|
|
27
|
+
/** The participant id an adapter recorded on a saved stream (a fan-out `lane-NN` id), when it has one. */
|
|
28
28
|
export declare function streamParticipantIdOf(stream: RunStream): string | undefined;
|
|
@@ -30,7 +30,7 @@ export function participantRecord(ids, place, fields) {
|
|
|
30
30
|
};
|
|
31
31
|
}
|
|
32
32
|
/**
|
|
33
|
-
* A participant's stream. `participantId` is the route's own participant id (a fan-out
|
|
33
|
+
* A participant's stream. `participantId` is the route's own participant id (a fan-out entry's `lane-NN` id),
|
|
34
34
|
* saved right after the record id when the route has one.
|
|
35
35
|
*/
|
|
36
36
|
export function participantStream(ids, fields, participantId) {
|
|
@@ -57,7 +57,7 @@ export function recordIdOf(stream) {
|
|
|
57
57
|
export function eventRecordIdOf(event) {
|
|
58
58
|
return event.simId;
|
|
59
59
|
}
|
|
60
|
-
/** The participant id an adapter recorded on a saved stream (a fan-out lane id), when it has one. */
|
|
60
|
+
/** The participant id an adapter recorded on a saved stream (a fan-out `lane-NN` id), when it has one. */
|
|
61
61
|
export function streamParticipantIdOf(stream) {
|
|
62
62
|
return stream.laneId;
|
|
63
63
|
}
|
package/dist/run/paths.js
CHANGED
|
@@ -262,7 +262,7 @@ async function assertNoSymlinkDescendants(directory) {
|
|
|
262
262
|
const entries = await readdir(directory, { withFileTypes: true });
|
|
263
263
|
for (const entry of entries) {
|
|
264
264
|
const child = path.join(directory, entry.name);
|
|
265
|
-
// A run directory can be written
|
|
265
|
+
// A run directory can be written concurrently with this walk: the atomic writer creates a
|
|
266
266
|
// `.humanish-write-*.tmp` sibling and renames it, and a run now also refreshes its own status
|
|
267
267
|
// record on a cadence. An entry that vanished between readdir and lstat therefore proves
|
|
268
268
|
// nothing except that it is gone, and a path that no longer exists cannot be a symlink escape:
|
package/dist/run/pricing.d.ts
CHANGED
|
@@ -10,12 +10,12 @@ export interface ModelRate {
|
|
|
10
10
|
* a reduced rate. Optional: absent means we do not model a discount and every input token is
|
|
11
11
|
* billed at `inputUsdPerToken`. */
|
|
12
12
|
cachedInputUsdPerToken?: number;
|
|
13
|
-
/** USD per input token newly
|
|
13
|
+
/** USD per input token newly written to the provider's prompt cache, when the provider bills
|
|
14
14
|
* writes (OpenAI: GPT-5.6+ bills `cache_write_tokens` at 1.25x the uncached input rate, as the
|
|
15
|
-
*
|
|
15
|
+
* total rate for those tokens, with no extra charge on top). Absent = writes are free (every
|
|
16
16
|
* pre-5.6 model) and any reported write tokens price at the plain input rate. */
|
|
17
17
|
cacheWriteUsdPerToken?: number;
|
|
18
|
-
/** Long-context tier, when the provider re-prices the
|
|
18
|
+
/** Long-context tier, when the provider re-prices the whole request past an input-size
|
|
19
19
|
* threshold (OpenAI GPT-5.6: >272K input tokens => 2x input-side, 1.5x output, full request).
|
|
20
20
|
* Priced exactly only when the usage carries per-request `turns` records; totals alone cannot
|
|
21
21
|
* say which requests crossed, so without turns the estimate stays on the short-context rate,
|
|
@@ -29,7 +29,7 @@ export interface ModelRate {
|
|
|
29
29
|
asOf: string;
|
|
30
30
|
/** Public pricing page the number came from (a comment/URL, never a secret). */
|
|
31
31
|
source: string;
|
|
32
|
-
/** true = a stand-in
|
|
32
|
+
/** true = a stand-in that was not copied from a live sheet; the estimate carries this flag so a
|
|
33
33
|
* placeholder rate is never mistaken for a confirmed one. */
|
|
34
34
|
placeholder?: boolean;
|
|
35
35
|
}
|
|
@@ -52,8 +52,8 @@ export interface DesktopResourceRate {
|
|
|
52
52
|
source: string;
|
|
53
53
|
}
|
|
54
54
|
/**
|
|
55
|
-
* The token-derived cost
|
|
56
|
-
* (unknown rate or no token usage)
|
|
55
|
+
* The token-derived cost estimate for one actor trace. `estimatedCostUsd: null` = declared absent
|
|
56
|
+
* (unknown rate or no token usage) and is never coerced to 0. A non-null figure always carries its
|
|
57
57
|
* pricing provenance (`ratesAsOf` + `source`) so the mechanism (a rate-table multiply) matches
|
|
58
58
|
* the claim (an estimate, not a charge). Defined here so the rate table and the field that
|
|
59
59
|
* consumes it live together; `ActorTrace` imports it type-only.
|
|
@@ -71,13 +71,17 @@ export interface ActorEstimatedCost {
|
|
|
71
71
|
modelId?: string;
|
|
72
72
|
/** true when the rate is a stand-in, not a live sheet. */
|
|
73
73
|
placeholder?: boolean;
|
|
74
|
+
/** Set when usage arrived as runtime-turn totals that each sum several requests. No request's
|
|
75
|
+
* own size is known, so no per-request long-context tier was applied: tokens are priced at the
|
|
76
|
+
* base tier, cached input at the cached rate. */
|
|
77
|
+
basis?: "aggregated_turns_base_rate";
|
|
74
78
|
breakdown?: {
|
|
75
79
|
inputUsd: number;
|
|
76
80
|
outputUsd: number;
|
|
77
81
|
inputTokens: number;
|
|
78
82
|
outputTokens: number;
|
|
79
83
|
/** Of `inputTokens`, how many were billed at the reduced cached rate. Present only when the
|
|
80
|
-
* provider reported cache hits
|
|
84
|
+
* provider reported cache hits and the rate sheet models a cached rate. */
|
|
81
85
|
cachedInputTokens?: number;
|
|
82
86
|
/** Of `inputTokens`, how many were billed at the cache-WRITE rate (OpenAI 5.6+). */
|
|
83
87
|
cacheWriteInputTokens?: number;
|
|
@@ -86,7 +90,7 @@ export interface ActorEstimatedCost {
|
|
|
86
90
|
longContextTurns?: number;
|
|
87
91
|
};
|
|
88
92
|
}
|
|
89
|
-
/** The desktop-minute cost
|
|
93
|
+
/** The desktop-minute cost estimate (host-side create->teardown span * a per-minute rate). Same
|
|
90
94
|
* null-discipline as ActorEstimatedCost: `estimatedCostUsd: null` = not measured (no duration). */
|
|
91
95
|
export interface DesktopCostEstimate {
|
|
92
96
|
estimatedCostUsd: number | null;
|
|
@@ -108,13 +112,19 @@ export declare function estimateAllocatedDesktopCost(minutes: number | undefined
|
|
|
108
112
|
* precision. */
|
|
109
113
|
export declare function round6(n: number): number;
|
|
110
114
|
/**
|
|
111
|
-
* Estimate one actor
|
|
115
|
+
* Estimate one actor trace's model-token cost from its trace tokenUsage + model id. Deterministic;
|
|
112
116
|
* the rate table is injectable (tests pass a fake sheet). Returns a DECLARED-ABSENT estimate
|
|
113
117
|
* (estimatedCostUsd: null + a reason) for a missing rate or missing usage — never a guessed cost.
|
|
114
118
|
*/
|
|
115
119
|
export declare function estimateActorCostForExecution(usage: ActorTokenUsage | undefined, modelId: string | undefined, profile?: {
|
|
116
120
|
billing?: unknown;
|
|
117
121
|
}): ActorEstimatedCost;
|
|
122
|
+
/**
|
|
123
|
+
* Price usage reported as runtime-turn totals, such as Codex `turn.completed`, which sums every
|
|
124
|
+
* request in the turn. Pricing a turn as one request would apply the long-context tier to the
|
|
125
|
+
* whole turn, so the per-turn records are dropped and the totals price on the base tier.
|
|
126
|
+
*/
|
|
127
|
+
export declare function estimateAggregatedTurnCost(tokenUsage: ActorTokenUsage | undefined, modelId: string | undefined): ActorEstimatedCost;
|
|
118
128
|
export declare function estimateActorCost(tokenUsage: ActorTokenUsage | undefined, modelId: string | undefined, rates?: Record<string, ModelRate>): ActorEstimatedCost;
|
|
119
129
|
/**
|
|
120
130
|
* Estimate the E2B desktop-minute cost from a host-side create->teardown span (minutes). The rate
|
package/dist/run/pricing.js
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
//
|
|
2
|
-
// notice. When they do, update
|
|
3
|
-
// Every dollar figure humanish derives from this table is surfaced/persisted as an
|
|
4
|
-
// labeled "estimated (rates as of <asOf>)", and is
|
|
1
|
+
// Operator-editable estimates, which are not authoritative prices. Providers change pricing without
|
|
2
|
+
// notice. When they do, update both the number and the `asOf` date on the affected entry.
|
|
3
|
+
// Every dollar figure humanish derives from this table is surfaced/persisted as an estimate,
|
|
4
|
+
// labeled "estimated (rates as of <asOf>)", and is never presented as an exact charge.
|
|
5
5
|
//
|
|
6
|
-
// This module is
|
|
7
|
-
// an
|
|
8
|
-
// on the live numbers below. An
|
|
9
|
-
// (estimatedCostUsd: null + a reason)
|
|
6
|
+
// This module is pure (node builtins only, no deps) and deterministic: the estimator functions take
|
|
7
|
+
// an optional injected rate table/rate so tests drive assertions with a fake sheet and never depend
|
|
8
|
+
// on the live numbers below. An unknown model/desktop rate yields a declared-absent estimate
|
|
9
|
+
// (estimatedCostUsd: null + a reason) and never a guessed or silent-zero cost (invariant 5). A bare
|
|
10
10
|
// `costUsd` elsewhere in the contract means a provider actually billed that amount; the
|
|
11
11
|
// token-derived estimate here always lives under `estimatedCostUsd` so a reader can never confuse
|
|
12
12
|
// an estimate for an authoritative charge (invariant 6).
|
|
13
13
|
export const PRICING_SCHEMA = "humanish.pricing.v1";
|
|
14
14
|
export const ACTOR_ESTIMATED_COST_SCHEMA = "humanish.actor-estimated-cost.v1";
|
|
15
|
-
// The gpt-5.6 long-context tier: >272K input tokens re-prices the
|
|
15
|
+
// The gpt-5.6 long-context tier: >272K input tokens re-prices the full request at 2x
|
|
16
16
|
// input-side / 1.5x output (developers.openai.com/api/docs/models/gpt-5.6-sol, 2026-08-18).
|
|
17
17
|
const LONG_CONTEXT_TIER_272K = {
|
|
18
18
|
thresholdInputTokens: 272_000,
|
|
@@ -41,7 +41,7 @@ function rateWithLongContextTier(inPer1M, cachedPer1M, writePer1M, outPer1M, asO
|
|
|
41
41
|
const GPT56_SOL_PROMO_AS_OF = "2026-09-03";
|
|
42
42
|
const GPT6_ASTRA_AS_OF = "2026-09-03";
|
|
43
43
|
// Per-model rates, keyed on the model id that lands in trace.ids.model (lookup is
|
|
44
|
-
// case-insensitive on a trimmed id). An id
|
|
44
|
+
// case-insensitive on a trimmed id). An id missing here is declared absent, never guessed.
|
|
45
45
|
export const MODEL_RATES = {
|
|
46
46
|
// OpenAI computer-use-preview (the classic CUA model). ~$3 / 1M input, ~$12 / 1M output.
|
|
47
47
|
// source: openai.com/api/pricing (verify — providers change without notice).
|
|
@@ -74,7 +74,7 @@ export const MODEL_RATES = {
|
|
|
74
74
|
"gpt-5.6-cyber": rateWithLongContextTier(12.5, 1.25, 15.625, 75),
|
|
75
75
|
// Daybreak program aliases (blue -> sol, red -> cyber today). OpenAI repoints these as new
|
|
76
76
|
// frontier models ship, so prefer the explicit tier id in labs; the entries exist so a
|
|
77
|
-
// configured alias still prices at what the alias bills
|
|
77
|
+
// configured alias still prices at what the alias bills today.
|
|
78
78
|
"daybreak-blue-latest": rateWithLongContextTier(4, 0.4, 5, 20, GPT56_SOL_PROMO_AS_OF),
|
|
79
79
|
"daybreak-red-latest": rateWithLongContextTier(12.5, 1.25, 15.625, 75),
|
|
80
80
|
// gpt-6-astra (shipped 2026-09-03; API access announced as rolling out). Same two mechanics
|
|
@@ -157,7 +157,7 @@ export function round6(n) {
|
|
|
157
157
|
return Math.round(n * 1e6) / 1e6;
|
|
158
158
|
}
|
|
159
159
|
/**
|
|
160
|
-
* Estimate one actor
|
|
160
|
+
* Estimate one actor trace's model-token cost from its trace tokenUsage + model id. Deterministic;
|
|
161
161
|
* the rate table is injectable (tests pass a fake sheet). Returns a DECLARED-ABSENT estimate
|
|
162
162
|
* (estimatedCostUsd: null + a reason) for a missing rate or missing usage — never a guessed cost.
|
|
163
163
|
*/
|
|
@@ -172,6 +172,18 @@ export function estimateActorCostForExecution(usage, modelId, profile) {
|
|
|
172
172
|
}
|
|
173
173
|
: estimateActorCost(usage, modelId);
|
|
174
174
|
}
|
|
175
|
+
/**
|
|
176
|
+
* Price usage reported as runtime-turn totals, such as Codex `turn.completed`, which sums every
|
|
177
|
+
* request in the turn. Pricing a turn as one request would apply the long-context tier to the
|
|
178
|
+
* whole turn, so the per-turn records are dropped and the totals price on the base tier.
|
|
179
|
+
*/
|
|
180
|
+
export function estimateAggregatedTurnCost(tokenUsage, modelId) {
|
|
181
|
+
const { turns: _turns, ...totals } = tokenUsage ?? {};
|
|
182
|
+
const estimate = estimateActorCost(tokenUsage === undefined ? undefined : totals, modelId);
|
|
183
|
+
return estimate.estimatedCostUsd === null
|
|
184
|
+
? estimate
|
|
185
|
+
: { ...estimate, basis: "aggregated_turns_base_rate" };
|
|
186
|
+
}
|
|
175
187
|
export function estimateActorCost(tokenUsage, modelId, rates = MODEL_RATES) {
|
|
176
188
|
if (!tokenUsage || (tokenUsage.input === undefined && tokenUsage.output === undefined)) {
|
|
177
189
|
return {
|
|
@@ -193,15 +205,15 @@ export function estimateActorCost(tokenUsage, modelId, rates = MODEL_RATES) {
|
|
|
193
205
|
}
|
|
194
206
|
const inTok = tokenUsage.input ?? 0;
|
|
195
207
|
const outTok = tokenUsage.output ?? 0;
|
|
196
|
-
// Long-context tiering needs to know each
|
|
197
|
-
// requests past the threshold), so it engages only when per-turn usage records exist
|
|
208
|
+
// Long-context tiering needs to know each request's input size (the provider re-prices whole
|
|
209
|
+
// requests past the threshold), so it engages only when per-turn usage records exist and their
|
|
198
210
|
// input sums to the reported total — a partial turn ledger must not silently price the missing
|
|
199
211
|
// remainder at the wrong tier. Otherwise totals price on the base (short-context) rate, which is
|
|
200
212
|
// the under-estimate direction and never trips a cap early.
|
|
201
213
|
const turns = tokenUsage.turns ?? [];
|
|
202
214
|
const sumOf = (field) => turns.reduce((sum, turn) => sum + (turn[field] ?? 0), 0);
|
|
203
|
-
// The ledger is trusted only when it decomposes the totals
|
|
204
|
-
//
|
|
215
|
+
// The ledger is trusted only when it decomposes the totals exactly, in all four sums including the
|
|
216
|
+
// cache splits. A ledger that carries request sizes but not the cache splits would otherwise
|
|
205
217
|
// price every token at the full rate while the session totals sit ignored, overstating spend
|
|
206
218
|
// 3.5-5x and tripping caps early. Inconsistent evidence falls back to the totals path, which
|
|
207
219
|
// honors the declared splits on the base tier.
|
|
@@ -217,8 +229,8 @@ export function estimateActorCost(tokenUsage, modelId, rates = MODEL_RATES) {
|
|
|
217
229
|
let writeTotal = 0;
|
|
218
230
|
let longContextTurns = 0;
|
|
219
231
|
// Price one request's usage at one tier. Cached input is billed at a fraction of the full rate,
|
|
220
|
-
// and on a session that threads provider state it is the
|
|
221
|
-
// full rate overstates real spend by up to ~10x. Cache
|
|
232
|
+
// and on a session that threads provider state it is the majority of input, and pricing it at the
|
|
233
|
+
// full rate overstates real spend by up to ~10x. Cache writes bill at their own rate (1.25x on
|
|
222
234
|
// OpenAI 5.6+) as the total rate for those tokens; a sheet without a write rate prices writes as
|
|
223
235
|
// plain input (pre-5.6: writes are free-of-extra-fee, i.e. plain input). Every piece is honestly
|
|
224
236
|
// absent: no reported split means no discount and no surcharge assumed.
|