Environment
memanto 0.2.4, on-prem backend brought up via the Docker quick start (moorcheh up), all defaults, zero config.
- Embedding model:
nomic-embed-text (context length 2048); LLM: qwen2.5 — the quick-start defaults.
- Two Compose containers on a shared network:
moorcheh-onprem-server (:8080) and moorcheh-ollama (:11434).
This is the documented out-of-the-box configuration, so the failure reproduces with the quick start and no custom settings.
Current behavior
memanto detect-conflicts fails for any day with a non-trivial amount of session activity:
Failed to detect conflicts: Conflict detection failed: ollama embeddings request returned error status
The mechanism: DailyAnalysisService.generate_conflict_report (memanto/app/services/daily_analysis_service.py) concatenates that day's session summaries into full_text, folds them into a single conflict_prompt, and passes the whole thing as the retrieval query to client.answer.generate(..., top_k=50). The on-prem server embeds that query through Ollama. With the default embedding model nomic-embed-text (context length 2048 tokens) from the quick start, and the embedding request issued without truncation, any query longer than the context window is rejected.
Reproduced on memanto 0.2.4, on-prem backend, nomic-embed-text embedding. The failure is purely a function of query length. Hitting the on-prem /search endpoint (the same server-side embedding path) with increasing slices of a real session summary:
chars=20 HTTP 200
chars=2000 HTTP 200
chars=4000 HTTP 200
chars=6000 HTTP 400 {"message":"ollama embeddings request returned error status","status":"error"}
chars=11190 HTTP 400 {"message":"ollama embeddings request returned error status","status":"error"}
Confirming the cause at the Ollama layer, with real (dense) text over 2048 tokens:
POST /api/embed {"input": <6k chars>} -> HTTP 200 (prompt_eval_count=2048, silently truncated)
POST /api/embed {"input": <6k chars>, "truncate": false} -> HTTP 400 "the input length exceeds the context length"
POST /api/embeddings {"prompt": <6k chars>} -> HTTP 500 "the input length exceeds the context length"
remember, recall, and small-query answer are unaffected, since their queries stay well under 2048 tokens. The consequence is that conflict detection breaks precisely on the days with enough activity to be worth checking; a single day's ~11 KB summary is already well past the limit.
Expected behavior
detect-conflicts should complete regardless of how much session content a day accumulates, and produce a conflict report (empty or not). A day's volume of memories should never surface as an embedding error.
Suggested approaches
Roughly from narrowest to most structural:
- Bound the retrieval query. The query used to pull historical memories does not need to be the entire day's text; a context-sized window or a compact digest is enough to retrieve the relevant memories, and avoids the limit. Note that
/answer uses query for both the retrieval embedding and the LLM prompt, so this should decouple the two, moving the instruction block into header_prompt/footer_prompt while a shorter digest serves as the embedded query.
- Chunk the day and detect per chunk. Split the session content into context-sized chunks, retrieve per chunk, and union the candidate historical memories before the LLM pass. Higher recall than (1), at the cost of more embedding calls.
- Truncate at the embedding call. Have the on-prem embedding path request Ollama with
truncate: true (the /api/embed default) rather than letting the request fail. This prevents the hard error, but silent truncation to the first 2048 tokens is lossy and would mask the design issue that (1) and (2) address.
Approaches (1) and (2) belong in memanto; (3) is a complementary server-side guard in the Moorcheh on-prem embedding path, not a substitute. Separately, the error surfaced to the user could name the cause (query length versus context window) rather than the opaque upstream status. Let's discuss the preferred shape.
Environment
memanto 0.2.4, on-prem backend brought up via the Docker quick start (moorcheh up), all defaults, zero config.nomic-embed-text(context length 2048); LLM:qwen2.5— the quick-start defaults.moorcheh-onprem-server(:8080) andmoorcheh-ollama(:11434).This is the documented out-of-the-box configuration, so the failure reproduces with the quick start and no custom settings.
Current behavior
memanto detect-conflictsfails for any day with a non-trivial amount of session activity:The mechanism:
DailyAnalysisService.generate_conflict_report(memanto/app/services/daily_analysis_service.py) concatenates that day's session summaries intofull_text, folds them into a singleconflict_prompt, and passes the whole thing as the retrievalquerytoclient.answer.generate(..., top_k=50). The on-prem server embeds that query through Ollama. With the default embedding modelnomic-embed-text(context length 2048 tokens) from the quick start, and the embedding request issued without truncation, any query longer than the context window is rejected.Reproduced on
memanto 0.2.4, on-prem backend,nomic-embed-textembedding. The failure is purely a function of query length. Hitting the on-prem/searchendpoint (the same server-side embedding path) with increasing slices of a real session summary:Confirming the cause at the Ollama layer, with real (dense) text over 2048 tokens:
remember,recall, and small-queryanswerare unaffected, since their queries stay well under 2048 tokens. The consequence is that conflict detection breaks precisely on the days with enough activity to be worth checking; a single day's ~11 KB summary is already well past the limit.Expected behavior
detect-conflictsshould complete regardless of how much session content a day accumulates, and produce a conflict report (empty or not). A day's volume of memories should never surface as an embedding error.Suggested approaches
Roughly from narrowest to most structural:
/answerusesqueryfor both the retrieval embedding and the LLM prompt, so this should decouple the two, moving the instruction block intoheader_prompt/footer_promptwhile a shorter digest serves as the embeddedquery.truncate: true(the/api/embeddefault) rather than letting the request fail. This prevents the hard error, but silent truncation to the first 2048 tokens is lossy and would mask the design issue that (1) and (2) address.Approaches (1) and (2) belong in
memanto; (3) is a complementary server-side guard in the Moorcheh on-prem embedding path, not a substitute. Separately, the error surfaced to the user could name the cause (query length versus context window) rather than the opaque upstream status. Let's discuss the preferred shape.