agno 1.8.1__py3-none-any.whl → 2.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- agno/__init__.py +8 -0
- agno/agent/__init__.py +19 -27
- agno/agent/agent.py +3143 -4170
- agno/api/agent.py +11 -67
- agno/api/api.py +5 -46
- agno/api/evals.py +8 -19
- agno/api/os.py +17 -0
- agno/api/routes.py +6 -41
- agno/api/schemas/__init__.py +9 -0
- agno/api/schemas/agent.py +5 -21
- agno/api/schemas/evals.py +7 -16
- agno/api/schemas/os.py +14 -0
- agno/api/schemas/team.py +5 -21
- agno/api/schemas/utils.py +21 -0
- agno/api/schemas/workflows.py +11 -7
- agno/api/settings.py +53 -0
- agno/api/team.py +11 -66
- agno/api/workflow.py +28 -0
- agno/cloud/aws/base.py +214 -0
- agno/cloud/aws/s3/__init__.py +2 -0
- agno/cloud/aws/s3/api_client.py +43 -0
- agno/cloud/aws/s3/bucket.py +195 -0
- agno/cloud/aws/s3/object.py +57 -0
- agno/db/__init__.py +24 -0
- agno/db/base.py +245 -0
- agno/db/dynamo/__init__.py +3 -0
- agno/db/dynamo/dynamo.py +1743 -0
- agno/db/dynamo/schemas.py +278 -0
- agno/db/dynamo/utils.py +684 -0
- agno/db/firestore/__init__.py +3 -0
- agno/db/firestore/firestore.py +1432 -0
- agno/db/firestore/schemas.py +130 -0
- agno/db/firestore/utils.py +278 -0
- agno/db/gcs_json/__init__.py +3 -0
- agno/db/gcs_json/gcs_json_db.py +1001 -0
- agno/db/gcs_json/utils.py +194 -0
- agno/db/in_memory/__init__.py +3 -0
- agno/db/in_memory/in_memory_db.py +882 -0
- agno/db/in_memory/utils.py +172 -0
- agno/db/json/__init__.py +3 -0
- agno/db/json/json_db.py +1045 -0
- agno/db/json/utils.py +196 -0
- agno/db/migrations/v1_to_v2.py +162 -0
- agno/db/mongo/__init__.py +3 -0
- agno/db/mongo/mongo.py +1416 -0
- agno/db/mongo/schemas.py +77 -0
- agno/db/mongo/utils.py +204 -0
- agno/db/mysql/__init__.py +3 -0
- agno/db/mysql/mysql.py +1719 -0
- agno/db/mysql/schemas.py +124 -0
- agno/db/mysql/utils.py +297 -0
- agno/db/postgres/__init__.py +3 -0
- agno/db/postgres/postgres.py +1710 -0
- agno/db/postgres/schemas.py +124 -0
- agno/db/postgres/utils.py +280 -0
- agno/db/redis/__init__.py +3 -0
- agno/db/redis/redis.py +1367 -0
- agno/db/redis/schemas.py +109 -0
- agno/db/redis/utils.py +288 -0
- agno/db/schemas/__init__.py +3 -0
- agno/db/schemas/evals.py +33 -0
- agno/db/schemas/knowledge.py +40 -0
- agno/db/schemas/memory.py +46 -0
- agno/db/singlestore/__init__.py +3 -0
- agno/db/singlestore/schemas.py +116 -0
- agno/db/singlestore/singlestore.py +1712 -0
- agno/db/singlestore/utils.py +326 -0
- agno/db/sqlite/__init__.py +3 -0
- agno/db/sqlite/schemas.py +119 -0
- agno/db/sqlite/sqlite.py +1676 -0
- agno/db/sqlite/utils.py +268 -0
- agno/db/utils.py +88 -0
- agno/eval/__init__.py +14 -0
- agno/eval/accuracy.py +154 -48
- agno/eval/performance.py +88 -23
- agno/eval/reliability.py +73 -20
- agno/eval/utils.py +23 -13
- agno/integrations/discord/__init__.py +3 -0
- agno/{app → integrations}/discord/client.py +15 -11
- agno/knowledge/__init__.py +2 -2
- agno/{document → knowledge}/chunking/agentic.py +2 -2
- agno/{document → knowledge}/chunking/document.py +2 -2
- agno/{document → knowledge}/chunking/fixed.py +3 -3
- agno/{document → knowledge}/chunking/markdown.py +2 -2
- agno/{document → knowledge}/chunking/recursive.py +2 -2
- agno/{document → knowledge}/chunking/row.py +2 -2
- agno/knowledge/chunking/semantic.py +59 -0
- agno/knowledge/chunking/strategy.py +121 -0
- agno/knowledge/content.py +74 -0
- agno/knowledge/document/__init__.py +5 -0
- agno/{document → knowledge/document}/base.py +12 -2
- agno/knowledge/embedder/__init__.py +5 -0
- agno/{embedder → knowledge/embedder}/aws_bedrock.py +127 -1
- agno/{embedder → knowledge/embedder}/azure_openai.py +65 -1
- agno/{embedder → knowledge/embedder}/base.py +6 -0
- agno/{embedder → knowledge/embedder}/cohere.py +72 -1
- agno/{embedder → knowledge/embedder}/fastembed.py +17 -1
- agno/{embedder → knowledge/embedder}/fireworks.py +1 -1
- agno/{embedder → knowledge/embedder}/google.py +74 -1
- agno/{embedder → knowledge/embedder}/huggingface.py +36 -2
- agno/{embedder → knowledge/embedder}/jina.py +48 -2
- agno/knowledge/embedder/langdb.py +22 -0
- agno/knowledge/embedder/mistral.py +139 -0
- agno/{embedder → knowledge/embedder}/nebius.py +1 -1
- agno/{embedder → knowledge/embedder}/ollama.py +54 -3
- agno/knowledge/embedder/openai.py +223 -0
- agno/{embedder → knowledge/embedder}/sentence_transformer.py +16 -1
- agno/{embedder → knowledge/embedder}/together.py +1 -1
- agno/{embedder → knowledge/embedder}/voyageai.py +49 -1
- agno/knowledge/knowledge.py +1551 -0
- agno/knowledge/reader/__init__.py +7 -0
- agno/{document → knowledge}/reader/arxiv_reader.py +32 -4
- agno/knowledge/reader/base.py +88 -0
- agno/{document → knowledge}/reader/csv_reader.py +47 -65
- agno/knowledge/reader/docx_reader.py +83 -0
- agno/{document → knowledge}/reader/firecrawl_reader.py +42 -21
- agno/{document → knowledge}/reader/json_reader.py +30 -9
- agno/{document → knowledge}/reader/markdown_reader.py +58 -9
- agno/{document → knowledge}/reader/pdf_reader.py +71 -126
- agno/knowledge/reader/reader_factory.py +268 -0
- agno/knowledge/reader/s3_reader.py +101 -0
- agno/{document → knowledge}/reader/text_reader.py +31 -10
- agno/knowledge/reader/url_reader.py +128 -0
- agno/knowledge/reader/web_search_reader.py +366 -0
- agno/{document → knowledge}/reader/website_reader.py +37 -10
- agno/knowledge/reader/wikipedia_reader.py +59 -0
- agno/knowledge/reader/youtube_reader.py +78 -0
- agno/knowledge/remote_content/remote_content.py +88 -0
- agno/{reranker → knowledge/reranker}/base.py +1 -1
- agno/{reranker → knowledge/reranker}/cohere.py +2 -2
- agno/{reranker → knowledge/reranker}/infinity.py +2 -2
- agno/{reranker → knowledge/reranker}/sentence_transformer.py +2 -2
- agno/knowledge/types.py +30 -0
- agno/knowledge/utils.py +169 -0
- agno/media.py +269 -268
- agno/memory/__init__.py +2 -10
- agno/memory/manager.py +1003 -148
- agno/models/aimlapi/__init__.py +2 -2
- agno/models/aimlapi/aimlapi.py +6 -6
- agno/models/anthropic/claude.py +131 -131
- agno/models/aws/bedrock.py +110 -182
- agno/models/aws/claude.py +64 -18
- agno/models/azure/ai_foundry.py +73 -23
- agno/models/base.py +346 -290
- agno/models/cerebras/cerebras.py +84 -27
- agno/models/cohere/chat.py +106 -98
- agno/models/google/gemini.py +105 -46
- agno/models/groq/groq.py +97 -35
- agno/models/huggingface/huggingface.py +92 -27
- agno/models/ibm/watsonx.py +72 -13
- agno/models/litellm/chat.py +85 -13
- agno/models/message.py +46 -151
- agno/models/meta/llama.py +85 -49
- agno/models/metrics.py +120 -0
- agno/models/mistral/mistral.py +90 -21
- agno/models/ollama/__init__.py +0 -2
- agno/models/ollama/chat.py +85 -47
- agno/models/openai/chat.py +154 -37
- agno/models/openai/responses.py +178 -105
- agno/models/perplexity/perplexity.py +26 -2
- agno/models/portkey/portkey.py +0 -7
- agno/models/response.py +15 -9
- agno/models/utils.py +20 -0
- agno/models/vercel/__init__.py +2 -2
- agno/models/vercel/v0.py +1 -1
- agno/models/vllm/__init__.py +2 -2
- agno/models/vllm/vllm.py +3 -3
- agno/models/xai/xai.py +10 -10
- agno/os/__init__.py +3 -0
- agno/os/app.py +497 -0
- agno/os/auth.py +47 -0
- agno/os/config.py +103 -0
- agno/os/interfaces/agui/__init__.py +3 -0
- agno/os/interfaces/agui/agui.py +31 -0
- agno/{app/agui/async_router.py → os/interfaces/agui/router.py} +16 -16
- agno/{app → os/interfaces}/agui/utils.py +77 -33
- agno/os/interfaces/base.py +21 -0
- agno/os/interfaces/slack/__init__.py +3 -0
- agno/{app/slack/async_router.py → os/interfaces/slack/router.py} +3 -5
- agno/os/interfaces/slack/slack.py +32 -0
- agno/os/interfaces/whatsapp/__init__.py +3 -0
- agno/{app/whatsapp/async_router.py → os/interfaces/whatsapp/router.py} +4 -7
- agno/os/interfaces/whatsapp/whatsapp.py +29 -0
- agno/os/mcp.py +235 -0
- agno/os/router.py +1400 -0
- agno/os/routers/__init__.py +3 -0
- agno/os/routers/evals/__init__.py +3 -0
- agno/os/routers/evals/evals.py +393 -0
- agno/os/routers/evals/schemas.py +142 -0
- agno/os/routers/evals/utils.py +161 -0
- agno/os/routers/knowledge/__init__.py +3 -0
- agno/os/routers/knowledge/knowledge.py +850 -0
- agno/os/routers/knowledge/schemas.py +118 -0
- agno/os/routers/memory/__init__.py +3 -0
- agno/os/routers/memory/memory.py +410 -0
- agno/os/routers/memory/schemas.py +58 -0
- agno/os/routers/metrics/__init__.py +3 -0
- agno/os/routers/metrics/metrics.py +178 -0
- agno/os/routers/metrics/schemas.py +47 -0
- agno/os/routers/session/__init__.py +3 -0
- agno/os/routers/session/session.py +536 -0
- agno/os/schema.py +945 -0
- agno/{app/playground → os}/settings.py +7 -15
- agno/os/utils.py +270 -0
- agno/reasoning/azure_ai_foundry.py +4 -4
- agno/reasoning/deepseek.py +4 -4
- agno/reasoning/default.py +6 -11
- agno/reasoning/groq.py +4 -4
- agno/reasoning/helpers.py +4 -6
- agno/reasoning/ollama.py +4 -4
- agno/reasoning/openai.py +4 -4
- agno/run/agent.py +633 -0
- agno/run/base.py +53 -77
- agno/run/cancel.py +81 -0
- agno/run/team.py +243 -96
- agno/run/workflow.py +550 -12
- agno/session/__init__.py +10 -0
- agno/session/agent.py +244 -0
- agno/session/summary.py +225 -0
- agno/session/team.py +262 -0
- agno/{storage/session/v2 → session}/workflow.py +47 -24
- agno/team/__init__.py +15 -16
- agno/team/team.py +3260 -4824
- agno/tools/agentql.py +14 -5
- agno/tools/airflow.py +9 -4
- agno/tools/api.py +7 -3
- agno/tools/apify.py +2 -46
- agno/tools/arxiv.py +8 -3
- agno/tools/aws_lambda.py +7 -5
- agno/tools/aws_ses.py +7 -1
- agno/tools/baidusearch.py +4 -1
- agno/tools/bitbucket.py +4 -4
- agno/tools/brandfetch.py +14 -11
- agno/tools/bravesearch.py +4 -1
- agno/tools/brightdata.py +43 -23
- agno/tools/browserbase.py +13 -4
- agno/tools/calcom.py +12 -10
- agno/tools/calculator.py +10 -27
- agno/tools/cartesia.py +20 -17
- agno/tools/{clickup_tool.py → clickup.py} +12 -25
- agno/tools/confluence.py +8 -8
- agno/tools/crawl4ai.py +7 -1
- agno/tools/csv_toolkit.py +9 -8
- agno/tools/dalle.py +22 -12
- agno/tools/daytona.py +13 -16
- agno/tools/decorator.py +6 -3
- agno/tools/desi_vocal.py +17 -8
- agno/tools/discord.py +11 -8
- agno/tools/docker.py +30 -42
- agno/tools/duckdb.py +34 -53
- agno/tools/duckduckgo.py +8 -7
- agno/tools/e2b.py +62 -62
- agno/tools/eleven_labs.py +36 -29
- agno/tools/email.py +4 -1
- agno/tools/evm.py +7 -1
- agno/tools/exa.py +19 -14
- agno/tools/fal.py +30 -30
- agno/tools/file.py +9 -8
- agno/tools/financial_datasets.py +25 -44
- agno/tools/firecrawl.py +22 -22
- agno/tools/function.py +127 -18
- agno/tools/giphy.py +23 -11
- agno/tools/github.py +48 -126
- agno/tools/gmail.py +45 -61
- agno/tools/google_bigquery.py +7 -6
- agno/tools/google_maps.py +11 -26
- agno/tools/googlesearch.py +7 -2
- agno/tools/googlesheets.py +21 -17
- agno/tools/hackernews.py +9 -5
- agno/tools/jina.py +5 -4
- agno/tools/jira.py +18 -9
- agno/tools/knowledge.py +31 -32
- agno/tools/linear.py +19 -34
- agno/tools/linkup.py +5 -1
- agno/tools/local_file_system.py +8 -5
- agno/tools/lumalab.py +32 -20
- agno/tools/mcp.py +1 -2
- agno/tools/mem0.py +18 -12
- agno/tools/memori.py +14 -10
- agno/tools/mlx_transcribe.py +3 -2
- agno/tools/models/azure_openai.py +33 -15
- agno/tools/models/gemini.py +59 -32
- agno/tools/models/groq.py +30 -23
- agno/tools/models/nebius.py +28 -12
- agno/tools/models_labs.py +40 -16
- agno/tools/moviepy_video.py +7 -6
- agno/tools/neo4j.py +10 -8
- agno/tools/newspaper.py +7 -2
- agno/tools/newspaper4k.py +8 -3
- agno/tools/openai.py +58 -32
- agno/tools/openbb.py +12 -11
- agno/tools/opencv.py +63 -47
- agno/tools/openweather.py +14 -12
- agno/tools/pandas.py +11 -3
- agno/tools/postgres.py +4 -12
- agno/tools/pubmed.py +4 -1
- agno/tools/python.py +9 -22
- agno/tools/reasoning.py +35 -27
- agno/tools/reddit.py +11 -26
- agno/tools/replicate.py +55 -42
- agno/tools/resend.py +4 -1
- agno/tools/scrapegraph.py +15 -14
- agno/tools/searxng.py +10 -23
- agno/tools/serpapi.py +6 -3
- agno/tools/serper.py +13 -4
- agno/tools/shell.py +9 -2
- agno/tools/slack.py +12 -11
- agno/tools/sleep.py +3 -2
- agno/tools/spider.py +24 -4
- agno/tools/sql.py +7 -6
- agno/tools/tavily.py +6 -4
- agno/tools/telegram.py +12 -4
- agno/tools/todoist.py +11 -31
- agno/tools/toolkit.py +1 -1
- agno/tools/trafilatura.py +22 -6
- agno/tools/trello.py +9 -22
- agno/tools/twilio.py +10 -3
- agno/tools/user_control_flow.py +6 -1
- agno/tools/valyu.py +34 -5
- agno/tools/visualization.py +19 -28
- agno/tools/webbrowser.py +4 -3
- agno/tools/webex.py +11 -7
- agno/tools/website.py +15 -46
- agno/tools/webtools.py +12 -4
- agno/tools/whatsapp.py +5 -9
- agno/tools/wikipedia.py +20 -13
- agno/tools/x.py +14 -13
- agno/tools/yfinance.py +13 -40
- agno/tools/youtube.py +26 -20
- agno/tools/zendesk.py +7 -2
- agno/tools/zep.py +10 -7
- agno/tools/zoom.py +10 -9
- agno/utils/common.py +1 -19
- agno/utils/events.py +100 -123
- agno/utils/gemini.py +32 -2
- agno/utils/knowledge.py +29 -0
- agno/utils/log.py +54 -4
- agno/utils/mcp.py +68 -10
- agno/utils/media.py +39 -0
- agno/utils/message.py +12 -1
- agno/utils/models/aws_claude.py +1 -1
- agno/utils/models/claude.py +47 -4
- agno/utils/models/cohere.py +1 -1
- agno/utils/models/mistral.py +8 -7
- agno/utils/models/schema_utils.py +3 -3
- agno/utils/models/watsonx.py +1 -1
- agno/utils/openai.py +1 -1
- agno/utils/pprint.py +33 -32
- agno/utils/print_response/agent.py +779 -0
- agno/utils/print_response/team.py +1669 -0
- agno/utils/print_response/workflow.py +1451 -0
- agno/utils/prompts.py +14 -14
- agno/utils/reasoning.py +87 -0
- agno/utils/response.py +42 -42
- agno/utils/streamlit.py +481 -0
- agno/utils/string.py +8 -22
- agno/utils/team.py +50 -0
- agno/utils/timer.py +2 -2
- agno/vectordb/base.py +33 -21
- agno/vectordb/cassandra/cassandra.py +287 -23
- agno/vectordb/chroma/chromadb.py +482 -59
- agno/vectordb/clickhouse/clickhousedb.py +270 -63
- agno/vectordb/couchbase/couchbase.py +309 -29
- agno/vectordb/lancedb/lance_db.py +360 -21
- agno/vectordb/langchaindb/__init__.py +5 -0
- agno/vectordb/langchaindb/langchaindb.py +145 -0
- agno/vectordb/lightrag/__init__.py +5 -0
- agno/vectordb/lightrag/lightrag.py +374 -0
- agno/vectordb/llamaindex/llamaindexdb.py +127 -0
- agno/vectordb/milvus/milvus.py +242 -32
- agno/vectordb/mongodb/mongodb.py +200 -24
- agno/vectordb/pgvector/pgvector.py +319 -37
- agno/vectordb/pineconedb/pineconedb.py +221 -27
- agno/vectordb/qdrant/qdrant.py +334 -14
- agno/vectordb/singlestore/singlestore.py +286 -29
- agno/vectordb/surrealdb/surrealdb.py +187 -7
- agno/vectordb/upstashdb/upstashdb.py +342 -26
- agno/vectordb/weaviate/weaviate.py +227 -165
- agno/workflow/__init__.py +17 -13
- agno/workflow/{v2/condition.py → condition.py} +135 -32
- agno/workflow/{v2/loop.py → loop.py} +115 -28
- agno/workflow/{v2/parallel.py → parallel.py} +138 -108
- agno/workflow/{v2/router.py → router.py} +133 -32
- agno/workflow/{v2/step.py → step.py} +207 -49
- agno/workflow/{v2/steps.py → steps.py} +147 -66
- agno/workflow/types.py +482 -0
- agno/workflow/workflow.py +2410 -696
- agno-2.0.0.dist-info/METADATA +494 -0
- agno-2.0.0.dist-info/RECORD +515 -0
- agno-2.0.0.dist-info/licenses/LICENSE +201 -0
- agno/agent/metrics.py +0 -107
- agno/api/app.py +0 -35
- agno/api/playground.py +0 -92
- agno/api/schemas/app.py +0 -12
- agno/api/schemas/playground.py +0 -22
- agno/api/schemas/user.py +0 -35
- agno/api/schemas/workspace.py +0 -46
- agno/api/user.py +0 -160
- agno/api/workflows.py +0 -33
- agno/api/workspace.py +0 -175
- agno/app/agui/__init__.py +0 -3
- agno/app/agui/app.py +0 -17
- agno/app/agui/sync_router.py +0 -120
- agno/app/base.py +0 -186
- agno/app/discord/__init__.py +0 -3
- agno/app/fastapi/__init__.py +0 -3
- agno/app/fastapi/app.py +0 -107
- agno/app/fastapi/async_router.py +0 -457
- agno/app/fastapi/sync_router.py +0 -448
- agno/app/playground/app.py +0 -228
- agno/app/playground/async_router.py +0 -1050
- agno/app/playground/deploy.py +0 -249
- agno/app/playground/operator.py +0 -183
- agno/app/playground/schemas.py +0 -220
- agno/app/playground/serve.py +0 -55
- agno/app/playground/sync_router.py +0 -1042
- agno/app/playground/utils.py +0 -46
- agno/app/settings.py +0 -15
- agno/app/slack/__init__.py +0 -3
- agno/app/slack/app.py +0 -19
- agno/app/slack/sync_router.py +0 -92
- agno/app/utils.py +0 -54
- agno/app/whatsapp/__init__.py +0 -3
- agno/app/whatsapp/app.py +0 -15
- agno/app/whatsapp/sync_router.py +0 -197
- agno/cli/auth_server.py +0 -249
- agno/cli/config.py +0 -274
- agno/cli/console.py +0 -88
- agno/cli/credentials.py +0 -23
- agno/cli/entrypoint.py +0 -571
- agno/cli/operator.py +0 -357
- agno/cli/settings.py +0 -96
- agno/cli/ws/ws_cli.py +0 -817
- agno/constants.py +0 -13
- agno/document/__init__.py +0 -5
- agno/document/chunking/semantic.py +0 -45
- agno/document/chunking/strategy.py +0 -31
- agno/document/reader/__init__.py +0 -5
- agno/document/reader/base.py +0 -47
- agno/document/reader/docx_reader.py +0 -60
- agno/document/reader/gcs/pdf_reader.py +0 -44
- agno/document/reader/s3/pdf_reader.py +0 -59
- agno/document/reader/s3/text_reader.py +0 -63
- agno/document/reader/url_reader.py +0 -59
- agno/document/reader/youtube_reader.py +0 -58
- agno/embedder/__init__.py +0 -5
- agno/embedder/langdb.py +0 -80
- agno/embedder/mistral.py +0 -82
- agno/embedder/openai.py +0 -78
- agno/file/__init__.py +0 -5
- agno/file/file.py +0 -16
- agno/file/local/csv.py +0 -32
- agno/file/local/txt.py +0 -19
- agno/infra/app.py +0 -240
- agno/infra/base.py +0 -144
- agno/infra/context.py +0 -20
- agno/infra/db_app.py +0 -52
- agno/infra/resource.py +0 -205
- agno/infra/resources.py +0 -55
- agno/knowledge/agent.py +0 -702
- agno/knowledge/arxiv.py +0 -33
- agno/knowledge/combined.py +0 -36
- agno/knowledge/csv.py +0 -144
- agno/knowledge/csv_url.py +0 -124
- agno/knowledge/document.py +0 -223
- agno/knowledge/docx.py +0 -137
- agno/knowledge/firecrawl.py +0 -34
- agno/knowledge/gcs/__init__.py +0 -0
- agno/knowledge/gcs/base.py +0 -39
- agno/knowledge/gcs/pdf.py +0 -125
- agno/knowledge/json.py +0 -137
- agno/knowledge/langchain.py +0 -71
- agno/knowledge/light_rag.py +0 -273
- agno/knowledge/llamaindex.py +0 -66
- agno/knowledge/markdown.py +0 -154
- agno/knowledge/pdf.py +0 -164
- agno/knowledge/pdf_bytes.py +0 -42
- agno/knowledge/pdf_url.py +0 -148
- agno/knowledge/s3/__init__.py +0 -0
- agno/knowledge/s3/base.py +0 -64
- agno/knowledge/s3/pdf.py +0 -33
- agno/knowledge/s3/text.py +0 -34
- agno/knowledge/text.py +0 -141
- agno/knowledge/url.py +0 -46
- agno/knowledge/website.py +0 -179
- agno/knowledge/wikipedia.py +0 -32
- agno/knowledge/youtube.py +0 -35
- agno/memory/agent.py +0 -423
- agno/memory/classifier.py +0 -104
- agno/memory/db/__init__.py +0 -5
- agno/memory/db/base.py +0 -42
- agno/memory/db/mongodb.py +0 -189
- agno/memory/db/postgres.py +0 -203
- agno/memory/db/sqlite.py +0 -193
- agno/memory/memory.py +0 -22
- agno/memory/row.py +0 -36
- agno/memory/summarizer.py +0 -201
- agno/memory/summary.py +0 -19
- agno/memory/team.py +0 -415
- agno/memory/v2/__init__.py +0 -2
- agno/memory/v2/db/__init__.py +0 -1
- agno/memory/v2/db/base.py +0 -42
- agno/memory/v2/db/firestore.py +0 -339
- agno/memory/v2/db/mongodb.py +0 -196
- agno/memory/v2/db/postgres.py +0 -214
- agno/memory/v2/db/redis.py +0 -187
- agno/memory/v2/db/schema.py +0 -54
- agno/memory/v2/db/sqlite.py +0 -209
- agno/memory/v2/manager.py +0 -437
- agno/memory/v2/memory.py +0 -1097
- agno/memory/v2/schema.py +0 -55
- agno/memory/v2/summarizer.py +0 -215
- agno/memory/workflow.py +0 -38
- agno/models/ollama/tools.py +0 -430
- agno/models/qwen/__init__.py +0 -5
- agno/playground/__init__.py +0 -10
- agno/playground/deploy.py +0 -3
- agno/playground/playground.py +0 -3
- agno/playground/serve.py +0 -3
- agno/playground/settings.py +0 -3
- agno/reranker/__init__.py +0 -0
- agno/run/response.py +0 -467
- agno/run/v2/__init__.py +0 -0
- agno/run/v2/workflow.py +0 -567
- agno/storage/__init__.py +0 -0
- agno/storage/agent/__init__.py +0 -0
- agno/storage/agent/dynamodb.py +0 -1
- agno/storage/agent/json.py +0 -1
- agno/storage/agent/mongodb.py +0 -1
- agno/storage/agent/postgres.py +0 -1
- agno/storage/agent/singlestore.py +0 -1
- agno/storage/agent/sqlite.py +0 -1
- agno/storage/agent/yaml.py +0 -1
- agno/storage/base.py +0 -60
- agno/storage/dynamodb.py +0 -673
- agno/storage/firestore.py +0 -297
- agno/storage/gcs_json.py +0 -261
- agno/storage/in_memory.py +0 -234
- agno/storage/json.py +0 -237
- agno/storage/mongodb.py +0 -328
- agno/storage/mysql.py +0 -685
- agno/storage/postgres.py +0 -682
- agno/storage/redis.py +0 -336
- agno/storage/session/__init__.py +0 -16
- agno/storage/session/agent.py +0 -64
- agno/storage/session/team.py +0 -63
- agno/storage/session/v2/__init__.py +0 -5
- agno/storage/session/workflow.py +0 -61
- agno/storage/singlestore.py +0 -606
- agno/storage/sqlite.py +0 -646
- agno/storage/workflow/__init__.py +0 -0
- agno/storage/workflow/mongodb.py +0 -1
- agno/storage/workflow/postgres.py +0 -1
- agno/storage/workflow/sqlite.py +0 -1
- agno/storage/yaml.py +0 -241
- agno/tools/thinking.py +0 -73
- agno/utils/defaults.py +0 -57
- agno/utils/filesystem.py +0 -39
- agno/utils/git.py +0 -52
- agno/utils/json_io.py +0 -30
- agno/utils/load_env.py +0 -19
- agno/utils/py_io.py +0 -19
- agno/utils/pyproject.py +0 -18
- agno/utils/resource_filter.py +0 -31
- agno/workflow/v2/__init__.py +0 -21
- agno/workflow/v2/types.py +0 -357
- agno/workflow/v2/workflow.py +0 -3312
- agno/workspace/__init__.py +0 -0
- agno/workspace/config.py +0 -325
- agno/workspace/enums.py +0 -6
- agno/workspace/helpers.py +0 -52
- agno/workspace/operator.py +0 -757
- agno/workspace/settings.py +0 -158
- agno-1.8.1.dist-info/METADATA +0 -982
- agno-1.8.1.dist-info/RECORD +0 -566
- agno-1.8.1.dist-info/entry_points.txt +0 -3
- agno-1.8.1.dist-info/licenses/LICENSE +0 -375
- /agno/{app → db/migrations}/__init__.py +0 -0
- /agno/{app/playground/__init__.py → db/schemas/metrics.py} +0 -0
- /agno/{cli → integrations}/__init__.py +0 -0
- /agno/{cli/ws → knowledge/chunking}/__init__.py +0 -0
- /agno/{document/chunking → knowledge/remote_content}/__init__.py +0 -0
- /agno/{document/reader/gcs → knowledge/reranker}/__init__.py +0 -0
- /agno/{document/reader/s3 → os/interfaces}/__init__.py +0 -0
- /agno/{app → os/interfaces}/slack/security.py +0 -0
- /agno/{app → os/interfaces}/whatsapp/security.py +0 -0
- /agno/{file/local → utils/print_response}/__init__.py +0 -0
- /agno/{infra → vectordb/llamaindex}/__init__.py +0 -0
- {agno-1.8.1.dist-info → agno-2.0.0.dist-info}/WHEEL +0 -0
- {agno-1.8.1.dist-info → agno-2.0.0.dist-info}/top_level.txt +0 -0
agno/models/aws/bedrock.py
CHANGED
|
@@ -6,9 +6,11 @@ from typing import Any, AsyncIterator, Dict, Iterator, List, Optional, Tuple, Ty
|
|
|
6
6
|
from pydantic import BaseModel
|
|
7
7
|
|
|
8
8
|
from agno.exceptions import AgnoError, ModelProviderError
|
|
9
|
-
from agno.models.base import MessageData, Model
|
|
9
|
+
from agno.models.base import MessageData, Model
|
|
10
10
|
from agno.models.message import Message
|
|
11
|
+
from agno.models.metrics import Metrics
|
|
11
12
|
from agno.models.response import ModelResponse
|
|
13
|
+
from agno.run.agent import RunOutput
|
|
12
14
|
from agno.utils.log import log_debug, log_error, log_warning
|
|
13
15
|
|
|
14
16
|
try:
|
|
@@ -179,14 +181,10 @@ class AwsBedrock(Model):
|
|
|
179
181
|
required = []
|
|
180
182
|
|
|
181
183
|
for param_name, param_info in func_def.get("parameters", {}).get("properties", {}).items():
|
|
182
|
-
|
|
183
|
-
if isinstance(param_type, list):
|
|
184
|
-
param_type = [t for t in param_type if t != "null"][0]
|
|
184
|
+
properties[param_name] = param_info.copy()
|
|
185
185
|
|
|
186
|
-
properties[param_name]
|
|
187
|
-
"
|
|
188
|
-
"description": param_info.get("description") or "",
|
|
189
|
-
}
|
|
186
|
+
if "description" not in properties[param_name]:
|
|
187
|
+
properties[param_name]["description"] = ""
|
|
190
188
|
|
|
191
189
|
if "null" not in (
|
|
192
190
|
param_info.get("type") if isinstance(param_info.get("type"), list) else [param_info.get("type")]
|
|
@@ -349,10 +347,12 @@ class AwsBedrock(Model):
|
|
|
349
347
|
def invoke(
|
|
350
348
|
self,
|
|
351
349
|
messages: List[Message],
|
|
350
|
+
assistant_message: Message,
|
|
352
351
|
response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
|
|
353
352
|
tools: Optional[List[Dict[str, Any]]] = None,
|
|
354
353
|
tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
|
|
355
|
-
|
|
354
|
+
run_response: Optional[RunOutput] = None,
|
|
355
|
+
) -> ModelResponse:
|
|
356
356
|
"""
|
|
357
357
|
Invoke the Bedrock API.
|
|
358
358
|
"""
|
|
@@ -374,7 +374,17 @@ class AwsBedrock(Model):
|
|
|
374
374
|
log_debug(f"Calling {self.provider} with request parameters: {self.request_params}", log_level=2)
|
|
375
375
|
body.update(**self.request_params)
|
|
376
376
|
|
|
377
|
-
|
|
377
|
+
if run_response and run_response.metrics:
|
|
378
|
+
run_response.metrics.set_time_to_first_token()
|
|
379
|
+
|
|
380
|
+
assistant_message.metrics.start_timer()
|
|
381
|
+
response = self.get_client().converse(modelId=self.id, messages=formatted_messages, **body)
|
|
382
|
+
assistant_message.metrics.stop_timer()
|
|
383
|
+
|
|
384
|
+
model_response = self._parse_provider_response(response, response_format=response_format)
|
|
385
|
+
|
|
386
|
+
return model_response
|
|
387
|
+
|
|
378
388
|
except ClientError as e:
|
|
379
389
|
log_error(f"Unexpected error calling Bedrock API: {str(e)}")
|
|
380
390
|
raise ModelProviderError(message=str(e.response), model_name=self.name, model_id=self.id) from e
|
|
@@ -385,10 +395,12 @@ class AwsBedrock(Model):
|
|
|
385
395
|
def invoke_stream(
|
|
386
396
|
self,
|
|
387
397
|
messages: List[Message],
|
|
398
|
+
assistant_message: Message,
|
|
388
399
|
response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
|
|
389
400
|
tools: Optional[List[Dict[str, Any]]] = None,
|
|
390
401
|
tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
|
|
391
|
-
|
|
402
|
+
run_response: Optional[RunOutput] = None,
|
|
403
|
+
) -> Iterator[ModelResponse]:
|
|
392
404
|
"""
|
|
393
405
|
Invoke the Bedrock API with streaming.
|
|
394
406
|
"""
|
|
@@ -409,7 +421,18 @@ class AwsBedrock(Model):
|
|
|
409
421
|
if self.request_params:
|
|
410
422
|
body.update(**self.request_params)
|
|
411
423
|
|
|
412
|
-
|
|
424
|
+
if run_response and run_response.metrics:
|
|
425
|
+
run_response.metrics.set_time_to_first_token()
|
|
426
|
+
|
|
427
|
+
assistant_message.metrics.start_timer()
|
|
428
|
+
|
|
429
|
+
for chunk in self.get_client().converse_stream(modelId=self.id, messages=formatted_messages, **body)[
|
|
430
|
+
"stream"
|
|
431
|
+
]:
|
|
432
|
+
yield self._parse_provider_response_delta(chunk)
|
|
433
|
+
|
|
434
|
+
assistant_message.metrics.stop_timer()
|
|
435
|
+
|
|
413
436
|
except ClientError as e:
|
|
414
437
|
log_error(f"Unexpected error calling Bedrock API: {str(e)}")
|
|
415
438
|
raise ModelProviderError(message=str(e.response), model_name=self.name, model_id=self.id) from e
|
|
@@ -420,10 +443,12 @@ class AwsBedrock(Model):
|
|
|
420
443
|
async def ainvoke(
|
|
421
444
|
self,
|
|
422
445
|
messages: List[Message],
|
|
446
|
+
assistant_message: Message,
|
|
423
447
|
response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
|
|
424
448
|
tools: Optional[List[Dict[str, Any]]] = None,
|
|
425
449
|
tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
|
|
426
|
-
|
|
450
|
+
run_response: Optional[RunOutput] = None,
|
|
451
|
+
) -> ModelResponse:
|
|
427
452
|
"""
|
|
428
453
|
Async invoke the Bedrock API.
|
|
429
454
|
"""
|
|
@@ -445,8 +470,20 @@ class AwsBedrock(Model):
|
|
|
445
470
|
log_debug(f"Calling {self.provider} with request parameters: {self.request_params}", log_level=2)
|
|
446
471
|
body.update(**self.request_params)
|
|
447
472
|
|
|
473
|
+
if run_response and run_response.metrics:
|
|
474
|
+
run_response.metrics.set_time_to_first_token()
|
|
475
|
+
|
|
476
|
+
assistant_message.metrics.start_timer()
|
|
477
|
+
|
|
448
478
|
async with self.get_async_client() as client:
|
|
449
|
-
|
|
479
|
+
response = await client.converse(modelId=self.id, messages=formatted_messages, **body)
|
|
480
|
+
|
|
481
|
+
assistant_message.metrics.stop_timer()
|
|
482
|
+
|
|
483
|
+
model_response = self._parse_provider_response(response, response_format=response_format)
|
|
484
|
+
|
|
485
|
+
return model_response
|
|
486
|
+
|
|
450
487
|
except ClientError as e:
|
|
451
488
|
log_error(f"Unexpected error calling Bedrock API: {str(e)}")
|
|
452
489
|
raise ModelProviderError(message=str(e.response), model_name=self.name, model_id=self.id) from e
|
|
@@ -457,10 +494,12 @@ class AwsBedrock(Model):
|
|
|
457
494
|
async def ainvoke_stream(
|
|
458
495
|
self,
|
|
459
496
|
messages: List[Message],
|
|
497
|
+
assistant_message: Message,
|
|
460
498
|
response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
|
|
461
499
|
tools: Optional[List[Dict[str, Any]]] = None,
|
|
462
500
|
tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
|
|
463
|
-
|
|
501
|
+
run_response: Optional[RunOutput] = None,
|
|
502
|
+
) -> AsyncIterator[ModelResponse]:
|
|
464
503
|
"""
|
|
465
504
|
Async invoke the Bedrock API with streaming.
|
|
466
505
|
"""
|
|
@@ -481,10 +520,18 @@ class AwsBedrock(Model):
|
|
|
481
520
|
if self.request_params:
|
|
482
521
|
body.update(**self.request_params)
|
|
483
522
|
|
|
523
|
+
if run_response and run_response.metrics:
|
|
524
|
+
run_response.metrics.set_time_to_first_token()
|
|
525
|
+
|
|
526
|
+
assistant_message.metrics.start_timer()
|
|
527
|
+
|
|
484
528
|
async with self.get_async_client() as client:
|
|
485
529
|
response = await client.converse_stream(modelId=self.id, messages=formatted_messages, **body)
|
|
486
530
|
async for chunk in response["stream"]:
|
|
487
|
-
yield chunk
|
|
531
|
+
yield self._parse_provider_response_delta(chunk)
|
|
532
|
+
|
|
533
|
+
assistant_message.metrics.stop_timer()
|
|
534
|
+
|
|
488
535
|
except ClientError as e:
|
|
489
536
|
log_error(f"Unexpected error calling Bedrock API: {str(e)}")
|
|
490
537
|
raise ModelProviderError(message=str(e.response), model_name=self.name, model_id=self.id) from e
|
|
@@ -519,7 +566,7 @@ class AwsBedrock(Model):
|
|
|
519
566
|
|
|
520
567
|
messages.append(Message(role="user", content=tool_result_content))
|
|
521
568
|
|
|
522
|
-
def
|
|
569
|
+
def _parse_provider_response(self, response: Dict[str, Any], **kwargs) -> ModelResponse:
|
|
523
570
|
"""
|
|
524
571
|
Parse the provider response.
|
|
525
572
|
|
|
@@ -566,11 +613,7 @@ class AwsBedrock(Model):
|
|
|
566
613
|
model_response.content = content
|
|
567
614
|
|
|
568
615
|
if "usage" in response:
|
|
569
|
-
model_response.response_usage =
|
|
570
|
-
"input_tokens": response["usage"]["inputTokens"],
|
|
571
|
-
"output_tokens": response["usage"]["outputTokens"],
|
|
572
|
-
"total_tokens": response["usage"]["totalTokens"],
|
|
573
|
-
}
|
|
616
|
+
model_response.response_usage = self._get_metrics(response["usage"])
|
|
574
617
|
|
|
575
618
|
return model_response
|
|
576
619
|
|
|
@@ -582,6 +625,7 @@ class AwsBedrock(Model):
|
|
|
582
625
|
response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
|
|
583
626
|
tools: Optional[List[Dict[str, Any]]] = None,
|
|
584
627
|
tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
|
|
628
|
+
run_response: Optional[RunOutput] = None,
|
|
585
629
|
) -> Iterator[ModelResponse]:
|
|
586
630
|
"""
|
|
587
631
|
Process the synchronous response stream.
|
|
@@ -591,94 +635,28 @@ class AwsBedrock(Model):
|
|
|
591
635
|
assistant_message (Message): The assistant message.
|
|
592
636
|
stream_data (MessageData): The stream data.
|
|
593
637
|
"""
|
|
594
|
-
tool_use: Dict[str, Any] = {}
|
|
595
|
-
content = []
|
|
596
|
-
tool_ids = []
|
|
597
|
-
|
|
598
638
|
for response_delta in self.invoke_stream(
|
|
599
|
-
messages=messages,
|
|
639
|
+
messages=messages,
|
|
640
|
+
assistant_message=assistant_message,
|
|
641
|
+
response_format=response_format,
|
|
642
|
+
tools=tools,
|
|
643
|
+
tool_choice=tool_choice,
|
|
644
|
+
run_response=run_response,
|
|
600
645
|
):
|
|
601
|
-
model_response = ModelResponse(role="assistant")
|
|
602
646
|
should_yield = False
|
|
603
|
-
if "contentBlockStart" in response_delta:
|
|
604
|
-
# Handle tool use requests
|
|
605
|
-
tool = response_delta["contentBlockStart"]["start"].get("toolUse")
|
|
606
|
-
if tool:
|
|
607
|
-
tool_use["toolUseId"] = tool["toolUseId"]
|
|
608
|
-
tool_use["name"] = tool["name"]
|
|
609
|
-
|
|
610
|
-
elif "contentBlockDelta" in response_delta:
|
|
611
|
-
delta = response_delta["contentBlockDelta"]["delta"]
|
|
612
|
-
if "toolUse" in delta:
|
|
613
|
-
if "input" not in tool_use:
|
|
614
|
-
tool_use["input"] = ""
|
|
615
|
-
tool_use["input"] += delta["toolUse"]["input"]
|
|
616
|
-
elif "text" in delta:
|
|
617
|
-
model_response.content = delta["text"]
|
|
618
|
-
|
|
619
|
-
elif "contentBlockStop" in response_delta:
|
|
620
|
-
if "input" in tool_use:
|
|
621
|
-
# Finish collecting tool use input
|
|
622
|
-
try:
|
|
623
|
-
tool_use["input"] = json.loads(tool_use["input"])
|
|
624
|
-
except json.JSONDecodeError as e:
|
|
625
|
-
log_error(f"Failed to parse tool input as JSON: {e}")
|
|
626
|
-
tool_use["input"] = {}
|
|
627
|
-
content.append({"toolUse": tool_use})
|
|
628
|
-
tool_ids.append(tool_use["toolUseId"])
|
|
629
|
-
# Prepare the tool call
|
|
630
|
-
tool_call = {
|
|
631
|
-
"id": tool_use["toolUseId"],
|
|
632
|
-
"type": "function",
|
|
633
|
-
"function": {
|
|
634
|
-
"name": tool_use["name"],
|
|
635
|
-
"arguments": json.dumps(tool_use["input"]),
|
|
636
|
-
},
|
|
637
|
-
}
|
|
638
|
-
# Append the tool call to the list of "done" tool calls
|
|
639
|
-
model_response.tool_calls.append(tool_call)
|
|
640
|
-
# Reset the tool use
|
|
641
|
-
tool_use = {}
|
|
642
|
-
else:
|
|
643
|
-
# Finish collecting text content
|
|
644
|
-
content.append({"text": stream_data.response_content})
|
|
645
|
-
|
|
646
|
-
elif "messageStop" in response_delta or "metadata" in response_delta:
|
|
647
|
-
body = response_delta.get("metadata") or response_delta.get("messageStop") or {}
|
|
648
|
-
if "usage" in body:
|
|
649
|
-
usage = body["usage"]
|
|
650
|
-
model_response.response_usage = {
|
|
651
|
-
"input_tokens": usage.get("inputTokens", 0),
|
|
652
|
-
"output_tokens": usage.get("outputTokens", 0),
|
|
653
|
-
"total_tokens": usage.get("totalTokens", 0),
|
|
654
|
-
}
|
|
655
647
|
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
assistant_message.metrics.set_time_to_first_token()
|
|
659
|
-
|
|
660
|
-
if model_response.content:
|
|
661
|
-
stream_data.response_content += model_response.content
|
|
648
|
+
if response_delta.content:
|
|
649
|
+
stream_data.response_content += response_delta.content
|
|
662
650
|
should_yield = True
|
|
663
651
|
|
|
664
|
-
if
|
|
652
|
+
if response_delta.tool_calls:
|
|
665
653
|
if stream_data.response_tool_calls is None:
|
|
666
654
|
stream_data.response_tool_calls = []
|
|
667
|
-
stream_data.response_tool_calls.extend(
|
|
655
|
+
stream_data.response_tool_calls.extend(response_delta.tool_calls)
|
|
668
656
|
should_yield = True
|
|
669
657
|
|
|
670
|
-
if model_response.response_usage is not None:
|
|
671
|
-
_add_usage_metrics_to_assistant_message(
|
|
672
|
-
assistant_message=assistant_message, response_usage=model_response.response_usage
|
|
673
|
-
)
|
|
674
|
-
|
|
675
658
|
if should_yield:
|
|
676
|
-
yield
|
|
677
|
-
|
|
678
|
-
if tool_ids:
|
|
679
|
-
if stream_data.extra is None:
|
|
680
|
-
stream_data.extra = {}
|
|
681
|
-
stream_data.extra["tool_ids"] = tool_ids
|
|
659
|
+
yield response_delta
|
|
682
660
|
|
|
683
661
|
async def aprocess_response_stream(
|
|
684
662
|
self,
|
|
@@ -688,6 +666,7 @@ class AwsBedrock(Model):
|
|
|
688
666
|
response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
|
|
689
667
|
tools: Optional[List[Dict[str, Any]]] = None,
|
|
690
668
|
tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
|
|
669
|
+
run_response: Optional[RunOutput] = None,
|
|
691
670
|
) -> AsyncIterator[ModelResponse]:
|
|
692
671
|
"""
|
|
693
672
|
Process the asynchronous response stream.
|
|
@@ -697,96 +676,32 @@ class AwsBedrock(Model):
|
|
|
697
676
|
assistant_message (Message): The assistant message.
|
|
698
677
|
stream_data (MessageData): The stream data.
|
|
699
678
|
"""
|
|
700
|
-
tool_use: Dict[str, Any] = {}
|
|
701
|
-
content = []
|
|
702
|
-
tool_ids = []
|
|
703
|
-
|
|
704
679
|
async for response_delta in self.ainvoke_stream(
|
|
705
|
-
messages=messages,
|
|
680
|
+
messages=messages,
|
|
681
|
+
assistant_message=assistant_message,
|
|
682
|
+
response_format=response_format,
|
|
683
|
+
tools=tools,
|
|
684
|
+
tool_choice=tool_choice,
|
|
685
|
+
run_response=run_response,
|
|
706
686
|
):
|
|
707
|
-
model_response = ModelResponse(role="assistant")
|
|
708
687
|
should_yield = False
|
|
709
|
-
if "contentBlockStart" in response_delta:
|
|
710
|
-
# Handle tool use requests
|
|
711
|
-
tool = response_delta["contentBlockStart"]["start"].get("toolUse")
|
|
712
|
-
if tool:
|
|
713
|
-
tool_use["toolUseId"] = tool["toolUseId"]
|
|
714
|
-
tool_use["name"] = tool["name"]
|
|
715
|
-
|
|
716
|
-
elif "contentBlockDelta" in response_delta:
|
|
717
|
-
delta = response_delta["contentBlockDelta"]["delta"]
|
|
718
|
-
if "toolUse" in delta:
|
|
719
|
-
if "input" not in tool_use:
|
|
720
|
-
tool_use["input"] = ""
|
|
721
|
-
tool_use["input"] += delta["toolUse"]["input"]
|
|
722
|
-
elif "text" in delta:
|
|
723
|
-
model_response.content = delta["text"]
|
|
724
|
-
|
|
725
|
-
elif "contentBlockStop" in response_delta:
|
|
726
|
-
if "input" in tool_use:
|
|
727
|
-
# Finish collecting tool use input
|
|
728
|
-
try:
|
|
729
|
-
tool_use["input"] = json.loads(tool_use["input"])
|
|
730
|
-
except json.JSONDecodeError as e:
|
|
731
|
-
log_error(f"Failed to parse tool input as JSON: {e}")
|
|
732
|
-
tool_use["input"] = {}
|
|
733
|
-
content.append({"toolUse": tool_use})
|
|
734
|
-
tool_ids.append(tool_use["toolUseId"])
|
|
735
|
-
# Prepare the tool call
|
|
736
|
-
tool_call = {
|
|
737
|
-
"id": tool_use["toolUseId"],
|
|
738
|
-
"type": "function",
|
|
739
|
-
"function": {
|
|
740
|
-
"name": tool_use["name"],
|
|
741
|
-
"arguments": json.dumps(tool_use["input"]),
|
|
742
|
-
},
|
|
743
|
-
}
|
|
744
|
-
# Append the tool call to the list of "done" tool calls
|
|
745
|
-
model_response.tool_calls.append(tool_call)
|
|
746
|
-
# Reset the tool use
|
|
747
|
-
tool_use = {}
|
|
748
|
-
else:
|
|
749
|
-
# Finish collecting text content
|
|
750
|
-
content.append({"text": stream_data.response_content})
|
|
751
|
-
|
|
752
|
-
elif "messageStop" in response_delta or "metadata" in response_delta:
|
|
753
|
-
body = response_delta.get("metadata") or response_delta.get("messageStop") or {}
|
|
754
|
-
if "usage" in body:
|
|
755
|
-
usage = body["usage"]
|
|
756
|
-
model_response.response_usage = {
|
|
757
|
-
"input_tokens": usage.get("inputTokens", 0),
|
|
758
|
-
"output_tokens": usage.get("outputTokens", 0),
|
|
759
|
-
"total_tokens": usage.get("totalTokens", 0),
|
|
760
|
-
}
|
|
761
|
-
|
|
762
|
-
# Update metrics
|
|
763
|
-
if not assistant_message.metrics.time_to_first_token:
|
|
764
|
-
assistant_message.metrics.set_time_to_first_token()
|
|
765
688
|
|
|
766
|
-
if
|
|
767
|
-
stream_data.response_content +=
|
|
689
|
+
if response_delta.content:
|
|
690
|
+
stream_data.response_content += response_delta.content
|
|
768
691
|
should_yield = True
|
|
769
692
|
|
|
770
|
-
if
|
|
693
|
+
if response_delta.tool_calls:
|
|
771
694
|
if stream_data.response_tool_calls is None:
|
|
772
695
|
stream_data.response_tool_calls = []
|
|
773
|
-
stream_data.response_tool_calls.extend(
|
|
696
|
+
stream_data.response_tool_calls.extend(response_delta.tool_calls)
|
|
774
697
|
should_yield = True
|
|
775
698
|
|
|
776
|
-
if model_response.response_usage is not None:
|
|
777
|
-
_add_usage_metrics_to_assistant_message(
|
|
778
|
-
assistant_message=assistant_message, response_usage=model_response.response_usage
|
|
779
|
-
)
|
|
780
|
-
|
|
781
699
|
if should_yield:
|
|
782
|
-
yield
|
|
700
|
+
yield response_delta
|
|
783
701
|
|
|
784
|
-
|
|
785
|
-
if stream_data.extra is None:
|
|
786
|
-
stream_data.extra = {}
|
|
787
|
-
stream_data.extra["tool_ids"] = tool_ids
|
|
702
|
+
self._populate_assistant_message(assistant_message=assistant_message, provider_response=response_delta)
|
|
788
703
|
|
|
789
|
-
def
|
|
704
|
+
def _parse_provider_response_delta(self, response_delta: Dict[str, Any]) -> ModelResponse: # type: ignore
|
|
790
705
|
"""Parse the provider response delta for streaming.
|
|
791
706
|
|
|
792
707
|
Args:
|
|
@@ -823,11 +738,24 @@ class AwsBedrock(Model):
|
|
|
823
738
|
elif "metadata" in response_delta or "messageStop" in response_delta:
|
|
824
739
|
body = response_delta.get("metadata") or response_delta.get("messageStop") or {}
|
|
825
740
|
if "usage" in body:
|
|
826
|
-
|
|
827
|
-
model_response.response_usage = {
|
|
828
|
-
"input_tokens": usage.get("inputTokens", 0),
|
|
829
|
-
"output_tokens": usage.get("outputTokens", 0),
|
|
830
|
-
"total_tokens": usage.get("totalTokens", 0),
|
|
831
|
-
}
|
|
741
|
+
model_response.response_usage = self._get_metrics(body["usage"])
|
|
832
742
|
|
|
833
743
|
return model_response
|
|
744
|
+
|
|
745
|
+
def _get_metrics(self, response_usage: Dict[str, Any]) -> Metrics:
|
|
746
|
+
"""
|
|
747
|
+
Parse the given AWS Bedrock usage into an Agno Metrics object.
|
|
748
|
+
|
|
749
|
+
Args:
|
|
750
|
+
response_usage: Usage data from AWS Bedrock
|
|
751
|
+
|
|
752
|
+
Returns:
|
|
753
|
+
Metrics: Parsed metrics data
|
|
754
|
+
"""
|
|
755
|
+
metrics = Metrics()
|
|
756
|
+
|
|
757
|
+
metrics.input_tokens = response_usage.get("inputTokens", 0) or 0
|
|
758
|
+
metrics.output_tokens = response_usage.get("outputTokens", 0) or 0
|
|
759
|
+
metrics.total_tokens = metrics.input_tokens + metrics.output_tokens
|
|
760
|
+
|
|
761
|
+
return metrics
|
agno/models/aws/claude.py
CHANGED
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
from dataclasses import dataclass
|
|
2
2
|
from os import getenv
|
|
3
|
-
from typing import Any, AsyncIterator, Dict, List, Optional, Type, Union
|
|
3
|
+
from typing import Any, AsyncIterator, Dict, Iterator, List, Optional, Type, Union
|
|
4
4
|
|
|
5
5
|
from pydantic import BaseModel
|
|
6
6
|
|
|
7
7
|
from agno.exceptions import ModelProviderError, ModelRateLimitError
|
|
8
8
|
from agno.models.anthropic import Claude as AnthropicClaude
|
|
9
9
|
from agno.models.message import Message
|
|
10
|
+
from agno.models.response import ModelResponse
|
|
11
|
+
from agno.run.agent import RunOutput
|
|
10
12
|
from agno.utils.log import log_debug, log_error, log_warning
|
|
11
13
|
from agno.utils.models.aws_claude import format_messages
|
|
12
14
|
|
|
13
15
|
try:
|
|
14
16
|
from anthropic import AnthropicBedrock, APIConnectionError, APIStatusError, AsyncAnthropicBedrock, RateLimitError
|
|
15
|
-
from anthropic.types import Message as AnthropicMessage
|
|
16
17
|
except ImportError:
|
|
17
18
|
raise ImportError("`anthropic[bedrock]` not installed. Please install using `pip install anthropic[bedrock]`")
|
|
18
19
|
|
|
@@ -167,10 +168,12 @@ class Claude(AnthropicClaude):
|
|
|
167
168
|
def invoke(
|
|
168
169
|
self,
|
|
169
170
|
messages: List[Message],
|
|
171
|
+
assistant_message: Message,
|
|
170
172
|
response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
|
|
171
173
|
tools: Optional[List[Dict[str, Any]]] = None,
|
|
172
174
|
tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
|
|
173
|
-
|
|
175
|
+
run_response: Optional[RunOutput] = None,
|
|
176
|
+
) -> ModelResponse:
|
|
174
177
|
"""
|
|
175
178
|
Send a request to the Anthropic API to generate a response.
|
|
176
179
|
"""
|
|
@@ -179,11 +182,21 @@ class Claude(AnthropicClaude):
|
|
|
179
182
|
chat_messages, system_message = format_messages(messages)
|
|
180
183
|
request_kwargs = self._prepare_request_kwargs(system_message, tools)
|
|
181
184
|
|
|
182
|
-
|
|
185
|
+
if run_response and run_response.metrics:
|
|
186
|
+
run_response.metrics.set_time_to_first_token()
|
|
187
|
+
|
|
188
|
+
assistant_message.metrics.start_timer()
|
|
189
|
+
response = self.get_client().messages.create(
|
|
183
190
|
model=self.id,
|
|
184
191
|
messages=chat_messages, # type: ignore
|
|
185
192
|
**request_kwargs,
|
|
186
193
|
)
|
|
194
|
+
assistant_message.metrics.stop_timer()
|
|
195
|
+
|
|
196
|
+
model_response = self._parse_provider_response(response, response_format=response_format)
|
|
197
|
+
|
|
198
|
+
return model_response
|
|
199
|
+
|
|
187
200
|
except APIConnectionError as e:
|
|
188
201
|
log_error(f"Connection error while calling Claude API: {str(e)}")
|
|
189
202
|
raise ModelProviderError(message=e.message, model_name=self.name, model_id=self.id) from e
|
|
@@ -202,10 +215,12 @@ class Claude(AnthropicClaude):
|
|
|
202
215
|
def invoke_stream(
|
|
203
216
|
self,
|
|
204
217
|
messages: List[Message],
|
|
218
|
+
assistant_message: Message,
|
|
205
219
|
response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
|
|
206
220
|
tools: Optional[List[Dict[str, Any]]] = None,
|
|
207
221
|
tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
|
|
208
|
-
|
|
222
|
+
run_response: Optional[RunOutput] = None,
|
|
223
|
+
) -> Iterator[ModelResponse]:
|
|
209
224
|
"""
|
|
210
225
|
Stream a response from the Anthropic API.
|
|
211
226
|
|
|
@@ -225,15 +240,21 @@ class Claude(AnthropicClaude):
|
|
|
225
240
|
request_kwargs = self._prepare_request_kwargs(system_message, tools)
|
|
226
241
|
|
|
227
242
|
try:
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
243
|
+
if run_response and run_response.metrics:
|
|
244
|
+
run_response.metrics.set_time_to_first_token()
|
|
245
|
+
|
|
246
|
+
assistant_message.metrics.start_timer()
|
|
247
|
+
|
|
248
|
+
with self.get_client().messages.stream(
|
|
249
|
+
model=self.id,
|
|
250
|
+
messages=chat_messages, # type: ignore
|
|
251
|
+
**request_kwargs,
|
|
252
|
+
) as stream:
|
|
253
|
+
for chunk in stream:
|
|
254
|
+
yield self._parse_provider_response_delta(chunk)
|
|
255
|
+
|
|
256
|
+
assistant_message.metrics.stop_timer()
|
|
257
|
+
|
|
237
258
|
except APIConnectionError as e:
|
|
238
259
|
log_error(f"Connection error while calling Claude API: {str(e)}")
|
|
239
260
|
raise ModelProviderError(message=e.message, model_name=self.name, model_id=self.id) from e
|
|
@@ -252,10 +273,12 @@ class Claude(AnthropicClaude):
|
|
|
252
273
|
async def ainvoke(
|
|
253
274
|
self,
|
|
254
275
|
messages: List[Message],
|
|
276
|
+
assistant_message: Message,
|
|
255
277
|
response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
|
|
256
278
|
tools: Optional[List[Dict[str, Any]]] = None,
|
|
257
279
|
tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
|
|
258
|
-
|
|
280
|
+
run_response: Optional[RunOutput] = None,
|
|
281
|
+
) -> ModelResponse:
|
|
259
282
|
"""
|
|
260
283
|
Send an asynchronous request to the Anthropic API to generate a response.
|
|
261
284
|
"""
|
|
@@ -264,11 +287,23 @@ class Claude(AnthropicClaude):
|
|
|
264
287
|
chat_messages, system_message = format_messages(messages)
|
|
265
288
|
request_kwargs = self._prepare_request_kwargs(system_message, tools)
|
|
266
289
|
|
|
267
|
-
|
|
290
|
+
if run_response and run_response.metrics:
|
|
291
|
+
run_response.metrics.set_time_to_first_token()
|
|
292
|
+
|
|
293
|
+
assistant_message.metrics.start_timer()
|
|
294
|
+
|
|
295
|
+
response = await self.get_async_client().messages.create(
|
|
268
296
|
model=self.id,
|
|
269
297
|
messages=chat_messages, # type: ignore
|
|
270
298
|
**request_kwargs,
|
|
271
299
|
)
|
|
300
|
+
|
|
301
|
+
assistant_message.metrics.stop_timer()
|
|
302
|
+
|
|
303
|
+
model_response = self._parse_provider_response(response, response_format=response_format)
|
|
304
|
+
|
|
305
|
+
return model_response
|
|
306
|
+
|
|
272
307
|
except APIConnectionError as e:
|
|
273
308
|
log_error(f"Connection error while calling Claude API: {str(e)}")
|
|
274
309
|
raise ModelProviderError(message=e.message, model_name=self.name, model_id=self.id) from e
|
|
@@ -287,10 +322,12 @@ class Claude(AnthropicClaude):
|
|
|
287
322
|
async def ainvoke_stream(
|
|
288
323
|
self,
|
|
289
324
|
messages: List[Message],
|
|
325
|
+
assistant_message: Message,
|
|
290
326
|
response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
|
|
291
327
|
tools: Optional[List[Dict[str, Any]]] = None,
|
|
292
328
|
tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
|
|
293
|
-
|
|
329
|
+
run_response: Optional[RunOutput] = None,
|
|
330
|
+
) -> AsyncIterator[ModelResponse]:
|
|
294
331
|
"""
|
|
295
332
|
Stream an asynchronous response from the Anthropic API.
|
|
296
333
|
|
|
@@ -309,13 +346,22 @@ class Claude(AnthropicClaude):
|
|
|
309
346
|
try:
|
|
310
347
|
chat_messages, system_message = format_messages(messages)
|
|
311
348
|
request_kwargs = self._prepare_request_kwargs(system_message, tools)
|
|
349
|
+
|
|
350
|
+
if run_response and run_response.metrics:
|
|
351
|
+
run_response.metrics.set_time_to_first_token()
|
|
352
|
+
|
|
353
|
+
assistant_message.metrics.start_timer()
|
|
354
|
+
|
|
312
355
|
async with self.get_async_client().messages.stream(
|
|
313
356
|
model=self.id,
|
|
314
357
|
messages=chat_messages, # type: ignore
|
|
315
358
|
**request_kwargs,
|
|
316
359
|
) as stream:
|
|
317
360
|
async for chunk in stream:
|
|
318
|
-
yield chunk
|
|
361
|
+
yield self._parse_provider_response_delta(chunk)
|
|
362
|
+
|
|
363
|
+
assistant_message.metrics.stop_timer()
|
|
364
|
+
|
|
319
365
|
except APIConnectionError as e:
|
|
320
366
|
log_error(f"Connection error while calling Claude API: {str(e)}")
|
|
321
367
|
raise ModelProviderError(message=e.message, model_name=self.name, model_id=self.id) from e
|