@namzu/sdk 42.0.2 → 44.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 +540 -0
- package/README.md +41 -34
- package/dist/advisory/budget.js +3 -3
- package/dist/advisory/budget.js.map +1 -1
- package/dist/advisory/context.d.ts +5 -5
- package/dist/advisory/context.d.ts.map +1 -1
- package/dist/advisory/context.js +6 -6
- package/dist/advisory/context.js.map +1 -1
- package/dist/advisory/evaluator.js +2 -2
- package/dist/advisory/evaluator.js.map +1 -1
- package/dist/advisory/parse.d.ts +1 -1
- package/dist/advisory/parse.js +1 -1
- package/dist/agents/AbstractAgent.d.ts +47 -40
- package/dist/agents/AbstractAgent.d.ts.map +1 -1
- package/dist/agents/AbstractAgent.js +60 -46
- package/dist/agents/AbstractAgent.js.map +1 -1
- package/dist/agents/PipelineAgent.d.ts +7 -7
- package/dist/agents/PipelineAgent.d.ts.map +1 -1
- package/dist/agents/PipelineAgent.js +75 -23
- package/dist/agents/PipelineAgent.js.map +1 -1
- package/dist/agents/ReactiveAgent.d.ts +7 -7
- package/dist/agents/ReactiveAgent.d.ts.map +1 -1
- package/dist/agents/ReactiveAgent.js +32 -25
- package/dist/agents/ReactiveAgent.js.map +1 -1
- package/dist/agents/RouterAgent.d.ts +7 -7
- package/dist/agents/RouterAgent.d.ts.map +1 -1
- package/dist/agents/RouterAgent.js +29 -32
- package/dist/agents/RouterAgent.js.map +1 -1
- package/dist/agents/SupervisorAgent.d.ts +13 -10
- package/dist/agents/SupervisorAgent.d.ts.map +1 -1
- package/dist/agents/SupervisorAgent.js +50 -36
- package/dist/agents/SupervisorAgent.js.map +1 -1
- package/dist/agents/budget.d.ts +17 -4
- package/dist/agents/budget.d.ts.map +1 -1
- package/dist/agents/budget.js +55 -14
- package/dist/agents/budget.js.map +1 -1
- package/dist/agents/defineAgent.d.ts +2 -2
- package/dist/agents/defineAgent.d.ts.map +1 -1
- package/dist/agents/defineAgent.js.map +1 -1
- package/dist/agents/handle.d.ts +12 -14
- package/dist/agents/handle.d.ts.map +1 -1
- package/dist/agents/handle.js +6 -6
- package/dist/agents/handle.js.map +1 -1
- package/dist/agents/lock.js +4 -4
- package/dist/agents/lock.js.map +1 -1
- package/dist/agents/runAgent.d.ts +42 -29
- package/dist/agents/runAgent.d.ts.map +1 -1
- package/dist/agents/runAgent.js +53 -14
- package/dist/agents/runAgent.js.map +1 -1
- package/dist/agents/storage.d.ts +21 -0
- package/dist/agents/storage.d.ts.map +1 -0
- package/dist/agents/storage.js +33 -0
- package/dist/agents/storage.js.map +1 -0
- package/dist/authorization/command-line.d.ts +1 -1
- package/dist/authorization/command-line.js +1 -1
- package/dist/authorization/gate.js +1 -1
- package/dist/authorization/gate.js.map +1 -1
- package/dist/authorization/permission-presets.d.ts +4 -4
- package/dist/authorization/permission-presets.d.ts.map +1 -1
- package/dist/authorization/permission-presets.js +2 -2
- package/dist/bridge/a2a/client.d.ts +1 -1
- package/dist/bridge/a2a/client.js +2 -2
- package/dist/bridge/a2a/client.js.map +1 -1
- package/dist/bridge/a2a/context.d.ts +26 -0
- package/dist/bridge/a2a/context.d.ts.map +1 -0
- package/dist/bridge/a2a/context.js +20 -0
- package/dist/bridge/a2a/context.js.map +1 -0
- package/dist/bridge/a2a/index.d.ts +4 -2
- package/dist/bridge/a2a/index.d.ts.map +1 -1
- package/dist/bridge/a2a/index.js +6 -2
- package/dist/bridge/a2a/index.js.map +1 -1
- package/dist/bridge/a2a/mapper.d.ts +12 -4
- package/dist/bridge/a2a/mapper.d.ts.map +1 -1
- package/dist/bridge/a2a/mapper.js +38 -31
- package/dist/bridge/a2a/mapper.js.map +1 -1
- package/dist/bridge/a2a/task.d.ts +39 -7
- package/dist/bridge/a2a/task.d.ts.map +1 -1
- package/dist/bridge/a2a/task.js +52 -31
- package/dist/bridge/a2a/task.js.map +1 -1
- package/dist/bridge/acp/permission.d.ts +2 -2
- package/dist/bridge/acp/server.d.ts +22 -8
- package/dist/bridge/acp/server.d.ts.map +1 -1
- package/dist/bridge/acp/server.js +18 -5
- package/dist/bridge/acp/server.js.map +1 -1
- package/dist/bridge/acp/update.d.ts +4 -4
- package/dist/bridge/acp/update.d.ts.map +1 -1
- package/dist/bridge/acp/update.js +6 -6
- package/dist/bridge/acp/update.js.map +1 -1
- package/dist/bridge/external-session.d.ts +43 -0
- package/dist/bridge/external-session.d.ts.map +1 -0
- package/dist/bridge/external-session.js +28 -0
- package/dist/bridge/external-session.js.map +1 -0
- package/dist/bridge/sse/index.d.ts +1 -1
- package/dist/bridge/sse/index.d.ts.map +1 -1
- package/dist/bridge/sse/index.js +1 -1
- package/dist/bridge/sse/index.js.map +1 -1
- package/dist/bridge/sse/mapper.d.ts +21 -13
- package/dist/bridge/sse/mapper.d.ts.map +1 -1
- package/dist/bridge/sse/mapper.js +99 -129
- package/dist/bridge/sse/mapper.js.map +1 -1
- package/dist/bus/breaker.d.ts +6 -6
- package/dist/bus/breaker.d.ts.map +1 -1
- package/dist/bus/breaker.js +28 -27
- package/dist/bus/breaker.js.map +1 -1
- package/dist/bus/index.d.ts +2 -2
- package/dist/bus/index.d.ts.map +1 -1
- package/dist/bus/index.js +6 -6
- package/dist/bus/index.js.map +1 -1
- package/dist/bus/lock.d.ts +5 -5
- package/dist/bus/lock.d.ts.map +1 -1
- package/dist/bus/lock.js.map +1 -1
- package/dist/bus/ownership.d.ts +8 -8
- package/dist/bus/ownership.d.ts.map +1 -1
- package/dist/bus/ownership.js.map +1 -1
- package/dist/compaction/consolidation.d.ts +23 -11
- package/dist/compaction/consolidation.d.ts.map +1 -1
- package/dist/compaction/consolidation.js +43 -13
- package/dist/compaction/consolidation.js.map +1 -1
- package/dist/compaction/context-window.d.ts +4 -4
- package/dist/compaction/context-window.js +4 -4
- package/dist/compaction/index.d.ts +1 -1
- package/dist/compaction/index.d.ts.map +1 -1
- package/dist/compaction/index.js +2 -2
- package/dist/compaction/index.js.map +1 -1
- package/dist/compaction/manager.d.ts +4 -4
- package/dist/compaction/manager.js +4 -4
- package/dist/compaction/manual.d.ts +2 -2
- package/dist/compaction/manual.js +3 -3
- package/dist/compaction/manual.js.map +1 -1
- package/dist/compaction/plan.d.ts +5 -5
- package/dist/compaction/plan.js +4 -4
- package/dist/compaction/plan.js.map +1 -1
- package/dist/compaction/reducer.d.ts +8 -8
- package/dist/compaction/reducer.d.ts.map +1 -1
- package/dist/compaction/retention.js +2 -2
- package/dist/compaction/salience/bm25.d.ts +2 -2
- package/dist/compaction/salience/bm25.js +2 -2
- package/dist/compaction/salience/goal.d.ts +3 -3
- package/dist/compaction/salience/goal.js +3 -3
- package/dist/compaction/salience/minhash.d.ts +1 -1
- package/dist/compaction/salience/minhash.js +1 -1
- package/dist/compaction/salience/score.d.ts +2 -2
- package/dist/compaction/salience/score.js +3 -3
- package/dist/compaction/salience/score.js.map +1 -1
- package/dist/compaction/salience/tokenize.d.ts +1 -1
- package/dist/compaction/salience/tokenize.js +1 -1
- package/dist/compaction/verifier.d.ts +6 -6
- package/dist/compaction/verifier.js +5 -5
- package/dist/compaction/verifier.js.map +1 -1
- package/dist/compaction/wire.d.ts +1 -1
- package/dist/config/registry.d.ts +4 -4
- package/dist/config/registry.js +2 -2
- package/dist/config/runtime.d.ts +24 -24
- package/dist/config/runtime.js +3 -3
- package/dist/connector/http-operation.d.ts +1 -1
- package/dist/connector/http-operation.js +1 -1
- package/dist/connector/mcp/adapter.js +1 -1
- package/dist/connector/mcp/client.d.ts +1 -1
- package/dist/connector/mcp/client.js +1 -1
- package/dist/connector/mcp/discovery.d.ts +1 -1
- package/dist/connector/mcp/discovery.js +1 -1
- package/dist/connector/mcp/discovery.js.map +1 -1
- package/dist/connector/mcp/policy.d.ts +1 -1
- package/dist/connector/mcp/prompt-adapter.d.ts +1 -1
- package/dist/connector/mcp/prompt-adapter.js +3 -3
- package/dist/connector/mcp/prompt-adapter.js.map +1 -1
- package/dist/constants/a2a/index.d.ts +8 -2
- package/dist/constants/a2a/index.d.ts.map +1 -1
- package/dist/constants/a2a/index.js +9 -2
- package/dist/constants/a2a/index.js.map +1 -1
- package/dist/constants/continuation.d.ts +1 -1
- package/dist/constants/continuation.js +1 -1
- package/dist/constants/index.d.ts +0 -1
- package/dist/constants/index.d.ts.map +1 -1
- package/dist/constants/index.js +0 -1
- package/dist/constants/index.js.map +1 -1
- package/dist/constants/limits.d.ts +2 -2
- package/dist/constants/limits.js +2 -2
- package/dist/constants/telemetry/index.d.ts +9 -3
- package/dist/constants/telemetry/index.d.ts.map +1 -1
- package/dist/constants/telemetry/index.js +14 -12
- package/dist/constants/telemetry/index.js.map +1 -1
- package/dist/constants/tools/index.d.ts +2 -2
- package/dist/constants/tools/index.js +2 -2
- package/dist/contracts/a2a.d.ts +2 -2
- package/dist/contracts/api.d.ts +11 -126
- package/dist/contracts/api.d.ts.map +1 -1
- package/dist/contracts/index.d.ts +3 -2
- package/dist/contracts/index.d.ts.map +1 -1
- package/dist/contracts/index.js +7 -2
- package/dist/contracts/index.js.map +1 -1
- package/dist/contracts/schemas.d.ts +6 -165
- package/dist/contracts/schemas.d.ts.map +1 -1
- package/dist/contracts/schemas.js +6 -36
- package/dist/contracts/schemas.js.map +1 -1
- package/dist/contracts/session/api.d.ts +94 -0
- package/dist/contracts/session/api.d.ts.map +1 -0
- package/dist/contracts/session/api.js +10 -0
- package/dist/contracts/session/api.js.map +1 -0
- package/dist/contracts/session/index.d.ts +7 -0
- package/dist/contracts/session/index.d.ts.map +1 -0
- package/dist/contracts/session/index.js +7 -0
- package/dist/contracts/session/index.js.map +1 -0
- package/dist/contracts/session/schemas.d.ts +173 -0
- package/dist/contracts/session/schemas.d.ts.map +1 -0
- package/dist/contracts/session/schemas.js +52 -0
- package/dist/contracts/session/schemas.js.map +1 -0
- package/dist/contracts/session/turn-status.d.ts +45 -0
- package/dist/contracts/session/turn-status.d.ts.map +1 -0
- package/dist/contracts/session/turn-status.js +46 -0
- package/dist/contracts/session/turn-status.js.map +1 -0
- package/dist/contracts/session/turn.d.ts +64 -0
- package/dist/contracts/session/turn.d.ts.map +1 -0
- package/dist/contracts/session/turn.js +2 -0
- package/dist/contracts/session/turn.js.map +1 -0
- package/dist/directory/derive-supervisor.d.ts +1 -1
- package/dist/directory/derive-supervisor.js +2 -2
- package/dist/directory/derive-supervisor.js.map +1 -1
- package/dist/directory/derive.d.ts +2 -2
- package/dist/directory/derive.d.ts.map +1 -1
- package/dist/directory/derive.js +2 -2
- package/dist/directory/derive.js.map +1 -1
- package/dist/directory/index.d.ts +2 -2
- package/dist/directory/index.d.ts.map +1 -1
- package/dist/directory/index.js +1 -1
- package/dist/directory/index.js.map +1 -1
- package/dist/directory/load.js +2 -2
- package/dist/directory/load.js.map +1 -1
- package/dist/directory/types.d.ts +2 -2
- package/dist/directory/types.d.ts.map +1 -1
- package/dist/eval/experiment.d.ts +5 -5
- package/dist/eval/experiment.d.ts.map +1 -1
- package/dist/eval/experiment.js +18 -18
- package/dist/eval/experiment.js.map +1 -1
- package/dist/eval/from-turn.d.ts +30 -0
- package/dist/eval/from-turn.d.ts.map +1 -0
- package/dist/eval/from-turn.js +46 -0
- package/dist/eval/from-turn.js.map +1 -0
- package/dist/eval/harness-verification.js +7 -7
- package/dist/eval/harness-verification.js.map +1 -1
- package/dist/eval/index.d.ts +2 -2
- package/dist/eval/index.d.ts.map +1 -1
- package/dist/eval/index.js +1 -1
- package/dist/eval/index.js.map +1 -1
- package/dist/eval/judge.d.ts +3 -3
- package/dist/eval/judge.d.ts.map +1 -1
- package/dist/eval/judge.js +6 -6
- package/dist/eval/judge.js.map +1 -1
- package/dist/eval/scorers.d.ts +8 -8
- package/dist/eval/scorers.d.ts.map +1 -1
- package/dist/eval/scorers.js +21 -21
- package/dist/eval/scorers.js.map +1 -1
- package/dist/eval/types.d.ts +12 -12
- package/dist/eval/types.d.ts.map +1 -1
- package/dist/eval/uncertainty.d.ts +2 -2
- package/dist/eval/uncertainty.js +2 -2
- package/dist/execution/code-runtime/types.d.ts +4 -4
- package/dist/execution/code-runtime/types.js +2 -2
- package/dist/execution/code-runtime/worker.d.ts +1 -1
- package/dist/execution/code-runtime/worker.js +1 -1
- package/dist/invariants/index.d.ts +1 -1
- package/dist/manager/agent/child-session.d.ts +49 -0
- package/dist/manager/agent/child-session.d.ts.map +1 -0
- package/dist/manager/agent/child-session.js +94 -0
- package/dist/manager/agent/child-session.js.map +1 -0
- package/dist/manager/agent/lifecycle.d.ts +90 -13
- package/dist/manager/agent/lifecycle.d.ts.map +1 -1
- package/dist/manager/agent/lifecycle.js +332 -88
- package/dist/manager/agent/lifecycle.js.map +1 -1
- package/dist/manager/index.d.ts +1 -2
- package/dist/manager/index.d.ts.map +1 -1
- package/dist/manager/index.js +1 -2
- package/dist/manager/index.js.map +1 -1
- package/dist/manager/plan/lifecycle.d.ts +11 -7
- package/dist/manager/plan/lifecycle.d.ts.map +1 -1
- package/dist/manager/plan/lifecycle.js +12 -9
- package/dist/manager/plan/lifecycle.js.map +1 -1
- package/dist/manager/resident/consumption.d.ts +12 -6
- package/dist/manager/resident/consumption.d.ts.map +1 -1
- package/dist/manager/resident/consumption.js +7 -5
- package/dist/manager/resident/consumption.js.map +1 -1
- package/dist/manager/resident/evidence-recall.d.ts +5 -5
- package/dist/manager/resident/evidence-recall.d.ts.map +1 -1
- package/dist/manager/resident/evidence-recall.js +9 -9
- package/dist/manager/resident/evidence-recall.js.map +1 -1
- package/dist/manager/resident/host.d.ts +2 -2
- package/dist/manager/resident/host.d.ts.map +1 -1
- package/dist/manager/resident/host.js +1 -1
- package/dist/manager/resident/learning-cycle.d.ts +8 -4
- package/dist/manager/resident/learning-cycle.d.ts.map +1 -1
- package/dist/manager/resident/learning-cycle.js +4 -2
- package/dist/manager/resident/learning-cycle.js.map +1 -1
- package/dist/manager/resident/learning-observation.d.ts +12 -7
- package/dist/manager/resident/learning-observation.d.ts.map +1 -1
- package/dist/manager/resident/learning-observation.js +8 -4
- package/dist/manager/resident/learning-observation.js.map +1 -1
- package/dist/manager/resident/learning-store.d.ts +13 -0
- package/dist/manager/resident/learning-store.d.ts.map +1 -1
- package/dist/manager/resident/learning-store.js +35 -16
- package/dist/manager/resident/learning-store.js.map +1 -1
- package/dist/manager/resident/learning.d.ts +14 -14
- package/dist/manager/resident/outbox.d.ts +4 -4
- package/dist/manager/resident/store.d.ts +8 -8
- package/dist/manager/resident/tool-evidence.d.ts +15 -10
- package/dist/manager/resident/tool-evidence.d.ts.map +1 -1
- package/dist/manager/resident/tool-evidence.js +14 -14
- package/dist/manager/resident/tool-evidence.js.map +1 -1
- package/dist/manager/session/turn-recorder.d.ts +261 -0
- package/dist/manager/session/turn-recorder.d.ts.map +1 -0
- package/dist/manager/session/turn-recorder.js +1115 -0
- package/dist/manager/session/turn-recorder.js.map +1 -0
- package/dist/plugin/lifecycle.d.ts +4 -4
- package/dist/plugin/lifecycle.d.ts.map +1 -1
- package/dist/plugin/lifecycle.js +17 -10
- package/dist/plugin/lifecycle.js.map +1 -1
- package/dist/plugin/shell-hook.d.ts +35 -12
- package/dist/plugin/shell-hook.d.ts.map +1 -1
- package/dist/plugin/shell-hook.js +52 -20
- package/dist/plugin/shell-hook.js.map +1 -1
- package/dist/pricing/index.d.ts +4 -4
- package/dist/pricing/index.js +5 -5
- package/dist/pricing/index.js.map +1 -1
- package/dist/probe/context.d.ts +3 -2
- package/dist/probe/context.d.ts.map +1 -1
- package/dist/probe/context.js +2 -1
- package/dist/probe/context.js.map +1 -1
- package/dist/probe/registry.js +1 -1
- package/dist/probe/registry.js.map +1 -1
- package/dist/prompt/coding-agent-doctrine.d.ts +1 -1
- package/dist/prompt/coding-agent-doctrine.js +1 -1
- package/dist/prompt/contributions.d.ts +27 -6
- package/dist/prompt/contributions.d.ts.map +1 -1
- package/dist/prompt/contributions.js +1 -1
- package/dist/prompt/contributions.js.map +1 -1
- package/dist/prompt/resident-learning.js +2 -2
- package/dist/prompt/resident-learning.js.map +1 -1
- package/dist/provider/collect-chat-completion.d.ts +2 -2
- package/dist/provider/collect-chat-completion.js +3 -3
- package/dist/provider/collect-chat-completion.js.map +1 -1
- package/dist/provider/conformance.d.ts +8 -1
- package/dist/provider/conformance.d.ts.map +1 -1
- package/dist/provider/conformance.js +13 -1
- package/dist/provider/conformance.js.map +1 -1
- package/dist/provider/errors.d.ts +1 -1
- package/dist/provider/errors.js +2 -2
- package/dist/provider/fallback.d.ts +4 -4
- package/dist/provider/fallback.js +6 -6
- package/dist/provider/fallback.js.map +1 -1
- package/dist/provider/idle-timeout.d.ts +2 -2
- package/dist/provider/idle-timeout.d.ts.map +1 -1
- package/dist/provider/idle-timeout.js +3 -3
- package/dist/provider/idle-timeout.js.map +1 -1
- package/dist/provider/instrumentation.d.ts +5 -2
- package/dist/provider/instrumentation.d.ts.map +1 -1
- package/dist/provider/instrumentation.js +9 -5
- package/dist/provider/instrumentation.js.map +1 -1
- package/dist/provider/mock.d.ts +1 -1
- package/dist/provider/mock.js +1 -1
- package/dist/provider/retry.d.ts +2 -2
- package/dist/provider/retry.js +6 -6
- package/dist/provider/retry.js.map +1 -1
- package/dist/provider/stream-text.d.ts +1 -1
- package/dist/provider/stream-text.d.ts.map +1 -1
- package/dist/provider/stream-text.js +1 -1
- package/dist/provider/stream-text.js.map +1 -1
- package/dist/provider/thinking-support.js +2 -2
- package/dist/provider/thinking-support.js.map +1 -1
- package/dist/provider/token-budget.d.ts +2 -2
- package/dist/provider/token-budget.d.ts.map +1 -1
- package/dist/provider/token-budget.js.map +1 -1
- package/dist/public-runtime.d.ts +69 -55
- package/dist/public-runtime.d.ts.map +1 -1
- package/dist/public-runtime.js +104 -99
- package/dist/public-runtime.js.map +1 -1
- package/dist/public-tools.d.ts +2 -2
- package/dist/public-tools.d.ts.map +1 -1
- package/dist/public-tools.js +7 -7
- package/dist/public-tools.js.map +1 -1
- package/dist/public-types.d.ts +18 -16
- package/dist/public-types.d.ts.map +1 -1
- package/dist/rag/embedding.js +1 -1
- package/dist/rag/embedding.js.map +1 -1
- package/dist/read-model/index.d.ts +2 -2
- package/dist/read-model/index.d.ts.map +1 -1
- package/dist/read-model/index.js +1 -1
- package/dist/read-model/index.js.map +1 -1
- package/dist/read-model/registry.d.ts +11 -11
- package/dist/read-model/registry.d.ts.map +1 -1
- package/dist/read-model/registry.js +2 -2
- package/dist/read-model/registry.js.map +1 -1
- package/dist/read-model/session-status.d.ts +34 -0
- package/dist/read-model/session-status.d.ts.map +1 -0
- package/dist/read-model/session-status.js +58 -0
- package/dist/read-model/session-status.js.map +1 -0
- package/dist/registry/command/kernel-commands.d.ts +4 -4
- package/dist/registry/command/kernel-commands.d.ts.map +1 -1
- package/dist/registry/command/kernel-commands.js +6 -6
- package/dist/registry/command/kernel-commands.js.map +1 -1
- package/dist/registry/tool/dialect.js +1 -1
- package/dist/registry/tool/execute.d.ts +2 -2
- package/dist/registry/tool/execute.d.ts.map +1 -1
- package/dist/registry/tool/execute.js +19 -7
- package/dist/registry/tool/execute.js.map +1 -1
- package/dist/registry/tool/portable.d.ts +1 -1
- package/dist/registry/tool/portable.js +1 -1
- package/dist/registry/tool/presentation.d.ts +1 -1
- package/dist/registry/tool/presentation.js +1 -1
- package/dist/registry/tool/schema.js +1 -1
- package/dist/registry/tool/screen.js +3 -3
- package/dist/registry/tool/screen.js.map +1 -1
- package/dist/runtime/bidi/index.d.ts +2 -2
- package/dist/runtime/bidi/index.d.ts.map +1 -1
- package/dist/runtime/bidi/index.js +1 -1
- package/dist/runtime/bidi/index.js.map +1 -1
- package/dist/runtime/bidi/session.d.ts +14 -11
- package/dist/runtime/bidi/session.d.ts.map +1 -1
- package/dist/runtime/bidi/session.js +27 -21
- package/dist/runtime/bidi/session.js.map +1 -1
- package/dist/runtime/jobs/awaited-jobs.d.ts +15 -15
- package/dist/runtime/jobs/awaited-jobs.d.ts.map +1 -1
- package/dist/runtime/jobs/awaited-jobs.js +13 -13
- package/dist/runtime/jobs/awaited-jobs.js.map +1 -1
- package/dist/runtime/jobs/registry.d.ts +10 -10
- package/dist/runtime/jobs/registry.d.ts.map +1 -1
- package/dist/runtime/jobs/registry.js +5 -5
- package/dist/runtime/jobs/registry.js.map +1 -1
- package/dist/runtime/query/abandon-turn.d.ts +35 -0
- package/dist/runtime/query/abandon-turn.d.ts.map +1 -0
- package/dist/runtime/query/abandon-turn.js +81 -0
- package/dist/runtime/query/abandon-turn.js.map +1 -0
- package/dist/runtime/query/approval-policy.d.ts +10 -10
- package/dist/runtime/query/approval-policy.d.ts.map +1 -1
- package/dist/runtime/query/approval-policy.js +5 -5
- package/dist/runtime/query/approval-policy.js.map +1 -1
- package/dist/runtime/query/callback-inference.d.ts +1 -1
- package/dist/runtime/query/callback-inference.d.ts.map +1 -1
- package/dist/runtime/query/callback-inference.js +12 -6
- package/dist/runtime/query/callback-inference.js.map +1 -1
- package/dist/runtime/query/cancelled-before-start.d.ts +20 -20
- package/dist/runtime/query/cancelled-before-start.d.ts.map +1 -1
- package/dist/runtime/query/cancelled-before-start.js +72 -55
- package/dist/runtime/query/cancelled-before-start.js.map +1 -1
- package/dist/runtime/query/checkpoint.d.ts +153 -220
- package/dist/runtime/query/checkpoint.d.ts.map +1 -1
- package/dist/runtime/query/checkpoint.js +399 -370
- package/dist/runtime/query/checkpoint.js.map +1 -1
- package/dist/runtime/query/compact-session.d.ts +20 -0
- package/dist/runtime/query/compact-session.d.ts.map +1 -0
- package/dist/runtime/query/compact-session.js +81 -0
- package/dist/runtime/query/compact-session.js.map +1 -0
- package/dist/runtime/query/context.d.ts +42 -85
- package/dist/runtime/query/context.d.ts.map +1 -1
- package/dist/runtime/query/context.js +36 -75
- package/dist/runtime/query/context.js.map +1 -1
- package/dist/runtime/query/events.d.ts +54 -26
- package/dist/runtime/query/events.d.ts.map +1 -1
- package/dist/runtime/query/events.js +121 -114
- package/dist/runtime/query/events.js.map +1 -1
- package/dist/runtime/query/executor/tool-call-admission.d.ts.map +1 -1
- package/dist/runtime/query/executor/tool-call-admission.js +6 -5
- package/dist/runtime/query/executor/tool-call-admission.js.map +1 -1
- package/dist/runtime/query/executor.d.ts +56 -34
- package/dist/runtime/query/executor.d.ts.map +1 -1
- package/dist/runtime/query/executor.js +165 -85
- package/dist/runtime/query/executor.js.map +1 -1
- package/dist/runtime/query/file-evidence-seed.d.ts +1 -1
- package/dist/runtime/query/file-evidence-seed.d.ts.map +1 -1
- package/dist/runtime/query/file-evidence-seed.js +1 -1
- package/dist/runtime/query/finalize-turn.d.ts +55 -0
- package/dist/runtime/query/finalize-turn.d.ts.map +1 -0
- package/dist/runtime/query/finalize-turn.js +129 -0
- package/dist/runtime/query/finalize-turn.js.map +1 -0
- package/dist/runtime/query/fork/list.d.ts +15 -0
- package/dist/runtime/query/fork/list.d.ts.map +1 -0
- package/dist/runtime/query/fork/list.js +11 -0
- package/dist/runtime/query/fork/list.js.map +1 -0
- package/dist/runtime/query/fork/mutate.d.ts +17 -0
- package/dist/runtime/query/fork/mutate.d.ts.map +1 -0
- package/dist/runtime/query/fork/mutate.js +69 -0
- package/dist/runtime/query/fork/mutate.js.map +1 -0
- package/dist/runtime/query/fork/prepare.d.ts +52 -0
- package/dist/runtime/query/fork/prepare.d.ts.map +1 -0
- package/dist/runtime/query/fork/prepare.js +43 -0
- package/dist/runtime/query/fork/prepare.js.map +1 -0
- package/dist/runtime/query/guard.d.ts +16 -16
- package/dist/runtime/query/guard.d.ts.map +1 -1
- package/dist/runtime/query/guard.js +16 -16
- package/dist/runtime/query/guard.js.map +1 -1
- package/dist/runtime/query/guardrail-presets.d.ts +10 -10
- package/dist/runtime/query/guardrail-presets.js +12 -12
- package/dist/runtime/query/guardrail-presets.js.map +1 -1
- package/dist/runtime/query/guardrails.d.ts +4 -4
- package/dist/runtime/query/guardrails.js +11 -11
- package/dist/runtime/query/guardrails.js.map +1 -1
- package/dist/runtime/query/index.d.ts +178 -155
- package/dist/runtime/query/index.d.ts.map +1 -1
- package/dist/runtime/query/index.js +1294 -1260
- package/dist/runtime/query/index.js.map +1 -1
- package/dist/runtime/query/iteration/index.d.ts +16 -16
- package/dist/runtime/query/iteration/index.d.ts.map +1 -1
- package/dist/runtime/query/iteration/index.js +285 -243
- package/dist/runtime/query/iteration/index.js.map +1 -1
- package/dist/runtime/query/iteration/outstanding-work.d.ts +22 -22
- package/dist/runtime/query/iteration/outstanding-work.d.ts.map +1 -1
- package/dist/runtime/query/iteration/outstanding-work.js +63 -63
- package/dist/runtime/query/iteration/outstanding-work.js.map +1 -1
- package/dist/runtime/query/iteration/phases/advisory.js +16 -16
- package/dist/runtime/query/iteration/phases/advisory.js.map +1 -1
- package/dist/runtime/query/iteration/phases/checkpoint.d.ts +2 -2
- package/dist/runtime/query/iteration/phases/checkpoint.d.ts.map +1 -1
- package/dist/runtime/query/iteration/phases/checkpoint.js +25 -8
- package/dist/runtime/query/iteration/phases/checkpoint.js.map +1 -1
- package/dist/runtime/query/iteration/phases/compaction.d.ts +2 -2
- package/dist/runtime/query/iteration/phases/compaction.d.ts.map +1 -1
- package/dist/runtime/query/iteration/phases/compaction.js +74 -72
- package/dist/runtime/query/iteration/phases/compaction.js.map +1 -1
- package/dist/runtime/query/iteration/phases/context.d.ts +32 -29
- package/dist/runtime/query/iteration/phases/context.d.ts.map +1 -1
- package/dist/runtime/query/iteration/phases/context.js +29 -29
- package/dist/runtime/query/iteration/phases/context.js.map +1 -1
- package/dist/runtime/query/iteration/phases/plan.d.ts +2 -2
- package/dist/runtime/query/iteration/phases/plan.d.ts.map +1 -1
- package/dist/runtime/query/iteration/phases/plan.js +5 -4
- package/dist/runtime/query/iteration/phases/plan.js.map +1 -1
- package/dist/runtime/query/iteration/phases/tool-review.d.ts +2 -2
- package/dist/runtime/query/iteration/phases/tool-review.d.ts.map +1 -1
- package/dist/runtime/query/iteration/phases/tool-review.js +129 -24
- package/dist/runtime/query/iteration/phases/tool-review.js.map +1 -1
- package/dist/runtime/query/iteration/phases/working-memory.d.ts +27 -3
- package/dist/runtime/query/iteration/phases/working-memory.d.ts.map +1 -1
- package/dist/runtime/query/iteration/phases/working-memory.js +54 -20
- package/dist/runtime/query/iteration/phases/working-memory.js.map +1 -1
- package/dist/runtime/query/iteration/step-context.d.ts +11 -0
- package/dist/runtime/query/iteration/step-context.d.ts.map +1 -0
- package/dist/runtime/query/iteration/step-context.js +14 -0
- package/dist/runtime/query/iteration/step-context.js.map +1 -0
- package/dist/runtime/query/iteration/step-shaping.d.ts +4 -3
- package/dist/runtime/query/iteration/step-shaping.d.ts.map +1 -1
- package/dist/runtime/query/iteration/step-shaping.js +20 -19
- package/dist/runtime/query/iteration/step-shaping.js.map +1 -1
- package/dist/runtime/query/iteration/stream-turn.d.ts +5 -3
- package/dist/runtime/query/iteration/stream-turn.d.ts.map +1 -1
- package/dist/runtime/query/iteration/stream-turn.js +32 -28
- package/dist/runtime/query/iteration/stream-turn.js.map +1 -1
- package/dist/runtime/query/plugin-hooks.js +1 -1
- package/dist/runtime/query/plugin-hooks.js.map +1 -1
- package/dist/runtime/query/prepare-turn.d.ts +105 -0
- package/dist/runtime/query/prepare-turn.d.ts.map +1 -0
- package/dist/runtime/query/prepare-turn.js +779 -0
- package/dist/runtime/query/prepare-turn.js.map +1 -0
- package/dist/runtime/query/project-instructions.d.ts +5 -4
- package/dist/runtime/query/project-instructions.d.ts.map +1 -1
- package/dist/runtime/query/project-instructions.js.map +1 -1
- package/dist/runtime/query/prompt-cache.js +1 -1
- package/dist/runtime/query/prompt-cache.js.map +1 -1
- package/dist/runtime/query/prompt.d.ts +3 -3
- package/dist/runtime/query/prompt.d.ts.map +1 -1
- package/dist/runtime/query/prompt.js +3 -3
- package/dist/runtime/query/prompt.js.map +1 -1
- package/dist/runtime/query/question-park.d.ts +7 -7
- package/dist/runtime/query/question-park.d.ts.map +1 -1
- package/dist/runtime/query/question-park.js +5 -5
- package/dist/runtime/query/question-park.js.map +1 -1
- package/dist/runtime/query/release-turn.d.ts +53 -0
- package/dist/runtime/query/release-turn.d.ts.map +1 -0
- package/dist/runtime/query/release-turn.js +95 -0
- package/dist/runtime/query/release-turn.js.map +1 -0
- package/dist/runtime/query/repeat-call.d.ts +2 -2
- package/dist/runtime/query/repeat-call.js +7 -7
- package/dist/runtime/query/repeat-call.js.map +1 -1
- package/dist/runtime/query/result.d.ts +25 -17
- package/dist/runtime/query/result.d.ts.map +1 -1
- package/dist/runtime/query/result.js +110 -115
- package/dist/runtime/query/result.js.map +1 -1
- package/dist/runtime/query/resume-pending.d.ts +34 -17
- package/dist/runtime/query/resume-pending.d.ts.map +1 -1
- package/dist/runtime/query/resume-pending.js +70 -30
- package/dist/runtime/query/resume-pending.js.map +1 -1
- package/dist/runtime/query/resume-session.d.ts +65 -0
- package/dist/runtime/query/resume-session.d.ts.map +1 -0
- package/dist/runtime/query/resume-session.js +88 -0
- package/dist/runtime/query/resume-session.js.map +1 -0
- package/dist/runtime/query/review-policy.d.ts +57 -16
- package/dist/runtime/query/review-policy.d.ts.map +1 -1
- package/dist/runtime/query/review-policy.js +115 -11
- package/dist/runtime/query/review-policy.js.map +1 -1
- package/dist/runtime/query/sandbox-lifecycle.d.ts +5 -5
- package/dist/runtime/query/sandbox-lifecycle.d.ts.map +1 -1
- package/dist/runtime/query/sandbox-lifecycle.js +4 -4
- package/dist/runtime/query/sandbox-lifecycle.js.map +1 -1
- package/dist/runtime/query/session-storage.d.ts +75 -0
- package/dist/runtime/query/session-storage.d.ts.map +1 -0
- package/dist/runtime/query/session-storage.js +236 -0
- package/dist/runtime/query/session-storage.js.map +1 -0
- package/dist/runtime/query/steering.d.ts +9 -3
- package/dist/runtime/query/steering.d.ts.map +1 -1
- package/dist/runtime/query/steering.js +12 -2
- package/dist/runtime/query/steering.js.map +1 -1
- package/dist/runtime/query/token-budget.d.ts +19 -5
- package/dist/runtime/query/token-budget.d.ts.map +1 -1
- package/dist/runtime/query/token-budget.js +43 -74
- package/dist/runtime/query/token-budget.js.map +1 -1
- package/dist/runtime/query/tool-call-budget.d.ts +6 -5
- package/dist/runtime/query/tool-call-budget.d.ts.map +1 -1
- package/dist/runtime/query/tool-call-budget.js +10 -12
- package/dist/runtime/query/tool-call-budget.js.map +1 -1
- package/dist/runtime/query/tool-executions.d.ts +26 -0
- package/dist/runtime/query/tool-executions.d.ts.map +1 -0
- package/dist/runtime/query/tool-executions.js +66 -0
- package/dist/runtime/query/tool-executions.js.map +1 -0
- package/dist/runtime/query/tool-grants.d.ts +3 -3
- package/dist/runtime/query/tool-grants.js +3 -3
- package/dist/runtime/query/tool-output-budget.d.ts +2 -2
- package/dist/runtime/query/tool-output-budget.js +4 -4
- package/dist/runtime/query/tool-output-budget.js.map +1 -1
- package/dist/runtime/query/tool-pause.d.ts +4 -3
- package/dist/runtime/query/tool-pause.d.ts.map +1 -1
- package/dist/runtime/query/tool-pause.js +5 -4
- package/dist/runtime/query/tool-pause.js.map +1 -1
- package/dist/runtime/query/tooling.d.ts +15 -10
- package/dist/runtime/query/tooling.d.ts.map +1 -1
- package/dist/runtime/query/tooling.js +7 -4
- package/dist/runtime/query/tooling.js.map +1 -1
- package/dist/runtime/query/turn-state.d.ts +56 -0
- package/dist/runtime/query/turn-state.d.ts.map +1 -0
- package/dist/runtime/query/turn-state.js +99 -0
- package/dist/runtime/query/turn-state.js.map +1 -0
- package/dist/sandbox/isolation.d.ts +1 -1
- package/dist/sandbox/isolation.js +2 -2
- package/dist/sandbox/isolation.js.map +1 -1
- package/dist/sandbox/provider/local.d.ts +2 -2
- package/dist/sandbox/provider/local.js +7 -7
- package/dist/sandbox/provider/local.js.map +1 -1
- package/dist/scheduler/completion-inbox.d.ts +21 -21
- package/dist/scheduler/completion-inbox.js +36 -36
- package/dist/scheduler/completion-inbox.js.map +1 -1
- package/dist/scheduler/delegating.d.ts +6 -3
- package/dist/scheduler/delegating.d.ts.map +1 -1
- package/dist/scheduler/delegating.js +15 -8
- package/dist/scheduler/delegating.js.map +1 -1
- package/dist/scheduler/local.d.ts +10 -8
- package/dist/scheduler/local.d.ts.map +1 -1
- package/dist/scheduler/local.js +37 -11
- package/dist/scheduler/local.js.map +1 -1
- package/dist/session/events/index.d.ts +3 -3
- package/dist/session/events/index.d.ts.map +1 -1
- package/dist/session/events/index.js +4 -8
- package/dist/session/events/index.js.map +1 -1
- package/dist/session/handoff/broadcast.d.ts +3 -3
- package/dist/session/handoff/broadcast.d.ts.map +1 -1
- package/dist/session/handoff/broadcast.js +4 -4
- package/dist/session/handoff/broadcast.js.map +1 -1
- package/dist/session/handoff/events.d.ts +1 -1
- package/dist/session/handoff/events.js +1 -1
- package/dist/session/handoff/index.d.ts +1 -1
- package/dist/session/handoff/index.d.ts.map +1 -1
- package/dist/session/handoff/single.d.ts +12 -12
- package/dist/session/handoff/single.d.ts.map +1 -1
- package/dist/session/handoff/single.js +9 -9
- package/dist/session/handoff/single.js.map +1 -1
- package/dist/session/handoff/version.d.ts +7 -7
- package/dist/session/handoff/version.d.ts.map +1 -1
- package/dist/session/handoff/version.js +2 -2
- package/dist/session/handoff/version.js.map +1 -1
- package/dist/session/home.d.ts +23 -0
- package/dist/session/home.d.ts.map +1 -0
- package/dist/session/home.js +45 -0
- package/dist/session/home.js.map +1 -0
- package/dist/session/index.d.ts +1 -0
- package/dist/session/index.d.ts.map +1 -1
- package/dist/session/index.js +1 -0
- package/dist/session/index.js.map +1 -1
- package/dist/session/log-hash.d.ts +25 -0
- package/dist/session/log-hash.d.ts.map +1 -0
- package/dist/session/log-hash.js +82 -0
- package/dist/session/log-hash.js.map +1 -0
- package/dist/session/messages.d.ts +11 -0
- package/dist/session/messages.d.ts.map +1 -0
- package/dist/session/messages.js +32 -0
- package/dist/session/messages.js.map +1 -0
- package/dist/session/paths.d.ts +168 -0
- package/dist/session/paths.d.ts.map +1 -0
- package/dist/session/paths.js +338 -0
- package/dist/session/paths.js.map +1 -0
- package/dist/session/retention/archive.d.ts +8 -1
- package/dist/session/retention/archive.d.ts.map +1 -1
- package/dist/session/retention/archive.js +3 -5
- package/dist/session/retention/archive.js.map +1 -1
- package/dist/session/status/derive.d.ts +13 -13
- package/dist/session/status/derive.d.ts.map +1 -1
- package/dist/session/status/derive.js +20 -20
- package/dist/session/status/derive.js.map +1 -1
- package/dist/session/workspace/git-worktree.d.ts +8 -1
- package/dist/session/workspace/git-worktree.d.ts.map +1 -1
- package/dist/session/workspace/git-worktree.js +29 -1
- package/dist/session/workspace/git-worktree.js.map +1 -1
- package/dist/session/workspace/index.d.ts +2 -4
- package/dist/session/workspace/index.d.ts.map +1 -1
- package/dist/session/workspace/index.js +2 -3
- package/dist/session/workspace/index.js.map +1 -1
- package/dist/session/workspace/shared-session.d.ts +112 -0
- package/dist/session/workspace/shared-session.d.ts.map +1 -0
- package/dist/session/workspace/shared-session.js +290 -0
- package/dist/session/workspace/shared-session.js.map +1 -0
- package/dist/session-query/index.d.ts +67 -0
- package/dist/session-query/index.d.ts.map +1 -0
- package/dist/session-query/index.js +100 -0
- package/dist/session-query/index.js.map +1 -0
- package/dist/skills/registry.d.ts +1 -1
- package/dist/skills/registry.js +1 -1
- package/dist/store/activity/memory.d.ts +3 -3
- package/dist/store/activity/memory.d.ts.map +1 -1
- package/dist/store/activity/memory.js +4 -4
- package/dist/store/activity/memory.js.map +1 -1
- package/dist/store/attachment/index.d.ts +4 -4
- package/dist/store/attachment/index.d.ts.map +1 -1
- package/dist/store/attachment/index.js +3 -3
- package/dist/store/attachment/index.js.map +1 -1
- package/dist/store/budget/disk.d.ts +59 -0
- package/dist/store/budget/disk.d.ts.map +1 -0
- package/dist/store/budget/disk.js +179 -0
- package/dist/store/budget/disk.js.map +1 -0
- package/dist/store/budget/index.d.ts +6 -0
- package/dist/store/budget/index.d.ts.map +1 -0
- package/dist/store/budget/index.js +6 -0
- package/dist/store/budget/index.js.map +1 -0
- package/dist/store/budget/ledger.d.ts +156 -0
- package/dist/store/budget/ledger.d.ts.map +1 -0
- package/dist/store/budget/ledger.js +683 -0
- package/dist/store/budget/ledger.js.map +1 -0
- package/dist/store/budget/memory.d.ts +18 -0
- package/dist/store/budget/memory.d.ts.map +1 -0
- package/dist/store/budget/memory.js +31 -0
- package/dist/store/budget/memory.js.map +1 -0
- package/dist/store/checkpoint/contract.d.ts +140 -0
- package/dist/store/checkpoint/contract.d.ts.map +1 -0
- package/dist/store/checkpoint/contract.js +91 -0
- package/dist/store/checkpoint/contract.js.map +1 -0
- package/dist/store/checkpoint/disk.d.ts +44 -0
- package/dist/store/checkpoint/disk.d.ts.map +1 -0
- package/dist/store/checkpoint/disk.js +168 -0
- package/dist/store/checkpoint/disk.js.map +1 -0
- package/dist/store/checkpoint/index.d.ts +9 -0
- package/dist/store/checkpoint/index.d.ts.map +1 -0
- package/dist/store/checkpoint/index.js +7 -0
- package/dist/store/checkpoint/index.js.map +1 -0
- package/dist/store/checkpoint/memory.d.ts +27 -0
- package/dist/store/checkpoint/memory.d.ts.map +1 -0
- package/dist/store/checkpoint/memory.js +80 -0
- package/dist/store/checkpoint/memory.js.map +1 -0
- package/dist/store/checkpoint/prune.d.ts +45 -0
- package/dist/store/checkpoint/prune.d.ts.map +1 -0
- package/dist/store/checkpoint/prune.js +71 -0
- package/dist/store/checkpoint/prune.js.map +1 -0
- package/dist/store/config/index.d.ts +1 -1
- package/dist/store/config/index.js +1 -1
- package/dist/store/evidence/disk.d.ts +25 -8
- package/dist/store/evidence/disk.d.ts.map +1 -1
- package/dist/store/evidence/disk.js +148 -47
- package/dist/store/evidence/disk.js.map +1 -1
- package/dist/store/evidence/index-page.d.ts +31 -140
- package/dist/store/evidence/index-page.d.ts.map +1 -1
- package/dist/store/evidence/index-page.js +59 -129
- package/dist/store/evidence/index-page.js.map +1 -1
- package/dist/store/evidence/source-text.d.ts +7 -6
- package/dist/store/evidence/source-text.d.ts.map +1 -1
- package/dist/store/evidence/source-text.js +16 -23
- package/dist/store/evidence/source-text.js.map +1 -1
- package/dist/store/evidence/types.d.ts +38 -39
- package/dist/store/evidence/types.d.ts.map +1 -1
- package/dist/store/feedback/conformance.d.ts +6 -6
- package/dist/store/feedback/conformance.d.ts.map +1 -1
- package/dist/store/feedback/conformance.js +30 -29
- package/dist/store/feedback/conformance.js.map +1 -1
- package/dist/store/feedback/disk.d.ts +20 -19
- package/dist/store/feedback/disk.d.ts.map +1 -1
- package/dist/store/feedback/disk.js +53 -53
- package/dist/store/feedback/disk.js.map +1 -1
- package/dist/store/feedback/index.d.ts +1 -1
- package/dist/store/feedback/index.d.ts.map +1 -1
- package/dist/store/feedback/index.js +1 -1
- package/dist/store/feedback/index.js.map +1 -1
- package/dist/store/feedback/memory.d.ts +8 -5
- package/dist/store/feedback/memory.d.ts.map +1 -1
- package/dist/store/feedback/memory.js +0 -0
- package/dist/store/feedback/memory.js.map +1 -1
- package/dist/store/feedback/types.d.ts +12 -11
- package/dist/store/feedback/types.d.ts.map +1 -1
- package/dist/store/feedback/types.js +3 -3
- package/dist/store/feedback/types.js.map +1 -1
- package/dist/store/index.d.ts +7 -8
- package/dist/store/index.d.ts.map +1 -1
- package/dist/store/index.js +4 -16
- package/dist/store/index.js.map +1 -1
- package/dist/store/memory/digest.d.ts +15 -0
- package/dist/store/memory/digest.d.ts.map +1 -0
- package/dist/store/memory/digest.js +27 -0
- package/dist/store/memory/digest.js.map +1 -0
- package/dist/store/memory/disk.d.ts.map +1 -1
- package/dist/store/memory/disk.js +42 -7
- package/dist/store/memory/disk.js.map +1 -1
- package/dist/store/memory/index-file.d.ts +56 -0
- package/dist/store/memory/index-file.d.ts.map +1 -0
- package/dist/store/memory/index-file.js +92 -0
- package/dist/store/memory/index-file.js.map +1 -0
- package/dist/store/memory/index.d.ts.map +1 -1
- package/dist/store/memory/index.js +4 -2
- package/dist/store/memory/index.js.map +1 -1
- package/dist/store/memory/links.d.ts +15 -0
- package/dist/store/memory/links.d.ts.map +1 -0
- package/dist/store/memory/links.js +35 -0
- package/dist/store/memory/links.js.map +1 -0
- package/dist/store/memory/markdown-format.d.ts +88 -0
- package/dist/store/memory/markdown-format.d.ts.map +1 -0
- package/dist/store/memory/markdown-format.js +222 -0
- package/dist/store/memory/markdown-format.js.map +1 -0
- package/dist/store/memory/markdown.d.ts +109 -0
- package/dist/store/memory/markdown.d.ts.map +1 -0
- package/dist/store/memory/markdown.js +606 -0
- package/dist/store/memory/markdown.js.map +1 -0
- package/dist/store/memory/memory.d.ts.map +1 -1
- package/dist/store/memory/memory.js +17 -4
- package/dist/store/memory/memory.js.map +1 -1
- package/dist/store/memory/naming.d.ts +66 -0
- package/dist/store/memory/naming.d.ts.map +1 -0
- package/dist/store/memory/naming.js +162 -0
- package/dist/store/memory/naming.js.map +1 -0
- package/dist/store/memory/origin.d.ts +25 -0
- package/dist/store/memory/origin.d.ts.map +1 -0
- package/dist/store/memory/origin.js +26 -0
- package/dist/store/memory/origin.js.map +1 -0
- package/dist/store/session/disk.d.ts +21 -24
- package/dist/store/session/disk.d.ts.map +1 -1
- package/dist/store/session/disk.js +27 -132
- package/dist/store/session/disk.js.map +1 -1
- package/dist/store/session/index.d.ts +0 -3
- package/dist/store/session/index.d.ts.map +1 -1
- package/dist/store/session/index.js +5 -7
- package/dist/store/session/index.js.map +1 -1
- package/dist/store/session/memory.d.ts +1 -8
- package/dist/store/session/memory.d.ts.map +1 -1
- package/dist/store/session/memory.js +1 -58
- package/dist/store/session/memory.js.map +1 -1
- package/dist/store/session-claim.d.ts +30 -0
- package/dist/store/session-claim.d.ts.map +1 -0
- package/dist/store/session-claim.js +71 -0
- package/dist/store/session-claim.js.map +1 -0
- package/dist/store/session-index/fts.d.ts +60 -0
- package/dist/store/session-index/fts.d.ts.map +1 -0
- package/dist/store/session-index/fts.js +160 -0
- package/dist/store/session-index/fts.js.map +1 -0
- package/dist/store/session-index/index.d.ts +206 -0
- package/dist/store/session-index/index.d.ts.map +1 -0
- package/dist/store/session-index/index.js +22 -0
- package/dist/store/session-index/index.js.map +1 -0
- package/dist/store/session-index/rebuild.d.ts +180 -0
- package/dist/store/session-index/rebuild.d.ts.map +1 -0
- package/dist/store/session-index/rebuild.js +669 -0
- package/dist/store/session-index/rebuild.js.map +1 -0
- package/dist/store/session-index/refs.d.ts +66 -0
- package/dist/store/session-index/refs.d.ts.map +1 -0
- package/dist/store/session-index/refs.js +107 -0
- package/dist/store/session-index/refs.js.map +1 -0
- package/dist/store/session-index/scan.d.ts +42 -0
- package/dist/store/session-index/scan.d.ts.map +1 -0
- package/dist/store/session-index/scan.js +188 -0
- package/dist/store/session-index/scan.js.map +1 -0
- package/dist/store/session-index/sqlite.d.ts +76 -0
- package/dist/store/session-index/sqlite.d.ts.map +1 -0
- package/dist/store/session-index/sqlite.js +547 -0
- package/dist/store/session-index/sqlite.js.map +1 -0
- package/dist/store/session-log/chain.d.ts +111 -0
- package/dist/store/session-log/chain.d.ts.map +1 -0
- package/dist/store/session-log/chain.js +212 -0
- package/dist/store/session-log/chain.js.map +1 -0
- package/dist/store/session-log/conformance.d.ts +61 -0
- package/dist/store/session-log/conformance.d.ts.map +1 -0
- package/dist/store/session-log/conformance.js +392 -0
- package/dist/store/session-log/conformance.js.map +1 -0
- package/dist/store/session-log/core.d.ts +203 -0
- package/dist/store/session-log/core.d.ts.map +1 -0
- package/dist/store/session-log/core.js +516 -0
- package/dist/store/session-log/core.js.map +1 -0
- package/dist/store/session-log/disk.d.ts +56 -0
- package/dist/store/session-log/disk.d.ts.map +1 -0
- package/dist/store/session-log/disk.js +169 -0
- package/dist/store/session-log/disk.js.map +1 -0
- package/dist/store/session-log/fold.d.ts +115 -0
- package/dist/store/session-log/fold.d.ts.map +1 -0
- package/dist/store/session-log/fold.js +265 -0
- package/dist/store/session-log/fold.js.map +1 -0
- package/dist/store/session-log/heal.d.ts +34 -0
- package/dist/store/session-log/heal.d.ts.map +1 -0
- package/dist/store/session-log/heal.js +12 -0
- package/dist/store/session-log/heal.js.map +1 -0
- package/dist/store/session-log/held-leases.d.ts +56 -0
- package/dist/store/session-log/held-leases.d.ts.map +1 -0
- package/dist/store/session-log/held-leases.js +67 -0
- package/dist/store/session-log/held-leases.js.map +1 -0
- package/dist/store/session-log/index.d.ts +10 -0
- package/dist/store/session-log/index.d.ts.map +1 -0
- package/dist/store/session-log/index.js +16 -0
- package/dist/store/session-log/index.js.map +1 -0
- package/dist/store/session-log/lease.d.ts +126 -0
- package/dist/store/session-log/lease.d.ts.map +1 -0
- package/dist/store/session-log/lease.js +226 -0
- package/dist/store/session-log/lease.js.map +1 -0
- package/dist/store/session-log/memory.d.ts +43 -0
- package/dist/store/session-log/memory.d.ts.map +1 -0
- package/dist/store/session-log/memory.js +78 -0
- package/dist/store/session-log/memory.js.map +1 -0
- package/dist/store/session-log/spill.d.ts +109 -0
- package/dist/store/session-log/spill.d.ts.map +1 -0
- package/dist/store/session-log/spill.js +223 -0
- package/dist/store/session-log/spill.js.map +1 -0
- package/dist/store/task/context.d.ts +25 -0
- package/dist/store/task/context.d.ts.map +1 -0
- package/dist/store/task/context.js +18 -0
- package/dist/store/task/context.js.map +1 -0
- package/dist/store/task/disk.d.ts +29 -26
- package/dist/store/task/disk.d.ts.map +1 -1
- package/dist/store/task/disk.js +102 -137
- package/dist/store/task/disk.js.map +1 -1
- package/dist/store/task/memory.d.ts +2 -2
- package/dist/store/task/memory.d.ts.map +1 -1
- package/dist/store/task/memory.js +10 -6
- package/dist/store/task/memory.js.map +1 -1
- package/dist/store/topic/index.js +2 -2
- package/dist/store/topic/index.js.map +1 -1
- package/dist/store/topic/objective.d.ts.map +1 -1
- package/dist/store/topic/objective.js +10 -3
- package/dist/store/topic/objective.js.map +1 -1
- package/dist/store/topic/state.js +1 -1
- package/dist/streaming/coalesce.d.ts +3 -3
- package/dist/streaming/coalesce.d.ts.map +1 -1
- package/dist/streaming/coalesce.js +1 -1
- package/dist/streaming/coalesce.js.map +1 -1
- package/dist/telemetry/attributes.d.ts +9 -8
- package/dist/telemetry/attributes.d.ts.map +1 -1
- package/dist/telemetry/attributes.js +6 -5
- package/dist/telemetry/attributes.js.map +1 -1
- package/dist/telemetry/metrics.d.ts +2 -2
- package/dist/telemetry/metrics.d.ts.map +1 -1
- package/dist/telemetry/metrics.js +5 -5
- package/dist/telemetry/metrics.js.map +1 -1
- package/dist/telemetry/runtime-accessors.js +1 -1
- package/dist/telemetry/runtime-accessors.js.map +1 -1
- package/dist/test-support/ids.d.ts +4 -4
- package/dist/test-support/ids.d.ts.map +1 -1
- package/dist/test-support/ids.js +3 -3
- package/dist/test-support/ids.js.map +1 -1
- package/dist/testing.d.ts +4 -6
- package/dist/testing.d.ts.map +1 -1
- package/dist/testing.js +3 -5
- package/dist/testing.js.map +1 -1
- package/dist/tools/advisory/index.js +1 -1
- package/dist/tools/advisory/index.js.map +1 -1
- package/dist/tools/builtins/bash.d.ts +6 -0
- package/dist/tools/builtins/bash.d.ts.map +1 -1
- package/dist/tools/builtins/bash.js +37 -5
- package/dist/tools/builtins/bash.js.map +1 -1
- package/dist/tools/builtins/content-fingerprint.d.ts +2 -2
- package/dist/tools/builtins/content-fingerprint.js +2 -2
- package/dist/tools/builtins/edit-apply.js +1 -1
- package/dist/tools/builtins/edit-apply.js.map +1 -1
- package/dist/tools/builtins/edit.d.ts.map +1 -1
- package/dist/tools/builtins/edit.js +3 -0
- package/dist/tools/builtins/edit.js.map +1 -1
- package/dist/tools/builtins/glob.d.ts.map +1 -1
- package/dist/tools/builtins/glob.js +3 -0
- 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 +3 -0
- package/dist/tools/builtins/grep.js.map +1 -1
- package/dist/tools/builtins/job.js +5 -5
- package/dist/tools/builtins/job.js.map +1 -1
- package/dist/tools/builtins/ls.d.ts +1 -1
- package/dist/tools/builtins/ls.d.ts.map +1 -1
- package/dist/tools/builtins/ls.js +3 -0
- package/dist/tools/builtins/ls.js.map +1 -1
- package/dist/tools/builtins/lsp.d.ts +1 -1
- package/dist/tools/builtins/lsp.d.ts.map +1 -1
- package/dist/tools/builtins/lsp.js +5 -2
- package/dist/tools/builtins/lsp.js.map +1 -1
- package/dist/tools/builtins/read-file.d.ts.map +1 -1
- package/dist/tools/builtins/read-file.js +3 -0
- package/dist/tools/builtins/read-file.js.map +1 -1
- package/dist/tools/builtins/run-code.js +9 -9
- package/dist/tools/builtins/run-code.js.map +1 -1
- package/dist/tools/builtins/skill.js +3 -3
- package/dist/tools/builtins/skill.js.map +1 -1
- package/dist/tools/builtins/wait-for-job-bounds.d.ts +4 -4
- package/dist/tools/builtins/wait-for-job-bounds.d.ts.map +1 -1
- package/dist/tools/builtins/wait-for-job-bounds.js +2 -2
- package/dist/tools/builtins/wait-for-job-bounds.js.map +1 -1
- package/dist/tools/builtins/wait-for-job.js +3 -3
- package/dist/tools/builtins/wait-for-job.js.map +1 -1
- package/dist/tools/builtins/web-guidance.d.ts +2 -2
- package/dist/tools/builtins/web-guidance.js +2 -2
- package/dist/tools/builtins/web.js +3 -3
- package/dist/tools/builtins/web.js.map +1 -1
- package/dist/tools/builtins/write-file.d.ts.map +1 -1
- package/dist/tools/builtins/write-file.js +3 -0
- package/dist/tools/builtins/write-file.js.map +1 -1
- package/dist/tools/coordinator/agent.d.ts +1 -1
- package/dist/tools/coordinator/agent.js +7 -7
- package/dist/tools/coordinator/agent.js.map +1 -1
- package/dist/tools/coordinator/ask-user-question.d.ts +10 -9
- package/dist/tools/coordinator/ask-user-question.d.ts.map +1 -1
- package/dist/tools/coordinator/ask-user-question.js +9 -8
- package/dist/tools/coordinator/ask-user-question.js.map +1 -1
- package/dist/tools/coordinator/index.d.ts +17 -11
- package/dist/tools/coordinator/index.d.ts.map +1 -1
- package/dist/tools/coordinator/index.js +45 -44
- package/dist/tools/coordinator/index.js.map +1 -1
- package/dist/tools/coordinator/outcome.d.ts +5 -5
- package/dist/tools/coordinator/outcome.js +7 -7
- package/dist/tools/coordinator/outcome.js.map +1 -1
- package/dist/tools/coordinator/plan-dependencies.js +1 -1
- package/dist/tools/coordinator/plan-dependencies.js.map +1 -1
- package/dist/tools/coordinator/wait-with-idle-bound.d.ts +4 -4
- package/dist/tools/coordinator/wait-with-idle-bound.d.ts.map +1 -1
- package/dist/tools/coordinator/wait-with-idle-bound.js +2 -2
- package/dist/tools/coordinator/wait-with-idle-bound.js.map +1 -1
- package/dist/tools/defineTool.d.ts +5 -1
- package/dist/tools/defineTool.d.ts.map +1 -1
- package/dist/tools/defineTool.js +4 -0
- package/dist/tools/defineTool.js.map +1 -1
- package/dist/tools/env-scrub.d.ts +1 -1
- package/dist/tools/env-scrub.js +1 -1
- package/dist/tools/goal/index.d.ts +10 -6
- package/dist/tools/goal/index.d.ts.map +1 -1
- package/dist/tools/goal/index.js +9 -9
- package/dist/tools/goal/index.js.map +1 -1
- package/dist/tools/memory/fields.d.ts +8 -0
- package/dist/tools/memory/fields.d.ts.map +1 -0
- package/dist/tools/memory/fields.js +22 -0
- package/dist/tools/memory/fields.js.map +1 -0
- package/dist/tools/memory/read.d.ts.map +1 -1
- package/dist/tools/memory/read.js +60 -7
- package/dist/tools/memory/read.js.map +1 -1
- package/dist/tools/memory/resolve.d.ts +21 -0
- package/dist/tools/memory/resolve.d.ts.map +1 -0
- package/dist/tools/memory/resolve.js +23 -0
- package/dist/tools/memory/resolve.js.map +1 -0
- package/dist/tools/memory/save.d.ts.map +1 -1
- package/dist/tools/memory/save.js +57 -18
- 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 +9 -2
- package/dist/tools/memory/search.js.map +1 -1
- package/dist/tools/memory/update.d.ts.map +1 -1
- package/dist/tools/memory/update.js +45 -7
- package/dist/tools/memory/update.js.map +1 -1
- package/dist/tools/paths.d.ts +29 -3
- package/dist/tools/paths.d.ts.map +1 -1
- package/dist/tools/paths.js +81 -23
- package/dist/tools/paths.js.map +1 -1
- package/dist/tools/posix-path.js +1 -1
- package/dist/tools/posix-path.js.map +1 -1
- package/dist/tools/resident-history.d.ts +1 -1
- package/dist/tools/resident-history.js +1 -1
- package/dist/tools/resident-tool-evidence.d.ts +1 -1
- package/dist/tools/resident-tool-evidence.d.ts.map +1 -1
- package/dist/tools/resident-tool-evidence.js +1 -1
- package/dist/tools/resident-tool-evidence.js.map +1 -1
- package/dist/tools/task/create.d.ts +2 -2
- package/dist/tools/task/create.d.ts.map +1 -1
- package/dist/tools/task/create.js +3 -2
- package/dist/tools/task/create.js.map +1 -1
- package/dist/tools/task/index.d.ts +16 -2
- package/dist/tools/task/index.d.ts.map +1 -1
- package/dist/tools/task/index.js +4 -3
- package/dist/tools/task/index.js.map +1 -1
- package/dist/tools/task/list.d.ts +4 -2
- package/dist/tools/task/list.d.ts.map +1 -1
- package/dist/tools/task/list.js +8 -4
- package/dist/tools/task/list.js.map +1 -1
- package/dist/turn/LimitChecker.d.ts +30 -0
- package/dist/turn/LimitChecker.d.ts.map +1 -0
- package/dist/turn/LimitChecker.js +57 -0
- package/dist/turn/LimitChecker.js.map +1 -0
- package/dist/turn/command-gate.d.ts +107 -0
- package/dist/turn/command-gate.d.ts.map +1 -0
- package/dist/turn/command-gate.js +221 -0
- package/dist/turn/command-gate.js.map +1 -0
- package/dist/turn/drain.d.ts +138 -0
- package/dist/turn/drain.d.ts.map +1 -0
- package/dist/turn/drain.js +209 -0
- package/dist/turn/drain.js.map +1 -0
- package/dist/turn/evidence-query.d.ts +41 -0
- package/dist/turn/evidence-query.d.ts.map +1 -0
- package/dist/turn/evidence-query.js +270 -0
- package/dist/turn/evidence-query.js.map +1 -0
- package/dist/turn/evidence-recall.d.ts +102 -0
- package/dist/turn/evidence-recall.d.ts.map +1 -0
- package/dist/turn/evidence-recall.js +635 -0
- package/dist/turn/evidence-recall.js.map +1 -0
- package/dist/turn/index.d.ts +17 -0
- package/dist/turn/index.d.ts.map +1 -0
- package/dist/turn/index.js +9 -0
- package/dist/turn/index.js.map +1 -0
- package/dist/turn/json-claim-verifier.d.ts +83 -0
- package/dist/turn/json-claim-verifier.d.ts.map +1 -0
- package/dist/turn/json-claim-verifier.js +200 -0
- package/dist/turn/json-claim-verifier.js.map +1 -0
- package/dist/turn/memory-promoter.d.ts +43 -0
- package/dist/turn/memory-promoter.d.ts.map +1 -0
- package/dist/turn/memory-promoter.js +111 -0
- package/dist/turn/memory-promoter.js.map +1 -0
- package/dist/turn/memory-recall.d.ts +33 -0
- package/dist/turn/memory-recall.d.ts.map +1 -0
- package/dist/turn/memory-recall.js +248 -0
- package/dist/turn/memory-recall.js.map +1 -0
- package/dist/turn/preparation-context-error.d.ts.map +1 -0
- package/dist/turn/preparation-context-error.js.map +1 -0
- package/dist/turn/reporter.d.ts +8 -0
- package/dist/turn/reporter.d.ts.map +1 -0
- package/dist/turn/reporter.js +420 -0
- package/dist/turn/reporter.js.map +1 -0
- package/dist/turn/workspace-fingerprint.d.ts.map +1 -0
- package/dist/turn/workspace-fingerprint.js.map +1 -0
- package/dist/types/activity/index.d.ts +2 -2
- package/dist/types/activity/index.d.ts.map +1 -1
- package/dist/types/advisory/config.d.ts +7 -7
- package/dist/types/advisory/config.d.ts.map +1 -1
- package/dist/types/agent/base.d.ts +71 -44
- package/dist/types/agent/base.d.ts.map +1 -1
- package/dist/types/agent/core.d.ts +10 -10
- package/dist/types/agent/core.d.ts.map +1 -1
- package/dist/types/agent/delegate.d.ts +2 -2
- package/dist/types/agent/factory.d.ts +6 -4
- package/dist/types/agent/factory.d.ts.map +1 -1
- package/dist/types/agent/manager.d.ts +6 -6
- package/dist/types/agent/manager.d.ts.map +1 -1
- package/dist/types/agent/pipeline.d.ts +5 -4
- package/dist/types/agent/pipeline.d.ts.map +1 -1
- package/dist/types/agent/reactive.d.ts +11 -10
- package/dist/types/agent/reactive.d.ts.map +1 -1
- package/dist/types/agent/router.d.ts +1 -1
- package/dist/types/agent/scheduler.d.ts +27 -11
- package/dist/types/agent/scheduler.d.ts.map +1 -1
- package/dist/types/agent/supervisor.d.ts +13 -13
- package/dist/types/agent/task.d.ts +48 -12
- package/dist/types/agent/task.d.ts.map +1 -1
- package/dist/types/agent/working-memory.d.ts +5 -4
- package/dist/types/agent/working-memory.d.ts.map +1 -1
- package/dist/types/authorization/index.d.ts +6 -6
- package/dist/types/bidi/index.d.ts +21 -12
- package/dist/types/bidi/index.d.ts.map +1 -1
- package/dist/types/bus/index.d.ts +34 -28
- package/dist/types/bus/index.d.ts.map +1 -1
- package/dist/types/code-navigation/index.d.ts +1 -1
- package/dist/types/common/index.d.ts +10 -18
- package/dist/types/common/index.d.ts.map +1 -1
- package/dist/types/common/index.js +3 -2
- package/dist/types/common/index.js.map +1 -1
- package/dist/types/connector/core.d.ts +2 -2
- package/dist/types/connector/definition.d.ts +1 -1
- package/dist/types/connector/mcp.d.ts +1 -1
- package/dist/types/errors/catalog.js +4 -4
- package/dist/types/errors/catalog.js.map +1 -1
- package/dist/types/errors/index.d.ts +5 -5
- package/dist/types/errors/index.d.ts.map +1 -1
- package/dist/types/guardrail/index.d.ts +12 -10
- package/dist/types/guardrail/index.d.ts.map +1 -1
- package/dist/types/hitl/index.d.ts +60 -117
- package/dist/types/hitl/index.d.ts.map +1 -1
- package/dist/types/hitl/index.js +1 -1
- package/dist/types/hitl/index.js.map +1 -1
- package/dist/types/hitl/policy.d.ts +8 -6
- package/dist/types/hitl/policy.d.ts.map +1 -1
- package/dist/types/ids/brand.d.ts +10 -3
- package/dist/types/ids/brand.d.ts.map +1 -1
- package/dist/types/ids/brand.js.map +1 -1
- package/dist/types/ids/index.d.ts +10 -4
- package/dist/types/ids/index.d.ts.map +1 -1
- package/dist/types/ids/index.js.map +1 -1
- package/dist/types/memory/index.d.ts +35 -0
- package/dist/types/memory/index.d.ts.map +1 -1
- package/dist/types/memory/index.js +17 -0
- package/dist/types/memory/index.js.map +1 -1
- package/dist/types/message/index.d.ts +4 -4
- package/dist/types/plan/index.d.ts +5 -3
- package/dist/types/plan/index.d.ts.map +1 -1
- package/dist/types/plugin/index.d.ts +27 -19
- package/dist/types/plugin/index.d.ts.map +1 -1
- package/dist/types/plugin/index.js +16 -3
- package/dist/types/plugin/index.js.map +1 -1
- package/dist/types/probe/event-kind.d.ts +3 -3
- package/dist/types/probe/event-kind.d.ts.map +1 -1
- package/dist/types/probe/registry.d.ts +3 -2
- package/dist/types/probe/registry.d.ts.map +1 -1
- package/dist/types/project/entity.d.ts +3 -3
- package/dist/types/provider/config.d.ts +3 -3
- package/dist/types/provider/error.d.ts +1 -1
- package/dist/types/provider/errors.d.ts +2 -2
- package/dist/types/provider/errors.js +2 -2
- package/dist/types/provider/errors.js.map +1 -1
- package/dist/types/provider/interface.d.ts +5 -5
- package/dist/types/provider/model.d.ts +26 -2
- package/dist/types/provider/model.d.ts.map +1 -1
- package/dist/types/router/task-router.d.ts +1 -1
- package/dist/types/sandbox/index.d.ts +14 -14
- package/dist/types/sandbox/index.d.ts.map +1 -1
- package/dist/types/sandbox/index.js +4 -4
- package/dist/types/session/answer-review.d.ts +80 -0
- package/dist/types/session/answer-review.d.ts.map +1 -0
- package/dist/types/session/answer-review.js.map +1 -0
- package/dist/types/session/audit.d.ts +153 -0
- package/dist/types/session/audit.d.ts.map +1 -0
- package/dist/types/session/audit.js +35 -0
- package/dist/types/session/audit.js.map +1 -0
- package/dist/types/session/cancel-cause.d.ts +49 -0
- package/dist/types/session/cancel-cause.d.ts.map +1 -0
- package/dist/types/session/cancel-cause.js +39 -0
- package/dist/types/session/cancel-cause.js.map +1 -0
- package/dist/types/session/checkpoint.d.ts +325 -0
- package/dist/types/session/checkpoint.d.ts.map +1 -0
- package/dist/types/session/checkpoint.js +100 -0
- package/dist/types/session/checkpoint.js.map +1 -0
- package/dist/types/session/config.d.ts +199 -0
- package/dist/types/session/config.d.ts.map +1 -0
- package/dist/types/session/config.js.map +1 -0
- package/dist/types/session/derive-status.d.ts +28 -0
- package/dist/types/session/derive-status.d.ts.map +1 -0
- package/dist/types/session/derive-status.js +49 -0
- package/dist/types/session/derive-status.js.map +1 -0
- package/dist/types/session/durable.d.ts +142 -0
- package/dist/types/session/durable.d.ts.map +1 -0
- package/dist/types/session/durable.js +11 -0
- package/dist/types/session/durable.js.map +1 -0
- package/dist/types/session/entity.d.ts +1 -1
- package/dist/types/session/events.d.ts +1139 -0
- package/dist/types/session/events.d.ts.map +1 -0
- package/dist/types/session/events.js +15 -0
- package/dist/types/session/events.js.map +1 -0
- package/dist/types/session/fork.d.ts +45 -0
- package/dist/types/session/fork.d.ts.map +1 -0
- package/dist/types/session/fork.js +15 -0
- package/dist/types/session/fork.js.map +1 -0
- package/dist/types/session/ids.d.ts +1 -1
- package/dist/types/session/ids.d.ts.map +1 -1
- package/dist/types/session/index.d.ts +20 -1
- package/dist/types/session/index.d.ts.map +1 -1
- package/dist/types/session/index.js +22 -4
- package/dist/types/session/index.js.map +1 -1
- package/dist/types/session/lineage.d.ts +15 -0
- package/dist/types/session/lineage.d.ts.map +1 -0
- package/dist/types/session/lineage.js.map +1 -0
- package/dist/types/session/log-cursor.d.ts +57 -0
- package/dist/types/session/log-cursor.d.ts.map +1 -0
- package/dist/types/session/log-cursor.js +34 -0
- package/dist/types/session/log-cursor.js.map +1 -0
- package/dist/types/session/memory-promotion.d.ts +91 -0
- package/dist/types/session/memory-promotion.d.ts.map +1 -0
- package/dist/types/session/memory-promotion.js +39 -0
- package/dist/types/session/memory-promotion.js.map +1 -0
- package/dist/types/session/messages.d.ts +1 -1
- package/dist/types/session/messages.js +1 -1
- package/dist/types/session/prepare-step.d.ts +278 -0
- package/dist/types/session/prepare-step.d.ts.map +1 -0
- package/dist/types/session/prepare-step.js.map +1 -0
- package/dist/types/session/records.d.ts +5597 -0
- package/dist/types/session/records.d.ts.map +1 -0
- package/dist/types/session/records.js +721 -0
- package/dist/types/session/records.js.map +1 -0
- package/dist/types/session/step.d.ts +195 -0
- package/dist/types/session/step.d.ts.map +1 -0
- package/dist/types/session/step.js +26 -0
- package/dist/types/session/step.js.map +1 -0
- package/dist/types/session/stop-reason.d.ts +67 -0
- package/dist/types/session/stop-reason.d.ts.map +1 -0
- package/dist/types/session/stop-reason.js.map +1 -0
- package/dist/types/session/store.d.ts +2 -43
- package/dist/types/session/store.d.ts.map +1 -1
- package/dist/types/session/tool-execution.d.ts +34 -0
- package/dist/types/session/tool-execution.d.ts.map +1 -0
- package/dist/types/session/tool-execution.js +11 -0
- package/dist/types/session/tool-execution.js.map +1 -0
- package/dist/types/session/turn-state.d.ts +74 -0
- package/dist/types/session/turn-state.d.ts.map +1 -0
- package/dist/types/session/turn-state.js +59 -0
- package/dist/types/session/turn-state.js.map +1 -0
- package/dist/types/session/turn.d.ts +215 -0
- package/dist/types/session/turn.d.ts.map +1 -0
- package/dist/types/session/turn.js +44 -0
- package/dist/types/session/turn.js.map +1 -0
- package/dist/types/structured-output/index.d.ts +2 -2
- package/dist/types/structured-output/index.d.ts.map +1 -1
- package/dist/types/summary/deliverable.d.ts +4 -4
- package/dist/types/summary/deliverable.d.ts.map +1 -1
- package/dist/types/task/index.d.ts +8 -4
- package/dist/types/task/index.d.ts.map +1 -1
- package/dist/types/tool/index.d.ts +73 -26
- package/dist/types/tool/index.d.ts.map +1 -1
- package/dist/types/tool/index.js.map +1 -1
- package/dist/types/topic/entity.d.ts +6 -6
- package/dist/types/topic/objective.d.ts +10 -5
- package/dist/types/topic/objective.d.ts.map +1 -1
- package/dist/types/topic/objective.js.map +1 -1
- package/dist/types/topic/state.d.ts +4 -4
- package/dist/types/topic/store.d.ts +1 -1
- package/dist/types/topic/store.js +1 -1
- package/dist/types/workspace/index.d.ts +1 -1
- package/dist/types/workspace/index.d.ts.map +1 -1
- package/dist/types/workspace/index.js +1 -1
- package/dist/types/workspace/index.js.map +1 -1
- package/dist/types/workspace/ref.d.ts +3 -3
- package/dist/types/workspace/shared-session.d.ts +61 -0
- package/dist/types/workspace/shared-session.d.ts.map +1 -0
- package/dist/types/workspace/shared-session.js +2 -0
- package/dist/types/workspace/shared-session.js.map +1 -0
- package/dist/utils/abort.js +4 -4
- package/dist/utils/abort.js.map +1 -1
- package/dist/utils/atomic-write.d.ts +29 -1
- package/dist/utils/atomic-write.d.ts.map +1 -1
- package/dist/utils/atomic-write.js +60 -4
- package/dist/utils/atomic-write.js.map +1 -1
- package/dist/utils/cost.d.ts +3 -3
- package/dist/utils/cost.d.ts.map +1 -1
- package/dist/utils/cost.js +11 -12
- package/dist/utils/cost.js.map +1 -1
- package/dist/utils/env.d.ts +1 -1
- package/dist/utils/env.js +1 -1
- package/dist/utils/id.d.ts +9 -8
- package/dist/utils/id.d.ts.map +1 -1
- package/dist/utils/id.js +20 -13
- package/dist/utils/id.js.map +1 -1
- package/dist/utils/log/create-logger.js +1 -1
- package/dist/utils/log/create-logger.js.map +1 -1
- package/dist/utils/log/types.js +1 -1
- package/dist/utils/log/types.js.map +1 -1
- package/dist/utils/shell-compress.js +2 -2
- package/dist/utils/shell-compress.js.map +1 -1
- package/dist/utils/uuidv7.d.ts +33 -0
- package/dist/utils/uuidv7.d.ts.map +1 -0
- package/dist/utils/uuidv7.js +70 -0
- package/dist/utils/uuidv7.js.map +1 -0
- package/dist/vault/instrumentation.d.ts +5 -2
- package/dist/vault/instrumentation.d.ts.map +1 -1
- package/dist/vault/instrumentation.js +12 -6
- package/dist/vault/instrumentation.js.map +1 -1
- package/package.json +1 -1
- package/src/advisory/budget.ts +3 -3
- package/src/advisory/context.ts +9 -9
- package/src/advisory/evaluator.ts +2 -2
- package/src/advisory/parse.ts +1 -1
- package/src/agents/AbstractAgent.ts +74 -50
- package/src/agents/PipelineAgent.ts +91 -26
- package/src/agents/ReactiveAgent.ts +35 -29
- package/src/agents/RouterAgent.ts +32 -44
- package/src/agents/SupervisorAgent.ts +55 -41
- package/src/agents/budget.ts +73 -16
- package/src/agents/defineAgent.ts +7 -3
- package/src/agents/handle.ts +17 -19
- package/src/agents/lock.ts +4 -4
- package/src/agents/runAgent.ts +96 -38
- package/src/agents/storage.ts +36 -0
- package/src/authorization/command-line.ts +1 -1
- package/src/authorization/gate.ts +1 -1
- package/src/authorization/permission-presets.ts +4 -4
- package/src/bridge/a2a/client.ts +2 -2
- package/src/bridge/a2a/context.ts +46 -0
- package/src/bridge/a2a/index.ts +12 -5
- package/src/bridge/a2a/mapper.ts +48 -38
- package/src/bridge/a2a/task.ts +91 -37
- package/src/bridge/acp/permission.ts +2 -2
- package/src/bridge/acp/server.ts +45 -11
- package/src/bridge/acp/update.ts +9 -9
- package/src/bridge/external-session.ts +82 -0
- package/src/bridge/sse/index.ts +1 -1
- package/src/bridge/sse/mapper.ts +116 -145
- package/src/bus/breaker.ts +30 -29
- package/src/bus/index.ts +7 -7
- package/src/bus/lock.ts +7 -7
- package/src/bus/ownership.ts +8 -8
- package/src/compaction/consolidation.ts +61 -15
- package/src/compaction/context-window.ts +4 -4
- package/src/compaction/index.ts +2 -2
- package/src/compaction/manager.ts +4 -4
- package/src/compaction/manual.ts +5 -5
- package/src/compaction/plan.ts +8 -8
- package/src/compaction/reducer.ts +8 -8
- package/src/compaction/retention.ts +2 -2
- package/src/compaction/salience/bm25.ts +2 -2
- package/src/compaction/salience/goal.ts +3 -3
- package/src/compaction/salience/minhash.ts +1 -1
- package/src/compaction/salience/score.ts +3 -3
- package/src/compaction/salience/tokenize.ts +1 -1
- package/src/compaction/verifier.ts +7 -7
- package/src/compaction/wire.ts +1 -1
- package/src/config/registry.ts +4 -4
- package/src/config/runtime.ts +3 -3
- package/src/connector/http-operation.ts +1 -1
- package/src/connector/mcp/adapter.ts +1 -1
- package/src/connector/mcp/client.ts +1 -1
- package/src/connector/mcp/discovery.ts +2 -2
- package/src/connector/mcp/policy.ts +1 -1
- package/src/connector/mcp/prompt-adapter.ts +3 -3
- package/src/constants/a2a/index.ts +10 -3
- package/src/constants/continuation.ts +1 -1
- package/src/constants/index.ts +0 -1
- package/src/constants/limits.ts +2 -2
- package/src/constants/telemetry/index.ts +15 -12
- package/src/constants/tools/index.ts +2 -2
- package/src/contracts/api.ts +11 -202
- package/src/contracts/index.ts +8 -15
- package/src/contracts/schemas.ts +6 -39
- package/src/contracts/session/api.ts +150 -0
- package/src/contracts/session/index.ts +29 -0
- package/src/contracts/session/schemas.ts +60 -0
- package/src/contracts/session/turn-status.ts +83 -0
- package/src/contracts/session/turn.ts +67 -0
- package/src/directory/derive-supervisor.ts +2 -2
- package/src/directory/derive.ts +4 -4
- package/src/directory/index.ts +2 -2
- package/src/directory/load.ts +2 -2
- package/src/directory/types.ts +2 -2
- package/src/eval/experiment.ts +23 -23
- package/src/eval/from-turn.ts +50 -0
- package/src/eval/harness-verification.ts +7 -7
- package/src/eval/index.ts +2 -2
- package/src/eval/judge.ts +10 -10
- package/src/eval/scorers.ts +23 -23
- package/src/eval/types.ts +12 -12
- package/src/eval/uncertainty.ts +2 -2
- package/src/execution/code-runtime/types.ts +4 -4
- package/src/execution/code-runtime/worker.ts +1 -1
- package/src/invariants/index.ts +2 -2
- package/src/manager/agent/child-session.ts +120 -0
- package/src/manager/agent/lifecycle.ts +422 -102
- package/src/manager/index.ts +1 -2
- package/src/manager/plan/lifecycle.ts +16 -10
- package/src/manager/resident/consumption.ts +8 -6
- package/src/manager/resident/evidence-recall.ts +14 -14
- package/src/manager/resident/host.ts +2 -2
- package/src/manager/resident/learning-cycle.ts +5 -3
- package/src/manager/resident/learning-observation.ts +9 -4
- package/src/manager/resident/learning-store.ts +46 -16
- package/src/manager/resident/tool-evidence.ts +38 -31
- package/src/manager/session/turn-recorder.ts +1291 -0
- package/src/plugin/lifecycle.ts +20 -13
- package/src/plugin/shell-hook.ts +64 -25
- package/src/pricing/index.ts +5 -5
- package/src/pricing/rates.source.json +5 -5
- package/src/probe/context.ts +5 -3
- package/src/probe/registry.ts +1 -1
- package/src/prompt/coding-agent-doctrine.ts +1 -1
- package/src/prompt/contributions.ts +28 -6
- package/src/prompt/resident-learning.ts +2 -2
- package/src/provider/collect-chat-completion.ts +3 -3
- package/src/provider/conformance.ts +21 -6
- package/src/provider/errors.ts +2 -2
- package/src/provider/fallback.ts +8 -8
- package/src/provider/idle-timeout.ts +4 -4
- package/src/provider/instrumentation.ts +14 -7
- package/src/provider/mock.ts +1 -1
- package/src/provider/retry.ts +7 -7
- package/src/provider/stream-text.ts +1 -1
- package/src/provider/thinking-support.ts +2 -2
- package/src/provider/token-budget.ts +2 -2
- package/src/public-runtime.ts +213 -141
- package/src/public-tools.ts +14 -7
- package/src/public-types.ts +71 -59
- package/src/rag/embedding.ts +1 -1
- package/src/read-model/index.ts +2 -2
- package/src/read-model/registry.ts +11 -11
- package/src/read-model/session-status.ts +87 -0
- package/src/registry/command/kernel-commands.ts +10 -10
- package/src/registry/tool/dialect.ts +1 -1
- package/src/registry/tool/execute.ts +20 -7
- package/src/registry/tool/portable.ts +1 -1
- package/src/registry/tool/presentation.ts +1 -1
- package/src/registry/tool/schema.ts +1 -1
- package/src/registry/tool/screen.ts +3 -3
- package/src/runtime/bidi/index.ts +2 -2
- package/src/runtime/bidi/session.ts +45 -34
- package/src/runtime/jobs/awaited-jobs.ts +13 -13
- package/src/runtime/jobs/registry.ts +11 -11
- package/src/runtime/query/abandon-turn.ts +110 -0
- package/src/runtime/query/approval-policy.ts +13 -13
- package/src/runtime/query/callback-inference.ts +16 -10
- package/src/runtime/query/cancelled-before-start.ts +96 -79
- package/src/runtime/query/checkpoint.ts +519 -420
- package/src/runtime/query/compact-session.ts +92 -0
- package/src/runtime/query/context.ts +80 -136
- package/src/runtime/query/events.ts +159 -126
- package/src/runtime/query/executor/tool-call-admission.ts +6 -5
- package/src/runtime/query/executor.ts +206 -111
- package/src/runtime/query/file-evidence-seed.ts +2 -2
- package/src/runtime/query/finalize-turn.ts +209 -0
- package/src/runtime/query/fork/list.ts +20 -0
- package/src/runtime/query/fork/mutate.ts +82 -0
- package/src/runtime/query/fork/prepare.ts +92 -0
- package/src/runtime/query/guard.ts +22 -22
- package/src/runtime/query/guardrail-presets.ts +12 -12
- package/src/runtime/query/guardrails.ts +11 -11
- package/src/runtime/query/index.ts +1607 -1533
- package/src/runtime/query/iteration/index.ts +304 -253
- package/src/runtime/query/iteration/outstanding-work.ts +65 -65
- package/src/runtime/query/iteration/phases/advisory.ts +16 -16
- package/src/runtime/query/iteration/phases/checkpoint.ts +26 -10
- package/src/runtime/query/iteration/phases/compaction.ts +74 -72
- package/src/runtime/query/iteration/phases/context.ts +57 -60
- package/src/runtime/query/iteration/phases/plan.ts +9 -6
- package/src/runtime/query/iteration/phases/tool-review.ts +141 -27
- package/src/runtime/query/iteration/phases/working-memory.ts +57 -22
- package/src/runtime/query/iteration/step-context.ts +17 -0
- package/src/runtime/query/iteration/step-shaping.ts +21 -24
- package/src/runtime/query/iteration/stream-turn.ts +36 -32
- package/src/runtime/query/plugin-hooks.ts +1 -1
- package/src/runtime/query/prepare-turn.ts +932 -0
- package/src/runtime/query/project-instructions.ts +5 -4
- package/src/runtime/query/prompt-cache.ts +1 -1
- package/src/runtime/query/prompt.ts +5 -5
- package/src/runtime/query/question-park.ts +7 -7
- package/src/runtime/query/release-turn.ts +157 -0
- package/src/runtime/query/repeat-call.ts +7 -7
- package/src/runtime/query/result.ts +123 -131
- package/src/runtime/query/resume-pending.ts +101 -44
- package/src/runtime/query/resume-session.ts +153 -0
- package/src/runtime/query/review-policy.ts +147 -19
- package/src/runtime/query/sandbox-lifecycle.ts +5 -5
- package/src/runtime/query/session-storage.ts +302 -0
- package/src/runtime/query/steering.ts +17 -4
- package/src/runtime/query/token-budget.ts +59 -93
- package/src/runtime/query/tool-call-budget.ts +14 -14
- package/src/runtime/query/tool-executions.ts +77 -0
- package/src/runtime/query/tool-grants.ts +3 -3
- package/src/runtime/query/tool-output-budget.ts +4 -4
- package/src/runtime/query/tool-pause.ts +8 -6
- package/src/runtime/query/tooling.ts +22 -14
- package/src/runtime/query/turn-state.ts +153 -0
- package/src/sandbox/isolation.ts +2 -2
- package/src/sandbox/provider/local.ts +8 -8
- package/src/scheduler/completion-inbox.ts +36 -36
- package/src/scheduler/delegating.ts +27 -13
- package/src/scheduler/local.ts +49 -21
- package/src/session/events/index.ts +10 -14
- package/src/session/handoff/broadcast.ts +7 -7
- package/src/session/handoff/events.ts +1 -1
- package/src/session/handoff/index.ts +1 -1
- package/src/session/handoff/single.ts +21 -21
- package/src/session/handoff/version.ts +11 -7
- package/src/session/home.ts +66 -0
- package/src/session/index.ts +1 -0
- package/src/session/log-hash.ts +115 -0
- package/src/session/messages.ts +39 -0
- package/src/session/paths.ts +449 -0
- package/src/session/retention/archive.ts +13 -5
- package/src/session/status/derive.ts +21 -21
- package/src/session/workspace/git-worktree.ts +31 -2
- package/src/session/workspace/index.ts +5 -8
- package/src/session/workspace/shared-session.ts +354 -0
- package/src/session-query/index.ts +152 -0
- package/src/skills/registry.ts +1 -1
- package/src/store/activity/memory.ts +5 -5
- package/src/store/attachment/index.ts +5 -5
- package/src/store/budget/disk.ts +243 -0
- package/src/store/budget/index.ts +24 -0
- package/src/store/budget/ledger.ts +836 -0
- package/src/store/budget/memory.ts +39 -0
- package/src/store/checkpoint/contract.ts +225 -0
- package/src/store/checkpoint/disk.ts +209 -0
- package/src/store/checkpoint/index.ts +22 -0
- package/src/store/checkpoint/memory.ts +112 -0
- package/src/store/checkpoint/prune.ts +93 -0
- package/src/store/config/index.ts +1 -1
- package/src/store/evidence/disk.ts +185 -81
- package/src/store/evidence/index-page.ts +67 -140
- package/src/store/evidence/source-text.ts +23 -28
- package/src/store/evidence/types.ts +51 -41
- package/src/store/feedback/conformance.ts +37 -35
- package/src/store/feedback/disk.ts +61 -63
- package/src/store/feedback/index.ts +1 -1
- package/src/store/feedback/memory.ts +0 -0
- package/src/store/feedback/types.ts +14 -13
- package/src/store/index.ts +24 -28
- package/src/store/memory/digest.ts +35 -0
- package/src/store/memory/disk.ts +66 -20
- package/src/store/memory/index-file.ts +121 -0
- package/src/store/memory/index.ts +4 -2
- package/src/store/memory/links.ts +37 -0
- package/src/store/memory/markdown-format.ts +276 -0
- package/src/store/memory/markdown.ts +741 -0
- package/src/store/memory/memory.ts +39 -17
- package/src/store/memory/naming.ts +195 -0
- package/src/store/memory/origin.ts +35 -0
- package/src/store/session/disk.ts +27 -200
- package/src/store/session/index.ts +5 -9
- package/src/store/session/memory.ts +1 -78
- package/src/store/session-claim.ts +101 -0
- package/src/store/session-index/fts.ts +215 -0
- package/src/store/session-index/index.ts +253 -0
- package/src/store/session-index/rebuild.ts +869 -0
- package/src/store/session-index/refs.ts +164 -0
- package/src/store/session-index/scan.ts +273 -0
- package/src/store/session-index/sqlite.ts +772 -0
- package/src/store/session-log/chain.ts +314 -0
- package/src/store/session-log/conformance.ts +487 -0
- package/src/store/session-log/core.ts +809 -0
- package/src/store/session-log/disk.ts +217 -0
- package/src/store/session-log/fold.ts +368 -0
- package/src/store/session-log/heal.ts +44 -0
- package/src/store/session-log/held-leases.ts +103 -0
- package/src/store/session-log/index.ts +87 -0
- package/src/store/session-log/lease.ts +354 -0
- package/src/store/session-log/memory.ts +111 -0
- package/src/store/session-log/spill.ts +311 -0
- package/src/store/task/context.ts +33 -0
- package/src/store/task/disk.ts +122 -141
- package/src/store/task/memory.ts +14 -8
- package/src/store/topic/index.ts +2 -2
- package/src/store/topic/objective.ts +12 -3
- package/src/store/topic/state.ts +1 -1
- package/src/streaming/coalesce.ts +8 -7
- package/src/telemetry/attributes.ts +10 -9
- package/src/telemetry/metrics.ts +6 -6
- package/src/telemetry/runtime-accessors.ts +1 -1
- package/src/test-support/ids.ts +5 -6
- package/src/testing.ts +11 -16
- package/src/tools/advisory/index.ts +1 -1
- package/src/tools/builtins/bash.ts +43 -5
- package/src/tools/builtins/content-fingerprint.ts +2 -2
- package/src/tools/builtins/edit-apply.ts +1 -1
- package/src/tools/builtins/edit.ts +3 -0
- package/src/tools/builtins/glob.ts +3 -0
- package/src/tools/builtins/grep.ts +3 -0
- package/src/tools/builtins/job.ts +5 -5
- package/src/tools/builtins/ls.ts +3 -0
- package/src/tools/builtins/lsp.ts +5 -2
- package/src/tools/builtins/read-file.ts +3 -0
- package/src/tools/builtins/run-code.ts +11 -11
- package/src/tools/builtins/skill.ts +3 -3
- package/src/tools/builtins/wait-for-job-bounds.ts +6 -6
- package/src/tools/builtins/wait-for-job.ts +3 -3
- package/src/tools/builtins/web-guidance.ts +2 -2
- package/src/tools/builtins/web.ts +3 -3
- package/src/tools/builtins/write-file.ts +3 -0
- package/src/tools/coordinator/agent.ts +8 -8
- package/src/tools/coordinator/ask-user-question.ts +16 -14
- package/src/tools/coordinator/index.ts +64 -54
- package/src/tools/coordinator/outcome.ts +7 -7
- package/src/tools/coordinator/plan-dependencies.ts +1 -1
- package/src/tools/coordinator/wait-with-idle-bound.ts +6 -6
- package/src/tools/defineTool.ts +9 -1
- package/src/tools/env-scrub.ts +1 -1
- package/src/tools/goal/index.ts +16 -12
- package/src/tools/memory/fields.ts +26 -0
- package/src/tools/memory/read.ts +75 -8
- package/src/tools/memory/resolve.ts +37 -0
- package/src/tools/memory/save.ts +54 -18
- package/src/tools/memory/search.ts +9 -5
- package/src/tools/memory/update.ts +43 -7
- package/src/tools/paths.ts +87 -27
- package/src/tools/posix-path.ts +1 -1
- package/src/tools/resident-history.ts +1 -1
- package/src/tools/resident-tool-evidence.ts +1 -1
- package/src/tools/task/create.ts +7 -3
- package/src/tools/task/index.ts +20 -4
- package/src/tools/task/list.ts +12 -6
- package/src/turn/LimitChecker.ts +99 -0
- package/src/turn/command-gate.ts +294 -0
- package/src/turn/drain.ts +324 -0
- package/src/turn/evidence-query.ts +333 -0
- package/src/turn/evidence-recall.ts +860 -0
- package/src/turn/index.ts +38 -0
- package/src/turn/json-claim-verifier.ts +298 -0
- package/src/turn/memory-promoter.ts +160 -0
- package/src/turn/memory-recall.ts +285 -0
- package/src/turn/reporter.ts +469 -0
- package/src/types/activity/index.ts +2 -2
- package/src/types/advisory/config.ts +7 -7
- package/src/types/agent/base.ts +74 -44
- package/src/types/agent/core.ts +10 -10
- package/src/types/agent/delegate.ts +2 -2
- package/src/types/agent/factory.ts +8 -4
- package/src/types/agent/manager.ts +6 -6
- package/src/types/agent/pipeline.ts +5 -4
- package/src/types/agent/reactive.ts +11 -10
- package/src/types/agent/router.ts +1 -1
- package/src/types/agent/scheduler.ts +28 -11
- package/src/types/agent/supervisor.ts +13 -13
- package/src/types/agent/task.ts +53 -12
- package/src/types/agent/working-memory.ts +6 -4
- package/src/types/bidi/index.ts +31 -12
- package/src/types/bus/index.ts +32 -26
- package/src/types/code-navigation/index.ts +1 -1
- package/src/types/common/index.ts +12 -26
- package/src/types/connector/core.ts +2 -2
- package/src/types/connector/definition.ts +1 -1
- package/src/types/connector/mcp.ts +1 -1
- package/src/types/errors/catalog.ts +4 -4
- package/src/types/errors/index.ts +5 -5
- package/src/types/guardrail/index.ts +12 -10
- package/src/types/hitl/index.ts +81 -125
- package/src/types/hitl/policy.ts +8 -6
- package/src/types/ids/brand.ts +10 -2
- package/src/types/ids/index.ts +10 -4
- package/src/types/memory/index.ts +53 -0
- package/src/types/message/index.ts +4 -4
- package/src/types/plan/index.ts +5 -3
- package/src/types/plugin/index.ts +41 -24
- package/src/types/probe/event-kind.ts +3 -3
- package/src/types/probe/registry.ts +3 -2
- package/src/types/project/entity.ts +3 -3
- package/src/types/provider/config.ts +3 -3
- package/src/types/provider/error.ts +1 -1
- package/src/types/provider/errors.ts +3 -3
- package/src/types/provider/interface.ts +5 -5
- package/src/types/provider/model.ts +26 -2
- package/src/types/router/task-router.ts +1 -1
- package/src/types/sandbox/index.ts +12 -12
- package/src/types/session/answer-review.ts +85 -0
- package/src/types/session/audit.ts +167 -0
- package/src/types/session/cancel-cause.ts +60 -0
- package/src/types/session/checkpoint.ts +167 -0
- package/src/types/session/config.ts +212 -0
- package/src/types/session/derive-status.ts +61 -0
- package/src/types/session/durable.ts +150 -0
- package/src/types/session/entity.ts +1 -1
- package/src/types/session/events.ts +1187 -0
- package/src/types/session/fork.ts +52 -0
- package/src/types/session/ids.ts +1 -1
- package/src/types/session/index.ts +24 -4
- package/src/types/session/lineage.ts +15 -0
- package/src/types/session/log-cursor.ts +69 -0
- package/src/types/session/memory-promotion.ts +116 -0
- package/src/types/session/messages.ts +1 -1
- package/src/types/session/prepare-step.ts +299 -0
- package/src/types/session/records.ts +931 -0
- package/src/types/session/step.ts +214 -0
- package/src/types/session/stop-reason.ts +83 -0
- package/src/types/session/store.ts +5 -52
- package/src/types/session/tool-execution.ts +32 -0
- package/src/types/session/turn-state.ts +136 -0
- package/src/types/session/turn.ts +289 -0
- package/src/types/structured-output/index.ts +4 -4
- package/src/types/summary/deliverable.ts +4 -4
- package/src/types/task/index.ts +8 -4
- package/src/types/tool/index.ts +74 -27
- package/src/types/topic/entity.ts +6 -6
- package/src/types/topic/objective.ts +7 -5
- package/src/types/topic/state.ts +4 -4
- package/src/types/topic/store.ts +1 -1
- package/src/types/workspace/index.ts +8 -8
- package/src/types/workspace/ref.ts +3 -3
- package/src/types/workspace/shared-session.ts +65 -0
- package/src/utils/abort.ts +4 -4
- package/src/utils/atomic-write.ts +67 -4
- package/src/utils/cost.ts +11 -12
- package/src/utils/env.ts +1 -1
- package/src/utils/id.ts +25 -18
- package/src/utils/log/attributes.ts +2 -2
- package/src/utils/log/create-logger.ts +1 -1
- package/src/utils/log/types.ts +1 -1
- package/src/utils/shell-compress.ts +2 -2
- package/src/utils/uuidv7.ts +107 -0
- package/src/vault/instrumentation.ts +21 -8
- package/dist/constants/emergency.d.ts +0 -4
- package/dist/constants/emergency.d.ts.map +0 -1
- package/dist/constants/emergency.js +0 -4
- package/dist/constants/emergency.js.map +0 -1
- package/dist/contracts/run-status.d.ts +0 -17
- package/dist/contracts/run-status.d.ts.map +0 -1
- package/dist/contracts/run-status.js +0 -41
- package/dist/contracts/run-status.js.map +0 -1
- package/dist/eval/from-run.d.ts +0 -30
- package/dist/eval/from-run.d.ts.map +0 -1
- package/dist/eval/from-run.js +0 -46
- package/dist/eval/from-run.js.map +0 -1
- package/dist/manager/run/emergency.d.ts +0 -19
- package/dist/manager/run/emergency.d.ts.map +0 -1
- package/dist/manager/run/emergency.js +0 -122
- package/dist/manager/run/emergency.js.map +0 -1
- package/dist/manager/run/persistence.d.ts +0 -312
- package/dist/manager/run/persistence.d.ts.map +0 -1
- package/dist/manager/run/persistence.js +0 -656
- package/dist/manager/run/persistence.js.map +0 -1
- package/dist/read-model/run-status.d.ts +0 -43
- package/dist/read-model/run-status.d.ts.map +0 -1
- package/dist/read-model/run-status.js +0 -89
- package/dist/read-model/run-status.js.map +0 -1
- package/dist/run/LimitChecker.d.ts +0 -30
- package/dist/run/LimitChecker.d.ts.map +0 -1
- package/dist/run/LimitChecker.js +0 -57
- package/dist/run/LimitChecker.js.map +0 -1
- package/dist/run/command-gate.d.ts +0 -107
- package/dist/run/command-gate.d.ts.map +0 -1
- package/dist/run/command-gate.js +0 -221
- package/dist/run/command-gate.js.map +0 -1
- package/dist/run/drain.d.ts +0 -204
- package/dist/run/drain.d.ts.map +0 -1
- package/dist/run/drain.js +0 -238
- package/dist/run/drain.js.map +0 -1
- package/dist/run/evidence-query.d.ts +0 -41
- package/dist/run/evidence-query.d.ts.map +0 -1
- package/dist/run/evidence-query.js +0 -270
- package/dist/run/evidence-query.js.map +0 -1
- package/dist/run/evidence-recall.d.ts +0 -99
- package/dist/run/evidence-recall.d.ts.map +0 -1
- package/dist/run/evidence-recall.js +0 -633
- package/dist/run/evidence-recall.js.map +0 -1
- package/dist/run/index.d.ts +0 -19
- package/dist/run/index.d.ts.map +0 -1
- package/dist/run/index.js +0 -11
- package/dist/run/index.js.map +0 -1
- package/dist/run/json-claim-verifier.d.ts +0 -83
- package/dist/run/json-claim-verifier.d.ts.map +0 -1
- package/dist/run/json-claim-verifier.js +0 -200
- package/dist/run/json-claim-verifier.js.map +0 -1
- package/dist/run/memory-promoter.d.ts +0 -38
- package/dist/run/memory-promoter.d.ts.map +0 -1
- package/dist/run/memory-promoter.js +0 -109
- package/dist/run/memory-promoter.js.map +0 -1
- package/dist/run/memory-recall.d.ts +0 -25
- package/dist/run/memory-recall.d.ts.map +0 -1
- package/dist/run/memory-recall.js +0 -228
- package/dist/run/memory-recall.js.map +0 -1
- package/dist/run/preparation-context-error.d.ts.map +0 -1
- package/dist/run/preparation-context-error.js.map +0 -1
- package/dist/run/reporter.d.ts +0 -8
- package/dist/run/reporter.d.ts.map +0 -1
- package/dist/run/reporter.js +0 -420
- package/dist/run/reporter.js.map +0 -1
- package/dist/run/token-budget.d.ts +0 -116
- package/dist/run/token-budget.d.ts.map +0 -1
- package/dist/run/token-budget.js +0 -626
- package/dist/run/token-budget.js.map +0 -1
- package/dist/run/workspace-fingerprint.d.ts.map +0 -1
- package/dist/run/workspace-fingerprint.js.map +0 -1
- package/dist/run-query/index.d.ts +0 -90
- package/dist/run-query/index.d.ts.map +0 -1
- package/dist/run-query/index.js +0 -127
- package/dist/run-query/index.js.map +0 -1
- package/dist/runtime/query/finalize-run.d.ts +0 -55
- package/dist/runtime/query/finalize-run.d.ts.map +0 -1
- package/dist/runtime/query/finalize-run.js +0 -113
- package/dist/runtime/query/finalize-run.js.map +0 -1
- package/dist/runtime/query/prepare-run.d.ts +0 -94
- package/dist/runtime/query/prepare-run.d.ts.map +0 -1
- package/dist/runtime/query/prepare-run.js +0 -589
- package/dist/runtime/query/prepare-run.js.map +0 -1
- package/dist/runtime/query/release-run.d.ts +0 -56
- package/dist/runtime/query/release-run.d.ts.map +0 -1
- package/dist/runtime/query/release-run.js +0 -101
- package/dist/runtime/query/release-run.js.map +0 -1
- package/dist/runtime/query/replay/list.d.ts +0 -40
- package/dist/runtime/query/replay/list.d.ts.map +0 -1
- package/dist/runtime/query/replay/list.js +0 -38
- package/dist/runtime/query/replay/list.js.map +0 -1
- package/dist/runtime/query/replay/mutate.d.ts +0 -17
- package/dist/runtime/query/replay/mutate.d.ts.map +0 -1
- package/dist/runtime/query/replay/mutate.js +0 -69
- package/dist/runtime/query/replay/mutate.js.map +0 -1
- package/dist/runtime/query/replay/prepare.d.ts +0 -66
- package/dist/runtime/query/replay/prepare.d.ts.map +0 -1
- package/dist/runtime/query/replay/prepare.js +0 -81
- package/dist/runtime/query/replay/prepare.js.map +0 -1
- package/dist/runtime/query/resume-run.d.ts +0 -103
- package/dist/runtime/query/resume-run.d.ts.map +0 -1
- package/dist/runtime/query/resume-run.js +0 -105
- package/dist/runtime/query/resume-run.js.map +0 -1
- package/dist/runtime/query/run-state.d.ts +0 -57
- package/dist/runtime/query/run-state.d.ts.map +0 -1
- package/dist/runtime/query/run-state.js +0 -96
- package/dist/runtime/query/run-state.js.map +0 -1
- package/dist/session/workspace/path-builder.d.ts +0 -50
- package/dist/session/workspace/path-builder.d.ts.map +0 -1
- package/dist/session/workspace/path-builder.js +0 -51
- package/dist/session/workspace/path-builder.js.map +0 -1
- package/dist/session/workspace/shared-run.d.ts +0 -112
- package/dist/session/workspace/shared-run.d.ts.map +0 -1
- package/dist/session/workspace/shared-run.js +0 -290
- package/dist/session/workspace/shared-run.js.map +0 -1
- package/dist/store/evidence/compaction-archive.d.ts +0 -109
- package/dist/store/evidence/compaction-archive.d.ts.map +0 -1
- package/dist/store/evidence/compaction-archive.js +0 -125
- package/dist/store/evidence/compaction-archive.js.map +0 -1
- package/dist/store/evidence/linked.d.ts +0 -9
- package/dist/store/evidence/linked.d.ts.map +0 -1
- package/dist/store/evidence/linked.js +0 -314
- package/dist/store/evidence/linked.js.map +0 -1
- package/dist/store/evidence/record-chain.d.ts +0 -42
- package/dist/store/evidence/record-chain.d.ts.map +0 -1
- package/dist/store/evidence/record-chain.js +0 -111
- package/dist/store/evidence/record-chain.js.map +0 -1
- package/dist/store/run/checkpoint-disk.d.ts +0 -98
- package/dist/store/run/checkpoint-disk.d.ts.map +0 -1
- package/dist/store/run/checkpoint-disk.js +0 -190
- package/dist/store/run/checkpoint-disk.js.map +0 -1
- package/dist/store/run/checkpoint-memory.d.ts +0 -51
- package/dist/store/run/checkpoint-memory.d.ts.map +0 -1
- package/dist/store/run/checkpoint-memory.js +0 -178
- package/dist/store/run/checkpoint-memory.js.map +0 -1
- package/dist/store/run/claim-disk.d.ts +0 -130
- package/dist/store/run/claim-disk.d.ts.map +0 -1
- package/dist/store/run/claim-disk.js +0 -570
- package/dist/store/run/claim-disk.js.map +0 -1
- package/dist/store/run/conformance.d.ts +0 -159
- package/dist/store/run/conformance.d.ts.map +0 -1
- package/dist/store/run/conformance.js +0 -466
- package/dist/store/run/conformance.js.map +0 -1
- package/dist/store/run/disk.d.ts +0 -189
- package/dist/store/run/disk.d.ts.map +0 -1
- package/dist/store/run/disk.js +0 -804
- package/dist/store/run/disk.js.map +0 -1
- package/dist/store/run/listing.d.ts +0 -118
- package/dist/store/run/listing.d.ts.map +0 -1
- package/dist/store/run/listing.js +0 -333
- package/dist/store/run/listing.js.map +0 -1
- package/dist/store/run/memory.d.ts +0 -55
- package/dist/store/run/memory.d.ts.map +0 -1
- package/dist/store/run/memory.js +0 -176
- package/dist/store/run/memory.js.map +0 -1
- package/dist/store/run/token-budget-disk.d.ts +0 -37
- package/dist/store/run/token-budget-disk.d.ts.map +0 -1
- package/dist/store/run/token-budget-disk.js +0 -211
- package/dist/store/run/token-budget-disk.js.map +0 -1
- package/dist/store/run/tool-executions.d.ts +0 -13
- package/dist/store/run/tool-executions.d.ts.map +0 -1
- package/dist/store/run/tool-executions.js +0 -99
- package/dist/store/run/tool-executions.js.map +0 -1
- package/dist/store/session/sqlite.d.ts +0 -57
- package/dist/store/session/sqlite.d.ts.map +0 -1
- package/dist/store/session/sqlite.js +0 -430
- package/dist/store/session/sqlite.js.map +0 -1
- package/dist/types/run/answer-review.d.ts +0 -79
- package/dist/types/run/answer-review.d.ts.map +0 -1
- package/dist/types/run/answer-review.js.map +0 -1
- package/dist/types/run/audit.d.ts +0 -150
- package/dist/types/run/audit.d.ts.map +0 -1
- package/dist/types/run/audit.js +0 -39
- package/dist/types/run/audit.js.map +0 -1
- package/dist/types/run/cancel-cause.d.ts +0 -49
- package/dist/types/run/cancel-cause.d.ts.map +0 -1
- package/dist/types/run/cancel-cause.js +0 -39
- package/dist/types/run/cancel-cause.js.map +0 -1
- package/dist/types/run/checkpoint-store.d.ts +0 -511
- package/dist/types/run/checkpoint-store.d.ts.map +0 -1
- package/dist/types/run/checkpoint-store.js +0 -12
- package/dist/types/run/checkpoint-store.js.map +0 -1
- package/dist/types/run/config.d.ts +0 -207
- package/dist/types/run/config.d.ts.map +0 -1
- package/dist/types/run/config.js.map +0 -1
- package/dist/types/run/derive-status.d.ts +0 -29
- package/dist/types/run/derive-status.d.ts.map +0 -1
- package/dist/types/run/derive-status.js +0 -49
- package/dist/types/run/derive-status.js.map +0 -1
- package/dist/types/run/emergency.d.ts +0 -32
- package/dist/types/run/emergency.d.ts.map +0 -1
- package/dist/types/run/emergency.js +0 -6
- package/dist/types/run/emergency.js.map +0 -1
- package/dist/types/run/entity.d.ts +0 -151
- package/dist/types/run/entity.d.ts.map +0 -1
- package/dist/types/run/entity.js +0 -2
- package/dist/types/run/entity.js.map +0 -1
- package/dist/types/run/event-cursor.d.ts +0 -90
- package/dist/types/run/event-cursor.d.ts.map +0 -1
- package/dist/types/run/event-cursor.js +0 -47
- package/dist/types/run/event-cursor.js.map +0 -1
- package/dist/types/run/events.d.ts +0 -1064
- package/dist/types/run/events.d.ts.map +0 -1
- package/dist/types/run/events.js +0 -31
- package/dist/types/run/events.js.map +0 -1
- package/dist/types/run/index.d.ts +0 -24
- package/dist/types/run/index.d.ts.map +0 -1
- package/dist/types/run/index.js +0 -23
- package/dist/types/run/index.js.map +0 -1
- package/dist/types/run/lineage.d.ts +0 -15
- package/dist/types/run/lineage.d.ts.map +0 -1
- package/dist/types/run/lineage.js.map +0 -1
- package/dist/types/run/memory-promotion.d.ts +0 -90
- package/dist/types/run/memory-promotion.d.ts.map +0 -1
- package/dist/types/run/memory-promotion.js +0 -38
- package/dist/types/run/memory-promotion.js.map +0 -1
- package/dist/types/run/metadata.d.ts +0 -47
- package/dist/types/run/metadata.d.ts.map +0 -1
- package/dist/types/run/metadata.js +0 -2
- package/dist/types/run/metadata.js.map +0 -1
- package/dist/types/run/prepare-step.d.ts +0 -260
- package/dist/types/run/prepare-step.d.ts.map +0 -1
- package/dist/types/run/prepare-step.js.map +0 -1
- package/dist/types/run/replay.d.ts +0 -53
- package/dist/types/run/replay.d.ts.map +0 -1
- package/dist/types/run/replay.js +0 -15
- package/dist/types/run/replay.js.map +0 -1
- package/dist/types/run/schema-version.d.ts +0 -19
- package/dist/types/run/schema-version.d.ts.map +0 -1
- package/dist/types/run/schema-version.js +0 -18
- package/dist/types/run/schema-version.js.map +0 -1
- package/dist/types/run/state.d.ts +0 -109
- package/dist/types/run/state.d.ts.map +0 -1
- package/dist/types/run/state.js +0 -109
- package/dist/types/run/state.js.map +0 -1
- package/dist/types/run/status.d.ts +0 -26
- package/dist/types/run/status.d.ts.map +0 -1
- package/dist/types/run/status.js +0 -2
- package/dist/types/run/status.js.map +0 -1
- package/dist/types/run/step.d.ts +0 -198
- package/dist/types/run/step.d.ts.map +0 -1
- package/dist/types/run/step.js +0 -26
- package/dist/types/run/step.js.map +0 -1
- package/dist/types/run/stop-reason.d.ts +0 -67
- package/dist/types/run/stop-reason.d.ts.map +0 -1
- package/dist/types/run/stop-reason.js.map +0 -1
- package/dist/types/run/store.d.ts +0 -300
- package/dist/types/run/store.d.ts.map +0 -1
- package/dist/types/run/store.js +0 -2
- package/dist/types/run/store.js.map +0 -1
- package/dist/types/run/subsession-events.d.ts +0 -64
- package/dist/types/run/subsession-events.d.ts.map +0 -1
- package/dist/types/run/subsession-events.js +0 -2
- package/dist/types/run/subsession-events.js.map +0 -1
- package/dist/types/run/token-budget-store.d.ts +0 -29
- package/dist/types/run/token-budget-store.d.ts.map +0 -1
- package/dist/types/run/token-budget-store.js +0 -25
- package/dist/types/run/token-budget-store.js.map +0 -1
- package/dist/types/workspace/shared-run.d.ts +0 -61
- package/dist/types/workspace/shared-run.d.ts.map +0 -1
- package/dist/types/workspace/shared-run.js +0 -2
- package/dist/types/workspace/shared-run.js.map +0 -1
- package/src/constants/emergency.ts +0 -3
- package/src/contracts/run-status.ts +0 -43
- package/src/eval/from-run.ts +0 -48
- package/src/manager/run/emergency.ts +0 -148
- package/src/manager/run/persistence.ts +0 -746
- package/src/read-model/run-status.ts +0 -127
- package/src/run/LimitChecker.ts +0 -99
- package/src/run/command-gate.ts +0 -294
- package/src/run/drain.ts +0 -403
- package/src/run/evidence-query.ts +0 -333
- package/src/run/evidence-recall.ts +0 -854
- package/src/run/index.ts +0 -42
- package/src/run/json-claim-verifier.ts +0 -298
- package/src/run/memory-promoter.ts +0 -147
- package/src/run/memory-recall.ts +0 -254
- package/src/run/reporter.ts +0 -469
- package/src/run/token-budget.ts +0 -733
- package/src/run-query/index.ts +0 -177
- package/src/runtime/query/finalize-run.ts +0 -192
- package/src/runtime/query/prepare-run.ts +0 -718
- package/src/runtime/query/release-run.ts +0 -168
- package/src/runtime/query/replay/list.ts +0 -66
- package/src/runtime/query/replay/mutate.ts +0 -82
- package/src/runtime/query/replay/prepare.ts +0 -147
- package/src/runtime/query/resume-run.ts +0 -202
- package/src/runtime/query/run-state.ts +0 -138
- package/src/session/workspace/path-builder.ts +0 -72
- package/src/session/workspace/shared-run.ts +0 -354
- package/src/store/evidence/compaction-archive.ts +0 -139
- package/src/store/evidence/linked.ts +0 -365
- package/src/store/evidence/record-chain.ts +0 -108
- package/src/store/run/checkpoint-disk.ts +0 -264
- package/src/store/run/checkpoint-memory.ts +0 -216
- package/src/store/run/claim-disk.ts +0 -638
- package/src/store/run/conformance.ts +0 -728
- package/src/store/run/disk.ts +0 -911
- package/src/store/run/listing.ts +0 -422
- package/src/store/run/memory.ts +0 -204
- package/src/store/run/token-budget-disk.ts +0 -250
- package/src/store/run/tool-executions.ts +0 -112
- package/src/store/session/sqlite.ts +0 -584
- package/src/types/run/answer-review.ts +0 -84
- package/src/types/run/audit.ts +0 -164
- package/src/types/run/cancel-cause.ts +0 -60
- package/src/types/run/checkpoint-store.ts +0 -545
- package/src/types/run/config.ts +0 -221
- package/src/types/run/derive-status.ts +0 -62
- package/src/types/run/emergency.ts +0 -28
- package/src/types/run/entity.ts +0 -161
- package/src/types/run/event-cursor.ts +0 -118
- package/src/types/run/events.ts +0 -1146
- package/src/types/run/index.ts +0 -32
- package/src/types/run/lineage.ts +0 -15
- package/src/types/run/memory-promotion.ts +0 -112
- package/src/types/run/metadata.ts +0 -51
- package/src/types/run/prepare-step.ts +0 -281
- package/src/types/run/replay.ts +0 -61
- package/src/types/run/schema-version.ts +0 -19
- package/src/types/run/state.ts +0 -206
- package/src/types/run/status.ts +0 -33
- package/src/types/run/step.ts +0 -217
- package/src/types/run/stop-reason.ts +0 -83
- package/src/types/run/store.ts +0 -325
- package/src/types/run/subsession-events.ts +0 -71
- package/src/types/run/token-budget-store.ts +0 -54
- package/src/types/workspace/shared-run.ts +0 -65
- /package/dist/{run → turn}/preparation-context-error.d.ts +0 -0
- /package/dist/{run → turn}/preparation-context-error.js +0 -0
- /package/dist/{run → turn}/workspace-fingerprint.d.ts +0 -0
- /package/dist/{run → turn}/workspace-fingerprint.js +0 -0
- /package/dist/types/{run → session}/answer-review.js +0 -0
- /package/dist/types/{run → session}/config.js +0 -0
- /package/dist/types/{run → session}/lineage.js +0 -0
- /package/dist/types/{run → session}/prepare-step.js +0 -0
- /package/dist/types/{run → session}/stop-reason.js +0 -0
- /package/src/{run → turn}/preparation-context-error.ts +0 -0
- /package/src/{run → turn}/workspace-fingerprint.ts +0 -0
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { join } from 'node:path'
|
|
2
1
|
import {
|
|
3
2
|
AdvisorRegistry,
|
|
4
3
|
AdvisoryContext,
|
|
@@ -14,21 +13,23 @@ import type { ContextReducer } from '../../compaction/reducer.js'
|
|
|
14
13
|
import { serializeState as serializeWorkingState } from '../../compaction/serializer.js'
|
|
15
14
|
import { restoreWorkingState, snapshotWorkingState } from '../../compaction/wire.js'
|
|
16
15
|
import { type CompactionConfig, CompactionConfigSchema } from '../../config/runtime.js'
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import type { RunPersistence } from '../../manager/run/persistence.js'
|
|
16
|
+
import { childSessionLog } from '../../manager/agent/child-session.js'
|
|
17
|
+
import { type TurnRecorder, recordedTurnStart } from '../../manager/session/turn-recorder.js'
|
|
20
18
|
import { PromptContributionRegistry } from '../../prompt/contributions.js'
|
|
21
19
|
import { resolveProviderCapabilities } from '../../provider/capabilities.js'
|
|
22
20
|
import type { ProviderChainMember } from '../../provider/fallback.js'
|
|
23
21
|
import { withStreamIdleTimeout } from '../../provider/idle-timeout.js'
|
|
24
22
|
import type { ProviderRetryConfig } from '../../provider/retry.js'
|
|
25
23
|
import { withTokenBudget } from '../../provider/token-budget.js'
|
|
26
|
-
|
|
27
|
-
import type {
|
|
24
|
+
// The session → turn surface QueryParams and query() are frozen against.
|
|
25
|
+
import type { SessionPaths } from '../../session/paths.js'
|
|
26
|
+
import type { SessionTokenBudget, SessionTokenBudgetStore } from '../../store/budget/index.js'
|
|
27
|
+
import type { SessionCheckpointStore } from '../../store/checkpoint/index.js'
|
|
28
|
+
import type { SessionLease, SessionLog } from '../../store/session-log/index.js'
|
|
28
29
|
import {
|
|
29
30
|
GENAI,
|
|
30
31
|
NAMZU,
|
|
31
|
-
|
|
32
|
+
agentTurnSpanName,
|
|
32
33
|
parentContext,
|
|
33
34
|
serializeSpan,
|
|
34
35
|
} from '../../telemetry/attributes.js'
|
|
@@ -53,7 +54,7 @@ import {
|
|
|
53
54
|
type ResumeHandler,
|
|
54
55
|
autoApproveHandler,
|
|
55
56
|
} from '../../types/hitl/index.js'
|
|
56
|
-
import type { CheckpointId,
|
|
57
|
+
import type { CheckpointId, MessageId, SessionId, TenantId } from '../../types/ids/index.js'
|
|
57
58
|
import type { InvocationState } from '../../types/invocation/index.js'
|
|
58
59
|
import type { MemoryStore } from '../../types/memory/index.js'
|
|
59
60
|
import {
|
|
@@ -64,24 +65,28 @@ import {
|
|
|
64
65
|
import type { AgentPersona } from '../../types/persona/index.js'
|
|
65
66
|
import type { LLMProvider } from '../../types/provider/index.js'
|
|
66
67
|
import type { TaskRouterConfig } from '../../types/router/index.js'
|
|
67
|
-
import type {
|
|
68
|
-
import type {
|
|
69
|
-
import type {
|
|
68
|
+
import type { Sandbox, SandboxProvider } from '../../types/sandbox/index.js'
|
|
69
|
+
import type { ReviewAnswer } from '../../types/session/answer-review.js'
|
|
70
|
+
import type { ProjectId, TopicId } from '../../types/session/ids.js'
|
|
70
71
|
import type {
|
|
71
|
-
AgentRunConfig,
|
|
72
72
|
BeforeStep,
|
|
73
73
|
PrepareStepChain,
|
|
74
|
-
Run,
|
|
75
|
-
RunEvent,
|
|
76
|
-
RunEventListener,
|
|
77
74
|
StepResult,
|
|
78
75
|
StopCondition,
|
|
79
|
-
} from '../../types/
|
|
80
|
-
import
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
76
|
+
} from '../../types/session/index.js'
|
|
77
|
+
import {
|
|
78
|
+
type Origin,
|
|
79
|
+
type SessionEvent,
|
|
80
|
+
type SessionEventListener,
|
|
81
|
+
type SessionLogCursor,
|
|
82
|
+
type SessionLogReplay,
|
|
83
|
+
type Turn,
|
|
84
|
+
type TurnConfig,
|
|
85
|
+
type TurnForkOrigin,
|
|
86
|
+
type TurnId,
|
|
87
|
+
isTurnInProgressError,
|
|
88
|
+
} from '../../types/session/index.js'
|
|
89
|
+
import type { PromoteMemory } from '../../types/session/memory-promotion.js'
|
|
85
90
|
import type { Skill } from '../../types/skills/index.js'
|
|
86
91
|
import type { StructuredOutputConfig } from '../../types/structured-output/index.js'
|
|
87
92
|
import type { TaskStore } from '../../types/task/index.js'
|
|
@@ -96,7 +101,8 @@ import { AwaitedJobs } from '../jobs/awaited-jobs.js'
|
|
|
96
101
|
import type { BackgroundJobRegistry } from '../jobs/registry.js'
|
|
97
102
|
import { catchUpFromCursor, settlePreStartCancellation } from './cancelled-before-start.js'
|
|
98
103
|
import { CheckpointManager, findPendingCheckpoint } from './checkpoint.js'
|
|
99
|
-
import {
|
|
104
|
+
import type { EventTranslator } from './events.js'
|
|
105
|
+
import { finalizeTurn } from './finalize-turn.js'
|
|
100
106
|
import { GuardCoordinator } from './guard.js'
|
|
101
107
|
import { runInputGuardrails } from './guardrails.js'
|
|
102
108
|
import { IterationOrchestrator } from './iteration/index.js'
|
|
@@ -105,17 +111,17 @@ import { isWorkingMemoryMessage } from './iteration/phases/working-memory.js'
|
|
|
105
111
|
import { applyLifecycleHookResults } from './plugin-hooks.js'
|
|
106
112
|
import {
|
|
107
113
|
type SelectedResumeState,
|
|
108
|
-
|
|
114
|
+
prepareTurn,
|
|
109
115
|
projectStateBearingHistory,
|
|
110
116
|
resolveProviderContextWindow,
|
|
111
117
|
selectedResumeStates,
|
|
112
|
-
} from './prepare-
|
|
118
|
+
} from './prepare-turn.js'
|
|
113
119
|
import type { ProjectInstructionContext } from './project-instructions.js'
|
|
114
120
|
import type { PromptCache } from './prompt-cache.js'
|
|
115
121
|
import { PromptBuilder } from './prompt.js'
|
|
116
122
|
import type { PromptSegments } from './prompt.js'
|
|
117
123
|
import { PendingAnswers, QuestionParkBinding } from './question-park.js'
|
|
118
|
-
import {
|
|
124
|
+
import { releaseTurnResources } from './release-turn.js'
|
|
119
125
|
import { RepeatCallTracker } from './repeat-call.js'
|
|
120
126
|
import { ResultAssembler } from './result.js'
|
|
121
127
|
import {
|
|
@@ -137,10 +143,14 @@ import { ToolingBootstrap } from './tooling.js'
|
|
|
137
143
|
export interface QueryParams {
|
|
138
144
|
/** Share observations across turns of one conversation and filesystem; otherwise run-local. */
|
|
139
145
|
fileReadTracker?: import('../../types/tool/index.js').FileReadTracker
|
|
140
|
-
/** One
|
|
141
|
-
budget?:
|
|
142
|
-
/**
|
|
143
|
-
|
|
146
|
+
/** One ledger shared with the task scheduler and descendant child sessions, keyed by (rootSessionId, rootTurnId). */
|
|
147
|
+
budget?: SessionTokenBudget
|
|
148
|
+
/**
|
|
149
|
+
* Where root-turn ledgers are kept (`<root-session-id>/budgets/<root-turn-id>.json`).
|
|
150
|
+
* Absent: beside the session under {@link QueryParams.paths}, or in memory
|
|
151
|
+
* for an in-memory {@link QueryParams.sessionLog}.
|
|
152
|
+
*/
|
|
153
|
+
tokenBudgetStore?: SessionTokenBudgetStore
|
|
144
154
|
/**
|
|
145
155
|
* Notice when the model issues the identical tool call repeatedly, and
|
|
146
156
|
* say so on the next `tool_result`. Defaults on.
|
|
@@ -152,7 +162,7 @@ export interface QueryParams {
|
|
|
152
162
|
repeatCallAdvisory?: boolean
|
|
153
163
|
|
|
154
164
|
/**
|
|
155
|
-
* Tool names this
|
|
165
|
+
* Tool names this turn may not use, subtracted from its effective list.
|
|
156
166
|
* See {@link import('../../types/agent/base.js').BaseAgentConfig.deniedTools}.
|
|
157
167
|
*/
|
|
158
168
|
deniedTools?: readonly string[]
|
|
@@ -164,7 +174,7 @@ export interface QueryParams {
|
|
|
164
174
|
provider: LLMProvider
|
|
165
175
|
/**
|
|
166
176
|
* Transient-failure policy for model calls. A single 429 or 503 used to
|
|
167
|
-
* terminate a
|
|
177
|
+
* terminate a turn outright — no driver in the estate retries. Defaults
|
|
168
178
|
* to {@link DEFAULT_PROVIDER_RETRY}; pass `false` to opt out (e.g. when
|
|
169
179
|
* the host already wraps the provider with its own policy).
|
|
170
180
|
*
|
|
@@ -190,38 +200,18 @@ export interface QueryParams {
|
|
|
190
200
|
*/
|
|
191
201
|
fallbackProviders?: readonly ProviderChainMember[]
|
|
192
202
|
|
|
193
|
-
/**
|
|
194
|
-
* Install process-level crash handlers that dump this run's state to
|
|
195
|
-
* `<runDir>/../emergency/<runId>.json` on SIGINT, SIGTERM or an
|
|
196
|
-
* uncaught exception. `replay({ fromCheckpoint: 'emergency' })` reads
|
|
197
|
-
* that file.
|
|
198
|
-
*
|
|
199
|
-
* **Off by default, and it must stay that way.** `attach` registers
|
|
200
|
-
* `process.on(...)` handlers that call `process.exit()`. A library
|
|
201
|
-
* seizing a host's termination path is an overreach in any embedded
|
|
202
|
-
* context (an API server has its own drain sequence), and the manager
|
|
203
|
-
* is a singleton whose `attach` detaches whoever held it before — so
|
|
204
|
-
* with concurrent runs the last one to start would silently become the
|
|
205
|
-
* only one that gets saved.
|
|
206
|
-
*
|
|
207
|
-
* Turn it on for a process the run owns end-to-end: a CLI, a worker
|
|
208
|
-
* that handles one run at a time. The handlers are removed when the
|
|
209
|
-
* run settles.
|
|
210
|
-
*/
|
|
211
|
-
emergencySave?: boolean
|
|
212
|
-
|
|
213
203
|
/**
|
|
214
204
|
* Durability for questions raised by a tool that closed over its
|
|
215
|
-
* binding before the
|
|
205
|
+
* binding before the turn existed.
|
|
216
206
|
*
|
|
217
207
|
* The built-in `ask_user_question` is built with the agent's tool
|
|
218
208
|
* registry, so only whoever builds the tools can hand it one — that is
|
|
219
|
-
* what lets a single tool instance be durable inside a
|
|
209
|
+
* what lets a single tool instance be durable inside a turn and inert
|
|
220
210
|
* outside one. Without it, THAT tool's park is only a suspended
|
|
221
211
|
* `await`: kill the process while somebody is looking at the card and
|
|
222
212
|
* the answer can never be applied.
|
|
223
213
|
*
|
|
224
|
-
* Not required for `ToolContext.requestPause`. The
|
|
214
|
+
* Not required for `ToolContext.requestPause`. The turn builds that
|
|
225
215
|
* seam per call and binds its own recorder when none is passed, so a
|
|
226
216
|
* pause raised from a host-authored tool is durable on every surface
|
|
227
217
|
* rather than only on the one agent class that supplies this.
|
|
@@ -242,9 +232,9 @@ export interface QueryParams {
|
|
|
242
232
|
* The registry a re-entered `ask_user_question` reads its answer from.
|
|
243
233
|
*
|
|
244
234
|
* Same shape, same reason and same limit as {@link questionParks}: it
|
|
245
|
-
* exists for a tool that closed over the instance before the
|
|
246
|
-
* and without it a resumed
|
|
247
|
-
* from `ToolContext.requestPause` needs none, because the
|
|
235
|
+
* exists for a tool that closed over the instance before the turn did,
|
|
236
|
+
* and without it a resumed turn re-asks that tool's question. A pause
|
|
237
|
+
* from `ToolContext.requestPause` needs none, because the turn fills
|
|
248
238
|
* its own on the resume path.
|
|
249
239
|
*/
|
|
250
240
|
pendingAnswers?: PendingAnswers
|
|
@@ -252,29 +242,29 @@ export interface QueryParams {
|
|
|
252
242
|
/** Default per-tool execution deadline. See {@link ToolDefinition.timeoutMs}. */
|
|
253
243
|
toolTimeoutMs?: number
|
|
254
244
|
/**
|
|
255
|
-
* Where background jobs this
|
|
245
|
+
* Where background jobs this turn starts are held, and killed.
|
|
256
246
|
*
|
|
257
|
-
* Host-owned so it can outlive one
|
|
258
|
-
* never be the thing that kills a
|
|
259
|
-
* gone. This
|
|
260
|
-
* run's are untouched. The registry launches host processes, so a
|
|
247
|
+
* Host-owned so it can outlive one turn — a registry built per turn could
|
|
248
|
+
* never be the thing that kills a turn's jobs when the turn is already
|
|
249
|
+
* gone. This turn's jobs are torn down in the `finally` below; another
|
|
250
|
+
* run's are untouched. The registry launches host processes, so a turn
|
|
261
251
|
* that also supplies a {@link sandboxProvider} does not expose it to tools:
|
|
262
252
|
* background execution is refused rather than silently bypassing the sandbox.
|
|
263
253
|
*/
|
|
264
254
|
backgroundJobs?: BackgroundJobRegistry
|
|
265
255
|
/**
|
|
266
|
-
* Which owner the
|
|
267
|
-
* jobs are stopped when the
|
|
256
|
+
* Which owner the turn's background jobs belong to. Absent, the turn id:
|
|
257
|
+
* jobs are stopped when the turn ends. A host that wants a job to
|
|
268
258
|
* outlive the turn that started it — a dev server started in one turn
|
|
269
259
|
* and read in the next — passes its session id here and calls
|
|
270
|
-
* `backgroundJobs.killOwner(sessionId)` when the session ends; the
|
|
260
|
+
* `backgroundJobs.killOwner(sessionId)` when the session ends; the turn
|
|
271
261
|
* then stops nothing at its end and still tells the model when a job
|
|
272
262
|
* finishes.
|
|
273
263
|
*/
|
|
274
264
|
backgroundJobOwner?: string
|
|
275
265
|
|
|
276
266
|
/**
|
|
277
|
-
* What else goes in this
|
|
267
|
+
* What else goes in this turn's prompt.
|
|
278
268
|
*
|
|
279
269
|
* `static` and `dynamic` contributions reach the system prompt through
|
|
280
270
|
* `PromptBuilder`; `turn` contributions reach the ephemeral trailing
|
|
@@ -287,8 +277,8 @@ export interface QueryParams {
|
|
|
287
277
|
* Where the `skill` tool loads from.
|
|
288
278
|
*
|
|
289
279
|
* Separate from `skills`, which is the LIST that goes in the prompt
|
|
290
|
-
* manifest. A
|
|
291
|
-
* every
|
|
280
|
+
* manifest. A turn can have the manifest without the tool — that is what
|
|
281
|
+
* every turn did before the tool existed — and the two are wired
|
|
292
282
|
* independently on purpose: a host may want the guidance visible without
|
|
293
283
|
* granting a way to pull bodies in mid-run.
|
|
294
284
|
*/
|
|
@@ -297,19 +287,19 @@ export interface QueryParams {
|
|
|
297
287
|
/**
|
|
298
288
|
* Where a message's stored attachments are resolved from.
|
|
299
289
|
*
|
|
300
|
-
* Absent is fine for every
|
|
301
|
-
* every
|
|
290
|
+
* Absent is fine for every turn whose attachments are inline, which is
|
|
291
|
+
* every turn that existed before this. A message carrying a ref with no
|
|
302
292
|
* store REFUSES rather than dropping the attachment.
|
|
303
293
|
*/
|
|
304
294
|
attachmentStore?: import('../../store/attachment/index.js').AttachmentStore
|
|
305
295
|
/**
|
|
306
|
-
* Maximum wall-clock time for resolving the
|
|
296
|
+
* Maximum wall-clock time for resolving the turn's stored attachments.
|
|
307
297
|
* Defaults to one minute; `0` retains the prior unbounded wait.
|
|
308
298
|
*/
|
|
309
299
|
attachmentResolveTimeoutMs?: number
|
|
310
300
|
|
|
311
301
|
/**
|
|
312
|
-
* How this
|
|
302
|
+
* How this turn reaches the web.
|
|
313
303
|
*
|
|
314
304
|
* `fetch` and `search` are independent, and this kernel ships only the
|
|
315
305
|
* first — see `connector/web` for why choosing a search backend here
|
|
@@ -330,12 +320,12 @@ export interface QueryParams {
|
|
|
330
320
|
|
|
331
321
|
/** Max concurrently-executing concurrency-safe tools in one batch. */
|
|
332
322
|
maxToolConcurrency?: number
|
|
333
|
-
/** Per-
|
|
323
|
+
/** Per-turn cumulative tool attempt limit, including nested calls and retries. Unset is unlimited. Re-supply on resume; durable reservations are never refunded. */
|
|
334
324
|
maxToolCalls?: number
|
|
335
325
|
|
|
336
326
|
/**
|
|
337
327
|
* Model-visible size cap for a single tool result. Over-budget output is
|
|
338
|
-
* spilled to the
|
|
328
|
+
* spilled to the turn directory and replaced with a head+tail preview
|
|
339
329
|
* naming the path, so nothing is lost and tokens are paid only if the
|
|
340
330
|
* agent decides the rest is worth re-reading. Set `0` to disable.
|
|
341
331
|
*/
|
|
@@ -344,9 +334,9 @@ export interface QueryParams {
|
|
|
344
334
|
* Screens to run against every tool result, where the registry was not
|
|
345
335
|
* built with its own.
|
|
346
336
|
*
|
|
347
|
-
* This is the
|
|
337
|
+
* This is the turn's half of a boundary whose only other door is the
|
|
348
338
|
* registry constructor — and a registry is usually the HOST's, assembled
|
|
349
|
-
* before the
|
|
339
|
+
* before the turn exists, so a turn-config option is the only way a turn
|
|
350
340
|
* screens a registry it did not build. A registry built WITH
|
|
351
341
|
* `resultGuardrails` states its own policy and wins, `[]` included.
|
|
352
342
|
*
|
|
@@ -392,7 +382,7 @@ export interface QueryParams {
|
|
|
392
382
|
*
|
|
393
383
|
* Before this the only halt was `GuardCoordinator`, which sees four
|
|
394
384
|
* numeric budgets and never the messages — so a terminal
|
|
395
|
-
* `submit_answer` tool could not end a
|
|
385
|
+
* `submit_answer` tool could not end a turn, and the model had to be
|
|
396
386
|
* prompt-begged to stop with `maxIterations: 200` as the only backstop.
|
|
397
387
|
*
|
|
398
388
|
* Helpers: `stepCountIs`, `hasToolCall`, `anyOf`.
|
|
@@ -400,30 +390,30 @@ export interface QueryParams {
|
|
|
400
390
|
stopWhen?: StopCondition
|
|
401
391
|
|
|
402
392
|
/**
|
|
403
|
-
* Judge the answer the
|
|
393
|
+
* Judge the answer the turn is about to settle with, and hand it back
|
|
404
394
|
* with feedback when it is not good enough.
|
|
405
395
|
*
|
|
406
396
|
* `stopWhen` is only consulted after tools have run, so there was no
|
|
407
|
-
* seam at the point the model stops calling them: the
|
|
397
|
+
* seam at the point the model stops calling them: the turn finalized
|
|
408
398
|
* with whatever it had. Verify-then-fix — run the build, feed the
|
|
409
|
-
* failure back, let it try again — meant starting a new
|
|
399
|
+
* failure back, let it try again — meant starting a new turn and
|
|
410
400
|
* re-supplying the context the first one had already assembled.
|
|
411
401
|
*
|
|
412
402
|
* Bounded by {@link maxAnswerReviews}. Never called on the forced-final
|
|
413
403
|
* turn, which exists to extract a closing summary under pressure.
|
|
414
|
-
* Exceptions or malformed verdicts fail the
|
|
404
|
+
* Exceptions or malformed verdicts fail the turn; cancellation stops waiting.
|
|
415
405
|
*/
|
|
416
406
|
reviewAnswer?: ReviewAnswer
|
|
417
407
|
|
|
418
408
|
/**
|
|
419
|
-
* Decide what this
|
|
409
|
+
* Decide what this turn should leave behind when it settles.
|
|
420
410
|
*
|
|
421
411
|
* See {@link PromoteMemory}. Absent means nothing is offered and the
|
|
422
412
|
* run behaves exactly as it did.
|
|
423
413
|
*/
|
|
424
414
|
promoteMemory?: PromoteMemory
|
|
425
415
|
|
|
426
|
-
/** Corrections allowed before the
|
|
416
|
+
/** Corrections allowed before the turn stops. Nonnegative safe integer; default 3. Consumed rejections survive checkpoints. */
|
|
427
417
|
maxAnswerReviews?: number
|
|
428
418
|
|
|
429
419
|
/** Called with each completed step, as it completes. */
|
|
@@ -433,11 +423,11 @@ export interface QueryParams {
|
|
|
433
423
|
* Shape each step before the model is called: narrow the tool surface,
|
|
434
424
|
* swap the model, add one-step guidance, change sampling.
|
|
435
425
|
*
|
|
436
|
-
* `stopWhen` let a
|
|
426
|
+
* `stopWhen` let a turn decide TO STOP from what its steps produced;
|
|
437
427
|
* this is the other half — deciding how the next step should look.
|
|
438
428
|
* Without it, the tool surface and model are fixed at `query()` time,
|
|
439
429
|
* so a phased agent (research with search tools, write with file tools,
|
|
440
|
-
* verify with a cheaper model) had to be three separate
|
|
430
|
+
* verify with a cheaper model) had to be three separate turns, each
|
|
441
431
|
* starting blind to the last one's context.
|
|
442
432
|
*
|
|
443
433
|
* Narrowing `activeTools` costs a prompt-cache prefix, since tools
|
|
@@ -446,7 +436,7 @@ export interface QueryParams {
|
|
|
446
436
|
* `allowed_tools`, and moving `tool_choice` invalidates cached MESSAGE
|
|
447
437
|
* blocks too, which is a strictly worse trade for the same effect.
|
|
448
438
|
*
|
|
449
|
-
* Fails open — a throw leaves the step with the
|
|
439
|
+
* Fails open — a throw leaves the step with the turn's configuration.
|
|
450
440
|
*/
|
|
451
441
|
prepareStep?: PrepareStepChain
|
|
452
442
|
/**
|
|
@@ -463,7 +453,7 @@ export interface QueryParams {
|
|
|
463
453
|
structuredOutput?: StructuredOutputConfig
|
|
464
454
|
|
|
465
455
|
/**
|
|
466
|
-
* Checks run BEFORE the first model call. A block settles the
|
|
456
|
+
* Checks run BEFORE the first model call. A block settles the turn as
|
|
467
457
|
* `input_guardrail` having spent nothing.
|
|
468
458
|
*
|
|
469
459
|
* namzu's three tool gates all point one way — they protect the world
|
|
@@ -472,7 +462,7 @@ export interface QueryParams {
|
|
|
472
462
|
inputGuardrails?: readonly InputGuardrailSpec[]
|
|
473
463
|
|
|
474
464
|
/**
|
|
475
|
-
* Checks run against the FINAL result. A block settles the
|
|
465
|
+
* Checks run against the FINAL result. A block settles the turn as
|
|
476
466
|
* `output_guardrail`; a `rewrite` replaces the text (so a PII policy
|
|
477
467
|
* can redact rather than discard the whole answer).
|
|
478
468
|
*
|
|
@@ -482,17 +472,46 @@ export interface QueryParams {
|
|
|
482
472
|
*/
|
|
483
473
|
outputGuardrails?: readonly OutputGuardrailSpec[]
|
|
484
474
|
tools: ToolRegistryContract
|
|
485
|
-
|
|
475
|
+
turnConfig: TurnConfig
|
|
486
476
|
allowedTools?: string[]
|
|
487
477
|
agentId: string
|
|
488
478
|
agentName: string
|
|
489
479
|
workingDirectory?: string
|
|
490
480
|
/**
|
|
491
481
|
* Directories besides the working directory the file tools may reach,
|
|
492
|
-
* absolute; a sandboxed
|
|
482
|
+
* absolute; a sandboxed turn binds each read-write. See
|
|
493
483
|
* `ToolContext.additionalDirectories`.
|
|
494
484
|
*/
|
|
495
485
|
additionalDirectories?: readonly string[]
|
|
486
|
+
/**
|
|
487
|
+
* What a file tool's path outside `workingDirectory` and
|
|
488
|
+
* `additionalDirectories` becomes, on a turn with no sandbox.
|
|
489
|
+
*
|
|
490
|
+
* `'refuse'` (the default) keeps the boundary a refusal the tool returns.
|
|
491
|
+
* `'review'` makes it a question asked before the call runs: the call is
|
|
492
|
+
* marked (`ToolCallSummary.escalation.outsidePaths`), routed to the
|
|
493
|
+
* turn's review even when its tool only reads and even where an `allow`
|
|
494
|
+
* rule or a remembered grant would have covered it, and — once approved
|
|
495
|
+
* — reaches exactly the named paths for that call alone. A `deny` rule
|
|
496
|
+
* still refuses it. The review's own mode decides it, so a turn whose
|
|
497
|
+
* policy approves everything approves these too, on the audit record.
|
|
498
|
+
*
|
|
499
|
+
* Only tools that declare `pathArgument` are looked at; a sandboxed turn
|
|
500
|
+
* is never, because the path is not mounted there to be reached.
|
|
501
|
+
*/
|
|
502
|
+
outsideRootAccess?: 'refuse' | 'review'
|
|
503
|
+
/**
|
|
504
|
+
* Whether a call may ask to run outside the turn's sandbox (the shipped
|
|
505
|
+
* `bash` tool's `dangerously_disable_sandbox`).
|
|
506
|
+
*
|
|
507
|
+
* `'refuse'` (the default) refuses every such request. `'review'` routes
|
|
508
|
+
* it to the turn's review every time; it runs unconfined only when the
|
|
509
|
+
* decision confirms its id (`HITLResumeDecision.confirmedEscalations`),
|
|
510
|
+
* which `createReviewHandler` does only after asking a person, or with
|
|
511
|
+
* `unattendedSandboxEscape: 'allow'`. Every confirmation and refusal is
|
|
512
|
+
* written to the audit trail.
|
|
513
|
+
*/
|
|
514
|
+
sandboxEscape?: 'refuse' | 'review'
|
|
496
515
|
pricing?: ModelPricing
|
|
497
516
|
enableActivityTracking?: boolean
|
|
498
517
|
messages: Message[]
|
|
@@ -505,7 +524,7 @@ export interface QueryParams {
|
|
|
505
524
|
* out-of-band — typically in a different process.
|
|
506
525
|
*
|
|
507
526
|
* Recording a park makes the request survive a restart; this is what
|
|
508
|
-
* makes the ANSWER survive one. Without it a resumed
|
|
527
|
+
* makes the ANSWER survive one. Without it a resumed turn repairs the
|
|
509
528
|
* unanswered `tool_use` blocks away and lets the model re-decide, so a
|
|
510
529
|
* human's "yes, delete that row" degrades into "ask the model again and
|
|
511
530
|
* hope it asks for the same thing".
|
|
@@ -525,128 +544,142 @@ export interface QueryParams {
|
|
|
525
544
|
* A park is only worth persisting if a human is actually looking at it:
|
|
526
545
|
* a programmatic handler answers in microseconds, and the iteration
|
|
527
546
|
* gate runs on every iteration, so recording every park unconditionally
|
|
528
|
-
* would take a long
|
|
547
|
+
* would take a long turn from one full-history checkpoint write per
|
|
529
548
|
* iteration to three. Set `0` to record every park (tests, or a host
|
|
530
549
|
* that wants an unconditional audit trail).
|
|
531
550
|
*/
|
|
532
551
|
parkRecordDelayMs?: number
|
|
533
552
|
|
|
534
553
|
/**
|
|
535
|
-
* Span this
|
|
554
|
+
* Span this turn should hang off, when it is a delegated one.
|
|
536
555
|
*
|
|
537
556
|
* A spawned sub-agent is part of its parent's work, and a trace that
|
|
538
557
|
* shows the delegation is the whole reason to trace a supervisor at
|
|
539
|
-
* all. Absent for a top-level
|
|
558
|
+
* all. Absent for a top-level turn, which correctly starts its own root.
|
|
540
559
|
*/
|
|
541
560
|
parentSpan?: import('@opentelemetry/api').Span
|
|
542
561
|
|
|
543
|
-
/** Session scope for the
|
|
562
|
+
/** Session scope for the turn. Required — every turn is attributed to a Session. */
|
|
544
563
|
sessionId: SessionId
|
|
545
564
|
|
|
546
565
|
/**
|
|
547
|
-
* Topic the Session lives under. Required — every
|
|
548
|
-
* five-layer scope (Tenant → Project → Topic → Session →
|
|
566
|
+
* Topic the Session lives under. Required — every turn carries the full
|
|
567
|
+
* five-layer scope (Tenant → Project → Topic → Session → Turn).
|
|
549
568
|
* Denormalized from `session.topicId`; callers build this alongside
|
|
550
569
|
* `sessionId` so the query pipeline never needs a second SessionStore
|
|
551
570
|
* round-trip to recover it.
|
|
552
571
|
*/
|
|
553
572
|
topicId: TopicId
|
|
554
573
|
|
|
555
|
-
/** Long-lived goal scope for the
|
|
574
|
+
/** Long-lived goal scope for the turn. Required. */
|
|
556
575
|
projectId: ProjectId
|
|
557
576
|
|
|
558
577
|
/** Isolation boundary (Convention #17). Required. */
|
|
559
578
|
tenantId: TenantId
|
|
560
579
|
|
|
561
580
|
/**
|
|
562
|
-
*
|
|
563
|
-
*
|
|
564
|
-
*
|
|
565
|
-
* the fallback working-directory store as a side effect.
|
|
581
|
+
* Where the session lives on disk (`<NAMZU_HOME>/projects/<slug>/…`).
|
|
582
|
+
* Defaults to `SessionPaths` under `resolveNamzuHome()`. Namzu never writes
|
|
583
|
+
* under the working directory.
|
|
566
584
|
*/
|
|
567
|
-
|
|
585
|
+
paths?: SessionPaths
|
|
568
586
|
|
|
569
587
|
/**
|
|
570
|
-
* Optional checkpoint persistence override. Absent
|
|
571
|
-
*
|
|
572
|
-
*
|
|
573
|
-
* {@link CheckpointStore} (e.g. Postgres-backed) so mid-turn resume
|
|
574
|
-
* survives machines that lose their local disk.
|
|
588
|
+
* Optional checkpoint persistence override. Absent: checkpoint documents go
|
|
589
|
+
* to `<session-id>/checkpoints/`, or stay in memory for an in-memory
|
|
590
|
+
* {@link QueryParams.sessionLog}.
|
|
575
591
|
*/
|
|
576
|
-
checkpointStore?:
|
|
592
|
+
checkpointStore?: SessionCheckpointStore
|
|
577
593
|
|
|
578
594
|
/**
|
|
579
|
-
* The
|
|
580
|
-
*
|
|
581
|
-
*
|
|
582
|
-
*
|
|
583
|
-
*
|
|
584
|
-
* every run did before claims existed.
|
|
585
|
-
*
|
|
586
|
-
* This hop did not exist for a release. The claim, the fence and the
|
|
587
|
-
* store-side refusal were all built and tested, and no path between a run
|
|
588
|
-
* and its store carried the number — so every checkpoint a RUN wrote went
|
|
589
|
-
* out unfenced while the tests, which called the store directly, all
|
|
590
|
-
* passed. A capability complete except for the wire between its halves
|
|
591
|
-
* reads exactly like a working one.
|
|
592
|
-
*
|
|
593
|
-
* It fences checkpoints and nothing else. {@link QueryParams.runStore}
|
|
594
|
-
* takes no fence, so two workers that both took one run still overwrite
|
|
595
|
-
* each other's run record, transcript and report — see the changeset.
|
|
595
|
+
* The lease this worker holds on the session, from `claimSession`. Every
|
|
596
|
+
* record the turn appends carries its fence (`gen`), so a worker that
|
|
597
|
+
* stalled past its lease is refused rather than writing into a session
|
|
598
|
+
* somebody else has taken over. Absent: `query()` claims the lease itself
|
|
599
|
+
* and releases it when the turn settles or parks.
|
|
596
600
|
*/
|
|
597
|
-
|
|
601
|
+
lease?: SessionLease
|
|
598
602
|
|
|
599
603
|
/**
|
|
600
|
-
*
|
|
601
|
-
*
|
|
602
|
-
*
|
|
603
|
-
*
|
|
604
|
-
* The sibling of {@link QueryParams.checkpointStore}, and it should always
|
|
605
|
-
* have been one: checkpoints could be pointed at durable storage and the
|
|
606
|
-
* evidence could not.
|
|
604
|
+
* The session log this turn appends to. Defaults to the log at
|
|
605
|
+
* {@link QueryParams.paths}. An `InMemorySessionLog` with no `paths` keeps
|
|
606
|
+
* the whole session in memory: its checkpoints, its ledger and its child
|
|
607
|
+
* sessions.
|
|
607
608
|
*/
|
|
608
|
-
|
|
609
|
+
sessionLog?: SessionLog
|
|
609
610
|
|
|
610
611
|
/**
|
|
611
|
-
* Where a reconnecting consumer left off, so this
|
|
612
|
+
* Where a reconnecting consumer left off, so this turn's stream can start by
|
|
612
613
|
* handing back what it missed.
|
|
613
614
|
*
|
|
614
615
|
* The case this serves is the one that exists without a network hop: the
|
|
615
|
-
* process holding the
|
|
616
|
-
* to a
|
|
617
|
-
* reach it through {@link import('./resume-
|
|
616
|
+
* process holding the turn died, and the consumer watching it is coming back
|
|
617
|
+
* to a turn that has to be resumed. Pair it with `resumeFromCheckpoint` — or
|
|
618
|
+
* reach it through {@link import('./resume-session.js').resumeSession}, which is the
|
|
618
619
|
* surface that does both — and the missed durable events are yielded, in
|
|
619
|
-
* order, before the resumed
|
|
620
|
+
* order, before the resumed turn emits anything of its own.
|
|
620
621
|
*
|
|
621
|
-
* On a
|
|
622
|
+
* On a turn with no log to catch up on the cursor is answered honestly rather
|
|
622
623
|
* than ignored: a `sinceSeq` above what exists is `cursor_ahead`, not
|
|
623
624
|
* silence.
|
|
624
625
|
*
|
|
625
626
|
* What comes back is message-granular. Streaming deltas are never persisted
|
|
626
|
-
* — see {@link import('../../types/
|
|
627
|
+
* — see {@link import('../../types/session/events.js').isEphemeralEvent} —
|
|
627
628
|
* so a late subscriber recovers the assistant text, the tool results and the
|
|
628
629
|
* lifecycle, not the keystroke cadence that produced them.
|
|
629
630
|
*/
|
|
630
|
-
eventCursor?:
|
|
631
|
+
eventCursor?: SessionLogCursor
|
|
631
632
|
|
|
632
633
|
/**
|
|
633
634
|
* What became of {@link QueryParams.eventCursor}.
|
|
634
635
|
*
|
|
635
636
|
* A callback rather than an event on the stream, because the answer is about
|
|
636
|
-
* the SUBSCRIPTION and not about the
|
|
637
|
-
* a stale cursor is a client's problem and must not be able to stop a
|
|
637
|
+
* the SUBSCRIPTION and not about the turn — and rather than a throw, because
|
|
638
|
+
* a stale cursor is a client's problem and must not be able to stop a turn
|
|
638
639
|
* from continuing. A host that receives `unavailable` re-derives from the
|
|
639
640
|
* transcript; one that receives nothing at all would splice a hole into its
|
|
640
641
|
* state and never know.
|
|
641
642
|
*
|
|
642
|
-
* Called once, before the
|
|
643
|
+
* Called once, before the turn's first event, and only when a cursor was
|
|
643
644
|
* supplied.
|
|
644
645
|
*/
|
|
645
|
-
onEventReplay?: (replay:
|
|
646
|
+
onEventReplay?: (replay: SessionLogReplay) => void
|
|
646
647
|
|
|
647
|
-
|
|
648
|
+
/**
|
|
649
|
+
* Continue this turn (with `resumeFromCheckpoint`). Absent: a new turn is
|
|
650
|
+
* begun, and refused with `TurnInProgressError` when the session already
|
|
651
|
+
* has an active one.
|
|
652
|
+
*/
|
|
653
|
+
turnId?: TurnId
|
|
654
|
+
|
|
655
|
+
/**
|
|
656
|
+
* Close an `interrupted` active turn — one whose process is gone — with
|
|
657
|
+
* `turn_failed{interrupted}` before this turn begins, instead of refusing
|
|
658
|
+
* with `TurnInProgressError`. A running or paused turn is never closed
|
|
659
|
+
* this way. An interactive host that never resumes an interrupted turn
|
|
660
|
+
* sets it.
|
|
661
|
+
*/
|
|
662
|
+
abandonInterrupted?: boolean
|
|
663
|
+
|
|
664
|
+
/**
|
|
665
|
+
* Which protocol opened this turn, and the caller-side ids it used
|
|
666
|
+
* (`turn_started.origin`). A protocol adapter records the client's own
|
|
667
|
+
* turn id here (`externalTurnId`) rather than making it a namzu id.
|
|
668
|
+
*/
|
|
669
|
+
origin?: Origin
|
|
670
|
+
|
|
671
|
+
/**
|
|
672
|
+
* Present when this session was forked from another session's checkpoint:
|
|
673
|
+
* written into `session_started.forkedFrom` when the log is started, and
|
|
674
|
+
* carried on the returned turn. See `prepareForkState`.
|
|
675
|
+
*/
|
|
676
|
+
forkedFrom?: TurnForkOrigin
|
|
677
|
+
|
|
678
|
+
/** Present on a child session: the session that delegated it. */
|
|
679
|
+
parentSessionId?: SessionId
|
|
648
680
|
|
|
649
|
-
|
|
681
|
+
/** Present on a child session: the parent turn whose tool call spawned it. */
|
|
682
|
+
parentTurnId?: TurnId
|
|
650
683
|
|
|
651
684
|
depth?: number
|
|
652
685
|
|
|
@@ -665,10 +698,10 @@ export interface QueryParams {
|
|
|
665
698
|
taskScheduler?: import('../../types/agent/scheduler.js').TaskScheduler
|
|
666
699
|
|
|
667
700
|
/**
|
|
668
|
-
* Text queued for this
|
|
701
|
+
* Text queued for this turn since its last turn, drained at the boundary.
|
|
669
702
|
*
|
|
670
703
|
* A callback because the queue belongs to whoever accepts the messages,
|
|
671
|
-
* and an array captured here would be whatever was queued before the
|
|
704
|
+
* and an array captured here would be whatever was queued before the turn
|
|
672
705
|
* started. See `BaseAgentConfig.inboundMessages` for what it closes.
|
|
673
706
|
*/
|
|
674
707
|
inboundMessages?: () => import('../../types/message/index.js').Message[]
|
|
@@ -681,7 +714,7 @@ export interface QueryParams {
|
|
|
681
714
|
waitForInbound?: (signal: AbortSignal) => Promise<void>
|
|
682
715
|
|
|
683
716
|
/**
|
|
684
|
-
* Live project policy for this
|
|
717
|
+
* Live project policy for this turn. Unlike `inboundMessages`, snapshot
|
|
685
718
|
* replacement is durable state and never implies another model turn.
|
|
686
719
|
*/
|
|
687
720
|
projectInstructionContext?: ProjectInstructionContext
|
|
@@ -689,9 +722,9 @@ export interface QueryParams {
|
|
|
689
722
|
/**
|
|
690
723
|
* Where this conversation's durable state lives.
|
|
691
724
|
*
|
|
692
|
-
* Supplies the permission mode when `
|
|
725
|
+
* Supplies the permission mode when `turnConfig.permissionMode` names
|
|
693
726
|
* none, and receives the flip when a plan is approved. Absent is the
|
|
694
|
-
* ordinary case: a
|
|
727
|
+
* ordinary case: a turn with no topic state behaves exactly as it did.
|
|
695
728
|
*/
|
|
696
729
|
topicStateStore?: import('../../store/topic/state.js').TopicStateStore
|
|
697
730
|
|
|
@@ -716,15 +749,15 @@ export interface QueryParams {
|
|
|
716
749
|
approvalPolicyName?: string
|
|
717
750
|
|
|
718
751
|
/**
|
|
719
|
-
* Receive this
|
|
752
|
+
* Receive this turn's approval-policy box, so it can be swapped mid-run.
|
|
720
753
|
*
|
|
721
754
|
* The box is built HERE rather than passed in, unlike
|
|
722
755
|
* {@link permissionModeRef}, because changing the policy emits a durable
|
|
723
|
-
* event and only the
|
|
756
|
+
* event and only the turn holds the emitter. A host that constructed its
|
|
724
757
|
* own box would be able to change the policy without recording it, which
|
|
725
758
|
* is the one thing this must not allow.
|
|
726
759
|
*/
|
|
727
|
-
onApprovalPolicy?: (policy: import('../../types/hitl/policy.js').
|
|
760
|
+
onApprovalPolicy?: (policy: import('../../types/hitl/policy.js').SessionApprovalPolicy) => void
|
|
728
761
|
|
|
729
762
|
/**
|
|
730
763
|
* Where a worker completion goes when no tool call is waiting for it.
|
|
@@ -747,11 +780,11 @@ export interface QueryParams {
|
|
|
747
780
|
compactionConfig?: CompactionConfig
|
|
748
781
|
|
|
749
782
|
/**
|
|
750
|
-
* Where what the
|
|
783
|
+
* Where what the turn learned is written when it ends: its decisions,
|
|
751
784
|
* discoveries and failures, as one entry tagged `learning`. Episodic
|
|
752
|
-
* memory (the working state) dies with the
|
|
753
|
-
* the semantic store a later
|
|
754
|
-
* written. A store that fails is logged and never fails the
|
|
785
|
+
* memory (the working state) dies with the turn; this is the bridge to
|
|
786
|
+
* the semantic store a later turn searches. Absent means nothing is
|
|
787
|
+
* written. A store that fails is logged and never fails the turn.
|
|
755
788
|
*/
|
|
756
789
|
consolidateInto?: MemoryStore
|
|
757
790
|
|
|
@@ -759,13 +792,13 @@ export interface QueryParams {
|
|
|
759
792
|
* Optional neutral working-memory seam. When set, the iteration loop
|
|
760
793
|
* re-renders the provider's string into a single pinned leading system
|
|
761
794
|
* message every turn (the primacy-edge, compaction-preserved slot).
|
|
762
|
-
* Absent ⇒ `refreshWorkingMemory` early-returns and the
|
|
795
|
+
* Absent ⇒ `refreshWorkingMemory` early-returns and the turn path is
|
|
763
796
|
* byte-identical.
|
|
764
797
|
*/
|
|
765
798
|
workingMemoryProvider?: WorkingMemoryProvider
|
|
766
799
|
|
|
767
800
|
/**
|
|
768
|
-
* Replace context reduction for this
|
|
801
|
+
* Replace context reduction for this turn.
|
|
769
802
|
*
|
|
770
803
|
* Outranks `compactionConfig.strategy`, and the built-in structured pass
|
|
771
804
|
* does not also run: two mechanisms editing one history in the same pass
|
|
@@ -783,10 +816,10 @@ export interface QueryParams {
|
|
|
783
816
|
sandboxProvider?: SandboxProvider
|
|
784
817
|
|
|
785
818
|
/**
|
|
786
|
-
* Maximum time the
|
|
819
|
+
* Maximum time the turn waits for sandbox teardown, in milliseconds.
|
|
787
820
|
*
|
|
788
821
|
* Defaults to 30 seconds. A fresh private signal is passed to `destroy()`;
|
|
789
|
-
* the
|
|
822
|
+
* the turn also races the returned promise so an implementation that ignores
|
|
790
823
|
* cancellation cannot pin `drainQuery()`. Set `0` to retain an unbounded
|
|
791
824
|
* teardown wait.
|
|
792
825
|
*/
|
|
@@ -803,7 +836,7 @@ export interface QueryParams {
|
|
|
803
836
|
* explicitly (tool surfaces stripped from prompt + request;
|
|
804
837
|
* attachments left unmapped by the driver). The same policy is checked
|
|
805
838
|
* immediately before every request for image/document blocks produced by a
|
|
806
|
-
* tool, because those do not exist at
|
|
839
|
+
* tool, because those do not exist at turn setup. `true`: throw instead of
|
|
807
840
|
* degrading.
|
|
808
841
|
*/
|
|
809
842
|
strictCapabilities?: boolean
|
|
@@ -815,7 +848,7 @@ export interface QueryParams {
|
|
|
815
848
|
* The plan re-appends the exact assistant with real/denied/recovered results.
|
|
816
849
|
* Generic history repair must not synthesize a competing result first. Any
|
|
817
850
|
* partial results for that turn are removed too; the executor reconstructs
|
|
818
|
-
* them from the durable
|
|
851
|
+
* them from the durable turn transcript through `recoveredResults`.
|
|
819
852
|
*/
|
|
820
853
|
function withoutOwnedResumeTurn(
|
|
821
854
|
messages: readonly Message[],
|
|
@@ -886,10 +919,10 @@ function withOwnedResumeOutcomes(
|
|
|
886
919
|
]
|
|
887
920
|
}
|
|
888
921
|
|
|
889
|
-
export async function* query(params: QueryParams): AsyncGenerator<
|
|
890
|
-
const prepared = await
|
|
922
|
+
export async function* query(params: QueryParams): AsyncGenerator<SessionEvent, Turn> {
|
|
923
|
+
const prepared = await prepareTurn(params)
|
|
891
924
|
const {
|
|
892
|
-
|
|
925
|
+
turnConfig,
|
|
893
926
|
budget,
|
|
894
927
|
log,
|
|
895
928
|
ctx,
|
|
@@ -902,6 +935,7 @@ export async function* query(params: QueryParams): AsyncGenerator<RunEvent, Run>
|
|
|
902
935
|
executeUserInterruptHooks,
|
|
903
936
|
pendingHistoryRepairs,
|
|
904
937
|
initialMessages,
|
|
938
|
+
historyIds,
|
|
905
939
|
queuedForThisRun,
|
|
906
940
|
selectedResumeState,
|
|
907
941
|
attachmentResolutionCancelled,
|
|
@@ -912,1465 +946,1505 @@ export async function* query(params: QueryParams): AsyncGenerator<RunEvent, Run>
|
|
|
912
946
|
} = prepared
|
|
913
947
|
|
|
914
948
|
if (attachmentResolutionCancelled) {
|
|
915
|
-
|
|
949
|
+
try {
|
|
950
|
+
return yield* settlePreStartCancellation(params, prepared)
|
|
951
|
+
} finally {
|
|
952
|
+
await ctx.recorder.release()
|
|
953
|
+
}
|
|
916
954
|
}
|
|
917
955
|
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
const
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
956
|
+
// Everything from here to the turn body can refuse (a capability the
|
|
957
|
+
// provider lacks, a sandbox mode it does not offer); the lease the
|
|
958
|
+
// prelude took is given back on the way out.
|
|
959
|
+
let unsubscribeChildSessions: (() => void) | undefined
|
|
960
|
+
try {
|
|
961
|
+
const unsubscribeTaskStore = params.taskStore
|
|
962
|
+
? eventTranslator.wireTaskStore(params.taskStore, ctx.sessionId)
|
|
963
|
+
: undefined
|
|
964
|
+
// The children this turn delegates to are recorded in this session's
|
|
965
|
+
// log: `child_session_spawned` when one starts, `child_session_ended`
|
|
966
|
+
// (read from the child's own log) when it goes idle. That is what lets
|
|
967
|
+
// the parent list and replay its children once the process is gone.
|
|
968
|
+
unsubscribeChildSessions = taskScheduler?.onChildSessionEvent?.((event) => {
|
|
969
|
+
// Looked up now, while the manager still holds the child's spawn record.
|
|
970
|
+
const childLog =
|
|
971
|
+
event.type === 'child_session_idled' ? childSessionLog(event.childSessionId) : undefined
|
|
972
|
+
void ctx.recorder.recordChildSessionEvent(event, childLog).catch((err: unknown) => {
|
|
973
|
+
ctx.log.warn('A child session record could not be appended', {
|
|
974
|
+
[NAMZU.TURN_ID]: ctx.turnId,
|
|
975
|
+
'namzu.child_session.id': event.childSessionId,
|
|
976
|
+
'exception.message': err instanceof Error ? err.message : String(err),
|
|
977
|
+
})
|
|
978
|
+
})
|
|
979
|
+
})
|
|
980
|
+
|
|
981
|
+
if (params.taskStore) {
|
|
982
|
+
const taskTools = buildTaskTools(params.taskStore, {
|
|
983
|
+
sessionId: ctx.sessionId,
|
|
984
|
+
turnId: ctx.turnId,
|
|
985
|
+
// A resumed turn began when its `turn_started` was recorded, maybe
|
|
986
|
+
// in another process: tasks it closed before the pause are still
|
|
987
|
+
// "closed in this turn".
|
|
988
|
+
turnStartedAt:
|
|
989
|
+
(params.resumeFromCheckpoint
|
|
990
|
+
? await recordedTurnStart(ctx.recorder.log, ctx.turnId)
|
|
991
|
+
: undefined) ?? ctx.recorder.getTurn().startedAt,
|
|
992
|
+
})
|
|
993
|
+
const overrides = params.runtimeToolOverrides
|
|
994
|
+
for (const tool of taskTools) {
|
|
995
|
+
const override = overrides?.[tool.name]
|
|
996
|
+
if (override === 'disabled') continue
|
|
997
|
+
params.tools.register(tool, override ?? 'deferred')
|
|
998
|
+
}
|
|
929
999
|
}
|
|
930
|
-
}
|
|
931
1000
|
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
1001
|
+
if (!params.tools.has(SearchToolsTool.name)) {
|
|
1002
|
+
const hasDeferred = params.tools
|
|
1003
|
+
.listNames()
|
|
1004
|
+
.some((n) => params.tools.getAvailability(n) === 'deferred')
|
|
1005
|
+
if (hasDeferred) {
|
|
1006
|
+
params.tools.register(SearchToolsTool)
|
|
1007
|
+
}
|
|
938
1008
|
}
|
|
939
|
-
}
|
|
940
1009
|
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
1010
|
+
// Registered HERE, before the first turn, not when the model is nearly
|
|
1011
|
+
// done. Tools render at prefix position 0, so injecting one late would
|
|
1012
|
+
// invalidate the whole prompt cache for the rest of the turn — the same
|
|
1013
|
+
// reason the forced-final turn keeps its tools array and uses
|
|
1014
|
+
// `toolChoice: 'none'` instead of dropping it.
|
|
1015
|
+
if (
|
|
1016
|
+
params.structuredOutput &&
|
|
1017
|
+
params.structuredOutput.mode !== 'native' &&
|
|
1018
|
+
!params.tools.has(STRUCTURED_OUTPUT_TOOL_NAME)
|
|
1019
|
+
) {
|
|
1020
|
+
params.tools.register(createStructuredOutputTool(params.structuredOutput.schema))
|
|
1021
|
+
}
|
|
953
1022
|
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
1023
|
+
// ─── Provider capability negotiation (before tooling bootstrap) ────────
|
|
1024
|
+
// Compare what the request asks for with what the DRIVER declared it
|
|
1025
|
+
// does. Undeclared capabilities resolve permissively (today's behavior
|
|
1026
|
+
// for third-party providers); declared gaps degrade loudly instead of
|
|
1027
|
+
// silently.
|
|
1028
|
+
const capabilities = resolveProviderCapabilities(params.provider)
|
|
1029
|
+
const registeredToolCount = params.tools.listNames().length
|
|
1030
|
+
const stripToolSurfaces = !capabilities.supportsTools && registeredToolCount > 0
|
|
1031
|
+
// Counted separately because they are separate wire shapes: a driver can
|
|
1032
|
+
// map images and drop documents, and a vision warning would send the
|
|
1033
|
+
// reader looking at the wrong half.
|
|
1034
|
+
const carries = (m: (typeof params.messages)[number], kind: 'image' | 'document') =>
|
|
1035
|
+
m.role === 'user' && (m.attachments ?? []).some((a) => (a.type ?? 'image') === kind)
|
|
1036
|
+
|
|
1037
|
+
const attachmentMessageCount = capabilities.supportsVision
|
|
1038
|
+
? 0
|
|
1039
|
+
: params.messages.filter((m) => carries(m, 'image')).length
|
|
1040
|
+
const documentMessageCount = capabilities.supportsDocuments
|
|
1041
|
+
? 0
|
|
1042
|
+
: params.messages.filter((m) => carries(m, 'document')).length
|
|
1043
|
+
|
|
1044
|
+
if (stripToolSurfaces) {
|
|
1045
|
+
const message = `Provider '${params.provider.id}' declares supportsTools: false but ${registeredToolCount} tool(s) are registered — stripping all tool surfaces from the prompt and request so the model is never told about tools it cannot call. Pass strictCapabilities: true to fail instead, or use a tools-capable provider.`
|
|
1046
|
+
if (params.strictCapabilities) {
|
|
1047
|
+
throw new NamzuError({
|
|
1048
|
+
code: 'capability_unavailable',
|
|
1049
|
+
message,
|
|
1050
|
+
details: {
|
|
1051
|
+
providerId: params.provider.id,
|
|
1052
|
+
capability: 'tools',
|
|
1053
|
+
registeredToolCount,
|
|
1054
|
+
},
|
|
1055
|
+
})
|
|
1056
|
+
}
|
|
1057
|
+
ctx.log.warn('Capability mismatch: the provider declares no tool support', {
|
|
1058
|
+
'namzu.capability.detail': message,
|
|
1059
|
+
[GENAI.SYSTEM]: params.provider.id,
|
|
1060
|
+
'namzu.runtime.registered_tool_count': registeredToolCount,
|
|
986
1061
|
})
|
|
987
1062
|
}
|
|
988
|
-
ctx.log.warn('Capability mismatch: the provider declares no tool support', {
|
|
989
|
-
'namzu.capability.detail': message,
|
|
990
|
-
[GENAI.SYSTEM]: params.provider.id,
|
|
991
|
-
'namzu.runtime.registered_tool_count': registeredToolCount,
|
|
992
|
-
})
|
|
993
|
-
}
|
|
994
1063
|
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1064
|
+
if (attachmentMessageCount > 0) {
|
|
1065
|
+
const message = `Provider '${params.provider.id}' declares supportsVision: false but ${attachmentMessageCount} user message(s) carry image attachments — the driver will not map them, so the model never sees the images. Pass strictCapabilities: true to fail instead, or use a vision-capable provider.`
|
|
1066
|
+
if (params.strictCapabilities) {
|
|
1067
|
+
throw new NamzuError({
|
|
1068
|
+
code: 'capability_unavailable',
|
|
1069
|
+
message,
|
|
1070
|
+
details: {
|
|
1071
|
+
providerId: params.provider.id,
|
|
1072
|
+
capability: 'vision',
|
|
1073
|
+
attachmentMessageCount,
|
|
1074
|
+
},
|
|
1075
|
+
})
|
|
1076
|
+
}
|
|
1077
|
+
ctx.log.warn('Capability mismatch: the provider declares no vision support', {
|
|
1078
|
+
'namzu.capability.detail': message,
|
|
1079
|
+
[GENAI.SYSTEM]: params.provider.id,
|
|
1080
|
+
'namzu.runtime.attachment_message_count': attachmentMessageCount,
|
|
1006
1081
|
})
|
|
1007
1082
|
}
|
|
1008
|
-
ctx.log.warn('Capability mismatch: the provider declares no vision support', {
|
|
1009
|
-
'namzu.capability.detail': message,
|
|
1010
|
-
[GENAI.SYSTEM]: params.provider.id,
|
|
1011
|
-
'namzu.runtime.attachment_message_count': attachmentMessageCount,
|
|
1012
|
-
})
|
|
1013
|
-
}
|
|
1014
1083
|
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1084
|
+
if (documentMessageCount > 0) {
|
|
1085
|
+
const message = `Provider '${params.provider.id}' declares supportsDocuments: false but ${documentMessageCount} user message(s) carry document attachments — the driver will not map them, so the model never sees the documents. Pass strictCapabilities: true to fail instead, or use a document-capable provider.`
|
|
1086
|
+
if (params.strictCapabilities) {
|
|
1087
|
+
throw new NamzuError({
|
|
1088
|
+
code: 'capability_unavailable',
|
|
1089
|
+
message,
|
|
1090
|
+
details: {
|
|
1091
|
+
providerId: params.provider.id,
|
|
1092
|
+
capability: 'documents',
|
|
1093
|
+
documentMessageCount,
|
|
1094
|
+
},
|
|
1095
|
+
})
|
|
1096
|
+
}
|
|
1097
|
+
ctx.log.warn('Capability mismatch: the provider declares no document support', {
|
|
1098
|
+
'namzu.capability.detail': message,
|
|
1099
|
+
[GENAI.SYSTEM]: params.provider.id,
|
|
1100
|
+
'namzu.runtime.document_message_count': documentMessageCount,
|
|
1026
1101
|
})
|
|
1027
1102
|
}
|
|
1028
|
-
ctx.log.warn('Capability mismatch: the provider declares no document support', {
|
|
1029
|
-
'namzu.capability.detail': message,
|
|
1030
|
-
[GENAI.SYSTEM]: params.provider.id,
|
|
1031
|
-
'namzu.runtime.document_message_count': documentMessageCount,
|
|
1032
|
-
})
|
|
1033
|
-
}
|
|
1034
|
-
|
|
1035
|
-
// Denied names are subtracted LAST, after the allow-list is resolved
|
|
1036
|
-
// against the registry — so a deny reaches a run that named no
|
|
1037
|
-
// allow-list at all, which is the ordinary case for a delegated child.
|
|
1038
|
-
// Applied to `effectiveAllowedTools`, which `query()` binds to both the
|
|
1039
|
-
// request tool list AND the `ToolExecutor`: narrowing only the request
|
|
1040
|
-
// shows the model fewer tools and lets it call any of them by name.
|
|
1041
|
-
const allowedBeforeDenial = stripToolSurfaces
|
|
1042
|
-
? []
|
|
1043
|
-
: withDeferredDiscoveryTool(params.tools, params.allowedTools)
|
|
1044
|
-
const denied = new Set(params.deniedTools ?? [])
|
|
1045
|
-
const effectiveAllowedTools: string[] | undefined =
|
|
1046
|
-
denied.size === 0
|
|
1047
|
-
? allowedBeforeDenial
|
|
1048
|
-
: // An absent allow-list means "every registered tool", so a deny
|
|
1049
|
-
// with no allow-list has to be resolved against the registry
|
|
1050
|
-
// here — otherwise the subtraction would be from an empty list
|
|
1051
|
-
// and would deny nothing, which is the shape a delegated child
|
|
1052
|
-
// arrives in.
|
|
1053
|
-
[...(allowedBeforeDenial ?? params.tools.listNames())].filter((name) => !denied.has(name))
|
|
1054
|
-
|
|
1055
|
-
// The two halves of a durable pause, owned by the RUN when the host
|
|
1056
|
-
// does not own them.
|
|
1057
|
-
//
|
|
1058
|
-
// `SupervisorAgent` builds both before the run exists, because the
|
|
1059
|
-
// tools it builds close over them, and it passes them in. Nothing else
|
|
1060
|
-
// could: neither type is exported from `public-runtime.ts`, so a host
|
|
1061
|
-
// on `ReactiveAgent`, `drainQuery` or `resumeRun` had no way to supply
|
|
1062
|
-
// either — and `ToolContext.requestPause`, which every tool author is
|
|
1063
|
-
// handed, silently wrote no checkpoint and could receive no answer on
|
|
1064
|
-
// those surfaces. Which agent class the host happened to pick is not
|
|
1065
|
-
// visible at the call site, so the degradation was invisible too.
|
|
1066
|
-
//
|
|
1067
|
-
// A run-local pair is enough for the general seam because `query()`
|
|
1068
|
-
// builds its `createToolPause` itself, below, and can hand it the
|
|
1069
|
-
// run's own. Pinned by the "a pause is durable on any surface" cases
|
|
1070
|
-
// in `__tests__/tool-pause-resume.test.ts`.
|
|
1071
|
-
const questionParks = params.questionParks ?? new QuestionParkBinding()
|
|
1072
|
-
const pendingAnswers = params.pendingAnswers ?? new PendingAnswers()
|
|
1073
|
-
|
|
1074
|
-
// One gate instance owns both model-issued calls and calls dispatched by
|
|
1075
|
-
// another tool. Constructing it only inside the iteration review left the
|
|
1076
|
-
// nested registry path outside the operator's policy entirely.
|
|
1077
|
-
const gateConfig = params.authorizationGate
|
|
1078
|
-
const verificationGate = gateConfig?.enabled
|
|
1079
|
-
? new AuthorizationGate(gateConfig, ctx.log)
|
|
1080
|
-
: undefined
|
|
1081
|
-
|
|
1082
|
-
// The store is initialized when the async query starts, after tooling is
|
|
1083
|
-
// composed. Resolve lazily at execution time: capturing getRunDir() here
|
|
1084
|
-
// permanently disabled retention for fresh disk-backed invocations.
|
|
1085
|
-
const toolOutputDir = () => {
|
|
1086
|
-
const runDir = ctx.runMgr.getRunDir()
|
|
1087
|
-
return runDir ? join(runDir, TOOL_OUTPUT_DIR_NAME) : undefined
|
|
1088
|
-
}
|
|
1089
|
-
// The same invocation-owned capability serves tools and optional preparation.
|
|
1090
|
-
// Local cancellation cannot override the run's cancellation or settled state.
|
|
1091
|
-
const captureRunEvidence = async (maxReadBytes?: number, signal?: AbortSignal) => {
|
|
1092
|
-
const combined = signal
|
|
1093
|
-
? AbortSignal.any([ctx.abortController.signal, signal])
|
|
1094
|
-
: ctx.abortController.signal
|
|
1095
|
-
combined.throwIfAborted()
|
|
1096
|
-
const source = await eventTranslator.captureRunEvidence(maxReadBytes, combined)
|
|
1097
|
-
combined.throwIfAborted()
|
|
1098
|
-
return source
|
|
1099
|
-
}
|
|
1100
1103
|
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
...(params.maxToolContentBytes !== undefined
|
|
1164
|
-
? { maxToolContentBytes: params.maxToolContentBytes }
|
|
1165
|
-
: {}),
|
|
1166
|
-
// Overflow lands beside the run's other artifacts, so it is
|
|
1167
|
-
// cleaned up with the run and reachable by the model's own
|
|
1168
|
-
// `read`/`grep` without a new affordance.
|
|
1169
|
-
toolOutputDir,
|
|
1170
|
-
captureRunEvidence,
|
|
1171
|
-
...(params.repairToolCall ? { repairToolCall: params.repairToolCall } : {}),
|
|
1172
|
-
...(verificationGate ? { authorizationGate: verificationGate } : {}),
|
|
1173
|
-
recordAudit: (input) => ctx.runMgr.recordAudit(input),
|
|
1174
|
-
// The durable pause, reachable from any tool rather than from the
|
|
1175
|
-
// four kernel-owned points that used to own it. Built here from
|
|
1176
|
-
// the machinery the run already holds; the recorder binds a few
|
|
1177
|
-
// lines below, and until it does a pause is in-process only —
|
|
1178
|
-
// the same degradation the built-in question tool has.
|
|
1179
|
-
toolPause: (toolUseId) =>
|
|
1180
|
-
createToolPause({
|
|
1181
|
-
runId: ctx.runId,
|
|
1182
|
-
toolUseId,
|
|
1183
|
-
parkHandler: (request) => approvalPolicy.current.handler(request),
|
|
1184
|
-
recorder: questionParks,
|
|
1185
|
-
pendingAnswers,
|
|
1186
|
-
}),
|
|
1187
|
-
},
|
|
1188
|
-
ctx.activityStore,
|
|
1189
|
-
eventTranslator.emitEvent,
|
|
1190
|
-
ctx.log,
|
|
1191
|
-
)
|
|
1104
|
+
// Denied names are subtracted LAST, after the allow-list is resolved
|
|
1105
|
+
// against the registry — so a deny reaches a turn that named no
|
|
1106
|
+
// allow-list at all, which is the ordinary case for a delegated child.
|
|
1107
|
+
// Applied to `effectiveAllowedTools`, which `query()` binds to both the
|
|
1108
|
+
// request tool list AND the `ToolExecutor`: narrowing only the request
|
|
1109
|
+
// shows the model fewer tools and lets it call any of them by name.
|
|
1110
|
+
const allowedBeforeDenial = stripToolSurfaces
|
|
1111
|
+
? []
|
|
1112
|
+
: withDeferredDiscoveryTool(params.tools, params.allowedTools)
|
|
1113
|
+
const denied = new Set(params.deniedTools ?? [])
|
|
1114
|
+
const effectiveAllowedTools: string[] | undefined =
|
|
1115
|
+
denied.size === 0
|
|
1116
|
+
? allowedBeforeDenial
|
|
1117
|
+
: // An absent allow-list means "every registered tool", so a deny
|
|
1118
|
+
// with no allow-list has to be resolved against the registry
|
|
1119
|
+
// here — otherwise the subtraction would be from an empty list
|
|
1120
|
+
// and would deny nothing, which is the shape a delegated child
|
|
1121
|
+
// arrives in.
|
|
1122
|
+
[...(allowedBeforeDenial ?? params.tools.listNames())].filter((name) => !denied.has(name))
|
|
1123
|
+
|
|
1124
|
+
// The two halves of a durable pause, owned by the TURN when the host
|
|
1125
|
+
// does not own them.
|
|
1126
|
+
//
|
|
1127
|
+
// `SupervisorAgent` builds both before the turn exists, because the
|
|
1128
|
+
// tools it builds close over them, and it passes them in. Nothing else
|
|
1129
|
+
// could: neither type is exported from `public-runtime.ts`, so a host
|
|
1130
|
+
// on `ReactiveAgent`, `drainQuery` or `resumeSession` had no way to supply
|
|
1131
|
+
// either — and `ToolContext.requestPause`, which every tool author is
|
|
1132
|
+
// handed, silently wrote no checkpoint and could receive no answer on
|
|
1133
|
+
// those surfaces. Which agent class the host happened to pick is not
|
|
1134
|
+
// visible at the call site, so the degradation was invisible too.
|
|
1135
|
+
//
|
|
1136
|
+
// A run-local pair is enough for the general seam because `query()`
|
|
1137
|
+
// builds its `createToolPause` itself, below, and can hand it the
|
|
1138
|
+
// run's own. Pinned by the "a pause is durable on any surface" cases
|
|
1139
|
+
// in `__tests__/tool-pause-resume.test.ts`.
|
|
1140
|
+
const questionParks = params.questionParks ?? new QuestionParkBinding()
|
|
1141
|
+
const pendingAnswers = params.pendingAnswers ?? new PendingAnswers()
|
|
1142
|
+
|
|
1143
|
+
// One gate instance owns both model-issued calls and calls dispatched by
|
|
1144
|
+
// another tool. Constructing it only inside the iteration review left the
|
|
1145
|
+
// nested registry path outside the operator's policy entirely.
|
|
1146
|
+
const gateConfig = params.authorizationGate
|
|
1147
|
+
const verificationGate = gateConfig?.enabled
|
|
1148
|
+
? new AuthorizationGate(gateConfig, ctx.log)
|
|
1149
|
+
: undefined
|
|
1150
|
+
|
|
1151
|
+
// Oversized tool output is spilled beside the session log
|
|
1152
|
+
// (`<session-id>/tool-results/`). An in-memory session has nowhere to
|
|
1153
|
+
// spill it, so the ordinary output budget applies.
|
|
1154
|
+
const toolOutputDir = () => ctx.toolResultsDir
|
|
1155
|
+
// The same invocation-owned capability serves tools and optional preparation.
|
|
1156
|
+
// Local cancellation cannot override the turn's cancellation or settled state.
|
|
1157
|
+
const captureSessionEvidence = async (maxReadBytes?: number, signal?: AbortSignal) => {
|
|
1158
|
+
const combined = signal
|
|
1159
|
+
? AbortSignal.any([ctx.abortController.signal, signal])
|
|
1160
|
+
: ctx.abortController.signal
|
|
1161
|
+
combined.throwIfAborted()
|
|
1162
|
+
const source = await eventTranslator.captureSessionEvidence(maxReadBytes, combined)
|
|
1163
|
+
combined.throwIfAborted()
|
|
1164
|
+
return source
|
|
1165
|
+
}
|
|
1192
1166
|
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1167
|
+
// Whose jobs this turn speaks for: its own by default, the session's when
|
|
1168
|
+
// the host said so. Resolved before the tools are built, because the
|
|
1169
|
+
// wait-intent recorder below is bound into them.
|
|
1170
|
+
const jobOwner = params.backgroundJobOwner ?? ctx.turnId
|
|
1171
|
+
// What the model reads when a job ends. Built up here, ahead of the
|
|
1172
|
+
// subscription that fills it below, because the wait-intent recorder needs
|
|
1173
|
+
// to ask whether its text has been read yet.
|
|
1174
|
+
const jobNotices = params.backgroundJobs ? new SteeringBinding() : undefined
|
|
1175
|
+
// Jobs the model told `wait_for_job` it is waiting on, which is the only
|
|
1176
|
+
// thing that can hold this turn open for a job. Built only where there is a
|
|
1177
|
+
// registry, so a host with no background mode carries no recorder and the
|
|
1178
|
+
// bound ref has no `markAwaited` to offer.
|
|
1179
|
+
const awaitedJobs = params.backgroundJobs
|
|
1180
|
+
? new AwaitedJobs(params.backgroundJobs, jobOwner, () => jobNotices?.pending ?? false)
|
|
1181
|
+
: undefined
|
|
1182
|
+
awaitedJobs?.attach()
|
|
1183
|
+
|
|
1184
|
+
const toolExecutor = ToolingBootstrap.init(
|
|
1185
|
+
{
|
|
1186
|
+
tools: params.tools,
|
|
1187
|
+
sessionId: ctx.sessionId,
|
|
1188
|
+
turnId: ctx.turnId,
|
|
1189
|
+
workingDirectory: ctx.cwd,
|
|
1190
|
+
...(params.additionalDirectories?.length
|
|
1191
|
+
? { additionalDirectories: params.additionalDirectories }
|
|
1192
|
+
: {}),
|
|
1193
|
+
...(params.outsideRootAccess ? { outsideRootAccess: params.outsideRootAccess } : {}),
|
|
1194
|
+
...(params.sandboxEscape ? { sandboxEscape: params.sandboxEscape } : {}),
|
|
1195
|
+
permissionMode: () => ctx.permissionMode.current,
|
|
1196
|
+
env: turnConfig.env ?? {},
|
|
1197
|
+
abortSignal: ctx.abortController.signal,
|
|
1198
|
+
allowedTools: effectiveAllowedTools,
|
|
1199
|
+
invocationState: params.invocationState,
|
|
1200
|
+
pluginManager: params.pluginManager,
|
|
1201
|
+
...(params.backgroundJobs ? { backgroundJobs: params.backgroundJobs } : {}),
|
|
1202
|
+
...(params.backgroundJobOwner ? { backgroundJobOwner: params.backgroundJobOwner } : {}),
|
|
1203
|
+
...(awaitedJobs ? { onJobAwaited: (id: string) => awaitedJobs.expect(id) } : {}),
|
|
1204
|
+
// The `skill` tool's registry. Threaded from the turn rather than
|
|
1205
|
+
// held by the tool, because a tool that reached for a module-level
|
|
1206
|
+
// registry would answer about whatever the last turn configured.
|
|
1207
|
+
...(params.skillRegistry ? { skills: params.skillRegistry } : {}),
|
|
1208
|
+
...(params.web ? { web: params.web } : {}),
|
|
1209
|
+
...(params.fileReadTracker ? { fileReadTracker: params.fileReadTracker } : {}),
|
|
1210
|
+
...(params.toolTimeoutMs !== undefined ? { toolTimeoutMs: params.toolTimeoutMs } : {}),
|
|
1211
|
+
...(params.toolRetryBackoff !== undefined
|
|
1212
|
+
? { toolRetryBackoff: params.toolRetryBackoff }
|
|
1213
|
+
: {}),
|
|
1214
|
+
...(params.maxToolCalls !== undefined
|
|
1215
|
+
? {
|
|
1216
|
+
maxToolCalls: params.maxToolCalls,
|
|
1217
|
+
readToolCallBudgetRecords: () => eventTranslator.readRecords({ mode: 'strict' }),
|
|
1218
|
+
}
|
|
1219
|
+
: {}),
|
|
1220
|
+
...(params.maxToolConcurrency !== undefined
|
|
1221
|
+
? { maxToolConcurrency: params.maxToolConcurrency }
|
|
1222
|
+
: {}),
|
|
1223
|
+
...(params.maxToolOutputChars !== undefined
|
|
1224
|
+
? { maxToolOutputChars: params.maxToolOutputChars }
|
|
1225
|
+
: {}),
|
|
1226
|
+
...(params.toolResultGuardrails !== undefined
|
|
1227
|
+
? { toolResultGuardrails: params.toolResultGuardrails }
|
|
1228
|
+
: {}),
|
|
1229
|
+
...(params.retainedToolPreviewChars !== undefined
|
|
1230
|
+
? { retainedToolPreviewChars: params.retainedToolPreviewChars }
|
|
1231
|
+
: {}),
|
|
1232
|
+
...(params.maxToolContentBytes !== undefined
|
|
1233
|
+
? { maxToolContentBytes: params.maxToolContentBytes }
|
|
1234
|
+
: {}),
|
|
1235
|
+
// Overflow lands beside the turn's other artifacts, so it is
|
|
1236
|
+
// cleaned up with the turn and reachable by the model's own
|
|
1237
|
+
// `read`/`grep` without a new affordance.
|
|
1238
|
+
toolOutputDir,
|
|
1239
|
+
captureSessionEvidence,
|
|
1240
|
+
...(params.repairToolCall ? { repairToolCall: params.repairToolCall } : {}),
|
|
1241
|
+
...(verificationGate ? { authorizationGate: verificationGate } : {}),
|
|
1242
|
+
recordAudit: (input) => ctx.recorder.recordAudit(input),
|
|
1243
|
+
// The durable pause, reachable from any tool rather than from the
|
|
1244
|
+
// four kernel-owned points that used to own it. Built here from
|
|
1245
|
+
// the machinery the turn already holds; the recorder binds a few
|
|
1246
|
+
// lines below, and until it does a pause is in-process only —
|
|
1247
|
+
// the same degradation the built-in question tool has.
|
|
1248
|
+
toolPause: (toolUseId) =>
|
|
1249
|
+
createToolPause({
|
|
1250
|
+
sessionId: ctx.sessionId,
|
|
1251
|
+
turnId: ctx.turnId,
|
|
1252
|
+
toolUseId,
|
|
1253
|
+
parkHandler: (request) => approvalPolicy.current.handler(request),
|
|
1254
|
+
recorder: questionParks,
|
|
1255
|
+
pendingAnswers,
|
|
1256
|
+
}),
|
|
1257
|
+
},
|
|
1258
|
+
ctx.activityStore,
|
|
1259
|
+
eventTranslator.emitEvent,
|
|
1260
|
+
ctx.log,
|
|
1205
1261
|
)
|
|
1206
|
-
void eventTranslator
|
|
1207
|
-
.emitEvent({
|
|
1208
|
-
type: 'background_job_exited',
|
|
1209
|
-
runId: ctx.runId,
|
|
1210
|
-
jobId: job.id,
|
|
1211
|
-
command: job.command,
|
|
1212
|
-
status: job.status === 'killed' ? 'killed' : 'exited',
|
|
1213
|
-
...(job.exitCode !== undefined ? { exitCode: job.exitCode } : {}),
|
|
1214
|
-
...(job.signal ? { signal: job.signal } : {}),
|
|
1215
|
-
})
|
|
1216
|
-
.catch(() => {})
|
|
1217
|
-
})
|
|
1218
|
-
let workingStateManager: WorkingStateManager | undefined
|
|
1219
|
-
// Normalised once, defaults applied. A host that passes a partial
|
|
1220
|
-
// object — a strategy and a window, nothing else — used to reach the
|
|
1221
|
-
// phase with `triggerThreshold` undefined, and `usage < undefined` is
|
|
1222
|
-
// false: the pass ran on every iteration and the salience strategy fell
|
|
1223
|
-
// through to the stale-result clearing it exists to replace. The eval
|
|
1224
|
-
// suite that passed exactly that object found it.
|
|
1225
|
-
const compactionConfig = params.compactionConfig
|
|
1226
|
-
? CompactionConfigSchema.parse(params.compactionConfig)
|
|
1227
|
-
: undefined
|
|
1228
|
-
if (compactionConfig && compactionConfig.strategy !== 'disabled') {
|
|
1229
|
-
workingStateManager = new WorkingStateManager(compactionConfig)
|
|
1230
|
-
toolExecutor.setWorkingStateManager(workingStateManager)
|
|
1231
|
-
}
|
|
1232
1262
|
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1263
|
+
// A background job's exit reaches the model as a notice on its next tool
|
|
1264
|
+
// result, and the host as an event — without either polling. Subscribed
|
|
1265
|
+
// for the owner the turn's jobs are bound to, so a session-owned job that
|
|
1266
|
+
// ends during this turn is reported here too.
|
|
1267
|
+
const unsubscribeJobExits = params.backgroundJobs?.onExit((job) => {
|
|
1268
|
+
if (job.owner !== jobOwner) return
|
|
1269
|
+
const outcome =
|
|
1270
|
+
job.status === 'killed'
|
|
1271
|
+
? 'was stopped'
|
|
1272
|
+
: `exited with code ${job.exitCode ?? 'unknown'}${job.signal ? ` (${job.signal})` : ''}`
|
|
1273
|
+
jobNotices?.steer(
|
|
1274
|
+
`Background job ${job.id} (${job.command}) ${outcome}. Read its output with the job tool if you need it.`,
|
|
1275
|
+
)
|
|
1276
|
+
void eventTranslator
|
|
1277
|
+
.emitEvent({
|
|
1278
|
+
type: 'background_job_exited',
|
|
1279
|
+
turnId: ctx.turnId,
|
|
1280
|
+
jobId: job.id,
|
|
1281
|
+
command: job.command,
|
|
1282
|
+
status: job.status === 'killed' ? 'killed' : 'exited',
|
|
1283
|
+
...(job.exitCode !== undefined ? { exitCode: job.exitCode } : {}),
|
|
1284
|
+
...(job.signal ? { signal: job.signal } : {}),
|
|
1285
|
+
})
|
|
1286
|
+
.catch(() => {})
|
|
1287
|
+
})
|
|
1288
|
+
let workingStateManager: WorkingStateManager | undefined
|
|
1289
|
+
// Normalised once, defaults applied. A host that passes a partial
|
|
1290
|
+
// object — a strategy and a window, nothing else — used to reach the
|
|
1291
|
+
// phase with `triggerThreshold` undefined, and `usage < undefined` is
|
|
1292
|
+
// false: the pass ran on every iteration and the salience strategy fell
|
|
1293
|
+
// through to the stale-result clearing it exists to replace. The eval
|
|
1294
|
+
// suite that passed exactly that object found it.
|
|
1295
|
+
const compactionConfig = params.compactionConfig
|
|
1296
|
+
? CompactionConfigSchema.parse(params.compactionConfig)
|
|
1297
|
+
: undefined
|
|
1298
|
+
if (compactionConfig && compactionConfig.strategy !== 'disabled') {
|
|
1299
|
+
workingStateManager = new WorkingStateManager(compactionConfig)
|
|
1300
|
+
toolExecutor.setWorkingStateManager(workingStateManager)
|
|
1301
|
+
}
|
|
1247
1302
|
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
costLimitUsd: runConfig.costLimitUsd,
|
|
1252
|
-
maxIterations: runConfig.maxIterations,
|
|
1253
|
-
})
|
|
1303
|
+
// The turn's own registry when the host passed none, so a hook's
|
|
1304
|
+
// annotation has somewhere to land.
|
|
1305
|
+
const promptContributions = params.promptContributions ?? new PromptContributionRegistry()
|
|
1254
1306
|
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1307
|
+
const promptBuilder = new PromptBuilder({
|
|
1308
|
+
systemPrompt: params.systemPrompt,
|
|
1309
|
+
persona: params.persona,
|
|
1310
|
+
skills: params.skills,
|
|
1311
|
+
basePrompt: params.basePrompt,
|
|
1312
|
+
tools: params.tools,
|
|
1313
|
+
allowedTools: effectiveAllowedTools,
|
|
1314
|
+
runtimeContext: params.runtimeContext,
|
|
1315
|
+
contributions: promptContributions,
|
|
1316
|
+
})
|
|
1259
1317
|
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
const manager = workingStateManager
|
|
1267
|
-
checkpointMgr.setWorkingStateSource(() => snapshotWorkingState(manager))
|
|
1268
|
-
}
|
|
1318
|
+
const guard = new GuardCoordinator({
|
|
1319
|
+
tokenBudget: turnConfig.tokenBudget,
|
|
1320
|
+
timeoutMs: turnConfig.timeoutMs,
|
|
1321
|
+
costLimitUsd: turnConfig.costLimitUsd,
|
|
1322
|
+
maxIterations: turnConfig.maxIterations,
|
|
1323
|
+
})
|
|
1269
1324
|
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
drainPending: () => eventTranslator.drainPending(),
|
|
1277
|
-
// Read at settle time, not now: checkpoints are written per
|
|
1278
|
-
// iteration, so the answer changes as the run proceeds.
|
|
1279
|
-
resumeCheckpointId: () => checkpointMgr.lastCheckpointId,
|
|
1280
|
-
// Read only to recover WHY a cancellation happened. The run loop
|
|
1281
|
-
// already knows THAT it was cancelled; the origin lives on the abort
|
|
1282
|
-
// reason and nothing else carries it this far.
|
|
1283
|
-
signal: ctx.abortController.signal,
|
|
1284
|
-
})
|
|
1325
|
+
const checkpointMgr = new CheckpointManager(ctx.recorder, ctx.storage.checkpoints, {
|
|
1326
|
+
tenantId: ctx.tenantId,
|
|
1327
|
+
projectId: ctx.projectId,
|
|
1328
|
+
sessionId: ctx.sessionId,
|
|
1329
|
+
turnId: ctx.turnId,
|
|
1330
|
+
})
|
|
1285
1331
|
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
//
|
|
1289
|
-
//
|
|
1290
|
-
//
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
const boundedAdvisors = params.advisory.advisors.map((advisor) => ({
|
|
1296
|
-
...advisor,
|
|
1297
|
-
provider: withTokenBudget(
|
|
1298
|
-
withStreamIdleTimeout(advisor.provider, {
|
|
1299
|
-
idleTimeoutMs: streamIdleTimeoutMs,
|
|
1300
|
-
log: ctx.log,
|
|
1301
|
-
}),
|
|
1302
|
-
budget,
|
|
1303
|
-
),
|
|
1304
|
-
}))
|
|
1305
|
-
const advisorRegistry = new AdvisorRegistry(boundedAdvisors, params.advisory.defaultAdvisorId)
|
|
1306
|
-
// A budget the runtime cannot measure is refused here rather than
|
|
1307
|
-
// silently ignored for the length of the run.
|
|
1308
|
-
assertBudgetEnforceable(params.advisory)
|
|
1309
|
-
const advisoryExecutor = new AdvisoryExecutor(
|
|
1310
|
-
ctx.log,
|
|
1311
|
-
params.advisory.budget,
|
|
1312
|
-
ctx.abortController.signal,
|
|
1313
|
-
)
|
|
1314
|
-
const triggerEvaluator = new TriggerEvaluator(
|
|
1315
|
-
params.advisory.triggers ?? [],
|
|
1316
|
-
params.advisory.budget,
|
|
1317
|
-
)
|
|
1318
|
-
advisoryCtx = new AdvisoryContext(
|
|
1319
|
-
advisorRegistry,
|
|
1320
|
-
advisoryExecutor,
|
|
1321
|
-
triggerEvaluator,
|
|
1322
|
-
params.advisory.budget,
|
|
1323
|
-
)
|
|
1332
|
+
// Every checkpoint carries compaction's accumulated state, so a turn that
|
|
1333
|
+
// comes back in a new process can adopt it (see the restore block).
|
|
1334
|
+
// Without it, compaction's own justification for dropping the prior
|
|
1335
|
+
// `[COMPACTED CONTEXT]` block — that `serializeState` is cumulative —
|
|
1336
|
+
// holds within one process and fails across a resume.
|
|
1337
|
+
if (workingStateManager) {
|
|
1338
|
+
const manager = workingStateManager
|
|
1339
|
+
checkpointMgr.setWorkingStateSource(() => snapshotWorkingState(manager))
|
|
1340
|
+
}
|
|
1324
1341
|
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
...(summary !== undefined ? { workingStateSummary: summary } : {}),
|
|
1344
|
-
...(advisoryConfig.includeToolCatalog
|
|
1345
|
-
? { toolCatalog: params.tools.toLLMTools(effectiveAllowedTools) }
|
|
1346
|
-
: {}),
|
|
1347
|
-
iteration: ctx.runMgr.currentIteration,
|
|
1348
|
-
}
|
|
1342
|
+
const resultAssembler = new ResultAssembler({
|
|
1343
|
+
recorder: ctx.recorder,
|
|
1344
|
+
planManager: ctx.planManager,
|
|
1345
|
+
activityStore: ctx.activityStore,
|
|
1346
|
+
log: ctx.log,
|
|
1347
|
+
emitEvent: eventTranslator.emitEvent,
|
|
1348
|
+
drainPending: () => eventTranslator.drainPending(),
|
|
1349
|
+
// Read at settle time, not now: checkpoints are written per
|
|
1350
|
+
// iteration, so the answer changes as the turn proceeds. A turn
|
|
1351
|
+
// that fails before writing one (a 429 on its first request)
|
|
1352
|
+
// commits the state its loop began from, so it pauses like any
|
|
1353
|
+
// later failure rather than failing with nothing to resume.
|
|
1354
|
+
resumeCheckpointId: async () =>
|
|
1355
|
+
checkpointMgr.lastCheckpointId ?? (await checkpointMgr.createAtLoopStart(ctx.recorder))?.id,
|
|
1356
|
+
// Read only to recover WHY a cancellation happened. The turn loop
|
|
1357
|
+
// already knows THAT it was cancelled; the origin lives on the abort
|
|
1358
|
+
// reason and nothing else carries it this far.
|
|
1359
|
+
signal: ctx.abortController.signal,
|
|
1349
1360
|
})
|
|
1350
1361
|
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1362
|
+
let advisoryCtx: AdvisoryContext | undefined
|
|
1363
|
+
if (params.advisory && params.advisory.advisors.length > 0) {
|
|
1364
|
+
// Advisors are model calls owned by this turn even when they use a
|
|
1365
|
+
// different provider. Sending the raw definitions into the registry
|
|
1366
|
+
// lets a triggered or model-requested consultation bypass both the
|
|
1367
|
+
// finite stream-silence bound and Stop. Bind every advisor provider at
|
|
1368
|
+
// the query boundary, where the effective timeout and run signal are
|
|
1369
|
+
// already known; standalone AdvisoryExecutor callers retain their
|
|
1370
|
+
// explicitly chosen provider/cancellation policy.
|
|
1371
|
+
const boundedAdvisors = params.advisory.advisors.map((advisor) => ({
|
|
1372
|
+
...advisor,
|
|
1373
|
+
provider: withTokenBudget(
|
|
1374
|
+
withStreamIdleTimeout(advisor.provider, {
|
|
1375
|
+
idleTimeoutMs: streamIdleTimeoutMs,
|
|
1376
|
+
log: ctx.log,
|
|
1377
|
+
}),
|
|
1378
|
+
budget,
|
|
1379
|
+
),
|
|
1380
|
+
}))
|
|
1381
|
+
const advisorRegistry = new AdvisorRegistry(boundedAdvisors, params.advisory.defaultAdvisorId)
|
|
1382
|
+
// A budget the runtime cannot measure is refused here rather than
|
|
1383
|
+
// silently ignored for the length of the turn.
|
|
1384
|
+
assertBudgetEnforceable(params.advisory)
|
|
1385
|
+
const advisoryExecutor = new AdvisoryExecutor(
|
|
1386
|
+
ctx.log,
|
|
1387
|
+
params.advisory.budget,
|
|
1388
|
+
ctx.abortController.signal,
|
|
1389
|
+
)
|
|
1390
|
+
const triggerEvaluator = new TriggerEvaluator(
|
|
1391
|
+
params.advisory.triggers ?? [],
|
|
1392
|
+
params.advisory.budget,
|
|
1393
|
+
)
|
|
1394
|
+
advisoryCtx = new AdvisoryContext(
|
|
1395
|
+
advisorRegistry,
|
|
1396
|
+
advisoryExecutor,
|
|
1397
|
+
triggerEvaluator,
|
|
1398
|
+
params.advisory.budget,
|
|
1399
|
+
)
|
|
1400
|
+
|
|
1401
|
+
// What the turn looks like when the MODEL consults an advisor, as
|
|
1402
|
+
// opposed to when a trigger does. The trigger path has always passed
|
|
1403
|
+
// this; the tool path passed an empty context, so an advisor the model
|
|
1404
|
+
// asked for help saw the question and nothing else.
|
|
1405
|
+
//
|
|
1406
|
+
// `includeToolCatalog` and `useCompactedContext` are read here and
|
|
1407
|
+
// nowhere else. Both were declared on `AdvisoryConfig` /
|
|
1408
|
+
// `AdvisorDefinition` and consulted by nothing, so a host who turned
|
|
1409
|
+
// the catalogue off still paid for it in every advisory prompt.
|
|
1410
|
+
const advisoryConfig = params.advisory
|
|
1411
|
+
advisoryCtx.setCallContextProvider(() => {
|
|
1412
|
+
const summary =
|
|
1413
|
+
workingStateManager && advisoryConfig.advisors.some((a) => a.useCompactedContext)
|
|
1414
|
+
? serializeWorkingState(workingStateManager.getState())
|
|
1415
|
+
: undefined
|
|
1416
|
+
return {
|
|
1417
|
+
messages: ctx.recorder.messages,
|
|
1418
|
+
turn: iterationOrchestrator.getAdvisoryTurnContext(),
|
|
1419
|
+
...(summary !== undefined ? { workingStateSummary: summary } : {}),
|
|
1420
|
+
...(advisoryConfig.includeToolCatalog
|
|
1421
|
+
? { toolCatalog: params.tools.toLLMTools(effectiveAllowedTools) }
|
|
1422
|
+
: {}),
|
|
1423
|
+
iteration: ctx.recorder.currentIteration,
|
|
1424
|
+
}
|
|
1425
|
+
})
|
|
1426
|
+
|
|
1427
|
+
if (params.advisory.enableAgentTool) {
|
|
1428
|
+
const advisoryTools = buildAdvisoryTools({ advisoryCtx })
|
|
1429
|
+
const overrides = params.runtimeToolOverrides
|
|
1430
|
+
for (const tool of advisoryTools) {
|
|
1431
|
+
const override = overrides?.[tool.name]
|
|
1432
|
+
if (override === 'disabled') continue
|
|
1433
|
+
params.tools.register(tool, override ?? 'active')
|
|
1434
|
+
}
|
|
1358
1435
|
}
|
|
1359
1436
|
}
|
|
1360
|
-
}
|
|
1361
1437
|
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
? {
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
? {
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
resilientProvider,
|
|
1438
|
+
const iterationOrchestrator = new IterationOrchestrator({
|
|
1439
|
+
captureSessionEvidence,
|
|
1440
|
+
provider: resilientProvider,
|
|
1441
|
+
providerCapabilities: capabilities,
|
|
1442
|
+
strictCapabilities: params.strictCapabilities === true,
|
|
1443
|
+
servingMember: () => serving.current,
|
|
1444
|
+
turnConfig,
|
|
1445
|
+
...(params.stopWhen ? { stopWhen: params.stopWhen } : {}),
|
|
1446
|
+
...(params.prepareStep ? { prepareStep: params.prepareStep } : {}),
|
|
1447
|
+
...(params.beforeStep ? { beforeStep: params.beforeStep } : {}),
|
|
1448
|
+
...(params.onStepFinish ? { onStepFinish: params.onStepFinish } : {}),
|
|
1449
|
+
...(params.reviewAnswer ? { reviewAnswer: params.reviewAnswer } : {}),
|
|
1450
|
+
...(params.maxAnswerReviews !== undefined
|
|
1451
|
+
? { maxAnswerReviews: params.maxAnswerReviews }
|
|
1452
|
+
: {}),
|
|
1453
|
+
...(params.structuredOutput ? { structuredOutput: params.structuredOutput } : {}),
|
|
1454
|
+
...(params.parkRecordDelayMs !== undefined
|
|
1455
|
+
? { parkRecordDelayMs: params.parkRecordDelayMs }
|
|
1456
|
+
: {}),
|
|
1457
|
+
tools: params.tools,
|
|
1458
|
+
allowedTools: effectiveAllowedTools,
|
|
1459
|
+
recorder: ctx.recorder,
|
|
1460
|
+
toolExecutor,
|
|
1461
|
+
guard,
|
|
1462
|
+
activityStore: ctx.activityStore,
|
|
1463
|
+
emitEvent: eventTranslator.emitEvent,
|
|
1464
|
+
drainPending: () => eventTranslator.drainPending(),
|
|
1465
|
+
abortController: ctx.abortController,
|
|
1466
|
+
log: ctx.log,
|
|
1467
|
+
// Read through the box on every call, so a swap lands on the next
|
|
1468
|
+
// question rather than the next turn.
|
|
1469
|
+
resumeHandler: (request) => approvalPolicy.current.handler(request),
|
|
1470
|
+
takeApprovalPolicyChange: () => approvalPolicy.takeUnannouncedChange(),
|
|
1471
|
+
promptContributions,
|
|
1472
|
+
...(params.steering ? { steering: params.steering } : {}),
|
|
1473
|
+
...(jobNotices ? { jobNotices } : {}),
|
|
1474
|
+
...(awaitedJobs ? { awaitedJobs } : {}),
|
|
1475
|
+
checkpointMgr,
|
|
1476
|
+
planManager: ctx.planManager,
|
|
1477
|
+
taskGateway: taskScheduler,
|
|
1478
|
+
completionInbox: params.completionInbox,
|
|
1479
|
+
taskStore: params.taskStore,
|
|
1480
|
+
// Turn-scoped. An approval is a statement about this turn's work;
|
|
1481
|
+
// carrying one into a later turn would be reuse nobody agreed to.
|
|
1482
|
+
toolGrants: new ToolGrantSet(),
|
|
1483
|
+
// Turn-scoped for the same reason. A repeat count carried into a later
|
|
1484
|
+
// run is a claim about work nobody repeated, and a module-level map
|
|
1485
|
+
// would leak exactly that way.
|
|
1486
|
+
...(params.repeatCallAdvisory === false ? {} : { repeatCalls: new RepeatCallTracker() }),
|
|
1487
|
+
compactionConfig,
|
|
1488
|
+
...(params.inboundMessages ? { inboundMessages: params.inboundMessages } : {}),
|
|
1489
|
+
...(params.resumeFromCheckpoint ? { resumedInput: queuedForThisRun } : {}),
|
|
1490
|
+
...(params.waitForInbound ? { waitForInbound: params.waitForInbound } : {}),
|
|
1491
|
+
...(params.projectInstructionContext
|
|
1492
|
+
? { projectInstructionContext: params.projectInstructionContext }
|
|
1493
|
+
: {}),
|
|
1494
|
+
...(providerContextWindow !== undefined ? { providerContextWindow } : {}),
|
|
1495
|
+
resolveModelContextWindow: async (model) => {
|
|
1496
|
+
if (!modelContextWindows.has(model)) {
|
|
1497
|
+
modelContextWindows.set(
|
|
1423
1498
|
model,
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
workingStateManager,
|
|
1433
|
-
taskRouter: params.taskRouter,
|
|
1434
|
-
contextReducer: params.contextReducer,
|
|
1435
|
-
workingMemoryProvider: params.workingMemoryProvider,
|
|
1436
|
-
advisoryCtx,
|
|
1437
|
-
agentBus: params.agentBus,
|
|
1438
|
-
verificationGate,
|
|
1439
|
-
pluginManager: params.pluginManager,
|
|
1440
|
-
})
|
|
1441
|
-
|
|
1442
|
-
const tracer = getTracer()
|
|
1443
|
-
|
|
1444
|
-
// Whether the run reached its settle. Read by the `finally` below, and
|
|
1445
|
-
// the only thing that distinguishes a run that finished from one whose
|
|
1446
|
-
// consumer walked away — see `settleAbandonedRun`.
|
|
1447
|
-
let settled = false
|
|
1448
|
-
|
|
1449
|
-
const runBody = (async function* (): AsyncGenerator<RunEvent, Run> {
|
|
1450
|
-
// Parent explicitly when a caller supplied one. Without this every
|
|
1451
|
-
// run starts its OWN root trace, so a supervisor delegating to three
|
|
1452
|
-
// children produced four disconnected traces instead of one tree —
|
|
1453
|
-
// the same defect that made a 20-turn run show up as 21 roots before
|
|
1454
|
-
// iterations were parented, except across the spawn boundary, where
|
|
1455
|
-
// it is worse: the delegation structure is the thing you most want
|
|
1456
|
-
// to see.
|
|
1457
|
-
const runStartedAt = Date.now()
|
|
1458
|
-
|
|
1459
|
-
// Read before the span is minted, because a parent can only be set
|
|
1460
|
-
// at creation. A resumed run used to start a brand-new trace with no
|
|
1461
|
-
// link to the one that crashed, so the failure and its recovery
|
|
1462
|
-
// could not be put on one timeline — the run id correlated them well
|
|
1463
|
-
// enough to find both by query and not well enough to see a single
|
|
1464
|
-
// waterfall, and for a replay fork (which mints a new run id) not
|
|
1465
|
-
// even that. An explicit caller-supplied parent still wins: it is
|
|
1466
|
-
// the more specific statement about where this run belongs.
|
|
1467
|
-
const resumedTrace = selectedResumeState
|
|
1468
|
-
? selectedResumeState.traceContext
|
|
1469
|
-
: params.resumeFromCheckpoint
|
|
1470
|
-
? await checkpointMgr.readTraceContext(params.resumeFromCheckpoint)
|
|
1471
|
-
: undefined
|
|
1472
|
-
|
|
1473
|
-
const rootSpan = tracer.startSpan(
|
|
1474
|
-
agentRunSpanName(params.agentName),
|
|
1475
|
-
{},
|
|
1476
|
-
parentContext(params.parentSpan ?? resumedTrace),
|
|
1477
|
-
)
|
|
1478
|
-
// Hand the run span to the loop so every iteration parents to it.
|
|
1479
|
-
iterationOrchestrator.setRootSpan(rootSpan)
|
|
1480
|
-
// Every checkpoint from here on records the trace it was taken
|
|
1481
|
-
// inside, so the next resume can join this one.
|
|
1482
|
-
checkpointMgr.setTraceSource(() => serializeSpan(rootSpan))
|
|
1483
|
-
// And every park it records carries an absolute deadline, so an
|
|
1484
|
-
// unanswered approval cannot outlive the worker that asked for it.
|
|
1485
|
-
checkpointMgr.setParkTtl(runConfig.hitlParkTtlMs)
|
|
1486
|
-
// The claim this worker holds, if it took one. Without this hop the
|
|
1487
|
-
// fence exists, the refusal exists, and no checkpoint a RUN writes ever
|
|
1488
|
-
// carries a number — so a stalled worker is refused nowhere.
|
|
1489
|
-
checkpointMgr.setClaimFence(params.claimFence)
|
|
1490
|
-
// A question raised from inside a tool becomes a real checkpoint
|
|
1491
|
-
// here. It used to park under a synthetic id nothing ever wrote, so
|
|
1492
|
-
// the checkpoint did not exist: nothing on disk said a human owed
|
|
1493
|
-
// this run an answer, and a remote host could not observe the
|
|
1494
|
-
// question at all.
|
|
1495
|
-
questionParks.bind({
|
|
1496
|
-
record: async (question) => {
|
|
1497
|
-
try {
|
|
1498
|
-
const checkpoint = await checkpointMgr.create(ctx.runMgr, ctx.runMgr.currentIteration)
|
|
1499
|
-
const parked = await checkpointMgr.park(checkpoint, {
|
|
1500
|
-
type: 'user_question',
|
|
1501
|
-
runId: ctx.runMgr.id,
|
|
1502
|
-
checkpointId: checkpoint.id,
|
|
1503
|
-
question,
|
|
1504
|
-
})
|
|
1505
|
-
await eventTranslator.emitEvent({
|
|
1506
|
-
type: 'user_question_asked',
|
|
1507
|
-
runId: ctx.runMgr.id,
|
|
1508
|
-
checkpointId: parked.id,
|
|
1509
|
-
questionId: question.questionId,
|
|
1510
|
-
question: question.question,
|
|
1511
|
-
})
|
|
1512
|
-
return parked.id
|
|
1513
|
-
} catch (err) {
|
|
1514
|
-
// A store that cannot record the park must not take the
|
|
1515
|
-
// tool down with it: the in-process await is still valid
|
|
1516
|
-
// and only the cross-process handoff is lost. Loudly,
|
|
1517
|
-
// because a host building an approval queue from durable
|
|
1518
|
-
// state will not see this question.
|
|
1519
|
-
ctx.log.error('Failed to record a question park — it is not resumable', {
|
|
1520
|
-
[NAMZU.RUN_ID]: ctx.runMgr.id,
|
|
1521
|
-
'namzu.runtime.question_id': question.questionId,
|
|
1522
|
-
'exception.message': err instanceof Error ? err.message : String(err),
|
|
1523
|
-
})
|
|
1524
|
-
return null
|
|
1499
|
+
await resolveProviderContextWindow(
|
|
1500
|
+
resilientProvider,
|
|
1501
|
+
model,
|
|
1502
|
+
ctx.abortController.signal,
|
|
1503
|
+
turnConfig.timeoutMs,
|
|
1504
|
+
log,
|
|
1505
|
+
),
|
|
1506
|
+
)
|
|
1525
1507
|
}
|
|
1508
|
+
return modelContextWindows.get(model)
|
|
1526
1509
|
},
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
})
|
|
1536
|
-
await eventTranslator.emitEvent({
|
|
1537
|
-
type: 'user_question_answered',
|
|
1538
|
-
runId: ctx.runMgr.id,
|
|
1539
|
-
checkpointId,
|
|
1540
|
-
...(decision.action === 'answer_question' && decision.questionId !== undefined
|
|
1541
|
-
? { questionId: decision.questionId }
|
|
1542
|
-
: {}),
|
|
1543
|
-
answered: decision.action === 'answer_question',
|
|
1544
|
-
})
|
|
1545
|
-
},
|
|
1546
|
-
})
|
|
1547
|
-
rootSpan.setAttributes({
|
|
1548
|
-
[NAMZU.RUN_ID]: ctx.runMgr.id,
|
|
1549
|
-
[GENAI.AGENT_NAME]: params.agentName,
|
|
1550
|
-
[GENAI.AGENT_ID]: params.agentId,
|
|
1551
|
-
[GENAI.REQUEST_MODEL]: runConfig.model,
|
|
1552
|
-
[GENAI.SYSTEM]: params.provider.id,
|
|
1510
|
+
workingStateManager,
|
|
1511
|
+
taskRouter: params.taskRouter,
|
|
1512
|
+
contextReducer: params.contextReducer,
|
|
1513
|
+
workingMemoryProvider: params.workingMemoryProvider,
|
|
1514
|
+
advisoryCtx,
|
|
1515
|
+
agentBus: params.agentBus,
|
|
1516
|
+
verificationGate,
|
|
1517
|
+
pluginManager: params.pluginManager,
|
|
1553
1518
|
})
|
|
1554
1519
|
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
//
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1520
|
+
const tracer = getTracer()
|
|
1521
|
+
|
|
1522
|
+
// Whether the turn reached its settle. Read by the `finally` below, and
|
|
1523
|
+
// the only thing that distinguishes a turn that finished from one whose
|
|
1524
|
+
// consumer walked away — see `settleAbandonedTurn`.
|
|
1525
|
+
let settled = false
|
|
1526
|
+
|
|
1527
|
+
const runBody = (async function* (): AsyncGenerator<SessionEvent, Turn> {
|
|
1528
|
+
// Parent explicitly when a caller supplied one. Without this every
|
|
1529
|
+
// run starts its OWN root trace, so a supervisor delegating to three
|
|
1530
|
+
// children produced four disconnected traces instead of one tree —
|
|
1531
|
+
// the same defect that made a 20-turn run show up as 21 roots before
|
|
1532
|
+
// iterations were parented, except across the spawn boundary, where
|
|
1533
|
+
// it is worse: the delegation structure is the thing you most want
|
|
1534
|
+
// to see.
|
|
1535
|
+
const runStartedAt = Date.now()
|
|
1536
|
+
|
|
1537
|
+
// Read before the span is minted, because a parent can only be set
|
|
1538
|
+
// at creation. A resumed turn used to start a brand-new trace with no
|
|
1539
|
+
// link to the one that crashed, so the failure and its recovery
|
|
1540
|
+
// could not be put on one timeline — the turn id correlated them well
|
|
1541
|
+
// enough to find both by query and not well enough to see a single
|
|
1542
|
+
// waterfall, and for a replay fork (which mints a new turn id) not
|
|
1543
|
+
// even that. An explicit caller-supplied parent still wins: it is
|
|
1544
|
+
// the more specific statement about where this turn belongs.
|
|
1545
|
+
const resumedTrace = selectedResumeState
|
|
1546
|
+
? selectedResumeState.traceContext
|
|
1547
|
+
: params.resumeFromCheckpoint
|
|
1548
|
+
? await checkpointMgr.readTraceContext(params.resumeFromCheckpoint)
|
|
1549
|
+
: undefined
|
|
1567
1550
|
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
//
|
|
1574
|
-
|
|
1575
|
-
//
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1551
|
+
const rootSpan = tracer.startSpan(
|
|
1552
|
+
agentTurnSpanName(params.agentName),
|
|
1553
|
+
{},
|
|
1554
|
+
parentContext(params.parentSpan ?? resumedTrace),
|
|
1555
|
+
)
|
|
1556
|
+
// Hand the turn span to the loop so every iteration parents to it.
|
|
1557
|
+
iterationOrchestrator.setRootSpan(rootSpan)
|
|
1558
|
+
// Every checkpoint from here on records the trace it was taken
|
|
1559
|
+
// inside, so the next resume can join this one.
|
|
1560
|
+
checkpointMgr.setTraceSource(() => serializeSpan(rootSpan))
|
|
1561
|
+
// And every park it records carries an absolute deadline, so an
|
|
1562
|
+
// unanswered approval cannot outlive the worker that asked for it.
|
|
1563
|
+
checkpointMgr.setParkTtl(turnConfig.hitlParkTtlMs)
|
|
1564
|
+
// A question raised from inside a tool becomes a real checkpoint
|
|
1565
|
+
// here. It used to park under a synthetic id nothing ever wrote, so
|
|
1566
|
+
// the checkpoint did not exist: nothing on disk said a human owed
|
|
1567
|
+
// this turn an answer, and a remote host could not observe the
|
|
1568
|
+
// question at all.
|
|
1569
|
+
questionParks.bind({
|
|
1570
|
+
record: async (question) => {
|
|
1571
|
+
try {
|
|
1572
|
+
const checkpoint = await checkpointMgr.create(
|
|
1573
|
+
ctx.recorder,
|
|
1574
|
+
ctx.recorder.currentIteration,
|
|
1575
|
+
)
|
|
1576
|
+
await checkpointMgr.park(checkpoint, {
|
|
1577
|
+
type: 'user_question',
|
|
1578
|
+
sessionId: ctx.sessionId,
|
|
1579
|
+
turnId: ctx.turnId,
|
|
1580
|
+
checkpointId: checkpoint.id,
|
|
1581
|
+
question,
|
|
1585
1582
|
})
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
const annotations = applyLifecycleHookResults('user_prompt_submit', hookResults)
|
|
1616
|
-
if (annotations.length > 0) {
|
|
1617
|
-
promptContributions.replace({
|
|
1618
|
-
id: 'hooks:user_prompt_submit',
|
|
1619
|
-
placement: 'dynamic',
|
|
1620
|
-
render: () => `Context from the operator's hooks:\n\n${annotations.join('\n\n')}`,
|
|
1583
|
+
await eventTranslator.emitEvent({
|
|
1584
|
+
type: 'user_question_asked',
|
|
1585
|
+
checkpointId: checkpoint.id,
|
|
1586
|
+
questionId: question.questionId,
|
|
1587
|
+
question: question.question,
|
|
1588
|
+
})
|
|
1589
|
+
return checkpoint.id
|
|
1590
|
+
} catch (err) {
|
|
1591
|
+
// A store that cannot record the park must not take the
|
|
1592
|
+
// tool down with it: the in-process await is still valid
|
|
1593
|
+
// and only the cross-process handoff is lost. Loudly,
|
|
1594
|
+
// because a host building an approval queue from durable
|
|
1595
|
+
// state will not see this question.
|
|
1596
|
+
ctx.log.error('Failed to record a question park — it is not resumable', {
|
|
1597
|
+
[NAMZU.TURN_ID]: ctx.recorder.turnId,
|
|
1598
|
+
'namzu.runtime.question_id': question.questionId,
|
|
1599
|
+
'exception.message': err instanceof Error ? err.message : String(err),
|
|
1600
|
+
})
|
|
1601
|
+
return null
|
|
1602
|
+
}
|
|
1603
|
+
},
|
|
1604
|
+
resolve: async (checkpointId, decision) => {
|
|
1605
|
+
await checkpointMgr.unpark(checkpointId, decision).catch((err: unknown) => {
|
|
1606
|
+
ctx.log.error('Failed to clear a recorded question park', {
|
|
1607
|
+
[NAMZU.TURN_ID]: ctx.recorder.turnId,
|
|
1608
|
+
'namzu.checkpoint.id': checkpointId,
|
|
1609
|
+
'exception.message': err instanceof Error ? err.message : String(err),
|
|
1610
|
+
})
|
|
1611
|
+
return null
|
|
1621
1612
|
})
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
:
|
|
1641
|
-
|
|
1642
|
-
ctx.log.info('Prompt segments assembled', {
|
|
1643
|
-
'namzu.runtime.static_length': segments.static.length,
|
|
1644
|
-
'namzu.runtime.dynamic_length': segments.dynamic.length,
|
|
1613
|
+
await eventTranslator.emitEvent({
|
|
1614
|
+
type: 'user_question_answered',
|
|
1615
|
+
checkpointId,
|
|
1616
|
+
...(decision.action === 'answer_question' && decision.questionId !== undefined
|
|
1617
|
+
? { questionId: decision.questionId }
|
|
1618
|
+
: {}),
|
|
1619
|
+
answered: decision.action === 'answer_question',
|
|
1620
|
+
})
|
|
1621
|
+
},
|
|
1622
|
+
})
|
|
1623
|
+
rootSpan.setAttributes({
|
|
1624
|
+
[GENAI.CONVERSATION_ID]: ctx.sessionId,
|
|
1625
|
+
[NAMZU.TURN_ID]: ctx.recorder.turnId,
|
|
1626
|
+
...(params.parentSessionId !== undefined && {
|
|
1627
|
+
[NAMZU.SESSION_PARENT_ID]: params.parentSessionId,
|
|
1628
|
+
}),
|
|
1629
|
+
[GENAI.AGENT_NAME]: params.agentName,
|
|
1630
|
+
[GENAI.AGENT_ID]: params.agentId,
|
|
1631
|
+
[GENAI.REQUEST_MODEL]: turnConfig.model,
|
|
1632
|
+
[GENAI.SYSTEM]: params.provider.id,
|
|
1645
1633
|
})
|
|
1646
1634
|
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1635
|
+
let sandbox: Sandbox | undefined
|
|
1636
|
+
// Decided during checkpoint restore, executed after the sandbox
|
|
1637
|
+
// exists — the approved tools may well need it.
|
|
1638
|
+
let pendingResume: PendingResumePlan | null = null
|
|
1639
|
+
/** The record id of the parked assistant message the plan re-appends. */
|
|
1640
|
+
let pendingResumeAssistantId: MessageId | undefined
|
|
1641
|
+
/**
|
|
1642
|
+
* The cadence park this resume answered, when the decision is one the
|
|
1643
|
+
* ordinary continue path carries out. See the restore path below.
|
|
1644
|
+
*/
|
|
1645
|
+
let answeredParkId: CheckpointId | undefined
|
|
1646
|
+
/** Tool results recovered from the transcript; see the restore path. */
|
|
1647
|
+
let recoveredResults: ReadonlyMap<string, { result: string; isError: boolean }> = new Map()
|
|
1648
|
+
|
|
1649
|
+
try {
|
|
1650
|
+
// A consumer coming back gets what it missed BEFORE the turn says
|
|
1651
|
+
// anything new, which is the only order that lets it fold one
|
|
1652
|
+
// stream into one state. It follows the prelude's `open()` — which
|
|
1653
|
+
// took the lease and read the log's head — and precedes every emit
|
|
1654
|
+
// below.
|
|
1655
|
+
if (params.eventCursor) {
|
|
1656
|
+
yield* catchUpFromCursor(
|
|
1657
|
+
ctx.recorder,
|
|
1658
|
+
params.eventCursor,
|
|
1659
|
+
params.onEventReplay,
|
|
1660
|
+
(error) => {
|
|
1661
|
+
ctx.log.warn('Replay observer failed', {
|
|
1662
|
+
'exception.message': toErrorMessage(error),
|
|
1663
|
+
})
|
|
1664
|
+
},
|
|
1665
|
+
)
|
|
1651
1666
|
}
|
|
1652
|
-
}
|
|
1653
1667
|
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
await eventTranslator.emitEvent({
|
|
1663
|
-
type: 'run_resuming',
|
|
1664
|
-
runId: ctx.runMgr.id,
|
|
1665
|
-
fromCheckpointId: checkpoint.id,
|
|
1668
|
+
ctx.log.info('Starting query', {
|
|
1669
|
+
[NAMZU.TURN_ID]: ctx.recorder.turnId,
|
|
1670
|
+
'namzu.runtime.agent': params.agentName,
|
|
1671
|
+
[GENAI.REQUEST_MODEL]: turnConfig.model,
|
|
1672
|
+
'namzu.runtime.token_budget': turnConfig.tokenBudget,
|
|
1673
|
+
'namzu.runtime.activity_tracking': ctx.activityStore.enabled,
|
|
1674
|
+
'namzu.runtime.permission_mode': ctx.permissionMode.current,
|
|
1675
|
+
'namzu.runtime.resume_from_checkpoint': params.resumeFromCheckpoint ?? null,
|
|
1666
1676
|
})
|
|
1667
|
-
yield* eventTranslator.drainPending()
|
|
1668
1677
|
|
|
1669
|
-
//
|
|
1670
|
-
// it
|
|
1671
|
-
//
|
|
1672
|
-
//
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
[NAMZU.RUN_ID]: ctx.runMgr.id,
|
|
1694
|
-
'namzu.checkpoint.id': checkpoint.id,
|
|
1695
|
-
'namzu.runtime.slots': workingStateManager.slotCount(),
|
|
1696
|
-
})
|
|
1678
|
+
// The operator's prompt, before the model sees it. A hook may
|
|
1679
|
+
// refuse it — the turn ends here, before a prompt is built — or add
|
|
1680
|
+
// to what the model is told; the addition rides the prompt as a
|
|
1681
|
+
// dynamic contribution so every iteration of the turn carries it.
|
|
1682
|
+
if (params.pluginManager) {
|
|
1683
|
+
const hookResults = await params.pluginManager.executeHooks(
|
|
1684
|
+
'user_prompt_submit',
|
|
1685
|
+
{
|
|
1686
|
+
turnId: ctx.turnId,
|
|
1687
|
+
sessionId: params.sessionId,
|
|
1688
|
+
prompt: lastUserPrompt(initialMessages),
|
|
1689
|
+
signal: ctx.abortController.signal,
|
|
1690
|
+
},
|
|
1691
|
+
eventTranslator.emitEvent,
|
|
1692
|
+
)
|
|
1693
|
+
const annotations = applyLifecycleHookResults('user_prompt_submit', hookResults)
|
|
1694
|
+
if (annotations.length > 0) {
|
|
1695
|
+
promptContributions.replace({
|
|
1696
|
+
id: 'hooks:user_prompt_submit',
|
|
1697
|
+
placement: 'dynamic',
|
|
1698
|
+
render: () => `Context from the operator's hooks:\n\n${annotations.join('\n\n')}`,
|
|
1699
|
+
})
|
|
1700
|
+
}
|
|
1701
|
+
yield* eventTranslator.drainPending()
|
|
1697
1702
|
}
|
|
1698
|
-
ctx.log.info('Restored budgets from checkpoint', {
|
|
1699
|
-
[NAMZU.RUN_ID]: ctx.runMgr.id,
|
|
1700
|
-
'namzu.checkpoint.id': checkpoint.id,
|
|
1701
|
-
'namzu.usage.total_tokens': checkpoint.tokenUsage.totalTokens,
|
|
1702
|
-
'namzu.runtime.total_cost': checkpoint.costInfo.totalCost,
|
|
1703
|
-
[NAMZU.ITERATION]: checkpoint.guardState.iterationCount,
|
|
1704
|
-
'namzu.runtime.elapsed_ms': checkpoint.guardState.elapsedMs,
|
|
1705
|
-
})
|
|
1706
|
-
|
|
1707
|
-
pushSystemMessages()
|
|
1708
|
-
|
|
1709
|
-
// A human answered the park in a different process; apply that
|
|
1710
|
-
// answer to the tool calls they were actually shown. Without
|
|
1711
|
-
// this the repair below throws the approval away and the model
|
|
1712
|
-
// re-decides, so "yes, delete that row" degrades into "ask
|
|
1713
|
-
// again and hope it asks for the same thing".
|
|
1714
|
-
pendingResume =
|
|
1715
|
-
params.pendingDecision && projectedCheckpoint.pending
|
|
1716
|
-
? planPendingResume(projectedCheckpoint, params.pendingDecision, ctx.log)
|
|
1717
|
-
: null
|
|
1718
1703
|
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
// so a second resume of the finished run was refused with
|
|
1731
|
-
// `awaiting-decision` for a decision already taken, and because
|
|
1732
|
-
// `prune` skips an unresolved park the row could no longer be
|
|
1733
|
-
// collected by anything.
|
|
1734
|
-
//
|
|
1735
|
-
// The decision IS carried out here — continuing is exactly what
|
|
1736
|
-
// the loop below does, and a plan verdict is the answer to the
|
|
1737
|
-
// question the plan park asked — so the park is resolved at the
|
|
1738
|
-
// same point and with the same meaning "resolved" carries
|
|
1739
|
-
// everywhere else: the record stays, and only its pending state
|
|
1740
|
-
// ends. A `pause` is deliberately not resolved: it holds the
|
|
1741
|
-
// park rather than answering it, which is how the live path
|
|
1742
|
-
// treats it too. `answersParkOf` is the whole map, park type to
|
|
1743
|
-
// answering decision, so an arm cannot go missing by being
|
|
1744
|
-
// absent from a condition again — which is how the plan arm
|
|
1745
|
-
// leaked a finished run's park.
|
|
1746
|
-
//
|
|
1747
|
-
// Resolving it does not depend on the resumed process being able
|
|
1748
|
-
// to act on it, and that is deliberate: the plan's own fate is a
|
|
1749
|
-
// separate defect (nothing restores a plan on the resume path at
|
|
1750
|
-
// all, so the new process has none to approve, execute or
|
|
1751
|
-
// reject) and making the resolution wait for it would leave the
|
|
1752
|
-
// row outstanding for exactly the runs that need it cleared.
|
|
1753
|
-
const parked = projectedCheckpoint.pending
|
|
1754
|
-
answeredParkId =
|
|
1755
|
-
params.pendingDecision &&
|
|
1756
|
-
parked !== undefined &&
|
|
1757
|
-
parked.resolvedAt === undefined &&
|
|
1758
|
-
answersParkOf(parked.request.type, params.pendingDecision)
|
|
1759
|
-
? projectedCheckpoint.id
|
|
1760
|
-
: undefined
|
|
1704
|
+
const contextLevel = params.contextLevel ?? 'full'
|
|
1705
|
+
const cacheInput = {
|
|
1706
|
+
systemPrompt: params.systemPrompt,
|
|
1707
|
+
persona: params.persona,
|
|
1708
|
+
skills: params.skills,
|
|
1709
|
+
basePrompt: contextLevel === 'full' ? params.basePrompt : undefined,
|
|
1710
|
+
tools: params.tools,
|
|
1711
|
+
allowedTools: effectiveAllowedTools,
|
|
1712
|
+
runtimeContext: params.runtimeContext,
|
|
1713
|
+
contributions: promptContributions,
|
|
1714
|
+
}
|
|
1761
1715
|
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
recoveredResults =
|
|
1766
|
-
unanswered.length > 0
|
|
1767
|
-
? await recoverCompletedCalls(ctx.runMgr, unanswered, ctx.log, {
|
|
1768
|
-
answers: pendingResume?.answers,
|
|
1769
|
-
signal: ctx.abortController.signal,
|
|
1770
|
-
})
|
|
1771
|
-
: new Map()
|
|
1716
|
+
const segments: PromptSegments = promptCache
|
|
1717
|
+
? promptCache.getSystemPromptSegmented(cacheInput, contextLevel, params.workingDirectory)
|
|
1718
|
+
: promptBuilder.buildSegmented(contextLevel, params.workingDirectory)
|
|
1772
1719
|
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
}
|
|
1720
|
+
ctx.log.info('Prompt segments assembled', {
|
|
1721
|
+
'namzu.runtime.static_length': segments.static.length,
|
|
1722
|
+
'namzu.runtime.dynamic_length': segments.dynamic.length,
|
|
1723
|
+
})
|
|
1778
1724
|
|
|
1779
|
-
//
|
|
1780
|
-
//
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
// history and is repaired conservatively rather than deleted.
|
|
1785
|
-
const abandonedCheckpointMessages = pendingResume
|
|
1786
|
-
? withoutOwnedResumeTurn(projectedCheckpoint.messages, pendingResume.assistant)
|
|
1787
|
-
: projectedCheckpoint.messages
|
|
1788
|
-
const checkpointRepair = repairToolMessageHistory(abandonedCheckpointMessages)
|
|
1789
|
-
const restoredMessages = checkpointRepair.messages
|
|
1790
|
-
if (toolHistoryRepairChanged(checkpointRepair.report)) {
|
|
1791
|
-
pendingHistoryRepairs.push({
|
|
1792
|
-
source: 'abandoned-checkpoint',
|
|
1793
|
-
report: checkpointRepair.report,
|
|
1794
|
-
})
|
|
1795
|
-
ctx.log.warn('Repaired abandoned tool history while restoring a checkpoint', {
|
|
1796
|
-
[NAMZU.RUN_ID]: ctx.runMgr.id,
|
|
1797
|
-
'namzu.checkpoint.id': checkpoint.id,
|
|
1798
|
-
'namzu.history.source': 'abandoned-checkpoint',
|
|
1799
|
-
'namzu.history.duplicate_tool_results_removed':
|
|
1800
|
-
checkpointRepair.report.duplicateToolResultsRemoved,
|
|
1801
|
-
'namzu.history.orphaned_tool_results_removed':
|
|
1802
|
-
checkpointRepair.report.orphanedToolResultsRemoved,
|
|
1803
|
-
'namzu.history.synthetic_tool_results_inserted':
|
|
1804
|
-
checkpointRepair.report.syntheticToolResultsInserted,
|
|
1725
|
+
// The prompt floor is rebuilt every turn and never recorded:
|
|
1726
|
+
// `turn_started.systemPrompt` carries it.
|
|
1727
|
+
const pushSystemMessages = (): void => {
|
|
1728
|
+
ctx.recorder.pushMessage(createSystemMessage(segments.static, 'cache'), {
|
|
1729
|
+
transient: true,
|
|
1805
1730
|
})
|
|
1731
|
+
if (segments.dynamic.length > 0) {
|
|
1732
|
+
ctx.recorder.pushMessage(createSystemMessage(segments.dynamic, 'ephemeral'), {
|
|
1733
|
+
transient: true,
|
|
1734
|
+
})
|
|
1735
|
+
}
|
|
1736
|
+
}
|
|
1737
|
+
const pushRestored = (message: Message, ids: ReadonlyMap<Message, MessageId>): void => {
|
|
1738
|
+
const messageId = ids.get(message)
|
|
1739
|
+
ctx.recorder.pushMessage(message, messageId ? { messageId } : {})
|
|
1806
1740
|
}
|
|
1807
1741
|
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1742
|
+
if (params.resumeFromCheckpoint) {
|
|
1743
|
+
const checkpoint = await checkpointMgr.restore(params.resumeFromCheckpoint)
|
|
1744
|
+
const projectedCheckpoint = {
|
|
1745
|
+
...checkpoint,
|
|
1746
|
+
messages: projectStateBearingHistory(checkpoint.messages, {
|
|
1747
|
+
pinCompaction: false,
|
|
1748
|
+
}),
|
|
1749
|
+
}
|
|
1750
|
+
await eventTranslator.resumeTurn(checkpoint.id)
|
|
1751
|
+
yield* eventTranslator.drainPending()
|
|
1752
|
+
|
|
1753
|
+
// Budgets are properties of the TURN, not of the process hosting
|
|
1754
|
+
// it. The checkpoint already carried all three; they were
|
|
1755
|
+
// written and then discarded on the way back in, so a turn
|
|
1756
|
+
// recalled at $4.80 of a $5 cap came back with a fresh $5 and
|
|
1757
|
+
// a fresh timeout clock. Restore before the first iteration so
|
|
1758
|
+
// a resumed turn that is already over budget stops immediately.
|
|
1759
|
+
ctx.recorder.restoreUsage(
|
|
1760
|
+
checkpoint.document.tokenUsage,
|
|
1761
|
+
checkpoint.document.costInfo,
|
|
1762
|
+
checkpoint.document.guards.iteration,
|
|
1824
1763
|
)
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
//
|
|
1828
|
-
//
|
|
1829
|
-
//
|
|
1830
|
-
//
|
|
1831
|
-
//
|
|
1832
|
-
|
|
1833
|
-
|
|
1764
|
+
guard.restoreElapsed(checkpoint.document.guards.elapsedMs)
|
|
1765
|
+
|
|
1766
|
+
// Adopt the working state the earlier summary was built from.
|
|
1767
|
+
// The `[COMPACTED CONTEXT]` block below is preserved precisely
|
|
1768
|
+
// because it is the only surviving record of the history the
|
|
1769
|
+
// first pass deleted — and without this, the NEXT compaction
|
|
1770
|
+
// would drop it and replace it with a summary covering only
|
|
1771
|
+
// what happened after the resume, silently losing the turn's
|
|
1772
|
+
// first hour.
|
|
1773
|
+
if (workingStateManager && checkpoint.document.workingState && compactionConfig) {
|
|
1774
|
+
const revived = restoreWorkingState(checkpoint.document.workingState, compactionConfig)
|
|
1775
|
+
workingStateManager.replaceState(revived.getState())
|
|
1776
|
+
ctx.log.info('Restored compaction working state from checkpoint', {
|
|
1777
|
+
[NAMZU.TURN_ID]: ctx.recorder.turnId,
|
|
1778
|
+
'namzu.checkpoint.id': checkpoint.id,
|
|
1779
|
+
'namzu.runtime.slots': workingStateManager.slotCount(),
|
|
1780
|
+
})
|
|
1781
|
+
}
|
|
1782
|
+
ctx.log.info('Restored budgets from checkpoint', {
|
|
1783
|
+
[NAMZU.TURN_ID]: ctx.recorder.turnId,
|
|
1834
1784
|
'namzu.checkpoint.id': checkpoint.id,
|
|
1835
|
-
'
|
|
1785
|
+
'namzu.usage.total_tokens': checkpoint.document.tokenUsage.totalTokens,
|
|
1786
|
+
'namzu.runtime.total_cost': checkpoint.document.costInfo.totalCost,
|
|
1787
|
+
[NAMZU.ITERATION]: checkpoint.document.guards.iteration,
|
|
1788
|
+
'namzu.runtime.elapsed_ms': checkpoint.document.guards.elapsedMs,
|
|
1836
1789
|
})
|
|
1837
|
-
}
|
|
1838
1790
|
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
ctx.
|
|
1791
|
+
pushSystemMessages()
|
|
1792
|
+
|
|
1793
|
+
// A human answered the park in a different process; apply that
|
|
1794
|
+
// answer to the tool calls they were actually shown. Without
|
|
1795
|
+
// this the repair below throws the approval away and the model
|
|
1796
|
+
// re-decides, so "yes, delete that row" degrades into "ask
|
|
1797
|
+
// again and hope it asks for the same thing".
|
|
1798
|
+
pendingResume =
|
|
1799
|
+
params.pendingDecision && projectedCheckpoint.pending
|
|
1800
|
+
? planPendingResume(projectedCheckpoint, params.pendingDecision, ctx.log)
|
|
1801
|
+
: null
|
|
1802
|
+
|
|
1803
|
+
// The park this resume ANSWERS even though there is no plan to
|
|
1804
|
+
// carry the decision out through.
|
|
1805
|
+
//
|
|
1806
|
+
// `planPendingResume` covers the two arms whose decision has to
|
|
1807
|
+
// reach something — the calls a `tool_review` park is about, the
|
|
1808
|
+
// tool a `user_question` park is inside. An `iteration_checkpoint`
|
|
1809
|
+
// park has neither, so it returns no plan, and the unpark further
|
|
1810
|
+
// down — which ran only when there was one — never fired for it.
|
|
1811
|
+
// A turn that parked on the cadence, was resumed with
|
|
1812
|
+
// `{action: 'continue'}` and went on to finish its work therefore
|
|
1813
|
+
// kept reporting an OUTSTANDING park to `findPendingCheckpoint`,
|
|
1814
|
+
// so a second resume of the finished turn was refused with
|
|
1815
|
+
// `awaiting-decision` for a decision already taken, and because
|
|
1816
|
+
// `prune` skips an unresolved park the row could no longer be
|
|
1817
|
+
// collected by anything.
|
|
1818
|
+
//
|
|
1819
|
+
// The decision IS carried out here — continuing is exactly what
|
|
1820
|
+
// the loop below does, and a plan verdict is the answer to the
|
|
1821
|
+
// question the plan park asked — so the park is resolved at the
|
|
1822
|
+
// same point and with the same meaning "resolved" carries
|
|
1823
|
+
// everywhere else: the record stays, and only its pending state
|
|
1824
|
+
// ends. A `pause` is deliberately not resolved: it holds the
|
|
1825
|
+
// park rather than answering it, which is how the live path
|
|
1826
|
+
// treats it too. `answersParkOf` is the whole map, park type to
|
|
1827
|
+
// answering decision, so an arm cannot go missing by being
|
|
1828
|
+
// absent from a condition again — which is how the plan arm
|
|
1829
|
+
// leaked a finished turn's park.
|
|
1830
|
+
//
|
|
1831
|
+
// Resolving it does not depend on the resumed process being able
|
|
1832
|
+
// to act on it, and that is deliberate: the plan's own fate is a
|
|
1833
|
+
// separate defect (nothing restores a plan on the resume path at
|
|
1834
|
+
// all, so the new process has none to approve, execute or
|
|
1835
|
+
// reject) and making the resolution wait for it would leave the
|
|
1836
|
+
// row outstanding for exactly the turns that need it cleared.
|
|
1837
|
+
const parked = projectedCheckpoint.pending
|
|
1838
|
+
answeredParkId =
|
|
1839
|
+
params.pendingDecision &&
|
|
1840
|
+
parked !== undefined &&
|
|
1841
|
+
parked.resolvedAt === undefined &&
|
|
1842
|
+
answersParkOf(parked.request.type, params.pendingDecision)
|
|
1843
|
+
? projectedCheckpoint.id
|
|
1844
|
+
: undefined
|
|
1845
|
+
|
|
1846
|
+
// Recover completed observations and explicitly unknown outcomes.
|
|
1847
|
+
// A recorded start is not proof that its external effect failed.
|
|
1848
|
+
const unanswered = interruptedToolCalls(projectedCheckpoint.messages)
|
|
1849
|
+
recoveredResults =
|
|
1850
|
+
unanswered.length > 0
|
|
1851
|
+
? await recoverCompletedCalls(ctx.recorder, unanswered, ctx.log, {
|
|
1852
|
+
answers: pendingResume?.answers,
|
|
1853
|
+
signal: ctx.abortController.signal,
|
|
1854
|
+
})
|
|
1855
|
+
: new Map()
|
|
1856
|
+
|
|
1857
|
+
// Preserve both known and unknown outcomes before continuing calls
|
|
1858
|
+
// whose absence of a start was established by a complete scan.
|
|
1859
|
+
if (!pendingResume && recoveredResults.size > 0) {
|
|
1860
|
+
pendingResume = planCrashResume(projectedCheckpoint, recoveredResults, ctx.log)
|
|
1861
|
+
}
|
|
1862
|
+
|
|
1863
|
+
// An incomplete turn with a durable owner is NOT abandoned. A
|
|
1864
|
+
// pending decision or crash-resume plan re-appends that exact
|
|
1865
|
+
// assistant with real/denied/recovered results below. Remove it
|
|
1866
|
+
// from the generic pass so no synthetic result competes with the
|
|
1867
|
+
// authority that still owns the call. Everything else is abandoned
|
|
1868
|
+
// history and is repaired conservatively rather than deleted.
|
|
1869
|
+
pendingResumeAssistantId = pendingResume
|
|
1870
|
+
? checkpoint.messageIds.get(pendingResume.assistant)
|
|
1871
|
+
: undefined
|
|
1872
|
+
const abandonedCheckpointMessages = pendingResume
|
|
1873
|
+
? withoutOwnedResumeTurn(projectedCheckpoint.messages, pendingResume.assistant)
|
|
1874
|
+
: projectedCheckpoint.messages
|
|
1875
|
+
const checkpointRepair = repairToolMessageHistory(abandonedCheckpointMessages)
|
|
1876
|
+
const restoredMessages = checkpointRepair.messages
|
|
1877
|
+
if (toolHistoryRepairChanged(checkpointRepair.report)) {
|
|
1878
|
+
pendingHistoryRepairs.push({
|
|
1879
|
+
source: 'abandoned-checkpoint',
|
|
1880
|
+
report: checkpointRepair.report,
|
|
1881
|
+
})
|
|
1882
|
+
ctx.log.warn('Repaired abandoned tool history while restoring a checkpoint', {
|
|
1883
|
+
[NAMZU.TURN_ID]: ctx.recorder.turnId,
|
|
1884
|
+
'namzu.checkpoint.id': checkpoint.id,
|
|
1885
|
+
'namzu.history.source': 'abandoned-checkpoint',
|
|
1886
|
+
'namzu.history.duplicate_tool_results_removed':
|
|
1887
|
+
checkpointRepair.report.duplicateToolResultsRemoved,
|
|
1888
|
+
'namzu.history.orphaned_tool_results_removed':
|
|
1889
|
+
checkpointRepair.report.orphanedToolResultsRemoved,
|
|
1890
|
+
'namzu.history.synthetic_tool_results_inserted':
|
|
1891
|
+
checkpointRepair.report.syntheticToolResultsInserted,
|
|
1892
|
+
})
|
|
1893
|
+
}
|
|
1894
|
+
|
|
1895
|
+
// The ledger is process state and a resumed turn starts with an empty
|
|
1896
|
+
// one, so until something reads a file again this turn knows nothing
|
|
1897
|
+
// about files the conversation already wrote in full — and re-reads
|
|
1898
|
+
// them. Rebuilt from the REPAIRED history, which is what the model
|
|
1899
|
+
// is about to be shown, rather than from the checkpoint's own
|
|
1900
|
+
// messages — plus whatever of the owned resume turn actually ran,
|
|
1901
|
+
// which the repaired list does not carry; see
|
|
1902
|
+
// `withOwnedResumeOutcomes`. Reads no file's content: every
|
|
1903
|
+
// fingerprint recovered here is still checked against the real one
|
|
1904
|
+
// at mutation time.
|
|
1905
|
+
try {
|
|
1906
|
+
await toolExecutor.seedFileObservations(
|
|
1907
|
+
pendingResume
|
|
1908
|
+
? withOwnedResumeOutcomes(
|
|
1909
|
+
restoredMessages,
|
|
1910
|
+
pendingResume.assistant,
|
|
1911
|
+
recoveredResults,
|
|
1912
|
+
)
|
|
1913
|
+
: restoredMessages,
|
|
1914
|
+
params.sandboxProvider !== undefined,
|
|
1915
|
+
)
|
|
1916
|
+
} catch (err: unknown) {
|
|
1917
|
+
// A ledger that could not be rebuilt is the empty one every resume
|
|
1918
|
+
// used to get, so the turn continues without its witnesses and the
|
|
1919
|
+
// model reads what it needs. Failing the resume over it would trade
|
|
1920
|
+
// a conversation that works for one that does not, to protect an
|
|
1921
|
+
// optimisation. Said out loud all the same, because a seeding that
|
|
1922
|
+
// failed and one that found nothing are otherwise the same silence.
|
|
1923
|
+
ctx.log.debug('Could not rebuild the file observation ledger on resume', {
|
|
1924
|
+
[NAMZU.TURN_ID]: ctx.recorder.turnId,
|
|
1925
|
+
'namzu.checkpoint.id': checkpoint.id,
|
|
1926
|
+
'exception.message': err instanceof Error ? err.message : String(err),
|
|
1927
|
+
})
|
|
1928
|
+
}
|
|
1929
|
+
|
|
1930
|
+
for (const msg of restoredMessages) {
|
|
1931
|
+
if (msg.role === 'system') {
|
|
1932
|
+
// Re-push the FRESH static/dynamic floor (done above) but PRESERVE
|
|
1933
|
+
// the two system messages that carry irreplaceable run state: the
|
|
1934
|
+
// `[COMPACTED CONTEXT]` summary is the only surviving record of the
|
|
1935
|
+
// older history a compaction pass deleted, and the working-memory
|
|
1936
|
+
// slot pins the produced-artifact ledger. Dropping every system
|
|
1937
|
+
// message on restore silently lost both on resume.
|
|
1938
|
+
if (isCompactionMessage(msg.content) || isWorkingMemoryMessage(msg.content)) {
|
|
1939
|
+
pushRestored(msg, checkpoint.messageIds)
|
|
1940
|
+
}
|
|
1941
|
+
continue
|
|
1849
1942
|
}
|
|
1850
|
-
|
|
1943
|
+
pushRestored(msg, checkpoint.messageIds)
|
|
1851
1944
|
}
|
|
1852
|
-
ctx.runMgr.pushMessage(msg)
|
|
1853
|
-
}
|
|
1854
1945
|
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1946
|
+
// The queue, on the resume path too. It is drained
|
|
1947
|
+
// unconditionally above, so leaving this out would take a
|
|
1948
|
+
// host's "start with this" off the record and deliver it
|
|
1949
|
+
// nowhere — the one outcome a durable queue must not have.
|
|
1950
|
+
//
|
|
1951
|
+
// AFTER the restored history rather than before it: on a
|
|
1952
|
+
// resume the conversation already exists, and a message left
|
|
1953
|
+
// for "the next turn" is the newest thing said, not the oldest.
|
|
1954
|
+
for (const queued of queuedForThisRun) ctx.recorder.pushMessage(queued)
|
|
1955
|
+
} else if (params.continuationMode) {
|
|
1956
|
+
for (const msg of initialMessages) pushRestored(msg, historyIds)
|
|
1957
|
+
} else {
|
|
1958
|
+
pushSystemMessages()
|
|
1959
|
+
for (const msg of initialMessages) {
|
|
1960
|
+
if (msg.role === 'system') {
|
|
1961
|
+
// A fresh turn rebuilds its current static/dynamic prompt above,
|
|
1962
|
+
// so arbitrary historical system messages stay out. These two
|
|
1963
|
+
// are different: they are conversation STATE, and dropping them
|
|
1964
|
+
// deletes the only surviving record of compacted history or the
|
|
1965
|
+
// produced-artifact ledger. A compaction summary arriving from a
|
|
1966
|
+
// prior turn is pinned because this new WorkingStateManager cannot
|
|
1967
|
+
// prove it has reconstructed equivalent state yet.
|
|
1968
|
+
if (isCompactionMessage(msg.content)) {
|
|
1969
|
+
// Pinned by the prelude already; a copy would lose its record id.
|
|
1970
|
+
pushRestored(msg.retain ? msg : { ...msg, retain: true }, historyIds)
|
|
1971
|
+
} else if (isWorkingMemoryMessage(msg.content)) {
|
|
1972
|
+
pushRestored(msg, historyIds)
|
|
1973
|
+
}
|
|
1974
|
+
continue
|
|
1883
1975
|
}
|
|
1884
|
-
|
|
1976
|
+
pushRestored(msg, historyIds)
|
|
1885
1977
|
}
|
|
1886
|
-
ctx.runMgr.pushMessage(msg)
|
|
1887
1978
|
}
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1979
|
+
// Fresh and continuation histories seed the same operator state.
|
|
1980
|
+
// A worker report or project-policy message may have role `user`,
|
|
1981
|
+
// but it must not become the task or an operator requirement.
|
|
1982
|
+
// Resume restores this state and adopts only its newer queue arrivals.
|
|
1983
|
+
if (!params.resumeFromCheckpoint && workingStateManager) {
|
|
1984
|
+
let isFirstUserMessage = true
|
|
1985
|
+
for (const message of initialMessages) {
|
|
1986
|
+
if (!isOperatorUserMessage(message) || !message.content.trim()) continue
|
|
1987
|
+
extractFromUserMessage(workingStateManager, message.content, isFirstUserMessage)
|
|
1988
|
+
isFirstUserMessage = false
|
|
1989
|
+
}
|
|
1899
1990
|
}
|
|
1900
|
-
}
|
|
1901
|
-
|
|
1902
|
-
const assembledPrompt =
|
|
1903
|
-
segments.dynamic.length > 0
|
|
1904
|
-
? `${segments.static}\n\n---\n\n${segments.dynamic}`
|
|
1905
|
-
: segments.static
|
|
1906
|
-
|
|
1907
|
-
ctx.runMgr.markRunning()
|
|
1908
|
-
await eventTranslator.emitEvent({
|
|
1909
|
-
type: 'run_started',
|
|
1910
|
-
runId: ctx.runMgr.id,
|
|
1911
|
-
systemPrompt: assembledPrompt,
|
|
1912
|
-
})
|
|
1913
|
-
yield* eventTranslator.drainPending()
|
|
1914
|
-
|
|
1915
|
-
// Pre-run materialization can observe cancellation before RunContext
|
|
1916
|
-
// exists. The exact input has now been seeded and the run is writable;
|
|
1917
|
-
// hand the cancellation to the normal terminal path before invoking
|
|
1918
|
-
// any host callback, guardrail, plugin, sandbox, or provider. Those
|
|
1919
|
-
// boundaries are not all cooperative and must not regain withdrawn
|
|
1920
|
-
// authority merely because the run record still had to be created.
|
|
1921
|
-
ctx.abortController.signal.throwIfAborted()
|
|
1922
|
-
|
|
1923
|
-
// Handed over here, and the position is load-bearing in three
|
|
1924
|
-
// directions. It has to follow `wirePlanManager`, or a host that
|
|
1925
|
-
// builds its plan in this callback does it into silence. It has to
|
|
1926
|
-
// follow `runMgr.init()` and `run_started`, because plan events append
|
|
1927
|
-
// to that durable run. It also has to follow the pre-model abort fence:
|
|
1928
|
-
// a callback invoked after attachment resolution observed cancellation
|
|
1929
|
-
// would regain withdrawn authority and could replace the cancellation
|
|
1930
|
-
// with its own failure. This is still before the iteration loop, which
|
|
1931
|
-
// is the guarantee the callback makes.
|
|
1932
|
-
params.onContextCreated?.({ planManager: ctx.planManager })
|
|
1933
|
-
|
|
1934
|
-
// The box is handed out HERE, after `run_started`, and the position
|
|
1935
|
-
// is load-bearing rather than tidy. It moved twice:
|
|
1936
|
-
//
|
|
1937
|
-
// 1. Beside the box's construction — a host that called `set`
|
|
1938
|
-
// synchronously reached `eventTranslator` inside its temporal
|
|
1939
|
-
// dead zone and killed the run before it started.
|
|
1940
|
-
// 2. Beside the translator's construction — the translator existed,
|
|
1941
|
-
// but the run directory did not, so the durable append hit
|
|
1942
|
-
// ENOENT on `transcript.jsonl`.
|
|
1943
|
-
//
|
|
1944
|
-
// Both were found by the test that takes the box and immediately
|
|
1945
|
-
// swaps the policy, which is not an exotic host: it is the shape of
|
|
1946
|
-
// "start unattended" wiring. A policy change is durably recorded
|
|
1947
|
-
// before it takes effect, so the handout cannot precede the run
|
|
1948
|
-
// being writable.
|
|
1949
|
-
params.onApprovalPolicy?.(approvalPolicy)
|
|
1950
|
-
|
|
1951
|
-
// History repair happens before the run manager sees the first model
|
|
1952
|
-
// request, but its durable event cannot precede run_started: there is no
|
|
1953
|
-
// writable run log until that event initializes it. Emit the measured
|
|
1954
|
-
// counts here, still before any provider call, so hosts can tell that the
|
|
1955
|
-
// model received a repaired projection rather than the raw history.
|
|
1956
|
-
for (const repair of pendingHistoryRepairs) {
|
|
1957
|
-
await eventTranslator.emitEvent({
|
|
1958
|
-
type: 'message_history_repaired',
|
|
1959
|
-
runId: ctx.runMgr.id,
|
|
1960
|
-
source: repair.source,
|
|
1961
|
-
...repair.report,
|
|
1962
|
-
})
|
|
1963
|
-
yield* eventTranslator.drainPending()
|
|
1964
|
-
}
|
|
1965
1991
|
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
await eventTranslator.emitEvent({
|
|
1981
|
-
type: 'capability_warning',
|
|
1982
|
-
runId: ctx.runMgr.id,
|
|
1983
|
-
capability: 'vision',
|
|
1984
|
-
providerId: params.provider.id,
|
|
1985
|
-
message: `Provider '${params.provider.id}' does not support vision — image attachments on ${attachmentMessageCount} user message(s) will not reach the model.`,
|
|
1986
|
-
})
|
|
1987
|
-
yield* eventTranslator.drainPending()
|
|
1988
|
-
}
|
|
1989
|
-
if (documentMessageCount > 0) {
|
|
1990
|
-
await eventTranslator.emitEvent({
|
|
1991
|
-
type: 'capability_warning',
|
|
1992
|
-
runId: ctx.runMgr.id,
|
|
1993
|
-
capability: 'documents',
|
|
1994
|
-
providerId: params.provider.id,
|
|
1995
|
-
message: `Provider '${params.provider.id}' does not support documents — document attachments on ${documentMessageCount} user message(s) will not reach the model.`,
|
|
1996
|
-
})
|
|
1992
|
+
const assembledPrompt =
|
|
1993
|
+
segments.dynamic.length > 0
|
|
1994
|
+
? `${segments.static}\n\n---\n\n${segments.dynamic}`
|
|
1995
|
+
: segments.static
|
|
1996
|
+
|
|
1997
|
+
ctx.recorder.markRunning()
|
|
1998
|
+
// A resumed turn already began; `turn_resuming` above continued it.
|
|
1999
|
+
if (!params.resumeFromCheckpoint) {
|
|
2000
|
+
await eventTranslator.beginTurn({
|
|
2001
|
+
systemPrompt: assembledPrompt,
|
|
2002
|
+
...(params.origin ? { origin: params.origin } : {}),
|
|
2003
|
+
...(params.abandonInterrupted ? { abandonInterrupted: true } : {}),
|
|
2004
|
+
})
|
|
2005
|
+
}
|
|
1997
2006
|
yield* eventTranslator.drainPending()
|
|
1998
|
-
}
|
|
1999
2007
|
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2008
|
+
// Pre-run materialization can observe cancellation before TurnContext
|
|
2009
|
+
// exists. The exact input has now been seeded and the turn is writable;
|
|
2010
|
+
// hand the cancellation to the normal terminal path before invoking
|
|
2011
|
+
// any host callback, guardrail, plugin, sandbox, or provider. Those
|
|
2012
|
+
// boundaries are not all cooperative and must not regain withdrawn
|
|
2013
|
+
// authority merely because the turn record still had to be created.
|
|
2014
|
+
ctx.abortController.signal.throwIfAborted()
|
|
2015
|
+
|
|
2016
|
+
// Handed over here, and the position is load-bearing in three
|
|
2017
|
+
// directions. It has to follow `wirePlanManager`, or a host that
|
|
2018
|
+
// builds its plan in this callback does it into silence. It has to
|
|
2019
|
+
// follow `recorder.init()` and `turn_started`, because plan events append
|
|
2020
|
+
// to that durable turn. It also has to follow the pre-model abort fence:
|
|
2021
|
+
// a callback invoked after attachment resolution observed cancellation
|
|
2022
|
+
// would regain withdrawn authority and could replace the cancellation
|
|
2023
|
+
// with its own failure. This is still before the iteration loop, which
|
|
2024
|
+
// is the guarantee the callback makes.
|
|
2025
|
+
params.onContextCreated?.({ planManager: ctx.planManager })
|
|
2026
|
+
|
|
2027
|
+
// The box is handed out HERE, after `turn_started`, and the position
|
|
2028
|
+
// is load-bearing rather than tidy. It moved twice:
|
|
2029
|
+
//
|
|
2030
|
+
// 1. Beside the box's construction — a host that called `set`
|
|
2031
|
+
// synchronously reached `eventTranslator` inside its temporal
|
|
2032
|
+
// dead zone and killed the turn before it started.
|
|
2033
|
+
// 2. Beside the translator's construction — the translator existed,
|
|
2034
|
+
// but the turn directory did not, so the durable append hit
|
|
2035
|
+
// ENOENT on `transcript.jsonl`.
|
|
2036
|
+
//
|
|
2037
|
+
// Both were found by the test that takes the box and immediately
|
|
2038
|
+
// swaps the policy, which is not an exotic host: it is the shape of
|
|
2039
|
+
// "start unattended" wiring. A policy change is durably recorded
|
|
2040
|
+
// before it takes effect, so the handout cannot precede the turn
|
|
2041
|
+
// being writable.
|
|
2042
|
+
params.onApprovalPolicy?.(approvalPolicy)
|
|
2043
|
+
|
|
2044
|
+
// History repair happens before the turn manager sees the first model
|
|
2045
|
+
// request, but its durable event cannot precede turn_started: there is no
|
|
2046
|
+
// writable run log until that event initializes it. Emit the measured
|
|
2047
|
+
// counts here, still before any provider call, so hosts can tell that the
|
|
2048
|
+
// model received a repaired projection rather than the raw history.
|
|
2049
|
+
for (const repair of pendingHistoryRepairs) {
|
|
2050
|
+
await eventTranslator.emitEvent({
|
|
2051
|
+
type: 'message_history_repaired',
|
|
2052
|
+
turnId: ctx.recorder.turnId,
|
|
2053
|
+
source: repair.source,
|
|
2054
|
+
...repair.report,
|
|
2055
|
+
})
|
|
2056
|
+
yield* eventTranslator.drainPending()
|
|
2057
|
+
}
|
|
2009
2058
|
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
// of a specific tree and quietly got an empty one has been
|
|
2021
|
-
// told their files are protected by something that is not
|
|
2022
|
-
// looking at them.
|
|
2023
|
-
if (rootAtCwd && params.workingDirectory === undefined) {
|
|
2024
|
-
throw new NamzuError({
|
|
2025
|
-
code: 'invalid_config',
|
|
2026
|
-
message:
|
|
2027
|
-
"sandbox.workspace is 'working-directory' but this run has no workingDirectory. Pass one, or use the default 'ephemeral' — the kernel will not fall back to a temp directory, because that would confine a directory you did not name.",
|
|
2028
|
-
details: { workspace: 'working-directory' },
|
|
2059
|
+
// Surface capability degradation to the host as run events —
|
|
2060
|
+
// explicit, not silent (the log.warn above fires at setup time;
|
|
2061
|
+
// this is the machine-readable channel).
|
|
2062
|
+
if (stripToolSurfaces) {
|
|
2063
|
+
await eventTranslator.emitEvent({
|
|
2064
|
+
type: 'capability_warning',
|
|
2065
|
+
turnId: ctx.recorder.turnId,
|
|
2066
|
+
capability: 'tools',
|
|
2067
|
+
providerId: params.provider.id,
|
|
2068
|
+
message: `Provider '${params.provider.id}' does not support tools — ${registeredToolCount} registered tool(s) were stripped from the prompt and request.`,
|
|
2029
2069
|
})
|
|
2070
|
+
yield* eventTranslator.drainPending()
|
|
2030
2071
|
}
|
|
2031
|
-
if (
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
},
|
|
2072
|
+
if (attachmentMessageCount > 0) {
|
|
2073
|
+
await eventTranslator.emitEvent({
|
|
2074
|
+
type: 'capability_warning',
|
|
2075
|
+
turnId: ctx.recorder.turnId,
|
|
2076
|
+
capability: 'vision',
|
|
2077
|
+
providerId: params.provider.id,
|
|
2078
|
+
message: `Provider '${params.provider.id}' does not support vision — image attachments on ${attachmentMessageCount} user message(s) will not reach the model.`,
|
|
2039
2079
|
})
|
|
2080
|
+
yield* eventTranslator.drainPending()
|
|
2040
2081
|
}
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2082
|
+
if (documentMessageCount > 0) {
|
|
2083
|
+
await eventTranslator.emitEvent({
|
|
2084
|
+
type: 'capability_warning',
|
|
2085
|
+
turnId: ctx.recorder.turnId,
|
|
2086
|
+
capability: 'documents',
|
|
2087
|
+
providerId: params.provider.id,
|
|
2088
|
+
message: `Provider '${params.provider.id}' does not support documents — document attachments on ${documentMessageCount} user message(s) will not reach the model.`,
|
|
2089
|
+
})
|
|
2090
|
+
yield* eventTranslator.drainPending()
|
|
2091
|
+
}
|
|
2092
|
+
|
|
2093
|
+
if (params.pluginManager) {
|
|
2094
|
+
const hookResults = await params.pluginManager.executeHooks(
|
|
2095
|
+
'turn_start',
|
|
2096
|
+
{ sessionId: ctx.sessionId, turnId: ctx.turnId, signal: ctx.abortController.signal },
|
|
2097
|
+
eventTranslator.emitEvent,
|
|
2098
|
+
)
|
|
2099
|
+
applyLifecycleHookResults('turn_start', hookResults)
|
|
2100
|
+
yield* eventTranslator.drainPending()
|
|
2101
|
+
}
|
|
2102
|
+
|
|
2103
|
+
// --- Sandbox lifecycle: create before iteration loop ---
|
|
2104
|
+
if (params.sandboxProvider) {
|
|
2105
|
+
const rootAtCwd = turnConfig.sandbox?.workspace === 'working-directory'
|
|
2106
|
+
// Checked against what the CALLER passed, not against `ctx.cwd`.
|
|
2107
|
+
// `ctx.cwd` falls back to `process.cwd()`, so reading it here
|
|
2108
|
+
// would silently root the sandbox at whatever directory the
|
|
2109
|
+
// host process happens to be in — which is not the directory
|
|
2110
|
+
// anybody asked to confine, and is worse than the temp dir the
|
|
2111
|
+
// caller declined. Refused before the sandbox exists, and not
|
|
2112
|
+
// downgraded to ephemeral: a caller who asked for confinement
|
|
2113
|
+
// of a specific tree and quietly got an empty one has been
|
|
2114
|
+
// told their files are protected by something that is not
|
|
2115
|
+
// looking at them.
|
|
2116
|
+
if (rootAtCwd && params.workingDirectory === undefined) {
|
|
2117
|
+
throw new NamzuError({
|
|
2118
|
+
code: 'invalid_config',
|
|
2119
|
+
message:
|
|
2120
|
+
"sandbox.workspace is 'working-directory' but this turn has no workingDirectory. Pass one, or use the default 'ephemeral' — the kernel will not fall back to a temp directory, because that would confine a directory you did not name.",
|
|
2121
|
+
details: { workspace: 'working-directory' },
|
|
2065
2122
|
})
|
|
2066
|
-
},
|
|
2067
|
-
})
|
|
2068
|
-
if (acquisition.kind !== 'created') {
|
|
2069
|
-
if (acquisition.createPending) {
|
|
2070
|
-
ctx.log.warn(
|
|
2071
|
-
'Sandbox creation was unsettled when the run stopped; any returned handle will be released, but a remote allocation hidden behind a lost response requires provider-side reconciliation or a fleet reaper',
|
|
2072
|
-
{
|
|
2073
|
-
[NAMZU.RUN_ID]: ctx.runId,
|
|
2074
|
-
'namzu.sandbox.provider_id': params.sandboxProvider.id,
|
|
2075
|
-
},
|
|
2076
|
-
)
|
|
2077
2123
|
}
|
|
2078
|
-
if (
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2124
|
+
if (rootAtCwd && !params.sandboxProvider.workspaceModes?.includes('working-directory')) {
|
|
2125
|
+
throw new NamzuError({
|
|
2126
|
+
code: 'invalid_config',
|
|
2127
|
+
message: `Sandbox provider '${params.sandboxProvider.id}' does not advertise working-directory workspace support. Refusing instead of passing a project path the provider may ignore.`,
|
|
2128
|
+
details: {
|
|
2129
|
+
providerId: params.sandboxProvider.id,
|
|
2130
|
+
workspace: 'working-directory',
|
|
2131
|
+
},
|
|
2086
2132
|
})
|
|
2087
2133
|
}
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2134
|
+
const acquisition = await acquireSandbox({
|
|
2135
|
+
provider: params.sandboxProvider,
|
|
2136
|
+
config: {
|
|
2137
|
+
...(rootAtCwd ? { workingDirectory: ctx.cwd } : {}),
|
|
2138
|
+
...(rootAtCwd && params.additionalDirectories?.length
|
|
2139
|
+
? { additionalDirectories: params.additionalDirectories }
|
|
2140
|
+
: {}),
|
|
2141
|
+
timeoutMs: turnConfig.sandbox?.timeoutMs,
|
|
2142
|
+
memoryLimitMb: turnConfig.sandbox?.memoryLimitMb,
|
|
2143
|
+
maxProcesses: turnConfig.sandbox?.maxProcesses,
|
|
2144
|
+
},
|
|
2145
|
+
signal: ctx.abortController.signal,
|
|
2146
|
+
timeoutMs: guard.remainingUntilTimeoutMs(),
|
|
2147
|
+
teardownTimeoutMs: sandboxTeardownTimeoutMs,
|
|
2148
|
+
onLateTeardown: (result) => {
|
|
2149
|
+
if (result.kind === 'destroyed') {
|
|
2150
|
+
ctx.log.info('Late sandbox allocation was destroyed after the turn stopped', {
|
|
2151
|
+
[NAMZU.TURN_ID]: ctx.turnId,
|
|
2152
|
+
})
|
|
2153
|
+
return
|
|
2154
|
+
}
|
|
2155
|
+
ctx.log.error('Late sandbox allocation did not stop cleanly', {
|
|
2156
|
+
[NAMZU.TURN_ID]: ctx.turnId,
|
|
2157
|
+
...errorAttributes(result.error),
|
|
2158
|
+
})
|
|
2159
|
+
},
|
|
2160
|
+
})
|
|
2161
|
+
if (acquisition.kind !== 'created') {
|
|
2162
|
+
if (acquisition.createPending) {
|
|
2163
|
+
ctx.log.warn(
|
|
2164
|
+
'Sandbox creation was unsettled when the turn stopped; any returned handle will be released, but a remote allocation hidden behind a lost response requires provider-side reconciliation or a fleet reaper',
|
|
2165
|
+
{
|
|
2166
|
+
[NAMZU.TURN_ID]: ctx.turnId,
|
|
2167
|
+
'namzu.sandbox.provider_id': params.sandboxProvider.id,
|
|
2168
|
+
},
|
|
2169
|
+
)
|
|
2170
|
+
}
|
|
2171
|
+
if (acquisition.kind === 'cancelled') {
|
|
2172
|
+
ctx.recorder.markCancelled()
|
|
2173
|
+
} else {
|
|
2174
|
+
ctx.recorder.setStopReason('timeout')
|
|
2175
|
+
ctx.log.warn('Sandbox creation exhausted the turn timeout', {
|
|
2176
|
+
[NAMZU.TURN_ID]: ctx.turnId,
|
|
2177
|
+
'namzu.sandbox.provider_id': params.sandboxProvider.id,
|
|
2178
|
+
...errorAttributes(acquisition.error),
|
|
2179
|
+
})
|
|
2180
|
+
}
|
|
2181
|
+
yield* resultAssembler.completeTurn(rootSpan)
|
|
2182
|
+
// The turn HAS settled, so the outer `finally` must not read
|
|
2183
|
+
// this as an abandonment — it would persist a second time.
|
|
2184
|
+
settled = true
|
|
2185
|
+
return await resultAssembler.finalize()
|
|
2186
|
+
}
|
|
2187
|
+
sandbox = acquisition.sandbox
|
|
2188
|
+
toolExecutor.setSandbox(sandbox)
|
|
2189
|
+
|
|
2190
|
+
await eventTranslator.emitEvent({
|
|
2191
|
+
type: 'sandbox_created',
|
|
2192
|
+
turnId: ctx.turnId,
|
|
2193
|
+
sandboxId: sandbox.id,
|
|
2194
|
+
environment: sandbox.environment,
|
|
2195
|
+
})
|
|
2196
|
+
yield* eventTranslator.drainPending()
|
|
2197
|
+
|
|
2198
|
+
ctx.log.info('Sandbox created for run', {
|
|
2199
|
+
'namzu.sandbox.id': sandbox.id,
|
|
2200
|
+
'namzu.execution.environment': sandbox.environment,
|
|
2201
|
+
'namzu.runtime.root_dir': sandbox.rootDir,
|
|
2202
|
+
})
|
|
2203
|
+
}
|
|
2204
|
+
|
|
2205
|
+
// Before the first model call: the cheapest place to refuse, since
|
|
2206
|
+
// nothing has been spent. Previously unreachable — `turn_start`
|
|
2207
|
+
// fires with only `{ sessionId, turnId }` and `turn_started` carries only the
|
|
2208
|
+
// system prompt, so no hook could see the user's message.
|
|
2209
|
+
const inputVerdict = await runInputGuardrails(
|
|
2210
|
+
params.inputGuardrails,
|
|
2211
|
+
{
|
|
2212
|
+
sessionId: ctx.sessionId,
|
|
2213
|
+
turnId: ctx.turnId,
|
|
2214
|
+
messages: ctx.recorder.messages,
|
|
2215
|
+
...(segments?.static ? { systemPrompt: segments.static } : {}),
|
|
2216
|
+
},
|
|
2217
|
+
ctx.log,
|
|
2218
|
+
)
|
|
2219
|
+
if (inputVerdict.blocked) {
|
|
2220
|
+
await eventTranslator.emitEvent({
|
|
2221
|
+
type: 'guardrail_triggered',
|
|
2222
|
+
turnId: ctx.turnId,
|
|
2223
|
+
stage: 'input',
|
|
2224
|
+
action: 'block',
|
|
2225
|
+
...(inputVerdict.name ? { guardrail: inputVerdict.name } : {}),
|
|
2226
|
+
...(inputVerdict.reason ? { reason: inputVerdict.reason } : {}),
|
|
2227
|
+
})
|
|
2228
|
+
yield* eventTranslator.drainPending()
|
|
2229
|
+
// A guardrail block is a refusal — first-class in the audit trail
|
|
2230
|
+
// (LOG-14, design §5), not merely a SessionEvent a host happens to be
|
|
2231
|
+
// subscribed to when it fires.
|
|
2232
|
+
await ctx.recorder.recordAudit({
|
|
2233
|
+
what: { action: 'guardrail:input', resource: inputVerdict.name },
|
|
2234
|
+
outcome: 'refused',
|
|
2235
|
+
reason: inputVerdict.reason ?? 'blocked by an input guardrail',
|
|
2236
|
+
...(params.persona?.identity.role ? { persona: params.persona.identity.role } : {}),
|
|
2237
|
+
})
|
|
2238
|
+
ctx.recorder.setStopReason('input_guardrail')
|
|
2239
|
+
ctx.recorder.setLastError(inputVerdict.reason ?? 'blocked by an input guardrail')
|
|
2240
|
+
yield* resultAssembler.completeTurn(rootSpan)
|
|
2241
|
+
// Same two lines as the sandbox path above, and for the same
|
|
2242
|
+
// reasons — with one that path does not have. This return used to
|
|
2243
|
+
// hand back `getRun()` without persisting, so the terminal state
|
|
2244
|
+
// reached the disk only because the abandonment path found
|
|
2245
|
+
// `settled` false and settled it a second time. A branch that
|
|
2246
|
+
// exists for runs which did NOT settle must not be the reason a
|
|
2247
|
+
// settled one is written down.
|
|
2091
2248
|
settled = true
|
|
2092
2249
|
return await resultAssembler.finalize()
|
|
2093
2250
|
}
|
|
2094
|
-
sandbox = acquisition.sandbox
|
|
2095
|
-
toolExecutor.setSandbox(sandbox)
|
|
2096
|
-
|
|
2097
|
-
await eventTranslator.emitEvent({
|
|
2098
|
-
type: 'sandbox_created',
|
|
2099
|
-
runId: ctx.runId,
|
|
2100
|
-
sandboxId: sandbox.id,
|
|
2101
|
-
environment: sandbox.environment,
|
|
2102
|
-
})
|
|
2103
|
-
yield* eventTranslator.drainPending()
|
|
2104
2251
|
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2252
|
+
// Honor the approval a human already gave, before the loop's
|
|
2253
|
+
// first model call. The sandbox exists by now, so an approved
|
|
2254
|
+
// tool that needs one gets it.
|
|
2255
|
+
if (pendingResume) {
|
|
2256
|
+
ctx.log.info('Applying a pending HITL decision to the checkpointed tool calls', {
|
|
2257
|
+
[NAMZU.TURN_ID]: ctx.turnId,
|
|
2258
|
+
'namzu.tool.names': pendingResume.response.message.toolCalls?.map(
|
|
2259
|
+
(tc) => tc.function.name,
|
|
2260
|
+
),
|
|
2261
|
+
'namzu.runtime.denied': pendingResume.denials.size,
|
|
2262
|
+
})
|
|
2263
|
+
// Hand the recorded answer to the already-built tool. The tool
|
|
2264
|
+
// closed over its registry when the agent was constructed,
|
|
2265
|
+
// long before this turn existed, so the answers are copied in
|
|
2266
|
+
// rather than passed down.
|
|
2267
|
+
if (pendingResume.answers) {
|
|
2268
|
+
for (const [questionId, answer] of pendingResume.answers.entries()) {
|
|
2269
|
+
pendingAnswers.set(questionId, answer)
|
|
2270
|
+
}
|
|
2271
|
+
}
|
|
2111
2272
|
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
emergencyManager.attach(ctx.runMgr, runDir, ctx.log)
|
|
2119
|
-
} else {
|
|
2120
|
-
ctx.log.warn(
|
|
2121
|
-
'emergencySave requested but the run has no output directory — crash dumps disabled',
|
|
2122
|
-
{ [NAMZU.RUN_ID]: ctx.runId },
|
|
2273
|
+
await applyPendingResume(
|
|
2274
|
+
pendingResume,
|
|
2275
|
+
ctx.recorder,
|
|
2276
|
+
toolExecutor,
|
|
2277
|
+
recoveredResults,
|
|
2278
|
+
pendingResumeAssistantId,
|
|
2123
2279
|
)
|
|
2280
|
+
yield* eventTranslator.drainPending()
|
|
2124
2281
|
}
|
|
2125
|
-
}
|
|
2126
2282
|
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
//
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
// exists for runs which did NOT settle must not be the reason a
|
|
2168
|
-
// settled one is written down.
|
|
2169
|
-
settled = true
|
|
2170
|
-
return await resultAssembler.finalize()
|
|
2171
|
-
}
|
|
2172
|
-
|
|
2173
|
-
// Honor the approval a human already gave, before the loop's
|
|
2174
|
-
// first model call. The sandbox exists by now, so an approved
|
|
2175
|
-
// tool that needs one gets it.
|
|
2176
|
-
if (pendingResume) {
|
|
2177
|
-
ctx.log.info('Applying a pending HITL decision to the checkpointed tool calls', {
|
|
2178
|
-
[NAMZU.RUN_ID]: ctx.runId,
|
|
2179
|
-
'namzu.tool.names': pendingResume.response.message.toolCalls?.map(
|
|
2180
|
-
(tc) => tc.function.name,
|
|
2181
|
-
),
|
|
2182
|
-
'namzu.runtime.denied': pendingResume.denials.size,
|
|
2183
|
-
})
|
|
2184
|
-
// Hand the recorded answer to the already-built tool. The tool
|
|
2185
|
-
// closed over its registry when the agent was constructed,
|
|
2186
|
-
// long before this run existed, so the answers are copied in
|
|
2187
|
-
// rather than passed down.
|
|
2188
|
-
if (pendingResume.answers) {
|
|
2189
|
-
for (const [questionId, answer] of pendingResume.answers.entries()) {
|
|
2190
|
-
pendingAnswers.set(questionId, answer)
|
|
2191
|
-
}
|
|
2283
|
+
// The decision has now actually been carried out, so the park it
|
|
2284
|
+
// answered is no longer outstanding. Without this the checkpoint
|
|
2285
|
+
// keeps reporting `pending` with no `resolvedAt`, and an approval
|
|
2286
|
+
// queue re-serves a call that already ran — or a question already
|
|
2287
|
+
// answered — which defeats the entire point of recording the park.
|
|
2288
|
+
//
|
|
2289
|
+
// Two arms reach this point, and being outside `if (pendingResume)`
|
|
2290
|
+
// is what the second one needs. One is a plan whose decision was
|
|
2291
|
+
// applied to a batch above. The other is the cadence arm, for which
|
|
2292
|
+
// `planPendingResume` rightly produces no plan because the loop
|
|
2293
|
+
// resuming IS its decision being carried out (`answeredParkId`, set
|
|
2294
|
+
// on the restore path). Resolving only the first left a finished turn
|
|
2295
|
+
// reporting `awaiting-decision` forever.
|
|
2296
|
+
//
|
|
2297
|
+
// What is RECORDED depends on which of the two produced the plan. A
|
|
2298
|
+
// recovery plan means the batch was answered by the crash path
|
|
2299
|
+
// rather than by the decision — the calls the human was asked about
|
|
2300
|
+
// were closed with explicitly unknown outcomes — so the human's
|
|
2301
|
+
// answer must not be written down as what ended the park. The park is
|
|
2302
|
+
// still resolved: the question is moot, and leaving it outstanding
|
|
2303
|
+
// would have `findPendingCheckpoint` serve it as the newest
|
|
2304
|
+
// outstanding park, so a host resuming it would rewind this turn to
|
|
2305
|
+
// the checkpoint the crash happened on and re-execute a batch the turn
|
|
2306
|
+
// has long since moved past.
|
|
2307
|
+
const resolvedCheckpointId = pendingResume?.checkpointId ?? answeredParkId
|
|
2308
|
+
const recordedDecision =
|
|
2309
|
+
pendingResume?.source === 'recovery' && params.pendingDecision
|
|
2310
|
+
? supersededByRecovery(params.pendingDecision)
|
|
2311
|
+
: params.pendingDecision
|
|
2312
|
+
if (recordedDecision && resolvedCheckpointId) {
|
|
2313
|
+
await checkpointMgr
|
|
2314
|
+
.unpark(resolvedCheckpointId, recordedDecision)
|
|
2315
|
+
.catch((err: unknown) => {
|
|
2316
|
+
ctx.log.error('Applied a pending decision but failed to clear the park', {
|
|
2317
|
+
[NAMZU.TURN_ID]: ctx.turnId,
|
|
2318
|
+
'namzu.checkpoint.id': resolvedCheckpointId,
|
|
2319
|
+
'exception.message': err instanceof Error ? err.message : String(err),
|
|
2320
|
+
})
|
|
2321
|
+
return null
|
|
2322
|
+
})
|
|
2192
2323
|
}
|
|
2193
2324
|
|
|
2194
|
-
|
|
2195
|
-
yield* eventTranslator.drainPending()
|
|
2196
|
-
}
|
|
2325
|
+
yield* iterationOrchestrator.runLoop()
|
|
2197
2326
|
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
})
|
|
2234
|
-
return null
|
|
2327
|
+
yield* finalizeTurn({
|
|
2328
|
+
ctx,
|
|
2329
|
+
params,
|
|
2330
|
+
eventTranslator,
|
|
2331
|
+
takeSteps: () => iterationOrchestrator.getSteps(),
|
|
2332
|
+
workingStateManager,
|
|
2333
|
+
resultAssembler,
|
|
2334
|
+
rootSpan,
|
|
2335
|
+
})
|
|
2336
|
+
} catch (err) {
|
|
2337
|
+
// Another turn is active in this session: nothing of this turn was
|
|
2338
|
+
// written, so there is nothing to settle. The caller gets the
|
|
2339
|
+
// refusal itself.
|
|
2340
|
+
if (isTurnInProgressError(err) && !ctx.recorder.isActive) throw err
|
|
2341
|
+
// A failed turn still spent its steps; report them.
|
|
2342
|
+
ctx.recorder.setSteps(iterationOrchestrator.getSteps())
|
|
2343
|
+
await executeUserInterruptHooks(err)
|
|
2344
|
+
yield* eventTranslator.drainPending()
|
|
2345
|
+
yield* resultAssembler.handleError(err, rootSpan)
|
|
2346
|
+
} finally {
|
|
2347
|
+
yield* releaseTurnResources({
|
|
2348
|
+
ctx,
|
|
2349
|
+
eventTranslator,
|
|
2350
|
+
unsubscribeJobExits,
|
|
2351
|
+
unsubscribeTaskStore,
|
|
2352
|
+
awaitedJobs,
|
|
2353
|
+
backgroundJobs: params.backgroundJobs,
|
|
2354
|
+
backgroundJobOwner: params.backgroundJobOwner,
|
|
2355
|
+
questionParks,
|
|
2356
|
+
workingStateManager,
|
|
2357
|
+
promoteMemory: params.promoteMemory,
|
|
2358
|
+
sandbox,
|
|
2359
|
+
sandboxTeardownTimeoutMs,
|
|
2360
|
+
runStartedAt,
|
|
2361
|
+
rootSpan,
|
|
2235
2362
|
})
|
|
2236
2363
|
}
|
|
2237
2364
|
|
|
2238
|
-
|
|
2365
|
+
// Reached only by a turn that settled on its own terms. `finalize()` is
|
|
2366
|
+
// the only thing in this body that writes the durable half of the turn,
|
|
2367
|
+
// and a `return` completion arriving from a consumer (`break` out of
|
|
2368
|
+
// `for await`, `gen.return()`) runs the `finally` above and stops short
|
|
2369
|
+
// of here. The flag is what tells the two apart, and this is one of
|
|
2370
|
+
// three sites that set it — the sandbox-acquisition and input-guardrail
|
|
2371
|
+
// returns settle early and set it there. Set before the await rather
|
|
2372
|
+
// than after, because a store that throws on the way out must not send
|
|
2373
|
+
// the abandonment path over the same broken ground.
|
|
2374
|
+
settled = true
|
|
2375
|
+
return await resultAssembler.finalize()
|
|
2376
|
+
})()
|
|
2239
2377
|
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
params,
|
|
2243
|
-
eventTranslator,
|
|
2244
|
-
takeSteps: () => iterationOrchestrator.getSteps(),
|
|
2245
|
-
workingStateManager,
|
|
2246
|
-
resultAssembler,
|
|
2247
|
-
rootSpan,
|
|
2248
|
-
})
|
|
2249
|
-
} catch (err) {
|
|
2250
|
-
// A failed run still spent its steps; report them.
|
|
2251
|
-
ctx.runMgr.setSteps(iterationOrchestrator.getSteps())
|
|
2252
|
-
await executeUserInterruptHooks(err)
|
|
2253
|
-
yield* eventTranslator.drainPending()
|
|
2254
|
-
yield* resultAssembler.handleError(err, rootSpan)
|
|
2378
|
+
try {
|
|
2379
|
+
return yield* runBody
|
|
2255
2380
|
} finally {
|
|
2256
|
-
|
|
2257
|
-
ctx,
|
|
2258
|
-
eventTranslator,
|
|
2259
|
-
emergencyManager,
|
|
2260
|
-
unsubscribeJobExits,
|
|
2261
|
-
unsubscribeTaskStore,
|
|
2262
|
-
awaitedJobs,
|
|
2263
|
-
backgroundJobs: params.backgroundJobs,
|
|
2264
|
-
backgroundJobOwner: params.backgroundJobOwner,
|
|
2265
|
-
questionParks,
|
|
2266
|
-
workingStateManager,
|
|
2267
|
-
promoteMemory: params.promoteMemory,
|
|
2268
|
-
sandbox,
|
|
2269
|
-
sandboxTeardownTimeoutMs,
|
|
2270
|
-
runStartedAt,
|
|
2271
|
-
rootSpan,
|
|
2272
|
-
})
|
|
2381
|
+
if (!settled) await settleAbandonedTurn(ctx.recorder, eventTranslator, ctx.log)
|
|
2273
2382
|
}
|
|
2274
|
-
|
|
2275
|
-
// Reached only by a run that settled on its own terms. `finalize()` is
|
|
2276
|
-
// the only thing in this body that writes the durable half of the run,
|
|
2277
|
-
// and a `return` completion arriving from a consumer (`break` out of
|
|
2278
|
-
// `for await`, `gen.return()`) runs the `finally` above and stops short
|
|
2279
|
-
// of here. The flag is what tells the two apart, and this is one of
|
|
2280
|
-
// three sites that set it — the sandbox-acquisition and input-guardrail
|
|
2281
|
-
// returns settle early and set it there. Set before the await rather
|
|
2282
|
-
// than after, because a store that throws on the way out must not send
|
|
2283
|
-
// the abandonment path over the same broken ground.
|
|
2284
|
-
settled = true
|
|
2285
|
-
return await resultAssembler.finalize()
|
|
2286
|
-
})()
|
|
2287
|
-
|
|
2288
|
-
try {
|
|
2289
|
-
return yield* runBody
|
|
2290
2383
|
} finally {
|
|
2291
|
-
|
|
2384
|
+
unsubscribeChildSessions?.()
|
|
2385
|
+
// The lease `open()` took in the prelude; a caller-supplied lease is the
|
|
2386
|
+
// caller's to give back.
|
|
2387
|
+
await ctx.recorder.release()
|
|
2292
2388
|
}
|
|
2293
2389
|
}
|
|
2294
2390
|
|
|
2295
2391
|
/**
|
|
2296
|
-
* Write a
|
|
2297
|
-
*
|
|
2298
|
-
* `for await (… ) break` and an explicit `gen.return()` both end the run
|
|
2299
|
-
* body early. Everything the run's `finally` owns still happens — background
|
|
2300
|
-
* jobs are killed, the sandbox is destroyed, the span ends, the duration is
|
|
2301
|
-
* recorded — and then the generator stops. `finalize()` never runs, so
|
|
2302
|
-
* `persist()` never runs, and the store keeps whatever `init()` wrote: a
|
|
2303
|
-
* non-terminal status for a run that no longer exists. `deriveRunStatus`
|
|
2304
|
-
* reads that record back as `queued`, work waiting to start, and a host
|
|
2305
|
-
* rebuilding its view from the store believes it.
|
|
2392
|
+
* Write a durable record for a turn whose consumer walked away.
|
|
2306
2393
|
*
|
|
2307
|
-
*
|
|
2308
|
-
*
|
|
2309
|
-
* the
|
|
2394
|
+
* `for await (… ) break` and an explicit `gen.return()` both end the turn
|
|
2395
|
+
* body early. Everything the body's `finally` owns still happens — jobs are
|
|
2396
|
+
* killed, the sandbox is destroyed, the span ends — and then the generator
|
|
2397
|
+
* stops without settling. Without this the log would end mid-turn, and the
|
|
2398
|
+
* turn would read as `interrupted` for a process that is gone.
|
|
2310
2399
|
*
|
|
2311
|
-
*
|
|
2312
|
-
*
|
|
2313
|
-
*
|
|
2314
|
-
*
|
|
2315
|
-
*
|
|
2316
|
-
*
|
|
2317
|
-
* down. It needs no new `RunExecutionStatus` and no new `StopReason`.
|
|
2318
|
-
*
|
|
2319
|
-
* A verdict the run already reached is left standing. A run that failed,
|
|
2320
|
-
* or was cancelled, before the consumer left still says so; what the
|
|
2321
|
-
* abandonment adds is that the record reaches the disk at all.
|
|
2322
|
-
*
|
|
2323
|
-
* Neither is a verdict written over a PARK. A park is a promise to a human
|
|
2324
|
-
* that outlives the consumer: the run is resumable and somebody is still owed
|
|
2325
|
-
* an answer, and `deriveRunStatus` reads a terminal status BEFORE it reads the
|
|
2326
|
-
* park — so recording `cancelled` turns `awaiting_hitl` into `cancelled` for a
|
|
2327
|
-
* run nobody answered for, while the unanswered question stays on the record
|
|
2328
|
-
* and the checkpoint it belongs to stays the place a resume starts from. The
|
|
2329
|
-
* durable state is asked rather than the in-memory one because the in-memory
|
|
2330
|
-
* one is the misleading half here: `handleHITLDecision` emits `run_paused` and
|
|
2331
|
-
* drains it BEFORE it calls `setStopReason('paused')`, so a consumer that
|
|
2332
|
-
* leaves on that event leaves a run whose status is `running` and whose stop
|
|
2333
|
-
* reason is unset at the exact instant its park is already durable.
|
|
2334
|
-
* `findPendingCheckpoint` is the same read an approval queue is built from,
|
|
2335
|
-
* expired parks included in its judgement: a park nobody answered in time is
|
|
2336
|
-
* not somebody still being asked.
|
|
2400
|
+
* - A turn that already settled, or already paused, is left as it stands.
|
|
2401
|
+
* - A turn parked on a decision (an open `decision_requested`) is PAUSED on
|
|
2402
|
+
* that checkpoint: a park is a promise to a human that outlives the
|
|
2403
|
+
* consumer, and `resumeSession` continues it once the answer arrives.
|
|
2404
|
+
* - Any other turn is settled `cancelled` (`turn_completed`): it did not
|
|
2405
|
+
* complete and nothing failed; its consumer stopped reading.
|
|
2337
2406
|
*
|
|
2338
2407
|
* Never throws. It runs while an exception may already be unwinding, and a
|
|
2339
|
-
*
|
|
2340
|
-
* its own.
|
|
2408
|
+
* log that cannot be written must not replace the turn's real failure.
|
|
2341
2409
|
*/
|
|
2342
|
-
async function
|
|
2410
|
+
async function settleAbandonedTurn(
|
|
2411
|
+
recorder: TurnRecorder,
|
|
2412
|
+
eventTranslator: EventTranslator,
|
|
2413
|
+
log: Logger,
|
|
2414
|
+
): Promise<void> {
|
|
2343
2415
|
try {
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
}
|
|
2362
|
-
runMgr.markCancelled()
|
|
2416
|
+
if (recorder.isClosed || recorder.isPaused || !recorder.isActive) return
|
|
2417
|
+
await recorder.flush()
|
|
2418
|
+
const parked = await findPendingCheckpoint(recorder.log, { turnId: recorder.turnId })
|
|
2419
|
+
if (parked) {
|
|
2420
|
+
recorder.setStopReason('paused')
|
|
2421
|
+
await eventTranslator.emitEvent({
|
|
2422
|
+
type: 'turn_paused',
|
|
2423
|
+
checkpointId: parked.checkpointId,
|
|
2424
|
+
reason: 'The consumer stopped reading while the turn was awaiting a decision.',
|
|
2425
|
+
})
|
|
2426
|
+
await recorder.persist()
|
|
2427
|
+
log.info('Abandoned turn left paused for a human to answer', {
|
|
2428
|
+
[NAMZU.TURN_ID]: recorder.turnId,
|
|
2429
|
+
'namzu.checkpoint.id': parked.checkpointId,
|
|
2430
|
+
'namzu.runtime.park_type': parked.pending.request.type,
|
|
2431
|
+
})
|
|
2432
|
+
return
|
|
2363
2433
|
}
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2434
|
+
if (!isTerminalStatus(recorder.status)) recorder.markCancelled()
|
|
2435
|
+
await eventTranslator.emitEvent({
|
|
2436
|
+
type: 'turn_completed',
|
|
2437
|
+
result: recorder.getTurn().result ?? '',
|
|
2438
|
+
...(recorder.stopReason ? { stopReason: recorder.stopReason } : {}),
|
|
2439
|
+
settlement: recorder.settlement(recorder.status === 'cancelled' ? 'cancelled' : 'completed'),
|
|
2440
|
+
})
|
|
2441
|
+
await recorder.persist()
|
|
2442
|
+
log.info('Abandoned turn recorded as cancelled', {
|
|
2443
|
+
[NAMZU.TURN_ID]: recorder.turnId,
|
|
2370
2444
|
})
|
|
2371
2445
|
} catch (err) {
|
|
2372
|
-
log.error('Failed to record the
|
|
2373
|
-
[NAMZU.
|
|
2446
|
+
log.error('Failed to record the end of an abandoned turn', {
|
|
2447
|
+
[NAMZU.TURN_ID]: recorder.turnId,
|
|
2374
2448
|
'exception.message': err instanceof Error ? err.message : String(err),
|
|
2375
2449
|
})
|
|
2376
2450
|
}
|
|
@@ -2391,8 +2465,8 @@ type DrainQueryParams = Omit<QueryParams, 'resumeHandler'> & {
|
|
|
2391
2465
|
|
|
2392
2466
|
async function drainPreparedQuery(
|
|
2393
2467
|
fullParams: QueryParams,
|
|
2394
|
-
listener?:
|
|
2395
|
-
): Promise<
|
|
2468
|
+
listener?: SessionEventListener,
|
|
2469
|
+
): Promise<Turn> {
|
|
2396
2470
|
const gen = query(fullParams)
|
|
2397
2471
|
let result = await gen.next()
|
|
2398
2472
|
|
|
@@ -2410,8 +2484,8 @@ export async function drainQuery(
|
|
|
2410
2484
|
params: Omit<QueryParams, 'resumeHandler'> & {
|
|
2411
2485
|
resumeHandler?: ResumeHandler
|
|
2412
2486
|
},
|
|
2413
|
-
listener?:
|
|
2414
|
-
): Promise<
|
|
2487
|
+
listener?: SessionEventListener,
|
|
2488
|
+
): Promise<Turn> {
|
|
2415
2489
|
const fullParams: QueryParams = {
|
|
2416
2490
|
...params,
|
|
2417
2491
|
resumeHandler: params.resumeHandler ?? autoApproveHandler,
|
|
@@ -2419,12 +2493,12 @@ export async function drainQuery(
|
|
|
2419
2493
|
return await drainPreparedQuery(fullParams, listener)
|
|
2420
2494
|
}
|
|
2421
2495
|
|
|
2422
|
-
/** @internal Canonical resume state already selected by `
|
|
2496
|
+
/** @internal Canonical resume state already selected by `resumeSession`. */
|
|
2423
2497
|
export async function drainQueryWithSelectedResumeState(
|
|
2424
2498
|
params: DrainQueryParams,
|
|
2425
2499
|
state: SelectedResumeState,
|
|
2426
|
-
listener?:
|
|
2427
|
-
): Promise<
|
|
2500
|
+
listener?: SessionEventListener,
|
|
2501
|
+
): Promise<Turn> {
|
|
2428
2502
|
const fullParams: QueryParams = {
|
|
2429
2503
|
...params,
|
|
2430
2504
|
resumeHandler: params.resumeHandler ?? autoApproveHandler,
|
|
@@ -2439,17 +2513,17 @@ export async function drainQueryWithSelectedResumeState(
|
|
|
2439
2513
|
|
|
2440
2514
|
function assertSelectedResumeAttribution(params: QueryParams, state: SelectedResumeState): void {
|
|
2441
2515
|
const mismatchedFields: string[] = []
|
|
2442
|
-
if (params.
|
|
2516
|
+
if (params.turnId !== state.turnId) mismatchedFields.push('turnId')
|
|
2443
2517
|
if (params.sessionId !== state.sessionId) mismatchedFields.push('sessionId')
|
|
2444
2518
|
if (params.topicId !== state.topicId) mismatchedFields.push('topicId')
|
|
2445
2519
|
if (params.projectId !== state.projectId) mismatchedFields.push('projectId')
|
|
2446
2520
|
if (params.tenantId !== state.tenantId) mismatchedFields.push('tenantId')
|
|
2447
|
-
if (params.
|
|
2521
|
+
if (params.parentSessionId !== state.parentSessionId) mismatchedFields.push('parentSessionId')
|
|
2448
2522
|
if (mismatchedFields.length === 0) return
|
|
2449
2523
|
|
|
2450
2524
|
throw new NamzuError({
|
|
2451
2525
|
code: 'invalid_config',
|
|
2452
|
-
message: 'The selected resume state does not match the
|
|
2526
|
+
message: 'The selected resume state does not match the turn attribution supplied to the query.',
|
|
2453
2527
|
details: { fields: mismatchedFields },
|
|
2454
2528
|
})
|
|
2455
2529
|
}
|