fix(agents): deliver complete subagent answers to waiting parents (#1…

fix(agents): deliver complete subagent answers to waiting parents (#149223)

Most added lines cover regressions and move formatting beside exact-run reads; archived histories now stream through the existing storage worker.

## What Problem This Solves

Completed child answers could lose required fields before their parent read them. Closes #138555. Reported by @aleps001.

## Why This Change Was Made

The parent receives the complete visible final answer from the selected child run, including its registered deletion archive. Descendant results remain input to the child's synthesis. A persisted final message-tool reply remains authoritative after a later same-run `NO_REPLY`.

The shared 4,096-character terminal snapshot stays bounded for lifecycle and durable evidence. This state has one writer. Stored shapes, retention, and cleanup ownership are unchanged. Complete answers use more parent context. The owner's September 15 decision replaces projection limits from #119731 and #124171 while preserving escaping, metadata limits, stable order, and whole-item queue delivery.

## User Impact

Waiting and returning parents receive complete answers while the exact-run transcript remains retained. If archive pruning has removed it, that completion uses its capped published result with a `truncated-by-retention` marker. Healthy siblings and the parent continue. Public and private nested children forward their own conclusions. Large archived histories no longer require one decoded string on the Gateway thread.

## Evidence

An 8,638-character answer lost its required tail on the baseline. Served Chat now delivers all 11,758 escaped characters to the resumed parent and retains them after child deletion. A public nested case delivers the middle child's distinct conclusion. Earlier aggregate, nested-yield, and ordinary completion captures also pass.

The registered `maybeWakeRequesterAfterAllChildrenSettled` regression uses capped visible terminal evidence and a complete >4,096-character exact-run transcript with a trailing same-run `NO_REPLY` row. It fails on the original implementation and passes here. The producer contract is covered by [run-entry-terminal.ts](https://github.com/openclaw/openclaw/blob/a97d75a928ed8f5a9f70ee7977da8e767d03acea/src/agents/embedded-agent-runner/run-entry-terminal.ts#L153) and [run-entry.test.ts:928–931](https://github.com/openclaw/openclaw/blob/a97d75a928ed8f5a9f70ee7977da8e767d03acea/src/agents/embedded-agent-runner/run-entry.test.ts#L928). Native children cannot call `message` under the existing hard deny, so that live cell is excluded.

A returning parent can receive a kept child’s answer and then continue after that child starts a valid follow-up. The registered tool-result continuation fails on `a97d75a9` and passes here. Initial source rejection, parent cancellation, and pre-prompt compaction remain covered.

The registered `attempt-prompt-submit.retention.test.ts` regression publishes and prunes a child archive, then consumes deferred results through the real parent session (`node scripts/run-vitest.mjs run src/agents/embedded-agent-runner/run/attempt-prompt-submit.retention.test.ts`). It fails before the correction and passes with the marked retained result, the healthy sibling’s complete answer, cleared delivery leases, and a successful next parent turn.

[Scenario and captures](https://gist.github.com/obviyus/cce960c04dafd949c21141686af3696e).

| Before | After |
| --- | --- |
| ![Missing field](https://gist.githubusercontent.com/obviyus/cce960c04dafd949c21141686af3696e/raw/e8b97302964ad1bd874c7b4f578c30a72593610a/before.png) | ![Complete field](https://gist.githubusercontent.com/obviyus/cce960c04dafd949c21141686af3696e/raw/e8b97302964ad1bd874c7b4f578c30a72593610a/after.png) |

## Compatibility

No public API, schema, retention, or retrieval feature changes. Archive hash, header, session, and owner checks remain. The existing worker scans a 536.9 MB decoded archive whose previous whole-string decoder failed.

## Consumers

Requester settlement, deferred turns, nested announcements, event projections, and retained parent history use the complete result, or the marked retained snapshot when its exact answer is unavailable.

## Invalidation

Run, producer, generation, batch, requester, and lease authority are rechecked after reads and before delivery. Failed prompt assembly releases its lease. Deferred source validation ends after the first foreground stream is acquired; parent abort checks remain active.

## Tests

The retained complete-result proof covers 374 tests across 15 files, including the format suite. The retained owner and sibling proof covers 379 passing tests across 17 files on a fresh merge with main, including the format and retention regressions. Four additional consumer suites update their explicit session-accessor mocks for the exact-run reader; their 286 tests pass on a fresh merge with main, with behavior assertions unchanged. Registered settlement, deferred-input, and continuation regressions fail on their original source. Type-aware preflight, structural checks, and test registration pass.

Production growth is 422 lines: result +241; output −130; queue +27; registry API +8; prompt build/phase/submit +6/+1/+16; wake/message −44/+54; announce +13; events −16; archive read/session/types/dispatch/worker/history +183/+6/+14/+20/+9/+11; history export +3. Growth accepted under the owner's standing acceptance (2026-09-15).

Co-authored-by: Ayaan Zaidi 
添加评论
点赞收藏
点踩分享查看原文
评论
?
参与讨论