fix(session): persist the delegation depth in the session header

A subagent child's recursion depth lived only in runtime AgentOptions,
so a persisted child came back from resume counted as top-level and
maxDepth stopped binding after every restart. Add
SessionHeader.delegationDepth, round-trip it through the JSONL and
SQLite backends (SQLite schema v5), restore it on agent-loop resume,
and write it when the in-process backends create a child. The seam now
owns the shared depth vocabulary (delegationDepthOf): the persisted
header is authoritative and monotone — runtime options may deepen it
but never lower it.
This commit is contained in:
Yichen Jiang
2026-07-19 17:20:36 +08:00
parent e05e7a0870
commit 0d00106fa8
29 changed files with 229 additions and 106 deletions
+15 -15
View File
@@ -7,7 +7,7 @@
Agent service (`ctx.agents`): tracks live agents and carries the initiating Agent through one process-local asynchronous driver chain. Agent *creation* is provided by whichever plugin implements the AgentFactory (`@deepseek-ai/dsh-agent-loop`), registered via setFactory.
Initiator methods provide same-process causal attribution only. Ambient presence is neither liveness proof nor authorization; subjects and owners remain explicit, as does identity at worker, process, persistence, and wire boundaries. Returned Promise boundaries drain during teardown, except a nested lineage that starts an owning-fiber unload is excluded from its own drain.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/index.ts#L217)
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/index.ts#L223)
### ctx.agents.currentInitiator()
@@ -28,7 +28,7 @@ Read the Agent that initiated the inherited asynchronous driver chain. Use this
**Returns** the inherited Agent, or `undefined` outside an initiator boundary and inside an explicit clearing boundary.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/index.ts#L256)
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/index.ts#L262)
### ctx.agents.requireInitiator()
@@ -48,7 +48,7 @@ Read the initiating Agent and fail when no initiator boundary is active. Use thi
**Returns** the inherited Agent.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/index.ts#L269)
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/index.ts#L275)
### ctx.agents.withInitiator(agent, operation)
@@ -76,7 +76,7 @@ Run an operation with one exact Agent as its process-local initiator. The exact
**Returns** the exact value returned by `operation`.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/index.ts#L288)
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/index.ts#L294)
### ctx.agents.withoutInitiator(operation)
@@ -101,7 +101,7 @@ Run an operation inside a boundary that hides any inherited initiating Agent. Th
**Returns** the exact value returned by `operation`.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/index.ts#L303)
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/index.ts#L309)
### ctx.agents.setFactory(factory)
@@ -127,7 +127,7 @@ Register the agent-creation factory (the loop calls this on construction, effect
**Returns** the disposer that clears the factory slot. The exact Cordis effect disposer (single-shot): composite (generator) effects may yield it directly — exact identity nests the teardown in order.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/index.ts#L319)
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/index.ts#L325)
### ctx.agents.create(options)
@@ -150,7 +150,7 @@ Create and publish a new agent through the registered factory. Distinct from reg
**Returns** the handle after setup, rollback-covered publication, and loop start complete.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/index.ts#L352)
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/index.ts#L358)
### ctx.agents.resume(options)
@@ -171,7 +171,7 @@ Load a persisted session and resume an agent on it through the registered factor
**Returns** the handle after setup, rollback-covered publication, and loop start complete.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/index.ts#L371)
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/index.ts#L377)
### ctx.agents.register(agent)
@@ -203,7 +203,7 @@ Register a live agent. Throws if an agent with the same id is already registered
**Returns** the EXACT Cordis effect disposer (single-shot; a repeat call returns undefined without awaiting an in-flight teardown). Exact identity is load-bearing: a composite (generator) effect that owns a teardown ORDER — the agent factory's lifecycle chain — must yield THIS function so Cordis nests the unregistration at that yield position; yielding a wrapper would leave it disposing as a concurrent sibling on owner unload, unregistering the agent (and emitting `agent/disposed`) while its final turn is still draining.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/index.ts#L397)
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/index.ts#L403)
### ctx.agents.enter(agent, owner)
@@ -233,7 +233,7 @@ Insert an already-constructed agent without announcing it. This is the advanced
**Returns** an idempotent closure that removes this exact entry and emits `agent/disposed` with listener failures contained. When called from a synchronous `agent/created` listener, removal and disposal wait until that creation dispatch unwinds.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/index.ts#L421)
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/index.ts#L427)
### ctx.agents.announce(agent)
@@ -252,7 +252,7 @@ Announce an agent previously inserted with enter.
- `agent` — the live inserted agent to announce.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/index.ts#L496)
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/index.ts#L502)
### ctx.agents.get(id)
@@ -271,7 +271,7 @@ Look up a live agent.
**Returns** the agent, or undefined when no live agent has that id.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/index.ts#L530)
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/index.ts#L536)
### ctx.agents.isOwnedBy(id, owner)
@@ -294,7 +294,7 @@ Test whether a live agent was created through one exact parent agent's scoped co
**Returns** true only while the exact child entry is live under that owner.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/index.ts#L542)
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/index.ts#L548)
### ctx.agents.list()
@@ -310,7 +310,7 @@ All live agents, in registration order.
**Returns** a fresh array; mutating it does not affect the registry.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/index.ts#L550)
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/index.ts#L556)
### ctx.agents.roots()
@@ -328,4 +328,4 @@ All live top-level agents in registration order. A top-level agent was created w
**Returns** a fresh array; mutating it does not affect the registry.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/index.ts#L560)
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/index.ts#L566)