megachangelog
Feature

Pi Durable harness support in Agents SDK

The Agents SDK now supports building long-running agents using the Pi Durable harness via the new PiHarness class. This enables agents to persist work durably in Durable Objects, surviving interruptions and restarts.

The Agents SDK now provides first-class support for building agents using the Pi harness. You can build long-running agents using the combination of Pi 1.0 ↗︎, Pi Durable ↗︎, and the new PiHarness class that the Cloudflare Agents SDK provides, ensuring your agent's work is durably persisted, even if interrupted mid-turn.

Built with Earendil ↗︎, this integration is our first step toward first-class support for third-party agent harnesses on Cloudflare.

Copy promptPrompt copied!

Deploy to Cloudflare

Beta

PiHarness is in beta. Pi Durable ↗︎ is a new, experimental package, and the PiHarness API will likely change as Pi Durable matures.

PiHarness is a new "Lifecycle capability" provided by the Cloudflare Agents SDK. Pi Durable provides the agent harness and the Lifecycle is responsible for keeping the agent running in the Durable Object. The Lifecycle is a core concept in the Agents SDK ensuring that long-running work can run in a Durable Object, surviving restarts, crashes, and network issues. We will share more on Lifecycle capabilities in the near future.

Install

npmyarnpnpmbun
npm i agents@latest @earendil-works/pi-durable @earendil-works/pi-ai
yarn add agents@latest @earendil-works/pi-durable @earendil-works/pi-ai
pnpm add agents@latest @earendil-works/pi-durable @earendil-works/pi-ai
bun add agents@latest @earendil-works/pi-durable @earendil-works/pi-ai

Both Pi packages are optional peer dependencies of agents, so you only install them if you use the harness.

Use it in an Agent

Creating a Pi agent requires configuring the Pi Harness with a model, skills, and tools, then registering the PiHarness with the Agent class.

import { Agent } from "agents";
import { createModels } from "@earendil-works/pi-ai/models";
import { createRegistry, Harness } from "@earendil-works/pi-durable";
import { PiHarness } from "agents/harness/pi";
import { createAI } from "agents/models/pi-ai";

export class Assistant extends Agent {
	ai = createAI({ binding: this.env.AI });
	registry = createRegistry();

	harness = new PiHarness({
		harness: ({ storage, context }) => {
			const models = createModels();
			models.setProvider(this.ai.provider);
			return Harness.open(
				storage,
				{ models, registry: this.registry },
				context,
			);
		},
		defaults: { model: this.ai("@cf/moonshotai/kimi-k2.7-code") },
	});

	constructor(ctx, env) {
		super(ctx, env);
		this.lifecycle.use(this.harness);
	}

	async ask(prompt) {
		const { text } = await this.harness.prompt(prompt);
		return text;
	}
}
import { Agent } from "agents";
import { createModels } from "@earendil-works/pi-ai/models";
import { createRegistry, Harness } from "@earendil-works/pi-durable";
import { PiHarness } from "agents/harness/pi";
import { createAI } from "agents/models/pi-ai";

export class Assistant extends Agent<Env> {
	ai = createAI({ binding: this.env.AI });
	registry = createRegistry();

	harness = new PiHarness({
		harness: ({ storage, context }) => {
			const models = createModels();
			models.setProvider(this.ai.provider);
			return Harness.open(
				storage,
				{ models, registry: this.registry },
				context,
			);
		},
		defaults: { model: this.ai("@cf/moonshotai/kimi-k2.7-code") },
	});

	constructor(ctx: DurableObjectState, env: Env) {
		super(ctx, env);
		this.lifecycle.use(this.harness);
	}

	async ask(prompt: string) {
		const { text } = await this.harness.prompt(prompt);
		return text;
	}
}

The agents/models/pi-ai entry point supports AI Gateway and Workers AI models, so you can get started with Cloudflare models right away or use your existing pi-ai provider.

Add tools with extensions

Both tools and system prompt sections are provided to the Pi Harness via extensions.

import { Type } from "@earendil-works/pi-ai";

import { skills } from "agents/harness/pi";

const WordCount = Type.Object({ text: Type.String() });

const wordCount = {
	name: "word_count",
	description: "Count the words in a text.",
	parameters: WordCount,
	replay: "safe",
	async execute({ text }) {
		const words = text.split(/\s+/).filter(Boolean).length;
		return { content: [{ type: "text", text: String(words) }] };
	},
};

// In the harness factory, before Harness.open():
registry.install({
	name: "editor",
	sections: [
		{ key: "preamble", render: () => "You are an editor.", tag: false },
	],
	tools: [wordCount],
});
registry.install(await skills(sources));
import { Type } from "@earendil-works/pi-ai";
import type { ToolRegistration } from "@earendil-works/pi-durable";
import { skills } from "agents/harness/pi";

const WordCount = Type.Object({ text: Type.String() });

const wordCount: ToolRegistration<typeof WordCount> = {
	name: "word_count",
	description: "Count the words in a text.",
	parameters: WordCount,
	replay: "safe",
	async execute({ text }) {
		const words = text.split(/\s+/).filter(Boolean).length;
		return { content: [{ type: "text", text: String(words) }] };
	},
};

// In the harness factory, before Harness.open():
registry.install({
	name: "editor",
	sections: [
		{ key: "preamble", render: () => "You are an editor.", tag: false },
	],
	tools: [wordCount],
});
registry.install(await skills(sources));

For more information on creating and configuring extensions, refer to Extensions.

Learn more

agentsworkersdurable-objectsaiharness

Source: original entry ↗

More from Cloudflare

Follow Cloudflare to get its new changes in your feed and email digest.

Improvement2026.8.2100.0

Cloudflare One Client for macOS 2026.8.2100.0

GA release for macOS Cloudflare One Client with improved split tunnel handling that no longer briefly blocks traffic during reconnects, support for non-RFC 1918 local IPv4 networks, faster connects with lower memory use, and numerous reliability fixes across DNS, reauthentication, and client stability.

macosvpnreliabilityperformancedns
Improvement2026.8.2100.0

Cloudflare One Client for Windows 2026.8.2100.0

This GA release improves split tunnel reliability, adds support for non-RFC 1918 local networks, optimizes connection performance with faster reconnections and lower memory usage, and includes numerous bug fixes for DNS, registration, and network handling. The client now features a service recovery mechanism that automatically restarts on system unlock and better handles large hosts files without blocking traffic.

windowsvpnclienttunneldns
Improvement2026.8.2100.0

Cloudflare One Client for Linux 2026.8.2100.0

New GA release for Linux with improved split tunnel handling that no longer briefly blocks traffic during reconnects, support for non-RFC 1918 local IPv4 networks, faster tunnel reconnections, and lower memory usage. Includes numerous stability and reliability fixes for DNS, reconnection behavior, and crash issues.

linuxvpnclientperformancestability
See all Cloudflare changes →