feat(graphile-llm): auto-embed unifiedSearch text for hybrid vector+keyword search#1290
Merged
Conversation
…eyword search
When graphile-llm is active with a configured embedder, unifiedSearch
now automatically embeds the text query and includes pgvector in the
RRF rank fusion alongside text adapters (tsvector, BM25, trgm).
Changes:
- graphile-search plugin.ts: apply function accepts both String and
{ __text, __vector } object shape. When __vector is present, pgvector
adapter participates in the OR + RRF fusion.
- LlmTextSearchPlugin: resolver wrapper detects unifiedSearch string
values, embeds them via the configured embedder, and transforms to
{ __text, __vector } before the apply function runs.
- Graceful degradation: if embedder returns null (quota exceeded) and
text adapters exist, falls back to text-only search. If no text
adapters available, throws explicit error.
- 12 unit tests for embedding transformation logic
- 4 integration tests with mock LLM plugin verifying RRF fusion
Closes #1054 (graphile-llm + unifiedSearch integration)
Contributor
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
This comment has been minimized.
This comment has been minimized.
…atible integration tests
Grafast plan-based execution skips resolve() on connection fields,
so the mock LLM plugin's resolver wrapper never fires in direct
schema execution. Replace with tests that verify the equivalent
end-user behavior: unifiedSearch + vectorEmbedding combined produce
correct RRF fusion across all 4 adapters.
The object-shape handling ({ __text, __vector }) is tested via
unit tests in graphile-llm/src/__tests__/unified-search-embedding.test.ts.
The full resolver-wrapper → apply flow is exercised in PostGraphile
server-level tests (graphile-llm CI).
…ion input detection, text-search scope - Fix RAG plugin: move chunk table discovery from init to build hook so @hasChunks smart tags are visible; scan pgCodecs (not pgResources) - Fix text-search-plugin: use context.Self.name instead of scope.inputObjectTypeName for PostGraphile v5 type identification - Fix text-mutation-plugin: detect create input types (ArticleInput) that lack isPgBaseInput scope flag via type name convention fallback - Fix makeTestSmartTagsPlugin: apply tags during build hook (not init) with before: ['LlmRagPlugin'] ordering to ensure tags are set first - Export embedTextInWhere from text-search-plugin, remove duplicated re-implementation in unit tests - Extract injectScoreAndRank helper in graphile-search plugin.ts to de-duplicate 60-line block repeated 3 times - Add 7 real Ollama nomic-embed integration tests (Suite 7) covering text-only, vector-only, RRF fusion, and semantic ranking - Add CI config for graphile-llm tests with Ollama service All 52 graphile-llm tests pass, all 75 graphile-search tests pass.
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.
Summary
When
graphile-llmis active with a configured embedder,unifiedSearch: "text"now automatically embeds the text and includes pgvector in the RRF rank fusion — zero client changes, zero new fields.Architecture (resolver-wrapper pattern):
Graceful degradation:
null(quota exceeded) + text adapters exist → falls back to text-only search (no error)null+ NO text adapters (vector-only table) → throws explicit errorKey changes:
graphile-search/plugin.tsapplyfunction: accepts{ __text, __vector }object in addition to plain Stringgraphile-llm/text-search-plugin.tsembedTextInWhere: detectsunifiedSearchkey, embeds text, transforms to object shapehasTextAdaptersparameter threads through for degradation logicTests: 12 unit tests (no DB) + 4 integration tests with mock LLM plugin verifying pgvector participates in RRF fusion when embedding is injected.
Closes #1054
Link to Devin session: https://app.devin.ai/sessions/4a9f098c74fb4cb6a9b6868fcff321db
Requested by: @pyramation