Lancer / app /api /schemas.py
Madras1's picture
Upload 38 files
db9bbfd verified
"""Pydantic schemas for API request/response models."""
from datetime import datetime
from typing import Literal
from pydantic import BaseModel, Field
# === Request Models ===
class SearchRequest(BaseModel):
"""Search request payload."""
query: str = Field(..., min_length=1, max_length=1000, description="Search query")
max_results: int = Field(default=10, ge=1, le=50, description="Maximum results to return")
freshness: Literal["day", "week", "month", "year", "any"] = Field(
default="any",
description="Filter results by recency"
)
include_domains: list[str] | None = Field(
default=None,
description="Only include results from these domains"
)
exclude_domains: list[str] | None = Field(
default=None,
description="Exclude results from these domains"
)
include_answer: bool = Field(
default=True,
description="Include AI-generated answer"
)
# === Response Models ===
class Citation(BaseModel):
"""Citation reference for the answer."""
index: int = Field(..., description="Citation index (1-based)")
url: str = Field(..., description="Source URL")
title: str = Field(..., description="Source title")
class TemporalContext(BaseModel):
"""Temporal metadata about the search."""
query_temporal_intent: Literal["current", "historical", "neutral"] = Field(
...,
description="Detected temporal intent of the query"
)
temporal_urgency: float = Field(
...,
ge=0.0,
le=1.0,
description="How important freshness is for this query (0-1)"
)
current_date: str = Field(..., description="Current date for context")
class SearchResult(BaseModel):
"""Individual search result."""
title: str = Field(..., description="Result title")
url: str = Field(..., description="Result URL")
content: str = Field(..., description="Result content/snippet")
score: float = Field(..., ge=0.0, le=1.0, description="Overall relevance score")
published_date: datetime | None = Field(
default=None,
description="Publication date if available"
)
freshness_score: float = Field(
default=0.5,
ge=0.0,
le=1.0,
description="How fresh/recent the content is"
)
authority_score: float = Field(
default=0.5,
ge=0.0,
le=1.0,
description="Domain authority/trust score"
)
class SearchResponse(BaseModel):
"""Complete search response."""
query: str = Field(..., description="Original query")
answer: str | None = Field(
default=None,
description="AI-generated answer synthesized from results"
)
results: list[SearchResult] = Field(
default_factory=list,
description="Ranked search results"
)
citations: list[Citation] = Field(
default_factory=list,
description="Citations referenced in the answer"
)
temporal_context: TemporalContext | None = Field(
default=None,
description="Temporal analysis metadata"
)
processing_time_ms: float = Field(..., description="Total processing time in milliseconds")
class ErrorResponse(BaseModel):
"""Error response model."""
error: str = Field(..., description="Error message")
detail: str | None = Field(default=None, description="Detailed error information")
# === Deep Research Models ===
class DeepResearchRequest(BaseModel):
"""Deep research request payload."""
query: str = Field(..., min_length=1, max_length=2000, description="Research query")
max_dimensions: int = Field(
default=5,
ge=2,
le=8,
description="Maximum research dimensions to explore"
)
max_sources_per_dim: int = Field(
default=5,
ge=1,
le=10,
description="Maximum sources per dimension"
)
max_total_searches: int = Field(
default=20,
ge=5,
le=30,
description="Maximum total API searches"
)