@stonega/pi-expo-agents
v0.54.12
Published
Expo AI agent framework with mobile tools for file editing, memory, and compaction
Downloads
1,125
Maintainers
Readme
@stonega/pi-expo-agents
Expo AI agent framework for building intelligent mobile agents with file editing, memory management, and context compaction. Built on top of expo-file-system — no Node.js fs dependency, safe to bundle on iOS and Android.
Overview
pi-expo-agents provides a self-contained framework for integrating AI agents into Expo mobile applications. It does not depend on @stonega/pi-coding-agent or any Node.js standard library module.
Key capabilities:
- Real LLM calls via
@stonega/pi-ai(completeSimple) - Mobile-optimized tools — read, write, edit, list, remove — backed by
expo-file-system - Memory system — persistent, token-counted conversation memory
- Context compaction — automatic summarization when memory exceeds thresholds
- Session management — save and restore named conversation threads
- Utilities — system prompt builder, prompt templates, event bus, and text truncation helpers
Installation
npm install @stonega/pi-expo-agents expo-file-systemexpo-file-system is a peer dependency and is included in the standard Expo SDK.
Quick Start
import { createExpoAgent, DefaultModelRegistry, buildSystemPrompt } from "@stonega/pi-expo-agents";
import { anthropicModels } from "@stonega/pi-ai";
const registry = new DefaultModelRegistry({
apiKeys: { anthropic: process.env.EXPO_PUBLIC_ANTHROPIC_API_KEY },
});
const agent = await createExpoAgent({
model: anthropicModels["claude-3-5-haiku-20241022"],
modelRegistry: registry,
systemPrompt: buildSystemPrompt({ appName: "My App" }),
});
const response = await agent.prompt("Hello! What can you help me with?");
console.log(response);API Reference
createExpoAgent(config)
Factory function — returns a fully initialized ExpoAgent.
interface ExpoAgentConfig {
/** Model to use (from @stonega/pi-ai). Required. */
model: Model<Api>;
/** Optional registry for API key resolution. */
modelRegistry?: ModelRegistry;
/** Optional system prompt string. */
systemPrompt?: string;
/** Directory for persisted memory (default: ".expo-agent"). */
memoryDir?: string;
/** Directory for sessions (default: "<memoryDir>/sessions"). */
sessionDir?: string;
/** Max tokens in memory before compaction (default: 100 000). */
maxMemoryTokens?: number;
maxSessionTokens?: number;
/** Compaction trigger ratio 0–1 (default: 0.85). */
compactionThreshold?: number;
/** Enable automatic compaction (default: true). */
autoCompact?: boolean;
/** Additional custom tools. */
customTools?: Tool[];
/** Override the default ExpoStorage adapter. */
storageAdapter?: StorageAdapter;
}ExpoAgent
class ExpoAgent {
// Send a message and receive an LLM response
prompt(message: string): Promise<string>;
// Add a message to memory directly
addMessage(role: "user" | "assistant", content: string): Promise<void>;
// Access current conversation memory
getMemory(): ExpoAgentMemory;
// Summarize and compress conversation history
compactMemory(customInstructions?: string): Promise<void>;
// Create a new named session
createSession(name: string): Promise<ExpoAgentSession>;
// Restore a previously saved session by its ID
resumeSession(sessionId: string): Promise<ExpoAgentSession>;
}DefaultModelRegistry
A self-contained registry that resolves API keys from explicit values or environment variables.
const registry = new DefaultModelRegistry({
models: [anthropicModels["claude-3-5-haiku-20241022"]],
apiKeys: { anthropic: "sk-ant-..." },
});
// Register and update at runtime
registry.registerModel(myModel);
registry.setApiKey("openai", "sk-...");
const key = await registry.getApiKey(model);ExpoStorage
Storage adapter backed by expo-file-system v2 (class-based API). No fs imports.
import { ExpoStorage } from "@stonega/pi-expo-agents";
import { Paths, Directory } from "expo-file-system";
// Defaults to Paths.document/documents
const storage = new ExpoStorage();
// Or pass a custom Directory
const storage = new ExpoStorage(new Directory(Paths.document, "my-agent"));
// StorageAdapter interface:
await storage.read("notes/hello.txt"); // string | null
await storage.save("notes/hello.txt", "…"); // void
await storage.remove("notes/hello.txt"); // void
await storage.list("notes"); // string[]
await storage.mkdir("notes/archive"); // void
await storage.exists("notes/hello.txt"); // booleanbuildSystemPrompt(options)
Generates a structured system prompt for the agent.
import { buildSystemPrompt } from "@stonega/pi-expo-agents";
const system = buildSystemPrompt({
appName: "Finance Assistant",
selectedTools: ["read", "write", "edit"],
appendSystemPrompt: "Always respond in the user's language.",
contextEntries: [
{ label: "User Profile", content: "Name: Alice, plan: Pro" },
],
});createExpoTools(storage, baseDir)
Returns the five built-in file tools (read, write, edit, list, remove) as Tool[] objects compatible with @stonega/pi-ai.
import { createExpoTools, ExpoStorage } from "@stonega/pi-expo-agents";
const storage = new ExpoStorage();
const tools = createExpoTools(storage, "documents");Prompt Templates
import { expandPromptTemplate, parseCommandArgs, substituteArgs } from "@stonega/pi-expo-agents";
const templates = [{ name: "fix", description: "Fix bug", content: "Fix: $1", source: "builtin" }];
const expanded = expandPromptTemplate("/fix memory leak", templates);
// => "Fix: memory leak"Event Bus
Lightweight typed event bus for agent lifecycle events.
import { createEventBus } from "@stonega/pi-expo-agents";
const { bus, controller } = createEventBus<{ message: string }>();
bus.on("message", (data) => console.log(data));
controller.emit("message", { message: "hello" });Session Management
const session = await agent.createSession("my-session");
await session.prompt("Start a task");
await session.saveSession();
// Later:
const resumed = await agent.resumeSession("session-1234567890");
const response = await resumed.prompt("Continue the task");Memory Compaction
// Manual compaction
await agent.compactMemory("Summarize focusing on key decisions");
// Automatic compaction occurs at compactionThreshold (default 85 % of maxMemoryTokens)Architecture
src/
├── core/
│ ├── agent.ts # ExpoAgent + createExpoAgent + ExpoAgentSession
│ ├── model-registry.ts # DefaultModelRegistry
│ ├── memory/ # ExpoAgentMemory
│ └── compaction/ # MemoryCompactor
├── storage/
│ ├── storage.ts # ExpoStorage (expo-file-system v2)
│ └── types.ts # StorageAdapter interface
├── tools/
│ ├── read.ts / write.ts / edit.ts / list.ts / remove.ts
│ └── index.ts # createExpoTools
└── utils/
├── system-prompt.ts # buildSystemPrompt
├── prompt-templates.ts
├── event-bus.ts
└── truncate.tsDevelopment
npm install
npm run build
npm run testLicense
MIT
