Skip to content

bug(agents): session messages, /tree holds and pre-run prompts still escape the prompt-lifecycle delivery after #1631 #1638

Description

@BGamboa13

Before submitting

  • I searched open and closed issues and did not find a report of this problem.
  • I reviewed this report and removed credentials, tokens, private paths, hostnames, and other sensitive data.

Problem

#1631 moved child output onto an idle/run/hold delivery router so an idle parent is woken through prompt() and before_agent_start (#1528). Three delivery paths in extensions/gentle-agents.ts are still outside that guarantee on main (2549f17a):

  1. Incoming session messages still start a direct turn. The orchestrator_send_message receiver (gentle-agents.ts:501) still calls pi.sendMessage(message, { deliverAs: "followUp", triggerTurn: true }).
  2. Held content is never released after /tree. Content held for a parent that is busy without a run is released only by agent/turn boundaries and session_compact(_failed). /tree branch summarization also makes the host busy without a run, but session_tree is not handled, and a cancelled or aborted summarization emits no event at all. Held child output, child messages and session messages then wait for an unrelated user prompt. The fix(agents): preserve prompt lifecycle for idle child delivery #1631 task notes list "missing compact event can delay held content until next boundary" as a known limitation.
  3. A wake can race the user's own prompt. A user prompt is in its pre-run phase from input until before_agent_start (input handlers, auth, model checks) while ctx.isIdle() still reads true. Child content arriving in that window dispatches an idle wake. The wake prompt and the user's prompt both reach Agent.prompt(), and the user's session.prompt() rejects with Agent is already processing, so the human's message is lost. The fix(agents): preserve prompt lifecycle for idle child delivery #1631 notes call this a residual pre-run race.

Steps to reproduce

Each case is reproduced on the real Pi host (createAgentSession, SessionManager.inMemory, the pi-ai faux provider, the real Gentle Agents factory). A probe extension appends a marker to the system prompt in before_agent_start, and every provider request is checked for it.

  1. Idle parent, incoming session message: the woken provider request lacks the before_agent_start marker.
  2. Manual session.compact() with the summary response held; deliver a session message during compaction: a provider request for the message is issued before compaction ends.
  3. session.navigateTree(target, { summarize: true }) with the summary held; settle a child completion; complete (or abortBranchSummary()) the summarization: no turn ever delivers the completion.
  4. Park a user session.prompt() inside a probe input handler; settle a child completion; release: session.prompt() rejects with Agent is already processing. Specify streamingBehavior ('steer' or 'followUp') to queue the message.

Expected and actual behavior

Expected: every model-visible message Gentle Agents hands to the parent starts its turn through the prompt lifecycle in every host state, and held content reaches the parent without waiting for an unrelated user prompt.

Actual: the three paths above, as described.

gentle-pi version

Unreleased main at 2549f17a (includes #1631).

Pi version

0.99.2

Operating system

Linux

Relevant logs or error output (optional)

Error: Agent is already processing. Specify streamingBehavior ('steer' or 'followUp') to queue the message.

Related: #1528 (closed by #1631), #1518 (receiver-side admission for session messages), #1092 / #1574.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions