agno 2.2.5__py3-none-any.whl → 2.2.7__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 +500 -423
- agno/api/os.py +1 -1
- agno/culture/manager.py +12 -8
- agno/guardrails/prompt_injection.py +1 -0
- agno/knowledge/chunking/agentic.py +6 -2
- agno/knowledge/embedder/vllm.py +262 -0
- agno/knowledge/knowledge.py +37 -5
- agno/memory/manager.py +9 -4
- agno/models/anthropic/claude.py +1 -2
- agno/models/azure/ai_foundry.py +31 -14
- agno/models/azure/openai_chat.py +12 -4
- agno/models/base.py +106 -65
- agno/models/cerebras/cerebras.py +11 -6
- agno/models/groq/groq.py +7 -4
- agno/models/meta/llama.py +12 -6
- agno/models/meta/llama_openai.py +5 -1
- agno/models/openai/chat.py +26 -17
- agno/models/openai/responses.py +11 -63
- agno/models/requesty/requesty.py +5 -2
- agno/models/utils.py +254 -8
- agno/models/vertexai/claude.py +9 -13
- agno/os/app.py +13 -12
- agno/os/routers/evals/evals.py +8 -8
- agno/os/routers/evals/utils.py +1 -0
- agno/os/schema.py +56 -38
- agno/os/utils.py +27 -0
- agno/run/__init__.py +6 -0
- agno/run/agent.py +5 -0
- agno/run/base.py +18 -1
- agno/run/team.py +13 -9
- agno/run/workflow.py +39 -0
- agno/session/summary.py +8 -2
- agno/session/workflow.py +4 -3
- agno/team/team.py +302 -369
- agno/tools/exa.py +21 -16
- agno/tools/file.py +153 -25
- agno/tools/function.py +98 -17
- agno/tools/mcp/mcp.py +8 -1
- agno/tools/notion.py +204 -0
- agno/utils/agent.py +78 -0
- agno/utils/events.py +2 -0
- agno/utils/hooks.py +1 -1
- agno/utils/models/claude.py +25 -8
- agno/utils/print_response/workflow.py +115 -16
- agno/vectordb/__init__.py +2 -1
- agno/vectordb/milvus/milvus.py +5 -0
- agno/vectordb/redis/__init__.py +5 -0
- agno/vectordb/redis/redisdb.py +687 -0
- agno/workflow/__init__.py +2 -0
- agno/workflow/agent.py +299 -0
- agno/workflow/step.py +13 -2
- agno/workflow/workflow.py +969 -72
- {agno-2.2.5.dist-info → agno-2.2.7.dist-info}/METADATA +10 -3
- {agno-2.2.5.dist-info → agno-2.2.7.dist-info}/RECORD +57 -52
- {agno-2.2.5.dist-info → agno-2.2.7.dist-info}/WHEEL +0 -0
- {agno-2.2.5.dist-info → agno-2.2.7.dist-info}/licenses/LICENSE +0 -0
- {agno-2.2.5.dist-info → agno-2.2.7.dist-info}/top_level.txt +0 -0
agno/agent/agent.py
CHANGED
|
@@ -47,14 +47,15 @@ from agno.models.base import Model
|
|
|
47
47
|
from agno.models.message import Message, MessageReferences
|
|
48
48
|
from agno.models.metrics import Metrics
|
|
49
49
|
from agno.models.response import ModelResponse, ModelResponseEvent, ToolExecution
|
|
50
|
+
from agno.models.utils import get_model
|
|
50
51
|
from agno.reasoning.step import NextAction, ReasoningStep, ReasoningSteps
|
|
52
|
+
from agno.run import RunContext, RunStatus
|
|
51
53
|
from agno.run.agent import (
|
|
52
54
|
RunEvent,
|
|
53
55
|
RunInput,
|
|
54
56
|
RunOutput,
|
|
55
57
|
RunOutputEvent,
|
|
56
58
|
)
|
|
57
|
-
from agno.run.base import RunStatus
|
|
58
59
|
from agno.run.cancel import (
|
|
59
60
|
cancel_run as cancel_run_global,
|
|
60
61
|
)
|
|
@@ -94,7 +95,9 @@ from agno.utils.agent import (
|
|
|
94
95
|
scrub_media_from_run_output,
|
|
95
96
|
scrub_tool_results_from_run_output,
|
|
96
97
|
set_session_name_util,
|
|
98
|
+
store_media_util,
|
|
97
99
|
update_session_state_util,
|
|
100
|
+
validate_media_object_id,
|
|
98
101
|
wait_for_background_tasks,
|
|
99
102
|
wait_for_background_tasks_stream,
|
|
100
103
|
)
|
|
@@ -262,9 +265,9 @@ class Agent:
|
|
|
262
265
|
|
|
263
266
|
# --- Agent Hooks ---
|
|
264
267
|
# Functions called right after agent-session is loaded, before processing starts
|
|
265
|
-
pre_hooks: Optional[Union[
|
|
268
|
+
pre_hooks: Optional[List[Union[Callable[..., Any], BaseGuardrail]]] = None
|
|
266
269
|
# Functions called after output is generated but before the response is returned
|
|
267
|
-
post_hooks: Optional[Union[
|
|
270
|
+
post_hooks: Optional[List[Union[Callable[..., Any], BaseGuardrail]]] = None
|
|
268
271
|
|
|
269
272
|
# --- Agent Reasoning ---
|
|
270
273
|
# Enable reasoning by working through the problem step by step.
|
|
@@ -346,7 +349,7 @@ class Agent:
|
|
|
346
349
|
|
|
347
350
|
# --- Agent Response Model Settings ---
|
|
348
351
|
# Provide an input schema to validate the input
|
|
349
|
-
input_schema: Optional[
|
|
352
|
+
input_schema: Optional[Type[BaseModel]] = None
|
|
350
353
|
# Provide a response model to get the response as a Pydantic model
|
|
351
354
|
output_schema: Optional[Type[BaseModel]] = None
|
|
352
355
|
# Provide a secondary model to parse the response from the primary model
|
|
@@ -416,7 +419,7 @@ class Agent:
|
|
|
416
419
|
def __init__(
|
|
417
420
|
self,
|
|
418
421
|
*,
|
|
419
|
-
model: Optional[Model] = None,
|
|
422
|
+
model: Optional[Union[Model, str]] = None,
|
|
420
423
|
name: Optional[str] = None,
|
|
421
424
|
id: Optional[str] = None,
|
|
422
425
|
introduction: Optional[str] = None,
|
|
@@ -457,10 +460,10 @@ class Agent:
|
|
|
457
460
|
tool_call_limit: Optional[int] = None,
|
|
458
461
|
tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
|
|
459
462
|
tool_hooks: Optional[List[Callable]] = None,
|
|
460
|
-
pre_hooks: Optional[Union[
|
|
461
|
-
post_hooks: Optional[Union[
|
|
463
|
+
pre_hooks: Optional[List[Union[Callable[..., Any], BaseGuardrail]]] = None,
|
|
464
|
+
post_hooks: Optional[List[Union[Callable[..., Any], BaseGuardrail]]] = None,
|
|
462
465
|
reasoning: bool = False,
|
|
463
|
-
reasoning_model: Optional[Model] = None,
|
|
466
|
+
reasoning_model: Optional[Union[Model, str]] = None,
|
|
464
467
|
reasoning_agent: Optional[Agent] = None,
|
|
465
468
|
reasoning_min_steps: int = 1,
|
|
466
469
|
reasoning_max_steps: int = 10,
|
|
@@ -488,12 +491,12 @@ class Agent:
|
|
|
488
491
|
retries: int = 0,
|
|
489
492
|
delay_between_retries: int = 1,
|
|
490
493
|
exponential_backoff: bool = False,
|
|
491
|
-
parser_model: Optional[Model] = None,
|
|
494
|
+
parser_model: Optional[Union[Model, str]] = None,
|
|
492
495
|
parser_model_prompt: Optional[str] = None,
|
|
493
|
-
input_schema: Optional[
|
|
496
|
+
input_schema: Optional[Type[BaseModel]] = None,
|
|
494
497
|
output_schema: Optional[Type[BaseModel]] = None,
|
|
495
498
|
parse_response: bool = True,
|
|
496
|
-
output_model: Optional[Model] = None,
|
|
499
|
+
output_model: Optional[Union[Model, str]] = None,
|
|
497
500
|
output_model_prompt: Optional[str] = None,
|
|
498
501
|
structured_outputs: Optional[bool] = None,
|
|
499
502
|
use_json_mode: bool = False,
|
|
@@ -512,7 +515,7 @@ class Agent:
|
|
|
512
515
|
debug_level: Literal[1, 2] = 1,
|
|
513
516
|
telemetry: bool = True,
|
|
514
517
|
):
|
|
515
|
-
self.model = model
|
|
518
|
+
self.model = model # type: ignore[assignment]
|
|
516
519
|
self.name = name
|
|
517
520
|
self.id = id
|
|
518
521
|
self.introduction = introduction
|
|
@@ -578,7 +581,7 @@ class Agent:
|
|
|
578
581
|
self.post_hooks = post_hooks
|
|
579
582
|
|
|
580
583
|
self.reasoning = reasoning
|
|
581
|
-
self.reasoning_model = reasoning_model
|
|
584
|
+
self.reasoning_model = reasoning_model # type: ignore[assignment]
|
|
582
585
|
self.reasoning_agent = reasoning_agent
|
|
583
586
|
self.reasoning_min_steps = reasoning_min_steps
|
|
584
587
|
self.reasoning_max_steps = reasoning_max_steps
|
|
@@ -609,12 +612,12 @@ class Agent:
|
|
|
609
612
|
self.retries = retries
|
|
610
613
|
self.delay_between_retries = delay_between_retries
|
|
611
614
|
self.exponential_backoff = exponential_backoff
|
|
612
|
-
self.parser_model = parser_model
|
|
615
|
+
self.parser_model = parser_model # type: ignore[assignment]
|
|
613
616
|
self.parser_model_prompt = parser_model_prompt
|
|
614
617
|
self.input_schema = input_schema
|
|
615
618
|
self.output_schema = output_schema
|
|
616
619
|
self.parse_response = parse_response
|
|
617
|
-
self.output_model = output_model
|
|
620
|
+
self.output_model = output_model # type: ignore[assignment]
|
|
618
621
|
self.output_model_prompt = output_model_prompt
|
|
619
622
|
|
|
620
623
|
self.structured_outputs = structured_outputs
|
|
@@ -658,6 +661,8 @@ class Agent:
|
|
|
658
661
|
# Lazy-initialized shared thread pool executor for background tasks (memory, cultural knowledge, etc.)
|
|
659
662
|
self._background_executor: Optional[Any] = None
|
|
660
663
|
|
|
664
|
+
self._get_models()
|
|
665
|
+
|
|
661
666
|
@property
|
|
662
667
|
def background_executor(self) -> Any:
|
|
663
668
|
"""Lazy initialization of shared thread pool executor for background tasks.
|
|
@@ -814,6 +819,16 @@ class Agent:
|
|
|
814
819
|
"""Return True if the db the agent is equipped with is an Async implementation"""
|
|
815
820
|
return self.db is not None and isinstance(self.db, AsyncBaseDb)
|
|
816
821
|
|
|
822
|
+
def _get_models(self) -> None:
|
|
823
|
+
if self.model is not None:
|
|
824
|
+
self.model = get_model(self.model)
|
|
825
|
+
if self.reasoning_model is not None:
|
|
826
|
+
self.reasoning_model = get_model(self.reasoning_model)
|
|
827
|
+
if self.parser_model is not None:
|
|
828
|
+
self.parser_model = get_model(self.parser_model)
|
|
829
|
+
if self.output_model is not None:
|
|
830
|
+
self.output_model = get_model(self.output_model)
|
|
831
|
+
|
|
817
832
|
def initialize_agent(self, debug_mode: Optional[bool] = None) -> None:
|
|
818
833
|
self._set_default_model()
|
|
819
834
|
self._set_debug(debug_mode=debug_mode)
|
|
@@ -900,16 +915,13 @@ class Agent:
|
|
|
900
915
|
def _run(
|
|
901
916
|
self,
|
|
902
917
|
run_response: RunOutput,
|
|
918
|
+
run_context: RunContext,
|
|
903
919
|
session: AgentSession,
|
|
904
|
-
session_state: Optional[Dict[str, Any]] = None,
|
|
905
920
|
user_id: Optional[str] = None,
|
|
906
|
-
knowledge_filters: Optional[Dict[str, Any]] = None,
|
|
907
921
|
add_history_to_context: Optional[bool] = None,
|
|
908
922
|
add_dependencies_to_context: Optional[bool] = None,
|
|
909
923
|
add_session_state_to_context: Optional[bool] = None,
|
|
910
|
-
metadata: Optional[Dict[str, Any]] = None,
|
|
911
924
|
response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
|
|
912
|
-
dependencies: Optional[Dict[str, Any]] = None,
|
|
913
925
|
debug_mode: Optional[bool] = None,
|
|
914
926
|
**kwargs: Any,
|
|
915
927
|
) -> RunOutput:
|
|
@@ -943,9 +955,7 @@ class Agent:
|
|
|
943
955
|
hooks=self.pre_hooks, # type: ignore
|
|
944
956
|
run_response=run_response,
|
|
945
957
|
run_input=run_input,
|
|
946
|
-
|
|
947
|
-
dependencies=dependencies,
|
|
948
|
-
metadata=metadata,
|
|
958
|
+
run_context=run_context,
|
|
949
959
|
session=session,
|
|
950
960
|
user_id=user_id,
|
|
951
961
|
debug_mode=debug_mode,
|
|
@@ -957,36 +967,32 @@ class Agent:
|
|
|
957
967
|
# 2. Determine tools for model
|
|
958
968
|
processed_tools = self.get_tools(
|
|
959
969
|
run_response=run_response,
|
|
970
|
+
run_context=run_context,
|
|
960
971
|
session=session,
|
|
961
972
|
user_id=user_id,
|
|
962
|
-
knowledge_filters=knowledge_filters,
|
|
963
973
|
)
|
|
964
974
|
_tools = self._determine_tools_for_model(
|
|
965
975
|
model=self.model,
|
|
966
976
|
processed_tools=processed_tools,
|
|
967
977
|
run_response=run_response,
|
|
968
978
|
session=session,
|
|
969
|
-
|
|
970
|
-
dependencies=dependencies,
|
|
979
|
+
run_context=run_context,
|
|
971
980
|
)
|
|
972
981
|
|
|
973
982
|
# 3. Prepare run messages
|
|
974
983
|
run_messages: RunMessages = self._get_run_messages(
|
|
975
984
|
run_response=run_response,
|
|
985
|
+
run_context=run_context,
|
|
976
986
|
input=run_input.input_content,
|
|
977
987
|
session=session,
|
|
978
|
-
session_state=session_state,
|
|
979
988
|
user_id=user_id,
|
|
980
989
|
audio=run_input.audios,
|
|
981
990
|
images=run_input.images,
|
|
982
991
|
videos=run_input.videos,
|
|
983
992
|
files=run_input.files,
|
|
984
|
-
knowledge_filters=knowledge_filters,
|
|
985
993
|
add_history_to_context=add_history_to_context,
|
|
986
|
-
dependencies=dependencies,
|
|
987
994
|
add_dependencies_to_context=add_dependencies_to_context,
|
|
988
995
|
add_session_state_to_context=add_session_state_to_context,
|
|
989
|
-
metadata=metadata,
|
|
990
996
|
tools=_tools,
|
|
991
997
|
**kwargs,
|
|
992
998
|
)
|
|
@@ -1061,7 +1067,7 @@ class Agent:
|
|
|
1061
1067
|
|
|
1062
1068
|
# 8. Store media if enabled
|
|
1063
1069
|
if self.store_media:
|
|
1064
|
-
|
|
1070
|
+
store_media_util(run_response, model_response)
|
|
1065
1071
|
|
|
1066
1072
|
# 9. Convert the response to the structured format if needed
|
|
1067
1073
|
self._convert_response_to_structured_format(run_response)
|
|
@@ -1071,11 +1077,9 @@ class Agent:
|
|
|
1071
1077
|
post_hook_iterator = self._execute_post_hooks(
|
|
1072
1078
|
hooks=self.post_hooks, # type: ignore
|
|
1073
1079
|
run_output=run_response,
|
|
1080
|
+
run_context=run_context,
|
|
1074
1081
|
session=session,
|
|
1075
1082
|
user_id=user_id,
|
|
1076
|
-
session_state=session_state,
|
|
1077
|
-
dependencies=dependencies,
|
|
1078
|
-
metadata=metadata,
|
|
1079
1083
|
debug_mode=debug_mode,
|
|
1080
1084
|
**kwargs,
|
|
1081
1085
|
)
|
|
@@ -1099,7 +1103,9 @@ class Agent:
|
|
|
1099
1103
|
run_response.status = RunStatus.completed
|
|
1100
1104
|
|
|
1101
1105
|
# 13. Cleanup and store the run response and session
|
|
1102
|
-
self._cleanup_and_store(
|
|
1106
|
+
self._cleanup_and_store(
|
|
1107
|
+
run_response=run_response, session=session, run_context=run_context, user_id=user_id
|
|
1108
|
+
)
|
|
1103
1109
|
|
|
1104
1110
|
# Log Agent Telemetry
|
|
1105
1111
|
self._log_agent_telemetry(session_id=session.session_id, run_id=run_response.run_id)
|
|
@@ -1114,7 +1120,9 @@ class Agent:
|
|
|
1114
1120
|
run_response.status = RunStatus.cancelled
|
|
1115
1121
|
|
|
1116
1122
|
# Cleanup and store the run response and session
|
|
1117
|
-
self._cleanup_and_store(
|
|
1123
|
+
self._cleanup_and_store(
|
|
1124
|
+
run_response=run_response, session=session, run_context=run_context, user_id=user_id
|
|
1125
|
+
)
|
|
1118
1126
|
|
|
1119
1127
|
return run_response
|
|
1120
1128
|
finally:
|
|
@@ -1124,15 +1132,12 @@ class Agent:
|
|
|
1124
1132
|
def _run_stream(
|
|
1125
1133
|
self,
|
|
1126
1134
|
run_response: RunOutput,
|
|
1135
|
+
run_context: RunContext,
|
|
1127
1136
|
session: AgentSession,
|
|
1128
|
-
session_state: Optional[Dict[str, Any]] = None,
|
|
1129
1137
|
user_id: Optional[str] = None,
|
|
1130
|
-
knowledge_filters: Optional[Dict[str, Any]] = None,
|
|
1131
1138
|
add_history_to_context: Optional[bool] = None,
|
|
1132
1139
|
add_dependencies_to_context: Optional[bool] = None,
|
|
1133
1140
|
add_session_state_to_context: Optional[bool] = None,
|
|
1134
|
-
metadata: Optional[Dict[str, Any]] = None,
|
|
1135
|
-
dependencies: Optional[Dict[str, Any]] = None,
|
|
1136
1141
|
response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
|
|
1137
1142
|
stream_events: bool = False,
|
|
1138
1143
|
yield_run_response: bool = False,
|
|
@@ -1166,9 +1171,7 @@ class Agent:
|
|
|
1166
1171
|
hooks=self.pre_hooks, # type: ignore
|
|
1167
1172
|
run_response=run_response,
|
|
1168
1173
|
run_input=run_input,
|
|
1169
|
-
|
|
1170
|
-
dependencies=dependencies,
|
|
1171
|
-
metadata=metadata,
|
|
1174
|
+
run_context=run_context,
|
|
1172
1175
|
session=session,
|
|
1173
1176
|
user_id=user_id,
|
|
1174
1177
|
debug_mode=debug_mode,
|
|
@@ -1180,17 +1183,16 @@ class Agent:
|
|
|
1180
1183
|
# 2. Determine tools for model
|
|
1181
1184
|
processed_tools = self.get_tools(
|
|
1182
1185
|
run_response=run_response,
|
|
1186
|
+
run_context=run_context,
|
|
1183
1187
|
session=session,
|
|
1184
1188
|
user_id=user_id,
|
|
1185
|
-
knowledge_filters=knowledge_filters,
|
|
1186
1189
|
)
|
|
1187
1190
|
_tools = self._determine_tools_for_model(
|
|
1188
1191
|
model=self.model,
|
|
1189
1192
|
processed_tools=processed_tools,
|
|
1190
1193
|
run_response=run_response,
|
|
1191
1194
|
session=session,
|
|
1192
|
-
|
|
1193
|
-
dependencies=dependencies,
|
|
1195
|
+
run_context=run_context,
|
|
1194
1196
|
)
|
|
1195
1197
|
|
|
1196
1198
|
# 3. Prepare run messages
|
|
@@ -1198,18 +1200,15 @@ class Agent:
|
|
|
1198
1200
|
run_response=run_response,
|
|
1199
1201
|
input=run_input.input_content,
|
|
1200
1202
|
session=session,
|
|
1201
|
-
|
|
1203
|
+
run_context=run_context,
|
|
1202
1204
|
user_id=user_id,
|
|
1203
1205
|
audio=run_input.audios,
|
|
1204
1206
|
images=run_input.images,
|
|
1205
1207
|
videos=run_input.videos,
|
|
1206
1208
|
files=run_input.files,
|
|
1207
|
-
knowledge_filters=knowledge_filters,
|
|
1208
1209
|
add_history_to_context=add_history_to_context,
|
|
1209
|
-
dependencies=dependencies,
|
|
1210
1210
|
add_dependencies_to_context=add_dependencies_to_context,
|
|
1211
1211
|
add_session_state_to_context=add_session_state_to_context,
|
|
1212
|
-
metadata=metadata,
|
|
1213
1212
|
tools=_tools,
|
|
1214
1213
|
**kwargs,
|
|
1215
1214
|
)
|
|
@@ -1268,6 +1267,7 @@ class Agent:
|
|
|
1268
1267
|
tools=_tools,
|
|
1269
1268
|
response_format=response_format,
|
|
1270
1269
|
stream_events=stream_events,
|
|
1270
|
+
session_state=run_context.session_state,
|
|
1271
1271
|
):
|
|
1272
1272
|
raise_if_cancelled(run_response.run_id) # type: ignore
|
|
1273
1273
|
yield event
|
|
@@ -1284,6 +1284,7 @@ class Agent:
|
|
|
1284
1284
|
tools=_tools,
|
|
1285
1285
|
response_format=response_format,
|
|
1286
1286
|
stream_events=stream_events,
|
|
1287
|
+
session_state=run_context.session_state,
|
|
1287
1288
|
):
|
|
1288
1289
|
raise_if_cancelled(run_response.run_id) # type: ignore
|
|
1289
1290
|
if isinstance(event, RunContentEvent):
|
|
@@ -1303,7 +1304,7 @@ class Agent:
|
|
|
1303
1304
|
stream_events=stream_events,
|
|
1304
1305
|
):
|
|
1305
1306
|
raise_if_cancelled(run_response.run_id) # type: ignore
|
|
1306
|
-
yield event
|
|
1307
|
+
yield event # type: ignore
|
|
1307
1308
|
|
|
1308
1309
|
# Check for cancellation after model processing
|
|
1309
1310
|
raise_if_cancelled(run_response.run_id) # type: ignore
|
|
@@ -1344,9 +1345,7 @@ class Agent:
|
|
|
1344
1345
|
yield from self._execute_post_hooks(
|
|
1345
1346
|
hooks=self.post_hooks, # type: ignore
|
|
1346
1347
|
run_output=run_response,
|
|
1347
|
-
|
|
1348
|
-
dependencies=dependencies,
|
|
1349
|
-
metadata=metadata,
|
|
1348
|
+
run_context=run_context,
|
|
1350
1349
|
session=session,
|
|
1351
1350
|
user_id=user_id,
|
|
1352
1351
|
debug_mode=debug_mode,
|
|
@@ -1387,6 +1386,11 @@ class Agent:
|
|
|
1387
1386
|
store_events=self.store_events,
|
|
1388
1387
|
)
|
|
1389
1388
|
|
|
1389
|
+
# Update run_response.session_state before creating RunCompletedEvent
|
|
1390
|
+
# This ensures the event has the final state after all tool modifications
|
|
1391
|
+
if session.session_data is not None and "session_state" in session.session_data:
|
|
1392
|
+
run_response.session_state = session.session_data["session_state"]
|
|
1393
|
+
|
|
1390
1394
|
# Create the run completed event
|
|
1391
1395
|
completed_event = handle_event( # type: ignore
|
|
1392
1396
|
create_run_completed_event(from_run_response=run_response),
|
|
@@ -1399,7 +1403,9 @@ class Agent:
|
|
|
1399
1403
|
run_response.status = RunStatus.completed
|
|
1400
1404
|
|
|
1401
1405
|
# 10. Cleanup and store the run response and session
|
|
1402
|
-
self._cleanup_and_store(
|
|
1406
|
+
self._cleanup_and_store(
|
|
1407
|
+
run_response=run_response, session=session, run_context=run_context, user_id=user_id
|
|
1408
|
+
)
|
|
1403
1409
|
|
|
1404
1410
|
if stream_events:
|
|
1405
1411
|
yield completed_event # type: ignore
|
|
@@ -1430,7 +1436,9 @@ class Agent:
|
|
|
1430
1436
|
)
|
|
1431
1437
|
|
|
1432
1438
|
# Cleanup and store the run response and session
|
|
1433
|
-
self._cleanup_and_store(
|
|
1439
|
+
self._cleanup_and_store(
|
|
1440
|
+
run_response=run_response, session=session, run_context=run_context, user_id=user_id
|
|
1441
|
+
)
|
|
1434
1442
|
finally:
|
|
1435
1443
|
# Always clean up the run tracking
|
|
1436
1444
|
cleanup_run(run_response.run_id) # type: ignore
|
|
@@ -1533,9 +1541,9 @@ class Agent:
|
|
|
1533
1541
|
# Normalise hook & guardails
|
|
1534
1542
|
if not self._hooks_normalised:
|
|
1535
1543
|
if self.pre_hooks:
|
|
1536
|
-
self.pre_hooks = normalize_hooks(self.pre_hooks)
|
|
1544
|
+
self.pre_hooks = normalize_hooks(self.pre_hooks) # type: ignore
|
|
1537
1545
|
if self.post_hooks:
|
|
1538
|
-
self.post_hooks = normalize_hooks(self.post_hooks)
|
|
1546
|
+
self.post_hooks = normalize_hooks(self.post_hooks) # type: ignore
|
|
1539
1547
|
self._hooks_normalised = True
|
|
1540
1548
|
|
|
1541
1549
|
session_id, user_id = self._initialize_session(session_id=session_id, user_id=user_id)
|
|
@@ -1543,7 +1551,7 @@ class Agent:
|
|
|
1543
1551
|
# Initialize the Agent
|
|
1544
1552
|
self.initialize_agent(debug_mode=debug_mode)
|
|
1545
1553
|
|
|
1546
|
-
image_artifacts, video_artifacts, audio_artifacts, file_artifacts =
|
|
1554
|
+
image_artifacts, video_artifacts, audio_artifacts, file_artifacts = validate_media_object_id(
|
|
1547
1555
|
images=images, videos=videos, audios=audio, files=files
|
|
1548
1556
|
)
|
|
1549
1557
|
|
|
@@ -1566,12 +1574,22 @@ class Agent:
|
|
|
1566
1574
|
)
|
|
1567
1575
|
# Update session state from DB
|
|
1568
1576
|
session_state = self._load_session_state(session=agent_session, session_state=session_state)
|
|
1577
|
+
|
|
1569
1578
|
# Determine runtime dependencies
|
|
1570
|
-
|
|
1579
|
+
dependencies = dependencies if dependencies is not None else self.dependencies
|
|
1580
|
+
|
|
1581
|
+
# Initialize run context
|
|
1582
|
+
run_context = RunContext(
|
|
1583
|
+
run_id=run_id,
|
|
1584
|
+
session_id=session_id,
|
|
1585
|
+
user_id=user_id,
|
|
1586
|
+
session_state=session_state,
|
|
1587
|
+
dependencies=dependencies,
|
|
1588
|
+
)
|
|
1571
1589
|
|
|
1572
1590
|
# Resolve dependencies
|
|
1573
|
-
if
|
|
1574
|
-
self._resolve_run_dependencies(
|
|
1591
|
+
if run_context.dependencies is not None:
|
|
1592
|
+
self._resolve_run_dependencies(run_context=run_context)
|
|
1575
1593
|
|
|
1576
1594
|
add_dependencies = (
|
|
1577
1595
|
add_dependencies_to_context if add_dependencies_to_context is not None else self.add_dependencies_to_context
|
|
@@ -1583,12 +1601,9 @@ class Agent:
|
|
|
1583
1601
|
)
|
|
1584
1602
|
add_history = add_history_to_context if add_history_to_context is not None else self.add_history_to_context
|
|
1585
1603
|
|
|
1586
|
-
# Initialize Knowledge Filters
|
|
1587
|
-
effective_filters = knowledge_filters
|
|
1588
|
-
|
|
1589
1604
|
# When filters are passed manually
|
|
1590
1605
|
if self.knowledge_filters or knowledge_filters:
|
|
1591
|
-
|
|
1606
|
+
run_context.knowledge_filters = self._get_effective_filters(knowledge_filters)
|
|
1592
1607
|
|
|
1593
1608
|
# Use stream override value when necessary
|
|
1594
1609
|
if stream is None:
|
|
@@ -1612,11 +1627,8 @@ class Agent:
|
|
|
1612
1627
|
self.model = cast(Model, self.model)
|
|
1613
1628
|
|
|
1614
1629
|
# Merge agent metadata with run metadata
|
|
1615
|
-
if self.metadata is not None:
|
|
1616
|
-
|
|
1617
|
-
metadata = self.metadata
|
|
1618
|
-
else:
|
|
1619
|
-
merge_dictionaries(metadata, self.metadata)
|
|
1630
|
+
if self.metadata is not None and metadata is not None:
|
|
1631
|
+
merge_dictionaries(metadata, self.metadata)
|
|
1620
1632
|
|
|
1621
1633
|
# Create a new run_response for this attempt
|
|
1622
1634
|
run_response = RunOutput(
|
|
@@ -1625,7 +1637,8 @@ class Agent:
|
|
|
1625
1637
|
agent_id=self.id,
|
|
1626
1638
|
user_id=user_id,
|
|
1627
1639
|
agent_name=self.name,
|
|
1628
|
-
metadata=metadata,
|
|
1640
|
+
metadata=run_context.metadata,
|
|
1641
|
+
session_state=run_context.session_state,
|
|
1629
1642
|
input=run_input,
|
|
1630
1643
|
)
|
|
1631
1644
|
|
|
@@ -1647,15 +1660,12 @@ class Agent:
|
|
|
1647
1660
|
if stream:
|
|
1648
1661
|
response_iterator = self._run_stream(
|
|
1649
1662
|
run_response=run_response,
|
|
1663
|
+
run_context=run_context,
|
|
1650
1664
|
session=agent_session,
|
|
1651
|
-
session_state=session_state,
|
|
1652
1665
|
user_id=user_id,
|
|
1653
|
-
knowledge_filters=effective_filters,
|
|
1654
1666
|
add_history_to_context=add_history,
|
|
1655
1667
|
add_dependencies_to_context=add_dependencies,
|
|
1656
1668
|
add_session_state_to_context=add_session_state,
|
|
1657
|
-
metadata=metadata,
|
|
1658
|
-
dependencies=run_dependencies,
|
|
1659
1669
|
response_format=response_format,
|
|
1660
1670
|
stream_events=stream_events,
|
|
1661
1671
|
yield_run_response=yield_run_response,
|
|
@@ -1666,15 +1676,12 @@ class Agent:
|
|
|
1666
1676
|
else:
|
|
1667
1677
|
response = self._run(
|
|
1668
1678
|
run_response=run_response,
|
|
1679
|
+
run_context=run_context,
|
|
1669
1680
|
session=agent_session,
|
|
1670
|
-
session_state=session_state,
|
|
1671
1681
|
user_id=user_id,
|
|
1672
|
-
knowledge_filters=effective_filters,
|
|
1673
1682
|
add_history_to_context=add_history,
|
|
1674
1683
|
add_dependencies_to_context=add_dependencies,
|
|
1675
1684
|
add_session_state_to_context=add_session_state,
|
|
1676
|
-
metadata=metadata,
|
|
1677
|
-
dependencies=run_dependencies,
|
|
1678
1685
|
response_format=response_format,
|
|
1679
1686
|
debug_mode=debug_mode,
|
|
1680
1687
|
**kwargs,
|
|
@@ -1727,16 +1734,13 @@ class Agent:
|
|
|
1727
1734
|
async def _arun(
|
|
1728
1735
|
self,
|
|
1729
1736
|
run_response: RunOutput,
|
|
1737
|
+
run_context: RunContext,
|
|
1730
1738
|
session_id: str,
|
|
1731
|
-
session_state: Optional[Dict[str, Any]] = None,
|
|
1732
1739
|
user_id: Optional[str] = None,
|
|
1733
|
-
knowledge_filters: Optional[Dict[str, Any]] = None,
|
|
1734
1740
|
add_history_to_context: Optional[bool] = None,
|
|
1735
1741
|
add_dependencies_to_context: Optional[bool] = None,
|
|
1736
1742
|
add_session_state_to_context: Optional[bool] = None,
|
|
1737
|
-
metadata: Optional[Dict[str, Any]] = None,
|
|
1738
1743
|
response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
|
|
1739
|
-
dependencies: Optional[Dict[str, Any]] = None,
|
|
1740
1744
|
debug_mode: Optional[bool] = None,
|
|
1741
1745
|
**kwargs: Any,
|
|
1742
1746
|
) -> RunOutput:
|
|
@@ -1771,16 +1775,21 @@ class Agent:
|
|
|
1771
1775
|
# 2. Update metadata and session state
|
|
1772
1776
|
self._update_metadata(session=agent_session)
|
|
1773
1777
|
# Initialize session state
|
|
1774
|
-
session_state = self._initialize_session_state(
|
|
1775
|
-
session_state=session_state or {},
|
|
1778
|
+
run_context.session_state = self._initialize_session_state(
|
|
1779
|
+
session_state=run_context.session_state or {},
|
|
1780
|
+
user_id=user_id,
|
|
1781
|
+
session_id=session_id,
|
|
1782
|
+
run_id=run_response.run_id,
|
|
1776
1783
|
)
|
|
1777
1784
|
# Update session state from DB
|
|
1778
|
-
if session_state is not None:
|
|
1779
|
-
session_state = self._load_session_state(
|
|
1785
|
+
if run_context.session_state is not None:
|
|
1786
|
+
run_context.session_state = self._load_session_state(
|
|
1787
|
+
session=agent_session, session_state=run_context.session_state
|
|
1788
|
+
)
|
|
1780
1789
|
|
|
1781
1790
|
# 3. Resolve dependencies
|
|
1782
|
-
if dependencies is not None:
|
|
1783
|
-
await self._aresolve_run_dependencies(
|
|
1791
|
+
if run_context.dependencies is not None:
|
|
1792
|
+
await self._aresolve_run_dependencies(run_context=run_context)
|
|
1784
1793
|
|
|
1785
1794
|
# 4. Execute pre-hooks
|
|
1786
1795
|
run_input = cast(RunInput, run_response.input)
|
|
@@ -1790,10 +1799,8 @@ class Agent:
|
|
|
1790
1799
|
pre_hook_iterator = self._aexecute_pre_hooks(
|
|
1791
1800
|
hooks=self.pre_hooks, # type: ignore
|
|
1792
1801
|
run_response=run_response,
|
|
1802
|
+
run_context=run_context,
|
|
1793
1803
|
run_input=run_input,
|
|
1794
|
-
session_state=session_state,
|
|
1795
|
-
dependencies=dependencies,
|
|
1796
|
-
metadata=metadata,
|
|
1797
1804
|
session=agent_session,
|
|
1798
1805
|
user_id=user_id,
|
|
1799
1806
|
debug_mode=debug_mode,
|
|
@@ -1807,36 +1814,33 @@ class Agent:
|
|
|
1807
1814
|
self.model = cast(Model, self.model)
|
|
1808
1815
|
processed_tools = await self.aget_tools(
|
|
1809
1816
|
run_response=run_response,
|
|
1817
|
+
run_context=run_context,
|
|
1810
1818
|
session=agent_session,
|
|
1811
1819
|
user_id=user_id,
|
|
1812
|
-
knowledge_filters=knowledge_filters,
|
|
1813
1820
|
)
|
|
1821
|
+
|
|
1814
1822
|
_tools = self._determine_tools_for_model(
|
|
1815
1823
|
model=self.model,
|
|
1816
1824
|
processed_tools=processed_tools,
|
|
1817
1825
|
run_response=run_response,
|
|
1826
|
+
run_context=run_context,
|
|
1818
1827
|
session=agent_session,
|
|
1819
|
-
session_state=session_state,
|
|
1820
|
-
dependencies=dependencies,
|
|
1821
1828
|
)
|
|
1822
1829
|
|
|
1823
1830
|
# 6. Prepare run messages
|
|
1824
1831
|
run_messages: RunMessages = await self._aget_run_messages(
|
|
1825
1832
|
run_response=run_response,
|
|
1833
|
+
run_context=run_context,
|
|
1826
1834
|
input=run_input.input_content,
|
|
1827
1835
|
session=agent_session,
|
|
1828
|
-
session_state=session_state,
|
|
1829
1836
|
user_id=user_id,
|
|
1830
1837
|
audio=run_input.audios,
|
|
1831
1838
|
images=run_input.images,
|
|
1832
1839
|
videos=run_input.videos,
|
|
1833
1840
|
files=run_input.files,
|
|
1834
|
-
knowledge_filters=knowledge_filters,
|
|
1835
1841
|
add_history_to_context=add_history_to_context,
|
|
1836
|
-
dependencies=dependencies,
|
|
1837
1842
|
add_dependencies_to_context=add_dependencies_to_context,
|
|
1838
1843
|
add_session_state_to_context=add_session_state_to_context,
|
|
1839
|
-
metadata=metadata,
|
|
1840
1844
|
tools=_tools,
|
|
1841
1845
|
**kwargs,
|
|
1842
1846
|
)
|
|
@@ -1877,6 +1881,7 @@ class Agent:
|
|
|
1877
1881
|
tool_call_limit=self.tool_call_limit,
|
|
1878
1882
|
response_format=response_format,
|
|
1879
1883
|
send_media_to_model=self.send_media_to_model,
|
|
1884
|
+
run_response=run_response,
|
|
1880
1885
|
)
|
|
1881
1886
|
|
|
1882
1887
|
# Check for cancellation after model call
|
|
@@ -1909,16 +1914,14 @@ class Agent:
|
|
|
1909
1914
|
|
|
1910
1915
|
# 12. Store media if enabled
|
|
1911
1916
|
if self.store_media:
|
|
1912
|
-
|
|
1917
|
+
store_media_util(run_response, model_response)
|
|
1913
1918
|
|
|
1914
1919
|
# 13. Execute post-hooks (after output is generated but before response is returned)
|
|
1915
1920
|
if self.post_hooks is not None:
|
|
1916
1921
|
async for _ in self._aexecute_post_hooks(
|
|
1917
1922
|
hooks=self.post_hooks, # type: ignore
|
|
1918
1923
|
run_output=run_response,
|
|
1919
|
-
|
|
1920
|
-
dependencies=dependencies,
|
|
1921
|
-
metadata=metadata,
|
|
1924
|
+
run_context=run_context,
|
|
1922
1925
|
session=agent_session,
|
|
1923
1926
|
user_id=user_id,
|
|
1924
1927
|
debug_mode=debug_mode,
|
|
@@ -1944,7 +1947,12 @@ class Agent:
|
|
|
1944
1947
|
run_response.status = RunStatus.completed
|
|
1945
1948
|
|
|
1946
1949
|
# 16. Cleanup and store the run response and session
|
|
1947
|
-
await self._acleanup_and_store(
|
|
1950
|
+
await self._acleanup_and_store(
|
|
1951
|
+
run_response=run_response,
|
|
1952
|
+
session=agent_session,
|
|
1953
|
+
run_context=run_context,
|
|
1954
|
+
user_id=user_id,
|
|
1955
|
+
)
|
|
1948
1956
|
|
|
1949
1957
|
# Log Agent Telemetry
|
|
1950
1958
|
await self._alog_agent_telemetry(session_id=agent_session.session_id, run_id=run_response.run_id)
|
|
@@ -1960,7 +1968,12 @@ class Agent:
|
|
|
1960
1968
|
run_response.status = RunStatus.cancelled
|
|
1961
1969
|
|
|
1962
1970
|
# Cleanup and store the run response and session
|
|
1963
|
-
await self._acleanup_and_store(
|
|
1971
|
+
await self._acleanup_and_store(
|
|
1972
|
+
run_response=run_response,
|
|
1973
|
+
session=agent_session,
|
|
1974
|
+
run_context=run_context,
|
|
1975
|
+
user_id=user_id,
|
|
1976
|
+
)
|
|
1964
1977
|
|
|
1965
1978
|
return run_response
|
|
1966
1979
|
|
|
@@ -1988,15 +2001,12 @@ class Agent:
|
|
|
1988
2001
|
async def _arun_stream(
|
|
1989
2002
|
self,
|
|
1990
2003
|
run_response: RunOutput,
|
|
2004
|
+
run_context: RunContext,
|
|
1991
2005
|
session_id: str,
|
|
1992
|
-
session_state: Optional[Dict[str, Any]] = None,
|
|
1993
2006
|
user_id: Optional[str] = None,
|
|
1994
|
-
knowledge_filters: Optional[Dict[str, Any]] = None,
|
|
1995
|
-
dependencies: Optional[Dict[str, Any]] = None,
|
|
1996
2007
|
add_history_to_context: Optional[bool] = None,
|
|
1997
2008
|
add_dependencies_to_context: Optional[bool] = None,
|
|
1998
2009
|
add_session_state_to_context: Optional[bool] = None,
|
|
1999
|
-
metadata: Optional[Dict[str, Any]] = None,
|
|
2000
2010
|
response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
|
|
2001
2011
|
stream_events: bool = False,
|
|
2002
2012
|
yield_run_response: Optional[bool] = None,
|
|
@@ -2037,16 +2047,21 @@ class Agent:
|
|
|
2037
2047
|
# 2. Update metadata and session state
|
|
2038
2048
|
self._update_metadata(session=agent_session)
|
|
2039
2049
|
# Initialize session state
|
|
2040
|
-
session_state = self._initialize_session_state(
|
|
2041
|
-
session_state=session_state or {},
|
|
2050
|
+
run_context.session_state = self._initialize_session_state(
|
|
2051
|
+
session_state=run_context.session_state or {},
|
|
2052
|
+
user_id=user_id,
|
|
2053
|
+
session_id=session_id,
|
|
2054
|
+
run_id=run_response.run_id,
|
|
2042
2055
|
)
|
|
2043
2056
|
# Update session state from DB
|
|
2044
|
-
if session_state is not None:
|
|
2045
|
-
session_state = self._load_session_state(
|
|
2057
|
+
if run_context.session_state is not None:
|
|
2058
|
+
run_context.session_state = self._load_session_state(
|
|
2059
|
+
session=agent_session, session_state=run_context.session_state
|
|
2060
|
+
)
|
|
2046
2061
|
|
|
2047
2062
|
# 3. Resolve dependencies
|
|
2048
|
-
if dependencies is not None:
|
|
2049
|
-
await self._aresolve_run_dependencies(
|
|
2063
|
+
if run_context.dependencies is not None:
|
|
2064
|
+
await self._aresolve_run_dependencies(run_context=run_context)
|
|
2050
2065
|
|
|
2051
2066
|
# 4. Execute pre-hooks
|
|
2052
2067
|
run_input = cast(RunInput, run_response.input)
|
|
@@ -2056,11 +2071,9 @@ class Agent:
|
|
|
2056
2071
|
pre_hook_iterator = self._aexecute_pre_hooks(
|
|
2057
2072
|
hooks=self.pre_hooks, # type: ignore
|
|
2058
2073
|
run_response=run_response,
|
|
2074
|
+
run_context=run_context,
|
|
2059
2075
|
run_input=run_input,
|
|
2060
2076
|
session=agent_session,
|
|
2061
|
-
session_state=session_state,
|
|
2062
|
-
dependencies=dependencies,
|
|
2063
|
-
metadata=metadata,
|
|
2064
2077
|
user_id=user_id,
|
|
2065
2078
|
debug_mode=debug_mode,
|
|
2066
2079
|
**kwargs,
|
|
@@ -2072,36 +2085,33 @@ class Agent:
|
|
|
2072
2085
|
self.model = cast(Model, self.model)
|
|
2073
2086
|
processed_tools = await self.aget_tools(
|
|
2074
2087
|
run_response=run_response,
|
|
2088
|
+
run_context=run_context,
|
|
2075
2089
|
session=agent_session,
|
|
2076
2090
|
user_id=user_id,
|
|
2077
|
-
knowledge_filters=knowledge_filters,
|
|
2078
2091
|
)
|
|
2092
|
+
|
|
2079
2093
|
_tools = self._determine_tools_for_model(
|
|
2080
2094
|
model=self.model,
|
|
2081
2095
|
processed_tools=processed_tools,
|
|
2082
2096
|
run_response=run_response,
|
|
2097
|
+
run_context=run_context,
|
|
2083
2098
|
session=agent_session,
|
|
2084
|
-
session_state=session_state,
|
|
2085
|
-
dependencies=dependencies,
|
|
2086
2099
|
)
|
|
2087
2100
|
|
|
2088
2101
|
# 6. Prepare run messages
|
|
2089
2102
|
run_messages: RunMessages = await self._aget_run_messages(
|
|
2090
2103
|
run_response=run_response,
|
|
2104
|
+
run_context=run_context,
|
|
2091
2105
|
input=run_input.input_content,
|
|
2092
2106
|
session=agent_session,
|
|
2093
|
-
session_state=session_state,
|
|
2094
2107
|
user_id=user_id,
|
|
2095
2108
|
audio=run_input.audios,
|
|
2096
2109
|
images=run_input.images,
|
|
2097
2110
|
videos=run_input.videos,
|
|
2098
2111
|
files=run_input.files,
|
|
2099
|
-
knowledge_filters=knowledge_filters,
|
|
2100
2112
|
add_history_to_context=add_history_to_context,
|
|
2101
|
-
dependencies=dependencies,
|
|
2102
2113
|
add_dependencies_to_context=add_dependencies_to_context,
|
|
2103
2114
|
add_session_state_to_context=add_session_state_to_context,
|
|
2104
|
-
metadata=metadata,
|
|
2105
2115
|
tools=_tools,
|
|
2106
2116
|
**kwargs,
|
|
2107
2117
|
)
|
|
@@ -2148,6 +2158,7 @@ class Agent:
|
|
|
2148
2158
|
tools=_tools,
|
|
2149
2159
|
response_format=response_format,
|
|
2150
2160
|
stream_events=stream_events,
|
|
2161
|
+
session_state=run_context.session_state,
|
|
2151
2162
|
):
|
|
2152
2163
|
raise_if_cancelled(run_response.run_id) # type: ignore
|
|
2153
2164
|
yield event
|
|
@@ -2164,6 +2175,7 @@ class Agent:
|
|
|
2164
2175
|
tools=_tools,
|
|
2165
2176
|
response_format=response_format,
|
|
2166
2177
|
stream_events=stream_events,
|
|
2178
|
+
session_state=run_context.session_state,
|
|
2167
2179
|
):
|
|
2168
2180
|
raise_if_cancelled(run_response.run_id) # type: ignore
|
|
2169
2181
|
if isinstance(event, RunContentEvent):
|
|
@@ -2223,9 +2235,7 @@ class Agent:
|
|
|
2223
2235
|
async for event in self._aexecute_post_hooks(
|
|
2224
2236
|
hooks=self.post_hooks, # type: ignore
|
|
2225
2237
|
run_output=run_response,
|
|
2226
|
-
|
|
2227
|
-
dependencies=dependencies,
|
|
2228
|
-
metadata=metadata,
|
|
2238
|
+
run_context=run_context,
|
|
2229
2239
|
session=agent_session,
|
|
2230
2240
|
user_id=user_id,
|
|
2231
2241
|
debug_mode=debug_mode,
|
|
@@ -2270,6 +2280,11 @@ class Agent:
|
|
|
2270
2280
|
store_events=self.store_events,
|
|
2271
2281
|
)
|
|
2272
2282
|
|
|
2283
|
+
# Update run_response.session_state before creating RunCompletedEvent
|
|
2284
|
+
# This ensures the event has the final state after all tool modifications
|
|
2285
|
+
if agent_session.session_data is not None and "session_state" in agent_session.session_data:
|
|
2286
|
+
run_response.session_state = agent_session.session_data["session_state"]
|
|
2287
|
+
|
|
2273
2288
|
# Create the run completed event
|
|
2274
2289
|
completed_event = handle_event(
|
|
2275
2290
|
create_run_completed_event(from_run_response=run_response),
|
|
@@ -2282,7 +2297,12 @@ class Agent:
|
|
|
2282
2297
|
run_response.status = RunStatus.completed
|
|
2283
2298
|
|
|
2284
2299
|
# 13. Cleanup and store the run response and session
|
|
2285
|
-
await self._acleanup_and_store(
|
|
2300
|
+
await self._acleanup_and_store(
|
|
2301
|
+
run_response=run_response,
|
|
2302
|
+
session=agent_session,
|
|
2303
|
+
run_context=run_context,
|
|
2304
|
+
user_id=user_id,
|
|
2305
|
+
)
|
|
2286
2306
|
|
|
2287
2307
|
if stream_events:
|
|
2288
2308
|
yield completed_event # type: ignore
|
|
@@ -2313,7 +2333,12 @@ class Agent:
|
|
|
2313
2333
|
)
|
|
2314
2334
|
|
|
2315
2335
|
# Cleanup and store the run response and session
|
|
2316
|
-
await self._acleanup_and_store(
|
|
2336
|
+
await self._acleanup_and_store(
|
|
2337
|
+
run_response=run_response,
|
|
2338
|
+
session=agent_session,
|
|
2339
|
+
run_context=run_context,
|
|
2340
|
+
user_id=user_id,
|
|
2341
|
+
)
|
|
2317
2342
|
finally:
|
|
2318
2343
|
# Always disconnect MCP tools
|
|
2319
2344
|
await self._disconnect_mcp_tools()
|
|
@@ -2426,12 +2451,12 @@ class Agent:
|
|
|
2426
2451
|
# 2. Validate input against input_schema if provided
|
|
2427
2452
|
validated_input = self._validate_input(input)
|
|
2428
2453
|
|
|
2429
|
-
# Normalise
|
|
2454
|
+
# Normalise hooks & guardails
|
|
2430
2455
|
if not self._hooks_normalised:
|
|
2431
2456
|
if self.pre_hooks:
|
|
2432
|
-
self.pre_hooks = normalize_hooks(self.pre_hooks, async_mode=True)
|
|
2457
|
+
self.pre_hooks = normalize_hooks(self.pre_hooks, async_mode=True) # type: ignore
|
|
2433
2458
|
if self.post_hooks:
|
|
2434
|
-
self.post_hooks = normalize_hooks(self.post_hooks, async_mode=True)
|
|
2459
|
+
self.post_hooks = normalize_hooks(self.post_hooks, async_mode=True) # type: ignore
|
|
2435
2460
|
self._hooks_normalised = True
|
|
2436
2461
|
|
|
2437
2462
|
# Initialize session
|
|
@@ -2440,12 +2465,12 @@ class Agent:
|
|
|
2440
2465
|
# Initialize the Agent
|
|
2441
2466
|
self.initialize_agent(debug_mode=debug_mode)
|
|
2442
2467
|
|
|
2443
|
-
image_artifacts, video_artifacts, audio_artifacts, file_artifacts =
|
|
2468
|
+
image_artifacts, video_artifacts, audio_artifacts, file_artifacts = validate_media_object_id(
|
|
2444
2469
|
images=images, videos=videos, audios=audio, files=files
|
|
2445
2470
|
)
|
|
2446
2471
|
|
|
2447
2472
|
# Resolve variables
|
|
2448
|
-
|
|
2473
|
+
dependencies = dependencies if dependencies is not None else self.dependencies
|
|
2449
2474
|
add_dependencies = (
|
|
2450
2475
|
add_dependencies_to_context if add_dependencies_to_context is not None else self.add_dependencies_to_context
|
|
2451
2476
|
)
|
|
@@ -2487,9 +2512,9 @@ class Agent:
|
|
|
2487
2512
|
self.model = cast(Model, self.model)
|
|
2488
2513
|
|
|
2489
2514
|
# Get knowledge filters
|
|
2490
|
-
|
|
2515
|
+
knowledge_filters = knowledge_filters
|
|
2491
2516
|
if self.knowledge_filters or knowledge_filters:
|
|
2492
|
-
|
|
2517
|
+
knowledge_filters = self._get_effective_filters(knowledge_filters)
|
|
2493
2518
|
|
|
2494
2519
|
# Merge agent metadata with run metadata
|
|
2495
2520
|
if self.metadata is not None:
|
|
@@ -2498,6 +2523,17 @@ class Agent:
|
|
|
2498
2523
|
else:
|
|
2499
2524
|
merge_dictionaries(metadata, self.metadata)
|
|
2500
2525
|
|
|
2526
|
+
# Initialize run context
|
|
2527
|
+
run_context = RunContext(
|
|
2528
|
+
run_id=run_id,
|
|
2529
|
+
session_id=session_id,
|
|
2530
|
+
user_id=user_id,
|
|
2531
|
+
session_state=session_state,
|
|
2532
|
+
dependencies=dependencies,
|
|
2533
|
+
knowledge_filters=knowledge_filters,
|
|
2534
|
+
metadata=metadata,
|
|
2535
|
+
)
|
|
2536
|
+
|
|
2501
2537
|
# If no retries are set, use the agent's default retries
|
|
2502
2538
|
retries = retries if retries is not None else self.retries
|
|
2503
2539
|
|
|
@@ -2508,7 +2544,8 @@ class Agent:
|
|
|
2508
2544
|
agent_id=self.id,
|
|
2509
2545
|
user_id=user_id,
|
|
2510
2546
|
agent_name=self.name,
|
|
2511
|
-
metadata=metadata,
|
|
2547
|
+
metadata=run_context.metadata,
|
|
2548
|
+
session_state=run_context.session_state,
|
|
2512
2549
|
input=run_input,
|
|
2513
2550
|
)
|
|
2514
2551
|
|
|
@@ -2528,34 +2565,28 @@ class Agent:
|
|
|
2528
2565
|
if stream:
|
|
2529
2566
|
return self._arun_stream( # type: ignore
|
|
2530
2567
|
run_response=run_response,
|
|
2568
|
+
run_context=run_context,
|
|
2531
2569
|
user_id=user_id,
|
|
2532
2570
|
response_format=response_format,
|
|
2533
2571
|
stream_events=stream_events,
|
|
2534
2572
|
yield_run_response=yield_run_response,
|
|
2535
|
-
dependencies=run_dependencies,
|
|
2536
2573
|
session_id=session_id,
|
|
2537
|
-
session_state=session_state,
|
|
2538
|
-
knowledge_filters=effective_filters,
|
|
2539
2574
|
add_history_to_context=add_history,
|
|
2540
2575
|
add_dependencies_to_context=add_dependencies,
|
|
2541
2576
|
add_session_state_to_context=add_session_state,
|
|
2542
|
-
metadata=metadata,
|
|
2543
2577
|
debug_mode=debug_mode,
|
|
2544
2578
|
**kwargs,
|
|
2545
2579
|
) # type: ignore[assignment]
|
|
2546
2580
|
else:
|
|
2547
2581
|
return self._arun( # type: ignore
|
|
2548
2582
|
run_response=run_response,
|
|
2583
|
+
run_context=run_context,
|
|
2549
2584
|
user_id=user_id,
|
|
2550
2585
|
response_format=response_format,
|
|
2551
|
-
dependencies=run_dependencies,
|
|
2552
2586
|
session_id=session_id,
|
|
2553
|
-
session_state=session_state,
|
|
2554
|
-
knowledge_filters=effective_filters,
|
|
2555
2587
|
add_history_to_context=add_history,
|
|
2556
2588
|
add_dependencies_to_context=add_dependencies,
|
|
2557
2589
|
add_session_state_to_context=add_session_state,
|
|
2558
|
-
metadata=metadata,
|
|
2559
2590
|
debug_mode=debug_mode,
|
|
2560
2591
|
**kwargs,
|
|
2561
2592
|
)
|
|
@@ -2646,7 +2677,7 @@ class Agent:
|
|
|
2646
2677
|
self,
|
|
2647
2678
|
run_response: Optional[RunOutput] = None,
|
|
2648
2679
|
*,
|
|
2649
|
-
run_id: Optional[str] = None,
|
|
2680
|
+
run_id: Optional[str] = None, # type: ignore
|
|
2650
2681
|
updated_tools: Optional[List[ToolExecution]] = None,
|
|
2651
2682
|
stream: Optional[bool] = None,
|
|
2652
2683
|
stream_events: Optional[bool] = False,
|
|
@@ -2687,6 +2718,7 @@ class Agent:
|
|
|
2687
2718
|
raise Exception("continue_run() is not supported with an async DB. Please use acontinue_arun() instead.")
|
|
2688
2719
|
|
|
2689
2720
|
session_id = run_response.session_id if run_response else session_id
|
|
2721
|
+
run_id: str = run_response.run_id if run_response else run_id # type: ignore
|
|
2690
2722
|
|
|
2691
2723
|
session_id, user_id = self._initialize_session(
|
|
2692
2724
|
session_id=session_id,
|
|
@@ -2706,24 +2738,32 @@ class Agent:
|
|
|
2706
2738
|
# Update session state from DB
|
|
2707
2739
|
session_state = self._load_session_state(session=agent_session, session_state=session_state)
|
|
2708
2740
|
|
|
2709
|
-
|
|
2741
|
+
dependencies = dependencies if dependencies is not None else self.dependencies
|
|
2710
2742
|
|
|
2711
|
-
#
|
|
2712
|
-
|
|
2713
|
-
|
|
2743
|
+
# Initialize run context
|
|
2744
|
+
run_context = RunContext(
|
|
2745
|
+
run_id=run_id, # type: ignore
|
|
2746
|
+
session_id=session_id,
|
|
2747
|
+
user_id=user_id,
|
|
2748
|
+
session_state=session_state,
|
|
2749
|
+
dependencies=dependencies,
|
|
2750
|
+
)
|
|
2714
2751
|
|
|
2715
|
-
|
|
2752
|
+
# Resolve dependencies
|
|
2753
|
+
if run_context.dependencies is not None:
|
|
2754
|
+
self._resolve_run_dependencies(run_context=run_context)
|
|
2716
2755
|
|
|
2717
2756
|
# When filters are passed manually
|
|
2718
|
-
if self.knowledge_filters or knowledge_filters:
|
|
2719
|
-
|
|
2757
|
+
if self.knowledge_filters or run_context.knowledge_filters or knowledge_filters:
|
|
2758
|
+
run_context.knowledge_filters = self._get_effective_filters(knowledge_filters)
|
|
2720
2759
|
|
|
2721
2760
|
# Merge agent metadata with run metadata
|
|
2761
|
+
run_context.metadata = metadata
|
|
2722
2762
|
if self.metadata is not None:
|
|
2723
|
-
if metadata is None:
|
|
2724
|
-
metadata = self.metadata
|
|
2763
|
+
if run_context.metadata is None:
|
|
2764
|
+
run_context.metadata = self.metadata
|
|
2725
2765
|
else:
|
|
2726
|
-
merge_dictionaries(metadata, self.metadata)
|
|
2766
|
+
merge_dictionaries(run_context.metadata, self.metadata)
|
|
2727
2767
|
|
|
2728
2768
|
# If no retries are set, use the agent's default retries
|
|
2729
2769
|
retries = retries if retries is not None else self.retries
|
|
@@ -2774,17 +2814,17 @@ class Agent:
|
|
|
2774
2814
|
|
|
2775
2815
|
processed_tools = self.get_tools(
|
|
2776
2816
|
run_response=run_response,
|
|
2817
|
+
run_context=run_context,
|
|
2777
2818
|
session=agent_session,
|
|
2778
2819
|
user_id=user_id,
|
|
2779
|
-
knowledge_filters=effective_filters,
|
|
2780
2820
|
)
|
|
2821
|
+
|
|
2781
2822
|
_tools = self._determine_tools_for_model(
|
|
2782
2823
|
model=self.model,
|
|
2783
2824
|
processed_tools=processed_tools,
|
|
2784
2825
|
run_response=run_response,
|
|
2826
|
+
run_context=run_context,
|
|
2785
2827
|
session=agent_session,
|
|
2786
|
-
session_state=session_state,
|
|
2787
|
-
dependencies=run_dependencies,
|
|
2788
2828
|
)
|
|
2789
2829
|
|
|
2790
2830
|
last_exception = None
|
|
@@ -2807,12 +2847,10 @@ class Agent:
|
|
|
2807
2847
|
response_iterator = self._continue_run_stream(
|
|
2808
2848
|
run_response=run_response,
|
|
2809
2849
|
run_messages=run_messages,
|
|
2850
|
+
run_context=run_context,
|
|
2810
2851
|
tools=_tools,
|
|
2811
2852
|
user_id=user_id,
|
|
2812
2853
|
session=agent_session,
|
|
2813
|
-
session_state=session_state,
|
|
2814
|
-
dependencies=run_dependencies,
|
|
2815
|
-
metadata=metadata,
|
|
2816
2854
|
response_format=response_format,
|
|
2817
2855
|
stream_events=stream_events,
|
|
2818
2856
|
debug_mode=debug_mode,
|
|
@@ -2823,12 +2861,10 @@ class Agent:
|
|
|
2823
2861
|
response = self._continue_run(
|
|
2824
2862
|
run_response=run_response,
|
|
2825
2863
|
run_messages=run_messages,
|
|
2864
|
+
run_context=run_context,
|
|
2826
2865
|
tools=_tools,
|
|
2827
2866
|
user_id=user_id,
|
|
2828
2867
|
session=agent_session,
|
|
2829
|
-
session_state=session_state,
|
|
2830
|
-
dependencies=run_dependencies,
|
|
2831
|
-
metadata=metadata,
|
|
2832
2868
|
response_format=response_format,
|
|
2833
2869
|
debug_mode=debug_mode,
|
|
2834
2870
|
**kwargs,
|
|
@@ -2875,11 +2911,9 @@ class Agent:
|
|
|
2875
2911
|
self,
|
|
2876
2912
|
run_response: RunOutput,
|
|
2877
2913
|
run_messages: RunMessages,
|
|
2914
|
+
run_context: RunContext,
|
|
2878
2915
|
session: AgentSession,
|
|
2879
2916
|
tools: List[Union[Function, dict]],
|
|
2880
|
-
session_state: Optional[Dict[str, Any]] = None,
|
|
2881
|
-
dependencies: Optional[Dict[str, Any]] = None,
|
|
2882
|
-
metadata: Optional[Dict[str, Any]] = None,
|
|
2883
2917
|
user_id: Optional[str] = None,
|
|
2884
2918
|
response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
|
|
2885
2919
|
debug_mode: Optional[bool] = None,
|
|
@@ -2936,18 +2970,16 @@ class Agent:
|
|
|
2936
2970
|
|
|
2937
2971
|
# 5. Store media if enabled
|
|
2938
2972
|
if self.store_media:
|
|
2939
|
-
|
|
2973
|
+
store_media_util(run_response, model_response)
|
|
2940
2974
|
|
|
2941
2975
|
# 6. Execute post-hooks
|
|
2942
2976
|
if self.post_hooks is not None:
|
|
2943
2977
|
post_hook_iterator = self._execute_post_hooks(
|
|
2944
2978
|
hooks=self.post_hooks, # type: ignore
|
|
2945
2979
|
run_output=run_response,
|
|
2980
|
+
run_context=run_context,
|
|
2946
2981
|
session=session,
|
|
2947
2982
|
user_id=user_id,
|
|
2948
|
-
session_state=session_state,
|
|
2949
|
-
dependencies=dependencies,
|
|
2950
|
-
metadata=metadata,
|
|
2951
2983
|
debug_mode=debug_mode,
|
|
2952
2984
|
**kwargs,
|
|
2953
2985
|
)
|
|
@@ -2969,7 +3001,9 @@ class Agent:
|
|
|
2969
3001
|
run_response.status = RunStatus.completed
|
|
2970
3002
|
|
|
2971
3003
|
# 8. Cleanup and store the run response and session
|
|
2972
|
-
self._cleanup_and_store(
|
|
3004
|
+
self._cleanup_and_store(
|
|
3005
|
+
run_response=run_response, session=session, run_context=run_context, user_id=user_id
|
|
3006
|
+
)
|
|
2973
3007
|
|
|
2974
3008
|
# Log Agent Telemetry
|
|
2975
3009
|
self._log_agent_telemetry(session_id=session.session_id, run_id=run_response.run_id)
|
|
@@ -2982,7 +3016,9 @@ class Agent:
|
|
|
2982
3016
|
run_response.content = str(e)
|
|
2983
3017
|
|
|
2984
3018
|
# Cleanup and store the run response and session
|
|
2985
|
-
self._cleanup_and_store(
|
|
3019
|
+
self._cleanup_and_store(
|
|
3020
|
+
run_response=run_response, session=session, run_context=run_context, user_id=user_id
|
|
3021
|
+
)
|
|
2986
3022
|
|
|
2987
3023
|
return run_response
|
|
2988
3024
|
finally:
|
|
@@ -2993,14 +3029,12 @@ class Agent:
|
|
|
2993
3029
|
self,
|
|
2994
3030
|
run_response: RunOutput,
|
|
2995
3031
|
run_messages: RunMessages,
|
|
3032
|
+
run_context: RunContext,
|
|
2996
3033
|
session: AgentSession,
|
|
2997
3034
|
tools: List[Union[Function, dict]],
|
|
2998
|
-
session_state: Optional[Dict[str, Any]] = None,
|
|
2999
|
-
metadata: Optional[Dict[str, Any]] = None,
|
|
3000
3035
|
user_id: Optional[str] = None,
|
|
3001
3036
|
response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
|
|
3002
3037
|
stream_events: bool = False,
|
|
3003
|
-
dependencies: Optional[Dict[str, Any]] = None,
|
|
3004
3038
|
debug_mode: Optional[bool] = None,
|
|
3005
3039
|
**kwargs,
|
|
3006
3040
|
) -> Iterator[RunOutputEvent]:
|
|
@@ -3016,8 +3050,8 @@ class Agent:
|
|
|
3016
3050
|
"""
|
|
3017
3051
|
|
|
3018
3052
|
# 1. Resolve dependencies
|
|
3019
|
-
if dependencies is not None:
|
|
3020
|
-
self._resolve_run_dependencies(
|
|
3053
|
+
if run_context.dependencies is not None:
|
|
3054
|
+
self._resolve_run_dependencies(run_context=run_context)
|
|
3021
3055
|
|
|
3022
3056
|
# Start the Run by yielding a RunContinued event
|
|
3023
3057
|
if stream_events:
|
|
@@ -3042,6 +3076,7 @@ class Agent:
|
|
|
3042
3076
|
tools=tools,
|
|
3043
3077
|
response_format=response_format,
|
|
3044
3078
|
stream_events=stream_events,
|
|
3079
|
+
session_state=run_context.session_state,
|
|
3045
3080
|
):
|
|
3046
3081
|
yield event
|
|
3047
3082
|
|
|
@@ -3072,9 +3107,7 @@ class Agent:
|
|
|
3072
3107
|
hooks=self.post_hooks, # type: ignore
|
|
3073
3108
|
run_output=run_response,
|
|
3074
3109
|
session=session,
|
|
3075
|
-
|
|
3076
|
-
dependencies=dependencies,
|
|
3077
|
-
metadata=metadata,
|
|
3110
|
+
run_context=run_context,
|
|
3078
3111
|
user_id=user_id,
|
|
3079
3112
|
debug_mode=debug_mode,
|
|
3080
3113
|
**kwargs,
|
|
@@ -3110,6 +3143,11 @@ class Agent:
|
|
|
3110
3143
|
store_events=self.store_events,
|
|
3111
3144
|
)
|
|
3112
3145
|
|
|
3146
|
+
# Update run_response.session_state before creating RunCompletedEvent
|
|
3147
|
+
# This ensures the event has the final state after all tool modifications
|
|
3148
|
+
if session.session_data is not None and "session_state" in session.session_data:
|
|
3149
|
+
run_response.session_state = session.session_data["session_state"]
|
|
3150
|
+
|
|
3113
3151
|
# Create the run completed event
|
|
3114
3152
|
completed_event = handle_event(
|
|
3115
3153
|
create_run_completed_event(run_response),
|
|
@@ -3122,7 +3160,9 @@ class Agent:
|
|
|
3122
3160
|
run_response.status = RunStatus.completed
|
|
3123
3161
|
|
|
3124
3162
|
# 5. Cleanup and store the run response and session
|
|
3125
|
-
self._cleanup_and_store(
|
|
3163
|
+
self._cleanup_and_store(
|
|
3164
|
+
run_response=run_response, session=session, run_context=run_context, user_id=user_id
|
|
3165
|
+
)
|
|
3126
3166
|
|
|
3127
3167
|
if stream_events:
|
|
3128
3168
|
yield completed_event # type: ignore
|
|
@@ -3147,7 +3187,9 @@ class Agent:
|
|
|
3147
3187
|
)
|
|
3148
3188
|
|
|
3149
3189
|
# Cleanup and store the run response and session
|
|
3150
|
-
self._cleanup_and_store(
|
|
3190
|
+
self._cleanup_and_store(
|
|
3191
|
+
run_response=run_response, session=session, run_context=run_context, user_id=user_id
|
|
3192
|
+
)
|
|
3151
3193
|
finally:
|
|
3152
3194
|
# Always clean up the run tracking
|
|
3153
3195
|
cleanup_run(run_response.run_id) # type: ignore
|
|
@@ -3194,7 +3236,7 @@ class Agent:
|
|
|
3194
3236
|
self,
|
|
3195
3237
|
run_response: Optional[RunOutput] = None,
|
|
3196
3238
|
*,
|
|
3197
|
-
run_id: Optional[str] = None,
|
|
3239
|
+
run_id: Optional[str] = None, # type: ignore
|
|
3198
3240
|
updated_tools: Optional[List[ToolExecution]] = None,
|
|
3199
3241
|
stream: Optional[bool] = None,
|
|
3200
3242
|
stream_events: Optional[bool] = None,
|
|
@@ -3237,11 +3279,12 @@ class Agent:
|
|
|
3237
3279
|
session_id=session_id,
|
|
3238
3280
|
user_id=user_id,
|
|
3239
3281
|
)
|
|
3282
|
+
run_id: str = run_id or run_response.run_id if run_response else run_id # type: ignore
|
|
3240
3283
|
|
|
3241
3284
|
# Initialize the Agent
|
|
3242
3285
|
self.initialize_agent(debug_mode=debug_mode)
|
|
3243
3286
|
|
|
3244
|
-
|
|
3287
|
+
dependencies = dependencies if dependencies is not None else self.dependencies
|
|
3245
3288
|
|
|
3246
3289
|
# If no retries are set, use the agent's default retries
|
|
3247
3290
|
retries = retries if retries is not None else self.retries
|
|
@@ -3268,9 +3311,9 @@ class Agent:
|
|
|
3268
3311
|
self.stream_events = self.stream_events or stream_events
|
|
3269
3312
|
|
|
3270
3313
|
# Get knowledge filters
|
|
3271
|
-
|
|
3314
|
+
knowledge_filters = knowledge_filters
|
|
3272
3315
|
if self.knowledge_filters or knowledge_filters:
|
|
3273
|
-
|
|
3316
|
+
knowledge_filters = self._get_effective_filters(knowledge_filters)
|
|
3274
3317
|
|
|
3275
3318
|
# Merge agent metadata with run metadata
|
|
3276
3319
|
if self.metadata is not None:
|
|
@@ -3283,6 +3326,17 @@ class Agent:
|
|
|
3283
3326
|
response_format = self._get_response_format()
|
|
3284
3327
|
self.model = cast(Model, self.model)
|
|
3285
3328
|
|
|
3329
|
+
# Initialize run context
|
|
3330
|
+
run_context = RunContext(
|
|
3331
|
+
run_id=run_id, # type: ignore
|
|
3332
|
+
session_id=session_id,
|
|
3333
|
+
user_id=user_id,
|
|
3334
|
+
session_state={},
|
|
3335
|
+
dependencies=dependencies,
|
|
3336
|
+
knowledge_filters=knowledge_filters,
|
|
3337
|
+
metadata=metadata,
|
|
3338
|
+
)
|
|
3339
|
+
|
|
3286
3340
|
last_exception = None
|
|
3287
3341
|
num_attempts = retries + 1
|
|
3288
3342
|
for attempt in range(num_attempts):
|
|
@@ -3290,15 +3344,13 @@ class Agent:
|
|
|
3290
3344
|
if stream:
|
|
3291
3345
|
return self._acontinue_run_stream(
|
|
3292
3346
|
run_response=run_response,
|
|
3347
|
+
run_context=run_context,
|
|
3293
3348
|
updated_tools=updated_tools,
|
|
3294
|
-
knowledge_filters=effective_filters,
|
|
3295
3349
|
run_id=run_id,
|
|
3296
3350
|
user_id=user_id,
|
|
3297
3351
|
session_id=session_id,
|
|
3298
3352
|
response_format=response_format,
|
|
3299
|
-
dependencies=run_dependencies,
|
|
3300
3353
|
stream_events=stream_events,
|
|
3301
|
-
metadata=metadata,
|
|
3302
3354
|
yield_run_response=yield_run_response,
|
|
3303
3355
|
debug_mode=debug_mode,
|
|
3304
3356
|
**kwargs,
|
|
@@ -3307,13 +3359,11 @@ class Agent:
|
|
|
3307
3359
|
return self._acontinue_run( # type: ignore
|
|
3308
3360
|
session_id=session_id,
|
|
3309
3361
|
run_response=run_response,
|
|
3362
|
+
run_context=run_context,
|
|
3310
3363
|
updated_tools=updated_tools,
|
|
3311
|
-
knowledge_filters=effective_filters,
|
|
3312
3364
|
run_id=run_id,
|
|
3313
3365
|
user_id=user_id,
|
|
3314
3366
|
response_format=response_format,
|
|
3315
|
-
dependencies=run_dependencies,
|
|
3316
|
-
metadata=metadata,
|
|
3317
3367
|
debug_mode=debug_mode,
|
|
3318
3368
|
**kwargs,
|
|
3319
3369
|
)
|
|
@@ -3357,14 +3407,12 @@ class Agent:
|
|
|
3357
3407
|
async def _acontinue_run(
|
|
3358
3408
|
self,
|
|
3359
3409
|
session_id: str,
|
|
3410
|
+
run_context: RunContext,
|
|
3360
3411
|
run_response: Optional[RunOutput] = None,
|
|
3361
3412
|
updated_tools: Optional[List[ToolExecution]] = None,
|
|
3362
|
-
knowledge_filters: Optional[Dict[str, Any]] = None,
|
|
3363
3413
|
run_id: Optional[str] = None,
|
|
3364
3414
|
user_id: Optional[str] = None,
|
|
3365
3415
|
response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
|
|
3366
|
-
dependencies: Optional[Dict[str, Any]] = None,
|
|
3367
|
-
metadata: Optional[Dict[str, Any]] = None,
|
|
3368
3416
|
debug_mode: Optional[bool] = None,
|
|
3369
3417
|
**kwargs,
|
|
3370
3418
|
) -> RunOutput:
|
|
@@ -3392,18 +3440,20 @@ class Agent:
|
|
|
3392
3440
|
agent_session = await self._aread_or_create_session(session_id=session_id, user_id=user_id)
|
|
3393
3441
|
|
|
3394
3442
|
# 2. Resolve dependencies
|
|
3395
|
-
if dependencies is not None:
|
|
3396
|
-
await self._aresolve_run_dependencies(
|
|
3443
|
+
if run_context.dependencies is not None:
|
|
3444
|
+
await self._aresolve_run_dependencies(run_context=run_context)
|
|
3397
3445
|
|
|
3398
3446
|
# 3. Update metadata and session state
|
|
3399
3447
|
self._update_metadata(session=agent_session)
|
|
3400
3448
|
# Initialize session state
|
|
3401
|
-
session_state = self._initialize_session_state(
|
|
3449
|
+
run_context.session_state = self._initialize_session_state(
|
|
3402
3450
|
session_state={}, user_id=user_id, session_id=session_id, run_id=run_id
|
|
3403
3451
|
)
|
|
3404
3452
|
# Update session state from DB
|
|
3405
|
-
if session_state is not None:
|
|
3406
|
-
session_state = self._load_session_state(
|
|
3453
|
+
if run_context.session_state is not None:
|
|
3454
|
+
run_context.session_state = self._load_session_state(
|
|
3455
|
+
session=agent_session, session_state=run_context.session_state
|
|
3456
|
+
)
|
|
3407
3457
|
|
|
3408
3458
|
# 4. Prepare run response
|
|
3409
3459
|
if run_response is not None:
|
|
@@ -3430,17 +3480,17 @@ class Agent:
|
|
|
3430
3480
|
self.model = cast(Model, self.model)
|
|
3431
3481
|
processed_tools = await self.aget_tools(
|
|
3432
3482
|
run_response=run_response,
|
|
3483
|
+
run_context=run_context,
|
|
3433
3484
|
session=agent_session,
|
|
3434
3485
|
user_id=user_id,
|
|
3435
|
-
knowledge_filters=knowledge_filters,
|
|
3436
3486
|
)
|
|
3487
|
+
|
|
3437
3488
|
_tools = self._determine_tools_for_model(
|
|
3438
3489
|
model=self.model,
|
|
3439
3490
|
processed_tools=processed_tools,
|
|
3440
3491
|
run_response=run_response,
|
|
3492
|
+
run_context=run_context,
|
|
3441
3493
|
session=agent_session,
|
|
3442
|
-
session_state=session_state,
|
|
3443
|
-
dependencies=dependencies,
|
|
3444
3494
|
)
|
|
3445
3495
|
|
|
3446
3496
|
# 6. Prepare run messages
|
|
@@ -3490,7 +3540,7 @@ class Agent:
|
|
|
3490
3540
|
|
|
3491
3541
|
# 11. Store media if enabled
|
|
3492
3542
|
if self.store_media:
|
|
3493
|
-
|
|
3543
|
+
store_media_util(run_response, model_response)
|
|
3494
3544
|
|
|
3495
3545
|
raise_if_cancelled(run_response.run_id) # type: ignore
|
|
3496
3546
|
|
|
@@ -3499,12 +3549,10 @@ class Agent:
|
|
|
3499
3549
|
async for _ in self._aexecute_post_hooks(
|
|
3500
3550
|
hooks=self.post_hooks, # type: ignore
|
|
3501
3551
|
run_output=run_response,
|
|
3552
|
+
run_context=run_context,
|
|
3502
3553
|
session=agent_session,
|
|
3503
3554
|
user_id=user_id,
|
|
3504
3555
|
debug_mode=debug_mode,
|
|
3505
|
-
session_state=session_state,
|
|
3506
|
-
dependencies=dependencies,
|
|
3507
|
-
metadata=metadata,
|
|
3508
3556
|
**kwargs,
|
|
3509
3557
|
):
|
|
3510
3558
|
pass
|
|
@@ -3526,7 +3574,12 @@ class Agent:
|
|
|
3526
3574
|
run_response.status = RunStatus.completed
|
|
3527
3575
|
|
|
3528
3576
|
# 14. Cleanup and store the run response and session
|
|
3529
|
-
await self._acleanup_and_store(
|
|
3577
|
+
await self._acleanup_and_store(
|
|
3578
|
+
run_response=run_response,
|
|
3579
|
+
session=agent_session,
|
|
3580
|
+
run_context=run_context,
|
|
3581
|
+
user_id=user_id,
|
|
3582
|
+
)
|
|
3530
3583
|
|
|
3531
3584
|
# Log Agent Telemetry
|
|
3532
3585
|
await self._alog_agent_telemetry(session_id=agent_session.session_id, run_id=run_response.run_id)
|
|
@@ -3542,7 +3595,12 @@ class Agent:
|
|
|
3542
3595
|
run_response.status = RunStatus.cancelled
|
|
3543
3596
|
|
|
3544
3597
|
# Cleanup and store the run response and session
|
|
3545
|
-
await self._acleanup_and_store(
|
|
3598
|
+
await self._acleanup_and_store(
|
|
3599
|
+
run_response=run_response,
|
|
3600
|
+
session=agent_session,
|
|
3601
|
+
run_context=run_context,
|
|
3602
|
+
user_id=user_id,
|
|
3603
|
+
)
|
|
3546
3604
|
|
|
3547
3605
|
return run_response
|
|
3548
3606
|
finally:
|
|
@@ -3555,16 +3613,14 @@ class Agent:
|
|
|
3555
3613
|
async def _acontinue_run_stream(
|
|
3556
3614
|
self,
|
|
3557
3615
|
session_id: str,
|
|
3616
|
+
run_context: RunContext,
|
|
3558
3617
|
run_response: Optional[RunOutput] = None,
|
|
3559
3618
|
updated_tools: Optional[List[ToolExecution]] = None,
|
|
3560
|
-
knowledge_filters: Optional[Dict[str, Any]] = None,
|
|
3561
3619
|
run_id: Optional[str] = None,
|
|
3562
3620
|
user_id: Optional[str] = None,
|
|
3563
3621
|
response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
|
|
3564
3622
|
stream_events: bool = False,
|
|
3565
3623
|
yield_run_response: Optional[bool] = None,
|
|
3566
|
-
dependencies: Optional[Dict[str, Any]] = None,
|
|
3567
|
-
metadata: Optional[Dict[str, Any]] = None,
|
|
3568
3624
|
debug_mode: Optional[bool] = None,
|
|
3569
3625
|
**kwargs,
|
|
3570
3626
|
) -> AsyncIterator[Union[RunOutputEvent, RunOutput]]:
|
|
@@ -3586,8 +3642,8 @@ class Agent:
|
|
|
3586
3642
|
log_debug(f"Agent Run Continue: {run_response.run_id if run_response else run_id}", center=True) # type: ignore
|
|
3587
3643
|
|
|
3588
3644
|
# 1. Resolve dependencies
|
|
3589
|
-
if dependencies is not None:
|
|
3590
|
-
await self._aresolve_run_dependencies(
|
|
3645
|
+
if run_context.dependencies is not None:
|
|
3646
|
+
await self._aresolve_run_dependencies(run_context=run_context)
|
|
3591
3647
|
|
|
3592
3648
|
# 2. Read existing session from db
|
|
3593
3649
|
agent_session = await self._aread_or_create_session(session_id=session_id, user_id=user_id)
|
|
@@ -3595,12 +3651,14 @@ class Agent:
|
|
|
3595
3651
|
# 3. Update session state and metadata
|
|
3596
3652
|
self._update_metadata(session=agent_session)
|
|
3597
3653
|
# Initialize session state
|
|
3598
|
-
session_state = self._initialize_session_state(
|
|
3654
|
+
run_context.session_state = self._initialize_session_state(
|
|
3599
3655
|
session_state={}, user_id=user_id, session_id=session_id, run_id=run_id
|
|
3600
3656
|
)
|
|
3601
3657
|
# Update session state from DB
|
|
3602
|
-
if session_state is not None:
|
|
3603
|
-
session_state = self._load_session_state(
|
|
3658
|
+
if run_context.session_state is not None:
|
|
3659
|
+
run_context.session_state = self._load_session_state(
|
|
3660
|
+
session=agent_session, session_state=run_context.session_state
|
|
3661
|
+
)
|
|
3604
3662
|
|
|
3605
3663
|
# 4. Prepare run response
|
|
3606
3664
|
if run_response is not None:
|
|
@@ -3627,17 +3685,17 @@ class Agent:
|
|
|
3627
3685
|
self.model = cast(Model, self.model)
|
|
3628
3686
|
processed_tools = await self.aget_tools(
|
|
3629
3687
|
run_response=run_response,
|
|
3688
|
+
run_context=run_context,
|
|
3630
3689
|
session=agent_session,
|
|
3631
3690
|
user_id=user_id,
|
|
3632
|
-
knowledge_filters=knowledge_filters,
|
|
3633
3691
|
)
|
|
3692
|
+
|
|
3634
3693
|
_tools = self._determine_tools_for_model(
|
|
3635
3694
|
model=self.model,
|
|
3636
3695
|
processed_tools=processed_tools,
|
|
3637
3696
|
run_response=run_response,
|
|
3697
|
+
run_context=run_context,
|
|
3638
3698
|
session=agent_session,
|
|
3639
|
-
session_state=session_state,
|
|
3640
|
-
dependencies=dependencies,
|
|
3641
3699
|
)
|
|
3642
3700
|
|
|
3643
3701
|
# 6. Prepare run messages
|
|
@@ -3742,11 +3800,9 @@ class Agent:
|
|
|
3742
3800
|
async for event in self._aexecute_post_hooks(
|
|
3743
3801
|
hooks=self.post_hooks, # type: ignore
|
|
3744
3802
|
run_output=run_response,
|
|
3803
|
+
run_context=run_context,
|
|
3745
3804
|
session=agent_session,
|
|
3746
3805
|
user_id=user_id,
|
|
3747
|
-
session_state=session_state,
|
|
3748
|
-
dependencies=dependencies,
|
|
3749
|
-
metadata=metadata,
|
|
3750
3806
|
debug_mode=debug_mode,
|
|
3751
3807
|
**kwargs,
|
|
3752
3808
|
):
|
|
@@ -3780,6 +3836,11 @@ class Agent:
|
|
|
3780
3836
|
store_events=self.store_events,
|
|
3781
3837
|
)
|
|
3782
3838
|
|
|
3839
|
+
# Update run_response.session_state before creating RunCompletedEvent
|
|
3840
|
+
# This ensures the event has the final state after all tool modifications
|
|
3841
|
+
if agent_session.session_data is not None and "session_state" in agent_session.session_data:
|
|
3842
|
+
run_response.session_state = agent_session.session_data["session_state"]
|
|
3843
|
+
|
|
3783
3844
|
# Create the run completed event
|
|
3784
3845
|
completed_event = handle_event(
|
|
3785
3846
|
create_run_completed_event(run_response),
|
|
@@ -3792,7 +3853,9 @@ class Agent:
|
|
|
3792
3853
|
run_response.status = RunStatus.completed
|
|
3793
3854
|
|
|
3794
3855
|
# 10. Cleanup and store the run response and session
|
|
3795
|
-
await self._acleanup_and_store(
|
|
3856
|
+
await self._acleanup_and_store(
|
|
3857
|
+
run_response=run_response, session=agent_session, run_context=run_context, user_id=user_id
|
|
3858
|
+
)
|
|
3796
3859
|
|
|
3797
3860
|
if stream_events:
|
|
3798
3861
|
yield completed_event # type: ignore
|
|
@@ -3819,7 +3882,12 @@ class Agent:
|
|
|
3819
3882
|
)
|
|
3820
3883
|
|
|
3821
3884
|
# Cleanup and store the run response and session
|
|
3822
|
-
await self._acleanup_and_store(
|
|
3885
|
+
await self._acleanup_and_store(
|
|
3886
|
+
run_response=run_response,
|
|
3887
|
+
session=agent_session,
|
|
3888
|
+
run_context=run_context,
|
|
3889
|
+
user_id=user_id,
|
|
3890
|
+
)
|
|
3823
3891
|
finally:
|
|
3824
3892
|
# Always disconnect MCP tools
|
|
3825
3893
|
await self._disconnect_mcp_tools()
|
|
@@ -3833,9 +3901,7 @@ class Agent:
|
|
|
3833
3901
|
run_response: RunOutput,
|
|
3834
3902
|
run_input: RunInput,
|
|
3835
3903
|
session: AgentSession,
|
|
3836
|
-
|
|
3837
|
-
dependencies: Optional[Dict[str, Any]] = None,
|
|
3838
|
-
metadata: Optional[Dict[str, Any]] = None,
|
|
3904
|
+
run_context: RunContext,
|
|
3839
3905
|
user_id: Optional[str] = None,
|
|
3840
3906
|
debug_mode: Optional[bool] = None,
|
|
3841
3907
|
**kwargs: Any,
|
|
@@ -3847,11 +3913,12 @@ class Agent:
|
|
|
3847
3913
|
# Prepare all possible arguments once
|
|
3848
3914
|
all_args = {
|
|
3849
3915
|
"run_input": run_input,
|
|
3916
|
+
"run_context": run_context,
|
|
3850
3917
|
"agent": self,
|
|
3851
3918
|
"session": session,
|
|
3852
|
-
"session_state": session_state,
|
|
3853
|
-
"dependencies": dependencies,
|
|
3854
|
-
"metadata": metadata,
|
|
3919
|
+
"session_state": run_context.session_state,
|
|
3920
|
+
"dependencies": run_context.dependencies,
|
|
3921
|
+
"metadata": run_context.metadata,
|
|
3855
3922
|
"user_id": user_id,
|
|
3856
3923
|
"debug_mode": debug_mode or self.debug_mode,
|
|
3857
3924
|
}
|
|
@@ -3902,10 +3969,8 @@ class Agent:
|
|
|
3902
3969
|
hooks: Optional[List[Callable[..., Any]]],
|
|
3903
3970
|
run_response: RunOutput,
|
|
3904
3971
|
run_input: RunInput,
|
|
3972
|
+
run_context: RunContext,
|
|
3905
3973
|
session: AgentSession,
|
|
3906
|
-
session_state: Optional[Dict[str, Any]] = None,
|
|
3907
|
-
dependencies: Optional[Dict[str, Any]] = None,
|
|
3908
|
-
metadata: Optional[Dict[str, Any]] = None,
|
|
3909
3974
|
user_id: Optional[str] = None,
|
|
3910
3975
|
debug_mode: Optional[bool] = None,
|
|
3911
3976
|
**kwargs: Any,
|
|
@@ -3919,9 +3984,10 @@ class Agent:
|
|
|
3919
3984
|
"run_input": run_input,
|
|
3920
3985
|
"agent": self,
|
|
3921
3986
|
"session": session,
|
|
3922
|
-
"
|
|
3923
|
-
"
|
|
3924
|
-
"
|
|
3987
|
+
"run_context": run_context,
|
|
3988
|
+
"session_state": run_context.session_state,
|
|
3989
|
+
"dependencies": run_context.dependencies,
|
|
3990
|
+
"metadata": run_context.metadata,
|
|
3925
3991
|
"user_id": user_id,
|
|
3926
3992
|
"debug_mode": debug_mode or self.debug_mode,
|
|
3927
3993
|
}
|
|
@@ -3976,9 +4042,7 @@ class Agent:
|
|
|
3976
4042
|
hooks: Optional[List[Callable[..., Any]]],
|
|
3977
4043
|
run_output: RunOutput,
|
|
3978
4044
|
session: AgentSession,
|
|
3979
|
-
|
|
3980
|
-
dependencies: Optional[Dict[str, Any]] = None,
|
|
3981
|
-
metadata: Optional[Dict[str, Any]] = None,
|
|
4045
|
+
run_context: RunContext,
|
|
3982
4046
|
user_id: Optional[str] = None,
|
|
3983
4047
|
debug_mode: Optional[bool] = None,
|
|
3984
4048
|
**kwargs: Any,
|
|
@@ -3992,10 +4056,11 @@ class Agent:
|
|
|
3992
4056
|
"run_output": run_output,
|
|
3993
4057
|
"agent": self,
|
|
3994
4058
|
"session": session,
|
|
4059
|
+
"session_state": run_context.session_state,
|
|
4060
|
+
"dependencies": run_context.dependencies,
|
|
4061
|
+
"metadata": run_context.metadata,
|
|
3995
4062
|
"user_id": user_id,
|
|
3996
|
-
"
|
|
3997
|
-
"dependencies": dependencies,
|
|
3998
|
-
"metadata": metadata,
|
|
4063
|
+
"run_context": run_context,
|
|
3999
4064
|
"debug_mode": debug_mode or self.debug_mode,
|
|
4000
4065
|
}
|
|
4001
4066
|
all_args.update(kwargs)
|
|
@@ -4038,10 +4103,8 @@ class Agent:
|
|
|
4038
4103
|
self,
|
|
4039
4104
|
hooks: Optional[List[Callable[..., Any]]],
|
|
4040
4105
|
run_output: RunOutput,
|
|
4106
|
+
run_context: RunContext,
|
|
4041
4107
|
session: AgentSession,
|
|
4042
|
-
session_state: Optional[Dict[str, Any]] = None,
|
|
4043
|
-
dependencies: Optional[Dict[str, Any]] = None,
|
|
4044
|
-
metadata: Optional[Dict[str, Any]] = None,
|
|
4045
4108
|
user_id: Optional[str] = None,
|
|
4046
4109
|
debug_mode: Optional[bool] = None,
|
|
4047
4110
|
**kwargs: Any,
|
|
@@ -4055,10 +4118,11 @@ class Agent:
|
|
|
4055
4118
|
"run_output": run_output,
|
|
4056
4119
|
"agent": self,
|
|
4057
4120
|
"session": session,
|
|
4121
|
+
"run_context": run_context,
|
|
4122
|
+
"session_state": run_context.session_state,
|
|
4123
|
+
"dependencies": run_context.dependencies,
|
|
4124
|
+
"metadata": run_context.metadata,
|
|
4058
4125
|
"user_id": user_id,
|
|
4059
|
-
"session_state": session_state,
|
|
4060
|
-
"dependencies": dependencies,
|
|
4061
|
-
"metadata": metadata,
|
|
4062
4126
|
"debug_mode": debug_mode or self.debug_mode,
|
|
4063
4127
|
}
|
|
4064
4128
|
all_args.update(kwargs)
|
|
@@ -4547,25 +4611,6 @@ class Agent:
|
|
|
4547
4611
|
_t.requires_user_input = False
|
|
4548
4612
|
_t.answered = True
|
|
4549
4613
|
|
|
4550
|
-
def _store_media(self, run_response: RunOutput, model_response: ModelResponse):
|
|
4551
|
-
"""Store media from model response in run_response for persistence"""
|
|
4552
|
-
# Handle generated media fields from ModelResponse (generated media)
|
|
4553
|
-
if model_response.images is not None:
|
|
4554
|
-
for image in model_response.images:
|
|
4555
|
-
self._add_image(image, run_response) # Generated images go to run_response.images
|
|
4556
|
-
|
|
4557
|
-
if model_response.videos is not None:
|
|
4558
|
-
for video in model_response.videos:
|
|
4559
|
-
self._add_video(video, run_response) # Generated videos go to run_response.videos
|
|
4560
|
-
|
|
4561
|
-
if model_response.audios is not None:
|
|
4562
|
-
for audio in model_response.audios:
|
|
4563
|
-
self._add_audio(audio, run_response) # Generated audio go to run_response.audio
|
|
4564
|
-
|
|
4565
|
-
if model_response.files is not None:
|
|
4566
|
-
for file in model_response.files:
|
|
4567
|
-
self._add_file(file, run_response) # Generated files go to run_response.files
|
|
4568
|
-
|
|
4569
4614
|
def _update_run_response(
|
|
4570
4615
|
self,
|
|
4571
4616
|
model_response: ModelResponse,
|
|
@@ -4651,6 +4696,7 @@ class Agent:
|
|
|
4651
4696
|
tools: Optional[List[Union[Function, dict]]] = None,
|
|
4652
4697
|
response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
|
|
4653
4698
|
stream_events: bool = False,
|
|
4699
|
+
session_state: Optional[Dict[str, Any]] = None,
|
|
4654
4700
|
) -> Iterator[RunOutputEvent]:
|
|
4655
4701
|
self.model = cast(Model, self.model)
|
|
4656
4702
|
|
|
@@ -4683,6 +4729,7 @@ class Agent:
|
|
|
4683
4729
|
reasoning_state=reasoning_state,
|
|
4684
4730
|
parse_structured_output=self.should_parse_structured_output,
|
|
4685
4731
|
stream_events=stream_events,
|
|
4732
|
+
session_state=session_state,
|
|
4686
4733
|
)
|
|
4687
4734
|
|
|
4688
4735
|
# Determine reasoning completed
|
|
@@ -4729,6 +4776,7 @@ class Agent:
|
|
|
4729
4776
|
tools: Optional[List[Union[Function, dict]]] = None,
|
|
4730
4777
|
response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
|
|
4731
4778
|
stream_events: bool = False,
|
|
4779
|
+
session_state: Optional[Dict[str, Any]] = None,
|
|
4732
4780
|
) -> AsyncIterator[RunOutputEvent]:
|
|
4733
4781
|
self.model = cast(Model, self.model)
|
|
4734
4782
|
|
|
@@ -4763,6 +4811,7 @@ class Agent:
|
|
|
4763
4811
|
reasoning_state=reasoning_state,
|
|
4764
4812
|
parse_structured_output=self.should_parse_structured_output,
|
|
4765
4813
|
stream_events=stream_events,
|
|
4814
|
+
session_state=session_state,
|
|
4766
4815
|
):
|
|
4767
4816
|
yield event
|
|
4768
4817
|
|
|
@@ -4810,9 +4859,14 @@ class Agent:
|
|
|
4810
4859
|
reasoning_state: Optional[Dict[str, Any]] = None,
|
|
4811
4860
|
parse_structured_output: bool = False,
|
|
4812
4861
|
stream_events: bool = False,
|
|
4862
|
+
session_state: Optional[Dict[str, Any]] = None,
|
|
4813
4863
|
) -> Iterator[RunOutputEvent]:
|
|
4814
|
-
|
|
4815
|
-
|
|
4864
|
+
from agno.run.workflow import WorkflowRunOutputEvent
|
|
4865
|
+
|
|
4866
|
+
if (
|
|
4867
|
+
isinstance(model_response_event, tuple(get_args(RunOutputEvent)))
|
|
4868
|
+
or isinstance(model_response_event, tuple(get_args(TeamRunOutputEvent)))
|
|
4869
|
+
or isinstance(model_response_event, tuple(get_args(WorkflowRunOutputEvent)))
|
|
4816
4870
|
):
|
|
4817
4871
|
if model_response_event.event == RunEvent.custom_event: # type: ignore
|
|
4818
4872
|
model_response_event.agent_id = self.id # type: ignore
|
|
@@ -4981,7 +5035,9 @@ class Agent:
|
|
|
4981
5035
|
# Store media in run_response if store_media is enabled
|
|
4982
5036
|
if self.store_media:
|
|
4983
5037
|
for image in model_response_event.images:
|
|
4984
|
-
|
|
5038
|
+
if run_response.images is None:
|
|
5039
|
+
run_response.images = []
|
|
5040
|
+
run_response.images.append(image)
|
|
4985
5041
|
|
|
4986
5042
|
# Handle tool interruption events
|
|
4987
5043
|
elif model_response_event.event == ModelResponseEvent.tool_call_paused.value:
|
|
@@ -5018,23 +5074,39 @@ class Agent:
|
|
|
5018
5074
|
|
|
5019
5075
|
# If the model response is a tool_call_completed, update the existing tool call in the run_response
|
|
5020
5076
|
elif model_response_event.event == ModelResponseEvent.tool_call_completed.value:
|
|
5021
|
-
if model_response_event.updated_session_state is not None
|
|
5022
|
-
|
|
5023
|
-
|
|
5024
|
-
model_response_event.updated_session_state
|
|
5025
|
-
|
|
5077
|
+
if model_response_event.updated_session_state is not None:
|
|
5078
|
+
# update the session_state for RunOutput
|
|
5079
|
+
if session_state is not None:
|
|
5080
|
+
merge_dictionaries(session_state, model_response_event.updated_session_state)
|
|
5081
|
+
# update the DB session
|
|
5082
|
+
if session.session_data is not None and session.session_data.get("session_state") is not None:
|
|
5083
|
+
merge_dictionaries(
|
|
5084
|
+
session.session_data["session_state"], model_response_event.updated_session_state
|
|
5085
|
+
)
|
|
5026
5086
|
|
|
5027
5087
|
if model_response_event.images is not None:
|
|
5028
5088
|
for image in model_response_event.images:
|
|
5029
|
-
|
|
5089
|
+
if run_response.images is None:
|
|
5090
|
+
run_response.images = []
|
|
5091
|
+
run_response.images.append(image)
|
|
5030
5092
|
|
|
5031
5093
|
if model_response_event.videos is not None:
|
|
5032
5094
|
for video in model_response_event.videos:
|
|
5033
|
-
|
|
5095
|
+
if run_response.videos is None:
|
|
5096
|
+
run_response.videos = []
|
|
5097
|
+
run_response.videos.append(video)
|
|
5034
5098
|
|
|
5035
5099
|
if model_response_event.audios is not None:
|
|
5036
5100
|
for audio in model_response_event.audios:
|
|
5037
|
-
|
|
5101
|
+
if run_response.audio is None:
|
|
5102
|
+
run_response.audio = []
|
|
5103
|
+
run_response.audio.append(audio)
|
|
5104
|
+
|
|
5105
|
+
if model_response_event.files is not None:
|
|
5106
|
+
for file_obj in model_response_event.files:
|
|
5107
|
+
if run_response.files is None:
|
|
5108
|
+
run_response.files = []
|
|
5109
|
+
run_response.files.append(file_obj)
|
|
5038
5110
|
|
|
5039
5111
|
reasoning_step: Optional[ReasoningStep] = None
|
|
5040
5112
|
|
|
@@ -5251,12 +5323,16 @@ class Agent:
|
|
|
5251
5323
|
def get_tools(
|
|
5252
5324
|
self,
|
|
5253
5325
|
run_response: RunOutput,
|
|
5326
|
+
run_context: RunContext,
|
|
5254
5327
|
session: AgentSession,
|
|
5255
5328
|
user_id: Optional[str] = None,
|
|
5256
5329
|
knowledge_filters: Optional[Dict[str, Any]] = None,
|
|
5257
5330
|
) -> List[Union[Toolkit, Callable, Function, Dict]]:
|
|
5258
5331
|
agent_tools: List[Union[Toolkit, Callable, Function, Dict]] = []
|
|
5259
5332
|
|
|
5333
|
+
# Consider both run_context.knowledge_filters and knowledge_filters (deprecated)
|
|
5334
|
+
run_context.knowledge_filters = run_context.knowledge_filters or knowledge_filters
|
|
5335
|
+
|
|
5260
5336
|
# Add provided tools
|
|
5261
5337
|
if self.tools is not None:
|
|
5262
5338
|
# If not running in async mode, raise if any tool is async
|
|
@@ -5302,7 +5378,7 @@ class Agent:
|
|
|
5302
5378
|
self._search_knowledge_base_with_agentic_filters_function(
|
|
5303
5379
|
run_response=run_response,
|
|
5304
5380
|
async_mode=False,
|
|
5305
|
-
knowledge_filters=knowledge_filters,
|
|
5381
|
+
knowledge_filters=run_context.knowledge_filters,
|
|
5306
5382
|
)
|
|
5307
5383
|
)
|
|
5308
5384
|
else:
|
|
@@ -5310,7 +5386,7 @@ class Agent:
|
|
|
5310
5386
|
self._get_search_knowledge_base_function(
|
|
5311
5387
|
run_response=run_response,
|
|
5312
5388
|
async_mode=False,
|
|
5313
|
-
knowledge_filters=knowledge_filters,
|
|
5389
|
+
knowledge_filters=run_context.knowledge_filters,
|
|
5314
5390
|
)
|
|
5315
5391
|
)
|
|
5316
5392
|
|
|
@@ -5322,6 +5398,7 @@ class Agent:
|
|
|
5322
5398
|
async def aget_tools(
|
|
5323
5399
|
self,
|
|
5324
5400
|
run_response: RunOutput,
|
|
5401
|
+
run_context: RunContext,
|
|
5325
5402
|
session: AgentSession,
|
|
5326
5403
|
user_id: Optional[str] = None,
|
|
5327
5404
|
knowledge_filters: Optional[Dict[str, Any]] = None,
|
|
@@ -5329,6 +5406,9 @@ class Agent:
|
|
|
5329
5406
|
) -> List[Union[Toolkit, Callable, Function, Dict]]:
|
|
5330
5407
|
agent_tools: List[Union[Toolkit, Callable, Function, Dict]] = []
|
|
5331
5408
|
|
|
5409
|
+
# Consider both run_context.knowledge_filters and knowledge_filters (deprecated)
|
|
5410
|
+
run_context.knowledge_filters = run_context.knowledge_filters or knowledge_filters
|
|
5411
|
+
|
|
5332
5412
|
# Connect MCP tools
|
|
5333
5413
|
await self._connect_mcp_tools()
|
|
5334
5414
|
|
|
@@ -5386,7 +5466,7 @@ class Agent:
|
|
|
5386
5466
|
self._search_knowledge_base_with_agentic_filters_function(
|
|
5387
5467
|
run_response=run_response,
|
|
5388
5468
|
async_mode=True,
|
|
5389
|
-
knowledge_filters=knowledge_filters,
|
|
5469
|
+
knowledge_filters=run_context.knowledge_filters,
|
|
5390
5470
|
)
|
|
5391
5471
|
)
|
|
5392
5472
|
else:
|
|
@@ -5394,7 +5474,7 @@ class Agent:
|
|
|
5394
5474
|
self._get_search_knowledge_base_function(
|
|
5395
5475
|
run_response=run_response,
|
|
5396
5476
|
async_mode=True,
|
|
5397
|
-
knowledge_filters=knowledge_filters,
|
|
5477
|
+
knowledge_filters=run_context.knowledge_filters,
|
|
5398
5478
|
)
|
|
5399
5479
|
)
|
|
5400
5480
|
|
|
@@ -5408,9 +5488,8 @@ class Agent:
|
|
|
5408
5488
|
model: Model,
|
|
5409
5489
|
processed_tools: List[Union[Toolkit, Callable, Function, Dict]],
|
|
5410
5490
|
run_response: RunOutput,
|
|
5491
|
+
run_context: RunContext,
|
|
5411
5492
|
session: AgentSession,
|
|
5412
|
-
session_state: Optional[Dict[str, Any]] = None,
|
|
5413
|
-
dependencies: Optional[Dict[str, Any]] = None,
|
|
5414
5493
|
) -> List[Union[Function, dict]]:
|
|
5415
5494
|
_function_names = []
|
|
5416
5495
|
_functions: List[Union[Function, dict]] = []
|
|
@@ -5515,8 +5594,9 @@ class Agent:
|
|
|
5515
5594
|
|
|
5516
5595
|
for func in _functions: # type: ignore
|
|
5517
5596
|
if isinstance(func, Function):
|
|
5518
|
-
func.
|
|
5519
|
-
func.
|
|
5597
|
+
func._run_context = run_context
|
|
5598
|
+
func._session_state = run_context.session_state
|
|
5599
|
+
func._dependencies = run_context.dependencies
|
|
5520
5600
|
func._images = joint_images
|
|
5521
5601
|
func._files = joint_files
|
|
5522
5602
|
func._audios = joint_audios
|
|
@@ -5566,49 +5646,70 @@ class Agent:
|
|
|
5566
5646
|
log_debug("Model does not support structured or JSON schema outputs.")
|
|
5567
5647
|
return json_response_format
|
|
5568
5648
|
|
|
5569
|
-
def _resolve_run_dependencies(self,
|
|
5649
|
+
def _resolve_run_dependencies(self, run_context: RunContext) -> None:
|
|
5570
5650
|
from inspect import iscoroutine, iscoroutinefunction, signature
|
|
5571
5651
|
|
|
5572
5652
|
# Dependencies should already be resolved in run() method
|
|
5573
5653
|
log_debug("Resolving dependencies")
|
|
5574
|
-
if not isinstance(dependencies, dict):
|
|
5575
|
-
log_warning("
|
|
5654
|
+
if not isinstance(run_context.dependencies, dict):
|
|
5655
|
+
log_warning("Run dependencies are not a dict")
|
|
5576
5656
|
return
|
|
5577
5657
|
|
|
5578
|
-
for key, value in dependencies.items():
|
|
5658
|
+
for key, value in run_context.dependencies.items():
|
|
5579
5659
|
if iscoroutine(value) or iscoroutinefunction(value):
|
|
5580
5660
|
log_warning(f"Dependency {key} is a coroutine. Use agent.arun() or agent.aprint_response() instead.")
|
|
5581
5661
|
continue
|
|
5582
5662
|
elif callable(value):
|
|
5583
5663
|
try:
|
|
5584
5664
|
sig = signature(value)
|
|
5585
|
-
|
|
5665
|
+
|
|
5666
|
+
# Build kwargs for the function
|
|
5667
|
+
kwargs: Dict[str, Any] = {}
|
|
5668
|
+
if "agent" in sig.parameters:
|
|
5669
|
+
kwargs["agent"] = self
|
|
5670
|
+
if "run_context" in sig.parameters:
|
|
5671
|
+
kwargs["run_context"] = run_context
|
|
5672
|
+
|
|
5673
|
+
# Run the function
|
|
5674
|
+
result = value(**kwargs)
|
|
5675
|
+
|
|
5676
|
+
# Carry the result in the run context
|
|
5586
5677
|
if result is not None:
|
|
5587
|
-
dependencies[key] = result
|
|
5678
|
+
run_context.dependencies[key] = result
|
|
5679
|
+
|
|
5588
5680
|
except Exception as e:
|
|
5589
5681
|
log_warning(f"Failed to resolve dependencies for '{key}': {e}")
|
|
5590
5682
|
else:
|
|
5591
|
-
dependencies[key] = value
|
|
5683
|
+
run_context.dependencies[key] = value
|
|
5592
5684
|
|
|
5593
|
-
async def _aresolve_run_dependencies(self,
|
|
5685
|
+
async def _aresolve_run_dependencies(self, run_context: RunContext) -> None:
|
|
5594
5686
|
from inspect import iscoroutine, iscoroutinefunction, signature
|
|
5595
5687
|
|
|
5596
5688
|
log_debug("Resolving context (async)")
|
|
5597
|
-
if not isinstance(dependencies, dict):
|
|
5598
|
-
log_warning("
|
|
5689
|
+
if not isinstance(run_context.dependencies, dict):
|
|
5690
|
+
log_warning("Run dependencies are not a dict")
|
|
5599
5691
|
return
|
|
5600
5692
|
|
|
5601
|
-
for key, value in dependencies.items():
|
|
5693
|
+
for key, value in run_context.dependencies.items():
|
|
5602
5694
|
if not callable(value):
|
|
5603
|
-
dependencies[key] = value
|
|
5695
|
+
run_context.dependencies[key] = value
|
|
5604
5696
|
continue
|
|
5605
5697
|
try:
|
|
5606
5698
|
sig = signature(value)
|
|
5607
|
-
result = value(agent=self) if "agent" in sig.parameters else value()
|
|
5608
5699
|
|
|
5700
|
+
# Build kwargs for the function
|
|
5701
|
+
kwargs: Dict[str, Any] = {}
|
|
5702
|
+
if "agent" in sig.parameters:
|
|
5703
|
+
kwargs["agent"] = self
|
|
5704
|
+
if "run_context" in sig.parameters:
|
|
5705
|
+
kwargs["run_context"] = run_context
|
|
5706
|
+
|
|
5707
|
+
# Run the function
|
|
5708
|
+
result = value(**kwargs)
|
|
5609
5709
|
if iscoroutine(result) or iscoroutinefunction(result):
|
|
5610
|
-
result = await result
|
|
5611
|
-
|
|
5710
|
+
result = await result # type: ignore
|
|
5711
|
+
|
|
5712
|
+
run_context.dependencies[key] = result
|
|
5612
5713
|
except Exception as e:
|
|
5613
5714
|
log_warning(f"Failed to resolve context for '{key}': {e}")
|
|
5614
5715
|
|
|
@@ -6477,10 +6578,10 @@ class Agent:
|
|
|
6477
6578
|
def _format_message_with_state_variables(
|
|
6478
6579
|
self,
|
|
6479
6580
|
message: Any,
|
|
6480
|
-
user_id: Optional[str] = None,
|
|
6481
6581
|
session_state: Optional[Dict[str, Any]] = None,
|
|
6482
6582
|
dependencies: Optional[Dict[str, Any]] = None,
|
|
6483
6583
|
metadata: Optional[Dict[str, Any]] = None,
|
|
6584
|
+
user_id: Optional[str] = None,
|
|
6484
6585
|
) -> Any:
|
|
6485
6586
|
"""Format a message with the session state variables."""
|
|
6486
6587
|
import re
|
|
@@ -6497,6 +6598,7 @@ class Agent:
|
|
|
6497
6598
|
metadata or {},
|
|
6498
6599
|
{"user_id": user_id} if user_id is not None else {},
|
|
6499
6600
|
)
|
|
6601
|
+
|
|
6500
6602
|
converted_msg = deepcopy(message)
|
|
6501
6603
|
for var_name in format_variables.keys():
|
|
6502
6604
|
# Only convert standalone {var_name} patterns, not nested ones
|
|
@@ -6516,12 +6618,13 @@ class Agent:
|
|
|
6516
6618
|
def get_system_message(
|
|
6517
6619
|
self,
|
|
6518
6620
|
session: AgentSession,
|
|
6519
|
-
|
|
6621
|
+
run_context: Optional[RunContext] = None,
|
|
6520
6622
|
user_id: Optional[str] = None,
|
|
6521
6623
|
tools: Optional[List[Union[Function, dict]]] = None,
|
|
6522
|
-
dependencies: Optional[Dict[str, Any]] = None,
|
|
6523
|
-
metadata: Optional[Dict[str, Any]] = None,
|
|
6524
6624
|
add_session_state_to_context: Optional[bool] = None,
|
|
6625
|
+
session_state: Optional[Dict[str, Any]] = None, # Deprecated
|
|
6626
|
+
dependencies: Optional[Dict[str, Any]] = None, # Deprecated
|
|
6627
|
+
metadata: Optional[Dict[str, Any]] = None, # Deprecated
|
|
6525
6628
|
) -> Optional[Message]:
|
|
6526
6629
|
"""Return the system message for the Agent.
|
|
6527
6630
|
|
|
@@ -6530,6 +6633,12 @@ class Agent:
|
|
|
6530
6633
|
3. Build and return the default system message for the Agent.
|
|
6531
6634
|
"""
|
|
6532
6635
|
|
|
6636
|
+
# Consider both run_context and session_state, dependencies, metadata (deprecated fields)
|
|
6637
|
+
if run_context is not None:
|
|
6638
|
+
session_state = run_context.session_state or session_state
|
|
6639
|
+
dependencies = run_context.dependencies or dependencies
|
|
6640
|
+
metadata = run_context.metadata or metadata
|
|
6641
|
+
|
|
6533
6642
|
# 1. If the system_message is provided, use that.
|
|
6534
6643
|
if self.system_message is not None:
|
|
6535
6644
|
if isinstance(self.system_message, Message):
|
|
@@ -6543,14 +6652,13 @@ class Agent:
|
|
|
6543
6652
|
if not isinstance(sys_message_content, str):
|
|
6544
6653
|
raise Exception("system_message must return a string")
|
|
6545
6654
|
|
|
6546
|
-
# Format the system message with the session state variables
|
|
6547
6655
|
if self.resolve_in_context:
|
|
6548
6656
|
sys_message_content = self._format_message_with_state_variables(
|
|
6549
6657
|
sys_message_content,
|
|
6550
6658
|
user_id=user_id,
|
|
6659
|
+
session_state=session_state,
|
|
6551
6660
|
dependencies=dependencies,
|
|
6552
6661
|
metadata=metadata,
|
|
6553
|
-
session_state=session_state,
|
|
6554
6662
|
)
|
|
6555
6663
|
|
|
6556
6664
|
# type: ignore
|
|
@@ -6582,6 +6690,11 @@ class Agent:
|
|
|
6582
6690
|
if "session_state" in signature.parameters:
|
|
6583
6691
|
instruction_args["session_state"] = session_state or {}
|
|
6584
6692
|
|
|
6693
|
+
# Check for run_context parameter
|
|
6694
|
+
if "run_context" in signature.parameters:
|
|
6695
|
+
instruction_args["run_context"] = run_context or None
|
|
6696
|
+
|
|
6697
|
+
# Run the instructions function
|
|
6585
6698
|
_instructions = self.instructions(**instruction_args)
|
|
6586
6699
|
|
|
6587
6700
|
if isinstance(_instructions, str):
|
|
@@ -6859,11 +6972,13 @@ class Agent:
|
|
|
6859
6972
|
async def aget_system_message(
|
|
6860
6973
|
self,
|
|
6861
6974
|
session: AgentSession,
|
|
6862
|
-
|
|
6975
|
+
run_context: Optional[RunContext] = None,
|
|
6863
6976
|
user_id: Optional[str] = None,
|
|
6864
6977
|
tools: Optional[List[Union[Function, dict]]] = None,
|
|
6865
|
-
|
|
6866
|
-
|
|
6978
|
+
add_session_state_to_context: Optional[bool] = None,
|
|
6979
|
+
session_state: Optional[Dict[str, Any]] = None, # Deprecated
|
|
6980
|
+
dependencies: Optional[Dict[str, Any]] = None, # Deprecated
|
|
6981
|
+
metadata: Optional[Dict[str, Any]] = None, # Deprecated
|
|
6867
6982
|
) -> Optional[Message]:
|
|
6868
6983
|
"""Return the system message for the Agent.
|
|
6869
6984
|
|
|
@@ -6872,6 +6987,12 @@ class Agent:
|
|
|
6872
6987
|
3. Build and return the default system message for the Agent.
|
|
6873
6988
|
"""
|
|
6874
6989
|
|
|
6990
|
+
# Consider both run_context and session_state, dependencies, metadata (deprecated fields)
|
|
6991
|
+
if run_context is not None:
|
|
6992
|
+
session_state = run_context.session_state or session_state
|
|
6993
|
+
dependencies = run_context.dependencies or dependencies
|
|
6994
|
+
metadata = run_context.metadata or metadata
|
|
6995
|
+
|
|
6875
6996
|
# 1. If the system_message is provided, use that.
|
|
6876
6997
|
if self.system_message is not None:
|
|
6877
6998
|
if isinstance(self.system_message, Message):
|
|
@@ -6984,7 +7105,7 @@ class Agent:
|
|
|
6984
7105
|
|
|
6985
7106
|
# 3.2.5 Add information about agentic filters if enabled
|
|
6986
7107
|
if self.knowledge is not None and self.enable_agentic_knowledge_filters:
|
|
6987
|
-
valid_filters =
|
|
7108
|
+
valid_filters = await self.knowledge.aget_valid_filters()
|
|
6988
7109
|
if valid_filters:
|
|
6989
7110
|
valid_filters_str = ", ".join(valid_filters)
|
|
6990
7111
|
additional_information.append(
|
|
@@ -7191,7 +7312,7 @@ class Agent:
|
|
|
7191
7312
|
system_message_content += f"{get_response_model_format_prompt(self.output_schema)}"
|
|
7192
7313
|
|
|
7193
7314
|
# 3.3.15 Add the session state to the system message
|
|
7194
|
-
if
|
|
7315
|
+
if add_session_state_to_context and session_state is not None:
|
|
7195
7316
|
system_message_content += self._get_formatted_session_state_for_system_message(session_state)
|
|
7196
7317
|
|
|
7197
7318
|
# Return the system message
|
|
@@ -7208,17 +7329,18 @@ class Agent:
|
|
|
7208
7329
|
self,
|
|
7209
7330
|
*,
|
|
7210
7331
|
run_response: RunOutput,
|
|
7332
|
+
run_context: Optional[RunContext] = None,
|
|
7211
7333
|
session_state: Optional[Dict[str, Any]] = None,
|
|
7334
|
+
dependencies: Optional[Dict[str, Any]] = None,
|
|
7335
|
+
metadata: Optional[Dict[str, Any]] = None,
|
|
7212
7336
|
user_id: Optional[str] = None,
|
|
7213
7337
|
input: Optional[Union[str, List, Dict, Message, BaseModel, List[Message]]] = None,
|
|
7214
7338
|
audio: Optional[Sequence[Audio]] = None,
|
|
7215
7339
|
images: Optional[Sequence[Image]] = None,
|
|
7216
7340
|
videos: Optional[Sequence[Video]] = None,
|
|
7217
7341
|
files: Optional[Sequence[File]] = None,
|
|
7218
|
-
knowledge_filters: Optional[Dict[str, Any]] = None,
|
|
7219
|
-
dependencies: Optional[Dict[str, Any]] = None,
|
|
7220
7342
|
add_dependencies_to_context: Optional[bool] = None,
|
|
7221
|
-
|
|
7343
|
+
knowledge_filters: Optional[Dict[str, Any]] = None,
|
|
7222
7344
|
**kwargs: Any,
|
|
7223
7345
|
) -> Optional[Message]:
|
|
7224
7346
|
"""Return the user message for the Agent.
|
|
@@ -7227,6 +7349,13 @@ class Agent:
|
|
|
7227
7349
|
2. If build_user_context is False or if the message is a list, return the message as is.
|
|
7228
7350
|
3. Build the default user message for the Agent
|
|
7229
7351
|
"""
|
|
7352
|
+
# Consider both run_context and session_state, dependencies, metadata, knowledge_filters (deprecated fields)
|
|
7353
|
+
if run_context is not None:
|
|
7354
|
+
session_state = run_context.session_state or session_state
|
|
7355
|
+
dependencies = run_context.dependencies or dependencies
|
|
7356
|
+
metadata = run_context.metadata or metadata
|
|
7357
|
+
knowledge_filters = run_context.knowledge_filters or knowledge_filters
|
|
7358
|
+
|
|
7230
7359
|
# Get references from the knowledge base to use in the user message
|
|
7231
7360
|
references = None
|
|
7232
7361
|
|
|
@@ -7234,7 +7363,7 @@ class Agent:
|
|
|
7234
7363
|
if not self.build_user_context:
|
|
7235
7364
|
return Message(
|
|
7236
7365
|
role=self.user_message_role or "user",
|
|
7237
|
-
content=input,
|
|
7366
|
+
content=input, # type: ignore
|
|
7238
7367
|
images=None if not self.send_media_to_model else images,
|
|
7239
7368
|
audio=None if not self.send_media_to_model else audio,
|
|
7240
7369
|
videos=None if not self.send_media_to_model else videos,
|
|
@@ -7375,20 +7504,17 @@ class Agent:
|
|
|
7375
7504
|
self,
|
|
7376
7505
|
*,
|
|
7377
7506
|
run_response: RunOutput,
|
|
7507
|
+
run_context: RunContext,
|
|
7378
7508
|
input: Union[str, List, Dict, Message, BaseModel, List[Message]],
|
|
7379
7509
|
session: AgentSession,
|
|
7380
|
-
session_state: Optional[Dict[str, Any]] = None,
|
|
7381
7510
|
user_id: Optional[str] = None,
|
|
7382
7511
|
audio: Optional[Sequence[Audio]] = None,
|
|
7383
7512
|
images: Optional[Sequence[Image]] = None,
|
|
7384
7513
|
videos: Optional[Sequence[Video]] = None,
|
|
7385
7514
|
files: Optional[Sequence[File]] = None,
|
|
7386
|
-
knowledge_filters: Optional[Dict[str, Any]] = None,
|
|
7387
7515
|
add_history_to_context: Optional[bool] = None,
|
|
7388
|
-
dependencies: Optional[Dict[str, Any]] = None,
|
|
7389
7516
|
add_dependencies_to_context: Optional[bool] = None,
|
|
7390
7517
|
add_session_state_to_context: Optional[bool] = None,
|
|
7391
|
-
metadata: Optional[Dict[str, Any]] = None,
|
|
7392
7518
|
tools: Optional[List[Union[Function, dict]]] = None,
|
|
7393
7519
|
**kwargs: Any,
|
|
7394
7520
|
) -> RunMessages:
|
|
@@ -7422,11 +7548,12 @@ class Agent:
|
|
|
7422
7548
|
# 1. Add system message to run_messages
|
|
7423
7549
|
system_message = self.get_system_message(
|
|
7424
7550
|
session=session,
|
|
7425
|
-
|
|
7551
|
+
run_context=run_context,
|
|
7552
|
+
session_state=run_context.session_state,
|
|
7553
|
+
dependencies=run_context.dependencies,
|
|
7554
|
+
metadata=run_context.metadata,
|
|
7426
7555
|
user_id=user_id,
|
|
7427
7556
|
tools=tools,
|
|
7428
|
-
dependencies=dependencies,
|
|
7429
|
-
metadata=metadata,
|
|
7430
7557
|
add_session_state_to_context=add_session_state_to_context,
|
|
7431
7558
|
)
|
|
7432
7559
|
if system_message is not None:
|
|
@@ -7511,16 +7638,13 @@ class Agent:
|
|
|
7511
7638
|
):
|
|
7512
7639
|
user_message = self._get_user_message(
|
|
7513
7640
|
run_response=run_response,
|
|
7514
|
-
|
|
7641
|
+
run_context=run_context,
|
|
7515
7642
|
input=input,
|
|
7516
7643
|
audio=audio,
|
|
7517
7644
|
images=images,
|
|
7518
7645
|
videos=videos,
|
|
7519
7646
|
files=files,
|
|
7520
|
-
knowledge_filters=knowledge_filters,
|
|
7521
|
-
dependencies=dependencies,
|
|
7522
7647
|
add_dependencies_to_context=add_dependencies_to_context,
|
|
7523
|
-
metadata=metadata,
|
|
7524
7648
|
**kwargs,
|
|
7525
7649
|
)
|
|
7526
7650
|
|
|
@@ -7585,6 +7709,7 @@ class Agent:
|
|
|
7585
7709
|
run_response: RunOutput,
|
|
7586
7710
|
input: Union[str, List, Dict, Message, BaseModel, List[Message]],
|
|
7587
7711
|
session: AgentSession,
|
|
7712
|
+
run_context: Optional[RunContext] = None,
|
|
7588
7713
|
session_state: Optional[Dict[str, Any]] = None,
|
|
7589
7714
|
user_id: Optional[str] = None,
|
|
7590
7715
|
audio: Optional[Sequence[Audio]] = None,
|
|
@@ -7624,17 +7749,25 @@ class Agent:
|
|
|
7624
7749
|
)
|
|
7625
7750
|
"""
|
|
7626
7751
|
|
|
7752
|
+
# Consider both run_context and session_state, dependencies, metadata (deprecated fields)
|
|
7753
|
+
if run_context is not None:
|
|
7754
|
+
session_state = run_context.session_state or session_state
|
|
7755
|
+
dependencies = run_context.dependencies or dependencies
|
|
7756
|
+
metadata = run_context.metadata or metadata
|
|
7757
|
+
|
|
7627
7758
|
# Initialize the RunMessages object (no media here - that's in RunInput now)
|
|
7628
7759
|
run_messages = RunMessages()
|
|
7629
7760
|
|
|
7630
7761
|
# 1. Add system message to run_messages
|
|
7631
7762
|
system_message = await self.aget_system_message(
|
|
7632
7763
|
session=session,
|
|
7764
|
+
run_context=run_context,
|
|
7633
7765
|
session_state=session_state,
|
|
7634
7766
|
user_id=user_id,
|
|
7635
7767
|
tools=tools,
|
|
7636
7768
|
dependencies=dependencies,
|
|
7637
7769
|
metadata=metadata,
|
|
7770
|
+
add_session_state_to_context=add_session_state_to_context,
|
|
7638
7771
|
)
|
|
7639
7772
|
if system_message is not None:
|
|
7640
7773
|
run_messages.system_message = system_message
|
|
@@ -7718,16 +7851,17 @@ class Agent:
|
|
|
7718
7851
|
):
|
|
7719
7852
|
user_message = self._get_user_message(
|
|
7720
7853
|
run_response=run_response,
|
|
7854
|
+
run_context=run_context,
|
|
7721
7855
|
session_state=session_state,
|
|
7856
|
+
dependencies=dependencies,
|
|
7857
|
+
metadata=metadata,
|
|
7722
7858
|
input=input,
|
|
7723
7859
|
audio=audio,
|
|
7724
7860
|
images=images,
|
|
7725
7861
|
videos=videos,
|
|
7726
7862
|
files=files,
|
|
7727
7863
|
knowledge_filters=knowledge_filters,
|
|
7728
|
-
dependencies=dependencies,
|
|
7729
7864
|
add_dependencies_to_context=add_dependencies_to_context,
|
|
7730
|
-
metadata=metadata,
|
|
7731
7865
|
**kwargs,
|
|
7732
7866
|
)
|
|
7733
7867
|
|
|
@@ -7967,7 +8101,7 @@ class Agent:
|
|
|
7967
8101
|
|
|
7968
8102
|
# Validate the filters against known valid filter keys
|
|
7969
8103
|
if self.knowledge is not None:
|
|
7970
|
-
valid_filters, invalid_keys = self.knowledge.
|
|
8104
|
+
valid_filters, invalid_keys = await self.knowledge.async_validate_filters(filters) # type: ignore
|
|
7971
8105
|
|
|
7972
8106
|
# Warn about invalid filter keys
|
|
7973
8107
|
if invalid_keys: # type: ignore
|
|
@@ -8203,38 +8337,6 @@ class Agent:
|
|
|
8203
8337
|
|
|
8204
8338
|
return metrics
|
|
8205
8339
|
|
|
8206
|
-
###########################################################################
|
|
8207
|
-
# Handle images, videos and audio
|
|
8208
|
-
###########################################################################
|
|
8209
|
-
|
|
8210
|
-
def _add_image(self, image: Image, run_response: RunOutput) -> None:
|
|
8211
|
-
"""Add an image to both the agent's stateful storage and the current run response"""
|
|
8212
|
-
# Add to run response
|
|
8213
|
-
if run_response.images is None:
|
|
8214
|
-
run_response.images = []
|
|
8215
|
-
run_response.images.append(image)
|
|
8216
|
-
|
|
8217
|
-
def _add_video(self, video: Video, run_response: RunOutput) -> None:
|
|
8218
|
-
"""Add a video to both the agent's stateful storage and the current run response"""
|
|
8219
|
-
# Add to run response
|
|
8220
|
-
if run_response.videos is None:
|
|
8221
|
-
run_response.videos = []
|
|
8222
|
-
run_response.videos.append(video)
|
|
8223
|
-
|
|
8224
|
-
def _add_audio(self, audio: Audio, run_response: RunOutput) -> None:
|
|
8225
|
-
"""Add audio to both the agent's stateful storage and the current run response"""
|
|
8226
|
-
# Add to run response
|
|
8227
|
-
if run_response.audio is None:
|
|
8228
|
-
run_response.audio = []
|
|
8229
|
-
run_response.audio.append(audio)
|
|
8230
|
-
|
|
8231
|
-
def _add_file(self, file: File, run_response: RunOutput) -> None:
|
|
8232
|
-
"""Add file to both the agent's stateful storage and the current run response"""
|
|
8233
|
-
# Add to run response
|
|
8234
|
-
if run_response.files is None:
|
|
8235
|
-
run_response.files = []
|
|
8236
|
-
run_response.files.append(file)
|
|
8237
|
-
|
|
8238
8340
|
###########################################################################
|
|
8239
8341
|
# Reasoning
|
|
8240
8342
|
###########################################################################
|
|
@@ -8454,7 +8556,7 @@ class Agent:
|
|
|
8454
8556
|
store_events=self.store_events,
|
|
8455
8557
|
)
|
|
8456
8558
|
else:
|
|
8457
|
-
|
|
8559
|
+
log_info(
|
|
8458
8560
|
f"Reasoning model: {reasoning_model.__class__.__name__} is not a native reasoning model, defaulting to manual Chain-of-Thought reasoning"
|
|
8459
8561
|
)
|
|
8460
8562
|
use_default_reasoning = True
|
|
@@ -8747,7 +8849,7 @@ class Agent:
|
|
|
8747
8849
|
store_events=self.store_events,
|
|
8748
8850
|
)
|
|
8749
8851
|
else:
|
|
8750
|
-
|
|
8852
|
+
log_info(
|
|
8751
8853
|
f"Reasoning model: {reasoning_model.__class__.__name__} is not a native reasoning model, defaulting to manual Chain-of-Thought reasoning"
|
|
8752
8854
|
)
|
|
8753
8855
|
use_default_reasoning = True
|
|
@@ -10002,7 +10104,13 @@ class Agent:
|
|
|
10002
10104
|
|
|
10003
10105
|
return effective_filters
|
|
10004
10106
|
|
|
10005
|
-
def _cleanup_and_store(
|
|
10107
|
+
def _cleanup_and_store(
|
|
10108
|
+
self,
|
|
10109
|
+
run_response: RunOutput,
|
|
10110
|
+
session: AgentSession,
|
|
10111
|
+
run_context: Optional[RunContext] = None,
|
|
10112
|
+
user_id: Optional[str] = None,
|
|
10113
|
+
) -> None:
|
|
10006
10114
|
# Scrub the stored run based on storage flags
|
|
10007
10115
|
self._scrub_run_output_for_storage(run_response)
|
|
10008
10116
|
|
|
@@ -10010,6 +10118,11 @@ class Agent:
|
|
|
10010
10118
|
if run_response.metrics:
|
|
10011
10119
|
run_response.metrics.stop_timer()
|
|
10012
10120
|
|
|
10121
|
+
# Update run_response.session_state before saving
|
|
10122
|
+
# This ensures RunOutput reflects all tool modifications
|
|
10123
|
+
if session.session_data is not None and run_context is not None and run_context.session_state is not None:
|
|
10124
|
+
run_response.session_state = run_context.session_state
|
|
10125
|
+
|
|
10013
10126
|
# Optional: Save output to file if save_response_to_file is set
|
|
10014
10127
|
self.save_run_response_to_file(
|
|
10015
10128
|
run_response=run_response,
|
|
@@ -10028,7 +10141,11 @@ class Agent:
|
|
|
10028
10141
|
self.save_session(session=session)
|
|
10029
10142
|
|
|
10030
10143
|
async def _acleanup_and_store(
|
|
10031
|
-
self,
|
|
10144
|
+
self,
|
|
10145
|
+
run_response: RunOutput,
|
|
10146
|
+
session: AgentSession,
|
|
10147
|
+
run_context: Optional[RunContext] = None,
|
|
10148
|
+
user_id: Optional[str] = None,
|
|
10032
10149
|
) -> None:
|
|
10033
10150
|
# Scrub the stored run based on storage flags
|
|
10034
10151
|
self._scrub_run_output_for_storage(run_response)
|
|
@@ -10037,6 +10154,11 @@ class Agent:
|
|
|
10037
10154
|
if run_response.metrics:
|
|
10038
10155
|
run_response.metrics.stop_timer()
|
|
10039
10156
|
|
|
10157
|
+
# Update run_response.session_state from session before saving
|
|
10158
|
+
# This ensures RunOutput reflects all tool modifications
|
|
10159
|
+
if session.session_data is not None and run_context is not None and run_context.session_state is not None:
|
|
10160
|
+
run_response.session_state = run_context.session_state
|
|
10161
|
+
|
|
10040
10162
|
# Optional: Save output to file if save_response_to_file is set
|
|
10041
10163
|
self.save_run_response_to_file(
|
|
10042
10164
|
run_response=run_response,
|
|
@@ -10051,7 +10173,14 @@ class Agent:
|
|
|
10051
10173
|
# Calculate session metrics
|
|
10052
10174
|
self._update_session_metrics(session=session, run_response=run_response)
|
|
10053
10175
|
|
|
10054
|
-
#
|
|
10176
|
+
# Update session state before saving the session
|
|
10177
|
+
if run_context is not None and run_context.session_state is not None:
|
|
10178
|
+
if session.session_data is not None:
|
|
10179
|
+
session.session_data["session_state"] = run_context.session_state
|
|
10180
|
+
else:
|
|
10181
|
+
session.session_data = {"session_state": run_context.session_state}
|
|
10182
|
+
|
|
10183
|
+
# Save session to memory
|
|
10055
10184
|
await self.asave_session(session=session)
|
|
10056
10185
|
|
|
10057
10186
|
def _scrub_run_output_for_storage(self, run_response: RunOutput) -> None:
|
|
@@ -10067,58 +10196,6 @@ class Agent:
|
|
|
10067
10196
|
if not self.store_history_messages:
|
|
10068
10197
|
scrub_history_messages_from_run_output(run_response)
|
|
10069
10198
|
|
|
10070
|
-
def _validate_media_object_id(
|
|
10071
|
-
self,
|
|
10072
|
-
images: Optional[Sequence[Image]] = None,
|
|
10073
|
-
videos: Optional[Sequence[Video]] = None,
|
|
10074
|
-
audios: Optional[Sequence[Audio]] = None,
|
|
10075
|
-
files: Optional[Sequence[File]] = None,
|
|
10076
|
-
) -> tuple:
|
|
10077
|
-
"""Convert raw Image/Video/Audio objects - now unified, so just return as-is."""
|
|
10078
|
-
# With unified classes, no conversion needed - just ensure IDs are set
|
|
10079
|
-
image_list = None
|
|
10080
|
-
if images:
|
|
10081
|
-
image_list = []
|
|
10082
|
-
for img in images:
|
|
10083
|
-
# Ensure ID is set (validation should handle this, but double-check)
|
|
10084
|
-
if not img.id:
|
|
10085
|
-
from uuid import uuid4
|
|
10086
|
-
|
|
10087
|
-
img.id = str(uuid4())
|
|
10088
|
-
image_list.append(img)
|
|
10089
|
-
|
|
10090
|
-
video_list = None
|
|
10091
|
-
if videos:
|
|
10092
|
-
video_list = []
|
|
10093
|
-
for vid in videos:
|
|
10094
|
-
if not vid.id:
|
|
10095
|
-
from uuid import uuid4
|
|
10096
|
-
|
|
10097
|
-
vid.id = str(uuid4())
|
|
10098
|
-
video_list.append(vid)
|
|
10099
|
-
|
|
10100
|
-
audio_list = None
|
|
10101
|
-
if audios:
|
|
10102
|
-
audio_list = []
|
|
10103
|
-
for aud in audios:
|
|
10104
|
-
if not aud.id:
|
|
10105
|
-
from uuid import uuid4
|
|
10106
|
-
|
|
10107
|
-
aud.id = str(uuid4())
|
|
10108
|
-
audio_list.append(aud)
|
|
10109
|
-
|
|
10110
|
-
file_list = None
|
|
10111
|
-
if files:
|
|
10112
|
-
file_list = []
|
|
10113
|
-
for file in files:
|
|
10114
|
-
if not file.id:
|
|
10115
|
-
from uuid import uuid4
|
|
10116
|
-
|
|
10117
|
-
file.id = str(uuid4())
|
|
10118
|
-
file_list.append(file)
|
|
10119
|
-
|
|
10120
|
-
return image_list, video_list, audio_list, file_list
|
|
10121
|
-
|
|
10122
10199
|
def cli_app(
|
|
10123
10200
|
self,
|
|
10124
10201
|
input: Optional[str] = None,
|