Releases: davccavalcante/caduceus
Release list
[PUBLISHED ON NPMJS] @takk/caduceus@1.0.0
STATUS: PUBLISHED ON NPMJS. This version was published to the npm registry on 2026-06-30T00:44:15Z with provenance attestation. View on npm: https://www.npmjs.com/package/@takk/caduceus/v/1.0.0
STATUS: REVIEW REQUIRED, NOT YET ON NPMJS. This GitHub Release was created by the
release.ymlworkflow. The Creator must review the contents (tag, changelog, attached commit, pack-smoke result in the workflow logs) and then explicitly runnpm-publish.ymlto publish this version to the npm registry.
[1.0.0] - 2026-06-30T00:12:31Z
Initial stable release. Caduceus is a universal, zero-runtime-dependency NPM library and CLI that gives any provider a single shape: it normalizes OpenAI, Anthropic, and Gemini requests, responses, streams, and tool calls into one typed vocabulary, then routes each request across a pool of heterogeneous models by one of seven strategies, with per-model circuit breakers, hard USD budgets, automatic failover, and an auditable route trace that names which model answered. The core never speaks HTTP; it is routing logic over an injectable dispatch, which keeps it provider-agnostic, node-free, and testable offline. It is the open, local-first transport layer for multi-agent Massive Intelligence (IM) systems and non-human entities, and it feeds the agent pool of the @takk/coryphaeus orchestrator.
Added
Transport
Caduceus(@takk/caduceus/transport): the router most callers use. It exposesregisterProvider,registerModel,providers,models,plan(the strategy ordering and per-candidate cost forecast without any call),complete(route, fail over, and return aRouteResult),stream(route and return a normalized event stream from the first model that connects),breakerSnapshot, andresetBreakers. Route options carry a fixed request id, a strategy override, a candidate-model restriction, and a hard per-request USD ceiling. Time is an injectable clock, so latency and breaker timing are deterministic.
The compatibility matrix
encodeRequest,decodeResponse,decodeStream,collectStream,encodeResponse,streamChunksOf, andcreateEchoDispatch(@takk/caduceus/codec): the only place that knows how each provider shapes a request, a response, a token usage, a tool call, and a stream. It encodes one normalizedChatRequestinto the OpenAI, Anthropic, or Gemini wire body; decodes each provider's response and streaming events back into one typed vocabulary; translates tool definitions and tool calls in both directions; and runs in reverse so the offline echo dispatch exercises the full encode, dispatch, decode path with no network.
Strategies
STRATEGY_KINDS,createStrategy,orderCandidates, andisStrategyKind(@takk/caduceus/strategy): the seven configurable routing strategies, the opposite of a black-box gateway. Cost-then-quality, cost-first, quality-first, latency-first, weighted, round-robin, and sequential-cascade order the candidate models; the router then tries them in order, skipping open breakers and failing over on error. Round-robin carries a cursor so successive requests start at different models.
Circuit breakers
CircuitBreakerandBreakerRegistry(@takk/caduceus/breaker): one closed, open, half-open state machine per model over the injected clock. A breaker trips open after a configurable failure threshold so the router stops sending it traffic; after a cooldown it goes half-open and lets a single probe through, where a success closes it and a failure re-opens it. The registry creates a breaker per model lazily and snapshots every model's state.
Rate-limit recovery
resolveRetry,backoffDelay,isRateLimitStatus,defaultWait, and theRetryConfigandWaitFntypes (@takk/caduceus): on a rate-limit (HTTP 429) the router does not fail over blindly. It honors the provider'sRetry-After(or an exponential backoff, both capped) and retries the same model up tomaxRetriesbefore failing over, recording the retry count and total wait in the trace asretriesandwaitedMs. The wait is injectable so the policy is deterministic and node-free. The Node fetch dispatch parses theRetry-Afterheader intoretryAfterMson a 429.withKeyRotation(@takk/caduceus/adapter): wraps a per-key dispatch factory so each retry presents a fresh key, the@takk/keymeshintegration seam for key rotation and rate-limit recovery without a hard dependency. The key pool is fixed by the host.
Budget
estimateTokens,estimateRequestTokens,costOf,forecastUsd,BudgetTracker, andZERO_COST(@takk/caduceus/budget): token estimation from a request, USD pricing against a per-model cost profile (a cached rate defaults to the input rate), and a running ledger with an optional hard ceiling. The router forecasts each call andassertCanAffordraises a typedBUDGET_EXCEEDEDbefore a breaching call is dispatched. The same primitive scopes a per-request, per-task, or per-day ceiling.
Providers and models
defineProvider,defineModel,ProviderRegistry,providerId,modelId,isProviderShape,qualityOf,weightOf,costRank, andlatencyOf(@takk/caduceus/provider). A provider is an endpoint family with one wire shape; a model is a routing candidate, treated as a black box, carrying the cost, quality, and latency metadata the strategies sort on. Descriptors are validated and frozen, and a model resolves to its provider and shape through the registry.
The auditable route trace
provenanceOf,traceJson,renderTraceDot,renderTraceMermaid,sealTrace,verifyTraceSeal, andsha256Hex(@takk/caduceus/trace): every route records which models were tried, in what order, each breaker's state, each attempt's cost and latency, and which model finally answered. It renders to JSON, Graphviz DOT, or Mermaid as a transport graph, exposes the provenance of the answer, and seals with a SHA-256 digest over the Web Crypto API for tamper-evidence. The seal is an integrity seal, not a signature.
Adapters and the tool
dispatchFromVercel,dispatchFromOpenAIChat,respondWith,streamWith,withKeyRotation,agentClientFromCaduceus,createTransportTool,describeRouteTool,parseRouteToolInput,toJsonSafe, andROUTE_TOOL_NAME(@takk/caduceus/adapter). Two-line bridges wrap a Vercel AI SDK call or an OpenAI-style chat function as the injected dispatch;agentClientFromCaduceusimplements the @takk/coryphaeus AgentClient contract so the transport feeds the orchestrator's agent pool with no hard dependency; and the transport is exposed as a framework-agnostic tool (namecaduceus_route) with a JSON Schema and a JSON-safe handler, ready to register with an MCP server or any tool-calling API. Model-supplied input is parsed defensively; the pool is fixed by the host.
The injectable dispatch and the Node fetch transport
- The
Dispatchcontract is the seam that keeps the core provider-agnostic: it takes a fully encodedProviderCalland returns a decoded JSON body or a raw chunk iterable.createFetchDispatch(@takk/caduceus/node) is the real transport over the global fetch, building the chat-completions, messages, or generateContent URL for each shape and parsing Server-Sent Events into the chunk objects the codec normalizes. The Node entry also adds disk loaders (loadProviders,loadModels,loadRequest,loadTrace,readJsonFile), each defensively validated.@takk/caduceus/edgere-exports the node-free core for Cloudflare Workers, Vercel Edge, Bun, Deno, and the browser.
CLI
- The
caduceusbinary:providers(list the registered provider and model pool),plan <request.json>(the strategy ordering and a cost forecast, no network),route ... --mock(route offline with the deterministic echo dispatch, optionally writing the trace to a file), andtrace <trace.json>(render a saved trace to DOT, Mermaid, or JSON). Exit codes: 0 ok, 2 usage or input error, 21 no route could be completed, 30 the budget ceiling tripped. The CLI carries no provider credentials; real runs use the library API with the Node fetch dispatch or an injected one.
Errors
CaduceusErrorwith a stable, machine-readablecode(@takk/caduceus):INVALID_CONFIG,INVALID_PROVIDER,INVALID_MODEL,INVALID_REQUEST,INVALID_STRATEGY,INVALID_SHAPE,BUDGET_EXCEEDED,NO_ROUTE,DISPATCH_FAILED,INVALID_STATE,INVALID_SNAPSHOT,NUMERIC. Callers branch onerror.code, never on the message.
Examples and the transport benchmark
- Five runnable examples that route against the built
dist: a failover route with a DOT render, the seven strategies' orderings, a circuit breaker tripping and recovering, a hard USD budget ceiling, and a Vercel adapter plus the routing tool and the AgentClient bridge. - A transport benchmark (
benchmarks/transport-benchmark.mjs) that runs the built router over a controlled failure model on a fixed seed, 4000 requests per regime. It measures the mechanisms the transport contributes: three-way failover over independent 40% provider failures lifts the success rate from 59.4% to 93.5% (against the 93.6% theoretical bound of one minus the failure probability cubed), and a circuit breaker over one fully-down provider cuts wasted calls to it by 49.9%. It is a mechanism demonstration, not an LLM quality claim.
Engineering
- Zero required runtime dependencies; a node-free core (the trace seal uses the Web Crypto API, not
node:crypto; the fetch dispatch lives in./node); dual ESM and CJS distribution with separate.d.tsand.d.ctsper subpath; eleven functional subpath exports plus./package.json. - TypeScript 6 in maximum strict mode (
exactOptionalPropertyTypes,useUnknownInCatchVariables,noUncheckedIndexedAccess,noPropertyAccessFromIndexSignature,verbatimModuleSyntax,isolatedModules). Biome 2.5 lint clean. - 159 tests across 13 suites passing unde...