notte-sdk 0.0.dev0__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.
- notte_sdk/__init__.py +7 -0
- notte_sdk/client.py +50 -0
- notte_sdk/endpoints/__init__.py +0 -0
- notte_sdk/endpoints/agents.py +504 -0
- notte_sdk/endpoints/base.py +247 -0
- notte_sdk/endpoints/page.py +215 -0
- notte_sdk/endpoints/personas.py +285 -0
- notte_sdk/endpoints/sessions.py +542 -0
- notte_sdk/endpoints/vaults.py +83 -0
- notte_sdk/errors.py +40 -0
- notte_sdk/py.typed +0 -0
- notte_sdk/types.py +851 -0
- notte_sdk/vault.py +68 -0
- notte_sdk/websockets/__init__.py +0 -0
- notte_sdk/websockets/recording.py +106 -0
- notte_sdk-0.0.dev0.dist-info/METADATA +8 -0
- notte_sdk-0.0.dev0.dist-info/RECORD +18 -0
- notte_sdk-0.0.dev0.dist-info/WHEEL +4 -0
notte_sdk/__init__.py
ADDED
notte_sdk/client.py
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
from typing import Unpack
|
|
2
|
+
|
|
3
|
+
from notte_core.data.space import DataSpace
|
|
4
|
+
from typing_extensions import final
|
|
5
|
+
|
|
6
|
+
from notte_sdk.endpoints.agents import AgentsClient, RemoteAgentFactory
|
|
7
|
+
from notte_sdk.endpoints.personas import PersonasClient
|
|
8
|
+
from notte_sdk.endpoints.sessions import RemoteSessionFactory, SessionsClient
|
|
9
|
+
from notte_sdk.endpoints.vaults import VaultsClient
|
|
10
|
+
from notte_sdk.types import ScrapeRequestDict
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@final
|
|
14
|
+
class NotteClient:
|
|
15
|
+
"""
|
|
16
|
+
Client for the Notte API.
|
|
17
|
+
|
|
18
|
+
Note: this client is only able to handle one session at a time.
|
|
19
|
+
If you need to handle multiple sessions, you need to create a new client for each session.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
def __init__(
|
|
23
|
+
self,
|
|
24
|
+
api_key: str | None = None,
|
|
25
|
+
verbose: bool = False,
|
|
26
|
+
):
|
|
27
|
+
"""Initialize a NotteClient instance.
|
|
28
|
+
|
|
29
|
+
Initializes the NotteClient with the specified API key and server URL, creating instances
|
|
30
|
+
of SessionsClient, AgentsClient, VaultsClient, and PersonasClient.
|
|
31
|
+
|
|
32
|
+
Args:
|
|
33
|
+
api_key: Optional API key for authentication.
|
|
34
|
+
"""
|
|
35
|
+
self.sessions: SessionsClient = SessionsClient(api_key=api_key, verbose=verbose)
|
|
36
|
+
self.agents: AgentsClient = AgentsClient(api_key=api_key, verbose=verbose)
|
|
37
|
+
self.personas: PersonasClient = PersonasClient(api_key=api_key, verbose=verbose)
|
|
38
|
+
self.vaults: VaultsClient = VaultsClient(api_key=api_key, persona_client=self.personas, verbose=verbose)
|
|
39
|
+
|
|
40
|
+
@property
|
|
41
|
+
def Agent(self) -> RemoteAgentFactory:
|
|
42
|
+
return RemoteAgentFactory(self.agents)
|
|
43
|
+
|
|
44
|
+
@property
|
|
45
|
+
def Session(self) -> RemoteSessionFactory:
|
|
46
|
+
return RemoteSessionFactory(self.sessions)
|
|
47
|
+
|
|
48
|
+
def scrape(self, **data: Unpack[ScrapeRequestDict]) -> DataSpace:
|
|
49
|
+
with self.Session() as session:
|
|
50
|
+
return session.scrape(**data)
|
|
File without changes
|
|
@@ -0,0 +1,504 @@
|
|
|
1
|
+
import time
|
|
2
|
+
from collections.abc import Sequence
|
|
3
|
+
from typing import Any, Unpack
|
|
4
|
+
|
|
5
|
+
from loguru import logger
|
|
6
|
+
from notte_core.utils.webp_replay import WebpReplay
|
|
7
|
+
from pydantic import BaseModel
|
|
8
|
+
from typing_extensions import final, override
|
|
9
|
+
|
|
10
|
+
from notte_sdk.endpoints.base import BaseClient, NotteEndpoint
|
|
11
|
+
from notte_sdk.endpoints.sessions import RemoteSessionFactory
|
|
12
|
+
from notte_sdk.types import (
|
|
13
|
+
AgentCreateRequest,
|
|
14
|
+
AgentCreateRequestDict,
|
|
15
|
+
AgentListRequest,
|
|
16
|
+
AgentResponse,
|
|
17
|
+
AgentRunRequestDict,
|
|
18
|
+
AgentStartRequest,
|
|
19
|
+
AgentStartRequestDict,
|
|
20
|
+
AgentStatus,
|
|
21
|
+
AgentStatusRequest,
|
|
22
|
+
AgentStatusRequestDict,
|
|
23
|
+
ListRequestDict,
|
|
24
|
+
)
|
|
25
|
+
from notte_sdk.types import AgentStatusResponse as _AgentStatusResponse
|
|
26
|
+
from notte_sdk.vault import NotteVault
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
# proxy for: StepAgentOutput
|
|
30
|
+
class _AgentResponse(BaseModel):
|
|
31
|
+
state: dict[str, Any]
|
|
32
|
+
actions: list[dict[str, dict[str, Any]]]
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
AgentStatusResponse = _AgentStatusResponse[_AgentResponse]
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
@final
|
|
39
|
+
class AgentsClient(BaseClient):
|
|
40
|
+
"""
|
|
41
|
+
Client for the Notte API.
|
|
42
|
+
|
|
43
|
+
Note: this client is only able to handle one session at a time.
|
|
44
|
+
If you need to handle multiple sessions, you need to create a new client for each session.
|
|
45
|
+
"""
|
|
46
|
+
|
|
47
|
+
# Session
|
|
48
|
+
AGENT_START = "start"
|
|
49
|
+
AGENT_STOP = "{agent_id}/stop"
|
|
50
|
+
AGENT_STATUS = "{agent_id}"
|
|
51
|
+
AGENT_LIST = ""
|
|
52
|
+
# The following endpoints downloads a .webp file
|
|
53
|
+
AGENT_REPLAY = "{agent_id}/replay"
|
|
54
|
+
|
|
55
|
+
def __init__(
|
|
56
|
+
self,
|
|
57
|
+
api_key: str | None = None,
|
|
58
|
+
verbose: bool = False,
|
|
59
|
+
):
|
|
60
|
+
"""
|
|
61
|
+
Initialize an AgentsClient instance.
|
|
62
|
+
|
|
63
|
+
Configures the client to use the "agents" endpoint path and sets optional API key and server URL for authentication and server configuration. The initial state has no recorded agent response.
|
|
64
|
+
|
|
65
|
+
Args:
|
|
66
|
+
api_key: Optional API key for authenticating requests.
|
|
67
|
+
"""
|
|
68
|
+
super().__init__(base_endpoint_path="agents", api_key=api_key, verbose=verbose)
|
|
69
|
+
self._last_agent_response: AgentResponse | None = None
|
|
70
|
+
|
|
71
|
+
@staticmethod
|
|
72
|
+
def agent_start_endpoint() -> NotteEndpoint[AgentResponse]:
|
|
73
|
+
"""
|
|
74
|
+
Returns an endpoint for running an agent.
|
|
75
|
+
|
|
76
|
+
Creates a NotteEndpoint configured with the AGENT_START path, a POST method, and an expected AgentResponse.
|
|
77
|
+
"""
|
|
78
|
+
return NotteEndpoint(path=AgentsClient.AGENT_START, response=AgentResponse, method="POST")
|
|
79
|
+
|
|
80
|
+
@staticmethod
|
|
81
|
+
def agent_stop_endpoint(agent_id: str | None = None) -> NotteEndpoint[AgentResponse]:
|
|
82
|
+
"""
|
|
83
|
+
Constructs a DELETE endpoint for stopping an agent.
|
|
84
|
+
|
|
85
|
+
If an agent ID is provided, it is inserted into the endpoint URL. The returned
|
|
86
|
+
endpoint is configured with the DELETE HTTP method and expects an AgentStatusResponse.
|
|
87
|
+
|
|
88
|
+
Args:
|
|
89
|
+
agent_id (str, optional): The identifier of the agent to stop. If omitted,
|
|
90
|
+
the URL template will remain unformatted.
|
|
91
|
+
|
|
92
|
+
Returns:
|
|
93
|
+
NotteEndpoint[AgentResponse]: The endpoint object for stopping the agent.
|
|
94
|
+
"""
|
|
95
|
+
path = AgentsClient.AGENT_STOP
|
|
96
|
+
if agent_id is not None:
|
|
97
|
+
path = path.format(agent_id=agent_id)
|
|
98
|
+
return NotteEndpoint(path=path, response=AgentStatusResponse, method="DELETE")
|
|
99
|
+
|
|
100
|
+
@staticmethod
|
|
101
|
+
def agent_status_endpoint(agent_id: str | None = None) -> NotteEndpoint[AgentStatusResponse]:
|
|
102
|
+
"""
|
|
103
|
+
Creates an endpoint for retrieving an agent's status.
|
|
104
|
+
|
|
105
|
+
If an agent ID is provided, formats the endpoint path to target that specific agent.
|
|
106
|
+
|
|
107
|
+
Args:
|
|
108
|
+
agent_id: Optional identifier of the agent; if specified, the endpoint path will include this ID.
|
|
109
|
+
|
|
110
|
+
Returns:
|
|
111
|
+
NotteEndpoint configured with the GET method and AgentStatusResponse as the expected response.
|
|
112
|
+
"""
|
|
113
|
+
path = AgentsClient.AGENT_STATUS
|
|
114
|
+
if agent_id is not None:
|
|
115
|
+
path = path.format(agent_id=agent_id)
|
|
116
|
+
return NotteEndpoint(path=path, response=AgentStatusResponse, method="GET")
|
|
117
|
+
|
|
118
|
+
@staticmethod
|
|
119
|
+
def agent_replay_endpoint(agent_id: str | None = None) -> NotteEndpoint[BaseModel]:
|
|
120
|
+
"""
|
|
121
|
+
Creates an endpoint for downloading an agent's replay.
|
|
122
|
+
"""
|
|
123
|
+
path = AgentsClient.AGENT_REPLAY
|
|
124
|
+
if agent_id is not None:
|
|
125
|
+
path = path.format(agent_id=agent_id)
|
|
126
|
+
return NotteEndpoint(path=path, response=BaseModel, method="GET")
|
|
127
|
+
|
|
128
|
+
@staticmethod
|
|
129
|
+
def agent_list_endpoint(params: AgentListRequest | None = None) -> NotteEndpoint[AgentResponse]:
|
|
130
|
+
"""
|
|
131
|
+
Creates a NotteEndpoint for listing agents.
|
|
132
|
+
|
|
133
|
+
Returns an endpoint configured with the agent listing path and a GET method.
|
|
134
|
+
The optional params argument provides filtering or pagination details for the request.
|
|
135
|
+
"""
|
|
136
|
+
return NotteEndpoint(
|
|
137
|
+
path=AgentsClient.AGENT_LIST,
|
|
138
|
+
response=AgentResponse,
|
|
139
|
+
method="GET",
|
|
140
|
+
request=None,
|
|
141
|
+
params=params,
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
@override
|
|
145
|
+
@staticmethod
|
|
146
|
+
def endpoints() -> Sequence[NotteEndpoint[BaseModel]]:
|
|
147
|
+
"""
|
|
148
|
+
Returns a list of endpoints for agent operations.
|
|
149
|
+
|
|
150
|
+
Aggregates endpoints for running, stopping, checking status, and listing agents.
|
|
151
|
+
"""
|
|
152
|
+
return [
|
|
153
|
+
AgentsClient.agent_start_endpoint(),
|
|
154
|
+
AgentsClient.agent_stop_endpoint(),
|
|
155
|
+
AgentsClient.agent_status_endpoint(),
|
|
156
|
+
AgentsClient.agent_list_endpoint(),
|
|
157
|
+
AgentsClient.agent_replay_endpoint(),
|
|
158
|
+
]
|
|
159
|
+
|
|
160
|
+
@property
|
|
161
|
+
def agent_id(self) -> str | None:
|
|
162
|
+
"""
|
|
163
|
+
Returns the agent ID from the last agent response, or None if no response exists.
|
|
164
|
+
|
|
165
|
+
This property retrieves the identifier from the most recent agent operation response.
|
|
166
|
+
If no agent has been run or if the response is missing, it returns None.
|
|
167
|
+
"""
|
|
168
|
+
return self._last_agent_response.agent_id if self._last_agent_response is not None else None
|
|
169
|
+
|
|
170
|
+
def get_agent_id(self, agent_id: str | None = None) -> str:
|
|
171
|
+
"""
|
|
172
|
+
Retrieves the agent ID to be used for agent operations.
|
|
173
|
+
|
|
174
|
+
If an `agent_id` is provided, it is returned directly. Otherwise, the method attempts to obtain the agent ID from the client's last agent response. Raises a ValueError if no agent ID is available.
|
|
175
|
+
|
|
176
|
+
Args:
|
|
177
|
+
agent_id (Optional[str]): An agent identifier. If omitted, the ID from the last agent response is used.
|
|
178
|
+
|
|
179
|
+
Raises:
|
|
180
|
+
ValueError: If no agent ID is provided and the client has no recorded agent response.
|
|
181
|
+
|
|
182
|
+
Returns:
|
|
183
|
+
str: The determined agent identifier.
|
|
184
|
+
"""
|
|
185
|
+
if agent_id is None:
|
|
186
|
+
if self._last_agent_response is None:
|
|
187
|
+
raise ValueError("No agent to get agent id from")
|
|
188
|
+
agent_id = self._last_agent_response.agent_id
|
|
189
|
+
return agent_id
|
|
190
|
+
|
|
191
|
+
def start(self, **data: Unpack[AgentStartRequestDict]) -> AgentResponse:
|
|
192
|
+
"""
|
|
193
|
+
Start an agent with the specified request parameters.
|
|
194
|
+
|
|
195
|
+
Validates the provided data using the AgentRunRequest model, sends a run request through the
|
|
196
|
+
designated endpoint, updates the last agent response, and returns the resulting AgentResponse.
|
|
197
|
+
|
|
198
|
+
Args:
|
|
199
|
+
**data: Keyword arguments representing the fields of an AgentRunRequest.
|
|
200
|
+
|
|
201
|
+
Returns:
|
|
202
|
+
AgentResponse: The response obtained from the agent run request.
|
|
203
|
+
"""
|
|
204
|
+
request = AgentStartRequest.model_validate(data)
|
|
205
|
+
response = self.request(AgentsClient.agent_start_endpoint().with_request(request))
|
|
206
|
+
self._last_agent_response = response
|
|
207
|
+
return response
|
|
208
|
+
|
|
209
|
+
def wait(
|
|
210
|
+
self,
|
|
211
|
+
agent_id: str | None = None,
|
|
212
|
+
polling_interval_seconds: int = 10,
|
|
213
|
+
max_attempts: int = 30,
|
|
214
|
+
) -> AgentStatusResponse:
|
|
215
|
+
"""
|
|
216
|
+
Waits for the specified agent to complete.
|
|
217
|
+
|
|
218
|
+
Args:
|
|
219
|
+
agent_id: The identifier of the agent to wait for.
|
|
220
|
+
polling_interval_seconds: The interval between status checks.
|
|
221
|
+
max_attempts: The maximum number of attempts to check the agent's status.
|
|
222
|
+
|
|
223
|
+
Returns:
|
|
224
|
+
AgentStatusResponse: The response from the agent status check.
|
|
225
|
+
"""
|
|
226
|
+
agent_id = self.get_agent_id(agent_id)
|
|
227
|
+
last_step = 0
|
|
228
|
+
for _ in range(max_attempts):
|
|
229
|
+
response = self.status(agent_id=agent_id, replay=False)
|
|
230
|
+
if response.status == AgentStatus.closed:
|
|
231
|
+
return response
|
|
232
|
+
if len(response.steps) >= last_step:
|
|
233
|
+
for step in response.steps[last_step:]:
|
|
234
|
+
for action in step.actions:
|
|
235
|
+
logger.info(f"Executing action: {action}")
|
|
236
|
+
last_step = len(response.steps)
|
|
237
|
+
logger.info(
|
|
238
|
+
f"Waiting {polling_interval_seconds} seconds for agent to complete (current step: {last_step})..."
|
|
239
|
+
)
|
|
240
|
+
time.sleep(polling_interval_seconds)
|
|
241
|
+
raise TimeoutError("Agent did not complete in time")
|
|
242
|
+
|
|
243
|
+
def stop(self, agent_id: str) -> AgentResponse:
|
|
244
|
+
"""
|
|
245
|
+
Stops the specified agent and clears the last agent response.
|
|
246
|
+
|
|
247
|
+
Retrieves a valid agent identifier using the provided value or the last stored
|
|
248
|
+
response, sends a stop request to the API, resets the internal agent response,
|
|
249
|
+
and returns the resulting AgentResponse.
|
|
250
|
+
|
|
251
|
+
Args:
|
|
252
|
+
agent_id: The identifier of the agent to stop.
|
|
253
|
+
|
|
254
|
+
Returns:
|
|
255
|
+
AgentResponse: The response from the stop operation.
|
|
256
|
+
|
|
257
|
+
Raises:
|
|
258
|
+
ValueError: If a valid agent identifier cannot be determined.
|
|
259
|
+
"""
|
|
260
|
+
agent_id = self.get_agent_id(agent_id)
|
|
261
|
+
endpoint = AgentsClient.agent_stop_endpoint(agent_id=agent_id)
|
|
262
|
+
response = self.request(endpoint)
|
|
263
|
+
self._last_agent_response = None
|
|
264
|
+
return response
|
|
265
|
+
|
|
266
|
+
def run(self, **data: Unpack[AgentStartRequestDict]) -> AgentStatusResponse:
|
|
267
|
+
"""
|
|
268
|
+
Run an agent with the specified request parameters.
|
|
269
|
+
and wait for completion
|
|
270
|
+
|
|
271
|
+
Validates the provided data using the AgentCreateRequest model, sends a run request through the
|
|
272
|
+
designated endpoint, updates the last agent response, and returns the resulting AgentResponse.
|
|
273
|
+
"""
|
|
274
|
+
response = self.start(**data)
|
|
275
|
+
# wait for completion
|
|
276
|
+
return self.wait(agent_id=response.agent_id)
|
|
277
|
+
|
|
278
|
+
def status(self, **data: Unpack[AgentStatusRequestDict]) -> AgentStatusResponse:
|
|
279
|
+
"""
|
|
280
|
+
Retrieves the status of the specified agent.
|
|
281
|
+
|
|
282
|
+
Queries the API for the current status of an agent using a validated agent ID.
|
|
283
|
+
The provided ID is confirmed (or obtained from the last response if needed), and the
|
|
284
|
+
resulting status is stored internally before being returned.
|
|
285
|
+
|
|
286
|
+
Args:
|
|
287
|
+
agent_id: Unique identifier of the agent to check.
|
|
288
|
+
|
|
289
|
+
Returns:
|
|
290
|
+
AgentResponse: The current status information of the specified agent.
|
|
291
|
+
|
|
292
|
+
Raises:
|
|
293
|
+
ValueError: If no valid agent ID can be determined.
|
|
294
|
+
"""
|
|
295
|
+
agent_id = self.get_agent_id(data["agent_id"])
|
|
296
|
+
request = AgentStatusRequest.model_validate(data)
|
|
297
|
+
endpoint = AgentsClient.agent_status_endpoint(agent_id=agent_id).with_params(request)
|
|
298
|
+
response = self.request(endpoint)
|
|
299
|
+
self._last_agent_response = response
|
|
300
|
+
return response
|
|
301
|
+
|
|
302
|
+
def list(self, **data: Unpack[ListRequestDict]) -> Sequence[AgentResponse]:
|
|
303
|
+
"""
|
|
304
|
+
Lists agents matching specified criteria.
|
|
305
|
+
|
|
306
|
+
Validates the keyword arguments using the AgentListRequest model, constructs
|
|
307
|
+
the corresponding endpoint for listing agents, and returns a sequence of agent
|
|
308
|
+
responses.
|
|
309
|
+
|
|
310
|
+
Args:
|
|
311
|
+
data: Arbitrary keyword arguments representing filter criteria for agents.
|
|
312
|
+
|
|
313
|
+
Returns:
|
|
314
|
+
A sequence of AgentResponse objects.
|
|
315
|
+
"""
|
|
316
|
+
params = AgentListRequest.model_validate(data)
|
|
317
|
+
endpoint = AgentsClient.agent_list_endpoint(params=params)
|
|
318
|
+
return self.request_list(endpoint)
|
|
319
|
+
|
|
320
|
+
def replay(
|
|
321
|
+
self,
|
|
322
|
+
agent_id: str | None = None,
|
|
323
|
+
) -> WebpReplay:
|
|
324
|
+
"""
|
|
325
|
+
Downloads the replay for the specified agent in webp format.
|
|
326
|
+
|
|
327
|
+
Args:
|
|
328
|
+
agent_id: The identifier of the agent to download the replay for.
|
|
329
|
+
|
|
330
|
+
Returns:
|
|
331
|
+
WebpReplay: The replay file in webp format.
|
|
332
|
+
"""
|
|
333
|
+
agent_id = self.get_agent_id(agent_id)
|
|
334
|
+
endpoint = AgentsClient.agent_replay_endpoint(agent_id=agent_id)
|
|
335
|
+
file_bytes = self._request_file(endpoint, file_type="webp")
|
|
336
|
+
return WebpReplay(file_bytes)
|
|
337
|
+
|
|
338
|
+
|
|
339
|
+
@final
|
|
340
|
+
class RemoteAgentFactory:
|
|
341
|
+
"""
|
|
342
|
+
Factory for creating RemoteAgent instances.
|
|
343
|
+
|
|
344
|
+
This factory provides a convenient way to create RemoteAgent instances with
|
|
345
|
+
optional vault and session configurations. It handles the validation of
|
|
346
|
+
agent creation requests and sets up the appropriate connections.
|
|
347
|
+
|
|
348
|
+
Attributes:
|
|
349
|
+
client (AgentsClient): The client used to communicate with the Notte API.
|
|
350
|
+
"""
|
|
351
|
+
|
|
352
|
+
class RemoteAgent:
|
|
353
|
+
"""
|
|
354
|
+
A remote agent that can execute tasks through the Notte API.
|
|
355
|
+
|
|
356
|
+
This class provides an interface for running tasks, checking status, and managing replays
|
|
357
|
+
of agent executions. It maintains state about the current agent execution and provides
|
|
358
|
+
methods to interact with the agent through an AgentsClient.
|
|
359
|
+
|
|
360
|
+
Attributes:
|
|
361
|
+
request (AgentCreateRequest): The configuration request used to create this agent.
|
|
362
|
+
client (AgentsClient): The client used to communicate with the Notte API.
|
|
363
|
+
response (AgentResponse | None): The latest response from the agent execution.
|
|
364
|
+
"""
|
|
365
|
+
|
|
366
|
+
def __init__(self, client: AgentsClient, request: AgentCreateRequest) -> None:
|
|
367
|
+
"""
|
|
368
|
+
Initialize a new RemoteAgent instance.
|
|
369
|
+
|
|
370
|
+
Args:
|
|
371
|
+
client (AgentsClient): The client used to communicate with the Notte API.
|
|
372
|
+
request (AgentCreateRequest): The configuration request for this agent.
|
|
373
|
+
"""
|
|
374
|
+
self.request: AgentCreateRequest = request
|
|
375
|
+
self.client: AgentsClient = client
|
|
376
|
+
self.response: AgentResponse | None = None
|
|
377
|
+
|
|
378
|
+
@property
|
|
379
|
+
def agent_id(self) -> str:
|
|
380
|
+
"""
|
|
381
|
+
Get the ID of the current agent execution.
|
|
382
|
+
|
|
383
|
+
Returns:
|
|
384
|
+
str: The unique identifier of the current agent execution.
|
|
385
|
+
|
|
386
|
+
Raises:
|
|
387
|
+
ValueError: If the agent hasn't been run yet (no response available).
|
|
388
|
+
"""
|
|
389
|
+
if self.response is None:
|
|
390
|
+
raise ValueError("You need to run the agent first to get the agent id")
|
|
391
|
+
return self.response.agent_id
|
|
392
|
+
|
|
393
|
+
def start(self, **data: Unpack[AgentStartRequestDict]) -> AgentResponse:
|
|
394
|
+
"""
|
|
395
|
+
Start the agent with the specified request parameters.
|
|
396
|
+
"""
|
|
397
|
+
self.response = self.client.start(**self.request.model_dump(), **data)
|
|
398
|
+
return self.response
|
|
399
|
+
|
|
400
|
+
def wait(self) -> AgentStatusResponse:
|
|
401
|
+
"""
|
|
402
|
+
Wait for the agent to complete.
|
|
403
|
+
"""
|
|
404
|
+
return self.client.wait(agent_id=self.agent_id)
|
|
405
|
+
|
|
406
|
+
def stop(self) -> AgentResponse:
|
|
407
|
+
"""
|
|
408
|
+
Stop the agent.
|
|
409
|
+
"""
|
|
410
|
+
return self.client.stop(agent_id=self.agent_id)
|
|
411
|
+
|
|
412
|
+
def run(self, **data: Unpack[AgentRunRequestDict]) -> AgentStatusResponse:
|
|
413
|
+
"""
|
|
414
|
+
Execute a task with the agent.
|
|
415
|
+
|
|
416
|
+
Runs the specified task and waits for its completion. If a URL is provided,
|
|
417
|
+
the agent will start from that URL before executing the task.
|
|
418
|
+
|
|
419
|
+
Args:
|
|
420
|
+
task (str): The task description for the agent to execute.
|
|
421
|
+
url (str | None): Optional starting URL for the task.
|
|
422
|
+
|
|
423
|
+
Returns:
|
|
424
|
+
AgentResponse: The response from the completed agent execution.
|
|
425
|
+
"""
|
|
426
|
+
self.response = self.client.start(**self.request.model_dump(), **data)
|
|
427
|
+
return self.client.wait(agent_id=self.agent_id)
|
|
428
|
+
|
|
429
|
+
async def arun(self, **data: Unpack[AgentRunRequestDict]) -> AgentStatusResponse:
|
|
430
|
+
"""
|
|
431
|
+
Asynchronously execute a task with the agent.
|
|
432
|
+
|
|
433
|
+
This is currently a wrapper around the synchronous run method.
|
|
434
|
+
In future versions, this might be implemented as a true async operation.
|
|
435
|
+
|
|
436
|
+
Args:
|
|
437
|
+
task (str): The task description for the agent to execute.
|
|
438
|
+
url (str | None): Optional starting URL for the task.
|
|
439
|
+
|
|
440
|
+
Returns:
|
|
441
|
+
AgentResponse: The response from the completed agent execution.
|
|
442
|
+
"""
|
|
443
|
+
return self.run(**data)
|
|
444
|
+
|
|
445
|
+
def status(self) -> AgentStatusResponse:
|
|
446
|
+
"""
|
|
447
|
+
Get the current status of the agent.
|
|
448
|
+
|
|
449
|
+
Returns:
|
|
450
|
+
AgentStatusResponse: The current status of the agent execution.
|
|
451
|
+
|
|
452
|
+
Raises:
|
|
453
|
+
ValueError: If the agent hasn't been run yet (no agent_id available).
|
|
454
|
+
"""
|
|
455
|
+
return self.client.status(agent_id=self.agent_id)
|
|
456
|
+
|
|
457
|
+
def replay(self) -> WebpReplay:
|
|
458
|
+
"""
|
|
459
|
+
Get a replay of the agent's execution in WEBP format.
|
|
460
|
+
|
|
461
|
+
Returns:
|
|
462
|
+
WebpReplay: The replay data in WEBP format.
|
|
463
|
+
|
|
464
|
+
Raises:
|
|
465
|
+
ValueError: If the agent hasn't been run yet (no agent_id available).
|
|
466
|
+
"""
|
|
467
|
+
return self.client.replay(agent_id=self.agent_id)
|
|
468
|
+
|
|
469
|
+
def __init__(self, client: AgentsClient) -> None:
|
|
470
|
+
"""
|
|
471
|
+
Initialize a new RemoteAgentFactory instance.
|
|
472
|
+
|
|
473
|
+
Args:
|
|
474
|
+
client (AgentsClient): The client used to communicate with the Notte API.
|
|
475
|
+
"""
|
|
476
|
+
self.client = client
|
|
477
|
+
|
|
478
|
+
def __call__(
|
|
479
|
+
self,
|
|
480
|
+
vault: NotteVault | None = None,
|
|
481
|
+
session: RemoteSessionFactory.RemoteSession | None = None,
|
|
482
|
+
**data: Unpack[AgentCreateRequestDict],
|
|
483
|
+
) -> RemoteAgent:
|
|
484
|
+
"""
|
|
485
|
+
Create a new RemoteAgent instance with the specified configuration.
|
|
486
|
+
|
|
487
|
+
This method validates the agent creation request and sets up the appropriate
|
|
488
|
+
connections with the provided vault and session if specified.
|
|
489
|
+
|
|
490
|
+
Args:
|
|
491
|
+
vault (NotteVault | None): Optional vault for secure credential storage.
|
|
492
|
+
session (RemoteSessionFactory.RemoteSession | None): Optional session for persistent state.
|
|
493
|
+
**data: Additional keyword arguments for the agent creation request.
|
|
494
|
+
|
|
495
|
+
Returns:
|
|
496
|
+
RemoteAgent: A new RemoteAgent instance configured with the specified parameters.
|
|
497
|
+
"""
|
|
498
|
+
request = AgentCreateRequest.model_validate(data)
|
|
499
|
+
if vault is not None:
|
|
500
|
+
request.vault_id = vault.vault_id
|
|
501
|
+
request.persona_id = vault.persona_id
|
|
502
|
+
if session is not None:
|
|
503
|
+
request.session_id = session.session_id
|
|
504
|
+
return RemoteAgentFactory.RemoteAgent(self.client, request)
|