feat: add Google AI (Gemini) embeddings for files and passages - #3181
Open
wayne-accelerandos wants to merge 1 commit into
Open
feat: add Google AI (Gemini) embeddings for files and passages#3181wayne-accelerandos wants to merge 1 commit into
wayne-accelerandos wants to merge 1 commit into
Conversation
Problem: - GoogleVertexClient.request_embeddings() raised NotImplementedError, causing 500 errors when creating passages with Google AI models - File processing pipeline always used OpenAIEmbedder regardless of the source's embedding_config, silently indexing files with OpenAI vectors. Since semantic_search_files queries use the agent's Google AI embedding config, search vectors never matched indexed file vectors. Changes: - Implement GoogleVertexClient.request_embeddings(): batches at 100 (Google AI limit), sanitizes empty strings, uses asyncio.gather() for parallel batch processing. GoogleAIClient inherits this implementation. - Add GoogleAIEmbedder: mirrors OpenAIEmbedder interface, uses global semaphore (3 concurrent), recursive halving retry on batch failure - Route google_ai embedding configs to GoogleAIEmbedder in sources.py, folders.py, and agent_serialization_manager.py Tests: - tests/test_google_ai_file_embedder.py: 12 unit tests for GoogleAIEmbedder - tests/test_embeddings.py: +14 unit tests for request_embeddings() on both GoogleAIClient and GoogleVertexClient (all mocked, no API key needed) - tests/test_google_ai_file_embeddings_integration.py: 4 integration tests (require GEMINI_API_KEY, skipped otherwise) - tests/configs/embedding_model_configs/google_ai_embed.json: config for parametrized embedding tests
huangyingting
pushed a commit
to repomesh/letta
that referenced
this pull request
May 17, 2026
Co-authored-by: Jin Peng <jinjpeng@Jins-MacBook-Pro.local> Co-authored-by: cpacker <packercharles@gmail.com>
huangyingting
pushed a commit
to repomesh/letta
that referenced
this pull request
May 17, 2026
Co-authored-by: Jin Peng <jinjpeng@Jins-MacBook-Pro.local> Co-authored-by: cpacker <packercharles@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
When using Google AI embedding models (e.g.,
google_ai/gemini-embedding-001), two separate code paths were broken:Passages/archival memory —
request_embeddingsinGoogleVertexClientraisedNotImplementedError, causing 500 errors on any archival memory operation with a Google AI embedding config.Files/sources —
sources.py,folders.py, andagent_serialization_manager.pyalways usedOpenAIEmbedderregardless of the source'sembedding_config. This silently produced OpenAI embedding vectors for file chunks. Sincesemantic_search_filesqueries use the agent's Google AI embedding config, search vectors never matched indexed file vectors, returning empty or incorrect results.Changes
1. Implement
GoogleVertexClient.request_embeddings()(letta/llm_api/google_vertex_client.py)asyncio.gather()Both
GoogleAIClientandGoogleVertexClientinherit this implementation.2. Add
GoogleAIEmbedder(letta/services/file_processor/embedder/google_ai_embedder.py)New embedder for the file processing pipeline, mirroring the
OpenAIEmbedderinterface:OpenAIEmbedder)log_event3. Route Google AI through
GoogleAIEmbedder(sources.py,folders.py,agent_serialization_manager.py)Added
elif embedding_config.embedding_endpoint_type == "google_ai"before the OpenAI fallback in the existing embedder selection chain: Turbopuffer → Pinecone → Google AI → OpenAI.Why the embedder must match
The embedding model used to index file chunks must be the same model used to embed search queries. Mixing OpenAI vectors (file index) with Google AI vectors (search query) produces semantically meaningless results — the vector spaces are incompatible.
Tests Added
tests/test_google_ai_file_embedder.py— 12 unit tests forGoogleAIEmbedder(all mocked, no API key needed)tests/test_embeddings.py— 14 new unit tests forrequest_embeddings()on bothGoogleAIClientandGoogleVertexClient(all mocked)tests/test_google_ai_file_embeddings_integration.py— 4 integration tests (requireGEMINI_API_KEY, skipped otherwise)tests/configs/embedding_model_configs/google_ai_embed.json— config for parametrized embedding testsNote: There are 3 pre-existing failures in
tests/test_file_processor.pyunrelated to this PR.Running the tests