LibBee / src /agentcore /models.py
nikeshn's picture
Upload 13 files
c597e9f verified
Raw History Blame Contribute Delete
3.6 kB
"""Strict request and response contracts for the LibBee agent."""
import time
from typing import Literal, Optional
from pydantic import BaseModel, ConfigDict, Field, field_validator
class ChatMessage(BaseModel):
model_config = ConfigDict(extra="forbid")
role: Literal["user", "assistant"]
content: str = Field(min_length=1, max_length=4000)
class SearchContextPayload(BaseModel):
model_config = ConfigDict(extra="ignore")
context_id: str = Field(min_length=1, max_length=80)
topic: str = Field(min_length=1, max_length=500)
display_topic: Optional[str] = Field(default=None, max_length=500)
intent: Literal["search_academic", "search_medical"] = "search_academic"
source: Literal["primo", "pubmed"] = "primo"
resource_type: Literal["articles", "books", "both"] = "articles"
query_field: Literal["any", "title", "creator", "sub"] = "any"
sort: Literal["rank", "date_d", "date_a"] = "rank"
peer_reviewed: bool = False
open_access: bool = False
year_from: Optional[str] = Field(default=None, pattern=r"^\d{4}$")
year_to: Optional[str] = Field(default=None, pattern=r"^\d{4}$")
ai_tool_query: Optional[str] = Field(default=None, max_length=1000)
primo_boolean_query: Optional[str] = Field(default=None, max_length=1500)
created_at: float = Field(default_factory=time.time)
clarification_needed: bool = False
clarification_message: Optional[str] = Field(default=None, max_length=500)
@field_validator("year_to")
@classmethod
def years_in_order(cls, value: Optional[str], info):
start = info.data.get("year_from")
if value and start and int(value) < int(start):
raise ValueError("year_to must not be earlier than year_from")
return value
class ClientStatePayload(BaseModel):
model_config = ConfigDict(extra="ignore")
session_id: Optional[str] = Field(default=None, pattern=r"^[A-Za-z0-9_-]{8,80}$")
active_search_context_id: Optional[str] = Field(default=None, max_length=80)
recent_search_contexts: list[SearchContextPayload] = Field(default_factory=list, max_length=5)
follow_up_action: Optional[str] = Field(default=None, max_length=80)
follow_up_context_id: Optional[str] = Field(default=None, max_length=80)
class AgentRequest(BaseModel):
model_config = ConfigDict(extra="forbid")
question: str = Field(min_length=1, max_length=2000)
model: Literal["gpt", "claude"] = "gpt"
history: list[ChatMessage] = Field(default_factory=list, max_length=12)
client_state: Optional[ClientStatePayload] = None
class AgentResponse(BaseModel):
model_config = ConfigDict(extra="ignore")
request_id: str = ""
answer: str
intent: str = "general"
tools_used: list[str] = Field(default_factory=list)
search_results: list[dict] = Field(default_factory=list)
sources: list[dict] = Field(default_factory=list)
model_used: str = "gpt"
response_time: float = 0
corrected_query: Optional[str] = None
natural_query: Optional[str] = None
database_query: Optional[str] = None
ask_librarian: Optional[bool] = None
is_follow_up: bool = False
follow_up_question: Optional[str] = None
follow_up_suggestions: list[dict] = Field(default_factory=list)
search_context: Optional[dict] = None
ai_tool_query: Optional[str] = None
primo_boolean_query: Optional[str] = None
primo_search_url: Optional[str] = None
primo_ai_url: Optional[str] = None
pubmed_search_url: Optional[str] = None