Skip to content

bug: prevent spawn_agent from returning stale final text - #81

Merged
ALX99 merged 2 commits into
masterfrom
bug/prevent-spawn-agent-stale-final-text
Jul 6, 2026
Merged

bug: prevent spawn_agent from returning stale final text#81
ALX99 merged 2 commits into
masterfrom
bug/prevent-spawn-agent-stale-final-text

Conversation

@ALX99

@ALX99 ALX99 commented Jul 5, 2026

Copy link
Copy Markdown
Owner

Bug

spawn_agent can return stale partial text instead of the child agent's final answer when the final assistant message_end contains multiple non-empty text parts. getFinalText() documents and is used as the last non-empty assistant text block selector, but it searched text parts in forward order inside the final assistant message.

Severity and impact

This is a correctness bug in normal subagent delegation. When a child emits an early text part, performs a tool call, and then emits the actual final answer as a later text part in the same assistant message, the parent receives the earlier draft/partial text. That can mislead the parent agent or user even though the child produced the correct final output.

Evidence

Relevant files and functions:

  • home/.pi/agent/extensions/subagents/process.ts, getFinalText()
  • home/.pi/agent/extensions/subagents/index.ts, execute() returns getFinalText(details.messages) as the tool content
  • home/.pi/agent/extensions/subagents/tests/process.test.ts, new regression test

Observed incorrect behavior before the fix:

Given a final assistant message with content parts:

[
  { type: "text", text: "draft answer" },
  { type: "toolCall", name: "read", arguments: { path: "README.md" } },
  { type: "text", text: "final answer after tool" },
]

getFinalText() returned "draft answer" because it iterated message.content from the beginning.

Why this is a real defect:

  • The function comment explicitly says it returns the last non-empty assistant text block.
  • spawn_agent uses this value as the child result returned to the parent.
  • Multi-part assistant content with text/tool/text ordering is a normal event shape for tool-using agents.

Reproduce

Setup:

cd home/.pi/agent/extensions
npm install

Triggering condition:

A child assistant message contains multiple non-empty text parts in the same final message_end.

Exact command:

node --test subagents/tests/process.test.ts

Actual result before the fix:

AssertionError: Expected values to be strictly equal:
+ actual - expected

+ 'draft answer'
- 'final answer after tool'

Expected result:

getFinalText() returns "final answer after tool".

Root cause

getFinalText() searched messages from newest to oldest, but searched each assistant message's content parts from oldest to newest. For the newest assistant message, that selected the first non-empty text part instead of the last one.

Fix

Iterate the final assistant message's content array in reverse order, returning the newest non-empty text part.

Validation

Commands run:

  • Not run locally in this automation environment; the environment could not execute repository commands.

Regression test added:

  • getFinalText returns the last text part within the final assistant message

Scope

This PR only changes final text selection for subagent output and adds focused regression coverage. It does not change subprocess spawning, JSON event parsing, tool-call accounting, rendering, or agent discovery.

@ALX99
ALX99 merged commit 8ed1787 into master Jul 6, 2026
4 checks passed
@ALX99
ALX99 deleted the bug/prevent-spawn-agent-stale-final-text branch July 6, 2026 13:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant