@namzu/sdk 62.6.0 → 62.7.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 +35 -0
- package/dist/agents/QueryAgent.d.ts.map +1 -1
- package/dist/agents/QueryAgent.js +5 -0
- package/dist/agents/QueryAgent.js.map +1 -1
- package/dist/agents/examples/SupervisorAgent.d.ts.map +1 -1
- package/dist/agents/examples/SupervisorAgent.js +1 -0
- package/dist/agents/examples/SupervisorAgent.js.map +1 -1
- package/dist/agents/explore.d.ts.map +1 -1
- package/dist/agents/explore.js +2 -1
- package/dist/agents/explore.js.map +1 -1
- package/dist/compaction/index.d.ts +1 -1
- package/dist/compaction/index.d.ts.map +1 -1
- package/dist/compaction/index.js +1 -1
- package/dist/compaction/index.js.map +1 -1
- package/dist/compaction/model-summary.js +2 -2
- package/dist/compaction/model-summary.js.map +1 -1
- package/dist/compaction/summary.d.ts +16 -1
- package/dist/compaction/summary.d.ts.map +1 -1
- package/dist/compaction/summary.js +25 -2
- package/dist/compaction/summary.js.map +1 -1
- package/dist/config/runtime.d.ts +8 -0
- package/dist/config/runtime.d.ts.map +1 -1
- package/dist/config/runtime.js +15 -0
- package/dist/config/runtime.js.map +1 -1
- package/dist/execution/workflow/runtime.d.ts.map +1 -1
- package/dist/execution/workflow/runtime.js +3 -0
- package/dist/execution/workflow/runtime.js.map +1 -1
- package/dist/execution/workflow/types.d.ts +8 -0
- package/dist/execution/workflow/types.d.ts.map +1 -1
- package/dist/manager/agent/child-session.d.ts +12 -0
- package/dist/manager/agent/child-session.d.ts.map +1 -1
- package/dist/manager/agent/child-session.js +29 -0
- package/dist/manager/agent/child-session.js.map +1 -1
- package/dist/manager/agent/lifecycle.d.ts.map +1 -1
- package/dist/manager/agent/lifecycle.js +8 -0
- package/dist/manager/agent/lifecycle.js.map +1 -1
- package/dist/manager/session/turn-recorder.d.ts +13 -2
- package/dist/manager/session/turn-recorder.d.ts.map +1 -1
- package/dist/manager/session/turn-recorder.js +57 -3
- package/dist/manager/session/turn-recorder.js.map +1 -1
- package/dist/prompt/coding-agent-doctrine.d.ts +3 -3
- package/dist/prompt/coding-agent-doctrine.d.ts.map +1 -1
- package/dist/prompt/coding-agent-doctrine.js +5 -3
- package/dist/prompt/coding-agent-doctrine.js.map +1 -1
- package/dist/provider/fallback.d.ts.map +1 -1
- package/dist/provider/fallback.js +5 -1
- package/dist/provider/fallback.js.map +1 -1
- package/dist/provider/retry.d.ts +25 -0
- package/dist/provider/retry.d.ts.map +1 -1
- package/dist/provider/retry.js +28 -0
- package/dist/provider/retry.js.map +1 -1
- package/dist/public-runtime.d.ts +3 -3
- package/dist/public-runtime.d.ts.map +1 -1
- package/dist/public-runtime.js +3 -3
- package/dist/public-runtime.js.map +1 -1
- package/dist/public-tools.d.ts +4 -2
- package/dist/public-tools.d.ts.map +1 -1
- package/dist/public-tools.js +5 -2
- package/dist/public-tools.js.map +1 -1
- package/dist/runtime/query/auto-review/classifier.d.ts +7 -1
- package/dist/runtime/query/auto-review/classifier.d.ts.map +1 -1
- package/dist/runtime/query/auto-review/classifier.js +8 -4
- package/dist/runtime/query/auto-review/classifier.js.map +1 -1
- package/dist/runtime/query/auto-review/prompt.d.ts.map +1 -1
- package/dist/runtime/query/auto-review/prompt.js +2 -0
- package/dist/runtime/query/auto-review/prompt.js.map +1 -1
- package/dist/runtime/query/auto-review/script-evidence.d.ts +93 -0
- package/dist/runtime/query/auto-review/script-evidence.d.ts.map +1 -0
- package/dist/runtime/query/auto-review/script-evidence.js +566 -0
- package/dist/runtime/query/auto-review/script-evidence.js.map +1 -0
- package/dist/runtime/query/checkpoint.d.ts +13 -0
- package/dist/runtime/query/checkpoint.d.ts.map +1 -1
- package/dist/runtime/query/checkpoint.js +37 -0
- package/dist/runtime/query/checkpoint.js.map +1 -1
- package/dist/runtime/query/executor.d.ts +38 -1
- package/dist/runtime/query/executor.d.ts.map +1 -1
- package/dist/runtime/query/executor.js +130 -11
- package/dist/runtime/query/executor.js.map +1 -1
- package/dist/runtime/query/finalize-turn.d.ts +7 -1
- package/dist/runtime/query/finalize-turn.d.ts.map +1 -1
- package/dist/runtime/query/finalize-turn.js +2 -0
- package/dist/runtime/query/finalize-turn.js.map +1 -1
- package/dist/runtime/query/index.d.ts +8 -0
- package/dist/runtime/query/index.d.ts.map +1 -1
- package/dist/runtime/query/index.js +7 -0
- package/dist/runtime/query/index.js.map +1 -1
- package/dist/runtime/query/iteration/index.d.ts +32 -1
- package/dist/runtime/query/iteration/index.d.ts.map +1 -1
- package/dist/runtime/query/iteration/index.js +158 -10
- package/dist/runtime/query/iteration/index.js.map +1 -1
- package/dist/runtime/query/iteration/phases/compaction.d.ts +12 -0
- package/dist/runtime/query/iteration/phases/compaction.d.ts.map +1 -1
- package/dist/runtime/query/iteration/phases/compaction.js +48 -1
- package/dist/runtime/query/iteration/phases/compaction.js.map +1 -1
- package/dist/runtime/query/iteration/phases/context.d.ts.map +1 -1
- package/dist/runtime/query/iteration/phases/context.js +5 -0
- package/dist/runtime/query/iteration/phases/context.js.map +1 -1
- package/dist/runtime/query/iteration/stream-turn.js +3 -3
- package/dist/runtime/query/iteration/stream-turn.js.map +1 -1
- package/dist/runtime/query/prelude-lease.d.ts.map +1 -1
- package/dist/runtime/query/prelude-lease.js +22 -0
- package/dist/runtime/query/prelude-lease.js.map +1 -1
- package/dist/runtime/query/prepare-turn.d.ts.map +1 -1
- package/dist/runtime/query/prepare-turn.js +13 -4
- package/dist/runtime/query/prepare-turn.js.map +1 -1
- package/dist/runtime/query/review-policy.d.ts.map +1 -1
- package/dist/runtime/query/review-policy.js +29 -0
- package/dist/runtime/query/review-policy.js.map +1 -1
- package/dist/runtime/query/tooling.d.ts +2 -0
- package/dist/runtime/query/tooling.d.ts.map +1 -1
- package/dist/runtime/query/tooling.js +1 -0
- package/dist/runtime/query/tooling.js.map +1 -1
- package/dist/runtime/query/turn/completion-audit.d.ts +27 -1
- package/dist/runtime/query/turn/completion-audit.d.ts.map +1 -1
- package/dist/runtime/query/turn/completion-audit.js +71 -6
- package/dist/runtime/query/turn/completion-audit.js.map +1 -1
- package/dist/runtime/query/turn/outcome-ledger.d.ts +113 -0
- package/dist/runtime/query/turn/outcome-ledger.d.ts.map +1 -0
- package/dist/runtime/query/turn/outcome-ledger.js +578 -0
- package/dist/runtime/query/turn/outcome-ledger.js.map +1 -0
- package/dist/sandbox/file-walk.d.ts.map +1 -1
- package/dist/sandbox/file-walk.js +34 -17
- package/dist/sandbox/file-walk.js.map +1 -1
- package/dist/sandbox/glob-segment.d.ts +35 -0
- package/dist/sandbox/glob-segment.d.ts.map +1 -0
- package/dist/sandbox/glob-segment.js +300 -0
- package/dist/sandbox/glob-segment.js.map +1 -0
- package/dist/store/session-log/index.d.ts +1 -0
- package/dist/store/session-log/index.d.ts.map +1 -1
- package/dist/store/session-log/index.js +1 -0
- package/dist/store/session-log/index.js.map +1 -1
- package/dist/store/session-log/turn-outcome.d.ts +37 -0
- package/dist/store/session-log/turn-outcome.d.ts.map +1 -0
- package/dist/store/session-log/turn-outcome.js +77 -0
- package/dist/store/session-log/turn-outcome.js.map +1 -0
- package/dist/tools/builtins/bash.js +1 -1
- package/dist/tools/builtins/bash.js.map +1 -1
- package/dist/tools/builtins/edit-apply.d.ts.map +1 -1
- package/dist/tools/builtins/edit-apply.js +24 -3
- package/dist/tools/builtins/edit-apply.js.map +1 -1
- package/dist/tools/builtins/edit.d.ts +31 -17
- package/dist/tools/builtins/edit.d.ts.map +1 -1
- package/dist/tools/builtins/edit.js +92 -27
- package/dist/tools/builtins/edit.js.map +1 -1
- package/dist/tools/builtins/glob.js +1 -1
- package/dist/tools/builtins/glob.js.map +1 -1
- package/dist/tools/builtins/grep.js +1 -1
- package/dist/tools/builtins/grep.js.map +1 -1
- package/dist/tools/builtins/notebook-guard.d.ts +19 -0
- package/dist/tools/builtins/notebook-guard.d.ts.map +1 -0
- package/dist/tools/builtins/notebook-guard.js +75 -0
- package/dist/tools/builtins/notebook-guard.js.map +1 -0
- package/dist/tools/builtins/read-render.d.ts.map +1 -1
- package/dist/tools/builtins/read-render.js +8 -2
- package/dist/tools/builtins/read-render.js.map +1 -1
- package/dist/tools/builtins/write-file.d.ts.map +1 -1
- package/dist/tools/builtins/write-file.js +14 -1
- package/dist/tools/builtins/write-file.js.map +1 -1
- package/dist/tools/coordinator/agent.d.ts.map +1 -1
- package/dist/tools/coordinator/agent.js +25 -6
- package/dist/tools/coordinator/agent.js.map +1 -1
- package/dist/tools/coordinator/index.d.ts.map +1 -1
- package/dist/tools/coordinator/index.js +6 -1
- package/dist/tools/coordinator/index.js.map +1 -1
- package/dist/tools/coordinator/outcome-record.d.ts +22 -0
- package/dist/tools/coordinator/outcome-record.d.ts.map +1 -0
- package/dist/tools/coordinator/outcome-record.js +91 -0
- package/dist/tools/coordinator/outcome-record.js.map +1 -0
- package/dist/tools/defineTool.d.ts +2 -0
- package/dist/tools/defineTool.d.ts.map +1 -1
- package/dist/tools/defineTool.js +1 -0
- package/dist/tools/defineTool.js.map +1 -1
- package/dist/tools/file-read-tracker.d.ts +23 -2
- package/dist/tools/file-read-tracker.d.ts.map +1 -1
- package/dist/tools/file-read-tracker.js +37 -2
- package/dist/tools/file-read-tracker.js.map +1 -1
- package/dist/tools/untrusted-envelope.d.ts +6 -0
- package/dist/tools/untrusted-envelope.d.ts.map +1 -1
- package/dist/tools/untrusted-envelope.js +22 -1
- package/dist/tools/untrusted-envelope.js.map +1 -1
- package/dist/toolsets/manager.d.ts.map +1 -1
- package/dist/toolsets/manager.js +3 -4
- package/dist/toolsets/manager.js.map +1 -1
- package/dist/toolsets/validation-issues.d.ts +27 -0
- package/dist/toolsets/validation-issues.d.ts.map +1 -0
- package/dist/toolsets/validation-issues.js +83 -0
- package/dist/toolsets/validation-issues.js.map +1 -0
- package/dist/turn/memory-recall.d.ts +13 -0
- package/dist/turn/memory-recall.d.ts.map +1 -1
- package/dist/turn/memory-recall.js +18 -0
- package/dist/turn/memory-recall.js.map +1 -1
- package/dist/types/agent/base.d.ts +19 -0
- package/dist/types/agent/base.d.ts.map +1 -1
- package/dist/types/agent/query.d.ts +2 -0
- package/dist/types/agent/query.d.ts.map +1 -1
- package/dist/types/common/index.d.ts +17 -0
- package/dist/types/common/index.d.ts.map +1 -1
- package/dist/types/common/index.js +8 -1
- package/dist/types/common/index.js.map +1 -1
- package/dist/types/hitl/index.d.ts +22 -0
- package/dist/types/hitl/index.d.ts.map +1 -1
- package/dist/types/hitl/index.js.map +1 -1
- package/dist/types/session/config.d.ts +20 -0
- package/dist/types/session/config.d.ts.map +1 -1
- package/dist/types/session/events.d.ts +3 -3
- package/dist/types/session/events.d.ts.map +1 -1
- package/dist/types/session/index.d.ts +1 -0
- package/dist/types/session/index.d.ts.map +1 -1
- package/dist/types/session/index.js +1 -0
- package/dist/types/session/index.js.map +1 -1
- package/dist/types/session/outcome.d.ts +95 -0
- package/dist/types/session/outcome.d.ts.map +1 -0
- package/dist/types/session/outcome.js +45 -0
- package/dist/types/session/outcome.js.map +1 -0
- package/dist/types/session/prepare-step.d.ts +2 -0
- package/dist/types/session/prepare-step.d.ts.map +1 -1
- package/dist/types/session/records.d.ts +167 -2
- package/dist/types/session/records.d.ts.map +1 -1
- package/dist/types/session/records.js +42 -0
- package/dist/types/session/records.js.map +1 -1
- package/dist/types/session/turn.d.ts +18 -0
- package/dist/types/session/turn.d.ts.map +1 -1
- package/dist/types/session/turn.js.map +1 -1
- package/dist/types/tool/index.d.ts +30 -0
- package/dist/types/tool/index.d.ts.map +1 -1
- package/dist/types/tool/index.js.map +1 -1
- package/package.json +2 -2
- package/src/agents/QueryAgent.ts +5 -0
- package/src/agents/examples/SupervisorAgent.ts +1 -0
- package/src/agents/explore.ts +2 -1
- package/src/compaction/index.ts +1 -0
- package/src/compaction/model-summary.ts +2 -2
- package/src/compaction/summary.ts +30 -2
- package/src/config/runtime.ts +15 -0
- package/src/execution/workflow/runtime.ts +4 -0
- package/src/execution/workflow/types.ts +9 -0
- package/src/manager/agent/child-session.ts +36 -0
- package/src/manager/agent/lifecycle.ts +9 -0
- package/src/manager/session/turn-recorder.ts +62 -3
- package/src/pricing/rates.source.json +1 -1
- package/src/prompt/coding-agent-doctrine.ts +5 -3
- package/src/provider/fallback.ts +6 -1
- package/src/provider/retry.ts +51 -0
- package/src/public-runtime.ts +10 -1
- package/src/public-tools.ts +6 -1
- package/src/runtime/query/auto-review/classifier.ts +21 -5
- package/src/runtime/query/auto-review/prompt.ts +2 -0
- package/src/runtime/query/auto-review/script-evidence.ts +618 -0
- package/src/runtime/query/checkpoint.ts +53 -1
- package/src/runtime/query/executor.ts +159 -19
- package/src/runtime/query/finalize-turn.ts +8 -1
- package/src/runtime/query/index.ts +19 -0
- package/src/runtime/query/iteration/index.ts +167 -14
- package/src/runtime/query/iteration/phases/compaction.ts +53 -3
- package/src/runtime/query/iteration/phases/context.ts +6 -0
- package/src/runtime/query/iteration/stream-turn.ts +3 -3
- package/src/runtime/query/prelude-lease.ts +19 -0
- package/src/runtime/query/prepare-turn.ts +13 -4
- package/src/runtime/query/review-policy.ts +33 -0
- package/src/runtime/query/tooling.ts +3 -0
- package/src/runtime/query/turn/completion-audit.ts +76 -5
- package/src/runtime/query/turn/outcome-ledger.ts +633 -0
- package/src/sandbox/file-walk.ts +38 -17
- package/src/sandbox/glob-segment.ts +309 -0
- package/src/store/session-log/index.ts +7 -0
- package/src/store/session-log/turn-outcome.ts +84 -0
- package/src/tools/builtins/bash.ts +1 -1
- package/src/tools/builtins/edit-apply.ts +26 -4
- package/src/tools/builtins/edit.ts +106 -41
- package/src/tools/builtins/glob.ts +1 -1
- package/src/tools/builtins/grep.ts +1 -1
- package/src/tools/builtins/notebook-guard.ts +76 -0
- package/src/tools/builtins/read-render.ts +12 -2
- package/src/tools/builtins/write-file.ts +12 -1
- package/src/tools/coordinator/agent.ts +31 -7
- package/src/tools/coordinator/index.ts +6 -1
- package/src/tools/coordinator/outcome-record.ts +93 -0
- package/src/tools/defineTool.ts +3 -0
- package/src/tools/file-read-tracker.ts +51 -2
- package/src/tools/untrusted-envelope.ts +23 -1
- package/src/toolsets/manager.ts +6 -10
- package/src/toolsets/validation-issues.ts +97 -0
- package/src/turn/memory-recall.ts +28 -0
- package/src/types/agent/base.ts +20 -0
- package/src/types/agent/query.ts +2 -0
- package/src/types/common/index.ts +25 -1
- package/src/types/hitl/index.ts +27 -0
- package/src/types/session/config.ts +20 -0
- package/src/types/session/events.ts +3 -3
- package/src/types/session/index.ts +1 -0
- package/src/types/session/outcome.ts +139 -0
- package/src/types/session/prepare-step.ts +2 -0
- package/src/types/session/records.ts +67 -1
- package/src/types/session/turn.ts +19 -0
- package/src/types/tool/index.ts +30 -0
|
@@ -14,6 +14,7 @@ import { GENAI, NAMZU, agentIterationSpanName, parentContext, } from '../../../t
|
|
|
14
14
|
import { getTracer } from '../../../telemetry/runtime-accessors.js';
|
|
15
15
|
import { STRUCTURED_OUTPUT_TOOL_NAME } from '../../../tools/builtins/structuredOutput.js';
|
|
16
16
|
import { RECALLED_MEMORY_ENTRY_KEY, recalledMemoryIds } from '../../../turn/memory-recall.js';
|
|
17
|
+
import { promptSizeOf } from '../../../types/common/index.js';
|
|
17
18
|
import { NamzuError } from '../../../types/errors/index.js';
|
|
18
19
|
import { createAssistantMessage, createRuntimeContextMessage, createSystemMessage, createToolMessage, turnContextEntries, turnContextKey, } from '../../../types/message/index.js';
|
|
19
20
|
import { classifyProviderError, readOutputOverflow } from '../../../types/provider/errors.js';
|
|
@@ -30,7 +31,8 @@ import { diffRequestContext, snapshotRequestContext, } from '../request-context.
|
|
|
30
31
|
import { markProviderRejectedImage, projectRequestRichContent, resolveMaxRequestRichContentBytes, } from '../request-rich-content.js';
|
|
31
32
|
import { withoutVoidAssistantTurns } from '../request-void-turns.js';
|
|
32
33
|
import { formatSteeringNote, isOperatorUserMessage } from '../steering.js';
|
|
33
|
-
import {
|
|
34
|
+
import { CompletionAudit } from '../turn/completion-audit.js';
|
|
35
|
+
import { OutcomeLedger } from '../turn/outcome-ledger.js';
|
|
34
36
|
import { FORCED_STEP_MESSAGE, REASONING_CAPPED_MESSAGE, REASONING_ONLY_MESSAGE, StallMonitor, callChangedState, reasoningCapChars, } from '../turn/stall-monitor.js';
|
|
35
37
|
import { effortForModel } from './effort-clamp.js';
|
|
36
38
|
import { parseNativeCandidate } from './native-output.js';
|
|
@@ -38,7 +40,7 @@ import { drainArrivedTaskCompletions, holdForOutstandingWork, settleOutstandingW
|
|
|
38
40
|
import { runAdvisoryPhase } from './phases/advisory.js';
|
|
39
41
|
import { runIterationCheckpoint } from './phases/checkpoint.js';
|
|
40
42
|
import { compactionBreaker, estimateRefillTokens } from './phases/compaction-breaker.js';
|
|
41
|
-
import { AUTOMATIC_COMPACTION_FAILED, OVERFLOW_RELIEF_LIMIT, activeContextWindow, clearCompactionErrorNote, compactionErrorNote, measureContext, relieveOverflow, runCompactionCheck, stopOnRefill, } from './phases/compaction.js';
|
|
43
|
+
import { AUTOMATIC_COMPACTION_FAILED, OVERFLOW_RELIEF_LIMIT, activeContextWindow, clearCompactionErrorNote, compactionErrorNote, measureContext, relieveOverflow, runCompactionCheck, runStaleResultClear, stopOnRefill, } from './phases/compaction.js';
|
|
42
44
|
import { runHandoffPause } from './phases/handoff.js';
|
|
43
45
|
import { runPlanGate } from './phases/plan.js';
|
|
44
46
|
import { runToolReview } from './phases/tool-review.js';
|
|
@@ -212,6 +214,9 @@ export class IterationOrchestrator {
|
|
|
212
214
|
stallMonitor;
|
|
213
215
|
/** Holds the turn back once when it changed files and checked nothing afterwards. */
|
|
214
216
|
completionAudit;
|
|
217
|
+
/** What the turn changed and what checked it; see {@link OutcomeLedger}. Kept whether or not the host asked. */
|
|
218
|
+
outcomeLedger;
|
|
219
|
+
outcomeHydrated = false;
|
|
215
220
|
/** The next step must call a tool, at low effort: set by the stall monitor or a capped step. */
|
|
216
221
|
forceActionNextStep = false;
|
|
217
222
|
/** Steps in a row cut at the per-step reasoning cap; past a few the cap stops applying. */
|
|
@@ -238,6 +243,10 @@ export class IterationOrchestrator {
|
|
|
238
243
|
turnEndFired = false;
|
|
239
244
|
/** A hook already kept this turn going once: it is asked again with `stop_hook_active`. */
|
|
240
245
|
stopHookActive = false;
|
|
246
|
+
/** End-of-turn refusals honoured since the last tool call. */
|
|
247
|
+
consecutiveHookRefusals = 0;
|
|
248
|
+
/** The cap was reached and its notice recorded; refusals are ignored for the rest of the turn. */
|
|
249
|
+
hookRefusalCapReached = false;
|
|
241
250
|
get turnEndHooksFired() {
|
|
242
251
|
return this.turnEndFired;
|
|
243
252
|
}
|
|
@@ -249,6 +258,10 @@ export class IterationOrchestrator {
|
|
|
249
258
|
* are returned, joined, as feedback for the model. A hook that asks for the
|
|
250
259
|
* turn to halt wins over any such feedback (`takeHalt`). With nothing asked,
|
|
251
260
|
* the events have fired for this turn and the finalizer does not repeat them.
|
|
261
|
+
*
|
|
262
|
+
* Refusals are counted in a row (a tool call in between starts the count
|
|
263
|
+
* over). Once `maxHookRefusals` have been honoured the next one is not: the
|
|
264
|
+
* turn ends, with one notice that names the hook.
|
|
252
265
|
*/
|
|
253
266
|
async *askStopHooks() {
|
|
254
267
|
const manager = this.ctx.pluginManager;
|
|
@@ -256,6 +269,12 @@ export class IterationOrchestrator {
|
|
|
256
269
|
return undefined;
|
|
257
270
|
const recorder = this.ctx.recorder;
|
|
258
271
|
const feedback = [];
|
|
272
|
+
const refusers = [];
|
|
273
|
+
const emit = async (event) => {
|
|
274
|
+
if (event.type === 'plugin_hook_completed' && event.result.action === 'skip')
|
|
275
|
+
refusers.push(String(event.pluginId));
|
|
276
|
+
await this.ctx.emitEvent(event);
|
|
277
|
+
};
|
|
259
278
|
const ask = async (event, extra) => {
|
|
260
279
|
const results = await manager.executeHooks(event, {
|
|
261
280
|
sessionId: recorder.sessionId,
|
|
@@ -263,7 +282,7 @@ export class IterationOrchestrator {
|
|
|
263
282
|
...extra,
|
|
264
283
|
...(this.stopHookActive ? { stopHookActive: true } : {}),
|
|
265
284
|
signal: this.ctx.abortController.signal,
|
|
266
|
-
},
|
|
285
|
+
}, emit);
|
|
267
286
|
applyLifecycleHookResults(event, results);
|
|
268
287
|
for (const result of results) {
|
|
269
288
|
if (result.action === 'skip')
|
|
@@ -283,10 +302,30 @@ export class IterationOrchestrator {
|
|
|
283
302
|
});
|
|
284
303
|
yield* this.ctx.drainPending();
|
|
285
304
|
}
|
|
286
|
-
|
|
305
|
+
// Once the cap has been reached, refusals stay ignored for the rest of the turn,
|
|
306
|
+
// whatever a tool call does to the count; a halt was already passed on above.
|
|
307
|
+
if (feedback.length === 0 || this.hookRefusalCapReached) {
|
|
287
308
|
this.turnEndFired = true;
|
|
288
309
|
return undefined;
|
|
289
310
|
}
|
|
311
|
+
const limit = this.ctx.turnConfig.maxHookRefusals ?? 0;
|
|
312
|
+
if (limit > 0 && this.consecutiveHookRefusals >= limit) {
|
|
313
|
+
// The turn has been kept going `limit` times in a row. A hook that
|
|
314
|
+
// still refuses is not going to stop; say so once, and let the turn end.
|
|
315
|
+
this.turnEndFired = true;
|
|
316
|
+
if (!this.hookRefusalCapReached) {
|
|
317
|
+
this.hookRefusalCapReached = true;
|
|
318
|
+
const names = [...new Set(refusers)];
|
|
319
|
+
const who = names.length > 0 ? names.map((n) => `"${n}"`).join(', ') : 'A hook';
|
|
320
|
+
recorder.pushMessage(createRuntimeContextMessage(`${who} asked for more before this turn could end ${limit} times in a row. Namzu is ending the turn anyway and will not honour further requests from it this turn.`, 'hook-feedback'));
|
|
321
|
+
this.ctx.log.warn('Hook refusal limit reached — ending the turn', {
|
|
322
|
+
[NAMZU.TURN_ID]: recorder.turnId,
|
|
323
|
+
'namzu.runtime.limit': limit,
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
return undefined;
|
|
327
|
+
}
|
|
328
|
+
this.consecutiveHookRefusals++;
|
|
290
329
|
this.stopHookActive = true;
|
|
291
330
|
return feedback.join('\n');
|
|
292
331
|
}
|
|
@@ -304,6 +343,13 @@ export class IterationOrchestrator {
|
|
|
304
343
|
};
|
|
305
344
|
if (ctx.turnConfig.completionAudit === true)
|
|
306
345
|
this.completionAudit = new CompletionAudit();
|
|
346
|
+
this.outcomeLedger = new OutcomeLedger(ctx.turnConfig.outcome);
|
|
347
|
+
ctx.checkpointMgr.setOutcomeSource?.(() => {
|
|
348
|
+
this.hydrateOutcome();
|
|
349
|
+
return this.outcomeLedger.recorded
|
|
350
|
+
? this.outcomeLedger.snapshot()
|
|
351
|
+
: undefined;
|
|
352
|
+
});
|
|
307
353
|
if (ctx.turnConfig.reasoning?.stall !== false) {
|
|
308
354
|
this.stallMonitor = new StallMonitor(ctx.turnConfig.reasoning?.stall || undefined);
|
|
309
355
|
}
|
|
@@ -640,6 +686,8 @@ export class IterationOrchestrator {
|
|
|
640
686
|
// edge BEFORE compaction runs (so the refreshed slot is what
|
|
641
687
|
// compaction preserves). No-op when no provider is configured.
|
|
642
688
|
await refreshWorkingMemory(this.ctx);
|
|
689
|
+
if (iterationNum === 1)
|
|
690
|
+
await runStaleResultClear(this.ctx);
|
|
643
691
|
await runCompactionCheck(this.ctx);
|
|
644
692
|
yield* this.ctx.drainPending();
|
|
645
693
|
if (this.stopForCompactionBreaker())
|
|
@@ -1089,7 +1137,7 @@ export class IterationOrchestrator {
|
|
|
1089
1137
|
'namzu.runtime.finish_reason': response.finishReason,
|
|
1090
1138
|
'namzu.runtime.has_content': response.message.content !== null && response.message.content.length > 0,
|
|
1091
1139
|
'namzu.runtime.tool_call_count': response.message.toolCalls?.length ?? 0,
|
|
1092
|
-
[GENAI.USAGE_INPUT_TOKENS]: response.usage
|
|
1140
|
+
[GENAI.USAGE_INPUT_TOKENS]: promptSizeOf(response.usage),
|
|
1093
1141
|
[GENAI.USAGE_OUTPUT_TOKENS]: response.usage.completionTokens,
|
|
1094
1142
|
'namzu.usage.total_tokens': recorder.tokenUsage.totalTokens,
|
|
1095
1143
|
'namzu.runtime.total_cost': recorder.costInfo.totalCost,
|
|
@@ -1187,7 +1235,7 @@ export class IterationOrchestrator {
|
|
|
1187
1235
|
}
|
|
1188
1236
|
yield* this.ctx.drainPending();
|
|
1189
1237
|
iterSpan.setAttributes({
|
|
1190
|
-
[GENAI.USAGE_INPUT_TOKENS]: response.usage
|
|
1238
|
+
[GENAI.USAGE_INPUT_TOKENS]: promptSizeOf(response.usage),
|
|
1191
1239
|
[GENAI.USAGE_OUTPUT_TOKENS]: response.usage.completionTokens,
|
|
1192
1240
|
});
|
|
1193
1241
|
iterSpan.setStatus({ code: SpanStatusCode.OK });
|
|
@@ -1609,13 +1657,14 @@ export class IterationOrchestrator {
|
|
|
1609
1657
|
// back to the model and the turn goes on.
|
|
1610
1658
|
// Files were changed and nothing checked them afterwards: ask once
|
|
1611
1659
|
// for a check before the turn is allowed to end.
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1660
|
+
const auditReminder = !forceFinalize && closingStopReason === undefined
|
|
1661
|
+
? this.completionAudit?.takeReminder(() => this.outcomeLedger.peek())
|
|
1662
|
+
: undefined;
|
|
1663
|
+
if (auditReminder !== undefined) {
|
|
1615
1664
|
this.ctx.log.info('Files changed and nothing checked them — asking for a check', {
|
|
1616
1665
|
[NAMZU.TURN_ID]: recorder.turnId,
|
|
1617
1666
|
});
|
|
1618
|
-
recorder.pushMessage(createRuntimeContextMessage(
|
|
1667
|
+
recorder.pushMessage(createRuntimeContextMessage(auditReminder, 'progress-nudge'));
|
|
1619
1668
|
continue;
|
|
1620
1669
|
}
|
|
1621
1670
|
if (!forceFinalize && closingStopReason === undefined) {
|
|
@@ -1635,6 +1684,9 @@ export class IterationOrchestrator {
|
|
|
1635
1684
|
(stopWasDeferredForOutstandingWork ? 'stop_condition' : 'end_turn'));
|
|
1636
1685
|
break;
|
|
1637
1686
|
}
|
|
1687
|
+
// A real tool call: whatever a hook refused before it is behind us.
|
|
1688
|
+
this.consecutiveHookRefusals = 0;
|
|
1689
|
+
await this.outcomeBefore(response);
|
|
1638
1690
|
const reviewOutcome = yield* runToolReview(this.ctx, response, iterationNum);
|
|
1639
1691
|
// The step record is built even for a rejected batch: a turn that
|
|
1640
1692
|
// spent a turn getting its tools refused still spent the tokens,
|
|
@@ -1658,6 +1710,7 @@ export class IterationOrchestrator {
|
|
|
1658
1710
|
this.reasoningOnlyRetried = false;
|
|
1659
1711
|
this.observeStall(response, reviewOutcome.results);
|
|
1660
1712
|
this.observeAudit(response, reviewOutcome.results);
|
|
1713
|
+
await this.outcomeObserve(iterationNum, response, reviewOutcome.results);
|
|
1661
1714
|
if (reviewOutcome.decision === 'stop') {
|
|
1662
1715
|
return;
|
|
1663
1716
|
}
|
|
@@ -2814,6 +2867,101 @@ export class IterationOrchestrator {
|
|
|
2814
2867
|
return undefined;
|
|
2815
2868
|
}
|
|
2816
2869
|
}
|
|
2870
|
+
/**
|
|
2871
|
+
* Take back the outcome record a checkpoint kept. Done at first use rather
|
|
2872
|
+
* than at construction: the checkpoint is read after this is built. A turn
|
|
2873
|
+
* resumed from a checkpoint with no record cannot say what came before it,
|
|
2874
|
+
* so it keeps none.
|
|
2875
|
+
*/
|
|
2876
|
+
hydrateOutcome() {
|
|
2877
|
+
if (this.outcomeHydrated)
|
|
2878
|
+
return;
|
|
2879
|
+
this.outcomeHydrated = true;
|
|
2880
|
+
const restored = this.ctx.checkpointMgr.restoredOutcome;
|
|
2881
|
+
if (restored?.resumed !== true)
|
|
2882
|
+
return;
|
|
2883
|
+
if (restored.snapshot === undefined)
|
|
2884
|
+
this.outcomeLedger.markUnrecorded();
|
|
2885
|
+
else
|
|
2886
|
+
this.outcomeLedger.restore(restored.snapshot);
|
|
2887
|
+
}
|
|
2888
|
+
/** Whether a call is one the outcome record may treat as only looking. */
|
|
2889
|
+
lookedOnly(toolName, input) {
|
|
2890
|
+
try {
|
|
2891
|
+
return !callChangedState(toolName, this.ctx.tools.get(toolName)?.isReadOnly?.(input), false);
|
|
2892
|
+
}
|
|
2893
|
+
catch {
|
|
2894
|
+
return false;
|
|
2895
|
+
}
|
|
2896
|
+
}
|
|
2897
|
+
parsedInput(call) {
|
|
2898
|
+
try {
|
|
2899
|
+
return call ? JSON.parse(call.function.arguments) : undefined;
|
|
2900
|
+
}
|
|
2901
|
+
catch {
|
|
2902
|
+
return undefined;
|
|
2903
|
+
}
|
|
2904
|
+
}
|
|
2905
|
+
/**
|
|
2906
|
+
* Before a step's calls run: the first one that could change the workspace
|
|
2907
|
+
* takes the starting fingerprint. A failure here must not fail the turn.
|
|
2908
|
+
*/
|
|
2909
|
+
async outcomeBefore(response) {
|
|
2910
|
+
try {
|
|
2911
|
+
this.hydrateOutcome();
|
|
2912
|
+
const pending = (response.message.toolCalls ?? []).map((call) => {
|
|
2913
|
+
const input = this.parsedInput(call);
|
|
2914
|
+
return {
|
|
2915
|
+
toolName: call.function.name,
|
|
2916
|
+
input,
|
|
2917
|
+
readOnly: this.lookedOnly(call.function.name, input),
|
|
2918
|
+
};
|
|
2919
|
+
});
|
|
2920
|
+
await this.outcomeLedger.before(pending);
|
|
2921
|
+
}
|
|
2922
|
+
catch (err) {
|
|
2923
|
+
this.ctx.log.warn('The outcome record could not take its starting point', {
|
|
2924
|
+
'exception.message': toErrorMessage(err),
|
|
2925
|
+
});
|
|
2926
|
+
}
|
|
2927
|
+
}
|
|
2928
|
+
/** Feed the outcome record the calls of one finished step. */
|
|
2929
|
+
async outcomeObserve(step, response, results) {
|
|
2930
|
+
try {
|
|
2931
|
+
this.hydrateOutcome();
|
|
2932
|
+
const calls = new Map((response.message.toolCalls ?? []).map((c) => [c.id, c]));
|
|
2933
|
+
const seen = results.map((result) => {
|
|
2934
|
+
const input = this.parsedInput(calls.get(result.toolCallId));
|
|
2935
|
+
return {
|
|
2936
|
+
toolName: result.toolName,
|
|
2937
|
+
input,
|
|
2938
|
+
isError: result.isError,
|
|
2939
|
+
...(result.skipped ? { skipped: true } : {}),
|
|
2940
|
+
readOnly: this.lookedOnly(result.toolName, input),
|
|
2941
|
+
...(result.facts ? { facts: result.facts } : {}),
|
|
2942
|
+
};
|
|
2943
|
+
});
|
|
2944
|
+
await this.outcomeLedger.observe(step, seen);
|
|
2945
|
+
}
|
|
2946
|
+
catch (err) {
|
|
2947
|
+
this.ctx.log.warn('The outcome record could not read a step', {
|
|
2948
|
+
'exception.message': toErrorMessage(err),
|
|
2949
|
+
});
|
|
2950
|
+
}
|
|
2951
|
+
}
|
|
2952
|
+
/** The outcome record as the turn leaves it; `undefined` when none was kept. */
|
|
2953
|
+
async takeOutcome() {
|
|
2954
|
+
try {
|
|
2955
|
+
this.hydrateOutcome();
|
|
2956
|
+
return await this.outcomeLedger.finish();
|
|
2957
|
+
}
|
|
2958
|
+
catch (err) {
|
|
2959
|
+
this.ctx.log.warn('The outcome record could not be settled', {
|
|
2960
|
+
'exception.message': toErrorMessage(err),
|
|
2961
|
+
});
|
|
2962
|
+
return undefined;
|
|
2963
|
+
}
|
|
2964
|
+
}
|
|
2817
2965
|
/** Feed the completion audit the calls of one finished step. */
|
|
2818
2966
|
observeAudit(response, results) {
|
|
2819
2967
|
const audit = this.completionAudit;
|