agno 1.8.0__py3-none-any.whl → 2.0.0a1__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 +2781 -4126
- agno/api/agent.py +9 -65
- agno/api/api.py +5 -46
- agno/api/evals.py +6 -17
- 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 +9 -64
- 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 +1749 -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 +1438 -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 +888 -0
- agno/db/in_memory/utils.py +172 -0
- agno/db/json/__init__.py +3 -0
- agno/db/json/json_db.py +1051 -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 +1417 -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 +298 -0
- agno/db/postgres/__init__.py +3 -0
- agno/db/postgres/postgres.py +1720 -0
- agno/db/postgres/schemas.py +124 -0
- agno/db/postgres/utils.py +281 -0
- agno/db/redis/__init__.py +3 -0
- agno/db/redis/redis.py +1371 -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 +1722 -0
- agno/db/singlestore/utils.py +327 -0
- agno/db/sqlite/__init__.py +3 -0
- agno/db/sqlite/schemas.py +119 -0
- agno/db/sqlite/sqlite.py +1680 -0
- agno/db/sqlite/utils.py +269 -0
- agno/db/utils.py +88 -0
- agno/eval/__init__.py +14 -0
- agno/eval/accuracy.py +142 -43
- agno/eval/performance.py +88 -23
- agno/eval/reliability.py +73 -20
- agno/eval/utils.py +23 -13
- agno/integrations/discord/__init__.py +3 -0
- agno/{app → integrations}/discord/client.py +10 -10
- agno/knowledge/__init__.py +2 -2
- agno/{document → knowledge}/chunking/agentic.py +2 -2
- agno/{document → knowledge}/chunking/document.py +2 -2
- agno/{document → knowledge}/chunking/fixed.py +3 -3
- agno/{document → knowledge}/chunking/markdown.py +2 -2
- agno/{document → knowledge}/chunking/recursive.py +2 -2
- agno/{document → knowledge}/chunking/row.py +2 -2
- agno/knowledge/chunking/semantic.py +59 -0
- agno/knowledge/chunking/strategy.py +121 -0
- agno/knowledge/content.py +74 -0
- agno/knowledge/document/__init__.py +5 -0
- agno/{document → knowledge/document}/base.py +12 -2
- agno/knowledge/embedder/__init__.py +5 -0
- agno/{embedder → knowledge/embedder}/aws_bedrock.py +127 -1
- agno/{embedder → knowledge/embedder}/azure_openai.py +65 -1
- agno/{embedder → knowledge/embedder}/base.py +6 -0
- agno/{embedder → knowledge/embedder}/cohere.py +72 -1
- agno/{embedder → knowledge/embedder}/fastembed.py +17 -1
- agno/{embedder → knowledge/embedder}/fireworks.py +1 -1
- agno/{embedder → knowledge/embedder}/google.py +74 -1
- agno/{embedder → knowledge/embedder}/huggingface.py +36 -2
- agno/{embedder → knowledge/embedder}/jina.py +48 -2
- agno/knowledge/embedder/langdb.py +22 -0
- agno/knowledge/embedder/mistral.py +139 -0
- agno/{embedder → knowledge/embedder}/nebius.py +1 -1
- agno/{embedder → knowledge/embedder}/ollama.py +54 -3
- agno/knowledge/embedder/openai.py +223 -0
- agno/{embedder → knowledge/embedder}/sentence_transformer.py +16 -1
- agno/{embedder → knowledge/embedder}/together.py +1 -1
- agno/{embedder → knowledge/embedder}/voyageai.py +49 -1
- agno/knowledge/knowledge.py +1515 -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 +68 -15
- agno/knowledge/reader/docx_reader.py +83 -0
- agno/{document → knowledge}/reader/firecrawl_reader.py +42 -21
- agno/knowledge/reader/gcs_reader.py +67 -0
- agno/{document → knowledge}/reader/json_reader.py +30 -9
- agno/{document → knowledge}/reader/markdown_reader.py +36 -9
- agno/{document → knowledge}/reader/pdf_reader.py +79 -21
- agno/knowledge/reader/reader_factory.py +275 -0
- agno/knowledge/reader/s3_reader.py +171 -0
- agno/{document → knowledge}/reader/text_reader.py +31 -10
- agno/knowledge/reader/url_reader.py +84 -0
- agno/knowledge/reader/web_search_reader.py +389 -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 +2 -2
- 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 +129 -82
- agno/models/aws/bedrock.py +107 -175
- agno/models/aws/claude.py +64 -18
- agno/models/azure/ai_foundry.py +73 -23
- agno/models/base.py +347 -287
- agno/models/cerebras/cerebras.py +84 -27
- agno/models/cohere/chat.py +106 -98
- agno/models/dashscope/dashscope.py +14 -5
- agno/models/google/gemini.py +123 -53
- 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 +38 -144
- 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 +84 -46
- agno/models/openai/chat.py +135 -27
- agno/models/openai/responses.py +233 -115
- agno/models/perplexity/perplexity.py +26 -2
- agno/models/portkey/portkey.py +0 -7
- agno/models/response.py +14 -8
- 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 +393 -0
- agno/os/auth.py +47 -0
- agno/os/config.py +103 -0
- agno/os/interfaces/agui/__init__.py +3 -0
- agno/os/interfaces/agui/agui.py +31 -0
- agno/{app/agui/async_router.py → os/interfaces/agui/router.py} +16 -16
- agno/{app → os/interfaces}/agui/utils.py +65 -28
- agno/os/interfaces/base.py +21 -0
- agno/os/interfaces/slack/__init__.py +3 -0
- agno/{app/slack/async_router.py → os/interfaces/slack/router.py} +3 -5
- agno/os/interfaces/slack/slack.py +33 -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 +30 -0
- agno/os/router.py +843 -0
- agno/os/routers/__init__.py +3 -0
- agno/os/routers/evals/__init__.py +3 -0
- agno/os/routers/evals/evals.py +204 -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 +413 -0
- agno/os/routers/knowledge/schemas.py +118 -0
- agno/os/routers/memory/__init__.py +3 -0
- agno/os/routers/memory/memory.py +179 -0
- agno/os/routers/memory/schemas.py +58 -0
- agno/os/routers/metrics/__init__.py +3 -0
- agno/os/routers/metrics/metrics.py +58 -0
- agno/os/routers/metrics/schemas.py +47 -0
- agno/os/routers/session/__init__.py +3 -0
- agno/os/routers/session/session.py +163 -0
- agno/os/schema.py +892 -0
- agno/{app/playground → os}/settings.py +8 -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/{response.py → agent.py} +144 -72
- agno/run/base.py +44 -58
- agno/run/cancel.py +83 -0
- agno/run/team.py +133 -77
- agno/run/workflow.py +537 -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 +2967 -4243
- 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 +42 -22
- agno/tools/browserbase.py +13 -4
- agno/tools/calcom.py +12 -10
- agno/tools/calculator.py +10 -27
- agno/tools/cartesia.py +18 -13
- agno/tools/{clickup_tool.py → clickup.py} +12 -25
- agno/tools/confluence.py +71 -18
- agno/tools/crawl4ai.py +7 -1
- agno/tools/csv_toolkit.py +9 -8
- agno/tools/dalle.py +18 -11
- agno/tools/daytona.py +13 -16
- agno/tools/decorator.py +6 -3
- agno/tools/desi_vocal.py +16 -7
- 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 +35 -28
- agno/tools/email.py +4 -1
- agno/tools/evm.py +7 -1
- agno/tools/exa.py +19 -14
- agno/tools/fal.py +29 -29
- agno/tools/file.py +9 -8
- agno/tools/financial_datasets.py +25 -44
- agno/tools/firecrawl.py +22 -22
- agno/tools/function.py +68 -17
- agno/tools/giphy.py +22 -10
- agno/tools/github.py +48 -126
- agno/tools/gmail.py +46 -62
- agno/tools/google_bigquery.py +7 -6
- agno/tools/google_maps.py +11 -26
- agno/tools/googlesearch.py +7 -2
- agno/tools/googlesheets.py +21 -17
- agno/tools/hackernews.py +9 -5
- agno/tools/jina.py +5 -4
- agno/tools/jira.py +18 -9
- agno/tools/knowledge.py +31 -32
- agno/tools/linear.py +18 -33
- agno/tools/linkup.py +5 -1
- agno/tools/local_file_system.py +8 -5
- agno/tools/lumalab.py +31 -19
- 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 +32 -14
- agno/tools/models/gemini.py +58 -31
- agno/tools/models/groq.py +29 -20
- agno/tools/models/nebius.py +27 -11
- agno/tools/models_labs.py +39 -15
- agno/tools/moviepy_video.py +7 -6
- agno/tools/neo4j.py +134 -0
- agno/tools/newspaper.py +7 -2
- agno/tools/newspaper4k.py +8 -3
- agno/tools/openai.py +57 -26
- agno/tools/openbb.py +12 -11
- agno/tools/opencv.py +62 -46
- 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 +54 -41
- 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 +95 -118
- agno/utils/knowledge.py +29 -0
- agno/utils/location.py +2 -2
- agno/utils/log.py +2 -2
- agno/utils/mcp.py +11 -5
- agno/utils/media.py +39 -0
- agno/utils/message.py +12 -1
- agno/utils/models/claude.py +6 -4
- agno/utils/models/mistral.py +8 -7
- agno/utils/models/schema_utils.py +3 -3
- agno/utils/pprint.py +33 -32
- agno/utils/print_response/agent.py +779 -0
- agno/utils/print_response/team.py +1565 -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/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 +356 -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} +200 -42
- agno/workflow/{v2/steps.py → steps.py} +147 -66
- agno/workflow/types.py +482 -0
- agno/workflow/workflow.py +2394 -696
- agno-2.0.0a1.dist-info/METADATA +355 -0
- agno-2.0.0a1.dist-info/RECORD +514 -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 -698
- 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/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.0.dist-info/METADATA +0 -979
- agno-1.8.0.dist-info/RECORD +0 -565
- agno-1.8.0.dist-info/entry_points.txt +0 -3
- /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.0.dist-info → agno-2.0.0a1.dist-info}/WHEEL +0 -0
- {agno-1.8.0.dist-info → agno-2.0.0a1.dist-info}/licenses/LICENSE +0 -0
- {agno-1.8.0.dist-info → agno-2.0.0a1.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from copy import deepcopy
|
|
3
|
+
from typing import List, Optional
|
|
4
|
+
|
|
5
|
+
from fastapi import APIRouter, Depends, HTTPException, Query
|
|
6
|
+
|
|
7
|
+
from agno.agent.agent import Agent
|
|
8
|
+
from agno.db.base import BaseDb
|
|
9
|
+
from agno.db.schemas.evals import EvalFilterType, EvalType
|
|
10
|
+
from agno.models.utils import get_model
|
|
11
|
+
from agno.os.auth import get_authentication_dependency
|
|
12
|
+
from agno.os.routers.evals.schemas import (
|
|
13
|
+
DeleteEvalRunsRequest,
|
|
14
|
+
EvalRunInput,
|
|
15
|
+
EvalSchema,
|
|
16
|
+
UpdateEvalRunRequest,
|
|
17
|
+
)
|
|
18
|
+
from agno.os.routers.evals.utils import run_accuracy_eval, run_performance_eval, run_reliability_eval
|
|
19
|
+
from agno.os.schema import PaginatedResponse, PaginationInfo, SortOrder
|
|
20
|
+
from agno.os.settings import AgnoAPISettings
|
|
21
|
+
from agno.os.utils import get_agent_by_id, get_db, get_team_by_id
|
|
22
|
+
from agno.team.team import Team
|
|
23
|
+
|
|
24
|
+
logger = logging.getLogger(__name__)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def get_eval_router(
|
|
28
|
+
dbs: dict[str, BaseDb],
|
|
29
|
+
agents: Optional[List[Agent]] = None,
|
|
30
|
+
teams: Optional[List[Team]] = None,
|
|
31
|
+
settings: AgnoAPISettings = AgnoAPISettings(),
|
|
32
|
+
) -> APIRouter:
|
|
33
|
+
router = APIRouter(dependencies=[Depends(get_authentication_dependency(settings))], tags=["Evals"])
|
|
34
|
+
return attach_routes(router=router, dbs=dbs, agents=agents, teams=teams)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def attach_routes(
|
|
38
|
+
router: APIRouter, dbs: dict[str, BaseDb], agents: Optional[List[Agent]] = None, teams: Optional[List[Team]] = None
|
|
39
|
+
) -> APIRouter:
|
|
40
|
+
@router.get("/eval-runs", response_model=PaginatedResponse[EvalSchema], status_code=200)
|
|
41
|
+
async def get_eval_runs(
|
|
42
|
+
agent_id: Optional[str] = Query(default=None, description="Agent ID"),
|
|
43
|
+
team_id: Optional[str] = Query(default=None, description="Team ID"),
|
|
44
|
+
workflow_id: Optional[str] = Query(default=None, description="Workflow ID"),
|
|
45
|
+
model_id: Optional[str] = Query(default=None, description="Model ID"),
|
|
46
|
+
filter_type: Optional[EvalFilterType] = Query(default=None, description="Filter type", alias="type"),
|
|
47
|
+
eval_types: Optional[List[EvalType]] = Depends(parse_eval_types_filter),
|
|
48
|
+
limit: Optional[int] = Query(default=20, description="Number of eval runs to return"),
|
|
49
|
+
page: Optional[int] = Query(default=1, description="Page number"),
|
|
50
|
+
sort_by: Optional[str] = Query(default="created_at", description="Field to sort by"),
|
|
51
|
+
sort_order: Optional[SortOrder] = Query(default="desc", description="Sort order (asc or desc)"),
|
|
52
|
+
db_id: Optional[str] = Query(default=None, description="The ID of the database to use"),
|
|
53
|
+
) -> PaginatedResponse[EvalSchema]:
|
|
54
|
+
db = get_db(dbs, db_id)
|
|
55
|
+
eval_runs, total_count = db.get_eval_runs(
|
|
56
|
+
limit=limit,
|
|
57
|
+
page=page,
|
|
58
|
+
sort_by=sort_by,
|
|
59
|
+
sort_order=sort_order,
|
|
60
|
+
agent_id=agent_id,
|
|
61
|
+
team_id=team_id,
|
|
62
|
+
workflow_id=workflow_id,
|
|
63
|
+
model_id=model_id,
|
|
64
|
+
eval_type=eval_types,
|
|
65
|
+
filter_type=filter_type,
|
|
66
|
+
deserialize=False,
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
return PaginatedResponse(
|
|
70
|
+
data=[EvalSchema.from_dict(eval_run) for eval_run in eval_runs], # type: ignore
|
|
71
|
+
meta=PaginationInfo(
|
|
72
|
+
page=page,
|
|
73
|
+
limit=limit,
|
|
74
|
+
total_count=total_count, # type: ignore
|
|
75
|
+
total_pages=(total_count + limit - 1) // limit if limit is not None and limit > 0 else 0, # type: ignore
|
|
76
|
+
),
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
@router.get("/eval-runs/{eval_run_id}", response_model=EvalSchema, status_code=200)
|
|
80
|
+
async def get_eval_run(
|
|
81
|
+
eval_run_id: str,
|
|
82
|
+
db_id: Optional[str] = Query(default=None, description="The ID of the database to use"),
|
|
83
|
+
) -> EvalSchema:
|
|
84
|
+
db = get_db(dbs, db_id)
|
|
85
|
+
eval_run = db.get_eval_run(eval_run_id=eval_run_id, deserialize=False)
|
|
86
|
+
if not eval_run:
|
|
87
|
+
raise HTTPException(status_code=404, detail=f"Eval run with id '{eval_run_id}' not found")
|
|
88
|
+
|
|
89
|
+
return EvalSchema.from_dict(eval_run) # type: ignore
|
|
90
|
+
|
|
91
|
+
@router.delete("/eval-runs", status_code=204)
|
|
92
|
+
async def delete_eval_runs(
|
|
93
|
+
request: DeleteEvalRunsRequest,
|
|
94
|
+
db_id: Optional[str] = Query(default=None, description="The ID of the database to use"),
|
|
95
|
+
) -> None:
|
|
96
|
+
try:
|
|
97
|
+
db = get_db(dbs, db_id)
|
|
98
|
+
db.delete_eval_runs(eval_run_ids=request.eval_run_ids)
|
|
99
|
+
except Exception as e:
|
|
100
|
+
raise HTTPException(status_code=500, detail=f"Failed to delete eval runs: {e}")
|
|
101
|
+
|
|
102
|
+
@router.patch("/eval-runs/{eval_run_id}", response_model=EvalSchema, status_code=200)
|
|
103
|
+
async def update_eval_run(
|
|
104
|
+
eval_run_id: str,
|
|
105
|
+
request: UpdateEvalRunRequest,
|
|
106
|
+
db_id: Optional[str] = Query(default=None, description="The ID of the database to use"),
|
|
107
|
+
) -> EvalSchema:
|
|
108
|
+
try:
|
|
109
|
+
db = get_db(dbs, db_id)
|
|
110
|
+
eval_run = db.rename_eval_run(eval_run_id=eval_run_id, name=request.name, deserialize=False)
|
|
111
|
+
except Exception as e:
|
|
112
|
+
raise HTTPException(status_code=500, detail=f"Failed to rename eval run: {e}")
|
|
113
|
+
|
|
114
|
+
if not eval_run:
|
|
115
|
+
raise HTTPException(status_code=404, detail=f"Eval run with id '{eval_run_id}' not found")
|
|
116
|
+
|
|
117
|
+
return EvalSchema.from_dict(eval_run) # type: ignore
|
|
118
|
+
|
|
119
|
+
@router.post("/eval-runs", response_model=EvalSchema, status_code=200)
|
|
120
|
+
async def run_eval(
|
|
121
|
+
eval_run_input: EvalRunInput,
|
|
122
|
+
db_id: Optional[str] = Query(default=None, description="The ID of the database to use"),
|
|
123
|
+
) -> Optional[EvalSchema]:
|
|
124
|
+
db = get_db(dbs, db_id)
|
|
125
|
+
|
|
126
|
+
if eval_run_input.agent_id and eval_run_input.team_id:
|
|
127
|
+
raise HTTPException(status_code=400, detail="Only one of agent_id or team_id must be provided")
|
|
128
|
+
|
|
129
|
+
if eval_run_input.agent_id:
|
|
130
|
+
agent = get_agent_by_id(agent_id=eval_run_input.agent_id, agents=agents)
|
|
131
|
+
if not agent:
|
|
132
|
+
raise HTTPException(status_code=404, detail=f"Agent with id '{eval_run_input.agent_id}' not found")
|
|
133
|
+
|
|
134
|
+
default_model = None
|
|
135
|
+
if (
|
|
136
|
+
hasattr(agent, "model")
|
|
137
|
+
and agent.model is not None
|
|
138
|
+
and eval_run_input.model_id is not None
|
|
139
|
+
and eval_run_input.model_provider is not None
|
|
140
|
+
):
|
|
141
|
+
default_model = deepcopy(agent.model)
|
|
142
|
+
if eval_run_input.model_id != agent.model.id or eval_run_input.model_provider != agent.model.provider:
|
|
143
|
+
model = get_model(
|
|
144
|
+
model_id=eval_run_input.model_id.lower(),
|
|
145
|
+
model_provider=eval_run_input.model_provider.lower(),
|
|
146
|
+
)
|
|
147
|
+
agent.model = model
|
|
148
|
+
|
|
149
|
+
team = None
|
|
150
|
+
|
|
151
|
+
elif eval_run_input.team_id:
|
|
152
|
+
team = get_team_by_id(team_id=eval_run_input.team_id, teams=teams)
|
|
153
|
+
if not team:
|
|
154
|
+
raise HTTPException(status_code=404, detail=f"Team with id '{eval_run_input.team_id}' not found")
|
|
155
|
+
|
|
156
|
+
default_model = None
|
|
157
|
+
if (
|
|
158
|
+
hasattr(team, "model")
|
|
159
|
+
and team.model is not None
|
|
160
|
+
and eval_run_input.model_id is not None
|
|
161
|
+
and eval_run_input.model_provider is not None
|
|
162
|
+
):
|
|
163
|
+
default_model = deepcopy(team.model)
|
|
164
|
+
if eval_run_input.model_id != team.model.id or eval_run_input.model_provider != team.model.provider:
|
|
165
|
+
model = get_model(
|
|
166
|
+
model_id=eval_run_input.model_id.lower(),
|
|
167
|
+
model_provider=eval_run_input.model_provider.lower(),
|
|
168
|
+
)
|
|
169
|
+
team.model = model
|
|
170
|
+
|
|
171
|
+
agent = None
|
|
172
|
+
|
|
173
|
+
else:
|
|
174
|
+
raise HTTPException(status_code=400, detail="One of agent_id or team_id must be provided")
|
|
175
|
+
|
|
176
|
+
# Run the evaluation
|
|
177
|
+
if eval_run_input.eval_type == EvalType.ACCURACY:
|
|
178
|
+
return await run_accuracy_eval(
|
|
179
|
+
eval_run_input=eval_run_input, db=db, agent=agent, team=team, default_model=default_model
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
elif eval_run_input.eval_type == EvalType.PERFORMANCE:
|
|
183
|
+
return await run_performance_eval(
|
|
184
|
+
eval_run_input=eval_run_input, db=db, agent=agent, team=team, default_model=default_model
|
|
185
|
+
)
|
|
186
|
+
|
|
187
|
+
else:
|
|
188
|
+
return await run_reliability_eval(
|
|
189
|
+
eval_run_input=eval_run_input, db=db, agent=agent, team=team, default_model=default_model
|
|
190
|
+
)
|
|
191
|
+
|
|
192
|
+
return router
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
def parse_eval_types_filter(
|
|
196
|
+
eval_types: Optional[str] = Query(default=None, description="Comma-separated eval types"),
|
|
197
|
+
) -> Optional[List[EvalType]]:
|
|
198
|
+
"""Parse a comma-separated string of eval types into a list of EvalType enums"""
|
|
199
|
+
if not eval_types:
|
|
200
|
+
return None
|
|
201
|
+
try:
|
|
202
|
+
return [EvalType(item.strip()) for item in eval_types.split(",")]
|
|
203
|
+
except ValueError as e:
|
|
204
|
+
raise HTTPException(status_code=422, detail=f"Invalid eval_type: {e}")
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
from dataclasses import asdict
|
|
2
|
+
from datetime import datetime, timezone
|
|
3
|
+
from typing import Any, Dict, List, Optional
|
|
4
|
+
|
|
5
|
+
from pydantic import BaseModel
|
|
6
|
+
|
|
7
|
+
from agno.db.schemas.evals import EvalType
|
|
8
|
+
from agno.eval import AccuracyResult, PerformanceResult, ReliabilityResult
|
|
9
|
+
from agno.eval.accuracy import AccuracyEval
|
|
10
|
+
from agno.eval.performance import PerformanceEval
|
|
11
|
+
from agno.eval.reliability import ReliabilityEval
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class EvalRunInput(BaseModel):
|
|
15
|
+
agent_id: Optional[str] = None
|
|
16
|
+
team_id: Optional[str] = None
|
|
17
|
+
|
|
18
|
+
model_id: Optional[str] = None
|
|
19
|
+
model_provider: Optional[str] = None
|
|
20
|
+
eval_type: EvalType
|
|
21
|
+
input: str
|
|
22
|
+
additional_guidelines: Optional[str] = None
|
|
23
|
+
additional_context: Optional[str] = None
|
|
24
|
+
num_iterations: Optional[int] = 1
|
|
25
|
+
name: Optional[str] = None
|
|
26
|
+
|
|
27
|
+
# Accuracy eval specific fields
|
|
28
|
+
expected_output: Optional[str] = None
|
|
29
|
+
|
|
30
|
+
# Performance eval specific fields
|
|
31
|
+
warmup_runs: Optional[int] = 0
|
|
32
|
+
|
|
33
|
+
# Reliability eval specific fields
|
|
34
|
+
expected_tool_calls: Optional[List[str]] = None
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class EvalSchema(BaseModel):
|
|
38
|
+
id: str
|
|
39
|
+
|
|
40
|
+
agent_id: Optional[str] = None
|
|
41
|
+
model_id: Optional[str] = None
|
|
42
|
+
model_provider: Optional[str] = None
|
|
43
|
+
team_id: Optional[str] = None
|
|
44
|
+
workflow_id: Optional[str] = None
|
|
45
|
+
name: Optional[str] = None
|
|
46
|
+
evaluated_component_name: Optional[str] = None
|
|
47
|
+
eval_type: EvalType
|
|
48
|
+
eval_data: Dict[str, Any]
|
|
49
|
+
eval_input: Optional[Dict[str, Any]] = None
|
|
50
|
+
created_at: Optional[datetime] = None
|
|
51
|
+
updated_at: Optional[datetime] = None
|
|
52
|
+
|
|
53
|
+
@classmethod
|
|
54
|
+
def from_dict(cls, eval_run: Dict[str, Any]) -> "EvalSchema":
|
|
55
|
+
return cls(
|
|
56
|
+
id=eval_run["run_id"],
|
|
57
|
+
name=eval_run.get("name"),
|
|
58
|
+
agent_id=eval_run.get("agent_id"),
|
|
59
|
+
model_id=eval_run.get("model_id"),
|
|
60
|
+
model_provider=eval_run.get("model_provider"),
|
|
61
|
+
team_id=eval_run.get("team_id"),
|
|
62
|
+
workflow_id=eval_run.get("workflow_id"),
|
|
63
|
+
evaluated_component_name=eval_run.get("evaluated_component_name"),
|
|
64
|
+
eval_type=eval_run["eval_type"],
|
|
65
|
+
eval_data=eval_run["eval_data"],
|
|
66
|
+
eval_input=eval_run.get("eval_input"),
|
|
67
|
+
created_at=datetime.fromtimestamp(eval_run["created_at"], tz=timezone.utc),
|
|
68
|
+
updated_at=datetime.fromtimestamp(eval_run["updated_at"], tz=timezone.utc),
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
@classmethod
|
|
72
|
+
def from_accuracy_eval(cls, accuracy_eval: AccuracyEval, result: AccuracyResult) -> "EvalSchema":
|
|
73
|
+
model_provider = (
|
|
74
|
+
accuracy_eval.agent.model.provider
|
|
75
|
+
if accuracy_eval.agent and accuracy_eval.agent.model
|
|
76
|
+
else accuracy_eval.team.model.provider
|
|
77
|
+
if accuracy_eval.team and accuracy_eval.team.model
|
|
78
|
+
else None
|
|
79
|
+
)
|
|
80
|
+
return cls(
|
|
81
|
+
id=accuracy_eval.eval_id,
|
|
82
|
+
name=accuracy_eval.name,
|
|
83
|
+
agent_id=accuracy_eval.agent.id if accuracy_eval.agent else None,
|
|
84
|
+
team_id=accuracy_eval.team.id if accuracy_eval.team else None,
|
|
85
|
+
workflow_id=None,
|
|
86
|
+
model_id=accuracy_eval.agent.model.id if accuracy_eval.agent else accuracy_eval.team.model.id, # type: ignore
|
|
87
|
+
model_provider=model_provider,
|
|
88
|
+
eval_type=EvalType.ACCURACY,
|
|
89
|
+
eval_data=asdict(result),
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
@classmethod
|
|
93
|
+
def from_performance_eval(
|
|
94
|
+
cls,
|
|
95
|
+
performance_eval: PerformanceEval,
|
|
96
|
+
result: PerformanceResult,
|
|
97
|
+
model_id: Optional[str] = None,
|
|
98
|
+
model_provider: Optional[str] = None,
|
|
99
|
+
agent_id: Optional[str] = None,
|
|
100
|
+
team_id: Optional[str] = None,
|
|
101
|
+
) -> "EvalSchema":
|
|
102
|
+
return cls(
|
|
103
|
+
id=performance_eval.eval_id,
|
|
104
|
+
name=performance_eval.name,
|
|
105
|
+
agent_id=agent_id,
|
|
106
|
+
team_id=team_id,
|
|
107
|
+
workflow_id=None,
|
|
108
|
+
model_id=model_id,
|
|
109
|
+
model_provider=model_provider,
|
|
110
|
+
eval_type=EvalType.PERFORMANCE,
|
|
111
|
+
eval_data=asdict(result),
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
@classmethod
|
|
115
|
+
def from_reliability_eval(
|
|
116
|
+
cls,
|
|
117
|
+
reliability_eval: ReliabilityEval,
|
|
118
|
+
result: ReliabilityResult,
|
|
119
|
+
model_id: Optional[str] = None,
|
|
120
|
+
model_provider: Optional[str] = None,
|
|
121
|
+
agent_id: Optional[str] = None,
|
|
122
|
+
team_id: Optional[str] = None,
|
|
123
|
+
) -> "EvalSchema":
|
|
124
|
+
return cls(
|
|
125
|
+
id=reliability_eval.eval_id,
|
|
126
|
+
name=reliability_eval.name,
|
|
127
|
+
agent_id=agent_id,
|
|
128
|
+
team_id=team_id,
|
|
129
|
+
workflow_id=None,
|
|
130
|
+
model_id=model_id,
|
|
131
|
+
model_provider=model_provider,
|
|
132
|
+
eval_type=EvalType.RELIABILITY,
|
|
133
|
+
eval_data=asdict(result),
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
class DeleteEvalRunsRequest(BaseModel):
|
|
138
|
+
eval_run_ids: List[str]
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
class UpdateEvalRunRequest(BaseModel):
|
|
142
|
+
name: str
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
3
|
+
from fastapi import HTTPException
|
|
4
|
+
|
|
5
|
+
from agno.agent.agent import Agent
|
|
6
|
+
from agno.db.base import BaseDb
|
|
7
|
+
from agno.eval.accuracy import AccuracyEval
|
|
8
|
+
from agno.eval.performance import PerformanceEval
|
|
9
|
+
from agno.eval.reliability import ReliabilityEval
|
|
10
|
+
from agno.models.base import Model
|
|
11
|
+
from agno.os.routers.evals.schemas import EvalRunInput, EvalSchema
|
|
12
|
+
from agno.team.team import Team
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
async def run_accuracy_eval(
|
|
16
|
+
eval_run_input: EvalRunInput,
|
|
17
|
+
db: BaseDb,
|
|
18
|
+
agent: Optional[Agent] = None,
|
|
19
|
+
team: Optional[Team] = None,
|
|
20
|
+
default_model: Optional[Model] = None,
|
|
21
|
+
) -> EvalSchema:
|
|
22
|
+
"""Run an Accuracy evaluation for the given agent or team"""
|
|
23
|
+
if not eval_run_input.expected_output:
|
|
24
|
+
raise HTTPException(status_code=400, detail="expected_output is required for accuracy evaluation")
|
|
25
|
+
|
|
26
|
+
accuracy_eval = AccuracyEval(
|
|
27
|
+
db=db,
|
|
28
|
+
agent=agent,
|
|
29
|
+
team=team,
|
|
30
|
+
input=eval_run_input.input,
|
|
31
|
+
expected_output=eval_run_input.expected_output,
|
|
32
|
+
additional_guidelines=eval_run_input.additional_guidelines,
|
|
33
|
+
additional_context=eval_run_input.additional_context,
|
|
34
|
+
num_iterations=eval_run_input.num_iterations or 1,
|
|
35
|
+
name=eval_run_input.name,
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
result = accuracy_eval.run(print_results=False, print_summary=False)
|
|
39
|
+
if not result:
|
|
40
|
+
raise HTTPException(status_code=500, detail="Failed to run accuracy evaluation")
|
|
41
|
+
|
|
42
|
+
eval_run = EvalSchema.from_accuracy_eval(accuracy_eval=accuracy_eval, result=result)
|
|
43
|
+
|
|
44
|
+
if default_model is not None:
|
|
45
|
+
if agent is not None:
|
|
46
|
+
agent.model = default_model
|
|
47
|
+
elif team is not None:
|
|
48
|
+
team.model = default_model
|
|
49
|
+
|
|
50
|
+
return eval_run
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
async def run_performance_eval(
|
|
54
|
+
eval_run_input: EvalRunInput,
|
|
55
|
+
db: BaseDb,
|
|
56
|
+
agent: Optional[Agent] = None,
|
|
57
|
+
team: Optional[Team] = None,
|
|
58
|
+
default_model: Optional[Model] = None,
|
|
59
|
+
) -> EvalSchema:
|
|
60
|
+
"""Run a performance evaluation for the given agent or team"""
|
|
61
|
+
if agent:
|
|
62
|
+
|
|
63
|
+
def run_component(): # type: ignore
|
|
64
|
+
return agent.run(eval_run_input.input)
|
|
65
|
+
|
|
66
|
+
model_id = agent.model.id if agent and agent.model else None
|
|
67
|
+
model_provider = agent.model.provider if agent and agent.model else None
|
|
68
|
+
|
|
69
|
+
elif team:
|
|
70
|
+
|
|
71
|
+
def run_component():
|
|
72
|
+
return team.run(eval_run_input.input)
|
|
73
|
+
|
|
74
|
+
model_id = team.model.id if team and team.model else None
|
|
75
|
+
model_provider = team.model.provider if team and team.model else None
|
|
76
|
+
|
|
77
|
+
performance_eval = PerformanceEval(
|
|
78
|
+
db=db,
|
|
79
|
+
name=eval_run_input.name,
|
|
80
|
+
func=run_component,
|
|
81
|
+
num_iterations=eval_run_input.num_iterations or 10,
|
|
82
|
+
warmup_runs=eval_run_input.warmup_runs,
|
|
83
|
+
agent_id=agent.id if agent else None,
|
|
84
|
+
team_id=team.id if team else None,
|
|
85
|
+
model_id=model_id,
|
|
86
|
+
model_provider=model_provider,
|
|
87
|
+
)
|
|
88
|
+
result = performance_eval.run(print_results=False, print_summary=False)
|
|
89
|
+
if not result:
|
|
90
|
+
raise HTTPException(status_code=500, detail="Failed to run performance evaluation")
|
|
91
|
+
|
|
92
|
+
eval_run = EvalSchema.from_performance_eval(
|
|
93
|
+
performance_eval=performance_eval,
|
|
94
|
+
result=result,
|
|
95
|
+
agent_id=agent.id if agent else None,
|
|
96
|
+
team_id=team.id if team else None,
|
|
97
|
+
model_id=model_id,
|
|
98
|
+
model_provider=model_provider,
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
if default_model is not None:
|
|
102
|
+
if agent is not None:
|
|
103
|
+
agent.model = default_model
|
|
104
|
+
elif team is not None:
|
|
105
|
+
team.model = default_model
|
|
106
|
+
|
|
107
|
+
return eval_run
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
async def run_reliability_eval(
|
|
111
|
+
eval_run_input: EvalRunInput,
|
|
112
|
+
db: BaseDb,
|
|
113
|
+
agent: Optional[Agent] = None,
|
|
114
|
+
team: Optional[Team] = None,
|
|
115
|
+
default_model: Optional[Model] = None,
|
|
116
|
+
) -> EvalSchema:
|
|
117
|
+
"""Run a reliability evaluation for the given agent or team"""
|
|
118
|
+
if not eval_run_input.expected_tool_calls:
|
|
119
|
+
raise HTTPException(status_code=400, detail="expected_tool_calls is required for reliability evaluations")
|
|
120
|
+
|
|
121
|
+
if agent:
|
|
122
|
+
agent_response = agent.run(eval_run_input.input)
|
|
123
|
+
reliability_eval = ReliabilityEval(
|
|
124
|
+
db=db,
|
|
125
|
+
name=eval_run_input.name,
|
|
126
|
+
agent_response=agent_response,
|
|
127
|
+
expected_tool_calls=eval_run_input.expected_tool_calls,
|
|
128
|
+
)
|
|
129
|
+
model_id = agent.model.id if agent and agent.model else None
|
|
130
|
+
model_provider = agent.model.provider if agent and agent.model else None
|
|
131
|
+
|
|
132
|
+
elif team:
|
|
133
|
+
team_response = team.run(eval_run_input.input)
|
|
134
|
+
reliability_eval = ReliabilityEval(
|
|
135
|
+
db=db,
|
|
136
|
+
name=eval_run_input.name,
|
|
137
|
+
team_response=team_response,
|
|
138
|
+
expected_tool_calls=eval_run_input.expected_tool_calls,
|
|
139
|
+
)
|
|
140
|
+
model_id = team.model.id if team and team.model else None
|
|
141
|
+
model_provider = team.model.provider if team and team.model else None
|
|
142
|
+
|
|
143
|
+
result = reliability_eval.run(print_results=False)
|
|
144
|
+
if not result:
|
|
145
|
+
raise HTTPException(status_code=500, detail="Failed to run reliability evaluation")
|
|
146
|
+
|
|
147
|
+
eval_run = EvalSchema.from_reliability_eval(
|
|
148
|
+
reliability_eval=reliability_eval,
|
|
149
|
+
result=result,
|
|
150
|
+
agent_id=agent.id if agent else None,
|
|
151
|
+
model_id=model_id,
|
|
152
|
+
model_provider=model_provider,
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
if default_model is not None:
|
|
156
|
+
if agent is not None:
|
|
157
|
+
agent.model = default_model
|
|
158
|
+
elif team is not None:
|
|
159
|
+
team.model = default_model
|
|
160
|
+
|
|
161
|
+
return eval_run
|