agno 1.8.2__py3-none-any.whl → 2.0.0__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 +19 -27
- agno/agent/agent.py +3143 -4170
- agno/api/agent.py +11 -67
- agno/api/api.py +5 -46
- agno/api/evals.py +8 -19
- agno/api/os.py +17 -0
- agno/api/routes.py +6 -41
- agno/api/schemas/__init__.py +9 -0
- agno/api/schemas/agent.py +5 -21
- agno/api/schemas/evals.py +7 -16
- agno/api/schemas/os.py +14 -0
- agno/api/schemas/team.py +5 -21
- agno/api/schemas/utils.py +21 -0
- agno/api/schemas/workflows.py +11 -7
- agno/api/settings.py +53 -0
- agno/api/team.py +11 -66
- agno/api/workflow.py +28 -0
- agno/cloud/aws/base.py +214 -0
- agno/cloud/aws/s3/__init__.py +2 -0
- agno/cloud/aws/s3/api_client.py +43 -0
- agno/cloud/aws/s3/bucket.py +195 -0
- agno/cloud/aws/s3/object.py +57 -0
- agno/db/__init__.py +24 -0
- agno/db/base.py +245 -0
- agno/db/dynamo/__init__.py +3 -0
- agno/db/dynamo/dynamo.py +1743 -0
- agno/db/dynamo/schemas.py +278 -0
- agno/db/dynamo/utils.py +684 -0
- agno/db/firestore/__init__.py +3 -0
- agno/db/firestore/firestore.py +1432 -0
- agno/db/firestore/schemas.py +130 -0
- agno/db/firestore/utils.py +278 -0
- agno/db/gcs_json/__init__.py +3 -0
- agno/db/gcs_json/gcs_json_db.py +1001 -0
- agno/db/gcs_json/utils.py +194 -0
- agno/db/in_memory/__init__.py +3 -0
- agno/db/in_memory/in_memory_db.py +882 -0
- agno/db/in_memory/utils.py +172 -0
- agno/db/json/__init__.py +3 -0
- agno/db/json/json_db.py +1045 -0
- agno/db/json/utils.py +196 -0
- agno/db/migrations/v1_to_v2.py +162 -0
- agno/db/mongo/__init__.py +3 -0
- agno/db/mongo/mongo.py +1416 -0
- agno/db/mongo/schemas.py +77 -0
- agno/db/mongo/utils.py +204 -0
- agno/db/mysql/__init__.py +3 -0
- agno/db/mysql/mysql.py +1719 -0
- agno/db/mysql/schemas.py +124 -0
- agno/db/mysql/utils.py +297 -0
- agno/db/postgres/__init__.py +3 -0
- agno/db/postgres/postgres.py +1710 -0
- agno/db/postgres/schemas.py +124 -0
- agno/db/postgres/utils.py +280 -0
- agno/db/redis/__init__.py +3 -0
- agno/db/redis/redis.py +1367 -0
- agno/db/redis/schemas.py +109 -0
- agno/db/redis/utils.py +288 -0
- agno/db/schemas/__init__.py +3 -0
- agno/db/schemas/evals.py +33 -0
- agno/db/schemas/knowledge.py +40 -0
- agno/db/schemas/memory.py +46 -0
- agno/db/singlestore/__init__.py +3 -0
- agno/db/singlestore/schemas.py +116 -0
- agno/db/singlestore/singlestore.py +1712 -0
- agno/db/singlestore/utils.py +326 -0
- agno/db/sqlite/__init__.py +3 -0
- agno/db/sqlite/schemas.py +119 -0
- agno/db/sqlite/sqlite.py +1676 -0
- agno/db/sqlite/utils.py +268 -0
- agno/db/utils.py +88 -0
- agno/eval/__init__.py +14 -0
- agno/eval/accuracy.py +154 -48
- agno/eval/performance.py +88 -23
- agno/eval/reliability.py +73 -20
- agno/eval/utils.py +23 -13
- agno/integrations/discord/__init__.py +3 -0
- agno/{app → integrations}/discord/client.py +10 -10
- agno/knowledge/__init__.py +2 -2
- agno/{document → knowledge}/chunking/agentic.py +2 -2
- agno/{document → knowledge}/chunking/document.py +2 -2
- agno/{document → knowledge}/chunking/fixed.py +3 -3
- agno/{document → knowledge}/chunking/markdown.py +2 -2
- agno/{document → knowledge}/chunking/recursive.py +2 -2
- agno/{document → knowledge}/chunking/row.py +2 -2
- agno/knowledge/chunking/semantic.py +59 -0
- agno/knowledge/chunking/strategy.py +121 -0
- agno/knowledge/content.py +74 -0
- agno/knowledge/document/__init__.py +5 -0
- agno/{document → knowledge/document}/base.py +12 -2
- agno/knowledge/embedder/__init__.py +5 -0
- agno/{embedder → knowledge/embedder}/aws_bedrock.py +127 -1
- agno/{embedder → knowledge/embedder}/azure_openai.py +65 -1
- agno/{embedder → knowledge/embedder}/base.py +6 -0
- agno/{embedder → knowledge/embedder}/cohere.py +72 -1
- agno/{embedder → knowledge/embedder}/fastembed.py +17 -1
- agno/{embedder → knowledge/embedder}/fireworks.py +1 -1
- agno/{embedder → knowledge/embedder}/google.py +74 -1
- agno/{embedder → knowledge/embedder}/huggingface.py +36 -2
- agno/{embedder → knowledge/embedder}/jina.py +48 -2
- agno/knowledge/embedder/langdb.py +22 -0
- agno/knowledge/embedder/mistral.py +139 -0
- agno/{embedder → knowledge/embedder}/nebius.py +1 -1
- agno/{embedder → knowledge/embedder}/ollama.py +54 -3
- agno/knowledge/embedder/openai.py +223 -0
- agno/{embedder → knowledge/embedder}/sentence_transformer.py +16 -1
- agno/{embedder → knowledge/embedder}/together.py +1 -1
- agno/{embedder → knowledge/embedder}/voyageai.py +49 -1
- agno/knowledge/knowledge.py +1551 -0
- agno/knowledge/reader/__init__.py +7 -0
- agno/{document → knowledge}/reader/arxiv_reader.py +32 -4
- agno/knowledge/reader/base.py +88 -0
- agno/{document → knowledge}/reader/csv_reader.py +47 -65
- agno/knowledge/reader/docx_reader.py +83 -0
- agno/{document → knowledge}/reader/firecrawl_reader.py +42 -21
- agno/{document → knowledge}/reader/json_reader.py +30 -9
- agno/{document → knowledge}/reader/markdown_reader.py +58 -9
- agno/{document → knowledge}/reader/pdf_reader.py +71 -126
- agno/knowledge/reader/reader_factory.py +268 -0
- agno/knowledge/reader/s3_reader.py +101 -0
- agno/{document → knowledge}/reader/text_reader.py +31 -10
- agno/knowledge/reader/url_reader.py +128 -0
- agno/knowledge/reader/web_search_reader.py +366 -0
- agno/{document → knowledge}/reader/website_reader.py +37 -10
- agno/knowledge/reader/wikipedia_reader.py +59 -0
- agno/knowledge/reader/youtube_reader.py +78 -0
- agno/knowledge/remote_content/remote_content.py +88 -0
- agno/{reranker → knowledge/reranker}/base.py +1 -1
- agno/{reranker → knowledge/reranker}/cohere.py +2 -2
- agno/{reranker → knowledge/reranker}/infinity.py +2 -2
- agno/{reranker → knowledge/reranker}/sentence_transformer.py +2 -2
- agno/knowledge/types.py +30 -0
- agno/knowledge/utils.py +169 -0
- agno/media.py +269 -268
- agno/memory/__init__.py +2 -10
- agno/memory/manager.py +1003 -148
- agno/models/aimlapi/__init__.py +2 -2
- agno/models/aimlapi/aimlapi.py +6 -6
- agno/models/anthropic/claude.py +128 -72
- agno/models/aws/bedrock.py +107 -175
- agno/models/aws/claude.py +64 -18
- agno/models/azure/ai_foundry.py +73 -23
- agno/models/base.py +346 -290
- agno/models/cerebras/cerebras.py +84 -27
- agno/models/cohere/chat.py +106 -98
- agno/models/google/gemini.py +105 -46
- agno/models/groq/groq.py +97 -35
- agno/models/huggingface/huggingface.py +92 -27
- agno/models/ibm/watsonx.py +72 -13
- agno/models/litellm/chat.py +85 -13
- agno/models/message.py +46 -151
- agno/models/meta/llama.py +85 -49
- agno/models/metrics.py +120 -0
- agno/models/mistral/mistral.py +90 -21
- agno/models/ollama/__init__.py +0 -2
- agno/models/ollama/chat.py +85 -47
- agno/models/openai/chat.py +154 -37
- agno/models/openai/responses.py +178 -105
- agno/models/perplexity/perplexity.py +26 -2
- agno/models/portkey/portkey.py +0 -7
- agno/models/response.py +15 -9
- agno/models/utils.py +20 -0
- agno/models/vercel/__init__.py +2 -2
- agno/models/vercel/v0.py +1 -1
- agno/models/vllm/__init__.py +2 -2
- agno/models/vllm/vllm.py +3 -3
- agno/models/xai/xai.py +10 -10
- agno/os/__init__.py +3 -0
- agno/os/app.py +497 -0
- agno/os/auth.py +47 -0
- agno/os/config.py +103 -0
- agno/os/interfaces/agui/__init__.py +3 -0
- agno/os/interfaces/agui/agui.py +31 -0
- agno/{app/agui/async_router.py → os/interfaces/agui/router.py} +16 -16
- agno/{app → os/interfaces}/agui/utils.py +65 -28
- agno/os/interfaces/base.py +21 -0
- agno/os/interfaces/slack/__init__.py +3 -0
- agno/{app/slack/async_router.py → os/interfaces/slack/router.py} +3 -5
- agno/os/interfaces/slack/slack.py +32 -0
- agno/os/interfaces/whatsapp/__init__.py +3 -0
- agno/{app/whatsapp/async_router.py → os/interfaces/whatsapp/router.py} +4 -7
- agno/os/interfaces/whatsapp/whatsapp.py +29 -0
- agno/os/mcp.py +235 -0
- agno/os/router.py +1400 -0
- agno/os/routers/__init__.py +3 -0
- agno/os/routers/evals/__init__.py +3 -0
- agno/os/routers/evals/evals.py +393 -0
- agno/os/routers/evals/schemas.py +142 -0
- agno/os/routers/evals/utils.py +161 -0
- agno/os/routers/knowledge/__init__.py +3 -0
- agno/os/routers/knowledge/knowledge.py +850 -0
- agno/os/routers/knowledge/schemas.py +118 -0
- agno/os/routers/memory/__init__.py +3 -0
- agno/os/routers/memory/memory.py +410 -0
- agno/os/routers/memory/schemas.py +58 -0
- agno/os/routers/metrics/__init__.py +3 -0
- agno/os/routers/metrics/metrics.py +178 -0
- agno/os/routers/metrics/schemas.py +47 -0
- agno/os/routers/session/__init__.py +3 -0
- agno/os/routers/session/session.py +536 -0
- agno/os/schema.py +945 -0
- agno/{app/playground → os}/settings.py +7 -15
- agno/os/utils.py +270 -0
- agno/reasoning/azure_ai_foundry.py +4 -4
- agno/reasoning/deepseek.py +4 -4
- agno/reasoning/default.py +6 -11
- agno/reasoning/groq.py +4 -4
- agno/reasoning/helpers.py +4 -6
- agno/reasoning/ollama.py +4 -4
- agno/reasoning/openai.py +4 -4
- agno/run/agent.py +633 -0
- agno/run/base.py +53 -77
- agno/run/cancel.py +81 -0
- agno/run/team.py +243 -96
- agno/run/workflow.py +550 -12
- agno/session/__init__.py +10 -0
- agno/session/agent.py +244 -0
- agno/session/summary.py +225 -0
- agno/session/team.py +262 -0
- agno/{storage/session/v2 → session}/workflow.py +47 -24
- agno/team/__init__.py +15 -16
- agno/team/team.py +3260 -4824
- agno/tools/agentql.py +14 -5
- agno/tools/airflow.py +9 -4
- agno/tools/api.py +7 -3
- agno/tools/apify.py +2 -46
- agno/tools/arxiv.py +8 -3
- agno/tools/aws_lambda.py +7 -5
- agno/tools/aws_ses.py +7 -1
- agno/tools/baidusearch.py +4 -1
- agno/tools/bitbucket.py +4 -4
- agno/tools/brandfetch.py +14 -11
- agno/tools/bravesearch.py +4 -1
- agno/tools/brightdata.py +43 -23
- agno/tools/browserbase.py +13 -4
- agno/tools/calcom.py +12 -10
- agno/tools/calculator.py +10 -27
- agno/tools/cartesia.py +20 -17
- agno/tools/{clickup_tool.py → clickup.py} +12 -25
- agno/tools/confluence.py +8 -8
- agno/tools/crawl4ai.py +7 -1
- agno/tools/csv_toolkit.py +9 -8
- agno/tools/dalle.py +22 -12
- agno/tools/daytona.py +13 -16
- agno/tools/decorator.py +6 -3
- agno/tools/desi_vocal.py +17 -8
- agno/tools/discord.py +11 -8
- agno/tools/docker.py +30 -42
- agno/tools/duckdb.py +34 -53
- agno/tools/duckduckgo.py +8 -7
- agno/tools/e2b.py +62 -62
- agno/tools/eleven_labs.py +36 -29
- agno/tools/email.py +4 -1
- agno/tools/evm.py +7 -1
- agno/tools/exa.py +19 -14
- agno/tools/fal.py +30 -30
- agno/tools/file.py +9 -8
- agno/tools/financial_datasets.py +25 -44
- agno/tools/firecrawl.py +17 -18
- agno/tools/function.py +127 -18
- agno/tools/giphy.py +23 -11
- agno/tools/github.py +48 -126
- agno/tools/gmail.py +45 -61
- agno/tools/google_bigquery.py +7 -6
- agno/tools/google_maps.py +11 -26
- agno/tools/googlesearch.py +7 -2
- agno/tools/googlesheets.py +21 -17
- agno/tools/hackernews.py +9 -5
- agno/tools/jina.py +5 -4
- agno/tools/jira.py +18 -9
- agno/tools/knowledge.py +31 -32
- agno/tools/linear.py +18 -33
- agno/tools/linkup.py +5 -1
- agno/tools/local_file_system.py +8 -5
- agno/tools/lumalab.py +32 -20
- agno/tools/mcp.py +1 -2
- agno/tools/mem0.py +18 -12
- agno/tools/memori.py +14 -10
- agno/tools/mlx_transcribe.py +3 -2
- agno/tools/models/azure_openai.py +33 -15
- agno/tools/models/gemini.py +59 -32
- agno/tools/models/groq.py +30 -23
- agno/tools/models/nebius.py +28 -12
- agno/tools/models_labs.py +40 -16
- agno/tools/moviepy_video.py +7 -6
- agno/tools/neo4j.py +10 -8
- agno/tools/newspaper.py +7 -2
- agno/tools/newspaper4k.py +8 -3
- agno/tools/openai.py +58 -32
- agno/tools/openbb.py +12 -11
- agno/tools/opencv.py +63 -47
- agno/tools/openweather.py +14 -12
- agno/tools/pandas.py +11 -3
- agno/tools/postgres.py +4 -12
- agno/tools/pubmed.py +4 -1
- agno/tools/python.py +9 -22
- agno/tools/reasoning.py +35 -27
- agno/tools/reddit.py +11 -26
- agno/tools/replicate.py +55 -42
- agno/tools/resend.py +4 -1
- agno/tools/scrapegraph.py +15 -14
- agno/tools/searxng.py +10 -23
- agno/tools/serpapi.py +6 -3
- agno/tools/serper.py +13 -4
- agno/tools/shell.py +9 -2
- agno/tools/slack.py +12 -11
- agno/tools/sleep.py +3 -2
- agno/tools/spider.py +24 -4
- agno/tools/sql.py +7 -6
- agno/tools/tavily.py +6 -4
- agno/tools/telegram.py +12 -4
- agno/tools/todoist.py +11 -31
- agno/tools/toolkit.py +1 -1
- agno/tools/trafilatura.py +22 -6
- agno/tools/trello.py +9 -22
- agno/tools/twilio.py +10 -3
- agno/tools/user_control_flow.py +6 -1
- agno/tools/valyu.py +34 -5
- agno/tools/visualization.py +19 -28
- agno/tools/webbrowser.py +4 -3
- agno/tools/webex.py +11 -7
- agno/tools/website.py +15 -46
- agno/tools/webtools.py +12 -4
- agno/tools/whatsapp.py +5 -9
- agno/tools/wikipedia.py +20 -13
- agno/tools/x.py +14 -13
- agno/tools/yfinance.py +13 -40
- agno/tools/youtube.py +26 -20
- agno/tools/zendesk.py +7 -2
- agno/tools/zep.py +10 -7
- agno/tools/zoom.py +10 -9
- agno/utils/common.py +1 -19
- agno/utils/events.py +100 -123
- agno/utils/gemini.py +1 -1
- agno/utils/knowledge.py +29 -0
- agno/utils/log.py +54 -4
- agno/utils/mcp.py +68 -10
- agno/utils/media.py +39 -0
- agno/utils/message.py +12 -1
- agno/utils/models/aws_claude.py +1 -1
- agno/utils/models/claude.py +6 -12
- agno/utils/models/cohere.py +1 -1
- agno/utils/models/mistral.py +8 -7
- agno/utils/models/schema_utils.py +3 -3
- agno/utils/models/watsonx.py +1 -1
- agno/utils/openai.py +1 -1
- agno/utils/pprint.py +33 -32
- agno/utils/print_response/agent.py +779 -0
- agno/utils/print_response/team.py +1669 -0
- agno/utils/print_response/workflow.py +1451 -0
- agno/utils/prompts.py +14 -14
- agno/utils/reasoning.py +87 -0
- agno/utils/response.py +42 -42
- agno/utils/streamlit.py +481 -0
- agno/utils/string.py +8 -22
- agno/utils/team.py +50 -0
- agno/utils/timer.py +2 -2
- agno/vectordb/base.py +33 -21
- agno/vectordb/cassandra/cassandra.py +287 -23
- agno/vectordb/chroma/chromadb.py +482 -59
- agno/vectordb/clickhouse/clickhousedb.py +270 -63
- agno/vectordb/couchbase/couchbase.py +309 -29
- agno/vectordb/lancedb/lance_db.py +360 -21
- agno/vectordb/langchaindb/__init__.py +5 -0
- agno/vectordb/langchaindb/langchaindb.py +145 -0
- agno/vectordb/lightrag/__init__.py +5 -0
- agno/vectordb/lightrag/lightrag.py +374 -0
- agno/vectordb/llamaindex/llamaindexdb.py +127 -0
- agno/vectordb/milvus/milvus.py +242 -32
- agno/vectordb/mongodb/mongodb.py +200 -24
- agno/vectordb/pgvector/pgvector.py +319 -37
- agno/vectordb/pineconedb/pineconedb.py +221 -27
- agno/vectordb/qdrant/qdrant.py +334 -14
- agno/vectordb/singlestore/singlestore.py +286 -29
- agno/vectordb/surrealdb/surrealdb.py +187 -7
- agno/vectordb/upstashdb/upstashdb.py +342 -26
- agno/vectordb/weaviate/weaviate.py +227 -165
- agno/workflow/__init__.py +17 -13
- agno/workflow/{v2/condition.py → condition.py} +135 -32
- agno/workflow/{v2/loop.py → loop.py} +115 -28
- agno/workflow/{v2/parallel.py → parallel.py} +138 -108
- agno/workflow/{v2/router.py → router.py} +133 -32
- agno/workflow/{v2/step.py → step.py} +207 -49
- agno/workflow/{v2/steps.py → steps.py} +147 -66
- agno/workflow/types.py +482 -0
- agno/workflow/workflow.py +2410 -696
- agno-2.0.0.dist-info/METADATA +494 -0
- agno-2.0.0.dist-info/RECORD +515 -0
- agno-2.0.0.dist-info/licenses/LICENSE +201 -0
- agno/agent/metrics.py +0 -110
- agno/api/app.py +0 -35
- agno/api/playground.py +0 -92
- agno/api/schemas/app.py +0 -12
- agno/api/schemas/playground.py +0 -22
- agno/api/schemas/user.py +0 -35
- agno/api/schemas/workspace.py +0 -46
- agno/api/user.py +0 -160
- agno/api/workflows.py +0 -33
- agno/api/workspace.py +0 -175
- agno/app/agui/__init__.py +0 -3
- agno/app/agui/app.py +0 -17
- agno/app/agui/sync_router.py +0 -120
- agno/app/base.py +0 -186
- agno/app/discord/__init__.py +0 -3
- agno/app/fastapi/__init__.py +0 -3
- agno/app/fastapi/app.py +0 -107
- agno/app/fastapi/async_router.py +0 -457
- agno/app/fastapi/sync_router.py +0 -448
- agno/app/playground/app.py +0 -228
- agno/app/playground/async_router.py +0 -1053
- agno/app/playground/deploy.py +0 -249
- agno/app/playground/operator.py +0 -183
- agno/app/playground/schemas.py +0 -223
- agno/app/playground/serve.py +0 -55
- agno/app/playground/sync_router.py +0 -1045
- agno/app/playground/utils.py +0 -46
- agno/app/settings.py +0 -15
- agno/app/slack/__init__.py +0 -3
- agno/app/slack/app.py +0 -19
- agno/app/slack/sync_router.py +0 -92
- agno/app/utils.py +0 -54
- agno/app/whatsapp/__init__.py +0 -3
- agno/app/whatsapp/app.py +0 -15
- agno/app/whatsapp/sync_router.py +0 -197
- agno/cli/auth_server.py +0 -249
- agno/cli/config.py +0 -274
- agno/cli/console.py +0 -88
- agno/cli/credentials.py +0 -23
- agno/cli/entrypoint.py +0 -571
- agno/cli/operator.py +0 -357
- agno/cli/settings.py +0 -96
- agno/cli/ws/ws_cli.py +0 -817
- agno/constants.py +0 -13
- agno/document/__init__.py +0 -5
- agno/document/chunking/semantic.py +0 -45
- agno/document/chunking/strategy.py +0 -31
- agno/document/reader/__init__.py +0 -5
- agno/document/reader/base.py +0 -47
- agno/document/reader/docx_reader.py +0 -60
- agno/document/reader/gcs/pdf_reader.py +0 -44
- agno/document/reader/s3/pdf_reader.py +0 -59
- agno/document/reader/s3/text_reader.py +0 -63
- agno/document/reader/url_reader.py +0 -59
- agno/document/reader/youtube_reader.py +0 -58
- agno/embedder/__init__.py +0 -5
- agno/embedder/langdb.py +0 -80
- agno/embedder/mistral.py +0 -82
- agno/embedder/openai.py +0 -78
- agno/file/__init__.py +0 -5
- agno/file/file.py +0 -16
- agno/file/local/csv.py +0 -32
- agno/file/local/txt.py +0 -19
- agno/infra/app.py +0 -240
- agno/infra/base.py +0 -144
- agno/infra/context.py +0 -20
- agno/infra/db_app.py +0 -52
- agno/infra/resource.py +0 -205
- agno/infra/resources.py +0 -55
- agno/knowledge/agent.py +0 -702
- agno/knowledge/arxiv.py +0 -33
- agno/knowledge/combined.py +0 -36
- agno/knowledge/csv.py +0 -144
- agno/knowledge/csv_url.py +0 -124
- agno/knowledge/document.py +0 -223
- agno/knowledge/docx.py +0 -137
- agno/knowledge/firecrawl.py +0 -34
- agno/knowledge/gcs/__init__.py +0 -0
- agno/knowledge/gcs/base.py +0 -39
- agno/knowledge/gcs/pdf.py +0 -125
- agno/knowledge/json.py +0 -137
- agno/knowledge/langchain.py +0 -71
- agno/knowledge/light_rag.py +0 -273
- agno/knowledge/llamaindex.py +0 -66
- agno/knowledge/markdown.py +0 -154
- agno/knowledge/pdf.py +0 -164
- agno/knowledge/pdf_bytes.py +0 -42
- agno/knowledge/pdf_url.py +0 -148
- agno/knowledge/s3/__init__.py +0 -0
- agno/knowledge/s3/base.py +0 -64
- agno/knowledge/s3/pdf.py +0 -33
- agno/knowledge/s3/text.py +0 -34
- agno/knowledge/text.py +0 -141
- agno/knowledge/url.py +0 -46
- agno/knowledge/website.py +0 -179
- agno/knowledge/wikipedia.py +0 -32
- agno/knowledge/youtube.py +0 -35
- agno/memory/agent.py +0 -423
- agno/memory/classifier.py +0 -104
- agno/memory/db/__init__.py +0 -5
- agno/memory/db/base.py +0 -42
- agno/memory/db/mongodb.py +0 -189
- agno/memory/db/postgres.py +0 -203
- agno/memory/db/sqlite.py +0 -193
- agno/memory/memory.py +0 -22
- agno/memory/row.py +0 -36
- agno/memory/summarizer.py +0 -201
- agno/memory/summary.py +0 -19
- agno/memory/team.py +0 -415
- agno/memory/v2/__init__.py +0 -2
- agno/memory/v2/db/__init__.py +0 -1
- agno/memory/v2/db/base.py +0 -42
- agno/memory/v2/db/firestore.py +0 -339
- agno/memory/v2/db/mongodb.py +0 -196
- agno/memory/v2/db/postgres.py +0 -214
- agno/memory/v2/db/redis.py +0 -187
- agno/memory/v2/db/schema.py +0 -54
- agno/memory/v2/db/sqlite.py +0 -209
- agno/memory/v2/manager.py +0 -437
- agno/memory/v2/memory.py +0 -1097
- agno/memory/v2/schema.py +0 -55
- agno/memory/v2/summarizer.py +0 -215
- agno/memory/workflow.py +0 -38
- agno/models/ollama/tools.py +0 -430
- agno/models/qwen/__init__.py +0 -5
- agno/playground/__init__.py +0 -10
- agno/playground/deploy.py +0 -3
- agno/playground/playground.py +0 -3
- agno/playground/serve.py +0 -3
- agno/playground/settings.py +0 -3
- agno/reranker/__init__.py +0 -0
- agno/run/response.py +0 -467
- agno/run/v2/__init__.py +0 -0
- agno/run/v2/workflow.py +0 -567
- agno/storage/__init__.py +0 -0
- agno/storage/agent/__init__.py +0 -0
- agno/storage/agent/dynamodb.py +0 -1
- agno/storage/agent/json.py +0 -1
- agno/storage/agent/mongodb.py +0 -1
- agno/storage/agent/postgres.py +0 -1
- agno/storage/agent/singlestore.py +0 -1
- agno/storage/agent/sqlite.py +0 -1
- agno/storage/agent/yaml.py +0 -1
- agno/storage/base.py +0 -60
- agno/storage/dynamodb.py +0 -673
- agno/storage/firestore.py +0 -297
- agno/storage/gcs_json.py +0 -261
- agno/storage/in_memory.py +0 -234
- agno/storage/json.py +0 -237
- agno/storage/mongodb.py +0 -328
- agno/storage/mysql.py +0 -685
- agno/storage/postgres.py +0 -682
- agno/storage/redis.py +0 -336
- agno/storage/session/__init__.py +0 -16
- agno/storage/session/agent.py +0 -64
- agno/storage/session/team.py +0 -63
- agno/storage/session/v2/__init__.py +0 -5
- agno/storage/session/workflow.py +0 -61
- agno/storage/singlestore.py +0 -606
- agno/storage/sqlite.py +0 -646
- agno/storage/workflow/__init__.py +0 -0
- agno/storage/workflow/mongodb.py +0 -1
- agno/storage/workflow/postgres.py +0 -1
- agno/storage/workflow/sqlite.py +0 -1
- agno/storage/yaml.py +0 -241
- agno/tools/thinking.py +0 -73
- agno/utils/defaults.py +0 -57
- agno/utils/filesystem.py +0 -39
- agno/utils/git.py +0 -52
- agno/utils/json_io.py +0 -30
- agno/utils/load_env.py +0 -19
- agno/utils/py_io.py +0 -19
- agno/utils/pyproject.py +0 -18
- agno/utils/resource_filter.py +0 -31
- agno/workflow/v2/__init__.py +0 -21
- agno/workflow/v2/types.py +0 -357
- agno/workflow/v2/workflow.py +0 -3313
- agno/workspace/__init__.py +0 -0
- agno/workspace/config.py +0 -325
- agno/workspace/enums.py +0 -6
- agno/workspace/helpers.py +0 -52
- agno/workspace/operator.py +0 -757
- agno/workspace/settings.py +0 -158
- agno-1.8.2.dist-info/METADATA +0 -982
- agno-1.8.2.dist-info/RECORD +0 -566
- agno-1.8.2.dist-info/entry_points.txt +0 -3
- agno-1.8.2.dist-info/licenses/LICENSE +0 -375
- /agno/{app → db/migrations}/__init__.py +0 -0
- /agno/{app/playground/__init__.py → db/schemas/metrics.py} +0 -0
- /agno/{cli → integrations}/__init__.py +0 -0
- /agno/{cli/ws → knowledge/chunking}/__init__.py +0 -0
- /agno/{document/chunking → knowledge/remote_content}/__init__.py +0 -0
- /agno/{document/reader/gcs → knowledge/reranker}/__init__.py +0 -0
- /agno/{document/reader/s3 → os/interfaces}/__init__.py +0 -0
- /agno/{app → os/interfaces}/slack/security.py +0 -0
- /agno/{app → os/interfaces}/whatsapp/security.py +0 -0
- /agno/{file/local → utils/print_response}/__init__.py +0 -0
- /agno/{infra → vectordb/llamaindex}/__init__.py +0 -0
- {agno-1.8.2.dist-info → agno-2.0.0.dist-info}/WHEEL +0 -0
- {agno-1.8.2.dist-info → agno-2.0.0.dist-info}/top_level.txt +0 -0
|
@@ -2,20 +2,21 @@ import asyncio
|
|
|
2
2
|
from concurrent.futures import ThreadPoolExecutor, as_completed
|
|
3
3
|
from dataclasses import dataclass
|
|
4
4
|
from typing import Any, AsyncIterator, Awaitable, Callable, Dict, Iterator, List, Optional, Union
|
|
5
|
+
from uuid import uuid4
|
|
5
6
|
|
|
6
|
-
from agno.
|
|
7
|
-
from agno.run.
|
|
8
|
-
from agno.run.
|
|
7
|
+
from agno.models.metrics import Metrics
|
|
8
|
+
from agno.run.agent import RunOutputEvent
|
|
9
|
+
from agno.run.team import TeamRunOutputEvent
|
|
10
|
+
from agno.run.workflow import (
|
|
9
11
|
ParallelExecutionCompletedEvent,
|
|
10
12
|
ParallelExecutionStartedEvent,
|
|
11
|
-
|
|
12
|
-
|
|
13
|
+
WorkflowRunOutput,
|
|
14
|
+
WorkflowRunOutputEvent,
|
|
13
15
|
)
|
|
14
16
|
from agno.utils.log import log_debug, logger
|
|
15
|
-
from agno.workflow.
|
|
16
|
-
from agno.workflow.
|
|
17
|
-
from agno.workflow.
|
|
18
|
-
from agno.workflow.v2.types import StepInput, StepOutput
|
|
17
|
+
from agno.workflow.condition import Condition
|
|
18
|
+
from agno.workflow.step import Step
|
|
19
|
+
from agno.workflow.types import StepInput, StepOutput, StepType
|
|
19
20
|
|
|
20
21
|
WorkflowSteps = List[
|
|
21
22
|
Union[
|
|
@@ -55,10 +56,10 @@ class Parallel:
|
|
|
55
56
|
"""Prepare the steps for execution - mirrors workflow logic"""
|
|
56
57
|
from agno.agent.agent import Agent
|
|
57
58
|
from agno.team.team import Team
|
|
58
|
-
from agno.workflow.
|
|
59
|
-
from agno.workflow.
|
|
60
|
-
from agno.workflow.
|
|
61
|
-
from agno.workflow.
|
|
59
|
+
from agno.workflow.loop import Loop
|
|
60
|
+
from agno.workflow.router import Router
|
|
61
|
+
from agno.workflow.step import Step
|
|
62
|
+
from agno.workflow.steps import Steps
|
|
62
63
|
|
|
63
64
|
prepared_steps: WorkflowSteps = []
|
|
64
65
|
for step in self.steps:
|
|
@@ -78,23 +79,25 @@ class Parallel:
|
|
|
78
79
|
def _aggregate_results(self, step_outputs: List[StepOutput]) -> StepOutput:
|
|
79
80
|
"""Aggregate multiple step outputs into a single StepOutput"""
|
|
80
81
|
if not step_outputs:
|
|
81
|
-
return StepOutput(
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
82
|
+
return StepOutput(
|
|
83
|
+
step_name=self.name or "Parallel",
|
|
84
|
+
step_id=str(uuid4()),
|
|
85
|
+
step_type="Parallel",
|
|
86
|
+
content="No parallel steps executed",
|
|
87
|
+
steps=[],
|
|
88
|
+
)
|
|
85
89
|
|
|
86
90
|
if len(step_outputs) == 1:
|
|
87
|
-
# Single result,
|
|
91
|
+
# Single result, but still create a Parallel container
|
|
88
92
|
single_result = step_outputs[0]
|
|
89
|
-
|
|
90
|
-
# Extract metrics using the dedicated method
|
|
91
93
|
aggregated_metrics = self._extract_metrics_from_response(step_outputs)
|
|
92
94
|
|
|
93
95
|
return StepOutput(
|
|
94
96
|
step_name=self.name or "Parallel",
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
97
|
+
step_id=str(uuid4()),
|
|
98
|
+
step_type=StepType.PARALLEL,
|
|
99
|
+
content=f"Parallel {self.name or 'execution'} completed with 1 result",
|
|
100
|
+
executor_name=self.name or "Parallel",
|
|
98
101
|
images=single_result.images,
|
|
99
102
|
videos=single_result.videos,
|
|
100
103
|
audio=single_result.audio,
|
|
@@ -102,12 +105,13 @@ class Parallel:
|
|
|
102
105
|
success=single_result.success,
|
|
103
106
|
error=single_result.error,
|
|
104
107
|
stop=single_result.stop,
|
|
108
|
+
steps=step_outputs, # This is the key addition
|
|
105
109
|
)
|
|
106
110
|
|
|
107
111
|
early_termination_requested = any(output.stop for output in step_outputs if hasattr(output, "stop"))
|
|
108
112
|
|
|
109
113
|
# Multiple results - aggregate them
|
|
110
|
-
aggregated_content = self.
|
|
114
|
+
aggregated_content = f"Parallel {self.name or 'execution'} completed with {len(step_outputs)} results"
|
|
111
115
|
|
|
112
116
|
# Combine all media from parallel steps
|
|
113
117
|
all_images = []
|
|
@@ -127,63 +131,42 @@ class Parallel:
|
|
|
127
131
|
|
|
128
132
|
return StepOutput(
|
|
129
133
|
step_name=self.name or "Parallel",
|
|
134
|
+
step_id=str(uuid4()),
|
|
135
|
+
step_type=StepType.PARALLEL,
|
|
136
|
+
executor_type="parallel",
|
|
137
|
+
executor_name=self.name or "Parallel",
|
|
130
138
|
content=aggregated_content,
|
|
131
|
-
parallel_step_outputs=parallel_step_outputs,
|
|
132
139
|
images=all_images if all_images else None,
|
|
133
140
|
videos=all_videos if all_videos else None,
|
|
134
141
|
audio=all_audio if all_audio else None,
|
|
135
142
|
success=not has_any_failure,
|
|
136
143
|
stop=early_termination_requested,
|
|
137
144
|
metrics=aggregated_metrics,
|
|
145
|
+
steps=step_outputs,
|
|
138
146
|
)
|
|
139
147
|
|
|
140
|
-
def _extract_metrics_from_response(self, step_outputs: List[StepOutput]) -> Optional[
|
|
148
|
+
def _extract_metrics_from_response(self, step_outputs: List[StepOutput]) -> Optional[Metrics]:
|
|
141
149
|
"""Extract and aggregate metrics from parallel step outputs"""
|
|
142
150
|
if not step_outputs:
|
|
143
151
|
return None
|
|
144
152
|
|
|
145
|
-
|
|
153
|
+
# Aggregate metrics from all parallel step outputs
|
|
154
|
+
total_metrics = Metrics()
|
|
146
155
|
|
|
147
156
|
for result in step_outputs:
|
|
148
|
-
step_name = result.step_name or "unknown"
|
|
149
|
-
|
|
150
|
-
# Create clean step metrics for parallel steps
|
|
151
157
|
if result.metrics:
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
parallel_step_metrics[step_name] = {
|
|
163
|
-
"step_name": step_name,
|
|
164
|
-
"executor_type": executor_type,
|
|
165
|
-
"executor_name": executor_name,
|
|
166
|
-
"metrics": actual_metrics,
|
|
167
|
-
}
|
|
168
|
-
else:
|
|
169
|
-
# Even if no metrics, record the step execution
|
|
170
|
-
parallel_step_metrics[step_name] = {
|
|
171
|
-
"step_name": step_name,
|
|
172
|
-
"executor_type": getattr(result, "executor_type", "unknown"),
|
|
173
|
-
"executor_name": getattr(result, "executor_name", "unknown"),
|
|
174
|
-
"metrics": None,
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
# Create aggregated metrics structure for parallel execution
|
|
178
|
-
if parallel_step_metrics:
|
|
179
|
-
return {
|
|
180
|
-
"step_name": self.name or "Parallel",
|
|
181
|
-
"executor_type": "parallel",
|
|
182
|
-
"executor_name": self.name or "Parallel",
|
|
183
|
-
"parallel_steps": parallel_step_metrics,
|
|
184
|
-
}
|
|
158
|
+
total_metrics = total_metrics + result.metrics
|
|
159
|
+
|
|
160
|
+
# If no metrics were found, return None
|
|
161
|
+
if (
|
|
162
|
+
total_metrics.input_tokens == 0
|
|
163
|
+
and total_metrics.output_tokens == 0
|
|
164
|
+
and total_metrics.total_tokens == 0
|
|
165
|
+
and total_metrics.duration is None
|
|
166
|
+
):
|
|
167
|
+
return None
|
|
185
168
|
|
|
186
|
-
return
|
|
169
|
+
return total_metrics
|
|
187
170
|
|
|
188
171
|
def _build_aggregated_content(self, step_outputs: List[StepOutput]) -> str:
|
|
189
172
|
"""Build aggregated content from multiple step outputs"""
|
|
@@ -212,6 +195,9 @@ class Parallel:
|
|
|
212
195
|
step_input: StepInput,
|
|
213
196
|
session_id: Optional[str] = None,
|
|
214
197
|
user_id: Optional[str] = None,
|
|
198
|
+
workflow_run_response: Optional[WorkflowRunOutput] = None,
|
|
199
|
+
store_executor_outputs: bool = True,
|
|
200
|
+
session_state: Optional[Dict[str, Any]] = None,
|
|
215
201
|
) -> StepOutput:
|
|
216
202
|
"""Execute all steps in parallel and return aggregated result"""
|
|
217
203
|
# Use workflow logger for parallel orchestration
|
|
@@ -221,17 +207,27 @@ class Parallel:
|
|
|
221
207
|
|
|
222
208
|
def execute_step_with_index(step_with_index):
|
|
223
209
|
"""Execute a single step and preserve its original index"""
|
|
224
|
-
|
|
210
|
+
idx, step = step_with_index
|
|
225
211
|
try:
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
212
|
+
step_result = step.execute(
|
|
213
|
+
step_input,
|
|
214
|
+
session_id=session_id,
|
|
215
|
+
user_id=user_id,
|
|
216
|
+
workflow_run_response=workflow_run_response,
|
|
217
|
+
store_executor_outputs=store_executor_outputs,
|
|
218
|
+
session_state=session_state,
|
|
219
|
+
) # type: ignore[union-attr]
|
|
220
|
+
return idx, step_result
|
|
221
|
+
except Exception as exc:
|
|
222
|
+
parallel_step_name = getattr(step, "name", f"step_{idx}")
|
|
223
|
+
logger.error(f"Parallel step {parallel_step_name} failed: {exc}")
|
|
231
224
|
return (
|
|
232
|
-
|
|
225
|
+
idx,
|
|
233
226
|
StepOutput(
|
|
234
|
-
step_name=
|
|
227
|
+
step_name=parallel_step_name,
|
|
228
|
+
content=f"Step {parallel_step_name} failed: {str(exc)}",
|
|
229
|
+
success=False,
|
|
230
|
+
error=str(exc),
|
|
235
231
|
),
|
|
236
232
|
)
|
|
237
233
|
|
|
@@ -295,12 +291,17 @@ class Parallel:
|
|
|
295
291
|
session_id: Optional[str] = None,
|
|
296
292
|
user_id: Optional[str] = None,
|
|
297
293
|
stream_intermediate_steps: bool = False,
|
|
298
|
-
workflow_run_response: Optional[
|
|
294
|
+
workflow_run_response: Optional[WorkflowRunOutput] = None,
|
|
299
295
|
step_index: Optional[Union[int, tuple]] = None,
|
|
300
|
-
|
|
296
|
+
store_executor_outputs: bool = True,
|
|
297
|
+
session_state: Optional[Dict[str, Any]] = None,
|
|
298
|
+
parent_step_id: Optional[str] = None,
|
|
299
|
+
) -> Iterator[Union[WorkflowRunOutputEvent, StepOutput]]:
|
|
301
300
|
"""Execute all steps in parallel with streaming support"""
|
|
302
301
|
log_debug(f"Parallel Start: {self.name} ({len(self.steps)} steps)", center=True, symbol="=")
|
|
303
302
|
|
|
303
|
+
parallel_step_id = str(uuid4())
|
|
304
|
+
|
|
304
305
|
self._prepare_steps()
|
|
305
306
|
|
|
306
307
|
if stream_intermediate_steps and workflow_run_response:
|
|
@@ -313,19 +314,21 @@ class Parallel:
|
|
|
313
314
|
step_name=self.name,
|
|
314
315
|
step_index=step_index,
|
|
315
316
|
parallel_step_count=len(self.steps),
|
|
317
|
+
step_id=parallel_step_id,
|
|
318
|
+
parent_step_id=parent_step_id,
|
|
316
319
|
)
|
|
317
320
|
|
|
318
321
|
def execute_step_stream_with_index(step_with_index):
|
|
319
322
|
"""Execute a single step with streaming and preserve its original index"""
|
|
320
|
-
|
|
323
|
+
idx, step = step_with_index
|
|
321
324
|
try:
|
|
322
|
-
|
|
325
|
+
step_events = []
|
|
323
326
|
|
|
324
327
|
# If step_index is None or integer (main step): create (step_index, sub_index)
|
|
325
328
|
# If step_index is tuple (child step): all parallel sub-steps get same index
|
|
326
329
|
if step_index is None or isinstance(step_index, int):
|
|
327
330
|
# Parallel is a main step - sub-steps get sequential numbers: 1.1, 1.2, 1.3
|
|
328
|
-
sub_step_index = (step_index if step_index is not None else 0,
|
|
331
|
+
sub_step_index = (step_index if step_index is not None else 0, idx)
|
|
329
332
|
else:
|
|
330
333
|
# Parallel is a child step - all sub-steps get the same parent number: 1.1, 1.1, 1.1
|
|
331
334
|
sub_step_index = step_index
|
|
@@ -338,20 +341,23 @@ class Parallel:
|
|
|
338
341
|
stream_intermediate_steps=stream_intermediate_steps,
|
|
339
342
|
workflow_run_response=workflow_run_response,
|
|
340
343
|
step_index=sub_step_index,
|
|
344
|
+
store_executor_outputs=store_executor_outputs,
|
|
345
|
+
session_state=session_state,
|
|
346
|
+
parent_step_id=parallel_step_id,
|
|
341
347
|
):
|
|
342
|
-
|
|
343
|
-
return
|
|
344
|
-
except Exception as
|
|
345
|
-
|
|
346
|
-
logger.error(f"Parallel step {
|
|
348
|
+
step_events.append(event)
|
|
349
|
+
return idx, step_events
|
|
350
|
+
except Exception as exc:
|
|
351
|
+
parallel_step_name = getattr(step, "name", f"step_{idx}")
|
|
352
|
+
logger.error(f"Parallel step {parallel_step_name} streaming failed: {exc}")
|
|
347
353
|
return (
|
|
348
|
-
|
|
354
|
+
idx,
|
|
349
355
|
[
|
|
350
356
|
StepOutput(
|
|
351
|
-
step_name=
|
|
352
|
-
content=f"Step {
|
|
357
|
+
step_name=parallel_step_name,
|
|
358
|
+
content=f"Step {parallel_step_name} failed: {str(exc)}",
|
|
353
359
|
success=False,
|
|
354
|
-
error=str(
|
|
360
|
+
error=str(exc),
|
|
355
361
|
)
|
|
356
362
|
],
|
|
357
363
|
)
|
|
@@ -431,6 +437,8 @@ class Parallel:
|
|
|
431
437
|
step_index=step_index,
|
|
432
438
|
parallel_step_count=len(self.steps),
|
|
433
439
|
step_results=[aggregated_result], # Now single aggregated result
|
|
440
|
+
step_id=parallel_step_id,
|
|
441
|
+
parent_step_id=parent_step_id,
|
|
434
442
|
)
|
|
435
443
|
|
|
436
444
|
async def aexecute(
|
|
@@ -438,6 +446,9 @@ class Parallel:
|
|
|
438
446
|
step_input: StepInput,
|
|
439
447
|
session_id: Optional[str] = None,
|
|
440
448
|
user_id: Optional[str] = None,
|
|
449
|
+
workflow_run_response: Optional[WorkflowRunOutput] = None,
|
|
450
|
+
store_executor_outputs: bool = True,
|
|
451
|
+
session_state: Optional[Dict[str, Any]] = None,
|
|
441
452
|
) -> StepOutput:
|
|
442
453
|
"""Execute all steps in parallel using asyncio and return aggregated result"""
|
|
443
454
|
# Use workflow logger for async parallel orchestration
|
|
@@ -447,20 +458,27 @@ class Parallel:
|
|
|
447
458
|
|
|
448
459
|
async def execute_step_async_with_index(step_with_index):
|
|
449
460
|
"""Execute a single step asynchronously and preserve its original index"""
|
|
450
|
-
|
|
461
|
+
idx, step = step_with_index
|
|
451
462
|
try:
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
463
|
+
inner_step_result = await step.aexecute(
|
|
464
|
+
step_input,
|
|
465
|
+
session_id=session_id,
|
|
466
|
+
user_id=user_id,
|
|
467
|
+
workflow_run_response=workflow_run_response,
|
|
468
|
+
store_executor_outputs=store_executor_outputs,
|
|
469
|
+
session_state=session_state,
|
|
470
|
+
) # type: ignore[union-attr]
|
|
471
|
+
return idx, inner_step_result
|
|
472
|
+
except Exception as exc:
|
|
473
|
+
parallel_step_name = getattr(step, "name", f"step_{idx}")
|
|
474
|
+
logger.error(f"Parallel step {parallel_step_name} failed: {exc}")
|
|
457
475
|
return (
|
|
458
|
-
|
|
476
|
+
idx,
|
|
459
477
|
StepOutput(
|
|
460
|
-
step_name=
|
|
461
|
-
content=f"Step {
|
|
478
|
+
step_name=parallel_step_name,
|
|
479
|
+
content=f"Step {parallel_step_name} failed: {str(exc)}",
|
|
462
480
|
success=False,
|
|
463
|
-
error=str(
|
|
481
|
+
error=str(exc),
|
|
464
482
|
),
|
|
465
483
|
)
|
|
466
484
|
|
|
@@ -522,12 +540,17 @@ class Parallel:
|
|
|
522
540
|
session_id: Optional[str] = None,
|
|
523
541
|
user_id: Optional[str] = None,
|
|
524
542
|
stream_intermediate_steps: bool = False,
|
|
525
|
-
workflow_run_response: Optional[
|
|
543
|
+
workflow_run_response: Optional[WorkflowRunOutput] = None,
|
|
526
544
|
step_index: Optional[Union[int, tuple]] = None,
|
|
527
|
-
|
|
545
|
+
store_executor_outputs: bool = True,
|
|
546
|
+
session_state: Optional[Dict[str, Any]] = None,
|
|
547
|
+
parent_step_id: Optional[str] = None,
|
|
548
|
+
) -> AsyncIterator[Union[WorkflowRunOutputEvent, TeamRunOutputEvent, RunOutputEvent, StepOutput]]:
|
|
528
549
|
"""Execute all steps in parallel with async streaming support"""
|
|
529
550
|
log_debug(f"Parallel Start: {self.name} ({len(self.steps)} steps)", center=True, symbol="=")
|
|
530
551
|
|
|
552
|
+
parallel_step_id = str(uuid4())
|
|
553
|
+
|
|
531
554
|
self._prepare_steps()
|
|
532
555
|
|
|
533
556
|
if stream_intermediate_steps and workflow_run_response:
|
|
@@ -540,19 +563,21 @@ class Parallel:
|
|
|
540
563
|
step_name=self.name,
|
|
541
564
|
step_index=step_index,
|
|
542
565
|
parallel_step_count=len(self.steps),
|
|
566
|
+
step_id=parallel_step_id,
|
|
567
|
+
parent_step_id=parent_step_id,
|
|
543
568
|
)
|
|
544
569
|
|
|
545
570
|
async def execute_step_stream_async_with_index(step_with_index):
|
|
546
571
|
"""Execute a single step with async streaming and preserve its original index"""
|
|
547
|
-
|
|
572
|
+
idx, step = step_with_index
|
|
548
573
|
try:
|
|
549
|
-
|
|
574
|
+
step_events = []
|
|
550
575
|
|
|
551
576
|
# If step_index is None or integer (main step): create (step_index, sub_index)
|
|
552
577
|
# If step_index is tuple (child step): all parallel sub-steps get same index
|
|
553
578
|
if step_index is None or isinstance(step_index, int):
|
|
554
579
|
# Parallel is a main step - sub-steps get sequential numbers: 1.1, 1.2, 1.3
|
|
555
|
-
sub_step_index = (step_index if step_index is not None else 0,
|
|
580
|
+
sub_step_index = (step_index if step_index is not None else 0, idx)
|
|
556
581
|
else:
|
|
557
582
|
# Parallel is a child step - all sub-steps get the same parent number: 1.1, 1.1, 1.1
|
|
558
583
|
sub_step_index = step_index
|
|
@@ -565,18 +590,21 @@ class Parallel:
|
|
|
565
590
|
stream_intermediate_steps=stream_intermediate_steps,
|
|
566
591
|
workflow_run_response=workflow_run_response,
|
|
567
592
|
step_index=sub_step_index,
|
|
593
|
+
store_executor_outputs=store_executor_outputs,
|
|
594
|
+
session_state=session_state,
|
|
595
|
+
parent_step_id=parallel_step_id,
|
|
568
596
|
): # type: ignore[union-attr]
|
|
569
|
-
|
|
570
|
-
return
|
|
597
|
+
step_events.append(event)
|
|
598
|
+
return idx, step_events
|
|
571
599
|
except Exception as e:
|
|
572
|
-
|
|
573
|
-
logger.error(f"Parallel step {
|
|
600
|
+
parallel_step_name = getattr(step, "name", f"step_{idx}")
|
|
601
|
+
logger.error(f"Parallel step {parallel_step_name} async streaming failed: {e}")
|
|
574
602
|
return (
|
|
575
|
-
|
|
603
|
+
idx,
|
|
576
604
|
[
|
|
577
605
|
StepOutput(
|
|
578
|
-
step_name=
|
|
579
|
-
content=f"Step {
|
|
606
|
+
step_name=parallel_step_name,
|
|
607
|
+
content=f"Step {parallel_step_name} failed: {str(e)}",
|
|
580
608
|
success=False,
|
|
581
609
|
error=str(e),
|
|
582
610
|
)
|
|
@@ -656,4 +684,6 @@ class Parallel:
|
|
|
656
684
|
step_index=step_index,
|
|
657
685
|
parallel_step_count=len(self.steps),
|
|
658
686
|
step_results=[aggregated_result], # Now single aggregated result
|
|
687
|
+
step_id=parallel_step_id,
|
|
688
|
+
parent_step_id=parent_step_id,
|
|
659
689
|
)
|