agno 2.2.13__py3-none-any.whl → 2.3.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.
- agno/agent/agent.py +197 -110
- agno/api/api.py +2 -0
- agno/db/base.py +26 -0
- agno/db/dynamo/dynamo.py +8 -0
- agno/db/dynamo/schemas.py +1 -0
- agno/db/firestore/firestore.py +8 -0
- agno/db/firestore/schemas.py +1 -0
- agno/db/gcs_json/gcs_json_db.py +8 -0
- agno/db/in_memory/in_memory_db.py +8 -1
- agno/db/json/json_db.py +8 -0
- agno/db/migrations/manager.py +199 -0
- agno/db/migrations/versions/__init__.py +0 -0
- agno/db/migrations/versions/v2_3_0.py +938 -0
- agno/db/mongo/async_mongo.py +16 -6
- agno/db/mongo/mongo.py +11 -0
- agno/db/mongo/schemas.py +3 -0
- agno/db/mongo/utils.py +17 -0
- agno/db/mysql/mysql.py +76 -3
- agno/db/mysql/schemas.py +20 -10
- agno/db/postgres/async_postgres.py +99 -25
- agno/db/postgres/postgres.py +75 -6
- agno/db/postgres/schemas.py +30 -20
- agno/db/redis/redis.py +15 -2
- agno/db/redis/schemas.py +4 -0
- agno/db/schemas/memory.py +13 -0
- agno/db/singlestore/schemas.py +11 -0
- agno/db/singlestore/singlestore.py +79 -5
- agno/db/sqlite/async_sqlite.py +97 -19
- agno/db/sqlite/schemas.py +10 -0
- agno/db/sqlite/sqlite.py +79 -2
- agno/db/surrealdb/surrealdb.py +8 -0
- agno/knowledge/chunking/semantic.py +7 -2
- agno/knowledge/embedder/nebius.py +1 -1
- agno/knowledge/knowledge.py +57 -86
- agno/knowledge/reader/csv_reader.py +7 -9
- agno/knowledge/reader/docx_reader.py +5 -5
- agno/knowledge/reader/field_labeled_csv_reader.py +16 -18
- agno/knowledge/reader/json_reader.py +5 -4
- agno/knowledge/reader/markdown_reader.py +8 -8
- agno/knowledge/reader/pdf_reader.py +11 -11
- agno/knowledge/reader/pptx_reader.py +5 -5
- agno/knowledge/reader/s3_reader.py +3 -3
- agno/knowledge/reader/text_reader.py +8 -8
- agno/knowledge/reader/web_search_reader.py +1 -48
- agno/knowledge/reader/website_reader.py +10 -10
- agno/models/anthropic/claude.py +319 -28
- agno/models/aws/claude.py +32 -0
- agno/models/azure/openai_chat.py +19 -10
- agno/models/base.py +612 -545
- agno/models/cerebras/cerebras.py +8 -11
- agno/models/cohere/chat.py +27 -1
- agno/models/google/gemini.py +39 -7
- agno/models/groq/groq.py +25 -11
- agno/models/meta/llama.py +20 -9
- agno/models/meta/llama_openai.py +3 -19
- agno/models/nebius/nebius.py +4 -4
- agno/models/openai/chat.py +30 -14
- agno/models/openai/responses.py +10 -13
- agno/models/response.py +1 -0
- agno/models/vertexai/claude.py +26 -0
- agno/os/app.py +8 -19
- agno/os/router.py +54 -0
- agno/os/routers/knowledge/knowledge.py +2 -2
- agno/os/schema.py +2 -2
- agno/session/agent.py +57 -92
- agno/session/summary.py +1 -1
- agno/session/team.py +62 -112
- agno/session/workflow.py +353 -57
- agno/team/team.py +227 -125
- agno/tools/models/nebius.py +5 -5
- agno/tools/models_labs.py +20 -10
- agno/tools/nano_banana.py +151 -0
- agno/tools/yfinance.py +12 -11
- agno/utils/http.py +111 -0
- agno/utils/media.py +11 -0
- agno/utils/models/claude.py +8 -0
- agno/utils/print_response/agent.py +33 -12
- agno/utils/print_response/team.py +22 -12
- agno/vectordb/couchbase/couchbase.py +6 -2
- agno/workflow/condition.py +13 -0
- agno/workflow/loop.py +13 -0
- agno/workflow/parallel.py +13 -0
- agno/workflow/router.py +13 -0
- agno/workflow/step.py +120 -20
- agno/workflow/steps.py +13 -0
- agno/workflow/workflow.py +76 -63
- {agno-2.2.13.dist-info → agno-2.3.1.dist-info}/METADATA +6 -2
- {agno-2.2.13.dist-info → agno-2.3.1.dist-info}/RECORD +91 -88
- agno/tools/googlesearch.py +0 -98
- {agno-2.2.13.dist-info → agno-2.3.1.dist-info}/WHEEL +0 -0
- {agno-2.2.13.dist-info → agno-2.3.1.dist-info}/licenses/LICENSE +0 -0
- {agno-2.2.13.dist-info → agno-2.3.1.dist-info}/top_level.txt +0 -0
|
@@ -25,6 +25,7 @@ def print_response(
|
|
|
25
25
|
show_message: bool = True,
|
|
26
26
|
show_reasoning: bool = True,
|
|
27
27
|
show_full_reasoning: bool = False,
|
|
28
|
+
show_member_responses: Optional[bool] = None,
|
|
28
29
|
tags_to_include_in_markdown: Optional[Set[str]] = None,
|
|
29
30
|
session_id: Optional[str] = None,
|
|
30
31
|
session_state: Optional[Dict[str, Any]] = None,
|
|
@@ -85,6 +86,7 @@ def print_response(
|
|
|
85
86
|
videos=videos,
|
|
86
87
|
files=files,
|
|
87
88
|
stream=False,
|
|
89
|
+
stream_events=True,
|
|
88
90
|
session_id=session_id,
|
|
89
91
|
session_state=session_state,
|
|
90
92
|
user_id=user_id,
|
|
@@ -152,7 +154,7 @@ def print_response(
|
|
|
152
154
|
|
|
153
155
|
if isinstance(run_response, TeamRunOutput):
|
|
154
156
|
# Handle member responses
|
|
155
|
-
if
|
|
157
|
+
if show_member_responses:
|
|
156
158
|
for member_response in run_response.member_responses:
|
|
157
159
|
# Handle member reasoning
|
|
158
160
|
reasoning_steps = []
|
|
@@ -323,6 +325,7 @@ def print_response_stream(
|
|
|
323
325
|
show_message: bool = True,
|
|
324
326
|
show_reasoning: bool = True,
|
|
325
327
|
show_full_reasoning: bool = False,
|
|
328
|
+
show_member_responses: Optional[bool] = None,
|
|
326
329
|
tags_to_include_in_markdown: Optional[Set[str]] = None,
|
|
327
330
|
session_id: Optional[str] = None,
|
|
328
331
|
session_state: Optional[Dict[str, Any]] = None,
|
|
@@ -412,7 +415,7 @@ def print_response_stream(
|
|
|
412
415
|
add_session_state_to_context=add_session_state_to_context,
|
|
413
416
|
metadata=metadata,
|
|
414
417
|
debug_mode=debug_mode,
|
|
415
|
-
|
|
418
|
+
yield_run_output=True,
|
|
416
419
|
**kwargs,
|
|
417
420
|
)
|
|
418
421
|
|
|
@@ -470,7 +473,7 @@ def print_response_stream(
|
|
|
470
473
|
team_tool_calls.append(tool)
|
|
471
474
|
|
|
472
475
|
# Collect member tool calls, avoiding duplicates
|
|
473
|
-
if hasattr(resp, "member_responses") and resp.member_responses:
|
|
476
|
+
if show_member_responses and hasattr(resp, "member_responses") and resp.member_responses:
|
|
474
477
|
for member_response in resp.member_responses:
|
|
475
478
|
member_id = None
|
|
476
479
|
if isinstance(member_response, RunOutput) and member_response.agent_id is not None:
|
|
@@ -532,7 +535,9 @@ def print_response_stream(
|
|
|
532
535
|
panels.append(status)
|
|
533
536
|
|
|
534
537
|
# Process member responses and their tool calls
|
|
535
|
-
for member_response in
|
|
538
|
+
for member_response in (
|
|
539
|
+
resp.member_responses if show_member_responses and hasattr(resp, "member_responses") else []
|
|
540
|
+
):
|
|
536
541
|
member_id = None
|
|
537
542
|
member_name = "Team Member"
|
|
538
543
|
if isinstance(member_response, RunOutput) and member_response.agent_id is not None:
|
|
@@ -565,7 +570,7 @@ def print_response_stream(
|
|
|
565
570
|
panels.append(member_tool_calls_panel)
|
|
566
571
|
|
|
567
572
|
# Process member response content
|
|
568
|
-
if
|
|
573
|
+
if show_member_responses and member_id is not None:
|
|
569
574
|
show_markdown = False
|
|
570
575
|
if markdown:
|
|
571
576
|
show_markdown = True
|
|
@@ -708,7 +713,7 @@ def print_response_stream(
|
|
|
708
713
|
final_panels.append(thinking_panel)
|
|
709
714
|
|
|
710
715
|
# Add member tool calls and responses in correct order
|
|
711
|
-
if run_response is not None and hasattr(run_response, "member_responses"):
|
|
716
|
+
if show_member_responses and run_response is not None and hasattr(run_response, "member_responses"):
|
|
712
717
|
for i, member_response in enumerate(run_response.member_responses): # type: ignore
|
|
713
718
|
member_id = None
|
|
714
719
|
if isinstance(member_response, RunOutput) and member_response.agent_id is not None:
|
|
@@ -857,6 +862,7 @@ async def aprint_response(
|
|
|
857
862
|
show_message: bool = True,
|
|
858
863
|
show_reasoning: bool = True,
|
|
859
864
|
show_full_reasoning: bool = False,
|
|
865
|
+
show_member_responses: Optional[bool] = None,
|
|
860
866
|
tags_to_include_in_markdown: Optional[Set[str]] = None,
|
|
861
867
|
session_id: Optional[str] = None,
|
|
862
868
|
session_state: Optional[Dict[str, Any]] = None,
|
|
@@ -917,6 +923,7 @@ async def aprint_response(
|
|
|
917
923
|
videos=videos,
|
|
918
924
|
files=files,
|
|
919
925
|
stream=False,
|
|
926
|
+
stream_events=True,
|
|
920
927
|
session_id=session_id,
|
|
921
928
|
session_state=session_state,
|
|
922
929
|
user_id=user_id,
|
|
@@ -984,7 +991,7 @@ async def aprint_response(
|
|
|
984
991
|
|
|
985
992
|
if isinstance(run_response, TeamRunOutput):
|
|
986
993
|
# Handle member responses
|
|
987
|
-
if
|
|
994
|
+
if show_member_responses:
|
|
988
995
|
for member_response in run_response.member_responses:
|
|
989
996
|
# Handle member reasoning
|
|
990
997
|
reasoning_steps = []
|
|
@@ -1153,6 +1160,7 @@ async def aprint_response_stream(
|
|
|
1153
1160
|
show_message: bool = True,
|
|
1154
1161
|
show_reasoning: bool = True,
|
|
1155
1162
|
show_full_reasoning: bool = False,
|
|
1163
|
+
show_member_responses: Optional[bool] = None,
|
|
1156
1164
|
tags_to_include_in_markdown: Optional[Set[str]] = None,
|
|
1157
1165
|
session_id: Optional[str] = None,
|
|
1158
1166
|
session_state: Optional[Dict[str, Any]] = None,
|
|
@@ -1252,7 +1260,7 @@ async def aprint_response_stream(
|
|
|
1252
1260
|
dependencies=dependencies,
|
|
1253
1261
|
metadata=metadata,
|
|
1254
1262
|
debug_mode=debug_mode,
|
|
1255
|
-
|
|
1263
|
+
yield_run_output=True,
|
|
1256
1264
|
**kwargs,
|
|
1257
1265
|
):
|
|
1258
1266
|
if team_markdown is None:
|
|
@@ -1299,7 +1307,7 @@ async def aprint_response_stream(
|
|
|
1299
1307
|
team_tool_calls.append(tool)
|
|
1300
1308
|
|
|
1301
1309
|
# Collect member tool calls, avoiding duplicates
|
|
1302
|
-
if hasattr(resp, "member_responses") and resp.member_responses:
|
|
1310
|
+
if show_member_responses and hasattr(resp, "member_responses") and resp.member_responses:
|
|
1303
1311
|
for member_response in resp.member_responses:
|
|
1304
1312
|
member_id = None
|
|
1305
1313
|
if isinstance(member_response, RunOutput) and member_response.agent_id is not None:
|
|
@@ -1360,7 +1368,9 @@ async def aprint_response_stream(
|
|
|
1360
1368
|
panels.append(status)
|
|
1361
1369
|
|
|
1362
1370
|
# Process member responses and their tool calls
|
|
1363
|
-
for member_response in
|
|
1371
|
+
for member_response in (
|
|
1372
|
+
resp.member_responses if show_member_responses and hasattr(resp, "member_responses") else []
|
|
1373
|
+
):
|
|
1364
1374
|
member_id = None
|
|
1365
1375
|
member_name = "Team Member"
|
|
1366
1376
|
if isinstance(member_response, RunOutput) and member_response.agent_id is not None:
|
|
@@ -1393,7 +1403,7 @@ async def aprint_response_stream(
|
|
|
1393
1403
|
panels.append(member_tool_calls_panel)
|
|
1394
1404
|
|
|
1395
1405
|
# Process member response content
|
|
1396
|
-
if
|
|
1406
|
+
if show_member_responses and member_id is not None:
|
|
1397
1407
|
show_markdown = False
|
|
1398
1408
|
if markdown:
|
|
1399
1409
|
show_markdown = True
|
|
@@ -1537,7 +1547,7 @@ async def aprint_response_stream(
|
|
|
1537
1547
|
final_panels.append(thinking_panel)
|
|
1538
1548
|
|
|
1539
1549
|
# Add member tool calls and responses in correct order
|
|
1540
|
-
if run_response is not None and hasattr(run_response, "member_responses"):
|
|
1550
|
+
if show_member_responses and run_response is not None and hasattr(run_response, "member_responses"):
|
|
1541
1551
|
for i, member_response in enumerate(run_response.member_responses):
|
|
1542
1552
|
member_id = None
|
|
1543
1553
|
if isinstance(member_response, RunOutput) and member_response.agent_id is not None:
|
|
@@ -6,7 +6,6 @@ from typing import Any, Dict, List, Optional, Union
|
|
|
6
6
|
from agno.filters import FilterExpr
|
|
7
7
|
from agno.knowledge.document import Document
|
|
8
8
|
from agno.knowledge.embedder import Embedder
|
|
9
|
-
from agno.knowledge.embedder.openai import OpenAIEmbedder
|
|
10
9
|
from agno.utils.log import log_debug, log_info, log_warning, logger
|
|
11
10
|
from agno.vectordb.base import VectorDb
|
|
12
11
|
|
|
@@ -62,7 +61,7 @@ class CouchbaseSearch(VectorDb):
|
|
|
62
61
|
couchbase_connection_string: str,
|
|
63
62
|
cluster_options: ClusterOptions,
|
|
64
63
|
search_index: Union[str, SearchIndex],
|
|
65
|
-
embedder: Embedder =
|
|
64
|
+
embedder: Optional[Embedder] = None,
|
|
66
65
|
overwrite: bool = False,
|
|
67
66
|
is_global_level_index: bool = False,
|
|
68
67
|
wait_until_index_ready: float = 0,
|
|
@@ -97,6 +96,11 @@ class CouchbaseSearch(VectorDb):
|
|
|
97
96
|
self.collection_name = collection_name
|
|
98
97
|
self.connection_string = couchbase_connection_string
|
|
99
98
|
self.cluster_options = cluster_options
|
|
99
|
+
if embedder is None:
|
|
100
|
+
from agno.knowledge.embedder.openai import OpenAIEmbedder
|
|
101
|
+
|
|
102
|
+
embedder = OpenAIEmbedder()
|
|
103
|
+
log_info("Embedder not provided, using OpenAIEmbedder as default.")
|
|
100
104
|
self.embedder = embedder
|
|
101
105
|
self.overwrite = overwrite
|
|
102
106
|
self.is_global_level_index = is_global_level_index
|
agno/workflow/condition.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import inspect
|
|
2
|
+
import warnings
|
|
2
3
|
from dataclasses import dataclass
|
|
3
4
|
from typing import Any, AsyncIterator, Awaitable, Callable, Dict, Iterator, List, Optional, Union
|
|
4
5
|
from uuid import uuid4
|
|
@@ -313,6 +314,12 @@ class Condition:
|
|
|
313
314
|
log_debug(f"Condition {self.name} evaluated to: {condition_result}")
|
|
314
315
|
|
|
315
316
|
# Considering both stream_events and stream_intermediate_steps (deprecated)
|
|
317
|
+
if stream_intermediate_steps is not None:
|
|
318
|
+
warnings.warn(
|
|
319
|
+
"The 'stream_intermediate_steps' parameter is deprecated and will be removed in future versions. Use 'stream_events' instead.",
|
|
320
|
+
DeprecationWarning,
|
|
321
|
+
stacklevel=2,
|
|
322
|
+
)
|
|
316
323
|
stream_events = stream_events or stream_intermediate_steps
|
|
317
324
|
|
|
318
325
|
if stream_events and workflow_run_response:
|
|
@@ -595,6 +602,12 @@ class Condition:
|
|
|
595
602
|
log_debug(f"Condition {self.name} evaluated to: {condition_result}")
|
|
596
603
|
|
|
597
604
|
# Considering both stream_events and stream_intermediate_steps (deprecated)
|
|
605
|
+
if stream_intermediate_steps is not None:
|
|
606
|
+
warnings.warn(
|
|
607
|
+
"The 'stream_intermediate_steps' parameter is deprecated and will be removed in future versions. Use 'stream_events' instead.",
|
|
608
|
+
DeprecationWarning,
|
|
609
|
+
stacklevel=2,
|
|
610
|
+
)
|
|
598
611
|
stream_events = stream_events or stream_intermediate_steps
|
|
599
612
|
|
|
600
613
|
if stream_events and workflow_run_response:
|
agno/workflow/loop.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import inspect
|
|
2
|
+
import warnings
|
|
2
3
|
from dataclasses import dataclass
|
|
3
4
|
from typing import Any, AsyncIterator, Awaitable, Callable, Dict, Iterator, List, Optional, Union
|
|
4
5
|
from uuid import uuid4
|
|
@@ -251,6 +252,12 @@ class Loop:
|
|
|
251
252
|
loop_step_id = str(uuid4())
|
|
252
253
|
|
|
253
254
|
# Considering both stream_events and stream_intermediate_steps (deprecated)
|
|
255
|
+
if stream_intermediate_steps is not None:
|
|
256
|
+
warnings.warn(
|
|
257
|
+
"The 'stream_intermediate_steps' parameter is deprecated and will be removed in future versions. Use 'stream_events' instead.",
|
|
258
|
+
DeprecationWarning,
|
|
259
|
+
stacklevel=2,
|
|
260
|
+
)
|
|
254
261
|
stream_events = stream_events or stream_intermediate_steps
|
|
255
262
|
|
|
256
263
|
if stream_events and workflow_run_response:
|
|
@@ -556,6 +563,12 @@ class Loop:
|
|
|
556
563
|
self._prepare_steps()
|
|
557
564
|
|
|
558
565
|
# Considering both stream_events and stream_intermediate_steps (deprecated)
|
|
566
|
+
if stream_intermediate_steps is not None:
|
|
567
|
+
warnings.warn(
|
|
568
|
+
"The 'stream_intermediate_steps' parameter is deprecated and will be removed in future versions. Use 'stream_events' instead.",
|
|
569
|
+
DeprecationWarning,
|
|
570
|
+
stacklevel=2,
|
|
571
|
+
)
|
|
559
572
|
stream_events = stream_events or stream_intermediate_steps
|
|
560
573
|
|
|
561
574
|
if stream_events and workflow_run_response:
|
agno/workflow/parallel.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import asyncio
|
|
2
|
+
import warnings
|
|
2
3
|
from concurrent.futures import ThreadPoolExecutor, as_completed
|
|
3
4
|
from copy import deepcopy
|
|
4
5
|
from dataclasses import dataclass
|
|
@@ -356,6 +357,12 @@ class Parallel:
|
|
|
356
357
|
session_state_copies.append({})
|
|
357
358
|
|
|
358
359
|
# Considering both stream_events and stream_intermediate_steps (deprecated)
|
|
360
|
+
if stream_intermediate_steps is not None:
|
|
361
|
+
warnings.warn(
|
|
362
|
+
"The 'stream_intermediate_steps' parameter is deprecated and will be removed in future versions. Use 'stream_events' instead.",
|
|
363
|
+
DeprecationWarning,
|
|
364
|
+
stacklevel=2,
|
|
365
|
+
)
|
|
359
366
|
stream_events = stream_events or stream_intermediate_steps
|
|
360
367
|
|
|
361
368
|
if stream_events and workflow_run_response:
|
|
@@ -676,6 +683,12 @@ class Parallel:
|
|
|
676
683
|
session_state_copies.append({})
|
|
677
684
|
|
|
678
685
|
# Considering both stream_events and stream_intermediate_steps (deprecated)
|
|
686
|
+
if stream_intermediate_steps is not None:
|
|
687
|
+
warnings.warn(
|
|
688
|
+
"The 'stream_intermediate_steps' parameter is deprecated and will be removed in future versions. Use 'stream_events' instead.",
|
|
689
|
+
DeprecationWarning,
|
|
690
|
+
stacklevel=2,
|
|
691
|
+
)
|
|
679
692
|
stream_events = stream_events or stream_intermediate_steps
|
|
680
693
|
|
|
681
694
|
if stream_events and workflow_run_response:
|
agno/workflow/router.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import inspect
|
|
2
|
+
import warnings
|
|
2
3
|
from dataclasses import dataclass
|
|
3
4
|
from typing import Any, AsyncIterator, Awaitable, Callable, Dict, Iterator, List, Optional, Union
|
|
4
5
|
from uuid import uuid4
|
|
@@ -300,6 +301,12 @@ class Router:
|
|
|
300
301
|
log_debug(f"Router {self.name}: Selected {len(steps_to_execute)} steps to execute")
|
|
301
302
|
|
|
302
303
|
# Considering both stream_events and stream_intermediate_steps (deprecated)
|
|
304
|
+
if stream_intermediate_steps is not None:
|
|
305
|
+
warnings.warn(
|
|
306
|
+
"The 'stream_intermediate_steps' parameter is deprecated and will be removed in future versions. Use 'stream_events' instead.",
|
|
307
|
+
DeprecationWarning,
|
|
308
|
+
stacklevel=2,
|
|
309
|
+
)
|
|
303
310
|
stream_events = stream_events or stream_intermediate_steps
|
|
304
311
|
|
|
305
312
|
if stream_events and workflow_run_response:
|
|
@@ -567,6 +574,12 @@ class Router:
|
|
|
567
574
|
log_debug(f"Router {self.name} selected: {len(steps_to_execute)} steps to execute")
|
|
568
575
|
|
|
569
576
|
# Considering both stream_events and stream_intermediate_steps (deprecated)
|
|
577
|
+
if stream_intermediate_steps is not None:
|
|
578
|
+
warnings.warn(
|
|
579
|
+
"The 'stream_intermediate_steps' parameter is deprecated and will be removed in future versions. Use 'stream_events' instead.",
|
|
580
|
+
DeprecationWarning,
|
|
581
|
+
stacklevel=2,
|
|
582
|
+
)
|
|
570
583
|
stream_events = stream_events or stream_intermediate_steps
|
|
571
584
|
|
|
572
585
|
if stream_events and workflow_run_response:
|
agno/workflow/step.py
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import inspect
|
|
2
|
+
import warnings
|
|
2
3
|
from copy import copy
|
|
3
4
|
from dataclasses import dataclass
|
|
4
|
-
from typing import Any, AsyncIterator, Awaitable, Callable, Dict, Iterator, List, Optional, Union
|
|
5
|
+
from typing import Any, AsyncIterator, Awaitable, Callable, Dict, Iterator, List, Optional, Union, cast
|
|
5
6
|
from uuid import uuid4
|
|
6
7
|
|
|
7
8
|
from pydantic import BaseModel
|
|
@@ -9,6 +10,7 @@ from typing_extensions import TypeGuard
|
|
|
9
10
|
|
|
10
11
|
from agno.agent import Agent
|
|
11
12
|
from agno.media import Audio, Image, Video
|
|
13
|
+
from agno.models.message import Message
|
|
12
14
|
from agno.models.metrics import Metrics
|
|
13
15
|
from agno.run import RunContext
|
|
14
16
|
from agno.run.agent import RunContentEvent, RunOutput
|
|
@@ -21,9 +23,11 @@ from agno.run.workflow import (
|
|
|
21
23
|
WorkflowRunOutput,
|
|
22
24
|
WorkflowRunOutputEvent,
|
|
23
25
|
)
|
|
26
|
+
from agno.session.agent import AgentSession
|
|
27
|
+
from agno.session.team import TeamSession
|
|
24
28
|
from agno.session.workflow import WorkflowSession
|
|
25
29
|
from agno.team import Team
|
|
26
|
-
from agno.utils.log import log_debug, logger, use_agent_logger, use_team_logger, use_workflow_logger
|
|
30
|
+
from agno.utils.log import log_debug, log_warning, logger, use_agent_logger, use_team_logger, use_workflow_logger
|
|
27
31
|
from agno.utils.merge_dict import merge_dictionaries
|
|
28
32
|
from agno.workflow.types import StepInput, StepOutput, StepType
|
|
29
33
|
|
|
@@ -272,17 +276,18 @@ class Step:
|
|
|
272
276
|
elif isinstance(chunk.content, BaseModel):
|
|
273
277
|
content = chunk.content # type: ignore[assignment]
|
|
274
278
|
else:
|
|
275
|
-
#
|
|
279
|
+
# Case when parse_response is False and the content is a dict
|
|
276
280
|
content += str(chunk.content)
|
|
277
281
|
elif isinstance(chunk, (RunOutput, TeamRunOutput)):
|
|
278
282
|
# This is the final response from the agent/team
|
|
279
283
|
content = chunk.content # type: ignore[assignment]
|
|
280
|
-
else:
|
|
281
|
-
# Non Agent/Team data structure that was yielded
|
|
282
|
-
content += str(chunk)
|
|
283
284
|
# If the chunk is a StepOutput, use it as the final response
|
|
284
|
-
|
|
285
|
+
elif isinstance(chunk, StepOutput):
|
|
285
286
|
final_response = chunk
|
|
287
|
+
break
|
|
288
|
+
# Non Agent/Team data structure that was yielded
|
|
289
|
+
else:
|
|
290
|
+
content += str(chunk)
|
|
286
291
|
|
|
287
292
|
except StopIteration as e:
|
|
288
293
|
if hasattr(e, "value") and isinstance(e.value, StepOutput):
|
|
@@ -482,6 +487,12 @@ class Step:
|
|
|
482
487
|
session_state_copy = copy(session_state) if session_state is not None else {}
|
|
483
488
|
|
|
484
489
|
# Considering both stream_events and stream_intermediate_steps (deprecated)
|
|
490
|
+
if stream_intermediate_steps is not None:
|
|
491
|
+
warnings.warn(
|
|
492
|
+
"The 'stream_intermediate_steps' parameter is deprecated and will be removed in future versions. Use 'stream_events' instead.",
|
|
493
|
+
DeprecationWarning,
|
|
494
|
+
stacklevel=2,
|
|
495
|
+
)
|
|
485
496
|
stream_events = stream_events or stream_intermediate_steps
|
|
486
497
|
|
|
487
498
|
# Emit StepStartedEvent
|
|
@@ -537,11 +548,11 @@ class Step:
|
|
|
537
548
|
yield enriched_event # type: ignore[misc]
|
|
538
549
|
elif isinstance(event, (RunOutput, TeamRunOutput)):
|
|
539
550
|
content = event.content # type: ignore[assignment]
|
|
540
|
-
|
|
541
|
-
content += str(event)
|
|
542
|
-
if isinstance(event, StepOutput):
|
|
551
|
+
elif isinstance(event, StepOutput):
|
|
543
552
|
final_response = event
|
|
544
553
|
break
|
|
554
|
+
else:
|
|
555
|
+
content += str(event)
|
|
545
556
|
|
|
546
557
|
# Merge session_state changes back
|
|
547
558
|
if run_context is None and session_state is not None:
|
|
@@ -758,10 +769,12 @@ class Step:
|
|
|
758
769
|
content = str(chunk.content)
|
|
759
770
|
elif isinstance(chunk, (RunOutput, TeamRunOutput)):
|
|
760
771
|
content = chunk.content # type: ignore[assignment]
|
|
772
|
+
elif isinstance(chunk, StepOutput):
|
|
773
|
+
final_response = chunk
|
|
774
|
+
break
|
|
761
775
|
else:
|
|
762
776
|
content += str(chunk)
|
|
763
|
-
|
|
764
|
-
final_response = chunk
|
|
777
|
+
|
|
765
778
|
else:
|
|
766
779
|
if _is_async_generator_function(self.active_executor):
|
|
767
780
|
iterator = await self._acall_custom_function(
|
|
@@ -784,10 +797,11 @@ class Step:
|
|
|
784
797
|
content = str(chunk.content)
|
|
785
798
|
elif isinstance(chunk, (RunOutput, TeamRunOutput)):
|
|
786
799
|
content = chunk.content # type: ignore[assignment]
|
|
800
|
+
elif isinstance(chunk, StepOutput):
|
|
801
|
+
final_response = chunk
|
|
802
|
+
break
|
|
787
803
|
else:
|
|
788
804
|
content += str(chunk)
|
|
789
|
-
if isinstance(chunk, StepOutput):
|
|
790
|
-
final_response = chunk
|
|
791
805
|
|
|
792
806
|
except StopIteration as e:
|
|
793
807
|
if hasattr(e, "value") and isinstance(e.value, StepOutput):
|
|
@@ -948,6 +962,12 @@ class Step:
|
|
|
948
962
|
session_state_copy = copy(session_state) if session_state is not None else {}
|
|
949
963
|
|
|
950
964
|
# Considering both stream_events and stream_intermediate_steps (deprecated)
|
|
965
|
+
if stream_intermediate_steps is not None:
|
|
966
|
+
warnings.warn(
|
|
967
|
+
"The 'stream_intermediate_steps' parameter is deprecated and will be removed in future versions. Use 'stream_events' instead.",
|
|
968
|
+
DeprecationWarning,
|
|
969
|
+
stacklevel=2,
|
|
970
|
+
)
|
|
951
971
|
stream_events = stream_events or stream_intermediate_steps
|
|
952
972
|
|
|
953
973
|
if stream_events and workflow_run_response:
|
|
@@ -1003,11 +1023,11 @@ class Step:
|
|
|
1003
1023
|
yield enriched_event # type: ignore[misc]
|
|
1004
1024
|
elif isinstance(event, (RunOutput, TeamRunOutput)):
|
|
1005
1025
|
content = event.content # type: ignore[assignment]
|
|
1006
|
-
|
|
1007
|
-
content += str(event)
|
|
1008
|
-
if isinstance(event, StepOutput):
|
|
1026
|
+
elif isinstance(event, StepOutput):
|
|
1009
1027
|
final_response = event
|
|
1010
1028
|
break
|
|
1029
|
+
else:
|
|
1030
|
+
content += str(event)
|
|
1011
1031
|
if not final_response:
|
|
1012
1032
|
final_response = StepOutput(content=content)
|
|
1013
1033
|
elif _is_async_callable(self.active_executor):
|
|
@@ -1054,11 +1074,14 @@ class Step:
|
|
|
1054
1074
|
yield enriched_event # type: ignore[misc]
|
|
1055
1075
|
elif isinstance(event, (RunOutput, TeamRunOutput)):
|
|
1056
1076
|
content = event.content # type: ignore[assignment]
|
|
1057
|
-
|
|
1058
|
-
content += str(event)
|
|
1059
|
-
if isinstance(event, StepOutput):
|
|
1077
|
+
elif isinstance(event, StepOutput):
|
|
1060
1078
|
final_response = event
|
|
1061
1079
|
break
|
|
1080
|
+
else:
|
|
1081
|
+
if isinstance(content, str):
|
|
1082
|
+
content += str(event)
|
|
1083
|
+
else:
|
|
1084
|
+
content = str(event)
|
|
1062
1085
|
if not final_response:
|
|
1063
1086
|
final_response = StepOutput(content=content)
|
|
1064
1087
|
else:
|
|
@@ -1202,6 +1225,83 @@ class Step:
|
|
|
1202
1225
|
|
|
1203
1226
|
return
|
|
1204
1227
|
|
|
1228
|
+
def get_chat_history(self, session_id: str, last_n_runs: Optional[int] = None) -> List[Message]:
|
|
1229
|
+
"""Return the step's Agent or Team chat history for the given session.
|
|
1230
|
+
|
|
1231
|
+
Args:
|
|
1232
|
+
session_id: The session ID to get the chat history for. If not provided, the current cached session ID is used.
|
|
1233
|
+
last_n_runs: Number of recent runs to include. If None, all runs will be considered.
|
|
1234
|
+
|
|
1235
|
+
Returns:
|
|
1236
|
+
List[Message]: The step's Agent or Team chat history for the given session.
|
|
1237
|
+
"""
|
|
1238
|
+
session: Union[AgentSession, TeamSession, WorkflowSession, None] = None
|
|
1239
|
+
|
|
1240
|
+
if self.agent:
|
|
1241
|
+
session = self.agent.get_session(session_id=session_id)
|
|
1242
|
+
if not session:
|
|
1243
|
+
log_warning("Session not found")
|
|
1244
|
+
return []
|
|
1245
|
+
|
|
1246
|
+
if not isinstance(session, WorkflowSession):
|
|
1247
|
+
raise ValueError("The provided session is not a WorkflowSession")
|
|
1248
|
+
|
|
1249
|
+
session = cast(WorkflowSession, session)
|
|
1250
|
+
return session.get_messages(last_n_runs=last_n_runs, agent_id=self.agent.id)
|
|
1251
|
+
|
|
1252
|
+
elif self.team:
|
|
1253
|
+
session = self.team.get_session(session_id=session_id)
|
|
1254
|
+
if not session:
|
|
1255
|
+
log_warning("Session not found")
|
|
1256
|
+
return []
|
|
1257
|
+
|
|
1258
|
+
if not isinstance(session, WorkflowSession):
|
|
1259
|
+
raise ValueError("The provided session is not a WorkflowSession")
|
|
1260
|
+
|
|
1261
|
+
session = cast(WorkflowSession, session)
|
|
1262
|
+
return session.get_messages(last_n_runs=last_n_runs, team_id=self.team.id)
|
|
1263
|
+
|
|
1264
|
+
return []
|
|
1265
|
+
|
|
1266
|
+
async def aget_chat_history(
|
|
1267
|
+
self, session_id: Optional[str] = None, last_n_runs: Optional[int] = None
|
|
1268
|
+
) -> List[Message]:
|
|
1269
|
+
"""Return the step's Agent or Team chat history for the given session.
|
|
1270
|
+
|
|
1271
|
+
Args:
|
|
1272
|
+
session_id: The session ID to get the chat history for. If not provided, the current cached session ID is used.
|
|
1273
|
+
last_n_runs: Number of recent runs to include. If None, all runs will be considered.
|
|
1274
|
+
|
|
1275
|
+
Returns:
|
|
1276
|
+
List[Message]: The step's Agent or Team chat history for the given session.
|
|
1277
|
+
"""
|
|
1278
|
+
session: Union[AgentSession, TeamSession, WorkflowSession, None] = None
|
|
1279
|
+
|
|
1280
|
+
if self.agent:
|
|
1281
|
+
session = await self.agent.aget_session(session_id=session_id)
|
|
1282
|
+
if not session:
|
|
1283
|
+
log_warning("Session not found")
|
|
1284
|
+
return []
|
|
1285
|
+
|
|
1286
|
+
if not isinstance(session, WorkflowSession):
|
|
1287
|
+
raise ValueError("The provided session is not a WorkflowSession")
|
|
1288
|
+
|
|
1289
|
+
session = cast(WorkflowSession, session)
|
|
1290
|
+
return session.get_messages(last_n_runs=last_n_runs, agent_id=self.agent.id)
|
|
1291
|
+
|
|
1292
|
+
elif self.team:
|
|
1293
|
+
session = await self.team.aget_session(session_id=session_id)
|
|
1294
|
+
if not session:
|
|
1295
|
+
log_warning("Session not found")
|
|
1296
|
+
return []
|
|
1297
|
+
|
|
1298
|
+
if not isinstance(session, WorkflowSession):
|
|
1299
|
+
raise ValueError("The provided session is not a WorkflowSession")
|
|
1300
|
+
|
|
1301
|
+
return session.get_messages(last_n_runs=last_n_runs, team_id=self.team.id)
|
|
1302
|
+
|
|
1303
|
+
return []
|
|
1304
|
+
|
|
1205
1305
|
def _store_executor_response(
|
|
1206
1306
|
self, workflow_run_response: "WorkflowRunOutput", executor_run_response: Union[RunOutput, TeamRunOutput]
|
|
1207
1307
|
) -> None:
|
agno/workflow/steps.py
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import warnings
|
|
1
2
|
from dataclasses import dataclass
|
|
2
3
|
from typing import Any, AsyncIterator, Awaitable, Callable, Dict, Iterator, List, Optional, Union
|
|
3
4
|
from uuid import uuid4
|
|
@@ -229,6 +230,12 @@ class Steps:
|
|
|
229
230
|
self._prepare_steps()
|
|
230
231
|
|
|
231
232
|
# Considering both stream_events and stream_intermediate_steps (deprecated)
|
|
233
|
+
if stream_intermediate_steps is not None:
|
|
234
|
+
warnings.warn(
|
|
235
|
+
"The 'stream_intermediate_steps' parameter is deprecated and will be removed in future versions. Use 'stream_events' instead.",
|
|
236
|
+
DeprecationWarning,
|
|
237
|
+
stacklevel=2,
|
|
238
|
+
)
|
|
232
239
|
stream_events = stream_events or stream_intermediate_steps
|
|
233
240
|
|
|
234
241
|
if stream_events:
|
|
@@ -468,6 +475,12 @@ class Steps:
|
|
|
468
475
|
self._prepare_steps()
|
|
469
476
|
|
|
470
477
|
# Considering both stream_events and stream_intermediate_steps (deprecated)
|
|
478
|
+
if stream_intermediate_steps is not None:
|
|
479
|
+
warnings.warn(
|
|
480
|
+
"The 'stream_intermediate_steps' parameter is deprecated and will be removed in future versions. Use 'stream_events' instead.",
|
|
481
|
+
DeprecationWarning,
|
|
482
|
+
stacklevel=2,
|
|
483
|
+
)
|
|
471
484
|
stream_events = stream_events or stream_intermediate_steps
|
|
472
485
|
|
|
473
486
|
if stream_events:
|