@namzu/sdk 51.1.0 → 52.1.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 +119 -0
- package/dist/agents/QueryAgent.d.ts.map +1 -1
- package/dist/agents/QueryAgent.js +2 -0
- package/dist/agents/QueryAgent.js.map +1 -1
- package/dist/agents/SupervisorAgent.d.ts +1 -1
- package/dist/agents/SupervisorAgent.d.ts.map +1 -1
- package/dist/agents/SupervisorAgent.js.map +1 -1
- package/dist/agents/examples/SupervisorAgent.d.ts +42 -0
- package/dist/agents/examples/SupervisorAgent.d.ts.map +1 -1
- package/dist/agents/examples/SupervisorAgent.js +80 -4
- package/dist/agents/examples/SupervisorAgent.js.map +1 -1
- package/dist/agents/index.d.ts +1 -1
- package/dist/agents/index.d.ts.map +1 -1
- package/dist/agents/index.js.map +1 -1
- package/dist/authorization/protected-paths.d.ts +36 -0
- package/dist/authorization/protected-paths.d.ts.map +1 -0
- package/dist/authorization/protected-paths.js +107 -0
- package/dist/authorization/protected-paths.js.map +1 -0
- package/dist/authorization/readonly-commands.d.ts +39 -0
- package/dist/authorization/readonly-commands.d.ts.map +1 -0
- package/dist/authorization/readonly-commands.js +797 -0
- package/dist/authorization/readonly-commands.js.map +1 -0
- package/dist/authorization/readonly-flags.d.ts +19 -0
- package/dist/authorization/readonly-flags.d.ts.map +1 -0
- package/dist/authorization/readonly-flags.js +178 -0
- package/dist/authorization/readonly-flags.js.map +1 -0
- package/dist/authorization/removal.d.ts +52 -0
- package/dist/authorization/removal.d.ts.map +1 -0
- package/dist/authorization/removal.js +283 -0
- package/dist/authorization/removal.js.map +1 -0
- package/dist/authorization/shell-paths.d.ts +66 -0
- package/dist/authorization/shell-paths.d.ts.map +1 -0
- package/dist/authorization/shell-paths.js +697 -0
- package/dist/authorization/shell-paths.js.map +1 -0
- package/dist/bridge/acp/update.d.ts.map +1 -1
- package/dist/bridge/acp/update.js +1 -0
- package/dist/bridge/acp/update.js.map +1 -1
- package/dist/compaction/context-window.d.ts +24 -0
- package/dist/compaction/context-window.d.ts.map +1 -1
- package/dist/compaction/context-window.js +34 -0
- package/dist/compaction/context-window.js.map +1 -1
- package/dist/compaction/manual.d.ts.map +1 -1
- package/dist/compaction/manual.js +10 -2
- package/dist/compaction/manual.js.map +1 -1
- package/dist/compaction/plan.d.ts +4 -0
- package/dist/compaction/plan.d.ts.map +1 -1
- package/dist/compaction/plan.js +6 -2
- package/dist/compaction/plan.js.map +1 -1
- package/dist/compaction/verifier.d.ts +11 -1
- package/dist/compaction/verifier.d.ts.map +1 -1
- package/dist/compaction/verifier.js +75 -23
- package/dist/compaction/verifier.js.map +1 -1
- package/dist/config/runtime.d.ts +55 -7
- package/dist/config/runtime.d.ts.map +1 -1
- package/dist/config/runtime.js +23 -2
- package/dist/config/runtime.js.map +1 -1
- package/dist/connector/web/guarded-fetch.d.ts.map +1 -1
- package/dist/connector/web/guarded-fetch.js +24 -0
- package/dist/connector/web/guarded-fetch.js.map +1 -1
- package/dist/connector/web/index.d.ts +1 -1
- package/dist/connector/web/index.d.ts.map +1 -1
- package/dist/connector/web/page.d.ts +59 -0
- package/dist/connector/web/page.d.ts.map +1 -0
- package/dist/connector/web/page.js +112 -0
- package/dist/connector/web/page.js.map +1 -0
- package/dist/connector/web/types.d.ts +47 -0
- package/dist/connector/web/types.d.ts.map +1 -1
- package/dist/connector/web/types.js.map +1 -1
- package/dist/constants/continuation.d.ts +8 -0
- package/dist/constants/continuation.d.ts.map +1 -1
- package/dist/constants/continuation.js +8 -0
- package/dist/constants/continuation.js.map +1 -1
- package/dist/constants/plugin/index.d.ts +1 -1
- package/dist/constants/plugin/index.d.ts.map +1 -1
- package/dist/constants/plugin/index.js +1 -1
- package/dist/constants/plugin/index.js.map +1 -1
- package/dist/contracts/a2a.d.ts +2 -2
- package/dist/manager/agent/lifecycle.d.ts +7 -0
- package/dist/manager/agent/lifecycle.d.ts.map +1 -1
- package/dist/manager/agent/lifecycle.js +11 -2
- package/dist/manager/agent/lifecycle.js.map +1 -1
- package/dist/manager/session/turn-recorder.d.ts.map +1 -1
- package/dist/manager/session/turn-recorder.js +4 -2
- package/dist/manager/session/turn-recorder.js.map +1 -1
- package/dist/plugin/index.d.ts +1 -1
- package/dist/plugin/index.d.ts.map +1 -1
- package/dist/plugin/index.js +1 -1
- package/dist/plugin/index.js.map +1 -1
- package/dist/plugin/lifecycle.d.ts +6 -0
- package/dist/plugin/lifecycle.d.ts.map +1 -1
- package/dist/plugin/lifecycle.js +98 -114
- package/dist/plugin/lifecycle.js.map +1 -1
- package/dist/plugin/shell-hook.d.ts +90 -22
- package/dist/plugin/shell-hook.d.ts.map +1 -1
- package/dist/plugin/shell-hook.js +434 -41
- package/dist/plugin/shell-hook.js.map +1 -1
- package/dist/provider/capabilities.d.ts +9 -0
- package/dist/provider/capabilities.d.ts.map +1 -1
- package/dist/provider/capabilities.js +15 -0
- package/dist/provider/capabilities.js.map +1 -1
- package/dist/provider/errors.d.ts.map +1 -1
- package/dist/provider/errors.js +13 -0
- package/dist/provider/errors.js.map +1 -1
- package/dist/provider/fallback.d.ts.map +1 -1
- package/dist/provider/fallback.js +10 -0
- package/dist/provider/fallback.js.map +1 -1
- package/dist/provider/idle-timeout.d.ts.map +1 -1
- package/dist/provider/idle-timeout.js +5 -0
- package/dist/provider/idle-timeout.js.map +1 -1
- package/dist/provider/image-input-refusal.d.ts +9 -0
- package/dist/provider/image-input-refusal.d.ts.map +1 -0
- package/dist/provider/image-input-refusal.js +54 -0
- package/dist/provider/image-input-refusal.js.map +1 -0
- package/dist/provider/index.d.ts +2 -1
- package/dist/provider/index.d.ts.map +1 -1
- package/dist/provider/index.js +2 -1
- package/dist/provider/index.js.map +1 -1
- package/dist/provider/retry.d.ts +7 -2
- package/dist/provider/retry.d.ts.map +1 -1
- package/dist/provider/retry.js +38 -4
- package/dist/provider/retry.js.map +1 -1
- package/dist/public-runtime.d.ts +5 -2
- package/dist/public-runtime.d.ts.map +1 -1
- package/dist/public-runtime.js +5 -2
- package/dist/public-runtime.js.map +1 -1
- package/dist/public-types.d.ts +2 -2
- package/dist/public-types.d.ts.map +1 -1
- package/dist/runtime/jobs/registry.d.ts +21 -0
- package/dist/runtime/jobs/registry.d.ts.map +1 -1
- package/dist/runtime/jobs/registry.js +15 -2
- package/dist/runtime/jobs/registry.js.map +1 -1
- package/dist/runtime/query/deferred-sandbox.d.ts +54 -0
- package/dist/runtime/query/deferred-sandbox.d.ts.map +1 -0
- package/dist/runtime/query/deferred-sandbox.js +75 -0
- package/dist/runtime/query/deferred-sandbox.js.map +1 -0
- package/dist/runtime/query/executor/tool-call-admission.d.ts +10 -0
- package/dist/runtime/query/executor/tool-call-admission.d.ts.map +1 -1
- package/dist/runtime/query/executor/tool-call-admission.js +74 -13
- package/dist/runtime/query/executor/tool-call-admission.js.map +1 -1
- package/dist/runtime/query/executor.d.ts +51 -2
- package/dist/runtime/query/executor.d.ts.map +1 -1
- package/dist/runtime/query/executor.js +214 -9
- package/dist/runtime/query/executor.js.map +1 -1
- package/dist/runtime/query/finalize-turn.d.ts +6 -0
- package/dist/runtime/query/finalize-turn.d.ts.map +1 -1
- package/dist/runtime/query/finalize-turn.js +1 -1
- package/dist/runtime/query/finalize-turn.js.map +1 -1
- package/dist/runtime/query/index.d.ts +29 -0
- package/dist/runtime/query/index.d.ts.map +1 -1
- package/dist/runtime/query/index.js +108 -28
- package/dist/runtime/query/index.js.map +1 -1
- package/dist/runtime/query/iteration/index.d.ts +57 -0
- package/dist/runtime/query/iteration/index.d.ts.map +1 -1
- package/dist/runtime/query/iteration/index.js +380 -28
- package/dist/runtime/query/iteration/index.js.map +1 -1
- package/dist/runtime/query/iteration/phases/compaction-breaker.d.ts +61 -0
- package/dist/runtime/query/iteration/phases/compaction-breaker.d.ts.map +1 -0
- package/dist/runtime/query/iteration/phases/compaction-breaker.js +94 -0
- package/dist/runtime/query/iteration/phases/compaction-breaker.js.map +1 -0
- package/dist/runtime/query/iteration/phases/compaction.d.ts +42 -1
- package/dist/runtime/query/iteration/phases/compaction.d.ts.map +1 -1
- package/dist/runtime/query/iteration/phases/compaction.js +203 -23
- package/dist/runtime/query/iteration/phases/compaction.js.map +1 -1
- package/dist/runtime/query/iteration/phases/context.d.ts +10 -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 +165 -2
- package/dist/runtime/query/iteration/phases/tool-review.js.map +1 -1
- package/dist/runtime/query/iteration/provider-rejected-image.d.ts +21 -1
- package/dist/runtime/query/iteration/provider-rejected-image.d.ts.map +1 -1
- package/dist/runtime/query/iteration/provider-rejected-image.js +53 -7
- package/dist/runtime/query/iteration/provider-rejected-image.js.map +1 -1
- package/dist/runtime/query/iteration/request-repair.d.ts +108 -0
- package/dist/runtime/query/iteration/request-repair.d.ts.map +1 -0
- package/dist/runtime/query/iteration/request-repair.js +593 -0
- package/dist/runtime/query/iteration/request-repair.js.map +1 -0
- package/dist/runtime/query/iteration/stream-turn.d.ts +6 -0
- package/dist/runtime/query/iteration/stream-turn.d.ts.map +1 -1
- package/dist/runtime/query/iteration/stream-turn.js +2 -2
- package/dist/runtime/query/iteration/stream-turn.js.map +1 -1
- package/dist/runtime/query/path-escalation.d.ts +36 -0
- package/dist/runtime/query/path-escalation.d.ts.map +1 -0
- package/dist/runtime/query/path-escalation.js +184 -0
- package/dist/runtime/query/path-escalation.js.map +1 -0
- package/dist/runtime/query/plugin-hooks.d.ts.map +1 -1
- package/dist/runtime/query/plugin-hooks.js +8 -0
- package/dist/runtime/query/plugin-hooks.js.map +1 -1
- package/dist/runtime/query/reminders.d.ts +35 -0
- package/dist/runtime/query/reminders.d.ts.map +1 -0
- package/dist/runtime/query/reminders.js +7 -0
- package/dist/runtime/query/reminders.js.map +1 -0
- package/dist/runtime/query/request-rich-content.d.ts +5 -1
- package/dist/runtime/query/request-rich-content.d.ts.map +1 -1
- package/dist/runtime/query/request-rich-content.js +67 -25
- package/dist/runtime/query/request-rich-content.js.map +1 -1
- package/dist/runtime/query/resume-pending.d.ts.map +1 -1
- package/dist/runtime/query/resume-pending.js +26 -0
- package/dist/runtime/query/resume-pending.js.map +1 -1
- package/dist/runtime/query/review-policy.d.ts +26 -0
- package/dist/runtime/query/review-policy.d.ts.map +1 -1
- package/dist/runtime/query/review-policy.js +79 -5
- package/dist/runtime/query/review-policy.js.map +1 -1
- package/dist/runtime/query/tool-output-budget.d.ts +46 -0
- package/dist/runtime/query/tool-output-budget.d.ts.map +1 -1
- package/dist/runtime/query/tool-output-budget.js +85 -1
- package/dist/runtime/query/tool-output-budget.js.map +1 -1
- package/dist/runtime/query/tooling.d.ts +1 -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/session/paths.d.ts +5 -1
- package/dist/session/paths.d.ts.map +1 -1
- package/dist/session/paths.js +8 -0
- package/dist/session/paths.js.map +1 -1
- package/dist/store/memory/disk.d.ts.map +1 -1
- package/dist/store/memory/disk.js +2 -2
- package/dist/store/memory/disk.js.map +1 -1
- package/dist/store/memory/markdown.d.ts.map +1 -1
- package/dist/store/memory/markdown.js +2 -2
- package/dist/store/memory/markdown.js.map +1 -1
- package/dist/store/memory/naming.d.ts +9 -0
- package/dist/store/memory/naming.d.ts.map +1 -1
- package/dist/store/memory/naming.js +12 -0
- package/dist/store/memory/naming.js.map +1 -1
- package/dist/tools/builtins/bash.d.ts +30 -1
- package/dist/tools/builtins/bash.d.ts.map +1 -1
- package/dist/tools/builtins/bash.js +170 -26
- package/dist/tools/builtins/bash.js.map +1 -1
- package/dist/tools/builtins/computer-use.d.ts +1 -1
- package/dist/tools/builtins/computer-use.d.ts.map +1 -1
- package/dist/tools/builtins/computer-use.js +12 -5
- package/dist/tools/builtins/computer-use.js.map +1 -1
- package/dist/tools/builtins/content-fingerprint.d.ts +2 -0
- package/dist/tools/builtins/content-fingerprint.d.ts.map +1 -1
- package/dist/tools/builtins/content-fingerprint.js +4 -0
- package/dist/tools/builtins/content-fingerprint.js.map +1 -1
- package/dist/tools/builtins/edit.d.ts.map +1 -1
- package/dist/tools/builtins/edit.js +60 -18
- package/dist/tools/builtins/edit.js.map +1 -1
- package/dist/tools/builtins/grep.d.ts +8 -1
- package/dist/tools/builtins/grep.d.ts.map +1 -1
- package/dist/tools/builtins/grep.js +152 -33
- package/dist/tools/builtins/grep.js.map +1 -1
- package/dist/tools/builtins/read-file.d.ts +1 -0
- package/dist/tools/builtins/read-file.d.ts.map +1 -1
- package/dist/tools/builtins/read-file.js +44 -5
- package/dist/tools/builtins/read-file.js.map +1 -1
- package/dist/tools/builtins/read-render.d.ts +52 -0
- package/dist/tools/builtins/read-render.d.ts.map +1 -1
- package/dist/tools/builtins/read-render.js +143 -0
- package/dist/tools/builtins/read-render.js.map +1 -1
- package/dist/tools/builtins/web.d.ts +13 -2
- package/dist/tools/builtins/web.d.ts.map +1 -1
- package/dist/tools/builtins/web.js +225 -32
- package/dist/tools/builtins/web.js.map +1 -1
- package/dist/tools/coordinator/ask-user-question.d.ts +2 -0
- package/dist/tools/coordinator/ask-user-question.d.ts.map +1 -1
- package/dist/tools/coordinator/ask-user-question.js +256 -92
- package/dist/tools/coordinator/ask-user-question.js.map +1 -1
- package/dist/tools/coordinator/question-options.d.ts +1 -0
- package/dist/tools/coordinator/question-options.d.ts.map +1 -1
- package/dist/tools/coordinator/question-options.js +6 -1
- package/dist/tools/coordinator/question-options.js.map +1 -1
- package/dist/tools/defineTool.d.ts +4 -1
- package/dist/tools/defineTool.d.ts.map +1 -1
- package/dist/tools/defineTool.js +6 -1
- package/dist/tools/defineTool.js.map +1 -1
- package/dist/tools/paths.d.ts +6 -0
- package/dist/tools/paths.d.ts.map +1 -1
- package/dist/tools/paths.js +1 -1
- package/dist/tools/paths.js.map +1 -1
- package/dist/types/agent/query.d.ts +3 -0
- package/dist/types/agent/query.d.ts.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 +104 -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 +1 -1
- package/dist/types/message/index.d.ts.map +1 -1
- package/dist/types/message/index.js +2 -0
- package/dist/types/message/index.js.map +1 -1
- package/dist/types/plugin/index.d.ts +93 -19
- package/dist/types/plugin/index.d.ts.map +1 -1
- package/dist/types/plugin/index.js +3 -0
- package/dist/types/plugin/index.js.map +1 -1
- package/dist/types/provider/errors.d.ts +19 -0
- package/dist/types/provider/errors.d.ts.map +1 -1
- package/dist/types/provider/errors.js +54 -5
- package/dist/types/provider/errors.js.map +1 -1
- package/dist/types/provider/interface.d.ts +12 -0
- package/dist/types/provider/interface.d.ts.map +1 -1
- package/dist/types/provider/stream.d.ts +1 -1
- package/dist/types/session/config.d.ts +14 -0
- package/dist/types/session/config.d.ts.map +1 -1
- package/dist/types/session/events.d.ts +27 -4
- package/dist/types/session/events.d.ts.map +1 -1
- package/dist/types/session/events.js.map +1 -1
- package/dist/types/session/records.d.ts +9 -9
- package/dist/types/session/records.d.ts.map +1 -1
- package/dist/types/session/records.js +1 -0
- package/dist/types/session/records.js.map +1 -1
- package/dist/types/session/stop-reason.d.ts +5 -0
- package/dist/types/session/stop-reason.d.ts.map +1 -1
- package/dist/types/tool/index.d.ts +52 -0
- package/dist/types/tool/index.d.ts.map +1 -1
- package/dist/types/tool/index.js.map +1 -1
- package/package.json +4 -2
- package/src/agents/QueryAgent.ts +5 -1
- package/src/agents/SupervisorAgent.ts +1 -1
- package/src/agents/examples/SupervisorAgent.ts +217 -106
- package/src/agents/index.ts +1 -1
- package/src/authorization/protected-paths.ts +110 -0
- package/src/authorization/readonly-commands.ts +771 -0
- package/src/authorization/readonly-flags.ts +196 -0
- package/src/authorization/removal.ts +326 -0
- package/src/authorization/shell-paths.ts +927 -0
- package/src/bridge/acp/update.ts +1 -0
- package/src/compaction/context-window.ts +41 -0
- package/src/compaction/manual.ts +10 -2
- package/src/compaction/plan.ts +11 -2
- package/src/compaction/verifier.ts +84 -22
- package/src/config/runtime.ts +23 -2
- package/src/connector/web/guarded-fetch.ts +26 -0
- package/src/connector/web/index.ts +3 -0
- package/src/connector/web/page.ts +130 -0
- package/src/connector/web/types.ts +47 -0
- package/src/constants/continuation.ts +10 -0
- package/src/constants/plugin/index.ts +1 -1
- package/src/manager/agent/lifecycle.ts +12 -4
- package/src/manager/session/turn-recorder.ts +10 -2
- package/src/plugin/index.ts +1 -0
- package/src/plugin/lifecycle.ts +107 -119
- package/src/plugin/shell-hook.ts +477 -43
- package/src/provider/capabilities.ts +17 -0
- package/src/provider/errors.ts +13 -0
- package/src/provider/fallback.ts +10 -0
- package/src/provider/idle-timeout.ts +5 -0
- package/src/provider/image-input-refusal.ts +54 -0
- package/src/provider/index.ts +2 -0
- package/src/provider/retry.ts +42 -4
- package/src/public-runtime.ts +11 -0
- package/src/public-types.ts +4 -0
- package/src/runtime/jobs/registry.ts +39 -2
- package/src/runtime/query/deferred-sandbox.ts +110 -0
- package/src/runtime/query/executor/tool-call-admission.ts +79 -13
- package/src/runtime/query/executor.ts +267 -11
- package/src/runtime/query/finalize-turn.ts +7 -1
- package/src/runtime/query/index.ts +169 -52
- package/src/runtime/query/iteration/index.ts +439 -35
- package/src/runtime/query/iteration/phases/compaction-breaker.ts +108 -0
- package/src/runtime/query/iteration/phases/compaction.ts +241 -38
- package/src/runtime/query/iteration/phases/context.ts +11 -0
- package/src/runtime/query/iteration/phases/tool-review.ts +177 -2
- package/src/runtime/query/iteration/provider-rejected-image.ts +71 -5
- package/src/runtime/query/iteration/request-repair.ts +743 -0
- package/src/runtime/query/iteration/stream-turn.ts +11 -1
- package/src/runtime/query/path-escalation.ts +204 -0
- package/src/runtime/query/plugin-hooks.ts +8 -0
- package/src/runtime/query/reminders.ts +45 -0
- package/src/runtime/query/request-rich-content.ts +77 -27
- package/src/runtime/query/resume-pending.ts +27 -0
- package/src/runtime/query/review-policy.ts +106 -5
- package/src/runtime/query/tool-output-budget.ts +115 -1
- package/src/runtime/query/tooling.ts +6 -0
- package/src/session/paths.ts +11 -1
- package/src/store/memory/disk.ts +2 -1
- package/src/store/memory/markdown.ts +2 -1
- package/src/store/memory/naming.ts +13 -0
- package/src/tools/builtins/bash.ts +203 -34
- package/src/tools/builtins/computer-use.ts +13 -4
- package/src/tools/builtins/content-fingerprint.ts +5 -0
- package/src/tools/builtins/edit.ts +69 -19
- package/src/tools/builtins/grep.ts +159 -38
- package/src/tools/builtins/read-file.ts +48 -5
- package/src/tools/builtins/read-render.ts +193 -0
- package/src/tools/builtins/web.ts +258 -33
- package/src/tools/coordinator/ask-user-question.ts +309 -103
- package/src/tools/coordinator/question-options.ts +8 -1
- package/src/tools/defineTool.ts +11 -2
- package/src/tools/paths.ts +1 -1
- package/src/types/agent/query.ts +3 -0
- package/src/types/errors/catalog.ts +1 -1
- package/src/types/hitl/index.ts +104 -0
- package/src/types/message/index.ts +2 -0
- package/src/types/plugin/index.ts +101 -18
- package/src/types/provider/errors.ts +66 -5
- package/src/types/provider/interface.ts +13 -0
- package/src/types/provider/stream.ts +1 -1
- package/src/types/session/config.ts +14 -0
- package/src/types/session/events.ts +32 -4
- package/src/types/session/records.ts +1 -0
- package/src/types/session/stop-reason.ts +5 -0
- package/src/types/tool/index.ts +53 -2
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { SpanStatusCode } from '@opentelemetry/api';
|
|
2
2
|
import { extractFromAssistantMessage, extractFromUserMessage, } from '../../../compaction/extractor.js';
|
|
3
3
|
import { estimateMessageTokens } from '../../../compaction/token-estimate.js';
|
|
4
|
-
import { AUTO_CONTINUATION_USER_MESSAGE } from '../../../constants/continuation.js';
|
|
4
|
+
import { AUTO_CONTINUATION_USER_MESSAGE, REASONING_CUT_USER_MESSAGE, } from '../../../constants/continuation.js';
|
|
5
5
|
import { CHARS_PER_TOKEN } from '../../../constants/limits.js';
|
|
6
6
|
import { DEFAULT_STRUCTURED_OUTPUT_RETRIES, STRUCTURED_OUTPUT_REPROMPT, } from '../../../constants/tools/index.js';
|
|
7
7
|
import { withStreamedMessageIdentity } from '../../../manager/session/streamed-message-identity.js';
|
|
8
8
|
import { renderSkillsSection } from '../../../persona/assembler.js';
|
|
9
|
-
import { resolveProviderCapabilities } from '../../../provider/capabilities.js';
|
|
9
|
+
import { modelReadsImages, resolveProviderCapabilities } from '../../../provider/capabilities.js';
|
|
10
10
|
import { collectChatCompletion } from '../../../provider/collect-chat-completion.js';
|
|
11
11
|
import { renderToolSchema } from '../../../registry/tool/schema.js';
|
|
12
12
|
import { formatCompletionNotification } from '../../../scheduler/completion-inbox.js';
|
|
@@ -15,12 +15,13 @@ import { getTracer } from '../../../telemetry/runtime-accessors.js';
|
|
|
15
15
|
import { STRUCTURED_OUTPUT_TOOL_NAME } from '../../../tools/builtins/structuredOutput.js';
|
|
16
16
|
import { NamzuError } from '../../../types/errors/index.js';
|
|
17
17
|
import { createAssistantMessage, createRuntimeContextMessage, createSystemMessage, } from '../../../types/message/index.js';
|
|
18
|
-
import { classifyProviderError } from '../../../types/provider/errors.js';
|
|
18
|
+
import { classifyProviderError, readOutputOverflow } from '../../../types/provider/errors.js';
|
|
19
19
|
import { toErrorMessage } from '../../../utils/error.js';
|
|
20
20
|
import { stableDigest } from '../../../utils/hash.js';
|
|
21
21
|
import { generateMessageId } from '../../../utils/id.js';
|
|
22
22
|
import { parseStructuredResultJson } from '../../../utils/structured-result-json.js';
|
|
23
23
|
import { createCallbackInference } from '../callback-inference.js';
|
|
24
|
+
import { SandboxAcquisitionStopped } from '../deferred-sandbox.js';
|
|
24
25
|
import { deliverDurableInbound } from '../durable-inbound.js';
|
|
25
26
|
import { projectObservationContext } from '../observation-context.js';
|
|
26
27
|
import { applyLifecycleHookResults } from '../plugin-hooks.js';
|
|
@@ -31,12 +32,14 @@ import { parseNativeCandidate } from './native-output.js';
|
|
|
31
32
|
import { drainArrivedTaskCompletions, holdForOutstandingWork, settleOutstandingWork, } from './outstanding-work.js';
|
|
32
33
|
import { runAdvisoryPhase } from './phases/advisory.js';
|
|
33
34
|
import { runIterationCheckpoint } from './phases/checkpoint.js';
|
|
34
|
-
import {
|
|
35
|
+
import { compactionBreaker } from './phases/compaction-breaker.js';
|
|
36
|
+
import { AUTOMATIC_COMPACTION_FAILED, OVERFLOW_RELIEF_LIMIT, activeContextWindow, clearCompactionErrorNote, compactionErrorNote, measureContext, relieveOverflow, runCompactionCheck, stopOnRefill, } from './phases/compaction.js';
|
|
35
37
|
import { runHandoffPause } from './phases/handoff.js';
|
|
36
38
|
import { runPlanGate } from './phases/plan.js';
|
|
37
39
|
import { runToolReview } from './phases/tool-review.js';
|
|
38
40
|
import { refreshWorkingMemory, splitWorkingMemoryForRequest } from './phases/working-memory.js';
|
|
39
|
-
import { streamWithProviderRejectedImageRecovery } from './provider-rejected-image.js';
|
|
41
|
+
import { streamWithProviderRejectedImageRecovery, } from './provider-rejected-image.js';
|
|
42
|
+
import { RequestRepair } from './request-repair.js';
|
|
40
43
|
import { appendWorkContext, beforeStep, prepareStep, selectContextModel, stepContextMessage, } from './step-shaping.js';
|
|
41
44
|
import { streamProviderTurn } from './stream-turn.js';
|
|
42
45
|
/** A host reviewer is not the model transport, even when its cause is an HTTP failure. */
|
|
@@ -60,10 +63,18 @@ class AnswerReviewFailure extends NamzuError {
|
|
|
60
63
|
* on the thing that actually went wrong.
|
|
61
64
|
*/
|
|
62
65
|
const DEFAULT_ANSWER_REVIEW_LIMIT = 3;
|
|
66
|
+
/** Left unused when an output cap is shrunk to fit the window (reference: 1000). */
|
|
67
|
+
const OUTPUT_CAP_MARGIN_TOKENS = 1000;
|
|
68
|
+
/** A shrunk output cap below this is not worth a call (reference floor: 3000). */
|
|
69
|
+
const MIN_OUTPUT_CAP_TOKENS = 3000;
|
|
63
70
|
// Ending a turn changes the available actions, not the strength of its evidence.
|
|
64
71
|
// Use the same standard for warning closure and empty-completion recovery.
|
|
65
72
|
const CLOSING_RESPONSE_GUIDANCE = 'Give a concise response using only what the available evidence supports. Attribute unverified statements to their source instead of presenting them as observed facts. If evidence is missing or conflicting, state what cannot be established. Do not claim unfinished work is complete. Do not request any more tool calls.';
|
|
66
73
|
export { awaitedJobGraceMs, settleGraceMs } from './outstanding-work.js';
|
|
74
|
+
/** One provider's model, as {@link IterationOrchestrator} remembers it. */
|
|
75
|
+
function textOnlyKey(providerId, model) {
|
|
76
|
+
return `${providerId}\u0000${model}`;
|
|
77
|
+
}
|
|
67
78
|
export class IterationOrchestrator {
|
|
68
79
|
ctx;
|
|
69
80
|
advisoryTurn;
|
|
@@ -98,6 +109,68 @@ export class IterationOrchestrator {
|
|
|
98
109
|
}
|
|
99
110
|
/** Rich tool blocks already reported; durable history is scanned every turn. */
|
|
100
111
|
warnedRichToolResults = new Set();
|
|
112
|
+
/** What this run has learned about requests its provider rejects as invalid, and how to repair them. */
|
|
113
|
+
requestRepair = new RequestRepair({
|
|
114
|
+
debug: (message) => this.ctx.log.debug(message),
|
|
115
|
+
onMediaRemoved: (removal) => this.noteMediaRemoved(removal),
|
|
116
|
+
servedBy: () => this.ctx.servingMember?.(),
|
|
117
|
+
});
|
|
118
|
+
/**
|
|
119
|
+
* Provider and model pairs that refused a request for holding an image; they
|
|
120
|
+
* get none for the rest of the run. Keyed by both: one model id can be served
|
|
121
|
+
* by two members of a fallback chain, and only the one that refused is known.
|
|
122
|
+
*/
|
|
123
|
+
textOnlyModels = new Set();
|
|
124
|
+
/**
|
|
125
|
+
* The member a request for `model` goes to first. A fallback chain keeps
|
|
126
|
+
* serving from the member it last moved to, so that member, not the head,
|
|
127
|
+
* is the one whose reading of images counts.
|
|
128
|
+
*/
|
|
129
|
+
servingModel(model) {
|
|
130
|
+
const serving = this.ctx.servingMember?.();
|
|
131
|
+
return {
|
|
132
|
+
providerId: serving?.providerId ?? this.ctx.provider.id,
|
|
133
|
+
model: serving?.model ?? model,
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
/** Whether a request for `model` may carry images: the driver's catalogue and this run's own evidence agree. */
|
|
137
|
+
modelReadsImages(model) {
|
|
138
|
+
const serving = this.servingModel(model);
|
|
139
|
+
return (!this.textOnlyModels.has(textOnlyKey(serving.providerId, serving.model)) &&
|
|
140
|
+
modelReadsImages(this.ctx.provider, model));
|
|
141
|
+
}
|
|
142
|
+
/** What a request for `model` does when its model turns out to read text only. */
|
|
143
|
+
textOnlyRecovery(model) {
|
|
144
|
+
return {
|
|
145
|
+
servedBy: () => this.servingModel(model),
|
|
146
|
+
onAccepted: (refused) => this.noteTextOnlyModel(refused),
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* A provider refused a request for holding an image its model cannot read, and
|
|
151
|
+
* the retry without images was accepted. Stop sending images to it, and say so
|
|
152
|
+
* once, so the host can remember the model beyond this run.
|
|
153
|
+
*/
|
|
154
|
+
async noteTextOnlyModel(refused) {
|
|
155
|
+
const key = textOnlyKey(refused.providerId, refused.model ?? '');
|
|
156
|
+
if (this.textOnlyModels.has(key))
|
|
157
|
+
return;
|
|
158
|
+
this.textOnlyModels.add(key);
|
|
159
|
+
const { providerId, model } = refused;
|
|
160
|
+
this.ctx.log.warn('Capability mismatch: the model cannot read images', {
|
|
161
|
+
[GENAI.SYSTEM]: providerId,
|
|
162
|
+
[GENAI.REQUEST_MODEL]: model ?? '',
|
|
163
|
+
});
|
|
164
|
+
await this.ctx.emitEvent?.({
|
|
165
|
+
type: 'capability_warning',
|
|
166
|
+
turnId: this.ctx.recorder.turnId,
|
|
167
|
+
capability: 'vision',
|
|
168
|
+
contentSource: 'history',
|
|
169
|
+
providerId,
|
|
170
|
+
...(model !== undefined ? { model } : {}),
|
|
171
|
+
message: `Model '${model ?? 'unknown'}' on provider '${providerId}' refused a request that held an image, so images are left out of its requests. They stay in the conversation and are sent again to a model that reads them.`,
|
|
172
|
+
});
|
|
173
|
+
}
|
|
101
174
|
/**
|
|
102
175
|
* The previous iteration held a `stopWhen` decision open for a worker.
|
|
103
176
|
*
|
|
@@ -113,6 +186,67 @@ export class IterationOrchestrator {
|
|
|
113
186
|
* sets it.
|
|
114
187
|
*/
|
|
115
188
|
stopDeferredForOutstandingWork = false;
|
|
189
|
+
/** Nudges sent since the model last finished a call without hitting its output cap. */
|
|
190
|
+
outputContinuations = 0;
|
|
191
|
+
/**
|
|
192
|
+
* `turn_end` (and, for a child, `subagent_stop`) fired when the model
|
|
193
|
+
* finished and no hook asked for more. `finalizeTurn` then does not fire
|
|
194
|
+
* them a second time.
|
|
195
|
+
*/
|
|
196
|
+
turnEndFired = false;
|
|
197
|
+
/** A hook already kept this turn going once: it is asked again with `stop_hook_active`. */
|
|
198
|
+
stopHookActive = false;
|
|
199
|
+
get turnEndHooksFired() {
|
|
200
|
+
return this.turnEndFired;
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Fire `turn_end` (and `subagent_stop` for a child) at the point the model
|
|
204
|
+
* has finished, and read the answer.
|
|
205
|
+
*
|
|
206
|
+
* A hook that answers `skip` is refusing to let the turn end: its reasons
|
|
207
|
+
* are returned, joined, as feedback for the model. A hook that asks for the
|
|
208
|
+
* turn to halt wins over any such feedback (`takeHalt`). With nothing asked,
|
|
209
|
+
* the events have fired for this turn and the finalizer does not repeat them.
|
|
210
|
+
*/
|
|
211
|
+
async *askStopHooks() {
|
|
212
|
+
const manager = this.ctx.pluginManager;
|
|
213
|
+
if (!manager)
|
|
214
|
+
return undefined;
|
|
215
|
+
const recorder = this.ctx.recorder;
|
|
216
|
+
const feedback = [];
|
|
217
|
+
const ask = async (event, extra) => {
|
|
218
|
+
const results = await manager.executeHooks(event, {
|
|
219
|
+
sessionId: recorder.sessionId,
|
|
220
|
+
turnId: recorder.turnId,
|
|
221
|
+
...extra,
|
|
222
|
+
...(this.stopHookActive ? { stopHookActive: true } : {}),
|
|
223
|
+
signal: this.ctx.abortController.signal,
|
|
224
|
+
}, this.ctx.emitEvent);
|
|
225
|
+
applyLifecycleHookResults(event, results);
|
|
226
|
+
for (const result of results) {
|
|
227
|
+
if (result.action === 'skip')
|
|
228
|
+
feedback.push(result.reason);
|
|
229
|
+
if ((result.action === 'continue' || result.action === 'skip') && result.halt) {
|
|
230
|
+
this.ctx.toolExecutor.requestHalt?.(result.halt.reason);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
};
|
|
234
|
+
await ask('turn_end', {});
|
|
235
|
+
yield* this.ctx.drainPending();
|
|
236
|
+
if (this.ctx.parentSessionId !== undefined) {
|
|
237
|
+
await ask('subagent_stop', {
|
|
238
|
+
parentSessionId: this.ctx.parentSessionId,
|
|
239
|
+
...(this.ctx.parentTurnId !== undefined ? { parentTurnId: this.ctx.parentTurnId } : {}),
|
|
240
|
+
});
|
|
241
|
+
yield* this.ctx.drainPending();
|
|
242
|
+
}
|
|
243
|
+
if (feedback.length === 0) {
|
|
244
|
+
this.turnEndFired = true;
|
|
245
|
+
return undefined;
|
|
246
|
+
}
|
|
247
|
+
this.stopHookActive = true;
|
|
248
|
+
return feedback.join('\n');
|
|
249
|
+
}
|
|
116
250
|
/** One current input, independent of the compactable history array. */
|
|
117
251
|
latestUserMessage;
|
|
118
252
|
initialDurableDelivered = false;
|
|
@@ -264,16 +398,22 @@ export class IterationOrchestrator {
|
|
|
264
398
|
// paused it. Taken after the intent above is known, so the
|
|
265
399
|
// checkpoint names the message the turn is answering.
|
|
266
400
|
await this.ctx.checkpointMgr.markLoopStart?.(recorder);
|
|
267
|
-
//
|
|
401
|
+
// Context-overflow relief is a two-rung ladder per *stuck point*, not per
|
|
402
|
+
// turn, as in the reference terminal (at most two reactive compactions per
|
|
403
|
+
// overflow): the first relief, then one deeper pass if the retry still
|
|
404
|
+
// overflows.
|
|
268
405
|
//
|
|
269
|
-
// The
|
|
270
|
-
//
|
|
271
|
-
//
|
|
272
|
-
//
|
|
273
|
-
//
|
|
274
|
-
//
|
|
275
|
-
//
|
|
276
|
-
let
|
|
406
|
+
// The limit exists so that an overflow that survives both rungs — an
|
|
407
|
+
// irreducible prompt — stops instead of looping. It was never meant to
|
|
408
|
+
// disarm the mechanism for the rest of the turn, which is what a
|
|
409
|
+
// turn-scoped flag did: one relief at iteration 3 left iteration 40 to die
|
|
410
|
+
// on an overflow with obvious moves left. The count is cleared by a turn
|
|
411
|
+
// that actually succeeded, which is the evidence that the turn is no
|
|
412
|
+
// longer stuck.
|
|
413
|
+
let overflowReliefs = 0;
|
|
414
|
+
// The output cap a provider told us fits beside this prompt. One request's
|
|
415
|
+
// worth: it is cleared by a call that went through.
|
|
416
|
+
let outputCapOverride;
|
|
277
417
|
// A `finally` rather than a line at each exit, for the reason written
|
|
278
418
|
// beside `iterSpan.end()` below: this loop leaves by eight `break`s,
|
|
279
419
|
// two `return`s and a `throw`, and a rule every future edit has to
|
|
@@ -446,12 +586,16 @@ export class IterationOrchestrator {
|
|
|
446
586
|
applyLifecycleHookResults('iteration_start', hookResults);
|
|
447
587
|
yield* this.ctx.drainPending();
|
|
448
588
|
}
|
|
589
|
+
if (!forceFinalize)
|
|
590
|
+
await this.deliverReminders(iterationNum);
|
|
449
591
|
// Re-pin the working-memory block from ground truth at the primacy
|
|
450
592
|
// edge BEFORE compaction runs (so the refreshed slot is what
|
|
451
593
|
// compaction preserves). No-op when no provider is configured.
|
|
452
594
|
await refreshWorkingMemory(this.ctx);
|
|
453
595
|
await runCompactionCheck(this.ctx);
|
|
454
596
|
yield* this.ctx.drainPending();
|
|
597
|
+
if (this.stopForCompactionBreaker())
|
|
598
|
+
break;
|
|
455
599
|
// Cache discipline: keep the tools param byte-stable even on the
|
|
456
600
|
// forced-final iteration and forbid tool use via tool_choice
|
|
457
601
|
// 'none' instead. Dropping the tools array would invalidate the
|
|
@@ -498,6 +642,8 @@ export class IterationOrchestrator {
|
|
|
498
642
|
await runCompactionCheck(this.ctx);
|
|
499
643
|
// Publish context edits before entering a possibly slow provider.
|
|
500
644
|
yield* this.ctx.drainPending();
|
|
645
|
+
if (this.stopForCompactionBreaker())
|
|
646
|
+
break;
|
|
501
647
|
const stepAllowedTools = step.allowedTools ?? this.ctx.allowedTools;
|
|
502
648
|
const deferredMcpContext = deferredMcpHints?.forNames(stepAllowedTools) ?? '';
|
|
503
649
|
const contextText = [
|
|
@@ -587,7 +733,7 @@ export class IterationOrchestrator {
|
|
|
587
733
|
if (step.context)
|
|
588
734
|
requestHistory.push(stepContextMessage(step.context));
|
|
589
735
|
const messages = projectRequestRichContent(this.projectObservations(requestHistory), this.ctx.turnConfig.maxRequestRichContentBytes ??
|
|
590
|
-
DEFAULT_MAX_REQUEST_RICH_CONTENT_BYTES);
|
|
736
|
+
DEFAULT_MAX_REQUEST_RICH_CONTENT_BYTES, { imagesReadable: this.modelReadsImages(stepModel) });
|
|
591
737
|
appendWorkContext(shaping, messages, iterationNum, step);
|
|
592
738
|
if (closingDirective)
|
|
593
739
|
messages.push(closingDirective);
|
|
@@ -660,7 +806,7 @@ export class IterationOrchestrator {
|
|
|
660
806
|
messages: Object.freeze(messages.map((m) => Object.freeze({ ...m }))),
|
|
661
807
|
toolNames: Object.freeze(llmTools.map((t) => t.function.name)),
|
|
662
808
|
temperature: step.temperature ?? turnConfig.temperature,
|
|
663
|
-
maxTokens: step.maxResponseTokens ?? turnConfig.maxResponseTokens,
|
|
809
|
+
maxTokens: outputCapOverride ?? step.maxResponseTokens ?? turnConfig.maxResponseTokens,
|
|
664
810
|
}),
|
|
665
811
|
}, this.ctx.emitEvent);
|
|
666
812
|
applyLifecycleHookResults('pre_llm_call', hookResults);
|
|
@@ -726,7 +872,7 @@ export class IterationOrchestrator {
|
|
|
726
872
|
? step.toolChoice
|
|
727
873
|
: undefined,
|
|
728
874
|
temperature: step.temperature ?? turnConfig.temperature,
|
|
729
|
-
maxTokens: step.maxResponseTokens ?? turnConfig.maxResponseTokens,
|
|
875
|
+
maxTokens: outputCapOverride ?? step.maxResponseTokens ?? turnConfig.maxResponseTokens,
|
|
730
876
|
cacheControl: { type: 'auto' },
|
|
731
877
|
...(turnConfig.thinking ? { thinking: turnConfig.thinking } : {}),
|
|
732
878
|
...(turnConfig.effort ? { effort: turnConfig.effort } : {}),
|
|
@@ -739,6 +885,8 @@ export class IterationOrchestrator {
|
|
|
739
885
|
signal: this.ctx.abortController.signal,
|
|
740
886
|
}, this.ctx.emitEvent, this.ctx.drainPending, recorder.turnId, iterationNum, forceFinalize, this.ctx.log, iterSpan, stepMessageId, {
|
|
741
887
|
onAccepted: (identity) => this.acceptProviderRejectedImage(identity),
|
|
888
|
+
textOnly: this.textOnlyRecovery(stepModel),
|
|
889
|
+
repair: this.requestRepair,
|
|
742
890
|
}, Boolean(this.ctx.reviewAnswer || this.ctx.structuredOutput?.review || this.ctx.advisoryCtx), recorder.sessionId);
|
|
743
891
|
stepResponse = response;
|
|
744
892
|
const reviewRequest = {
|
|
@@ -784,7 +932,11 @@ export class IterationOrchestrator {
|
|
|
784
932
|
});
|
|
785
933
|
// The turn went through, so the turn is not sitting on an
|
|
786
934
|
// irreducible prompt any more. Re-arm relief for the next one.
|
|
787
|
-
|
|
935
|
+
overflowReliefs = 0;
|
|
936
|
+
clearCompactionErrorNote(this.ctx);
|
|
937
|
+
outputCapOverride = undefined;
|
|
938
|
+
if (response.finishReason !== 'length')
|
|
939
|
+
this.outputContinuations = 0;
|
|
788
940
|
if (this.ctx.pluginManager) {
|
|
789
941
|
const hookResults = await this.ctx.pluginManager.executeHooks('post_llm_call', {
|
|
790
942
|
sessionId: recorder.sessionId,
|
|
@@ -1055,16 +1207,43 @@ export class IterationOrchestrator {
|
|
|
1055
1207
|
// it has no room left to continue into, and the
|
|
1056
1208
|
// continuation would only send a longer prompt into
|
|
1057
1209
|
// the same full window. The reply stands as it is.
|
|
1210
|
+
const cutDuringReasoning = !hasContent &&
|
|
1211
|
+
(response.message.toolCalls?.length ?? 0) === 0 &&
|
|
1212
|
+
(response.message.reasoning?.length ?? 0) > 0;
|
|
1058
1213
|
if (!forceFinalize &&
|
|
1059
1214
|
response.finishReason === 'length' &&
|
|
1060
1215
|
response.finishDetail !== 'context_window' &&
|
|
1061
|
-
hasContent) {
|
|
1062
|
-
|
|
1216
|
+
(hasContent || cutDuringReasoning)) {
|
|
1217
|
+
// A host that opted in gets a cap on the nudges: a model that
|
|
1218
|
+
// overruns its output limit every time would otherwise spend the
|
|
1219
|
+
// whole turn on it. Past the cap the turn stops, and says why.
|
|
1220
|
+
const cap = this.ctx.maxOutputContinuations;
|
|
1221
|
+
if (cap !== undefined && this.outputContinuations >= cap) {
|
|
1222
|
+
this.ctx.log.warn('LLM kept hitting max_tokens — stopping the turn', {
|
|
1223
|
+
[NAMZU.TURN_ID]: recorder.turnId,
|
|
1224
|
+
[NAMZU.ITERATION]: iterationNum,
|
|
1225
|
+
'namzu.runtime.output_continuations': this.outputContinuations,
|
|
1226
|
+
});
|
|
1227
|
+
recorder.setLastError(`The reply was cut off at the output limit ${cap + 1} times in a row. Ask for a smaller piece of the work, or raise the output limit.`);
|
|
1228
|
+
recorder.setStopReason('output_limit');
|
|
1229
|
+
await this.ctx.emitEvent({
|
|
1230
|
+
type: 'iteration_completed',
|
|
1231
|
+
turnId: recorder.turnId,
|
|
1232
|
+
iteration: iterationNum,
|
|
1233
|
+
hasToolCalls: false,
|
|
1234
|
+
});
|
|
1235
|
+
yield* this.ctx.drainPending();
|
|
1236
|
+
break;
|
|
1237
|
+
}
|
|
1238
|
+
this.outputContinuations++;
|
|
1239
|
+
this.ctx.log.info(cutDuringReasoning
|
|
1240
|
+
? 'LLM hit max_tokens while reasoning — nudging to answer briefly'
|
|
1241
|
+
: 'LLM hit max_tokens mid-text — auto-continuing', {
|
|
1063
1242
|
[NAMZU.TURN_ID]: recorder.turnId,
|
|
1064
1243
|
[NAMZU.ITERATION]: iterationNum,
|
|
1065
1244
|
[GENAI.USAGE_OUTPUT_TOKENS]: response.usage.completionTokens,
|
|
1066
1245
|
});
|
|
1067
|
-
recorder.pushMessage(createRuntimeContextMessage(AUTO_CONTINUATION_USER_MESSAGE, 'auto-continuation'));
|
|
1246
|
+
recorder.pushMessage(createRuntimeContextMessage(cutDuringReasoning ? REASONING_CUT_USER_MESSAGE : AUTO_CONTINUATION_USER_MESSAGE, 'auto-continuation'));
|
|
1068
1247
|
await this.ctx.emitEvent({
|
|
1069
1248
|
type: 'iteration_completed',
|
|
1070
1249
|
turnId: recorder.turnId,
|
|
@@ -1206,6 +1385,22 @@ export class IterationOrchestrator {
|
|
|
1206
1385
|
// also settle as `end_turn`, and there the deferred predicate
|
|
1207
1386
|
// is not why the turn ended: those decided the answer
|
|
1208
1387
|
// themselves.
|
|
1388
|
+
// The model is done and has no tool calls. A `turn_end` (or
|
|
1389
|
+
// `subagent_stop`) hook may refuse to let it be: its reason goes
|
|
1390
|
+
// back to the model and the turn goes on.
|
|
1391
|
+
if (!forceFinalize && closingStopReason === undefined) {
|
|
1392
|
+
const feedback = yield* this.askStopHooks();
|
|
1393
|
+
const stoppedByHook = this.ctx.toolExecutor.takeHalt?.();
|
|
1394
|
+
if (stoppedByHook !== undefined) {
|
|
1395
|
+
recorder.setLastError(`Stopped by a hook: ${stoppedByHook}`);
|
|
1396
|
+
recorder.setStopReason('stop_condition');
|
|
1397
|
+
break;
|
|
1398
|
+
}
|
|
1399
|
+
if (feedback !== undefined) {
|
|
1400
|
+
recorder.pushMessage(createRuntimeContextMessage(`A hook asked for more before this turn ends:\n${feedback}`, 'hook-feedback'));
|
|
1401
|
+
continue;
|
|
1402
|
+
}
|
|
1403
|
+
}
|
|
1209
1404
|
recorder.setStopReason(closingStopReason ??
|
|
1210
1405
|
(stopWasDeferredForOutstandingWork ? 'stop_condition' : 'end_turn'));
|
|
1211
1406
|
break;
|
|
@@ -1240,6 +1435,27 @@ export class IterationOrchestrator {
|
|
|
1240
1435
|
if ((yield* runHandoffPause(this.ctx, iterationNum, reviewOutcome.results)) === 'stop') {
|
|
1241
1436
|
return;
|
|
1242
1437
|
}
|
|
1438
|
+
// A hook asked for the turn to stop once this step's calls were
|
|
1439
|
+
// answered. Every `tool_use` has its `tool_result` by now, so the
|
|
1440
|
+
// transcript is whole; what is left is to end the turn and say why.
|
|
1441
|
+
const hookHalt = this.ctx.toolExecutor.takeHalt?.();
|
|
1442
|
+
if (hookHalt !== undefined) {
|
|
1443
|
+
this.ctx.log.info('A hook stopped the turn', {
|
|
1444
|
+
[NAMZU.TURN_ID]: recorder.turnId,
|
|
1445
|
+
[NAMZU.ITERATION]: iterationNum,
|
|
1446
|
+
'namzu.hook.reason': hookHalt,
|
|
1447
|
+
});
|
|
1448
|
+
recorder.setLastError(`Stopped by a hook: ${hookHalt}`);
|
|
1449
|
+
recorder.setStopReason('stop_condition');
|
|
1450
|
+
await this.ctx.emitEvent({
|
|
1451
|
+
type: 'iteration_completed',
|
|
1452
|
+
turnId: recorder.turnId,
|
|
1453
|
+
iteration: iterationNum,
|
|
1454
|
+
hasToolCalls: true,
|
|
1455
|
+
});
|
|
1456
|
+
yield* this.ctx.drainPending();
|
|
1457
|
+
break;
|
|
1458
|
+
}
|
|
1243
1459
|
if (reviewOutcome.decision === 'rejected') {
|
|
1244
1460
|
continue;
|
|
1245
1461
|
}
|
|
@@ -1449,6 +1665,12 @@ export class IterationOrchestrator {
|
|
|
1449
1665
|
}
|
|
1450
1666
|
catch (err) {
|
|
1451
1667
|
const cancelled = this.ctx.abortController.signal.aborted;
|
|
1668
|
+
// A deferred sandbox that was cancelled or ran out of time. The
|
|
1669
|
+
// turn settles it as `cancelled` / `timeout` in `query()`, which is
|
|
1670
|
+
// not a failure of this iteration: it is recorded the way a turn
|
|
1671
|
+
// stopped by its own abort or timeout is (a cancelled step, no
|
|
1672
|
+
// error span), so the ledger and the stop reason agree.
|
|
1673
|
+
const sandboxStopped = err instanceof SandboxAcquisitionStopped;
|
|
1452
1674
|
// This iteration gets a step too, and it is the one the
|
|
1453
1675
|
// argument three hundred lines above was actually about.
|
|
1454
1676
|
//
|
|
@@ -1509,7 +1731,7 @@ export class IterationOrchestrator {
|
|
|
1509
1731
|
startedAt: stepStartedAt,
|
|
1510
1732
|
usageBefore,
|
|
1511
1733
|
costBefore,
|
|
1512
|
-
unfinished: cancelled
|
|
1734
|
+
unfinished: cancelled || sandboxStopped
|
|
1513
1735
|
? { finishReason: 'cancelled' }
|
|
1514
1736
|
: {
|
|
1515
1737
|
finishReason: 'error',
|
|
@@ -1541,21 +1763,82 @@ export class IterationOrchestrator {
|
|
|
1541
1763
|
// actually shed something. A second overflow after a successful
|
|
1542
1764
|
// compaction means the prompt is irreducible, and looping on it
|
|
1543
1765
|
// would burn the budget to arrive at the same error.
|
|
1544
|
-
|
|
1545
|
-
|
|
1766
|
+
// The prompt fit and only the requested output did not: ask for what
|
|
1767
|
+
// room is left (less a margin) and send it again, once. A reply that
|
|
1768
|
+
// would be too small to be useful, or a cap that is not smaller than
|
|
1769
|
+
// the one already tried, is not retried: the same failure would follow.
|
|
1770
|
+
const outputOverflow = err instanceof AnswerReviewFailure ? undefined : readOutputOverflow(err);
|
|
1771
|
+
if (outputOverflow) {
|
|
1772
|
+
const room = Math.max(0, outputOverflow.contextLimit - outputOverflow.inputTokens - OUTPUT_CAP_MARGIN_TOKENS);
|
|
1773
|
+
if (room >= MIN_OUTPUT_CAP_TOKENS &&
|
|
1774
|
+
(outputCapOverride === undefined || room < outputCapOverride)) {
|
|
1775
|
+
outputCapOverride = room;
|
|
1776
|
+
this.ctx.log.info('Output cap does not fit beside the prompt — retrying with less', {
|
|
1777
|
+
[NAMZU.TURN_ID]: recorder.turnId,
|
|
1778
|
+
[NAMZU.ITERATION]: iterationNum,
|
|
1779
|
+
'namzu.runtime.input_tokens': outputOverflow.inputTokens,
|
|
1780
|
+
'namzu.runtime.context_limit': outputOverflow.contextLimit,
|
|
1781
|
+
'namzu.runtime.adjusted_max_tokens': room,
|
|
1782
|
+
});
|
|
1783
|
+
if (iterationActivity) {
|
|
1784
|
+
this.ctx.activityStore.complete(iterationActivity.id);
|
|
1785
|
+
}
|
|
1786
|
+
continue;
|
|
1787
|
+
}
|
|
1788
|
+
}
|
|
1789
|
+
if (!(err instanceof AnswerReviewFailure) &&
|
|
1546
1790
|
classifyProviderError(err, this.ctx.provider.id).code === 'context_length_exceeded') {
|
|
1547
|
-
|
|
1548
|
-
|
|
1791
|
+
// The rapid-refill check comes first, before the first reactive relief
|
|
1792
|
+
// of an overflow, as in the reference terminal. A relief that follows
|
|
1793
|
+
// the previous compaction within the refill window counts toward the
|
|
1794
|
+
// limit, so a tool that re-fills the window every time it is called
|
|
1795
|
+
// stops the turn instead of being cleared and called again without end.
|
|
1796
|
+
// The deeper rung of the same overflow is not counted again.
|
|
1797
|
+
if (overflowReliefs === 0 && (await stopOnRefill(this.ctx))) {
|
|
1798
|
+
if (iterationActivity) {
|
|
1799
|
+
this.ctx.activityStore.fail(iterationActivity.id, toErrorMessage(err));
|
|
1800
|
+
}
|
|
1801
|
+
if (this.stopForCompactionBreaker())
|
|
1802
|
+
break;
|
|
1803
|
+
}
|
|
1804
|
+
// A rung that sheds too little to change the verdict is not worth a
|
|
1805
|
+
// provider call; climb to the next one at once.
|
|
1806
|
+
let shed = false;
|
|
1807
|
+
while (!shed && overflowReliefs < OVERFLOW_RELIEF_LIMIT) {
|
|
1808
|
+
overflowReliefs++;
|
|
1809
|
+
shed = await relieveOverflow(this.ctx, { deeper: overflowReliefs > 1 });
|
|
1810
|
+
}
|
|
1549
1811
|
if (shed) {
|
|
1812
|
+
// Clearing results is a compaction too: only summaries and reducers
|
|
1813
|
+
// recorded themselves, so a clear-only relief was invisible to the
|
|
1814
|
+
// breaker.
|
|
1815
|
+
compactionBreaker(this.ctx)?.recordCompaction(iterationNum);
|
|
1550
1816
|
this.ctx.log.info('Retrying the turn after relieving a context overflow', {
|
|
1551
1817
|
[NAMZU.TURN_ID]: recorder.turnId,
|
|
1552
1818
|
[NAMZU.ITERATION]: iterationNum,
|
|
1819
|
+
'namzu.runtime.relief_rung': overflowReliefs,
|
|
1553
1820
|
});
|
|
1554
1821
|
if (iterationActivity) {
|
|
1555
1822
|
this.ctx.activityStore.complete(iterationActivity.id);
|
|
1556
1823
|
}
|
|
1557
1824
|
continue;
|
|
1558
1825
|
}
|
|
1826
|
+
// Out of rungs. The conversation is kept; say why compaction could not
|
|
1827
|
+
// make room when it errored, as the reference does.
|
|
1828
|
+
const cause = compactionErrorNote(this.ctx);
|
|
1829
|
+
if (cause !== undefined && err instanceof Error) {
|
|
1830
|
+
try {
|
|
1831
|
+
err.message = `${err.message}${AUTOMATIC_COMPACTION_FAILED}${cause}`;
|
|
1832
|
+
}
|
|
1833
|
+
catch {
|
|
1834
|
+
// A frozen error keeps its own message; the cause stays in the log.
|
|
1835
|
+
}
|
|
1836
|
+
}
|
|
1837
|
+
}
|
|
1838
|
+
if (sandboxStopped) {
|
|
1839
|
+
if (iterationActivity)
|
|
1840
|
+
this.ctx.activityStore.complete(iterationActivity.id);
|
|
1841
|
+
throw err;
|
|
1559
1842
|
}
|
|
1560
1843
|
if (iterationActivity) {
|
|
1561
1844
|
this.ctx.activityStore.fail(iterationActivity.id, toErrorMessage(err));
|
|
@@ -1639,6 +1922,41 @@ export class IterationOrchestrator {
|
|
|
1639
1922
|
extractFromUserMessage(manager, message.content, !manager.getState().task);
|
|
1640
1923
|
}
|
|
1641
1924
|
}
|
|
1925
|
+
/**
|
|
1926
|
+
* Ask the host's reminder source (`QueryParams.reminders`) what the model
|
|
1927
|
+
* should be told before this request, and append each text as a hidden
|
|
1928
|
+
* user-role message. The start of a request is a provider-valid boundary:
|
|
1929
|
+
* the history ends in the operator's message or in a finished tool batch.
|
|
1930
|
+
* A source that throws has nothing to say; it never fails the turn.
|
|
1931
|
+
*/
|
|
1932
|
+
async deliverReminders(iteration) {
|
|
1933
|
+
const source = this.ctx.reminders;
|
|
1934
|
+
if (!source)
|
|
1935
|
+
return;
|
|
1936
|
+
const { recorder } = this.ctx;
|
|
1937
|
+
let texts;
|
|
1938
|
+
try {
|
|
1939
|
+
texts = await source({
|
|
1940
|
+
sessionId: recorder.sessionId,
|
|
1941
|
+
turnId: recorder.turnId,
|
|
1942
|
+
iteration,
|
|
1943
|
+
messages: recorder.messages,
|
|
1944
|
+
});
|
|
1945
|
+
}
|
|
1946
|
+
catch (error) {
|
|
1947
|
+
this.ctx.log.warn('A reminder source threw; the request goes without its reminders', {
|
|
1948
|
+
[NAMZU.TURN_ID]: recorder.turnId,
|
|
1949
|
+
[NAMZU.ITERATION]: iteration,
|
|
1950
|
+
'exception.message': error instanceof Error ? error.message : String(error),
|
|
1951
|
+
});
|
|
1952
|
+
return;
|
|
1953
|
+
}
|
|
1954
|
+
for (const text of texts ?? []) {
|
|
1955
|
+
if (text.trim().length === 0)
|
|
1956
|
+
continue;
|
|
1957
|
+
recorder.pushMessage(createRuntimeContextMessage(text, 'reminder'));
|
|
1958
|
+
}
|
|
1959
|
+
}
|
|
1642
1960
|
async deliverInbound() {
|
|
1643
1961
|
const queued = this.ctx.inboundMessages?.() ?? [];
|
|
1644
1962
|
for (const message of queued) {
|
|
@@ -1756,6 +2074,15 @@ export class IterationOrchestrator {
|
|
|
1756
2074
|
recorder.setStopReason('structured_output_failed');
|
|
1757
2075
|
return true;
|
|
1758
2076
|
}
|
|
2077
|
+
/** The compaction circuit breaker asked for the turn to stop (opt-in; see `compactionConfig.circuitBreaker`). */
|
|
2078
|
+
stopForCompactionBreaker() {
|
|
2079
|
+
const reason = compactionBreaker(this.ctx)?.stop;
|
|
2080
|
+
if (reason === undefined)
|
|
2081
|
+
return false;
|
|
2082
|
+
this.ctx.recorder.setLastError(reason);
|
|
2083
|
+
this.ctx.recorder.setStopReason('error');
|
|
2084
|
+
return true;
|
|
2085
|
+
}
|
|
1759
2086
|
async recordToolStructuredFailure(results, iteration) {
|
|
1760
2087
|
if (!this.needsStructuredOutput() ||
|
|
1761
2088
|
this.ctx.structuredOutput?.mode === 'native' ||
|
|
@@ -2048,6 +2375,31 @@ export class IterationOrchestrator {
|
|
|
2048
2375
|
.listTasks()
|
|
2049
2376
|
.some((t) => t.state !== 'completed' && t.state !== 'failed' && t.state !== 'canceled');
|
|
2050
2377
|
}
|
|
2378
|
+
/** Media the provider could not process was left out of a request that then went through. */
|
|
2379
|
+
async noteMediaRemoved(removal) {
|
|
2380
|
+
this.ctx.log.warn('Media the provider rejected was left out of the request', {
|
|
2381
|
+
[GENAI.SYSTEM]: this.ctx.provider.id,
|
|
2382
|
+
'namzu.request.media_removed': removal.count,
|
|
2383
|
+
});
|
|
2384
|
+
const noun = removal.count === 1 ? 'a file' : `${removal.count} files`;
|
|
2385
|
+
const it = removal.count === 1 ? 'it' : 'they';
|
|
2386
|
+
await this.ctx.emitEvent?.({
|
|
2387
|
+
type: 'capability_warning',
|
|
2388
|
+
turnId: this.ctx.recorder.turnId,
|
|
2389
|
+
capability: removal.kind === 'document' ? 'documents' : 'vision',
|
|
2390
|
+
// The person's own latest attachment is named as such; a count limit is
|
|
2391
|
+
// not a fault in any file.
|
|
2392
|
+
contentSource: removal.current
|
|
2393
|
+
? 'media-removed-current'
|
|
2394
|
+
: removal.limit
|
|
2395
|
+
? 'media-limit'
|
|
2396
|
+
: 'media-removed',
|
|
2397
|
+
providerId: this.ctx.provider.id,
|
|
2398
|
+
message: removal.limit
|
|
2399
|
+
? `The conversation holds more files than the provider accepts at once, so ${noun} (the oldest) ${removal.count === 1 ? 'was' : 'were'} left out of the request. The conversation still holds ${it}.`
|
|
2400
|
+
: `The provider could not process ${noun}${removal.current ? ' attached to your latest message' : ' in this conversation'}, so ${it} ${removal.count === 1 ? 'was' : 'were'} left out of the request. The conversation still holds ${it}.`,
|
|
2401
|
+
});
|
|
2402
|
+
}
|
|
2051
2403
|
async acceptProviderRejectedImage(identity) {
|
|
2052
2404
|
const repaired = markProviderRejectedImage(this.ctx.recorder.messages, identity);
|
|
2053
2405
|
if (repaired.count === 0) {
|
|
@@ -2092,7 +2444,7 @@ export class IterationOrchestrator {
|
|
|
2092
2444
|
...workingMemory.history,
|
|
2093
2445
|
...(workingMemory.context ? [workingMemory.context] : []),
|
|
2094
2446
|
];
|
|
2095
|
-
const finalMessages = projectRequestRichContent(this.projectObservations(finalHistory), this.ctx.turnConfig.maxRequestRichContentBytes ?? DEFAULT_MAX_REQUEST_RICH_CONTENT_BYTES);
|
|
2447
|
+
const finalMessages = projectRequestRichContent(this.projectObservations(finalHistory), this.ctx.turnConfig.maxRequestRichContentBytes ?? DEFAULT_MAX_REQUEST_RICH_CONTENT_BYTES, { imagesReadable: this.modelReadsImages(model) });
|
|
2096
2448
|
appendWorkContext(this.stepShaping(), finalMessages, this.steps.length + 1, { model });
|
|
2097
2449
|
// The closing directive is the last thing the model reads: after
|
|
2098
2450
|
// the working memory and any work context above.
|
|
@@ -2131,7 +2483,7 @@ export class IterationOrchestrator {
|
|
|
2131
2483
|
// stream to completion.
|
|
2132
2484
|
signal: this.ctx.abortController.signal,
|
|
2133
2485
|
};
|
|
2134
|
-
const response = await collectChatCompletion(streamWithProviderRejectedImageRecovery(this.ctx.provider, finalParams, (identity) => this.acceptProviderRejectedImage(identity)));
|
|
2486
|
+
const response = await collectChatCompletion(streamWithProviderRejectedImageRecovery(this.ctx.provider, finalParams, (identity) => this.acceptProviderRejectedImage(identity), undefined, this.textOnlyRecovery(model), this.requestRepair));
|
|
2135
2487
|
const servingMember = this.ctx.servingMember?.() ?? requestedMember;
|
|
2136
2488
|
const servedBy = {
|
|
2137
2489
|
providerId: servingMember.providerId,
|