Statewave

June 25, 2026 · View on GitHub

CI License: Apache 2.0 Python 3.11+ PyPI Docker Pulls

Statewave is the open-source memory runtime that gives AI agents reproducible, provenance-tagged context — without sampling-noise from query-time retrieval.

If Statewave is useful to you, a ⭐ on the repo helps others discover it.

v1.3.0 — actively developed. Changelog · Roadmap · Limitations

🎯 Try it

The interactive comparison demo is embedded directly in the website at statewave.ai — open the chat widget to see two identical AI agents answer the same question, one stateless and one backed by Statewave.

🚀 Skip to Getting Started →

The problem

Most AI applications have no memory. Every conversation starts from scratch. Context is lost between sessions, decisions aren't remembered, and user history disappears the moment a session ends. Bolting on a vector database or dumping chat logs into a prompt doesn't solve this — it creates fragile, unstructured context that degrades as it scales.

What Statewave does

Statewave gives your AI system durable, structured memory with a clear data lifecycle:

  1. Ingest — record raw events (episodes) as they happen, append-only
  2. Compile — extract typed, summarised memories with confidence scores and provenance
  3. Retrieve — assemble ranked, token-bounded context bundles ready for your prompts
  4. Govern — inspect subject timelines, trace every memory to its source, delete by subject

Everything is organised around subjects — a user, account, agent, repo, or any entity you track.

Statewave is not a chatbot framework, a vector database, a RAG pipeline, or a hosted service. It is infrastructure you run alongside your application.

How it works

Statewave reads raw events, compiles them once per subject change into typed memories, and assembles a token-bounded context bundle on demand. Each bundle carries provenance back to its source episodes — the same query against the same subject at the same point in time always produces the same bytes. That determinism is what separates compile-then-use from query-time retrieval, where sampling noise leaks into every answer.

How Statewave works: events → compiled memories → ranked, token-bounded context bundle with provenance

Idempotent at every step — recompiling a subject produces no duplicates; reassembling a bundle for the same task at the same point in time returns the same bytes.

Capabilities

The runtime essentials. Full capability inventory →

  • Compiled context bundles — ranked, token-bounded, deterministic per subject and task
  • Provenance — every memory traces back to its source episodes; receipts are content-hashed
  • Pluggable compilers — heuristic (regex, fully local) or LLM (any LiteLLM provider)
  • Subject-organiseduser:, repo:, account:, or any entity prefix you choose
  • State-assembly receipts — immutable, ULID-addressable record of which memories influenced each bundle. HMAC-SHA256 signature (v0.9), embedded policy snapshot (v0.9), and POST /v1/receipts/{id}/replay for "what would today's code say with the original rules?"
  • Sensitivity labels + policy engine — declarative YAML policies (deny / redact) over per-memory tags (pii, financial, secret, …) with log_only and enforce modes. v0.9 adds advisory suggested_labels from heuristic detectors (pii.email/phone, financial.card, secret.token) with operator review + explicit promotion via the admin app
  • Multi-tenant — query-scoped data isolation via X-Tenant-ID header, per-tenant config and policies. v0.9 adds per-tenant region pinning for residency: requests for a tenant pinned to eu are 403'd at any process running in another region
  • Self-hosted on Postgres + pgvector — no vendor lock-in; runs on your infrastructure

Why Statewave

  • Your AI remembers — preferences, decisions, history persist across sessions
  • Context is structured, not dumped — ranked retrieval with token budgets, not raw chat-log stuffing
  • Provenance is built in — every memory traces back to its source episodes
  • You own the storage — self-hosted, open source, no vendor lock-in. Episodes and compiled memories live in your Postgres. The default heuristic compiler runs fully local; choose an LLM compiler or hosted embeddings if you want them. See Privacy & Data Flow.
  • No GPU required — the API process is CPU-only. GPUs only enter the picture if you self-host an LLM compiler or embedding model. See Hardware & Scaling.
  • Framework-neutral — works with any AI stack, any language, via REST API or typed SDKs

Quickstart

from statewave import StatewaveClient

with StatewaveClient("http://localhost:8100") as sw:
    sw.create_episode(subject_id="user-42", source="chat", type="message",
                      payload={"text": "Alice asked about pricing tiers"})
    sw.compile_memories("user-42")
    print(sw.get_context("user-42", task="answer pricing", max_tokens=1000).assembled_context)

That's the loop: ingest → compile → use — ranked, token-bounded context with provenance. Run the server below, or self-host with Docker / Helm. Full SDK docs: statewave-py (Python) · statewave-ts (TypeScript).

Use cases

Three runnable examples in statewave-examples:

  • Customer support agent — returning customer recognised across sessions, ranked context with token budget, provenance tracing, handoff pack on escalation. (Python · TypeScript)
  • Long-running coding agent — multi-session project memory: tech stack, preferences, architecture decisions persist between conversations. (Python · TypeScript)
  • Stateless vs memory-powered agent (live LLM) — full loop with a real LLM (any LiteLLM provider) running side by side with and without Statewave so you can A/B the difference yourself. (Python)

Plus the minimal quickstart, docs-grounded support, eval suite (56 assertions across 23 tests), a benchmark, and drop-in framework integrationsLangChain, CrewAI, and AutoGen — in the examples repo.

Run the server

Fastest — one line to a running server:

# macOS / Linux
npx @statewavedev/statewave
# or
curl -fsSL https://www.statewave.ai/install | sh
# Windows (PowerShell)
irm https://www.statewave.ai/install.ps1 | iex

Prefer to run it yourself?

git clone https://github.com/smaramwbc/statewave && cd statewave
docker compose up -d

Brings up Postgres (pgvector) + the API; migrations run automatically on container start. The API is available at http://localhost:8100.

By default the server boots in demo mode — stub hash-based embeddings + the heuristic compiler, no real semantic search. For LLM-backed behaviour, add a .env next to docker-compose.yml and re-run docker compose up -d to pick it up:

STATEWAVE_EMBEDDING_PROVIDER=litellm
STATEWAVE_LITELLM_API_KEY=sk-...            # any LiteLLM provider
STATEWAVE_LITELLM_MODEL=gpt-4o-mini
STATEWAVE_LITELLM_EMBEDDING_MODEL=text-embedding-3-small
EndpointPurpose
http://localhost:8100/docsOpenAPI (Swagger)
http://localhost:8100/redocReDoc
GET /healthz or GET /healthLiveness check
GET /readyz or GET /readyReadiness check

Check GET /readyz to confirm your LLM key was picked up — if the llm check shows "detail":"STATEWAVE_LITELLM_API_KEY is not set", the key isn't being read (re-check that .env sits next to docker-compose.yml and re-run docker compose up -d).

See the full getting started guide for step-by-step setup including environment configuration.

API

MethodPathDescription
POST/v1/episodesIngest a single episode (append-only)
POST/v1/episodes/batchIngest up to 100 episodes at once
POST/v1/memories/compileCompile memories from episodes (idempotent)
GET/v1/memories/searchSearch by kind, text, or semantic similarity
POST/v1/contextAssemble ranked, token-bounded context bundle
GET/v1/timelineChronological subject timeline
GET/v1/subjectsList known subjects with episode/memory counts
DELETE/v1/subjects/{id}Permanently delete all data for a subject
POST/v1/resolutionsTrack issue resolution state per session
GET/v1/resolutionsList resolutions for a subject
POST/v1/handoffGenerate compact handoff context pack
GET/v1/subjects/{id}/healthCustomer health score with explainable factors
GET/v1/subjects/{id}/slaSLA metrics — response time, resolution time, breaches

Full reference: API v1 contract.

Supported platforms

SurfaceSupported
Python3.11+ (CI runs 3.11; 3.12 / 3.13 expected to work but not gated in CI yet)
OS — serverLinux verified in CI; macOS + Windows usually fine for local dev but not CI-tested
Docker imagelinux/amd64 and linux/arm64
DatabasePostgreSQL 14+ with pgvector ≥ 0.4.2
LLM provider (compiler)Any of 100+ LiteLLM-supported providers — OpenAI, Anthropic, Azure, Bedrock, Ollama, Cohere, Gemini, Mistral, Groq, …
Embedding providerAny LiteLLM-supported, plus stub (local heuristic, no API key)
SDKsPython (pip install statewave) · TypeScript (npm install @statewavedev/sdk)

FAQ

How is this different from other memory systems? Most memory layers store isolated facts and retrieve them per query; some extract a graph whose retrieval surface can return the same summary regardless of the question. Statewave compiles the context once per subject change, with provenance — which is what buys the higher multi-hop accuracy in our benchmarks.

Does it work with my model provider? Yes — Statewave uses LiteLLM so any of 100+ providers work (OpenAI, Anthropic, Azure, Bedrock, Ollama, Groq, Cohere, Gemini, Mistral, …). Set STATEWAVE_LITELLM_MODEL to any LiteLLM identifier.

What's the license — can I use this commercially? Yes. Statewave (server + SDKs) is Apache-2.0 — a permissive license with an explicit patent grant. Use it freely in proprietary, hosted, or commercial products with no source-disclosure obligations. See LICENSING.md.

Can I self-host? Yes — that's the default. Docker Compose, Helm chart, or bare-metal. See Deployment guide.

Why does it cost more tokens per answer than a plain fact store? Compiled context bundles are denser than fact-store retrieval — that's what buys the higher multi-hop accuracy. If your queries are mostly single-hop and you're cost-sensitive, a lighter fact store may be the right call.

Connectors

Statewave is not limited to live chat transcripts. Connectors feed real-world events into Statewave as episodes, so your agents can build memory from repos, communities, docs, support tools, email, and workflows — without you hand-writing an ingest path for each source.

SourceMemory shapeStatus
MCP serverCopilot / Claude / Cursor / agent memory✅ shipped
GitHubIssues, pull requests, reviews, releases → repo memory✅ shipped
MarkdownLocal docs, ADRs, RFCs → decision memory✅ shipped
SlackChannel + thread history (pull) + Events-API webhook (push, with opt-in DMs and group DMs) → team memory✅ shipped
n8nWorkflow runs, failures, per-node errors → workflow memory✅ shipped
Zapier"Webhooks by Zapier" → push-mode helper for any zap✅ shipped
DiscordServer channel + thread history → community memory✅ shipped
NotionPages + opt-in body content + database scoping → decision memory✅ shipped
Zendesk / Intercom / FreshdeskTickets + replies + notes (pull) and real-time webhook receivers (push) → customer memory✅ shipped
GmailQuery-scoped messages (pull, with History-API delta sync) and Cloud Pub/Sub push receiver → relationship memory✅ shipped

Connectors live in their own repository so this core stays focused on the runtime. They are modular — install only what you need:

# Pick what you need — every package is independent
npm install @statewavedev/connectors-github
npm install @statewavedev/connectors-jira          # preview
npm install @statewavedev/connectors-database      # preview — postgres/mysql/mariadb/mssql
npm install @statewavedev/connectors-markdown
npm install @statewavedev/connectors-slack
npm install @statewavedev/connectors-n8n
npm install @statewavedev/connectors-zapier
npm install @statewavedev/mcp-server

A convenience meta-package @statewavedev/connectors re-exports the official connectors for the rare case where you want them all at once. It is not required for normal usage.

Quick examples (dry-run-first — nothing is ingested without your say-so):

statewave-connectors sync github \
  --repo smaramwbc/statewave \
  --subject repo:smaramwbc/statewave \
  --dry-run

statewave-connectors sync markdown \
  --path ./docs \
  --subject repo:smaramwbc/statewave \
  --dry-run

statewave-connectors mcp start

Where to go next:

No connector code lives in this repo. Connectors talk to Statewave through the same public HTTP API documented above. If you don't need any of them, you don't install any of them.

Configuration

All settings use the STATEWAVE_ env prefix. Copy .env.example to .env to get started.

For best results: Set STATEWAVE_COMPILER_TYPE=llm and STATEWAVE_EMBEDDING_PROVIDER=litellm with an STATEWAVE_LITELLM_API_KEY. Statewave uses LiteLLM as its single provider abstraction, so you can use any supported provider — OpenAI, Anthropic, Azure, Ollama, Cohere, Gemini, Bedrock, Mistral, Groq, and 100+ others — by setting STATEWAVE_LITELLM_MODEL to any LiteLLM model identifier (e.g. gpt-4o-mini, claude-3-haiku-20240307, ollama/llama3, azure/gpt-4). The heuristic compiler still works without any LLM API key.

VariableDefaultDescription
STATEWAVE_DATABASE_URLpostgresql+asyncpg://statewave:statewave@localhost:5432/statewavePostgres connection string
STATEWAVE_DEBUGfalseEnable debug logging
STATEWAVE_COMPILER_TYPEheuristicheuristic or llm
STATEWAVE_EMBEDDING_PROVIDERstubstub, litellm, or none
STATEWAVE_LITELLM_API_KEYProvider-neutral API key (e.g. OpenAI sk-..., Anthropic sk-ant-...) — passed through to the provider chosen by STATEWAVE_LITELLM_MODEL
STATEWAVE_LITELLM_MODELgpt-4o-miniChat-completion model — any LiteLLM identifier (claude-3-haiku-20240307, ollama/llama3, azure/gpt-4, etc.)
STATEWAVE_LITELLM_EMBEDDING_MODELtext-embedding-3-smallEmbedding model — any LiteLLM-supported (cohere/embed-english-v3.0, voyage/voyage-large-2, …)
STATEWAVE_LITELLM_API_BASECustom base URL (e.g. http://localhost:11434 for Ollama, or a self-hosted OpenAI-compatible gateway)
STATEWAVE_LITELLM_TIMEOUT_SECONDS60Request timeout
STATEWAVE_LITELLM_MAX_RETRIES2Retries on transient errors
STATEWAVE_EMBEDDING_DIMENSIONS1536Embedding vector dimensions
STATEWAVE_API_KEYAPI key for auth (empty = open access)
STATEWAVE_RATE_LIMIT_RPM0Requests/min/IP (0 = disabled)
STATEWAVE_RATE_LIMIT_STRATEGYdistributeddistributed (Postgres) or memory (in-process)
STATEWAVE_WEBHOOK_URLWebhook callback URL (empty = disabled)
STATEWAVE_WEBHOOK_TIMEOUT5.0Webhook HTTP timeout in seconds
STATEWAVE_WEBHOOK_EVENTSComma-separated event-type allowlist (empty = deliver every event)
STATEWAVE_RECEIPT_SIGNING_KEYSJSON {"<key_id>": "<base64>"} map of HMAC keys for receipt signing (≥32 bytes each). Never persisted to the DB; per-tenant active key id set via tenant_configs.config.receipt_signing_key_id.
STATEWAVE_AUTO_LABELING_ENABLEDfalseRun heuristic detectors at compile time and stamp advisory suggested_labels on memories (v0.9). See docs/auto-labeling.md.
STATEWAVE_AUTO_LABELING_PROVIDERheuristicDetector provider. Only heuristic is currently supported (since v0.9); the switch is reserved for future LLM-based classifiers.
STATEWAVE_REGIONRegion this server process is running in. When set, requests for tenants pinned to a different region are refused with HTTP 403 residency.mismatch (v0.9). Empty = single-region mode, residency disabled. See docs/residency.md.
STATEWAVE_TENANT_HEADERX-Tenant-IDHeader for multi-tenant isolation
STATEWAVE_REQUIRE_TENANTfalseReject requests without tenant header
STATEWAVE_DEFAULT_MAX_CONTEXT_TOKENS4000Default token budget for context assembly
STATEWAVE_CORS_ORIGINS["*"]Allowed CORS origins

Running tests

# Unit tests (no DB required)
pytest tests/test_*.py -v

# Integration tests (requires Postgres)
PGPASSWORD=statewave createdb -h localhost -U statewave statewave_test
pytest tests/integration/ -v

# All tests
pytest tests/ -v

Current limitations

Statewave is in active development (v1.3.0). Honest status:

  • Rate limiting is per-IP — distributed (Postgres-backed), but keyed by IP only, not per-tenant or per-API-key yet
  • Multi-tenant is app-layer — query-scoped data isolation (v0.5) + per-tenant config / policy bundles / receipts (v0.8) + HMAC-signed audit + tenant region pin (v0.9), but no Postgres RLS yet
  • No built-in auth provider — validates API keys you configure, doesn't issue them
  • No admin-action identity yet — the v0.9 auto-labeling promote endpoint stamps promoted_at + labels on every promotion, but promoted_by is null until an admin-identity layer ships
  • No visual policy editor — policy bundles are authored as YAML in git and uploaded through the admin workflow; a no-YAML form-based editor is deferred to a future admin release
  • No federated cross-region audit — v0.9 ships strict per-region isolation by design; operators running multiple regions cannot search receipts or memories across regions from a single console yet. Federated audit should be added explicitly later, not through implicit cross-region access
  • Replay is "current code + original policy" — v0.9 receipt replay re-runs the original retrieval against today's memories using the original policy bundle (frozen on every v0.9+ receipt). Byte-for-byte historical reproduction needs memory snapshots, which are deferred

See the roadmap for what's being fixed and when.

Horizontal scaling. Statewave runs multi-replica in production (Fly multi-machine + Helm HPA both verified). The policy bundle cache that previously assumed single-process was dropped in v0.8 (#77) precisely so multi-replica deploys behave correctly under enforce mode. Heavy load is bottlenecked by Postgres + your embedding provider, not the API.

Documentation

Getting startedClone, run, ingest your first episode
What is Statewave?Product overview, use cases, limitations
Why Statewave?Technical comparison for support-agent workflows
API v1 contractFull endpoint reference
Architecture overviewSystem design and data flow
Compiler modesHeuristic vs LLM — when to use which
Privacy & data flowWhat stays local, what leaves your network
Hardware & scalingGPU is never required; scaling characteristics
Deployment sizing guideHardware profiles by tier (local → enterprise) and topology patterns
Capacity planning checklistDiagnostic flow + tuning order when load grows
Deployment guideProduction deployment guidance
State-assembly receiptsReceipt schema, HMAC signing, verify semantics
Receipt replayv0.9 — re-run a historical retrieval against current memories + original policy
Auto-labelingv0.9 — heuristic detectors + review/promote workflow
Residencyv0.9 — per-region deployment + tenant pinning + ops runbook
RoadmapWhat's next
ChangelogRelease history

Community

Statewave is built in the open. Where to post what:

The full community guide — categories, RFC process, moderation — lives in statewave-docs/community/discussions.md. Copy-paste templates for questions, feature requests, RFCs, and show-and-tell are in discussion-templates.md.

Ecosystem

ProjectDescription
Server (this repo)Core server — API, domain model, DB, services
Python SDKpip install statewave — sync + async client
TypeScript SDKnpm install @statewavedev/sdk — fetch-based client
Connectors@statewavedev/connectors-* — GitHub, Markdown/docs, MCP server, modular packages
DocsArchitecture, API contracts, ADRs
ExamplesQuickstarts, evals, benchmarks
Website + demoMarketing website + embedded interactive demo (statewave.ai)
AdminOperator console (read-only)

Licensing

Statewave is licensed under the Apache License, Version 2.0.

You may use, modify, and distribute it — including in proprietary or hosted products — without a separate agreement. Apache-2.0 includes an explicit patent grant from contributors.