Skip to content

Improvement/improve retrieval - #66

Merged
bernoussama merged 7 commits into
masterfrom
improvement/improve-retrieval
Jun 22, 2026
Merged

Improvement/improve retrieval#66
bernoussama merged 7 commits into
masterfrom
improvement/improve-retrieval

Conversation

@bernoussama

@bernoussama bernoussama commented Jun 22, 2026

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • New Features
    • Updated search fallback: exact keyword first, then hybrid, then tiered keyword if hybrid is unavailable.
    • Keyword searches now support exact vs tiered strategies (including improved hybrid re-ranking when RRF is used).
    • Search tooling behavior (CLI/MCP) updated to include and report the selected keyword strategy.
  • Documentation
    • Expanded search command guidance, including advanced keyword syntax and -- for leading-dash queries.
    • Added local/hosted benchmarking documentation.
  • Chores
    • Added Unicode-safe search indexes and new migration/benchmark scripts.
    • Bumped CLI/plugin versions (1.3.0 → 1.3.1).

…rgonomics

Address 8 local-search bugs:

- Empty/whitespace query no longer crashes the embedder; rejected upfront
  (CLI parseSearchQuery, MCP zod schema, local-backend guard).
- --limit now enforces integer 1-20 (was silently 0/empty); local embed
  --limit requires >= 1. Docs corrected (default 1, not 3).
- Leading-dash queries (`-1`, `v2.0-beta-1`) surface a `--` separator
  hint instead of a bare unknown-option error.
- ftsQuery rewritten to parse and honor FTS5 operators (AND/OR/NOT, NEAR,
  column filters, prefix terms, groups) or reject malformed syntax with a
  clear message; auto mode falls through to hybrid on a keyword syntax error.
- Semantic ranking improved by prefixing query embeddings with the required
  BGE v1.5 retrieval instruction (document side unchanged, no re-embedding).
- Documented `clanker mcp` for batch/repeated queries to avoid cold starts,
  and the benign node-llama-cpp tokenizer warning.
@coderabbitai

coderabbitai Bot commented Jun 22, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@bernoussama, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 52 minutes and 38 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan refill rate.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, the refill rate gradually slows as usage increases. The highest same-day bursts are limited more strictly.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: c402e3e4-a672-465e-b6ef-4cf49eb92683

📥 Commits

Reviewing files that changed from the base of the PR and between 7b00797 and 559752e.

📒 Files selected for processing (1)
  • packages/cli/src/index.ts

Walkthrough

This PR introduces a two-tier keyword search strategy (exact / tiered) throughout the entire stack: DB layer with new Unicode GIN indexes, tRPC router, CLI MCP backends, auto-search fallback logic, and WebMCP provider. The hybrid-unavailable fallback is replaced with a tiered keyword attempt. It also adds RRF fusion to hosted hybrid search and introduces a complete local-embeddings benchmark suite plus a hosted retrieval benchmark using Cloudflare Workers and Vectorize.

Changes

Keyword Search Strategy Refactor

Layer / File(s) Summary
DB: Unicode indexes and HostedKeywordStrategy
packages/db/src/search.ts, packages/db/src/migrations/0006_unicode_search.sql, packages/db/src/migrations/meta/_journal.json, packages/db/src/create-search-indexes.ts, packages/db/src/search.test.ts
Adds HostedKeywordStrategy type; refactors searchSolutions SQL into exactQueryText/relaxedQueryText branches; creates Unicode GIN tsvector and trigram indexes via migration and a standalone script; tests cover tiered prefix relaxation, Unicode search, and leading-hyphen handling.
API: hosted hybrid RRF fusion
packages/api/src/semantic/search.ts, packages/api/src/semantic/search.test.ts
Exports HostedHybridFusion and HOSTED_HYBRID_FUSION; extends searchSolutionsHybrid with optional fusion param; increases candidate counts and passes strategy:"tiered" to keyword search; adds weighted RRF merge that returns early when fusion="rrf".
API router: keywordStrategy input
packages/api/src/routers/solutions.ts, packages/api/src/routers/solutions.test.ts
Adds keywordStrategy enum input (default "exact") to solutions.search; forwards it as strategy to searchSolutions; records keyword_strategy in analytics for keyword-mode searches.
CLI MCP: backend types, local FTS rewrite, and query embedding
packages/cli/src/mcp/backend.ts, packages/cli/src/mcp/local-backend.ts, packages/cli/src/mcp/local-semantic.ts, packages/cli/src/mcp/local-backend.test.ts, packages/cli/src/mcp/local-semantic.test.ts
Adds KeywordSearchStrategy type and optional searchExactKeyword to SolutionBackend; replaces ftsQuery with a full FTS5 translator (localFtsQuery, FtsQuerySyntaxError, advanced/simple modes); extracts searchLocalKeywordExact/Relaxed/Semantic helpers; adds LOCAL_QUERY_INSTRUCTION prefix to queryEmbeddingText.
CLI MCP: auto-search fallback and remote backend
packages/cli/src/mcp/auto-search.ts, packages/cli/src/mcp/remote-backend.ts, packages/cli/src/mcp/format.ts, packages/cli/src/mcp/auto-search.test.ts
SearchAttempt gains keywordStrategy; searchWithAutoFallback uses searchExactKeyword for first probe and tiered keyword instead of hybrid-unavailable return; RemoteBackend defaults keywordStrategy:"tiered" and adds searchExactKeyword; formatSearchAttempts labels show "keyword exact"/"keyword tiered".
WebMCP provider
apps/web/src/components/webmcp-provider.tsx, apps/web/src/components/webmcp-provider.test.ts, apps/web/src/components/webmcp-provider.test.tsx, apps/web/src/app/(site)/solutions/solutions-page.tsx
search helper forwards keywordStrategy to tRPC; non-auto keyword mode uses "tiered"; hybrid-unavailable path replaced with tiered keyword search; tool description strings updated; web solutions page passes keywordStrategy:"tiered" for keyword mode.
CLI server, index UX, and docs
packages/cli/src/mcp/server.ts, packages/cli/src/index.ts, packages/cli/src/index.test.ts, packages/cli/src/mcp/server.test.ts, packages/cli/commands/search-solutions.md, packages/cli/skills/.../*.md
Updates SERVER_INSTRUCTIONS and tool descriptions to reflect the new sequence; adds SEARCH_LIMIT_MIN/MAX validation, blank-query guard, and leading-dash Commander error enhancement; documents advanced FTS5 syntax and -- separator.

Benchmark Infrastructure

Layer / File(s) Summary
Benchmark types and corpus
packages/cli/benchmarks/local-embeddings/types.ts, .../corpus.ts
Defines comprehensive TypeScript types for categories, languages, documents, queries, corpus, models, backends, and result shapes; introduces 200-document/100-query static corpus with category/language mappings and build/validate functions.
Metrics, quality gate, and profiles
packages/cli/benchmarks/local-embeddings/metrics.ts, .../quality-gate.ts, .../profiles.ts, .../benchmark.test.ts
Implements nDCG@10, MRR@10, recall@k metrics with bootstrap confidence intervals; evaluateRetrievalGate computes overall and per-slice nDCG deltas; profile-specific document/query formatting with model-native prefixes; corpus/metrics/gate tests validate shape, behavior, and determinism.
Model registry and local worker
packages/cli/benchmarks/local-embeddings/models.ts, .../worker.ts
BENCHMARK_MODELS registry with SHA-256 integrity checks and ensureModel download/verify; worker loads local llama embedder, seeds SQLite vectors, executes cold/full benchmark phases with shuffled queries, and returns structured timing/memory/ranking metrics.
Local benchmark runner and config
packages/cli/benchmarks/local-embeddings/run.ts, .../tsconfig.json, .../README.md, .gitignore
CLI orchestrator parses options, spawns worker subprocesses, computes local FTS keyword rankings, shapes quality/performance metrics, and writes JSON/Markdown reports; includes configuration, documentation, and output path ignoring.
Hosted retrieval benchmark infrastructure
packages/infra/src/retrieval-benchmark-worker.ts, packages/infra/retrieval-benchmark.run.ts, packages/db/benchmarks/hosted-retrieval.ts, packages/infra/src/alchemy-run.test.ts, packages/db/package.json, packages/infra/tsconfig.json, packages/db/tsconfig.benchmarks.json
Cloudflare Worker with authenticated /seed and /query endpoints using Workers AI + Vectorize; Alchemy provisioning script deploys worker with vector index; DB orchestration creates disposable Postgres, seeds/queries worker, evaluates retrieval gate, writes JSON report, and cleans up resources.

Version Bumps and Scripts

Layer / File(s) Summary
Version bumps and new scripts
packages/cli/package.json, packages/cli/openclaw.plugin.json, packages/cli/.claude-plugin/plugin.json, packages/cli/.codex-plugin/plugin.json, package.json
Bumps CLI and plugin manifests from 1.3.0 to 1.3.1; adds benchmark:local-embeddings, benchmark:hosted-retrieval, db:migrate:search-indexes scripts; adds check-types script to CLI package.

Sequence Diagram(s)

sequenceDiagram
  participant Client as CLI / WebMCP
  participant AutoSearch as searchWithAutoFallback
  participant RemoteBackend as RemoteBackend
  participant TRPC as tRPC solutions.search
  participant DB as PostgreSQL searchSolutions

  Client->>AutoSearch: query, limit, allowHybridFallback
  AutoSearch->>RemoteBackend: searchExactKeyword({ query, limit })
  RemoteBackend->>TRPC: mode:"keyword", keywordStrategy:"exact"
  TRPC->>DB: strategy:"exact"
  DB-->>TRPC: results
  TRPC-->>RemoteBackend: results
  RemoteBackend-->>AutoSearch: results

  alt exact results found
    AutoSearch-->>Client: results + attempts[keyword exact]
  else empty
    AutoSearch->>RemoteBackend: search({ mode:"hybrid" })
    RemoteBackend->>TRPC: mode:"hybrid"
    TRPC-->>RemoteBackend: hybridResults
    alt hybrid succeeds
      AutoSearch-->>Client: hybridResults + attempts[keyword exact, hybrid]
    else hybrid unavailable or error
      AutoSearch->>RemoteBackend: search({ mode:"keyword", keywordStrategy:"tiered" })
      RemoteBackend->>TRPC: mode:"keyword", keywordStrategy:"tiered"
      TRPC->>DB: strategy:"tiered"
      DB-->>AutoSearch: tieredResults
      AutoSearch-->>Client: tieredResults + attempts[keyword exact, hybrid?, keyword tiered]
    end
  end
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Poem

🐇 Hopping through the query haze,
Exact first, then hybrid blaze,
Tiered fallback saves the day,
RRF to show the way.
Unicode indexes shine so bright—
No more lost results at night! ✨

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 13.10% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'Improvement/improve retrieval' is vague and generic. It uses non-descriptive terms that don't convey the specific nature of the substantial changes across search strategies, keyword/semantic/hybrid modes, benchmarking infrastructure, and CLI behavior. Consider a more specific title such as 'Add keyword strategy modes and retrieval benchmarking infrastructure' or 'Implement tiered keyword search with hybrid fallback and benchmarks' to clearly communicate the main changes.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch improvement/improve-retrieval

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 11

🧹 Nitpick comments (1)
packages/db/tsconfig.json (1)

10-11: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Keep benchmark sources in a typechecked TS project.

This excludes benchmarks/** from the package TS project while the same package now ships a benchmark entry script. Consider a dedicated tsconfig.benchmarks.json (or include this folder) so CI catches drift before runtime.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/db/tsconfig.json` around lines 10 - 11, The exclude array in the
tsconfig.json file currently excludes the benchmarks directory from type
checking. Since the package now includes a benchmark entry script, either remove
"benchmarks" from the exclude array to include benchmarks in the main type
checking, or create a dedicated tsconfig.benchmarks.json file that includes the
benchmarks folder so TypeScript type checking can catch any drift in the
benchmarks before runtime.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/web/src/components/webmcp-provider.tsx`:
- Around line 74-77: When recording the attempt result in the return statement
for non-auto mode keyword searches, the attempts array is missing the
keywordStrategy field. Since the search function is called with "tiered" as the
strategy when mode is "keyword" (as seen on line 75), add the keywordStrategy
property to the attempts object to include this execution metadata. The
keywordStrategy should be set to "tiered" when mode equals "keyword", otherwise
it should be undefined or omitted, to ensure the recorded metadata matches what
was actually passed to the search function.

In `@packages/cli/benchmarks/local-embeddings/metrics.ts`:
- Around line 56-85: The summarizeMetrics function does not validate the
bootstrapSamples parameter, so if it is set to 0 or a negative number, the
samples array becomes empty and the quantile function silently returns 0 for
both low and high confidence interval bounds, producing misleading results. Add
a validation check at the beginning of the summarizeMetrics function (similar to
the existing check for queries.length === 0) to ensure bootstrapSamples is
greater than 0 and throw an appropriate error if the validation fails.

In `@packages/cli/benchmarks/local-embeddings/models.ts`:
- Around line 78-83: Add a bounded timeout to prevent indefinite hangs during
model downloads in the fetch call. Implement an AbortController with a timeout
that will abort the request after a specified duration. Wrap the entire download
block (the fetch, pipeline, and fileSha256 operations) in a try-catch block, and
in the catch handler, clean up the temporary file at temporaryPath using
filesystem operations like unlink or rm before re-throwing the error. This
ensures that partial downloads are removed when the operation fails due to
timeout or network errors.

In `@packages/cli/benchmarks/local-embeddings/README.md`:
- Around line 27-29: The README.md file at lines 27-29 contains inaccurate
documentation about the download verification process. The text claims that
downloads are checked against both SHA-256 and byte size, but the actual
implementation in models.ts only validates SHA-256. Update the wording in the
README to accurately reflect that only SHA-256 verification is performed,
removing the reference to byte size validation. This ensures the documentation
accurately describes the current behavior of the benchmark tool.

In `@packages/cli/benchmarks/local-embeddings/worker.ts`:
- Around line 106-123: The runCold function does not handle exceptions safely
because cleanup code is only executed on the happy path. If any operation like
loaded.embed(query) or result assignments throws an exception, the dispose calls
for loaded.context, loaded.model, and loaded.llama will never execute, causing
resource leaks. Refactor the function by wrapping all operations starting from
loadEmbedder through the result object creation in a try block, then move all
three dispose calls (loaded.context.dispose, loaded.model.dispose, and
loaded.llama.dispose) into a finally block to ensure cleanup always runs
regardless of whether an exception occurs. Apply this same pattern to the other
worker functions mentioned in the comment (around lines 153-220).

In `@packages/cli/src/index.test.ts`:
- Around line 348-373: The test "passes a leading-dash query via the --
separator" does not actually test a leading-dash query because it uses "version"
as the positional argument after the -- separator. To fix this, replace the
string "version" with an actual leading-dash query string (such as "-version" or
"-mode") in the searchProgram.parseAsync call to properly validate that
leading-dash queries are handled correctly through the -- separator.

In `@packages/cli/src/index.ts`:
- Around line 590-599: The limit validation in the options parsing has a bug
where Number.parseInt truncates decimal inputs (e.g., "2.5" becomes 2), allowing
them to pass the Number.isInteger() check when they should fail. Replace the
Number.parseInt(String(options.limit), 10) call with
Number(String(options.limit)) to preserve decimal values so that inputs like 2.5
remain as floats and correctly fail the integer validation, ensuring the error
message about requiring an integer is properly enforced.

In `@packages/cli/src/mcp/local-backend.ts`:
- Around line 125-127: The tokenizeFtsQuery function at line 125 splits
parentheses into separate tokens, which prevents NEAR(...) syntax from being
recognized as a single token and prevents the NEAR passthrough logic at line 252
from executing. Additionally, the runtime search paths at lines 390/394 and 490
use localFtsQuery and localRelaxedFtsQuery which bypass the operator-aware
parsing validation in the main ftsQuery function, causing advanced FTS5 syntax
like AND/OR/NOT, column filters, and NEAR(...) to not be consistently applied.
Modify tokenizeFtsQuery to preserve parentheses as part of NEAR tokens instead
of splitting them, and refactor localFtsQuery and localRelaxedFtsQuery to apply
the same operator-aware parsing and validation logic as ftsQuery so that
advanced syntax is consistently handled across all search modes (keyword,
hybrid, and auto).

In `@packages/db/benchmarks/hosted-retrieval.ts`:
- Around line 54-63: The post function lacks a timeout mechanism on its fetch
call, which can cause the benchmark to hang indefinitely if a request stalls.
Add a timeout configuration to the fetch call in the post function by including
an AbortSignal with a reasonable deadline (typically a few seconds for API
calls). You can create an AbortController, set a timeout using setTimeout to
abort it after the desired duration, and pass the controller's signal in the
fetch options to ensure requests don't hang the benchmark run.

In `@packages/infra/src/retrieval-benchmark-worker.ts`:
- Around line 41-43: The validation for the documents payload only checks if it
is a non-empty array, but does not validate the structure of individual document
items within that array. Malformed items (missing the text field or other
required properties) can pass through and cause errors later. Add additional
validation logic after the array length check to iterate through each document
and verify that required properties (like text) are present. If any document
item is malformed, return a 400 error with an appropriate message indicating the
invalid document structure. Apply the same validation pattern to the other
request payload validation around lines 61-67 to ensure consistency across all
ingestion points.
- Around line 71-77: The code at line 76 in the query loop assumes
vectors[index] exists without validation, which can lead to unclear errors if
Workers AI returns fewer vectors or wrong dimensions. Add the same embedding
sanity check that already exists in the /seed path to validate the vectors array
and its dimensions before accessing vectors[index] in the for loop that queries
SOLUTION_VECTORS. This will ensure the code fails fast with a clear error
message rather than throwing during the vector query operation.

---

Nitpick comments:
In `@packages/db/tsconfig.json`:
- Around line 10-11: The exclude array in the tsconfig.json file currently
excludes the benchmarks directory from type checking. Since the package now
includes a benchmark entry script, either remove "benchmarks" from the exclude
array to include benchmarks in the main type checking, or create a dedicated
tsconfig.benchmarks.json file that includes the benchmarks folder so TypeScript
type checking can catch any drift in the benchmarks before runtime.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 7b7dbbbe-83b4-40e3-9f3b-c35948ef6036

📥 Commits

Reviewing files that changed from the base of the PR and between 36f30f4 and d60d7ea.

📒 Files selected for processing (53)
  • .gitignore
  • apps/web/src/app/(site)/solutions/solutions-page.tsx
  • apps/web/src/components/webmcp-provider.test.ts
  • apps/web/src/components/webmcp-provider.test.tsx
  • apps/web/src/components/webmcp-provider.tsx
  • package.json
  • packages/api/src/routers/solutions.test.ts
  • packages/api/src/routers/solutions.ts
  • packages/api/src/semantic/search.test.ts
  • packages/api/src/semantic/search.ts
  • packages/cli/.claude-plugin/plugin.json
  • packages/cli/.codex-plugin/plugin.json
  • packages/cli/benchmarks/local-embeddings/README.md
  • packages/cli/benchmarks/local-embeddings/benchmark.test.ts
  • packages/cli/benchmarks/local-embeddings/corpus.ts
  • packages/cli/benchmarks/local-embeddings/metrics.ts
  • packages/cli/benchmarks/local-embeddings/models.ts
  • packages/cli/benchmarks/local-embeddings/profiles.ts
  • packages/cli/benchmarks/local-embeddings/quality-gate.ts
  • packages/cli/benchmarks/local-embeddings/run.ts
  • packages/cli/benchmarks/local-embeddings/tsconfig.json
  • packages/cli/benchmarks/local-embeddings/types.ts
  • packages/cli/benchmarks/local-embeddings/worker.ts
  • packages/cli/commands/search-solutions.md
  • packages/cli/openclaw.plugin.json
  • packages/cli/package.json
  • packages/cli/skills/clankeroverflow-cli/SKILL.md
  • packages/cli/skills/clankeroverflow-mcp/SKILL.md
  • packages/cli/src/index.test.ts
  • packages/cli/src/index.ts
  • packages/cli/src/mcp/auto-search.test.ts
  • packages/cli/src/mcp/auto-search.ts
  • packages/cli/src/mcp/backend.ts
  • packages/cli/src/mcp/format.ts
  • packages/cli/src/mcp/local-backend.test.ts
  • packages/cli/src/mcp/local-backend.ts
  • packages/cli/src/mcp/local-semantic.test.ts
  • packages/cli/src/mcp/local-semantic.ts
  • packages/cli/src/mcp/remote-backend.ts
  • packages/cli/src/mcp/server.test.ts
  • packages/cli/src/mcp/server.ts
  • packages/db/benchmarks/hosted-retrieval.ts
  • packages/db/package.json
  • packages/db/src/create-search-indexes.ts
  • packages/db/src/migrations/0006_unicode_search.sql
  • packages/db/src/migrations/meta/_journal.json
  • packages/db/src/search.test.ts
  • packages/db/src/search.ts
  • packages/db/tsconfig.json
  • packages/infra/retrieval-benchmark.run.ts
  • packages/infra/src/alchemy-run.test.ts
  • packages/infra/src/retrieval-benchmark-worker.ts
  • packages/infra/tsconfig.json

Comment thread apps/web/src/components/webmcp-provider.tsx
Comment thread packages/cli/benchmarks/local-embeddings/metrics.ts
Comment thread packages/cli/benchmarks/local-embeddings/models.ts Outdated
Comment thread packages/cli/benchmarks/local-embeddings/README.md
Comment thread packages/cli/benchmarks/local-embeddings/worker.ts Outdated
Comment thread packages/cli/src/index.ts Outdated
Comment on lines +125 to +127
if (char === "(" || char === ")") {
flushWord();
tokens.push(char === "(" ? { type: "lparen" } : { type: "rparen" });

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Advanced FTS5 behavior is not applied on runtime search paths.

Line 390/Line 394 and Line 490 route keyword execution through localFtsQuery/localRelaxedFtsQuery, so operator-aware parsing/validation in ftsQuery never executes for actual keyword/hybrid searches. Also, the NEAR passthrough at Line 252 is unreachable because tokenizeFtsQuery splits ( into a separate token at Line 125, so NEAR(...) cannot remain a single token.

This creates a user-visible contract gap for advanced queries (AND/OR/NOT, column filters, NEAR(...)) and for syntax-rejection behavior.

Proposed direction
-export function searchLocalKeywordExact(db: LocalDb, queryText: string, limit: number) {
-  return searchLocalKeywordExpression(db, localFtsQuery(queryText.trim()), limit);
-}
+export function searchLocalKeywordExact(db: LocalDb, queryText: string, limit: number) {
+  return searchLocalKeywordExpression(db, ftsQuery(queryText.trim()), limit);
+}

Then align the hybrid keyword leg and relaxed fallback strategy so advanced syntax is preserved (or explicitly disallowed) consistently across keyword, hybrid, and auto.

Also applies to: 252-254, 389-395, 490-503

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/cli/src/mcp/local-backend.ts` around lines 125 - 127, The
tokenizeFtsQuery function at line 125 splits parentheses into separate tokens,
which prevents NEAR(...) syntax from being recognized as a single token and
prevents the NEAR passthrough logic at line 252 from executing. Additionally,
the runtime search paths at lines 390/394 and 490 use localFtsQuery and
localRelaxedFtsQuery which bypass the operator-aware parsing validation in the
main ftsQuery function, causing advanced FTS5 syntax like AND/OR/NOT, column
filters, and NEAR(...) to not be consistently applied. Modify tokenizeFtsQuery
to preserve parentheses as part of NEAR tokens instead of splitting them, and
refactor localFtsQuery and localRelaxedFtsQuery to apply the same operator-aware
parsing and validation logic as ftsQuery so that advanced syntax is consistently
handled across all search modes (keyword, hybrid, and auto).

Comment thread packages/db/benchmarks/hosted-retrieval.ts Outdated
Comment thread packages/infra/src/retrieval-benchmark-worker.ts
Comment thread packages/infra/src/retrieval-benchmark-worker.ts
- webmcp-provider: record keywordStrategy in non-auto keyword attempts
- metrics: validate bootstrapSamples is an integer >= 1
- models: add 5-min download timeout + temp-file cleanup on failure
- worker: dispose model handles and temp dirs in try/finally
- index: use Number() not parseInt() for embed --limit (decimals rejected)
- index.test: actually exercise leading-dash query via -- separator
- hosted-retrieval: add 60s timeout to benchmark post() requests
- retrieval-benchmark-worker: validate item shapes + /query dimension check
- db: add tsconfig.benchmarks.json + check-types script for benchmark typecheck
- README: correct download verification wording (SHA-256 only)
@bernoussama
bernoussama merged commit b758081 into master Jun 22, 2026
2 checks passed
@coderabbitai coderabbitai Bot mentioned this pull request Jun 24, 2026
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.

1 participant