agno 0.1.2__py3-none-any.whl → 2.3.13__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- agno/__init__.py +8 -0
- agno/agent/__init__.py +44 -5
- agno/agent/agent.py +10531 -2975
- agno/api/agent.py +14 -53
- agno/api/api.py +7 -46
- agno/api/evals.py +22 -0
- agno/api/os.py +17 -0
- agno/api/routes.py +6 -25
- agno/api/schemas/__init__.py +9 -0
- agno/api/schemas/agent.py +6 -9
- agno/api/schemas/evals.py +16 -0
- agno/api/schemas/os.py +14 -0
- agno/api/schemas/team.py +10 -10
- agno/api/schemas/utils.py +21 -0
- agno/api/schemas/workflows.py +16 -0
- agno/api/settings.py +53 -0
- agno/api/team.py +22 -26
- agno/api/workflow.py +28 -0
- agno/cloud/aws/base.py +214 -0
- agno/cloud/aws/s3/__init__.py +2 -0
- agno/cloud/aws/s3/api_client.py +43 -0
- agno/cloud/aws/s3/bucket.py +195 -0
- agno/cloud/aws/s3/object.py +57 -0
- agno/compression/__init__.py +3 -0
- agno/compression/manager.py +247 -0
- agno/culture/__init__.py +3 -0
- agno/culture/manager.py +956 -0
- agno/db/__init__.py +24 -0
- agno/db/async_postgres/__init__.py +3 -0
- agno/db/base.py +946 -0
- agno/db/dynamo/__init__.py +3 -0
- agno/db/dynamo/dynamo.py +2781 -0
- agno/db/dynamo/schemas.py +442 -0
- agno/db/dynamo/utils.py +743 -0
- agno/db/firestore/__init__.py +3 -0
- agno/db/firestore/firestore.py +2379 -0
- agno/db/firestore/schemas.py +181 -0
- agno/db/firestore/utils.py +376 -0
- agno/db/gcs_json/__init__.py +3 -0
- agno/db/gcs_json/gcs_json_db.py +1791 -0
- agno/db/gcs_json/utils.py +228 -0
- agno/db/in_memory/__init__.py +3 -0
- agno/db/in_memory/in_memory_db.py +1312 -0
- agno/db/in_memory/utils.py +230 -0
- agno/db/json/__init__.py +3 -0
- agno/db/json/json_db.py +1777 -0
- agno/db/json/utils.py +230 -0
- agno/db/migrations/manager.py +199 -0
- agno/db/migrations/v1_to_v2.py +635 -0
- agno/db/migrations/versions/v2_3_0.py +938 -0
- agno/db/mongo/__init__.py +17 -0
- agno/db/mongo/async_mongo.py +2760 -0
- agno/db/mongo/mongo.py +2597 -0
- agno/db/mongo/schemas.py +119 -0
- agno/db/mongo/utils.py +276 -0
- agno/db/mysql/__init__.py +4 -0
- agno/db/mysql/async_mysql.py +2912 -0
- agno/db/mysql/mysql.py +2923 -0
- agno/db/mysql/schemas.py +186 -0
- agno/db/mysql/utils.py +488 -0
- agno/db/postgres/__init__.py +4 -0
- agno/db/postgres/async_postgres.py +2579 -0
- agno/db/postgres/postgres.py +2870 -0
- agno/db/postgres/schemas.py +187 -0
- agno/db/postgres/utils.py +442 -0
- agno/db/redis/__init__.py +3 -0
- agno/db/redis/redis.py +2141 -0
- agno/db/redis/schemas.py +159 -0
- agno/db/redis/utils.py +346 -0
- agno/db/schemas/__init__.py +4 -0
- agno/db/schemas/culture.py +120 -0
- agno/db/schemas/evals.py +34 -0
- agno/db/schemas/knowledge.py +40 -0
- agno/db/schemas/memory.py +61 -0
- agno/db/singlestore/__init__.py +3 -0
- agno/db/singlestore/schemas.py +179 -0
- agno/db/singlestore/singlestore.py +2877 -0
- agno/db/singlestore/utils.py +384 -0
- agno/db/sqlite/__init__.py +4 -0
- agno/db/sqlite/async_sqlite.py +2911 -0
- agno/db/sqlite/schemas.py +181 -0
- agno/db/sqlite/sqlite.py +2908 -0
- agno/db/sqlite/utils.py +429 -0
- agno/db/surrealdb/__init__.py +3 -0
- agno/db/surrealdb/metrics.py +292 -0
- agno/db/surrealdb/models.py +334 -0
- agno/db/surrealdb/queries.py +71 -0
- agno/db/surrealdb/surrealdb.py +1908 -0
- agno/db/surrealdb/utils.py +147 -0
- agno/db/utils.py +118 -0
- agno/eval/__init__.py +24 -0
- agno/eval/accuracy.py +666 -276
- agno/eval/agent_as_judge.py +861 -0
- agno/eval/base.py +29 -0
- agno/eval/performance.py +779 -0
- agno/eval/reliability.py +241 -62
- agno/eval/utils.py +120 -0
- agno/exceptions.py +143 -1
- agno/filters.py +354 -0
- agno/guardrails/__init__.py +6 -0
- agno/guardrails/base.py +19 -0
- agno/guardrails/openai.py +144 -0
- agno/guardrails/pii.py +94 -0
- agno/guardrails/prompt_injection.py +52 -0
- agno/hooks/__init__.py +3 -0
- agno/hooks/decorator.py +164 -0
- agno/integrations/discord/__init__.py +3 -0
- agno/integrations/discord/client.py +203 -0
- agno/knowledge/__init__.py +5 -1
- agno/{document → knowledge}/chunking/agentic.py +22 -14
- agno/{document → knowledge}/chunking/document.py +2 -2
- agno/{document → knowledge}/chunking/fixed.py +7 -6
- agno/knowledge/chunking/markdown.py +151 -0
- agno/{document → knowledge}/chunking/recursive.py +15 -3
- agno/knowledge/chunking/row.py +39 -0
- agno/knowledge/chunking/semantic.py +91 -0
- agno/knowledge/chunking/strategy.py +165 -0
- agno/knowledge/content.py +74 -0
- agno/knowledge/document/__init__.py +5 -0
- agno/{document → knowledge/document}/base.py +12 -2
- agno/knowledge/embedder/__init__.py +5 -0
- agno/knowledge/embedder/aws_bedrock.py +343 -0
- agno/knowledge/embedder/azure_openai.py +210 -0
- agno/{embedder → knowledge/embedder}/base.py +8 -0
- agno/knowledge/embedder/cohere.py +323 -0
- agno/knowledge/embedder/fastembed.py +62 -0
- agno/{embedder → knowledge/embedder}/fireworks.py +1 -1
- agno/knowledge/embedder/google.py +258 -0
- agno/knowledge/embedder/huggingface.py +94 -0
- agno/knowledge/embedder/jina.py +182 -0
- agno/knowledge/embedder/langdb.py +22 -0
- agno/knowledge/embedder/mistral.py +206 -0
- agno/knowledge/embedder/nebius.py +13 -0
- agno/knowledge/embedder/ollama.py +154 -0
- agno/knowledge/embedder/openai.py +195 -0
- agno/knowledge/embedder/sentence_transformer.py +63 -0
- agno/{embedder → knowledge/embedder}/together.py +1 -1
- agno/knowledge/embedder/vllm.py +262 -0
- agno/knowledge/embedder/voyageai.py +165 -0
- agno/knowledge/knowledge.py +3006 -0
- agno/knowledge/reader/__init__.py +7 -0
- agno/knowledge/reader/arxiv_reader.py +81 -0
- agno/knowledge/reader/base.py +95 -0
- agno/knowledge/reader/csv_reader.py +164 -0
- agno/knowledge/reader/docx_reader.py +82 -0
- agno/knowledge/reader/field_labeled_csv_reader.py +290 -0
- agno/knowledge/reader/firecrawl_reader.py +201 -0
- agno/knowledge/reader/json_reader.py +88 -0
- agno/knowledge/reader/markdown_reader.py +137 -0
- agno/knowledge/reader/pdf_reader.py +431 -0
- agno/knowledge/reader/pptx_reader.py +101 -0
- agno/knowledge/reader/reader_factory.py +313 -0
- agno/knowledge/reader/s3_reader.py +89 -0
- agno/knowledge/reader/tavily_reader.py +193 -0
- agno/knowledge/reader/text_reader.py +127 -0
- agno/knowledge/reader/web_search_reader.py +325 -0
- agno/knowledge/reader/website_reader.py +455 -0
- agno/knowledge/reader/wikipedia_reader.py +91 -0
- agno/knowledge/reader/youtube_reader.py +78 -0
- agno/knowledge/remote_content/remote_content.py +88 -0
- agno/knowledge/reranker/__init__.py +3 -0
- agno/{reranker → knowledge/reranker}/base.py +1 -1
- agno/{reranker → knowledge/reranker}/cohere.py +2 -2
- agno/knowledge/reranker/infinity.py +195 -0
- agno/knowledge/reranker/sentence_transformer.py +54 -0
- agno/knowledge/types.py +39 -0
- agno/knowledge/utils.py +234 -0
- agno/media.py +439 -95
- agno/memory/__init__.py +16 -3
- agno/memory/manager.py +1474 -123
- agno/memory/strategies/__init__.py +15 -0
- agno/memory/strategies/base.py +66 -0
- agno/memory/strategies/summarize.py +196 -0
- agno/memory/strategies/types.py +37 -0
- agno/models/aimlapi/__init__.py +5 -0
- agno/models/aimlapi/aimlapi.py +62 -0
- agno/models/anthropic/__init__.py +4 -0
- agno/models/anthropic/claude.py +960 -496
- agno/models/aws/__init__.py +15 -0
- agno/models/aws/bedrock.py +686 -451
- agno/models/aws/claude.py +190 -183
- agno/models/azure/__init__.py +18 -1
- agno/models/azure/ai_foundry.py +489 -0
- agno/models/azure/openai_chat.py +89 -40
- agno/models/base.py +2477 -550
- agno/models/cerebras/__init__.py +12 -0
- agno/models/cerebras/cerebras.py +565 -0
- agno/models/cerebras/cerebras_openai.py +131 -0
- agno/models/cohere/__init__.py +4 -0
- agno/models/cohere/chat.py +306 -492
- agno/models/cometapi/__init__.py +5 -0
- agno/models/cometapi/cometapi.py +74 -0
- agno/models/dashscope/__init__.py +5 -0
- agno/models/dashscope/dashscope.py +90 -0
- agno/models/deepinfra/__init__.py +5 -0
- agno/models/deepinfra/deepinfra.py +45 -0
- agno/models/deepseek/__init__.py +4 -0
- agno/models/deepseek/deepseek.py +110 -9
- agno/models/fireworks/__init__.py +4 -0
- agno/models/fireworks/fireworks.py +19 -22
- agno/models/google/__init__.py +3 -7
- agno/models/google/gemini.py +1717 -662
- agno/models/google/utils.py +22 -0
- agno/models/groq/__init__.py +4 -0
- agno/models/groq/groq.py +391 -666
- agno/models/huggingface/__init__.py +4 -0
- agno/models/huggingface/huggingface.py +266 -538
- agno/models/ibm/__init__.py +5 -0
- agno/models/ibm/watsonx.py +432 -0
- agno/models/internlm/__init__.py +3 -0
- agno/models/internlm/internlm.py +20 -3
- agno/models/langdb/__init__.py +1 -0
- agno/models/langdb/langdb.py +60 -0
- agno/models/litellm/__init__.py +14 -0
- agno/models/litellm/chat.py +503 -0
- agno/models/litellm/litellm_openai.py +42 -0
- agno/models/llama_cpp/__init__.py +5 -0
- agno/models/llama_cpp/llama_cpp.py +22 -0
- agno/models/lmstudio/__init__.py +5 -0
- agno/models/lmstudio/lmstudio.py +25 -0
- agno/models/message.py +361 -39
- agno/models/meta/__init__.py +12 -0
- agno/models/meta/llama.py +502 -0
- agno/models/meta/llama_openai.py +79 -0
- agno/models/metrics.py +120 -0
- agno/models/mistral/__init__.py +4 -0
- agno/models/mistral/mistral.py +293 -393
- agno/models/nebius/__init__.py +3 -0
- agno/models/nebius/nebius.py +53 -0
- agno/models/nexus/__init__.py +3 -0
- agno/models/nexus/nexus.py +22 -0
- agno/models/nvidia/__init__.py +4 -0
- agno/models/nvidia/nvidia.py +22 -3
- agno/models/ollama/__init__.py +4 -2
- agno/models/ollama/chat.py +257 -492
- agno/models/openai/__init__.py +7 -0
- agno/models/openai/chat.py +725 -770
- agno/models/openai/like.py +16 -2
- agno/models/openai/responses.py +1121 -0
- agno/models/openrouter/__init__.py +4 -0
- agno/models/openrouter/openrouter.py +62 -5
- agno/models/perplexity/__init__.py +5 -0
- agno/models/perplexity/perplexity.py +203 -0
- agno/models/portkey/__init__.py +3 -0
- agno/models/portkey/portkey.py +82 -0
- agno/models/requesty/__init__.py +5 -0
- agno/models/requesty/requesty.py +69 -0
- agno/models/response.py +177 -7
- agno/models/sambanova/__init__.py +4 -0
- agno/models/sambanova/sambanova.py +23 -4
- agno/models/siliconflow/__init__.py +5 -0
- agno/models/siliconflow/siliconflow.py +42 -0
- agno/models/together/__init__.py +4 -0
- agno/models/together/together.py +21 -164
- agno/models/utils.py +266 -0
- agno/models/vercel/__init__.py +3 -0
- agno/models/vercel/v0.py +43 -0
- agno/models/vertexai/__init__.py +0 -1
- agno/models/vertexai/claude.py +190 -0
- agno/models/vllm/__init__.py +3 -0
- agno/models/vllm/vllm.py +83 -0
- agno/models/xai/__init__.py +2 -0
- agno/models/xai/xai.py +111 -7
- agno/os/__init__.py +3 -0
- agno/os/app.py +1027 -0
- agno/os/auth.py +244 -0
- agno/os/config.py +126 -0
- agno/os/interfaces/__init__.py +1 -0
- agno/os/interfaces/a2a/__init__.py +3 -0
- agno/os/interfaces/a2a/a2a.py +42 -0
- agno/os/interfaces/a2a/router.py +249 -0
- agno/os/interfaces/a2a/utils.py +924 -0
- agno/os/interfaces/agui/__init__.py +3 -0
- agno/os/interfaces/agui/agui.py +47 -0
- agno/os/interfaces/agui/router.py +147 -0
- agno/os/interfaces/agui/utils.py +574 -0
- agno/os/interfaces/base.py +25 -0
- agno/os/interfaces/slack/__init__.py +3 -0
- agno/os/interfaces/slack/router.py +148 -0
- agno/os/interfaces/slack/security.py +30 -0
- agno/os/interfaces/slack/slack.py +47 -0
- agno/os/interfaces/whatsapp/__init__.py +3 -0
- agno/os/interfaces/whatsapp/router.py +210 -0
- agno/os/interfaces/whatsapp/security.py +55 -0
- agno/os/interfaces/whatsapp/whatsapp.py +36 -0
- agno/os/mcp.py +293 -0
- agno/os/middleware/__init__.py +9 -0
- agno/os/middleware/jwt.py +797 -0
- agno/os/router.py +258 -0
- agno/os/routers/__init__.py +3 -0
- agno/os/routers/agents/__init__.py +3 -0
- agno/os/routers/agents/router.py +599 -0
- agno/os/routers/agents/schema.py +261 -0
- agno/os/routers/evals/__init__.py +3 -0
- agno/os/routers/evals/evals.py +450 -0
- agno/os/routers/evals/schemas.py +174 -0
- agno/os/routers/evals/utils.py +231 -0
- agno/os/routers/health.py +31 -0
- agno/os/routers/home.py +52 -0
- agno/os/routers/knowledge/__init__.py +3 -0
- agno/os/routers/knowledge/knowledge.py +1008 -0
- agno/os/routers/knowledge/schemas.py +178 -0
- agno/os/routers/memory/__init__.py +3 -0
- agno/os/routers/memory/memory.py +661 -0
- agno/os/routers/memory/schemas.py +88 -0
- agno/os/routers/metrics/__init__.py +3 -0
- agno/os/routers/metrics/metrics.py +190 -0
- agno/os/routers/metrics/schemas.py +47 -0
- agno/os/routers/session/__init__.py +3 -0
- agno/os/routers/session/session.py +997 -0
- agno/os/routers/teams/__init__.py +3 -0
- agno/os/routers/teams/router.py +512 -0
- agno/os/routers/teams/schema.py +257 -0
- agno/os/routers/traces/__init__.py +3 -0
- agno/os/routers/traces/schemas.py +414 -0
- agno/os/routers/traces/traces.py +499 -0
- agno/os/routers/workflows/__init__.py +3 -0
- agno/os/routers/workflows/router.py +624 -0
- agno/os/routers/workflows/schema.py +75 -0
- agno/os/schema.py +534 -0
- agno/os/scopes.py +469 -0
- agno/{playground → os}/settings.py +7 -15
- agno/os/utils.py +973 -0
- agno/reasoning/anthropic.py +80 -0
- agno/reasoning/azure_ai_foundry.py +67 -0
- agno/reasoning/deepseek.py +63 -0
- agno/reasoning/default.py +97 -0
- agno/reasoning/gemini.py +73 -0
- agno/reasoning/groq.py +71 -0
- agno/reasoning/helpers.py +24 -1
- agno/reasoning/ollama.py +67 -0
- agno/reasoning/openai.py +86 -0
- agno/reasoning/step.py +2 -1
- agno/reasoning/vertexai.py +76 -0
- agno/run/__init__.py +6 -0
- agno/run/agent.py +822 -0
- agno/run/base.py +247 -0
- agno/run/cancel.py +81 -0
- agno/run/requirement.py +181 -0
- agno/run/team.py +767 -0
- agno/run/workflow.py +708 -0
- agno/session/__init__.py +10 -0
- agno/session/agent.py +260 -0
- agno/session/summary.py +265 -0
- agno/session/team.py +342 -0
- agno/session/workflow.py +501 -0
- agno/table.py +10 -0
- agno/team/__init__.py +37 -0
- agno/team/team.py +9536 -0
- agno/tools/__init__.py +7 -0
- agno/tools/agentql.py +120 -0
- agno/tools/airflow.py +22 -12
- agno/tools/api.py +122 -0
- agno/tools/apify.py +276 -83
- agno/tools/{arxiv_toolkit.py → arxiv.py} +20 -12
- agno/tools/aws_lambda.py +28 -7
- agno/tools/aws_ses.py +66 -0
- agno/tools/baidusearch.py +11 -4
- agno/tools/bitbucket.py +292 -0
- agno/tools/brandfetch.py +213 -0
- agno/tools/bravesearch.py +106 -0
- agno/tools/brightdata.py +367 -0
- agno/tools/browserbase.py +209 -0
- agno/tools/calcom.py +32 -23
- agno/tools/calculator.py +24 -37
- agno/tools/cartesia.py +187 -0
- agno/tools/{clickup_tool.py → clickup.py} +17 -28
- agno/tools/confluence.py +91 -26
- agno/tools/crawl4ai.py +139 -43
- agno/tools/csv_toolkit.py +28 -22
- agno/tools/dalle.py +36 -22
- agno/tools/daytona.py +475 -0
- agno/tools/decorator.py +169 -14
- agno/tools/desi_vocal.py +23 -11
- agno/tools/discord.py +32 -29
- agno/tools/docker.py +716 -0
- agno/tools/duckdb.py +76 -81
- agno/tools/duckduckgo.py +43 -40
- agno/tools/e2b.py +703 -0
- agno/tools/eleven_labs.py +65 -54
- agno/tools/email.py +13 -5
- agno/tools/evm.py +129 -0
- agno/tools/exa.py +324 -42
- agno/tools/fal.py +39 -35
- agno/tools/file.py +196 -30
- agno/tools/file_generation.py +356 -0
- agno/tools/financial_datasets.py +288 -0
- agno/tools/firecrawl.py +108 -33
- agno/tools/function.py +960 -122
- agno/tools/giphy.py +34 -12
- agno/tools/github.py +1294 -97
- agno/tools/gmail.py +922 -0
- agno/tools/google_bigquery.py +117 -0
- agno/tools/google_drive.py +271 -0
- agno/tools/google_maps.py +253 -0
- agno/tools/googlecalendar.py +607 -107
- agno/tools/googlesheets.py +377 -0
- agno/tools/hackernews.py +20 -12
- agno/tools/jina.py +24 -14
- agno/tools/jira.py +48 -19
- agno/tools/knowledge.py +218 -0
- agno/tools/linear.py +82 -43
- agno/tools/linkup.py +58 -0
- agno/tools/local_file_system.py +15 -7
- agno/tools/lumalab.py +41 -26
- agno/tools/mcp/__init__.py +10 -0
- agno/tools/mcp/mcp.py +331 -0
- agno/tools/mcp/multi_mcp.py +347 -0
- agno/tools/mcp/params.py +24 -0
- agno/tools/mcp_toolbox.py +284 -0
- agno/tools/mem0.py +193 -0
- agno/tools/memory.py +419 -0
- agno/tools/mlx_transcribe.py +11 -9
- agno/tools/models/azure_openai.py +190 -0
- agno/tools/models/gemini.py +203 -0
- agno/tools/models/groq.py +158 -0
- agno/tools/models/morph.py +186 -0
- agno/tools/models/nebius.py +124 -0
- agno/tools/models_labs.py +163 -82
- agno/tools/moviepy_video.py +18 -13
- agno/tools/nano_banana.py +151 -0
- agno/tools/neo4j.py +134 -0
- agno/tools/newspaper.py +15 -4
- agno/tools/newspaper4k.py +19 -6
- agno/tools/notion.py +204 -0
- agno/tools/openai.py +181 -17
- agno/tools/openbb.py +27 -20
- agno/tools/opencv.py +321 -0
- agno/tools/openweather.py +233 -0
- agno/tools/oxylabs.py +385 -0
- agno/tools/pandas.py +25 -15
- agno/tools/parallel.py +314 -0
- agno/tools/postgres.py +238 -185
- agno/tools/pubmed.py +125 -13
- agno/tools/python.py +48 -35
- agno/tools/reasoning.py +283 -0
- agno/tools/reddit.py +207 -29
- agno/tools/redshift.py +406 -0
- agno/tools/replicate.py +69 -26
- agno/tools/resend.py +11 -6
- agno/tools/scrapegraph.py +179 -19
- agno/tools/searxng.py +23 -31
- agno/tools/serpapi.py +15 -10
- agno/tools/serper.py +255 -0
- agno/tools/shell.py +23 -12
- agno/tools/shopify.py +1519 -0
- agno/tools/slack.py +56 -14
- agno/tools/sleep.py +8 -6
- agno/tools/spider.py +35 -11
- agno/tools/spotify.py +919 -0
- agno/tools/sql.py +34 -19
- agno/tools/tavily.py +158 -8
- agno/tools/telegram.py +18 -8
- agno/tools/todoist.py +218 -0
- agno/tools/toolkit.py +134 -9
- agno/tools/trafilatura.py +388 -0
- agno/tools/trello.py +25 -28
- agno/tools/twilio.py +18 -9
- agno/tools/user_control_flow.py +78 -0
- agno/tools/valyu.py +228 -0
- agno/tools/visualization.py +467 -0
- agno/tools/webbrowser.py +28 -0
- agno/tools/webex.py +76 -0
- agno/tools/website.py +23 -19
- agno/tools/webtools.py +45 -0
- agno/tools/whatsapp.py +286 -0
- agno/tools/wikipedia.py +28 -19
- agno/tools/workflow.py +285 -0
- agno/tools/{twitter.py → x.py} +142 -46
- agno/tools/yfinance.py +41 -39
- agno/tools/youtube.py +34 -17
- agno/tools/zendesk.py +15 -5
- agno/tools/zep.py +454 -0
- agno/tools/zoom.py +86 -37
- agno/tracing/__init__.py +12 -0
- agno/tracing/exporter.py +157 -0
- agno/tracing/schemas.py +276 -0
- agno/tracing/setup.py +111 -0
- agno/utils/agent.py +938 -0
- agno/utils/audio.py +37 -1
- agno/utils/certs.py +27 -0
- agno/utils/code_execution.py +11 -0
- agno/utils/common.py +103 -20
- agno/utils/cryptography.py +22 -0
- agno/utils/dttm.py +33 -0
- agno/utils/events.py +700 -0
- agno/utils/functions.py +107 -37
- agno/utils/gemini.py +426 -0
- agno/utils/hooks.py +171 -0
- agno/utils/http.py +185 -0
- agno/utils/json_schema.py +159 -37
- agno/utils/knowledge.py +36 -0
- agno/utils/location.py +19 -0
- agno/utils/log.py +221 -8
- agno/utils/mcp.py +214 -0
- agno/utils/media.py +335 -14
- agno/utils/merge_dict.py +22 -1
- agno/utils/message.py +77 -2
- agno/utils/models/ai_foundry.py +50 -0
- agno/utils/models/claude.py +373 -0
- agno/utils/models/cohere.py +94 -0
- agno/utils/models/llama.py +85 -0
- agno/utils/models/mistral.py +100 -0
- agno/utils/models/openai_responses.py +140 -0
- agno/utils/models/schema_utils.py +153 -0
- agno/utils/models/watsonx.py +41 -0
- agno/utils/openai.py +257 -0
- agno/utils/pickle.py +1 -1
- agno/utils/pprint.py +124 -8
- agno/utils/print_response/agent.py +930 -0
- agno/utils/print_response/team.py +1914 -0
- agno/utils/print_response/workflow.py +1668 -0
- agno/utils/prompts.py +111 -0
- agno/utils/reasoning.py +108 -0
- agno/utils/response.py +163 -0
- agno/utils/serialize.py +32 -0
- agno/utils/shell.py +4 -4
- agno/utils/streamlit.py +487 -0
- agno/utils/string.py +204 -51
- agno/utils/team.py +139 -0
- agno/utils/timer.py +9 -2
- agno/utils/tokens.py +657 -0
- agno/utils/tools.py +19 -1
- agno/utils/whatsapp.py +305 -0
- agno/utils/yaml_io.py +3 -3
- agno/vectordb/__init__.py +2 -0
- agno/vectordb/base.py +87 -9
- agno/vectordb/cassandra/__init__.py +5 -1
- agno/vectordb/cassandra/cassandra.py +383 -27
- agno/vectordb/chroma/__init__.py +4 -0
- agno/vectordb/chroma/chromadb.py +748 -83
- agno/vectordb/clickhouse/__init__.py +7 -1
- agno/vectordb/clickhouse/clickhousedb.py +554 -53
- agno/vectordb/couchbase/__init__.py +3 -0
- agno/vectordb/couchbase/couchbase.py +1446 -0
- agno/vectordb/lancedb/__init__.py +5 -0
- agno/vectordb/lancedb/lance_db.py +730 -98
- agno/vectordb/langchaindb/__init__.py +5 -0
- agno/vectordb/langchaindb/langchaindb.py +163 -0
- agno/vectordb/lightrag/__init__.py +5 -0
- agno/vectordb/lightrag/lightrag.py +388 -0
- agno/vectordb/llamaindex/__init__.py +3 -0
- agno/vectordb/llamaindex/llamaindexdb.py +166 -0
- agno/vectordb/milvus/__init__.py +3 -0
- agno/vectordb/milvus/milvus.py +966 -78
- agno/vectordb/mongodb/__init__.py +9 -1
- agno/vectordb/mongodb/mongodb.py +1175 -172
- agno/vectordb/pgvector/__init__.py +8 -0
- agno/vectordb/pgvector/pgvector.py +599 -115
- agno/vectordb/pineconedb/__init__.py +5 -1
- agno/vectordb/pineconedb/pineconedb.py +406 -43
- agno/vectordb/qdrant/__init__.py +4 -0
- agno/vectordb/qdrant/qdrant.py +914 -61
- agno/vectordb/redis/__init__.py +9 -0
- agno/vectordb/redis/redisdb.py +682 -0
- agno/vectordb/singlestore/__init__.py +8 -1
- agno/vectordb/singlestore/singlestore.py +771 -0
- agno/vectordb/surrealdb/__init__.py +3 -0
- agno/vectordb/surrealdb/surrealdb.py +663 -0
- agno/vectordb/upstashdb/__init__.py +5 -0
- agno/vectordb/upstashdb/upstashdb.py +718 -0
- agno/vectordb/weaviate/__init__.py +8 -0
- agno/vectordb/weaviate/index.py +15 -0
- agno/vectordb/weaviate/weaviate.py +1009 -0
- agno/workflow/__init__.py +23 -1
- agno/workflow/agent.py +299 -0
- agno/workflow/condition.py +759 -0
- agno/workflow/loop.py +756 -0
- agno/workflow/parallel.py +853 -0
- agno/workflow/router.py +723 -0
- agno/workflow/step.py +1564 -0
- agno/workflow/steps.py +613 -0
- agno/workflow/types.py +556 -0
- agno/workflow/workflow.py +4327 -514
- agno-2.3.13.dist-info/METADATA +639 -0
- agno-2.3.13.dist-info/RECORD +613 -0
- {agno-0.1.2.dist-info → agno-2.3.13.dist-info}/WHEEL +1 -1
- agno-2.3.13.dist-info/licenses/LICENSE +201 -0
- agno/api/playground.py +0 -91
- agno/api/schemas/playground.py +0 -22
- agno/api/schemas/user.py +0 -22
- agno/api/schemas/workspace.py +0 -46
- agno/api/user.py +0 -160
- agno/api/workspace.py +0 -151
- agno/cli/auth_server.py +0 -118
- agno/cli/config.py +0 -275
- agno/cli/console.py +0 -88
- agno/cli/credentials.py +0 -23
- agno/cli/entrypoint.py +0 -571
- agno/cli/operator.py +0 -355
- agno/cli/settings.py +0 -85
- agno/cli/ws/ws_cli.py +0 -817
- agno/constants.py +0 -13
- agno/document/__init__.py +0 -1
- agno/document/chunking/semantic.py +0 -47
- agno/document/chunking/strategy.py +0 -31
- agno/document/reader/__init__.py +0 -1
- agno/document/reader/arxiv_reader.py +0 -41
- agno/document/reader/base.py +0 -22
- agno/document/reader/csv_reader.py +0 -84
- agno/document/reader/docx_reader.py +0 -46
- agno/document/reader/firecrawl_reader.py +0 -99
- agno/document/reader/json_reader.py +0 -43
- agno/document/reader/pdf_reader.py +0 -219
- agno/document/reader/s3/pdf_reader.py +0 -46
- agno/document/reader/s3/text_reader.py +0 -51
- agno/document/reader/text_reader.py +0 -41
- agno/document/reader/website_reader.py +0 -175
- agno/document/reader/youtube_reader.py +0 -50
- agno/embedder/__init__.py +0 -1
- agno/embedder/azure_openai.py +0 -86
- agno/embedder/cohere.py +0 -72
- agno/embedder/fastembed.py +0 -37
- agno/embedder/google.py +0 -73
- agno/embedder/huggingface.py +0 -54
- agno/embedder/mistral.py +0 -80
- agno/embedder/ollama.py +0 -57
- agno/embedder/openai.py +0 -74
- agno/embedder/sentence_transformer.py +0 -38
- agno/embedder/voyageai.py +0 -64
- agno/eval/perf.py +0 -201
- agno/file/__init__.py +0 -1
- agno/file/file.py +0 -16
- agno/file/local/csv.py +0 -32
- agno/file/local/txt.py +0 -19
- agno/infra/app.py +0 -240
- agno/infra/base.py +0 -144
- agno/infra/context.py +0 -20
- agno/infra/db_app.py +0 -52
- agno/infra/resource.py +0 -205
- agno/infra/resources.py +0 -55
- agno/knowledge/agent.py +0 -230
- agno/knowledge/arxiv.py +0 -22
- agno/knowledge/combined.py +0 -22
- agno/knowledge/csv.py +0 -28
- agno/knowledge/csv_url.py +0 -19
- agno/knowledge/document.py +0 -20
- agno/knowledge/docx.py +0 -30
- agno/knowledge/json.py +0 -28
- agno/knowledge/langchain.py +0 -71
- agno/knowledge/llamaindex.py +0 -66
- agno/knowledge/pdf.py +0 -28
- agno/knowledge/pdf_url.py +0 -26
- agno/knowledge/s3/base.py +0 -60
- agno/knowledge/s3/pdf.py +0 -21
- agno/knowledge/s3/text.py +0 -23
- agno/knowledge/text.py +0 -30
- agno/knowledge/website.py +0 -88
- agno/knowledge/wikipedia.py +0 -31
- agno/knowledge/youtube.py +0 -22
- agno/memory/agent.py +0 -392
- agno/memory/classifier.py +0 -104
- agno/memory/db/__init__.py +0 -1
- agno/memory/db/base.py +0 -42
- agno/memory/db/mongodb.py +0 -189
- agno/memory/db/postgres.py +0 -203
- agno/memory/db/sqlite.py +0 -193
- agno/memory/memory.py +0 -15
- agno/memory/row.py +0 -36
- agno/memory/summarizer.py +0 -192
- agno/memory/summary.py +0 -19
- agno/memory/workflow.py +0 -38
- agno/models/google/gemini_openai.py +0 -26
- agno/models/ollama/hermes.py +0 -221
- agno/models/ollama/tools.py +0 -362
- agno/models/vertexai/gemini.py +0 -595
- agno/playground/__init__.py +0 -3
- agno/playground/async_router.py +0 -421
- agno/playground/deploy.py +0 -249
- agno/playground/operator.py +0 -92
- agno/playground/playground.py +0 -91
- agno/playground/schemas.py +0 -76
- agno/playground/serve.py +0 -55
- agno/playground/sync_router.py +0 -405
- agno/reasoning/agent.py +0 -68
- agno/run/response.py +0 -112
- agno/storage/agent/__init__.py +0 -0
- agno/storage/agent/base.py +0 -38
- agno/storage/agent/dynamodb.py +0 -350
- agno/storage/agent/json.py +0 -92
- agno/storage/agent/mongodb.py +0 -228
- agno/storage/agent/postgres.py +0 -367
- agno/storage/agent/session.py +0 -79
- agno/storage/agent/singlestore.py +0 -303
- agno/storage/agent/sqlite.py +0 -357
- agno/storage/agent/yaml.py +0 -93
- agno/storage/workflow/__init__.py +0 -0
- agno/storage/workflow/base.py +0 -40
- agno/storage/workflow/mongodb.py +0 -233
- agno/storage/workflow/postgres.py +0 -366
- agno/storage/workflow/session.py +0 -60
- agno/storage/workflow/sqlite.py +0 -359
- agno/tools/googlesearch.py +0 -88
- agno/utils/defaults.py +0 -57
- agno/utils/filesystem.py +0 -39
- agno/utils/git.py +0 -52
- agno/utils/json_io.py +0 -30
- agno/utils/load_env.py +0 -19
- agno/utils/py_io.py +0 -19
- agno/utils/pyproject.py +0 -18
- agno/utils/resource_filter.py +0 -31
- agno/vectordb/singlestore/s2vectordb.py +0 -390
- agno/vectordb/singlestore/s2vectordb2.py +0 -355
- agno/workspace/__init__.py +0 -0
- agno/workspace/config.py +0 -325
- agno/workspace/enums.py +0 -6
- agno/workspace/helpers.py +0 -48
- agno/workspace/operator.py +0 -758
- agno/workspace/settings.py +0 -63
- agno-0.1.2.dist-info/LICENSE +0 -375
- agno-0.1.2.dist-info/METADATA +0 -502
- agno-0.1.2.dist-info/RECORD +0 -352
- agno-0.1.2.dist-info/entry_points.txt +0 -3
- /agno/{cli → db/migrations}/__init__.py +0 -0
- /agno/{cli/ws → db/migrations/versions}/__init__.py +0 -0
- /agno/{document/chunking/__init__.py → db/schemas/metrics.py} +0 -0
- /agno/{document/reader/s3 → integrations}/__init__.py +0 -0
- /agno/{file/local → knowledge/chunking}/__init__.py +0 -0
- /agno/{infra → knowledge/remote_content}/__init__.py +0 -0
- /agno/{knowledge/s3 → tools/models}/__init__.py +0 -0
- /agno/{reranker → utils/models}/__init__.py +0 -0
- /agno/{storage → utils/print_response}/__init__.py +0 -0
- {agno-0.1.2.dist-info → agno-2.3.13.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
import json
|
|
2
|
+
from dataclasses import dataclass
|
|
3
|
+
from os import getenv
|
|
4
|
+
from typing import Any, Dict, List, Optional, Tuple
|
|
5
|
+
|
|
6
|
+
from agno.exceptions import AgnoError, ModelProviderError
|
|
7
|
+
from agno.knowledge.embedder.base import Embedder
|
|
8
|
+
from agno.utils.log import log_error, log_warning
|
|
9
|
+
|
|
10
|
+
try:
|
|
11
|
+
from boto3 import client as AwsClient
|
|
12
|
+
from boto3.session import Session
|
|
13
|
+
from botocore.exceptions import ClientError
|
|
14
|
+
except ImportError:
|
|
15
|
+
log_error("`boto3` not installed. Please install it via `pip install boto3`.")
|
|
16
|
+
raise
|
|
17
|
+
|
|
18
|
+
try:
|
|
19
|
+
import aioboto3
|
|
20
|
+
from aioboto3.session import Session as AioSession
|
|
21
|
+
except ImportError:
|
|
22
|
+
log_error("`aioboto3` not installed. Please install it via `pip install aioboto3`.")
|
|
23
|
+
aioboto3 = None
|
|
24
|
+
AioSession = None
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@dataclass
|
|
28
|
+
class AwsBedrockEmbedder(Embedder):
|
|
29
|
+
"""
|
|
30
|
+
AWS Bedrock embedder.
|
|
31
|
+
|
|
32
|
+
To use this embedder, you need to either:
|
|
33
|
+
1. Set the following environment variables:
|
|
34
|
+
- AWS_ACCESS_KEY_ID
|
|
35
|
+
- AWS_SECRET_ACCESS_KEY
|
|
36
|
+
- AWS_REGION
|
|
37
|
+
2. Or provide a boto3 Session object
|
|
38
|
+
|
|
39
|
+
Args:
|
|
40
|
+
id (str): The model ID to use. Default is 'cohere.embed-multilingual-v3'.
|
|
41
|
+
dimensions (Optional[int]): The dimensions of the embeddings. Default is 1024.
|
|
42
|
+
input_type (str): Prepends special tokens to differentiate types. Options:
|
|
43
|
+
'search_document', 'search_query', 'classification', 'clustering'. Default is 'search_query'.
|
|
44
|
+
truncate (Optional[str]): How to handle inputs longer than the maximum token length.
|
|
45
|
+
Options: 'NONE', 'START', 'END'. Default is 'NONE'.
|
|
46
|
+
embedding_types (Optional[List[str]]): Types of embeddings to return. Options:
|
|
47
|
+
'float', 'int8', 'uint8', 'binary', 'ubinary'. Default is ['float'].
|
|
48
|
+
aws_region (Optional[str]): The AWS region to use.
|
|
49
|
+
aws_access_key_id (Optional[str]): The AWS access key ID to use.
|
|
50
|
+
aws_secret_access_key (Optional[str]): The AWS secret access key to use.
|
|
51
|
+
session (Optional[Session]): A boto3 Session object to use for authentication.
|
|
52
|
+
request_params (Optional[Dict[str, Any]]): Additional parameters to pass to the API requests.
|
|
53
|
+
client_params (Optional[Dict[str, Any]]): Additional parameters to pass to the boto3 client.
|
|
54
|
+
"""
|
|
55
|
+
|
|
56
|
+
id: str = "cohere.embed-multilingual-v3"
|
|
57
|
+
dimensions: int = 1024 # Cohere models have 1024 dimensions by default
|
|
58
|
+
input_type: str = "search_query"
|
|
59
|
+
truncate: Optional[str] = None # 'NONE', 'START', or 'END'
|
|
60
|
+
# 'float', 'int8', 'uint8', etc.
|
|
61
|
+
embedding_types: Optional[List[str]] = None
|
|
62
|
+
|
|
63
|
+
aws_region: Optional[str] = None
|
|
64
|
+
aws_access_key_id: Optional[str] = None
|
|
65
|
+
aws_secret_access_key: Optional[str] = None
|
|
66
|
+
session: Optional[Session] = None
|
|
67
|
+
|
|
68
|
+
request_params: Optional[Dict[str, Any]] = None
|
|
69
|
+
client_params: Optional[Dict[str, Any]] = None
|
|
70
|
+
client: Optional[AwsClient] = None
|
|
71
|
+
|
|
72
|
+
def __post_init__(self):
|
|
73
|
+
if self.enable_batch:
|
|
74
|
+
log_warning("AwsBedrockEmbedder does not support batch embeddings, setting enable_batch to False")
|
|
75
|
+
self.enable_batch = False
|
|
76
|
+
|
|
77
|
+
def get_client(self) -> AwsClient:
|
|
78
|
+
"""
|
|
79
|
+
Returns an AWS Bedrock client.
|
|
80
|
+
|
|
81
|
+
Returns:
|
|
82
|
+
AwsClient: An instance of the AWS Bedrock client.
|
|
83
|
+
"""
|
|
84
|
+
if self.client is not None:
|
|
85
|
+
return self.client
|
|
86
|
+
|
|
87
|
+
if self.session:
|
|
88
|
+
self.client = self.session.client("bedrock-runtime")
|
|
89
|
+
return self.client
|
|
90
|
+
|
|
91
|
+
self.aws_access_key_id = self.aws_access_key_id or getenv("AWS_ACCESS_KEY_ID")
|
|
92
|
+
self.aws_secret_access_key = self.aws_secret_access_key or getenv("AWS_SECRET_ACCESS_KEY")
|
|
93
|
+
self.aws_region = self.aws_region or getenv("AWS_REGION")
|
|
94
|
+
|
|
95
|
+
if not self.aws_access_key_id or not self.aws_secret_access_key:
|
|
96
|
+
raise AgnoError(
|
|
97
|
+
message="AWS credentials not found. Please set AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables or provide a boto3 session.",
|
|
98
|
+
status_code=400,
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
self.client = AwsClient(
|
|
102
|
+
service_name="bedrock-runtime",
|
|
103
|
+
region_name=self.aws_region,
|
|
104
|
+
aws_access_key_id=self.aws_access_key_id,
|
|
105
|
+
aws_secret_access_key=self.aws_secret_access_key,
|
|
106
|
+
**(self.client_params or {}),
|
|
107
|
+
)
|
|
108
|
+
return self.client
|
|
109
|
+
|
|
110
|
+
def get_async_client(self):
|
|
111
|
+
"""
|
|
112
|
+
Returns an async AWS Bedrock client using aioboto3.
|
|
113
|
+
|
|
114
|
+
Returns:
|
|
115
|
+
An aioboto3 bedrock-runtime client context manager.
|
|
116
|
+
"""
|
|
117
|
+
if aioboto3 is None:
|
|
118
|
+
raise AgnoError(
|
|
119
|
+
message="aioboto3 not installed. Please install it via `pip install aioboto3`.",
|
|
120
|
+
status_code=400,
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
if self.session:
|
|
124
|
+
# Convert boto3 session to aioboto3 session
|
|
125
|
+
aio_session = aioboto3.Session(
|
|
126
|
+
aws_access_key_id=self.session.get_credentials().access_key,
|
|
127
|
+
aws_secret_access_key=self.session.get_credentials().secret_key,
|
|
128
|
+
aws_session_token=self.session.get_credentials().token,
|
|
129
|
+
region_name=self.session.region_name,
|
|
130
|
+
)
|
|
131
|
+
else:
|
|
132
|
+
self.aws_access_key_id = self.aws_access_key_id or getenv("AWS_ACCESS_KEY_ID")
|
|
133
|
+
self.aws_secret_access_key = self.aws_secret_access_key or getenv("AWS_SECRET_ACCESS_KEY")
|
|
134
|
+
self.aws_region = self.aws_region or getenv("AWS_REGION")
|
|
135
|
+
|
|
136
|
+
if not self.aws_access_key_id or not self.aws_secret_access_key:
|
|
137
|
+
raise AgnoError(
|
|
138
|
+
message="AWS credentials not found. Please set AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables or provide a boto3 session.",
|
|
139
|
+
status_code=400,
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
aio_session = aioboto3.Session(
|
|
143
|
+
aws_access_key_id=self.aws_access_key_id,
|
|
144
|
+
aws_secret_access_key=self.aws_secret_access_key,
|
|
145
|
+
region_name=self.aws_region,
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
return aio_session.client("bedrock-runtime", **(self.client_params or {}))
|
|
149
|
+
|
|
150
|
+
def _format_request_body(self, text: str) -> str:
|
|
151
|
+
"""
|
|
152
|
+
Format the request body for the embedder.
|
|
153
|
+
|
|
154
|
+
Args:
|
|
155
|
+
text (str): The text to embed.
|
|
156
|
+
|
|
157
|
+
Returns:
|
|
158
|
+
str: The formatted request body as a JSON string.
|
|
159
|
+
"""
|
|
160
|
+
request_body = {
|
|
161
|
+
"texts": [text],
|
|
162
|
+
"input_type": self.input_type,
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
if self.truncate:
|
|
166
|
+
request_body["truncate"] = self.truncate
|
|
167
|
+
|
|
168
|
+
if self.embedding_types:
|
|
169
|
+
request_body["embedding_types"] = self.embedding_types
|
|
170
|
+
|
|
171
|
+
# Add additional request parameters if provided
|
|
172
|
+
if self.request_params:
|
|
173
|
+
request_body.update(self.request_params)
|
|
174
|
+
|
|
175
|
+
return json.dumps(request_body)
|
|
176
|
+
|
|
177
|
+
def response(self, text: str) -> Dict[str, Any]:
|
|
178
|
+
"""
|
|
179
|
+
Get embeddings from AWS Bedrock for the given text.
|
|
180
|
+
|
|
181
|
+
Args:
|
|
182
|
+
text (str): The text to embed.
|
|
183
|
+
|
|
184
|
+
Returns:
|
|
185
|
+
Dict[str, Any]: The response from the API.
|
|
186
|
+
"""
|
|
187
|
+
try:
|
|
188
|
+
body = self._format_request_body(text)
|
|
189
|
+
response = self.get_client().invoke_model(
|
|
190
|
+
modelId=self.id,
|
|
191
|
+
body=body,
|
|
192
|
+
contentType="application/json",
|
|
193
|
+
accept="application/json",
|
|
194
|
+
)
|
|
195
|
+
response_body = json.loads(response["body"].read().decode("utf-8"))
|
|
196
|
+
return response_body
|
|
197
|
+
except ClientError as e:
|
|
198
|
+
log_error(f"Unexpected error calling Bedrock API: {str(e)}")
|
|
199
|
+
raise ModelProviderError(message=str(e.response), model_name="AwsBedrockEmbedder", model_id=self.id) from e
|
|
200
|
+
except Exception as e:
|
|
201
|
+
log_error(f"Unexpected error calling Bedrock API: {str(e)}")
|
|
202
|
+
raise ModelProviderError(message=str(e), model_name="AwsBedrockEmbedder", model_id=self.id) from e
|
|
203
|
+
|
|
204
|
+
def get_embedding(self, text: str) -> List[float]:
|
|
205
|
+
"""
|
|
206
|
+
Get embeddings for the given text.
|
|
207
|
+
|
|
208
|
+
Args:
|
|
209
|
+
text (str): The text to embed.
|
|
210
|
+
|
|
211
|
+
Returns:
|
|
212
|
+
List[float]: The embedding vector.
|
|
213
|
+
"""
|
|
214
|
+
response = self.response(text=text)
|
|
215
|
+
try:
|
|
216
|
+
# Check if response contains embeddings or embeddings by type
|
|
217
|
+
if "embeddings" in response:
|
|
218
|
+
if isinstance(response["embeddings"], list):
|
|
219
|
+
# Default 'float' embeddings response format
|
|
220
|
+
return response["embeddings"][0]
|
|
221
|
+
elif isinstance(response["embeddings"], dict):
|
|
222
|
+
# If embeddings_types parameter was used, select float embeddings
|
|
223
|
+
if "float" in response["embeddings"]:
|
|
224
|
+
return response["embeddings"]["float"][0]
|
|
225
|
+
# Fallback to the first available embedding type
|
|
226
|
+
for embedding_type in response["embeddings"]:
|
|
227
|
+
return response["embeddings"][embedding_type][0]
|
|
228
|
+
log_warning("No embeddings found in response")
|
|
229
|
+
return []
|
|
230
|
+
except Exception as e:
|
|
231
|
+
log_warning(f"Error extracting embeddings: {e}")
|
|
232
|
+
return []
|
|
233
|
+
|
|
234
|
+
def get_embedding_and_usage(self, text: str) -> Tuple[List[float], Optional[Dict[str, Any]]]:
|
|
235
|
+
"""
|
|
236
|
+
Get embeddings and usage information for the given text.
|
|
237
|
+
|
|
238
|
+
Args:
|
|
239
|
+
text (str): The text to embed.
|
|
240
|
+
|
|
241
|
+
Returns:
|
|
242
|
+
Tuple[List[float], Optional[Dict[str, Any]]]: The embedding vector and usage information.
|
|
243
|
+
"""
|
|
244
|
+
response = self.response(text=text)
|
|
245
|
+
|
|
246
|
+
embedding: List[float] = []
|
|
247
|
+
# Extract embeddings
|
|
248
|
+
if "embeddings" in response:
|
|
249
|
+
if isinstance(response["embeddings"], list):
|
|
250
|
+
embedding = response["embeddings"][0]
|
|
251
|
+
elif isinstance(response["embeddings"], dict):
|
|
252
|
+
if "float" in response["embeddings"]:
|
|
253
|
+
embedding = response["embeddings"]["float"][0]
|
|
254
|
+
# Fallback to the first available embedding type
|
|
255
|
+
else:
|
|
256
|
+
for embedding_type in response["embeddings"]:
|
|
257
|
+
embedding = response["embeddings"][embedding_type][0]
|
|
258
|
+
break
|
|
259
|
+
|
|
260
|
+
# Extract usage metrics if available
|
|
261
|
+
usage = None
|
|
262
|
+
if "usage" in response:
|
|
263
|
+
usage = response["usage"]
|
|
264
|
+
|
|
265
|
+
return embedding, usage
|
|
266
|
+
|
|
267
|
+
async def async_get_embedding(self, text: str) -> List[float]:
|
|
268
|
+
"""
|
|
269
|
+
Async version of get_embedding() using native aioboto3 async client.
|
|
270
|
+
"""
|
|
271
|
+
try:
|
|
272
|
+
body = self._format_request_body(text)
|
|
273
|
+
async with self.get_async_client() as client:
|
|
274
|
+
response = await client.invoke_model(
|
|
275
|
+
modelId=self.id,
|
|
276
|
+
body=body,
|
|
277
|
+
contentType="application/json",
|
|
278
|
+
accept="application/json",
|
|
279
|
+
)
|
|
280
|
+
response_body = json.loads((await response["body"].read()).decode("utf-8"))
|
|
281
|
+
|
|
282
|
+
# Extract embeddings using the same logic as get_embedding
|
|
283
|
+
if "embeddings" in response_body:
|
|
284
|
+
if isinstance(response_body["embeddings"], list):
|
|
285
|
+
# Default 'float' embeddings response format
|
|
286
|
+
return response_body["embeddings"][0]
|
|
287
|
+
elif isinstance(response_body["embeddings"], dict):
|
|
288
|
+
# If embeddings_types parameter was used, select float embeddings
|
|
289
|
+
if "float" in response_body["embeddings"]:
|
|
290
|
+
return response_body["embeddings"]["float"][0]
|
|
291
|
+
# Fallback to the first available embedding type
|
|
292
|
+
for embedding_type in response_body["embeddings"]:
|
|
293
|
+
return response_body["embeddings"][embedding_type][0]
|
|
294
|
+
log_warning("No embeddings found in response")
|
|
295
|
+
return []
|
|
296
|
+
except ClientError as e:
|
|
297
|
+
log_error(f"Unexpected error calling Bedrock API: {str(e)}")
|
|
298
|
+
raise ModelProviderError(message=str(e.response), model_name="AwsBedrockEmbedder", model_id=self.id) from e
|
|
299
|
+
except Exception as e:
|
|
300
|
+
log_error(f"Unexpected error calling Bedrock API: {str(e)}")
|
|
301
|
+
raise ModelProviderError(message=str(e), model_name="AwsBedrockEmbedder", model_id=self.id) from e
|
|
302
|
+
|
|
303
|
+
async def async_get_embedding_and_usage(self, text: str) -> Tuple[List[float], Optional[Dict[str, Any]]]:
|
|
304
|
+
"""
|
|
305
|
+
Async version of get_embedding_and_usage() using native aioboto3 async client.
|
|
306
|
+
"""
|
|
307
|
+
try:
|
|
308
|
+
body = self._format_request_body(text)
|
|
309
|
+
async with self.get_async_client() as client:
|
|
310
|
+
response = await client.invoke_model(
|
|
311
|
+
modelId=self.id,
|
|
312
|
+
body=body,
|
|
313
|
+
contentType="application/json",
|
|
314
|
+
accept="application/json",
|
|
315
|
+
)
|
|
316
|
+
response_body = json.loads((await response["body"].read()).decode("utf-8"))
|
|
317
|
+
|
|
318
|
+
embedding: List[float] = []
|
|
319
|
+
# Extract embeddings using the same logic as get_embedding_and_usage
|
|
320
|
+
if "embeddings" in response_body:
|
|
321
|
+
if isinstance(response_body["embeddings"], list):
|
|
322
|
+
embedding = response_body["embeddings"][0]
|
|
323
|
+
elif isinstance(response_body["embeddings"], dict):
|
|
324
|
+
if "float" in response_body["embeddings"]:
|
|
325
|
+
embedding = response_body["embeddings"]["float"][0]
|
|
326
|
+
# Fallback to the first available embedding type
|
|
327
|
+
else:
|
|
328
|
+
for embedding_type in response_body["embeddings"]:
|
|
329
|
+
embedding = response_body["embeddings"][embedding_type][0]
|
|
330
|
+
break
|
|
331
|
+
|
|
332
|
+
# Extract usage metrics if available
|
|
333
|
+
usage = None
|
|
334
|
+
if "usage" in response_body:
|
|
335
|
+
usage = response_body["usage"]
|
|
336
|
+
|
|
337
|
+
return embedding, usage
|
|
338
|
+
except ClientError as e:
|
|
339
|
+
log_error(f"Unexpected error calling Bedrock API: {str(e)}")
|
|
340
|
+
raise ModelProviderError(message=str(e.response), model_name="AwsBedrockEmbedder", model_id=self.id) from e
|
|
341
|
+
except Exception as e:
|
|
342
|
+
log_error(f"Unexpected error calling Bedrock API: {str(e)}")
|
|
343
|
+
raise ModelProviderError(message=str(e), model_name="AwsBedrockEmbedder", model_id=self.id) from e
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from os import getenv
|
|
3
|
+
from typing import Any, Dict, List, Optional, Tuple
|
|
4
|
+
|
|
5
|
+
from typing_extensions import Literal
|
|
6
|
+
|
|
7
|
+
from agno.knowledge.embedder.base import Embedder
|
|
8
|
+
from agno.utils.log import logger
|
|
9
|
+
|
|
10
|
+
try:
|
|
11
|
+
from openai import AsyncAzureOpenAI as AsyncAzureOpenAIClient
|
|
12
|
+
from openai import AzureOpenAI as AzureOpenAIClient
|
|
13
|
+
from openai.types.create_embedding_response import CreateEmbeddingResponse
|
|
14
|
+
except ImportError:
|
|
15
|
+
raise ImportError("`openai` not installed")
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@dataclass
|
|
19
|
+
class AzureOpenAIEmbedder(Embedder):
|
|
20
|
+
id: str = "text-embedding-3-small" # This has to match the model that you deployed at the provided URL
|
|
21
|
+
|
|
22
|
+
dimensions: int = 1536
|
|
23
|
+
encoding_format: Literal["float", "base64"] = "float"
|
|
24
|
+
user: Optional[str] = None
|
|
25
|
+
api_key: Optional[str] = getenv("AZURE_EMBEDDER_OPENAI_API_KEY")
|
|
26
|
+
api_version: str = getenv("AZURE_EMBEDDER_OPENAI_API_VERSION", "2024-10-21")
|
|
27
|
+
azure_endpoint: Optional[str] = getenv("AZURE_EMBEDDER_OPENAI_ENDPOINT")
|
|
28
|
+
azure_deployment: Optional[str] = getenv("AZURE_EMBEDDER_DEPLOYMENT")
|
|
29
|
+
base_url: Optional[str] = None
|
|
30
|
+
azure_ad_token: Optional[str] = None
|
|
31
|
+
azure_ad_token_provider: Optional[Any] = None
|
|
32
|
+
organization: Optional[str] = None
|
|
33
|
+
request_params: Optional[Dict[str, Any]] = None
|
|
34
|
+
client_params: Optional[Dict[str, Any]] = None
|
|
35
|
+
openai_client: Optional[AzureOpenAIClient] = None
|
|
36
|
+
async_client: Optional[AsyncAzureOpenAIClient] = None
|
|
37
|
+
|
|
38
|
+
@property
|
|
39
|
+
def client(self) -> AzureOpenAIClient:
|
|
40
|
+
if self.openai_client:
|
|
41
|
+
return self.openai_client
|
|
42
|
+
|
|
43
|
+
_client_params: Dict[str, Any] = {}
|
|
44
|
+
if self.api_key:
|
|
45
|
+
_client_params["api_key"] = self.api_key
|
|
46
|
+
if self.api_version:
|
|
47
|
+
_client_params["api_version"] = self.api_version
|
|
48
|
+
if self.organization:
|
|
49
|
+
_client_params["organization"] = self.organization
|
|
50
|
+
if self.azure_endpoint:
|
|
51
|
+
_client_params["azure_endpoint"] = self.azure_endpoint
|
|
52
|
+
if self.azure_deployment:
|
|
53
|
+
_client_params["azure_deployment"] = self.azure_deployment
|
|
54
|
+
if self.base_url:
|
|
55
|
+
_client_params["base_url"] = self.base_url
|
|
56
|
+
if self.azure_ad_token:
|
|
57
|
+
_client_params["azure_ad_token"] = self.azure_ad_token
|
|
58
|
+
if self.azure_ad_token_provider:
|
|
59
|
+
_client_params["azure_ad_token_provider"] = self.azure_ad_token_provider
|
|
60
|
+
|
|
61
|
+
if self.client_params:
|
|
62
|
+
_client_params.update(self.client_params)
|
|
63
|
+
|
|
64
|
+
return AzureOpenAIClient(**_client_params)
|
|
65
|
+
|
|
66
|
+
@property
|
|
67
|
+
def aclient(self) -> AsyncAzureOpenAIClient:
|
|
68
|
+
if self.async_client:
|
|
69
|
+
return self.async_client
|
|
70
|
+
|
|
71
|
+
_client_params: Dict[str, Any] = {}
|
|
72
|
+
if self.api_key:
|
|
73
|
+
_client_params["api_key"] = self.api_key
|
|
74
|
+
if self.api_version:
|
|
75
|
+
_client_params["api_version"] = self.api_version
|
|
76
|
+
if self.organization:
|
|
77
|
+
_client_params["organization"] = self.organization
|
|
78
|
+
if self.azure_endpoint:
|
|
79
|
+
_client_params["azure_endpoint"] = self.azure_endpoint
|
|
80
|
+
if self.azure_deployment:
|
|
81
|
+
_client_params["azure_deployment"] = self.azure_deployment
|
|
82
|
+
if self.base_url:
|
|
83
|
+
_client_params["base_url"] = self.base_url
|
|
84
|
+
if self.azure_ad_token:
|
|
85
|
+
_client_params["azure_ad_token"] = self.azure_ad_token
|
|
86
|
+
if self.azure_ad_token_provider:
|
|
87
|
+
_client_params["azure_ad_token_provider"] = self.azure_ad_token_provider
|
|
88
|
+
|
|
89
|
+
if self.client_params:
|
|
90
|
+
_client_params.update(self.client_params)
|
|
91
|
+
|
|
92
|
+
self.async_client = AsyncAzureOpenAIClient(**_client_params)
|
|
93
|
+
return self.async_client
|
|
94
|
+
|
|
95
|
+
def _response(self, text: str) -> CreateEmbeddingResponse:
|
|
96
|
+
_request_params: Dict[str, Any] = {
|
|
97
|
+
"input": text,
|
|
98
|
+
"model": self.id,
|
|
99
|
+
"encoding_format": self.encoding_format,
|
|
100
|
+
}
|
|
101
|
+
if self.user is not None:
|
|
102
|
+
_request_params["user"] = self.user
|
|
103
|
+
if self.id.startswith("text-embedding-3"):
|
|
104
|
+
_request_params["dimensions"] = self.dimensions
|
|
105
|
+
if self.request_params:
|
|
106
|
+
_request_params.update(self.request_params)
|
|
107
|
+
|
|
108
|
+
return self.client.embeddings.create(**_request_params)
|
|
109
|
+
|
|
110
|
+
def get_embedding(self, text: str) -> List[float]:
|
|
111
|
+
response: CreateEmbeddingResponse = self._response(text=text)
|
|
112
|
+
try:
|
|
113
|
+
return response.data[0].embedding
|
|
114
|
+
except Exception as e:
|
|
115
|
+
logger.warning(e)
|
|
116
|
+
return []
|
|
117
|
+
|
|
118
|
+
def get_embedding_and_usage(self, text: str) -> Tuple[List[float], Optional[Dict]]:
|
|
119
|
+
response: CreateEmbeddingResponse = self._response(text=text)
|
|
120
|
+
|
|
121
|
+
embedding = response.data[0].embedding
|
|
122
|
+
usage = response.usage
|
|
123
|
+
return embedding, usage.model_dump()
|
|
124
|
+
|
|
125
|
+
async def _aresponse(self, text: str) -> CreateEmbeddingResponse:
|
|
126
|
+
"""Async version of _response method."""
|
|
127
|
+
_request_params: Dict[str, Any] = {
|
|
128
|
+
"input": text,
|
|
129
|
+
"model": self.id,
|
|
130
|
+
"encoding_format": self.encoding_format,
|
|
131
|
+
}
|
|
132
|
+
if self.user is not None:
|
|
133
|
+
_request_params["user"] = self.user
|
|
134
|
+
if self.id.startswith("text-embedding-3"):
|
|
135
|
+
_request_params["dimensions"] = self.dimensions
|
|
136
|
+
if self.request_params:
|
|
137
|
+
_request_params.update(self.request_params)
|
|
138
|
+
|
|
139
|
+
return await self.aclient.embeddings.create(**_request_params)
|
|
140
|
+
|
|
141
|
+
async def async_get_embedding(self, text: str) -> List[float]:
|
|
142
|
+
"""Async version of get_embedding using the native Azure OpenAI async client."""
|
|
143
|
+
response: CreateEmbeddingResponse = await self._aresponse(text=text)
|
|
144
|
+
try:
|
|
145
|
+
return response.data[0].embedding
|
|
146
|
+
except Exception as e:
|
|
147
|
+
logger.warning(e)
|
|
148
|
+
return []
|
|
149
|
+
|
|
150
|
+
async def async_get_embedding_and_usage(self, text: str) -> Tuple[List[float], Optional[Dict]]:
|
|
151
|
+
"""Async version of get_embedding_and_usage using the native Azure OpenAI async client."""
|
|
152
|
+
response: CreateEmbeddingResponse = await self._aresponse(text=text)
|
|
153
|
+
|
|
154
|
+
embedding = response.data[0].embedding
|
|
155
|
+
usage = response.usage
|
|
156
|
+
return embedding, usage.model_dump()
|
|
157
|
+
|
|
158
|
+
async def async_get_embeddings_batch_and_usage(
|
|
159
|
+
self, texts: List[str]
|
|
160
|
+
) -> Tuple[List[List[float]], List[Optional[Dict]]]:
|
|
161
|
+
"""
|
|
162
|
+
Get embeddings and usage for multiple texts in batches.
|
|
163
|
+
|
|
164
|
+
Args:
|
|
165
|
+
texts: List of text strings to embed
|
|
166
|
+
|
|
167
|
+
Returns:
|
|
168
|
+
Tuple of (List of embedding vectors, List of usage dictionaries)
|
|
169
|
+
"""
|
|
170
|
+
all_embeddings = []
|
|
171
|
+
all_usage = []
|
|
172
|
+
logger.info(f"Getting embeddings and usage for {len(texts)} texts in batches of {self.batch_size}")
|
|
173
|
+
|
|
174
|
+
for i in range(0, len(texts), self.batch_size):
|
|
175
|
+
batch_texts = texts[i : i + self.batch_size]
|
|
176
|
+
|
|
177
|
+
req: Dict[str, Any] = {
|
|
178
|
+
"input": batch_texts,
|
|
179
|
+
"model": self.id,
|
|
180
|
+
"encoding_format": self.encoding_format,
|
|
181
|
+
}
|
|
182
|
+
if self.user is not None:
|
|
183
|
+
req["user"] = self.user
|
|
184
|
+
if self.id.startswith("text-embedding-3"):
|
|
185
|
+
req["dimensions"] = self.dimensions
|
|
186
|
+
if self.request_params:
|
|
187
|
+
req.update(self.request_params)
|
|
188
|
+
|
|
189
|
+
try:
|
|
190
|
+
response: CreateEmbeddingResponse = await self.aclient.embeddings.create(**req)
|
|
191
|
+
batch_embeddings = [data.embedding for data in response.data]
|
|
192
|
+
all_embeddings.extend(batch_embeddings)
|
|
193
|
+
|
|
194
|
+
# For each embedding in the batch, add the same usage information
|
|
195
|
+
usage_dict = response.usage.model_dump() if response.usage else None
|
|
196
|
+
all_usage.extend([usage_dict] * len(batch_embeddings))
|
|
197
|
+
except Exception as e:
|
|
198
|
+
logger.warning(f"Error in async batch embedding: {e}")
|
|
199
|
+
# Fallback to individual calls for this batch
|
|
200
|
+
for text in batch_texts:
|
|
201
|
+
try:
|
|
202
|
+
embedding, usage = await self.async_get_embedding_and_usage(text)
|
|
203
|
+
all_embeddings.append(embedding)
|
|
204
|
+
all_usage.append(usage)
|
|
205
|
+
except Exception as e2:
|
|
206
|
+
logger.warning(f"Error in individual async embedding fallback: {e2}")
|
|
207
|
+
all_embeddings.append([])
|
|
208
|
+
all_usage.append(None)
|
|
209
|
+
|
|
210
|
+
return all_embeddings, all_usage
|
|
@@ -7,9 +7,17 @@ class Embedder:
|
|
|
7
7
|
"""Base class for managing embedders"""
|
|
8
8
|
|
|
9
9
|
dimensions: Optional[int] = 1536
|
|
10
|
+
enable_batch: bool = False
|
|
11
|
+
batch_size: int = 100 # Number of texts to process in each API call
|
|
10
12
|
|
|
11
13
|
def get_embedding(self, text: str) -> List[float]:
|
|
12
14
|
raise NotImplementedError
|
|
13
15
|
|
|
14
16
|
def get_embedding_and_usage(self, text: str) -> Tuple[List[float], Optional[Dict]]:
|
|
15
17
|
raise NotImplementedError
|
|
18
|
+
|
|
19
|
+
async def async_get_embedding(self, text: str) -> List[float]:
|
|
20
|
+
raise NotImplementedError
|
|
21
|
+
|
|
22
|
+
async def async_get_embedding_and_usage(self, text: str) -> Tuple[List[float], Optional[Dict]]:
|
|
23
|
+
raise NotImplementedError
|