Reflect and Retry Plugin
Automatically reflect on tool errors and retry with corrected calls in @iqai/adk
The Reflect and Retry Plugin helps your agent recover from tool execution errors by guiding the model to reflect on failures and retry with corrected arguments or strategy. It intercepts tool failures, generates structured reflection guidance, and retries the operation up to a configurable limit.
This plugin is especially useful for improving robustness when tools may fail due to invalid parameters, transient state, or incorrect function selection.
Key Capabilities
- Concurrency-safe: Uses an internal lock to safely handle parallel tool executions
- Configurable retry limits: Control how many retries are attempted per tool
- Flexible tracking scope: Track failures per invocation (default) or globally across invocations
- Per-tool failure tracking: Retry counters are tracked independently for each tool
- Extensible error detection: Override error extraction to detect failures in non-exception responses
Installation
pnpm add @iqai/adkUsage
import {
AgentBuilder,
InMemorySessionService,
ReflectAndRetryToolPlugin,
} from "@iqai/adk";
import { openrouter } from "@openrouter/ai-sdk-provider";
import { randomUUID } from "crypto";
import dedent from "dedent";
const reflectAndRetryPlugin = new ReflectAndRetryToolPlugin({
maxRetries: 3,
});
const sessionService = new InMemorySessionService();
const { runner } = await AgentBuilder.withModel(
openrouter("openai/gpt-4.1-mini"),
)
.withDescription("Calendar scheduling assistant")
.withInstruction(
dedent`
You help users manage calendar events.
If a tool call fails, carefully analyze the error
and retry with corrected arguments or a new approach.
`,
)
.withTools
/* calendar tools */
()
.withSessionService(sessionService)
.withQuickSession({
sessionId: randomUUID(),
appName: "calendar-agent",
})
.withPlugins(reflectAndRetryPlugin)
.build();import { LlmAgent, ReflectAndRetryToolPlugin } from "@iqai/adk";
const agent = new LlmAgent({
name: "calendar_specialist",
description: "Specialist agent for managing calendar and scheduling tasks",
plugins: [
new ReflectAndRetryToolPlugin({
maxRetries: 3,
}),
],
});import { LlmAgent, ReflectAndRetryToolPlugin } from "@iqai/adk";
const customRetryPlugin = new ReflectAndRetryToolPlugin({
name: "my_custom_retry_plugin",
maxRetries: 5,
throwExceptionIfRetryExceeded: false,
trackingScope: TrackingScope.GLOBAL,
});
const agent = new LlmAgent({
name: "robust_assistant",
description: "Assistant with enhanced error recovery",
plugins: [customRetryPlugin],
});Configuration Options
ReflectAndRetryToolPluginOptions
interface ReflectAndRetryToolPluginOptions {
/** Plugin name (default: "reflect_retry_tool_plugin") */
name?: string;
/** Number of retry attempts per tool after an error is detected (default: 3) */
maxRetries?: number;
/** Whether to throw the original error after retries are exhausted (default: true) */
throwExceptionIfRetryExceeded?: boolean;
/** Controls how retry counters are scoped (default: TrackingScope.INVOCATION) */
trackingScope?: TrackingScope;
}Configuration Details
-
name(optional)- Plugin name for identification
- Default:
"reflect_retry_tool_plugin"
-
maxRetries(optional)- Number of retry attempts per tool after an error is detected
- Default:
3 - Must be a non-negative integer
- Set to
0to disable retries
-
throwExceptionIfRetryExceeded(optional)- Whether to throw the original error after retries are exhausted
- Default:
true - If
false, the plugin returns a final reflection message instead
-
trackingScope(optional)- Controls how retry counters are scoped
- Default:
TrackingScope.INVOCATION - Options:
TrackingScope.INVOCATION: Track failures per invocationTrackingScope.GLOBAL: Track failures globally across all invocations
Advanced Configuration
Custom Error Detection
You can extend the ReflectAndRetryToolPlugin class to customize how errors are detected in tool responses:
import { LlmAgent, ReflectAndRetryToolPlugin } from "@iqai/adk";
class CustomRetryPlugin extends ReflectAndRetryToolPlugin {
async extractErrorFromResult({
result,
}: {
result: any;
}): Promise<any | undefined> {
// Detect error based on a response property
if (result?.status === "error") {
return result;
}
// Detect error based on specific fields
if (result?.error_code || result?.error_message) {
return {
error: result.error_message || "Unknown error",
code: result.error_code,
};
}
return undefined; // No error detected
}
}
// Use the custom plugin when creating an agent
const customReflectPlugin = new CustomRetryPlugin({
maxRetries: 5,
name: "custom_error_detector",
});
const agent = new LlmAgent({
name: "calendar_specialist",
description: "Specialist agent for managing calendar tasks",
plugins: [customReflectPlugin],
});Integration with Multiple Plugins
import { InMemoryRunner, LlmAgent } from "@iqai/adk";
import { ReflectAndRetryToolPlugin, ToolOutputFilterPlugin } from "@iqai/adk";
const plugins = [
// Filter large outputs first
new ToolOutputFilterPlugin({
filterModel: "gemini-1.5-flash",
config: { sizeThreshold: 8000, targetSize: 4000 },
}),
// Then handle any errors that occur
new ReflectAndRetryToolPlugin({
maxRetries: 3,
throwExceptionIfRetryExceeded: true,
}),
];
const runner = new InMemoryRunner(agent, {
appName: "production-app",
plugins,
});How It Works
Retry Process
- Error Detection: Monitors tool execution for failures (exceptions or custom error detection)
- Reflection Generation: Creates structured guidance for the model to understand the error
- Retry Attempt: Allows the model to retry with corrected arguments or approach
- Tracking: Maintains retry counters per tool (based on tracking scope)
- Limit Enforcement: Stops retrying after maxRetries is reached
Reflection Guidance
When a tool fails, the plugin generates context for the model including:
- Original tool call and arguments
- Error message and type
- Suggestions for correction
- Remaining retry attempts
Concurrency Safety
The plugin uses internal locking mechanisms to ensure thread-safe operation when multiple tools are executing in parallel:
- Per-tool retry counters are safely managed
- No race conditions in error tracking
- Consistent behavior across concurrent executions
Best Practices
When to Use
- Unreliable External APIs: Services that may have transient failures
- Complex Tool Logic: Tools with multiple validation steps
- User Input Validation: Tools that validate user-provided parameters
- State-dependent Operations: Tools that depend on external state
- Development Phase: During development to handle edge cases
When Not to Use
- Deterministic Failures: Errors that will always occur with the same input
- Security-sensitive Operations: Where retry could cause security issues
- Resource-intensive Operations: Where retry is too expensive
- Time-critical Operations: Where retry delay is unacceptable
Configuration Guidelines
Configuration Tips
Start with default settings and adjust based on your specific use case and failure patterns.
- Start Conservative: Begin with
maxRetries: 3and adjust based on observations - Choose Appropriate Tracking: Use
INVOCATIONscope for user-specific retries,GLOBALfor system-wide limits - Handle Exhaustion Gracefully: Set
throwExceptionIfRetryExceededbased on your error handling strategy - Monitor Retry Patterns: Track which tools fail most frequently and why
- Test Error Scenarios: Validate that your custom error detection works correctly
Troubleshooting
Common Issues
Plugin not retrying failures:
- Check if error detection is working correctly
- Verify
maxRetriesis greater than 0 - Ensure tool failures are being detected (use custom error detection if needed)
Too many retries:
- Reduce
maxRetriesvalue - Implement more specific error detection
- Use
INVOCATIONscope instead ofGLOBAL
Retries not helping:
- Analyze failure patterns to understand root cause
- Improve tool error messages for better guidance
- Consider if the failure is deterministic rather than transient
Concurrency issues:
- The plugin is designed to be concurrency-safe
- Check for external resource conflicts
- Ensure tool implementations are thread-safe
Performance Considerations
- Retry Overhead: Each retry adds latency to tool execution
- Model Context: Failed attempts consume tokens in the conversation history
- Resource Usage: Failed operations may consume external resources
- Error Detection: Custom error detection adds minimal overhead
Support
For issues with the Reflect and Retry Plugin:
- Test Error Detection: Verify your custom error detection works correctly
- Monitor Retry Patterns: Track which tools and error types trigger retries
- Review Configuration: Ensure settings match your use case requirements
- Analyze Failure Causes: Understand why tools are failing to determine if retries are appropriate