@namzu/sdk 35.0.0 → 37.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 +218 -0
- package/README.md +68 -41
- package/dist/bridge/a2a/mapper.d.ts.map +1 -1
- package/dist/bridge/a2a/mapper.js +2 -0
- package/dist/bridge/a2a/mapper.js.map +1 -1
- package/dist/bridge/sse/mapper.d.ts.map +1 -1
- package/dist/bridge/sse/mapper.js +2 -0
- package/dist/bridge/sse/mapper.js.map +1 -1
- package/dist/compaction/extractor.d.ts +1 -1
- package/dist/compaction/extractor.d.ts.map +1 -1
- package/dist/compaction/extractor.js +15 -7
- package/dist/compaction/extractor.js.map +1 -1
- package/dist/compaction/manager.d.ts +2 -0
- package/dist/compaction/manager.d.ts.map +1 -1
- package/dist/compaction/manager.js +12 -1
- package/dist/compaction/manager.js.map +1 -1
- package/dist/compaction/verifier.d.ts.map +1 -1
- package/dist/compaction/verifier.js +82 -15
- package/dist/compaction/verifier.js.map +1 -1
- package/dist/contracts/schemas.d.ts +10 -10
- package/dist/eval/harness-verification.d.ts +63 -0
- package/dist/eval/harness-verification.d.ts.map +1 -0
- package/dist/eval/harness-verification.js +165 -0
- package/dist/eval/harness-verification.js.map +1 -0
- package/dist/eval/index.d.ts +2 -0
- package/dist/eval/index.d.ts.map +1 -1
- package/dist/eval/index.js +1 -0
- package/dist/eval/index.js.map +1 -1
- package/dist/execution/code-runtime/json-value.d.ts +10 -0
- package/dist/execution/code-runtime/json-value.d.ts.map +1 -0
- package/dist/execution/code-runtime/json-value.js +89 -0
- package/dist/execution/code-runtime/json-value.js.map +1 -0
- package/dist/execution/code-runtime/worker-program.d.ts +8 -0
- package/dist/execution/code-runtime/worker-program.d.ts.map +1 -0
- package/dist/execution/code-runtime/worker-program.js +240 -0
- package/dist/execution/code-runtime/worker-program.js.map +1 -0
- package/dist/execution/code-runtime/worker.d.ts +22 -0
- package/dist/execution/code-runtime/worker.d.ts.map +1 -1
- package/dist/execution/code-runtime/worker.js +148 -111
- package/dist/execution/code-runtime/worker.js.map +1 -1
- package/dist/manager/agent/lifecycle.d.ts +12 -0
- package/dist/manager/agent/lifecycle.d.ts.map +1 -1
- package/dist/manager/agent/lifecycle.js +306 -37
- package/dist/manager/agent/lifecycle.js.map +1 -1
- package/dist/manager/run/persistence.d.ts +2 -0
- package/dist/manager/run/persistence.d.ts.map +1 -1
- package/dist/manager/run/persistence.js +6 -0
- package/dist/manager/run/persistence.js.map +1 -1
- package/dist/provider/capabilities.d.ts +3 -1
- package/dist/provider/capabilities.d.ts.map +1 -1
- package/dist/provider/capabilities.js +13 -0
- package/dist/provider/capabilities.js.map +1 -1
- package/dist/provider/fallback.d.ts.map +1 -1
- package/dist/provider/fallback.js +2 -0
- package/dist/provider/fallback.js.map +1 -1
- package/dist/provider/token-budget.d.ts.map +1 -1
- package/dist/provider/token-budget.js +56 -8
- package/dist/provider/token-budget.js.map +1 -1
- package/dist/public-runtime.d.ts +5 -3
- package/dist/public-runtime.d.ts.map +1 -1
- package/dist/public-runtime.js +3 -2
- package/dist/public-runtime.js.map +1 -1
- package/dist/public-tools.d.ts +1 -1
- package/dist/public-tools.d.ts.map +1 -1
- package/dist/public-tools.js +1 -1
- package/dist/public-tools.js.map +1 -1
- package/dist/public-types.d.ts +1 -0
- package/dist/public-types.d.ts.map +1 -1
- package/dist/registry/tool/execute.d.ts +3 -0
- package/dist/registry/tool/execute.d.ts.map +1 -1
- package/dist/registry/tool/execute.js +11 -80
- package/dist/registry/tool/execute.js.map +1 -1
- package/dist/run/command-gate.d.ts.map +1 -1
- package/dist/run/command-gate.js +65 -12
- package/dist/run/command-gate.js.map +1 -1
- package/dist/run/index.d.ts +2 -0
- package/dist/run/index.d.ts.map +1 -1
- package/dist/run/index.js +1 -0
- package/dist/run/index.js.map +1 -1
- package/dist/run/memory-promoter.d.ts +3 -35
- package/dist/run/memory-promoter.d.ts.map +1 -1
- package/dist/run/memory-promoter.js +32 -40
- package/dist/run/memory-promoter.js.map +1 -1
- package/dist/run/memory-recall.d.ts +25 -0
- package/dist/run/memory-recall.d.ts.map +1 -0
- package/dist/run/memory-recall.js +228 -0
- package/dist/run/memory-recall.js.map +1 -0
- package/dist/run/reporter.d.ts.map +1 -1
- package/dist/run/reporter.js +1 -0
- package/dist/run/reporter.js.map +1 -1
- package/dist/run/token-budget.d.ts +2 -0
- package/dist/run/token-budget.d.ts.map +1 -1
- package/dist/run/token-budget.js +4 -0
- package/dist/run/token-budget.js.map +1 -1
- package/dist/run/workspace-fingerprint.d.ts +10 -3
- package/dist/run/workspace-fingerprint.d.ts.map +1 -1
- package/dist/run/workspace-fingerprint.js +17 -8
- package/dist/run/workspace-fingerprint.js.map +1 -1
- package/dist/runtime/query/checkpoint.d.ts +14 -0
- package/dist/runtime/query/checkpoint.d.ts.map +1 -1
- package/dist/runtime/query/checkpoint.js +82 -1
- package/dist/runtime/query/checkpoint.js.map +1 -1
- package/dist/runtime/query/executor.d.ts +6 -0
- package/dist/runtime/query/executor.d.ts.map +1 -1
- package/dist/runtime/query/executor.js +120 -24
- package/dist/runtime/query/executor.js.map +1 -1
- package/dist/runtime/query/index.d.ts +12 -8
- package/dist/runtime/query/index.d.ts.map +1 -1
- package/dist/runtime/query/index.js +55 -7
- package/dist/runtime/query/index.js.map +1 -1
- package/dist/runtime/query/iteration/index.d.ts +13 -3
- package/dist/runtime/query/iteration/index.d.ts.map +1 -1
- package/dist/runtime/query/iteration/index.js +356 -42
- package/dist/runtime/query/iteration/index.js.map +1 -1
- package/dist/runtime/query/iteration/native-output.d.ts +10 -0
- package/dist/runtime/query/iteration/native-output.d.ts.map +1 -0
- package/dist/runtime/query/iteration/native-output.js +32 -0
- package/dist/runtime/query/iteration/native-output.js.map +1 -0
- package/dist/runtime/query/iteration/phases/advisory.d.ts.map +1 -1
- package/dist/runtime/query/iteration/phases/advisory.js +18 -13
- package/dist/runtime/query/iteration/phases/advisory.js.map +1 -1
- package/dist/runtime/query/iteration/phases/compaction.d.ts +2 -0
- package/dist/runtime/query/iteration/phases/compaction.d.ts.map +1 -1
- package/dist/runtime/query/iteration/phases/compaction.js +32 -11
- package/dist/runtime/query/iteration/phases/compaction.js.map +1 -1
- package/dist/runtime/query/iteration/phases/context.d.ts +11 -0
- package/dist/runtime/query/iteration/phases/context.d.ts.map +1 -1
- package/dist/runtime/query/iteration/phases/context.js.map +1 -1
- package/dist/runtime/query/iteration/phases/tool-review.d.ts.map +1 -1
- package/dist/runtime/query/iteration/phases/tool-review.js +1 -1
- package/dist/runtime/query/iteration/phases/tool-review.js.map +1 -1
- package/dist/runtime/query/iteration/phases/working-memory.d.ts +1 -1
- package/dist/runtime/query/iteration/phases/working-memory.d.ts.map +1 -1
- package/dist/runtime/query/iteration/phases/working-memory.js +23 -6
- package/dist/runtime/query/iteration/phases/working-memory.js.map +1 -1
- package/dist/runtime/query/iteration/stream-turn.d.ts.map +1 -1
- package/dist/runtime/query/iteration/stream-turn.js +12 -5
- package/dist/runtime/query/iteration/stream-turn.js.map +1 -1
- package/dist/runtime/query/prompt.d.ts.map +1 -1
- package/dist/runtime/query/prompt.js +14 -4
- package/dist/runtime/query/prompt.js.map +1 -1
- package/dist/runtime/query/steering.d.ts +6 -2
- package/dist/runtime/query/steering.d.ts.map +1 -1
- package/dist/runtime/query/steering.js +17 -2
- package/dist/runtime/query/steering.js.map +1 -1
- package/dist/runtime/query/tool-call-budget.d.ts +19 -0
- package/dist/runtime/query/tool-call-budget.d.ts.map +1 -0
- package/dist/runtime/query/tool-call-budget.js +110 -0
- package/dist/runtime/query/tool-call-budget.js.map +1 -0
- package/dist/runtime/query/tooling.d.ts +2 -0
- package/dist/runtime/query/tooling.d.ts.map +1 -1
- package/dist/runtime/query/tooling.js +4 -0
- package/dist/runtime/query/tooling.js.map +1 -1
- package/dist/sandbox/file-walk-program.d.ts +3 -0
- package/dist/sandbox/file-walk-program.d.ts.map +1 -0
- package/dist/sandbox/file-walk-program.js +94 -0
- package/dist/sandbox/file-walk-program.js.map +1 -0
- package/dist/sandbox/file-walk.d.ts +12 -0
- package/dist/sandbox/file-walk.d.ts.map +1 -0
- package/dist/sandbox/file-walk.js +429 -0
- package/dist/sandbox/file-walk.js.map +1 -0
- package/dist/sandbox/index.d.ts +2 -0
- package/dist/sandbox/index.d.ts.map +1 -1
- package/dist/sandbox/index.js +1 -0
- package/dist/sandbox/index.js.map +1 -1
- package/dist/sandbox/provider/local.d.ts.map +1 -1
- package/dist/sandbox/provider/local.js +9 -0
- package/dist/sandbox/provider/local.js.map +1 -1
- package/dist/scheduler/completion-inbox.d.ts +3 -2
- package/dist/scheduler/completion-inbox.d.ts.map +1 -1
- package/dist/scheduler/completion-inbox.js +29 -15
- package/dist/scheduler/completion-inbox.js.map +1 -1
- package/dist/scheduler/local.d.ts.map +1 -1
- package/dist/scheduler/local.js +1 -0
- package/dist/scheduler/local.js.map +1 -1
- package/dist/session/handoff/capacity.d.ts +2 -2
- package/dist/session/handoff/capacity.d.ts.map +1 -1
- package/dist/session/handoff/capacity.js +3 -2
- package/dist/session/handoff/capacity.js.map +1 -1
- package/dist/store/memory/disk.d.ts +6 -2
- package/dist/store/memory/disk.d.ts.map +1 -1
- package/dist/store/memory/disk.js +42 -25
- package/dist/store/memory/disk.js.map +1 -1
- package/dist/store/memory/index.d.ts +4 -0
- package/dist/store/memory/index.d.ts.map +1 -1
- package/dist/store/memory/index.js +55 -19
- package/dist/store/memory/index.js.map +1 -1
- package/dist/store/memory/memory.d.ts +3 -2
- package/dist/store/memory/memory.d.ts.map +1 -1
- package/dist/store/memory/memory.js +11 -2
- package/dist/store/memory/memory.js.map +1 -1
- package/dist/store/memory/operation-lock.d.ts +11 -0
- package/dist/store/memory/operation-lock.d.ts.map +1 -0
- package/dist/store/memory/operation-lock.js +94 -0
- package/dist/store/memory/operation-lock.js.map +1 -0
- package/dist/tools/builtins/bash.d.ts.map +1 -1
- package/dist/tools/builtins/bash.js +215 -59
- package/dist/tools/builtins/bash.js.map +1 -1
- package/dist/tools/builtins/computer-use.d.ts.map +1 -1
- package/dist/tools/builtins/computer-use.js +60 -10
- package/dist/tools/builtins/computer-use.js.map +1 -1
- package/dist/tools/builtins/glob.d.ts +2 -1
- package/dist/tools/builtins/glob.d.ts.map +1 -1
- package/dist/tools/builtins/glob.js +95 -103
- package/dist/tools/builtins/glob.js.map +1 -1
- package/dist/tools/builtins/grep.d.ts.map +1 -1
- package/dist/tools/builtins/grep.js +155 -111
- package/dist/tools/builtins/grep.js.map +1 -1
- package/dist/tools/builtins/ls.js +2 -2
- package/dist/tools/builtins/ls.js.map +1 -1
- package/dist/tools/builtins/run-code.d.ts +6 -0
- package/dist/tools/builtins/run-code.d.ts.map +1 -1
- package/dist/tools/builtins/run-code.js +15 -4
- package/dist/tools/builtins/run-code.js.map +1 -1
- package/dist/tools/builtins/search-tools.d.ts.map +1 -1
- package/dist/tools/builtins/search-tools.js +14 -2
- package/dist/tools/builtins/search-tools.js.map +1 -1
- package/dist/tools/defineTool.d.ts +2 -0
- package/dist/tools/defineTool.d.ts.map +1 -1
- package/dist/tools/defineTool.js +3 -0
- package/dist/tools/defineTool.js.map +1 -1
- package/dist/tools/memory/delete.d.ts +4 -0
- package/dist/tools/memory/delete.d.ts.map +1 -0
- package/dist/tools/memory/delete.js +26 -0
- package/dist/tools/memory/delete.js.map +1 -0
- package/dist/tools/memory/index.d.ts +2 -0
- package/dist/tools/memory/index.d.ts.map +1 -1
- package/dist/tools/memory/index.js +6 -0
- package/dist/tools/memory/index.js.map +1 -1
- package/dist/tools/memory/save.d.ts.map +1 -1
- package/dist/tools/memory/save.js +3 -2
- package/dist/tools/memory/save.js.map +1 -1
- package/dist/tools/memory/search.d.ts.map +1 -1
- package/dist/tools/memory/search.js +12 -5
- package/dist/tools/memory/search.js.map +1 -1
- package/dist/tools/memory/update.d.ts +4 -0
- package/dist/tools/memory/update.d.ts.map +1 -0
- package/dist/tools/memory/update.js +47 -0
- package/dist/tools/memory/update.js.map +1 -0
- package/dist/types/agent/scheduler.d.ts +5 -0
- package/dist/types/agent/scheduler.d.ts.map +1 -1
- package/dist/types/agent/task.d.ts +10 -0
- package/dist/types/agent/task.d.ts.map +1 -1
- package/dist/types/computer-use/index.d.ts +6 -0
- package/dist/types/computer-use/index.d.ts.map +1 -1
- package/dist/types/computer-use/index.js.map +1 -1
- package/dist/types/errors/catalog.js +1 -1
- package/dist/types/errors/catalog.js.map +1 -1
- package/dist/types/hitl/index.d.ts +11 -1
- package/dist/types/hitl/index.d.ts.map +1 -1
- package/dist/types/hitl/index.js.map +1 -1
- package/dist/types/memory/index.d.ts +14 -1
- package/dist/types/memory/index.d.ts.map +1 -1
- package/dist/types/project/entity.d.ts +1 -0
- package/dist/types/project/entity.d.ts.map +1 -1
- package/dist/types/provider/config.d.ts +2 -0
- package/dist/types/provider/config.d.ts.map +1 -1
- package/dist/types/provider/model.d.ts +4 -0
- package/dist/types/provider/model.d.ts.map +1 -1
- package/dist/types/run/answer-review.d.ts +2 -0
- package/dist/types/run/answer-review.d.ts.map +1 -1
- package/dist/types/run/events.d.ts +9 -0
- package/dist/types/run/events.d.ts.map +1 -1
- package/dist/types/run/events.js.map +1 -1
- package/dist/types/run/prepare-step.d.ts +19 -1
- package/dist/types/run/prepare-step.d.ts.map +1 -1
- package/dist/types/sandbox/index.d.ts +20 -0
- package/dist/types/sandbox/index.d.ts.map +1 -1
- package/dist/types/sandbox/index.js.map +1 -1
- package/dist/types/structured-output/index.d.ts +8 -2
- package/dist/types/structured-output/index.d.ts.map +1 -1
- package/dist/types/tool/index.d.ts +15 -0
- package/dist/types/tool/index.d.ts.map +1 -1
- package/dist/types/tool/index.js.map +1 -1
- package/dist/utils/json-snapshot.d.ts +3 -0
- package/dist/utils/json-snapshot.d.ts.map +1 -0
- package/dist/utils/json-snapshot.js +79 -0
- package/dist/utils/json-snapshot.js.map +1 -0
- package/package.json +8 -1
- package/src/bridge/a2a/mapper.ts +2 -0
- package/src/bridge/sse/mapper.ts +2 -0
- package/src/compaction/extractor.ts +21 -8
- package/src/compaction/manager.ts +11 -1
- package/src/compaction/verifier.ts +80 -18
- package/src/eval/harness-verification.ts +270 -0
- package/src/eval/index.ts +10 -0
- package/src/execution/code-runtime/json-value.ts +82 -0
- package/src/execution/code-runtime/worker-program.ts +239 -0
- package/src/execution/code-runtime/worker.ts +164 -111
- package/src/manager/agent/lifecycle.ts +340 -45
- package/src/manager/run/persistence.ts +7 -0
- package/src/provider/capabilities.ts +25 -1
- package/src/provider/fallback.ts +2 -0
- package/src/provider/token-budget.ts +52 -8
- package/src/public-runtime.ts +6 -1
- package/src/public-tools.ts +5 -1
- package/src/public-types.ts +1 -0
- package/src/registry/tool/execute.ts +17 -79
- package/src/run/command-gate.ts +61 -13
- package/src/run/index.ts +2 -0
- package/src/run/memory-promoter.ts +32 -40
- package/src/run/memory-recall.ts +254 -0
- package/src/run/reporter.ts +1 -0
- package/src/run/token-budget.ts +4 -0
- package/src/run/workspace-fingerprint.ts +17 -8
- package/src/runtime/query/checkpoint.ts +96 -2
- package/src/runtime/query/executor.ts +131 -28
- package/src/runtime/query/index.ts +81 -16
- package/src/runtime/query/iteration/index.ts +406 -53
- package/src/runtime/query/iteration/native-output.ts +35 -0
- package/src/runtime/query/iteration/phases/advisory.ts +21 -11
- package/src/runtime/query/iteration/phases/compaction.ts +36 -14
- package/src/runtime/query/iteration/phases/context.ts +11 -0
- package/src/runtime/query/iteration/phases/tool-review.ts +5 -1
- package/src/runtime/query/iteration/phases/working-memory.ts +23 -5
- package/src/runtime/query/iteration/stream-turn.ts +11 -5
- package/src/runtime/query/prompt.ts +21 -4
- package/src/runtime/query/steering.ts +19 -2
- package/src/runtime/query/tool-call-budget.ts +115 -0
- package/src/runtime/query/tooling.ts +6 -0
- package/src/sandbox/file-walk-program.ts +93 -0
- package/src/sandbox/file-walk.ts +463 -0
- package/src/sandbox/index.ts +2 -0
- package/src/sandbox/provider/local.ts +13 -0
- package/src/scheduler/completion-inbox.ts +29 -19
- package/src/scheduler/local.ts +1 -0
- package/src/session/handoff/capacity.ts +7 -3
- package/src/store/memory/disk.ts +52 -30
- package/src/store/memory/index.ts +75 -27
- package/src/store/memory/memory.ts +18 -6
- package/src/store/memory/operation-lock.ts +99 -0
- package/src/tools/builtins/bash.ts +230 -58
- package/src/tools/builtins/computer-use.ts +61 -7
- package/src/tools/builtins/glob.ts +104 -122
- package/src/tools/builtins/grep.ts +166 -132
- package/src/tools/builtins/ls.ts +2 -2
- package/src/tools/builtins/run-code.ts +24 -5
- package/src/tools/builtins/search-tools.ts +18 -3
- package/src/tools/defineTool.ts +5 -0
- package/src/tools/memory/delete.ts +29 -0
- package/src/tools/memory/index.ts +6 -0
- package/src/tools/memory/save.ts +4 -2
- package/src/tools/memory/search.ts +12 -5
- package/src/tools/memory/update.ts +50 -0
- package/src/types/agent/scheduler.ts +6 -0
- package/src/types/agent/task.ts +13 -0
- package/src/types/computer-use/index.ts +6 -0
- package/src/types/errors/catalog.ts +1 -1
- package/src/types/hitl/index.ts +11 -1
- package/src/types/memory/index.ts +16 -1
- package/src/types/project/entity.ts +1 -0
- package/src/types/provider/config.ts +2 -0
- package/src/types/provider/model.ts +4 -0
- package/src/types/run/answer-review.ts +2 -0
- package/src/types/run/events.ts +10 -0
- package/src/types/run/prepare-step.ts +19 -1
- package/src/types/sandbox/index.ts +21 -0
- package/src/types/structured-output/index.ts +15 -2
- package/src/types/tool/index.ts +16 -0
- package/src/utils/json-snapshot.ts +76 -0
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { SpanStatusCode } from '@opentelemetry/api';
|
|
2
2
|
import { resolveContextWindow } from '../../../compaction/context-window.js';
|
|
3
|
-
import { extractFromAssistantMessage } from '../../../compaction/extractor.js';
|
|
3
|
+
import { extractFromAssistantMessage, extractFromUserMessage, } from '../../../compaction/extractor.js';
|
|
4
|
+
import { estimateMessageTokens } from '../../../compaction/token-estimate.js';
|
|
4
5
|
import { AUTO_CONTINUATION_USER_MESSAGE } from '../../../constants/continuation.js';
|
|
5
6
|
import { DEFAULT_STRUCTURED_OUTPUT_RETRIES, STRUCTURED_OUTPUT_REPROMPT, } from '../../../constants/tools/index.js';
|
|
6
7
|
import { renderSkillsSection } from '../../../persona/assembler.js';
|
|
7
8
|
import { resolveProviderCapabilities } from '../../../provider/capabilities.js';
|
|
8
9
|
import { collectChatCompletion } from '../../../provider/collect-chat-completion.js';
|
|
10
|
+
import { renderToolSchema } from '../../../registry/tool/schema.js';
|
|
9
11
|
import { formatCompletionNotification } from '../../../scheduler/completion-inbox.js';
|
|
10
12
|
import { GENAI, NAMZU, agentIterationSpanName, parentContext, } from '../../../telemetry/attributes.js';
|
|
11
13
|
import { getTracer } from '../../../telemetry/runtime-accessors.js';
|
|
@@ -19,10 +21,11 @@ import { stableDigest } from '../../../utils/hash.js';
|
|
|
19
21
|
import { generateMessageId } from '../../../utils/id.js';
|
|
20
22
|
import { applyLifecycleHookResults } from '../plugin-hooks.js';
|
|
21
23
|
import { DEFAULT_MAX_REQUEST_RICH_CONTENT_BYTES, markProviderRejectedImage, projectRequestRichContent, } from '../request-rich-content.js';
|
|
22
|
-
import { formatSteeringNote } from '../steering.js';
|
|
24
|
+
import { formatSteeringNote, isOperatorUserMessage } from '../steering.js';
|
|
25
|
+
import { parseNativeCandidate } from './native-output.js';
|
|
23
26
|
import { runAdvisoryPhase } from './phases/advisory.js';
|
|
24
27
|
import { runIterationCheckpoint } from './phases/checkpoint.js';
|
|
25
|
-
import { measureContext, relieveOverflow, runCompactionCheck } from './phases/compaction.js';
|
|
28
|
+
import { activeContextWindow, measureContext, relieveOverflow, runCompactionCheck, } from './phases/compaction.js';
|
|
26
29
|
import { runPlanGate } from './phases/plan.js';
|
|
27
30
|
import { runToolReview } from './phases/tool-review.js';
|
|
28
31
|
import { refreshWorkingMemory } from './phases/working-memory.js';
|
|
@@ -121,8 +124,29 @@ export class IterationOrchestrator {
|
|
|
121
124
|
* sets it.
|
|
122
125
|
*/
|
|
123
126
|
stopDeferredForOutstandingWork = false;
|
|
127
|
+
/** One current input, independent of the compactable history array. */
|
|
128
|
+
latestUserMessage;
|
|
124
129
|
constructor(ctx) {
|
|
125
|
-
this.ctx =
|
|
130
|
+
this.ctx = {
|
|
131
|
+
...ctx,
|
|
132
|
+
onSteeringDelivered: (text) => {
|
|
133
|
+
this.rememberUserMessage(createRuntimeContextMessage(text, 'steering'));
|
|
134
|
+
},
|
|
135
|
+
};
|
|
136
|
+
ctx.checkpointMgr.setLatestUserMessageSource(() => this.latestUserMessage);
|
|
137
|
+
ctx.checkpointMgr.setStructuredReviewAttemptsSource?.(() => this.structuredReviewAttempts);
|
|
138
|
+
ctx.checkpointMgr.setNativeStructuredAttemptsSource?.(() => this.nativeStructuredAttempts);
|
|
139
|
+
if (ctx.structuredOutput?.mode === 'native') {
|
|
140
|
+
const limit = ctx.structuredOutput.maxRetries;
|
|
141
|
+
if (limit !== undefined && (!Number.isSafeInteger(limit) || limit < 0))
|
|
142
|
+
throw new RangeError('Native structuredOutput.maxRetries must be a nonnegative safe integer');
|
|
143
|
+
}
|
|
144
|
+
if (ctx.structuredOutput?.mode !== undefined &&
|
|
145
|
+
!['tool', 'native'].includes(ctx.structuredOutput.mode))
|
|
146
|
+
throw new RangeError('Unknown structuredOutput.mode');
|
|
147
|
+
const maxReviews = ctx.structuredOutput?.maxReviews;
|
|
148
|
+
if (maxReviews !== undefined && (!Number.isSafeInteger(maxReviews) || maxReviews < 0))
|
|
149
|
+
throw new RangeError('structuredOutput.maxReviews must be a nonnegative safe integer');
|
|
126
150
|
}
|
|
127
151
|
/**
|
|
128
152
|
* Check the exact post-budget request for tool-result shapes the active driver
|
|
@@ -198,6 +222,19 @@ export class IterationOrchestrator {
|
|
|
198
222
|
const { runConfig, runMgr } = this.ctx;
|
|
199
223
|
const { model } = runConfig;
|
|
200
224
|
const tracer = getTracer();
|
|
225
|
+
// Resume hydration happens after construction, before the loop starts.
|
|
226
|
+
this.latestUserMessage = this.ctx.checkpointMgr.restoredLatestUserMessage;
|
|
227
|
+
this.structuredReviewAttempts = this.ctx.checkpointMgr.restoredStructuredReviewAttempts ?? 0;
|
|
228
|
+
this.nativeStructuredAttempts = this.ctx.checkpointMgr.restoredNativeStructuredAttempts ?? 0;
|
|
229
|
+
if (!this.latestUserMessage) {
|
|
230
|
+
for (const message of runMgr.messages)
|
|
231
|
+
this.rememberUserMessage(message, false);
|
|
232
|
+
}
|
|
233
|
+
// The restored field can outlive the historical message it describes.
|
|
234
|
+
// Only known post-checkpoint arrivals may supersede it, never an old
|
|
235
|
+
// retained user turn encountered while scanning restored history.
|
|
236
|
+
for (const message of this.ctx.resumedInput ?? [])
|
|
237
|
+
this.rememberUserMessage(message);
|
|
201
238
|
// One context-overflow relief per *stuck point*, not per run.
|
|
202
239
|
//
|
|
203
240
|
// The latch exists so that a second overflow immediately after a
|
|
@@ -222,6 +259,22 @@ export class IterationOrchestrator {
|
|
|
222
259
|
// no post-loop block reaches.
|
|
223
260
|
try {
|
|
224
261
|
while (true) {
|
|
262
|
+
if (this.ctx.abortController.signal.aborted) {
|
|
263
|
+
runMgr.setStopReason('cancelled');
|
|
264
|
+
runMgr.markCancelled();
|
|
265
|
+
break;
|
|
266
|
+
}
|
|
267
|
+
if (this.ctx.structuredOutput?.mode === 'native' &&
|
|
268
|
+
this.nativeStructuredAttempts > this.structuredOutputRetryLimit()) {
|
|
269
|
+
runMgr.setStopReason('structured_output_failed');
|
|
270
|
+
break;
|
|
271
|
+
}
|
|
272
|
+
if (this.ctx.structuredOutput?.review &&
|
|
273
|
+
this.structuredReviewAttempts >
|
|
274
|
+
(this.ctx.structuredOutput.maxReviews ?? DEFAULT_ANSWER_REVIEW_LIMIT)) {
|
|
275
|
+
runMgr.setStopReason('answer_rejected');
|
|
276
|
+
break;
|
|
277
|
+
}
|
|
225
278
|
// Read AND clear, in that order, in this one place.
|
|
226
279
|
//
|
|
227
280
|
// The flag is set by the previous iteration and read by this
|
|
@@ -265,6 +318,14 @@ export class IterationOrchestrator {
|
|
|
265
318
|
// run and been paid for; this is the seam a host with a live
|
|
266
319
|
// rate limit or a revoked tenant actually needs.
|
|
267
320
|
const veto = await this.beforeStep(runMgr.currentIteration + 1);
|
|
321
|
+
// The hook may settle because its run signal was aborted. Stop
|
|
322
|
+
// before interpreting that settlement as a policy refusal or
|
|
323
|
+
// counting an iteration that will never reach the provider.
|
|
324
|
+
if (this.ctx.abortController.signal.aborted) {
|
|
325
|
+
runMgr.setStopReason('cancelled');
|
|
326
|
+
runMgr.markCancelled();
|
|
327
|
+
break;
|
|
328
|
+
}
|
|
268
329
|
if (veto) {
|
|
269
330
|
// Namespaced. The un-namespaced keys elsewhere in this file are
|
|
270
331
|
// the frozen inventory LOG-22 exists to drain; a new call site
|
|
@@ -354,10 +415,6 @@ export class IterationOrchestrator {
|
|
|
354
415
|
// compaction preserves). No-op when no provider is configured.
|
|
355
416
|
await refreshWorkingMemory(this.ctx);
|
|
356
417
|
await runCompactionCheck(this.ctx);
|
|
357
|
-
// A context edit is a host-visible state transition, not a prelude
|
|
358
|
-
// whose events may wait behind the next network call. In particular,
|
|
359
|
-
// a slow or failing provider must not leave the host displaying the
|
|
360
|
-
// pre-compaction context after Run.messages already shrank.
|
|
361
418
|
yield* this.ctx.drainPending();
|
|
362
419
|
// Cache discipline: keep the tools param byte-stable even on the
|
|
363
420
|
// forced-final iteration and forbid tool use via tool_choice
|
|
@@ -373,9 +430,22 @@ export class IterationOrchestrator {
|
|
|
373
430
|
// Shape this step before calling the model. `stopWhen` decides
|
|
374
431
|
// whether to keep going; this decides HOW. No-op when the host
|
|
375
432
|
// supplied no hook.
|
|
433
|
+
const contextModelBeforePreparation = this.ctx.contextModel ?? model;
|
|
376
434
|
const step = await this.prepareStep(iterationNum);
|
|
435
|
+
stepModel = step.model ?? model;
|
|
436
|
+
await this.selectContextModel(stepModel);
|
|
437
|
+
// Preserve post-compaction preparation/recall semantics. A changed
|
|
438
|
+
// model needs a second check against its own window; never replay
|
|
439
|
+
// host preparation effects merely to rebuild its request guidance.
|
|
440
|
+
if (stepModel !== contextModelBeforePreparation)
|
|
441
|
+
await runCompactionCheck(this.ctx);
|
|
442
|
+
// Publish context edits before entering a possibly slow provider.
|
|
443
|
+
yield* this.ctx.drainPending();
|
|
377
444
|
const stepAllowedTools = step.allowedTools ?? this.ctx.allowedTools;
|
|
378
|
-
const llmTools = this.ctx.tools
|
|
445
|
+
const llmTools = this.ctx.tools
|
|
446
|
+
.toLLMTools(stepAllowedTools)
|
|
447
|
+
.filter((tool) => this.ctx.structuredOutput?.mode !== 'native' ||
|
|
448
|
+
tool.function.name !== STRUCTURED_OUTPUT_TOOL_NAME);
|
|
379
449
|
// The same list the request was built from now also bounds what
|
|
380
450
|
// may run. Narrowing only the request left the restriction
|
|
381
451
|
// presentational — the model was shown fewer tools and could
|
|
@@ -531,6 +601,18 @@ export class IterationOrchestrator {
|
|
|
531
601
|
};
|
|
532
602
|
const { response, messageId } = yield* streamProviderTurn(this.ctx.provider, {
|
|
533
603
|
model: stepModel,
|
|
604
|
+
...(this.ctx.structuredOutput?.mode === 'native'
|
|
605
|
+
? {
|
|
606
|
+
responseFormat: {
|
|
607
|
+
type: 'json_schema',
|
|
608
|
+
json_schema: {
|
|
609
|
+
name: 'structured_output',
|
|
610
|
+
schema: renderToolSchema(this.ctx.structuredOutput.schema),
|
|
611
|
+
strict: true,
|
|
612
|
+
},
|
|
613
|
+
},
|
|
614
|
+
}
|
|
615
|
+
: {}),
|
|
534
616
|
providerRoute: requestedRoute,
|
|
535
617
|
messages,
|
|
536
618
|
tools: llmTools.length > 0 ? llmTools : undefined,
|
|
@@ -646,7 +728,7 @@ export class IterationOrchestrator {
|
|
|
646
728
|
const contextFigures = this.ctx.compactionConfig
|
|
647
729
|
? (() => {
|
|
648
730
|
const measured = measureContext(this.ctx);
|
|
649
|
-
const window =
|
|
731
|
+
const window = activeContextWindow(this.ctx);
|
|
650
732
|
return {
|
|
651
733
|
contextTokens: measured.tokens,
|
|
652
734
|
contextMeasuredBy: measured.source,
|
|
@@ -780,6 +862,60 @@ export class IterationOrchestrator {
|
|
|
780
862
|
usageBefore,
|
|
781
863
|
costBefore,
|
|
782
864
|
});
|
|
865
|
+
if (this.ctx.structuredOutput?.mode === 'native') {
|
|
866
|
+
const candidate = await parseNativeCandidate(this.ctx.structuredOutput.schema, response, this.ctx.abortController.signal);
|
|
867
|
+
let outcome;
|
|
868
|
+
if (candidate.success)
|
|
869
|
+
outcome = await this.reviewStructuredOutput(candidate.value);
|
|
870
|
+
else {
|
|
871
|
+
this.nativeStructuredAttempts++;
|
|
872
|
+
runMgr.pushMessage(createRuntimeContextMessage('Return a complete JSON value matching the supplied response schema. Do not continue a partial JSON fragment.', 'structured-output'));
|
|
873
|
+
const checkpoint = await this.ctx.checkpointMgr.create(runMgr, iterationNum);
|
|
874
|
+
await this.ctx.emitEvent({
|
|
875
|
+
type: 'checkpoint_created',
|
|
876
|
+
runId: runMgr.id,
|
|
877
|
+
checkpointId: checkpoint.id,
|
|
878
|
+
iteration: iterationNum,
|
|
879
|
+
});
|
|
880
|
+
outcome =
|
|
881
|
+
this.nativeStructuredAttempts > this.structuredOutputRetryLimit()
|
|
882
|
+
? 'exhausted'
|
|
883
|
+
: 'retry';
|
|
884
|
+
}
|
|
885
|
+
await this.ctx.emitEvent({
|
|
886
|
+
type: 'iteration_completed',
|
|
887
|
+
runId: runMgr.id,
|
|
888
|
+
iteration: iterationNum,
|
|
889
|
+
hasToolCalls: false,
|
|
890
|
+
});
|
|
891
|
+
yield* this.ctx.drainPending();
|
|
892
|
+
if (this.ctx.abortController.signal.aborted || outcome === 'cancelled') {
|
|
893
|
+
runMgr.setStopReason('cancelled');
|
|
894
|
+
runMgr.markCancelled();
|
|
895
|
+
break;
|
|
896
|
+
}
|
|
897
|
+
if (outcome === 'accepted') {
|
|
898
|
+
if (!forceFinalize) {
|
|
899
|
+
const changed = yield* this.holdForOutstandingWork(iterationNum, false);
|
|
900
|
+
const inbound = this.deliverInbound();
|
|
901
|
+
if (changed || inbound > 0)
|
|
902
|
+
continue;
|
|
903
|
+
}
|
|
904
|
+
if (this.ctx.abortController.signal.aborted) {
|
|
905
|
+
runMgr.setStopReason('cancelled');
|
|
906
|
+
runMgr.markCancelled();
|
|
907
|
+
break;
|
|
908
|
+
}
|
|
909
|
+
this.publishStructuredOutput();
|
|
910
|
+
runMgr.setStopReason('end_turn');
|
|
911
|
+
break;
|
|
912
|
+
}
|
|
913
|
+
if (outcome === 'exhausted') {
|
|
914
|
+
runMgr.setStopReason(candidate.success ? 'answer_rejected' : 'structured_output_failed');
|
|
915
|
+
break;
|
|
916
|
+
}
|
|
917
|
+
continue;
|
|
918
|
+
}
|
|
783
919
|
const hasContent = response.message.content !== null && response.message.content.length > 0;
|
|
784
920
|
// Auto-continuation on `stop_reason: max_tokens`. The
|
|
785
921
|
// model hit its per-call output cap mid-text (NOT
|
|
@@ -862,6 +998,11 @@ export class IterationOrchestrator {
|
|
|
862
998
|
// a loud stop rather than a loop.
|
|
863
999
|
if (!forceFinalize && this.ctx.reviewAnswer) {
|
|
864
1000
|
const review = await this.reviewAnswer(response.message.content ?? '');
|
|
1001
|
+
if (this.ctx.abortController.signal.aborted) {
|
|
1002
|
+
runMgr.setStopReason('cancelled');
|
|
1003
|
+
runMgr.markCancelled();
|
|
1004
|
+
break;
|
|
1005
|
+
}
|
|
865
1006
|
if (review && !review.accept) {
|
|
866
1007
|
const attempt = ++this.answerReviewAttempts;
|
|
867
1008
|
const limit = this.ctx.maxAnswerReviews ?? DEFAULT_ANSWER_REVIEW_LIMIT;
|
|
@@ -988,12 +1129,34 @@ export class IterationOrchestrator {
|
|
|
988
1129
|
// run ends here rather than paying for another turn whose only
|
|
989
1130
|
// job would be to restate it — unless it shared its turn with
|
|
990
1131
|
// other calls, which relays instead. See the method.
|
|
991
|
-
|
|
1132
|
+
const structuredOutcome = await this.captureStructuredOutput(reviewOutcome.results, response);
|
|
1133
|
+
if (structuredOutcome === 'retry' ||
|
|
1134
|
+
structuredOutcome === 'exhausted' ||
|
|
1135
|
+
structuredOutcome === 'cancelled') {
|
|
1136
|
+
await this.ctx.emitEvent({
|
|
1137
|
+
type: 'iteration_completed',
|
|
1138
|
+
runId: runMgr.id,
|
|
1139
|
+
iteration: iterationNum,
|
|
1140
|
+
hasToolCalls: true,
|
|
1141
|
+
});
|
|
1142
|
+
yield* this.ctx.drainPending();
|
|
1143
|
+
if (this.ctx.abortController.signal.aborted) {
|
|
1144
|
+
runMgr.setStopReason('cancelled');
|
|
1145
|
+
runMgr.markCancelled();
|
|
1146
|
+
break;
|
|
1147
|
+
}
|
|
1148
|
+
if (structuredOutcome === 'retry')
|
|
1149
|
+
continue;
|
|
1150
|
+
runMgr.setStopReason(structuredOutcome === 'cancelled' ? 'cancelled' : 'answer_rejected');
|
|
1151
|
+
if (structuredOutcome === 'cancelled')
|
|
1152
|
+
runMgr.markCancelled();
|
|
1153
|
+
break;
|
|
1154
|
+
}
|
|
1155
|
+
if (structuredOutcome === 'accepted') {
|
|
992
1156
|
this.ctx.log.info('Structured output produced — ending run', {
|
|
993
1157
|
[NAMZU.RUN_ID]: runMgr.id,
|
|
994
1158
|
[NAMZU.ITERATION]: iterationNum,
|
|
995
1159
|
});
|
|
996
|
-
runMgr.setStopReason('end_turn');
|
|
997
1160
|
await this.ctx.emitEvent({
|
|
998
1161
|
type: 'iteration_completed',
|
|
999
1162
|
runId: runMgr.id,
|
|
@@ -1001,6 +1164,13 @@ export class IterationOrchestrator {
|
|
|
1001
1164
|
hasToolCalls: true,
|
|
1002
1165
|
});
|
|
1003
1166
|
yield* this.ctx.drainPending();
|
|
1167
|
+
if (this.ctx.abortController.signal.aborted) {
|
|
1168
|
+
runMgr.setStopReason('cancelled');
|
|
1169
|
+
runMgr.markCancelled();
|
|
1170
|
+
break;
|
|
1171
|
+
}
|
|
1172
|
+
this.publishStructuredOutput();
|
|
1173
|
+
runMgr.setStopReason('end_turn');
|
|
1004
1174
|
break;
|
|
1005
1175
|
}
|
|
1006
1176
|
// A tool the author declared terminal settles the run with its
|
|
@@ -1260,9 +1430,9 @@ export class IterationOrchestrator {
|
|
|
1260
1430
|
/**
|
|
1261
1431
|
* Hold the run open for a worker that has not finished, and deliver it.
|
|
1262
1432
|
*
|
|
1263
|
-
* Returns whether a completion
|
|
1264
|
-
* caller continues
|
|
1265
|
-
*
|
|
1433
|
+
* Returns whether a completion or operator message entered the transcript —
|
|
1434
|
+
* the caller continues on `true`, so the model gets a turn to respond.
|
|
1435
|
+
* That turn is the entire justification for waiting, which
|
|
1266
1436
|
* is why only the exits that can still take one call this.
|
|
1267
1437
|
*
|
|
1268
1438
|
* Bounded by `settleGraceMs` and by `maxIterations`, so a worker that never
|
|
@@ -1280,11 +1450,36 @@ export class IterationOrchestrator {
|
|
|
1280
1450
|
[NAMZU.ITERATION]: iterationNum,
|
|
1281
1451
|
'namzu.runtime.grace_ms': graceMs,
|
|
1282
1452
|
});
|
|
1283
|
-
|
|
1453
|
+
// User input releases this wait without cancelling any child. Both waits
|
|
1454
|
+
// share a disposable signal so the losing arrival listener cannot leak.
|
|
1455
|
+
const waiting = new AbortController();
|
|
1456
|
+
const runSignal = this.ctx.abortController.signal;
|
|
1457
|
+
const cancelWait = () => waiting.abort(runSignal.reason);
|
|
1458
|
+
runSignal.addEventListener('abort', cancelWait, { once: true });
|
|
1459
|
+
if (runSignal.aborted)
|
|
1460
|
+
cancelWait();
|
|
1461
|
+
try {
|
|
1462
|
+
await Promise.race([
|
|
1463
|
+
this.ctx.completionInbox.waitForArrival(graceMs, waiting.signal),
|
|
1464
|
+
...(this.ctx.waitForInbound ? [this.ctx.waitForInbound(waiting.signal)] : []),
|
|
1465
|
+
]);
|
|
1466
|
+
}
|
|
1467
|
+
catch (error) {
|
|
1468
|
+
if (!runSignal.aborted)
|
|
1469
|
+
throw error;
|
|
1470
|
+
}
|
|
1471
|
+
finally {
|
|
1472
|
+
waiting.abort();
|
|
1473
|
+
runSignal.removeEventListener('abort', cancelWait);
|
|
1474
|
+
}
|
|
1475
|
+
runSignal.throwIfAborted();
|
|
1284
1476
|
const arrived = this.ctx.completionInbox.drain();
|
|
1285
|
-
if (arrived.length
|
|
1477
|
+
if (arrived.length > 0) {
|
|
1478
|
+
this.ctx.runMgr.pushMessage(createRuntimeContextMessage(formatCompletionNotification(arrived), 'task-completion'));
|
|
1479
|
+
}
|
|
1480
|
+
const inbound = this.deliverInbound();
|
|
1481
|
+
if (arrived.length === 0 && inbound === 0)
|
|
1286
1482
|
return false;
|
|
1287
|
-
this.ctx.runMgr.pushMessage(createRuntimeContextMessage(formatCompletionNotification(arrived), 'task-completion'));
|
|
1288
1483
|
await this.ctx.emitEvent({
|
|
1289
1484
|
type: 'iteration_completed',
|
|
1290
1485
|
runId: this.ctx.runMgr.id,
|
|
@@ -1381,18 +1576,39 @@ export class IterationOrchestrator {
|
|
|
1381
1576
|
* message becomes the reason, so an operator is not left with a run
|
|
1382
1577
|
* that stopped and no account of it.
|
|
1383
1578
|
*/
|
|
1579
|
+
stepContext(stepNumber, prepared) {
|
|
1580
|
+
const model = prepared.model ?? this.ctx.runConfig.model;
|
|
1581
|
+
const window = resolveContextWindow(this.ctx.compactionConfig?.contextWindowTokens, model, model === this.ctx.runConfig.model
|
|
1582
|
+
? this.ctx.providerContextWindow
|
|
1583
|
+
: model === this.ctx.contextModel
|
|
1584
|
+
? this.ctx.activeProviderContextWindow
|
|
1585
|
+
: undefined);
|
|
1586
|
+
const skills = prepared.skills ? renderSkillsSection([...prepared.skills]) : null;
|
|
1587
|
+
const preamble = [prepared.system, skills].filter(Boolean).join('\n\n');
|
|
1588
|
+
const preparedTokens = preamble ? estimateMessageTokens(createSystemMessage(preamble)) : 0;
|
|
1589
|
+
const responseReserve = Math.min(prepared.maxResponseTokens ??
|
|
1590
|
+
this.ctx.runConfig.maxResponseTokens ??
|
|
1591
|
+
Math.floor(window.tokens / 4), Math.floor(window.tokens / 4));
|
|
1592
|
+
return {
|
|
1593
|
+
runId: this.ctx.runMgr.id,
|
|
1594
|
+
stepNumber,
|
|
1595
|
+
messages: this.ctx.runMgr.messages,
|
|
1596
|
+
...(this.latestUserMessage ? { latestUserMessage: this.latestUserMessage } : {}),
|
|
1597
|
+
signal: this.ctx.abortController.signal,
|
|
1598
|
+
contextBudget: {
|
|
1599
|
+
windowTokens: window.tokens,
|
|
1600
|
+
remainingTokens: Math.max(0, Math.floor(window.tokens - measureContext(this.ctx).tokens - preparedTokens - responseReserve)),
|
|
1601
|
+
},
|
|
1602
|
+
steps: this.steps,
|
|
1603
|
+
prepared,
|
|
1604
|
+
};
|
|
1605
|
+
}
|
|
1384
1606
|
async beforeStep(stepNumber) {
|
|
1385
1607
|
const configured = this.ctx.beforeStep;
|
|
1386
1608
|
if (!configured)
|
|
1387
1609
|
return undefined;
|
|
1388
1610
|
try {
|
|
1389
|
-
return (
|
|
1390
|
-
runId: this.ctx.runMgr.id,
|
|
1391
|
-
stepNumber,
|
|
1392
|
-
messages: this.ctx.runMgr.messages,
|
|
1393
|
-
steps: this.steps,
|
|
1394
|
-
prepared: {},
|
|
1395
|
-
})) ?? undefined);
|
|
1611
|
+
return (await configured(this.stepContext(stepNumber, {}))) ?? undefined;
|
|
1396
1612
|
}
|
|
1397
1613
|
catch (err) {
|
|
1398
1614
|
return { reason: `beforeStep threw: ${toErrorMessage(err)}` };
|
|
@@ -1410,15 +1626,10 @@ export class IterationOrchestrator {
|
|
|
1410
1626
|
let result = {};
|
|
1411
1627
|
for (const stage of stages) {
|
|
1412
1628
|
try {
|
|
1413
|
-
const decided = await stage(
|
|
1414
|
-
runId: this.ctx.runMgr.id,
|
|
1415
|
-
stepNumber,
|
|
1416
|
-
messages: this.ctx.runMgr.messages,
|
|
1417
|
-
steps: this.steps,
|
|
1418
|
-
prepared: result,
|
|
1419
|
-
});
|
|
1629
|
+
const decided = await stage(this.stepContext(stepNumber, result));
|
|
1420
1630
|
if (decided)
|
|
1421
1631
|
result = { ...result, ...decided };
|
|
1632
|
+
await this.selectContextModel(result.model ?? this.ctx.runConfig.model);
|
|
1422
1633
|
}
|
|
1423
1634
|
catch (err) {
|
|
1424
1635
|
// Skipped, and the rest still run: one broken concern must
|
|
@@ -1473,6 +1684,17 @@ export class IterationOrchestrator {
|
|
|
1473
1684
|
}
|
|
1474
1685
|
return prepared;
|
|
1475
1686
|
}
|
|
1687
|
+
async selectContextModel(model) {
|
|
1688
|
+
if (model !== (this.ctx.contextModel ?? this.ctx.runConfig.model)) {
|
|
1689
|
+
// A measurement from another tokenizer cannot price the new request.
|
|
1690
|
+
this.ctx.runMgr.clearLastPromptTokens();
|
|
1691
|
+
}
|
|
1692
|
+
this.ctx.contextModel = model;
|
|
1693
|
+
this.ctx.activeProviderContextWindow =
|
|
1694
|
+
model && model !== this.ctx.runConfig.model && !this.ctx.compactionConfig?.contextWindowTokens
|
|
1695
|
+
? await this.ctx.resolveModelContextWindow?.(model)
|
|
1696
|
+
: undefined;
|
|
1697
|
+
}
|
|
1476
1698
|
/** Steps completed so far, exposed on the returned `Run`. */
|
|
1477
1699
|
steps = [];
|
|
1478
1700
|
getSteps() {
|
|
@@ -1499,16 +1721,32 @@ export class IterationOrchestrator {
|
|
|
1499
1721
|
* empty drain must change nothing at all: a `continue` on nothing queued
|
|
1500
1722
|
* spends an iteration and a model call to say the same thing again.
|
|
1501
1723
|
*/
|
|
1724
|
+
rememberUserMessage(message, arriving = true) {
|
|
1725
|
+
if (!isOperatorUserMessage(message))
|
|
1726
|
+
return;
|
|
1727
|
+
this.latestUserMessage = message;
|
|
1728
|
+
// The hook field alone does not reach the model. Preserve arrivals in
|
|
1729
|
+
// the compaction state too, before their original message or attached
|
|
1730
|
+
// tool result can be shed. Initial history was already extracted at seed.
|
|
1731
|
+
const manager = this.ctx.workingStateManager;
|
|
1732
|
+
if (arriving && manager) {
|
|
1733
|
+
extractFromUserMessage(manager, message.content, !manager.getState().task);
|
|
1734
|
+
}
|
|
1735
|
+
}
|
|
1502
1736
|
deliverInbound() {
|
|
1503
1737
|
const queued = this.ctx.inboundMessages?.() ?? [];
|
|
1504
|
-
for (const message of queued)
|
|
1738
|
+
for (const message of queued) {
|
|
1505
1739
|
this.ctx.runMgr.pushMessage(message);
|
|
1740
|
+
this.rememberUserMessage(message);
|
|
1741
|
+
}
|
|
1506
1742
|
// The steering channel's remainder. `attachSteering` already took
|
|
1507
1743
|
// what it could carry on a tool result; anything still pending is
|
|
1508
1744
|
// guidance from a turn that had no result to attach it to.
|
|
1509
1745
|
const stranded = this.ctx.steering?.drain();
|
|
1510
1746
|
if (stranded) {
|
|
1511
|
-
|
|
1747
|
+
const message = createRuntimeContextMessage(formatSteeringNote(stranded), 'steering');
|
|
1748
|
+
this.ctx.runMgr.pushMessage(message);
|
|
1749
|
+
this.rememberUserMessage(createRuntimeContextMessage(stranded, 'steering'));
|
|
1512
1750
|
}
|
|
1513
1751
|
return queued.length + (stranded ? 1 : 0);
|
|
1514
1752
|
}
|
|
@@ -1586,7 +1824,10 @@ export class IterationOrchestrator {
|
|
|
1586
1824
|
}
|
|
1587
1825
|
/** Turns spent asking the model again for a valid structured output. */
|
|
1588
1826
|
structuredOutputAttempts = 0;
|
|
1827
|
+
nativeStructuredAttempts = 0;
|
|
1589
1828
|
structuredOutputDone = false;
|
|
1829
|
+
pendingStructuredOutput;
|
|
1830
|
+
structuredReviewAttempts = 0;
|
|
1590
1831
|
structuredOutputRetryLimit() {
|
|
1591
1832
|
return this.ctx.structuredOutput?.maxRetries ?? DEFAULT_STRUCTURED_OUTPUT_RETRIES;
|
|
1592
1833
|
}
|
|
@@ -1607,6 +1848,8 @@ export class IterationOrchestrator {
|
|
|
1607
1848
|
* avoid.
|
|
1608
1849
|
*/
|
|
1609
1850
|
terminalToolOutput(results, response) {
|
|
1851
|
+
if (this.ctx.structuredOutput?.mode === 'native')
|
|
1852
|
+
return undefined;
|
|
1610
1853
|
const terminal = results.filter((r) => this.ctx.tools.get(r.toolName)?.terminal === true);
|
|
1611
1854
|
if (terminal.length === 0)
|
|
1612
1855
|
return undefined;
|
|
@@ -1673,30 +1916,98 @@ export class IterationOrchestrator {
|
|
|
1673
1916
|
* doing work, and it is the bound the neighbour relies on for the
|
|
1674
1917
|
* identical pathology.
|
|
1675
1918
|
*/
|
|
1676
|
-
captureStructuredOutput(results, response) {
|
|
1677
|
-
if (!this.needsStructuredOutput())
|
|
1678
|
-
return
|
|
1919
|
+
async captureStructuredOutput(results, response) {
|
|
1920
|
+
if (!this.needsStructuredOutput() || this.ctx.structuredOutput?.mode === 'native')
|
|
1921
|
+
return 'absent';
|
|
1679
1922
|
const hit = results.find((r) => r.toolName === STRUCTURED_OUTPUT_TOOL_NAME && !r.isError);
|
|
1680
1923
|
if (!hit)
|
|
1681
|
-
return
|
|
1924
|
+
return 'absent';
|
|
1682
1925
|
const callCount = response.message.toolCalls?.length ?? 0;
|
|
1683
1926
|
if (callCount > 1) {
|
|
1684
1927
|
this.ctx.log.info('Structured output shared its turn — relaying instead of settling', {
|
|
1685
1928
|
[NAMZU.RUN_ID]: this.ctx.runMgr.id,
|
|
1686
1929
|
'namzu.runtime.calls_in_turn': callCount,
|
|
1687
1930
|
});
|
|
1688
|
-
return
|
|
1931
|
+
return 'absent';
|
|
1689
1932
|
}
|
|
1933
|
+
let parsed;
|
|
1690
1934
|
try {
|
|
1691
|
-
|
|
1935
|
+
parsed = JSON.parse(hit.output);
|
|
1692
1936
|
}
|
|
1693
1937
|
catch {
|
|
1694
1938
|
// The tool serializes its own validated input, so this is
|
|
1695
1939
|
// unreachable in practice; keep the raw text rather than losing it.
|
|
1696
|
-
this.ctx.
|
|
1940
|
+
if (this.ctx.structuredOutput?.review)
|
|
1941
|
+
throw new Error('Structured review requires an intact JSON tool result; check tool-output limits and result transformations');
|
|
1942
|
+
parsed = hit.output;
|
|
1697
1943
|
}
|
|
1944
|
+
return this.reviewStructuredOutput(parsed);
|
|
1945
|
+
}
|
|
1946
|
+
publishStructuredOutput() {
|
|
1947
|
+
this.ctx.runMgr.setStructuredOutput(this.pendingStructuredOutput);
|
|
1698
1948
|
this.structuredOutputDone = true;
|
|
1699
|
-
|
|
1949
|
+
}
|
|
1950
|
+
async reviewStructuredOutput(parsed) {
|
|
1951
|
+
if (this.ctx.abortController.signal.aborted)
|
|
1952
|
+
return 'cancelled';
|
|
1953
|
+
const reviewer = this.ctx.structuredOutput?.review;
|
|
1954
|
+
if (reviewer) {
|
|
1955
|
+
const signal = this.ctx.abortController.signal;
|
|
1956
|
+
if (signal.aborted)
|
|
1957
|
+
return 'cancelled';
|
|
1958
|
+
let onAbort = () => { };
|
|
1959
|
+
const aborted = new Promise((_resolve, reject) => {
|
|
1960
|
+
onAbort = () => reject(signal.reason ?? new Error('Structured review cancelled'));
|
|
1961
|
+
signal.addEventListener('abort', onAbort, { once: true });
|
|
1962
|
+
});
|
|
1963
|
+
let verdict;
|
|
1964
|
+
try {
|
|
1965
|
+
verdict = await Promise.race([
|
|
1966
|
+
Promise.resolve().then(() => reviewer(structuredClone(parsed), {
|
|
1967
|
+
runId: this.ctx.runMgr.id,
|
|
1968
|
+
iteration: this.ctx.runMgr.currentIteration,
|
|
1969
|
+
signal,
|
|
1970
|
+
messages: this.ctx.runMgr.messages,
|
|
1971
|
+
})),
|
|
1972
|
+
aborted,
|
|
1973
|
+
]);
|
|
1974
|
+
}
|
|
1975
|
+
catch (error) {
|
|
1976
|
+
if (signal.aborted)
|
|
1977
|
+
return 'cancelled';
|
|
1978
|
+
throw error;
|
|
1979
|
+
}
|
|
1980
|
+
finally {
|
|
1981
|
+
signal.removeEventListener('abort', onAbort);
|
|
1982
|
+
}
|
|
1983
|
+
if (signal.aborted)
|
|
1984
|
+
return 'cancelled';
|
|
1985
|
+
if (!verdict || typeof verdict.accept !== 'boolean')
|
|
1986
|
+
throw new Error('Structured reviewer returned an invalid verdict');
|
|
1987
|
+
if (!verdict.accept) {
|
|
1988
|
+
if (typeof verdict.feedback !== 'string' || verdict.feedback.trim().length === 0)
|
|
1989
|
+
throw new Error('Structured reviewer rejection requires feedback');
|
|
1990
|
+
this.structuredReviewAttempts++;
|
|
1991
|
+
this.ctx.runMgr.pushMessage(createRuntimeContextMessage(verdict.feedback, 'answer-review'));
|
|
1992
|
+
// Persist both the feedback and its consumed allowance before the
|
|
1993
|
+
// next request. This checkpoint is not an approval/park boundary.
|
|
1994
|
+
const checkpoint = await this.ctx.checkpointMgr.create(this.ctx.runMgr, this.ctx.runMgr.currentIteration);
|
|
1995
|
+
await this.ctx.emitEvent({
|
|
1996
|
+
type: 'checkpoint_created',
|
|
1997
|
+
runId: this.ctx.runMgr.id,
|
|
1998
|
+
checkpointId: checkpoint.id,
|
|
1999
|
+
iteration: this.ctx.runMgr.currentIteration,
|
|
2000
|
+
});
|
|
2001
|
+
if (signal.aborted)
|
|
2002
|
+
return 'cancelled';
|
|
2003
|
+
return this.structuredReviewAttempts >
|
|
2004
|
+
(this.ctx.structuredOutput?.maxReviews ?? DEFAULT_ANSWER_REVIEW_LIMIT)
|
|
2005
|
+
? 'exhausted'
|
|
2006
|
+
: 'retry';
|
|
2007
|
+
}
|
|
2008
|
+
}
|
|
2009
|
+
this.pendingStructuredOutput = parsed;
|
|
2010
|
+
return 'accepted';
|
|
1700
2011
|
}
|
|
1701
2012
|
/**
|
|
1702
2013
|
* Ask the host whether this answer is good enough.
|
|
@@ -1717,6 +2028,7 @@ export class IterationOrchestrator {
|
|
|
1717
2028
|
return await this.ctx.reviewAnswer(answer, {
|
|
1718
2029
|
runId: this.ctx.runMgr.id,
|
|
1719
2030
|
iteration: this.ctx.runMgr.currentIteration,
|
|
2031
|
+
signal: this.ctx.abortController.signal,
|
|
1720
2032
|
messages: this.ctx.runMgr.messages,
|
|
1721
2033
|
});
|
|
1722
2034
|
}
|
|
@@ -1776,6 +2088,8 @@ export class IterationOrchestrator {
|
|
|
1776
2088
|
});
|
|
1777
2089
|
}
|
|
1778
2090
|
async requestFinalResponse(model, reason) {
|
|
2091
|
+
if (this.ctx.structuredOutput?.mode === 'native')
|
|
2092
|
+
return 'structured_output_failed';
|
|
1779
2093
|
const lastAssistant = [...this.ctx.runMgr.messages]
|
|
1780
2094
|
.reverse()
|
|
1781
2095
|
.find((m) => m.role === 'assistant');
|