agno 2.0.8__py3-none-any.whl → 2.0.9__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 +2 -2
- agno/db/base.py +14 -0
- agno/db/dynamo/dynamo.py +107 -27
- agno/db/firestore/firestore.py +109 -33
- agno/db/gcs_json/gcs_json_db.py +100 -20
- agno/db/in_memory/in_memory_db.py +95 -20
- agno/db/json/json_db.py +101 -21
- agno/db/migrations/v1_to_v2.py +181 -35
- agno/db/mongo/mongo.py +251 -26
- agno/db/mysql/mysql.py +307 -6
- agno/db/postgres/postgres.py +279 -33
- agno/db/redis/redis.py +99 -22
- agno/db/singlestore/singlestore.py +319 -38
- agno/db/sqlite/sqlite.py +339 -23
- agno/models/anthropic/claude.py +0 -20
- agno/models/huggingface/huggingface.py +2 -1
- agno/models/ollama/chat.py +28 -2
- agno/models/openai/chat.py +7 -0
- agno/models/openai/responses.py +8 -8
- agno/os/interfaces/base.py +2 -0
- agno/os/interfaces/slack/router.py +50 -10
- agno/os/interfaces/slack/slack.py +6 -4
- agno/os/interfaces/whatsapp/router.py +7 -4
- agno/os/router.py +18 -0
- agno/os/utils.py +2 -2
- agno/reasoning/azure_ai_foundry.py +2 -2
- agno/reasoning/deepseek.py +2 -2
- agno/reasoning/groq.py +2 -2
- agno/reasoning/ollama.py +2 -2
- agno/reasoning/openai.py +2 -2
- agno/run/base.py +15 -2
- agno/team/team.py +0 -7
- agno/tools/mcp_toolbox.py +284 -0
- agno/tools/scrapegraph.py +58 -31
- agno/tools/whatsapp.py +1 -1
- agno/utils/print_response/agent.py +2 -2
- agno/utils/print_response/team.py +6 -6
- agno/utils/reasoning.py +22 -1
- agno/utils/string.py +9 -0
- agno/workflow/workflow.py +0 -1
- {agno-2.0.8.dist-info → agno-2.0.9.dist-info}/METADATA +4 -1
- {agno-2.0.8.dist-info → agno-2.0.9.dist-info}/RECORD +45 -44
- {agno-2.0.8.dist-info → agno-2.0.9.dist-info}/WHEEL +0 -0
- {agno-2.0.8.dist-info → agno-2.0.9.dist-info}/licenses/LICENSE +0 -0
- {agno-2.0.8.dist-info → agno-2.0.9.dist-info}/top_level.txt +0 -0
agno/agent/agent.py
CHANGED
|
@@ -7406,8 +7406,8 @@ class Agent:
|
|
|
7406
7406
|
"parser_model": self.parser_model.to_dict() if self.parser_model else None,
|
|
7407
7407
|
"output_model": self.output_model.to_dict() if self.output_model else None,
|
|
7408
7408
|
"has_tools": self.tools is not None,
|
|
7409
|
-
"has_memory": self.enable_user_memories is
|
|
7410
|
-
"has_reasoning": self.reasoning is
|
|
7409
|
+
"has_memory": self.enable_user_memories is True,
|
|
7410
|
+
"has_reasoning": self.reasoning is True,
|
|
7411
7411
|
"has_knowledge": self.knowledge is not None,
|
|
7412
7412
|
"has_input_schema": self.input_schema is not None,
|
|
7413
7413
|
"has_output_schema": self.output_schema is not None,
|
agno/db/base.py
CHANGED
|
@@ -81,6 +81,13 @@ class BaseDb(ABC):
|
|
|
81
81
|
) -> Optional[Union[Session, Dict[str, Any]]]:
|
|
82
82
|
raise NotImplementedError
|
|
83
83
|
|
|
84
|
+
@abstractmethod
|
|
85
|
+
def upsert_sessions(
|
|
86
|
+
self, sessions: List[Session], deserialize: Optional[bool] = True
|
|
87
|
+
) -> List[Union[Session, Dict[str, Any]]]:
|
|
88
|
+
"""Bulk upsert multiple sessions for improved performance on large datasets."""
|
|
89
|
+
raise NotImplementedError
|
|
90
|
+
|
|
84
91
|
# --- Memory ---
|
|
85
92
|
|
|
86
93
|
@abstractmethod
|
|
@@ -135,6 +142,13 @@ class BaseDb(ABC):
|
|
|
135
142
|
) -> Optional[Union[UserMemory, Dict[str, Any]]]:
|
|
136
143
|
raise NotImplementedError
|
|
137
144
|
|
|
145
|
+
@abstractmethod
|
|
146
|
+
def upsert_memories(
|
|
147
|
+
self, memories: List[UserMemory], deserialize: Optional[bool] = True
|
|
148
|
+
) -> List[Union[UserMemory, Dict[str, Any]]]:
|
|
149
|
+
"""Bulk upsert multiple memories for improved performance on large datasets."""
|
|
150
|
+
raise NotImplementedError
|
|
151
|
+
|
|
138
152
|
# --- Metrics ---
|
|
139
153
|
@abstractmethod
|
|
140
154
|
def get_metrics(
|
agno/db/dynamo/dynamo.py
CHANGED
|
@@ -31,7 +31,7 @@ from agno.db.schemas.evals import EvalFilterType, EvalRunRecord, EvalType
|
|
|
31
31
|
from agno.db.schemas.knowledge import KnowledgeRow
|
|
32
32
|
from agno.db.schemas.memory import UserMemory
|
|
33
33
|
from agno.session import AgentSession, Session, TeamSession, WorkflowSession
|
|
34
|
-
from agno.utils.log import log_debug, log_error
|
|
34
|
+
from agno.utils.log import log_debug, log_error, log_info
|
|
35
35
|
from agno.utils.string import generate_id
|
|
36
36
|
|
|
37
37
|
try:
|
|
@@ -232,6 +232,7 @@ class DynamoDb(BaseDb):
|
|
|
232
232
|
|
|
233
233
|
except Exception as e:
|
|
234
234
|
log_error(f"Failed to delete sessions: {e}")
|
|
235
|
+
raise e
|
|
235
236
|
|
|
236
237
|
def get_session(
|
|
237
238
|
self,
|
|
@@ -290,7 +291,7 @@ class DynamoDb(BaseDb):
|
|
|
290
291
|
|
|
291
292
|
except Exception as e:
|
|
292
293
|
log_error(f"Failed to get session {session_id}: {e}")
|
|
293
|
-
|
|
294
|
+
raise e
|
|
294
295
|
|
|
295
296
|
def get_sessions(
|
|
296
297
|
self,
|
|
@@ -410,7 +411,7 @@ class DynamoDb(BaseDb):
|
|
|
410
411
|
|
|
411
412
|
except Exception as e:
|
|
412
413
|
log_error(f"Failed to get sessions: {e}")
|
|
413
|
-
|
|
414
|
+
raise e
|
|
414
415
|
|
|
415
416
|
def rename_session(
|
|
416
417
|
self,
|
|
@@ -478,7 +479,7 @@ class DynamoDb(BaseDb):
|
|
|
478
479
|
|
|
479
480
|
except Exception as e:
|
|
480
481
|
log_error(f"Failed to rename session {session_id}: {e}")
|
|
481
|
-
|
|
482
|
+
raise e
|
|
482
483
|
|
|
483
484
|
def upsert_session(
|
|
484
485
|
self, session: Session, deserialize: Optional[bool] = True
|
|
@@ -520,7 +521,44 @@ class DynamoDb(BaseDb):
|
|
|
520
521
|
|
|
521
522
|
except Exception as e:
|
|
522
523
|
log_error(f"Failed to upsert session {session.session_id}: {e}")
|
|
523
|
-
|
|
524
|
+
raise e
|
|
525
|
+
|
|
526
|
+
def upsert_sessions(
|
|
527
|
+
self, sessions: List[Session], deserialize: Optional[bool] = True
|
|
528
|
+
) -> List[Union[Session, Dict[str, Any]]]:
|
|
529
|
+
"""
|
|
530
|
+
Bulk upsert multiple sessions for improved performance on large datasets.
|
|
531
|
+
|
|
532
|
+
Args:
|
|
533
|
+
sessions (List[Session]): List of sessions to upsert.
|
|
534
|
+
deserialize (Optional[bool]): Whether to deserialize the sessions. Defaults to True.
|
|
535
|
+
|
|
536
|
+
Returns:
|
|
537
|
+
List[Union[Session, Dict[str, Any]]]: List of upserted sessions.
|
|
538
|
+
|
|
539
|
+
Raises:
|
|
540
|
+
Exception: If an error occurs during bulk upsert.
|
|
541
|
+
"""
|
|
542
|
+
if not sessions:
|
|
543
|
+
return []
|
|
544
|
+
|
|
545
|
+
try:
|
|
546
|
+
log_info(
|
|
547
|
+
f"DynamoDb doesn't support efficient bulk operations, falling back to individual upserts for {len(sessions)} sessions"
|
|
548
|
+
)
|
|
549
|
+
|
|
550
|
+
# Fall back to individual upserts
|
|
551
|
+
results = []
|
|
552
|
+
for session in sessions:
|
|
553
|
+
if session is not None:
|
|
554
|
+
result = self.upsert_session(session, deserialize=deserialize)
|
|
555
|
+
if result is not None:
|
|
556
|
+
results.append(result)
|
|
557
|
+
return results
|
|
558
|
+
|
|
559
|
+
except Exception as e:
|
|
560
|
+
log_error(f"Exception during bulk session upsert: {e}")
|
|
561
|
+
return []
|
|
524
562
|
|
|
525
563
|
# --- User Memory ---
|
|
526
564
|
|
|
@@ -543,6 +581,7 @@ class DynamoDb(BaseDb):
|
|
|
543
581
|
|
|
544
582
|
except Exception as e:
|
|
545
583
|
log_error(f"Failed to delete user memory {memory_id}: {e}")
|
|
584
|
+
raise e
|
|
546
585
|
|
|
547
586
|
def delete_user_memories(self, memory_ids: List[str]) -> None:
|
|
548
587
|
"""
|
|
@@ -567,6 +606,7 @@ class DynamoDb(BaseDb):
|
|
|
567
606
|
|
|
568
607
|
except Exception as e:
|
|
569
608
|
log_error(f"Failed to delete user memories: {e}")
|
|
609
|
+
raise e
|
|
570
610
|
|
|
571
611
|
def get_all_memory_topics(self) -> List[str]:
|
|
572
612
|
"""Get all memory topics from the database.
|
|
@@ -599,7 +639,7 @@ class DynamoDb(BaseDb):
|
|
|
599
639
|
|
|
600
640
|
except Exception as e:
|
|
601
641
|
log_error(f"Exception reading from memory table: {e}")
|
|
602
|
-
|
|
642
|
+
raise e
|
|
603
643
|
|
|
604
644
|
def get_user_memory(
|
|
605
645
|
self, memory_id: str, deserialize: Optional[bool] = True
|
|
@@ -632,7 +672,7 @@ class DynamoDb(BaseDb):
|
|
|
632
672
|
|
|
633
673
|
except Exception as e:
|
|
634
674
|
log_error(f"Failed to get user memory {memory_id}: {e}")
|
|
635
|
-
|
|
675
|
+
raise e
|
|
636
676
|
|
|
637
677
|
def get_user_memories(
|
|
638
678
|
self,
|
|
@@ -752,7 +792,7 @@ class DynamoDb(BaseDb):
|
|
|
752
792
|
|
|
753
793
|
except Exception as e:
|
|
754
794
|
log_error(f"Failed to get user memories: {e}")
|
|
755
|
-
|
|
795
|
+
raise e
|
|
756
796
|
|
|
757
797
|
def get_user_memory_stats(
|
|
758
798
|
self,
|
|
@@ -838,7 +878,7 @@ class DynamoDb(BaseDb):
|
|
|
838
878
|
|
|
839
879
|
except Exception as e:
|
|
840
880
|
log_error(f"Failed to get user memory stats: {e}")
|
|
841
|
-
|
|
881
|
+
raise e
|
|
842
882
|
|
|
843
883
|
def upsert_user_memory(
|
|
844
884
|
self, memory: UserMemory, deserialize: Optional[bool] = True
|
|
@@ -867,7 +907,44 @@ class DynamoDb(BaseDb):
|
|
|
867
907
|
|
|
868
908
|
except Exception as e:
|
|
869
909
|
log_error(f"Failed to upsert user memory: {e}")
|
|
870
|
-
|
|
910
|
+
raise e
|
|
911
|
+
|
|
912
|
+
def upsert_memories(
|
|
913
|
+
self, memories: List[UserMemory], deserialize: Optional[bool] = True
|
|
914
|
+
) -> List[Union[UserMemory, Dict[str, Any]]]:
|
|
915
|
+
"""
|
|
916
|
+
Bulk upsert multiple user memories for improved performance on large datasets.
|
|
917
|
+
|
|
918
|
+
Args:
|
|
919
|
+
memories (List[UserMemory]): List of memories to upsert.
|
|
920
|
+
deserialize (Optional[bool]): Whether to deserialize the memories. Defaults to True.
|
|
921
|
+
|
|
922
|
+
Returns:
|
|
923
|
+
List[Union[UserMemory, Dict[str, Any]]]: List of upserted memories.
|
|
924
|
+
|
|
925
|
+
Raises:
|
|
926
|
+
Exception: If an error occurs during bulk upsert.
|
|
927
|
+
"""
|
|
928
|
+
if not memories:
|
|
929
|
+
return []
|
|
930
|
+
|
|
931
|
+
try:
|
|
932
|
+
log_info(
|
|
933
|
+
f"DynamoDb doesn't support efficient bulk operations, falling back to individual upserts for {len(memories)} memories"
|
|
934
|
+
)
|
|
935
|
+
|
|
936
|
+
# Fall back to individual upserts
|
|
937
|
+
results = []
|
|
938
|
+
for memory in memories:
|
|
939
|
+
if memory is not None:
|
|
940
|
+
result = self.upsert_user_memory(memory, deserialize=deserialize)
|
|
941
|
+
if result is not None:
|
|
942
|
+
results.append(result)
|
|
943
|
+
return results
|
|
944
|
+
|
|
945
|
+
except Exception as e:
|
|
946
|
+
log_error(f"Exception during bulk memory upsert: {e}")
|
|
947
|
+
return []
|
|
871
948
|
|
|
872
949
|
def clear_memories(self) -> None:
|
|
873
950
|
"""Delete all memories from the database.
|
|
@@ -908,6 +985,7 @@ class DynamoDb(BaseDb):
|
|
|
908
985
|
from agno.utils.log import log_warning
|
|
909
986
|
|
|
910
987
|
log_warning(f"Exception deleting all memories: {e}")
|
|
988
|
+
raise e
|
|
911
989
|
|
|
912
990
|
# --- Metrics ---
|
|
913
991
|
|
|
@@ -985,7 +1063,7 @@ class DynamoDb(BaseDb):
|
|
|
985
1063
|
|
|
986
1064
|
except Exception as e:
|
|
987
1065
|
log_error(f"Failed to calculate metrics: {e}")
|
|
988
|
-
|
|
1066
|
+
raise e
|
|
989
1067
|
|
|
990
1068
|
def _get_metrics_calculation_starting_date(self) -> Optional[date]:
|
|
991
1069
|
"""Get the first date for which metrics calculation is needed:
|
|
@@ -1071,7 +1149,7 @@ class DynamoDb(BaseDb):
|
|
|
1071
1149
|
|
|
1072
1150
|
except Exception as e:
|
|
1073
1151
|
log_error(f"Failed to get metrics calculation starting date: {e}")
|
|
1074
|
-
|
|
1152
|
+
raise e
|
|
1075
1153
|
|
|
1076
1154
|
def _get_all_sessions_for_metrics_calculation(
|
|
1077
1155
|
self, start_timestamp: int, end_timestamp: int
|
|
@@ -1129,7 +1207,7 @@ class DynamoDb(BaseDb):
|
|
|
1129
1207
|
|
|
1130
1208
|
except Exception as e:
|
|
1131
1209
|
log_error(f"Failed to get sessions for metrics calculation: {e}")
|
|
1132
|
-
|
|
1210
|
+
raise e
|
|
1133
1211
|
|
|
1134
1212
|
def _bulk_upsert_metrics(self, metrics_records: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
|
|
1135
1213
|
"""Bulk upsert metrics records into DynamoDB with proper deduplication.
|
|
@@ -1157,7 +1235,7 @@ class DynamoDb(BaseDb):
|
|
|
1157
1235
|
|
|
1158
1236
|
except Exception as e:
|
|
1159
1237
|
log_error(f"Failed to bulk upsert metrics: {e}")
|
|
1160
|
-
|
|
1238
|
+
raise e
|
|
1161
1239
|
|
|
1162
1240
|
def _upsert_single_metrics_record(self, table_name: str, record: Dict[str, Any]) -> Optional[Dict[str, Any]]:
|
|
1163
1241
|
"""Upsert a single metrics record, checking for existing records with the same date.
|
|
@@ -1189,7 +1267,7 @@ class DynamoDb(BaseDb):
|
|
|
1189
1267
|
|
|
1190
1268
|
except Exception as e:
|
|
1191
1269
|
log_error(f"Failed to upsert single metrics record: {e}")
|
|
1192
|
-
|
|
1270
|
+
raise e
|
|
1193
1271
|
|
|
1194
1272
|
def _get_existing_metrics_record(self, table_name: str, date_str: str) -> Optional[Dict[str, Any]]:
|
|
1195
1273
|
"""Get existing metrics record for a given date.
|
|
@@ -1222,7 +1300,7 @@ class DynamoDb(BaseDb):
|
|
|
1222
1300
|
|
|
1223
1301
|
except Exception as e:
|
|
1224
1302
|
log_error(f"Failed to get existing metrics record for date {date_str}: {e}")
|
|
1225
|
-
|
|
1303
|
+
raise e
|
|
1226
1304
|
|
|
1227
1305
|
def _update_existing_metrics_record(
|
|
1228
1306
|
self,
|
|
@@ -1256,7 +1334,7 @@ class DynamoDb(BaseDb):
|
|
|
1256
1334
|
|
|
1257
1335
|
except Exception as e:
|
|
1258
1336
|
log_error(f"Failed to update existing metrics record: {e}")
|
|
1259
|
-
|
|
1337
|
+
raise e
|
|
1260
1338
|
|
|
1261
1339
|
def _create_new_metrics_record(self, table_name: str, record: Dict[str, Any]) -> Optional[Dict[str, Any]]:
|
|
1262
1340
|
"""Create a new metrics record.
|
|
@@ -1280,7 +1358,7 @@ class DynamoDb(BaseDb):
|
|
|
1280
1358
|
|
|
1281
1359
|
except Exception as e:
|
|
1282
1360
|
log_error(f"Failed to create new metrics record: {e}")
|
|
1283
|
-
|
|
1361
|
+
raise e
|
|
1284
1362
|
|
|
1285
1363
|
def _prepare_metrics_record_for_dynamo(self, record: Dict[str, Any]) -> Dict[str, Any]:
|
|
1286
1364
|
"""Prepare a metrics record for DynamoDB serialization by converting all data types properly.
|
|
@@ -1403,7 +1481,7 @@ class DynamoDb(BaseDb):
|
|
|
1403
1481
|
|
|
1404
1482
|
except Exception as e:
|
|
1405
1483
|
log_error(f"Failed to get metrics: {e}")
|
|
1406
|
-
|
|
1484
|
+
raise e
|
|
1407
1485
|
|
|
1408
1486
|
# --- Knowledge methods ---
|
|
1409
1487
|
|
|
@@ -1425,6 +1503,7 @@ class DynamoDb(BaseDb):
|
|
|
1425
1503
|
|
|
1426
1504
|
except Exception as e:
|
|
1427
1505
|
log_error(f"Failed to delete knowledge content {id}: {e}")
|
|
1506
|
+
raise e
|
|
1428
1507
|
|
|
1429
1508
|
def get_knowledge_content(self, id: str) -> Optional[KnowledgeRow]:
|
|
1430
1509
|
"""Get a knowledge row from the database.
|
|
@@ -1447,7 +1526,7 @@ class DynamoDb(BaseDb):
|
|
|
1447
1526
|
|
|
1448
1527
|
except Exception as e:
|
|
1449
1528
|
log_error(f"Failed to get knowledge content {id}: {e}")
|
|
1450
|
-
|
|
1529
|
+
raise e
|
|
1451
1530
|
|
|
1452
1531
|
def get_knowledge_contents(
|
|
1453
1532
|
self,
|
|
@@ -1519,7 +1598,7 @@ class DynamoDb(BaseDb):
|
|
|
1519
1598
|
|
|
1520
1599
|
except Exception as e:
|
|
1521
1600
|
log_error(f"Failed to get knowledge contents: {e}")
|
|
1522
|
-
|
|
1601
|
+
raise e
|
|
1523
1602
|
|
|
1524
1603
|
def upsert_knowledge_content(self, knowledge_row: KnowledgeRow):
|
|
1525
1604
|
"""Upsert knowledge content in the database.
|
|
@@ -1540,7 +1619,7 @@ class DynamoDb(BaseDb):
|
|
|
1540
1619
|
|
|
1541
1620
|
except Exception as e:
|
|
1542
1621
|
log_error(f"Failed to upsert knowledge content {knowledge_row.id}: {e}")
|
|
1543
|
-
|
|
1622
|
+
raise e
|
|
1544
1623
|
|
|
1545
1624
|
# --- Eval ---
|
|
1546
1625
|
|
|
@@ -1570,7 +1649,7 @@ class DynamoDb(BaseDb):
|
|
|
1570
1649
|
|
|
1571
1650
|
except Exception as e:
|
|
1572
1651
|
log_error(f"Failed to create eval run: {e}")
|
|
1573
|
-
|
|
1652
|
+
raise e
|
|
1574
1653
|
|
|
1575
1654
|
def delete_eval_runs(self, eval_run_ids: List[str]) -> None:
|
|
1576
1655
|
if not eval_run_ids or not self.eval_table_name:
|
|
@@ -1588,6 +1667,7 @@ class DynamoDb(BaseDb):
|
|
|
1588
1667
|
|
|
1589
1668
|
except Exception as e:
|
|
1590
1669
|
log_error(f"Failed to delete eval runs: {e}")
|
|
1670
|
+
raise e
|
|
1591
1671
|
|
|
1592
1672
|
def get_eval_run_raw(self, eval_run_id: str, table: Optional[Any] = None) -> Optional[Dict[str, Any]]:
|
|
1593
1673
|
if not self.eval_table_name:
|
|
@@ -1603,7 +1683,7 @@ class DynamoDb(BaseDb):
|
|
|
1603
1683
|
|
|
1604
1684
|
except Exception as e:
|
|
1605
1685
|
log_error(f"Failed to get eval run {eval_run_id}: {e}")
|
|
1606
|
-
|
|
1686
|
+
raise e
|
|
1607
1687
|
|
|
1608
1688
|
def get_eval_run(self, eval_run_id: str, table: Optional[Any] = None) -> Optional[EvalRunRecord]:
|
|
1609
1689
|
if not self.eval_table_name:
|
|
@@ -1619,7 +1699,7 @@ class DynamoDb(BaseDb):
|
|
|
1619
1699
|
|
|
1620
1700
|
except Exception as e:
|
|
1621
1701
|
log_error(f"Failed to get eval run {eval_run_id}: {e}")
|
|
1622
|
-
|
|
1702
|
+
raise e
|
|
1623
1703
|
|
|
1624
1704
|
def get_eval_runs(
|
|
1625
1705
|
self,
|
|
@@ -1718,7 +1798,7 @@ class DynamoDb(BaseDb):
|
|
|
1718
1798
|
|
|
1719
1799
|
except Exception as e:
|
|
1720
1800
|
log_error(f"Failed to get eval runs: {e}")
|
|
1721
|
-
|
|
1801
|
+
raise e
|
|
1722
1802
|
|
|
1723
1803
|
def rename_eval_run(
|
|
1724
1804
|
self, eval_run_id: str, name: str, deserialize: Optional[bool] = True
|
|
@@ -1750,4 +1830,4 @@ class DynamoDb(BaseDb):
|
|
|
1750
1830
|
|
|
1751
1831
|
except Exception as e:
|
|
1752
1832
|
log_error(f"Failed to rename eval run {eval_run_id}: {e}")
|
|
1753
|
-
|
|
1833
|
+
raise e
|