
# Advanced Pi API

Most applications should use `createPiSession()`. The `agentak/pi` entry also exports the
layers underneath it for hosts that want Pi with a different picker, store, or surface.

## Agent and store

```ts
import { createAgent, createAgentStore } from "agentak/pi";

const runtime = createAgent({
  systemPrompt: "Answer from the supplied tools.",
  tools,
  approvals: "once",
});

const store = createAgentStore(runtime);
const unsubscribe = store.subscribe(() => {
  render(store.snapshot());
});

store.send("What is on this page?");

// Later:
unsubscribe();
store.dispose();
```

`createAgent()` creates Pi's `Agent` and its approval gate. It uses the default LLM7 model
until a host sets another model. It does not add provider settings or history.

`createAgentStore()` converts agent events into an identity-stable snapshot with visible
messages, streaming state, errors, usage, model, thinking level, and queued messages. It
also supplies `send`, `stop`, `reset`, `load`, `retry`, approval response, queue removal,
model selection, and thinking-level selection.

`useAgent(runtime)` exposes the same store behavior as a Preact hook and disposes its store
when the component unmounts.

## Providers and catalogs

Use these exports to build a custom picker:

- `PROVIDERS`, `availableProviders()`, `findProvider()`, and `corsFree()`
- `SUPPORTED_APIS` and `streamFor()`
- `loadCatalog()`, `cachedCatalog()`, `catalogModels()`, and `findModel()`
- `useCatalogSource()` for bundled, offline, or policy-restricted catalogs
- default provider and model constants

`streamFor()` reads the API family from the selected model and imports only that stream
module. A provider-specific fetch adapter can rewrite requests where browser CORS requires
it.

## Storage, snapshots, and history

- `memoryStorage()`, `browserStorage()`, `pageStorage`, and `createChoices()`
- `readPiSnapshot()`, `usablePiMessages()`, version and field constants
- `createHistory()`, `mintConversationId()`, and the `PiHistory` types

Always pass stored JSON through `readPiSnapshot()` before using it. `usablePiMessages()`
removes a trailing failed turn and cuts a transcript at an unanswered tool call, because
providers reject that incomplete sequence.

## Transcript and errors

- `toViewMessages()` converts Pi messages to Agentak `ViewMessage` objects.
- `toContextUsage()` builds token, cost, context-window, and near-limit data.
- `describeFailure()` creates user-facing provider error text.
- `failureStatus()` extracts a leading HTTP status for control flow.
- `generateTitle()`, `titleRequest()`, `toTitle()`, and `useTitle()` provide title behavior.

These helpers are useful when a host runs Pi but drives `ChatView` instead of using a
`ChatSession`.

## Approvals

`createApprovalGate(policy, approvalFor?)` returns:

- `beforeToolCall()` for Pi's agent hook
- `pending()` and `answers()` for rendering state
- `respond()` to allow or deny a call
- `subscribe()` for updates
- `clear()` to deny pending work and reset remembered approvals

Read [Tools and approvals](/agents/pi/tools-and-approvals) for policy behavior.

## Page tools and WebMCP

The page-tool layer is independent of the current document:

- `documentTools()` creates a `PageTools` source for `document.modelContext`.
- `createPageToolset()` turns any `PageTools` source into Pi tools and approval rules.
- `pageToolName()` normalizes names for providers.
- `toToolContent()` reads plain JSON or MCP-shaped text/image results.
- `modelContext()`, `webmcpSupported()`, and `toPageTool()` expose the browser adapter.

This split lets an iframe, worker bridge, or extension tab provide the serializable half
while the source document keeps its live WebMCP objects.

## On-device hooks

Chrome exports include Prompt API capability helpers, model constants, and provider IDs.
wllama exports include capability detection, local model metadata, loader URLs, and
`useWllamaSource()`.

Read [On-device models](/agents/pi/on-device-models) before replacing loaders or model
metadata.

## When to stay at the session layer

Use `createPiSession()` when you want Agentak's settings, key flow, provider filtering,
catalog loading, error routing, history, and title behavior. The lower-level APIs are not a
second setup shortcut; they are the pieces for a host that intentionally owns those
policies itself.
