Skip to main content
The @polpo-ai/client package provides a typed HTTP client, SSE streaming, and reactive store for interacting with the Polpo API from any TypeScript/JavaScript environment — Node.js, Deno, Bun, browser, or edge runtimes.
This is the framework-agnostic foundation. For React hooks, see @polpo-ai/react which builds on top of this package.

Installation

npm install @polpo-ai/client
No peer dependencies. Works in Node.js 18+, Deno, Bun, and modern browsers.

Quick Start

import { PolpoClient } from "@polpo-ai/client";

const client = new PolpoClient({
  baseUrl: "http://localhost:3000",
  apiKey: "my-api-key",
});

// List all tasks
const tasks = await client.getTasks();

// Create a mission
const mission = await client.createMission({
  name: "Deploy v2",
  tasks: [
    { title: "Run tests", assignTo: "backend-dev" },
    { title: "Build Docker image", assignTo: "devops", dependsOn: ["Run tests"] },
  ],
});

// Execute it
await client.executeMission(mission.id);

// Stream a chat completion
const stream = client.streamChatCompletion({
  messages: [{ role: "user", content: "Create a REST API for user management" }],
});

for await (const chunk of stream) {
  process.stdout.write(chunk.choices[0]?.delta?.content ?? "");
}

PolpoClient

The main HTTP client class. All methods return typed promises.
const client = new PolpoClient({
  baseUrl: "http://localhost:3000",
  apiKey: "optional-api-key",          // sent as X-API-Key header
  fetch: customFetch,                   // optional: inject a custom fetch implementation
});

Tasks

MethodReturnsDescription
getTasks(filters?)Task[]List tasks with optional status/group/agent filters
getTask(id)TaskGet a single task
createTask(opts)TaskCreate a new task
updateTask(id, opts)TaskUpdate a task
deleteTask(id)voidDelete a task
retryTask(id)voidRetry a failed task
killTask(id)voidKill a running task’s agent
reassessTask(id)voidRe-run assessment on a task
queueTask(id)voidQueue a task for execution

Missions

MethodReturnsDescription
getMissions()Mission[]List all missions
getMission(id)MissionGet a single mission
createMission(opts)MissionCreate a new mission
updateMission(id, opts)MissionUpdate mission metadata
deleteMission(id)voidDelete a mission
executeMission(id)ExecuteMissionResultExecute a draft mission
resumeMission(id, opts?)ResumeMissionResultResume a failed/paused mission
abortMission(id){ aborted: number }Abort an active mission

Agents

MethodReturnsDescription
getAgents()AgentConfig[]List all agents
getAgent(name)AgentConfigGet a single agent
addAgent(opts)voidRegister a new agent
removeAgent(name)voidRemove an agent
getProcesses()AgentProcess[]List active agent processes

Chat

MethodReturnsDescription
chatCompletion(opts)ChatCompletionResponseNon-streaming chat completion
streamChatCompletion(opts)ChatCompletionStreamStreaming chat (async iterable)
getSessions()ChatSession[]List chat sessions
getSessionMessages(id)ChatMessage[]Get messages for a session

Other

MethodReturnsDescription
getPlaybooks()PlaybookInfo[]List available playbooks
runPlaybook(name, params?)PlaybookRunResultExecute a playbook
getSkills()SkillWithAssignment[]List skills
getApprovals(status?)ApprovalRequest[]List approval requests
approve(id, opts?)voidApprove a request
reject(id, feedback)voidReject a request
getNotifications(opts?)NotificationRecord[]List notifications
getMemory(){ exists, content }Get project memory
updateMemory(content)voidUpdate project memory
getAuthStatus()AuthStatusResponsePer-provider auth health

ChatCompletionStream

Async iterable for streaming chat completions:
const stream = client.streamChatCompletion({
  messages: [{ role: "user", content: "Hello" }],
});

for await (const chunk of stream) {
  // chunk: ChatCompletionChunk
  const content = chunk.choices[0]?.delta?.content;
  if (content) process.stdout.write(content);
}

EventSourceManager

SSE connection manager with auto-reconnect:
import { EventSourceManager } from "@polpo-ai/client";

const es = new EventSourceManager({
  url: client.getEventsUrl(),
  onEvent: (event) => {
    console.log(event.event, event.data);
  },
  onStatusChange: (status) => {
    console.log("Connection:", status); // "connected" | "connecting" | "disconnected"
  },
});

es.connect();
// ... later
es.disconnect();
EventSource is a browser API. In Node.js, use a polyfill like eventsource or use the PolpoStore approach below for a higher-level API.

PolpoStore

A framework-agnostic reactive store that consumes SSE events and maintains application state:
import { PolpoClient, PolpoStore, EventSourceManager } from "@polpo-ai/client";

const client = new PolpoClient({ baseUrl: "http://localhost:3000" });
const store = new PolpoStore();

// Populate initial state
const [tasks, missions, agents] = await Promise.all([
  client.getTasks(),
  client.getMissions(),
  client.getAgents(),
]);
store.setTasks(tasks);
store.setMissions(missions);
store.setAgents(agents);

// Subscribe to changes
store.subscribe(() => {
  const state = store.getSnapshot();
  console.log("Tasks:", state.tasks.size, "Missions:", state.missions.size);
});

// Connect SSE for real-time updates
const es = new EventSourceManager({
  url: client.getEventsUrl(),
  onEvent: (event) => store.applyEvent(event),
  onStatusChange: (status) => store.setConnectionStatus(status),
});
es.connect();

Store API

MethodDescription
subscribe(listener)Subscribe to state changes. Returns unsubscribe function.
getSnapshot()Get current state
setTasks(tasks)Bulk-set tasks (deduplicates)
setMissions(missions)Bulk-set missions
setAgents(agents)Bulk-set agents
setProcesses(processes)Bulk-set processes
applyEvent(event)Apply a single SSE event
applyEventBatch(events)Apply multiple SSE events atomically

Selectors

Memoized selector functions for extracting data from the store state:
import { selectTasks, selectMission, selectEvents } from "@polpo-ai/client";

const state = store.getSnapshot();

// Filter tasks
const runningTasks = selectTasks(state, { status: "in_progress" });

// Get a specific mission
const mission = selectMission(state, "mission-123");

// Filter events
const taskEvents = selectEvents(state, ["task:*"]);

Subpath Exports

// Full import
import { PolpoClient, PolpoStore } from "@polpo-ai/client";

// Client-only import
import { PolpoClient } from "@polpo-ai/client/client";

// Store-only import
import { PolpoStore, reduceEvent } from "@polpo-ai/client/store";