01 // AI agents

The minimal agent runtime

The Pi harness is built on top of the Workflows fragment and Pi's AgentHarness. It provides durable session routes while keeping workflow and tool construction owned by your application.

Install

npm install @fragno-dev/pi-harness @fragno-dev/workflows @fragno-dev/db

Depends on

Workflows + DB

Best for

Embedding agents

Capabilities

Durable sessions

Every turn runs through workflows, so agent state survives retries and restarts.

Tool execution

Agent turns can invoke registered tools with structured messages and traceable results.

Typed session APIs

Create sessions, inspect runs, and send messages from framework-native clients.

Interface

Pi keeps the route surface small. The complexity lives in durable execution semantics, not in transport sprawl.

Route surface

POST /workflows/:workflowName/sessionsGET  /workflows/:workflowName/sessionsGET  /workflows/:workflowName/sessions/:sessionIdGET  /workflows/:workflowName/sessions/:sessionId/eventsPOST /workflows/:workflowName/sessions/:sessionId/command

Why it matters

Agent features fail when state and side effects are implicit. Pi makes both explicit: sessions are queryable records, tool calls are persisted in execution output, and clients consume typed hooks instead of bespoke chat plumbing.

Blueprint

Define the agent once, then integrate the product around it.

Create the server

import { defaultFragnoRuntime } from "@fragno-dev/core";import { createPiHarness, createPiWorkflows } from "@fragno-dev/pi-harness/factory";import { createInteractiveChatWorkflow } from "@fragno-dev/pi-harness/workflows/interactive-chat-workflow";import { createWorkflowsFragment } from "@fragno-dev/workflows";const interactiveChat = createInteractiveChatWorkflow({  harnesses: {    support: {      env,      model,      systemPrompt: "You are a helpful support agent.",      tools: [searchTool],    },  },});const piConfig = { workflows: [interactiveChat] };const workflows = createPiWorkflows(piConfig);const workflowsFragment = createWorkflowsFragment(  { workflows, runtime: defaultFragnoRuntime },  { databaseAdapter, mountRoute: "/api/workflows" },);export const fragment = createPiHarness(  piConfig,  { databaseAdapter, mountRoute: "/api/pi" },  { workflows: workflowsFragment.services },);

Create a client

import { createPiFragmentClient } from "@fragno-dev/pi-harness/react";const pi = createPiFragmentClient({ baseUrl: "/api/pi" });const createSession = pi.useCreateSession();const session = pi.useSession({  path: { workflowName: "interactive-chat-workflow", sessionId },});

Use it

const created = await createSession.mutateQuery({  path: { workflowName: "interactive-chat-workflow" },  body: { name: "Customer issue", input: { harnessName: "support" } },});await session.sendCommand({  kind: "prompt",  input: { text: "Summarize the bug report and propose next steps." },});

Outcome

Built to survive real runtime conditions.

Long-running turns

Pause, resume, and recover work without losing context.

Safe side effects

Replays reuse captured tool results instead of re-running risky actions.

Inspectable state

Sessions and messages remain queryable, not trapped in ephemeral runtime memory.