Skip to content

fix: chunk long text before embedding to prevent context-length errors - #59

Open
johnathanneals-dev wants to merge 1 commit into
benclawbot:masterfrom
johnathanneals-dev:fix/embedding-context-length-chunking
Open

fix: chunk long text before embedding to prevent context-length errors#59
johnathanneals-dev wants to merge 1 commit into
benclawbot:masterfrom
johnathanneals-dev:fix/embedding-context-length-chunking

Conversation

@johnathanneals-dev

Copy link
Copy Markdown

Closes #58.

create_embedding() and create_embeddings() pass full text to the provider with no size handling. When input exceeds the model's context window (2048 tokens for nomic-embed-text, 8191 for text-embedding-3-small), the API returns 400 and the memory store fails.

Fix

Adds automatic chunking at the create_embedding() convenience function level — above the provider abstraction, so all 4 providers (OpenRouter, OpenAI, Ollama, Custom) benefit:

  • Text exceeding 4000 chars is split into overlapping chunks (500-char overlap)
  • Each chunk is embedded independently via the existing provider embed() method
  • Chunk embeddings are mean-pooled + L2-normalized into a single vector

The batch path create_embeddings() now routes each text through create_embedding() so both paths handle long content consistently.

Threshold

4000 chars safely fits within nomic-embed-text's 2048-token window even for dense technical content (~2-3 chars/token). Higher-capacity models like text-embedding-3-small have more headroom but the conservative default prevents failures across all providers.

The full memory text is stored unchanged in the database — only embedding generation is affected. Search recall is slightly reduced for chunked content (mean-pooling vs single-vector), but the memory is stored successfully instead of crashing.

Context: I flagged a related issue in PR #15's code review (stale embeddings on content update) — this is a complementary fix addressing the input-size surface.

The embed() path sends full text to the provider with no size handling.
When input exceeds the model's context window (2048 tokens for
nomic-embed-text, 8191 for text-embedding-3-small), the API returns
400 and the memory store fails.

Adds automatic chunking at the create_embedding() level (above the
provider abstraction, so all providers benefit):
- Text exceeding 4000 chars is split into overlapping chunks
- Each chunk is embedded independently
- Chunk embeddings are mean-pooled + L2-normalized into one vector

Also routes create_embeddings() (batch) through the same guard so
both single and batch paths handle long content consistently.

The 4000-char threshold safely fits within nomic-embed-text's 2048-token
window even for dense technical content (~2-3 chars/token). The full
memory text is stored unchanged — only embedding generation is affected.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: embedding fails with 400 on long content (no chunking or size handling)

1 participant