@namzu/sdk 38.2.1 → 40.0.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/CHANGELOG.md +851 -0
- package/dist/advisory/executor.d.ts +10 -1
- package/dist/advisory/executor.d.ts.map +1 -1
- package/dist/advisory/executor.js +5 -26
- package/dist/advisory/executor.js.map +1 -1
- package/dist/advisory/history.d.ts +9 -0
- package/dist/advisory/history.d.ts.map +1 -0
- package/dist/advisory/history.js +120 -0
- package/dist/advisory/history.js.map +1 -0
- package/dist/advisory/index.d.ts +1 -1
- package/dist/advisory/index.d.ts.map +1 -1
- package/dist/advisory/index.js.map +1 -1
- package/dist/agents/ReactiveAgent.d.ts.map +1 -1
- package/dist/agents/ReactiveAgent.js +3 -0
- package/dist/agents/ReactiveAgent.js.map +1 -1
- package/dist/agents/runAgent.d.ts +10 -0
- package/dist/agents/runAgent.d.ts.map +1 -1
- package/dist/agents/runAgent.js +3 -0
- package/dist/agents/runAgent.js.map +1 -1
- package/dist/compaction/manual.d.ts +6 -0
- package/dist/compaction/manual.d.ts.map +1 -1
- package/dist/compaction/manual.js +21 -2
- package/dist/compaction/manual.js.map +1 -1
- package/dist/compaction/summary.d.ts.map +1 -1
- package/dist/compaction/summary.js +4 -1
- package/dist/compaction/summary.js.map +1 -1
- package/dist/config/runtime.js +2 -2
- package/dist/config/runtime.js.map +1 -1
- package/dist/connector/mcp/adapter.d.ts.map +1 -1
- package/dist/connector/mcp/adapter.js +20 -6
- package/dist/connector/mcp/adapter.js.map +1 -1
- package/dist/contracts/schemas.js +1 -1
- package/dist/contracts/schemas.js.map +1 -1
- package/dist/eval/harness-protection.d.ts +18 -0
- package/dist/eval/harness-protection.d.ts.map +1 -0
- package/dist/eval/harness-protection.js +58 -0
- package/dist/eval/harness-protection.js.map +1 -0
- package/dist/eval/harness-verification.d.ts +6 -1
- package/dist/eval/harness-verification.d.ts.map +1 -1
- package/dist/eval/harness-verification.js +19 -2
- package/dist/eval/harness-verification.js.map +1 -1
- package/dist/eval/index.d.ts +1 -0
- package/dist/eval/index.d.ts.map +1 -1
- package/dist/eval/index.js.map +1 -1
- package/dist/manager/resident/activity.d.ts +50 -0
- package/dist/manager/resident/activity.d.ts.map +1 -0
- package/dist/manager/resident/activity.js +125 -0
- package/dist/manager/resident/activity.js.map +1 -0
- package/dist/manager/resident/agenda.d.ts +13 -1
- package/dist/manager/resident/agenda.d.ts.map +1 -1
- package/dist/manager/resident/agenda.js +40 -5
- package/dist/manager/resident/agenda.js.map +1 -1
- package/dist/manager/resident/consumption.d.ts +104 -0
- package/dist/manager/resident/consumption.d.ts.map +1 -0
- package/dist/manager/resident/consumption.js +233 -0
- package/dist/manager/resident/consumption.js.map +1 -0
- package/dist/manager/resident/evidence-recall.d.ts +24 -0
- package/dist/manager/resident/evidence-recall.d.ts.map +1 -0
- package/dist/manager/resident/evidence-recall.js +295 -0
- package/dist/manager/resident/evidence-recall.js.map +1 -0
- package/dist/manager/resident/history-disk.d.ts +10 -0
- package/dist/manager/resident/history-disk.d.ts.map +1 -0
- package/dist/manager/resident/history-disk.js +50 -0
- package/dist/manager/resident/history-disk.js.map +1 -0
- package/dist/manager/resident/history.d.ts +79 -0
- package/dist/manager/resident/history.d.ts.map +1 -0
- package/dist/manager/resident/history.js +203 -0
- package/dist/manager/resident/history.js.map +1 -0
- package/dist/manager/resident/initiative.d.ts.map +1 -1
- package/dist/manager/resident/initiative.js +11 -3
- package/dist/manager/resident/initiative.js.map +1 -1
- package/dist/manager/resident/learning-cycle.d.ts +131 -0
- package/dist/manager/resident/learning-cycle.d.ts.map +1 -0
- package/dist/manager/resident/learning-cycle.js +306 -0
- package/dist/manager/resident/learning-cycle.js.map +1 -0
- package/dist/manager/resident/learning-observation.d.ts +80 -0
- package/dist/manager/resident/learning-observation.d.ts.map +1 -0
- package/dist/manager/resident/learning-observation.js +22 -0
- package/dist/manager/resident/learning-observation.js.map +1 -0
- package/dist/manager/resident/learning-store.d.ts +106 -0
- package/dist/manager/resident/learning-store.d.ts.map +1 -0
- package/dist/manager/resident/learning-store.js +598 -0
- package/dist/manager/resident/learning-store.js.map +1 -0
- package/dist/manager/resident/learning.d.ts +246 -3
- package/dist/manager/resident/learning.d.ts.map +1 -1
- package/dist/manager/resident/learning.js +96 -6
- package/dist/manager/resident/learning.js.map +1 -1
- package/dist/manager/resident/outbox.d.ts +4 -4
- package/dist/manager/resident/store.d.ts +37 -4
- package/dist/manager/resident/store.d.ts.map +1 -1
- package/dist/manager/resident/store.js +27 -3
- package/dist/manager/resident/store.js.map +1 -1
- package/dist/manager/resident/tool-evidence.d.ts +71 -0
- package/dist/manager/resident/tool-evidence.d.ts.map +1 -0
- package/dist/manager/resident/tool-evidence.js +285 -0
- package/dist/manager/resident/tool-evidence.js.map +1 -0
- package/dist/manager/run/persistence.d.ts +8 -0
- package/dist/manager/run/persistence.d.ts.map +1 -1
- package/dist/manager/run/persistence.js +18 -0
- package/dist/manager/run/persistence.js.map +1 -1
- package/dist/plugin/loader.d.ts.map +1 -1
- package/dist/plugin/loader.js +5 -3
- package/dist/plugin/loader.js.map +1 -1
- package/dist/prompt/coding-agent-doctrine.d.ts +1 -1
- package/dist/prompt/coding-agent-doctrine.d.ts.map +1 -1
- package/dist/prompt/coding-agent-doctrine.js +2 -0
- package/dist/prompt/coding-agent-doctrine.js.map +1 -1
- package/dist/prompt/index.d.ts +2 -0
- package/dist/prompt/index.d.ts.map +1 -1
- package/dist/prompt/index.js +1 -0
- package/dist/prompt/index.js.map +1 -1
- package/dist/prompt/resident-learning.d.ts +19 -0
- package/dist/prompt/resident-learning.d.ts.map +1 -0
- package/dist/prompt/resident-learning.js +125 -0
- package/dist/prompt/resident-learning.js.map +1 -0
- package/dist/prompt/resident-step.d.ts +8 -1
- package/dist/prompt/resident-step.d.ts.map +1 -1
- package/dist/prompt/resident-step.js +65 -4
- package/dist/prompt/resident-step.js.map +1 -1
- package/dist/provider/collect-chat-completion.d.ts +2 -1
- package/dist/provider/collect-chat-completion.d.ts.map +1 -1
- package/dist/provider/collect-chat-completion.js +7 -6
- package/dist/provider/collect-chat-completion.js.map +1 -1
- package/dist/provider/fallback.d.ts.map +1 -1
- package/dist/provider/fallback.js +2 -1
- package/dist/provider/fallback.js.map +1 -1
- package/dist/provider/stream-text.d.ts +16 -0
- package/dist/provider/stream-text.d.ts.map +1 -0
- package/dist/provider/stream-text.js +51 -0
- package/dist/provider/stream-text.js.map +1 -0
- package/dist/public-runtime.d.ts +16 -4
- package/dist/public-runtime.d.ts.map +1 -1
- package/dist/public-runtime.js +17 -4
- package/dist/public-runtime.js.map +1 -1
- package/dist/public-tools.d.ts +13 -0
- package/dist/public-tools.d.ts.map +1 -1
- package/dist/public-tools.js +16 -0
- package/dist/public-tools.js.map +1 -1
- package/dist/public-types.d.ts +15 -3
- package/dist/public-types.d.ts.map +1 -1
- package/dist/registry/tool/execute.d.ts.map +1 -1
- package/dist/registry/tool/execute.js +2 -3
- package/dist/registry/tool/execute.js.map +1 -1
- package/dist/registry/tool/portable.d.ts +65 -0
- package/dist/registry/tool/portable.d.ts.map +1 -0
- package/dist/registry/tool/portable.js +244 -0
- package/dist/registry/tool/portable.js.map +1 -0
- package/dist/registry/tool/schema.d.ts +32 -5
- package/dist/registry/tool/schema.d.ts.map +1 -1
- package/dist/registry/tool/schema.js +35 -9
- package/dist/registry/tool/schema.js.map +1 -1
- package/dist/registry/toolset/catalog.js +8 -8
- package/dist/registry/toolset/catalog.js.map +1 -1
- package/dist/run/LimitChecker.js +3 -3
- package/dist/run/LimitChecker.js.map +1 -1
- package/dist/run/evidence-query.d.ts +41 -0
- package/dist/run/evidence-query.d.ts.map +1 -0
- package/dist/run/evidence-query.js +270 -0
- package/dist/run/evidence-query.js.map +1 -0
- package/dist/run/evidence-recall.d.ts +99 -0
- package/dist/run/evidence-recall.d.ts.map +1 -0
- package/dist/run/evidence-recall.js +633 -0
- package/dist/run/evidence-recall.js.map +1 -0
- package/dist/run/index.d.ts +2 -0
- package/dist/run/index.d.ts.map +1 -1
- package/dist/run/index.js +1 -0
- package/dist/run/index.js.map +1 -1
- package/dist/run/json-claim-verifier.d.ts +83 -0
- package/dist/run/json-claim-verifier.d.ts.map +1 -0
- package/dist/run/json-claim-verifier.js +200 -0
- package/dist/run/json-claim-verifier.js.map +1 -0
- package/dist/run/preparation-context-error.d.ts +10 -0
- package/dist/run/preparation-context-error.d.ts.map +1 -0
- package/dist/run/preparation-context-error.js +15 -0
- package/dist/run/preparation-context-error.js.map +1 -0
- package/dist/run-query/index.d.ts +3 -1
- package/dist/run-query/index.d.ts.map +1 -1
- package/dist/runtime/jobs/awaited-jobs.d.ts +215 -0
- package/dist/runtime/jobs/awaited-jobs.d.ts.map +1 -0
- package/dist/runtime/jobs/awaited-jobs.js +259 -0
- package/dist/runtime/jobs/awaited-jobs.js.map +1 -0
- package/dist/runtime/jobs/registry.d.ts +33 -2
- package/dist/runtime/jobs/registry.d.ts.map +1 -1
- package/dist/runtime/jobs/registry.js +37 -0
- package/dist/runtime/jobs/registry.js.map +1 -1
- package/dist/runtime/query/callback-inference.d.ts +8 -0
- package/dist/runtime/query/callback-inference.d.ts.map +1 -0
- package/dist/runtime/query/callback-inference.js +89 -0
- package/dist/runtime/query/callback-inference.js.map +1 -0
- package/dist/runtime/query/checkpoint.d.ts +4 -0
- package/dist/runtime/query/checkpoint.d.ts.map +1 -1
- package/dist/runtime/query/checkpoint.js +13 -0
- package/dist/runtime/query/checkpoint.js.map +1 -1
- package/dist/runtime/query/events.d.ts +1 -0
- package/dist/runtime/query/events.d.ts.map +1 -1
- package/dist/runtime/query/events.js +18 -0
- package/dist/runtime/query/events.js.map +1 -1
- package/dist/runtime/query/executor.d.ts +35 -1
- package/dist/runtime/query/executor.d.ts.map +1 -1
- package/dist/runtime/query/executor.js +77 -8
- package/dist/runtime/query/executor.js.map +1 -1
- package/dist/runtime/query/file-evidence-context.d.ts +5 -0
- package/dist/runtime/query/file-evidence-context.d.ts.map +1 -0
- package/dist/runtime/query/file-evidence-context.js +180 -0
- package/dist/runtime/query/file-evidence-context.js.map +1 -0
- package/dist/runtime/query/file-evidence-replay.d.ts +260 -0
- package/dist/runtime/query/file-evidence-replay.d.ts.map +1 -0
- package/dist/runtime/query/file-evidence-replay.js +647 -0
- package/dist/runtime/query/file-evidence-replay.js.map +1 -0
- package/dist/runtime/query/file-evidence-seed.d.ts +50 -0
- package/dist/runtime/query/file-evidence-seed.d.ts.map +1 -0
- package/dist/runtime/query/file-evidence-seed.js +100 -0
- package/dist/runtime/query/file-evidence-seed.js.map +1 -0
- package/dist/runtime/query/guard.d.ts.map +1 -1
- package/dist/runtime/query/guard.js +4 -0
- package/dist/runtime/query/guard.js.map +1 -1
- package/dist/runtime/query/index.d.ts +10 -1
- package/dist/runtime/query/index.d.ts.map +1 -1
- package/dist/runtime/query/index.js +133 -26
- package/dist/runtime/query/index.js.map +1 -1
- package/dist/runtime/query/iteration/index.d.ts +92 -36
- package/dist/runtime/query/iteration/index.d.ts.map +1 -1
- package/dist/runtime/query/iteration/index.js +420 -117
- package/dist/runtime/query/iteration/index.js.map +1 -1
- package/dist/runtime/query/iteration/phases/advisory.d.ts +2 -1
- package/dist/runtime/query/iteration/phases/advisory.d.ts.map +1 -1
- package/dist/runtime/query/iteration/phases/advisory.js +2 -1
- package/dist/runtime/query/iteration/phases/advisory.js.map +1 -1
- package/dist/runtime/query/iteration/phases/context.d.ts +12 -1
- package/dist/runtime/query/iteration/phases/context.d.ts.map +1 -1
- package/dist/runtime/query/iteration/phases/context.js.map +1 -1
- package/dist/runtime/query/iteration/phases/tool-review.d.ts.map +1 -1
- package/dist/runtime/query/iteration/phases/tool-review.js +8 -1
- package/dist/runtime/query/iteration/phases/tool-review.js.map +1 -1
- package/dist/runtime/query/iteration/provider-rejected-image.d.ts +2 -1
- package/dist/runtime/query/iteration/provider-rejected-image.d.ts.map +1 -1
- package/dist/runtime/query/iteration/provider-rejected-image.js +5 -2
- package/dist/runtime/query/iteration/provider-rejected-image.js.map +1 -1
- package/dist/runtime/query/iteration/stream-turn.d.ts +4 -1
- package/dist/runtime/query/iteration/stream-turn.d.ts.map +1 -1
- package/dist/runtime/query/iteration/stream-turn.js +22 -8
- package/dist/runtime/query/iteration/stream-turn.js.map +1 -1
- package/dist/runtime/query/plugin-hooks.d.ts +14 -0
- package/dist/runtime/query/plugin-hooks.d.ts.map +1 -1
- package/dist/runtime/query/plugin-hooks.js +18 -0
- package/dist/runtime/query/plugin-hooks.js.map +1 -1
- package/dist/runtime/query/repeat-call.d.ts +17 -4
- package/dist/runtime/query/repeat-call.d.ts.map +1 -1
- package/dist/runtime/query/repeat-call.js +26 -19
- package/dist/runtime/query/repeat-call.js.map +1 -1
- package/dist/runtime/query/resume-pending.d.ts +18 -33
- package/dist/runtime/query/resume-pending.d.ts.map +1 -1
- package/dist/runtime/query/resume-pending.js +59 -42
- package/dist/runtime/query/resume-pending.js.map +1 -1
- package/dist/runtime/query/review-policy.d.ts +4 -4
- package/dist/runtime/query/review-policy.d.ts.map +1 -1
- package/dist/runtime/query/review-policy.js +10 -9
- package/dist/runtime/query/review-policy.js.map +1 -1
- package/dist/runtime/query/sandbox-lifecycle.d.ts.map +1 -1
- package/dist/runtime/query/sandbox-lifecycle.js +4 -0
- package/dist/runtime/query/sandbox-lifecycle.js.map +1 -1
- package/dist/runtime/query/steering.d.ts +11 -1
- package/dist/runtime/query/steering.d.ts.map +1 -1
- package/dist/runtime/query/steering.js +12 -1
- package/dist/runtime/query/steering.js.map +1 -1
- package/dist/runtime/query/tool-output-budget.d.ts +10 -6
- package/dist/runtime/query/tool-output-budget.d.ts.map +1 -1
- package/dist/runtime/query/tool-output-budget.js +54 -12
- package/dist/runtime/query/tool-output-budget.js.map +1 -1
- package/dist/runtime/query/tooling.d.ts +5 -1
- package/dist/runtime/query/tooling.d.ts.map +1 -1
- package/dist/runtime/query/tooling.js +5 -0
- package/dist/runtime/query/tooling.js.map +1 -1
- package/dist/scheduler/completion-inbox.d.ts +49 -0
- package/dist/scheduler/completion-inbox.d.ts.map +1 -1
- package/dist/scheduler/completion-inbox.js +122 -2
- package/dist/scheduler/completion-inbox.js.map +1 -1
- package/dist/store/evidence/compaction-archive.d.ts +109 -0
- package/dist/store/evidence/compaction-archive.d.ts.map +1 -0
- package/dist/store/evidence/compaction-archive.js +125 -0
- package/dist/store/evidence/compaction-archive.js.map +1 -0
- package/dist/store/evidence/compaction-provenance.d.ts +7 -0
- package/dist/store/evidence/compaction-provenance.d.ts.map +1 -0
- package/dist/store/evidence/compaction-provenance.js +49 -0
- package/dist/store/evidence/compaction-provenance.js.map +1 -0
- package/dist/store/evidence/compaction-text.d.ts +16 -0
- package/dist/store/evidence/compaction-text.d.ts.map +1 -0
- package/dist/store/evidence/compaction-text.js +51 -0
- package/dist/store/evidence/compaction-text.js.map +1 -0
- package/dist/store/evidence/disk.d.ts +11 -0
- package/dist/store/evidence/disk.d.ts.map +1 -0
- package/dist/store/evidence/disk.js +367 -0
- package/dist/store/evidence/disk.js.map +1 -0
- package/dist/store/evidence/format.d.ts +25 -0
- package/dist/store/evidence/format.d.ts.map +1 -0
- package/dist/store/evidence/format.js +115 -0
- package/dist/store/evidence/format.js.map +1 -0
- package/dist/store/evidence/index-page.d.ts +208 -0
- package/dist/store/evidence/index-page.d.ts.map +1 -0
- package/dist/store/evidence/index-page.js +262 -0
- package/dist/store/evidence/index-page.js.map +1 -0
- package/dist/store/evidence/io.d.ts +24 -0
- package/dist/store/evidence/io.d.ts.map +1 -0
- package/dist/store/evidence/io.js +69 -0
- package/dist/store/evidence/io.js.map +1 -0
- package/dist/store/evidence/linked.d.ts +9 -0
- package/dist/store/evidence/linked.d.ts.map +1 -0
- package/dist/store/evidence/linked.js +314 -0
- package/dist/store/evidence/linked.js.map +1 -0
- package/dist/store/evidence/passages.d.ts +15 -0
- package/dist/store/evidence/passages.d.ts.map +1 -0
- package/dist/store/evidence/passages.js +72 -0
- package/dist/store/evidence/passages.js.map +1 -0
- package/dist/store/evidence/record-chain.d.ts +42 -0
- package/dist/store/evidence/record-chain.d.ts.map +1 -0
- package/dist/store/evidence/record-chain.js +111 -0
- package/dist/store/evidence/record-chain.js.map +1 -0
- package/dist/store/evidence/search-input.d.ts +21 -0
- package/dist/store/evidence/search-input.d.ts.map +1 -0
- package/dist/store/evidence/search-input.js +44 -0
- package/dist/store/evidence/search-input.js.map +1 -0
- package/dist/store/evidence/selection.d.ts +9 -0
- package/dist/store/evidence/selection.d.ts.map +1 -0
- package/dist/store/evidence/selection.js +17 -0
- package/dist/store/evidence/selection.js.map +1 -0
- package/dist/store/evidence/source-kind.d.ts +11 -0
- package/dist/store/evidence/source-kind.d.ts.map +1 -0
- package/dist/store/evidence/source-kind.js +26 -0
- package/dist/store/evidence/source-kind.js.map +1 -0
- package/dist/store/evidence/source-text.d.ts +51 -0
- package/dist/store/evidence/source-text.d.ts.map +1 -0
- package/dist/store/evidence/source-text.js +213 -0
- package/dist/store/evidence/source-text.js.map +1 -0
- package/dist/store/evidence/types.d.ts +162 -0
- package/dist/store/evidence/types.d.ts.map +1 -0
- package/dist/store/evidence/types.js +2 -0
- package/dist/store/evidence/types.js.map +1 -0
- package/dist/store/memory/disk.d.ts +2 -0
- package/dist/store/memory/disk.d.ts.map +1 -1
- package/dist/store/memory/disk.js +2 -1
- package/dist/store/memory/disk.js.map +1 -1
- package/dist/store/run/disk.d.ts +10 -0
- package/dist/store/run/disk.d.ts.map +1 -1
- package/dist/store/run/disk.js +87 -7
- package/dist/store/run/disk.js.map +1 -1
- package/dist/store/run/memory.d.ts +1 -0
- package/dist/store/run/memory.d.ts.map +1 -1
- package/dist/store/run/memory.js +10 -0
- package/dist/store/run/memory.js.map +1 -1
- package/dist/store/run/tool-executions.d.ts +13 -0
- package/dist/store/run/tool-executions.d.ts.map +1 -0
- package/dist/store/run/tool-executions.js +99 -0
- package/dist/store/run/tool-executions.js.map +1 -0
- package/dist/store/session/index.d.ts +2 -0
- package/dist/store/session/index.d.ts.map +1 -1
- package/dist/store/session/index.js +1 -0
- package/dist/store/session/index.js.map +1 -1
- package/dist/store/session/sqlite.d.ts +57 -0
- package/dist/store/session/sqlite.d.ts.map +1 -0
- package/dist/store/session/sqlite.js +430 -0
- package/dist/store/session/sqlite.js.map +1 -0
- package/dist/tools/builtins/bash.d.ts.map +1 -1
- package/dist/tools/builtins/bash.js +4 -10
- package/dist/tools/builtins/bash.js.map +1 -1
- package/dist/tools/builtins/edit-apply.d.ts +126 -0
- package/dist/tools/builtins/edit-apply.d.ts.map +1 -0
- package/dist/tools/builtins/edit-apply.js +360 -0
- package/dist/tools/builtins/edit-apply.js.map +1 -0
- package/dist/tools/builtins/edit.d.ts +143 -1
- package/dist/tools/builtins/edit.d.ts.map +1 -1
- package/dist/tools/builtins/edit.js +37 -219
- package/dist/tools/builtins/edit.js.map +1 -1
- package/dist/tools/builtins/index.d.ts +1 -0
- package/dist/tools/builtins/index.d.ts.map +1 -1
- package/dist/tools/builtins/index.js +9 -3
- package/dist/tools/builtins/index.js.map +1 -1
- package/dist/tools/builtins/job.d.ts.map +1 -1
- package/dist/tools/builtins/job.js +5 -6
- package/dist/tools/builtins/job.js.map +1 -1
- package/dist/tools/builtins/read-file.d.ts +2 -2
- package/dist/tools/builtins/read-file.d.ts.map +1 -1
- package/dist/tools/builtins/read-file.js +50 -65
- package/dist/tools/builtins/read-file.js.map +1 -1
- package/dist/tools/builtins/read-render.d.ts +56 -0
- package/dist/tools/builtins/read-render.d.ts.map +1 -0
- package/dist/tools/builtins/read-render.js +73 -0
- package/dist/tools/builtins/read-render.js.map +1 -0
- package/dist/tools/builtins/wait-for-job-bounds.d.ts +67 -0
- package/dist/tools/builtins/wait-for-job-bounds.d.ts.map +1 -0
- package/dist/tools/builtins/wait-for-job-bounds.js +108 -0
- package/dist/tools/builtins/wait-for-job-bounds.js.map +1 -0
- package/dist/tools/builtins/wait-for-job.d.ts +6 -0
- package/dist/tools/builtins/wait-for-job.d.ts.map +1 -0
- package/dist/tools/builtins/wait-for-job.js +162 -0
- package/dist/tools/builtins/wait-for-job.js.map +1 -0
- package/dist/tools/builtins/write-file.js +7 -2
- package/dist/tools/builtins/write-file.js.map +1 -1
- package/dist/tools/coordinator/index.d.ts.map +1 -1
- package/dist/tools/coordinator/index.js +1 -7
- package/dist/tools/coordinator/index.js.map +1 -1
- package/dist/tools/defineTool.d.ts +2 -1
- package/dist/tools/defineTool.d.ts.map +1 -1
- package/dist/tools/defineTool.js +1 -1
- package/dist/tools/defineTool.js.map +1 -1
- package/dist/tools/file-read-tracker.d.ts.map +1 -1
- package/dist/tools/file-read-tracker.js +90 -3
- package/dist/tools/file-read-tracker.js.map +1 -1
- package/dist/tools/resident-history.d.ts +10 -0
- package/dist/tools/resident-history.d.ts.map +1 -0
- package/dist/tools/resident-history.js +80 -0
- package/dist/tools/resident-history.js.map +1 -0
- package/dist/tools/resident-tool-evidence.d.ts +5 -0
- package/dist/tools/resident-tool-evidence.d.ts.map +1 -0
- package/dist/tools/resident-tool-evidence.js +57 -0
- package/dist/tools/resident-tool-evidence.js.map +1 -0
- package/dist/types/advisory/config.d.ts +7 -0
- package/dist/types/advisory/config.d.ts.map +1 -1
- package/dist/types/agent/reactive.d.ts +1 -0
- package/dist/types/agent/reactive.d.ts.map +1 -1
- package/dist/types/authorization/index.d.ts +9 -9
- package/dist/types/authorization/index.d.ts.map +1 -1
- package/dist/types/authorization/index.js +1 -1
- package/dist/types/authorization/index.js.map +1 -1
- package/dist/types/hitl/index.d.ts +4 -0
- package/dist/types/hitl/index.d.ts.map +1 -1
- package/dist/types/hitl/index.js.map +1 -1
- package/dist/types/message/index.d.ts +16 -2
- package/dist/types/message/index.d.ts.map +1 -1
- package/dist/types/message/index.js +10 -1
- package/dist/types/message/index.js.map +1 -1
- package/dist/types/provider/chat.d.ts +2 -0
- package/dist/types/provider/chat.d.ts.map +1 -1
- package/dist/types/provider/stream.d.ts +4 -0
- package/dist/types/provider/stream.d.ts.map +1 -1
- package/dist/types/run/answer-review.d.ts +34 -3
- package/dist/types/run/answer-review.d.ts.map +1 -1
- package/dist/types/run/config.d.ts +3 -0
- package/dist/types/run/config.d.ts.map +1 -1
- package/dist/types/run/entity.d.ts +20 -0
- package/dist/types/run/entity.d.ts.map +1 -1
- package/dist/types/run/events.d.ts +31 -8
- package/dist/types/run/events.d.ts.map +1 -1
- package/dist/types/run/events.js.map +1 -1
- package/dist/types/run/prepare-step.d.ts +53 -8
- package/dist/types/run/prepare-step.d.ts.map +1 -1
- package/dist/types/run/store.d.ts +29 -4
- package/dist/types/run/store.d.ts.map +1 -1
- package/dist/types/run/store.js +0 -28
- package/dist/types/run/store.js.map +1 -1
- package/dist/types/sandbox/index.d.ts +15 -14
- package/dist/types/sandbox/index.d.ts.map +1 -1
- package/dist/types/sandbox/index.js.map +1 -1
- package/dist/types/tool/index.d.ts +124 -1
- package/dist/types/tool/index.d.ts.map +1 -1
- package/dist/types/tool/index.js.map +1 -1
- package/dist/utils/await-with-abort.d.ts +8 -0
- package/dist/utils/await-with-abort.d.ts.map +1 -0
- package/dist/utils/await-with-abort.js +28 -0
- package/dist/utils/await-with-abort.js.map +1 -0
- package/dist/utils/env.d.ts +19 -0
- package/dist/utils/env.d.ts.map +1 -0
- package/dist/utils/env.js +25 -0
- package/dist/utils/env.js.map +1 -0
- package/dist/utils/evidence-time.d.ts +3 -0
- package/dist/utils/evidence-time.d.ts.map +1 -0
- package/dist/utils/evidence-time.js +10 -0
- package/dist/utils/evidence-time.js.map +1 -0
- package/dist/utils/evidence-tokens.d.ts +13 -0
- package/dist/utils/evidence-tokens.d.ts.map +1 -0
- package/dist/utils/evidence-tokens.js +29 -0
- package/dist/utils/evidence-tokens.js.map +1 -0
- package/package.json +1 -1
- package/src/advisory/executor.ts +15 -30
- package/src/advisory/history.ts +126 -0
- package/src/advisory/index.ts +5 -1
- package/src/agents/ReactiveAgent.ts +3 -0
- package/src/agents/runAgent.ts +14 -1
- package/src/compaction/manual.ts +30 -2
- package/src/compaction/summary.ts +4 -1
- package/src/config/runtime.ts +2 -2
- package/src/connector/mcp/adapter.ts +20 -6
- package/src/contracts/schemas.ts +1 -1
- package/src/eval/harness-protection.ts +79 -0
- package/src/eval/harness-verification.ts +31 -1
- package/src/eval/index.ts +1 -0
- package/src/manager/resident/activity.ts +187 -0
- package/src/manager/resident/agenda.ts +59 -5
- package/src/manager/resident/consumption.ts +311 -0
- package/src/manager/resident/evidence-recall.ts +363 -0
- package/src/manager/resident/history-disk.ts +63 -0
- package/src/manager/resident/history.ts +312 -0
- package/src/manager/resident/initiative.ts +13 -3
- package/src/manager/resident/learning-cycle.ts +499 -0
- package/src/manager/resident/learning-observation.ts +39 -0
- package/src/manager/resident/learning-store.ts +813 -0
- package/src/manager/resident/learning.ts +132 -8
- package/src/manager/resident/store.ts +31 -3
- package/src/manager/resident/tool-evidence.ts +412 -0
- package/src/manager/run/persistence.ts +18 -0
- package/src/plugin/loader.ts +8 -3
- package/src/prompt/coding-agent-doctrine.ts +2 -0
- package/src/prompt/index.ts +2 -0
- package/src/prompt/resident-learning.ts +143 -0
- package/src/prompt/resident-step.ts +83 -3
- package/src/provider/collect-chat-completion.ts +7 -6
- package/src/provider/fallback.ts +2 -1
- package/src/provider/stream-text.ts +56 -0
- package/src/public-runtime.ts +39 -1
- package/src/public-tools.ts +21 -0
- package/src/public-types.ts +98 -0
- package/src/registry/tool/execute.ts +2 -4
- package/src/registry/tool/portable.ts +264 -0
- package/src/registry/tool/schema.ts +38 -8
- package/src/registry/toolset/catalog.ts +8 -9
- package/src/run/LimitChecker.ts +3 -3
- package/src/run/evidence-query.ts +333 -0
- package/src/run/evidence-recall.ts +854 -0
- package/src/run/index.ts +11 -0
- package/src/run/json-claim-verifier.ts +298 -0
- package/src/run/preparation-context-error.ts +16 -0
- package/src/run-query/index.ts +1 -1
- package/src/runtime/jobs/awaited-jobs.ts +271 -0
- package/src/runtime/jobs/registry.ts +50 -0
- package/src/runtime/query/callback-inference.ts +94 -0
- package/src/runtime/query/checkpoint.ts +14 -0
- package/src/runtime/query/events.ts +22 -0
- package/src/runtime/query/executor.ts +100 -10
- package/src/runtime/query/file-evidence-context.ts +209 -0
- package/src/runtime/query/file-evidence-replay.ts +776 -0
- package/src/runtime/query/file-evidence-seed.ts +126 -0
- package/src/runtime/query/guard.ts +2 -0
- package/src/runtime/query/index.ts +153 -27
- package/src/runtime/query/iteration/index.ts +467 -110
- package/src/runtime/query/iteration/phases/advisory.ts +3 -0
- package/src/runtime/query/iteration/phases/context.ts +12 -0
- package/src/runtime/query/iteration/phases/tool-review.ts +7 -0
- package/src/runtime/query/iteration/provider-rejected-image.ts +6 -1
- package/src/runtime/query/iteration/stream-turn.ts +35 -8
- package/src/runtime/query/plugin-hooks.ts +20 -0
- package/src/runtime/query/repeat-call.ts +28 -18
- package/src/runtime/query/resume-pending.ts +65 -40
- package/src/runtime/query/review-policy.ts +13 -9
- package/src/runtime/query/sandbox-lifecycle.ts +3 -0
- package/src/runtime/query/steering.ts +11 -0
- package/src/runtime/query/tool-output-budget.ts +65 -13
- package/src/runtime/query/tooling.ts +10 -1
- package/src/scheduler/completion-inbox.ts +124 -2
- package/src/store/evidence/compaction-archive.ts +139 -0
- package/src/store/evidence/compaction-provenance.ts +52 -0
- package/src/store/evidence/compaction-text.ts +61 -0
- package/src/store/evidence/disk.ts +461 -0
- package/src/store/evidence/format.ts +126 -0
- package/src/store/evidence/index-page.ts +292 -0
- package/src/store/evidence/io.ts +95 -0
- package/src/store/evidence/linked.ts +365 -0
- package/src/store/evidence/passages.ts +88 -0
- package/src/store/evidence/record-chain.ts +108 -0
- package/src/store/evidence/search-input.ts +62 -0
- package/src/store/evidence/selection.ts +25 -0
- package/src/store/evidence/source-kind.ts +36 -0
- package/src/store/evidence/source-text.ts +285 -0
- package/src/store/evidence/types.ts +177 -0
- package/src/store/memory/disk.ts +4 -1
- package/src/store/run/disk.ts +110 -8
- package/src/store/run/memory.ts +10 -0
- package/src/store/run/tool-executions.ts +112 -0
- package/src/store/session/index.ts +2 -0
- package/src/store/session/sqlite.ts +584 -0
- package/src/tools/builtins/bash.ts +4 -10
- package/src/tools/builtins/edit-apply.ts +456 -0
- package/src/tools/builtins/edit.ts +39 -270
- package/src/tools/builtins/index.ts +9 -3
- package/src/tools/builtins/job.ts +5 -6
- package/src/tools/builtins/read-file.ts +56 -77
- package/src/tools/builtins/read-render.ts +104 -0
- package/src/tools/builtins/wait-for-job-bounds.ts +179 -0
- package/src/tools/builtins/wait-for-job.ts +184 -0
- package/src/tools/builtins/write-file.ts +7 -2
- package/src/tools/coordinator/index.ts +1 -7
- package/src/tools/defineTool.ts +4 -2
- package/src/tools/file-read-tracker.ts +86 -2
- package/src/tools/resident-history.ts +86 -0
- package/src/tools/resident-tool-evidence.ts +68 -0
- package/src/types/advisory/config.ts +7 -0
- package/src/types/agent/reactive.ts +1 -0
- package/src/types/authorization/index.ts +2 -2
- package/src/types/hitl/index.ts +4 -0
- package/src/types/message/index.ts +22 -0
- package/src/types/provider/chat.ts +2 -0
- package/src/types/provider/stream.ts +4 -0
- package/src/types/run/answer-review.ts +34 -3
- package/src/types/run/config.ts +3 -0
- package/src/types/run/entity.ts +21 -0
- package/src/types/run/events.ts +31 -8
- package/src/types/run/prepare-step.ts +59 -8
- package/src/types/run/store.ts +35 -4
- package/src/types/sandbox/index.ts +15 -14
- package/src/types/tool/index.ts +123 -1
- package/src/utils/await-with-abort.ts +26 -0
- package/src/utils/env.ts +23 -0
- package/src/utils/evidence-time.ts +9 -0
- package/src/utils/evidence-tokens.ts +32 -0
|
@@ -0,0 +1,647 @@
|
|
|
1
|
+
import { resolve } from 'node:path';
|
|
2
|
+
import { isClearedToolResult } from '../../compaction/tool-result-editing.js';
|
|
3
|
+
import { replayEditCallWithin } from '../../tools/builtins/edit-apply.js';
|
|
4
|
+
import { EditTool } from '../../tools/builtins/edit.js';
|
|
5
|
+
import { ReadFileTool } from '../../tools/builtins/read-file.js';
|
|
6
|
+
import { renderNumberedRead, resolveReadWindow, } from '../../tools/builtins/read-render.js';
|
|
7
|
+
import { WriteFileTool } from '../../tools/builtins/write-file.js';
|
|
8
|
+
import { isSkippedToolResult } from './plugin-hooks.js';
|
|
9
|
+
/**
|
|
10
|
+
* Reconstructing a file's body from calls the conversation can still see.
|
|
11
|
+
*
|
|
12
|
+
* One module because two callers need the same answer and must not each have
|
|
13
|
+
* their own idea of it: the derived work context asks "is this ledger entry's
|
|
14
|
+
* body one the model can rebuild from what is in front of it?", and the resume
|
|
15
|
+
* seed asks "which of these ledger entries can be rebuilt at all?". A
|
|
16
|
+
* predicate that admitted a hop in one and refused it in the other would mean
|
|
17
|
+
* a path referenced as evidence that the ledger never witnessed, or the
|
|
18
|
+
* reverse. Everything below is a function of the messages, the ledger and the
|
|
19
|
+
* bounds — there is no filesystem access anywhere in this file.
|
|
20
|
+
*/
|
|
21
|
+
/**
|
|
22
|
+
* Edit CALLS one chain may carry before the path is withheld.
|
|
23
|
+
*
|
|
24
|
+
* On calls rather than replacements because the bound is on replay work, and
|
|
25
|
+
* an `edits: [...]` batch is one pass over the content however many hunks it
|
|
26
|
+
* holds. Eight is generous for the shape this exists for — a file written and
|
|
27
|
+
* then refined within a turn — and short enough that the whole request's
|
|
28
|
+
* replay stays a rounding error beside the model call it rides on.
|
|
29
|
+
*/
|
|
30
|
+
export const MAX_EDIT_CALLS = 8;
|
|
31
|
+
/**
|
|
32
|
+
* Content a replay may materialise across every path in one pass.
|
|
33
|
+
*
|
|
34
|
+
* Counted cumulatively in UTF-16 units — the measure the caps below and the
|
|
35
|
+
* step-context budget already use — and charged for the write body each chain
|
|
36
|
+
* starts from as well as every body an edit builds on top of it, because those
|
|
37
|
+
* are the strings actually built. Each operation is measured exactly against
|
|
38
|
+
* the content it is about to be applied to and refused before it is built, so
|
|
39
|
+
* a pass whose history is full of long chains it is going to refuse anyway
|
|
40
|
+
* cannot make itself slow proving that. A refusal is charged nothing: the body
|
|
41
|
+
* was never built, and the paths after it keep their room.
|
|
42
|
+
*/
|
|
43
|
+
export const MAX_REPLAYED_UNITS = 256 * 1024;
|
|
44
|
+
/**
|
|
45
|
+
* Arguments longer than a real tool call carries; past this the call is not
|
|
46
|
+
* read AS EVIDENCE.
|
|
47
|
+
*
|
|
48
|
+
* A bound on what may be BELIEVED, and on nothing else. The path such a call
|
|
49
|
+
* declares is still read, under no bound at all — see {@link declaredPath} —
|
|
50
|
+
* because a write too long to quote back is still a write that happened, and a
|
|
51
|
+
* pass that could not say WHICH file it happened to would have to abandon every
|
|
52
|
+
* other path in the conversation to stay honest.
|
|
53
|
+
*/
|
|
54
|
+
const MAX_ARGUMENT_UNITS = 32_000;
|
|
55
|
+
/** Call ids longer than any provider mints. */
|
|
56
|
+
const MAX_CALL_ID_UNITS = 256;
|
|
57
|
+
/**
|
|
58
|
+
* Path lengths a `write` entry may go out with.
|
|
59
|
+
*
|
|
60
|
+
* Exported because `file-evidence-context.ts` puts the same bound on the
|
|
61
|
+
* spelling a `read` entry emits — a read is the other thing that puts a path
|
|
62
|
+
* in the work-context message, and the constant belongs to this module.
|
|
63
|
+
*/
|
|
64
|
+
export const MAX_PATH_UNITS = 512;
|
|
65
|
+
/**
|
|
66
|
+
* Arguments this module will not read as JSON at all, at any bound.
|
|
67
|
+
*
|
|
68
|
+
* {@link MAX_ARGUMENT_UNITS} governs what may be BELIEVED about a call, and
|
|
69
|
+
* deliberately leaves attribution unbounded so that one large `write` cannot
|
|
70
|
+
* cost a conversation every other witness in it. Unbounded is still not free:
|
|
71
|
+
* `JSON.parse` over a multi-megabyte body is real work, and it was being done
|
|
72
|
+
* up to three times for one call — once to collect the paths, once to key the
|
|
73
|
+
* mutation, once to read the call as evidence. Two of those are gone: the
|
|
74
|
+
* attribution answer is now memoised for the whole pass (see
|
|
75
|
+
* {@link PathAttributions}), and the evidence read never reaches a call past
|
|
76
|
+
* the far smaller bound above. What is left is this ceiling on the single
|
|
77
|
+
* remaining parse.
|
|
78
|
+
*
|
|
79
|
+
* About a megabyte, some thirty times the evidence bound, because the rule is
|
|
80
|
+
* that an oversize-but-ORDINARY write stays attributable — a generated file, a
|
|
81
|
+
* bundled config, a long document — while the pathological input is refused. A
|
|
82
|
+
* call past it is attributable to nothing, and the walk treats it exactly as
|
|
83
|
+
* it treats one that names no `path`: there is no key to withdraw, so the
|
|
84
|
+
* whole pass is abandoned and the conversation keeps the empty ledger a resume
|
|
85
|
+
* has always started from.
|
|
86
|
+
*/
|
|
87
|
+
const MAX_ATTRIBUTION_UNITS = 1024 * 1024;
|
|
88
|
+
export function createPathAttributions() {
|
|
89
|
+
return new WeakMap();
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* A call's arguments as JSON, or `undefined` for arguments this module will
|
|
93
|
+
* not read.
|
|
94
|
+
*
|
|
95
|
+
* Every `JSON.parse` of a tool call in this file goes through here, so the
|
|
96
|
+
* ceiling is one rule rather than one rule per reader, and malformed input is
|
|
97
|
+
* a value the callers test rather than an exception they have to be wrapped
|
|
98
|
+
* against.
|
|
99
|
+
*/
|
|
100
|
+
function parseArguments(call) {
|
|
101
|
+
if (call.function.arguments.length > MAX_ATTRIBUTION_UNITS)
|
|
102
|
+
return undefined;
|
|
103
|
+
try {
|
|
104
|
+
return JSON.parse(call.function.arguments);
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
return undefined;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* The lexical key space: the path resolved against the working directory, or
|
|
112
|
+
* the path as written when the tools address a sandbox.
|
|
113
|
+
*
|
|
114
|
+
* What a reader of the ledger uses. Not what a writer of it may use: see
|
|
115
|
+
* {@link FileKeyResolver}.
|
|
116
|
+
*/
|
|
117
|
+
export function lexicalFileKeys(workingDirectory, sandboxed) {
|
|
118
|
+
return (path) => (sandboxed ? path : resolve(workingDirectory, path));
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Index a transcript once, so every lookup below is a map hit.
|
|
122
|
+
*
|
|
123
|
+
* An id claimed twice, or answered twice, indexes to `null` rather than to
|
|
124
|
+
* whichever message came last: two calls wearing one id is an ambiguity, and
|
|
125
|
+
* resolving it by position would let the second silently vouch for the first.
|
|
126
|
+
*/
|
|
127
|
+
export function indexVisibleHistory(messages, keyOf) {
|
|
128
|
+
const calls = new Map();
|
|
129
|
+
const results = new Map();
|
|
130
|
+
for (const message of messages) {
|
|
131
|
+
if (message.role === 'assistant') {
|
|
132
|
+
for (const call of message.toolCalls ?? []) {
|
|
133
|
+
calls.set(call.id, calls.has(call.id) ? null : call);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
else if (message.role === 'tool') {
|
|
137
|
+
results.set(message.toolCallId, results.has(message.toolCallId) ? null : message);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
return { calls, results, keyOf };
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Every path a replay of this history might have to key, in the order the
|
|
144
|
+
* calls arrived.
|
|
145
|
+
*
|
|
146
|
+
* For a caller that has to resolve them before the replay can run, and only
|
|
147
|
+
* for that: nothing here decides anything about a path. Empty when the history
|
|
148
|
+
* holds no `write` and no `edit` call at all, because a claim is only ever made
|
|
149
|
+
* by a mutation — a conversation that only read files reconstructs nothing, and
|
|
150
|
+
* resolving its reads would be filesystem work with no possible result.
|
|
151
|
+
*
|
|
152
|
+
* Every mutation the walk can ATTRIBUTE has to appear here, the ones it will
|
|
153
|
+
* refuse to reconstruct included. This used to drop a call whose arguments ran
|
|
154
|
+
* past the evidence bound, so the walk reached it holding no key for its path,
|
|
155
|
+
* read that as a mutation it could not attribute, and abandoned the seeding
|
|
156
|
+
* entirely: one thirty-kilobyte `write` anywhere in a conversation erased every
|
|
157
|
+
* witness in it. The bounds belong to what may be believed; the path is read
|
|
158
|
+
* here out of the same field the walk reads it from, under no bound at all.
|
|
159
|
+
*/
|
|
160
|
+
export function collectObservedPaths(messages, attributions = createPathAttributions()) {
|
|
161
|
+
const paths = new Set();
|
|
162
|
+
let mutated = false;
|
|
163
|
+
for (const message of messages) {
|
|
164
|
+
if (message.role !== 'assistant')
|
|
165
|
+
continue;
|
|
166
|
+
for (const call of message.toolCalls ?? []) {
|
|
167
|
+
const name = call.function.name;
|
|
168
|
+
if (name !== 'write' && name !== 'edit' && name !== 'read')
|
|
169
|
+
continue;
|
|
170
|
+
if (name !== 'read')
|
|
171
|
+
mutated = true;
|
|
172
|
+
const path = declaredPath(call, attributions);
|
|
173
|
+
if (path !== undefined)
|
|
174
|
+
paths.add(path);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return mutated ? [...paths] : [];
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* The `path` argument a tool call declares, whatever else its input holds.
|
|
181
|
+
*
|
|
182
|
+
* The one attribution rule, used both to collect the paths a pass must resolve
|
|
183
|
+
* and to key each mutation as the walk reaches it — one function, so the two
|
|
184
|
+
* can never disagree about which file a call touched, which is the disagreement
|
|
185
|
+
* that turns an ordinary large write into a total loss.
|
|
186
|
+
*
|
|
187
|
+
* The recorded arguments and nothing else. A receipt names the path too, but it
|
|
188
|
+
* names it inside a sentence a path may itself contain, in a spelling that
|
|
189
|
+
* differs between the host and sandbox branches, and compaction clears receipts
|
|
190
|
+
* while it never clears a call. A call the provider stream cut off mid-JSON
|
|
191
|
+
* carries `{}` here: `function.arguments` is normalized to that and the raw
|
|
192
|
+
* buffer moves to `metadata.partialArguments`, which is what the model was
|
|
193
|
+
* saying rather than what ran — a `repairToolCall` hook may have rewritten the
|
|
194
|
+
* arguments before execution. So a truncated call is attributable to nothing,
|
|
195
|
+
* and the walk treats it as such. So is a call whose arguments run past
|
|
196
|
+
* {@link MAX_ATTRIBUTION_UNITS}, which this does not read at all.
|
|
197
|
+
*
|
|
198
|
+
* Answered once per pass and remembered. The path collection and the walk ask
|
|
199
|
+
* the same question of the same calls, and a `write` carries a whole file body
|
|
200
|
+
* in the string being parsed to answer it.
|
|
201
|
+
*/
|
|
202
|
+
function declaredPath(call, attributions) {
|
|
203
|
+
const remembered = attributions.get(call);
|
|
204
|
+
if (remembered !== undefined)
|
|
205
|
+
return remembered ?? undefined;
|
|
206
|
+
const parsed = parseArguments(call);
|
|
207
|
+
const declared = typeof parsed === 'object' && parsed !== null ? parsed.path : undefined;
|
|
208
|
+
const path = typeof declared === 'string' && declared.length > 0 ? declared : null;
|
|
209
|
+
attributions.set(call, path);
|
|
210
|
+
return path ?? undefined;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* The visibility every hop must pass, write or edit, root or tip.
|
|
214
|
+
*
|
|
215
|
+
* One function because a middle hop is not a lesser claim than the last one.
|
|
216
|
+
* A chain whose second edit was cleared by compaction, or came back an error,
|
|
217
|
+
* or arrived truncated, reconstructs nothing at all — so the whole path is
|
|
218
|
+
* withheld rather than emitted as the part still visible, which would name a
|
|
219
|
+
* body the model cannot rebuild.
|
|
220
|
+
*
|
|
221
|
+
* A call a `pre_tool_use` hook SKIPPED is the one refusal that does not arrive
|
|
222
|
+
* as an error. The hook declined the call; nothing failed, so the receipt is a
|
|
223
|
+
* plain success carrying the sentence `plugin-hooks.ts` writes for it, and
|
|
224
|
+
* reading that as a `write` would hand back a body the tool was never allowed
|
|
225
|
+
* to put on disk — a fingerprint for a file that still holds whatever it held
|
|
226
|
+
* before, and a spurious drift refusal on the next edit. Recognised through
|
|
227
|
+
* the same function that writes the sentence, so the two cannot drift apart.
|
|
228
|
+
*/
|
|
229
|
+
export function visibleCall(history, id, name) {
|
|
230
|
+
const call = history.calls.get(id);
|
|
231
|
+
const receipt = history.results.get(id);
|
|
232
|
+
if (!call ||
|
|
233
|
+
call.function.name !== name ||
|
|
234
|
+
call.metadata?.inputTruncated ||
|
|
235
|
+
call.function.arguments.length > MAX_ARGUMENT_UNITS ||
|
|
236
|
+
id.length > MAX_CALL_ID_UNITS ||
|
|
237
|
+
!receipt ||
|
|
238
|
+
receipt.role !== 'tool' ||
|
|
239
|
+
receipt.isError ||
|
|
240
|
+
typeof receipt.content !== 'string' ||
|
|
241
|
+
isClearedToolResult(receipt.content) ||
|
|
242
|
+
isSkippedToolResult(name, receipt.content))
|
|
243
|
+
return undefined;
|
|
244
|
+
return call;
|
|
245
|
+
}
|
|
246
|
+
/** A full body that arrived whole in one visible call. */
|
|
247
|
+
export function visibleWrite(history, id) {
|
|
248
|
+
const call = visibleCall(history, id, 'write');
|
|
249
|
+
if (!call)
|
|
250
|
+
return;
|
|
251
|
+
const input = WriteFileTool.inputSchema.safeParse(parseArguments(call));
|
|
252
|
+
if (!input.success || input.data.path.length > MAX_PATH_UNITS)
|
|
253
|
+
return;
|
|
254
|
+
const body = input.data.content ?? input.data.newStr;
|
|
255
|
+
if (typeof body !== 'string')
|
|
256
|
+
return;
|
|
257
|
+
const key = history.keyOf(input.data.path);
|
|
258
|
+
if (key === undefined)
|
|
259
|
+
return;
|
|
260
|
+
return { path: input.data.path, key, body };
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* One visible edit call's arguments, ready to replay.
|
|
264
|
+
*
|
|
265
|
+
* No length bound on the path here, unlike the write above. A write's path is
|
|
266
|
+
* the spelling an entry goes out with; an edit is held to the KEY it resolves
|
|
267
|
+
* to, which its chain's root has already been bounded on.
|
|
268
|
+
*/
|
|
269
|
+
export function visibleEdit(history, id) {
|
|
270
|
+
const call = visibleCall(history, id, 'edit');
|
|
271
|
+
if (!call)
|
|
272
|
+
return;
|
|
273
|
+
const input = EditTool.inputSchema.safeParse(parseArguments(call));
|
|
274
|
+
if (!input.success)
|
|
275
|
+
return;
|
|
276
|
+
const key = history.keyOf(input.data.path);
|
|
277
|
+
if (key === undefined)
|
|
278
|
+
return;
|
|
279
|
+
return { key, input: input.data };
|
|
280
|
+
}
|
|
281
|
+
export function createReplayBudget(units = MAX_REPLAYED_UNITS) {
|
|
282
|
+
return { remaining: units };
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Charge one body against the pass's replay allowance.
|
|
286
|
+
*
|
|
287
|
+
* Checked before it is taken, so a refusal costs nothing. Deducting first and
|
|
288
|
+
* reporting afterwards left the allowance negative, and one oversized path
|
|
289
|
+
* then refused every admissible path behind it in the same pass.
|
|
290
|
+
*/
|
|
291
|
+
export function spend(budget, units) {
|
|
292
|
+
if (units > budget.remaining)
|
|
293
|
+
return false;
|
|
294
|
+
budget.remaining -= units;
|
|
295
|
+
return true;
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Replay one edit call onto the body in hand, within what the budget has left.
|
|
299
|
+
*
|
|
300
|
+
* `undefined` for a hop the budget turns away and for one that no longer
|
|
301
|
+
* applies, because both mean the same thing to every caller here: this path
|
|
302
|
+
* reconstructs nothing. The charge is settled either way — what the attempt
|
|
303
|
+
* built, it built — and for a hop refused at its first operation that charge
|
|
304
|
+
* is zero.
|
|
305
|
+
*/
|
|
306
|
+
export function replayHop(content, input, budget) {
|
|
307
|
+
const replay = replayEditCallWithin(content, input, budget.remaining);
|
|
308
|
+
budget.remaining = Math.max(budget.remaining - replay.charged, 0);
|
|
309
|
+
return replay.outcome === 'replayed' ? replay.content : undefined;
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Whether a refused mutation has reported this path stale since the ledger
|
|
313
|
+
* last observed it.
|
|
314
|
+
*
|
|
315
|
+
* That refusal read the real file to make its comparison, so the ledger knows
|
|
316
|
+
* its body is behind disk without a consumer here touching the filesystem.
|
|
317
|
+
* The reconstruction would still be a body the model can rebuild — but not the
|
|
318
|
+
* FILE's body, which is what an entry claims. Withheld until a real
|
|
319
|
+
* observation re-baselines the ledger, which is also what clears the flag.
|
|
320
|
+
*/
|
|
321
|
+
export function knownStale(tracker, key) {
|
|
322
|
+
return tracker.driftObserved?.(key) === true;
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Paths one pass may hold a reconstructed body for at a time.
|
|
326
|
+
*
|
|
327
|
+
* The projection emits at most this many entries and keeps the most recent, so
|
|
328
|
+
* a pass that tracked more would be doing work whose result is discarded.
|
|
329
|
+
*/
|
|
330
|
+
export const MAX_WITNESSED_PATHS = 6;
|
|
331
|
+
/**
|
|
332
|
+
* Rebuild an observation ledger from a conversation's own history.
|
|
333
|
+
*
|
|
334
|
+
* The ledger is process state. A resumed conversation gets a fresh empty one,
|
|
335
|
+
* and until something reads a file again the runtime knows nothing about files
|
|
336
|
+
* this conversation wrote in full — so the projection admits nothing and the
|
|
337
|
+
* model re-reads a body already in front of it, every time a session is picked
|
|
338
|
+
* back up.
|
|
339
|
+
*
|
|
340
|
+
* What is reconstructable here is exactly what the projection would admit, by
|
|
341
|
+
* the same predicates and the same bounded replay, because both go through the
|
|
342
|
+
* functions above. A `write` whose call and successful receipt are both intact
|
|
343
|
+
* hands back its body and its witness; the edits on top of it are replayed
|
|
344
|
+
* hop by hop and extend the chain. Anything else about a path the conversation
|
|
345
|
+
* mutated — a receipt compaction cleared, a call the transcript never answered,
|
|
346
|
+
* a mutation it refused, one a `pre_tool_use` hook skipped before it ever ran,
|
|
347
|
+
* a hop that no longer applies, a body past the bounds, a call too long to
|
|
348
|
+
* quote back — withdraws whatever this pass was holding for that path and
|
|
349
|
+
* writes NOTHING for it.
|
|
350
|
+
*
|
|
351
|
+
* Content-backed observations only, and that is the whole of what a resume
|
|
352
|
+
* restores. A path in the ledger with no fingerprint is a path `write` lets
|
|
353
|
+
* through unread: the read-before-overwrite refusal is `hasRead`, and the drift
|
|
354
|
+
* comparison it guards needs a body to compare. Seeding membership alone would
|
|
355
|
+
* therefore admit a full overwrite of a file that changed while the session was
|
|
356
|
+
* closed, with nothing checked — weaker than the empty ledger a resume used to
|
|
357
|
+
* start from, which refuses that overwrite outright. So a path this pass cannot
|
|
358
|
+
* rebuild is left exactly as that empty ledger leaves it, and the first real
|
|
359
|
+
* read re-establishes it.
|
|
360
|
+
*
|
|
361
|
+
* Two things this deliberately does not do. It never reads the filesystem: a
|
|
362
|
+
* fingerprint restored here is a claim derived from history, and the built-in
|
|
363
|
+
* mutation checks still compare it against the real file before anything is
|
|
364
|
+
* written — so a file changed while the session was closed is refused exactly
|
|
365
|
+
* as it is today, and the refusal's drift flag withdraws the entry. And it
|
|
366
|
+
* never recovers a body from a `read` receipt by undoing the line numbering: a
|
|
367
|
+
* read's rendering is compared, whole, against a body this pass already holds,
|
|
368
|
+
* and a read that cannot be matched that way withdraws the body rather than
|
|
369
|
+
* supplying one.
|
|
370
|
+
*
|
|
371
|
+
* That first guarantee is the reason `keyOf` is a parameter. Everything written
|
|
372
|
+
* here has to land on the key the mutation tools will look it up under, and on
|
|
373
|
+
* a host those keys are canonical — `write` and `edit` follow every symlink
|
|
374
|
+
* before they touch the ledger. Keying a seed lexically instead writes entries
|
|
375
|
+
* into a key space the tools never read: the projection would then match a
|
|
376
|
+
* fingerprint this pass had just written to it, and the drift refusal that is
|
|
377
|
+
* supposed to withdraw the claim would land somewhere else and never reach it.
|
|
378
|
+
* So the caller resolves the paths the way the tools do — see
|
|
379
|
+
* `file-evidence-seed.ts` — and a path it could not resolve gets no key, which
|
|
380
|
+
* makes the mutation that named it unattributable and stops the pass.
|
|
381
|
+
*/
|
|
382
|
+
export function replayObservationLedger(messages, tracker, keyOf, attributions = createPathAttributions()) {
|
|
383
|
+
const history = indexVisibleHistory(messages, keyOf);
|
|
384
|
+
const budget = createReplayBudget();
|
|
385
|
+
const claims = new Map();
|
|
386
|
+
// The keys currently holding a body, newest last — the projection's own
|
|
387
|
+
// order, so the paths this keeps are the paths it would emit.
|
|
388
|
+
const withBody = new Set();
|
|
389
|
+
for (const message of messages) {
|
|
390
|
+
if (message.role !== 'assistant')
|
|
391
|
+
continue;
|
|
392
|
+
for (const call of message.toolCalls ?? []) {
|
|
393
|
+
const name = call.function.name;
|
|
394
|
+
if (name !== 'write' && name !== 'edit' && name !== 'read')
|
|
395
|
+
continue;
|
|
396
|
+
const receipt = history.results.get(call.id);
|
|
397
|
+
// Two receipts wearing one call id hide which of them this call got.
|
|
398
|
+
// On a mutation that is the ambiguity below, arriving from the other
|
|
399
|
+
// side. On a READ it is no smaller: the receipt that was hidden could
|
|
400
|
+
// be the one showing a body this walk is holding to be something else,
|
|
401
|
+
// and skipping the read past would keep a claim that very observation
|
|
402
|
+
// withdrew. Both get the same answer.
|
|
403
|
+
if (receipt === null)
|
|
404
|
+
return commit(tracker, new Map(), budget);
|
|
405
|
+
const answered = receipt !== undefined && receipt.role === 'tool' && !receipt.isError;
|
|
406
|
+
if (name === 'read') {
|
|
407
|
+
// A read that never came back, or came back refused, saw no body: it
|
|
408
|
+
// can neither confirm what this pass holds nor contradict it. And a
|
|
409
|
+
// read changes no file, so a claim left standing across one is still a
|
|
410
|
+
// claim about the same bytes.
|
|
411
|
+
if (answered)
|
|
412
|
+
observeRead(history, call, claims, withBody, budget);
|
|
413
|
+
continue;
|
|
414
|
+
}
|
|
415
|
+
// One id claimed by two calls hides which of them ran. On a path this
|
|
416
|
+
// pass is not holding that is merely invisible, but a mutation could
|
|
417
|
+
// have replaced a body claimed somewhere else in this walk, and there
|
|
418
|
+
// is no way to tell where — so the pass establishes nothing at all
|
|
419
|
+
// rather than carry a body something unseen may have moved past.
|
|
420
|
+
if (history.calls.get(call.id) === null)
|
|
421
|
+
return commit(tracker, new Map(), budget);
|
|
422
|
+
// Attribution before outcome, for every mutation the walk reaches. A call
|
|
423
|
+
// the transcript never answered — the unknown-outcome result the kernel's
|
|
424
|
+
// own repair writes for one included — is precisely the call whose effect
|
|
425
|
+
// on the file nobody knows: the process may have died with the write half
|
|
426
|
+
// made. And a refusal is a tool's own report about this path, a drift
|
|
427
|
+
// refusal above all, which read the disk and found the body this ledger
|
|
428
|
+
// holds is not the body there. Carrying a claim through either would have
|
|
429
|
+
// the first resumed request tell the model a file holds a body the
|
|
430
|
+
// transcript itself says nobody can vouch for, so each withdraws the path
|
|
431
|
+
// it names — and only that path. A mutation attributable to no path at all
|
|
432
|
+
// is still the one thing that stops the pass, because then there is no
|
|
433
|
+
// path to withdraw.
|
|
434
|
+
const key = mutatedKey(history, call, attributions);
|
|
435
|
+
if (key === undefined)
|
|
436
|
+
return commit(tracker, new Map(), budget);
|
|
437
|
+
const claim = answered
|
|
438
|
+
? mutate(history, call, name, key, claims.get(key), budget)
|
|
439
|
+
: { kind: 'seen' };
|
|
440
|
+
claims.set(key, claim);
|
|
441
|
+
withBody.delete(key);
|
|
442
|
+
if (claim.kind === 'content')
|
|
443
|
+
withBody.add(key);
|
|
444
|
+
// Oldest body first, matching what the projection keeps. An evicted
|
|
445
|
+
// path is one this pass stops vouching for: it was mutated here, and
|
|
446
|
+
// what it holds is past what the pass can carry, so it reaches the
|
|
447
|
+
// ledger as the nothing every unrebuilt path reaches it as.
|
|
448
|
+
if (withBody.size > MAX_WITNESSED_PATHS) {
|
|
449
|
+
const oldest = withBody.values().next().value;
|
|
450
|
+
withBody.delete(oldest);
|
|
451
|
+
// Setting an existing key leaves it where it is, so the order the
|
|
452
|
+
// ledger is written in stays the order the calls arrived in.
|
|
453
|
+
claims.set(oldest, { kind: 'seen' });
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
return commit(tracker, claims, budget);
|
|
458
|
+
}
|
|
459
|
+
/** Apply a walk's surviving claims to the ledger, in the order they were made. */
|
|
460
|
+
function commit(tracker, claims, budget) {
|
|
461
|
+
let pathsWitnessed = 0;
|
|
462
|
+
let pathsSeen = 0;
|
|
463
|
+
for (const [key, claim] of claims) {
|
|
464
|
+
if (claim.kind === 'seen') {
|
|
465
|
+
// Nothing. Not even membership: `hasRead` is the read-before-overwrite
|
|
466
|
+
// refusal, and granting it without a fingerprint would let a full
|
|
467
|
+
// overwrite of this path through with no body to compare — over a file
|
|
468
|
+
// that may have moved while the session was closed. The claim was
|
|
469
|
+
// carried through the walk so that no edit stacked onto a body
|
|
470
|
+
// something unseen had replaced; having done that, it is dropped.
|
|
471
|
+
pathsSeen++;
|
|
472
|
+
continue;
|
|
473
|
+
}
|
|
474
|
+
for (const step of claim.steps) {
|
|
475
|
+
if (step.kind === 'write') {
|
|
476
|
+
tracker.recordRead(key, step.body, step.callId);
|
|
477
|
+
}
|
|
478
|
+
else if (tracker.recordEdit) {
|
|
479
|
+
tracker.recordEdit(key, step.content, step.callId);
|
|
480
|
+
}
|
|
481
|
+
else {
|
|
482
|
+
// The same fallback the `edit` tool takes against a tracker without
|
|
483
|
+
// the method: the observation advances and no chain is built.
|
|
484
|
+
tracker.recordRead(key, step.content);
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
pathsWitnessed++;
|
|
488
|
+
}
|
|
489
|
+
return { pathsWitnessed, pathsSeen, unitsReplayed: MAX_REPLAYED_UNITS - budget.remaining };
|
|
490
|
+
}
|
|
491
|
+
/** Fold one successful mutation into the path's claim. */
|
|
492
|
+
function mutate(history, call, name, key, claim, budget) {
|
|
493
|
+
if (name === 'write') {
|
|
494
|
+
const written = visibleWrite(history, call.id);
|
|
495
|
+
// A write nothing may quote back is still a write that HAPPENED, and the
|
|
496
|
+
// path it happened to is known: arguments past the evidence bound, a call
|
|
497
|
+
// the stream truncated, a path longer than an entry goes out with, a key
|
|
498
|
+
// the call and the ledger disagree about. Each of those withdraws the
|
|
499
|
+
// body and keeps the walk going — what was on this path is now unknown,
|
|
500
|
+
// which is a statement about one path rather than a reason to stop. A
|
|
501
|
+
// call a hook SKIPPED lands here too, from the other direction: that one
|
|
502
|
+
// never ran, so the file holds whatever it held before and this pass
|
|
503
|
+
// cannot say what that was either.
|
|
504
|
+
if (!written || written.key !== key)
|
|
505
|
+
return { kind: 'seen' };
|
|
506
|
+
if (!spend(budget, written.body.length))
|
|
507
|
+
return { kind: 'seen' };
|
|
508
|
+
// A full body replaces everything under it, chain included.
|
|
509
|
+
return {
|
|
510
|
+
kind: 'content',
|
|
511
|
+
body: written.body,
|
|
512
|
+
steps: [{ kind: 'write', body: written.body, callId: call.id }],
|
|
513
|
+
};
|
|
514
|
+
}
|
|
515
|
+
// An edit onto a body this pass is not holding cannot be replayed onto
|
|
516
|
+
// anything, and one onto a chain already at its bound stops being followed.
|
|
517
|
+
if (!claim || claim.kind !== 'content')
|
|
518
|
+
return { kind: 'seen' };
|
|
519
|
+
if (claim.steps.length > MAX_EDIT_CALLS)
|
|
520
|
+
return { kind: 'seen' };
|
|
521
|
+
const hop = visibleEdit(history, call.id);
|
|
522
|
+
if (!hop || hop.key !== key)
|
|
523
|
+
return { kind: 'seen' };
|
|
524
|
+
const replayed = replayHop(claim.body, hop.input, budget);
|
|
525
|
+
if (replayed === undefined)
|
|
526
|
+
return { kind: 'seen' };
|
|
527
|
+
claim.body = replayed;
|
|
528
|
+
claim.steps.push({ kind: 'edit', content: replayed, callId: call.id });
|
|
529
|
+
return claim;
|
|
530
|
+
}
|
|
531
|
+
/**
|
|
532
|
+
* Confirm or withdraw a body this pass holds, from a `read` that observed it.
|
|
533
|
+
*
|
|
534
|
+
* A read changes no file, so on its own it establishes nothing: a partial read
|
|
535
|
+
* shows a window, and a body cannot be recovered from the rendering without
|
|
536
|
+
* stripping the line numbers back off — which would be inventing a file from
|
|
537
|
+
* text that was formatted for a reader, and is exactly what the ledger's
|
|
538
|
+
* contract forbids. What a read CAN do is settle whether a body already
|
|
539
|
+
* reconstructed here is the one the read saw. The rendering is produced
|
|
540
|
+
* forwards, from the body in hand through the read tool's own renderer, and
|
|
541
|
+
* compared whole.
|
|
542
|
+
*
|
|
543
|
+
* Equality is conclusive because of the numbering. Every line of a rendering
|
|
544
|
+
* goes out behind its own `${n}\t`, so one rendering belongs to exactly one
|
|
545
|
+
* body and window; and the partial-view notice carries no such prefix on its
|
|
546
|
+
* lines, so a rendering that covers a whole file cannot be equal to one that
|
|
547
|
+
* was cut short. A read this cannot match leaves the path known and its body
|
|
548
|
+
* withdrawn — the honest answer, and the one the drift check then re-derives
|
|
549
|
+
* from disk.
|
|
550
|
+
*/
|
|
551
|
+
function observeRead(history, call, claims, withBody, budget) {
|
|
552
|
+
const read = readWindow(history, call);
|
|
553
|
+
if (!read)
|
|
554
|
+
return;
|
|
555
|
+
const claim = claims.get(read.key);
|
|
556
|
+
if (!claim || claim.kind !== 'content')
|
|
557
|
+
return;
|
|
558
|
+
const shown = history.results.get(call.id)?.content;
|
|
559
|
+
if (visibleCall(history, call.id, 'read') && typeof shown === 'string') {
|
|
560
|
+
// A whole-file rendering is the body plus a number on every line, so one
|
|
561
|
+
// shorter than the body it would render cannot be equal to it. The cheap
|
|
562
|
+
// half of the comparison, taken before anything is measured.
|
|
563
|
+
const units = shown.length < claim.body.length ? undefined : wholeFileRenderUnits(claim.body, read.window);
|
|
564
|
+
// The rendering is content this pass materialises, so it is charged like
|
|
565
|
+
// every other body — and charged for what it will actually come to,
|
|
566
|
+
// worked out from the body and the window while the string does not exist
|
|
567
|
+
// yet. Charging the RECEIPT's length was charging one number and building
|
|
568
|
+
// another: a receipt that had been rewritten short could have the pass
|
|
569
|
+
// build a rendering the ceiling had never been asked about.
|
|
570
|
+
if (units !== undefined && spend(budget, units)) {
|
|
571
|
+
const rendered = renderNumberedRead(claim.body, read.window);
|
|
572
|
+
if (!rendered.partial && rendered.output === shown)
|
|
573
|
+
return;
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
claims.set(read.key, { kind: 'seen' });
|
|
577
|
+
// Off the held list as well as out of the claim. A withdrawn path is one
|
|
578
|
+
// this pass is no longer carrying a body for, so counting it against the
|
|
579
|
+
// eviction bound would have a later mutation evict a path that IS still
|
|
580
|
+
// holding one — the pass would then write fewer witnesses than the
|
|
581
|
+
// projection can emit, and the one it dropped was admissible.
|
|
582
|
+
withBody.delete(read.key);
|
|
583
|
+
}
|
|
584
|
+
/**
|
|
585
|
+
* What `read` would return for this whole body, in UTF-16 units, without
|
|
586
|
+
* building it — and `undefined` for a window that would leave a line out.
|
|
587
|
+
*
|
|
588
|
+
* The rendering puts `${n}\t` in front of every line and joins them back with
|
|
589
|
+
* the newlines the body already carries, so its length is the body's, plus one
|
|
590
|
+
* tab per line, plus the digits of the numbers `1..lines`. A windowed read
|
|
591
|
+
* renumbers from its offset and carries the PARTIAL notice, and can never equal
|
|
592
|
+
* a whole body's rendering — so it is refused here rather than built and
|
|
593
|
+
* compared, which is also what makes the figure above exact.
|
|
594
|
+
*/
|
|
595
|
+
function wholeFileRenderUnits(body, window) {
|
|
596
|
+
const lines = countLines(body);
|
|
597
|
+
const { start, end } = resolveReadWindow(window, lines);
|
|
598
|
+
if (start !== 0 || end < lines)
|
|
599
|
+
return undefined;
|
|
600
|
+
return body.length + lines + lineNumberUnits(lines);
|
|
601
|
+
}
|
|
602
|
+
/** Lines the way `String.split('\n')` counts them, without building the array. */
|
|
603
|
+
function countLines(body) {
|
|
604
|
+
let lines = 1;
|
|
605
|
+
for (let at = body.indexOf('\n'); at !== -1; at = body.indexOf('\n', at + 1))
|
|
606
|
+
lines++;
|
|
607
|
+
return lines;
|
|
608
|
+
}
|
|
609
|
+
/** Units the line numbers `1..lines` occupy, counted by decade rather than one by one. */
|
|
610
|
+
function lineNumberUnits(lines) {
|
|
611
|
+
let units = 0;
|
|
612
|
+
for (let width = 1, first = 1; first <= lines; width++, first *= 10)
|
|
613
|
+
units += (Math.min(lines, first * 10 - 1) - first + 1) * width;
|
|
614
|
+
return units;
|
|
615
|
+
}
|
|
616
|
+
/**
|
|
617
|
+
* The ledger key a mutation belongs to, whatever the transcript says came back
|
|
618
|
+
* — or `undefined` for one this pass cannot attribute to any file at all.
|
|
619
|
+
*
|
|
620
|
+
* Deliberately the declared path rather than the tool's own schema, and asked
|
|
621
|
+
* before the outcome is. A call that fails validation in some OTHER field, that
|
|
622
|
+
* is too long to read as evidence, that was never answered or that was refused
|
|
623
|
+
* still says which file it was aimed at, and a mutation that can be attributed
|
|
624
|
+
* can be honoured — as a content-changing observation nothing here can replay,
|
|
625
|
+
* which costs the path it names and no other. A key is exactly what withdrawing
|
|
626
|
+
* one path rather than the whole pass requires. `undefined` is kept for the two
|
|
627
|
+
* things that really are unattributable: a call naming no path, and a path this
|
|
628
|
+
* run may not reach, whose key the resolver therefore withheld. Those, and only
|
|
629
|
+
* those, stop the pass — a refused call included, because a refusal this pass
|
|
630
|
+
* cannot place is a refusal it cannot act on either.
|
|
631
|
+
*/
|
|
632
|
+
function mutatedKey(history, call, attributions) {
|
|
633
|
+
const path = declaredPath(call, attributions);
|
|
634
|
+
return path === undefined ? undefined : history.keyOf(path);
|
|
635
|
+
}
|
|
636
|
+
/** The path and window one `read` call asked for. */
|
|
637
|
+
function readWindow(history, call) {
|
|
638
|
+
const input = ReadFileTool.inputSchema.safeParse(parseArguments(call));
|
|
639
|
+
if (!input.success)
|
|
640
|
+
return undefined;
|
|
641
|
+
const key = history.keyOf(input.data.path);
|
|
642
|
+
// A read this pass cannot key cannot contradict a claim either: the only
|
|
643
|
+
// claims it holds came from mutations, and a mutation whose path would
|
|
644
|
+
// not resolve stopped the pass before it made one.
|
|
645
|
+
return key === undefined ? undefined : { key, window: input.data };
|
|
646
|
+
}
|
|
647
|
+
//# sourceMappingURL=file-evidence-replay.js.map
|