agno 1.8.1__py3-none-any.whl → 2.0.0rc1__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 +3181 -4169
- 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 +1411 -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 +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 +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 +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/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 +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/google/gemini.py +100 -42
- 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 +45 -150
- 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 +121 -23
- 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 +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 +489 -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 +255 -0
- agno/os/router.py +869 -0
- agno/os/routers/__init__.py +3 -0
- agno/os/routers/evals/__init__.py +3 -0
- agno/os/routers/evals/evals.py +208 -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 +436 -0
- agno/os/routers/knowledge/schemas.py +118 -0
- agno/os/routers/memory/__init__.py +3 -0
- agno/os/routers/memory/memory.py +188 -0
- agno/os/routers/memory/schemas.py +58 -0
- agno/os/routers/metrics/__init__.py +3 -0
- agno/os/routers/metrics/metrics.py +60 -0
- agno/os/routers/metrics/schemas.py +47 -0
- agno/os/routers/session/__init__.py +3 -0
- agno/os/routers/session/session.py +168 -0
- agno/os/schema.py +892 -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/{response.py → agent.py} +231 -74
- agno/run/base.py +44 -58
- agno/run/cancel.py +81 -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 +2960 -4252
- 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 +8 -8
- 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 +61 -61
- 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 +127 -18
- agno/tools/giphy.py +22 -10
- 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 +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 +10 -8
- 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/gemini.py +31 -1
- agno/utils/knowledge.py +29 -0
- 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 +55 -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/streamlit.py +454 -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} +200 -42
- agno/workflow/{v2/steps.py → steps.py} +147 -66
- agno/workflow/types.py +482 -0
- agno/workflow/workflow.py +2401 -696
- agno-2.0.0rc1.dist-info/METADATA +355 -0
- agno-2.0.0rc1.dist-info/RECORD +516 -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/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/{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.0rc1.dist-info}/WHEEL +0 -0
- {agno-1.8.1.dist-info → agno-2.0.0rc1.dist-info}/licenses/LICENSE +0 -0
- {agno-1.8.1.dist-info → agno-2.0.0rc1.dist-info}/top_level.txt +0 -0
agno/models/google/gemini.py
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import json
|
|
2
2
|
import time
|
|
3
|
+
from collections.abc import AsyncIterator
|
|
3
4
|
from dataclasses import dataclass
|
|
4
5
|
from os import getenv
|
|
5
6
|
from pathlib import Path
|
|
6
|
-
from typing import Any, Dict, List, Optional, Type, Union
|
|
7
|
+
from typing import Any, Dict, Iterator, List, Optional, Type, Union
|
|
7
8
|
from uuid import uuid4
|
|
8
9
|
|
|
9
10
|
from pydantic import BaseModel
|
|
@@ -11,8 +12,10 @@ from pydantic import BaseModel
|
|
|
11
12
|
from agno.exceptions import ModelProviderError
|
|
12
13
|
from agno.media import Audio, File, ImageArtifact, Video
|
|
13
14
|
from agno.models.base import Model
|
|
14
|
-
from agno.models.message import Citations, Message,
|
|
15
|
+
from agno.models.message import Citations, Message, UrlCitation
|
|
16
|
+
from agno.models.metrics import Metrics
|
|
15
17
|
from agno.models.response import ModelResponse
|
|
18
|
+
from agno.run.agent import RunOutput
|
|
16
19
|
from agno.utils.gemini import convert_schema, format_function_definitions, format_image_for_message
|
|
17
20
|
from agno.utils.log import log_debug, log_error, log_info, log_warning
|
|
18
21
|
from agno.utils.models.schema_utils import get_response_schema_for_provider
|
|
@@ -262,21 +265,33 @@ class Gemini(Model):
|
|
|
262
265
|
def invoke(
|
|
263
266
|
self,
|
|
264
267
|
messages: List[Message],
|
|
268
|
+
assistant_message: Message,
|
|
265
269
|
response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
|
|
266
270
|
tools: Optional[List[Dict[str, Any]]] = None,
|
|
267
271
|
tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
|
|
268
|
-
|
|
272
|
+
run_response: Optional[RunOutput] = None,
|
|
273
|
+
) -> ModelResponse:
|
|
269
274
|
"""
|
|
270
275
|
Invokes the model with a list of messages and returns the response.
|
|
271
276
|
"""
|
|
272
277
|
formatted_messages, system_message = self._format_messages(messages)
|
|
273
278
|
request_kwargs = self.get_request_params(system_message, response_format=response_format, tools=tools)
|
|
274
279
|
try:
|
|
275
|
-
|
|
280
|
+
if run_response and run_response.metrics:
|
|
281
|
+
run_response.metrics.set_time_to_first_token()
|
|
282
|
+
|
|
283
|
+
assistant_message.metrics.start_timer()
|
|
284
|
+
provider_response = self.get_client().models.generate_content(
|
|
276
285
|
model=self.id,
|
|
277
286
|
contents=formatted_messages,
|
|
278
287
|
**request_kwargs,
|
|
279
288
|
)
|
|
289
|
+
assistant_message.metrics.stop_timer()
|
|
290
|
+
|
|
291
|
+
model_response = self._parse_provider_response(provider_response, response_format=response_format)
|
|
292
|
+
|
|
293
|
+
return model_response
|
|
294
|
+
|
|
280
295
|
except (ClientError, ServerError) as e:
|
|
281
296
|
log_error(f"Error from Gemini API: {e}")
|
|
282
297
|
error_message = str(e.response) if hasattr(e, "response") else str(e)
|
|
@@ -293,10 +308,12 @@ class Gemini(Model):
|
|
|
293
308
|
def invoke_stream(
|
|
294
309
|
self,
|
|
295
310
|
messages: List[Message],
|
|
311
|
+
assistant_message: Message,
|
|
296
312
|
response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
|
|
297
313
|
tools: Optional[List[Dict[str, Any]]] = None,
|
|
298
314
|
tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
|
|
299
|
-
|
|
315
|
+
run_response: Optional[RunOutput] = None,
|
|
316
|
+
) -> Iterator[ModelResponse]:
|
|
300
317
|
"""
|
|
301
318
|
Invokes the model with a list of messages and returns the response as a stream.
|
|
302
319
|
"""
|
|
@@ -304,11 +321,19 @@ class Gemini(Model):
|
|
|
304
321
|
|
|
305
322
|
request_kwargs = self.get_request_params(system_message, response_format=response_format, tools=tools)
|
|
306
323
|
try:
|
|
307
|
-
|
|
324
|
+
if run_response and run_response.metrics:
|
|
325
|
+
run_response.metrics.set_time_to_first_token()
|
|
326
|
+
|
|
327
|
+
assistant_message.metrics.start_timer()
|
|
328
|
+
for response in self.get_client().models.generate_content_stream(
|
|
308
329
|
model=self.id,
|
|
309
330
|
contents=formatted_messages,
|
|
310
331
|
**request_kwargs,
|
|
311
|
-
)
|
|
332
|
+
):
|
|
333
|
+
yield self._parse_provider_response_delta(response)
|
|
334
|
+
|
|
335
|
+
assistant_message.metrics.stop_timer()
|
|
336
|
+
|
|
312
337
|
except (ClientError, ServerError) as e:
|
|
313
338
|
log_error(f"Error from Gemini API: {e}")
|
|
314
339
|
raise ModelProviderError(
|
|
@@ -324,10 +349,12 @@ class Gemini(Model):
|
|
|
324
349
|
async def ainvoke(
|
|
325
350
|
self,
|
|
326
351
|
messages: List[Message],
|
|
352
|
+
assistant_message: Message,
|
|
327
353
|
response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
|
|
328
354
|
tools: Optional[List[Dict[str, Any]]] = None,
|
|
329
355
|
tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
|
|
330
|
-
|
|
356
|
+
run_response: Optional[RunOutput] = None,
|
|
357
|
+
) -> ModelResponse:
|
|
331
358
|
"""
|
|
332
359
|
Invokes the model with a list of messages and returns the response.
|
|
333
360
|
"""
|
|
@@ -336,11 +363,21 @@ class Gemini(Model):
|
|
|
336
363
|
request_kwargs = self.get_request_params(system_message, response_format=response_format, tools=tools)
|
|
337
364
|
|
|
338
365
|
try:
|
|
339
|
-
|
|
366
|
+
if run_response and run_response.metrics:
|
|
367
|
+
run_response.metrics.set_time_to_first_token()
|
|
368
|
+
|
|
369
|
+
assistant_message.metrics.start_timer()
|
|
370
|
+
provider_response = await self.get_client().aio.models.generate_content(
|
|
340
371
|
model=self.id,
|
|
341
372
|
contents=formatted_messages,
|
|
342
373
|
**request_kwargs,
|
|
343
374
|
)
|
|
375
|
+
assistant_message.metrics.stop_timer()
|
|
376
|
+
|
|
377
|
+
model_response = self._parse_provider_response(provider_response, response_format=response_format)
|
|
378
|
+
|
|
379
|
+
return model_response
|
|
380
|
+
|
|
344
381
|
except (ClientError, ServerError) as e:
|
|
345
382
|
log_error(f"Error from Gemini API: {e}")
|
|
346
383
|
raise ModelProviderError(
|
|
@@ -356,10 +393,12 @@ class Gemini(Model):
|
|
|
356
393
|
async def ainvoke_stream(
|
|
357
394
|
self,
|
|
358
395
|
messages: List[Message],
|
|
396
|
+
assistant_message: Message,
|
|
359
397
|
response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
|
|
360
398
|
tools: Optional[List[Dict[str, Any]]] = None,
|
|
361
399
|
tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
|
|
362
|
-
|
|
400
|
+
run_response: Optional[RunOutput] = None,
|
|
401
|
+
) -> AsyncIterator[ModelResponse]:
|
|
363
402
|
"""
|
|
364
403
|
Invokes the model with a list of messages and returns the response as a stream.
|
|
365
404
|
"""
|
|
@@ -368,13 +407,21 @@ class Gemini(Model):
|
|
|
368
407
|
request_kwargs = self.get_request_params(system_message, response_format=response_format, tools=tools)
|
|
369
408
|
|
|
370
409
|
try:
|
|
410
|
+
if run_response and run_response.metrics:
|
|
411
|
+
run_response.metrics.set_time_to_first_token()
|
|
412
|
+
|
|
413
|
+
assistant_message.metrics.start_timer()
|
|
414
|
+
|
|
371
415
|
async_stream = await self.get_client().aio.models.generate_content_stream(
|
|
372
416
|
model=self.id,
|
|
373
417
|
contents=formatted_messages,
|
|
374
418
|
**request_kwargs,
|
|
375
419
|
)
|
|
376
420
|
async for chunk in async_stream:
|
|
377
|
-
yield chunk
|
|
421
|
+
yield self._parse_provider_response_delta(chunk)
|
|
422
|
+
|
|
423
|
+
assistant_message.metrics.stop_timer()
|
|
424
|
+
|
|
378
425
|
except (ClientError, ServerError) as e:
|
|
379
426
|
log_error(f"Error from Gemini API: {e}")
|
|
380
427
|
raise ModelProviderError(
|
|
@@ -696,7 +743,7 @@ class Gemini(Model):
|
|
|
696
743
|
"""
|
|
697
744
|
combined_content: List = []
|
|
698
745
|
combined_function_result: List = []
|
|
699
|
-
message_metrics =
|
|
746
|
+
message_metrics = Metrics()
|
|
700
747
|
if len(function_call_results) > 0:
|
|
701
748
|
for result in function_call_results:
|
|
702
749
|
combined_content.append(result.content)
|
|
@@ -710,7 +757,7 @@ class Gemini(Model):
|
|
|
710
757
|
)
|
|
711
758
|
)
|
|
712
759
|
|
|
713
|
-
def
|
|
760
|
+
def _parse_provider_response(self, response: GenerateContentResponse, **kwargs) -> ModelResponse:
|
|
714
761
|
"""
|
|
715
762
|
Parse the OpenAI response into a ModelResponse.
|
|
716
763
|
|
|
@@ -765,8 +812,12 @@ class Gemini(Model):
|
|
|
765
812
|
model_response.content += content_str
|
|
766
813
|
|
|
767
814
|
if hasattr(part, "inline_data") and part.inline_data is not None:
|
|
768
|
-
model_response.
|
|
769
|
-
|
|
815
|
+
if model_response.images is None:
|
|
816
|
+
model_response.images = []
|
|
817
|
+
model_response.images.append(
|
|
818
|
+
ImageArtifact(
|
|
819
|
+
id=str(uuid4()), content=part.inline_data.data, mime_type=part.inline_data.mime_type
|
|
820
|
+
)
|
|
770
821
|
)
|
|
771
822
|
|
|
772
823
|
# Extract function call if present
|
|
@@ -836,18 +887,7 @@ class Gemini(Model):
|
|
|
836
887
|
|
|
837
888
|
# Extract usage metadata if present
|
|
838
889
|
if hasattr(response, "usage_metadata") and response.usage_metadata is not None:
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
output_tokens = usage.candidates_token_count or 0
|
|
842
|
-
if hasattr(usage, "thoughts_token_count") and usage.thoughts_token_count is not None:
|
|
843
|
-
output_tokens += usage.thoughts_token_count or 0
|
|
844
|
-
|
|
845
|
-
model_response.response_usage = {
|
|
846
|
-
"input_tokens": usage.prompt_token_count or 0,
|
|
847
|
-
"output_tokens": output_tokens,
|
|
848
|
-
"total_tokens": usage.total_token_count or 0,
|
|
849
|
-
"cached_tokens": usage.cached_content_token_count or 0,
|
|
850
|
-
}
|
|
890
|
+
model_response.response_usage = self._get_metrics(response.usage_metadata)
|
|
851
891
|
|
|
852
892
|
# If we have no content but have a role, add a default empty content
|
|
853
893
|
if model_response.role and model_response.content is None and not model_response.tool_calls:
|
|
@@ -855,7 +895,7 @@ class Gemini(Model):
|
|
|
855
895
|
|
|
856
896
|
return model_response
|
|
857
897
|
|
|
858
|
-
def
|
|
898
|
+
def _parse_provider_response_delta(self, response_delta: GenerateContentResponse) -> ModelResponse:
|
|
859
899
|
model_response = ModelResponse()
|
|
860
900
|
|
|
861
901
|
if response_delta.candidates and len(response_delta.candidates) > 0:
|
|
@@ -886,8 +926,12 @@ class Gemini(Model):
|
|
|
886
926
|
model_response.content += text_content
|
|
887
927
|
|
|
888
928
|
if hasattr(part, "inline_data") and part.inline_data is not None:
|
|
889
|
-
model_response.
|
|
890
|
-
|
|
929
|
+
if model_response.images is None:
|
|
930
|
+
model_response.images = []
|
|
931
|
+
model_response.images.append(
|
|
932
|
+
ImageArtifact(
|
|
933
|
+
id=str(uuid4()), content=part.inline_data.data, mime_type=part.inline_data.mime_type
|
|
934
|
+
)
|
|
891
935
|
)
|
|
892
936
|
|
|
893
937
|
# Extract function call if present
|
|
@@ -932,18 +976,7 @@ class Gemini(Model):
|
|
|
932
976
|
|
|
933
977
|
# Extract usage metadata if present
|
|
934
978
|
if hasattr(response_delta, "usage_metadata") and response_delta.usage_metadata is not None:
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
output_tokens = usage.candidates_token_count or 0
|
|
938
|
-
if hasattr(usage, "thoughts_token_count") and usage.thoughts_token_count is not None:
|
|
939
|
-
output_tokens += usage.thoughts_token_count or 0
|
|
940
|
-
|
|
941
|
-
model_response.response_usage = {
|
|
942
|
-
"input_tokens": usage.prompt_token_count or 0,
|
|
943
|
-
"output_tokens": output_tokens,
|
|
944
|
-
"total_tokens": usage.total_token_count or 0,
|
|
945
|
-
"cached_tokens": usage.cached_content_token_count or 0,
|
|
946
|
-
}
|
|
979
|
+
model_response.response_usage = self._get_metrics(response_delta.usage_metadata)
|
|
947
980
|
|
|
948
981
|
return model_response
|
|
949
982
|
|
|
@@ -984,3 +1017,28 @@ class Gemini(Model):
|
|
|
984
1017
|
setattr(new_instance, "client", None)
|
|
985
1018
|
|
|
986
1019
|
return new_instance
|
|
1020
|
+
|
|
1021
|
+
def _get_metrics(self, response_usage: GenerateContentResponseUsageMetadata) -> Metrics:
|
|
1022
|
+
"""
|
|
1023
|
+
Parse the given Google Gemini usage into an Agno Metrics object.
|
|
1024
|
+
|
|
1025
|
+
Args:
|
|
1026
|
+
response_usage: Usage data from Google Gemini
|
|
1027
|
+
|
|
1028
|
+
Returns:
|
|
1029
|
+
Metrics: Parsed metrics data
|
|
1030
|
+
"""
|
|
1031
|
+
metrics = Metrics()
|
|
1032
|
+
|
|
1033
|
+
metrics.input_tokens = response_usage.prompt_token_count or 0
|
|
1034
|
+
metrics.output_tokens = response_usage.candidates_token_count or 0
|
|
1035
|
+
metrics.total_tokens = metrics.input_tokens + metrics.output_tokens
|
|
1036
|
+
if response_usage.thoughts_token_count is not None:
|
|
1037
|
+
metrics.output_tokens += response_usage.thoughts_token_count or 0
|
|
1038
|
+
|
|
1039
|
+
metrics.cache_read_tokens = response_usage.cached_content_token_count or 0
|
|
1040
|
+
|
|
1041
|
+
if response_usage.traffic_type is not None:
|
|
1042
|
+
metrics.provider_metrics = {"traffic_type": response_usage.traffic_type}
|
|
1043
|
+
|
|
1044
|
+
return metrics
|
agno/models/groq/groq.py
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from collections.abc import AsyncIterator
|
|
1
2
|
from dataclasses import dataclass
|
|
2
3
|
from os import getenv
|
|
3
4
|
from typing import Any, Dict, Iterator, List, Optional, Type, Union
|
|
@@ -8,7 +9,9 @@ from pydantic import BaseModel
|
|
|
8
9
|
from agno.exceptions import ModelProviderError
|
|
9
10
|
from agno.models.base import Model
|
|
10
11
|
from agno.models.message import Message
|
|
12
|
+
from agno.models.metrics import Metrics
|
|
11
13
|
from agno.models.response import ModelResponse
|
|
14
|
+
from agno.run.agent import RunOutput
|
|
12
15
|
from agno.utils.log import log_debug, log_error, log_warning
|
|
13
16
|
from agno.utils.openai import images_to_message
|
|
14
17
|
|
|
@@ -18,6 +21,7 @@ try:
|
|
|
18
21
|
from groq import Groq as GroqClient
|
|
19
22
|
from groq.types.chat import ChatCompletion
|
|
20
23
|
from groq.types.chat.chat_completion_chunk import ChatCompletionChunk, ChoiceDelta, ChoiceDeltaToolCall
|
|
24
|
+
from groq.types.completion_usage import CompletionUsage
|
|
21
25
|
except ImportError:
|
|
22
26
|
raise ImportError("`groq` not installed. Please install using `pip install groq`")
|
|
23
27
|
|
|
@@ -250,19 +254,31 @@ class Groq(Model):
|
|
|
250
254
|
def invoke(
|
|
251
255
|
self,
|
|
252
256
|
messages: List[Message],
|
|
257
|
+
assistant_message: Message,
|
|
253
258
|
response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
|
|
254
259
|
tools: Optional[List[Dict[str, Any]]] = None,
|
|
255
260
|
tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
|
|
256
|
-
|
|
261
|
+
run_response: Optional[RunOutput] = None,
|
|
262
|
+
) -> ModelResponse:
|
|
257
263
|
"""
|
|
258
264
|
Send a chat completion request to the Groq API.
|
|
259
265
|
"""
|
|
260
266
|
try:
|
|
261
|
-
|
|
267
|
+
if run_response and run_response.metrics:
|
|
268
|
+
run_response.metrics.set_time_to_first_token()
|
|
269
|
+
|
|
270
|
+
assistant_message.metrics.start_timer()
|
|
271
|
+
provider_response = self.get_client().chat.completions.create(
|
|
262
272
|
model=self.id,
|
|
263
273
|
messages=[self.format_message(m) for m in messages], # type: ignore
|
|
264
274
|
**self.get_request_params(response_format=response_format, tools=tools, tool_choice=tool_choice),
|
|
265
275
|
)
|
|
276
|
+
assistant_message.metrics.stop_timer()
|
|
277
|
+
|
|
278
|
+
model_response = self._parse_provider_response(provider_response, response_format=response_format)
|
|
279
|
+
|
|
280
|
+
return model_response
|
|
281
|
+
|
|
266
282
|
except (APIResponseValidationError, APIStatusError) as e:
|
|
267
283
|
log_error(f"Error calling Groq API: {str(e)}")
|
|
268
284
|
raise ModelProviderError(
|
|
@@ -278,19 +294,31 @@ class Groq(Model):
|
|
|
278
294
|
async def ainvoke(
|
|
279
295
|
self,
|
|
280
296
|
messages: List[Message],
|
|
297
|
+
assistant_message: Message,
|
|
281
298
|
response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
|
|
282
299
|
tools: Optional[List[Dict[str, Any]]] = None,
|
|
283
300
|
tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
|
|
284
|
-
|
|
301
|
+
run_response: Optional[RunOutput] = None,
|
|
302
|
+
) -> ModelResponse:
|
|
285
303
|
"""
|
|
286
304
|
Sends an asynchronous chat completion request to the Groq API.
|
|
287
305
|
"""
|
|
288
306
|
try:
|
|
289
|
-
|
|
307
|
+
if run_response and run_response.metrics:
|
|
308
|
+
run_response.metrics.set_time_to_first_token()
|
|
309
|
+
|
|
310
|
+
assistant_message.metrics.start_timer()
|
|
311
|
+
response = await self.get_async_client().chat.completions.create(
|
|
290
312
|
model=self.id,
|
|
291
313
|
messages=[self.format_message(m) for m in messages], # type: ignore
|
|
292
314
|
**self.get_request_params(response_format=response_format, tools=tools, tool_choice=tool_choice),
|
|
293
315
|
)
|
|
316
|
+
assistant_message.metrics.stop_timer()
|
|
317
|
+
|
|
318
|
+
model_response = self._parse_provider_response(response, response_format=response_format)
|
|
319
|
+
|
|
320
|
+
return model_response
|
|
321
|
+
|
|
294
322
|
except (APIResponseValidationError, APIStatusError) as e:
|
|
295
323
|
log_error(f"Error calling Groq API: {str(e)}")
|
|
296
324
|
raise ModelProviderError(
|
|
@@ -306,20 +334,31 @@ class Groq(Model):
|
|
|
306
334
|
def invoke_stream(
|
|
307
335
|
self,
|
|
308
336
|
messages: List[Message],
|
|
337
|
+
assistant_message: Message,
|
|
309
338
|
response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
|
|
310
339
|
tools: Optional[List[Dict[str, Any]]] = None,
|
|
311
340
|
tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
|
|
312
|
-
|
|
341
|
+
run_response: Optional[RunOutput] = None,
|
|
342
|
+
) -> Iterator[ModelResponse]:
|
|
313
343
|
"""
|
|
314
344
|
Send a streaming chat completion request to the Groq API.
|
|
315
345
|
"""
|
|
316
346
|
try:
|
|
317
|
-
|
|
347
|
+
if run_response and run_response.metrics:
|
|
348
|
+
run_response.metrics.set_time_to_first_token()
|
|
349
|
+
|
|
350
|
+
assistant_message.metrics.start_timer()
|
|
351
|
+
|
|
352
|
+
for chunk in self.get_client().chat.completions.create(
|
|
318
353
|
model=self.id,
|
|
319
354
|
messages=[self.format_message(m) for m in messages], # type: ignore
|
|
320
355
|
stream=True,
|
|
321
356
|
**self.get_request_params(response_format=response_format, tools=tools, tool_choice=tool_choice),
|
|
322
|
-
)
|
|
357
|
+
):
|
|
358
|
+
yield self._parse_provider_response_delta(chunk) # type: ignore
|
|
359
|
+
|
|
360
|
+
assistant_message.metrics.stop_timer()
|
|
361
|
+
|
|
323
362
|
except (APIResponseValidationError, APIStatusError) as e:
|
|
324
363
|
log_error(f"Error calling Groq API: {str(e)}")
|
|
325
364
|
raise ModelProviderError(
|
|
@@ -335,23 +374,33 @@ class Groq(Model):
|
|
|
335
374
|
async def ainvoke_stream(
|
|
336
375
|
self,
|
|
337
376
|
messages: List[Message],
|
|
377
|
+
assistant_message: Message,
|
|
338
378
|
response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
|
|
339
379
|
tools: Optional[List[Dict[str, Any]]] = None,
|
|
340
380
|
tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
|
|
341
|
-
|
|
381
|
+
run_response: Optional[RunOutput] = None,
|
|
382
|
+
) -> AsyncIterator[ModelResponse]:
|
|
342
383
|
"""
|
|
343
384
|
Sends an asynchronous streaming chat completion request to the Groq API.
|
|
344
385
|
"""
|
|
345
386
|
|
|
346
387
|
try:
|
|
347
|
-
|
|
388
|
+
if run_response and run_response.metrics:
|
|
389
|
+
run_response.metrics.set_time_to_first_token()
|
|
390
|
+
|
|
391
|
+
assistant_message.metrics.start_timer()
|
|
392
|
+
|
|
393
|
+
async_stream = await self.get_async_client().chat.completions.create(
|
|
348
394
|
model=self.id,
|
|
349
395
|
messages=[self.format_message(m) for m in messages], # type: ignore
|
|
350
396
|
stream=True,
|
|
351
397
|
**self.get_request_params(response_format=response_format, tools=tools, tool_choice=tool_choice),
|
|
352
398
|
)
|
|
353
|
-
async for chunk in
|
|
354
|
-
yield chunk
|
|
399
|
+
async for chunk in async_stream: # type: ignore
|
|
400
|
+
yield self._parse_provider_response_delta(chunk) # type: ignore
|
|
401
|
+
|
|
402
|
+
assistant_message.metrics.stop_timer()
|
|
403
|
+
|
|
355
404
|
except (APIResponseValidationError, APIStatusError) as e:
|
|
356
405
|
log_error(f"Error calling Groq API: {str(e)}")
|
|
357
406
|
raise ModelProviderError(
|
|
@@ -405,7 +454,7 @@ class Groq(Model):
|
|
|
405
454
|
tool_call_entry["type"] = _tool_call_type
|
|
406
455
|
return tool_calls
|
|
407
456
|
|
|
408
|
-
def
|
|
457
|
+
def _parse_provider_response(self, response: ChatCompletion, **kwargs) -> ModelResponse:
|
|
409
458
|
"""
|
|
410
459
|
Parse the Groq response into a ModelResponse.
|
|
411
460
|
|
|
@@ -437,20 +486,11 @@ class Groq(Model):
|
|
|
437
486
|
|
|
438
487
|
# Add usage metrics if present
|
|
439
488
|
if response.usage is not None:
|
|
440
|
-
model_response.response_usage =
|
|
441
|
-
|
|
442
|
-
"output_tokens": response.usage.completion_tokens,
|
|
443
|
-
"total_tokens": response.usage.total_tokens,
|
|
444
|
-
"additional_metrics": {
|
|
445
|
-
"completion_time": response.usage.completion_time,
|
|
446
|
-
"prompt_time": response.usage.prompt_time,
|
|
447
|
-
"queue_time": response.usage.queue_time,
|
|
448
|
-
"total_time": response.usage.total_time,
|
|
449
|
-
},
|
|
450
|
-
}
|
|
489
|
+
model_response.response_usage = self._get_metrics(response.usage)
|
|
490
|
+
|
|
451
491
|
return model_response
|
|
452
492
|
|
|
453
|
-
def
|
|
493
|
+
def _parse_provider_response_delta(self, response: ChatCompletionChunk) -> ModelResponse:
|
|
454
494
|
"""
|
|
455
495
|
Parse the Groq streaming response into ModelResponse objects.
|
|
456
496
|
|
|
@@ -476,16 +516,38 @@ class Groq(Model):
|
|
|
476
516
|
|
|
477
517
|
# Add usage metrics if present
|
|
478
518
|
if response.x_groq is not None and response.x_groq.usage is not None:
|
|
479
|
-
model_response.response_usage =
|
|
480
|
-
"input_tokens": response.x_groq.usage.prompt_tokens,
|
|
481
|
-
"output_tokens": response.x_groq.usage.completion_tokens,
|
|
482
|
-
"total_tokens": response.x_groq.usage.total_tokens,
|
|
483
|
-
"additional_metrics": {
|
|
484
|
-
"completion_time": response.x_groq.usage.completion_time,
|
|
485
|
-
"prompt_time": response.x_groq.usage.prompt_time,
|
|
486
|
-
"queue_time": response.x_groq.usage.queue_time,
|
|
487
|
-
"total_time": response.x_groq.usage.total_time,
|
|
488
|
-
},
|
|
489
|
-
}
|
|
519
|
+
model_response.response_usage = self._get_metrics(response.x_groq.usage)
|
|
490
520
|
|
|
491
521
|
return model_response
|
|
522
|
+
|
|
523
|
+
def _get_metrics(self, response_usage: CompletionUsage) -> Metrics:
|
|
524
|
+
"""
|
|
525
|
+
Parse the given Groq usage into an Agno Metrics object.
|
|
526
|
+
|
|
527
|
+
Args:
|
|
528
|
+
response_usage: Usage data from Groq
|
|
529
|
+
|
|
530
|
+
Returns:
|
|
531
|
+
Metrics: Parsed metrics data
|
|
532
|
+
"""
|
|
533
|
+
metrics = Metrics()
|
|
534
|
+
|
|
535
|
+
metrics.input_tokens = response_usage.prompt_tokens or 0
|
|
536
|
+
metrics.output_tokens = response_usage.completion_tokens or 0
|
|
537
|
+
metrics.total_tokens = metrics.input_tokens + metrics.output_tokens
|
|
538
|
+
|
|
539
|
+
# Additional time metrics offered by Groq
|
|
540
|
+
if completion_time := response_usage.completion_time:
|
|
541
|
+
metrics.provider_metrics = metrics.provider_metrics or {}
|
|
542
|
+
metrics.provider_metrics["completion_time"] = completion_time
|
|
543
|
+
if prompt_time := response_usage.prompt_time:
|
|
544
|
+
metrics.provider_metrics = metrics.provider_metrics or {}
|
|
545
|
+
metrics.provider_metrics["prompt_time"] = prompt_time
|
|
546
|
+
if queue_time := response_usage.queue_time:
|
|
547
|
+
metrics.provider_metrics = metrics.provider_metrics or {}
|
|
548
|
+
metrics.provider_metrics["queue_time"] = queue_time
|
|
549
|
+
if total_time := response_usage.total_time:
|
|
550
|
+
metrics.provider_metrics = metrics.provider_metrics or {}
|
|
551
|
+
metrics.provider_metrics["total_time"] = total_time
|
|
552
|
+
|
|
553
|
+
return metrics
|