The agent stopped in the middle of a task. Maybe a person must approve the next step. Maybe the process restarted while a tool was updating an external system. When the run returns, starting from the original prompt sounds simple. It mixes completed work, pending work, and effects that nobody has confirmed.

To pause and resume an AI agent safely, persist an execution boundary that the runtime can explain. Save intent, the next step, pending requests, approval, and tool receipts. On resume, use the same run identity, validate the state version, and investigate any external effect that may have happened before the interruption.

The guide to durable execution for AI agents covers the choice between a queue and a workflow. This article focuses on a smaller boundary: what it means to pause a run and which evidence is needed before it continues.

The code is illustrative. It was not executed against an agent SDK in this repository. Its purpose is to make the contract explicit and guide tests with the adapter you choose.

Diagram showing an AI agent pausing, saving a checkpoint, and resuming after verifying an external effect.

The short answer

  • Pause at a transition the runtime can record, not in the middle of an action without a receipt.
  • Separate agent intent, runtime progress, and the tool's consequence.
  • Resume one run with exclusive ownership, versioned state, and a still-valid approval.
  • If an external effect is uncertain, observe the system before repeating the action.

Is pausing different from cancelling or retrying?

Pausing preserves the option to continue the same run. Cancelling ends the execution and may require a compensating action. Retrying creates another attempt, which can repeat a decision or a tool call. The OpenAI Agents SDK, "Run State" describes serializable state as the boundary for interrupting and resuming human-in-the-loop flows.

These states should appear in the runtime model. paused can mean that the run is waiting for a person or an operating window. cancelled says that the run must not continue. failed says that execution ended with an error. running should return only after the process has recovered the checkpoint and acquired ownership of the run.

Do not turn every interruption into a retry. If a tool created an order, sent a message, or changed a record, the local process may have died before it got the response. The name is different, but the problem is the same as duplicate tool calls during LLM failover: the executor must know whether the effect already exists.

What should an agent checkpoint contain?

A useful checkpoint stores the state needed to decide the next step, not only the history the model saw. Microsoft Agent Framework, "Checkpoints" describes checkpoints that include executor state, pending messages, pending requests and responses, and shared state. A checkpoint is therefore a workflow boundary, not a conversation file.

A minimal structure can contain these fields:

Field Purpose
runId Prevents two workers from resuming the same run without coordination.
stateVersion Lets the runtime reject or migrate an old checkpoint.
status Separates running, paused, approval, cancellation, and failure states.
nextStep Names the first transition that is not confirmed.
pendingApproval Stores the request and the representation of what was approved.
toolReceipts Records observed results and external IDs created.
updatedAt Helps detect abandoned ownership and stale state.

You can keep the transcript for context and auditing, but it should not be the only recovery source. A summary may help the model decide. A raw receipt helps the runtime prove that a call was accepted, rejected, completed, or left unknown.

The most important field is not lastMessage. It is nextStep together with what the runtime knows about the previous effect. A message may have been generated without being persisted. A call may have been accepted without its response arriving. The checkpoint must preserve that difference so resume does not guess.

Where is a safe pause boundary?

Create the boundary after a confirmed transition and before admitting the next action. The Google Developers Blog, "Build long-running AI agents that pause, resume, and never lose context with ADK" shows this pattern with persistent sessions and checkpoints associated with agent state. The storage must survive the process executing the run.

In practice, there are four different moments:

  1. The agent proposed a tool, but it has not been sent. Pause and record the proposal as pending.
  2. The tool was sent and a receipt confirms the result. Save the receipt and advance nextStep.
  3. The tool was sent, but the process died before the receipt. Mark the effect unknown and observe the external system before deciding.
  4. A person approved an action, but the context changed. Revalidate the approval or return to manual review.

A checkpoint inside a function that combines a model call and an external effect is a weak boundary. If the process dies between the two parts, the runtime cannot say which one happened. Split preparation, commit, and observation when an operation creates an effect that is hard to undo.

How should the runtime model pause and resume?

The runtime should decide whether it may advance. The model should propose the next step. The code below represents that split with simple types. These names are not a vendor API and do not replace the contract of your executor.

type RunStatus =
  | "running"
  | "paused"
  | "waiting_for_approval"
  | "failed"
  | "cancelled"
  | "completed";

type ToolReceipt = {
  operationId: string;
  status: "committed" | "rejected" | "unknown";
  externalId?: string;
};

type AgentCheckpoint = {
  runId: string;
  stateVersion: number;
  status: RunStatus;
  nextStep: string;
  pendingApproval?: { inputHash: string; approvedBy?: string };
  toolReceipts: ToolReceipt[];
};

function canResume(checkpoint: AgentCheckpoint): boolean {
  return checkpoint.status === "paused" ||
    checkpoint.status === "waiting_for_approval";
}

A production adapter still has to do the difficult part: save the checkpoint atomically, acquire a lease or another form of exclusive ownership, and query external IDs before executing an unknown operation. Types only make the decisions visible. They do not create idempotency by themselves.

How do you resume after human approval?

Resume the original execution when the checkpoint contains the approval, the approved request, and the session identity it needs. The OpenAI Agents SDK, "Sessions" recommends keeping the same session when resuming a RunState. It also describes protections that prevent ambiguous output from being persisted as final.

Approval should be tied to what the person actually reviewed. Store a hash or canonical representation of the approved input, plus the reviewer and policy identifier when your system needs them. On resume, compare the current input with the approved one. If the plan, recipient, amount, or permission changed, ask for approval again.

This separates two questions that often get mixed together: "may the execution continue?" and "is the effect still authorized?" The first belongs to the runtime. The second depends on current state, policy, and the tool. The guide to when an AI agent should ask for human approval covers the decision to request review. Here, the concern is avoiding an old approval that acts like a permanent pass.

What should happen when an external effect is unknown?

Do not repeat a tool when the only known fact is that the client did not receive the response. AWS, "Implement comprehensive state management and checkpoint-based recovery" connects safe recovery with idempotent steps, idempotency keys, conditional writes, and event deduplication.

The resume path should query the external source with operationId, when that query exists. Three responses are useful:

  • committed: the effect was found. Record the receipt and advance without calling the operation again.
  • not_found: the system confirms that the effect does not exist. Recheck policy and execute with the same operation identity if that is safe.
  • unknown: there is not enough evidence. Stop, mark the run for review, or use a domain-specific reconciliation action.

Do not use the transcript as a receipt. It proves that the model requested an action, but not that the external service accepted it. Do not hide unknown behind an optimistic summary either. The guide to observability for coding agents in CI uses the same boundary: decisions and effects must remain distinguishable in the record.

When an agent may wait for a long time, RemoteCode is the tool I use to keep agent sessions and context visible. That describes how I use the tool, not a performance test here.

Where should you store agent state?

Store the checkpoint in durable, private storage that the worker resuming the run can reach. Local memory works only while the same process remains alive. The Google article about long-running agents uses persistent session storage because the process may restart or remain idle between steps.

Microsoft Agent Framework, "Checkpoints" also treats checkpoint storage as a trust boundary. Protect reads and writes, validate the format before deserialization, and do not accept checkpoints from an untrusted source. A snapshot with unexpected objects or instructions can become a security problem during resume.

Separate responsibilities according to volume and risk:

Data Storage and rule
Current state Transactional database or store with versioning and ownership.
Tool receipts Durable record queryable by operationId.
Model context Session or compact summary with defined retention.
Audit events Append-only log with secrets redacted.

Do not choose Redis, SQLite, a managed workflow, or a relational database just because a vendor's documentation names it. The decision depends on durability, concurrency, retention, recovery, and how much control the executor needs.

How do you test a resume without duplicating work?

Test interruption at the boundaries where state can diverge. The OpenAI Agents SDK, "Testing" documents testing agent runs and responses. For this case, the fixture must also control storage and a fake executor.

A minimal set should verify:

Interruption Expected result
Before sending the tool Resume sends one pending operation.
After the tool confirms Resume uses the receipt and does not send again.
After sending, before the receipt Resume queries the effect before deciding.
While waiting for approval Resume keeps the request and validates its input.
After the state version changes The runtime migrates or rejects the checkpoint explicitly.
Two workers try to resume One gets ownership; the other does not execute the run.
The user cancels during the pause The run ends as cancelled and does not return to running.

Kill the process at each point, restore state, and inspect effects in the fake executor. Then repeat with a different model response. If completion depends on the model choosing exactly the same tool, the test is replaying a prompt, not proving resume safety.

Frequently asked questions

Does pausing an agent save the entire conversation history?

Not necessarily. A checkpoint needs the state the runtime requires to continue, while history may have a different retention policy. The OpenAI Agents SDK, "Run State" separates the serializable snapshot, generated items, context, and interruptions. Save what the next decision needs and retain the transcript according to your policy.

Can I resume the agent in another process?

Yes, when state lives in shared storage and the new process can rehydrate the required context. The run identity needs exclusive ownership during resume. If the SDK relies on the same session or conversation identifier, keep that link. If state is ambiguous, stop and repair it manually.

Does checkpointing guarantee that a tool call happens only once?

No. A checkpoint tells you what was persisted, but the tool must recognize the operation and query its own effects. The AWS guidance for checkpoint-based recovery recommends idempotency and deduplication because resume can encounter a window where the call was accepted but its result was not recorded.

Conclusion

A safe resume does not reconstruct the past from the prompt. It loads a checkpoint the runtime can explain, preserves intent and the next step, and checks consequences before repeating an action.

The design can start small: explicit status, runId, nextStep, a state version, and tool receipts. Then add exclusive ownership, approval revalidation, schema migration, retention, and interruption tests. The boundary of responsibility should stay clear: the runtime decides progress, and the tool owns the effect it leaves in the world.

Sources consulted