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:
- Body limit — reject oversized payloads early.
- Auth —
none/api_key/jwt(see auth); installsRequestContext(tenant, scopes,LimitState). - 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 eventsNames 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, …) |