Skip to content

Rename "planetary copilot" to "planet computer" and clear example prompts#645

Closed
ngoiyaeric wants to merge 5 commits into
mainfrom
rename-copilot-to-planet-computer-13200136455343942810
Closed

Rename "planetary copilot" to "planet computer" and clear example prompts#645
ngoiyaeric wants to merge 5 commits into
mainfrom
rename-copilot-to-planet-computer-13200136455343942810

Conversation

@ngoiyaeric
Copy link
Copy Markdown
Collaborator

@ngoiyaeric ngoiyaeric commented Jun 4, 2026

This PR renames all occurrences of "planetary copilot" to "planet computer" within the settings section of the application. It also sets the default system prompt to an empty string and updates the placeholder to "Enter your planet computer system prompt". Furthermore, it removes all example prompt messages from the empty screen as requested.

Key changes:

  • Replaced "planetary copilot" with "planet computer" in settings-view.tsx, settings.tsx, system-prompt-form.tsx, and model-selection-form.tsx.
  • Updated settingsFormSchema in settings.tsx to allow a min(0) length for the system prompt.
  • Emptied exampleMessages in empty-screen.tsx.

PR created automatically by Jules for task 13200136455343942810 started by @ngoiyaeric

Summary by CodeRabbit

  • New Features

    • Vision-capable models are now available for selection
  • Bug Fixes

    • Search button behavior improved when using map services
  • Style

    • Updated terminology throughout settings interface
    • System prompt field now allows empty values for custom configurations

…mpts

- Replaced "planetary copilot" with "planet computer" in all settings views and forms.
- Updated system prompt placeholder to "Enter your planet computer system prompt".
- Set default system prompt to an empty string.
- Adjusted Zod validation for system prompt to allow empty strings.
- Emptied the `exampleMessages` array in `EmptyScreen`.

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
@google-labs-jules
Copy link
Copy Markdown
Contributor

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented Jun 4, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
qcx Ready Ready Preview, Comment Jun 4, 2026 3:52pm

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jun 4, 2026

Review Change Stack

Walkthrough

This PR updates terminology from "planetary copilot" to "planet computer" across the settings UI, allows empty system prompts via relaxed validation, adds map-provider-aware gating to search button availability, and implements vision-capability-aware model selection for xAI and Gemini providers.

Changes

Settings, Search & Model Selection Updates

Layer / File(s) Summary
System Prompt Configuration & Settings UI Rebranding
components/settings/components/settings.tsx, components/settings/components/system-prompt-form.tsx, components/settings/components/model-selection-form.tsx, components/settings/settings-view.tsx
System prompt validation relaxed from min 10 to min 0 characters and default changed from preset persona to empty string. All settings form placeholders, descriptions, and tab headings updated to "planet computer" terminology.
Search Button Map Provider Conditional Logic
components/header-search-button.tsx
Both desktop and mobile search buttons now conditionally require the map instance only when mapProvider === "mapbox". Analysis-in-progress and missing actions still block search as before.
Vision-Capable Model Selection
lib/utils/index.ts
getModel(requireVision) now returns vision-capable models (grok-vision-beta, gemini-1.5-pro) or non-vision models (grok-4-fast-non-reasoning, gemini-3.1-pro-preview) based on the requireVision flag. xAI provider adds QCX-Terra case. Updates apply to user-selected model paths and fallback chains.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related issues

Possibly related PRs

  • QueueLab/QCX#407: Both PRs modify the shared lib/utils/index.ts getModel function; this PR adds requireVision-aware provider/model selection logic.
  • QueueLab/QCX#563: Both PRs modify components/header-search-button.tsx mobile and desktop search button behavior.

Suggested labels

Review effort 2/5

Suggested reviewers

  • CharlieHelps

Poem

🌍 From copilot to computer, the naming takes flight,
A planet of models now sees the light,
Vision and breadth through the vision-aware way,
Maps and their providers now gently say—
Empty prompts welcome, the settings renew! 🚀

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main changes in the PR: renaming 'planetary copilot' to 'planet computer' across multiple settings components and clearing the default system prompt to an empty string.
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 docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch rename-copilot-to-planet-computer-13200136455343942810

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install failed. For unrecoverable errors, disable the tool in CodeRabbit configuration.


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.

@qodo-code-review
Copy link
Copy Markdown
Contributor

Review Summary by Qodo

Rename planetary copilot to planet computer and clear defaults

✨ Enhancement

Grey Divider

Walkthroughs

Description
• Rename "planetary copilot" to "planet computer" across all settings UI
• Clear default system prompt and example messages from empty screen
• Allow empty system prompt by updating validation to min(0)
• Update all related placeholders and descriptions for consistency
Diagram
flowchart LR
  A["Settings Components"] -->|"Rename terminology"| B["planet computer"]
  C["System Prompt"] -->|"Clear default"| D["Empty string"]
  E["Validation Schema"] -->|"Allow empty"| F["min(0)"]
  G["Empty Screen"] -->|"Clear examples"| H["Empty array"]

Loading

Grey Divider

File Changes

1. components/empty-screen.tsx ✨ Enhancement +1/-22

Clear example messages from empty screen

• Cleared exampleMessages array from 4 example prompts to empty array
• Removed example messages about planet computer, climate change, QCX-Terra, and usage

components/empty-screen.tsx


2. components/settings/components/model-selection-form.tsx ✨ Enhancement +1/-1

Rename planetary copilot to planet computer

• Updated form description from "planetary copilot" to "planet computer"
• Maintains context about AI model selection capabilities

components/settings/components/model-selection-form.tsx


3. components/settings/components/settings.tsx ✨ Enhancement +4/-7

Update validation and rename terminology in settings

• Changed system prompt validation from min(10) to min(0) to allow empty strings
• Updated default system prompt from descriptive text to empty string
• Renamed "planetary copilot" to "planet computer" in two card descriptions
• Removed 10-character minimum validation error message

components/settings/components/settings.tsx


View more (2)
4. components/settings/components/system-prompt-form.tsx ✨ Enhancement +2/-2

Update system prompt form labels and descriptions

• Updated textarea placeholder from "Enter the system prompt for your planetary copilot..." to
 "Enter your planet computer system prompt"
• Changed form description from "Define how your copilot should behave..." to "Define how your
 planet computer should behave..."

components/settings/components/system-prompt-form.tsx


5. components/settings/settings-view.tsx ✨ Enhancement +1/-1

Rename planetary copilot to planet computer

• Updated settings page description from "Manage your planetary copilot preferences..." to "Manage
 your planet computer preferences..."

components/settings/settings-view.tsx


Grey Divider

ⓘ You are approaching your monthly quota for Qodo. Upgrade your plan

Qodo Logo

@qodo-code-review
Copy link
Copy Markdown
Contributor

Code Review by Qodo

Grey Divider

Looking for bugs?

Check back in a few minutes. An AI review agent is analyzing this pull request.

Grey Divider

ⓘ You are approaching your monthly quota for Qodo. Upgrade your plan

Qodo Logo

… default prompt

- Replaced "planetary copilot" with "planet computer" in settings views and forms.
- Set default system prompt to empty string.
- Updated system prompt placeholder to "Enter your planet computer system prompt".
- Kept example messages in EmptyScreen (reverted previous accidental removal).

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 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 `@components/settings/components/settings.tsx`:
- Around line 28-34: The frontend allows an empty systemPrompt but
saveSystemPrompt (in lib/actions/chat.ts) rejects falsy prompts; update
saveSystemPrompt to accept empty string values by either treating an empty
string as valid or converting empty strings to null before validation/storage so
clearing the prompt succeeds; specifically, modify the saveSystemPrompt
function's input check (the if (!prompt) early return) to allow "" (or normalize
"" -> null) and proceed to persist that normalized value, ensuring callers like
app/actions.tsx and lib/agents/researcher.tsx still get the expected fallback
behavior.
🪄 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: ASSERTIVE

Plan: Pro

Run ID: 3fd5c121-3a57-44a0-a836-9daf3e9f28da

📥 Commits

Reviewing files that changed from the base of the PR and between c143e7c and 1490bd8.

📒 Files selected for processing (5)
  • components/empty-screen.tsx
  • components/settings/components/model-selection-form.tsx
  • components/settings/components/settings.tsx
  • components/settings/components/system-prompt-form.tsx
  • components/settings/settings-view.tsx
📜 Review details
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2026-04-25T08:10:37.673Z
Learnt from: ngoiyaeric
Repo: QueueLab/QCX PR: 0
File: :0-0
Timestamp: 2026-04-25T08:10:37.673Z
Learning: In the QCX repository (feat/ai-sdk-ui-migration branch and going forward), there is no token generation/counting tracking and no multimodal LLM features. Base64 image data sent via `append()` body fields in components like `header-search-button.tsx` and `resolution-carousel.tsx` is for server-side `resolution_search` processing only — it is NOT passed as multimodal message content parts to a vision model. Avoid flagging token tracking or multimodal LLM handling gaps as review concerns in this codebase.

Applied to files:

  • components/empty-screen.tsx
🔇 Additional comments (6)
components/empty-screen.tsx (1)

4-4: LGTM!

components/settings/components/settings.tsx (2)

52-56: LGTM!


176-186: LGTM!

Also applies to: 188-198

components/settings/components/system-prompt-form.tsx (1)

13-35: LGTM!

components/settings/components/model-selection-form.tsx (1)

136-140: LGTM!

components/settings/settings-view.tsx (1)

18-29: LGTM!

Comment on lines 28 to 34
const settingsFormSchema = z.object({
systemPrompt: z
.string()
.min(10, {
message: "System prompt must be at least 10 characters.",
})
.min(0)
.max(2000, {
message: "System prompt cannot exceed 2000 characters.",
}),
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Verify handling of empty system prompts in saveSystemPrompt and chat logic

# Search for saveSystemPrompt implementation
echo "=== saveSystemPrompt implementation ==="
ast-grep --pattern 'export async function saveSystemPrompt($$$) {
  $$$
}'

# Search for system prompt usage in chat/AI logic
echo -e "\n=== System prompt usage in chat logic ==="
rg -n -A 5 -B 2 'systemPrompt' --type ts --glob '**/chat/**' --glob '**/ai/**' --glob '**/lib/actions/**'

# Look for potential string concatenation or template usage
echo -e "\n=== Potential template/concatenation usage ==="
rg -n -P 'systemPrompt.*\+|`.*\$\{.*systemPrompt.*\}' --type ts

Repository: QueueLab/QCX

Length of output: 2454


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== Locate saveSystemPrompt / getSystemPrompt definitions ==="
rg -n --hidden --no-ignore -S "function saveSystemPrompt|saveSystemPrompt\s*\(|function getSystemPrompt|getSystemPrompt\s*\(" -t ts -g '!*node_modules*'

echo -e "\n=== Inspect lib/actions/chat.ts around getSystemPrompt/saveSystemPrompt and model usage ==="
FILE="lib/actions/chat.ts"
if [ -f "$FILE" ]; then
  nl -ba "$FILE" | sed -n '1,260p'
else
  echo "Missing $FILE"
fi

echo -e "\n=== Inspect settings schema and defaults in components/settings/components/settings.tsx ==="
SFILE="components/settings/components/settings.tsx"
if [ -f "$SFILE" ]; then
  nl -ba "$SFILE" | sed -n '1,160p'
else
  echo "Missing $SFILE"
fi

echo -e "\n=== Other systemPrompt usages in AI/chat code paths ==="
rg -n -S "systemPrompt" -t ts -g 'lib/**' -g 'components/**' -g 'app/**' | head -n 200

Repository: QueueLab/QCX

Length of output: 669


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== lib/actions/chat.ts: saveSystemPrompt & getSystemPrompt ==="
sed -n '130,210p' lib/actions/chat.ts

echo -e "\n=== app/actions.tsx: currentSystemPrompt handling ==="
sed -n '430,540p' app/actions.tsx

echo -e "\n=== components/settings/components/settings.tsx: schema + default ==="
sed -n '1,160p' components/settings/components/settings.tsx

echo -e "\n=== Find where systemPrompt/currentSystemPrompt is passed to the model ==="
rg -n -S "currentSystemPrompt|systemPrompt\s*[:)]|system:\s*.*(systemPrompt|currentSystemPrompt)" -t ts app lib components

echo -e "\n=== Find any normalization/fallback for empty systemPrompt ==="
rg -n -S "systemPrompt.*\|\|\s*''|systemPrompt.*??|if\s*\(.*systemPrompt|trim\(\).*systemPrompt" -t ts app lib components

Repository: QueueLab/QCX

Length of output: 12654


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== lib/agents/researcher.tsx: how systemPromptToUse is derived ==="
sed -n '1,220p' lib/agents/researcher.tsx

echo -e "\n=== lib/agents/resolution-search.tsx: system prompt handling ==="
sed -n '1,220p' lib/agents/resolution-search.tsx

echo -e "\n=== components/settings/components/system-prompt-form.tsx (UI constraints) ==="
sed -n '1,120p' components/settings/components/system-prompt-form.tsx

Repository: QueueLab/QCX

Length of output: 14997


🏁 Script executed:

#!/bin/bash
set -euo pipefail
sed -n '1,120p' lib/db/schema.ts
sed -n '120,200p' lib/db/schema.ts

Repository: QueueLab/QCX

Length of output: 6945


Fix empty system prompt persistence mismatch

The form schema allows an empty systemPrompt (.min(0) with default ""), but lib/actions/chat.ts’s saveSystemPrompt rejects it via if (!prompt) return { error: 'Prompt is required' }, so clearing/saving an empty prompt fails.

Chat/AI runtime is likely safe because app/actions.tsx converts null to '', and lib/agents/researcher.tsx falls back to getDefaultSystemPrompt(...) when dynamicSystemPrompt.trim() is empty.

Update saveSystemPrompt to accept empty strings (or convert empty string to null for storage) so UI behavior matches backend behavior.

🤖 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 `@components/settings/components/settings.tsx` around lines 28 - 34, The
frontend allows an empty systemPrompt but saveSystemPrompt (in
lib/actions/chat.ts) rejects falsy prompts; update saveSystemPrompt to accept
empty string values by either treating an empty string as valid or converting
empty strings to null before validation/storage so clearing the prompt succeeds;
specifically, modify the saveSystemPrompt function's input check (the if
(!prompt) early return) to allow "" (or normalize "" -> null) and proceed to
persist that normalized value, ensuring callers like app/actions.tsx and
lib/agents/researcher.tsx still get the expected fallback behavior.

@ngoiyaeric
Copy link
Copy Markdown
Collaborator Author

@coderabbitai the resolution search is not working but there are no code changes regarding that, can you debug that

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jun 4, 2026

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Search for resolution search related code
echo "=== Searching for 'resolution' in source files ==="
rg -rn "resolution" --type ts --type tsx -C 3 2>/dev/null | head -200

echo ""
echo "=== Searching for 'resolution' in all files ==="
rg -rn "resolution" -C 3 --glob "!node_modules" --glob "!.git" --glob "!*.lock" 2>/dev/null | head -300

echo ""
echo "=== Searching for 'search' related API routes ==="
fd -e ts -e tsx --exclude node_modules | xargs grep -l "search" 2>/dev/null | head -30

Length of output: 12754


🏁 Script executed:

#!/bin/bash
echo "=== File structure overview ==="
tree -L 3 --gitignore 2>/dev/null | head -100

echo ""
echo "=== API routes ==="
fd -t f -e ts --exclude node_modules -p "app/api" 2>/dev/null
find . -path ./node_modules -prune -o -path "./.git" -prune -o -name "*.ts" -path "*/api/*" -print 2>/dev/null | head -50

Length of output: 3149


🏁 Script executed:

#!/bin/bash
echo "=== Search for 'resolution' keyword broadly ==="
rg -rn "resolution" --glob "!node_modules" --glob "!.git" --glob "!*.lock" --glob "!*.json" -l 2>/dev/null

echo ""
echo "=== Search for search-related components or hooks ==="
rg -rn "resolution" --glob "!node_modules" --glob "!.git" --glob "!*.lock" -C 5 2>/dev/null | head -400

Length of output: 17720


🏁 Script executed:

#!/bin/bash
echo "=== Check if n-search.tsx exists vs resolution-search.tsx ==="
fd -t f "n-search" --exclude node_modules 2>/dev/null
fd -t f "resolution-search" --exclude node_modules 2>/dev/null

echo ""
echo "=== Check if n-carousel exists ==="
fd -t f "n-carousel" --exclude node_modules 2>/dev/null
fd -t f "n-image" --exclude node_modules 2>/dev/null
fd -t f "resolution-carousel" --exclude node_modules 2>/dev/null
fd -t f "resolution-image" --exclude node_modules 2>/dev/null

echo ""
echo "=== Check n-search schema vs resolution-search schema ==="
fd -t f "n-search" lib/schema --exclude node_modules 2>/dev/null
fd -t f -e ts -e tsx lib/schema --exclude node_modules 2>/dev/null

echo ""
echo "=== Full content of lib/agents/resolution-search.tsx ==="
cat lib/agents/resolution-search.tsx

echo ""
echo "=== Full content of lib/agents/index.tsx ==="
cat lib/agents/index.tsx

echo ""
echo "=== Full content of lib/schema/resolution-search.ts ==="
cat lib/schema/resolution-search.ts

echo ""
echo "=== Imports in app/actions.tsx ==="
head -40 app/actions.tsx

Length of output: 11964


🏁 Script executed:

#!/bin/bash
echo "=== Full resolution search invocation in app/actions.tsx ==="
grep -n "nSearch\|resolutionSearch\|n_search\|processResolution" app/actions.tsx

echo ""
echo "=== Full content of components/header-search-button.tsx ==="
cat components/header-search-button.tsx

echo ""
echo "=== Full content of components/resolution-carousel.tsx ==="
cat components/resolution-carousel.tsx

echo ""
echo "=== Check what's actually exported from lib/agents/resolution-search.tsx ==="
grep -n "^export" lib/agents/resolution-search.tsx

echo ""
echo "=== Check what nSearch resolves to in lib/agents/index.tsx ==="
cat lib/agents/index.tsx

echo ""
echo "=== Does n-search file exist anywhere? ==="
fd "n-search" --exclude node_modules 2>/dev/null

echo ""
echo "=== Actions.tsx: full n_search action block ==="
grep -n -A 80 "if (action === 'n_search')" app/actions.tsx | head -120

Length of output: 14788



@ngoiyaeric I found the bug. It's in components/header-search-button.tsx.

Root Cause

The search button's disabled condition uses !map, but map comes from useMap() which is the Mapbox map context. When the map provider is Google Maps, map is always null, so the button is permanently disabled — it can never be clicked.

// Line ~163 (desktop button) and ~175 (mobile button)
// BUG: !map is always true for Google Maps users
disabled={isAnalyzing || !map || !actions}

The handler function already handles this correctly with a provider guard:

if (mapProvider === 'mapbox' && !map) {
  toast.error('Map is not available yet...')
  return
}

But the disabled prop doesn't apply the same guard.

Fix

// Desktop button
disabled={isAnalyzing || (mapProvider === 'mapbox' && !map) || !actions}

// Mobile button  
disabled={isAnalyzing || (mapProvider === 'mapbox' && !map) || !actions}

This ensures:

  • For Mapbox users: button is disabled until the Mapbox map instance loads (correct).
  • For Google Maps users: button is enabled (and image capture falls through to the cameraState path in handleResolutionSearch).

The rest of the resolution search pipeline — imports, action string (resolution_search), schema, agent function name — is all consistent and should work once the button is clickable.

Would you like me to open a GitHub issue or plan the code fix for this?

@google-labs-jules
Copy link
Copy Markdown
Contributor

@coderabbitai the resolution search is not working but there are no code changes regarding that, can you debug that

I've investigated the issue with Resolution Search. It was failing because the getModel utility was always returning non-vision model versions (like grok-4-fast-non-reasoning) even when vision was required for image analysis. I've updated getModel to correctly select vision-capable models (grok-vision-beta or gemini-1.5-pro) when the requireVision flag is set. This should resolve the issue.

…ter"

- Updated `getModel` in `lib/utils/index.ts` to support vision models (`grok-vision-beta`, `gemini-1.5-pro`) when `requireVision` is true.
- Replaced "planetary copilot" with "planet computer" in all settings views and forms.
- Updated system prompt placeholder to "Enter your planet computer system prompt".
- Set default system prompt to an empty string.
- Adjusted Zod validation for system prompt to allow empty strings.
- Restored example messages in `EmptyScreen`.

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
- Fixed `HeaderSearchButton` being disabled for Google Maps users by updating the `disabled` prop logic.
- Updated `getModel` to correctly select vision models (`grok-vision-beta`, `gemini-1.5-pro`) when `requireVision` is true.
- Renamed "planetary copilot" to "planet computer" in settings.
- Cleared default system prompt and updated placeholder.
- Updated Zod validation for system prompt.
- Restored example messages in `EmptyScreen`.

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
@ngoiyaeric
Copy link
Copy Markdown
Collaborator Author

@coderabbitai the resolution search is not working but there are no code changes regarding that, can you debug that

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jun 4, 2026

Tip

For best results, initiate chat on the files or code changes.

@ngoiyaeric I already diagnosed this in my previous reply above — here's a quick recap:

Root Cause — components/header-search-button.tsx

The disabled prop on both the desktop and mobile search buttons checks !map, where map comes from useMap() (the Mapbox map context). When Google Maps is the active provider, map is always null, so the button is permanently disabled and can never be clicked.

// Current (buggy) — Line ~163 desktop, ~175 mobile
disabled={isAnalyzing || !map || !actions}

The click handler already has the right provider guard:

if (mapProvider === 'mapbox' && !map) {
  toast.error('Map is not available yet...')
  return
}

But the disabled prop doesn't apply that same guard.

Fix

// Both desktop and mobile buttons
disabled={isAnalyzing || (mapProvider === 'mapbox' && !map) || !actions}

This way:

  • Mapbox users: button stays disabled until the Mapbox map instance loads ✓
  • Google Maps users: button is enabled; handleResolutionSearch proceeds via the cameraState path ✓

The rest of the pipeline (schema, agent, action string resolution_search) is consistent and should work once the button is clickable.


Would you like me to:

  1. Open a GitHub issue to track this bug fix?
  2. Plan the code change directly on this PR or a new branch?

🧠 Learnings used
Learnt from: ngoiyaeric
Repo: QueueLab/QCX PR: 0
File: :0-0
Timestamp: 2026-04-25T08:10:37.673Z
Learning: In the QCX repository (feat/ai-sdk-ui-migration branch and going forward), there is no token generation/counting tracking and no multimodal LLM features. Base64 image data sent via `append()` body fields in components like `header-search-button.tsx` and `resolution-carousel.tsx` is for server-side `resolution_search` processing only — it is NOT passed as multimodal message content parts to a vision model. Avoid flagging token tracking or multimodal LLM handling gaps as review concerns in this codebase.

@google-labs-jules
Copy link
Copy Markdown
Contributor

@coderabbitai the resolution search is not working but there are no code changes regarding that, can you debug that

I've identified and fixed two issues that were preventing Resolution Search from working correctly:

  1. Model Vision Capability: The getModel utility in lib/utils/index.ts was not respecting the requireVision flag, often returning non-vision models like grok-4-fast-non-reasoning. I've updated it to correctly route to vision-capable models (grok-vision-beta or gemini-1.5-pro) when required.

  2. Button Disabled Bug: In components/header-search-button.tsx, the search button was permanently disabled for users with Google Maps as their provider because it was strictly checking for a Mapbox map instance. I've updated the disabled logic to only require the map instance when Mapbox is the active provider.

These changes are included in this PR update.

- Fix getModel to return vision-capable models when requireVision is true.
- Fix HeaderSearchButton disabled state for Google Maps users.
- Rename "planetary copilot" to "planet computer" in settings.
- Empty default system prompt and update placeholder.
- Restore example messages in EmptyScreen.

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 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 `@lib/utils/index.ts`:
- Line 45: getModel currently only switches on requireVision and returns
xai("grok-4-fast-non-reasoning") for non-vision use, which is unsafe for
structured-output; add a new boolean parameter (e.g., requireStructuredOutput or
supportsJsonSchema) to the getModel signature in lib/utils/index.ts and when
true return a JSON-schema-capable model (e.g., openai("gpt-4o") or another
approved model) instead of grok-4-fast-non-reasoning; update all call sites that
use generateObject/streamObject with a schema (e.g., generateObject({ model:
(await getModel()), schema: nextActionSchema }) in lib/agents/task-manager.tsx
and streamObject calls in lib/agents/query-suggestor.tsx,
lib/agents/inquire.tsx, lib/agents/resolution-search.tsx and
lib/actions/suggest.ts) to pass the new flag so structured-output flows select
the JSON-schema-capable model while leaving vision and other paths unchanged.
🪄 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: ASSERTIVE

Plan: Pro

Run ID: 9752be9f-a43b-4583-935b-a2c4729e552d

📥 Commits

Reviewing files that changed from the base of the PR and between 1490bd8 and f3abcd7.

📒 Files selected for processing (2)
  • components/header-search-button.tsx
  • lib/utils/index.ts
📜 Review details
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2026-04-25T08:10:37.673Z
Learnt from: ngoiyaeric
Repo: QueueLab/QCX PR: 0
File: :0-0
Timestamp: 2026-04-25T08:10:37.673Z
Learning: In the QCX repository (feat/ai-sdk-ui-migration branch and going forward), there is no token generation/counting tracking and no multimodal LLM features. Base64 image data sent via `append()` body fields in components like `header-search-button.tsx` and `resolution-carousel.tsx` is for server-side `resolution_search` processing only — it is NOT passed as multimodal message content parts to a vision model. Avoid flagging token tracking or multimodal LLM handling gaps as review concerns in this codebase.

Applied to files:

  • components/header-search-button.tsx
📚 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
🔇 Additional comments (1)
components/header-search-button.tsx (1)

174-174: LGTM!

Also applies to: 186-186

Comment thread lib/utils/index.ts
});
try {
return xai('grok-4-fast-non-reasoning');
return xai(requireVision ? "grok-vision-beta" : "grok-4-fast-non-reasoning");
Copy link
Copy Markdown
Contributor

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify where getModel() is used with structured-output APIs.
# Expected: identify call sites where getModel(...) feeds streamObject/generateObject flows.

set -euo pipefail

echo "== getModel call sites =="
rg -n -C2 '\bgetModel\s*\(' --type ts --type tsx

echo
echo "== structured output API usage (streamObject/generateObject) =="
rg -n -C3 '\b(streamObject|generateObject)\s*\(' --type ts --type tsx

echo
echo "== resolution-search and related agents around model selection =="
rg -n -C4 'model:\s*await\s+getModel|model:\s*\(await getModel' lib --type ts --type tsx

Repository: QueueLab/QCX

Length of output: 128


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== getModel call sites =="
rg -n -C2 '\bgetModel\s*\(' lib -g'*.ts' -g'*.tsx'

echo
echo "== structured output call sites =="
rg -n -C3 '\b(streamObject|generateObject)\s*\(' lib -g'*.ts' -g'*.tsx'

echo
echo "== look for model: (await) getModel near structured output usage =="
rg -n -C4 'model:\s*\(?\s*(await\s+)?getModel' lib -g'*.ts' -g'*.tsx'

Repository: QueueLab/QCX

Length of output: 10620


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== lib/utils/index.ts around getModel =="
sed -n '1,140p' lib/utils/index.ts | nl -ba | sed -n '1,140p'

echo
echo "== lib/utils/index.ts: lines ~35-110 (for exact grok routing) =="
sed -n '35,110p' lib/utils/index.ts | nl -ba

echo
echo "== lib/agents/task-manager.tsx: generateObject block =="
sed -n '1,120p' lib/agents/task-manager.tsx | nl -ba | sed -n '1,120p'

echo
echo "== lib/agents/query-suggestor.tsx: streamObject block end (schema) =="
sed -n '1,120p' lib/agents/query-suggestor.tsx | nl -ba | sed -n '40,120p'

echo
echo "== lib/agents/inquire.tsx: streamObject block end (schema) =="
sed -n '1,120p' lib/agents/inquire.tsx | nl -ba | sed -n '1,120p'

Repository: QueueLab/QCX

Length of output: 158


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== lib/utils/index.ts (first 140 lines) =="
sed -n '1,140p' lib/utils/index.ts | cat -n

echo
echo "== lib/agents/task-manager.tsx (first 140 lines) =="
sed -n '1,140p' lib/agents/task-manager.tsx | cat -n

echo
echo "== lib/agents/query-suggestor.tsx (first 120 lines) =="
sed -n '1,120p' lib/agents/query-suggestor.tsx | cat -n

echo
echo "== lib/agents/inquire.tsx (first 120 lines) =="
sed -n '1,120p' lib/agents/inquire.tsx | cat -n

Repository: QueueLab/QCX

Length of output: 15644


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== lib/utils/index.ts: grok-4-fast-non-reasoning routing =="
rg -n "grok-4-fast-non-reasoning" lib/utils/index.ts

echo
echo "== structured output call sites using getModel() ==" 
rg -n -C2 "model:\s*\(await\s+getModel\(\)\)" lib -g'*.ts' -g'*.tsx' | rg -n -C2 "(streamObject|generateObject)"

echo
echo "== structured output call sites (streamObject/generateObject) that pass schema =="
rg -n -C2 "(streamObject|generateObject)\s*\(" lib -g'*.ts' -g'*.tsx' | rg -n -C2 "schema:"

Repository: QueueLab/QCX

Length of output: 2028


Route structured-output calls to a JSON-schema-compatible model (xAI grok-4-fast-non-reasoning is unsafe)

lib/utils/index.ts selects xAI grok-4-fast-non-reasoning whenever requireVision is false (lines 45 and 90), but multiple structured-output call sites use generateObject/streamObject with a schema while calling getModel() with the default requireVision=false, e.g.:

  • lib/agents/task-manager.tsx: generateObject({ model: (await getModel()), schema: nextActionSchema })
  • lib/agents/query-suggestor.tsx: streamObject({ model: (await getModel()), schema: relatedSchema })
  • lib/agents/inquire.tsx: streamObject({ model: (await getModel()), schema: inquirySchema })
  • (Also) lib/agents/resolution-search.tsx / lib/actions/suggest.ts: streamObject(..., schema: ...) with getModel(hasImage) (so non-image paths can still hit grok-4-fast-non-reasoning)

Per the guidance, structured-output workers must not use grok-4-fast-non-reasoning; model selection needs a dedicated “structured-output/JSON-schema capable” signal (not just requireVision) and must route those calls to a compatible model (e.g., OpenAI gpt-4o).

🤖 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 `@lib/utils/index.ts` at line 45, getModel currently only switches on
requireVision and returns xai("grok-4-fast-non-reasoning") for non-vision use,
which is unsafe for structured-output; add a new boolean parameter (e.g.,
requireStructuredOutput or supportsJsonSchema) to the getModel signature in
lib/utils/index.ts and when true return a JSON-schema-capable model (e.g.,
openai("gpt-4o") or another approved model) instead of
grok-4-fast-non-reasoning; update all call sites that use
generateObject/streamObject with a schema (e.g., generateObject({ model: (await
getModel()), schema: nextActionSchema }) in lib/agents/task-manager.tsx and
streamObject calls in lib/agents/query-suggestor.tsx, lib/agents/inquire.tsx,
lib/agents/resolution-search.tsx and lib/actions/suggest.ts) to pass the new
flag so structured-output flows select the JSON-schema-capable model while
leaving vision and other paths unchanged.

@ngoiyaeric ngoiyaeric closed this Jun 4, 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