Skip to content

fix(server): Pi turns start while an extension run is streaming - #15444

Open
pedrozimmermannsoares wants to merge 1 commit into
pingdotgg:mainfrom
pedrozimmermannsoares:fix/pi-turn-start-while-streaming
Open

pedrozimmermannsoares wants to merge 1 commit into
pingdotgg:mainfrom
pedrozimmermannsoares:fix/pi-turn-start-while-streaming

Conversation

@pedrozimmermannsoares

Copy link
Copy Markdown

Problem

When a Pi extension continuation is already streaming as a T3 turn starts, Pi rejects the turn-start prompt with "Agent is already processing. Specify streamingBehavior ('steer' or 'followUp') to queue the message." The turn fails, and each retry fails the same way while the extension run continues. Reported and triaged in #15221.

Change

PiAdapterV2 now sends the turn-start prompt with streamingBehavior: "steer", as the steer path already does. Pi's AgentSession.prompt() reads the field only while isStreaming is true (v1.0.1, L1950 and L1965-L1977). An idle session starts a run exactly as before. A streaming session queues the message into the active run instead of throwing.

The Pi replay transcripts compare outbound frames exactly, so their 18 turn-start prompt frames gain "streamingBehavior":"steer". Only frames the adapter writes change. Pi's recorded output stays the same, which matches Pi ignoring the field when idle. The message_steering assertion expected the initial prompt to omit the field and now expects steer.

Scope and approval

Fixes #15221. Maintainer triage confirmed the bug on main and named this option as the one that matches the existing steer path, including the message_steering fixture change.

It does not change how the adapter handles agent work that starts before any T3 turn exists (PI_UNSOLICITED_ACTIVITY_ERROR).

Verification

  • New test starts a turn while an extension run is already streaming in PiAdapterV2.test.ts. The fake answers the prompt as Pi does during a run: with Pi's exact rejection when streamingBehavior is missing. On main the turn ends failed with provider_error "Agent is already processing. Specify streamingBehavior ('steer' or 'followUp') to queue the message.". With the fix it ends completed.
  • vp test run apps/server/src/orchestration-v2/Adapters/PiAdapterV2.test.ts: 50 passed.
  • vp test run apps/server/src/orchestration-v2/testkit/OrchestratorReplayFixtures.integration.test.ts -t "/pi through": 8 passed. On main the same 8 pass. With the adapter change and the old transcripts, all 8 fail.
  • vp test run on OrchestratorReplayFixtures.contract.test.ts, UserFacingErrors.test.ts, and piT3McpInjection.test.ts: 10 passed.
  • A script compared the 18 transcript lines with main. The only difference in each is the added "streamingBehavior":"steer".
  • vp lint on the changed TypeScript files: no new findings. The one warning (layer unused in PiAdapterV2.ts) is already on main. vp run --filter t3 typecheck: exit 0.

Not checked: a live Pi 1.0.x session with a streaming extension. The transcripts were edited, not re-recorded against a live Pi.

The turn-start prompt was sent without streamingBehavior. When a Pi extension continuation was already streaming, Pi rejected it with "Agent is already processing" and the turn failed. Send it with streamingBehavior: "steer", as the steer path already does. Pi ignores the field when idle, so recorded replay frames only gain the field.

Fixes pingdotgg#15221
@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Oct 4, 2026
@macroscopeapp

macroscopeapp Bot commented Oct 4, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 7ef4d99

Macroscope's review found this PR approvable — This is a focused server bug fix that adds Pi’s existing steering mode only to turn-start prompts, allowing prompts to queue during an extension stream while leaving idle behavior unchanged. The accompanying regression test and replay-fixture updates are limited in scope, with no schema, deployment, security, billing, or static-analysis implications.

You can add or adjust custom eligibility rules. Learn more.

@coderabbitai

coderabbitai Bot commented Oct 4, 2026

Copy link
Copy Markdown

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

🧰 Additional context used
📚 Code guidelines (1)
docs/internals/effect-services.md — auto-discovered

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: pingdotgg/t3code/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: a3ac329e-1440-4635-b690-d2e4cd16dca0
📥 Commits

Reviewing files that changed from the base of the PR and between 7379933 and 7ef4d99.

📒 Files selected for processing (11)
  • apps/server/src/orchestration-v2/Adapters/PiAdapterV2.test.ts
  • apps/server/src/orchestration-v2/Adapters/PiAdapterV2.ts
  • apps/server/src/orchestration-v2/testkit/fixtures/message_steering/pi_output.ts
  • apps/server/src/orchestration-v2/testkit/fixtures/message_steering/pi_transcript.ndjson
  • apps/server/src/orchestration-v2/testkit/fixtures/multi_turn/pi_transcript.ndjson
  • apps/server/src/orchestration-v2/testkit/fixtures/pi_compaction/pi_transcript.ndjson
  • apps/server/src/orchestration-v2/testkit/fixtures/provider_thread_resume/pi_transcript.ndjson
  • apps/server/src/orchestration-v2/testkit/fixtures/simple/pi_transcript.ndjson
  • apps/server/src/orchestration-v2/testkit/fixtures/thread_rollback/pi_transcript.ndjson
  • apps/server/src/orchestration-v2/testkit/fixtures/thread_rollback_after_stop/pi_transcript.ndjson
  • apps/server/src/orchestration-v2/testkit/fixtures/turn_interrupt_mid_tool/pi_transcript.ndjson

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 8 remain after this review.


📝 Walkthrough

Walkthrough

The Pi adapter now sends initial prompts with streamingBehavior: "steer". A regression test covers starting a turn during an active extension continuation, and Pi transcript fixtures now expect the steering setting.

Changes

Pi prompt steering

Layer / File(s) Summary
Initial prompt steering and validation
apps/server/src/orchestration-v2/Adapters/PiAdapterV2.ts, apps/server/src/orchestration-v2/Adapters/PiAdapterV2.test.ts, apps/server/src/orchestration-v2/testkit/fixtures/message_steering/*, apps/server/src/orchestration-v2/testkit/fixtures/{multi_turn,pi_compaction,provider_thread_resume,simple,thread_rollback,thread_rollback_after_stop,turn_interrupt_mid_tool}/*
Initial Pi prompts now specify streamingBehavior: "steer". The regression test checks that a turn completes after agent_settled when an extension continuation is already streaming. Transcript and output fixtures expect the steering setting.

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix · Severity of issue fixed: Medium

Suggested reviewers: juliusmarminge

Merge Risk: ⚪ Minimal · up to 7ef4d

Initial prompts can now join active extension work while idle starts retain normal prompt handling. The inspected Pi contract supports this change, so no material merge-readiness risk remains.

Architecture Summary

Architecture risk: 🔵 Low · up to 7ef4d

The change affects 1 system.

Changed systems: apps/server

Architecture concerns
No architecture-level concerns identified.

Review details

Systems and components

  • observed — apps/server (service) was modified; 11 changed files map to changed impact.

Before / after behavior

  • observed — Modified behavior in apps/server/src/orchestration-v2/Adapters/PiAdapterV2.test.ts: Adds a regression test for starting a turn during an already-streaming extension continuation. It simulates Pi’s rejection when the prompt lacks streamingBehavior, or a successful acknowledgement when that field is present, then verifies the settled turn completes.
  • observed — Modified behavior in apps/server/src/orchestration-v2/Adapters/PiAdapterV2.ts: Initial prompts now include streamingBehavior: "steer"; previously they sent a bare prompt. When an extension is already streaming, the initial message therefore uses Pi’s steering behavior instead of the bare-prompt path.
  • observed — Modified behavior in apps/server/src/orchestration-v2/testkit/fixtures/message_steering/pi_output.ts: The expected outbound frame for the initial prompt changes from an unset streamingBehavior to "steer".
  • observed — Modified behavior in apps/server/src/orchestration-v2/testkit/fixtures/message_steering/pi_transcript.ndjson: The initial prompt now includes streamingBehavior: "steer"; previously it sent the same message without specifying streaming behavior.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the Pi turn-start issue and the fix for starting turns while an extension run is streaming.
Description check ✅ Passed The description covers the problem, change, scope and approval context, and focused verification. It also states that live Pi verification was not performed.
Linked Issues check ✅ Passed Issue #15221 requires the turn-start prompt to pass Pi's streamingBehavior option or abort the active run. PiAdapterV2 now sends streamingBehavior: "steer" on turn-start prompts. The added test …
Out of Scope Changes check ✅ Passed The adapter test covers issue #15221. The fixture and transcript edits update expected outbound prompt frames to match the adapter change. The summary identifies no unrelated changes.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 2 functions across 3 files. (8 skipped: 8 …
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

aliceisjustplaying added a commit to aliceisjustplaying/t3code that referenced this pull request Oct 6, 2026
aliceisjustplaying added a commit to aliceisjustplaying/t3code that referenced this pull request Oct 6, 2026
@kushaldotdev

Copy link
Copy Markdown

Heads-up: main has moved a lot since this was opened. Pi now lives in packages/provider-pi (#17302) and the provider packages were reworked (#17542, #17427, #17381, #17375). This PR is currently mergeable: false, so it cannot land as-is.

Would you be able to rebase and push? A push also puts a new head in front of Macroscope, whose approval was recorded against 7ef4d99, so eligibility gets re-evaluated automatically. If the conflicts are awkward, happy to help work them out — this one is still referenced as the remaining blocker for the follow-up-turn failures reported in #15589.

This branch has not been deployed

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

Labels

size:M 30-99 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Pi turn-start prompt lacks streamingBehavior — pi 1.0.x rejects prompts while an agent run is active

2 participants