Skip to main content

Agent Quick Start

View as Markdown

Run your framework's agent as a durable Dex session, then stop it in the middle of a conversation and watch it carry on. It takes about 10 minutes.

1. Get the example and run it

In one terminal, run dexcli dev (install dexcli). In a second terminal, download the example and ask the agent about an order:

curl -sL https://codeload.github.com/superdurable/dex/tar.gz/main | tar -xz --strip-components=3 dex-main/examples/python/agent-harnesses
cd agent-harnesses
uv sync --locked
uv run --frozen python -m agent_harness_examples.quick_start claude-agent-sdk "Look up order 1001"

You need Python 3.11 or later with uv. It calls Claude, so set ANTHROPIC_API_KEY first.

It prints the session ID and the agent's reply:

Session claude-agent-sdk-quick-start-<8 hex digits>
Agent: <the model's reply about order 1001>

Example: examples/python/agent-harnesses/agent_harness_examples/quick_start/__main__.py

The agent is a small order support agent with two tools. look_up_order reads an order, so Dex may retry it. cancel_order cancels an order that has not shipped; it is a write, so it runs at most once, and only after a person approves it.

2. Approve a write

Run the same command with the message Cancel order 1002. The program stops and asks:

cancel_order wants to run with {"order_id":"1002","reason":"requested by the customer"}. Approve? [y/N]

The session waits in AwaitToolApproval. Type y, and the agent cancels the order and replies. Approvals shows how your app reads and answers the waiting call, and how a person approves it in Dex Web.

3. Stop the program while the agent waits

Ask to cancel order 1002 again; each run without --session-id starts a new session. When the program asks you to approve, press Ctrl+C. The program, its Worker, and its Client stop, and the session keeps waiting in Dex.

Run the step 1 command again from the same folder, with --session-id SESSION_ID in place of the message. A new Worker starts, and the program asks about the same cancel_order call. Type y. The order is cancelled once, and the model calls before the restart stay done.

  1. WorkerRunModel calls the model. The model asks to call cancel_order.
  2. Dex Servercancel_order waits in AwaitToolApproval. Dex Server holds the wait.
  3. WorkerYou stop the program, and its Worker stops.
  4. Dex ServerThe approval keeps waiting on Dex Server. No Worker is needed.
  5. Worker, restartedYou start the program again. Its Worker connects to Dex.
  6. Dex ServerYou approve cancel_order at the program's prompt. Dex Server records the answer.
  7. Worker, restartedcancel_order runs once. The model writes the reply.
  8. Dex ServerThe turn completes.
The model call before the stop stayed done, and cancel_order ran once.

4. Stop it while a tool runs

A crash in the middle of a tool call is the harder case. The example can slow each tool call down, so you have time to stop it.

  1. Put DEX_ORDER_DESK_TOOL_DELAY_SECONDS=20 in front of the step 1 command and ask about order 1001.
  2. Within 20 seconds, kill the program as a crash would. A crash is a kill signal; Ctrl+C lets a running call finish first.
pkill -9 -f agent_harness_examples.quick_start

Example: examples/python/agent-harnesses/agent_harness_examples/quick_start/__main__.py

  1. Run the program again with --session-id and no message. The agent answers with the order.
  2. Check how the tool call ran:
dexcli flow history --all SESSION_ID | jq '.events[]
| select(.payload.context.stepType == "CallTool")
| .payload.context | {finalAttempt, failure: .lastFailureInfo.details.detail}'

finalAttempt is 2. The first attempt failed when the Worker disconnected, and because look_up_order is a read, Dex ran it again on the new Worker. The model call before it ran once.

Now do the same with a write: ask to cancel order 1002 with the delay set, approve it, kill the program within 20 seconds, and run it again with --session-id. Dex records cancel_order as outcome_unknown and runs it no second time, because it is a non-idempotent write. The agent tells the user that the outcome is unknown, and your application checks the order system before anyone tries again. Reconcile outcome_unknown shows how.

What made it durable

The example writes the agent as your framework alone would, then wraps it in a Dex agent session and gives each tool a policy. What changes in your code shows both versions for every framework.

Next

  • Add Dex to Your Agent moves this agent into your own app, with the complete files and a web app.
  • Sessions explains what survived the restart, and how your framework's turn maps onto Steps.
  • Tool Calls explains why cancel_order runs at most once, and the one narrow case where a write can run twice.
  • Built-in Agent Loop builds an agent without a framework.
  • Order Support Agent is the full example, with its HTTP routes.