from pydantic import BaseModel, Field from typing import List,Literal, Optional # Pydantic Models class CreditCardRecommendation(BaseModel): """ Structured response for credit card recommendations. Handles both successful recommendations and cases where no suitable card is found. """ card_found: bool = Field( description="A boolean flag that MUST be `True` if a card is recommended, and `False` otherwise." ) best_card: Optional[str] = Field( default=None, description="The name of the best credit card recommended. This MUST be null if card_found is false." ) explanation: Optional[List[str]] = Field( default=None, description=("A numbered list explaining why the card is best: " "1. Main benefit aligned to user query. " "2-3. Additional perks. " "4. Final justification tying everything to the query." ) ) reply_if_card_not_found: Optional[str] = Field( default=None, description=( "A user-facing message generated by rephrasing the AI agent's internal monologue when no exact card is found. " "This reply should politely explain and justify that no perfect match was found and present the alternative cards or information, if available, as helpful suggestions to explore. " "This field MUST be populated if and only if card_found is false." ) ) class IntentClassification(BaseModel): """ Classifies the user query into 'credit-card-recommendation', 'general-credit-related', or 'out-of-scope'. """ intent: Literal["credit-card-recommendation", "general-credit-related", "out-of-scope"] = Field( description=( "The classification of the user's query. " "'credit-card-recommendation' for seeking card suggestions. " "'general-credit-related' for informational questions about credit cards. " "'out-of-scope' for all other cases." ) ) #for Chain of Thoughts(CoT) prompting class RouterResult(BaseModel): """The structured output from the router agent.""" decision: Literal["call_tool", "answer_from_context"] card_names_to_fetch: Optional[List[str]] = None