TypeScriptADK-TS

Reflect and Retry Plugin

Automatically recover from tool errors with intelligent retry logic

When a tool fails, the Reflect and Retry Plugin doesn't just retry blindly — it generates structured reflection guidance so the model understands what went wrong and can retry with corrected arguments or a different approach.

This is especially useful when tools fail due to invalid parameters, transient errors, or incorrect function selection.

Quick start

import { AgentBuilder, ReflectAndRetryToolPlugin } from "@iqai/adk";

const { runner } = await AgentBuilder.withModel("gpt-4o")
  .withPlugins(new ReflectAndRetryToolPlugin({ maxRetries: 3 }))
  .build();

How it works

  1. A tool throws an error (or returns an error response)
  2. The plugin catches it and generates reflection guidance — including the original call, error message, and suggestions
  3. The model sees the guidance and retries with corrected arguments
  4. If it fails again, the cycle repeats up to maxRetries
  5. After all retries are exhausted, the error is thrown (or a final reflection message is returned, depending on config)

The plugin tracks retries independently per tool and is concurrency-safe — multiple tools can fail and retry in parallel without race conditions.

Usage

import { AgentBuilder, ReflectAndRetryToolPlugin } from "@iqai/adk";

const { runner } = await AgentBuilder.withModel("gpt-4o")
  .withDescription("Calendar scheduling assistant")
  .withPlugins(new ReflectAndRetryToolPlugin({ maxRetries: 3 }))
  .build();
import { LlmAgent, ReflectAndRetryToolPlugin } from "@iqai/adk";

const agent = new LlmAgent({
  name: "calendar_specialist",
  description: "Manages calendar and scheduling tasks",
  plugins: [new ReflectAndRetryToolPlugin({ maxRetries: 3 })],
});
import { LlmAgent, ReflectAndRetryToolPlugin, TrackingScope } from "@iqai/adk";

const agent = new LlmAgent({
  name: "robust_assistant",
  description: "Assistant with enhanced error recovery",
  plugins: [
    new ReflectAndRetryToolPlugin({
      maxRetries: 5,
      throwExceptionIfRetryExceeded: false, // return reflection instead of throwing
      trackingScope: TrackingScope.GLOBAL,   // track retries across all requests
    }),
  ],
});

Configuration

OptionTypeDefaultDescription
maxRetriesnumber3Retry attempts per tool after an error
throwExceptionIfRetryExceededbooleantrueThrow original error after retries exhausted (if false, returns reflection message)
trackingScopeTrackingScopeINVOCATIONINVOCATION resets per request, GLOBAL tracks across all requests
namestring"reflect_retry_tool_plugin"Plugin name for identification

Use INVOCATION scope (default) for user-facing agents where each request should start fresh. Use GLOBAL for system-wide rate limiting across all invocations.

Custom error detection

By default, the plugin catches exceptions thrown by tools. If your tools return error objects instead of throwing, override extractErrorFromResult:

import { ReflectAndRetryToolPlugin, LlmAgent } from "@iqai/adk";

class CustomRetryPlugin extends ReflectAndRetryToolPlugin {
  async extractErrorFromResult({
    result,
  }: {
    result: any;
  }): Promise<any | undefined> {
    if (result?.status === "error") return result;
    if (result?.error_code) {
      return {
        error: result.error_message || "Unknown error",
        code: result.error_code,
      };
    }
    return undefined; // no error detected
  }
}

const agent = new LlmAgent({
  name: "api_agent",
  description: "Agent with custom error detection",
  plugins: [new CustomRetryPlugin({ maxRetries: 5 })],
});

When to use it

  • Unreliable external APIs — transient failures, flaky services
  • Complex tool logic — tools with multiple validation steps
  • User input validation — tools that validate parameters the model provides
  • Development phase — catch and recover from edge cases during prototyping

When not to use it

  • Deterministic failures — same input will always fail (retrying won't help)
  • Security-sensitive operations — where retrying could cause issues
  • Resource-intensive operations — where retry cost is too high
  • Time-critical operations — where retry latency is unacceptable

Troubleshooting

IssueFix
Not retrying failuresCheck maxRetries > 0. For non-exception errors, implement extractErrorFromResult.
Too many retriesReduce maxRetries. Use more specific error detection. Use INVOCATION scope.
Retries not helpingThe failure may be deterministic. Check tool error messages for better guidance.
Concurrency issuesPlugin is concurrency-safe. Check for resource conflicts in your tools.

Next steps