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.
Files changed (64) hide show
  1. agno/agent/agent.py +83 -51
  2. agno/db/base.py +14 -0
  3. agno/db/dynamo/dynamo.py +107 -27
  4. agno/db/firestore/firestore.py +109 -33
  5. agno/db/gcs_json/gcs_json_db.py +100 -20
  6. agno/db/in_memory/in_memory_db.py +95 -20
  7. agno/db/json/json_db.py +101 -21
  8. agno/db/migrations/v1_to_v2.py +322 -47
  9. agno/db/mongo/mongo.py +251 -26
  10. agno/db/mysql/mysql.py +307 -6
  11. agno/db/postgres/postgres.py +279 -33
  12. agno/db/redis/redis.py +99 -22
  13. agno/db/singlestore/singlestore.py +319 -38
  14. agno/db/sqlite/sqlite.py +339 -23
  15. agno/knowledge/embedder/sentence_transformer.py +3 -3
  16. agno/knowledge/knowledge.py +152 -31
  17. agno/knowledge/types.py +8 -0
  18. agno/models/anthropic/claude.py +0 -20
  19. agno/models/cometapi/__init__.py +5 -0
  20. agno/models/cometapi/cometapi.py +57 -0
  21. agno/models/google/gemini.py +4 -8
  22. agno/models/huggingface/huggingface.py +2 -1
  23. agno/models/ollama/chat.py +52 -3
  24. agno/models/openai/chat.py +9 -7
  25. agno/models/openai/responses.py +21 -17
  26. agno/os/interfaces/agui/agui.py +2 -2
  27. agno/os/interfaces/agui/utils.py +81 -18
  28. agno/os/interfaces/base.py +2 -0
  29. agno/os/interfaces/slack/router.py +50 -10
  30. agno/os/interfaces/slack/slack.py +6 -4
  31. agno/os/interfaces/whatsapp/router.py +7 -4
  32. agno/os/interfaces/whatsapp/whatsapp.py +2 -2
  33. agno/os/router.py +18 -0
  34. agno/os/utils.py +10 -2
  35. agno/reasoning/azure_ai_foundry.py +2 -2
  36. agno/reasoning/deepseek.py +2 -2
  37. agno/reasoning/default.py +3 -1
  38. agno/reasoning/groq.py +2 -2
  39. agno/reasoning/ollama.py +2 -2
  40. agno/reasoning/openai.py +2 -2
  41. agno/run/base.py +15 -2
  42. agno/session/agent.py +8 -5
  43. agno/session/team.py +14 -10
  44. agno/team/team.py +218 -111
  45. agno/tools/function.py +43 -4
  46. agno/tools/mcp.py +60 -37
  47. agno/tools/mcp_toolbox.py +284 -0
  48. agno/tools/scrapegraph.py +58 -31
  49. agno/tools/whatsapp.py +1 -1
  50. agno/utils/gemini.py +147 -19
  51. agno/utils/models/claude.py +9 -0
  52. agno/utils/print_response/agent.py +18 -2
  53. agno/utils/print_response/team.py +22 -6
  54. agno/utils/reasoning.py +22 -1
  55. agno/utils/string.py +9 -0
  56. agno/vectordb/base.py +2 -2
  57. agno/vectordb/langchaindb/langchaindb.py +5 -7
  58. agno/vectordb/llamaindex/llamaindexdb.py +25 -6
  59. agno/workflow/workflow.py +30 -15
  60. {agno-2.0.7.dist-info → agno-2.0.9.dist-info}/METADATA +4 -1
  61. {agno-2.0.7.dist-info → agno-2.0.9.dist-info}/RECORD +64 -61
  62. {agno-2.0.7.dist-info → agno-2.0.9.dist-info}/WHEEL +0 -0
  63. {agno-2.0.7.dist-info → agno-2.0.9.dist-info}/licenses/LICENSE +0 -0
  64. {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 and thinking
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 thinking
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
- # Get the user message if we are using the input directly
4056
- user_message = None
4057
- if self.determine_input_for_members is False:
4058
- user_message = self._get_user_message(
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
- input_message=input_message,
4128
+ team_run_context=team_run_context,
4129
+ input=user_message,
4062
4130
  user_id=user_id,
4063
- audio=audio,
4064
- images=images,
4065
- videos=videos,
4066
- files=files,
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
- delegate_task_func = self._get_delegate_task_function(
4073
- run_response=run_response,
4074
- session=session,
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
- system_message_content += "You are the leader of a team and sub-teams of AI Agents.\n"
4359
- system_message_content += "Your task is to coordinate the team to complete the user's request.\n"
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
- system_message_content += "\nHere are the members in your team:\n"
4362
- system_message_content += "<team_members>\n"
4363
- system_message_content += self.get_members_system_message_content()
4364
- if self.get_member_information_tool:
4365
- 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"
4366
- system_message_content += "</team_members>\n"
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
- system_message_content += "\n<how_to_respond>\n"
4428
+ system_message_content += "\n<how_to_respond>\n"
4369
4429
 
4370
- if self.delegate_task_to_all_members:
4371
- system_message_content += (
4372
- "- 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"
4373
- "- 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"
4374
- "- Analyze the responses from all members and evaluate whether the task has been completed.\n"
4375
- "- If you feel the task has been completed, you can stop and respond to the user.\n"
4376
- )
4377
- else:
4378
- system_message_content += (
4379
- "- Your role is to delegate tasks to members in your team with the highest likelihood of completing the user's request.\n"
4380
- "- Carefully analyze the tools available to the members and their roles before delegating tasks.\n"
4381
- "- You cannot use a member tool directly. You can only delegate tasks to members.\n"
4382
- "- When you delegate a task to another member, make sure to include:\n"
4383
- " - 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"
4384
- " - task_description (str): A clear description of the task.\n"
4385
- " - expected_output (str): The expected output.\n"
4386
- "- You can delegate tasks to multiple members at once.\n"
4387
- "- You must always analyze the responses from members before responding to the user.\n"
4388
- "- After analyzing the responses from the members, if you feel the task has been completed, you can stop and respond to the user.\n"
4389
- "- If you are not satisfied with the responses from the members, you should re-assign the task.\n"
4390
- "- For simple greetings, thanks, or questions about the team itself, you should respond directly.\n"
4391
- "- For all work requests, tasks, or questions requiring expertise, route to appropriate team members.\n"
4392
- )
4393
- system_message_content += "</how_to_respond>\n\n"
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 self.add_session_state_to_context and session_state is not None:
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=self.system_message_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=self.system_message_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
- add_history_to_context=add_history_to_context,
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
- add_history_to_context=add_history_to_context,
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
- add_history_to_context=add_history_to_context,
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
- add_history_to_context=add_history_to_context,
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
- add_history_to_context=add_history_to_context,
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
- add_history_to_context=add_history_to_context,
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
- add_history_to_context=add_history_to_context,
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 update the current session_state
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 updates session_state_from_db
6019
- # If there are conflicting keys, values from provided session_state will take precedence
6020
- merge_dictionaries(session_state_from_db, session_state)
6021
- session_state = session_state_from_db
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[Dict[str, Any]] = None) -> str:
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 dictionary of key-value pairs.
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
- search_filters = get_agentic_or_user_search_filters(filters, knowledge_filters)
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[Dict[str, Any]] = None) -> str:
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 dictionary of key-value pairs.
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
- search_filters = get_agentic_or_user_search_filters(filters, knowledge_filters)
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()