Pi Session Branch Summary Localization Design and Extension Implementation
1. What This Article Covers
An analysis of why Pi Coding Agent generates English summaries when switching conversation tree branches (via /tree backtracking), and the design and implementation of a global Chinese summary replacement based on the official session_before_tree extension lifecycle event.
2. Background and Observed Behavior
In Chinese-language technical research and documentation sessions, when the user switches and backtracks a conversation branch with /tree, Pi inserts a <summary> node into the conversation history as a compressed-context memory.
Even though the entire conversation is in Chinese, the auto-generated summary is still forced into an English structure with English headings:
<summary>
The user explored a different conversation branch before returning here.
Summary of that exploration:
## Goal
[What was the user trying to accomplish in this branch?]
## Constraints & Preferences
- [Any constraints, preferences, or requirements mentioned]
...
While logically accurate, the native English summary creates a reading barrier in a Chinese context. A fully Chinese structured prompt aims to provide a zero-friction reading experience and preserve information-retrieval efficiency during technical retrospectives.
3. Source-Code Probing
Pi is a fully open-source project (official repo: earendil-works/pi). Reviewing its core source reveals the underlying mechanism of branch-summary generation:
3.1 Hard-Coded Default Prompt
In the core module packages/coding-agent/src/core/compaction/branch-summarization.ts:258, Pi defines a constant template BRANCH_SUMMARY_PROMPT:
const BRANCH_SUMMARY_PROMPT = `Create a structured summary of this conversation branch for context when returning later.
Use this EXACT format:
## Goal
[What was the user trying to accomplish in this branch?]
## Constraints & Preferences
- [Any constraints, preferences, or requirements mentioned]
- [Or "(none)" if none were mentioned]
## Progress
### Done
- [x] [Completed tasks/changes]
### In Progress
- [ ] [Work that was started but not finished]
### Blocked
- [Issues preventing progress, if any]
## Key Decisions
- **[Decision]**: [Brief rationale]
## Next Steps
1. [What should happen next to continue this work]
Keep each section concise. Preserve exact file paths, function names, and error messages.`;
Regardless of the system locale or the user’s interaction language, the system always assembles its prompt from this English template before sending it to the summary model.
3.2 Official Extension Hook and Event Sequence
After the branch switch is confirmed and before the summary-model call is dispatched, the Pi core broadcasts a lifecycle event to the extension layer via its event bus. The overall collaboration sequence is:
4. Design Choices
Three technical approaches were considered for the localization requirement:
| Approach | Mechanism | Pros | Cons | Verdict |
|---|---|---|---|---|
| A. Source patch | Patch the globally-installed npm package directly | Most thorough; no plugin-system dependency | Modifies core source; breaks on host upgrade | ❌ Rejected |
| B. Extension-provided summary | Extension intercepts and calls an external model to summarize | Maximum flexibility | Adds extra model-config burden; bypasses built-in token budget and streaming control | ❌ Rejected |
| C. Full instruction replacement (this approach) | Use session_before_tree to inject replaceInstructions: true, making the core fully override the built-in English template with a Chinese prompt | Reuses all of Pi core’s retry, budget-truncation, and authenticated-model-call capabilities; relies only on the public event contract, so host upgrades are unlikely to break it | Only works on Pi versions that support the relevant event | ✅ Adopted |
5. Core Contract and Engineering Delivery
5.1 Minimal Extension Contract
Under approach C, the extension’s responsibility is strictly limited to intercepting and replacing the instructions when the event fires — it never touches the underlying model inference or network communication.
The core contract only needs to return a control tuple at the session_before_tree stage:
pi.on("session_before_tree", async () => {
return {
replaceInstructions: true, // required: declare full override of the default English template
customInstructions: CHINESE_BRANCH_SUMMARY_PROMPT // inject the equivalent Chinese template
};
});
5.2 Prompt Structure Design
The Chinese prompt uses a 1:1 isomorphic translation of Pi’s native template to preserve the logical density and reading experience of the summary.
Design requirements:
- Same skeleton: retain the five sections —
## 目标(Goal),## 约束与偏好(Constraints & Preferences),## 进展(Progress),## 关键决策(Key Decisions),## 下一步(Next Steps); - Consistent hierarchy: keep the second-level heading structure, leveraging Markdown’s collapsible behavior to improve readability.
5.3 Implementation
The full implementation is available in the open-source repository:
6. Architectural Takeaway: Replace the Instructions, Not the Engine
The pattern distilled from this approach — “Instruction Replacement over Engine Takeover” — has lasting reusable value:
- Minimal invasiveness: when the host (harness) already has a mature budget manager, retry logic, and network pipeline, extensions should first look for a “prompt/parameter replacement point” rather than a “logic replacement point”;
- Forward compatibility: extensions should depend only on the host’s public events and parameter contracts, never touching its internal implementation. As long as the contract remains stable, internal refactors and version upgrades in the host should not require changes in the extension;
Comments