@namzu/sdk 38.1.0 → 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 +758 -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 +137 -0
- package/dist/manager/resident/agenda.d.ts.map +1 -0
- package/dist/manager/resident/agenda.js +586 -0
- package/dist/manager/resident/agenda.js.map +1 -0
- 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/delivery-window.d.ts +22 -0
- package/dist/manager/resident/delivery-window.d.ts.map +1 -0
- package/dist/manager/resident/delivery-window.js +78 -0
- package/dist/manager/resident/delivery-window.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/host.d.ts +78 -0
- package/dist/manager/resident/host.d.ts.map +1 -0
- package/dist/manager/resident/host.js +252 -0
- package/dist/manager/resident/host.js.map +1 -0
- package/dist/manager/resident/initiative.d.ts +111 -0
- package/dist/manager/resident/initiative.d.ts.map +1 -0
- package/dist/manager/resident/initiative.js +129 -0
- package/dist/manager/resident/initiative.js.map +1 -0
- 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 +726 -0
- package/dist/manager/resident/learning.d.ts.map +1 -0
- package/dist/manager/resident/learning.js +353 -0
- package/dist/manager/resident/learning.js.map +1 -0
- package/dist/manager/resident/loop.d.ts +31 -0
- package/dist/manager/resident/loop.d.ts.map +1 -0
- package/dist/manager/resident/loop.js +69 -0
- package/dist/manager/resident/loop.js.map +1 -0
- package/dist/manager/resident/outbox.d.ts +180 -0
- package/dist/manager/resident/outbox.d.ts.map +1 -0
- package/dist/manager/resident/outbox.js +214 -0
- package/dist/manager/resident/outbox.js.map +1 -0
- package/dist/manager/resident/proposal.d.ts +91 -0
- package/dist/manager/resident/proposal.d.ts.map +1 -0
- package/dist/manager/resident/proposal.js +75 -0
- package/dist/manager/resident/proposal.js.map +1 -0
- package/dist/manager/resident/store.d.ts +182 -0
- package/dist/manager/resident/store.d.ts.map +1 -0
- package/dist/manager/resident/store.js +199 -0
- package/dist/manager/resident/store.js.map +1 -0
- 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/contributions.d.ts +5 -2
- package/dist/prompt/contributions.d.ts.map +1 -1
- package/dist/prompt/contributions.js.map +1 -1
- package/dist/prompt/index.d.ts +4 -0
- package/dist/prompt/index.d.ts.map +1 -1
- package/dist/prompt/index.js +2 -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 +36 -0
- package/dist/prompt/resident-step.d.ts.map +1 -0
- package/dist/prompt/resident-step.js +135 -0
- package/dist/prompt/resident-step.js.map +1 -0
- 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 +22 -3
- package/dist/public-runtime.d.ts.map +1 -1
- package/dist/public-runtime.js +21 -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 +29 -3
- package/dist/public-types.d.ts.map +1 -1
- package/dist/registry/index.d.ts +1 -1
- package/dist/registry/index.d.ts.map +1 -1
- package/dist/registry/tool/execute.d.ts +18 -0
- package/dist/registry/tool/execute.d.ts.map +1 -1
- package/dist/registry/tool/execute.js +43 -6
- package/dist/registry/tool/execute.js.map +1 -1
- package/dist/run/LimitChecker.js +3 -3
- package/dist/run/LimitChecker.js.map +1 -1
- package/dist/run/evidence-query.d.ts +41 -0
- package/dist/run/evidence-query.d.ts.map +1 -0
- package/dist/run/evidence-query.js +270 -0
- package/dist/run/evidence-query.js.map +1 -0
- package/dist/run/evidence-recall.d.ts +99 -0
- package/dist/run/evidence-recall.d.ts.map +1 -0
- package/dist/run/evidence-recall.js +633 -0
- package/dist/run/evidence-recall.js.map +1 -0
- package/dist/run/index.d.ts +2 -0
- package/dist/run/index.d.ts.map +1 -1
- package/dist/run/index.js +1 -0
- package/dist/run/index.js.map +1 -1
- package/dist/run/json-claim-verifier.d.ts +83 -0
- package/dist/run/json-claim-verifier.d.ts.map +1 -0
- package/dist/run/json-claim-verifier.js +200 -0
- package/dist/run/json-claim-verifier.js.map +1 -0
- package/dist/run/preparation-context-error.d.ts +10 -0
- package/dist/run/preparation-context-error.d.ts.map +1 -0
- package/dist/run/preparation-context-error.js +15 -0
- package/dist/run/preparation-context-error.js.map +1 -0
- package/dist/run-query/index.d.ts +3 -1
- package/dist/run-query/index.d.ts.map +1 -1
- package/dist/runtime/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 +7 -1
- package/dist/runtime/query/events.d.ts.map +1 -1
- package/dist/runtime/query/events.js +39 -12
- 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 +40 -25
- 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/prompt-cache.d.ts.map +1 -1
- package/dist/runtime/query/prompt-cache.js +21 -42
- package/dist/runtime/query/prompt-cache.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 +907 -0
- package/src/manager/resident/consumption.ts +311 -0
- package/src/manager/resident/delivery-window.ts +93 -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/host.ts +356 -0
- package/src/manager/resident/initiative.ts +205 -0
- 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 +493 -0
- package/src/manager/resident/loop.ts +101 -0
- package/src/manager/resident/outbox.ts +307 -0
- package/src/manager/resident/proposal.ts +105 -0
- package/src/manager/resident/store.ts +257 -0
- 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/contributions.ts +5 -2
- package/src/prompt/index.ts +4 -0
- package/src/prompt/resident-learning.ts +143 -0
- package/src/prompt/resident-step.ts +176 -0
- 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 +44 -0
- package/src/public-tools.ts +3 -0
- package/src/public-types.ts +165 -0
- package/src/registry/index.ts +1 -1
- package/src/registry/tool/execute.ts +56 -9
- package/src/run/LimitChecker.ts +3 -3
- package/src/run/evidence-query.ts +333 -0
- package/src/run/evidence-recall.ts +854 -0
- package/src/run/index.ts +11 -0
- package/src/run/json-claim-verifier.ts +298 -0
- package/src/run/preparation-context-error.ts +16 -0
- package/src/run-query/index.ts +1 -1
- package/src/runtime/query/callback-inference.ts +94 -0
- package/src/runtime/query/checkpoint.ts +14 -0
- package/src/runtime/query/events.ts +46 -14
- 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 +50 -27
- 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/prompt-cache.ts +24 -47
- 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,312 @@
|
|
|
1
|
+
import { z } from 'zod'
|
|
2
|
+
import type { ResidentAgendaState } from './agenda.js'
|
|
3
|
+
import { ResidentHistoryPageLimit, type ResidentHistoryReadBudget } from './history-disk.js'
|
|
4
|
+
|
|
5
|
+
const SCAN_BYTES = 8 * 1024 * 1024
|
|
6
|
+
const SCAN_REVISIONS = 32
|
|
7
|
+
const TEXT_PAGE_CHARS = 6_000
|
|
8
|
+
|
|
9
|
+
/** @experimental Host-bound historical scope; the upper revision never advances implicitly. */
|
|
10
|
+
export interface ResidentHistoryScope {
|
|
11
|
+
readonly tenantId: string
|
|
12
|
+
readonly agentKey: string
|
|
13
|
+
readonly pursuitId: string
|
|
14
|
+
readonly throughRevision: number
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** @experimental Revision plus part identifies retained text within one pursuit. */
|
|
18
|
+
export interface ResidentHistoryAddress {
|
|
19
|
+
readonly revision: number
|
|
20
|
+
readonly part: number
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** @experimental Summary or accepted wake input from a settled historical step. */
|
|
24
|
+
export interface ResidentHistoryMatch extends ResidentHistoryAddress {
|
|
25
|
+
readonly step: number
|
|
26
|
+
readonly claimId: string
|
|
27
|
+
readonly kind: 'wait' | 'complete' | 'blocked'
|
|
28
|
+
readonly source: 'summary' | 'wake'
|
|
29
|
+
readonly excerpt: string
|
|
30
|
+
readonly matchingParts: readonly number[]
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** @experimental Empty query browses recent steps; cursor is the next inclusive revision. */
|
|
34
|
+
export interface ResidentHistorySearchOptions {
|
|
35
|
+
/** Optional per-call ceiling, 1 byte–8 MiB. Defaults to 8 MiB. */
|
|
36
|
+
readonly maxReadBytes?: number
|
|
37
|
+
readonly query?: string
|
|
38
|
+
readonly cursor?: number
|
|
39
|
+
readonly limit?: number
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** @experimental Counts describe this page, not the whole history. */
|
|
43
|
+
export interface ResidentHistorySearchResult {
|
|
44
|
+
readonly matches: readonly ResidentHistoryMatch[]
|
|
45
|
+
readonly nextCursor: number | null
|
|
46
|
+
readonly scannedRevisions: number
|
|
47
|
+
readonly scannedBytes: number
|
|
48
|
+
readonly unavailableRevisions: readonly number[]
|
|
49
|
+
readonly incomplete: boolean
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** @experimental Use the returned nextOffset to continue exact Unicode-safe text. */
|
|
53
|
+
export interface ResidentHistoryReadOptions extends ResidentHistoryAddress {
|
|
54
|
+
readonly offset?: number
|
|
55
|
+
/** Optional per-call ceiling, 1 byte–8 MiB. Defaults to 8 MiB. */
|
|
56
|
+
readonly maxReadBytes?: number
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** @experimental A recorded claim remains historical evidence, not proof of current validity. */
|
|
60
|
+
export interface ResidentHistoryText extends ResidentHistoryAddress {
|
|
61
|
+
readonly step: number
|
|
62
|
+
readonly claimId: string
|
|
63
|
+
readonly kind: 'wait' | 'complete' | 'blocked'
|
|
64
|
+
readonly source: 'summary' | 'wake'
|
|
65
|
+
readonly receivedAt?: number
|
|
66
|
+
readonly text: string
|
|
67
|
+
readonly offset: number
|
|
68
|
+
readonly totalChars: number
|
|
69
|
+
readonly nextOffset: number | null
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** @experimental Null with unavailable revisions means unreadable evidence, not proven absence. */
|
|
73
|
+
export interface ResidentHistoryReadResult {
|
|
74
|
+
readonly entry: ResidentHistoryText | null
|
|
75
|
+
readonly scannedRevisions: number
|
|
76
|
+
readonly scannedBytes: number
|
|
77
|
+
readonly unavailableRevisions: readonly number[]
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** @experimental A backend must enforce its bound scope and bounded reads. */
|
|
81
|
+
export interface ResidentHistorySource {
|
|
82
|
+
readonly scope: ResidentHistoryScope
|
|
83
|
+
search(
|
|
84
|
+
options?: ResidentHistorySearchOptions,
|
|
85
|
+
signal?: AbortSignal,
|
|
86
|
+
): Promise<ResidentHistorySearchResult>
|
|
87
|
+
read(
|
|
88
|
+
options: ResidentHistoryReadOptions,
|
|
89
|
+
signal?: AbortSignal,
|
|
90
|
+
): Promise<ResidentHistoryReadResult>
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
type LoadRevision = (
|
|
94
|
+
revision: number,
|
|
95
|
+
budget: ResidentHistoryReadBudget,
|
|
96
|
+
) => Promise<ResidentAgendaState>
|
|
97
|
+
interface Part {
|
|
98
|
+
source: 'summary' | 'wake'
|
|
99
|
+
text: string
|
|
100
|
+
receivedAt?: number
|
|
101
|
+
}
|
|
102
|
+
interface Episode {
|
|
103
|
+
step: number
|
|
104
|
+
claimId: string
|
|
105
|
+
kind: 'wait' | 'complete' | 'blocked'
|
|
106
|
+
parts: Part[]
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function episode(
|
|
110
|
+
before: ResidentAgendaState | null,
|
|
111
|
+
after: ResidentAgendaState | null,
|
|
112
|
+
id: string,
|
|
113
|
+
): Episode | null {
|
|
114
|
+
const previous = before?.pursuits.find((p) => p.id === id)?.state
|
|
115
|
+
const current = after?.pursuits.find((p) => p.id === id)?.state
|
|
116
|
+
if (
|
|
117
|
+
!before ||
|
|
118
|
+
!after ||
|
|
119
|
+
!previous ||
|
|
120
|
+
!current ||
|
|
121
|
+
previous.phase !== 'running' ||
|
|
122
|
+
!previous.claimId ||
|
|
123
|
+
current.phase === 'running' ||
|
|
124
|
+
current.claimId !== null ||
|
|
125
|
+
current.summary === null ||
|
|
126
|
+
current.stepsAdmitted !== previous.stepsAdmitted ||
|
|
127
|
+
current.revision !== previous.revision + 1
|
|
128
|
+
)
|
|
129
|
+
return null
|
|
130
|
+
return {
|
|
131
|
+
step: current.stepsAdmitted,
|
|
132
|
+
claimId: previous.claimId,
|
|
133
|
+
kind: current.phase === 'waiting' ? 'wait' : current.phase,
|
|
134
|
+
parts: [
|
|
135
|
+
{ source: 'summary', text: current.summary },
|
|
136
|
+
...(previous.wakeEvidence ?? []).map((entry) => ({
|
|
137
|
+
source: 'wake' as const,
|
|
138
|
+
text: entry.reason,
|
|
139
|
+
receivedAt: entry.receivedAt,
|
|
140
|
+
})),
|
|
141
|
+
],
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function boundary(text: string, offset: number): boolean {
|
|
146
|
+
const current = text.charCodeAt(offset)
|
|
147
|
+
const previous = text.charCodeAt(offset - 1)
|
|
148
|
+
return !(current >= 0xdc00 && current <= 0xdfff && previous >= 0xd800 && previous <= 0xdbff)
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function textSlice(text: string, offset: number, maxChars: number): string {
|
|
152
|
+
let end = Math.min(text.length, offset + maxChars)
|
|
153
|
+
if (!boundary(text, end)) end--
|
|
154
|
+
return text.slice(offset, end)
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/** Internal disk adapter. Other backends may implement ResidentHistorySource directly. */
|
|
158
|
+
export function createResidentHistorySource(
|
|
159
|
+
scopeInput: ResidentHistoryScope,
|
|
160
|
+
identity: { identity: string; objective: string },
|
|
161
|
+
load: LoadRevision,
|
|
162
|
+
): ResidentHistorySource {
|
|
163
|
+
const scope = Object.freeze({ ...scopeInput })
|
|
164
|
+
const expected = { ...identity }
|
|
165
|
+
const revisionSchema = z.number().int().min(1).max(scope.throughRevision).safe()
|
|
166
|
+
function page(signal: AbortSignal | undefined, requestedBytes: number | undefined) {
|
|
167
|
+
const limit = z
|
|
168
|
+
.number()
|
|
169
|
+
.int()
|
|
170
|
+
.min(1)
|
|
171
|
+
.max(SCAN_BYTES)
|
|
172
|
+
.parse(requestedBytes ?? SCAN_BYTES)
|
|
173
|
+
const budget: ResidentHistoryReadBudget = { remaining: limit, bytesRead: 0, signal }
|
|
174
|
+
const unavailable = new Set<number>()
|
|
175
|
+
let scanned = 0
|
|
176
|
+
const cache = new Map<number, ResidentAgendaState | null>()
|
|
177
|
+
return {
|
|
178
|
+
budget,
|
|
179
|
+
async load(revision: number) {
|
|
180
|
+
signal?.throwIfAborted()
|
|
181
|
+
if (cache.has(revision)) return cache.get(revision) ?? null
|
|
182
|
+
if (scanned >= SCAN_REVISIONS) throw new ResidentHistoryPageLimit()
|
|
183
|
+
scanned++
|
|
184
|
+
let record: ResidentAgendaState | null = null
|
|
185
|
+
try {
|
|
186
|
+
record = await load(revision, budget)
|
|
187
|
+
const pursuit = record.pursuits.find((p) => p.id === scope.pursuitId)
|
|
188
|
+
if (
|
|
189
|
+
record.revision !== revision ||
|
|
190
|
+
record.tenantId !== scope.tenantId ||
|
|
191
|
+
record.agentKey !== scope.agentKey ||
|
|
192
|
+
(pursuit &&
|
|
193
|
+
(pursuit.state.identity !== expected.identity ||
|
|
194
|
+
pursuit.state.objective !== expected.objective))
|
|
195
|
+
)
|
|
196
|
+
throw new Error('History identity does not match its bound pursuit.')
|
|
197
|
+
} catch (error) {
|
|
198
|
+
signal?.throwIfAborted()
|
|
199
|
+
if (error instanceof ResidentHistoryPageLimit) throw error
|
|
200
|
+
unavailable.add(revision)
|
|
201
|
+
record = null
|
|
202
|
+
}
|
|
203
|
+
// Adjacent revisions are reused on the next scan iteration, without
|
|
204
|
+
// keeping the whole archive in memory.
|
|
205
|
+
if (cache.size >= 2) cache.delete(cache.keys().next().value as number)
|
|
206
|
+
cache.set(revision, record)
|
|
207
|
+
return record
|
|
208
|
+
},
|
|
209
|
+
counts: () => ({
|
|
210
|
+
scannedRevisions: scanned,
|
|
211
|
+
scannedBytes: budget.bytesRead,
|
|
212
|
+
unavailableRevisions: [...unavailable],
|
|
213
|
+
}),
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
return Object.freeze({
|
|
217
|
+
scope,
|
|
218
|
+
async search(options: ResidentHistorySearchOptions = {}, signal?: AbortSignal) {
|
|
219
|
+
signal?.throwIfAborted()
|
|
220
|
+
const query = z
|
|
221
|
+
.string()
|
|
222
|
+
.max(256)
|
|
223
|
+
.parse(options.query ?? '')
|
|
224
|
+
const limit = z
|
|
225
|
+
.number()
|
|
226
|
+
.int()
|
|
227
|
+
.min(1)
|
|
228
|
+
.max(8)
|
|
229
|
+
.parse(options.limit ?? 5)
|
|
230
|
+
let revision = revisionSchema.parse(options.cursor ?? scope.throughRevision)
|
|
231
|
+
const reader = page(signal, options.maxReadBytes)
|
|
232
|
+
const matches: ResidentHistoryMatch[] = []
|
|
233
|
+
while (revision >= 2 && matches.length < limit) {
|
|
234
|
+
let found: Episode | null
|
|
235
|
+
try {
|
|
236
|
+
const after = await reader.load(revision)
|
|
237
|
+
const before = await reader.load(revision - 1)
|
|
238
|
+
found = episode(before, after, scope.pursuitId)
|
|
239
|
+
} catch (error) {
|
|
240
|
+
if (!(error instanceof ResidentHistoryPageLimit)) throw error
|
|
241
|
+
break
|
|
242
|
+
}
|
|
243
|
+
if (found) {
|
|
244
|
+
const matchingParts = found.parts.flatMap((part, index) =>
|
|
245
|
+
part.text.includes(query) ? [index] : [],
|
|
246
|
+
)
|
|
247
|
+
const part = matchingParts[0]
|
|
248
|
+
const matched = part === undefined ? undefined : found.parts[part]
|
|
249
|
+
if (matched && part !== undefined) {
|
|
250
|
+
let start = Math.max(0, matched.text.indexOf(query) - 120)
|
|
251
|
+
if (!boundary(matched.text, start)) start--
|
|
252
|
+
matches.push({
|
|
253
|
+
revision,
|
|
254
|
+
part,
|
|
255
|
+
step: found.step,
|
|
256
|
+
claimId: found.claimId,
|
|
257
|
+
kind: found.kind,
|
|
258
|
+
source: matched.source,
|
|
259
|
+
excerpt: textSlice(matched.text, start, 512),
|
|
260
|
+
matchingParts,
|
|
261
|
+
})
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
revision--
|
|
265
|
+
}
|
|
266
|
+
const nextCursor = revision >= 2 ? revision : null
|
|
267
|
+
const counts = reader.counts()
|
|
268
|
+
return {
|
|
269
|
+
matches,
|
|
270
|
+
nextCursor,
|
|
271
|
+
...counts,
|
|
272
|
+
incomplete: nextCursor !== null || counts.unavailableRevisions.length > 0,
|
|
273
|
+
}
|
|
274
|
+
},
|
|
275
|
+
async read(options: ResidentHistoryReadOptions, signal?: AbortSignal) {
|
|
276
|
+
const revision = revisionSchema.parse(options.revision)
|
|
277
|
+
const part = z.number().int().min(0).max(16).parse(options.part)
|
|
278
|
+
const offset = z
|
|
279
|
+
.number()
|
|
280
|
+
.int()
|
|
281
|
+
.nonnegative()
|
|
282
|
+
.safe()
|
|
283
|
+
.parse(options.offset ?? 0)
|
|
284
|
+
const reader = page(signal, options.maxReadBytes)
|
|
285
|
+
const after = await reader.load(revision)
|
|
286
|
+
const before = revision >= 2 ? await reader.load(revision - 1) : null
|
|
287
|
+
const found = episode(before, after, scope.pursuitId)
|
|
288
|
+
const selected = found?.parts[part]
|
|
289
|
+
if (!selected || !found) return { entry: null, ...reader.counts() }
|
|
290
|
+
if (offset > selected.text.length || !boundary(selected.text, offset))
|
|
291
|
+
throw new Error('Invalid retained text offset; use nextOffset from the previous page.')
|
|
292
|
+
const text = textSlice(selected.text, offset, TEXT_PAGE_CHARS)
|
|
293
|
+
const end = offset + text.length
|
|
294
|
+
return {
|
|
295
|
+
entry: {
|
|
296
|
+
revision,
|
|
297
|
+
part,
|
|
298
|
+
step: found.step,
|
|
299
|
+
claimId: found.claimId,
|
|
300
|
+
kind: found.kind,
|
|
301
|
+
source: selected.source,
|
|
302
|
+
...(selected.receivedAt !== undefined ? { receivedAt: selected.receivedAt } : {}),
|
|
303
|
+
text,
|
|
304
|
+
offset,
|
|
305
|
+
totalChars: selected.text.length,
|
|
306
|
+
nextOffset: end < selected.text.length ? end : null,
|
|
307
|
+
},
|
|
308
|
+
...reader.counts(),
|
|
309
|
+
}
|
|
310
|
+
},
|
|
311
|
+
})
|
|
312
|
+
}
|
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
import { setTimeout as sleep } from 'node:timers/promises'
|
|
2
|
+
import type { ResidentAgendaState, ResidentAgendaStore, ResidentPursuit } from './agenda.js'
|
|
3
|
+
import {
|
|
4
|
+
type ResidentObservation,
|
|
5
|
+
type ResidentSelection,
|
|
6
|
+
type ResidentSelector,
|
|
7
|
+
residentObservationSchema,
|
|
8
|
+
} from './initiative.js'
|
|
9
|
+
import { type ResidentLearningState, freezeResidentLearning } from './learning.js'
|
|
10
|
+
import { type ResidentStep, stepResident } from './loop.js'
|
|
11
|
+
import { type ResidentMessageInput, residentMessageInputSchema } from './outbox.js'
|
|
12
|
+
import { ResidentConflictError, type ResidentDecision, residentDecisionSchema } from './store.js'
|
|
13
|
+
|
|
14
|
+
/** @experimental Host result describes execution, not external-effect rollback. */
|
|
15
|
+
export interface ResidentHostResult {
|
|
16
|
+
readonly status: 'idle' | 'paused' | 'unresolved' | 'cancelled' | 'limit' | 'contended'
|
|
17
|
+
readonly stepsSettled: number
|
|
18
|
+
readonly nextWakeAt: number | null
|
|
19
|
+
readonly selection?: ResidentSelection
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/** @experimental Explicit authorization to drive a finite number of background steps. */
|
|
23
|
+
export interface ResidentHostRunOptions {
|
|
24
|
+
readonly signal: AbortSignal
|
|
25
|
+
readonly maxSteps: number
|
|
26
|
+
/** Maximum single idle wait; with keepAlive, also bounds local agenda polling. */
|
|
27
|
+
readonly maxIdleMs?: number
|
|
28
|
+
/** Keep waiting for useful work within this invocation's finite step cap. Default false. */
|
|
29
|
+
readonly keepAlive?: boolean
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** @experimental Immutable context from the agenda snapshot that authorized this admission. */
|
|
33
|
+
export interface ResidentStepContext {
|
|
34
|
+
readonly agendaRevision: number
|
|
35
|
+
readonly learning?: ResidentLearningState
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** @experimental A developer callback may bind a different SDK run for each pursuit. */
|
|
39
|
+
export type ResidentPursuitStep = (
|
|
40
|
+
pursuit: ResidentPursuit,
|
|
41
|
+
signal: AbortSignal,
|
|
42
|
+
) => ReturnType<ResidentStep>
|
|
43
|
+
|
|
44
|
+
/** @experimental Context-aware callback; existing two-argument steps remain assignable. */
|
|
45
|
+
export type ResidentContextualStep = (
|
|
46
|
+
pursuit: ResidentPursuit,
|
|
47
|
+
signal: AbortSignal,
|
|
48
|
+
context: ResidentStepContext,
|
|
49
|
+
) => ReturnType<ResidentStep>
|
|
50
|
+
|
|
51
|
+
/** @experimental Inspect actual outcomes and resource receipts independently of model prose. */
|
|
52
|
+
export type ResidentObserver = (
|
|
53
|
+
pursuit: ResidentPursuit,
|
|
54
|
+
decision: ResidentDecision,
|
|
55
|
+
signal: AbortSignal,
|
|
56
|
+
) => Promise<ResidentObservation>
|
|
57
|
+
|
|
58
|
+
/** @experimental Host validates content and destination; null means no communication. */
|
|
59
|
+
export type ResidentMessageFactory = (
|
|
60
|
+
pursuit: ResidentPursuit,
|
|
61
|
+
decision: ResidentDecision,
|
|
62
|
+
signal: AbortSignal,
|
|
63
|
+
) => Promise<ResidentMessageInput | null>
|
|
64
|
+
|
|
65
|
+
/** @experimental Opt-in local selection, observed settlement and atomic outbound intent. */
|
|
66
|
+
export interface ResidentHostOptions {
|
|
67
|
+
readonly select?: ResidentSelector
|
|
68
|
+
readonly observe?: ResidentObserver
|
|
69
|
+
readonly prepareMessage?: ResidentMessageFactory
|
|
70
|
+
/** Bind approved learning to the exact admission snapshot. Default false. */
|
|
71
|
+
readonly learning?: boolean
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* @experimental Local driver for one durable agenda. Shared agenda admission
|
|
76
|
+
* prevents overlapping pursuits across processes. Notifications are local;
|
|
77
|
+
* opt-in keepAlive also rereads durable state on bounded idle timers.
|
|
78
|
+
*/
|
|
79
|
+
export class ResidentHost {
|
|
80
|
+
private controller: AbortController | undefined
|
|
81
|
+
private active: Promise<ResidentHostResult> | undefined
|
|
82
|
+
private idle: AbortController | undefined
|
|
83
|
+
private generation = 0
|
|
84
|
+
private controls: Promise<void> = Promise.resolve()
|
|
85
|
+
private controlsPending = 0
|
|
86
|
+
private readonly options: ResidentHostOptions
|
|
87
|
+
|
|
88
|
+
constructor(
|
|
89
|
+
private readonly agenda: ResidentAgendaStore,
|
|
90
|
+
private readonly step: ResidentContextualStep,
|
|
91
|
+
options: ResidentHostOptions = {},
|
|
92
|
+
) {
|
|
93
|
+
if (options.learning !== undefined && typeof options.learning !== 'boolean')
|
|
94
|
+
throw new TypeError('Resident learning must be explicitly enabled with a boolean.')
|
|
95
|
+
if ((options.select || options.learning) && !agenda.executionAt)
|
|
96
|
+
throw new TypeError('Resident selection or learning requires atomic executionAt support.')
|
|
97
|
+
if (options.observe && !agenda.settleObserved)
|
|
98
|
+
throw new TypeError('Resident observation requires atomic settleObserved support.')
|
|
99
|
+
if (options.prepareMessage && !agenda.settleWithMessage)
|
|
100
|
+
throw new TypeError('Resident messages require atomic settleWithMessage support.')
|
|
101
|
+
this.options = Object.freeze({ ...options })
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/** Interrupt local idle waiting after the host learns of new durable state. */
|
|
105
|
+
notify(): void {
|
|
106
|
+
this.generation++
|
|
107
|
+
this.idle?.abort()
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
private async snapshot(): Promise<ResidentAgendaState> {
|
|
111
|
+
const state = await this.agenda.read()
|
|
112
|
+
if (!state) throw new Error('Create the resident agenda before running the host.')
|
|
113
|
+
return state
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
private async paused(value: boolean): Promise<void> {
|
|
117
|
+
for (let attempt = 0; attempt < 8; attempt++) {
|
|
118
|
+
const state = await this.snapshot()
|
|
119
|
+
if (state.paused === value) return
|
|
120
|
+
try {
|
|
121
|
+
await this.agenda.setPaused(state, value)
|
|
122
|
+
return
|
|
123
|
+
} catch (error) {
|
|
124
|
+
if (!(error instanceof ResidentConflictError) || attempt === 7) throw error
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
private control(update: () => Promise<void>): Promise<void> {
|
|
130
|
+
this.controlsPending++
|
|
131
|
+
const pending = this.controls.then(update)
|
|
132
|
+
this.controls = pending.catch(() => {})
|
|
133
|
+
return pending.finally(() => {
|
|
134
|
+
this.controlsPending--
|
|
135
|
+
})
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Signal current work and durably close future admission. Resolving this method
|
|
140
|
+
* is NOT quiescence: await the run promise before claiming the callback stopped.
|
|
141
|
+
* An interrupted admitted pursuit remains unresolved until reconciled explicitly.
|
|
142
|
+
*/
|
|
143
|
+
async pause(): Promise<void> {
|
|
144
|
+
this.controller?.abort()
|
|
145
|
+
this.notify()
|
|
146
|
+
await this.control(() => this.paused(true))
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/** Reauthorize future work only after this host's previous invocation drained. */
|
|
150
|
+
async resume(): Promise<void> {
|
|
151
|
+
if (this.controlsPending) throw new Error('Wait for pending resident controls before resuming.')
|
|
152
|
+
if (this.active)
|
|
153
|
+
throw new Error('Wait for the active resident invocation to drain before resuming.')
|
|
154
|
+
await this.control(() => this.paused(false))
|
|
155
|
+
this.notify()
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/** Persist fresh evidence and interrupt this host's idle timer. */
|
|
159
|
+
async wake(id: string, reason: string): Promise<void> {
|
|
160
|
+
const state = await this.snapshot()
|
|
161
|
+
const pursuit = state.pursuits.find((p) => p.id === id)
|
|
162
|
+
if (!pursuit) throw new Error('Unknown resident pursuit.')
|
|
163
|
+
await this.agenda.wake(id, pursuit.state, reason, Date.now())
|
|
164
|
+
this.notify()
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
run(options: ResidentHostRunOptions): Promise<ResidentHostResult> {
|
|
168
|
+
if (this.controlsPending) throw new Error('Wait for pending resident controls before running.')
|
|
169
|
+
if (this.active) throw new Error('A resident host invocation is already active.')
|
|
170
|
+
const maxIdleMs = options.maxIdleMs ?? 60_000
|
|
171
|
+
const keepAlive = options.keepAlive ?? false
|
|
172
|
+
if (options.keepAlive !== undefined && typeof options.keepAlive !== 'boolean')
|
|
173
|
+
throw new TypeError('Resident keepAlive must be explicitly enabled with a boolean.')
|
|
174
|
+
if (
|
|
175
|
+
!Number.isSafeInteger(options.maxSteps) ||
|
|
176
|
+
options.maxSteps < 1 ||
|
|
177
|
+
!Number.isSafeInteger(maxIdleMs) ||
|
|
178
|
+
maxIdleMs < 0 ||
|
|
179
|
+
maxIdleMs > 2_147_483_647 ||
|
|
180
|
+
(keepAlive && maxIdleMs === 0)
|
|
181
|
+
)
|
|
182
|
+
throw new TypeError('Invalid resident host limits.')
|
|
183
|
+
const controller = new AbortController()
|
|
184
|
+
this.controller = controller
|
|
185
|
+
const signal = AbortSignal.any([controller.signal, options.signal])
|
|
186
|
+
this.active = this.drive(options.maxSteps, maxIdleMs, keepAlive, signal).finally(() => {
|
|
187
|
+
this.active = undefined
|
|
188
|
+
this.controller = undefined
|
|
189
|
+
this.idle = undefined
|
|
190
|
+
})
|
|
191
|
+
return this.active
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
private async drive(
|
|
195
|
+
maxSteps: number,
|
|
196
|
+
maxIdleMs: number,
|
|
197
|
+
keepAlive: boolean,
|
|
198
|
+
signal: AbortSignal,
|
|
199
|
+
): Promise<ResidentHostResult> {
|
|
200
|
+
let stepsSettled = 0
|
|
201
|
+
try {
|
|
202
|
+
while (true) {
|
|
203
|
+
signal.throwIfAborted()
|
|
204
|
+
const observed = this.generation
|
|
205
|
+
const state = await this.snapshot()
|
|
206
|
+
signal.throwIfAborted()
|
|
207
|
+
if (state.paused) return { status: 'paused', stepsSettled, nextWakeAt: null }
|
|
208
|
+
if (state.pursuits.some((p) => p.state.phase === 'running'))
|
|
209
|
+
return { status: 'unresolved', stepsSettled, nextWakeAt: null }
|
|
210
|
+
const waiting = state.pursuits.filter(
|
|
211
|
+
(p) => p.state.phase === 'waiting' && p.state.wakeAt !== null,
|
|
212
|
+
)
|
|
213
|
+
const now = Date.now()
|
|
214
|
+
// Fair, deterministic baseline; this is not model-authored initiative.
|
|
215
|
+
let due = waiting
|
|
216
|
+
.filter((p) => (p.state.wakeAt ?? 0) <= now)
|
|
217
|
+
.sort(
|
|
218
|
+
(a, b) =>
|
|
219
|
+
a.state.stepsAdmitted - b.state.stepsAdmitted ||
|
|
220
|
+
(a.state.wakeAt ?? 0) - (b.state.wakeAt ?? 0) ||
|
|
221
|
+
a.id.localeCompare(b.id),
|
|
222
|
+
)[0]
|
|
223
|
+
let selection: ResidentSelection | undefined
|
|
224
|
+
if (due && this.options.select) {
|
|
225
|
+
selection = this.options.select(state, now)
|
|
226
|
+
signal.throwIfAborted()
|
|
227
|
+
if (selection.agendaRevision !== state.revision)
|
|
228
|
+
throw new Error('Resident selector returned a stale agenda revision.')
|
|
229
|
+
if (selection.pursuitId === null) due = undefined
|
|
230
|
+
else {
|
|
231
|
+
const selectedId = selection.pursuitId
|
|
232
|
+
due = waiting.find((p) => p.id === selectedId && (p.state.wakeAt ?? 0) <= now)
|
|
233
|
+
if (!due) throw new Error('Resident selector chose an ineligible pursuit.')
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
if (due) {
|
|
238
|
+
const selected = due
|
|
239
|
+
const context: ResidentStepContext = Object.freeze({
|
|
240
|
+
agendaRevision: state.revision,
|
|
241
|
+
...(this.options.learning && state.learning
|
|
242
|
+
? { learning: freezeResidentLearning(state.learning) }
|
|
243
|
+
: {}),
|
|
244
|
+
})
|
|
245
|
+
const execution =
|
|
246
|
+
this.options.select || this.options.learning
|
|
247
|
+
? this.agenda.executionAt?.(selected.id, state)
|
|
248
|
+
: this.agenda.execution(selected.id)
|
|
249
|
+
if (!execution) throw new Error('Resident executionAt support was removed.')
|
|
250
|
+
const observe = this.options.observe
|
|
251
|
+
const prepareMessage = this.options.prepareMessage
|
|
252
|
+
const observedExecution =
|
|
253
|
+
observe || prepareMessage
|
|
254
|
+
? {
|
|
255
|
+
read: () => execution.read(),
|
|
256
|
+
claim: (...args: Parameters<typeof execution.claim>) => execution.claim(...args),
|
|
257
|
+
settle: async (
|
|
258
|
+
current: Parameters<typeof execution.settle>[0],
|
|
259
|
+
decision: ResidentDecision,
|
|
260
|
+
at: number,
|
|
261
|
+
) => {
|
|
262
|
+
const disposition = Object.freeze(residentDecisionSchema.parse(decision))
|
|
263
|
+
const observed = await observe?.(
|
|
264
|
+
{ ...selected, state: current },
|
|
265
|
+
disposition,
|
|
266
|
+
signal,
|
|
267
|
+
)
|
|
268
|
+
signal.throwIfAborted()
|
|
269
|
+
const observation = observe
|
|
270
|
+
? Object.freeze(residentObservationSchema.parse(observed))
|
|
271
|
+
: undefined
|
|
272
|
+
const prepared = await prepareMessage?.(
|
|
273
|
+
{ ...selected, state: current },
|
|
274
|
+
disposition,
|
|
275
|
+
signal,
|
|
276
|
+
)
|
|
277
|
+
signal.throwIfAborted()
|
|
278
|
+
const message =
|
|
279
|
+
prepareMessage && prepared !== null
|
|
280
|
+
? Object.freeze(residentMessageInputSchema.parse(prepared))
|
|
281
|
+
: null
|
|
282
|
+
if (message !== null) {
|
|
283
|
+
if (!this.agenda.settleWithMessage)
|
|
284
|
+
throw new Error('Resident settleWithMessage support was removed.')
|
|
285
|
+
return this.agenda.settleWithMessage(
|
|
286
|
+
selected.id,
|
|
287
|
+
current,
|
|
288
|
+
disposition,
|
|
289
|
+
message,
|
|
290
|
+
at,
|
|
291
|
+
observation,
|
|
292
|
+
)
|
|
293
|
+
}
|
|
294
|
+
if (observation) {
|
|
295
|
+
if (!this.agenda.settleObserved)
|
|
296
|
+
throw new Error('Resident settleObserved support was removed.')
|
|
297
|
+
return this.agenda.settleObserved(
|
|
298
|
+
selected.id,
|
|
299
|
+
current,
|
|
300
|
+
disposition,
|
|
301
|
+
observation,
|
|
302
|
+
at,
|
|
303
|
+
)
|
|
304
|
+
}
|
|
305
|
+
return execution.settle(current, disposition, at)
|
|
306
|
+
},
|
|
307
|
+
}
|
|
308
|
+
: execution
|
|
309
|
+
const result = await stepResident(
|
|
310
|
+
observedExecution,
|
|
311
|
+
(current, abort) => this.step({ ...selected, state: current }, abort, context),
|
|
312
|
+
signal,
|
|
313
|
+
)
|
|
314
|
+
if (result.status === 'idle')
|
|
315
|
+
return {
|
|
316
|
+
status: result.reason === 'unresolved' ? 'unresolved' : 'contended',
|
|
317
|
+
stepsSettled,
|
|
318
|
+
nextWakeAt: null,
|
|
319
|
+
}
|
|
320
|
+
stepsSettled++
|
|
321
|
+
if (stepsSettled >= maxSteps) return { status: 'limit', stepsSettled, nextWakeAt: null }
|
|
322
|
+
continue
|
|
323
|
+
}
|
|
324
|
+
const scheduled =
|
|
325
|
+
selection?.pursuitId === null
|
|
326
|
+
? waiting.filter((p) => (p.state.wakeAt ?? 0) > now)
|
|
327
|
+
: waiting
|
|
328
|
+
const nextWakeAt =
|
|
329
|
+
scheduled.length === 0 ? null : Math.min(...scheduled.map((p) => p.state.wakeAt ?? now))
|
|
330
|
+
if (observed !== this.generation) continue
|
|
331
|
+
if (!keepAlive && (nextWakeAt === null || nextWakeAt - now > maxIdleMs))
|
|
332
|
+
return { status: 'idle', stepsSettled, nextWakeAt, ...(selection ? { selection } : {}) }
|
|
333
|
+
const delay =
|
|
334
|
+
nextWakeAt === null
|
|
335
|
+
? maxIdleMs
|
|
336
|
+
: keepAlive
|
|
337
|
+
? Math.min(maxIdleMs, nextWakeAt - now)
|
|
338
|
+
: nextWakeAt - now
|
|
339
|
+
const idle = new AbortController()
|
|
340
|
+
this.idle = idle
|
|
341
|
+
try {
|
|
342
|
+
await sleep(Math.max(1, delay), undefined, {
|
|
343
|
+
signal: AbortSignal.any([signal, idle.signal]),
|
|
344
|
+
})
|
|
345
|
+
} catch (error) {
|
|
346
|
+
if (!idle.signal.aborted || signal.aborted) throw error
|
|
347
|
+
} finally {
|
|
348
|
+
if (this.idle === idle) this.idle = undefined
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
} catch (error) {
|
|
352
|
+
if (!signal.aborted) throw error
|
|
353
|
+
return { status: 'cancelled', stepsSettled, nextWakeAt: null }
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
}
|