File size: 4,915 Bytes
75fbdf4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# models.py
from pydantic import BaseModel, Field
from typing import List, Optional
from enum import Enum


class ExtractRequest(BaseModel):
    """Request model for department extraction"""
    query: str = Field(..., min_length=1, description="User query text")


class ExtractedInfo(BaseModel):
    """Response model for division extraction using embeddings"""
    division: str = Field(..., description="Division name")
    department: Optional[str] = Field(default=None, description="Parent department name")
    confidence: float = Field(default=0.0, ge=0.0, le=1.0, description="Confidence score (0-1)")

    class Config:
        populate_by_name = True


class RoutingAction(str, Enum):
    """Actions based on confidence level"""
    DIRECT = "direct"           # High confidence - route directly
    SUGGEST = "suggest"         # Medium confidence - suggest with alternatives
    CLARIFY = "clarify"         # Low confidence - ask for clarification
    ESCALATE = "escalate"       # Very low - escalate to operator


class ExtractedInfoList(BaseModel):
    """Enhanced response model with confidence-based routing and name extraction"""
    matches: List[ExtractedInfo] = Field(..., description="List of possible matches ordered by confidence")
    action: RoutingAction = Field(default=RoutingAction.DIRECT, description="Recommended routing action")
    message: str = Field(default="", description="User-facing message based on confidence")
    show_alternatives: bool = Field(default=False, description="Whether to show alternative divisions")
    confidence_level: str = Field(default="high", description="Confidence level: high, medium, low, very_low")
    names: List[str] = Field(default_factory=list, description="Extracted person names from the query")
    has_names: bool = Field(default=False, description="Whether any names were found in the query")


class VoiceQueryInfo(BaseModel):
    """Information about the voice query processing"""
    query: str = Field(..., description="Processed text query (in English)")
    original_text: str = Field(..., description="Original transcribed text")
    language: str = Field(..., description="Detected language code (e.g., 'en', 'ar')")
    language_name: str = Field(..., description="Full language name (e.g., 'English', 'Arabic')")
    was_translated: bool = Field(..., description="Whether the text was translated to English")
    audio_duration: float = Field(..., description="Audio duration in seconds")


class VoiceExtractResponse(BaseModel):
    """Response model for voice query extraction"""
    voice_info: VoiceQueryInfo = Field(..., description="Voice processing information")
    extraction_result: ExtractedInfoList = Field(..., description="Division and name extraction results")


# Contact Search Models
class ContactInfo(BaseModel):
    """Individual contact information"""
    id: int = Field(..., description="Contact ID")
    first_name_ar: str = Field(..., description="First name in Arabic")
    last_name_ar: str = Field(..., description="Last name in Arabic")
    full_name_ar: str = Field(..., description="Full name in Arabic")
    first_name_en: str = Field(..., description="First name in English")
    last_name_en: str = Field(..., description="Last name in English")
    full_name_en: str = Field(..., description="Full name in English")
    title_en: str = Field(..., description="Job title in English")
    title_ar: str = Field(..., description="Job title in Arabic")
    division: str = Field(..., description="Division name")
    department: str = Field(..., description="Department name")
    department_id: str = Field(..., description="Department ID")
    email: str = Field(..., description="Email address")
    extension: str = Field(..., description="Phone extension")
    phone: str = Field(..., description="Full phone number")
    confidence: float = Field(..., ge=0.0, le=1.0, description="Match confidence score (0-1)")
    match_reason: str = Field(..., description="Reason for match (exact_name_match, fuzzy_name_match, division_match, name_and_division_match)")


class ContactSearchResponse(BaseModel):
    """Response model for contact search"""
    query: str = Field(..., description="Original search query")
    total_matches: int = Field(..., description="Total number of matches found")
    contacts: List[ContactInfo] = Field(..., description="List of matched contacts sorted by confidence")
    extracted_names: List[str] = Field(default_factory=list, description="Names extracted from query")
    matched_divisions: List[str] = Field(default_factory=list, description="Divisions matched from query")


class VoiceContactSearchResponse(BaseModel):
    """Response model for voice-based contact search"""
    voice_info: VoiceQueryInfo = Field(..., description="Voice processing information")
    search_result: ContactSearchResponse = Field(..., description="Contact search results")