agentic-flow 1.9.2 → 1.9.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +86 -0
- package/README.md +104 -0
- package/dist/cli-proxy.js +38 -6
- package/dist/core/long-running-agent.js +219 -0
- package/dist/core/provider-manager.js +434 -0
- package/dist/examples/use-provider-fallback.js +176 -0
- package/dist/proxy/anthropic-to-gemini.js +50 -15
- package/dist/proxy/proxy/anthropic-to-gemini.js +439 -0
- package/dist/proxy/utils/logger.js +59 -0
- package/docs/LANDING-PAGE-PROVIDER-CONTENT.md +204 -0
- package/docs/PROVIDER-FALLBACK-GUIDE.md +619 -0
- package/docs/PROVIDER-FALLBACK-SUMMARY.md +418 -0
- package/package.json +1 -1
- package/validation/test-provider-fallback.ts +285 -0
- package/wasm/reasoningbank/reasoningbank_wasm_bg.js +2 -2
- package/wasm/reasoningbank/reasoningbank_wasm_bg.wasm +0 -0
|
@@ -0,0 +1,619 @@
|
|
|
1
|
+
# Provider Fallback & Dynamic Switching Guide
|
|
2
|
+
|
|
3
|
+
**Production-grade LLM provider fallback for long-running agents**
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The `ProviderManager` and `LongRunningAgent` classes provide enterprise-grade provider fallback, health monitoring, cost optimization, and automatic recovery for long-running AI agents.
|
|
8
|
+
|
|
9
|
+
### Key Features
|
|
10
|
+
|
|
11
|
+
- ✅ **Automatic Fallback** - Seamless switching between providers on failure
|
|
12
|
+
- ✅ **Circuit Breaker** - Prevents cascading failures with automatic recovery
|
|
13
|
+
- ✅ **Health Monitoring** - Real-time provider health tracking
|
|
14
|
+
- ✅ **Cost Optimization** - Intelligent provider selection based on cost/performance
|
|
15
|
+
- ✅ **Retry Logic** - Exponential/linear backoff for transient errors
|
|
16
|
+
- ✅ **Checkpointing** - Save/restore agent state for crash recovery
|
|
17
|
+
- ✅ **Budget Control** - Hard limits on spending and runtime
|
|
18
|
+
- ✅ **Performance Tracking** - Latency, success rate, and token usage metrics
|
|
19
|
+
|
|
20
|
+
## Quick Start
|
|
21
|
+
|
|
22
|
+
### Basic Provider Fallback
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
import { ProviderManager, ProviderConfig } from 'agentic-flow/core/provider-manager';
|
|
26
|
+
|
|
27
|
+
// Configure providers
|
|
28
|
+
const providers: ProviderConfig[] = [
|
|
29
|
+
{
|
|
30
|
+
name: 'gemini',
|
|
31
|
+
apiKey: process.env.GOOGLE_GEMINI_API_KEY,
|
|
32
|
+
priority: 1, // Try first
|
|
33
|
+
maxRetries: 3,
|
|
34
|
+
timeout: 30000,
|
|
35
|
+
costPerToken: 0.00015,
|
|
36
|
+
enabled: true
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
name: 'anthropic',
|
|
40
|
+
apiKey: process.env.ANTHROPIC_API_KEY,
|
|
41
|
+
priority: 2, // Fallback
|
|
42
|
+
maxRetries: 3,
|
|
43
|
+
timeout: 60000,
|
|
44
|
+
costPerToken: 0.003,
|
|
45
|
+
enabled: true
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
name: 'onnx',
|
|
49
|
+
priority: 3, // Last resort (free, local)
|
|
50
|
+
maxRetries: 2,
|
|
51
|
+
timeout: 120000,
|
|
52
|
+
costPerToken: 0,
|
|
53
|
+
enabled: true
|
|
54
|
+
}
|
|
55
|
+
];
|
|
56
|
+
|
|
57
|
+
// Initialize manager
|
|
58
|
+
const manager = new ProviderManager(providers, {
|
|
59
|
+
type: 'priority', // or 'cost-optimized', 'performance-optimized', 'round-robin'
|
|
60
|
+
maxFailures: 3,
|
|
61
|
+
recoveryTime: 60000,
|
|
62
|
+
retryBackoff: 'exponential'
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
// Execute with automatic fallback
|
|
66
|
+
const { result, provider, attempts } = await manager.executeWithFallback(
|
|
67
|
+
async (providerName) => {
|
|
68
|
+
// Your LLM API call here
|
|
69
|
+
return await callLLM(providerName, prompt);
|
|
70
|
+
}
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
console.log(`Success with ${provider} after ${attempts} attempts`);
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Long-Running Agent
|
|
77
|
+
|
|
78
|
+
```typescript
|
|
79
|
+
import { LongRunningAgent } from 'agentic-flow/core/long-running-agent';
|
|
80
|
+
|
|
81
|
+
// Create agent
|
|
82
|
+
const agent = new LongRunningAgent({
|
|
83
|
+
agentName: 'research-agent',
|
|
84
|
+
providers,
|
|
85
|
+
fallbackStrategy: {
|
|
86
|
+
type: 'cost-optimized',
|
|
87
|
+
maxFailures: 3,
|
|
88
|
+
recoveryTime: 60000,
|
|
89
|
+
retryBackoff: 'exponential',
|
|
90
|
+
costThreshold: 0.50, // Max $0.50 per request
|
|
91
|
+
latencyThreshold: 30000 // Max 30s per request
|
|
92
|
+
},
|
|
93
|
+
checkpointInterval: 30000, // Save state every 30s
|
|
94
|
+
maxRuntime: 3600000, // Max 1 hour
|
|
95
|
+
costBudget: 5.00 // Max $5 total
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
await agent.start();
|
|
99
|
+
|
|
100
|
+
// Execute tasks with automatic provider selection
|
|
101
|
+
const result = await agent.executeTask({
|
|
102
|
+
name: 'analyze-code',
|
|
103
|
+
complexity: 'complex', // 'simple' | 'medium' | 'complex'
|
|
104
|
+
estimatedTokens: 5000,
|
|
105
|
+
execute: async (provider) => {
|
|
106
|
+
return await analyzeCode(provider, code);
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
// Get status
|
|
111
|
+
const status = agent.getStatus();
|
|
112
|
+
console.log(`Completed: ${status.completedTasks}, Cost: $${status.totalCost}`);
|
|
113
|
+
|
|
114
|
+
await agent.stop();
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Fallback Strategies
|
|
118
|
+
|
|
119
|
+
### 1. Priority-Based (Default)
|
|
120
|
+
|
|
121
|
+
Tries providers in priority order (1 = highest).
|
|
122
|
+
|
|
123
|
+
```typescript
|
|
124
|
+
{
|
|
125
|
+
type: 'priority',
|
|
126
|
+
maxFailures: 3,
|
|
127
|
+
recoveryTime: 60000,
|
|
128
|
+
retryBackoff: 'exponential'
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
**Use Case:** Prefer specific provider (e.g., Claude for quality)
|
|
133
|
+
|
|
134
|
+
### 2. Cost-Optimized
|
|
135
|
+
|
|
136
|
+
Selects cheapest provider for estimated token count.
|
|
137
|
+
|
|
138
|
+
```typescript
|
|
139
|
+
{
|
|
140
|
+
type: 'cost-optimized',
|
|
141
|
+
maxFailures: 3,
|
|
142
|
+
recoveryTime: 60000,
|
|
143
|
+
retryBackoff: 'exponential',
|
|
144
|
+
costThreshold: 0.50 // Max $0.50 per request
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
**Use Case:** High-volume applications, budget constraints
|
|
149
|
+
|
|
150
|
+
### 3. Performance-Optimized
|
|
151
|
+
|
|
152
|
+
Selects provider with best latency and success rate.
|
|
153
|
+
|
|
154
|
+
```typescript
|
|
155
|
+
{
|
|
156
|
+
type: 'performance-optimized',
|
|
157
|
+
maxFailures: 3,
|
|
158
|
+
recoveryTime: 60000,
|
|
159
|
+
retryBackoff: 'exponential',
|
|
160
|
+
latencyThreshold: 30000 // Max 30s
|
|
161
|
+
}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
**Use Case:** Real-time applications, user-facing services
|
|
165
|
+
|
|
166
|
+
### 4. Round-Robin
|
|
167
|
+
|
|
168
|
+
Distributes load evenly across providers.
|
|
169
|
+
|
|
170
|
+
```typescript
|
|
171
|
+
{
|
|
172
|
+
type: 'round-robin',
|
|
173
|
+
maxFailures: 3,
|
|
174
|
+
recoveryTime: 60000,
|
|
175
|
+
retryBackoff: 'exponential'
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
**Use Case:** Load balancing, testing multiple providers
|
|
180
|
+
|
|
181
|
+
## Task Complexity Heuristics
|
|
182
|
+
|
|
183
|
+
The system applies intelligent heuristics based on task complexity:
|
|
184
|
+
|
|
185
|
+
### Simple Tasks → Prefer Gemini/ONNX
|
|
186
|
+
```typescript
|
|
187
|
+
await agent.executeTask({
|
|
188
|
+
name: 'format-code',
|
|
189
|
+
complexity: 'simple', // Fast, cheap providers preferred
|
|
190
|
+
estimatedTokens: 200,
|
|
191
|
+
execute: async (provider) => formatCode(code)
|
|
192
|
+
});
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
**Rationale:** Simple tasks don't need Claude's reasoning power
|
|
196
|
+
|
|
197
|
+
### Medium Tasks → Auto-Optimized
|
|
198
|
+
```typescript
|
|
199
|
+
await agent.executeTask({
|
|
200
|
+
name: 'refactor-function',
|
|
201
|
+
complexity: 'medium', // Balance cost/quality
|
|
202
|
+
estimatedTokens: 1500,
|
|
203
|
+
execute: async (provider) => refactorFunction(code)
|
|
204
|
+
});
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
**Rationale:** Uses fallback strategy (cost/performance)
|
|
208
|
+
|
|
209
|
+
### Complex Tasks → Prefer Claude
|
|
210
|
+
```typescript
|
|
211
|
+
await agent.executeTask({
|
|
212
|
+
name: 'design-architecture',
|
|
213
|
+
complexity: 'complex', // Quality matters most
|
|
214
|
+
estimatedTokens: 5000,
|
|
215
|
+
execute: async (provider) => designArchitecture(requirements)
|
|
216
|
+
});
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
**Rationale:** Complex reasoning benefits from Claude's capabilities
|
|
220
|
+
|
|
221
|
+
## Circuit Breaker
|
|
222
|
+
|
|
223
|
+
Prevents cascading failures by temporarily disabling failing providers.
|
|
224
|
+
|
|
225
|
+
### How It Works
|
|
226
|
+
|
|
227
|
+
1. **Failure Tracking:** Count consecutive failures per provider
|
|
228
|
+
2. **Threshold:** Open circuit after N failures (configurable)
|
|
229
|
+
3. **Recovery:** Automatically recover after timeout
|
|
230
|
+
4. **Fallback:** Use next available provider
|
|
231
|
+
|
|
232
|
+
### Configuration
|
|
233
|
+
|
|
234
|
+
```typescript
|
|
235
|
+
{
|
|
236
|
+
maxFailures: 3, // Open circuit after 3 consecutive failures
|
|
237
|
+
recoveryTime: 60000, // Try recovery after 60 seconds
|
|
238
|
+
retryBackoff: 'exponential' // 1s, 2s, 4s, 8s, 16s...
|
|
239
|
+
}
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### Monitoring
|
|
243
|
+
|
|
244
|
+
```typescript
|
|
245
|
+
const health = manager.getHealth();
|
|
246
|
+
|
|
247
|
+
health.forEach(h => {
|
|
248
|
+
console.log(`${h.provider}:`);
|
|
249
|
+
console.log(` Circuit Breaker: ${h.circuitBreakerOpen ? 'OPEN' : 'CLOSED'}`);
|
|
250
|
+
console.log(` Consecutive Failures: ${h.consecutiveFailures}`);
|
|
251
|
+
console.log(` Success Rate: ${(h.successRate * 100).toFixed(1)}%`);
|
|
252
|
+
});
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
## Cost Tracking & Optimization
|
|
256
|
+
|
|
257
|
+
### Real-Time Cost Monitoring
|
|
258
|
+
|
|
259
|
+
```typescript
|
|
260
|
+
const costs = manager.getCostSummary();
|
|
261
|
+
|
|
262
|
+
console.log(`Total: $${costs.total.toFixed(4)}`);
|
|
263
|
+
console.log(`Tokens: ${costs.totalTokens.toLocaleString()}`);
|
|
264
|
+
|
|
265
|
+
for (const [provider, cost] of Object.entries(costs.byProvider)) {
|
|
266
|
+
console.log(` ${provider}: $${cost.toFixed(4)}`);
|
|
267
|
+
}
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
### Budget Constraints
|
|
271
|
+
|
|
272
|
+
```typescript
|
|
273
|
+
const agent = new LongRunningAgent({
|
|
274
|
+
agentName: 'budget-agent',
|
|
275
|
+
providers,
|
|
276
|
+
costBudget: 10.00, // Hard limit: $10
|
|
277
|
+
// ... other config
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
// Agent automatically stops when budget exceeded
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
### Cost-Per-Provider Configuration
|
|
284
|
+
|
|
285
|
+
```typescript
|
|
286
|
+
const providers: ProviderConfig[] = [
|
|
287
|
+
{
|
|
288
|
+
name: 'gemini',
|
|
289
|
+
costPerToken: 0.00015, // $0.15 per 1M tokens
|
|
290
|
+
// ...
|
|
291
|
+
},
|
|
292
|
+
{
|
|
293
|
+
name: 'anthropic',
|
|
294
|
+
costPerToken: 0.003, // $3 per 1M tokens (Sonnet)
|
|
295
|
+
// ...
|
|
296
|
+
},
|
|
297
|
+
{
|
|
298
|
+
name: 'onnx',
|
|
299
|
+
costPerToken: 0, // FREE (local)
|
|
300
|
+
// ...
|
|
301
|
+
}
|
|
302
|
+
];
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
## Health Monitoring
|
|
306
|
+
|
|
307
|
+
### Automatic Health Checks
|
|
308
|
+
|
|
309
|
+
```typescript
|
|
310
|
+
const providers: ProviderConfig[] = [
|
|
311
|
+
{
|
|
312
|
+
name: 'gemini',
|
|
313
|
+
healthCheckInterval: 60000, // Check every minute
|
|
314
|
+
// ...
|
|
315
|
+
}
|
|
316
|
+
];
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
### Manual Health Check
|
|
320
|
+
|
|
321
|
+
```typescript
|
|
322
|
+
const health = manager.getHealth();
|
|
323
|
+
|
|
324
|
+
health.forEach(h => {
|
|
325
|
+
console.log(`${h.provider}:`);
|
|
326
|
+
console.log(` Healthy: ${h.isHealthy}`);
|
|
327
|
+
console.log(` Success Rate: ${(h.successRate * 100).toFixed(1)}%`);
|
|
328
|
+
console.log(` Avg Latency: ${h.averageLatency.toFixed(0)}ms`);
|
|
329
|
+
console.log(` Error Rate: ${(h.errorRate * 100).toFixed(1)}%`);
|
|
330
|
+
});
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
### Metrics Collection
|
|
334
|
+
|
|
335
|
+
```typescript
|
|
336
|
+
const metrics = manager.getMetrics();
|
|
337
|
+
|
|
338
|
+
metrics.forEach(m => {
|
|
339
|
+
console.log(`${m.provider}:`);
|
|
340
|
+
console.log(` Total Requests: ${m.totalRequests}`);
|
|
341
|
+
console.log(` Successful: ${m.successfulRequests}`);
|
|
342
|
+
console.log(` Failed: ${m.failedRequests}`);
|
|
343
|
+
console.log(` Avg Latency: ${m.averageLatency.toFixed(0)}ms`);
|
|
344
|
+
console.log(` Total Cost: $${m.totalCost.toFixed(4)}`);
|
|
345
|
+
});
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
## Checkpointing & Recovery
|
|
349
|
+
|
|
350
|
+
### Automatic Checkpoints
|
|
351
|
+
|
|
352
|
+
```typescript
|
|
353
|
+
const agent = new LongRunningAgent({
|
|
354
|
+
agentName: 'checkpoint-agent',
|
|
355
|
+
providers,
|
|
356
|
+
checkpointInterval: 30000, // Save every 30 seconds
|
|
357
|
+
// ...
|
|
358
|
+
});
|
|
359
|
+
|
|
360
|
+
await agent.start();
|
|
361
|
+
|
|
362
|
+
// Agent automatically saves checkpoints every 30s
|
|
363
|
+
// On crash, restore from last checkpoint
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
### Manual Checkpoint Management
|
|
367
|
+
|
|
368
|
+
```typescript
|
|
369
|
+
// Get all checkpoints
|
|
370
|
+
const metrics = agent.getMetrics();
|
|
371
|
+
const checkpoints = metrics.checkpoints;
|
|
372
|
+
|
|
373
|
+
// Restore from specific checkpoint
|
|
374
|
+
const lastCheckpoint = checkpoints[checkpoints.length - 1];
|
|
375
|
+
agent.restoreFromCheckpoint(lastCheckpoint);
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
### Checkpoint Data
|
|
379
|
+
|
|
380
|
+
```typescript
|
|
381
|
+
interface AgentCheckpoint {
|
|
382
|
+
timestamp: Date;
|
|
383
|
+
taskProgress: number; // 0-1
|
|
384
|
+
currentProvider: string;
|
|
385
|
+
totalCost: number;
|
|
386
|
+
totalTokens: number;
|
|
387
|
+
completedTasks: number;
|
|
388
|
+
failedTasks: number;
|
|
389
|
+
state: Record<string, any>; // Custom state
|
|
390
|
+
}
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
## Retry Logic
|
|
394
|
+
|
|
395
|
+
### Exponential Backoff (Recommended)
|
|
396
|
+
|
|
397
|
+
```typescript
|
|
398
|
+
{
|
|
399
|
+
retryBackoff: 'exponential'
|
|
400
|
+
}
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
**Delays:** 1s, 2s, 4s, 8s, 16s, 30s (max)
|
|
404
|
+
|
|
405
|
+
**Use Case:** Rate limits, transient errors
|
|
406
|
+
|
|
407
|
+
### Linear Backoff
|
|
408
|
+
|
|
409
|
+
```typescript
|
|
410
|
+
{
|
|
411
|
+
retryBackoff: 'linear'
|
|
412
|
+
}
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
**Delays:** 1s, 2s, 3s, 4s, 5s, 10s (max)
|
|
416
|
+
|
|
417
|
+
**Use Case:** Predictable retry patterns
|
|
418
|
+
|
|
419
|
+
### Retryable Errors
|
|
420
|
+
|
|
421
|
+
Automatically retried:
|
|
422
|
+
- `rate limit`
|
|
423
|
+
- `timeout`
|
|
424
|
+
- `connection`
|
|
425
|
+
- `network`
|
|
426
|
+
- HTTP 503, 502, 429
|
|
427
|
+
|
|
428
|
+
Non-retryable errors fail immediately:
|
|
429
|
+
- Authentication errors
|
|
430
|
+
- Invalid requests
|
|
431
|
+
- HTTP 4xx (except 429)
|
|
432
|
+
|
|
433
|
+
## Production Best Practices
|
|
434
|
+
|
|
435
|
+
### 1. Multi-Provider Strategy
|
|
436
|
+
|
|
437
|
+
```typescript
|
|
438
|
+
const providers: ProviderConfig[] = [
|
|
439
|
+
// Primary: Fast & cheap for simple tasks
|
|
440
|
+
{ name: 'gemini', priority: 1, costPerToken: 0.00015 },
|
|
441
|
+
|
|
442
|
+
// Fallback: High quality for complex tasks
|
|
443
|
+
{ name: 'anthropic', priority: 2, costPerToken: 0.003 },
|
|
444
|
+
|
|
445
|
+
// Emergency: Free local inference
|
|
446
|
+
{ name: 'onnx', priority: 3, costPerToken: 0 }
|
|
447
|
+
];
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
### 2. Cost Optimization
|
|
451
|
+
|
|
452
|
+
```typescript
|
|
453
|
+
// Use cost-optimized strategy for high-volume
|
|
454
|
+
const agent = new LongRunningAgent({
|
|
455
|
+
agentName: 'production-agent',
|
|
456
|
+
providers,
|
|
457
|
+
fallbackStrategy: {
|
|
458
|
+
type: 'cost-optimized',
|
|
459
|
+
costThreshold: 0.50
|
|
460
|
+
},
|
|
461
|
+
costBudget: 100.00 // Daily budget
|
|
462
|
+
});
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
### 3. Health Monitoring
|
|
466
|
+
|
|
467
|
+
```typescript
|
|
468
|
+
// Monitor provider health every minute
|
|
469
|
+
const providers: ProviderConfig[] = [
|
|
470
|
+
{
|
|
471
|
+
name: 'gemini',
|
|
472
|
+
healthCheckInterval: 60000,
|
|
473
|
+
enabled: true
|
|
474
|
+
}
|
|
475
|
+
];
|
|
476
|
+
|
|
477
|
+
// Check health before critical operations
|
|
478
|
+
const health = manager.getHealth();
|
|
479
|
+
const unhealthy = health.filter(h => !h.isHealthy);
|
|
480
|
+
|
|
481
|
+
if (unhealthy.length > 0) {
|
|
482
|
+
console.warn('Unhealthy providers:', unhealthy.map(h => h.provider));
|
|
483
|
+
}
|
|
484
|
+
```
|
|
485
|
+
|
|
486
|
+
### 4. Graceful Degradation
|
|
487
|
+
|
|
488
|
+
```typescript
|
|
489
|
+
// Prefer quality, fallback to cost
|
|
490
|
+
const providers: ProviderConfig[] = [
|
|
491
|
+
{ name: 'anthropic', priority: 1 }, // Best quality
|
|
492
|
+
{ name: 'gemini', priority: 2 }, // Cheaper fallback
|
|
493
|
+
{ name: 'onnx', priority: 3 } // Always available
|
|
494
|
+
];
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
### 5. Circuit Breaker Tuning
|
|
498
|
+
|
|
499
|
+
```typescript
|
|
500
|
+
{
|
|
501
|
+
maxFailures: 5, // More tolerant in production
|
|
502
|
+
recoveryTime: 300000, // 5 minutes before retry
|
|
503
|
+
retryBackoff: 'exponential'
|
|
504
|
+
}
|
|
505
|
+
```
|
|
506
|
+
|
|
507
|
+
## Docker Validation
|
|
508
|
+
|
|
509
|
+
### Build Image
|
|
510
|
+
|
|
511
|
+
```bash
|
|
512
|
+
docker build -f Dockerfile.provider-fallback -t agentic-flow-provider-fallback .
|
|
513
|
+
```
|
|
514
|
+
|
|
515
|
+
### Run Tests
|
|
516
|
+
|
|
517
|
+
```bash
|
|
518
|
+
# With Gemini API key
|
|
519
|
+
docker run --rm \
|
|
520
|
+
-e GOOGLE_GEMINI_API_KEY=your_key_here \
|
|
521
|
+
agentic-flow-provider-fallback
|
|
522
|
+
|
|
523
|
+
# ONNX only (no API key needed)
|
|
524
|
+
docker run --rm agentic-flow-provider-fallback
|
|
525
|
+
```
|
|
526
|
+
|
|
527
|
+
### Expected Output
|
|
528
|
+
|
|
529
|
+
```
|
|
530
|
+
✅ Provider Fallback Validation Test
|
|
531
|
+
====================================
|
|
532
|
+
|
|
533
|
+
📋 Testing Provider Manager...
|
|
534
|
+
|
|
535
|
+
1️⃣ Building TypeScript...
|
|
536
|
+
✅ Build complete
|
|
537
|
+
|
|
538
|
+
2️⃣ Running provider fallback example...
|
|
539
|
+
Using Gemini API key: AIza...
|
|
540
|
+
🚀 Starting Long-Running Agent with Provider Fallback
|
|
541
|
+
|
|
542
|
+
📋 Task 1: Simple Code Generation (Gemini optimal)
|
|
543
|
+
Using provider: gemini
|
|
544
|
+
✅ Result: { code: 'console.log("Hello World");', provider: 'gemini' }
|
|
545
|
+
|
|
546
|
+
📋 Task 2: Complex Architecture Design (Claude optimal)
|
|
547
|
+
Using provider: anthropic
|
|
548
|
+
✅ Result: { architecture: 'Event-driven microservices', provider: 'anthropic' }
|
|
549
|
+
|
|
550
|
+
📈 Provider Health:
|
|
551
|
+
gemini:
|
|
552
|
+
Healthy: true
|
|
553
|
+
Success Rate: 100.0%
|
|
554
|
+
Circuit Breaker: CLOSED
|
|
555
|
+
|
|
556
|
+
✅ All provider fallback tests passed!
|
|
557
|
+
```
|
|
558
|
+
|
|
559
|
+
## API Reference
|
|
560
|
+
|
|
561
|
+
### ProviderManager
|
|
562
|
+
|
|
563
|
+
```typescript
|
|
564
|
+
class ProviderManager {
|
|
565
|
+
constructor(providers: ProviderConfig[], strategy: FallbackStrategy);
|
|
566
|
+
|
|
567
|
+
selectProvider(
|
|
568
|
+
taskComplexity?: 'simple' | 'medium' | 'complex',
|
|
569
|
+
estimatedTokens?: number
|
|
570
|
+
): Promise<ProviderType>;
|
|
571
|
+
|
|
572
|
+
executeWithFallback<T>(
|
|
573
|
+
requestFn: (provider: ProviderType) => Promise<T>,
|
|
574
|
+
taskComplexity?: 'simple' | 'medium' | 'complex',
|
|
575
|
+
estimatedTokens?: number
|
|
576
|
+
): Promise<{ result: T; provider: ProviderType; attempts: number }>;
|
|
577
|
+
|
|
578
|
+
getMetrics(): ProviderMetrics[];
|
|
579
|
+
getHealth(): ProviderHealth[];
|
|
580
|
+
getCostSummary(): { total: number; byProvider: Record<ProviderType, number>; totalTokens: number };
|
|
581
|
+
destroy(): void;
|
|
582
|
+
}
|
|
583
|
+
```
|
|
584
|
+
|
|
585
|
+
### LongRunningAgent
|
|
586
|
+
|
|
587
|
+
```typescript
|
|
588
|
+
class LongRunningAgent {
|
|
589
|
+
constructor(config: LongRunningAgentConfig);
|
|
590
|
+
|
|
591
|
+
start(): Promise<void>;
|
|
592
|
+
stop(): Promise<void>;
|
|
593
|
+
|
|
594
|
+
executeTask<T>(task: {
|
|
595
|
+
name: string;
|
|
596
|
+
complexity: 'simple' | 'medium' | 'complex';
|
|
597
|
+
estimatedTokens?: number;
|
|
598
|
+
execute: (provider: string) => Promise<T>;
|
|
599
|
+
}): Promise<T>;
|
|
600
|
+
|
|
601
|
+
getStatus(): AgentStatus;
|
|
602
|
+
getMetrics(): AgentMetrics;
|
|
603
|
+
restoreFromCheckpoint(checkpoint: AgentCheckpoint): void;
|
|
604
|
+
}
|
|
605
|
+
```
|
|
606
|
+
|
|
607
|
+
## Examples
|
|
608
|
+
|
|
609
|
+
See `src/examples/use-provider-fallback.ts` for complete working examples.
|
|
610
|
+
|
|
611
|
+
## Support
|
|
612
|
+
|
|
613
|
+
- **GitHub Issues:** https://github.com/ruvnet/agentic-flow/issues
|
|
614
|
+
- **Documentation:** https://github.com/ruvnet/agentic-flow#readme
|
|
615
|
+
- **Discord:** Coming soon
|
|
616
|
+
|
|
617
|
+
## License
|
|
618
|
+
|
|
619
|
+
MIT - See LICENSE file for details
|