agno 2.0.7__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 +83 -51
- 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 +322 -47
- 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/knowledge/embedder/sentence_transformer.py +3 -3
- agno/knowledge/knowledge.py +152 -31
- agno/knowledge/types.py +8 -0
- agno/models/anthropic/claude.py +0 -20
- agno/models/cometapi/__init__.py +5 -0
- agno/models/cometapi/cometapi.py +57 -0
- agno/models/google/gemini.py +4 -8
- agno/models/huggingface/huggingface.py +2 -1
- agno/models/ollama/chat.py +52 -3
- agno/models/openai/chat.py +9 -7
- agno/models/openai/responses.py +21 -17
- agno/os/interfaces/agui/agui.py +2 -2
- agno/os/interfaces/agui/utils.py +81 -18
- 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/interfaces/whatsapp/whatsapp.py +2 -2
- agno/os/router.py +18 -0
- agno/os/utils.py +10 -2
- agno/reasoning/azure_ai_foundry.py +2 -2
- agno/reasoning/deepseek.py +2 -2
- agno/reasoning/default.py +3 -1
- 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/session/agent.py +8 -5
- agno/session/team.py +14 -10
- agno/team/team.py +218 -111
- agno/tools/function.py +43 -4
- agno/tools/mcp.py +60 -37
- agno/tools/mcp_toolbox.py +284 -0
- agno/tools/scrapegraph.py +58 -31
- agno/tools/whatsapp.py +1 -1
- agno/utils/gemini.py +147 -19
- agno/utils/models/claude.py +9 -0
- agno/utils/print_response/agent.py +18 -2
- agno/utils/print_response/team.py +22 -6
- agno/utils/reasoning.py +22 -1
- agno/utils/string.py +9 -0
- agno/vectordb/base.py +2 -2
- agno/vectordb/langchaindb/langchaindb.py +5 -7
- agno/vectordb/llamaindex/llamaindexdb.py +25 -6
- agno/workflow/workflow.py +30 -15
- {agno-2.0.7.dist-info → agno-2.0.9.dist-info}/METADATA +4 -1
- {agno-2.0.7.dist-info → agno-2.0.9.dist-info}/RECORD +64 -61
- {agno-2.0.7.dist-info → agno-2.0.9.dist-info}/WHEEL +0 -0
- {agno-2.0.7.dist-info → agno-2.0.9.dist-info}/licenses/LICENSE +0 -0
- {agno-2.0.7.dist-info → agno-2.0.9.dist-info}/top_level.txt +0 -0
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
|
agno/db/firestore/firestore.py
CHANGED
|
@@ -205,7 +205,7 @@ class FirestoreDb(BaseDb):
|
|
|
205
205
|
|
|
206
206
|
except Exception as e:
|
|
207
207
|
log_error(f"Error deleting session: {e}")
|
|
208
|
-
|
|
208
|
+
raise e
|
|
209
209
|
|
|
210
210
|
def delete_sessions(self, session_ids: List[str]) -> None:
|
|
211
211
|
"""Delete multiple sessions from the database.
|
|
@@ -230,6 +230,7 @@ class FirestoreDb(BaseDb):
|
|
|
230
230
|
|
|
231
231
|
except Exception as e:
|
|
232
232
|
log_error(f"Error deleting sessions: {e}")
|
|
233
|
+
raise e
|
|
233
234
|
|
|
234
235
|
def get_session(
|
|
235
236
|
self,
|
|
@@ -288,7 +289,7 @@ class FirestoreDb(BaseDb):
|
|
|
288
289
|
|
|
289
290
|
except Exception as e:
|
|
290
291
|
log_error(f"Exception reading session: {e}")
|
|
291
|
-
|
|
292
|
+
raise e
|
|
292
293
|
|
|
293
294
|
def get_sessions(
|
|
294
295
|
self,
|
|
@@ -402,7 +403,7 @@ class FirestoreDb(BaseDb):
|
|
|
402
403
|
|
|
403
404
|
except Exception as e:
|
|
404
405
|
log_error(f"Exception reading sessions: {e}")
|
|
405
|
-
|
|
406
|
+
raise e
|
|
406
407
|
|
|
407
408
|
def rename_session(
|
|
408
409
|
self, session_id: str, session_type: SessionType, session_name: str, deserialize: Optional[bool] = True
|
|
@@ -457,7 +458,7 @@ class FirestoreDb(BaseDb):
|
|
|
457
458
|
|
|
458
459
|
except Exception as e:
|
|
459
460
|
log_error(f"Exception renaming session: {e}")
|
|
460
|
-
|
|
461
|
+
raise e
|
|
461
462
|
|
|
462
463
|
def upsert_session(
|
|
463
464
|
self, session: Session, deserialize: Optional[bool] = True
|
|
@@ -554,7 +555,44 @@ class FirestoreDb(BaseDb):
|
|
|
554
555
|
|
|
555
556
|
except Exception as e:
|
|
556
557
|
log_error(f"Exception upserting session: {e}")
|
|
557
|
-
|
|
558
|
+
raise e
|
|
559
|
+
|
|
560
|
+
def upsert_sessions(
|
|
561
|
+
self, sessions: List[Session], deserialize: Optional[bool] = True
|
|
562
|
+
) -> List[Union[Session, Dict[str, Any]]]:
|
|
563
|
+
"""
|
|
564
|
+
Bulk upsert multiple sessions for improved performance on large datasets.
|
|
565
|
+
|
|
566
|
+
Args:
|
|
567
|
+
sessions (List[Session]): List of sessions to upsert.
|
|
568
|
+
deserialize (Optional[bool]): Whether to deserialize the sessions. Defaults to True.
|
|
569
|
+
|
|
570
|
+
Returns:
|
|
571
|
+
List[Union[Session, Dict[str, Any]]]: List of upserted sessions.
|
|
572
|
+
|
|
573
|
+
Raises:
|
|
574
|
+
Exception: If an error occurs during bulk upsert.
|
|
575
|
+
"""
|
|
576
|
+
if not sessions:
|
|
577
|
+
return []
|
|
578
|
+
|
|
579
|
+
try:
|
|
580
|
+
log_info(
|
|
581
|
+
f"FirestoreDb doesn't support efficient bulk operations, falling back to individual upserts for {len(sessions)} sessions"
|
|
582
|
+
)
|
|
583
|
+
|
|
584
|
+
# Fall back to individual upserts
|
|
585
|
+
results = []
|
|
586
|
+
for session in sessions:
|
|
587
|
+
if session is not None:
|
|
588
|
+
result = self.upsert_session(session, deserialize=deserialize)
|
|
589
|
+
if result is not None:
|
|
590
|
+
results.append(result)
|
|
591
|
+
return results
|
|
592
|
+
|
|
593
|
+
except Exception as e:
|
|
594
|
+
log_error(f"Exception during bulk session upsert: {e}")
|
|
595
|
+
return []
|
|
558
596
|
|
|
559
597
|
# -- Memory methods --
|
|
560
598
|
|
|
@@ -587,6 +625,7 @@ class FirestoreDb(BaseDb):
|
|
|
587
625
|
|
|
588
626
|
except Exception as e:
|
|
589
627
|
log_error(f"Error deleting user memory: {e}")
|
|
628
|
+
raise e
|
|
590
629
|
|
|
591
630
|
def delete_user_memories(self, memory_ids: List[str]) -> None:
|
|
592
631
|
"""Delete user memories from the database.
|
|
@@ -617,6 +656,7 @@ class FirestoreDb(BaseDb):
|
|
|
617
656
|
|
|
618
657
|
except Exception as e:
|
|
619
658
|
log_error(f"Error deleting memories: {e}")
|
|
659
|
+
raise e
|
|
620
660
|
|
|
621
661
|
def get_all_memory_topics(self, create_collection_if_not_found: Optional[bool] = True) -> List[str]:
|
|
622
662
|
"""Get all memory topics from the database.
|
|
@@ -644,8 +684,8 @@ class FirestoreDb(BaseDb):
|
|
|
644
684
|
return [topic for topic in all_topics if topic]
|
|
645
685
|
|
|
646
686
|
except Exception as e:
|
|
647
|
-
log_error(f"Exception
|
|
648
|
-
|
|
687
|
+
log_error(f"Exception getting all memory topics: {e}")
|
|
688
|
+
raise e
|
|
649
689
|
|
|
650
690
|
def get_user_memory(self, memory_id: str, deserialize: Optional[bool] = True) -> Optional[UserMemory]:
|
|
651
691
|
"""Get a memory from the database.
|
|
@@ -677,8 +717,8 @@ class FirestoreDb(BaseDb):
|
|
|
677
717
|
return UserMemory.from_dict(result)
|
|
678
718
|
|
|
679
719
|
except Exception as e:
|
|
680
|
-
log_error(f"Exception
|
|
681
|
-
|
|
720
|
+
log_error(f"Exception getting user memory: {e}")
|
|
721
|
+
raise e
|
|
682
722
|
|
|
683
723
|
def get_user_memories(
|
|
684
724
|
self,
|
|
@@ -756,8 +796,8 @@ class FirestoreDb(BaseDb):
|
|
|
756
796
|
return [UserMemory.from_dict(record) for record in records]
|
|
757
797
|
|
|
758
798
|
except Exception as e:
|
|
759
|
-
log_error(f"Exception
|
|
760
|
-
|
|
799
|
+
log_error(f"Exception getting user memories: {e}")
|
|
800
|
+
raise e
|
|
761
801
|
|
|
762
802
|
def get_user_memory_stats(
|
|
763
803
|
self,
|
|
@@ -813,7 +853,7 @@ class FirestoreDb(BaseDb):
|
|
|
813
853
|
|
|
814
854
|
except Exception as e:
|
|
815
855
|
log_error(f"Exception getting user memory stats: {e}")
|
|
816
|
-
|
|
856
|
+
raise e
|
|
817
857
|
|
|
818
858
|
def upsert_user_memory(
|
|
819
859
|
self, memory: UserMemory, deserialize: Optional[bool] = True
|
|
@@ -859,7 +899,43 @@ class FirestoreDb(BaseDb):
|
|
|
859
899
|
|
|
860
900
|
except Exception as e:
|
|
861
901
|
log_error(f"Exception upserting user memory: {e}")
|
|
862
|
-
|
|
902
|
+
raise e
|
|
903
|
+
|
|
904
|
+
def upsert_memories(
|
|
905
|
+
self, memories: List[UserMemory], deserialize: Optional[bool] = True
|
|
906
|
+
) -> List[Union[UserMemory, Dict[str, Any]]]:
|
|
907
|
+
"""
|
|
908
|
+
Bulk upsert multiple user memories for improved performance on large datasets.
|
|
909
|
+
|
|
910
|
+
Args:
|
|
911
|
+
memories (List[UserMemory]): List of memories to upsert.
|
|
912
|
+
deserialize (Optional[bool]): Whether to deserialize the memories. Defaults to True.
|
|
913
|
+
|
|
914
|
+
Returns:
|
|
915
|
+
List[Union[UserMemory, Dict[str, Any]]]: List of upserted memories.
|
|
916
|
+
|
|
917
|
+
Raises:
|
|
918
|
+
Exception: If an error occurs during bulk upsert.
|
|
919
|
+
"""
|
|
920
|
+
if not memories:
|
|
921
|
+
return []
|
|
922
|
+
|
|
923
|
+
try:
|
|
924
|
+
log_info(
|
|
925
|
+
f"FirestoreDb doesn't support efficient bulk operations, falling back to individual upserts for {len(memories)} memories"
|
|
926
|
+
)
|
|
927
|
+
# Fall back to individual upserts
|
|
928
|
+
results = []
|
|
929
|
+
for memory in memories:
|
|
930
|
+
if memory is not None:
|
|
931
|
+
result = self.upsert_user_memory(memory, deserialize=deserialize)
|
|
932
|
+
if result is not None:
|
|
933
|
+
results.append(result)
|
|
934
|
+
return results
|
|
935
|
+
|
|
936
|
+
except Exception as e:
|
|
937
|
+
log_error(f"Exception during bulk memory upsert: {e}")
|
|
938
|
+
return []
|
|
863
939
|
|
|
864
940
|
def clear_memories(self) -> None:
|
|
865
941
|
"""Delete all memories from the database.
|
|
@@ -892,9 +968,8 @@ class FirestoreDb(BaseDb):
|
|
|
892
968
|
batch.commit()
|
|
893
969
|
|
|
894
970
|
except Exception as e:
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
log_warning(f"Exception deleting all memories: {e}")
|
|
971
|
+
log_error(f"Exception deleting all memories: {e}")
|
|
972
|
+
raise e
|
|
898
973
|
|
|
899
974
|
# -- Metrics methods --
|
|
900
975
|
|
|
@@ -928,8 +1003,8 @@ class FirestoreDb(BaseDb):
|
|
|
928
1003
|
return results
|
|
929
1004
|
|
|
930
1005
|
except Exception as e:
|
|
931
|
-
log_error(f"Exception
|
|
932
|
-
|
|
1006
|
+
log_error(f"Exception getting all sessions for metrics calculation: {e}")
|
|
1007
|
+
raise e
|
|
933
1008
|
|
|
934
1009
|
def _get_metrics_calculation_starting_date(self, collection_ref) -> Optional[date]:
|
|
935
1010
|
"""Get the first date for which metrics calculation is needed."""
|
|
@@ -961,7 +1036,7 @@ class FirestoreDb(BaseDb):
|
|
|
961
1036
|
|
|
962
1037
|
except Exception as e:
|
|
963
1038
|
log_error(f"Exception getting metrics calculation starting date: {e}")
|
|
964
|
-
|
|
1039
|
+
raise e
|
|
965
1040
|
|
|
966
1041
|
def calculate_metrics(self) -> Optional[list[dict]]:
|
|
967
1042
|
"""Calculate metrics for all dates without complete metrics."""
|
|
@@ -1053,7 +1128,7 @@ class FirestoreDb(BaseDb):
|
|
|
1053
1128
|
|
|
1054
1129
|
except Exception as e:
|
|
1055
1130
|
log_error(f"Exception getting metrics: {e}")
|
|
1056
|
-
|
|
1131
|
+
raise e
|
|
1057
1132
|
|
|
1058
1133
|
# -- Knowledge methods --
|
|
1059
1134
|
|
|
@@ -1074,7 +1149,8 @@ class FirestoreDb(BaseDb):
|
|
|
1074
1149
|
doc.reference.delete()
|
|
1075
1150
|
|
|
1076
1151
|
except Exception as e:
|
|
1077
|
-
log_error(f"Error deleting knowledge
|
|
1152
|
+
log_error(f"Error deleting knowledge content: {e}")
|
|
1153
|
+
raise e
|
|
1078
1154
|
|
|
1079
1155
|
def get_knowledge_content(self, id: str) -> Optional[KnowledgeRow]:
|
|
1080
1156
|
"""Get a knowledge row from the database.
|
|
@@ -1099,8 +1175,8 @@ class FirestoreDb(BaseDb):
|
|
|
1099
1175
|
return None
|
|
1100
1176
|
|
|
1101
1177
|
except Exception as e:
|
|
1102
|
-
log_error(f"Error getting knowledge
|
|
1103
|
-
|
|
1178
|
+
log_error(f"Error getting knowledge content: {e}")
|
|
1179
|
+
raise e
|
|
1104
1180
|
|
|
1105
1181
|
def get_knowledge_contents(
|
|
1106
1182
|
self,
|
|
@@ -1148,8 +1224,8 @@ class FirestoreDb(BaseDb):
|
|
|
1148
1224
|
return knowledge_rows, total_count
|
|
1149
1225
|
|
|
1150
1226
|
except Exception as e:
|
|
1151
|
-
log_error(f"Error getting knowledge
|
|
1152
|
-
|
|
1227
|
+
log_error(f"Error getting knowledge contents: {e}")
|
|
1228
|
+
raise e
|
|
1153
1229
|
|
|
1154
1230
|
def upsert_knowledge_content(self, knowledge_row: KnowledgeRow):
|
|
1155
1231
|
"""Upsert knowledge content in the database.
|
|
@@ -1179,8 +1255,8 @@ class FirestoreDb(BaseDb):
|
|
|
1179
1255
|
return knowledge_row
|
|
1180
1256
|
|
|
1181
1257
|
except Exception as e:
|
|
1182
|
-
log_error(f"Error upserting knowledge
|
|
1183
|
-
|
|
1258
|
+
log_error(f"Error upserting knowledge content: {e}")
|
|
1259
|
+
raise e
|
|
1184
1260
|
|
|
1185
1261
|
# -- Eval methods --
|
|
1186
1262
|
|
|
@@ -1203,7 +1279,7 @@ class FirestoreDb(BaseDb):
|
|
|
1203
1279
|
|
|
1204
1280
|
except Exception as e:
|
|
1205
1281
|
log_error(f"Error creating eval run: {e}")
|
|
1206
|
-
|
|
1282
|
+
raise e
|
|
1207
1283
|
|
|
1208
1284
|
def delete_eval_run(self, eval_run_id: str) -> None:
|
|
1209
1285
|
"""Delete an eval run from the database."""
|
|
@@ -1223,7 +1299,7 @@ class FirestoreDb(BaseDb):
|
|
|
1223
1299
|
|
|
1224
1300
|
except Exception as e:
|
|
1225
1301
|
log_error(f"Error deleting eval run {eval_run_id}: {e}")
|
|
1226
|
-
raise
|
|
1302
|
+
raise e
|
|
1227
1303
|
|
|
1228
1304
|
def delete_eval_runs(self, eval_run_ids: List[str]) -> None:
|
|
1229
1305
|
"""Delete multiple eval runs from the database.
|
|
@@ -1254,7 +1330,7 @@ class FirestoreDb(BaseDb):
|
|
|
1254
1330
|
|
|
1255
1331
|
except Exception as e:
|
|
1256
1332
|
log_error(f"Error deleting eval runs {eval_run_ids}: {e}")
|
|
1257
|
-
raise
|
|
1333
|
+
raise e
|
|
1258
1334
|
|
|
1259
1335
|
def get_eval_run(
|
|
1260
1336
|
self, eval_run_id: str, deserialize: Optional[bool] = True
|
|
@@ -1292,7 +1368,7 @@ class FirestoreDb(BaseDb):
|
|
|
1292
1368
|
|
|
1293
1369
|
except Exception as e:
|
|
1294
1370
|
log_error(f"Exception getting eval run {eval_run_id}: {e}")
|
|
1295
|
-
|
|
1371
|
+
raise e
|
|
1296
1372
|
|
|
1297
1373
|
def get_eval_runs(
|
|
1298
1374
|
self,
|
|
@@ -1393,7 +1469,7 @@ class FirestoreDb(BaseDb):
|
|
|
1393
1469
|
|
|
1394
1470
|
except Exception as e:
|
|
1395
1471
|
log_error(f"Exception getting eval runs: {e}")
|
|
1396
|
-
|
|
1472
|
+
raise e
|
|
1397
1473
|
|
|
1398
1474
|
def rename_eval_run(
|
|
1399
1475
|
self, eval_run_id: str, name: str, deserialize: Optional[bool] = True
|
|
@@ -1439,4 +1515,4 @@ class FirestoreDb(BaseDb):
|
|
|
1439
1515
|
|
|
1440
1516
|
except Exception as e:
|
|
1441
1517
|
log_error(f"Error updating eval run name {eval_run_id}: {e}")
|
|
1442
|
-
raise
|
|
1518
|
+
raise e
|