agno 1.8.0__py3-none-any.whl → 2.0.0a1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- agno/__init__.py +8 -0
- agno/agent/__init__.py +19 -27
- agno/agent/agent.py +2781 -4126
- agno/api/agent.py +9 -65
- agno/api/api.py +5 -46
- agno/api/evals.py +6 -17
- agno/api/os.py +17 -0
- agno/api/routes.py +6 -41
- agno/api/schemas/__init__.py +9 -0
- agno/api/schemas/agent.py +5 -21
- agno/api/schemas/evals.py +7 -16
- agno/api/schemas/os.py +14 -0
- agno/api/schemas/team.py +5 -21
- agno/api/schemas/utils.py +21 -0
- agno/api/schemas/workflows.py +11 -7
- agno/api/settings.py +53 -0
- agno/api/team.py +9 -64
- agno/api/workflow.py +28 -0
- agno/cloud/aws/base.py +214 -0
- agno/cloud/aws/s3/__init__.py +2 -0
- agno/cloud/aws/s3/api_client.py +43 -0
- agno/cloud/aws/s3/bucket.py +195 -0
- agno/cloud/aws/s3/object.py +57 -0
- agno/db/__init__.py +24 -0
- agno/db/base.py +245 -0
- agno/db/dynamo/__init__.py +3 -0
- agno/db/dynamo/dynamo.py +1749 -0
- agno/db/dynamo/schemas.py +278 -0
- agno/db/dynamo/utils.py +684 -0
- agno/db/firestore/__init__.py +3 -0
- agno/db/firestore/firestore.py +1438 -0
- agno/db/firestore/schemas.py +130 -0
- agno/db/firestore/utils.py +278 -0
- agno/db/gcs_json/__init__.py +3 -0
- agno/db/gcs_json/gcs_json_db.py +1001 -0
- agno/db/gcs_json/utils.py +194 -0
- agno/db/in_memory/__init__.py +3 -0
- agno/db/in_memory/in_memory_db.py +888 -0
- agno/db/in_memory/utils.py +172 -0
- agno/db/json/__init__.py +3 -0
- agno/db/json/json_db.py +1051 -0
- agno/db/json/utils.py +196 -0
- agno/db/migrations/v1_to_v2.py +162 -0
- agno/db/mongo/__init__.py +3 -0
- agno/db/mongo/mongo.py +1417 -0
- agno/db/mongo/schemas.py +77 -0
- agno/db/mongo/utils.py +204 -0
- agno/db/mysql/__init__.py +3 -0
- agno/db/mysql/mysql.py +1719 -0
- agno/db/mysql/schemas.py +124 -0
- agno/db/mysql/utils.py +298 -0
- agno/db/postgres/__init__.py +3 -0
- agno/db/postgres/postgres.py +1720 -0
- agno/db/postgres/schemas.py +124 -0
- agno/db/postgres/utils.py +281 -0
- agno/db/redis/__init__.py +3 -0
- agno/db/redis/redis.py +1371 -0
- agno/db/redis/schemas.py +109 -0
- agno/db/redis/utils.py +288 -0
- agno/db/schemas/__init__.py +3 -0
- agno/db/schemas/evals.py +33 -0
- agno/db/schemas/knowledge.py +40 -0
- agno/db/schemas/memory.py +46 -0
- agno/db/singlestore/__init__.py +3 -0
- agno/db/singlestore/schemas.py +116 -0
- agno/db/singlestore/singlestore.py +1722 -0
- agno/db/singlestore/utils.py +327 -0
- agno/db/sqlite/__init__.py +3 -0
- agno/db/sqlite/schemas.py +119 -0
- agno/db/sqlite/sqlite.py +1680 -0
- agno/db/sqlite/utils.py +269 -0
- agno/db/utils.py +88 -0
- agno/eval/__init__.py +14 -0
- agno/eval/accuracy.py +142 -43
- agno/eval/performance.py +88 -23
- agno/eval/reliability.py +73 -20
- agno/eval/utils.py +23 -13
- agno/integrations/discord/__init__.py +3 -0
- agno/{app → integrations}/discord/client.py +10 -10
- agno/knowledge/__init__.py +2 -2
- agno/{document → knowledge}/chunking/agentic.py +2 -2
- agno/{document → knowledge}/chunking/document.py +2 -2
- agno/{document → knowledge}/chunking/fixed.py +3 -3
- agno/{document → knowledge}/chunking/markdown.py +2 -2
- agno/{document → knowledge}/chunking/recursive.py +2 -2
- agno/{document → knowledge}/chunking/row.py +2 -2
- agno/knowledge/chunking/semantic.py +59 -0
- agno/knowledge/chunking/strategy.py +121 -0
- agno/knowledge/content.py +74 -0
- agno/knowledge/document/__init__.py +5 -0
- agno/{document → knowledge/document}/base.py +12 -2
- agno/knowledge/embedder/__init__.py +5 -0
- agno/{embedder → knowledge/embedder}/aws_bedrock.py +127 -1
- agno/{embedder → knowledge/embedder}/azure_openai.py +65 -1
- agno/{embedder → knowledge/embedder}/base.py +6 -0
- agno/{embedder → knowledge/embedder}/cohere.py +72 -1
- agno/{embedder → knowledge/embedder}/fastembed.py +17 -1
- agno/{embedder → knowledge/embedder}/fireworks.py +1 -1
- agno/{embedder → knowledge/embedder}/google.py +74 -1
- agno/{embedder → knowledge/embedder}/huggingface.py +36 -2
- agno/{embedder → knowledge/embedder}/jina.py +48 -2
- agno/knowledge/embedder/langdb.py +22 -0
- agno/knowledge/embedder/mistral.py +139 -0
- agno/{embedder → knowledge/embedder}/nebius.py +1 -1
- agno/{embedder → knowledge/embedder}/ollama.py +54 -3
- agno/knowledge/embedder/openai.py +223 -0
- agno/{embedder → knowledge/embedder}/sentence_transformer.py +16 -1
- agno/{embedder → knowledge/embedder}/together.py +1 -1
- agno/{embedder → knowledge/embedder}/voyageai.py +49 -1
- agno/knowledge/knowledge.py +1515 -0
- agno/knowledge/reader/__init__.py +7 -0
- agno/{document → knowledge}/reader/arxiv_reader.py +32 -4
- agno/knowledge/reader/base.py +88 -0
- agno/{document → knowledge}/reader/csv_reader.py +68 -15
- agno/knowledge/reader/docx_reader.py +83 -0
- agno/{document → knowledge}/reader/firecrawl_reader.py +42 -21
- agno/knowledge/reader/gcs_reader.py +67 -0
- agno/{document → knowledge}/reader/json_reader.py +30 -9
- agno/{document → knowledge}/reader/markdown_reader.py +36 -9
- agno/{document → knowledge}/reader/pdf_reader.py +79 -21
- agno/knowledge/reader/reader_factory.py +275 -0
- agno/knowledge/reader/s3_reader.py +171 -0
- agno/{document → knowledge}/reader/text_reader.py +31 -10
- agno/knowledge/reader/url_reader.py +84 -0
- agno/knowledge/reader/web_search_reader.py +389 -0
- agno/{document → knowledge}/reader/website_reader.py +37 -10
- agno/knowledge/reader/wikipedia_reader.py +59 -0
- agno/knowledge/reader/youtube_reader.py +78 -0
- agno/knowledge/remote_content/remote_content.py +88 -0
- agno/{reranker → knowledge/reranker}/base.py +1 -1
- agno/{reranker → knowledge/reranker}/cohere.py +2 -2
- agno/{reranker → knowledge/reranker}/infinity.py +2 -2
- agno/{reranker → knowledge/reranker}/sentence_transformer.py +2 -2
- agno/knowledge/types.py +30 -0
- agno/knowledge/utils.py +169 -0
- agno/media.py +2 -2
- agno/memory/__init__.py +2 -10
- agno/memory/manager.py +1003 -148
- agno/models/aimlapi/__init__.py +2 -2
- agno/models/aimlapi/aimlapi.py +6 -6
- agno/models/anthropic/claude.py +129 -82
- agno/models/aws/bedrock.py +107 -175
- agno/models/aws/claude.py +64 -18
- agno/models/azure/ai_foundry.py +73 -23
- agno/models/base.py +347 -287
- agno/models/cerebras/cerebras.py +84 -27
- agno/models/cohere/chat.py +106 -98
- agno/models/dashscope/dashscope.py +14 -5
- agno/models/google/gemini.py +123 -53
- agno/models/groq/groq.py +97 -35
- agno/models/huggingface/huggingface.py +92 -27
- agno/models/ibm/watsonx.py +72 -13
- agno/models/litellm/chat.py +85 -13
- agno/models/message.py +38 -144
- agno/models/meta/llama.py +85 -49
- agno/models/metrics.py +120 -0
- agno/models/mistral/mistral.py +90 -21
- agno/models/ollama/__init__.py +0 -2
- agno/models/ollama/chat.py +84 -46
- agno/models/openai/chat.py +135 -27
- agno/models/openai/responses.py +233 -115
- agno/models/perplexity/perplexity.py +26 -2
- agno/models/portkey/portkey.py +0 -7
- agno/models/response.py +14 -8
- agno/models/utils.py +20 -0
- agno/models/vercel/__init__.py +2 -2
- agno/models/vercel/v0.py +1 -1
- agno/models/vllm/__init__.py +2 -2
- agno/models/vllm/vllm.py +3 -3
- agno/models/xai/xai.py +10 -10
- agno/os/__init__.py +3 -0
- agno/os/app.py +393 -0
- agno/os/auth.py +47 -0
- agno/os/config.py +103 -0
- agno/os/interfaces/agui/__init__.py +3 -0
- agno/os/interfaces/agui/agui.py +31 -0
- agno/{app/agui/async_router.py → os/interfaces/agui/router.py} +16 -16
- agno/{app → os/interfaces}/agui/utils.py +65 -28
- agno/os/interfaces/base.py +21 -0
- agno/os/interfaces/slack/__init__.py +3 -0
- agno/{app/slack/async_router.py → os/interfaces/slack/router.py} +3 -5
- agno/os/interfaces/slack/slack.py +33 -0
- agno/os/interfaces/whatsapp/__init__.py +3 -0
- agno/{app/whatsapp/async_router.py → os/interfaces/whatsapp/router.py} +4 -7
- agno/os/interfaces/whatsapp/whatsapp.py +30 -0
- agno/os/router.py +843 -0
- agno/os/routers/__init__.py +3 -0
- agno/os/routers/evals/__init__.py +3 -0
- agno/os/routers/evals/evals.py +204 -0
- agno/os/routers/evals/schemas.py +142 -0
- agno/os/routers/evals/utils.py +161 -0
- agno/os/routers/knowledge/__init__.py +3 -0
- agno/os/routers/knowledge/knowledge.py +413 -0
- agno/os/routers/knowledge/schemas.py +118 -0
- agno/os/routers/memory/__init__.py +3 -0
- agno/os/routers/memory/memory.py +179 -0
- agno/os/routers/memory/schemas.py +58 -0
- agno/os/routers/metrics/__init__.py +3 -0
- agno/os/routers/metrics/metrics.py +58 -0
- agno/os/routers/metrics/schemas.py +47 -0
- agno/os/routers/session/__init__.py +3 -0
- agno/os/routers/session/session.py +163 -0
- agno/os/schema.py +892 -0
- agno/{app/playground → os}/settings.py +8 -15
- agno/os/utils.py +270 -0
- agno/reasoning/azure_ai_foundry.py +4 -4
- agno/reasoning/deepseek.py +4 -4
- agno/reasoning/default.py +6 -11
- agno/reasoning/groq.py +4 -4
- agno/reasoning/helpers.py +4 -6
- agno/reasoning/ollama.py +4 -4
- agno/reasoning/openai.py +4 -4
- agno/run/{response.py → agent.py} +144 -72
- agno/run/base.py +44 -58
- agno/run/cancel.py +83 -0
- agno/run/team.py +133 -77
- agno/run/workflow.py +537 -12
- agno/session/__init__.py +10 -0
- agno/session/agent.py +244 -0
- agno/session/summary.py +225 -0
- agno/session/team.py +262 -0
- agno/{storage/session/v2 → session}/workflow.py +47 -24
- agno/team/__init__.py +15 -16
- agno/team/team.py +2967 -4243
- agno/tools/agentql.py +14 -5
- agno/tools/airflow.py +9 -4
- agno/tools/api.py +7 -3
- agno/tools/apify.py +2 -46
- agno/tools/arxiv.py +8 -3
- agno/tools/aws_lambda.py +7 -5
- agno/tools/aws_ses.py +7 -1
- agno/tools/baidusearch.py +4 -1
- agno/tools/bitbucket.py +4 -4
- agno/tools/brandfetch.py +14 -11
- agno/tools/bravesearch.py +4 -1
- agno/tools/brightdata.py +42 -22
- agno/tools/browserbase.py +13 -4
- agno/tools/calcom.py +12 -10
- agno/tools/calculator.py +10 -27
- agno/tools/cartesia.py +18 -13
- agno/tools/{clickup_tool.py → clickup.py} +12 -25
- agno/tools/confluence.py +71 -18
- agno/tools/crawl4ai.py +7 -1
- agno/tools/csv_toolkit.py +9 -8
- agno/tools/dalle.py +18 -11
- agno/tools/daytona.py +13 -16
- agno/tools/decorator.py +6 -3
- agno/tools/desi_vocal.py +16 -7
- agno/tools/discord.py +11 -8
- agno/tools/docker.py +30 -42
- agno/tools/duckdb.py +34 -53
- agno/tools/duckduckgo.py +8 -7
- agno/tools/e2b.py +62 -62
- agno/tools/eleven_labs.py +35 -28
- agno/tools/email.py +4 -1
- agno/tools/evm.py +7 -1
- agno/tools/exa.py +19 -14
- agno/tools/fal.py +29 -29
- agno/tools/file.py +9 -8
- agno/tools/financial_datasets.py +25 -44
- agno/tools/firecrawl.py +22 -22
- agno/tools/function.py +68 -17
- agno/tools/giphy.py +22 -10
- agno/tools/github.py +48 -126
- agno/tools/gmail.py +46 -62
- agno/tools/google_bigquery.py +7 -6
- agno/tools/google_maps.py +11 -26
- agno/tools/googlesearch.py +7 -2
- agno/tools/googlesheets.py +21 -17
- agno/tools/hackernews.py +9 -5
- agno/tools/jina.py +5 -4
- agno/tools/jira.py +18 -9
- agno/tools/knowledge.py +31 -32
- agno/tools/linear.py +18 -33
- agno/tools/linkup.py +5 -1
- agno/tools/local_file_system.py +8 -5
- agno/tools/lumalab.py +31 -19
- agno/tools/mem0.py +18 -12
- agno/tools/memori.py +14 -10
- agno/tools/mlx_transcribe.py +3 -2
- agno/tools/models/azure_openai.py +32 -14
- agno/tools/models/gemini.py +58 -31
- agno/tools/models/groq.py +29 -20
- agno/tools/models/nebius.py +27 -11
- agno/tools/models_labs.py +39 -15
- agno/tools/moviepy_video.py +7 -6
- agno/tools/neo4j.py +134 -0
- agno/tools/newspaper.py +7 -2
- agno/tools/newspaper4k.py +8 -3
- agno/tools/openai.py +57 -26
- agno/tools/openbb.py +12 -11
- agno/tools/opencv.py +62 -46
- agno/tools/openweather.py +14 -12
- agno/tools/pandas.py +11 -3
- agno/tools/postgres.py +4 -12
- agno/tools/pubmed.py +4 -1
- agno/tools/python.py +9 -22
- agno/tools/reasoning.py +35 -27
- agno/tools/reddit.py +11 -26
- agno/tools/replicate.py +54 -41
- agno/tools/resend.py +4 -1
- agno/tools/scrapegraph.py +15 -14
- agno/tools/searxng.py +10 -23
- agno/tools/serpapi.py +6 -3
- agno/tools/serper.py +13 -4
- agno/tools/shell.py +9 -2
- agno/tools/slack.py +12 -11
- agno/tools/sleep.py +3 -2
- agno/tools/spider.py +24 -4
- agno/tools/sql.py +7 -6
- agno/tools/tavily.py +6 -4
- agno/tools/telegram.py +12 -4
- agno/tools/todoist.py +11 -31
- agno/tools/toolkit.py +1 -1
- agno/tools/trafilatura.py +22 -6
- agno/tools/trello.py +9 -22
- agno/tools/twilio.py +10 -3
- agno/tools/user_control_flow.py +6 -1
- agno/tools/valyu.py +34 -5
- agno/tools/visualization.py +19 -28
- agno/tools/webbrowser.py +4 -3
- agno/tools/webex.py +11 -7
- agno/tools/website.py +15 -46
- agno/tools/webtools.py +12 -4
- agno/tools/whatsapp.py +5 -9
- agno/tools/wikipedia.py +20 -13
- agno/tools/x.py +14 -13
- agno/tools/yfinance.py +13 -40
- agno/tools/youtube.py +26 -20
- agno/tools/zendesk.py +7 -2
- agno/tools/zep.py +10 -7
- agno/tools/zoom.py +10 -9
- agno/utils/common.py +1 -19
- agno/utils/events.py +95 -118
- agno/utils/knowledge.py +29 -0
- agno/utils/location.py +2 -2
- agno/utils/log.py +2 -2
- agno/utils/mcp.py +11 -5
- agno/utils/media.py +39 -0
- agno/utils/message.py +12 -1
- agno/utils/models/claude.py +6 -4
- agno/utils/models/mistral.py +8 -7
- agno/utils/models/schema_utils.py +3 -3
- agno/utils/pprint.py +33 -32
- agno/utils/print_response/agent.py +779 -0
- agno/utils/print_response/team.py +1565 -0
- agno/utils/print_response/workflow.py +1451 -0
- agno/utils/prompts.py +14 -14
- agno/utils/reasoning.py +87 -0
- agno/utils/response.py +42 -42
- agno/utils/string.py +8 -22
- agno/utils/team.py +50 -0
- agno/utils/timer.py +2 -2
- agno/vectordb/base.py +33 -21
- agno/vectordb/cassandra/cassandra.py +287 -23
- agno/vectordb/chroma/chromadb.py +482 -59
- agno/vectordb/clickhouse/clickhousedb.py +270 -63
- agno/vectordb/couchbase/couchbase.py +309 -29
- agno/vectordb/lancedb/lance_db.py +360 -21
- agno/vectordb/langchaindb/__init__.py +5 -0
- agno/vectordb/langchaindb/langchaindb.py +145 -0
- agno/vectordb/lightrag/__init__.py +5 -0
- agno/vectordb/lightrag/lightrag.py +374 -0
- agno/vectordb/llamaindex/llamaindexdb.py +127 -0
- agno/vectordb/milvus/milvus.py +242 -32
- agno/vectordb/mongodb/mongodb.py +200 -24
- agno/vectordb/pgvector/pgvector.py +319 -37
- agno/vectordb/pineconedb/pineconedb.py +221 -27
- agno/vectordb/qdrant/qdrant.py +356 -14
- agno/vectordb/singlestore/singlestore.py +286 -29
- agno/vectordb/surrealdb/surrealdb.py +187 -7
- agno/vectordb/upstashdb/upstashdb.py +342 -26
- agno/vectordb/weaviate/weaviate.py +227 -165
- agno/workflow/__init__.py +17 -13
- agno/workflow/{v2/condition.py → condition.py} +135 -32
- agno/workflow/{v2/loop.py → loop.py} +115 -28
- agno/workflow/{v2/parallel.py → parallel.py} +138 -108
- agno/workflow/{v2/router.py → router.py} +133 -32
- agno/workflow/{v2/step.py → step.py} +200 -42
- agno/workflow/{v2/steps.py → steps.py} +147 -66
- agno/workflow/types.py +482 -0
- agno/workflow/workflow.py +2394 -696
- agno-2.0.0a1.dist-info/METADATA +355 -0
- agno-2.0.0a1.dist-info/RECORD +514 -0
- agno/agent/metrics.py +0 -107
- agno/api/app.py +0 -35
- agno/api/playground.py +0 -92
- agno/api/schemas/app.py +0 -12
- agno/api/schemas/playground.py +0 -22
- agno/api/schemas/user.py +0 -35
- agno/api/schemas/workspace.py +0 -46
- agno/api/user.py +0 -160
- agno/api/workflows.py +0 -33
- agno/api/workspace.py +0 -175
- agno/app/agui/__init__.py +0 -3
- agno/app/agui/app.py +0 -17
- agno/app/agui/sync_router.py +0 -120
- agno/app/base.py +0 -186
- agno/app/discord/__init__.py +0 -3
- agno/app/fastapi/__init__.py +0 -3
- agno/app/fastapi/app.py +0 -107
- agno/app/fastapi/async_router.py +0 -457
- agno/app/fastapi/sync_router.py +0 -448
- agno/app/playground/app.py +0 -228
- agno/app/playground/async_router.py +0 -1050
- agno/app/playground/deploy.py +0 -249
- agno/app/playground/operator.py +0 -183
- agno/app/playground/schemas.py +0 -220
- agno/app/playground/serve.py +0 -55
- agno/app/playground/sync_router.py +0 -1042
- agno/app/playground/utils.py +0 -46
- agno/app/settings.py +0 -15
- agno/app/slack/__init__.py +0 -3
- agno/app/slack/app.py +0 -19
- agno/app/slack/sync_router.py +0 -92
- agno/app/utils.py +0 -54
- agno/app/whatsapp/__init__.py +0 -3
- agno/app/whatsapp/app.py +0 -15
- agno/app/whatsapp/sync_router.py +0 -197
- agno/cli/auth_server.py +0 -249
- agno/cli/config.py +0 -274
- agno/cli/console.py +0 -88
- agno/cli/credentials.py +0 -23
- agno/cli/entrypoint.py +0 -571
- agno/cli/operator.py +0 -357
- agno/cli/settings.py +0 -96
- agno/cli/ws/ws_cli.py +0 -817
- agno/constants.py +0 -13
- agno/document/__init__.py +0 -5
- agno/document/chunking/semantic.py +0 -45
- agno/document/chunking/strategy.py +0 -31
- agno/document/reader/__init__.py +0 -5
- agno/document/reader/base.py +0 -47
- agno/document/reader/docx_reader.py +0 -60
- agno/document/reader/gcs/pdf_reader.py +0 -44
- agno/document/reader/s3/pdf_reader.py +0 -59
- agno/document/reader/s3/text_reader.py +0 -63
- agno/document/reader/url_reader.py +0 -59
- agno/document/reader/youtube_reader.py +0 -58
- agno/embedder/__init__.py +0 -5
- agno/embedder/langdb.py +0 -80
- agno/embedder/mistral.py +0 -82
- agno/embedder/openai.py +0 -78
- agno/file/__init__.py +0 -5
- agno/file/file.py +0 -16
- agno/file/local/csv.py +0 -32
- agno/file/local/txt.py +0 -19
- agno/infra/app.py +0 -240
- agno/infra/base.py +0 -144
- agno/infra/context.py +0 -20
- agno/infra/db_app.py +0 -52
- agno/infra/resource.py +0 -205
- agno/infra/resources.py +0 -55
- agno/knowledge/agent.py +0 -698
- agno/knowledge/arxiv.py +0 -33
- agno/knowledge/combined.py +0 -36
- agno/knowledge/csv.py +0 -144
- agno/knowledge/csv_url.py +0 -124
- agno/knowledge/document.py +0 -223
- agno/knowledge/docx.py +0 -137
- agno/knowledge/firecrawl.py +0 -34
- agno/knowledge/gcs/__init__.py +0 -0
- agno/knowledge/gcs/base.py +0 -39
- agno/knowledge/gcs/pdf.py +0 -125
- agno/knowledge/json.py +0 -137
- agno/knowledge/langchain.py +0 -71
- agno/knowledge/light_rag.py +0 -273
- agno/knowledge/llamaindex.py +0 -66
- agno/knowledge/markdown.py +0 -154
- agno/knowledge/pdf.py +0 -164
- agno/knowledge/pdf_bytes.py +0 -42
- agno/knowledge/pdf_url.py +0 -148
- agno/knowledge/s3/__init__.py +0 -0
- agno/knowledge/s3/base.py +0 -64
- agno/knowledge/s3/pdf.py +0 -33
- agno/knowledge/s3/text.py +0 -34
- agno/knowledge/text.py +0 -141
- agno/knowledge/url.py +0 -46
- agno/knowledge/website.py +0 -179
- agno/knowledge/wikipedia.py +0 -32
- agno/knowledge/youtube.py +0 -35
- agno/memory/agent.py +0 -423
- agno/memory/classifier.py +0 -104
- agno/memory/db/__init__.py +0 -5
- agno/memory/db/base.py +0 -42
- agno/memory/db/mongodb.py +0 -189
- agno/memory/db/postgres.py +0 -203
- agno/memory/db/sqlite.py +0 -193
- agno/memory/memory.py +0 -22
- agno/memory/row.py +0 -36
- agno/memory/summarizer.py +0 -201
- agno/memory/summary.py +0 -19
- agno/memory/team.py +0 -415
- agno/memory/v2/__init__.py +0 -2
- agno/memory/v2/db/__init__.py +0 -1
- agno/memory/v2/db/base.py +0 -42
- agno/memory/v2/db/firestore.py +0 -339
- agno/memory/v2/db/mongodb.py +0 -196
- agno/memory/v2/db/postgres.py +0 -214
- agno/memory/v2/db/redis.py +0 -187
- agno/memory/v2/db/schema.py +0 -54
- agno/memory/v2/db/sqlite.py +0 -209
- agno/memory/v2/manager.py +0 -437
- agno/memory/v2/memory.py +0 -1097
- agno/memory/v2/schema.py +0 -55
- agno/memory/v2/summarizer.py +0 -215
- agno/memory/workflow.py +0 -38
- agno/models/ollama/tools.py +0 -430
- agno/models/qwen/__init__.py +0 -5
- agno/playground/__init__.py +0 -10
- agno/playground/deploy.py +0 -3
- agno/playground/playground.py +0 -3
- agno/playground/serve.py +0 -3
- agno/playground/settings.py +0 -3
- agno/reranker/__init__.py +0 -0
- agno/run/v2/__init__.py +0 -0
- agno/run/v2/workflow.py +0 -567
- agno/storage/__init__.py +0 -0
- agno/storage/agent/__init__.py +0 -0
- agno/storage/agent/dynamodb.py +0 -1
- agno/storage/agent/json.py +0 -1
- agno/storage/agent/mongodb.py +0 -1
- agno/storage/agent/postgres.py +0 -1
- agno/storage/agent/singlestore.py +0 -1
- agno/storage/agent/sqlite.py +0 -1
- agno/storage/agent/yaml.py +0 -1
- agno/storage/base.py +0 -60
- agno/storage/dynamodb.py +0 -673
- agno/storage/firestore.py +0 -297
- agno/storage/gcs_json.py +0 -261
- agno/storage/in_memory.py +0 -234
- agno/storage/json.py +0 -237
- agno/storage/mongodb.py +0 -328
- agno/storage/mysql.py +0 -685
- agno/storage/postgres.py +0 -682
- agno/storage/redis.py +0 -336
- agno/storage/session/__init__.py +0 -16
- agno/storage/session/agent.py +0 -64
- agno/storage/session/team.py +0 -63
- agno/storage/session/v2/__init__.py +0 -5
- agno/storage/session/workflow.py +0 -61
- agno/storage/singlestore.py +0 -606
- agno/storage/sqlite.py +0 -646
- agno/storage/workflow/__init__.py +0 -0
- agno/storage/workflow/mongodb.py +0 -1
- agno/storage/workflow/postgres.py +0 -1
- agno/storage/workflow/sqlite.py +0 -1
- agno/storage/yaml.py +0 -241
- agno/tools/thinking.py +0 -73
- agno/utils/defaults.py +0 -57
- agno/utils/filesystem.py +0 -39
- agno/utils/git.py +0 -52
- agno/utils/json_io.py +0 -30
- agno/utils/load_env.py +0 -19
- agno/utils/py_io.py +0 -19
- agno/utils/pyproject.py +0 -18
- agno/utils/resource_filter.py +0 -31
- agno/workflow/v2/__init__.py +0 -21
- agno/workflow/v2/types.py +0 -357
- agno/workflow/v2/workflow.py +0 -3312
- agno/workspace/__init__.py +0 -0
- agno/workspace/config.py +0 -325
- agno/workspace/enums.py +0 -6
- agno/workspace/helpers.py +0 -52
- agno/workspace/operator.py +0 -757
- agno/workspace/settings.py +0 -158
- agno-1.8.0.dist-info/METADATA +0 -979
- agno-1.8.0.dist-info/RECORD +0 -565
- agno-1.8.0.dist-info/entry_points.txt +0 -3
- /agno/{app → db/migrations}/__init__.py +0 -0
- /agno/{app/playground/__init__.py → db/schemas/metrics.py} +0 -0
- /agno/{cli → integrations}/__init__.py +0 -0
- /agno/{cli/ws → knowledge/chunking}/__init__.py +0 -0
- /agno/{document/chunking → knowledge/remote_content}/__init__.py +0 -0
- /agno/{document/reader/gcs → knowledge/reranker}/__init__.py +0 -0
- /agno/{document/reader/s3 → os/interfaces}/__init__.py +0 -0
- /agno/{app → os/interfaces}/slack/security.py +0 -0
- /agno/{app → os/interfaces}/whatsapp/security.py +0 -0
- /agno/{file/local → utils/print_response}/__init__.py +0 -0
- /agno/{infra → vectordb/llamaindex}/__init__.py +0 -0
- {agno-1.8.0.dist-info → agno-2.0.0a1.dist-info}/WHEEL +0 -0
- {agno-1.8.0.dist-info → agno-2.0.0a1.dist-info}/licenses/LICENSE +0 -0
- {agno-1.8.0.dist-info → agno-2.0.0a1.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
from abc import ABC, abstractmethod
|
|
2
|
+
from enum import Enum
|
|
3
|
+
from typing import List
|
|
4
|
+
|
|
5
|
+
from agno.knowledge.document.base import Document
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class ChunkingStrategy(ABC):
|
|
9
|
+
"""Base class for chunking strategies"""
|
|
10
|
+
|
|
11
|
+
@abstractmethod
|
|
12
|
+
def chunk(self, document: Document) -> List[Document]:
|
|
13
|
+
raise NotImplementedError
|
|
14
|
+
|
|
15
|
+
def clean_text(self, text: str) -> str:
|
|
16
|
+
"""Clean the text by replacing multiple newlines with a single newline"""
|
|
17
|
+
import re
|
|
18
|
+
|
|
19
|
+
# Replace multiple newlines with a single newline
|
|
20
|
+
cleaned_text = re.sub(r"\n+", "\n", text)
|
|
21
|
+
# Replace multiple spaces with a single space
|
|
22
|
+
cleaned_text = re.sub(r"\s+", " ", cleaned_text)
|
|
23
|
+
# Replace multiple tabs with a single tab
|
|
24
|
+
cleaned_text = re.sub(r"\t+", "\t", cleaned_text)
|
|
25
|
+
# Replace multiple carriage returns with a single carriage return
|
|
26
|
+
cleaned_text = re.sub(r"\r+", "\r", cleaned_text)
|
|
27
|
+
# Replace multiple form feeds with a single form feed
|
|
28
|
+
cleaned_text = re.sub(r"\f+", "\f", cleaned_text)
|
|
29
|
+
# Replace multiple vertical tabs with a single vertical tab
|
|
30
|
+
cleaned_text = re.sub(r"\v+", "\v", cleaned_text)
|
|
31
|
+
|
|
32
|
+
return cleaned_text
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class ChunkingStrategyType(str, Enum):
|
|
36
|
+
"""Enumeration of available chunking strategies."""
|
|
37
|
+
|
|
38
|
+
AGENTIC_CHUNKING = "AgenticChunking"
|
|
39
|
+
DOCUMENT_CHUNKING = "DocumentChunking"
|
|
40
|
+
RECURSIVE_CHUNKING = "RecursiveChunking"
|
|
41
|
+
SEMANTIC_CHUNKING = "SemanticChunking"
|
|
42
|
+
FIXED_SIZE_CHUNKING = "FixedSizeChunking"
|
|
43
|
+
ROW_CHUNKING = "RowChunking"
|
|
44
|
+
MARKDOWN_CHUNKING = "MarkdownChunking"
|
|
45
|
+
|
|
46
|
+
@classmethod
|
|
47
|
+
def from_string(cls, strategy_name: str) -> "ChunkingStrategyType":
|
|
48
|
+
"""Convert a string to a ChunkingStrategyType."""
|
|
49
|
+
strategy_name_clean = strategy_name.strip()
|
|
50
|
+
|
|
51
|
+
# Try exact enum value match first
|
|
52
|
+
for enum_member in cls:
|
|
53
|
+
if enum_member.value == strategy_name_clean:
|
|
54
|
+
return enum_member
|
|
55
|
+
|
|
56
|
+
raise ValueError(f"Unsupported chunking strategy: {strategy_name}. Valid options: {[e.value for e in cls]}")
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class ChunkingStrategyFactory:
|
|
60
|
+
"""Factory for creating chunking strategy instances."""
|
|
61
|
+
|
|
62
|
+
@classmethod
|
|
63
|
+
def create_strategy(cls, strategy_type: ChunkingStrategyType, **kwargs) -> ChunkingStrategy:
|
|
64
|
+
"""Create an instance of the chunking strategy with the given parameters."""
|
|
65
|
+
strategy_map = {
|
|
66
|
+
ChunkingStrategyType.AGENTIC_CHUNKING: cls._create_agentic_chunking,
|
|
67
|
+
ChunkingStrategyType.DOCUMENT_CHUNKING: cls._create_document_chunking,
|
|
68
|
+
ChunkingStrategyType.RECURSIVE_CHUNKING: cls._create_recursive_chunking,
|
|
69
|
+
ChunkingStrategyType.SEMANTIC_CHUNKING: cls._create_semantic_chunking,
|
|
70
|
+
ChunkingStrategyType.FIXED_SIZE_CHUNKING: cls._create_fixed_chunking,
|
|
71
|
+
ChunkingStrategyType.ROW_CHUNKING: cls._create_row_chunking,
|
|
72
|
+
ChunkingStrategyType.MARKDOWN_CHUNKING: cls._create_markdown_chunking,
|
|
73
|
+
}
|
|
74
|
+
return strategy_map[strategy_type](**kwargs)
|
|
75
|
+
|
|
76
|
+
@classmethod
|
|
77
|
+
def _create_agentic_chunking(cls, **kwargs) -> ChunkingStrategy:
|
|
78
|
+
from agno.knowledge.chunking.agentic import AgenticChunking
|
|
79
|
+
|
|
80
|
+
# Map chunk_size to max_chunk_size for AgenticChunking
|
|
81
|
+
if "chunk_size" in kwargs and "max_chunk_size" not in kwargs:
|
|
82
|
+
kwargs["max_chunk_size"] = kwargs.pop("chunk_size")
|
|
83
|
+
return AgenticChunking(**kwargs)
|
|
84
|
+
|
|
85
|
+
@classmethod
|
|
86
|
+
def _create_document_chunking(cls, **kwargs) -> ChunkingStrategy:
|
|
87
|
+
from agno.knowledge.chunking.document import DocumentChunking
|
|
88
|
+
|
|
89
|
+
return DocumentChunking(**kwargs)
|
|
90
|
+
|
|
91
|
+
@classmethod
|
|
92
|
+
def _create_recursive_chunking(cls, **kwargs) -> ChunkingStrategy:
|
|
93
|
+
from agno.knowledge.chunking.recursive import RecursiveChunking
|
|
94
|
+
|
|
95
|
+
return RecursiveChunking(**kwargs)
|
|
96
|
+
|
|
97
|
+
@classmethod
|
|
98
|
+
def _create_semantic_chunking(cls, **kwargs) -> ChunkingStrategy:
|
|
99
|
+
from agno.knowledge.chunking.semantic import SemanticChunking
|
|
100
|
+
|
|
101
|
+
return SemanticChunking(**kwargs)
|
|
102
|
+
|
|
103
|
+
@classmethod
|
|
104
|
+
def _create_fixed_chunking(cls, **kwargs) -> ChunkingStrategy:
|
|
105
|
+
from agno.knowledge.chunking.fixed import FixedSizeChunking
|
|
106
|
+
|
|
107
|
+
return FixedSizeChunking(**kwargs)
|
|
108
|
+
|
|
109
|
+
@classmethod
|
|
110
|
+
def _create_row_chunking(cls, **kwargs) -> ChunkingStrategy:
|
|
111
|
+
from agno.knowledge.chunking.row import RowChunking
|
|
112
|
+
|
|
113
|
+
# Remove chunk_size if present since RowChunking doesn't use it
|
|
114
|
+
kwargs.pop("chunk_size", None)
|
|
115
|
+
return RowChunking(**kwargs)
|
|
116
|
+
|
|
117
|
+
@classmethod
|
|
118
|
+
def _create_markdown_chunking(cls, **kwargs) -> ChunkingStrategy:
|
|
119
|
+
from agno.knowledge.chunking.markdown import MarkdownChunking
|
|
120
|
+
|
|
121
|
+
return MarkdownChunking(**kwargs)
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from enum import Enum
|
|
3
|
+
from typing import Any, Dict, List, Optional, Union
|
|
4
|
+
|
|
5
|
+
from agno.knowledge.reader import Reader
|
|
6
|
+
from agno.knowledge.remote_content.remote_content import RemoteContent
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class ContentStatus(str, Enum):
|
|
10
|
+
"""Enumeration of possible content processing statuses."""
|
|
11
|
+
|
|
12
|
+
PROCESSING = "processing"
|
|
13
|
+
COMPLETED = "completed"
|
|
14
|
+
FAILED = "failed"
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@dataclass
|
|
18
|
+
class FileData:
|
|
19
|
+
content: Optional[Union[str, bytes]] = None
|
|
20
|
+
type: Optional[str] = None
|
|
21
|
+
filename: Optional[str] = None
|
|
22
|
+
size: Optional[int] = None
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
@dataclass
|
|
26
|
+
class ContentAuth:
|
|
27
|
+
password: Optional[str] = None
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@dataclass
|
|
31
|
+
class Content:
|
|
32
|
+
id: Optional[str] = None
|
|
33
|
+
name: Optional[str] = None
|
|
34
|
+
description: Optional[str] = None
|
|
35
|
+
path: Optional[str] = None
|
|
36
|
+
url: Optional[str] = None
|
|
37
|
+
auth: Optional[ContentAuth] = None
|
|
38
|
+
file_data: Optional[FileData] = None
|
|
39
|
+
metadata: Optional[Dict[str, Any]] = None
|
|
40
|
+
topics: Optional[List[str]] = None
|
|
41
|
+
remote_content: Optional[RemoteContent] = None
|
|
42
|
+
reader: Optional[Reader] = None
|
|
43
|
+
size: Optional[int] = None
|
|
44
|
+
file_type: Optional[str] = None
|
|
45
|
+
content_hash: Optional[str] = None
|
|
46
|
+
status: Optional[ContentStatus] = None
|
|
47
|
+
status_message: Optional[str] = None
|
|
48
|
+
created_at: Optional[int] = None
|
|
49
|
+
updated_at: Optional[int] = None
|
|
50
|
+
external_id: Optional[str] = None
|
|
51
|
+
|
|
52
|
+
@classmethod
|
|
53
|
+
def from_dict(cls, data: Dict[str, Any]) -> "Content":
|
|
54
|
+
return cls(
|
|
55
|
+
id=data.get("id"),
|
|
56
|
+
name=data.get("name"),
|
|
57
|
+
description=data.get("description"),
|
|
58
|
+
path=data.get("path"),
|
|
59
|
+
url=data.get("url"),
|
|
60
|
+
auth=data.get("auth"),
|
|
61
|
+
file_data=data.get("file_data"),
|
|
62
|
+
metadata=data.get("metadata"),
|
|
63
|
+
topics=data.get("topics"),
|
|
64
|
+
remote_content=data.get("remote_content"),
|
|
65
|
+
reader=data.get("reader"),
|
|
66
|
+
size=data.get("size"),
|
|
67
|
+
file_type=data.get("file_type"),
|
|
68
|
+
content_hash=data.get("content_hash"),
|
|
69
|
+
status=data.get("status"),
|
|
70
|
+
status_message=data.get("status_message"),
|
|
71
|
+
created_at=data.get("created_at"),
|
|
72
|
+
updated_at=data.get("updated_at"),
|
|
73
|
+
external_id=data.get("external_id"),
|
|
74
|
+
)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from dataclasses import dataclass, field
|
|
2
2
|
from typing import Any, Dict, List, Optional
|
|
3
3
|
|
|
4
|
-
from agno.embedder import Embedder
|
|
4
|
+
from agno.knowledge.embedder import Embedder
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
@dataclass
|
|
@@ -12,10 +12,13 @@ class Document:
|
|
|
12
12
|
id: Optional[str] = None
|
|
13
13
|
name: Optional[str] = None
|
|
14
14
|
meta_data: Dict[str, Any] = field(default_factory=dict)
|
|
15
|
-
embedder: Optional[Embedder] = None
|
|
15
|
+
embedder: Optional["Embedder"] = None
|
|
16
16
|
embedding: Optional[List[float]] = None
|
|
17
17
|
usage: Optional[Dict[str, Any]] = None
|
|
18
18
|
reranking_score: Optional[float] = None
|
|
19
|
+
content_id: Optional[str] = None
|
|
20
|
+
content_origin: Optional[str] = None
|
|
21
|
+
size: Optional[int] = None
|
|
19
22
|
|
|
20
23
|
def embed(self, embedder: Optional[Embedder] = None) -> None:
|
|
21
24
|
"""Embed the document using the provided embedder"""
|
|
@@ -26,6 +29,13 @@ class Document:
|
|
|
26
29
|
|
|
27
30
|
self.embedding, self.usage = _embedder.get_embedding_and_usage(self.content)
|
|
28
31
|
|
|
32
|
+
async def async_embed(self, embedder: Optional[Embedder] = None) -> None:
|
|
33
|
+
"""Embed the document using the provided embedder"""
|
|
34
|
+
_embedder = embedder or self.embedder
|
|
35
|
+
if _embedder is None:
|
|
36
|
+
raise ValueError("No embedder provided")
|
|
37
|
+
self.embedding, self.usage = await _embedder.async_get_embedding_and_usage(self.content)
|
|
38
|
+
|
|
29
39
|
def to_dict(self) -> Dict[str, Any]:
|
|
30
40
|
"""Returns a dictionary representation of the document"""
|
|
31
41
|
fields = {"name", "meta_data", "content"}
|
|
@@ -3,8 +3,8 @@ from dataclasses import dataclass
|
|
|
3
3
|
from os import getenv
|
|
4
4
|
from typing import Any, Dict, List, Optional, Tuple
|
|
5
5
|
|
|
6
|
-
from agno.embedder.base import Embedder
|
|
7
6
|
from agno.exceptions import AgnoError, ModelProviderError
|
|
7
|
+
from agno.knowledge.embedder.base import Embedder
|
|
8
8
|
from agno.utils.log import log_error, logger
|
|
9
9
|
|
|
10
10
|
try:
|
|
@@ -15,6 +15,14 @@ except ImportError:
|
|
|
15
15
|
log_error("`boto3` not installed. Please install it via `pip install boto3`.")
|
|
16
16
|
raise
|
|
17
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
|
+
|
|
18
26
|
|
|
19
27
|
@dataclass
|
|
20
28
|
class AwsBedrockEmbedder(Embedder):
|
|
@@ -94,6 +102,46 @@ class AwsBedrockEmbedder(Embedder):
|
|
|
94
102
|
)
|
|
95
103
|
return self.client
|
|
96
104
|
|
|
105
|
+
def get_async_client(self):
|
|
106
|
+
"""
|
|
107
|
+
Returns an async AWS Bedrock client using aioboto3.
|
|
108
|
+
|
|
109
|
+
Returns:
|
|
110
|
+
An aioboto3 bedrock-runtime client context manager.
|
|
111
|
+
"""
|
|
112
|
+
if aioboto3 is None:
|
|
113
|
+
raise AgnoError(
|
|
114
|
+
message="aioboto3 not installed. Please install it via `pip install aioboto3`.",
|
|
115
|
+
status_code=400,
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
if self.session:
|
|
119
|
+
# Convert boto3 session to aioboto3 session
|
|
120
|
+
aio_session = aioboto3.Session(
|
|
121
|
+
aws_access_key_id=self.session.get_credentials().access_key,
|
|
122
|
+
aws_secret_access_key=self.session.get_credentials().secret_key,
|
|
123
|
+
aws_session_token=self.session.get_credentials().token,
|
|
124
|
+
region_name=self.session.region_name,
|
|
125
|
+
)
|
|
126
|
+
else:
|
|
127
|
+
self.aws_access_key_id = self.aws_access_key_id or getenv("AWS_ACCESS_KEY_ID")
|
|
128
|
+
self.aws_secret_access_key = self.aws_secret_access_key or getenv("AWS_SECRET_ACCESS_KEY")
|
|
129
|
+
self.aws_region = self.aws_region or getenv("AWS_REGION")
|
|
130
|
+
|
|
131
|
+
if not self.aws_access_key_id or not self.aws_secret_access_key:
|
|
132
|
+
raise AgnoError(
|
|
133
|
+
message="AWS credentials not found. Please set AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables or provide a boto3 session.",
|
|
134
|
+
status_code=400,
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
aio_session = aioboto3.Session(
|
|
138
|
+
aws_access_key_id=self.aws_access_key_id,
|
|
139
|
+
aws_secret_access_key=self.aws_secret_access_key,
|
|
140
|
+
region_name=self.aws_region,
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
return aio_session.client("bedrock-runtime", **(self.client_params or {}))
|
|
144
|
+
|
|
97
145
|
def _format_request_body(self, text: str) -> str:
|
|
98
146
|
"""
|
|
99
147
|
Format the request body for the embedder.
|
|
@@ -210,3 +258,81 @@ class AwsBedrockEmbedder(Embedder):
|
|
|
210
258
|
usage = response["usage"]
|
|
211
259
|
|
|
212
260
|
return embedding, usage
|
|
261
|
+
|
|
262
|
+
async def async_get_embedding(self, text: str) -> List[float]:
|
|
263
|
+
"""
|
|
264
|
+
Async version of get_embedding() using native aioboto3 async client.
|
|
265
|
+
"""
|
|
266
|
+
try:
|
|
267
|
+
body = self._format_request_body(text)
|
|
268
|
+
async with self.get_async_client() as client:
|
|
269
|
+
response = await client.invoke_model(
|
|
270
|
+
modelId=self.id,
|
|
271
|
+
body=body,
|
|
272
|
+
contentType="application/json",
|
|
273
|
+
accept="application/json",
|
|
274
|
+
)
|
|
275
|
+
response_body = json.loads(response["body"].read().decode("utf-8"))
|
|
276
|
+
|
|
277
|
+
# Extract embeddings using the same logic as get_embedding
|
|
278
|
+
if "embeddings" in response_body:
|
|
279
|
+
if isinstance(response_body["embeddings"], list):
|
|
280
|
+
# Default 'float' embeddings response format
|
|
281
|
+
return response_body["embeddings"][0]
|
|
282
|
+
elif isinstance(response_body["embeddings"], dict):
|
|
283
|
+
# If embeddings_types parameter was used, select float embeddings
|
|
284
|
+
if "float" in response_body["embeddings"]:
|
|
285
|
+
return response_body["embeddings"]["float"][0]
|
|
286
|
+
# Fallback to the first available embedding type
|
|
287
|
+
for embedding_type in response_body["embeddings"]:
|
|
288
|
+
return response_body["embeddings"][embedding_type][0]
|
|
289
|
+
logger.warning("No embeddings found in response")
|
|
290
|
+
return []
|
|
291
|
+
except ClientError as e:
|
|
292
|
+
log_error(f"Unexpected error calling Bedrock API: {str(e)}")
|
|
293
|
+
raise ModelProviderError(message=str(e.response), model_name="AwsBedrockEmbedder", model_id=self.id) from e
|
|
294
|
+
except Exception as e:
|
|
295
|
+
log_error(f"Unexpected error calling Bedrock API: {str(e)}")
|
|
296
|
+
raise ModelProviderError(message=str(e), model_name="AwsBedrockEmbedder", model_id=self.id) from e
|
|
297
|
+
|
|
298
|
+
async def async_get_embedding_and_usage(self, text: str) -> Tuple[List[float], Optional[Dict[str, Any]]]:
|
|
299
|
+
"""
|
|
300
|
+
Async version of get_embedding_and_usage() using native aioboto3 async client.
|
|
301
|
+
"""
|
|
302
|
+
try:
|
|
303
|
+
body = self._format_request_body(text)
|
|
304
|
+
async with self.get_async_client() as client:
|
|
305
|
+
response = await client.invoke_model(
|
|
306
|
+
modelId=self.id,
|
|
307
|
+
body=body,
|
|
308
|
+
contentType="application/json",
|
|
309
|
+
accept="application/json",
|
|
310
|
+
)
|
|
311
|
+
response_body = json.loads(response["body"].read().decode("utf-8"))
|
|
312
|
+
|
|
313
|
+
embedding: List[float] = []
|
|
314
|
+
# Extract embeddings using the same logic as get_embedding_and_usage
|
|
315
|
+
if "embeddings" in response_body:
|
|
316
|
+
if isinstance(response_body["embeddings"], list):
|
|
317
|
+
embedding = response_body["embeddings"][0]
|
|
318
|
+
elif isinstance(response_body["embeddings"], dict):
|
|
319
|
+
if "float" in response_body["embeddings"]:
|
|
320
|
+
embedding = response_body["embeddings"]["float"][0]
|
|
321
|
+
# Fallback to the first available embedding type
|
|
322
|
+
else:
|
|
323
|
+
for embedding_type in response_body["embeddings"]:
|
|
324
|
+
embedding = response_body["embeddings"][embedding_type][0]
|
|
325
|
+
break
|
|
326
|
+
|
|
327
|
+
# Extract usage metrics if available
|
|
328
|
+
usage = None
|
|
329
|
+
if "usage" in response_body:
|
|
330
|
+
usage = response_body["usage"]
|
|
331
|
+
|
|
332
|
+
return embedding, usage
|
|
333
|
+
except ClientError as e:
|
|
334
|
+
log_error(f"Unexpected error calling Bedrock API: {str(e)}")
|
|
335
|
+
raise ModelProviderError(message=str(e.response), model_name="AwsBedrockEmbedder", model_id=self.id) from e
|
|
336
|
+
except Exception as e:
|
|
337
|
+
log_error(f"Unexpected error calling Bedrock API: {str(e)}")
|
|
338
|
+
raise ModelProviderError(message=str(e), model_name="AwsBedrockEmbedder", model_id=self.id) from e
|
|
@@ -4,10 +4,11 @@ from typing import Any, Dict, List, Optional, Tuple
|
|
|
4
4
|
|
|
5
5
|
from typing_extensions import Literal
|
|
6
6
|
|
|
7
|
-
from agno.embedder.base import Embedder
|
|
7
|
+
from agno.knowledge.embedder.base import Embedder
|
|
8
8
|
from agno.utils.log import logger
|
|
9
9
|
|
|
10
10
|
try:
|
|
11
|
+
from openai import AsyncAzureOpenAI as AsyncAzureOpenAIClient
|
|
11
12
|
from openai import AzureOpenAI as AzureOpenAIClient
|
|
12
13
|
from openai.types.create_embedding_response import CreateEmbeddingResponse
|
|
13
14
|
except ImportError:
|
|
@@ -32,6 +33,7 @@ class AzureOpenAIEmbedder(Embedder):
|
|
|
32
33
|
request_params: Optional[Dict[str, Any]] = None
|
|
33
34
|
client_params: Optional[Dict[str, Any]] = None
|
|
34
35
|
openai_client: Optional[AzureOpenAIClient] = None
|
|
36
|
+
async_client: Optional[AsyncAzureOpenAIClient] = None
|
|
35
37
|
|
|
36
38
|
@property
|
|
37
39
|
def client(self) -> AzureOpenAIClient:
|
|
@@ -61,6 +63,35 @@ class AzureOpenAIEmbedder(Embedder):
|
|
|
61
63
|
|
|
62
64
|
return AzureOpenAIClient(**_client_params)
|
|
63
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
|
+
|
|
64
95
|
def _response(self, text: str) -> CreateEmbeddingResponse:
|
|
65
96
|
_request_params: Dict[str, Any] = {
|
|
66
97
|
"input": text,
|
|
@@ -90,3 +121,36 @@ class AzureOpenAIEmbedder(Embedder):
|
|
|
90
121
|
embedding = response.data[0].embedding
|
|
91
122
|
usage = response.usage
|
|
92
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()
|
|
@@ -13,3 +13,9 @@ class Embedder:
|
|
|
13
13
|
|
|
14
14
|
def get_embedding_and_usage(self, text: str) -> Tuple[List[float], Optional[Dict]]:
|
|
15
15
|
raise NotImplementedError
|
|
16
|
+
|
|
17
|
+
async def async_get_embedding(self, text: str) -> List[float]:
|
|
18
|
+
raise NotImplementedError
|
|
19
|
+
|
|
20
|
+
async def async_get_embedding_and_usage(self, text: str) -> Tuple[List[float], Optional[Dict]]:
|
|
21
|
+
raise NotImplementedError
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
from dataclasses import dataclass
|
|
2
2
|
from typing import Any, Dict, List, Optional, Tuple, Union
|
|
3
3
|
|
|
4
|
-
from agno.embedder.base import Embedder
|
|
4
|
+
from agno.knowledge.embedder.base import Embedder
|
|
5
5
|
from agno.utils.log import logger
|
|
6
6
|
|
|
7
7
|
try:
|
|
8
|
+
from cohere import AsyncClient as AsyncCohereClient
|
|
8
9
|
from cohere import Client as CohereClient
|
|
9
10
|
from cohere.types.embed_response import EmbeddingsByTypeEmbedResponse, EmbeddingsFloatsEmbedResponse
|
|
10
11
|
except ImportError:
|
|
@@ -20,6 +21,7 @@ class CohereEmbedder(Embedder):
|
|
|
20
21
|
request_params: Optional[Dict[str, Any]] = None
|
|
21
22
|
client_params: Optional[Dict[str, Any]] = None
|
|
22
23
|
cohere_client: Optional[CohereClient] = None
|
|
24
|
+
async_client: Optional[AsyncCohereClient] = None
|
|
23
25
|
|
|
24
26
|
@property
|
|
25
27
|
def client(self) -> CohereClient:
|
|
@@ -28,9 +30,24 @@ class CohereEmbedder(Embedder):
|
|
|
28
30
|
client_params: Dict[str, Any] = {}
|
|
29
31
|
if self.api_key:
|
|
30
32
|
client_params["api_key"] = self.api_key
|
|
33
|
+
if self.client_params:
|
|
34
|
+
client_params.update(self.client_params)
|
|
31
35
|
self.cohere_client = CohereClient(**client_params)
|
|
32
36
|
return self.cohere_client
|
|
33
37
|
|
|
38
|
+
@property
|
|
39
|
+
def aclient(self) -> AsyncCohereClient:
|
|
40
|
+
"""Lazy init for Cohere async client."""
|
|
41
|
+
if self.async_client:
|
|
42
|
+
return self.async_client
|
|
43
|
+
params: Dict[str, Any] = {}
|
|
44
|
+
if self.api_key:
|
|
45
|
+
params["api_key"] = self.api_key
|
|
46
|
+
if self.client_params:
|
|
47
|
+
params.update(self.client_params)
|
|
48
|
+
self.async_client = AsyncCohereClient(**params)
|
|
49
|
+
return self.async_client
|
|
50
|
+
|
|
34
51
|
def response(self, text: str) -> Union[EmbeddingsFloatsEmbedResponse, EmbeddingsByTypeEmbedResponse]:
|
|
35
52
|
request_params: Dict[str, Any] = {}
|
|
36
53
|
|
|
@@ -71,3 +88,57 @@ class CohereEmbedder(Embedder):
|
|
|
71
88
|
if usage:
|
|
72
89
|
return embedding, usage.model_dump()
|
|
73
90
|
return embedding, None
|
|
91
|
+
|
|
92
|
+
async def async_get_embedding(self, text: str) -> List[float]:
|
|
93
|
+
request_params: Dict[str, Any] = {}
|
|
94
|
+
|
|
95
|
+
if self.id:
|
|
96
|
+
request_params["model"] = self.id
|
|
97
|
+
if self.input_type:
|
|
98
|
+
request_params["input_type"] = self.input_type
|
|
99
|
+
if self.embedding_types:
|
|
100
|
+
request_params["embedding_types"] = self.embedding_types
|
|
101
|
+
if self.request_params:
|
|
102
|
+
request_params.update(self.request_params)
|
|
103
|
+
|
|
104
|
+
try:
|
|
105
|
+
response: Union[EmbeddingsFloatsEmbedResponse, EmbeddingsByTypeEmbedResponse] = await self.aclient.embed(
|
|
106
|
+
texts=[text], **request_params
|
|
107
|
+
)
|
|
108
|
+
if isinstance(response, EmbeddingsFloatsEmbedResponse):
|
|
109
|
+
return response.embeddings[0]
|
|
110
|
+
elif isinstance(response, EmbeddingsByTypeEmbedResponse):
|
|
111
|
+
return response.embeddings.float_[0] if response.embeddings.float_ else []
|
|
112
|
+
else:
|
|
113
|
+
logger.warning("No embeddings found")
|
|
114
|
+
return []
|
|
115
|
+
except Exception as e:
|
|
116
|
+
logger.warning(e)
|
|
117
|
+
return []
|
|
118
|
+
|
|
119
|
+
async def async_get_embedding_and_usage(self, text: str) -> Tuple[List[float], Optional[Dict[str, Any]]]:
|
|
120
|
+
request_params: Dict[str, Any] = {}
|
|
121
|
+
|
|
122
|
+
if self.id:
|
|
123
|
+
request_params["model"] = self.id
|
|
124
|
+
if self.input_type:
|
|
125
|
+
request_params["input_type"] = self.input_type
|
|
126
|
+
if self.embedding_types:
|
|
127
|
+
request_params["embedding_types"] = self.embedding_types
|
|
128
|
+
if self.request_params:
|
|
129
|
+
request_params.update(self.request_params)
|
|
130
|
+
|
|
131
|
+
response: Union[EmbeddingsFloatsEmbedResponse, EmbeddingsByTypeEmbedResponse] = await self.aclient.embed(
|
|
132
|
+
texts=[text], **request_params
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
embedding: List[float] = []
|
|
136
|
+
if isinstance(response, EmbeddingsFloatsEmbedResponse):
|
|
137
|
+
embedding = response.embeddings[0]
|
|
138
|
+
elif isinstance(response, EmbeddingsByTypeEmbedResponse):
|
|
139
|
+
embedding = response.embeddings.float_[0] if response.embeddings.float_ else []
|
|
140
|
+
|
|
141
|
+
usage = response.meta.billed_units if response.meta else None
|
|
142
|
+
if usage:
|
|
143
|
+
return embedding, usage.model_dump()
|
|
144
|
+
return embedding, None
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from dataclasses import dataclass
|
|
2
2
|
from typing import Dict, List, Optional, Tuple
|
|
3
3
|
|
|
4
|
-
from agno.embedder.base import Embedder
|
|
4
|
+
from agno.knowledge.embedder.base import Embedder
|
|
5
5
|
from agno.utils.log import logger
|
|
6
6
|
|
|
7
7
|
try:
|
|
@@ -44,3 +44,19 @@ class FastEmbedEmbedder(Embedder):
|
|
|
44
44
|
usage = None
|
|
45
45
|
|
|
46
46
|
return embedding, usage
|
|
47
|
+
|
|
48
|
+
async def async_get_embedding(self, text: str) -> List[float]:
|
|
49
|
+
"""Async version using thread executor for CPU-bound operations."""
|
|
50
|
+
import asyncio
|
|
51
|
+
|
|
52
|
+
loop = asyncio.get_event_loop()
|
|
53
|
+
# Run the CPU-bound operation in a thread executor
|
|
54
|
+
return await loop.run_in_executor(None, self.get_embedding, text)
|
|
55
|
+
|
|
56
|
+
async def async_get_embedding_and_usage(self, text: str) -> Tuple[List[float], Optional[Dict]]:
|
|
57
|
+
"""Async version using thread executor for CPU-bound operations."""
|
|
58
|
+
import asyncio
|
|
59
|
+
|
|
60
|
+
loop = asyncio.get_event_loop()
|
|
61
|
+
# Run the CPU-bound operation in a thread executor
|
|
62
|
+
return await loop.run_in_executor(None, self.get_embedding_and_usage, text)
|