agno 1.8.2__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/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 +10 -10
- agno/knowledge/__init__.py +2 -2
- agno/{document → knowledge}/chunking/agentic.py +2 -2
- agno/{document → knowledge}/chunking/document.py +2 -2
- agno/{document → knowledge}/chunking/fixed.py +3 -3
- agno/{document → knowledge}/chunking/markdown.py +2 -2
- agno/{document → knowledge}/chunking/recursive.py +2 -2
- agno/{document → knowledge}/chunking/row.py +2 -2
- agno/knowledge/chunking/semantic.py +59 -0
- agno/knowledge/chunking/strategy.py +121 -0
- agno/knowledge/content.py +74 -0
- agno/knowledge/document/__init__.py +5 -0
- agno/{document → knowledge/document}/base.py +12 -2
- agno/knowledge/embedder/__init__.py +5 -0
- agno/{embedder → knowledge/embedder}/aws_bedrock.py +127 -1
- agno/{embedder → knowledge/embedder}/azure_openai.py +65 -1
- agno/{embedder → knowledge/embedder}/base.py +6 -0
- agno/{embedder → knowledge/embedder}/cohere.py +72 -1
- agno/{embedder → knowledge/embedder}/fastembed.py +17 -1
- agno/{embedder → knowledge/embedder}/fireworks.py +1 -1
- agno/{embedder → knowledge/embedder}/google.py +74 -1
- agno/{embedder → knowledge/embedder}/huggingface.py +36 -2
- agno/{embedder → knowledge/embedder}/jina.py +48 -2
- agno/knowledge/embedder/langdb.py +22 -0
- agno/knowledge/embedder/mistral.py +139 -0
- agno/{embedder → knowledge/embedder}/nebius.py +1 -1
- agno/{embedder → knowledge/embedder}/ollama.py +54 -3
- agno/knowledge/embedder/openai.py +223 -0
- agno/{embedder → knowledge/embedder}/sentence_transformer.py +16 -1
- agno/{embedder → knowledge/embedder}/together.py +1 -1
- agno/{embedder → knowledge/embedder}/voyageai.py +49 -1
- agno/knowledge/knowledge.py +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 +128 -72
- 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 +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 +65 -28
- agno/os/interfaces/base.py +21 -0
- agno/os/interfaces/slack/__init__.py +3 -0
- agno/{app/slack/async_router.py → os/interfaces/slack/router.py} +3 -5
- agno/os/interfaces/slack/slack.py +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 +17 -18
- 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 +18 -33
- 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 +1 -1
- 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 +6 -12
- 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 -110
- 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 -1053
- agno/app/playground/deploy.py +0 -249
- agno/app/playground/operator.py +0 -183
- agno/app/playground/schemas.py +0 -223
- agno/app/playground/serve.py +0 -55
- agno/app/playground/sync_router.py +0 -1045
- 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 -3313
- 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.2.dist-info/METADATA +0 -982
- agno-1.8.2.dist-info/RECORD +0 -566
- agno-1.8.2.dist-info/entry_points.txt +0 -3
- agno-1.8.2.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.2.dist-info → agno-2.0.0.dist-info}/WHEEL +0 -0
- {agno-1.8.2.dist-info → agno-2.0.0.dist-info}/top_level.txt +0 -0
agno/models/openai/chat.py
CHANGED
|
@@ -2,15 +2,18 @@ from collections.abc import AsyncIterator
|
|
|
2
2
|
from dataclasses import dataclass
|
|
3
3
|
from os import getenv
|
|
4
4
|
from typing import Any, Dict, Iterator, List, Literal, Optional, Type, Union
|
|
5
|
+
from uuid import uuid4
|
|
5
6
|
|
|
6
7
|
import httpx
|
|
7
8
|
from pydantic import BaseModel
|
|
8
9
|
|
|
9
10
|
from agno.exceptions import ModelProviderError
|
|
10
|
-
from agno.media import
|
|
11
|
+
from agno.media import Audio
|
|
11
12
|
from agno.models.base import Model
|
|
12
13
|
from agno.models.message import Message
|
|
14
|
+
from agno.models.metrics import Metrics
|
|
13
15
|
from agno.models.response import ModelResponse
|
|
16
|
+
from agno.run.agent import RunOutput
|
|
14
17
|
from agno.utils.log import log_debug, log_error, log_warning
|
|
15
18
|
from agno.utils.openai import _format_file_for_message, audio_to_message, images_to_message
|
|
16
19
|
|
|
@@ -18,6 +21,7 @@ try:
|
|
|
18
21
|
from openai import APIConnectionError, APIStatusError, RateLimitError
|
|
19
22
|
from openai import AsyncOpenAI as AsyncOpenAIClient
|
|
20
23
|
from openai import OpenAI as OpenAIClient
|
|
24
|
+
from openai.types import CompletionUsage
|
|
21
25
|
from openai.types.chat import ChatCompletionAudio
|
|
22
26
|
from openai.types.chat.chat_completion import ChatCompletion
|
|
23
27
|
from openai.types.chat.chat_completion_chunk import (
|
|
@@ -215,6 +219,15 @@ class OpenAIChat(Model):
|
|
|
215
219
|
|
|
216
220
|
# Add tools
|
|
217
221
|
if tools is not None and len(tools) > 0:
|
|
222
|
+
# Remove unsupported fields for OpenAILike models
|
|
223
|
+
if self.provider in ["AIMLAPI", "Fireworks", "Nvidia"]:
|
|
224
|
+
for tool in tools:
|
|
225
|
+
if tool.get("type") == "function":
|
|
226
|
+
if tool["function"].get("requires_confirmation") is not None:
|
|
227
|
+
del tool["function"]["requires_confirmation"]
|
|
228
|
+
if tool["function"].get("external_execution") is not None:
|
|
229
|
+
del tool["function"]["external_execution"]
|
|
230
|
+
|
|
218
231
|
request_params["tools"] = tools
|
|
219
232
|
|
|
220
233
|
if tool_choice is not None:
|
|
@@ -330,25 +343,43 @@ class OpenAIChat(Model):
|
|
|
330
343
|
def invoke(
|
|
331
344
|
self,
|
|
332
345
|
messages: List[Message],
|
|
346
|
+
assistant_message: Message,
|
|
333
347
|
response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
|
|
334
348
|
tools: Optional[List[Dict[str, Any]]] = None,
|
|
335
349
|
tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
|
|
336
|
-
|
|
350
|
+
run_response: Optional[RunOutput] = None,
|
|
351
|
+
) -> ModelResponse:
|
|
337
352
|
"""
|
|
338
|
-
Send a chat completion request to the OpenAI API.
|
|
353
|
+
Send a chat completion request to the OpenAI API and parse the response.
|
|
339
354
|
|
|
340
355
|
Args:
|
|
341
356
|
messages (List[Message]): A list of messages to send to the model.
|
|
357
|
+
assistant_message (Message): The assistant message to populate.
|
|
358
|
+
response_format (Optional[Union[Dict, Type[BaseModel]]]): The response format to use.
|
|
359
|
+
tools (Optional[List[Dict[str, Any]]]): The tools to use.
|
|
360
|
+
tool_choice (Optional[Union[str, Dict[str, Any]]]): The tool choice to use.
|
|
342
361
|
|
|
343
362
|
Returns:
|
|
344
|
-
|
|
363
|
+
ModelResponse: The chat completion response from the API.
|
|
345
364
|
"""
|
|
346
365
|
try:
|
|
347
|
-
|
|
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
|
+
|
|
371
|
+
provider_response = self.get_client().chat.completions.create(
|
|
348
372
|
model=self.id,
|
|
349
373
|
messages=[self._format_message(m) for m in messages], # type: ignore
|
|
350
374
|
**self.get_request_params(response_format=response_format, tools=tools, tool_choice=tool_choice),
|
|
351
375
|
)
|
|
376
|
+
assistant_message.metrics.stop_timer()
|
|
377
|
+
|
|
378
|
+
# Parse the response into an Agno ModelResponse object
|
|
379
|
+
model_response = self._parse_provider_response(provider_response, response_format=response_format)
|
|
380
|
+
|
|
381
|
+
return model_response
|
|
382
|
+
|
|
352
383
|
except RateLimitError as e:
|
|
353
384
|
log_error(f"Rate limit error from OpenAI API: {e}")
|
|
354
385
|
error_message = e.response.json().get("error", {})
|
|
@@ -390,25 +421,42 @@ class OpenAIChat(Model):
|
|
|
390
421
|
async def ainvoke(
|
|
391
422
|
self,
|
|
392
423
|
messages: List[Message],
|
|
424
|
+
assistant_message: Message,
|
|
393
425
|
response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
|
|
394
426
|
tools: Optional[List[Dict[str, Any]]] = None,
|
|
395
427
|
tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
|
|
396
|
-
|
|
428
|
+
run_response: Optional[RunOutput] = None,
|
|
429
|
+
) -> ModelResponse:
|
|
397
430
|
"""
|
|
398
431
|
Sends an asynchronous chat completion request to the OpenAI API.
|
|
399
432
|
|
|
400
433
|
Args:
|
|
401
434
|
messages (List[Message]): A list of messages to send to the model.
|
|
435
|
+
assistant_message (Message): The assistant message to populate.
|
|
436
|
+
response_format (Optional[Union[Dict, Type[BaseModel]]]): The response format to use.
|
|
437
|
+
tools (Optional[List[Dict[str, Any]]]): The tools to use.
|
|
438
|
+
tool_choice (Optional[Union[str, Dict[str, Any]]]): The tool choice to use.
|
|
402
439
|
|
|
403
440
|
Returns:
|
|
404
|
-
|
|
441
|
+
ModelResponse: The chat completion response from the API.
|
|
405
442
|
"""
|
|
406
443
|
try:
|
|
407
|
-
|
|
444
|
+
if run_response and run_response.metrics:
|
|
445
|
+
run_response.metrics.set_time_to_first_token()
|
|
446
|
+
|
|
447
|
+
assistant_message.metrics.start_timer()
|
|
448
|
+
response = await self.get_async_client().chat.completions.create(
|
|
408
449
|
model=self.id,
|
|
409
450
|
messages=[self._format_message(m) for m in messages], # type: ignore
|
|
410
451
|
**self.get_request_params(response_format=response_format, tools=tools, tool_choice=tool_choice),
|
|
411
452
|
)
|
|
453
|
+
assistant_message.metrics.stop_timer()
|
|
454
|
+
|
|
455
|
+
# Parse the response into an Agno ModelResponse object
|
|
456
|
+
provider_response: ModelResponse = self._parse_provider_response(response, response_format=response_format)
|
|
457
|
+
|
|
458
|
+
return provider_response
|
|
459
|
+
|
|
412
460
|
except RateLimitError as e:
|
|
413
461
|
log_error(f"Rate limit error from OpenAI API: {e}")
|
|
414
462
|
error_message = e.response.json().get("error", {})
|
|
@@ -450,10 +498,12 @@ class OpenAIChat(Model):
|
|
|
450
498
|
def invoke_stream(
|
|
451
499
|
self,
|
|
452
500
|
messages: List[Message],
|
|
501
|
+
assistant_message: Message,
|
|
453
502
|
response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
|
|
454
503
|
tools: Optional[List[Dict[str, Any]]] = None,
|
|
455
504
|
tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
|
|
456
|
-
|
|
505
|
+
run_response: Optional[RunOutput] = None,
|
|
506
|
+
) -> Iterator[ModelResponse]:
|
|
457
507
|
"""
|
|
458
508
|
Send a streaming chat completion request to the OpenAI API.
|
|
459
509
|
|
|
@@ -461,17 +511,26 @@ class OpenAIChat(Model):
|
|
|
461
511
|
messages (List[Message]): A list of messages to send to the model.
|
|
462
512
|
|
|
463
513
|
Returns:
|
|
464
|
-
Iterator[
|
|
514
|
+
Iterator[ModelResponse]: An iterator of model responses.
|
|
465
515
|
"""
|
|
466
516
|
|
|
467
517
|
try:
|
|
468
|
-
|
|
518
|
+
if run_response and run_response.metrics:
|
|
519
|
+
run_response.metrics.set_time_to_first_token()
|
|
520
|
+
|
|
521
|
+
assistant_message.metrics.start_timer()
|
|
522
|
+
|
|
523
|
+
for chunk in self.get_client().chat.completions.create(
|
|
469
524
|
model=self.id,
|
|
470
525
|
messages=[self._format_message(m) for m in messages], # type: ignore
|
|
471
526
|
stream=True,
|
|
472
527
|
stream_options={"include_usage": True},
|
|
473
528
|
**self.get_request_params(response_format=response_format, tools=tools, tool_choice=tool_choice),
|
|
474
|
-
)
|
|
529
|
+
):
|
|
530
|
+
yield self._parse_provider_response_delta(chunk)
|
|
531
|
+
|
|
532
|
+
assistant_message.metrics.stop_timer()
|
|
533
|
+
|
|
475
534
|
except RateLimitError as e:
|
|
476
535
|
log_error(f"Rate limit error from OpenAI API: {e}")
|
|
477
536
|
error_message = e.response.json().get("error", {})
|
|
@@ -513,10 +572,12 @@ class OpenAIChat(Model):
|
|
|
513
572
|
async def ainvoke_stream(
|
|
514
573
|
self,
|
|
515
574
|
messages: List[Message],
|
|
575
|
+
assistant_message: Message,
|
|
516
576
|
response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
|
|
517
577
|
tools: Optional[List[Dict[str, Any]]] = None,
|
|
518
578
|
tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
|
|
519
|
-
|
|
579
|
+
run_response: Optional[RunOutput] = None,
|
|
580
|
+
) -> AsyncIterator[ModelResponse]:
|
|
520
581
|
"""
|
|
521
582
|
Sends an asynchronous streaming chat completion request to the OpenAI API.
|
|
522
583
|
|
|
@@ -524,10 +585,15 @@ class OpenAIChat(Model):
|
|
|
524
585
|
messages (List[Message]): A list of messages to send to the model.
|
|
525
586
|
|
|
526
587
|
Returns:
|
|
527
|
-
Any: An asynchronous iterator of
|
|
588
|
+
Any: An asynchronous iterator of model responses.
|
|
528
589
|
"""
|
|
529
590
|
|
|
530
591
|
try:
|
|
592
|
+
if run_response and run_response.metrics:
|
|
593
|
+
run_response.metrics.set_time_to_first_token()
|
|
594
|
+
|
|
595
|
+
assistant_message.metrics.start_timer()
|
|
596
|
+
|
|
531
597
|
async_stream = await self.get_async_client().chat.completions.create(
|
|
532
598
|
model=self.id,
|
|
533
599
|
messages=[self._format_message(m) for m in messages], # type: ignore
|
|
@@ -535,8 +601,12 @@ class OpenAIChat(Model):
|
|
|
535
601
|
stream_options={"include_usage": True},
|
|
536
602
|
**self.get_request_params(response_format=response_format, tools=tools, tool_choice=tool_choice),
|
|
537
603
|
)
|
|
604
|
+
|
|
538
605
|
async for chunk in async_stream:
|
|
539
|
-
yield chunk
|
|
606
|
+
yield self._parse_provider_response_delta(chunk)
|
|
607
|
+
|
|
608
|
+
assistant_message.metrics.stop_timer()
|
|
609
|
+
|
|
540
610
|
except RateLimitError as e:
|
|
541
611
|
log_error(f"Rate limit error from OpenAI API: {e}")
|
|
542
612
|
error_message = e.response.json().get("error", {})
|
|
@@ -575,7 +645,6 @@ class OpenAIChat(Model):
|
|
|
575
645
|
log_error(f"Error from OpenAI API: {e}")
|
|
576
646
|
raise ModelProviderError(message=str(e), model_name=self.name, model_id=self.id) from e
|
|
577
647
|
|
|
578
|
-
# Override base method
|
|
579
648
|
@staticmethod
|
|
580
649
|
def parse_tool_calls(tool_calls_data: List[ChoiceDeltaToolCall]) -> List[Dict[str, Any]]:
|
|
581
650
|
"""
|
|
@@ -616,7 +685,7 @@ class OpenAIChat(Model):
|
|
|
616
685
|
tool_call_entry["type"] = _tool_call_type
|
|
617
686
|
return tool_calls
|
|
618
687
|
|
|
619
|
-
def
|
|
688
|
+
def _parse_provider_response(
|
|
620
689
|
self,
|
|
621
690
|
response: ChatCompletion,
|
|
622
691
|
response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
|
|
@@ -626,9 +695,9 @@ class OpenAIChat(Model):
|
|
|
626
695
|
"""
|
|
627
696
|
model_response = ModelResponse()
|
|
628
697
|
|
|
629
|
-
if hasattr(response, "error") and response.error:
|
|
698
|
+
if hasattr(response, "error") and response.error: # type: ignore
|
|
630
699
|
raise ModelProviderError(
|
|
631
|
-
message=response.error.get("message", "Unknown model error"),
|
|
700
|
+
message=response.error.get("message", "Unknown model error"), # type: ignore
|
|
632
701
|
model_name=self.name,
|
|
633
702
|
model_id=self.id,
|
|
634
703
|
)
|
|
@@ -661,14 +730,14 @@ class OpenAIChat(Model):
|
|
|
661
730
|
# If the audio output modality is requested, we can extract an audio response
|
|
662
731
|
try:
|
|
663
732
|
if isinstance(response_message.audio, dict):
|
|
664
|
-
model_response.audio =
|
|
733
|
+
model_response.audio = Audio(
|
|
665
734
|
id=response_message.audio.get("id"),
|
|
666
735
|
content=response_message.audio.get("data"),
|
|
667
736
|
expires_at=response_message.audio.get("expires_at"),
|
|
668
737
|
transcript=response_message.audio.get("transcript"),
|
|
669
738
|
)
|
|
670
739
|
else:
|
|
671
|
-
model_response.audio =
|
|
740
|
+
model_response.audio = Audio(
|
|
672
741
|
id=response_message.audio.id,
|
|
673
742
|
content=response_message.audio.data,
|
|
674
743
|
expires_at=response_message.audio.expires_at,
|
|
@@ -677,15 +746,15 @@ class OpenAIChat(Model):
|
|
|
677
746
|
except Exception as e:
|
|
678
747
|
log_warning(f"Error processing audio: {e}")
|
|
679
748
|
|
|
680
|
-
if hasattr(response_message, "reasoning_content") and response_message.reasoning_content is not None:
|
|
681
|
-
model_response.reasoning_content = response_message.reasoning_content
|
|
749
|
+
if hasattr(response_message, "reasoning_content") and response_message.reasoning_content is not None: # type: ignore
|
|
750
|
+
model_response.reasoning_content = response_message.reasoning_content # type: ignore
|
|
682
751
|
|
|
683
752
|
if response.usage is not None:
|
|
684
|
-
model_response.response_usage = response.usage
|
|
753
|
+
model_response.response_usage = self._get_metrics(response.usage)
|
|
685
754
|
|
|
686
755
|
return model_response
|
|
687
756
|
|
|
688
|
-
def
|
|
757
|
+
def _parse_provider_response_delta(self, response_delta: ChatCompletionChunk) -> ModelResponse:
|
|
689
758
|
"""
|
|
690
759
|
Parse the OpenAI streaming response into a ModelResponse.
|
|
691
760
|
|
|
@@ -696,6 +765,7 @@ class OpenAIChat(Model):
|
|
|
696
765
|
ModelResponse: Parsed response data
|
|
697
766
|
"""
|
|
698
767
|
model_response = ModelResponse()
|
|
768
|
+
|
|
699
769
|
if response_delta.choices and len(response_delta.choices) > 0:
|
|
700
770
|
choice_delta: ChoiceDelta = response_delta.choices[0].delta
|
|
701
771
|
|
|
@@ -714,21 +784,39 @@ class OpenAIChat(Model):
|
|
|
714
784
|
# Add audio if present
|
|
715
785
|
if hasattr(choice_delta, "audio") and choice_delta.audio is not None:
|
|
716
786
|
try:
|
|
787
|
+
audio_data = None
|
|
788
|
+
audio_id = None
|
|
789
|
+
audio_expires_at = None
|
|
790
|
+
audio_transcript = None
|
|
791
|
+
|
|
717
792
|
if isinstance(choice_delta.audio, dict):
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
793
|
+
audio_data = choice_delta.audio.get("data")
|
|
794
|
+
audio_id = choice_delta.audio.get("id")
|
|
795
|
+
audio_expires_at = choice_delta.audio.get("expires_at")
|
|
796
|
+
audio_transcript = choice_delta.audio.get("transcript")
|
|
797
|
+
else:
|
|
798
|
+
audio_data = choice_delta.audio.data
|
|
799
|
+
audio_id = choice_delta.audio.id
|
|
800
|
+
audio_expires_at = choice_delta.audio.expires_at
|
|
801
|
+
audio_transcript = choice_delta.audio.transcript
|
|
802
|
+
|
|
803
|
+
# Only create Audio object if there's actual content
|
|
804
|
+
if audio_data is not None:
|
|
805
|
+
model_response.audio = Audio(
|
|
806
|
+
id=audio_id,
|
|
807
|
+
content=audio_data,
|
|
808
|
+
expires_at=audio_expires_at,
|
|
809
|
+
transcript=audio_transcript,
|
|
723
810
|
sample_rate=24000,
|
|
724
811
|
mime_type="pcm16",
|
|
725
812
|
)
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
813
|
+
# If no content but there's transcript/metadata, create minimal Audio object
|
|
814
|
+
elif audio_transcript is not None or audio_id is not None:
|
|
815
|
+
model_response.audio = Audio(
|
|
816
|
+
id=audio_id or str(uuid4()),
|
|
817
|
+
content=b"",
|
|
818
|
+
expires_at=audio_expires_at,
|
|
819
|
+
transcript=audio_transcript,
|
|
732
820
|
sample_rate=24000,
|
|
733
821
|
mime_type="pcm16",
|
|
734
822
|
)
|
|
@@ -737,6 +825,35 @@ class OpenAIChat(Model):
|
|
|
737
825
|
|
|
738
826
|
# Add usage metrics if present
|
|
739
827
|
if response_delta.usage is not None:
|
|
740
|
-
model_response.response_usage = response_delta.usage
|
|
828
|
+
model_response.response_usage = self._get_metrics(response_delta.usage)
|
|
741
829
|
|
|
742
830
|
return model_response
|
|
831
|
+
|
|
832
|
+
def _get_metrics(self, response_usage: CompletionUsage) -> Metrics:
|
|
833
|
+
"""
|
|
834
|
+
Parse the given OpenAI-specific usage into an Agno Metrics object.
|
|
835
|
+
|
|
836
|
+
Args:
|
|
837
|
+
response_usage: Usage data from OpenAI
|
|
838
|
+
|
|
839
|
+
Returns:
|
|
840
|
+
Metrics: Parsed metrics data
|
|
841
|
+
"""
|
|
842
|
+
|
|
843
|
+
metrics = Metrics()
|
|
844
|
+
|
|
845
|
+
metrics.input_tokens = response_usage.prompt_tokens or 0
|
|
846
|
+
metrics.output_tokens = response_usage.completion_tokens or 0
|
|
847
|
+
metrics.total_tokens = response_usage.total_tokens or 0
|
|
848
|
+
|
|
849
|
+
# Add the prompt_tokens_details field
|
|
850
|
+
if prompt_token_details := response_usage.prompt_tokens_details:
|
|
851
|
+
metrics.audio_input_tokens = prompt_token_details.audio_tokens or 0
|
|
852
|
+
metrics.cache_read_tokens = prompt_token_details.cached_tokens or 0
|
|
853
|
+
|
|
854
|
+
# Add the completion_tokens_details field
|
|
855
|
+
if completion_tokens_details := response_usage.completion_tokens_details:
|
|
856
|
+
metrics.audio_output_tokens = completion_tokens_details.audio_tokens or 0
|
|
857
|
+
metrics.reasoning_tokens = completion_tokens_details.reasoning_tokens or 0
|
|
858
|
+
|
|
859
|
+
return metrics
|