agno 2.0.2__py3-none-any.whl → 2.0.4__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 +164 -87
- agno/db/dynamo/dynamo.py +8 -0
- agno/db/firestore/firestore.py +8 -1
- agno/db/gcs_json/gcs_json_db.py +9 -0
- agno/db/json/json_db.py +8 -0
- agno/db/mongo/mongo.py +10 -1
- agno/db/mysql/mysql.py +10 -0
- agno/db/postgres/postgres.py +16 -8
- agno/db/redis/redis.py +6 -0
- agno/db/singlestore/schemas.py +1 -1
- agno/db/singlestore/singlestore.py +8 -1
- agno/db/sqlite/sqlite.py +9 -1
- agno/db/utils.py +14 -0
- agno/knowledge/chunking/fixed.py +1 -1
- agno/knowledge/knowledge.py +91 -65
- agno/knowledge/reader/base.py +3 -0
- agno/knowledge/reader/csv_reader.py +1 -1
- agno/knowledge/reader/json_reader.py +1 -1
- agno/knowledge/reader/markdown_reader.py +5 -5
- agno/knowledge/reader/s3_reader.py +0 -12
- agno/knowledge/reader/text_reader.py +5 -5
- agno/models/base.py +2 -2
- agno/models/cerebras/cerebras.py +5 -3
- agno/models/cerebras/cerebras_openai.py +5 -3
- agno/models/google/gemini.py +33 -11
- agno/models/litellm/chat.py +1 -1
- agno/models/openai/chat.py +3 -0
- agno/models/openai/responses.py +81 -40
- agno/models/response.py +5 -0
- agno/models/siliconflow/__init__.py +5 -0
- agno/models/siliconflow/siliconflow.py +25 -0
- agno/os/app.py +4 -1
- agno/os/auth.py +24 -14
- agno/os/interfaces/slack/router.py +1 -1
- agno/os/interfaces/whatsapp/router.py +2 -0
- agno/os/router.py +187 -76
- agno/os/routers/evals/utils.py +9 -9
- agno/os/routers/health.py +26 -0
- agno/os/routers/knowledge/knowledge.py +11 -11
- agno/os/routers/session/session.py +24 -8
- agno/os/schema.py +8 -2
- agno/run/agent.py +5 -2
- agno/run/base.py +6 -3
- agno/run/team.py +11 -3
- agno/run/workflow.py +69 -12
- agno/session/team.py +1 -0
- agno/team/team.py +196 -93
- agno/tools/mcp.py +1 -0
- agno/tools/mem0.py +11 -17
- agno/tools/memory.py +419 -0
- agno/tools/workflow.py +279 -0
- agno/utils/audio.py +27 -0
- agno/utils/common.py +90 -1
- agno/utils/print_response/agent.py +6 -2
- agno/utils/streamlit.py +14 -8
- agno/vectordb/chroma/chromadb.py +8 -2
- agno/workflow/step.py +111 -13
- agno/workflow/workflow.py +16 -13
- {agno-2.0.2.dist-info → agno-2.0.4.dist-info}/METADATA +1 -1
- {agno-2.0.2.dist-info → agno-2.0.4.dist-info}/RECORD +63 -58
- {agno-2.0.2.dist-info → agno-2.0.4.dist-info}/WHEEL +0 -0
- {agno-2.0.2.dist-info → agno-2.0.4.dist-info}/licenses/LICENSE +0 -0
- {agno-2.0.2.dist-info → agno-2.0.4.dist-info}/top_level.txt +0 -0
agno/team/team.py
CHANGED
|
@@ -55,6 +55,7 @@ from agno.run.team import TeamRunEvent, TeamRunInput, TeamRunOutput, TeamRunOutp
|
|
|
55
55
|
from agno.session import SessionSummaryManager, TeamSession
|
|
56
56
|
from agno.tools import Toolkit
|
|
57
57
|
from agno.tools.function import Function
|
|
58
|
+
from agno.utils.common import is_typed_dict, validate_typed_dict
|
|
58
59
|
from agno.utils.events import (
|
|
59
60
|
create_team_memory_update_completed_event,
|
|
60
61
|
create_team_memory_update_started_event,
|
|
@@ -408,6 +409,7 @@ class Team:
|
|
|
408
409
|
enable_agentic_memory: bool = False,
|
|
409
410
|
enable_user_memories: bool = False,
|
|
410
411
|
add_memories_to_context: Optional[bool] = None,
|
|
412
|
+
memory_manager: Optional[MemoryManager] = None,
|
|
411
413
|
enable_session_summaries: bool = False,
|
|
412
414
|
session_summary_manager: Optional[SessionSummaryManager] = None,
|
|
413
415
|
add_session_summary_to_context: Optional[bool] = None,
|
|
@@ -505,6 +507,7 @@ class Team:
|
|
|
505
507
|
self.enable_agentic_memory = enable_agentic_memory
|
|
506
508
|
self.enable_user_memories = enable_user_memories
|
|
507
509
|
self.add_memories_to_context = add_memories_to_context
|
|
510
|
+
self.memory_manager = memory_manager
|
|
508
511
|
self.enable_session_summaries = enable_session_summaries
|
|
509
512
|
self.session_summary_manager = session_summary_manager
|
|
510
513
|
self.add_session_summary_to_context = add_session_summary_to_context
|
|
@@ -619,8 +622,6 @@ class Team:
|
|
|
619
622
|
if isinstance(input, BaseModel):
|
|
620
623
|
if isinstance(input, self.input_schema):
|
|
621
624
|
try:
|
|
622
|
-
# Re-validate to catch any field validation errors
|
|
623
|
-
input.model_validate(input.model_dump())
|
|
624
625
|
return input
|
|
625
626
|
except Exception as e:
|
|
626
627
|
raise ValueError(f"BaseModel validation failed: {str(e)}")
|
|
@@ -631,8 +632,13 @@ class Team:
|
|
|
631
632
|
# Case 2: Message is a dict
|
|
632
633
|
elif isinstance(input, dict):
|
|
633
634
|
try:
|
|
634
|
-
|
|
635
|
-
|
|
635
|
+
# Check if the schema is a TypedDict
|
|
636
|
+
if is_typed_dict(self.input_schema):
|
|
637
|
+
validated_dict = validate_typed_dict(input, self.input_schema)
|
|
638
|
+
return validated_dict
|
|
639
|
+
else:
|
|
640
|
+
validated_model = self.input_schema(**input)
|
|
641
|
+
return validated_model
|
|
636
642
|
except Exception as e:
|
|
637
643
|
raise ValueError(f"Failed to parse dict into {self.input_schema.__name__}: {str(e)}")
|
|
638
644
|
|
|
@@ -804,9 +810,9 @@ class Team:
|
|
|
804
810
|
1. Reason about the task(s) if reasoning is enabled
|
|
805
811
|
2. Get a response from the model
|
|
806
812
|
3. Update Team Memory
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
813
|
+
4. Add RunOutput to Team Session
|
|
814
|
+
5. Calculate session metrics
|
|
815
|
+
6. Save session to storage
|
|
810
816
|
"""
|
|
811
817
|
log_debug(f"Team Run Start: {run_response.run_id}", center=True)
|
|
812
818
|
|
|
@@ -847,10 +853,7 @@ class Team:
|
|
|
847
853
|
else:
|
|
848
854
|
self._scrub_media_from_run_output(run_response)
|
|
849
855
|
|
|
850
|
-
#
|
|
851
|
-
session.upsert_run(run_response=run_response)
|
|
852
|
-
|
|
853
|
-
# 5. Update Team Memory
|
|
856
|
+
# 3. Update Team Memory
|
|
854
857
|
response_iterator = self._make_memories_and_summaries(
|
|
855
858
|
run_response=run_response,
|
|
856
859
|
run_messages=run_messages,
|
|
@@ -859,14 +862,17 @@ class Team:
|
|
|
859
862
|
)
|
|
860
863
|
deque(response_iterator, maxlen=0)
|
|
861
864
|
|
|
862
|
-
# 5. Calculate session metrics
|
|
863
|
-
self._update_session_metrics(session=session)
|
|
864
|
-
|
|
865
865
|
run_response.status = RunStatus.completed
|
|
866
866
|
|
|
867
|
-
#
|
|
867
|
+
# Parse team response model
|
|
868
868
|
self._convert_response_to_structured_format(run_response=run_response)
|
|
869
869
|
|
|
870
|
+
# 4. Add the RunOutput to Team Session
|
|
871
|
+
session.upsert_run(run_response=run_response)
|
|
872
|
+
|
|
873
|
+
# 5. Calculate session metrics
|
|
874
|
+
self._update_session_metrics(session=session)
|
|
875
|
+
|
|
870
876
|
# 6. Save session to storage
|
|
871
877
|
self.save_session(session=session)
|
|
872
878
|
|
|
@@ -897,8 +903,9 @@ class Team:
|
|
|
897
903
|
1. Reason about the task(s) if reasoning is enabled
|
|
898
904
|
2. Get a response from the model
|
|
899
905
|
3. Update Team Memory
|
|
900
|
-
4.
|
|
901
|
-
5.
|
|
906
|
+
4. Add RunOutput to Team Session
|
|
907
|
+
5. Calculate session metrics
|
|
908
|
+
6. Save session to storage
|
|
902
909
|
"""
|
|
903
910
|
|
|
904
911
|
log_debug(f"Team Run Start: {run_response.run_id}", center=True)
|
|
@@ -971,10 +978,7 @@ class Team:
|
|
|
971
978
|
session=session, run_response=run_response, stream_intermediate_steps=stream_intermediate_steps
|
|
972
979
|
)
|
|
973
980
|
|
|
974
|
-
#
|
|
975
|
-
session.upsert_run(run_response=run_response)
|
|
976
|
-
|
|
977
|
-
# 5. Update Team Memory
|
|
981
|
+
# 3. Update Team Memory
|
|
978
982
|
yield from self._make_memories_and_summaries(
|
|
979
983
|
run_response=run_response,
|
|
980
984
|
run_messages=run_messages,
|
|
@@ -982,11 +986,14 @@ class Team:
|
|
|
982
986
|
user_id=user_id,
|
|
983
987
|
)
|
|
984
988
|
|
|
989
|
+
run_response.status = RunStatus.completed
|
|
990
|
+
|
|
991
|
+
# 4. Add the run to memory
|
|
992
|
+
session.upsert_run(run_response=run_response)
|
|
993
|
+
|
|
985
994
|
# 5. Calculate session metrics
|
|
986
995
|
self._update_session_metrics(session=session)
|
|
987
996
|
|
|
988
|
-
run_response.status = RunStatus.completed
|
|
989
|
-
|
|
990
997
|
completed_event = self._handle_event(
|
|
991
998
|
create_team_run_completed_event(
|
|
992
999
|
from_run_response=run_response,
|
|
@@ -1336,35 +1343,72 @@ class Team:
|
|
|
1336
1343
|
async def _arun(
|
|
1337
1344
|
self,
|
|
1338
1345
|
run_response: TeamRunOutput,
|
|
1339
|
-
|
|
1346
|
+
input_message: Union[str, List, Dict, Message, BaseModel, List[Message]],
|
|
1340
1347
|
session: TeamSession,
|
|
1348
|
+
session_state: Optional[Dict[str, Any]] = None,
|
|
1341
1349
|
user_id: Optional[str] = None,
|
|
1350
|
+
images: Optional[Sequence[Image]] = None,
|
|
1351
|
+
videos: Optional[Sequence[Video]] = None,
|
|
1352
|
+
audio: Optional[Sequence[Audio]] = None,
|
|
1353
|
+
files: Optional[Sequence[File]] = None,
|
|
1354
|
+
knowledge_filters: Optional[Dict[str, Any]] = None,
|
|
1355
|
+
add_history_to_context: Optional[bool] = None,
|
|
1356
|
+
add_dependencies_to_context: Optional[bool] = None,
|
|
1357
|
+
add_session_state_to_context: Optional[bool] = None,
|
|
1358
|
+
metadata: Optional[Dict[str, Any]] = None,
|
|
1342
1359
|
response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
|
|
1360
|
+
dependencies: Optional[Dict[str, Any]] = None,
|
|
1361
|
+
**kwargs: Any,
|
|
1343
1362
|
) -> TeamRunOutput:
|
|
1344
1363
|
"""Run the Team and return the response.
|
|
1345
1364
|
|
|
1346
1365
|
Steps:
|
|
1347
|
-
1.
|
|
1348
|
-
2.
|
|
1349
|
-
3.
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1366
|
+
1. Resolve dependencies
|
|
1367
|
+
2. Prepare run messages
|
|
1368
|
+
3. Reason about the task(s) if reasoning is enabled
|
|
1369
|
+
4. Get a response from the model
|
|
1370
|
+
5. Update Team Memory
|
|
1371
|
+
6. Add RunOutput to Team Session
|
|
1372
|
+
7. Calculate session metrics
|
|
1373
|
+
8. Save session to storage
|
|
1353
1374
|
"""
|
|
1354
|
-
|
|
1375
|
+
# 1. Resolve callable dependencies if present
|
|
1376
|
+
if dependencies is not None:
|
|
1377
|
+
await self._aresolve_run_dependencies(dependencies=dependencies)
|
|
1355
1378
|
|
|
1379
|
+
# 2. Prepare run messages
|
|
1380
|
+
run_messages = self._get_run_messages(
|
|
1381
|
+
run_response=run_response,
|
|
1382
|
+
session=session,
|
|
1383
|
+
session_state=session_state,
|
|
1384
|
+
user_id=user_id,
|
|
1385
|
+
input_message=input_message,
|
|
1386
|
+
audio=audio,
|
|
1387
|
+
images=images,
|
|
1388
|
+
videos=videos,
|
|
1389
|
+
files=files,
|
|
1390
|
+
knowledge_filters=knowledge_filters,
|
|
1391
|
+
add_history_to_context=add_history_to_context,
|
|
1392
|
+
dependencies=dependencies,
|
|
1393
|
+
add_dependencies_to_context=add_dependencies_to_context,
|
|
1394
|
+
add_session_state_to_context=add_session_state_to_context,
|
|
1395
|
+
metadata=metadata,
|
|
1396
|
+
**kwargs,
|
|
1397
|
+
)
|
|
1398
|
+
|
|
1399
|
+
self.model = cast(Model, self.model)
|
|
1356
1400
|
log_debug(f"Team Run Start: {run_response.run_id}", center=True)
|
|
1357
1401
|
|
|
1358
1402
|
# Register run for cancellation tracking
|
|
1359
1403
|
register_run(run_response.run_id) # type: ignore
|
|
1360
1404
|
|
|
1361
|
-
#
|
|
1405
|
+
# 3. Reason about the task(s) if reasoning is enabled
|
|
1362
1406
|
await self._ahandle_reasoning(run_response=run_response, run_messages=run_messages)
|
|
1363
1407
|
|
|
1364
1408
|
# Check for cancellation before model call
|
|
1365
1409
|
raise_if_cancelled(run_response.run_id) # type: ignore
|
|
1366
1410
|
|
|
1367
|
-
#
|
|
1411
|
+
# 4. Get the model response for the team leader
|
|
1368
1412
|
model_response = await self.model.aresponse(
|
|
1369
1413
|
messages=run_messages.messages,
|
|
1370
1414
|
tools=self._tools_for_model,
|
|
@@ -1391,10 +1435,7 @@ class Team:
|
|
|
1391
1435
|
else:
|
|
1392
1436
|
self._scrub_media_from_run_output(run_response)
|
|
1393
1437
|
|
|
1394
|
-
#
|
|
1395
|
-
session.upsert_run(run_response=run_response)
|
|
1396
|
-
|
|
1397
|
-
# 4. Update Team Memory
|
|
1438
|
+
# 5. Update Team Memory
|
|
1398
1439
|
async for _ in self._amake_memories_and_summaries(
|
|
1399
1440
|
run_response=run_response,
|
|
1400
1441
|
session=session,
|
|
@@ -1403,18 +1444,21 @@ class Team:
|
|
|
1403
1444
|
):
|
|
1404
1445
|
pass
|
|
1405
1446
|
|
|
1406
|
-
# 5. Calculate session metrics
|
|
1407
|
-
self._update_session_metrics(session=session)
|
|
1408
|
-
|
|
1409
1447
|
run_response.status = RunStatus.completed
|
|
1410
1448
|
|
|
1411
|
-
#
|
|
1449
|
+
# Parse team response model
|
|
1412
1450
|
self._convert_response_to_structured_format(run_response=run_response)
|
|
1413
1451
|
|
|
1414
|
-
#
|
|
1452
|
+
# 6. Add the run to memory
|
|
1453
|
+
session.upsert_run(run_response=run_response)
|
|
1454
|
+
|
|
1455
|
+
# 7. Calculate session metrics
|
|
1456
|
+
self._update_session_metrics(session=session)
|
|
1457
|
+
|
|
1458
|
+
# 8. Save session to storage
|
|
1415
1459
|
self.save_session(session=session)
|
|
1416
1460
|
|
|
1417
|
-
#
|
|
1461
|
+
# Log Team Telemetry
|
|
1418
1462
|
await self._alog_team_telemetry(session_id=session.session_id, run_id=run_response.run_id)
|
|
1419
1463
|
|
|
1420
1464
|
log_debug(f"Team Run End: {run_response.run_id}", center=True, symbol="*")
|
|
@@ -1427,25 +1471,64 @@ class Team:
|
|
|
1427
1471
|
async def _arun_stream(
|
|
1428
1472
|
self,
|
|
1429
1473
|
run_response: TeamRunOutput,
|
|
1430
|
-
|
|
1474
|
+
input_message: Union[str, List, Dict, Message, BaseModel, List[Message]],
|
|
1431
1475
|
session: TeamSession,
|
|
1476
|
+
session_state: Optional[Dict[str, Any]] = None,
|
|
1432
1477
|
user_id: Optional[str] = None,
|
|
1478
|
+
images: Optional[Sequence[Image]] = None,
|
|
1479
|
+
videos: Optional[Sequence[Video]] = None,
|
|
1480
|
+
audio: Optional[Sequence[Audio]] = None,
|
|
1481
|
+
files: Optional[Sequence[File]] = None,
|
|
1482
|
+
knowledge_filters: Optional[Dict[str, Any]] = None,
|
|
1483
|
+
add_history_to_context: Optional[bool] = None,
|
|
1484
|
+
add_dependencies_to_context: Optional[bool] = None,
|
|
1485
|
+
add_session_state_to_context: Optional[bool] = None,
|
|
1486
|
+
metadata: Optional[Dict[str, Any]] = None,
|
|
1433
1487
|
response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
|
|
1488
|
+
dependencies: Optional[Dict[str, Any]] = None,
|
|
1434
1489
|
stream_intermediate_steps: bool = False,
|
|
1435
1490
|
workflow_context: Optional[Dict] = None,
|
|
1436
1491
|
yield_run_response: bool = False,
|
|
1492
|
+
**kwargs: Any,
|
|
1437
1493
|
) -> AsyncIterator[Union[TeamRunOutputEvent, RunOutputEvent, TeamRunOutput]]:
|
|
1438
1494
|
"""Run the Team and return the response.
|
|
1439
1495
|
|
|
1440
1496
|
Steps:
|
|
1441
|
-
1.
|
|
1442
|
-
2.
|
|
1443
|
-
3.
|
|
1444
|
-
4.
|
|
1445
|
-
5.
|
|
1497
|
+
1. Resolve dependencies
|
|
1498
|
+
2. Prepare run messages
|
|
1499
|
+
3. Reason about the task(s) if reasoning is enabled
|
|
1500
|
+
4. Get a response from the model
|
|
1501
|
+
5. Update Team Memory
|
|
1502
|
+
6. Add RunOutput to Team Session
|
|
1503
|
+
7. Calculate session metrics
|
|
1504
|
+
8. Save session to storage
|
|
1446
1505
|
"""
|
|
1447
|
-
log_debug(f"Team Run Start: {run_response.run_id}", center=True)
|
|
1448
1506
|
|
|
1507
|
+
# 1. Resolve callable dependencies if present
|
|
1508
|
+
if dependencies is not None:
|
|
1509
|
+
await self._aresolve_run_dependencies(dependencies=dependencies)
|
|
1510
|
+
|
|
1511
|
+
# 2. Prepare run messages
|
|
1512
|
+
run_messages = self._get_run_messages(
|
|
1513
|
+
run_response=run_response,
|
|
1514
|
+
session=session,
|
|
1515
|
+
session_state=session_state,
|
|
1516
|
+
user_id=user_id,
|
|
1517
|
+
input_message=input_message,
|
|
1518
|
+
audio=audio,
|
|
1519
|
+
images=images,
|
|
1520
|
+
videos=videos,
|
|
1521
|
+
files=files,
|
|
1522
|
+
knowledge_filters=knowledge_filters,
|
|
1523
|
+
add_history_to_context=add_history_to_context,
|
|
1524
|
+
dependencies=dependencies,
|
|
1525
|
+
add_dependencies_to_context=add_dependencies_to_context,
|
|
1526
|
+
add_session_state_to_context=add_session_state_to_context,
|
|
1527
|
+
metadata=metadata,
|
|
1528
|
+
**kwargs,
|
|
1529
|
+
)
|
|
1530
|
+
|
|
1531
|
+
log_debug(f"Team Run Start: {run_response.run_id}", center=True)
|
|
1449
1532
|
# Register run for cancellation tracking
|
|
1450
1533
|
register_run(run_response.run_id) # type: ignore
|
|
1451
1534
|
|
|
@@ -1456,7 +1539,7 @@ class Team:
|
|
|
1456
1539
|
create_team_run_started_event(from_run_response=run_response), run_response, workflow_context
|
|
1457
1540
|
)
|
|
1458
1541
|
|
|
1459
|
-
#
|
|
1542
|
+
# 3. Reason about the task(s) if reasoning is enabled
|
|
1460
1543
|
async for item in self._ahandle_reasoning_stream(run_response=run_response, run_messages=run_messages):
|
|
1461
1544
|
raise_if_cancelled(run_response.run_id) # type: ignore
|
|
1462
1545
|
yield item
|
|
@@ -1464,7 +1547,7 @@ class Team:
|
|
|
1464
1547
|
# Check for cancellation before model processing
|
|
1465
1548
|
raise_if_cancelled(run_response.run_id) # type: ignore
|
|
1466
1549
|
|
|
1467
|
-
#
|
|
1550
|
+
# 4. Get a response from the model
|
|
1468
1551
|
if self.output_model is None:
|
|
1469
1552
|
async for event in self._ahandle_model_response_stream(
|
|
1470
1553
|
session=session,
|
|
@@ -1516,10 +1599,7 @@ class Team:
|
|
|
1516
1599
|
):
|
|
1517
1600
|
yield event
|
|
1518
1601
|
|
|
1519
|
-
#
|
|
1520
|
-
session.upsert_run(run_response=run_response)
|
|
1521
|
-
|
|
1522
|
-
# 4. Update Team Memory
|
|
1602
|
+
# 6. Update Team Memory
|
|
1523
1603
|
async for event in self._amake_memories_and_summaries(
|
|
1524
1604
|
run_response=run_response,
|
|
1525
1605
|
session=session,
|
|
@@ -1528,16 +1608,19 @@ class Team:
|
|
|
1528
1608
|
):
|
|
1529
1609
|
yield event
|
|
1530
1610
|
|
|
1531
|
-
# 5. Calculate session metrics
|
|
1532
|
-
self._update_session_metrics(session=session)
|
|
1533
|
-
|
|
1534
1611
|
run_response.status = RunStatus.completed
|
|
1535
1612
|
|
|
1613
|
+
# 7. Add the run to memory
|
|
1614
|
+
session.upsert_run(run_response=run_response)
|
|
1615
|
+
|
|
1616
|
+
# 8. Calculate session metrics
|
|
1617
|
+
self._update_session_metrics(session=session)
|
|
1618
|
+
|
|
1536
1619
|
completed_event = self._handle_event(
|
|
1537
1620
|
create_team_run_completed_event(from_run_response=run_response), run_response, workflow_context
|
|
1538
1621
|
)
|
|
1539
1622
|
|
|
1540
|
-
#
|
|
1623
|
+
# 9. Save session to storage
|
|
1541
1624
|
self.save_session(session=session)
|
|
1542
1625
|
|
|
1543
1626
|
if stream_intermediate_steps:
|
|
@@ -1546,7 +1629,7 @@ class Team:
|
|
|
1546
1629
|
if yield_run_response:
|
|
1547
1630
|
yield run_response
|
|
1548
1631
|
|
|
1549
|
-
#
|
|
1632
|
+
# Log Team Telemetry
|
|
1550
1633
|
await self._alog_team_telemetry(session_id=session.session_id, run_id=run_response.run_id)
|
|
1551
1634
|
|
|
1552
1635
|
log_debug(f"Team Run End: {run_response.run_id}", center=True, symbol="*")
|
|
@@ -1679,10 +1762,6 @@ class Team:
|
|
|
1679
1762
|
# Determine run dependencies (runtime override takes priority)
|
|
1680
1763
|
run_dependencies = dependencies if dependencies is not None else self.dependencies
|
|
1681
1764
|
|
|
1682
|
-
# Resolve callable dependencies if present
|
|
1683
|
-
if run_dependencies is not None:
|
|
1684
|
-
self._resolve_run_dependencies(dependencies=run_dependencies)
|
|
1685
|
-
|
|
1686
1765
|
# Determine runtime context parameters
|
|
1687
1766
|
add_dependencies = (
|
|
1688
1767
|
add_dependencies_to_context if add_dependencies_to_context is not None else self.add_dependencies_to_context
|
|
@@ -1779,43 +1858,49 @@ class Team:
|
|
|
1779
1858
|
for attempt in range(num_attempts):
|
|
1780
1859
|
# Run the team
|
|
1781
1860
|
try:
|
|
1782
|
-
run_messages = self._get_run_messages(
|
|
1783
|
-
run_response=run_response,
|
|
1784
|
-
session=team_session, # type: ignore
|
|
1785
|
-
session_state=session_state,
|
|
1786
|
-
user_id=user_id,
|
|
1787
|
-
input_message=validated_input,
|
|
1788
|
-
audio=audio,
|
|
1789
|
-
images=images,
|
|
1790
|
-
videos=videos,
|
|
1791
|
-
files=files,
|
|
1792
|
-
knowledge_filters=effective_filters,
|
|
1793
|
-
add_history_to_context=add_history,
|
|
1794
|
-
dependencies=run_dependencies,
|
|
1795
|
-
add_dependencies_to_context=add_dependencies,
|
|
1796
|
-
add_session_state_to_context=add_session_state,
|
|
1797
|
-
**kwargs,
|
|
1798
|
-
)
|
|
1799
|
-
|
|
1800
1861
|
if stream:
|
|
1801
1862
|
response_iterator = self._arun_stream(
|
|
1802
1863
|
run_response=run_response,
|
|
1803
|
-
|
|
1864
|
+
input_message=validated_input,
|
|
1804
1865
|
session=team_session, # type: ignore
|
|
1866
|
+
session_state=session_state,
|
|
1805
1867
|
user_id=user_id,
|
|
1868
|
+
audio=audio,
|
|
1869
|
+
images=images,
|
|
1870
|
+
videos=videos,
|
|
1871
|
+
files=files,
|
|
1872
|
+
knowledge_filters=effective_filters,
|
|
1873
|
+
add_history_to_context=add_history,
|
|
1874
|
+
add_dependencies_to_context=add_dependencies,
|
|
1875
|
+
add_session_state_to_context=add_session_state,
|
|
1876
|
+
metadata=metadata,
|
|
1806
1877
|
response_format=response_format,
|
|
1878
|
+
dependencies=run_dependencies,
|
|
1807
1879
|
stream_intermediate_steps=stream_intermediate_steps,
|
|
1808
1880
|
workflow_context=workflow_context,
|
|
1809
1881
|
yield_run_response=yield_run_response,
|
|
1882
|
+
**kwargs,
|
|
1810
1883
|
)
|
|
1811
1884
|
return response_iterator # type: ignore
|
|
1812
1885
|
else:
|
|
1813
1886
|
return self._arun( # type: ignore
|
|
1814
1887
|
run_response=run_response,
|
|
1815
|
-
|
|
1888
|
+
input_message=validated_input,
|
|
1816
1889
|
session=team_session, # type: ignore
|
|
1817
1890
|
user_id=user_id,
|
|
1891
|
+
session_state=session_state,
|
|
1892
|
+
audio=audio,
|
|
1893
|
+
images=images,
|
|
1894
|
+
videos=videos,
|
|
1895
|
+
files=files,
|
|
1896
|
+
knowledge_filters=effective_filters,
|
|
1897
|
+
add_history_to_context=add_history,
|
|
1898
|
+
add_dependencies_to_context=add_dependencies,
|
|
1899
|
+
add_session_state_to_context=add_session_state,
|
|
1900
|
+
metadata=metadata,
|
|
1818
1901
|
response_format=response_format,
|
|
1902
|
+
dependencies=run_dependencies,
|
|
1903
|
+
**kwargs,
|
|
1819
1904
|
)
|
|
1820
1905
|
|
|
1821
1906
|
except ModelProviderError as e:
|
|
@@ -2282,11 +2367,13 @@ class Team:
|
|
|
2282
2367
|
tc.tool_call_id: i for i, tc in enumerate(run_response.tools) if tc.tool_call_id is not None
|
|
2283
2368
|
}
|
|
2284
2369
|
# Process tool calls
|
|
2285
|
-
for
|
|
2286
|
-
tool_call_id =
|
|
2370
|
+
for tool_execution in tool_executions_list:
|
|
2371
|
+
tool_call_id = tool_execution.tool_call_id or ""
|
|
2287
2372
|
index = tool_call_index_map.get(tool_call_id)
|
|
2288
2373
|
if index is not None:
|
|
2289
|
-
run_response.tools[index]
|
|
2374
|
+
if run_response.tools[index].child_run_id is not None:
|
|
2375
|
+
tool_execution.child_run_id = run_response.tools[index].child_run_id
|
|
2376
|
+
run_response.tools[index] = tool_execution
|
|
2290
2377
|
else:
|
|
2291
2378
|
run_response.tools = tool_executions_list
|
|
2292
2379
|
|
|
@@ -3729,7 +3816,7 @@ class Team:
|
|
|
3729
3816
|
|
|
3730
3817
|
try:
|
|
3731
3818
|
sig = signature(value)
|
|
3732
|
-
resolved_value = value(
|
|
3819
|
+
resolved_value = value(team=self) if "team" in sig.parameters else value()
|
|
3733
3820
|
|
|
3734
3821
|
if iscoroutine(resolved_value):
|
|
3735
3822
|
resolved_value = await resolved_value
|
|
@@ -4390,8 +4477,8 @@ class Team:
|
|
|
4390
4477
|
f"<additional_context>\n{self.additional_context.strip()}\n</additional_context>\n\n"
|
|
4391
4478
|
)
|
|
4392
4479
|
|
|
4393
|
-
if self.add_session_state_to_context:
|
|
4394
|
-
system_message_content +=
|
|
4480
|
+
if self.add_session_state_to_context and session_state is not None:
|
|
4481
|
+
system_message_content += self._get_formatted_session_state_for_system_message(session_state)
|
|
4395
4482
|
|
|
4396
4483
|
# Add the JSON output prompt if output_schema is provided and structured_outputs is False
|
|
4397
4484
|
if (
|
|
@@ -4404,6 +4491,9 @@ class Team:
|
|
|
4404
4491
|
|
|
4405
4492
|
return Message(role=self.system_message_role, content=system_message_content.strip())
|
|
4406
4493
|
|
|
4494
|
+
def _get_formatted_session_state_for_system_message(self, session_state: Dict[str, Any]) -> str:
|
|
4495
|
+
return f"\n<session_state>\n{session_state}\n</session_state>\n\n"
|
|
4496
|
+
|
|
4407
4497
|
def _get_run_messages(
|
|
4408
4498
|
self,
|
|
4409
4499
|
*,
|
|
@@ -4595,7 +4685,13 @@ class Team:
|
|
|
4595
4685
|
# If message is provided as a dict, try to validate it as a Message
|
|
4596
4686
|
elif isinstance(input_message, dict):
|
|
4597
4687
|
try:
|
|
4598
|
-
|
|
4688
|
+
if self.input_schema and is_typed_dict(self.input_schema):
|
|
4689
|
+
import json
|
|
4690
|
+
|
|
4691
|
+
content = json.dumps(input_message, indent=2, ensure_ascii=False)
|
|
4692
|
+
return Message(role="user", content=content)
|
|
4693
|
+
else:
|
|
4694
|
+
return Message.model_validate(input_message)
|
|
4599
4695
|
except Exception as e:
|
|
4600
4696
|
log_warning(f"Failed to validate input: {e}")
|
|
4601
4697
|
|
|
@@ -5156,6 +5252,12 @@ class Team:
|
|
|
5156
5252
|
if member_agent_run_response is not None:
|
|
5157
5253
|
member_agent_run_response.parent_run_id = run_response.run_id # type: ignore
|
|
5158
5254
|
|
|
5255
|
+
# Update the top-level team run_response tool call to have the run_id of the member run
|
|
5256
|
+
if run_response.tools is not None:
|
|
5257
|
+
for tool in run_response.tools:
|
|
5258
|
+
if tool.tool_name and tool.tool_name.lower() == "delegate_task_to_member":
|
|
5259
|
+
tool.child_run_id = member_agent_run_response.run_id # type: ignore
|
|
5260
|
+
|
|
5159
5261
|
# Update the team run context
|
|
5160
5262
|
member_name = member_agent.name if member_agent.name else member_agent.id if member_agent.id else "Unknown"
|
|
5161
5263
|
if isinstance(member_agent_task, str):
|
|
@@ -6040,7 +6142,8 @@ class Team:
|
|
|
6040
6142
|
session = self.get_session(session_id=session_id) # type: ignore
|
|
6041
6143
|
|
|
6042
6144
|
if session is None:
|
|
6043
|
-
|
|
6145
|
+
log_warning(f"Session {session_id} not found")
|
|
6146
|
+
return []
|
|
6044
6147
|
|
|
6045
6148
|
# Only filter by agent_id if this is part of a team
|
|
6046
6149
|
return session.get_messages_from_last_n_runs(
|
agno/tools/mcp.py
CHANGED
agno/tools/mem0.py
CHANGED
|
@@ -2,7 +2,6 @@ import json
|
|
|
2
2
|
from os import getenv
|
|
3
3
|
from typing import Any, Dict, List, Optional, Union
|
|
4
4
|
|
|
5
|
-
from agno.agent import Agent
|
|
6
5
|
from agno.tools import Toolkit
|
|
7
6
|
from agno.utils.log import log_debug, log_error, log_warning
|
|
8
7
|
|
|
@@ -69,15 +68,13 @@ class Mem0Tools(Toolkit):
|
|
|
69
68
|
def _get_user_id(
|
|
70
69
|
self,
|
|
71
70
|
method_name: str,
|
|
72
|
-
|
|
71
|
+
session_state: Dict[str, Any],
|
|
73
72
|
) -> str:
|
|
74
73
|
"""Resolve the user ID"""
|
|
75
74
|
resolved_user_id = self.user_id
|
|
76
|
-
if not resolved_user_id
|
|
75
|
+
if not resolved_user_id:
|
|
77
76
|
try:
|
|
78
|
-
|
|
79
|
-
if isinstance(session_state, dict):
|
|
80
|
-
resolved_user_id = session_state.get("current_user_id")
|
|
77
|
+
resolved_user_id = session_state.get("current_user_id")
|
|
81
78
|
except Exception:
|
|
82
79
|
pass
|
|
83
80
|
if not resolved_user_id:
|
|
@@ -88,7 +85,7 @@ class Mem0Tools(Toolkit):
|
|
|
88
85
|
|
|
89
86
|
def add_memory(
|
|
90
87
|
self,
|
|
91
|
-
|
|
88
|
+
session_state,
|
|
92
89
|
content: Union[str, Dict[str, str]],
|
|
93
90
|
) -> str:
|
|
94
91
|
"""Add facts to the user's memory.
|
|
@@ -101,7 +98,7 @@ class Mem0Tools(Toolkit):
|
|
|
101
98
|
str: JSON-encoded Mem0 response or an error message.
|
|
102
99
|
"""
|
|
103
100
|
|
|
104
|
-
resolved_user_id = self._get_user_id("add_memory",
|
|
101
|
+
resolved_user_id = self._get_user_id("add_memory", session_state=session_state)
|
|
105
102
|
if isinstance(resolved_user_id, str) and resolved_user_id.startswith("Error in add_memory:"):
|
|
106
103
|
return resolved_user_id
|
|
107
104
|
try:
|
|
@@ -116,7 +113,6 @@ class Mem0Tools(Toolkit):
|
|
|
116
113
|
messages_list,
|
|
117
114
|
user_id=resolved_user_id,
|
|
118
115
|
infer=self.infer,
|
|
119
|
-
output_format="v1.1",
|
|
120
116
|
)
|
|
121
117
|
return json.dumps(result)
|
|
122
118
|
except Exception as e:
|
|
@@ -125,19 +121,18 @@ class Mem0Tools(Toolkit):
|
|
|
125
121
|
|
|
126
122
|
def search_memory(
|
|
127
123
|
self,
|
|
128
|
-
|
|
124
|
+
session_state: Dict[str, Any],
|
|
129
125
|
query: str,
|
|
130
126
|
) -> str:
|
|
131
127
|
"""Semantic search for *query* across the user's stored memories."""
|
|
132
128
|
|
|
133
|
-
resolved_user_id = self._get_user_id("search_memory",
|
|
129
|
+
resolved_user_id = self._get_user_id("search_memory", session_state=session_state)
|
|
134
130
|
if isinstance(resolved_user_id, str) and resolved_user_id.startswith("Error in search_memory:"):
|
|
135
131
|
return resolved_user_id
|
|
136
132
|
try:
|
|
137
133
|
results = self.client.search(
|
|
138
134
|
query=query,
|
|
139
135
|
user_id=resolved_user_id,
|
|
140
|
-
output_format="v1.1",
|
|
141
136
|
)
|
|
142
137
|
|
|
143
138
|
if isinstance(results, dict) and "results" in results:
|
|
@@ -156,16 +151,15 @@ class Mem0Tools(Toolkit):
|
|
|
156
151
|
log_error(f"Error searching memory: {e}")
|
|
157
152
|
return f"Error searching memory: {e}"
|
|
158
153
|
|
|
159
|
-
def get_all_memories(self,
|
|
154
|
+
def get_all_memories(self, session_state: Dict[str, Any]) -> str:
|
|
160
155
|
"""Return **all** memories for the current user as a JSON string."""
|
|
161
156
|
|
|
162
|
-
resolved_user_id = self._get_user_id("get_all_memories",
|
|
157
|
+
resolved_user_id = self._get_user_id("get_all_memories", session_state=session_state)
|
|
163
158
|
if isinstance(resolved_user_id, str) and resolved_user_id.startswith("Error in get_all_memories:"):
|
|
164
159
|
return resolved_user_id
|
|
165
160
|
try:
|
|
166
161
|
results = self.client.get_all(
|
|
167
162
|
user_id=resolved_user_id,
|
|
168
|
-
output_format="v1.1",
|
|
169
163
|
)
|
|
170
164
|
|
|
171
165
|
if isinstance(results, dict) and "results" in results:
|
|
@@ -183,10 +177,10 @@ class Mem0Tools(Toolkit):
|
|
|
183
177
|
log_error(f"Error getting all memories: {e}")
|
|
184
178
|
return f"Error getting all memories: {e}"
|
|
185
179
|
|
|
186
|
-
def delete_all_memories(self,
|
|
180
|
+
def delete_all_memories(self, session_state: Dict[str, Any]) -> str:
|
|
187
181
|
"""Delete *all* memories associated with the current user"""
|
|
188
182
|
|
|
189
|
-
resolved_user_id = self._get_user_id("delete_all_memories",
|
|
183
|
+
resolved_user_id = self._get_user_id("delete_all_memories", session_state=session_state)
|
|
190
184
|
if isinstance(resolved_user_id, str) and resolved_user_id.startswith("Error in delete_all_memories:"):
|
|
191
185
|
error_msg = resolved_user_id
|
|
192
186
|
log_error(error_msg)
|