agno 2.0.7__py3-none-any.whl → 2.0.9__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- agno/agent/agent.py +83 -51
- agno/db/base.py +14 -0
- agno/db/dynamo/dynamo.py +107 -27
- agno/db/firestore/firestore.py +109 -33
- agno/db/gcs_json/gcs_json_db.py +100 -20
- agno/db/in_memory/in_memory_db.py +95 -20
- agno/db/json/json_db.py +101 -21
- agno/db/migrations/v1_to_v2.py +322 -47
- agno/db/mongo/mongo.py +251 -26
- agno/db/mysql/mysql.py +307 -6
- agno/db/postgres/postgres.py +279 -33
- agno/db/redis/redis.py +99 -22
- agno/db/singlestore/singlestore.py +319 -38
- agno/db/sqlite/sqlite.py +339 -23
- agno/knowledge/embedder/sentence_transformer.py +3 -3
- agno/knowledge/knowledge.py +152 -31
- agno/knowledge/types.py +8 -0
- agno/models/anthropic/claude.py +0 -20
- agno/models/cometapi/__init__.py +5 -0
- agno/models/cometapi/cometapi.py +57 -0
- agno/models/google/gemini.py +4 -8
- agno/models/huggingface/huggingface.py +2 -1
- agno/models/ollama/chat.py +52 -3
- agno/models/openai/chat.py +9 -7
- agno/models/openai/responses.py +21 -17
- agno/os/interfaces/agui/agui.py +2 -2
- agno/os/interfaces/agui/utils.py +81 -18
- agno/os/interfaces/base.py +2 -0
- agno/os/interfaces/slack/router.py +50 -10
- agno/os/interfaces/slack/slack.py +6 -4
- agno/os/interfaces/whatsapp/router.py +7 -4
- agno/os/interfaces/whatsapp/whatsapp.py +2 -2
- agno/os/router.py +18 -0
- agno/os/utils.py +10 -2
- agno/reasoning/azure_ai_foundry.py +2 -2
- agno/reasoning/deepseek.py +2 -2
- agno/reasoning/default.py +3 -1
- agno/reasoning/groq.py +2 -2
- agno/reasoning/ollama.py +2 -2
- agno/reasoning/openai.py +2 -2
- agno/run/base.py +15 -2
- agno/session/agent.py +8 -5
- agno/session/team.py +14 -10
- agno/team/team.py +218 -111
- agno/tools/function.py +43 -4
- agno/tools/mcp.py +60 -37
- agno/tools/mcp_toolbox.py +284 -0
- agno/tools/scrapegraph.py +58 -31
- agno/tools/whatsapp.py +1 -1
- agno/utils/gemini.py +147 -19
- agno/utils/models/claude.py +9 -0
- agno/utils/print_response/agent.py +18 -2
- agno/utils/print_response/team.py +22 -6
- agno/utils/reasoning.py +22 -1
- agno/utils/string.py +9 -0
- agno/vectordb/base.py +2 -2
- agno/vectordb/langchaindb/langchaindb.py +5 -7
- agno/vectordb/llamaindex/llamaindexdb.py +25 -6
- agno/workflow/workflow.py +30 -15
- {agno-2.0.7.dist-info → agno-2.0.9.dist-info}/METADATA +4 -1
- {agno-2.0.7.dist-info → agno-2.0.9.dist-info}/RECORD +64 -61
- {agno-2.0.7.dist-info → agno-2.0.9.dist-info}/WHEEL +0 -0
- {agno-2.0.7.dist-info → agno-2.0.9.dist-info}/licenses/LICENSE +0 -0
- {agno-2.0.7.dist-info → agno-2.0.9.dist-info}/top_level.txt +0 -0
agno/team/team.py
CHANGED
|
@@ -33,6 +33,7 @@ from agno.agent import Agent
|
|
|
33
33
|
from agno.db.base import BaseDb, SessionType, UserMemory
|
|
34
34
|
from agno.exceptions import ModelProviderError, RunCancelledException
|
|
35
35
|
from agno.knowledge.knowledge import Knowledge
|
|
36
|
+
from agno.knowledge.types import KnowledgeFilter
|
|
36
37
|
from agno.media import Audio, File, Image, Video
|
|
37
38
|
from agno.memory import MemoryManager
|
|
38
39
|
from agno.models.base import Model
|
|
@@ -515,6 +516,11 @@ class Team:
|
|
|
515
516
|
self.num_history_runs = num_history_runs
|
|
516
517
|
self.metadata = metadata
|
|
517
518
|
|
|
519
|
+
if add_history_to_context and not db:
|
|
520
|
+
log_warning(
|
|
521
|
+
"add_history_to_context is True, but no database has been assigned to the agent. History will not be added to the context."
|
|
522
|
+
)
|
|
523
|
+
|
|
518
524
|
self.reasoning = reasoning
|
|
519
525
|
self.reasoning_model = reasoning_model
|
|
520
526
|
self.reasoning_agent = reasoning_agent
|
|
@@ -727,9 +733,19 @@ class Team:
|
|
|
727
733
|
if user_id is None:
|
|
728
734
|
user_id = self.user_id
|
|
729
735
|
|
|
730
|
-
# Determine the session_state
|
|
736
|
+
# Determine the session_state with proper precedence
|
|
731
737
|
if session_state is None:
|
|
732
738
|
session_state = self.session_state or {}
|
|
739
|
+
else:
|
|
740
|
+
# If run session_state is provided, merge agent defaults under it
|
|
741
|
+
# This ensures run state takes precedence over agent defaults
|
|
742
|
+
if self.session_state:
|
|
743
|
+
from agno.utils.merge_dict import merge_dictionaries
|
|
744
|
+
|
|
745
|
+
base_state = self.session_state.copy()
|
|
746
|
+
merge_dictionaries(base_state, session_state)
|
|
747
|
+
session_state.clear()
|
|
748
|
+
session_state.update(base_state)
|
|
733
749
|
|
|
734
750
|
if user_id is not None:
|
|
735
751
|
session_state["current_user_id"] = user_id
|
|
@@ -1231,7 +1247,9 @@ class Team:
|
|
|
1231
1247
|
workflow_context=workflow_context,
|
|
1232
1248
|
debug_mode=debug_mode,
|
|
1233
1249
|
add_history_to_context=add_history,
|
|
1250
|
+
add_session_state_to_context=add_session_state,
|
|
1234
1251
|
dependencies=run_dependencies,
|
|
1252
|
+
add_dependencies_to_context=add_dependencies,
|
|
1235
1253
|
metadata=metadata,
|
|
1236
1254
|
)
|
|
1237
1255
|
|
|
@@ -1849,6 +1867,8 @@ class Team:
|
|
|
1849
1867
|
workflow_context=workflow_context,
|
|
1850
1868
|
debug_mode=debug_mode,
|
|
1851
1869
|
add_history_to_context=add_history_to_context,
|
|
1870
|
+
add_dependencies_to_context=add_dependencies_to_context,
|
|
1871
|
+
add_session_state_to_context=add_session_state_to_context,
|
|
1852
1872
|
dependencies=dependencies,
|
|
1853
1873
|
metadata=metadata,
|
|
1854
1874
|
)
|
|
@@ -2017,9 +2037,6 @@ class Team:
|
|
|
2017
2037
|
if model_response.audio is not None:
|
|
2018
2038
|
run_response.response_audio = model_response.audio
|
|
2019
2039
|
|
|
2020
|
-
# Update the run_response created_at with the model response created_at
|
|
2021
|
-
run_response.created_at = model_response.created_at
|
|
2022
|
-
|
|
2023
2040
|
# Build a list of messages that should be added to the RunOutput
|
|
2024
2041
|
messages_for_run_response = [m for m in run_messages.messages if m.add_to_agent_memory]
|
|
2025
2042
|
|
|
@@ -2079,7 +2096,6 @@ class Team:
|
|
|
2079
2096
|
)
|
|
2080
2097
|
|
|
2081
2098
|
# 3. Update TeamRunOutput
|
|
2082
|
-
run_response.created_at = full_model_response.created_at
|
|
2083
2099
|
if full_model_response.content is not None:
|
|
2084
2100
|
run_response.content = full_model_response.content
|
|
2085
2101
|
if full_model_response.reasoning_content is not None:
|
|
@@ -2169,7 +2185,6 @@ class Team:
|
|
|
2169
2185
|
run_response.content = full_model_response.parsed
|
|
2170
2186
|
|
|
2171
2187
|
# Update TeamRunOutput
|
|
2172
|
-
run_response.created_at = full_model_response.created_at
|
|
2173
2188
|
if full_model_response.content is not None:
|
|
2174
2189
|
run_response.content = full_model_response.content
|
|
2175
2190
|
if full_model_response.reasoning_content is not None:
|
|
@@ -2240,7 +2255,7 @@ class Team:
|
|
|
2240
2255
|
content_type = "str"
|
|
2241
2256
|
|
|
2242
2257
|
should_yield = False
|
|
2243
|
-
# Process content
|
|
2258
|
+
# Process content
|
|
2244
2259
|
if model_response_event.content is not None:
|
|
2245
2260
|
if parse_structured_output:
|
|
2246
2261
|
full_model_response.content = model_response_event.content
|
|
@@ -2256,7 +2271,31 @@ class Team:
|
|
|
2256
2271
|
full_model_response.content = (full_model_response.content or "") + model_response_event.content
|
|
2257
2272
|
should_yield = True
|
|
2258
2273
|
|
|
2259
|
-
# Process
|
|
2274
|
+
# Process reasoning content
|
|
2275
|
+
if model_response_event.reasoning_content is not None:
|
|
2276
|
+
full_model_response.reasoning_content = (
|
|
2277
|
+
full_model_response.reasoning_content or ""
|
|
2278
|
+
) + model_response_event.reasoning_content
|
|
2279
|
+
run_response.reasoning_content = full_model_response.reasoning_content
|
|
2280
|
+
should_yield = True
|
|
2281
|
+
|
|
2282
|
+
if model_response_event.redacted_reasoning_content is not None:
|
|
2283
|
+
if not full_model_response.reasoning_content:
|
|
2284
|
+
full_model_response.reasoning_content = model_response_event.redacted_reasoning_content
|
|
2285
|
+
else:
|
|
2286
|
+
full_model_response.reasoning_content += model_response_event.redacted_reasoning_content
|
|
2287
|
+
run_response.reasoning_content = full_model_response.reasoning_content
|
|
2288
|
+
should_yield = True
|
|
2289
|
+
|
|
2290
|
+
# Handle provider data (one chunk)
|
|
2291
|
+
if model_response_event.provider_data is not None:
|
|
2292
|
+
run_response.model_provider_data = model_response_event.provider_data
|
|
2293
|
+
|
|
2294
|
+
# Handle citations (one chunk)
|
|
2295
|
+
if model_response_event.citations is not None:
|
|
2296
|
+
run_response.citations = model_response_event.citations
|
|
2297
|
+
|
|
2298
|
+
# Process audio
|
|
2260
2299
|
if model_response_event.audio is not None:
|
|
2261
2300
|
if full_model_response.audio is None:
|
|
2262
2301
|
full_model_response.audio = Audio(id=str(uuid4()), content=b"", transcript="")
|
|
@@ -2807,7 +2846,6 @@ class Team:
|
|
|
2807
2846
|
|
|
2808
2847
|
# Update the TeamRunResponse content
|
|
2809
2848
|
run_response.content = model_response.content
|
|
2810
|
-
run_response.created_at = model_response.created_at
|
|
2811
2849
|
|
|
2812
2850
|
if stream_intermediate_steps:
|
|
2813
2851
|
yield self._handle_event(create_team_output_model_response_completed_event(run_response), run_response)
|
|
@@ -2865,7 +2903,6 @@ class Team:
|
|
|
2865
2903
|
|
|
2866
2904
|
# Update the TeamRunResponse content
|
|
2867
2905
|
run_response.content = model_response.content
|
|
2868
|
-
run_response.created_at = model_response.created_at
|
|
2869
2906
|
|
|
2870
2907
|
if stream_intermediate_steps:
|
|
2871
2908
|
yield self._handle_event(create_team_output_model_response_completed_event(run_response), run_response)
|
|
@@ -2911,11 +2948,6 @@ class Team:
|
|
|
2911
2948
|
session_id: Optional[str] = None,
|
|
2912
2949
|
session_state: Optional[Dict[str, Any]] = None,
|
|
2913
2950
|
user_id: Optional[str] = None,
|
|
2914
|
-
show_message: bool = True,
|
|
2915
|
-
show_reasoning: bool = True,
|
|
2916
|
-
show_full_reasoning: bool = False,
|
|
2917
|
-
console: Optional[Any] = None,
|
|
2918
|
-
tags_to_include_in_markdown: Optional[Set[str]] = None,
|
|
2919
2951
|
audio: Optional[Sequence[Audio]] = None,
|
|
2920
2952
|
images: Optional[Sequence[Image]] = None,
|
|
2921
2953
|
videos: Optional[Sequence[Video]] = None,
|
|
@@ -2923,9 +2955,16 @@ class Team:
|
|
|
2923
2955
|
markdown: Optional[bool] = None,
|
|
2924
2956
|
knowledge_filters: Optional[Dict[str, Any]] = None,
|
|
2925
2957
|
add_history_to_context: Optional[bool] = None,
|
|
2958
|
+
add_dependencies_to_context: Optional[bool] = None,
|
|
2959
|
+
add_session_state_to_context: Optional[bool] = None,
|
|
2926
2960
|
dependencies: Optional[Dict[str, Any]] = None,
|
|
2927
2961
|
metadata: Optional[Dict[str, Any]] = None,
|
|
2928
2962
|
debug_mode: Optional[bool] = None,
|
|
2963
|
+
show_message: bool = True,
|
|
2964
|
+
show_reasoning: bool = True,
|
|
2965
|
+
show_full_reasoning: bool = False,
|
|
2966
|
+
console: Optional[Any] = None,
|
|
2967
|
+
tags_to_include_in_markdown: Optional[Set[str]] = None,
|
|
2929
2968
|
**kwargs: Any,
|
|
2930
2969
|
) -> None:
|
|
2931
2970
|
if not tags_to_include_in_markdown:
|
|
@@ -2964,6 +3003,8 @@ class Team:
|
|
|
2964
3003
|
knowledge_filters=knowledge_filters,
|
|
2965
3004
|
add_history_to_context=add_history_to_context,
|
|
2966
3005
|
dependencies=dependencies,
|
|
3006
|
+
add_dependencies_to_context=add_dependencies_to_context,
|
|
3007
|
+
add_session_state_to_context=add_session_state_to_context,
|
|
2967
3008
|
metadata=metadata,
|
|
2968
3009
|
debug_mode=debug_mode,
|
|
2969
3010
|
**kwargs,
|
|
@@ -2988,6 +3029,8 @@ class Team:
|
|
|
2988
3029
|
knowledge_filters=knowledge_filters,
|
|
2989
3030
|
add_history_to_context=add_history_to_context,
|
|
2990
3031
|
dependencies=dependencies,
|
|
3032
|
+
add_dependencies_to_context=add_dependencies_to_context,
|
|
3033
|
+
add_session_state_to_context=add_session_state_to_context,
|
|
2991
3034
|
metadata=metadata,
|
|
2992
3035
|
debug_mode=debug_mode,
|
|
2993
3036
|
**kwargs,
|
|
@@ -3002,11 +3045,6 @@ class Team:
|
|
|
3002
3045
|
session_id: Optional[str] = None,
|
|
3003
3046
|
session_state: Optional[Dict[str, Any]] = None,
|
|
3004
3047
|
user_id: Optional[str] = None,
|
|
3005
|
-
show_message: bool = True,
|
|
3006
|
-
show_reasoning: bool = True,
|
|
3007
|
-
show_full_reasoning: bool = False,
|
|
3008
|
-
console: Optional[Any] = None,
|
|
3009
|
-
tags_to_include_in_markdown: Optional[Set[str]] = None,
|
|
3010
3048
|
audio: Optional[Sequence[Audio]] = None,
|
|
3011
3049
|
images: Optional[Sequence[Image]] = None,
|
|
3012
3050
|
videos: Optional[Sequence[Video]] = None,
|
|
@@ -3015,8 +3053,15 @@ class Team:
|
|
|
3015
3053
|
knowledge_filters: Optional[Dict[str, Any]] = None,
|
|
3016
3054
|
add_history_to_context: Optional[bool] = None,
|
|
3017
3055
|
dependencies: Optional[Dict[str, Any]] = None,
|
|
3056
|
+
add_dependencies_to_context: Optional[bool] = None,
|
|
3057
|
+
add_session_state_to_context: Optional[bool] = None,
|
|
3018
3058
|
metadata: Optional[Dict[str, Any]] = None,
|
|
3019
3059
|
debug_mode: Optional[bool] = None,
|
|
3060
|
+
show_message: bool = True,
|
|
3061
|
+
show_reasoning: bool = True,
|
|
3062
|
+
show_full_reasoning: bool = False,
|
|
3063
|
+
console: Optional[Any] = None,
|
|
3064
|
+
tags_to_include_in_markdown: Optional[Set[str]] = None,
|
|
3020
3065
|
**kwargs: Any,
|
|
3021
3066
|
) -> None:
|
|
3022
3067
|
if not tags_to_include_in_markdown:
|
|
@@ -3055,6 +3100,8 @@ class Team:
|
|
|
3055
3100
|
knowledge_filters=knowledge_filters,
|
|
3056
3101
|
add_history_to_context=add_history_to_context,
|
|
3057
3102
|
dependencies=dependencies,
|
|
3103
|
+
add_dependencies_to_context=add_dependencies_to_context,
|
|
3104
|
+
add_session_state_to_context=add_session_state_to_context,
|
|
3058
3105
|
metadata=metadata,
|
|
3059
3106
|
debug_mode=debug_mode,
|
|
3060
3107
|
**kwargs,
|
|
@@ -3079,6 +3126,8 @@ class Team:
|
|
|
3079
3126
|
knowledge_filters=knowledge_filters,
|
|
3080
3127
|
add_history_to_context=add_history_to_context,
|
|
3081
3128
|
dependencies=dependencies,
|
|
3129
|
+
add_dependencies_to_context=add_dependencies_to_context,
|
|
3130
|
+
add_session_state_to_context=add_session_state_to_context,
|
|
3082
3131
|
metadata=metadata,
|
|
3083
3132
|
debug_mode=debug_mode,
|
|
3084
3133
|
**kwargs,
|
|
@@ -3478,6 +3527,7 @@ class Team:
|
|
|
3478
3527
|
reasoning_model=reasoning_model,
|
|
3479
3528
|
min_steps=self.reasoning_min_steps,
|
|
3480
3529
|
max_steps=self.reasoning_max_steps,
|
|
3530
|
+
tool_call_limit=self.tool_call_limit,
|
|
3481
3531
|
telemetry=self.telemetry,
|
|
3482
3532
|
debug_mode=self.debug_mode,
|
|
3483
3533
|
debug_level=self.debug_level,
|
|
@@ -4005,6 +4055,7 @@ class Team:
|
|
|
4005
4055
|
add_history_to_context: Optional[bool] = None,
|
|
4006
4056
|
dependencies: Optional[Dict[str, Any]] = None,
|
|
4007
4057
|
add_dependencies_to_context: Optional[bool] = None,
|
|
4058
|
+
add_session_state_to_context: Optional[bool] = None,
|
|
4008
4059
|
metadata: Optional[Dict[str, Any]] = None,
|
|
4009
4060
|
) -> None:
|
|
4010
4061
|
# Prepare tools
|
|
@@ -4052,46 +4103,51 @@ class Team:
|
|
|
4052
4103
|
if self.knowledge is not None and self.update_knowledge:
|
|
4053
4104
|
_tools.append(self.add_to_knowledge)
|
|
4054
4105
|
|
|
4055
|
-
|
|
4056
|
-
|
|
4057
|
-
|
|
4058
|
-
|
|
4106
|
+
if self.members:
|
|
4107
|
+
# Get the user message if we are using the input directly
|
|
4108
|
+
user_message = None
|
|
4109
|
+
if self.determine_input_for_members is False:
|
|
4110
|
+
user_message = self._get_user_message(
|
|
4111
|
+
run_response=run_response,
|
|
4112
|
+
session_state=session_state,
|
|
4113
|
+
input_message=input_message,
|
|
4114
|
+
user_id=user_id,
|
|
4115
|
+
audio=audio,
|
|
4116
|
+
images=images,
|
|
4117
|
+
videos=videos,
|
|
4118
|
+
files=files,
|
|
4119
|
+
dependencies=dependencies,
|
|
4120
|
+
add_dependencies_to_context=add_dependencies_to_context,
|
|
4121
|
+
metadata=metadata,
|
|
4122
|
+
)
|
|
4123
|
+
|
|
4124
|
+
delegate_task_func = self._get_delegate_task_function(
|
|
4059
4125
|
run_response=run_response,
|
|
4126
|
+
session=session,
|
|
4060
4127
|
session_state=session_state,
|
|
4061
|
-
|
|
4128
|
+
team_run_context=team_run_context,
|
|
4129
|
+
input=user_message,
|
|
4062
4130
|
user_id=user_id,
|
|
4063
|
-
|
|
4064
|
-
|
|
4065
|
-
|
|
4066
|
-
|
|
4131
|
+
stream=self.stream or False,
|
|
4132
|
+
stream_intermediate_steps=self.stream_intermediate_steps,
|
|
4133
|
+
async_mode=async_mode,
|
|
4134
|
+
images=images, # type: ignore
|
|
4135
|
+
videos=videos, # type: ignore
|
|
4136
|
+
audio=audio, # type: ignore
|
|
4137
|
+
files=files, # type: ignore
|
|
4138
|
+
knowledge_filters=knowledge_filters,
|
|
4139
|
+
add_history_to_context=add_history_to_context,
|
|
4140
|
+
workflow_context=workflow_context,
|
|
4067
4141
|
dependencies=dependencies,
|
|
4068
4142
|
add_dependencies_to_context=add_dependencies_to_context,
|
|
4143
|
+
add_session_state_to_context=add_session_state_to_context,
|
|
4069
4144
|
metadata=metadata,
|
|
4145
|
+
debug_mode=debug_mode,
|
|
4070
4146
|
)
|
|
4071
4147
|
|
|
4072
|
-
|
|
4073
|
-
|
|
4074
|
-
|
|
4075
|
-
session_state=session_state,
|
|
4076
|
-
team_run_context=team_run_context,
|
|
4077
|
-
input=user_message,
|
|
4078
|
-
user_id=user_id,
|
|
4079
|
-
stream=self.stream or False,
|
|
4080
|
-
stream_intermediate_steps=self.stream_intermediate_steps,
|
|
4081
|
-
async_mode=async_mode,
|
|
4082
|
-
images=images, # type: ignore
|
|
4083
|
-
videos=videos, # type: ignore
|
|
4084
|
-
audio=audio, # type: ignore
|
|
4085
|
-
files=files, # type: ignore
|
|
4086
|
-
knowledge_filters=knowledge_filters,
|
|
4087
|
-
workflow_context=workflow_context,
|
|
4088
|
-
debug_mode=debug_mode,
|
|
4089
|
-
add_history_to_context=add_history_to_context,
|
|
4090
|
-
)
|
|
4091
|
-
|
|
4092
|
-
_tools.append(delegate_task_func)
|
|
4093
|
-
if self.get_member_information_tool:
|
|
4094
|
-
_tools.append(self.get_member_information)
|
|
4148
|
+
_tools.append(delegate_task_func)
|
|
4149
|
+
if self.get_member_information_tool:
|
|
4150
|
+
_tools.append(self.get_member_information)
|
|
4095
4151
|
|
|
4096
4152
|
self._functions_for_model = {}
|
|
4097
4153
|
self._tools_for_model = []
|
|
@@ -4120,6 +4176,7 @@ class Team:
|
|
|
4120
4176
|
if name not in self._functions_for_model:
|
|
4121
4177
|
func._team = self
|
|
4122
4178
|
func._session_state = session_state
|
|
4179
|
+
func._dependencies = dependencies
|
|
4123
4180
|
func.process_entrypoint(strict=strict)
|
|
4124
4181
|
if strict:
|
|
4125
4182
|
func.strict = True
|
|
@@ -4139,6 +4196,7 @@ class Team:
|
|
|
4139
4196
|
if tool.name not in self._functions_for_model:
|
|
4140
4197
|
tool._team = self
|
|
4141
4198
|
tool._session_state = session_state
|
|
4199
|
+
tool._dependencies = dependencies
|
|
4142
4200
|
tool.process_entrypoint(strict=strict)
|
|
4143
4201
|
if strict and tool.strict is None:
|
|
4144
4202
|
tool.strict = True
|
|
@@ -4160,6 +4218,7 @@ class Team:
|
|
|
4160
4218
|
func = Function.from_callable(tool, strict=strict)
|
|
4161
4219
|
func._team = self
|
|
4162
4220
|
func._session_state = session_state
|
|
4221
|
+
func._dependencies = dependencies
|
|
4163
4222
|
if strict:
|
|
4164
4223
|
func.strict = True
|
|
4165
4224
|
if self.tool_hooks:
|
|
@@ -4355,42 +4414,43 @@ class Team:
|
|
|
4355
4414
|
|
|
4356
4415
|
# 2 Build the default system message for the Agent.
|
|
4357
4416
|
system_message_content: str = ""
|
|
4358
|
-
|
|
4359
|
-
|
|
4417
|
+
if self.members is not None and len(self.members) > 0:
|
|
4418
|
+
system_message_content += "You are the leader of a team and sub-teams of AI Agents.\n"
|
|
4419
|
+
system_message_content += "Your task is to coordinate the team to complete the user's request.\n"
|
|
4360
4420
|
|
|
4361
|
-
|
|
4362
|
-
|
|
4363
|
-
|
|
4364
|
-
|
|
4365
|
-
|
|
4366
|
-
|
|
4421
|
+
system_message_content += "\nHere are the members in your team:\n"
|
|
4422
|
+
system_message_content += "<team_members>\n"
|
|
4423
|
+
system_message_content += self.get_members_system_message_content()
|
|
4424
|
+
if self.get_member_information_tool:
|
|
4425
|
+
system_message_content += "If you need to get information about your team members, you can use the `get_member_information` tool at any time.\n"
|
|
4426
|
+
system_message_content += "</team_members>\n"
|
|
4367
4427
|
|
|
4368
|
-
|
|
4428
|
+
system_message_content += "\n<how_to_respond>\n"
|
|
4369
4429
|
|
|
4370
|
-
|
|
4371
|
-
|
|
4372
|
-
|
|
4373
|
-
|
|
4374
|
-
|
|
4375
|
-
|
|
4376
|
-
|
|
4377
|
-
|
|
4378
|
-
|
|
4379
|
-
|
|
4380
|
-
|
|
4381
|
-
|
|
4382
|
-
|
|
4383
|
-
|
|
4384
|
-
|
|
4385
|
-
|
|
4386
|
-
|
|
4387
|
-
|
|
4388
|
-
|
|
4389
|
-
|
|
4390
|
-
|
|
4391
|
-
|
|
4392
|
-
|
|
4393
|
-
|
|
4430
|
+
if self.delegate_task_to_all_members:
|
|
4431
|
+
system_message_content += (
|
|
4432
|
+
"- You can either respond directly or use the `delegate_task_to_members` tool to delegate a task to all members in your team to get a collaborative response.\n"
|
|
4433
|
+
"- To delegate a task to all members in your team, call `delegate_task_to_members` ONLY once. This will delegate a task to all members in your team.\n"
|
|
4434
|
+
"- Analyze the responses from all members and evaluate whether the task has been completed.\n"
|
|
4435
|
+
"- If you feel the task has been completed, you can stop and respond to the user.\n"
|
|
4436
|
+
)
|
|
4437
|
+
else:
|
|
4438
|
+
system_message_content += (
|
|
4439
|
+
"- Your role is to delegate tasks to members in your team with the highest likelihood of completing the user's request.\n"
|
|
4440
|
+
"- Carefully analyze the tools available to the members and their roles before delegating tasks.\n"
|
|
4441
|
+
"- You cannot use a member tool directly. You can only delegate tasks to members.\n"
|
|
4442
|
+
"- When you delegate a task to another member, make sure to include:\n"
|
|
4443
|
+
" - member_id (str): The ID of the member to delegate the task to. Use only the ID of the member, not the ID of the team followed by the ID of the member.\n"
|
|
4444
|
+
" - task_description (str): A clear description of the task.\n"
|
|
4445
|
+
" - expected_output (str): The expected output.\n"
|
|
4446
|
+
"- You can delegate tasks to multiple members at once.\n"
|
|
4447
|
+
"- You must always analyze the responses from members before responding to the user.\n"
|
|
4448
|
+
"- After analyzing the responses from the members, if you feel the task has been completed, you can stop and respond to the user.\n"
|
|
4449
|
+
"- If you are not satisfied with the responses from the members, you should re-assign the task.\n"
|
|
4450
|
+
"- For simple greetings, thanks, or questions about the team itself, you should respond directly.\n"
|
|
4451
|
+
"- For all work requests, tasks, or questions requiring expertise, route to appropriate team members.\n"
|
|
4452
|
+
)
|
|
4453
|
+
system_message_content += "</how_to_respond>\n\n"
|
|
4394
4454
|
|
|
4395
4455
|
# Attached media
|
|
4396
4456
|
if audio is not None or images is not None or videos is not None or files is not None:
|
|
@@ -4506,7 +4566,7 @@ class Team:
|
|
|
4506
4566
|
f"<additional_context>\n{self.additional_context.strip()}\n</additional_context>\n\n"
|
|
4507
4567
|
)
|
|
4508
4568
|
|
|
4509
|
-
if
|
|
4569
|
+
if add_session_state_to_context and session_state is not None:
|
|
4510
4570
|
system_message_content += self._get_formatted_session_state_for_system_message(session_state)
|
|
4511
4571
|
|
|
4512
4572
|
# Add the JSON output prompt if output_schema is provided and structured_outputs is False
|
|
@@ -4607,9 +4667,16 @@ class Team:
|
|
|
4607
4667
|
if add_history_to_context:
|
|
4608
4668
|
from copy import deepcopy
|
|
4609
4669
|
|
|
4670
|
+
# Only skip messages from history when system_message_role is NOT a standard conversation role.
|
|
4671
|
+
# Standard conversation roles ("user", "assistant", "tool") should never be filtered
|
|
4672
|
+
# to preserve conversation continuity.
|
|
4673
|
+
skip_role = (
|
|
4674
|
+
self.system_message_role if self.system_message_role not in ["user", "assistant", "tool"] else None
|
|
4675
|
+
)
|
|
4676
|
+
|
|
4610
4677
|
history = session.get_messages_from_last_n_runs(
|
|
4611
4678
|
last_n=self.num_history_runs,
|
|
4612
|
-
skip_role=
|
|
4679
|
+
skip_role=skip_role,
|
|
4613
4680
|
team_id=self.id,
|
|
4614
4681
|
)
|
|
4615
4682
|
|
|
@@ -4693,6 +4760,9 @@ class Team:
|
|
|
4693
4760
|
if len(input_message) > 0 and isinstance(input_message[0], dict) and "type" in input_message[0]:
|
|
4694
4761
|
# This is multimodal content (text + images/audio/video), preserve the structure
|
|
4695
4762
|
input_content = input_message
|
|
4763
|
+
elif len(input_message) > 0 and isinstance(input_message[0], Message):
|
|
4764
|
+
# This is a list of Message objects, extract text content from them
|
|
4765
|
+
input_content = get_text_from_message(input_message)
|
|
4696
4766
|
elif all(isinstance(item, str) for item in input_message):
|
|
4697
4767
|
input_content = "\n".join([str(item) for item in input_message])
|
|
4698
4768
|
else:
|
|
@@ -5130,9 +5200,14 @@ class Team:
|
|
|
5130
5200
|
member_agent_id = member_agent.id if isinstance(member_agent, Agent) else None
|
|
5131
5201
|
member_team_id = member_agent.id if isinstance(member_agent, Team) else None
|
|
5132
5202
|
|
|
5203
|
+
# Only skip messages from history when system_message_role is NOT a standard conversation role.
|
|
5204
|
+
# Standard conversation roles ("user", "assistant", "tool") should never be filtered
|
|
5205
|
+
# to preserve conversation continuity.
|
|
5206
|
+
skip_role = self.system_message_role if self.system_message_role not in ["user", "assistant", "tool"] else None
|
|
5207
|
+
|
|
5133
5208
|
history = session.get_messages_from_last_n_runs(
|
|
5134
5209
|
last_n=member_agent.num_history_runs or self.num_history_runs,
|
|
5135
|
-
skip_role=
|
|
5210
|
+
skip_role=skip_role,
|
|
5136
5211
|
agent_id=member_agent_id,
|
|
5137
5212
|
team_id=member_team_id,
|
|
5138
5213
|
member_runs=True,
|
|
@@ -5206,9 +5281,13 @@ class Team:
|
|
|
5206
5281
|
audio: Optional[List[Audio]] = None,
|
|
5207
5282
|
files: Optional[List[File]] = None,
|
|
5208
5283
|
knowledge_filters: Optional[Dict[str, Any]] = None,
|
|
5284
|
+
add_history_to_context: Optional[bool] = None,
|
|
5209
5285
|
workflow_context: Optional[Dict] = None,
|
|
5286
|
+
dependencies: Optional[Dict[str, Any]] = None,
|
|
5287
|
+
add_dependencies_to_context: Optional[bool] = None,
|
|
5288
|
+
add_session_state_to_context: Optional[bool] = None,
|
|
5289
|
+
metadata: Optional[Dict[str, Any]] = None,
|
|
5210
5290
|
debug_mode: Optional[bool] = None,
|
|
5211
|
-
add_history_to_context: Optional[bool] = None,
|
|
5212
5291
|
) -> Function:
|
|
5213
5292
|
if not images:
|
|
5214
5293
|
images = []
|
|
@@ -5244,9 +5323,9 @@ class Team:
|
|
|
5244
5323
|
task_description, expected_output, team_member_interactions_str
|
|
5245
5324
|
)
|
|
5246
5325
|
|
|
5247
|
-
# 4. Add history for the member if enabled
|
|
5326
|
+
# 4. Add history for the member if enabled (because we won't load the session for the member, so history won't be loaded automatically)
|
|
5248
5327
|
history = None
|
|
5249
|
-
if member_agent.add_history_to_context:
|
|
5328
|
+
if member_agent.add_history_to_context or add_history_to_context:
|
|
5250
5329
|
history = self._get_history_for_member_agent(session, member_agent)
|
|
5251
5330
|
if history:
|
|
5252
5331
|
if isinstance(member_agent_task, str):
|
|
@@ -5358,8 +5437,11 @@ class Team:
|
|
|
5358
5437
|
stream=True,
|
|
5359
5438
|
stream_intermediate_steps=stream_intermediate_steps,
|
|
5360
5439
|
debug_mode=debug_mode,
|
|
5361
|
-
add_history_to_context=add_history_to_context,
|
|
5362
5440
|
workflow_context=workflow_context,
|
|
5441
|
+
dependencies=dependencies,
|
|
5442
|
+
add_dependencies_to_context=add_dependencies_to_context,
|
|
5443
|
+
metadata=metadata,
|
|
5444
|
+
add_session_state_to_context=add_session_state_to_context,
|
|
5363
5445
|
knowledge_filters=knowledge_filters
|
|
5364
5446
|
if not member_agent.knowledge_filters and member_agent.knowledge
|
|
5365
5447
|
else None,
|
|
@@ -5393,7 +5475,10 @@ class Team:
|
|
|
5393
5475
|
stream=False,
|
|
5394
5476
|
debug_mode=debug_mode,
|
|
5395
5477
|
workflow_context=workflow_context,
|
|
5396
|
-
|
|
5478
|
+
dependencies=dependencies,
|
|
5479
|
+
add_dependencies_to_context=add_dependencies_to_context,
|
|
5480
|
+
add_session_state_to_context=add_session_state_to_context,
|
|
5481
|
+
metadata=metadata,
|
|
5397
5482
|
knowledge_filters=knowledge_filters
|
|
5398
5483
|
if not member_agent.knowledge_filters and member_agent.knowledge
|
|
5399
5484
|
else None,
|
|
@@ -5477,7 +5562,10 @@ class Team:
|
|
|
5477
5562
|
stream=True,
|
|
5478
5563
|
stream_intermediate_steps=stream_intermediate_steps,
|
|
5479
5564
|
debug_mode=debug_mode,
|
|
5480
|
-
|
|
5565
|
+
dependencies=dependencies,
|
|
5566
|
+
add_dependencies_to_context=add_dependencies_to_context,
|
|
5567
|
+
add_session_state_to_context=add_session_state_to_context,
|
|
5568
|
+
metadata=metadata,
|
|
5481
5569
|
workflow_context=workflow_context,
|
|
5482
5570
|
knowledge_filters=knowledge_filters
|
|
5483
5571
|
if not member_agent.knowledge_filters and member_agent.knowledge
|
|
@@ -5512,7 +5600,10 @@ class Team:
|
|
|
5512
5600
|
stream=False,
|
|
5513
5601
|
debug_mode=debug_mode,
|
|
5514
5602
|
workflow_context=workflow_context,
|
|
5515
|
-
|
|
5603
|
+
dependencies=dependencies,
|
|
5604
|
+
add_dependencies_to_context=add_dependencies_to_context,
|
|
5605
|
+
add_session_state_to_context=add_session_state_to_context,
|
|
5606
|
+
metadata=metadata,
|
|
5516
5607
|
knowledge_filters=knowledge_filters
|
|
5517
5608
|
if not member_agent.knowledge_filters and member_agent.knowledge
|
|
5518
5609
|
else None,
|
|
@@ -5590,7 +5681,10 @@ class Team:
|
|
|
5590
5681
|
if not member_agent.knowledge_filters and member_agent.knowledge
|
|
5591
5682
|
else None,
|
|
5592
5683
|
debug_mode=debug_mode,
|
|
5593
|
-
|
|
5684
|
+
dependencies=dependencies,
|
|
5685
|
+
add_dependencies_to_context=add_dependencies_to_context,
|
|
5686
|
+
add_session_state_to_context=add_session_state_to_context,
|
|
5687
|
+
metadata=metadata,
|
|
5594
5688
|
yield_run_response=True,
|
|
5595
5689
|
)
|
|
5596
5690
|
member_agent_run_response = None
|
|
@@ -5625,7 +5719,10 @@ class Team:
|
|
|
5625
5719
|
if not member_agent.knowledge_filters and member_agent.knowledge
|
|
5626
5720
|
else None,
|
|
5627
5721
|
debug_mode=debug_mode,
|
|
5628
|
-
|
|
5722
|
+
dependencies=dependencies,
|
|
5723
|
+
add_dependencies_to_context=add_dependencies_to_context,
|
|
5724
|
+
add_session_state_to_context=add_session_state_to_context,
|
|
5725
|
+
metadata=metadata,
|
|
5629
5726
|
)
|
|
5630
5727
|
|
|
5631
5728
|
check_if_run_cancelled(member_agent_run_response) # type: ignore
|
|
@@ -5699,7 +5796,10 @@ class Team:
|
|
|
5699
5796
|
knowledge_filters=knowledge_filters
|
|
5700
5797
|
if not member_agent.knowledge_filters and member_agent.knowledge
|
|
5701
5798
|
else None,
|
|
5702
|
-
|
|
5799
|
+
dependencies=dependencies,
|
|
5800
|
+
add_dependencies_to_context=add_dependencies_to_context,
|
|
5801
|
+
add_session_state_to_context=add_session_state_to_context,
|
|
5802
|
+
metadata=metadata,
|
|
5703
5803
|
yield_run_response=True,
|
|
5704
5804
|
)
|
|
5705
5805
|
member_agent_run_response = None
|
|
@@ -5716,6 +5816,7 @@ class Team:
|
|
|
5716
5816
|
_process_delegate_task_to_member(
|
|
5717
5817
|
member_agent_run_response, member_agent, member_agent_task, member_session_state_copy
|
|
5718
5818
|
)
|
|
5819
|
+
await queue.put(done_marker)
|
|
5719
5820
|
|
|
5720
5821
|
# Initialize and launch all members
|
|
5721
5822
|
tasks: List[asyncio.Task[None]] = []
|
|
@@ -5743,7 +5844,6 @@ class Team:
|
|
|
5743
5844
|
for t in tasks:
|
|
5744
5845
|
with contextlib.suppress(Exception):
|
|
5745
5846
|
await t
|
|
5746
|
-
|
|
5747
5847
|
else:
|
|
5748
5848
|
# Non-streaming concurrent run of members; collect results when done
|
|
5749
5849
|
tasks = []
|
|
@@ -5773,7 +5873,10 @@ class Team:
|
|
|
5773
5873
|
knowledge_filters=knowledge_filters
|
|
5774
5874
|
if not member_agent.knowledge_filters and member_agent.knowledge
|
|
5775
5875
|
else None,
|
|
5776
|
-
|
|
5876
|
+
dependencies=dependencies,
|
|
5877
|
+
add_dependencies_to_context=add_dependencies_to_context,
|
|
5878
|
+
add_session_state_to_context=add_session_state_to_context,
|
|
5879
|
+
metadata=metadata,
|
|
5777
5880
|
)
|
|
5778
5881
|
check_if_run_cancelled(member_agent_run_response)
|
|
5779
5882
|
|
|
@@ -6006,7 +6109,8 @@ class Team:
|
|
|
6006
6109
|
|
|
6007
6110
|
from agno.utils.merge_dict import merge_dictionaries
|
|
6008
6111
|
|
|
6009
|
-
# Get the session_state from the database and
|
|
6112
|
+
# Get the session_state from the database and merge with proper precedence
|
|
6113
|
+
# At this point session_state contains: agent_defaults + run_params
|
|
6010
6114
|
if session.session_data is not None and "session_state" in session.session_data:
|
|
6011
6115
|
session_state_from_db = session.session_data.get("session_state")
|
|
6012
6116
|
|
|
@@ -6015,10 +6119,11 @@ class Team:
|
|
|
6015
6119
|
and isinstance(session_state_from_db, dict)
|
|
6016
6120
|
and len(session_state_from_db) > 0
|
|
6017
6121
|
):
|
|
6018
|
-
# This
|
|
6019
|
-
|
|
6020
|
-
merge_dictionaries(
|
|
6021
|
-
session_state
|
|
6122
|
+
# This preserves precedence: run_params > db_state > agent_defaults
|
|
6123
|
+
merged_state = session_state_from_db.copy()
|
|
6124
|
+
merge_dictionaries(merged_state, session_state)
|
|
6125
|
+
session_state.clear()
|
|
6126
|
+
session_state.update(merged_state)
|
|
6022
6127
|
|
|
6023
6128
|
# Update the session_state in the session
|
|
6024
6129
|
if session.session_data is not None:
|
|
@@ -6656,17 +6761,18 @@ class Team:
|
|
|
6656
6761
|
) -> Function:
|
|
6657
6762
|
"""Factory function to create a search_knowledge_base function with filters."""
|
|
6658
6763
|
|
|
6659
|
-
def search_knowledge_base(query: str, filters: Optional[
|
|
6764
|
+
def search_knowledge_base(query: str, filters: Optional[List[KnowledgeFilter]] = None) -> str:
|
|
6660
6765
|
"""Use this function to search the knowledge base for information about a query.
|
|
6661
6766
|
|
|
6662
6767
|
Args:
|
|
6663
6768
|
query: The query to search for.
|
|
6664
|
-
filters: The filters to apply to the search. This is a
|
|
6769
|
+
filters (optional): The filters to apply to the search. This is a list of KnowledgeFilter objects.
|
|
6665
6770
|
|
|
6666
6771
|
Returns:
|
|
6667
6772
|
str: A string containing the response from the knowledge base.
|
|
6668
6773
|
"""
|
|
6669
|
-
|
|
6774
|
+
filters_dict = {filt.key: filt.value for filt in filters} if filters else None
|
|
6775
|
+
search_filters = get_agentic_or_user_search_filters(filters_dict, knowledge_filters)
|
|
6670
6776
|
|
|
6671
6777
|
# Get the relevant documents from the knowledge base, passing filters
|
|
6672
6778
|
retrieval_timer = Timer()
|
|
@@ -6687,17 +6793,18 @@ class Team:
|
|
|
6687
6793
|
return "No documents found"
|
|
6688
6794
|
return self._convert_documents_to_string(docs_from_knowledge)
|
|
6689
6795
|
|
|
6690
|
-
async def asearch_knowledge_base(query: str, filters: Optional[
|
|
6796
|
+
async def asearch_knowledge_base(query: str, filters: Optional[List[KnowledgeFilter]] = None) -> str:
|
|
6691
6797
|
"""Use this function to search the knowledge base for information about a query asynchronously.
|
|
6692
6798
|
|
|
6693
6799
|
Args:
|
|
6694
6800
|
query: The query to search for.
|
|
6695
|
-
filters: The filters to apply to the search. This is a
|
|
6801
|
+
filters (optional): The filters to apply to the search. This is a list of KnowledgeFilter objects.
|
|
6696
6802
|
|
|
6697
6803
|
Returns:
|
|
6698
6804
|
str: A string containing the response from the knowledge base.
|
|
6699
6805
|
"""
|
|
6700
|
-
|
|
6806
|
+
filters_dict = {filt.key: filt.value for filt in filters} if filters else None
|
|
6807
|
+
search_filters = get_agentic_or_user_search_filters(filters_dict, knowledge_filters)
|
|
6701
6808
|
|
|
6702
6809
|
retrieval_timer = Timer()
|
|
6703
6810
|
retrieval_timer.start()
|