Context
After #13945 fixed the LM Studio embedding truncation path, we checked whether native Ollama can hit the same data-integrity class. It can, through a different mechanism: the readiness layer warms native Ollama roles with options.num_ctx, but the live OllamaProvider.embed() request still sends only {model, input}.
Official Ollama API docs for /api/embed say truncate defaults to true. Official Ollama FAQ says API callers set context length through options.num_ctx. That means a native Ollama embedding request can silently return a truncated vector unless the request explicitly opts out.
Live latest-open sweep: checked latest 20 open issues at 2026-06-24T10:53:28Z; no equivalent found. #13852 is related but broader and currently not-code-ready / deferred-by-design; it covers serving lifecycle and preload, not the live /api/embed request-shape guard. A2A in-flight sweep: checked latest 30 messages at 2026-06-24T10:53Z; no competing peer claim for this narrow scope.
Release classification: deployment-hardening follow-up, boardless. Promote to release-board scope only if a release gate requires native-Ollama large-input embedding before ship.
The Problem
Native Ollama embedding currently relies on provider defaults at the request boundary. If the model is resident at too small a context, or if readiness was bypassed, stale, or failed open, /api/embed can truncate by default and still return embeddings. That is worse than a thrown error: KB / Memory Core would index corrupted vectors.
The Architectural Reality
ai/services/graph/providerReadinessHelper.mjs already warms native Ollama embedding through /api/embed with options.num_ctx when a role context length is configured.
ai/provider/Ollama.mjs live embed() currently builds a payload with only model and input.
ai/services/memory-core/TextEmbeddingService.mjs calls provider.embed(texts) for embeddingProvider === "ollama" and does not pass the local embedding context cap.
- ADR 0019 applies: read
AiConfig.localModels.embedding.contextLimitTokens at the use site. Do not add hidden defaults, defensive optional chains, type conversions, or pass a copied config object across modules.
The Fix
- Extend the native Ollama embedding request path so
/api/embed sends truncate: false.
- Thread a resolved
num_ctx into the request as options.num_ctx from AiConfig.localModels.embedding.contextLimitTokens at the TextEmbeddingService native-Ollama callsite.
- Preserve fail-loud behavior: over-context native Ollama responses must reject the embedding path rather than returning a vector.
- Add focused unit coverage for single and batch native Ollama embeddings.
Contract Ledger Matrix
| Target Surface |
Source of Authority |
Proposed Behavior |
Fallback |
Docs |
Evidence |
OllamaProvider.embed(input, options) |
Ollama /api/embed API docs |
Supports truncate:false and options.num_ctx in the native payload |
Provider error propagates; no synthetic vector |
JSDoc update |
Unit captures /api/embed POST body |
TextEmbeddingService.embedText/embedTexts(..., "ollama") |
ADR 0019 + AiConfig.localModels.embedding.contextLimitTokens |
Reads the resolved leaf at use site and passes it to the provider call |
Missing/invalid leaf fails loud through normal Provider/type discipline |
JSDoc/comment if needed |
Unit verifies single and batch pass context |
| KB / Memory Core embedding integrity |
Memory Core embedding contract |
No native-Ollama silent truncation before vector indexing |
Request fails; caller handles existing embedding failure path |
none |
Unit + existing provider tests |
Decision Record Impact
Aligned with ADR 0019. The implementation should read the resolved AiConfig leaf at the use site and avoid hidden defaults, type conversions, defensive subtree checks, or passing AiConfig between modules.
Acceptance Criteria
Out of Scope
- Starting or supervising
ollama serve.
- Changing
OLLAMA_NUM_PARALLEL, OLLAMA_CONTEXT_LENGTH, or deployment env defaults.
- Reopening the broader
#13852 local serving-lifecycle lane.
- Adding public privileged daemon, shell, socket, or deployment-control surfaces.
Avoided Traps
- Do not rely on readiness warm-up alone; request-level integrity still matters.
- Do not mirror the LM Studio
lms ps guard for native Ollama unless needed. Ollama already exposes request-level truncate:false and num_ctx.
- Do not add hidden fallback values around AiConfig leaves.
Related
Refs #13945
Refs #13944
Refs #13852
Origin Session ID: cd2b88d7-8134-4ef8-a10f-0b1e80c03db4
Retrieval Hint: native Ollama /api/embed truncate false num_ctx embedding request follow-up provider readiness #13945
Context
After #13945 fixed the LM Studio embedding truncation path, we checked whether native Ollama can hit the same data-integrity class. It can, through a different mechanism: the readiness layer warms native Ollama roles with
options.num_ctx, but the liveOllamaProvider.embed()request still sends only{model, input}.Official Ollama API docs for
/api/embedsaytruncatedefaults totrue. Official Ollama FAQ says API callers set context length throughoptions.num_ctx. That means a native Ollama embedding request can silently return a truncated vector unless the request explicitly opts out.Live latest-open sweep: checked latest 20 open issues at 2026-06-24T10:53:28Z; no equivalent found.
#13852is related but broader and currentlynot-code-ready/deferred-by-design; it covers serving lifecycle and preload, not the live/api/embedrequest-shape guard. A2A in-flight sweep: checked latest 30 messages at 2026-06-24T10:53Z; no competing peer claim for this narrow scope.Release classification: deployment-hardening follow-up, boardless. Promote to release-board scope only if a release gate requires native-Ollama large-input embedding before ship.
The Problem
Native Ollama embedding currently relies on provider defaults at the request boundary. If the model is resident at too small a context, or if readiness was bypassed, stale, or failed open,
/api/embedcan truncate by default and still return embeddings. That is worse than a thrown error: KB / Memory Core would index corrupted vectors.The Architectural Reality
ai/services/graph/providerReadinessHelper.mjsalready warms native Ollama embedding through/api/embedwithoptions.num_ctxwhen a role context length is configured.ai/provider/Ollama.mjsliveembed()currently builds a payload with onlymodelandinput.ai/services/memory-core/TextEmbeddingService.mjscallsprovider.embed(texts)forembeddingProvider === "ollama"and does not pass the local embedding context cap.AiConfig.localModels.embedding.contextLimitTokensat the use site. Do not add hidden defaults, defensive optional chains, type conversions, or pass a copied config object across modules.The Fix
/api/embedsendstruncate: false.num_ctxinto the request asoptions.num_ctxfromAiConfig.localModels.embedding.contextLimitTokensat the TextEmbeddingService native-Ollama callsite.Contract Ledger Matrix
OllamaProvider.embed(input, options)/api/embedAPI docstruncate:falseandoptions.num_ctxin the native payload/api/embedPOST bodyTextEmbeddingService.embedText/embedTexts(..., "ollama")AiConfig.localModels.embedding.contextLimitTokensDecision Record Impact
Aligned with ADR 0019. The implementation should read the resolved AiConfig leaf at the use site and avoid hidden defaults, type conversions, defensive subtree checks, or passing AiConfig between modules.
Acceptance Criteria
/api/embedrequests includetruncate:false.options.num_ctxusingAiConfig.localModels.embedding.contextLimitTokens.embedText(..., "ollama")andembedTexts(..., "ollama")both preserve the fail-loud request shape.Out of Scope
ollama serve.OLLAMA_NUM_PARALLEL,OLLAMA_CONTEXT_LENGTH, or deployment env defaults.#13852local serving-lifecycle lane.Avoided Traps
lms psguard for native Ollama unless needed. Ollama already exposes request-leveltruncate:falseandnum_ctx.Related
Refs #13945 Refs #13944 Refs #13852
Origin Session ID: cd2b88d7-8134-4ef8-a10f-0b1e80c03db4
Retrieval Hint:
native Ollama /api/embed truncate false num_ctx embedding request follow-up provider readiness #13945