paybondpaybond
Sign in

T04 · Tutorial

Multi-step agent runs

Bind a sandbox run, execute tools under one run-id, inspect with CLI table trace.

~30 minIntermediateSandboxbuilderoperatorStep track

Outcome: bind → tool execute → run trace completes for a multi-step job.

Learning view: objectives and extras expanded. Switch for commands only.

Mental model

One intent owns many tool executes. Trace is the audit of boundary decisions — not model chain-of-thought.

You will be able to

  • Bind a sandbox run and capture run-id
  • Execute at least one registered tool under that run
  • Inspect the run with table/JSON CLI trace

Prerequisites

  • · Middleware or first guarded spend
  • · Sandbox credentials (multi-step bind needs a real session beyond pure offline mock)

Prep sandbox credentials

paybond login so multi-step run commands can call the sandbox Gateway. Offline loops cover single-smoke; multi-step binds need a real or wired session.

Goal: Fix credentials and project directory before bind complexity rises.

Bind a run

Create a run bound to policy-aligned tools. Capture run-id for subsequent tool executes.

Goal: One intent lifecycle owns every later execute.

Execute tools

Each execute checks capability and spend, runs the handler, and records evidence when side-effecting.

Goal: Drive tool ops under that run-id — authorize happens before the handler.

Trace the run

Table or JSON trace for CI; open paybond dev trace for the vertical UI on recorded events.

Goal: Inspect decisions without re-running every step by hand.

CLI sequence

Language-agnostic CLI
  1. Step 1 of 3

    Bind sandbox run

    Start a multi-step job under one intent lifecycle.

    Goal: One run-id owns every later execute.

    Run this

    paybond agent run bind --sandbox --format json

    Example response

    {
      "runId": "run_01H…",
      "binding": { "phase": "bound", "sandbox": true }
    }

    You should see: JSON includes a runId (or run-id) you can copy.

    Note: Capture runId for the next commands.

  2. Step 2 of 3

    Execute a registered tool

    Swap operation/spend to match your paybond.policy.yaml.

    Goal: You pick run-id and operation — policy decides authorize vs deny.

    Run this

    paybond agent tool execute --run-id <run-id> --operation travel.book_hotel --requested-spend-cents 20000 --format json

    Example response

    {
      "authorized": true,
      "operation": "travel.book_hotel",
      "status": "released"
    }

    You should see: Execute succeeds for a tool listed on the bound policy.

  3. Step 3 of 3

    Inspect run trace

    Headless-friendly table for CI logs.

    Goal: Confirm both execute decisions appear under the same run.

    Run this

    paybond agent run trace --run-id <run-id> --format table

    Example response

    PHASE       OP                  RESULT
    authorize   travel.book_hotel   ok
    evidence    travel.book_hotel   released

    You should see: Table rows include authorize/evidence (or denial) for executed ops.

Same lifecycle in SDK

Register several tools under one sandbox policy — same sequence as the CLI, in-process.

multi-step.ts

TS
TypeScript: paybond.instrumentSwipe to inspect long lines
// Same CLI sequence in process (TypeScript):
const instrumented = await paybond.instrument({
  policy: "./paybond.policy.yaml",
  tools: {
    "travel.book_hotel": bookHotel,
    "travel.book_flight": bookFlight,
  },
  sandbox: true,
});
// Run id / intent live on instrumented.run after sandbox bind
// Evidence auto-submits per side-effecting tool success

Result: Each side-effecting success submits evidence on the shared sandbox run.

Doctor also exercises middleware smoke when sandbox credentials are configured: paybond doctor --agent. After binds, open paybond dev trace if you want the browser timeline for the same events.

Verify before you continue

Check these off against your terminal or timeline output — progress stays on this device.

0/3

If something goes wrong

  • If you see

    Execute fails with unknown run

    Do this

    Reuse the exact run-id from bind JSON; new bind creates a new intent lifecycle.

  • If you see

    Second tool denied under same run

    Do this

    Register every paid tool on policy and intent.allowed_tools for that bind.

Self-check

Answer without scrolling up — then reveal the model answer to compare.

Why keep multiple tool executes on one run-id instead of a new bind per tool for a single user task?

Next steps

Pick a branch — not every path needs every tutorial.

Recipes are copy-paste production smokes — not repeated inside this tutorial.