7.3 KiB
Requirements Document
Project Description (Input)
Fix Graphiti embedding integration with Ollama (mxbai-embed-large) and stop silently swallowing embedding failures. Two bugs: (1) No first-class support for local Ollama embedders — EMBEDDING_MODEL defaults to OpenAI's text-embedding-3-small and the embedder reuses LLM_BASE_URL when EMBEDDING_BASE_URL is unset, so Ollama users get 404s; .env.example and CLAUDE.md don't document Ollama. (2) backend/app/services/graphiti_adapter.py:471-473 catches every exception during episode ingestion, logs a truncated WARNING, and substitutes a placeholder UUID, so a graph build appears to succeed but writes nothing. Tracked as GitHub issue #18.
Introduction
This feature adds first-class documentation for using a local Ollama embedder
(mxbai-embed-large, 1024-dim) with the Graphiti adapter and removes the
silent placeholder-UUID fallback in _GraphNamespace.add_batch so that
embedding failures terminate the surrounding background Task with the
underlying error visible in the UI and logs.
The work spans two narrowly scoped changes:
- Documentation update —
.env.example,CLAUDE.md, and the README / docker-compose comments gain a short Ollama section that explains how to point the embedder at a local Ollama instance, whymxbai-embed-largeis the recommended model (1024-dim, matches Graphiti's defaultEMBEDDING_DIM), and how to smoke-test connectivity with onecurlcommand before kicking off a graph build. - Loud failure — the broad
except Exceptionin_GraphNamespace.add_batchis removed (or narrowed to a small set of transient network errors). Episode ingestion failures now propagate to the calling background task, which marks itselfFAILEDwith the underlying error message attached, rather than logging aWARNINGand returning a fake UUID.
No new dependency, environment variable, or config flag is introduced. All existing OpenAI/Gemini configurations continue to work unchanged.
Boundary Context
- In scope: documenting Ollama as a third supported embedder provider
in
.env.example,CLAUDE.md, and the docker-compose / README comments; removing the silent placeholder-UUID fallback in_GraphNamespace.add_batch; surfacing the underlying ingestion error to the backgroundTaskso it terminates withstatus=FAILED; documenting a one-linecurlsmoke test for embedder connectivity. - Out of scope: a startup-time embedder health probe that refuses to
boot on dim/model mismatch; making
EMBEDDING_DIMenv-configurable so 768-dim or 1536-dim embedders can be used; adding a per-provider embedder factory (today the adapter only branches onopenaiandgemini); generic retry/backoff policy changes elsewhere in the pipeline. - Adjacent expectations: the existing background-task error-handling
contract from
.kiro/steering/error-handling.mdalready specifies that worker exceptions must callfail_task(...). This feature relies on that contract — it does not introduce a new one. The single-episode_GraphNamespace.add(...)path is left untouched because it already re-raises naturally.
Requirements
Requirement 1: Ollama Embedder Documentation
Objective: As a self-hosting MiroFish operator, I want first-class documentation for using a local Ollama embedder, so that I can run the Graphiti pipeline without needing an OpenAI- or Gemini-compatible embeddings endpoint.
Acceptance Criteria
- The
.env.examplefile shall contain a commented Ollama embedder block showingEMBEDDING_BASE_URL,EMBEDDING_API_KEY, andEMBEDDING_MODELset tohttp://host.docker.internal:11434/v1, a non-empty placeholder string, andmxbai-embed-largerespectively, with a comment noting theollama pull mxbai-embed-largeprerequisite. - The
CLAUDE.mdfile shall list the three supported embedder providers (OpenAI, Gemini, Ollama) and shall state the 1024-dim constraint that forcesmxbai-embed-largeovernomic-embed-text(768-dim). - Where the user runs MiroFish in Docker, the docker-compose comments or
README shall note that Ollama on the host is reached from the
mirofishcontainer viahost.docker.internal:11434. - The documentation shall include a one-line
curlexample that calls$EMBEDDING_BASE_URL/embeddingswith the configured model and confirms the response embedding length is 1024. - When the operator follows the documented Ollama configuration with
mxbai-embed-largepulled in Ollama, the existing graph-build pipeline shall complete end-to-end and write real nodes and edges to Neo4j with no code changes beyond the env-var configuration.
Requirement 2: Loud Embedding Failure
Objective: As a MiroFish operator, I want embedding failures during graph build to surface as a visible task failure with the underlying error, so that I can fix my embedder configuration instead of seeing an "empty graph" with no diagnostic.
Acceptance Criteria
- The
_GraphNamespace.add_batchmethod shall not return a placeholder_EpisodeResultUUID when the underlyingadd_episodecall raises an exception. - If
add_episoderaises any exception other than a narrowly defined set of transient network errors, then_GraphNamespace.add_batchshall propagate the exception to its caller. - When
_GraphNamespace.add_batchpropagates an exception, the surrounding graph-build backgroundTaskshall transition toFAILEDwithTask.errorcontaining a non-empty message derived from the underlying exception (per the existing.kiro/steering/error-handling.mdcontract). - While a graph-build task is failing because of a misconfigured
EMBEDDING_MODEL,EMBEDDING_BASE_URL, orEMBEDDING_API_KEY, the adapter shall log the underlyingadd_episodeerror atERRORlevel (notWARNING) before raising, so the root cause is visible in server logs. - Where the configured
EMBEDDING_MODELis invalid (e.g. a typo, or a model not pulled in Ollama), the user-facing project state shall move out ofGRAPH_BUILDINGand the task shall surface the underlying embedder error to the frontend without producing a placeholder-UUID "successful" episode. - The
_GraphNamespace.add_batchmethod shall preserve its current contract for successful episodes: each successfully ingested episode shall still produce one_EpisodeResultwhoseuuid_matches the Graphiti-assigned episode UUID, in input order.
Requirement 3: Backwards Compatibility
Objective: As an existing MiroFish operator already running with an OpenAI- or Gemini-compatible embedder, I want this change to be invisible on the happy path, so that no upgrade action is required.
Acceptance Criteria
- Where
EMBEDDING_BASE_URL,EMBEDDING_API_KEY, andEMBEDDING_MODELare unset or set to OpenAI/Gemini-compatible values, the embedder construction in_build_llm_and_embeddershall behave identically to the current implementation. - The graph-build pipeline shall not require any new environment
variable to function; Ollama support shall be enabled purely by
setting the three existing
EMBEDDING_*variables. - While Graphiti's default
EMBEDDING_DIMis 1024, the documentation shall explicitly note that any embedder model with a different output dimension is unsupported by this change and is an explicit follow-up item.