Agentoria

Resilience

Retry, fallback, rate limiting, circuit breaking — production hardening for agent calls.

The agent loop is only as reliable as the calls underneath it. @agentoria/runtime ships composable primitives for the failure modes real apps hit.

Retry

Both providers already retry transient failures (429 / 5xx / network) with exponential backoff, jitter, and Retry-After. For your own fetch calls, resilientFetch does the same:

import { resilientFetch } from '@agentoria/runtime';

const res = await resilientFetch(url, init, { maxRetries: 2, retryBaseMs: 250 });

Fallback

Re-route a single failed call to a backup provider:

import { withFallback } from '@agentoria/runtime';

const provider = withFallback(primary, backup); // tries each until one starts streaming

Circuit breaker

Stop hammering a provider that's already down. After N consecutive failures it trips open and fails fast, then lets a single probe through to test recovery:

import { circuitBreaker } from '@agentoria/runtime';

const guarded = circuitBreaker((req) => provider.complete(req), {
  failureThreshold: 5,
  resetTimeoutMs: 30_000,
  onStateChange: (from, to) => log(`circuit ${from} → ${to}`),
});

Rate limiting

Cap concurrency and request rate — the layer between retry and a cost budget:

import { semaphore, tokenBucket, RateLimitedError } from '@agentoria/runtime';

const gate = semaphore(4);                                   // ≤ 4 concurrent turns
const bucket = tokenBucket({ capacity: 20, refillPerSec: 5 }); // burst 20, then 5/s

if (!bucket.tryAcquire()) throw new RateLimitedError(bucket.timeUntil());
const reply = await gate.run(() => agent.run(req));

semaphore is timer-free and FIFO-fair; tokenBucket is clock-injectable, so both are trivially testable.

On this page