mirror of
https://github.com/deepseek-ai/deepseek-harness
synced 2026-08-15 21:04:50 +00:00
fix(subagent): preserve published run failures
This commit is contained in:
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write docs/core-data-structures/subagent.md
|
||||
subagent.md: fec0cc0c54d7d895cde8708bb8b12d81a3b21dd1
|
||||
subagent.zh.md: c36ae26b791cbd3dc8972e6f185ed4ff9594b70f
|
||||
subagent.md: 08270a0487402d29e12bb1fc2687b29903f5bd6b
|
||||
subagent.zh.md: aade7a2edc13a6ec694634cee9dcb47cfb9e6bea
|
||||
|
||||
@@ -59,8 +59,8 @@ interface SubagentStartRequest {
|
||||
* Cancellation signal from the spawning context (the tool's `exec.signal`).
|
||||
* This is the canonical cancellation channel both before and after startup:
|
||||
* a provider rejects `start()` after cleaning partial resources when it
|
||||
* fires before publication, and cancels a published child when it fires
|
||||
* afterward.
|
||||
* fires before the run is published, and cancels the published run's
|
||||
* remaining turn work when it fires afterward.
|
||||
*/
|
||||
readonly signal: AbortSignal
|
||||
readonly agentOptions?: AgentOptions
|
||||
@@ -271,16 +271,17 @@ interface SubagentStopReasonMap {
|
||||
|
||||
## A one-shot run: `SubagentRun`
|
||||
|
||||
`SubagentRun` is the consumer-owned handle for a ready one-shot child — one disposable foreground delegation with one result, never a durable child handle. Consumers await `result` and always dispose the run to reach quiescence. Child failures resolve with a non-completed stop reason; only unrepresentable infrastructure faults reject. A run has no steering and no resume: continuable conversations have no run at all, because the continuation manager holds their `AgentHandle` directly and orders every turn through the child's own inbox.
|
||||
`SubagentRun` is the consumer-owned handle for a published one-shot child — one disposable foreground delegation with one result, never a durable child handle. Prompt submission, turn work, and infrastructure faults after publication belong to `result`. Consumers await that result and always dispose the run to reach quiescence. Child failures resolve with a non-completed stop reason; only unrepresentable infrastructure faults reject. A run has no steering and no resume: continuable conversations have no run at all, because the continuation manager holds their `AgentHandle` directly and orders every turn through the child's own inbox.
|
||||
|
||||
```ts type-equiv
|
||||
/**
|
||||
* ONE-SHOT child handle returned only after readiness. Consumers await
|
||||
* {@link result} and must always {@link dispose} to cancel remaining work and
|
||||
* reach quiescence. A run is one disposable foreground delegation with one
|
||||
* result; continuable conversations have no run — the continuation manager
|
||||
* holds their `AgentHandle` directly and orders every turn through the child's
|
||||
* own inbox.
|
||||
* ONE-SHOT child handle returned after publication. Prompt submission, turn
|
||||
* work, and infrastructure faults after that boundary belong to {@link result}.
|
||||
* Consumers await that result and must always {@link dispose} to cancel
|
||||
* remaining work and reach quiescence. A run is one disposable foreground
|
||||
* delegation with one result; continuable conversations have no run — the
|
||||
* continuation manager holds their `AgentHandle` directly and orders every
|
||||
* turn through the child's own inbox.
|
||||
*/
|
||||
interface SubagentRun {
|
||||
/**
|
||||
@@ -335,13 +336,14 @@ interface SubagentProvider {
|
||||
*/
|
||||
readonly inheritsParentContext: boolean
|
||||
/**
|
||||
* Establish a ONE-SHOT child and return its handle only after publication.
|
||||
* Establish a ONE-SHOT child and return its handle after publication.
|
||||
* The service has already validated that every requested start-time
|
||||
* capability is supported and resolved `request.descriptor`, so a
|
||||
* session-backed implementation appends that descriptor inside the child's
|
||||
* initial turn. If setup fails or `request.signal` aborts before fulfillment,
|
||||
* the provider owns and cleans all partial resources before this promise
|
||||
* rejects. Ownership transfers to the caller only on fulfillment.
|
||||
* initial turn. Before fulfillment, the provider owns setup and cleans any
|
||||
* unpublished partial resources before rejecting. Ownership transfers on
|
||||
* fulfillment; subsequent turn or infrastructure failure settles through
|
||||
* the returned run.
|
||||
*/
|
||||
start(request: ResolvedSubagentStartRequest): Promise<SubagentRun>
|
||||
/**
|
||||
@@ -361,7 +363,7 @@ interface SubagentProvider {
|
||||
}
|
||||
```
|
||||
|
||||
Provider `start()` fulfills only with a ready run. The service mints a unique `runId`, snapshots `local` from the provider's exact `localAgent`, observes the result, emits `subagent/start`, and returns the same run; rejection implies provider cleanup and emits no lifecycle pair. Each continuable Activation emits the same observe-only pair for its residency epoch, so a cold resume is a new epoch with its own `runId`. The paired `subagent/end` carries the same identity and the final output or infrastructure failure. Both events are observe-only and contain listener exceptions. Their `provider` field is provenance for the run or Activation epoch, not a claim that the provider remains registered when the edge is emitted.
|
||||
Provider `start()` fulfills with a published run. The service mints a unique `runId`, snapshots `local` from the provider's exact `localAgent`, observes the result, emits `subagent/start`, and returns the same run; a `start()` rejection implies cleanup of unpublished resources and emits no lifecycle pair, while a post-publication result rejection closes the emitted pair. Each continuable Activation emits the same observe-only pair for its residency epoch, so a cold resume is a new epoch with its own `runId`. The paired `subagent/end` carries the same identity and the final output or infrastructure failure. Both events are observe-only and contain listener exceptions. Their `provider` field is provenance for the run or Activation epoch, not a claim that the provider remains registered when the edge is emitted.
|
||||
|
||||
## In-process backends: depth and seed
|
||||
|
||||
|
||||
@@ -59,8 +59,8 @@ interface SubagentStartRequest {
|
||||
* Cancellation signal from the spawning context (the tool's `exec.signal`).
|
||||
* This is the canonical cancellation channel both before and after startup:
|
||||
* a provider rejects `start()` after cleaning partial resources when it
|
||||
* fires before publication, and cancels a published child when it fires
|
||||
* afterward.
|
||||
* fires before the run is published, and cancels the published run's
|
||||
* remaining turn work when it fires afterward.
|
||||
*/
|
||||
readonly signal: AbortSignal
|
||||
readonly agentOptions?: AgentOptions
|
||||
@@ -271,16 +271,17 @@ interface SubagentStopReasonMap {
|
||||
|
||||
## 单次 run:`SubagentRun`
|
||||
|
||||
`SubagentRun` 是消费方持有的、指向一个就绪单次子 agent 的句柄——一次可 dispose 的前台委派,只有一个结果,绝不是持久化子 agent handle。消费方 await `result` 并始终 dispose 该 run,直至完全停稳。子 agent 失败时以非 completed 的 stop reason resolve;只有无法表示的基础设施故障才会 reject。run 没有 steering,也没有 resume:可继续对话根本没有 run,因为继续执行管理器直接持有它们的 `AgentHandle`,并通过子 agent 自己的收件箱为每个轮次排序。
|
||||
`SubagentRun` 是消费方持有的、指向一个已发布单次子 agent 的句柄——一次可 dispose 的前台委派,只有一个结果,绝不是持久化子 agent handle。发布后的提示词提交、轮次工作与基础设施故障归 `result` 所有。消费方 await 该结果并始终 dispose 该 run,直至完全停稳。子 agent 失败时以非 completed 的 stop reason resolve;只有无法表示的基础设施故障才会 reject。run 没有 steering,也没有 resume:可继续对话根本没有 run,因为继续执行管理器直接持有它们的 `AgentHandle`,并通过子 agent 自己的收件箱为每个轮次排序。
|
||||
|
||||
```ts type-equiv
|
||||
/**
|
||||
* ONE-SHOT child handle returned only after readiness. Consumers await
|
||||
* {@link result} and must always {@link dispose} to cancel remaining work and
|
||||
* reach quiescence. A run is one disposable foreground delegation with one
|
||||
* result; continuable conversations have no run — the continuation manager
|
||||
* holds their `AgentHandle` directly and orders every turn through the child's
|
||||
* own inbox.
|
||||
* ONE-SHOT child handle returned after publication. Prompt submission, turn
|
||||
* work, and infrastructure faults after that boundary belong to {@link result}.
|
||||
* Consumers await that result and must always {@link dispose} to cancel
|
||||
* remaining work and reach quiescence. A run is one disposable foreground
|
||||
* delegation with one result; continuable conversations have no run — the
|
||||
* continuation manager holds their `AgentHandle` directly and orders every
|
||||
* turn through the child's own inbox.
|
||||
*/
|
||||
interface SubagentRun {
|
||||
/**
|
||||
@@ -337,13 +338,14 @@ interface SubagentProvider {
|
||||
*/
|
||||
readonly inheritsParentContext: boolean
|
||||
/**
|
||||
* Establish a ONE-SHOT child and return its handle only after publication.
|
||||
* Establish a ONE-SHOT child and return its handle after publication.
|
||||
* The service has already validated that every requested start-time
|
||||
* capability is supported and resolved `request.descriptor`, so a
|
||||
* session-backed implementation appends that descriptor inside the child's
|
||||
* initial turn. If setup fails or `request.signal` aborts before fulfillment,
|
||||
* the provider owns and cleans all partial resources before this promise
|
||||
* rejects. Ownership transfers to the caller only on fulfillment.
|
||||
* initial turn. Before fulfillment, the provider owns setup and cleans any
|
||||
* unpublished partial resources before rejecting. Ownership transfers on
|
||||
* fulfillment; subsequent turn or infrastructure failure settles through
|
||||
* the returned run.
|
||||
*/
|
||||
start(request: ResolvedSubagentStartRequest): Promise<SubagentRun>
|
||||
/**
|
||||
@@ -363,7 +365,7 @@ interface SubagentProvider {
|
||||
}
|
||||
```
|
||||
|
||||
提供方的 `start()` 仅在 run 就绪时 fulfill。服务铸造唯一的 `runId`,从提供方确切的 `localAgent` 快照 `local`,观察结果,emit `subagent/start`,并返回同一个 run;rejection 意味着提供方已清理,且不会 emit 生命周期事件对。每个可继续 Activation 都会为其驻留纪元 emit 相同的仅观察事件对,因此一次冷恢复就是一段拥有自己 `runId` 的新纪元。配对的 `subagent/end` 携带相同标识与最终输出或基础设施失败。两个事件都仅用于观察,且会隔离各自的 listener 异常。其中的 `provider` 字段是 run 或 Activation 时段的来源信息,并不声明该 edge 发出时提供方仍处于注册状态。
|
||||
提供方的 `start()` 会以已发布的 run fulfill。服务铸造唯一的 `runId`,从提供方确切的 `localAgent` 快照 `local`,观察结果,emit `subagent/start`,并返回同一个 run;`start()` rejection 意味着未发布资源已清理,且不会 emit 生命周期事件对,而发布后的结果 rejection 会结束已经 emit 的事件对。每个可继续 Activation 都会为其驻留纪元 emit 相同的仅观察事件对,因此一次冷恢复就是一段拥有自己 `runId` 的新纪元。配对的 `subagent/end` 携带相同标识与最终输出或基础设施失败。两个事件都仅用于观察,且会隔离各自的 listener 异常。其中的 `provider` 字段是 run 或 Activation 时段的来源信息,并不声明该 edge 发出时提供方仍处于注册状态。
|
||||
|
||||
## 进程内后端:深度与种子
|
||||
|
||||
|
||||
Reference in New Issue
Block a user