"""Response contracts without imposing new assumptions on upstream JSON. Only fields constructed by this service have concrete types. Upstream-owned values remain Any, and unknown fields remain allowed at every modeled level. Responses are validated but serialized from their original payloads so omitted fields, numeric representations, key order, and unknown values stay unchanged. """ from typing import Any, Literal from pydantic import BaseModel, ConfigDict, RootModel class OpenResponse(BaseModel): model_config = ConfigDict(extra="allow", strict=True) class ConfigResponse(OpenResponse): search: bool lb: bool allowDirect: bool s2sUrl: str primaryPrompt: str reasoningType: Literal["PROXY", "OPENAI"] injectProfile: bool debugPrompt: bool startSessionMode: str theme: str apipilot: bool class SearchResult(OpenResponse): # Serper values have historically passed through, including nulls, numbers, # and objects. The service guarantees these keys, not their value types. title: Any snippet: Any url: Any class SearchResponse(OpenResponse): query: str answer: Any results: list[SearchResult] class ReportEntry(OpenResponse): sourceScheduleLabel: Any date: Any class ReportsResponse(OpenResponse): count: int wrappedLen: int hints: list[str] entries: list[ReportEntry] rawCount: int | None = None cap: int | None = None skipped: bool | None = None reason: str | None = None truncated: bool | None = None note: str | None = None class ToolInvocation(OpenResponse): name: str success: bool result_length: int class ReasoningResponse(OpenResponse): answer: str usage_pass2: Any = None apipilot_invoked: ToolInvocation | None = None class ToolDefinition(OpenResponse): name: str description: str parameters: dict[str, Any] requires_auth: bool class ToolCatalog(OpenResponse): count: int include_unauthorized: bool tools: list[ToolDefinition] class ToolCatalogResponse(OpenResponse): success: bool data: ToolCatalog | None error: Any class ToolExecutionResponse(OpenResponse): success: bool # The upstream may omit these fields or return any JSON value for them. data: Any = None error: Any = None class AllocationResponse(OpenResponse): """LB-owned object: no new required fields or value-type restrictions.""" state: Any = None session_id: Any = None connect_url: Any = None pending_timeout_s: Any = None queue_id: Any = None position: Any = None poll_interval_s: Any = None class UserProfileResponse(RootModel[Any]): """The profile endpoint relays objects, arrays, scalars, and null verbatim.""" class QueueCancellationResponse(OpenResponse): ok: bool