PAI
The TypeScript framework behind Persi in Persuit — durable threads, server tools, and a live React UI.
PAI is the TypeScript framework behind Persi in Persuit. These public docs are for the developers building and maintaining that integration.
Talking to a model is easy. Persi's conversations have to survive a refresh, tools have to run on the server, and the UI has to stay in sync while the model works.
PAI takes care of that layer so Persi's code can focus on the agent. The small examples below show the package contracts without bringing in the rest of Persuit.
import { createPai, defineAgent } from "@pai/core";
import { openai } from "@ai-sdk/openai";
import { z } from "zod";
const assistant = defineAgent({
name: "assistant",
model: openai("gpt-4.1-mini"),
identity: z.object({
userId: z.string(),
workspaceId: z.string(),
}),
instructions: "Help with this workspace. Prefer tools over guessing.",
});
export const pai = createPai({
agents: { main: assistant },
scopeKey: (identity) => identity.workspaceId,
});That pai object is the app. Mount it on Express, talk to it from React, and every message lives on a thread.
Why PAI?
The AI SDK is how you call models, stream tokens, and define tools. PAI sits on top of it and adds what a product agent needs:
- Threads that persist across processes and page loads
- Identity decided on the server, so users only see their own data
- Tools that run in your backend, wait for a person, or run in the browser
- A React UI that streams the same thread the server stored
You keep using AI SDK models (openai(...), anthropic(...), …). PAI does not replace them.
How you will use it
| You write | PAI provides |
|---|---|
| An agent, its tools, and identity | Durable threads and runs |
resolveIdentity on Express | An HTTP/SSE API for every agent |
| A React page | Live chat, tool cards, a thread list |
| Storage / files / realtime providers | Mongo, Redis, in-memory adapters |
Start with in-memory storage locally. Persi uses Mongo for threads and Redis for live updates across server processes. GKE sandboxes can be configured where that capability is enabled; the agent definition does not change.
Start here
- Getting started — what PAI is, in a few words
- First app — define, serve, send a message
- React chat — the same agent in the browser
Then pick a guide for the next feature. Short pages are the basics; Testing, Tools, and React have nested working pages. The API reference is the catalog of public exports.
Packages you will import
@pai/core—defineAgent,defineTool,createPai@pai/express—createPaiExpressReceiver@pai/client-http—createPaiHttpClient@pai/react—createPaiReact, thenPai.agent("main").useChat()/useThreads()on the binding@pai/storage-mongo/@pai/storage-inmemory@pai/files-mongo/@pai/files-inmemory@pai/realtime-redis/@pai/realtime-inmemory@pai/sandbox/@pai/sandbox-gke
The API reference lists every public package.