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/session/workflow.py
ADDED
|
@@ -0,0 +1,501 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import time
|
|
4
|
+
from dataclasses import dataclass
|
|
5
|
+
from typing import Any, Dict, List, Mapping, Optional, Tuple, Union
|
|
6
|
+
|
|
7
|
+
from pydantic import BaseModel
|
|
8
|
+
|
|
9
|
+
from agno.models.message import Message
|
|
10
|
+
from agno.run.agent import RunOutput
|
|
11
|
+
from agno.run.base import RunStatus
|
|
12
|
+
from agno.run.team import TeamRunOutput
|
|
13
|
+
from agno.run.workflow import WorkflowRunOutput
|
|
14
|
+
from agno.utils.log import log_debug, logger
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@dataclass
|
|
18
|
+
class WorkflowSession:
|
|
19
|
+
"""Workflow Session V2 for pipeline-based workflows"""
|
|
20
|
+
|
|
21
|
+
# Session UUID - this is the workflow_session_id that gets set on agents/teams
|
|
22
|
+
session_id: str
|
|
23
|
+
# ID of the user interacting with this workflow
|
|
24
|
+
user_id: Optional[str] = None
|
|
25
|
+
|
|
26
|
+
# ID of the workflow that this session is associated with
|
|
27
|
+
workflow_id: Optional[str] = None
|
|
28
|
+
# Workflow name
|
|
29
|
+
workflow_name: Optional[str] = None
|
|
30
|
+
|
|
31
|
+
# Workflow runs - stores WorkflowRunOutput objects in memory
|
|
32
|
+
runs: Optional[List[WorkflowRunOutput]] = None
|
|
33
|
+
|
|
34
|
+
# Session Data: session_name, session_state, images, videos, audio
|
|
35
|
+
session_data: Optional[Dict[str, Any]] = None
|
|
36
|
+
# Workflow configuration and metadata
|
|
37
|
+
workflow_data: Optional[Dict[str, Any]] = None
|
|
38
|
+
# Metadata stored with this workflow session
|
|
39
|
+
metadata: Optional[Dict[str, Any]] = None
|
|
40
|
+
|
|
41
|
+
# The unix timestamp when this session was created
|
|
42
|
+
created_at: Optional[int] = None
|
|
43
|
+
# The unix timestamp when this session was last updated
|
|
44
|
+
updated_at: Optional[int] = None
|
|
45
|
+
|
|
46
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
47
|
+
"""Convert to dictionary for storage, serializing runs to dicts"""
|
|
48
|
+
|
|
49
|
+
runs_data = None
|
|
50
|
+
if self.runs:
|
|
51
|
+
runs_data = []
|
|
52
|
+
for run in self.runs:
|
|
53
|
+
try:
|
|
54
|
+
runs_data.append(run.to_dict())
|
|
55
|
+
except Exception as e:
|
|
56
|
+
raise ValueError(f"Serialization failed: {str(e)}")
|
|
57
|
+
|
|
58
|
+
return {
|
|
59
|
+
"session_id": self.session_id,
|
|
60
|
+
"user_id": self.user_id,
|
|
61
|
+
"workflow_id": self.workflow_id,
|
|
62
|
+
"workflow_name": self.workflow_name,
|
|
63
|
+
"runs": runs_data,
|
|
64
|
+
"session_data": self.session_data,
|
|
65
|
+
"workflow_data": self.workflow_data,
|
|
66
|
+
"metadata": self.metadata,
|
|
67
|
+
"created_at": self.created_at,
|
|
68
|
+
"updated_at": self.updated_at,
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
@classmethod
|
|
72
|
+
def from_dict(cls, data: Mapping[str, Any]) -> Optional[WorkflowSession]:
|
|
73
|
+
"""Create WorkflowSession from dictionary, deserializing runs from dicts"""
|
|
74
|
+
if data is None or data.get("session_id") is None:
|
|
75
|
+
logger.warning("WorkflowSession is missing session_id")
|
|
76
|
+
return None
|
|
77
|
+
|
|
78
|
+
# Deserialize runs from dictionaries back to WorkflowRunOutput objects
|
|
79
|
+
runs_data = data.get("runs")
|
|
80
|
+
runs: Optional[List[WorkflowRunOutput]] = None
|
|
81
|
+
|
|
82
|
+
if runs_data is not None:
|
|
83
|
+
runs = []
|
|
84
|
+
for run_item in runs_data:
|
|
85
|
+
if isinstance(run_item, WorkflowRunOutput):
|
|
86
|
+
# Already a WorkflowRunOutput object (from deserialize_session_json_fields)
|
|
87
|
+
runs.append(run_item)
|
|
88
|
+
elif isinstance(run_item, dict):
|
|
89
|
+
# Still a dictionary, needs to be converted
|
|
90
|
+
runs.append(WorkflowRunOutput.from_dict(run_item))
|
|
91
|
+
else:
|
|
92
|
+
logger.warning(f"Unexpected run item type: {type(run_item)}")
|
|
93
|
+
|
|
94
|
+
return cls(
|
|
95
|
+
session_id=data.get("session_id"), # type: ignore
|
|
96
|
+
user_id=data.get("user_id"),
|
|
97
|
+
workflow_id=data.get("workflow_id"),
|
|
98
|
+
workflow_name=data.get("workflow_name"),
|
|
99
|
+
runs=runs,
|
|
100
|
+
session_data=data.get("session_data"),
|
|
101
|
+
workflow_data=data.get("workflow_data"),
|
|
102
|
+
metadata=data.get("metadata"),
|
|
103
|
+
created_at=data.get("created_at"),
|
|
104
|
+
updated_at=data.get("updated_at"),
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
def __post_init__(self):
|
|
108
|
+
if self.runs is None:
|
|
109
|
+
self.runs = []
|
|
110
|
+
|
|
111
|
+
# Ensure session_data, workflow_data, and metadata are dictionaries, not None
|
|
112
|
+
if self.session_data is None:
|
|
113
|
+
self.session_data = {}
|
|
114
|
+
if self.workflow_data is None:
|
|
115
|
+
self.workflow_data = {}
|
|
116
|
+
if self.metadata is None:
|
|
117
|
+
self.metadata = {}
|
|
118
|
+
|
|
119
|
+
# Set timestamps if they're not already set
|
|
120
|
+
current_time = int(time.time())
|
|
121
|
+
if self.created_at is None:
|
|
122
|
+
self.created_at = current_time
|
|
123
|
+
if self.updated_at is None:
|
|
124
|
+
self.updated_at = current_time
|
|
125
|
+
|
|
126
|
+
def get_run(self, run_id: str) -> Optional[WorkflowRunOutput]:
|
|
127
|
+
for run in self.runs or []:
|
|
128
|
+
if run.run_id == run_id:
|
|
129
|
+
return run
|
|
130
|
+
return None
|
|
131
|
+
|
|
132
|
+
def upsert_run(self, run: WorkflowRunOutput) -> None:
|
|
133
|
+
"""Add or update a workflow run (upsert behavior)"""
|
|
134
|
+
if self.runs is None:
|
|
135
|
+
self.runs = []
|
|
136
|
+
|
|
137
|
+
# Find existing run and update it, or append new one
|
|
138
|
+
for i, existing_run in enumerate(self.runs):
|
|
139
|
+
if existing_run.run_id == run.run_id:
|
|
140
|
+
self.runs[i] = run
|
|
141
|
+
break
|
|
142
|
+
else:
|
|
143
|
+
self.runs.append(run)
|
|
144
|
+
|
|
145
|
+
def get_workflow_history(self, num_runs: Optional[int] = None) -> List[Tuple[str, str]]:
|
|
146
|
+
"""Get workflow history as structured data (input, response pairs)
|
|
147
|
+
|
|
148
|
+
Args:
|
|
149
|
+
num_runs: Number of recent runs to include. If None, returns all available history.
|
|
150
|
+
"""
|
|
151
|
+
if not self.runs:
|
|
152
|
+
return []
|
|
153
|
+
|
|
154
|
+
# Get completed runs only (exclude current/pending run)
|
|
155
|
+
completed_runs = [run for run in self.runs if run.status == RunStatus.completed]
|
|
156
|
+
|
|
157
|
+
if num_runs is not None and len(completed_runs) > num_runs:
|
|
158
|
+
recent_runs = completed_runs[-num_runs:]
|
|
159
|
+
else:
|
|
160
|
+
recent_runs = completed_runs
|
|
161
|
+
|
|
162
|
+
if not recent_runs:
|
|
163
|
+
return []
|
|
164
|
+
|
|
165
|
+
# Return structured data as list of (input, response) tuples
|
|
166
|
+
history_data = []
|
|
167
|
+
for run in recent_runs:
|
|
168
|
+
# Get input
|
|
169
|
+
input_str = ""
|
|
170
|
+
if run.input:
|
|
171
|
+
input_str = str(run.input) if not isinstance(run.input, str) else run.input
|
|
172
|
+
|
|
173
|
+
# Get response
|
|
174
|
+
response_str = ""
|
|
175
|
+
if run.content:
|
|
176
|
+
response_str = str(run.content) if not isinstance(run.content, str) else run.content
|
|
177
|
+
|
|
178
|
+
history_data.append((input_str, response_str))
|
|
179
|
+
|
|
180
|
+
return history_data
|
|
181
|
+
|
|
182
|
+
def get_workflow_history_context(self, num_runs: Optional[int] = None) -> Optional[str]:
|
|
183
|
+
"""Get formatted workflow history context for steps
|
|
184
|
+
|
|
185
|
+
Args:
|
|
186
|
+
num_runs: Number of recent runs to include. If None, returns all available history.
|
|
187
|
+
"""
|
|
188
|
+
history_data = self.get_workflow_history(num_runs)
|
|
189
|
+
|
|
190
|
+
if not history_data:
|
|
191
|
+
return None
|
|
192
|
+
|
|
193
|
+
# Format as workflow context using the structured data
|
|
194
|
+
context_parts = ["<workflow_history_context>"]
|
|
195
|
+
|
|
196
|
+
for i, (input_str, response_str) in enumerate(history_data, 1):
|
|
197
|
+
context_parts.append(f"[Workflow Run-{i}]")
|
|
198
|
+
|
|
199
|
+
if input_str:
|
|
200
|
+
context_parts.append(f"User input: {input_str}")
|
|
201
|
+
if response_str:
|
|
202
|
+
context_parts.append(f"Workflow output: {response_str}")
|
|
203
|
+
|
|
204
|
+
context_parts.append("") # Empty line between runs
|
|
205
|
+
|
|
206
|
+
context_parts.append("</workflow_history_context>")
|
|
207
|
+
context_parts.append("") # Empty line before current input
|
|
208
|
+
|
|
209
|
+
return "\n".join(context_parts)
|
|
210
|
+
|
|
211
|
+
def get_messages_from_agent_runs(
|
|
212
|
+
self,
|
|
213
|
+
runs: List[RunOutput],
|
|
214
|
+
last_n_runs: Optional[int] = None,
|
|
215
|
+
limit: Optional[int] = None,
|
|
216
|
+
skip_roles: Optional[List[str]] = None,
|
|
217
|
+
skip_statuses: Optional[List[RunStatus]] = None,
|
|
218
|
+
skip_history_messages: bool = True,
|
|
219
|
+
) -> List[Message]:
|
|
220
|
+
"""Return the messages belonging to the given agent runs that fit the given criteria.
|
|
221
|
+
|
|
222
|
+
Args:
|
|
223
|
+
runs: The list of agent runs to get the messages from.
|
|
224
|
+
last_n_runs: Number of recent runs to include. If None, all runs will be considered.
|
|
225
|
+
limit: Number of messages to include. If None, all messages will be included.
|
|
226
|
+
skip_roles: Roles to skip.
|
|
227
|
+
skip_statuses: Statuses to skip.
|
|
228
|
+
skip_history_messages: Whether to skip history messages.
|
|
229
|
+
|
|
230
|
+
Returns:
|
|
231
|
+
A list of messages from the given agent runs.
|
|
232
|
+
"""
|
|
233
|
+
|
|
234
|
+
def _should_skip_message(
|
|
235
|
+
message: Message, skip_roles: Optional[List[str]] = None, skip_history_messages: bool = True
|
|
236
|
+
) -> bool:
|
|
237
|
+
"""Logic to determine if a message should be skipped"""
|
|
238
|
+
# Skip messages that were tagged as history in previous runs
|
|
239
|
+
if hasattr(message, "from_history") and message.from_history and skip_history_messages:
|
|
240
|
+
return True
|
|
241
|
+
|
|
242
|
+
# Skip messages with specified role
|
|
243
|
+
if skip_roles and message.role in skip_roles:
|
|
244
|
+
return True
|
|
245
|
+
|
|
246
|
+
return False
|
|
247
|
+
|
|
248
|
+
# Filter by status
|
|
249
|
+
if skip_statuses:
|
|
250
|
+
runs = [run for run in runs if hasattr(run, "status") and run.status not in skip_statuses] # type: ignore
|
|
251
|
+
|
|
252
|
+
messages_from_history = []
|
|
253
|
+
system_message = None
|
|
254
|
+
|
|
255
|
+
# Limit the number of messages returned if limit is set
|
|
256
|
+
if limit is not None:
|
|
257
|
+
for run_response in runs:
|
|
258
|
+
if not run_response or not run_response.messages:
|
|
259
|
+
continue
|
|
260
|
+
|
|
261
|
+
for message in run_response.messages or []:
|
|
262
|
+
if _should_skip_message(message, skip_roles, skip_history_messages):
|
|
263
|
+
continue
|
|
264
|
+
|
|
265
|
+
if message.role == "system":
|
|
266
|
+
# Only add the system message once
|
|
267
|
+
if system_message is None:
|
|
268
|
+
system_message = message
|
|
269
|
+
else:
|
|
270
|
+
messages_from_history.append(message)
|
|
271
|
+
|
|
272
|
+
if system_message:
|
|
273
|
+
messages_from_history = [system_message] + messages_from_history[
|
|
274
|
+
-(limit - 1) :
|
|
275
|
+
] # Grab one less message then add the system message
|
|
276
|
+
else:
|
|
277
|
+
messages_from_history = messages_from_history[-limit:]
|
|
278
|
+
|
|
279
|
+
# Remove tool result messages that don't have an associated assistant message with tool calls
|
|
280
|
+
while len(messages_from_history) > 0 and messages_from_history[0].role == "tool":
|
|
281
|
+
messages_from_history.pop(0)
|
|
282
|
+
|
|
283
|
+
# If limit is not set, return all messages
|
|
284
|
+
else:
|
|
285
|
+
runs_to_process = runs[-last_n_runs:] if last_n_runs is not None else runs
|
|
286
|
+
for run_response in runs_to_process:
|
|
287
|
+
if not run_response or not run_response.messages:
|
|
288
|
+
continue
|
|
289
|
+
|
|
290
|
+
for message in run_response.messages or []:
|
|
291
|
+
if _should_skip_message(message, skip_roles, skip_history_messages):
|
|
292
|
+
continue
|
|
293
|
+
|
|
294
|
+
if message.role == "system":
|
|
295
|
+
# Only add the system message once
|
|
296
|
+
if system_message is None:
|
|
297
|
+
system_message = message
|
|
298
|
+
messages_from_history.append(system_message)
|
|
299
|
+
else:
|
|
300
|
+
messages_from_history.append(message)
|
|
301
|
+
|
|
302
|
+
log_debug(f"Getting messages from previous runs: {len(messages_from_history)}")
|
|
303
|
+
return messages_from_history
|
|
304
|
+
|
|
305
|
+
def get_messages_from_team_runs(
|
|
306
|
+
self,
|
|
307
|
+
team_id: str,
|
|
308
|
+
runs: List[TeamRunOutput],
|
|
309
|
+
last_n_runs: Optional[int] = None,
|
|
310
|
+
limit: Optional[int] = None,
|
|
311
|
+
skip_roles: Optional[List[str]] = None,
|
|
312
|
+
skip_statuses: Optional[List[RunStatus]] = None,
|
|
313
|
+
skip_history_messages: bool = True,
|
|
314
|
+
skip_member_messages: bool = True,
|
|
315
|
+
) -> List[Message]:
|
|
316
|
+
"""Return the messages in the given team runs that fit the given criteria.
|
|
317
|
+
|
|
318
|
+
Args:
|
|
319
|
+
team_id: The ID of the contextual team.
|
|
320
|
+
runs: The list of team runs to get the messages from.
|
|
321
|
+
last_n_runs: Number of recent runs to include. If None, all runs will be considered.
|
|
322
|
+
limit: Number of messages to include. If None, all messages will be included.
|
|
323
|
+
skip_roles: Roles to skip.
|
|
324
|
+
skip_statuses: Statuses to skip.
|
|
325
|
+
skip_history_messages: Whether to skip history messages.
|
|
326
|
+
skip_member_messages: Whether to skip messages from members of the team.
|
|
327
|
+
|
|
328
|
+
Returns:
|
|
329
|
+
A list of messages from the given team runs.
|
|
330
|
+
"""
|
|
331
|
+
|
|
332
|
+
def _should_skip_message(
|
|
333
|
+
message: Message, skip_roles: Optional[List[str]] = None, skip_history_messages: bool = True
|
|
334
|
+
) -> bool:
|
|
335
|
+
"""Logic to determine if a message should be skipped"""
|
|
336
|
+
# Skip messages that were tagged as history in previous runs
|
|
337
|
+
if hasattr(message, "from_history") and message.from_history and skip_history_messages:
|
|
338
|
+
return True
|
|
339
|
+
|
|
340
|
+
# Skip messages with specified role
|
|
341
|
+
if skip_roles and message.role in skip_roles:
|
|
342
|
+
return True
|
|
343
|
+
|
|
344
|
+
return False
|
|
345
|
+
|
|
346
|
+
# Filter for top-level runs (main team runs or agent runs when sharing session)
|
|
347
|
+
if skip_member_messages:
|
|
348
|
+
session_runs = [run for run in runs if run.team_id == team_id]
|
|
349
|
+
|
|
350
|
+
# Filter runs by status
|
|
351
|
+
if skip_statuses:
|
|
352
|
+
session_runs = [run for run in session_runs if hasattr(run, "status") and run.status not in skip_statuses]
|
|
353
|
+
|
|
354
|
+
messages_from_history = []
|
|
355
|
+
system_message = None
|
|
356
|
+
|
|
357
|
+
# Limit the number of messages returned if limit is set
|
|
358
|
+
if limit is not None:
|
|
359
|
+
for run_response in session_runs:
|
|
360
|
+
if not run_response or not run_response.messages:
|
|
361
|
+
continue
|
|
362
|
+
|
|
363
|
+
for message in run_response.messages or []:
|
|
364
|
+
if _should_skip_message(message, skip_roles, skip_history_messages):
|
|
365
|
+
continue
|
|
366
|
+
|
|
367
|
+
if message.role == "system":
|
|
368
|
+
# Only add the system message once
|
|
369
|
+
if system_message is None:
|
|
370
|
+
system_message = message
|
|
371
|
+
else:
|
|
372
|
+
messages_from_history.append(message)
|
|
373
|
+
|
|
374
|
+
if system_message:
|
|
375
|
+
messages_from_history = [system_message] + messages_from_history[
|
|
376
|
+
-(limit - 1) :
|
|
377
|
+
] # Grab one less message then add the system message
|
|
378
|
+
else:
|
|
379
|
+
messages_from_history = messages_from_history[-limit:]
|
|
380
|
+
|
|
381
|
+
# Remove tool result messages that don't have an associated assistant message with tool calls
|
|
382
|
+
while len(messages_from_history) > 0 and messages_from_history[0].role == "tool":
|
|
383
|
+
messages_from_history.pop(0)
|
|
384
|
+
else:
|
|
385
|
+
# Filter by last_n runs
|
|
386
|
+
runs_to_process = session_runs[-last_n_runs:] if last_n_runs is not None else session_runs
|
|
387
|
+
|
|
388
|
+
for run_response in runs_to_process:
|
|
389
|
+
if not (run_response and run_response.messages):
|
|
390
|
+
continue
|
|
391
|
+
|
|
392
|
+
for message in run_response.messages or []:
|
|
393
|
+
if _should_skip_message(message, skip_roles, skip_history_messages):
|
|
394
|
+
continue
|
|
395
|
+
|
|
396
|
+
if message.role == "system":
|
|
397
|
+
# Only add the system message once
|
|
398
|
+
if system_message is None:
|
|
399
|
+
system_message = message
|
|
400
|
+
messages_from_history.append(system_message)
|
|
401
|
+
else:
|
|
402
|
+
messages_from_history.append(message)
|
|
403
|
+
|
|
404
|
+
log_debug(f"Getting messages from previous runs: {len(messages_from_history)}")
|
|
405
|
+
return messages_from_history
|
|
406
|
+
|
|
407
|
+
def get_messages(
|
|
408
|
+
self,
|
|
409
|
+
agent_id: Optional[str] = None,
|
|
410
|
+
team_id: Optional[str] = None,
|
|
411
|
+
last_n_runs: Optional[int] = None,
|
|
412
|
+
limit: Optional[int] = None,
|
|
413
|
+
skip_roles: Optional[List[str]] = None,
|
|
414
|
+
skip_statuses: Optional[List[RunStatus]] = None,
|
|
415
|
+
skip_history_messages: bool = True,
|
|
416
|
+
skip_member_messages: bool = True,
|
|
417
|
+
) -> List[Message]:
|
|
418
|
+
"""Return the messages belonging to the session that fit the given criteria.
|
|
419
|
+
|
|
420
|
+
Args:
|
|
421
|
+
agent_id: The ID of the agent to get the messages for.
|
|
422
|
+
team_id: The ID of the team to get the messages for.
|
|
423
|
+
last_n_runs: Number of recent runs to include. If None, all runs will be considered.
|
|
424
|
+
limit: Number of messages to include. If None, all messages will be included.
|
|
425
|
+
skip_roles: Roles to skip.
|
|
426
|
+
skip_statuses: Statuses to skip.
|
|
427
|
+
skip_history_messages: Whether to skip history messages.
|
|
428
|
+
skip_member_messages: Whether to skip messages from members of the team.
|
|
429
|
+
|
|
430
|
+
Returns:
|
|
431
|
+
A list of messages from the session.
|
|
432
|
+
"""
|
|
433
|
+
if agent_id and team_id:
|
|
434
|
+
raise ValueError("agent_id and team_id cannot be used together")
|
|
435
|
+
|
|
436
|
+
if not self.runs:
|
|
437
|
+
return []
|
|
438
|
+
|
|
439
|
+
if agent_id:
|
|
440
|
+
agent_runs: List[RunOutput] = []
|
|
441
|
+
for run in self.runs:
|
|
442
|
+
if run.step_executor_runs:
|
|
443
|
+
for executor_run in run.step_executor_runs:
|
|
444
|
+
if isinstance(executor_run, RunOutput) and executor_run.agent_id == agent_id:
|
|
445
|
+
agent_runs.append(executor_run)
|
|
446
|
+
return self.get_messages_from_agent_runs(
|
|
447
|
+
runs=agent_runs,
|
|
448
|
+
last_n_runs=last_n_runs,
|
|
449
|
+
limit=limit,
|
|
450
|
+
skip_roles=skip_roles,
|
|
451
|
+
skip_statuses=skip_statuses,
|
|
452
|
+
skip_history_messages=skip_history_messages,
|
|
453
|
+
)
|
|
454
|
+
|
|
455
|
+
elif team_id:
|
|
456
|
+
team_runs: List[TeamRunOutput] = []
|
|
457
|
+
for run in self.runs:
|
|
458
|
+
if run.step_executor_runs:
|
|
459
|
+
for executor_run in run.step_executor_runs:
|
|
460
|
+
if isinstance(executor_run, TeamRunOutput) and executor_run.team_id == team_id:
|
|
461
|
+
team_runs.append(executor_run)
|
|
462
|
+
return self.get_messages_from_team_runs(
|
|
463
|
+
team_id=team_id,
|
|
464
|
+
runs=team_runs,
|
|
465
|
+
last_n_runs=last_n_runs,
|
|
466
|
+
limit=limit,
|
|
467
|
+
skip_roles=skip_roles,
|
|
468
|
+
skip_statuses=skip_statuses,
|
|
469
|
+
skip_history_messages=skip_history_messages,
|
|
470
|
+
skip_member_messages=skip_member_messages,
|
|
471
|
+
)
|
|
472
|
+
|
|
473
|
+
else:
|
|
474
|
+
raise ValueError("agent_id or team_id must be provided")
|
|
475
|
+
|
|
476
|
+
def get_chat_history(self, last_n_runs: Optional[int] = None) -> List[WorkflowChatInteraction]:
|
|
477
|
+
"""Return a list of dictionaries containing the input and output for each run in the session.
|
|
478
|
+
|
|
479
|
+
Args:
|
|
480
|
+
last_n_runs: Number of recent runs to include. If None, all runs will be considered.
|
|
481
|
+
|
|
482
|
+
Returns:
|
|
483
|
+
A list of WorkflowChatInteraction objects.
|
|
484
|
+
"""
|
|
485
|
+
if not self.runs:
|
|
486
|
+
return []
|
|
487
|
+
|
|
488
|
+
runs = self.runs
|
|
489
|
+
|
|
490
|
+
if last_n_runs is not None:
|
|
491
|
+
runs = self.runs[-last_n_runs:]
|
|
492
|
+
|
|
493
|
+
return [
|
|
494
|
+
WorkflowChatInteraction(input=run.input, output=run.content) for run in runs if run.input and run.content
|
|
495
|
+
]
|
|
496
|
+
|
|
497
|
+
|
|
498
|
+
@dataclass
|
|
499
|
+
class WorkflowChatInteraction:
|
|
500
|
+
input: Union[str, Dict[str, Any], List[Any], BaseModel]
|
|
501
|
+
output: Any
|
agno/table.py
ADDED
agno/team/__init__.py
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
from agno.run.team import (
|
|
2
|
+
MemoryUpdateCompletedEvent,
|
|
3
|
+
MemoryUpdateStartedEvent,
|
|
4
|
+
ReasoningCompletedEvent,
|
|
5
|
+
ReasoningStartedEvent,
|
|
6
|
+
ReasoningStepEvent,
|
|
7
|
+
RunCancelledEvent,
|
|
8
|
+
RunCompletedEvent,
|
|
9
|
+
RunContentEvent,
|
|
10
|
+
RunErrorEvent,
|
|
11
|
+
RunStartedEvent,
|
|
12
|
+
TeamRunEvent,
|
|
13
|
+
TeamRunOutput,
|
|
14
|
+
TeamRunOutputEvent,
|
|
15
|
+
ToolCallCompletedEvent,
|
|
16
|
+
ToolCallStartedEvent,
|
|
17
|
+
)
|
|
18
|
+
from agno.team.team import Team
|
|
19
|
+
|
|
20
|
+
__all__ = [
|
|
21
|
+
"Team",
|
|
22
|
+
"TeamRunOutput",
|
|
23
|
+
"TeamRunOutputEvent",
|
|
24
|
+
"TeamRunEvent",
|
|
25
|
+
"RunContentEvent",
|
|
26
|
+
"RunCancelledEvent",
|
|
27
|
+
"RunErrorEvent",
|
|
28
|
+
"RunStartedEvent",
|
|
29
|
+
"RunCompletedEvent",
|
|
30
|
+
"MemoryUpdateStartedEvent",
|
|
31
|
+
"MemoryUpdateCompletedEvent",
|
|
32
|
+
"ReasoningStartedEvent",
|
|
33
|
+
"ReasoningStepEvent",
|
|
34
|
+
"ReasoningCompletedEvent",
|
|
35
|
+
"ToolCallStartedEvent",
|
|
36
|
+
"ToolCallCompletedEvent",
|
|
37
|
+
]
|