exa-py 1.14.19__py3-none-any.whl → 1.15.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of exa-py might be problematic. Click here for more details.
- exa_py/api.py +78 -31
- exa_py/research/__init__.py +34 -5
- exa_py/research/async_client.py +310 -0
- exa_py/research/base.py +165 -0
- exa_py/research/models.py +314 -113
- exa_py/research/sync_client.py +308 -0
- exa_py/research/utils.py +222 -0
- exa_py/utils.py +1 -4
- {exa_py-1.14.19.dist-info → exa_py-1.15.0.dist-info}/METADATA +1 -1
- {exa_py-1.14.19.dist-info → exa_py-1.15.0.dist-info}/RECORD +11 -8
- exa_py/research/client.py +0 -358
- {exa_py-1.14.19.dist-info → exa_py-1.15.0.dist-info}/WHEEL +0 -0
exa_py/research/base.py
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
"""Base client classes for the Research API."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import TYPE_CHECKING, Any, Dict, Optional, Union
|
|
6
|
+
|
|
7
|
+
import httpx
|
|
8
|
+
import requests
|
|
9
|
+
|
|
10
|
+
if TYPE_CHECKING:
|
|
11
|
+
from exa_py.api import Exa, AsyncExa
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class ResearchBaseClient:
|
|
15
|
+
"""Base client for synchronous Research API operations."""
|
|
16
|
+
|
|
17
|
+
def __init__(self, client: "Exa"):
|
|
18
|
+
"""Initialize the base client.
|
|
19
|
+
|
|
20
|
+
Args:
|
|
21
|
+
client: The parent Exa client instance.
|
|
22
|
+
"""
|
|
23
|
+
self._client = client
|
|
24
|
+
self.base_path = "/research/v1"
|
|
25
|
+
|
|
26
|
+
def request(
|
|
27
|
+
self,
|
|
28
|
+
endpoint: str,
|
|
29
|
+
method: str = "POST",
|
|
30
|
+
data: Optional[Union[Dict[str, Any], str]] = None,
|
|
31
|
+
params: Optional[Dict[str, str]] = None,
|
|
32
|
+
stream: bool = False,
|
|
33
|
+
) -> Union[Dict[str, Any], requests.Response]:
|
|
34
|
+
"""Make a request to the Research API.
|
|
35
|
+
|
|
36
|
+
Args:
|
|
37
|
+
endpoint: The API endpoint (relative to base_path).
|
|
38
|
+
method: HTTP method to use.
|
|
39
|
+
data: Request body data.
|
|
40
|
+
params: Query parameters.
|
|
41
|
+
stream: Whether to stream the response.
|
|
42
|
+
|
|
43
|
+
Returns:
|
|
44
|
+
The API response as a dict or raw Response for streaming.
|
|
45
|
+
"""
|
|
46
|
+
full_endpoint = f"{self.base_path}{endpoint}"
|
|
47
|
+
|
|
48
|
+
if stream:
|
|
49
|
+
# For streaming, handle differently based on method
|
|
50
|
+
if method == "GET":
|
|
51
|
+
# For GET requests, streaming is controlled by params
|
|
52
|
+
# The params should already have stream=true set by the caller
|
|
53
|
+
return self._client.request(
|
|
54
|
+
full_endpoint, data=None, method=method, params=params
|
|
55
|
+
)
|
|
56
|
+
else:
|
|
57
|
+
# For POST requests, add stream flag to data
|
|
58
|
+
if data is None:
|
|
59
|
+
data = {}
|
|
60
|
+
if isinstance(data, dict):
|
|
61
|
+
data["stream"] = True
|
|
62
|
+
# The client's request method returns raw Response when streaming
|
|
63
|
+
return self._client.request(
|
|
64
|
+
full_endpoint, data=data, method=method, params=params
|
|
65
|
+
)
|
|
66
|
+
else:
|
|
67
|
+
return self._client.request(
|
|
68
|
+
full_endpoint, data=data, method=method, params=params
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
def build_pagination_params(
|
|
72
|
+
self, cursor: Optional[str] = None, limit: Optional[int] = None
|
|
73
|
+
) -> Dict[str, str]:
|
|
74
|
+
"""Build pagination parameters for list requests.
|
|
75
|
+
|
|
76
|
+
Args:
|
|
77
|
+
cursor: Pagination cursor.
|
|
78
|
+
limit: Maximum number of results.
|
|
79
|
+
|
|
80
|
+
Returns:
|
|
81
|
+
Dictionary of query parameters.
|
|
82
|
+
"""
|
|
83
|
+
params = {}
|
|
84
|
+
if cursor is not None:
|
|
85
|
+
params["cursor"] = cursor
|
|
86
|
+
if limit is not None:
|
|
87
|
+
params["limit"] = str(limit)
|
|
88
|
+
return params
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
class AsyncResearchBaseClient:
|
|
92
|
+
"""Base client for asynchronous Research API operations."""
|
|
93
|
+
|
|
94
|
+
def __init__(self, client: "AsyncExa"):
|
|
95
|
+
"""Initialize the async base client.
|
|
96
|
+
|
|
97
|
+
Args:
|
|
98
|
+
client: The parent AsyncExa client instance.
|
|
99
|
+
"""
|
|
100
|
+
self._client = client
|
|
101
|
+
self.base_path = "/research/v1"
|
|
102
|
+
|
|
103
|
+
async def request(
|
|
104
|
+
self,
|
|
105
|
+
endpoint: str,
|
|
106
|
+
method: str = "POST",
|
|
107
|
+
data: Optional[Union[Dict[str, Any], str]] = None,
|
|
108
|
+
params: Optional[Dict[str, str]] = None,
|
|
109
|
+
stream: bool = False,
|
|
110
|
+
) -> Union[Dict[str, Any], httpx.Response]:
|
|
111
|
+
"""Make an async request to the Research API.
|
|
112
|
+
|
|
113
|
+
Args:
|
|
114
|
+
endpoint: The API endpoint (relative to base_path).
|
|
115
|
+
method: HTTP method to use.
|
|
116
|
+
data: Request body data.
|
|
117
|
+
params: Query parameters.
|
|
118
|
+
stream: Whether to stream the response.
|
|
119
|
+
|
|
120
|
+
Returns:
|
|
121
|
+
The API response as a dict or raw Response for streaming.
|
|
122
|
+
"""
|
|
123
|
+
full_endpoint = f"{self.base_path}{endpoint}"
|
|
124
|
+
|
|
125
|
+
if stream:
|
|
126
|
+
# For streaming, handle differently based on method
|
|
127
|
+
if method == "GET":
|
|
128
|
+
# For GET requests, streaming is controlled by params
|
|
129
|
+
# The params should already have stream=true set by the caller
|
|
130
|
+
return await self._client.async_request(
|
|
131
|
+
full_endpoint, data=None, method=method, params=params
|
|
132
|
+
)
|
|
133
|
+
else:
|
|
134
|
+
# For POST requests, add stream flag to data
|
|
135
|
+
if data is None:
|
|
136
|
+
data = {}
|
|
137
|
+
if isinstance(data, dict):
|
|
138
|
+
data["stream"] = True
|
|
139
|
+
# The async_request method returns raw Response when streaming
|
|
140
|
+
return await self._client.async_request(
|
|
141
|
+
full_endpoint, data=data, method=method, params=params
|
|
142
|
+
)
|
|
143
|
+
else:
|
|
144
|
+
return await self._client.async_request(
|
|
145
|
+
full_endpoint, data=data, method=method, params=params
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
def build_pagination_params(
|
|
149
|
+
self, cursor: Optional[str] = None, limit: Optional[int] = None
|
|
150
|
+
) -> Dict[str, str]:
|
|
151
|
+
"""Build pagination parameters for list requests.
|
|
152
|
+
|
|
153
|
+
Args:
|
|
154
|
+
cursor: Pagination cursor.
|
|
155
|
+
limit: Maximum number of results.
|
|
156
|
+
|
|
157
|
+
Returns:
|
|
158
|
+
Dictionary of query parameters.
|
|
159
|
+
"""
|
|
160
|
+
params = {}
|
|
161
|
+
if cursor is not None:
|
|
162
|
+
params["cursor"] = cursor
|
|
163
|
+
if limit is not None:
|
|
164
|
+
params["limit"] = str(limit)
|
|
165
|
+
return params
|
exa_py/research/models.py
CHANGED
|
@@ -1,120 +1,321 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
from
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
class
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
3
|
+
from typing import Annotated, Any, Dict, List, Literal, Optional, Union
|
|
4
|
+
|
|
5
|
+
from pydantic import BaseModel, Field, RootModel
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class CostDollars(BaseModel):
|
|
9
|
+
total: float
|
|
10
|
+
num_pages: Annotated[float, Field(alias="numPages")]
|
|
11
|
+
num_searches: Annotated[float, Field(alias="numSearches")]
|
|
12
|
+
reasoning_tokens: Annotated[float, Field(alias="reasoningTokens")]
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class Result(BaseModel):
|
|
16
|
+
url: str
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class ResearchThinkOperation(BaseModel):
|
|
20
|
+
type: Literal["think"]
|
|
21
|
+
content: str
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class ResearchSearchOperation(BaseModel):
|
|
25
|
+
type: Literal["search"]
|
|
26
|
+
search_type: Annotated[
|
|
27
|
+
Literal["neural", "keyword", "auto", "fast"], Field(alias="searchType")
|
|
28
|
+
]
|
|
29
|
+
query: str
|
|
30
|
+
results: List[Result]
|
|
31
|
+
page_tokens: Annotated[float, Field(alias="pageTokens")]
|
|
32
|
+
goal: Optional[str] = None
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class ResearchCrawlOperation(BaseModel):
|
|
36
|
+
type: Literal["crawl"]
|
|
37
|
+
result: Result
|
|
38
|
+
page_tokens: Annotated[float, Field(alias="pageTokens")]
|
|
39
|
+
goal: Optional[str] = None
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
ResearchOperation = Annotated[
|
|
43
|
+
Union[ResearchThinkOperation, ResearchSearchOperation, ResearchCrawlOperation],
|
|
44
|
+
Field(discriminator="type"),
|
|
45
|
+
]
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class ResearchDefinitionEvent(BaseModel):
|
|
49
|
+
event_type: Annotated[Literal["research-definition"], Field(alias="eventType")]
|
|
50
|
+
research_id: Annotated[str, Field(alias="researchId")]
|
|
51
|
+
created_at: Annotated[
|
|
52
|
+
float, Field(alias="createdAt", description="Milliseconds since epoch time")
|
|
53
|
+
]
|
|
54
|
+
instructions: str
|
|
55
|
+
output_schema: Annotated[Optional[Dict[str, Any]], Field(alias="outputSchema")] = (
|
|
56
|
+
None
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
class ResearchOutputCompleted(BaseModel):
|
|
61
|
+
output_type: Annotated[Literal["completed"], Field(alias="outputType")]
|
|
62
|
+
content: str
|
|
63
|
+
cost_dollars: Annotated[CostDollars, Field(alias="costDollars")]
|
|
64
|
+
parsed: Optional[Dict[str, Any]] = None
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class ResearchOutputFailed(BaseModel):
|
|
68
|
+
output_type: Annotated[Literal["failed"], Field(alias="outputType")]
|
|
69
|
+
error: str
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
class ResearchOutputEvent(BaseModel):
|
|
73
|
+
event_type: Annotated[Literal["research-output"], Field(alias="eventType")]
|
|
74
|
+
research_id: Annotated[str, Field(alias="researchId")]
|
|
75
|
+
created_at: Annotated[
|
|
76
|
+
float, Field(alias="createdAt", description="Milliseconds since epoch time")
|
|
77
|
+
]
|
|
78
|
+
output: Annotated[
|
|
79
|
+
Union[ResearchOutputCompleted, ResearchOutputFailed],
|
|
80
|
+
Field(discriminator="output_type"),
|
|
81
|
+
]
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
class ResearchPlanDefinitionEvent(BaseModel):
|
|
85
|
+
event_type: Annotated[Literal["plan-definition"], Field(alias="eventType")]
|
|
86
|
+
research_id: Annotated[str, Field(alias="researchId")]
|
|
87
|
+
plan_id: Annotated[str, Field(alias="planId")]
|
|
88
|
+
created_at: Annotated[
|
|
89
|
+
float, Field(alias="createdAt", description="Milliseconds since epoch time")
|
|
90
|
+
]
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
class ResearchPlanOperationEvent(BaseModel):
|
|
94
|
+
event_type: Annotated[Literal["plan-operation"], Field(alias="eventType")]
|
|
95
|
+
research_id: Annotated[str, Field(alias="researchId")]
|
|
96
|
+
plan_id: Annotated[str, Field(alias="planId")]
|
|
97
|
+
operation_id: Annotated[str, Field(alias="operationId")]
|
|
98
|
+
created_at: Annotated[
|
|
99
|
+
float, Field(alias="createdAt", description="Milliseconds since epoch time")
|
|
100
|
+
]
|
|
101
|
+
data: ResearchOperation
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
class ResearchPlanOutputTasks(BaseModel):
|
|
105
|
+
output_type: Annotated[Literal["tasks"], Field(alias="outputType")]
|
|
106
|
+
reasoning: str
|
|
107
|
+
tasks_instructions: Annotated[List[str], Field(alias="tasksInstructions")]
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
class ResearchPlanOutputStop(BaseModel):
|
|
111
|
+
output_type: Annotated[Literal["stop"], Field(alias="outputType")]
|
|
112
|
+
reasoning: str
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
class ResearchPlanOutputEvent(BaseModel):
|
|
116
|
+
event_type: Annotated[Literal["plan-output"], Field(alias="eventType")]
|
|
117
|
+
research_id: Annotated[str, Field(alias="researchId")]
|
|
118
|
+
plan_id: Annotated[str, Field(alias="planId")]
|
|
119
|
+
created_at: Annotated[
|
|
120
|
+
float, Field(alias="createdAt", description="Milliseconds since epoch time")
|
|
121
|
+
]
|
|
122
|
+
output: Annotated[
|
|
123
|
+
Union[ResearchPlanOutputTasks, ResearchPlanOutputStop],
|
|
124
|
+
Field(discriminator="output_type"),
|
|
125
|
+
]
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
class ResearchTaskDefinitionEvent(BaseModel):
|
|
129
|
+
event_type: Annotated[Literal["task-definition"], Field(alias="eventType")]
|
|
130
|
+
research_id: Annotated[str, Field(alias="researchId")]
|
|
131
|
+
plan_id: Annotated[str, Field(alias="planId")]
|
|
132
|
+
task_id: Annotated[str, Field(alias="taskId")]
|
|
133
|
+
created_at: Annotated[
|
|
134
|
+
float, Field(alias="createdAt", description="Milliseconds since epoch time")
|
|
135
|
+
]
|
|
57
136
|
instructions: str
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
class ResearchTaskOperationEvent(BaseModel):
|
|
140
|
+
event_type: Annotated[Literal["task-operation"], Field(alias="eventType")]
|
|
141
|
+
research_id: Annotated[str, Field(alias="researchId")]
|
|
142
|
+
plan_id: Annotated[str, Field(alias="planId")]
|
|
143
|
+
task_id: Annotated[str, Field(alias="taskId")]
|
|
144
|
+
operation_id: Annotated[str, Field(alias="operationId")]
|
|
145
|
+
created_at: Annotated[
|
|
146
|
+
float, Field(alias="createdAt", description="Milliseconds since epoch time")
|
|
147
|
+
]
|
|
148
|
+
data: ResearchOperation
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
class ResearchTaskOutput(BaseModel):
|
|
152
|
+
output_type: Annotated[Literal["completed"], Field(alias="outputType")]
|
|
153
|
+
content: str
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
class ResearchTaskOutputEvent(BaseModel):
|
|
157
|
+
event_type: Annotated[Literal["task-output"], Field(alias="eventType")]
|
|
158
|
+
research_id: Annotated[str, Field(alias="researchId")]
|
|
159
|
+
plan_id: Annotated[str, Field(alias="planId")]
|
|
160
|
+
task_id: Annotated[str, Field(alias="taskId")]
|
|
161
|
+
created_at: Annotated[
|
|
162
|
+
float, Field(alias="createdAt", description="Milliseconds since epoch time")
|
|
163
|
+
]
|
|
164
|
+
output: ResearchTaskOutput
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
ResearchMetaEvent = Union[ResearchDefinitionEvent, ResearchOutputEvent]
|
|
168
|
+
ResearchPlanEvent = Union[
|
|
169
|
+
ResearchPlanDefinitionEvent, ResearchPlanOperationEvent, ResearchPlanOutputEvent
|
|
170
|
+
]
|
|
171
|
+
ResearchTaskEvent = Union[
|
|
172
|
+
ResearchTaskDefinitionEvent, ResearchTaskOperationEvent, ResearchTaskOutputEvent
|
|
173
|
+
]
|
|
174
|
+
ResearchEvent = Union[ResearchMetaEvent, ResearchPlanEvent, ResearchTaskEvent]
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
class ResearchOutput(BaseModel):
|
|
178
|
+
content: str
|
|
179
|
+
parsed: Optional[Dict[str, Any]] = None
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
class ResearchBaseDto(BaseModel):
|
|
183
|
+
research_id: Annotated[
|
|
184
|
+
str,
|
|
185
|
+
Field(
|
|
186
|
+
alias="researchId",
|
|
187
|
+
description="The unique identifier for the research request",
|
|
188
|
+
),
|
|
189
|
+
]
|
|
190
|
+
created_at: Annotated[
|
|
191
|
+
float, Field(alias="createdAt", description="Milliseconds since epoch time")
|
|
192
|
+
]
|
|
193
|
+
model: Annotated[
|
|
194
|
+
Literal["exa-research", "exa-research-pro"],
|
|
195
|
+
Field(description="The model used for the research request"),
|
|
196
|
+
] = "exa-research"
|
|
197
|
+
instructions: Annotated[
|
|
198
|
+
str, Field(description="The instructions given to this research request")
|
|
199
|
+
]
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
class ResearchPendingDto(ResearchBaseDto):
|
|
203
|
+
status: Literal["pending"]
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
class ResearchRunningDto(ResearchBaseDto):
|
|
207
|
+
status: Literal["running"]
|
|
208
|
+
events: Optional[List[ResearchEvent]] = None
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
class ResearchCompletedDto(ResearchBaseDto):
|
|
212
|
+
status: Literal["completed"]
|
|
213
|
+
events: Optional[List[ResearchEvent]] = None
|
|
214
|
+
output: ResearchOutput
|
|
215
|
+
cost_dollars: Annotated[CostDollars, Field(alias="costDollars")]
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
class ResearchCanceledDto(ResearchBaseDto):
|
|
219
|
+
status: Literal["canceled"]
|
|
220
|
+
events: Optional[List[ResearchEvent]] = None
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
class ResearchFailedDto(ResearchBaseDto):
|
|
224
|
+
status: Literal["failed"]
|
|
225
|
+
events: Optional[List[ResearchEvent]] = None
|
|
226
|
+
error: Annotated[
|
|
227
|
+
str, Field(description="A message indicating why the request failed")
|
|
228
|
+
]
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
ResearchDto = Annotated[
|
|
232
|
+
Union[
|
|
233
|
+
ResearchPendingDto,
|
|
234
|
+
ResearchRunningDto,
|
|
235
|
+
ResearchCompletedDto,
|
|
236
|
+
ResearchCanceledDto,
|
|
237
|
+
ResearchFailedDto,
|
|
238
|
+
],
|
|
239
|
+
Field(discriminator="status"),
|
|
240
|
+
]
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
class ListResearchResponseDto(BaseModel):
|
|
244
|
+
data: Annotated[
|
|
245
|
+
List[ResearchDto], Field(description="The list of research requests")
|
|
246
|
+
]
|
|
247
|
+
has_more: Annotated[
|
|
248
|
+
bool,
|
|
249
|
+
Field(
|
|
250
|
+
alias="hasMore",
|
|
251
|
+
description="Whether there are more results to paginate through",
|
|
252
|
+
),
|
|
253
|
+
]
|
|
254
|
+
next_cursor: Annotated[
|
|
255
|
+
Optional[str],
|
|
256
|
+
Field(
|
|
257
|
+
alias="nextCursor",
|
|
258
|
+
description="The cursor to paginate through the next set of results",
|
|
259
|
+
),
|
|
260
|
+
]
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
class ResearchCreateRequestDto(BaseModel):
|
|
264
|
+
model: Literal["exa-research", "exa-research-pro"] = "exa-research"
|
|
265
|
+
instructions: Annotated[
|
|
266
|
+
str,
|
|
267
|
+
Field(
|
|
268
|
+
description="Instructions for what research should be conducted",
|
|
269
|
+
max_length=4096,
|
|
270
|
+
),
|
|
271
|
+
]
|
|
272
|
+
output_schema: Annotated[Optional[Dict[str, Any]], Field(alias="outputSchema")] = (
|
|
273
|
+
None
|
|
274
|
+
)
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
ResearchDtoClass = RootModel[ResearchDto]
|
|
278
|
+
ResearchCreateRequestDtoClass = ResearchCreateRequestDto
|
|
279
|
+
ResearchEventDtoClass = RootModel[ResearchEvent]
|
|
280
|
+
ResearchOperationDtoClass = RootModel[ResearchOperation]
|
|
114
281
|
|
|
115
282
|
|
|
116
283
|
__all__ = [
|
|
117
|
-
"
|
|
118
|
-
"
|
|
119
|
-
"
|
|
284
|
+
"CostDollars",
|
|
285
|
+
"Result",
|
|
286
|
+
"ResearchThinkOperation",
|
|
287
|
+
"ResearchSearchOperation",
|
|
288
|
+
"ResearchCrawlOperation",
|
|
289
|
+
"ResearchOperation",
|
|
290
|
+
"ResearchDefinitionEvent",
|
|
291
|
+
"ResearchOutputCompleted",
|
|
292
|
+
"ResearchOutputFailed",
|
|
293
|
+
"ResearchOutputEvent",
|
|
294
|
+
"ResearchPlanDefinitionEvent",
|
|
295
|
+
"ResearchPlanOperationEvent",
|
|
296
|
+
"ResearchPlanOutputTasks",
|
|
297
|
+
"ResearchPlanOutputStop",
|
|
298
|
+
"ResearchPlanOutputEvent",
|
|
299
|
+
"ResearchTaskDefinitionEvent",
|
|
300
|
+
"ResearchTaskOperationEvent",
|
|
301
|
+
"ResearchTaskOutput",
|
|
302
|
+
"ResearchTaskOutputEvent",
|
|
303
|
+
"ResearchMetaEvent",
|
|
304
|
+
"ResearchPlanEvent",
|
|
305
|
+
"ResearchTaskEvent",
|
|
306
|
+
"ResearchEvent",
|
|
307
|
+
"ResearchOutput",
|
|
308
|
+
"ResearchBaseDto",
|
|
309
|
+
"ResearchPendingDto",
|
|
310
|
+
"ResearchRunningDto",
|
|
311
|
+
"ResearchCompletedDto",
|
|
312
|
+
"ResearchCanceledDto",
|
|
313
|
+
"ResearchFailedDto",
|
|
314
|
+
"ResearchDto",
|
|
315
|
+
"ListResearchResponseDto",
|
|
316
|
+
"ResearchCreateRequestDto",
|
|
317
|
+
"ResearchDtoClass",
|
|
318
|
+
"ResearchCreateRequestDtoClass",
|
|
319
|
+
"ResearchEventDtoClass",
|
|
320
|
+
"ResearchOperationDtoClass",
|
|
120
321
|
]
|