You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Version:@deepseek-ai/dsh-subagent 0.1.5-rc.2 (behavior identical in the 0.1.2-rc.1 published artifact)
What I'm asking for
An opt-in way for the creator of a continuable child to say: "do not deliver a settlement notice to the parent for this child."
Concretely, an optional field on ContinuableStartSpec — e.g. settlementNotice?: 'notify' | 'silent', defaulting to 'notify' so today's behavior is unchanged — persisted in the durable descriptor alongside the per-child options that already survive cold resume (toolFilter, persona, agentOptions).
The scenario it's for
A host integration where the child's outcome is already delivered to its real audience through a channel the host owns — a chat surface, a ticket update, a webhook. The parent is not the audience and never was.
The shape that makes this hurt:
the parent is a long-lived session a human is actively working in, not a throwaway orchestrator;
that one parent owns several continuable children serving different destinations;
each child, on settling, delivers a notice to the parent.
Today that notice reaches a non-idle parent through steer:
and steer is documented as "Submit steering for the nearest step. … a running driver consumes it at its next step boundary."
So every child settlement lands inside whatever turn the human's session is currently running. With N children that's N interruptions of unrelated in-progress work, carrying information the parent has no use for — the outcome was already reported elsewhere.
Why the existing outs don't cover it
I checked each of these against both 0.1.2-rc.1 and 0.1.5-rc.2 before posting:
activation.announced — documented as "Whether any delivery to this child was ever accepted. A materialization rolled back before its first acceptance is a child the caller was told does not exist, so its teardown owes the parent no settlement account." That is a "this child never really existed" gate. My children very much existed and did real work; they just reported somewhere else. Semantically the wrong switch.
parent === undefined — would suppress it, but only by making the parent non-live. Not something anyone should engineer for a session a human is using.
closingTeardownFor(parent) — this branch uses parent.inject(...), but its condition (parent already tearing down) is unreachable for a healthy long-lived parent.
Intercepting in sendWaking — when the parent is a plain root agent rather than a resident activation, sendWaking falls through to parent.steer(message) directly, so there is no intermediate object to interpose on.
Cleaning up on the parent side afterwards — subagent-settled is a public message source kind, so a host can recognize and remove the entry; but by then the steering has already been consumed at a step boundary. That removes the transcript line, not the interruption.
Switching the delivery to inject instead of steer — I considered proposing this as the smaller change, then ruled it out: inject and steer differ only in the wakeup flag (agent-loop/src/agent.ts, both target next-step). It removes the extra wake, but the message still enters the parent's in-flight turn at the next step boundary. For this use case the requirement is that the parent's current work is untouched, so opting out entirely is the only thing that satisfies it.
Why opt-in rather than a default change
I'm explicitly not proposing to change what parents see by default. A parent that has no other visibility into its children should keep getting the notice — that's the right default, and #5360 argues for even more parent-visible signal, which I agree with for its scenario.
The request is only for callers that have taken on the reporting responsibility themselves to be able to say so. That's also why the descriptor needs to carry it: after a cold resume the runtime has to still know this child's outcome is somebody else's job.
#5360 asks for the opposite direction — an additional parent-visible notice on the running → waiting transition, so a parked manager stops falling off its supervisor's radar.
I don't think these conflict, and I'd rather they be considered together: that request is about making sure a parent learns about a child it would otherwise lose track of; this one is about letting a caller that already reports elsewhere decline a notice it doesn't need. Both point at the same underlying gap — settlement delivery currently has exactly one policy, and whether that policy is right depends on who owns the child's reporting channel.
Notes
Not a regression: notifySettlement is byte-identical in the 0.1.2-rc.1 published artifact, so this has always been the behavior.
Happy to provide a minimal reproduction (one long-lived parent mid-turn, two continuable children settling) if useful.
I understand external PRs aren't accepted; posting here per CONTRIBUTING.md. If the shape is acceptable I'm glad to share the exact diff I'm running locally for reference.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Version:
@deepseek-ai/dsh-subagent0.1.5-rc.2 (behavior identical in the 0.1.2-rc.1 published artifact)What I'm asking for
An opt-in way for the creator of a continuable child to say: "do not deliver a settlement notice to the parent for this child."
Concretely, an optional field on
ContinuableStartSpec— e.g.settlementNotice?: 'notify' | 'silent', defaulting to'notify'so today's behavior is unchanged — persisted in the durable descriptor alongside the per-child options that already survive cold resume (toolFilter,persona,agentOptions).The scenario it's for
A host integration where the child's outcome is already delivered to its real audience through a channel the host owns — a chat surface, a ticket update, a webhook. The parent is not the audience and never was.
The shape that makes this hurt:
Today that notice reaches a non-idle parent through
steer:and
steeris documented as "Submit steering for the nearest step. … a running driver consumes it at its next step boundary."So every child settlement lands inside whatever turn the human's session is currently running. With N children that's N interruptions of unrelated in-progress work, carrying information the parent has no use for — the outcome was already reported elsewhere.
Why the existing outs don't cover it
I checked each of these against both 0.1.2-rc.1 and 0.1.5-rc.2 before posting:
activation.announced— documented as "Whether any delivery to this child was ever accepted. A materialization rolled back before its first acceptance is a child the caller was told does not exist, so its teardown owes the parent no settlement account." That is a "this child never really existed" gate. My children very much existed and did real work; they just reported somewhere else. Semantically the wrong switch.parent === undefined— would suppress it, but only by making the parent non-live. Not something anyone should engineer for a session a human is using.closingTeardownFor(parent)— this branch usesparent.inject(...), but its condition (parent already tearing down) is unreachable for a healthy long-lived parent.sendWaking— when the parent is a plain root agent rather than a resident activation,sendWakingfalls through toparent.steer(message)directly, so there is no intermediate object to interpose on.subagent-settledis a public message source kind, so a host can recognize and remove the entry; but by then the steering has already been consumed at a step boundary. That removes the transcript line, not the interruption.injectinstead ofsteer— I considered proposing this as the smaller change, then ruled it out:injectandsteerdiffer only in thewakeupflag (agent-loop/src/agent.ts, both targetnext-step). It removes the extra wake, but the message still enters the parent's in-flight turn at the next step boundary. For this use case the requirement is that the parent's current work is untouched, so opting out entirely is the only thing that satisfies it.Why opt-in rather than a default change
I'm explicitly not proposing to change what parents see by default. A parent that has no other visibility into its children should keep getting the notice — that's the right default, and #5360 argues for even more parent-visible signal, which I agree with for its scenario.
The request is only for callers that have taken on the reporting responsibility themselves to be able to say so. That's also why the descriptor needs to carry it: after a cold resume the runtime has to still know this child's outcome is somebody else's job.
Relationship to #5360
#5360 asks for the opposite direction — an additional parent-visible notice on the
running → waitingtransition, so a parked manager stops falling off its supervisor's radar.I don't think these conflict, and I'd rather they be considered together: that request is about making sure a parent learns about a child it would otherwise lose track of; this one is about letting a caller that already reports elsewhere decline a notice it doesn't need. Both point at the same underlying gap — settlement delivery currently has exactly one policy, and whether that policy is right depends on who owns the child's reporting channel.
Notes
notifySettlementis byte-identical in the 0.1.2-rc.1 published artifact, so this has always been the behavior.CONTRIBUTING.md. If the shape is acceptable I'm glad to share the exact diff I'm running locally for reference.All reactions