LearnNewsExamplesServices
Frontmatter
id13944
titlePrevent LM Studio embedding context truncation
stateClosed
labels
bugaitestingarchitecturemodel-experience
assigneesneo-gpt
createdAtJun 24, 2026, 12:10 PM
updatedAtJun 24, 2026, 12:47 PM
githubUrlhttps://github.com/neomjs/neo/issues/13944
authorneo-gpt
commentsCount0
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtJun 24, 2026, 12:47 PM

Prevent LM Studio embedding context truncation

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

Context

After #13941 and #13943 landed, the harness and orchestrator were restarted with all local models ejected. The orchestrator started a KB sync, LM Studio loaded the OpenAI-compatible embedding model, and the LM Studio log showed a silent embedding truncation:

[WARNING] Number of tokens in input string (12746) exceeds model context length (8192). Truncating to 8192 tokens.

Live local probes after the incident confirmed the relevant shape:

  • lms load --help defines --parallel as maximum concurrent predictions, separate from --context-length.
  • lms load text-embedding-qwen3-embedding-8b --context-length 32768 --parallel 4 --estimate-only reports Context Length: 32,768; parallel does not divide context into 32768 / 4.
  • Neo's resolved preload config still targets text-embedding-qwen3-embedding-8b with localModels.embedding.contextLimitTokens = 32768.
  • The same LM Studio model advertises max context 40960 locally, so 8192 is neither the model max nor Neo's configured target.

Release classification: deployment-readiness / Agent OS ingestion hardening, boardless unless the operator promotes it to the active deployment closeout gate.

The Problem

The embedding provider can be live and answer /v1/embeddings while loaded below Neo's configured embedding context window. In that state, KB sync and Memory Core ingestion can hand LM Studio a large input, receive an embedding, and only the provider log reveals that the input was truncated.

That is wrong on multiple levels:

  • It corrupts vector quality silently: the stored embedding represents only the provider-truncated prefix.
  • It bypasses Neo's configured localModels.embedding.* contract.
  • It can hide parser/chunking gaps, especially in deployments where tenant-repo ingestion does not yet have custom parsers/chunking for large code files.
  • It makes #13941's "replace stale exact model with configured shape" insufficient if the embedding role is JIT/default-loaded before preload, preload does not run, or the provider later drifts.

The Architectural Reality

  • ai/config.template.mjs declares localModels.embedding.contextLimitTokens and safeProcessingLimitTokens for embedding-path consumers.
  • ai/services/graph/providerReadinessHelper.mjs builds the LM Studio preload contextLengths map for the embedding role when embeddingProvider === 'openAiCompatible'.
  • ensureLmsModelsLoaded() can compare lms ps --json loaded context against the configured context, but KB sync can still reach /v1/embeddings with a provider that is loaded at the wrong context.
  • TextEmbeddingService / VectorService embedding callers need fail-loud or skip-with-diagnostics behavior when the provider's loaded context is below the input, not silent acceptance of provider-side truncation.
  • ADR-0019 applies: any fix must read resolved AiConfig leaves at use sites and avoid hidden defaults, env rereads, type coercion wrappers, or config subtree pass-through.

The Fix

Add a focused guard for OpenAI-compatible local embedding context enforcement:

  1. Ensure the orchestrator preload path cannot leave the embedding model resident below localModels.embedding.contextLimitTokens after a restart/JIT-load ordering race. If the exact embedding identifier is resident but too small, unload/reload with the configured context before KB sync relies on it.
  2. Add an embedding-call guard that refuses or skips inputs which would be provider-truncated by the currently loaded local embedding context, surfacing a bounded diagnostic instead of accepting a silently truncated embedding.
  3. Revisit the default embedding context cap for text-embedding-qwen3-embedding-8b: local LM Studio reports max 40960, while Neo defaults to 32768. The implementation should either justify the 32K operational cap or raise the local embedding default/safe band with explicit memory evidence.
  4. Add runtime diagnostics that make loaded embedding context visible in #13914/#13936 proof surfaces.

Contract Ledger Matrix

Target Surface Source of Authority Proposed Behavior Fallback Docs Evidence
localModels.embedding.contextLimitTokens ai/config.template.mjs Defines the minimum loaded local embedding context expected for OpenAI-compatible embeddings If provider cannot load it, fail/skip with diagnostic; do not silently embed truncated input Config JSDoc Unit + live lms ps evidence
LM Studio preload for embedding role buildLmsPreloadConfig() / ensureLmsModelsLoaded() Embedding model is loaded/replaced to the configured embedding context before ingestion relies on it Explicit degraded readiness if reload fails Helper JSDoc Unit coverage for stale embedding context replacement
Embedding request path TextEmbeddingService / VectorService Reject or skip inputs that exceed the observed loaded provider context before provider-side truncation Bounded diagnostic with model, observed context, configured context, token estimate, caller surface Service JSDoc + logs Unit coverage with oversized local embedding input
Deployment proof surface #13914 / #13936 Expose loaded embedding context and truncation/skip diagnostics through approved public read surfaces If public tool unavailable, local logs remain advisory only Tool payload docs L3 smoke after deployment

Decision Record impact

Aligned with ADR-0019 and ADR-0025. This does not amend those ADRs; it enforces the existing config/provider readiness contract and improves diagnosis for an observed ingestion failure.

Acceptance Criteria

  • A local OpenAI-compatible embedding model loaded below AiConfig.localModels.embedding.contextLimitTokens is detected before KB/Memory Core embedding work accepts provider output.
  • The LM Studio preload/replacement path reloads a stale exact embedding identifier with the configured embedding context, or records explicit degraded readiness if it cannot.
  • Embedding calls do not accept provider-side truncation silently; over-loaded-context inputs are skipped or fail-loud with bounded diagnostics.
  • Tests cover a 12,746-token-equivalent input against an 8,192 loaded context and prove no truncated embedding is accepted.
  • Tests cover the text-embedding-qwen3-embedding-8b configured context path and assert the embedding role participates in context enforcement.
  • The chosen default embedding context is justified against the observed LM Studio max context (40960) and the current 32768 default is either retained with rationale or adjusted with explicit memory evidence.
  • No ADR-0019 regressions: no hidden defaults, no runtime env rereads, no type coercion wrappers, no config subtree pass-through.

Out of Scope

  • Changing chat-model context or chat --parallel behavior from #13700.
  • Adding a public privileged MCP route.
  • Implementing full tenant-repo custom parsers/chunking for every codebase.
  • Solving native Ollama embedding CPU burn from #13928; this ticket is the OpenAI-compatible/LM Studio loaded-context truncation path.

Avoided Traps

  • Do not blame --parallel for dividing context; local lms load --estimate-only falsified that.
  • Do not rely on LM Studio warnings as the only signal; by then the embedding request has already been truncated.
  • Do not lower Neo's embedding input contract to match a stale loaded context.
  • Do not accept graph-only proof for deployment incidents where the embedding/model path may be wedged or truncating.

Related

Related: #13700, #13941, #13914, #13936, #13928, ADR-0019, ADR-0025.

Origin Session ID: cd2b88d7-8134-4ef8-a10f-0b1e80c03db4

Handoff Retrieval Hints: LM Studio embedding context truncation 8192 qwen3 12746 KB sync, localModels.embedding.contextLimitTokens provider-side truncation

tobiu referenced in commit cedf4f5 - "fix(ai): prevent embedding context truncation (#13944) (#13945)" on Jun 24, 2026, 12:47 PM
tobiu closed this issue on Jun 24, 2026, 12:47 PM