Open-source project
icey1287/SuperMew avatar
icey1287/SuperMew

SuperMew: an agent platform that persists every run, event and document version

SuperMew — Agentic RAG with LangChain & LangGraph

901 stars168 forksPythonMIT

At a glance

What is it?
SuperMew is a knowledge-base-first agent platform built on FastAPI, PostgreSQL, Milvus and LangGraph, where a chat request is modelled as persisted objects rather than an HTTP call, and a retrieval failure is reported as a failure rather than silently downgraded. The practical cost is a multi-service local stack, a long environment file and a codebase that is still at version 0.1.0.
Who is it for?
SuperMew suits a team building a retrieval-backed assistant that has to survive restarts, has to be auditable, and cannot treat a broken vector store as an empty result set, because the distinction between a degraded retrieval and a failed one is enforced in code. It does not suit a quick prototype, since the local stack needs PostgreSQL, Redis, Milvus with etcd and MinIO, and the environment file alone configures embedding, rerank, retrieval and evaluation behaviour.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 18 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 25, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A chat request is not an HTTP call here

The framing decision at the top of the project description is the one that shapes everything else. SuperMew does not treat a single chat request as an unrecoverable HTTP call. Instead, user input, agent execution, tool calls, retrieved evidence, human confirmation and the final result are modelled as domain objects that can be persisted, replayed and audited. The objects are named: a Thread holds the long-lived conversation boundary, a Message holds the factual history, a Run represents one resumable execution, an Event Journal records the execution, and a Checkpoint allows a human-in-the-loop pause to be resumed on the same Run. The project also states that only the canonical Thread, Run and Event interface is kept, and that the older chat, chat stream and sessions compatibility entry points have been removed rather than kept alive with double writes, double reads or hidden fallbacks. That is a deliberate refusal to maintain two execution paths, and it means the cost of the design is paid up front in migration rather than forever in bug reports.

Events land in PostgreSQL before they reach the browser

The streaming path has a specific ordering that matters for anyone reasoning about what a user saw. Events are written to the PostgreSQL journal first, and only then projected over server-sent events. The frontend deduplicates by sequence, reconnects with a Last-Event-ID header, and can replay missed events from the events endpoint. The message.completed event and the terminal event are the authoritative result, and Redis is only responsible for low-latency notification. That means Redis is not on the critical path for correctness, which is the point of the arrangement: if the notification layer drops a message, the run still has a durable record and the client can catch up. The same care is applied to cancellation. Stopping requests cancellation of the backend Run, while closing the browser or losing the SSE connection only stops observation and is explicitly not allowed to pretend that execution has terminated. Checkpoint, Run, Thread and assistant Message identity all stay the same across a pause and its resume, so a human approval does not fork the conversation into a different lineage.

Two-phase document publishing keeps a bad index out of production

The knowledge base side has an equivalent discipline. When a document is uploaded, a persistent index job builds an immutable document version, and the chunks are split across two stores: leaf chunks go into Milvus, and parent chunks with the version metadata go into PostgreSQL. A new version is switched in through a two-stage publish, and the reason given is that a version under construction must not pollute the version that is currently retrievable. The mechanics are stricter still. The index job builds in an isolated candidate scope and verifies an exact manifest, and the switch to the current version is a compare-and-swap in PostgreSQL, so the swap is atomic. If the build fails, the published version is untouched. The consequence for a user is that search results are either from a complete, verified version of a document or from the previous complete version, never from a half-indexed mixture. The document versions are immutable, which also means an evaluation run can be tied to the exact corpus it was measured against, and a bad answer can be traced back to the version of the source that produced it.

A failed retrieval is never dressed up as an empty result

This is the behaviour that separates the project from most retrieval systems, and it is stated as a rule rather than a feature. The retrieval path is hybrid: dense vectors and Milvus native BM25 sparse vectors are recalled in two channels and fused with reciprocal rank fusion, auto-merging is applied over the full candidate pool, and an optional rerank stage follows with an input budget, a timeout and circuit breaker protection. The degradation semantics are strict. Only when the Milvus adapter explicitly reports that sparse or hybrid capability is incompatible does the affected target fall back to dense retrieval, reusing the same query embedding. A connection failure, a timeout, an unavailable service, a parameter error or a malformed response fails explicitly and is never presented as a successful degradation. The rerank path is bounded in the same spirit: when rerank is not configured the fused candidate order is kept as is, and when a configured rerank provider still fails after its own limited retries, the result falls back to the RRF and auto-merging output, with the error code, the attempt count and a rerank_fallback_applied flag written into the RAG trace. The point is that a reader of the trace can tell the difference between a weak answer and a broken system.

The agent loop has a middleware chain and a hard budget

The execution side is built on LangGraph, and the loop is fenced rather than free. A fixed middleware chain constrains model calls, tool calls, recursion, the deadline, the context budget and repeated tool fingerprints, and when a repeated call or an alternating A and B loop exceeds the limit, the run returns TOOL_LOOP_BLOCKED. Before the agent does anything, a complexity planner decides what kind of question it is. Obvious short single-fact questions go straight to retrieval through local rules, and the rest are judged once by a fast model. A complex question is then split into two to four subquestions, which are retrieved and evidence-judged in parallel using LangGraph Send, and a synthesis node deduplicates and combines the results. The corrective path is deliberately small. A grader makes one structured judgement covering relevance, answerability, ambiguity and route, and only if the evidence is judged insufficient does a fast model choose one of two rewrites, step-back or HyDE, with exactly one rewritten retrieval and one re-evaluation afterwards. The entire pipeline keeps observability information in a rag_trace table, and the trace survives the run, which is what makes the evaluation workbench possible later.

The capability registry decides what a run can even see

Tools are not simply enabled. A version-pinned skill and tool registry manages the knowledge base, weather, read-only SQL, web research, sandbox and restricted HTTPS JSON tool, and the tool schema is disclosed lazily according to the permissions of the current run, so a run never sees a capability it cannot call. Execution has three layers. The registry decides whether a capability is visible, a guardrail applies deterministic constraints before the handler runs, and the sandbox isolates only the code execution that has already been permitted. The auditing rule is worth noting: an ordinary allow is not shown in the frontend, the user only sees a denial or a request for approval, and the detailed policy reason goes only into a redacted tool audit. Approval happens before the run is created. There is deliberately no state machine that pops up mid-run to temporarily widen permissions and then resume, and an approval-only tool that was not authorised in the creation request is rejected. Web research is similarly narrow: web_search allocates source identifiers such as S1 and S2 for the run, and web_fetch takes a source id and an optional query and returns at most three query-ranked chunks through Tavily Extract, without fetching or injecting a whole web page into the context.

The SQL assistant is read-only by construction, not by policy

The read-only SQL assistant is the sharpest example of the project's approach to dangerous capabilities. It is available only to the admin role, and it is constrained at several independent layers: a separate database account, a schema and table allowlist, AST-level checks, permissions, row level security, cost limits, timeouts, result size limits and masking of sensitive fields. It offers no DDL and no DML. The reasoning behind that design is visible in how the other capabilities are described too, and it is a reasonable model for a general agent product, where the safe thing is to make the dangerous operation structurally absent rather than to rely on a prompt telling the model not to do it. The sandbox follows the same principle from a different angle. You choose Python or Shell, submit source, and the mode is fixed at no network, no host mount and no persistent workspace, and the confirmation before sending signs a names-only grant for the single run that is about to be created. The sandbox does not export persistent artifacts either: the temporary workspace is destroyed when the call ends, so files never expose a container or host path.

Four services, one environment file and version 0.1.0

Running it locally means running the stack, and the Compose file is more than a database. PostgreSQL 15 holds the application database, Redis 7 runs with append-only persistence, and Milvus brings its own etcd and MinIO dependencies, each with its own volume, healthcheck and port. The backend itself is FastAPI with SQLAlchemy, and the front end is Vite with Vue 3, TypeScript, Pinia and Axios, served same-origin by FastAPI in a production build. The Python requirement is 3.12 or newer, and the dependency set is large and pinned in places, with langchain at 1.3.9, langgraph at 1.2.x, langgraph-checkpoint-postgres for the checkpointing, pymilvus, sqlglot pinned exactly, unstructured for document parsing, bcrypt and PyJWT for credentials, and sentence-transformers with langchain-huggingface for local embeddings. Three console scripts are defined: an auth cleanup entry point, an indexing worker and a registry command line tool. The environment file is where the operational behaviour lives, and its length is a fair measure of the surface. The first block sets the model roles, with separate Answer, Fast, Grader and Evaluator model names, a base URL and a thirty second native timeout, and the SDK's built-in retry is fixed off so that the provider policy is the only thing that retries:

bash
APP_ENV=development
HOST=0.0.0.0
PORT=8000
MODEL=your_model_name
FAST_MODEL=your_fast_model_name
GRADE_MODEL=your_grade_model_name
EVALUATION_MODEL=your_evaluation_model_name
BASE_URL=https://your-llm-endpoint/v1
MODEL_TIMEOUT_SECONDS=30

Further down, the embedding block names BAAI/bge-m3 as the default local dense model with a 1024 dimension and CPU execution, the rerank block is marked optional and says that leaving it unset degrades automatically, and the retrieval block sets a top k of 8, at most four subquestions with two running in parallel, and a synthesis context budget of 12000 tokens. The MIT licence applies, the last push was on 2026-10-07, and the only release so far is 0.1.0 from 2026-08-27.

Editorial conclusion

SuperMew suits a team building a retrieval-backed assistant that has to survive restarts, has to be auditable, and cannot treat a broken vector store as an empty result set, because the distinction between a degraded retrieval and a failed one is enforced in code. It does not suit a quick prototype, since the local stack needs PostgreSQL, Redis, Milvus with etcd and MinIO, and the environment file alone configures embedding, rerank, retrieval and evaluation behaviour. Before adopting it, read the degradation semantics in the retrieval section first, because that is the behaviour your users will notice, and check the Docker Compose file, since the Compose services with their own volumes have to be running before the backend starts.

Frequently asked questions

What does SuperMew persist that a typical agent does not?

It models a chat request as persisted domain objects rather than an HTTP call: a Thread for the conversation boundary, Messages for factual history, a Run for one resumable execution, an Event Journal for the execution, and Checkpoints so a human approval resumes the same Run. Events are written to the PostgreSQL journal first and only then projected over server-sent events.

How does SuperMew handle a vector store failure during retrieval?

It fails explicitly rather than downgrading. Only when the Milvus adapter itself reports that sparse or hybrid capability is incompatible does the affected target fall back to dense retrieval with the same query embedding. Connection failures, timeouts, unavailable services, parameter errors and malformed responses are reported as failures, and the RAG trace records the error code, attempt count and whether a rerank fallback was applied.

Can the SuperMew SQL assistant modify the database?

No. It is read-only and restricted to the admin role, and it offers no DDL and no DML. It runs under a separate database account with a schema and table allowlist, AST checks, row level security, cost and timeout limits, result size limits and masking of sensitive fields.

What services do I need to run SuperMew locally?

The Docker Compose file starts PostgreSQL 15, Redis 7 with append-only persistence, and Milvus with its etcd and MinIO dependencies, each with its own volume and healthcheck. The backend is FastAPI with SQLAlchemy and the front end is Vite with Vue 3 and TypeScript, served same-origin by FastAPI in a production build, and Python 3.12 or newer is required.

Official sources

  1. icey1287/SuperMew on GitHub
  2. Issues
  3. License: MIT
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/icey1287-supermew.svg)](https://hysenlabs.com/projects/icey1287-supermew)

Was this useful?