A model generates a response. A harness turns that response into work: it supplies context, offers tools, executes tool calls, and sends the results back to the model. Condensate provides that loop itself, and it can also connect to harnesses that run their own loop.
Start with the agent loop
Suppose you ask an agent to explain a function. The model requests a file read. The harness executes that read, returns the contents, and calls the model again. The model can now explain the function or request another tool.
Your request: “Explain how this function works.”
↓
Model requests a file read
↓
Harness executes the tool and returns the file contents
↓
Model reads the result and responds
This is an illustrative turn, not an API payload. The important engineering boundary is that the model proposes tool calls; the harness runs them under its configured policy.
Path 1: Condensate runs the loop
The native engine owns the model-and-tool cycle, transcripts, and context-window policy. It uses @earendil-works/pi-ai to communicate with providers, plus selected utilities from pi-coding-agent.
In configuration, this engine is called pi. That is an engine identifier inside Condensate. The implementation of its loop lives in packages/engine/src/pi/loop.ts.
// From packages/engine/src/index.ts
import { createPiLoop } from "./pi/loop.js";
For application code, use the runtime or SDK. The import above identifies the internal implementation; it is not an application setup example.
Path 2: Condensate wraps a Claude session
The Claude adapter runs a session through the Claude Agent SDK. Condensate coordinates the surrounding thread and integrates the session's hooks, transcript recording, and context-window behavior.
The session factory selects the adapter using the engine setting. This is the branch in packages/engine/src/index.ts:
if (full.engine !== "pi") return createProcessClaudeSession(full);
The allowed engine identifiers are pi and claude. The factory also checks that a requested model is compatible with its engine before constructing the session.
Path 3: Another harness connects to middleware
An existing harness can connect to Condensate's MCP endpoint for tools and wire its lifecycle hooks to middleware. Its own loop continues to run. Condensate can then evaluate the events and tool calls that flow through those connections.
For example, a tool request can pass through MCP policy before reaching an upstream server. A lifecycle hook can return a verdict through the client's hook shim. The client's supported hooks determine what it can apply.
Connect tools and hooks shows the endpoint configuration and a catalog request.
Choose by who should own the work
| You want to… | Use… | Who runs the session? |
|---|---|---|
| Build an app around durable agent tasks | Runtime + native engine | Condensate |
| Use Claude sessions inside that runtime | Runtime + Claude adapter | Claude Agent SDK, integrated by Condensate |
| Add tools and policy to an existing agent | MCP + supported hooks | The external harness |
Provider access is a separate choice. Selecting an OpenAI Codex provider or an OpenCode model catalog entry does not launch the Codex application or OpenCode CLI. The engine setting tells you which execution path is active.
Where the runtime fits
The harness handles the conversation with the model. The runtime keeps the durable thread and exposes controls to applications. Together they let a UI follow a task, recover its recorded history, and request further work through a consistent interface.
Continue with the lifecycle of a thread or context windows.