
# Pi Harness

The Pi harness adapter connects `HarnessAgent` to
`@earendil-works/pi-coding-agent`. Pi runs in the host Node.js process and uses
the sandbox as a remote filesystem and shell. It does not install a bridge
inside the sandbox.

<Note>
  Harness packages are **experimental**. Expect breaking changes between
  releases as this early API gets further refined.
</Note>

## Setup

<InstallPackages packages="@ai-sdk/harness @ai-sdk/harness-pi @ai-sdk/sandbox-vercel" />

## Import

```ts
import { pi, createPi } from '@ai-sdk/harness-pi';
```

`pi` is equivalent to `createPi()` with its default configuration.

## Basic Usage

```ts
import { HarnessAgent } from '@ai-sdk/harness/agent';
import { pi } from '@ai-sdk/harness-pi';
import { createVercelSandbox } from '@ai-sdk/sandbox-vercel';

const agent = new HarnessAgent({
  harness: pi,
  model: 'anthropic/claude-sonnet-4.6',
  sandbox: createVercelSandbox({
    runtime: 'node24',
  }),
});

const session = await agent.createSession();

let exitCode = 0;
try {
  const result = await agent.stream({
    session,
    prompt: 'Check the test failures and fix the production code.',
  });

  for await (const part of result.stream) {
    if (part.type === 'text-delta') {
      process.stdout.write(part.text);
    }
  }
} catch (err) {
  exitCode = 1;
  console.error(err);
} finally {
  await session.destroy();
  process.exit(exitCode);
}
```

To use this agent, ensure environment variables include `VERCEL_OIDC_TOKEN` for
Vercel Sandbox, and one of the variables listed under [authentication](#authentication)
for Pi.

## Adapter Settings

Use `createPi()` to configure the runtime:

```ts
const harness = createPi({
  thinkingLevel: 'medium',
});
```

Settings:

- `auth`: authentication mode (`auto`, `openai`, `anthropic`, `custom`, or
  `ai-gateway`) or an isolated authentication environment.
- `credentials`: application-owned Pi credential storage. This replaces the
  file-backed `auth.json` store and supports persistent database-backed
  credentials.
- `extensionFactories`: trusted inline Pi extension factories that run in the
  host Node.js process.
- `mcpServers`: MCP server definitions keyed by server name.
- `providers`: explicit Pi provider configurations for custom models.
- `reattachInProcess`: whether a suspended turn can reuse its live Pi session
  in the current process. Defaults to `true`.
- `thinkingLevel`: Pi thinking level (`off`, `minimal`, `low`, `medium`,
  `high`, `xhigh`, or `max`).

## Inline Extensions

Use `extensionFactories` to load trusted inline Pi extensions for each harness
session:

```ts
const harness = createPi({
  extensionFactories: [
    pi => {
      pi.on('agent_start', () => {
        console.log('Pi agent started');
      });
    },
  ],
});
```

Routine resource refreshes between turns reuse the active extension runtime and
do not reinitialize factories. If the underlying Pi session is rebuilt, the
factories initialize again for the new Pi runtime.

Extension factories execute in the host Node.js process with access to the host
environment, so only pass factories you trust. This setting enables only the
factories you explicitly provide. Filesystem extension discovery remains
disabled, including user, project, and settings-based extensions. Themes and
prompt templates also remain disabled.

## Session Reattachment

By default, Pi keeps a suspended turn alive for an efficient continuation in
the same process when the incoming request has compatible settings and runtime
resources. Changed request-scoped settings or sandbox handles cause a cold
restore from persisted lifecycle state.

For stateless or multi-replica applications, disable in-process reattachment so
every continuation restores the persisted lifecycle state with the current
request's settings:

```ts
const harness = createPi({
  reattachInProcess: false,
});
```

An incoming completed `resume-session` state always takes precedence over an
older live suspended turn in the process.

## Authentication

The `auth` setting selects which credentials Pi reads from the host environment:

- `auto` (default): use AI Gateway credentials when available, then fall back
  to all provider credentials found in the environment.
- `openai`: use `OPENAI_API_KEY` and the optional `OPENAI_BASE_URL`.
- `anthropic`: use `ANTHROPIC_API_KEY` and the optional
  `ANTHROPIC_AUTH_TOKEN` and `ANTHROPIC_BASE_URL`.
- `custom`: register all providers configured through environment variables.
- `ai-gateway`: use `AI_GATEWAY_API_KEY` or `VERCEL_OIDC_TOKEN` and the
  optional `AI_GATEWAY_BASE_URL`.

If no applicable credential environment variable is set, the adapter attempts
to resolve a native subscription from the host system unless AI Gateway
authentication is selected.

```ts
const harness = createPi({ auth: 'ai-gateway' });
```

Pass an authentication environment to use programmatically resolved
credentials without reading `process.env`:

```ts
const harness = createPi({
  auth: {
    MISTRAL_API_KEY: await resolveMistralToken(),
    MISTRAL_BASE_URL: 'https://api.mistral.ai',
  },
});
```

The supplied record replaces the host environment for authentication
discovery. Pi parses provider API keys and base URLs from that record.

For credentials managed outside environment variables or files, inject an
application-owned credential store. Pi performs credential reads, refreshes,
and updates through this interface:

```ts
import { createPi, type PiCredentialStore } from '@ai-sdk/harness-pi';

declare const credentials: PiCredentialStore;

const harness = createPi({
  credentials,
  reattachInProcess: false,
});
```

`credentials` replaces Pi's `auth.json` storage. In request-scoped or
multi-replica deployments, pair it with `reattachInProcess: false` so each
continuation constructs a model runtime from the current request.

With `custom`, standard providers use environment variables such as
`OPENAI_API_KEY`, `OPENAI_BASE_URL`, `ANTHROPIC_API_KEY`, and
`ANTHROPIC_BASE_URL`. Other providers use a `<PREFIX>_API_KEY` and matching
`<PREFIX>_BASE_URL` pair.

Authentication variables do not identify a provider's API protocol or models.
Register that metadata explicitly when using a custom model:

```ts
const harness = createPi({
  auth: {
    MYPROVIDER_API_KEY: await resolveMyProviderToken(),
    MYPROVIDER_BASE_URL: 'https://api.example.com/v1',
  },
  providers: {
    myprovider: {
      api: 'openai-completions',
      models: [
        {
          id: 'my-custom-model',
          name: 'My Custom Model',
          reasoning: false,
          input: ['text'],
          cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
          contextWindow: 128_000,
          maxTokens: 16_384,
        },
      ],
    },
  },
});
```

## Sandbox

Pi needs a `HarnessV1SandboxProvider`, but it does not require exposed ports.
You can use a network sandbox adapter like `@ai-sdk/sandbox-vercel`, or a
local emulation like `@ai-sdk/sandbox-just-bash`:

```ts
const sandbox = createVercelSandbox({
  runtime: 'node24',
});
```

## Built-in Tools

The adapter exposes these common Pi built-ins through `agent.tools`:

- `read`
- `write`
- `edit`
- `bash`
- `grep`
- `glob`
- `ls`

Additional Pi built-ins may also appear in `agent.tools` when they do not fit a
common tool shape.

Pi supports built-in tool approval requests when `permissionMode` is
`allow-reads` or `allow-edits`.

## Known Limitations

Pi does not support structured output. Supplying `output` to `HarnessAgent`
causes the turn to throw `HarnessCapabilityUnsupportedError`.

## Related

- [HarnessAgent](/docs/ai-sdk-harnesses/harness-agent)
- [Harness tools](/docs/ai-sdk-harnesses/tools)
- [Harness adapters](/docs/ai-sdk-harnesses/harness-adapters)


## Navigation

- [Claude Code](/providers/ai-sdk-harnesses/claude-code)
- [Codex](/providers/ai-sdk-harnesses/codex)
- [Pi](/providers/ai-sdk-harnesses/pi)
- [OpenCode](/providers/ai-sdk-harnesses/opencode)
- [Deep Agents](/providers/ai-sdk-harnesses/deepagents)
- [Agent Client Protocol](/providers/ai-sdk-harnesses/acp)
- [Grok Build](/providers/ai-sdk-harnesses/grok-build)
- [Cline](/providers/ai-sdk-harnesses/cline)
- [Cursor](/providers/ai-sdk-harnesses/cursor)
- [fx](/providers/ai-sdk-harnesses/fx)
- [GitHub Copilot](/providers/ai-sdk-harnesses/github-copilot)


[Full Sitemap](/sitemap.md)
