@namzu/sdk 36.0.0 → 38.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 +244 -0
- package/README.md +68 -41
- package/dist/bridge/a2a/mapper.d.ts.map +1 -1
- package/dist/bridge/a2a/mapper.js +4 -0
- package/dist/bridge/a2a/mapper.js.map +1 -1
- package/dist/bridge/sse/mapper.d.ts.map +1 -1
- package/dist/bridge/sse/mapper.js +16 -1
- package/dist/bridge/sse/mapper.js.map +1 -1
- package/dist/compaction/extractor.d.ts +1 -1
- package/dist/compaction/extractor.d.ts.map +1 -1
- package/dist/compaction/extractor.js +15 -7
- package/dist/compaction/extractor.js.map +1 -1
- package/dist/compaction/manager.d.ts +2 -0
- package/dist/compaction/manager.d.ts.map +1 -1
- package/dist/compaction/manager.js +12 -1
- package/dist/compaction/manager.js.map +1 -1
- package/dist/compaction/verifier.d.ts.map +1 -1
- package/dist/compaction/verifier.js +82 -15
- package/dist/compaction/verifier.js.map +1 -1
- package/dist/config/runtime.d.ts +16 -6
- package/dist/config/runtime.d.ts.map +1 -1
- package/dist/config/runtime.js +2 -0
- package/dist/config/runtime.js.map +1 -1
- package/dist/contracts/api.d.ts +1 -1
- package/dist/contracts/api.d.ts.map +1 -1
- package/dist/contracts/schemas.d.ts +10 -10
- package/dist/eval/harness-verification.d.ts +63 -0
- package/dist/eval/harness-verification.d.ts.map +1 -0
- package/dist/eval/harness-verification.js +165 -0
- package/dist/eval/harness-verification.js.map +1 -0
- package/dist/eval/index.d.ts +2 -0
- package/dist/eval/index.d.ts.map +1 -1
- package/dist/eval/index.js +1 -0
- package/dist/eval/index.js.map +1 -1
- package/dist/execution/code-runtime/json-value.d.ts +10 -0
- package/dist/execution/code-runtime/json-value.d.ts.map +1 -0
- package/dist/execution/code-runtime/json-value.js +89 -0
- package/dist/execution/code-runtime/json-value.js.map +1 -0
- package/dist/execution/code-runtime/worker-program.d.ts +8 -0
- package/dist/execution/code-runtime/worker-program.d.ts.map +1 -0
- package/dist/execution/code-runtime/worker-program.js +240 -0
- package/dist/execution/code-runtime/worker-program.js.map +1 -0
- package/dist/execution/code-runtime/worker.d.ts +22 -0
- package/dist/execution/code-runtime/worker.d.ts.map +1 -1
- package/dist/execution/code-runtime/worker.js +148 -111
- package/dist/execution/code-runtime/worker.js.map +1 -1
- package/dist/manager/agent/lifecycle.d.ts +12 -0
- package/dist/manager/agent/lifecycle.d.ts.map +1 -1
- package/dist/manager/agent/lifecycle.js +316 -46
- package/dist/manager/agent/lifecycle.js.map +1 -1
- package/dist/manager/run/persistence.d.ts +2 -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/prompt/coding-agent-doctrine.d.ts +2 -2
- package/dist/prompt/coding-agent-doctrine.d.ts.map +1 -1
- package/dist/prompt/coding-agent-doctrine.js +11 -5
- package/dist/prompt/coding-agent-doctrine.js.map +1 -1
- package/dist/provider/capabilities.d.ts +5 -1
- package/dist/provider/capabilities.d.ts.map +1 -1
- package/dist/provider/capabilities.js +24 -0
- package/dist/provider/capabilities.js.map +1 -1
- package/dist/provider/fallback.d.ts.map +1 -1
- package/dist/provider/fallback.js +6 -2
- package/dist/provider/fallback.js.map +1 -1
- package/dist/public-runtime.d.ts +4 -1
- package/dist/public-runtime.d.ts.map +1 -1
- package/dist/public-runtime.js +3 -1
- package/dist/public-runtime.js.map +1 -1
- package/dist/public-tools.d.ts +2 -1
- package/dist/public-tools.d.ts.map +1 -1
- package/dist/public-tools.js +2 -1
- package/dist/public-tools.js.map +1 -1
- package/dist/public-types.d.ts +2 -0
- package/dist/public-types.d.ts.map +1 -1
- package/dist/registry/tool/execute.d.ts +3 -0
- package/dist/registry/tool/execute.d.ts.map +1 -1
- package/dist/registry/tool/execute.js +11 -80
- package/dist/registry/tool/execute.js.map +1 -1
- package/dist/run/command-gate.d.ts.map +1 -1
- package/dist/run/command-gate.js +65 -12
- package/dist/run/command-gate.js.map +1 -1
- 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/memory-promoter.d.ts +3 -35
- package/dist/run/memory-promoter.d.ts.map +1 -1
- package/dist/run/memory-promoter.js +32 -40
- package/dist/run/memory-promoter.js.map +1 -1
- package/dist/run/memory-recall.d.ts +25 -0
- package/dist/run/memory-recall.d.ts.map +1 -0
- package/dist/run/memory-recall.js +228 -0
- package/dist/run/memory-recall.js.map +1 -0
- package/dist/run/reporter.d.ts.map +1 -1
- package/dist/run/reporter.js +2 -0
- package/dist/run/reporter.js.map +1 -1
- package/dist/run/token-budget.d.ts +12 -4
- package/dist/run/token-budget.d.ts.map +1 -1
- package/dist/run/token-budget.js +49 -14
- package/dist/run/token-budget.js.map +1 -1
- package/dist/run/workspace-fingerprint.d.ts +10 -3
- package/dist/run/workspace-fingerprint.d.ts.map +1 -1
- package/dist/run/workspace-fingerprint.js +17 -8
- package/dist/run/workspace-fingerprint.js.map +1 -1
- package/dist/runtime/query/checkpoint.d.ts +14 -0
- package/dist/runtime/query/checkpoint.d.ts.map +1 -1
- package/dist/runtime/query/checkpoint.js +82 -1
- package/dist/runtime/query/checkpoint.js.map +1 -1
- package/dist/runtime/query/executor.d.ts +8 -3
- package/dist/runtime/query/executor.d.ts.map +1 -1
- package/dist/runtime/query/executor.js +94 -30
- package/dist/runtime/query/executor.js.map +1 -1
- package/dist/runtime/query/index.d.ts +7 -8
- package/dist/runtime/query/index.d.ts.map +1 -1
- package/dist/runtime/query/index.js +55 -7
- package/dist/runtime/query/index.js.map +1 -1
- package/dist/runtime/query/iteration/index.d.ts +12 -0
- package/dist/runtime/query/iteration/index.d.ts.map +1 -1
- package/dist/runtime/query/iteration/index.js +348 -38
- package/dist/runtime/query/iteration/index.js.map +1 -1
- package/dist/runtime/query/iteration/native-output.d.ts +10 -0
- package/dist/runtime/query/iteration/native-output.d.ts.map +1 -0
- package/dist/runtime/query/iteration/native-output.js +32 -0
- package/dist/runtime/query/iteration/native-output.js.map +1 -0
- package/dist/runtime/query/iteration/phases/advisory.d.ts.map +1 -1
- package/dist/runtime/query/iteration/phases/advisory.js +18 -13
- package/dist/runtime/query/iteration/phases/advisory.js.map +1 -1
- package/dist/runtime/query/iteration/phases/compaction.d.ts +2 -0
- package/dist/runtime/query/iteration/phases/compaction.d.ts.map +1 -1
- package/dist/runtime/query/iteration/phases/compaction.js +32 -11
- package/dist/runtime/query/iteration/phases/compaction.js.map +1 -1
- package/dist/runtime/query/iteration/phases/context.d.ts +9 -0
- 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 +1 -1
- package/dist/runtime/query/iteration/phases/tool-review.js.map +1 -1
- package/dist/runtime/query/iteration/phases/working-memory.d.ts +1 -1
- package/dist/runtime/query/iteration/phases/working-memory.d.ts.map +1 -1
- package/dist/runtime/query/iteration/phases/working-memory.js +23 -6
- package/dist/runtime/query/iteration/phases/working-memory.js.map +1 -1
- package/dist/runtime/query/iteration/stream-turn.d.ts.map +1 -1
- package/dist/runtime/query/iteration/stream-turn.js +12 -0
- package/dist/runtime/query/iteration/stream-turn.js.map +1 -1
- package/dist/runtime/query/observation-context.d.ts +10 -0
- package/dist/runtime/query/observation-context.d.ts.map +1 -0
- package/dist/runtime/query/observation-context.js +84 -0
- package/dist/runtime/query/observation-context.js.map +1 -0
- package/dist/runtime/query/request-context.d.ts +30 -0
- package/dist/runtime/query/request-context.d.ts.map +1 -0
- package/dist/runtime/query/request-context.js +76 -0
- package/dist/runtime/query/request-context.js.map +1 -0
- package/dist/runtime/query/request-rich-content.d.ts.map +1 -1
- package/dist/runtime/query/request-rich-content.js +6 -3
- package/dist/runtime/query/request-rich-content.js.map +1 -1
- package/dist/runtime/query/review-policy.d.ts +3 -0
- package/dist/runtime/query/review-policy.d.ts.map +1 -1
- package/dist/runtime/query/review-policy.js +4 -1
- package/dist/runtime/query/review-policy.js.map +1 -1
- package/dist/runtime/query/steering.d.ts +6 -2
- package/dist/runtime/query/steering.d.ts.map +1 -1
- package/dist/runtime/query/steering.js +17 -2
- package/dist/runtime/query/steering.js.map +1 -1
- package/dist/runtime/query/tool-call-budget.d.ts +19 -0
- package/dist/runtime/query/tool-call-budget.d.ts.map +1 -0
- package/dist/runtime/query/tool-call-budget.js +110 -0
- package/dist/runtime/query/tool-call-budget.js.map +1 -0
- package/dist/runtime/query/tooling.d.ts +3 -0
- package/dist/runtime/query/tooling.d.ts.map +1 -1
- package/dist/runtime/query/tooling.js +5 -0
- package/dist/runtime/query/tooling.js.map +1 -1
- package/dist/sandbox/file-walk-program.d.ts.map +1 -1
- package/dist/sandbox/file-walk-program.js +8 -0
- package/dist/sandbox/file-walk-program.js.map +1 -1
- package/dist/sandbox/file-walk.d.ts.map +1 -1
- package/dist/sandbox/file-walk.js +9 -0
- package/dist/sandbox/file-walk.js.map +1 -1
- package/dist/scheduler/completion-inbox.d.ts.map +1 -1
- package/dist/scheduler/completion-inbox.js +3 -0
- package/dist/scheduler/completion-inbox.js.map +1 -1
- package/dist/scheduler/local.d.ts.map +1 -1
- package/dist/scheduler/local.js +1 -0
- package/dist/scheduler/local.js.map +1 -1
- package/dist/session/handoff/capacity.d.ts +2 -2
- package/dist/session/handoff/capacity.d.ts.map +1 -1
- package/dist/session/handoff/capacity.js +3 -2
- package/dist/session/handoff/capacity.js.map +1 -1
- package/dist/store/memory/disk.d.ts +6 -2
- package/dist/store/memory/disk.d.ts.map +1 -1
- package/dist/store/memory/disk.js +42 -25
- package/dist/store/memory/disk.js.map +1 -1
- package/dist/store/memory/index.d.ts +4 -0
- package/dist/store/memory/index.d.ts.map +1 -1
- package/dist/store/memory/index.js +55 -19
- package/dist/store/memory/index.js.map +1 -1
- package/dist/store/memory/memory.d.ts +3 -2
- package/dist/store/memory/memory.d.ts.map +1 -1
- package/dist/store/memory/memory.js +11 -2
- package/dist/store/memory/memory.js.map +1 -1
- package/dist/store/memory/operation-lock.d.ts +11 -0
- package/dist/store/memory/operation-lock.d.ts.map +1 -0
- package/dist/store/memory/operation-lock.js +94 -0
- package/dist/store/memory/operation-lock.js.map +1 -0
- package/dist/store/run/token-budget-disk.js +3 -0
- package/dist/store/run/token-budget-disk.js.map +1 -1
- package/dist/tools/builtins/computer-use.d.ts.map +1 -1
- package/dist/tools/builtins/computer-use.js +60 -10
- package/dist/tools/builtins/computer-use.js.map +1 -1
- package/dist/tools/builtins/edit.d.ts.map +1 -1
- package/dist/tools/builtins/edit.js +12 -26
- package/dist/tools/builtins/edit.js.map +1 -1
- package/dist/tools/builtins/file-write-result.d.ts +4 -0
- package/dist/tools/builtins/file-write-result.d.ts.map +1 -0
- package/dist/tools/builtins/file-write-result.js +72 -0
- package/dist/tools/builtins/file-write-result.js.map +1 -0
- package/dist/tools/builtins/glob.d.ts.map +1 -1
- package/dist/tools/builtins/glob.js +8 -1
- package/dist/tools/builtins/glob.js.map +1 -1
- package/dist/tools/builtins/grep.d.ts.map +1 -1
- package/dist/tools/builtins/grep.js +10 -0
- package/dist/tools/builtins/grep.js.map +1 -1
- package/dist/tools/builtins/job.d.ts.map +1 -1
- package/dist/tools/builtins/job.js +6 -0
- package/dist/tools/builtins/job.js.map +1 -1
- package/dist/tools/builtins/read-file.d.ts.map +1 -1
- package/dist/tools/builtins/read-file.js +10 -0
- package/dist/tools/builtins/read-file.js.map +1 -1
- package/dist/tools/builtins/run-code.d.ts +6 -0
- package/dist/tools/builtins/run-code.d.ts.map +1 -1
- package/dist/tools/builtins/run-code.js +15 -4
- package/dist/tools/builtins/run-code.js.map +1 -1
- package/dist/tools/builtins/search-tools.d.ts.map +1 -1
- package/dist/tools/builtins/search-tools.js +14 -2
- package/dist/tools/builtins/search-tools.js.map +1 -1
- package/dist/tools/builtins/write-file.d.ts.map +1 -1
- package/dist/tools/builtins/write-file.js +30 -44
- package/dist/tools/builtins/write-file.js.map +1 -1
- package/dist/tools/defineTool.d.ts +2 -0
- package/dist/tools/defineTool.d.ts.map +1 -1
- package/dist/tools/defineTool.js +3 -0
- package/dist/tools/defineTool.js.map +1 -1
- package/dist/tools/file-read-tracker.d.ts +4 -0
- package/dist/tools/file-read-tracker.d.ts.map +1 -0
- package/dist/tools/file-read-tracker.js +16 -0
- package/dist/tools/file-read-tracker.js.map +1 -0
- package/dist/tools/memory/delete.d.ts +4 -0
- package/dist/tools/memory/delete.d.ts.map +1 -0
- package/dist/tools/memory/delete.js +26 -0
- package/dist/tools/memory/delete.js.map +1 -0
- package/dist/tools/memory/index.d.ts +2 -0
- package/dist/tools/memory/index.d.ts.map +1 -1
- package/dist/tools/memory/index.js +6 -0
- package/dist/tools/memory/index.js.map +1 -1
- package/dist/tools/memory/save.d.ts.map +1 -1
- package/dist/tools/memory/save.js +3 -2
- package/dist/tools/memory/save.js.map +1 -1
- package/dist/tools/memory/search.d.ts.map +1 -1
- package/dist/tools/memory/search.js +12 -5
- package/dist/tools/memory/search.js.map +1 -1
- package/dist/tools/memory/update.d.ts +4 -0
- package/dist/tools/memory/update.d.ts.map +1 -0
- package/dist/tools/memory/update.js +47 -0
- package/dist/tools/memory/update.js.map +1 -0
- package/dist/tools/task/list.js +2 -2
- package/dist/tools/task/list.js.map +1 -1
- package/dist/types/agent/scheduler.d.ts +5 -0
- package/dist/types/agent/scheduler.d.ts.map +1 -1
- package/dist/types/agent/task.d.ts +10 -0
- package/dist/types/agent/task.d.ts.map +1 -1
- package/dist/types/computer-use/index.d.ts +6 -0
- package/dist/types/computer-use/index.d.ts.map +1 -1
- package/dist/types/computer-use/index.js.map +1 -1
- package/dist/types/errors/catalog.js +1 -1
- package/dist/types/errors/catalog.js.map +1 -1
- package/dist/types/hitl/index.d.ts +11 -1
- package/dist/types/hitl/index.d.ts.map +1 -1
- package/dist/types/hitl/index.js.map +1 -1
- package/dist/types/memory/index.d.ts +14 -1
- package/dist/types/memory/index.d.ts.map +1 -1
- package/dist/types/plugin/index.d.ts +7 -0
- package/dist/types/plugin/index.d.ts.map +1 -1
- package/dist/types/plugin/index.js.map +1 -1
- package/dist/types/project/entity.d.ts +1 -0
- package/dist/types/project/entity.d.ts.map +1 -1
- package/dist/types/provider/chat.d.ts +4 -0
- package/dist/types/provider/chat.d.ts.map +1 -1
- package/dist/types/provider/config.d.ts +4 -0
- package/dist/types/provider/config.d.ts.map +1 -1
- package/dist/types/provider/model.d.ts +4 -0
- package/dist/types/provider/model.d.ts.map +1 -1
- package/dist/types/provider/stream.d.ts +6 -0
- package/dist/types/provider/stream.d.ts.map +1 -1
- package/dist/types/run/answer-review.d.ts +2 -0
- package/dist/types/run/answer-review.d.ts.map +1 -1
- package/dist/types/run/config.d.ts +2 -0
- package/dist/types/run/config.d.ts.map +1 -1
- package/dist/types/run/events.d.ts +19 -0
- 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 +19 -1
- package/dist/types/run/prepare-step.d.ts.map +1 -1
- package/dist/types/sandbox/index.d.ts +1 -0
- package/dist/types/sandbox/index.d.ts.map +1 -1
- package/dist/types/sandbox/index.js.map +1 -1
- package/dist/types/structured-output/index.d.ts +8 -2
- package/dist/types/structured-output/index.d.ts.map +1 -1
- package/dist/types/tool/index.d.ts +15 -0
- package/dist/types/tool/index.d.ts.map +1 -1
- package/dist/types/tool/index.js.map +1 -1
- package/dist/types/tool/presentation.d.ts +4 -0
- package/dist/types/tool/presentation.d.ts.map +1 -1
- package/dist/utils/json-snapshot.d.ts +3 -0
- package/dist/utils/json-snapshot.d.ts.map +1 -0
- package/dist/utils/json-snapshot.js +79 -0
- package/dist/utils/json-snapshot.js.map +1 -0
- package/package.json +4 -2
- package/src/bridge/a2a/mapper.ts +4 -0
- package/src/bridge/sse/mapper.ts +16 -1
- package/src/compaction/extractor.ts +21 -8
- package/src/compaction/manager.ts +11 -1
- package/src/compaction/verifier.ts +80 -18
- package/src/config/runtime.ts +2 -0
- package/src/contracts/api.ts +1 -0
- package/src/eval/harness-verification.ts +270 -0
- package/src/eval/index.ts +10 -0
- package/src/execution/code-runtime/json-value.ts +82 -0
- package/src/execution/code-runtime/worker-program.ts +239 -0
- package/src/execution/code-runtime/worker.ts +164 -111
- package/src/manager/agent/lifecycle.ts +352 -54
- package/src/manager/run/persistence.ts +7 -0
- package/src/prompt/coding-agent-doctrine.ts +11 -5
- package/src/provider/capabilities.ts +41 -1
- package/src/provider/fallback.ts +9 -2
- package/src/public-runtime.ts +6 -0
- package/src/public-tools.ts +7 -1
- package/src/public-types.ts +7 -0
- package/src/registry/tool/execute.ts +17 -79
- package/src/run/command-gate.ts +61 -13
- package/src/run/index.ts +2 -0
- package/src/run/memory-promoter.ts +32 -40
- package/src/run/memory-recall.ts +254 -0
- package/src/run/reporter.ts +2 -0
- package/src/run/token-budget.ts +55 -14
- package/src/run/workspace-fingerprint.ts +17 -8
- package/src/runtime/query/checkpoint.ts +96 -2
- package/src/runtime/query/executor.ts +100 -29
- package/src/runtime/query/index.ts +76 -16
- package/src/runtime/query/iteration/index.ts +405 -46
- package/src/runtime/query/iteration/native-output.ts +35 -0
- package/src/runtime/query/iteration/phases/advisory.ts +21 -11
- package/src/runtime/query/iteration/phases/compaction.ts +36 -14
- package/src/runtime/query/iteration/phases/context.ts +9 -0
- package/src/runtime/query/iteration/phases/tool-review.ts +5 -1
- package/src/runtime/query/iteration/phases/working-memory.ts +23 -5
- package/src/runtime/query/iteration/stream-turn.ts +15 -0
- package/src/runtime/query/observation-context.ts +86 -0
- package/src/runtime/query/request-context.ts +103 -0
- package/src/runtime/query/request-rich-content.ts +8 -3
- package/src/runtime/query/review-policy.ts +7 -1
- package/src/runtime/query/steering.ts +19 -2
- package/src/runtime/query/tool-call-budget.ts +115 -0
- package/src/runtime/query/tooling.ts +8 -0
- package/src/sandbox/file-walk-program.ts +8 -0
- package/src/sandbox/file-walk.ts +9 -0
- package/src/scheduler/completion-inbox.ts +3 -0
- package/src/scheduler/local.ts +1 -0
- package/src/session/handoff/capacity.ts +7 -3
- package/src/store/memory/disk.ts +52 -30
- package/src/store/memory/index.ts +75 -27
- package/src/store/memory/memory.ts +18 -6
- package/src/store/memory/operation-lock.ts +99 -0
- package/src/store/run/token-budget-disk.ts +3 -0
- package/src/tools/builtins/computer-use.ts +61 -7
- package/src/tools/builtins/edit.ts +12 -27
- package/src/tools/builtins/file-write-result.ts +84 -0
- package/src/tools/builtins/glob.ts +7 -1
- package/src/tools/builtins/grep.ts +10 -0
- package/src/tools/builtins/job.ts +8 -0
- package/src/tools/builtins/read-file.ts +10 -0
- package/src/tools/builtins/run-code.ts +24 -5
- package/src/tools/builtins/search-tools.ts +18 -3
- package/src/tools/builtins/write-file.ts +39 -44
- package/src/tools/defineTool.ts +5 -0
- package/src/tools/file-read-tracker.ts +16 -0
- package/src/tools/memory/delete.ts +29 -0
- package/src/tools/memory/index.ts +6 -0
- package/src/tools/memory/save.ts +4 -2
- package/src/tools/memory/search.ts +12 -5
- package/src/tools/memory/update.ts +50 -0
- package/src/tools/task/list.ts +2 -2
- package/src/types/agent/scheduler.ts +6 -0
- package/src/types/agent/task.ts +13 -0
- package/src/types/computer-use/index.ts +6 -0
- package/src/types/errors/catalog.ts +1 -1
- package/src/types/hitl/index.ts +11 -1
- package/src/types/memory/index.ts +16 -1
- package/src/types/plugin/index.ts +10 -0
- package/src/types/project/entity.ts +1 -0
- package/src/types/provider/chat.ts +2 -0
- package/src/types/provider/config.ts +4 -0
- package/src/types/provider/model.ts +4 -0
- package/src/types/provider/stream.ts +7 -0
- package/src/types/run/answer-review.ts +2 -0
- package/src/types/run/config.ts +2 -0
- package/src/types/run/events.ts +20 -0
- package/src/types/run/prepare-step.ts +19 -1
- package/src/types/sandbox/index.ts +1 -0
- package/src/types/structured-output/index.ts +15 -2
- package/src/types/tool/index.ts +16 -0
- package/src/types/tool/presentation.ts +4 -0
- package/src/utils/json-snapshot.ts +76 -0
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { type Span, SpanStatusCode } from '@opentelemetry/api'
|
|
2
2
|
import { resolveContextWindow } from '../../../compaction/context-window.js'
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
extractFromAssistantMessage,
|
|
5
|
+
extractFromUserMessage,
|
|
6
|
+
} from '../../../compaction/extractor.js'
|
|
7
|
+
import { estimateMessageTokens } from '../../../compaction/token-estimate.js'
|
|
4
8
|
import { AUTO_CONTINUATION_USER_MESSAGE } from '../../../constants/continuation.js'
|
|
5
9
|
import {
|
|
6
10
|
DEFAULT_STRUCTURED_OUTPUT_RETRIES,
|
|
@@ -9,6 +13,7 @@ import {
|
|
|
9
13
|
import { renderSkillsSection } from '../../../persona/assembler.js'
|
|
10
14
|
import { resolveProviderCapabilities } from '../../../provider/capabilities.js'
|
|
11
15
|
import { collectChatCompletion } from '../../../provider/collect-chat-completion.js'
|
|
16
|
+
import { renderToolSchema } from '../../../registry/tool/schema.js'
|
|
12
17
|
import { formatCompletionNotification } from '../../../scheduler/completion-inbox.js'
|
|
13
18
|
import {
|
|
14
19
|
GENAI,
|
|
@@ -24,6 +29,7 @@ import { NamzuError } from '../../../types/errors/index.js'
|
|
|
24
29
|
import type { MessageId } from '../../../types/ids/index.js'
|
|
25
30
|
import {
|
|
26
31
|
type Message,
|
|
32
|
+
type UserMessage,
|
|
27
33
|
createAssistantMessage,
|
|
28
34
|
createRuntimeContextMessage,
|
|
29
35
|
createSystemMessage,
|
|
@@ -33,6 +39,7 @@ import { classifyProviderError } from '../../../types/provider/errors.js'
|
|
|
33
39
|
import type { ChatCompletionResponse } from '../../../types/provider/index.js'
|
|
34
40
|
import type { AnswerReview } from '../../../types/run/answer-review.js'
|
|
35
41
|
import type {
|
|
42
|
+
PrepareStepContext,
|
|
36
43
|
PrepareStepResult,
|
|
37
44
|
RunEvent,
|
|
38
45
|
StepFailure,
|
|
@@ -47,17 +54,29 @@ import { toErrorMessage } from '../../../utils/error.js'
|
|
|
47
54
|
import { stableDigest } from '../../../utils/hash.js'
|
|
48
55
|
import { generateMessageId } from '../../../utils/id.js'
|
|
49
56
|
import type { ToolCallOutcome } from '../executor.js'
|
|
57
|
+
import { projectObservationContext } from '../observation-context.js'
|
|
50
58
|
import { applyLifecycleHookResults } from '../plugin-hooks.js'
|
|
59
|
+
import {
|
|
60
|
+
type RequestContextSnapshot,
|
|
61
|
+
diffRequestContext,
|
|
62
|
+
snapshotRequestContext,
|
|
63
|
+
} from '../request-context.js'
|
|
51
64
|
import {
|
|
52
65
|
DEFAULT_MAX_REQUEST_RICH_CONTENT_BYTES,
|
|
53
66
|
type RequestImageIdentity,
|
|
54
67
|
markProviderRejectedImage,
|
|
55
68
|
projectRequestRichContent,
|
|
56
69
|
} from '../request-rich-content.js'
|
|
57
|
-
import { formatSteeringNote } from '../steering.js'
|
|
70
|
+
import { formatSteeringNote, isOperatorUserMessage } from '../steering.js'
|
|
71
|
+
import { parseNativeCandidate } from './native-output.js'
|
|
58
72
|
import { runAdvisoryPhase } from './phases/advisory.js'
|
|
59
73
|
import { runIterationCheckpoint } from './phases/checkpoint.js'
|
|
60
|
-
import {
|
|
74
|
+
import {
|
|
75
|
+
activeContextWindow,
|
|
76
|
+
measureContext,
|
|
77
|
+
relieveOverflow,
|
|
78
|
+
runCompactionCheck,
|
|
79
|
+
} from './phases/compaction.js'
|
|
61
80
|
import type { IterationContext } from './phases/index.js'
|
|
62
81
|
import { runPlanGate } from './phases/plan.js'
|
|
63
82
|
import { runToolReview } from './phases/tool-review.js'
|
|
@@ -151,6 +170,14 @@ export class IterationOrchestrator {
|
|
|
151
170
|
* one process must not suppress each other's first envelope.
|
|
152
171
|
*/
|
|
153
172
|
private lastEnvelopeKey: string | undefined
|
|
173
|
+
private previousRequestContext: RequestContextSnapshot | undefined
|
|
174
|
+
|
|
175
|
+
private projectObservations(messages: Message[]): Message[] {
|
|
176
|
+
const config = this.ctx.compactionConfig
|
|
177
|
+
return config && config.strategy !== 'disabled' && config.deduplicateObservations !== false
|
|
178
|
+
? projectObservationContext(messages, this.ctx.tools, config.preserveToolResultsFrom)
|
|
179
|
+
: messages
|
|
180
|
+
}
|
|
154
181
|
/** Rich tool blocks already reported; durable history is scanned every turn. */
|
|
155
182
|
private readonly warnedRichToolResults = new Set<string>()
|
|
156
183
|
/**
|
|
@@ -168,9 +195,34 @@ export class IterationOrchestrator {
|
|
|
168
195
|
* sets it.
|
|
169
196
|
*/
|
|
170
197
|
private stopDeferredForOutstandingWork = false
|
|
198
|
+
/** One current input, independent of the compactable history array. */
|
|
199
|
+
private latestUserMessage: UserMessage | undefined
|
|
171
200
|
|
|
172
201
|
constructor(ctx: IterationContext) {
|
|
173
|
-
this.ctx =
|
|
202
|
+
this.ctx = {
|
|
203
|
+
...ctx,
|
|
204
|
+
onSteeringDelivered: (text) => {
|
|
205
|
+
this.rememberUserMessage(createRuntimeContextMessage(text, 'steering'))
|
|
206
|
+
},
|
|
207
|
+
}
|
|
208
|
+
ctx.checkpointMgr.setLatestUserMessageSource(() => this.latestUserMessage)
|
|
209
|
+
ctx.checkpointMgr.setStructuredReviewAttemptsSource?.(() => this.structuredReviewAttempts)
|
|
210
|
+
ctx.checkpointMgr.setNativeStructuredAttemptsSource?.(() => this.nativeStructuredAttempts)
|
|
211
|
+
if (ctx.structuredOutput?.mode === 'native') {
|
|
212
|
+
const limit = ctx.structuredOutput.maxRetries
|
|
213
|
+
if (limit !== undefined && (!Number.isSafeInteger(limit) || limit < 0))
|
|
214
|
+
throw new RangeError(
|
|
215
|
+
'Native structuredOutput.maxRetries must be a nonnegative safe integer',
|
|
216
|
+
)
|
|
217
|
+
}
|
|
218
|
+
if (
|
|
219
|
+
ctx.structuredOutput?.mode !== undefined &&
|
|
220
|
+
!['tool', 'native'].includes(ctx.structuredOutput.mode)
|
|
221
|
+
)
|
|
222
|
+
throw new RangeError('Unknown structuredOutput.mode')
|
|
223
|
+
const maxReviews = ctx.structuredOutput?.maxReviews
|
|
224
|
+
if (maxReviews !== undefined && (!Number.isSafeInteger(maxReviews) || maxReviews < 0))
|
|
225
|
+
throw new RangeError('structuredOutput.maxReviews must be a nonnegative safe integer')
|
|
174
226
|
}
|
|
175
227
|
|
|
176
228
|
/**
|
|
@@ -252,6 +304,17 @@ export class IterationOrchestrator {
|
|
|
252
304
|
const { runConfig, runMgr } = this.ctx
|
|
253
305
|
const { model } = runConfig
|
|
254
306
|
const tracer = getTracer()
|
|
307
|
+
// Resume hydration happens after construction, before the loop starts.
|
|
308
|
+
this.latestUserMessage = this.ctx.checkpointMgr.restoredLatestUserMessage
|
|
309
|
+
this.structuredReviewAttempts = this.ctx.checkpointMgr.restoredStructuredReviewAttempts ?? 0
|
|
310
|
+
this.nativeStructuredAttempts = this.ctx.checkpointMgr.restoredNativeStructuredAttempts ?? 0
|
|
311
|
+
if (!this.latestUserMessage) {
|
|
312
|
+
for (const message of runMgr.messages) this.rememberUserMessage(message, false)
|
|
313
|
+
}
|
|
314
|
+
// The restored field can outlive the historical message it describes.
|
|
315
|
+
// Only known post-checkpoint arrivals may supersede it, never an old
|
|
316
|
+
// retained user turn encountered while scanning restored history.
|
|
317
|
+
for (const message of this.ctx.resumedInput ?? []) this.rememberUserMessage(message)
|
|
255
318
|
|
|
256
319
|
// One context-overflow relief per *stuck point*, not per run.
|
|
257
320
|
//
|
|
@@ -278,6 +341,26 @@ export class IterationOrchestrator {
|
|
|
278
341
|
// no post-loop block reaches.
|
|
279
342
|
try {
|
|
280
343
|
while (true) {
|
|
344
|
+
if (this.ctx.abortController.signal.aborted) {
|
|
345
|
+
runMgr.setStopReason('cancelled')
|
|
346
|
+
runMgr.markCancelled()
|
|
347
|
+
break
|
|
348
|
+
}
|
|
349
|
+
if (
|
|
350
|
+
this.ctx.structuredOutput?.mode === 'native' &&
|
|
351
|
+
this.nativeStructuredAttempts > this.structuredOutputRetryLimit()
|
|
352
|
+
) {
|
|
353
|
+
runMgr.setStopReason('structured_output_failed')
|
|
354
|
+
break
|
|
355
|
+
}
|
|
356
|
+
if (
|
|
357
|
+
this.ctx.structuredOutput?.review &&
|
|
358
|
+
this.structuredReviewAttempts >
|
|
359
|
+
(this.ctx.structuredOutput.maxReviews ?? DEFAULT_ANSWER_REVIEW_LIMIT)
|
|
360
|
+
) {
|
|
361
|
+
runMgr.setStopReason('answer_rejected')
|
|
362
|
+
break
|
|
363
|
+
}
|
|
281
364
|
// Read AND clear, in that order, in this one place.
|
|
282
365
|
//
|
|
283
366
|
// The flag is set by the previous iteration and read by this
|
|
@@ -325,6 +408,14 @@ export class IterationOrchestrator {
|
|
|
325
408
|
// run and been paid for; this is the seam a host with a live
|
|
326
409
|
// rate limit or a revoked tenant actually needs.
|
|
327
410
|
const veto = await this.beforeStep(runMgr.currentIteration + 1)
|
|
411
|
+
// The hook may settle because its run signal was aborted. Stop
|
|
412
|
+
// before interpreting that settlement as a policy refusal or
|
|
413
|
+
// counting an iteration that will never reach the provider.
|
|
414
|
+
if (this.ctx.abortController.signal.aborted) {
|
|
415
|
+
runMgr.setStopReason('cancelled')
|
|
416
|
+
runMgr.markCancelled()
|
|
417
|
+
break
|
|
418
|
+
}
|
|
328
419
|
if (veto) {
|
|
329
420
|
// Namespaced. The un-namespaced keys elsewhere in this file are
|
|
330
421
|
// the frozen inventory LOG-22 exists to drain; a new call site
|
|
@@ -431,10 +522,6 @@ export class IterationOrchestrator {
|
|
|
431
522
|
// compaction preserves). No-op when no provider is configured.
|
|
432
523
|
await refreshWorkingMemory(this.ctx)
|
|
433
524
|
await runCompactionCheck(this.ctx)
|
|
434
|
-
// A context edit is a host-visible state transition, not a prelude
|
|
435
|
-
// whose events may wait behind the next network call. In particular,
|
|
436
|
-
// a slow or failing provider must not leave the host displaying the
|
|
437
|
-
// pre-compaction context after Run.messages already shrank.
|
|
438
525
|
yield* this.ctx.drainPending()
|
|
439
526
|
|
|
440
527
|
// Cache discipline: keep the tools param byte-stable even on the
|
|
@@ -452,10 +539,25 @@ export class IterationOrchestrator {
|
|
|
452
539
|
// Shape this step before calling the model. `stopWhen` decides
|
|
453
540
|
// whether to keep going; this decides HOW. No-op when the host
|
|
454
541
|
// supplied no hook.
|
|
542
|
+
const contextModelBeforePreparation = this.ctx.contextModel ?? model
|
|
455
543
|
const step = await this.prepareStep(iterationNum)
|
|
544
|
+
stepModel = step.model ?? model
|
|
545
|
+
await this.selectContextModel(stepModel)
|
|
546
|
+
// Preserve post-compaction preparation/recall semantics. A changed
|
|
547
|
+
// model needs a second check against its own window; never replay
|
|
548
|
+
// host preparation effects merely to rebuild its request guidance.
|
|
549
|
+
if (stepModel !== contextModelBeforePreparation) await runCompactionCheck(this.ctx)
|
|
550
|
+
// Publish context edits before entering a possibly slow provider.
|
|
551
|
+
yield* this.ctx.drainPending()
|
|
456
552
|
|
|
457
553
|
const stepAllowedTools = step.allowedTools ?? this.ctx.allowedTools
|
|
458
|
-
const llmTools = this.ctx.tools
|
|
554
|
+
const llmTools = this.ctx.tools
|
|
555
|
+
.toLLMTools(stepAllowedTools)
|
|
556
|
+
.filter(
|
|
557
|
+
(tool) =>
|
|
558
|
+
this.ctx.structuredOutput?.mode !== 'native' ||
|
|
559
|
+
tool.function.name !== STRUCTURED_OUTPUT_TOOL_NAME,
|
|
560
|
+
)
|
|
459
561
|
// The same list the request was built from now also bounds what
|
|
460
562
|
// may run. Narrowing only the request left the restriction
|
|
461
563
|
// presentational — the model was shown fewer tools and could
|
|
@@ -526,7 +628,7 @@ export class IterationOrchestrator {
|
|
|
526
628
|
? [...baseMessages, createSystemMessage(stepPreamble)]
|
|
527
629
|
: [...baseMessages]
|
|
528
630
|
const messages = projectRequestRichContent(
|
|
529
|
-
requestHistory,
|
|
631
|
+
this.projectObservations(requestHistory),
|
|
530
632
|
this.ctx.runConfig.maxRequestRichContentBytes ?? DEFAULT_MAX_REQUEST_RICH_CONTENT_BYTES,
|
|
531
633
|
)
|
|
532
634
|
await this.reportUnsupportedToolResults(messages)
|
|
@@ -576,6 +678,16 @@ export class IterationOrchestrator {
|
|
|
576
678
|
}
|
|
577
679
|
|
|
578
680
|
if (this.ctx.pluginManager) {
|
|
681
|
+
const snapshot = snapshotRequestContext(messages)
|
|
682
|
+
const context = Object.freeze({
|
|
683
|
+
snapshot,
|
|
684
|
+
...(this.previousRequestContext
|
|
685
|
+
? {
|
|
686
|
+
change: diffRequestContext(this.previousRequestContext, snapshot),
|
|
687
|
+
}
|
|
688
|
+
: {}),
|
|
689
|
+
})
|
|
690
|
+
this.previousRequestContext = snapshot
|
|
579
691
|
const hookResults = await this.ctx.pluginManager.executeHooks(
|
|
580
692
|
'pre_llm_call',
|
|
581
693
|
{
|
|
@@ -585,6 +697,7 @@ export class IterationOrchestrator {
|
|
|
585
697
|
// Built inside the guard: a run with no plugins installed
|
|
586
698
|
// pays nothing for a projection nobody reads.
|
|
587
699
|
request: Object.freeze({
|
|
700
|
+
context,
|
|
588
701
|
model: stepModel,
|
|
589
702
|
// Copied per turn, not handed over live: these are the
|
|
590
703
|
// run's own message objects, and a hook writing into
|
|
@@ -632,6 +745,18 @@ export class IterationOrchestrator {
|
|
|
632
745
|
this.ctx.provider,
|
|
633
746
|
{
|
|
634
747
|
model: stepModel,
|
|
748
|
+
...(this.ctx.structuredOutput?.mode === 'native'
|
|
749
|
+
? {
|
|
750
|
+
responseFormat: {
|
|
751
|
+
type: 'json_schema' as const,
|
|
752
|
+
json_schema: {
|
|
753
|
+
name: 'structured_output',
|
|
754
|
+
schema: renderToolSchema(this.ctx.structuredOutput.schema),
|
|
755
|
+
strict: true,
|
|
756
|
+
},
|
|
757
|
+
},
|
|
758
|
+
}
|
|
759
|
+
: {}),
|
|
635
760
|
providerRoute: requestedRoute,
|
|
636
761
|
messages,
|
|
637
762
|
tools: llmTools.length > 0 ? llmTools : undefined,
|
|
@@ -652,6 +777,7 @@ export class IterationOrchestrator {
|
|
|
652
777
|
cacheControl: { type: 'auto' },
|
|
653
778
|
...(runConfig.thinking ? { thinking: runConfig.thinking } : {}),
|
|
654
779
|
...(runConfig.effort ? { effort: runConfig.effort } : {}),
|
|
780
|
+
...(!forceFinalize && runConfig.webSearch ? { webSearch: runConfig.webSearch } : {}),
|
|
655
781
|
// Thread the run abort into the model call so a Stop tears the
|
|
656
782
|
// in-flight turn down (provider passes it to fetch; the consumer
|
|
657
783
|
// also races it). Inert when never aborted.
|
|
@@ -771,11 +897,7 @@ export class IterationOrchestrator {
|
|
|
771
897
|
const contextFigures = this.ctx.compactionConfig
|
|
772
898
|
? (() => {
|
|
773
899
|
const measured = measureContext(this.ctx)
|
|
774
|
-
const window =
|
|
775
|
-
this.ctx.compactionConfig?.contextWindowTokens,
|
|
776
|
-
runConfig.model,
|
|
777
|
-
this.ctx.providerContextWindow,
|
|
778
|
-
)
|
|
900
|
+
const window = activeContextWindow(this.ctx)
|
|
779
901
|
return {
|
|
780
902
|
contextTokens: measured.tokens,
|
|
781
903
|
contextMeasuredBy: measured.source,
|
|
@@ -932,6 +1054,70 @@ export class IterationOrchestrator {
|
|
|
932
1054
|
costBefore,
|
|
933
1055
|
})
|
|
934
1056
|
|
|
1057
|
+
if (this.ctx.structuredOutput?.mode === 'native') {
|
|
1058
|
+
const candidate = await parseNativeCandidate(
|
|
1059
|
+
this.ctx.structuredOutput.schema,
|
|
1060
|
+
response,
|
|
1061
|
+
this.ctx.abortController.signal,
|
|
1062
|
+
)
|
|
1063
|
+
let outcome: 'accepted' | 'retry' | 'exhausted' | 'cancelled'
|
|
1064
|
+
if (candidate.success) outcome = await this.reviewStructuredOutput(candidate.value)
|
|
1065
|
+
else {
|
|
1066
|
+
this.nativeStructuredAttempts++
|
|
1067
|
+
runMgr.pushMessage(
|
|
1068
|
+
createRuntimeContextMessage(
|
|
1069
|
+
'Return a complete JSON value matching the supplied response schema. Do not continue a partial JSON fragment.',
|
|
1070
|
+
'structured-output',
|
|
1071
|
+
),
|
|
1072
|
+
)
|
|
1073
|
+
const checkpoint = await this.ctx.checkpointMgr.create(runMgr, iterationNum)
|
|
1074
|
+
await this.ctx.emitEvent({
|
|
1075
|
+
type: 'checkpoint_created',
|
|
1076
|
+
runId: runMgr.id,
|
|
1077
|
+
checkpointId: checkpoint.id,
|
|
1078
|
+
iteration: iterationNum,
|
|
1079
|
+
})
|
|
1080
|
+
outcome =
|
|
1081
|
+
this.nativeStructuredAttempts > this.structuredOutputRetryLimit()
|
|
1082
|
+
? 'exhausted'
|
|
1083
|
+
: 'retry'
|
|
1084
|
+
}
|
|
1085
|
+
await this.ctx.emitEvent({
|
|
1086
|
+
type: 'iteration_completed',
|
|
1087
|
+
runId: runMgr.id,
|
|
1088
|
+
iteration: iterationNum,
|
|
1089
|
+
hasToolCalls: false,
|
|
1090
|
+
})
|
|
1091
|
+
yield* this.ctx.drainPending()
|
|
1092
|
+
if (this.ctx.abortController.signal.aborted || outcome === 'cancelled') {
|
|
1093
|
+
runMgr.setStopReason('cancelled')
|
|
1094
|
+
runMgr.markCancelled()
|
|
1095
|
+
break
|
|
1096
|
+
}
|
|
1097
|
+
if (outcome === 'accepted') {
|
|
1098
|
+
if (!forceFinalize) {
|
|
1099
|
+
const changed = yield* this.holdForOutstandingWork(iterationNum, false)
|
|
1100
|
+
const inbound = this.deliverInbound()
|
|
1101
|
+
if (changed || inbound > 0) continue
|
|
1102
|
+
}
|
|
1103
|
+
if (this.ctx.abortController.signal.aborted) {
|
|
1104
|
+
runMgr.setStopReason('cancelled')
|
|
1105
|
+
runMgr.markCancelled()
|
|
1106
|
+
break
|
|
1107
|
+
}
|
|
1108
|
+
this.publishStructuredOutput()
|
|
1109
|
+
runMgr.setStopReason('end_turn')
|
|
1110
|
+
break
|
|
1111
|
+
}
|
|
1112
|
+
if (outcome === 'exhausted') {
|
|
1113
|
+
runMgr.setStopReason(
|
|
1114
|
+
candidate.success ? 'answer_rejected' : 'structured_output_failed',
|
|
1115
|
+
)
|
|
1116
|
+
break
|
|
1117
|
+
}
|
|
1118
|
+
continue
|
|
1119
|
+
}
|
|
1120
|
+
|
|
935
1121
|
const hasContent =
|
|
936
1122
|
response.message.content !== null && response.message.content.length > 0
|
|
937
1123
|
|
|
@@ -1022,6 +1208,11 @@ export class IterationOrchestrator {
|
|
|
1022
1208
|
// a loud stop rather than a loop.
|
|
1023
1209
|
if (!forceFinalize && this.ctx.reviewAnswer) {
|
|
1024
1210
|
const review = await this.reviewAnswer(response.message.content ?? '')
|
|
1211
|
+
if (this.ctx.abortController.signal.aborted) {
|
|
1212
|
+
runMgr.setStopReason('cancelled')
|
|
1213
|
+
runMgr.markCancelled()
|
|
1214
|
+
break
|
|
1215
|
+
}
|
|
1025
1216
|
if (review && !review.accept) {
|
|
1026
1217
|
const attempt = ++this.answerReviewAttempts
|
|
1027
1218
|
const limit = this.ctx.maxAnswerReviews ?? DEFAULT_ANSWER_REVIEW_LIMIT
|
|
@@ -1159,12 +1350,39 @@ export class IterationOrchestrator {
|
|
|
1159
1350
|
// run ends here rather than paying for another turn whose only
|
|
1160
1351
|
// job would be to restate it — unless it shared its turn with
|
|
1161
1352
|
// other calls, which relays instead. See the method.
|
|
1162
|
-
|
|
1353
|
+
const structuredOutcome = await this.captureStructuredOutput(
|
|
1354
|
+
reviewOutcome.results,
|
|
1355
|
+
response,
|
|
1356
|
+
)
|
|
1357
|
+
if (
|
|
1358
|
+
structuredOutcome === 'retry' ||
|
|
1359
|
+
structuredOutcome === 'exhausted' ||
|
|
1360
|
+
structuredOutcome === 'cancelled'
|
|
1361
|
+
) {
|
|
1362
|
+
await this.ctx.emitEvent({
|
|
1363
|
+
type: 'iteration_completed',
|
|
1364
|
+
runId: runMgr.id,
|
|
1365
|
+
iteration: iterationNum,
|
|
1366
|
+
hasToolCalls: true,
|
|
1367
|
+
})
|
|
1368
|
+
yield* this.ctx.drainPending()
|
|
1369
|
+
if (this.ctx.abortController.signal.aborted) {
|
|
1370
|
+
runMgr.setStopReason('cancelled')
|
|
1371
|
+
runMgr.markCancelled()
|
|
1372
|
+
break
|
|
1373
|
+
}
|
|
1374
|
+
if (structuredOutcome === 'retry') continue
|
|
1375
|
+
runMgr.setStopReason(
|
|
1376
|
+
structuredOutcome === 'cancelled' ? 'cancelled' : 'answer_rejected',
|
|
1377
|
+
)
|
|
1378
|
+
if (structuredOutcome === 'cancelled') runMgr.markCancelled()
|
|
1379
|
+
break
|
|
1380
|
+
}
|
|
1381
|
+
if (structuredOutcome === 'accepted') {
|
|
1163
1382
|
this.ctx.log.info('Structured output produced — ending run', {
|
|
1164
1383
|
[NAMZU.RUN_ID]: runMgr.id,
|
|
1165
1384
|
[NAMZU.ITERATION]: iterationNum,
|
|
1166
1385
|
})
|
|
1167
|
-
runMgr.setStopReason('end_turn')
|
|
1168
1386
|
await this.ctx.emitEvent({
|
|
1169
1387
|
type: 'iteration_completed',
|
|
1170
1388
|
runId: runMgr.id,
|
|
@@ -1172,6 +1390,13 @@ export class IterationOrchestrator {
|
|
|
1172
1390
|
hasToolCalls: true,
|
|
1173
1391
|
})
|
|
1174
1392
|
yield* this.ctx.drainPending()
|
|
1393
|
+
if (this.ctx.abortController.signal.aborted) {
|
|
1394
|
+
runMgr.setStopReason('cancelled')
|
|
1395
|
+
runMgr.markCancelled()
|
|
1396
|
+
break
|
|
1397
|
+
}
|
|
1398
|
+
this.publishStructuredOutput()
|
|
1399
|
+
runMgr.setStopReason('end_turn')
|
|
1175
1400
|
break
|
|
1176
1401
|
}
|
|
1177
1402
|
|
|
@@ -1603,19 +1828,51 @@ export class IterationOrchestrator {
|
|
|
1603
1828
|
* message becomes the reason, so an operator is not left with a run
|
|
1604
1829
|
* that stopped and no account of it.
|
|
1605
1830
|
*/
|
|
1831
|
+
private stepContext(stepNumber: number, prepared: PrepareStepResult): PrepareStepContext {
|
|
1832
|
+
const model = prepared.model ?? this.ctx.runConfig.model
|
|
1833
|
+
const window = resolveContextWindow(
|
|
1834
|
+
this.ctx.compactionConfig?.contextWindowTokens,
|
|
1835
|
+
model,
|
|
1836
|
+
model === this.ctx.runConfig.model
|
|
1837
|
+
? this.ctx.providerContextWindow
|
|
1838
|
+
: model === this.ctx.contextModel
|
|
1839
|
+
? this.ctx.activeProviderContextWindow
|
|
1840
|
+
: undefined,
|
|
1841
|
+
)
|
|
1842
|
+
const skills = prepared.skills ? renderSkillsSection([...prepared.skills]) : null
|
|
1843
|
+
const preamble = [prepared.system, skills].filter(Boolean).join('\n\n')
|
|
1844
|
+
const preparedTokens = preamble ? estimateMessageTokens(createSystemMessage(preamble)) : 0
|
|
1845
|
+
const responseReserve = Math.min(
|
|
1846
|
+
prepared.maxResponseTokens ??
|
|
1847
|
+
this.ctx.runConfig.maxResponseTokens ??
|
|
1848
|
+
Math.floor(window.tokens / 4),
|
|
1849
|
+
Math.floor(window.tokens / 4),
|
|
1850
|
+
)
|
|
1851
|
+
return {
|
|
1852
|
+
runId: this.ctx.runMgr.id,
|
|
1853
|
+
stepNumber,
|
|
1854
|
+
messages: this.ctx.runMgr.messages,
|
|
1855
|
+
...(this.latestUserMessage ? { latestUserMessage: this.latestUserMessage } : {}),
|
|
1856
|
+
signal: this.ctx.abortController.signal,
|
|
1857
|
+
contextBudget: {
|
|
1858
|
+
windowTokens: window.tokens,
|
|
1859
|
+
remainingTokens: Math.max(
|
|
1860
|
+
0,
|
|
1861
|
+
Math.floor(
|
|
1862
|
+
window.tokens - measureContext(this.ctx).tokens - preparedTokens - responseReserve,
|
|
1863
|
+
),
|
|
1864
|
+
),
|
|
1865
|
+
},
|
|
1866
|
+
steps: this.steps,
|
|
1867
|
+
prepared,
|
|
1868
|
+
}
|
|
1869
|
+
}
|
|
1870
|
+
|
|
1606
1871
|
private async beforeStep(stepNumber: number): Promise<StepVeto | undefined> {
|
|
1607
1872
|
const configured = this.ctx.beforeStep
|
|
1608
1873
|
if (!configured) return undefined
|
|
1609
1874
|
try {
|
|
1610
|
-
return (
|
|
1611
|
-
(await configured({
|
|
1612
|
-
runId: this.ctx.runMgr.id,
|
|
1613
|
-
stepNumber,
|
|
1614
|
-
messages: this.ctx.runMgr.messages,
|
|
1615
|
-
steps: this.steps,
|
|
1616
|
-
prepared: {},
|
|
1617
|
-
})) ?? undefined
|
|
1618
|
-
)
|
|
1875
|
+
return (await configured(this.stepContext(stepNumber, {}))) ?? undefined
|
|
1619
1876
|
} catch (err) {
|
|
1620
1877
|
return { reason: `beforeStep threw: ${toErrorMessage(err)}` }
|
|
1621
1878
|
}
|
|
@@ -1641,14 +1898,9 @@ export class IterationOrchestrator {
|
|
|
1641
1898
|
let result: PrepareStepResult = {}
|
|
1642
1899
|
for (const stage of stages) {
|
|
1643
1900
|
try {
|
|
1644
|
-
const decided = await stage(
|
|
1645
|
-
runId: this.ctx.runMgr.id,
|
|
1646
|
-
stepNumber,
|
|
1647
|
-
messages: this.ctx.runMgr.messages,
|
|
1648
|
-
steps: this.steps,
|
|
1649
|
-
prepared: result,
|
|
1650
|
-
})
|
|
1901
|
+
const decided = await stage(this.stepContext(stepNumber, result))
|
|
1651
1902
|
if (decided) result = { ...result, ...decided }
|
|
1903
|
+
await this.selectContextModel(result.model ?? this.ctx.runConfig.model)
|
|
1652
1904
|
} catch (err) {
|
|
1653
1905
|
// Skipped, and the rest still run: one broken concern must
|
|
1654
1906
|
// not silently disable the others it was declared beside.
|
|
@@ -1710,6 +1962,18 @@ export class IterationOrchestrator {
|
|
|
1710
1962
|
return prepared
|
|
1711
1963
|
}
|
|
1712
1964
|
|
|
1965
|
+
private async selectContextModel(model: string | undefined): Promise<void> {
|
|
1966
|
+
if (model !== (this.ctx.contextModel ?? this.ctx.runConfig.model)) {
|
|
1967
|
+
// A measurement from another tokenizer cannot price the new request.
|
|
1968
|
+
this.ctx.runMgr.clearLastPromptTokens()
|
|
1969
|
+
}
|
|
1970
|
+
this.ctx.contextModel = model
|
|
1971
|
+
this.ctx.activeProviderContextWindow =
|
|
1972
|
+
model && model !== this.ctx.runConfig.model && !this.ctx.compactionConfig?.contextWindowTokens
|
|
1973
|
+
? await this.ctx.resolveModelContextWindow?.(model)
|
|
1974
|
+
: undefined
|
|
1975
|
+
}
|
|
1976
|
+
|
|
1713
1977
|
/** Steps completed so far, exposed on the returned `Run`. */
|
|
1714
1978
|
private readonly steps: StepResult[] = []
|
|
1715
1979
|
|
|
@@ -1738,18 +2002,33 @@ export class IterationOrchestrator {
|
|
|
1738
2002
|
* empty drain must change nothing at all: a `continue` on nothing queued
|
|
1739
2003
|
* spends an iteration and a model call to say the same thing again.
|
|
1740
2004
|
*/
|
|
2005
|
+
private rememberUserMessage(message: Message, arriving = true): void {
|
|
2006
|
+
if (!isOperatorUserMessage(message)) return
|
|
2007
|
+
this.latestUserMessage = message
|
|
2008
|
+
// The hook field alone does not reach the model. Preserve arrivals in
|
|
2009
|
+
// the compaction state too, before their original message or attached
|
|
2010
|
+
// tool result can be shed. Initial history was already extracted at seed.
|
|
2011
|
+
const manager = this.ctx.workingStateManager
|
|
2012
|
+
if (arriving && manager) {
|
|
2013
|
+
extractFromUserMessage(manager, message.content, !manager.getState().task)
|
|
2014
|
+
}
|
|
2015
|
+
}
|
|
2016
|
+
|
|
1741
2017
|
private deliverInbound(): number {
|
|
1742
2018
|
const queued = this.ctx.inboundMessages?.() ?? []
|
|
1743
|
-
for (const message of queued)
|
|
2019
|
+
for (const message of queued) {
|
|
2020
|
+
this.ctx.runMgr.pushMessage(message)
|
|
2021
|
+
this.rememberUserMessage(message)
|
|
2022
|
+
}
|
|
1744
2023
|
|
|
1745
2024
|
// The steering channel's remainder. `attachSteering` already took
|
|
1746
2025
|
// what it could carry on a tool result; anything still pending is
|
|
1747
2026
|
// guidance from a turn that had no result to attach it to.
|
|
1748
2027
|
const stranded = this.ctx.steering?.drain()
|
|
1749
2028
|
if (stranded) {
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
)
|
|
2029
|
+
const message = createRuntimeContextMessage(formatSteeringNote(stranded), 'steering')
|
|
2030
|
+
this.ctx.runMgr.pushMessage(message)
|
|
2031
|
+
this.rememberUserMessage(createRuntimeContextMessage(stranded, 'steering'))
|
|
1753
2032
|
}
|
|
1754
2033
|
|
|
1755
2034
|
return queued.length + (stranded ? 1 : 0)
|
|
@@ -1856,7 +2135,10 @@ export class IterationOrchestrator {
|
|
|
1856
2135
|
|
|
1857
2136
|
/** Turns spent asking the model again for a valid structured output. */
|
|
1858
2137
|
private structuredOutputAttempts = 0
|
|
2138
|
+
private nativeStructuredAttempts = 0
|
|
1859
2139
|
private structuredOutputDone = false
|
|
2140
|
+
private pendingStructuredOutput: unknown
|
|
2141
|
+
private structuredReviewAttempts = 0
|
|
1860
2142
|
|
|
1861
2143
|
private structuredOutputRetryLimit(): number {
|
|
1862
2144
|
return this.ctx.structuredOutput?.maxRetries ?? DEFAULT_STRUCTURED_OUTPUT_RETRIES
|
|
@@ -1883,6 +2165,7 @@ export class IterationOrchestrator {
|
|
|
1883
2165
|
results: readonly ToolCallOutcome[],
|
|
1884
2166
|
response: ChatCompletionResponse,
|
|
1885
2167
|
): ToolCallOutcome | undefined {
|
|
2168
|
+
if (this.ctx.structuredOutput?.mode === 'native') return undefined
|
|
1886
2169
|
const terminal = results.filter((r) => this.ctx.tools.get(r.toolName)?.terminal === true)
|
|
1887
2170
|
if (terminal.length === 0) return undefined
|
|
1888
2171
|
|
|
@@ -1951,13 +2234,14 @@ export class IterationOrchestrator {
|
|
|
1951
2234
|
* doing work, and it is the bound the neighbour relies on for the
|
|
1952
2235
|
* identical pathology.
|
|
1953
2236
|
*/
|
|
1954
|
-
private captureStructuredOutput(
|
|
2237
|
+
private async captureStructuredOutput(
|
|
1955
2238
|
results: readonly ToolCallOutcome[],
|
|
1956
2239
|
response: ChatCompletionResponse,
|
|
1957
|
-
):
|
|
1958
|
-
if (!this.needsStructuredOutput()
|
|
2240
|
+
): Promise<'absent' | 'accepted' | 'retry' | 'exhausted' | 'cancelled'> {
|
|
2241
|
+
if (!this.needsStructuredOutput() || this.ctx.structuredOutput?.mode === 'native')
|
|
2242
|
+
return 'absent'
|
|
1959
2243
|
const hit = results.find((r) => r.toolName === STRUCTURED_OUTPUT_TOOL_NAME && !r.isError)
|
|
1960
|
-
if (!hit) return
|
|
2244
|
+
if (!hit) return 'absent'
|
|
1961
2245
|
|
|
1962
2246
|
const callCount = response.message.toolCalls?.length ?? 0
|
|
1963
2247
|
if (callCount > 1) {
|
|
@@ -1965,18 +2249,90 @@ export class IterationOrchestrator {
|
|
|
1965
2249
|
[NAMZU.RUN_ID]: this.ctx.runMgr.id,
|
|
1966
2250
|
'namzu.runtime.calls_in_turn': callCount,
|
|
1967
2251
|
})
|
|
1968
|
-
return
|
|
2252
|
+
return 'absent'
|
|
1969
2253
|
}
|
|
1970
2254
|
|
|
2255
|
+
let parsed: unknown
|
|
1971
2256
|
try {
|
|
1972
|
-
|
|
2257
|
+
parsed = JSON.parse(hit.output)
|
|
1973
2258
|
} catch {
|
|
1974
2259
|
// The tool serializes its own validated input, so this is
|
|
1975
2260
|
// unreachable in practice; keep the raw text rather than losing it.
|
|
1976
|
-
this.ctx.
|
|
2261
|
+
if (this.ctx.structuredOutput?.review)
|
|
2262
|
+
throw new Error(
|
|
2263
|
+
'Structured review requires an intact JSON tool result; check tool-output limits and result transformations',
|
|
2264
|
+
)
|
|
2265
|
+
parsed = hit.output
|
|
1977
2266
|
}
|
|
2267
|
+
return this.reviewStructuredOutput(parsed)
|
|
2268
|
+
}
|
|
2269
|
+
|
|
2270
|
+
private publishStructuredOutput(): void {
|
|
2271
|
+
this.ctx.runMgr.setStructuredOutput(this.pendingStructuredOutput)
|
|
1978
2272
|
this.structuredOutputDone = true
|
|
1979
|
-
|
|
2273
|
+
}
|
|
2274
|
+
|
|
2275
|
+
private async reviewStructuredOutput(
|
|
2276
|
+
parsed: unknown,
|
|
2277
|
+
): Promise<'accepted' | 'retry' | 'exhausted' | 'cancelled'> {
|
|
2278
|
+
if (this.ctx.abortController.signal.aborted) return 'cancelled'
|
|
2279
|
+
const reviewer = this.ctx.structuredOutput?.review
|
|
2280
|
+
if (reviewer) {
|
|
2281
|
+
const signal = this.ctx.abortController.signal
|
|
2282
|
+
if (signal.aborted) return 'cancelled'
|
|
2283
|
+
let onAbort: () => void = () => {}
|
|
2284
|
+
const aborted = new Promise<never>((_resolve, reject) => {
|
|
2285
|
+
onAbort = () => reject(signal.reason ?? new Error('Structured review cancelled'))
|
|
2286
|
+
signal.addEventListener('abort', onAbort, { once: true })
|
|
2287
|
+
})
|
|
2288
|
+
let verdict: AnswerReview
|
|
2289
|
+
try {
|
|
2290
|
+
verdict = await Promise.race([
|
|
2291
|
+
Promise.resolve().then(() =>
|
|
2292
|
+
reviewer(structuredClone(parsed), {
|
|
2293
|
+
runId: this.ctx.runMgr.id,
|
|
2294
|
+
iteration: this.ctx.runMgr.currentIteration,
|
|
2295
|
+
signal,
|
|
2296
|
+
messages: this.ctx.runMgr.messages,
|
|
2297
|
+
}),
|
|
2298
|
+
),
|
|
2299
|
+
aborted,
|
|
2300
|
+
])
|
|
2301
|
+
} catch (error) {
|
|
2302
|
+
if (signal.aborted) return 'cancelled'
|
|
2303
|
+
throw error
|
|
2304
|
+
} finally {
|
|
2305
|
+
signal.removeEventListener('abort', onAbort)
|
|
2306
|
+
}
|
|
2307
|
+
if (signal.aborted) return 'cancelled'
|
|
2308
|
+
if (!verdict || typeof verdict.accept !== 'boolean')
|
|
2309
|
+
throw new Error('Structured reviewer returned an invalid verdict')
|
|
2310
|
+
if (!verdict.accept) {
|
|
2311
|
+
if (typeof verdict.feedback !== 'string' || verdict.feedback.trim().length === 0)
|
|
2312
|
+
throw new Error('Structured reviewer rejection requires feedback')
|
|
2313
|
+
this.structuredReviewAttempts++
|
|
2314
|
+
this.ctx.runMgr.pushMessage(createRuntimeContextMessage(verdict.feedback, 'answer-review'))
|
|
2315
|
+
// Persist both the feedback and its consumed allowance before the
|
|
2316
|
+
// next request. This checkpoint is not an approval/park boundary.
|
|
2317
|
+
const checkpoint = await this.ctx.checkpointMgr.create(
|
|
2318
|
+
this.ctx.runMgr,
|
|
2319
|
+
this.ctx.runMgr.currentIteration,
|
|
2320
|
+
)
|
|
2321
|
+
await this.ctx.emitEvent({
|
|
2322
|
+
type: 'checkpoint_created',
|
|
2323
|
+
runId: this.ctx.runMgr.id,
|
|
2324
|
+
checkpointId: checkpoint.id,
|
|
2325
|
+
iteration: this.ctx.runMgr.currentIteration,
|
|
2326
|
+
})
|
|
2327
|
+
if (signal.aborted) return 'cancelled'
|
|
2328
|
+
return this.structuredReviewAttempts >
|
|
2329
|
+
(this.ctx.structuredOutput?.maxReviews ?? DEFAULT_ANSWER_REVIEW_LIMIT)
|
|
2330
|
+
? 'exhausted'
|
|
2331
|
+
: 'retry'
|
|
2332
|
+
}
|
|
2333
|
+
}
|
|
2334
|
+
this.pendingStructuredOutput = parsed
|
|
2335
|
+
return 'accepted'
|
|
1980
2336
|
}
|
|
1981
2337
|
|
|
1982
2338
|
/**
|
|
@@ -1997,6 +2353,7 @@ export class IterationOrchestrator {
|
|
|
1997
2353
|
return await this.ctx.reviewAnswer(answer, {
|
|
1998
2354
|
runId: this.ctx.runMgr.id,
|
|
1999
2355
|
iteration: this.ctx.runMgr.currentIteration,
|
|
2356
|
+
signal: this.ctx.abortController.signal,
|
|
2000
2357
|
messages: this.ctx.runMgr.messages,
|
|
2001
2358
|
})
|
|
2002
2359
|
} catch (err) {
|
|
@@ -2059,6 +2416,8 @@ export class IterationOrchestrator {
|
|
|
2059
2416
|
model: string,
|
|
2060
2417
|
reason: StopReason,
|
|
2061
2418
|
): Promise<StopReason | undefined> {
|
|
2419
|
+
if (this.ctx.structuredOutput?.mode === 'native') return 'structured_output_failed'
|
|
2420
|
+
|
|
2062
2421
|
const lastAssistant = [...this.ctx.runMgr.messages]
|
|
2063
2422
|
.reverse()
|
|
2064
2423
|
.find((m) => m.role === 'assistant')
|
|
@@ -2091,7 +2450,7 @@ export class IterationOrchestrator {
|
|
|
2091
2450
|
),
|
|
2092
2451
|
]
|
|
2093
2452
|
const finalMessages = projectRequestRichContent(
|
|
2094
|
-
finalHistory,
|
|
2453
|
+
this.projectObservations(finalHistory),
|
|
2095
2454
|
this.ctx.runConfig.maxRequestRichContentBytes ?? DEFAULT_MAX_REQUEST_RICH_CONTENT_BYTES,
|
|
2096
2455
|
)
|
|
2097
2456
|
await this.reportUnsupportedToolResults(finalMessages)
|