@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
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Two ways automatic compaction gives up for the rest of a turn.
|
|
3
|
+
*
|
|
4
|
+
* - Three failures in a row (a pass that ran and shed nothing): every one of
|
|
5
|
+
* them paid for a summary or a reducer call and left the history as it was,
|
|
6
|
+
* so a fourth would do the same. Proactive compaction is skipped from then on
|
|
7
|
+
* and the turn carries on, silently as far as the person is concerned (a log
|
|
8
|
+
* line and a `breaker_open` event, no sentence); a pass the provider forces
|
|
9
|
+
* by rejecting the prompt is not gated, so the reactive ladder still runs.
|
|
10
|
+
* - Three compactions in a row, each followed by the context filling back up
|
|
11
|
+
* within three iterations: something in the loop (a huge file read, a tool
|
|
12
|
+
* that prints without limit) refills the window faster than any summary can
|
|
13
|
+
* empty it. The turn stops, because carrying on only buys the same wall.
|
|
14
|
+
*
|
|
15
|
+
* Off unless `compactionConfig.circuitBreaker` is true: stopping compaction,
|
|
16
|
+
* and above all stopping a turn, is not something a host had before.
|
|
17
|
+
*
|
|
18
|
+
* State is per turn, held against the turn's recorder, so two turns never
|
|
19
|
+
* share a count.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import type { IterationContext } from './context.js'
|
|
23
|
+
|
|
24
|
+
/** Consecutive failed passes after which automatic compaction stops. */
|
|
25
|
+
export const COMPACTION_FAILURE_LIMIT = 3
|
|
26
|
+
/** A compaction followed by a trigger sooner than this many iterations is a refill. */
|
|
27
|
+
export const COMPACTION_REFILL_ITERATIONS = 3
|
|
28
|
+
/** Consecutive refills that stop the turn. */
|
|
29
|
+
export const COMPACTION_REFILL_LIMIT = 3
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* One short line, shown once, when the turn stops on refills. It names the
|
|
33
|
+
* cause and a step that keeps the conversation: the reference terminal also
|
|
34
|
+
* offers to start over here, and Namzu never does.
|
|
35
|
+
*/
|
|
36
|
+
export const COMPACTION_REFILL_MESSAGE =
|
|
37
|
+
'The context filled up again right after being compacted, three times in a row. A file being read or a tool output is probably too large for the context window. Try reading it in smaller parts.'
|
|
38
|
+
|
|
39
|
+
export class CompactionBreaker {
|
|
40
|
+
private failures = 0
|
|
41
|
+
private refills = 0
|
|
42
|
+
private pendingRefills = 0
|
|
43
|
+
private lastCompactedIteration: number | undefined
|
|
44
|
+
private failureNoticeSent = false
|
|
45
|
+
private stopReason: string | undefined
|
|
46
|
+
|
|
47
|
+
/** Whether three failures in a row have switched automatic compaction off. */
|
|
48
|
+
get failuresOpen(): boolean {
|
|
49
|
+
return this.failures >= COMPACTION_FAILURE_LIMIT
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** Mark the failure notice sent; true the first time only. */
|
|
53
|
+
takeFailureNotice(): boolean {
|
|
54
|
+
if (this.failureNoticeSent) return false
|
|
55
|
+
this.failureNoticeSent = true
|
|
56
|
+
return true
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
recordFailure(): void {
|
|
60
|
+
this.failures++
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** A pass committed an edit; failures start over. */
|
|
64
|
+
recordRelief(): void {
|
|
65
|
+
this.failures = 0
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* A summary or reducer pass is about to run at `iteration`. True when it
|
|
70
|
+
* would be the third refill in a row, in which case it must not run.
|
|
71
|
+
*/
|
|
72
|
+
wouldTrip(iteration: number): boolean {
|
|
73
|
+
const quick =
|
|
74
|
+
this.lastCompactedIteration !== undefined &&
|
|
75
|
+
iteration - this.lastCompactedIteration < COMPACTION_REFILL_ITERATIONS
|
|
76
|
+
this.pendingRefills = quick ? this.refills + 1 : 0
|
|
77
|
+
return this.pendingRefills >= COMPACTION_REFILL_LIMIT
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** The pass that `wouldTrip` allowed completed at `iteration`. */
|
|
81
|
+
recordCompaction(iteration: number): void {
|
|
82
|
+
this.refills = this.pendingRefills
|
|
83
|
+
this.lastCompactedIteration = iteration
|
|
84
|
+
this.recordRelief()
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
stopTurn(message: string): void {
|
|
88
|
+
this.stopReason ??= message
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/** The reason the turn must stop, when a breaker has asked for it. */
|
|
92
|
+
get stop(): string | undefined {
|
|
93
|
+
return this.stopReason
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const breakers = new WeakMap<object, CompactionBreaker>()
|
|
98
|
+
|
|
99
|
+
/** The turn's breaker, or `undefined` when the host did not opt in. */
|
|
100
|
+
export function compactionBreaker(ctx: IterationContext): CompactionBreaker | undefined {
|
|
101
|
+
if (ctx.compactionConfig?.circuitBreaker !== true) return undefined
|
|
102
|
+
let breaker = breakers.get(ctx.recorder)
|
|
103
|
+
if (!breaker) {
|
|
104
|
+
breaker = new CompactionBreaker()
|
|
105
|
+
breakers.set(ctx.recorder, breaker)
|
|
106
|
+
}
|
|
107
|
+
return breaker
|
|
108
|
+
}
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
resolveContextWindow,
|
|
3
|
+
resolveTriggerThreshold,
|
|
4
|
+
} from '../../../../compaction/context-window.js'
|
|
2
5
|
import { findDanglingMessages } from '../../../../compaction/dangling.js'
|
|
3
6
|
import {
|
|
4
7
|
type CompactionPlan,
|
|
@@ -13,12 +16,14 @@ import { serializeState } from '../../../../compaction/serializer.js'
|
|
|
13
16
|
import { buildCompactionMessage, isCompactionMessage } from '../../../../compaction/summary.js'
|
|
14
17
|
import { estimateMessagesTokens } from '../../../../compaction/token-estimate.js'
|
|
15
18
|
import { buildVerifiedSummaryWithBoundedProvider } from '../../../../compaction/verifier.js'
|
|
19
|
+
import type { CompactionConfig } from '../../../../config/runtime.js'
|
|
16
20
|
import { CHARS_PER_TOKEN } from '../../../../constants/limits.js'
|
|
17
21
|
import { NAMZU } from '../../../../constants/telemetry/index.js'
|
|
18
22
|
import { invariants } from '../../../../invariants/index.js'
|
|
19
23
|
import { resolveTaskModel } from '../../../../model-router/task-router.js'
|
|
20
24
|
import type { Message } from '../../../../types/message/index.js'
|
|
21
25
|
import { applyLifecycleHookResults } from '../../plugin-hooks.js'
|
|
26
|
+
import { COMPACTION_REFILL_MESSAGE, compactionBreaker } from './compaction-breaker.js'
|
|
22
27
|
import type { IterationContext } from './context.js'
|
|
23
28
|
import { isWorkingMemoryMessage } from './working-memory.js'
|
|
24
29
|
|
|
@@ -169,6 +174,7 @@ async function commitToolResultClear(
|
|
|
169
174
|
ctx.recorder.clearLastPromptTokens?.()
|
|
170
175
|
await emitToolResultClear(ctx, plan)
|
|
171
176
|
await emitContextUsageSnapshot(ctx, estimateTokens(ctx), contextWindowTokens, windowSource)
|
|
177
|
+
compactionBreaker(ctx)?.recordRelief()
|
|
172
178
|
}
|
|
173
179
|
|
|
174
180
|
/**
|
|
@@ -214,6 +220,73 @@ export function measureContext(ctx: IterationContext): {
|
|
|
214
220
|
return { tokens: estimateTokens(ctx), source: 'estimate' }
|
|
215
221
|
}
|
|
216
222
|
|
|
223
|
+
/**
|
|
224
|
+
* Reactive compactions allowed for one overflow, as in the reference
|
|
225
|
+
* terminal: the first relief, then at most one deeper pass.
|
|
226
|
+
*/
|
|
227
|
+
export const OVERFLOW_RELIEF_LIMIT = 2
|
|
228
|
+
|
|
229
|
+
/** Round-groups that must remain for the deeper pass to be worth running. */
|
|
230
|
+
export const DEEPER_PASS_MIN_GROUPS = 3
|
|
231
|
+
|
|
232
|
+
export interface OverflowReliefOptions {
|
|
233
|
+
/**
|
|
234
|
+
* The second rung. Keep only the newest round-group verbatim instead of the
|
|
235
|
+
* configured recent window (when at least {@link DEEPER_PASS_MIN_GROUPS}
|
|
236
|
+
* groups remain), and clear oversized tool results even inside the recent
|
|
237
|
+
* window, with the same placeholder and spill pointer a stale result gets.
|
|
238
|
+
*/
|
|
239
|
+
readonly deeper?: boolean
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* A round-group starts at each assistant message and runs to the next one, so
|
|
244
|
+
* its tool results stay with the call that made them. The newest group is the
|
|
245
|
+
* last assistant message and everything after it; the opening user messages
|
|
246
|
+
* ride with the first group.
|
|
247
|
+
*/
|
|
248
|
+
function roundGroups(messages: readonly Message[]): number {
|
|
249
|
+
let groups = 0
|
|
250
|
+
for (const message of messages) if (message.role === 'assistant') groups++
|
|
251
|
+
return groups
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* The deeper rung's configuration: no tool result protected, and a recent
|
|
256
|
+
* window no larger than the first rung's. With three or more groups the
|
|
257
|
+
* window shrinks to the newest group, but never grows past what the
|
|
258
|
+
* configuration already kept: a newest group bigger than that would make the
|
|
259
|
+
* "deeper" pass shed less than the first one.
|
|
260
|
+
*/
|
|
261
|
+
export function deepenConfig(
|
|
262
|
+
config: CompactionConfig,
|
|
263
|
+
messages: readonly Message[],
|
|
264
|
+
): CompactionConfig {
|
|
265
|
+
let lastAssistant = -1
|
|
266
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
267
|
+
if (messages[i]?.role === 'assistant') {
|
|
268
|
+
lastAssistant = i
|
|
269
|
+
break
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
const deeper = { ...config, keepRecentToolResults: 0 }
|
|
273
|
+
if (lastAssistant < 0 || roundGroups(messages) < DEEPER_PASS_MIN_GROUPS) return deeper
|
|
274
|
+
const newest = messages.slice(lastAssistant)
|
|
275
|
+
if (config.keepRecentTokens !== undefined) {
|
|
276
|
+
return {
|
|
277
|
+
...deeper,
|
|
278
|
+
keepRecentTokens: Math.max(
|
|
279
|
+
1,
|
|
280
|
+
Math.min(config.keepRecentTokens, estimateMessagesTokens(newest)),
|
|
281
|
+
),
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
return {
|
|
285
|
+
...deeper,
|
|
286
|
+
keepRecentMessages: Math.max(1, Math.min(config.keepRecentMessages, newest.length)),
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
|
|
217
290
|
/**
|
|
218
291
|
* Shed history because the PROVIDER said the prompt is too long.
|
|
219
292
|
*
|
|
@@ -232,12 +305,18 @@ export function measureContext(ctx: IterationContext): {
|
|
|
232
305
|
* @returns whether anything was actually shed. `false` means retrying would
|
|
233
306
|
* send the same prompt again, so the caller must not.
|
|
234
307
|
*/
|
|
235
|
-
export async function relieveOverflow(
|
|
308
|
+
export async function relieveOverflow(
|
|
309
|
+
ctx: IterationContext,
|
|
310
|
+
options: OverflowReliefOptions = {},
|
|
311
|
+
): Promise<boolean> {
|
|
312
|
+
// The cause belongs to the rung that is about to run: an earlier rung's
|
|
313
|
+
// summary failure must not be blamed for a later rung that compacted cleanly.
|
|
314
|
+
clearCompactionErrorNote(ctx)
|
|
236
315
|
const before = ctx.recorder.messages.length
|
|
237
316
|
const beforeChars = totalChars(ctx.recorder.messages)
|
|
238
317
|
const beforeTokens = estimateMessagesTokens(ctx.recorder.messages)
|
|
239
318
|
|
|
240
|
-
await runCompactionCheck(ctx, { force: true })
|
|
319
|
+
await runCompactionCheck(ctx, { force: true, ...(options.deeper ? { deeper: true } : {}) })
|
|
241
320
|
|
|
242
321
|
const shed = beforeChars - totalChars(ctx.recorder.messages)
|
|
243
322
|
const tokensShed = beforeTokens - estimateMessagesTokens(ctx.recorder.messages)
|
|
@@ -269,6 +348,31 @@ export async function relieveOverflow(ctx: IterationContext): Promise<boolean> {
|
|
|
269
348
|
return true
|
|
270
349
|
}
|
|
271
350
|
|
|
351
|
+
/**
|
|
352
|
+
* Why the last compaction attempt errored, kept for the turn so that when
|
|
353
|
+
* relief runs out the failure it ends on can say so, as the reference
|
|
354
|
+
* terminal's " · automatic compaction failed: <cause>" does.
|
|
355
|
+
*/
|
|
356
|
+
const compactionErrors = new WeakMap<object, string>()
|
|
357
|
+
const MAX_COMPACTION_CAUSE_CHARS = 300
|
|
358
|
+
/** The sentence the cause is appended with. */
|
|
359
|
+
export const AUTOMATIC_COMPACTION_FAILED = ' · automatic compaction failed: '
|
|
360
|
+
|
|
361
|
+
function noteCompactionError(ctx: IterationContext, error: unknown): void {
|
|
362
|
+
const text = error instanceof Error ? error.message : String(error)
|
|
363
|
+
if (text.length > 0) compactionErrors.set(ctx.recorder, text.slice(0, MAX_COMPACTION_CAUSE_CHARS))
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
/** The turn's last compaction error, or `undefined` when none errored. */
|
|
367
|
+
export function compactionErrorNote(ctx: IterationContext): string | undefined {
|
|
368
|
+
return compactionErrors.get(ctx.recorder)
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
/** A turn that got through has nothing left to explain. */
|
|
372
|
+
export function clearCompactionErrorNote(ctx: IterationContext): void {
|
|
373
|
+
compactionErrors.delete(ctx.recorder)
|
|
374
|
+
}
|
|
375
|
+
|
|
272
376
|
function totalChars(messages: readonly { content: unknown }[]): number {
|
|
273
377
|
let total = 0
|
|
274
378
|
for (const msg of messages) total += measureContentChars(msg.content)
|
|
@@ -312,6 +416,7 @@ async function declined(
|
|
|
312
416
|
messages: number,
|
|
313
417
|
error?: string,
|
|
314
418
|
): Promise<void> {
|
|
419
|
+
compactionBreaker(ctx)?.recordFailure()
|
|
315
420
|
await ctx.emitEvent?.({
|
|
316
421
|
type: 'compaction_failed',
|
|
317
422
|
turnId: ctx.recorder.turnId,
|
|
@@ -322,6 +427,35 @@ async function declined(
|
|
|
322
427
|
})
|
|
323
428
|
}
|
|
324
429
|
|
|
430
|
+
/**
|
|
431
|
+
* The third refill in a row: stop the turn instead of compacting again.
|
|
432
|
+
* Returns true when this pass must not run. Only with `circuitBreaker`.
|
|
433
|
+
* The loop also asks it before the first reactive relief of an overflow, as
|
|
434
|
+
* the reference terminal does (`rhr` runs first in its withheld-overflow
|
|
435
|
+
* handling), so a re-read loop made only of overflows is counted too.
|
|
436
|
+
*/
|
|
437
|
+
export async function stopOnRefill(ctx: IterationContext): Promise<boolean> {
|
|
438
|
+
const breaker = compactionBreaker(ctx)
|
|
439
|
+
if (!breaker) return false
|
|
440
|
+
// Already announced: the turn is on its way out; do not say it twice.
|
|
441
|
+
if (breaker.stop !== undefined) return true
|
|
442
|
+
if (!breaker.wouldTrip(ctx.recorder.currentIteration)) return false
|
|
443
|
+
ctx.log.warn('Compaction keeps refilling — stopping the turn', {
|
|
444
|
+
[NAMZU.TURN_ID]: ctx.recorder.turnId,
|
|
445
|
+
[NAMZU.ITERATION]: ctx.recorder.currentIteration,
|
|
446
|
+
})
|
|
447
|
+
breaker.stopTurn(COMPACTION_REFILL_MESSAGE)
|
|
448
|
+
await ctx.emitEvent?.({
|
|
449
|
+
type: 'compaction_failed',
|
|
450
|
+
turnId: ctx.recorder.turnId,
|
|
451
|
+
iteration: ctx.recorder.currentIteration,
|
|
452
|
+
cause: 'refilling',
|
|
453
|
+
messages: ctx.recorder.messages.length,
|
|
454
|
+
error: COMPACTION_REFILL_MESSAGE,
|
|
455
|
+
})
|
|
456
|
+
return true
|
|
457
|
+
}
|
|
458
|
+
|
|
325
459
|
/**
|
|
326
460
|
* Ctx for `compaction:no-split-tool-pair`, registered just below: the
|
|
327
461
|
* candidate history a reducer just returned, not yet installed. Passed on
|
|
@@ -382,6 +516,7 @@ async function applyReducer(
|
|
|
382
516
|
'namzu.runtime.reason': reduction.reason,
|
|
383
517
|
'exception.message': message,
|
|
384
518
|
})
|
|
519
|
+
noteCompactionError(ctx, error)
|
|
385
520
|
await declined(ctx, 'reducer_threw', before, message)
|
|
386
521
|
return
|
|
387
522
|
}
|
|
@@ -456,6 +591,7 @@ async function applyReducer(
|
|
|
456
591
|
reduction.contextWindowTokens,
|
|
457
592
|
measurement.windowSource,
|
|
458
593
|
)
|
|
594
|
+
compactionBreaker(ctx)?.recordCompaction(ctx.recorder.currentIteration)
|
|
459
595
|
}
|
|
460
596
|
|
|
461
597
|
/**
|
|
@@ -498,9 +634,10 @@ async function recordShed(
|
|
|
498
634
|
|
|
499
635
|
/**
|
|
500
636
|
* A pass, once the check decided to run one, is bracketed by the
|
|
501
|
-
* `pre_compact` and `post_compact` hooks.
|
|
502
|
-
*
|
|
503
|
-
*
|
|
637
|
+
* `pre_compact` and `post_compact` hooks. A hook sees the numbers and may
|
|
638
|
+
* cancel a pass the threshold asked for (`skip`), and cannot stop one the
|
|
639
|
+
* provider forced, because a context the provider will reject is not a thing
|
|
640
|
+
* a hook may insist on.
|
|
504
641
|
*/
|
|
505
642
|
interface CompactionPass {
|
|
506
643
|
attempted: boolean
|
|
@@ -511,7 +648,7 @@ interface CompactionPass {
|
|
|
511
648
|
|
|
512
649
|
export async function runCompactionCheck(
|
|
513
650
|
ctx: IterationContext,
|
|
514
|
-
options?: { force?: boolean },
|
|
651
|
+
options?: { force?: boolean; deeper?: boolean },
|
|
515
652
|
): Promise<void> {
|
|
516
653
|
const pass: CompactionPass = {
|
|
517
654
|
attempted: false,
|
|
@@ -547,11 +684,12 @@ export async function runCompactionCheck(
|
|
|
547
684
|
async function runCompactionCheckInner(
|
|
548
685
|
ctx: IterationContext,
|
|
549
686
|
pass: CompactionPass,
|
|
550
|
-
options?: { force?: boolean },
|
|
687
|
+
options?: { force?: boolean; deeper?: boolean },
|
|
551
688
|
): Promise<void> {
|
|
552
|
-
const
|
|
553
|
-
if (!
|
|
554
|
-
if (
|
|
689
|
+
const configured = ctx.compactionConfig
|
|
690
|
+
if (!configured) return
|
|
691
|
+
if (configured.strategy === 'disabled') return
|
|
692
|
+
const config = options?.deeper ? deepenConfig(configured, ctx.recorder.messages) : configured
|
|
555
693
|
|
|
556
694
|
const measured = measureContext(ctx)
|
|
557
695
|
const estimatedTokens = measured.tokens
|
|
@@ -573,11 +711,33 @@ async function runCompactionCheckInner(
|
|
|
573
711
|
// The salience strategy starts holding the context at `softTarget`,
|
|
574
712
|
// well before the summary trigger; every other strategy waits for it.
|
|
575
713
|
const salience = config.strategy === 'salience'
|
|
576
|
-
const
|
|
577
|
-
|
|
578
|
-
|
|
714
|
+
const maxOutputTokens = ctx.providerCapabilities?.maxOutputTokens
|
|
715
|
+
const trigger = resolveTriggerThreshold(config.triggerThreshold, budget, maxOutputTokens)
|
|
716
|
+
const startAt = salience ? Math.min(config.softTarget ?? DEFAULT_SOFT_TARGET, trigger) : trigger
|
|
579
717
|
if (!options?.force && usage < startAt) return
|
|
580
718
|
|
|
719
|
+
// Three failed passes in a row: stop proactive compaction for the rest of
|
|
720
|
+
// the turn. A pass the provider forced is never gated.
|
|
721
|
+
const breaker = compactionBreaker(ctx)
|
|
722
|
+
if (breaker?.failuresOpen && !options?.force) {
|
|
723
|
+
if (breaker.takeFailureNotice()) {
|
|
724
|
+
// Silent for the person, as in the reference terminal: a log line and the
|
|
725
|
+
// event for a host that wants it, but no sentence to show. Only the
|
|
726
|
+
// proactive pass stops; a real overflow still runs the reactive ladder.
|
|
727
|
+
ctx.log.warn('Compaction failed three times in a row — switched off for this turn', {
|
|
728
|
+
[NAMZU.TURN_ID]: ctx.recorder.turnId,
|
|
729
|
+
})
|
|
730
|
+
await ctx.emitEvent?.({
|
|
731
|
+
type: 'compaction_failed',
|
|
732
|
+
turnId: ctx.recorder.turnId,
|
|
733
|
+
iteration: ctx.recorder.currentIteration,
|
|
734
|
+
cause: 'breaker_open',
|
|
735
|
+
messages: ctx.recorder.messages.length,
|
|
736
|
+
})
|
|
737
|
+
}
|
|
738
|
+
return
|
|
739
|
+
}
|
|
740
|
+
|
|
581
741
|
pass.attempted = true
|
|
582
742
|
pass.tokensBefore = estimatedTokens
|
|
583
743
|
pass.contextWindowTokens = budget
|
|
@@ -598,6 +758,25 @@ async function runCompactionCheckInner(
|
|
|
598
758
|
ctx.emitEvent,
|
|
599
759
|
)
|
|
600
760
|
applyLifecycleHookResults('pre_compact', results)
|
|
761
|
+
const refusal = results.find((result) => result.action === 'skip')
|
|
762
|
+
if (refusal?.action === 'skip') {
|
|
763
|
+
// A threshold pass is the context's own housekeeping and a hook may
|
|
764
|
+
// postpone it. A forced pass runs because the provider rejected the
|
|
765
|
+
// prompt: a context it will reject is not something a hook may insist
|
|
766
|
+
// on, so the refusal is reported and the pass runs.
|
|
767
|
+
if (!options?.force) {
|
|
768
|
+
pass.attempted = false
|
|
769
|
+
ctx.log.info('A pre_compact hook cancelled the compaction pass', {
|
|
770
|
+
[NAMZU.TURN_ID]: ctx.recorder.turnId,
|
|
771
|
+
'namzu.hook.reason': refusal.reason,
|
|
772
|
+
})
|
|
773
|
+
return
|
|
774
|
+
}
|
|
775
|
+
ctx.log.warn('A pre_compact hook asked to cancel a compaction the provider forced; it ran', {
|
|
776
|
+
[NAMZU.TURN_ID]: ctx.recorder.turnId,
|
|
777
|
+
'namzu.hook.reason': refusal.reason,
|
|
778
|
+
})
|
|
779
|
+
}
|
|
601
780
|
}
|
|
602
781
|
|
|
603
782
|
// A reducer, when the turn has one, OWNS reduction — the structured pass
|
|
@@ -609,6 +788,7 @@ async function runCompactionCheckInner(
|
|
|
609
788
|
ctx.contextReducer ??
|
|
610
789
|
(config.strategy === 'sliding-window' ? createSlidingWindowReducer() : undefined)
|
|
611
790
|
if (reducer) {
|
|
791
|
+
if (!options?.force && (await stopOnRefill(ctx))) return
|
|
612
792
|
await applyReducer(
|
|
613
793
|
ctx,
|
|
614
794
|
reducer,
|
|
@@ -635,7 +815,7 @@ async function runCompactionCheckInner(
|
|
|
635
815
|
'namzu.runtime.window': budget,
|
|
636
816
|
'namzu.runtime.window_source': window.source,
|
|
637
817
|
'namzu.runtime.usage': Math.round(usage * 100),
|
|
638
|
-
'namzu.runtime.trigger_threshold':
|
|
818
|
+
'namzu.runtime.trigger_threshold': trigger,
|
|
639
819
|
'namzu.runtime.slot_count': manager.slotCount(),
|
|
640
820
|
})
|
|
641
821
|
|
|
@@ -668,6 +848,7 @@ async function runCompactionCheckInner(
|
|
|
668
848
|
messages: ctx.recorder.messages,
|
|
669
849
|
config,
|
|
670
850
|
contextWindowTokens: budget,
|
|
851
|
+
...(maxOutputTokens !== undefined ? { maxOutputTokens } : {}),
|
|
671
852
|
estimatedTokens,
|
|
672
853
|
...(openTasks ? { openTasks } : {}),
|
|
673
854
|
})
|
|
@@ -676,10 +857,7 @@ async function runCompactionCheckInner(
|
|
|
676
857
|
}
|
|
677
858
|
// Under the trigger, the working set was the whole pass: the summary
|
|
678
859
|
// path is for the trigger, not for the soft target.
|
|
679
|
-
if (
|
|
680
|
-
!options?.force &&
|
|
681
|
-
(estimatedTokens - working.reclaimedTokens) / budget < config.triggerThreshold
|
|
682
|
-
) {
|
|
860
|
+
if (!options?.force && (estimatedTokens - working.reclaimedTokens) / budget < trigger) {
|
|
683
861
|
return
|
|
684
862
|
}
|
|
685
863
|
}
|
|
@@ -687,6 +865,7 @@ async function runCompactionCheckInner(
|
|
|
687
865
|
messages: ctx.recorder.messages,
|
|
688
866
|
config,
|
|
689
867
|
contextWindowTokens: budget,
|
|
868
|
+
...(maxOutputTokens !== undefined ? { maxOutputTokens } : {}),
|
|
690
869
|
estimatedTokens,
|
|
691
870
|
...(options?.force ? { force: true } : {}),
|
|
692
871
|
})
|
|
@@ -712,6 +891,7 @@ async function runCompactionCheckInner(
|
|
|
712
891
|
messages,
|
|
713
892
|
config,
|
|
714
893
|
contextWindowTokens: budget,
|
|
894
|
+
...(maxOutputTokens !== undefined ? { maxOutputTokens } : {}),
|
|
715
895
|
estimatedTokens,
|
|
716
896
|
skipToolResultClear: true,
|
|
717
897
|
...(options?.force ? { force: true } : {}),
|
|
@@ -754,6 +934,14 @@ async function runCompactionCheckInner(
|
|
|
754
934
|
return
|
|
755
935
|
}
|
|
756
936
|
|
|
937
|
+
if (!options?.force && (await stopOnRefill(ctx))) {
|
|
938
|
+
// A clear staged for this pass is still a useful edit.
|
|
939
|
+
if (stagedClear) {
|
|
940
|
+
await commitToolResultClear(ctx, stagedClear, budget, window.source, pass.reason)
|
|
941
|
+
}
|
|
942
|
+
return
|
|
943
|
+
}
|
|
944
|
+
|
|
757
945
|
const { systemMessages, olderMessages, recentMessages, keepStart } = plan
|
|
758
946
|
|
|
759
947
|
let compactedContent: string
|
|
@@ -765,25 +953,39 @@ async function runCompactionCheckInner(
|
|
|
765
953
|
// to a cheap model while the bill is written against the expensive one
|
|
766
954
|
// is a mistake with no symptom.
|
|
767
955
|
const compactionModel = resolveTaskModel('compaction', ctx.taskRouter, ctx.turnConfig.model)
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
956
|
+
try {
|
|
957
|
+
compactedContent = await buildVerifiedSummaryWithBoundedProvider(
|
|
958
|
+
manager,
|
|
959
|
+
olderMessages as Message[],
|
|
960
|
+
ctx.provider,
|
|
961
|
+
config,
|
|
962
|
+
(usage) =>
|
|
963
|
+
ctx.recorder.accumulateUsage(usage, {
|
|
964
|
+
providerId: ctx.recorder.servingProviderId,
|
|
965
|
+
model: compactionModel,
|
|
966
|
+
}),
|
|
967
|
+
// The one model call a turn makes that the user never asked for. It
|
|
968
|
+
// reads a transcript and writes a summary, which is the cheapest
|
|
969
|
+
// thing a small model does well, and it fires on exactly the long
|
|
970
|
+
// runs where the primary model is most expensive. `taskRouter` had
|
|
971
|
+
// been accepted, validated and threaded through four types since it
|
|
972
|
+
// was added, and nothing ever consulted it.
|
|
973
|
+
compactionModel,
|
|
974
|
+
ctx.abortController.signal,
|
|
975
|
+
)
|
|
976
|
+
} catch (error) {
|
|
977
|
+
// The model step only ADDS to the extracted state, so a failed one (a
|
|
978
|
+
// timeout, a provider error, its own overflow after the ladder in the
|
|
979
|
+
// verifier ran out) is not a reason to leave the history as it is. Cancellation
|
|
980
|
+
// is the caller's, and still stops the pass.
|
|
981
|
+
if (ctx.abortController.signal.aborted) throw error
|
|
982
|
+
noteCompactionError(ctx, error)
|
|
983
|
+
ctx.log.warn('The compaction summary call failed — using the extracted state alone', {
|
|
984
|
+
[NAMZU.TURN_ID]: ctx.recorder.turnId,
|
|
985
|
+
'exception.message': error instanceof Error ? error.message : String(error),
|
|
986
|
+
})
|
|
987
|
+
compactedContent = serializeState(manager.getState())
|
|
988
|
+
}
|
|
787
989
|
} else {
|
|
788
990
|
compactedContent = serializeState(manager.getState())
|
|
789
991
|
}
|
|
@@ -910,4 +1112,5 @@ async function runCompactionCheckInner(
|
|
|
910
1112
|
reachedResetThreshold: reachedReset,
|
|
911
1113
|
})
|
|
912
1114
|
await emitContextUsageSnapshot(ctx, newEstimate, budget, window.source)
|
|
1115
|
+
compactionBreaker(ctx)?.recordCompaction(ctx.recorder.currentIteration)
|
|
913
1116
|
}
|
|
@@ -199,6 +199,8 @@ export interface IterationContext {
|
|
|
199
199
|
readonly taskRouter?: TaskRouterConfig
|
|
200
200
|
|
|
201
201
|
readonly compactionConfig?: CompactionConfig
|
|
202
|
+
/** See `QueryParams.maxOutputContinuations`. */
|
|
203
|
+
readonly maxOutputContinuations?: number
|
|
202
204
|
|
|
203
205
|
/**
|
|
204
206
|
* What the driver said this model's context window is, resolved once.
|
|
@@ -225,6 +227,11 @@ export interface IterationContext {
|
|
|
225
227
|
* after tool results and before the next turn.
|
|
226
228
|
*/
|
|
227
229
|
readonly inboundMessages?: () => readonly import('../../../../types/message/index.js').Message[]
|
|
230
|
+
/**
|
|
231
|
+
* Hidden reminders for each model request; see `ReminderSource`. Absent:
|
|
232
|
+
* the turn gets none, as before.
|
|
233
|
+
*/
|
|
234
|
+
readonly reminders?: import('../../reminders.js').ReminderSource
|
|
228
235
|
/** Known topic-queue arrivals appended after the restored checkpoint history. */
|
|
229
236
|
readonly resumedInput?: readonly import('../../../../types/message/index.js').Message[]
|
|
230
237
|
/** Observes pending input without draining it; abort releases the waiter. */
|
|
@@ -252,6 +259,10 @@ export interface IterationContext {
|
|
|
252
259
|
|
|
253
260
|
readonly pluginManager?: import('../../../../plugin/lifecycle.js').PluginLifecycleManager
|
|
254
261
|
|
|
262
|
+
/** The delegating session, when this turn is a child's: `subagent_stop` names it. */
|
|
263
|
+
readonly parentSessionId?: import('../../../../types/ids/index.js').SessionId
|
|
264
|
+
readonly parentTurnId?: import('../../../../types/ids/index.js').TurnId
|
|
265
|
+
|
|
255
266
|
/**
|
|
256
267
|
* Override for {@link PARK_RECORD_DELAY_MS}. Internal; tests set `0` to
|
|
257
268
|
* observe a recorded park without waiting out the real threshold.
|