Skip to content

fix(pi): separate typed final answers from activity text - #547

Open
lidge-jun wants to merge 14 commits into
codex/native-activity-02from
codex/native-activity-pi-finality
Open

fix(pi): separate typed final answers from activity text#547
lidge-jun wants to merge 14 commits into
codex/native-activity-02from
codex/native-activity-pi-finality

Conversation

@lidge-jun

@lidge-jun lidge-jun commented Sep 5, 2026

Copy link
Copy Markdown
Owner

Pi tool turns could include pre-tool commentary in the final answer because the runtime accumulated every assistant message. Select the latest completed typed assistant at the Pi settlement boundary, while retaining accepted text separately for interrupted-turn salvage. Preserve empty/absent finals and failure status, and avoid replaying streamed text from terminal snapshots.

The Pi lifecycle receives the explicit outcome before lease release, retains kill-steer provenance for interrupted MESSAGE storage, and invokes lifecycle delivery once. Upstream Pi 0.80.4+ uses agent_settled; older or unrecognized versions retain the legacy completion boundary without timer guessing.

This branch normally merges published parent 2c3dd0fa5188739aaa3802d272dd857e02fa296f and its test-only follow-up ef1fb23bf125513fd9a595d46cded24c18107689. Source integration commits are 6f27ce332 and 6577fcbae (first-parent diffs); private document pins are separate. Parent behavioral Pi cancellation and gateway/Stop tests are retained. Pi finality/old-version semantics remain unchanged.

Validation:

  • 356 focused checks across 28 explicit files, including all 11 Pi test files and affected Cursor/lifecycle/Stop/gateway tests, run serially with the existing test driver.
  • Independent integration review passed 168 distinct checks; typecheck, strict baseline 103, atomic build, dist assets and 484 structure counts passed.
  • Fresh compiled Pi main probe on the merged production tree returned and stored exactly PI_ACTIVITY_DONE, retaining commentary in partial output. Child exited and runtime pool was empty. The subsequent parent follow-up changes only tests, with production-tree equality verified.
  • New-head CI is tracked in this PR's checks; prior head certifications are historical.

Validation history: the earlier Node run had 9,067 passes, one inherited DOCS-CHECK-001 failure, and 46 skips. Clean base 7335600 reproduced the same API count mismatch. Docs-only f3d1dc5dd changed 256/255 to the extracted 258/257, with unchanged assertions passing 2/2. That repair is already in the parent, not an additional API/route change in this diff.

@coderabbitai

coderabbitai Bot commented Sep 5, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Team

Run ID: 538ee26b-4e37-4bdd-b412-4923c7742ddc

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@lidge-jun
lidge-jun marked this pull request as ready for review September 5, 2026 18:28
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 5, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-05T18:36:32.714582Z 897e3d3 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 897e3d35b2

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/agent/pi-runtime.ts
}

function usesPiSettled(command: PiCommand): boolean {
const result = probePiCommandVersion(command, process.env);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Cache Pi version detection outside the request path

Whenever a Pi runtime is created, usesPiSettled() synchronously launches <pi command> --version with a 15-second timeout; resolvePiCommand() may already have run its own probe immediately beforehand. With the npm-exec fallback or a slow/broken wrapper, each pooled-session creation—and every direct worker turn—can block the server event loop for seconds, delaying unrelated HTTP, SSE, and agent work. Cache the detected capability or perform this probe asynchronously rather than running spawnSync during each spawn.

Useful? React with 👍 / 👎.

Comment on lines +11 to +13
Pi final selection is owned by `src/agent/runtime/pi-turn.ts`, independently of Activity storage. The latest typed assistant message supplies a final only when its `stopReason` is `stop` and its content has no `toolCall`; text blocks preserve null, empty and whitespace distinctly. Earlier assistant commentary and accepted deltas stay in bounded `partialText`, while repeated message/turn/agent snapshots do not duplicate them. Error, abort, length and unknown stop reasons cannot promote an earlier answer. Pi invokes the existing explicit-outcome lifecycle handoff; adapters that omit an outcome retain legacy selection.

Upstream Pi versions from 0.80.4 finish at `agent_settled`, after automatic retry, compaction and queued continuations. Older or unrecognized version strings retain the legacy `agent_end` boundary, except `willRetry:true`; this compatibility path cannot promise session-level settlement. `willRetry` itself predates `agent_settled` and is not a capability flag. Version probing is bounded and writes no shared capability/profile settings. Activity message phases may remain `unknown`; UI and journal replay never select the final.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Synchronize the Pi terminal contract in stream-events

This activates explicit Pi outcome selection and changes the authoritative completion boundary, but structure/stream-events.md still describes Pi callbacks as legacy and says the observer does not affect the existing final/abort lifecycle. Update that companion document with the new partialText/typed-final and agent_settled behavior so consumers do not implement against the obsolete contract.

AGENTS.md reference: structure/AGENTS.md:L33-L33

Useful? React with 👍 / 👎.

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