agno 2.2.6__py3-none-any.whl → 2.2.8__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
agno/workflow/agent.py CHANGED
@@ -1,9 +1,10 @@
1
1
  """WorkflowAgent - A restricted Agent for workflow orchestration"""
2
2
 
3
- from typing import TYPE_CHECKING, Any, Callable, Dict, Optional
3
+ from typing import TYPE_CHECKING, Any, Callable, Optional
4
4
 
5
5
  from agno.agent import Agent
6
6
  from agno.models.base import Model
7
+ from agno.run import RunContext
7
8
  from agno.workflow.types import WebSocketHandler
8
9
 
9
10
  if TYPE_CHECKING:
@@ -81,7 +82,7 @@ Guidelines:
81
82
  workflow: "Any", # Workflow type
82
83
  session: "WorkflowSession",
83
84
  execution_input: "WorkflowExecutionInput",
84
- session_state: Optional[Dict[str, Any]],
85
+ run_context: RunContext,
85
86
  stream: bool = False,
86
87
  ) -> Callable:
87
88
  """
@@ -91,7 +92,7 @@ Guidelines:
91
92
  workflow: The workflow instance
92
93
  session: The workflow session
93
94
  execution_input: The execution input
94
- session_state: The session state
95
+ run_context: The run context
95
96
  stream: Whether to stream the workflow execution
96
97
  Returns:
97
98
  Callable tool function
@@ -150,9 +151,9 @@ Guidelines:
150
151
  final_content = ""
151
152
  for event in workflow._execute_stream(
152
153
  session=session_from_db,
154
+ run_context=run_context,
153
155
  execution_input=workflow_execution_input,
154
156
  workflow_run_response=workflow_run_response,
155
- session_state=session_state,
156
157
  stream_events=True,
157
158
  ):
158
159
  yield event
@@ -170,7 +171,7 @@ Guidelines:
170
171
  session=session_from_db,
171
172
  execution_input=workflow_execution_input,
172
173
  workflow_run_response=workflow_run_response,
173
- session_state=session_state,
174
+ run_context=run_context,
174
175
  )
175
176
 
176
177
  if isinstance(result.content, str):
@@ -187,7 +188,7 @@ Guidelines:
187
188
  workflow: "Any", # Workflow type
188
189
  session: "WorkflowSession",
189
190
  execution_input: "WorkflowExecutionInput",
190
- session_state: Optional[Dict[str, Any]],
191
+ run_context: RunContext,
191
192
  stream: bool = False,
192
193
  websocket_handler: Optional[WebSocketHandler] = None,
193
194
  ) -> Callable:
@@ -199,7 +200,7 @@ Guidelines:
199
200
  workflow: The workflow instance
200
201
  session: The workflow session
201
202
  execution_input: The execution input
202
- session_state: The session state
203
+ run_context: The run context
203
204
  stream: Whether to stream the workflow execution
204
205
 
205
206
  Returns:
@@ -267,7 +268,7 @@ Guidelines:
267
268
  user_id=session_from_db.user_id,
268
269
  execution_input=workflow_execution_input,
269
270
  workflow_run_response=workflow_run_response,
270
- session_state=session_state,
271
+ session_state=run_context.session_state,
271
272
  stream_events=True,
272
273
  websocket_handler=websocket_handler,
273
274
  ):
@@ -285,7 +286,7 @@ Guidelines:
285
286
  user_id=session_from_db.user_id,
286
287
  execution_input=workflow_execution_input,
287
288
  workflow_run_response=workflow_run_response,
288
- session_state=session_state,
289
+ session_state=run_context.session_state,
289
290
  )
290
291
 
291
292
  if isinstance(result.content, str):
agno/workflow/step.py CHANGED
@@ -10,6 +10,7 @@ from typing_extensions import TypeGuard
10
10
  from agno.agent import Agent
11
11
  from agno.media import Audio, Image, Video
12
12
  from agno.models.metrics import Metrics
13
+ from agno.run import RunContext
13
14
  from agno.run.agent import RunOutput
14
15
  from agno.run.team import TeamRunOutput
15
16
  from agno.run.workflow import (
@@ -210,6 +211,7 @@ class Step:
210
211
  session_id: Optional[str] = None,
211
212
  user_id: Optional[str] = None,
212
213
  workflow_run_response: Optional["WorkflowRunOutput"] = None,
214
+ run_context: Optional[RunContext] = None,
213
215
  session_state: Optional[Dict[str, Any]] = None,
214
216
  store_executor_outputs: bool = True,
215
217
  workflow_session: Optional[WorkflowSession] = None,
@@ -224,7 +226,11 @@ class Step:
224
226
 
225
227
  if workflow_session:
226
228
  step_input.workflow_session = workflow_session
227
- session_state_copy = copy(session_state) if session_state is not None else {}
229
+
230
+ if run_context is not None and run_context.session_state is not None:
231
+ session_state_copy = copy(run_context.session_state)
232
+ else:
233
+ session_state_copy = copy(session_state) if session_state is not None else {}
228
234
 
229
235
  # Execute with retries
230
236
  for attempt in range(self.max_retries + 1):
@@ -407,6 +413,7 @@ class Step:
407
413
  stream_intermediate_steps: bool = False,
408
414
  stream_executor_events: bool = True,
409
415
  workflow_run_response: Optional["WorkflowRunOutput"] = None,
416
+ run_context: Optional[RunContext] = None,
410
417
  session_state: Optional[Dict[str, Any]] = None,
411
418
  step_index: Optional[Union[int, tuple]] = None,
412
419
  store_executor_outputs: bool = True,
@@ -422,8 +429,12 @@ class Step:
422
429
 
423
430
  if workflow_session:
424
431
  step_input.workflow_session = workflow_session
432
+
425
433
  # Create session_state copy once to avoid duplication
426
- session_state_copy = copy(session_state) if session_state is not None else {}
434
+ if run_context is not None and run_context.session_state is not None:
435
+ session_state_copy = copy(run_context.session_state)
436
+ else:
437
+ session_state_copy = copy(session_state) if session_state is not None else {}
427
438
 
428
439
  # Considering both stream_events and stream_intermediate_steps (deprecated)
429
440
  stream_events = stream_events or stream_intermediate_steps
agno/workflow/workflow.py CHANGED
@@ -29,8 +29,8 @@ from agno.exceptions import InputCheckError, OutputCheckError, RunCancelledExcep
29
29
  from agno.media import Audio, File, Image, Video
30
30
  from agno.models.message import Message
31
31
  from agno.models.metrics import Metrics
32
+ from agno.run import RunContext, RunStatus
32
33
  from agno.run.agent import RunContentEvent, RunEvent, RunOutput
33
- from agno.run.base import RunStatus
34
34
  from agno.run.cancel import (
35
35
  cancel_run as cancel_run_global,
36
36
  )
@@ -1216,7 +1216,7 @@ class Workflow:
1216
1216
  session: WorkflowSession,
1217
1217
  execution_input: WorkflowExecutionInput,
1218
1218
  workflow_run_response: WorkflowRunOutput,
1219
- session_state: Optional[Dict[str, Any]] = None,
1219
+ run_context: RunContext,
1220
1220
  **kwargs: Any,
1221
1221
  ) -> WorkflowRunOutput:
1222
1222
  """Execute a specific pipeline by name synchronously"""
@@ -1283,7 +1283,7 @@ class Workflow:
1283
1283
  session_id=session.session_id,
1284
1284
  user_id=self.user_id,
1285
1285
  workflow_run_response=workflow_run_response,
1286
- session_state=session_state,
1286
+ session_state=run_context.session_state,
1287
1287
  store_executor_outputs=self.store_executor_outputs,
1288
1288
  workflow_session=session,
1289
1289
  add_workflow_history_to_steps=self.add_workflow_history_to_steps
@@ -1377,7 +1377,7 @@ class Workflow:
1377
1377
  session: WorkflowSession,
1378
1378
  execution_input: WorkflowExecutionInput,
1379
1379
  workflow_run_response: WorkflowRunOutput,
1380
- session_state: Optional[Dict[str, Any]] = None,
1380
+ run_context: RunContext,
1381
1381
  stream_events: bool = False,
1382
1382
  **kwargs: Any,
1383
1383
  ) -> Iterator[WorkflowRunOutputEvent]:
@@ -1468,7 +1468,7 @@ class Workflow:
1468
1468
  stream_events=stream_events,
1469
1469
  stream_executor_events=self.stream_executor_events,
1470
1470
  workflow_run_response=workflow_run_response,
1471
- session_state=session_state,
1471
+ session_state=run_context.session_state,
1472
1472
  step_index=i,
1473
1473
  store_executor_outputs=self.store_executor_outputs,
1474
1474
  workflow_session=session,
@@ -2267,6 +2267,13 @@ class Workflow:
2267
2267
  session_id=session_id, user_id=user_id, session_state=session_state
2268
2268
  )
2269
2269
 
2270
+ run_context = RunContext(
2271
+ run_id=run_id,
2272
+ session_id=session_id,
2273
+ user_id=user_id,
2274
+ session_state=session_state,
2275
+ )
2276
+
2270
2277
  self._prepare_steps()
2271
2278
 
2272
2279
  # Create workflow run response with PENDING status
@@ -2312,10 +2319,8 @@ class Workflow:
2312
2319
  if self.agent is not None:
2313
2320
  self._aexecute_workflow_agent(
2314
2321
  user_input=input, # type: ignore
2315
- session_id=session_id,
2316
- user_id=user_id,
2317
2322
  execution_input=inputs,
2318
- session_state=session_state,
2323
+ run_context=run_context,
2319
2324
  stream=False,
2320
2325
  **kwargs,
2321
2326
  )
@@ -2375,6 +2380,13 @@ class Workflow:
2375
2380
  session_id=session_id, user_id=user_id, session_state=session_state
2376
2381
  )
2377
2382
 
2383
+ run_context = RunContext(
2384
+ run_id=run_id,
2385
+ session_id=session_id,
2386
+ user_id=user_id,
2387
+ session_state=session_state,
2388
+ )
2389
+
2378
2390
  self._prepare_steps()
2379
2391
 
2380
2392
  # Create workflow run response with PENDING status
@@ -2406,10 +2418,8 @@ class Workflow:
2406
2418
  if self.agent is not None:
2407
2419
  result = self._aexecute_workflow_agent(
2408
2420
  user_input=input, # type: ignore
2409
- session_id=session_id,
2410
- user_id=user_id,
2421
+ run_context=run_context,
2411
2422
  execution_input=inputs,
2412
- session_state=session_state,
2413
2423
  stream=True,
2414
2424
  websocket_handler=websocket_handler,
2415
2425
  **kwargs,
@@ -2437,7 +2447,7 @@ class Workflow:
2437
2447
  execution_input=inputs,
2438
2448
  workflow_run_response=workflow_run_response,
2439
2449
  stream_events=stream_events,
2440
- session_state=session_state,
2450
+ run_context=run_context,
2441
2451
  websocket_handler=websocket_handler,
2442
2452
  **kwargs,
2443
2453
  ):
@@ -2491,7 +2501,7 @@ class Workflow:
2491
2501
  self,
2492
2502
  session: WorkflowSession,
2493
2503
  execution_input: WorkflowExecutionInput,
2494
- session_state: Optional[Dict[str, Any]],
2504
+ run_context: RunContext,
2495
2505
  stream: bool = False,
2496
2506
  ) -> None:
2497
2507
  """Initialize the workflow agent with tools (but NOT context - that's passed per-run)"""
@@ -2501,7 +2511,7 @@ class Workflow:
2501
2511
  workflow=self,
2502
2512
  session=session,
2503
2513
  execution_input=execution_input,
2504
- session_state=session_state,
2514
+ run_context=run_context,
2505
2515
  stream=stream,
2506
2516
  )
2507
2517
  workflow_tool = Function.from_callable(workflow_tool_func)
@@ -2544,7 +2554,7 @@ class Workflow:
2544
2554
  user_input: Union[str, Dict[str, Any], List[Any], BaseModel],
2545
2555
  session: WorkflowSession,
2546
2556
  execution_input: WorkflowExecutionInput,
2547
- session_state: Optional[Dict[str, Any]],
2557
+ run_context: RunContext,
2548
2558
  stream: bool = False,
2549
2559
  **kwargs: Any,
2550
2560
  ) -> Union[WorkflowRunOutput, Iterator[WorkflowRunOutputEvent]]:
@@ -2557,7 +2567,7 @@ class Workflow:
2557
2567
  user_input: The user's input
2558
2568
  session: The workflow session
2559
2569
  execution_input: The execution input
2560
- session_state: The session state
2570
+ run_context: The run context
2561
2571
  stream: Whether to stream the response
2562
2572
  stream_intermediate_steps: Whether to stream intermediate steps
2563
2573
 
@@ -2569,7 +2579,7 @@ class Workflow:
2569
2579
  agent_input=user_input,
2570
2580
  session=session,
2571
2581
  execution_input=execution_input,
2572
- session_state=session_state,
2582
+ run_context=run_context,
2573
2583
  stream=stream,
2574
2584
  **kwargs,
2575
2585
  )
@@ -2578,7 +2588,7 @@ class Workflow:
2578
2588
  agent_input=user_input,
2579
2589
  session=session,
2580
2590
  execution_input=execution_input,
2581
- session_state=session_state,
2591
+ run_context=run_context,
2582
2592
  stream=stream,
2583
2593
  )
2584
2594
 
@@ -2587,7 +2597,7 @@ class Workflow:
2587
2597
  agent_input: Union[str, Dict[str, Any], List[Any], BaseModel],
2588
2598
  session: WorkflowSession,
2589
2599
  execution_input: WorkflowExecutionInput,
2590
- session_state: Optional[Dict[str, Any]],
2600
+ run_context: RunContext,
2591
2601
  stream: bool = False,
2592
2602
  **kwargs: Any,
2593
2603
  ) -> Iterator[WorkflowRunOutputEvent]:
@@ -2606,10 +2616,10 @@ class Workflow:
2606
2616
  from agno.run.workflow import WorkflowCompletedEvent, WorkflowRunOutputEvent
2607
2617
 
2608
2618
  # Initialize agent with stream_intermediate_steps=True so tool yields events
2609
- self._initialize_workflow_agent(session, execution_input, session_state, stream=stream)
2619
+ self._initialize_workflow_agent(session, execution_input, run_context=run_context, stream=stream)
2610
2620
 
2611
2621
  # Build dependencies with workflow context
2612
- dependencies = self._get_workflow_agent_dependencies(session)
2622
+ run_context.dependencies = self._get_workflow_agent_dependencies(session)
2613
2623
 
2614
2624
  # Run agent with streaming - workflow events will bubble up from the tool
2615
2625
  agent_response: Optional[RunOutput] = None
@@ -2647,7 +2657,8 @@ class Workflow:
2647
2657
  stream_intermediate_steps=True,
2648
2658
  yield_run_response=True,
2649
2659
  session_id=session.session_id,
2650
- dependencies=dependencies, # Pass context dynamically per-run
2660
+ dependencies=run_context.dependencies, # Pass context dynamically per-run
2661
+ session_state=run_context.session_state, # Pass session state dynamically per-run
2651
2662
  ): # type: ignore
2652
2663
  if isinstance(event, tuple(get_args(WorkflowRunOutputEvent))):
2653
2664
  yield event # type: ignore[misc]
@@ -2751,7 +2762,7 @@ class Workflow:
2751
2762
  agent_input: Union[str, Dict[str, Any], List[Any], BaseModel],
2752
2763
  session: WorkflowSession,
2753
2764
  execution_input: WorkflowExecutionInput,
2754
- session_state: Optional[Dict[str, Any]],
2765
+ run_context: RunContext,
2755
2766
  stream: bool = False,
2756
2767
  ) -> WorkflowRunOutput:
2757
2768
  """
@@ -2764,16 +2775,17 @@ class Workflow:
2764
2775
  """
2765
2776
 
2766
2777
  # Initialize the agent
2767
- self._initialize_workflow_agent(session, execution_input, session_state, stream=stream)
2778
+ self._initialize_workflow_agent(session, execution_input, run_context=run_context, stream=stream)
2768
2779
 
2769
2780
  # Build dependencies with workflow context
2770
- dependencies = self._get_workflow_agent_dependencies(session)
2781
+ run_context.dependencies = self._get_workflow_agent_dependencies(session)
2771
2782
 
2772
2783
  # Run the agent
2773
2784
  agent_response: RunOutput = self.agent.run( # type: ignore[union-attr]
2774
2785
  input=agent_input,
2775
2786
  session_id=session.session_id,
2776
- dependencies=dependencies,
2787
+ dependencies=run_context.dependencies,
2788
+ session_state=run_context.session_state,
2777
2789
  stream=stream,
2778
2790
  ) # type: ignore
2779
2791
 
@@ -2865,7 +2877,7 @@ class Workflow:
2865
2877
  self,
2866
2878
  session: WorkflowSession,
2867
2879
  execution_input: WorkflowExecutionInput,
2868
- session_state: Optional[Dict[str, Any]],
2880
+ run_context: RunContext,
2869
2881
  websocket_handler: Optional[WebSocketHandler] = None,
2870
2882
  stream: bool = False,
2871
2883
  ) -> None:
@@ -2876,7 +2888,7 @@ class Workflow:
2876
2888
  workflow=self,
2877
2889
  session=session,
2878
2890
  execution_input=execution_input,
2879
- session_state=session_state,
2891
+ run_context=run_context,
2880
2892
  stream=stream,
2881
2893
  websocket_handler=websocket_handler,
2882
2894
  )
@@ -2899,10 +2911,8 @@ class Workflow:
2899
2911
  def _aexecute_workflow_agent(
2900
2912
  self,
2901
2913
  user_input: Union[str, Dict[str, Any], List[Any], BaseModel],
2902
- session_id: str,
2903
- user_id: Optional[str],
2914
+ run_context: RunContext,
2904
2915
  execution_input: WorkflowExecutionInput,
2905
- session_state: Optional[Dict[str, Any]],
2906
2916
  stream: bool = False,
2907
2917
  websocket_handler: Optional[WebSocketHandler] = None,
2908
2918
  **kwargs: Any,
@@ -2914,27 +2924,27 @@ class Workflow:
2914
2924
 
2915
2925
  Args:
2916
2926
  user_input: The user's input
2917
- session_id: The workflow session ID
2918
- user_id: The user ID
2927
+ session: The workflow session
2928
+ run_context: The run context
2919
2929
  execution_input: The execution input
2920
- session_state: The session state
2921
2930
  stream: Whether to stream the response
2922
2931
  websocket_handler: The WebSocket handler
2923
2932
 
2924
2933
  Returns:
2925
2934
  Coroutine[WorkflowRunOutput] if stream=False, AsyncIterator[WorkflowRunOutputEvent] if stream=True
2926
2935
  """
2936
+
2927
2937
  if stream:
2928
2938
 
2929
2939
  async def _stream():
2930
2940
  session, session_state_loaded = await self._aload_session_for_workflow_agent(
2931
- session_id, user_id, session_state
2941
+ run_context.session_id, run_context.user_id, run_context.session_state
2932
2942
  )
2933
2943
  async for event in self._arun_workflow_agent_stream(
2934
2944
  agent_input=user_input,
2935
2945
  session=session,
2936
2946
  execution_input=execution_input,
2937
- session_state=session_state_loaded,
2947
+ run_context=run_context,
2938
2948
  stream=stream,
2939
2949
  websocket_handler=websocket_handler,
2940
2950
  **kwargs,
@@ -2946,13 +2956,13 @@ class Workflow:
2946
2956
 
2947
2957
  async def _execute():
2948
2958
  session, session_state_loaded = await self._aload_session_for_workflow_agent(
2949
- session_id, user_id, session_state
2959
+ run_context.session_id, run_context.user_id, run_context.session_state
2950
2960
  )
2951
2961
  return await self._arun_workflow_agent(
2952
2962
  agent_input=user_input,
2953
2963
  session=session,
2954
2964
  execution_input=execution_input,
2955
- session_state=session_state_loaded,
2965
+ run_context=run_context,
2956
2966
  stream=stream,
2957
2967
  )
2958
2968
 
@@ -2963,7 +2973,7 @@ class Workflow:
2963
2973
  agent_input: Union[str, Dict[str, Any], List[Any], BaseModel],
2964
2974
  session: WorkflowSession,
2965
2975
  execution_input: WorkflowExecutionInput,
2966
- session_state: Optional[Dict[str, Any]],
2976
+ run_context: RunContext,
2967
2977
  stream: bool = False,
2968
2978
  websocket_handler: Optional[WebSocketHandler] = None,
2969
2979
  **kwargs: Any,
@@ -2986,10 +2996,14 @@ class Workflow:
2986
2996
  log_debug(f"User input: {agent_input}")
2987
2997
 
2988
2998
  self._async_initialize_workflow_agent(
2989
- session, execution_input, session_state, stream=stream, websocket_handler=websocket_handler
2999
+ session,
3000
+ execution_input,
3001
+ run_context=run_context,
3002
+ stream=stream,
3003
+ websocket_handler=websocket_handler,
2990
3004
  )
2991
3005
 
2992
- dependencies = self._get_workflow_agent_dependencies(session)
3006
+ run_context.dependencies = self._get_workflow_agent_dependencies(session)
2993
3007
 
2994
3008
  agent_response: Optional[RunOutput] = None
2995
3009
  workflow_executed = False
@@ -3027,7 +3041,8 @@ class Workflow:
3027
3041
  stream_intermediate_steps=True,
3028
3042
  yield_run_response=True,
3029
3043
  session_id=session.session_id,
3030
- dependencies=dependencies, # Pass context dynamically per-run
3044
+ dependencies=run_context.dependencies, # Pass context dynamically per-run
3045
+ session_state=run_context.session_state, # Pass session state dynamically per-run
3031
3046
  ): # type: ignore
3032
3047
  if isinstance(event, tuple(get_args(WorkflowRunOutputEvent))):
3033
3048
  yield event # type: ignore[misc]
@@ -3150,7 +3165,7 @@ class Workflow:
3150
3165
  agent_input: Union[str, Dict[str, Any], List[Any], BaseModel],
3151
3166
  session: WorkflowSession,
3152
3167
  execution_input: WorkflowExecutionInput,
3153
- session_state: Optional[Dict[str, Any]],
3168
+ run_context: RunContext,
3154
3169
  stream: bool = False,
3155
3170
  ) -> WorkflowRunOutput:
3156
3171
  """
@@ -3162,16 +3177,17 @@ class Workflow:
3162
3177
  WorkflowRunOutput: The workflow run output with agent response
3163
3178
  """
3164
3179
  # Initialize the agent
3165
- self._async_initialize_workflow_agent(session, execution_input, session_state, stream=stream)
3180
+ self._async_initialize_workflow_agent(session, execution_input, run_context=run_context, stream=stream)
3166
3181
 
3167
3182
  # Build dependencies with workflow context
3168
- dependencies = self._get_workflow_agent_dependencies(session)
3183
+ run_context.dependencies = self._get_workflow_agent_dependencies(session)
3169
3184
 
3170
3185
  # Run the agent
3171
3186
  agent_response: RunOutput = await self.agent.arun( # type: ignore[union-attr]
3172
3187
  input=agent_input,
3173
3188
  session_id=session.session_id,
3174
- dependencies=dependencies,
3189
+ dependencies=run_context.dependencies,
3190
+ session_state=run_context.session_state,
3175
3191
  stream=stream,
3176
3192
  ) # type: ignore
3177
3193
 
@@ -3366,6 +3382,14 @@ class Workflow:
3366
3382
  # Update session state from DB
3367
3383
  session_state = self._load_session_state(session=workflow_session, session_state=session_state)
3368
3384
 
3385
+ # Initialize run context
3386
+ run_context = RunContext(
3387
+ run_id=run_id,
3388
+ session_id=session_id,
3389
+ user_id=user_id,
3390
+ session_state=session_state,
3391
+ )
3392
+
3369
3393
  log_debug(f"Workflow Run Start: {self.name}", center=True)
3370
3394
 
3371
3395
  # Use simple defaults
@@ -3404,7 +3428,7 @@ class Workflow:
3404
3428
  user_input=input, # type: ignore
3405
3429
  session=workflow_session,
3406
3430
  execution_input=inputs,
3407
- session_state=session_state,
3431
+ run_context=run_context,
3408
3432
  stream=stream,
3409
3433
  **kwargs,
3410
3434
  )
@@ -3425,7 +3449,7 @@ class Workflow:
3425
3449
  execution_input=inputs, # type: ignore[arg-type]
3426
3450
  workflow_run_response=workflow_run_response,
3427
3451
  stream_events=stream_events,
3428
- session_state=session_state,
3452
+ run_context=run_context,
3429
3453
  **kwargs,
3430
3454
  )
3431
3455
  else:
@@ -3433,7 +3457,7 @@ class Workflow:
3433
3457
  session=workflow_session,
3434
3458
  execution_input=inputs, # type: ignore[arg-type]
3435
3459
  workflow_run_response=workflow_run_response,
3436
- session_state=session_state,
3460
+ run_context=run_context,
3437
3461
  **kwargs,
3438
3462
  )
3439
3463
 
@@ -3548,6 +3572,14 @@ class Workflow:
3548
3572
  self.initialize_workflow()
3549
3573
  session_id, user_id = self._initialize_session(session_id=session_id, user_id=user_id)
3550
3574
 
3575
+ # Initialize run context
3576
+ run_context = RunContext(
3577
+ run_id=run_id,
3578
+ session_id=session_id,
3579
+ user_id=user_id,
3580
+ session_state=session_state,
3581
+ )
3582
+
3551
3583
  log_debug(f"Async Workflow Run Start: {self.name}", center=True)
3552
3584
 
3553
3585
  # Use simple defaults
@@ -3582,10 +3614,8 @@ class Workflow:
3582
3614
  if self.agent is not None:
3583
3615
  return self._aexecute_workflow_agent( # type: ignore
3584
3616
  user_input=input, # type: ignore
3585
- session_id=session_id,
3586
- user_id=user_id,
3587
3617
  execution_input=inputs,
3588
- session_state=session_state,
3618
+ run_context=run_context,
3589
3619
  stream=stream,
3590
3620
  **kwargs,
3591
3621
  )
@@ -3687,6 +3717,7 @@ class Workflow:
3687
3717
  audio: Audio input
3688
3718
  images: Image input
3689
3719
  videos: Video input
3720
+ files: File input
3690
3721
  stream: Whether to stream the response content
3691
3722
  stream_events: Whether to stream intermediate steps
3692
3723
  markdown: Whether to render content as markdown
@@ -3780,6 +3811,7 @@ class Workflow:
3780
3811
  audio: Audio input
3781
3812
  images: Image input
3782
3813
  videos: Video input
3814
+ files: Files input
3783
3815
  stream: Whether to stream the response content
3784
3816
  stream_events: Whether to stream intermediate steps
3785
3817
  markdown: Whether to render content as markdown
@@ -3886,7 +3918,7 @@ class Workflow:
3886
3918
  step_dict["team"] = step.team if hasattr(step, "team") else None # type: ignore
3887
3919
 
3888
3920
  # Handle nested steps for Router/Loop
3889
- if isinstance(step, (Router)):
3921
+ if isinstance(step, Router):
3890
3922
  step_dict["steps"] = (
3891
3923
  [serialize_step(step) for step in step.choices] if hasattr(step, "choices") else None
3892
3924
  )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agno
3
- Version: 2.2.6
3
+ Version: 2.2.8
4
4
  Summary: Agno: a lightweight library for building Multi-Agent Systems
5
5
  Author-email: Ashpreet Bedi <ashpreet@agno.com>
6
6
  Project-URL: homepage, https://agno.com
@@ -35,12 +35,12 @@ Requires-Dist: rich
35
35
  Requires-Dist: typer
36
36
  Requires-Dist: typing-extensions
37
37
  Provides-Extra: dev
38
- Requires-Dist: mypy; extra == "dev"
38
+ Requires-Dist: mypy==1.18.2; extra == "dev"
39
+ Requires-Dist: ruff==0.14.3; extra == "dev"
39
40
  Requires-Dist: pytest; extra == "dev"
40
41
  Requires-Dist: pytest-asyncio; extra == "dev"
41
42
  Requires-Dist: pytest-cov; extra == "dev"
42
43
  Requires-Dist: pytest-mock; extra == "dev"
43
- Requires-Dist: ruff; extra == "dev"
44
44
  Requires-Dist: timeout-decorator; extra == "dev"
45
45
  Requires-Dist: types-pyyaml; extra == "dev"
46
46
  Requires-Dist: types-aiofiles; extra == "dev"
@@ -206,6 +206,7 @@ Provides-Extra: firestore
206
206
  Requires-Dist: google-cloud-firestore; extra == "firestore"
207
207
  Provides-Extra: redis
208
208
  Requires-Dist: redis; extra == "redis"
209
+ Requires-Dist: redisvl; extra == "redis"
209
210
  Provides-Extra: pgvector
210
211
  Requires-Dist: pgvector; extra == "pgvector"
211
212
  Provides-Extra: chromadb
@@ -261,6 +262,8 @@ Provides-Extra: a2a
261
262
  Requires-Dist: a2a-sdk; extra == "a2a"
262
263
  Provides-Extra: huggingface
263
264
  Requires-Dist: huggingface-hub; extra == "huggingface"
265
+ Provides-Extra: vllm
266
+ Requires-Dist: vllm; extra == "vllm"
264
267
  Provides-Extra: performance
265
268
  Requires-Dist: memory_profiler; extra == "performance"
266
269
  Provides-Extra: cookbooks
@@ -361,6 +364,7 @@ Requires-Dist: agno[markdown]; extra == "knowledge"
361
364
  Requires-Dist: agno[chonkie]; extra == "knowledge"
362
365
  Provides-Extra: embedders
363
366
  Requires-Dist: agno[huggingface]; extra == "embedders"
367
+ Requires-Dist: agno[vllm]; extra == "embedders"
364
368
  Provides-Extra: tests
365
369
  Requires-Dist: agno[dev]; extra == "tests"
366
370
  Requires-Dist: agno[models]; extra == "tests"