@namzu/sdk 51.1.0 → 52.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +100 -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 +19 -7
- 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/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/public-runtime.d.ts +4 -1
- package/dist/public-runtime.d.ts.map +1 -1
- package/dist/public-runtime.js +4 -1
- 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/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 +41 -2
- package/dist/runtime/query/executor.d.ts.map +1 -1
- package/dist/runtime/query/executor.js +190 -6
- 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 +15 -3
- package/dist/runtime/query/index.js.map +1 -1
- package/dist/runtime/query/iteration/index.d.ts +31 -0
- package/dist/runtime/query/iteration/index.d.ts.map +1 -1
- package/dist/runtime/query/iteration/index.js +216 -7
- package/dist/runtime/query/iteration/index.js.map +1 -1
- package/dist/runtime/query/iteration/phases/compaction-breaker.d.ts +58 -0
- package/dist/runtime/query/iteration/phases/compaction-breaker.d.ts.map +1 -0
- package/dist/runtime/query/iteration/phases/compaction-breaker.js +91 -0
- package/dist/runtime/query/iteration/phases/compaction-breaker.js.map +1 -0
- package/dist/runtime/query/iteration/phases/compaction.d.ts.map +1 -1
- package/dist/runtime/query/iteration/phases/compaction.js +89 -7
- 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/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/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/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 +24 -0
- package/dist/types/provider/errors.js.map +1 -1
- package/dist/types/session/events.d.ts +10 -2
- 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 +28 -3
- 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/public-runtime.ts +8 -0
- package/src/public-types.ts +4 -0
- package/src/runtime/jobs/registry.ts +39 -2
- package/src/runtime/query/executor/tool-call-admission.ts +79 -13
- package/src/runtime/query/executor.ts +242 -8
- package/src/runtime/query/finalize-turn.ts +7 -1
- package/src/runtime/query/index.ts +45 -3
- package/src/runtime/query/iteration/index.ts +251 -12
- package/src/runtime/query/iteration/phases/compaction-breaker.ts +106 -0
- package/src/runtime/query/iteration/phases/compaction.ts +99 -12
- 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/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/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/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 +33 -0
- package/src/types/session/events.ts +10 -2
- 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,7 +1,7 @@
|
|
|
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';
|
|
@@ -15,7 +15,7 @@ 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';
|
|
@@ -31,6 +31,7 @@ import { parseNativeCandidate } from './native-output.js';
|
|
|
31
31
|
import { drainArrivedTaskCompletions, holdForOutstandingWork, settleOutstandingWork, } from './outstanding-work.js';
|
|
32
32
|
import { runAdvisoryPhase } from './phases/advisory.js';
|
|
33
33
|
import { runIterationCheckpoint } from './phases/checkpoint.js';
|
|
34
|
+
import { compactionBreaker } from './phases/compaction-breaker.js';
|
|
34
35
|
import { activeContextWindow, measureContext, relieveOverflow, runCompactionCheck, } from './phases/compaction.js';
|
|
35
36
|
import { runHandoffPause } from './phases/handoff.js';
|
|
36
37
|
import { runPlanGate } from './phases/plan.js';
|
|
@@ -60,6 +61,10 @@ class AnswerReviewFailure extends NamzuError {
|
|
|
60
61
|
* on the thing that actually went wrong.
|
|
61
62
|
*/
|
|
62
63
|
const DEFAULT_ANSWER_REVIEW_LIMIT = 3;
|
|
64
|
+
/** Left unused when an output cap is shrunk to fit the window (reference: 1000). */
|
|
65
|
+
const OUTPUT_CAP_MARGIN_TOKENS = 1000;
|
|
66
|
+
/** A shrunk output cap below this is not worth a call (reference floor: 3000). */
|
|
67
|
+
const MIN_OUTPUT_CAP_TOKENS = 3000;
|
|
63
68
|
// Ending a turn changes the available actions, not the strength of its evidence.
|
|
64
69
|
// Use the same standard for warning closure and empty-completion recovery.
|
|
65
70
|
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.';
|
|
@@ -113,6 +118,67 @@ export class IterationOrchestrator {
|
|
|
113
118
|
* sets it.
|
|
114
119
|
*/
|
|
115
120
|
stopDeferredForOutstandingWork = false;
|
|
121
|
+
/** Nudges sent since the model last finished a call without hitting its output cap. */
|
|
122
|
+
outputContinuations = 0;
|
|
123
|
+
/**
|
|
124
|
+
* `turn_end` (and, for a child, `subagent_stop`) fired when the model
|
|
125
|
+
* finished and no hook asked for more. `finalizeTurn` then does not fire
|
|
126
|
+
* them a second time.
|
|
127
|
+
*/
|
|
128
|
+
turnEndFired = false;
|
|
129
|
+
/** A hook already kept this turn going once: it is asked again with `stop_hook_active`. */
|
|
130
|
+
stopHookActive = false;
|
|
131
|
+
get turnEndHooksFired() {
|
|
132
|
+
return this.turnEndFired;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Fire `turn_end` (and `subagent_stop` for a child) at the point the model
|
|
136
|
+
* has finished, and read the answer.
|
|
137
|
+
*
|
|
138
|
+
* A hook that answers `skip` is refusing to let the turn end: its reasons
|
|
139
|
+
* are returned, joined, as feedback for the model. A hook that asks for the
|
|
140
|
+
* turn to halt wins over any such feedback (`takeHalt`). With nothing asked,
|
|
141
|
+
* the events have fired for this turn and the finalizer does not repeat them.
|
|
142
|
+
*/
|
|
143
|
+
async *askStopHooks() {
|
|
144
|
+
const manager = this.ctx.pluginManager;
|
|
145
|
+
if (!manager)
|
|
146
|
+
return undefined;
|
|
147
|
+
const recorder = this.ctx.recorder;
|
|
148
|
+
const feedback = [];
|
|
149
|
+
const ask = async (event, extra) => {
|
|
150
|
+
const results = await manager.executeHooks(event, {
|
|
151
|
+
sessionId: recorder.sessionId,
|
|
152
|
+
turnId: recorder.turnId,
|
|
153
|
+
...extra,
|
|
154
|
+
...(this.stopHookActive ? { stopHookActive: true } : {}),
|
|
155
|
+
signal: this.ctx.abortController.signal,
|
|
156
|
+
}, this.ctx.emitEvent);
|
|
157
|
+
applyLifecycleHookResults(event, results);
|
|
158
|
+
for (const result of results) {
|
|
159
|
+
if (result.action === 'skip')
|
|
160
|
+
feedback.push(result.reason);
|
|
161
|
+
if ((result.action === 'continue' || result.action === 'skip') && result.halt) {
|
|
162
|
+
this.ctx.toolExecutor.requestHalt?.(result.halt.reason);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
await ask('turn_end', {});
|
|
167
|
+
yield* this.ctx.drainPending();
|
|
168
|
+
if (this.ctx.parentSessionId !== undefined) {
|
|
169
|
+
await ask('subagent_stop', {
|
|
170
|
+
parentSessionId: this.ctx.parentSessionId,
|
|
171
|
+
...(this.ctx.parentTurnId !== undefined ? { parentTurnId: this.ctx.parentTurnId } : {}),
|
|
172
|
+
});
|
|
173
|
+
yield* this.ctx.drainPending();
|
|
174
|
+
}
|
|
175
|
+
if (feedback.length === 0) {
|
|
176
|
+
this.turnEndFired = true;
|
|
177
|
+
return undefined;
|
|
178
|
+
}
|
|
179
|
+
this.stopHookActive = true;
|
|
180
|
+
return feedback.join('\n');
|
|
181
|
+
}
|
|
116
182
|
/** One current input, independent of the compactable history array. */
|
|
117
183
|
latestUserMessage;
|
|
118
184
|
initialDurableDelivered = false;
|
|
@@ -274,6 +340,9 @@ export class IterationOrchestrator {
|
|
|
274
340
|
// obvious moves left. It is cleared by a turn that actually
|
|
275
341
|
// succeeded, which is the evidence that the turn is no longer stuck.
|
|
276
342
|
let overflowRelieved = false;
|
|
343
|
+
// The output cap a provider told us fits beside this prompt. One request's
|
|
344
|
+
// worth: it is cleared by a call that went through.
|
|
345
|
+
let outputCapOverride;
|
|
277
346
|
// A `finally` rather than a line at each exit, for the reason written
|
|
278
347
|
// beside `iterSpan.end()` below: this loop leaves by eight `break`s,
|
|
279
348
|
// two `return`s and a `throw`, and a rule every future edit has to
|
|
@@ -446,12 +515,16 @@ export class IterationOrchestrator {
|
|
|
446
515
|
applyLifecycleHookResults('iteration_start', hookResults);
|
|
447
516
|
yield* this.ctx.drainPending();
|
|
448
517
|
}
|
|
518
|
+
if (!forceFinalize)
|
|
519
|
+
await this.deliverReminders(iterationNum);
|
|
449
520
|
// Re-pin the working-memory block from ground truth at the primacy
|
|
450
521
|
// edge BEFORE compaction runs (so the refreshed slot is what
|
|
451
522
|
// compaction preserves). No-op when no provider is configured.
|
|
452
523
|
await refreshWorkingMemory(this.ctx);
|
|
453
524
|
await runCompactionCheck(this.ctx);
|
|
454
525
|
yield* this.ctx.drainPending();
|
|
526
|
+
if (this.stopForCompactionBreaker())
|
|
527
|
+
break;
|
|
455
528
|
// Cache discipline: keep the tools param byte-stable even on the
|
|
456
529
|
// forced-final iteration and forbid tool use via tool_choice
|
|
457
530
|
// 'none' instead. Dropping the tools array would invalidate the
|
|
@@ -498,6 +571,8 @@ export class IterationOrchestrator {
|
|
|
498
571
|
await runCompactionCheck(this.ctx);
|
|
499
572
|
// Publish context edits before entering a possibly slow provider.
|
|
500
573
|
yield* this.ctx.drainPending();
|
|
574
|
+
if (this.stopForCompactionBreaker())
|
|
575
|
+
break;
|
|
501
576
|
const stepAllowedTools = step.allowedTools ?? this.ctx.allowedTools;
|
|
502
577
|
const deferredMcpContext = deferredMcpHints?.forNames(stepAllowedTools) ?? '';
|
|
503
578
|
const contextText = [
|
|
@@ -660,7 +735,7 @@ export class IterationOrchestrator {
|
|
|
660
735
|
messages: Object.freeze(messages.map((m) => Object.freeze({ ...m }))),
|
|
661
736
|
toolNames: Object.freeze(llmTools.map((t) => t.function.name)),
|
|
662
737
|
temperature: step.temperature ?? turnConfig.temperature,
|
|
663
|
-
maxTokens: step.maxResponseTokens ?? turnConfig.maxResponseTokens,
|
|
738
|
+
maxTokens: outputCapOverride ?? step.maxResponseTokens ?? turnConfig.maxResponseTokens,
|
|
664
739
|
}),
|
|
665
740
|
}, this.ctx.emitEvent);
|
|
666
741
|
applyLifecycleHookResults('pre_llm_call', hookResults);
|
|
@@ -726,7 +801,7 @@ export class IterationOrchestrator {
|
|
|
726
801
|
? step.toolChoice
|
|
727
802
|
: undefined,
|
|
728
803
|
temperature: step.temperature ?? turnConfig.temperature,
|
|
729
|
-
maxTokens: step.maxResponseTokens ?? turnConfig.maxResponseTokens,
|
|
804
|
+
maxTokens: outputCapOverride ?? step.maxResponseTokens ?? turnConfig.maxResponseTokens,
|
|
730
805
|
cacheControl: { type: 'auto' },
|
|
731
806
|
...(turnConfig.thinking ? { thinking: turnConfig.thinking } : {}),
|
|
732
807
|
...(turnConfig.effort ? { effort: turnConfig.effort } : {}),
|
|
@@ -785,6 +860,9 @@ export class IterationOrchestrator {
|
|
|
785
860
|
// The turn went through, so the turn is not sitting on an
|
|
786
861
|
// irreducible prompt any more. Re-arm relief for the next one.
|
|
787
862
|
overflowRelieved = false;
|
|
863
|
+
outputCapOverride = undefined;
|
|
864
|
+
if (response.finishReason !== 'length')
|
|
865
|
+
this.outputContinuations = 0;
|
|
788
866
|
if (this.ctx.pluginManager) {
|
|
789
867
|
const hookResults = await this.ctx.pluginManager.executeHooks('post_llm_call', {
|
|
790
868
|
sessionId: recorder.sessionId,
|
|
@@ -1055,16 +1133,43 @@ export class IterationOrchestrator {
|
|
|
1055
1133
|
// it has no room left to continue into, and the
|
|
1056
1134
|
// continuation would only send a longer prompt into
|
|
1057
1135
|
// the same full window. The reply stands as it is.
|
|
1136
|
+
const cutDuringReasoning = !hasContent &&
|
|
1137
|
+
(response.message.toolCalls?.length ?? 0) === 0 &&
|
|
1138
|
+
(response.message.reasoning?.length ?? 0) > 0;
|
|
1058
1139
|
if (!forceFinalize &&
|
|
1059
1140
|
response.finishReason === 'length' &&
|
|
1060
1141
|
response.finishDetail !== 'context_window' &&
|
|
1061
|
-
hasContent) {
|
|
1062
|
-
|
|
1142
|
+
(hasContent || cutDuringReasoning)) {
|
|
1143
|
+
// A host that opted in gets a cap on the nudges: a model that
|
|
1144
|
+
// overruns its output limit every time would otherwise spend the
|
|
1145
|
+
// whole turn on it. Past the cap the turn stops, and says why.
|
|
1146
|
+
const cap = this.ctx.maxOutputContinuations;
|
|
1147
|
+
if (cap !== undefined && this.outputContinuations >= cap) {
|
|
1148
|
+
this.ctx.log.warn('LLM kept hitting max_tokens — stopping the turn', {
|
|
1149
|
+
[NAMZU.TURN_ID]: recorder.turnId,
|
|
1150
|
+
[NAMZU.ITERATION]: iterationNum,
|
|
1151
|
+
'namzu.runtime.output_continuations': this.outputContinuations,
|
|
1152
|
+
});
|
|
1153
|
+
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.`);
|
|
1154
|
+
recorder.setStopReason('output_limit');
|
|
1155
|
+
await this.ctx.emitEvent({
|
|
1156
|
+
type: 'iteration_completed',
|
|
1157
|
+
turnId: recorder.turnId,
|
|
1158
|
+
iteration: iterationNum,
|
|
1159
|
+
hasToolCalls: false,
|
|
1160
|
+
});
|
|
1161
|
+
yield* this.ctx.drainPending();
|
|
1162
|
+
break;
|
|
1163
|
+
}
|
|
1164
|
+
this.outputContinuations++;
|
|
1165
|
+
this.ctx.log.info(cutDuringReasoning
|
|
1166
|
+
? 'LLM hit max_tokens while reasoning — nudging to answer briefly'
|
|
1167
|
+
: 'LLM hit max_tokens mid-text — auto-continuing', {
|
|
1063
1168
|
[NAMZU.TURN_ID]: recorder.turnId,
|
|
1064
1169
|
[NAMZU.ITERATION]: iterationNum,
|
|
1065
1170
|
[GENAI.USAGE_OUTPUT_TOKENS]: response.usage.completionTokens,
|
|
1066
1171
|
});
|
|
1067
|
-
recorder.pushMessage(createRuntimeContextMessage(AUTO_CONTINUATION_USER_MESSAGE, 'auto-continuation'));
|
|
1172
|
+
recorder.pushMessage(createRuntimeContextMessage(cutDuringReasoning ? REASONING_CUT_USER_MESSAGE : AUTO_CONTINUATION_USER_MESSAGE, 'auto-continuation'));
|
|
1068
1173
|
await this.ctx.emitEvent({
|
|
1069
1174
|
type: 'iteration_completed',
|
|
1070
1175
|
turnId: recorder.turnId,
|
|
@@ -1206,6 +1311,22 @@ export class IterationOrchestrator {
|
|
|
1206
1311
|
// also settle as `end_turn`, and there the deferred predicate
|
|
1207
1312
|
// is not why the turn ended: those decided the answer
|
|
1208
1313
|
// themselves.
|
|
1314
|
+
// The model is done and has no tool calls. A `turn_end` (or
|
|
1315
|
+
// `subagent_stop`) hook may refuse to let it be: its reason goes
|
|
1316
|
+
// back to the model and the turn goes on.
|
|
1317
|
+
if (!forceFinalize && closingStopReason === undefined) {
|
|
1318
|
+
const feedback = yield* this.askStopHooks();
|
|
1319
|
+
const stoppedByHook = this.ctx.toolExecutor.takeHalt?.();
|
|
1320
|
+
if (stoppedByHook !== undefined) {
|
|
1321
|
+
recorder.setLastError(`Stopped by a hook: ${stoppedByHook}`);
|
|
1322
|
+
recorder.setStopReason('stop_condition');
|
|
1323
|
+
break;
|
|
1324
|
+
}
|
|
1325
|
+
if (feedback !== undefined) {
|
|
1326
|
+
recorder.pushMessage(createRuntimeContextMessage(`A hook asked for more before this turn ends:\n${feedback}`, 'hook-feedback'));
|
|
1327
|
+
continue;
|
|
1328
|
+
}
|
|
1329
|
+
}
|
|
1209
1330
|
recorder.setStopReason(closingStopReason ??
|
|
1210
1331
|
(stopWasDeferredForOutstandingWork ? 'stop_condition' : 'end_turn'));
|
|
1211
1332
|
break;
|
|
@@ -1240,6 +1361,27 @@ export class IterationOrchestrator {
|
|
|
1240
1361
|
if ((yield* runHandoffPause(this.ctx, iterationNum, reviewOutcome.results)) === 'stop') {
|
|
1241
1362
|
return;
|
|
1242
1363
|
}
|
|
1364
|
+
// A hook asked for the turn to stop once this step's calls were
|
|
1365
|
+
// answered. Every `tool_use` has its `tool_result` by now, so the
|
|
1366
|
+
// transcript is whole; what is left is to end the turn and say why.
|
|
1367
|
+
const hookHalt = this.ctx.toolExecutor.takeHalt?.();
|
|
1368
|
+
if (hookHalt !== undefined) {
|
|
1369
|
+
this.ctx.log.info('A hook stopped the turn', {
|
|
1370
|
+
[NAMZU.TURN_ID]: recorder.turnId,
|
|
1371
|
+
[NAMZU.ITERATION]: iterationNum,
|
|
1372
|
+
'namzu.hook.reason': hookHalt,
|
|
1373
|
+
});
|
|
1374
|
+
recorder.setLastError(`Stopped by a hook: ${hookHalt}`);
|
|
1375
|
+
recorder.setStopReason('stop_condition');
|
|
1376
|
+
await this.ctx.emitEvent({
|
|
1377
|
+
type: 'iteration_completed',
|
|
1378
|
+
turnId: recorder.turnId,
|
|
1379
|
+
iteration: iterationNum,
|
|
1380
|
+
hasToolCalls: true,
|
|
1381
|
+
});
|
|
1382
|
+
yield* this.ctx.drainPending();
|
|
1383
|
+
break;
|
|
1384
|
+
}
|
|
1243
1385
|
if (reviewOutcome.decision === 'rejected') {
|
|
1244
1386
|
continue;
|
|
1245
1387
|
}
|
|
@@ -1541,6 +1683,29 @@ export class IterationOrchestrator {
|
|
|
1541
1683
|
// actually shed something. A second overflow after a successful
|
|
1542
1684
|
// compaction means the prompt is irreducible, and looping on it
|
|
1543
1685
|
// would burn the budget to arrive at the same error.
|
|
1686
|
+
// The prompt fit and only the requested output did not: ask for what
|
|
1687
|
+
// room is left (less a margin) and send it again, once. A reply that
|
|
1688
|
+
// would be too small to be useful, or a cap that is not smaller than
|
|
1689
|
+
// the one already tried, is not retried: the same failure would follow.
|
|
1690
|
+
const outputOverflow = err instanceof AnswerReviewFailure ? undefined : readOutputOverflow(err);
|
|
1691
|
+
if (outputOverflow) {
|
|
1692
|
+
const room = Math.max(0, outputOverflow.contextLimit - outputOverflow.inputTokens - OUTPUT_CAP_MARGIN_TOKENS);
|
|
1693
|
+
if (room >= MIN_OUTPUT_CAP_TOKENS &&
|
|
1694
|
+
(outputCapOverride === undefined || room < outputCapOverride)) {
|
|
1695
|
+
outputCapOverride = room;
|
|
1696
|
+
this.ctx.log.info('Output cap does not fit beside the prompt — retrying with less', {
|
|
1697
|
+
[NAMZU.TURN_ID]: recorder.turnId,
|
|
1698
|
+
[NAMZU.ITERATION]: iterationNum,
|
|
1699
|
+
'namzu.runtime.input_tokens': outputOverflow.inputTokens,
|
|
1700
|
+
'namzu.runtime.context_limit': outputOverflow.contextLimit,
|
|
1701
|
+
'namzu.runtime.adjusted_max_tokens': room,
|
|
1702
|
+
});
|
|
1703
|
+
if (iterationActivity) {
|
|
1704
|
+
this.ctx.activityStore.complete(iterationActivity.id);
|
|
1705
|
+
}
|
|
1706
|
+
continue;
|
|
1707
|
+
}
|
|
1708
|
+
}
|
|
1544
1709
|
if (!overflowRelieved &&
|
|
1545
1710
|
!(err instanceof AnswerReviewFailure) &&
|
|
1546
1711
|
classifyProviderError(err, this.ctx.provider.id).code === 'context_length_exceeded') {
|
|
@@ -1639,6 +1804,41 @@ export class IterationOrchestrator {
|
|
|
1639
1804
|
extractFromUserMessage(manager, message.content, !manager.getState().task);
|
|
1640
1805
|
}
|
|
1641
1806
|
}
|
|
1807
|
+
/**
|
|
1808
|
+
* Ask the host's reminder source (`QueryParams.reminders`) what the model
|
|
1809
|
+
* should be told before this request, and append each text as a hidden
|
|
1810
|
+
* user-role message. The start of a request is a provider-valid boundary:
|
|
1811
|
+
* the history ends in the operator's message or in a finished tool batch.
|
|
1812
|
+
* A source that throws has nothing to say; it never fails the turn.
|
|
1813
|
+
*/
|
|
1814
|
+
async deliverReminders(iteration) {
|
|
1815
|
+
const source = this.ctx.reminders;
|
|
1816
|
+
if (!source)
|
|
1817
|
+
return;
|
|
1818
|
+
const { recorder } = this.ctx;
|
|
1819
|
+
let texts;
|
|
1820
|
+
try {
|
|
1821
|
+
texts = await source({
|
|
1822
|
+
sessionId: recorder.sessionId,
|
|
1823
|
+
turnId: recorder.turnId,
|
|
1824
|
+
iteration,
|
|
1825
|
+
messages: recorder.messages,
|
|
1826
|
+
});
|
|
1827
|
+
}
|
|
1828
|
+
catch (error) {
|
|
1829
|
+
this.ctx.log.warn('A reminder source threw; the request goes without its reminders', {
|
|
1830
|
+
[NAMZU.TURN_ID]: recorder.turnId,
|
|
1831
|
+
[NAMZU.ITERATION]: iteration,
|
|
1832
|
+
'exception.message': error instanceof Error ? error.message : String(error),
|
|
1833
|
+
});
|
|
1834
|
+
return;
|
|
1835
|
+
}
|
|
1836
|
+
for (const text of texts ?? []) {
|
|
1837
|
+
if (text.trim().length === 0)
|
|
1838
|
+
continue;
|
|
1839
|
+
recorder.pushMessage(createRuntimeContextMessage(text, 'reminder'));
|
|
1840
|
+
}
|
|
1841
|
+
}
|
|
1642
1842
|
async deliverInbound() {
|
|
1643
1843
|
const queued = this.ctx.inboundMessages?.() ?? [];
|
|
1644
1844
|
for (const message of queued) {
|
|
@@ -1756,6 +1956,15 @@ export class IterationOrchestrator {
|
|
|
1756
1956
|
recorder.setStopReason('structured_output_failed');
|
|
1757
1957
|
return true;
|
|
1758
1958
|
}
|
|
1959
|
+
/** The compaction circuit breaker asked for the turn to stop (opt-in; see `compactionConfig.circuitBreaker`). */
|
|
1960
|
+
stopForCompactionBreaker() {
|
|
1961
|
+
const reason = compactionBreaker(this.ctx)?.stop;
|
|
1962
|
+
if (reason === undefined)
|
|
1963
|
+
return false;
|
|
1964
|
+
this.ctx.recorder.setLastError(reason);
|
|
1965
|
+
this.ctx.recorder.setStopReason('error');
|
|
1966
|
+
return true;
|
|
1967
|
+
}
|
|
1759
1968
|
async recordToolStructuredFailure(results, iteration) {
|
|
1760
1969
|
if (!this.needsStructuredOutput() ||
|
|
1761
1970
|
this.ctx.structuredOutput?.mode === 'native' ||
|