From 4d9b0afde72b23d454a5fed439b0b2bbd780e566 Mon Sep 17 00:00:00 2001 From: michael Date: Mon, 1 Dec 2025 10:37:36 -0600 Subject: [PATCH] upgraded to Gemini 3.0 Pro (gemini-3-pro-preview) from Gemini 2.5 Pro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Upgraded google-genai package from 1.31.0 to 1.52.0 - Updated DEFAULT_MODEL in llm_service.py to gemini-3-pro-preview - Updated all backend routes, services, and models with new model string - Updated all frontend components with new model string and display labels - Updated CLAUDE.md documentation 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- CLAUDE.md | 44 ++++++++++++++----- backend/app/models/focus_group.py | 2 +- backend/app/routes/ai_personas.py | 10 ++--- backend/app/routes/focus_group_ai.py | 4 +- backend/app/routes/personas.py | 4 +- backend/app/services/ai_persona_service.py | 8 ++-- .../autonomous_conversation_controller.py | 2 +- .../services/focus_group_response_service.py | 2 +- backend/app/services/focus_group_service.py | 4 +- backend/app/services/key_theme_service.py | 10 ++--- backend/app/services/llm_service.py | 6 +-- .../services/persona_modification_service.py | 2 +- src/components/AIRecruiter.tsx | 4 +- src/components/FocusGroupModerator.tsx | 10 ++--- .../ai-recruiter/AIRecruiterForm.tsx | 4 +- .../persona/PersonaModificationModal.tsx | 4 +- src/pages/FocusGroupSession.tsx | 18 ++++---- src/pages/SyntheticUsers.tsx | 8 ++-- src/utils/personaGenerator.ts | 2 +- 19 files changed, 85 insertions(+), 63 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 7c83d66d..40d1f8ef 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -15,7 +15,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co - **Start Backend**: `python run.py` (from backend/ directory) - **Backend Server**: Runs on port 5137 with Hypercorn ASGI server - **Database**: MongoDB with PyMongo -- **Authentication**: JWT tokens via Flask-JWT-Extended +- **Authentication**: Custom Quart-compatible JWT (not Flask-JWT-Extended) ## Testing **Python Backend**: After modifying any Python files: @@ -26,9 +26,30 @@ python -c "from app import create_app; app = create_app()" # Test app creation ``` **Frontend**: Run `npm run build` to verify TypeScript compilation +## Architecture Overview + +### Real-Time Communication +The application uses Socket.IO for real-time WebSocket communication between frontend and backend: +- **Backend**: `python-socketio` with `AsyncServer` wrapped in ASGI app +- **Frontend**: `socket.io-client` managed via `WebSocketContext` +- WebSocket manager (`websocket_manager_async.py`) handles room-based messaging for focus group sessions + +### Autonomous Conversation System +Focus group sessions can run autonomously with AI-driven conversations: +- `ai_runner_service.py` - Manages background task execution for autonomous mode +- `autonomous_conversation_controller.py` - Orchestrates multi-persona conversations +- `conversation_decision_service.py` - Determines next speaker and conversation flow +- `conversation_context_service.py` - Maintains conversation state and history + +### LLM Integration +Multi-model support through `llm_service.py`: +- **Google Gemini** (`gemini-3-pro-preview`) - Default model +- **OpenAI** (`gpt-4.1`, `gpt-5`) - Alternative models +- Prompts are stored as markdown templates in `/backend/prompts/` + ## Code Style Guidelines - **Imports**: Group imports by source (React, third-party, local) -- **Types**: Use TypeScript. Project allows nullable types (`strictNullChecks: false`) +- **Types**: Use TypeScript. Project allows nullable types (`strictNullChecks: false`) - **Components**: Use functional components with hooks - **Naming**: Use PascalCase for components, camelCase for variables/functions - **Formatting**: Follow ESLint recommendations, focus on readability @@ -41,12 +62,13 @@ python -c "from app import create_app; app = create_app()" # Test app creation ## Project Stack **Frontend**: Vite, React 18, TypeScript, Tailwind CSS, shadcn-ui -**Backend**: Flask 2.2.3, Hypercorn, PyMongo, JWT Extended -**Key Libraries**: +**Backend**: Quart (async Flask), Hypercorn ASGI, PyMongo, python-socketio +**Key Libraries**: - UI: Radix UI components, Lucide React icons - State: TanStack Query, React Hook Form with Zod validation - Routing: React Router DOM -- AI/LLM: OpenAI, Google Generative AI +- AI/LLM: OpenAI, Google Generative AI (genai) +- Real-time: Socket.IO (client and server) - Charts: Recharts - Drag & Drop: DND Kit @@ -58,15 +80,15 @@ python -c "from app import create_app; app = create_app()" # Test app creation ## File Organization - **Backend Services**: `/backend/app/services/` - Business logic and AI integrations -- **Backend Models**: `/backend/app/models/` - Data models (User, FocusGroup, Persona) -- **Backend Routes**: `/backend/app/routes/` - API endpoints -- **AI Prompts**: `/backend/prompts/` - LLM prompt templates -- **Frontend Components**: +- **Backend Models**: `/backend/app/models/` - Data models (User, FocusGroup, Persona, Folder) +- **Backend Routes**: `/backend/app/routes/` - API endpoints (auth, personas, focus-groups, ai-personas, folders, tasks) +- **AI Prompts**: `/backend/prompts/` - LLM prompt templates (markdown files loaded by `prompt_loader.py`) +- **Frontend Components**: - `/src/components/ui/` - Reusable shadcn-ui components - - `/src/components/focus-group-session/` - Focus group specific components + - `/src/components/focus-group-session/` - Focus group session UI (DiscussionPanel, ParticipantPanel, ThemesPanel, etc.) - `/src/components/persona/` - Persona management components - **Types**: `/src/types/` - TypeScript type definitions -- **Contexts**: `/src/contexts/` - React context providers +- **Contexts**: `/src/contexts/` - React context providers (AuthContext, WebSocketContext, NavigationContext) ## Environment Configuration diff --git a/backend/app/models/focus_group.py b/backend/app/models/focus_group.py index bc819754..4ffecdbc 100644 --- a/backend/app/models/focus_group.py +++ b/backend/app/models/focus_group.py @@ -82,7 +82,7 @@ class FocusGroup: # Set default LLM model if not provided if "llm_model" not in focus_group_data: - focus_group_data["llm_model"] = "gemini-2.5-pro" + focus_group_data["llm_model"] = "gemini-3-pro-preview" # Set default GPT-5 parameters if not provided if "reasoning_effort" not in focus_group_data: diff --git a/backend/app/routes/ai_personas.py b/backend/app/routes/ai_personas.py index 79d5aba1..3f1af550 100644 --- a/backend/app/routes/ai_personas.py +++ b/backend/app/routes/ai_personas.py @@ -67,7 +67,7 @@ async def generate_basic_profiles(): temperature = 1.0 customer_data_session_id = data.get('customer_data_session_id') # Optional parameter - llm_model = data.get('llm_model', 'gemini-2.5-pro') # Optional parameter with default + llm_model = data.get('llm_model', 'gemini-3-pro-preview') # Optional parameter with default try: # Register current task for cancellation @@ -197,7 +197,7 @@ async def complete_and_save_persona(): temperature = 1.0 customer_data_session_id = data.get('customer_data_session_id') # Optional parameter - llm_model = data.get('llm_model', 'gemini-2.5-pro') # Optional parameter with default + llm_model = data.get('llm_model', 'gemini-3-pro-preview') # Optional parameter with default # Get persona name for logging persona_name = basic_profile.get('name', 'Unknown') @@ -816,7 +816,7 @@ async def batch_generate_summaries(): if not (0 <= temperature <= 1.5): temperature = 1.0 - llm_model = data.get('llm_model', 'gemini-2.5-pro') # Optional parameter with default + llm_model = data.get('llm_model', 'gemini-3-pro-preview') # Optional parameter with default # Log the request with model information print(f"🔄 Backend: Received batch-generate-summaries request for {len(persona_ids)} personas with model: {llm_model}") @@ -1013,7 +1013,7 @@ async def generate_personas_full(): "count": 5, "temperature": 0.8, "customer_data_session_id": "optional_session_id", - "llm_model": "gemini-2.5-pro", + "llm_model": "gemini-3-pro-preview", "target_folder_id": "optional_folder_id" } @@ -1038,7 +1038,7 @@ async def generate_personas_full(): temperature = 1.0 customer_data_session_id = data.get('customer_data_session_id') - llm_model = data.get('llm_model', 'gemini-2.5-pro') + llm_model = data.get('llm_model', 'gemini-3-pro-preview') target_folder_id = data.get('target_folder_id') try: diff --git a/backend/app/routes/focus_group_ai.py b/backend/app/routes/focus_group_ai.py index 3c2df9df..7788f01a 100644 --- a/backend/app/routes/focus_group_ai.py +++ b/backend/app/routes/focus_group_ai.py @@ -84,7 +84,7 @@ async def generate_ai_response(): import datetime log_msg = f"🤖 [{datetime.datetime.now()}] AI RESPONSE - Focus group keys: {list(focus_group.keys())}\n" log_msg += f"🤖 [{datetime.datetime.now()}] AI RESPONSE - Raw llm_model from DB: '{focus_group.get('llm_model')}' (type: {type(focus_group.get('llm_model'))})\n" - log_msg += f"🤖 [{datetime.datetime.now()}] AI RESPONSE - Using model: {llm_model or 'default (gemini-2.5-pro)'} for focus group {focus_group_id}\n" + log_msg += f"🤖 [{datetime.datetime.now()}] AI RESPONSE - Using model: {llm_model or 'default (gemini-3-pro-preview)'} for focus group {focus_group_id}\n" with open('/tmp/focus_group_debug.log', 'a') as f: f.write(log_msg) f.flush() @@ -93,7 +93,7 @@ async def generate_ai_response(): current_app.logger.info(f"🔍 DEBUG: Focus group data keys: {list(focus_group.keys())}") current_app.logger.info(f"🔍 DEBUG: Raw llm_model value from DB: '{focus_group.get('llm_model')}' (type: {type(focus_group.get('llm_model'))})") - current_app.logger.info(f"🤖 Generating AI response using model: {llm_model or 'default (gemini-2.5-pro)'} for focus group {focus_group_id}") + current_app.logger.info(f"🤖 Generating AI response using model: {llm_model or 'default (gemini-3-pro-preview)'} for focus group {focus_group_id}") # Validate persona exists persona = await Persona.find_by_id(persona_id) diff --git a/backend/app/routes/personas.py b/backend/app/routes/personas.py index c30fbd7e..c5acd216 100644 --- a/backend/app/routes/personas.py +++ b/backend/app/routes/personas.py @@ -173,7 +173,7 @@ async def modify_persona_with_ai(persona_id): Request body should include: - modification_prompt: Natural language description of desired changes - - llm_model: Model to use (defaults to 'gemini-2.5-pro') + - llm_model: Model to use (defaults to 'gemini-3-pro-preview') - reasoning_effort: For GPT-5 (minimal, low, medium, high) - verbosity: For GPT-5 (low, medium, high) - preview_only: If true, returns modified data without saving to database (defaults to false) @@ -188,7 +188,7 @@ async def modify_persona_with_ai(persona_id): if not modification_prompt: return jsonify({"error": "modification_prompt is required"}), 400 - llm_model = request_data.get('llm_model', 'gemini-2.5-pro') + llm_model = request_data.get('llm_model', 'gemini-3-pro-preview') reasoning_effort = request_data.get('reasoning_effort', 'medium') verbosity = request_data.get('verbosity', 'medium') preview_only = request_data.get('preview_only', False) diff --git a/backend/app/services/ai_persona_service.py b/backend/app/services/ai_persona_service.py index eee84842..62e0dc43 100644 --- a/backend/app/services/ai_persona_service.py +++ b/backend/app/services/ai_persona_service.py @@ -218,7 +218,7 @@ async def _generate_basic_personas_attempt( # Log the LLM API call with attempt number attempt_text = f" (attempt {attempt})" if attempt > 1 else "" - print(f"🤖 Backend: Making LLM API call to {llm_model or 'gemini-2.5-pro'} for basic persona generation{attempt_text}") + print(f"🤖 Backend: Making LLM API call to {llm_model or 'gemini-3-pro-preview'} for basic persona generation{attempt_text}") raw_response = await LLMService.generate_content( prompt=final_prompt, @@ -504,7 +504,7 @@ async def generate_persona( # Log the LLM API call persona_name = basic_persona.get('name', 'Unknown') if basic_persona else 'New Persona' - print(f"🤖 Backend: Making LLM API call to {llm_model or 'gemini-2.5-pro'} for detailed persona generation of '{persona_name}'") + print(f"🤖 Backend: Making LLM API call to {llm_model or 'gemini-3-pro-preview'} for detailed persona generation of '{persona_name}'") persona_data = await LLMService.generate_structured_response( prompt=final_prompt, @@ -589,7 +589,7 @@ async def generate_persona_summary( # Log the LLM API call persona_name = persona_data.get('name', 'Unknown') - print(f"🤖 Backend: Making LLM API call to {llm_model or 'gemini-2.5-pro'} for summary generation of '{persona_name}'") + print(f"🤖 Backend: Making LLM API call to {llm_model or 'gemini-3-pro-preview'} for summary generation of '{persona_name}'") raw_response = await LLMService.generate_content( prompt=final_prompt, @@ -694,7 +694,7 @@ async def generate_persona_download_summary( # Log the LLM API call persona_name = persona_data.get('name', 'Unknown') - print(f"🤖 Backend: Making LLM API call to {llm_model or 'gemini-2.5-pro'} for download summary of '{persona_name}'") + print(f"🤖 Backend: Making LLM API call to {llm_model or 'gemini-3-pro-preview'} for download summary of '{persona_name}'") # Generate the markdown content directly markdown_response = await LLMService.generate_content( diff --git a/backend/app/services/autonomous_conversation_controller.py b/backend/app/services/autonomous_conversation_controller.py index 5dbbd967..c0547f88 100644 --- a/backend/app/services/autonomous_conversation_controller.py +++ b/backend/app/services/autonomous_conversation_controller.py @@ -664,7 +664,7 @@ class AutonomousConversationController: llm_model = focus_group.get('llm_model') reasoning_effort = focus_group.get('reasoning_effort', 'medium') verbosity = focus_group.get('verbosity', 'medium') - self.logger.info(f"🤖 Autonomous conversation using model: {llm_model or 'default (gemini-2.5-pro)'} for focus group {self.focus_group_id}") + self.logger.info(f"🤖 Autonomous conversation using model: {llm_model or 'default (gemini-3-pro-preview)'} for focus group {self.focus_group_id}") # Get recent messages messages = await FocusGroup.get_messages(self.focus_group_id) diff --git a/backend/app/services/focus_group_response_service.py b/backend/app/services/focus_group_response_service.py index 858f52c7..67da7b3d 100644 --- a/backend/app/services/focus_group_response_service.py +++ b/backend/app/services/focus_group_response_service.py @@ -52,7 +52,7 @@ async def generate_persona_response( if llm_model == 'gpt-5': print(f" - llm_model: {llm_model} (reasoning_effort: {reasoning_effort or 'medium'}, verbosity: {verbosity or 'medium'}) [using Responses API]") else: - print(f" - llm_model: {llm_model or 'default (gemini-2.5-pro)'}") + print(f" - llm_model: {llm_model or 'default (gemini-3-pro-preview)'}") # Import LLMService at the top to avoid scoping issues from app.services.llm_service import LLMService diff --git a/backend/app/services/focus_group_service.py b/backend/app/services/focus_group_service.py index d3ba0f2e..7060d76f 100644 --- a/backend/app/services/focus_group_service.py +++ b/backend/app/services/focus_group_service.py @@ -224,7 +224,7 @@ class FocusGroupService: 'content': question.get('content', 'No content')[:100] + '...' }) - logger.info(f"=== CREATIVE REVIEW VALIDATION RESULTS (Model: {llm_model or 'gemini-2.5-pro'}) ===") + logger.info(f"=== CREATIVE REVIEW VALIDATION RESULTS (Model: {llm_model or 'gemini-3-pro-preview'}) ===") logger.info(f"Found {creative_review_count} creative_review activities for {len(uploaded_assets)} uploaded assets") if creative_review_activities: @@ -236,7 +236,7 @@ class FocusGroupService: # If no creative review activities were generated, retry with enhanced prompt if creative_review_count == 0: logger.warning(f"❌ WARNING: No creative_review activities generated despite {len(uploaded_assets)} uploaded assets!") - logger.warning(f"❌ This suggests {llm_model or 'gemini-2.5-pro'} is not following the creative asset instructions") + logger.warning(f"❌ This suggests {llm_model or 'gemini-3-pro-preview'} is not following the creative asset instructions") # For GPT models, if this was already the enhanced prompt, we have a serious issue if llm_model and llm_model.startswith('gpt') and attempt < max_retries: diff --git a/backend/app/services/key_theme_service.py b/backend/app/services/key_theme_service.py index 2ffc3683..9eaa8370 100644 --- a/backend/app/services/key_theme_service.py +++ b/backend/app/services/key_theme_service.py @@ -41,7 +41,7 @@ class KeyThemeService: """ logger = logging.getLogger(__name__) logger.info(f"Starting key theme generation for focus group {focus_group_id} with temperature {temperature}") - logger.info(f"Using LLM model: {llm_model or 'default (gemini-2.5-pro)'}") + logger.info(f"Using LLM model: {llm_model or 'default (gemini-3-pro-preview)'}") try: # Get the focus group @@ -105,7 +105,7 @@ class KeyThemeService: """ logger = logging.getLogger(__name__) logger.info(f"Beginning theme extraction from {len(messages)} messages") - logger.info(f"Theme extraction using LLM model: {llm_model or 'default (gemini-2.5-pro)'}") + logger.info(f"Theme extraction using LLM model: {llm_model or 'default (gemini-3-pro-preview)'}") try: # Load and prepare the prompt for the LLM @@ -135,7 +135,7 @@ class KeyThemeService: for attempt in range(max_retries): attempt_num = attempt + 1 - logger.info(f"Attempt {attempt_num}/{max_retries}: Calling LLM ({llm_model or 'gemini-2.5-pro'}) for theme generation") + logger.info(f"Attempt {attempt_num}/{max_retries}: Calling LLM ({llm_model or 'gemini-3-pro-preview'}) for theme generation") try: themes = await LLMService.generate_structured_array( @@ -145,7 +145,7 @@ class KeyThemeService: model_name=llm_model ) - logger.info(f"Attempt {attempt_num}/{max_retries}: LLM ({llm_model or 'gemini-2.5-pro'}) call successful, received {len(themes)} themes") + logger.info(f"Attempt {attempt_num}/{max_retries}: LLM ({llm_model or 'gemini-3-pro-preview'}) call successful, received {len(themes)} themes") # Validate the response structure validated_themes = [] @@ -175,7 +175,7 @@ class KeyThemeService: validated_themes.append(validated_theme) - logger.info(f"Theme generation completed successfully with {len(validated_themes)} validated themes using {llm_model or 'gemini-2.5-pro'}") + logger.info(f"Theme generation completed successfully with {len(validated_themes)} validated themes using {llm_model or 'gemini-3-pro-preview'}") return validated_themes except LLMServiceError as e: diff --git a/backend/app/services/llm_service.py b/backend/app/services/llm_service.py index 8acba2cb..3f676899 100644 --- a/backend/app/services/llm_service.py +++ b/backend/app/services/llm_service.py @@ -25,12 +25,12 @@ gemini_client = genai.Client(api_key=GEMINI_API_KEY) OPENAI_API_KEY = os.environ.get('OPENAI_API_KEY', 'REDACTED_OPENAI_KEY') openai_client = AsyncOpenAI(api_key=OPENAI_API_KEY, timeout=600.0) -# The default model we're using -DEFAULT_MODEL = "gemini-2.5-pro" +# The default model we're using +DEFAULT_MODEL = "gemini-3-pro-preview" # Supported models SUPPORTED_MODELS = { - 'gemini-2.5-pro': 'gemini', + 'gemini-3-pro-preview': 'gemini', 'gpt-4.1': 'openai', 'gpt-5': 'openai' } diff --git a/backend/app/services/persona_modification_service.py b/backend/app/services/persona_modification_service.py index bad46854..487681c7 100644 --- a/backend/app/services/persona_modification_service.py +++ b/backend/app/services/persona_modification_service.py @@ -134,7 +134,7 @@ class PersonaModificationService: async def modify_persona( persona_id: str, modification_prompt: str, - llm_model: str = 'gemini-2.5-pro', + llm_model: str = 'gemini-3-pro-preview', reasoning_effort: str = 'medium', verbosity: str = 'medium', max_retries: int = 3, diff --git a/src/components/AIRecruiter.tsx b/src/components/AIRecruiter.tsx index 0a8028a7..edf636fa 100644 --- a/src/components/AIRecruiter.tsx +++ b/src/components/AIRecruiter.tsx @@ -159,7 +159,7 @@ export default function AIRecruiter({ targetFolderId, targetFolderName }: AIRecr if (response.partial_success || (response.errors && response.errors.length > 0)) { // Some personas succeeded but others failed toast.success("Some personas generated successfully", { - description: `${personas.length} synthetic personas were created using ${values.llm_model || 'Gemini 2.5 Pro'}. ${response.errors?.length || 0} failed due to timeout or other errors.`, + description: `${personas.length} synthetic personas were created using ${values.llm_model || 'Gemini 3 Pro'}. ${response.errors?.length || 0} failed due to timeout or other errors.`, duration: 8000 }); @@ -175,7 +175,7 @@ export default function AIRecruiter({ targetFolderId, targetFolderName }: AIRecr } else { // All personas succeeded toast.success("Personas generated and saved successfully", { - description: `${personas.length} synthetic personas have been created using ${values.llm_model || 'Gemini 2.5 Pro'} and saved ${targetFolderId ? `to the "${targetFolderName}" folder` : 'to the database'}.` + description: `${personas.length} synthetic personas have been created using ${values.llm_model || 'Gemini 3 Pro'} and saved ${targetFolderId ? `to the "${targetFolderName}" folder` : 'to the database'}.` }); } diff --git a/src/components/FocusGroupModerator.tsx b/src/components/FocusGroupModerator.tsx index 16c85b98..964d8c9f 100644 --- a/src/components/FocusGroupModerator.tsx +++ b/src/components/FocusGroupModerator.tsx @@ -527,7 +527,7 @@ export default function FocusGroupModerator({ draftToEdit, onDraftSaved, preSele focusGroupName: "", discussionTopics: "", duration: "60", - llm_model: "gemini-2.5-pro", + llm_model: "gemini-3-pro-preview", reasoning_effort: "medium", verbosity: "medium", }, @@ -554,7 +554,7 @@ export default function FocusGroupModerator({ draftToEdit, onDraftSaved, preSele objective: values.researchBrief || '', topic: values.discussionTopics || '', duration: values.duration ? parseInt(values.duration) : 60, - llm_model: values.llm_model || 'gemini-2.5-pro', + llm_model: values.llm_model || 'gemini-3-pro-preview', reasoning_effort: values.reasoning_effort || 'medium', verbosity: values.verbosity || 'medium', participants: selectedParticipants, @@ -692,7 +692,7 @@ export default function FocusGroupModerator({ draftToEdit, onDraftSaved, preSele topic: values.discussionTopics || '', description: values.researchBrief || '', objective: values.researchBrief || '', - llm_model: values.llm_model || 'gemini-2.5-pro', + llm_model: values.llm_model || 'gemini-3-pro-preview', reasoning_effort: values.reasoning_effort || 'medium', verbosity: values.verbosity || 'medium', discussionGuide: sourceFocusGroup.discussionGuide @@ -860,7 +860,7 @@ export default function FocusGroupModerator({ draftToEdit, onDraftSaved, preSele objective: draftToEdit.description || draftToEdit.objective || '', topic: draftToEdit.topic || '', duration: draftToEdit.duration || 60, - llm_model: draftToEdit.llm_model || 'gemini-2.5-pro', + llm_model: draftToEdit.llm_model || 'gemini-3-pro-preview', reasoning_effort: draftToEdit.reasoning_effort || 'medium', verbosity: draftToEdit.verbosity || 'medium', participants: draftToEdit.participants || [], @@ -1580,7 +1580,7 @@ true; - Gemini 2.5 Pro + Gemini 3 Pro GPT-4.1 GPT-5 diff --git a/src/components/ai-recruiter/AIRecruiterForm.tsx b/src/components/ai-recruiter/AIRecruiterForm.tsx index d533b73b..b2e473e7 100644 --- a/src/components/ai-recruiter/AIRecruiterForm.tsx +++ b/src/components/ai-recruiter/AIRecruiterForm.tsx @@ -70,7 +70,7 @@ export default function AIRecruiterForm({ onSubmit, isGenerating }: AIRecruiterF researchObjective: "", personaCount: "5", temperature: 1.0, - llm_model: "gemini-2.5-pro", + llm_model: "gemini-3-pro-preview", }, }); @@ -380,7 +380,7 @@ export default function AIRecruiterForm({ onSubmit, isGenerating }: AIRecruiterF - Gemini 2.5 Pro + Gemini 3 Pro GPT-4.1 GPT-5 diff --git a/src/components/persona/PersonaModificationModal.tsx b/src/components/persona/PersonaModificationModal.tsx index 96899c40..bff11558 100644 --- a/src/components/persona/PersonaModificationModal.tsx +++ b/src/components/persona/PersonaModificationModal.tsx @@ -70,7 +70,7 @@ export default function PersonaModificationModal({ resolver: zodResolver(modificationFormSchema), defaultValues: { modificationPrompt: "", - llm_model: "gemini-2.5-pro", + llm_model: "gemini-3-pro-preview", reasoning_effort: "medium", verbosity: "medium", }, @@ -221,7 +221,7 @@ export default function PersonaModificationModal({ - Gemini 2.5 Pro + Gemini 3 Pro GPT-4.1 GPT-5 diff --git a/src/pages/FocusGroupSession.tsx b/src/pages/FocusGroupSession.tsx index de95149f..0e3e454c 100644 --- a/src/pages/FocusGroupSession.tsx +++ b/src/pages/FocusGroupSession.tsx @@ -730,11 +730,11 @@ const FocusGroupSession = () => { duration: data.duration || 60, topic: data.topic || 'general', discussionGuide: data.discussionGuide || '', - llm_model: data.llm_model || 'gemini-2.5-pro' + llm_model: data.llm_model || 'gemini-3-pro-preview' }; setFocusGroup(focusGroupData); - setSelectedModel(focusGroupData.llm_model || 'gemini-2.5-pro'); + setSelectedModel(focusGroupData.llm_model || 'gemini-3-pro-preview'); setSelectedReasoningEffort(focusGroupData.reasoning_effort || 'medium'); setSelectedVerbosity(focusGroupData.verbosity || 'medium'); @@ -816,7 +816,7 @@ const FocusGroupSession = () => { } : null); toastService.success('AI Model Updated', { description: `Focus group will now use ${ - newModel === 'gemini-2.5-pro' ? 'Gemini 2.5 Pro' : + newModel === 'gemini-3-pro-preview' ? 'Gemini 3 Pro' : newModel === 'gpt-4.1' ? 'GPT-4.1' : newModel === 'gpt-5' ? 'GPT-5' : newModel } for AI responses` @@ -869,11 +869,11 @@ const FocusGroupSession = () => { duration: data.duration || 60, topic: data.topic || 'general', discussionGuide: data.discussionGuide || '', - llm_model: data.llm_model || 'gemini-2.5-pro' + llm_model: data.llm_model || 'gemini-3-pro-preview' }; setFocusGroup(focusGroupData); - setSelectedModel(focusGroupData.llm_model || 'gemini-2.5-pro'); + setSelectedModel(focusGroupData.llm_model || 'gemini-3-pro-preview'); setSelectedReasoningEffort(focusGroupData.reasoning_effort || 'medium'); setSelectedVerbosity(focusGroupData.verbosity || 'medium'); @@ -1932,7 +1932,7 @@ const FocusGroupSession = () => { {focusGroup.llm_model === 'gpt-4.1' ? 'GPT-4.1' : - focusGroup.llm_model === 'gpt-5' ? 'GPT-5' : 'Gemini 2.5 Pro'} + focusGroup.llm_model === 'gpt-5' ? 'GPT-5' : 'Gemini 3 Pro'} @@ -2294,7 +2294,7 @@ const FocusGroupSession = () => { Current Model: {focusGroup?.llm_model === 'gpt-4.1' ? 'GPT-4.1' : - focusGroup?.llm_model === 'gpt-5' ? 'GPT-5' : 'Gemini 2.5 Pro'} + focusGroup?.llm_model === 'gpt-5' ? 'GPT-5' : 'Gemini 3 Pro'} @@ -2308,7 +2308,7 @@ const FocusGroupSession = () => { - Gemini 2.5 Pro + Gemini 3 Pro GPT-4.1 GPT-5 @@ -2364,7 +2364,7 @@ Controls how thoroughly GPT-5 thinks and how detailed responses are )}
-

Gemini 2.5 Pro: Google's advanced model, great for creative and analytical tasks.

+

Gemini 3 Pro: Google's advanced model, great for creative and analytical tasks.

GPT-4.1: OpenAI's latest model, excellent for conversational and reasoning tasks.

GPT-5: OpenAI's newest model with advanced reasoning and customizable response styles.

diff --git a/src/pages/SyntheticUsers.tsx b/src/pages/SyntheticUsers.tsx index b2001e74..4ef9327a 100644 --- a/src/pages/SyntheticUsers.tsx +++ b/src/pages/SyntheticUsers.tsx @@ -142,7 +142,7 @@ const SyntheticUsers = () => { }); // LLM selection for download const [downloadLlmModalOpen, setDownloadLlmModalOpen] = useState(false); - const [selectedDownloadLlmModel, setSelectedDownloadLlmModel] = useState('gemini-2.5-pro'); + const [selectedDownloadLlmModel, setSelectedDownloadLlmModel] = useState('gemini-3-pro-preview'); // Bulk export no longer needs state - direct download @@ -1057,7 +1057,7 @@ const SyntheticUsers = () => { summaryGenerationControls.completeGeneration(); // Show success toast with details including model information - const modelDisplayName = selectedDownloadLlmModel === 'gpt-4.1' ? 'GPT-4.1' : 'Gemini 2.5 Pro'; + const modelDisplayName = selectedDownloadLlmModel === 'gpt-4.1' ? 'GPT-4.1' : 'Gemini 3 Pro'; if (summary_stats.total_successful === summary_stats.total_requested) { toastService.success("Persona summary downloaded", { description: `Successfully processed all ${summary_stats.total_successful} persona${summary_stats.total_successful !== 1 ? 's' : ''} from "${folderName}" using ${modelDisplayName}` @@ -1929,9 +1929,9 @@ const SyntheticUsers = () => { className="space-y-3" >
- +
diff --git a/src/utils/personaGenerator.ts b/src/utils/personaGenerator.ts index c6564cee..0a86c3fe 100644 --- a/src/utils/personaGenerator.ts +++ b/src/utils/personaGenerator.ts @@ -27,7 +27,7 @@ export async function generateSyntheticPersonas( ): Promise<{personas: Persona[], task_id?: string, partial_success?: boolean, errors?: any[]}> { // Debug logging for folder and model console.log(`generateSyntheticPersonas called with targetFolderId: ${targetFolderId || 'none'}`); - console.log(`🔄 generateSyntheticPersonas using model: ${llmModel || 'gemini-2.5-pro'}`); + console.log(`🔄 generateSyntheticPersonas using model: ${llmModel || 'gemini-3-pro-preview'}`); try { // We'll use the two-stage approach