@adaptif/server
v0.1.0
Published
The Adaptif server: request handler, providers, and outcome sinks.
Maintainers
Readme
@adaptif/server
The request handler, provider adapters, and outcome sinks that run on the developer's own server. The main entry is Fetch-API–based and has no Node-only dependencies, so it runs unmodified on Cloudflare Workers, Next.js Route Handlers, or any other Fetch-compatible runtime. Node-only concerns (the JSONL sink) live under the @adaptif/server/node subpath.
npm install @adaptif/core @adaptif/serverproviderFromEnv() builds typesafe(), openrouter(), or vercelGateway() from the server environment (TYPESAFE_API_KEY, then OPENROUTER_API_KEY, then AI_GATEWAY_API_KEY). @adaptif/next wraps createHandler as a Next.js route; other Fetch runtimes can mount the handler directly. The config object you pass is the allowlist in every environment.
Both routes require Content-Type: application/json and send no CORS headers, so they answer same-origin requests only. With debug off, a failing or timed-out provider logs one warning per minute with the error class only. See Production hardening for rate limits and timeouts.
The model-vs-rule eval behind the README's results lives in the repository at packages/server/scripts/eval/; it isn't part of the published package.
Outcome sinks
POST …/outcome validates outcome events, adds receivedAt, session, assignmentKey, and schema: 1 (never IP addresses or user agents), and passes them to createHandler's sinks. A failing sink is logged by name and never fails the request. Outcome requests are rate-limited like evaluate requests (by default 30 per session per minute).
consoleSink(): one line per event, for development.jsonlSink(path)(@adaptif/server/node): appends JSON lines, creating directories, with writes serialized. Needs a persistent disk: on serverless hosts (Vercel, Netlify, Cloudflare, Lambda) usewebhookSinkor your own sink.webhookSink(url, { headers?, batchMs?, timeoutMs? }): POSTs JSON arrays with a timeout and one retry.multiSink(...sinks): writes to several sinks; one failing doesn't stop the others.- Your own:
{ name, write(events: readonly StoredOutcomeEvent[]) }. The event format is@adaptif/core/outcome-schema.json.
