agno 1.8.1__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/__init__.py +8 -0
- 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 +15 -11
- 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 +131 -131
- agno/models/aws/bedrock.py +110 -182
- 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 +77 -33
- 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 +22 -22
- 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 +19 -34
- 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 +32 -2
- 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 +47 -4
- 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 -107
- 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 -1050
- agno/app/playground/deploy.py +0 -249
- agno/app/playground/operator.py +0 -183
- agno/app/playground/schemas.py +0 -220
- agno/app/playground/serve.py +0 -55
- agno/app/playground/sync_router.py +0 -1042
- 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 -3312
- 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.1.dist-info/METADATA +0 -982
- agno-1.8.1.dist-info/RECORD +0 -566
- agno-1.8.1.dist-info/entry_points.txt +0 -3
- agno-1.8.1.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.1.dist-info → agno-2.0.0.dist-info}/WHEEL +0 -0
- {agno-1.8.1.dist-info → agno-2.0.0.dist-info}/top_level.txt +0 -0
|
@@ -1,22 +1,26 @@
|
|
|
1
1
|
import inspect
|
|
2
|
+
from copy import copy
|
|
2
3
|
from dataclasses import dataclass
|
|
3
4
|
from typing import Any, AsyncIterator, Awaitable, Callable, Dict, Iterator, List, Optional, Union
|
|
5
|
+
from uuid import uuid4
|
|
4
6
|
|
|
5
7
|
from pydantic import BaseModel
|
|
6
8
|
|
|
7
9
|
from agno.agent import Agent
|
|
8
|
-
from agno.media import Audio,
|
|
9
|
-
from agno.
|
|
10
|
-
from agno.run.
|
|
11
|
-
from agno.run.
|
|
10
|
+
from agno.media import Audio, Image, Video
|
|
11
|
+
from agno.models.metrics import Metrics
|
|
12
|
+
from agno.run.agent import RunOutput
|
|
13
|
+
from agno.run.team import TeamRunOutput
|
|
14
|
+
from agno.run.workflow import (
|
|
12
15
|
StepCompletedEvent,
|
|
13
16
|
StepStartedEvent,
|
|
14
|
-
|
|
15
|
-
|
|
17
|
+
WorkflowRunOutput,
|
|
18
|
+
WorkflowRunOutputEvent,
|
|
16
19
|
)
|
|
17
20
|
from agno.team import Team
|
|
18
21
|
from agno.utils.log import log_debug, logger, use_agent_logger, use_team_logger, use_workflow_logger
|
|
19
|
-
from agno.
|
|
22
|
+
from agno.utils.merge_dict import merge_dictionaries
|
|
23
|
+
from agno.workflow.types import StepInput, StepOutput, StepType
|
|
20
24
|
|
|
21
25
|
StepExecutor = Callable[
|
|
22
26
|
[StepInput],
|
|
@@ -89,6 +93,10 @@ class Step:
|
|
|
89
93
|
self.timeout_seconds = timeout_seconds
|
|
90
94
|
self.skip_on_failure = skip_on_failure
|
|
91
95
|
self.strict_input_validation = strict_input_validation
|
|
96
|
+
self.step_id = step_id
|
|
97
|
+
|
|
98
|
+
if step_id is None:
|
|
99
|
+
self.step_id = str(uuid4())
|
|
92
100
|
|
|
93
101
|
# Set the active executor
|
|
94
102
|
self._set_active_executor()
|
|
@@ -150,19 +158,20 @@ class Step:
|
|
|
150
158
|
else:
|
|
151
159
|
raise ValueError("No executor configured")
|
|
152
160
|
|
|
153
|
-
def _extract_metrics_from_response(self, response: Union[
|
|
161
|
+
def _extract_metrics_from_response(self, response: Union[RunOutput, TeamRunOutput]) -> Optional[Metrics]:
|
|
154
162
|
"""Extract metrics from agent or team response"""
|
|
155
163
|
if hasattr(response, "metrics") and response.metrics:
|
|
156
|
-
return
|
|
157
|
-
"step_name": self.name,
|
|
158
|
-
"executor_type": self._executor_type,
|
|
159
|
-
"executor_name": self.executor_name,
|
|
160
|
-
"metrics": response.metrics,
|
|
161
|
-
}
|
|
164
|
+
return response.metrics
|
|
162
165
|
return None
|
|
163
166
|
|
|
164
167
|
def execute(
|
|
165
|
-
self,
|
|
168
|
+
self,
|
|
169
|
+
step_input: StepInput,
|
|
170
|
+
session_id: Optional[str] = None,
|
|
171
|
+
user_id: Optional[str] = None,
|
|
172
|
+
workflow_run_response: Optional["WorkflowRunOutput"] = None,
|
|
173
|
+
session_state: Optional[Dict[str, Any]] = None,
|
|
174
|
+
store_executor_outputs: bool = True,
|
|
166
175
|
) -> StepOutput:
|
|
167
176
|
"""Execute the step with StepInput, returning final StepOutput (non-streaming)"""
|
|
168
177
|
log_debug(f"Executing step: {self.name}")
|
|
@@ -173,7 +182,7 @@ class Step:
|
|
|
173
182
|
# Execute with retries
|
|
174
183
|
for attempt in range(self.max_retries + 1):
|
|
175
184
|
try:
|
|
176
|
-
response: Union[
|
|
185
|
+
response: Union[RunOutput, TeamRunOutput, StepOutput]
|
|
177
186
|
if self._executor_type == "function":
|
|
178
187
|
if inspect.iscoroutinefunction(self.active_executor) or inspect.isasyncgenfunction(
|
|
179
188
|
self.active_executor
|
|
@@ -215,7 +224,7 @@ class Step:
|
|
|
215
224
|
else:
|
|
216
225
|
# For agents and teams, prepare message with context
|
|
217
226
|
message = self._prepare_message(
|
|
218
|
-
step_input.
|
|
227
|
+
step_input.input,
|
|
219
228
|
step_input.previous_step_outputs,
|
|
220
229
|
)
|
|
221
230
|
|
|
@@ -234,16 +243,30 @@ class Step:
|
|
|
234
243
|
self._convert_video_artifacts_to_videos(step_input.videos) if step_input.videos else None
|
|
235
244
|
)
|
|
236
245
|
audios = self._convert_audio_artifacts_to_audio(step_input.audio) if step_input.audio else None
|
|
237
|
-
|
|
238
|
-
|
|
246
|
+
|
|
247
|
+
kwargs: Dict[str, Any] = {}
|
|
248
|
+
if isinstance(self.active_executor, Team):
|
|
249
|
+
kwargs["store_member_responses"] = True
|
|
250
|
+
|
|
251
|
+
session_state_copy = copy(session_state)
|
|
252
|
+
response = self.active_executor.run( # type: ignore
|
|
253
|
+
input=message, # type: ignore
|
|
239
254
|
images=images,
|
|
240
255
|
videos=videos,
|
|
241
256
|
audio=audios,
|
|
242
257
|
files=step_input.files,
|
|
243
258
|
session_id=session_id,
|
|
244
259
|
user_id=user_id,
|
|
260
|
+
session_state=session_state_copy, # Send a copy to the executor
|
|
261
|
+
**kwargs,
|
|
245
262
|
)
|
|
246
263
|
|
|
264
|
+
# Update workflow session state
|
|
265
|
+
merge_dictionaries(session_state, session_state_copy) # type: ignore
|
|
266
|
+
|
|
267
|
+
if store_executor_outputs and workflow_run_response is not None:
|
|
268
|
+
self._store_executor_response(workflow_run_response, response) # type: ignore
|
|
269
|
+
|
|
247
270
|
# Switch back to workflow logger after execution
|
|
248
271
|
use_workflow_logger()
|
|
249
272
|
else:
|
|
@@ -274,9 +297,12 @@ class Step:
|
|
|
274
297
|
session_id: Optional[str] = None,
|
|
275
298
|
user_id: Optional[str] = None,
|
|
276
299
|
stream_intermediate_steps: bool = False,
|
|
277
|
-
workflow_run_response: Optional["
|
|
300
|
+
workflow_run_response: Optional["WorkflowRunOutput"] = None,
|
|
301
|
+
session_state: Optional[Dict[str, Any]] = None,
|
|
278
302
|
step_index: Optional[Union[int, tuple]] = None,
|
|
279
|
-
|
|
303
|
+
store_executor_outputs: bool = True,
|
|
304
|
+
parent_step_id: Optional[str] = None,
|
|
305
|
+
) -> Iterator[Union[WorkflowRunOutputEvent, StepOutput]]:
|
|
280
306
|
"""Execute the step with event-driven streaming support"""
|
|
281
307
|
|
|
282
308
|
if step_input.previous_step_outputs:
|
|
@@ -291,6 +317,8 @@ class Step:
|
|
|
291
317
|
session_id=workflow_run_response.session_id or "",
|
|
292
318
|
step_name=self.name,
|
|
293
319
|
step_index=step_index,
|
|
320
|
+
step_id=self.step_id,
|
|
321
|
+
parent_step_id=parent_step_id,
|
|
294
322
|
)
|
|
295
323
|
|
|
296
324
|
# Execute with retries and streaming
|
|
@@ -341,7 +369,7 @@ class Step:
|
|
|
341
369
|
else:
|
|
342
370
|
# For agents and teams, prepare message with context
|
|
343
371
|
message = self._prepare_message(
|
|
344
|
-
step_input.
|
|
372
|
+
step_input.input,
|
|
345
373
|
step_input.previous_step_outputs,
|
|
346
374
|
)
|
|
347
375
|
|
|
@@ -359,21 +387,49 @@ class Step:
|
|
|
359
387
|
self._convert_video_artifacts_to_videos(step_input.videos) if step_input.videos else None
|
|
360
388
|
)
|
|
361
389
|
audios = self._convert_audio_artifacts_to_audio(step_input.audio) if step_input.audio else None
|
|
390
|
+
|
|
391
|
+
kwargs: Dict[str, Any] = {}
|
|
392
|
+
if isinstance(self.active_executor, Team):
|
|
393
|
+
kwargs["store_member_responses"] = True
|
|
394
|
+
|
|
395
|
+
session_state_copy = copy(session_state)
|
|
362
396
|
response_stream = self.active_executor.run( # type: ignore[call-overload, misc]
|
|
363
|
-
|
|
397
|
+
input=message,
|
|
364
398
|
images=images,
|
|
365
399
|
videos=videos,
|
|
366
400
|
audio=audios,
|
|
367
401
|
files=step_input.files,
|
|
368
402
|
session_id=session_id,
|
|
369
403
|
user_id=user_id,
|
|
404
|
+
session_state=session_state_copy, # Send a copy to the executor
|
|
370
405
|
stream=True,
|
|
371
406
|
stream_intermediate_steps=stream_intermediate_steps,
|
|
407
|
+
# Pass workflow context directly via kwargs
|
|
408
|
+
workflow_context={
|
|
409
|
+
"workflow_id": workflow_run_response.workflow_id if workflow_run_response else None,
|
|
410
|
+
"workflow_run_id": workflow_run_response.run_id if workflow_run_response else None,
|
|
411
|
+
"step_id": self.step_id,
|
|
412
|
+
"step_name": self.name,
|
|
413
|
+
"step_index": step_index,
|
|
414
|
+
},
|
|
415
|
+
yield_run_response=True,
|
|
416
|
+
**kwargs,
|
|
372
417
|
)
|
|
373
418
|
|
|
419
|
+
active_executor_run_response = None
|
|
374
420
|
for event in response_stream:
|
|
421
|
+
if isinstance(event, RunOutput) or isinstance(event, TeamRunOutput):
|
|
422
|
+
active_executor_run_response = event
|
|
423
|
+
break
|
|
375
424
|
yield event # type: ignore[misc]
|
|
376
|
-
|
|
425
|
+
|
|
426
|
+
# Update workflow session state
|
|
427
|
+
merge_dictionaries(session_state, session_state_copy) # type: ignore
|
|
428
|
+
|
|
429
|
+
if store_executor_outputs and workflow_run_response is not None:
|
|
430
|
+
self._store_executor_response(workflow_run_response, active_executor_run_response) # type: ignore
|
|
431
|
+
|
|
432
|
+
final_response = self._process_step_output(active_executor_run_response) # type: ignore
|
|
377
433
|
|
|
378
434
|
else:
|
|
379
435
|
raise ValueError(f"Unsupported executor type: {self._executor_type}")
|
|
@@ -400,6 +456,7 @@ class Step:
|
|
|
400
456
|
step_index=step_index,
|
|
401
457
|
content=final_response.content,
|
|
402
458
|
step_response=final_response,
|
|
459
|
+
parent_step_id=parent_step_id,
|
|
403
460
|
)
|
|
404
461
|
|
|
405
462
|
return
|
|
@@ -422,7 +479,13 @@ class Step:
|
|
|
422
479
|
return
|
|
423
480
|
|
|
424
481
|
async def aexecute(
|
|
425
|
-
self,
|
|
482
|
+
self,
|
|
483
|
+
step_input: StepInput,
|
|
484
|
+
session_id: Optional[str] = None,
|
|
485
|
+
user_id: Optional[str] = None,
|
|
486
|
+
workflow_run_response: Optional["WorkflowRunOutput"] = None,
|
|
487
|
+
session_state: Optional[Dict[str, Any]] = None,
|
|
488
|
+
store_executor_outputs: bool = True,
|
|
426
489
|
) -> StepOutput:
|
|
427
490
|
"""Execute the step with StepInput, returning final StepOutput (non-streaming)"""
|
|
428
491
|
logger.info(f"Executing async step (non-streaming): {self.name}")
|
|
@@ -492,7 +555,7 @@ class Step:
|
|
|
492
555
|
else:
|
|
493
556
|
# For agents and teams, prepare message with context
|
|
494
557
|
message = self._prepare_message(
|
|
495
|
-
step_input.
|
|
558
|
+
step_input.input,
|
|
496
559
|
step_input.previous_step_outputs,
|
|
497
560
|
)
|
|
498
561
|
|
|
@@ -511,16 +574,30 @@ class Step:
|
|
|
511
574
|
self._convert_video_artifacts_to_videos(step_input.videos) if step_input.videos else None
|
|
512
575
|
)
|
|
513
576
|
audios = self._convert_audio_artifacts_to_audio(step_input.audio) if step_input.audio else None
|
|
577
|
+
|
|
578
|
+
kwargs: Dict[str, Any] = {}
|
|
579
|
+
if isinstance(self.active_executor, Team):
|
|
580
|
+
kwargs["store_member_responses"] = True
|
|
581
|
+
|
|
582
|
+
session_state_copy = copy(session_state)
|
|
514
583
|
response = await self.active_executor.arun( # type: ignore
|
|
515
|
-
|
|
584
|
+
input=message, # type: ignore
|
|
516
585
|
images=images,
|
|
517
586
|
videos=videos,
|
|
518
587
|
audio=audios,
|
|
519
588
|
files=step_input.files,
|
|
520
589
|
session_id=session_id,
|
|
521
590
|
user_id=user_id,
|
|
591
|
+
session_state=session_state_copy,
|
|
592
|
+
**kwargs,
|
|
522
593
|
)
|
|
523
594
|
|
|
595
|
+
# Update workflow session state
|
|
596
|
+
merge_dictionaries(session_state, session_state_copy) # type: ignore
|
|
597
|
+
|
|
598
|
+
if store_executor_outputs and workflow_run_response is not None:
|
|
599
|
+
self._store_executor_response(workflow_run_response, response) # type: ignore
|
|
600
|
+
|
|
524
601
|
# Switch back to workflow logger after execution
|
|
525
602
|
use_workflow_logger()
|
|
526
603
|
else:
|
|
@@ -551,9 +628,12 @@ class Step:
|
|
|
551
628
|
session_id: Optional[str] = None,
|
|
552
629
|
user_id: Optional[str] = None,
|
|
553
630
|
stream_intermediate_steps: bool = False,
|
|
554
|
-
workflow_run_response: Optional["
|
|
631
|
+
workflow_run_response: Optional["WorkflowRunOutput"] = None,
|
|
632
|
+
session_state: Optional[Dict[str, Any]] = None,
|
|
555
633
|
step_index: Optional[Union[int, tuple]] = None,
|
|
556
|
-
|
|
634
|
+
store_executor_outputs: bool = True,
|
|
635
|
+
parent_step_id: Optional[str] = None,
|
|
636
|
+
) -> AsyncIterator[Union[WorkflowRunOutputEvent, StepOutput]]:
|
|
557
637
|
"""Execute the step with event-driven streaming support"""
|
|
558
638
|
|
|
559
639
|
if step_input.previous_step_outputs:
|
|
@@ -568,6 +648,8 @@ class Step:
|
|
|
568
648
|
session_id=workflow_run_response.session_id or "",
|
|
569
649
|
step_name=self.name,
|
|
570
650
|
step_index=step_index,
|
|
651
|
+
step_id=self.step_id,
|
|
652
|
+
parent_step_id=parent_step_id,
|
|
571
653
|
)
|
|
572
654
|
|
|
573
655
|
# Execute with retries and streaming
|
|
@@ -636,7 +718,7 @@ class Step:
|
|
|
636
718
|
else:
|
|
637
719
|
# For agents and teams, prepare message with context
|
|
638
720
|
message = self._prepare_message(
|
|
639
|
-
step_input.
|
|
721
|
+
step_input.input,
|
|
640
722
|
step_input.previous_step_outputs,
|
|
641
723
|
)
|
|
642
724
|
|
|
@@ -654,22 +736,50 @@ class Step:
|
|
|
654
736
|
self._convert_video_artifacts_to_videos(step_input.videos) if step_input.videos else None
|
|
655
737
|
)
|
|
656
738
|
audios = self._convert_audio_artifacts_to_audio(step_input.audio) if step_input.audio else None
|
|
657
|
-
|
|
658
|
-
|
|
739
|
+
|
|
740
|
+
kwargs: Dict[str, Any] = {}
|
|
741
|
+
if isinstance(self.active_executor, Team):
|
|
742
|
+
kwargs["store_member_responses"] = True
|
|
743
|
+
|
|
744
|
+
session_state_copy = copy(session_state)
|
|
745
|
+
response_stream = self.active_executor.arun( # type: ignore
|
|
746
|
+
input=message,
|
|
659
747
|
images=images,
|
|
660
748
|
videos=videos,
|
|
661
749
|
audio=audios,
|
|
662
750
|
files=step_input.files,
|
|
663
751
|
session_id=session_id,
|
|
664
752
|
user_id=user_id,
|
|
753
|
+
session_state=session_state_copy,
|
|
665
754
|
stream=True,
|
|
666
755
|
stream_intermediate_steps=stream_intermediate_steps,
|
|
756
|
+
# Pass workflow context directly via kwargs
|
|
757
|
+
workflow_context={
|
|
758
|
+
"workflow_id": workflow_run_response.workflow_id if workflow_run_response else None,
|
|
759
|
+
"workflow_run_id": workflow_run_response.run_id if workflow_run_response else None,
|
|
760
|
+
"step_id": self.step_id,
|
|
761
|
+
"step_name": self.name,
|
|
762
|
+
"step_index": step_index,
|
|
763
|
+
},
|
|
764
|
+
yield_run_response=True,
|
|
765
|
+
**kwargs,
|
|
667
766
|
)
|
|
668
767
|
|
|
768
|
+
active_executor_run_response = None
|
|
669
769
|
async for event in response_stream:
|
|
670
770
|
log_debug(f"Received async event from agent: {type(event).__name__}")
|
|
771
|
+
if isinstance(event, RunOutput) or isinstance(event, TeamRunOutput):
|
|
772
|
+
active_executor_run_response = event
|
|
773
|
+
break
|
|
671
774
|
yield event # type: ignore[misc]
|
|
672
|
-
|
|
775
|
+
|
|
776
|
+
# Update workflow session state
|
|
777
|
+
merge_dictionaries(session_state, session_state_copy) # type: ignore
|
|
778
|
+
|
|
779
|
+
if store_executor_outputs and workflow_run_response is not None:
|
|
780
|
+
self._store_executor_response(workflow_run_response, active_executor_run_response) # type: ignore
|
|
781
|
+
|
|
782
|
+
final_response = self._process_step_output(active_executor_run_response) # type: ignore
|
|
673
783
|
else:
|
|
674
784
|
raise ValueError(f"Unsupported executor type: {self._executor_type}")
|
|
675
785
|
|
|
@@ -692,8 +802,10 @@ class Step:
|
|
|
692
802
|
session_id=workflow_run_response.session_id or "",
|
|
693
803
|
step_name=self.name,
|
|
694
804
|
step_index=step_index,
|
|
805
|
+
step_id=self.step_id,
|
|
695
806
|
content=final_response.content,
|
|
696
807
|
step_response=final_response,
|
|
808
|
+
parent_step_id=parent_step_id,
|
|
697
809
|
)
|
|
698
810
|
return
|
|
699
811
|
|
|
@@ -714,6 +826,48 @@ class Step:
|
|
|
714
826
|
|
|
715
827
|
return
|
|
716
828
|
|
|
829
|
+
def _store_executor_response(
|
|
830
|
+
self, workflow_run_response: "WorkflowRunOutput", executor_run_response: Union[RunOutput, TeamRunOutput]
|
|
831
|
+
) -> None:
|
|
832
|
+
"""Store agent/team responses in step_executor_runs if enabled"""
|
|
833
|
+
if self._executor_type in ["agent", "team"]:
|
|
834
|
+
# propogate the workflow run id as parent run id to the executor response
|
|
835
|
+
executor_run_response.parent_run_id = workflow_run_response.run_id
|
|
836
|
+
executor_run_response.workflow_step_id = self.step_id
|
|
837
|
+
|
|
838
|
+
# Get the raw response from the step's active executor
|
|
839
|
+
raw_response = executor_run_response
|
|
840
|
+
if raw_response and isinstance(raw_response, (RunOutput, TeamRunOutput)):
|
|
841
|
+
if workflow_run_response.step_executor_runs is None:
|
|
842
|
+
workflow_run_response.step_executor_runs = []
|
|
843
|
+
|
|
844
|
+
raw_response.workflow_step_id = self.step_id
|
|
845
|
+
# Add the primary executor run
|
|
846
|
+
workflow_run_response.step_executor_runs.append(raw_response)
|
|
847
|
+
|
|
848
|
+
# Add direct member agent runs (in case of a team we force store_member_responses=True here)
|
|
849
|
+
if isinstance(raw_response, TeamRunOutput) and getattr(
|
|
850
|
+
self.active_executor, "store_member_responses", False
|
|
851
|
+
):
|
|
852
|
+
for mr in raw_response.member_responses or []:
|
|
853
|
+
if isinstance(mr, RunOutput):
|
|
854
|
+
workflow_run_response.step_executor_runs.append(mr)
|
|
855
|
+
|
|
856
|
+
def _get_deepest_content_from_step_output(self, step_output: "StepOutput") -> Optional[str]:
|
|
857
|
+
"""
|
|
858
|
+
Extract the deepest content from a step output, handling nested structures like Steps, Router, Loop, etc.
|
|
859
|
+
|
|
860
|
+
For container steps (Steps, Router, Loop, etc.), this will recursively find the content from the
|
|
861
|
+
last actual step rather than using the generic container message.
|
|
862
|
+
"""
|
|
863
|
+
# If this step has nested steps (like Steps, Condition, Router, Loop, etc.)
|
|
864
|
+
if hasattr(step_output, "steps") and step_output.steps and len(step_output.steps) > 0:
|
|
865
|
+
# Recursively get content from the last nested step
|
|
866
|
+
return self._get_deepest_content_from_step_output(step_output.steps[-1])
|
|
867
|
+
|
|
868
|
+
# For regular steps, return their content
|
|
869
|
+
return step_output.content # type: ignore
|
|
870
|
+
|
|
717
871
|
def _prepare_message(
|
|
718
872
|
self,
|
|
719
873
|
message: Optional[Union[str, Dict[str, Any], List[Any], BaseModel]],
|
|
@@ -723,17 +877,20 @@ class Step:
|
|
|
723
877
|
|
|
724
878
|
if previous_step_outputs and self._executor_type in ["agent", "team"]:
|
|
725
879
|
last_output = list(previous_step_outputs.values())[-1] if previous_step_outputs else None
|
|
726
|
-
if last_output
|
|
727
|
-
|
|
880
|
+
if last_output:
|
|
881
|
+
deepest_content = self._get_deepest_content_from_step_output(last_output)
|
|
882
|
+
if deepest_content:
|
|
883
|
+
return deepest_content
|
|
728
884
|
|
|
729
885
|
# If no previous step outputs, return the original message unchanged
|
|
730
886
|
return message
|
|
731
887
|
|
|
732
|
-
def _process_step_output(self, response: Union[
|
|
888
|
+
def _process_step_output(self, response: Union[RunOutput, TeamRunOutput, StepOutput]) -> StepOutput:
|
|
733
889
|
"""Create StepOutput from execution response"""
|
|
734
890
|
if isinstance(response, StepOutput):
|
|
735
891
|
response.step_name = self.name or "unnamed_step"
|
|
736
892
|
response.step_id = self.step_id
|
|
893
|
+
response.step_type = StepType.STEP
|
|
737
894
|
response.executor_type = self._executor_type
|
|
738
895
|
response.executor_name = self.executor_name
|
|
739
896
|
return response
|
|
@@ -749,44 +906,45 @@ class Step:
|
|
|
749
906
|
return StepOutput(
|
|
750
907
|
step_name=self.name or "unnamed_step",
|
|
751
908
|
step_id=self.step_id,
|
|
909
|
+
step_type=StepType.STEP,
|
|
752
910
|
executor_type=self._executor_type,
|
|
753
911
|
executor_name=self.executor_name,
|
|
754
912
|
content=response.content,
|
|
755
|
-
|
|
913
|
+
step_run_id=getattr(response, "run_id", None),
|
|
756
914
|
images=images,
|
|
757
915
|
videos=videos,
|
|
758
916
|
audio=audio,
|
|
759
917
|
metrics=metrics,
|
|
760
918
|
)
|
|
761
919
|
|
|
762
|
-
def _convert_function_result_to_response(self, result: Any) ->
|
|
763
|
-
"""Convert function execution result to
|
|
764
|
-
if isinstance(result,
|
|
920
|
+
def _convert_function_result_to_response(self, result: Any) -> RunOutput:
|
|
921
|
+
"""Convert function execution result to RunOutput"""
|
|
922
|
+
if isinstance(result, RunOutput):
|
|
765
923
|
return result
|
|
766
924
|
elif isinstance(result, str):
|
|
767
|
-
return
|
|
925
|
+
return RunOutput(content=result)
|
|
768
926
|
elif isinstance(result, dict):
|
|
769
927
|
# If it's a dict, try to extract content
|
|
770
928
|
content = result.get("content", str(result))
|
|
771
|
-
return
|
|
929
|
+
return RunOutput(content=content)
|
|
772
930
|
else:
|
|
773
931
|
# Convert any other type to string
|
|
774
|
-
return
|
|
932
|
+
return RunOutput(content=str(result))
|
|
775
933
|
|
|
776
|
-
def _convert_audio_artifacts_to_audio(self, audio_artifacts: List[
|
|
934
|
+
def _convert_audio_artifacts_to_audio(self, audio_artifacts: List[Audio]) -> List[Audio]:
|
|
777
935
|
"""Convert AudioArtifact objects to Audio objects"""
|
|
778
936
|
audios = []
|
|
779
937
|
for audio_artifact in audio_artifacts:
|
|
780
938
|
if audio_artifact.url:
|
|
781
939
|
audios.append(Audio(url=audio_artifact.url))
|
|
782
|
-
elif audio_artifact.
|
|
783
|
-
audios.append(Audio(content=audio_artifact.
|
|
940
|
+
elif audio_artifact.content:
|
|
941
|
+
audios.append(Audio(content=audio_artifact.content))
|
|
784
942
|
else:
|
|
785
|
-
logger.warning(f"Skipping AudioArtifact with no URL or
|
|
943
|
+
logger.warning(f"Skipping AudioArtifact with no URL or content: {audio_artifact}")
|
|
786
944
|
continue
|
|
787
945
|
return audios
|
|
788
946
|
|
|
789
|
-
def _convert_image_artifacts_to_images(self, image_artifacts: List[
|
|
947
|
+
def _convert_image_artifacts_to_images(self, image_artifacts: List[Image]) -> List[Image]:
|
|
790
948
|
"""
|
|
791
949
|
Convert ImageArtifact objects to Image objects with proper content handling.
|
|
792
950
|
|
|
@@ -838,7 +996,7 @@ class Step:
|
|
|
838
996
|
|
|
839
997
|
return images
|
|
840
998
|
|
|
841
|
-
def _convert_video_artifacts_to_videos(self, video_artifacts: List[
|
|
999
|
+
def _convert_video_artifacts_to_videos(self, video_artifacts: List[Video]) -> List[Video]:
|
|
842
1000
|
"""
|
|
843
1001
|
Convert VideoArtifact objects to Video objects with proper content handling.
|
|
844
1002
|
|