@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,94 @@
|
|
|
1
|
+
import { z } from 'zod'
|
|
2
|
+
import { StreamTextAccumulator } from '../../provider/stream-text.js'
|
|
3
|
+
import { type TokenUsage, mergeTokenUsage } from '../../types/common/index.js'
|
|
4
|
+
import { createSystemMessage, createUserMessage } from '../../types/message/index.js'
|
|
5
|
+
import type { PreparationTextRequest, PreparationTextResult } from '../../types/run/prepare-step.js'
|
|
6
|
+
import type { IterationContext } from './iteration/phases/context.js'
|
|
7
|
+
|
|
8
|
+
const requestSchema = z
|
|
9
|
+
.object({
|
|
10
|
+
system: z.string().min(1).max(12_000),
|
|
11
|
+
prompt: z.string().min(1).max(12_000),
|
|
12
|
+
maxTokens: z.number().int().min(1).max(1024).default(256),
|
|
13
|
+
timeoutMs: z.number().int().min(1).max(10_000).default(10_000),
|
|
14
|
+
})
|
|
15
|
+
.strict()
|
|
16
|
+
|
|
17
|
+
/** The provider already owns retry, fallback, cancellation and budget admission. */
|
|
18
|
+
export function createCallbackInference(
|
|
19
|
+
ctx: IterationContext,
|
|
20
|
+
model: string,
|
|
21
|
+
phase: 'preparation' | 'review',
|
|
22
|
+
) {
|
|
23
|
+
const label = phase === 'preparation' ? 'Preparation' : 'Review'
|
|
24
|
+
const owner = phase === 'preparation' ? 'preparation stage' : 'answer reviewer'
|
|
25
|
+
const lifetime = new AbortController()
|
|
26
|
+
let used = false
|
|
27
|
+
return {
|
|
28
|
+
close: () => lifetime.abort(new Error(`The ${owner} has ended.`)),
|
|
29
|
+
async generateText(request: PreparationTextRequest): Promise<PreparationTextResult> {
|
|
30
|
+
lifetime.signal.throwIfAborted()
|
|
31
|
+
ctx.abortController.signal.throwIfAborted()
|
|
32
|
+
request.signal?.throwIfAborted()
|
|
33
|
+
const { signal: requestedSignal, ...fields } = request
|
|
34
|
+
const input = requestSchema.parse(fields)
|
|
35
|
+
if (input.system.length + input.prompt.length > 12_000)
|
|
36
|
+
throw new Error(`${label} inference input exceeds 12,000 characters.`)
|
|
37
|
+
if (used)
|
|
38
|
+
throw new Error(
|
|
39
|
+
`${phase === 'preparation' ? 'A' : 'An'} ${owner} may make only one inference call.`,
|
|
40
|
+
)
|
|
41
|
+
used = true
|
|
42
|
+
const deadline = new AbortController()
|
|
43
|
+
const timer = setTimeout(
|
|
44
|
+
() => deadline.abort(new Error(`${label} inference timed out.`)),
|
|
45
|
+
input.timeoutMs,
|
|
46
|
+
)
|
|
47
|
+
const signal = AbortSignal.any([
|
|
48
|
+
ctx.abortController.signal,
|
|
49
|
+
lifetime.signal,
|
|
50
|
+
deadline.signal,
|
|
51
|
+
...(requestedSignal ? [requestedSignal] : []),
|
|
52
|
+
])
|
|
53
|
+
const requested = ctx.servingMember?.() ?? { index: 0, providerId: ctx.provider.id }
|
|
54
|
+
const route = () => {
|
|
55
|
+
const member = ctx.servingMember?.() ?? requested
|
|
56
|
+
return {
|
|
57
|
+
providerId: member.providerId,
|
|
58
|
+
model: member.model ?? model,
|
|
59
|
+
chainIndex: member.index,
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
const text = new StreamTextAccumulator()
|
|
63
|
+
let invalidOutput: string | undefined
|
|
64
|
+
let usage: TokenUsage | undefined
|
|
65
|
+
try {
|
|
66
|
+
for await (const chunk of ctx.provider.chatStream({
|
|
67
|
+
model,
|
|
68
|
+
providerRoute: route(),
|
|
69
|
+
messages: [createSystemMessage(input.system), createUserMessage(input.prompt)],
|
|
70
|
+
maxTokens: input.maxTokens,
|
|
71
|
+
...(ctx.runConfig.effort ? { effort: ctx.runConfig.effort } : {}),
|
|
72
|
+
signal,
|
|
73
|
+
})) {
|
|
74
|
+
if (chunk.usage) usage = usage ? mergeTokenUsage(usage, chunk.usage) : { ...chunk.usage }
|
|
75
|
+
if (chunk.error) throw new Error(chunk.error)
|
|
76
|
+
signal.throwIfAborted()
|
|
77
|
+
if (chunk.delta.toolCalls?.length) invalidOutput = `${label} inference cannot call tools.`
|
|
78
|
+
if (!invalidOutput) {
|
|
79
|
+
text.push(chunk)
|
|
80
|
+
if (text.characters > 8192)
|
|
81
|
+
invalidOutput = `${label} inference output exceeds 8,192 characters.`
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
signal.throwIfAborted()
|
|
85
|
+
if (!usage) throw new Error(`${label} inference ended without usage.`)
|
|
86
|
+
if (invalidOutput) throw new Error(invalidOutput)
|
|
87
|
+
return { text: text.text, usage, servedBy: route() }
|
|
88
|
+
} finally {
|
|
89
|
+
clearTimeout(timer)
|
|
90
|
+
if (usage) ctx.runMgr.accumulateUsage(usage, route())
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
}
|
|
94
|
+
}
|
|
@@ -214,6 +214,8 @@ export class CheckpointManager {
|
|
|
214
214
|
private workingStateSource?: () => WorkingStateSnapshot | undefined
|
|
215
215
|
private latestUserMessageSource?: () => UserMessage | undefined
|
|
216
216
|
private restoredUserMessage?: UserMessage
|
|
217
|
+
private answerReviewAttemptsSource?: () => number
|
|
218
|
+
private restoredAnswerAttempts = 0
|
|
217
219
|
private structuredReviewAttemptsSource?: () => number
|
|
218
220
|
private restoredReviewAttempts = 0
|
|
219
221
|
private nativeStructuredAttemptsSource?: () => number
|
|
@@ -298,6 +300,13 @@ export class CheckpointManager {
|
|
|
298
300
|
return this.restoredUserMessage
|
|
299
301
|
}
|
|
300
302
|
|
|
303
|
+
setAnswerReviewAttemptsSource(source: () => number): void {
|
|
304
|
+
this.answerReviewAttemptsSource = source
|
|
305
|
+
}
|
|
306
|
+
get restoredAnswerReviewAttempts(): number {
|
|
307
|
+
return this.restoredAnswerAttempts
|
|
308
|
+
}
|
|
309
|
+
|
|
301
310
|
setNativeStructuredAttemptsSource(source: () => number): void {
|
|
302
311
|
this.nativeStructuredAttemptsSource = source
|
|
303
312
|
}
|
|
@@ -344,6 +353,7 @@ export class CheckpointManager {
|
|
|
344
353
|
runCreatedAt: this.runCreatedAt,
|
|
345
354
|
iteration,
|
|
346
355
|
messages: [...runMgr.messages],
|
|
356
|
+
answerReviewAttempts: this.answerReviewAttemptsSource?.() ?? this.restoredAnswerAttempts,
|
|
347
357
|
nativeStructuredAttempts:
|
|
348
358
|
this.nativeStructuredAttemptsSource?.() ?? this.restoredNativeAttempts,
|
|
349
359
|
structuredReviewAttempts:
|
|
@@ -539,6 +549,10 @@ export class CheckpointManager {
|
|
|
539
549
|
// its origin's age. A guard that no input can trip would have read as
|
|
540
550
|
// protection and been none.
|
|
541
551
|
this.runCreatedAt ??= checkpoint.runCreatedAt
|
|
552
|
+
const answerAttempts = checkpoint.answerReviewAttempts ?? 0
|
|
553
|
+
if (!Number.isSafeInteger(answerAttempts) || answerAttempts < 0)
|
|
554
|
+
throw new Error('Checkpoint answerReviewAttempts must be a nonnegative safe integer')
|
|
555
|
+
this.restoredAnswerAttempts = answerAttempts
|
|
542
556
|
const nativeAttempts = checkpoint.nativeStructuredAttempts ?? 0
|
|
543
557
|
if (!Number.isSafeInteger(nativeAttempts) || nativeAttempts < 0)
|
|
544
558
|
throw new Error('Invalid nativeStructuredAttempts in checkpoint')
|
|
@@ -11,6 +11,7 @@ import { type PersistedRunEvent, isEphemeralEvent } from '../../types/run/events
|
|
|
11
11
|
import type { RunEvent } from '../../types/run/index.js'
|
|
12
12
|
import type { ReadRunEventsOptions } from '../../types/run/store.js'
|
|
13
13
|
import type { TaskEvent, TaskStore } from '../../types/task/index.js'
|
|
14
|
+
import { awaitWithAbort } from '../../utils/await-with-abort.js'
|
|
14
15
|
import { SCOPE_ATTRIBUTE } from '../../utils/log/types.js'
|
|
15
16
|
import { type Logger, resolveLogger } from '../../utils/logger.js'
|
|
16
17
|
|
|
@@ -78,6 +79,27 @@ export class EventTranslator {
|
|
|
78
79
|
return this.withTranscriptLock(() => this.runMgr.getRunStore().readEvents(options))
|
|
79
80
|
}
|
|
80
81
|
|
|
82
|
+
captureRunEvidence(
|
|
83
|
+
maxReadBytes?: number,
|
|
84
|
+
signal?: AbortSignal,
|
|
85
|
+
): Promise<import('../../store/evidence/types.js').RunTextEvidenceSource | undefined> {
|
|
86
|
+
const capture = this.withTranscriptLock(async () => {
|
|
87
|
+
signal?.throwIfAborted()
|
|
88
|
+
const run = this.runMgr.getRun()
|
|
89
|
+
if (run.status !== 'running')
|
|
90
|
+
throw new Error('Evidence capture requires the active invocation.')
|
|
91
|
+
const { tenantId, projectId, sessionId, runId } = this.runMgr.getRunScope()
|
|
92
|
+
const source = await this.runMgr
|
|
93
|
+
.getRunStore()
|
|
94
|
+
.captureTextEvidence?.({ tenantId, projectId, sessionId, runId }, maxReadBytes, signal)
|
|
95
|
+
signal?.throwIfAborted()
|
|
96
|
+
if (this.runMgr.getRun().status !== 'running')
|
|
97
|
+
throw new Error('Evidence capture requires the active invocation.')
|
|
98
|
+
return source
|
|
99
|
+
})
|
|
100
|
+
return awaitWithAbort(capture, signal)
|
|
101
|
+
}
|
|
102
|
+
|
|
81
103
|
setGeneration(fence: FencingToken | undefined): void {
|
|
82
104
|
this.generation = fence
|
|
83
105
|
}
|
|
@@ -43,12 +43,16 @@ import type {
|
|
|
43
43
|
ToolCallRepairReason,
|
|
44
44
|
} from '../../types/tool/repair.js'
|
|
45
45
|
import { abortReasonText } from '../../utils/abort.js'
|
|
46
|
+
import { awaitWithAbort } from '../../utils/await-with-abort.js'
|
|
46
47
|
import { type BackoffPolicy, backoffWithJitter, sleep } from '../../utils/backoff.js'
|
|
47
48
|
import { toErrorMessage } from '../../utils/error.js'
|
|
48
49
|
import { generateToolCallId } from '../../utils/id.js'
|
|
49
50
|
import type { Logger } from '../../utils/logger.js'
|
|
50
51
|
import { compressShellOutput } from '../../utils/shell-compress.js'
|
|
51
52
|
import { type BackgroundJobRegistry, type JobProcess, bindOwner } from '../jobs/registry.js'
|
|
53
|
+
import { describeVisibleFileEvidence } from './file-evidence-context.js'
|
|
54
|
+
import { seedObservationLedger } from './file-evidence-seed.js'
|
|
55
|
+
import { skippedToolResultText } from './plugin-hooks.js'
|
|
52
56
|
import type { ToolResultObservation } from './project-instructions.js'
|
|
53
57
|
import { ToolCallBudget, assertMaxToolCalls } from './tool-call-budget.js'
|
|
54
58
|
import {
|
|
@@ -332,6 +336,16 @@ export interface ToolExecutorConfig {
|
|
|
332
336
|
* session and stops them itself when the session ends.
|
|
333
337
|
*/
|
|
334
338
|
backgroundJobOwner?: string
|
|
339
|
+
/**
|
|
340
|
+
* Where `wait_for_job` records that the model is waiting on a job.
|
|
341
|
+
*
|
|
342
|
+
* A callback rather than the recorder itself: the executor's part is to
|
|
343
|
+
* hand the tools a bound ref, and what the run does with the intent —
|
|
344
|
+
* hold itself open for the job — is the iteration loop's business. Absent
|
|
345
|
+
* means the bound ref has no `markAwaited` at all, so a host that wires no
|
|
346
|
+
* recorder gets no hold rather than a marking call that goes nowhere.
|
|
347
|
+
*/
|
|
348
|
+
onJobAwaited?: (id: string) => void
|
|
335
349
|
|
|
336
350
|
/**
|
|
337
351
|
* Where the `skill` tool reads from.
|
|
@@ -376,6 +390,8 @@ export interface ToolExecutorConfig {
|
|
|
376
390
|
* {@link DEFAULT_MAX_TOOL_OUTPUT_CHARS}; set `0` to disable.
|
|
377
391
|
*/
|
|
378
392
|
maxToolOutputChars?: number
|
|
393
|
+
/** See QueryParams.retainedToolPreviewChars; applies to the recorded host output. */
|
|
394
|
+
retainedToolPreviewChars?: number
|
|
379
395
|
|
|
380
396
|
/**
|
|
381
397
|
* Cap on the RICH channel of a single tool result, in base64
|
|
@@ -401,7 +417,8 @@ export interface ToolExecutorConfig {
|
|
|
401
417
|
* with `read`/`grep`. Absent ⇒ over-budget output is middle-elided and
|
|
402
418
|
* the overflow is lost.
|
|
403
419
|
*/
|
|
404
|
-
|
|
420
|
+
captureRunEvidence?: ToolContext['captureRunEvidence']
|
|
421
|
+
toolOutputDir?: string | (() => string | undefined)
|
|
405
422
|
/**
|
|
406
423
|
* Last chance to fix a tool call the model got wrong, before the error
|
|
407
424
|
* reaches it. See {@link RepairToolCall}.
|
|
@@ -491,6 +508,12 @@ export function deniedToolOutput(toolName: string, reason: string): string {
|
|
|
491
508
|
}
|
|
492
509
|
|
|
493
510
|
export class ToolExecutor {
|
|
511
|
+
private outputDirectory(): string | undefined {
|
|
512
|
+
return typeof this.config.toolOutputDir === 'function'
|
|
513
|
+
? this.config.toolOutputDir()
|
|
514
|
+
: this.config.toolOutputDir
|
|
515
|
+
}
|
|
516
|
+
|
|
494
517
|
private config: ToolExecutorConfig
|
|
495
518
|
private activityStore: ActivityStore
|
|
496
519
|
private emitEvent: EmitEvent
|
|
@@ -503,6 +526,8 @@ export class ToolExecutor {
|
|
|
503
526
|
/** Set per turn by the orchestrator; see {@link setStepAllowedTools}. */
|
|
504
527
|
private stepAllowedTools?: readonly string[]
|
|
505
528
|
private readonly fileReadTracker: FileReadTracker
|
|
529
|
+
/** A ledger is rebuilt from history at most once; a second pass would re-append its chains. */
|
|
530
|
+
private fileObservationsSeeded = false
|
|
506
531
|
|
|
507
532
|
constructor(
|
|
508
533
|
config: ToolExecutorConfig,
|
|
@@ -536,6 +561,49 @@ export class ToolExecutor {
|
|
|
536
561
|
this.config = { ...this.config, sandbox }
|
|
537
562
|
}
|
|
538
563
|
|
|
564
|
+
/**
|
|
565
|
+
* Rebuild this run's observation ledger from history a resume restored.
|
|
566
|
+
*
|
|
567
|
+
* Once, and only from a history that has already been repaired — the ledger
|
|
568
|
+
* has to describe what the model is about to be shown, not what was
|
|
569
|
+
* checkpointed before the repair removed an abandoned call. `sandboxed` is
|
|
570
|
+
* passed rather than read off this executor's config because a resumed run
|
|
571
|
+
* restores its history before it acquires a sandbox, so the config does not
|
|
572
|
+
* know yet what the run's tool paths will be keyed on.
|
|
573
|
+
*
|
|
574
|
+
* Awaited, and the only filesystem work anywhere in this feature: the seed
|
|
575
|
+
* has to write its entries under the keys the mutation tools will look them
|
|
576
|
+
* up under, which on a host means resolving each path through its symlinks
|
|
577
|
+
* the way `write` and `edit` do. No file's content is read.
|
|
578
|
+
*/
|
|
579
|
+
async seedFileObservations(messages: readonly Message[], sandboxed: boolean): Promise<void> {
|
|
580
|
+
if (this.fileObservationsSeeded) return
|
|
581
|
+
this.fileObservationsSeeded = true
|
|
582
|
+
const report = await seedObservationLedger(messages, this.fileReadTracker, {
|
|
583
|
+
workingDirectory: this.config.workingDirectory,
|
|
584
|
+
...(this.config.additionalDirectories
|
|
585
|
+
? { additionalDirectories: this.config.additionalDirectories }
|
|
586
|
+
: {}),
|
|
587
|
+
sandboxed,
|
|
588
|
+
})
|
|
589
|
+
this.log.info('Rebuilt the file observation ledger from restored history', {
|
|
590
|
+
[NAMZU.RUN_ID]: this.config.runId,
|
|
591
|
+
'namzu.files.witnessed': report.pathsWitnessed,
|
|
592
|
+
'namzu.files.seen': report.pathsSeen,
|
|
593
|
+
'namzu.files.replayed_units': report.unitsReplayed,
|
|
594
|
+
})
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
/** Request-only evidence from the same ledger used by mutation admission. No filesystem I/O. */
|
|
598
|
+
describeFileEvidence(messages: readonly Message[]): string | undefined {
|
|
599
|
+
return describeVisibleFileEvidence(
|
|
600
|
+
messages,
|
|
601
|
+
this.fileReadTracker,
|
|
602
|
+
this.config.workingDirectory,
|
|
603
|
+
this.config.sandbox !== undefined,
|
|
604
|
+
)
|
|
605
|
+
}
|
|
606
|
+
|
|
539
607
|
/**
|
|
540
608
|
* Span that this executor's tool spans should hang off — the current
|
|
541
609
|
* iteration. Re-set each turn by the orchestrator, because a tool span
|
|
@@ -1175,7 +1243,8 @@ export class ToolExecutor {
|
|
|
1175
1243
|
toolUseId: nestedId,
|
|
1176
1244
|
output: rawOutput,
|
|
1177
1245
|
maxChars: this.config.maxToolOutputChars ?? DEFAULT_MAX_TOOL_OUTPUT_CHARS,
|
|
1178
|
-
|
|
1246
|
+
retainedPreviewChars: this.config.retainedToolPreviewChars,
|
|
1247
|
+
spillDir: this.outputDirectory(),
|
|
1179
1248
|
onError: (message) =>
|
|
1180
1249
|
this.log.warn('Failed to spill oversized nested tool output', {
|
|
1181
1250
|
[NAMZU.RUN_ID]: this.config.runId,
|
|
@@ -1206,6 +1275,7 @@ export class ToolExecutor {
|
|
|
1206
1275
|
outputLength: budgeted.originalLength,
|
|
1207
1276
|
...(budgeted.truncated ? { outputTruncated: true } : {}),
|
|
1208
1277
|
...(budgeted.spillPath ? { outputSpillPath: budgeted.spillPath } : {}),
|
|
1278
|
+
...(budgeted.spillIntegrity ? { outputSpillIntegrity: budgeted.spillIntegrity } : {}),
|
|
1209
1279
|
...(via ? { via } : {}),
|
|
1210
1280
|
})
|
|
1211
1281
|
recordObservation({
|
|
@@ -1253,6 +1323,7 @@ export class ToolExecutor {
|
|
|
1253
1323
|
workingDirectory: this.config.workingDirectory,
|
|
1254
1324
|
},
|
|
1255
1325
|
invocationState: this.config.invocationState,
|
|
1326
|
+
captureRunEvidence: this.config.captureRunEvidence,
|
|
1256
1327
|
toolRegistry: this.config.tools,
|
|
1257
1328
|
// The step's list wins where it has one; the run's is the default.
|
|
1258
1329
|
// Same precedence the request already uses when it decides which
|
|
@@ -1318,6 +1389,7 @@ export class ToolExecutor {
|
|
|
1318
1389
|
) as JobProcess,
|
|
1319
1390
|
}
|
|
1320
1391
|
: {}),
|
|
1392
|
+
...(this.config.onJobAwaited ? { onAwaited: this.config.onJobAwaited } : {}),
|
|
1321
1393
|
},
|
|
1322
1394
|
),
|
|
1323
1395
|
}
|
|
@@ -1628,8 +1700,8 @@ export class ToolExecutor {
|
|
|
1628
1700
|
: formatFailedToolOutput(result.output, result.error)
|
|
1629
1701
|
|
|
1630
1702
|
const postOverride = post.override
|
|
1631
|
-
let output =
|
|
1632
|
-
|
|
1703
|
+
let output = postOverride?.output ?? rawOutput
|
|
1704
|
+
const preview = !postOverride && result.success ? this.maybeCompress(toolName, output) : output
|
|
1633
1705
|
let selectedContent = postOverride?.isError
|
|
1634
1706
|
? undefined
|
|
1635
1707
|
: (postOverride?.content ?? result.content)
|
|
@@ -1655,16 +1727,22 @@ export class ToolExecutor {
|
|
|
1655
1727
|
toolName,
|
|
1656
1728
|
toolUseId: toolCall.id,
|
|
1657
1729
|
output,
|
|
1730
|
+
preview,
|
|
1658
1731
|
maxChars: maxToolOutputChars,
|
|
1659
|
-
|
|
1732
|
+
retainedPreviewChars: this.config.retainedToolPreviewChars,
|
|
1733
|
+
spillDir: this.outputDirectory(),
|
|
1660
1734
|
onError: (message) =>
|
|
1661
|
-
this.log.warn('Failed to
|
|
1735
|
+
this.log.warn('Failed to retain original tool output', {
|
|
1662
1736
|
[NAMZU.RUN_ID]: this.config.runId,
|
|
1663
1737
|
[GENAI.TOOL_NAME]: toolName,
|
|
1664
1738
|
'exception.message': message,
|
|
1665
1739
|
}),
|
|
1666
1740
|
})
|
|
1667
|
-
if (
|
|
1741
|
+
if (
|
|
1742
|
+
budgeted.truncated &&
|
|
1743
|
+
maxToolOutputChars > 0 &&
|
|
1744
|
+
budgeted.originalLength > maxToolOutputChars
|
|
1745
|
+
) {
|
|
1668
1746
|
this.log.warn('Tool output exceeded the model-visible budget', {
|
|
1669
1747
|
[NAMZU.RUN_ID]: this.config.runId,
|
|
1670
1748
|
[GENAI.TOOL_NAME]: toolName,
|
|
@@ -1736,6 +1814,7 @@ export class ToolExecutor {
|
|
|
1736
1814
|
outputLength: budgeted.originalLength,
|
|
1737
1815
|
...(budgeted.truncated ? { outputTruncated: true } : {}),
|
|
1738
1816
|
...(budgeted.spillPath ? { outputSpillPath: budgeted.spillPath } : {}),
|
|
1817
|
+
...(budgeted.spillIntegrity ? { outputSpillIntegrity: budgeted.spillIntegrity } : {}),
|
|
1739
1818
|
})
|
|
1740
1819
|
recordObservation({
|
|
1741
1820
|
runId: this.config.runId,
|
|
@@ -1864,9 +1943,20 @@ export class ToolExecutor {
|
|
|
1864
1943
|
}
|
|
1865
1944
|
}
|
|
1866
1945
|
|
|
1946
|
+
const inheritedCapture = toolContext.captureRunEvidence
|
|
1947
|
+
const scopedCapture: ToolContext['captureRunEvidence'] = inheritedCapture
|
|
1948
|
+
? async (maxReadBytes, signal) => {
|
|
1949
|
+
const combined = signal
|
|
1950
|
+
? AbortSignal.any([controller.signal, signal])
|
|
1951
|
+
: controller.signal
|
|
1952
|
+
combined.throwIfAborted()
|
|
1953
|
+
return awaitWithAbort(inheritedCapture(maxReadBytes, combined), combined)
|
|
1954
|
+
}
|
|
1955
|
+
: undefined
|
|
1867
1956
|
const context = {
|
|
1868
1957
|
...toolContext,
|
|
1869
1958
|
abortSignal: controller.signal,
|
|
1959
|
+
...(scopedCapture ? { captureRunEvidence: scopedCapture } : {}),
|
|
1870
1960
|
...(scopedDispatch ? { dispatchTool: scopedDispatch } : {}),
|
|
1871
1961
|
}
|
|
1872
1962
|
const execution = prepared
|
|
@@ -2223,7 +2313,7 @@ export class ToolExecutor {
|
|
|
2223
2313
|
return {
|
|
2224
2314
|
kind: 'skip',
|
|
2225
2315
|
input: currentInput,
|
|
2226
|
-
output:
|
|
2316
|
+
output: skippedToolResultText(toolName, result.reason),
|
|
2227
2317
|
}
|
|
2228
2318
|
case 'error':
|
|
2229
2319
|
return {
|
|
@@ -2686,8 +2776,8 @@ export class ToolExecutor {
|
|
|
2686
2776
|
...(notice ? { notice } : {}),
|
|
2687
2777
|
// A tool may return different host and model text. They must
|
|
2688
2778
|
// never compete for the same exclusive spill filename.
|
|
2689
|
-
spillDir: this.
|
|
2690
|
-
? join(this.
|
|
2779
|
+
spillDir: this.outputDirectory()
|
|
2780
|
+
? join(this.outputDirectory() as string, 'content')
|
|
2691
2781
|
: undefined,
|
|
2692
2782
|
onError: (message) =>
|
|
2693
2783
|
this.log.warn('Failed to spill oversized model tool content', {
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import { fingerprintContent } from '../../tools/builtins/content-fingerprint.js'
|
|
2
|
+
import { ReadFileTool } from '../../tools/builtins/read-file.js'
|
|
3
|
+
import type { Message } from '../../types/message/index.js'
|
|
4
|
+
import type { FileReadTracker } from '../../types/tool/index.js'
|
|
5
|
+
import {
|
|
6
|
+
MAX_EDIT_CALLS,
|
|
7
|
+
MAX_PATH_UNITS,
|
|
8
|
+
MAX_WITNESSED_PATHS,
|
|
9
|
+
type ReplayBudget,
|
|
10
|
+
type VisibleHistory,
|
|
11
|
+
createReplayBudget,
|
|
12
|
+
indexVisibleHistory,
|
|
13
|
+
knownStale,
|
|
14
|
+
lexicalFileKeys,
|
|
15
|
+
replayHop,
|
|
16
|
+
spend,
|
|
17
|
+
visibleCall,
|
|
18
|
+
visibleEdit,
|
|
19
|
+
visibleWrite,
|
|
20
|
+
} from './file-evidence-replay.js'
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Receipt text a read entry may point at.
|
|
24
|
+
*
|
|
25
|
+
* The same class of bound as the one on a write call's arguments, and set to
|
|
26
|
+
* the same number for the same reason: past it the text is not read at all. A
|
|
27
|
+
* bigger file is simply not admitted this way — the model re-reads it, which is
|
|
28
|
+
* what it does today.
|
|
29
|
+
*/
|
|
30
|
+
const MAX_RECEIPT_UNITS = 32_000
|
|
31
|
+
|
|
32
|
+
interface FileEvidence {
|
|
33
|
+
readonly path: string
|
|
34
|
+
/** Absent on the write-rooted entries; `'read'` on a body that is a receipt. */
|
|
35
|
+
readonly kind?: 'read'
|
|
36
|
+
readonly bodyInCall: string
|
|
37
|
+
readonly editsInCalls?: readonly string[]
|
|
38
|
+
readonly observedFingerprint: string
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** Join visible call bodies, successful receipts and this executor's observation ledger. */
|
|
42
|
+
export function describeVisibleFileEvidence(
|
|
43
|
+
messages: readonly Message[],
|
|
44
|
+
tracker: FileReadTracker,
|
|
45
|
+
workingDirectory: string,
|
|
46
|
+
sandboxed: boolean,
|
|
47
|
+
): string | undefined {
|
|
48
|
+
// Execution-owned witnesses survive transparent wrappers; a name alone proves nothing.
|
|
49
|
+
if (!tracker.writeCallId || !tracker.fingerprint) return
|
|
50
|
+
// Lexical, as this projection has always looked entries up: a spelling that
|
|
51
|
+
// does not resolve to the tool's canonical key finds nothing and the path is
|
|
52
|
+
// simply not admitted. Writing the ledger is the side that has to key the
|
|
53
|
+
// way the tools do — see `file-evidence-seed.ts`.
|
|
54
|
+
const history = indexVisibleHistory(messages, lexicalFileKeys(workingDirectory, sandboxed))
|
|
55
|
+
const budget = createReplayBudget()
|
|
56
|
+
const files = new Map<string, FileEvidence>()
|
|
57
|
+
for (const [id, call] of history.calls) {
|
|
58
|
+
const name = call?.function.name
|
|
59
|
+
if (name !== 'write' && name !== 'edit' && name !== 'read') continue
|
|
60
|
+
try {
|
|
61
|
+
const admitted =
|
|
62
|
+
name === 'write'
|
|
63
|
+
? writeEvidence(id, tracker, history)
|
|
64
|
+
: name === 'edit'
|
|
65
|
+
? chainEvidence(id, tracker, history, budget)
|
|
66
|
+
: readEvidence(id, tracker, history)
|
|
67
|
+
if (!admitted) continue
|
|
68
|
+
// A write-rooted entry outranks a read of the same file: it names a
|
|
69
|
+
// body the model composed itself, and edits can be replayed onto it.
|
|
70
|
+
// The ledger already withholds a read witness where one survives; this
|
|
71
|
+
// keeps a read that ran BEFORE the write from taking the path back.
|
|
72
|
+
const held = files.get(admitted.key)
|
|
73
|
+
if (admitted.evidence.kind === 'read' && held && held.kind !== 'read') continue
|
|
74
|
+
files.delete(admitted.key)
|
|
75
|
+
files.set(admitted.key, admitted.evidence)
|
|
76
|
+
if (files.size > MAX_WITNESSED_PATHS) files.delete(files.keys().next().value as string)
|
|
77
|
+
} catch {
|
|
78
|
+
// Malformed retained inputs or a custom tracker cannot establish evidence.
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
if (files.size === 0) return
|
|
82
|
+
return `Visible file evidence (this request only): each entry's current body is the complete body in the named successful write call, with the edit calls in editsInCalls — when present — applied in that order. An entry marked kind:"read" instead names a successful read call whose own receipt shows the file WHOLE, rendered with every line behind its own N<tab> prefix; that receipt is the body, and such an entry never carries editsInCalls. This runtime performed that reconstruction and checked it against its own file observation; it is not a derivation left to you. Reuse the body for a targeted edit; a read solely to recall it is unnecessary. This is NOT a fresh disk check, and after a resume the observation behind an entry may itself have been rebuilt from this conversation's own earlier calls rather than made while this process ran. Built-in edit/write still compare the disk body at mutation admission and refuse observed drift; on refusal inspect the current file and replan. Missing entries establish nothing.\n${JSON.stringify([...files.values()])}`
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/** A full body that arrived whole in one call and is still the file's body. */
|
|
86
|
+
function writeEvidence(
|
|
87
|
+
id: string,
|
|
88
|
+
tracker: FileReadTracker,
|
|
89
|
+
history: VisibleHistory,
|
|
90
|
+
): { key: string; evidence: FileEvidence } | undefined {
|
|
91
|
+
const written = visibleWrite(history, id)
|
|
92
|
+
if (!written || knownStale(tracker, written.key)) return
|
|
93
|
+
const fingerprint = fingerprintContent(written.body)
|
|
94
|
+
if (
|
|
95
|
+
tracker.writeCallId?.(written.key) !== id ||
|
|
96
|
+
tracker.fingerprint?.(written.key) !== fingerprint
|
|
97
|
+
)
|
|
98
|
+
return
|
|
99
|
+
return {
|
|
100
|
+
key: written.key,
|
|
101
|
+
evidence: {
|
|
102
|
+
path: written.path,
|
|
103
|
+
bodyInCall: id,
|
|
104
|
+
observedFingerprint: fingerprint,
|
|
105
|
+
},
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* A full body plus the visible edits since, replayed and then checked.
|
|
111
|
+
*
|
|
112
|
+
* Only the chain's TIP establishes the path: a middle hop is validated as part
|
|
113
|
+
* of the walk below, and admitting one on its own would claim the file stops
|
|
114
|
+
* at an edit later calls have already moved past. The replay runs the same
|
|
115
|
+
* apply core the tool ran at mutation time, over call arguments that are
|
|
116
|
+
* already in the conversation — no filesystem read, and the result is compared
|
|
117
|
+
* to the ledger's disk-derived fingerprint, never written into it.
|
|
118
|
+
*/
|
|
119
|
+
function chainEvidence(
|
|
120
|
+
id: string,
|
|
121
|
+
tracker: FileReadTracker,
|
|
122
|
+
history: VisibleHistory,
|
|
123
|
+
budget: ReplayBudget,
|
|
124
|
+
): { key: string; evidence: FileEvidence } | undefined {
|
|
125
|
+
const tip = visibleEdit(history, id)
|
|
126
|
+
if (!tip || knownStale(tracker, tip.key)) return
|
|
127
|
+
const key = tip.key
|
|
128
|
+
const chain = tracker.editChain?.(key)
|
|
129
|
+
const observed = tracker.fingerprint?.(key)
|
|
130
|
+
if (!chain || observed === undefined || chain.editCallIds.at(-1) !== id) return
|
|
131
|
+
// The call bound before the walk, the unit bound before each operation it
|
|
132
|
+
// pays for. Neither is measured by doing the work it exists to refuse.
|
|
133
|
+
if (chain.editCallIds.length > MAX_EDIT_CALLS) return
|
|
134
|
+
const rootId = chain.rootWriteCallId
|
|
135
|
+
const root = visibleWrite(history, rootId)
|
|
136
|
+
// A root naming a different file is an ambiguity, not a base: the ledger
|
|
137
|
+
// and the visible call disagree about what was written where.
|
|
138
|
+
if (!root || root.key !== key) return
|
|
139
|
+
let content = root.body
|
|
140
|
+
if (!spend(budget, content.length)) return
|
|
141
|
+
for (const editId of chain.editCallIds) {
|
|
142
|
+
const hop = editId === id ? tip : visibleEdit(history, editId)
|
|
143
|
+
if (!hop || hop.key !== key) return
|
|
144
|
+
// Each of this hop's operations is measured against the body it is about
|
|
145
|
+
// to be applied to, charged, and only then applied — so a hop over the
|
|
146
|
+
// ceiling is refused before it is built rather than after, and one that
|
|
147
|
+
// fits is never turned away for a ceiling that guessed high. A hop the
|
|
148
|
+
// budget refuses, or one whose anchors no longer match, reconstructs
|
|
149
|
+
// nothing and withholds the whole path.
|
|
150
|
+
const replayed = replayHop(content, hop.input, budget)
|
|
151
|
+
if (replayed === undefined) return
|
|
152
|
+
content = replayed
|
|
153
|
+
}
|
|
154
|
+
if (fingerprintContent(content) !== observed) return
|
|
155
|
+
return {
|
|
156
|
+
key,
|
|
157
|
+
evidence: {
|
|
158
|
+
path: root.path,
|
|
159
|
+
bodyInCall: rootId,
|
|
160
|
+
editsInCalls: [...chain.editCallIds],
|
|
161
|
+
observedFingerprint: observed,
|
|
162
|
+
},
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* A body the model can still see because a read of the whole file put it there.
|
|
168
|
+
*
|
|
169
|
+
* Structurally unlike the two above, and deliberately so. They name a body the
|
|
170
|
+
* model itself composed, in arguments this projection can parse and replay; this
|
|
171
|
+
* names a RESULT, and the only thing anyone is allowed to do with it is compare
|
|
172
|
+
* it. The tool fingerprinted the exact string it emitted, and the entry is
|
|
173
|
+
* admitted only while the receipt still fingerprints to that — so a receipt the
|
|
174
|
+
* output budget elided or spilled, one compaction cleared, or one changed in any
|
|
175
|
+
* other way withholds the path rather than pointing the model at a body that is
|
|
176
|
+
* no longer in front of it. Nothing here undoes the line numbering to recover
|
|
177
|
+
* text: the numbering is what makes the comparison conclusive, not an encoding
|
|
178
|
+
* to be reversed.
|
|
179
|
+
*
|
|
180
|
+
* No chain, ever. A read roots nothing, so an entry here is the file as that one
|
|
181
|
+
* call showed it, and the ledger drops the witness the moment an edit lands.
|
|
182
|
+
*/
|
|
183
|
+
function readEvidence(
|
|
184
|
+
id: string,
|
|
185
|
+
tracker: FileReadTracker,
|
|
186
|
+
history: VisibleHistory,
|
|
187
|
+
): { key: string; evidence: FileEvidence } | undefined {
|
|
188
|
+
if (!tracker.readWitness) return
|
|
189
|
+
const call = visibleCall(history, id, 'read')
|
|
190
|
+
const shown = history.results.get(id)?.content
|
|
191
|
+
if (!call || typeof shown !== 'string' || shown.length > MAX_RECEIPT_UNITS) return
|
|
192
|
+
const input = ReadFileTool.inputSchema.safeParse(JSON.parse(call.function.arguments))
|
|
193
|
+
if (!input.success || input.data.path.length > MAX_PATH_UNITS) return
|
|
194
|
+
const key = history.keyOf(input.data.path)
|
|
195
|
+
if (key === undefined || knownStale(tracker, key)) return
|
|
196
|
+
const witness = tracker.readWitness(key)
|
|
197
|
+
const observed = tracker.fingerprint?.(key)
|
|
198
|
+
if (!witness || witness.callId !== id || observed === undefined) return
|
|
199
|
+
if (fingerprintContent(shown) !== witness.renderedFingerprint) return
|
|
200
|
+
return {
|
|
201
|
+
key,
|
|
202
|
+
evidence: {
|
|
203
|
+
path: input.data.path,
|
|
204
|
+
kind: 'read',
|
|
205
|
+
bodyInCall: id,
|
|
206
|
+
observedFingerprint: observed,
|
|
207
|
+
},
|
|
208
|
+
}
|
|
209
|
+
}
|