Skip to main content
You’ll build an agent that starts, does some work, pauses to wait for a human decision, and resumes from exactly where it left off. Nothing here needs an API key.

1. Declare and start an agent

agent name: ... only declares — nothing runs until start(agent). A plain agent blocks until its body finishes:
analyst.finding reads a variable the body set — an agent’s own scope stays inspectable after it runs, like a module’s.

2. Pause mid-task

pause(reason?) suspends the agent right where it’s called. start() returns as soon as that happens — it doesn’t wait for the agent to finish, because it might not, for a while:
Notice "this only runs after resume()" never printed — the agent is genuinely suspended, not just slow.

3. Resume it

resume(agent, value?) continues the agent from exactly where pause() left it. Whatever you pass becomes pause()’s own return value inside the agent body:

4. ask_human — the same thing, one call

ask_human(question) is pause(question) under a friendlier name for the common case — asking a person something and waiting for their answer:
In a real system, resume(approver, answer) is the call your UI or Slack bot makes once the actual human replies — this program supplies "yes" directly so it stays runnable non-interactively.

What you built

  • agent name: ... — declares, doesn’t run; start(agent) runs the body
  • .statuscreatedrunningpaused/completed/failed
  • pause(reason?) / resume(agent, value?) — genuine mid-body suspension, not polling
  • ask_human(question)pause() under the name that matches what it’s for

Next

Agents

The full reference — async agent, concurrency, agent state.

Pause & Resume

More patterns: approval gates, multi-step human review.

Safe Actions

Previous tutorial, if you missed it.

Which keyword do I want?

def vs tool vs action vs agent, decided in one glance.