Context
PR #14014 closed #14009 by appending <|im_end|> to LM Studio GGUF/Qwen3 embedding requests. The operator restarted the Memory Core repair-defrag after pulling dev, but LM Studio still emitted the GGUF warning:
[WARNING] At least one last token in strings embedded is not SEP. 'tokenizer.ggml.add_eos_token' should be set to 'true' in the GGUF header
The follow-up investigation found that the requests were in fact ending with <|im_end|>:
{
"model": "text-embedding-qwen3-embedding-8b",
"input": [
"...<|im_end|>",
"...<|im_end|>"
]
}That falsifies the earlier assumption that <|im_end|> satisfies this GGUF's required final token.
The Problem
The suffix logic in #14014 was metadata-scoped to LMS/Qwen, but the suffix value itself was still hard-coded from the architecture name. For the installed Qwen3-Embedding-8B-Q4_K_M.gguf, direct GGUF header inspection shows:
tokenizer.ggml.eos_token_id = 151643 -> <|endoftext|>
tokenizer.ggml.eot_token_id = 151645 -> <|im_end|>
tokenizer.ggml.add_eos_token = true
So <|im_end|> is the chat EOT token, not the EOS/SEP token this embedding runtime is warning about. Appending EOT leaves the final-token warning alive during the missing-vector re-embed phase.
The Architectural Reality
ai/services/memory-core/TextEmbeddingService.mjs owns regular Memory Core / Knowledge Base embedding dispatch.
ai/services/graph/providerReadinessHelper.mjs owns direct embedding-serving canary requests.
openAiCompatible is a shared transport surface for LM Studio, MLX, vLLM, llama.cpp, Ollama compatibility, and fixtures. The fix must not turn the provider name into an LMS/Qwen switch and must not add a suffix config that would break Ollama/native or generic OpenAI-compatible deployments.
- The reliable authority for this case is LMS GGUF metadata: the loaded model row identifies a GGUF path, and the GGUF header maps
eos_token_id to the actual token string.
The Fix
- Add a pure shared vector helper that resolves the LMS embedding-input suffix from GGUF tokenizer metadata.
- For GGUF models, read
tokenizer.ggml.eos_token_id and tokenizer.ggml.tokens[eos_token_id]; append that token when absent.
- Keep non-GGUF, non-LMS, and unknown-metadata paths unchanged.
- Use the helper from both
TextEmbeddingService and the embedding-serving canary path.
- Add unit coverage proving
<|im_end|> alone is not treated as already sufficient when GGUF EOS resolves to <|endoftext|>.
Contract Ledger Matrix
| Target Surface |
Source of Authority |
Proposed Behavior |
Fallback |
Docs |
Evidence |
TextEmbeddingService LMS request normalization |
Live LM Studio warning + GGUF header metadata |
Append the GGUF EOS token text, not a hard-coded architecture token |
No suffix when metadata cannot prove a GGUF EOS token |
Helper JSDoc |
Unit request-body capture + live helper probe |
checkOpenAiCompatibleEmbeddingServing() canary |
Provider-readiness contract |
Apply the same LMS GGUF suffix when loaded-model metadata is available |
Raw canary input for non-LMS or unknown metadata |
JSDoc option |
Unit request-body capture |
| OpenAI-compatible provider boundary |
ADR 0019 AiConfig SSOT discipline |
No config leaf; no runtime AiConfig mutation; provider name is not treated as LMS |
Metadata unavailable means no mutation |
None beyond code comments |
Tests for unchanged generic path |
Decision Record impact
Aligned with ADR 0019. This must remain metadata-derived at the provider request boundary and must not introduce a config suffix leaf or OpenAI-compatible-wide default.
Acceptance Criteria
Out of Scope
- Reopening #14009 or #14014.
- Changing Ollama native embedding behavior.
- Adding a user-configurable suffix.
- Repairing Memory Core vector corruption or defrag progress logging.
Avoided Traps
- Do not make
openAiCompatible itself mean LMS.
- Do not suffix every OpenAI-compatible embedding request.
- Do not hard-code
<|im_end|> from Qwen architecture; the GGUF header is the authority.
Related
Related: #14009
Related: #14014
Live latest-open sweep: checked latest 20 open issues at 2026-06-25T18:20Z; no equivalent open ticket found. Targeted open search for LMS SEP embedding canary Qwen3 warning returned no open issues. A2A in-flight claim sweep: checked latest 30 all-status messages at the same time; no overlapping [lane-claim] or [lane-intent] found.
Origin Session ID: 9280140f-8b54-4462-9342-49cca7e226f4
Handoff Retrieval Hints: LMS SEP GGUF eos_token_id endoftext im_end, tokenizer.ggml.add_eos_token #14009 #14014, TextEmbeddingService lmsEmbeddingInputSuffix
Context
PR #14014 closed #14009 by appending
<|im_end|>to LM Studio GGUF/Qwen3 embedding requests. The operator restarted the Memory Core repair-defrag after pullingdev, but LM Studio still emitted the GGUF warning:The follow-up investigation found that the requests were in fact ending with
<|im_end|>:{ "model": "text-embedding-qwen3-embedding-8b", "input": [ "...<|im_end|>", "...<|im_end|>" ] }That falsifies the earlier assumption that
<|im_end|>satisfies this GGUF's required final token.The Problem
The suffix logic in #14014 was metadata-scoped to LMS/Qwen, but the suffix value itself was still hard-coded from the architecture name. For the installed
Qwen3-Embedding-8B-Q4_K_M.gguf, direct GGUF header inspection shows:So
<|im_end|>is the chat EOT token, not the EOS/SEP token this embedding runtime is warning about. Appending EOT leaves the final-token warning alive during the missing-vector re-embed phase.The Architectural Reality
ai/services/memory-core/TextEmbeddingService.mjsowns regular Memory Core / Knowledge Base embedding dispatch.ai/services/graph/providerReadinessHelper.mjsowns direct embedding-serving canary requests.openAiCompatibleis a shared transport surface for LM Studio, MLX, vLLM, llama.cpp, Ollama compatibility, and fixtures. The fix must not turn the provider name into an LMS/Qwen switch and must not add a suffix config that would break Ollama/native or generic OpenAI-compatible deployments.eos_token_idto the actual token string.The Fix
tokenizer.ggml.eos_token_idandtokenizer.ggml.tokens[eos_token_id]; append that token when absent.TextEmbeddingServiceand the embedding-serving canary path.<|im_end|>alone is not treated as already sufficient when GGUF EOS resolves to<|endoftext|>.Contract Ledger Matrix
TextEmbeddingServiceLMS request normalizationcheckOpenAiCompatibleEmbeddingServing()canaryDecision Record impact
Aligned with ADR 0019. This must remain metadata-derived at the provider request boundary and must not introduce a config suffix leaf or OpenAI-compatible-wide default.
Acceptance Criteria
TextEmbeddingServiceappends<|endoftext|>for the installed Qwen3 embedding GGUF rather than<|im_end|>.<|im_end|>still receive the GGUF EOS suffix when EOS is different.Out of Scope
Avoided Traps
openAiCompatibleitself mean LMS.<|im_end|>from Qwen architecture; the GGUF header is the authority.Related
Related: #14009 Related: #14014
Live latest-open sweep: checked latest 20 open issues at 2026-06-25T18:20Z; no equivalent open ticket found. Targeted open search for
LMS SEP embedding canary Qwen3 warningreturned no open issues. A2A in-flight claim sweep: checked latest 30 all-status messages at the same time; no overlapping[lane-claim]or[lane-intent]found.Origin Session ID: 9280140f-8b54-4462-9342-49cca7e226f4
Handoff Retrieval Hints:
LMS SEP GGUF eos_token_id endoftext im_end,tokenizer.ggml.add_eos_token #14009 #14014,TextEmbeddingService lmsEmbeddingInputSuffix