omp packages

pi-t3-bridge0.4.1

Pi extension adapter for t3-pstack inside T3 Code.

klods Published 4 hours ago MIT ~480 downloads/mo

Untested on omp

This is a pi package. No one has reported whether it works on omp yet. If you try it, add your result below.

Did it work for you?

Result

One report per person. A new report replaces your old one.

Reports 0

No reports yet.

Readme

pi-t3-bridge

pi-t3-bridge is a Pi package that lets Pi work as an agent inside T3 Code. It also ships pstack, Lauren Tan's set of agent workflows, so a Pi thread in T3 can delegate subagents and run review panels that mix Claude, GPT, and other model families.

flowchart LR
    User((You)) --> T3[T3 Code app]
    T3 -->|runs a thread| Pi[Pi agent]
    subgraph pkg [pi-t3-bridge]
        Bridge[bridge.ts<br/>T3 tools, cards, limits]
        Pstack[pstack.ts<br/>skills and model routing]
    end
    Pi --> Bridge
    Pi --> Pstack
    Bridge -->|MCP| T3
    Pstack -->|delegate_task| T3
    T3 -->|child threads| Children[Claude, GPT, and other models]

Requirements

You need the following programs:

  • Node.js 22.19.0 or later
  • Pi 1.4.0 or later
  • T3 Code, if you want to run Pi threads inside T3 or call T3 tools from Pi

Delegated children run their shell commands in a sandbox: sandbox-exec on macOS, and bwrap (bubblewrap) on Linux and WSL2. Linux needs the bubblewrap package and unprivileged user namespaces. On Ubuntu, the bubblewrap package ships an AppArmor profile that lets bwrap run (checked on 26.04). If AppArmor still blocks it, run sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0. Native Windows and WSL1 have no sandbox. Where no sandbox can run, a child's shell commands are blocked unless childSandbox is "off" in the config.

The tests need Docker, because they also run the child tests in Linux containers.

Install

Install the package with Pi:

pi install npm:pi-t3-bridge

Pi loads both extensions in the package on the next start. To try the package for one session without saving it to your settings, run pi -e npm:pi-t3-bridge.

What is in the package

The package has two Pi extensions, and you can turn off either one. The bridge in bridge.ts imports only src/bridge and npm packages, so it works on its own when the pstack extension is off.

pi-t3-bridge/
├── bridge.ts         # extension 1: connects Pi to T3 Code
├── pstack.ts         # extension 2: adds pstack skills and model routing
├── src/
│   ├── bridge/       # code for bridge.ts
│   └── pstack/       # code for pstack.ts
└── pstack/           # upstream pstack skills, agents, and model defaults
    ├── skills/
    ├── agents/
    └── models.json

To load only the bridge, list the package in ~/.pi/agent/settings.json in its object form:

{
  "packages": [
    {
      "source": "npm:pi-t3-bridge",
      "extensions": ["bridge.ts"]
    }
  ]
}

The bridge extension

The bridge gives Pi the tools and commands that T3 Code expects, and it shows them as cards in the T3 chat. When another installed package already registers a tool with the same name, for example ask from pi-ask, the bridge keeps the other package's tool and tells you once that its own copy is off.

Name Kind What it does
tasks tool Publishes the task list for the run as a card in the chat.
plan tool Shows a plan card with Approve, Revise, and Cancel buttons.
ask tool Asks you one or more questions as cards and waits for your answers.
transcript tool Returns the session file and session ID, for workflows that read the transcript.
/t3-usage command Shows the cost of the thread and its children, the cache hit rate, and which model families are out of usage.
/t3-transcript command Records the transcript reference and shows the session file path.
/t3-exhausted <family> [reset time] command Marks a model family as out of usage for every chat on the machine.
/t3-recovered <family> command Marks a model family as usable again for every chat on the machine.

Plan mode

When T3 is in Plan mode, or when a plan is waiting for your answer, the bridge blocks every tool that can change files. Only read-only tools run until you approve a plan.

stateDiagram-v2
    [*] --> open
    open --> planning: T3 enters Plan mode
    planning --> awaiting: agent calls plan
    awaiting --> approved: you pick Approve
    awaiting --> revising: you pick Revise
    awaiting --> cancelled: you pick Cancel
    revising --> awaiting: agent calls plan again
    cancelled --> open: you send a new message
    approved --> [*]: write tools run again

Calls to T3 from outside T3

When you run Pi in a terminal instead of inside a T3 thread, the bridge adds T3's MCP server, which is the endpoint that T3 Code serves its tools on. You can then launch threads, send messages to them, and wait on them from Pi. The status bar shows the connection state.

on(session start)
  if Pi runs inside a T3 thread
    use the tools T3 already gives the thread
  else
    connect to http://127.0.0.1:3773/mcp
    hide the tools that only work inside a T3 thread
    every 3 seconds, update the status bar
      "connected, N tools"
      "offline, start T3 Code"
      "not signed in, run /mcp login t3"

Usage limits and resume

The bridge keeps track of which model families are out of usage, and it shares that record with every Pi session on the machine. When a child fails with a usage limit, the bridge marks the family as out until the reset time, and pstack routes new work to another family. The account of the main thread can also run out, and then the agent can't call any tool. The bridge handles the case by asking T3 to post a resume message into the thread just after the reset.

sequenceDiagram
    participant Parent as Parent thread
    participant Bridge
    participant T3
    participant Child as Child thread
    Parent->>T3: delegate_task (Claude)
    T3->>Child: start
    Child-->>T3: usage limit reached
    T3-->>Bridge: task failed
    Bridge->>Bridge: mark claude as out until the reset
    Parent->>T3: delegate_task (next family)

Shell timeout

The bridge caps every shell command at 300 seconds, in the main thread and in children. A command that sets no timeout gets the 300 second cap, so a hung test suite stops the chat for minutes instead of forever. Set bashTimeoutSeconds in the config to change the cap.

Stop checks

When a run is about to stop, the bridge asks a classifier how the run ended. The classifier is typesafe/jev-latest from your Pi model catalog. When the classifier says the agent gave up partway, the bridge adds a note and gives the agent one more turn, at most twice per prompt. Every 3 turns during a run, the bridge also asks the classifier whether the agent shows a known failure, and it adds a note when one is likely. The failures it checks for come from the MAST list of agent failures:

  • Stuck in a loop
  • Doesn't know when to stop
  • Wandered off
  • Broke the brief, and says one thing but does another
on(run about to stop)
  ask the classifier how the run ended
  if the classifier is down or takes more than 5 seconds
    let the run stop
  if the agent gave up partway and fewer than 2 notes were sent for this prompt
    add a note
    continue for one more turn

The stop check and the notes come from pi-mast-steer. Set steer to "shadow" in the config to log verdicts without changing the session, or to "off" to turn the checks off.

The pstack extension

The pstack extension adds the pstack skills to Pi's skill catalog, and it adds a note to each prompt that tells the agent when to enter poteto-mode. poteto-mode picks the workflow that fits your goal, for example a bug fix, a feature, a design review, or a PR watch. The skills come from pstack by way of t3-pstack, and they live unchanged under pstack/.

Model routing

The pstack_model tool picks the model for each subagent. The agent passes a role, a job type, and a size, and the tool returns a target to pass to T3's delegate_task.

pstack_model(role, job, size)
  if the model sheet names a model for the role
    use that model
  else
    look up the job and size in the routing table
  if that model's family is out of usage
    use the same tier in the next family
    (GPT takes only size S work)
  return the target for delegate_task

The routing table in pstack/models.json maps each job and size to a default model and reasoning level. Size S is a job of 30 minutes or less that touches 5 files or fewer, and size M is a job of 90 minutes or less that touches 15 files or fewer. The tool refuses size L, so the agent has to split the job.

Job Size S Size M
mechanical, such as a lint fix or rename Haiku 5.5, low Sonnet 5.5, medium
check, which runs given commands GPT 6 Luna, low Haiku 5.5, medium
research, which writes one notes file Muse Spark 1.3, medium Muse Wonder 1.0, medium
implement, one unit with named tests GPT 6.1 Sol, medium Sonnet 5.5, high
hard, such as concurrency or a bug with an unknown cause Opus 5.5, high Opus 5.5, high
review panel Opus 5.5, Muse Wonder Full 1.0, and GPT 6.1 Sol, all high same
design panel Opus 5.5, Muse Wonder Full 1.0, and GPT 6 Astra, all high same

Run the setup-pstack skill to write your own model sheet at ~/.config/pi-t3-bridge/models.md. A line of session hook: off in the sheet stops the per-prompt note about poteto-mode.

Limits for delegated children

When the first message of a session is a complete pstack brief, the extension treats the session as a delegated child and holds it to the brief. The child can't lift the limits through anything it writes.

sequenceDiagram
    participant Parent as Parent thread
    participant T3
    participant Child as Child thread (pi-t3-bridge)
    Parent->>T3: delegate_task with a brief
    T3->>Child: start with the brief
    Note over Child: shell runs in a sandbox limited to the workdir<br/>write and edit limited to the listed files<br/>time and disk limits enforced
    Child->>Child: write report from commands it ran itself
    Child-->>T3: final message
    Child->>Child: append report to the ledger
    Parent->>T3: task_status
    T3-->>Parent: result
    Note over Parent: the extension adds the report from the ledger

Configuration

The bridge reads one JSON file per machine, at ~/.config/pi-t3/config.json. Every key is optional. The bridge reads the file again on each prompt, so an edit applies on the next prompt. When one value is invalid, only the invalid key falls back to its default, and the bridge tells you once.

{
  "bashTimeoutSeconds": 300,
  "childSandbox": "on",
  "mcpUrl": "http://127.0.0.1:3773/mcp",
  "steer": "on"
}
Key Default Meaning
bashTimeoutSeconds 300 The longest a shell command can run, in seconds.
childSandbox "on" Whether a delegated child's shell commands need a sandbox. With "on", a child's bash is blocked when no sandbox can run. With "off", commands run with no sandbox on every platform, and the child's report says SANDBOX: off.
mcpUrl http://127.0.0.1:3773/mcp The T3 MCP endpoint to use outside a T3 thread.
steer "on" The stop checks, as "on", "shadow", or "off".

The package writes its files in the following places. When XDG_CONFIG_HOME or XDG_STATE_HOME is set, those folders replace ~/.config and ~/.local/state.

~/.config/
├── pi-t3/config.json          # bridge settings
└── pi-t3-bridge/models.md     # model sheet, written by setup-pstack
~/.local/state/pi-t3/
├── accounts.json              # model families that are out of usage
├── ledger.jsonl               # one line per delegated brief: cost and report
└── steer.jsonl                # one line per stop check verdict, with no transcript text

Earlier releases kept the state and the model sheet under t3-pstack. The first start after an upgrade moves them to the new folders once.

Data handling

The package has no server and sends no telemetry. The stop checks send parts of the session transcript to the classifier provider in your Pi model catalog, and any file a skill asks the agent to read goes to your model provider. Scripts run on your machine, and the PR tools use your GitHub CLI login.

Development

The repository uses npm, and the following commands check the code:

npm install
npm test           # node:test suites for the bridge and the pstack scripts
npm run typecheck
npm run check      # Ultracite lint and format check

The pstack/ folder is a git subtree of t3-pstack. Merge upstream changes with git merge -X subtree=pstack pstack-upstream, and keep the files under pstack/.

License

The package is under the MIT license. The copyright holders include the following people and companies:

  • Lauren Tan, for the original pstack
  • Cursor, for the imported cursor-team-kit and thermos skills
  • Christian Bager Bach Houmann, for the T3 changes in t3-pstack

See LICENSE and NOTICE.md for the full list.