agno 2.2.13__py3-none-any.whl → 2.4.3__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/__init__.py +6 -0
- agno/agent/agent.py +5252 -3145
- agno/agent/remote.py +525 -0
- agno/api/api.py +2 -0
- agno/client/__init__.py +3 -0
- agno/client/a2a/__init__.py +10 -0
- agno/client/a2a/client.py +554 -0
- agno/client/a2a/schemas.py +112 -0
- agno/client/a2a/utils.py +369 -0
- agno/client/os.py +2669 -0
- agno/compression/__init__.py +3 -0
- agno/compression/manager.py +247 -0
- agno/culture/manager.py +2 -2
- agno/db/base.py +927 -6
- agno/db/dynamo/dynamo.py +788 -2
- agno/db/dynamo/schemas.py +128 -0
- agno/db/dynamo/utils.py +26 -3
- agno/db/firestore/firestore.py +674 -50
- agno/db/firestore/schemas.py +41 -0
- agno/db/firestore/utils.py +25 -10
- agno/db/gcs_json/gcs_json_db.py +506 -3
- agno/db/gcs_json/utils.py +14 -2
- agno/db/in_memory/in_memory_db.py +203 -4
- agno/db/in_memory/utils.py +14 -2
- agno/db/json/json_db.py +498 -2
- agno/db/json/utils.py +14 -2
- agno/db/migrations/manager.py +199 -0
- agno/db/migrations/utils.py +19 -0
- agno/db/migrations/v1_to_v2.py +54 -16
- agno/db/migrations/versions/__init__.py +0 -0
- agno/db/migrations/versions/v2_3_0.py +977 -0
- agno/db/mongo/async_mongo.py +1013 -39
- agno/db/mongo/mongo.py +684 -4
- agno/db/mongo/schemas.py +48 -0
- agno/db/mongo/utils.py +17 -0
- agno/db/mysql/__init__.py +2 -1
- agno/db/mysql/async_mysql.py +2958 -0
- agno/db/mysql/mysql.py +722 -53
- agno/db/mysql/schemas.py +77 -11
- agno/db/mysql/utils.py +151 -8
- agno/db/postgres/async_postgres.py +1254 -137
- agno/db/postgres/postgres.py +2316 -93
- agno/db/postgres/schemas.py +153 -21
- agno/db/postgres/utils.py +22 -7
- agno/db/redis/redis.py +531 -3
- agno/db/redis/schemas.py +36 -0
- agno/db/redis/utils.py +31 -15
- agno/db/schemas/evals.py +1 -0
- agno/db/schemas/memory.py +20 -9
- agno/db/singlestore/schemas.py +70 -1
- agno/db/singlestore/singlestore.py +737 -74
- agno/db/singlestore/utils.py +13 -3
- agno/db/sqlite/async_sqlite.py +1069 -89
- agno/db/sqlite/schemas.py +133 -1
- agno/db/sqlite/sqlite.py +2203 -165
- agno/db/sqlite/utils.py +21 -11
- agno/db/surrealdb/models.py +25 -0
- agno/db/surrealdb/surrealdb.py +603 -1
- agno/db/utils.py +60 -0
- agno/eval/__init__.py +26 -3
- agno/eval/accuracy.py +25 -12
- agno/eval/agent_as_judge.py +871 -0
- agno/eval/base.py +29 -0
- agno/eval/performance.py +10 -4
- agno/eval/reliability.py +22 -13
- agno/eval/utils.py +2 -1
- agno/exceptions.py +42 -0
- agno/hooks/__init__.py +3 -0
- agno/hooks/decorator.py +164 -0
- agno/integrations/discord/client.py +13 -2
- agno/knowledge/__init__.py +4 -0
- agno/knowledge/chunking/code.py +90 -0
- agno/knowledge/chunking/document.py +65 -4
- agno/knowledge/chunking/fixed.py +4 -1
- agno/knowledge/chunking/markdown.py +102 -11
- agno/knowledge/chunking/recursive.py +2 -2
- agno/knowledge/chunking/semantic.py +130 -48
- agno/knowledge/chunking/strategy.py +18 -0
- agno/knowledge/embedder/azure_openai.py +0 -1
- agno/knowledge/embedder/google.py +1 -1
- agno/knowledge/embedder/mistral.py +1 -1
- agno/knowledge/embedder/nebius.py +1 -1
- agno/knowledge/embedder/openai.py +16 -12
- agno/knowledge/filesystem.py +412 -0
- agno/knowledge/knowledge.py +4261 -1199
- agno/knowledge/protocol.py +134 -0
- agno/knowledge/reader/arxiv_reader.py +3 -2
- agno/knowledge/reader/base.py +9 -7
- agno/knowledge/reader/csv_reader.py +91 -42
- agno/knowledge/reader/docx_reader.py +9 -10
- agno/knowledge/reader/excel_reader.py +225 -0
- agno/knowledge/reader/field_labeled_csv_reader.py +38 -48
- agno/knowledge/reader/firecrawl_reader.py +3 -2
- agno/knowledge/reader/json_reader.py +16 -22
- agno/knowledge/reader/markdown_reader.py +15 -14
- agno/knowledge/reader/pdf_reader.py +33 -28
- agno/knowledge/reader/pptx_reader.py +9 -10
- agno/knowledge/reader/reader_factory.py +135 -1
- agno/knowledge/reader/s3_reader.py +8 -16
- agno/knowledge/reader/tavily_reader.py +3 -3
- agno/knowledge/reader/text_reader.py +15 -14
- agno/knowledge/reader/utils/__init__.py +17 -0
- agno/knowledge/reader/utils/spreadsheet.py +114 -0
- agno/knowledge/reader/web_search_reader.py +8 -65
- agno/knowledge/reader/website_reader.py +16 -13
- agno/knowledge/reader/wikipedia_reader.py +36 -3
- agno/knowledge/reader/youtube_reader.py +3 -2
- agno/knowledge/remote_content/__init__.py +33 -0
- agno/knowledge/remote_content/config.py +266 -0
- agno/knowledge/remote_content/remote_content.py +105 -17
- agno/knowledge/utils.py +76 -22
- agno/learn/__init__.py +71 -0
- agno/learn/config.py +463 -0
- agno/learn/curate.py +185 -0
- agno/learn/machine.py +725 -0
- agno/learn/schemas.py +1114 -0
- agno/learn/stores/__init__.py +38 -0
- agno/learn/stores/decision_log.py +1156 -0
- agno/learn/stores/entity_memory.py +3275 -0
- agno/learn/stores/learned_knowledge.py +1583 -0
- agno/learn/stores/protocol.py +117 -0
- agno/learn/stores/session_context.py +1217 -0
- agno/learn/stores/user_memory.py +1495 -0
- agno/learn/stores/user_profile.py +1220 -0
- agno/learn/utils.py +209 -0
- agno/media.py +22 -6
- agno/memory/__init__.py +14 -1
- agno/memory/manager.py +223 -8
- agno/memory/strategies/__init__.py +15 -0
- agno/memory/strategies/base.py +66 -0
- agno/memory/strategies/summarize.py +196 -0
- agno/memory/strategies/types.py +37 -0
- agno/models/aimlapi/aimlapi.py +17 -0
- agno/models/anthropic/claude.py +434 -59
- agno/models/aws/bedrock.py +121 -20
- agno/models/aws/claude.py +131 -274
- agno/models/azure/ai_foundry.py +10 -6
- agno/models/azure/openai_chat.py +33 -10
- agno/models/base.py +1162 -561
- agno/models/cerebras/cerebras.py +120 -24
- agno/models/cerebras/cerebras_openai.py +21 -2
- agno/models/cohere/chat.py +65 -6
- agno/models/cometapi/cometapi.py +18 -1
- agno/models/dashscope/dashscope.py +2 -3
- agno/models/deepinfra/deepinfra.py +18 -1
- agno/models/deepseek/deepseek.py +69 -3
- agno/models/fireworks/fireworks.py +18 -1
- agno/models/google/gemini.py +959 -89
- agno/models/google/utils.py +22 -0
- agno/models/groq/groq.py +48 -18
- agno/models/huggingface/huggingface.py +17 -6
- agno/models/ibm/watsonx.py +16 -6
- agno/models/internlm/internlm.py +18 -1
- agno/models/langdb/langdb.py +13 -1
- agno/models/litellm/chat.py +88 -9
- agno/models/litellm/litellm_openai.py +18 -1
- agno/models/message.py +24 -5
- agno/models/meta/llama.py +40 -13
- agno/models/meta/llama_openai.py +22 -21
- agno/models/metrics.py +12 -0
- agno/models/mistral/mistral.py +8 -4
- agno/models/n1n/__init__.py +3 -0
- agno/models/n1n/n1n.py +57 -0
- agno/models/nebius/nebius.py +6 -7
- agno/models/nvidia/nvidia.py +20 -3
- agno/models/ollama/__init__.py +2 -0
- agno/models/ollama/chat.py +17 -6
- agno/models/ollama/responses.py +100 -0
- agno/models/openai/__init__.py +2 -0
- agno/models/openai/chat.py +117 -26
- agno/models/openai/open_responses.py +46 -0
- agno/models/openai/responses.py +110 -32
- agno/models/openrouter/__init__.py +2 -0
- agno/models/openrouter/openrouter.py +67 -2
- agno/models/openrouter/responses.py +146 -0
- agno/models/perplexity/perplexity.py +19 -1
- agno/models/portkey/portkey.py +7 -6
- agno/models/requesty/requesty.py +19 -2
- agno/models/response.py +20 -2
- agno/models/sambanova/sambanova.py +20 -3
- agno/models/siliconflow/siliconflow.py +19 -2
- agno/models/together/together.py +20 -3
- agno/models/vercel/v0.py +20 -3
- agno/models/vertexai/claude.py +124 -4
- agno/models/vllm/vllm.py +19 -14
- agno/models/xai/xai.py +19 -2
- agno/os/app.py +467 -137
- agno/os/auth.py +253 -5
- agno/os/config.py +22 -0
- agno/os/interfaces/a2a/a2a.py +7 -6
- agno/os/interfaces/a2a/router.py +635 -26
- agno/os/interfaces/a2a/utils.py +32 -33
- agno/os/interfaces/agui/agui.py +5 -3
- agno/os/interfaces/agui/router.py +26 -16
- agno/os/interfaces/agui/utils.py +97 -57
- agno/os/interfaces/base.py +7 -7
- agno/os/interfaces/slack/router.py +16 -7
- agno/os/interfaces/slack/slack.py +7 -7
- agno/os/interfaces/whatsapp/router.py +35 -7
- agno/os/interfaces/whatsapp/security.py +3 -1
- agno/os/interfaces/whatsapp/whatsapp.py +11 -8
- agno/os/managers.py +326 -0
- agno/os/mcp.py +652 -79
- agno/os/middleware/__init__.py +4 -0
- agno/os/middleware/jwt.py +718 -115
- agno/os/middleware/trailing_slash.py +27 -0
- agno/os/router.py +105 -1558
- agno/os/routers/agents/__init__.py +3 -0
- agno/os/routers/agents/router.py +655 -0
- agno/os/routers/agents/schema.py +288 -0
- agno/os/routers/components/__init__.py +3 -0
- agno/os/routers/components/components.py +475 -0
- agno/os/routers/database.py +155 -0
- agno/os/routers/evals/evals.py +111 -18
- agno/os/routers/evals/schemas.py +38 -5
- agno/os/routers/evals/utils.py +80 -11
- agno/os/routers/health.py +3 -3
- agno/os/routers/knowledge/knowledge.py +284 -35
- agno/os/routers/knowledge/schemas.py +14 -2
- agno/os/routers/memory/memory.py +274 -11
- agno/os/routers/memory/schemas.py +44 -3
- agno/os/routers/metrics/metrics.py +30 -15
- agno/os/routers/metrics/schemas.py +10 -6
- agno/os/routers/registry/__init__.py +3 -0
- agno/os/routers/registry/registry.py +337 -0
- agno/os/routers/session/session.py +143 -14
- agno/os/routers/teams/__init__.py +3 -0
- agno/os/routers/teams/router.py +550 -0
- agno/os/routers/teams/schema.py +280 -0
- agno/os/routers/traces/__init__.py +3 -0
- agno/os/routers/traces/schemas.py +414 -0
- agno/os/routers/traces/traces.py +549 -0
- agno/os/routers/workflows/__init__.py +3 -0
- agno/os/routers/workflows/router.py +757 -0
- agno/os/routers/workflows/schema.py +139 -0
- agno/os/schema.py +157 -584
- agno/os/scopes.py +469 -0
- agno/os/settings.py +3 -0
- agno/os/utils.py +574 -185
- agno/reasoning/anthropic.py +85 -1
- agno/reasoning/azure_ai_foundry.py +93 -1
- agno/reasoning/deepseek.py +102 -2
- agno/reasoning/default.py +6 -7
- agno/reasoning/gemini.py +87 -3
- agno/reasoning/groq.py +109 -2
- agno/reasoning/helpers.py +6 -7
- agno/reasoning/manager.py +1238 -0
- agno/reasoning/ollama.py +93 -1
- agno/reasoning/openai.py +115 -1
- agno/reasoning/vertexai.py +85 -1
- agno/registry/__init__.py +3 -0
- agno/registry/registry.py +68 -0
- agno/remote/__init__.py +3 -0
- agno/remote/base.py +581 -0
- agno/run/__init__.py +2 -4
- agno/run/agent.py +134 -19
- agno/run/base.py +49 -1
- agno/run/cancel.py +65 -52
- agno/run/cancellation_management/__init__.py +9 -0
- agno/run/cancellation_management/base.py +78 -0
- agno/run/cancellation_management/in_memory_cancellation_manager.py +100 -0
- agno/run/cancellation_management/redis_cancellation_manager.py +236 -0
- agno/run/requirement.py +181 -0
- agno/run/team.py +111 -19
- agno/run/workflow.py +2 -1
- agno/session/agent.py +57 -92
- agno/session/summary.py +1 -1
- agno/session/team.py +62 -115
- agno/session/workflow.py +353 -57
- agno/skills/__init__.py +17 -0
- agno/skills/agent_skills.py +377 -0
- agno/skills/errors.py +32 -0
- agno/skills/loaders/__init__.py +4 -0
- agno/skills/loaders/base.py +27 -0
- agno/skills/loaders/local.py +216 -0
- agno/skills/skill.py +65 -0
- agno/skills/utils.py +107 -0
- agno/skills/validator.py +277 -0
- agno/table.py +10 -0
- agno/team/__init__.py +5 -1
- agno/team/remote.py +447 -0
- agno/team/team.py +3769 -2202
- agno/tools/brandfetch.py +27 -18
- agno/tools/browserbase.py +225 -16
- agno/tools/crawl4ai.py +3 -0
- agno/tools/duckduckgo.py +25 -71
- agno/tools/exa.py +0 -21
- agno/tools/file.py +14 -13
- agno/tools/file_generation.py +12 -6
- agno/tools/firecrawl.py +15 -7
- agno/tools/function.py +94 -113
- agno/tools/google_bigquery.py +11 -2
- agno/tools/google_drive.py +4 -3
- agno/tools/knowledge.py +9 -4
- agno/tools/mcp/mcp.py +301 -18
- agno/tools/mcp/multi_mcp.py +269 -14
- agno/tools/mem0.py +11 -10
- agno/tools/memory.py +47 -46
- agno/tools/mlx_transcribe.py +10 -7
- agno/tools/models/nebius.py +5 -5
- agno/tools/models_labs.py +20 -10
- agno/tools/nano_banana.py +151 -0
- agno/tools/parallel.py +0 -7
- agno/tools/postgres.py +76 -36
- agno/tools/python.py +14 -6
- agno/tools/reasoning.py +30 -23
- agno/tools/redshift.py +406 -0
- agno/tools/shopify.py +1519 -0
- agno/tools/spotify.py +919 -0
- agno/tools/tavily.py +4 -1
- agno/tools/toolkit.py +253 -18
- agno/tools/websearch.py +93 -0
- agno/tools/website.py +1 -1
- agno/tools/wikipedia.py +1 -1
- agno/tools/workflow.py +56 -48
- agno/tools/yfinance.py +12 -11
- agno/tracing/__init__.py +12 -0
- agno/tracing/exporter.py +161 -0
- agno/tracing/schemas.py +276 -0
- agno/tracing/setup.py +112 -0
- agno/utils/agent.py +251 -10
- agno/utils/cryptography.py +22 -0
- agno/utils/dttm.py +33 -0
- agno/utils/events.py +264 -7
- agno/utils/hooks.py +111 -3
- agno/utils/http.py +161 -2
- agno/utils/mcp.py +49 -8
- agno/utils/media.py +22 -1
- agno/utils/models/ai_foundry.py +9 -2
- agno/utils/models/claude.py +20 -5
- agno/utils/models/cohere.py +9 -2
- agno/utils/models/llama.py +9 -2
- agno/utils/models/mistral.py +4 -2
- agno/utils/os.py +0 -0
- agno/utils/print_response/agent.py +99 -16
- agno/utils/print_response/team.py +223 -24
- agno/utils/print_response/workflow.py +0 -2
- agno/utils/prompts.py +8 -6
- agno/utils/remote.py +23 -0
- agno/utils/response.py +1 -13
- agno/utils/string.py +91 -2
- agno/utils/team.py +62 -12
- agno/utils/tokens.py +657 -0
- agno/vectordb/base.py +15 -2
- agno/vectordb/cassandra/cassandra.py +1 -1
- agno/vectordb/chroma/__init__.py +2 -1
- agno/vectordb/chroma/chromadb.py +468 -23
- agno/vectordb/clickhouse/clickhousedb.py +1 -1
- agno/vectordb/couchbase/couchbase.py +6 -2
- agno/vectordb/lancedb/lance_db.py +7 -38
- agno/vectordb/lightrag/lightrag.py +7 -6
- agno/vectordb/milvus/milvus.py +118 -84
- agno/vectordb/mongodb/__init__.py +2 -1
- agno/vectordb/mongodb/mongodb.py +14 -31
- agno/vectordb/pgvector/pgvector.py +120 -66
- agno/vectordb/pineconedb/pineconedb.py +2 -19
- agno/vectordb/qdrant/__init__.py +2 -1
- agno/vectordb/qdrant/qdrant.py +33 -56
- agno/vectordb/redis/__init__.py +2 -1
- agno/vectordb/redis/redisdb.py +19 -31
- agno/vectordb/singlestore/singlestore.py +17 -9
- agno/vectordb/surrealdb/surrealdb.py +2 -38
- agno/vectordb/weaviate/__init__.py +2 -1
- agno/vectordb/weaviate/weaviate.py +7 -3
- agno/workflow/__init__.py +5 -1
- agno/workflow/agent.py +2 -2
- agno/workflow/condition.py +12 -10
- agno/workflow/loop.py +28 -9
- agno/workflow/parallel.py +21 -13
- agno/workflow/remote.py +362 -0
- agno/workflow/router.py +12 -9
- agno/workflow/step.py +261 -36
- agno/workflow/steps.py +12 -8
- agno/workflow/types.py +40 -77
- agno/workflow/workflow.py +939 -213
- {agno-2.2.13.dist-info → agno-2.4.3.dist-info}/METADATA +134 -181
- agno-2.4.3.dist-info/RECORD +677 -0
- {agno-2.2.13.dist-info → agno-2.4.3.dist-info}/WHEEL +1 -1
- agno/tools/googlesearch.py +0 -98
- agno/tools/memori.py +0 -339
- agno-2.2.13.dist-info/RECORD +0 -575
- {agno-2.2.13.dist-info → agno-2.4.3.dist-info}/licenses/LICENSE +0 -0
- {agno-2.2.13.dist-info → agno-2.4.3.dist-info}/top_level.txt +0 -0
agno/workflow/step.py
CHANGED
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
import inspect
|
|
2
2
|
from copy import copy
|
|
3
3
|
from dataclasses import dataclass
|
|
4
|
-
from typing import Any, AsyncIterator, Awaitable, Callable, Dict, Iterator, List, Optional, Union
|
|
4
|
+
from typing import Any, AsyncIterator, Awaitable, Callable, Dict, Iterator, List, Optional, Union, cast
|
|
5
5
|
from uuid import uuid4
|
|
6
6
|
|
|
7
7
|
from pydantic import BaseModel
|
|
8
8
|
from typing_extensions import TypeGuard
|
|
9
9
|
|
|
10
10
|
from agno.agent import Agent
|
|
11
|
+
from agno.db.base import BaseDb
|
|
11
12
|
from agno.media import Audio, Image, Video
|
|
13
|
+
from agno.models.message import Message
|
|
12
14
|
from agno.models.metrics import Metrics
|
|
15
|
+
from agno.registry import Registry
|
|
13
16
|
from agno.run import RunContext
|
|
14
17
|
from agno.run.agent import RunContentEvent, RunOutput
|
|
15
18
|
from agno.run.base import BaseRunOutputEvent
|
|
@@ -21,9 +24,11 @@ from agno.run.workflow import (
|
|
|
21
24
|
WorkflowRunOutput,
|
|
22
25
|
WorkflowRunOutputEvent,
|
|
23
26
|
)
|
|
27
|
+
from agno.session.agent import AgentSession
|
|
28
|
+
from agno.session.team import TeamSession
|
|
24
29
|
from agno.session.workflow import WorkflowSession
|
|
25
30
|
from agno.team import Team
|
|
26
|
-
from agno.utils.log import log_debug, logger, use_agent_logger, use_team_logger, use_workflow_logger
|
|
31
|
+
from agno.utils.log import log_debug, log_warning, logger, use_agent_logger, use_team_logger, use_workflow_logger
|
|
27
32
|
from agno.utils.merge_dict import merge_dictionaries
|
|
28
33
|
from agno.workflow.types import StepInput, StepOutput, StepType
|
|
29
34
|
|
|
@@ -57,7 +62,6 @@ class Step:
|
|
|
57
62
|
|
|
58
63
|
# Step configuration
|
|
59
64
|
max_retries: int = 3
|
|
60
|
-
timeout_seconds: Optional[int] = None
|
|
61
65
|
|
|
62
66
|
skip_on_failure: bool = False
|
|
63
67
|
|
|
@@ -79,7 +83,6 @@ class Step:
|
|
|
79
83
|
step_id: Optional[str] = None,
|
|
80
84
|
description: Optional[str] = None,
|
|
81
85
|
max_retries: int = 3,
|
|
82
|
-
timeout_seconds: Optional[int] = None,
|
|
83
86
|
skip_on_failure: bool = False,
|
|
84
87
|
strict_input_validation: bool = False,
|
|
85
88
|
add_workflow_history: Optional[bool] = None,
|
|
@@ -100,7 +103,6 @@ class Step:
|
|
|
100
103
|
self.step_id = step_id
|
|
101
104
|
self.description = description
|
|
102
105
|
self.max_retries = max_retries
|
|
103
|
-
self.timeout_seconds = timeout_seconds
|
|
104
106
|
self.skip_on_failure = skip_on_failure
|
|
105
107
|
self.strict_input_validation = strict_input_validation
|
|
106
108
|
self.add_workflow_history = add_workflow_history
|
|
@@ -113,6 +115,121 @@ class Step:
|
|
|
113
115
|
# Set the active executor
|
|
114
116
|
self._set_active_executor()
|
|
115
117
|
|
|
118
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
119
|
+
"""Convert step to a dictionary representation."""
|
|
120
|
+
result = {
|
|
121
|
+
"name": self.name,
|
|
122
|
+
"step_id": self.step_id,
|
|
123
|
+
"description": self.description,
|
|
124
|
+
"max_retries": self.max_retries,
|
|
125
|
+
"skip_on_failure": self.skip_on_failure,
|
|
126
|
+
"strict_input_validation": self.strict_input_validation,
|
|
127
|
+
"add_workflow_history": self.add_workflow_history,
|
|
128
|
+
"num_history_runs": self.num_history_runs,
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if self.agent is not None:
|
|
132
|
+
result["agent_id"] = self.agent.id
|
|
133
|
+
if self.team is not None:
|
|
134
|
+
result["team_id"] = self.team.id
|
|
135
|
+
# TODO: Add support for custom executors
|
|
136
|
+
|
|
137
|
+
return result
|
|
138
|
+
|
|
139
|
+
@classmethod
|
|
140
|
+
def from_dict(
|
|
141
|
+
cls,
|
|
142
|
+
data: Dict[str, Any],
|
|
143
|
+
registry: Optional[Registry] = None,
|
|
144
|
+
db: Optional["BaseDb"] = None,
|
|
145
|
+
links: Optional[List[Dict[str, Any]]] = None,
|
|
146
|
+
) -> "Step":
|
|
147
|
+
"""
|
|
148
|
+
Create a Step from a dictionary.
|
|
149
|
+
|
|
150
|
+
Args:
|
|
151
|
+
data: Dictionary containing step configuration
|
|
152
|
+
registry: Optional registry for rehydrating non-serializable objects
|
|
153
|
+
db: Optional database for loading agents/teams in steps
|
|
154
|
+
links: Optional links for this step version
|
|
155
|
+
|
|
156
|
+
Returns:
|
|
157
|
+
Step: Reconstructed step instance
|
|
158
|
+
"""
|
|
159
|
+
config = data.copy()
|
|
160
|
+
|
|
161
|
+
agent = None
|
|
162
|
+
team = None
|
|
163
|
+
executor = None
|
|
164
|
+
|
|
165
|
+
# --- Handle Agent reconstruction ---
|
|
166
|
+
if "agent_id" in config and config["agent_id"]:
|
|
167
|
+
from agno.agent.agent import get_agent_by_id
|
|
168
|
+
|
|
169
|
+
agent_id = config.get("agent_id")
|
|
170
|
+
if db is not None and agent_id is not None:
|
|
171
|
+
agent = get_agent_by_id(db=db, id=agent_id, registry=registry)
|
|
172
|
+
|
|
173
|
+
# --- Handle Team reconstruction ---
|
|
174
|
+
# if "team_id" in config and config["team_id"] and registry:
|
|
175
|
+
# from agno.team.team import get_team_by_id
|
|
176
|
+
# team = get_team_by_id(db=db, id=config["team_id"])
|
|
177
|
+
|
|
178
|
+
# --- Handle Executor reconstruction ---
|
|
179
|
+
# TODO: Implement executor reconstruction
|
|
180
|
+
# if "executor_ref" in config and config["executor_ref"] and registry:
|
|
181
|
+
# executor = registry.rehydrate_function(config["executor_ref"])
|
|
182
|
+
|
|
183
|
+
return cls(
|
|
184
|
+
name=config.get("name"),
|
|
185
|
+
step_id=config.get("step_id"),
|
|
186
|
+
description=config.get("description"),
|
|
187
|
+
max_retries=config.get("max_retries", 3),
|
|
188
|
+
skip_on_failure=config.get("skip_on_failure", False),
|
|
189
|
+
strict_input_validation=config.get("strict_input_validation", False),
|
|
190
|
+
add_workflow_history=config.get("add_workflow_history"),
|
|
191
|
+
num_history_runs=config.get("num_history_runs", 3),
|
|
192
|
+
agent=agent,
|
|
193
|
+
team=team,
|
|
194
|
+
executor=executor,
|
|
195
|
+
)
|
|
196
|
+
|
|
197
|
+
def get_links(self, position: int = 0) -> List[Dict[str, Any]]:
|
|
198
|
+
"""Get links for this step's agent/team.
|
|
199
|
+
|
|
200
|
+
Args:
|
|
201
|
+
position: Position of this step in the workflow.
|
|
202
|
+
|
|
203
|
+
Returns:
|
|
204
|
+
List of link dictionaries for the links table.
|
|
205
|
+
"""
|
|
206
|
+
links = []
|
|
207
|
+
link_key = self.step_id or self.name
|
|
208
|
+
|
|
209
|
+
if self.agent is not None:
|
|
210
|
+
links.append(
|
|
211
|
+
{
|
|
212
|
+
"link_kind": "step_agent",
|
|
213
|
+
"link_key": link_key,
|
|
214
|
+
"child_component_id": self.agent.id,
|
|
215
|
+
"child_version": None,
|
|
216
|
+
"position": position,
|
|
217
|
+
}
|
|
218
|
+
)
|
|
219
|
+
|
|
220
|
+
if self.team is not None:
|
|
221
|
+
links.append(
|
|
222
|
+
{
|
|
223
|
+
"link_kind": "step_team",
|
|
224
|
+
"link_key": link_key,
|
|
225
|
+
"child_component_id": self.team.id,
|
|
226
|
+
"child_version": None,
|
|
227
|
+
"position": position,
|
|
228
|
+
}
|
|
229
|
+
)
|
|
230
|
+
|
|
231
|
+
return links
|
|
232
|
+
|
|
116
233
|
@property
|
|
117
234
|
def executor_name(self) -> str:
|
|
118
235
|
"""Get the name of the current executor"""
|
|
@@ -225,6 +342,7 @@ class Step:
|
|
|
225
342
|
workflow_session: Optional[WorkflowSession] = None,
|
|
226
343
|
add_workflow_history_to_steps: Optional[bool] = False,
|
|
227
344
|
num_history_runs: int = 3,
|
|
345
|
+
background_tasks: Optional[Any] = None,
|
|
228
346
|
) -> StepOutput:
|
|
229
347
|
"""Execute the step with StepInput, returning final StepOutput (non-streaming)"""
|
|
230
348
|
log_debug(f"Executing step: {self.name}")
|
|
@@ -272,17 +390,18 @@ class Step:
|
|
|
272
390
|
elif isinstance(chunk.content, BaseModel):
|
|
273
391
|
content = chunk.content # type: ignore[assignment]
|
|
274
392
|
else:
|
|
275
|
-
#
|
|
393
|
+
# Case when parse_response is False and the content is a dict
|
|
276
394
|
content += str(chunk.content)
|
|
277
395
|
elif isinstance(chunk, (RunOutput, TeamRunOutput)):
|
|
278
396
|
# This is the final response from the agent/team
|
|
279
397
|
content = chunk.content # type: ignore[assignment]
|
|
280
|
-
else:
|
|
281
|
-
# Non Agent/Team data structure that was yielded
|
|
282
|
-
content += str(chunk)
|
|
283
398
|
# If the chunk is a StepOutput, use it as the final response
|
|
284
|
-
|
|
399
|
+
elif isinstance(chunk, StepOutput):
|
|
285
400
|
final_response = chunk
|
|
401
|
+
break
|
|
402
|
+
# Non Agent/Team data structure that was yielded
|
|
403
|
+
else:
|
|
404
|
+
content += str(chunk)
|
|
286
405
|
|
|
287
406
|
except StopIteration as e:
|
|
288
407
|
if hasattr(e, "value") and isinstance(e.value, StepOutput):
|
|
@@ -343,6 +462,10 @@ class Step:
|
|
|
343
462
|
if isinstance(self.active_executor, Team):
|
|
344
463
|
kwargs["store_member_responses"] = True
|
|
345
464
|
|
|
465
|
+
# Forward background_tasks if provided
|
|
466
|
+
if background_tasks is not None:
|
|
467
|
+
kwargs["background_tasks"] = background_tasks
|
|
468
|
+
|
|
346
469
|
num_history_runs = self.num_history_runs if self.num_history_runs else num_history_runs
|
|
347
470
|
|
|
348
471
|
use_history = (
|
|
@@ -454,7 +577,6 @@ class Step:
|
|
|
454
577
|
session_id: Optional[str] = None,
|
|
455
578
|
user_id: Optional[str] = None,
|
|
456
579
|
stream_events: bool = False,
|
|
457
|
-
stream_intermediate_steps: bool = False,
|
|
458
580
|
stream_executor_events: bool = True,
|
|
459
581
|
workflow_run_response: Optional["WorkflowRunOutput"] = None,
|
|
460
582
|
run_context: Optional[RunContext] = None,
|
|
@@ -465,6 +587,7 @@ class Step:
|
|
|
465
587
|
workflow_session: Optional["WorkflowSession"] = None,
|
|
466
588
|
add_workflow_history_to_steps: Optional[bool] = False,
|
|
467
589
|
num_history_runs: int = 3,
|
|
590
|
+
background_tasks: Optional[Any] = None,
|
|
468
591
|
) -> Iterator[Union[WorkflowRunOutputEvent, StepOutput]]:
|
|
469
592
|
"""Execute the step with event-driven streaming support"""
|
|
470
593
|
|
|
@@ -481,9 +604,6 @@ class Step:
|
|
|
481
604
|
else:
|
|
482
605
|
session_state_copy = copy(session_state) if session_state is not None else {}
|
|
483
606
|
|
|
484
|
-
# Considering both stream_events and stream_intermediate_steps (deprecated)
|
|
485
|
-
stream_events = stream_events or stream_intermediate_steps
|
|
486
|
-
|
|
487
607
|
# Emit StepStartedEvent
|
|
488
608
|
if stream_events and workflow_run_response:
|
|
489
609
|
yield StepStartedEvent(
|
|
@@ -537,11 +657,11 @@ class Step:
|
|
|
537
657
|
yield enriched_event # type: ignore[misc]
|
|
538
658
|
elif isinstance(event, (RunOutput, TeamRunOutput)):
|
|
539
659
|
content = event.content # type: ignore[assignment]
|
|
540
|
-
|
|
541
|
-
content += str(event)
|
|
542
|
-
if isinstance(event, StepOutput):
|
|
660
|
+
elif isinstance(event, StepOutput):
|
|
543
661
|
final_response = event
|
|
544
662
|
break
|
|
663
|
+
else:
|
|
664
|
+
content += str(event)
|
|
545
665
|
|
|
546
666
|
# Merge session_state changes back
|
|
547
667
|
if run_context is None and session_state is not None:
|
|
@@ -598,6 +718,10 @@ class Step:
|
|
|
598
718
|
if isinstance(self.active_executor, Team):
|
|
599
719
|
kwargs["store_member_responses"] = True
|
|
600
720
|
|
|
721
|
+
# Forward background_tasks if provided
|
|
722
|
+
if background_tasks is not None:
|
|
723
|
+
kwargs["background_tasks"] = background_tasks
|
|
724
|
+
|
|
601
725
|
num_history_runs = self.num_history_runs if self.num_history_runs else num_history_runs
|
|
602
726
|
|
|
603
727
|
use_history = (
|
|
@@ -623,7 +747,7 @@ class Step:
|
|
|
623
747
|
session_state=session_state_copy, # Send a copy to the executor
|
|
624
748
|
stream=True,
|
|
625
749
|
stream_events=stream_events,
|
|
626
|
-
|
|
750
|
+
yield_run_output=True,
|
|
627
751
|
run_context=run_context,
|
|
628
752
|
**kwargs,
|
|
629
753
|
)
|
|
@@ -632,7 +756,7 @@ class Step:
|
|
|
632
756
|
for event in response_stream:
|
|
633
757
|
if isinstance(event, RunOutput) or isinstance(event, TeamRunOutput):
|
|
634
758
|
active_executor_run_response = event
|
|
635
|
-
|
|
759
|
+
continue
|
|
636
760
|
# Only yield executor events if stream_executor_events is True
|
|
637
761
|
if stream_executor_events:
|
|
638
762
|
enriched_event = self._enrich_event_with_context(
|
|
@@ -709,6 +833,7 @@ class Step:
|
|
|
709
833
|
workflow_session: Optional["WorkflowSession"] = None,
|
|
710
834
|
add_workflow_history_to_steps: Optional[bool] = False,
|
|
711
835
|
num_history_runs: int = 3,
|
|
836
|
+
background_tasks: Optional[Any] = None,
|
|
712
837
|
) -> StepOutput:
|
|
713
838
|
"""Execute the step with StepInput, returning final StepOutput (non-streaming)"""
|
|
714
839
|
logger.info(f"Executing async step (non-streaming): {self.name}")
|
|
@@ -758,10 +883,12 @@ class Step:
|
|
|
758
883
|
content = str(chunk.content)
|
|
759
884
|
elif isinstance(chunk, (RunOutput, TeamRunOutput)):
|
|
760
885
|
content = chunk.content # type: ignore[assignment]
|
|
886
|
+
elif isinstance(chunk, StepOutput):
|
|
887
|
+
final_response = chunk
|
|
888
|
+
break
|
|
761
889
|
else:
|
|
762
890
|
content += str(chunk)
|
|
763
|
-
|
|
764
|
-
final_response = chunk
|
|
891
|
+
|
|
765
892
|
else:
|
|
766
893
|
if _is_async_generator_function(self.active_executor):
|
|
767
894
|
iterator = await self._acall_custom_function(
|
|
@@ -784,10 +911,11 @@ class Step:
|
|
|
784
911
|
content = str(chunk.content)
|
|
785
912
|
elif isinstance(chunk, (RunOutput, TeamRunOutput)):
|
|
786
913
|
content = chunk.content # type: ignore[assignment]
|
|
914
|
+
elif isinstance(chunk, StepOutput):
|
|
915
|
+
final_response = chunk
|
|
916
|
+
break
|
|
787
917
|
else:
|
|
788
918
|
content += str(chunk)
|
|
789
|
-
if isinstance(chunk, StepOutput):
|
|
790
|
-
final_response = chunk
|
|
791
919
|
|
|
792
920
|
except StopIteration as e:
|
|
793
921
|
if hasattr(e, "value") and isinstance(e.value, StepOutput):
|
|
@@ -856,6 +984,10 @@ class Step:
|
|
|
856
984
|
if isinstance(self.active_executor, Team):
|
|
857
985
|
kwargs["store_member_responses"] = True
|
|
858
986
|
|
|
987
|
+
# Forward background_tasks if provided
|
|
988
|
+
if background_tasks is not None:
|
|
989
|
+
kwargs["background_tasks"] = background_tasks
|
|
990
|
+
|
|
859
991
|
num_history_runs = self.num_history_runs if self.num_history_runs else num_history_runs
|
|
860
992
|
|
|
861
993
|
use_history = (
|
|
@@ -920,7 +1052,6 @@ class Step:
|
|
|
920
1052
|
session_id: Optional[str] = None,
|
|
921
1053
|
user_id: Optional[str] = None,
|
|
922
1054
|
stream_events: bool = False,
|
|
923
|
-
stream_intermediate_steps: bool = False,
|
|
924
1055
|
stream_executor_events: bool = True,
|
|
925
1056
|
workflow_run_response: Optional["WorkflowRunOutput"] = None,
|
|
926
1057
|
run_context: Optional[RunContext] = None,
|
|
@@ -931,6 +1062,7 @@ class Step:
|
|
|
931
1062
|
workflow_session: Optional["WorkflowSession"] = None,
|
|
932
1063
|
add_workflow_history_to_steps: Optional[bool] = False,
|
|
933
1064
|
num_history_runs: int = 3,
|
|
1065
|
+
background_tasks: Optional[Any] = None,
|
|
934
1066
|
) -> AsyncIterator[Union[WorkflowRunOutputEvent, StepOutput]]:
|
|
935
1067
|
"""Execute the step with event-driven streaming support"""
|
|
936
1068
|
|
|
@@ -947,9 +1079,6 @@ class Step:
|
|
|
947
1079
|
else:
|
|
948
1080
|
session_state_copy = copy(session_state) if session_state is not None else {}
|
|
949
1081
|
|
|
950
|
-
# Considering both stream_events and stream_intermediate_steps (deprecated)
|
|
951
|
-
stream_events = stream_events or stream_intermediate_steps
|
|
952
|
-
|
|
953
1082
|
if stream_events and workflow_run_response:
|
|
954
1083
|
# Emit StepStartedEvent
|
|
955
1084
|
yield StepStartedEvent(
|
|
@@ -1003,11 +1132,11 @@ class Step:
|
|
|
1003
1132
|
yield enriched_event # type: ignore[misc]
|
|
1004
1133
|
elif isinstance(event, (RunOutput, TeamRunOutput)):
|
|
1005
1134
|
content = event.content # type: ignore[assignment]
|
|
1006
|
-
|
|
1007
|
-
content += str(event)
|
|
1008
|
-
if isinstance(event, StepOutput):
|
|
1135
|
+
elif isinstance(event, StepOutput):
|
|
1009
1136
|
final_response = event
|
|
1010
1137
|
break
|
|
1138
|
+
else:
|
|
1139
|
+
content += str(event)
|
|
1011
1140
|
if not final_response:
|
|
1012
1141
|
final_response = StepOutput(content=content)
|
|
1013
1142
|
elif _is_async_callable(self.active_executor):
|
|
@@ -1054,11 +1183,14 @@ class Step:
|
|
|
1054
1183
|
yield enriched_event # type: ignore[misc]
|
|
1055
1184
|
elif isinstance(event, (RunOutput, TeamRunOutput)):
|
|
1056
1185
|
content = event.content # type: ignore[assignment]
|
|
1057
|
-
|
|
1058
|
-
content += str(event)
|
|
1059
|
-
if isinstance(event, StepOutput):
|
|
1186
|
+
elif isinstance(event, StepOutput):
|
|
1060
1187
|
final_response = event
|
|
1061
1188
|
break
|
|
1189
|
+
else:
|
|
1190
|
+
if isinstance(content, str):
|
|
1191
|
+
content += str(event)
|
|
1192
|
+
else:
|
|
1193
|
+
content = str(event)
|
|
1062
1194
|
if not final_response:
|
|
1063
1195
|
final_response = StepOutput(content=content)
|
|
1064
1196
|
else:
|
|
@@ -1105,6 +1237,10 @@ class Step:
|
|
|
1105
1237
|
if isinstance(self.active_executor, Team):
|
|
1106
1238
|
kwargs["store_member_responses"] = True
|
|
1107
1239
|
|
|
1240
|
+
# Forward background_tasks if provided
|
|
1241
|
+
if background_tasks is not None:
|
|
1242
|
+
kwargs["background_tasks"] = background_tasks
|
|
1243
|
+
|
|
1108
1244
|
num_history_runs = self.num_history_runs if self.num_history_runs else num_history_runs
|
|
1109
1245
|
|
|
1110
1246
|
use_history = (
|
|
@@ -1131,7 +1267,7 @@ class Step:
|
|
|
1131
1267
|
stream=True,
|
|
1132
1268
|
stream_events=stream_events,
|
|
1133
1269
|
run_context=run_context,
|
|
1134
|
-
|
|
1270
|
+
yield_run_output=True,
|
|
1135
1271
|
**kwargs,
|
|
1136
1272
|
)
|
|
1137
1273
|
|
|
@@ -1202,6 +1338,83 @@ class Step:
|
|
|
1202
1338
|
|
|
1203
1339
|
return
|
|
1204
1340
|
|
|
1341
|
+
def get_chat_history(self, session_id: str, last_n_runs: Optional[int] = None) -> List[Message]:
|
|
1342
|
+
"""Return the step's Agent or Team chat history for the given session.
|
|
1343
|
+
|
|
1344
|
+
Args:
|
|
1345
|
+
session_id: The session ID to get the chat history for. If not provided, the current cached session ID is used.
|
|
1346
|
+
last_n_runs: Number of recent runs to include. If None, all runs will be considered.
|
|
1347
|
+
|
|
1348
|
+
Returns:
|
|
1349
|
+
List[Message]: The step's Agent or Team chat history for the given session.
|
|
1350
|
+
"""
|
|
1351
|
+
session: Union[AgentSession, TeamSession, WorkflowSession, None] = None
|
|
1352
|
+
|
|
1353
|
+
if self.agent:
|
|
1354
|
+
session = self.agent.get_session(session_id=session_id)
|
|
1355
|
+
if not session:
|
|
1356
|
+
log_warning("Session not found")
|
|
1357
|
+
return []
|
|
1358
|
+
|
|
1359
|
+
if not isinstance(session, WorkflowSession):
|
|
1360
|
+
raise ValueError("The provided session is not a WorkflowSession")
|
|
1361
|
+
|
|
1362
|
+
session = cast(WorkflowSession, session)
|
|
1363
|
+
return session.get_messages(last_n_runs=last_n_runs, agent_id=self.agent.id)
|
|
1364
|
+
|
|
1365
|
+
elif self.team:
|
|
1366
|
+
session = self.team.get_session(session_id=session_id)
|
|
1367
|
+
if not session:
|
|
1368
|
+
log_warning("Session not found")
|
|
1369
|
+
return []
|
|
1370
|
+
|
|
1371
|
+
if not isinstance(session, WorkflowSession):
|
|
1372
|
+
raise ValueError("The provided session is not a WorkflowSession")
|
|
1373
|
+
|
|
1374
|
+
session = cast(WorkflowSession, session)
|
|
1375
|
+
return session.get_messages(last_n_runs=last_n_runs, team_id=self.team.id)
|
|
1376
|
+
|
|
1377
|
+
return []
|
|
1378
|
+
|
|
1379
|
+
async def aget_chat_history(
|
|
1380
|
+
self, session_id: Optional[str] = None, last_n_runs: Optional[int] = None
|
|
1381
|
+
) -> List[Message]:
|
|
1382
|
+
"""Return the step's Agent or Team chat history for the given session.
|
|
1383
|
+
|
|
1384
|
+
Args:
|
|
1385
|
+
session_id: The session ID to get the chat history for. If not provided, the current cached session ID is used.
|
|
1386
|
+
last_n_runs: Number of recent runs to include. If None, all runs will be considered.
|
|
1387
|
+
|
|
1388
|
+
Returns:
|
|
1389
|
+
List[Message]: The step's Agent or Team chat history for the given session.
|
|
1390
|
+
"""
|
|
1391
|
+
session: Union[AgentSession, TeamSession, WorkflowSession, None] = None
|
|
1392
|
+
|
|
1393
|
+
if self.agent:
|
|
1394
|
+
session = await self.agent.aget_session(session_id=session_id)
|
|
1395
|
+
if not session:
|
|
1396
|
+
log_warning("Session not found")
|
|
1397
|
+
return []
|
|
1398
|
+
|
|
1399
|
+
if not isinstance(session, WorkflowSession):
|
|
1400
|
+
raise ValueError("The provided session is not a WorkflowSession")
|
|
1401
|
+
|
|
1402
|
+
session = cast(WorkflowSession, session)
|
|
1403
|
+
return session.get_messages(last_n_runs=last_n_runs, agent_id=self.agent.id)
|
|
1404
|
+
|
|
1405
|
+
elif self.team:
|
|
1406
|
+
session = await self.team.aget_session(session_id=session_id)
|
|
1407
|
+
if not session:
|
|
1408
|
+
log_warning("Session not found")
|
|
1409
|
+
return []
|
|
1410
|
+
|
|
1411
|
+
if not isinstance(session, WorkflowSession):
|
|
1412
|
+
raise ValueError("The provided session is not a WorkflowSession")
|
|
1413
|
+
|
|
1414
|
+
return session.get_messages(last_n_runs=last_n_runs, team_id=self.team.id)
|
|
1415
|
+
|
|
1416
|
+
return []
|
|
1417
|
+
|
|
1205
1418
|
def _store_executor_response(
|
|
1206
1419
|
self, workflow_run_response: "WorkflowRunOutput", executor_run_response: Union[RunOutput, TeamRunOutput]
|
|
1207
1420
|
) -> None:
|
|
@@ -1243,10 +1456,22 @@ class Step:
|
|
|
1243
1456
|
|
|
1244
1457
|
For container steps (Steps, Router, Loop, etc.), this will recursively find the content from the
|
|
1245
1458
|
last actual step rather than using the generic container message.
|
|
1459
|
+
|
|
1460
|
+
For Parallel steps, aggregates content from ALL inner steps (not just the last one).
|
|
1246
1461
|
"""
|
|
1247
|
-
# If this step has nested steps (like Steps, Condition, Router, Loop, etc.)
|
|
1462
|
+
# If this step has nested steps (like Steps, Condition, Router, Loop, Parallel, etc.)
|
|
1248
1463
|
if hasattr(step_output, "steps") and step_output.steps and len(step_output.steps) > 0:
|
|
1249
|
-
#
|
|
1464
|
+
# For Parallel steps, aggregate content from ALL inner steps
|
|
1465
|
+
if step_output.step_type == StepType.PARALLEL:
|
|
1466
|
+
aggregated_parts = []
|
|
1467
|
+
for i, inner_step in enumerate(step_output.steps):
|
|
1468
|
+
inner_content = self._get_deepest_content_from_step_output(inner_step)
|
|
1469
|
+
if inner_content:
|
|
1470
|
+
step_name = inner_step.step_name or f"Step {i + 1}"
|
|
1471
|
+
aggregated_parts.append(f"=== {step_name} ===\n{inner_content}")
|
|
1472
|
+
return "\n\n".join(aggregated_parts) if aggregated_parts else step_output.content # type: ignore
|
|
1473
|
+
|
|
1474
|
+
# For other nested step types, recursively get content from the last nested step
|
|
1250
1475
|
return self._get_deepest_content_from_step_output(step_output.steps[-1])
|
|
1251
1476
|
|
|
1252
1477
|
# For regular steps, return their content
|
agno/workflow/steps.py
CHANGED
|
@@ -125,6 +125,7 @@ class Steps:
|
|
|
125
125
|
workflow_session: Optional[WorkflowSession] = None,
|
|
126
126
|
add_workflow_history_to_steps: Optional[bool] = False,
|
|
127
127
|
num_history_runs: int = 3,
|
|
128
|
+
background_tasks: Optional[Any] = None,
|
|
128
129
|
) -> StepOutput:
|
|
129
130
|
"""Execute all steps in sequence and return the final result"""
|
|
130
131
|
log_debug(f"Steps Start: {self.name} ({len(self.steps)} steps)", center=True, symbol="-")
|
|
@@ -158,6 +159,7 @@ class Steps:
|
|
|
158
159
|
workflow_session=workflow_session,
|
|
159
160
|
add_workflow_history_to_steps=add_workflow_history_to_steps,
|
|
160
161
|
num_history_runs=num_history_runs,
|
|
162
|
+
background_tasks=background_tasks,
|
|
161
163
|
)
|
|
162
164
|
|
|
163
165
|
# Handle both single StepOutput and List[StepOutput] (from Loop/Condition/Router steps)
|
|
@@ -191,6 +193,7 @@ class Steps:
|
|
|
191
193
|
step_type=StepType.STEPS,
|
|
192
194
|
content=f"Steps {self.name} completed with {len(all_results)} results",
|
|
193
195
|
success=all(result.success for result in all_results) if all_results else True,
|
|
196
|
+
stop=any(result.stop for result in all_results) if all_results else False,
|
|
194
197
|
steps=all_results,
|
|
195
198
|
)
|
|
196
199
|
|
|
@@ -212,7 +215,6 @@ class Steps:
|
|
|
212
215
|
session_id: Optional[str] = None,
|
|
213
216
|
user_id: Optional[str] = None,
|
|
214
217
|
stream_events: bool = False,
|
|
215
|
-
stream_intermediate_steps: bool = False,
|
|
216
218
|
stream_executor_events: bool = True,
|
|
217
219
|
step_index: Optional[Union[int, tuple]] = None,
|
|
218
220
|
store_executor_outputs: bool = True,
|
|
@@ -220,6 +222,7 @@ class Steps:
|
|
|
220
222
|
workflow_session: Optional[WorkflowSession] = None,
|
|
221
223
|
add_workflow_history_to_steps: Optional[bool] = False,
|
|
222
224
|
num_history_runs: int = 3,
|
|
225
|
+
background_tasks: Optional[Any] = None,
|
|
223
226
|
) -> Iterator[Union[WorkflowRunOutputEvent, TeamRunOutputEvent, RunOutputEvent, StepOutput]]:
|
|
224
227
|
"""Execute all steps in sequence with streaming support"""
|
|
225
228
|
log_debug(f"Steps Start: {self.name} ({len(self.steps)} steps)", center=True, symbol="-")
|
|
@@ -228,9 +231,6 @@ class Steps:
|
|
|
228
231
|
|
|
229
232
|
self._prepare_steps()
|
|
230
233
|
|
|
231
|
-
# Considering both stream_events and stream_intermediate_steps (deprecated)
|
|
232
|
-
stream_events = stream_events or stream_intermediate_steps
|
|
233
|
-
|
|
234
234
|
if stream_events:
|
|
235
235
|
# Yield steps execution started event
|
|
236
236
|
yield StepsExecutionStartedEvent(
|
|
@@ -284,6 +284,7 @@ class Steps:
|
|
|
284
284
|
workflow_session=workflow_session,
|
|
285
285
|
add_workflow_history_to_steps=add_workflow_history_to_steps,
|
|
286
286
|
num_history_runs=num_history_runs,
|
|
287
|
+
background_tasks=background_tasks,
|
|
287
288
|
):
|
|
288
289
|
if isinstance(event, StepOutput):
|
|
289
290
|
step_outputs_for_step.append(event)
|
|
@@ -340,6 +341,7 @@ class Steps:
|
|
|
340
341
|
step_type=StepType.STEPS,
|
|
341
342
|
content=f"Steps {self.name} completed with {len(all_results)} results",
|
|
342
343
|
success=all(result.success for result in all_results) if all_results else True,
|
|
344
|
+
stop=any(result.stop for result in all_results) if all_results else False,
|
|
343
345
|
steps=all_results,
|
|
344
346
|
)
|
|
345
347
|
|
|
@@ -365,6 +367,7 @@ class Steps:
|
|
|
365
367
|
workflow_session: Optional[WorkflowSession] = None,
|
|
366
368
|
add_workflow_history_to_steps: Optional[bool] = False,
|
|
367
369
|
num_history_runs: int = 3,
|
|
370
|
+
background_tasks: Optional[Any] = None,
|
|
368
371
|
) -> StepOutput:
|
|
369
372
|
"""Execute all steps in sequence asynchronously and return the final result"""
|
|
370
373
|
log_debug(f"Steps Start: {self.name} ({len(self.steps)} steps)", center=True, symbol="-")
|
|
@@ -398,6 +401,7 @@ class Steps:
|
|
|
398
401
|
workflow_session=workflow_session,
|
|
399
402
|
add_workflow_history_to_steps=add_workflow_history_to_steps,
|
|
400
403
|
num_history_runs=num_history_runs,
|
|
404
|
+
background_tasks=background_tasks,
|
|
401
405
|
)
|
|
402
406
|
|
|
403
407
|
# Handle both single StepOutput and List[StepOutput] (from Loop/Condition/Router steps)
|
|
@@ -430,6 +434,7 @@ class Steps:
|
|
|
430
434
|
step_type=StepType.STEPS,
|
|
431
435
|
content=f"Steps {self.name} completed with {len(all_results)} results",
|
|
432
436
|
success=all(result.success for result in all_results) if all_results else True,
|
|
437
|
+
stop=any(result.stop for result in all_results) if all_results else False,
|
|
433
438
|
steps=all_results,
|
|
434
439
|
)
|
|
435
440
|
|
|
@@ -451,7 +456,6 @@ class Steps:
|
|
|
451
456
|
session_id: Optional[str] = None,
|
|
452
457
|
user_id: Optional[str] = None,
|
|
453
458
|
stream_events: bool = False,
|
|
454
|
-
stream_intermediate_steps: bool = False,
|
|
455
459
|
stream_executor_events: bool = True,
|
|
456
460
|
step_index: Optional[Union[int, tuple]] = None,
|
|
457
461
|
store_executor_outputs: bool = True,
|
|
@@ -459,6 +463,7 @@ class Steps:
|
|
|
459
463
|
workflow_session: Optional[WorkflowSession] = None,
|
|
460
464
|
add_workflow_history_to_steps: Optional[bool] = False,
|
|
461
465
|
num_history_runs: int = 3,
|
|
466
|
+
background_tasks: Optional[Any] = None,
|
|
462
467
|
) -> AsyncIterator[Union[WorkflowRunOutputEvent, TeamRunOutputEvent, RunOutputEvent, StepOutput]]:
|
|
463
468
|
"""Execute all steps in sequence with async streaming support"""
|
|
464
469
|
log_debug(f"Steps Start: {self.name} ({len(self.steps)} steps)", center=True, symbol="-")
|
|
@@ -467,9 +472,6 @@ class Steps:
|
|
|
467
472
|
|
|
468
473
|
self._prepare_steps()
|
|
469
474
|
|
|
470
|
-
# Considering both stream_events and stream_intermediate_steps (deprecated)
|
|
471
|
-
stream_events = stream_events or stream_intermediate_steps
|
|
472
|
-
|
|
473
475
|
if stream_events:
|
|
474
476
|
# Yield steps execution started event
|
|
475
477
|
yield StepsExecutionStartedEvent(
|
|
@@ -523,6 +525,7 @@ class Steps:
|
|
|
523
525
|
workflow_session=workflow_session,
|
|
524
526
|
add_workflow_history_to_steps=add_workflow_history_to_steps,
|
|
525
527
|
num_history_runs=num_history_runs,
|
|
528
|
+
background_tasks=background_tasks,
|
|
526
529
|
):
|
|
527
530
|
if isinstance(event, StepOutput):
|
|
528
531
|
step_outputs_for_step.append(event)
|
|
@@ -578,6 +581,7 @@ class Steps:
|
|
|
578
581
|
step_type=StepType.STEPS,
|
|
579
582
|
content=f"Steps {self.name} completed with {len(all_results)} results",
|
|
580
583
|
success=all(result.success for result in all_results) if all_results else True,
|
|
584
|
+
stop=any(result.stop for result in all_results) if all_results else False,
|
|
581
585
|
steps=all_results,
|
|
582
586
|
)
|
|
583
587
|
|