cd /news/developer-tools/pi-btw-side-chat · home topics developer-tools article
[ARTICLE · art-85810] src=perrotta.dev ↗ pub= topic=developer-tools verified=true sentiment=· neutral

pi: /btw side-chat

Developer Thiago Perrotta implemented a '/btw' side-chat extension for the pi coding agent, allowing tangential questions to be answered without polluting the main agent thread. The extension reads a frozen snapshot of the main conversation, calls the model directly in a custom UI overlay, and never appends to the session, preserving the main thread's state. Perrotta reimplemented the feature against the current API of earendil-works/pi, cross-checking with the bundled summarize.ts example, and added it to his dotfiles repository.

read1 min views2 publishedJul 22, 2026

Previously.

Problem statement: mid-task, I want to ask the LLM agent a quick tangential question — “will this change cause downtime?” — without polluting the main agent thread.

Claude Code has /btw

1 for exactly this.

The upstream extension imports the pre-fork @mariozechner/*

package names, which are now deprecated. As such, I use earendil-works/pi. Rather than trust a diff I hadn’t read, I reimplemented it against the current API, and cross-checked against the bundled examples/extensions/summarize.ts

(the canonical example for calling the model from an extension):

import { complete } from "@earendil-works/pi-ai/compat";
import type { ExtensionAPI, SessionEntry } from "@earendil-works/pi-coding-agent";
import { convertToLlm, getMarkdownTheme } from "@earendil-works/pi-coding-agent";

// ...inside the /btw command handler, once at entry:
const branch = ctx.sessionManager.getBranch();
const mainMessages = branch
  .filter((entry): entry is SessionEntry & { type: "message" } => entry.type === "message")
  .map((entry) => entry.message);
const mainLlmMessages = convertToLlm(mainMessages);   // frozen snapshot
const systemPrompt = ctx.getSystemPrompt();

// ...per question, the side-chat calls the model directly:
const response = await complete(
  ctx.model!,
  { systemPrompt, messages: [...mainLlmMessages, ...btwLlmMessages] },
  { apiKey: auth.apiKey, headers: auth.headers, env: auth.env, signal },
);

The key move is what’s missing: the handler never calls pi.sendMessage()

or appends anything. It reads the branch once, talks to the model in an ctx.ui.custom() overlay, and returns. The main session is untouched, so the next real prompt doesn’t pay for any of it.

Added to ~/.pi/agent/extensions/btw.ts.

🤖 *Drafted with *

/bloggify

.— § —

Reply via [email](mailto:serendipity@perrotta.dev?subject=Reply to: pi: /btw side-chat)

── more in #developer-tools 4 stories · sorted by recency
── more on @thiago perrotta 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/pi-btw-side-chat] indexed:0 read:1min 2026-07-22 ·