Fix system prompt defaults and user ID retrieval#517
Conversation
- Update `app/actions.tsx` to fetch the system prompt using the authenticated user's ID via `getCurrentUserIdOnServer()`, falling back to 'anonymous' if not logged in. - Update the hardcoded default system prompt in `components/settings/components/settings.tsx` to a more relevant geospatial assistant prompt. - Fixes issue where custom system prompts were ignored during chat and 'Reset to Defaults' used a planetary copilot placeholder. Co-authored-by: ngoiyaeric <115367894+ngoiyaeric@users.noreply.github.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
👋 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 New to Jules? Learn more at jules.google/docs. For security, I will only act on instructions from the user who triggered this task. |
|
|
WalkthroughThis PR introduces server-side user identification by replacing hard-coded 'anonymous' userIds with dynamic fetches via getCurrentUserIdOnServer(), and updates the default system prompt from a planetary copilot description to a geospatial/mapping-oriented assistant description. Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (3 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 |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In `@app/actions.tsx`:
- Line 25: Redundant dynamic import: remove the dynamic import of
getCurrentUserIdOnServer inside onSetAIState and use the already statically
imported getCurrentUserIdOnServer instead; update the onSetAIState
implementation to call getCurrentUserIdOnServer() directly (replace await
import(...).then(m => m.getCurrentUserIdOnServer()) or similar), and remove any
unused dynamic-import variables so the static import at the top is the single
source of truth.
In `@components/settings/components/settings.tsx`:
- Around line 54-59: The defaultValues.constant for systemPrompt is inconsistent
with the UI copy that uses "planetary copilot"; update the systemPrompt string
inside defaultValues (and, if preferred, the placeholder in
system-prompt-form.tsx and the heading text around the component) so all three
references use the same terminology (e.g., "planetary copilot") and matching
wording about geospatial/mapping/environment-aware behavior; locate the symbols
defaultValues and systemPrompt in the settings component and the
placeholder/heading text in system-prompt-form.tsx and make the copy identical
for a consistent UX.
📜 Review details
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (2)
app/actions.tsxcomponents/settings/components/settings.tsx
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: ngoiyaeric
Repo: QueueLab/QCX PR: 0
File: :0-0
Timestamp: 2026-02-08T16:50:33.791Z
Learning: The PR branch implements RAG (Retrieval-Augmented Generation) via `lib/actions/rag.ts` which uses Supabase RPC functions `generate_embedding()` and `hybrid_search()` to retrieve relevant context from past conversations. However, there's a bug on line 433 of `app/actions.tsx` where `currentSystemPrompt` is passed to the researcher instead of `augmentedSystemPrompt`, preventing the retrieved context from being used.
📚 Learning: 2026-02-10T08:45:03.719Z
Learnt from: ngoiyaeric
Repo: QueueLab/QCX PR: 0
File: :0-0
Timestamp: 2026-02-10T08:45:03.719Z
Learning: The user confirmed that app/auth/page.tsx, lib/auth/v0/auth-service.ts, lib/supabase/browser-client.ts, and middleware.ts all exist and are fully implemented with Supabase SSR authentication. These files are production-ready and should not be replaced or considered legacy/stubs.
Applied to files:
app/actions.tsx
🧬 Code graph analysis (1)
components/settings/components/settings.tsx (1)
components/settings/components/system-prompt-form.tsx (1)
SystemPromptForm(9-36)
🔇 Additional comments (1)
app/actions.tsx (1)
401-402: LGTM — user-specific system prompt retrieval.Correctly resolves the authenticated user's ID before fetching their customized system prompt, with a sensible
'anonymous'fallback.
✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.
| import SearchRelated from '@/components/search-related' | ||
| import { GeoJsonLayer } from '@/components/map/geojson-layer' | ||
| import { ResolutionCarousel } from '@/components/resolution-carousel' | ||
| import { getCurrentUserIdOnServer } from '@/lib/auth/get-current-user' |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major
Redundant dynamic import — getCurrentUserIdOnServer is already statically imported.
Line 25 adds a static import, but lines 641–643 in onSetAIState still dynamically import the same module. The dynamic import is now unnecessary overhead and a maintenance inconsistency.
♻️ Suggested fix
- const { getCurrentUserIdOnServer } = await import(
- '@/lib/auth/get-current-user'
- )
- const actualUserId = await getCurrentUserIdOnServer()
+ const actualUserId = await getCurrentUserIdOnServer()Also applies to: 641-643
🤖 Prompt for AI Agents
In `@app/actions.tsx` at line 25, Redundant dynamic import: remove the dynamic
import of getCurrentUserIdOnServer inside onSetAIState and use the already
statically imported getCurrentUserIdOnServer instead; update the onSetAIState
implementation to call getCurrentUserIdOnServer() directly (replace await
import(...).then(m => m.getCurrentUserIdOnServer()) or similar), and remove any
unused dynamic-import variables so the static import at the top is the single
source of truth.
| const defaultValues: Partial<SettingsFormValues> = { | ||
| systemPrompt: | ||
| "You are a planetary copilot, an AI assistant designed to help users with information about planets, space exploration, and astronomy. Provide accurate, educational, and engaging responses about our solar system and beyond.", | ||
| "You are an AI assistant designed to help users with geospatial data, mapping, and environment-aware insights. Provide accurate and helpful responses based on the available tools and context.", | ||
| selectedModel: "Grok 4.2", | ||
| users: [], | ||
| } |
There was a problem hiding this comment.
Minor terminology inconsistency with surrounding UI text.
The default prompt now describes a "geospatial data, mapping, and environment-aware insights" assistant, but system-prompt-form.tsx (line 22) still uses the placeholder "Enter the system prompt for your planetary copilot..." and line 183 of this file still reads "Customize the behavior and persona of your planetary copilot". Consider aligning the terminology for a consistent user experience.
🤖 Prompt for AI Agents
In `@components/settings/components/settings.tsx` around lines 54 - 59, The
defaultValues.constant for systemPrompt is inconsistent with the UI copy that
uses "planetary copilot"; update the systemPrompt string inside defaultValues
(and, if preferred, the placeholder in system-prompt-form.tsx and the heading
text around the component) so all three references use the same terminology
(e.g., "planetary copilot") and matching wording about
geospatial/mapping/environment-aware behavior; locate the symbols defaultValues
and systemPrompt in the settings component and the placeholder/heading text in
system-prompt-form.tsx and make the copy identical for a consistent UX.
There was a problem hiding this comment.
The session-aware userId lookup is a functional improvement, but it’s currently performed unconditionally; if skip is a fast-path, this adds unnecessary server work/latency. The updated default system prompt matches the domain better, but it may be too generic to reliably steer tool use and GeoJSON/mapping behaviors after resets. Addressing these would improve performance and default behavior quality.
Additional notes (2)
- Maintainability |
components/settings/components/settings.tsx:54-59
The new default system prompt is still fairly generic. If the app relies on tool-use or specific behaviors (e.g., map provider selection, GeoJSON handling, coordinate systems, safety constraints, citation requirements), this default may under-specify expected behavior and lead to lower-quality outputs after a reset.
This isn’t a correctness issue, but defaults are product-critical because they shape behavior for new users and after reset.
- Maintainability |
components/settings/components/settings.tsx:53-59
Hardcoding a specific model name ("Grok 4.2") in defaults can become brittle if the available model list changes (or if this app is deployed in environments with different model availability). If there is a canonical "default model" coming from config/server capabilities, it’s better to derive this default from that source to avoid shipping a stale value and causing confusing resets.
Summary of changes
What changed
app/actions.tsx
- Added an import for
getCurrentUserIdOnServerfrom@/lib/auth/get-current-user. - Updated
submit()to deriveuserIdfrom the authenticated session viaawait getCurrentUserIdOnServer()and fallback to'anonymous'. - Continued to fetch the system prompt via
getSystemPrompt(userId)using the session-awareuserId.
components/settings/components/settings.tsx
- Updated
defaultValues.systemPromptfrom a space/astronomy-focused prompt to a geospatial/mapping-focused prompt so Reset to Defaults aligns with the app domain.
|
|
||
| const userId = 'anonymous' | ||
| const userId = (await getCurrentUserIdOnServer()) || 'anonymous' | ||
| const currentSystemPrompt = (await getSystemPrompt(userId)) || '' | ||
| const mapProvider = formData?.get('mapProvider') as 'mapbox' | 'google' |
There was a problem hiding this comment.
submit() now hits getCurrentUserIdOnServer() unconditionally, even when skip is true. If skip is used for preview/fast-path flows (or other scenarios where the action doesn’t need user-scoped prompt), this introduces avoidable server work and potential latency. Also, getSystemPrompt(userId) is called even when currentSystemPrompt may not be used depending on later control flow.
Consider moving user/system-prompt resolution behind the branch that actually needs it, or at least behind if (!skip) if that matches intended behavior.
Suggestion
If skip is intended to bypass any model/task execution, gate the user lookup and prompt fetch behind the non-skip path (or lazily fetch only when needed). For example:
let currentSystemPrompt = ''
if (!skip) {
const userId = (await getCurrentUserIdOnServer()) || 'anonymous'
currentSystemPrompt = (await getSystemPrompt(userId)) || ''
}If you still need the prompt in skip mode, consider documenting why with an inline comment, or caching the userId/prompt at a higher level if submit() is called frequently.
Reply with "@CharlieHelps yes please" if you’d like me to add a commit with this refactor.
|
|
||
| const userId = 'anonymous' | ||
| const userId = (await getCurrentUserIdOnServer()) || 'anonymous' | ||
| const currentSystemPrompt = (await getSystemPrompt(userId)) || '' |
There was a problem hiding this comment.
Fetching the user ID on every submit() call may add avoidable latency, especially if getCurrentUserIdOnServer() hits an auth provider/DB each time. If submit() can be invoked multiple times in a single request lifecycle (e.g., via retries/stream steps) or if it’s called frequently, consider reading the user ID once at the top-level request boundary (or caching within the request) and threading it through.
Also consider whether 'anonymous' should be a shared bucket. As implemented, all unauthenticated users will share the same system prompt record (if stored), which can cause cross-user leakage of prompt customization if anonymous prompts are persisted and editable anywhere in the UI.
Suggestion
Consider caching the user ID for the lifetime of the request, and ensure anonymous prompts are not globally shared unless that’s intentional.
Example approach:
- Resolve once at the top of
submit()and pass it down to any inner functions that need it. - If you want per-session anonymous prompts, key by session ID (or avoid persistence for anonymous users).
Reply with "@CharlieHelps yes please" if you'd like me to add a commit implementing request-scoped caching and/or a safer anonymous-keying strategy.
|
@coderabbitai now its hardcoded and not changing! |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: Length of output: 15576 🏁 Script executed: Length of output: 10770 🏁 Script executed: Length of output: 0 🏁 Script executed: Length of output: 0 🏁 Script executed: Length of output: 0 🏁 Script executed: Length of output: 14 🏁 Script executed: Length of output: 0 🏁 Script executed: Length of output: 784 🏁 Script executed: Length of output: 0 🏁 Script executed: Length of output: 1057 🏁 Script executed: Length of output: 1800 🏁 Script executed: Length of output: 527 🏁 Script executed: Length of output: 667 🏁 Script executed: Length of output: 1030 🏁 Script executed: Length of output: 647 🏁 Script executed: Length of output: 1105 🏁 Script executed: Length of output: 0 🏁 Script executed: Length of output: 1490 🏁 Script executed: Length of output: 1076 🏁 Script executed: Length of output: 1070
When you save a system prompt in Settings, it's stored in the database. But when you use the chat, if the system can't retrieve your saved prompt, it falls back to a hardcoded default defined in the Let me check a few things to diagnose the exact problem: Can you help me understand what's happening by answering these questions:
🏁 Script executed: Length of output: 602 🏁 Script executed: Length of output: 677 🏁 Script executed: Length of output: 19 Based on my analysis, I've found the issue! Here's what's happening: The ProblemIn const userId = (await getCurrentUserIdOnServer()) || 'anonymous'
const currentSystemPrompt = (await getSystemPrompt(userId)) || ''When Then in const systemPromptToUse =
dynamicSystemPrompt?.trim()
? dynamicSystemPrompt
: getDefaultSystemPrompt(currentDate, drawnFeatures)The Root CauseThis happens when:
Let me check your environment: To fix this issue, you need to ensure the default system prompt is properly set. The PR changed the default in Would you like me to help you create a proper fix that:
🏁 Script executed: Length of output: 46 🏁 Script executed: Length of output: 0 Root Cause Identified! 🎯I found the problem! Your PR updated the default system prompt in the Settings form (
When a user's system prompt isn't found in the database (or they're unauthenticated), the chat uses the researcher's hardcoded default, NOT the one you set in settings.tsx. That's why it's "hardcoded and not changing"! The SolutionYou need to:
Would you like me to plan these code changes for you? I can:
Should I go ahead and plan the fix? 🐰 🧠 Learnings used |
|
@coderabbitai the resolution search feature does not work |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain
🏁 Script executed: Length of output: 27 🏁 Script executed: Length of output: 27 🏁 Script executed: Length of output: 544 🏁 Script executed: Length of output: 0 🏁 Script executed: Length of output: 0 🏁 Script executed: Length of output: 4162 🏁 Script executed: Length of output: 5153 🏁 Script executed: Length of output: 14273 🏁 Script executed: Length of output: 187 🏁 Script executed: Length of output: 6425 🏁 Script executed: Length of output: 1274 🏁 Script executed: Length of output: 1293 🏁 Script executed: Length of output: 324 🏁 Script executed: Length of output: 2966 🏁 Script executed: Length of output: 6208 🏁 Script executed: Length of output: 3333 🏁 Script executed: Length of output: 8089 🏁 Script executed: Length of output: 0 🏁 Script executed: Length of output: 8155
🎯 Root CauseThe resolution search feature requires an AI model with vision capabilities to analyze satellite images. The 🔑 Required ConfigurationYou need to configure at least one of these API keys in your Option 1: Grok (xAI) - RecommendedXAI_API_KEY=your_xai_api_key_here
Option 2: Gemini 3 ProGEMINI_3_PRO_API_KEY=your_gemini_api_key_here
Option 3: OpenAIOPENAI_API_KEY=your_openai_api_key_here
Option 4: AWS Bedrock (Claude)AWS_ACCESS_KEY_ID=your_aws_access_key
AWS_SECRET_ACCESS_KEY=your_aws_secret_key
AWS_REGION=us-east-1
BEDROCK_MODEL_ID=anthropic.claude-3-5-sonnet-20241022-v2:0
🛠️ How to Fix
📝 Current Model SelectionYour settings currently default to "Grok 4.2", which requires
🔍 DebuggingIf it still doesn't work after adding an API key:
Let me know which API key you're planning to use, and I can help you verify it's set up correctly! 🐰 🧠 Learnings used |
Updated the codebase to ensure that the system prompt is correctly retrieved for authenticated users and updated the hardcoded default values in the settings form.
Key changes:
submitinapp/actions.tsxto usegetCurrentUserIdOnServer()for fetching the user-specific system prompt from the database. It now correctly falls back to'anonymous'for unauthenticated sessions.defaultValues.systemPromptincomponents/settings/components/settings.tsxto a geospatial-focused prompt, replacing the previous "planetary copilot" (astronomy) default.These changes ensure that user customizations to the system prompt are actually applied during chat interactions and that the "Reset to Defaults" button behaves as expected for the application's domain.
PR created automatically by Jules for task 12021650852449529727 started by @ngoiyaeric
Summary by CodeRabbit