> For the complete documentation index, see [llms.txt](https://docs.zenml.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.zenml.io/kitaru/adapters/choose-an-adapter.md).

# Choose an Adapter

An adapter wraps an existing agent harness so each model call and tool call lands as a Kitaru checkpoint, with no rewrite of your agent. The boundary you pick decides how fine-grained your checkpoints are, which in turn sets how precisely you can replay: per-call checkpoints let you reproduce a run and replay it from the exact call you changed, while a single coarse checkpoint only lets you replay the whole turn. Pick the boundary that matches the code you already have, then go as granular as your replay needs require.

## Decision table

The **replay boundary** column is the unit you can replay from: a finer boundary means `flow.replay(exec_id, at="<checkpoint>", ...)` can re-execute from a single model or tool call instead of re-running the entire turn.

| You have...                 | Use this                | Replay boundary (finest available)                             | First page                                                       |
| --------------------------- | ----------------------- | -------------------------------------------------------------- | ---------------------------------------------------------------- |
| Plain Python functions      | `@flow` + `@checkpoint` | Your function boundaries — you choose them                     | [Quickstart](/kitaru/getting-started/quickstart.md)              |
| PydanticAI agent            | `KitaruAgent`           | **Per model/tool/MCP call** by default, or one turn checkpoint | [PydanticAI Adapter](/kitaru/adapters/pydantic-ai.md)            |
| OpenAI Agents SDK agent     | `KitaruRunner`          | **Per call**, or one runner-call checkpoint                    | [OpenAI Agents Adapter](/kitaru/adapters/openai-agents.md)       |
| Claude Agent SDK invocation | `KitaruClaudeRunner`    | One completed Claude invocation                                | [Claude Agent SDK Adapter](/kitaru/adapters/claude-agent-sdk.md) |
| LangGraph graph             | `KitaruGraphRunner`     | One graph call, or middleware-wrapped model/tool calls         | [LangGraph Adapter](/kitaru/adapters/langgraph.md)               |

{% hint style="info" %}
**Per-call checkpointing is fullest in the PydanticAI (`KitaruAgent`) and OpenAI Agents SDK (`KitaruRunner`) adapters.** Both can record every model and tool call as its own checkpoint, so replay can target an individual call. The Claude Agent SDK adapter currently checkpoints at the invocation boundary, and LangGraph's per-call granularity depends on middleware wrapping the model/tool calls. If call-level replay fidelity is your priority, prefer PydanticAI or OpenAI calls mode.
{% endhint %}

## Pick by goal

<table data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>I want the simplest durable boundary</strong></td><td>Wrap phases of work in @checkpoint and keep your existing Python control flow</td><td><a href="/pages/Zt6utJ6bxTsCzHn1d3At">/pages/Zt6utJ6bxTsCzHn1d3At</a></td></tr><tr><td><strong>I want granular agent observability</strong></td><td>Use PydanticAI or OpenAI calls mode so model and tool calls become visible replay units</td><td><a href="/pages/iiOo4wYH4K6fDhJMCaJT">/pages/iiOo4wYH4K6fDhJMCaJT</a></td></tr><tr><td><strong>I want a clean return value from flow.wait()</strong></td><td>Use a coarse runner-call or turn checkpoint around the whole agent turn</td><td><a href="/pages/isuczCq30zR8fJrUKXHc">/pages/isuczCq30zR8fJrUKXHc</a></td></tr><tr><td><strong>I need human approval</strong></td><td>Keep wait/approval bridges at flow scope so the execution can suspend safely</td><td><a href="/pages/BUp6cWRuU8VUfknQKRto">/pages/BUp6cWRuU8VUfknQKRto</a></td></tr></tbody></table>

## Strategy notes

| Strategy                        | Best for                                                                                | Trade-off                                                                    |
| ------------------------------- | --------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------- |
| Coarse checkpoint               | Fast migration, clean `.wait()` return value, low adapter complexity                    | Replay can only re-run the whole turn — you cannot replay from a single call |
| Granular (per-call) checkpoints | Expensive LLM/tool chains where you want to replay from one call with one input changed | More checkpoint rows and stricter rules around waits/nesting                 |
| Explicit raw checkpoints        | Maximum control and framework independence                                              | You decide every durable boundary yourself                                   |

## Human-in-the-loop rule

`kitaru.wait()` belongs at flow scope, not inside a normal checkpoint body. If your harness adapter creates granular tool checkpoints, configure wait-bearing tools so the adapter keeps that wait outside the synthetic checkpoint wrapper.

Start with:

* [Wait, Input, and Resume](/kitaru/guides/wait-and-resume.md)
* [PydanticAI human-in-the-loop tools](/kitaru/adapters/pydantic-ai.md#ask-the-human-from-a-tool-body)
* [OpenAI approval interruptions](/kitaru/adapters/openai-agents.md#approval-interruptions)
* [LangGraph interrupt and resume](/kitaru/adapters/langgraph.md#interrupt-and-resume)

## Next

Run a small adapter example from [Examples](/kitaru/getting-started/examples.md) before porting a production agent. The fastest useful proof is one completed execution where you can see the expected checkpoint shape.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.zenml.io/kitaru/adapters/choose-an-adapter.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
