Edit on GitHub

agent_search_gateway.models

Side-effect-free domain and protocol data models.

  1"""Side-effect-free domain and protocol data models."""
  2
  3from __future__ import annotations
  4
  5from collections.abc import Mapping
  6from dataclasses import dataclass, field
  7from datetime import date
  8from typing import TYPE_CHECKING, Literal, TypeAlias
  9
 10from .errors import ErrorCode, ExecutionFailure
 11from .url_normalization import NormalizedURL
 12
 13if TYPE_CHECKING:
 14    from .providers.contracts import URLFetchCandidate
 15
 16
 17@dataclass(frozen=True, slots=True)
 18class URLRecord:
 19    url: NormalizedURL
 20    raw_content: str = ""
 21    content: str = ""
 22    abstract: str = ""
 23    available: bool = True
 24
 25
 26@dataclass(frozen=True, slots=True)
 27class SearchRecord:
 28    url: NormalizedURL
 29    abstract: str
 30
 31
 32@dataclass(frozen=True, slots=True)
 33class PaperIdentifiers:
 34    doi: str = ""
 35    arxiv_id: str = ""
 36    semantic_scholar_id: str = ""
 37    openalex_id: str = ""
 38    dblp_key: str = ""
 39    core_id: str = ""
 40
 41
 42@dataclass(frozen=True, slots=True)
 43class PaperRecord:
 44    title: str
 45    authors: tuple[str, ...]
 46    abstract: str
 47    identifiers: PaperIdentifiers
 48    published_date: date | None
 49    updated_date: date | None
 50    url: NormalizedURL
 51    pdf_url: NormalizedURL | None
 52    venue: str
 53    topics: tuple[str, ...]
 54    citation_counts: Mapping[str, int]
 55    is_open_access: bool | None
 56    oa_status: str
 57    license: str
 58    sources: tuple[str, ...]
 59
 60
 61@dataclass(frozen=True, slots=True)
 62class OAResolution:
 63    landing_url: NormalizedURL | None
 64    pdf_url: NormalizedURL | None
 65    is_open_access: bool
 66    oa_status: str = ""
 67    license: str = ""
 68
 69
 70@dataclass(frozen=True, slots=True)
 71class LLMInvocation:
 72    provider: str
 73    model: str
 74    extra_body: Mapping[str, object] = field(default_factory=dict)
 75
 76
 77@dataclass(frozen=True, slots=True)
 78class RetryPolicy:
 79    max_attempts: int
 80    base_delay_seconds: float
 81    max_delay_seconds: float
 82    request_timeout_seconds: float
 83
 84
 85@dataclass(frozen=True, slots=True)
 86class StageDecision:
 87    ok: bool
 88    reason: str = ""
 89
 90
 91@dataclass(frozen=True, slots=True)
 92class KeywordSearchRequest:
 93    query: str
 94
 95
 96@dataclass(frozen=True, slots=True)
 97class PaperSearchRequest:
 98    query: str
 99
100
101LLMSearchScope = Literal["web", "paper", "all"]
102
103
104@dataclass(frozen=True, slots=True)
105class LLMSearchRequest:
106    prompt: str
107    scope: LLMSearchScope = "web"
108
109
110@dataclass(frozen=True, slots=True)
111class URLFetchRequest:
112    url: str
113    focus: str | None = None
114
115
116@dataclass(frozen=True, slots=True)
117class ShutdownRequest:
118    pass
119
120
121Request: TypeAlias = (
122    KeywordSearchRequest | PaperSearchRequest | LLMSearchRequest | URLFetchRequest | ShutdownRequest
123)
124
125
126@dataclass(frozen=True, slots=True)
127class SuccessResponse:
128    text: str
129    ok: bool = field(default=True, init=False)
130
131
132@dataclass(frozen=True, slots=True)
133class ErrorResponse:
134    error: ErrorCode
135    message: str
136    ok: bool = field(default=False, init=False)
137
138
139Response: TypeAlias = SuccessResponse | ErrorResponse
140
141
142@dataclass(frozen=True, slots=True)
143class FetchOutcome:
144    kind: Literal["accepted", "semantic_failure", "execution_failure"]
145    candidate: URLFetchCandidate | None = None
146    failures: tuple[ExecutionFailure, ...] = ()
@dataclass(frozen=True, slots=True)
class URLRecord:
18@dataclass(frozen=True, slots=True)
19class URLRecord:
20    url: NormalizedURL
21    raw_content: str = ""
22    content: str = ""
23    abstract: str = ""
24    available: bool = True
URLRecord( url: agent_search_gateway.url_normalization.NormalizedURL, raw_content: str = '', content: str = '', abstract: str = '', available: bool = True)
raw_content: str
content: str
abstract: str
available: bool
@dataclass(frozen=True, slots=True)
class SearchRecord:
27@dataclass(frozen=True, slots=True)
28class SearchRecord:
29    url: NormalizedURL
30    abstract: str
SearchRecord( url: agent_search_gateway.url_normalization.NormalizedURL, abstract: str)
abstract: str
@dataclass(frozen=True, slots=True)
class PaperIdentifiers:
33@dataclass(frozen=True, slots=True)
34class PaperIdentifiers:
35    doi: str = ""
36    arxiv_id: str = ""
37    semantic_scholar_id: str = ""
38    openalex_id: str = ""
39    dblp_key: str = ""
40    core_id: str = ""
PaperIdentifiers( doi: str = '', arxiv_id: str = '', semantic_scholar_id: str = '', openalex_id: str = '', dblp_key: str = '', core_id: str = '')
doi: str
arxiv_id: str
semantic_scholar_id: str
openalex_id: str
dblp_key: str
core_id: str
@dataclass(frozen=True, slots=True)
class PaperRecord:
43@dataclass(frozen=True, slots=True)
44class PaperRecord:
45    title: str
46    authors: tuple[str, ...]
47    abstract: str
48    identifiers: PaperIdentifiers
49    published_date: date | None
50    updated_date: date | None
51    url: NormalizedURL
52    pdf_url: NormalizedURL | None
53    venue: str
54    topics: tuple[str, ...]
55    citation_counts: Mapping[str, int]
56    is_open_access: bool | None
57    oa_status: str
58    license: str
59    sources: tuple[str, ...]
PaperRecord( title: str, authors: tuple[str, ...], abstract: str, identifiers: PaperIdentifiers, published_date: datetime.date | None, updated_date: datetime.date | None, url: agent_search_gateway.url_normalization.NormalizedURL, pdf_url: Optional[agent_search_gateway.url_normalization.NormalizedURL], venue: str, topics: tuple[str, ...], citation_counts: Mapping[str, int], is_open_access: bool | None, oa_status: str, license: str, sources: tuple[str, ...])
title: str
authors: tuple[str, ...]
abstract: str
identifiers: PaperIdentifiers
published_date: datetime.date | None
updated_date: datetime.date | None
venue: str
topics: tuple[str, ...]
citation_counts: Mapping[str, int]
is_open_access: bool | None
oa_status: str
license: str
sources: tuple[str, ...]
@dataclass(frozen=True, slots=True)
class OAResolution:
62@dataclass(frozen=True, slots=True)
63class OAResolution:
64    landing_url: NormalizedURL | None
65    pdf_url: NormalizedURL | None
66    is_open_access: bool
67    oa_status: str = ""
68    license: str = ""
OAResolution( landing_url: Optional[agent_search_gateway.url_normalization.NormalizedURL], pdf_url: Optional[agent_search_gateway.url_normalization.NormalizedURL], is_open_access: bool, oa_status: str = '', license: str = '')
is_open_access: bool
oa_status: str
license: str
@dataclass(frozen=True, slots=True)
class LLMInvocation:
71@dataclass(frozen=True, slots=True)
72class LLMInvocation:
73    provider: str
74    model: str
75    extra_body: Mapping[str, object] = field(default_factory=dict)
LLMInvocation( provider: str, model: str, extra_body: Mapping[str, object] = <factory>)
provider: str
model: str
extra_body: Mapping[str, object]
@dataclass(frozen=True, slots=True)
class RetryPolicy:
78@dataclass(frozen=True, slots=True)
79class RetryPolicy:
80    max_attempts: int
81    base_delay_seconds: float
82    max_delay_seconds: float
83    request_timeout_seconds: float
RetryPolicy( max_attempts: int, base_delay_seconds: float, max_delay_seconds: float, request_timeout_seconds: float)
max_attempts: int
base_delay_seconds: float
max_delay_seconds: float
request_timeout_seconds: float
@dataclass(frozen=True, slots=True)
class StageDecision:
86@dataclass(frozen=True, slots=True)
87class StageDecision:
88    ok: bool
89    reason: str = ""
StageDecision(ok: bool, reason: str = '')
ok: bool
reason: str
@dataclass(frozen=True, slots=True)
class KeywordSearchRequest:
92@dataclass(frozen=True, slots=True)
93class KeywordSearchRequest:
94    query: str
KeywordSearchRequest(query: str)
query: str
@dataclass(frozen=True, slots=True)
class PaperSearchRequest:
97@dataclass(frozen=True, slots=True)
98class PaperSearchRequest:
99    query: str
PaperSearchRequest(query: str)
query: str
LLMSearchScope = typing.Literal['web', 'paper', 'all']
@dataclass(frozen=True, slots=True)
class LLMSearchRequest:
105@dataclass(frozen=True, slots=True)
106class LLMSearchRequest:
107    prompt: str
108    scope: LLMSearchScope = "web"
LLMSearchRequest(prompt: str, scope: Literal['web', 'paper', 'all'] = 'web')
prompt: str
scope: Literal['web', 'paper', 'all']
@dataclass(frozen=True, slots=True)
class URLFetchRequest:
111@dataclass(frozen=True, slots=True)
112class URLFetchRequest:
113    url: str
114    focus: str | None = None
URLFetchRequest(url: str, focus: str | None = None)
url: str
focus: str | None
@dataclass(frozen=True, slots=True)
class ShutdownRequest:
117@dataclass(frozen=True, slots=True)
118class ShutdownRequest:
119    pass
@dataclass(frozen=True, slots=True)
class SuccessResponse:
127@dataclass(frozen=True, slots=True)
128class SuccessResponse:
129    text: str
130    ok: bool = field(default=True, init=False)
SuccessResponse(text: str)
text: str
ok: bool
@dataclass(frozen=True, slots=True)
class ErrorResponse:
133@dataclass(frozen=True, slots=True)
134class ErrorResponse:
135    error: ErrorCode
136    message: str
137    ok: bool = field(default=False, init=False)
ErrorResponse(error: agent_search_gateway.errors.ErrorCode, message: str)
message: str
ok: bool
Response: TypeAlias = SuccessResponse | ErrorResponse
@dataclass(frozen=True, slots=True)
class FetchOutcome:
143@dataclass(frozen=True, slots=True)
144class FetchOutcome:
145    kind: Literal["accepted", "semantic_failure", "execution_failure"]
146    candidate: URLFetchCandidate | None = None
147    failures: tuple[ExecutionFailure, ...] = ()
FetchOutcome( kind: Literal['accepted', 'semantic_failure', 'execution_failure'], candidate: agent_search_gateway.providers.contracts.URLFetchCandidate | None = None, failures: tuple[agent_search_gateway.errors.ExecutionFailure, ...] = ())
kind: Literal['accepted', 'semantic_failure', 'execution_failure']