agno 2.1.9__py3-none-any.whl → 2.1.10__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 +646 -133
- agno/culture/__init__.py +3 -0
- agno/culture/manager.py +954 -0
- agno/db/async_postgres/async_postgres.py +232 -0
- agno/db/async_postgres/schemas.py +15 -0
- agno/db/async_postgres/utils.py +58 -0
- agno/db/base.py +83 -6
- agno/db/dynamo/dynamo.py +162 -0
- agno/db/dynamo/schemas.py +44 -0
- agno/db/dynamo/utils.py +59 -0
- agno/db/firestore/firestore.py +231 -0
- agno/db/firestore/schemas.py +10 -0
- agno/db/firestore/utils.py +96 -0
- agno/db/gcs_json/gcs_json_db.py +190 -0
- agno/db/gcs_json/utils.py +58 -0
- agno/db/in_memory/in_memory_db.py +118 -0
- agno/db/in_memory/utils.py +58 -0
- agno/db/json/json_db.py +129 -0
- agno/db/json/utils.py +58 -0
- agno/db/mongo/mongo.py +222 -0
- agno/db/mongo/schemas.py +10 -0
- agno/db/mongo/utils.py +59 -0
- agno/db/mysql/mysql.py +232 -1
- agno/db/mysql/schemas.py +14 -0
- agno/db/mysql/utils.py +58 -0
- agno/db/postgres/postgres.py +242 -0
- agno/db/postgres/schemas.py +15 -0
- agno/db/postgres/utils.py +58 -0
- agno/db/redis/redis.py +181 -0
- agno/db/redis/schemas.py +14 -0
- agno/db/redis/utils.py +58 -0
- agno/db/schemas/__init__.py +2 -1
- agno/db/schemas/culture.py +120 -0
- agno/db/singlestore/schemas.py +14 -0
- agno/db/singlestore/singlestore.py +231 -0
- agno/db/singlestore/utils.py +58 -0
- agno/db/sqlite/schemas.py +14 -0
- agno/db/sqlite/sqlite.py +274 -7
- agno/db/sqlite/utils.py +62 -0
- agno/db/surrealdb/models.py +51 -1
- agno/db/surrealdb/surrealdb.py +154 -0
- agno/db/surrealdb/utils.py +61 -1
- agno/knowledge/reader/field_labeled_csv_reader.py +0 -2
- agno/memory/manager.py +28 -11
- agno/models/message.py +0 -1
- agno/os/app.py +28 -6
- agno/team/team.py +1 -1
- agno/tools/gmail.py +59 -14
- agno/workflow/router.py +1 -1
- {agno-2.1.9.dist-info → agno-2.1.10.dist-info}/METADATA +1 -1
- {agno-2.1.9.dist-info → agno-2.1.10.dist-info}/RECORD +54 -51
- {agno-2.1.9.dist-info → agno-2.1.10.dist-info}/WHEEL +0 -0
- {agno-2.1.9.dist-info → agno-2.1.10.dist-info}/licenses/LICENSE +0 -0
- {agno-2.1.9.dist-info → agno-2.1.10.dist-info}/top_level.txt +0 -0
agno/agent/agent.py
CHANGED
|
@@ -27,7 +27,9 @@ from uuid import uuid4
|
|
|
27
27
|
|
|
28
28
|
from pydantic import BaseModel
|
|
29
29
|
|
|
30
|
+
from agno.culture.manager import CultureManager
|
|
30
31
|
from agno.db.base import AsyncBaseDb, BaseDb, SessionType, UserMemory
|
|
32
|
+
from agno.db.schemas.culture import CulturalKnowledge
|
|
31
33
|
from agno.exceptions import (
|
|
32
34
|
InputCheckError,
|
|
33
35
|
ModelProviderError,
|
|
@@ -349,6 +351,17 @@ class Agent:
|
|
|
349
351
|
# Metadata stored with this agent
|
|
350
352
|
metadata: Optional[Dict[str, Any]] = None
|
|
351
353
|
|
|
354
|
+
# --- Experimental Features ---
|
|
355
|
+
# --- Agent Culture ---
|
|
356
|
+
# Culture manager to use for this agent
|
|
357
|
+
culture_manager: Optional[CultureManager] = None
|
|
358
|
+
# Enable the agent to manage cultural knowledge
|
|
359
|
+
enable_agentic_culture: bool = False
|
|
360
|
+
# Update cultural knowledge after every run
|
|
361
|
+
update_cultural_knowledge: bool = False
|
|
362
|
+
# If True, the agent adds cultural knowledge in the response
|
|
363
|
+
add_culture_to_context: Optional[bool] = None
|
|
364
|
+
|
|
352
365
|
# --- Debug ---
|
|
353
366
|
# Enable debug logs
|
|
354
367
|
debug_mode: bool = False
|
|
@@ -447,6 +460,10 @@ class Agent:
|
|
|
447
460
|
store_events: bool = False,
|
|
448
461
|
events_to_skip: Optional[List[RunEvent]] = None,
|
|
449
462
|
role: Optional[str] = None,
|
|
463
|
+
culture_manager: Optional[CultureManager] = None,
|
|
464
|
+
enable_agentic_culture: bool = False,
|
|
465
|
+
update_cultural_knowledge: bool = False,
|
|
466
|
+
add_culture_to_context: Optional[bool] = None,
|
|
450
467
|
debug_mode: bool = False,
|
|
451
468
|
debug_level: Literal[1, 2] = 1,
|
|
452
469
|
telemetry: bool = True,
|
|
@@ -566,6 +583,11 @@ class Agent:
|
|
|
566
583
|
if self.events_to_skip is None:
|
|
567
584
|
self.events_to_skip = [RunEvent.run_content]
|
|
568
585
|
|
|
586
|
+
self.culture_manager = culture_manager
|
|
587
|
+
self.enable_agentic_culture = enable_agentic_culture
|
|
588
|
+
self.update_cultural_knowledge = update_cultural_knowledge
|
|
589
|
+
self.add_culture_to_context = add_culture_to_context
|
|
590
|
+
|
|
569
591
|
self.debug_mode = debug_mode
|
|
570
592
|
if debug_level not in [1, 2]:
|
|
571
593
|
log_warning(f"Invalid debug level: {debug_level}. Setting to 1.")
|
|
@@ -669,6 +691,23 @@ class Agent:
|
|
|
669
691
|
f"Cannot validate {type(input)} against input_schema. Expected dict or {self.input_schema.__name__} instance."
|
|
670
692
|
)
|
|
671
693
|
|
|
694
|
+
def _set_culture_manager(self) -> None:
|
|
695
|
+
if self.db is None:
|
|
696
|
+
log_warning("Database not provided. Cultural knowledge will not be stored.")
|
|
697
|
+
|
|
698
|
+
if self.culture_manager is None:
|
|
699
|
+
self.culture_manager = CultureManager(model=self.model, db=self.db)
|
|
700
|
+
else:
|
|
701
|
+
if self.culture_manager.model is None:
|
|
702
|
+
self.culture_manager.model = self.model
|
|
703
|
+
if self.culture_manager.db is None:
|
|
704
|
+
self.culture_manager.db = self.db
|
|
705
|
+
|
|
706
|
+
if self.add_culture_to_context is None:
|
|
707
|
+
self.add_culture_to_context = (
|
|
708
|
+
self.enable_agentic_culture or self.update_cultural_knowledge or self.culture_manager is not None
|
|
709
|
+
)
|
|
710
|
+
|
|
672
711
|
def _set_memory_manager(self) -> None:
|
|
673
712
|
if self.db is None:
|
|
674
713
|
log_warning("Database not provided. Memories will not be stored.")
|
|
@@ -709,6 +748,13 @@ class Agent:
|
|
|
709
748
|
self.set_id()
|
|
710
749
|
if self.enable_user_memories or self.enable_agentic_memory or self.memory_manager is not None:
|
|
711
750
|
self._set_memory_manager()
|
|
751
|
+
if (
|
|
752
|
+
self.add_culture_to_context
|
|
753
|
+
or self.update_cultural_knowledge
|
|
754
|
+
or self.enable_agentic_culture
|
|
755
|
+
or self.culture_manager is not None
|
|
756
|
+
):
|
|
757
|
+
self._set_culture_manager()
|
|
712
758
|
if self.enable_session_summaries or self.session_summary_manager is not None:
|
|
713
759
|
self._set_session_summary_manager()
|
|
714
760
|
|
|
@@ -791,8 +837,8 @@ class Agent:
|
|
|
791
837
|
debug_mode: Optional[bool] = None,
|
|
792
838
|
**kwargs: Any,
|
|
793
839
|
) -> RunOutput:
|
|
794
|
-
"""
|
|
795
|
-
|
|
840
|
+
"""Run the Agent and return the RunOutput.
|
|
841
|
+
|
|
796
842
|
Steps:
|
|
797
843
|
1. Execute pre-hooks
|
|
798
844
|
2. Prepare run messages
|
|
@@ -803,7 +849,7 @@ class Agent:
|
|
|
803
849
|
7. Calculate session metrics
|
|
804
850
|
8. Optional: Save output to file if save_response_to_file is set
|
|
805
851
|
9. Add RunOutput to Agent Session
|
|
806
|
-
10. Update Agent Memory
|
|
852
|
+
10. Update Agent Memory, Cultural Knowledge and Summaries
|
|
807
853
|
11. Save session to storage
|
|
808
854
|
"""
|
|
809
855
|
|
|
@@ -865,7 +911,7 @@ class Agent:
|
|
|
865
911
|
|
|
866
912
|
log_debug(f"Agent Run Start: {run_response.run_id}", center=True)
|
|
867
913
|
|
|
868
|
-
# 3. Reason about the task
|
|
914
|
+
# 3. Reason about the task if reasoning is enabled
|
|
869
915
|
self._handle_reasoning(run_response=run_response, run_messages=run_messages)
|
|
870
916
|
|
|
871
917
|
# Check for cancellation before model call
|
|
@@ -894,7 +940,11 @@ class Agent:
|
|
|
894
940
|
self._parse_response_with_parser_model(model_response, run_messages)
|
|
895
941
|
|
|
896
942
|
# 5. Update the RunOutput with the model response
|
|
897
|
-
self._update_run_response(
|
|
943
|
+
self._update_run_response(
|
|
944
|
+
model_response=model_response,
|
|
945
|
+
run_response=run_response,
|
|
946
|
+
run_messages=run_messages,
|
|
947
|
+
)
|
|
898
948
|
|
|
899
949
|
if self.store_media:
|
|
900
950
|
self._store_media(run_response, model_response)
|
|
@@ -902,7 +952,10 @@ class Agent:
|
|
|
902
952
|
# We should break out of the run function
|
|
903
953
|
if any(tool_call.is_paused for tool_call in run_response.tools or []):
|
|
904
954
|
return self._handle_agent_run_paused(
|
|
905
|
-
run_response=run_response,
|
|
955
|
+
run_response=run_response,
|
|
956
|
+
run_messages=run_messages,
|
|
957
|
+
session=session,
|
|
958
|
+
user_id=user_id,
|
|
906
959
|
)
|
|
907
960
|
|
|
908
961
|
# Convert the response to the structured format if needed
|
|
@@ -931,15 +984,21 @@ class Agent:
|
|
|
931
984
|
|
|
932
985
|
# 8. Optional: Save output to file if save_response_to_file is set
|
|
933
986
|
self.save_run_response_to_file(
|
|
934
|
-
run_response=run_response,
|
|
987
|
+
run_response=run_response,
|
|
988
|
+
input=run_messages.user_message,
|
|
989
|
+
session_id=session.session_id,
|
|
990
|
+
user_id=user_id,
|
|
935
991
|
)
|
|
936
992
|
|
|
937
993
|
# 9. Add the RunOutput to Agent Session
|
|
938
994
|
session.upsert_run(run=run_response)
|
|
939
995
|
|
|
940
|
-
# 10. Update Agent Memory
|
|
941
|
-
response_iterator = self.
|
|
942
|
-
run_response=run_response,
|
|
996
|
+
# 10. Update Agent Memory, Cultural Knowledge and Summaries
|
|
997
|
+
response_iterator = self._make_memories_cultural_knowledge_and_summaries(
|
|
998
|
+
run_response=run_response,
|
|
999
|
+
run_messages=run_messages,
|
|
1000
|
+
session=session,
|
|
1001
|
+
user_id=user_id,
|
|
943
1002
|
)
|
|
944
1003
|
# Consume the response iterator to ensure the memory is updated before the run is completed
|
|
945
1004
|
deque(response_iterator, maxlen=0)
|
|
@@ -989,7 +1048,7 @@ class Agent:
|
|
|
989
1048
|
5. Calculate session metrics
|
|
990
1049
|
6. Optional: Save output to file if save_response_to_file is set
|
|
991
1050
|
7. Add the RunOutput to the Agent Session
|
|
992
|
-
8. Update Agent Memory
|
|
1051
|
+
8. Update Agent Memory, Cultural Knowledge and Summaries
|
|
993
1052
|
9. Create the run completed event
|
|
994
1053
|
10. Save session to storage
|
|
995
1054
|
"""
|
|
@@ -1063,7 +1122,7 @@ class Agent:
|
|
|
1063
1122
|
# Check for cancellation before model processing
|
|
1064
1123
|
raise_if_cancelled(run_response.run_id) # type: ignore
|
|
1065
1124
|
|
|
1066
|
-
# 4.
|
|
1125
|
+
# 4. Generate a response from the Model (includes running function calls)
|
|
1067
1126
|
if self.output_model is None:
|
|
1068
1127
|
for event in self._handle_model_response_stream(
|
|
1069
1128
|
session=session,
|
|
@@ -1112,13 +1171,18 @@ class Agent:
|
|
|
1112
1171
|
|
|
1113
1172
|
# If a parser model is provided, structure the response separately
|
|
1114
1173
|
yield from self._parse_response_with_parser_model_stream(
|
|
1115
|
-
session=session,
|
|
1174
|
+
session=session,
|
|
1175
|
+
run_response=run_response,
|
|
1176
|
+
stream_intermediate_steps=stream_intermediate_steps,
|
|
1116
1177
|
)
|
|
1117
1178
|
|
|
1118
1179
|
# We should break out of the run function
|
|
1119
1180
|
if any(tool_call.is_paused for tool_call in run_response.tools or []):
|
|
1120
1181
|
yield from self._handle_agent_run_paused_stream(
|
|
1121
|
-
run_response=run_response,
|
|
1182
|
+
run_response=run_response,
|
|
1183
|
+
run_messages=run_messages,
|
|
1184
|
+
session=session,
|
|
1185
|
+
user_id=user_id,
|
|
1122
1186
|
)
|
|
1123
1187
|
return
|
|
1124
1188
|
|
|
@@ -1156,9 +1220,12 @@ class Agent:
|
|
|
1156
1220
|
# 7. Add RunOutput to Agent Session
|
|
1157
1221
|
session.upsert_run(run=run_response)
|
|
1158
1222
|
|
|
1159
|
-
# 8. Update Agent Memory
|
|
1160
|
-
yield from self.
|
|
1161
|
-
run_response=run_response,
|
|
1223
|
+
# 8. Update Agent Memory, Cultural Knowledge and Summaries
|
|
1224
|
+
yield from self._make_memories_cultural_knowledge_and_summaries(
|
|
1225
|
+
run_response=run_response,
|
|
1226
|
+
run_messages=run_messages,
|
|
1227
|
+
session=session,
|
|
1228
|
+
user_id=user_id,
|
|
1162
1229
|
)
|
|
1163
1230
|
|
|
1164
1231
|
# 9. Create the run completed event
|
|
@@ -1299,7 +1366,10 @@ class Agent:
|
|
|
1299
1366
|
self._hooks_normalised = True
|
|
1300
1367
|
|
|
1301
1368
|
session_id, user_id, session_state = self._initialize_session(
|
|
1302
|
-
run_id=run_id,
|
|
1369
|
+
run_id=run_id,
|
|
1370
|
+
session_id=session_id,
|
|
1371
|
+
user_id=user_id,
|
|
1372
|
+
session_state=session_state,
|
|
1303
1373
|
)
|
|
1304
1374
|
|
|
1305
1375
|
# Initialize the Agent
|
|
@@ -1470,7 +1540,10 @@ class Agent:
|
|
|
1470
1540
|
|
|
1471
1541
|
if stream:
|
|
1472
1542
|
return generator_wrapper( # type: ignore
|
|
1473
|
-
create_run_cancelled_event(
|
|
1543
|
+
create_run_cancelled_event(
|
|
1544
|
+
from_run_response=run_response,
|
|
1545
|
+
reason="Operation cancelled by user",
|
|
1546
|
+
)
|
|
1474
1547
|
)
|
|
1475
1548
|
else:
|
|
1476
1549
|
return run_response
|
|
@@ -1623,7 +1696,9 @@ class Agent:
|
|
|
1623
1696
|
|
|
1624
1697
|
# 9. Update the RunOutput with the model response
|
|
1625
1698
|
self._update_run_response(
|
|
1626
|
-
model_response=model_response,
|
|
1699
|
+
model_response=model_response,
|
|
1700
|
+
run_response=run_response,
|
|
1701
|
+
run_messages=run_messages,
|
|
1627
1702
|
)
|
|
1628
1703
|
|
|
1629
1704
|
# Optional: Store media
|
|
@@ -1633,7 +1708,10 @@ class Agent:
|
|
|
1633
1708
|
# Break out of the run function if a tool call is paused
|
|
1634
1709
|
if any(tool_call.is_paused for tool_call in run_response.tools or []):
|
|
1635
1710
|
return self._handle_agent_run_paused(
|
|
1636
|
-
run_response=run_response,
|
|
1711
|
+
run_response=run_response,
|
|
1712
|
+
run_messages=run_messages,
|
|
1713
|
+
session=agent_session,
|
|
1714
|
+
user_id=user_id,
|
|
1637
1715
|
)
|
|
1638
1716
|
raise_if_cancelled(run_response.run_id) # type: ignore
|
|
1639
1717
|
|
|
@@ -1675,9 +1753,12 @@ class Agent:
|
|
|
1675
1753
|
# 11. Add RunOutput to Agent Session
|
|
1676
1754
|
agent_session.upsert_run(run=run_response)
|
|
1677
1755
|
|
|
1678
|
-
# 12. Update Agent Memory
|
|
1679
|
-
async for _ in self.
|
|
1680
|
-
run_response=run_response,
|
|
1756
|
+
# 12. Update Agent Memory, Cultural Knowledge and Summaries
|
|
1757
|
+
async for _ in self._amake_memories_cultural_knowledge_and_summaries(
|
|
1758
|
+
run_response=run_response,
|
|
1759
|
+
run_messages=run_messages,
|
|
1760
|
+
session=agent_session,
|
|
1761
|
+
user_id=user_id,
|
|
1681
1762
|
):
|
|
1682
1763
|
pass
|
|
1683
1764
|
|
|
@@ -1884,14 +1965,19 @@ class Agent:
|
|
|
1884
1965
|
|
|
1885
1966
|
# If a parser model is provided, structure the response separately
|
|
1886
1967
|
async for event in self._aparse_response_with_parser_model_stream(
|
|
1887
|
-
session=agent_session,
|
|
1968
|
+
session=agent_session,
|
|
1969
|
+
run_response=run_response,
|
|
1970
|
+
stream_intermediate_steps=stream_intermediate_steps,
|
|
1888
1971
|
):
|
|
1889
1972
|
yield event
|
|
1890
1973
|
|
|
1891
1974
|
# Break out of the run function if a tool call is paused
|
|
1892
1975
|
if any(tool_call.is_paused for tool_call in run_response.tools or []):
|
|
1893
1976
|
for item in self._handle_agent_run_paused_stream(
|
|
1894
|
-
run_response=run_response,
|
|
1977
|
+
run_response=run_response,
|
|
1978
|
+
run_messages=run_messages,
|
|
1979
|
+
session=agent_session,
|
|
1980
|
+
user_id=user_id,
|
|
1895
1981
|
):
|
|
1896
1982
|
yield item
|
|
1897
1983
|
return
|
|
@@ -1932,8 +2018,11 @@ class Agent:
|
|
|
1932
2018
|
agent_session.upsert_run(run=run_response)
|
|
1933
2019
|
|
|
1934
2020
|
# 11. Update Agent Memory
|
|
1935
|
-
async for event in self.
|
|
1936
|
-
run_response=run_response,
|
|
2021
|
+
async for event in self._amake_memories_cultural_knowledge_and_summaries(
|
|
2022
|
+
run_response=run_response,
|
|
2023
|
+
run_messages=run_messages,
|
|
2024
|
+
session=agent_session,
|
|
2025
|
+
user_id=user_id,
|
|
1937
2026
|
):
|
|
1938
2027
|
yield event
|
|
1939
2028
|
|
|
@@ -2077,7 +2166,10 @@ class Agent:
|
|
|
2077
2166
|
|
|
2078
2167
|
# Initialize session
|
|
2079
2168
|
session_id, user_id, session_state = self._initialize_session(
|
|
2080
|
-
run_id=run_id,
|
|
2169
|
+
run_id=run_id,
|
|
2170
|
+
session_id=session_id,
|
|
2171
|
+
user_id=user_id,
|
|
2172
|
+
session_state=session_state,
|
|
2081
2173
|
)
|
|
2082
2174
|
|
|
2083
2175
|
# Initialize the Agent
|
|
@@ -2224,7 +2316,10 @@ class Agent:
|
|
|
2224
2316
|
|
|
2225
2317
|
if stream:
|
|
2226
2318
|
return async_generator_wrapper( # type: ignore
|
|
2227
|
-
create_run_cancelled_event(
|
|
2319
|
+
create_run_cancelled_event(
|
|
2320
|
+
from_run_response=run_response,
|
|
2321
|
+
reason="Operation cancelled by user",
|
|
2322
|
+
)
|
|
2228
2323
|
)
|
|
2229
2324
|
else:
|
|
2230
2325
|
return run_response
|
|
@@ -2531,12 +2626,19 @@ class Agent:
|
|
|
2531
2626
|
tool_call_limit=self.tool_call_limit,
|
|
2532
2627
|
)
|
|
2533
2628
|
|
|
2534
|
-
self._update_run_response(
|
|
2629
|
+
self._update_run_response(
|
|
2630
|
+
model_response=model_response,
|
|
2631
|
+
run_response=run_response,
|
|
2632
|
+
run_messages=run_messages,
|
|
2633
|
+
)
|
|
2535
2634
|
|
|
2536
2635
|
# We should break out of the run function
|
|
2537
2636
|
if any(tool_call.is_paused for tool_call in run_response.tools or []):
|
|
2538
2637
|
return self._handle_agent_run_paused(
|
|
2539
|
-
run_response=run_response,
|
|
2638
|
+
run_response=run_response,
|
|
2639
|
+
run_messages=run_messages,
|
|
2640
|
+
session=session,
|
|
2641
|
+
user_id=user_id,
|
|
2540
2642
|
)
|
|
2541
2643
|
|
|
2542
2644
|
# 3. Calculate session metrics
|
|
@@ -2565,15 +2667,21 @@ class Agent:
|
|
|
2565
2667
|
|
|
2566
2668
|
# 4. Save output to file if save_response_to_file is set
|
|
2567
2669
|
self.save_run_response_to_file(
|
|
2568
|
-
run_response=run_response,
|
|
2670
|
+
run_response=run_response,
|
|
2671
|
+
input=run_messages.user_message,
|
|
2672
|
+
session_id=session.session_id,
|
|
2673
|
+
user_id=user_id,
|
|
2569
2674
|
)
|
|
2570
2675
|
|
|
2571
2676
|
# 5. Add the run to memory
|
|
2572
2677
|
session.upsert_run(run=run_response)
|
|
2573
2678
|
|
|
2574
|
-
# 6. Update Agent Memory
|
|
2575
|
-
response_iterator = self.
|
|
2576
|
-
run_response=run_response,
|
|
2679
|
+
# 6. Update Agent Memory, Cultural Knowledge and Summaries
|
|
2680
|
+
response_iterator = self._make_memories_cultural_knowledge_and_summaries(
|
|
2681
|
+
run_response=run_response,
|
|
2682
|
+
run_messages=run_messages,
|
|
2683
|
+
session=session,
|
|
2684
|
+
user_id=user_id,
|
|
2577
2685
|
)
|
|
2578
2686
|
# Consume the response iterator to ensure the memory is updated before the run is completed
|
|
2579
2687
|
deque(response_iterator, maxlen=0)
|
|
@@ -2636,7 +2744,10 @@ class Agent:
|
|
|
2636
2744
|
# We should break out of the run function
|
|
2637
2745
|
if any(tool_call.is_paused for tool_call in run_response.tools or []):
|
|
2638
2746
|
yield from self._handle_agent_run_paused_stream(
|
|
2639
|
-
run_response=run_response,
|
|
2747
|
+
run_response=run_response,
|
|
2748
|
+
run_messages=run_messages,
|
|
2749
|
+
session=session,
|
|
2750
|
+
user_id=user_id,
|
|
2640
2751
|
)
|
|
2641
2752
|
return
|
|
2642
2753
|
|
|
@@ -2664,15 +2775,21 @@ class Agent:
|
|
|
2664
2775
|
|
|
2665
2776
|
# 4. Save output to file if save_response_to_file is set
|
|
2666
2777
|
self.save_run_response_to_file(
|
|
2667
|
-
run_response=run_response,
|
|
2778
|
+
run_response=run_response,
|
|
2779
|
+
input=run_messages.user_message,
|
|
2780
|
+
session_id=session.session_id,
|
|
2781
|
+
user_id=user_id,
|
|
2668
2782
|
)
|
|
2669
2783
|
|
|
2670
2784
|
# 5. Add the run to memory
|
|
2671
2785
|
session.upsert_run(run=run_response)
|
|
2672
2786
|
|
|
2673
2787
|
# 6. Update Agent Memory
|
|
2674
|
-
yield from self.
|
|
2675
|
-
run_response=run_response,
|
|
2788
|
+
yield from self._make_memories_cultural_knowledge_and_summaries(
|
|
2789
|
+
run_response=run_response,
|
|
2790
|
+
run_messages=run_messages,
|
|
2791
|
+
session=session,
|
|
2792
|
+
user_id=user_id,
|
|
2676
2793
|
)
|
|
2677
2794
|
|
|
2678
2795
|
# 7. Create the run completed event
|
|
@@ -2998,7 +3115,9 @@ class Agent:
|
|
|
2998
3115
|
|
|
2999
3116
|
# 9. Update the RunOutput with the model response
|
|
3000
3117
|
self._update_run_response(
|
|
3001
|
-
model_response=model_response,
|
|
3118
|
+
model_response=model_response,
|
|
3119
|
+
run_response=run_response,
|
|
3120
|
+
run_messages=run_messages,
|
|
3002
3121
|
)
|
|
3003
3122
|
|
|
3004
3123
|
if self.store_media:
|
|
@@ -3009,7 +3128,10 @@ class Agent:
|
|
|
3009
3128
|
# Break out of the run function if a tool call is paused
|
|
3010
3129
|
if any(tool_call.is_paused for tool_call in run_response.tools or []):
|
|
3011
3130
|
return self._handle_agent_run_paused(
|
|
3012
|
-
run_response=run_response,
|
|
3131
|
+
run_response=run_response,
|
|
3132
|
+
run_messages=run_messages,
|
|
3133
|
+
session=agent_session,
|
|
3134
|
+
user_id=user_id,
|
|
3013
3135
|
)
|
|
3014
3136
|
raise_if_cancelled(run_response.run_id) # type: ignore
|
|
3015
3137
|
|
|
@@ -3039,8 +3161,11 @@ class Agent:
|
|
|
3039
3161
|
run_response.metrics.stop_timer()
|
|
3040
3162
|
|
|
3041
3163
|
# 12. Update Agent Memory
|
|
3042
|
-
async for _ in self.
|
|
3043
|
-
run_response=run_response,
|
|
3164
|
+
async for _ in self._amake_memories_cultural_knowledge_and_summaries(
|
|
3165
|
+
run_response=run_response,
|
|
3166
|
+
run_messages=run_messages,
|
|
3167
|
+
session=agent_session,
|
|
3168
|
+
user_id=user_id,
|
|
3044
3169
|
):
|
|
3045
3170
|
pass
|
|
3046
3171
|
|
|
@@ -3238,7 +3363,10 @@ class Agent:
|
|
|
3238
3363
|
# Break out of the run function if a tool call is paused
|
|
3239
3364
|
if any(tool_call.is_paused for tool_call in run_response.tools or []):
|
|
3240
3365
|
for item in self._handle_agent_run_paused_stream(
|
|
3241
|
-
run_response=run_response,
|
|
3366
|
+
run_response=run_response,
|
|
3367
|
+
run_messages=run_messages,
|
|
3368
|
+
session=agent_session,
|
|
3369
|
+
user_id=user_id,
|
|
3242
3370
|
):
|
|
3243
3371
|
yield item
|
|
3244
3372
|
return
|
|
@@ -3281,8 +3409,11 @@ class Agent:
|
|
|
3281
3409
|
self._update_session_metrics(session=agent_session, run_response=run_response)
|
|
3282
3410
|
|
|
3283
3411
|
# 12. Update Agent Memory
|
|
3284
|
-
async for event in self.
|
|
3285
|
-
run_response=run_response,
|
|
3412
|
+
async for event in self._amake_memories_cultural_knowledge_and_summaries(
|
|
3413
|
+
run_response=run_response,
|
|
3414
|
+
run_messages=run_messages,
|
|
3415
|
+
session=agent_session,
|
|
3416
|
+
user_id=user_id,
|
|
3286
3417
|
):
|
|
3287
3418
|
yield event
|
|
3288
3419
|
|
|
@@ -3358,7 +3489,9 @@ class Agent:
|
|
|
3358
3489
|
yield self._handle_event(
|
|
3359
3490
|
run_response=run_response,
|
|
3360
3491
|
event=create_pre_hook_started_event(
|
|
3361
|
-
from_run_response=run_response,
|
|
3492
|
+
from_run_response=run_response,
|
|
3493
|
+
run_input=run_input,
|
|
3494
|
+
pre_hook_name=hook.__name__,
|
|
3362
3495
|
),
|
|
3363
3496
|
)
|
|
3364
3497
|
try:
|
|
@@ -3370,7 +3503,9 @@ class Agent:
|
|
|
3370
3503
|
yield self._handle_event(
|
|
3371
3504
|
run_response=run_response,
|
|
3372
3505
|
event=create_pre_hook_completed_event(
|
|
3373
|
-
from_run_response=run_response,
|
|
3506
|
+
from_run_response=run_response,
|
|
3507
|
+
run_input=run_input,
|
|
3508
|
+
pre_hook_name=hook.__name__,
|
|
3374
3509
|
),
|
|
3375
3510
|
)
|
|
3376
3511
|
|
|
@@ -3420,7 +3555,9 @@ class Agent:
|
|
|
3420
3555
|
yield self._handle_event(
|
|
3421
3556
|
run_response=run_response,
|
|
3422
3557
|
event=create_pre_hook_started_event(
|
|
3423
|
-
from_run_response=run_response,
|
|
3558
|
+
from_run_response=run_response,
|
|
3559
|
+
run_input=run_input,
|
|
3560
|
+
pre_hook_name=hook.__name__,
|
|
3424
3561
|
),
|
|
3425
3562
|
)
|
|
3426
3563
|
try:
|
|
@@ -3436,7 +3573,9 @@ class Agent:
|
|
|
3436
3573
|
yield self._handle_event(
|
|
3437
3574
|
run_response=run_response,
|
|
3438
3575
|
event=create_pre_hook_completed_event(
|
|
3439
|
-
from_run_response=run_response,
|
|
3576
|
+
from_run_response=run_response,
|
|
3577
|
+
run_input=run_input,
|
|
3578
|
+
pre_hook_name=hook.__name__,
|
|
3440
3579
|
),
|
|
3441
3580
|
)
|
|
3442
3581
|
|
|
@@ -3559,7 +3698,10 @@ class Agent:
|
|
|
3559
3698
|
|
|
3560
3699
|
# Save output to file if save_response_to_file is set
|
|
3561
3700
|
self.save_run_response_to_file(
|
|
3562
|
-
run_response=run_response,
|
|
3701
|
+
run_response=run_response,
|
|
3702
|
+
input=run_messages.user_message,
|
|
3703
|
+
session_id=session.session_id,
|
|
3704
|
+
user_id=user_id,
|
|
3563
3705
|
)
|
|
3564
3706
|
|
|
3565
3707
|
session.upsert_run(run=run_response)
|
|
@@ -3596,7 +3738,10 @@ class Agent:
|
|
|
3596
3738
|
|
|
3597
3739
|
# Save output to file if save_response_to_file is set
|
|
3598
3740
|
self.save_run_response_to_file(
|
|
3599
|
-
run_response=run_response,
|
|
3741
|
+
run_response=run_response,
|
|
3742
|
+
input=run_messages.user_message,
|
|
3743
|
+
session_id=session.session_id,
|
|
3744
|
+
user_id=user_id,
|
|
3600
3745
|
)
|
|
3601
3746
|
session.upsert_run(run=run_response)
|
|
3602
3747
|
# Save session to storage
|
|
@@ -3703,7 +3848,9 @@ class Agent:
|
|
|
3703
3848
|
tool.tool_call_error = tool_execution.tool_call_error
|
|
3704
3849
|
yield self._handle_event(
|
|
3705
3850
|
create_tool_call_completed_event(
|
|
3706
|
-
from_run_response=run_response,
|
|
3851
|
+
from_run_response=run_response,
|
|
3852
|
+
tool=tool,
|
|
3853
|
+
content=call_result.content,
|
|
3707
3854
|
),
|
|
3708
3855
|
run_response,
|
|
3709
3856
|
)
|
|
@@ -3750,7 +3897,9 @@ class Agent:
|
|
|
3750
3897
|
tool.tool_call_error = tool_execution.tool_call_error
|
|
3751
3898
|
yield self._handle_event(
|
|
3752
3899
|
create_tool_call_completed_event(
|
|
3753
|
-
from_run_response=run_response,
|
|
3900
|
+
from_run_response=run_response,
|
|
3901
|
+
tool=tool,
|
|
3902
|
+
content=call_result.content,
|
|
3754
3903
|
),
|
|
3755
3904
|
run_response,
|
|
3756
3905
|
)
|
|
@@ -3925,7 +4074,12 @@ class Agent:
|
|
|
3925
4074
|
for file in model_response.files:
|
|
3926
4075
|
self._add_file(file, run_response) # Generated files go to run_response.files
|
|
3927
4076
|
|
|
3928
|
-
def _update_run_response(
|
|
4077
|
+
def _update_run_response(
|
|
4078
|
+
self,
|
|
4079
|
+
model_response: ModelResponse,
|
|
4080
|
+
run_response: RunOutput,
|
|
4081
|
+
run_messages: RunMessages,
|
|
4082
|
+
):
|
|
3929
4083
|
# Handle structured outputs
|
|
3930
4084
|
if self.output_schema is not None and model_response.parsed is not None:
|
|
3931
4085
|
# We get native structured outputs from the model
|
|
@@ -3966,7 +4120,9 @@ class Agent:
|
|
|
3966
4120
|
if tool_name.lower() in ["think", "analyze"]:
|
|
3967
4121
|
tool_args = tool_call.tool_args or {}
|
|
3968
4122
|
self._update_reasoning_content_from_tool_call(
|
|
3969
|
-
run_response=run_response,
|
|
4123
|
+
run_response=run_response,
|
|
4124
|
+
tool_name=tool_name,
|
|
4125
|
+
tool_args=tool_args,
|
|
3970
4126
|
)
|
|
3971
4127
|
|
|
3972
4128
|
# Update the run_response audio with the model response audio
|
|
@@ -4045,7 +4201,8 @@ class Agent:
|
|
|
4045
4201
|
|
|
4046
4202
|
if all_reasoning_steps:
|
|
4047
4203
|
add_reasoning_metrics_to_metadata(
|
|
4048
|
-
run_response=run_response,
|
|
4204
|
+
run_response=run_response,
|
|
4205
|
+
reasoning_time_taken=reasoning_state["reasoning_time_taken"],
|
|
4049
4206
|
)
|
|
4050
4207
|
yield self._handle_event(
|
|
4051
4208
|
create_reasoning_completed_event(
|
|
@@ -4122,7 +4279,8 @@ class Agent:
|
|
|
4122
4279
|
|
|
4123
4280
|
if all_reasoning_steps:
|
|
4124
4281
|
add_reasoning_metrics_to_metadata(
|
|
4125
|
-
run_response=run_response,
|
|
4282
|
+
run_response=run_response,
|
|
4283
|
+
reasoning_time_taken=reasoning_state["reasoning_time_taken"],
|
|
4126
4284
|
)
|
|
4127
4285
|
yield self._handle_event(
|
|
4128
4286
|
create_reasoning_completed_event(
|
|
@@ -4342,14 +4500,16 @@ class Agent:
|
|
|
4342
4500
|
# Yield each tool call started event
|
|
4343
4501
|
for tool in tool_executions_list:
|
|
4344
4502
|
yield self._handle_event(
|
|
4345
|
-
create_tool_call_started_event(from_run_response=run_response, tool=tool),
|
|
4503
|
+
create_tool_call_started_event(from_run_response=run_response, tool=tool),
|
|
4504
|
+
run_response,
|
|
4346
4505
|
)
|
|
4347
4506
|
|
|
4348
4507
|
# If the model response is a tool_call_completed, update the existing tool call in the run_response
|
|
4349
4508
|
elif model_response_event.event == ModelResponseEvent.tool_call_completed.value:
|
|
4350
4509
|
if model_response_event.updated_session_state is not None and session.session_data is not None:
|
|
4351
4510
|
merge_dictionaries(
|
|
4352
|
-
session.session_data["session_state"],
|
|
4511
|
+
session.session_data["session_state"],
|
|
4512
|
+
model_response_event.updated_session_state,
|
|
4353
4513
|
)
|
|
4354
4514
|
|
|
4355
4515
|
if model_response_event.images is not None:
|
|
@@ -4390,7 +4550,9 @@ class Agent:
|
|
|
4390
4550
|
tool_args = tool_call.tool_args or {}
|
|
4391
4551
|
|
|
4392
4552
|
reasoning_step = self._update_reasoning_content_from_tool_call(
|
|
4393
|
-
run_response=run_response,
|
|
4553
|
+
run_response=run_response,
|
|
4554
|
+
tool_name=tool_name,
|
|
4555
|
+
tool_args=tool_args,
|
|
4394
4556
|
)
|
|
4395
4557
|
|
|
4396
4558
|
tool_call_metrics = tool_call.metrics
|
|
@@ -4406,7 +4568,9 @@ class Agent:
|
|
|
4406
4568
|
|
|
4407
4569
|
yield self._handle_event(
|
|
4408
4570
|
create_tool_call_completed_event(
|
|
4409
|
-
from_run_response=run_response,
|
|
4571
|
+
from_run_response=run_response,
|
|
4572
|
+
tool=tool_call,
|
|
4573
|
+
content=model_response_event.content,
|
|
4410
4574
|
),
|
|
4411
4575
|
run_response,
|
|
4412
4576
|
)
|
|
@@ -4415,7 +4579,8 @@ class Agent:
|
|
|
4415
4579
|
if reasoning_step is not None:
|
|
4416
4580
|
if reasoning_state and not reasoning_state["reasoning_started"]:
|
|
4417
4581
|
yield self._handle_event(
|
|
4418
|
-
create_reasoning_started_event(from_run_response=run_response),
|
|
4582
|
+
create_reasoning_started_event(from_run_response=run_response),
|
|
4583
|
+
run_response,
|
|
4419
4584
|
)
|
|
4420
4585
|
reasoning_state["reasoning_started"] = True
|
|
4421
4586
|
|
|
@@ -4428,7 +4593,7 @@ class Agent:
|
|
|
4428
4593
|
run_response,
|
|
4429
4594
|
)
|
|
4430
4595
|
|
|
4431
|
-
def
|
|
4596
|
+
def _make_memories_cultural_knowledge_and_summaries(
|
|
4432
4597
|
self,
|
|
4433
4598
|
run_response: RunOutput,
|
|
4434
4599
|
run_messages: RunMessages,
|
|
@@ -4440,10 +4605,11 @@ class Agent:
|
|
|
4440
4605
|
with ThreadPoolExecutor(max_workers=3) as executor:
|
|
4441
4606
|
futures = []
|
|
4442
4607
|
|
|
4443
|
-
# Create user memories
|
|
4444
4608
|
user_message_str = (
|
|
4445
4609
|
run_messages.user_message.get_content_string() if run_messages.user_message is not None else None
|
|
4446
4610
|
)
|
|
4611
|
+
|
|
4612
|
+
# Create user memories
|
|
4447
4613
|
if user_message_str is not None and self.memory_manager is not None and not self.enable_agentic_memory:
|
|
4448
4614
|
log_debug("Creating user memories.")
|
|
4449
4615
|
futures.append(
|
|
@@ -4486,6 +4652,16 @@ class Agent:
|
|
|
4486
4652
|
else:
|
|
4487
4653
|
log_warning("Unable to add messages to memory")
|
|
4488
4654
|
|
|
4655
|
+
# Create cultural knowledge
|
|
4656
|
+
if user_message_str is not None and self.culture_manager is not None and self.update_cultural_knowledge:
|
|
4657
|
+
log_debug("Creating cultural knowledge.")
|
|
4658
|
+
futures.append(
|
|
4659
|
+
executor.submit(
|
|
4660
|
+
self.culture_manager.create_cultural_knowledge,
|
|
4661
|
+
message=user_message_str,
|
|
4662
|
+
)
|
|
4663
|
+
)
|
|
4664
|
+
|
|
4489
4665
|
# Create session summary
|
|
4490
4666
|
if self.session_summary_manager is not None:
|
|
4491
4667
|
log_debug("Creating session summary.")
|
|
@@ -4499,7 +4675,8 @@ class Agent:
|
|
|
4499
4675
|
if futures:
|
|
4500
4676
|
if self.stream_intermediate_steps:
|
|
4501
4677
|
yield self._handle_event(
|
|
4502
|
-
create_memory_update_started_event(from_run_response=run_response),
|
|
4678
|
+
create_memory_update_started_event(from_run_response=run_response),
|
|
4679
|
+
run_response,
|
|
4503
4680
|
)
|
|
4504
4681
|
|
|
4505
4682
|
# Wait for all operations to complete and handle any errors
|
|
@@ -4511,10 +4688,11 @@ class Agent:
|
|
|
4511
4688
|
|
|
4512
4689
|
if self.stream_intermediate_steps:
|
|
4513
4690
|
yield self._handle_event(
|
|
4514
|
-
create_memory_update_completed_event(from_run_response=run_response),
|
|
4691
|
+
create_memory_update_completed_event(from_run_response=run_response),
|
|
4692
|
+
run_response,
|
|
4515
4693
|
)
|
|
4516
4694
|
|
|
4517
|
-
async def
|
|
4695
|
+
async def _amake_memories_cultural_knowledge_and_summaries(
|
|
4518
4696
|
self,
|
|
4519
4697
|
run_response: RunOutput,
|
|
4520
4698
|
run_messages: RunMessages,
|
|
@@ -4529,7 +4707,9 @@ class Agent:
|
|
|
4529
4707
|
|
|
4530
4708
|
tasks.append(
|
|
4531
4709
|
self.memory_manager.acreate_user_memories(
|
|
4532
|
-
message=run_messages.user_message.get_content_string(),
|
|
4710
|
+
message=run_messages.user_message.get_content_string(),
|
|
4711
|
+
user_id=user_id,
|
|
4712
|
+
agent_id=self.id,
|
|
4533
4713
|
)
|
|
4534
4714
|
)
|
|
4535
4715
|
|
|
@@ -4561,6 +4741,18 @@ class Agent:
|
|
|
4561
4741
|
else:
|
|
4562
4742
|
log_warning("Unable to add messages to memory")
|
|
4563
4743
|
|
|
4744
|
+
# Create cultural knowledge
|
|
4745
|
+
if (
|
|
4746
|
+
run_messages.user_message is not None
|
|
4747
|
+
and self.culture_manager is not None
|
|
4748
|
+
and self.update_cultural_knowledge
|
|
4749
|
+
):
|
|
4750
|
+
log_debug("Creating cultural knowledge.")
|
|
4751
|
+
|
|
4752
|
+
tasks.append(
|
|
4753
|
+
self.culture_manager.acreate_cultural_knowledge(message=run_messages.user_message.get_content_string())
|
|
4754
|
+
)
|
|
4755
|
+
|
|
4564
4756
|
# Create session summary
|
|
4565
4757
|
if self.session_summary_manager is not None:
|
|
4566
4758
|
log_debug("Creating session summary.")
|
|
@@ -4573,7 +4765,8 @@ class Agent:
|
|
|
4573
4765
|
if tasks:
|
|
4574
4766
|
if self.stream_intermediate_steps:
|
|
4575
4767
|
yield self._handle_event(
|
|
4576
|
-
create_memory_update_started_event(from_run_response=run_response),
|
|
4768
|
+
create_memory_update_started_event(from_run_response=run_response),
|
|
4769
|
+
run_response,
|
|
4577
4770
|
)
|
|
4578
4771
|
|
|
4579
4772
|
# Execute all tasks concurrently and handle any errors
|
|
@@ -4584,7 +4777,8 @@ class Agent:
|
|
|
4584
4777
|
|
|
4585
4778
|
if self.stream_intermediate_steps:
|
|
4586
4779
|
yield self._handle_event(
|
|
4587
|
-
create_memory_update_completed_event(from_run_response=run_response),
|
|
4780
|
+
create_memory_update_completed_event(from_run_response=run_response),
|
|
4781
|
+
run_response,
|
|
4588
4782
|
)
|
|
4589
4783
|
|
|
4590
4784
|
def _raise_if_async_tools(self) -> None:
|
|
@@ -4634,7 +4828,15 @@ class Agent:
|
|
|
4634
4828
|
|
|
4635
4829
|
# If any of the tools has "agent" as parameter, set _rebuild_tools to True
|
|
4636
4830
|
for tool in agent_tools:
|
|
4637
|
-
param_names = {
|
|
4831
|
+
param_names = {
|
|
4832
|
+
"agent",
|
|
4833
|
+
"session_state",
|
|
4834
|
+
"team",
|
|
4835
|
+
"images",
|
|
4836
|
+
"videos",
|
|
4837
|
+
"audios",
|
|
4838
|
+
"files",
|
|
4839
|
+
}
|
|
4638
4840
|
|
|
4639
4841
|
if isinstance(tool, Function):
|
|
4640
4842
|
if param_names & set(tool.parameters):
|
|
@@ -4671,6 +4873,10 @@ class Agent:
|
|
|
4671
4873
|
agent_tools.append(self._get_update_user_memory_function(user_id=user_id, async_mode=async_mode))
|
|
4672
4874
|
self._rebuild_tools = True
|
|
4673
4875
|
|
|
4876
|
+
if self.enable_agentic_culture:
|
|
4877
|
+
agent_tools.append(self._get_update_cultural_knowledge_function(async_mode=async_mode))
|
|
4878
|
+
self._rebuild_tools = True
|
|
4879
|
+
|
|
4674
4880
|
if self.enable_agentic_state:
|
|
4675
4881
|
agent_tools.append(self.update_session_state)
|
|
4676
4882
|
|
|
@@ -4690,13 +4896,17 @@ class Agent:
|
|
|
4690
4896
|
if self.enable_agentic_knowledge_filters:
|
|
4691
4897
|
agent_tools.append(
|
|
4692
4898
|
self._search_knowledge_base_with_agentic_filters_function(
|
|
4693
|
-
run_response=run_response,
|
|
4899
|
+
run_response=run_response,
|
|
4900
|
+
async_mode=async_mode,
|
|
4901
|
+
knowledge_filters=knowledge_filters,
|
|
4694
4902
|
)
|
|
4695
4903
|
)
|
|
4696
4904
|
else:
|
|
4697
4905
|
agent_tools.append(
|
|
4698
4906
|
self._get_search_knowledge_base_function(
|
|
4699
|
-
run_response=run_response,
|
|
4907
|
+
run_response=run_response,
|
|
4908
|
+
async_mode=async_mode,
|
|
4909
|
+
knowledge_filters=knowledge_filters,
|
|
4700
4910
|
)
|
|
4701
4911
|
)
|
|
4702
4912
|
self._rebuild_tools = True
|
|
@@ -4784,13 +4994,17 @@ class Agent:
|
|
|
4784
4994
|
if self.enable_agentic_knowledge_filters:
|
|
4785
4995
|
agent_tools.append(
|
|
4786
4996
|
self._search_knowledge_base_with_agentic_filters_function(
|
|
4787
|
-
run_response=run_response,
|
|
4997
|
+
run_response=run_response,
|
|
4998
|
+
async_mode=async_mode,
|
|
4999
|
+
knowledge_filters=knowledge_filters,
|
|
4788
5000
|
)
|
|
4789
5001
|
)
|
|
4790
5002
|
else:
|
|
4791
5003
|
agent_tools.append(
|
|
4792
5004
|
self._get_search_knowledge_base_function(
|
|
4793
|
-
run_response=run_response,
|
|
5005
|
+
run_response=run_response,
|
|
5006
|
+
async_mode=async_mode,
|
|
5007
|
+
knowledge_filters=knowledge_filters,
|
|
4794
5008
|
)
|
|
4795
5009
|
)
|
|
4796
5010
|
self._rebuild_tools = True
|
|
@@ -5614,7 +5828,10 @@ class Agent:
|
|
|
5614
5828
|
self.save_session(session=session) # type: ignore
|
|
5615
5829
|
|
|
5616
5830
|
def set_session_name(
|
|
5617
|
-
self,
|
|
5831
|
+
self,
|
|
5832
|
+
session_id: Optional[str] = None,
|
|
5833
|
+
autogenerate: bool = False,
|
|
5834
|
+
session_name: Optional[str] = None,
|
|
5618
5835
|
) -> AgentSession:
|
|
5619
5836
|
"""Set the session name and save to storage"""
|
|
5620
5837
|
session_id = session_id or self.session_id
|
|
@@ -5775,6 +5992,20 @@ class Agent:
|
|
|
5775
5992
|
|
|
5776
5993
|
return await self.memory_manager.aget_user_memories(user_id=user_id)
|
|
5777
5994
|
|
|
5995
|
+
def get_culture_knowledge(self) -> Optional[List[CulturalKnowledge]]:
|
|
5996
|
+
"""Get the cultural knowledge the agent has access to"""
|
|
5997
|
+
if self.culture_manager is None:
|
|
5998
|
+
return None
|
|
5999
|
+
|
|
6000
|
+
return self.culture_manager.get_all_knowledge()
|
|
6001
|
+
|
|
6002
|
+
async def aget_culture_knowledge(self) -> Optional[List[CulturalKnowledge]]:
|
|
6003
|
+
"""Get the cultural knowledge the agent has access to"""
|
|
6004
|
+
if self.culture_manager is None:
|
|
6005
|
+
return None
|
|
6006
|
+
|
|
6007
|
+
return await self.culture_manager.aget_all_knowledge()
|
|
6008
|
+
|
|
5778
6009
|
def _format_message_with_state_variables(
|
|
5779
6010
|
self,
|
|
5780
6011
|
message: Any,
|
|
@@ -5924,7 +6155,14 @@ class Agent:
|
|
|
5924
6155
|
location = get_location()
|
|
5925
6156
|
if location:
|
|
5926
6157
|
location_str = ", ".join(
|
|
5927
|
-
filter(
|
|
6158
|
+
filter(
|
|
6159
|
+
None,
|
|
6160
|
+
[
|
|
6161
|
+
location.get("city"),
|
|
6162
|
+
location.get("region"),
|
|
6163
|
+
location.get("country"),
|
|
6164
|
+
],
|
|
6165
|
+
)
|
|
5928
6166
|
)
|
|
5929
6167
|
if location_str:
|
|
5930
6168
|
additional_information.append(f"Your approximate location is: {location_str}.")
|
|
@@ -5939,7 +6177,8 @@ class Agent:
|
|
|
5939
6177
|
if valid_filters:
|
|
5940
6178
|
valid_filters_str = ", ".join(valid_filters)
|
|
5941
6179
|
additional_information.append(
|
|
5942
|
-
dedent(
|
|
6180
|
+
dedent(
|
|
6181
|
+
f"""
|
|
5943
6182
|
The knowledge base contains documents with these metadata filters: {valid_filters_str}.
|
|
5944
6183
|
Always use filters when the user query indicates specific metadata.
|
|
5945
6184
|
|
|
@@ -5955,7 +6194,8 @@ class Agent:
|
|
|
5955
6194
|
- Ensure the filter keys match the valid metadata filters: {valid_filters_str}.
|
|
5956
6195
|
|
|
5957
6196
|
You can use the search_knowledge_base tool to search the knowledge base and get the most relevant documents. Make sure to pass the filters as [Dict[str: Any]] to the tool. FOLLOW THIS STRUCTURE STRICTLY.
|
|
5958
|
-
"""
|
|
6197
|
+
"""
|
|
6198
|
+
)
|
|
5959
6199
|
)
|
|
5960
6200
|
|
|
5961
6201
|
# 3.3 Build the default system message for the Agent.
|
|
@@ -6043,6 +6283,67 @@ class Agent:
|
|
|
6043
6283
|
"</updating_user_memories>\n\n"
|
|
6044
6284
|
)
|
|
6045
6285
|
|
|
6286
|
+
# 3.3.10 Then add cultural knowledge to the system prompt
|
|
6287
|
+
if self.add_culture_to_context:
|
|
6288
|
+
_culture_manager_not_set = None
|
|
6289
|
+
if not self.culture_manager:
|
|
6290
|
+
self._set_culture_manager()
|
|
6291
|
+
_culture_manager_not_set = True
|
|
6292
|
+
|
|
6293
|
+
cultural_knowledge = self.culture_manager.get_all_knowledge() # type: ignore
|
|
6294
|
+
|
|
6295
|
+
if cultural_knowledge and len(cultural_knowledge) > 0:
|
|
6296
|
+
system_message_content += (
|
|
6297
|
+
"You have access to shared **Cultural Knowledge**, which provides context, norms, rules and guidance "
|
|
6298
|
+
"for your reasoning, communication, and decision-making. "
|
|
6299
|
+
"Cultural Knowledge represents the collective understanding, values, rules and practices that have "
|
|
6300
|
+
"emerged across agents and teams. It encodes collective experience — including preferred "
|
|
6301
|
+
"approaches, common patterns, lessons learned, and ethical guardrails.\n\n"
|
|
6302
|
+
"When performing any task:\n"
|
|
6303
|
+
"- **Reference Cultural Knowledge** to align with shared norms and best practices.\n"
|
|
6304
|
+
"- **Apply it contextually**, not mechanically — adapt principles to the current situation.\n"
|
|
6305
|
+
"- **Preserve consistency** with cultural values (tone, reasoning, and style) unless explicitly told otherwise.\n"
|
|
6306
|
+
"- **Extend it** when you discover new insights — your outputs may become future Cultural Knowledge.\n"
|
|
6307
|
+
"- **Clarify conflicts** if Cultural Knowledge appears to contradict explicit user instructions.\n\n"
|
|
6308
|
+
"Your goal is to act not only intelligently but also *culturally coherently* — reflecting the "
|
|
6309
|
+
"collective intelligence of the system.\n\n"
|
|
6310
|
+
"Below is the currently available Cultural Knowledge for this context:\n\n"
|
|
6311
|
+
)
|
|
6312
|
+
system_message_content += "<cultural_knowledge>"
|
|
6313
|
+
for _knowledge in cultural_knowledge: # type: ignore
|
|
6314
|
+
system_message_content += "\n---"
|
|
6315
|
+
system_message_content += f"\nName: {_knowledge.name}"
|
|
6316
|
+
system_message_content += f"\nSummary: {_knowledge.summary}"
|
|
6317
|
+
system_message_content += f"\nContent: {_knowledge.content}"
|
|
6318
|
+
system_message_content += "\n</cultural_knowledge>\n"
|
|
6319
|
+
else:
|
|
6320
|
+
system_message_content += (
|
|
6321
|
+
"You have the capability to access shared **Cultural Knowledge**, which normally provides "
|
|
6322
|
+
"context, norms, and guidance for your behavior and reasoning. However, no cultural knowledge "
|
|
6323
|
+
"is currently available in this session.\n"
|
|
6324
|
+
"Proceed thoughtfully and document any useful insights you create — they may become future "
|
|
6325
|
+
"Cultural Knowledge for others.\n\n"
|
|
6326
|
+
)
|
|
6327
|
+
|
|
6328
|
+
if _culture_manager_not_set:
|
|
6329
|
+
self.culture_manager = None
|
|
6330
|
+
|
|
6331
|
+
if self.enable_agentic_culture:
|
|
6332
|
+
system_message_content += (
|
|
6333
|
+
"\n<contributing_to_culture>\n"
|
|
6334
|
+
"When you discover an insight, pattern, rule, or best practice that will help future agents, use the `create_or_update_cultural_knowledge` tool to add or update entries in the shared cultural knowledge.\n"
|
|
6335
|
+
"\n"
|
|
6336
|
+
"When to contribute:\n"
|
|
6337
|
+
"- You discover a reusable insight, pattern, rule, or best practice that will help future agents.\n"
|
|
6338
|
+
"- You correct or clarify an existing cultural entry.\n"
|
|
6339
|
+
"- You capture a guardrail, decision rationale, postmortem lesson, or example template.\n"
|
|
6340
|
+
"- You identify missing context that should persist across sessions or teams.\n"
|
|
6341
|
+
"\n"
|
|
6342
|
+
"Cultural knowledge should capture reusable insights, best practices, or contextual knowledge that transcends individual conversations.\n"
|
|
6343
|
+
"Mention your contribution to the user only if it is relevant to their request or they asked to be notified.\n"
|
|
6344
|
+
"</contributing_to_culture>\n\n"
|
|
6345
|
+
)
|
|
6346
|
+
|
|
6046
6347
|
# 3.3.11 Then add a summary of the interaction to the system prompt
|
|
6047
6348
|
if self.add_session_summary_to_context and session.summary is not None:
|
|
6048
6349
|
system_message_content += "Here is a brief summary of your previous interactions:\n\n"
|
|
@@ -6195,7 +6496,14 @@ class Agent:
|
|
|
6195
6496
|
location = get_location()
|
|
6196
6497
|
if location:
|
|
6197
6498
|
location_str = ", ".join(
|
|
6198
|
-
filter(
|
|
6499
|
+
filter(
|
|
6500
|
+
None,
|
|
6501
|
+
[
|
|
6502
|
+
location.get("city"),
|
|
6503
|
+
location.get("region"),
|
|
6504
|
+
location.get("country"),
|
|
6505
|
+
],
|
|
6506
|
+
)
|
|
6199
6507
|
)
|
|
6200
6508
|
if location_str:
|
|
6201
6509
|
additional_information.append(f"Your approximate location is: {location_str}.")
|
|
@@ -6210,7 +6518,8 @@ class Agent:
|
|
|
6210
6518
|
if valid_filters:
|
|
6211
6519
|
valid_filters_str = ", ".join(valid_filters)
|
|
6212
6520
|
additional_information.append(
|
|
6213
|
-
dedent(
|
|
6521
|
+
dedent(
|
|
6522
|
+
f"""
|
|
6214
6523
|
The knowledge base contains documents with these metadata filters: {valid_filters_str}.
|
|
6215
6524
|
Always use filters when the user query indicates specific metadata.
|
|
6216
6525
|
|
|
@@ -6226,7 +6535,8 @@ class Agent:
|
|
|
6226
6535
|
- Ensure the filter keys match the valid metadata filters: {valid_filters_str}.
|
|
6227
6536
|
|
|
6228
6537
|
You can use the search_knowledge_base tool to search the knowledge base and get the most relevant documents. Make sure to pass the filters as [Dict[str: Any]] to the tool. FOLLOW THIS STRUCTURE STRICTLY.
|
|
6229
|
-
"""
|
|
6538
|
+
"""
|
|
6539
|
+
)
|
|
6230
6540
|
)
|
|
6231
6541
|
|
|
6232
6542
|
# 3.3 Build the default system message for the Agent.
|
|
@@ -6317,6 +6627,67 @@ class Agent:
|
|
|
6317
6627
|
"</updating_user_memories>\n\n"
|
|
6318
6628
|
)
|
|
6319
6629
|
|
|
6630
|
+
# 3.3.10 Then add cultural knowledge to the system prompt
|
|
6631
|
+
if self.add_culture_to_context:
|
|
6632
|
+
_culture_manager_not_set = None
|
|
6633
|
+
if not self.culture_manager:
|
|
6634
|
+
self._set_culture_manager()
|
|
6635
|
+
_culture_manager_not_set = True
|
|
6636
|
+
|
|
6637
|
+
cultural_knowledge = await self.culture_manager.aget_all_knowledge() # type: ignore
|
|
6638
|
+
|
|
6639
|
+
if cultural_knowledge and len(cultural_knowledge) > 0:
|
|
6640
|
+
system_message_content += (
|
|
6641
|
+
"You have access to shared **Cultural Knowledge**, which provides context, norms, rules and guidance "
|
|
6642
|
+
"for your reasoning, communication, and decision-making.\n\n"
|
|
6643
|
+
"Cultural Knowledge represents the collective understanding, values, rules and practices that have "
|
|
6644
|
+
"emerged across agents and teams. It encodes collective experience — including preferred "
|
|
6645
|
+
"approaches, common patterns, lessons learned, and ethical guardrails.\n\n"
|
|
6646
|
+
"When performing any task:\n"
|
|
6647
|
+
"- **Reference Cultural Knowledge** to align with shared norms and best practices.\n"
|
|
6648
|
+
"- **Apply it contextually**, not mechanically — adapt principles to the current situation.\n"
|
|
6649
|
+
"- **Preserve consistency** with cultural values (tone, reasoning, and style) unless explicitly told otherwise.\n"
|
|
6650
|
+
"- **Extend it** when you discover new insights — your outputs may become future Cultural Knowledge.\n"
|
|
6651
|
+
"- **Clarify conflicts** if Cultural Knowledge appears to contradict explicit user instructions.\n\n"
|
|
6652
|
+
"Your goal is to act not only intelligently but also *culturally coherently* — reflecting the "
|
|
6653
|
+
"collective intelligence of the system.\n\n"
|
|
6654
|
+
"Below is the currently available Cultural Knowledge for this context:\n\n"
|
|
6655
|
+
)
|
|
6656
|
+
system_message_content += "<cultural_knowledge>"
|
|
6657
|
+
for _knowledge in cultural_knowledge: # type: ignore
|
|
6658
|
+
system_message_content += "\n---"
|
|
6659
|
+
system_message_content += f"\nName: {_knowledge.name}"
|
|
6660
|
+
system_message_content += f"\nSummary: {_knowledge.summary}"
|
|
6661
|
+
system_message_content += f"\nContent: {_knowledge.content}"
|
|
6662
|
+
system_message_content += "\n</cultural_knowledge>\n"
|
|
6663
|
+
else:
|
|
6664
|
+
system_message_content += (
|
|
6665
|
+
"You have the capability to access shared **Cultural Knowledge**, which normally provides "
|
|
6666
|
+
"context, norms, and guidance for your behavior and reasoning. However, no cultural knowledge "
|
|
6667
|
+
"is currently available in this session.\n"
|
|
6668
|
+
"Proceed thoughtfully and document any useful insights you create — they may become future "
|
|
6669
|
+
"Cultural Knowledge for others.\n\n"
|
|
6670
|
+
)
|
|
6671
|
+
|
|
6672
|
+
if _culture_manager_not_set:
|
|
6673
|
+
self.culture_manager = None
|
|
6674
|
+
|
|
6675
|
+
if self.enable_agentic_culture:
|
|
6676
|
+
system_message_content += (
|
|
6677
|
+
"\n<contributing_to_culture>\n"
|
|
6678
|
+
"When you discover an insight, pattern, rule, or best practice that will help future agents, use the `create_or_update_cultural_knowledge` tool to add or update entries in the shared cultural knowledge.\n"
|
|
6679
|
+
"\n"
|
|
6680
|
+
"When to contribute:\n"
|
|
6681
|
+
"- You discover a reusable insight, pattern, rule, or best practice that will help future agents.\n"
|
|
6682
|
+
"- You correct or clarify an existing cultural entry.\n"
|
|
6683
|
+
"- You capture a guardrail, decision rationale, postmortem lesson, or example template.\n"
|
|
6684
|
+
"- You identify missing context that should persist across sessions or teams.\n"
|
|
6685
|
+
"\n"
|
|
6686
|
+
"Cultural knowledge should capture reusable insights, best practices, or contextual knowledge that transcends individual conversations.\n"
|
|
6687
|
+
"Mention your contribution to the user only if it is relevant to their request or they asked to be notified.\n"
|
|
6688
|
+
"</contributing_to_culture>\n\n"
|
|
6689
|
+
)
|
|
6690
|
+
|
|
6320
6691
|
# 3.3.11 Then add a summary of the interaction to the system prompt
|
|
6321
6692
|
if self.add_session_summary_to_context and session.summary is not None:
|
|
6322
6693
|
system_message_content += "Here is a brief summary of your previous interactions:\n\n"
|
|
@@ -6954,7 +7325,9 @@ class Agent:
|
|
|
6954
7325
|
return run_messages
|
|
6955
7326
|
|
|
6956
7327
|
def _get_messages_for_parser_model(
|
|
6957
|
-
self,
|
|
7328
|
+
self,
|
|
7329
|
+
model_response: ModelResponse,
|
|
7330
|
+
response_format: Optional[Union[Dict, Type[BaseModel]]],
|
|
6958
7331
|
) -> List[Message]:
|
|
6959
7332
|
"""Get the messages for the parser model."""
|
|
6960
7333
|
system_content = (
|
|
@@ -6972,7 +7345,9 @@ class Agent:
|
|
|
6972
7345
|
]
|
|
6973
7346
|
|
|
6974
7347
|
def _get_messages_for_parser_model_stream(
|
|
6975
|
-
self,
|
|
7348
|
+
self,
|
|
7349
|
+
run_response: RunOutput,
|
|
7350
|
+
response_format: Optional[Union[Dict, Type[BaseModel]]],
|
|
6976
7351
|
) -> List[Message]:
|
|
6977
7352
|
"""Get the messages for the parser model."""
|
|
6978
7353
|
system_content = (
|
|
@@ -7008,7 +7383,11 @@ class Agent:
|
|
|
7008
7383
|
return messages
|
|
7009
7384
|
|
|
7010
7385
|
def get_relevant_docs_from_knowledge(
|
|
7011
|
-
self,
|
|
7386
|
+
self,
|
|
7387
|
+
query: str,
|
|
7388
|
+
num_documents: Optional[int] = None,
|
|
7389
|
+
filters: Optional[Dict[str, Any]] = None,
|
|
7390
|
+
**kwargs,
|
|
7012
7391
|
) -> Optional[List[Union[Dict[str, Any], str]]]:
|
|
7013
7392
|
"""Get relevant docs from the knowledge base to answer a query.
|
|
7014
7393
|
|
|
@@ -7083,7 +7462,11 @@ class Agent:
|
|
|
7083
7462
|
raise e
|
|
7084
7463
|
|
|
7085
7464
|
async def aget_relevant_docs_from_knowledge(
|
|
7086
|
-
self,
|
|
7465
|
+
self,
|
|
7466
|
+
query: str,
|
|
7467
|
+
num_documents: Optional[int] = None,
|
|
7468
|
+
filters: Optional[Dict[str, Any]] = None,
|
|
7469
|
+
**kwargs,
|
|
7087
7470
|
) -> Optional[List[Union[Dict[str, Any], str]]]:
|
|
7088
7471
|
"""Get relevant documents from knowledge base asynchronously."""
|
|
7089
7472
|
from agno.knowledge.document import Document
|
|
@@ -7418,7 +7801,10 @@ class Agent:
|
|
|
7418
7801
|
def _reason(self, run_response: RunOutput, run_messages: RunMessages) -> Iterator[RunOutputEvent]:
|
|
7419
7802
|
# Yield a reasoning started event
|
|
7420
7803
|
if self.stream_intermediate_steps:
|
|
7421
|
-
yield self._handle_event(
|
|
7804
|
+
yield self._handle_event(
|
|
7805
|
+
create_reasoning_started_event(from_run_response=run_response),
|
|
7806
|
+
run_response,
|
|
7807
|
+
)
|
|
7422
7808
|
|
|
7423
7809
|
use_default_reasoning = False
|
|
7424
7810
|
|
|
@@ -7479,56 +7865,64 @@ class Agent:
|
|
|
7479
7865
|
|
|
7480
7866
|
log_debug("Starting DeepSeek Reasoning", center=True, symbol="=")
|
|
7481
7867
|
reasoning_message = get_deepseek_reasoning(
|
|
7482
|
-
reasoning_agent=reasoning_agent,
|
|
7868
|
+
reasoning_agent=reasoning_agent,
|
|
7869
|
+
messages=run_messages.get_input_messages(),
|
|
7483
7870
|
)
|
|
7484
7871
|
elif is_groq:
|
|
7485
7872
|
from agno.reasoning.groq import get_groq_reasoning
|
|
7486
7873
|
|
|
7487
7874
|
log_debug("Starting Groq Reasoning", center=True, symbol="=")
|
|
7488
7875
|
reasoning_message = get_groq_reasoning(
|
|
7489
|
-
reasoning_agent=reasoning_agent,
|
|
7876
|
+
reasoning_agent=reasoning_agent,
|
|
7877
|
+
messages=run_messages.get_input_messages(),
|
|
7490
7878
|
)
|
|
7491
7879
|
elif is_openai:
|
|
7492
7880
|
from agno.reasoning.openai import get_openai_reasoning
|
|
7493
7881
|
|
|
7494
7882
|
log_debug("Starting OpenAI Reasoning", center=True, symbol="=")
|
|
7495
7883
|
reasoning_message = get_openai_reasoning(
|
|
7496
|
-
reasoning_agent=reasoning_agent,
|
|
7884
|
+
reasoning_agent=reasoning_agent,
|
|
7885
|
+
messages=run_messages.get_input_messages(),
|
|
7497
7886
|
)
|
|
7498
7887
|
elif is_ollama:
|
|
7499
7888
|
from agno.reasoning.ollama import get_ollama_reasoning
|
|
7500
7889
|
|
|
7501
7890
|
log_debug("Starting Ollama Reasoning", center=True, symbol="=")
|
|
7502
7891
|
reasoning_message = get_ollama_reasoning(
|
|
7503
|
-
reasoning_agent=reasoning_agent,
|
|
7892
|
+
reasoning_agent=reasoning_agent,
|
|
7893
|
+
messages=run_messages.get_input_messages(),
|
|
7504
7894
|
)
|
|
7505
7895
|
elif is_ai_foundry:
|
|
7506
7896
|
from agno.reasoning.azure_ai_foundry import get_ai_foundry_reasoning
|
|
7507
7897
|
|
|
7508
7898
|
log_debug("Starting Azure AI Foundry Reasoning", center=True, symbol="=")
|
|
7509
7899
|
reasoning_message = get_ai_foundry_reasoning(
|
|
7510
|
-
reasoning_agent=reasoning_agent,
|
|
7900
|
+
reasoning_agent=reasoning_agent,
|
|
7901
|
+
messages=run_messages.get_input_messages(),
|
|
7511
7902
|
)
|
|
7512
7903
|
elif is_gemini:
|
|
7513
7904
|
from agno.reasoning.gemini import get_gemini_reasoning
|
|
7514
7905
|
|
|
7515
7906
|
log_debug("Starting Gemini Reasoning", center=True, symbol="=")
|
|
7516
7907
|
reasoning_message = get_gemini_reasoning(
|
|
7517
|
-
reasoning_agent=reasoning_agent,
|
|
7908
|
+
reasoning_agent=reasoning_agent,
|
|
7909
|
+
messages=run_messages.get_input_messages(),
|
|
7518
7910
|
)
|
|
7519
7911
|
elif is_anthropic:
|
|
7520
7912
|
from agno.reasoning.anthropic import get_anthropic_reasoning
|
|
7521
7913
|
|
|
7522
7914
|
log_debug("Starting Anthropic Claude Reasoning", center=True, symbol="=")
|
|
7523
7915
|
reasoning_message = get_anthropic_reasoning(
|
|
7524
|
-
reasoning_agent=reasoning_agent,
|
|
7916
|
+
reasoning_agent=reasoning_agent,
|
|
7917
|
+
messages=run_messages.get_input_messages(),
|
|
7525
7918
|
)
|
|
7526
7919
|
elif is_vertexai:
|
|
7527
7920
|
from agno.reasoning.vertexai import get_vertexai_reasoning
|
|
7528
7921
|
|
|
7529
7922
|
log_debug("Starting VertexAI Reasoning", center=True, symbol="=")
|
|
7530
7923
|
reasoning_message = get_vertexai_reasoning(
|
|
7531
|
-
reasoning_agent=reasoning_agent,
|
|
7924
|
+
reasoning_agent=reasoning_agent,
|
|
7925
|
+
messages=run_messages.get_input_messages(),
|
|
7532
7926
|
)
|
|
7533
7927
|
|
|
7534
7928
|
if reasoning_message is None:
|
|
@@ -7561,7 +7955,10 @@ class Agent:
|
|
|
7561
7955
|
|
|
7562
7956
|
if use_default_reasoning:
|
|
7563
7957
|
from agno.reasoning.default import get_default_reasoning_agent
|
|
7564
|
-
from agno.reasoning.helpers import
|
|
7958
|
+
from agno.reasoning.helpers import (
|
|
7959
|
+
get_next_action,
|
|
7960
|
+
update_messages_with_reasoning,
|
|
7961
|
+
)
|
|
7565
7962
|
|
|
7566
7963
|
# Get default reasoning agent
|
|
7567
7964
|
reasoning_agent: Optional[Agent] = self.reasoning_agent # type: ignore
|
|
@@ -7627,7 +8024,8 @@ class Agent:
|
|
|
7627
8024
|
if self.stream_intermediate_steps:
|
|
7628
8025
|
for reasoning_step in reasoning_steps:
|
|
7629
8026
|
updated_reasoning_content = self._format_reasoning_step_content(
|
|
7630
|
-
run_response=run_response,
|
|
8027
|
+
run_response=run_response,
|
|
8028
|
+
reasoning_step=reasoning_step,
|
|
7631
8029
|
)
|
|
7632
8030
|
|
|
7633
8031
|
yield self._handle_event(
|
|
@@ -7686,7 +8084,10 @@ class Agent:
|
|
|
7686
8084
|
async def _areason(self, run_response: RunOutput, run_messages: RunMessages) -> Any:
|
|
7687
8085
|
# Yield a reasoning started event
|
|
7688
8086
|
if self.stream_intermediate_steps:
|
|
7689
|
-
yield self._handle_event(
|
|
8087
|
+
yield self._handle_event(
|
|
8088
|
+
create_reasoning_started_event(from_run_response=run_response),
|
|
8089
|
+
run_response,
|
|
8090
|
+
)
|
|
7690
8091
|
|
|
7691
8092
|
use_default_reasoning = False
|
|
7692
8093
|
|
|
@@ -7747,56 +8148,64 @@ class Agent:
|
|
|
7747
8148
|
|
|
7748
8149
|
log_debug("Starting DeepSeek Reasoning", center=True, symbol="=")
|
|
7749
8150
|
reasoning_message = await aget_deepseek_reasoning(
|
|
7750
|
-
reasoning_agent=reasoning_agent,
|
|
8151
|
+
reasoning_agent=reasoning_agent,
|
|
8152
|
+
messages=run_messages.get_input_messages(),
|
|
7751
8153
|
)
|
|
7752
8154
|
elif is_groq:
|
|
7753
8155
|
from agno.reasoning.groq import aget_groq_reasoning
|
|
7754
8156
|
|
|
7755
8157
|
log_debug("Starting Groq Reasoning", center=True, symbol="=")
|
|
7756
8158
|
reasoning_message = await aget_groq_reasoning(
|
|
7757
|
-
reasoning_agent=reasoning_agent,
|
|
8159
|
+
reasoning_agent=reasoning_agent,
|
|
8160
|
+
messages=run_messages.get_input_messages(),
|
|
7758
8161
|
)
|
|
7759
8162
|
elif is_openai:
|
|
7760
8163
|
from agno.reasoning.openai import aget_openai_reasoning
|
|
7761
8164
|
|
|
7762
8165
|
log_debug("Starting OpenAI Reasoning", center=True, symbol="=")
|
|
7763
8166
|
reasoning_message = await aget_openai_reasoning(
|
|
7764
|
-
reasoning_agent=reasoning_agent,
|
|
8167
|
+
reasoning_agent=reasoning_agent,
|
|
8168
|
+
messages=run_messages.get_input_messages(),
|
|
7765
8169
|
)
|
|
7766
8170
|
elif is_ollama:
|
|
7767
8171
|
from agno.reasoning.ollama import get_ollama_reasoning
|
|
7768
8172
|
|
|
7769
8173
|
log_debug("Starting Ollama Reasoning", center=True, symbol="=")
|
|
7770
8174
|
reasoning_message = get_ollama_reasoning(
|
|
7771
|
-
reasoning_agent=reasoning_agent,
|
|
8175
|
+
reasoning_agent=reasoning_agent,
|
|
8176
|
+
messages=run_messages.get_input_messages(),
|
|
7772
8177
|
)
|
|
7773
8178
|
elif is_ai_foundry:
|
|
7774
8179
|
from agno.reasoning.azure_ai_foundry import get_ai_foundry_reasoning
|
|
7775
8180
|
|
|
7776
8181
|
log_debug("Starting Azure AI Foundry Reasoning", center=True, symbol="=")
|
|
7777
8182
|
reasoning_message = get_ai_foundry_reasoning(
|
|
7778
|
-
reasoning_agent=reasoning_agent,
|
|
8183
|
+
reasoning_agent=reasoning_agent,
|
|
8184
|
+
messages=run_messages.get_input_messages(),
|
|
7779
8185
|
)
|
|
7780
8186
|
elif is_gemini:
|
|
7781
8187
|
from agno.reasoning.gemini import aget_gemini_reasoning
|
|
7782
8188
|
|
|
7783
8189
|
log_debug("Starting Gemini Reasoning", center=True, symbol="=")
|
|
7784
8190
|
reasoning_message = await aget_gemini_reasoning(
|
|
7785
|
-
reasoning_agent=reasoning_agent,
|
|
8191
|
+
reasoning_agent=reasoning_agent,
|
|
8192
|
+
messages=run_messages.get_input_messages(),
|
|
7786
8193
|
)
|
|
7787
8194
|
elif is_anthropic:
|
|
7788
8195
|
from agno.reasoning.anthropic import aget_anthropic_reasoning
|
|
7789
8196
|
|
|
7790
8197
|
log_debug("Starting Anthropic Claude Reasoning", center=True, symbol="=")
|
|
7791
8198
|
reasoning_message = await aget_anthropic_reasoning(
|
|
7792
|
-
reasoning_agent=reasoning_agent,
|
|
8199
|
+
reasoning_agent=reasoning_agent,
|
|
8200
|
+
messages=run_messages.get_input_messages(),
|
|
7793
8201
|
)
|
|
7794
8202
|
elif is_vertexai:
|
|
7795
8203
|
from agno.reasoning.vertexai import aget_vertexai_reasoning
|
|
7796
8204
|
|
|
7797
8205
|
log_debug("Starting VertexAI Reasoning", center=True, symbol="=")
|
|
7798
8206
|
reasoning_message = await aget_vertexai_reasoning(
|
|
7799
|
-
reasoning_agent=reasoning_agent,
|
|
8207
|
+
reasoning_agent=reasoning_agent,
|
|
8208
|
+
messages=run_messages.get_input_messages(),
|
|
7800
8209
|
)
|
|
7801
8210
|
|
|
7802
8211
|
if reasoning_message is None:
|
|
@@ -7829,7 +8238,10 @@ class Agent:
|
|
|
7829
8238
|
|
|
7830
8239
|
if use_default_reasoning:
|
|
7831
8240
|
from agno.reasoning.default import get_default_reasoning_agent
|
|
7832
|
-
from agno.reasoning.helpers import
|
|
8241
|
+
from agno.reasoning.helpers import (
|
|
8242
|
+
get_next_action,
|
|
8243
|
+
update_messages_with_reasoning,
|
|
8244
|
+
)
|
|
7833
8245
|
|
|
7834
8246
|
# Get default reasoning agent
|
|
7835
8247
|
reasoning_agent: Optional[Agent] = self.reasoning_agent # type: ignore
|
|
@@ -7895,7 +8307,8 @@ class Agent:
|
|
|
7895
8307
|
if self.stream_intermediate_steps:
|
|
7896
8308
|
for reasoning_step in reasoning_steps:
|
|
7897
8309
|
updated_reasoning_content = self._format_reasoning_step_content(
|
|
7898
|
-
run_response=run_response,
|
|
8310
|
+
run_response=run_response,
|
|
8311
|
+
reasoning_step=reasoning_step,
|
|
7899
8312
|
)
|
|
7900
8313
|
|
|
7901
8314
|
# Yield the response with the updated reasoning_content
|
|
@@ -7985,7 +8398,10 @@ class Agent:
|
|
|
7985
8398
|
response_format=parser_response_format,
|
|
7986
8399
|
)
|
|
7987
8400
|
self._process_parser_response(
|
|
7988
|
-
model_response,
|
|
8401
|
+
model_response,
|
|
8402
|
+
run_messages,
|
|
8403
|
+
parser_model_response,
|
|
8404
|
+
messages_for_parser_model,
|
|
7989
8405
|
)
|
|
7990
8406
|
else:
|
|
7991
8407
|
log_warning("A response model is required to parse the response with a parser model")
|
|
@@ -8005,19 +8421,28 @@ class Agent:
|
|
|
8005
8421
|
response_format=parser_response_format,
|
|
8006
8422
|
)
|
|
8007
8423
|
self._process_parser_response(
|
|
8008
|
-
model_response,
|
|
8424
|
+
model_response,
|
|
8425
|
+
run_messages,
|
|
8426
|
+
parser_model_response,
|
|
8427
|
+
messages_for_parser_model,
|
|
8009
8428
|
)
|
|
8010
8429
|
else:
|
|
8011
8430
|
log_warning("A response model is required to parse the response with a parser model")
|
|
8012
8431
|
|
|
8013
8432
|
def _parse_response_with_parser_model_stream(
|
|
8014
|
-
self,
|
|
8433
|
+
self,
|
|
8434
|
+
session: AgentSession,
|
|
8435
|
+
run_response: RunOutput,
|
|
8436
|
+
stream_intermediate_steps: bool = True,
|
|
8015
8437
|
):
|
|
8016
8438
|
"""Parse the model response using the parser model"""
|
|
8017
8439
|
if self.parser_model is not None:
|
|
8018
8440
|
if self.output_schema is not None:
|
|
8019
8441
|
if stream_intermediate_steps:
|
|
8020
|
-
yield self._handle_event(
|
|
8442
|
+
yield self._handle_event(
|
|
8443
|
+
create_parser_model_response_started_event(run_response),
|
|
8444
|
+
run_response,
|
|
8445
|
+
)
|
|
8021
8446
|
|
|
8022
8447
|
parser_model_response = ModelResponse(content="")
|
|
8023
8448
|
parser_response_format = self._get_response_format(self.parser_model)
|
|
@@ -8050,19 +8475,28 @@ class Agent:
|
|
|
8050
8475
|
log_warning("Unable to parse response with parser model")
|
|
8051
8476
|
|
|
8052
8477
|
if stream_intermediate_steps:
|
|
8053
|
-
yield self._handle_event(
|
|
8478
|
+
yield self._handle_event(
|
|
8479
|
+
create_parser_model_response_completed_event(run_response),
|
|
8480
|
+
run_response,
|
|
8481
|
+
)
|
|
8054
8482
|
|
|
8055
8483
|
else:
|
|
8056
8484
|
log_warning("A response model is required to parse the response with a parser model")
|
|
8057
8485
|
|
|
8058
8486
|
async def _aparse_response_with_parser_model_stream(
|
|
8059
|
-
self,
|
|
8487
|
+
self,
|
|
8488
|
+
session: AgentSession,
|
|
8489
|
+
run_response: RunOutput,
|
|
8490
|
+
stream_intermediate_steps: bool = True,
|
|
8060
8491
|
):
|
|
8061
8492
|
"""Parse the model response using the parser model stream."""
|
|
8062
8493
|
if self.parser_model is not None:
|
|
8063
8494
|
if self.output_schema is not None:
|
|
8064
8495
|
if stream_intermediate_steps:
|
|
8065
|
-
yield self._handle_event(
|
|
8496
|
+
yield self._handle_event(
|
|
8497
|
+
create_parser_model_response_started_event(run_response),
|
|
8498
|
+
run_response,
|
|
8499
|
+
)
|
|
8066
8500
|
|
|
8067
8501
|
parser_model_response = ModelResponse(content="")
|
|
8068
8502
|
parser_response_format = self._get_response_format(self.parser_model)
|
|
@@ -8097,7 +8531,10 @@ class Agent:
|
|
|
8097
8531
|
log_warning("Unable to parse response with parser model")
|
|
8098
8532
|
|
|
8099
8533
|
if stream_intermediate_steps:
|
|
8100
|
-
yield self._handle_event(
|
|
8534
|
+
yield self._handle_event(
|
|
8535
|
+
create_parser_model_response_completed_event(run_response),
|
|
8536
|
+
run_response,
|
|
8537
|
+
)
|
|
8101
8538
|
else:
|
|
8102
8539
|
log_warning("A response model is required to parse the response with a parser model")
|
|
8103
8540
|
|
|
@@ -8258,6 +8695,30 @@ class Agent:
|
|
|
8258
8695
|
|
|
8259
8696
|
return Function.from_callable(update_user_memory_function, name="update_user_memory")
|
|
8260
8697
|
|
|
8698
|
+
def _get_update_cultural_knowledge_function(self, async_mode: bool = False) -> Function:
|
|
8699
|
+
def update_cultural_knowledge(task: str) -> str:
|
|
8700
|
+
"""Use this function to update a cultural knowledge."""
|
|
8701
|
+
self.culture_manager = cast(CultureManager, self.culture_manager)
|
|
8702
|
+
response = self.culture_manager.update_culture_task(task=task)
|
|
8703
|
+
|
|
8704
|
+
return response
|
|
8705
|
+
|
|
8706
|
+
async def aupdate_cultural_knowledge(task: str) -> str:
|
|
8707
|
+
"""Use this function to update a cultural knowledge asynchronously."""
|
|
8708
|
+
self.culture_manager = cast(CultureManager, self.culture_manager)
|
|
8709
|
+
response = await self.culture_manager.aupdate_culture_task(task=task)
|
|
8710
|
+
return response
|
|
8711
|
+
|
|
8712
|
+
if async_mode:
|
|
8713
|
+
update_cultural_knowledge_function = aupdate_cultural_knowledge
|
|
8714
|
+
else:
|
|
8715
|
+
update_cultural_knowledge_function = update_cultural_knowledge # type: ignore
|
|
8716
|
+
|
|
8717
|
+
return Function.from_callable(
|
|
8718
|
+
update_cultural_knowledge_function,
|
|
8719
|
+
name="create_or_update_cultural_knowledge",
|
|
8720
|
+
)
|
|
8721
|
+
|
|
8261
8722
|
def _get_chat_history_function(self, session: AgentSession) -> Callable:
|
|
8262
8723
|
def get_chat_history(num_chats: Optional[int] = None) -> str:
|
|
8263
8724
|
"""Use this function to get the chat history between the user and agent.
|
|
@@ -8333,7 +8794,10 @@ class Agent:
|
|
|
8333
8794
|
return f"Updated session state: {session_state}"
|
|
8334
8795
|
|
|
8335
8796
|
def _get_search_knowledge_base_function(
|
|
8336
|
-
self,
|
|
8797
|
+
self,
|
|
8798
|
+
run_response: RunOutput,
|
|
8799
|
+
knowledge_filters: Optional[Dict[str, Any]] = None,
|
|
8800
|
+
async_mode: bool = False,
|
|
8337
8801
|
) -> Function:
|
|
8338
8802
|
"""Factory function to create a search_knowledge_base function with filters."""
|
|
8339
8803
|
|
|
@@ -8353,7 +8817,9 @@ class Agent:
|
|
|
8353
8817
|
docs_from_knowledge = self.get_relevant_docs_from_knowledge(query=query, filters=knowledge_filters)
|
|
8354
8818
|
if docs_from_knowledge is not None:
|
|
8355
8819
|
references = MessageReferences(
|
|
8356
|
-
query=query,
|
|
8820
|
+
query=query,
|
|
8821
|
+
references=docs_from_knowledge,
|
|
8822
|
+
time=round(retrieval_timer.elapsed, 4),
|
|
8357
8823
|
)
|
|
8358
8824
|
# Add the references to the run_response
|
|
8359
8825
|
if run_response.references is None:
|
|
@@ -8382,7 +8848,9 @@ class Agent:
|
|
|
8382
8848
|
docs_from_knowledge = await self.aget_relevant_docs_from_knowledge(query=query, filters=knowledge_filters)
|
|
8383
8849
|
if docs_from_knowledge is not None:
|
|
8384
8850
|
references = MessageReferences(
|
|
8385
|
-
query=query,
|
|
8851
|
+
query=query,
|
|
8852
|
+
references=docs_from_knowledge,
|
|
8853
|
+
time=round(retrieval_timer.elapsed, 4),
|
|
8386
8854
|
)
|
|
8387
8855
|
if run_response.references is None:
|
|
8388
8856
|
run_response.references = []
|
|
@@ -8402,7 +8870,10 @@ class Agent:
|
|
|
8402
8870
|
return Function.from_callable(search_knowledge_base_function, name="search_knowledge_base")
|
|
8403
8871
|
|
|
8404
8872
|
def _search_knowledge_base_with_agentic_filters_function(
|
|
8405
|
-
self,
|
|
8873
|
+
self,
|
|
8874
|
+
run_response: RunOutput,
|
|
8875
|
+
knowledge_filters: Optional[Dict[str, Any]] = None,
|
|
8876
|
+
async_mode: bool = False,
|
|
8406
8877
|
) -> Function:
|
|
8407
8878
|
"""Factory function to create a search_knowledge_base function with filters."""
|
|
8408
8879
|
|
|
@@ -8425,7 +8896,9 @@ class Agent:
|
|
|
8425
8896
|
docs_from_knowledge = self.get_relevant_docs_from_knowledge(query=query, filters=search_filters)
|
|
8426
8897
|
if docs_from_knowledge is not None:
|
|
8427
8898
|
references = MessageReferences(
|
|
8428
|
-
query=query,
|
|
8899
|
+
query=query,
|
|
8900
|
+
references=docs_from_knowledge,
|
|
8901
|
+
time=round(retrieval_timer.elapsed, 4),
|
|
8429
8902
|
)
|
|
8430
8903
|
# Add the references to the run_response
|
|
8431
8904
|
if run_response.references is None:
|
|
@@ -8458,7 +8931,9 @@ class Agent:
|
|
|
8458
8931
|
docs_from_knowledge = await self.aget_relevant_docs_from_knowledge(query=query, filters=search_filters)
|
|
8459
8932
|
if docs_from_knowledge is not None:
|
|
8460
8933
|
references = MessageReferences(
|
|
8461
|
-
query=query,
|
|
8934
|
+
query=query,
|
|
8935
|
+
references=docs_from_knowledge,
|
|
8936
|
+
time=round(retrieval_timer.elapsed, 4),
|
|
8462
8937
|
)
|
|
8463
8938
|
if run_response.references is None:
|
|
8464
8939
|
run_response.references = []
|
|
@@ -8475,7 +8950,10 @@ class Agent:
|
|
|
8475
8950
|
else:
|
|
8476
8951
|
search_knowledge_base_function = search_knowledge_base # type: ignore
|
|
8477
8952
|
|
|
8478
|
-
return Function.from_callable(
|
|
8953
|
+
return Function.from_callable(
|
|
8954
|
+
search_knowledge_base_function,
|
|
8955
|
+
name="search_knowledge_base_with_agentic_filters",
|
|
8956
|
+
)
|
|
8479
8957
|
|
|
8480
8958
|
def add_to_knowledge(self, query: str, result: str) -> str:
|
|
8481
8959
|
"""Use this function to add information to the knowledge base for future use.
|
|
@@ -8530,7 +9008,9 @@ class Agent:
|
|
|
8530
9008
|
self.db = cast(BaseDb, self.db)
|
|
8531
9009
|
|
|
8532
9010
|
selected_sessions = self.db.get_sessions(
|
|
8533
|
-
session_type=SessionType.AGENT,
|
|
9011
|
+
session_type=SessionType.AGENT,
|
|
9012
|
+
limit=num_history_sessions,
|
|
9013
|
+
user_id=user_id,
|
|
8534
9014
|
)
|
|
8535
9015
|
|
|
8536
9016
|
all_messages = []
|
|
@@ -9139,7 +9619,12 @@ class Agent:
|
|
|
9139
9619
|
|
|
9140
9620
|
if input:
|
|
9141
9621
|
self.print_response(
|
|
9142
|
-
input=input,
|
|
9622
|
+
input=input,
|
|
9623
|
+
stream=stream,
|
|
9624
|
+
markdown=markdown,
|
|
9625
|
+
user_id=user_id,
|
|
9626
|
+
session_id=session_id,
|
|
9627
|
+
**kwargs,
|
|
9143
9628
|
)
|
|
9144
9629
|
|
|
9145
9630
|
_exit_on = exit_on or ["exit", "quit", "bye"]
|
|
@@ -9149,7 +9634,12 @@ class Agent:
|
|
|
9149
9634
|
break
|
|
9150
9635
|
|
|
9151
9636
|
self.print_response(
|
|
9152
|
-
input=message,
|
|
9637
|
+
input=message,
|
|
9638
|
+
stream=stream,
|
|
9639
|
+
markdown=markdown,
|
|
9640
|
+
user_id=user_id,
|
|
9641
|
+
session_id=session_id,
|
|
9642
|
+
**kwargs,
|
|
9153
9643
|
)
|
|
9154
9644
|
|
|
9155
9645
|
async def acli_app(
|
|
@@ -9172,7 +9662,12 @@ class Agent:
|
|
|
9172
9662
|
|
|
9173
9663
|
if input:
|
|
9174
9664
|
await self.aprint_response(
|
|
9175
|
-
input=input,
|
|
9665
|
+
input=input,
|
|
9666
|
+
stream=stream,
|
|
9667
|
+
markdown=markdown,
|
|
9668
|
+
user_id=user_id,
|
|
9669
|
+
session_id=session_id,
|
|
9670
|
+
**kwargs,
|
|
9176
9671
|
)
|
|
9177
9672
|
|
|
9178
9673
|
_exit_on = exit_on or ["exit", "quit", "bye"]
|
|
@@ -9182,7 +9677,12 @@ class Agent:
|
|
|
9182
9677
|
break
|
|
9183
9678
|
|
|
9184
9679
|
await self.aprint_response(
|
|
9185
|
-
input=message,
|
|
9680
|
+
input=message,
|
|
9681
|
+
stream=stream,
|
|
9682
|
+
markdown=markdown,
|
|
9683
|
+
user_id=user_id,
|
|
9684
|
+
session_id=session_id,
|
|
9685
|
+
**kwargs,
|
|
9186
9686
|
)
|
|
9187
9687
|
|
|
9188
9688
|
###########################################################################
|
|
@@ -9200,7 +9700,12 @@ class Agent:
|
|
|
9200
9700
|
"parser_model": self.parser_model.to_dict() if self.parser_model else None,
|
|
9201
9701
|
"output_model": self.output_model.to_dict() if self.output_model else None,
|
|
9202
9702
|
"has_tools": self.tools is not None,
|
|
9203
|
-
"has_memory": self.enable_user_memories is True
|
|
9703
|
+
"has_memory": self.enable_user_memories is True
|
|
9704
|
+
or self.enable_agentic_memory is True
|
|
9705
|
+
or self.memory_manager is not None,
|
|
9706
|
+
"has_culture": self.enable_agentic_culture is True
|
|
9707
|
+
or self.update_cultural_knowledge is True
|
|
9708
|
+
or self.culture_manager is not None,
|
|
9204
9709
|
"has_reasoning": self.reasoning is True,
|
|
9205
9710
|
"has_knowledge": self.knowledge is not None,
|
|
9206
9711
|
"has_input_schema": self.input_schema is not None,
|
|
@@ -9219,7 +9724,11 @@ class Agent:
|
|
|
9219
9724
|
|
|
9220
9725
|
try:
|
|
9221
9726
|
create_agent_run(
|
|
9222
|
-
run=AgentRunCreate(
|
|
9727
|
+
run=AgentRunCreate(
|
|
9728
|
+
session_id=session_id,
|
|
9729
|
+
run_id=run_id,
|
|
9730
|
+
data=self._get_telemetry_data(),
|
|
9731
|
+
),
|
|
9223
9732
|
)
|
|
9224
9733
|
except Exception as e:
|
|
9225
9734
|
log_debug(f"Could not create Agent run telemetry event: {e}")
|
|
@@ -9235,7 +9744,11 @@ class Agent:
|
|
|
9235
9744
|
|
|
9236
9745
|
try:
|
|
9237
9746
|
await acreate_agent_run(
|
|
9238
|
-
run=AgentRunCreate(
|
|
9747
|
+
run=AgentRunCreate(
|
|
9748
|
+
session_id=session_id,
|
|
9749
|
+
run_id=run_id,
|
|
9750
|
+
data=self._get_telemetry_data(),
|
|
9751
|
+
)
|
|
9239
9752
|
)
|
|
9240
9753
|
|
|
9241
9754
|
except Exception as e:
|