🔎 fix: Install LadybugDB Extensions and Patch Vector Load for GitNexus Search (#12607)

Two upstream GitNexus 1.5.3 bugs combine to break query() in serve mode:

1. pool-adapter.ts calls LOAD EXTENSION fts but never INSTALL fts. The
   CI-produced .gitnexus/ artifact doesn't include the extension cache
   (~/.kuzu/extension/), so LOAD silently fails in the fresh container
   and all BM25/FTS searches return empty.

2. pool-adapter.ts only loads the FTS extension — it never loads the
   vector extension. Every CALL QUERY_VECTOR_INDEX in semanticSearch
   fails, so hybrid search's semantic leg returns empty too.

Combined, query() returns empty even for exact function names because
both the BM25 and semantic legs of RRF merging have zero inputs.
Meanwhile context()/cypher()/route_map() still work because they use
plain Cypher with no extensions.

Workaround:
- Add install-extensions.js that runs INSTALL fts and INSTALL vector
  against a throwaway database during Docker build, populating
  ~/.kuzu/extension/ with the cached extension binaries
- Sed-patch pool-adapter.js at build time to also LOAD EXTENSION vector
  alongside the existing FTS load, wrapped in try/catch
- Update deploy workflow to copy install-extensions.js into the build
  context
This commit is contained in:
Danny Avila 2026-04-10 13:41:55 -04:00 committed by GitHub
parent a121ae3dea
commit 711747a5a0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 60 additions and 0 deletions

View file

@ -18,6 +18,22 @@ RUN echo "deb http://deb.debian.org/debian trixie main" > /etc/apt/sources.list.
&& rm /etc/apt/sources.list.d/trixie.list \
&& rm -rf /var/lib/apt/lists/*
# 3. Pre-install LadybugDB FTS + vector extensions so the cache in
# ~/.kuzu/extension/ is baked into the image. Workaround for upstream
# bug: gitnexus serve's pool-adapter calls LOAD EXTENSION but never
# INSTALL, so without this step, query()'s BM25 + semantic search
# silently return empty.
COPY install-extensions.js /tmp/install-extensions.js
RUN node /tmp/install-extensions.js && rm -rf /tmp/install-extensions.js /tmp/lbug-ext-install
# 4. Patch pool-adapter.js to also LOAD EXTENSION vector after FTS.
# Upstream only loads FTS at serve time; without vector extension
# loaded, semantic search's CALL QUERY_VECTOR_INDEX fails silently.
RUN POOL_ADAPTER=/usr/local/lib/node_modules/gitnexus/dist/core/lbug/pool-adapter.js \
&& grep -q "LOAD EXTENSION fts" "$POOL_ADAPTER" \
&& sed -i "s|await available\[0\]\.query('LOAD EXTENSION fts');|await available[0].query('LOAD EXTENSION fts'); try { await available[0].query('LOAD EXTENSION vector'); } catch (e) { /* vector extension may not be installed */ }|g" "$POOL_ADAPTER" \
&& echo "pool-adapter.js patched to load vector extension"
# Copy pre-built GitNexus indexes (one per branch) and register each.
# The directory name becomes the repo name in `list_repos` output, so
# each branch lands in /LibreChat or /LibreChat-dev etc.

View file

@ -0,0 +1,43 @@
/**
* Pre-install LadybugDB extensions (FTS + vector) into the Docker image's
* extension cache (~/.kuzu/extension/). Without this, gitnexus serve's
* pool-adapter calls LOAD EXTENSION fts at runtime but fails silently
* because the extension was never installed, causing all BM25 and
* semantic queries via the query() tool to return empty.
*
* This is a workaround for an upstream GitNexus 1.5.3 bug:
* pool-adapter.ts loads extensions but never installs them, and the
* CI-produced .gitnexus/ artifact doesn't include the extension cache.
*/
const path = require('path');
const fs = require('fs');
// @ladybugdb/core lives under the globally-installed gitnexus package
const lbugPath = '/usr/local/lib/node_modules/gitnexus/node_modules/@ladybugdb/core';
const lbug = require(lbugPath);
const tmpDir = '/tmp/lbug-ext-install';
fs.mkdirSync(tmpDir, { recursive: true });
// Open a throwaway database to run INSTALL against. The extension cache
// persists in ~/.kuzu/extension/ regardless of which database was used.
const db = new lbug.Database(path.join(tmpDir, 'db'), 0, false, false);
const conn = new lbug.Connection(db);
(async () => {
try {
await conn.query('INSTALL fts');
console.log('FTS extension installed');
} catch (err) {
console.error('FTS install failed:', err.message);
process.exit(1);
}
try {
await conn.query('INSTALL vector');
console.log('Vector extension installed');
} catch (err) {
console.error('Vector install failed:', err.message);
process.exit(1);
}
})();

View file

@ -102,6 +102,7 @@ jobs:
cp .fly/gitnexus/Dockerfile deploy/Dockerfile
cp .fly/gitnexus/Caddyfile deploy/Caddyfile
cp .fly/gitnexus/entrypoint.sh deploy/entrypoint.sh
cp .fly/gitnexus/install-extensions.js deploy/install-extensions.js
echo "Deploy context:"
ls -la deploy/
echo "Indexes staged:"