agno 2.3.16__py3-none-any.whl → 2.3.18__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.
- agno/agent/__init__.py +2 -0
- agno/agent/agent.py +4 -53
- agno/agent/remote.py +351 -0
- agno/client/__init__.py +3 -0
- agno/client/os.py +2669 -0
- agno/db/base.py +20 -0
- agno/db/mongo/async_mongo.py +11 -0
- agno/db/mongo/mongo.py +10 -0
- agno/db/mysql/async_mysql.py +9 -0
- agno/db/mysql/mysql.py +9 -0
- agno/db/postgres/async_postgres.py +9 -0
- agno/db/postgres/postgres.py +9 -0
- agno/db/postgres/utils.py +3 -2
- agno/db/sqlite/async_sqlite.py +9 -0
- agno/db/sqlite/sqlite.py +11 -1
- agno/exceptions.py +23 -0
- agno/knowledge/chunking/semantic.py +123 -46
- agno/knowledge/reader/csv_reader.py +1 -1
- agno/knowledge/reader/field_labeled_csv_reader.py +1 -1
- agno/knowledge/reader/json_reader.py +1 -1
- agno/models/google/gemini.py +5 -0
- agno/os/app.py +108 -25
- agno/os/auth.py +25 -1
- agno/os/interfaces/a2a/a2a.py +7 -6
- agno/os/interfaces/a2a/router.py +13 -13
- agno/os/interfaces/agui/agui.py +5 -3
- agno/os/interfaces/agui/router.py +23 -16
- agno/os/interfaces/base.py +7 -7
- agno/os/interfaces/slack/router.py +6 -6
- agno/os/interfaces/slack/slack.py +7 -7
- agno/os/interfaces/whatsapp/router.py +29 -6
- agno/os/interfaces/whatsapp/whatsapp.py +11 -8
- agno/os/managers.py +326 -0
- agno/os/mcp.py +651 -79
- agno/os/router.py +125 -18
- agno/os/routers/agents/router.py +65 -22
- agno/os/routers/agents/schema.py +16 -4
- agno/os/routers/database.py +5 -0
- agno/os/routers/evals/evals.py +93 -11
- agno/os/routers/evals/utils.py +6 -6
- agno/os/routers/knowledge/knowledge.py +104 -16
- agno/os/routers/memory/memory.py +124 -7
- agno/os/routers/metrics/metrics.py +21 -4
- agno/os/routers/session/session.py +141 -12
- agno/os/routers/teams/router.py +40 -14
- agno/os/routers/teams/schema.py +12 -4
- agno/os/routers/traces/traces.py +54 -4
- agno/os/routers/workflows/router.py +223 -117
- agno/os/routers/workflows/schema.py +65 -1
- agno/os/schema.py +38 -12
- agno/os/utils.py +87 -166
- agno/remote/__init__.py +3 -0
- agno/remote/base.py +484 -0
- agno/run/workflow.py +1 -0
- agno/team/__init__.py +2 -0
- agno/team/remote.py +287 -0
- agno/team/team.py +25 -54
- agno/tracing/exporter.py +10 -6
- agno/tracing/setup.py +2 -1
- agno/utils/agent.py +58 -1
- agno/utils/http.py +68 -20
- agno/utils/os.py +0 -0
- agno/utils/remote.py +23 -0
- agno/vectordb/chroma/chromadb.py +452 -16
- agno/vectordb/pgvector/pgvector.py +7 -0
- agno/vectordb/redis/redisdb.py +1 -1
- agno/workflow/__init__.py +2 -0
- agno/workflow/agent.py +2 -2
- agno/workflow/remote.py +222 -0
- agno/workflow/types.py +0 -73
- agno/workflow/workflow.py +119 -68
- {agno-2.3.16.dist-info → agno-2.3.18.dist-info}/METADATA +1 -1
- {agno-2.3.16.dist-info → agno-2.3.18.dist-info}/RECORD +76 -66
- {agno-2.3.16.dist-info → agno-2.3.18.dist-info}/WHEEL +0 -0
- {agno-2.3.16.dist-info → agno-2.3.18.dist-info}/licenses/LICENSE +0 -0
- {agno-2.3.16.dist-info → agno-2.3.18.dist-info}/top_level.txt +0 -0
agno/agent/__init__.py
CHANGED
|
@@ -5,6 +5,7 @@ from agno.agent.agent import (
|
|
|
5
5
|
Message,
|
|
6
6
|
Toolkit,
|
|
7
7
|
)
|
|
8
|
+
from agno.agent.remote import RemoteAgent
|
|
8
9
|
from agno.run.agent import (
|
|
9
10
|
MemoryUpdateCompletedEvent,
|
|
10
11
|
MemoryUpdateStartedEvent,
|
|
@@ -27,6 +28,7 @@ from agno.run.agent import (
|
|
|
27
28
|
|
|
28
29
|
__all__ = [
|
|
29
30
|
"Agent",
|
|
31
|
+
"RemoteAgent",
|
|
30
32
|
"AgentSession",
|
|
31
33
|
"Function",
|
|
32
34
|
"Message",
|
agno/agent/agent.py
CHANGED
|
@@ -103,11 +103,12 @@ from agno.utils.agent import (
|
|
|
103
103
|
set_session_name_util,
|
|
104
104
|
store_media_util,
|
|
105
105
|
update_session_state_util,
|
|
106
|
+
validate_input,
|
|
106
107
|
validate_media_object_id,
|
|
107
108
|
wait_for_open_threads,
|
|
108
109
|
wait_for_thread_tasks_stream,
|
|
109
110
|
)
|
|
110
|
-
from agno.utils.common import is_typed_dict
|
|
111
|
+
from agno.utils.common import is_typed_dict
|
|
111
112
|
from agno.utils.events import (
|
|
112
113
|
add_error_event,
|
|
113
114
|
create_parser_model_response_completed_event,
|
|
@@ -762,56 +763,6 @@ class Agent:
|
|
|
762
763
|
log_info("Setting default model to OpenAI Chat")
|
|
763
764
|
self.model = OpenAIChat(id="gpt-4o")
|
|
764
765
|
|
|
765
|
-
def _validate_input(
|
|
766
|
-
self, input: Union[str, List, Dict, Message, BaseModel]
|
|
767
|
-
) -> Union[str, List, Dict, Message, BaseModel]:
|
|
768
|
-
"""Parse and validate input against input_schema if provided, otherwise return input as-is"""
|
|
769
|
-
if self.input_schema is None:
|
|
770
|
-
return input # Return input unchanged if no schema is set
|
|
771
|
-
|
|
772
|
-
# Handle Message objects - extract content
|
|
773
|
-
if isinstance(input, Message):
|
|
774
|
-
input = input.content # type: ignore
|
|
775
|
-
|
|
776
|
-
# If input is a string, convert it to a dict
|
|
777
|
-
if isinstance(input, str):
|
|
778
|
-
import json
|
|
779
|
-
|
|
780
|
-
try:
|
|
781
|
-
input = json.loads(input)
|
|
782
|
-
except Exception as e:
|
|
783
|
-
raise ValueError(f"Failed to parse input. Is it a valid JSON string?: {e}")
|
|
784
|
-
|
|
785
|
-
# Case 1: Message is already a BaseModel instance
|
|
786
|
-
if isinstance(input, BaseModel):
|
|
787
|
-
if isinstance(input, self.input_schema):
|
|
788
|
-
try:
|
|
789
|
-
return input
|
|
790
|
-
except Exception as e:
|
|
791
|
-
raise ValueError(f"BaseModel validation failed: {str(e)}")
|
|
792
|
-
else:
|
|
793
|
-
# Different BaseModel types
|
|
794
|
-
raise ValueError(f"Expected {self.input_schema.__name__} but got {type(input).__name__}")
|
|
795
|
-
|
|
796
|
-
# Case 2: Message is a dict
|
|
797
|
-
elif isinstance(input, dict):
|
|
798
|
-
try:
|
|
799
|
-
# Check if the schema is a TypedDict
|
|
800
|
-
if is_typed_dict(self.input_schema):
|
|
801
|
-
validated_dict = validate_typed_dict(input, self.input_schema)
|
|
802
|
-
return validated_dict
|
|
803
|
-
else:
|
|
804
|
-
validated_model = self.input_schema(**input)
|
|
805
|
-
return validated_model
|
|
806
|
-
except Exception as e:
|
|
807
|
-
raise ValueError(f"Failed to parse dict into {self.input_schema.__name__}: {str(e)}")
|
|
808
|
-
|
|
809
|
-
# Case 3: Other types not supported for structured input
|
|
810
|
-
else:
|
|
811
|
-
raise ValueError(
|
|
812
|
-
f"Cannot validate {type(input)} against input_schema. Expected dict or {self.input_schema.__name__} instance."
|
|
813
|
-
)
|
|
814
|
-
|
|
815
766
|
def _set_culture_manager(self) -> None:
|
|
816
767
|
if self.db is None:
|
|
817
768
|
log_warning("Database not provided. Cultural knowledge will not be stored.")
|
|
@@ -1654,7 +1605,7 @@ class Agent:
|
|
|
1654
1605
|
background_tasks: BackgroundTasks = background_tasks # type: ignore
|
|
1655
1606
|
|
|
1656
1607
|
# Validate input against input_schema if provided
|
|
1657
|
-
validated_input = self.
|
|
1608
|
+
validated_input = validate_input(input, self.input_schema)
|
|
1658
1609
|
|
|
1659
1610
|
# Normalise hook & guardails
|
|
1660
1611
|
if not self._hooks_normalised:
|
|
@@ -2828,7 +2779,7 @@ class Agent:
|
|
|
2828
2779
|
background_tasks: BackgroundTasks = background_tasks # type: ignore
|
|
2829
2780
|
|
|
2830
2781
|
# 2. Validate input against input_schema if provided
|
|
2831
|
-
validated_input = self.
|
|
2782
|
+
validated_input = validate_input(input, self.input_schema)
|
|
2832
2783
|
|
|
2833
2784
|
# Normalise hooks & guardails
|
|
2834
2785
|
if not self._hooks_normalised:
|
agno/agent/remote.py
ADDED
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import time
|
|
3
|
+
from dataclasses import dataclass, field
|
|
4
|
+
from typing import TYPE_CHECKING, Any, AsyncIterator, Dict, List, Literal, Optional, Sequence, Tuple, Union, overload
|
|
5
|
+
|
|
6
|
+
from pydantic import BaseModel
|
|
7
|
+
|
|
8
|
+
from agno.media import Audio, File, Image, Video
|
|
9
|
+
from agno.models.base import Model
|
|
10
|
+
from agno.models.message import Message
|
|
11
|
+
from agno.models.response import ToolExecution
|
|
12
|
+
from agno.remote.base import BaseRemote, RemoteDb, RemoteKnowledge
|
|
13
|
+
from agno.run.agent import RunOutput, RunOutputEvent
|
|
14
|
+
from agno.utils.agent import validate_input
|
|
15
|
+
from agno.utils.log import log_warning
|
|
16
|
+
from agno.utils.remote import serialize_input
|
|
17
|
+
|
|
18
|
+
if TYPE_CHECKING:
|
|
19
|
+
from agno.os.routers.agents.schema import AgentResponse
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@dataclass
|
|
23
|
+
class RemoteAgent(BaseRemote):
|
|
24
|
+
# Private cache for agent config with TTL: (config, timestamp)
|
|
25
|
+
_cached_agent_config: Optional[Tuple["AgentResponse", float]] = field(default=None, init=False, repr=False)
|
|
26
|
+
|
|
27
|
+
def __init__(
|
|
28
|
+
self,
|
|
29
|
+
base_url: str,
|
|
30
|
+
agent_id: str,
|
|
31
|
+
timeout: float = 60.0,
|
|
32
|
+
config_ttl: float = 300.0,
|
|
33
|
+
):
|
|
34
|
+
"""Initialize AgentOSRunner for local or remote execution.
|
|
35
|
+
|
|
36
|
+
For remote execution, provide base_url and agent_id.
|
|
37
|
+
|
|
38
|
+
Args:
|
|
39
|
+
base_url: Base URL for remote AgentOS instance (e.g., "http://localhost:7777")
|
|
40
|
+
agent_id: ID of remote agent
|
|
41
|
+
timeout: Request timeout in seconds (default: 60)
|
|
42
|
+
config_ttl: Time-to-live for cached config in seconds (default: 300)
|
|
43
|
+
"""
|
|
44
|
+
super().__init__(base_url, timeout, config_ttl)
|
|
45
|
+
self.agent_id = agent_id
|
|
46
|
+
self._cached_agent_config = None
|
|
47
|
+
|
|
48
|
+
@property
|
|
49
|
+
def id(self) -> str:
|
|
50
|
+
return self.agent_id
|
|
51
|
+
|
|
52
|
+
async def get_agent_config(self) -> "AgentResponse":
|
|
53
|
+
"""Get the agent config from remote (always fetches fresh)."""
|
|
54
|
+
return await self.client.aget_agent(self.agent_id)
|
|
55
|
+
|
|
56
|
+
@property
|
|
57
|
+
def _agent_config(self) -> "AgentResponse":
|
|
58
|
+
"""Get the agent config from remote, cached with TTL."""
|
|
59
|
+
from agno.os.routers.agents.schema import AgentResponse
|
|
60
|
+
|
|
61
|
+
current_time = time.time()
|
|
62
|
+
|
|
63
|
+
# Check if cache is valid
|
|
64
|
+
if self._cached_agent_config is not None:
|
|
65
|
+
config, cached_at = self._cached_agent_config
|
|
66
|
+
if current_time - cached_at < self.config_ttl:
|
|
67
|
+
return config
|
|
68
|
+
|
|
69
|
+
# Fetch fresh config
|
|
70
|
+
config: AgentResponse = self.client.get_agent(self.agent_id) # type: ignore
|
|
71
|
+
self._cached_agent_config = (config, current_time)
|
|
72
|
+
return config
|
|
73
|
+
|
|
74
|
+
def refresh_config(self) -> "AgentResponse":
|
|
75
|
+
"""Force refresh the cached agent config."""
|
|
76
|
+
from agno.os.routers.agents.schema import AgentResponse
|
|
77
|
+
|
|
78
|
+
config: AgentResponse = self.client.get_agent(self.agent_id)
|
|
79
|
+
self._cached_agent_config = (config, time.time())
|
|
80
|
+
return config
|
|
81
|
+
|
|
82
|
+
@property
|
|
83
|
+
def name(self) -> Optional[str]:
|
|
84
|
+
if self._agent_config is not None:
|
|
85
|
+
return self._agent_config.name
|
|
86
|
+
return self.agent_id
|
|
87
|
+
|
|
88
|
+
@property
|
|
89
|
+
def description(self) -> Optional[str]:
|
|
90
|
+
if self._agent_config is not None:
|
|
91
|
+
return self._agent_config.description
|
|
92
|
+
return ""
|
|
93
|
+
|
|
94
|
+
@property
|
|
95
|
+
def role(self) -> Optional[str]:
|
|
96
|
+
if self._agent_config is not None:
|
|
97
|
+
return self._agent_config.role
|
|
98
|
+
return None
|
|
99
|
+
|
|
100
|
+
@property
|
|
101
|
+
def tools(self) -> Optional[List[Dict[str, Any]]]:
|
|
102
|
+
if self._agent_config is not None:
|
|
103
|
+
try:
|
|
104
|
+
return json.loads(self._agent_config.tools["tools"]) if self._agent_config.tools else None
|
|
105
|
+
except Exception as e:
|
|
106
|
+
log_warning(f"Failed to load tools for agent {self.agent_id}: {e}")
|
|
107
|
+
return None
|
|
108
|
+
return None
|
|
109
|
+
|
|
110
|
+
@property
|
|
111
|
+
def db(self) -> Optional[RemoteDb]:
|
|
112
|
+
if self._agent_config is not None and self._agent_config.db_id is not None:
|
|
113
|
+
return RemoteDb.from_config(
|
|
114
|
+
db_id=self._agent_config.db_id,
|
|
115
|
+
client=self.client,
|
|
116
|
+
config=self._config,
|
|
117
|
+
)
|
|
118
|
+
return None
|
|
119
|
+
|
|
120
|
+
@property
|
|
121
|
+
def knowledge(self) -> Optional[RemoteKnowledge]:
|
|
122
|
+
"""Whether the agent has knowledge enabled."""
|
|
123
|
+
if self._agent_config is not None and self._agent_config.knowledge is not None:
|
|
124
|
+
return RemoteKnowledge(
|
|
125
|
+
client=self.client,
|
|
126
|
+
contents_db=RemoteDb(
|
|
127
|
+
id=self._agent_config.knowledge.get("db_id"), # type: ignore
|
|
128
|
+
client=self.client,
|
|
129
|
+
knowledge_table_name=self._agent_config.knowledge.get("knowledge_table"),
|
|
130
|
+
)
|
|
131
|
+
if self._agent_config.knowledge.get("db_id") is not None
|
|
132
|
+
else None,
|
|
133
|
+
)
|
|
134
|
+
return None
|
|
135
|
+
|
|
136
|
+
@property
|
|
137
|
+
def model(self) -> Optional[Model]:
|
|
138
|
+
# We don't expose the remote agent's models, since they can't be used by other services in AgentOS.
|
|
139
|
+
return None
|
|
140
|
+
|
|
141
|
+
async def aget_tools(self, **kwargs: Any) -> List[Dict]:
|
|
142
|
+
if self._agent_config.tools is not None:
|
|
143
|
+
return json.loads(self._agent_config.tools["tools"])
|
|
144
|
+
return []
|
|
145
|
+
|
|
146
|
+
@overload
|
|
147
|
+
async def arun(
|
|
148
|
+
self,
|
|
149
|
+
input: Union[str, List, Dict, Message, BaseModel, List[Message]],
|
|
150
|
+
*,
|
|
151
|
+
stream: Literal[False] = False,
|
|
152
|
+
user_id: Optional[str] = None,
|
|
153
|
+
session_id: Optional[str] = None,
|
|
154
|
+
session_state: Optional[Dict[str, Any]] = None,
|
|
155
|
+
audio: Optional[Sequence[Audio]] = None,
|
|
156
|
+
images: Optional[Sequence[Image]] = None,
|
|
157
|
+
videos: Optional[Sequence[Video]] = None,
|
|
158
|
+
files: Optional[Sequence[File]] = None,
|
|
159
|
+
stream_events: Optional[bool] = None,
|
|
160
|
+
retries: Optional[int] = None,
|
|
161
|
+
knowledge_filters: Optional[Dict[str, Any]] = None,
|
|
162
|
+
add_history_to_context: Optional[bool] = None,
|
|
163
|
+
add_dependencies_to_context: Optional[bool] = None,
|
|
164
|
+
add_session_state_to_context: Optional[bool] = None,
|
|
165
|
+
dependencies: Optional[Dict[str, Any]] = None,
|
|
166
|
+
metadata: Optional[Dict[str, Any]] = None,
|
|
167
|
+
auth_token: Optional[str] = None,
|
|
168
|
+
**kwargs: Any,
|
|
169
|
+
) -> RunOutput: ...
|
|
170
|
+
|
|
171
|
+
@overload
|
|
172
|
+
def arun(
|
|
173
|
+
self,
|
|
174
|
+
input: Union[str, List, Dict, Message, BaseModel, List[Message]],
|
|
175
|
+
*,
|
|
176
|
+
stream: Literal[True] = True,
|
|
177
|
+
user_id: Optional[str] = None,
|
|
178
|
+
session_id: Optional[str] = None,
|
|
179
|
+
audio: Optional[Sequence[Audio]] = None,
|
|
180
|
+
images: Optional[Sequence[Image]] = None,
|
|
181
|
+
videos: Optional[Sequence[Video]] = None,
|
|
182
|
+
files: Optional[Sequence[File]] = None,
|
|
183
|
+
stream_events: Optional[bool] = None,
|
|
184
|
+
retries: Optional[int] = None,
|
|
185
|
+
knowledge_filters: Optional[Dict[str, Any]] = None,
|
|
186
|
+
add_history_to_context: Optional[bool] = None,
|
|
187
|
+
add_dependencies_to_context: Optional[bool] = None,
|
|
188
|
+
add_session_state_to_context: Optional[bool] = None,
|
|
189
|
+
dependencies: Optional[Dict[str, Any]] = None,
|
|
190
|
+
metadata: Optional[Dict[str, Any]] = None,
|
|
191
|
+
auth_token: Optional[str] = None,
|
|
192
|
+
**kwargs: Any,
|
|
193
|
+
) -> AsyncIterator[RunOutputEvent]: ...
|
|
194
|
+
|
|
195
|
+
def arun( # type: ignore
|
|
196
|
+
self,
|
|
197
|
+
input: Union[str, List, Dict, Message, BaseModel, List[Message]],
|
|
198
|
+
*,
|
|
199
|
+
stream: Optional[bool] = None,
|
|
200
|
+
user_id: Optional[str] = None,
|
|
201
|
+
session_id: Optional[str] = None,
|
|
202
|
+
session_state: Optional[Dict[str, Any]] = None,
|
|
203
|
+
audio: Optional[Sequence[Audio]] = None,
|
|
204
|
+
images: Optional[Sequence[Image]] = None,
|
|
205
|
+
videos: Optional[Sequence[Video]] = None,
|
|
206
|
+
files: Optional[Sequence[File]] = None,
|
|
207
|
+
stream_events: Optional[bool] = None,
|
|
208
|
+
retries: Optional[int] = None,
|
|
209
|
+
knowledge_filters: Optional[Dict[str, Any]] = None,
|
|
210
|
+
add_history_to_context: Optional[bool] = None,
|
|
211
|
+
add_dependencies_to_context: Optional[bool] = None,
|
|
212
|
+
add_session_state_to_context: Optional[bool] = None,
|
|
213
|
+
dependencies: Optional[Dict[str, Any]] = None,
|
|
214
|
+
metadata: Optional[Dict[str, Any]] = None,
|
|
215
|
+
auth_token: Optional[str] = None,
|
|
216
|
+
**kwargs: Any,
|
|
217
|
+
) -> Union[
|
|
218
|
+
RunOutput,
|
|
219
|
+
AsyncIterator[RunOutputEvent],
|
|
220
|
+
]:
|
|
221
|
+
validated_input = validate_input(input)
|
|
222
|
+
serialized_input = serialize_input(validated_input)
|
|
223
|
+
headers = self._get_auth_headers(auth_token)
|
|
224
|
+
|
|
225
|
+
if stream:
|
|
226
|
+
# Handle streaming response
|
|
227
|
+
return self.get_client().run_agent_stream(
|
|
228
|
+
agent_id=self.agent_id,
|
|
229
|
+
message=serialized_input,
|
|
230
|
+
session_id=session_id,
|
|
231
|
+
user_id=user_id,
|
|
232
|
+
audio=audio,
|
|
233
|
+
images=images,
|
|
234
|
+
videos=videos,
|
|
235
|
+
files=files,
|
|
236
|
+
session_state=session_state,
|
|
237
|
+
stream_events=stream_events,
|
|
238
|
+
retries=retries,
|
|
239
|
+
knowledge_filters=knowledge_filters,
|
|
240
|
+
add_history_to_context=add_history_to_context,
|
|
241
|
+
add_dependencies_to_context=add_dependencies_to_context,
|
|
242
|
+
add_session_state_to_context=add_session_state_to_context,
|
|
243
|
+
dependencies=dependencies,
|
|
244
|
+
metadata=metadata,
|
|
245
|
+
headers=headers,
|
|
246
|
+
**kwargs,
|
|
247
|
+
)
|
|
248
|
+
else:
|
|
249
|
+
return self.get_client().run_agent( # type: ignore
|
|
250
|
+
agent_id=self.agent_id,
|
|
251
|
+
message=serialized_input,
|
|
252
|
+
session_id=session_id,
|
|
253
|
+
user_id=user_id,
|
|
254
|
+
audio=audio,
|
|
255
|
+
images=images,
|
|
256
|
+
videos=videos,
|
|
257
|
+
files=files,
|
|
258
|
+
session_state=session_state,
|
|
259
|
+
stream_events=stream_events,
|
|
260
|
+
retries=retries,
|
|
261
|
+
knowledge_filters=knowledge_filters,
|
|
262
|
+
add_history_to_context=add_history_to_context,
|
|
263
|
+
add_dependencies_to_context=add_dependencies_to_context,
|
|
264
|
+
add_session_state_to_context=add_session_state_to_context,
|
|
265
|
+
dependencies=dependencies,
|
|
266
|
+
metadata=metadata,
|
|
267
|
+
headers=headers,
|
|
268
|
+
**kwargs,
|
|
269
|
+
)
|
|
270
|
+
|
|
271
|
+
@overload
|
|
272
|
+
async def acontinue_run(
|
|
273
|
+
self,
|
|
274
|
+
run_id: str,
|
|
275
|
+
updated_tools: List[ToolExecution],
|
|
276
|
+
stream: Literal[False] = False,
|
|
277
|
+
user_id: Optional[str] = None,
|
|
278
|
+
session_id: Optional[str] = None,
|
|
279
|
+
auth_token: Optional[str] = None,
|
|
280
|
+
**kwargs: Any,
|
|
281
|
+
) -> RunOutput: ...
|
|
282
|
+
|
|
283
|
+
@overload
|
|
284
|
+
def acontinue_run(
|
|
285
|
+
self,
|
|
286
|
+
run_id: str,
|
|
287
|
+
updated_tools: List[ToolExecution],
|
|
288
|
+
stream: Literal[True] = True,
|
|
289
|
+
user_id: Optional[str] = None,
|
|
290
|
+
session_id: Optional[str] = None,
|
|
291
|
+
auth_token: Optional[str] = None,
|
|
292
|
+
**kwargs: Any,
|
|
293
|
+
) -> AsyncIterator[RunOutputEvent]: ...
|
|
294
|
+
|
|
295
|
+
def acontinue_run( # type: ignore
|
|
296
|
+
self,
|
|
297
|
+
run_id: str, # type: ignore
|
|
298
|
+
updated_tools: List[ToolExecution],
|
|
299
|
+
stream: Optional[bool] = None,
|
|
300
|
+
user_id: Optional[str] = None,
|
|
301
|
+
session_id: Optional[str] = None,
|
|
302
|
+
auth_token: Optional[str] = None,
|
|
303
|
+
**kwargs: Any,
|
|
304
|
+
) -> Union[
|
|
305
|
+
RunOutput,
|
|
306
|
+
AsyncIterator[RunOutputEvent],
|
|
307
|
+
]:
|
|
308
|
+
headers = self._get_auth_headers(auth_token)
|
|
309
|
+
|
|
310
|
+
if stream:
|
|
311
|
+
# Handle streaming response
|
|
312
|
+
return self.get_client().continue_agent_run_stream( # type: ignore
|
|
313
|
+
agent_id=self.agent_id,
|
|
314
|
+
run_id=run_id,
|
|
315
|
+
user_id=user_id,
|
|
316
|
+
session_id=session_id,
|
|
317
|
+
tools=updated_tools,
|
|
318
|
+
headers=headers,
|
|
319
|
+
**kwargs,
|
|
320
|
+
)
|
|
321
|
+
else:
|
|
322
|
+
return self.get_client().continue_agent_run( # type: ignore
|
|
323
|
+
agent_id=self.agent_id,
|
|
324
|
+
run_id=run_id,
|
|
325
|
+
tools=updated_tools,
|
|
326
|
+
user_id=user_id,
|
|
327
|
+
session_id=session_id,
|
|
328
|
+
headers=headers,
|
|
329
|
+
**kwargs,
|
|
330
|
+
)
|
|
331
|
+
|
|
332
|
+
async def cancel_run(self, run_id: str, auth_token: Optional[str] = None) -> bool:
|
|
333
|
+
"""Cancel a running agent execution.
|
|
334
|
+
|
|
335
|
+
Args:
|
|
336
|
+
run_id (str): The run_id to cancel.
|
|
337
|
+
auth_token: Optional JWT token for authentication.
|
|
338
|
+
|
|
339
|
+
Returns:
|
|
340
|
+
bool: True if the run was successfully cancelled, False otherwise.
|
|
341
|
+
"""
|
|
342
|
+
headers = self._get_auth_headers(auth_token)
|
|
343
|
+
try:
|
|
344
|
+
await self.get_client().cancel_agent_run(
|
|
345
|
+
agent_id=self.agent_id,
|
|
346
|
+
run_id=run_id,
|
|
347
|
+
headers=headers,
|
|
348
|
+
)
|
|
349
|
+
return True
|
|
350
|
+
except Exception:
|
|
351
|
+
return False
|
agno/client/__init__.py
ADDED