agi-python 0.0.1__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.
- agi/__init__.py +70 -0
- agi/_http.py +135 -0
- agi/_session_context.py +345 -0
- agi/_sse.py +77 -0
- agi/client.py +142 -0
- agi/exceptions.py +43 -0
- agi/py.typed +0 -0
- agi/resources/__init__.py +5 -0
- agi/resources/sessions.py +358 -0
- agi/types/__init__.py +39 -0
- agi/types/results.py +183 -0
- agi/types/sessions.py +119 -0
- agi/types/shared.py +26 -0
- agi_python-0.0.1.dist-info/METADATA +363 -0
- agi_python-0.0.1.dist-info/RECORD +18 -0
- agi_python-0.0.1.dist-info/WHEEL +5 -0
- agi_python-0.0.1.dist-info/licenses/LICENSE +21 -0
- agi_python-0.0.1.dist-info/top_level.txt +1 -0
agi/client.py
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
"""Main AGI API client."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
from typing import Any
|
|
7
|
+
|
|
8
|
+
from agi._http import HTTPClient
|
|
9
|
+
from agi._session_context import SessionContext
|
|
10
|
+
from agi.resources.sessions import SessionsResource
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class AGIClient:
|
|
14
|
+
"""Official Python client for the AGI.tech API.
|
|
15
|
+
|
|
16
|
+
The AGIClient provides access to the AGI API for creating and managing
|
|
17
|
+
AI agent sessions that can perform complex web tasks.
|
|
18
|
+
|
|
19
|
+
Example:
|
|
20
|
+
Simple usage with context manager (recommended):
|
|
21
|
+
|
|
22
|
+
>>> from agi import AGIClient
|
|
23
|
+
>>> client = AGIClient(api_key="your_api_key")
|
|
24
|
+
>>>
|
|
25
|
+
>>> with client.session("agi-0") as session:
|
|
26
|
+
... result = session.run_task("Find cheapest iPhone 15 on Amazon")
|
|
27
|
+
... print(result)
|
|
28
|
+
|
|
29
|
+
Advanced usage with direct API access:
|
|
30
|
+
|
|
31
|
+
>>> session = client.sessions.create(
|
|
32
|
+
... agent_name="agi-0",
|
|
33
|
+
... webhook_url="https://yourapp.com/webhook"
|
|
34
|
+
... )
|
|
35
|
+
>>> client.sessions.send_message(session.session_id, "Find flights...")
|
|
36
|
+
>>>
|
|
37
|
+
>>> for event in client.sessions.stream_events(session.session_id):
|
|
38
|
+
... if event.event == "thought":
|
|
39
|
+
... print(f"Agent: {event.data}")
|
|
40
|
+
... elif event.event == "done":
|
|
41
|
+
... break
|
|
42
|
+
>>>
|
|
43
|
+
>>> client.sessions.delete(session.session_id)
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
def __init__(
|
|
47
|
+
self,
|
|
48
|
+
api_key: str | None = None,
|
|
49
|
+
base_url: str = "https://api.agi.tech",
|
|
50
|
+
timeout: int = 60,
|
|
51
|
+
max_retries: int = 3,
|
|
52
|
+
):
|
|
53
|
+
"""Initialize the AGI API client.
|
|
54
|
+
|
|
55
|
+
Args:
|
|
56
|
+
api_key: API key for authentication. If not provided, will look
|
|
57
|
+
for AGI_API_KEY environment variable.
|
|
58
|
+
base_url: Base URL for the API (default: https://api.agi.tech)
|
|
59
|
+
timeout: Request timeout in seconds (default: 60)
|
|
60
|
+
max_retries: Maximum number of retry attempts for 5xx errors (default: 3)
|
|
61
|
+
|
|
62
|
+
Raises:
|
|
63
|
+
ValueError: If api_key is not provided and AGI_API_KEY env var is not set
|
|
64
|
+
|
|
65
|
+
Example:
|
|
66
|
+
>>> client = AGIClient(api_key="your_api_key")
|
|
67
|
+
>>> # Or use environment variable:
|
|
68
|
+
>>> import os
|
|
69
|
+
>>> os.environ["AGI_API_KEY"] = "your_api_key"
|
|
70
|
+
>>> client = AGIClient()
|
|
71
|
+
"""
|
|
72
|
+
self.api_key = api_key or os.getenv("AGI_API_KEY")
|
|
73
|
+
if not self.api_key:
|
|
74
|
+
raise ValueError(
|
|
75
|
+
"api_key is required. Either pass it as a parameter or set "
|
|
76
|
+
"the AGI_API_KEY environment variable."
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
self._http = HTTPClient(
|
|
80
|
+
api_key=self.api_key,
|
|
81
|
+
base_url=base_url,
|
|
82
|
+
timeout=timeout,
|
|
83
|
+
max_retries=max_retries,
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
self.sessions = SessionsResource(self._http)
|
|
87
|
+
|
|
88
|
+
def session(
|
|
89
|
+
self,
|
|
90
|
+
agent_name: str = "agi-0",
|
|
91
|
+
**kwargs: Any,
|
|
92
|
+
) -> SessionContext:
|
|
93
|
+
"""Create a session context manager for easy session lifecycle management.
|
|
94
|
+
|
|
95
|
+
This is the recommended way to use the SDK, matching the pattern shown
|
|
96
|
+
in the documentation. The context manager automatically creates and
|
|
97
|
+
deletes the session.
|
|
98
|
+
|
|
99
|
+
Args:
|
|
100
|
+
agent_name: Agent model to use (e.g., "agi-0", "agi-0-fast")
|
|
101
|
+
**kwargs: Additional session creation parameters:
|
|
102
|
+
- webhook_url (str): URL for session event notifications
|
|
103
|
+
- goal (str): Task goal to set upfront
|
|
104
|
+
- max_steps (int): Maximum number of agent steps (default: 100)
|
|
105
|
+
- restore_from_environment_id (str): Environment UUID to restore
|
|
106
|
+
|
|
107
|
+
Returns:
|
|
108
|
+
SessionContext manager
|
|
109
|
+
|
|
110
|
+
Example:
|
|
111
|
+
>>> with client.session("agi-0") as session:
|
|
112
|
+
... result = session.run_task("Find flights SFO→JFK under $450")
|
|
113
|
+
... print(result)
|
|
114
|
+
>>>
|
|
115
|
+
>>> # With webhook
|
|
116
|
+
>>> with client.session(
|
|
117
|
+
... "agi-0",
|
|
118
|
+
... webhook_url="https://yourapp.com/webhook"
|
|
119
|
+
... ) as session:
|
|
120
|
+
... result = session.run_task("Research company XYZ")
|
|
121
|
+
"""
|
|
122
|
+
return SessionContext(self, agent_name=agent_name, **kwargs)
|
|
123
|
+
|
|
124
|
+
def close(self) -> None:
|
|
125
|
+
"""Close the HTTP client and cleanup resources.
|
|
126
|
+
|
|
127
|
+
Note: Usually not needed as the client will cleanup automatically.
|
|
128
|
+
|
|
129
|
+
Example:
|
|
130
|
+
>>> client = AGIClient(api_key="...")
|
|
131
|
+
>>> # ... use client ...
|
|
132
|
+
>>> client.close()
|
|
133
|
+
"""
|
|
134
|
+
self._http.close()
|
|
135
|
+
|
|
136
|
+
def __enter__(self) -> AGIClient:
|
|
137
|
+
"""Support using AGIClient as a context manager."""
|
|
138
|
+
return self
|
|
139
|
+
|
|
140
|
+
def __exit__(self, *args: Any) -> None:
|
|
141
|
+
"""Cleanup when used as context manager."""
|
|
142
|
+
self.close()
|
agi/exceptions.py
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"""AGI SDK exceptions."""
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class AGIError(Exception):
|
|
5
|
+
"""Base exception for all AGI SDK errors."""
|
|
6
|
+
|
|
7
|
+
pass
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class AuthenticationError(AGIError):
|
|
11
|
+
"""401 - Invalid API key."""
|
|
12
|
+
|
|
13
|
+
pass
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class PermissionError(AGIError):
|
|
17
|
+
"""403 - Insufficient permissions."""
|
|
18
|
+
|
|
19
|
+
pass
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class NotFoundError(AGIError):
|
|
23
|
+
"""404 - Resource not found."""
|
|
24
|
+
|
|
25
|
+
pass
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class RateLimitError(AGIError):
|
|
29
|
+
"""429 - Rate limit exceeded."""
|
|
30
|
+
|
|
31
|
+
pass
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class APIError(AGIError):
|
|
35
|
+
"""5xx - Server error."""
|
|
36
|
+
|
|
37
|
+
pass
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class AgentExecutionError(AGIError):
|
|
41
|
+
"""Agent task execution failed."""
|
|
42
|
+
|
|
43
|
+
pass
|
agi/py.typed
ADDED
|
File without changes
|
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
"""Sessions API resource."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import builtins
|
|
6
|
+
from collections.abc import Iterator
|
|
7
|
+
from typing import TYPE_CHECKING, Any
|
|
8
|
+
|
|
9
|
+
from agi.types.sessions import (
|
|
10
|
+
DeleteResponse,
|
|
11
|
+
ExecuteStatusResponse,
|
|
12
|
+
MessagesResponse,
|
|
13
|
+
NavigateResponse,
|
|
14
|
+
ScreenshotResponse,
|
|
15
|
+
SessionResponse,
|
|
16
|
+
SSEEvent,
|
|
17
|
+
SuccessResponse,
|
|
18
|
+
)
|
|
19
|
+
from agi.types.shared import SnapshotMode
|
|
20
|
+
|
|
21
|
+
if TYPE_CHECKING:
|
|
22
|
+
from agi._http import HTTPClient
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class SessionsResource:
|
|
26
|
+
"""Sessions API resource providing all session-related operations."""
|
|
27
|
+
|
|
28
|
+
def __init__(self, http: HTTPClient):
|
|
29
|
+
"""Initialize sessions resource.
|
|
30
|
+
|
|
31
|
+
Args:
|
|
32
|
+
http: HTTP client instance
|
|
33
|
+
"""
|
|
34
|
+
self._http = http
|
|
35
|
+
|
|
36
|
+
# ===== SESSION MANAGEMENT (5 endpoints) =====
|
|
37
|
+
|
|
38
|
+
def create(
|
|
39
|
+
self,
|
|
40
|
+
agent_name: str = "agi-0",
|
|
41
|
+
webhook_url: str | None = None,
|
|
42
|
+
goal: str | None = None,
|
|
43
|
+
max_steps: int = 100,
|
|
44
|
+
restore_from_environment_id: str | None = None,
|
|
45
|
+
) -> SessionResponse:
|
|
46
|
+
"""Create a new agent session.
|
|
47
|
+
|
|
48
|
+
Args:
|
|
49
|
+
agent_name: Agent model to use (e.g., "agi-0", "agi-0-fast")
|
|
50
|
+
webhook_url: URL for session event notifications
|
|
51
|
+
goal: Task goal (optional, can be set later via send_message)
|
|
52
|
+
max_steps: Maximum number of agent steps (default: 100)
|
|
53
|
+
restore_from_environment_id: Environment UUID to restore from
|
|
54
|
+
|
|
55
|
+
Returns:
|
|
56
|
+
SessionResponse with session_id, vnc_url, status, etc.
|
|
57
|
+
|
|
58
|
+
Example:
|
|
59
|
+
>>> session = client.sessions.create(
|
|
60
|
+
... agent_name="agi-0",
|
|
61
|
+
... goal="Find cheapest iPhone 15 on Amazon"
|
|
62
|
+
... )
|
|
63
|
+
>>> print(session.session_id)
|
|
64
|
+
"""
|
|
65
|
+
payload = {
|
|
66
|
+
"agent_name": agent_name,
|
|
67
|
+
"max_steps": max_steps,
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if webhook_url is not None:
|
|
71
|
+
payload["webhook_url"] = webhook_url
|
|
72
|
+
if goal is not None:
|
|
73
|
+
payload["goal"] = goal
|
|
74
|
+
if restore_from_environment_id is not None:
|
|
75
|
+
payload["restore_from_environment_id"] = restore_from_environment_id
|
|
76
|
+
|
|
77
|
+
response = self._http.request("POST", "/v1/sessions", json=payload)
|
|
78
|
+
return SessionResponse(**response.json())
|
|
79
|
+
|
|
80
|
+
def list(self) -> list[SessionResponse]:
|
|
81
|
+
"""List all sessions for the authenticated user.
|
|
82
|
+
|
|
83
|
+
Returns:
|
|
84
|
+
List of SessionResponse objects
|
|
85
|
+
|
|
86
|
+
Example:
|
|
87
|
+
>>> sessions = client.sessions.list()
|
|
88
|
+
>>> for session in sessions:
|
|
89
|
+
... print(f"{session.session_id}: {session.status}")
|
|
90
|
+
"""
|
|
91
|
+
response = self._http.request("GET", "/v1/sessions")
|
|
92
|
+
return [SessionResponse(**s) for s in response.json()]
|
|
93
|
+
|
|
94
|
+
def get(self, session_id: str) -> SessionResponse:
|
|
95
|
+
"""Get details for a specific session.
|
|
96
|
+
|
|
97
|
+
Args:
|
|
98
|
+
session_id: Session UUID
|
|
99
|
+
|
|
100
|
+
Returns:
|
|
101
|
+
SessionResponse with session details
|
|
102
|
+
|
|
103
|
+
Raises:
|
|
104
|
+
NotFoundError: If session doesn't exist
|
|
105
|
+
|
|
106
|
+
Example:
|
|
107
|
+
>>> session = client.sessions.get("123e4567-e89b-12d3-a456-426614174000")
|
|
108
|
+
>>> print(session.status)
|
|
109
|
+
"""
|
|
110
|
+
response = self._http.request("GET", f"/v1/sessions/{session_id}")
|
|
111
|
+
return SessionResponse(**response.json())
|
|
112
|
+
|
|
113
|
+
def delete(
|
|
114
|
+
self,
|
|
115
|
+
session_id: str,
|
|
116
|
+
save_snapshot_mode: SnapshotMode = "none",
|
|
117
|
+
) -> DeleteResponse:
|
|
118
|
+
"""Delete a session and cleanup its resources.
|
|
119
|
+
|
|
120
|
+
Args:
|
|
121
|
+
session_id: Session UUID
|
|
122
|
+
save_snapshot_mode: Snapshot mode - "none", "memory", or "filesystem"
|
|
123
|
+
|
|
124
|
+
Returns:
|
|
125
|
+
DeleteResponse confirming deletion
|
|
126
|
+
|
|
127
|
+
Example:
|
|
128
|
+
>>> client.sessions.delete("123e4567-e89b-12d3-a456-426614174000")
|
|
129
|
+
"""
|
|
130
|
+
response = self._http.request(
|
|
131
|
+
"DELETE",
|
|
132
|
+
f"/v1/sessions/{session_id}",
|
|
133
|
+
params={"save_snapshot_mode": save_snapshot_mode},
|
|
134
|
+
)
|
|
135
|
+
return DeleteResponse(**response.json())
|
|
136
|
+
|
|
137
|
+
def delete_all(self) -> DeleteResponse:
|
|
138
|
+
"""Delete all sessions for the authenticated user.
|
|
139
|
+
|
|
140
|
+
Returns:
|
|
141
|
+
DeleteResponse with count of deleted sessions
|
|
142
|
+
|
|
143
|
+
Example:
|
|
144
|
+
>>> result = client.sessions.delete_all()
|
|
145
|
+
>>> print(result.message)
|
|
146
|
+
"""
|
|
147
|
+
response = self._http.request("DELETE", "/v1/sessions")
|
|
148
|
+
return DeleteResponse(**response.json())
|
|
149
|
+
|
|
150
|
+
# ===== AGENT INTERACTION (4 endpoints) =====
|
|
151
|
+
|
|
152
|
+
def send_message(
|
|
153
|
+
self,
|
|
154
|
+
session_id: str,
|
|
155
|
+
message: str,
|
|
156
|
+
start_url: str | None = None,
|
|
157
|
+
config_updates: dict[str, Any] | None = None,
|
|
158
|
+
) -> SuccessResponse:
|
|
159
|
+
"""Send a message to the agent to start a task or respond to questions.
|
|
160
|
+
|
|
161
|
+
Args:
|
|
162
|
+
session_id: Session UUID
|
|
163
|
+
message: Message content (task instruction or response)
|
|
164
|
+
start_url: Optional starting URL for the task
|
|
165
|
+
config_updates: Optional configuration updates
|
|
166
|
+
|
|
167
|
+
Returns:
|
|
168
|
+
SuccessResponse confirming message was sent
|
|
169
|
+
|
|
170
|
+
Example:
|
|
171
|
+
>>> client.sessions.send_message(
|
|
172
|
+
... session_id="123...",
|
|
173
|
+
... message="Find flights from SFO to JFK under $450"
|
|
174
|
+
... )
|
|
175
|
+
"""
|
|
176
|
+
payload: dict[str, Any] = {"message": message}
|
|
177
|
+
|
|
178
|
+
if start_url is not None:
|
|
179
|
+
payload["start_url"] = start_url
|
|
180
|
+
if config_updates is not None:
|
|
181
|
+
payload["config_updates"] = config_updates
|
|
182
|
+
|
|
183
|
+
response = self._http.request(
|
|
184
|
+
"POST",
|
|
185
|
+
f"/v1/sessions/{session_id}/message",
|
|
186
|
+
json=payload,
|
|
187
|
+
)
|
|
188
|
+
return SuccessResponse(**response.json())
|
|
189
|
+
|
|
190
|
+
def get_status(self, session_id: str) -> ExecuteStatusResponse:
|
|
191
|
+
"""Get the current execution status of a session.
|
|
192
|
+
|
|
193
|
+
Args:
|
|
194
|
+
session_id: Session UUID
|
|
195
|
+
|
|
196
|
+
Returns:
|
|
197
|
+
ExecuteStatusResponse with status ("running", "finished", etc.)
|
|
198
|
+
|
|
199
|
+
Example:
|
|
200
|
+
>>> status = client.sessions.get_status("123...")
|
|
201
|
+
>>> if status.status == "finished":
|
|
202
|
+
... print("Task completed!")
|
|
203
|
+
"""
|
|
204
|
+
response = self._http.request("GET", f"/v1/sessions/{session_id}/status")
|
|
205
|
+
return ExecuteStatusResponse(**response.json())
|
|
206
|
+
|
|
207
|
+
def get_messages(
|
|
208
|
+
self,
|
|
209
|
+
session_id: str,
|
|
210
|
+
after_id: int = 0,
|
|
211
|
+
sanitize: bool = True,
|
|
212
|
+
) -> MessagesResponse:
|
|
213
|
+
"""Poll for messages and updates from the agent.
|
|
214
|
+
|
|
215
|
+
Args:
|
|
216
|
+
session_id: Session UUID
|
|
217
|
+
after_id: Return messages with ID > after_id (for polling)
|
|
218
|
+
sanitize: Filter out system messages, prompts, and images
|
|
219
|
+
|
|
220
|
+
Returns:
|
|
221
|
+
MessagesResponse with messages list and status
|
|
222
|
+
|
|
223
|
+
Example:
|
|
224
|
+
>>> messages = client.sessions.get_messages("123...", after_id=0)
|
|
225
|
+
>>> for msg in messages.messages:
|
|
226
|
+
... print(f"[{msg.type}] {msg.content}")
|
|
227
|
+
"""
|
|
228
|
+
response = self._http.request(
|
|
229
|
+
"GET",
|
|
230
|
+
f"/v1/sessions/{session_id}/messages",
|
|
231
|
+
params={"after_id": after_id, "sanitize": sanitize},
|
|
232
|
+
)
|
|
233
|
+
return MessagesResponse(**response.json())
|
|
234
|
+
|
|
235
|
+
def stream_events(
|
|
236
|
+
self,
|
|
237
|
+
session_id: str,
|
|
238
|
+
event_types: builtins.list[str] | None = None,
|
|
239
|
+
sanitize: bool = True,
|
|
240
|
+
include_history: bool = True,
|
|
241
|
+
) -> Iterator[SSEEvent]:
|
|
242
|
+
"""Stream real-time events from the session via Server-Sent Events.
|
|
243
|
+
|
|
244
|
+
Args:
|
|
245
|
+
session_id: Session UUID
|
|
246
|
+
event_types: Filter specific event types (e.g., ["thought", "done"])
|
|
247
|
+
sanitize: Filter out system messages
|
|
248
|
+
include_history: Include historical messages on connection
|
|
249
|
+
|
|
250
|
+
Yields:
|
|
251
|
+
SSEEvent objects with id, event type, and data
|
|
252
|
+
|
|
253
|
+
Example:
|
|
254
|
+
>>> for event in client.sessions.stream_events("123..."):
|
|
255
|
+
... if event.event == "thought":
|
|
256
|
+
... print(f"Agent: {event.data}")
|
|
257
|
+
... elif event.event == "done":
|
|
258
|
+
... print(f"Result: {event.data}")
|
|
259
|
+
... break
|
|
260
|
+
"""
|
|
261
|
+
from agi._sse import SSEClient
|
|
262
|
+
|
|
263
|
+
sse = SSEClient(self._http)
|
|
264
|
+
params: dict[str, Any] = {
|
|
265
|
+
"sanitize": sanitize,
|
|
266
|
+
"include_history": include_history,
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
if event_types:
|
|
270
|
+
params["event_types"] = ",".join(event_types)
|
|
271
|
+
|
|
272
|
+
yield from sse.stream(f"/v1/sessions/{session_id}/events", params=params)
|
|
273
|
+
|
|
274
|
+
# ===== SESSION CONTROL (3 endpoints) =====
|
|
275
|
+
|
|
276
|
+
def pause(self, session_id: str) -> SuccessResponse:
|
|
277
|
+
"""Temporarily pause task execution.
|
|
278
|
+
|
|
279
|
+
Args:
|
|
280
|
+
session_id: Session UUID
|
|
281
|
+
|
|
282
|
+
Returns:
|
|
283
|
+
SuccessResponse confirming pause
|
|
284
|
+
|
|
285
|
+
Example:
|
|
286
|
+
>>> client.sessions.pause("123...")
|
|
287
|
+
"""
|
|
288
|
+
response = self._http.request("POST", f"/v1/sessions/{session_id}/pause")
|
|
289
|
+
return SuccessResponse(**response.json())
|
|
290
|
+
|
|
291
|
+
def resume(self, session_id: str) -> SuccessResponse:
|
|
292
|
+
"""Resume a paused task.
|
|
293
|
+
|
|
294
|
+
Args:
|
|
295
|
+
session_id: Session UUID
|
|
296
|
+
|
|
297
|
+
Returns:
|
|
298
|
+
SuccessResponse confirming resume
|
|
299
|
+
|
|
300
|
+
Example:
|
|
301
|
+
>>> client.sessions.resume("123...")
|
|
302
|
+
"""
|
|
303
|
+
response = self._http.request("POST", f"/v1/sessions/{session_id}/resume")
|
|
304
|
+
return SuccessResponse(**response.json())
|
|
305
|
+
|
|
306
|
+
def cancel(self, session_id: str) -> SuccessResponse:
|
|
307
|
+
"""Cancel task execution.
|
|
308
|
+
|
|
309
|
+
Args:
|
|
310
|
+
session_id: Session UUID
|
|
311
|
+
|
|
312
|
+
Returns:
|
|
313
|
+
SuccessResponse confirming cancellation
|
|
314
|
+
|
|
315
|
+
Example:
|
|
316
|
+
>>> client.sessions.cancel("123...")
|
|
317
|
+
"""
|
|
318
|
+
response = self._http.request("POST", f"/v1/sessions/{session_id}/cancel")
|
|
319
|
+
return SuccessResponse(**response.json())
|
|
320
|
+
|
|
321
|
+
# ===== BROWSER CONTROL (2 endpoints) =====
|
|
322
|
+
|
|
323
|
+
def navigate(self, session_id: str, url: str) -> NavigateResponse:
|
|
324
|
+
"""Navigate the browser to a specific URL.
|
|
325
|
+
|
|
326
|
+
Args:
|
|
327
|
+
session_id: Session UUID
|
|
328
|
+
url: URL to navigate to
|
|
329
|
+
|
|
330
|
+
Returns:
|
|
331
|
+
NavigateResponse with current URL
|
|
332
|
+
|
|
333
|
+
Example:
|
|
334
|
+
>>> client.sessions.navigate("123...", "https://amazon.com")
|
|
335
|
+
"""
|
|
336
|
+
response = self._http.request(
|
|
337
|
+
"POST",
|
|
338
|
+
f"/v1/sessions/{session_id}/navigate",
|
|
339
|
+
json={"url": url},
|
|
340
|
+
)
|
|
341
|
+
return NavigateResponse(**response.json())
|
|
342
|
+
|
|
343
|
+
def screenshot(self, session_id: str) -> ScreenshotResponse:
|
|
344
|
+
"""Get a screenshot of the browser.
|
|
345
|
+
|
|
346
|
+
Args:
|
|
347
|
+
session_id: Session UUID
|
|
348
|
+
|
|
349
|
+
Returns:
|
|
350
|
+
ScreenshotResponse with base64-encoded image, URL, and title
|
|
351
|
+
|
|
352
|
+
Example:
|
|
353
|
+
>>> screenshot = client.sessions.screenshot("123...")
|
|
354
|
+
>>> print(screenshot.url)
|
|
355
|
+
>>> # screenshot.screenshot contains base64 JPEG data
|
|
356
|
+
"""
|
|
357
|
+
response = self._http.request("GET", f"/v1/sessions/{session_id}/screenshot")
|
|
358
|
+
return ScreenshotResponse(**response.json())
|
agi/types/__init__.py
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"""Type definitions for AGI SDK."""
|
|
2
|
+
|
|
3
|
+
from agi.types.results import Screenshot, TaskMetadata, TaskResult
|
|
4
|
+
from agi.types.sessions import (
|
|
5
|
+
CreateSessionRequest,
|
|
6
|
+
DeleteResponse,
|
|
7
|
+
ExecuteStatusResponse,
|
|
8
|
+
MessageResponse,
|
|
9
|
+
MessagesResponse,
|
|
10
|
+
NavigateRequest,
|
|
11
|
+
NavigateResponse,
|
|
12
|
+
ScreenshotResponse,
|
|
13
|
+
SendMessageRequest,
|
|
14
|
+
SessionResponse,
|
|
15
|
+
SSEEvent,
|
|
16
|
+
SuccessResponse,
|
|
17
|
+
)
|
|
18
|
+
from agi.types.shared import EventType, MessageType, SessionStatus
|
|
19
|
+
|
|
20
|
+
__all__ = [
|
|
21
|
+
"CreateSessionRequest",
|
|
22
|
+
"DeleteResponse",
|
|
23
|
+
"ExecuteStatusResponse",
|
|
24
|
+
"MessageResponse",
|
|
25
|
+
"MessagesResponse",
|
|
26
|
+
"NavigateRequest",
|
|
27
|
+
"NavigateResponse",
|
|
28
|
+
"Screenshot",
|
|
29
|
+
"ScreenshotResponse",
|
|
30
|
+
"SendMessageRequest",
|
|
31
|
+
"SessionResponse",
|
|
32
|
+
"SSEEvent",
|
|
33
|
+
"SuccessResponse",
|
|
34
|
+
"TaskMetadata",
|
|
35
|
+
"TaskResult",
|
|
36
|
+
"EventType",
|
|
37
|
+
"MessageType",
|
|
38
|
+
"SessionStatus",
|
|
39
|
+
]
|