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.
Files changed (52) hide show
  1. agno/agent/agent.py +94 -48
  2. agno/db/migrations/v1_to_v2.py +140 -11
  3. agno/knowledge/chunking/semantic.py +33 -6
  4. agno/knowledge/embedder/sentence_transformer.py +3 -3
  5. agno/knowledge/knowledge.py +152 -31
  6. agno/knowledge/types.py +8 -0
  7. agno/media.py +2 -0
  8. agno/models/base.py +38 -9
  9. agno/models/cometapi/__init__.py +5 -0
  10. agno/models/cometapi/cometapi.py +57 -0
  11. agno/models/google/gemini.py +4 -8
  12. agno/models/llama_cpp/__init__.py +5 -0
  13. agno/models/llama_cpp/llama_cpp.py +22 -0
  14. agno/models/nexus/__init__.py +1 -1
  15. agno/models/nexus/nexus.py +2 -5
  16. agno/models/ollama/chat.py +24 -1
  17. agno/models/openai/chat.py +2 -7
  18. agno/models/openai/responses.py +21 -17
  19. agno/os/app.py +4 -10
  20. agno/os/interfaces/agui/agui.py +2 -2
  21. agno/os/interfaces/agui/utils.py +81 -18
  22. agno/os/interfaces/slack/slack.py +2 -2
  23. agno/os/interfaces/whatsapp/whatsapp.py +2 -2
  24. agno/os/router.py +3 -4
  25. agno/os/routers/evals/evals.py +1 -1
  26. agno/os/routers/memory/memory.py +1 -1
  27. agno/os/schema.py +3 -4
  28. agno/os/utils.py +55 -12
  29. agno/reasoning/default.py +3 -1
  30. agno/run/agent.py +4 -0
  31. agno/run/team.py +3 -1
  32. agno/session/agent.py +8 -5
  33. agno/session/team.py +14 -10
  34. agno/team/team.py +239 -115
  35. agno/tools/decorator.py +4 -2
  36. agno/tools/function.py +43 -4
  37. agno/tools/mcp.py +61 -38
  38. agno/tools/memori.py +1 -53
  39. agno/utils/events.py +7 -1
  40. agno/utils/gemini.py +147 -19
  41. agno/utils/models/claude.py +9 -0
  42. agno/utils/print_response/agent.py +16 -0
  43. agno/utils/print_response/team.py +16 -0
  44. agno/vectordb/base.py +2 -2
  45. agno/vectordb/langchaindb/langchaindb.py +5 -7
  46. agno/vectordb/llamaindex/llamaindexdb.py +25 -6
  47. agno/workflow/workflow.py +59 -15
  48. {agno-2.0.6.dist-info → agno-2.0.8.dist-info}/METADATA +1 -1
  49. {agno-2.0.6.dist-info → agno-2.0.8.dist-info}/RECORD +52 -48
  50. {agno-2.0.6.dist-info → agno-2.0.8.dist-info}/WHEEL +0 -0
  51. {agno-2.0.6.dist-info → agno-2.0.8.dist-info}/licenses/LICENSE +0 -0
  52. {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 and thinking
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 thinking
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
- # Get the user message if we are using the input directly
4045
- user_message = None
4046
- if self.determine_input_for_members is False:
4047
- user_message = self._get_user_message(
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
- input_message=input_message,
4135
+ team_run_context=team_run_context,
4136
+ input=user_message,
4051
4137
  user_id=user_id,
4052
- audio=audio,
4053
- images=images,
4054
- videos=videos,
4055
- files=files,
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
- delegate_task_func = self._get_delegate_task_function(
4062
- run_response=run_response,
4063
- session=session,
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
- system_message_content += "You are the leader of a team and sub-teams of AI Agents.\n"
4348
- system_message_content += "Your task is to coordinate the team to complete the user's request.\n"
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
- system_message_content += "\nHere are the members in your team:\n"
4351
- system_message_content += "<team_members>\n"
4352
- system_message_content += self.get_members_system_message_content()
4353
- if self.get_member_information_tool:
4354
- 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"
4355
- system_message_content += "</team_members>\n"
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
- system_message_content += "\n<how_to_respond>\n"
4435
+ system_message_content += "\n<how_to_respond>\n"
4358
4436
 
4359
- if self.delegate_task_to_all_members:
4360
- system_message_content += (
4361
- "- 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"
4362
- "- 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"
4363
- "- Analyze the responses from all members and evaluate whether the task has been completed.\n"
4364
- "- If you feel the task has been completed, you can stop and respond to the user.\n"
4365
- )
4366
- else:
4367
- system_message_content += (
4368
- "- Your role is to delegate tasks to members in your team with the highest likelihood of completing the user's request.\n"
4369
- "- Carefully analyze the tools available to the members and their roles before delegating tasks.\n"
4370
- "- You cannot use a member tool directly. You can only delegate tasks to members.\n"
4371
- "- When you delegate a task to another member, make sure to include:\n"
4372
- " - 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"
4373
- " - task_description (str): A clear description of the task.\n"
4374
- " - expected_output (str): The expected output.\n"
4375
- "- You can delegate tasks to multiple members at once.\n"
4376
- "- You must always analyze the responses from members before responding to the user.\n"
4377
- "- After analyzing the responses from the members, if you feel the task has been completed, you can stop and respond to the user.\n"
4378
- "- If you are not satisfied with the responses from the members, you should re-assign the task.\n"
4379
- "- For simple greetings, thanks, or questions about the team itself, you should respond directly.\n"
4380
- "- For all work requests, tasks, or questions requiring expertise, route to appropriate team members.\n"
4381
- )
4382
- system_message_content += "</how_to_respond>\n\n"
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 self.add_session_state_to_context and session_state is not None:
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=self.system_message_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
- if len(all_chats) == 0:
5086
- return ""
5171
+ all_chats = session.get_messages_from_last_n_runs(
5172
+ team_id=self.id,
5173
+ )
5087
5174
 
5088
- for chat in all_chats[::-1]: # type: ignore
5089
- history.insert(0, chat.to_dict()) # type: ignore
5175
+ if len(all_chats) == 0:
5176
+ return ""
5090
5177
 
5091
- if num_chats is not None:
5092
- history = history[:num_chats]
5178
+ for chat in all_chats[::-1]: # type: ignore
5179
+ history.insert(0, chat.to_dict()) # type: ignore
5093
5180
 
5094
- else:
5095
- return ""
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=self.system_message_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
- add_history_to_context=add_history_to_context,
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
- add_history_to_context=add_history_to_context,
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
- add_history_to_context=add_history_to_context,
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
- add_history_to_context=add_history_to_context,
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
- add_history_to_context=add_history_to_context,
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
- add_history_to_context=add_history_to_context,
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
- add_history_to_context=add_history_to_context,
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 update the current session_state
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 updates session_state_from_db
6009
- # If there are conflicting keys, values from provided session_state will take precedence
6010
- merge_dictionaries(session_state_from_db, session_state)
6011
- session_state = session_state_from_db
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[Dict[str, Any]] = None) -> str:
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 dictionary of key-value pairs.
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
- search_filters = get_agentic_or_user_search_filters(filters, knowledge_filters)
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[Dict[str, Any]] = None) -> str:
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 dictionary of key-value pairs.
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
- search_filters = get_agentic_or_user_search_filters(filters, knowledge_filters)
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()