agno 1.7.2__py3-none-any.whl → 1.7.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- agno/agent/agent.py +264 -155
- agno/api/schemas/agent.py +1 -0
- agno/api/schemas/team.py +1 -0
- agno/app/base.py +0 -22
- agno/app/discord/client.py +134 -56
- agno/app/fastapi/app.py +0 -11
- agno/app/playground/app.py +3 -24
- agno/app/playground/async_router.py +97 -28
- agno/app/playground/operator.py +25 -19
- agno/app/playground/schemas.py +1 -0
- agno/app/playground/sync_router.py +93 -26
- agno/document/reader/gcs/__init__.py +0 -0
- agno/document/reader/gcs/pdf_reader.py +44 -0
- agno/embedder/langdb.py +9 -5
- agno/knowledge/document.py +199 -8
- agno/knowledge/gcs/__init__.py +0 -0
- agno/knowledge/gcs/base.py +39 -0
- agno/knowledge/gcs/pdf.py +21 -0
- agno/models/langdb/langdb.py +8 -5
- agno/run/base.py +2 -0
- agno/run/response.py +4 -4
- agno/run/team.py +6 -6
- agno/run/v2/__init__.py +0 -0
- agno/run/v2/workflow.py +563 -0
- agno/storage/base.py +4 -4
- agno/storage/dynamodb.py +74 -10
- agno/storage/firestore.py +6 -1
- agno/storage/gcs_json.py +8 -2
- agno/storage/json.py +20 -5
- agno/storage/mongodb.py +14 -5
- agno/storage/mysql.py +56 -17
- agno/storage/postgres.py +55 -13
- agno/storage/redis.py +25 -5
- agno/storage/session/__init__.py +3 -1
- agno/storage/session/agent.py +3 -0
- agno/storage/session/team.py +3 -0
- agno/storage/session/v2/__init__.py +5 -0
- agno/storage/session/v2/workflow.py +89 -0
- agno/storage/singlestore.py +74 -12
- agno/storage/sqlite.py +64 -18
- agno/storage/yaml.py +26 -6
- agno/team/team.py +198 -243
- agno/tools/scrapegraph.py +8 -10
- agno/utils/log.py +12 -0
- agno/utils/message.py +5 -1
- agno/utils/openai.py +20 -5
- agno/utils/pprint.py +32 -8
- agno/workflow/v2/__init__.py +21 -0
- agno/workflow/v2/condition.py +554 -0
- agno/workflow/v2/loop.py +602 -0
- agno/workflow/v2/parallel.py +659 -0
- agno/workflow/v2/router.py +521 -0
- agno/workflow/v2/step.py +861 -0
- agno/workflow/v2/steps.py +465 -0
- agno/workflow/v2/types.py +347 -0
- agno/workflow/v2/workflow.py +3134 -0
- agno/workflow/workflow.py +15 -147
- {agno-1.7.2.dist-info → agno-1.7.4.dist-info}/METADATA +1 -1
- {agno-1.7.2.dist-info → agno-1.7.4.dist-info}/RECORD +63 -45
- {agno-1.7.2.dist-info → agno-1.7.4.dist-info}/WHEEL +0 -0
- {agno-1.7.2.dist-info → agno-1.7.4.dist-info}/entry_points.txt +0 -0
- {agno-1.7.2.dist-info → agno-1.7.4.dist-info}/licenses/LICENSE +0 -0
- {agno-1.7.2.dist-info → agno-1.7.4.dist-info}/top_level.txt +0 -0
agno/agent/agent.py
CHANGED
|
@@ -16,6 +16,7 @@ from typing import (
|
|
|
16
16
|
Optional,
|
|
17
17
|
Sequence,
|
|
18
18
|
Set,
|
|
19
|
+
Tuple,
|
|
19
20
|
Type,
|
|
20
21
|
Union,
|
|
21
22
|
cast,
|
|
@@ -317,9 +318,13 @@ class Agent:
|
|
|
317
318
|
|
|
318
319
|
# Optional workflow ID. Indicates this agent is part of a workflow.
|
|
319
320
|
workflow_id: Optional[str] = None
|
|
321
|
+
# Set when this agent is part of a workflow.
|
|
322
|
+
workflow_session_id: Optional[str] = None
|
|
320
323
|
|
|
321
324
|
# Optional team session state. Set by the team leader agent.
|
|
322
325
|
team_session_state: Optional[Dict[str, Any]] = None
|
|
326
|
+
# Optional workflow session state. Set by the workflow.
|
|
327
|
+
workflow_session_state: Optional[Dict[str, Any]] = None
|
|
323
328
|
|
|
324
329
|
# --- Debug & Monitoring ---
|
|
325
330
|
# Enable debug logs
|
|
@@ -542,7 +547,7 @@ class Agent:
|
|
|
542
547
|
self.session_metrics: Optional[SessionMetrics] = None
|
|
543
548
|
|
|
544
549
|
self.run_id: Optional[str] = None
|
|
545
|
-
self.run_input: Optional[Union[str, List, Dict, Message]] = None
|
|
550
|
+
self.run_input: Optional[Union[str, List, Dict, Message, BaseModel]] = None
|
|
546
551
|
self.run_messages: Optional[RunMessages] = None
|
|
547
552
|
self.run_response: Optional[RunResponse] = None
|
|
548
553
|
|
|
@@ -621,9 +626,9 @@ class Agent:
|
|
|
621
626
|
if self.num_history_responses is not None:
|
|
622
627
|
self.num_history_runs = self.num_history_responses
|
|
623
628
|
|
|
624
|
-
def
|
|
625
|
-
self.session_name = None
|
|
629
|
+
def reset_session(self) -> None:
|
|
626
630
|
self.session_state = None
|
|
631
|
+
self.session_name = None
|
|
627
632
|
self.session_metrics = None
|
|
628
633
|
self.images = None
|
|
629
634
|
self.videos = None
|
|
@@ -688,6 +693,72 @@ class Agent:
|
|
|
688
693
|
self.tools = tools
|
|
689
694
|
self._rebuild_tools = True
|
|
690
695
|
|
|
696
|
+
def _initialize_session_state(self, user_id: Optional[str] = None, session_id: Optional[str] = None) -> None:
|
|
697
|
+
self.session_state = self.session_state or {}
|
|
698
|
+
if user_id is not None:
|
|
699
|
+
self.session_state["current_user_id"] = user_id
|
|
700
|
+
if self.team_session_state is not None:
|
|
701
|
+
self.team_session_state["current_user_id"] = user_id
|
|
702
|
+
if self.workflow_session_state is not None:
|
|
703
|
+
self.workflow_session_state["current_user_id"] = user_id
|
|
704
|
+
if session_id is not None:
|
|
705
|
+
self.session_state["current_session_id"] = session_id
|
|
706
|
+
if self.team_session_state is not None:
|
|
707
|
+
self.team_session_state["current_session_id"] = session_id
|
|
708
|
+
if self.workflow_session_state is not None:
|
|
709
|
+
self.workflow_session_state["current_user_id"] = user_id
|
|
710
|
+
|
|
711
|
+
def _reset_session_state(self) -> None:
|
|
712
|
+
"""Reset the session state for the agent."""
|
|
713
|
+
if self.team_session_state is not None:
|
|
714
|
+
self.team_session_state.pop("current_session_id", None)
|
|
715
|
+
self.team_session_state.pop("current_user_id", None)
|
|
716
|
+
if self.session_state is not None:
|
|
717
|
+
self.session_state.pop("current_session_id", None)
|
|
718
|
+
self.session_state.pop("current_user_id", None)
|
|
719
|
+
|
|
720
|
+
def _initialize_session(
|
|
721
|
+
self,
|
|
722
|
+
session_id: Optional[str] = None,
|
|
723
|
+
user_id: Optional[str] = None,
|
|
724
|
+
session_state: Optional[Dict[str, Any]] = None,
|
|
725
|
+
) -> Tuple[str, Optional[str]]:
|
|
726
|
+
"""Initialize the session for the agent."""
|
|
727
|
+
|
|
728
|
+
self.reset_run_state()
|
|
729
|
+
|
|
730
|
+
# Determine the session_id
|
|
731
|
+
if session_id is not None and session_id != "":
|
|
732
|
+
# Reset session state if a session_id is provided. Session name and session state will be loaded from storage.
|
|
733
|
+
# Only reset session state if the session_id is different from the current session_id
|
|
734
|
+
if self.session_id is not None and session_id != self.session_id:
|
|
735
|
+
self.reset_session()
|
|
736
|
+
|
|
737
|
+
self.session_id = session_id
|
|
738
|
+
else:
|
|
739
|
+
if not (self.session_id is None or self.session_id == ""):
|
|
740
|
+
session_id = self.session_id
|
|
741
|
+
else:
|
|
742
|
+
# Generate a new session_id and store it in the agent
|
|
743
|
+
self.session_id = session_id = str(uuid4())
|
|
744
|
+
|
|
745
|
+
# Use the default user_id when necessary
|
|
746
|
+
if user_id is not None and user_id != "":
|
|
747
|
+
user_id = user_id
|
|
748
|
+
else:
|
|
749
|
+
user_id = self.user_id
|
|
750
|
+
|
|
751
|
+
# Determine the session_state
|
|
752
|
+
if session_state is not None:
|
|
753
|
+
self.session_state = session_state
|
|
754
|
+
|
|
755
|
+
self._initialize_session_state(user_id=user_id, session_id=session_id)
|
|
756
|
+
|
|
757
|
+
# Read existing session from storage
|
|
758
|
+
self.read_from_storage(session_id=session_id)
|
|
759
|
+
|
|
760
|
+
return session_id, user_id
|
|
761
|
+
|
|
691
762
|
def _run(
|
|
692
763
|
self,
|
|
693
764
|
run_response: RunResponse,
|
|
@@ -695,6 +766,7 @@ class Agent:
|
|
|
695
766
|
session_id: str,
|
|
696
767
|
user_id: Optional[str] = None,
|
|
697
768
|
response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
|
|
769
|
+
refresh_session_before_write: Optional[bool] = False,
|
|
698
770
|
) -> RunResponse:
|
|
699
771
|
"""Run the Agent and return the RunResponse.
|
|
700
772
|
|
|
@@ -762,7 +834,7 @@ class Agent:
|
|
|
762
834
|
self._convert_response_to_structured_format(run_response)
|
|
763
835
|
|
|
764
836
|
# 6. Save session to storage
|
|
765
|
-
self.write_to_storage(user_id=user_id, session_id=session_id)
|
|
837
|
+
self.write_to_storage(user_id=user_id, session_id=session_id, refresh_session=refresh_session_before_write)
|
|
766
838
|
|
|
767
839
|
# 7. Save output to file if save_response_to_file is set
|
|
768
840
|
self.save_run_response_to_file(message=run_messages.user_message, session_id=session_id)
|
|
@@ -782,6 +854,7 @@ class Agent:
|
|
|
782
854
|
user_id: Optional[str] = None,
|
|
783
855
|
response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
|
|
784
856
|
stream_intermediate_steps: bool = False,
|
|
857
|
+
refresh_session_before_write: Optional[bool] = False,
|
|
785
858
|
) -> Iterator[RunResponseEvent]:
|
|
786
859
|
"""Run the Agent and yield the RunResponse.
|
|
787
860
|
|
|
@@ -854,7 +927,7 @@ class Agent:
|
|
|
854
927
|
yield self._handle_event(create_run_response_completed_event(from_run_response=run_response), run_response)
|
|
855
928
|
|
|
856
929
|
# 7. Save session to storage
|
|
857
|
-
self.write_to_storage(user_id=user_id, session_id=session_id)
|
|
930
|
+
self.write_to_storage(user_id=user_id, session_id=session_id, refresh_session=refresh_session_before_write)
|
|
858
931
|
|
|
859
932
|
# Log Agent Run
|
|
860
933
|
self._log_agent_run(user_id=user_id, session_id=session_id)
|
|
@@ -864,12 +937,13 @@ class Agent:
|
|
|
864
937
|
@overload
|
|
865
938
|
def run(
|
|
866
939
|
self,
|
|
867
|
-
message: Optional[Union[str, List, Dict, Message]] = None,
|
|
940
|
+
message: Optional[Union[str, List, Dict, Message, BaseModel]] = None,
|
|
868
941
|
*,
|
|
869
942
|
stream: Literal[False] = False,
|
|
870
943
|
stream_intermediate_steps: Optional[bool] = None,
|
|
871
944
|
user_id: Optional[str] = None,
|
|
872
945
|
session_id: Optional[str] = None,
|
|
946
|
+
session_state: Optional[Dict[str, Any]] = None,
|
|
873
947
|
audio: Optional[Sequence[Audio]] = None,
|
|
874
948
|
images: Optional[Sequence[Image]] = None,
|
|
875
949
|
videos: Optional[Sequence[Video]] = None,
|
|
@@ -877,18 +951,20 @@ class Agent:
|
|
|
877
951
|
messages: Optional[Sequence[Union[Dict, Message]]] = None,
|
|
878
952
|
retries: Optional[int] = None,
|
|
879
953
|
knowledge_filters: Optional[Dict[str, Any]] = None,
|
|
954
|
+
refresh_session_before_write: Optional[bool] = False,
|
|
880
955
|
**kwargs: Any,
|
|
881
956
|
) -> RunResponse: ...
|
|
882
957
|
|
|
883
958
|
@overload
|
|
884
959
|
def run(
|
|
885
960
|
self,
|
|
886
|
-
message: Optional[Union[str, List, Dict, Message]] = None,
|
|
961
|
+
message: Optional[Union[str, List, Dict, Message, BaseModel]] = None,
|
|
887
962
|
*,
|
|
888
963
|
stream: Literal[True] = True,
|
|
889
964
|
stream_intermediate_steps: Optional[bool] = None,
|
|
890
965
|
user_id: Optional[str] = None,
|
|
891
966
|
session_id: Optional[str] = None,
|
|
967
|
+
session_state: Optional[Dict[str, Any]] = None,
|
|
892
968
|
audio: Optional[Sequence[Audio]] = None,
|
|
893
969
|
images: Optional[Sequence[Image]] = None,
|
|
894
970
|
videos: Optional[Sequence[Video]] = None,
|
|
@@ -896,17 +972,19 @@ class Agent:
|
|
|
896
972
|
messages: Optional[Sequence[Union[Dict, Message]]] = None,
|
|
897
973
|
retries: Optional[int] = None,
|
|
898
974
|
knowledge_filters: Optional[Dict[str, Any]] = None,
|
|
975
|
+
refresh_session_before_write: Optional[bool] = False,
|
|
899
976
|
**kwargs: Any,
|
|
900
977
|
) -> Iterator[RunResponseEvent]: ...
|
|
901
978
|
|
|
902
979
|
def run(
|
|
903
980
|
self,
|
|
904
|
-
message: Optional[Union[str, List, Dict, Message]] = None,
|
|
981
|
+
message: Optional[Union[str, List, Dict, Message, BaseModel]] = None,
|
|
905
982
|
*,
|
|
906
983
|
stream: Optional[bool] = None,
|
|
907
984
|
stream_intermediate_steps: Optional[bool] = None,
|
|
908
985
|
user_id: Optional[str] = None,
|
|
909
986
|
session_id: Optional[str] = None,
|
|
987
|
+
session_state: Optional[Dict[str, Any]] = None,
|
|
910
988
|
audio: Optional[Sequence[Audio]] = None,
|
|
911
989
|
images: Optional[Sequence[Image]] = None,
|
|
912
990
|
videos: Optional[Sequence[Video]] = None,
|
|
@@ -914,39 +992,20 @@ class Agent:
|
|
|
914
992
|
messages: Optional[Sequence[Union[Dict, Message]]] = None,
|
|
915
993
|
retries: Optional[int] = None,
|
|
916
994
|
knowledge_filters: Optional[Dict[str, Any]] = None,
|
|
995
|
+
refresh_session_before_write: Optional[bool] = False,
|
|
917
996
|
**kwargs: Any,
|
|
918
997
|
) -> Union[RunResponse, Iterator[RunResponseEvent]]:
|
|
919
998
|
"""Run the Agent and return the response."""
|
|
920
999
|
|
|
921
|
-
self.
|
|
1000
|
+
session_id, user_id = self._initialize_session(
|
|
1001
|
+
session_id=session_id, user_id=user_id, session_state=session_state
|
|
1002
|
+
)
|
|
922
1003
|
|
|
923
|
-
|
|
924
|
-
# Reset session state if a session_id is provided. Session name and session state will be loaded from storage.
|
|
925
|
-
self.reset_session_state()
|
|
1004
|
+
log_debug(f"Session ID: {session_id}", center=True)
|
|
926
1005
|
|
|
927
1006
|
# Initialize the Agent
|
|
928
1007
|
self.initialize_agent()
|
|
929
1008
|
|
|
930
|
-
# Initialize Session
|
|
931
|
-
# Use the default user_id and session_id when necessary
|
|
932
|
-
user_id = user_id if user_id is not None else self.user_id
|
|
933
|
-
|
|
934
|
-
if session_id is None or session_id == "":
|
|
935
|
-
if not (self.session_id is None or self.session_id == ""):
|
|
936
|
-
session_id = self.session_id
|
|
937
|
-
else:
|
|
938
|
-
# Generate a new session_id and store it in the agent
|
|
939
|
-
session_id = str(uuid4())
|
|
940
|
-
self.session_id = session_id
|
|
941
|
-
else:
|
|
942
|
-
self.session_id = session_id
|
|
943
|
-
|
|
944
|
-
session_id = cast(str, session_id)
|
|
945
|
-
|
|
946
|
-
self._initialize_session_state(user_id=user_id, session_id=session_id)
|
|
947
|
-
|
|
948
|
-
log_debug(f"Session ID: {session_id}", center=True)
|
|
949
|
-
|
|
950
1009
|
# Initialize Knowledge Filters
|
|
951
1010
|
effective_filters = knowledge_filters
|
|
952
1011
|
|
|
@@ -983,9 +1042,6 @@ class Agent:
|
|
|
983
1042
|
self.stream = self.stream or stream
|
|
984
1043
|
self.stream_intermediate_steps = self.stream_intermediate_steps or (stream_intermediate_steps and self.stream)
|
|
985
1044
|
|
|
986
|
-
# Read existing session from storage
|
|
987
|
-
self.read_from_storage(session_id=session_id)
|
|
988
|
-
|
|
989
1045
|
# Read existing session from storage
|
|
990
1046
|
if self.context is not None:
|
|
991
1047
|
self.resolve_run_context()
|
|
@@ -1066,6 +1122,7 @@ class Agent:
|
|
|
1066
1122
|
session_id=session_id,
|
|
1067
1123
|
response_format=response_format,
|
|
1068
1124
|
stream_intermediate_steps=stream_intermediate_steps,
|
|
1125
|
+
refresh_session_before_write=refresh_session_before_write,
|
|
1069
1126
|
)
|
|
1070
1127
|
return response_iterator
|
|
1071
1128
|
else:
|
|
@@ -1075,6 +1132,7 @@ class Agent:
|
|
|
1075
1132
|
user_id=user_id,
|
|
1076
1133
|
session_id=session_id,
|
|
1077
1134
|
response_format=response_format,
|
|
1135
|
+
refresh_session_before_write=refresh_session_before_write,
|
|
1078
1136
|
)
|
|
1079
1137
|
return response
|
|
1080
1138
|
except ModelProviderError as e:
|
|
@@ -1100,6 +1158,8 @@ class Agent:
|
|
|
1100
1158
|
)
|
|
1101
1159
|
else:
|
|
1102
1160
|
return self.run_response
|
|
1161
|
+
finally:
|
|
1162
|
+
self._reset_session_state()
|
|
1103
1163
|
|
|
1104
1164
|
# If we get here, all retries failed
|
|
1105
1165
|
if last_exception is not None:
|
|
@@ -1122,6 +1182,7 @@ class Agent:
|
|
|
1122
1182
|
session_id: str,
|
|
1123
1183
|
user_id: Optional[str] = None,
|
|
1124
1184
|
response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
|
|
1185
|
+
refresh_session_before_write: Optional[bool] = False,
|
|
1125
1186
|
) -> RunResponse:
|
|
1126
1187
|
"""Run the Agent and yield the RunResponse.
|
|
1127
1188
|
|
|
@@ -1188,7 +1249,7 @@ class Agent:
|
|
|
1188
1249
|
self._convert_response_to_structured_format(run_response)
|
|
1189
1250
|
|
|
1190
1251
|
# 6. Save session to storage
|
|
1191
|
-
self.write_to_storage(user_id=user_id, session_id=session_id)
|
|
1252
|
+
self.write_to_storage(user_id=user_id, session_id=session_id, refresh_session=refresh_session_before_write)
|
|
1192
1253
|
|
|
1193
1254
|
# 7. Save output to file if save_response_to_file is set
|
|
1194
1255
|
self.save_run_response_to_file(message=run_messages.user_message, session_id=session_id)
|
|
@@ -1208,6 +1269,7 @@ class Agent:
|
|
|
1208
1269
|
user_id: Optional[str] = None,
|
|
1209
1270
|
response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
|
|
1210
1271
|
stream_intermediate_steps: bool = False,
|
|
1272
|
+
refresh_session_before_write: Optional[bool] = False,
|
|
1211
1273
|
) -> AsyncIterator[RunResponseEvent]:
|
|
1212
1274
|
"""Run the Agent and yield the RunResponse.
|
|
1213
1275
|
|
|
@@ -1283,7 +1345,7 @@ class Agent:
|
|
|
1283
1345
|
yield self._handle_event(create_run_response_completed_event(from_run_response=run_response), run_response)
|
|
1284
1346
|
|
|
1285
1347
|
# 7. Save session to storage
|
|
1286
|
-
self.write_to_storage(user_id=user_id, session_id=session_id)
|
|
1348
|
+
self.write_to_storage(user_id=user_id, session_id=session_id, refresh_session=refresh_session_before_write)
|
|
1287
1349
|
|
|
1288
1350
|
# Log Agent Run
|
|
1289
1351
|
await self._alog_agent_run(user_id=user_id, session_id=session_id)
|
|
@@ -1292,11 +1354,12 @@ class Agent:
|
|
|
1292
1354
|
|
|
1293
1355
|
async def arun(
|
|
1294
1356
|
self,
|
|
1295
|
-
message: Optional[Union[str, List, Dict, Message]] = None,
|
|
1357
|
+
message: Optional[Union[str, List, Dict, Message, BaseModel]] = None,
|
|
1296
1358
|
*,
|
|
1297
1359
|
stream: Optional[bool] = None,
|
|
1298
1360
|
user_id: Optional[str] = None,
|
|
1299
1361
|
session_id: Optional[str] = None,
|
|
1362
|
+
session_state: Optional[Dict[str, Any]] = None,
|
|
1300
1363
|
audio: Optional[Sequence[Audio]] = None,
|
|
1301
1364
|
images: Optional[Sequence[Image]] = None,
|
|
1302
1365
|
videos: Optional[Sequence[Video]] = None,
|
|
@@ -1305,40 +1368,21 @@ class Agent:
|
|
|
1305
1368
|
stream_intermediate_steps: Optional[bool] = None,
|
|
1306
1369
|
retries: Optional[int] = None,
|
|
1307
1370
|
knowledge_filters: Optional[Dict[str, Any]] = None,
|
|
1371
|
+
refresh_session_before_write: Optional[bool] = False,
|
|
1308
1372
|
**kwargs: Any,
|
|
1309
1373
|
) -> Any:
|
|
1310
1374
|
"""Async Run the Agent and return the response."""
|
|
1311
|
-
self.reset_run_state()
|
|
1312
1375
|
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1376
|
+
session_id, user_id = self._initialize_session(
|
|
1377
|
+
session_id=session_id, user_id=user_id, session_state=session_state
|
|
1378
|
+
)
|
|
1379
|
+
|
|
1380
|
+
log_debug(f"Session ID: {session_id}", center=True)
|
|
1316
1381
|
|
|
1317
1382
|
# Initialize the Agent
|
|
1318
1383
|
self.initialize_agent()
|
|
1319
1384
|
|
|
1320
|
-
# Initialize Session
|
|
1321
|
-
# Use the default user_id and session_id when necessary
|
|
1322
|
-
user_id = user_id if user_id is not None else self.user_id
|
|
1323
|
-
|
|
1324
|
-
if session_id is None or session_id == "":
|
|
1325
|
-
if not (self.session_id is None or self.session_id == ""):
|
|
1326
|
-
session_id = self.session_id
|
|
1327
|
-
else:
|
|
1328
|
-
# Generate a new session_id and store it in the agent
|
|
1329
|
-
session_id = str(uuid4())
|
|
1330
|
-
self.session_id = session_id
|
|
1331
|
-
else:
|
|
1332
|
-
self.session_id = session_id
|
|
1333
|
-
|
|
1334
|
-
session_id = cast(str, session_id)
|
|
1335
|
-
|
|
1336
|
-
self._initialize_session_state(user_id=user_id, session_id=session_id)
|
|
1337
|
-
|
|
1338
|
-
log_debug(f"Session ID: {session_id}", center=True)
|
|
1339
|
-
|
|
1340
1385
|
effective_filters = knowledge_filters
|
|
1341
|
-
|
|
1342
1386
|
# When filters are passed manually
|
|
1343
1387
|
if self.knowledge_filters or knowledge_filters:
|
|
1344
1388
|
"""
|
|
@@ -1372,9 +1416,6 @@ class Agent:
|
|
|
1372
1416
|
self.stream = self.stream or stream
|
|
1373
1417
|
self.stream_intermediate_steps = self.stream_intermediate_steps or (stream_intermediate_steps and self.stream)
|
|
1374
1418
|
|
|
1375
|
-
# Read existing session from storage
|
|
1376
|
-
self.read_from_storage(session_id=session_id)
|
|
1377
|
-
|
|
1378
1419
|
# Read existing session from storage
|
|
1379
1420
|
if self.context is not None:
|
|
1380
1421
|
self.resolve_run_context()
|
|
@@ -1456,16 +1497,19 @@ class Agent:
|
|
|
1456
1497
|
session_id=session_id,
|
|
1457
1498
|
response_format=response_format,
|
|
1458
1499
|
stream_intermediate_steps=stream_intermediate_steps,
|
|
1500
|
+
refresh_session_before_write=refresh_session_before_write,
|
|
1459
1501
|
) # type: ignore[assignment]
|
|
1460
1502
|
return response_iterator
|
|
1461
1503
|
else:
|
|
1462
|
-
|
|
1504
|
+
response = await self._arun(
|
|
1463
1505
|
run_response=run_response,
|
|
1464
1506
|
run_messages=run_messages,
|
|
1465
1507
|
user_id=user_id,
|
|
1466
1508
|
session_id=session_id,
|
|
1467
1509
|
response_format=response_format,
|
|
1510
|
+
refresh_session_before_write=refresh_session_before_write,
|
|
1468
1511
|
)
|
|
1512
|
+
return response
|
|
1469
1513
|
except ModelProviderError as e:
|
|
1470
1514
|
log_warning(f"Attempt {attempt + 1}/{num_attempts} failed: {str(e)}")
|
|
1471
1515
|
if isinstance(e, StopAgentRun):
|
|
@@ -1489,6 +1533,8 @@ class Agent:
|
|
|
1489
1533
|
)
|
|
1490
1534
|
else:
|
|
1491
1535
|
return self.run_response
|
|
1536
|
+
finally:
|
|
1537
|
+
self._reset_session_state()
|
|
1492
1538
|
|
|
1493
1539
|
# If we get here, all retries failed
|
|
1494
1540
|
if last_exception is not None:
|
|
@@ -1563,7 +1609,10 @@ class Agent:
|
|
|
1563
1609
|
if session_id is not None:
|
|
1564
1610
|
self.reset_run_state()
|
|
1565
1611
|
# Reset session state if a session_id is provided. Session name and session state will be loaded from storage.
|
|
1566
|
-
self.
|
|
1612
|
+
self.reset_session()
|
|
1613
|
+
# Only reset session state if the session_id is different from the current session_id
|
|
1614
|
+
if self.session_id is not None and session_id != self.session_id:
|
|
1615
|
+
self.session_state = None
|
|
1567
1616
|
|
|
1568
1617
|
# Initialize the Agent
|
|
1569
1618
|
self.initialize_agent()
|
|
@@ -1582,8 +1631,6 @@ class Agent:
|
|
|
1582
1631
|
else:
|
|
1583
1632
|
self.session_id = session_id
|
|
1584
1633
|
|
|
1585
|
-
session_id = cast(str, session_id)
|
|
1586
|
-
|
|
1587
1634
|
self._initialize_session_state(user_id=user_id, session_id=session_id)
|
|
1588
1635
|
|
|
1589
1636
|
log_debug(f"Session ID: {session_id}", center=True)
|
|
@@ -1711,7 +1758,6 @@ class Agent:
|
|
|
1711
1758
|
response_format=response_format,
|
|
1712
1759
|
stream_intermediate_steps=stream_intermediate_steps,
|
|
1713
1760
|
)
|
|
1714
|
-
|
|
1715
1761
|
return response_iterator
|
|
1716
1762
|
else:
|
|
1717
1763
|
response = self._continue_run(
|
|
@@ -1744,6 +1790,8 @@ class Agent:
|
|
|
1744
1790
|
return self.create_run_response(
|
|
1745
1791
|
run_state=RunStatus.cancelled, content="Operation cancelled by user", run_response=run_response
|
|
1746
1792
|
)
|
|
1793
|
+
finally:
|
|
1794
|
+
self._reset_session_state()
|
|
1747
1795
|
|
|
1748
1796
|
# If we get here, all retries failed
|
|
1749
1797
|
if last_exception is not None:
|
|
@@ -1951,7 +1999,10 @@ class Agent:
|
|
|
1951
1999
|
if session_id is not None:
|
|
1952
2000
|
self.reset_run_state()
|
|
1953
2001
|
# Reset session state if a session_id is provided. Session name and session state will be loaded from storage.
|
|
1954
|
-
self.
|
|
2002
|
+
self.reset_session()
|
|
2003
|
+
# Only reset session state if the session_id is different from the current session_id
|
|
2004
|
+
if self.session_id is not None and session_id != self.session_id:
|
|
2005
|
+
self.session_state = None
|
|
1955
2006
|
|
|
1956
2007
|
# Initialize the Agent
|
|
1957
2008
|
self.initialize_agent()
|
|
@@ -1970,8 +2021,6 @@ class Agent:
|
|
|
1970
2021
|
else:
|
|
1971
2022
|
self.session_id = session_id
|
|
1972
2023
|
|
|
1973
|
-
session_id = cast(str, session_id)
|
|
1974
|
-
|
|
1975
2024
|
self._initialize_session_state(user_id=user_id, session_id=session_id)
|
|
1976
2025
|
|
|
1977
2026
|
log_debug(f"Session ID: {session_id}", center=True)
|
|
@@ -2108,16 +2157,16 @@ class Agent:
|
|
|
2108
2157
|
response_format=response_format,
|
|
2109
2158
|
stream_intermediate_steps=stream_intermediate_steps,
|
|
2110
2159
|
)
|
|
2111
|
-
|
|
2112
2160
|
return response_iterator
|
|
2113
2161
|
else:
|
|
2114
|
-
|
|
2162
|
+
response = await self._acontinue_run(
|
|
2115
2163
|
run_response=run_response,
|
|
2116
2164
|
run_messages=run_messages,
|
|
2117
2165
|
user_id=user_id,
|
|
2118
2166
|
session_id=session_id,
|
|
2119
2167
|
response_format=response_format,
|
|
2120
2168
|
)
|
|
2169
|
+
return response
|
|
2121
2170
|
except ModelProviderError as e:
|
|
2122
2171
|
log_warning(f"Attempt {attempt + 1}/{num_attempts} failed: {str(e)}")
|
|
2123
2172
|
if isinstance(e, StopAgentRun):
|
|
@@ -2140,6 +2189,8 @@ class Agent:
|
|
|
2140
2189
|
return self.create_run_response(
|
|
2141
2190
|
run_state=RunStatus.cancelled, content="Operation cancelled by user", run_response=run_response
|
|
2142
2191
|
)
|
|
2192
|
+
finally:
|
|
2193
|
+
self._reset_session_state()
|
|
2143
2194
|
|
|
2144
2195
|
# If we get here, all retries failed
|
|
2145
2196
|
if last_exception is not None:
|
|
@@ -3361,17 +3412,6 @@ class Agent:
|
|
|
3361
3412
|
rr.model = model
|
|
3362
3413
|
return rr
|
|
3363
3414
|
|
|
3364
|
-
def _initialize_session_state(self, user_id: Optional[str] = None, session_id: Optional[str] = None) -> None:
|
|
3365
|
-
self.session_state = self.session_state or {}
|
|
3366
|
-
if user_id is not None:
|
|
3367
|
-
self.session_state["current_user_id"] = user_id
|
|
3368
|
-
if self.team_session_state is not None:
|
|
3369
|
-
self.team_session_state["current_user_id"] = user_id
|
|
3370
|
-
if session_id is not None:
|
|
3371
|
-
self.session_state["current_session_id"] = session_id
|
|
3372
|
-
if self.team_session_state is not None:
|
|
3373
|
-
self.team_session_state["current_session_id"] = session_id
|
|
3374
|
-
|
|
3375
3415
|
def _make_memories_and_summaries(
|
|
3376
3416
|
self,
|
|
3377
3417
|
run_messages: RunMessages,
|
|
@@ -3837,6 +3877,8 @@ class Agent:
|
|
|
3837
3877
|
session_data["session_state"] = self.session_state
|
|
3838
3878
|
if self.team_session_state is not None and len(self.team_session_state) > 0:
|
|
3839
3879
|
session_data["team_session_state"] = self.team_session_state
|
|
3880
|
+
if self.workflow_session_state is not None and len(self.workflow_session_state) > 0:
|
|
3881
|
+
session_data["workflow_session_state"] = self.workflow_session_state
|
|
3840
3882
|
if self.session_metrics is not None:
|
|
3841
3883
|
session_data["session_metrics"] = asdict(self.session_metrics) if self.session_metrics is not None else None
|
|
3842
3884
|
if self.team_data is not None:
|
|
@@ -3873,12 +3915,15 @@ class Agent:
|
|
|
3873
3915
|
memory_dict = None
|
|
3874
3916
|
|
|
3875
3917
|
self.team_session_id = cast(str, self.team_session_id)
|
|
3918
|
+
self.workflow_session_id = cast(str, self.workflow_session_id)
|
|
3919
|
+
|
|
3876
3920
|
self.agent_id = cast(str, self.agent_id)
|
|
3877
3921
|
return AgentSession(
|
|
3878
3922
|
session_id=session_id,
|
|
3879
3923
|
agent_id=self.agent_id,
|
|
3880
3924
|
user_id=user_id,
|
|
3881
3925
|
team_session_id=self.team_session_id,
|
|
3926
|
+
workflow_session_id=self.workflow_session_id,
|
|
3882
3927
|
memory=memory_dict,
|
|
3883
3928
|
agent_data=self.get_agent_data(),
|
|
3884
3929
|
session_data=self.get_session_data(),
|
|
@@ -3889,6 +3934,9 @@ class Agent:
|
|
|
3889
3934
|
def load_agent_session(self, session: AgentSession):
|
|
3890
3935
|
"""Load the existing Agent from an AgentSession (from the database)"""
|
|
3891
3936
|
|
|
3937
|
+
if not hasattr(session, "memory"):
|
|
3938
|
+
return
|
|
3939
|
+
|
|
3892
3940
|
from agno.utils.merge_dict import merge_dictionaries
|
|
3893
3941
|
|
|
3894
3942
|
# Get the agent_id, user_id and session_id from the database
|
|
@@ -3945,6 +3993,22 @@ class Agent:
|
|
|
3945
3993
|
# Update the current team_session_state
|
|
3946
3994
|
self.team_session_state = team_session_state_from_db
|
|
3947
3995
|
|
|
3996
|
+
if "workflow_session_state" in session.session_data:
|
|
3997
|
+
workflow_session_state_from_db = session.session_data.get("workflow_session_state")
|
|
3998
|
+
if (
|
|
3999
|
+
workflow_session_state_from_db is not None
|
|
4000
|
+
and isinstance(workflow_session_state_from_db, dict)
|
|
4001
|
+
and len(workflow_session_state_from_db) > 0
|
|
4002
|
+
):
|
|
4003
|
+
# If the workflow_session_state is already set, merge the workflow_session_state from the database with the current workflow_session_state
|
|
4004
|
+
if self.workflow_session_state is not None and len(self.workflow_session_state) > 0:
|
|
4005
|
+
# This updates workflow_session_state_from_db
|
|
4006
|
+
# If there are conflicting keys, values from workflow_session_state_from_db will take precedence
|
|
4007
|
+
merge_dictionaries(self.workflow_session_state, workflow_session_state_from_db)
|
|
4008
|
+
else:
|
|
4009
|
+
# Update the current workflow_session_state
|
|
4010
|
+
self.workflow_session_state = workflow_session_state_from_db
|
|
4011
|
+
|
|
3948
4012
|
# Get the session_metrics from the database
|
|
3949
4013
|
if "session_metrics" in session.session_data:
|
|
3950
4014
|
session_metrics_from_db = session.session_data.get("session_metrics")
|
|
@@ -4106,13 +4170,56 @@ class Agent:
|
|
|
4106
4170
|
self.load_agent_session(session=self.agent_session)
|
|
4107
4171
|
return self.agent_session
|
|
4108
4172
|
|
|
4109
|
-
def
|
|
4173
|
+
def refresh_from_storage(self, session_id: str) -> None:
|
|
4174
|
+
"""Refresh the AgentSession from storage
|
|
4175
|
+
|
|
4176
|
+
Args:
|
|
4177
|
+
session_id: The session_id to refresh from storage.
|
|
4178
|
+
"""
|
|
4179
|
+
if not self.storage:
|
|
4180
|
+
return
|
|
4181
|
+
|
|
4182
|
+
agent_session_from_db = self.storage.read(session_id=session_id) # type: ignore
|
|
4183
|
+
if (
|
|
4184
|
+
agent_session_from_db is not None
|
|
4185
|
+
and agent_session_from_db.memory is not None # type: ignore
|
|
4186
|
+
and "runs" in agent_session_from_db.memory # type: ignore
|
|
4187
|
+
):
|
|
4188
|
+
if isinstance(self.memory, AgentMemory):
|
|
4189
|
+
return
|
|
4190
|
+
try:
|
|
4191
|
+
if self.memory.runs is None: # type: ignore
|
|
4192
|
+
self.memory.runs = {} # type: ignore
|
|
4193
|
+
if session_id not in self.memory.runs: # type: ignore
|
|
4194
|
+
self.memory.runs[session_id] = [] # type: ignore
|
|
4195
|
+
for run in agent_session_from_db.memory["runs"]: # type: ignore
|
|
4196
|
+
run_session_id = run["session_id"]
|
|
4197
|
+
skip = False
|
|
4198
|
+
for existing_run in self.memory.runs[run_session_id]: # type: ignore
|
|
4199
|
+
if existing_run.run_id == run["run_id"]:
|
|
4200
|
+
skip = True
|
|
4201
|
+
break
|
|
4202
|
+
if skip:
|
|
4203
|
+
continue
|
|
4204
|
+
if "team_id" in run:
|
|
4205
|
+
self.memory.runs[run_session_id].append(TeamRunResponse.from_dict(run)) # type: ignore
|
|
4206
|
+
else:
|
|
4207
|
+
self.memory.runs[run_session_id].append(RunResponse.from_dict(run)) # type: ignore
|
|
4208
|
+
except Exception as e:
|
|
4209
|
+
log_warning(f"Failed to load runs from memory: {e}")
|
|
4210
|
+
|
|
4211
|
+
def write_to_storage(
|
|
4212
|
+
self, session_id: str, user_id: Optional[str] = None, refresh_session: Optional[bool] = False
|
|
4213
|
+
) -> Optional[AgentSession]:
|
|
4110
4214
|
"""Save the AgentSession to storage
|
|
4111
4215
|
|
|
4112
4216
|
Returns:
|
|
4113
4217
|
Optional[AgentSession]: The saved AgentSession or None if not saved.
|
|
4114
4218
|
"""
|
|
4115
4219
|
if self.storage is not None:
|
|
4220
|
+
if refresh_session:
|
|
4221
|
+
self.refresh_from_storage(session_id=session_id)
|
|
4222
|
+
|
|
4116
4223
|
self.agent_session = cast(
|
|
4117
4224
|
AgentSession,
|
|
4118
4225
|
self.storage.upsert(session=self.get_agent_session(session_id=session_id, user_id=user_id)),
|
|
@@ -4192,22 +4299,23 @@ class Agent:
|
|
|
4192
4299
|
self.session_id = str(uuid4())
|
|
4193
4300
|
self.load_session(force=True)
|
|
4194
4301
|
|
|
4195
|
-
def format_message_with_state_variables(self,
|
|
4302
|
+
def format_message_with_state_variables(self, message: Any) -> Any:
|
|
4196
4303
|
"""Format a message with the session state variables."""
|
|
4197
4304
|
import re
|
|
4198
4305
|
import string
|
|
4199
4306
|
|
|
4200
|
-
if not isinstance(
|
|
4201
|
-
return
|
|
4307
|
+
if not isinstance(message, str):
|
|
4308
|
+
return message
|
|
4202
4309
|
|
|
4203
4310
|
format_variables = ChainMap(
|
|
4204
4311
|
self.session_state or {},
|
|
4205
4312
|
self.team_session_state or {},
|
|
4313
|
+
self.workflow_session_state or {},
|
|
4206
4314
|
self.context or {},
|
|
4207
4315
|
self.extra_data or {},
|
|
4208
4316
|
{"user_id": self.user_id} if self.user_id is not None else {},
|
|
4209
4317
|
)
|
|
4210
|
-
converted_msg =
|
|
4318
|
+
converted_msg = message
|
|
4211
4319
|
for var_name in format_variables.keys():
|
|
4212
4320
|
# Only convert standalone {var_name} patterns, not nested ones
|
|
4213
4321
|
pattern = r"\{" + re.escape(var_name) + r"\}"
|
|
@@ -4221,7 +4329,7 @@ class Agent:
|
|
|
4221
4329
|
return result
|
|
4222
4330
|
except Exception as e:
|
|
4223
4331
|
log_warning(f"Template substitution failed: {e}")
|
|
4224
|
-
return
|
|
4332
|
+
return message
|
|
4225
4333
|
|
|
4226
4334
|
def get_system_message(self, session_id: str, user_id: Optional[str] = None) -> Optional[Message]:
|
|
4227
4335
|
"""Return the system message for the Agent.
|
|
@@ -4247,6 +4355,7 @@ class Agent:
|
|
|
4247
4355
|
# Format the system message with the session state variables
|
|
4248
4356
|
if self.add_state_in_messages:
|
|
4249
4357
|
sys_message_content = self.format_message_with_state_variables(sys_message_content)
|
|
4358
|
+
print("HELLO", sys_message_content)
|
|
4250
4359
|
|
|
4251
4360
|
# Add the JSON output prompt if response_model is provided and the model does not support native structured outputs or JSON schema outputs
|
|
4252
4361
|
# or if use_json_mode is True
|
|
@@ -4263,7 +4372,6 @@ class Agent:
|
|
|
4263
4372
|
|
|
4264
4373
|
# type: ignore
|
|
4265
4374
|
return Message(role=self.system_message_role, content=sys_message_content)
|
|
4266
|
-
|
|
4267
4375
|
# 2. If create_default_system_message is False, return None.
|
|
4268
4376
|
if not self.create_default_system_message:
|
|
4269
4377
|
return None
|
|
@@ -4277,12 +4385,19 @@ class Agent:
|
|
|
4277
4385
|
if self.instructions is not None:
|
|
4278
4386
|
_instructions = self.instructions
|
|
4279
4387
|
if callable(self.instructions):
|
|
4280
|
-
|
|
4388
|
+
import inspect
|
|
4389
|
+
|
|
4390
|
+
signature = inspect.signature(self.instructions)
|
|
4391
|
+
if "agent" in signature.parameters:
|
|
4392
|
+
_instructions = self.instructions(agent=self)
|
|
4393
|
+
else:
|
|
4394
|
+
_instructions = self.instructions()
|
|
4281
4395
|
|
|
4282
4396
|
if isinstance(_instructions, str):
|
|
4283
4397
|
instructions.append(_instructions)
|
|
4284
4398
|
elif isinstance(_instructions, list):
|
|
4285
4399
|
instructions.extend(_instructions)
|
|
4400
|
+
|
|
4286
4401
|
# 3.1.1 Add instructions from the Model
|
|
4287
4402
|
_model_instructions = self.model.get_instructions_for_model(self._tools_for_model)
|
|
4288
4403
|
if _model_instructions is not None:
|
|
@@ -4532,7 +4647,7 @@ class Agent:
|
|
|
4532
4647
|
def get_user_message(
|
|
4533
4648
|
self,
|
|
4534
4649
|
*,
|
|
4535
|
-
message: Optional[Union[str, List]],
|
|
4650
|
+
message: Optional[Union[str, List, Dict, Message, BaseModel]] = None,
|
|
4536
4651
|
audio: Optional[Sequence[Audio]] = None,
|
|
4537
4652
|
images: Optional[Sequence[Image]] = None,
|
|
4538
4653
|
videos: Optional[Sequence[Video]] = None,
|
|
@@ -4605,7 +4720,7 @@ class Agent:
|
|
|
4605
4720
|
)
|
|
4606
4721
|
|
|
4607
4722
|
# 2. If create_default_user_message is False or message is a list, return the message as is.
|
|
4608
|
-
if not self.create_default_user_message
|
|
4723
|
+
if not self.create_default_user_message:
|
|
4609
4724
|
return Message(
|
|
4610
4725
|
role=self.user_message_role,
|
|
4611
4726
|
content=message,
|
|
@@ -4616,6 +4731,24 @@ class Agent:
|
|
|
4616
4731
|
**kwargs,
|
|
4617
4732
|
)
|
|
4618
4733
|
|
|
4734
|
+
# Handle list messages by converting to string
|
|
4735
|
+
if isinstance(message, list):
|
|
4736
|
+
# Convert list to string (join with newlines if all elements are strings)
|
|
4737
|
+
if all(isinstance(item, str) for item in message):
|
|
4738
|
+
message_content = "\n".join(message)
|
|
4739
|
+
else:
|
|
4740
|
+
message_content = str(message)
|
|
4741
|
+
|
|
4742
|
+
return Message(
|
|
4743
|
+
role=self.user_message_role,
|
|
4744
|
+
content=message_content,
|
|
4745
|
+
images=images,
|
|
4746
|
+
audio=audio,
|
|
4747
|
+
videos=videos,
|
|
4748
|
+
files=files,
|
|
4749
|
+
**kwargs,
|
|
4750
|
+
)
|
|
4751
|
+
|
|
4619
4752
|
# 3. Build the default user message for the Agent
|
|
4620
4753
|
if message is None:
|
|
4621
4754
|
# If we have any media, return a message with empty content
|
|
@@ -4637,6 +4770,10 @@ class Agent:
|
|
|
4637
4770
|
# Format the message with the session state variables
|
|
4638
4771
|
if self.add_state_in_messages:
|
|
4639
4772
|
user_msg_content = self.format_message_with_state_variables(message)
|
|
4773
|
+
|
|
4774
|
+
# Convert to string for concatenation operations
|
|
4775
|
+
user_msg_content_str = get_text_from_message(user_msg_content) if user_msg_content is not None else ""
|
|
4776
|
+
|
|
4640
4777
|
# 4.1 Add references to user message
|
|
4641
4778
|
if (
|
|
4642
4779
|
self.add_references
|
|
@@ -4644,15 +4781,18 @@ class Agent:
|
|
|
4644
4781
|
and references.references is not None
|
|
4645
4782
|
and len(references.references) > 0
|
|
4646
4783
|
):
|
|
4647
|
-
|
|
4648
|
-
|
|
4649
|
-
|
|
4650
|
-
|
|
4784
|
+
user_msg_content_str += "\n\nUse the following references from the knowledge base if it helps:\n"
|
|
4785
|
+
user_msg_content_str += "<references>\n"
|
|
4786
|
+
user_msg_content_str += self.convert_documents_to_string(references.references) + "\n"
|
|
4787
|
+
user_msg_content_str += "</references>"
|
|
4651
4788
|
# 4.2 Add context to user message
|
|
4652
4789
|
if self.add_context and self.context is not None:
|
|
4653
|
-
|
|
4654
|
-
|
|
4655
|
-
|
|
4790
|
+
user_msg_content_str += "\n\n<context>\n"
|
|
4791
|
+
user_msg_content_str += self.convert_context_to_string(self.context) + "\n"
|
|
4792
|
+
user_msg_content_str += "</context>"
|
|
4793
|
+
|
|
4794
|
+
# Use the string version for the final content
|
|
4795
|
+
user_msg_content = user_msg_content_str
|
|
4656
4796
|
|
|
4657
4797
|
# Return the user message
|
|
4658
4798
|
return Message(
|
|
@@ -4668,7 +4808,7 @@ class Agent:
|
|
|
4668
4808
|
def get_run_messages(
|
|
4669
4809
|
self,
|
|
4670
4810
|
*,
|
|
4671
|
-
message: Optional[Union[str, List, Dict, Message]] = None,
|
|
4811
|
+
message: Optional[Union[str, List, Dict, Message, BaseModel]] = None,
|
|
4672
4812
|
session_id: str,
|
|
4673
4813
|
user_id: Optional[str] = None,
|
|
4674
4814
|
audio: Optional[Sequence[Audio]] = None,
|
|
@@ -4795,6 +4935,14 @@ class Agent:
|
|
|
4795
4935
|
user_message = Message.model_validate(message)
|
|
4796
4936
|
except Exception as e:
|
|
4797
4937
|
log_warning(f"Failed to validate message: {e}")
|
|
4938
|
+
# 4.4 If message is provided as a BaseModel, convert it to a Message
|
|
4939
|
+
elif isinstance(message, BaseModel):
|
|
4940
|
+
try:
|
|
4941
|
+
# Create a user message with the BaseModel content
|
|
4942
|
+
content = message.model_dump_json(indent=2, exclude_none=True)
|
|
4943
|
+
user_message = Message(role=self.user_message_role, content=content)
|
|
4944
|
+
except Exception as e:
|
|
4945
|
+
log_warning(f"Failed to convert BaseModel to message: {e}")
|
|
4798
4946
|
# Add user message to run_messages
|
|
4799
4947
|
if user_message is not None:
|
|
4800
4948
|
run_messages.user_message = user_message
|
|
@@ -5398,7 +5546,7 @@ class Agent:
|
|
|
5398
5546
|
session_metrics = SessionMetrics()
|
|
5399
5547
|
assistant_message_role = self.model.assistant_message_role if self.model is not None else "assistant"
|
|
5400
5548
|
for m in messages:
|
|
5401
|
-
if m.role == assistant_message_role and m.metrics is not None:
|
|
5549
|
+
if m.role == assistant_message_role and m.metrics is not None and m.from_history is False:
|
|
5402
5550
|
session_metrics += m.metrics
|
|
5403
5551
|
return session_metrics
|
|
5404
5552
|
|
|
@@ -6628,53 +6776,6 @@ class Agent:
|
|
|
6628
6776
|
|
|
6629
6777
|
return run_data
|
|
6630
6778
|
|
|
6631
|
-
def register_agent(self) -> None:
|
|
6632
|
-
"""Register this agent with Agno's platform."""
|
|
6633
|
-
self.set_monitoring()
|
|
6634
|
-
if not self.monitoring:
|
|
6635
|
-
return
|
|
6636
|
-
|
|
6637
|
-
from agno.api.agent import AgentCreate, create_agent
|
|
6638
|
-
|
|
6639
|
-
try:
|
|
6640
|
-
# Ensure we have a valid session_id
|
|
6641
|
-
if not self.session_id:
|
|
6642
|
-
self.session_id = str(uuid4())
|
|
6643
|
-
|
|
6644
|
-
create_agent(
|
|
6645
|
-
agent=AgentCreate(
|
|
6646
|
-
name=self.name,
|
|
6647
|
-
agent_id=self.agent_id,
|
|
6648
|
-
workflow_id=self.workflow_id,
|
|
6649
|
-
team_id=self.team_id,
|
|
6650
|
-
app_id=self.app_id,
|
|
6651
|
-
config=self.get_agent_config_dict(),
|
|
6652
|
-
)
|
|
6653
|
-
)
|
|
6654
|
-
except Exception as e:
|
|
6655
|
-
log_warning(f"Could not create Agent: {e}")
|
|
6656
|
-
|
|
6657
|
-
async def _aregister_agent(self) -> None:
|
|
6658
|
-
self.set_monitoring()
|
|
6659
|
-
if not self.monitoring:
|
|
6660
|
-
return
|
|
6661
|
-
|
|
6662
|
-
from agno.api.agent import AgentCreate, acreate_agent
|
|
6663
|
-
|
|
6664
|
-
try:
|
|
6665
|
-
await acreate_agent(
|
|
6666
|
-
agent=AgentCreate(
|
|
6667
|
-
name=self.name,
|
|
6668
|
-
agent_id=self.agent_id,
|
|
6669
|
-
workflow_id=self.workflow_id,
|
|
6670
|
-
team_id=self.team_id,
|
|
6671
|
-
app_id=self.app_id,
|
|
6672
|
-
config=self.get_agent_config_dict(),
|
|
6673
|
-
)
|
|
6674
|
-
)
|
|
6675
|
-
except Exception as e:
|
|
6676
|
-
log_debug(f"Could not create Agent app: {e}")
|
|
6677
|
-
|
|
6678
6779
|
def _log_agent_run(self, session_id: str, user_id: Optional[str] = None) -> None:
|
|
6679
6780
|
self.set_monitoring()
|
|
6680
6781
|
|
|
@@ -6696,6 +6797,7 @@ class Agent:
|
|
|
6696
6797
|
session_id=agent_session.session_id,
|
|
6697
6798
|
agent_data=agent_session.to_dict() if self.monitoring else agent_session.telemetry_data(),
|
|
6698
6799
|
team_session_id=agent_session.team_session_id,
|
|
6800
|
+
workflow_session_id=agent_session.workflow_session_id,
|
|
6699
6801
|
),
|
|
6700
6802
|
monitor=self.monitoring,
|
|
6701
6803
|
)
|
|
@@ -6723,6 +6825,7 @@ class Agent:
|
|
|
6723
6825
|
session_id=agent_session.session_id,
|
|
6724
6826
|
agent_data=agent_session.to_dict() if self.monitoring else agent_session.telemetry_data(),
|
|
6725
6827
|
team_session_id=agent_session.team_session_id,
|
|
6828
|
+
workflow_session_id=agent_session.workflow_session_id,
|
|
6726
6829
|
),
|
|
6727
6830
|
monitor=self.monitoring,
|
|
6728
6831
|
)
|
|
@@ -6735,9 +6838,10 @@ class Agent:
|
|
|
6735
6838
|
|
|
6736
6839
|
def print_response(
|
|
6737
6840
|
self,
|
|
6738
|
-
message: Optional[Union[List, Dict, str, Message]] = None,
|
|
6841
|
+
message: Optional[Union[List, Dict, str, Message, BaseModel]] = None,
|
|
6739
6842
|
*,
|
|
6740
6843
|
session_id: Optional[str] = None,
|
|
6844
|
+
session_state: Optional[Dict[str, Any]] = None,
|
|
6741
6845
|
user_id: Optional[str] = None,
|
|
6742
6846
|
messages: Optional[List[Union[Dict, Message]]] = None,
|
|
6743
6847
|
audio: Optional[Sequence[Audio]] = None,
|
|
@@ -6806,6 +6910,7 @@ class Agent:
|
|
|
6806
6910
|
message=message,
|
|
6807
6911
|
messages=messages,
|
|
6808
6912
|
session_id=session_id,
|
|
6913
|
+
session_state=session_state,
|
|
6809
6914
|
user_id=user_id,
|
|
6810
6915
|
audio=audio,
|
|
6811
6916
|
images=images,
|
|
@@ -7026,6 +7131,7 @@ class Agent:
|
|
|
7026
7131
|
message=message,
|
|
7027
7132
|
messages=messages,
|
|
7028
7133
|
session_id=session_id,
|
|
7134
|
+
session_state=session_state,
|
|
7029
7135
|
user_id=user_id,
|
|
7030
7136
|
audio=audio,
|
|
7031
7137
|
images=images,
|
|
@@ -7181,10 +7287,11 @@ class Agent:
|
|
|
7181
7287
|
|
|
7182
7288
|
async def aprint_response(
|
|
7183
7289
|
self,
|
|
7184
|
-
message: Optional[Union[List, Dict, str, Message]] = None,
|
|
7290
|
+
message: Optional[Union[List, Dict, str, Message, BaseModel]] = None,
|
|
7185
7291
|
*,
|
|
7186
7292
|
messages: Optional[List[Union[Dict, Message]]] = None,
|
|
7187
7293
|
session_id: Optional[str] = None,
|
|
7294
|
+
session_state: Optional[Dict[str, Any]] = None,
|
|
7188
7295
|
user_id: Optional[str] = None,
|
|
7189
7296
|
audio: Optional[Sequence[Audio]] = None,
|
|
7190
7297
|
images: Optional[Sequence[Image]] = None,
|
|
@@ -7252,6 +7359,7 @@ class Agent:
|
|
|
7252
7359
|
message=message,
|
|
7253
7360
|
messages=messages,
|
|
7254
7361
|
session_id=session_id,
|
|
7362
|
+
session_state=session_state,
|
|
7255
7363
|
user_id=user_id,
|
|
7256
7364
|
audio=audio,
|
|
7257
7365
|
images=images,
|
|
@@ -7475,6 +7583,7 @@ class Agent:
|
|
|
7475
7583
|
message=message,
|
|
7476
7584
|
messages=messages,
|
|
7477
7585
|
session_id=session_id,
|
|
7586
|
+
session_state=session_state,
|
|
7478
7587
|
user_id=user_id,
|
|
7479
7588
|
audio=audio,
|
|
7480
7589
|
images=images,
|