agno 2.2.5__py3-none-any.whl → 2.2.6__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/os/schema.py CHANGED
@@ -13,14 +13,17 @@ from agno.os.utils import (
13
13
  extract_input_media,
14
14
  format_team_tools,
15
15
  format_tools,
16
+ get_agent_input_schema_dict,
16
17
  get_run_input,
17
18
  get_session_name,
19
+ get_team_input_schema_dict,
18
20
  get_workflow_input_schema_dict,
19
21
  )
20
22
  from agno.run.agent import RunOutput
21
23
  from agno.run.team import TeamRunOutput
22
24
  from agno.session import AgentSession, TeamSession, WorkflowSession
23
25
  from agno.team.team import Team
26
+ from agno.workflow.agent import WorkflowAgent
24
27
  from agno.workflow.workflow import Workflow
25
28
 
26
29
 
@@ -166,21 +169,25 @@ class ModelResponse(BaseModel):
166
169
 
167
170
 
168
171
  class AgentResponse(BaseModel):
169
- id: Optional[str] = Field(None, description="Unique identifier for the agent")
170
- name: Optional[str] = Field(None, description="Name of the agent")
171
- db_id: Optional[str] = Field(None, description="Database identifier")
172
- model: Optional[ModelResponse] = Field(None, description="Model configuration")
173
- tools: Optional[Dict[str, Any]] = Field(None, description="Tool configurations")
174
- sessions: Optional[Dict[str, Any]] = Field(None, description="Session configurations")
175
- knowledge: Optional[Dict[str, Any]] = Field(None, description="Knowledge base configurations")
176
- memory: Optional[Dict[str, Any]] = Field(None, description="Memory configurations")
177
- reasoning: Optional[Dict[str, Any]] = Field(None, description="Reasoning configurations")
178
- default_tools: Optional[Dict[str, Any]] = Field(None, description="Default tool settings")
179
- system_message: Optional[Dict[str, Any]] = Field(None, description="System message configurations")
180
- extra_messages: Optional[Dict[str, Any]] = Field(None, description="Extra message configurations")
181
- response_settings: Optional[Dict[str, Any]] = Field(None, description="Response settings")
182
- streaming: Optional[Dict[str, Any]] = Field(None, description="Streaming configurations")
183
- metadata: Optional[Dict[str, Any]] = Field(None, description="Additional metadata")
172
+ id: Optional[str] = None
173
+ name: Optional[str] = None
174
+ db_id: Optional[str] = None
175
+ model: Optional[ModelResponse] = None
176
+ tools: Optional[Dict[str, Any]] = None
177
+ sessions: Optional[Dict[str, Any]] = None
178
+ knowledge: Optional[Dict[str, Any]] = None
179
+ memory: Optional[Dict[str, Any]] = None
180
+ reasoning: Optional[Dict[str, Any]] = None
181
+ default_tools: Optional[Dict[str, Any]] = None
182
+ system_message: Optional[Dict[str, Any]] = None
183
+ extra_messages: Optional[Dict[str, Any]] = None
184
+ response_settings: Optional[Dict[str, Any]] = None
185
+ streaming: Optional[Dict[str, Any]] = None
186
+ metadata: Optional[Dict[str, Any]] = None
187
+ input_schema: Optional[Dict[str, Any]] = None
188
+
189
+ class Config:
190
+ exclude_none = True
184
191
 
185
192
  @classmethod
186
193
  async def from_agent(cls, agent: Agent) -> "AgentResponse":
@@ -375,6 +382,7 @@ class AgentResponse(BaseModel):
375
382
  "stream_events": agent.stream_events,
376
383
  "stream_intermediate_steps": agent.stream_intermediate_steps,
377
384
  }
385
+
378
386
  return AgentResponse(
379
387
  id=agent.id,
380
388
  name=agent.name,
@@ -391,28 +399,28 @@ class AgentResponse(BaseModel):
391
399
  response_settings=filter_meaningful_config(response_settings_info, agent_defaults),
392
400
  streaming=filter_meaningful_config(streaming_info, agent_defaults),
393
401
  metadata=agent.metadata,
402
+ input_schema=get_agent_input_schema_dict(agent),
394
403
  )
395
404
 
396
405
 
397
406
  class TeamResponse(BaseModel):
398
- id: Optional[str] = Field(None, description="Unique identifier for the team")
399
- name: Optional[str] = Field(None, description="Name of the team")
400
- db_id: Optional[str] = Field(None, description="Database identifier")
401
- description: Optional[str] = Field(None, description="Description of the team")
402
- model: Optional[ModelResponse] = Field(None, description="Model configuration")
403
- tools: Optional[Dict[str, Any]] = Field(None, description="Tool configurations")
404
- sessions: Optional[Dict[str, Any]] = Field(None, description="Session configurations")
405
- knowledge: Optional[Dict[str, Any]] = Field(None, description="Knowledge base configurations")
406
- memory: Optional[Dict[str, Any]] = Field(None, description="Memory configurations")
407
- reasoning: Optional[Dict[str, Any]] = Field(None, description="Reasoning configurations")
408
- default_tools: Optional[Dict[str, Any]] = Field(None, description="Default tool settings")
409
- system_message: Optional[Dict[str, Any]] = Field(None, description="System message configurations")
410
- response_settings: Optional[Dict[str, Any]] = Field(None, description="Response settings")
411
- streaming: Optional[Dict[str, Any]] = Field(None, description="Streaming configurations")
412
- members: Optional[List[Union[AgentResponse, "TeamResponse"]]] = Field(
413
- None, description="List of team members (agents or teams)"
414
- )
415
- metadata: Optional[Dict[str, Any]] = Field(None, description="Additional metadata")
407
+ id: Optional[str] = None
408
+ name: Optional[str] = None
409
+ db_id: Optional[str] = None
410
+ description: Optional[str] = None
411
+ model: Optional[ModelResponse] = None
412
+ tools: Optional[Dict[str, Any]] = None
413
+ sessions: Optional[Dict[str, Any]] = None
414
+ knowledge: Optional[Dict[str, Any]] = None
415
+ memory: Optional[Dict[str, Any]] = None
416
+ reasoning: Optional[Dict[str, Any]] = None
417
+ default_tools: Optional[Dict[str, Any]] = None
418
+ system_message: Optional[Dict[str, Any]] = None
419
+ response_settings: Optional[Dict[str, Any]] = None
420
+ streaming: Optional[Dict[str, Any]] = None
421
+ members: Optional[List[Union[AgentResponse, "TeamResponse"]]] = None
422
+ metadata: Optional[Dict[str, Any]] = None
423
+ input_schema: Optional[Dict[str, Any]] = None
416
424
 
417
425
  @classmethod
418
426
  async def from_team(cls, team: Team) -> "TeamResponse":
@@ -621,6 +629,7 @@ class TeamResponse(BaseModel):
621
629
  streaming=filter_meaningful_config(streaming_info, team_defaults),
622
630
  members=members if members else None,
623
631
  metadata=team.metadata,
632
+ input_schema=get_team_input_schema_dict(team),
624
633
  )
625
634
 
626
635
 
@@ -634,6 +643,7 @@ class WorkflowResponse(BaseModel):
634
643
  agent: Optional[AgentResponse] = Field(None, description="Agent configuration if used")
635
644
  team: Optional[TeamResponse] = Field(None, description="Team configuration if used")
636
645
  metadata: Optional[Dict[str, Any]] = Field(None, description="Additional metadata")
646
+ workflow_agent: bool = Field(False, description="Whether this workflow uses a WorkflowAgent")
637
647
 
638
648
  @classmethod
639
649
  async def _resolve_agents_and_teams_recursively(cls, steps: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
@@ -685,6 +695,7 @@ class WorkflowResponse(BaseModel):
685
695
  steps=steps,
686
696
  input_schema=get_workflow_input_schema_dict(workflow),
687
697
  metadata=workflow.metadata,
698
+ workflow_agent=isinstance(workflow.agent, WorkflowAgent) if workflow.agent else False,
688
699
  )
689
700
 
690
701
 
@@ -870,6 +881,7 @@ class RunSchema(BaseModel):
870
881
  created_at: Optional[datetime] = Field(None, description="Run creation timestamp")
871
882
  references: Optional[List[dict]] = Field(None, description="References cited in the run")
872
883
  reasoning_messages: Optional[List[dict]] = Field(None, description="Reasoning process messages")
884
+ session_state: Optional[dict] = Field(None, description="Session state at the end of the run")
873
885
  images: Optional[List[dict]] = Field(None, description="Images included in the run")
874
886
  videos: Optional[List[dict]] = Field(None, description="Videos included in the run")
875
887
  audio: Optional[List[dict]] = Field(None, description="Audio files included in the run")
@@ -897,6 +909,7 @@ class RunSchema(BaseModel):
897
909
  events=[event for event in run_dict["events"]] if run_dict.get("events") else None,
898
910
  references=run_dict.get("references", []),
899
911
  reasoning_messages=run_dict.get("reasoning_messages", []),
912
+ session_state=run_dict.get("session_state"),
900
913
  images=run_dict.get("images", []),
901
914
  videos=run_dict.get("videos", []),
902
915
  audio=run_dict.get("audio", []),
@@ -925,6 +938,7 @@ class TeamRunSchema(BaseModel):
925
938
  created_at: Optional[datetime] = Field(None, description="Run creation timestamp")
926
939
  references: Optional[List[dict]] = Field(None, description="References cited in the run")
927
940
  reasoning_messages: Optional[List[dict]] = Field(None, description="Reasoning process messages")
941
+ session_state: Optional[dict] = Field(None, description="Session state at the end of the run")
928
942
  input_media: Optional[Dict[str, Any]] = Field(None, description="Input media attachments")
929
943
  images: Optional[List[dict]] = Field(None, description="Images included in the run")
930
944
  videos: Optional[List[dict]] = Field(None, description="Videos included in the run")
@@ -954,6 +968,7 @@ class TeamRunSchema(BaseModel):
954
968
  else None,
955
969
  references=run_dict.get("references", []),
956
970
  reasoning_messages=run_dict.get("reasoning_messages", []),
971
+ session_state=run_dict.get("session_state"),
957
972
  images=run_dict.get("images", []),
958
973
  videos=run_dict.get("videos", []),
959
974
  audio=run_dict.get("audio", []),
agno/os/utils.py CHANGED
@@ -274,6 +274,33 @@ def get_workflow_by_id(workflow_id: str, workflows: Optional[List[Workflow]] = N
274
274
  return None
275
275
 
276
276
 
277
+ # INPUT SCHEMA VALIDATIONS
278
+
279
+
280
+ def get_agent_input_schema_dict(agent: Agent) -> Optional[Dict[str, Any]]:
281
+ """Get input schema as dictionary for API responses"""
282
+
283
+ if agent.input_schema is not None:
284
+ try:
285
+ return agent.input_schema.model_json_schema()
286
+ except Exception:
287
+ return None
288
+
289
+ return None
290
+
291
+
292
+ def get_team_input_schema_dict(team: Team) -> Optional[Dict[str, Any]]:
293
+ """Get input schema as dictionary for API responses"""
294
+
295
+ if team.input_schema is not None:
296
+ try:
297
+ return team.input_schema.model_json_schema()
298
+ except Exception:
299
+ return None
300
+
301
+ return None
302
+
303
+
277
304
  def get_workflow_input_schema_dict(workflow: Workflow) -> Optional[Dict[str, Any]]:
278
305
  """Get input schema as dictionary for API responses"""
279
306
 
agno/run/agent.py CHANGED
@@ -221,6 +221,9 @@ class RunContentEvent(BaseAgentRunEvent):
221
221
 
222
222
  event: str = RunEvent.run_content.value
223
223
  content: Optional[Any] = None
224
+ workflow_agent: bool = (
225
+ False # Used by consumers of the events to distinguish between workflow agent and regular agent
226
+ )
224
227
  content_type: str = "str"
225
228
  reasoning_content: Optional[str] = None
226
229
  model_provider_data: Optional[Dict[str, Any]] = None
@@ -263,6 +266,7 @@ class RunCompletedEvent(BaseAgentRunEvent):
263
266
  reasoning_messages: Optional[List[Message]] = None
264
267
  metadata: Optional[Dict[str, Any]] = None
265
268
  metrics: Optional[Metrics] = None
269
+ session_state: Optional[Dict[str, Any]] = None
266
270
 
267
271
 
268
272
  @dataclass
@@ -527,6 +531,7 @@ class RunOutput:
527
531
  references: Optional[List[MessageReferences]] = None
528
532
 
529
533
  metadata: Optional[Dict[str, Any]] = None
534
+ session_state: Optional[Dict[str, Any]] = None
530
535
 
531
536
  created_at: int = field(default_factory=lambda: int(time()))
532
537
 
agno/run/team.py CHANGED
@@ -261,6 +261,7 @@ class RunCompletedEvent(BaseTeamRunEvent):
261
261
  member_responses: List[Union["TeamRunOutput", RunOutput]] = field(default_factory=list)
262
262
  metadata: Optional[Dict[str, Any]] = None
263
263
  metrics: Optional[Metrics] = None
264
+ session_state: Optional[Dict[str, Any]] = None
264
265
 
265
266
 
266
267
  @dataclass
@@ -500,6 +501,7 @@ class TeamRunOutput:
500
501
  citations: Optional[Citations] = None
501
502
  model_provider_data: Optional[Dict[str, Any]] = None
502
503
  metadata: Optional[Dict[str, Any]] = None
504
+ session_state: Optional[Dict[str, Any]] = None
503
505
 
504
506
  references: Optional[List[MessageReferences]] = None
505
507
  additional_input: Optional[List[Message]] = None
agno/run/workflow.py CHANGED
@@ -31,6 +31,9 @@ class WorkflowRunEvent(str, Enum):
31
31
  workflow_cancelled = "WorkflowCancelled"
32
32
  workflow_error = "WorkflowError"
33
33
 
34
+ workflow_agent_started = "WorkflowAgentStarted"
35
+ workflow_agent_completed = "WorkflowAgentCompleted"
36
+
34
37
  step_started = "StepStarted"
35
38
  step_completed = "StepCompleted"
36
39
  step_error = "StepError"
@@ -126,6 +129,21 @@ class WorkflowStartedEvent(BaseWorkflowRunOutputEvent):
126
129
  event: str = WorkflowRunEvent.workflow_started.value
127
130
 
128
131
 
132
+ @dataclass
133
+ class WorkflowAgentStartedEvent(BaseWorkflowRunOutputEvent):
134
+ """Event sent when workflow agent starts (before deciding to run workflow or answer directly)"""
135
+
136
+ event: str = WorkflowRunEvent.workflow_agent_started.value
137
+
138
+
139
+ @dataclass
140
+ class WorkflowAgentCompletedEvent(BaseWorkflowRunOutputEvent):
141
+ """Event sent when workflow agent completes (after running workflow or answering directly)"""
142
+
143
+ event: str = WorkflowRunEvent.workflow_agent_completed.value
144
+ content: Optional[Any] = None
145
+
146
+
129
147
  @dataclass
130
148
  class WorkflowCompletedEvent(BaseWorkflowRunOutputEvent):
131
149
  """Event sent when workflow execution completes"""
@@ -403,6 +421,8 @@ class CustomEvent(BaseWorkflowRunOutputEvent):
403
421
  # Union type for all workflow run response events
404
422
  WorkflowRunOutputEvent = Union[
405
423
  WorkflowStartedEvent,
424
+ WorkflowAgentStartedEvent,
425
+ WorkflowAgentCompletedEvent,
406
426
  WorkflowCompletedEvent,
407
427
  WorkflowErrorEvent,
408
428
  WorkflowCancelledEvent,
@@ -428,6 +448,8 @@ WorkflowRunOutputEvent = Union[
428
448
  # Map event string to dataclass for workflow events
429
449
  WORKFLOW_RUN_EVENT_TYPE_REGISTRY = {
430
450
  WorkflowRunEvent.workflow_started.value: WorkflowStartedEvent,
451
+ WorkflowRunEvent.workflow_agent_started.value: WorkflowAgentStartedEvent,
452
+ WorkflowRunEvent.workflow_agent_completed.value: WorkflowAgentCompletedEvent,
431
453
  WorkflowRunEvent.workflow_completed.value: WorkflowCompletedEvent,
432
454
  WorkflowRunEvent.workflow_cancelled.value: WorkflowCancelledEvent,
433
455
  WorkflowRunEvent.workflow_error.value: WorkflowErrorEvent,
@@ -491,6 +513,10 @@ class WorkflowRunOutput:
491
513
  # Store agent/team responses separately with parent_run_id references
492
514
  step_executor_runs: Optional[List[Union[RunOutput, TeamRunOutput]]] = None
493
515
 
516
+ # Workflow agent run - stores the full agent RunOutput when workflow agent is used
517
+ # The agent's parent_run_id will point to this workflow run's run_id to establish the relationship
518
+ workflow_agent_run: Optional[RunOutput] = None
519
+
494
520
  # Store events from workflow execution
495
521
  events: Optional[List[WorkflowRunOutputEvent]] = None
496
522
 
@@ -522,6 +548,7 @@ class WorkflowRunOutput:
522
548
  "step_executor_runs",
523
549
  "events",
524
550
  "metrics",
551
+ "workflow_agent_run",
525
552
  ]
526
553
  }
527
554
 
@@ -557,6 +584,9 @@ class WorkflowRunOutput:
557
584
  if self.step_executor_runs:
558
585
  _dict["step_executor_runs"] = [run.to_dict() for run in self.step_executor_runs]
559
586
 
587
+ if self.workflow_agent_run is not None:
588
+ _dict["workflow_agent_run"] = self.workflow_agent_run.to_dict()
589
+
560
590
  if self.metrics is not None:
561
591
  _dict["metrics"] = self.metrics.to_dict()
562
592
 
@@ -604,6 +634,14 @@ class WorkflowRunOutput:
604
634
  else:
605
635
  step_executor_runs.append(RunOutput.from_dict(run_data))
606
636
 
637
+ workflow_agent_run_data = data.pop("workflow_agent_run", None)
638
+ workflow_agent_run = None
639
+ if workflow_agent_run_data:
640
+ if isinstance(workflow_agent_run_data, dict):
641
+ workflow_agent_run = RunOutput.from_dict(workflow_agent_run_data)
642
+ elif isinstance(workflow_agent_run_data, RunOutput):
643
+ workflow_agent_run = workflow_agent_run_data
644
+
607
645
  metadata = data.pop("metadata", None)
608
646
 
609
647
  images = reconstruct_images(data.pop("images", []))
@@ -640,6 +678,7 @@ class WorkflowRunOutput:
640
678
 
641
679
  return cls(
642
680
  step_results=parsed_step_results,
681
+ workflow_agent_run=workflow_agent_run,
643
682
  metadata=metadata,
644
683
  images=images,
645
684
  videos=videos,
agno/session/summary.py CHANGED
@@ -1,11 +1,12 @@
1
1
  from dataclasses import dataclass
2
2
  from datetime import datetime
3
3
  from textwrap import dedent
4
- from typing import TYPE_CHECKING, Any, Dict, List, Optional, Type, Union, cast
4
+ from typing import TYPE_CHECKING, Any, Dict, List, Optional, Type, Union
5
5
 
6
6
  from pydantic import BaseModel, Field
7
7
 
8
8
  from agno.models.base import Model
9
+ from agno.models.utils import get_model
9
10
  from agno.run.agent import Message
10
11
  from agno.utils.log import log_debug, log_warning
11
12
 
@@ -142,7 +143,10 @@ class SessionSummaryManager:
142
143
  if not session:
143
144
  return None
144
145
 
145
- self.model = cast(Model, self.model)
146
+ self.model = get_model(self.model)
147
+ if self.model is None:
148
+ return None
149
+
146
150
  response_format = self.get_response_format(self.model)
147
151
 
148
152
  system_message = self.get_system_message(
@@ -210,6 +214,7 @@ class SessionSummaryManager:
210
214
  ) -> Optional[SessionSummary]:
211
215
  """Creates a summary of the session"""
212
216
  log_debug("Creating session summary", center=True)
217
+ self.model = get_model(self.model)
213
218
  if self.model is None:
214
219
  return None
215
220
 
@@ -237,6 +242,7 @@ class SessionSummaryManager:
237
242
  ) -> Optional[SessionSummary]:
238
243
  """Creates a summary of the session"""
239
244
  log_debug("Creating session summary", center=True)
245
+ self.model = get_model(self.model)
240
246
  if self.model is None:
241
247
  return None
242
248
 
agno/session/workflow.py CHANGED
@@ -129,12 +129,12 @@ class WorkflowSession:
129
129
  context_parts = ["<workflow_history_context>"]
130
130
 
131
131
  for i, (input_str, response_str) in enumerate(history_data, 1):
132
- context_parts.append(f"[run-{i}]")
132
+ context_parts.append(f"[Workflow Run-{i}]")
133
133
 
134
134
  if input_str:
135
- context_parts.append(f"input: {input_str}")
135
+ context_parts.append(f"User input: {input_str}")
136
136
  if response_str:
137
- context_parts.append(f"response: {response_str}")
137
+ context_parts.append(f"Workflow output: {response_str}")
138
138
 
139
139
  context_parts.append("") # Empty line between runs
140
140
 
@@ -154,6 +154,7 @@ class WorkflowSession:
154
154
  runs_data.append(run.to_dict())
155
155
  except Exception as e:
156
156
  raise ValueError(f"Serialization failed: {str(e)}")
157
+
157
158
  return {
158
159
  "session_id": self.session_id,
159
160
  "user_id": self.user_id,
agno/team/team.py CHANGED
@@ -45,6 +45,7 @@ from agno.models.base import Model
45
45
  from agno.models.message import Message, MessageReferences
46
46
  from agno.models.metrics import Metrics
47
47
  from agno.models.response import ModelResponse, ModelResponseEvent
48
+ from agno.models.utils import get_model
48
49
  from agno.reasoning.step import NextAction, ReasoningStep, ReasoningSteps
49
50
  from agno.run.agent import RunEvent, RunOutput, RunOutputEvent
50
51
  from agno.run.base import RunStatus
@@ -437,7 +438,7 @@ class Team:
437
438
  self,
438
439
  members: List[Union[Agent, "Team"]],
439
440
  id: Optional[str] = None,
440
- model: Optional[Model] = None,
441
+ model: Optional[Union[Model, str]] = None,
441
442
  name: Optional[str] = None,
442
443
  role: Optional[str] = None,
443
444
  respond_directly: bool = False,
@@ -498,9 +499,9 @@ class Team:
498
499
  post_hooks: Optional[Union[List[Callable[..., Any]], List[BaseGuardrail]]] = None,
499
500
  input_schema: Optional[Type[BaseModel]] = None,
500
501
  output_schema: Optional[Type[BaseModel]] = None,
501
- parser_model: Optional[Model] = None,
502
+ parser_model: Optional[Union[Model, str]] = None,
502
503
  parser_model_prompt: Optional[str] = None,
503
- output_model: Optional[Model] = None,
504
+ output_model: Optional[Union[Model, str]] = None,
504
505
  output_model_prompt: Optional[str] = None,
505
506
  use_json_mode: bool = False,
506
507
  parse_response: bool = True,
@@ -514,7 +515,7 @@ class Team:
514
515
  add_session_summary_to_context: Optional[bool] = None,
515
516
  metadata: Optional[Dict[str, Any]] = None,
516
517
  reasoning: bool = False,
517
- reasoning_model: Optional[Model] = None,
518
+ reasoning_model: Optional[Union[Model, str]] = None,
518
519
  reasoning_agent: Optional[Agent] = None,
519
520
  reasoning_min_steps: int = 1,
520
521
  reasoning_max_steps: int = 10,
@@ -535,7 +536,7 @@ class Team:
535
536
  ):
536
537
  self.members = members
537
538
 
538
- self.model = model
539
+ self.model = model # type: ignore[assignment]
539
540
 
540
541
  self.name = name
541
542
  self.id = id
@@ -618,9 +619,9 @@ class Team:
618
619
 
619
620
  self.input_schema = input_schema
620
621
  self.output_schema = output_schema
621
- self.parser_model = parser_model
622
+ self.parser_model = parser_model # type: ignore[assignment]
622
623
  self.parser_model_prompt = parser_model_prompt
623
- self.output_model = output_model
624
+ self.output_model = output_model # type: ignore[assignment]
624
625
  self.output_model_prompt = output_model_prompt
625
626
  self.use_json_mode = use_json_mode
626
627
  self.parse_response = parse_response
@@ -637,7 +638,7 @@ class Team:
637
638
  self.metadata = metadata
638
639
 
639
640
  self.reasoning = reasoning
640
- self.reasoning_model = reasoning_model
641
+ self.reasoning_model = reasoning_model # type: ignore[assignment]
641
642
  self.reasoning_agent = reasoning_agent
642
643
  self.reasoning_min_steps = reasoning_min_steps
643
644
  self.reasoning_max_steps = reasoning_max_steps
@@ -694,6 +695,8 @@ class Team:
694
695
  # Lazy-initialized shared thread pool executor for background tasks (memory, cultural knowledge, etc.)
695
696
  self._background_executor: Optional[Any] = None
696
697
 
698
+ self._resolve_models()
699
+
697
700
  @property
698
701
  def background_executor(self) -> Any:
699
702
  """Lazy initialization of shared thread pool executor for background tasks.
@@ -902,6 +905,17 @@ class Team:
902
905
  """Return True if the db the team is equipped with is an Async implementation"""
903
906
  return self.db is not None and isinstance(self.db, AsyncBaseDb)
904
907
 
908
+ def _resolve_models(self) -> None:
909
+ """Resolve model strings to Model instances."""
910
+ if self.model is not None:
911
+ self.model = get_model(self.model)
912
+ if self.reasoning_model is not None:
913
+ self.reasoning_model = get_model(self.reasoning_model)
914
+ if self.parser_model is not None:
915
+ self.parser_model = get_model(self.parser_model)
916
+ if self.output_model is not None:
917
+ self.output_model = get_model(self.output_model)
918
+
905
919
  def initialize_team(self, debug_mode: Optional[bool] = None) -> None:
906
920
  # Make sure for the team, we are using the team logger
907
921
  use_team_logger()
@@ -1593,6 +1607,7 @@ class Team:
1593
1607
  tools=_tools,
1594
1608
  response_format=response_format,
1595
1609
  stream_events=stream_events,
1610
+ session_state=session_state,
1596
1611
  ):
1597
1612
  raise_if_cancelled(run_response.run_id) # type: ignore
1598
1613
  yield event
@@ -1604,6 +1619,7 @@ class Team:
1604
1619
  tools=_tools,
1605
1620
  response_format=response_format,
1606
1621
  stream_events=stream_events,
1622
+ session_state=session_state,
1607
1623
  ):
1608
1624
  raise_if_cancelled(run_response.run_id) # type: ignore
1609
1625
  from agno.run.team import IntermediateRunContentEvent, RunContentEvent
@@ -1932,6 +1948,7 @@ class Team:
1932
1948
  team_id=self.id,
1933
1949
  team_name=self.name,
1934
1950
  metadata=metadata,
1951
+ session_state=session_state,
1935
1952
  input=run_input,
1936
1953
  )
1937
1954
 
@@ -2439,6 +2456,7 @@ class Team:
2439
2456
  tools=_tools,
2440
2457
  response_format=response_format,
2441
2458
  stream_events=stream_events,
2459
+ session_state=session_state,
2442
2460
  ):
2443
2461
  raise_if_cancelled(run_response.run_id) # type: ignore
2444
2462
  yield event
@@ -2450,6 +2468,7 @@ class Team:
2450
2468
  tools=_tools,
2451
2469
  response_format=response_format,
2452
2470
  stream_events=stream_events,
2471
+ session_state=session_state,
2453
2472
  ):
2454
2473
  raise_if_cancelled(run_response.run_id) # type: ignore
2455
2474
  from agno.run.team import IntermediateRunContentEvent, RunContentEvent
@@ -2771,6 +2790,7 @@ class Team:
2771
2790
  team_id=self.id,
2772
2791
  team_name=self.name,
2773
2792
  metadata=metadata,
2793
+ session_state=session_state,
2774
2794
  input=run_input,
2775
2795
  )
2776
2796
 
@@ -2930,6 +2950,12 @@ class Team:
2930
2950
  if model_response.audio is not None:
2931
2951
  run_response.response_audio = model_response.audio
2932
2952
 
2953
+ # Update session_state with changes from model response
2954
+ if model_response.updated_session_state is not None and run_response.session_state is not None:
2955
+ from agno.utils.merge_dict import merge_dictionaries
2956
+
2957
+ merge_dictionaries(run_response.session_state, model_response.updated_session_state)
2958
+
2933
2959
  # Build a list of messages that should be added to the RunOutput
2934
2960
  messages_for_run_response = [m for m in run_messages.messages if m.add_to_agent_memory]
2935
2961
 
@@ -2954,6 +2980,7 @@ class Team:
2954
2980
  tools: Optional[List[Union[Function, dict]]] = None,
2955
2981
  response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
2956
2982
  stream_events: bool = False,
2983
+ session_state: Optional[Dict[str, Any]] = None,
2957
2984
  ) -> Iterator[Union[TeamRunOutputEvent, RunOutputEvent]]:
2958
2985
  self.model = cast(Model, self.model)
2959
2986
 
@@ -2985,6 +3012,7 @@ class Team:
2985
3012
  reasoning_state=reasoning_state,
2986
3013
  stream_events=stream_events,
2987
3014
  parse_structured_output=self.should_parse_structured_output,
3015
+ session_state=session_state,
2988
3016
  )
2989
3017
 
2990
3018
  # 3. Update TeamRunOutput
@@ -3036,6 +3064,7 @@ class Team:
3036
3064
  tools: Optional[List[Union[Function, dict]]] = None,
3037
3065
  response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
3038
3066
  stream_events: bool = False,
3067
+ session_state: Optional[Dict[str, Any]] = None,
3039
3068
  ) -> AsyncIterator[Union[TeamRunOutputEvent, RunOutputEvent]]:
3040
3069
  self.model = cast(Model, self.model)
3041
3070
 
@@ -3068,6 +3097,7 @@ class Team:
3068
3097
  reasoning_state=reasoning_state,
3069
3098
  stream_events=stream_events,
3070
3099
  parse_structured_output=self.should_parse_structured_output,
3100
+ session_state=session_state,
3071
3101
  ):
3072
3102
  yield event
3073
3103
 
@@ -3122,6 +3152,7 @@ class Team:
3122
3152
  reasoning_state: Optional[Dict[str, Any]] = None,
3123
3153
  stream_events: bool = False,
3124
3154
  parse_structured_output: bool = False,
3155
+ session_state: Optional[Dict[str, Any]] = None,
3125
3156
  ) -> Iterator[Union[TeamRunOutputEvent, RunOutputEvent]]:
3126
3157
  if isinstance(model_response_event, tuple(get_args(RunOutputEvent))) or isinstance(
3127
3158
  model_response_event, tuple(get_args(TeamRunOutputEvent))
@@ -3299,10 +3330,15 @@ class Team:
3299
3330
 
3300
3331
  # If the model response is a tool_call_completed, update the existing tool call in the run_response
3301
3332
  elif model_response_event.event == ModelResponseEvent.tool_call_completed.value:
3302
- if model_response_event.updated_session_state is not None and session.session_data is not None:
3303
- merge_dictionaries(
3304
- session.session_data["session_state"], model_response_event.updated_session_state
3305
- )
3333
+ if model_response_event.updated_session_state is not None:
3334
+ # Update the session_state variable that TeamRunOutput references
3335
+ if session_state is not None:
3336
+ merge_dictionaries(session_state, model_response_event.updated_session_state)
3337
+ # Also update the DB session object
3338
+ if session.session_data is not None:
3339
+ merge_dictionaries(
3340
+ session.session_data["session_state"], model_response_event.updated_session_state
3341
+ )
3306
3342
 
3307
3343
  if model_response_event.images is not None:
3308
3344
  for image in model_response_event.images:
@@ -4498,7 +4534,7 @@ class Team:
4498
4534
  store_events=self.store_events,
4499
4535
  )
4500
4536
  else:
4501
- log_warning(
4537
+ log_info(
4502
4538
  f"Reasoning model: {reasoning_model.__class__.__name__} is not a native reasoning model, defaulting to manual Chain-of-Thought reasoning"
4503
4539
  )
4504
4540
  use_default_reasoning = True
@@ -4779,7 +4815,7 @@ class Team:
4779
4815
  store_events=self.store_events,
4780
4816
  )
4781
4817
  else:
4782
- log_warning(
4818
+ log_info(
4783
4819
  f"Reasoning model: {reasoning_model.__class__.__name__} is not a native reasoning model, defaulting to manual Chain-of-Thought reasoning"
4784
4820
  )
4785
4821
  use_default_reasoning = True