Repository navigation
Releases
v0.4.1
Added
pots initasks who decides on group messages that do not mention the bot: the bot itself (the default: every such message wakes it), Jev from TypeSafe with your TypeSafe API key, or a judge model you already set up in pi. Pots tries the judge with one message before it makes the bot.--judgegives the answer without the question.
Changed
- A mention or a DM wakes the bot at once. The bot used to wait 3 seconds after the last message of a place, also when someone was waiting for it. Now a mention or a DM wakes it when it comes, with the messages of that place that were waiting; what comes after reaches it while it works there. In our test on Slack, a DM "ping" got its reply in about 10 seconds instead of about 33. Other messages are grouped as before.
What's Changed
- The waker tests wait for real work by wall-clock time by @Crokily in #13
- pots init asks who decides on group messages that do not mention the bot by @Crokily in #15
- A mention or a DM wakes the bot at once by @Crokily in #14
Full Changelog: v0.4.0...v0.4.1
v0.4.0
A bot that works like a coworker: it hands longer work to helpers in the background, remembers by itself as Claude Code does, sees each new message in its wake, and keeps the start of its requests the same, so the provider's prompt cache serves most of them.
Added
- Children: helpers for longer work. With its new
tasktool the bot starts children: agents that work in the background withread,write,edit,bashandscreen, on a brief the bot writes. The bot answers the person first and stays free to talk. A child's final message comes back to the bot once, also across crashes and restarts. The bot chooses each child's thinking level:high,xhighormax. New inbot.json:childModel,childThinking(xhighby default) andsettings.maxChildren(50 by default).pots childrenlists the children and stops them, andpots statusshows how many work. - Automatic memory, as in Claude Code. Each bot has a
memory/folder of markdown files with aMEMORY.mdindex, and the bots of one computer share~/.pots/memory/. The bot sees the indexes at the start of every page and saves what is worth keeping. After each piece of work, a pass in the background, continuing the same conversation, saves what it missed; once a day, after 5 changes, a dream tidies the memory up. Code lets these passes change nothing but the memory files."settings": {"autoMemory": false}inbot.jsonturns the memory off. - The
screentool.screenruns commands asbashdoes, with the screen's environment, and holds the screen for one agent at a time; another agent learns who has it and since when. On Linux, plainbashno longer getsDISPLAY,XAUTHORITYorWAYLAND_DISPLAY. On macOS and Windows the screen does not need those variables, so there only the prompt keeps agents toscreen. A bot that sets up its own desktop writes it intoscreenin itsbot.json. - Wakes carry the messages. Each wake has the text of each new message (and whether it was edited or deleted), the start of its thread, and its files. Pots downloads a message's files when the message comes, up to 10 MB each, into
files/tmp/in the bot's folder, and deletes them there 30 days later. A larger file, or one not saved within 10 seconds, is given by its URL. The message log keeps the URL of every file, so the bot can download it again. pots traceandpots contextshow the prompt cache: how much of the input the provider's cache served, and what the requests that missed it cost.thinkinginbot.jsonalso takesmax. A level the model does not have becomes the nearest one it has, as in pi.
Changed
- The judge is
offby default. A bot whosebot.jsonhas nojudgenow gets every message that does not mention it, and decides itself. It used to bemain. To keep that, set"judge": "main", or use a fast classifier such astypesafe/jev-latest. - The start of each request stays the same. The bot's own prompt sections keep their text for the whole page: a change, such as a new
settingsvalue, shows after the page turns, after pi compacts, or once after an upgrade. The bot's address in each channel is now in the wake, and the bot runssudo -n trueitself to learn whether sudo needs a password. - The messages of one place reach the bot in the order they came, also when an earlier one waits for its files.
Fixed
- A sign-in opens the page with
$BROWSERwhen it is set, on macOS and Windows too. On macOS it is read as xdg-open reads it, a list of commands split by:; on Windows as one program; on Linux xdg-open reads it, as before. The tests set it, so they no longer open real browser tabs on a Mac. pots initends when it is done, also after a browser sign-in. It printed "Start the gateway with pots start" and then did not end for minutes: pi's sign-in server left open a connection the browser had opened ahead of time. Now apotscommand ends when its work is done and its output is written.pots start,pots chatandpots service logs --followrun as before.
What's Changed
- Coworker: wakes carry the message, background children, a screen lease, automatic memory and a stable prefix by @Crokily in #10
- pots opens a sign-in page with $BROWSER when it is set, so the tests open no browser on macOS by @Crokily in #11
- A pots command ends when it is done, also when a sign-in left a connection open by @Crokily in #12
Full Changelog: v0.3.3...v0.4.0
v0.3.3
A bot whose model fails says so in the chat, and the local server step of pots init writes where pi reads.
Fixed
- The local server step of
pots initwrites where pi reads. It wrote to~/.pi/agent/models.jsoneven whenPI_CODING_AGENT_DIRnames another folder. It now also tries the model, as for a login, and asks whether to try again, for example once the server runs. It used to make a bot even when the server was not running. pots statusandpots chatshow a failed run that was followed right away by the next one. They saw only runs that ended with the bot idle.
Changed
- A bot that cannot use its model says so in the chat. When its model fails, for example because a login expired, the bot says "I could not work on this" in each place that woke it, once until the model works again or the gateway restarts. It used to stay silent. The reason stays on the bot's computer, in
pots statusandpots chat: it can name the model's configuration, and a chat can be shared. - Pots uses pi's model layer, settings and skill loader through pi's public entry, not pi's internal files, so a pi upgrade is less likely to break them. The gateway starts about 0.3 seconds later.
What's Changed
- A bot whose model fails says so in the chat; init's local server step writes where pi reads by @Crokily in #9
Full Changelog: v0.3.2...v0.3.3
v0.3.2
Found by running pots init from npm on a fresh Ubuntu server without a desktop, from the first command to a reply in Slack.
Fixed
- Sign in with ChatGPT works. It stopped with "requires a device ID (UUID)".
pots initnow passes pi's own ID for this installation, as the pi command line does, and keeps it in pi's settings. - A sign-in that finishes in the browser no longer leaves "paste the redirect URL" waiting in the terminal, in the way of the next question.
- The bots keep running after you log out of SSH. Where Linux does not let a user turn on lingering,
pots initnow does it withsudo(without a password), and otherwise says the command to run. pots init --modelchecks that pi can use the model, and tries it, before it makes the bot. It used to make a bot that failed on its first wake when the model had no login or key, did not answer with that login, or its name was wrong.- No SQLite warning in the middle of the first question on Node releases that still call
node:sqliteexperimental, such as 24.13.
Changed
pots inittries the model you choose before it makes the bot. A login does not unlock every model of its provider: a ChatGPT account cannot use every OpenAI model. When the model does not answer, init says why and asks again. After a sign-in, pi's default model for the provider comes first, marked "(recommended)", when it answers with that login.
What's Changed
- pots init on a fresh server: ChatGPT sign-in, withdrawn prompts, recommended model, lingering by @Crokily in #7
- pots init --model checks that pi can use the model by @Crokily in #8
Full Changelog: v0.3.1...v0.3.2
v0.3.1
Fixed
potsstarts again afternpm install -g. A dependency of ours newly allowed@effect/platform-node-shared4.1.0, which needs a newereffectthan Pots uses, so every new install of 0.3.0 or 0.2.1 stopped withERR_MODULE_NOT_FOUND. Pots now pins it to the tested version. Each release is now installed and run the way a user gets it before it is published.
Full Changelog: v0.3.0...v0.3.1
v0.3.0
Setting Pots up on a server without a desktop, or through someone else's AI agent, and a bot that works like a pi session.
Added
- Secrets in
pots chat. The bot can ask the person for tokens withcall <terminal> ask-secret {text, file, keys}.pots chatasks for each one without showing it and writes it to that file in~/.pots/secrets/. The bot only learns which keys came, so the values reach neither its log nor the model. - Without a desktop, the bot offers three ways. When a task needs a screen, such as getting a chat app's tokens, the bot asks the person how to go about it and says what each way costs:
- a virtual desktop they can watch and sign in to over VNC;
- a browser-only tool such as agent-browser;
- browser steps on their own computer while the bot guides them.
docs/for-agents.md, for the AI agent (Claude Code, Codex, Cursor) that sets Pots up for someone. It explains what Pots is, how to install it, and that the bot connects its chat apps itself. The README and AGENTS.md point to it, and it ships in the npm package.- The bot works like a pi session. pi's own loader reads
AGENTS.mdand Agent Skills from the same places pi does, again before each request. The skills you give pi, the bot can use too. readshrinks large images to fit the model, as pi does.
Changed
- A bot's
persona.mdis now itsAGENTS.md. An existing bot'spersona.mdis renamed on its first start after the upgrade. - The Slack app manifest asks for no user scopes. The bot never used them. An app made from the old manifest keeps working.
Fixed
pots init: the arrow keys work in the login prompts, such as "Select Anthropic login method". They used to print^[[B, and the choice could not change.
What's Changed
- Set up without a desktop: login prompts fixed, secrets in pots chat, a guide for agents by @Crokily in #5
- The agent works like a pi session: AGENTS.md, skills and images by @Crokily in #6
Full Changelog: v0.2.1...v0.3.0
v0.2.1
npm install -g pi-durable-botFaster
- Every
potscommand starts in about 0.65 s instead of 2.9 s. A command loads only the code it uses, and Node keeps the compiled code of pots for the next run. The bot and its scripts callpotsoften, so this is the change you will feel most. - The gateway is ready in about 1.6 s instead of 3.0 s. It loads pi's model layer without pi's terminal interface, and checks
sudowhile it starts instead of before. pots traceon a week of spans: 0.9 s instead of 15.7 s. It finds the spans that link to a wake in one pass. The output is the same.- Fewer SQL statements per event and per wake decision, and one time formatter for wake texts: 2000 messages from one place go into the log about 15% faster.
- The idle gateway uses about 20 MB less memory.
Nothing else changes: the commands and their output, bot.json, the prompt, the log tables and the channels work as before.
Fixed
- A bot that fails while it stops now always stops its gateway and closes its file. Before, a deleted bot could stay connected to its chat apps.
Tested
New tests run the pots command line and change bot.json while the gateway runs, from outside. All 66 tests and the TLA+ models pass.
v0.2.0
npm install -g pi-durable-botWhat is new
- The bot uses its computer's screen like a person. It sees the screen with screenshots and uses the mouse and keyboard: the real browser and apps, with the logins people made there. People can watch and take over at any time. On its first wake it checks that it can use the screen and walks you through any permission the system asks for, such as Screen Recording and Accessibility on a Mac. On a server with no desktop it works without a screen, and asks you before it sets one up. No browser automation tool is installed; the bot finds, installs or writes what it needs.
pots traceshows what the gateway did for a wake, from the events to the messages sent, with the agent's run and each model request. Every span is kept in the bot's SQLite file for 7 days. WithOTEL_EXPORTER_OTLP_ENDPOINTset, the same spans also go to any OpenTelemetry tool.- The gateway core runs on Effect 4: inbox, waker, outbox, timers and the channel adapters' life, with typed errors and schemas for events and
bot.json.
Fixed
- A crash right after a wake no longer gives the bot the same events twice.
- Stopping or restarting the service no longer loses a reply the bot is sending; its work goes on after the next start.
- A failed timer wake waits 30 seconds before the next try, instead of trying again without end.
- A gateway that fails to start releases everything it started.
Tested
55 tests that start a real gateway and check only what is visible from outside, TestClock and fast-check tests for the gateway core, and TLA+ models of the outbox, the inbox with the waker, and the debounce, checked with TLC. See docs/development.md.
This release is published from GitHub Actions with npm trusted publishing and provenance.
v0.1.0: pots init
The first release on npm.
npm install -g pi-durable-bot
pots initpots init asks for a name, an AI (a subscription login, an API key or a local server) and, if you like, one sentence about what the bot is for. Then the gateway runs as a background service and you talk to your bot in the terminal. It connects its own chat apps from its computer and asks you only for what it cannot do, like signing in.
What is in it
pots, one command for people and for the bots:init,chat,status,service,start,bot, and the bot's ownsend,react,call,wake,context,turn-page.- A terminal channel, so a new bot can talk before it has joined any chat app. Messages wait in it while the bot is not running.
- macOS, Linux and Windows. The gateway runs as a service of your user: launchd, systemd (
--systemfor a server) or Task Scheduler. On Windows the bot uses Git Bash. - Any model pi can use: subscription logins, API keys from 40+ providers, OpenAI-compatible endpoints and local models. The judge is the bot's own model, a fast classifier such as Jev, a local llama.cpp model, or none.
- Slack, connected by the bot itself with docs/channels/slack.md.
- Everything on the machine lives in
~/.pots/.
Needs Node.js 24 or newer. The bot gets full control of the computer it runs on; give it a computer or VM of its own.