Replies: 4 comments 2 replies
我最近在读 以下行号引用均基于 我查到的1.
composeFrom(agentCtx, parentCtx) {
const agentKey = scopeOf(agentCtx);
const standing = standingMountFor(parentCtx); // 永远是父代理的 standing mount
if (standing === undefined) return undefined;
this.bindings.set(agentKey, bindScopeParent(agentKey, standing.key));
return standing.presetId;
}签名是 2. 子代理走的恰恰就是这个调用。
childCtx.get('agentPresets')?.composeFrom(childCtx, parent.ctx)而且预设是刻意从父代理的实时(live) scope 链读取,而非从它的持久化 header 读。对应的测试( 3. delegate 工具不暴露预设字段。
两个让我停顿的旁证
我一直撞上的那个约束
if (boundary !== undefined && (boundary.openTurnStartSeq !== null || boundary.lastTurn > 0)) {
throw new RemoteError('agent-preset/locked', ...)
}这就是文档化的"空白会话"契约。而 in-process 驱动是在同步的
我想达成的用例我希望父代理能把任务委派给自带技能集的专家子代理——例如一个 Unity 专家子代理和一个 Blender 专家子代理——而不需要人工去手工编排多个顶层会话。目前只能绕行:从 GUI 为每个预设单独开一个顶层会话,再在它们之间人工传递接口。 我的问题
无论你们接受哪个方向,我都乐意去做原型。我完全可能漏了仓库里的上下文,所以哪怕只是指个路,和给出答案一样有用。 |
|
Verified against Q1 — deliberate, and currently the only path. Inheritance is not just what
Q2 — the documented reason is exactly the one you quoted, and I found no stronger one in the tree (no trust-model note anywhere in the code). The reinforcements are structural rather than trust-based: the private binding authority and the sync Q3 — no in-tree seam selects a preset per delegation. The nearest thing, which you didn't mention, is the out-of-process backends ( (Your fixture reading is also right: Q4 — between your two shapes, (a) is the more honest one, and I'd add two constraints. One naming note first: at this commit the function is
I'd be happy to prototype (a) behind the capability flag if a maintainer blesses the direction. 中文摘要:① 子代理继承父预设是刻意设计(bind 而非 mount,子代加入父代的同一 standing 实例),也是当前唯一路径;② 代码里记录的理由就是你在 |
|
Follow-up after reading Why redirecting a live child is not availableThree facts, all verifiable against the tree:
The subagent subsystem exposes only four events ( What does work
So instead of redirecting the delegate path, I registered a separate delegation tool that creates its own child: const handle = await ctx.agents.create({
sessionId, parentAgent: parent, signal,
agentOptions: resolveChildAgentOptions(parent, undefined, childDepth),
meta: { origin: 'subagent', delegationDepth: childDepth, agentPreset: requested.id, ... },
setup: async (agentCtx) => { await ctx.agentPresets.mount(agentCtx, requested.id) },
})then It works in a normal production profile: the child's first request already carries the named preset's tools, skills, and prompt sections. Worth noting for anyone attempting the same: recording Two things I could not resolve from the docs
Happy to share the plugin if it is useful as a reference, or to drop it if this is intended to be impossible. |
|
Both corrections verified against the same checkout (c291e79) — you're right on both, and thank you for catching them:
On the two items you couldn't resolve from the docs:
Your plugin is a solid reference implementation for shape (a); if a maintainer blesses the direction, any PR could start from working code instead of zero. Thanks for the push-back on both points — the record is more accurate now. |
Uh oh!
There was an error while loading. Please reload this page.
I've been reading
packages/presetand the subagent drivers, and I can't find any supported way to make a delegated child run on a preset other than its parent's. Before treating that as a gap, I'd like to check whether it's deliberate and whether I'm missing a seam.All line references are against
master@c291e79(2026-09-10); I also verified the behaviour against the published@deepseek-ai/dsh-agent-presets@0.1.5-rc.2.What I found
1.
composeFromhas no preset id.packages/preset/agent-presets/src/index.ts(implementation inlib/types/index.js):The signature is
(agentCtx, parentCtx)— there is no parameter through which a different preset id could arrive.mount(agentCtx, id)is the one that takes an id.2. Children go through exactly that call.
packages/subagent/subagent/src/child-agent.ts:and the preset is deliberately read from the parent's live scope chain rather than its durable header. The matching tests (
packages/subagent/subagent-in-process-driver/tests/preset-inheritance.spec.ts) assert this inheritance directly, including a case where the parent wasrecomposed to a different preset while blank and the child follows it.3. The delegate tool exposes no preset field.
packages/subagent/tool-subagent— nopresetparameter. So there is no model-facing path either.Two adjacent things that made me pause
packages/subagent/subagent-in-process-driver/tests/fixtures/presets/containscodingandreviewing(with matchingpreset_only/reviewing_onlytools) andtests/preset-inheritance.spec.ts. The fixture names suggest per-child preset assignment was at least considered or prototyped. The archived preset-tool-filter-DSL note points in the same direction, though I couldn't reach that file (404) so I may be reading too much into fixture names.persona,toolFilter, andmaxDepth(2026-07-12-subagent-persona-tool-filter-and-depth.md). These customise a child but cannot switch its preset — they filter or overlay the inherited composition.The constraint I keep running into
agentPresets/selectexists as a remote method andselect(agent, agentPreset)as a service method, butswap()refuses once the session has produced anything:which is the documented blank-session contract. And the in-process drivers compose their children inside a synchronous
setup, whilemount()is async — so composing a child from a named preset does not obviously fit the window the drivers use.CreateAgentOptions.agentPresetdoes exist (packages/core/agent/src/types.ts) and the child header recordsagentPreset, but that field is set by whoever callsctx.agents.create— not by the tool caller.The use case I'm trying to reach
I want a parent to delegate to specialist children that carry their own skill sets — e.g. a Unity-expert child and a Blender-expert child — without a human hand-orchestrating several top-level sessions. Today the workaround is manual: open a separate top-level session per preset from the GUI and pass interfaces between them.
Questions
composeFrom's doc comment, or is there something stronger — trust, or composition semantics?presetfield on the subagent tool plus a new provider capability flag (alongsidepersona/toolFilter/depthLimit), orcomposeOneChildmounting an explicitly requested preset instead ofcomposeFromThe second looks smaller, but it has to solve the sync-
setup-vs-async-mountmismatch, which makes me suspect the first is the more honest shape.I'm happy to prototype whichever direction you'd accept. I may well be missing repo context, so a pointer would be just as useful as an answer.
All reactions