Add deep AI search to rerank all components in selected sources#2430
Conversation
🎩 PreviewA preview build has been created at: |
|
Warning This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
This stack of pull requests is managed by Graphite. Learn more about stacking. |
| candidates, | ||
| seenDigests, | ||
| lexicalSearch(index, trimmedQuery, { | ||
| limit: index.length, |
There was a problem hiding this comment.
🤖 This is an AI-generated code review comment.
[HIGH] Deep search builds an unbounded candidate pool: lexicalSearch(index, ..., { limit: index.length }) followed by appending every remaining entry with Number.MAX_SAFE_INTEGER, then JSON.stringify-ing each candidate into a billed LLM rerank prompt. Output is bounded (scoreAllCandidates: false → ≤20) but input is not — there is no cap, truncation, or confirmation. Cap the deep pool at a high-but-finite N (and/or surface a confirmation when the pool is very large). At minimum, make Number.MAX_SAFE_INTEGER a deliberate, documented bound rather than effectively unlimited.
| const candidates: LexicalMatch[] = []; | ||
| const seenDigests = new Set<string>(); | ||
| const allLexicalMatches = lexicalSearch(filteredIndex, query, { | ||
| limit: filteredIndex.length, |
There was a problem hiding this comment.
🤖 This is an AI-generated code review comment.
[HIGH] Same unbounded-deep-pool concern on the Dashboard surface: lexicalSearch(filteredIndex, ..., { limit: filteredIndex.length }) then every remaining sortedIndex entry is appended, and the whole pool is JSON.stringify-ed into a billed LLM rerank with no input cap or confirmation. Bound the deep pool to a finite N or confirm before sending a very large pool; document the worst-case prompt size.
| </Button> | ||
| <Button | ||
| variant="outline" | ||
| onClick={handleDeepAiSearch} |
There was a problem hiding this comment.
🤖 This is an AI-generated code review comment.
[MEDIUM] This "Deep AI search" Button gives no busy/in-progress feedback while isReranking, unlike the sibling Sparkles button which sets a dynamic aria-label. Add e.g. aria-label={isReranking ? "Deep AI search in progress" : "Deep AI search"} (and consider a busy indicator) so the disabled-while-reranking state is announced to assistive tech.
| }; | ||
|
|
||
| const handleSmartSearch = () => { | ||
| const startAiSearch = (matches: LexicalMatch[]) => { |
There was a problem hiding this comment.
🤖 This is an AI-generated code review comment.
[LOW] startAiSearch passes no scoreAllCandidates for either smart or deep, so both default to false here, whereas the Editor uses true for smart / false for deep. Routing the new deep button through this shared helper cements a smart/deep behavior divergence between the two surfaces. Consider passing a flag (as the Editor’s startRerank does) for parity.
| const trimmedQuery = query.trim(); | ||
| const lexicalMatches = buildLexicalMatches(index, trimmedQuery); | ||
| const aiCandidateMatches = buildAiCandidateMatches(index, trimmedQuery); | ||
| const deepAiCandidateMatches = buildDeepAiCandidateMatches( |
There was a problem hiding this comment.
🤖 This is an AI-generated code review comment.
[LOW] buildDeepAiCandidateMatches (full-index lexicalSearch + full [...index].sort()) runs every render though it is only needed at click time. React Compiler memoizes this, so it is not a correctness bug. Optionally, compute only .length/enabled-state during render and build the ordered pool lazily inside the deep handler.
[MEDIUM] (Posted as a PR-level comment because this file has no changed lines in the diff to anchor an inline comment to.) |
7d30372 to
c443c7a
Compare
d363ca7 to
60b076d
Compare
c443c7a to
9fdd3d5
Compare
60b076d to
455266e
Compare
9fdd3d5 to
d9e254e
Compare
4a246ee to
8cc6222
Compare
d9e254e to
1351eea
Compare
8cc6222 to
88f3546
Compare
1351eea to
817441b
Compare

Description
Adds a Deep AI search button alongside the existing AI (smart) search button. While the standard AI search sends a limited, curated set of candidate components to the reranker, Deep AI search sends the entire searchable index — lexical hits first so truncating providers still see the most likely matches early — allowing the model to rerank across every available component in the selected sources.
Key changes:
buildDeepAiCandidateMatches, which builds a candidate pool from all indexed components (no cap), ordered with lexical matches first and remaining components appended alphabetically.canDeepRerankanddeepRerankfromuseComponentSearchV2Stateand wires them into both the Dashboard and Editor search UIs.RerankCandidatewith richer I/O metadata (type and description, not just names) and asourcefield, giving the model more signal when ranking.startAiSearch/startRerankhelpers to accept an arbitrary candidate list, removing duplication between the standard and deep paths.componentReferenceToCandidateto accept an optionalsourceargument and serialize I/O types (including complex object types) viaJSON.stringify.Related Issue and Pull requests
Type of Change
Checklist
Screenshots (if applicable)
Test Instructions
Additional Comments
scoreAllCandidatesis intentionally set tofalsefor deep rerank to avoid scoring overhead across the full index on every result row. The standard AI search retainsscoreAllCandidates: trueso relevance percentages continue to appear on displayed results.