Conversation
This comment has been minimized.
This comment has been minimized.
|
Caution Review failedThe pull request is closed. ℹ️ Recent review infoConfiguration used: Organization UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
WalkthroughAdds an AI Search Assist feature: docs and changelog, a server action to translate natural-language prompts to Sourcebot queries, a new SearchAssistBox UI and SearchBar integration, query-language export for syntax description, analytics events, and plumbing for feature availability across pages and layout. Changes
Sequence DiagramsequenceDiagram
participant User
participant SearchAssistBox as SearchAssistBox (Client)
participant Server as translateSearchQuery (Server)
participant LM as LanguageModel (AI SDK)
participant SearchBar as SearchBar (Client)
User->>SearchAssistBox: Open panel / enter prompt
SearchAssistBox->>SearchAssistBox: Capture prompt
User->>SearchAssistBox: Press Enter / Click Generate
SearchAssistBox->>Server: POST translateSearchQuery({ prompt })
activate Server
Server->>Server: getConfiguredLanguageModelsInfo()
Server->>LM: generateObject(systemPrompt + SEARCH_SYNTAX_DESCRIPTION, schema)
activate LM
LM-->>Server: { query }
deactivate LM
Server-->>SearchAssistBox: { query }
deactivate Server
SearchAssistBox->>SearchBar: onQueryGenerated(query)
SearchBar->>SearchBar: Insert query, focus editor, set flags
SearchBar->>User: Display generated query in search input
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested labels
Suggested reviewers
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
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. Comment |
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
🧹 Nitpick comments (7)
docs/docs/features/search/ai-search-assist.mdx (1)
7-14: Consider wrapping the video in a<Frame>component for consistent styling.The coding guidelines specify that images should be wrapped in
<Frame>. While this video is technically not an image, wrapping it in<Frame>may provide consistent visual presentation with other media in the docs.💡 Optional: Wrap video in Frame
-<video - autoPlay - muted - loop - playsInline - className="w-full aspect-video" - src="/images/search-assist.mp4" -></video> +<Frame> + <video + autoPlay + muted + loop + playsInline + className="w-full aspect-video" + src="/images/search-assist.mp4" + ></video> +</Frame>🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/docs/features/search/ai-search-assist.mdx` around lines 7 - 14, Wrap the video JSX in the shared Frame component to ensure consistent styling with other media (replace the bare <video ...> element with a <Frame> that contains the <video>), updating the file's JSX where the video element appears; ensure the Frame import (Frame) is present at the top of the module if not already and preserve all existing video props (autoPlay, muted, loop, playsInline, className, src).packages/web/src/lib/posthogEvents.ts (1)
238-244: Consider adding error details to the failure event.The
wa_search_assist_generate_failedevent has an empty payload. Adding anerrorCodefield (consistent with other_failevents in this file) would help with debugging and analytics.💡 Suggested improvement
wa_search_assist_opened: {}, wa_search_assist_query_generated: {}, - wa_search_assist_generate_failed: {}, + wa_search_assist_generate_failed: { + errorCode: string, + }, wa_search_assist_example_clicked: { example: string, },🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/web/src/lib/posthogEvents.ts` around lines 238 - 244, Add an errorCode field to the wa_search_assist_generate_failed event payload so failures report useful error metadata; update the event definition named wa_search_assist_generate_failed to include errorCode: string (matching other *_fail events), and ensure any places emitting this event supply the errorCode when dispatching so analytics/debugging can surface the failure reason.packages/web/src/features/searchAssist/actions.ts (3)
27-28: Consider validating prompt length to prevent abuse.There's no validation on the input
promptlength. Extremely long prompts could:
- Increase API costs
- Hit model token limits
- Be used for abuse
💡 Optional: Add prompt length validation
export const translateSearchQuery = async ({ prompt }: { prompt: string }) => sew(() => withOptionalAuthV2(async () => { + const MAX_PROMPT_LENGTH = 1000; + if (!prompt || prompt.trim().length === 0) { + return { + statusCode: StatusCodes.BAD_REQUEST, + errorCode: ErrorCode.INVALID_REQUEST_BODY, + message: 'Prompt cannot be empty.', + } satisfies ServiceError; + } + if (prompt.length > MAX_PROMPT_LENGTH) { + return { + statusCode: StatusCodes.BAD_REQUEST, + errorCode: ErrorCode.INVALID_REQUEST_BODY, + message: `Prompt exceeds maximum length of ${MAX_PROMPT_LENGTH} characters.`, + } satisfies ServiceError; + } + const models = await _getConfiguredLanguageModelsFull();🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/web/src/features/searchAssist/actions.ts` around lines 27 - 28, translateSearchQuery currently accepts an unbounded prompt which can cause excessive cost, token-limit errors, or abuse; add input validation at the start of translateSearchQuery (before calling sew/withOptionalAuthV2 logic) to enforce a sensible max length (e.g., MAX_PROMPT_LENGTH constant) and reject or truncate prompts that exceed it, returning a clear error (or throwing an Error) for the caller; reference the translateSearchQuery function and enforce the check on the prompt parameter so oversized inputs are handled before invoking downstream model/API calls.
41-48: Consider adding error handling for the AI SDK call.The
generateObjectcall can throw exceptions (network errors, rate limits, invalid responses, etc.). Without try-catch, these will propagate as unhandled errors with potentially unclear error messages to users.💡 Suggested error handling
+ try { const { object } = await generateObject({ model, system: SYSTEM_PROMPT, prompt, schema: z.object({ query: z.string().describe("The Sourcebot search query."), }), }); return { query: object.query }; + } catch (error) { + console.error('Failed to generate search query:', error); + return { + statusCode: StatusCodes.INTERNAL_SERVER_ERROR, + errorCode: ErrorCode.INTERNAL_SERVER_ERROR, + message: 'Failed to generate search query.', + } satisfies ServiceError; + }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/web/src/features/searchAssist/actions.ts` around lines 41 - 48, Wrap the generateObject call in a try-catch inside the action where it is invoked (the generateObject invocation that destructures { object } with model, SYSTEM_PROMPT, prompt, and z.object schema). In the catch block log the full error (including error.message/stack) using the existing logger or console, return or throw a clear, user-friendly error response (or a fallback value) so the caller can handle it, and ensure you handle the case where object is undefined after failure before continuing processing.
31-37: Consider using a more appropriate HTTP status code.
BAD_REQUEST(400) implies the client sent an invalid request, but "no language models configured" is a server-side configuration issue.SERVICE_UNAVAILABLE(503) would more accurately indicate the feature is not available due to missing configuration.💡 Suggested fix
if (models.length === 0) { return { - statusCode: StatusCodes.BAD_REQUEST, - errorCode: ErrorCode.INVALID_REQUEST_BODY, + statusCode: StatusCodes.SERVICE_UNAVAILABLE, + errorCode: ErrorCode.INVALID_REQUEST_BODY, message: 'No language models are configured.', } satisfies ServiceError; }Also consider adding a more specific error code like
NO_LANGUAGE_MODEL_CONFIGUREDif the error code enum supports it.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/web/src/features/searchAssist/actions.ts` around lines 31 - 37, Replace the client-side 400 response when no language models are found with a server-side availability error: in the block checking models.length === 0, change StatusCodes.BAD_REQUEST to StatusCodes.SERVICE_UNAVAILABLE and swap ErrorCode.INVALID_REQUEST_BODY for a more specific code (e.g., ErrorCode.NO_LANGUAGE_MODEL_CONFIGURED or add that enum value if missing) while keeping the ServiceError shape returned by the function (refer to the models.length === 0 check, StatusCodes.BAD_REQUEST, and ErrorCode.INVALID_REQUEST_BODY).packages/queryLanguage/src/syntaxDescription.ts (1)
91-92: Minor: log4j example references package.json but log4j is a Java dependency.The example shows searching for log4j versions in
package.json, but log4j is a Java logging library typically found inpom.xmlorbuild.gradle. Consider updating to a JavaScript/Node.js package example for consistency, or changing to the appropriate file filter.💡 Suggested fix
-Input: find log4j versions 2.3.x or lower -Output: file:package\.json "\"log4j\": \"\^?2\.([0-2]|3)\." +Input: find lodash versions 4.16.x or lower +Output: file:package\.json "\"lodash\": \"\^?4\.(1[0-6]|[0-9])\."Or keep log4j but use Java build files:
-Output: file:package\.json "\"log4j\": \"\^?2\.([0-2]|3)\." +Output: file:pom\.xml "<version>2\.([0-2]|3)\."🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/queryLanguage/src/syntaxDescription.ts` around lines 91 - 92, Update the example "Input: find log4j versions 2.3.x or lower" / "Output: file:package\.json ..." in syntaxDescription.ts to avoid suggesting log4j is found in package.json; either replace the package.json file filter with a Java build file filter (e.g., pom.xml or build.gradle) when keeping log4j, or swap the dependency example to a JS/Node package (e.g., "lodash" or "express") so the file:package\.json regex is correct; locate and edit the example string(s) in syntaxDescription.ts (the Input/Output example lines) to reflect the chosen fix.packages/web/src/app/[domain]/components/searchBar/searchAssistBox.tsx (1)
9-10: Consolidate imports from the same module.The two imports from
@/lib/utilscan be merged into a single import statement for cleaner code organization.♻️ Suggested fix
-import { isServiceError } from "@/lib/utils"; -import { cn } from "@/lib/utils"; +import { cn, isServiceError } from "@/lib/utils";🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/web/src/app/`[domain]/components/searchBar/searchAssistBox.tsx around lines 9 - 10, Combine the two separate imports from "@/lib/utils" into a single import statement that imports both isServiceError and cn together; update the import declarations so only one import from "@/lib/utils" exists and references both symbols (isServiceError, cn) to remove the duplicate import.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@docs/docs/features/search/ai-search-assist.mdx`:
- Around line 7-14: Wrap the video JSX in the shared Frame component to ensure
consistent styling with other media (replace the bare <video ...> element with a
<Frame> that contains the <video>), updating the file's JSX where the video
element appears; ensure the Frame import (Frame) is present at the top of the
module if not already and preserve all existing video props (autoPlay, muted,
loop, playsInline, className, src).
In `@packages/queryLanguage/src/syntaxDescription.ts`:
- Around line 91-92: Update the example "Input: find log4j versions 2.3.x or
lower" / "Output: file:package\.json ..." in syntaxDescription.ts to avoid
suggesting log4j is found in package.json; either replace the package.json file
filter with a Java build file filter (e.g., pom.xml or build.gradle) when
keeping log4j, or swap the dependency example to a JS/Node package (e.g.,
"lodash" or "express") so the file:package\.json regex is correct; locate and
edit the example string(s) in syntaxDescription.ts (the Input/Output example
lines) to reflect the chosen fix.
In `@packages/web/src/app/`[domain]/components/searchBar/searchAssistBox.tsx:
- Around line 9-10: Combine the two separate imports from "@/lib/utils" into a
single import statement that imports both isServiceError and cn together; update
the import declarations so only one import from "@/lib/utils" exists and
references both symbols (isServiceError, cn) to remove the duplicate import.
In `@packages/web/src/features/searchAssist/actions.ts`:
- Around line 27-28: translateSearchQuery currently accepts an unbounded prompt
which can cause excessive cost, token-limit errors, or abuse; add input
validation at the start of translateSearchQuery (before calling
sew/withOptionalAuthV2 logic) to enforce a sensible max length (e.g.,
MAX_PROMPT_LENGTH constant) and reject or truncate prompts that exceed it,
returning a clear error (or throwing an Error) for the caller; reference the
translateSearchQuery function and enforce the check on the prompt parameter so
oversized inputs are handled before invoking downstream model/API calls.
- Around line 41-48: Wrap the generateObject call in a try-catch inside the
action where it is invoked (the generateObject invocation that destructures {
object } with model, SYSTEM_PROMPT, prompt, and z.object schema). In the catch
block log the full error (including error.message/stack) using the existing
logger or console, return or throw a clear, user-friendly error response (or a
fallback value) so the caller can handle it, and ensure you handle the case
where object is undefined after failure before continuing processing.
- Around line 31-37: Replace the client-side 400 response when no language
models are found with a server-side availability error: in the block checking
models.length === 0, change StatusCodes.BAD_REQUEST to
StatusCodes.SERVICE_UNAVAILABLE and swap ErrorCode.INVALID_REQUEST_BODY for a
more specific code (e.g., ErrorCode.NO_LANGUAGE_MODEL_CONFIGURED or add that
enum value if missing) while keeping the ServiceError shape returned by the
function (refer to the models.length === 0 check, StatusCodes.BAD_REQUEST, and
ErrorCode.INVALID_REQUEST_BODY).
In `@packages/web/src/lib/posthogEvents.ts`:
- Around line 238-244: Add an errorCode field to the
wa_search_assist_generate_failed event payload so failures report useful error
metadata; update the event definition named wa_search_assist_generate_failed to
include errorCode: string (matching other *_fail events), and ensure any places
emitting this event supply the errorCode when dispatching so analytics/debugging
can surface the failure reason.
ℹ️ Review info
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
docs/images/search-assist.mp4is excluded by!**/*.mp4
📒 Files selected for processing (16)
CHANGELOG.mddocs/docs.jsondocs/docs/features/search/ai-search-assist.mdxpackages/queryLanguage/src/index.tspackages/queryLanguage/src/syntaxDescription.tspackages/web/src/app/[domain]/browse/layout.tsxpackages/web/src/app/[domain]/browse/layoutClient.tsxpackages/web/src/app/[domain]/components/searchBar/searchAssistBox.tsxpackages/web/src/app/[domain]/components/searchBar/searchBar.tsxpackages/web/src/app/[domain]/components/searchBar/searchSuggestionsBox.tsxpackages/web/src/app/[domain]/search/components/searchLandingPage.tsxpackages/web/src/app/[domain]/search/components/searchResultsPage.tsxpackages/web/src/app/[domain]/search/page.tsxpackages/web/src/features/searchAssist/actions.tspackages/web/src/lib/newsData.tspackages/web/src/lib/posthogEvents.ts
search-assist.mp4
Summary
translateSearchQueryserver action backed by a configured language model using structured output (generateObject) to ensure clean query resultsSEARCH_SYNTAX_DESCRIPTIONto the query language package used as the LLM system promptisSearchAssistSupportedthrough the component tree — the wand button is disabled with a tooltip when no language model is configuredwa_search_assist_opened,wa_search_assist_query_generated,wa_search_assist_generate_failed,wa_search_assist_example_clicked)docs/features/search/ai-search-assist.mdxwith demo videoTest plan
🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Documentation
Chores