street-lingo/backend/core/base_models.py

127 lines
4.2 KiB
Python

from pydantic import BaseModel
from typing import List, Optional, Dict
from enum import Enum
class HelpfulPhrase(BaseModel):
native: str
english: str
class CharacterType(str, Enum):
VENDOR = "vendor"
DRIVER = "driver"
CASHIER = "cashier"
OFFICIAL = "official"
NEIGHBOR = "neighbor"
SERVICE_WORKER = "service_worker"
GENERIC = "generic"
class PersonalityTone(str, Enum):
FRIENDLY = "friendly"
CASUAL = "casual"
FORMAL = "formal"
CHEERFUL = "cheerful"
BUSINESS_LIKE = "business_like"
SLEEPY = "sleepy"
CHATTY = "chatty"
GRUFF = "gruff"
HELPFUL = "helpful"
class Gender(str, Enum):
MALE = "male"
FEMALE = "female"
NEUTRAL = "neutral"
class GoalItem(BaseModel):
id: str
description: str
keywords: List[str] = []
completed: bool = False
class BasePersonality(BaseModel):
character_type: CharacterType
name: str
gender: Gender
tone: PersonalityTone
age_range: str
background: str
typical_phrases: List[str]
response_style: str
location_context: str
scenario_title: str
scenario_description: str
scenario_challenge: str
scenario_goal: str
goal_items: List[GoalItem]
helpful_phrases: List[HelpfulPhrase]
is_impatient: bool = False
is_helpful: bool = True
is_talkative: bool = True
uses_slang: bool = False
# Language-specific settings
language_code: str
country_code: str
def get_system_prompt(self, scenario_context: str = "", language_specific_instructions: str = "") -> str:
"""Generate a system prompt based on this personality."""
casualness_note = f"""
SPEAKING STYLE - BE VERY CASUAL AND NATURAL:
- Use everyday {self.language_code.upper()} like real people do
- Drop formal words when people actually don't use them
- Use contractions and casual speech patterns
- Speak like you're talking to a friend or regular customer
- Don't be overly polite or formal - be natural and relaxed
- Sound like real street conversation
{language_specific_instructions}
"""
interaction_guide = self._get_interaction_guide()
base_prompt = f"""You are {self.name}, a real {self.character_type.value.replace('_', ' ')} in {self.country_code}. You talk like a normal person - casual, natural, and relaxed.
SCENARIO CONTEXT:
📍 {self.scenario_title}
🎯 What's happening: {self.scenario_description}
⚡ Challenge: {self.scenario_challenge}
🏆 Goal: {self.scenario_goal}
{casualness_note}
CHARACTER:
- {self.name} ({self.age_range} {self.character_type.value.replace('_', ' ')})
- {self.background}
- Works at: {self.location_context}
- Personality: {self.tone.value}, {'talkative' if self.is_talkative else 'quiet'}, {'helpful' if self.is_helpful else 'business-focused'}
YOUR TYPICAL PHRASES (use these naturally):
{chr(10).join(f'- {phrase}' for phrase in self.typical_phrases)}
CRITICAL RULES - READ CONVERSATION HISTORY CAREFULLY:
1. You are {self.name} - NOT a teacher, NOT formal, just a real person in this scenario
2. Speak casual {self.language_code.upper()} like in real life - very relaxed and natural
3. Keep responses SHORT (5-10 words max, like real conversation)
4. READ THE CONVERSATION HISTORY ABOVE - remember what was already asked and answered
5. NEVER repeat questions you already asked - check what was said before
6. TRACK the interaction progress - move naturally through the process based on what's been discussed
7. Stay relevant to your role and what customers need from you in this scenario
8. If customer already answered a question, move to the NEXT step in the process
9. Help the customer achieve their goal: {self.scenario_goal}
{interaction_guide}
ADDITIONAL CONTEXT: {scenario_context}
IMPORTANT: Look at the conversation history above before responding! Don't ask questions that were already answered. Continue naturally from where the conversation left off! Help them complete their goal in this scenario."""
return base_prompt
def _get_interaction_guide(self) -> str:
"""Override in language-specific implementations"""
return """
INTERACTION FLOW:
- Respond naturally to customer needs
- Help them with whatever service you provide
- Keep conversation relevant to your role
"""