tasq/node_modules/agentic-flow/dist/examples/use-provider-fallback.js

177 lines
7.0 KiB
JavaScript

/**
* Example: Long-Running Agent with Provider Fallback
*
* This example demonstrates:
* - Automatic provider fallback
* - Cost optimization
* - Health monitoring
* - Checkpointing for crash recovery
* - Budget constraints
*/
import { LongRunningAgent } from '../core/long-running-agent.js';
async function main() {
console.log('🚀 Starting Long-Running Agent with Provider Fallback\n');
// Configure providers with priorities and costs
const providers = [
{
name: 'gemini',
apiKey: process.env.GOOGLE_GEMINI_API_KEY,
priority: 1, // Try Gemini first (fastest, cheapest)
maxRetries: 3,
timeout: 30000,
costPerToken: 0.00015, // $0.15 per 1M tokens
enabled: !!process.env.GOOGLE_GEMINI_API_KEY,
healthCheckInterval: 60000 // Check every minute
},
{
name: 'anthropic',
apiKey: process.env.ANTHROPIC_API_KEY,
priority: 2, // Fallback to Claude (higher quality)
maxRetries: 3,
timeout: 60000,
costPerToken: 0.003, // $3 per 1M tokens (Sonnet)
enabled: !!process.env.ANTHROPIC_API_KEY,
healthCheckInterval: 60000
},
{
name: 'openrouter',
apiKey: process.env.OPENROUTER_API_KEY,
priority: 3, // Fallback to OpenRouter
maxRetries: 3,
timeout: 60000,
costPerToken: 0.001, // Varies by model
enabled: !!process.env.OPENROUTER_API_KEY,
healthCheckInterval: 60000
},
{
name: 'onnx',
priority: 4, // Last resort (local, free but slower)
maxRetries: 2,
timeout: 120000,
costPerToken: 0, // FREE
enabled: true,
healthCheckInterval: 300000 // Check every 5 minutes
}
];
// Create agent with cost and performance optimization
const agent = new LongRunningAgent({
agentName: 'research-and-code-agent',
providers,
fallbackStrategy: {
type: 'cost-optimized', // Prefer cheaper providers
maxFailures: 3, // Open circuit breaker after 3 failures
recoveryTime: 60000, // Try recovery after 1 minute
retryBackoff: 'exponential',
costThreshold: 0.50, // Max $0.50 per request
latencyThreshold: 30000 // Max 30s per request
},
checkpointInterval: 30000, // Save state every 30 seconds
maxRuntime: 3600000, // Max 1 hour
costBudget: 5.00 // Max $5 total spend
});
await agent.start();
try {
// Simulate long-running workflow with different task complexities
console.log('\n📋 Task 1: Simple Code Generation (Gemini optimal)\n');
const task1 = await agent.executeTask({
name: 'generate-hello-world',
complexity: 'simple',
estimatedTokens: 200,
execute: async (provider) => {
console.log(` Using provider: ${provider}`);
// Simulated API call
await new Promise(resolve => setTimeout(resolve, 1000));
return { code: 'console.log("Hello World");', provider };
}
});
console.log(` ✅ Result:`, task1);
console.log('\n📋 Task 2: Complex Architecture Design (Claude optimal)\n');
const task2 = await agent.executeTask({
name: 'design-microservices-architecture',
complexity: 'complex',
estimatedTokens: 5000,
execute: async (provider) => {
console.log(` Using provider: ${provider}`);
await new Promise(resolve => setTimeout(resolve, 2000));
return {
architecture: 'Event-driven microservices with CQRS',
provider
};
}
});
console.log(` ✅ Result:`, task2);
console.log('\n📋 Task 3: Medium Refactoring (Auto-optimized)\n');
const task3 = await agent.executeTask({
name: 'refactor-legacy-code',
complexity: 'medium',
estimatedTokens: 1500,
execute: async (provider) => {
console.log(` Using provider: ${provider}`);
await new Promise(resolve => setTimeout(resolve, 1500));
return {
refactored: true,
improvements: ['Better naming', 'Modular design'],
provider
};
}
});
console.log(` ✅ Result:`, task3);
// Simulate provider failure for demonstration
console.log('\n📋 Task 4: Testing Fallback (Simulated Failure)\n');
let failureCount = 0;
const task4 = await agent.executeTask({
name: 'test-fallback',
complexity: 'simple',
estimatedTokens: 300,
execute: async (provider) => {
console.log(` Attempting with provider: ${provider}`);
// Simulate failure on first two attempts
if (failureCount < 2) {
failureCount++;
throw new Error('Simulated rate limit error');
}
await new Promise(resolve => setTimeout(resolve, 1000));
return {
message: 'Success after fallback!',
provider,
attempts: failureCount + 1
};
}
});
console.log(` ✅ Result:`, task4);
// Get final status
console.log('\n📊 Final Agent Status:\n');
const status = agent.getStatus();
console.log(JSON.stringify(status, null, 2));
console.log('\n💰 Cost Summary:\n');
const metrics = agent.getMetrics();
console.log('Total Cost:', `$${metrics.costs.total.toFixed(4)}`);
console.log('Total Tokens:', metrics.costs.totalTokens.toLocaleString());
console.log('\nBy Provider:');
for (const [provider, cost] of Object.entries(metrics.costs.byProvider)) {
console.log(` ${provider}: $${cost.toFixed(4)}`);
}
console.log('\n📈 Provider Health:\n');
for (const health of metrics.health) {
console.log(`${health.provider}:`);
console.log(` Healthy: ${health.isHealthy}`);
console.log(` Success Rate: ${(health.successRate * 100).toFixed(1)}%`);
console.log(` Avg Latency: ${health.averageLatency.toFixed(0)}ms`);
console.log(` Circuit Breaker: ${health.circuitBreakerOpen ? 'OPEN' : 'CLOSED'}`);
console.log('');
}
}
catch (error) {
console.error('❌ Agent execution failed:', error);
}
finally {
await agent.stop();
console.log('\n✅ Agent stopped successfully\n');
}
}
// Run example
if (import.meta.url === `file://${process.argv[1]}`) {
main().catch(console.error);
}
export { main as runProviderFallbackExample };
//# sourceMappingURL=use-provider-fallback.js.map