@tangle-network/browser-agent-driver 0.33.3 → 0.34.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 +42 -1
- package/discovery/llms.txt +27 -0
- package/discovery/tangle-agent.json +36 -0
- package/dist/brain/action-parse.d.ts +16 -0
- package/dist/brain/action-parse.d.ts.map +1 -0
- package/dist/brain/action-parse.js +191 -0
- package/dist/brain/action-parse.js.map +1 -0
- package/dist/brain/decide.d.ts +58 -0
- package/dist/brain/decide.d.ts.map +1 -0
- package/dist/brain/decide.js +418 -0
- package/dist/brain/decide.js.map +1 -0
- package/dist/brain/history-compact.d.ts +19 -0
- package/dist/brain/history-compact.d.ts.map +1 -0
- package/dist/brain/history-compact.js +153 -0
- package/dist/brain/history-compact.js.map +1 -0
- package/dist/brain/index.d.ts +78 -152
- package/dist/brain/index.d.ts.map +1 -1
- package/dist/brain/index.js +62 -2268
- package/dist/brain/index.js.map +1 -1
- package/dist/brain/model-client.d.ts +101 -0
- package/dist/brain/model-client.d.ts.map +1 -0
- package/dist/brain/model-client.js +391 -0
- package/dist/brain/model-client.js.map +1 -0
- package/dist/brain/plan.d.ts +57 -0
- package/dist/brain/plan.d.ts.map +1 -0
- package/dist/brain/plan.js +194 -0
- package/dist/brain/plan.js.map +1 -0
- package/dist/brain/prompts.d.ts +37 -0
- package/dist/brain/prompts.d.ts.map +1 -0
- package/dist/brain/prompts.js +455 -0
- package/dist/brain/prompts.js.map +1 -0
- package/dist/brain/provider-fetch.d.ts +26 -0
- package/dist/brain/provider-fetch.d.ts.map +1 -0
- package/dist/brain/provider-fetch.js +45 -0
- package/dist/brain/provider-fetch.js.map +1 -0
- package/dist/brain/snapshot-budget.d.ts +20 -0
- package/dist/brain/snapshot-budget.d.ts.map +1 -0
- package/dist/brain/snapshot-budget.js +202 -0
- package/dist/brain/snapshot-budget.js.map +1 -0
- package/dist/brain/system-prompt.d.ts +67 -0
- package/dist/brain/system-prompt.d.ts.map +1 -0
- package/dist/brain/system-prompt.js +128 -0
- package/dist/brain/system-prompt.js.map +1 -0
- package/dist/brain/tasks/design-audit.d.ts +33 -0
- package/dist/brain/tasks/design-audit.d.ts.map +1 -0
- package/dist/brain/tasks/design-audit.js +100 -0
- package/dist/brain/tasks/design-audit.js.map +1 -0
- package/dist/brain/tasks/evaluate.d.ts +25 -0
- package/dist/brain/tasks/evaluate.d.ts.map +1 -0
- package/dist/brain/tasks/evaluate.js +55 -0
- package/dist/brain/tasks/evaluate.js.map +1 -0
- package/dist/brain/tasks/goal-verification.d.ts +32 -0
- package/dist/brain/tasks/goal-verification.d.ts.map +1 -0
- package/dist/brain/tasks/goal-verification.js +68 -0
- package/dist/brain/tasks/goal-verification.js.map +1 -0
- package/dist/brain/tasks/knowledge.d.ts +26 -0
- package/dist/brain/tasks/knowledge.d.ts.map +1 -0
- package/dist/brain/tasks/knowledge.js +56 -0
- package/dist/brain/tasks/knowledge.js.map +1 -0
- package/dist/brain/tasks/link-scout.d.ts +37 -0
- package/dist/brain/tasks/link-scout.d.ts.map +1 -0
- package/dist/brain/tasks/link-scout.js +69 -0
- package/dist/brain/tasks/link-scout.js.map +1 -0
- package/dist/brain/types.d.ts +55 -0
- package/dist/brain/types.d.ts.map +1 -0
- package/dist/brain/types.js +7 -0
- package/dist/brain/types.js.map +1 -0
- package/dist/browser/stealth-init-script.d.ts +9 -0
- package/dist/browser/stealth-init-script.d.ts.map +1 -0
- package/dist/browser/stealth-init-script.js +128 -0
- package/dist/browser/stealth-init-script.js.map +1 -0
- package/dist/browser/storage-state.d.ts +29 -0
- package/dist/browser/storage-state.d.ts.map +1 -0
- package/dist/browser/storage-state.js +47 -0
- package/dist/browser/storage-state.js.map +1 -0
- package/dist/cli/args.d.ts +141 -0
- package/dist/cli/args.d.ts.map +1 -0
- package/dist/cli/args.js +167 -0
- package/dist/cli/args.js.map +1 -0
- package/dist/cli/benchmark-sync.d.ts +9 -0
- package/dist/cli/benchmark-sync.d.ts.map +1 -0
- package/dist/cli/benchmark-sync.js +43 -0
- package/dist/cli/benchmark-sync.js.map +1 -0
- package/dist/cli/build-config.d.ts +11 -0
- package/dist/cli/build-config.d.ts.map +1 -0
- package/dist/cli/build-config.js +355 -0
- package/dist/cli/build-config.js.map +1 -0
- package/dist/cli/commands/auth.d.ts +3 -0
- package/dist/cli/commands/auth.d.ts.map +1 -0
- package/dist/cli/commands/auth.js +36 -0
- package/dist/cli/commands/auth.js.map +1 -0
- package/dist/cli/commands/chrome-debug.d.ts +7 -0
- package/dist/cli/commands/chrome-debug.d.ts.map +1 -0
- package/dist/cli/commands/chrome-debug.js +11 -0
- package/dist/cli/commands/chrome-debug.js.map +1 -0
- package/dist/cli/commands/design-audit.d.ts +3 -0
- package/dist/cli/commands/design-audit.d.ts.map +1 -0
- package/dist/cli/commands/design-audit.js +68 -0
- package/dist/cli/commands/design-audit.js.map +1 -0
- package/dist/cli/commands/preview.d.ts +14 -0
- package/dist/cli/commands/preview.d.ts.map +1 -0
- package/dist/cli/commands/preview.js +31 -0
- package/dist/cli/commands/preview.js.map +1 -0
- package/dist/cli/commands/run.d.ts +3 -0
- package/dist/cli/commands/run.d.ts.map +1 -0
- package/dist/cli/commands/run.js +728 -0
- package/dist/cli/commands/run.js.map +1 -0
- package/dist/cli/commands/runs.d.ts +8 -0
- package/dist/cli/commands/runs.d.ts.map +1 -0
- package/dist/cli/commands/runs.js +35 -0
- package/dist/cli/commands/runs.js.map +1 -0
- package/dist/cli/commands/share.d.ts +10 -0
- package/dist/cli/commands/share.d.ts.map +1 -0
- package/dist/cli/commands/share.js +32 -0
- package/dist/cli/commands/share.js.map +1 -0
- package/dist/cli/commands/showcase.d.ts +17 -0
- package/dist/cli/commands/showcase.d.ts.map +1 -0
- package/dist/cli/commands/showcase.js +20 -0
- package/dist/cli/commands/showcase.js.map +1 -0
- package/dist/cli/commands/snapshot.d.ts +12 -0
- package/dist/cli/commands/snapshot.d.ts.map +1 -0
- package/dist/cli/commands/snapshot.js +24 -0
- package/dist/cli/commands/snapshot.js.map +1 -0
- package/dist/cli/commands/view.d.ts +7 -0
- package/dist/cli/commands/view.d.ts.map +1 -0
- package/dist/cli/commands/view.js +23 -0
- package/dist/cli/commands/view.js.map +1 -0
- package/dist/cli/constants.d.ts +6 -0
- package/dist/cli/constants.d.ts.map +1 -0
- package/dist/cli/constants.js +3 -0
- package/dist/cli/constants.js.map +1 -0
- package/dist/cli/version.d.ts +7 -0
- package/dist/cli/version.d.ts.map +1 -0
- package/dist/cli/version.js +16 -0
- package/dist/cli/version.js.map +1 -0
- package/dist/cli-design-audit.d.ts +44 -36
- package/dist/cli-design-audit.d.ts.map +1 -1
- package/dist/cli-design-audit.js +137 -1646
- package/dist/cli-design-audit.js.map +1 -1
- package/dist/cli-jobs.js +2 -1
- package/dist/cli-jobs.js.map +1 -1
- package/dist/cli.js +66 -1697
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +5 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +8 -0
- package/dist/config.js.map +1 -1
- package/dist/design/audit/evolve/agent.d.ts +23 -0
- package/dist/design/audit/evolve/agent.d.ts.map +1 -0
- package/dist/design/audit/evolve/agent.js +272 -0
- package/dist/design/audit/evolve/agent.js.map +1 -0
- package/dist/design/audit/evolve/css.d.ts +10 -0
- package/dist/design/audit/evolve/css.d.ts.map +1 -0
- package/dist/design/audit/evolve/css.js +206 -0
- package/dist/design/audit/evolve/css.js.map +1 -0
- package/dist/design/audit/evolve/index.d.ts +13 -0
- package/dist/design/audit/evolve/index.d.ts.map +1 -0
- package/dist/design/audit/evolve/index.js +12 -0
- package/dist/design/audit/evolve/index.js.map +1 -0
- package/dist/design/audit/evolve/report.d.ts +3 -0
- package/dist/design/audit/evolve/report.d.ts.map +1 -0
- package/dist/design/audit/evolve/report.js +45 -0
- package/dist/design/audit/evolve/report.js.map +1 -0
- package/dist/design/audit/evolve/types.d.ts +14 -0
- package/dist/design/audit/evolve/types.d.ts.map +1 -0
- package/dist/design/audit/evolve/types.js +2 -0
- package/dist/design/audit/evolve/types.js.map +1 -0
- package/dist/design/audit/pipeline.d.ts +12 -0
- package/dist/design/audit/pipeline.d.ts.map +1 -1
- package/dist/design/audit/pipeline.js +43 -27
- package/dist/design/audit/pipeline.js.map +1 -1
- package/dist/design/audit/reference/artifact/build.d.ts +33 -0
- package/dist/design/audit/reference/artifact/build.d.ts.map +1 -0
- package/dist/design/audit/reference/artifact/build.js +64 -0
- package/dist/design/audit/reference/artifact/build.js.map +1 -0
- package/dist/design/audit/reference/artifact/render.d.ts +39 -0
- package/dist/design/audit/reference/artifact/render.d.ts.map +1 -0
- package/dist/design/audit/reference/artifact/render.js +213 -0
- package/dist/design/audit/reference/artifact/render.js.map +1 -0
- package/dist/design/audit/reference/artifact/text.d.ts +11 -0
- package/dist/design/audit/reference/artifact/text.d.ts.map +1 -0
- package/dist/design/audit/reference/artifact/text.js +20 -0
- package/dist/design/audit/reference/artifact/text.js.map +1 -0
- package/dist/design/audit/reference/artifact/to-findings.d.ts +57 -0
- package/dist/design/audit/reference/artifact/to-findings.d.ts.map +1 -0
- package/dist/design/audit/reference/artifact/to-findings.js +314 -0
- package/dist/design/audit/reference/artifact/to-findings.js.map +1 -0
- package/dist/design/audit/reference/config.d.ts +50 -0
- package/dist/design/audit/reference/config.d.ts.map +1 -0
- package/dist/design/audit/reference/config.js +108 -0
- package/dist/design/audit/reference/config.js.map +1 -0
- package/dist/design/audit/reference/contracts.d.ts +1030 -0
- package/dist/design/audit/reference/contracts.d.ts.map +1 -0
- package/dist/design/audit/reference/contracts.js +28 -0
- package/dist/design/audit/reference/contracts.js.map +1 -0
- package/dist/design/audit/reference/corpus/build.d.ts +115 -0
- package/dist/design/audit/reference/corpus/build.d.ts.map +1 -0
- package/dist/design/audit/reference/corpus/build.js +152 -0
- package/dist/design/audit/reference/corpus/build.js.map +1 -0
- package/dist/design/audit/reference/corpus/schema.d.ts +33 -0
- package/dist/design/audit/reference/corpus/schema.d.ts.map +1 -0
- package/dist/design/audit/reference/corpus/schema.js +249 -0
- package/dist/design/audit/reference/corpus/schema.js.map +1 -0
- package/dist/design/audit/reference/corpus/store.d.ts +26 -0
- package/dist/design/audit/reference/corpus/store.d.ts.map +1 -0
- package/dist/design/audit/reference/corpus/store.js +104 -0
- package/dist/design/audit/reference/corpus/store.js.map +1 -0
- package/dist/design/audit/reference/dna/delta.d.ts +21 -0
- package/dist/design/audit/reference/dna/delta.d.ts.map +1 -0
- package/dist/design/audit/reference/dna/delta.js +126 -0
- package/dist/design/audit/reference/dna/delta.js.map +1 -0
- package/dist/design/audit/reference/dna/derive.d.ts +31 -0
- package/dist/design/audit/reference/dna/derive.d.ts.map +1 -0
- package/dist/design/audit/reference/dna/derive.js +381 -0
- package/dist/design/audit/reference/dna/derive.js.map +1 -0
- package/dist/design/audit/reference/dna/descriptor.d.ts +36 -0
- package/dist/design/audit/reference/dna/descriptor.d.ts.map +1 -0
- package/dist/design/audit/reference/dna/descriptor.js +209 -0
- package/dist/design/audit/reference/dna/descriptor.js.map +1 -0
- package/dist/design/audit/reference/dna/page-adapter.d.ts +17 -0
- package/dist/design/audit/reference/dna/page-adapter.d.ts.map +1 -0
- package/dist/design/audit/reference/dna/page-adapter.js +35 -0
- package/dist/design/audit/reference/dna/page-adapter.js.map +1 -0
- package/dist/design/audit/reference/dna/scroll-capture.d.ts +93 -0
- package/dist/design/audit/reference/dna/scroll-capture.d.ts.map +1 -0
- package/dist/design/audit/reference/dna/scroll-capture.js +374 -0
- package/dist/design/audit/reference/dna/scroll-capture.js.map +1 -0
- package/dist/design/audit/reference/engine/budget.d.ts +63 -0
- package/dist/design/audit/reference/engine/budget.d.ts.map +1 -0
- package/dist/design/audit/reference/engine/budget.js +110 -0
- package/dist/design/audit/reference/engine/budget.js.map +1 -0
- package/dist/design/audit/reference/engine/core.d.ts +32 -0
- package/dist/design/audit/reference/engine/core.d.ts.map +1 -0
- package/dist/design/audit/reference/engine/core.js +261 -0
- package/dist/design/audit/reference/engine/core.js.map +1 -0
- package/dist/design/audit/reference/engine/guard.d.ts +43 -0
- package/dist/design/audit/reference/engine/guard.d.ts.map +1 -0
- package/dist/design/audit/reference/engine/guard.js +43 -0
- package/dist/design/audit/reference/engine/guard.js.map +1 -0
- package/dist/design/audit/reference/engine/score-core.d.ts +48 -0
- package/dist/design/audit/reference/engine/score-core.d.ts.map +1 -0
- package/dist/design/audit/reference/engine/score-core.js +134 -0
- package/dist/design/audit/reference/engine/score-core.js.map +1 -0
- package/dist/design/audit/reference/engine/wiring.d.ts +35 -0
- package/dist/design/audit/reference/engine/wiring.d.ts.map +1 -0
- package/dist/design/audit/reference/engine/wiring.js +80 -0
- package/dist/design/audit/reference/engine/wiring.js.map +1 -0
- package/dist/design/audit/reference/eval/taste-core.d.ts +77 -0
- package/dist/design/audit/reference/eval/taste-core.d.ts.map +1 -0
- package/dist/design/audit/reference/eval/taste-core.js +95 -0
- package/dist/design/audit/reference/eval/taste-core.js.map +1 -0
- package/dist/design/audit/reference/generate/generator.d.ts +49 -0
- package/dist/design/audit/reference/generate/generator.d.ts.map +1 -0
- package/dist/design/audit/reference/generate/generator.js +94 -0
- package/dist/design/audit/reference/generate/generator.js.map +1 -0
- package/dist/design/audit/reference/generate/parse.d.ts +28 -0
- package/dist/design/audit/reference/generate/parse.d.ts.map +1 -0
- package/dist/design/audit/reference/generate/parse.js +180 -0
- package/dist/design/audit/reference/generate/parse.js.map +1 -0
- package/dist/design/audit/reference/generate/prompt.d.ts +36 -0
- package/dist/design/audit/reference/generate/prompt.d.ts.map +1 -0
- package/dist/design/audit/reference/generate/prompt.js +124 -0
- package/dist/design/audit/reference/generate/prompt.js.map +1 -0
- package/dist/design/audit/reference/index.d.ts +26 -0
- package/dist/design/audit/reference/index.d.ts.map +1 -0
- package/dist/design/audit/reference/index.js +31 -0
- package/dist/design/audit/reference/index.js.map +1 -0
- package/dist/design/audit/reference/judge/image-clamp.d.ts +34 -0
- package/dist/design/audit/reference/judge/image-clamp.d.ts.map +1 -0
- package/dist/design/audit/reference/judge/image-clamp.js +88 -0
- package/dist/design/audit/reference/judge/image-clamp.js.map +1 -0
- package/dist/design/audit/reference/judge/pairwise.d.ts +34 -0
- package/dist/design/audit/reference/judge/pairwise.d.ts.map +1 -0
- package/dist/design/audit/reference/judge/pairwise.js +105 -0
- package/dist/design/audit/reference/judge/pairwise.js.map +1 -0
- package/dist/design/audit/reference/judge/parse.d.ts +31 -0
- package/dist/design/audit/reference/judge/parse.d.ts.map +1 -0
- package/dist/design/audit/reference/judge/parse.js +113 -0
- package/dist/design/audit/reference/judge/parse.js.map +1 -0
- package/dist/design/audit/reference/judge/prompt.d.ts +38 -0
- package/dist/design/audit/reference/judge/prompt.d.ts.map +1 -0
- package/dist/design/audit/reference/judge/prompt.js +111 -0
- package/dist/design/audit/reference/judge/prompt.js.map +1 -0
- package/dist/design/audit/reference/judge/quality.d.ts +28 -0
- package/dist/design/audit/reference/judge/quality.d.ts.map +1 -0
- package/dist/design/audit/reference/judge/quality.js +62 -0
- package/dist/design/audit/reference/judge/quality.js.map +1 -0
- package/dist/design/audit/reference/judge/rank.d.ts +41 -0
- package/dist/design/audit/reference/judge/rank.d.ts.map +1 -0
- package/dist/design/audit/reference/judge/rank.js +196 -0
- package/dist/design/audit/reference/judge/rank.js.map +1 -0
- package/dist/design/audit/reference/judge/text-judge.d.ts +31 -0
- package/dist/design/audit/reference/judge/text-judge.d.ts.map +1 -0
- package/dist/design/audit/reference/judge/text-judge.js +43 -0
- package/dist/design/audit/reference/judge/text-judge.js.map +1 -0
- package/dist/design/audit/reference/judge/vision-judge.d.ts +59 -0
- package/dist/design/audit/reference/judge/vision-judge.d.ts.map +1 -0
- package/dist/design/audit/reference/judge/vision-judge.js +150 -0
- package/dist/design/audit/reference/judge/vision-judge.js.map +1 -0
- package/dist/design/audit/reference/judge/vision-model.d.ts +65 -0
- package/dist/design/audit/reference/judge/vision-model.d.ts.map +1 -0
- package/dist/design/audit/reference/judge/vision-model.js +110 -0
- package/dist/design/audit/reference/judge/vision-model.js.map +1 -0
- package/dist/design/audit/reference/pipeline/evaluate-reference.d.ts +68 -0
- package/dist/design/audit/reference/pipeline/evaluate-reference.d.ts.map +1 -0
- package/dist/design/audit/reference/pipeline/evaluate-reference.js +52 -0
- package/dist/design/audit/reference/pipeline/evaluate-reference.js.map +1 -0
- package/dist/design/audit/reference/reference-context.d.ts +31 -0
- package/dist/design/audit/reference/reference-context.d.ts.map +1 -0
- package/dist/design/audit/reference/reference-context.js +73 -0
- package/dist/design/audit/reference/reference-context.js.map +1 -0
- package/dist/design/audit/reference/retrieval/embedding-hash.d.ts +30 -0
- package/dist/design/audit/reference/retrieval/embedding-hash.d.ts.map +1 -0
- package/dist/design/audit/reference/retrieval/embedding-hash.js +87 -0
- package/dist/design/audit/reference/retrieval/embedding-hash.js.map +1 -0
- package/dist/design/audit/reference/retrieval/embedding-openai.d.ts +38 -0
- package/dist/design/audit/reference/retrieval/embedding-openai.d.ts.map +1 -0
- package/dist/design/audit/reference/retrieval/embedding-openai.js +73 -0
- package/dist/design/audit/reference/retrieval/embedding-openai.js.map +1 -0
- package/dist/design/audit/reference/retrieval/matcher.d.ts +34 -0
- package/dist/design/audit/reference/retrieval/matcher.d.ts.map +1 -0
- package/dist/design/audit/reference/retrieval/matcher.js +107 -0
- package/dist/design/audit/reference/retrieval/matcher.js.map +1 -0
- package/dist/design/audit/reference/run.d.ts +59 -0
- package/dist/design/audit/reference/run.d.ts.map +1 -0
- package/dist/design/audit/reference/run.js +99 -0
- package/dist/design/audit/reference/run.js.map +1 -0
- package/dist/design/audit/report.d.ts +35 -0
- package/dist/design/audit/report.d.ts.map +1 -0
- package/dist/design/audit/report.js +195 -0
- package/dist/design/audit/report.js.map +1 -0
- package/dist/design/audit/tokens/extract.d.ts +71 -0
- package/dist/design/audit/tokens/extract.d.ts.map +1 -0
- package/dist/design/audit/tokens/extract.js +1034 -0
- package/dist/design/audit/tokens/extract.js.map +1 -0
- package/dist/design/audit/types.d.ts +8 -0
- package/dist/design/audit/types.d.ts.map +1 -1
- package/dist/design/compare.d.ts.map +1 -1
- package/dist/design/compare.js +2 -6
- package/dist/design/compare.js.map +1 -1
- package/dist/design/cookie-consent.d.ts +3 -0
- package/dist/design/cookie-consent.d.ts.map +1 -0
- package/dist/design/cookie-consent.js +26 -0
- package/dist/design/cookie-consent.js.map +1 -0
- package/dist/design/viewports.d.ts +18 -0
- package/dist/design/viewports.d.ts.map +1 -0
- package/dist/design/viewports.js +10 -0
- package/dist/design/viewports.js.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/memory/store.d.ts +19 -1
- package/dist/memory/store.d.ts.map +1 -1
- package/dist/memory/store.js +47 -0
- package/dist/memory/store.js.map +1 -1
- package/dist/provider-defaults.d.ts +18 -0
- package/dist/provider-defaults.d.ts.map +1 -1
- package/dist/provider-defaults.js +33 -0
- package/dist/provider-defaults.js.map +1 -1
- package/dist/runner/allowed-domains.d.ts +11 -0
- package/dist/runner/allowed-domains.d.ts.map +1 -0
- package/dist/runner/allowed-domains.js +14 -0
- package/dist/runner/allowed-domains.js.map +1 -0
- package/dist/runner/batch-fill.d.ts +28 -0
- package/dist/runner/batch-fill.d.ts.map +1 -0
- package/dist/runner/batch-fill.js +80 -0
- package/dist/runner/batch-fill.js.map +1 -0
- package/dist/runner/completion-policy.d.ts +26 -0
- package/dist/runner/completion-policy.d.ts.map +1 -0
- package/dist/runner/completion-policy.js +76 -0
- package/dist/runner/completion-policy.js.map +1 -0
- package/dist/runner/constants.d.ts +14 -0
- package/dist/runner/constants.d.ts.map +1 -0
- package/dist/runner/constants.js +23 -0
- package/dist/runner/constants.js.map +1 -0
- package/dist/runner/decision-screenshot.d.ts +24 -0
- package/dist/runner/decision-screenshot.d.ts.map +1 -0
- package/dist/runner/decision-screenshot.js +23 -0
- package/dist/runner/decision-screenshot.js.map +1 -0
- package/dist/runner/domain-boundary.d.ts +36 -0
- package/dist/runner/domain-boundary.d.ts.map +1 -0
- package/dist/runner/domain-boundary.js +81 -0
- package/dist/runner/domain-boundary.js.map +1 -0
- package/dist/runner/effect-verify.d.ts +28 -0
- package/dist/runner/effect-verify.d.ts.map +1 -0
- package/dist/runner/effect-verify.js +42 -0
- package/dist/runner/effect-verify.js.map +1 -0
- package/dist/runner/execute-plan.d.ts +58 -0
- package/dist/runner/execute-plan.d.ts.map +1 -0
- package/dist/runner/execute-plan.js +426 -0
- package/dist/runner/execute-plan.js.map +1 -0
- package/dist/runner/max-turns-extension.d.ts +19 -0
- package/dist/runner/max-turns-extension.d.ts.map +1 -0
- package/dist/runner/max-turns-extension.js +25 -0
- package/dist/runner/max-turns-extension.js.map +1 -0
- package/dist/runner/micro-plan.d.ts +11 -0
- package/dist/runner/micro-plan.d.ts.map +1 -0
- package/dist/runner/micro-plan.js +29 -0
- package/dist/runner/micro-plan.js.map +1 -0
- package/dist/runner/prompt-snippets.d.ts +5 -0
- package/dist/runner/prompt-snippets.d.ts.map +1 -0
- package/dist/runner/prompt-snippets.js +13 -0
- package/dist/runner/prompt-snippets.js.map +1 -0
- package/dist/runner/replay/contracts.d.ts +300 -0
- package/dist/runner/replay/contracts.d.ts.map +1 -0
- package/dist/runner/replay/contracts.js +42 -0
- package/dist/runner/replay/contracts.js.map +1 -0
- package/dist/runner/replay/controller.d.ts +27 -0
- package/dist/runner/replay/controller.d.ts.map +1 -0
- package/dist/runner/replay/controller.js +197 -0
- package/dist/runner/replay/controller.js.map +1 -0
- package/dist/runner/replay/guard.d.ts +28 -0
- package/dist/runner/replay/guard.d.ts.map +1 -0
- package/dist/runner/replay/guard.js +100 -0
- package/dist/runner/replay/guard.js.map +1 -0
- package/dist/runner/runner.d.ts +44 -51
- package/dist/runner/runner.d.ts.map +1 -1
- package/dist/runner/runner.js +155 -851
- package/dist/runner/runner.js.map +1 -1
- package/dist/runner/scout-feedback.d.ts +51 -0
- package/dist/runner/scout-feedback.d.ts.map +1 -0
- package/dist/runner/scout-feedback.js +149 -0
- package/dist/runner/scout-feedback.js.map +1 -0
- package/dist/skills/macro-loader.d.ts +1 -1
- package/dist/test-runner.d.ts.map +1 -1
- package/dist/test-runner.js +25 -0
- package/dist/test-runner.js.map +1 -1
- package/dist/types/actions.d.ts +241 -0
- package/dist/types/actions.d.ts.map +1 -0
- package/dist/types/actions.js +5 -0
- package/dist/types/actions.js.map +1 -0
- package/dist/types/config.d.ts +211 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +2 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/design-audit.d.ts +92 -0
- package/dist/types/design-audit.d.ts.map +1 -0
- package/dist/types/design-audit.js +5 -0
- package/dist/types/design-audit.js.map +1 -0
- package/dist/types/design-tokens.d.ts +138 -0
- package/dist/types/design-tokens.d.ts.map +1 -0
- package/dist/types/design-tokens.js +5 -0
- package/dist/types/design-tokens.js.map +1 -0
- package/dist/types/page.d.ts +16 -0
- package/dist/types/page.d.ts.map +1 -0
- package/dist/types/page.js +2 -0
- package/dist/types/page.js.map +1 -0
- package/dist/types/plan.d.ts +50 -0
- package/dist/types/plan.d.ts.map +1 -0
- package/dist/types/plan.js +2 -0
- package/dist/types/plan.js.map +1 -0
- package/dist/types/preview.d.ts +9 -0
- package/dist/types/preview.d.ts.map +1 -0
- package/dist/types/preview.js +5 -0
- package/dist/types/preview.js.map +1 -0
- package/dist/types/result.d.ts +62 -0
- package/dist/types/result.d.ts.map +1 -0
- package/dist/types/result.js +2 -0
- package/dist/types/result.js.map +1 -0
- package/dist/types/scenario.d.ts +20 -0
- package/dist/types/scenario.d.ts.map +1 -0
- package/dist/types/scenario.js +5 -0
- package/dist/types/scenario.js.map +1 -0
- package/dist/types/test-runner.d.ts +145 -0
- package/dist/types/test-runner.d.ts.map +1 -0
- package/dist/types/test-runner.js +10 -0
- package/dist/types/test-runner.js.map +1 -0
- package/dist/types/trajectory.d.ts +38 -0
- package/dist/types/trajectory.d.ts.map +1 -0
- package/dist/types/trajectory.js +2 -0
- package/dist/types/trajectory.js.map +1 -0
- package/dist/types/turn.d.ts +50 -0
- package/dist/types/turn.d.ts.map +1 -0
- package/dist/types/turn.js +2 -0
- package/dist/types/turn.js.map +1 -0
- package/dist/types.d.ts +16 -1017
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +15 -8
- package/dist/types.js.map +1 -1
- package/dist/wallet/rpc-interception.d.ts +15 -0
- package/dist/wallet/rpc-interception.d.ts.map +1 -0
- package/dist/wallet/rpc-interception.js +95 -0
- package/dist/wallet/rpc-interception.js.map +1 -0
- package/package.json +6 -2
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Micro-plan follow-up selection — given the primary action the LLM chose and
|
|
3
|
+
* the optional `nextActions` it proposed, pick the safe subset to chain in the
|
|
4
|
+
* same turn, bounded by the configured per-turn action cap.
|
|
5
|
+
*/
|
|
6
|
+
import { SAFE_MICRO_ACTIONS, DEFAULT_MICRO_PLAN_ACTIONS } from './constants.js';
|
|
7
|
+
export function selectMicroPlanFollowUps(primaryAction, nextActions, microPlanConfig) {
|
|
8
|
+
if (microPlanConfig?.enabled !== true || !Array.isArray(nextActions) || nextActions.length === 0) {
|
|
9
|
+
return [];
|
|
10
|
+
}
|
|
11
|
+
// Never chain follow-up actions behind terminal/meta actions.
|
|
12
|
+
if (!SAFE_MICRO_ACTIONS.has(primaryAction.action)) {
|
|
13
|
+
return [];
|
|
14
|
+
}
|
|
15
|
+
const limit = Math.max(1, Math.min(4, microPlanConfig.maxActionsPerTurn ?? DEFAULT_MICRO_PLAN_ACTIONS));
|
|
16
|
+
const remainingSlots = Math.max(0, limit - 1);
|
|
17
|
+
if (remainingSlots === 0)
|
|
18
|
+
return [];
|
|
19
|
+
const selected = [];
|
|
20
|
+
for (const action of nextActions) {
|
|
21
|
+
if (!SAFE_MICRO_ACTIONS.has(action.action))
|
|
22
|
+
continue;
|
|
23
|
+
selected.push(action);
|
|
24
|
+
if (selected.length >= remainingSlots)
|
|
25
|
+
break;
|
|
26
|
+
}
|
|
27
|
+
return selected;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=micro-plan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"micro-plan.js","sourceRoot":"","sources":["../../src/runner/micro-plan.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,kBAAkB,EAAE,0BAA0B,EAAE,MAAM,gBAAgB,CAAC;AAEhF,MAAM,UAAU,wBAAwB,CACtC,aAAqB,EACrB,WAAiC,EACjC,eAA8E;IAE9E,IAAI,eAAe,EAAE,OAAO,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACjG,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,8DAA8D;IAC9D,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC;QAClD,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CACpB,CAAC,EACD,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,eAAe,CAAC,iBAAiB,IAAI,0BAA0B,CAAC,CAC7E,CAAC;IACF,MAAM,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;IAC9C,IAAI,cAAc,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAEpC,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,KAAK,MAAM,MAAM,IAAI,WAAW,EAAE,CAAC;QACjC,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC;YAAE,SAAS;QACrD,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACtB,IAAI,QAAQ,CAAC,MAAM,IAAI,cAAc;YAAE,MAAM;IAC/C,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-snippets.d.ts","sourceRoot":"","sources":["../../src/runner/prompt-snippets.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,kBAAkB,QAS0F,CAAA"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Static prompt snippets the main loop injects into the brain context.
|
|
3
|
+
*/
|
|
4
|
+
export const DEFI_BRAIN_CONTEXT = '\nWALLET/DeFi MODE ACTIVE — crypto app patterns:\n' +
|
|
5
|
+
'- PERSISTENT WIDGETS: Many DeFi apps have always-on support/chat widgets (bottom-right) that show as alertdialog. These CANNOT be dismissed. Ignore them and interact with the page directly.\n' +
|
|
6
|
+
'- WALLET CONNECTION: Look for "Connect Wallet" button, select MetaMask. The wallet extension handles the approval popup automatically.\n' +
|
|
7
|
+
'- TOKEN SELECTION: If you need to change a token, click the token selector button (usually shows token symbol/icon), search for the token name, and select it from the dropdown.\n' +
|
|
8
|
+
'- TRANSACTION FLOW: Enter amount → wait for quote/estimate to load → click action button (Swap/Supply/etc.) → review dialog appears → stop before confirming in MetaMask.\n' +
|
|
9
|
+
'- LOADING STATES: DeFi apps make many RPC calls. Wait for balances and quotes to appear before clicking action buttons. If a button says "Enter amount" or is disabled, the app is still loading.\n' +
|
|
10
|
+
'- NATIVE ETH: Prefer native ETH over wrapped tokens (WETH) when possible — avoids ERC-20 spending approval steps.\n' +
|
|
11
|
+
'- NETWORK SELECTOR: Do NOT change the network/chain. If a network dropdown opens accidentally, close it immediately.\n' +
|
|
12
|
+
'- COOKIE BANNERS: Dismiss immediately via Escape or Reject button — don\'t spend multiple turns on consent dialogs.\n';
|
|
13
|
+
//# sourceMappingURL=prompt-snippets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-snippets.js","sourceRoot":"","sources":["../../src/runner/prompt-snippets.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,CAAC,MAAM,kBAAkB,GAC7B,oDAAoD;IACpD,iMAAiM;IACjM,0IAA0I;IAC1I,oLAAoL;IACpL,6KAA6K;IAC7K,qMAAqM;IACrM,qHAAqH;IACrH,wHAAwH;IACxH,uHAAuH,CAAA"}
|
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workflow Replay — contracts.
|
|
3
|
+
*
|
|
4
|
+
* Replay re-executes a previously-recorded successful {@link Trajectory} against
|
|
5
|
+
* the live browser with ZERO per-action LLM calls. A normal run is ~97-98%
|
|
6
|
+
* LLM-latency-bound (~10-13s per `brain.decide` round-trip); replaying a known
|
|
7
|
+
* task collapses a ~40s / 3-call run into ~1-3s of pure browser I/O plus a
|
|
8
|
+
* single goal-verification LLM call at the end.
|
|
9
|
+
*
|
|
10
|
+
* Where it slots in: replay is a SIBLING pre-loop path to the planner-first
|
|
11
|
+
* path in `runner.ts`. The runner attempts replay first; on success it returns,
|
|
12
|
+
* and on a self-heal abort it falls through to the normal per-action loop FROM
|
|
13
|
+
* THE CURRENT PAGE STATE (same fall-through pattern the planner path already
|
|
14
|
+
* uses). Replay never blindly claims success — even a fully-replayed run ends
|
|
15
|
+
* with the existing `brain.verifyGoalCompletion` (one LLM call).
|
|
16
|
+
*
|
|
17
|
+
* Self-heal semantics (the safety net):
|
|
18
|
+
* A wrong replay is cheap. Each step is gated twice — by a pure pre-execution
|
|
19
|
+
* guard ({@link ReplayGuard}) and by post-execution effect verification — so a
|
|
20
|
+
* trajectory that no longer fits the live page ABORTS after at most a few fast
|
|
21
|
+
* browser actions and hands control to the agent. The final outcome is never
|
|
22
|
+
* worse than running the agent from scratch; the only cost of a bad replay is
|
|
23
|
+
* the handful of actions executed before the heal fired. Because of this, the
|
|
24
|
+
* guard deliberately gates on ACTION-PERFORMABILITY, not on exact snapshot
|
|
25
|
+
* identity: the page legitimately differs run-to-run (timestamps, session
|
|
26
|
+
* chrome, ad slots, list ordering), so a hard `snapshotHash` equality gate
|
|
27
|
+
* would heal on nearly every replay and defeat the purpose. `snapshotHash`
|
|
28
|
+
* drift is at most a secondary heuristic; the real question the guard answers
|
|
29
|
+
* is "can THIS action still be performed against the page in front of me?".
|
|
30
|
+
*
|
|
31
|
+
* This module is contracts only — no executor logic. The pure guard core
|
|
32
|
+
* ({@link ReplayGuard}) is kept separate from the IO executor
|
|
33
|
+
* ({@link ReplayController}) so the decision logic unit-tests without a browser.
|
|
34
|
+
*/
|
|
35
|
+
import type { Action } from '../../types/actions.js';
|
|
36
|
+
import type { PageState } from '../../types/page.js';
|
|
37
|
+
import type { Turn } from '../../types/turn.js';
|
|
38
|
+
import type { GoalVerification } from '../../types/result.js';
|
|
39
|
+
import type { Trajectory, TrajectoryStep } from '../../types/trajectory.js';
|
|
40
|
+
import type { Driver } from '../../drivers/types.js';
|
|
41
|
+
import type { EffectVerificationInput, EffectVerificationResult } from '../effect-verification.js';
|
|
42
|
+
/**
|
|
43
|
+
* Strict goal-similarity bar for selecting a replay candidate. Far higher than
|
|
44
|
+
* the 0.5 hint-injection threshold used by {@link TrajectoryStore.findBestMatch}:
|
|
45
|
+
* an imperfect reference is fine to *show* the LLM as a hint, but replaying it
|
|
46
|
+
* verbatim against the live page demands a near-exact task match.
|
|
47
|
+
*/
|
|
48
|
+
export declare const DEFAULT_REPLAY_SIMILARITY_THRESHOLD = 0.85;
|
|
49
|
+
/**
|
|
50
|
+
* A single replayable step. Reuses {@link TrajectoryStep} (url + action +
|
|
51
|
+
* snapshotHash + verified + the OPTIONAL persisted `expectedEffect`).
|
|
52
|
+
*
|
|
53
|
+
* `expectedEffect` now rides on {@link TrajectoryStep} and is persisted by
|
|
54
|
+
* `save()` from `Turn.expectedEffect` (older trajectories written before that
|
|
55
|
+
* change simply lack the field). When present, the controller asserts it
|
|
56
|
+
* against the live page via the injected {@link ReplayContext.verifyEffect}
|
|
57
|
+
* (the runner's own `verifyExpectedEffect`) — this is the real second gate
|
|
58
|
+
* behind the "gated twice" safety thesis. When ABSENT, the controller falls
|
|
59
|
+
* back to a generic "the action executed without error" check and records
|
|
60
|
+
* whether the page changed for diagnostics only; the guard pre-check plus the
|
|
61
|
+
* execute-success gate plus the final goal verification remain the safety net.
|
|
62
|
+
*/
|
|
63
|
+
export interface ReplayStep extends TrajectoryStep {
|
|
64
|
+
/** Effect to assert after executing this step (see effect-verification). */
|
|
65
|
+
expectedEffect?: string;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* A matched replay candidate plus the metadata that justified selecting it.
|
|
69
|
+
* Produced from a strict {@link ReplayCandidateSource.findReplayCandidate} hit.
|
|
70
|
+
*/
|
|
71
|
+
export interface ReplayPlan {
|
|
72
|
+
/** The full source trajectory the steps came from. */
|
|
73
|
+
trajectory: Trajectory;
|
|
74
|
+
/** Concrete, executable browser steps (complete/abort already filtered at save time). */
|
|
75
|
+
steps: ReplayStep[];
|
|
76
|
+
/** Jaccard goal similarity between the live goal and the trajectory's goal (>= threshold). */
|
|
77
|
+
goalSimilarity: number;
|
|
78
|
+
/** Normalized origin the trajectory was scoped to, when known. */
|
|
79
|
+
origin?: string;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* The minimal live observation the pure guard reads: current URL + snapshot
|
|
83
|
+
* text. Deliberately narrower than {@link PageState} (no screenshot/diff) so
|
|
84
|
+
* guard unit tests can pass plain literals with no browser.
|
|
85
|
+
*/
|
|
86
|
+
export type ReplayObservation = Pick<PageState, 'url' | 'snapshot'>;
|
|
87
|
+
/**
|
|
88
|
+
* Result of the pure pre-execution guard for one step.
|
|
89
|
+
*
|
|
90
|
+
* Discriminated so an `abort` always carries a human-readable `reason` (the heal
|
|
91
|
+
* path must be explicit and logged) while `proceed` never needs one.
|
|
92
|
+
*/
|
|
93
|
+
export type StepGuardResult = {
|
|
94
|
+
decision: 'proceed';
|
|
95
|
+
} | {
|
|
96
|
+
decision: 'abort';
|
|
97
|
+
reason: string;
|
|
98
|
+
};
|
|
99
|
+
/**
|
|
100
|
+
* Pure decision core: given a recorded step and the current observation, decide
|
|
101
|
+
* whether the step can still be replayed. NO IO — it never touches the driver.
|
|
102
|
+
*
|
|
103
|
+
* It gates on action-performability, not snapshot identity:
|
|
104
|
+
* - the action's target must be addressable in the current snapshot (e.g. an
|
|
105
|
+
* `@ref` selector's `[ref=...]` token is still present), and
|
|
106
|
+
* - the URL/origin must be consistent with `step.url`.
|
|
107
|
+
* For selectors it cannot statically resolve against snapshot text (CSS, text=,
|
|
108
|
+
* role=), it returns `proceed` and defers to execution + effect verification —
|
|
109
|
+
* the guard is a cheap pre-filter, not the hard gate. See the module-level
|
|
110
|
+
* self-heal note for why exact `snapshotHash` equality is intentionally NOT a
|
|
111
|
+
* gate.
|
|
112
|
+
*/
|
|
113
|
+
export interface ReplayGuard {
|
|
114
|
+
check(step: ReplayStep, current: ReplayObservation): StepGuardResult;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Final goal verification (one LLM call). Matches `brain.verifyGoalCompletion`
|
|
118
|
+
* so the controller can depend on the capability without importing the brain.
|
|
119
|
+
*/
|
|
120
|
+
export type GoalVerifier = (state: PageState, goal: string, claimedResult: string) => Promise<GoalVerification>;
|
|
121
|
+
/**
|
|
122
|
+
* Observable lifecycle of a replay attempt. Every heal/abort is surfaced so the
|
|
123
|
+
* decision is never silent. Wired to the runner's event bus in the executor.
|
|
124
|
+
*/
|
|
125
|
+
export type ReplayEvent = {
|
|
126
|
+
type: 'replay-started';
|
|
127
|
+
trajectoryId: string;
|
|
128
|
+
totalSteps: number;
|
|
129
|
+
goalSimilarity: number;
|
|
130
|
+
} | {
|
|
131
|
+
type: 'replay-step';
|
|
132
|
+
index: number;
|
|
133
|
+
totalSteps: number;
|
|
134
|
+
action: Action['action'];
|
|
135
|
+
} | {
|
|
136
|
+
type: 'replay-guard-abort';
|
|
137
|
+
index: number;
|
|
138
|
+
reason: string;
|
|
139
|
+
} | {
|
|
140
|
+
type: 'replay-effect-failed';
|
|
141
|
+
index: number;
|
|
142
|
+
reason: string;
|
|
143
|
+
} | {
|
|
144
|
+
type: 'replay-healed';
|
|
145
|
+
completedSteps: number;
|
|
146
|
+
totalSteps: number;
|
|
147
|
+
reason: string;
|
|
148
|
+
} | {
|
|
149
|
+
type: 'replay-completed';
|
|
150
|
+
completedSteps: number;
|
|
151
|
+
achieved: boolean;
|
|
152
|
+
};
|
|
153
|
+
/**
|
|
154
|
+
* Everything the IO executor needs, injected so the controller stays decoupled
|
|
155
|
+
* from the concrete runner/brain wiring.
|
|
156
|
+
*/
|
|
157
|
+
export interface ReplayContext {
|
|
158
|
+
/** The live goal being pursued. */
|
|
159
|
+
goal: string;
|
|
160
|
+
/** Live browser driver (observe + execute). */
|
|
161
|
+
driver: Driver;
|
|
162
|
+
/** Pure step guard. */
|
|
163
|
+
guard: ReplayGuard;
|
|
164
|
+
/** Final goal-completion verifier (the single permitted LLM call). */
|
|
165
|
+
verifyGoal: GoalVerifier;
|
|
166
|
+
/**
|
|
167
|
+
* Per-step effect verifier — the runner injects its own pure
|
|
168
|
+
* `verifyExpectedEffect` (src/runner/effect-verification.ts). Typed against
|
|
169
|
+
* that module so the controller is FORCED to reuse the runner's verifier
|
|
170
|
+
* rather than hand-rolling a weaker per-step check, and so the second gate
|
|
171
|
+
* stays pure + unit-testable. Only consulted when a step carries a persisted
|
|
172
|
+
* `expectedEffect`. NO LLM call — this is deterministic string/state diffing.
|
|
173
|
+
*/
|
|
174
|
+
verifyEffect: (input: EffectVerificationInput) => EffectVerificationResult;
|
|
175
|
+
/** Cooperative cancellation. */
|
|
176
|
+
signal?: AbortSignal;
|
|
177
|
+
/** Verbose logging passthrough. */
|
|
178
|
+
debug?: boolean;
|
|
179
|
+
/** Optional structured event sink (runner bridges this to its TurnEventBus). */
|
|
180
|
+
onEvent?: (event: ReplayEvent) => void;
|
|
181
|
+
}
|
|
182
|
+
/** Discriminant for {@link ReplayOutcome}. */
|
|
183
|
+
export type ReplayOutcomeKind = 'completed' | 'healed' | 'no-candidate';
|
|
184
|
+
/** Fields common to every replay outcome. */
|
|
185
|
+
interface ReplayOutcomeBase {
|
|
186
|
+
/**
|
|
187
|
+
* Steps that replayed cleanly (guard proceed + execute + effect ok) before
|
|
188
|
+
* this outcome. EXCLUDES the step that aborted on `healed`. Diagnostic /
|
|
189
|
+
* event payload only — `turns.length` (below) is the authoritative count the
|
|
190
|
+
* runner uses to advance its loop index, mirroring the planner path's
|
|
191
|
+
* `cumulativeTurnsConsumed` semantics. `turns` may therefore contain one more
|
|
192
|
+
* entry than `completedSteps` when a step executed but its effect failed.
|
|
193
|
+
*/
|
|
194
|
+
completedSteps: number;
|
|
195
|
+
/** Total steps in the plan (0 when there was no candidate). */
|
|
196
|
+
totalSteps: number;
|
|
197
|
+
/** LLM calls replay itself spent — 1 on `completed` (final verify), 0 otherwise. */
|
|
198
|
+
llmCallsUsed: number;
|
|
199
|
+
/**
|
|
200
|
+
* Replay steps recorded as turns, for merging into the unified run timeline.
|
|
201
|
+
* AUTHORITATIVE for resume accounting: because replay is the FIRST pre-loop
|
|
202
|
+
* path it appends to an empty `turns` array, numbering its turns 1..N, and
|
|
203
|
+
* the runner offsets the per-action loop start by `turns.length` so a
|
|
204
|
+
* fall-through never re-executes a recorded step.
|
|
205
|
+
*/
|
|
206
|
+
turns: Turn[];
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* The result of a replay attempt.
|
|
210
|
+
*
|
|
211
|
+
* - `completed`: all steps replayed and the final goal verification ran. Carries
|
|
212
|
+
* the `goalVerification`, the `finalResult` string, and `lastState`.
|
|
213
|
+
* `achieved` may still be false — replay surfaces the verdict honestly rather
|
|
214
|
+
* than fabricating success. REQUIRED runner behavior: only
|
|
215
|
+
* `completed && goalVerification.achieved === true` is terminal (build the
|
|
216
|
+
* success result and return). `completed && achieved === false` MUST fall
|
|
217
|
+
* through to the per-action loop FROM `lastState`, exactly like `healed` —
|
|
218
|
+
* never return a confident failure off the back of a replay, which would be
|
|
219
|
+
* strictly worse than running the agent from scratch.
|
|
220
|
+
* - `healed`: a guard/execute/effect gate aborted mid-replay. Carries `reason`
|
|
221
|
+
* and `lastState` so the runner continues its per-action loop from here.
|
|
222
|
+
* - `no-candidate`: no strict match was found (or replay was disabled); the
|
|
223
|
+
* runner proceeds to its normal path untouched (no `lastState`, no turns).
|
|
224
|
+
*/
|
|
225
|
+
export type ReplayOutcome = (ReplayOutcomeBase & {
|
|
226
|
+
kind: 'completed';
|
|
227
|
+
lastState: PageState;
|
|
228
|
+
goalVerification: GoalVerification;
|
|
229
|
+
finalResult: string;
|
|
230
|
+
}) | (ReplayOutcomeBase & {
|
|
231
|
+
kind: 'healed';
|
|
232
|
+
lastState: PageState;
|
|
233
|
+
reason: string;
|
|
234
|
+
}) | (ReplayOutcomeBase & {
|
|
235
|
+
kind: 'no-candidate';
|
|
236
|
+
reason: string;
|
|
237
|
+
});
|
|
238
|
+
/**
|
|
239
|
+
* IO executor: drives the driver + guard through a {@link ReplayPlan}.
|
|
240
|
+
*
|
|
241
|
+
* For each step: observe → {@link ReplayGuard.check} (abort → heal) →
|
|
242
|
+
* `driver.execute` (error → heal) → verify expected effect (fail → heal). After
|
|
243
|
+
* all steps replay, run {@link ReplayContext.verifyGoal} once. Implementations
|
|
244
|
+
* MUST NOT make per-action LLM calls; the final goal verification is the only
|
|
245
|
+
* permitted model round-trip.
|
|
246
|
+
*/
|
|
247
|
+
export interface ReplayController {
|
|
248
|
+
replay(plan: ReplayPlan, ctx: ReplayContext): Promise<ReplayOutcome>;
|
|
249
|
+
}
|
|
250
|
+
/** Options for the strict replay-candidate lookup. */
|
|
251
|
+
export interface ReplayMatchOptions {
|
|
252
|
+
/**
|
|
253
|
+
* Origin to scope the lookup to. When supplied, only trajectories whose
|
|
254
|
+
* normalized origin matches exactly are eligible. The replay WIRING always
|
|
255
|
+
* supplies it from the live run's start URL (`scenario.startUrl`), and the
|
|
256
|
+
* runner only enters the replay path when an origin resolves — verbatim
|
|
257
|
+
* browser actions must never be selected cross-origin on lexical goal overlap
|
|
258
|
+
* alone. Left optional on the type so the store method stays general, but a
|
|
259
|
+
* production replay call without an origin is a wiring bug.
|
|
260
|
+
*/
|
|
261
|
+
origin?: string;
|
|
262
|
+
/** Minimum goal similarity to qualify. Defaults to {@link DEFAULT_REPLAY_SIMILARITY_THRESHOLD}. */
|
|
263
|
+
minSimilarity?: number;
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* A strict replay-candidate hit: the matched trajectory plus the score and
|
|
267
|
+
* origin that justified it. Returned (rather than a bare {@link Trajectory}) so
|
|
268
|
+
* the plan-builder can populate {@link ReplayPlan.goalSimilarity} and the
|
|
269
|
+
* `replay-started` event WITHOUT re-implementing the store's private Jaccard —
|
|
270
|
+
* the score that passed the gate is the score the plan reports.
|
|
271
|
+
*/
|
|
272
|
+
export interface ReplayCandidate {
|
|
273
|
+
trajectory: Trajectory;
|
|
274
|
+
/** Raw Jaccard goal similarity that cleared the threshold. */
|
|
275
|
+
similarity: number;
|
|
276
|
+
/** Normalized origin the trajectory was scoped to, when known. */
|
|
277
|
+
origin?: string;
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* The strict-match lookup replay depends on. Separate from `findBestMatch`
|
|
281
|
+
* (which keeps its 0.5 hint-injection threshold): a replay candidate requires
|
|
282
|
+
* `success === true`, a non-empty step list, an exact origin match when an
|
|
283
|
+
* origin is supplied, and goal similarity >= the strict threshold.
|
|
284
|
+
* {@link TrajectoryStore} satisfies this interface.
|
|
285
|
+
*/
|
|
286
|
+
export interface ReplayCandidateSource {
|
|
287
|
+
findReplayCandidate(goal: string, options?: ReplayMatchOptions): ReplayCandidate | null;
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Runtime config for replay. OPT-IN (`enabled` defaults to false / `--replay`)
|
|
291
|
+
* per the repo's experiment discipline until measured non-regressive.
|
|
292
|
+
*/
|
|
293
|
+
export interface ReplayConfig {
|
|
294
|
+
/** Master switch. Default behavior is byte-identical when false. */
|
|
295
|
+
enabled: boolean;
|
|
296
|
+
/** Override the strict similarity bar. Defaults to {@link DEFAULT_REPLAY_SIMILARITY_THRESHOLD}. */
|
|
297
|
+
minSimilarity?: number;
|
|
298
|
+
}
|
|
299
|
+
export {};
|
|
300
|
+
//# sourceMappingURL=contracts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contracts.d.ts","sourceRoot":"","sources":["../../../src/runner/replay/contracts.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workflow Replay — contracts.
|
|
3
|
+
*
|
|
4
|
+
* Replay re-executes a previously-recorded successful {@link Trajectory} against
|
|
5
|
+
* the live browser with ZERO per-action LLM calls. A normal run is ~97-98%
|
|
6
|
+
* LLM-latency-bound (~10-13s per `brain.decide` round-trip); replaying a known
|
|
7
|
+
* task collapses a ~40s / 3-call run into ~1-3s of pure browser I/O plus a
|
|
8
|
+
* single goal-verification LLM call at the end.
|
|
9
|
+
*
|
|
10
|
+
* Where it slots in: replay is a SIBLING pre-loop path to the planner-first
|
|
11
|
+
* path in `runner.ts`. The runner attempts replay first; on success it returns,
|
|
12
|
+
* and on a self-heal abort it falls through to the normal per-action loop FROM
|
|
13
|
+
* THE CURRENT PAGE STATE (same fall-through pattern the planner path already
|
|
14
|
+
* uses). Replay never blindly claims success — even a fully-replayed run ends
|
|
15
|
+
* with the existing `brain.verifyGoalCompletion` (one LLM call).
|
|
16
|
+
*
|
|
17
|
+
* Self-heal semantics (the safety net):
|
|
18
|
+
* A wrong replay is cheap. Each step is gated twice — by a pure pre-execution
|
|
19
|
+
* guard ({@link ReplayGuard}) and by post-execution effect verification — so a
|
|
20
|
+
* trajectory that no longer fits the live page ABORTS after at most a few fast
|
|
21
|
+
* browser actions and hands control to the agent. The final outcome is never
|
|
22
|
+
* worse than running the agent from scratch; the only cost of a bad replay is
|
|
23
|
+
* the handful of actions executed before the heal fired. Because of this, the
|
|
24
|
+
* guard deliberately gates on ACTION-PERFORMABILITY, not on exact snapshot
|
|
25
|
+
* identity: the page legitimately differs run-to-run (timestamps, session
|
|
26
|
+
* chrome, ad slots, list ordering), so a hard `snapshotHash` equality gate
|
|
27
|
+
* would heal on nearly every replay and defeat the purpose. `snapshotHash`
|
|
28
|
+
* drift is at most a secondary heuristic; the real question the guard answers
|
|
29
|
+
* is "can THIS action still be performed against the page in front of me?".
|
|
30
|
+
*
|
|
31
|
+
* This module is contracts only — no executor logic. The pure guard core
|
|
32
|
+
* ({@link ReplayGuard}) is kept separate from the IO executor
|
|
33
|
+
* ({@link ReplayController}) so the decision logic unit-tests without a browser.
|
|
34
|
+
*/
|
|
35
|
+
/**
|
|
36
|
+
* Strict goal-similarity bar for selecting a replay candidate. Far higher than
|
|
37
|
+
* the 0.5 hint-injection threshold used by {@link TrajectoryStore.findBestMatch}:
|
|
38
|
+
* an imperfect reference is fine to *show* the LLM as a hint, but replaying it
|
|
39
|
+
* verbatim against the live page demands a near-exact task match.
|
|
40
|
+
*/
|
|
41
|
+
export const DEFAULT_REPLAY_SIMILARITY_THRESHOLD = 0.85;
|
|
42
|
+
//# sourceMappingURL=contracts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contracts.js","sourceRoot":"","sources":["../../../src/runner/replay/contracts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAUH;;;;;GAKG;AACH,MAAM,CAAC,MAAM,mCAAmC,GAAG,IAAI,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workflow Replay — the IO executor.
|
|
3
|
+
*
|
|
4
|
+
* Drives the live driver + the pure {@link ReplayGuard} through a
|
|
5
|
+
* {@link ReplayPlan} with ZERO per-action LLM calls. Per step:
|
|
6
|
+
* observe → guard.check (abort → heal) → driver.execute (error → heal) →
|
|
7
|
+
* verify expected effect when present (fail → heal).
|
|
8
|
+
* After every step replays cleanly, a single {@link ReplayContext.verifyGoal}
|
|
9
|
+
* call (the only permitted model round-trip) decides whether the goal was
|
|
10
|
+
* actually achieved — replay never blindly claims success.
|
|
11
|
+
*
|
|
12
|
+
* The first guard/execute/effect failure ABORTS into a `healed` outcome carrying
|
|
13
|
+
* the live page state, so the runner resumes its per-action loop from exactly
|
|
14
|
+
* where replay stopped. A wrong replay therefore costs at most a handful of fast
|
|
15
|
+
* browser actions before control returns to the agent.
|
|
16
|
+
*/
|
|
17
|
+
import type { ReplayContext, ReplayController, ReplayOutcome, ReplayPlan } from './contracts.js';
|
|
18
|
+
/** Default {@link ReplayController}: self-healing, zero per-action LLM calls. */
|
|
19
|
+
export declare class SelfHealingReplayController implements ReplayController {
|
|
20
|
+
replay(plan: ReplayPlan, ctx: ReplayContext): Promise<ReplayOutcome>;
|
|
21
|
+
private heal;
|
|
22
|
+
private safeObserve;
|
|
23
|
+
private minimalState;
|
|
24
|
+
}
|
|
25
|
+
/** Factory mirroring the rest of the replay module's construction style. */
|
|
26
|
+
export declare function createReplayController(): ReplayController;
|
|
27
|
+
//# sourceMappingURL=controller.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../../src/runner/replay/controller.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,OAAO,KAAK,EACV,aAAa,EACb,gBAAgB,EAChB,aAAa,EACb,UAAU,EAEX,MAAM,gBAAgB,CAAC;AA2CxB,iFAAiF;AACjF,qBAAa,2BAA4B,YAAW,gBAAgB;IAC5D,MAAM,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC;IAoI1E,OAAO,CAAC,IAAI;YAuBE,WAAW;IAQzB,OAAO,CAAC,YAAY;CAGrB;AAED,4EAA4E;AAC5E,wBAAgB,sBAAsB,IAAI,gBAAgB,CAEzD"}
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workflow Replay — the IO executor.
|
|
3
|
+
*
|
|
4
|
+
* Drives the live driver + the pure {@link ReplayGuard} through a
|
|
5
|
+
* {@link ReplayPlan} with ZERO per-action LLM calls. Per step:
|
|
6
|
+
* observe → guard.check (abort → heal) → driver.execute (error → heal) →
|
|
7
|
+
* verify expected effect when present (fail → heal).
|
|
8
|
+
* After every step replays cleanly, a single {@link ReplayContext.verifyGoal}
|
|
9
|
+
* call (the only permitted model round-trip) decides whether the goal was
|
|
10
|
+
* actually achieved — replay never blindly claims success.
|
|
11
|
+
*
|
|
12
|
+
* The first guard/execute/effect failure ABORTS into a `healed` outcome carrying
|
|
13
|
+
* the live page state, so the runner resumes its per-action loop from exactly
|
|
14
|
+
* where replay stopped. A wrong replay therefore costs at most a handful of fast
|
|
15
|
+
* browser actions before control returns to the agent.
|
|
16
|
+
*/
|
|
17
|
+
function errMsg(err) {
|
|
18
|
+
return err instanceof Error ? err.message : String(err);
|
|
19
|
+
}
|
|
20
|
+
function hasStateChanged(pre, post) {
|
|
21
|
+
return pre.url !== post.url || pre.title !== post.title || pre.snapshot !== post.snapshot;
|
|
22
|
+
}
|
|
23
|
+
function buildTurn(turnNumber, state, step, extra) {
|
|
24
|
+
return {
|
|
25
|
+
turn: turnNumber,
|
|
26
|
+
state,
|
|
27
|
+
action: step.action,
|
|
28
|
+
reasoning: 'workflow-replay (zero-LLM)',
|
|
29
|
+
durationMs: extra.durationMs,
|
|
30
|
+
...(extra.expectedEffect !== undefined ? { expectedEffect: extra.expectedEffect } : {}),
|
|
31
|
+
...(extra.verified !== undefined ? { verified: extra.verified } : {}),
|
|
32
|
+
...(extra.verificationFailure !== undefined ? { verificationFailure: extra.verificationFailure } : {}),
|
|
33
|
+
...(extra.error !== undefined ? { error: extra.error } : {}),
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
function buildClaim(plan, finalState, completedSteps) {
|
|
37
|
+
return (`Replayed ${completedSteps} recorded step(s) from a prior successful run of a ` +
|
|
38
|
+
`near-identical goal (similarity ${plan.goalSimilarity.toFixed(2)}). ` +
|
|
39
|
+
`Final page: ${finalState.url} — "${finalState.title}".`);
|
|
40
|
+
}
|
|
41
|
+
/** Default {@link ReplayController}: self-healing, zero per-action LLM calls. */
|
|
42
|
+
export class SelfHealingReplayController {
|
|
43
|
+
async replay(plan, ctx) {
|
|
44
|
+
const totalSteps = plan.steps.length;
|
|
45
|
+
const turns = [];
|
|
46
|
+
ctx.onEvent?.({
|
|
47
|
+
type: 'replay-started',
|
|
48
|
+
trajectoryId: plan.trajectory.id,
|
|
49
|
+
totalSteps,
|
|
50
|
+
goalSimilarity: plan.goalSimilarity,
|
|
51
|
+
});
|
|
52
|
+
// Defensive: a plan with no steps can't be replayed. (The store filters
|
|
53
|
+
// empty trajectories out of findReplayCandidate, so this is a guard rail.)
|
|
54
|
+
if (totalSteps === 0) {
|
|
55
|
+
const lastState = (await this.safeObserve(ctx)) ?? this.minimalState(ctx);
|
|
56
|
+
return this.heal(ctx, turns, 0, totalSteps, lastState, 'replay plan had no steps');
|
|
57
|
+
}
|
|
58
|
+
let lastState;
|
|
59
|
+
for (let index = 0; index < totalSteps; index++) {
|
|
60
|
+
const step = plan.steps[index];
|
|
61
|
+
ctx.onEvent?.({ type: 'replay-step', index, totalSteps, action: step.action.action });
|
|
62
|
+
// -- observe current state (also the turn.state for this step) --
|
|
63
|
+
let preState;
|
|
64
|
+
try {
|
|
65
|
+
preState = await ctx.driver.observe();
|
|
66
|
+
}
|
|
67
|
+
catch (err) {
|
|
68
|
+
const recover = lastState ?? this.minimalState(ctx);
|
|
69
|
+
return this.heal(ctx, turns, index, totalSteps, recover, `observe failed before step ${index + 1}: ${errMsg(err)}`);
|
|
70
|
+
}
|
|
71
|
+
lastState = preState;
|
|
72
|
+
// Cooperative cancellation — surface as a heal so the runner's own
|
|
73
|
+
// abort check finalizes the run.
|
|
74
|
+
if (ctx.signal?.aborted) {
|
|
75
|
+
const reason = ctx.signal.reason ? String(ctx.signal.reason) : 'cancelled';
|
|
76
|
+
return this.heal(ctx, turns, index, totalSteps, preState, reason);
|
|
77
|
+
}
|
|
78
|
+
// -- pure guard: can this step still be performed? --
|
|
79
|
+
const guardResult = ctx.guard.check(step, { url: preState.url, snapshot: preState.snapshot });
|
|
80
|
+
if (guardResult.decision === 'abort') {
|
|
81
|
+
ctx.onEvent?.({ type: 'replay-guard-abort', index, reason: guardResult.reason });
|
|
82
|
+
return this.heal(ctx, turns, index, totalSteps, preState, guardResult.reason);
|
|
83
|
+
}
|
|
84
|
+
// -- execute --
|
|
85
|
+
const stepStartedAt = Date.now();
|
|
86
|
+
let execError;
|
|
87
|
+
try {
|
|
88
|
+
const result = await ctx.driver.execute(step.action);
|
|
89
|
+
if (!result.success)
|
|
90
|
+
execError = result.error ?? 'action reported failure';
|
|
91
|
+
}
|
|
92
|
+
catch (err) {
|
|
93
|
+
execError = errMsg(err);
|
|
94
|
+
}
|
|
95
|
+
if (execError) {
|
|
96
|
+
// Record the attempted (errored) turn so the timeline shows what was
|
|
97
|
+
// tried, then heal. This is the one case where turns.length exceeds
|
|
98
|
+
// completedSteps (the contract documents this).
|
|
99
|
+
turns.push(buildTurn(turns.length + 1, preState, step, {
|
|
100
|
+
verified: false,
|
|
101
|
+
error: execError,
|
|
102
|
+
durationMs: Date.now() - stepStartedAt,
|
|
103
|
+
...(step.expectedEffect !== undefined ? { expectedEffect: step.expectedEffect } : {}),
|
|
104
|
+
}));
|
|
105
|
+
return this.heal(ctx, turns, index, totalSteps, preState, `execute failed at step ${index + 1}: ${execError}`);
|
|
106
|
+
}
|
|
107
|
+
// -- observe post-state + verify the recorded effect when present --
|
|
108
|
+
let postState;
|
|
109
|
+
try {
|
|
110
|
+
postState = await ctx.driver.observe();
|
|
111
|
+
}
|
|
112
|
+
catch {
|
|
113
|
+
postState = preState;
|
|
114
|
+
}
|
|
115
|
+
lastState = postState;
|
|
116
|
+
let verified;
|
|
117
|
+
if (step.expectedEffect) {
|
|
118
|
+
const ev = ctx.verifyEffect({
|
|
119
|
+
expectedEffect: step.expectedEffect,
|
|
120
|
+
preActionState: preState,
|
|
121
|
+
postActionState: postState,
|
|
122
|
+
});
|
|
123
|
+
verified = ev.verified;
|
|
124
|
+
if (!ev.verified) {
|
|
125
|
+
const reason = ev.reason ?? 'expected effect not observed';
|
|
126
|
+
turns.push(buildTurn(turns.length + 1, preState, step, {
|
|
127
|
+
verified: false,
|
|
128
|
+
expectedEffect: step.expectedEffect,
|
|
129
|
+
verificationFailure: reason,
|
|
130
|
+
durationMs: Date.now() - stepStartedAt,
|
|
131
|
+
}));
|
|
132
|
+
ctx.onEvent?.({ type: 'replay-effect-failed', index, reason });
|
|
133
|
+
return this.heal(ctx, turns, index, totalSteps, postState, `effect verification failed at step ${index + 1}: ${reason}`);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
// No persisted effect — fall back to change-detection for the
|
|
138
|
+
// diagnostic `verified` flag only. Absence of change is NOT a heal
|
|
139
|
+
// signal: typing into a field or an idempotent click can leave the
|
|
140
|
+
// snapshot materially unchanged. The guard pre-check + execute-success
|
|
141
|
+
// + final goal verification remain the safety net here.
|
|
142
|
+
verified = hasStateChanged(preState, postState);
|
|
143
|
+
}
|
|
144
|
+
turns.push(buildTurn(turns.length + 1, preState, step, {
|
|
145
|
+
verified,
|
|
146
|
+
durationMs: Date.now() - stepStartedAt,
|
|
147
|
+
...(step.expectedEffect !== undefined ? { expectedEffect: step.expectedEffect } : {}),
|
|
148
|
+
}));
|
|
149
|
+
}
|
|
150
|
+
// -- all steps replayed: the single permitted LLM round-trip --
|
|
151
|
+
const finalState = (await this.safeObserve(ctx)) ?? lastState ?? this.minimalState(ctx);
|
|
152
|
+
const finalResult = buildClaim(plan, finalState, totalSteps);
|
|
153
|
+
const goalVerification = await ctx.verifyGoal(finalState, ctx.goal, finalResult);
|
|
154
|
+
ctx.onEvent?.({ type: 'replay-completed', completedSteps: totalSteps, achieved: goalVerification.achieved });
|
|
155
|
+
return {
|
|
156
|
+
kind: 'completed',
|
|
157
|
+
completedSteps: totalSteps,
|
|
158
|
+
totalSteps,
|
|
159
|
+
llmCallsUsed: 1,
|
|
160
|
+
turns,
|
|
161
|
+
lastState: finalState,
|
|
162
|
+
goalVerification,
|
|
163
|
+
finalResult,
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
heal(ctx, turns, completedSteps, totalSteps, lastState, reason) {
|
|
167
|
+
ctx.onEvent?.({ type: 'replay-healed', completedSteps, totalSteps, reason });
|
|
168
|
+
if (ctx.debug) {
|
|
169
|
+
console.log(`[Replay] healed after ${completedSteps}/${totalSteps} steps: ${reason}`);
|
|
170
|
+
}
|
|
171
|
+
return {
|
|
172
|
+
kind: 'healed',
|
|
173
|
+
completedSteps,
|
|
174
|
+
totalSteps,
|
|
175
|
+
llmCallsUsed: 0,
|
|
176
|
+
turns,
|
|
177
|
+
lastState,
|
|
178
|
+
reason,
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
async safeObserve(ctx) {
|
|
182
|
+
try {
|
|
183
|
+
return await ctx.driver.observe();
|
|
184
|
+
}
|
|
185
|
+
catch {
|
|
186
|
+
return undefined;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
minimalState(ctx) {
|
|
190
|
+
return { url: ctx.driver.getUrl?.() ?? '', title: '', snapshot: '' };
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
/** Factory mirroring the rest of the replay module's construction style. */
|
|
194
|
+
export function createReplayController() {
|
|
195
|
+
return new SelfHealingReplayController();
|
|
196
|
+
}
|
|
197
|
+
//# sourceMappingURL=controller.js.map
|