Integrate Resolution Search and UI Improvements#478
Integrate Resolution Search and UI Improvements#478ngoiyaeric wants to merge 46 commits intomainfrom
Conversation
Restored the branch to the expected head at commit 488b47c. This recovers several missing features and architectural improvements: - Integrated HistoryToggleProvider and HistorySidebar. - Integrated UsageToggleProvider and the new UsageView component. - Removed legacy usage-sidebar.tsx. - Restored pricing and feature updates in PurchaseCreditsPopup. - Fixed layout structure in app/layout.tsx to support these new global state providers. Resolved previous merge conflicts and incorrect force-push state. Co-authored-by: ngoiyaeric <115367894+ngoiyaeric@users.noreply.github.com>
…c380 Restore Branch Head to Commit 488b47c
- Reset branch HEAD to historical recovery point 488b47c. - Applied latest code fixes from orphan commit 166aee9, including Mapbox rendering optimizations and GeoJSON streaming. - Improved type safety in app/actions.tsx by removing 'as any' casts and properly typing message arrays. - Refined getModel utility to support vision-aware model fallback. - Documented non-blocking background task pattern in server actions. - Updated feature/billing-integration branch with the restored state. Co-authored-by: ngoiyaeric <115367894+ngoiyaeric@users.noreply.github.com>
- Reset branch HEAD to historical recovery point 488b47c. - Applied latest code fixes from orphan commit 166aee9. - Resolved TypeScript build error in app/actions.tsx by casting GeoJSON data to FeatureCollection. - Improved type safety for AIState message filtering and content handling. - Implemented background processing for resolution search with immediate UI streaming. - Optimized chat history fetching to trigger only when the sidebar is open. - Ensured Mapbox style loading is robust against re-renders. - Cleaned up dead code and improved documentation in server actions. Co-authored-by: ngoiyaeric <115367894+ngoiyaeric@users.noreply.github.com>
- Reset branch HEAD to historical recovery point 488b47c. - Applied latest code fixes from orphan commit 166aee9. - Resolved TypeScript build error in app/actions.tsx by casting GeoJSON data to FeatureCollection. - Improved type safety for AIState message filtering and content handling. - Implemented background processing for resolution search with immediate UI streaming. - Re-enabled auto-opening of the pricing popup in components/header.tsx. - Optimized chat history fetching to trigger only when the sidebar is open. - Ensured Mapbox style loading is robust against re-renders. - Cleaned up dead code and improved documentation in server actions. Co-authored-by: ngoiyaeric <115367894+ngoiyaeric@users.noreply.github.com>
- Restored historical state from 488b47c and merged latest changes. - Implemented streaming for resolution search in lib/agents/resolution-search.tsx and app/actions.tsx to improve response time. - Re-enabled auto-opening pricing popup in components/header.tsx. - Resolved all TypeScript build errors in app/actions.tsx. - Restored Grok model support for vision tasks in lib/utils/index.ts. - Optimized chat history loading in components/sidebar/chat-history-client.tsx. - Improved Mapbox style loading robustness in components/map/mapbox-map.tsx. Co-authored-by: ngoiyaeric <115367894+ngoiyaeric@users.noreply.github.com>
- Synchronized branch with origin/main, prioritizing main's code structure and latest features. - Bridged the history with historical recovery point 488b47c. - Implemented streaming for resolution search in lib/agents/resolution-search.tsx and app/actions.tsx to resolve performance issues. - Restored the auto-opening Pricing Popup and Usage View in the Header component. - Integrated the Timezone Clock and time context into the restored resolution search logic. - Resolved TypeScript build errors with proper type casting and fixed a missing 'use client' directive in components/history.tsx. - Ensured all required providers (History, Usage, etc.) are correctly wrapped in the root layout. Co-authored-by: ngoiyaeric <115367894+ngoiyaeric@users.noreply.github.com>
- Synchronized branch with origin/main, prioritizing main's code structure and latest features. - Bridged the history with historical recovery point 488b47c. - Integrated UsageView and billing UI into the Chat component, toggled by the tent tree icon. - Implemented streaming for resolution search in lib/agents/resolution-search.tsx and app/actions.tsx for better performance. - Restored the auto-opening Pricing Popup in the Header component. - Improved type safety across server actions and Mapbox components. - Ensured mutual exclusion between Settings, Usage, and Map views. - Fixed a missing 'use client' directive in components/history.tsx. Co-authored-by: ngoiyaeric <115367894+ngoiyaeric@users.noreply.github.com>
- Integrated UsageView into the main Chat component for both mobile and desktop. - Ensured mutual exclusion between Settings, Usage, and Map views in the UI panel. - Updated ConditionalLottie to hide the loading animation when the Usage View is open. - Synchronized with origin/main while prioritizing its code structure. - Maintained historical recovery and performance optimizations for resolution search. Co-authored-by: ngoiyaeric <115367894+ngoiyaeric@users.noreply.github.com>
- Synchronized with origin/main, prioritizing main branch code and features. - Fully restored historical context and missing changes from commit 488b47c. - Integrated Usage and Billing UI (UsageView) into the Chat component. - Implemented streaming for resolution search analysis to improve perceived performance. - Re-enabled auto-opening pricing popup in components/header.tsx. - Refined ConditionalLottie visibility to avoid overlaps with the Usage UI. - Ensured mutual exclusion between Settings, Usage, and Map views in the side panel. - Improved type safety across server actions and Mapbox components. - Resolved build failures related to missing client directives and type mismatches. Co-authored-by: ngoiyaeric <115367894+ngoiyaeric@users.noreply.github.com>
…ability - Recovered historical state from commit 488b47c and synchronized with main. - Optimized resolution search by refactoring to stream partial summaries. - Fixed Mapbox memory leaks by ensuring all event listeners are removed on cleanup. - Improved StreamableValue stability by initializing with default values. - Integrated Usage View with mutual exclusion logic and Lottie player visibility fixes. - Refined model selection for Grok vision and Gemini 1.5 Pro. - Integrated timezone-aware analysis using tz-lookup. Co-authored-by: ngoiyaeric <115367894+ngoiyaeric@users.noreply.github.com>
- Fixed Type error in `app/actions.tsx` by casting `content` to `string` in `createStreamableValue`. - Addressed ESLint warnings in `components/map/mapbox-map.tsx` and `components/chat-panel.tsx` by adding missing dependencies to `useEffect` and `useCallback` hooks. - Ensured `relatedQueries` streamable value is initialized with an empty state for stability. Co-authored-by: ngoiyaeric <115367894+ngoiyaeric@users.noreply.github.com>
Update LICENSE
- Reduced vertical padding in `.mobile-chat-input-area` in `globals.css`. - Removed redundant `.mobile-chat-input` class and associated styles from `globals.css`. - Adjusted `ChatPanel` to use more compact padding and a smaller minimum height on mobile. - Removed excessive left padding (`pl-14`) on the mobile chat input since the attachment button is moved to the icons bar. - Cleaned up unused mobile-specific CSS classes in `globals.css`. Co-authored-by: ngoiyaeric <115367894+ngoiyaeric@users.noreply.github.com>
…8048805505961867280 Reduce padding in mobile chat input area
Replaced all occurrences of the old Stripe checkout link with the new URL: https://buy.stripe.com/14A3cv7K72TR3go14Nasg02 Updated files: - components/mobile-icons-bar.tsx - components/header.tsx Co-authored-by: ngoiyaeric <115367894+ngoiyaeric@users.noreply.github.com>
…683339330 Update Stripe checkout links
- Updated `EmptyScreen` example buttons to use `whitespace-normal`, `text-left`, and `items-start` for better multi-line support. - Added `break-words` to `BotMessage` container to prevent horizontal overflow from long strings. - Improved `SuggestionsDropdown` and `SearchRelated` buttons with wrapping and top-alignment. - Replaced filename truncation with `break-all` wrapping in `ChatPanel` file attachments. - Ensured consistent icon alignment for multi-line buttons. Co-authored-by: ngoiyaeric <115367894+ngoiyaeric@users.noreply.github.com>
…911856121500176 Ensure text wrapping for long sentences across UI components
- Optimized resolution search with streaming. - Improved timezone handling and AI context. - Fixed UI mutual exclusion and loading state logic. - Stabilized Mapbox cleanup and event listeners. - Resolved build errors and ESLint warnings. Co-authored-by: ngoiyaeric <115367894+ngoiyaeric@users.noreply.github.com>
…head features - Reverted branch to commit 6acfbe5. - Merged changes from main (e95a25b). - Preserved Tentree Icon (UsageView logic), History layout (HistoryContainer), and PurchaseCreditsPopup from 6acfbe5 as requested. - Updated Stripe checkout URL in PurchaseCreditsPopup to the official one (14A3cv7K72TR3go14Nasg02). - Re-applied bug fixes from 6acfbe5 (type casting in app/actions.tsx, ESLint dependencies in components/map/mapbox-map.tsx and components/chat-panel.tsx, and relatedQueries initialization). - Verified build and synchronization with main branch features (e.g., resolution search enhancements). Co-authored-by: ngoiyaeric <115367894+ngoiyaeric@users.noreply.github.com>
…8' into jules-8488824498232079115-26d4e4cd
…ranch head features - Reverted branch to commit 6acfbe5 and merged with main (e95a25b). - Preserved Tentree Icon (Usage View), history layout, and PurchaseCreditsPopup from 6acfbe5. - Restored branch-specific UI components: Header, History button, Profile toggle, and Usage integration in Chat. - Synchronized all other logic with main, including resolution search enhancements. - Fixed an infinite re-render loop in Mapbox map by optimizing useEffect dependencies (removed cameraState from initialization effect). - Re-applied critical bug fixes from 6acfbe5: - Type casting in app/actions.tsx (getUIStateFromAIState). - Streamable value initialization for stability. - setSuggestions dependency in ChatPanel. - Updated Stripe checkout URL in PurchaseCreditsPopup to the official link. - Verified successful build with 'bun run build'. Co-authored-by: ngoiyaeric <115367894+ngoiyaeric@users.noreply.github.com>
…p, and history toggle
Jules 8488824498232079115 26d4e4cd
- Updated 'Daily refresh credits' to 'Yearly refresh credits' - Updated refresh credit value from 300 to 500 - Updated subtext to 'Refresh to 500 every year.' - Replaced task list with 'QCX-TERRA Crop yield Analysis', 'QCX-TERRA Flood predictions', and 'Green OS climate synchronization' - Set task dates to 'upcoming' and credit changes to single digits (-7, -5, -3) Co-authored-by: ngoiyaeric <115367894+ngoiyaeric@users.noreply.github.com>
…resh-14763946411330416327 Update Usage View to Yearly Refresh
|
@coderabbitai the resolution search is not responsive |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: Length of output: 4583 🏁 Script executed: Length of output: 27 🏁 Script executed: Length of output: 880 🏁 Script executed: Length of output: 0 🏁 Script executed: Length of output: 1059 🏁 Script executed: Length of output: 78 🏁 Script executed: Length of output: 3294 🏁 Script executed: Length of output: 14 🏁 Script executed: Length of output: 2457 🏁 Script executed: Length of output: 35 🏁 Script executed: Length of output: 31
Root CauseIn
This means the resolution search button cannot render on mobile devices, making the feature completely unavailable on smaller screens. Recommended FixYou have two options: Option 1: Add to Header Mobile SectionAdd the portal div to the mobile menu in {/* Mobile menu buttons */}
<div className="flex md:hidden gap-2">
<div id="mobile-header-search-portal" />
<Button variant="ghost" size="icon" onClick={handleUsageToggle}>
<TentTree className="h-[1.2rem] w-[1.2rem]" />
</Button>
<ProfileToggle/>
</div>Option 2: Replace Static Button in Mobile Icons BarIn <div id="mobile-header-search-portal" />This would be better since the existing Search button is non-functional anyway. Would you like me to create a plan to implement one of these fixes? |
I have fixed the responsiveness of the resolution search. The mobile search button was missing its portal target, and the 'disabled' logic was incorrectly requiring a Mapbox instance even when Google Maps was active. I've also aligned the mobile button style with other icons and switched to 'sonner' for toast notifications. |
…responsiveness This commit integrates key features and fixes from recent PRs: - Improved Resolution Search: included `drawnFeatures` in requests and fixed AI streaming stability. - Fixed Resolution Search Responsiveness: added missing portal target for mobile and corrected 'disabled' logic. - Optimized mobile UI: reduced vertical padding and improved chat panel layout. - Enhanced layout robustness: text wrapping fixes across multiple components. - Updated Stripe checkout links to the latest URL. - Updated LICENSE copyright. - Switched to 'sonner' for toast notifications in HeaderSearchButton. Co-authored-by: ngoiyaeric <115367894+ngoiyaeric@users.noreply.github.com>
This commit addresses the "no response" issue in resolution search by: - Updating `getModel` to correctly return vision-capable models when needed. - Improving `streamObject` partial update handling in `app/actions.tsx`. - Adding a spinner and improving UI streaming for resolution search. - Increasing static map quality with `scale=2`. It also fixes mobile responsiveness: - Added missing portal target for the mobile search button. - Corrected button disabled logic to support Google Maps. - Aligned mobile icon button styles. - Optimized mobile padding and fixed text wrapping across the UI. - Updated Stripe checkout links and LICENSE metadata. Co-authored-by: ngoiyaeric <115367894+ngoiyaeric@users.noreply.github.com>
This commit integrates several key features and fixes from the requested PRs: - Resolution Search: Added drawnFeatures support, fixed streaming logic, and improved vision model selection. - Mobile UI: Optimized chat input padding, fixed filename wrapping, and added mobile search portal. - Text Wrapping: Applied whitespace-normal and break-words to various components for better responsiveness. - Metadata: Updated LICENSE and Stripe checkout links. - Consistency: Maintained existing usage and history components as requested. Co-authored-by: ngoiyaeric <115367894+ngoiyaeric@users.noreply.github.com>
This commit refactors the desktop header icon container in `components/header.tsx` to ensure all icons are equidistant. Key changes: - Changed the icon container from `justify-between w-1/2` to `justify-center flex-1` with a fixed `gap-10`. - Removed the unused `<div id="timezone-clock-portal" />` which was causing irregular spacing between the TentTree and ModeToggle icons. - Applied `className="contents"` to the `<div id="header-search-portal" />` so that it doesn't affect the flex layout when empty. - These changes ensure that icons are always perfectly centered and equidistant regardless of the number of active icons. Co-authored-by: ngoiyaeric <115367894+ngoiyaeric@users.noreply.github.com>
There was a problem hiding this comment.
Actionable comments posted: 5
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
components/mobile-icons-bar.tsx (1)
7-16: 🧹 Nitpick | 🔵 TrivialUnused
Searchimport.The
Searchicon import is no longer used after replacing the mobile search button with the portal div.♻️ Remove unused import
import { - Search, CircleUserRound, Map, CalendarDays, TentTree, Paperclip, ArrowRight, Plus } from 'lucide-react'
🤖 Fix all issues with AI agents
In `@components/header-search-button.tsx`:
- Line 114: Extract the repeated disable expression into a single computed
boolean (e.g., const isDisabled = isAnalyzing || !actions || (mapProvider ===
'mapbox' && !map) || (mapProvider === 'google' && !mapData.cameraState)) and
replace the duplicated uses in both the desktop button and the mobileButton with
this variable; update any JSX props that currently use the long expression to
use isDisabled to improve maintainability and avoid divergence between
HeaderSearchButton and mobileButton render paths.
- Line 12: Update remaining uses of react-toastify (notably in
components/map/mapbox-map.tsx) to import and call sonner's toast API: replace
any imports from 'react-toastify' and calls to toast.success/toast.error etc.
with "import { toast } from 'sonner'" and use toast.success/toast.error (or
toast) accordingly; remove any <ToastContainer /> usage since <Toaster /> is
mounted in app/layout.tsx. Search the repo for other 'react-toastify'
imports/usages and convert them to sonner likewise, then remove the
'react-toastify' entry from package.json and run install to update dependencies.
In `@lib/utils/index.ts`:
- Around line 44-47: The local const named `openai` is shadowing the imported
`openai` from `@ai-sdk/openai`; rename the local variable returned by
createOpenAI (e.g., to `openaiClient` or `openaiInstance`) and return that
instead (update the return statement from `openai(specificModel)` to use the new
name) so that the imported symbol and the created client are distinct; update
any callers in this file that expect the created client variable name
accordingly.
- Around line 30-48: The code currently returns a client for SPECIFIC_API_MODEL
without checking requireVision; update the block that handles specificModel to
validate vision/structured-capability when requireVision is true: inspect the
specificModel string (the existing specificModel variable) against known
vision-capable model identifiers (or a small helper list you add) and if
requireVision is true and the chosen specificModel is not recognized as
vision-capable, emit a clear warning or throw an error; keep the existing client
creation calls (createXai, createGoogleGenerativeAI, createOpenAI) but add this
validation/logging before returning the client so callers requiring vision get
an immediate, descriptive message instead of failing at runtime.
- Line 61: The current getModel selection uses the requireVision flag to choose
between 'grok-vision-beta' and 'grok-4-fast-non-reasoning', which mixes vision
capability with structured-output capability and causes JSON Schema rejections
for consumers of streamObject/generateObject; update the model selection logic
in the getModel function(s) so that any callsite that requires structured output
(e.g., streamObject, generateObject, and callers getModel() used by
task-manager.tsx, query-suggestor.tsx, inquire.tsx, suggest.ts,
resolution-search.tsx) never gets 'grok-4-fast-non-reasoning'—instead route
those cases to 'gpt-4o'; keep vision-only requests able to choose
'grok-vision-beta' but add a separate boolean or enum (e.g.,
requiresStructuredOutput) or inspect the caller flag (hasImage vs
structuredOutput) so selection checks structured-output first and returns
'gpt-4o' when true, otherwise fall back to vision or non-reasoning Grok as
appropriate.
📜 Review details
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (5)
app/actions.tsxcomponents/header-search-button.tsxcomponents/mobile-icons-bar.tsxlib/agents/resolution-search.tsxlib/utils/index.ts
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2026-01-13T13:26:30.086Z
Learnt from: ngoiyaeric
Repo: QueueLab/QCX PR: 0
File: :0-0
Timestamp: 2026-01-13T13:26:30.086Z
Learning: Workers that rely on ai.generateObject (geojsonParser, map-command-generator, feedback-analyzer) must not use the X.AI 'grok-4-fast-non-reasoning' model because X.AI’s chat/completions rejects JSON Schema structured-output arguments; prefer OpenAI gpt-4o for structured outputs.
Applied to files:
lib/utils/index.ts
📚 Learning: 2026-01-17T06:14:51.070Z
Learnt from: ngoiyaeric
Repo: QueueLab/QCX PR: 0
File: :0-0
Timestamp: 2026-01-17T06:14:51.070Z
Learning: For structured output tasks using ai.generateObject (resolution-search, geojsonParser, map-command-generator, feedback-analyzer), prefer OpenAI gpt-4o. While xAI's grok-4-1-fast-reasoning technically supports structured outputs and vision, OpenAI has proven more reliable integration with the AI SDK's generateObject function and Zod schemas in production.
Applied to files:
lib/utils/index.ts
🧬 Code graph analysis (2)
lib/utils/index.ts (1)
lib/actions/users.ts (1)
getSelectedModel(126-139)
components/header-search-button.tsx (4)
components/map/google-map.tsx (2)
GoogleMapComponent(12-86)apiKey(20-29)components/map/mapbox-map.tsx (4)
prevData(166-166)map(66-167)map(320-341)isMapTypeChanged(460-512)components/map/google-geojson-layer.tsx (2)
feature(27-44)map(14-57)components/map/map-query-handler.tsx (1)
toolOutput(33-73)
🪛 Biome (2.3.13)
app/actions.tsx
[error] 672-672: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.
The declaration is defined in this switch clause:
Safe fix: Wrap the declaration in a block.
(lint/correctness/noSwitchDeclarations)
[error] 685-685: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.
The declaration is defined in this switch clause:
Safe fix: Wrap the declaration in a block.
(lint/correctness/noSwitchDeclarations)
🔇 Additional comments (7)
components/mobile-icons-bar.tsx (1)
48-48: Good fix for the missing mobile portal target.This correctly resolves the issue where the mobile resolution search button couldn't render because the portal container was missing from the DOM. The
HeaderSearchButtoncomponent now has a target element to portal the mobile search button into.lib/agents/resolution-search.tsx (1)
62-63: LGTM!The additional instruction reinforces JSON schema compliance, which helps ensure the LLM produces well-structured output matching the
resolutionSearchSchema. This is good defensive prompt engineering for structured output generation.components/header-search-button.tsx (3)
38-46: Good addition of state validation with early returns.The early returns with toast notifications provide clear user feedback when the map providers aren't ready. This prevents confusing errors during the resolution search process.
80-80: Static map quality improvement with scale=2.Using
scale=2doubles the pixel density of the static map image, which is beneficial for image analysis by the vision model. Good enhancement.
97-97: drawnFeatures correctly appended to form data.This enables the resolution search to analyze user-drawn areas/lines on the map. The JSON serialization with fallback to empty array is appropriate.
app/actions.tsx (2)
112-112: Good fallback chain for summary resolution.The fallback
analysisResult.summary || fullSummary || 'Analysis complete.'ensures the stream always completes with meaningful content, even if the structured output is partial.
724-725: Consistent streamable initialization pattern.The pattern of creating empty streamables and calling
done()with the value is now consistent across the codebase. This aligns with the PR objective of improving AI streaming stability.Also applies to: 738-739
✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.
| import { nanoid } from 'nanoid' | ||
| import { UserMessage } from './user-message' | ||
| import { toast } from 'react-toastify' | ||
| import { toast } from 'sonner' |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify Toaster component is mounted in the app
rg -n "Toaster" --type=tsx --type=ts -g '!node_modules'Repository: QueueLab/QCX
Length of output: 83
🏁 Script executed:
# Check for any remaining react-toastify imports
rg -n "react-toastify" --type=tsx --type=ts -g '!node_modules'Repository: QueueLab/QCX
Length of output: 83
🏁 Script executed:
# Verify the migration in the file
rg -n "from 'sonner'" --type=tsx --type=ts -g '!node_modules'Repository: QueueLab/QCX
Length of output: 83
🏁 Script executed:
#!/bin/bash
# Search for Toaster component in TypeScript/React files
rg -n "Toaster" --type-add 'web:*.{ts,tsx,js,jsx}' -t web -g '!node_modules'Repository: QueueLab/QCX
Length of output: 970
🏁 Script executed:
# Search for react-toastify to ensure it was fully removed
rg "react-toastify" -g '!node_modules'Repository: QueueLab/QCX
Length of output: 558
🏁 Script executed:
# Search for sonner imports
rg "from ['\"]sonner['\"]" -g '!node_modules'Repository: QueueLab/QCX
Length of output: 382
🏁 Script executed:
# List the app entry/layout files to check for Toaster
fd -e tsx -e ts . -path '*/app*' -o -path '*/layout*' -o -path '*/main*' -o -path '*/index*' | head -20Repository: QueueLab/QCX
Length of output: 224
Complete the sonner migration across the codebase.
The migration from react-toastify to sonner in this file is correct. The <Toaster /> component is properly mounted in app/layout.tsx. However, components/map/mapbox-map.tsx still imports and uses react-toastify. Complete the migration by updating this file and any other remaining references to use sonner instead, then remove the react-toastify dependency from package.json.
🤖 Prompt for AI Agents
In `@components/header-search-button.tsx` at line 12, Update remaining uses of
react-toastify (notably in components/map/mapbox-map.tsx) to import and call
sonner's toast API: replace any imports from 'react-toastify' and calls to
toast.success/toast.error etc. with "import { toast } from 'sonner'" and use
toast.success/toast.error (or toast) accordingly; remove any <ToastContainer />
usage since <Toaster /> is mounted in app/layout.tsx. Search the repo for other
'react-toastify' imports/usages and convert them to sonner likewise, then remove
the 'react-toastify' entry from package.json and run install to update
dependencies.
| size="icon" | ||
| onClick={handleResolutionSearch} | ||
| disabled={isAnalyzing || !map || !actions} | ||
| disabled={isAnalyzing || !actions || (mapProvider === 'mapbox' && !map) || (mapProvider === 'google' && !mapData.cameraState)} |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Disable logic consistency is good but verbose.
The disable condition is duplicated between desktop and mobile buttons. Consider extracting to a computed variable for maintainability.
♻️ Extract shared disable condition
+ const isDisabled = isAnalyzing || !actions || (mapProvider === 'mapbox' && !map) || (mapProvider === 'google' && !mapData.cameraState)
+
const desktopButton = (
<Button
variant="ghost"
size="icon"
onClick={handleResolutionSearch}
- disabled={isAnalyzing || !actions || (mapProvider === 'mapbox' && !map) || (mapProvider === 'google' && !mapData.cameraState)}
+ disabled={isDisabled}
title="Analyze current map view"
>And similarly for mobileButton.
Also applies to: 126-126
🤖 Prompt for AI Agents
In `@components/header-search-button.tsx` at line 114, Extract the repeated
disable expression into a single computed boolean (e.g., const isDisabled =
isAnalyzing || !actions || (mapProvider === 'mapbox' && !map) || (mapProvider
=== 'google' && !mapData.cameraState)) and replace the duplicated uses in both
the desktop button and the mobileButton with this variable; update any JSX props
that currently use the long expression to use isDisabled to improve
maintainability and avoid divergence between HeaderSearchButton and mobileButton
render paths.
| if (specificModel) { | ||
| if (specificModel.includes('grok')) { | ||
| const xai = createXai({ | ||
| apiKey: xaiApiKey, | ||
| baseURL: 'https://api.x.ai/v1', | ||
| }); | ||
| return xai(specificModel); | ||
| } | ||
| if (specificModel.includes('gemini')) { | ||
| const google = createGoogleGenerativeAI({ | ||
| apiKey: gemini3ProApiKey, | ||
| }); | ||
| return google(specificModel); | ||
| } | ||
| const openai = createOpenAI({ | ||
| apiKey: openaiApiKey, | ||
| }); | ||
| return openai(specificModel); | ||
| } |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
SPECIFIC_API_MODEL path doesn't validate vision capability.
When SPECIFIC_API_MODEL is set, the model is used directly regardless of the requireVision parameter. If someone sets SPECIFIC_API_MODEL=grok-4-fast-non-reasoning but calls a function requiring vision or structured output, it will fail silently at runtime.
Consider logging a warning when requireVision is true but the specified model may not support vision.
🤖 Prompt for AI Agents
In `@lib/utils/index.ts` around lines 30 - 48, The code currently returns a client
for SPECIFIC_API_MODEL without checking requireVision; update the block that
handles specificModel to validate vision/structured-capability when
requireVision is true: inspect the specificModel string (the existing
specificModel variable) against known vision-capable model identifiers (or a
small helper list you add) and if requireVision is true and the chosen
specificModel is not recognized as vision-capable, emit a clear warning or throw
an error; keep the existing client creation calls (createXai,
createGoogleGenerativeAI, createOpenAI) but add this validation/logging before
returning the client so callers requiring vision get an immediate, descriptive
message instead of failing at runtime.
| const openai = createOpenAI({ | ||
| apiKey: openaiApiKey, | ||
| }); | ||
| return openai(specificModel); |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Variable shadowing: openai redeclared.
The variable openai is imported at line 4 from @ai-sdk/openai and then redeclared here with createOpenAI. This shadows the import and could cause confusion.
♻️ Use a different variable name
- const openai = createOpenAI({
+ const openaiClient = createOpenAI({
apiKey: openaiApiKey,
});
- return openai(specificModel);
+ return openaiClient(specificModel);📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const openai = createOpenAI({ | |
| apiKey: openaiApiKey, | |
| }); | |
| return openai(specificModel); | |
| const openaiClient = createOpenAI({ | |
| apiKey: openaiApiKey, | |
| }); | |
| return openaiClient(specificModel); |
🤖 Prompt for AI Agents
In `@lib/utils/index.ts` around lines 44 - 47, The local const named `openai` is
shadowing the imported `openai` from `@ai-sdk/openai`; rename the local variable
returned by createOpenAI (e.g., to `openaiClient` or `openaiInstance`) and
return that instead (update the return statement from `openai(specificModel)` to
use the new name) so that the imported symbol and the created client are
distinct; update any callers in this file that expect the created client
variable name accordingly.
| }); | ||
| try { | ||
| return xai('grok-4-fast-non-reasoning'); | ||
| return xai(requireVision ? 'grok-vision-beta' : 'grok-4-fast-non-reasoning'); |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# Check all callers of getModel to understand structured output usage
rg -n "getModel\(" --type=ts -A 3 -B 2 | head -100Repository: QueueLab/QCX
Length of output: 4121
🏁 Script executed:
# Find resolution-search implementation
fd "resolution-search" --type=tsRepository: QueueLab/QCX
Length of output: 225
🏁 Script executed:
# Check what uses streamObject or generateObject
rg -n "streamObject|generateObject" --type=ts -B 2 -A 1Repository: QueueLab/QCX
Length of output: 2594
🏁 Script executed:
# Examine the actual getModel function in lib/utils/index.ts
cat lib/utils/index.tsRepository: QueueLab/QCX
Length of output: 4707
Structured output incompatibility with grok-4-fast-non-reasoning requires immediate fix.
Multiple workers use streamObject or generateObject (both requiring JSON Schema support) but are routed to grok-4-fast-non-reasoning when requireVision=false:
task-manager.tsx(line 19):generateObject+getModel()query-suggestor.tsx(line 21):streamObject+getModel()inquire.tsx(line 26):streamObject+getModel()suggest.ts(line 31):streamObject+getModel()resolution-search.tsx(line 76):streamObject+getModel(hasImage)
The xAI model grok-4-fast-non-reasoning rejects JSON Schema structured-output arguments per learnings. The fundamental issue: the requireVision parameter conflates vision capability (image analysis) with structured output capability—these are orthogonal concerns. Workers needing structured outputs regardless of image presence will fail at runtime with JSON Schema rejection errors.
For Grok fallback at line 61, 105, and 116: ensure structured output workers never receive grok-4-fast-non-reasoning. Route them to gpt-4o instead.
🤖 Prompt for AI Agents
In `@lib/utils/index.ts` at line 61, The current getModel selection uses the
requireVision flag to choose between 'grok-vision-beta' and
'grok-4-fast-non-reasoning', which mixes vision capability with
structured-output capability and causes JSON Schema rejections for consumers of
streamObject/generateObject; update the model selection logic in the getModel
function(s) so that any callsite that requires structured output (e.g.,
streamObject, generateObject, and callers getModel() used by task-manager.tsx,
query-suggestor.tsx, inquire.tsx, suggest.ts, resolution-search.tsx) never gets
'grok-4-fast-non-reasoning'—instead route those cases to 'gpt-4o'; keep
vision-only requests able to choose 'grok-vision-beta' but add a separate
boolean or enum (e.g., requiresStructuredOutput) or inspect the caller flag
(hasImage vs structuredOutput) so selection checks structured-output first and
returns 'gpt-4o' when true, otherwise fall back to vision or non-reasoning Grok
as appropriate.
This commit provides a final consolidated update of the features requested from PRs #466, #469, #470, #471, and #473: - Resolution Search: Finalized streaming logic and spatial context integration. - UI: Consolidated Tailwind-based layout fixes for mobile responsiveness and text wrapping. - Stability: Removed initial values from StreamableValue instances in app/actions.tsx to ensure hydration consistency. - Metadata: Verified license and copyright information. - Compliance: Ensured Usage and History components remain intact as requested. Co-authored-by: ngoiyaeric <115367894+ngoiyaeric@users.noreply.github.com>
…1736717079589 Standardize Header Icon Spacing
…non-responsive search
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
app/actions.tsx (1)
116-173:⚠️ Potential issue | 🟠 MajorPersisted summary can diverge from streamed summary.
summaryStream.doneusesanalysisResult.summary || fullSummary || 'Analysis complete.', but the persisted messages useanalysisResult.summary || 'Analysis complete.'. If the final object omitssummarybut the partial stream produced it, the UI shows the full summary while the saved history shows only “Analysis complete.”. Use a singlefinalSummaryfor all three writes.✅ Proposed fix
- // Mark the summary stream as done with the result. - summaryStream.done(analysisResult.summary || fullSummary || 'Analysis complete.'); - - messages.push({ role: 'assistant', content: analysisResult.summary || 'Analysis complete.' }); + const finalSummary = + analysisResult.summary || fullSummary || 'Analysis complete.'; + summaryStream.done(finalSummary); + + messages.push({ role: 'assistant', content: finalSummary }); ... - content: analysisResult.summary || 'Analysis complete.', + content: finalSummary,
📜 Review details
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (3)
app/actions.tsxapp/globals.csscomponents/empty-screen.tsx
🧰 Additional context used
🧬 Code graph analysis (2)
components/empty-screen.tsx (1)
components/ui/button.tsx (2)
props(43-52)ButtonProps(36-40)
app/actions.tsx (3)
components/section.tsx (1)
Section(24-75)components/message.tsx (1)
BotMessage(11-31)lib/agents/researcher.tsx (1)
researcher(77-161)
🪛 Biome (2.3.13)
app/actions.tsx
[error] 669-669: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.
The declaration is defined in this switch clause:
Safe fix: Wrap the declaration in a block.
(lint/correctness/noSwitchDeclarations)
[error] 682-682: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.
The declaration is defined in this switch clause:
Safe fix: Wrap the declaration in a block.
(lint/correctness/noSwitchDeclarations)
🔇 Additional comments (2)
components/empty-screen.tsx (1)
44-51: LGTM! Well-implemented mobile text wrapping improvements.The styling changes correctly address multi-line text scenarios:
items-start+mt-1on the icon ensures proper vertical alignment with the first line of wrapped textshrink-0prevents icon compression on narrow viewportswhitespace-normal text-leftwithflex-1span enables natural text wrapping while maintaining left alignmentThis is consistent with the related wrapping improvements in
search-related.tsxandsuggestions-dropdown.tsxnoted in the PR.app/globals.css (1)
190-200: LGTM!The padding reduction from
10pxto4px 10pxin.mobile-chat-input-areais a sensible UI refinement that reduces vertical space while maintaining horizontal padding. This aligns with the PR objective of improving mobile layout compactness. The media query breakpoint (max-width: 1024px) is consistent with the mobile detection logic incomponents/chat.tsx.
✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.
PR Compliance Guide 🔍Below is a summary of compliance checks for this PR:
Compliance status legend🟢 - Fully Compliant🟡 - Partial Compliant 🔴 - Not Compliant ⚪ - Requires Further Human Verification 🏷️ - Compliance label |
||||||||||||||||||||||||||
PR Code Suggestions ✨Explore these optional code suggestions:
|
||||||||||||||
User description
Integrated targeted improvements for resolution search (drawnFeatures context, streaming stability) and mobile UI (padding, layout, text wrapping) while maintaining existing codebase structure.
PR created automatically by Jules for task 545125209238302071 started by @ngoiyaeric
PR Type
Enhancement, Bug fix
Description
Improved resolution search with vision-capable model selection and streaming stability
Fixed mobile UI responsiveness with optimized padding and text wrapping
Enhanced model selection logic to support
SPECIFIC_API_MODELenvironment variableReplaced react-toastify with sonner for toast notifications
Updated LICENSE copyright and improved UI component layout robustness
Diagram Walkthrough
File Walkthrough
9 files
Enhanced model selection with vision capability supportOptimized mobile input styling and text wrappingAdded text wrapping and improved icon alignmentAdded drawnFeatures support and improved map validationAdded text wrapping for better content displayReplaced search button with portal targetAdded break-words for text wrapping supportImproved text wrapping and icon alignmentAdded clarification for JSON response format1 files
Reduced mobile padding and removed redundant styles1 files
Updated copyright year and author information1 files
Improved streaming and partial update handling1 files
Updated usage data and credit refresh information