Check what your agent called

Your agent’s final answer looks right. Its tool calls changed anyway.

A prompt edit can drop a verification step or change the destination passed to a write operation. Checking the final response alone leaves those differences out of your regression report.

tool-call-diff compares two recorded tool-call arrays and returns added calls, removed calls, position changes, and argument drift. Each argument difference includes its path, so you can inspect a nested field without reading both traces line by line.

The endpoint costs 0.008 USDC per call, paid through x402 on Base mainnet. Route a task here when you’ve already captured both runs and need a structural comparison. Your regression policy decides which differences are acceptable.

Send the baseline and changed arrays

Use POST with a JSON body containing before and after. Both fields are required arrays, each with a maximum of 500 entries.

Here’s an illustrative regression fixture. The changed run moves verify_record behind save_record, and the save destination changes:

{
  "before": [
    {
      "name": "verify_record",
      "args": { "record_id": "R-104" }
    },
    {
      "name": "save_record",
      "args": {
        "record_id": "R-104",
        "destination": { "folder": "review" }
      }
    }
  ],
  "after": [
    {
      "name": "save_record",
      "args": {
        "record_id": "R-104",
        "destination": { "folder": "published" }
      }
    },
    {
      "name": "verify_record",
      "args": { "record_id": "R-104" }
    }
  ]
}

These tool names belong to the example agent’s trace. Replace them with the names your runner records.

The endpoint accepts {name, args} objects. If your recorder uses {tool, arguments}, that shape works too. Keep arguments as structured JSON when you want differences inside nested objects; a serialized JSON string gets compared as a string.

For this fixture, the response includes:

{
  "before_count": 2,
  "after_count": 2,
  "added": [],
  "removed": [],
  "reordered": [
    {
      "name": "verify_record",
      "index_before": 0,
      "index_after": 1
    },
    {
      "name": "save_record",
      "index_before": 1,
      "index_after": 0
    }
  ],
  "arg_drifted": [
    {
      "index_before": 1,
      "index_after": 0,
      "name": "save_record",
      "arg_diffs": [
        {
          "path": "$.destination.folder",
          "before": "review",
          "after": "published"
        }
      ]
    }
  ],
  "unchanged_count": 0,
  "identical": false
}

And there’s the review target: save_record moved ahead of verification while its destination became published.

Read each difference on its own terms

added contains unmatched calls from the changed run. removed contains unmatched baseline calls. Both include the call’s index and its name, with arguments attached for inspection.

reordered reports matched calls whose absolute array positions changed. An inserted call at the beginning can shift every later call, so a long reorder list doesn’t automatically mean their relative execution order reversed. Read the indexes alongside additions and removals.

Argument changes appear in arg_drifted, under each matched call’s arg_diffs. Paths start at $; nested properties use dot notation, and array entries use bracket notation. The example’s $.destination.folder identifies the field that changed.

A call can appear in both reordered and arg_drifted. That’s why adding the list lengths won’t give you a count of distinct affected calls.

Make the regression gate explicit

For a strict replay check, require identical to be true. That flag means there were no differences across the four reported categories. unchanged_count counts matched calls whose arguments and positions stayed the same.

But repeated tool names need care. Calls match by name and occurrence order: the first search matches the first search in the other run. Inserting an extra search near the beginning can therefore change which arguments get paired. Keep the original traces available during review.

Before comparing runs, replace expected timestamp differences with a fixed test value. Keep action-bearing fields intact. A destination change deserves inspection even if the agent produced the same final answer.

So give your CI check a concrete rule: fail on any removed verify_record, and require review whenever $.destination.folder changes. Attach the returned diff to the failed case so the reviewer can inspect the exact call indexes before accepting a new baseline.