humanish 0.107.0 → 0.108.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 +22 -17
- package/CHANGELOG.md +14 -0
- package/CONTEXT.md +51 -44
- package/README.md +145 -172
- 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-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 +8 -6
- 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 +2 -2
- package/dist/actors/codex/restricted-session.js +10 -5
- package/dist/actors/computer-use/actor.d.ts +16 -16
- package/dist/actors/computer-use/actor.js +2 -2
- package/dist/actors/computer-use/admission-limit.d.ts +1 -1
- package/dist/actors/computer-use/admission-limit.js +1 -1
- package/dist/actors/computer-use/loop/actions.d.ts +3 -3
- package/dist/actors/computer-use/loop/actions.js +10 -10
- 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/ending.d.ts +5 -5
- package/dist/actors/computer-use/loop/ending.js +7 -7
- package/dist/actors/computer-use/loop/observation.d.ts +2 -2
- package/dist/actors/computer-use/loop/observation.js +9 -9
- package/dist/actors/computer-use/loop/provider-call.d.ts +1 -1
- package/dist/actors/computer-use/loop/provider-call.js +1 -1
- package/dist/actors/computer-use/loop/session.js +3 -3
- 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 +9 -8
- package/dist/actors/computer-use/loop/types.d.ts +25 -23
- package/dist/actors/computer-use/loop/usage.js +2 -2
- 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 +11 -8
- package/dist/actors/computer-use/openai-provider.js +45 -34
- 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/contract.d.ts +78 -43
- package/dist/actors/contract.js +29 -23
- package/dist/actors/local-agent/claude-session.d.ts +1 -1
- package/dist/actors/local-agent/claude-session.js +10 -9
- package/dist/actors/local-agent/cli.d.ts +8 -6
- 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 +6 -6
- package/dist/actors/registry.d.ts +10 -10
- package/dist/actors/registry.js +18 -17
- package/dist/actors/scripted-browser/actor.d.ts +8 -8
- package/dist/actors/scripted-browser/actor.js +16 -16
- 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/codex-config.d.ts +6 -2
- package/dist/analysis/codex-config.js +22 -14
- package/dist/analysis/service.js +5 -5
- package/dist/cli/commands/analyze.js +19 -16
- package/dist/cli/commands/codex.js +9 -9
- package/dist/cli/commands/comms.js +54 -33
- package/dist/cli/commands/feedback.js +20 -21
- package/dist/cli/commands/lab-format.d.ts +5 -4
- package/dist/cli/commands/lab-format.js +35 -23
- package/dist/cli/commands/lab-route-computer-use.js +6 -7
- package/dist/cli/commands/lab-route-preview.js +4 -3
- package/dist/cli/commands/lab-route-shared-world.js +3 -3
- package/dist/cli/commands/lab-run.js +10 -11
- package/dist/cli/commands/lab-scorer.d.ts +2 -2
- package/dist/cli/commands/lab-scorer.js +1 -1
- package/dist/cli/commands/migrate.d.ts +4 -0
- package/dist/cli/commands/migrate.js +65 -0
- package/dist/cli/commands/observe.js +147 -108
- 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 +137 -138
- package/dist/cli/commands/setup.d.ts +2 -2
- package/dist/cli/commands/setup.js +26 -21
- package/dist/cli/commands/study.d.ts +3 -0
- package/dist/cli/commands/study.js +182 -0
- package/dist/cli/commands/tui.d.ts +4 -4
- package/dist/cli/commands/tui.js +21 -21
- package/dist/cli/commands/watch.js +60 -75
- package/dist/cli/deprecations.d.ts +18 -0
- package/dist/cli/deprecations.js +48 -0
- package/dist/cli/doctor.d.ts +15 -5
- package/dist/cli/doctor.js +103 -48
- package/dist/cli/first-run-path.d.ts +12 -10
- package/dist/cli/first-run-path.js +30 -28
- package/dist/cli/io.d.ts +41 -6
- package/dist/cli/io.js +97 -22
- package/dist/cli/observer-follow.d.ts +2 -2
- package/dist/cli/observer-follow.js +5 -6
- package/dist/cli/orientation.d.ts +6 -3
- package/dist/cli/orientation.js +43 -39
- 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 +109 -40
- package/dist/cli/telemetry.d.ts +15 -15
- package/dist/cli/telemetry.js +48 -40
- 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 +14 -14
- package/dist/comms/email-catch.d.ts +3 -3
- package/dist/comms/email-catch.js +8 -8
- package/dist/comms/external-evidence.js +2 -2
- package/dist/comms/extract.js +2 -2
- package/dist/comms/fake-inbox.d.ts +2 -2
- package/dist/comms/fake-inbox.js +2 -2
- package/dist/comms/receiving-render.d.ts +1 -1
- package/dist/comms/receiving-render.js +2 -2
- 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 +36 -37
- package/dist/comms/sandbox-catch.js +34 -35
- package/dist/comms/setup.js +42 -8
- 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 +36 -78
- package/dist/feedback/export-bundle.js +1 -1
- package/dist/feedback/export.d.ts +5 -1
- package/dist/feedback/export.js +7 -8
- package/dist/feedback/feedback.d.ts +2 -2
- package/dist/feedback/feedback.js +21 -3
- package/dist/guest/chromium-text.js +2 -2
- package/dist/guest/desktop-native.d.ts +1 -1
- package/dist/guest/runtime.js +1 -1
- package/dist/index.d.ts +12 -10
- package/dist/index.js +8 -6
- package/dist/keys/key-resolution.d.ts +5 -5
- package/dist/keys/key-resolution.js +23 -23
- package/dist/lab/adapter-extension.d.ts +7 -7
- package/dist/lab/adapter-extension.js +13 -36
- package/dist/lab/adapter-scorer-loader.d.ts +7 -7
- package/dist/lab/adapter-scorer-loader.js +32 -32
- package/dist/lab/composition-rules.js +42 -42
- package/dist/lab/config.js +65 -25
- package/dist/lab/deprecated-fields.d.ts +10 -0
- package/dist/lab/deprecated-fields.js +24 -0
- package/dist/lab/device-presets.d.ts +8 -8
- package/dist/lab/device-presets.js +11 -11
- package/dist/lab/discover.d.ts +13 -9
- package/dist/lab/discover.js +117 -57
- package/dist/lab/doctor.d.ts +10 -3
- package/dist/lab/doctor.js +47 -9
- package/dist/lab/init-templates.js +147 -147
- package/dist/lab/init.d.ts +1 -1
- package/dist/lab/init.js +41 -9
- package/dist/lab/keys.d.ts +2 -0
- package/dist/lab/keys.js +42 -8
- package/dist/lab/lab-deps.d.ts +7 -12
- package/dist/lab/parse/actors.js +9 -9
- package/dist/lab/parse/comms.js +5 -5
- package/dist/lab/parse/execution.js +13 -13
- package/dist/lab/parse/study-v3.d.ts +23 -0
- package/dist/lab/parse/study-v3.js +259 -0
- package/dist/lab/parse/subject-state.d.ts +7 -7
- package/dist/lab/parse/subject-state.js +16 -16
- package/dist/lab/parse/subject.js +28 -28
- package/dist/lab/parse/values.d.ts +1 -1
- package/dist/lab/parse/values.js +3 -3
- package/dist/lab/persona-resolve.d.ts +4 -4
- package/dist/lab/persona-resolve.js +4 -4
- package/dist/lab/plan-participants.d.ts +2 -2
- package/dist/lab/plan-types.d.ts +4 -4
- package/dist/lab/plan.d.ts +1 -7
- package/dist/lab/plan.js +10 -41
- package/dist/lab/preflight-probes.js +11 -11
- package/dist/lab/preflight-result.d.ts +2 -1
- package/dist/lab/preflight-result.js +5 -4
- package/dist/lab/preflight.d.ts +7 -5
- package/dist/lab/preflight.js +5 -5
- package/dist/lab/routing.d.ts +31 -25
- package/dist/lab/routing.js +60 -29
- package/dist/lab/run-lab-events.d.ts +0 -3
- package/dist/lab/run-lab-events.js +0 -6
- package/dist/lab/run-lab-homes.d.ts +22 -10
- package/dist/lab/run-lab-homes.js +5 -1
- package/dist/lab/run-lab-options.d.ts +1 -1
- package/dist/lab/run-lab-options.js +16 -13
- package/dist/lab/summary.d.ts +7 -6
- package/dist/lab/summary.js +10 -10
- package/dist/lab/tasks.d.ts +15 -15
- package/dist/lab/tasks.js +14 -14
- package/dist/lab/types.d.ts +101 -95
- package/dist/lab/types.js +2 -0
- package/dist/lab/validation.d.ts +13 -13
- package/dist/lab/validation.js +44 -42
- package/dist/lab/warnings.d.ts +10 -0
- package/dist/lab/warnings.js +61 -33
- package/dist/library-aliases.d.ts +56 -0
- package/dist/library-aliases.js +22 -0
- package/dist/observer/artifact.d.ts +1 -1
- package/dist/observer/artifact.js +6 -6
- 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 +1 -1
- package/dist/observer/library.js +4 -2
- package/dist/observer/listen.js +5 -4
- package/dist/observer/render.d.ts +1 -1
- package/dist/observer/render.js +10 -5
- package/dist/observer/run-routes.d.ts +3 -3
- package/dist/observer/run-routes.js +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 +15 -15
- package/dist/routes/computer-use/bundle.js +3 -3
- package/dist/routes/computer-use/e2b-desktop/comms.d.ts +1 -1
- package/dist/routes/computer-use/e2b-desktop/comms.js +14 -14
- package/dist/routes/computer-use/e2b-desktop/desktop.js +4 -4
- package/dist/routes/computer-use/e2b-desktop/fidelity.d.ts +4 -3
- package/dist/routes/computer-use/e2b-desktop/fidelity.js +11 -10
- package/dist/routes/computer-use/e2b-desktop/prepare.js +7 -7
- package/dist/routes/computer-use/e2b-desktop/start.js +9 -8
- package/dist/routes/computer-use/e2b-desktop/teardown.js +5 -4
- package/dist/routes/computer-use/external-comms.d.ts +1 -1
- package/dist/routes/computer-use/external-comms.js +1 -1
- package/dist/routes/computer-use/fanout-bundle.js +18 -18
- package/dist/routes/computer-use/fanout-records.js +10 -11
- package/dist/routes/computer-use/live-flush.d.ts +1 -1
- package/dist/routes/computer-use/live-flush.js +6 -6
- package/dist/routes/computer-use/live-phase.d.ts +4 -2
- package/dist/routes/computer-use/live-phase.js +6 -6
- package/dist/routes/computer-use/local-vm.js +1 -1
- package/dist/routes/computer-use/participant-desktop.d.ts +4 -4
- package/dist/routes/computer-use/participant-desktop.js +4 -4
- package/dist/routes/computer-use/participant-execution.d.ts +4 -4
- package/dist/routes/computer-use/participant-execution.js +9 -9
- package/dist/routes/computer-use/participant-model.d.ts +6 -0
- package/dist/routes/computer-use/participant-model.js +31 -13
- package/dist/routes/computer-use/participant-prompt.d.ts +11 -11
- package/dist/routes/computer-use/participant-prompt.js +6 -6
- package/dist/routes/computer-use/participant-runs.d.ts +7 -7
- package/dist/routes/computer-use/participant-runs.js +13 -13
- package/dist/routes/computer-use/plan.js +22 -22
- package/dist/routes/computer-use/preflight.js +21 -21
- package/dist/routes/computer-use/rerun-selection.js +1 -1
- package/dist/routes/computer-use/result.js +11 -11
- package/dist/routes/computer-use/route.d.ts +2 -1
- package/dist/routes/computer-use/route.js +15 -14
- package/dist/routes/computer-use/self-report.d.ts +7 -7
- package/dist/routes/computer-use/self-report.js +31 -31
- package/dist/routes/computer-use/setup.d.ts +1 -1
- package/dist/routes/computer-use/setup.js +17 -18
- package/dist/routes/computer-use/single-bundle.d.ts +7 -7
- package/dist/routes/computer-use/single-bundle.js +28 -30
- package/dist/routes/computer-use/subject-projection.d.ts +1 -1
- package/dist/routes/computer-use/subject-projection.js +6 -6
- package/dist/routes/computer-use/types.d.ts +40 -42
- package/dist/routes/computer-use/types.js +10 -10
- package/dist/routes/preview.d.ts +8 -2
- package/dist/routes/preview.js +8 -4
- package/dist/routes/scripted/bundle.d.ts +2 -2
- package/dist/routes/scripted/bundle.js +13 -12
- package/dist/routes/scripted/plan.d.ts +1 -1
- package/dist/routes/scripted/plan.js +9 -9
- package/dist/routes/scripted/result.js +5 -5
- package/dist/routes/scripted/route.js +5 -6
- package/dist/routes/scripted/scenario.js +2 -2
- package/dist/routes/scripted/setup.js +7 -7
- package/dist/routes/scripted/subject.js +1 -1
- package/dist/routes/scripted/surface-records.js +3 -3
- package/dist/routes/scripted/types.d.ts +3 -5
- package/dist/routes/scripted/types.js +1 -1
- package/dist/routes/shared-world/bundle-records.js +9 -8
- package/dist/routes/shared-world/bundle.d.ts +5 -5
- package/dist/routes/shared-world/bundle.js +40 -38
- package/dist/routes/shared-world/checkpoints.d.ts +1 -1
- package/dist/routes/shared-world/checkpoints.js +1 -1
- package/dist/routes/shared-world/comms.d.ts +5 -5
- package/dist/routes/shared-world/comms.js +14 -14
- 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 +7 -6
- package/dist/routes/shared-world/participant-specs.js +31 -24
- package/dist/routes/shared-world/plan.js +7 -7
- 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.js +14 -13
- package/dist/routes/shared-world/result.js +20 -21
- package/dist/routes/shared-world/route.js +23 -22
- package/dist/routes/shared-world/setup.d.ts +3 -3
- package/dist/routes/shared-world/setup.js +4 -4
- package/dist/routes/shared-world/types.d.ts +30 -28
- package/dist/routes/shared-world/types.js +4 -4
- package/dist/routes/terminal/adapter.d.ts +3 -3
- package/dist/routes/terminal/adapter.js +5 -5
- package/dist/routes/terminal/bundle.d.ts +3 -3
- package/dist/routes/terminal/bundle.js +22 -21
- package/dist/routes/terminal/credentials.d.ts +4 -4
- package/dist/routes/terminal/credentials.js +7 -7
- package/dist/routes/terminal/dry-run.js +4 -4
- package/dist/routes/terminal/encoding.js +2 -2
- package/dist/routes/terminal/ledger.d.ts +3 -3
- package/dist/routes/terminal/ledger.js +14 -14
- package/dist/routes/terminal/live-finish.js +3 -3
- package/dist/routes/terminal/live-sandbox.js +12 -13
- package/dist/routes/terminal/persona.js +1 -1
- package/dist/routes/terminal/plan.js +11 -11
- package/dist/routes/terminal/recorder.js +2 -2
- package/dist/routes/terminal/result.js +8 -8
- package/dist/routes/terminal/route.js +6 -7
- package/dist/routes/terminal/sandbox.d.ts +1 -1
- package/dist/routes/terminal/sandbox.js +1 -1
- package/dist/routes/terminal/session.js +8 -7
- 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 +2 -2
- package/dist/routes/terminal/trace.js +2 -2
- package/dist/routes/terminal/types.d.ts +26 -28
- package/dist/routes/terminal/types.js +3 -3
- package/dist/run/bundle-shape.js +3 -3
- package/dist/run/bundle.d.ts +46 -46
- package/dist/run/bundle.js +2 -1
- package/dist/run/cost-summary.js +3 -3
- package/dist/run/costs.js +7 -1
- package/dist/run/detail.d.ts +6 -6
- package/dist/run/detail.js +4 -4
- package/dist/run/dry-run-inputs.js +1 -1
- package/dist/run/dry-run.js +18 -18
- package/dist/run/judge.d.ts +19 -13
- package/dist/run/judge.js +18 -8
- package/dist/run/paths.d.ts +1 -1
- package/dist/run/paths.js +1 -1
- package/dist/run/pricing.d.ts +11 -6
- package/dist/run/pricing.js +20 -13
- package/dist/run/projection.d.ts +14 -14
- package/dist/run/projection.js +15 -15
- package/dist/run/reclaim.js +2 -2
- package/dist/run/results.d.ts +5 -5
- package/dist/run/run-index.d.ts +8 -6
- package/dist/run/run-index.js +15 -16
- 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 +5 -4
- package/dist/run/run.js +1 -1
- 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 +36 -35
- 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 +6 -6
- package/dist/run/stats.d.ts +12 -6
- package/dist/run/stats.js +116 -58
- package/dist/run/status.d.ts +8 -29
- package/dist/run/status.js +5 -27
- package/dist/run/stored-runs.js +2 -1
- package/dist/run/stream-shape.js +1 -1
- package/dist/run/streams.d.ts +6 -6
- package/dist/run/study-provenance.d.ts +47 -0
- package/dist/run/study-provenance.js +63 -0
- package/dist/run/study-result.d.ts +16 -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-lab.d.ts +7 -7
- package/dist/run-lab.js +1 -3
- package/dist/study/convert.d.ts +33 -0
- package/dist/study/convert.js +432 -0
- 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 +43 -0
- 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/subject/clone.d.ts +1 -1
- package/dist/subject/desktop-cli.d.ts +1 -1
- package/dist/subject/desktop-cli.js +2 -2
- package/dist/subject/local-tree-archive.js +1 -1
- package/dist/subject/local-tree.d.ts +1 -1
- package/dist/subject/node-bootstrap.js +1 -1
- package/dist/subject/runtime.js +8 -9
- package/dist/subject/serve.d.ts +1 -1
- package/dist/subject/serve.js +3 -3
- package/dist/subject/state.d.ts +1 -1
- package/dist/subject/steps.d.ts +5 -5
- package/dist/subject/steps.js +4 -4
- package/dist/substrates/command-failure.d.ts +3 -3
- package/dist/substrates/command-failure.js +3 -3
- 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 +2 -2
- package/dist/substrates/e2b/desktop-browser.js +8 -8
- package/dist/substrates/e2b/desktop-cdp.d.ts +9 -9
- package/dist/substrates/e2b/desktop-cdp.js +8 -8
- package/dist/substrates/e2b/desktop-executor.d.ts +1 -1
- package/dist/substrates/e2b/desktop-executor.js +1 -1
- package/dist/substrates/e2b/desktop-geometry.d.ts +3 -3
- package/dist/substrates/e2b/desktop-geometry.js +7 -7
- package/dist/substrates/e2b/desktop-media.d.ts +1 -1
- 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/sandbox.d.ts +1 -1
- package/dist/substrates/e2b/sandbox.js +1 -1
- package/dist/substrates/e2b/sdk.d.ts +11 -11
- package/dist/substrates/e2b/sdk.js +6 -6
- package/dist/tui/actions.d.ts +1 -1
- package/dist/tui/actions.js +13 -13
- package/dist/tui/contract.d.ts +16 -16
- package/dist/tui/contract.js +10 -10
- package/dist/tui/launch.d.ts +4 -4
- package/dist/tui/launch.js +18 -19
- package/dist/tui/project.js +5 -5
- package/dist/tui-app.js +82 -82
- 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 +4 -4
- package/dist/verify/subject.js +18 -18
- package/dist/verify/verify.js +92 -43
- package/docs/README.md +25 -32
- package/docs/architecture/actor-contract.md +56 -87
- package/docs/architecture/desktop-sessions.md +7 -7
- package/docs/architecture/external-public-shared-world.md +61 -59
- package/docs/architecture/github-feedback-loop.md +1 -4
- 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 +5 -5
- package/docs/architecture/terminal-product-route.md +67 -107
- package/docs/contracts/README.md +24 -0
- package/docs/contracts/adapter-admission.md +3 -3
- package/docs/contracts/adapter-fixtures.md +2 -5
- 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 +45 -44
- package/docs/contracts/schemas.md +421 -362
- package/docs/contracts/study-analysis.md +3 -3
- package/docs/contracts/study-costs.md +11 -7
- 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/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/package.json +16 -17
- package/skills/humanish/SKILL.md +60 -58
- 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.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/observer/static.d.ts +0 -39
- package/dist/observer/static.js +0 -369
- 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
|
@@ -20,7 +20,7 @@ export class TraceRecorder {
|
|
|
20
20
|
constructor(now) {
|
|
21
21
|
this.now = now;
|
|
22
22
|
}
|
|
23
|
-
// The
|
|
23
|
+
// The single recording choke point: every trace item is stamped `at` from the
|
|
24
24
|
// loop's injected clock as it is recorded, so timed playback reads recorded facts
|
|
25
25
|
// (deterministic in tests via the injected `now`). The id is allocated before the body is
|
|
26
26
|
// built, so a body that fails to build (a redaction error) still consumes its id.
|
|
@@ -40,7 +40,7 @@ export function statusForCompletionReason(reason) {
|
|
|
40
40
|
case "turn_completed": // turn_completed is a Codex reason; this loop emits goal_satisfied
|
|
41
41
|
return "passed";
|
|
42
42
|
// A session that ran out of time or budget did not reach its goal, whatever it achieved along
|
|
43
|
-
// the way. Calling that `passed` is how a truncated study came to be reported as a green one
|
|
43
|
+
// the way. Calling that `passed` is how a truncated study came to be reported as a green one,
|
|
44
44
|
// and why "raise the timeout" kept landing on the operator instead of on the tool. This switch
|
|
45
45
|
// is exhaustive with no default, so a new completion reason forces a compile error here.
|
|
46
46
|
case "budget_reached":
|
|
@@ -51,7 +51,7 @@ export function statusForCompletionReason(reason) {
|
|
|
51
51
|
return "blocked";
|
|
52
52
|
// A participant who stopped trying is the single most valuable thing a usability study
|
|
53
53
|
// produces. Recording it as `failed` said the instrument broke, which is a different claim and
|
|
54
|
-
// a false one
|
|
54
|
+
// a false one; see docs/principles/three-roles.md.
|
|
55
55
|
case "gave_up":
|
|
56
56
|
return "abandoned";
|
|
57
57
|
// Only the harness failing is a harness failure.
|
|
@@ -77,12 +77,12 @@ export function loopResult(session, stop, debrief) {
|
|
|
77
77
|
? "no screenshots captured"
|
|
78
78
|
: session.redactScreenshots
|
|
79
79
|
? `${counts.screenshots} screenshot(s) redacted to blurred thumbnails via RedactionHooks`
|
|
80
|
-
: `${counts.screenshots}
|
|
81
|
-
// Self-describing artifact
|
|
80
|
+
: `${counts.screenshots} unblurred screenshot(s) kept for local use and not redacted for publishing; set redactScreenshots to blur screenshots in a bundle you plan to share`;
|
|
81
|
+
// Self-describing artifact: when any observation carried structured app state,
|
|
82
82
|
// the trace says how the loop handled it: it fed progress and task checks and was not written to
|
|
83
83
|
// the trace. The appState itself never appears in this bundle.
|
|
84
84
|
const notes = session.observedAppState
|
|
85
|
-
? `${screenshotNote}. App state was
|
|
85
|
+
? `${screenshotNote}. App state was read each turn to detect progress (an in-process executor) and was not written to the trace: it is used only while the run is live and is never stored as evidence.`
|
|
86
86
|
: screenshotNote;
|
|
87
87
|
const tokenUsage = usage.tokenUsage();
|
|
88
88
|
const trace = {
|
|
@@ -90,6 +90,7 @@ export function loopResult(session, stop, debrief) {
|
|
|
90
90
|
provider: provider.id,
|
|
91
91
|
...usage.liveMetadata(),
|
|
92
92
|
...(provider.version === undefined ? {} : { providerVersion: provider.version }),
|
|
93
|
+
...(provider.conversation === undefined ? {} : { conversation: provider.conversation }),
|
|
93
94
|
protocol: "cua-loop",
|
|
94
95
|
lane: "computer-use",
|
|
95
96
|
persona: settings.persona,
|
|
@@ -130,8 +131,8 @@ export function loopResult(session, stop, debrief) {
|
|
|
130
131
|
...(usage.interactionUsageIncomplete(session.capDeclared)
|
|
131
132
|
? { interactionUsageIncomplete: true }
|
|
132
133
|
: {}),
|
|
133
|
-
// The funnel is present exactly when a protocol was declared
|
|
134
|
-
// on turn 0, whose funnel
|
|
134
|
+
// The funnel is present exactly when a protocol was declared, including a session that ended
|
|
135
|
+
// on turn 0, whose funnel reads 0/N. No tasks declared means no funnel, not an empty one.
|
|
135
136
|
...(session.taskTracker === undefined ? {} : { taskFunnel: session.taskTracker.funnel() }),
|
|
136
137
|
...(tokenUsage === undefined ? {} : { tokenUsage }),
|
|
137
138
|
capabilities: provider.capabilities,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { HeardSpeech } from "../speech.js";
|
|
2
|
-
import type { ActorCapabilities, ActorExecutionProfile, ActorPersonaRef, ActorSessionResult, ActorTokenUsage, ActorTrace, ActorTraceItem, ParticipantClosingReport, ParticipantDeclaredOutcome, ProviderRequestReceipt } from "../../contract.js";
|
|
2
|
+
import type { ActorCapabilities, ActorConversation, ActorExecutionProfile, ActorPersonaRef, ActorSessionResult, ActorTokenUsage, ActorTrace, ActorTraceItem, ParticipantClosingReport, ParticipantDeclaredOutcome, ProviderRequestReceipt } from "../../contract.js";
|
|
3
3
|
import type { RedactionHooks } from "../../../evidence/redaction.js";
|
|
4
4
|
import type { DwellWindow, StopWhen } from "../../stop-conditions.js";
|
|
5
5
|
import type { LabTask } from "../../../lab/tasks.js";
|
|
@@ -93,7 +93,7 @@ export interface CuaObservation {
|
|
|
93
93
|
url?: string;
|
|
94
94
|
/**
|
|
95
95
|
* The page's vertical scroll offset (window.scrollY), when the executor can read it. Scroll
|
|
96
|
-
* position is state
|
|
96
|
+
* position is state: inside a scroll-pinned section the viewport stays visually fixed
|
|
97
97
|
* while the participant advances, so the frame hash alone reads "no change". Runtime-only like
|
|
98
98
|
* url and text: it feeds the progress key, bucketed, and is never persisted.
|
|
99
99
|
*/
|
|
@@ -182,7 +182,7 @@ export interface CuaTurn {
|
|
|
182
182
|
done: boolean;
|
|
183
183
|
/** Explicit provider interruption, independent of actions or participant intent. */
|
|
184
184
|
interruption?: "output_limit" | "token_limit" | "incomplete" | "unexpected_status";
|
|
185
|
-
/** The participant's own word for how it ended, when its reply format carries one
|
|
185
|
+
/** The participant's own word for how it ended, when its reply format carries one. */
|
|
186
186
|
outcome?: ParticipantDeclaredOutcome;
|
|
187
187
|
/** Present only for an accepted structured closing account. */
|
|
188
188
|
closingReport?: ParticipantClosingReport;
|
|
@@ -193,11 +193,13 @@ export interface CuaProvider {
|
|
|
193
193
|
readonly requestPolicy?: "fail_closed";
|
|
194
194
|
readonly executionProfile?: ActorExecutionProfile | undefined;
|
|
195
195
|
readonly historyTurnsOmitted?: number;
|
|
196
|
+
/** How the conversation was carried between requests, for the trace. */
|
|
197
|
+
readonly conversation?: ActorConversation;
|
|
196
198
|
readonly id: string;
|
|
197
199
|
readonly version?: string | undefined;
|
|
198
200
|
/**
|
|
199
201
|
* The request settings this provider will actually send, for the trace to record. `version` says
|
|
200
|
-
*
|
|
202
|
+
* which model; this says how it was asked to run. Optional: a provider with no such settings
|
|
201
203
|
* records none, and absence stays absence rather than becoming a default nobody chose.
|
|
202
204
|
*/
|
|
203
205
|
readonly modelSettings?: {
|
|
@@ -259,13 +261,13 @@ export interface CuaLoopOptions {
|
|
|
259
261
|
/** Hard wall-clock runaway guard. The only count-free hard stop. */
|
|
260
262
|
timeoutMs: number;
|
|
261
263
|
/**
|
|
262
|
-
* Per-attempt bound on the provider call
|
|
264
|
+
* Per-attempt bound on the provider call, so a hung request is told apart from a
|
|
263
265
|
* participant still thinking. A stalled turn is retried once with a notice; a second stall ends
|
|
264
266
|
* the participant as harness_error.
|
|
265
267
|
*/
|
|
266
268
|
turnTimeoutMs?: number;
|
|
267
269
|
/**
|
|
268
|
-
* Per-call bound on observation work
|
|
270
|
+
* Per-call bound on observation work: executor.observe() and the idle actions (`wait`,
|
|
269
271
|
* `screenshot`), whose only job is to look. A `wait` adds its own ms to the bound. A stalled
|
|
270
272
|
* observe is retried once; a stalled idle action is skipped with a notice.
|
|
271
273
|
*/
|
|
@@ -288,19 +290,19 @@ export interface CuaLoopOptions {
|
|
|
288
290
|
*/
|
|
289
291
|
acknowledgeSafetyChecks?: (checks: CuaSafetyCheck[]) => CuaSafetyCheck[] | null;
|
|
290
292
|
/**
|
|
291
|
-
* Redact (blur+downscale) persisted screenshots. Default
|
|
292
|
-
* retained, because the common case is a developer watching a sim of their
|
|
293
|
+
* Redact (blur+downscale) persisted screenshots. Default `false`: full-fidelity frames are
|
|
294
|
+
* retained, because the common case is a developer watching a sim of their own app locally
|
|
293
295
|
* (gitignored .humanish), where blur destroys the core deliverable. Set true for unowned
|
|
294
|
-
* subjects or when the bundle is meant to be shared as-is. The frame sent to the
|
|
296
|
+
* subjects or when the bundle is meant to be shared as-is. The frame sent to the provider is
|
|
295
297
|
* always full-resolution regardless (the model must see the screen to act); this flag only
|
|
296
|
-
* governs what is
|
|
298
|
+
* governs what is persisted. Publish-safety belongs at the publish boundary (commit scan / redactScreenshots), not capture.
|
|
297
299
|
*/
|
|
298
300
|
redactScreenshots?: boolean;
|
|
299
301
|
/**
|
|
300
|
-
* Extra literal scrub for
|
|
301
|
-
* pattern redaction cannot catch them), composed
|
|
302
|
+
* Extra literal scrub for known provisioned values (which have no detectable "shape", so
|
|
303
|
+
* pattern redaction cannot catch them), composed before redactText on every model-authored
|
|
302
304
|
* text item (reasoning, message, completion summary) and the loop error. The lab passes the
|
|
303
|
-
* env-value scrubber here so a value the
|
|
305
|
+
* env-value scrubber here so a value the model narrates can never land raw in the trace.
|
|
304
306
|
* Default: identity (the loop is shape-only on its own).
|
|
305
307
|
*/
|
|
306
308
|
scrubText?: (text: string) => string;
|
|
@@ -313,7 +315,7 @@ export interface CuaLoopOptions {
|
|
|
313
315
|
*/
|
|
314
316
|
stopWhen?: StopWhen;
|
|
315
317
|
/**
|
|
316
|
-
* A declared observation window
|
|
318
|
+
* A declared observation window: once its condition matches (or after the first
|
|
317
319
|
* observation when it has none) the loop holds the page for the window, captures a frame on the
|
|
318
320
|
* cadence, takes no action and requests no model turn, then hands control back or ends. Runs at
|
|
319
321
|
* most once per session and never past the session budget.
|
|
@@ -322,11 +324,11 @@ export interface CuaLoopOptions {
|
|
|
322
324
|
/** Injected pause for the dwell window's cadence; tests advance their clock through it. */
|
|
323
325
|
sleep?: (ms: number) => Promise<void>;
|
|
324
326
|
/**
|
|
325
|
-
* The lab's declared protocol
|
|
327
|
+
* The lab's declared protocol: discrete tasks whose completion is corroborated by the
|
|
326
328
|
* same observations stopWhen reads, on the same cadence. The tracker never influences the loop's
|
|
327
|
-
* control flow
|
|
329
|
+
* control flow: a completed task list does not stop a session (that is stopWhen's job); it only
|
|
328
330
|
* records the funnel that lands on the trace. The participant-facing halves of these tasks are
|
|
329
|
-
* already
|
|
331
|
+
* already in `instructions` (composed upstream); the loop reads only the `success` criteria,
|
|
330
332
|
* which never reach the prompt.
|
|
331
333
|
*/
|
|
332
334
|
tasks?: readonly LabTask[];
|
|
@@ -338,18 +340,18 @@ export interface CuaLoopOptions {
|
|
|
338
340
|
*/
|
|
339
341
|
maxUsd?: number;
|
|
340
342
|
/**
|
|
341
|
-
* Injected
|
|
343
|
+
* Injected pure per-turn cost estimator (keeps the loop free of the operator rate table and
|
|
342
344
|
* makes the cap deterministic in tests). Given running (input, output) token totals, returns the
|
|
343
345
|
* estimated USD, or null when unpriceable. Only consulted when `maxUsd` is set. A null estimate
|
|
344
|
-
* mid-run cannot trip the cap
|
|
346
|
+
* mid-run cannot trip the cap; preflight already guaranteed a rate exists, so a null here is a
|
|
345
347
|
* vanished-rate harness condition, not a silent uncapped pass.
|
|
346
348
|
*/
|
|
347
349
|
estimateTurnCostUsd?: (usage: ActorTokenUsage) => number | null;
|
|
348
350
|
/**
|
|
349
|
-
*
|
|
350
|
-
* point the per-participant cap is checked. Returns a human-readable reason when the
|
|
351
|
+
* Run-level spend guard: called with this participant's running usage each turn, at the same
|
|
352
|
+
* point the per-participant cap is checked. Returns a human-readable reason when the study's shared
|
|
351
353
|
* budget is exhausted, else null. On a non-null return the loop stops with `budget_reached`
|
|
352
|
-
* regardless of material progress
|
|
354
|
+
* regardless of material progress: a study-level stop is a recruiting decision hitting its
|
|
353
355
|
* limit, not this participant's runaway, so it never reads as `gave_up`.
|
|
354
356
|
*/
|
|
355
357
|
overRunBudget?: (usage: ActorTokenUsage) => string | null;
|
|
@@ -399,7 +401,7 @@ export interface CuaLoopOptions {
|
|
|
399
401
|
*/
|
|
400
402
|
onScreenshot?: (frame: Buffer) => void;
|
|
401
403
|
/**
|
|
402
|
-
* Trace snapshot for a watcher
|
|
404
|
+
* Trace snapshot for a watcher: the redacted items recorded so far, with the running
|
|
403
405
|
* usage so a run can be priced in flight. Called after each checkpoint's screenshot (the initial
|
|
404
406
|
* observation and every acted turn, so a flush never shows an action without the frame before
|
|
405
407
|
* it), after each dwell frame, and after a closing request. The array is a fresh copy; its items
|
|
@@ -80,7 +80,7 @@ export class UsageLedger {
|
|
|
80
80
|
cachedInput = 0;
|
|
81
81
|
cacheWriteInput = 0;
|
|
82
82
|
output = 0;
|
|
83
|
-
// Per model-inference usage, in order
|
|
83
|
+
// Per model-inference usage, in order: the recorded fact long-context pricing tiers
|
|
84
84
|
// need. A continuing native tool interaction may contain several inference requests.
|
|
85
85
|
turns = [];
|
|
86
86
|
/** An interaction turn arrived without complete usage, or its receipt said usage is incomplete. */
|
|
@@ -245,7 +245,7 @@ export class UsageLedger {
|
|
|
245
245
|
input: this.input,
|
|
246
246
|
output: this.output,
|
|
247
247
|
// Recorded only when the provider actually reported it, so a reader can tell "no cache
|
|
248
|
-
// hits" from "this provider does not say"
|
|
248
|
+
// hits" from "this provider does not say"; same for cache writes.
|
|
249
249
|
...(this.cachedInput > 0 ? { cachedInput: this.cachedInput } : {}),
|
|
250
250
|
...(this.cacheWriteInput > 0 ? { cacheWriteInput: this.cacheWriteInput } : {}),
|
|
251
251
|
...(this.turns.length > 0 ? { turns: this.turns.map((turn) => ({ ...turn })) } : {}),
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/** The estimated input a carried conversation may reach before its oldest turns are summarized. */
|
|
2
|
+
export declare const CONTEXT_TOKEN_BUDGET = 64000;
|
|
3
|
+
/** What the next request would carry, for the trace. */
|
|
4
|
+
export interface CarriedContextSize {
|
|
5
|
+
readonly exchanges: number;
|
|
6
|
+
readonly screenshots: number;
|
|
7
|
+
readonly notedTurns: number;
|
|
8
|
+
readonly estimatedTokens: number;
|
|
9
|
+
}
|
|
10
|
+
export declare class CarriedConversation {
|
|
11
|
+
private readonly budget;
|
|
12
|
+
private opening;
|
|
13
|
+
private readonly exchanges;
|
|
14
|
+
/** The latest accepted reply's output items, which the next request answers. */
|
|
15
|
+
private pending;
|
|
16
|
+
private readonly notes;
|
|
17
|
+
private notesDropped;
|
|
18
|
+
private collapsedTurns;
|
|
19
|
+
constructor(budget?: number);
|
|
20
|
+
/**
|
|
21
|
+
* Record an accepted reply. `sent` is what that request added after the carried items: the
|
|
22
|
+
* opening message on the first request, then the call outputs and any hint.
|
|
23
|
+
*/
|
|
24
|
+
accept(turn: number, sent: readonly unknown[], output: readonly unknown[]): void;
|
|
25
|
+
/** The items to send ahead of a request's own new items. */
|
|
26
|
+
carried(): unknown[];
|
|
27
|
+
/** The carried context's size, for the trace. */
|
|
28
|
+
size(): CarriedContextSize;
|
|
29
|
+
private trim;
|
|
30
|
+
private noteItem;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* A rough input-token estimate: images by their size in 32-pixel patches, everything else at four
|
|
34
|
+
* characters a token. It decides when to trim, not what is billed; the trace records the billed
|
|
35
|
+
* input per request beside it.
|
|
36
|
+
*/
|
|
37
|
+
export declare function estimateTokens(items: readonly unknown[]): number;
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import { asArray, asRecord, inputMessage, openAiActionToCua } from "./openai-wire.js";
|
|
2
|
+
// The conversation an explicit-context request carries, kept on the client because the server
|
|
3
|
+
// keeps none (a zero-data-retention org, or zeroDataRetention set). Requests made while the
|
|
4
|
+
// provider still threads on previous_response_id feed it too, so a switch partway through a
|
|
5
|
+
// session keeps everything before the switch.
|
|
6
|
+
//
|
|
7
|
+
// The Responses API pairs items: every computer_call needs its computer_call_output, and a
|
|
8
|
+
// reasoning item travels with the item it preceded. The conversation is therefore cut only at
|
|
9
|
+
// exchange boundaries: one reply's output items together with the items that answered them.
|
|
10
|
+
// When the estimate passes the budget, the opening screenshot goes first, then the oldest
|
|
11
|
+
// exchanges become lines of a progress note that keeps their reasoning summaries, messages and
|
|
12
|
+
// actions as text. The note is an assistant message, so text the model wrote (which can quote a
|
|
13
|
+
// web page) keeps the trust it had when the model wrote it. The newest MIN_KEPT_EXCHANGES
|
|
14
|
+
// exchanges are never collapsed, so a request passes the budget when they alone exceed it; the
|
|
15
|
+
// trace's per-request estimate shows when that happens.
|
|
16
|
+
/** The estimated input a carried conversation may reach before its oldest turns are summarized. */
|
|
17
|
+
export const CONTEXT_TOKEN_BUDGET = 64_000;
|
|
18
|
+
/** Exchanges always carried whole, so the model sees its latest actions with their screens. */
|
|
19
|
+
const MIN_KEPT_EXCHANGES = 2;
|
|
20
|
+
/** The progress note's length cap; past it, the oldest lines are counted instead of shown. */
|
|
21
|
+
const NOTE_CHAR_LIMIT = 16_000;
|
|
22
|
+
/** One note line's cap, so a reply with many actions cannot push the note past its own cap. */
|
|
23
|
+
const LINE_CHAR_LIMIT = 1_200;
|
|
24
|
+
/**
|
|
25
|
+
* Image input tokens per 32-pixel patch. The gpt-5.x and gpt-6 models bill 1.2 per patch, and at
|
|
26
|
+
* the default (auto) detail gpt-5.6 and gpt-6 keep the screenshot's own size. Models that resize
|
|
27
|
+
* to a lower patch budget bill less, so the estimate errs high for them.
|
|
28
|
+
*/
|
|
29
|
+
const TOKENS_PER_PATCH = 1.2;
|
|
30
|
+
/** A screenshot whose size cannot be read is estimated as a 2,500-patch image. */
|
|
31
|
+
const UNKNOWN_IMAGE_TOKENS = 3_000;
|
|
32
|
+
export class CarriedConversation {
|
|
33
|
+
budget;
|
|
34
|
+
opening;
|
|
35
|
+
exchanges = [];
|
|
36
|
+
/** The latest accepted reply's output items, which the next request answers. */
|
|
37
|
+
pending;
|
|
38
|
+
notes = [];
|
|
39
|
+
notesDropped = 0;
|
|
40
|
+
collapsedTurns = 0;
|
|
41
|
+
constructor(budget = CONTEXT_TOKEN_BUDGET) {
|
|
42
|
+
this.budget = budget;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Record an accepted reply. `sent` is what that request added after the carried items: the
|
|
46
|
+
* opening message on the first request, then the call outputs and any hint.
|
|
47
|
+
*/
|
|
48
|
+
accept(turn, sent, output) {
|
|
49
|
+
if (this.pending === undefined) {
|
|
50
|
+
this.opening = asRecord(sent[0]);
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
this.exchanges.push({ turn: this.pending.turn, output: this.pending.output, answers: sent });
|
|
54
|
+
}
|
|
55
|
+
this.pending = { turn, output };
|
|
56
|
+
this.trim();
|
|
57
|
+
}
|
|
58
|
+
/** The items to send ahead of a request's own new items. */
|
|
59
|
+
carried() {
|
|
60
|
+
const note = this.noteItem();
|
|
61
|
+
return [
|
|
62
|
+
...(this.opening === undefined ? [] : [this.opening]),
|
|
63
|
+
...(note === undefined ? [] : [note]),
|
|
64
|
+
...this.exchanges.flatMap((exchange) => [...exchange.output, ...exchange.answers]),
|
|
65
|
+
...(this.pending?.output ?? []),
|
|
66
|
+
];
|
|
67
|
+
}
|
|
68
|
+
/** The carried context's size, for the trace. */
|
|
69
|
+
size() {
|
|
70
|
+
const items = this.carried();
|
|
71
|
+
return {
|
|
72
|
+
exchanges: this.exchanges.length + (this.pending === undefined ? 0 : 1),
|
|
73
|
+
screenshots: items.reduce((count, item) => count + imagesOf(item).length, 0),
|
|
74
|
+
notedTurns: this.collapsedTurns,
|
|
75
|
+
estimatedTokens: estimateTokens(items),
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
trim() {
|
|
79
|
+
while (estimateTokens(this.carried()) > this.budget) {
|
|
80
|
+
if (this.opening !== undefined && imagesOf(this.opening).length > 0) {
|
|
81
|
+
this.opening = withoutImages(this.opening);
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
if (this.exchanges.length <= MIN_KEPT_EXCHANGES)
|
|
85
|
+
return;
|
|
86
|
+
const oldest = this.exchanges.shift();
|
|
87
|
+
this.notes.push(describeExchange(oldest));
|
|
88
|
+
this.collapsedTurns += 1;
|
|
89
|
+
while (this.notes.join("\n").length > NOTE_CHAR_LIMIT && this.notes.length > 1) {
|
|
90
|
+
this.notes.shift();
|
|
91
|
+
this.notesDropped += 1;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
noteItem() {
|
|
96
|
+
if (this.notes.length === 0)
|
|
97
|
+
return undefined;
|
|
98
|
+
const lead = `My notes on my earlier turns in this session, oldest first. Their screenshots are no ` +
|
|
99
|
+
`longer shown; this is what I thought, said and did.` +
|
|
100
|
+
(this.notesDropped === 0 ? "" : ` (${this.notesDropped} earlier turns are not listed.)`);
|
|
101
|
+
return inputMessage("assistant", [
|
|
102
|
+
{ type: "output_text", text: `${lead}\n${this.notes.join("\n")}` },
|
|
103
|
+
]);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
/** One exchange as a progress-note line: its reasoning summary, message and actions. */
|
|
107
|
+
function describeExchange(exchange) {
|
|
108
|
+
const thought = [];
|
|
109
|
+
const said = [];
|
|
110
|
+
const did = [];
|
|
111
|
+
for (const raw of exchange.output) {
|
|
112
|
+
const item = asRecord(raw);
|
|
113
|
+
if (item.type === "reasoning")
|
|
114
|
+
for (const entry of asArray(item.summary)) {
|
|
115
|
+
const text = asRecord(entry).text;
|
|
116
|
+
if (typeof text === "string" && text.length > 0)
|
|
117
|
+
thought.push(text);
|
|
118
|
+
}
|
|
119
|
+
if (item.type === "message")
|
|
120
|
+
for (const entry of asArray(item.content)) {
|
|
121
|
+
const text = asRecord(entry).text;
|
|
122
|
+
if (typeof text === "string" && text.length > 0)
|
|
123
|
+
said.push(text);
|
|
124
|
+
}
|
|
125
|
+
if (item.type === "computer_call") {
|
|
126
|
+
const actions = Array.isArray(item.actions) ? item.actions : [item.action];
|
|
127
|
+
for (const action of actions) {
|
|
128
|
+
const mapped = openAiActionToCua(action);
|
|
129
|
+
if (mapped !== null)
|
|
130
|
+
did.push(describeAction(mapped));
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
const parts = [
|
|
135
|
+
thought.length > 0 ? `thought: ${clip(thought.join(" "), 400)}` : undefined,
|
|
136
|
+
said.length > 0 ? `said: ${clip(said.join(" "), 300)}` : undefined,
|
|
137
|
+
did.length > 0 ? `did: ${did.join(", ")}` : undefined,
|
|
138
|
+
].filter((part) => part !== undefined);
|
|
139
|
+
const line = `Turn ${exchange.turn}: ${parts.length > 0 ? parts.join("; ") : "no recorded output"}`;
|
|
140
|
+
return `${clip(line, LINE_CHAR_LIMIT - 1)}.`;
|
|
141
|
+
}
|
|
142
|
+
function describeAction(action) {
|
|
143
|
+
switch (action.kind) {
|
|
144
|
+
case "click":
|
|
145
|
+
case "double_click":
|
|
146
|
+
case "move":
|
|
147
|
+
return `${action.kind} (${action.x}, ${action.y})`;
|
|
148
|
+
case "scroll":
|
|
149
|
+
return `scroll at (${action.x}, ${action.y}) by (${action.dx}, ${action.dy})`;
|
|
150
|
+
case "type":
|
|
151
|
+
return `type ${JSON.stringify(clip(action.text, 120))}`;
|
|
152
|
+
case "keypress":
|
|
153
|
+
return `keypress ${action.keys.join("+")}`;
|
|
154
|
+
default:
|
|
155
|
+
return action.kind;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
function clip(text, limit) {
|
|
159
|
+
const flat = text.replace(/\s+/g, " ").trim();
|
|
160
|
+
return flat.length <= limit ? flat : `${flat.slice(0, limit - 3)}...`;
|
|
161
|
+
}
|
|
162
|
+
/** The data URLs of the images an input item carries. */
|
|
163
|
+
function imagesOf(item) {
|
|
164
|
+
const record = asRecord(item);
|
|
165
|
+
const output = asRecord(record.output);
|
|
166
|
+
const urls = [];
|
|
167
|
+
if (typeof output.image_url === "string")
|
|
168
|
+
urls.push(output.image_url);
|
|
169
|
+
for (const part of asArray(record.content)) {
|
|
170
|
+
const url = asRecord(part).image_url;
|
|
171
|
+
if (typeof url === "string")
|
|
172
|
+
urls.push(url);
|
|
173
|
+
}
|
|
174
|
+
return urls;
|
|
175
|
+
}
|
|
176
|
+
function withoutImages(item) {
|
|
177
|
+
return {
|
|
178
|
+
...item,
|
|
179
|
+
content: asArray(item.content).filter((part) => asRecord(part).type !== "input_image"),
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* A rough input-token estimate: images by their size in 32-pixel patches, everything else at four
|
|
184
|
+
* characters a token. It decides when to trim, not what is billed; the trace records the billed
|
|
185
|
+
* input per request beside it.
|
|
186
|
+
*/
|
|
187
|
+
export function estimateTokens(items) {
|
|
188
|
+
let tokens = 0;
|
|
189
|
+
for (const item of items) {
|
|
190
|
+
const images = imagesOf(item);
|
|
191
|
+
for (const url of images)
|
|
192
|
+
tokens += imageTokens(url);
|
|
193
|
+
const text = JSON.stringify(item, (key, value) => (key === "image_url" ? "" : value));
|
|
194
|
+
tokens += Math.ceil(text.length / 4);
|
|
195
|
+
}
|
|
196
|
+
return tokens;
|
|
197
|
+
}
|
|
198
|
+
function imageTokens(dataUrl) {
|
|
199
|
+
const size = pngSize(dataUrl);
|
|
200
|
+
if (size === undefined)
|
|
201
|
+
return UNKNOWN_IMAGE_TOKENS;
|
|
202
|
+
const patches = Math.ceil(size.width / 32) * Math.ceil(size.height / 32);
|
|
203
|
+
return Math.ceil(patches * TOKENS_PER_PATCH);
|
|
204
|
+
}
|
|
205
|
+
/** A PNG's width and height, from the IHDR chunk at the start of its data URL. */
|
|
206
|
+
function pngSize(dataUrl) {
|
|
207
|
+
const prefix = "data:image/png;base64,";
|
|
208
|
+
if (!dataUrl.startsWith(prefix))
|
|
209
|
+
return undefined;
|
|
210
|
+
const head = Buffer.from(dataUrl.slice(prefix.length, prefix.length + 32), "base64");
|
|
211
|
+
if (head.length < 24 || head.toString("ascii", 12, 16) !== "IHDR")
|
|
212
|
+
return undefined;
|
|
213
|
+
return { width: head.readUInt32BE(16), height: head.readUInt32BE(20) };
|
|
214
|
+
}
|
|
@@ -7,13 +7,13 @@ export declare const DEFAULT_OPENAI_CU_MODEL = "gpt-5.6-sol";
|
|
|
7
7
|
/**
|
|
8
8
|
* The effort a request carries when a lab declares none. Exported because a default that only
|
|
9
9
|
* exists as a literal inside the provider is exactly how it stayed invisible: the lab surface has
|
|
10
|
-
* to be able to say what will actually run
|
|
10
|
+
* to be able to say what will actually run.
|
|
11
11
|
*/
|
|
12
12
|
export declare const DEFAULT_OPENAI_CU_REASONING_EFFORT: ReasoningEffort;
|
|
13
13
|
/** The opt-in gate for response wire capture: a directory path, or unset for off. */
|
|
14
14
|
export declare const WIRE_CAPTURE_ENV = "HUMANISH_CUA_WIRE_CAPTURE_DIR";
|
|
15
15
|
/**
|
|
16
|
-
* Deep-copy a captured wire value with every string
|
|
16
|
+
* Deep-copy a captured wire value with every string (object keys included)
|
|
17
17
|
* passed through the shared redactText, so a secret-shaped echo in a response
|
|
18
18
|
* can never persist to disk. Pure; non-string primitives pass through unchanged.
|
|
19
19
|
*/
|
|
@@ -61,7 +61,7 @@ export interface OpenAiResponsesProviderOptions {
|
|
|
61
61
|
model?: string;
|
|
62
62
|
/**
|
|
63
63
|
* How hard the model is asked to think per turn. Absent = the provider default below.
|
|
64
|
-
* The vocabulary is the documented union across models;
|
|
64
|
+
* The vocabulary is the documented union across models; support is model-dependent, so an
|
|
65
65
|
* unsupported level surfaces as the provider's own first-turn error rather than a silent
|
|
66
66
|
* downgrade to something the trace would then misreport. See src/actors/reasoning-effort.ts.
|
|
67
67
|
*/
|
|
@@ -69,11 +69,11 @@ export interface OpenAiResponsesProviderOptions {
|
|
|
69
69
|
/** Optional positive integer output limit per response, including reasoning. Not a spend cap. */
|
|
70
70
|
maxOutputTokens?: number;
|
|
71
71
|
/**
|
|
72
|
-
* Reasoning-summary capture
|
|
72
|
+
* Reasoning-summary capture. Defaults to "auto" (the provider picks the best
|
|
73
73
|
* summarizer the model supports); "off" never asks. If the account/model rejects the
|
|
74
74
|
* request (e.g. an org not verified for reasoning summaries), the provider latches
|
|
75
|
-
* summaries off for the session and retries the same turn
|
|
76
|
-
*
|
|
75
|
+
* summaries off for the session and retries the same turn; the run degrades to
|
|
76
|
+
* a run without summaries instead of failing after spend. The trace records the absence:
|
|
77
77
|
* no summary means no `reasoning` trace items and `counts.reasonings` stays 0.
|
|
78
78
|
*/
|
|
79
79
|
reasoningSummary?: OpenAiReasoningSummary | "off";
|
|
@@ -86,9 +86,12 @@ export interface OpenAiResponsesProviderOptions {
|
|
|
86
86
|
* paid request. */
|
|
87
87
|
singleDispatch?: boolean;
|
|
88
88
|
delayFn?: (ms: number) => Promise<void>;
|
|
89
|
+
/** Carry the conversation on the client from the first request (explicit_context). */
|
|
89
90
|
zeroDataRetention?: boolean;
|
|
91
|
+
/** The clock the trace's conversation record reads. Defaults to Date.now. */
|
|
92
|
+
now?: () => number;
|
|
90
93
|
/**
|
|
91
|
-
* Environment for the wire-capture gate (HUMANISH_CUA_WIRE_CAPTURE_DIR
|
|
94
|
+
* Environment for the wire-capture gate (HUMANISH_CUA_WIRE_CAPTURE_DIR; see the
|
|
92
95
|
* module header). Injectable so deterministic tests control the gate without
|
|
93
96
|
* mutating process.env. Defaults to process.env.
|
|
94
97
|
*/
|
|
@@ -100,7 +103,7 @@ export interface OpenAiResponsesProviderOptions {
|
|
|
100
103
|
* call outputs (with the latest screenshot) and thread state via
|
|
101
104
|
* previous_response_id, transparently falling back to explicit-context mode if
|
|
102
105
|
* the account rejects server-side retention. Transient HTTP failures are retried
|
|
103
|
-
* with exponential backoff. Returns
|
|
106
|
+
* with exponential backoff. Returns only a CuaTurn from nextTurn; nothing
|
|
104
107
|
* sensitive (the key, the request body, the screenshot, the raw response body)
|
|
105
108
|
* is ever returned or logged.
|
|
106
109
|
*/
|