> For the complete documentation index, see [llms.txt](https://docs.drizz.dev/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.drizz.dev/twins/using-twins/see-what-your-agent-did.md).

# See what your agent did

Read every call your agent made, watch calls live, read the world's state, keep or copy a world, and delete it.

The twin records every call your agent made and what each one changed. Read it, then keep or delete the world.

|                  |                                                                                          |
| ---------------- | ---------------------------------------------------------------------------------------- |
| **Twins**        | Google Calendar · Gmail                                                                  |
| **You need**     | a world folder your agent ran in                                                         |
| **Main command** | `twin world calls world`                                                                 |
| **Watch out**    | `twin api` and `twin world save` add their own calls to the record. Read the calls first |

## Prerequisites

* A world your agent ran in. See [Run your agent](/twins/using-twins/run-your-agent.md).

## Copy this

```bash
twin world calls world --writes              # only the calls that changed something
twin world calls world --json > traces.json  # every call, for your own tools
twin world save world -o after.md            # the world as it stands, as a seed file
twin world delete world                      # done with it
```

## The record

An agent's reply says what it thinks it did. The twin records what it actually did: every call your agent made in the world, and what each call changed. You read that record, and the world's state, from the `twin` CLI or the [web console](/twins/using-twins/web-console.md).

## Read the calls

```bash
twin world calls world
```

This prints the twin's record of every call made in the world since it was seeded, Calendar and Gmail, oldest first. The twin writes the record itself. An agent that reports a call it never made, or forgets one it did, does not change it.

Narrow it down:

```bash
twin world calls world --writes                     # only the calls that changed something
twin world calls world --app gmail                  # only the mailbox's calls
twin world calls world --status error               # only the calls that failed
twin world calls world --app gmail --status error   # both
```

| Option                           | Shows                                         |
| -------------------------------- | --------------------------------------------- |
| `--writes`                       | only the calls that changed something         |
| `--app calendar` / `--app gmail` | only that app's calls                         |
| `--status ok`                    | only calls that succeeded                     |
| `--status error`                 | any failure                                   |
| `--status 4xx`                   | the caller's errors: denied, invalid, unknown |
| `--status 5xx`                   | the twin's errors                             |
| `--json`                         | JSON, for a program to read                   |

Each call in the JSON has these fields:

| Field        | What it is                               |
| ------------ | ---------------------------------------- |
| `app`        | `calendar` or `gmail`                    |
| `tool`       | the tool called, such as `events.create` |
| `status`     | how the call ended                       |
| `at`         | when it was made                         |
| `latency_ms` | how long the twin took to answer         |
| `arguments`  | what your agent sent                     |
| `changes`    | what the call changed in the world       |

{% hint style="info" %}
**What is in the record, and what is not.**

* Reading the record (`twin world calls`) is not a call. It never shows up in the record.
* The seed's own calls, and those of `twin world trigger`, are left out. They made the world; they are not your agent's.
* `twin api` and `twin world save` read the world as its owner. Their calls do show up, beside your agent's. Read the calls first if you want a record of your agent alone.
  {% endhint %}

## Watch calls live

Follow the record while your agent runs, from a second terminal:

```bash
twin world calls world --follow                 # each call as the twin records it, until Ctrl-C
twin world calls world --follow --writes        # only the changes
twin world calls world --follow --json | jq .   # one JSON object per line
```

`--follow` first prints the calls so far, then each new one. It reads the record again every second; `--interval <seconds>` changes that.

In the web console, a twin's **Runs** page shows the same calls live, with what changed and what was refused. See [Web console](/twins/using-twins/web-console.md#runs).

## Read the world's state

`twin api` calls one of the world's MCP tools, as your agent would, and prints the JSON it returns:

```bash
twin api world --list                                      # every tool, calendar and gmail
twin api world events.list -F maxResults=5                 # the primary calendar's events
twin api world events.list -f calendarId=primary -F maxResults=5
twin api world message.list --app gmail -f q="is:unread"   # unread mail
twin api world events.create --input event.json            # arguments from a file
```

| Option                           | What it does                                                                         |
| -------------------------------- | ------------------------------------------------------------------------------------ |
| `-f key=value`                   | an argument, as a string                                                             |
| `-F key=value`                   | an argument, read as JSON when it is JSON (`5`, `true`, `{"a": 1}`)                  |
| `--input file`                   | the arguments as a JSON object, from a file (`-` for stdin). `-f` and `-F` add to it |
| `--app calendar` / `--app gmail` | the server to call. By default, the one that has the tool                            |
| `--list`                         | list the tools instead of calling one                                                |

A calendar tool that needs a `calendarId` gets `primary` when you give none. `twin api` exits with status 2 when the twin answers with an error.

### Before and after

To see the whole world as it stands, write it as a seed file:

```bash
twin world save world               # print it
twin world save world -o after.md   # or keep it
```

Put `after.md` beside the seed file you started from to see what your agent changed. Each call's `changes` in `twin world calls --json` shows the same, one call at a time.

## Keep a world

There are two ways to keep a world. Pick by what you want to do with it.

|                        | `twin world save`                                             | `twin world snapshot`                                                                                         |
| ---------------------- | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- |
| Gives you              | a seed file                                                   | an exact copy, as JSON                                                                                        |
| Use it to              | read or edit the world                                        | make the same world again                                                                                     |
| Holds                  | events, other calendars and sharing, the mailbox              | everything the twin holds, for every app: each event as stored, attendees' answers, labels, settings, threads |
| Left out               | what the seed syntax cannot write, listed under `# not saved` | nothing                                                                                                       |
| In the record of calls | yes (it reads the world as its owner)                         | no                                                                                                            |
| Holds a token          | no                                                            | no                                                                                                            |

```bash
twin world snapshot world -o snap.json       # an exact copy of everything
twin world create snap.json --folder again   # the same world, made again
```

Use a snapshot to fork a run, hand a state to a teammate, or replay a bug from the exact state it happened in. `--force` on `save` and `snapshot` replaces a file that already exists.

## Export the calls

Write the record to a file for your own tools, dashboards or CI:

```bash
twin world calls world --json > traces.json
```

From Python, `world.calls()` returns the same list, and `world.calls(app="gmail", writes=True, status="error")` narrows it. `world.follow_calls()` yields each call as the twin records it, until you stop.

## Hand a world to another machine

`twin world handle` prints the world as JSON. `twin world attach` picks it up on another machine, or in a later CI step, as a local folder that the other `twin world` commands take:

```bash
twin world handle world > world.json   # on this machine
twin world attach world.json           # on the other machine
```

{% hint style="warning" %}
The handle holds the world's tokens. Treat it as a secret.
{% endhint %}

## Delete the world

When you are done, delete the world and its folder:

```bash
twin world delete world
```

`twin world delete` also takes a world's id from `twin world list`, for a world that has no folder, such as one `twin start` made:

```bash
twin world list                      # this machine's worlds, and how full your organization is
twin world delete <world-id>
```

To delete a group of worlds at once, use their label:

```bash
twin world cleanup --label demo --dry-run   # list what would be deleted
twin world cleanup --label demo             # asks first, at a terminal
twin world cleanup --label demo --yes       # in a script or CI job
twin world cleanup --label start --yes      # every world twin start made
```

| Option                   | What it does                                                                                                                                                 |
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `--label <name>`         | the worlds made with this label                                                                                                                              |
| `--all`                  | every world made on this machine, and every older `t-...` world your key can list (a teammate's older ones too). A teammate's newer worlds are never touched |
| `--older-than <seconds>` | only those made more than this long ago                                                                                                                      |
| `--dry-run`              | list what would be deleted, and delete nothing                                                                                                               |
| `--yes`, `-y`            | delete without asking. Needed where there is no terminal                                                                                                     |

A folder `twin world create` made goes too, but only when it holds nothing but the world's own files.

A world you never delete deletes itself when its lease ends: 6 hours by default, or what you set with `--lease`.

{% hint style="info" %}
If the twin could not delete a world, its folder is kept. Run `twin world delete` again. It exits with 69 when the twin is down, and 2 otherwise.
{% endhint %}

## Common mistakes

| What you write                                            | What happens                                                                                  |
| --------------------------------------------------------- | --------------------------------------------------------------------------------------------- |
| `twin api` or `twin world save` before you read the calls | Their calls land in the record, beside your agent's                                           |
| `twin world save` to copy a world exactly                 | What the seed syntax cannot write is left out, under `# not saved`. Use `twin world snapshot` |

## Next

* [Web console](/twins/using-twins/web-console.md): the same record, live, in your browser.
* [Several twins as one unit](/twins/using-twins/several-twins.md): read the calls of a whole environment.
* [CLI reference](/twins/reference/cli.md): every option of `twin world calls` and `twin api`.

***

*Last updated: 27 October 2026*
