Plugin System
Why Plugins?
The plugin system is the only way to programmatically extend agent functionality beyond the built-in capabilities. While agents themselves are markdown-based and declarative, plugins provide a JavaScript/TypeScript interface for:
- Custom integrations: Connect agents to your existing systems, databases, or APIs
- Observability: Add monitoring, logging, or analytics to track agent performance
- Automation workflows: Trigger actions based on agent completion or failure
- Development tools: Build debugging utilities or testing frameworks
- Cross-agent functionality: Share logic across all agents without modifying each one
Without plugins, you would be limited to the tools and capabilities built into AgentUse. Plugins bridge the gap between AgentUse’s declarative agent definitions and your custom programmatic needs.
Quick Start
- Create a plugin directory:
mkdir -p .agentuse/plugins
- Add a plugin file (
.js
or .ts
):
// .agentuse/plugins/my-plugin.js
export default {
'agent:complete': async (event) => {
console.log(`Agent ${event.agent.name} completed!`);
}
};
- Run your agent normally - plugins auto-load!
Plugin Locations
Plugins are automatically loaded from:
./.agentuse/plugins/*.{ts,js}
- Project-specific plugins (loaded first)
~/.agentuse/plugins/*.{ts,js}
- User-global plugins (loaded second)
Note: Project-specific plugins take precedence and are loaded before global plugins. All plugins with the same event handler will execute in the order they are loaded.
Plugin Structure
Each plugin must export a default object with event handlers:
export default {
'agent:complete': async (event) => {
// Handle agent completion
}
};
Available Events
agent:complete
Fired when an agent successfully completes execution.
Event data:
{
agent: {
name: string; // Agent name
model: string; // Model used (e.g., "anthropic:claude-sonnet-4-0")
description?: string; // Agent description from YAML frontmatter
filePath?: string; // Path to agent file
};
result: {
text: string; // Final output text
duration: number; // Execution time in seconds
tokens?: number; // Total tokens used
toolCalls: number; // Number of tool calls made
toolCallTraces?: ToolCallTrace[]; // Detailed timing for each tool/sub-agent/LLM call
};
isSubAgent: boolean; // True if this is a sub-agent
consoleOutput: string; // Full console output including logs and results
}
The toolCallTraces
array provides detailed performance information for each operation during agent execution:
interface ToolCallTrace {
name: string; // Tool, sub-agent, or model name
type: 'tool' | 'subagent' | 'llm';
startTime: number; // Unix timestamp in ms
duration: number; // Duration in ms
tokens?: number; // Total tokens used (for sub-agents and LLM calls)
promptTokens?: number; // Input tokens (for LLM calls)
completionTokens?: number; // Output tokens (for LLM calls)
}
Trace Types:
tool
: Function tool calls (bash commands, file operations, etc.)
subagent
: Sub-agent executions
llm
: Direct LLM model calls
Use Cases:
- Performance monitoring and optimization
- Cost tracking for token usage
- Debugging slow operations
- Analytics and reporting
Example: Slack Notifications
// .agentuse/plugins/slack.js
export default {
'agent:complete': async (event) => {
const webhookUrl = process.env.SLACK_WEBHOOK_URL;
// Skip if no webhook or if sub-agent
if (!webhookUrl || event.isSubAgent) {
return;
}
await fetch(webhookUrl, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
text: `✅ Agent "${event.agent.name}" completed`,
attachments: [{
color: 'good',
fields: [
{ title: 'Duration', value: `${event.result.duration.toFixed(1)}s`, short: true },
{ title: 'Tokens', value: event.result.tokens?.toString() || 'N/A', short: true },
{ title: 'Tool Calls', value: event.result.toolCalls.toString(), short: true }
]
}]
})
});
}
};
Set your webhook URL:
export SLACK_WEBHOOK_URL=https://hooks.slack.com/services/YOUR/WEBHOOK/URL
Display detailed performance traces for agent executions using toolCallTraces
:
// .agentuse/plugins/trace-reporter.js
export default {
'agent:complete': async (event) => {
// Only process if traces are available and not a sub-agent
if (!event.result.toolCallTraces || event.isSubAgent) {
return;
}
console.log("\n📊 Performance Traces:");
// Display each trace with appropriate icon
for (const trace of event.result.toolCallTraces) {
const icon =
trace.type === 'llm' ? '🧠' :
trace.type === 'subagent' ? '🤖' : '🔧';
console.log(` ${icon} ${trace.name}: ${trace.duration}ms`);
if (trace.tokens) {
console.log(` └─ Tokens: ${trace.tokens}`);
}
}
// Summary statistics
const llmCalls = event.result.toolCallTraces.filter(t => t.type === 'llm');
const toolCalls = event.result.toolCallTraces.filter(t => t.type === 'tool');
const subagentCalls = event.result.toolCallTraces.filter(t => t.type === 'subagent');
console.log("\n📈 Summary:");
console.log(` LLM calls: ${llmCalls.length} (${llmCalls.reduce((sum, t) => sum + t.duration, 0)}ms total)`);
console.log(` Tool calls: ${toolCalls.length} (${toolCalls.reduce((sum, t) => sum + t.duration, 0)}ms total)`);
console.log(` Sub-agents: ${subagentCalls.length} (${subagentCalls.reduce((sum, t) => sum + t.duration, 0)}ms total)`);
}
};
This plugin outputs performance information like:
📊 Performance Traces:
🧠 anthropic:claude-sonnet-4-0: 1234ms
└─ Tokens: 450
🔧 bash: 567ms
🤖 code-reviewer: 8901ms
└─ Tokens: 1200
🧠 anthropic:claude-sonnet-4-0_segment_2: 2345ms
└─ Tokens: 320
📈 Summary:
LLM calls: 2 (3579ms total)
Tool calls: 1 (567ms total)
Sub-agents: 1 (8901ms total)
Ready to Use: Find this complete plugin in templates/plugins/trace-reporter.js
. Copy it to .agentuse/plugins/
to start tracking performance.
You can extend the basic trace reporting with more advanced features:
- Slow Operation Detection: Warn about operations taking longer than 5 seconds
- Token Usage Tracking: Monitor prompt and completion tokens with cost estimates
- Operation Breakdown: Categorize calls by type (tool, sub-agent, LLM)
- Historical Logging: Save performance data to
.agentuse/performance.log
- Smart Filtering: Skip sub-agent executions to avoid duplicate logging
- Cost Analysis: Calculate estimated costs based on token usage
- Performance Thresholds: Set alerts for operations exceeding time or token limits
- Dashboards: Export data to monitoring services like Datadog or Grafana
- Comparative Analysis: Compare performance across different models or agent versions
TypeScript Support
For TypeScript plugins, import the types:
// .agentuse/plugins/my-plugin.ts
import type { PluginHandlers } from 'agentuse/plugin/types';
const plugin: PluginHandlers = {
'agent:complete': async (event) => {
// Full type safety and intellisense
console.log(`Agent ${event.agent.name} completed!`);
console.log(`Console output: ${event.consoleOutput}`);
}
};
export default plugin;
Error Handling
- Plugin loading errors are caught and logged as warnings, but don’t prevent the agent from running
- Invalid plugin formats (non-object default exports) are skipped with a warning message
- Plugin execution errors are caught and logged but don’t fail agent execution
- Missing plugin directories are handled gracefully
- Plugins can be disabled by removing/renaming the file
Best Practices
- Check
event.isSubAgent
to avoid duplicate notifications
- Use environment variables for configuration
- Keep plugins focused on a single responsibility
- Handle errors gracefully within your plugin
- Use TypeScript for better type safety
Implementation Details
- Plugins are loaded using dynamic imports with absolute paths
- Plugin handlers are executed asynchronously in parallel
- Multiple plugins can handle the same event
- Console output is captured during agent execution and made available to plugins
- Plugin require cache is cleared for hot-reloading during development