@reticlehq/server 3.4.0 → 3.6.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/README.md +1 -1
- package/SKILL.md +16 -8
- package/dist/chromium-launch-options.d.ts +3 -1
- package/dist/chromium-launch-options.js +2 -1
- package/dist/command/cli/adhoc-verdict.d.ts +1 -0
- package/dist/command/cli/adhoc-verdict.js +6 -3
- package/dist/command/cli/answers/open-note.d.ts +2 -0
- package/dist/command/cli/answers/open-note.js +22 -0
- package/dist/command/cli/auth/cloud-session.d.ts +4 -4
- package/dist/command/cli/auth/device-flow.d.ts +2 -2
- package/dist/command/cli/cli-flow-commands.js +4 -8
- package/dist/command/cli/cli-parse.d.ts +1 -1
- package/dist/command/cli/cli-parse.js +13 -11
- package/dist/command/cli/cli-verify.d.ts +1 -1
- package/dist/command/cli/cli-verify.js +35 -25
- package/dist/command/cli/cloud-cli.js +110 -12
- package/dist/command/cli/cloud-login.d.ts +9 -1
- package/dist/command/cli/cloud-login.js +43 -8
- package/dist/command/cli/demo/demo-page.js +11 -3
- package/dist/command/cli/doctor/browser/chromium-hint.d.ts +46 -0
- package/dist/command/cli/doctor/browser/chromium-hint.js +99 -1
- package/dist/command/cli/drive/drive-attach.d.ts +27 -2
- package/dist/command/cli/drive/drive-attach.js +71 -4
- package/dist/command/cli/drive/drive-command.d.ts +2 -1
- package/dist/command/cli/drive/drive-command.js +13 -7
- package/dist/command/cli/lifecycle/daemon-lifecycle.js +4 -1
- package/dist/command/cli/ports/port-holder.d.ts +10 -0
- package/dist/command/cli/ports/port-holder.js +24 -0
- package/dist/command/cli/setup-mcp-cli.js +15 -5
- package/dist/command/cli/tutorial.d.ts +2 -2
- package/dist/command/cli/tutorial.js +6 -9
- package/dist/command/cli.d.ts +6 -0
- package/dist/command/cli.js +45 -23
- package/dist/command/daemon/binding/daemon-status-probe.d.ts +2 -0
- package/dist/command/daemon/binding/daemon-status-probe.js +1 -0
- package/dist/command/daemon/daemon-resolve.d.ts +14 -0
- package/dist/command/daemon/daemon-resolve.js +33 -2
- package/dist/command/setup/agent-writer.d.ts +1 -1
- package/dist/command/setup/agent-writer.js +3 -2
- package/dist/command/setup/bringup/connect-lease.d.ts +1 -0
- package/dist/command/setup/bringup/connect-lease.js +1 -0
- package/dist/command/setup/bringup/dev-server-wait.d.ts +10 -0
- package/dist/command/setup/bringup/dev-server-wait.js +20 -1
- package/dist/command/setup/init/init-port.d.ts +4 -0
- package/dist/command/setup/init/init-port.js +10 -0
- package/dist/command/setup/init/init-runtime.d.ts +10 -0
- package/dist/command/setup/init/init-runtime.js +71 -9
- package/dist/command/setup/node-effects.js +8 -2
- package/dist/command/setup/remaining-steps.js +2 -1
- package/dist/command/setup/run-setup.d.ts +7 -0
- package/dist/command/setup/run-setup.js +38 -25
- package/dist/command/setup/setup-command.d.ts +2 -1
- package/dist/command/setup/setup-command.js +2 -0
- package/dist/command/setup/setup-mcp.d.ts +2 -0
- package/dist/command/setup/setup-mcp.js +14 -5
- package/dist/command/version/peer-announce.d.ts +6 -2
- package/dist/command/version/peer-announce.js +8 -6
- package/dist/command/version/version-nudge.d.ts +17 -3
- package/dist/command/version/version-nudge.js +25 -4
- package/dist/command/version/version-skew.js +11 -2
- package/dist/features/crawl/crawl-tools.js +4 -0
- package/dist/features/crawl/crawl.d.ts +6 -0
- package/dist/features/crawl/crawl.js +9 -1
- package/dist/features/exhaust/ledger.d.ts +7 -0
- package/dist/features/exhaust/ledger.js +35 -9
- package/dist/features/harness/app-findings.d.ts +2 -0
- package/dist/features/harness/app-findings.js +52 -0
- package/dist/features/harness/drive-report.d.ts +27 -1
- package/dist/features/harness/drive-report.js +162 -11
- package/dist/features/harness/drivers.d.ts +10 -14
- package/dist/features/harness/drivers.js +10 -14
- package/dist/features/harness/fill-values.d.ts +3 -69
- package/dist/features/harness/fill-values.js +3 -133
- package/dist/features/harness/goals.d.ts +21 -0
- package/dist/features/harness/goals.js +77 -0
- package/dist/features/harness/harness.d.ts +21 -0
- package/dist/features/harness/harness.js +69 -2
- package/dist/features/harness/platform/drive-target.d.ts +30 -0
- package/dist/features/harness/platform/drive-target.js +81 -0
- package/dist/features/harness/platform/local-apps.d.ts +94 -0
- package/dist/features/harness/platform/local-apps.js +204 -0
- package/dist/features/harness/platform/remote-drive.d.ts +180 -0
- package/dist/features/harness/platform/remote-drive.js +365 -0
- package/dist/features/harness/platform/script.d.ts +48 -0
- package/dist/features/harness/platform/script.js +128 -0
- package/dist/features/harness/platform/server-driver.d.ts +41 -0
- package/dist/features/harness/platform/server-driver.js +179 -0
- package/dist/features/harness/platform-config.d.ts +7 -0
- package/dist/features/harness/platform-config.js +14 -2
- package/dist/features/harness/script/app-controls.d.ts +5 -0
- package/dist/features/harness/script/app-controls.js +40 -0
- package/dist/features/harness/script/lane-ids.d.ts +14 -0
- package/dist/features/harness/script/lane-ids.js +16 -0
- package/dist/features/harness/script/script-run.d.ts +41 -0
- package/dist/features/harness/script/script-run.js +299 -0
- package/dist/features/license/license.d.ts +2 -2
- package/dist/features/visual/visual-tools.d.ts +10 -1
- package/dist/features/visual/visual-tools.js +40 -3
- package/dist/hooks/driven-by.d.ts +4 -0
- package/dist/hooks/driven-by.js +16 -0
- package/dist/hooks/hook-commands.js +15 -4
- package/dist/hooks/tool-log.d.ts +9 -0
- package/dist/hooks/tool-log.js +29 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +91 -89
- package/dist/judgement/capsule/capsule-store.d.ts +4 -4
- package/dist/judgement/runs/artifact/build-verification-run.js +6 -0
- package/dist/judgement/runs/artifact/replay-mapping.d.ts +1 -1
- package/dist/judgement/runs/artifact/replay-mapping.js +16 -6
- package/dist/judgement/runs/artifact/run-store.d.ts +1 -1
- package/dist/judgement/runs/artifact/run-store.js +26 -1
- package/dist/judgement/runs/drive-run.d.ts +22 -0
- package/dist/judgement/runs/drive-run.js +99 -1
- package/dist/judgement/runs/repair-prompt.js +1 -1
- package/dist/judgement/runs/reticle-runner.js +8 -1
- package/dist/judgement/runs/verification-sync.d.ts +3 -2
- package/dist/judgement/runs/verification-sync.js +4 -3
- package/dist/language/flows/change/gate.d.ts +10 -0
- package/dist/language/flows/change/gate.js +22 -0
- package/dist/language/flows/decision.js +34 -0
- package/dist/language/flows/flow-anchor.d.ts +54 -8
- package/dist/language/flows/flow-anchor.js +88 -3
- package/dist/language/flows/flow-cross-step.d.ts +15 -0
- package/dist/language/flows/flow-cross-step.js +21 -0
- package/dist/language/flows/flow-learning.js +8 -11
- package/dist/language/flows/flow-mutate-tools.js +5 -3
- package/dist/language/flows/flow-replay-run.d.ts +23 -9
- package/dist/language/flows/flow-replay-run.js +101 -94
- package/dist/language/flows/flow-replay.d.ts +23 -1
- package/dist/language/flows/flow-replay.js +92 -19
- package/dist/language/flows/flow-scope.js +5 -1
- package/dist/language/flows/flow-step-runners.d.ts +20 -2
- package/dist/language/flows/flow-step-runners.js +236 -42
- package/dist/language/flows/flow-store-for-session.d.ts +2 -2
- package/dist/language/flows/flow-store-for-session.js +2 -2
- package/dist/language/flows/flow-tools.js +58 -34
- package/dist/language/flows/flows.js +5 -2
- package/dist/language/flows/heal-run.js +6 -4
- package/dist/language/flows/recording/flake.d.ts +2 -2
- package/dist/language/flows/recording/tape/recordings.d.ts +30 -4
- package/dist/language/flows/recording/tape/recordings.js +40 -8
- package/dist/language/flows/replay-from-hud.d.ts +20 -0
- package/dist/language/flows/replay-from-hud.js +51 -0
- package/dist/language/flows/replay.d.ts +9 -5
- package/dist/language/flows/replay.js +27 -9
- package/dist/language/flows/suite/suite-flakes.js +2 -0
- package/dist/language/flows/suite-selection.d.ts +2 -15
- package/dist/language/flows/suite-selection.js +4 -3
- package/dist/language/flows/verify-change-tools.js +8 -4
- package/dist/launch-chromium.d.ts +27 -5
- package/dist/launch-chromium.js +38 -8
- package/dist/memory/cloud/cloud-config.d.ts +12 -0
- package/dist/memory/cloud/cloud-config.js +15 -0
- package/dist/memory/cloud/cloud-sync.d.ts +17 -14
- package/dist/memory/cloud/cloud-sync.js +12 -1
- package/dist/memory/cloud/harness-config.d.ts +26 -1
- package/dist/memory/cloud/harness-config.js +99 -4
- package/dist/memory/cloud/hud-notices-source.d.ts +21 -0
- package/dist/memory/cloud/hud-notices-source.js +128 -0
- package/dist/memory/cloud/memory-scope.d.ts +144 -0
- package/dist/memory/cloud/memory-scope.js +205 -0
- package/dist/memory/cloud/sync-cycle.d.ts +21 -3
- package/dist/memory/cloud/sync-cycle.js +45 -5
- package/dist/memory/cloud/sync-daemon.js +7 -5
- package/dist/memory/cloud/sync-disk.d.ts +1 -1
- package/dist/memory/cloud/sync-disk.js +5 -8
- package/dist/memory/impact/account-watch.d.ts +19 -0
- package/dist/memory/impact/account-watch.js +34 -0
- package/dist/memory/impact/impact-recorder.d.ts +8 -0
- package/dist/memory/impact/impact-recorder.js +12 -2
- package/dist/memory/impact/impact-store.d.ts +16 -0
- package/dist/memory/impact/impact-store.js +142 -26
- package/dist/memory/intent/intent-shard.d.ts +2 -2
- package/dist/memory/intent/intent-tools.js +88 -5
- package/dist/memory/journal/envelope.d.ts +16 -16
- package/dist/memory/journal/journal-query.d.ts +14 -0
- package/dist/memory/journal/journal-query.js +15 -0
- package/dist/memory/journal/journal-recorder.js +7 -1
- package/dist/memory/journal/on-disk/retention.d.ts +3 -0
- package/dist/memory/journal/on-disk/retention.js +5 -0
- package/dist/memory/journal/on-disk/startup-maintenance.js +3 -1
- package/dist/memory/journal/on-disk/workspace-tiers.js +7 -4
- package/dist/memory/journal/session-end.js +6 -4
- package/dist/memory/project/artifact-root-resolver.d.ts +36 -1
- package/dist/memory/project/artifact-root-resolver.js +134 -26
- package/dist/memory/project/artifact-root.d.ts +42 -5
- package/dist/memory/project/artifact-root.js +87 -8
- package/dist/memory/project/dir/reticle-dir.d.ts +4 -2
- package/dist/memory/project/dir/reticle-dir.js +3 -1
- package/dist/memory/project/project-tools.js +22 -3
- package/dist/memory/project/session-root.d.ts +24 -1
- package/dist/memory/project/session-root.js +41 -5
- package/dist/memory/project/sync-status.d.ts +39 -0
- package/dist/memory/project/sync-status.js +90 -0
- package/dist/memory/recall/memory-tools.js +2 -0
- package/dist/memory/recall/project-memory.d.ts +19 -0
- package/dist/memory/recall/project-memory.js +45 -6
- package/dist/portal/bridge/bridge.d.ts +7 -4
- package/dist/portal/bridge/bridge.js +25 -3
- package/dist/portal/bridge/pairing-token.d.ts +9 -0
- package/dist/portal/bridge/pairing-token.js +17 -0
- package/dist/portal/input/real-input.d.ts +81 -10
- package/dist/portal/input/real-input.js +207 -22
- package/dist/portal/input/viewport-tools.js +19 -9
- package/dist/portal/pool/browser-pool.d.ts +22 -9
- package/dist/portal/pool/browser-pool.js +70 -35
- package/dist/portal/pool/playwright-launcher.d.ts +13 -0
- package/dist/portal/pool/playwright-launcher.js +17 -1
- package/dist/portal/pool/pool-contract.d.ts +7 -4
- package/dist/portal/session/command-payload.d.ts +8 -0
- package/dist/portal/session/command-payload.js +19 -0
- package/dist/portal/session/dev-server/dev-command.d.ts +12 -0
- package/dist/portal/session/dev-server/dev-command.js +61 -12
- package/dist/portal/session/facts/departure-note.d.ts +22 -0
- package/dist/portal/session/facts/departure-note.js +47 -0
- package/dist/portal/session/facts/session-replaced.d.ts +5 -0
- package/dist/portal/session/facts/session-replaced.js +5 -0
- package/dist/portal/session/first-run-wiring.d.ts +42 -0
- package/dist/portal/session/first-run-wiring.js +132 -0
- package/dist/portal/session/human/notes-ledger.d.ts +20 -0
- package/dist/portal/session/human/notes-ledger.js +55 -0
- package/dist/portal/session/human/review-store.d.ts +12 -0
- package/dist/portal/session/human/review-store.js +18 -10
- package/dist/portal/session/live-control-tools.d.ts +0 -13
- package/dist/portal/session/live-control-tools.js +28 -3
- package/dist/portal/session/no-session-diagnosis.d.ts +7 -0
- package/dist/portal/session/no-session-diagnosis.js +15 -0
- package/dist/portal/session/no-session-next-action.d.ts +11 -0
- package/dist/portal/session/no-session-next-action.js +31 -5
- package/dist/portal/session/no-session-watch.d.ts +14 -1
- package/dist/portal/session/no-session-watch.js +63 -10
- package/dist/portal/session/presence/session-mirror.js +3 -0
- package/dist/portal/session/serving-directory.d.ts +27 -0
- package/dist/portal/session/serving-directory.js +45 -0
- package/dist/portal/session/session-health.d.ts +7 -0
- package/dist/portal/session/session-health.js +6 -0
- package/dist/portal/session/session-info.d.ts +8 -1
- package/dist/portal/session/session-info.js +6 -0
- package/dist/portal/session/session-manager.d.ts +21 -0
- package/dist/portal/session/session-manager.js +44 -8
- package/dist/portal/session/session-reaper.js +4 -1
- package/dist/portal/session/session-successor.d.ts +5 -0
- package/dist/portal/session/session-tools.js +26 -3
- package/dist/portal/session/session.d.ts +12 -10
- package/dist/portal/session/session.js +30 -31
- package/dist/start-options.d.ts +6 -0
- package/dist/status-payload.d.ts +10 -0
- package/dist/status-payload.js +23 -0
- package/dist/surface/http-server.d.ts +1 -1
- package/dist/surface/http-server.js +15 -4
- package/dist/surface/mcp/mcp-proxy.d.ts +5 -0
- package/dist/surface/mcp/mcp-proxy.js +36 -5
- package/dist/surface/mcp/mcp.d.ts +11 -6
- package/dist/surface/mcp/mcp.js +28 -14
- package/dist/surface/mcp/proxy/proxy-log.js +3 -5
- package/dist/surface/mcp/server-instructions.d.ts +4 -2
- package/dist/surface/mcp/server-instructions.js +14 -4
- package/dist/surface/mcp/shared-params.js +2 -2
- package/dist/surface/tools/act/navigation/navigate-arrival.d.ts +8 -0
- package/dist/surface/tools/act/navigation/navigate-arrival.js +56 -2
- package/dist/surface/tools/act/settle-in-flight.js +25 -3
- package/dist/surface/tools/act-sequence-tool.js +2 -2
- package/dist/surface/tools/act-tools.js +25 -9
- package/dist/surface/tools/assert/assert-verdict.d.ts +1 -1
- package/dist/surface/tools/assert/assert-verdict.js +17 -2
- package/dist/surface/tools/browser-tools.js +8 -1
- package/dist/surface/tools/chat-drives.d.ts +26 -0
- package/dist/surface/tools/chat-drives.js +165 -0
- package/dist/surface/tools/dynamic-tools.js +29 -2
- package/dist/surface/tools/empty-session-list.d.ts +41 -0
- package/dist/surface/tools/empty-session-list.js +80 -0
- package/dist/surface/tools/error-recovery.d.ts +6 -0
- package/dist/surface/tools/error-recovery.js +38 -6
- package/dist/surface/tools/explore-tools.d.ts +10 -1
- package/dist/surface/tools/explore-tools.js +82 -13
- package/dist/surface/tools/feedback-tools.js +14 -0
- package/dist/surface/tools/harness-explore.d.ts +96 -14
- package/dist/surface/tools/harness-explore.js +227 -202
- package/dist/surface/tools/harness-plan.d.ts +12 -0
- package/dist/surface/tools/harness-plan.js +31 -0
- package/dist/surface/tools/harness-script.d.ts +8 -0
- package/dist/surface/tools/harness-script.js +342 -0
- package/dist/surface/tools/harness-toolset.d.ts +14 -1
- package/dist/surface/tools/harness-toolset.js +77 -6
- package/dist/surface/tools/invoke-tool.js +64 -9
- package/dist/surface/tools/lease-seed.d.ts +29 -0
- package/dist/surface/tools/lease-seed.js +123 -0
- package/dist/surface/tools/lease-tools.d.ts +3 -23
- package/dist/surface/tools/lease-tools.js +30 -131
- package/dist/surface/tools/live-call-text.js +2 -2
- package/dist/surface/tools/next-step.d.ts +19 -0
- package/dist/surface/tools/next-step.js +159 -0
- package/dist/surface/tools/observe-tools.js +2 -4
- package/dist/surface/tools/platform-moment.d.ts +12 -0
- package/dist/surface/tools/platform-moment.js +168 -0
- package/dist/surface/tools/query-hint-schema.d.ts +7 -0
- package/dist/surface/tools/query-hint-schema.js +10 -0
- package/dist/surface/tools/read-tools.js +8 -2
- package/dist/surface/tools/real-input-attempt.js +96 -13
- package/dist/surface/tools/tool-kit.d.ts +25 -1
- package/dist/surface/tools/tool-kit.js +4 -6
- package/dist/surface/tools/tools.js +20 -48
- package/dist/telemetry/argument-shape.js +1 -1
- package/dist/telemetry/hud-metrics.d.ts +2 -0
- package/dist/telemetry/hud-metrics.js +17 -0
- package/dist/telemetry/onboarding-firsts.d.ts +2 -2
- package/dist/telemetry/onboarding-firsts.js +2 -2
- package/dist/telemetry/telemetry.d.ts +12 -0
- package/dist/telemetry/telemetry.js +43 -14
- package/dist/telemetry/verification-of.js +1 -0
- package/dist/wire-journal.js +4 -1
- package/docs/README.md +1 -1
- package/docs/actions.mdx +1 -2
- package/docs/agent-cheatsheet.md +1 -1
- package/docs/autodrive.md +29 -25
- package/docs/cli/cloud.mdx +6 -4
- package/docs/cli/doctor.mdx +6 -0
- package/docs/cli/drive.mdx +8 -2
- package/docs/cli/init.mdx +11 -13
- package/docs/cli/status.mdx +5 -1
- package/docs/cli/version.mdx +3 -3
- package/docs/cli.mdx +14 -8
- package/docs/desktop.mdx +5 -1
- package/docs/environment.mdx +3 -7
- package/docs/getting-started.md +14 -2
- package/docs/human-control.md +1 -2
- package/docs/index.mdx +4 -3
- package/docs/install-agentic.mdx +1 -1
- package/docs/install-manual.mdx +2 -2
- package/docs/packages/next.mdx +3 -0
- package/docs/packages/tauri.mdx +2 -2
- package/docs/packages/vite-plugin.mdx +24 -1
- package/docs/packages.mdx +1 -1
- package/docs/quickstart.mdx +23 -11
- package/docs/telemetry.md +1 -1
- package/docs/tools/act.mdx +1 -1
- package/docs/tools/session-and-feedback.mdx +9 -9
- package/docs/usage.md +5 -3
- package/docs/what-is-recorded.md +13 -3
- package/docs/what-is-reticle.mdx +3 -1
- package/package.json +8 -12
- package/dist/features/harness/driver.d.ts +0 -50
- package/dist/features/harness/driver.js +0 -236
- package/dist/features/harness/jev-driver.d.ts +0 -188
- package/dist/features/harness/jev-driver.js +0 -678
- package/dist/features/harness/openai-driver.d.ts +0 -46
- package/dist/features/harness/openai-driver.js +0 -194
- package/dist/memory/project/dir/fill-value-store.d.ts +0 -32
- package/dist/memory/project/dir/fill-value-store.js +0 -88
- package/docs/local-registry.md +0 -143
|
@@ -1,236 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The model binding: the one file in the harness that knows there is a network.
|
|
3
|
-
*
|
|
4
|
-
* Everything about the loop lives in harness.ts against the `ModelDriver` interface, so this file is
|
|
5
|
-
* a translation layer and nothing else. That split is not tidiness — it is what lets the loop be
|
|
6
|
-
* tested against a scripted model with no API key, on every run of the unit gate.
|
|
7
|
-
*
|
|
8
|
-
* It speaks the Messages API over `fetch` rather than through a vendor SDK. The loop is ours (the
|
|
9
|
-
* harness owns the step budget and has to record every call even when a run is cut short), so an SDK
|
|
10
|
-
* would contribute one HTTP POST and a dependency — and this package's dependency list is short on
|
|
11
|
-
* purpose.
|
|
12
|
-
*/
|
|
13
|
-
import { z } from 'zod';
|
|
14
|
-
import { ReticleEnv, platformCredentialFrom } from '@reticlehq/core';
|
|
15
|
-
/**
|
|
16
|
-
* The default driver model.
|
|
17
|
-
*
|
|
18
|
-
* Deliberately not the largest model available. The harness is not reasoning about business logic; it
|
|
19
|
-
* is exploring an interface and stating consequences, and the verdict is produced by the engine
|
|
20
|
-
* reading what it drove. If finding defects required a frontier model HERE, the engine would not be
|
|
21
|
-
* doing its job — so the model tier is also a standing test of the design.
|
|
22
|
-
*/
|
|
23
|
-
export const DEFAULT_HARNESS_MODEL = 'claude-sonnet-5';
|
|
24
|
-
export const DEFAULT_HARNESS_BASE_URL = 'https://api.anthropic.com';
|
|
25
|
-
/** Output cap per turn. A driving turn is a sentence and a tool call, never an essay. */
|
|
26
|
-
const MAX_TOKENS = 4096;
|
|
27
|
-
const ANTHROPIC_VERSION = '2023-06-01';
|
|
28
|
-
const MESSAGES_PATH = '/v1/messages';
|
|
29
|
-
/**
|
|
30
|
-
* How much of one tool result the model is allowed to see.
|
|
31
|
-
*
|
|
32
|
-
* A snapshot of a dense page or a network window on a busy app is far larger than anything the model
|
|
33
|
-
* needs to choose its next click, and a handful of them will fill a context window that then has to
|
|
34
|
-
* be paid for on every subsequent turn. Truncation is announced in the payload rather than silent,
|
|
35
|
-
* because a model that cannot tell it was given a partial reading will reason about it as a complete
|
|
36
|
-
* one — and the tools already have cheaper lenses (`count_only`, `interactive`, `diff`) for exactly
|
|
37
|
-
* this. The full result is in the journal either way; nothing is lost from the record.
|
|
38
|
-
*/
|
|
39
|
-
const MAX_RESULT_CHARS = 8000;
|
|
40
|
-
/** The cache breakpoint marker. One object, because it is the same fact in three places. */
|
|
41
|
-
const CACHE_BREAKPOINT = { type: 'ephemeral' };
|
|
42
|
-
/** What one turn of the wire looks like, narrowed at the boundary rather than trusted. */
|
|
43
|
-
const TextBlock = z.object({ type: z.literal('text'), text: z.string() });
|
|
44
|
-
const ToolUseBlock = z.object({
|
|
45
|
-
type: z.literal('tool_use'),
|
|
46
|
-
id: z.string(),
|
|
47
|
-
name: z.string(),
|
|
48
|
-
input: z.unknown(),
|
|
49
|
-
});
|
|
50
|
-
const OtherBlock = z.object({ type: z.string() }).passthrough();
|
|
51
|
-
const MessageResponse = z.object({
|
|
52
|
-
content: z.array(z.union([TextBlock, ToolUseBlock, OtherBlock])).default([]),
|
|
53
|
-
usage: z
|
|
54
|
-
.object({
|
|
55
|
-
input_tokens: z.number().default(0),
|
|
56
|
-
output_tokens: z.number().default(0),
|
|
57
|
-
cache_read_input_tokens: z.number().nullish(),
|
|
58
|
-
cache_creation_input_tokens: z.number().nullish(),
|
|
59
|
-
})
|
|
60
|
-
.default({ input_tokens: 0, output_tokens: 0 }),
|
|
61
|
-
});
|
|
62
|
-
/**
|
|
63
|
-
* Read the harness's configuration out of the environment.
|
|
64
|
-
*
|
|
65
|
-
* Returns `undefined` when there is no key, which is the ONLY thing that decides whether the harness
|
|
66
|
-
* is available. Stated as a read rather than a throw because "you have not configured this" is a
|
|
67
|
-
* routine answer a caller offers a way out of, not a failure.
|
|
68
|
-
*/
|
|
69
|
-
export function harnessOptionsFromEnv(env) {
|
|
70
|
-
const model = env[ReticleEnv.HARNESS_MODEL];
|
|
71
|
-
const baseUrl = env[ReticleEnv.HARNESS_BASE_URL];
|
|
72
|
-
const withOptions = (apiKey, fallbackUrl) => {
|
|
73
|
-
const url = baseUrl === undefined || 0 === baseUrl.length ? fallbackUrl : baseUrl;
|
|
74
|
-
return {
|
|
75
|
-
apiKey,
|
|
76
|
-
...(model === undefined || 0 === model.length ? {} : { model }),
|
|
77
|
-
...(url === undefined || 0 === url.length ? {} : { baseUrl: url }),
|
|
78
|
-
};
|
|
79
|
-
};
|
|
80
|
-
const apiKey = env[ReticleEnv.HARNESS_KEY];
|
|
81
|
-
if (apiKey !== undefined && 0 < apiKey.length)
|
|
82
|
-
return withOptions(apiKey);
|
|
83
|
-
/**
|
|
84
|
-
* The platform key, against the platform.
|
|
85
|
-
*
|
|
86
|
-
* Reticle's own service answers the Messages API at `/v1/messages` and forwards with ITS provider
|
|
87
|
-
* key, so a user who has run `reticle link` can drive with a frontier model having never held an
|
|
88
|
-
* Anthropic key at all. Without this they would be told to set `ANTHROPIC_API_KEY` to a value
|
|
89
|
-
* beginning `rk_live_` — which works, and reads like a mistake, and is the sort of instruction
|
|
90
|
-
* people correct on the way past and then cannot explain why nothing runs.
|
|
91
|
-
*
|
|
92
|
-
* An explicit `ANTHROPIC_API_KEY` still wins: someone who exported one meant it.
|
|
93
|
-
*/
|
|
94
|
-
const cloud = platformCredentialFrom(env);
|
|
95
|
-
if (cloud === undefined)
|
|
96
|
-
return undefined;
|
|
97
|
-
return withOptions(cloud.apiKey, cloud.url);
|
|
98
|
-
}
|
|
99
|
-
/** Build a driver backed by the Messages API. */
|
|
100
|
-
export function harnessDriver(options) {
|
|
101
|
-
const model = options.model ?? DEFAULT_HARNESS_MODEL;
|
|
102
|
-
const baseUrl = options.baseUrl ?? DEFAULT_HARNESS_BASE_URL;
|
|
103
|
-
const call = options.fetch ?? ((url, init) => fetch(url, init));
|
|
104
|
-
return {
|
|
105
|
-
async turn({ system, tools, history }) {
|
|
106
|
-
const response = await call(`${baseUrl}${MESSAGES_PATH}`, {
|
|
107
|
-
method: 'POST',
|
|
108
|
-
headers: {
|
|
109
|
-
'content-type': 'application/json',
|
|
110
|
-
'x-api-key': options.apiKey,
|
|
111
|
-
'anthropic-version': ANTHROPIC_VERSION,
|
|
112
|
-
},
|
|
113
|
-
body: JSON.stringify({
|
|
114
|
-
model,
|
|
115
|
-
max_tokens: MAX_TOKENS,
|
|
116
|
-
system: [
|
|
117
|
-
{
|
|
118
|
-
type: 'text',
|
|
119
|
-
text: system,
|
|
120
|
-
// The system prompt and the tool list are byte-identical on every turn of a drive, and
|
|
121
|
-
// a drive is dozens of turns. Caching the prefix is most of the cost of driving an app.
|
|
122
|
-
cache_control: CACHE_BREAKPOINT,
|
|
123
|
-
},
|
|
124
|
-
],
|
|
125
|
-
tools: tools.map(toWireTool),
|
|
126
|
-
messages: withConversationCache(history.map(toWireMessage)),
|
|
127
|
-
}),
|
|
128
|
-
});
|
|
129
|
-
const body = await response.text();
|
|
130
|
-
if (!response.ok) {
|
|
131
|
-
// Thrown, not returned: the loop calls a model that will not answer a BROKEN drive, and a
|
|
132
|
-
// broken drive is never reported as clean. Swallowing this would be a verdict about an app
|
|
133
|
-
// nobody drove.
|
|
134
|
-
throw new Error(`the model refused the request (HTTP ${String(response.status)}): ${body}`);
|
|
135
|
-
}
|
|
136
|
-
const parsed = MessageResponse.parse(JSON.parse(body));
|
|
137
|
-
const text = parsed.content
|
|
138
|
-
.filter((block) => 'text' === block.type)
|
|
139
|
-
.map((block) => block.text)
|
|
140
|
-
.join('\n');
|
|
141
|
-
const calls = parsed.content
|
|
142
|
-
.filter((block) => 'tool_use' === block.type)
|
|
143
|
-
.map((block) => ({
|
|
144
|
-
id: block.id,
|
|
145
|
-
name: block.name,
|
|
146
|
-
args: isRecord(block.input) ? block.input : {},
|
|
147
|
-
}));
|
|
148
|
-
return {
|
|
149
|
-
text,
|
|
150
|
-
calls,
|
|
151
|
-
usage: {
|
|
152
|
-
input: parsed.usage.input_tokens,
|
|
153
|
-
output: parsed.usage.output_tokens,
|
|
154
|
-
// Reported so a missed cache is VISIBLE. A breakpoint that silently stops matching costs
|
|
155
|
-
// full price and looks exactly like one that is working from every other angle.
|
|
156
|
-
cacheRead: parsed.usage.cache_read_input_tokens ?? 0,
|
|
157
|
-
cacheWrite: parsed.usage.cache_creation_input_tokens ?? 0,
|
|
158
|
-
},
|
|
159
|
-
};
|
|
160
|
-
},
|
|
161
|
-
};
|
|
162
|
-
}
|
|
163
|
-
/**
|
|
164
|
-
* Cache the conversation so far, so the next turn does not pay to re-read it.
|
|
165
|
-
*
|
|
166
|
-
* The API is stateless: every turn re-sends the whole conversation, and a drive is dozens of turns.
|
|
167
|
-
* The system prompt and the tool list are already cached from the first turn — but those are the half
|
|
168
|
-
* that does not grow. The messages are the half that does, and without a breakpoint every byte of
|
|
169
|
-
* them is processed again at full price on every single turn.
|
|
170
|
-
*
|
|
171
|
-
* ONE breakpoint, on the last content block of the most-recently-appended turn. Next turn, this
|
|
172
|
-
* entire conversation is the request's prefix, so it is read at roughly a tenth of the input price
|
|
173
|
-
* rather than processed again. Earlier entries stay valid read points, so the saving accrues as the
|
|
174
|
-
* conversation grows — which is exactly the shape of the cost.
|
|
175
|
-
*
|
|
176
|
-
* Not several breakpoints: four is the hard limit per request and the system block already spends
|
|
177
|
-
* one. More here would buy nothing, because the lookup from a later breakpoint already finds the
|
|
178
|
-
* earlier turn's entry as its prefix.
|
|
179
|
-
*
|
|
180
|
-
* The one thing that would break it is a single turn adding more than twenty content blocks — the
|
|
181
|
-
* lookback window is twenty, and a breakpoint that cannot see the previous entry silently misses. A
|
|
182
|
-
* turn here is one text block, N tool_use blocks and N tool_result blocks, so it would take ten
|
|
183
|
-
* parallel calls in one turn to reach that. Worth knowing; not worth a second breakpoint until it
|
|
184
|
-
* happens, and the cache-read count in `usage` is where it would show up.
|
|
185
|
-
*/
|
|
186
|
-
function withConversationCache(messages) {
|
|
187
|
-
const last = messages[messages.length - 1];
|
|
188
|
-
if (last === undefined)
|
|
189
|
-
return [...messages];
|
|
190
|
-
const content = last.content.map((block, index) => index === last.content.length - 1 ? { ...block, cache_control: CACHE_BREAKPOINT } : block);
|
|
191
|
-
return [...messages.slice(0, -1), { ...last, content }];
|
|
192
|
-
}
|
|
193
|
-
function toWireTool(tool) {
|
|
194
|
-
return {
|
|
195
|
-
name: tool.name,
|
|
196
|
-
description: tool.description,
|
|
197
|
-
input_schema: tool.inputSchema,
|
|
198
|
-
};
|
|
199
|
-
}
|
|
200
|
-
function toWireMessage(entry) {
|
|
201
|
-
if ('user' === entry.role) {
|
|
202
|
-
// A text BLOCK rather than a bare string: only a block can carry a cache breakpoint, and the
|
|
203
|
-
// opening message is the one that would otherwise be a string. It changes the billing and
|
|
204
|
-
// nothing the model reads.
|
|
205
|
-
return { role: 'user', content: [{ type: 'text', text: entry.text }] };
|
|
206
|
-
}
|
|
207
|
-
if ('assistant' === entry.role) {
|
|
208
|
-
const blocks = [];
|
|
209
|
-
if (entry.text.length > 0)
|
|
210
|
-
blocks.push({ type: 'text', text: entry.text });
|
|
211
|
-
for (const call of entry.calls) {
|
|
212
|
-
blocks.push({ type: 'tool_use', id: call.id, name: call.name, input: call.args });
|
|
213
|
-
}
|
|
214
|
-
return { role: 'assistant', content: blocks };
|
|
215
|
-
}
|
|
216
|
-
// Every outcome goes back in ONE user message. Splitting tool results across messages teaches the
|
|
217
|
-
// model to stop asking for calls in parallel, which is most of what makes a drive fast.
|
|
218
|
-
return {
|
|
219
|
-
role: 'user',
|
|
220
|
-
content: entry.outcomes.map((outcome) => ({
|
|
221
|
-
type: 'tool_result',
|
|
222
|
-
tool_use_id: outcome.id,
|
|
223
|
-
content: truncate(JSON.stringify(outcome.result ?? null)),
|
|
224
|
-
is_error: outcome.isError,
|
|
225
|
-
})),
|
|
226
|
-
};
|
|
227
|
-
}
|
|
228
|
-
function truncate(text) {
|
|
229
|
-
if (text.length <= MAX_RESULT_CHARS)
|
|
230
|
-
return text;
|
|
231
|
-
const dropped = String(text.length - MAX_RESULT_CHARS);
|
|
232
|
-
return `${text.slice(0, MAX_RESULT_CHARS)}\n…[truncated ${dropped} characters — ask for a narrower lens (count_only, interactive, diff, or a path) if you need the rest]`;
|
|
233
|
-
}
|
|
234
|
-
function isRecord(value) {
|
|
235
|
-
return 'object' === typeof value && null !== value && !Array.isArray(value);
|
|
236
|
-
}
|
|
@@ -1,188 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* A harness driver with no text generator in it.
|
|
3
|
-
*
|
|
4
|
-
* `driver.ts` binds the harness to a frontier model, and the comment at the top of it has always
|
|
5
|
-
* claimed the tier is "a standing test of the design": the driver is not reasoning about business
|
|
6
|
-
* logic, it is choosing what to touch next and saying what it expects, and if that needed a large
|
|
7
|
-
* model then the engine would not be doing its job. Nothing tested the claim, because the only
|
|
8
|
-
* driver in the repo was a large model.
|
|
9
|
-
*
|
|
10
|
-
* This is the test. Jev is a System One model — it evaluates typed questions against a state and
|
|
11
|
-
* answers with probabilities, in one parallel pass, and it does not emit prose. It therefore cannot
|
|
12
|
-
* invent a tool call. So every call this driver makes is built HERE, deterministically, out of what
|
|
13
|
-
* the page actually offers, and the model's only contribution is picking one of them. That is a
|
|
14
|
-
* strictly smaller surface than a generating driver has, and it is the whole reason this is worth
|
|
15
|
-
* having: a driver that cannot name an element that is not on the page cannot hallucinate one.
|
|
16
|
-
*
|
|
17
|
-
* What did NOT move: the verdict. `decideVerified` still decides, on evidence, with no model in it.
|
|
18
|
-
* A System One model cannot hallucinate a type, but it still returns a PROBABILITY, and a
|
|
19
|
-
* probability is not proof. Anyone reading this file as an invitation to let Jev answer
|
|
20
|
-
* "did it work?" should read `engine/src/evidence/verified.ts` first — the seventeen clauses there
|
|
21
|
-
* exist because this product is the verdict, and a verdict sourced from a model's confidence is the
|
|
22
|
-
* thing Reticle sells the absence of.
|
|
23
|
-
*/
|
|
24
|
-
import type { ModelDriver } from './harness.js';
|
|
25
|
-
import type { HarnessFetch } from './driver.js';
|
|
26
|
-
export declare const DEFAULT_JEV_MODEL = "jev-latest";
|
|
27
|
-
export declare const DEFAULT_JEV_BASE_URL = "https://api.typesafe.ai";
|
|
28
|
-
/**
|
|
29
|
-
* The consequences the driver can declare, and the predicate each one becomes.
|
|
30
|
-
*
|
|
31
|
-
* Declaring one is not optional decoration — it is the difference between a drive and a click. The
|
|
32
|
-
* first version of this driver emitted `act_and_wait` with no `until` at all, and the engine said
|
|
33
|
-
* so in every single result: "the page settled and no channel reported a problem, but nothing was
|
|
34
|
-
* declared to prove — this is not verification". Six actions, zero proved. A flow recorded from that
|
|
35
|
-
* drive passes even when the feature is broken, which is the exact failure this product exists to
|
|
36
|
-
* catch, sitting inside the thing meant to catch it.
|
|
37
|
-
*
|
|
38
|
-
* Every predicate here is BARE — a kind with no specifics — because before acting the driver does
|
|
39
|
-
* not know which endpoint, signal or route to expect. Bare is still consequence-grade evidence: it
|
|
40
|
-
* asserts the app's own machinery moved, which a presence check on screen text does not.
|
|
41
|
-
*
|
|
42
|
-
* Only SIGNAL and NET can be declared bare, and that is a fact about the engine rather than a
|
|
43
|
-
* preference. `engine/src/evidence/already-true.ts` lists the kinds that read live state — element,
|
|
44
|
-
* text, route and state — and those are checked BEFORE the action as well as after, precisely so a
|
|
45
|
-
* condition that already held cannot be sold as something the action caused. A bare predicate of
|
|
46
|
-
* one of those kinds is unconditionally true: there is always a current route, and there is always
|
|
47
|
-
* some store. That file says so in as many words at its `ROUTE` case.
|
|
48
|
-
*
|
|
49
|
-
* This driver tried all four anyway and the engine refused all four, every time, with
|
|
50
|
-
* `already_true` — "the declared consequence was already true before this action, so it proves
|
|
51
|
-
* nothing about it". Signal and net are event-based and floored at the act's own cursor, so they
|
|
52
|
-
* cannot be answered by the past, which is exactly what makes them safe to declare with no
|
|
53
|
-
* specifics. Route and state come back the moment the driver can name a pathname or a store path
|
|
54
|
-
* instead of a bare kind, and they are the stronger evidence when it can.
|
|
55
|
-
*
|
|
56
|
-
* `anyOf` is not a loophole: it reports as live-reading if ANY branch does, so it holds only the
|
|
57
|
-
* two safe kinds for the same reason.
|
|
58
|
-
*
|
|
59
|
-
* ponytail: bare `net` can in principle be satisfied by unrelated traffic inside the action's
|
|
60
|
-
* window — a page polling every second would answer for a button that did nothing. The window is
|
|
61
|
-
* the action's own, not "ever", so the exposure is small but real. The upgrade is to learn the
|
|
62
|
-
* app's vocabulary first (one `reticle_observe` early in the drive gives the actual signal names
|
|
63
|
-
* and endpoint paths) and declare `urlContains`/`name` instead of a bare kind. Until then `state`
|
|
64
|
-
* and `signal` are the trustworthy ones and `net` is the one to distrust on a chatty app.
|
|
65
|
-
*/
|
|
66
|
-
export interface Consequence {
|
|
67
|
-
predicate: Record<string, unknown>;
|
|
68
|
-
describes: string;
|
|
69
|
-
/**
|
|
70
|
-
* Whether a SAVED FLOW can carry this claim, which is a different question from whether the drive
|
|
71
|
-
* can prove it.
|
|
72
|
-
*
|
|
73
|
-
* A recorded step keeps an expectation only in the forms a replay can re-check, and that filter
|
|
74
|
-
* refuses every unbound kind: `signal "export:generated"` survives, a bare "some signal fires"
|
|
75
|
-
* does not; `net { method: "POST" }` survives, a bare "some request happens" does not; `not` and
|
|
76
|
-
* `anyOf` have no representation at all.
|
|
77
|
-
*
|
|
78
|
-
* Measured on a real dashboard before this field existed: every one of the four consequences on
|
|
79
|
-
* offer was unbound, so 0 of 22 steps across 16 machine-driven flows recorded a single
|
|
80
|
-
* expectation, against 211 of 419 in the hand-authored flows beside them. The drive proved things
|
|
81
|
-
* and then saved flows that had forgotten all of it. Since a flow is meant to BE the regression
|
|
82
|
-
* suite, that is the product's own claim failing at its last step: those flows can only ever
|
|
83
|
-
* catch "the click stopped landing", never "the feature broke".
|
|
84
|
-
*/
|
|
85
|
-
recordable: boolean;
|
|
86
|
-
}
|
|
87
|
-
/**
|
|
88
|
-
* The app's own route, with Reticle's fingerprints wiped off it.
|
|
89
|
-
*
|
|
90
|
-
* A pooled launcher appends `__reticle_opened=1` to the URL it opens, and that parameter ended up
|
|
91
|
-
* inside a declared consequence: "this click leaves a route containing /?__reticle_opened=1". On a
|
|
92
|
-
* hash-routed app that claim can never hold, because the query string never changes -- only the
|
|
93
|
-
* fragment does -- so every navigation link was a guaranteed red, and the red was about OUR query
|
|
94
|
-
* parameter rather than about the application. Found by making a failed action say what it claimed;
|
|
95
|
-
* before that it read as an ordinary "the declared consequence did not hold".
|
|
96
|
-
*
|
|
97
|
-
* The fragment is kept, and is the point: on a hash-routed app it is the only part that moves.
|
|
98
|
-
*/
|
|
99
|
-
export declare function appRoute(route: string): string;
|
|
100
|
-
/**
|
|
101
|
-
* The consequences on offer, given where the app currently is and what it says it can do.
|
|
102
|
-
*
|
|
103
|
-
* Two things shape this list, and the second one was missing for a whole release.
|
|
104
|
-
*
|
|
105
|
-
* It is a function of the CURRENT ROUTE, because "this takes us off the page we are on" is only
|
|
106
|
-
* falsifiable against a route actually read.
|
|
107
|
-
*
|
|
108
|
-
* It is also a function of the app's OWN VOCABULARY, because an unbound claim cannot be saved. A
|
|
109
|
-
* drive that declares "some signal fires" proves something real at the time and writes a flow that
|
|
110
|
-
* asserts nothing, so every later replay passes as long as the clicks still land. Offering the
|
|
111
|
-
* declared signal NAMES turns the same choice into one a flow can keep, and costs nothing extra:
|
|
112
|
-
* the names are already read out of `.reticle` to build the plan.
|
|
113
|
-
*/
|
|
114
|
-
export declare function consequencesFor(route: string | undefined, vocabulary?: readonly string[]): Record<string, Consequence>;
|
|
115
|
-
/**
|
|
116
|
-
* One step of the plan the caller built from `.reticle`.
|
|
117
|
-
*
|
|
118
|
-
* Structural rather than imported: this package is a SINK — it is handed a toolset and a driver and
|
|
119
|
-
* reaches into nothing — so the plan arrives as data with the shape it needs and no dependency on
|
|
120
|
-
* where it was built.
|
|
121
|
-
*/
|
|
122
|
-
export interface DrivePlanStep {
|
|
123
|
-
/** `replay` for a journey already recorded, `drive` for declared intent nobody has proved. */
|
|
124
|
-
kind: string;
|
|
125
|
-
/** The flow to replay, or the signal/control a drive step is aimed at. */
|
|
126
|
-
target: string;
|
|
127
|
-
/** Why this step is worth taking, in the project's own words. */
|
|
128
|
-
why: string;
|
|
129
|
-
}
|
|
130
|
-
export interface JevDriverOptions {
|
|
131
|
-
apiKey: string;
|
|
132
|
-
model?: string;
|
|
133
|
-
baseUrl?: string;
|
|
134
|
-
/**
|
|
135
|
-
* The loop's step budget, so the driver can stop exploring in time to save what it drove.
|
|
136
|
-
*
|
|
137
|
-
* The loop does not tell a driver how much budget is left — it does not have to, because a
|
|
138
|
-
* generating model is expected to call `finish` when it is ready. This driver has a teardown it
|
|
139
|
-
* must reach, so it needs the number. Absent ⇒ no reserve, and a run that ends on BUDGET keeps
|
|
140
|
-
* nothing, which is why every caller inside the repo passes it.
|
|
141
|
-
*/
|
|
142
|
-
maxSteps?: number;
|
|
143
|
-
/**
|
|
144
|
-
* What this drive is FOR, read from `.reticle` before it started.
|
|
145
|
-
*
|
|
146
|
-
* Replay steps run FIRST and deterministically, with no model call at all — a journey already on
|
|
147
|
-
* disk must never be re-driven, which is the whole reason the plan exists. Only once they are
|
|
148
|
-
* done is the model asked anything, and then it is asked against the intent these steps carry
|
|
149
|
-
* rather than against whatever happens to be on the page.
|
|
150
|
-
*/
|
|
151
|
-
plan?: readonly DrivePlanStep[];
|
|
152
|
-
/**
|
|
153
|
-
* The signal names the app declares, untested ones first, read out of `.reticle` with the plan.
|
|
154
|
-
*
|
|
155
|
-
* Offered as consequences so a declaration can name something. Absent is not a failure: the
|
|
156
|
-
* method-bound network consequences are still recordable, and an app that declares no signals is
|
|
157
|
-
* simply an app with less to claim.
|
|
158
|
-
*/
|
|
159
|
-
vocabulary?: readonly string[];
|
|
160
|
-
/**
|
|
161
|
-
* What to type into a text field, when the label alone is not enough to guess.
|
|
162
|
-
*
|
|
163
|
-
* The one place a drive is a COMPOSITION rather than a decision, and therefore the one place worth
|
|
164
|
-
* paying a generating model for. Absent ⇒ the label heuristic answers, which is what every drive
|
|
165
|
-
* did before this seam existed; a drive with no text fields never reaches it either way. See
|
|
166
|
-
* `fill-values.ts` for why it is escalation rather than a second model in the loop.
|
|
167
|
-
*/
|
|
168
|
-
fillValue?: (label: string) => Promise<string>;
|
|
169
|
-
/** Injected for tests. Defaults to the platform `fetch`. */
|
|
170
|
-
fetch?: HarnessFetch;
|
|
171
|
-
}
|
|
172
|
-
/**
|
|
173
|
-
* Read this driver's configuration out of the environment.
|
|
174
|
-
*
|
|
175
|
-
* A direct Jev key wins over the platform key, so that someone debugging the upstream is never
|
|
176
|
-
* quietly talking to the proxy they were trying to bypass. Returns `undefined` when neither is set,
|
|
177
|
-
* which is a routine answer and not a failure — the caller falls back to the Anthropic driver.
|
|
178
|
-
*/
|
|
179
|
-
export declare function jevOptionsFromEnv(env: Record<string, string | undefined>): JevDriverOptions | undefined;
|
|
180
|
-
/**
|
|
181
|
-
* Build a driver backed by a System One model.
|
|
182
|
-
*
|
|
183
|
-
* Every turn emits exactly ONE call. The loop dispatches a turn's calls with `Promise.all`, so an
|
|
184
|
-
* act and the snapshot that reads its result cannot be batched into one turn — they would race, and
|
|
185
|
-
* the snapshot would describe a page mid-flight. One call per turn costs a step and buys a reading
|
|
186
|
-
* that is actually of the page the action produced.
|
|
187
|
-
*/
|
|
188
|
-
export declare function jevDriver(options: JevDriverOptions): ModelDriver;
|