agno 0.1.2__py3-none-any.whl → 2.3.13__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/__init__.py +8 -0
- agno/agent/__init__.py +44 -5
- agno/agent/agent.py +10531 -2975
- agno/api/agent.py +14 -53
- agno/api/api.py +7 -46
- agno/api/evals.py +22 -0
- agno/api/os.py +17 -0
- agno/api/routes.py +6 -25
- agno/api/schemas/__init__.py +9 -0
- agno/api/schemas/agent.py +6 -9
- agno/api/schemas/evals.py +16 -0
- agno/api/schemas/os.py +14 -0
- agno/api/schemas/team.py +10 -10
- agno/api/schemas/utils.py +21 -0
- agno/api/schemas/workflows.py +16 -0
- agno/api/settings.py +53 -0
- agno/api/team.py +22 -26
- 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/compression/__init__.py +3 -0
- agno/compression/manager.py +247 -0
- agno/culture/__init__.py +3 -0
- agno/culture/manager.py +956 -0
- agno/db/__init__.py +24 -0
- agno/db/async_postgres/__init__.py +3 -0
- agno/db/base.py +946 -0
- agno/db/dynamo/__init__.py +3 -0
- agno/db/dynamo/dynamo.py +2781 -0
- agno/db/dynamo/schemas.py +442 -0
- agno/db/dynamo/utils.py +743 -0
- agno/db/firestore/__init__.py +3 -0
- agno/db/firestore/firestore.py +2379 -0
- agno/db/firestore/schemas.py +181 -0
- agno/db/firestore/utils.py +376 -0
- agno/db/gcs_json/__init__.py +3 -0
- agno/db/gcs_json/gcs_json_db.py +1791 -0
- agno/db/gcs_json/utils.py +228 -0
- agno/db/in_memory/__init__.py +3 -0
- agno/db/in_memory/in_memory_db.py +1312 -0
- agno/db/in_memory/utils.py +230 -0
- agno/db/json/__init__.py +3 -0
- agno/db/json/json_db.py +1777 -0
- agno/db/json/utils.py +230 -0
- agno/db/migrations/manager.py +199 -0
- agno/db/migrations/v1_to_v2.py +635 -0
- agno/db/migrations/versions/v2_3_0.py +938 -0
- agno/db/mongo/__init__.py +17 -0
- agno/db/mongo/async_mongo.py +2760 -0
- agno/db/mongo/mongo.py +2597 -0
- agno/db/mongo/schemas.py +119 -0
- agno/db/mongo/utils.py +276 -0
- agno/db/mysql/__init__.py +4 -0
- agno/db/mysql/async_mysql.py +2912 -0
- agno/db/mysql/mysql.py +2923 -0
- agno/db/mysql/schemas.py +186 -0
- agno/db/mysql/utils.py +488 -0
- agno/db/postgres/__init__.py +4 -0
- agno/db/postgres/async_postgres.py +2579 -0
- agno/db/postgres/postgres.py +2870 -0
- agno/db/postgres/schemas.py +187 -0
- agno/db/postgres/utils.py +442 -0
- agno/db/redis/__init__.py +3 -0
- agno/db/redis/redis.py +2141 -0
- agno/db/redis/schemas.py +159 -0
- agno/db/redis/utils.py +346 -0
- agno/db/schemas/__init__.py +4 -0
- agno/db/schemas/culture.py +120 -0
- agno/db/schemas/evals.py +34 -0
- agno/db/schemas/knowledge.py +40 -0
- agno/db/schemas/memory.py +61 -0
- agno/db/singlestore/__init__.py +3 -0
- agno/db/singlestore/schemas.py +179 -0
- agno/db/singlestore/singlestore.py +2877 -0
- agno/db/singlestore/utils.py +384 -0
- agno/db/sqlite/__init__.py +4 -0
- agno/db/sqlite/async_sqlite.py +2911 -0
- agno/db/sqlite/schemas.py +181 -0
- agno/db/sqlite/sqlite.py +2908 -0
- agno/db/sqlite/utils.py +429 -0
- agno/db/surrealdb/__init__.py +3 -0
- agno/db/surrealdb/metrics.py +292 -0
- agno/db/surrealdb/models.py +334 -0
- agno/db/surrealdb/queries.py +71 -0
- agno/db/surrealdb/surrealdb.py +1908 -0
- agno/db/surrealdb/utils.py +147 -0
- agno/db/utils.py +118 -0
- agno/eval/__init__.py +24 -0
- agno/eval/accuracy.py +666 -276
- agno/eval/agent_as_judge.py +861 -0
- agno/eval/base.py +29 -0
- agno/eval/performance.py +779 -0
- agno/eval/reliability.py +241 -62
- agno/eval/utils.py +120 -0
- agno/exceptions.py +143 -1
- agno/filters.py +354 -0
- agno/guardrails/__init__.py +6 -0
- agno/guardrails/base.py +19 -0
- agno/guardrails/openai.py +144 -0
- agno/guardrails/pii.py +94 -0
- agno/guardrails/prompt_injection.py +52 -0
- agno/hooks/__init__.py +3 -0
- agno/hooks/decorator.py +164 -0
- agno/integrations/discord/__init__.py +3 -0
- agno/integrations/discord/client.py +203 -0
- agno/knowledge/__init__.py +5 -1
- agno/{document → knowledge}/chunking/agentic.py +22 -14
- agno/{document → knowledge}/chunking/document.py +2 -2
- agno/{document → knowledge}/chunking/fixed.py +7 -6
- agno/knowledge/chunking/markdown.py +151 -0
- agno/{document → knowledge}/chunking/recursive.py +15 -3
- agno/knowledge/chunking/row.py +39 -0
- agno/knowledge/chunking/semantic.py +91 -0
- agno/knowledge/chunking/strategy.py +165 -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/knowledge/embedder/aws_bedrock.py +343 -0
- agno/knowledge/embedder/azure_openai.py +210 -0
- agno/{embedder → knowledge/embedder}/base.py +8 -0
- agno/knowledge/embedder/cohere.py +323 -0
- agno/knowledge/embedder/fastembed.py +62 -0
- agno/{embedder → knowledge/embedder}/fireworks.py +1 -1
- agno/knowledge/embedder/google.py +258 -0
- agno/knowledge/embedder/huggingface.py +94 -0
- agno/knowledge/embedder/jina.py +182 -0
- agno/knowledge/embedder/langdb.py +22 -0
- agno/knowledge/embedder/mistral.py +206 -0
- agno/knowledge/embedder/nebius.py +13 -0
- agno/knowledge/embedder/ollama.py +154 -0
- agno/knowledge/embedder/openai.py +195 -0
- agno/knowledge/embedder/sentence_transformer.py +63 -0
- agno/{embedder → knowledge/embedder}/together.py +1 -1
- agno/knowledge/embedder/vllm.py +262 -0
- agno/knowledge/embedder/voyageai.py +165 -0
- agno/knowledge/knowledge.py +3006 -0
- agno/knowledge/reader/__init__.py +7 -0
- agno/knowledge/reader/arxiv_reader.py +81 -0
- agno/knowledge/reader/base.py +95 -0
- agno/knowledge/reader/csv_reader.py +164 -0
- agno/knowledge/reader/docx_reader.py +82 -0
- agno/knowledge/reader/field_labeled_csv_reader.py +290 -0
- agno/knowledge/reader/firecrawl_reader.py +201 -0
- agno/knowledge/reader/json_reader.py +88 -0
- agno/knowledge/reader/markdown_reader.py +137 -0
- agno/knowledge/reader/pdf_reader.py +431 -0
- agno/knowledge/reader/pptx_reader.py +101 -0
- agno/knowledge/reader/reader_factory.py +313 -0
- agno/knowledge/reader/s3_reader.py +89 -0
- agno/knowledge/reader/tavily_reader.py +193 -0
- agno/knowledge/reader/text_reader.py +127 -0
- agno/knowledge/reader/web_search_reader.py +325 -0
- agno/knowledge/reader/website_reader.py +455 -0
- agno/knowledge/reader/wikipedia_reader.py +91 -0
- agno/knowledge/reader/youtube_reader.py +78 -0
- agno/knowledge/remote_content/remote_content.py +88 -0
- agno/knowledge/reranker/__init__.py +3 -0
- agno/{reranker → knowledge/reranker}/base.py +1 -1
- agno/{reranker → knowledge/reranker}/cohere.py +2 -2
- agno/knowledge/reranker/infinity.py +195 -0
- agno/knowledge/reranker/sentence_transformer.py +54 -0
- agno/knowledge/types.py +39 -0
- agno/knowledge/utils.py +234 -0
- agno/media.py +439 -95
- agno/memory/__init__.py +16 -3
- agno/memory/manager.py +1474 -123
- 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/__init__.py +5 -0
- agno/models/aimlapi/aimlapi.py +62 -0
- agno/models/anthropic/__init__.py +4 -0
- agno/models/anthropic/claude.py +960 -496
- agno/models/aws/__init__.py +15 -0
- agno/models/aws/bedrock.py +686 -451
- agno/models/aws/claude.py +190 -183
- agno/models/azure/__init__.py +18 -1
- agno/models/azure/ai_foundry.py +489 -0
- agno/models/azure/openai_chat.py +89 -40
- agno/models/base.py +2477 -550
- agno/models/cerebras/__init__.py +12 -0
- agno/models/cerebras/cerebras.py +565 -0
- agno/models/cerebras/cerebras_openai.py +131 -0
- agno/models/cohere/__init__.py +4 -0
- agno/models/cohere/chat.py +306 -492
- agno/models/cometapi/__init__.py +5 -0
- agno/models/cometapi/cometapi.py +74 -0
- agno/models/dashscope/__init__.py +5 -0
- agno/models/dashscope/dashscope.py +90 -0
- agno/models/deepinfra/__init__.py +5 -0
- agno/models/deepinfra/deepinfra.py +45 -0
- agno/models/deepseek/__init__.py +4 -0
- agno/models/deepseek/deepseek.py +110 -9
- agno/models/fireworks/__init__.py +4 -0
- agno/models/fireworks/fireworks.py +19 -22
- agno/models/google/__init__.py +3 -7
- agno/models/google/gemini.py +1717 -662
- agno/models/google/utils.py +22 -0
- agno/models/groq/__init__.py +4 -0
- agno/models/groq/groq.py +391 -666
- agno/models/huggingface/__init__.py +4 -0
- agno/models/huggingface/huggingface.py +266 -538
- agno/models/ibm/__init__.py +5 -0
- agno/models/ibm/watsonx.py +432 -0
- agno/models/internlm/__init__.py +3 -0
- agno/models/internlm/internlm.py +20 -3
- agno/models/langdb/__init__.py +1 -0
- agno/models/langdb/langdb.py +60 -0
- agno/models/litellm/__init__.py +14 -0
- agno/models/litellm/chat.py +503 -0
- agno/models/litellm/litellm_openai.py +42 -0
- agno/models/llama_cpp/__init__.py +5 -0
- agno/models/llama_cpp/llama_cpp.py +22 -0
- agno/models/lmstudio/__init__.py +5 -0
- agno/models/lmstudio/lmstudio.py +25 -0
- agno/models/message.py +361 -39
- agno/models/meta/__init__.py +12 -0
- agno/models/meta/llama.py +502 -0
- agno/models/meta/llama_openai.py +79 -0
- agno/models/metrics.py +120 -0
- agno/models/mistral/__init__.py +4 -0
- agno/models/mistral/mistral.py +293 -393
- agno/models/nebius/__init__.py +3 -0
- agno/models/nebius/nebius.py +53 -0
- agno/models/nexus/__init__.py +3 -0
- agno/models/nexus/nexus.py +22 -0
- agno/models/nvidia/__init__.py +4 -0
- agno/models/nvidia/nvidia.py +22 -3
- agno/models/ollama/__init__.py +4 -2
- agno/models/ollama/chat.py +257 -492
- agno/models/openai/__init__.py +7 -0
- agno/models/openai/chat.py +725 -770
- agno/models/openai/like.py +16 -2
- agno/models/openai/responses.py +1121 -0
- agno/models/openrouter/__init__.py +4 -0
- agno/models/openrouter/openrouter.py +62 -5
- agno/models/perplexity/__init__.py +5 -0
- agno/models/perplexity/perplexity.py +203 -0
- agno/models/portkey/__init__.py +3 -0
- agno/models/portkey/portkey.py +82 -0
- agno/models/requesty/__init__.py +5 -0
- agno/models/requesty/requesty.py +69 -0
- agno/models/response.py +177 -7
- agno/models/sambanova/__init__.py +4 -0
- agno/models/sambanova/sambanova.py +23 -4
- agno/models/siliconflow/__init__.py +5 -0
- agno/models/siliconflow/siliconflow.py +42 -0
- agno/models/together/__init__.py +4 -0
- agno/models/together/together.py +21 -164
- agno/models/utils.py +266 -0
- agno/models/vercel/__init__.py +3 -0
- agno/models/vercel/v0.py +43 -0
- agno/models/vertexai/__init__.py +0 -1
- agno/models/vertexai/claude.py +190 -0
- agno/models/vllm/__init__.py +3 -0
- agno/models/vllm/vllm.py +83 -0
- agno/models/xai/__init__.py +2 -0
- agno/models/xai/xai.py +111 -7
- agno/os/__init__.py +3 -0
- agno/os/app.py +1027 -0
- agno/os/auth.py +244 -0
- agno/os/config.py +126 -0
- agno/os/interfaces/__init__.py +1 -0
- agno/os/interfaces/a2a/__init__.py +3 -0
- agno/os/interfaces/a2a/a2a.py +42 -0
- agno/os/interfaces/a2a/router.py +249 -0
- agno/os/interfaces/a2a/utils.py +924 -0
- agno/os/interfaces/agui/__init__.py +3 -0
- agno/os/interfaces/agui/agui.py +47 -0
- agno/os/interfaces/agui/router.py +147 -0
- agno/os/interfaces/agui/utils.py +574 -0
- agno/os/interfaces/base.py +25 -0
- agno/os/interfaces/slack/__init__.py +3 -0
- agno/os/interfaces/slack/router.py +148 -0
- agno/os/interfaces/slack/security.py +30 -0
- agno/os/interfaces/slack/slack.py +47 -0
- agno/os/interfaces/whatsapp/__init__.py +3 -0
- agno/os/interfaces/whatsapp/router.py +210 -0
- agno/os/interfaces/whatsapp/security.py +55 -0
- agno/os/interfaces/whatsapp/whatsapp.py +36 -0
- agno/os/mcp.py +293 -0
- agno/os/middleware/__init__.py +9 -0
- agno/os/middleware/jwt.py +797 -0
- agno/os/router.py +258 -0
- agno/os/routers/__init__.py +3 -0
- agno/os/routers/agents/__init__.py +3 -0
- agno/os/routers/agents/router.py +599 -0
- agno/os/routers/agents/schema.py +261 -0
- agno/os/routers/evals/__init__.py +3 -0
- agno/os/routers/evals/evals.py +450 -0
- agno/os/routers/evals/schemas.py +174 -0
- agno/os/routers/evals/utils.py +231 -0
- agno/os/routers/health.py +31 -0
- agno/os/routers/home.py +52 -0
- agno/os/routers/knowledge/__init__.py +3 -0
- agno/os/routers/knowledge/knowledge.py +1008 -0
- agno/os/routers/knowledge/schemas.py +178 -0
- agno/os/routers/memory/__init__.py +3 -0
- agno/os/routers/memory/memory.py +661 -0
- agno/os/routers/memory/schemas.py +88 -0
- agno/os/routers/metrics/__init__.py +3 -0
- agno/os/routers/metrics/metrics.py +190 -0
- agno/os/routers/metrics/schemas.py +47 -0
- agno/os/routers/session/__init__.py +3 -0
- agno/os/routers/session/session.py +997 -0
- agno/os/routers/teams/__init__.py +3 -0
- agno/os/routers/teams/router.py +512 -0
- agno/os/routers/teams/schema.py +257 -0
- agno/os/routers/traces/__init__.py +3 -0
- agno/os/routers/traces/schemas.py +414 -0
- agno/os/routers/traces/traces.py +499 -0
- agno/os/routers/workflows/__init__.py +3 -0
- agno/os/routers/workflows/router.py +624 -0
- agno/os/routers/workflows/schema.py +75 -0
- agno/os/schema.py +534 -0
- agno/os/scopes.py +469 -0
- agno/{playground → os}/settings.py +7 -15
- agno/os/utils.py +973 -0
- agno/reasoning/anthropic.py +80 -0
- agno/reasoning/azure_ai_foundry.py +67 -0
- agno/reasoning/deepseek.py +63 -0
- agno/reasoning/default.py +97 -0
- agno/reasoning/gemini.py +73 -0
- agno/reasoning/groq.py +71 -0
- agno/reasoning/helpers.py +24 -1
- agno/reasoning/ollama.py +67 -0
- agno/reasoning/openai.py +86 -0
- agno/reasoning/step.py +2 -1
- agno/reasoning/vertexai.py +76 -0
- agno/run/__init__.py +6 -0
- agno/run/agent.py +822 -0
- agno/run/base.py +247 -0
- agno/run/cancel.py +81 -0
- agno/run/requirement.py +181 -0
- agno/run/team.py +767 -0
- agno/run/workflow.py +708 -0
- agno/session/__init__.py +10 -0
- agno/session/agent.py +260 -0
- agno/session/summary.py +265 -0
- agno/session/team.py +342 -0
- agno/session/workflow.py +501 -0
- agno/table.py +10 -0
- agno/team/__init__.py +37 -0
- agno/team/team.py +9536 -0
- agno/tools/__init__.py +7 -0
- agno/tools/agentql.py +120 -0
- agno/tools/airflow.py +22 -12
- agno/tools/api.py +122 -0
- agno/tools/apify.py +276 -83
- agno/tools/{arxiv_toolkit.py → arxiv.py} +20 -12
- agno/tools/aws_lambda.py +28 -7
- agno/tools/aws_ses.py +66 -0
- agno/tools/baidusearch.py +11 -4
- agno/tools/bitbucket.py +292 -0
- agno/tools/brandfetch.py +213 -0
- agno/tools/bravesearch.py +106 -0
- agno/tools/brightdata.py +367 -0
- agno/tools/browserbase.py +209 -0
- agno/tools/calcom.py +32 -23
- agno/tools/calculator.py +24 -37
- agno/tools/cartesia.py +187 -0
- agno/tools/{clickup_tool.py → clickup.py} +17 -28
- agno/tools/confluence.py +91 -26
- agno/tools/crawl4ai.py +139 -43
- agno/tools/csv_toolkit.py +28 -22
- agno/tools/dalle.py +36 -22
- agno/tools/daytona.py +475 -0
- agno/tools/decorator.py +169 -14
- agno/tools/desi_vocal.py +23 -11
- agno/tools/discord.py +32 -29
- agno/tools/docker.py +716 -0
- agno/tools/duckdb.py +76 -81
- agno/tools/duckduckgo.py +43 -40
- agno/tools/e2b.py +703 -0
- agno/tools/eleven_labs.py +65 -54
- agno/tools/email.py +13 -5
- agno/tools/evm.py +129 -0
- agno/tools/exa.py +324 -42
- agno/tools/fal.py +39 -35
- agno/tools/file.py +196 -30
- agno/tools/file_generation.py +356 -0
- agno/tools/financial_datasets.py +288 -0
- agno/tools/firecrawl.py +108 -33
- agno/tools/function.py +960 -122
- agno/tools/giphy.py +34 -12
- agno/tools/github.py +1294 -97
- agno/tools/gmail.py +922 -0
- agno/tools/google_bigquery.py +117 -0
- agno/tools/google_drive.py +271 -0
- agno/tools/google_maps.py +253 -0
- agno/tools/googlecalendar.py +607 -107
- agno/tools/googlesheets.py +377 -0
- agno/tools/hackernews.py +20 -12
- agno/tools/jina.py +24 -14
- agno/tools/jira.py +48 -19
- agno/tools/knowledge.py +218 -0
- agno/tools/linear.py +82 -43
- agno/tools/linkup.py +58 -0
- agno/tools/local_file_system.py +15 -7
- agno/tools/lumalab.py +41 -26
- agno/tools/mcp/__init__.py +10 -0
- agno/tools/mcp/mcp.py +331 -0
- agno/tools/mcp/multi_mcp.py +347 -0
- agno/tools/mcp/params.py +24 -0
- agno/tools/mcp_toolbox.py +284 -0
- agno/tools/mem0.py +193 -0
- agno/tools/memory.py +419 -0
- agno/tools/mlx_transcribe.py +11 -9
- agno/tools/models/azure_openai.py +190 -0
- agno/tools/models/gemini.py +203 -0
- agno/tools/models/groq.py +158 -0
- agno/tools/models/morph.py +186 -0
- agno/tools/models/nebius.py +124 -0
- agno/tools/models_labs.py +163 -82
- agno/tools/moviepy_video.py +18 -13
- agno/tools/nano_banana.py +151 -0
- agno/tools/neo4j.py +134 -0
- agno/tools/newspaper.py +15 -4
- agno/tools/newspaper4k.py +19 -6
- agno/tools/notion.py +204 -0
- agno/tools/openai.py +181 -17
- agno/tools/openbb.py +27 -20
- agno/tools/opencv.py +321 -0
- agno/tools/openweather.py +233 -0
- agno/tools/oxylabs.py +385 -0
- agno/tools/pandas.py +25 -15
- agno/tools/parallel.py +314 -0
- agno/tools/postgres.py +238 -185
- agno/tools/pubmed.py +125 -13
- agno/tools/python.py +48 -35
- agno/tools/reasoning.py +283 -0
- agno/tools/reddit.py +207 -29
- agno/tools/redshift.py +406 -0
- agno/tools/replicate.py +69 -26
- agno/tools/resend.py +11 -6
- agno/tools/scrapegraph.py +179 -19
- agno/tools/searxng.py +23 -31
- agno/tools/serpapi.py +15 -10
- agno/tools/serper.py +255 -0
- agno/tools/shell.py +23 -12
- agno/tools/shopify.py +1519 -0
- agno/tools/slack.py +56 -14
- agno/tools/sleep.py +8 -6
- agno/tools/spider.py +35 -11
- agno/tools/spotify.py +919 -0
- agno/tools/sql.py +34 -19
- agno/tools/tavily.py +158 -8
- agno/tools/telegram.py +18 -8
- agno/tools/todoist.py +218 -0
- agno/tools/toolkit.py +134 -9
- agno/tools/trafilatura.py +388 -0
- agno/tools/trello.py +25 -28
- agno/tools/twilio.py +18 -9
- agno/tools/user_control_flow.py +78 -0
- agno/tools/valyu.py +228 -0
- agno/tools/visualization.py +467 -0
- agno/tools/webbrowser.py +28 -0
- agno/tools/webex.py +76 -0
- agno/tools/website.py +23 -19
- agno/tools/webtools.py +45 -0
- agno/tools/whatsapp.py +286 -0
- agno/tools/wikipedia.py +28 -19
- agno/tools/workflow.py +285 -0
- agno/tools/{twitter.py → x.py} +142 -46
- agno/tools/yfinance.py +41 -39
- agno/tools/youtube.py +34 -17
- agno/tools/zendesk.py +15 -5
- agno/tools/zep.py +454 -0
- agno/tools/zoom.py +86 -37
- agno/tracing/__init__.py +12 -0
- agno/tracing/exporter.py +157 -0
- agno/tracing/schemas.py +276 -0
- agno/tracing/setup.py +111 -0
- agno/utils/agent.py +938 -0
- agno/utils/audio.py +37 -1
- agno/utils/certs.py +27 -0
- agno/utils/code_execution.py +11 -0
- agno/utils/common.py +103 -20
- agno/utils/cryptography.py +22 -0
- agno/utils/dttm.py +33 -0
- agno/utils/events.py +700 -0
- agno/utils/functions.py +107 -37
- agno/utils/gemini.py +426 -0
- agno/utils/hooks.py +171 -0
- agno/utils/http.py +185 -0
- agno/utils/json_schema.py +159 -37
- agno/utils/knowledge.py +36 -0
- agno/utils/location.py +19 -0
- agno/utils/log.py +221 -8
- agno/utils/mcp.py +214 -0
- agno/utils/media.py +335 -14
- agno/utils/merge_dict.py +22 -1
- agno/utils/message.py +77 -2
- agno/utils/models/ai_foundry.py +50 -0
- agno/utils/models/claude.py +373 -0
- agno/utils/models/cohere.py +94 -0
- agno/utils/models/llama.py +85 -0
- agno/utils/models/mistral.py +100 -0
- agno/utils/models/openai_responses.py +140 -0
- agno/utils/models/schema_utils.py +153 -0
- agno/utils/models/watsonx.py +41 -0
- agno/utils/openai.py +257 -0
- agno/utils/pickle.py +1 -1
- agno/utils/pprint.py +124 -8
- agno/utils/print_response/agent.py +930 -0
- agno/utils/print_response/team.py +1914 -0
- agno/utils/print_response/workflow.py +1668 -0
- agno/utils/prompts.py +111 -0
- agno/utils/reasoning.py +108 -0
- agno/utils/response.py +163 -0
- agno/utils/serialize.py +32 -0
- agno/utils/shell.py +4 -4
- agno/utils/streamlit.py +487 -0
- agno/utils/string.py +204 -51
- agno/utils/team.py +139 -0
- agno/utils/timer.py +9 -2
- agno/utils/tokens.py +657 -0
- agno/utils/tools.py +19 -1
- agno/utils/whatsapp.py +305 -0
- agno/utils/yaml_io.py +3 -3
- agno/vectordb/__init__.py +2 -0
- agno/vectordb/base.py +87 -9
- agno/vectordb/cassandra/__init__.py +5 -1
- agno/vectordb/cassandra/cassandra.py +383 -27
- agno/vectordb/chroma/__init__.py +4 -0
- agno/vectordb/chroma/chromadb.py +748 -83
- agno/vectordb/clickhouse/__init__.py +7 -1
- agno/vectordb/clickhouse/clickhousedb.py +554 -53
- agno/vectordb/couchbase/__init__.py +3 -0
- agno/vectordb/couchbase/couchbase.py +1446 -0
- agno/vectordb/lancedb/__init__.py +5 -0
- agno/vectordb/lancedb/lance_db.py +730 -98
- agno/vectordb/langchaindb/__init__.py +5 -0
- agno/vectordb/langchaindb/langchaindb.py +163 -0
- agno/vectordb/lightrag/__init__.py +5 -0
- agno/vectordb/lightrag/lightrag.py +388 -0
- agno/vectordb/llamaindex/__init__.py +3 -0
- agno/vectordb/llamaindex/llamaindexdb.py +166 -0
- agno/vectordb/milvus/__init__.py +3 -0
- agno/vectordb/milvus/milvus.py +966 -78
- agno/vectordb/mongodb/__init__.py +9 -1
- agno/vectordb/mongodb/mongodb.py +1175 -172
- agno/vectordb/pgvector/__init__.py +8 -0
- agno/vectordb/pgvector/pgvector.py +599 -115
- agno/vectordb/pineconedb/__init__.py +5 -1
- agno/vectordb/pineconedb/pineconedb.py +406 -43
- agno/vectordb/qdrant/__init__.py +4 -0
- agno/vectordb/qdrant/qdrant.py +914 -61
- agno/vectordb/redis/__init__.py +9 -0
- agno/vectordb/redis/redisdb.py +682 -0
- agno/vectordb/singlestore/__init__.py +8 -1
- agno/vectordb/singlestore/singlestore.py +771 -0
- agno/vectordb/surrealdb/__init__.py +3 -0
- agno/vectordb/surrealdb/surrealdb.py +663 -0
- agno/vectordb/upstashdb/__init__.py +5 -0
- agno/vectordb/upstashdb/upstashdb.py +718 -0
- agno/vectordb/weaviate/__init__.py +8 -0
- agno/vectordb/weaviate/index.py +15 -0
- agno/vectordb/weaviate/weaviate.py +1009 -0
- agno/workflow/__init__.py +23 -1
- agno/workflow/agent.py +299 -0
- agno/workflow/condition.py +759 -0
- agno/workflow/loop.py +756 -0
- agno/workflow/parallel.py +853 -0
- agno/workflow/router.py +723 -0
- agno/workflow/step.py +1564 -0
- agno/workflow/steps.py +613 -0
- agno/workflow/types.py +556 -0
- agno/workflow/workflow.py +4327 -514
- agno-2.3.13.dist-info/METADATA +639 -0
- agno-2.3.13.dist-info/RECORD +613 -0
- {agno-0.1.2.dist-info → agno-2.3.13.dist-info}/WHEEL +1 -1
- agno-2.3.13.dist-info/licenses/LICENSE +201 -0
- agno/api/playground.py +0 -91
- agno/api/schemas/playground.py +0 -22
- agno/api/schemas/user.py +0 -22
- agno/api/schemas/workspace.py +0 -46
- agno/api/user.py +0 -160
- agno/api/workspace.py +0 -151
- agno/cli/auth_server.py +0 -118
- agno/cli/config.py +0 -275
- agno/cli/console.py +0 -88
- agno/cli/credentials.py +0 -23
- agno/cli/entrypoint.py +0 -571
- agno/cli/operator.py +0 -355
- agno/cli/settings.py +0 -85
- agno/cli/ws/ws_cli.py +0 -817
- agno/constants.py +0 -13
- agno/document/__init__.py +0 -1
- agno/document/chunking/semantic.py +0 -47
- agno/document/chunking/strategy.py +0 -31
- agno/document/reader/__init__.py +0 -1
- agno/document/reader/arxiv_reader.py +0 -41
- agno/document/reader/base.py +0 -22
- agno/document/reader/csv_reader.py +0 -84
- agno/document/reader/docx_reader.py +0 -46
- agno/document/reader/firecrawl_reader.py +0 -99
- agno/document/reader/json_reader.py +0 -43
- agno/document/reader/pdf_reader.py +0 -219
- agno/document/reader/s3/pdf_reader.py +0 -46
- agno/document/reader/s3/text_reader.py +0 -51
- agno/document/reader/text_reader.py +0 -41
- agno/document/reader/website_reader.py +0 -175
- agno/document/reader/youtube_reader.py +0 -50
- agno/embedder/__init__.py +0 -1
- agno/embedder/azure_openai.py +0 -86
- agno/embedder/cohere.py +0 -72
- agno/embedder/fastembed.py +0 -37
- agno/embedder/google.py +0 -73
- agno/embedder/huggingface.py +0 -54
- agno/embedder/mistral.py +0 -80
- agno/embedder/ollama.py +0 -57
- agno/embedder/openai.py +0 -74
- agno/embedder/sentence_transformer.py +0 -38
- agno/embedder/voyageai.py +0 -64
- agno/eval/perf.py +0 -201
- agno/file/__init__.py +0 -1
- 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 -230
- agno/knowledge/arxiv.py +0 -22
- agno/knowledge/combined.py +0 -22
- agno/knowledge/csv.py +0 -28
- agno/knowledge/csv_url.py +0 -19
- agno/knowledge/document.py +0 -20
- agno/knowledge/docx.py +0 -30
- agno/knowledge/json.py +0 -28
- agno/knowledge/langchain.py +0 -71
- agno/knowledge/llamaindex.py +0 -66
- agno/knowledge/pdf.py +0 -28
- agno/knowledge/pdf_url.py +0 -26
- agno/knowledge/s3/base.py +0 -60
- agno/knowledge/s3/pdf.py +0 -21
- agno/knowledge/s3/text.py +0 -23
- agno/knowledge/text.py +0 -30
- agno/knowledge/website.py +0 -88
- agno/knowledge/wikipedia.py +0 -31
- agno/knowledge/youtube.py +0 -22
- agno/memory/agent.py +0 -392
- agno/memory/classifier.py +0 -104
- agno/memory/db/__init__.py +0 -1
- 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 -15
- agno/memory/row.py +0 -36
- agno/memory/summarizer.py +0 -192
- agno/memory/summary.py +0 -19
- agno/memory/workflow.py +0 -38
- agno/models/google/gemini_openai.py +0 -26
- agno/models/ollama/hermes.py +0 -221
- agno/models/ollama/tools.py +0 -362
- agno/models/vertexai/gemini.py +0 -595
- agno/playground/__init__.py +0 -3
- agno/playground/async_router.py +0 -421
- agno/playground/deploy.py +0 -249
- agno/playground/operator.py +0 -92
- agno/playground/playground.py +0 -91
- agno/playground/schemas.py +0 -76
- agno/playground/serve.py +0 -55
- agno/playground/sync_router.py +0 -405
- agno/reasoning/agent.py +0 -68
- agno/run/response.py +0 -112
- agno/storage/agent/__init__.py +0 -0
- agno/storage/agent/base.py +0 -38
- agno/storage/agent/dynamodb.py +0 -350
- agno/storage/agent/json.py +0 -92
- agno/storage/agent/mongodb.py +0 -228
- agno/storage/agent/postgres.py +0 -367
- agno/storage/agent/session.py +0 -79
- agno/storage/agent/singlestore.py +0 -303
- agno/storage/agent/sqlite.py +0 -357
- agno/storage/agent/yaml.py +0 -93
- agno/storage/workflow/__init__.py +0 -0
- agno/storage/workflow/base.py +0 -40
- agno/storage/workflow/mongodb.py +0 -233
- agno/storage/workflow/postgres.py +0 -366
- agno/storage/workflow/session.py +0 -60
- agno/storage/workflow/sqlite.py +0 -359
- agno/tools/googlesearch.py +0 -88
- 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/vectordb/singlestore/s2vectordb.py +0 -390
- agno/vectordb/singlestore/s2vectordb2.py +0 -355
- agno/workspace/__init__.py +0 -0
- agno/workspace/config.py +0 -325
- agno/workspace/enums.py +0 -6
- agno/workspace/helpers.py +0 -48
- agno/workspace/operator.py +0 -758
- agno/workspace/settings.py +0 -63
- agno-0.1.2.dist-info/LICENSE +0 -375
- agno-0.1.2.dist-info/METADATA +0 -502
- agno-0.1.2.dist-info/RECORD +0 -352
- agno-0.1.2.dist-info/entry_points.txt +0 -3
- /agno/{cli → db/migrations}/__init__.py +0 -0
- /agno/{cli/ws → db/migrations/versions}/__init__.py +0 -0
- /agno/{document/chunking/__init__.py → db/schemas/metrics.py} +0 -0
- /agno/{document/reader/s3 → integrations}/__init__.py +0 -0
- /agno/{file/local → knowledge/chunking}/__init__.py +0 -0
- /agno/{infra → knowledge/remote_content}/__init__.py +0 -0
- /agno/{knowledge/s3 → tools/models}/__init__.py +0 -0
- /agno/{reranker → utils/models}/__init__.py +0 -0
- /agno/{storage → utils/print_response}/__init__.py +0 -0
- {agno-0.1.2.dist-info → agno-2.3.13.dist-info}/top_level.txt +0 -0
agno/workflow/steps.py
ADDED
|
@@ -0,0 +1,613 @@
|
|
|
1
|
+
import warnings
|
|
2
|
+
from dataclasses import dataclass
|
|
3
|
+
from typing import Any, AsyncIterator, Awaitable, Callable, Dict, Iterator, List, Optional, Union
|
|
4
|
+
from uuid import uuid4
|
|
5
|
+
|
|
6
|
+
from agno.run.agent import RunOutputEvent
|
|
7
|
+
from agno.run.base import RunContext
|
|
8
|
+
from agno.run.team import TeamRunOutputEvent
|
|
9
|
+
from agno.run.workflow import (
|
|
10
|
+
StepsExecutionCompletedEvent,
|
|
11
|
+
StepsExecutionStartedEvent,
|
|
12
|
+
WorkflowRunOutput,
|
|
13
|
+
WorkflowRunOutputEvent,
|
|
14
|
+
)
|
|
15
|
+
from agno.session.workflow import WorkflowSession
|
|
16
|
+
from agno.utils.log import log_debug, logger
|
|
17
|
+
from agno.workflow.step import Step, StepInput, StepOutput, StepType
|
|
18
|
+
|
|
19
|
+
WorkflowSteps = List[
|
|
20
|
+
Union[
|
|
21
|
+
Callable[
|
|
22
|
+
[StepInput], Union[StepOutput, Awaitable[StepOutput], Iterator[StepOutput], AsyncIterator[StepOutput]]
|
|
23
|
+
],
|
|
24
|
+
Step,
|
|
25
|
+
"Steps", # type: ignore # noqa: F821
|
|
26
|
+
"Loop", # type: ignore # noqa: F821
|
|
27
|
+
"Parallel", # type: ignore # noqa: F821
|
|
28
|
+
"Condition", # type: ignore # noqa: F821
|
|
29
|
+
"Router", # type: ignore # noqa: F821
|
|
30
|
+
]
|
|
31
|
+
]
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
@dataclass
|
|
35
|
+
class Steps:
|
|
36
|
+
"""A pipeline of steps that execute in order"""
|
|
37
|
+
|
|
38
|
+
# Steps to execute
|
|
39
|
+
steps: WorkflowSteps
|
|
40
|
+
|
|
41
|
+
# Pipeline identification
|
|
42
|
+
name: Optional[str] = None
|
|
43
|
+
description: Optional[str] = None
|
|
44
|
+
|
|
45
|
+
def __init__(
|
|
46
|
+
self, name: Optional[str] = None, description: Optional[str] = None, steps: Optional[List[Any]] = None
|
|
47
|
+
): # Change to List[Any]
|
|
48
|
+
self.name = name
|
|
49
|
+
self.description = description
|
|
50
|
+
self.steps = steps if steps else []
|
|
51
|
+
|
|
52
|
+
def _prepare_steps(self):
|
|
53
|
+
"""Prepare the steps for execution - mirrors workflow logic"""
|
|
54
|
+
from agno.agent.agent import Agent
|
|
55
|
+
from agno.team.team import Team
|
|
56
|
+
from agno.workflow.condition import Condition
|
|
57
|
+
from agno.workflow.loop import Loop
|
|
58
|
+
from agno.workflow.parallel import Parallel
|
|
59
|
+
from agno.workflow.router import Router
|
|
60
|
+
from agno.workflow.step import Step
|
|
61
|
+
|
|
62
|
+
prepared_steps: WorkflowSteps = []
|
|
63
|
+
for step in self.steps:
|
|
64
|
+
if callable(step) and hasattr(step, "__name__"):
|
|
65
|
+
prepared_steps.append(Step(name=step.__name__, description="User-defined callable step", executor=step))
|
|
66
|
+
elif isinstance(step, Agent):
|
|
67
|
+
prepared_steps.append(Step(name=step.name, description=step.description, agent=step))
|
|
68
|
+
elif isinstance(step, Team):
|
|
69
|
+
prepared_steps.append(Step(name=step.name, description=step.description, team=step))
|
|
70
|
+
elif isinstance(step, (Step, Steps, Loop, Parallel, Condition, Router)):
|
|
71
|
+
prepared_steps.append(step)
|
|
72
|
+
else:
|
|
73
|
+
raise ValueError(f"Invalid step type: {type(step).__name__}")
|
|
74
|
+
|
|
75
|
+
self.steps = prepared_steps
|
|
76
|
+
|
|
77
|
+
def _update_step_input_from_outputs(
|
|
78
|
+
self,
|
|
79
|
+
step_input: StepInput,
|
|
80
|
+
step_outputs: Union[StepOutput, List[StepOutput]],
|
|
81
|
+
steps_step_outputs: Optional[Dict[str, StepOutput]] = None,
|
|
82
|
+
) -> StepInput:
|
|
83
|
+
"""Helper to update step input from step outputs - mirrors Condition/Router logic"""
|
|
84
|
+
current_images = step_input.images or []
|
|
85
|
+
current_videos = step_input.videos or []
|
|
86
|
+
current_audio = step_input.audio or []
|
|
87
|
+
|
|
88
|
+
if isinstance(step_outputs, list):
|
|
89
|
+
step_images = sum([out.images or [] for out in step_outputs], [])
|
|
90
|
+
step_videos = sum([out.videos or [] for out in step_outputs], [])
|
|
91
|
+
step_audio = sum([out.audio or [] for out in step_outputs], [])
|
|
92
|
+
# Use the last output's content for chaining
|
|
93
|
+
previous_step_content = step_outputs[-1].content if step_outputs else None
|
|
94
|
+
else:
|
|
95
|
+
# Single output
|
|
96
|
+
step_images = step_outputs.images or []
|
|
97
|
+
step_videos = step_outputs.videos or []
|
|
98
|
+
step_audio = step_outputs.audio or []
|
|
99
|
+
previous_step_content = step_outputs.content
|
|
100
|
+
|
|
101
|
+
updated_previous_step_outputs = {}
|
|
102
|
+
if step_input.previous_step_outputs:
|
|
103
|
+
updated_previous_step_outputs.update(step_input.previous_step_outputs)
|
|
104
|
+
if steps_step_outputs:
|
|
105
|
+
updated_previous_step_outputs.update(steps_step_outputs)
|
|
106
|
+
|
|
107
|
+
return StepInput(
|
|
108
|
+
input=step_input.input,
|
|
109
|
+
previous_step_content=previous_step_content,
|
|
110
|
+
previous_step_outputs=updated_previous_step_outputs,
|
|
111
|
+
additional_data=step_input.additional_data,
|
|
112
|
+
images=current_images + step_images,
|
|
113
|
+
videos=current_videos + step_videos,
|
|
114
|
+
audio=current_audio + step_audio,
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
def execute(
|
|
118
|
+
self,
|
|
119
|
+
step_input: StepInput,
|
|
120
|
+
session_id: Optional[str] = None,
|
|
121
|
+
user_id: Optional[str] = None,
|
|
122
|
+
workflow_run_response: Optional[WorkflowRunOutput] = None,
|
|
123
|
+
run_context: Optional[RunContext] = None,
|
|
124
|
+
session_state: Optional[Dict[str, Any]] = None,
|
|
125
|
+
store_executor_outputs: bool = True,
|
|
126
|
+
workflow_session: Optional[WorkflowSession] = None,
|
|
127
|
+
add_workflow_history_to_steps: Optional[bool] = False,
|
|
128
|
+
num_history_runs: int = 3,
|
|
129
|
+
background_tasks: Optional[Any] = None,
|
|
130
|
+
) -> StepOutput:
|
|
131
|
+
"""Execute all steps in sequence and return the final result"""
|
|
132
|
+
log_debug(f"Steps Start: {self.name} ({len(self.steps)} steps)", center=True, symbol="-")
|
|
133
|
+
|
|
134
|
+
steps_id = str(uuid4())
|
|
135
|
+
|
|
136
|
+
self._prepare_steps()
|
|
137
|
+
|
|
138
|
+
if not self.steps:
|
|
139
|
+
return StepOutput(step_name=self.name or "Steps", content="No steps to execute")
|
|
140
|
+
|
|
141
|
+
# Track outputs and pass data between steps - following Condition/Router pattern
|
|
142
|
+
all_results: List[StepOutput] = []
|
|
143
|
+
current_step_input = step_input
|
|
144
|
+
steps_step_outputs = {}
|
|
145
|
+
|
|
146
|
+
try:
|
|
147
|
+
for i, step in enumerate(self.steps):
|
|
148
|
+
step_name = getattr(step, "name", f"step_{i + 1}")
|
|
149
|
+
log_debug(f"Steps {self.name}: Executing step {i + 1}/{len(self.steps)} - {step_name}")
|
|
150
|
+
|
|
151
|
+
# Execute step
|
|
152
|
+
step_output = step.execute( # type: ignore
|
|
153
|
+
current_step_input,
|
|
154
|
+
session_id=session_id,
|
|
155
|
+
user_id=user_id,
|
|
156
|
+
workflow_run_response=workflow_run_response,
|
|
157
|
+
store_executor_outputs=store_executor_outputs,
|
|
158
|
+
run_context=run_context,
|
|
159
|
+
session_state=session_state,
|
|
160
|
+
workflow_session=workflow_session,
|
|
161
|
+
add_workflow_history_to_steps=add_workflow_history_to_steps,
|
|
162
|
+
num_history_runs=num_history_runs,
|
|
163
|
+
background_tasks=background_tasks,
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
# Handle both single StepOutput and List[StepOutput] (from Loop/Condition/Router steps)
|
|
167
|
+
if isinstance(step_output, list):
|
|
168
|
+
all_results.extend(step_output)
|
|
169
|
+
if step_output:
|
|
170
|
+
steps_step_outputs[step_name] = step_output[-1]
|
|
171
|
+
|
|
172
|
+
if any(output.stop for output in step_output):
|
|
173
|
+
logger.info(f"Early termination requested by step {step_name}")
|
|
174
|
+
break
|
|
175
|
+
else:
|
|
176
|
+
all_results.append(step_output)
|
|
177
|
+
steps_step_outputs[step_name] = step_output
|
|
178
|
+
|
|
179
|
+
if step_output.stop:
|
|
180
|
+
logger.info(f"Early termination requested by step {step_name}")
|
|
181
|
+
break
|
|
182
|
+
log_debug(f"Steps {self.name}: Step {step_name} completed successfully")
|
|
183
|
+
|
|
184
|
+
# Update input for next step with proper chaining
|
|
185
|
+
current_step_input = self._update_step_input_from_outputs(
|
|
186
|
+
current_step_input, step_output, steps_step_outputs
|
|
187
|
+
)
|
|
188
|
+
|
|
189
|
+
log_debug(f"Steps End: {self.name} ({len(all_results)} results)", center=True, symbol="-")
|
|
190
|
+
|
|
191
|
+
return StepOutput(
|
|
192
|
+
step_name=self.name,
|
|
193
|
+
step_id=steps_id,
|
|
194
|
+
step_type=StepType.STEPS,
|
|
195
|
+
content=f"Steps {self.name} completed with {len(all_results)} results",
|
|
196
|
+
success=all(result.success for result in all_results) if all_results else True,
|
|
197
|
+
steps=all_results,
|
|
198
|
+
)
|
|
199
|
+
|
|
200
|
+
except Exception as e:
|
|
201
|
+
logger.error(f"Steps execution failed: {e}")
|
|
202
|
+
return StepOutput(
|
|
203
|
+
step_name=self.name or "Steps",
|
|
204
|
+
content=f"Steps execution failed: {str(e)}",
|
|
205
|
+
success=False,
|
|
206
|
+
error=str(e),
|
|
207
|
+
)
|
|
208
|
+
|
|
209
|
+
def execute_stream(
|
|
210
|
+
self,
|
|
211
|
+
step_input: StepInput,
|
|
212
|
+
workflow_run_response: WorkflowRunOutput,
|
|
213
|
+
run_context: Optional[RunContext] = None,
|
|
214
|
+
session_state: Optional[Dict[str, Any]] = None,
|
|
215
|
+
session_id: Optional[str] = None,
|
|
216
|
+
user_id: Optional[str] = None,
|
|
217
|
+
stream_events: bool = False,
|
|
218
|
+
stream_intermediate_steps: bool = False,
|
|
219
|
+
stream_executor_events: bool = True,
|
|
220
|
+
step_index: Optional[Union[int, tuple]] = None,
|
|
221
|
+
store_executor_outputs: bool = True,
|
|
222
|
+
parent_step_id: Optional[str] = None,
|
|
223
|
+
workflow_session: Optional[WorkflowSession] = None,
|
|
224
|
+
add_workflow_history_to_steps: Optional[bool] = False,
|
|
225
|
+
num_history_runs: int = 3,
|
|
226
|
+
background_tasks: Optional[Any] = None,
|
|
227
|
+
) -> Iterator[Union[WorkflowRunOutputEvent, TeamRunOutputEvent, RunOutputEvent, StepOutput]]:
|
|
228
|
+
"""Execute all steps in sequence with streaming support"""
|
|
229
|
+
log_debug(f"Steps Start: {self.name} ({len(self.steps)} steps)", center=True, symbol="-")
|
|
230
|
+
|
|
231
|
+
steps_id = str(uuid4())
|
|
232
|
+
|
|
233
|
+
self._prepare_steps()
|
|
234
|
+
|
|
235
|
+
# Considering both stream_events and stream_intermediate_steps (deprecated)
|
|
236
|
+
if stream_intermediate_steps is not None:
|
|
237
|
+
warnings.warn(
|
|
238
|
+
"The 'stream_intermediate_steps' parameter is deprecated and will be removed in future versions. Use 'stream_events' instead.",
|
|
239
|
+
DeprecationWarning,
|
|
240
|
+
stacklevel=2,
|
|
241
|
+
)
|
|
242
|
+
stream_events = stream_events or stream_intermediate_steps
|
|
243
|
+
|
|
244
|
+
if stream_events:
|
|
245
|
+
# Yield steps execution started event
|
|
246
|
+
yield StepsExecutionStartedEvent(
|
|
247
|
+
run_id=workflow_run_response.run_id or "",
|
|
248
|
+
workflow_name=workflow_run_response.workflow_name or "",
|
|
249
|
+
workflow_id=workflow_run_response.workflow_id or "",
|
|
250
|
+
session_id=workflow_run_response.session_id or "",
|
|
251
|
+
step_name=self.name,
|
|
252
|
+
step_index=step_index,
|
|
253
|
+
steps_count=len(self.steps),
|
|
254
|
+
step_id=steps_id,
|
|
255
|
+
parent_step_id=parent_step_id,
|
|
256
|
+
)
|
|
257
|
+
|
|
258
|
+
if not self.steps:
|
|
259
|
+
yield StepOutput(step_name=self.name or "Steps", content="No steps to execute")
|
|
260
|
+
return
|
|
261
|
+
|
|
262
|
+
# Track outputs and pass data between steps - following Condition/Router pattern
|
|
263
|
+
all_results = []
|
|
264
|
+
current_step_input = step_input
|
|
265
|
+
steps_step_outputs = {}
|
|
266
|
+
|
|
267
|
+
try:
|
|
268
|
+
for i, step in enumerate(self.steps):
|
|
269
|
+
step_name = getattr(step, "name", f"step_{i + 1}")
|
|
270
|
+
log_debug(f"Steps {self.name}: Executing step {i + 1}/{len(self.steps)} - {step_name}")
|
|
271
|
+
|
|
272
|
+
step_outputs_for_step = []
|
|
273
|
+
|
|
274
|
+
if step_index is None or isinstance(step_index, int):
|
|
275
|
+
# Steps is a main step - child steps get x.1, x.2, x.3 format
|
|
276
|
+
child_step_index = (step_index if step_index is not None else 1, i) # Use i, not i+1
|
|
277
|
+
else:
|
|
278
|
+
# Steps is already a child step - child steps get parent.1, parent.2, parent.3
|
|
279
|
+
child_step_index = step_index + (i,) # Extend the tuple
|
|
280
|
+
|
|
281
|
+
# Stream step execution
|
|
282
|
+
for event in step.execute_stream( # type: ignore
|
|
283
|
+
current_step_input,
|
|
284
|
+
session_id=session_id,
|
|
285
|
+
user_id=user_id,
|
|
286
|
+
run_context=run_context,
|
|
287
|
+
session_state=session_state,
|
|
288
|
+
stream_events=stream_events,
|
|
289
|
+
stream_executor_events=stream_executor_events,
|
|
290
|
+
workflow_run_response=workflow_run_response,
|
|
291
|
+
step_index=child_step_index,
|
|
292
|
+
store_executor_outputs=store_executor_outputs,
|
|
293
|
+
parent_step_id=steps_id,
|
|
294
|
+
workflow_session=workflow_session,
|
|
295
|
+
add_workflow_history_to_steps=add_workflow_history_to_steps,
|
|
296
|
+
num_history_runs=num_history_runs,
|
|
297
|
+
background_tasks=background_tasks,
|
|
298
|
+
):
|
|
299
|
+
if isinstance(event, StepOutput):
|
|
300
|
+
step_outputs_for_step.append(event)
|
|
301
|
+
all_results.append(event)
|
|
302
|
+
else:
|
|
303
|
+
# Yield other events (streaming content, step events, etc.)
|
|
304
|
+
yield event
|
|
305
|
+
|
|
306
|
+
# Update step outputs tracking and prepare input for next step
|
|
307
|
+
if step_outputs_for_step:
|
|
308
|
+
if len(step_outputs_for_step) == 1:
|
|
309
|
+
steps_step_outputs[step_name] = step_outputs_for_step[0]
|
|
310
|
+
|
|
311
|
+
if step_outputs_for_step[0].stop:
|
|
312
|
+
logger.info(f"Early termination requested by step {step_name}")
|
|
313
|
+
break
|
|
314
|
+
|
|
315
|
+
current_step_input = self._update_step_input_from_outputs(
|
|
316
|
+
current_step_input, step_outputs_for_step[0], steps_step_outputs
|
|
317
|
+
)
|
|
318
|
+
else:
|
|
319
|
+
# Use last output
|
|
320
|
+
steps_step_outputs[step_name] = step_outputs_for_step[-1]
|
|
321
|
+
|
|
322
|
+
if any(output.stop for output in step_outputs_for_step):
|
|
323
|
+
logger.info(f"Early termination requested by step {step_name}")
|
|
324
|
+
break
|
|
325
|
+
|
|
326
|
+
current_step_input = self._update_step_input_from_outputs(
|
|
327
|
+
current_step_input, step_outputs_for_step, steps_step_outputs
|
|
328
|
+
)
|
|
329
|
+
|
|
330
|
+
log_debug(f"Steps End: {self.name} ({len(all_results)} results)", center=True, symbol="-")
|
|
331
|
+
|
|
332
|
+
if stream_events:
|
|
333
|
+
# Yield steps execution completed event
|
|
334
|
+
yield StepsExecutionCompletedEvent(
|
|
335
|
+
run_id=workflow_run_response.run_id or "",
|
|
336
|
+
workflow_name=workflow_run_response.workflow_name or "",
|
|
337
|
+
workflow_id=workflow_run_response.workflow_id or "",
|
|
338
|
+
session_id=workflow_run_response.session_id or "",
|
|
339
|
+
step_name=self.name,
|
|
340
|
+
step_index=step_index,
|
|
341
|
+
steps_count=len(self.steps),
|
|
342
|
+
executed_steps=len(all_results),
|
|
343
|
+
step_results=all_results,
|
|
344
|
+
step_id=steps_id,
|
|
345
|
+
parent_step_id=parent_step_id,
|
|
346
|
+
)
|
|
347
|
+
|
|
348
|
+
yield StepOutput(
|
|
349
|
+
step_name=self.name,
|
|
350
|
+
step_id=steps_id,
|
|
351
|
+
step_type=StepType.STEPS,
|
|
352
|
+
content=f"Steps {self.name} completed with {len(all_results)} results",
|
|
353
|
+
success=all(result.success for result in all_results) if all_results else True,
|
|
354
|
+
steps=all_results,
|
|
355
|
+
)
|
|
356
|
+
|
|
357
|
+
except Exception as e:
|
|
358
|
+
logger.error(f"Steps streaming failed: {e}")
|
|
359
|
+
error_result = StepOutput(
|
|
360
|
+
step_name=self.name or "Steps",
|
|
361
|
+
content=f"Steps execution failed: {str(e)}",
|
|
362
|
+
success=False,
|
|
363
|
+
error=str(e),
|
|
364
|
+
)
|
|
365
|
+
yield error_result
|
|
366
|
+
|
|
367
|
+
async def aexecute(
|
|
368
|
+
self,
|
|
369
|
+
step_input: StepInput,
|
|
370
|
+
session_id: Optional[str] = None,
|
|
371
|
+
user_id: Optional[str] = None,
|
|
372
|
+
workflow_run_response: Optional[WorkflowRunOutput] = None,
|
|
373
|
+
run_context: Optional[RunContext] = None,
|
|
374
|
+
session_state: Optional[Dict[str, Any]] = None,
|
|
375
|
+
store_executor_outputs: bool = True,
|
|
376
|
+
workflow_session: Optional[WorkflowSession] = None,
|
|
377
|
+
add_workflow_history_to_steps: Optional[bool] = False,
|
|
378
|
+
num_history_runs: int = 3,
|
|
379
|
+
background_tasks: Optional[Any] = None,
|
|
380
|
+
) -> StepOutput:
|
|
381
|
+
"""Execute all steps in sequence asynchronously and return the final result"""
|
|
382
|
+
log_debug(f"Steps Start: {self.name} ({len(self.steps)} steps)", center=True, symbol="-")
|
|
383
|
+
|
|
384
|
+
steps_id = str(uuid4())
|
|
385
|
+
|
|
386
|
+
self._prepare_steps()
|
|
387
|
+
|
|
388
|
+
if not self.steps:
|
|
389
|
+
return StepOutput(step_name=self.name or "Steps", content="No steps to execute")
|
|
390
|
+
|
|
391
|
+
# Track outputs and pass data between steps - following Condition/Router pattern
|
|
392
|
+
all_results: List[StepOutput] = []
|
|
393
|
+
current_step_input = step_input
|
|
394
|
+
steps_step_outputs = {}
|
|
395
|
+
|
|
396
|
+
try:
|
|
397
|
+
for i, step in enumerate(self.steps):
|
|
398
|
+
step_name = getattr(step, "name", f"step_{i + 1}")
|
|
399
|
+
log_debug(f"Steps {self.name}: Executing async step {i + 1}/{len(self.steps)} - {step_name}")
|
|
400
|
+
|
|
401
|
+
# Execute step
|
|
402
|
+
step_output = await step.aexecute( # type: ignore
|
|
403
|
+
current_step_input,
|
|
404
|
+
session_id=session_id,
|
|
405
|
+
user_id=user_id,
|
|
406
|
+
workflow_run_response=workflow_run_response,
|
|
407
|
+
store_executor_outputs=store_executor_outputs,
|
|
408
|
+
run_context=run_context,
|
|
409
|
+
session_state=session_state,
|
|
410
|
+
workflow_session=workflow_session,
|
|
411
|
+
add_workflow_history_to_steps=add_workflow_history_to_steps,
|
|
412
|
+
num_history_runs=num_history_runs,
|
|
413
|
+
background_tasks=background_tasks,
|
|
414
|
+
)
|
|
415
|
+
|
|
416
|
+
# Handle both single StepOutput and List[StepOutput] (from Loop/Condition/Router steps)
|
|
417
|
+
if isinstance(step_output, list):
|
|
418
|
+
all_results.extend(step_output)
|
|
419
|
+
if step_output:
|
|
420
|
+
steps_step_outputs[step_name] = step_output[-1]
|
|
421
|
+
|
|
422
|
+
if any(output.stop for output in step_output):
|
|
423
|
+
logger.info(f"Early termination requested by step {step_name}")
|
|
424
|
+
break
|
|
425
|
+
else:
|
|
426
|
+
all_results.append(step_output)
|
|
427
|
+
steps_step_outputs[step_name] = step_output
|
|
428
|
+
|
|
429
|
+
if step_output.stop:
|
|
430
|
+
logger.info(f"Early termination requested by step {step_name}")
|
|
431
|
+
break
|
|
432
|
+
|
|
433
|
+
# Update input for next step with proper chaining
|
|
434
|
+
current_step_input = self._update_step_input_from_outputs(
|
|
435
|
+
current_step_input, step_output, steps_step_outputs
|
|
436
|
+
)
|
|
437
|
+
|
|
438
|
+
log_debug(f"Steps End: {self.name} ({len(all_results)} results)", center=True, symbol="-")
|
|
439
|
+
|
|
440
|
+
return StepOutput(
|
|
441
|
+
step_name=self.name,
|
|
442
|
+
step_id=steps_id,
|
|
443
|
+
step_type=StepType.STEPS,
|
|
444
|
+
content=f"Steps {self.name} completed with {len(all_results)} results",
|
|
445
|
+
success=all(result.success for result in all_results) if all_results else True,
|
|
446
|
+
steps=all_results,
|
|
447
|
+
)
|
|
448
|
+
|
|
449
|
+
except Exception as e:
|
|
450
|
+
logger.error(f"Async steps execution failed: {e}")
|
|
451
|
+
return StepOutput(
|
|
452
|
+
step_name=self.name or "Steps",
|
|
453
|
+
content=f"Steps execution failed: {str(e)}",
|
|
454
|
+
success=False,
|
|
455
|
+
error=str(e),
|
|
456
|
+
)
|
|
457
|
+
|
|
458
|
+
async def aexecute_stream(
|
|
459
|
+
self,
|
|
460
|
+
step_input: StepInput,
|
|
461
|
+
workflow_run_response: WorkflowRunOutput,
|
|
462
|
+
run_context: Optional[RunContext] = None,
|
|
463
|
+
session_state: Optional[Dict[str, Any]] = None,
|
|
464
|
+
session_id: Optional[str] = None,
|
|
465
|
+
user_id: Optional[str] = None,
|
|
466
|
+
stream_events: bool = False,
|
|
467
|
+
stream_intermediate_steps: bool = False,
|
|
468
|
+
stream_executor_events: bool = True,
|
|
469
|
+
step_index: Optional[Union[int, tuple]] = None,
|
|
470
|
+
store_executor_outputs: bool = True,
|
|
471
|
+
parent_step_id: Optional[str] = None,
|
|
472
|
+
workflow_session: Optional[WorkflowSession] = None,
|
|
473
|
+
add_workflow_history_to_steps: Optional[bool] = False,
|
|
474
|
+
num_history_runs: int = 3,
|
|
475
|
+
background_tasks: Optional[Any] = None,
|
|
476
|
+
) -> AsyncIterator[Union[WorkflowRunOutputEvent, TeamRunOutputEvent, RunOutputEvent, StepOutput]]:
|
|
477
|
+
"""Execute all steps in sequence with async streaming support"""
|
|
478
|
+
log_debug(f"Steps Start: {self.name} ({len(self.steps)} steps)", center=True, symbol="-")
|
|
479
|
+
|
|
480
|
+
steps_id = str(uuid4())
|
|
481
|
+
|
|
482
|
+
self._prepare_steps()
|
|
483
|
+
|
|
484
|
+
# Considering both stream_events and stream_intermediate_steps (deprecated)
|
|
485
|
+
if stream_intermediate_steps is not None:
|
|
486
|
+
warnings.warn(
|
|
487
|
+
"The 'stream_intermediate_steps' parameter is deprecated and will be removed in future versions. Use 'stream_events' instead.",
|
|
488
|
+
DeprecationWarning,
|
|
489
|
+
stacklevel=2,
|
|
490
|
+
)
|
|
491
|
+
stream_events = stream_events or stream_intermediate_steps
|
|
492
|
+
|
|
493
|
+
if stream_events:
|
|
494
|
+
# Yield steps execution started event
|
|
495
|
+
yield StepsExecutionStartedEvent(
|
|
496
|
+
run_id=workflow_run_response.run_id or "",
|
|
497
|
+
workflow_name=workflow_run_response.workflow_name or "",
|
|
498
|
+
workflow_id=workflow_run_response.workflow_id or "",
|
|
499
|
+
session_id=workflow_run_response.session_id or "",
|
|
500
|
+
step_name=self.name,
|
|
501
|
+
step_index=step_index,
|
|
502
|
+
steps_count=len(self.steps),
|
|
503
|
+
step_id=steps_id,
|
|
504
|
+
parent_step_id=parent_step_id,
|
|
505
|
+
)
|
|
506
|
+
|
|
507
|
+
if not self.steps:
|
|
508
|
+
yield StepOutput(step_name=self.name or "Steps", content="No steps to execute")
|
|
509
|
+
return
|
|
510
|
+
|
|
511
|
+
# Track outputs and pass data between steps - following Condition/Router pattern
|
|
512
|
+
all_results = []
|
|
513
|
+
current_step_input = step_input
|
|
514
|
+
steps_step_outputs = {}
|
|
515
|
+
|
|
516
|
+
try:
|
|
517
|
+
for i, step in enumerate(self.steps):
|
|
518
|
+
step_name = getattr(step, "name", f"step_{i + 1}")
|
|
519
|
+
log_debug(f"Steps {self.name}: Executing async step {i + 1}/{len(self.steps)} - {step_name}")
|
|
520
|
+
|
|
521
|
+
step_outputs_for_step = []
|
|
522
|
+
|
|
523
|
+
if step_index is None or isinstance(step_index, int):
|
|
524
|
+
# Steps is a main step - child steps get x.1, x.2, x.3 format
|
|
525
|
+
child_step_index = (step_index if step_index is not None else 1, i) # Use i, not i+1
|
|
526
|
+
else:
|
|
527
|
+
# Steps is already a child step - child steps get parent.1, parent.2, parent.3
|
|
528
|
+
child_step_index = step_index + (i,) # Extend the tuple
|
|
529
|
+
|
|
530
|
+
# Stream step execution
|
|
531
|
+
async for event in step.aexecute_stream( # type: ignore
|
|
532
|
+
current_step_input,
|
|
533
|
+
session_id=session_id,
|
|
534
|
+
user_id=user_id,
|
|
535
|
+
run_context=run_context,
|
|
536
|
+
session_state=session_state,
|
|
537
|
+
stream_events=stream_events,
|
|
538
|
+
stream_executor_events=stream_executor_events,
|
|
539
|
+
workflow_run_response=workflow_run_response,
|
|
540
|
+
step_index=child_step_index,
|
|
541
|
+
store_executor_outputs=store_executor_outputs,
|
|
542
|
+
parent_step_id=steps_id,
|
|
543
|
+
workflow_session=workflow_session,
|
|
544
|
+
add_workflow_history_to_steps=add_workflow_history_to_steps,
|
|
545
|
+
num_history_runs=num_history_runs,
|
|
546
|
+
background_tasks=background_tasks,
|
|
547
|
+
):
|
|
548
|
+
if isinstance(event, StepOutput):
|
|
549
|
+
step_outputs_for_step.append(event)
|
|
550
|
+
all_results.append(event)
|
|
551
|
+
else:
|
|
552
|
+
# Yield other events (streaming content, step events, etc.)
|
|
553
|
+
yield event
|
|
554
|
+
|
|
555
|
+
# Update step outputs tracking and prepare input for next step
|
|
556
|
+
if step_outputs_for_step:
|
|
557
|
+
if len(step_outputs_for_step) == 1:
|
|
558
|
+
steps_step_outputs[step_name] = step_outputs_for_step[0]
|
|
559
|
+
|
|
560
|
+
if step_outputs_for_step[0].stop:
|
|
561
|
+
logger.info(f"Early termination requested by step {step_name}")
|
|
562
|
+
break
|
|
563
|
+
|
|
564
|
+
current_step_input = self._update_step_input_from_outputs(
|
|
565
|
+
current_step_input, step_outputs_for_step[0], steps_step_outputs
|
|
566
|
+
)
|
|
567
|
+
else:
|
|
568
|
+
# Use last output
|
|
569
|
+
steps_step_outputs[step_name] = step_outputs_for_step[-1]
|
|
570
|
+
|
|
571
|
+
if any(output.stop for output in step_outputs_for_step):
|
|
572
|
+
logger.info(f"Early termination requested by step {step_name}")
|
|
573
|
+
break
|
|
574
|
+
|
|
575
|
+
current_step_input = self._update_step_input_from_outputs(
|
|
576
|
+
current_step_input, step_outputs_for_step, steps_step_outputs
|
|
577
|
+
)
|
|
578
|
+
|
|
579
|
+
log_debug(f"Steps End: {self.name} ({len(all_results)} results)", center=True, symbol="-")
|
|
580
|
+
# Yield steps execution completed event
|
|
581
|
+
if stream_events:
|
|
582
|
+
yield StepsExecutionCompletedEvent(
|
|
583
|
+
run_id=workflow_run_response.run_id or "",
|
|
584
|
+
workflow_name=workflow_run_response.workflow_name or "",
|
|
585
|
+
workflow_id=workflow_run_response.workflow_id or "",
|
|
586
|
+
session_id=workflow_run_response.session_id or "",
|
|
587
|
+
step_name=self.name,
|
|
588
|
+
step_index=step_index,
|
|
589
|
+
steps_count=len(self.steps),
|
|
590
|
+
executed_steps=len(all_results),
|
|
591
|
+
step_results=all_results,
|
|
592
|
+
step_id=steps_id,
|
|
593
|
+
parent_step_id=parent_step_id,
|
|
594
|
+
)
|
|
595
|
+
|
|
596
|
+
yield StepOutput(
|
|
597
|
+
step_name=self.name,
|
|
598
|
+
step_id=steps_id,
|
|
599
|
+
step_type=StepType.STEPS,
|
|
600
|
+
content=f"Steps {self.name} completed with {len(all_results)} results",
|
|
601
|
+
success=all(result.success for result in all_results) if all_results else True,
|
|
602
|
+
steps=all_results,
|
|
603
|
+
)
|
|
604
|
+
|
|
605
|
+
except Exception as e:
|
|
606
|
+
logger.error(f"Async steps streaming failed: {e}")
|
|
607
|
+
error_result = StepOutput(
|
|
608
|
+
step_name=self.name or "Steps",
|
|
609
|
+
content=f"Steps execution failed: {str(e)}",
|
|
610
|
+
success=False,
|
|
611
|
+
error=str(e),
|
|
612
|
+
)
|
|
613
|
+
yield error_result
|