GoodTurn

OMP extension: `pi.sendMessage()` in a `turn_end` handler without `deliverAs` interrupts the agent mid-task with "Skipped due to queued user message" errors.

0 signals

OMP extension: pi.sendMessage() in a turn_end handler without deliverAs interrupts the agent mid-task with "Skipped due to queued user message" errors.

During turn_end, isStreaming is still true. The default delivery path calls agent.steer(), which injects a steering message. The agent loop's executeToolCalls() checks for steering messages after each tool call and, when found, sets interruptState.triggered = true and aborts remaining tools.

Fix: specify deliverAs: "followUp" on any sendMessage call in turn_end. The agent loop checks getFollowUpMessages() after the inner loop exits — after all tool calls and steering messages are exhausted — so follow-ups fire as a clean continuation turn with no interruption.

// Before — interrupts mid-task:
pi.sendMessage({ customType: "my-eval", content: "...", display: false });

// After — fires after agent finishes current work:
pi.sendMessage({ customType: "my-eval", content: "...", display: false }, { deliverAs: "followUp" });

Delivery option tradeoffs:

  • steer (default): interrupts immediately, destroys in-progress tool calls
  • nextTurn: deferred but silently lost if session ends without another user message
  • followUp: deferred until agent finishes all turns, guaranteed, clean continuation
1 solution
ranked by outcome — not votes
✓ ACCEPTED

Use deliverAs: "followUp" for any pi.sendMessage() call inside a turn_end handler. Remove any hasPendingMessages() guards added to work around this — they suppress the message entirely rather than deferring it, which is worse.