Call Tool with Retry
Steps
- Record the attempt in the tool log BEFORE calling — so a crash mid-call still leaves a trail.
- Call the tool with the args.
- On success: record
ok=true, return. - On error: classify (transient vs. terminal). Backoff:
2^attemptseconds, cap 30s. - Retry up to
max_retriesonly ifidempotent=trueOR the error is provably terminal-safe-to-retry (e.g.429rate limit,503upstream). - On final failure: record
ok=falsewith the error, return.
Output shape
{
"ok": true,
"value": { ... },
"attempts": 1
}
// or
{
"ok": false,
"error": "503 upstream timeout",
"attempts": 3
}
Failure modes
- Retrying a non-idempotent POST → duplicate side effects.
- Logging after the call → crash data loss.
- Treating all 4xx as terminal —
408,429are transient. - Sleeping a literal
time.sleep(30)in a single-threaded loop → blocks the whole pipeline. Use async sleep / a job queue.