agno 2.0.6__py3-none-any.whl → 2.0.8__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 +94 -48
- agno/db/migrations/v1_to_v2.py +140 -11
- agno/knowledge/chunking/semantic.py +33 -6
- agno/knowledge/embedder/sentence_transformer.py +3 -3
- agno/knowledge/knowledge.py +152 -31
- agno/knowledge/types.py +8 -0
- agno/media.py +2 -0
- agno/models/base.py +38 -9
- agno/models/cometapi/__init__.py +5 -0
- agno/models/cometapi/cometapi.py +57 -0
- agno/models/google/gemini.py +4 -8
- agno/models/llama_cpp/__init__.py +5 -0
- agno/models/llama_cpp/llama_cpp.py +22 -0
- agno/models/nexus/__init__.py +1 -1
- agno/models/nexus/nexus.py +2 -5
- agno/models/ollama/chat.py +24 -1
- agno/models/openai/chat.py +2 -7
- agno/models/openai/responses.py +21 -17
- agno/os/app.py +4 -10
- agno/os/interfaces/agui/agui.py +2 -2
- agno/os/interfaces/agui/utils.py +81 -18
- agno/os/interfaces/slack/slack.py +2 -2
- agno/os/interfaces/whatsapp/whatsapp.py +2 -2
- agno/os/router.py +3 -4
- agno/os/routers/evals/evals.py +1 -1
- agno/os/routers/memory/memory.py +1 -1
- agno/os/schema.py +3 -4
- agno/os/utils.py +55 -12
- agno/reasoning/default.py +3 -1
- agno/run/agent.py +4 -0
- agno/run/team.py +3 -1
- agno/session/agent.py +8 -5
- agno/session/team.py +14 -10
- agno/team/team.py +239 -115
- agno/tools/decorator.py +4 -2
- agno/tools/function.py +43 -4
- agno/tools/mcp.py +61 -38
- agno/tools/memori.py +1 -53
- agno/utils/events.py +7 -1
- agno/utils/gemini.py +147 -19
- agno/utils/models/claude.py +9 -0
- agno/utils/print_response/agent.py +16 -0
- agno/utils/print_response/team.py +16 -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 +59 -15
- {agno-2.0.6.dist-info → agno-2.0.8.dist-info}/METADATA +1 -1
- {agno-2.0.6.dist-info → agno-2.0.8.dist-info}/RECORD +52 -48
- {agno-2.0.6.dist-info → agno-2.0.8.dist-info}/WHEEL +0 -0
- {agno-2.0.6.dist-info → agno-2.0.8.dist-info}/licenses/LICENSE +0 -0
- {agno-2.0.6.dist-info → agno-2.0.8.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
|
|
@@ -829,6 +845,7 @@ class Team:
|
|
|
829
845
|
functions=self._functions_for_model,
|
|
830
846
|
tool_choice=self.tool_choice,
|
|
831
847
|
tool_call_limit=self.tool_call_limit,
|
|
848
|
+
send_media_to_model=self.send_media_to_model,
|
|
832
849
|
)
|
|
833
850
|
|
|
834
851
|
# Check for cancellation after model call
|
|
@@ -1230,7 +1247,9 @@ class Team:
|
|
|
1230
1247
|
workflow_context=workflow_context,
|
|
1231
1248
|
debug_mode=debug_mode,
|
|
1232
1249
|
add_history_to_context=add_history,
|
|
1250
|
+
add_session_state_to_context=add_session_state,
|
|
1233
1251
|
dependencies=run_dependencies,
|
|
1252
|
+
add_dependencies_to_context=add_dependencies,
|
|
1234
1253
|
metadata=metadata,
|
|
1235
1254
|
)
|
|
1236
1255
|
|
|
@@ -1415,6 +1434,7 @@ class Team:
|
|
|
1415
1434
|
tool_choice=self.tool_choice,
|
|
1416
1435
|
tool_call_limit=self.tool_call_limit,
|
|
1417
1436
|
response_format=response_format,
|
|
1437
|
+
send_media_to_model=self.send_media_to_model,
|
|
1418
1438
|
) # type: ignore
|
|
1419
1439
|
|
|
1420
1440
|
# Check for cancellation after model call
|
|
@@ -1847,6 +1867,8 @@ class Team:
|
|
|
1847
1867
|
workflow_context=workflow_context,
|
|
1848
1868
|
debug_mode=debug_mode,
|
|
1849
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,
|
|
1850
1872
|
dependencies=dependencies,
|
|
1851
1873
|
metadata=metadata,
|
|
1852
1874
|
)
|
|
@@ -1997,7 +2019,9 @@ class Team:
|
|
|
1997
2019
|
run_response.reasoning_content = model_response.reasoning_content
|
|
1998
2020
|
else:
|
|
1999
2021
|
run_response.reasoning_content += model_response.reasoning_content
|
|
2000
|
-
|
|
2022
|
+
# Update provider data
|
|
2023
|
+
if model_response.provider_data is not None:
|
|
2024
|
+
run_response.model_provider_data = model_response.provider_data
|
|
2001
2025
|
# Update citations
|
|
2002
2026
|
if model_response.citations is not None:
|
|
2003
2027
|
run_response.citations = model_response.citations
|
|
@@ -2061,6 +2085,7 @@ class Team:
|
|
|
2061
2085
|
tool_choice=self.tool_choice,
|
|
2062
2086
|
tool_call_limit=self.tool_call_limit,
|
|
2063
2087
|
stream_model_response=stream_model_response,
|
|
2088
|
+
send_media_to_model=self.send_media_to_model,
|
|
2064
2089
|
):
|
|
2065
2090
|
yield from self._handle_model_response_chunk(
|
|
2066
2091
|
session=session,
|
|
@@ -2083,6 +2108,8 @@ class Team:
|
|
|
2083
2108
|
run_response.response_audio = full_model_response.audio
|
|
2084
2109
|
if full_model_response.citations is not None:
|
|
2085
2110
|
run_response.citations = full_model_response.citations
|
|
2111
|
+
if full_model_response.provider_data is not None:
|
|
2112
|
+
run_response.model_provider_data = full_model_response.provider_data
|
|
2086
2113
|
|
|
2087
2114
|
if stream_intermediate_steps and reasoning_state["reasoning_started"]:
|
|
2088
2115
|
all_reasoning_steps: List[ReasoningStep] = []
|
|
@@ -2141,6 +2168,7 @@ class Team:
|
|
|
2141
2168
|
tool_choice=self.tool_choice,
|
|
2142
2169
|
tool_call_limit=self.tool_call_limit,
|
|
2143
2170
|
stream_model_response=stream_model_response,
|
|
2171
|
+
send_media_to_model=self.send_media_to_model,
|
|
2144
2172
|
) # type: ignore
|
|
2145
2173
|
async for model_response_event in model_stream:
|
|
2146
2174
|
for event in self._handle_model_response_chunk(
|
|
@@ -2170,6 +2198,8 @@ class Team:
|
|
|
2170
2198
|
run_response.response_audio = full_model_response.audio
|
|
2171
2199
|
if full_model_response.citations is not None:
|
|
2172
2200
|
run_response.citations = full_model_response.citations
|
|
2201
|
+
if full_model_response.provider_data is not None:
|
|
2202
|
+
run_response.model_provider_data = full_model_response.provider_data
|
|
2173
2203
|
|
|
2174
2204
|
# Build a list of messages that should be added to the RunOutput
|
|
2175
2205
|
messages_for_run_response = [m for m in run_messages.messages if m.add_to_agent_memory]
|
|
@@ -2230,7 +2260,7 @@ class Team:
|
|
|
2230
2260
|
content_type = "str"
|
|
2231
2261
|
|
|
2232
2262
|
should_yield = False
|
|
2233
|
-
# Process content
|
|
2263
|
+
# Process content
|
|
2234
2264
|
if model_response_event.content is not None:
|
|
2235
2265
|
if parse_structured_output:
|
|
2236
2266
|
full_model_response.content = model_response_event.content
|
|
@@ -2246,7 +2276,31 @@ class Team:
|
|
|
2246
2276
|
full_model_response.content = (full_model_response.content or "") + model_response_event.content
|
|
2247
2277
|
should_yield = True
|
|
2248
2278
|
|
|
2249
|
-
# Process
|
|
2279
|
+
# Process reasoning content
|
|
2280
|
+
if model_response_event.reasoning_content is not None:
|
|
2281
|
+
full_model_response.reasoning_content = (
|
|
2282
|
+
full_model_response.reasoning_content or ""
|
|
2283
|
+
) + model_response_event.reasoning_content
|
|
2284
|
+
run_response.reasoning_content = full_model_response.reasoning_content
|
|
2285
|
+
should_yield = True
|
|
2286
|
+
|
|
2287
|
+
if model_response_event.redacted_reasoning_content is not None:
|
|
2288
|
+
if not full_model_response.reasoning_content:
|
|
2289
|
+
full_model_response.reasoning_content = model_response_event.redacted_reasoning_content
|
|
2290
|
+
else:
|
|
2291
|
+
full_model_response.reasoning_content += model_response_event.redacted_reasoning_content
|
|
2292
|
+
run_response.reasoning_content = full_model_response.reasoning_content
|
|
2293
|
+
should_yield = True
|
|
2294
|
+
|
|
2295
|
+
# Handle provider data (one chunk)
|
|
2296
|
+
if model_response_event.provider_data is not None:
|
|
2297
|
+
run_response.model_provider_data = model_response_event.provider_data
|
|
2298
|
+
|
|
2299
|
+
# Handle citations (one chunk)
|
|
2300
|
+
if model_response_event.citations is not None:
|
|
2301
|
+
run_response.citations = model_response_event.citations
|
|
2302
|
+
|
|
2303
|
+
# Process audio
|
|
2250
2304
|
if model_response_event.audio is not None:
|
|
2251
2305
|
if full_model_response.audio is None:
|
|
2252
2306
|
full_model_response.audio = Audio(id=str(uuid4()), content=b"", transcript="")
|
|
@@ -2309,6 +2363,7 @@ class Team:
|
|
|
2309
2363
|
redacted_reasoning_content=model_response_event.redacted_reasoning_content,
|
|
2310
2364
|
response_audio=full_model_response.audio,
|
|
2311
2365
|
citations=model_response_event.citations,
|
|
2366
|
+
model_provider_data=model_response_event.provider_data,
|
|
2312
2367
|
image=model_response_event.images[-1] if model_response_event.images else None,
|
|
2313
2368
|
),
|
|
2314
2369
|
run_response,
|
|
@@ -2900,11 +2955,6 @@ class Team:
|
|
|
2900
2955
|
session_id: Optional[str] = None,
|
|
2901
2956
|
session_state: Optional[Dict[str, Any]] = None,
|
|
2902
2957
|
user_id: Optional[str] = None,
|
|
2903
|
-
show_message: bool = True,
|
|
2904
|
-
show_reasoning: bool = True,
|
|
2905
|
-
show_full_reasoning: bool = False,
|
|
2906
|
-
console: Optional[Any] = None,
|
|
2907
|
-
tags_to_include_in_markdown: Optional[Set[str]] = None,
|
|
2908
2958
|
audio: Optional[Sequence[Audio]] = None,
|
|
2909
2959
|
images: Optional[Sequence[Image]] = None,
|
|
2910
2960
|
videos: Optional[Sequence[Video]] = None,
|
|
@@ -2912,9 +2962,16 @@ class Team:
|
|
|
2912
2962
|
markdown: Optional[bool] = None,
|
|
2913
2963
|
knowledge_filters: Optional[Dict[str, Any]] = None,
|
|
2914
2964
|
add_history_to_context: Optional[bool] = None,
|
|
2965
|
+
add_dependencies_to_context: Optional[bool] = None,
|
|
2966
|
+
add_session_state_to_context: Optional[bool] = None,
|
|
2915
2967
|
dependencies: Optional[Dict[str, Any]] = None,
|
|
2916
2968
|
metadata: Optional[Dict[str, Any]] = None,
|
|
2917
2969
|
debug_mode: Optional[bool] = None,
|
|
2970
|
+
show_message: bool = True,
|
|
2971
|
+
show_reasoning: bool = True,
|
|
2972
|
+
show_full_reasoning: bool = False,
|
|
2973
|
+
console: Optional[Any] = None,
|
|
2974
|
+
tags_to_include_in_markdown: Optional[Set[str]] = None,
|
|
2918
2975
|
**kwargs: Any,
|
|
2919
2976
|
) -> None:
|
|
2920
2977
|
if not tags_to_include_in_markdown:
|
|
@@ -2953,6 +3010,8 @@ class Team:
|
|
|
2953
3010
|
knowledge_filters=knowledge_filters,
|
|
2954
3011
|
add_history_to_context=add_history_to_context,
|
|
2955
3012
|
dependencies=dependencies,
|
|
3013
|
+
add_dependencies_to_context=add_dependencies_to_context,
|
|
3014
|
+
add_session_state_to_context=add_session_state_to_context,
|
|
2956
3015
|
metadata=metadata,
|
|
2957
3016
|
debug_mode=debug_mode,
|
|
2958
3017
|
**kwargs,
|
|
@@ -2977,6 +3036,8 @@ class Team:
|
|
|
2977
3036
|
knowledge_filters=knowledge_filters,
|
|
2978
3037
|
add_history_to_context=add_history_to_context,
|
|
2979
3038
|
dependencies=dependencies,
|
|
3039
|
+
add_dependencies_to_context=add_dependencies_to_context,
|
|
3040
|
+
add_session_state_to_context=add_session_state_to_context,
|
|
2980
3041
|
metadata=metadata,
|
|
2981
3042
|
debug_mode=debug_mode,
|
|
2982
3043
|
**kwargs,
|
|
@@ -2991,11 +3052,6 @@ class Team:
|
|
|
2991
3052
|
session_id: Optional[str] = None,
|
|
2992
3053
|
session_state: Optional[Dict[str, Any]] = None,
|
|
2993
3054
|
user_id: Optional[str] = None,
|
|
2994
|
-
show_message: bool = True,
|
|
2995
|
-
show_reasoning: bool = True,
|
|
2996
|
-
show_full_reasoning: bool = False,
|
|
2997
|
-
console: Optional[Any] = None,
|
|
2998
|
-
tags_to_include_in_markdown: Optional[Set[str]] = None,
|
|
2999
3055
|
audio: Optional[Sequence[Audio]] = None,
|
|
3000
3056
|
images: Optional[Sequence[Image]] = None,
|
|
3001
3057
|
videos: Optional[Sequence[Video]] = None,
|
|
@@ -3004,8 +3060,15 @@ class Team:
|
|
|
3004
3060
|
knowledge_filters: Optional[Dict[str, Any]] = None,
|
|
3005
3061
|
add_history_to_context: Optional[bool] = None,
|
|
3006
3062
|
dependencies: Optional[Dict[str, Any]] = None,
|
|
3063
|
+
add_dependencies_to_context: Optional[bool] = None,
|
|
3064
|
+
add_session_state_to_context: Optional[bool] = None,
|
|
3007
3065
|
metadata: Optional[Dict[str, Any]] = None,
|
|
3008
3066
|
debug_mode: Optional[bool] = None,
|
|
3067
|
+
show_message: bool = True,
|
|
3068
|
+
show_reasoning: bool = True,
|
|
3069
|
+
show_full_reasoning: bool = False,
|
|
3070
|
+
console: Optional[Any] = None,
|
|
3071
|
+
tags_to_include_in_markdown: Optional[Set[str]] = None,
|
|
3009
3072
|
**kwargs: Any,
|
|
3010
3073
|
) -> None:
|
|
3011
3074
|
if not tags_to_include_in_markdown:
|
|
@@ -3044,6 +3107,8 @@ class Team:
|
|
|
3044
3107
|
knowledge_filters=knowledge_filters,
|
|
3045
3108
|
add_history_to_context=add_history_to_context,
|
|
3046
3109
|
dependencies=dependencies,
|
|
3110
|
+
add_dependencies_to_context=add_dependencies_to_context,
|
|
3111
|
+
add_session_state_to_context=add_session_state_to_context,
|
|
3047
3112
|
metadata=metadata,
|
|
3048
3113
|
debug_mode=debug_mode,
|
|
3049
3114
|
**kwargs,
|
|
@@ -3068,6 +3133,8 @@ class Team:
|
|
|
3068
3133
|
knowledge_filters=knowledge_filters,
|
|
3069
3134
|
add_history_to_context=add_history_to_context,
|
|
3070
3135
|
dependencies=dependencies,
|
|
3136
|
+
add_dependencies_to_context=add_dependencies_to_context,
|
|
3137
|
+
add_session_state_to_context=add_session_state_to_context,
|
|
3071
3138
|
metadata=metadata,
|
|
3072
3139
|
debug_mode=debug_mode,
|
|
3073
3140
|
**kwargs,
|
|
@@ -3467,6 +3534,7 @@ class Team:
|
|
|
3467
3534
|
reasoning_model=reasoning_model,
|
|
3468
3535
|
min_steps=self.reasoning_min_steps,
|
|
3469
3536
|
max_steps=self.reasoning_max_steps,
|
|
3537
|
+
tool_call_limit=self.tool_call_limit,
|
|
3470
3538
|
telemetry=self.telemetry,
|
|
3471
3539
|
debug_mode=self.debug_mode,
|
|
3472
3540
|
debug_level=self.debug_level,
|
|
@@ -3994,6 +4062,7 @@ class Team:
|
|
|
3994
4062
|
add_history_to_context: Optional[bool] = None,
|
|
3995
4063
|
dependencies: Optional[Dict[str, Any]] = None,
|
|
3996
4064
|
add_dependencies_to_context: Optional[bool] = None,
|
|
4065
|
+
add_session_state_to_context: Optional[bool] = None,
|
|
3997
4066
|
metadata: Optional[Dict[str, Any]] = None,
|
|
3998
4067
|
) -> None:
|
|
3999
4068
|
# Prepare tools
|
|
@@ -4041,46 +4110,51 @@ class Team:
|
|
|
4041
4110
|
if self.knowledge is not None and self.update_knowledge:
|
|
4042
4111
|
_tools.append(self.add_to_knowledge)
|
|
4043
4112
|
|
|
4044
|
-
|
|
4045
|
-
|
|
4046
|
-
|
|
4047
|
-
|
|
4113
|
+
if self.members:
|
|
4114
|
+
# Get the user message if we are using the input directly
|
|
4115
|
+
user_message = None
|
|
4116
|
+
if self.determine_input_for_members is False:
|
|
4117
|
+
user_message = self._get_user_message(
|
|
4118
|
+
run_response=run_response,
|
|
4119
|
+
session_state=session_state,
|
|
4120
|
+
input_message=input_message,
|
|
4121
|
+
user_id=user_id,
|
|
4122
|
+
audio=audio,
|
|
4123
|
+
images=images,
|
|
4124
|
+
videos=videos,
|
|
4125
|
+
files=files,
|
|
4126
|
+
dependencies=dependencies,
|
|
4127
|
+
add_dependencies_to_context=add_dependencies_to_context,
|
|
4128
|
+
metadata=metadata,
|
|
4129
|
+
)
|
|
4130
|
+
|
|
4131
|
+
delegate_task_func = self._get_delegate_task_function(
|
|
4048
4132
|
run_response=run_response,
|
|
4133
|
+
session=session,
|
|
4049
4134
|
session_state=session_state,
|
|
4050
|
-
|
|
4135
|
+
team_run_context=team_run_context,
|
|
4136
|
+
input=user_message,
|
|
4051
4137
|
user_id=user_id,
|
|
4052
|
-
|
|
4053
|
-
|
|
4054
|
-
|
|
4055
|
-
|
|
4138
|
+
stream=self.stream or False,
|
|
4139
|
+
stream_intermediate_steps=self.stream_intermediate_steps,
|
|
4140
|
+
async_mode=async_mode,
|
|
4141
|
+
images=images, # type: ignore
|
|
4142
|
+
videos=videos, # type: ignore
|
|
4143
|
+
audio=audio, # type: ignore
|
|
4144
|
+
files=files, # type: ignore
|
|
4145
|
+
knowledge_filters=knowledge_filters,
|
|
4146
|
+
add_history_to_context=add_history_to_context,
|
|
4147
|
+
workflow_context=workflow_context,
|
|
4056
4148
|
dependencies=dependencies,
|
|
4057
4149
|
add_dependencies_to_context=add_dependencies_to_context,
|
|
4150
|
+
add_session_state_to_context=add_session_state_to_context,
|
|
4058
4151
|
metadata=metadata,
|
|
4152
|
+
debug_mode=debug_mode,
|
|
4059
4153
|
)
|
|
4060
4154
|
|
|
4061
|
-
|
|
4062
|
-
|
|
4063
|
-
|
|
4064
|
-
session_state=session_state,
|
|
4065
|
-
team_run_context=team_run_context,
|
|
4066
|
-
input=user_message,
|
|
4067
|
-
user_id=user_id,
|
|
4068
|
-
stream=self.stream or False,
|
|
4069
|
-
stream_intermediate_steps=self.stream_intermediate_steps,
|
|
4070
|
-
async_mode=async_mode,
|
|
4071
|
-
images=images, # type: ignore
|
|
4072
|
-
videos=videos, # type: ignore
|
|
4073
|
-
audio=audio, # type: ignore
|
|
4074
|
-
files=files, # type: ignore
|
|
4075
|
-
knowledge_filters=knowledge_filters,
|
|
4076
|
-
workflow_context=workflow_context,
|
|
4077
|
-
debug_mode=debug_mode,
|
|
4078
|
-
add_history_to_context=add_history_to_context,
|
|
4079
|
-
)
|
|
4080
|
-
|
|
4081
|
-
_tools.append(delegate_task_func)
|
|
4082
|
-
if self.get_member_information_tool:
|
|
4083
|
-
_tools.append(self.get_member_information)
|
|
4155
|
+
_tools.append(delegate_task_func)
|
|
4156
|
+
if self.get_member_information_tool:
|
|
4157
|
+
_tools.append(self.get_member_information)
|
|
4084
4158
|
|
|
4085
4159
|
self._functions_for_model = {}
|
|
4086
4160
|
self._tools_for_model = []
|
|
@@ -4109,6 +4183,7 @@ class Team:
|
|
|
4109
4183
|
if name not in self._functions_for_model:
|
|
4110
4184
|
func._team = self
|
|
4111
4185
|
func._session_state = session_state
|
|
4186
|
+
func._dependencies = dependencies
|
|
4112
4187
|
func.process_entrypoint(strict=strict)
|
|
4113
4188
|
if strict:
|
|
4114
4189
|
func.strict = True
|
|
@@ -4128,6 +4203,7 @@ class Team:
|
|
|
4128
4203
|
if tool.name not in self._functions_for_model:
|
|
4129
4204
|
tool._team = self
|
|
4130
4205
|
tool._session_state = session_state
|
|
4206
|
+
tool._dependencies = dependencies
|
|
4131
4207
|
tool.process_entrypoint(strict=strict)
|
|
4132
4208
|
if strict and tool.strict is None:
|
|
4133
4209
|
tool.strict = True
|
|
@@ -4149,6 +4225,7 @@ class Team:
|
|
|
4149
4225
|
func = Function.from_callable(tool, strict=strict)
|
|
4150
4226
|
func._team = self
|
|
4151
4227
|
func._session_state = session_state
|
|
4228
|
+
func._dependencies = dependencies
|
|
4152
4229
|
if strict:
|
|
4153
4230
|
func.strict = True
|
|
4154
4231
|
if self.tool_hooks:
|
|
@@ -4344,42 +4421,43 @@ class Team:
|
|
|
4344
4421
|
|
|
4345
4422
|
# 2 Build the default system message for the Agent.
|
|
4346
4423
|
system_message_content: str = ""
|
|
4347
|
-
|
|
4348
|
-
|
|
4424
|
+
if self.members is not None and len(self.members) > 0:
|
|
4425
|
+
system_message_content += "You are the leader of a team and sub-teams of AI Agents.\n"
|
|
4426
|
+
system_message_content += "Your task is to coordinate the team to complete the user's request.\n"
|
|
4349
4427
|
|
|
4350
|
-
|
|
4351
|
-
|
|
4352
|
-
|
|
4353
|
-
|
|
4354
|
-
|
|
4355
|
-
|
|
4428
|
+
system_message_content += "\nHere are the members in your team:\n"
|
|
4429
|
+
system_message_content += "<team_members>\n"
|
|
4430
|
+
system_message_content += self.get_members_system_message_content()
|
|
4431
|
+
if self.get_member_information_tool:
|
|
4432
|
+
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"
|
|
4433
|
+
system_message_content += "</team_members>\n"
|
|
4356
4434
|
|
|
4357
|
-
|
|
4435
|
+
system_message_content += "\n<how_to_respond>\n"
|
|
4358
4436
|
|
|
4359
|
-
|
|
4360
|
-
|
|
4361
|
-
|
|
4362
|
-
|
|
4363
|
-
|
|
4364
|
-
|
|
4365
|
-
|
|
4366
|
-
|
|
4367
|
-
|
|
4368
|
-
|
|
4369
|
-
|
|
4370
|
-
|
|
4371
|
-
|
|
4372
|
-
|
|
4373
|
-
|
|
4374
|
-
|
|
4375
|
-
|
|
4376
|
-
|
|
4377
|
-
|
|
4378
|
-
|
|
4379
|
-
|
|
4380
|
-
|
|
4381
|
-
|
|
4382
|
-
|
|
4437
|
+
if self.delegate_task_to_all_members:
|
|
4438
|
+
system_message_content += (
|
|
4439
|
+
"- 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"
|
|
4440
|
+
"- 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"
|
|
4441
|
+
"- Analyze the responses from all members and evaluate whether the task has been completed.\n"
|
|
4442
|
+
"- If you feel the task has been completed, you can stop and respond to the user.\n"
|
|
4443
|
+
)
|
|
4444
|
+
else:
|
|
4445
|
+
system_message_content += (
|
|
4446
|
+
"- Your role is to delegate tasks to members in your team with the highest likelihood of completing the user's request.\n"
|
|
4447
|
+
"- Carefully analyze the tools available to the members and their roles before delegating tasks.\n"
|
|
4448
|
+
"- You cannot use a member tool directly. You can only delegate tasks to members.\n"
|
|
4449
|
+
"- When you delegate a task to another member, make sure to include:\n"
|
|
4450
|
+
" - 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"
|
|
4451
|
+
" - task_description (str): A clear description of the task.\n"
|
|
4452
|
+
" - expected_output (str): The expected output.\n"
|
|
4453
|
+
"- You can delegate tasks to multiple members at once.\n"
|
|
4454
|
+
"- You must always analyze the responses from members before responding to the user.\n"
|
|
4455
|
+
"- After analyzing the responses from the members, if you feel the task has been completed, you can stop and respond to the user.\n"
|
|
4456
|
+
"- If you are not satisfied with the responses from the members, you should re-assign the task.\n"
|
|
4457
|
+
"- For simple greetings, thanks, or questions about the team itself, you should respond directly.\n"
|
|
4458
|
+
"- For all work requests, tasks, or questions requiring expertise, route to appropriate team members.\n"
|
|
4459
|
+
)
|
|
4460
|
+
system_message_content += "</how_to_respond>\n\n"
|
|
4383
4461
|
|
|
4384
4462
|
# Attached media
|
|
4385
4463
|
if audio is not None or images is not None or videos is not None or files is not None:
|
|
@@ -4495,7 +4573,7 @@ class Team:
|
|
|
4495
4573
|
f"<additional_context>\n{self.additional_context.strip()}\n</additional_context>\n\n"
|
|
4496
4574
|
)
|
|
4497
4575
|
|
|
4498
|
-
if
|
|
4576
|
+
if add_session_state_to_context and session_state is not None:
|
|
4499
4577
|
system_message_content += self._get_formatted_session_state_for_system_message(session_state)
|
|
4500
4578
|
|
|
4501
4579
|
# Add the JSON output prompt if output_schema is provided and structured_outputs is False
|
|
@@ -4596,9 +4674,16 @@ class Team:
|
|
|
4596
4674
|
if add_history_to_context:
|
|
4597
4675
|
from copy import deepcopy
|
|
4598
4676
|
|
|
4677
|
+
# Only skip messages from history when system_message_role is NOT a standard conversation role.
|
|
4678
|
+
# Standard conversation roles ("user", "assistant", "tool") should never be filtered
|
|
4679
|
+
# to preserve conversation continuity.
|
|
4680
|
+
skip_role = (
|
|
4681
|
+
self.system_message_role if self.system_message_role not in ["user", "assistant", "tool"] else None
|
|
4682
|
+
)
|
|
4683
|
+
|
|
4599
4684
|
history = session.get_messages_from_last_n_runs(
|
|
4600
4685
|
last_n=self.num_history_runs,
|
|
4601
|
-
skip_role=
|
|
4686
|
+
skip_role=skip_role,
|
|
4602
4687
|
team_id=self.id,
|
|
4603
4688
|
)
|
|
4604
4689
|
|
|
@@ -4682,6 +4767,9 @@ class Team:
|
|
|
4682
4767
|
if len(input_message) > 0 and isinstance(input_message[0], dict) and "type" in input_message[0]:
|
|
4683
4768
|
# This is multimodal content (text + images/audio/video), preserve the structure
|
|
4684
4769
|
input_content = input_message
|
|
4770
|
+
elif len(input_message) > 0 and isinstance(input_message[0], Message):
|
|
4771
|
+
# This is a list of Message objects, extract text content from them
|
|
4772
|
+
input_content = get_text_from_message(input_message)
|
|
4685
4773
|
elif all(isinstance(item, str) for item in input_message):
|
|
4686
4774
|
input_content = "\n".join([str(item) for item in input_message])
|
|
4687
4775
|
else:
|
|
@@ -5079,20 +5167,19 @@ class Team:
|
|
|
5079
5167
|
import json
|
|
5080
5168
|
|
|
5081
5169
|
history: List[Dict[str, Any]] = []
|
|
5082
|
-
if session is not None:
|
|
5083
|
-
all_chats = self.get_messages_for_session(session_id=session.session_id)
|
|
5084
5170
|
|
|
5085
|
-
|
|
5086
|
-
|
|
5171
|
+
all_chats = session.get_messages_from_last_n_runs(
|
|
5172
|
+
team_id=self.id,
|
|
5173
|
+
)
|
|
5087
5174
|
|
|
5088
|
-
|
|
5089
|
-
|
|
5175
|
+
if len(all_chats) == 0:
|
|
5176
|
+
return ""
|
|
5090
5177
|
|
|
5091
|
-
|
|
5092
|
-
|
|
5178
|
+
for chat in all_chats[::-1]: # type: ignore
|
|
5179
|
+
history.insert(0, chat.to_dict()) # type: ignore
|
|
5093
5180
|
|
|
5094
|
-
|
|
5095
|
-
|
|
5181
|
+
if num_chats is not None:
|
|
5182
|
+
history = history[:num_chats]
|
|
5096
5183
|
|
|
5097
5184
|
return json.dumps(history)
|
|
5098
5185
|
|
|
@@ -5120,9 +5207,14 @@ class Team:
|
|
|
5120
5207
|
member_agent_id = member_agent.id if isinstance(member_agent, Agent) else None
|
|
5121
5208
|
member_team_id = member_agent.id if isinstance(member_agent, Team) else None
|
|
5122
5209
|
|
|
5210
|
+
# Only skip messages from history when system_message_role is NOT a standard conversation role.
|
|
5211
|
+
# Standard conversation roles ("user", "assistant", "tool") should never be filtered
|
|
5212
|
+
# to preserve conversation continuity.
|
|
5213
|
+
skip_role = self.system_message_role if self.system_message_role not in ["user", "assistant", "tool"] else None
|
|
5214
|
+
|
|
5123
5215
|
history = session.get_messages_from_last_n_runs(
|
|
5124
5216
|
last_n=member_agent.num_history_runs or self.num_history_runs,
|
|
5125
|
-
skip_role=
|
|
5217
|
+
skip_role=skip_role,
|
|
5126
5218
|
agent_id=member_agent_id,
|
|
5127
5219
|
team_id=member_team_id,
|
|
5128
5220
|
member_runs=True,
|
|
@@ -5196,9 +5288,13 @@ class Team:
|
|
|
5196
5288
|
audio: Optional[List[Audio]] = None,
|
|
5197
5289
|
files: Optional[List[File]] = None,
|
|
5198
5290
|
knowledge_filters: Optional[Dict[str, Any]] = None,
|
|
5291
|
+
add_history_to_context: Optional[bool] = None,
|
|
5199
5292
|
workflow_context: Optional[Dict] = None,
|
|
5293
|
+
dependencies: Optional[Dict[str, Any]] = None,
|
|
5294
|
+
add_dependencies_to_context: Optional[bool] = None,
|
|
5295
|
+
add_session_state_to_context: Optional[bool] = None,
|
|
5296
|
+
metadata: Optional[Dict[str, Any]] = None,
|
|
5200
5297
|
debug_mode: Optional[bool] = None,
|
|
5201
|
-
add_history_to_context: Optional[bool] = None,
|
|
5202
5298
|
) -> Function:
|
|
5203
5299
|
if not images:
|
|
5204
5300
|
images = []
|
|
@@ -5234,9 +5330,9 @@ class Team:
|
|
|
5234
5330
|
task_description, expected_output, team_member_interactions_str
|
|
5235
5331
|
)
|
|
5236
5332
|
|
|
5237
|
-
# 4. Add history for the member if enabled
|
|
5333
|
+
# 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)
|
|
5238
5334
|
history = None
|
|
5239
|
-
if member_agent.add_history_to_context:
|
|
5335
|
+
if member_agent.add_history_to_context or add_history_to_context:
|
|
5240
5336
|
history = self._get_history_for_member_agent(session, member_agent)
|
|
5241
5337
|
if history:
|
|
5242
5338
|
if isinstance(member_agent_task, str):
|
|
@@ -5348,8 +5444,11 @@ class Team:
|
|
|
5348
5444
|
stream=True,
|
|
5349
5445
|
stream_intermediate_steps=stream_intermediate_steps,
|
|
5350
5446
|
debug_mode=debug_mode,
|
|
5351
|
-
add_history_to_context=add_history_to_context,
|
|
5352
5447
|
workflow_context=workflow_context,
|
|
5448
|
+
dependencies=dependencies,
|
|
5449
|
+
add_dependencies_to_context=add_dependencies_to_context,
|
|
5450
|
+
metadata=metadata,
|
|
5451
|
+
add_session_state_to_context=add_session_state_to_context,
|
|
5353
5452
|
knowledge_filters=knowledge_filters
|
|
5354
5453
|
if not member_agent.knowledge_filters and member_agent.knowledge
|
|
5355
5454
|
else None,
|
|
@@ -5383,7 +5482,10 @@ class Team:
|
|
|
5383
5482
|
stream=False,
|
|
5384
5483
|
debug_mode=debug_mode,
|
|
5385
5484
|
workflow_context=workflow_context,
|
|
5386
|
-
|
|
5485
|
+
dependencies=dependencies,
|
|
5486
|
+
add_dependencies_to_context=add_dependencies_to_context,
|
|
5487
|
+
add_session_state_to_context=add_session_state_to_context,
|
|
5488
|
+
metadata=metadata,
|
|
5387
5489
|
knowledge_filters=knowledge_filters
|
|
5388
5490
|
if not member_agent.knowledge_filters and member_agent.knowledge
|
|
5389
5491
|
else None,
|
|
@@ -5467,7 +5569,10 @@ class Team:
|
|
|
5467
5569
|
stream=True,
|
|
5468
5570
|
stream_intermediate_steps=stream_intermediate_steps,
|
|
5469
5571
|
debug_mode=debug_mode,
|
|
5470
|
-
|
|
5572
|
+
dependencies=dependencies,
|
|
5573
|
+
add_dependencies_to_context=add_dependencies_to_context,
|
|
5574
|
+
add_session_state_to_context=add_session_state_to_context,
|
|
5575
|
+
metadata=metadata,
|
|
5471
5576
|
workflow_context=workflow_context,
|
|
5472
5577
|
knowledge_filters=knowledge_filters
|
|
5473
5578
|
if not member_agent.knowledge_filters and member_agent.knowledge
|
|
@@ -5502,7 +5607,10 @@ class Team:
|
|
|
5502
5607
|
stream=False,
|
|
5503
5608
|
debug_mode=debug_mode,
|
|
5504
5609
|
workflow_context=workflow_context,
|
|
5505
|
-
|
|
5610
|
+
dependencies=dependencies,
|
|
5611
|
+
add_dependencies_to_context=add_dependencies_to_context,
|
|
5612
|
+
add_session_state_to_context=add_session_state_to_context,
|
|
5613
|
+
metadata=metadata,
|
|
5506
5614
|
knowledge_filters=knowledge_filters
|
|
5507
5615
|
if not member_agent.knowledge_filters and member_agent.knowledge
|
|
5508
5616
|
else None,
|
|
@@ -5580,7 +5688,10 @@ class Team:
|
|
|
5580
5688
|
if not member_agent.knowledge_filters and member_agent.knowledge
|
|
5581
5689
|
else None,
|
|
5582
5690
|
debug_mode=debug_mode,
|
|
5583
|
-
|
|
5691
|
+
dependencies=dependencies,
|
|
5692
|
+
add_dependencies_to_context=add_dependencies_to_context,
|
|
5693
|
+
add_session_state_to_context=add_session_state_to_context,
|
|
5694
|
+
metadata=metadata,
|
|
5584
5695
|
yield_run_response=True,
|
|
5585
5696
|
)
|
|
5586
5697
|
member_agent_run_response = None
|
|
@@ -5615,7 +5726,10 @@ class Team:
|
|
|
5615
5726
|
if not member_agent.knowledge_filters and member_agent.knowledge
|
|
5616
5727
|
else None,
|
|
5617
5728
|
debug_mode=debug_mode,
|
|
5618
|
-
|
|
5729
|
+
dependencies=dependencies,
|
|
5730
|
+
add_dependencies_to_context=add_dependencies_to_context,
|
|
5731
|
+
add_session_state_to_context=add_session_state_to_context,
|
|
5732
|
+
metadata=metadata,
|
|
5619
5733
|
)
|
|
5620
5734
|
|
|
5621
5735
|
check_if_run_cancelled(member_agent_run_response) # type: ignore
|
|
@@ -5689,7 +5803,10 @@ class Team:
|
|
|
5689
5803
|
knowledge_filters=knowledge_filters
|
|
5690
5804
|
if not member_agent.knowledge_filters and member_agent.knowledge
|
|
5691
5805
|
else None,
|
|
5692
|
-
|
|
5806
|
+
dependencies=dependencies,
|
|
5807
|
+
add_dependencies_to_context=add_dependencies_to_context,
|
|
5808
|
+
add_session_state_to_context=add_session_state_to_context,
|
|
5809
|
+
metadata=metadata,
|
|
5693
5810
|
yield_run_response=True,
|
|
5694
5811
|
)
|
|
5695
5812
|
member_agent_run_response = None
|
|
@@ -5706,6 +5823,7 @@ class Team:
|
|
|
5706
5823
|
_process_delegate_task_to_member(
|
|
5707
5824
|
member_agent_run_response, member_agent, member_agent_task, member_session_state_copy
|
|
5708
5825
|
)
|
|
5826
|
+
await queue.put(done_marker)
|
|
5709
5827
|
|
|
5710
5828
|
# Initialize and launch all members
|
|
5711
5829
|
tasks: List[asyncio.Task[None]] = []
|
|
@@ -5733,7 +5851,6 @@ class Team:
|
|
|
5733
5851
|
for t in tasks:
|
|
5734
5852
|
with contextlib.suppress(Exception):
|
|
5735
5853
|
await t
|
|
5736
|
-
|
|
5737
5854
|
else:
|
|
5738
5855
|
# Non-streaming concurrent run of members; collect results when done
|
|
5739
5856
|
tasks = []
|
|
@@ -5763,7 +5880,10 @@ class Team:
|
|
|
5763
5880
|
knowledge_filters=knowledge_filters
|
|
5764
5881
|
if not member_agent.knowledge_filters and member_agent.knowledge
|
|
5765
5882
|
else None,
|
|
5766
|
-
|
|
5883
|
+
dependencies=dependencies,
|
|
5884
|
+
add_dependencies_to_context=add_dependencies_to_context,
|
|
5885
|
+
add_session_state_to_context=add_session_state_to_context,
|
|
5886
|
+
metadata=metadata,
|
|
5767
5887
|
)
|
|
5768
5888
|
check_if_run_cancelled(member_agent_run_response)
|
|
5769
5889
|
|
|
@@ -5996,7 +6116,8 @@ class Team:
|
|
|
5996
6116
|
|
|
5997
6117
|
from agno.utils.merge_dict import merge_dictionaries
|
|
5998
6118
|
|
|
5999
|
-
# Get the session_state from the database and
|
|
6119
|
+
# Get the session_state from the database and merge with proper precedence
|
|
6120
|
+
# At this point session_state contains: agent_defaults + run_params
|
|
6000
6121
|
if session.session_data is not None and "session_state" in session.session_data:
|
|
6001
6122
|
session_state_from_db = session.session_data.get("session_state")
|
|
6002
6123
|
|
|
@@ -6005,10 +6126,11 @@ class Team:
|
|
|
6005
6126
|
and isinstance(session_state_from_db, dict)
|
|
6006
6127
|
and len(session_state_from_db) > 0
|
|
6007
6128
|
):
|
|
6008
|
-
# This
|
|
6009
|
-
|
|
6010
|
-
merge_dictionaries(
|
|
6011
|
-
session_state
|
|
6129
|
+
# This preserves precedence: run_params > db_state > agent_defaults
|
|
6130
|
+
merged_state = session_state_from_db.copy()
|
|
6131
|
+
merge_dictionaries(merged_state, session_state)
|
|
6132
|
+
session_state.clear()
|
|
6133
|
+
session_state.update(merged_state)
|
|
6012
6134
|
|
|
6013
6135
|
# Update the session_state in the session
|
|
6014
6136
|
if session.session_data is not None:
|
|
@@ -6646,17 +6768,18 @@ class Team:
|
|
|
6646
6768
|
) -> Function:
|
|
6647
6769
|
"""Factory function to create a search_knowledge_base function with filters."""
|
|
6648
6770
|
|
|
6649
|
-
def search_knowledge_base(query: str, filters: Optional[
|
|
6771
|
+
def search_knowledge_base(query: str, filters: Optional[List[KnowledgeFilter]] = None) -> str:
|
|
6650
6772
|
"""Use this function to search the knowledge base for information about a query.
|
|
6651
6773
|
|
|
6652
6774
|
Args:
|
|
6653
6775
|
query: The query to search for.
|
|
6654
|
-
filters: The filters to apply to the search. This is a
|
|
6776
|
+
filters (optional): The filters to apply to the search. This is a list of KnowledgeFilter objects.
|
|
6655
6777
|
|
|
6656
6778
|
Returns:
|
|
6657
6779
|
str: A string containing the response from the knowledge base.
|
|
6658
6780
|
"""
|
|
6659
|
-
|
|
6781
|
+
filters_dict = {filt.key: filt.value for filt in filters} if filters else None
|
|
6782
|
+
search_filters = get_agentic_or_user_search_filters(filters_dict, knowledge_filters)
|
|
6660
6783
|
|
|
6661
6784
|
# Get the relevant documents from the knowledge base, passing filters
|
|
6662
6785
|
retrieval_timer = Timer()
|
|
@@ -6677,17 +6800,18 @@ class Team:
|
|
|
6677
6800
|
return "No documents found"
|
|
6678
6801
|
return self._convert_documents_to_string(docs_from_knowledge)
|
|
6679
6802
|
|
|
6680
|
-
async def asearch_knowledge_base(query: str, filters: Optional[
|
|
6803
|
+
async def asearch_knowledge_base(query: str, filters: Optional[List[KnowledgeFilter]] = None) -> str:
|
|
6681
6804
|
"""Use this function to search the knowledge base for information about a query asynchronously.
|
|
6682
6805
|
|
|
6683
6806
|
Args:
|
|
6684
6807
|
query: The query to search for.
|
|
6685
|
-
filters: The filters to apply to the search. This is a
|
|
6808
|
+
filters (optional): The filters to apply to the search. This is a list of KnowledgeFilter objects.
|
|
6686
6809
|
|
|
6687
6810
|
Returns:
|
|
6688
6811
|
str: A string containing the response from the knowledge base.
|
|
6689
6812
|
"""
|
|
6690
|
-
|
|
6813
|
+
filters_dict = {filt.key: filt.value for filt in filters} if filters else None
|
|
6814
|
+
search_filters = get_agentic_or_user_search_filters(filters_dict, knowledge_filters)
|
|
6691
6815
|
|
|
6692
6816
|
retrieval_timer = Timer()
|
|
6693
6817
|
retrieval_timer.start()
|