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

已关闭 适合新手
#15,221 1 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

维护者通常 1 天内回复

@StiensWout 已经在做这个了。

开始于 2026年10月12日。

  • #15444 来自 @pedrozimmermannsoares —— 已关闭,未合并
  • #18639 来自 @StiensWout —— 未关闭

评估

难度
2/5
预计耗时
1-3 小时
新手友好度
84/100
Issue 类型
缺陷
描述清晰度
描述清楚
活跃度
活跃
技术栈
typescript
领域
api, backend

调研方向

从 apps/server/src/orchestration-v2/Adapters/PiAdapterV2.ts 中第 2358-2362 行附近的回合开始提示开始,并将其与第 2444 行附近的 steer 路径及其 streamingBehavior 注释进行比较。确保回合开始请求能够处理正在运行的 Pi,然后验证受影响的 thread 是否能在扩展驱动的工作进行期间成功启动。

由索引模型根据 Issue 内容生成。

描述

bug via-triage

Area: apps/server

Steps to reproduce

  1. Install pi ≥ 1.0.0 (observed on 1.0.0 and 1.0.1; npm i -g @earendil-works/pi-coding-agent or bun global) and enable the Pi provider.
  2. Have a pi session whose extension state triggers a run on resume — e.g. a pi-loop extension iteration waiting on a monitor event, or any pending extension continuation. (Observed: session last ended mid-run, so the resumed session re-fires work immediately after switch_session.)
  3. Open a T3 thread bound to that session and send a message.

T3's turn-start prompt races the extension-driven run:

→ {"type":"switch_session","sessionPath":"…/session.jsonl","id":"t3-0"}
→ {"type":"get_commands","id":"t3-1"}
→ {"type":"get_state","id":"t3-2"}
→ {"type":"get_available_models","id":"t3-3"}
→ {"type":"get_entries","id":"t3-4"}
→ {"type":"set_model",…,"id":"t3-5"}
→ {"type":"set_session_name",…,"id":"t3-6"}
→ {"type":"prompt","message":"Context handoff (delta_since_target_last_seen):…"}
← {"type":"response","command":"prompt","success":false,"error":"Agent is already processing. Specify streamingBehavior ('steer' or 'followUp') to queue the message."}

Expected behavior

The turn starts. Since pi 1.0.x, AgentSession.prompt() rejects a bare prompt while a run is active — agent-session.ts:1965-1970 at tag v1.0.1:

// If streaming, queue via steer() or followUp() based on option
if (this.isStreaming) {
	if (!options?.streamingBehavior) {
		throw new Error(
			"Agent is already processing. Specify streamingBehavior ('steer' or 'followUp') to queue the message.",
		);
	}

So the turn-start prompt must either pass streamingBehavior (pi's steer semantics queue it atomically during an active run) or T3 should check get_state and abort the active run before prompting.

Actual behavior

The prompt is rejected and the user sees:

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

The turn never starts; the session is left in an error state. Every retry while an extension-driven run is in flight bounces the same way, so the thread is effectively unusable.

Impact

Blocks work completely (for the affected thread). Workaround exists but is costly — see below.

Version or commit

0.0.46-nightly.20261003.2632 (f391794a35c6). Defect present at current main (ce90eec1): turn-start sends a bare prompt at apps/server/src/orchestration-v2/Adapters/PiAdapterV2.ts:2358-2362 while the steer path (line 2444) already passes streamingBehavior: "steer" — its own comment (line 2421) documents pi's queue-or-run semantics:

Prompt with streamingBehavior steer is atomic on Pi's side: it queues during an active run and starts a new run if settlement won the race.

Environment

macOS 27.0.1 (arm64), T3 Code desktop (Nightly), pi @earendil-works/pi-coding-agent 1.0.1 (bun global install; behavior identical on 1.0.0), Node v26.9.0.

Related

#13507 / #13839 cover extension-driven session rewinds and their ref/rollback reconciliation — a different mechanism. This report is about the prompt contract itself: pi 1.0.x made bare prompt throw while a run is active, and T3's turn-start path (tested against pi 0.8x, cf. #13839's verification against pi 0.87.1) hasn't caught up. Both are part of the same theme: extensions drive pi sessions in ways the adapter's request paths don't fully anticipate.

Logs or stack traces

ProviderAdapterEventStreamError: Failed while streaming pi provider session provider-session:provider-instance:pi:thread:…:… events.
  at orchestrationV2.providerTurnStart.start (apps/server/dist/binCli-D9mHsJrM.mjs:228797)
  [cause]: Error: Cause([Fail(PiRpcError: Pi RPC read failed: pi process exited with code 0.)])

RPC capture (tee on pi stdin/stdout) of the rejected exchange and the extension-driven runs that follow — full transcript available on request. Redacted: session paths truncated; no secrets in the capture.

Workaround

Setting the Pi provider's Launch arguments to --no-extensions stops extension-discovery extensions (pi-lens, pi-loop, …) from loading in T3 sessions — T3's own --extension still loads — which removes the busy-at-load races. Cost: pi-lens features are unavailable in T3 sessions. Alternatively wait for extension-driven runs to settle before prompting.

Minor side note

A bare 1.0.1 (version string) line appears on pi's stdout in RPC mode — most likely pi's own version/update-check output landing on the protocol channel. T3 drops non-JSON lines so it's harmless, but raw prints on the RPC channel would be worth avoiding.

主要语言
TypeScript
星标
24.8k
派生
6.4k
平均合并
13 小时 48 分钟
30 天内合并 PR
208

环境准备

在 Codespaces 中打开

在浏览器里用你自己的 GitHub 账号启动这个项目的开发容器。

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

pingdotgg/t3code 的其他 Issue

查看 pingdotgg/t3code 的全部 Issue

相似的 Issue

更多 TypeScript Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。