agno 2.2.9__py3-none-any.whl → 2.2.11__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- agno/agent/agent.py +27 -5
- agno/db/dynamo/utils.py +1 -1
- agno/db/firestore/utils.py +1 -1
- agno/db/gcs_json/utils.py +1 -1
- agno/db/in_memory/utils.py +1 -1
- agno/db/json/utils.py +1 -1
- agno/db/mongo/utils.py +3 -3
- agno/db/mysql/utils.py +1 -1
- agno/db/postgres/utils.py +1 -1
- agno/db/redis/utils.py +1 -1
- agno/db/singlestore/utils.py +1 -1
- agno/db/sqlite/utils.py +1 -1
- agno/knowledge/chunking/agentic.py +8 -9
- agno/knowledge/chunking/strategy.py +59 -15
- agno/knowledge/embedder/sentence_transformer.py +6 -2
- agno/knowledge/reader/base.py +6 -2
- agno/knowledge/utils.py +20 -0
- agno/models/anthropic/claude.py +45 -9
- agno/models/base.py +4 -0
- agno/os/app.py +35 -19
- agno/os/routers/health.py +5 -3
- agno/os/routers/knowledge/knowledge.py +43 -17
- agno/os/routers/knowledge/schemas.py +4 -3
- agno/run/agent.py +11 -1
- agno/team/team.py +20 -3
- agno/tools/file_generation.py +4 -4
- agno/tools/gmail.py +179 -0
- agno/tools/parallel.py +314 -0
- agno/utils/models/claude.py +2 -1
- agno/workflow/agent.py +2 -2
- agno/workflow/condition.py +26 -4
- agno/workflow/loop.py +9 -0
- agno/workflow/parallel.py +39 -16
- agno/workflow/router.py +25 -4
- agno/workflow/step.py +163 -91
- agno/workflow/steps.py +9 -0
- agno/workflow/types.py +20 -1
- agno/workflow/workflow.py +117 -30
- {agno-2.2.9.dist-info → agno-2.2.11.dist-info}/METADATA +4 -1
- {agno-2.2.9.dist-info → agno-2.2.11.dist-info}/RECORD +43 -42
- {agno-2.2.9.dist-info → agno-2.2.11.dist-info}/WHEEL +0 -0
- {agno-2.2.9.dist-info → agno-2.2.11.dist-info}/licenses/LICENSE +0 -0
- {agno-2.2.9.dist-info → agno-2.2.11.dist-info}/top_level.txt +0 -0
agno/workflow/parallel.py
CHANGED
|
@@ -7,6 +7,7 @@ from uuid import uuid4
|
|
|
7
7
|
|
|
8
8
|
from agno.models.metrics import Metrics
|
|
9
9
|
from agno.run.agent import RunOutputEvent
|
|
10
|
+
from agno.run.base import RunContext
|
|
10
11
|
from agno.run.team import TeamRunOutputEvent
|
|
11
12
|
from agno.run.workflow import (
|
|
12
13
|
ParallelExecutionCompletedEvent,
|
|
@@ -200,6 +201,7 @@ class Parallel:
|
|
|
200
201
|
user_id: Optional[str] = None,
|
|
201
202
|
workflow_run_response: Optional[WorkflowRunOutput] = None,
|
|
202
203
|
store_executor_outputs: bool = True,
|
|
204
|
+
run_context: Optional[RunContext] = None,
|
|
203
205
|
session_state: Optional[Dict[str, Any]] = None,
|
|
204
206
|
workflow_session: Optional[WorkflowSession] = None,
|
|
205
207
|
add_workflow_history_to_steps: Optional[bool] = False,
|
|
@@ -214,10 +216,14 @@ class Parallel:
|
|
|
214
216
|
# Create individual session_state copies for each step to prevent race conditions
|
|
215
217
|
session_state_copies = []
|
|
216
218
|
for _ in range(len(self.steps)):
|
|
217
|
-
|
|
218
|
-
|
|
219
|
+
# If using run context, no need to deepcopy the state. We want the direct reference.
|
|
220
|
+
if run_context is not None and run_context.session_state is not None:
|
|
221
|
+
session_state_copies.append(run_context.session_state)
|
|
219
222
|
else:
|
|
220
|
-
|
|
223
|
+
if session_state is not None:
|
|
224
|
+
session_state_copies.append(deepcopy(session_state))
|
|
225
|
+
else:
|
|
226
|
+
session_state_copies.append({})
|
|
221
227
|
|
|
222
228
|
def execute_step_with_index(step_with_index):
|
|
223
229
|
"""Execute a single step and preserve its original index"""
|
|
@@ -235,6 +241,7 @@ class Parallel:
|
|
|
235
241
|
workflow_session=workflow_session,
|
|
236
242
|
add_workflow_history_to_steps=add_workflow_history_to_steps,
|
|
237
243
|
num_history_runs=num_history_runs,
|
|
244
|
+
run_context=run_context,
|
|
238
245
|
session_state=step_session_state,
|
|
239
246
|
) # type: ignore[union-attr]
|
|
240
247
|
return idx, step_result, step_session_state
|
|
@@ -288,7 +295,7 @@ class Parallel:
|
|
|
288
295
|
)
|
|
289
296
|
)
|
|
290
297
|
|
|
291
|
-
if session_state is not None:
|
|
298
|
+
if run_context is None and session_state is not None:
|
|
292
299
|
merge_parallel_session_states(session_state, modified_session_states)
|
|
293
300
|
|
|
294
301
|
# Sort by original index to preserve order
|
|
@@ -322,6 +329,7 @@ class Parallel:
|
|
|
322
329
|
workflow_run_response: Optional[WorkflowRunOutput] = None,
|
|
323
330
|
step_index: Optional[Union[int, tuple]] = None,
|
|
324
331
|
store_executor_outputs: bool = True,
|
|
332
|
+
run_context: Optional[RunContext] = None,
|
|
325
333
|
session_state: Optional[Dict[str, Any]] = None,
|
|
326
334
|
parent_step_id: Optional[str] = None,
|
|
327
335
|
workflow_session: Optional[WorkflowSession] = None,
|
|
@@ -338,10 +346,14 @@ class Parallel:
|
|
|
338
346
|
# Create individual session_state copies for each step to prevent race conditions
|
|
339
347
|
session_state_copies = []
|
|
340
348
|
for _ in range(len(self.steps)):
|
|
341
|
-
|
|
342
|
-
|
|
349
|
+
# If using run context, no need to deepcopy the state. We want the direct reference.
|
|
350
|
+
if run_context is not None and run_context.session_state is not None:
|
|
351
|
+
session_state_copies.append(run_context.session_state)
|
|
343
352
|
else:
|
|
344
|
-
|
|
353
|
+
if session_state is not None:
|
|
354
|
+
session_state_copies.append(deepcopy(session_state))
|
|
355
|
+
else:
|
|
356
|
+
session_state_copies.append({})
|
|
345
357
|
|
|
346
358
|
# Considering both stream_events and stream_intermediate_steps (deprecated)
|
|
347
359
|
stream_events = stream_events or stream_intermediate_steps
|
|
@@ -468,7 +480,7 @@ class Parallel:
|
|
|
468
480
|
logger.error(f"Future completion error: {e}")
|
|
469
481
|
|
|
470
482
|
# Merge all session_state changes back into the original session_state
|
|
471
|
-
if session_state is not None:
|
|
483
|
+
if run_context is None and session_state is not None:
|
|
472
484
|
merge_parallel_session_states(session_state, modified_session_states)
|
|
473
485
|
|
|
474
486
|
# Flatten step_results - handle steps that return List[StepOutput] (like Condition/Loop)
|
|
@@ -509,6 +521,7 @@ class Parallel:
|
|
|
509
521
|
user_id: Optional[str] = None,
|
|
510
522
|
workflow_run_response: Optional[WorkflowRunOutput] = None,
|
|
511
523
|
store_executor_outputs: bool = True,
|
|
524
|
+
run_context: Optional[RunContext] = None,
|
|
512
525
|
session_state: Optional[Dict[str, Any]] = None,
|
|
513
526
|
workflow_session: Optional[WorkflowSession] = None,
|
|
514
527
|
add_workflow_history_to_steps: Optional[bool] = False,
|
|
@@ -523,10 +536,14 @@ class Parallel:
|
|
|
523
536
|
# Create individual session_state copies for each step to prevent race conditions
|
|
524
537
|
session_state_copies = []
|
|
525
538
|
for _ in range(len(self.steps)):
|
|
526
|
-
|
|
527
|
-
|
|
539
|
+
# If using run context, no need to deepcopy the state. We want the direct reference.
|
|
540
|
+
if run_context is not None and run_context.session_state is not None:
|
|
541
|
+
session_state_copies.append(run_context.session_state)
|
|
528
542
|
else:
|
|
529
|
-
|
|
543
|
+
if session_state is not None:
|
|
544
|
+
session_state_copies.append(deepcopy(session_state))
|
|
545
|
+
else:
|
|
546
|
+
session_state_copies.append({})
|
|
530
547
|
|
|
531
548
|
async def execute_step_async_with_index(step_with_index):
|
|
532
549
|
"""Execute a single step asynchronously and preserve its original index"""
|
|
@@ -598,7 +615,7 @@ class Parallel:
|
|
|
598
615
|
log_debug(f"Parallel step {step_name} completed")
|
|
599
616
|
|
|
600
617
|
# Smart merge all session_state changes back into the original session_state
|
|
601
|
-
if session_state is not None:
|
|
618
|
+
if run_context is None and session_state is not None:
|
|
602
619
|
merge_parallel_session_states(session_state, modified_session_states)
|
|
603
620
|
|
|
604
621
|
# Sort by original index to preserve order
|
|
@@ -632,6 +649,7 @@ class Parallel:
|
|
|
632
649
|
workflow_run_response: Optional[WorkflowRunOutput] = None,
|
|
633
650
|
step_index: Optional[Union[int, tuple]] = None,
|
|
634
651
|
store_executor_outputs: bool = True,
|
|
652
|
+
run_context: Optional[RunContext] = None,
|
|
635
653
|
session_state: Optional[Dict[str, Any]] = None,
|
|
636
654
|
parent_step_id: Optional[str] = None,
|
|
637
655
|
workflow_session: Optional[WorkflowSession] = None,
|
|
@@ -648,10 +666,14 @@ class Parallel:
|
|
|
648
666
|
# Create individual session_state copies for each step to prevent race conditions
|
|
649
667
|
session_state_copies = []
|
|
650
668
|
for _ in range(len(self.steps)):
|
|
651
|
-
|
|
652
|
-
|
|
669
|
+
# If using run context, no need to deepcopy the state. We want the direct reference.
|
|
670
|
+
if run_context is not None and run_context.session_state is not None:
|
|
671
|
+
session_state_copies.append(run_context.session_state)
|
|
653
672
|
else:
|
|
654
|
-
|
|
673
|
+
if session_state is not None:
|
|
674
|
+
session_state_copies.append(deepcopy(session_state))
|
|
675
|
+
else:
|
|
676
|
+
session_state_copies.append({})
|
|
655
677
|
|
|
656
678
|
# Considering both stream_events and stream_intermediate_steps (deprecated)
|
|
657
679
|
stream_events = stream_events or stream_intermediate_steps
|
|
@@ -705,6 +727,7 @@ class Parallel:
|
|
|
705
727
|
step_index=sub_step_index,
|
|
706
728
|
store_executor_outputs=store_executor_outputs,
|
|
707
729
|
session_state=step_session_state,
|
|
730
|
+
run_context=run_context,
|
|
708
731
|
parent_step_id=parallel_step_id,
|
|
709
732
|
workflow_session=workflow_session,
|
|
710
733
|
add_workflow_history_to_steps=add_workflow_history_to_steps,
|
|
@@ -766,7 +789,7 @@ class Parallel:
|
|
|
766
789
|
await asyncio.gather(*tasks, return_exceptions=True)
|
|
767
790
|
|
|
768
791
|
# Merge all session_state changes back into the original session_state
|
|
769
|
-
if session_state is not None:
|
|
792
|
+
if run_context is None and session_state is not None:
|
|
770
793
|
merge_parallel_session_states(session_state, modified_session_states)
|
|
771
794
|
|
|
772
795
|
# Flatten step_results - handle steps that return List[StepOutput] (like Condition/Loop)
|
agno/workflow/router.py
CHANGED
|
@@ -4,6 +4,7 @@ from typing import Any, AsyncIterator, Awaitable, Callable, Dict, Iterator, List
|
|
|
4
4
|
from uuid import uuid4
|
|
5
5
|
|
|
6
6
|
from agno.run.agent import RunOutputEvent
|
|
7
|
+
from agno.run.base import RunContext
|
|
7
8
|
from agno.run.team import TeamRunOutputEvent
|
|
8
9
|
from agno.run.workflow import (
|
|
9
10
|
RouterExecutionCompletedEvent,
|
|
@@ -171,6 +172,7 @@ class Router:
|
|
|
171
172
|
session_id: Optional[str] = None,
|
|
172
173
|
user_id: Optional[str] = None,
|
|
173
174
|
workflow_run_response: Optional[WorkflowRunOutput] = None,
|
|
175
|
+
run_context: Optional[RunContext] = None,
|
|
174
176
|
session_state: Optional[Dict[str, Any]] = None,
|
|
175
177
|
store_executor_outputs: bool = True,
|
|
176
178
|
workflow_session: Optional[WorkflowSession] = None,
|
|
@@ -185,7 +187,10 @@ class Router:
|
|
|
185
187
|
self._prepare_steps()
|
|
186
188
|
|
|
187
189
|
# Route to appropriate steps
|
|
188
|
-
|
|
190
|
+
if run_context is not None and run_context.session_state is not None:
|
|
191
|
+
steps_to_execute = self._route_steps(step_input, session_state=run_context.session_state)
|
|
192
|
+
else:
|
|
193
|
+
steps_to_execute = self._route_steps(step_input, session_state=session_state)
|
|
189
194
|
log_debug(f"Router {self.name}: Selected {len(steps_to_execute)} steps to execute")
|
|
190
195
|
|
|
191
196
|
if not steps_to_execute:
|
|
@@ -209,6 +214,7 @@ class Router:
|
|
|
209
214
|
user_id=user_id,
|
|
210
215
|
workflow_run_response=workflow_run_response,
|
|
211
216
|
store_executor_outputs=store_executor_outputs,
|
|
217
|
+
run_context=run_context,
|
|
212
218
|
session_state=session_state,
|
|
213
219
|
workflow_session=workflow_session,
|
|
214
220
|
add_workflow_history_to_steps=add_workflow_history_to_steps,
|
|
@@ -266,6 +272,7 @@ class Router:
|
|
|
266
272
|
step_input: StepInput,
|
|
267
273
|
session_id: Optional[str] = None,
|
|
268
274
|
user_id: Optional[str] = None,
|
|
275
|
+
run_context: Optional[RunContext] = None,
|
|
269
276
|
session_state: Optional[Dict[str, Any]] = None,
|
|
270
277
|
stream_events: bool = False,
|
|
271
278
|
stream_intermediate_steps: bool = False,
|
|
@@ -286,7 +293,10 @@ class Router:
|
|
|
286
293
|
router_step_id = str(uuid4())
|
|
287
294
|
|
|
288
295
|
# Route to appropriate steps
|
|
289
|
-
|
|
296
|
+
if run_context is not None and run_context.session_state is not None:
|
|
297
|
+
steps_to_execute = self._route_steps(step_input, session_state=run_context.session_state)
|
|
298
|
+
else:
|
|
299
|
+
steps_to_execute = self._route_steps(step_input, session_state=session_state)
|
|
290
300
|
log_debug(f"Router {self.name}: Selected {len(steps_to_execute)} steps to execute")
|
|
291
301
|
|
|
292
302
|
# Considering both stream_events and stream_intermediate_steps (deprecated)
|
|
@@ -341,6 +351,7 @@ class Router:
|
|
|
341
351
|
workflow_run_response=workflow_run_response,
|
|
342
352
|
step_index=step_index,
|
|
343
353
|
store_executor_outputs=store_executor_outputs,
|
|
354
|
+
run_context=run_context,
|
|
344
355
|
session_state=session_state,
|
|
345
356
|
parent_step_id=router_step_id,
|
|
346
357
|
workflow_session=workflow_session,
|
|
@@ -425,6 +436,7 @@ class Router:
|
|
|
425
436
|
session_id: Optional[str] = None,
|
|
426
437
|
user_id: Optional[str] = None,
|
|
427
438
|
workflow_run_response: Optional[WorkflowRunOutput] = None,
|
|
439
|
+
run_context: Optional[RunContext] = None,
|
|
428
440
|
session_state: Optional[Dict[str, Any]] = None,
|
|
429
441
|
store_executor_outputs: bool = True,
|
|
430
442
|
workflow_session: Optional[WorkflowSession] = None,
|
|
@@ -439,7 +451,10 @@ class Router:
|
|
|
439
451
|
self._prepare_steps()
|
|
440
452
|
|
|
441
453
|
# Route to appropriate steps
|
|
442
|
-
|
|
454
|
+
if run_context is not None and run_context.session_state is not None:
|
|
455
|
+
steps_to_execute = await self._aroute_steps(step_input, session_state=run_context.session_state)
|
|
456
|
+
else:
|
|
457
|
+
steps_to_execute = await self._aroute_steps(step_input, session_state=session_state)
|
|
443
458
|
log_debug(f"Router {self.name} selected: {len(steps_to_execute)} steps to execute")
|
|
444
459
|
|
|
445
460
|
if not steps_to_execute:
|
|
@@ -464,6 +479,7 @@ class Router:
|
|
|
464
479
|
user_id=user_id,
|
|
465
480
|
workflow_run_response=workflow_run_response,
|
|
466
481
|
store_executor_outputs=store_executor_outputs,
|
|
482
|
+
run_context=run_context,
|
|
467
483
|
session_state=session_state,
|
|
468
484
|
workflow_session=workflow_session,
|
|
469
485
|
add_workflow_history_to_steps=add_workflow_history_to_steps,
|
|
@@ -523,6 +539,7 @@ class Router:
|
|
|
523
539
|
step_input: StepInput,
|
|
524
540
|
session_id: Optional[str] = None,
|
|
525
541
|
user_id: Optional[str] = None,
|
|
542
|
+
run_context: Optional[RunContext] = None,
|
|
526
543
|
session_state: Optional[Dict[str, Any]] = None,
|
|
527
544
|
stream_events: bool = False,
|
|
528
545
|
stream_intermediate_steps: bool = False,
|
|
@@ -543,7 +560,10 @@ class Router:
|
|
|
543
560
|
router_step_id = str(uuid4())
|
|
544
561
|
|
|
545
562
|
# Route to appropriate steps
|
|
546
|
-
|
|
563
|
+
if run_context is not None and run_context.session_state is not None:
|
|
564
|
+
steps_to_execute = await self._aroute_steps(step_input, session_state=run_context.session_state)
|
|
565
|
+
else:
|
|
566
|
+
steps_to_execute = await self._aroute_steps(step_input, session_state=session_state)
|
|
547
567
|
log_debug(f"Router {self.name} selected: {len(steps_to_execute)} steps to execute")
|
|
548
568
|
|
|
549
569
|
# Considering both stream_events and stream_intermediate_steps (deprecated)
|
|
@@ -600,6 +620,7 @@ class Router:
|
|
|
600
620
|
workflow_run_response=workflow_run_response,
|
|
601
621
|
step_index=step_index,
|
|
602
622
|
store_executor_outputs=store_executor_outputs,
|
|
623
|
+
run_context=run_context,
|
|
603
624
|
session_state=session_state,
|
|
604
625
|
parent_step_id=router_step_id,
|
|
605
626
|
workflow_session=workflow_session,
|