You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
sdl.context defaults to hybrid retrieval end-to-end: hybrid seeding (entitySearch
via FTS + vector + RRF) now runs alongside path-inference, not instead of it.
Path-inferred refs are preserved first; hybrid adds semantically related refs
the heuristic misses. TaskOptions.semantic (default true) and TaskOptions.includeRetrievalEvidence (default true) toggle the behavior.
Retrieval evidence surfaced on sdl.context responses: ContextSeedResult
gained an evidence?: RetrievalEvidence field, captured from Stage 1
entitySearch and propagated into AgentContextPayloadSchema.retrievalEvidence.
The Zod schema now accepts sources, candidateCountPerSource, topRanksPerSource, fusionLatencyMs, fallbackReason, ftsAvailable, and vectorAvailable — so callers can see which lanes contributed to their
results.
Entity-search telemetry: entitySearch emits logger.info("Entity search", { eventType: "entity_search", ... }) at every
return path (fallback-to-legacy, db-connection-fail, main success) with
latency, per-source candidate counts, and ftsAvailable/vectorAvailable.
This makes hybrid contribution visible for sdl.context calls (previously
only sdl.symbol.search emitted hybrid telemetry).
Multi-model embedding pass: new semantic.additionalModels: string[]
config option. The indexer now loops over [model, ...additionalModels]
calling refreshSymbolEmbeddings per model, so both jina-embeddings-v2-base-code
and nomic-embed-text-v1.5 vectors can be populated from a single index run.
Hybrid fusion can then RRF-merge both vector lanes alongside FTS.
Changed
ONNX embedding models unbundled: jina-embeddings-v2-base-code (~162MB) and nomic-embed-text-v1.5 (~137MB) are no longer shipped inside the npm tarball.
Published package size dropped from ~215 MB to ~1.6 MB. Both models are now
fetched on npm install by scripts/postinstall-models.mjs into the platform
cache directory (%LOCALAPPDATA%/sdl-mcp/models/ on Windows, ~/.cache/sdl-mcp/models/ elsewhere). Set SDL_MCP_SKIP_MODEL_DOWNLOAD=1 to
skip the postinstall download.
Model registry fallback URLs: ModelInfo.fallbackDownloadUrls points at
the project's GitHub Releases mirror (tag models-v1) and is used
automatically when the primary HuggingFace URL fails at postinstall time or
on lazy runtime download. Both bundled models now have primary HuggingFace
URLs populated (jina previously had none).
Fixed
Hybrid retrieval FTS and vector lanes silently returned zero: The QUERY_FTS_INDEX and QUERY_VECTOR_INDEX calls in src/retrieval/orchestrator.ts
were malformed — missing RETURN clause (rejected by the LadybugDB binder),
passing the index name as a parameter (must be a literal), and passing topK
positionally (must be K := <int>). Every invocation threw and the error was
swallowed at logger.debug level, making both lanes invisible contributors
with zero candidates. Fixed in four call sites (two in hybridSearch, two in entitySearch). The fts.conjunctive config flag is now threaded through to
the FTS call. Index and table names are validated against a strict identifier
whitelist before interpolation. Swallow-catch logging bumped from debug → warn so future binder errors surface at the default log level.
Breaking Changes
API Consolidation: Reduced tool surface from 37 to 34 actions
Removed sdl.agent.context: Use sdl.context (Code Mode) for task-shaped context retrieval
Removed sdl.context.summary: Use sdl.context which provides structured cards + skeletons
Merged sdl.symbol.getCards into sdl.symbol.getCard:
Single symbol: { symbolId: "..." } (unchanged)
Batch: { symbolIds: ["...", "..."] } (was separate tool)
Response shape unchanged for each mode
Performance
Deferred fresh-DB index bootstrap: Fresh databases now create only base schema (node/edge tables)
during initialization, deferring 19 secondary indexes and retrieval indexes until after the first
successful full index completes. This removes index maintenance overhead from the ingestion-critical
path. Existing DB initialization is unchanged.
Write connection pool: Replaced single write connection with a pool of 4 warm connections using
two-layer concurrency control (connection acquisition + serialized execution). Enables instant
failover and hides connection acquisition latency from the batch drain loop.
Background batch drain: Batch persistence accumulator now uses an async background writer with
auto-enqueue at threshold (200 rows). Parsing threads are never blocked by DB writes.
TS engine batch persistence: TypeScript pass1 indexing now uses the same BatchPersistAccumulator
as the Rust engine, eliminating per-file transaction overhead and enabling write pipelining.
Fixed
Repository scanning descriptor cleanup: Replaced async node:fs/promises.glob()
traversal in the indexer with an explicit directory walker that closes every
opened directory handle deterministically. The same walker now backs Go,
Java/Kotlin, and C# import-resolution fallback scans to avoid leaving identical
traversal leak candidates in place.