fix: gemini provider custom baseUrl and add search note by rag#473
fix: gemini provider custom baseUrl and add search note by rag#473africa1207 wants to merge 2 commits intoglowingjade:mainfrom
Conversation
WalkthroughAdds a per-request baseUrl option to GeminiProvider and introduces a RAG search feature: a new modal UI, header button, command to open it, related styles, and a minor prop change to SimilaritySearchResults. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor User
participant ChatHeader
participant AppMain as App / Main
participant RAGSearchModal
participant RAGEngine
User->>ChatHeader: click "RAG Search" button
ChatHeader->>AppMain: request open RAG modal
AppMain->>RAGSearchModal: new RAGSearchModal(app, getRAGEngine)
RAGSearchModal->>RAGEngine: getRAGEngine() (lazy)
RAGEngine-->>RAGSearchModal: engine ready
User->>RAGSearchModal: enter query / press Search
RAGSearchModal->>RAGEngine: processQuery(query, onQueryProgressChange)
RAGEngine-->>RAGSearchModal: progress updates & results
RAGSearchModal-->>User: render progress and results (SimilaritySearchResults)
sequenceDiagram
autonumber
actor Caller
participant GeminiProvider
participant GeminiClient as Gemini Client
Caller->>GeminiProvider: generate()/stream()/embed()
activate GeminiProvider
note over GeminiProvider: Build RequestOptions via getRequestOptions()<br/>(may include baseUrl)
GeminiProvider->>GeminiClient: getGenerativeModel(model, RequestOptions)
alt Non-streaming
GeminiClient-->>GeminiProvider: content response
else Streaming
GeminiClient-->>GeminiProvider: stream events
end
opt Embedding
GeminiProvider->>GeminiClient: getEmbedding(input, RequestOptions)
GeminiClient-->>GeminiProvider: embedding vector
end
GeminiProvider-->>Caller: result/stream handle
deactivate GeminiProvider
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Poem
✨ Finishing Touches
🧪 Generate unit tests
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (3)
src/core/llm/gemini.ts (3)
63-69: Type the RequestOptions and lightly validate baseUrlUse the library’s RequestOptions type and (optionally) guard the scheme to http/https to avoid accidental misconfigurations.
Apply within this range:
- private getRequestOptions(): any { - const options: any = {} + private getRequestOptions(): RequestOptions { + const options: RequestOptions = {} if (this.provider.baseUrl) { - options.baseUrl = this.provider.baseUrl + // Optional: restrict to http(s) only + const u = new URL(this.provider.baseUrl) + if (u.protocol !== 'http:' && u.protocol !== 'https:') { + throw new Error(`Unsupported baseUrl scheme: ${u.protocol}`) + } + options.baseUrl = this.provider.baseUrl } return options }Add this import near the top (type-only import; no runtime impact):
import type { RequestOptions } from '@google/generative-ai'
92-104: Passing RequestOptions to getGenerativeModel: LGTM; consider avoiding duplicate systemInstructionThe RequestOptions hook-up looks correct. Minor: you set systemInstruction both in getGenerativeModel(...) and again in generateContent(...). Keeping only one source reduces ambiguity.
Optional tweak (outside this hunk): drop systemInstruction from the generateContent request body and keep it only in the model config.
164-175: Streaming path correctly propagates baseUrlGood parity with the non-streaming path; same note about duplicate systemInstruction applies here.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
src/core/llm/gemini.ts(4 hunks)
🔇 Additional comments (2)
src/core/llm/gemini.ts (2)
58-61: Good: enabling baseUrl via RequestOptionsComment is accurate and aligns with the change. No functional concerns here.
449-450: Embedding path now respects baseUrlCorrect usage of RequestOptions with getGenerativeModel before embedContent.
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (9)
src/components/chat-view/SimilaritySearchResults.tsx (3)
38-46: autoOpen acts as an initial-only flag; confirm intent or rename to initialOpen.Prop changes to autoOpen after mount won’t update isOpen. If that’s intentional, consider renaming to initialOpen for clarity; otherwise, sync via useEffect.
22-33: Make clickable divs accessible (keyboard + semantics).Add role="button", tabIndex={0}, and handle Enter/Space for both the item and the trigger.
- <div onClick={handleClick} className="smtcmp-similarity-search-item"> + <div + onClick={handleClick} + onKeyDown={(e) => { + if (e.key === 'Enter' || e.key === ' ') { + e.preventDefault() + handleClick() + } + }} + role="button" + tabIndex={0} + className="smtcmp-similarity-search-item" + >- <div - onClick={() => { - setIsOpen(!isOpen) - }} - className="smtcmp-similarity-search-results__trigger" - > + <div + onClick={() => setIsOpen(!isOpen)} + onKeyDown={(e) => { + if (e.key === 'Enter' || e.key === ' ') { + e.preventDefault() + setIsOpen(!isOpen) + } + }} + role="button" + tabIndex={0} + className="smtcmp-similarity-search-results__trigger" + >Also applies to: 49-56
9-15: Typo: Similiarty → Similarity.Rename the component for clarity and consistency.
-function SimiliartySearchItem({ +function SimilaritySearchItem({ chunk, }: { @@ - {similaritySearchResults.map((chunk) => ( - <SimiliartySearchItem key={chunk.id} chunk={chunk} /> - ))} + {similaritySearchResults.map((chunk) => ( + <SimilaritySearchItem key={chunk.id} chunk={chunk} /> + ))}Also applies to: 65-67
src/components/modals/RAGSearchModal.tsx (4)
46-48: Progress state is cleared immediately; “querying-done” message never displays.Dropping to idle in finally suppresses the completion message. Keep the last reported state or clear it after a short delay.
} finally { setIsSearching(false) - setQueryProgress({ type: 'idle' }) + // Optional: clear after a brief delay if you want it to disappear automatically + // setTimeout(() => setQueryProgress({ type: 'idle' }), 1000) }
28-31: Prevent duplicate submissions while a search is in progress.Guard both handlers with isSearching.
const handleSearch = async () => { - if (!searchQuery.trim()) return + if (isSearching || !searchQuery.trim()) returnconst handleKeyDown = (e: React.KeyboardEvent) => { - if (e.key === 'Enter' && !e.shiftKey) { + if (isSearching) return + if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault() handleSearch() } }Also applies to: 51-56
103-107: Announce progress to screen readers.Add aria-live for the progress region.
- {queryProgress.type !== 'idle' && ( - <div className="smtcmp-rag-search-modal__progress"> + {queryProgress.type !== 'idle' && ( + <div + className="smtcmp-rag-search-modal__progress" + aria-live="polite" + aria-atomic="true" + > {getProgressMessage()} </div> )}
42-45: Surface a user-facing error notice (and import Notice).Log + TODO is easy to miss; show a Notice so users know something failed.
-import { App } from 'obsidian' +import { App, Notice } from 'obsidian'} catch (error) { console.error('RAG search failed:', error) - // TODO: Show error message to user + new Notice('RAG search failed. See console for details.', 4000)Also applies to: 2-3
src/components/chat-view/Chat.tsx (2)
599-607: Open RAG modal: works; consider small ergonomics tweak.Inline onClick is fine; optionally factor into a memoized callback for readability and reuse with the command handler.
Apply within this hunk:
- <button - onClick={() => { - new RAGSearchModal(app, getRAGEngine).open() - }} + <button + onClick={openRAGSearch} className="clickable-icon" aria-label="RAG Search" > <Search size={18} /> </button>Add once near other callbacks:
const openRAGSearch = useCallback( () => new RAGSearchModal(app, getRAGEngine).open(), [app, getRAGEngine], )
61-61: Remove stray “Add an empty line here” comment.This looks like a leftover note.
-// Add an empty line here +
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (5)
src/components/chat-view/Chat.tsx(3 hunks)src/components/chat-view/SimilaritySearchResults.tsx(1 hunks)src/components/modals/RAGSearchModal.tsx(1 hunks)src/main.ts(2 hunks)styles.css(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- styles.css
🧰 Additional context used
🧬 Code graph analysis (3)
src/main.ts (1)
src/components/modals/RAGSearchModal.tsx (1)
RAGSearchModal(129-145)
src/components/chat-view/SimilaritySearchResults.tsx (1)
src/database/schema.ts (1)
SelectEmbedding(76-76)
src/components/modals/RAGSearchModal.tsx (6)
src/core/rag/ragEngine.ts (1)
RAGEngine(12-123)src/components/chat-view/QueryProgress.tsx (1)
QueryProgressState(4-23)src/main.ts (1)
getRAGEngine(276-299)src/contexts/app-context.tsx (1)
AppProvider(7-15)src/components/chat-view/SimilaritySearchResults.tsx (1)
SimilaritySearchResults(36-72)src/components/common/ReactModal.tsx (1)
ReactModal(12-40)
🔇 Additional comments (5)
src/components/modals/RAGSearchModal.tsx (1)
129-145: LGTM: Modal wrapper and sizing are clean and idiomatic.Constructor wiring through ReactModal with explicit dimensions looks good.
src/main.ts (2)
7-7: LGTM: Import added for RAGSearchModal.
129-136: LGTM: Command to open RAG search.Straightforward UX win; lazy getRAGEngine keeps startup fast.
src/components/chat-view/Chat.tsx (2)
2-2: Icon import looks good.The
Searchicon import is correct and used below.
49-49: Resolved: RAGSearchModal export and constructor signature confirmed.RAGSearchModal is a named export (
export class RAGSearchModal …) and its constructor signature(app: App, getRAGEngine: () => Promise<RAGEngine>)matches the usage in Chat.tsx.
Description
gemini type providers do not support custom
baseUrlconfigurations.#472
feat: search note by rag

Checklist before requesting a review
npm run lint:checkandnpm run type:check)npm run test)Summary by CodeRabbit
New Features
Style