Skip to main content

Utility Decorators

Utility decorators provide performance optimization, debugging, and development assistance features for Agent Forge applications.

@Visualizer

Enables automatic generation of interactive HTML timelines for team runs, providing visual insights into agent interactions and performance.

Syntax

@Visualizer()
@llmProvider(provider, config)
@forge()
class MyTeam {
static forge: AgentForge;
}

Features

  • Interactive Timeline: Visual representation of team execution flow
  • Task Cards: Detailed task information with status tracking
  • Performance Metrics: Execution times, success rates, and statistics
  • Agent Communication: Visual mapping of agent interactions
  • Automatic Export: Generates team-run-timeline.html file

Examples

Basic Team Visualization

@Visualizer()
@llmProvider("openai", { apiKey: process.env.OPENAI_API_KEY })
@forge()
class VisualizedTeam {
static forge: AgentForge;

static async run() {
const agentClasses = [ManagerAgent, ResearcherAgent, WriterAgent];
await readyForge(VisualizedTeam, agentClasses);

// Timeline will be automatically generated
return this.forge.runTeam(
"ManagerAgent",
["ResearcherAgent", "WriterAgent"],
"Create a market analysis report"
);
}
}

Complex Team with Visualization

@tool(WebSearchTool)
@Visualizer()
@RateLimiter({ rateLimitPerSecond: 2 })
@llmProvider("openai", { apiKey: process.env.OPENAI_API_KEY })
@forge()
class ComplexVisualizedTeam {
static forge: AgentForge;

static async run() {
const agentClasses = [
ProjectManager,
ResearchSpecialist,
DataAnalyst,
ContentWriter,
QualityReviewer
];

await readyForge(ComplexVisualizedTeam, agentClasses);

const result = await this.forge.runTeam(
"ProjectManager",
["ResearchSpecialist", "DataAnalyst", "ContentWriter", "QualityReviewer"],
"Conduct comprehensive analysis of renewable energy market trends",
{
verbose: true,
stream: true
}
);

// Timeline saved to team-run-timeline.html
console.log("Timeline generated: team-run-timeline.html");
return result;
}
}

Generated Timeline Features

Visual Elements

  • Task Cards: Interactive cards showing task details, status, and timing
  • Agent Nodes: Visual representation of each agent and their roles
  • Progress Bars: Real-time progress indicators for running tasks
  • Status Colors: Color-coded status indicators (pending, running, completed, failed)
  • Dependency Lines: Visual connections showing task dependencies

Interactive Features

  • Hover Details: Detailed information on hover
  • Expandable Sections: Click to expand task details
  • Timeline Scrubbing: Navigate through execution timeline
  • Filter Options: Filter by agent, status, or time range
  • Export Options: Export timeline data or images

Performance Metrics

<!-- Generated in timeline HTML -->
<div class="stats-section">
<div class="stat-card">
<h3>Total Execution Time</h3>
<p>2m 34s</p>
</div>
<div class="stat-card">
<h3>Tasks Completed</h3>
<p>8/8</p>
</div>
<div class="stat-card">
<h3>Success Rate</h3>
<p>100%</p>
</div>
</div>

Timeline File Output

The visualizer generates a self-contained HTML file:

project/
├── team-run-timeline.html ← Generated visualization
├── src/
│ └── your-team.ts
└── package.json

Customization Options

Custom File Path

// After team run completes
import { writeTeamRunTimelineHtmlToFile } from "agent-forge";

const events = team.getTeamRunLogger()?.getEvents() || [];
await writeTeamRunTimelineHtmlToFile(events, "custom-timeline.html");

Manual Timeline Generation

import { generateTeamRunTimelineHtml } from "agent-forge";

const team = new MyTeam();
const logger = team.getTeamRunLogger();

if (logger) {
const events = logger.getEvents();
const html = generateTeamRunTimelineHtml(events);

// Custom processing of HTML
const customHtml = html.replace(/DefaultTitle/, "My Custom Timeline");

fs.writeFileSync("custom-timeline.html", customHtml);
}

@RateLimiter

Applies rate limiting to LLM calls and tool executions to prevent API abuse and manage costs.

Syntax

@RateLimiter(config: RateLimiterConfig)
@llmProvider(provider, config)
@forge()
class MyRateLimitedApp {}

Parameters

RateLimiterConfig

PropertyTypeDescription
rateLimitPerSecondnumberMaximum calls per second
rateLimitPerMinutenumberMaximum calls per minute
verbosebooleanEnable rate limiting logs
cacheTTLnumberCache TTL for tool results (ms)
toolSpecificLimitsRecord<string, RateLimit>Per-tool rate limits

ToolSpecificLimits

interface ToolSpecificLimit {
rateLimitPerSecond?: number;
rateLimitPerMinute?: number;
}

Examples

Basic Rate Limiting

@RateLimiter({
rateLimitPerSecond: 2,
rateLimitPerMinute: 100,
verbose: true
})
@llmProvider("openai", { apiKey: process.env.OPENAI_API_KEY })
@forge()
class RateLimitedTeam {
static forge: AgentForge;
}

Advanced Rate Limiting with Tool-Specific Limits

@RateLimiter({
rateLimitPerSecond: 3,
rateLimitPerMinute: 150,
verbose: true,
cacheTTL: 300000, // 5 minutes
toolSpecificLimits: {
"WebSearchTool": {
rateLimitPerSecond: 0.5, // Very conservative for web search
rateLimitPerMinute: 20
},
"CalculatorTool": {
rateLimitPerSecond: 10, // Fast for local calculations
rateLimitPerMinute: 500
},
"expensive_api": {
rateLimitPerSecond: 0.1, // Very slow for expensive APIs
rateLimitPerMinute: 5
}
}
})
@llmProvider("openai", { apiKey: process.env.OPENAI_API_KEY })
@forge()
class AdvancedRateLimitedTeam {
static forge: AgentForge;
}

Production Rate Limiting

@RateLimiter({
rateLimitPerSecond: 1,
rateLimitPerMinute: 40, // Stay well under API limits
verbose: false, // Disable verbose logging in production
cacheTTL: 600000, // 10 minute cache
toolSpecificLimits: {
"WebSearchTool": {
rateLimitPerSecond: 0.2,
rateLimitPerMinute: 10
},
"WebPageContentTool": {
rateLimitPerSecond: 0.3,
rateLimitPerMinute: 15
}
}
})
@llmProvider("openai", { apiKey: process.env.OPENAI_API_KEY })
@forge()
class ProductionTeam {
static forge: AgentForge;
}

Rate Limiter Behavior

LLM Call Rate Limiting

// All LLM calls are automatically rate limited
const result = await agent.run("Analyze this data"); // Waits for rate limit

Tool Call Rate Limiting

// Tools with specific limits are automatically throttled
@tool(WebSearchTool) // Uses toolSpecificLimits["WebSearchTool"]
@agent(config)
class SearchAgent extends Agent {}

Verbose Logging Output

[RateLimiter] Waiting for token (WebSearchTool): 1.5s remaining
[RateLimiter] Token acquired for WebSearchTool
[RateLimiter] Current usage: 2/10 per minute for WebSearchTool

Caching Integration

Rate limiting includes automatic caching for tool results:

@RateLimiter({
cacheTTL: 300000, // 5 minutes
rateLimitPerSecond: 1
})
@tool(WebSearchTool)
@agent(config)
class CachedSearchAgent extends Agent {}

// First call: hits API and caches result
await agent.run("Search for AI news");

// Second call within 5 minutes: returns cached result, no API call
await agent.run("Search for AI news"); // Cache hit!

Combined Utility Decorators

@Visualizer() // Generate timeline
@RateLimiter({
rateLimitPerSecond: 1,
rateLimitPerMinute: 50,
verbose: true,
toolSpecificLimits: {
"WebSearchTool": {
rateLimitPerSecond: 0.3,
rateLimitPerMinute: 15
}
}
})
@tool(WebSearchTool)
@llmProvider("openai", { apiKey: process.env.OPENAI_API_KEY })
@forge()
class OptimizedTeam {
static forge: AgentForge;

static async run() {
const agentClasses = [ManagerAgent, ResearcherAgent];
await readyForge(OptimizedTeam, agentClasses);

const result = await this.forge.runTeam(
"ManagerAgent",
["ResearcherAgent"],
"Research latest AI developments",
{
verbose: true, // Show team communication
stream: true // Enable streaming
}
);

console.log("✅ Team run completed");
console.log("📊 Timeline: team-run-timeline.html");
console.log("🔄 Rate limiting applied throughout execution");

return result;
}
}

Best Practices

Rate Limiting Strategy

  • Conservative Limits: Start with conservative limits and increase as needed
  • Tool-Specific: Use different limits for different tool types
  • Production vs Development: Use stricter limits in production
  • Monitoring: Enable verbose logging during development

Performance Optimization

  • Caching: Use caching for expensive or repeated operations
  • Batch Operations: Group related operations when possible
  • Fallback Strategies: Have backup plans when rate limits are hit

Visualization Usage

  • Development: Use visualization during development to understand team behavior
  • Debugging: Generate timelines when debugging complex team interactions
  • Documentation: Use generated timelines to document team workflows
  • Optimization: Analyze timelines to identify performance bottlenecks

Monitoring and Debugging

Rate Limiter Status

// Access rate limiter instance (if needed for debugging)
const forge = MyTeam.forge;
const llmProvider = forge.getDefaultLLMProvider();
const rateLimiter = (llmProvider as any).__rateLimiter;

if (rateLimiter) {
console.log("Rate limiter active");
// rateLimiter provides internal monitoring capabilities
}

Timeline Analysis

// Access team run events for analysis
@Visualizer()
@forge()
class AnalyzableTeam {
static forge: AgentForge;

static async analyzeRun() {
const team = this.forge.createTeam("Manager", "AnalysisTeam");
const logger = team.getTeamRunLogger();

if (logger) {
const events = logger.getEvents();

// Analyze execution patterns
const taskEvents = events.filter(e => e.type.includes("task"));
const avgExecutionTime = taskEvents.reduce((sum, e) =>
sum + (e.details.duration || 0), 0) / taskEvents.length;

console.log(`Average task execution: ${avgExecutionTime}ms`);
}
}
}