@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,363 @@
|
|
|
1
|
+
import { z } from 'zod'
|
|
2
|
+
import {
|
|
3
|
+
type EvidenceRecallRequest,
|
|
4
|
+
type ScopedEvidenceRecallBatch,
|
|
5
|
+
type ScopedEvidenceRecallCandidate,
|
|
6
|
+
createScopedEvidenceRecallStep,
|
|
7
|
+
evidenceRecallQueryTokens,
|
|
8
|
+
refineEvidenceRecallTerms,
|
|
9
|
+
} from '../../run/evidence-recall.js'
|
|
10
|
+
import type { RunEvidenceScope } from '../../store/evidence/types.js'
|
|
11
|
+
import type { PrepareStep } from '../../types/run/prepare-step.js'
|
|
12
|
+
import { evidenceTokenKey } from '../../utils/evidence-tokens.js'
|
|
13
|
+
import { type ResidentState, residentStateSchema } from './store.js'
|
|
14
|
+
import type { ResidentToolEvidenceSource } from './tool-evidence.js'
|
|
15
|
+
|
|
16
|
+
/** @experimental Automatic original-tool recall for exactly one admitted resident run. */
|
|
17
|
+
export interface ResidentEvidenceRecallOptions {
|
|
18
|
+
readonly source: ResidentToolEvidenceSource
|
|
19
|
+
/** Already admitted state; summaries supply search words, never new observations. */
|
|
20
|
+
readonly state: ResidentState
|
|
21
|
+
/** The current executor, distinct from historical Session/run addresses. */
|
|
22
|
+
readonly scope: RunEvidenceScope
|
|
23
|
+
readonly maxChars?: number
|
|
24
|
+
readonly maxPassages?: number
|
|
25
|
+
readonly timeoutMs?: number
|
|
26
|
+
/** Host tool names whose successful archival copies should not occupy result slots. */
|
|
27
|
+
readonly excludeSuccessfulTools?: readonly string[]
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const ownerSchema = z.object({
|
|
31
|
+
tenantId: z.string().uuid(),
|
|
32
|
+
projectId: z.string().uuid(),
|
|
33
|
+
sessionId: z.string().uuid(),
|
|
34
|
+
runId: z.string().uuid(),
|
|
35
|
+
})
|
|
36
|
+
const historicalScopeSchema = ownerSchema.omit({ sessionId: true, runId: true }).extend({
|
|
37
|
+
agentKey: z.string().min(1).max(200),
|
|
38
|
+
pursuitId: z.string().uuid(),
|
|
39
|
+
throughRevision: z.number().int().positive().safe(),
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
// Sample both ends without merging or manufacturing a word at the cut. The
|
|
43
|
+
// field still contributes at most 4000 characters; its omitted middle is not
|
|
44
|
+
// inspected. Alternating ends also gives late corrections a term slot.
|
|
45
|
+
function residentQueryWords(text: string): string[] {
|
|
46
|
+
const words =
|
|
47
|
+
text.length <= 4000
|
|
48
|
+
? evidenceRecallQueryTokens(text)
|
|
49
|
+
: [
|
|
50
|
+
...evidenceRecallQueryTokens(
|
|
51
|
+
text
|
|
52
|
+
.slice(0, 2000)
|
|
53
|
+
.replace(/[\uD800-\uDBFF]$/u, '')
|
|
54
|
+
.replace(/[\p{L}\p{N}_]+$/u, ''),
|
|
55
|
+
),
|
|
56
|
+
...evidenceRecallQueryTokens(
|
|
57
|
+
text
|
|
58
|
+
.slice(-2000)
|
|
59
|
+
.replace(/^[\uDC00-\uDFFF]/u, '')
|
|
60
|
+
.replace(/^[\p{L}\p{N}_]+/u, ''),
|
|
61
|
+
),
|
|
62
|
+
]
|
|
63
|
+
const result: string[] = []
|
|
64
|
+
for (let left = 0, right = words.length - 1; left <= right; left++, right--) {
|
|
65
|
+
const first = words[left]
|
|
66
|
+
const last = words[right]
|
|
67
|
+
if (first) result.push(first)
|
|
68
|
+
if (left !== right && last) result.push(last)
|
|
69
|
+
}
|
|
70
|
+
return result
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Reuses the shared bounded ranking/rendering engine while retaining the
|
|
75
|
+
* pursuit's settlement authority. No arbitrary Session discovery, saved fact
|
|
76
|
+
* cache, inference, workspace reread or action replay is performed here.
|
|
77
|
+
*/
|
|
78
|
+
export function createResidentEvidenceRecallStep(
|
|
79
|
+
options: ResidentEvidenceRecallOptions,
|
|
80
|
+
): PrepareStep {
|
|
81
|
+
const state = residentStateSchema.parse(options.state)
|
|
82
|
+
const owner = Object.freeze(ownerSchema.parse(options.scope))
|
|
83
|
+
const source = options.source
|
|
84
|
+
const historicalScope = Object.freeze(historicalScopeSchema.parse(source.scope))
|
|
85
|
+
if (
|
|
86
|
+
state.phase !== 'running' ||
|
|
87
|
+
!state.claimId ||
|
|
88
|
+
state.tenantId !== owner.tenantId ||
|
|
89
|
+
state.tenantId !== historicalScope.tenantId ||
|
|
90
|
+
owner.projectId !== historicalScope.projectId ||
|
|
91
|
+
state.agentKey !== historicalScope.agentKey ||
|
|
92
|
+
state.pursuitId !== historicalScope.pursuitId
|
|
93
|
+
)
|
|
94
|
+
throw new Error('Resident recall requires one admitted pursuit and its authorized source.')
|
|
95
|
+
const exclusions = options.excludeSuccessfulTools
|
|
96
|
+
? [...new Set(options.excludeSuccessfulTools)].sort()
|
|
97
|
+
: undefined
|
|
98
|
+
if (
|
|
99
|
+
exclusions &&
|
|
100
|
+
(exclusions.length > 16 ||
|
|
101
|
+
exclusions.some((name) => typeof name !== 'string' || !name.length || name.length > 256))
|
|
102
|
+
)
|
|
103
|
+
throw new Error('Resident recall exclusions are invalid.')
|
|
104
|
+
if (
|
|
105
|
+
Buffer.byteLength(
|
|
106
|
+
JSON.stringify({
|
|
107
|
+
terms: ['x'],
|
|
108
|
+
...(exclusions?.length ? { excludeSuccessfulTools: exclusions } : {}),
|
|
109
|
+
}),
|
|
110
|
+
) > 512
|
|
111
|
+
)
|
|
112
|
+
throw new Error('Resident recall exclusions leave no bounded search room.')
|
|
113
|
+
const snapshot = JSON.stringify(historicalScope)
|
|
114
|
+
function assertSource() {
|
|
115
|
+
if (JSON.stringify(historicalScopeSchema.parse(source.scope)) !== snapshot)
|
|
116
|
+
throw new Error('Resident recall source changed ownership or admission boundary.')
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Round-robin categories keep a long objective or derived summary from
|
|
120
|
+
// monopolizing all search terms. Within wakes, newer accepted inputs start
|
|
121
|
+
// first; their original committed index is retained in query metadata.
|
|
122
|
+
const wakes = (state.wakeEvidence ?? [])
|
|
123
|
+
.map((wake, index) => ({
|
|
124
|
+
kind: 'accepted_wake' as const,
|
|
125
|
+
index,
|
|
126
|
+
words: residentQueryWords(wake.reason),
|
|
127
|
+
}))
|
|
128
|
+
.reverse()
|
|
129
|
+
const wakeWords: { term: string; source: string; wakeIndex?: number }[] = []
|
|
130
|
+
for (let word = 0; word < 256; word++)
|
|
131
|
+
for (const wake of wakes) {
|
|
132
|
+
const term = wake.words[word]
|
|
133
|
+
if (term) wakeWords.push({ term, source: wake.kind, wakeIndex: wake.index })
|
|
134
|
+
}
|
|
135
|
+
const groups = [
|
|
136
|
+
wakeWords,
|
|
137
|
+
residentQueryWords(state.objective).map((term) => ({ term, source: 'objective' })),
|
|
138
|
+
residentQueryWords(state.summary ?? '').map((term) => ({
|
|
139
|
+
term,
|
|
140
|
+
source: 'derived_summary',
|
|
141
|
+
})),
|
|
142
|
+
]
|
|
143
|
+
const selected: { term: string; source: string; wakeIndex?: number }[] = []
|
|
144
|
+
const seen = new Set<string>()
|
|
145
|
+
const offsets = [0, 0, 0]
|
|
146
|
+
for (let round = 0; round < 16; round++) {
|
|
147
|
+
for (const [i, group] of groups.entries()) {
|
|
148
|
+
while ((offsets[i] ?? 0) < group.length && selected.length < 16) {
|
|
149
|
+
const entry = group[offsets[i] ?? 0]
|
|
150
|
+
offsets[i] = (offsets[i] ?? 0) + 1
|
|
151
|
+
if (!entry || seen.has(evidenceTokenKey(entry.term))) continue
|
|
152
|
+
const terms = [...selected.map((item) => item.term), entry.term]
|
|
153
|
+
if (
|
|
154
|
+
Buffer.byteLength(
|
|
155
|
+
JSON.stringify({
|
|
156
|
+
terms,
|
|
157
|
+
...(exclusions?.length ? { excludeSuccessfulTools: exclusions } : {}),
|
|
158
|
+
}),
|
|
159
|
+
) > 512
|
|
160
|
+
)
|
|
161
|
+
continue
|
|
162
|
+
selected.push(entry)
|
|
163
|
+
seen.add(evidenceTokenKey(entry.term))
|
|
164
|
+
break
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
const query = {
|
|
169
|
+
terms: selected.map(({ term }) => term),
|
|
170
|
+
metadata: {
|
|
171
|
+
kind: 'literal_resident_state',
|
|
172
|
+
terms: selected,
|
|
173
|
+
throughRevision: historicalScope.throughRevision,
|
|
174
|
+
guidance:
|
|
175
|
+
'Words select historical tool records only. Objective/wakes are accepted inputs; derived_summary is a prior claim, not a new observation. Selection may omit relevant words. Fields over 4000 characters contribute their first/last 2000 characters; terms alternate ends. Query/ranking do not resolve ambiguous references or establish truth, freshness or completeness. Use read_resident_tool with revision/address/byteOffset for exact retained text.',
|
|
176
|
+
},
|
|
177
|
+
}
|
|
178
|
+
const addresses = new WeakMap<ScopedEvidenceRecallCandidate, Readonly<Record<string, unknown>>>()
|
|
179
|
+
const search = source.search.bind(source)
|
|
180
|
+
const retrieve = async (request: EvidenceRecallRequest): Promise<ScopedEvidenceRecallBatch> => {
|
|
181
|
+
if (request.runId !== owner.runId)
|
|
182
|
+
throw new Error('Resident recall called from a different run.')
|
|
183
|
+
assertSource()
|
|
184
|
+
const candidates: ScopedEvidenceRecallCandidate[] = []
|
|
185
|
+
let scannedBytes = 0
|
|
186
|
+
let incomplete = false
|
|
187
|
+
const scans: {
|
|
188
|
+
terms: readonly string[]
|
|
189
|
+
started: boolean
|
|
190
|
+
cursor?: string
|
|
191
|
+
refineTerms?: readonly string[]
|
|
192
|
+
}[] = [{ terms: request.terms, started: false }]
|
|
193
|
+
let excludedToolResults = 0
|
|
194
|
+
for (let pageNumber = 0; pageNumber < 4; pageNumber++) {
|
|
195
|
+
const scan = [...scans].reverse().find((entry) => !entry.started || entry.cursor)
|
|
196
|
+
if (!scan) break
|
|
197
|
+
request.signal.throwIfAborted()
|
|
198
|
+
const allowance = request.maxReadBytes - scannedBytes
|
|
199
|
+
if (allowance <= 1024 * 1024 || candidates.length >= request.maxCandidates) break
|
|
200
|
+
const page = await search(
|
|
201
|
+
{
|
|
202
|
+
...(scan.cursor
|
|
203
|
+
? {
|
|
204
|
+
cursor: scan.cursor,
|
|
205
|
+
...(scan.refineTerms ? { refineTerms: scan.refineTerms } : {}),
|
|
206
|
+
}
|
|
207
|
+
: {
|
|
208
|
+
terms: [...scan.terms],
|
|
209
|
+
...(exclusions?.length ? { excludeSuccessfulTools: exclusions } : {}),
|
|
210
|
+
}),
|
|
211
|
+
maxReadBytes: allowance,
|
|
212
|
+
},
|
|
213
|
+
request.signal,
|
|
214
|
+
)
|
|
215
|
+
request.signal.throwIfAborted()
|
|
216
|
+
assertSource()
|
|
217
|
+
if (
|
|
218
|
+
JSON.stringify(historicalScopeSchema.parse(page.scope)) !== snapshot ||
|
|
219
|
+
!Number.isSafeInteger(page.chargedBytes) ||
|
|
220
|
+
(page.chargedBytes ?? -1) < 0 ||
|
|
221
|
+
(page.chargedBytes ?? Number.POSITIVE_INFINITY) > allowance ||
|
|
222
|
+
typeof page.incomplete !== 'boolean' ||
|
|
223
|
+
!Array.isArray(page.unavailableRevisions) ||
|
|
224
|
+
page.unavailableRevisions.some(
|
|
225
|
+
(revision) =>
|
|
226
|
+
!Number.isSafeInteger(revision) ||
|
|
227
|
+
revision < 1 ||
|
|
228
|
+
revision > historicalScope.throughRevision,
|
|
229
|
+
) ||
|
|
230
|
+
(page.nextCursor !== null &&
|
|
231
|
+
(typeof page.nextCursor !== 'string' ||
|
|
232
|
+
!page.nextCursor.length ||
|
|
233
|
+
page.nextCursor.length > 8192))
|
|
234
|
+
)
|
|
235
|
+
throw new Error('Resident recall received an invalid bounded page.')
|
|
236
|
+
scannedBytes += page.chargedBytes ?? 0
|
|
237
|
+
// A page with a continuation is locally incomplete even when all
|
|
238
|
+
// records visited so far are valid. Clearing traversal later is safe;
|
|
239
|
+
// unavailable evidence stays incomplete for this entire pass.
|
|
240
|
+
incomplete ||=
|
|
241
|
+
(page.incomplete && !page.nextCursor) ||
|
|
242
|
+
page.unavailableRevisions.length > 0 ||
|
|
243
|
+
!!page.evidence?.incomplete
|
|
244
|
+
const evidence = page.evidence
|
|
245
|
+
if (evidence) {
|
|
246
|
+
const original = ownerSchema.parse(evidence.scope)
|
|
247
|
+
if (
|
|
248
|
+
original.tenantId !== owner.tenantId ||
|
|
249
|
+
original.projectId !== owner.projectId ||
|
|
250
|
+
original.runId === owner.runId ||
|
|
251
|
+
!Number.isSafeInteger(page.revision) ||
|
|
252
|
+
(page.revision ?? 0) < 1 ||
|
|
253
|
+
(page.revision ?? Number.POSITIVE_INFINITY) > historicalScope.throughRevision ||
|
|
254
|
+
!z.string().uuid().safeParse(page.claimId).success ||
|
|
255
|
+
page.claimId === state.claimId ||
|
|
256
|
+
!Array.isArray(evidence.matches) ||
|
|
257
|
+
evidence.matches.length > 24
|
|
258
|
+
)
|
|
259
|
+
throw new Error('Resident recall returned an unauthorized invocation.')
|
|
260
|
+
if (
|
|
261
|
+
evidence.excludedToolResults !== undefined &&
|
|
262
|
+
(!Number.isSafeInteger(evidence.excludedToolResults) || evidence.excludedToolResults < 0)
|
|
263
|
+
)
|
|
264
|
+
throw new Error('Resident recall returned an invalid exclusion count.')
|
|
265
|
+
excludedToolResults += evidence.excludedToolResults ?? 0
|
|
266
|
+
for (const match of evidence.matches) {
|
|
267
|
+
if (
|
|
268
|
+
typeof match.address !== 'string' ||
|
|
269
|
+
!match.address.length ||
|
|
270
|
+
match.address.length > 8192
|
|
271
|
+
)
|
|
272
|
+
throw new Error('Resident recall returned an invalid archive address.')
|
|
273
|
+
const candidate: ScopedEvidenceRecallCandidate = {
|
|
274
|
+
scope: original,
|
|
275
|
+
seq: match.seq,
|
|
276
|
+
recordedAt: match.recordedAt,
|
|
277
|
+
source: 'tool_completed',
|
|
278
|
+
toolName: match.toolName,
|
|
279
|
+
isError: match.isError,
|
|
280
|
+
retained: match.retained,
|
|
281
|
+
excerpt: match.excerpt,
|
|
282
|
+
excerptComplete: match.excerptComplete,
|
|
283
|
+
byteOffset: match.byteOffset,
|
|
284
|
+
}
|
|
285
|
+
addresses.set(candidate, {
|
|
286
|
+
sessionId: original.sessionId,
|
|
287
|
+
runId: original.runId,
|
|
288
|
+
seq: match.seq,
|
|
289
|
+
pursuitId: historicalScope.pursuitId,
|
|
290
|
+
revision: page.revision,
|
|
291
|
+
claimId: page.claimId,
|
|
292
|
+
address: match.address,
|
|
293
|
+
byteOffset: match.byteOffset,
|
|
294
|
+
})
|
|
295
|
+
candidates.push(candidate)
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
scan.started = true
|
|
299
|
+
scan.cursor = page.nextCursor ?? undefined
|
|
300
|
+
scan.refineTerms = undefined
|
|
301
|
+
// One strict-subset scan spends the SAME page/byte allowance. Keep
|
|
302
|
+
// the broad cursor: finishing a subset never exhausts the full query.
|
|
303
|
+
if (
|
|
304
|
+
scans.length === 1 &&
|
|
305
|
+
scan.cursor &&
|
|
306
|
+
pageNumber < 3 &&
|
|
307
|
+
(evidence?.matches.length ?? 0) >= 4
|
|
308
|
+
) {
|
|
309
|
+
const focused = refineEvidenceRecallTerms(
|
|
310
|
+
scan.terms,
|
|
311
|
+
candidates.map((candidate) => candidate.excerpt),
|
|
312
|
+
)
|
|
313
|
+
if (focused)
|
|
314
|
+
scans.push({
|
|
315
|
+
terms: focused,
|
|
316
|
+
started: false,
|
|
317
|
+
...(source.supportsTermRefinement === true
|
|
318
|
+
? { cursor: scan.cursor, refineTerms: focused }
|
|
319
|
+
: {}),
|
|
320
|
+
})
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
const continuations = scans.flatMap((scan) =>
|
|
324
|
+
scan.started && scan.cursor
|
|
325
|
+
? [{ toolName: 'search_resident_tools', input: { cursor: scan.cursor } }]
|
|
326
|
+
: [],
|
|
327
|
+
)
|
|
328
|
+
return {
|
|
329
|
+
candidates,
|
|
330
|
+
scannedBytes,
|
|
331
|
+
incomplete: incomplete || scans.some((scan) => !scan.started || !!scan.cursor),
|
|
332
|
+
excludedToolResults,
|
|
333
|
+
continuations,
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
const step = createScopedEvidenceRecallStep(
|
|
337
|
+
{
|
|
338
|
+
retrieve,
|
|
339
|
+
maxChars: options.maxChars,
|
|
340
|
+
maxPassages: options.maxPassages,
|
|
341
|
+
timeoutMs: options.timeoutMs,
|
|
342
|
+
},
|
|
343
|
+
{
|
|
344
|
+
kind: 'resident',
|
|
345
|
+
selectQuery: () => query,
|
|
346
|
+
validate(candidate) {
|
|
347
|
+
assertSource()
|
|
348
|
+
if (!addresses.has(candidate)) throw new Error('Unowned resident evidence candidate.')
|
|
349
|
+
},
|
|
350
|
+
address(candidate) {
|
|
351
|
+
const address = addresses.get(candidate)
|
|
352
|
+
if (!address) throw new Error('Missing resident evidence address.')
|
|
353
|
+
return address
|
|
354
|
+
},
|
|
355
|
+
},
|
|
356
|
+
)
|
|
357
|
+
return async (context) => {
|
|
358
|
+
if (context.runId !== owner.runId)
|
|
359
|
+
throw new Error('Resident recall called from a different run.')
|
|
360
|
+
assertSource()
|
|
361
|
+
return step(context)
|
|
362
|
+
}
|
|
363
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { constants } from 'node:fs'
|
|
2
|
+
import { lstat, open } from 'node:fs/promises'
|
|
3
|
+
import { join, relative, resolve, sep } from 'node:path'
|
|
4
|
+
|
|
5
|
+
const RECORD_BYTES = 4 * 1024 * 1024
|
|
6
|
+
|
|
7
|
+
export interface ResidentHistoryReadBudget {
|
|
8
|
+
remaining: number
|
|
9
|
+
bytesRead: number
|
|
10
|
+
signal?: AbortSignal
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export class ResidentHistoryPageLimit extends Error {}
|
|
14
|
+
|
|
15
|
+
/** Bounded read of an immutable record in a private host-owned hierarchy. */
|
|
16
|
+
export async function readResidentHistoryRecord(
|
|
17
|
+
root: string,
|
|
18
|
+
path: string,
|
|
19
|
+
budget: ResidentHistoryReadBudget,
|
|
20
|
+
): Promise<unknown> {
|
|
21
|
+
budget.signal?.throwIfAborted()
|
|
22
|
+
const base = resolve(root)
|
|
23
|
+
const suffix = relative(base, resolve(path))
|
|
24
|
+
if (suffix === '..' || suffix.startsWith(`..${sep}`)) throw new Error('Invalid history path.')
|
|
25
|
+
let current = base
|
|
26
|
+
for (const part of ['', ...suffix.split(sep).filter(Boolean)]) {
|
|
27
|
+
current = join(current, part)
|
|
28
|
+
if ((await lstat(current)).isSymbolicLink()) throw new Error('History symlinks are refused.')
|
|
29
|
+
}
|
|
30
|
+
const handle = await open(path, constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK)
|
|
31
|
+
try {
|
|
32
|
+
const before = await handle.stat()
|
|
33
|
+
if (!before.isFile() || before.size > RECORD_BYTES)
|
|
34
|
+
throw new Error('History record is not a bounded regular file.')
|
|
35
|
+
if (before.size > budget.remaining) throw new ResidentHistoryPageLimit()
|
|
36
|
+
const bytes = Buffer.alloc(before.size)
|
|
37
|
+
let offset = 0
|
|
38
|
+
while (offset < bytes.length) {
|
|
39
|
+
budget.signal?.throwIfAborted()
|
|
40
|
+
const { bytesRead } = await handle.read(
|
|
41
|
+
bytes,
|
|
42
|
+
offset,
|
|
43
|
+
Math.min(64 * 1024, bytes.length - offset),
|
|
44
|
+
offset,
|
|
45
|
+
)
|
|
46
|
+
budget.remaining -= bytesRead
|
|
47
|
+
budget.bytesRead += bytesRead
|
|
48
|
+
if (!bytesRead) throw new Error('History record shortened during read.')
|
|
49
|
+
offset += bytesRead
|
|
50
|
+
}
|
|
51
|
+
budget.signal?.throwIfAborted()
|
|
52
|
+
const after = await handle.stat()
|
|
53
|
+
if (
|
|
54
|
+
after.size !== before.size ||
|
|
55
|
+
after.mtimeMs !== before.mtimeMs ||
|
|
56
|
+
after.ctimeMs !== before.ctimeMs
|
|
57
|
+
)
|
|
58
|
+
throw new Error('History record changed during read.')
|
|
59
|
+
return JSON.parse(new TextDecoder('utf-8', { fatal: true }).decode(bytes))
|
|
60
|
+
} finally {
|
|
61
|
+
await handle.close()
|
|
62
|
+
}
|
|
63
|
+
}
|