@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
package/src/run/index.ts
CHANGED
|
@@ -29,3 +29,14 @@ export { RUN_MEMORY_TAG, createMemoryPromoter } from './memory-promoter.js'
|
|
|
29
29
|
export type { MemoryPromoterOptions } from './memory-promoter.js'
|
|
30
30
|
export { createMemoryRecallStep } from './memory-recall.js'
|
|
31
31
|
export type { MemoryRecallOptions } from './memory-recall.js'
|
|
32
|
+
export { createJsonClaimVerifier } from './json-claim-verifier.js'
|
|
33
|
+
export type {
|
|
34
|
+
JsonClaimValue,
|
|
35
|
+
JsonClaimRequirement,
|
|
36
|
+
JsonClaimReadRequest,
|
|
37
|
+
JsonClaimObservation,
|
|
38
|
+
JsonClaimReceipt,
|
|
39
|
+
JsonClaimVerdict,
|
|
40
|
+
JsonClaimVerifierOptions,
|
|
41
|
+
JsonClaimVerifier,
|
|
42
|
+
} from './json-claim-verifier.js'
|
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
import { createHash, randomUUID } from 'node:crypto'
|
|
2
|
+
import { performance } from 'node:perf_hooks'
|
|
3
|
+
import type { RunId } from '../types/ids/index.js'
|
|
4
|
+
import type { AnswerReviewContext } from '../types/run/answer-review.js'
|
|
5
|
+
|
|
6
|
+
/** Numbers are restricted to safe integers; use strings for exact decimal values. */
|
|
7
|
+
export type JsonClaimValue = string | number | boolean | null
|
|
8
|
+
|
|
9
|
+
export interface JsonClaimRequirement {
|
|
10
|
+
readonly id: string
|
|
11
|
+
/** Host-selected source identifier, never an address supplied by the candidate. */
|
|
12
|
+
readonly source: string
|
|
13
|
+
/** RFC 6901 pointer to a scalar in the complete JSON document. */
|
|
14
|
+
readonly pointer: string
|
|
15
|
+
/** Optional postcondition in addition to candidate/source equality. */
|
|
16
|
+
readonly expected?: JsonClaimValue
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface JsonClaimReadRequest {
|
|
20
|
+
readonly scope: string
|
|
21
|
+
readonly runId: RunId
|
|
22
|
+
readonly iteration: number
|
|
23
|
+
readonly requestId: string
|
|
24
|
+
readonly startedAt: number
|
|
25
|
+
/** Remaining total allowance. The host must bound capture, not only the returned buffer. */
|
|
26
|
+
readonly maxBytes: number
|
|
27
|
+
readonly signal: AbortSignal
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface JsonClaimObservation {
|
|
31
|
+
readonly scope: string
|
|
32
|
+
readonly runId: RunId
|
|
33
|
+
readonly iteration: number
|
|
34
|
+
readonly requestId: string
|
|
35
|
+
readonly source: string
|
|
36
|
+
readonly observedAt: number
|
|
37
|
+
readonly complete: boolean
|
|
38
|
+
readonly kind: 'current' | 'historical'
|
|
39
|
+
readonly bytes: Uint8Array
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface JsonClaimReceipt {
|
|
43
|
+
readonly scope: string
|
|
44
|
+
readonly runId: RunId
|
|
45
|
+
readonly iteration: number
|
|
46
|
+
readonly claims: Readonly<Record<string, JsonClaimValue>>
|
|
47
|
+
readonly observations: readonly {
|
|
48
|
+
readonly source: string
|
|
49
|
+
readonly requestId: string
|
|
50
|
+
readonly observedAt: number
|
|
51
|
+
readonly bytes: number
|
|
52
|
+
readonly sha256: string
|
|
53
|
+
}[]
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export type JsonClaimVerdict =
|
|
57
|
+
| { readonly accept: true; readonly receipt: JsonClaimReceipt }
|
|
58
|
+
| { readonly accept: false; readonly feedback: string }
|
|
59
|
+
|
|
60
|
+
export interface JsonClaimVerifierOptions {
|
|
61
|
+
/** Host-owned authorization scope, including the admitted revision/claim where applicable. */
|
|
62
|
+
readonly scope: string
|
|
63
|
+
readonly runId: RunId
|
|
64
|
+
readonly requirements: readonly JsonClaimRequirement[]
|
|
65
|
+
/**
|
|
66
|
+
* Trusted, read-only adapter. Enforce access, capture bounds and cancellation;
|
|
67
|
+
* observe during this call. A matching envelope is not authentication against
|
|
68
|
+
* a dishonest adapter. Do not replay an action or relabel an archive as current.
|
|
69
|
+
*/
|
|
70
|
+
readonly observe: (source: string, request: JsonClaimReadRequest) => Promise<JsonClaimObservation>
|
|
71
|
+
/** Total captured source bytes per verification; default 1 MiB, at most 8 MiB. */
|
|
72
|
+
readonly maxBytes?: number
|
|
73
|
+
/** Whole verification deadline; default 2 seconds, at most 30 seconds. */
|
|
74
|
+
readonly timeoutMs?: number
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export interface JsonClaimVerifier {
|
|
78
|
+
/** False while an observer is outstanding, including after timeout/cancellation. */
|
|
79
|
+
isDrained(): boolean
|
|
80
|
+
/** No success cache. Every call observes the configured sources again. */
|
|
81
|
+
verify(
|
|
82
|
+
claims: unknown,
|
|
83
|
+
context: Pick<AnswerReviewContext, 'runId' | 'iteration' | 'signal'>,
|
|
84
|
+
): Promise<JsonClaimVerdict>
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function scalar(value: unknown): value is JsonClaimValue {
|
|
88
|
+
return (
|
|
89
|
+
value === null ||
|
|
90
|
+
typeof value === 'boolean' ||
|
|
91
|
+
(typeof value === 'string' && value.length <= 2_000) ||
|
|
92
|
+
(typeof value === 'number' && Number.isSafeInteger(value))
|
|
93
|
+
)
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function reject(reason: string): JsonClaimVerdict {
|
|
97
|
+
return {
|
|
98
|
+
accept: false,
|
|
99
|
+
feedback: `Claim verification failed: ${reason} Do not claim verified completion. Correct the claims using a permitted observation, or report that completion is unavailable.`,
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function pointerParts(pointer: string): string[] {
|
|
104
|
+
if (pointer === '') return []
|
|
105
|
+
if (!pointer.startsWith('/') || pointer.length > 512 || /~(?:[^01]|$)/u.test(pointer))
|
|
106
|
+
throw new Error('Invalid JSON claim pointer.')
|
|
107
|
+
return pointer
|
|
108
|
+
.slice(1)
|
|
109
|
+
.split('/')
|
|
110
|
+
.map((part) => part.replaceAll('~1', '/').replaceAll('~0', '~'))
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function select(document: unknown, parts: readonly string[]): unknown {
|
|
114
|
+
let value = document
|
|
115
|
+
for (const part of parts) {
|
|
116
|
+
if (value === null || typeof value !== 'object' || !Object.hasOwn(value, part)) return undefined
|
|
117
|
+
if (Array.isArray(value) && !/^(0|[1-9]\d*)$/u.test(part)) return undefined
|
|
118
|
+
value = (value as Record<string, unknown>)[part]
|
|
119
|
+
}
|
|
120
|
+
return value
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Compare explicit candidate fields with fresh, host-authorized JSON observations.
|
|
125
|
+
* This does not judge prose or prove the broader task complete. A receipt describes
|
|
126
|
+
* observation time, not an atomic snapshot or continuing truth after the read.
|
|
127
|
+
*/
|
|
128
|
+
export function createJsonClaimVerifier(options: JsonClaimVerifierOptions): JsonClaimVerifier {
|
|
129
|
+
const { scope, runId, observe } = options
|
|
130
|
+
const maxBytes = options.maxBytes ?? 1_048_576
|
|
131
|
+
const timeoutMs = options.timeoutMs ?? 2_000
|
|
132
|
+
if (
|
|
133
|
+
typeof scope !== 'string' ||
|
|
134
|
+
!scope ||
|
|
135
|
+
scope.length > 2_000 ||
|
|
136
|
+
typeof runId !== 'string' ||
|
|
137
|
+
!runId ||
|
|
138
|
+
typeof observe !== 'function'
|
|
139
|
+
)
|
|
140
|
+
throw new Error('JSON claim verification requires a scope, run ID and observer.')
|
|
141
|
+
if (
|
|
142
|
+
!Number.isSafeInteger(maxBytes) ||
|
|
143
|
+
maxBytes < 1 ||
|
|
144
|
+
maxBytes > 8_388_608 ||
|
|
145
|
+
!Number.isSafeInteger(timeoutMs) ||
|
|
146
|
+
timeoutMs < 1 ||
|
|
147
|
+
timeoutMs > 30_000
|
|
148
|
+
)
|
|
149
|
+
throw new Error('Invalid JSON claim verification bounds.')
|
|
150
|
+
if (!options.requirements.length || options.requirements.length > 32)
|
|
151
|
+
throw new Error('JSON claim verification requires 1–32 requirements.')
|
|
152
|
+
const ids = new Set<string>()
|
|
153
|
+
const requirements = options.requirements.map((item) => {
|
|
154
|
+
if (
|
|
155
|
+
!/^[a-zA-Z][a-zA-Z0-9_-]{0,99}$/u.test(item.id) ||
|
|
156
|
+
ids.has(item.id) ||
|
|
157
|
+
typeof item.source !== 'string' ||
|
|
158
|
+
!item.source ||
|
|
159
|
+
item.source.length > 512 ||
|
|
160
|
+
typeof item.pointer !== 'string' ||
|
|
161
|
+
(Object.hasOwn(item, 'expected') && !scalar(item.expected))
|
|
162
|
+
)
|
|
163
|
+
throw new Error('Invalid or duplicate JSON claim requirement.')
|
|
164
|
+
ids.add(item.id)
|
|
165
|
+
return { ...item, parts: pointerParts(item.pointer) }
|
|
166
|
+
})
|
|
167
|
+
let active = false
|
|
168
|
+
let pending = 0
|
|
169
|
+
return {
|
|
170
|
+
isDrained: () => !active && pending === 0,
|
|
171
|
+
async verify(claims, context) {
|
|
172
|
+
context.signal?.throwIfAborted()
|
|
173
|
+
if (
|
|
174
|
+
context.runId !== runId ||
|
|
175
|
+
!Number.isSafeInteger(context.iteration) ||
|
|
176
|
+
context.iteration < 0
|
|
177
|
+
)
|
|
178
|
+
return reject('The review belongs to a different run or invalid iteration.')
|
|
179
|
+
if (active || pending) return reject('A previous observation has not drained.')
|
|
180
|
+
if (
|
|
181
|
+
!claims ||
|
|
182
|
+
typeof claims !== 'object' ||
|
|
183
|
+
Array.isArray(claims) ||
|
|
184
|
+
Object.keys(claims).length !== requirements.length ||
|
|
185
|
+
Object.keys(claims).some((id) => !ids.has(id))
|
|
186
|
+
)
|
|
187
|
+
return reject('Supply exactly the configured claim IDs and scalar values.')
|
|
188
|
+
const values: Record<string, JsonClaimValue> = Object.create(null)
|
|
189
|
+
for (const item of requirements) {
|
|
190
|
+
if (!Object.hasOwn(claims, item.id)) return reject('A required claim is missing.')
|
|
191
|
+
const value = (claims as Record<string, unknown>)[item.id]
|
|
192
|
+
if (!scalar(value)) return reject(`Claim ${item.id} is not a supported scalar.`)
|
|
193
|
+
values[item.id] = value
|
|
194
|
+
}
|
|
195
|
+
active = true
|
|
196
|
+
const controller = new AbortController()
|
|
197
|
+
const expiresAt = performance.now() + timeoutMs
|
|
198
|
+
const ensureActive = () => {
|
|
199
|
+
// A synchronous adapter can delay timers; late bytes still cannot pass.
|
|
200
|
+
if (performance.now() >= expiresAt) controller.abort(new Error('Verification timed out.'))
|
|
201
|
+
controller.signal.throwIfAborted()
|
|
202
|
+
}
|
|
203
|
+
const onAbort = () => controller.abort(context.signal?.reason)
|
|
204
|
+
context.signal?.addEventListener('abort', onAbort, { once: true })
|
|
205
|
+
const timer = setTimeout(
|
|
206
|
+
() => controller.abort(new Error('Verification timed out.')),
|
|
207
|
+
timeoutMs,
|
|
208
|
+
)
|
|
209
|
+
const observations: JsonClaimReceipt['observations'][number][] = []
|
|
210
|
+
let remaining = maxBytes
|
|
211
|
+
let removeAbort: (() => void) | undefined
|
|
212
|
+
try {
|
|
213
|
+
for (const source of new Set(requirements.map((item) => item.source))) {
|
|
214
|
+
ensureActive()
|
|
215
|
+
if (remaining < 1) return reject('The source byte allowance is exhausted.')
|
|
216
|
+
const request = Object.freeze({
|
|
217
|
+
scope,
|
|
218
|
+
runId,
|
|
219
|
+
iteration: context.iteration,
|
|
220
|
+
requestId: randomUUID(),
|
|
221
|
+
startedAt: Date.now(),
|
|
222
|
+
maxBytes: remaining,
|
|
223
|
+
signal: controller.signal,
|
|
224
|
+
})
|
|
225
|
+
pending++
|
|
226
|
+
const work = Promise.resolve()
|
|
227
|
+
.then(() => {
|
|
228
|
+
ensureActive()
|
|
229
|
+
return observe(source, request)
|
|
230
|
+
})
|
|
231
|
+
.finally(() => {
|
|
232
|
+
pending--
|
|
233
|
+
})
|
|
234
|
+
const aborted = new Promise<never>((_, fail) => {
|
|
235
|
+
const listener = () => fail(controller.signal.reason)
|
|
236
|
+
controller.signal.addEventListener('abort', listener, { once: true })
|
|
237
|
+
removeAbort = () => controller.signal.removeEventListener('abort', listener)
|
|
238
|
+
})
|
|
239
|
+
const observation = await Promise.race([work, aborted])
|
|
240
|
+
removeAbort?.()
|
|
241
|
+
ensureActive()
|
|
242
|
+
if (
|
|
243
|
+
!observation ||
|
|
244
|
+
observation.scope !== scope ||
|
|
245
|
+
observation.runId !== runId ||
|
|
246
|
+
observation.iteration !== context.iteration ||
|
|
247
|
+
observation.requestId !== request.requestId ||
|
|
248
|
+
observation.source !== source ||
|
|
249
|
+
observation.complete !== true ||
|
|
250
|
+
observation.kind !== 'current' ||
|
|
251
|
+
!Number.isSafeInteger(observation.observedAt) ||
|
|
252
|
+
observation.observedAt < request.startedAt ||
|
|
253
|
+
observation.observedAt > Date.now() ||
|
|
254
|
+
!(observation.bytes instanceof Uint8Array)
|
|
255
|
+
)
|
|
256
|
+
return reject('The observation is incomplete, historical or outside this review scope.')
|
|
257
|
+
if (observation.bytes.byteLength > remaining)
|
|
258
|
+
return reject('A source exceeded the byte allowance.')
|
|
259
|
+
const bytes = Buffer.from(observation.bytes)
|
|
260
|
+
remaining -= bytes.byteLength
|
|
261
|
+
const document: unknown = JSON.parse(
|
|
262
|
+
new TextDecoder('utf-8', { fatal: true }).decode(bytes),
|
|
263
|
+
)
|
|
264
|
+
for (const item of requirements.filter((item) => item.source === source)) {
|
|
265
|
+
const actual = select(document, item.parts)
|
|
266
|
+
if (!scalar(actual) || actual !== values[item.id])
|
|
267
|
+
return reject(`Claim ${item.id} does not match the selected source field.`)
|
|
268
|
+
if (Object.hasOwn(item, 'expected') && actual !== item.expected)
|
|
269
|
+
return reject(`Claim ${item.id} does not satisfy the configured postcondition.`)
|
|
270
|
+
}
|
|
271
|
+
observations.push({
|
|
272
|
+
source,
|
|
273
|
+
requestId: request.requestId,
|
|
274
|
+
observedAt: observation.observedAt,
|
|
275
|
+
bytes: bytes.byteLength,
|
|
276
|
+
sha256: createHash('sha256').update(bytes).digest('hex'),
|
|
277
|
+
})
|
|
278
|
+
}
|
|
279
|
+
ensureActive()
|
|
280
|
+
return {
|
|
281
|
+
accept: true,
|
|
282
|
+
receipt: { scope, runId, iteration: context.iteration, claims: values, observations },
|
|
283
|
+
}
|
|
284
|
+
} catch {
|
|
285
|
+
context.signal?.throwIfAborted()
|
|
286
|
+
return reject(
|
|
287
|
+
'A current source could not be fully observed and parsed within the deadline.',
|
|
288
|
+
)
|
|
289
|
+
} finally {
|
|
290
|
+
clearTimeout(timer)
|
|
291
|
+
removeAbort?.()
|
|
292
|
+
context.signal?.removeEventListener('abort', onAbort)
|
|
293
|
+
controller.abort()
|
|
294
|
+
active = false
|
|
295
|
+
}
|
|
296
|
+
},
|
|
297
|
+
}
|
|
298
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { toErrorMessage } from '../utils/error.js'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Internal bridge for SDK preparation failures with a safe availability note
|
|
5
|
+
* and, when available, fully validated fallback evidence within the same budget.
|
|
6
|
+
* The cause remains diagnostic-only. Ordinary thrown errors never become context.
|
|
7
|
+
*/
|
|
8
|
+
export class PreparationContextError extends Error {
|
|
9
|
+
constructor(
|
|
10
|
+
cause: unknown,
|
|
11
|
+
readonly context: string,
|
|
12
|
+
) {
|
|
13
|
+
super(toErrorMessage(cause), { cause })
|
|
14
|
+
this.name = 'PreparationContextError'
|
|
15
|
+
}
|
|
16
|
+
}
|
package/src/run-query/index.ts
CHANGED
|
@@ -62,7 +62,7 @@ export class RunTranscriptUnavailableError extends Error {
|
|
|
62
62
|
/** What one compaction pass removed. */
|
|
63
63
|
export interface ShedPass {
|
|
64
64
|
readonly iteration: number
|
|
65
|
-
readonly reason: '
|
|
65
|
+
readonly reason: Extract<PersistedRunEvent, { type: 'compaction_shed' }>['reason']
|
|
66
66
|
readonly messages: readonly Message[]
|
|
67
67
|
/** Where in the log the pass sits, for a caller correlating with events. */
|
|
68
68
|
readonly seq: number
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { z } from 'zod'
|
|
2
|
+
import { StreamTextAccumulator } from '../../provider/stream-text.js'
|
|
3
|
+
import { type TokenUsage, mergeTokenUsage } from '../../types/common/index.js'
|
|
4
|
+
import { createSystemMessage, createUserMessage } from '../../types/message/index.js'
|
|
5
|
+
import type { PreparationTextRequest, PreparationTextResult } from '../../types/run/prepare-step.js'
|
|
6
|
+
import type { IterationContext } from './iteration/phases/context.js'
|
|
7
|
+
|
|
8
|
+
const requestSchema = z
|
|
9
|
+
.object({
|
|
10
|
+
system: z.string().min(1).max(12_000),
|
|
11
|
+
prompt: z.string().min(1).max(12_000),
|
|
12
|
+
maxTokens: z.number().int().min(1).max(1024).default(256),
|
|
13
|
+
timeoutMs: z.number().int().min(1).max(10_000).default(10_000),
|
|
14
|
+
})
|
|
15
|
+
.strict()
|
|
16
|
+
|
|
17
|
+
/** The provider already owns retry, fallback, cancellation and budget admission. */
|
|
18
|
+
export function createCallbackInference(
|
|
19
|
+
ctx: IterationContext,
|
|
20
|
+
model: string,
|
|
21
|
+
phase: 'preparation' | 'review',
|
|
22
|
+
) {
|
|
23
|
+
const label = phase === 'preparation' ? 'Preparation' : 'Review'
|
|
24
|
+
const owner = phase === 'preparation' ? 'preparation stage' : 'answer reviewer'
|
|
25
|
+
const lifetime = new AbortController()
|
|
26
|
+
let used = false
|
|
27
|
+
return {
|
|
28
|
+
close: () => lifetime.abort(new Error(`The ${owner} has ended.`)),
|
|
29
|
+
async generateText(request: PreparationTextRequest): Promise<PreparationTextResult> {
|
|
30
|
+
lifetime.signal.throwIfAborted()
|
|
31
|
+
ctx.abortController.signal.throwIfAborted()
|
|
32
|
+
request.signal?.throwIfAborted()
|
|
33
|
+
const { signal: requestedSignal, ...fields } = request
|
|
34
|
+
const input = requestSchema.parse(fields)
|
|
35
|
+
if (input.system.length + input.prompt.length > 12_000)
|
|
36
|
+
throw new Error(`${label} inference input exceeds 12,000 characters.`)
|
|
37
|
+
if (used)
|
|
38
|
+
throw new Error(
|
|
39
|
+
`${phase === 'preparation' ? 'A' : 'An'} ${owner} may make only one inference call.`,
|
|
40
|
+
)
|
|
41
|
+
used = true
|
|
42
|
+
const deadline = new AbortController()
|
|
43
|
+
const timer = setTimeout(
|
|
44
|
+
() => deadline.abort(new Error(`${label} inference timed out.`)),
|
|
45
|
+
input.timeoutMs,
|
|
46
|
+
)
|
|
47
|
+
const signal = AbortSignal.any([
|
|
48
|
+
ctx.abortController.signal,
|
|
49
|
+
lifetime.signal,
|
|
50
|
+
deadline.signal,
|
|
51
|
+
...(requestedSignal ? [requestedSignal] : []),
|
|
52
|
+
])
|
|
53
|
+
const requested = ctx.servingMember?.() ?? { index: 0, providerId: ctx.provider.id }
|
|
54
|
+
const route = () => {
|
|
55
|
+
const member = ctx.servingMember?.() ?? requested
|
|
56
|
+
return {
|
|
57
|
+
providerId: member.providerId,
|
|
58
|
+
model: member.model ?? model,
|
|
59
|
+
chainIndex: member.index,
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
const text = new StreamTextAccumulator()
|
|
63
|
+
let invalidOutput: string | undefined
|
|
64
|
+
let usage: TokenUsage | undefined
|
|
65
|
+
try {
|
|
66
|
+
for await (const chunk of ctx.provider.chatStream({
|
|
67
|
+
model,
|
|
68
|
+
providerRoute: route(),
|
|
69
|
+
messages: [createSystemMessage(input.system), createUserMessage(input.prompt)],
|
|
70
|
+
maxTokens: input.maxTokens,
|
|
71
|
+
...(ctx.runConfig.effort ? { effort: ctx.runConfig.effort } : {}),
|
|
72
|
+
signal,
|
|
73
|
+
})) {
|
|
74
|
+
if (chunk.usage) usage = usage ? mergeTokenUsage(usage, chunk.usage) : { ...chunk.usage }
|
|
75
|
+
if (chunk.error) throw new Error(chunk.error)
|
|
76
|
+
signal.throwIfAborted()
|
|
77
|
+
if (chunk.delta.toolCalls?.length) invalidOutput = `${label} inference cannot call tools.`
|
|
78
|
+
if (!invalidOutput) {
|
|
79
|
+
text.push(chunk)
|
|
80
|
+
if (text.characters > 8192)
|
|
81
|
+
invalidOutput = `${label} inference output exceeds 8,192 characters.`
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
signal.throwIfAborted()
|
|
85
|
+
if (!usage) throw new Error(`${label} inference ended without usage.`)
|
|
86
|
+
if (invalidOutput) throw new Error(invalidOutput)
|
|
87
|
+
return { text: text.text, usage, servedBy: route() }
|
|
88
|
+
} finally {
|
|
89
|
+
clearTimeout(timer)
|
|
90
|
+
if (usage) ctx.runMgr.accumulateUsage(usage, route())
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
}
|
|
94
|
+
}
|
|
@@ -214,6 +214,8 @@ export class CheckpointManager {
|
|
|
214
214
|
private workingStateSource?: () => WorkingStateSnapshot | undefined
|
|
215
215
|
private latestUserMessageSource?: () => UserMessage | undefined
|
|
216
216
|
private restoredUserMessage?: UserMessage
|
|
217
|
+
private answerReviewAttemptsSource?: () => number
|
|
218
|
+
private restoredAnswerAttempts = 0
|
|
217
219
|
private structuredReviewAttemptsSource?: () => number
|
|
218
220
|
private restoredReviewAttempts = 0
|
|
219
221
|
private nativeStructuredAttemptsSource?: () => number
|
|
@@ -298,6 +300,13 @@ export class CheckpointManager {
|
|
|
298
300
|
return this.restoredUserMessage
|
|
299
301
|
}
|
|
300
302
|
|
|
303
|
+
setAnswerReviewAttemptsSource(source: () => number): void {
|
|
304
|
+
this.answerReviewAttemptsSource = source
|
|
305
|
+
}
|
|
306
|
+
get restoredAnswerReviewAttempts(): number {
|
|
307
|
+
return this.restoredAnswerAttempts
|
|
308
|
+
}
|
|
309
|
+
|
|
301
310
|
setNativeStructuredAttemptsSource(source: () => number): void {
|
|
302
311
|
this.nativeStructuredAttemptsSource = source
|
|
303
312
|
}
|
|
@@ -344,6 +353,7 @@ export class CheckpointManager {
|
|
|
344
353
|
runCreatedAt: this.runCreatedAt,
|
|
345
354
|
iteration,
|
|
346
355
|
messages: [...runMgr.messages],
|
|
356
|
+
answerReviewAttempts: this.answerReviewAttemptsSource?.() ?? this.restoredAnswerAttempts,
|
|
347
357
|
nativeStructuredAttempts:
|
|
348
358
|
this.nativeStructuredAttemptsSource?.() ?? this.restoredNativeAttempts,
|
|
349
359
|
structuredReviewAttempts:
|
|
@@ -539,6 +549,10 @@ export class CheckpointManager {
|
|
|
539
549
|
// its origin's age. A guard that no input can trip would have read as
|
|
540
550
|
// protection and been none.
|
|
541
551
|
this.runCreatedAt ??= checkpoint.runCreatedAt
|
|
552
|
+
const answerAttempts = checkpoint.answerReviewAttempts ?? 0
|
|
553
|
+
if (!Number.isSafeInteger(answerAttempts) || answerAttempts < 0)
|
|
554
|
+
throw new Error('Checkpoint answerReviewAttempts must be a nonnegative safe integer')
|
|
555
|
+
this.restoredAnswerAttempts = answerAttempts
|
|
542
556
|
const nativeAttempts = checkpoint.nativeStructuredAttempts ?? 0
|
|
543
557
|
if (!Number.isSafeInteger(nativeAttempts) || nativeAttempts < 0)
|
|
544
558
|
throw new Error('Invalid nativeStructuredAttempts in checkpoint')
|
|
@@ -11,6 +11,7 @@ import { type PersistedRunEvent, isEphemeralEvent } from '../../types/run/events
|
|
|
11
11
|
import type { RunEvent } from '../../types/run/index.js'
|
|
12
12
|
import type { ReadRunEventsOptions } from '../../types/run/store.js'
|
|
13
13
|
import type { TaskEvent, TaskStore } from '../../types/task/index.js'
|
|
14
|
+
import { awaitWithAbort } from '../../utils/await-with-abort.js'
|
|
14
15
|
import { SCOPE_ATTRIBUTE } from '../../utils/log/types.js'
|
|
15
16
|
import { type Logger, resolveLogger } from '../../utils/logger.js'
|
|
16
17
|
|
|
@@ -78,6 +79,27 @@ export class EventTranslator {
|
|
|
78
79
|
return this.withTranscriptLock(() => this.runMgr.getRunStore().readEvents(options))
|
|
79
80
|
}
|
|
80
81
|
|
|
82
|
+
captureRunEvidence(
|
|
83
|
+
maxReadBytes?: number,
|
|
84
|
+
signal?: AbortSignal,
|
|
85
|
+
): Promise<import('../../store/evidence/types.js').RunTextEvidenceSource | undefined> {
|
|
86
|
+
const capture = this.withTranscriptLock(async () => {
|
|
87
|
+
signal?.throwIfAborted()
|
|
88
|
+
const run = this.runMgr.getRun()
|
|
89
|
+
if (run.status !== 'running')
|
|
90
|
+
throw new Error('Evidence capture requires the active invocation.')
|
|
91
|
+
const { tenantId, projectId, sessionId, runId } = this.runMgr.getRunScope()
|
|
92
|
+
const source = await this.runMgr
|
|
93
|
+
.getRunStore()
|
|
94
|
+
.captureTextEvidence?.({ tenantId, projectId, sessionId, runId }, maxReadBytes, signal)
|
|
95
|
+
signal?.throwIfAborted()
|
|
96
|
+
if (this.runMgr.getRun().status !== 'running')
|
|
97
|
+
throw new Error('Evidence capture requires the active invocation.')
|
|
98
|
+
return source
|
|
99
|
+
})
|
|
100
|
+
return awaitWithAbort(capture, signal)
|
|
101
|
+
}
|
|
102
|
+
|
|
81
103
|
setGeneration(fence: FencingToken | undefined): void {
|
|
82
104
|
this.generation = fence
|
|
83
105
|
}
|
|
@@ -43,12 +43,14 @@ import type {
|
|
|
43
43
|
ToolCallRepairReason,
|
|
44
44
|
} from '../../types/tool/repair.js'
|
|
45
45
|
import { abortReasonText } from '../../utils/abort.js'
|
|
46
|
+
import { awaitWithAbort } from '../../utils/await-with-abort.js'
|
|
46
47
|
import { type BackoffPolicy, backoffWithJitter, sleep } from '../../utils/backoff.js'
|
|
47
48
|
import { toErrorMessage } from '../../utils/error.js'
|
|
48
49
|
import { generateToolCallId } from '../../utils/id.js'
|
|
49
50
|
import type { Logger } from '../../utils/logger.js'
|
|
50
51
|
import { compressShellOutput } from '../../utils/shell-compress.js'
|
|
51
52
|
import { type BackgroundJobRegistry, type JobProcess, bindOwner } from '../jobs/registry.js'
|
|
53
|
+
import { describeVisibleFileEvidence } from './file-evidence-context.js'
|
|
52
54
|
import type { ToolResultObservation } from './project-instructions.js'
|
|
53
55
|
import { ToolCallBudget, assertMaxToolCalls } from './tool-call-budget.js'
|
|
54
56
|
import {
|
|
@@ -376,6 +378,8 @@ export interface ToolExecutorConfig {
|
|
|
376
378
|
* {@link DEFAULT_MAX_TOOL_OUTPUT_CHARS}; set `0` to disable.
|
|
377
379
|
*/
|
|
378
380
|
maxToolOutputChars?: number
|
|
381
|
+
/** See QueryParams.retainedToolPreviewChars; applies to the recorded host output. */
|
|
382
|
+
retainedToolPreviewChars?: number
|
|
379
383
|
|
|
380
384
|
/**
|
|
381
385
|
* Cap on the RICH channel of a single tool result, in base64
|
|
@@ -401,7 +405,8 @@ export interface ToolExecutorConfig {
|
|
|
401
405
|
* with `read`/`grep`. Absent ⇒ over-budget output is middle-elided and
|
|
402
406
|
* the overflow is lost.
|
|
403
407
|
*/
|
|
404
|
-
|
|
408
|
+
captureRunEvidence?: ToolContext['captureRunEvidence']
|
|
409
|
+
toolOutputDir?: string | (() => string | undefined)
|
|
405
410
|
/**
|
|
406
411
|
* Last chance to fix a tool call the model got wrong, before the error
|
|
407
412
|
* reaches it. See {@link RepairToolCall}.
|
|
@@ -491,6 +496,12 @@ export function deniedToolOutput(toolName: string, reason: string): string {
|
|
|
491
496
|
}
|
|
492
497
|
|
|
493
498
|
export class ToolExecutor {
|
|
499
|
+
private outputDirectory(): string | undefined {
|
|
500
|
+
return typeof this.config.toolOutputDir === 'function'
|
|
501
|
+
? this.config.toolOutputDir()
|
|
502
|
+
: this.config.toolOutputDir
|
|
503
|
+
}
|
|
504
|
+
|
|
494
505
|
private config: ToolExecutorConfig
|
|
495
506
|
private activityStore: ActivityStore
|
|
496
507
|
private emitEvent: EmitEvent
|
|
@@ -536,6 +547,16 @@ export class ToolExecutor {
|
|
|
536
547
|
this.config = { ...this.config, sandbox }
|
|
537
548
|
}
|
|
538
549
|
|
|
550
|
+
/** Request-only evidence from the same ledger used by mutation admission. No filesystem I/O. */
|
|
551
|
+
describeFileEvidence(messages: readonly Message[]): string | undefined {
|
|
552
|
+
return describeVisibleFileEvidence(
|
|
553
|
+
messages,
|
|
554
|
+
this.fileReadTracker,
|
|
555
|
+
this.config.workingDirectory,
|
|
556
|
+
this.config.sandbox !== undefined,
|
|
557
|
+
)
|
|
558
|
+
}
|
|
559
|
+
|
|
539
560
|
/**
|
|
540
561
|
* Span that this executor's tool spans should hang off — the current
|
|
541
562
|
* iteration. Re-set each turn by the orchestrator, because a tool span
|
|
@@ -1175,7 +1196,8 @@ export class ToolExecutor {
|
|
|
1175
1196
|
toolUseId: nestedId,
|
|
1176
1197
|
output: rawOutput,
|
|
1177
1198
|
maxChars: this.config.maxToolOutputChars ?? DEFAULT_MAX_TOOL_OUTPUT_CHARS,
|
|
1178
|
-
|
|
1199
|
+
retainedPreviewChars: this.config.retainedToolPreviewChars,
|
|
1200
|
+
spillDir: this.outputDirectory(),
|
|
1179
1201
|
onError: (message) =>
|
|
1180
1202
|
this.log.warn('Failed to spill oversized nested tool output', {
|
|
1181
1203
|
[NAMZU.RUN_ID]: this.config.runId,
|
|
@@ -1206,6 +1228,7 @@ export class ToolExecutor {
|
|
|
1206
1228
|
outputLength: budgeted.originalLength,
|
|
1207
1229
|
...(budgeted.truncated ? { outputTruncated: true } : {}),
|
|
1208
1230
|
...(budgeted.spillPath ? { outputSpillPath: budgeted.spillPath } : {}),
|
|
1231
|
+
...(budgeted.spillIntegrity ? { outputSpillIntegrity: budgeted.spillIntegrity } : {}),
|
|
1209
1232
|
...(via ? { via } : {}),
|
|
1210
1233
|
})
|
|
1211
1234
|
recordObservation({
|
|
@@ -1253,6 +1276,7 @@ export class ToolExecutor {
|
|
|
1253
1276
|
workingDirectory: this.config.workingDirectory,
|
|
1254
1277
|
},
|
|
1255
1278
|
invocationState: this.config.invocationState,
|
|
1279
|
+
captureRunEvidence: this.config.captureRunEvidence,
|
|
1256
1280
|
toolRegistry: this.config.tools,
|
|
1257
1281
|
// The step's list wins where it has one; the run's is the default.
|
|
1258
1282
|
// Same precedence the request already uses when it decides which
|
|
@@ -1628,8 +1652,8 @@ export class ToolExecutor {
|
|
|
1628
1652
|
: formatFailedToolOutput(result.output, result.error)
|
|
1629
1653
|
|
|
1630
1654
|
const postOverride = post.override
|
|
1631
|
-
let output =
|
|
1632
|
-
|
|
1655
|
+
let output = postOverride?.output ?? rawOutput
|
|
1656
|
+
const preview = !postOverride && result.success ? this.maybeCompress(toolName, output) : output
|
|
1633
1657
|
let selectedContent = postOverride?.isError
|
|
1634
1658
|
? undefined
|
|
1635
1659
|
: (postOverride?.content ?? result.content)
|
|
@@ -1655,16 +1679,22 @@ export class ToolExecutor {
|
|
|
1655
1679
|
toolName,
|
|
1656
1680
|
toolUseId: toolCall.id,
|
|
1657
1681
|
output,
|
|
1682
|
+
preview,
|
|
1658
1683
|
maxChars: maxToolOutputChars,
|
|
1659
|
-
|
|
1684
|
+
retainedPreviewChars: this.config.retainedToolPreviewChars,
|
|
1685
|
+
spillDir: this.outputDirectory(),
|
|
1660
1686
|
onError: (message) =>
|
|
1661
|
-
this.log.warn('Failed to
|
|
1687
|
+
this.log.warn('Failed to retain original tool output', {
|
|
1662
1688
|
[NAMZU.RUN_ID]: this.config.runId,
|
|
1663
1689
|
[GENAI.TOOL_NAME]: toolName,
|
|
1664
1690
|
'exception.message': message,
|
|
1665
1691
|
}),
|
|
1666
1692
|
})
|
|
1667
|
-
if (
|
|
1693
|
+
if (
|
|
1694
|
+
budgeted.truncated &&
|
|
1695
|
+
maxToolOutputChars > 0 &&
|
|
1696
|
+
budgeted.originalLength > maxToolOutputChars
|
|
1697
|
+
) {
|
|
1668
1698
|
this.log.warn('Tool output exceeded the model-visible budget', {
|
|
1669
1699
|
[NAMZU.RUN_ID]: this.config.runId,
|
|
1670
1700
|
[GENAI.TOOL_NAME]: toolName,
|
|
@@ -1736,6 +1766,7 @@ export class ToolExecutor {
|
|
|
1736
1766
|
outputLength: budgeted.originalLength,
|
|
1737
1767
|
...(budgeted.truncated ? { outputTruncated: true } : {}),
|
|
1738
1768
|
...(budgeted.spillPath ? { outputSpillPath: budgeted.spillPath } : {}),
|
|
1769
|
+
...(budgeted.spillIntegrity ? { outputSpillIntegrity: budgeted.spillIntegrity } : {}),
|
|
1739
1770
|
})
|
|
1740
1771
|
recordObservation({
|
|
1741
1772
|
runId: this.config.runId,
|
|
@@ -1864,9 +1895,20 @@ export class ToolExecutor {
|
|
|
1864
1895
|
}
|
|
1865
1896
|
}
|
|
1866
1897
|
|
|
1898
|
+
const inheritedCapture = toolContext.captureRunEvidence
|
|
1899
|
+
const scopedCapture: ToolContext['captureRunEvidence'] = inheritedCapture
|
|
1900
|
+
? async (maxReadBytes, signal) => {
|
|
1901
|
+
const combined = signal
|
|
1902
|
+
? AbortSignal.any([controller.signal, signal])
|
|
1903
|
+
: controller.signal
|
|
1904
|
+
combined.throwIfAborted()
|
|
1905
|
+
return awaitWithAbort(inheritedCapture(maxReadBytes, combined), combined)
|
|
1906
|
+
}
|
|
1907
|
+
: undefined
|
|
1867
1908
|
const context = {
|
|
1868
1909
|
...toolContext,
|
|
1869
1910
|
abortSignal: controller.signal,
|
|
1911
|
+
...(scopedCapture ? { captureRunEvidence: scopedCapture } : {}),
|
|
1870
1912
|
...(scopedDispatch ? { dispatchTool: scopedDispatch } : {}),
|
|
1871
1913
|
}
|
|
1872
1914
|
const execution = prepared
|
|
@@ -2686,8 +2728,8 @@ export class ToolExecutor {
|
|
|
2686
2728
|
...(notice ? { notice } : {}),
|
|
2687
2729
|
// A tool may return different host and model text. They must
|
|
2688
2730
|
// never compete for the same exclusive spill filename.
|
|
2689
|
-
spillDir: this.
|
|
2690
|
-
? join(this.
|
|
2731
|
+
spillDir: this.outputDirectory()
|
|
2732
|
+
? join(this.outputDirectory() as string, 'content')
|
|
2691
2733
|
: undefined,
|
|
2692
2734
|
onError: (message) =>
|
|
2693
2735
|
this.log.warn('Failed to spill oversized model tool content', {
|