@namzu/sdk 38.2.1 → 39.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 +700 -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/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.map +1 -1
- package/dist/manager/run/persistence.js +6 -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 +13 -3
- package/dist/public-runtime.d.ts.map +1 -1
- package/dist/public-runtime.js +12 -3
- package/dist/public-runtime.js.map +1 -1
- package/dist/public-tools.d.ts +2 -0
- package/dist/public-tools.d.ts.map +1 -1
- package/dist/public-tools.js +2 -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/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/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 +7 -1
- package/dist/runtime/query/executor.d.ts.map +1 -1
- package/dist/runtime/query/executor.js +38 -7
- 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 +64 -0
- package/dist/runtime/query/file-evidence-context.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 +39 -24
- package/dist/runtime/query/index.js.map +1 -1
- package/dist/runtime/query/iteration/index.d.ts +9 -31
- package/dist/runtime/query/iteration/index.d.ts.map +1 -1
- package/dist/runtime/query/iteration/index.js +231 -93
- 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 +2 -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 +3 -0
- 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/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/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 +3 -1
- package/dist/runtime/query/tooling.d.ts.map +1 -1
- package/dist/runtime/query/tooling.js +4 -0
- package/dist/runtime/query/tooling.js.map +1 -1
- package/dist/scheduler/completion-inbox.d.ts +3 -0
- package/dist/scheduler/completion-inbox.d.ts.map +1 -1
- package/dist/scheduler/completion-inbox.js +28 -0
- 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/job.d.ts.map +1 -1
- package/dist/tools/builtins/job.js +4 -5
- package/dist/tools/builtins/job.js.map +1 -1
- package/dist/tools/builtins/write-file.js +2 -2
- package/dist/tools/builtins/write-file.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 +12 -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 +8 -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 +7 -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/tool/index.d.ts +15 -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/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/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 +6 -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 +30 -0
- package/src/public-tools.ts +3 -0
- package/src/public-types.ts +98 -0
- 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/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 +51 -9
- package/src/runtime/query/file-evidence-context.ts +65 -0
- package/src/runtime/query/guard.ts +2 -0
- package/src/runtime/query/index.ts +49 -25
- package/src/runtime/query/iteration/index.ts +269 -86
- package/src/runtime/query/iteration/phases/advisory.ts +3 -0
- package/src/runtime/query/iteration/phases/context.ts +2 -0
- package/src/runtime/query/iteration/phases/tool-review.ts +3 -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/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/tool-output-budget.ts +65 -13
- package/src/runtime/query/tooling.ts +7 -1
- package/src/scheduler/completion-inbox.ts +26 -0
- 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/job.ts +4 -5
- package/src/tools/builtins/write-file.ts +2 -2
- package/src/tools/defineTool.ts +4 -2
- package/src/tools/file-read-tracker.ts +8 -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 +20 -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 +7 -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/tool/index.ts +19 -1
- package/src/utils/await-with-abort.ts +26 -0
- package/src/utils/evidence-time.ts +9 -0
- package/src/utils/evidence-tokens.ts +32 -0
|
@@ -0,0 +1,461 @@
|
|
|
1
|
+
import { lstat } from 'node:fs/promises'
|
|
2
|
+
import type { FileHandle } from 'node:fs/promises'
|
|
3
|
+
import { join, resolve } from 'node:path'
|
|
4
|
+
import { z } from 'zod'
|
|
5
|
+
import { EVIDENCE_CHUNK_BYTES, digest, mayContain, mayContainToken } from './format.js'
|
|
6
|
+
import {
|
|
7
|
+
type EvidenceSeal,
|
|
8
|
+
entrySchema,
|
|
9
|
+
evidenceSeal,
|
|
10
|
+
indexPage,
|
|
11
|
+
positionSchema,
|
|
12
|
+
} from './index-page.js'
|
|
13
|
+
import {
|
|
14
|
+
type EvidenceBudget,
|
|
15
|
+
EvidencePageLimit,
|
|
16
|
+
PAGE_BYTES,
|
|
17
|
+
RECORD_BYTES,
|
|
18
|
+
decode,
|
|
19
|
+
openEvidence,
|
|
20
|
+
readBytes,
|
|
21
|
+
readSmall,
|
|
22
|
+
stamp,
|
|
23
|
+
} from './io.js'
|
|
24
|
+
import { passageMatcher, passagesInWindow } from './passages.js'
|
|
25
|
+
import { evidenceSearchInput, evidenceTermRefinement, evidenceTermsSchema } from './search-input.js'
|
|
26
|
+
import {
|
|
27
|
+
evidenceExclusionsKey,
|
|
28
|
+
evidenceExclusionsSchema,
|
|
29
|
+
excludesSuccessfulTool,
|
|
30
|
+
} from './selection.js'
|
|
31
|
+
import { createTextSourceReader, readTextPage } from './source-text.js'
|
|
32
|
+
import type {
|
|
33
|
+
DiskRunEvidenceOptions,
|
|
34
|
+
RunEvidenceReadOptions,
|
|
35
|
+
RunEvidenceReadResult,
|
|
36
|
+
RunEvidenceSource,
|
|
37
|
+
RunTextEvidenceMatch,
|
|
38
|
+
RunTextEvidenceReadResult,
|
|
39
|
+
RunTextEvidenceSearchOptions,
|
|
40
|
+
RunTextEvidenceSource,
|
|
41
|
+
} from './types.js'
|
|
42
|
+
|
|
43
|
+
const integer = z.number().int().nonnegative().safe()
|
|
44
|
+
const scopeSchema = z
|
|
45
|
+
.object({
|
|
46
|
+
tenantId: z.string().uuid(),
|
|
47
|
+
projectId: z.string().uuid(),
|
|
48
|
+
sessionId: z.string().uuid(),
|
|
49
|
+
runId: z.string().uuid(),
|
|
50
|
+
})
|
|
51
|
+
.strict()
|
|
52
|
+
const cursorSchema = z.object({
|
|
53
|
+
kind: z.enum(['search', 'search-terms', 'search-tokens']),
|
|
54
|
+
query: z.string().max(256),
|
|
55
|
+
termsKey: z
|
|
56
|
+
.string()
|
|
57
|
+
.regex(/^[a-f0-9]{64}$/)
|
|
58
|
+
.optional(),
|
|
59
|
+
caseSensitive: z.boolean().default(true),
|
|
60
|
+
matchMode: z.enum(['literal', 'token']).default('literal'),
|
|
61
|
+
exclusionsKey: z
|
|
62
|
+
.string()
|
|
63
|
+
.regex(/^[a-f0-9]{64}$/)
|
|
64
|
+
.optional(),
|
|
65
|
+
seq: integer.optional(),
|
|
66
|
+
part: integer.optional(),
|
|
67
|
+
mode: z.enum(['tools', 'text']).default('tools'),
|
|
68
|
+
position: positionSchema,
|
|
69
|
+
entry: integer.max(64),
|
|
70
|
+
chunk: integer,
|
|
71
|
+
within: integer.default(0),
|
|
72
|
+
})
|
|
73
|
+
const pointerSchema = entrySchema.pick({
|
|
74
|
+
offset: true,
|
|
75
|
+
length: true,
|
|
76
|
+
sha256: true,
|
|
77
|
+
seq: true,
|
|
78
|
+
part: true,
|
|
79
|
+
})
|
|
80
|
+
const addressSchema = z.object({ kind: z.literal('text'), entry: pointerSchema })
|
|
81
|
+
|
|
82
|
+
/** Ignore an uncommitted tail in a nonterminal snapshot without repairing the writer's file. */
|
|
83
|
+
async function completePrefix(handle: FileHandle, size: number, budget: EvidenceBudget) {
|
|
84
|
+
if ((await readBytes(handle, size - 1, 1, budget))[0] === 10) return size
|
|
85
|
+
const floor = Math.max(0, size - RECORD_BYTES)
|
|
86
|
+
let end = size - 1
|
|
87
|
+
while (end > floor) {
|
|
88
|
+
const start = Math.max(floor, end - 65_536)
|
|
89
|
+
const bytes = await readBytes(handle, start, end - start, budget)
|
|
90
|
+
const newline = bytes.lastIndexOf(10)
|
|
91
|
+
if (newline >= 0) return start + newline + 1
|
|
92
|
+
end = start
|
|
93
|
+
}
|
|
94
|
+
if (floor === 0) throw new Error('Transcript has no complete recorded evidence.')
|
|
95
|
+
throw new Error('Incomplete transcript tail exceeds the bounded record size.')
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* @experimental Bounded, authenticated disk index over one explicitly authorized run.
|
|
99
|
+
* Closed by default; snapshot mode permits nonterminal metadata without assuming a dead writer.
|
|
100
|
+
* The host owns authorization and the private directories. Stat changes invalidate addresses;
|
|
101
|
+
* individual record/chunk digests detect changed bytes. This is not a hostile filesystem sandbox.
|
|
102
|
+
*/
|
|
103
|
+
export function createDiskRunTextEvidenceSource(
|
|
104
|
+
options: DiskRunEvidenceOptions,
|
|
105
|
+
): RunTextEvidenceSource {
|
|
106
|
+
return createSource(options, 'text')
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/** @experimental Tool-only view of the shared invocation text index. */
|
|
110
|
+
export function createDiskRunEvidenceSource(options: DiskRunEvidenceOptions): RunEvidenceSource {
|
|
111
|
+
const source = createSource(options, 'tools')
|
|
112
|
+
const tool = <T extends { toolName?: string; isError?: boolean }>(value: T) => {
|
|
113
|
+
if (value.toolName === undefined || value.isError === undefined)
|
|
114
|
+
throw new Error('Expected tool evidence.')
|
|
115
|
+
return { ...value, toolName: value.toolName, isError: value.isError }
|
|
116
|
+
}
|
|
117
|
+
return Object.freeze({
|
|
118
|
+
scope: source.scope,
|
|
119
|
+
supportsTermRefinement: true,
|
|
120
|
+
async search(options: RunTextEvidenceSearchOptions = {}, signal?: AbortSignal) {
|
|
121
|
+
const result = await source.search(options, signal)
|
|
122
|
+
return { ...result, matches: result.matches.map(tool) }
|
|
123
|
+
},
|
|
124
|
+
async read(
|
|
125
|
+
options: RunEvidenceReadOptions,
|
|
126
|
+
signal?: AbortSignal,
|
|
127
|
+
): Promise<RunEvidenceReadResult> {
|
|
128
|
+
return tool(await source.read(options, signal))
|
|
129
|
+
},
|
|
130
|
+
})
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function createSource(
|
|
134
|
+
options: DiskRunEvidenceOptions,
|
|
135
|
+
mode: 'tools' | 'text',
|
|
136
|
+
): RunTextEvidenceSource {
|
|
137
|
+
const consistency = z.enum(['closed', 'snapshot']).parse(options.consistency ?? 'closed')
|
|
138
|
+
const maxReadBytes = z
|
|
139
|
+
.number()
|
|
140
|
+
.int()
|
|
141
|
+
.min(1024 * 1024)
|
|
142
|
+
.max(PAGE_BYTES)
|
|
143
|
+
.parse(options.maxReadBytes ?? PAGE_BYTES)
|
|
144
|
+
const scope = Object.freeze(scopeSchema.parse(options.scope))
|
|
145
|
+
const runDir = resolve(options.runDir)
|
|
146
|
+
const indexDir = resolve(options.indexDir)
|
|
147
|
+
const scopeKey = digest(JSON.stringify(scope))
|
|
148
|
+
async function access<T>(
|
|
149
|
+
signal: AbortSignal | undefined,
|
|
150
|
+
requestedBytes: number | undefined,
|
|
151
|
+
action: (
|
|
152
|
+
handle: FileHandle,
|
|
153
|
+
size: number,
|
|
154
|
+
seal: EvidenceSeal,
|
|
155
|
+
sourceKey: string,
|
|
156
|
+
budget: EvidenceBudget,
|
|
157
|
+
nonterminal: boolean,
|
|
158
|
+
) => Promise<T>,
|
|
159
|
+
): Promise<T> {
|
|
160
|
+
const budget: EvidenceBudget = {
|
|
161
|
+
bytes: 0,
|
|
162
|
+
limit: Math.min(maxReadBytes, requestedBytes ?? maxReadBytes),
|
|
163
|
+
signal,
|
|
164
|
+
}
|
|
165
|
+
signal?.throwIfAborted()
|
|
166
|
+
const metaPath = join(runDir, 'run.json')
|
|
167
|
+
const metaStamp = stamp(await lstat(metaPath))
|
|
168
|
+
const metaBytes = await readSmall(metaPath, budget, 512 * 1024)
|
|
169
|
+
if (metaStamp !== stamp(await lstat(metaPath)))
|
|
170
|
+
throw new Error('Run metadata changed during retrieval.')
|
|
171
|
+
const meta = JSON.parse(decode(metaBytes))
|
|
172
|
+
const terminal = ['completed', 'failed', 'cancelled'].includes(meta.status)
|
|
173
|
+
const readable =
|
|
174
|
+
terminal ||
|
|
175
|
+
(consistency === 'snapshot' && ['idle', 'pending', 'running'].includes(meta.status))
|
|
176
|
+
if (
|
|
177
|
+
meta.id !== scope.runId ||
|
|
178
|
+
!readable ||
|
|
179
|
+
JSON.stringify(scopeSchema.parse(meta.metadata?.scope)) !== JSON.stringify(scope)
|
|
180
|
+
)
|
|
181
|
+
throw new Error(
|
|
182
|
+
consistency === 'closed'
|
|
183
|
+
? 'Evidence run is not closed or does not belong to the authorized scope.'
|
|
184
|
+
: 'Evidence run does not satisfy snapshot consistency or its authorized scope.',
|
|
185
|
+
)
|
|
186
|
+
const path = join(runDir, 'transcript.jsonl')
|
|
187
|
+
const handle = await openEvidence(path)
|
|
188
|
+
try {
|
|
189
|
+
const before = await handle.stat()
|
|
190
|
+
if (before.size === 0) throw new Error('Transcript is empty; evidence is incomplete.')
|
|
191
|
+
const size =
|
|
192
|
+
consistency === 'snapshot' && !terminal
|
|
193
|
+
? await completePrefix(handle, before.size, budget)
|
|
194
|
+
: before.size
|
|
195
|
+
const sourceKey = digest(
|
|
196
|
+
`${consistency === 'snapshot' ? 'snapshot-v1:' : ''}${mode === 'text' ? 'text-v2:' : ''}${scopeKey}:${stamp(before)}:${digest(metaBytes)}`,
|
|
197
|
+
)
|
|
198
|
+
const seal = await evidenceSeal(indexDir, scopeKey, sourceKey, budget)
|
|
199
|
+
const value = await action(handle, size, seal, sourceKey, budget, !terminal)
|
|
200
|
+
signal?.throwIfAborted()
|
|
201
|
+
if (
|
|
202
|
+
stamp(before) !== stamp(await handle.stat()) ||
|
|
203
|
+
stamp(before) !== stamp(await lstat(path)) ||
|
|
204
|
+
metaStamp !== stamp(await lstat(metaPath))
|
|
205
|
+
)
|
|
206
|
+
throw new Error('Evidence source changed during retrieval.')
|
|
207
|
+
return value
|
|
208
|
+
} finally {
|
|
209
|
+
await handle.close()
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
return Object.freeze({
|
|
213
|
+
scope,
|
|
214
|
+
supportsTermRefinement: true,
|
|
215
|
+
async search(options: RunTextEvidenceSearchOptions = {}, signal?: AbortSignal) {
|
|
216
|
+
const input = z
|
|
217
|
+
.object({
|
|
218
|
+
maxReadBytes: integer
|
|
219
|
+
.min(1024 * 1024)
|
|
220
|
+
.max(PAGE_BYTES)
|
|
221
|
+
.optional(),
|
|
222
|
+
query: z.string().max(256).optional(),
|
|
223
|
+
terms: evidenceTermsSchema,
|
|
224
|
+
refineTerms: evidenceTermsSchema,
|
|
225
|
+
caseSensitive: z.boolean().default(true),
|
|
226
|
+
matchMode: z.enum(['literal', 'token']).default('literal'),
|
|
227
|
+
excludeSuccessfulTools: evidenceExclusionsSchema,
|
|
228
|
+
excludeDerivedSummaries: z.boolean().default(false),
|
|
229
|
+
cursor: z.string().max(4096).optional(),
|
|
230
|
+
seq: integer.positive().optional(),
|
|
231
|
+
part: integer.optional(),
|
|
232
|
+
limit: integer.min(1).max(4).default(4),
|
|
233
|
+
})
|
|
234
|
+
.strict()
|
|
235
|
+
.parse(options)
|
|
236
|
+
if (input.part !== undefined && input.seq === undefined)
|
|
237
|
+
throw new Error('Part requires an event sequence.')
|
|
238
|
+
const { query, terms, termsKey, browse } = evidenceSearchInput(input)
|
|
239
|
+
const refined = input.refineTerms
|
|
240
|
+
? evidenceSearchInput({
|
|
241
|
+
terms: evidenceTermRefinement(input, input.refineTerms),
|
|
242
|
+
matchMode: 'token',
|
|
243
|
+
})
|
|
244
|
+
: undefined
|
|
245
|
+
const selectedTerms = refined?.terms ?? terms
|
|
246
|
+
const exclusionsKey = evidenceExclusionsKey(
|
|
247
|
+
input.excludeSuccessfulTools,
|
|
248
|
+
input.excludeDerivedSummaries,
|
|
249
|
+
)
|
|
250
|
+
const kind =
|
|
251
|
+
input.matchMode === 'token'
|
|
252
|
+
? ('search-tokens' as const)
|
|
253
|
+
: terms
|
|
254
|
+
? ('search-terms' as const)
|
|
255
|
+
: ('search' as const)
|
|
256
|
+
return access(
|
|
257
|
+
signal,
|
|
258
|
+
input.maxReadBytes,
|
|
259
|
+
async (handle, size, seal, sourceKey, budget, nonterminal) => {
|
|
260
|
+
const readSource = createTextSourceReader(handle, runDir, scope.runId, budget)
|
|
261
|
+
const cursor = input.cursor
|
|
262
|
+
? cursorSchema.parse(seal.unpack(input.cursor))
|
|
263
|
+
: {
|
|
264
|
+
kind,
|
|
265
|
+
query,
|
|
266
|
+
termsKey,
|
|
267
|
+
exclusionsKey,
|
|
268
|
+
seq: input.seq,
|
|
269
|
+
part: input.part,
|
|
270
|
+
mode,
|
|
271
|
+
position: { offset: 0, seq: 0, textIndex: 0 },
|
|
272
|
+
entry: 0,
|
|
273
|
+
chunk: 0,
|
|
274
|
+
within: 0,
|
|
275
|
+
caseSensitive: input.caseSensitive,
|
|
276
|
+
matchMode: input.matchMode,
|
|
277
|
+
}
|
|
278
|
+
if (
|
|
279
|
+
cursor.kind !== kind ||
|
|
280
|
+
cursor.query !== query ||
|
|
281
|
+
cursor.termsKey !== termsKey ||
|
|
282
|
+
cursor.exclusionsKey !== exclusionsKey ||
|
|
283
|
+
cursor.caseSensitive !== input.caseSensitive ||
|
|
284
|
+
cursor.matchMode !== input.matchMode ||
|
|
285
|
+
cursor.seq !== input.seq ||
|
|
286
|
+
cursor.part !== input.part ||
|
|
287
|
+
cursor.mode !== mode
|
|
288
|
+
)
|
|
289
|
+
throw new Error('Search cursor query changed.')
|
|
290
|
+
// Authenticate the original query first, then seal future cursors
|
|
291
|
+
// with the narrower key at exactly the same archive position.
|
|
292
|
+
if (refined) cursor.termsKey = refined.termsKey
|
|
293
|
+
const { page, cacheHit } = await indexPage(
|
|
294
|
+
handle,
|
|
295
|
+
size,
|
|
296
|
+
scope.runId,
|
|
297
|
+
cursor.position,
|
|
298
|
+
seal,
|
|
299
|
+
sourceKey,
|
|
300
|
+
budget,
|
|
301
|
+
)
|
|
302
|
+
const matches: RunTextEvidenceMatch[] = []
|
|
303
|
+
const unavailable: string[] = []
|
|
304
|
+
let partial = false
|
|
305
|
+
let excludedToolResults = 0
|
|
306
|
+
let excludedSummaries = 0
|
|
307
|
+
let entryIndex = cursor.entry
|
|
308
|
+
let chunk = cursor.chunk
|
|
309
|
+
let within = cursor.within
|
|
310
|
+
const matchPassage = passageMatcher(
|
|
311
|
+
selectedTerms ?? query,
|
|
312
|
+
input.caseSensitive,
|
|
313
|
+
input.matchMode,
|
|
314
|
+
)
|
|
315
|
+
while (entryIndex < page.entries.length && matches.length < input.limit) {
|
|
316
|
+
const entry = page.entries[entryIndex]
|
|
317
|
+
if (!entry) throw new Error('Invalid index entry.')
|
|
318
|
+
if (
|
|
319
|
+
(mode === 'tools' && entry.source !== 'tool_completed') ||
|
|
320
|
+
(input.seq !== undefined && entry.seq !== input.seq) ||
|
|
321
|
+
(input.part !== undefined && entry.part !== input.part)
|
|
322
|
+
) {
|
|
323
|
+
entryIndex++
|
|
324
|
+
chunk = 0
|
|
325
|
+
within = 0
|
|
326
|
+
continue
|
|
327
|
+
}
|
|
328
|
+
try {
|
|
329
|
+
const derived =
|
|
330
|
+
input.excludeDerivedSummaries && entry.source === 'compaction_shed:summary'
|
|
331
|
+
if (derived || excludesSuccessfulTool(entry, input.excludeSuccessfulTools)) {
|
|
332
|
+
if (derived) excludedSummaries++
|
|
333
|
+
else excludedToolResults++
|
|
334
|
+
entryIndex++
|
|
335
|
+
chunk = 0
|
|
336
|
+
within = 0
|
|
337
|
+
continue
|
|
338
|
+
}
|
|
339
|
+
if (entry.truncated && !entry.spill) partial = true
|
|
340
|
+
if (
|
|
341
|
+
!entry.spill &&
|
|
342
|
+
!(selectedTerms ?? [query]).some((term) =>
|
|
343
|
+
input.matchMode === 'token'
|
|
344
|
+
? mayContainToken(entry.tokenFilter, term) &&
|
|
345
|
+
(!input.caseSensitive || mayContain(entry.filter, term))
|
|
346
|
+
: !input.caseSensitive || mayContain(entry.filter, term),
|
|
347
|
+
)
|
|
348
|
+
) {
|
|
349
|
+
entryIndex++
|
|
350
|
+
chunk = 0
|
|
351
|
+
within = 0
|
|
352
|
+
continue
|
|
353
|
+
}
|
|
354
|
+
const source = await readSource(entry)
|
|
355
|
+
while (chunk < source.chunks && matches.length < input.limit) {
|
|
356
|
+
signal?.throwIfAborted()
|
|
357
|
+
if (
|
|
358
|
+
(selectedTerms ?? [query]).some((term) =>
|
|
359
|
+
source.mayMatch(chunk, term, input.matchMode, input.caseSensitive),
|
|
360
|
+
)
|
|
361
|
+
) {
|
|
362
|
+
const window = await source.window(chunk, input.matchMode === 'token')
|
|
363
|
+
const text = decode(window.bytes)
|
|
364
|
+
const page = passagesInWindow(
|
|
365
|
+
text,
|
|
366
|
+
Math.max(within, window.searchFrom ?? 0),
|
|
367
|
+
matchPassage,
|
|
368
|
+
input.limit - matches.length,
|
|
369
|
+
entry.spill ? (chunk + 1) * EVIDENCE_CHUNK_BYTES - window.offset : undefined,
|
|
370
|
+
)
|
|
371
|
+
within = page.next
|
|
372
|
+
for (const { start, end } of page.passages) {
|
|
373
|
+
const excerpt = text.slice(start, end)
|
|
374
|
+
const byteOffset = window.offset + Buffer.byteLength(text.slice(0, start))
|
|
375
|
+
matches.push({
|
|
376
|
+
address: seal.pack({ kind: 'text', entry: pointerSchema.parse(entry) }),
|
|
377
|
+
seq: entry.seq,
|
|
378
|
+
recordedAt: source.recordedAt,
|
|
379
|
+
source: entry.source,
|
|
380
|
+
part: entry.part,
|
|
381
|
+
characterOffset:
|
|
382
|
+
window.characterOffset === undefined
|
|
383
|
+
? undefined
|
|
384
|
+
: window.characterOffset + start,
|
|
385
|
+
toolName: entry.toolName,
|
|
386
|
+
isError: entry.isError,
|
|
387
|
+
retained: source.retained,
|
|
388
|
+
excerpt,
|
|
389
|
+
excerptComplete:
|
|
390
|
+
source.retained === 'full' &&
|
|
391
|
+
byteOffset === 0 &&
|
|
392
|
+
Buffer.byteLength(excerpt) === source.bytes,
|
|
393
|
+
byteOffset,
|
|
394
|
+
})
|
|
395
|
+
}
|
|
396
|
+
if (within < text.length) break
|
|
397
|
+
}
|
|
398
|
+
within = 0
|
|
399
|
+
chunk++
|
|
400
|
+
if (browse) {
|
|
401
|
+
chunk = source.chunks
|
|
402
|
+
break
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
if (chunk < source.chunks) break
|
|
406
|
+
} catch (error) {
|
|
407
|
+
signal?.throwIfAborted()
|
|
408
|
+
if (error instanceof EvidencePageLimit) break
|
|
409
|
+
unavailable.push(`Text record ${entry.seq}/${entry.part} is unavailable or changed.`)
|
|
410
|
+
}
|
|
411
|
+
entryIndex++
|
|
412
|
+
chunk = 0
|
|
413
|
+
within = 0
|
|
414
|
+
}
|
|
415
|
+
const nextCursor =
|
|
416
|
+
entryIndex < page.entries.length
|
|
417
|
+
? seal.pack({ ...cursor, entry: entryIndex, chunk, within })
|
|
418
|
+
: page.next && (input.seq === undefined || page.next.seq < input.seq)
|
|
419
|
+
? seal.pack({ ...cursor, position: page.next, entry: 0, chunk: 0, within: 0 })
|
|
420
|
+
: null
|
|
421
|
+
return {
|
|
422
|
+
scope,
|
|
423
|
+
matches,
|
|
424
|
+
nextCursor,
|
|
425
|
+
scannedBytes: budget.bytes,
|
|
426
|
+
indexedRecords: cacheHit ? 0 : page.records,
|
|
427
|
+
cacheHit,
|
|
428
|
+
incomplete: nonterminal || unavailable.length > 0 || partial,
|
|
429
|
+
unavailable,
|
|
430
|
+
...(excludedToolResults ? { excludedToolResults } : {}),
|
|
431
|
+
...(excludedSummaries ? { excludedSummaries } : {}),
|
|
432
|
+
}
|
|
433
|
+
},
|
|
434
|
+
)
|
|
435
|
+
},
|
|
436
|
+
async read(
|
|
437
|
+
options: RunEvidenceReadOptions,
|
|
438
|
+
signal?: AbortSignal,
|
|
439
|
+
): Promise<RunTextEvidenceReadResult> {
|
|
440
|
+
const input = z
|
|
441
|
+
.object({
|
|
442
|
+
address: z.string().max(8192),
|
|
443
|
+
byteOffset: integer.optional(),
|
|
444
|
+
maxReadBytes: integer
|
|
445
|
+
.min(1024 * 1024)
|
|
446
|
+
.max(PAGE_BYTES)
|
|
447
|
+
.optional(),
|
|
448
|
+
})
|
|
449
|
+
.strict()
|
|
450
|
+
.parse(options)
|
|
451
|
+
return access(signal, input.maxReadBytes, async (handle, _size, seal, _sourceKey, budget) => {
|
|
452
|
+
const pointer = addressSchema.parse(seal.unpack(input.address)).entry
|
|
453
|
+
const source = await createTextSourceReader(handle, runDir, scope.runId, budget)(pointer)
|
|
454
|
+
const entry = source.entry
|
|
455
|
+
if (mode === 'tools' && entry.source !== 'tool_completed')
|
|
456
|
+
throw new Error('Not tool evidence.')
|
|
457
|
+
return readTextPage(source, scope, input.byteOffset ?? 0, budget)
|
|
458
|
+
})
|
|
459
|
+
},
|
|
460
|
+
})
|
|
461
|
+
}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto'
|
|
2
|
+
import { evidenceTokenEntries, evidenceTokenKey } from '../../utils/evidence-tokens.js'
|
|
3
|
+
import { RECORD_BYTES } from './io.js'
|
|
4
|
+
|
|
5
|
+
export const EVIDENCE_CHUNK_BYTES = 65_536
|
|
6
|
+
export const SEARCH_OVERLAP_BYTES = 1_024
|
|
7
|
+
const FILTER_BYTES = 1_024
|
|
8
|
+
const TOKEN_FILTER_PREFIX = `tokens-v1:${digest(`${process.version}:${process.versions.v8}:${process.versions.unicode}`).slice(0, 16)}:`
|
|
9
|
+
|
|
10
|
+
export function digest(value: string | Uint8Array): string {
|
|
11
|
+
return createHash('sha256').update(value).digest('hex')
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function hashAt(text: string, offset: number): number {
|
|
15
|
+
let hash = 2166136261
|
|
16
|
+
for (let i = 0; i < 3; i++) hash = Math.imul(hash ^ text.charCodeAt(offset + i), 16777619)
|
|
17
|
+
return hash >>> 0
|
|
18
|
+
}
|
|
19
|
+
function second(hash: number): number {
|
|
20
|
+
return Math.imul(hash ^ (hash >>> 16), 0x45d9f3b) >>> 0
|
|
21
|
+
}
|
|
22
|
+
function contains(bits: Buffer, hash: number): boolean {
|
|
23
|
+
const bit = hash % (bits.length * 8)
|
|
24
|
+
return ((bits[bit >>> 3] ?? 0) & (1 << (bit & 7))) !== 0
|
|
25
|
+
}
|
|
26
|
+
function set(bits: Buffer, hash: number): void {
|
|
27
|
+
const bit = hash % (bits.length * 8)
|
|
28
|
+
bits[bit >>> 3] = (bits[bit >>> 3] ?? 0) | (1 << (bit & 7))
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// A negative rules out a literal match; a positive always needs source verification.
|
|
32
|
+
export function textFilter(text: string): string {
|
|
33
|
+
const bits = Buffer.alloc(FILTER_BYTES)
|
|
34
|
+
for (let i = 0; i + 2 < text.length; i++) {
|
|
35
|
+
const hash = hashAt(text, i)
|
|
36
|
+
set(bits, hash)
|
|
37
|
+
set(bits, second(hash))
|
|
38
|
+
}
|
|
39
|
+
return bits.toString('base64')
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function mayContain(filter: string, query: string): boolean {
|
|
43
|
+
const bits = Buffer.from(filter, 'base64')
|
|
44
|
+
if (bits.length !== FILTER_BYTES) throw new Error('Invalid evidence filter.')
|
|
45
|
+
for (let i = 0; i + 2 < query.length; i++) {
|
|
46
|
+
const hash = hashAt(query, i)
|
|
47
|
+
if (!contains(bits, hash) || !contains(bits, second(hash))) return false
|
|
48
|
+
}
|
|
49
|
+
return true
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function tokenHash(token: string): number {
|
|
53
|
+
let hash = 2166136261
|
|
54
|
+
for (let i = 0; i < token.length; i++) hash = Math.imul(hash ^ token.charCodeAt(i), 16777619)
|
|
55
|
+
return hash >>> 0
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** Negative-only membership filter using the same whole-token keys as discovery. */
|
|
59
|
+
export function tokenFilter(text: string): string {
|
|
60
|
+
const bits = Buffer.alloc(text.length <= 1024 ? 128 : text.length <= 8192 ? 512 : FILTER_BYTES)
|
|
61
|
+
for (const match of evidenceTokenEntries(text)) {
|
|
62
|
+
const hash = tokenHash(evidenceTokenKey(match[0]))
|
|
63
|
+
set(bits, hash)
|
|
64
|
+
set(bits, second(hash))
|
|
65
|
+
}
|
|
66
|
+
return TOKEN_FILTER_PREFIX + bits.toString('base64')
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export function mayContainToken(filter: string | undefined, query: string): boolean {
|
|
70
|
+
if (filter === undefined || !filter.startsWith(TOKEN_FILTER_PREFIX)) return true
|
|
71
|
+
const bits = Buffer.from(filter.slice(TOKEN_FILTER_PREFIX.length), 'base64')
|
|
72
|
+
if (![128, 512, FILTER_BYTES].includes(bits.length))
|
|
73
|
+
throw new Error('Invalid evidence token filter.')
|
|
74
|
+
const hash = tokenHash(evidenceTokenKey(query))
|
|
75
|
+
return contains(bits, hash) && contains(bits, second(hash))
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/** Internal manifest, authenticated by the digest recorded in tool_completed. */
|
|
79
|
+
export interface SpillManifest {
|
|
80
|
+
version: 1
|
|
81
|
+
bytes: number
|
|
82
|
+
chars?: number
|
|
83
|
+
chunkBytes: number
|
|
84
|
+
chunks: { sha256: string; filter: string; tokenFilter?: string; characterOffset?: number }[]
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/** Optional acceleration must not reduce the previously retainable output size. */
|
|
88
|
+
export function encodeSpillManifest(manifest: SpillManifest): string {
|
|
89
|
+
const encoded = JSON.stringify(manifest)
|
|
90
|
+
if (Buffer.byteLength(encoded, 'utf8') <= RECORD_BYTES) return encoded
|
|
91
|
+
return JSON.stringify({
|
|
92
|
+
...manifest,
|
|
93
|
+
chunks: manifest.chunks.map(({ tokenFilter: _filter, ...chunk }) => chunk),
|
|
94
|
+
})
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export function spillManifest(bytes: Buffer): string {
|
|
98
|
+
const chunks: SpillManifest['chunks'] = []
|
|
99
|
+
let chars = 0
|
|
100
|
+
const boundary = (position: number) => {
|
|
101
|
+
let offset = position
|
|
102
|
+
while (offset < bytes.length && ((bytes[offset] ?? 0) & 0xc0) === 0x80) offset++
|
|
103
|
+
return Math.min(offset, bytes.length)
|
|
104
|
+
}
|
|
105
|
+
for (let offset = 0; offset < bytes.length; offset += EVIDENCE_CHUNK_BYTES) {
|
|
106
|
+
const text = bytes
|
|
107
|
+
.subarray(offset, offset + EVIDENCE_CHUNK_BYTES + SEARCH_OVERLAP_BYTES)
|
|
108
|
+
.toString('utf8')
|
|
109
|
+
chunks.push({
|
|
110
|
+
characterOffset: chars,
|
|
111
|
+
sha256: digest(bytes.subarray(offset, offset + EVIDENCE_CHUNK_BYTES)),
|
|
112
|
+
filter: textFilter(text),
|
|
113
|
+
tokenFilter: tokenFilter(text),
|
|
114
|
+
})
|
|
115
|
+
chars += bytes
|
|
116
|
+
.subarray(boundary(offset), boundary(offset + EVIDENCE_CHUNK_BYTES))
|
|
117
|
+
.toString('utf8').length
|
|
118
|
+
}
|
|
119
|
+
return encodeSpillManifest({
|
|
120
|
+
version: 1,
|
|
121
|
+
bytes: bytes.length,
|
|
122
|
+
chars,
|
|
123
|
+
chunkBytes: EVIDENCE_CHUNK_BYTES,
|
|
124
|
+
chunks,
|
|
125
|
+
})
|
|
126
|
+
}
|