Pi harness support: what to improve
Most core capabilities are already integrated. The best opportunities are reliable cancellation, visible extension and project state, terminal-session import, and structured planning. Keep the existing RPC adapter; these additions do not require migrating the whole harness to the SDK.
| Capability | Pi | Codex | Claude |
|---|---|---|---|
| Text and reasoning streaming | Yes | Yes | Yes |
| Active steering | Yes | Yes | Yes |
| MCP tools | Yes | Yes | Yes |
| Live tool-output streaming | Yes | Yes | Results only |
| Import terminal sessions | Missing | Yes | Yes |
| Structured plans and todos | Missing | Yes | Yes |
| Read live provider snapshot | Text only | Yes | Not exposed |
| Native child wait / fork | Not exposed | Yes | Not exposed |
| Approval enforcement | T3 extension | Native | Native |
Matrix reflects the adapters in this checkout, not an exhaustive ranking of the harnesses. Pi: packages/provider-pi/src/server/adapter.ts:90. Codex: apps/server/src/orchestration-v2/Adapters/CodexAdapterV2.ts:236. Claude: apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.ts:363. Import sources: packages/contracts/src/agentSessions.ts:5. “Native” describes policy enforcement, not a universal OS sandbox guarantee. Native child controls exclude T3-owned delegation, which Pi can already access through MCP.
What already works
Pi already has text/reasoning streaming, live tool output, image prompts, model switching, model-specific thinking levels, active steering, T3 queued messages, compaction and retry progress, rollback, forks, provider handoffs, usage/cost ingestion, skill and slash-command discovery, MCP tools, extension dialogs, and observations of the supported subagent extension result shape. These are not missing features.
Some support is stronger than our Claude adapter: Pi exposes live tool-output streaming and a readable active-branch snapshot. The snapshot is text-only, so that advantage does not imply full transcript fidelity.
Priorities
1. Make Stop account for Pi’s native queues
First correctness investigation; likely a small adapter fix if reproduced. Our ordinary Stop sends abort, while upstream documents clear_queue before abort for Escape-style cancellation because queued messages can continue. Pi extensions can also enqueue work, so the issue is broader than the composer’s queue.
Reproduce with a pending native steer/follow-up. Define whether Stop cancels only the current work or all provider-pending work, then reconcile cleared messages with T3’s durable queue. Keep T3 as that queue’s owner. Current Pi also aborts compaction in its generic abort method; reassess our process-kill fallback for modern versions without removing compatibility for older supported versions.
T3 source: packages/provider-pi/src/server/adapter.ts:2623; no clear_queue call in this package.
Primary evidence: Queue cancellation contract, AgentSession.abort implementation. This is a source-level candidate, not a confirmed product bug.
2. Show extension status and startup problems
Directly available RPC events; medium scope across server and clients. We support select, confirm, input, and editor, but explicitly discard setStatus, setWidget, setTitle, and set_editor_text. Notifications with no active turn are also dropped. That hides useful extension progress and can conceal MCP connection warnings at startup.
Start with persistent keyed status and important session-scoped notifications. Add text widgets with update/clear semantics, bounded size, and no terminal escape sequences. Composer prefills need draft ownership rules across devices; terminal titles should not overwrite user-owned thread names. The upstream plan-mode example already emits its todo list as a text widget, so widget support helps existing extensions immediately.
T3 source: packages/provider-pi/src/server/adapter.ts:1216.
Primary evidence: Portable extension UI protocol, Plan-mode example. Custom terminal components are not portable RPC UI.
3. Make project trust understandable
Startup integration gap; investigate before designing the flow. Pi can skip project settings, extensions, skills, and MCP configuration when trust has not been established. T3 accepts --approve and --no-approve in launch arguments, but does not provide a trust-specific bridge or explain which resources were skipped.
Expose the current decision and skipped resources. A new trust decision must happen before protected resources load. Initial RPC startup has no interactive trust UI, so simply adding a normal ctx.ui.confirm() handler is insufficient. Use a deliberate pre-spawn or bootstrap path and preserve explicit decline. Do not silently add --approve everywhere.
T3 source: packages/provider-pi/src/server/mcpInjection.ts:64; generated extension has no project_trust handler; discovery drains ordinary events in status.ts:135.
Primary evidence: Trust rules, Noninteractive trust context, Startup ordering. User-visible impact remains a source-based inference until reproduced in an isolated project.
4. Import terminal Pi sessions through our existing importer
Confirmed Codex/Claude parity gap; medium scope. Both the contract and scanner only accept claudeAgent and codex. Existing Pi sessions cannot appear in that discovery/import flow, although the adapter already knows how to resume an identified Pi session.
Add Pi to the same scanner/importer, respecting environment-local session locations and multi-instance identity. Pi JSONL is a tree: project only the active branch into the thread and retain the native file for continuation. Existing usage parsing already knows Pi’s session directories, so reuse that directory-resolution knowledge.
Separately, improve snapshot fidelity: readThreadSnapshot keeps only user/assistant text and returns attachments: []. Image-only messages disappear from that snapshot. This is relevant to handoffs and reconstruction, even though image input during live turns already works. Full raw-tree export and active-branch HTML export are distinct optional additions, not prerequisites for import.
T3 source: packages/contracts/src/agentSessions.ts:5; apps/server/src/project/AgentSessionScanner.ts:1084; packages/provider-pi/src/server/adapter.ts:2745; usage.ts:124.
Primary evidence: Pi session format, Session RPC commands.
5. Preserve nested tool relationships
Small, concrete adapter opportunity. Pi emits parentToolCallId for tools invoked inside another tool, including code-mode workflows. We ignore it: every item gets parentItemId: null, and tool nodes attach directly to the turn root.
Map the parent ID into existing execution-node and turn-item relationships. This makes a code-mode script and the tools it invoked understandable as one operation. Validate live progress, parent/child failures, and cancellation through the adapter contract; do not infer hierarchy by parsing the tool-call ID string.
T3 source: packages/provider-pi/src/server/adapter.ts:727, :753, :976.
Primary evidence: Nested calls through ctx.executeTool, Tool execution event protocol.
6. Bridge structured plans and todos
Confirmed parity gap; a new extension contract, not a missing core RPC switch. Codex and Claude emit structured plans, todos, and proposed plans. Pi advertises none of these, and its snapshot hides the interaction-mode toggle. Pi offers plan-mode/todo example extensions, not a universal native plan lifecycle.
Text widgets are the low-cost first improvement. For full parity, add a small explicit T3 extension/tool protocol that emits existing plan and todo artifacts, including stable IDs and completion state. Keep read-only planning behavior and proposed-plan approval distinct from merely displaying a todo list. Avoid parsing arbitrary widget text into a supposedly authoritative plan.
T3 source: packages/provider-pi/src/server/adapter.ts:143; packages/provider-pi/src/server/status.ts:53; existing artifact schemas in packages/contracts/src/orchestrationV2.ts.
Primary evidence: Upstream extension approach, Pi design and extension scope.
7. Diagnose authentication by the selected underlying provider
Small diagnostic improvement first; interactive login is a larger follow-up. T3 treats any discovered model as evidence that Pi is authenticated. This does not explain why a particular Anthropic/OpenAI/custom-provider selection fails, and local or virtual models complicate a global authenticated flag.
Use structured per-provider readiness checks where supported, such as pi auth check --provider <id> --json --no-refresh. Report readiness separately from a successful model request. Pi’s SDK exposes provider login/logout interaction, but the normal RPC command set does not. A proper in-app sign-in flow needs a deliberate SDK or extension bridge; sending TUI /login as a prompt is not that bridge. Native MCP OAuth is a separate, already available capability.
T3 source: packages/provider-pi/src/server/status.ts:176, :445; driver.ts exposes no provider auth controller.
Primary evidence: Credential check command, ModelRuntime auth APIs, RPC command surface. No credential checks were executed.
Use what Pi already provides
- MCP, code mode, and tool search already ship in current Pi. Native user/project MCP servers can coexist with our injected T3 bridge. The bridge already registers tools, supports deferred discovery, preserves structured/image output, and enforces T3 permissions. MCP reference; Code mode.
- Keep the bridge’s credential owner. Pi file configuration can override native MCP registrations. Replacing our HTTP bridge with
registerMcpServer()blindly would lose an existing credential/namespace invariant. Resource bridging and changed-list subscriptions are optional gaps to pursue only for a concrete use case. T3 evidence:mcpExtensionSource.ts:348. - Custom models and routers are already usable. Pi supports
models.json, custom-provider extensions, and virtual models. T3 discovers the model catalog and supports model-specific thinking levels. More settings UI may help, but this does not require building another router. Models; Virtual models. - Do not promise universal native subagents. Our adapter observes one extension’s results and T3 delegation already works through MCP. Codex-style native child IDs, wait/close, and child forks require an actual extension lifecycle contract. Claude’s current adapter also lacks those native controls.
- Preserve helper isolation. Background naming/content helpers intentionally disable extensions and tools. Extension-only models and routers therefore need a safe eligibility/fallback design if offered for helpers. Simply enabling all extensions would change the intended isolation. T3 evidence:
packages/provider-pi/src/server/textGeneration.ts:43.
Where I would start
Reproduce queued-input Stop and untrusted-project startup first. Then ship session-scoped notices/status, nested tool relationships, and Pi session import. Add structured plans/todos after choosing one small extension contract. Per-provider auth diagnostics can follow independently. A broad SDK rewrite, a new routing engine, and a generic Pi extension marketplace would add scope without closing the clearest gaps.
Coverage and limits
The server adapter and shared contracts own most of this work. Status/widgets, composer prefills, trust decisions, and import entry points must reach web, desktop, and mobile through the existing shared client runtime. Native file paths and credentials remain in the destination environment for local, relay, and tunnel connections. Queue state, widget clearing, reconnects, runtime replacement, and multi-device draft ownership need explicit behavior.
This audit read source and existing tests. It did not run Pi, billable model turns, browser tests, credential checks, or live settings changes. Candidate cancellation and trust defects require focused reproduction before being called bugs. No repository files changed.
T3 currently accepts Pi 0.80.5+; the upstream feature review uses released 1.4.0. Gate newer commands/events or make a deliberate minimum-version decision. Current upstream main 4b535d57ea88 has unreleased fixes that are not automatically present in npm 1.4.0.