@namzu/sdk 3.1.0 → 3.3.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 +221 -0
- package/dist/advisory/__tests__/consultation-context.test.d.ts +2 -0
- package/dist/advisory/__tests__/consultation-context.test.d.ts.map +1 -0
- package/dist/advisory/__tests__/consultation-context.test.js +124 -0
- package/dist/advisory/__tests__/consultation-context.test.js.map +1 -0
- package/dist/advisory/context.d.ts +25 -0
- package/dist/advisory/context.d.ts.map +1 -1
- package/dist/advisory/context.js +18 -0
- package/dist/advisory/context.js.map +1 -1
- package/dist/advisory/executor.d.ts.map +1 -1
- package/dist/advisory/executor.js +25 -3
- package/dist/advisory/executor.js.map +1 -1
- package/dist/agents/SupervisorAgent.d.ts.map +1 -1
- package/dist/agents/SupervisorAgent.js +6 -0
- package/dist/agents/SupervisorAgent.js.map +1 -1
- package/dist/agents/__tests__/supervisor-hands-down-hitl.test.d.ts +2 -0
- package/dist/agents/__tests__/supervisor-hands-down-hitl.test.d.ts.map +1 -0
- package/dist/agents/__tests__/supervisor-hands-down-hitl.test.js +112 -0
- package/dist/agents/__tests__/supervisor-hands-down-hitl.test.js.map +1 -0
- package/dist/compaction/__tests__/context-reducer.test.d.ts +2 -0
- package/dist/compaction/__tests__/context-reducer.test.d.ts.map +1 -0
- package/dist/compaction/__tests__/context-reducer.test.js +197 -0
- package/dist/compaction/__tests__/context-reducer.test.js.map +1 -0
- package/dist/compaction/factory.d.ts +7 -0
- package/dist/compaction/factory.d.ts.map +1 -1
- package/dist/compaction/factory.js +7 -0
- package/dist/compaction/factory.js.map +1 -1
- package/dist/compaction/index.d.ts +2 -0
- package/dist/compaction/index.d.ts.map +1 -1
- package/dist/compaction/index.js +1 -0
- package/dist/compaction/index.js.map +1 -1
- package/dist/compaction/interface.d.ts +13 -0
- package/dist/compaction/interface.d.ts.map +1 -1
- package/dist/compaction/managers/null.d.ts +3 -0
- package/dist/compaction/managers/null.d.ts.map +1 -1
- package/dist/compaction/managers/null.js +3 -0
- package/dist/compaction/managers/null.js.map +1 -1
- package/dist/compaction/managers/slidingWindow.d.ts +6 -0
- package/dist/compaction/managers/slidingWindow.d.ts.map +1 -1
- package/dist/compaction/managers/slidingWindow.js +6 -0
- package/dist/compaction/managers/slidingWindow.js.map +1 -1
- package/dist/compaction/managers/structured.d.ts +10 -0
- package/dist/compaction/managers/structured.d.ts.map +1 -1
- package/dist/compaction/managers/structured.js +10 -0
- package/dist/compaction/managers/structured.js.map +1 -1
- package/dist/compaction/reducer.d.ts +86 -0
- package/dist/compaction/reducer.d.ts.map +1 -0
- package/dist/compaction/reducer.js +77 -0
- package/dist/compaction/reducer.js.map +1 -0
- package/dist/connector/builtins/__tests__/oauth2-auth.test.d.ts +2 -0
- package/dist/connector/builtins/__tests__/oauth2-auth.test.d.ts.map +1 -0
- package/dist/connector/builtins/__tests__/oauth2-auth.test.js +54 -0
- package/dist/connector/builtins/__tests__/oauth2-auth.test.js.map +1 -0
- package/dist/connector/builtins/http.d.ts.map +1 -1
- package/dist/connector/builtins/http.js +24 -2
- package/dist/connector/builtins/http.js.map +1 -1
- package/dist/connector/builtins/http.test.js +18 -2
- package/dist/connector/builtins/http.test.js.map +1 -1
- package/dist/connector/index.d.ts +3 -2
- package/dist/connector/index.d.ts.map +1 -1
- package/dist/connector/index.js +2 -1
- package/dist/connector/index.js.map +1 -1
- package/dist/connector/mcp/__tests__/prompt-as-tool.test.d.ts +2 -0
- package/dist/connector/mcp/__tests__/prompt-as-tool.test.d.ts.map +1 -0
- package/dist/connector/mcp/__tests__/prompt-as-tool.test.js +122 -0
- package/dist/connector/mcp/__tests__/prompt-as-tool.test.js.map +1 -0
- package/dist/connector/mcp/__tests__/prompts-and-lifecycle.test.d.ts +2 -0
- package/dist/connector/mcp/__tests__/prompts-and-lifecycle.test.d.ts.map +1 -0
- package/dist/connector/mcp/__tests__/prompts-and-lifecycle.test.js +214 -0
- package/dist/connector/mcp/__tests__/prompts-and-lifecycle.test.js.map +1 -0
- package/dist/connector/mcp/client.d.ts +52 -1
- package/dist/connector/mcp/client.d.ts.map +1 -1
- package/dist/connector/mcp/client.js +86 -0
- package/dist/connector/mcp/client.js.map +1 -1
- package/dist/connector/mcp/discovery.d.ts +27 -2
- package/dist/connector/mcp/discovery.d.ts.map +1 -1
- package/dist/connector/mcp/discovery.js +58 -5
- package/dist/connector/mcp/discovery.js.map +1 -1
- package/dist/connector/mcp/index.d.ts +4 -3
- package/dist/connector/mcp/index.d.ts.map +1 -1
- package/dist/connector/mcp/index.js +3 -2
- package/dist/connector/mcp/index.js.map +1 -1
- package/dist/connector/mcp/policy.d.ts +17 -0
- package/dist/connector/mcp/policy.d.ts.map +1 -1
- package/dist/connector/mcp/policy.js +18 -7
- package/dist/connector/mcp/policy.js.map +1 -1
- package/dist/connector/mcp/prompt-adapter.d.ts +39 -0
- package/dist/connector/mcp/prompt-adapter.d.ts.map +1 -0
- package/dist/connector/mcp/prompt-adapter.js +113 -0
- package/dist/connector/mcp/prompt-adapter.js.map +1 -0
- package/dist/connector/mcp/server.d.ts +42 -1
- package/dist/connector/mcp/server.d.ts.map +1 -1
- package/dist/connector/mcp/server.js +77 -4
- package/dist/connector/mcp/server.js.map +1 -1
- package/dist/manager/agent/__tests__/depth-limit-authority.test.d.ts +2 -0
- package/dist/manager/agent/__tests__/depth-limit-authority.test.d.ts.map +1 -0
- package/dist/manager/agent/__tests__/depth-limit-authority.test.js +58 -0
- package/dist/manager/agent/__tests__/depth-limit-authority.test.js.map +1 -0
- package/dist/manager/agent/__tests__/hitl-across-spawn.test.d.ts +2 -0
- package/dist/manager/agent/__tests__/hitl-across-spawn.test.d.ts.map +1 -0
- package/dist/manager/agent/__tests__/hitl-across-spawn.test.js +226 -0
- package/dist/manager/agent/__tests__/hitl-across-spawn.test.js.map +1 -0
- package/dist/manager/agent/lifecycle.d.ts.map +1 -1
- package/dist/manager/agent/lifecycle.js +13 -0
- package/dist/manager/agent/lifecycle.js.map +1 -1
- package/dist/plugin/__tests__/discovery-scopes.test.d.ts +2 -0
- package/dist/plugin/__tests__/discovery-scopes.test.d.ts.map +1 -0
- package/dist/plugin/__tests__/discovery-scopes.test.js +97 -0
- package/dist/plugin/__tests__/discovery-scopes.test.js.map +1 -0
- package/dist/plugin/__tests__/enable-contributions.test.js +5 -1
- package/dist/plugin/__tests__/enable-contributions.test.js.map +1 -1
- package/dist/plugin/__tests__/mcp-admission.test.d.ts +2 -0
- package/dist/plugin/__tests__/mcp-admission.test.d.ts.map +1 -0
- package/dist/plugin/__tests__/mcp-admission.test.js +227 -0
- package/dist/plugin/__tests__/mcp-admission.test.js.map +1 -0
- package/dist/plugin/lifecycle.d.ts +41 -0
- package/dist/plugin/lifecycle.d.ts.map +1 -1
- package/dist/plugin/lifecycle.js +39 -1
- package/dist/plugin/lifecycle.js.map +1 -1
- package/dist/plugin/loader.d.ts +39 -3
- package/dist/plugin/loader.d.ts.map +1 -1
- package/dist/plugin/loader.js +37 -4
- package/dist/plugin/loader.js.map +1 -1
- package/dist/public-runtime.d.ts +4 -2
- package/dist/public-runtime.d.ts.map +1 -1
- package/dist/public-runtime.js +5 -2
- package/dist/public-runtime.js.map +1 -1
- package/dist/public-types.d.ts +2 -2
- package/dist/public-types.d.ts.map +1 -1
- package/dist/rag/__tests__/namespace-isolation.test.d.ts +2 -0
- package/dist/rag/__tests__/namespace-isolation.test.d.ts.map +1 -0
- package/dist/rag/__tests__/namespace-isolation.test.js +80 -0
- package/dist/rag/__tests__/namespace-isolation.test.js.map +1 -0
- package/dist/rag/ingestion.d.ts.map +1 -1
- package/dist/rag/ingestion.js +1 -0
- package/dist/rag/ingestion.js.map +1 -1
- package/dist/rag/retriever.d.ts.map +1 -1
- package/dist/rag/retriever.js +2 -0
- package/dist/rag/retriever.js.map +1 -1
- package/dist/rag/vector-store.d.ts.map +1 -1
- package/dist/rag/vector-store.js +6 -0
- package/dist/rag/vector-store.js.map +1 -1
- package/dist/registry/tool/execute.d.ts.map +1 -1
- package/dist/registry/tool/execute.js +113 -109
- package/dist/registry/tool/execute.js.map +1 -1
- package/dist/runtime/query/__tests__/per-step-skills.test.d.ts +10 -0
- package/dist/runtime/query/__tests__/per-step-skills.test.d.ts.map +1 -0
- package/dist/runtime/query/__tests__/per-step-skills.test.js +122 -0
- package/dist/runtime/query/__tests__/per-step-skills.test.js.map +1 -0
- package/dist/runtime/query/__tests__/per-step-tool-choice.test.d.ts +2 -0
- package/dist/runtime/query/__tests__/per-step-tool-choice.test.d.ts.map +1 -0
- package/dist/runtime/query/__tests__/per-step-tool-choice.test.js +153 -0
- package/dist/runtime/query/__tests__/per-step-tool-choice.test.js.map +1 -0
- package/dist/runtime/query/__tests__/resume-run.test.d.ts +2 -0
- package/dist/runtime/query/__tests__/resume-run.test.d.ts.map +1 -0
- package/dist/runtime/query/__tests__/resume-run.test.js +211 -0
- package/dist/runtime/query/__tests__/resume-run.test.js.map +1 -0
- package/dist/runtime/query/index.d.ts +10 -0
- package/dist/runtime/query/index.d.ts.map +1 -1
- package/dist/runtime/query/index.js +26 -0
- package/dist/runtime/query/index.js.map +1 -1
- package/dist/runtime/query/iteration/index.d.ts.map +1 -1
- package/dist/runtime/query/iteration/index.js +50 -33
- package/dist/runtime/query/iteration/index.js.map +1 -1
- package/dist/runtime/query/iteration/phases/compaction-model-routing.test.d.ts +2 -0
- package/dist/runtime/query/iteration/phases/compaction-model-routing.test.d.ts.map +1 -0
- package/dist/runtime/query/iteration/phases/compaction-model-routing.test.js +96 -0
- package/dist/runtime/query/iteration/phases/compaction-model-routing.test.js.map +1 -0
- package/dist/runtime/query/iteration/phases/compaction.d.ts.map +1 -1
- package/dist/runtime/query/iteration/phases/compaction.js +95 -5
- package/dist/runtime/query/iteration/phases/compaction.js.map +1 -1
- package/dist/runtime/query/iteration/phases/context-reducer-dispatch.test.d.ts +2 -0
- package/dist/runtime/query/iteration/phases/context-reducer-dispatch.test.d.ts.map +1 -0
- package/dist/runtime/query/iteration/phases/context-reducer-dispatch.test.js +180 -0
- package/dist/runtime/query/iteration/phases/context-reducer-dispatch.test.js.map +1 -0
- package/dist/runtime/query/iteration/phases/context.d.ts +9 -0
- package/dist/runtime/query/iteration/phases/context.d.ts.map +1 -1
- package/dist/runtime/query/iteration/phases/context.js.map +1 -1
- package/dist/runtime/query/resume-run.d.ts +70 -0
- package/dist/runtime/query/resume-run.d.ts.map +1 -0
- package/dist/runtime/query/resume-run.js +46 -0
- package/dist/runtime/query/resume-run.js.map +1 -0
- package/dist/telemetry/__tests__/model-call-span.test.d.ts +2 -0
- package/dist/telemetry/__tests__/model-call-span.test.d.ts.map +1 -0
- package/dist/telemetry/__tests__/model-call-span.test.js +152 -0
- package/dist/telemetry/__tests__/model-call-span.test.js.map +1 -0
- package/dist/telemetry/__tests__/span-closure.test.d.ts +2 -0
- package/dist/telemetry/__tests__/span-closure.test.d.ts.map +1 -0
- package/dist/telemetry/__tests__/span-closure.test.js +124 -0
- package/dist/telemetry/__tests__/span-closure.test.js.map +1 -0
- package/dist/tools/advisory/index.js +1 -1
- package/dist/tools/advisory/index.js.map +1 -1
- package/dist/tools/coordinator/__tests__/plan-dependencies.test.d.ts +2 -0
- package/dist/tools/coordinator/__tests__/plan-dependencies.test.d.ts.map +1 -0
- package/dist/tools/coordinator/__tests__/plan-dependencies.test.js +126 -0
- package/dist/tools/coordinator/__tests__/plan-dependencies.test.js.map +1 -0
- package/dist/tools/coordinator/index.d.ts.map +1 -1
- package/dist/tools/coordinator/index.js +13 -1
- package/dist/tools/coordinator/index.js.map +1 -1
- package/dist/tools/coordinator/plan-dependencies.d.ts +43 -0
- package/dist/tools/coordinator/plan-dependencies.d.ts.map +1 -0
- package/dist/tools/coordinator/plan-dependencies.js +148 -0
- package/dist/tools/coordinator/plan-dependencies.js.map +1 -0
- package/dist/types/agent/base.d.ts +26 -0
- package/dist/types/agent/base.d.ts.map +1 -1
- package/dist/types/agent/supervisor.d.ts +15 -0
- package/dist/types/agent/supervisor.d.ts.map +1 -1
- package/dist/types/agent/task.d.ts +17 -0
- package/dist/types/agent/task.d.ts.map +1 -1
- package/dist/types/agent/task.js.map +1 -1
- package/dist/types/connector/core.d.ts +34 -0
- package/dist/types/connector/core.d.ts.map +1 -1
- package/dist/types/connector/definition.d.ts +10 -0
- package/dist/types/connector/definition.d.ts.map +1 -1
- package/dist/types/connector/mcp.d.ts +13 -0
- package/dist/types/connector/mcp.d.ts.map +1 -1
- package/dist/types/rag/retrieval.d.ts +16 -0
- package/dist/types/rag/retrieval.d.ts.map +1 -1
- package/dist/types/rag/storage.d.ts +9 -0
- package/dist/types/rag/storage.d.ts.map +1 -1
- package/dist/types/rag/vector.d.ts +11 -0
- package/dist/types/rag/vector.d.ts.map +1 -1
- package/dist/types/router/task-router.d.ts +19 -0
- package/dist/types/router/task-router.d.ts.map +1 -1
- package/dist/types/run/prepare-step.d.ts +56 -3
- package/dist/types/run/prepare-step.d.ts.map +1 -1
- package/dist/types/toolset/index.d.ts +22 -0
- package/dist/types/toolset/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/advisory/__tests__/consultation-context.test.ts +191 -0
- package/src/advisory/context.ts +32 -0
- package/src/advisory/executor.ts +30 -3
- package/src/agents/SupervisorAgent.ts +6 -0
- package/src/agents/__tests__/supervisor-hands-down-hitl.test.ts +131 -0
- package/src/compaction/__tests__/context-reducer.test.ts +239 -0
- package/src/compaction/factory.ts +7 -0
- package/src/compaction/index.ts +8 -0
- package/src/compaction/interface.ts +13 -0
- package/src/compaction/managers/null.ts +3 -0
- package/src/compaction/managers/slidingWindow.ts +6 -0
- package/src/compaction/managers/structured.ts +10 -0
- package/src/compaction/reducer.ts +154 -0
- package/src/connector/builtins/__tests__/oauth2-auth.test.ts +73 -0
- package/src/connector/builtins/http.test.ts +28 -2
- package/src/connector/builtins/http.ts +26 -2
- package/src/connector/index.ts +7 -2
- package/src/connector/mcp/__tests__/prompt-as-tool.test.ts +157 -0
- package/src/connector/mcp/__tests__/prompts-and-lifecycle.test.ts +286 -0
- package/src/connector/mcp/client.ts +95 -0
- package/src/connector/mcp/discovery.ts +67 -5
- package/src/connector/mcp/index.ts +8 -3
- package/src/connector/mcp/policy.ts +23 -8
- package/src/connector/mcp/prompt-adapter.ts +139 -0
- package/src/connector/mcp/server.ts +101 -3
- package/src/manager/agent/__tests__/depth-limit-authority.test.ts +74 -0
- package/src/manager/agent/__tests__/hitl-across-spawn.test.ts +273 -0
- package/src/manager/agent/lifecycle.ts +12 -0
- package/src/plugin/__tests__/discovery-scopes.test.ts +133 -0
- package/src/plugin/__tests__/enable-contributions.test.ts +5 -1
- package/src/plugin/__tests__/mcp-admission.test.ts +286 -0
- package/src/plugin/lifecycle.ts +68 -1
- package/src/plugin/loader.ts +57 -3
- package/src/public-runtime.ts +10 -0
- package/src/public-types.ts +5 -0
- package/src/rag/__tests__/namespace-isolation.test.ts +109 -0
- package/src/rag/ingestion.ts +1 -0
- package/src/rag/retriever.ts +2 -0
- package/src/rag/vector-store.ts +5 -0
- package/src/registry/tool/execute.ts +123 -119
- package/src/runtime/query/__tests__/per-step-skills.test.ts +154 -0
- package/src/runtime/query/__tests__/per-step-tool-choice.test.ts +180 -0
- package/src/runtime/query/__tests__/resume-run.test.ts +262 -0
- package/src/runtime/query/index.ts +39 -0
- package/src/runtime/query/iteration/index.ts +55 -34
- package/src/runtime/query/iteration/phases/compaction-model-routing.test.ts +125 -0
- package/src/runtime/query/iteration/phases/compaction.ts +106 -5
- package/src/runtime/query/iteration/phases/context-reducer-dispatch.test.ts +238 -0
- package/src/runtime/query/iteration/phases/context.ts +11 -0
- package/src/runtime/query/resume-run.ts +93 -0
- package/src/telemetry/__tests__/model-call-span.test.ts +195 -0
- package/src/telemetry/__tests__/span-closure.test.ts +153 -0
- package/src/tools/advisory/index.ts +1 -1
- package/src/tools/coordinator/__tests__/plan-dependencies.test.ts +186 -0
- package/src/tools/coordinator/index.ts +14 -1
- package/src/tools/coordinator/plan-dependencies.ts +175 -0
- package/src/types/agent/base.ts +27 -0
- package/src/types/agent/supervisor.ts +15 -0
- package/src/types/agent/task.ts +18 -0
- package/src/types/connector/core.ts +34 -0
- package/src/types/connector/definition.ts +10 -0
- package/src/types/connector/mcp.ts +14 -0
- package/src/types/rag/retrieval.ts +16 -0
- package/src/types/rag/storage.ts +9 -0
- package/src/types/rag/vector.ts +11 -0
- package/src/types/router/task-router.ts +19 -0
- package/src/types/run/prepare-step.ts +58 -3
- package/src/types/toolset/index.ts +22 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,226 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 3.3.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 635ffa9: A human's approval now crosses the spawn boundary.
|
|
8
|
+
|
|
9
|
+
`BaseAgentConfig` carried no resume handler. `SendMessageOptions.configOverrides` is a `Partial` of it, so a parent could not hand its decision channel to a child **at the type level** — and no runtime path could carry one either. Every delegated child fell through to the SDK's `autoApproveHandler`, however carefully its parent had been wired.
|
|
10
|
+
|
|
11
|
+
**What that cost, exactly.** A `VerificationGate` _deny_ still bit inside a child: denials are threaded into the executor and no later approval releases them. What was lost is the **review** tier — every call the gate left undecided reached the resume handler, and for a child that handler auto-approved. So a host running "ask before acting" had a human review `write` at the top level and never see the same `write` issued one hop down. The shipped CLI encodes the workaround as policy: its sub-agent prompt says _"do not ask the parent questions; make reasonable assumptions"_, because a question had nowhere to go.
|
|
12
|
+
|
|
13
|
+
`AgentTaskContext.resumeHandler` carries the parent's channel and `AgentManager` stamps it onto the child config — beside the trace parent and the tenant triple, for the same reason: a `configBuilder` is written by whoever registered the agent and cannot be trusted to forward something it was never told about. An explicit `configOverrides.resumeHandler` still wins, so one child can be given a different channel or none. `SupervisorAgent` now puts its own handler on the spawn context; it already gave that handler to its own run and its own coordinator tools, so the two had disagreed — the supervisor paused for a human while the workers it launched approved themselves.
|
|
14
|
+
|
|
15
|
+
Absent still means auto-approve. A host that never wired a handler is unaffected.
|
|
16
|
+
|
|
17
|
+
The handler is passed as the function itself, which works because delegation is in-process — `LocalTaskGateway` is the only gateway in the tree. A gateway dispatching across a process boundary could not carry a closure and would have to proxy the request onto the parent's event stream and route the answer back by request id. The upward half of that already exists: `wrapChildListener` stamps lineage on every child event the parent sees, and `user_question_asked` / `tool_review_requested` / `run_paused` are already typed events.
|
|
18
|
+
|
|
19
|
+
- 6015989: A published MCP prompt reaches the model.
|
|
20
|
+
|
|
21
|
+
`listPrompts` and `getPrompt` landed on the client and server last release and stopped there: a server could publish prompts, the SDK could fetch them, and nothing ever put one in front of a model. That shipped the protocol half without the consumer half — the same primitive-with-no-driver shape this series exists to remove, created by the fix for it.
|
|
22
|
+
|
|
23
|
+
A prompt is now adapted into a tool the model can call, `mcp_prompt_<server>_<name>`, with an input schema built from the arguments the prompt declares.
|
|
24
|
+
|
|
25
|
+
**Why a tool and not system content.** Folding a prompt into the system prompt puts remote text in the cached prefix, so every turn pays for it and the cache breaks whenever the server changes its wording — and system position _reads_ as instruction, which is the last thing text from a remote party should read as. A slash command would route through the host's UI, so a headless run could never use one. A tool call is explicit, auditable, passes the same admission policy and `allowedTools` filter as every other capability, and its answer arrives as a `tool_result`, which a model already treats as data returned by something rather than as direction.
|
|
26
|
+
|
|
27
|
+
The result is wrapped in an envelope naming the server and the prompt, and saying the content is material to work with rather than instructions. Untrusted content arriving through a tool result is the standard injection surface, and the mitigation that survives contact is saying plainly whose words these are. A server that returns an `assistant` message has that role reported inside the envelope, never turned into an assistant turn in the run's own history.
|
|
28
|
+
|
|
29
|
+
Prompts pass the **same admission policy** as tools, via a shared name check — a server publishing a prompt is the same trust question as one publishing a tool, and two copies of an allow/deny rule are two chances for one to drift permissive. They are namespaced apart from tools, since a server may publish both under one name and collapsing them would let whichever registered second replace the first.
|
|
30
|
+
|
|
31
|
+
A fetch that fails is returned to the model rather than thrown: a read-only lookup that a server cannot answer is something an agent can work around, and ending the run over it is the wrong trade.
|
|
32
|
+
|
|
33
|
+
### Patch Changes
|
|
34
|
+
|
|
35
|
+
- 82888c6: One `chat` span per model call, not two.
|
|
36
|
+
|
|
37
|
+
3.2.0 shipped a second `chat {model}` span. `stream-turn.ts` already opened one — with the same justification, that `chatSpanName` had no call sites — and 3.2.0 added another beside it, same name, same parent, both carrying token counts. A consumer summing spans double-counted latency and tokens.
|
|
38
|
+
|
|
39
|
+
Verified by execution rather than by reading: one scripted model call produced two `chat mock-model` spans, both with `gen_ai.usage.input_tokens`.
|
|
40
|
+
|
|
41
|
+
The one added in 3.2.0 is removed and the earlier one kept, because it is strictly better — it wraps the call itself and records time to first delta, which the later one did not.
|
|
42
|
+
|
|
43
|
+
**How it shipped, since that matters more than the fix.** The search that concluded "zero call sites" covered `telemetry/attributes.ts` and `constants/telemetry/` and never the runtime. Then the test asserting `toHaveLength(1)` failed with `2`, and the failure was explained away — attributed to a forced-final turn — and relaxed to `>= 1`. That relaxation is now reverted to an exact count, and a mutation confirms it catches a re-introduced duplicate as well as a removed span. The reasoning is recorded next to the assertion so the next person to see it fail with `2` reads the history instead of re-deriving the same wrong explanation.
|
|
44
|
+
|
|
45
|
+
Reported by a consuming host reading 3.2.0 against its own telemetry.
|
|
46
|
+
|
|
47
|
+
## 3.2.0
|
|
48
|
+
|
|
49
|
+
### Minor Changes
|
|
50
|
+
|
|
51
|
+
- 480892a: Context reduction is a real seam now, and `strategy` has three behaviours instead of two.
|
|
52
|
+
|
|
53
|
+
`compactionConfig.strategy` accepted `'structured' | 'sliding-window' | 'disabled'`, and the runtime asked one question about it: is it `'disabled'`. So `'sliding-window'` — the value a host picks precisely to avoid paying for summarization — ran the full structured pass, LLM verification call included. The config lied, and it lied in the direction of spending money.
|
|
54
|
+
|
|
55
|
+
`'sliding-window'` now trims: it keeps the recent turns, drops what precedes them, and summarizes nothing. Every survivor is verbatim. For an agent whose state lives outside the transcript — a task queue, a file it keeps editing, a working-memory block the host renders each turn — the paraphrase was only ever cost.
|
|
56
|
+
|
|
57
|
+
**A host can also supply their own.** `query({ contextReducer })` takes a function: messages and why it is being asked (`'threshold'` — the estimate says the window is filling; `'overflow'` — the provider already rejected the prompt), returning the shorter history or `undefined` for "I cannot shorten this". It may be async, so a reducer can call a model of its own. A reducer outranks the strategy and fully owns reduction for that run; the structured pass does not also run, because two mechanisms editing one history in the same pass cannot both be reasoned about.
|
|
58
|
+
|
|
59
|
+
Three ways a reducer's answer is declined, and the third is the interesting one. `undefined` is the reducer itself declining. A throw is treated as the same answer and logged — a broken reduction hook should not kill a healthy run, the same way a broken `prepareStep` does not. And a result that leaves a `tool_result` without its `tool_use` is **refused rather than repaired**: installing it would trade a nameable "your reducer split a tool pair" for an opaque provider rejection a call later, with the reducer never implicated.
|
|
60
|
+
|
|
61
|
+
The built-in reducer keeps the three invariants the type documents: the leading system floor stays, tool pairs stay together, and messages marked `retain` survive. Where no cut below the requested window is safe it takes one above rather than declining — in a multi-step turn every boundary lands on an assistant or tool message, so declining there would fail exactly when the history is longest.
|
|
62
|
+
|
|
63
|
+
`ConversationManager`, `createConversationManager`, `SlidingWindowManager`, `StructuredCompactionManager` and `NullManager` are **deprecated** and still exported. That interface cannot be implemented correctly: `reduceContext` is documented as reducing the history but takes `Message[]` and returns `boolean`, so the only way to honour it is in-place mutation — and neither shipped implementation does. Both build a shorter array locally, discard it, and return `true`. Nothing in the runtime ever called any of it, which is how an unfulfillable contract survived this long. Use `ContextReducer`.
|
|
64
|
+
|
|
65
|
+
- 480892a: Deprecate `ToolCatalogSurface` and `ToolsetPolicy.surfaces`.
|
|
66
|
+
|
|
67
|
+
Neither does anything. No code constructs a member of the union, and nothing reads the field that carries it — setting `surfaces` on a toolset policy has no effect and never had one.
|
|
68
|
+
|
|
69
|
+
It is also the wrong axis. Which tools a run may use is already expressible four ways, and all of them are per-run and dynamic where this is fixed at definition time: `allowedTools` on the query, `ToolAvailability` (`active` / `deferred` / `suspended`) with mid-run activation through tool search, `runtimeToolOverrides`, and capability negotiation stripping tools a driver cannot carry. `allowedTools` says the same thing, per run.
|
|
70
|
+
|
|
71
|
+
The member names — `chat`, `managed-agent`, `worker` — encode deployment shapes this kernel does not own, which is the deeper reason not to keep them. A host's surfaces are the host's to name.
|
|
72
|
+
|
|
73
|
+
Deprecated rather than removed because both are reachable from the published typings, so removing them is a breaking change. They go in the next major. This is the deprecation cycle the release policy asks for: a version where the code still compiles and warns.
|
|
74
|
+
|
|
75
|
+
- beacf2d: Three things the model or the host was invited to say, and the kernel discarded.
|
|
76
|
+
|
|
77
|
+
**Plan step dependencies.** `approve_plan` shows the model `depends_on` on every step, described as "Step descriptions this depends on", and then passed `dependsOn: []` for all of them. The declared ordering was dropped at the one place it entered the system. The visible cost is not scheduling — `PlanManager.getNextPendingStep` holds the dependency gate and currently has no callers — it is the **approval**: `dependsOn` is serialized into the `plan_approval` payload a human reads before saying yes, so a reviewer was shown a plan whose steps all looked independent however carefully the model had ordered them.
|
|
78
|
+
|
|
79
|
+
Descriptions now resolve to step ids, matched case- and whitespace-insensitively because a model does not reproduce its own strings byte-for-byte. Four things are **refused rather than dropped**, each with the offending text named so the model can correct it and call again: a dependency naming no step, one that two steps could answer, a step depending on itself, and a cycle. The cycle check matters most — no step in a loop can ever start, so the plan does not error, it simply stops making progress with nothing to observe. A diamond is not a cycle and is accepted.
|
|
80
|
+
|
|
81
|
+
**Advisory context.** Two paths reach an advisor. The trigger path always passed the live messages, working state and tool catalogue. The tool path — the one the _model_ uses — passed `{ messages: [], iteration: 0 }`, a literal empty context. So an advisor the model consulted about a situation could not see the situation, and the model's own `include_context: true` had nothing to include. The runtime now supplies the live context through a provider function, read at call time rather than captured at construction, because the tool is built once per run and called at an unknown later point.
|
|
82
|
+
|
|
83
|
+
That is also where `AdvisoryConfig.includeToolCatalog` and `AdvisorDefinition.useCompactedContext` are read for the first time. Both were declared and consulted by nothing, so a host who turned the catalogue off still paid for it in every advisory prompt.
|
|
84
|
+
|
|
85
|
+
**Advisory urgency.** `urgency` reached exactly one debug log line, so `'high'` and `'low'` produced byte-identical requests. The advisor is now told, because it is the party that can act on it — one sentence rather than a routing policy this kernel has no business inventing. `'normal'` appends nothing at all: a sentence asserting the ordinary case is prompt weight that changes no answer and makes the two that matter harder to notice.
|
|
86
|
+
|
|
87
|
+
- e1a5e2d: The MCP admission boundary is on the path a real server takes.
|
|
88
|
+
|
|
89
|
+
`MCPToolDiscovery` has held two checks since it was written: a per-server allow/deny policy deciding what a server may contribute, and detection for a server whose tool set changed since it was last seen. It was implemented, tested and publicly exported, and **nothing outside its own tests ever constructed one**.
|
|
90
|
+
|
|
91
|
+
`PluginLifecycleManager.attachMCPServer` — the only code in the tree that connects a real MCP server — called `client.listTools()` and registered whatever came back. So the remote side decided what entered the agent's tool registry, which is least privilege inverted at the one place it matters. Tools land as `deferred` and a run's `allowedTools` filters the model-visible catalogue, so this was never "arbitrary tools reach the model immediately" — but the check written for exactly this was not consulted.
|
|
92
|
+
|
|
93
|
+
`PluginLifecycleManagerConfig` takes `mcpToolPolicies` and `onMCPToolDrift`, and discovery now runs through the boundary. Passing neither admits everything, exactly as before: adding a boundary must not turn a working plugin into a broken one.
|
|
94
|
+
|
|
95
|
+
**Drift is keyed by server name rather than client id, and that is what makes it fire at all.** A client id is minted per connection, so on the path a real server takes — a plugin enabling, connecting, being disabled, another enabling — every discovery was the first that id had ever seen and drift could not fire however many times the server changed underneath. The threat it exists for is a server that advertises something benign while a host is deciding and something else afterwards, which is a property of the _server_ across connections. For the same reason a disconnect no longer forgets what a server last advertised: forgetting on teardown is precisely the window that swap uses.
|
|
96
|
+
|
|
97
|
+
Drift compares what was **admitted**, not what was advertised, so a tool the policy refuses either way does not raise a warning. A warning that fires for something already refused trains a host to ignore the one that matters.
|
|
98
|
+
|
|
99
|
+
- b807b0d: MCP prompts, server lifecycle events, and an honest "not here".
|
|
100
|
+
|
|
101
|
+
**Prompts.** `MCPPromptDefinition` and `MCPPromptArgument` were declared when the MCP types were written; no client method ever asked a server for one and no server branch ever served one, so a server publishing prompts had them silently ignored. `MCPClient` gains `listPrompts()` and `getPrompt(name, args)`, and `MCPServer` takes an optional `MCPServerPromptProvider` alongside the tool and resource ones.
|
|
102
|
+
|
|
103
|
+
Prompts page through the same reader as every other list, which is the point of that reader being generic — a server that pages its prompts does not get silently truncated to page one the way the tool list once was. Required arguments are checked against the prompt's own declaration in the server rather than left to each provider to re-implement or forget.
|
|
104
|
+
|
|
105
|
+
The messages a prompt returns are the **server's** composition, carried in their own `MCPPromptMessage` shape rather than the kernel's `Message`. A prompt arriving from a remote server is exactly the untrusted-content case: converting at the boundary is what stops a server's `assistant` message from becoming a claim that this agent already said something.
|
|
106
|
+
|
|
107
|
+
**Lifecycle events.** `MCPLifecycleEvent` and `MCPEventListener` were declared beside the prompt types and nothing ever emitted one, so a host learned a server had died by noticing that calls had started failing. `MCPClient.onLifecycle(listener)` emits from the four transitions that already existed and already mutated `status` — no new state, the client just says out loud what it already knew. It returns an unsubscribe, which `onNotification` does not: a listener that cannot be removed keeps a disposed host object alive for the life of the client. A listener that throws is logged and the rest still run, because these fire from inside transport callbacks and an escaping exception would surface as a connection error, blaming the server for a bug in the host's observer.
|
|
108
|
+
|
|
109
|
+
**"None" and "not here" are different answers.** `resources/list` returned `{ resources: [] }` when no provider was configured, for a capability `initialize` never advertised — telling a client, in the protocol's own vocabulary, that the answer is "none" when the truth is "this server does not do that". The two send a client in opposite directions: one stops asking, the other looks elsewhere. Unimplemented methods now answer with the protocol's method-not-found code via the exported `MCPMethodNotFound`, while a provider that throws still reports an internal error — a broken provider is not an absent feature, and collapsing them tells a client to stop asking for something that works tomorrow.
|
|
110
|
+
|
|
111
|
+
- 9d2b927: The model call has a span.
|
|
112
|
+
|
|
113
|
+
There was none. `chatSpanName` shipped in the telemetry attributes with zero call sites, so a run's traces carried no LLM latency at all — and the one thing anybody opens a trace to find, which turn was slow and why, was the one thing not in it. The token counts landed on the iteration span, one level above the operation that spent them.
|
|
114
|
+
|
|
115
|
+
Each model call now opens `chat {model}` under its iteration span, parented explicitly because the loop body is an async generator and the ambient context at resume time belongs to the consumer, not to whoever created the run span.
|
|
116
|
+
|
|
117
|
+
It carries the request as sent — operation, provider, model, temperature, max tokens — and, once the turn settles, what came back: response model, response id, input and output tokens, the finish reason as an array per the convention, and cache read/write tokens. `RESPONSE_MODEL`, `RESPONSE_ID`, `REQUEST_TEMPERATURE`, `REQUEST_MAX_TOKENS`, `CACHE_READ_TOKENS` and `CACHE_WRITE_TOKENS` were all declared constants that nothing ever set.
|
|
118
|
+
|
|
119
|
+
The span closes on every path, including one the call threw on, using the same `finally` the iteration span now uses — with the duration still measured at the successful close so a healthy turn is not reported as lasting the whole iteration.
|
|
120
|
+
|
|
121
|
+
The iteration span keeps its own token attributes rather than having them moved. Something may already read them, and with one turn per iteration the two agree.
|
|
122
|
+
|
|
123
|
+
- 7370f6d: An OAuth2 connector no longer reaches the upstream unauthenticated.
|
|
124
|
+
|
|
125
|
+
`'oauth2'` was grouped with `'none'` and `'custom'` in the HTTP connector's header resolver, returning no headers. Every other auth type throws on a missing credential; this one quietly did not, so a connector configured for OAuth2 sent its request with no credential at all. The upstream's 401 then reads as a bad token rather than as no token, which sends whoever is debugging to look at the token.
|
|
126
|
+
|
|
127
|
+
An access token supplied in `credentials.accessToken` (or `token`) is now sent as a bearer. Without one the connector **refuses**, naming what is missing.
|
|
128
|
+
|
|
129
|
+
The token exchange itself is deliberately not implemented here: a client-credentials or authorization-code flow needs a token endpoint, refresh handling and somewhere to keep the result, none of which belong in a request-header helper. What is supported is the case a connector config can express today — a token the host already holds.
|
|
130
|
+
|
|
131
|
+
`'custom'` keeps returning nothing, and that is not the same omission: it means the host attaches its own headers, so there is nothing to leave out and nothing to refuse.
|
|
132
|
+
|
|
133
|
+
**Three connector declarations are now documented as not consulted** rather than left to be discovered. `ConnectorTrigger` and `ConnectorDefinition.triggers` are declared and unimplemented — no inbound event starts a run — and the note says what the missing half actually needs: cross-process de-duplication of a retried webhook, which requires a compare-and-set claim that this repo's only durable write primitive (an atomic file replace, last-writer-wins) cannot express, plus a release path so a claim held by a process that dies does not drop the event forever. It also names the two existing pieces to reuse rather than rebuild. `ConnectorMethod.outputSchema` is unread, with a pointer to how the tool layer already solved the same problem. `ConnectorDefinition.supportedAuth` is unchecked, with a note that the right place to check it is instance creation, not request time.
|
|
134
|
+
|
|
135
|
+
- ea2148c: A step can put a skill in front of the model.
|
|
136
|
+
|
|
137
|
+
`PrepareStepResult.skills` renders the named skills into the same ephemeral trailing system message `system` already uses. A run's skills are fixed at `query()` time and rendered into the cached system prefix, so every skill a run might ever need is paid for on every single turn — and a phased agent rarely needs them all at once. Research wants the search skill, writing wants the style guide, and neither benefits from carrying the other.
|
|
138
|
+
|
|
139
|
+
Appending rather than rewriting is the point: the run's own prompt stays byte-stable, so the cached prefix survives, where folding a phase's skills into it would invalidate the cache every iteration.
|
|
140
|
+
|
|
141
|
+
It is **additive** to the run's skills, not a replacement. A skill a run always carries should not be removable by a step naming a different one — that would make every step's list a complete restatement, and a phase that forgot one would silently lose it.
|
|
142
|
+
|
|
143
|
+
**Sub-agents are deliberately not per-step.** A peer runtime resolves instructions, model, tools, skills and subagents from context at run time; this closes the fourth of those and states why the fifth stays out. Which agents `create_task` can reach is baked into that tool's input schema, so varying it per step would rebuild the tool catalogue every turn — a worse prompt-cache trade than moving tools around, for a narrowing a step can already express by withholding `create_task` through `activeTools`.
|
|
144
|
+
|
|
145
|
+
- 480892a: A step can force the model's tool use, and the force cannot outlive that step.
|
|
146
|
+
|
|
147
|
+
`PrepareStepResult.toolChoice` accepts `'required'`, `'none'`, or a named function. Until now the loop set `tool_choice` only internally, only to `'none'`, and only on the forced-final turn — so a caller could narrow _which_ tools a step may reach for, but never make it actually call one. The clearest cost was structured output: the model answers in prose, the loop pays another full billed turn re-prompting, and after the retry limit the run dies — where one forced choice would have produced the object on the first turn.
|
|
148
|
+
|
|
149
|
+
**Why it lives on the step and not on the run config.** A forced choice that persists makes the model call a tool, read the result, and be forced again — an agent that cannot stop. Studying how a peer SDK handles this was the useful part: it puts `tool_choice` on persistent model settings and then needs three moving parts to undo it — a tool-use tracker, an opt-out flag, and a reset applied at two separate call sites — with the flag defaulting to on precisely because turning it off hangs the agent. Two other peer runtimes ship no forced choice at all.
|
|
150
|
+
|
|
151
|
+
Putting the knob on `prepareStep` removes that failure instead of managing it. The next step is prepared from scratch, so the force cannot carry forward: there is nothing to reset and no flag to get wrong. The loop still keeps the last word — the forced-final turn's `'none'` wins, so a run that must stop can still stop — and a choice is dropped when no tools are registered, because providers reject `tool_choice` sent without a tool list.
|
|
152
|
+
|
|
153
|
+
It costs more prompt cache than `activeTools` does: narrowing tools invalidates the tool prefix, moving `tool_choice` invalidates cached message blocks too. That trade is documented on the field so it is paid knowingly, at a phase boundary, rather than by habit.
|
|
154
|
+
|
|
155
|
+
- 9bbb8be: `allowedScopes` is a trust boundary now instead of a comment.
|
|
156
|
+
|
|
157
|
+
`discoverAllPluginDirs` scans two locations — `.namzu/plugins` under the working directory, and the same path under the user's home directory — and they are not equally trusted. A project plugin is reviewable in the repository the agent is working on; a user plugin comes from a home directory the repository's reviewers never see, and a plugin is arbitrary code with hooks into tool execution.
|
|
158
|
+
|
|
159
|
+
`PluginRuntimeConfig` has carried `enabled`, `autoDiscovery` and `allowedScopes` for as long as it has existed. Nothing anywhere read any of the three, and discovery scanned both locations unconditionally, so a host who set `allowedScopes: ['project']` got user plugins anyway — from a setting that reads exactly like a boundary.
|
|
160
|
+
|
|
161
|
+
`discoverAllPluginDirs(cwd, { enabled: true, allowedScopes: ['project'] })` now honours it. A disallowed scope is **not scanned** rather than scanned and filtered: reading a directory you have been told not to look in is pointless work, and the returned count would disclose how many plugins live there. `enabled: false` or `autoDiscovery: false` discovers nothing at all, and a parsed `PluginRuntimeConfig` satisfies the options type as-is.
|
|
162
|
+
|
|
163
|
+
Calling it with no second argument scans both scopes, exactly as before — every existing caller is unaffected, and a caller who opts in gets what the config says.
|
|
164
|
+
|
|
165
|
+
- 480892a: Ship the driver that picks a run back up in another process.
|
|
166
|
+
|
|
167
|
+
Every piece of a cross-process resume already existed. `CheckpointManager` wrote the history, budgets, working state, trace context and any human-decision park; `loadRunState` read them back; `query` accepted `runId` + `resumeFromCheckpoint` and restored all of it — budgets included, so a run recalled at $4.80 of a $5 cap does not come back with a fresh $5.
|
|
168
|
+
|
|
169
|
+
Nothing joined them. `resumeFromCheckpoint` had no caller anywhere outside `packages/sdk/src`, so the whole path shipped untravelled: every host was expected to write the same wiring and none did.
|
|
170
|
+
|
|
171
|
+
`resumeRun` is that wiring. The division of labour is the one the mechanism already implies — the caller brings what cannot be serialized (the provider client, the tool registry, the sandbox, the working directory), the store brings the state. A snapshot deliberately holds no socket and no open file, so it could never have carried the first half.
|
|
172
|
+
|
|
173
|
+
It refuses at both failure points rather than guessing:
|
|
174
|
+
|
|
175
|
+
- **No checkpoint** returns `{ resumed: false, reason: 'no-checkpoint' }`. Starting a fresh run here would be a different run wearing a recycled id, with the original's budget reset.
|
|
176
|
+
- **An outstanding park** returns the `PendingDecision` itself, so the host has what to put in front of a person, instead of resuming past a question the run is waiting on. A park with `resolvedAt` already set is an ordinary resume — blocking on an answered one would strand the run permanently.
|
|
177
|
+
|
|
178
|
+
`RunStateScope` is exported alongside it. It was internal, so a host calling the already-public `loadRunState` could not name the argument it had to construct.
|
|
179
|
+
|
|
180
|
+
- 8518b40: A retrieval namespace partitions what a query can see.
|
|
181
|
+
|
|
182
|
+
`TenantScope.namespace` and `KnowledgeBaseConfig.namespace` were declared from the start and neither reached storage. Ingestion copied `scope.tenantId` onto every chunk and dropped the namespace; the store filtered on tenant alone. So a partition a host asked for did not exist, and every namespace inside a tenant saw every other one's documents.
|
|
183
|
+
|
|
184
|
+
The namespace is now stamped onto each chunk at ingest and matched at search, across all three retrieval modes.
|
|
185
|
+
|
|
186
|
+
**An omitted namespace means the default partition, not the absence of a filter.** That distinction is the whole boundary: reading absence as "no filter" is how one leaks, because a caller who never asked for a namespace would then see every namespaced chunk in the tenant — the opposite of what partitioning is for. A caller who genuinely wants everything asks for each namespace it holds.
|
|
187
|
+
|
|
188
|
+
This is a behaviour change for existing data. Chunks ingested under a namespace before this release carry none, so they now answer only to a query with no namespace. Re-ingest to place them in a partition.
|
|
189
|
+
|
|
190
|
+
`RetrievalQuery.projectId` is **deprecated and documented as not consulted**. No chunk carries a project — ingestion stamps a tenant and a namespace, and `KnowledgeBaseConfig` has no project field to stamp a third from. Wiring one end of an isolation dimension is worse than wiring neither: a query filtering against a value nothing writes returns zero rows, and "no results" reads as "nothing matched" rather than "this scope was never stored".
|
|
191
|
+
|
|
192
|
+
- 480892a: `taskRouter` now routes something.
|
|
193
|
+
|
|
194
|
+
The compaction summary is the only model call a run makes that nobody asked for: it reads the older half of a transcript and writes a paraphrase, and it fires on exactly the long runs where the primary model costs the most. It was hardwired to that primary model. Meanwhile `taskRouter` had been accepted, schema-validated and threaded through four types since it was added, with `resolveTaskModel` exported and never called from anywhere — so a host who pointed compaction at a cheap model kept paying the expensive one, with nothing to indicate the setting was decoration.
|
|
195
|
+
|
|
196
|
+
`taskRouter: { compaction: 'a-small-model' }` now takes effect, falling back to `taskRouter.default` and then to the run's model.
|
|
197
|
+
|
|
198
|
+
The remaining keys are documented on `TaskRouterConfig` as **not consulted**, which is the point of the change as much as the wiring is. `coding`, `exploration`, `planning`, `verification` and `summarization` describe sub-agent routing; the supervisor already threads the config down to the agent factory, but nothing classifies a spawned task as exploration or coding, and inventing a classifier would put a wrong model behind a right-looking config. `advisory` is deliberately left alone because an advisor already carries its own `model`, and routing would override an explicit choice with a general one. An inert key is worse than an absent one — saying which is which converts a silent lie into a stated limit.
|
|
199
|
+
|
|
200
|
+
### Patch Changes
|
|
201
|
+
|
|
202
|
+
- 05b4103: Two timeouts that did nothing, and a recursion limit that was not the one in force.
|
|
203
|
+
|
|
204
|
+
**`OllamaConfig.timeout` and `LMStudioConfig.timeout`** were declared with no doc comment and read by nothing — both constructors forwarded the host and the model and never looked at them, so a host that set a timeout waited forever anyway. The wait they exist for is specific to a local server: the process is up, the socket accepts, and the model never answers because it is still loading or the machine is out of memory.
|
|
205
|
+
|
|
206
|
+
Both are composed with the caller's cancellation rather than replacing it. The caller's signal is how a run stops mid-generation, and dropping it for a deadline would leave a local model generating after the run that asked for it has stopped. Absent means no deadline, exactly as before.
|
|
207
|
+
|
|
208
|
+
The deadline covers the whole request rather than the time to the first byte, because the failure it exists for is a server that accepts and then never finishes — bounding only the head leaves precisely that case unbounded. A zero or negative value is refused at construction, since it would abort every request rather than bound it.
|
|
209
|
+
|
|
210
|
+
**`SupervisorAgentConfig.maxDepth` is deprecated** and documented as not consulted. The recursion bound is enforced in `AgentManager.sendMessage` against the manager's own config, and a supervisor receives a manager rather than building one — so a host setting it on the supervisor got the manager's value regardless. For a safety limit that is the worst way to be wrong: the number in front of the reviewer is not the number in force. Set it on `AgentManagerConfig`, where it is read. Tests now pin both halves, so a change that starts consulting the supervisor's copy fails rather than shipping quietly.
|
|
211
|
+
|
|
212
|
+
- e1a5e2d: A span closes however its work leaves.
|
|
213
|
+
|
|
214
|
+
Two sites had the same shape: `end()` called at every exit the author could see. The iteration loop had seventeen of them; the tool executor had three early returns plus a `finally` that opened below them. That makes span closure a rule every future edit has to remember, and it was already broken in both places.
|
|
215
|
+
|
|
216
|
+
In the iteration loop, the span was created and then four statements ran before the `try` — attaching the tool parent span, stamping attributes, emitting `iteration_started`, draining pending events. A throw from any of those left the span open. The loop body is also an async generator, so a consumer that abandons it reached no exit at all.
|
|
217
|
+
|
|
218
|
+
In the tool executor, `getOrThrow(toolName)` sat outside the `try` that owned the `finally`. The path where a model invents a tool name — the most likely way that throw happens — opened a span and never closed it.
|
|
219
|
+
|
|
220
|
+
An iteration span that never ends is a trace that never closes, so the export is incomplete for exactly the run that failed and is hardest to debug from the outside.
|
|
221
|
+
|
|
222
|
+
Both now end in a single `finally`. No status or exception recording moved; only the moment of closing.
|
|
223
|
+
|
|
3
224
|
## 3.1.0
|
|
4
225
|
|
|
5
226
|
### Minor Changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"consultation-context.test.d.ts","sourceRoot":"","sources":["../../../src/advisory/__tests__/consultation-context.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { describe, expect, it, vi } from 'vitest';
|
|
2
|
+
import { AdvisoryContext } from '../context.js';
|
|
3
|
+
import { TriggerEvaluator } from '../evaluator.js';
|
|
4
|
+
import { AdvisoryExecutor } from '../executor.js';
|
|
5
|
+
import { ADVISORY_RESPONSE_CONTRACT } from '../parse.js';
|
|
6
|
+
import { AdvisorRegistry } from '../registry.js';
|
|
7
|
+
/**
|
|
8
|
+
* An advisor consulted BY THE MODEL saw the question and nothing else.
|
|
9
|
+
*
|
|
10
|
+
* Two paths reach `AdvisoryExecutor.consult`. The trigger path
|
|
11
|
+
* (`iteration/phases/advisory.ts`) has always passed the live messages, the
|
|
12
|
+
* working state and the tool catalogue. The tool path passed
|
|
13
|
+
* `{ messages: [], iteration: 0 }` — a literal empty context — so the
|
|
14
|
+
* model's own `include_context: true` had nothing to include, and the
|
|
15
|
+
* advisor answered a question about a situation it could not see.
|
|
16
|
+
*/
|
|
17
|
+
function recordingProvider() {
|
|
18
|
+
const calls = [];
|
|
19
|
+
const provider = {
|
|
20
|
+
chatStream: async function* (params) {
|
|
21
|
+
calls.push(params.messages);
|
|
22
|
+
yield { id: 'a1', delta: { content: 'ADVICE: do the thing' } };
|
|
23
|
+
yield {
|
|
24
|
+
id: 'a1',
|
|
25
|
+
delta: {},
|
|
26
|
+
finishReason: 'stop',
|
|
27
|
+
usage: { promptTokens: 1, completionTokens: 1, totalTokens: 2 },
|
|
28
|
+
};
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
return { provider, calls };
|
|
32
|
+
}
|
|
33
|
+
function advisor(over = {}) {
|
|
34
|
+
return {
|
|
35
|
+
id: 'adv_1',
|
|
36
|
+
name: 'Reviewer',
|
|
37
|
+
provider: recordingProvider().provider,
|
|
38
|
+
model: 'mock-model',
|
|
39
|
+
...over,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
const log = {
|
|
43
|
+
debug: vi.fn(),
|
|
44
|
+
info: vi.fn(),
|
|
45
|
+
warn: vi.fn(),
|
|
46
|
+
error: vi.fn(),
|
|
47
|
+
child: () => log,
|
|
48
|
+
};
|
|
49
|
+
function contextFor(a) {
|
|
50
|
+
return new AdvisoryContext(new AdvisorRegistry([a]), new AdvisoryExecutor(log), new TriggerEvaluator([]));
|
|
51
|
+
}
|
|
52
|
+
describe('the context a tool-initiated consultation is given', () => {
|
|
53
|
+
it('is empty until the runtime supplies one', () => {
|
|
54
|
+
const ctx = contextFor(advisor());
|
|
55
|
+
// The fallback exists for a context built without a runtime, and it is
|
|
56
|
+
// what every tool-initiated call used to get.
|
|
57
|
+
expect(ctx.callContext()).toEqual({ messages: [], iteration: 0 });
|
|
58
|
+
});
|
|
59
|
+
it('is the live run once the runtime wires it', () => {
|
|
60
|
+
const ctx = contextFor(advisor());
|
|
61
|
+
const messages = [{ role: 'user', content: 'the situation', timestamp: 1 }];
|
|
62
|
+
ctx.setCallContextProvider(() => ({ messages, iteration: 7 }));
|
|
63
|
+
expect(ctx.callContext().messages).toBe(messages);
|
|
64
|
+
expect(ctx.callContext().iteration).toBe(7);
|
|
65
|
+
});
|
|
66
|
+
it('is read at call time, not at construction', () => {
|
|
67
|
+
const ctx = contextFor(advisor());
|
|
68
|
+
let iteration = 1;
|
|
69
|
+
ctx.setCallContextProvider(() => ({ messages: [], iteration }));
|
|
70
|
+
iteration = 4;
|
|
71
|
+
// The tool is built once per run and called at an unknown later point.
|
|
72
|
+
// A snapshot would hand every advisor the state the run started with.
|
|
73
|
+
expect(ctx.callContext().iteration).toBe(4);
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
describe('what the advisor actually receives', () => {
|
|
77
|
+
it('sees the conversation when context is included', async () => {
|
|
78
|
+
const { provider, calls } = recordingProvider();
|
|
79
|
+
const executor = new AdvisoryExecutor(log);
|
|
80
|
+
await executor.consult(advisor({ provider }), { advisorId: 'adv_1', question: 'what next?', includeContext: true }, { messages: [{ role: 'user', content: 'deploy is failing', timestamp: 1 }], iteration: 2 });
|
|
81
|
+
const sent = JSON.stringify(calls[0]);
|
|
82
|
+
expect(sent).toContain('deploy is failing');
|
|
83
|
+
});
|
|
84
|
+
it('sees none of it when the caller says not to', async () => {
|
|
85
|
+
const { provider, calls } = recordingProvider();
|
|
86
|
+
const executor = new AdvisoryExecutor(log);
|
|
87
|
+
await executor.consult(advisor({ provider }), { advisorId: 'adv_1', question: 'what next?', includeContext: false }, { messages: [{ role: 'user', content: 'deploy is failing', timestamp: 1 }], iteration: 2 });
|
|
88
|
+
expect(JSON.stringify(calls[0])).not.toContain('deploy is failing');
|
|
89
|
+
});
|
|
90
|
+
it('is told when the caller marked the request urgent', async () => {
|
|
91
|
+
const { provider, calls } = recordingProvider();
|
|
92
|
+
const executor = new AdvisoryExecutor(log);
|
|
93
|
+
await executor.consult(advisor({ provider }), { advisorId: 'adv_1', question: 'what next?', urgency: 'high' }, { messages: [], iteration: 1 });
|
|
94
|
+
// The value used to reach exactly one debug log line, so 'high' and
|
|
95
|
+
// 'low' produced byte-identical requests.
|
|
96
|
+
expect(String(calls[0]?.[0]?.content)).toContain('URGENT');
|
|
97
|
+
});
|
|
98
|
+
it('is told when there is room to consider alternatives', async () => {
|
|
99
|
+
const { provider, calls } = recordingProvider();
|
|
100
|
+
const executor = new AdvisoryExecutor(log);
|
|
101
|
+
await executor.consult(advisor({ provider }), { advisorId: 'adv_1', question: 'what next?', urgency: 'low' }, { messages: [], iteration: 1 });
|
|
102
|
+
expect(String(calls[0]?.[0]?.content)).toContain('low urgency');
|
|
103
|
+
});
|
|
104
|
+
it("appends nothing at all for 'normal', which is the point of not stating it", async () => {
|
|
105
|
+
const { provider, calls } = recordingProvider();
|
|
106
|
+
const executor = new AdvisoryExecutor(log);
|
|
107
|
+
const a = advisor({ provider });
|
|
108
|
+
await executor.consult(a, { advisorId: 'adv_1', question: 'what next?', urgency: 'normal' }, { messages: [], iteration: 1 });
|
|
109
|
+
await executor.consult(a, { advisorId: 'adv_1', question: 'what next?', urgency: 'high' }, { messages: [], iteration: 1 });
|
|
110
|
+
// Asserting "does not contain the other two phrases" is too weak — it
|
|
111
|
+
// would let ANY new sentence in. The response contract is the last
|
|
112
|
+
// thing the prompt says when urgency contributes nothing, so ending on
|
|
113
|
+
// it is what "appended nothing" actually means.
|
|
114
|
+
expect(String(calls[0]?.[0]?.content).trimEnd().endsWith(ADVISORY_RESPONSE_CONTRACT)).toBe(true);
|
|
115
|
+
expect(String(calls[1]?.[0]?.content).trimEnd().endsWith(ADVISORY_RESPONSE_CONTRACT)).toBe(false);
|
|
116
|
+
});
|
|
117
|
+
it('says nothing about urgency when the caller did not', async () => {
|
|
118
|
+
const { provider, calls } = recordingProvider();
|
|
119
|
+
const executor = new AdvisoryExecutor(log);
|
|
120
|
+
await executor.consult(advisor({ provider }), { advisorId: 'adv_1', question: 'what next?' }, { messages: [], iteration: 1 });
|
|
121
|
+
expect(String(calls[0]?.[0]?.content).trimEnd().endsWith(ADVISORY_RESPONSE_CONTRACT)).toBe(true);
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
//# sourceMappingURL=consultation-context.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"consultation-context.test.js","sourceRoot":"","sources":["../../../src/advisory/__tests__/consultation-context.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAA;AAIjD,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AACjD,OAAO,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAA;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAEhD;;;;;;;;;GASG;AAEH,SAAS,iBAAiB;IACzB,MAAM,KAAK,GAAgB,EAAE,CAAA;IAC7B,MAAM,QAAQ,GAAG;QAChB,UAAU,EAAE,KAAK,SAAS,CAAC,EAAE,MAA+B;YAC3D,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;YAC3B,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,sBAAsB,EAAE,EAAE,CAAA;YAC9D,MAAM;gBACL,EAAE,EAAE,IAAI;gBACR,KAAK,EAAE,EAAE;gBACT,YAAY,EAAE,MAAM;gBACpB,KAAK,EAAE,EAAE,YAAY,EAAE,CAAC,EAAE,gBAAgB,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE;aAC/D,CAAA;QACF,CAAC;KAC2C,CAAA;IAC7C,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAA;AAC3B,CAAC;AAED,SAAS,OAAO,CAAC,OAAmC,EAAE;IACrD,OAAO;QACN,EAAE,EAAE,OAAO;QACX,IAAI,EAAE,UAAU;QAChB,QAAQ,EAAE,iBAAiB,EAAE,CAAC,QAAQ;QACtC,KAAK,EAAE,YAAY;QACnB,GAAG,IAAI;KACc,CAAA;AACvB,CAAC;AAED,MAAM,GAAG,GAAG;IACX,KAAK,EAAE,EAAE,CAAC,EAAE,EAAE;IACd,IAAI,EAAE,EAAE,CAAC,EAAE,EAAE;IACb,IAAI,EAAE,EAAE,CAAC,EAAE,EAAE;IACb,KAAK,EAAE,EAAE,CAAC,EAAE,EAAE;IACd,KAAK,EAAE,GAAG,EAAE,CAAC,GAAG;CACP,CAAA;AAEV,SAAS,UAAU,CAAC,CAAoB;IACvC,OAAO,IAAI,eAAe,CACzB,IAAI,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,EACxB,IAAI,gBAAgB,CAAC,GAAG,CAAC,EACzB,IAAI,gBAAgB,CAAC,EAAE,CAAC,CACxB,CAAA;AACF,CAAC;AAED,QAAQ,CAAC,oDAAoD,EAAE,GAAG,EAAE;IACnE,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;QAClD,MAAM,GAAG,GAAG,UAAU,CAAC,OAAO,EAAE,CAAC,CAAA;QAEjC,uEAAuE;QACvE,8CAA8C;QAC9C,MAAM,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC,CAAA;IAClE,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;QACpD,MAAM,GAAG,GAAG,UAAU,CAAC,OAAO,EAAE,CAAC,CAAA;QACjC,MAAM,QAAQ,GAAc,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC,CAAA;QAEtF,GAAG,CAAC,sBAAsB,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;QAE9D,MAAM,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;QACjD,MAAM,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IAC5C,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;QACpD,MAAM,GAAG,GAAG,UAAU,CAAC,OAAO,EAAE,CAAC,CAAA;QACjC,IAAI,SAAS,GAAG,CAAC,CAAA;QACjB,GAAG,CAAC,sBAAsB,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC,CAAA;QAE/D,SAAS,GAAG,CAAC,CAAA;QAEb,uEAAuE;QACvE,sEAAsE;QACtE,MAAM,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IAC5C,CAAC,CAAC,CAAA;AACH,CAAC,CAAC,CAAA;AAEF,QAAQ,CAAC,oCAAoC,EAAE,GAAG,EAAE;IACnD,EAAE,CAAC,gDAAgD,EAAE,KAAK,IAAI,EAAE;QAC/D,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,iBAAiB,EAAE,CAAA;QAC/C,MAAM,QAAQ,GAAG,IAAI,gBAAgB,CAAC,GAAG,CAAC,CAAA;QAE1C,MAAM,QAAQ,CAAC,OAAO,CACrB,OAAO,CAAC,EAAE,QAAQ,EAAE,CAAC,EACrB,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,cAAc,EAAE,IAAI,EAAE,EACpE,EAAE,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,mBAAmB,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,CAC1F,CAAA;QAED,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;QACrC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAA;IAC5C,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,6CAA6C,EAAE,KAAK,IAAI,EAAE;QAC5D,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,iBAAiB,EAAE,CAAA;QAC/C,MAAM,QAAQ,GAAG,IAAI,gBAAgB,CAAC,GAAG,CAAC,CAAA;QAE1C,MAAM,QAAQ,CAAC,OAAO,CACrB,OAAO,CAAC,EAAE,QAAQ,EAAE,CAAC,EACrB,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,cAAc,EAAE,KAAK,EAAE,EACrE,EAAE,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,mBAAmB,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,CAC1F,CAAA;QAED,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAA;IACpE,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,mDAAmD,EAAE,KAAK,IAAI,EAAE;QAClE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,iBAAiB,EAAE,CAAA;QAC/C,MAAM,QAAQ,GAAG,IAAI,gBAAgB,CAAC,GAAG,CAAC,CAAA;QAE1C,MAAM,QAAQ,CAAC,OAAO,CACrB,OAAO,CAAC,EAAE,QAAQ,EAAE,CAAC,EACrB,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE,EAC/D,EAAE,QAAQ,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,EAAE,CAC9B,CAAA;QAED,oEAAoE;QACpE,0CAA0C;QAC1C,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAA;IAC3D,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,qDAAqD,EAAE,KAAK,IAAI,EAAE;QACpE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,iBAAiB,EAAE,CAAA;QAC/C,MAAM,QAAQ,GAAG,IAAI,gBAAgB,CAAC,GAAG,CAAC,CAAA;QAE1C,MAAM,QAAQ,CAAC,OAAO,CACrB,OAAO,CAAC,EAAE,QAAQ,EAAE,CAAC,EACrB,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,OAAO,EAAE,KAAK,EAAE,EAC9D,EAAE,QAAQ,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,EAAE,CAC9B,CAAA;QAED,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAA;IAChE,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,2EAA2E,EAAE,KAAK,IAAI,EAAE;QAC1F,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,iBAAiB,EAAE,CAAA;QAC/C,MAAM,QAAQ,GAAG,IAAI,gBAAgB,CAAC,GAAG,CAAC,CAAA;QAC1C,MAAM,CAAC,GAAG,OAAO,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAA;QAE/B,MAAM,QAAQ,CAAC,OAAO,CACrB,CAAC,EACD,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,EACjE,EAAE,QAAQ,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,EAAE,CAC9B,CAAA;QACD,MAAM,QAAQ,CAAC,OAAO,CACrB,CAAC,EACD,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE,EAC/D,EAAE,QAAQ,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,EAAE,CAC9B,CAAA;QAED,sEAAsE;QACtE,mEAAmE;QACnE,uEAAuE;QACvE,gDAAgD;QAChD,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,0BAA0B,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAChG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,0BAA0B,CAAC,CAAC,CAAC,IAAI,CACzF,KAAK,CACL,CAAA;IACF,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,oDAAoD,EAAE,KAAK,IAAI,EAAE;QACnE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,iBAAiB,EAAE,CAAA;QAC/C,MAAM,QAAQ,GAAG,IAAI,gBAAgB,CAAC,GAAG,CAAC,CAAA;QAE1C,MAAM,QAAQ,CAAC,OAAO,CACrB,OAAO,CAAC,EAAE,QAAQ,EAAE,CAAC,EACrB,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,EAC9C,EAAE,QAAQ,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,EAAE,CAC9B,CAAA;QAED,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,0BAA0B,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACjG,CAAC,CAAC,CAAA;AACH,CAAC,CAAC,CAAA"}
|
|
@@ -1,14 +1,39 @@
|
|
|
1
1
|
import type { AdvisoryBudget, AdvisoryCallRecord } from '../types/advisory/index.js';
|
|
2
2
|
import type { TriggerEvaluator } from './evaluator.js';
|
|
3
|
+
import type { AdvisoryCallContext } from './executor.js';
|
|
3
4
|
import type { AdvisoryExecutor } from './executor.js';
|
|
4
5
|
import type { AdvisorRegistry } from './registry.js';
|
|
6
|
+
/**
|
|
7
|
+
* What the run looks like right now, for an advisory call that did not come
|
|
8
|
+
* from the iteration loop.
|
|
9
|
+
*
|
|
10
|
+
* A function rather than a snapshot because the tool is built once per run
|
|
11
|
+
* and called at an unknown later point: capturing the context at
|
|
12
|
+
* construction would hand every advisor the state the run had before it
|
|
13
|
+
* started.
|
|
14
|
+
*/
|
|
15
|
+
export type AdvisoryCallContextProvider = () => AdvisoryCallContext;
|
|
5
16
|
export declare class AdvisoryContext {
|
|
6
17
|
readonly registry: AdvisorRegistry;
|
|
7
18
|
readonly executor: AdvisoryExecutor;
|
|
8
19
|
readonly evaluator: TriggerEvaluator;
|
|
9
20
|
readonly callHistory: AdvisoryCallRecord[];
|
|
10
21
|
private readonly budget;
|
|
22
|
+
private callContextProvider;
|
|
11
23
|
constructor(registry: AdvisorRegistry, executor: AdvisoryExecutor, evaluator: TriggerEvaluator, budget?: AdvisoryBudget);
|
|
24
|
+
/** Wired by the runtime once the run exists. */
|
|
25
|
+
setCallContextProvider(provider: AdvisoryCallContextProvider): void;
|
|
26
|
+
/**
|
|
27
|
+
* The call context for a tool-initiated consultation.
|
|
28
|
+
*
|
|
29
|
+
* The trigger path (`iteration/phases/advisory.ts`) has always passed the
|
|
30
|
+
* live messages, working state and tool catalogue. The TOOL path passed
|
|
31
|
+
* `{ messages: [], iteration: 0 }` — a literal empty context — so an
|
|
32
|
+
* advisor consulted by the model saw the question and nothing else, and
|
|
33
|
+
* the model's `include_context` had nothing to include either way. The
|
|
34
|
+
* empty fallback survives only for a context built without a runtime.
|
|
35
|
+
*/
|
|
36
|
+
callContext(): AdvisoryCallContext;
|
|
12
37
|
recordCall(record: AdvisoryCallRecord): void;
|
|
13
38
|
getBudgetStatus(): {
|
|
14
39
|
remaining: number | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/advisory/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAA;AACpF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AACtD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AACrD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAEpD,qBAAa,eAAe;IAC3B,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAA;IAClC,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAA;IACnC,QAAQ,CAAC,SAAS,EAAE,gBAAgB,CAAA;IACpC,QAAQ,CAAC,WAAW,EAAE,kBAAkB,EAAE,CAAK;IAE/C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA4B;
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/advisory/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAA;AACpF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AACtD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAA;AACxD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AACrD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAEpD;;;;;;;;GAQG;AACH,MAAM,MAAM,2BAA2B,GAAG,MAAM,mBAAmB,CAAA;AAEnE,qBAAa,eAAe;IAC3B,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAA;IAClC,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAA;IACnC,QAAQ,CAAC,SAAS,EAAE,gBAAgB,CAAA;IACpC,QAAQ,CAAC,WAAW,EAAE,kBAAkB,EAAE,CAAK;IAE/C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA4B;IACnD,OAAO,CAAC,mBAAmB,CAAyC;gBAGnE,QAAQ,EAAE,eAAe,EACzB,QAAQ,EAAE,gBAAgB,EAC1B,SAAS,EAAE,gBAAgB,EAC3B,MAAM,CAAC,EAAE,cAAc;IAQxB,gDAAgD;IAChD,sBAAsB,CAAC,QAAQ,EAAE,2BAA2B,GAAG,IAAI;IAInE;;;;;;;;;OASG;IACH,WAAW,IAAI,mBAAmB;IAIlC,UAAU,CAAC,MAAM,EAAE,kBAAkB,GAAG,IAAI;IAI5C,eAAe,IAAI;QAAE,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;QAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE;IAO7F,sEAAsE;IACtE,SAAS,IAAI,MAAM;IAInB,WAAW,IAAI;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE;CAwBpD"}
|
package/dist/advisory/context.js
CHANGED
|
@@ -4,12 +4,30 @@ export class AdvisoryContext {
|
|
|
4
4
|
evaluator;
|
|
5
5
|
callHistory = [];
|
|
6
6
|
budget;
|
|
7
|
+
callContextProvider;
|
|
7
8
|
constructor(registry, executor, evaluator, budget) {
|
|
8
9
|
this.registry = registry;
|
|
9
10
|
this.executor = executor;
|
|
10
11
|
this.evaluator = evaluator;
|
|
11
12
|
this.budget = budget;
|
|
12
13
|
}
|
|
14
|
+
/** Wired by the runtime once the run exists. */
|
|
15
|
+
setCallContextProvider(provider) {
|
|
16
|
+
this.callContextProvider = provider;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* The call context for a tool-initiated consultation.
|
|
20
|
+
*
|
|
21
|
+
* The trigger path (`iteration/phases/advisory.ts`) has always passed the
|
|
22
|
+
* live messages, working state and tool catalogue. The TOOL path passed
|
|
23
|
+
* `{ messages: [], iteration: 0 }` — a literal empty context — so an
|
|
24
|
+
* advisor consulted by the model saw the question and nothing else, and
|
|
25
|
+
* the model's `include_context` had nothing to include either way. The
|
|
26
|
+
* empty fallback survives only for a context built without a runtime.
|
|
27
|
+
*/
|
|
28
|
+
callContext() {
|
|
29
|
+
return this.callContextProvider?.() ?? { messages: [], iteration: 0 };
|
|
30
|
+
}
|
|
13
31
|
recordCall(record) {
|
|
14
32
|
this.callHistory.push(record);
|
|
15
33
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/advisory/context.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/advisory/context.ts"],"names":[],"mappings":"AAiBA,MAAM,OAAO,eAAe;IAClB,QAAQ,CAAiB;IACzB,QAAQ,CAAkB;IAC1B,SAAS,CAAkB;IAC3B,WAAW,GAAyB,EAAE,CAAA;IAE9B,MAAM,CAA4B;IAC3C,mBAAmB,CAAyC;IAEpE,YACC,QAAyB,EACzB,QAA0B,EAC1B,SAA2B,EAC3B,MAAuB;QAEvB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAA;QACxB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAA;QACxB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAA;QAC1B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;IACrB,CAAC;IAED,gDAAgD;IAChD,sBAAsB,CAAC,QAAqC;QAC3D,IAAI,CAAC,mBAAmB,GAAG,QAAQ,CAAA;IACpC,CAAC;IAED;;;;;;;;;OASG;IACH,WAAW;QACV,OAAO,IAAI,CAAC,mBAAmB,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,EAAE,CAAA;IACtE,CAAC;IAED,UAAU,CAAC,MAA0B;QACpC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IAC9B,CAAC;IAED,eAAe;QACd,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,CAAA;QACpC,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,cAAc,CAAA;QACzC,MAAM,SAAS,GAAG,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,SAAS,CAAA;QAChE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,CAAA;IAClC,CAAC;IAED,sEAAsE;IACtE,SAAS;QACR,OAAO,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAA;IAC5E,CAAC;IAED,WAAW;QACV,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,eAAe,EAAE,CAAA;QACnD,IAAI,SAAS,KAAK,SAAS,IAAI,SAAS,IAAI,CAAC,EAAE,CAAC;YAC/C,OAAO;gBACN,OAAO,EAAE,KAAK;gBACd,MAAM,EAAE,8BAA8B,KAAK,kBAAkB,KAAK,kBAAkB;aACpF,CAAA;QACF,CAAC;QAED,8DAA8D;QAC9D,8DAA8D;QAC9D,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,EAAE,aAAa,CAAA;QAC1C,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC3B,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,EAAE,CAAA;YAC9B,IAAI,KAAK,IAAI,OAAO,EAAE,CAAC;gBACtB,OAAO;oBACN,OAAO,EAAE,KAAK;oBACd,MAAM,EAAE,mCAAmC,KAAK,OAAO,OAAO,kBAAkB;iBAChF,CAAA;YACF,CAAC;QACF,CAAC;QAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAA;IACzB,CAAC;CACD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../src/advisory/executor.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AACpF,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AAClF,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAA;AACpE,OAAO,EAAE,KAAK,OAAO,EAA0C,MAAM,2BAA2B,CAAA;AAChG,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAA;AAE3D,OAAO,EAAE,KAAK,MAAM,EAAiB,MAAM,oBAAoB,CAAA;
|
|
1
|
+
{"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../src/advisory/executor.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AACpF,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AAClF,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAA;AACpE,OAAO,EAAE,KAAK,OAAO,EAA0C,MAAM,2BAA2B,CAAA;AAChG,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAA;AAE3D,OAAO,EAAE,KAAK,MAAM,EAAiB,MAAM,oBAAoB,CAAA;AAgB/D,MAAM,WAAW,mBAAmB;IACnC,QAAQ,CAAC,QAAQ,EAAE,OAAO,EAAE,CAAA;IAC5B,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAA;IACrC,QAAQ,CAAC,WAAW,CAAC,EAAE,aAAa,EAAE,CAAA;IACtC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAC1B;AAED,MAAM,WAAW,uBAAuB;IACvC,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAA;IAC/B,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAA;IAC1B,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAA;IACvB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAC3B;AAED,qBAAa,gBAAgB;IAC5B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAQ;IAC/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA4B;gBAEvC,MAAM,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,cAAc;IAKpD;;;;OAIG;IACH,OAAO,CAAC,oBAAoB;IAOtB,OAAO,CACZ,OAAO,EAAE,iBAAiB,EAC1B,OAAO,EAAE,eAAe,EACxB,OAAO,EAAE,mBAAmB,GAC1B,OAAO,CAAC,uBAAuB,CAAC;IAkDnC,OAAO,CAAC,iBAAiB;IAqBzB,OAAO,CAAC,eAAe;IAoBvB,OAAO,CAAC,YAAY;IA6CpB,OAAO,CAAC,gBAAgB;IAqBxB;;;;;;OAMG;IACH,OAAO,CAAC,WAAW;CAMnB"}
|
|
@@ -5,6 +5,18 @@ import { createSystemMessage, createUserMessage } from '../types/message/index.j
|
|
|
5
5
|
import { calculateCost } from '../utils/cost.js';
|
|
6
6
|
import { getRootLogger } from '../utils/logger.js';
|
|
7
7
|
import { ADVISORY_RESPONSE_CONTRACT, parseAdvisoryResponse } from './parse.js';
|
|
8
|
+
/**
|
|
9
|
+
* What the advisor is told about how urgent the caller said this is.
|
|
10
|
+
*
|
|
11
|
+
* `'normal'` says nothing on purpose. A sentence asserting the ordinary case
|
|
12
|
+
* is prompt weight that changes no answer, and stating it on every call
|
|
13
|
+
* would make the two that matter harder to notice.
|
|
14
|
+
*/
|
|
15
|
+
const URGENCY_DIRECTION = {
|
|
16
|
+
high: 'This request is marked URGENT. Lead with the single most important action and keep the reasoning to what is needed to justify it.',
|
|
17
|
+
normal: undefined,
|
|
18
|
+
low: 'This request is marked low urgency. There is room to note secondary considerations and alternatives worth weighing.',
|
|
19
|
+
};
|
|
8
20
|
export class AdvisoryExecutor {
|
|
9
21
|
logger;
|
|
10
22
|
budget;
|
|
@@ -27,7 +39,7 @@ export class AdvisoryExecutor {
|
|
|
27
39
|
}
|
|
28
40
|
async consult(advisor, request, callCtx) {
|
|
29
41
|
const startMs = Date.now();
|
|
30
|
-
const systemPrompt = this.buildSystemPrompt(advisor);
|
|
42
|
+
const systemPrompt = this.buildSystemPrompt(advisor, request.urgency);
|
|
31
43
|
const contextMessages = this.buildContext(advisor, request, callCtx);
|
|
32
44
|
const messages = [
|
|
33
45
|
createSystemMessage(systemPrompt),
|
|
@@ -63,11 +75,21 @@ export class AdvisoryExecutor {
|
|
|
63
75
|
durationMs,
|
|
64
76
|
};
|
|
65
77
|
}
|
|
66
|
-
buildSystemPrompt(advisor) {
|
|
78
|
+
buildSystemPrompt(advisor, urgency) {
|
|
67
79
|
// The contract is appended to every branch, not folded into the
|
|
68
80
|
// default: an advisor with its own prompt or a persona is still read
|
|
69
81
|
// back by the same parser, and used to be the one never told so.
|
|
70
|
-
|
|
82
|
+
const parts = [this.describeAdvisor(advisor), ADVISORY_RESPONSE_CONTRACT];
|
|
83
|
+
// The caller is invited to say how urgent this is, and the value used
|
|
84
|
+
// to reach exactly one debug log line — `urgency: 'high'` and
|
|
85
|
+
// `urgency: 'low'` produced byte-identical requests. Telling the
|
|
86
|
+
// ADVISOR is the honest minimum: it is the party that can act on the
|
|
87
|
+
// answer, and it costs one sentence rather than a routing policy this
|
|
88
|
+
// kernel has no business inventing.
|
|
89
|
+
const direction = URGENCY_DIRECTION[urgency ?? 'normal'];
|
|
90
|
+
if (direction)
|
|
91
|
+
parts.push(direction);
|
|
92
|
+
return parts.join('\n\n');
|
|
71
93
|
}
|
|
72
94
|
describeAdvisor(advisor) {
|
|
73
95
|
if (advisor.systemPrompt) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"executor.js","sourceRoot":"","sources":["../../src/advisory/executor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AACxD,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAA;AAC9D,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAA;AAKhD,OAAO,EAAgB,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAA;AAEhG,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAChD,OAAO,EAAe,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAC/D,OAAO,EAAE,0BAA0B,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"executor.js","sourceRoot":"","sources":["../../src/advisory/executor.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SupervisorAgent.d.ts","sourceRoot":"","sources":["../../src/agents/SupervisorAgent.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAe,UAAU,EAAE,MAAM,2BAA2B,CAAA;AACxE,OAAO,KAAK,EACX,UAAU,EACV,aAAa,EACb,eAAe,EACf,qBAAqB,EACrB,qBAAqB,EACrB,MAAM,yBAAyB,CAAA;AAEhC,OAAO,KAAK,EAAW,KAAK,EAAU,MAAM,uBAAuB,CAAA;AAEnE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAG7D,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAElD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,qBAAqB,CACpC,WAAW,EAAE,SAAS,UAAU,EAAE,EAClC,KAAK,EAAE,KAAK,EACZ,GAAG,GAAE,MAAmB,GACtB,eAAe,EAAE,CAcnB;AAED,4DAA4D;AAC5D,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,SAAS,eAAe,EAAE,GAAG,MAAM,CAEnF;AAED,qBAAa,eAAgB,SAAQ,aAAa,CAAC,qBAAqB,EAAE,qBAAqB,CAAC;IAC/F,QAAQ,CAAC,IAAI,EAAG,YAAY,CAAS;gBAEzB,QAAQ,EAAE,IAAI,CAAC,aAAa,EAAE,MAAM,GAAG,cAAc,CAAC;IAalE;;;;;;;;OAQG;IACG,GAAG,CACR,KAAK,EAAE,UAAU,EACjB,MAAM,EAAE,qBAAqB,EAC7B,QAAQ,CAAC,EAAE,gBAAgB,GACzB,OAAO,CAAC,qBAAqB,CAAC;YAMnB,YAAY;
|
|
1
|
+
{"version":3,"file":"SupervisorAgent.d.ts","sourceRoot":"","sources":["../../src/agents/SupervisorAgent.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAe,UAAU,EAAE,MAAM,2BAA2B,CAAA;AACxE,OAAO,KAAK,EACX,UAAU,EACV,aAAa,EACb,eAAe,EACf,qBAAqB,EACrB,qBAAqB,EACrB,MAAM,yBAAyB,CAAA;AAEhC,OAAO,KAAK,EAAW,KAAK,EAAU,MAAM,uBAAuB,CAAA;AAEnE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAG7D,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAElD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,qBAAqB,CACpC,WAAW,EAAE,SAAS,UAAU,EAAE,EAClC,KAAK,EAAE,KAAK,EACZ,GAAG,GAAE,MAAmB,GACtB,eAAe,EAAE,CAcnB;AAED,4DAA4D;AAC5D,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,SAAS,eAAe,EAAE,GAAG,MAAM,CAEnF;AAED,qBAAa,eAAgB,SAAQ,aAAa,CAAC,qBAAqB,EAAE,qBAAqB,CAAC;IAC/F,QAAQ,CAAC,IAAI,EAAG,YAAY,CAAS;gBAEzB,QAAQ,EAAE,IAAI,CAAC,aAAa,EAAE,MAAM,GAAG,cAAc,CAAC;IAalE;;;;;;;;OAQG;IACG,GAAG,CACR,KAAK,EAAE,UAAU,EACjB,MAAM,EAAE,qBAAqB,EAC7B,QAAQ,CAAC,EAAE,gBAAgB,GACzB,OAAO,CAAC,qBAAqB,CAAC;YAMnB,YAAY;CA2L1B"}
|
|
@@ -108,6 +108,12 @@ export class SupervisorAgent extends AbstractAgent {
|
|
|
108
108
|
remaining: config.tokenBudget,
|
|
109
109
|
},
|
|
110
110
|
factoryOptions: mergedFactoryOptions,
|
|
111
|
+
// The supervisor already hands this to its OWN run and its own
|
|
112
|
+
// coordinator tools; handing it to the spawn context is what
|
|
113
|
+
// makes a worker ask the same person the supervisor asks.
|
|
114
|
+
// Without it the two disagreed: the supervisor paused for a
|
|
115
|
+
// human and the workers it launched approved themselves.
|
|
116
|
+
...(config.resumeHandler ? { resumeHandler: config.resumeHandler } : {}),
|
|
111
117
|
tenantId,
|
|
112
118
|
threadId,
|
|
113
119
|
sessionId,
|