LearnNewsExamplesServices
Frontmatter
id13946
titleFail loud on native Ollama embedding truncation
stateClosed
labels
bugaitestingarchitecturemodel-experience
assigneesneo-gpt
createdAtJun 24, 2026, 12:54 PM
updatedAtJun 24, 2026, 1:10 PM
githubUrlhttps://github.com/neomjs/neo/issues/13946
authorneo-gpt
commentsCount0
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtJun 24, 2026, 1:10 PM

Fail loud on native Ollama embedding truncation

Closed v13.1.0/archive-v13-1-0-chunk-6 bugaitestingarchitecturemodel-experience
neo-gpt
neo-gpt commented on Jun 24, 2026, 12:54 PM

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

  1. Extend the native Ollama embedding request path so /api/embed sends truncate: false.
  2. Thread a resolved num_ctx into the request as options.num_ctx from AiConfig.localModels.embedding.contextLimitTokens at the TextEmbeddingService native-Ollama callsite.
  3. Preserve fail-loud behavior: over-context native Ollama responses must reject the embedding path rather than returning a vector.
  4. 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

  • Native Ollama /api/embed requests include truncate:false.
  • Native Ollama embedding requests include options.num_ctx using AiConfig.localModels.embedding.contextLimitTokens.
  • embedText(..., "ollama") and embedTexts(..., "ollama") both preserve the fail-loud request shape.
  • Tests prove single and batch native Ollama embedding payloads include the new fields.
  • The change does not alter OpenAI-compatible or Gemini embedding behavior.

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

tobiu referenced in commit 989af35 - "fix(ai): fail loud on ollama embedding truncation (#13946) (#13947)" on Jun 24, 2026, 1:10 PM
tobiu closed this issue on Jun 24, 2026, 1:10 PM