Skip to content

Architecture

How a request flows through Felix end-to-end. Source of truth: felix-run/felix.

Process topology

Client → Ingress (Caddy / Traefik / nginx / CDN)
├─ felix-api (CPython 3.14, Granian, FastAPI)
├─ felix-worker (Taskiq consumer)
└─ felix-scheduler (Taskiq cron enqueue)
Postgres+pgvector · Valkey · object store (fs | s3 | gcs | memory)
Process Role
API (apps/api) HTTP surfaces, OpenAPI//docs, agent invoke/stream
Worker (apps/worker) Audit flush, jobs, memory consolidation, retention, anomaly, continuous eval, fiber resume
Scheduler Enqueues labeled Taskiq cron tasks (required alongside the worker)

The harness library lives in packages/harness (felix). The CLI is packages/cli (felix migrate|doctor|eval|mint-jwt|…).

Felix is plain CPython in containers you run. There is no serverless or edge runtime in the stack, and no vendor-specific compute or storage binding — Postgres, Valkey and an object store sit behind Protocols. Deploy with Compose or Helm — see getting started and deploy.

HTTP surfaces

create_app (apps/api) mounts:

Surface Paths
Chat POST /chat, /chat/stream, /chat/steer, /chat/fork, /chat/rewind, GET /chat/runs/{resume_token}
OpenAI-compatible POST /v1/chat/completions, GET /v1/models
A2A POST /a2a
MCP POST /mcp
Discovery GET /.well-known/agent-card.json, JWKS when configured
Management /audit, /approvals, /plans, /jobs, /manifests, /eval
Internal POST /internal/* (consumer secret when auth ≠ none)

Interactive OpenAPI UI: a running harness serves Scalar at /docs (hosted: api.felix.run/docs).

Middleware chain

Order on every request:

  1. Body limit — reject oversized payloads early.
  2. Authnone / api_key / jwt (see auth); installs RequestContext (tenant, scopes, LimitState).
  3. Rate limit — keyed by tenant; skips /health, /.well-known/*, /docs, /openapi.json, /metrics.

Self-authenticating mounts (e.g. /internal) skip bearer parsing; the router enforces its own credential (FELIX_CONSUMER_SHARED_SECRET).

Chat request lifecycle

POST /chat or /v1/chat/completions
→ auth + rate limit
→ resolve_tenant_manifest (tenant Postgres → object store → bundled)
→ prepare_tenant_invoke
enforce_inbound_auth (spec.auth.inbound: anonymous / required scopes)
ensure_thread_pin (spec.governance.pin_compile → 409 if the pointer moved)
→ apply_inbound_screening on the caller's turn
→ build_agent(manifest, deps)
validate → system prompt + skills
bind MCP / peers / sandboxes / containers / queues / browser
governance wrappers (secret masking → … → approvals)
get_pattern(spec.pattern) → Agent
optional durable wrap (fibers / Temporal)
→ agent.invoke / agent.stream_events
session strategy renders working set
model chat → tool dispatch → persist session events

Names are the actual callables: felix.runtime owns resolve_tenant_manifest and prepare_tenant_invoke, felix.manifests.builder owns build_agent, and invoke / stream_events are the two methods on the Agent protocol in felix.patterns.types.

Durability

Default durability backend is fibers (Postgres-backed sleep/step/resume; worker resumes due fibers). Set spec.execution.mode: durable to enqueue and return 202 with a resume_token. Optional Temporal (FELIX_DURABILITY + felix temporal-worker on queue felix-fibers) for external durable execution.

Background work

felix-scheduler enqueues labeled cron tasks; felix-worker consumes them. Run both, or none of the following ever fires:

Task (apps/worker) Cron Does
flush_audit */1 * * * * Drain the audit buffer to Postgres (and the optional warehouse spill)
flush_usage */1 * * * * Drain buffered token usage
run_scheduled_jobs * * * * * Sweep due jobs rows
fiber_scheduler * * * * * Wake and resume due durable fibers
continuous_eval */10 * * * * Continuous eval tick
consolidate_memory */15 * * * * Memory consolidation
anomaly_scan */30 * * * * Error-rate scan and canary auto-rollback
retention_sweep 0 3 * * * Prune expired rows and objects

Package map

Path Concern
packages/harness/src/felix/ Manifests, patterns, tools, session, governance, auth, plugins
apps/api FastAPI composition + routes
apps/worker Taskiq worker / scheduler / Temporal entrypoints
packages/cli Ops CLI
manifests/ Bundled agents (quick, deep, router, …)