agno 1.8.2__py3-none-any.whl → 2.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- agno/agent/__init__.py +19 -27
- agno/agent/agent.py +3143 -4170
- agno/api/agent.py +11 -67
- agno/api/api.py +5 -46
- agno/api/evals.py +8 -19
- agno/api/os.py +17 -0
- agno/api/routes.py +6 -41
- agno/api/schemas/__init__.py +9 -0
- agno/api/schemas/agent.py +5 -21
- agno/api/schemas/evals.py +7 -16
- agno/api/schemas/os.py +14 -0
- agno/api/schemas/team.py +5 -21
- agno/api/schemas/utils.py +21 -0
- agno/api/schemas/workflows.py +11 -7
- agno/api/settings.py +53 -0
- agno/api/team.py +11 -66
- agno/api/workflow.py +28 -0
- agno/cloud/aws/base.py +214 -0
- agno/cloud/aws/s3/__init__.py +2 -0
- agno/cloud/aws/s3/api_client.py +43 -0
- agno/cloud/aws/s3/bucket.py +195 -0
- agno/cloud/aws/s3/object.py +57 -0
- agno/db/__init__.py +24 -0
- agno/db/base.py +245 -0
- agno/db/dynamo/__init__.py +3 -0
- agno/db/dynamo/dynamo.py +1743 -0
- agno/db/dynamo/schemas.py +278 -0
- agno/db/dynamo/utils.py +684 -0
- agno/db/firestore/__init__.py +3 -0
- agno/db/firestore/firestore.py +1432 -0
- agno/db/firestore/schemas.py +130 -0
- agno/db/firestore/utils.py +278 -0
- agno/db/gcs_json/__init__.py +3 -0
- agno/db/gcs_json/gcs_json_db.py +1001 -0
- agno/db/gcs_json/utils.py +194 -0
- agno/db/in_memory/__init__.py +3 -0
- agno/db/in_memory/in_memory_db.py +882 -0
- agno/db/in_memory/utils.py +172 -0
- agno/db/json/__init__.py +3 -0
- agno/db/json/json_db.py +1045 -0
- agno/db/json/utils.py +196 -0
- agno/db/migrations/v1_to_v2.py +162 -0
- agno/db/mongo/__init__.py +3 -0
- agno/db/mongo/mongo.py +1416 -0
- agno/db/mongo/schemas.py +77 -0
- agno/db/mongo/utils.py +204 -0
- agno/db/mysql/__init__.py +3 -0
- agno/db/mysql/mysql.py +1719 -0
- agno/db/mysql/schemas.py +124 -0
- agno/db/mysql/utils.py +297 -0
- agno/db/postgres/__init__.py +3 -0
- agno/db/postgres/postgres.py +1710 -0
- agno/db/postgres/schemas.py +124 -0
- agno/db/postgres/utils.py +280 -0
- agno/db/redis/__init__.py +3 -0
- agno/db/redis/redis.py +1367 -0
- agno/db/redis/schemas.py +109 -0
- agno/db/redis/utils.py +288 -0
- agno/db/schemas/__init__.py +3 -0
- agno/db/schemas/evals.py +33 -0
- agno/db/schemas/knowledge.py +40 -0
- agno/db/schemas/memory.py +46 -0
- agno/db/singlestore/__init__.py +3 -0
- agno/db/singlestore/schemas.py +116 -0
- agno/db/singlestore/singlestore.py +1712 -0
- agno/db/singlestore/utils.py +326 -0
- agno/db/sqlite/__init__.py +3 -0
- agno/db/sqlite/schemas.py +119 -0
- agno/db/sqlite/sqlite.py +1676 -0
- agno/db/sqlite/utils.py +268 -0
- agno/db/utils.py +88 -0
- agno/eval/__init__.py +14 -0
- agno/eval/accuracy.py +154 -48
- agno/eval/performance.py +88 -23
- agno/eval/reliability.py +73 -20
- agno/eval/utils.py +23 -13
- agno/integrations/discord/__init__.py +3 -0
- agno/{app → integrations}/discord/client.py +10 -10
- agno/knowledge/__init__.py +2 -2
- agno/{document → knowledge}/chunking/agentic.py +2 -2
- agno/{document → knowledge}/chunking/document.py +2 -2
- agno/{document → knowledge}/chunking/fixed.py +3 -3
- agno/{document → knowledge}/chunking/markdown.py +2 -2
- agno/{document → knowledge}/chunking/recursive.py +2 -2
- agno/{document → knowledge}/chunking/row.py +2 -2
- agno/knowledge/chunking/semantic.py +59 -0
- agno/knowledge/chunking/strategy.py +121 -0
- agno/knowledge/content.py +74 -0
- agno/knowledge/document/__init__.py +5 -0
- agno/{document → knowledge/document}/base.py +12 -2
- agno/knowledge/embedder/__init__.py +5 -0
- agno/{embedder → knowledge/embedder}/aws_bedrock.py +127 -1
- agno/{embedder → knowledge/embedder}/azure_openai.py +65 -1
- agno/{embedder → knowledge/embedder}/base.py +6 -0
- agno/{embedder → knowledge/embedder}/cohere.py +72 -1
- agno/{embedder → knowledge/embedder}/fastembed.py +17 -1
- agno/{embedder → knowledge/embedder}/fireworks.py +1 -1
- agno/{embedder → knowledge/embedder}/google.py +74 -1
- agno/{embedder → knowledge/embedder}/huggingface.py +36 -2
- agno/{embedder → knowledge/embedder}/jina.py +48 -2
- agno/knowledge/embedder/langdb.py +22 -0
- agno/knowledge/embedder/mistral.py +139 -0
- agno/{embedder → knowledge/embedder}/nebius.py +1 -1
- agno/{embedder → knowledge/embedder}/ollama.py +54 -3
- agno/knowledge/embedder/openai.py +223 -0
- agno/{embedder → knowledge/embedder}/sentence_transformer.py +16 -1
- agno/{embedder → knowledge/embedder}/together.py +1 -1
- agno/{embedder → knowledge/embedder}/voyageai.py +49 -1
- agno/knowledge/knowledge.py +1551 -0
- agno/knowledge/reader/__init__.py +7 -0
- agno/{document → knowledge}/reader/arxiv_reader.py +32 -4
- agno/knowledge/reader/base.py +88 -0
- agno/{document → knowledge}/reader/csv_reader.py +47 -65
- agno/knowledge/reader/docx_reader.py +83 -0
- agno/{document → knowledge}/reader/firecrawl_reader.py +42 -21
- agno/{document → knowledge}/reader/json_reader.py +30 -9
- agno/{document → knowledge}/reader/markdown_reader.py +58 -9
- agno/{document → knowledge}/reader/pdf_reader.py +71 -126
- agno/knowledge/reader/reader_factory.py +268 -0
- agno/knowledge/reader/s3_reader.py +101 -0
- agno/{document → knowledge}/reader/text_reader.py +31 -10
- agno/knowledge/reader/url_reader.py +128 -0
- agno/knowledge/reader/web_search_reader.py +366 -0
- agno/{document → knowledge}/reader/website_reader.py +37 -10
- agno/knowledge/reader/wikipedia_reader.py +59 -0
- agno/knowledge/reader/youtube_reader.py +78 -0
- agno/knowledge/remote_content/remote_content.py +88 -0
- agno/{reranker → knowledge/reranker}/base.py +1 -1
- agno/{reranker → knowledge/reranker}/cohere.py +2 -2
- agno/{reranker → knowledge/reranker}/infinity.py +2 -2
- agno/{reranker → knowledge/reranker}/sentence_transformer.py +2 -2
- agno/knowledge/types.py +30 -0
- agno/knowledge/utils.py +169 -0
- agno/media.py +269 -268
- agno/memory/__init__.py +2 -10
- agno/memory/manager.py +1003 -148
- agno/models/aimlapi/__init__.py +2 -2
- agno/models/aimlapi/aimlapi.py +6 -6
- agno/models/anthropic/claude.py +128 -72
- agno/models/aws/bedrock.py +107 -175
- agno/models/aws/claude.py +64 -18
- agno/models/azure/ai_foundry.py +73 -23
- agno/models/base.py +346 -290
- agno/models/cerebras/cerebras.py +84 -27
- agno/models/cohere/chat.py +106 -98
- agno/models/google/gemini.py +105 -46
- agno/models/groq/groq.py +97 -35
- agno/models/huggingface/huggingface.py +92 -27
- agno/models/ibm/watsonx.py +72 -13
- agno/models/litellm/chat.py +85 -13
- agno/models/message.py +46 -151
- agno/models/meta/llama.py +85 -49
- agno/models/metrics.py +120 -0
- agno/models/mistral/mistral.py +90 -21
- agno/models/ollama/__init__.py +0 -2
- agno/models/ollama/chat.py +85 -47
- agno/models/openai/chat.py +154 -37
- agno/models/openai/responses.py +178 -105
- agno/models/perplexity/perplexity.py +26 -2
- agno/models/portkey/portkey.py +0 -7
- agno/models/response.py +15 -9
- agno/models/utils.py +20 -0
- agno/models/vercel/__init__.py +2 -2
- agno/models/vercel/v0.py +1 -1
- agno/models/vllm/__init__.py +2 -2
- agno/models/vllm/vllm.py +3 -3
- agno/models/xai/xai.py +10 -10
- agno/os/__init__.py +3 -0
- agno/os/app.py +497 -0
- agno/os/auth.py +47 -0
- agno/os/config.py +103 -0
- agno/os/interfaces/agui/__init__.py +3 -0
- agno/os/interfaces/agui/agui.py +31 -0
- agno/{app/agui/async_router.py → os/interfaces/agui/router.py} +16 -16
- agno/{app → os/interfaces}/agui/utils.py +65 -28
- agno/os/interfaces/base.py +21 -0
- agno/os/interfaces/slack/__init__.py +3 -0
- agno/{app/slack/async_router.py → os/interfaces/slack/router.py} +3 -5
- agno/os/interfaces/slack/slack.py +32 -0
- agno/os/interfaces/whatsapp/__init__.py +3 -0
- agno/{app/whatsapp/async_router.py → os/interfaces/whatsapp/router.py} +4 -7
- agno/os/interfaces/whatsapp/whatsapp.py +29 -0
- agno/os/mcp.py +235 -0
- agno/os/router.py +1400 -0
- agno/os/routers/__init__.py +3 -0
- agno/os/routers/evals/__init__.py +3 -0
- agno/os/routers/evals/evals.py +393 -0
- agno/os/routers/evals/schemas.py +142 -0
- agno/os/routers/evals/utils.py +161 -0
- agno/os/routers/knowledge/__init__.py +3 -0
- agno/os/routers/knowledge/knowledge.py +850 -0
- agno/os/routers/knowledge/schemas.py +118 -0
- agno/os/routers/memory/__init__.py +3 -0
- agno/os/routers/memory/memory.py +410 -0
- agno/os/routers/memory/schemas.py +58 -0
- agno/os/routers/metrics/__init__.py +3 -0
- agno/os/routers/metrics/metrics.py +178 -0
- agno/os/routers/metrics/schemas.py +47 -0
- agno/os/routers/session/__init__.py +3 -0
- agno/os/routers/session/session.py +536 -0
- agno/os/schema.py +945 -0
- agno/{app/playground → os}/settings.py +7 -15
- agno/os/utils.py +270 -0
- agno/reasoning/azure_ai_foundry.py +4 -4
- agno/reasoning/deepseek.py +4 -4
- agno/reasoning/default.py +6 -11
- agno/reasoning/groq.py +4 -4
- agno/reasoning/helpers.py +4 -6
- agno/reasoning/ollama.py +4 -4
- agno/reasoning/openai.py +4 -4
- agno/run/agent.py +633 -0
- agno/run/base.py +53 -77
- agno/run/cancel.py +81 -0
- agno/run/team.py +243 -96
- agno/run/workflow.py +550 -12
- agno/session/__init__.py +10 -0
- agno/session/agent.py +244 -0
- agno/session/summary.py +225 -0
- agno/session/team.py +262 -0
- agno/{storage/session/v2 → session}/workflow.py +47 -24
- agno/team/__init__.py +15 -16
- agno/team/team.py +3260 -4824
- agno/tools/agentql.py +14 -5
- agno/tools/airflow.py +9 -4
- agno/tools/api.py +7 -3
- agno/tools/apify.py +2 -46
- agno/tools/arxiv.py +8 -3
- agno/tools/aws_lambda.py +7 -5
- agno/tools/aws_ses.py +7 -1
- agno/tools/baidusearch.py +4 -1
- agno/tools/bitbucket.py +4 -4
- agno/tools/brandfetch.py +14 -11
- agno/tools/bravesearch.py +4 -1
- agno/tools/brightdata.py +43 -23
- agno/tools/browserbase.py +13 -4
- agno/tools/calcom.py +12 -10
- agno/tools/calculator.py +10 -27
- agno/tools/cartesia.py +20 -17
- agno/tools/{clickup_tool.py → clickup.py} +12 -25
- agno/tools/confluence.py +8 -8
- agno/tools/crawl4ai.py +7 -1
- agno/tools/csv_toolkit.py +9 -8
- agno/tools/dalle.py +22 -12
- agno/tools/daytona.py +13 -16
- agno/tools/decorator.py +6 -3
- agno/tools/desi_vocal.py +17 -8
- agno/tools/discord.py +11 -8
- agno/tools/docker.py +30 -42
- agno/tools/duckdb.py +34 -53
- agno/tools/duckduckgo.py +8 -7
- agno/tools/e2b.py +62 -62
- agno/tools/eleven_labs.py +36 -29
- agno/tools/email.py +4 -1
- agno/tools/evm.py +7 -1
- agno/tools/exa.py +19 -14
- agno/tools/fal.py +30 -30
- agno/tools/file.py +9 -8
- agno/tools/financial_datasets.py +25 -44
- agno/tools/firecrawl.py +17 -18
- agno/tools/function.py +127 -18
- agno/tools/giphy.py +23 -11
- agno/tools/github.py +48 -126
- agno/tools/gmail.py +45 -61
- agno/tools/google_bigquery.py +7 -6
- agno/tools/google_maps.py +11 -26
- agno/tools/googlesearch.py +7 -2
- agno/tools/googlesheets.py +21 -17
- agno/tools/hackernews.py +9 -5
- agno/tools/jina.py +5 -4
- agno/tools/jira.py +18 -9
- agno/tools/knowledge.py +31 -32
- agno/tools/linear.py +18 -33
- agno/tools/linkup.py +5 -1
- agno/tools/local_file_system.py +8 -5
- agno/tools/lumalab.py +32 -20
- agno/tools/mcp.py +1 -2
- agno/tools/mem0.py +18 -12
- agno/tools/memori.py +14 -10
- agno/tools/mlx_transcribe.py +3 -2
- agno/tools/models/azure_openai.py +33 -15
- agno/tools/models/gemini.py +59 -32
- agno/tools/models/groq.py +30 -23
- agno/tools/models/nebius.py +28 -12
- agno/tools/models_labs.py +40 -16
- agno/tools/moviepy_video.py +7 -6
- agno/tools/neo4j.py +10 -8
- agno/tools/newspaper.py +7 -2
- agno/tools/newspaper4k.py +8 -3
- agno/tools/openai.py +58 -32
- agno/tools/openbb.py +12 -11
- agno/tools/opencv.py +63 -47
- agno/tools/openweather.py +14 -12
- agno/tools/pandas.py +11 -3
- agno/tools/postgres.py +4 -12
- agno/tools/pubmed.py +4 -1
- agno/tools/python.py +9 -22
- agno/tools/reasoning.py +35 -27
- agno/tools/reddit.py +11 -26
- agno/tools/replicate.py +55 -42
- agno/tools/resend.py +4 -1
- agno/tools/scrapegraph.py +15 -14
- agno/tools/searxng.py +10 -23
- agno/tools/serpapi.py +6 -3
- agno/tools/serper.py +13 -4
- agno/tools/shell.py +9 -2
- agno/tools/slack.py +12 -11
- agno/tools/sleep.py +3 -2
- agno/tools/spider.py +24 -4
- agno/tools/sql.py +7 -6
- agno/tools/tavily.py +6 -4
- agno/tools/telegram.py +12 -4
- agno/tools/todoist.py +11 -31
- agno/tools/toolkit.py +1 -1
- agno/tools/trafilatura.py +22 -6
- agno/tools/trello.py +9 -22
- agno/tools/twilio.py +10 -3
- agno/tools/user_control_flow.py +6 -1
- agno/tools/valyu.py +34 -5
- agno/tools/visualization.py +19 -28
- agno/tools/webbrowser.py +4 -3
- agno/tools/webex.py +11 -7
- agno/tools/website.py +15 -46
- agno/tools/webtools.py +12 -4
- agno/tools/whatsapp.py +5 -9
- agno/tools/wikipedia.py +20 -13
- agno/tools/x.py +14 -13
- agno/tools/yfinance.py +13 -40
- agno/tools/youtube.py +26 -20
- agno/tools/zendesk.py +7 -2
- agno/tools/zep.py +10 -7
- agno/tools/zoom.py +10 -9
- agno/utils/common.py +1 -19
- agno/utils/events.py +100 -123
- agno/utils/gemini.py +1 -1
- agno/utils/knowledge.py +29 -0
- agno/utils/log.py +54 -4
- agno/utils/mcp.py +68 -10
- agno/utils/media.py +39 -0
- agno/utils/message.py +12 -1
- agno/utils/models/aws_claude.py +1 -1
- agno/utils/models/claude.py +6 -12
- agno/utils/models/cohere.py +1 -1
- agno/utils/models/mistral.py +8 -7
- agno/utils/models/schema_utils.py +3 -3
- agno/utils/models/watsonx.py +1 -1
- agno/utils/openai.py +1 -1
- agno/utils/pprint.py +33 -32
- agno/utils/print_response/agent.py +779 -0
- agno/utils/print_response/team.py +1669 -0
- agno/utils/print_response/workflow.py +1451 -0
- agno/utils/prompts.py +14 -14
- agno/utils/reasoning.py +87 -0
- agno/utils/response.py +42 -42
- agno/utils/streamlit.py +481 -0
- agno/utils/string.py +8 -22
- agno/utils/team.py +50 -0
- agno/utils/timer.py +2 -2
- agno/vectordb/base.py +33 -21
- agno/vectordb/cassandra/cassandra.py +287 -23
- agno/vectordb/chroma/chromadb.py +482 -59
- agno/vectordb/clickhouse/clickhousedb.py +270 -63
- agno/vectordb/couchbase/couchbase.py +309 -29
- agno/vectordb/lancedb/lance_db.py +360 -21
- agno/vectordb/langchaindb/__init__.py +5 -0
- agno/vectordb/langchaindb/langchaindb.py +145 -0
- agno/vectordb/lightrag/__init__.py +5 -0
- agno/vectordb/lightrag/lightrag.py +374 -0
- agno/vectordb/llamaindex/llamaindexdb.py +127 -0
- agno/vectordb/milvus/milvus.py +242 -32
- agno/vectordb/mongodb/mongodb.py +200 -24
- agno/vectordb/pgvector/pgvector.py +319 -37
- agno/vectordb/pineconedb/pineconedb.py +221 -27
- agno/vectordb/qdrant/qdrant.py +334 -14
- agno/vectordb/singlestore/singlestore.py +286 -29
- agno/vectordb/surrealdb/surrealdb.py +187 -7
- agno/vectordb/upstashdb/upstashdb.py +342 -26
- agno/vectordb/weaviate/weaviate.py +227 -165
- agno/workflow/__init__.py +17 -13
- agno/workflow/{v2/condition.py → condition.py} +135 -32
- agno/workflow/{v2/loop.py → loop.py} +115 -28
- agno/workflow/{v2/parallel.py → parallel.py} +138 -108
- agno/workflow/{v2/router.py → router.py} +133 -32
- agno/workflow/{v2/step.py → step.py} +207 -49
- agno/workflow/{v2/steps.py → steps.py} +147 -66
- agno/workflow/types.py +482 -0
- agno/workflow/workflow.py +2410 -696
- agno-2.0.0.dist-info/METADATA +494 -0
- agno-2.0.0.dist-info/RECORD +515 -0
- agno-2.0.0.dist-info/licenses/LICENSE +201 -0
- agno/agent/metrics.py +0 -110
- agno/api/app.py +0 -35
- agno/api/playground.py +0 -92
- agno/api/schemas/app.py +0 -12
- agno/api/schemas/playground.py +0 -22
- agno/api/schemas/user.py +0 -35
- agno/api/schemas/workspace.py +0 -46
- agno/api/user.py +0 -160
- agno/api/workflows.py +0 -33
- agno/api/workspace.py +0 -175
- agno/app/agui/__init__.py +0 -3
- agno/app/agui/app.py +0 -17
- agno/app/agui/sync_router.py +0 -120
- agno/app/base.py +0 -186
- agno/app/discord/__init__.py +0 -3
- agno/app/fastapi/__init__.py +0 -3
- agno/app/fastapi/app.py +0 -107
- agno/app/fastapi/async_router.py +0 -457
- agno/app/fastapi/sync_router.py +0 -448
- agno/app/playground/app.py +0 -228
- agno/app/playground/async_router.py +0 -1053
- agno/app/playground/deploy.py +0 -249
- agno/app/playground/operator.py +0 -183
- agno/app/playground/schemas.py +0 -223
- agno/app/playground/serve.py +0 -55
- agno/app/playground/sync_router.py +0 -1045
- agno/app/playground/utils.py +0 -46
- agno/app/settings.py +0 -15
- agno/app/slack/__init__.py +0 -3
- agno/app/slack/app.py +0 -19
- agno/app/slack/sync_router.py +0 -92
- agno/app/utils.py +0 -54
- agno/app/whatsapp/__init__.py +0 -3
- agno/app/whatsapp/app.py +0 -15
- agno/app/whatsapp/sync_router.py +0 -197
- agno/cli/auth_server.py +0 -249
- agno/cli/config.py +0 -274
- agno/cli/console.py +0 -88
- agno/cli/credentials.py +0 -23
- agno/cli/entrypoint.py +0 -571
- agno/cli/operator.py +0 -357
- agno/cli/settings.py +0 -96
- agno/cli/ws/ws_cli.py +0 -817
- agno/constants.py +0 -13
- agno/document/__init__.py +0 -5
- agno/document/chunking/semantic.py +0 -45
- agno/document/chunking/strategy.py +0 -31
- agno/document/reader/__init__.py +0 -5
- agno/document/reader/base.py +0 -47
- agno/document/reader/docx_reader.py +0 -60
- agno/document/reader/gcs/pdf_reader.py +0 -44
- agno/document/reader/s3/pdf_reader.py +0 -59
- agno/document/reader/s3/text_reader.py +0 -63
- agno/document/reader/url_reader.py +0 -59
- agno/document/reader/youtube_reader.py +0 -58
- agno/embedder/__init__.py +0 -5
- agno/embedder/langdb.py +0 -80
- agno/embedder/mistral.py +0 -82
- agno/embedder/openai.py +0 -78
- agno/file/__init__.py +0 -5
- agno/file/file.py +0 -16
- agno/file/local/csv.py +0 -32
- agno/file/local/txt.py +0 -19
- agno/infra/app.py +0 -240
- agno/infra/base.py +0 -144
- agno/infra/context.py +0 -20
- agno/infra/db_app.py +0 -52
- agno/infra/resource.py +0 -205
- agno/infra/resources.py +0 -55
- agno/knowledge/agent.py +0 -702
- agno/knowledge/arxiv.py +0 -33
- agno/knowledge/combined.py +0 -36
- agno/knowledge/csv.py +0 -144
- agno/knowledge/csv_url.py +0 -124
- agno/knowledge/document.py +0 -223
- agno/knowledge/docx.py +0 -137
- agno/knowledge/firecrawl.py +0 -34
- agno/knowledge/gcs/__init__.py +0 -0
- agno/knowledge/gcs/base.py +0 -39
- agno/knowledge/gcs/pdf.py +0 -125
- agno/knowledge/json.py +0 -137
- agno/knowledge/langchain.py +0 -71
- agno/knowledge/light_rag.py +0 -273
- agno/knowledge/llamaindex.py +0 -66
- agno/knowledge/markdown.py +0 -154
- agno/knowledge/pdf.py +0 -164
- agno/knowledge/pdf_bytes.py +0 -42
- agno/knowledge/pdf_url.py +0 -148
- agno/knowledge/s3/__init__.py +0 -0
- agno/knowledge/s3/base.py +0 -64
- agno/knowledge/s3/pdf.py +0 -33
- agno/knowledge/s3/text.py +0 -34
- agno/knowledge/text.py +0 -141
- agno/knowledge/url.py +0 -46
- agno/knowledge/website.py +0 -179
- agno/knowledge/wikipedia.py +0 -32
- agno/knowledge/youtube.py +0 -35
- agno/memory/agent.py +0 -423
- agno/memory/classifier.py +0 -104
- agno/memory/db/__init__.py +0 -5
- agno/memory/db/base.py +0 -42
- agno/memory/db/mongodb.py +0 -189
- agno/memory/db/postgres.py +0 -203
- agno/memory/db/sqlite.py +0 -193
- agno/memory/memory.py +0 -22
- agno/memory/row.py +0 -36
- agno/memory/summarizer.py +0 -201
- agno/memory/summary.py +0 -19
- agno/memory/team.py +0 -415
- agno/memory/v2/__init__.py +0 -2
- agno/memory/v2/db/__init__.py +0 -1
- agno/memory/v2/db/base.py +0 -42
- agno/memory/v2/db/firestore.py +0 -339
- agno/memory/v2/db/mongodb.py +0 -196
- agno/memory/v2/db/postgres.py +0 -214
- agno/memory/v2/db/redis.py +0 -187
- agno/memory/v2/db/schema.py +0 -54
- agno/memory/v2/db/sqlite.py +0 -209
- agno/memory/v2/manager.py +0 -437
- agno/memory/v2/memory.py +0 -1097
- agno/memory/v2/schema.py +0 -55
- agno/memory/v2/summarizer.py +0 -215
- agno/memory/workflow.py +0 -38
- agno/models/ollama/tools.py +0 -430
- agno/models/qwen/__init__.py +0 -5
- agno/playground/__init__.py +0 -10
- agno/playground/deploy.py +0 -3
- agno/playground/playground.py +0 -3
- agno/playground/serve.py +0 -3
- agno/playground/settings.py +0 -3
- agno/reranker/__init__.py +0 -0
- agno/run/response.py +0 -467
- agno/run/v2/__init__.py +0 -0
- agno/run/v2/workflow.py +0 -567
- agno/storage/__init__.py +0 -0
- agno/storage/agent/__init__.py +0 -0
- agno/storage/agent/dynamodb.py +0 -1
- agno/storage/agent/json.py +0 -1
- agno/storage/agent/mongodb.py +0 -1
- agno/storage/agent/postgres.py +0 -1
- agno/storage/agent/singlestore.py +0 -1
- agno/storage/agent/sqlite.py +0 -1
- agno/storage/agent/yaml.py +0 -1
- agno/storage/base.py +0 -60
- agno/storage/dynamodb.py +0 -673
- agno/storage/firestore.py +0 -297
- agno/storage/gcs_json.py +0 -261
- agno/storage/in_memory.py +0 -234
- agno/storage/json.py +0 -237
- agno/storage/mongodb.py +0 -328
- agno/storage/mysql.py +0 -685
- agno/storage/postgres.py +0 -682
- agno/storage/redis.py +0 -336
- agno/storage/session/__init__.py +0 -16
- agno/storage/session/agent.py +0 -64
- agno/storage/session/team.py +0 -63
- agno/storage/session/v2/__init__.py +0 -5
- agno/storage/session/workflow.py +0 -61
- agno/storage/singlestore.py +0 -606
- agno/storage/sqlite.py +0 -646
- agno/storage/workflow/__init__.py +0 -0
- agno/storage/workflow/mongodb.py +0 -1
- agno/storage/workflow/postgres.py +0 -1
- agno/storage/workflow/sqlite.py +0 -1
- agno/storage/yaml.py +0 -241
- agno/tools/thinking.py +0 -73
- agno/utils/defaults.py +0 -57
- agno/utils/filesystem.py +0 -39
- agno/utils/git.py +0 -52
- agno/utils/json_io.py +0 -30
- agno/utils/load_env.py +0 -19
- agno/utils/py_io.py +0 -19
- agno/utils/pyproject.py +0 -18
- agno/utils/resource_filter.py +0 -31
- agno/workflow/v2/__init__.py +0 -21
- agno/workflow/v2/types.py +0 -357
- agno/workflow/v2/workflow.py +0 -3313
- agno/workspace/__init__.py +0 -0
- agno/workspace/config.py +0 -325
- agno/workspace/enums.py +0 -6
- agno/workspace/helpers.py +0 -52
- agno/workspace/operator.py +0 -757
- agno/workspace/settings.py +0 -158
- agno-1.8.2.dist-info/METADATA +0 -982
- agno-1.8.2.dist-info/RECORD +0 -566
- agno-1.8.2.dist-info/entry_points.txt +0 -3
- agno-1.8.2.dist-info/licenses/LICENSE +0 -375
- /agno/{app → db/migrations}/__init__.py +0 -0
- /agno/{app/playground/__init__.py → db/schemas/metrics.py} +0 -0
- /agno/{cli → integrations}/__init__.py +0 -0
- /agno/{cli/ws → knowledge/chunking}/__init__.py +0 -0
- /agno/{document/chunking → knowledge/remote_content}/__init__.py +0 -0
- /agno/{document/reader/gcs → knowledge/reranker}/__init__.py +0 -0
- /agno/{document/reader/s3 → os/interfaces}/__init__.py +0 -0
- /agno/{app → os/interfaces}/slack/security.py +0 -0
- /agno/{app → os/interfaces}/whatsapp/security.py +0 -0
- /agno/{file/local → utils/print_response}/__init__.py +0 -0
- /agno/{infra → vectordb/llamaindex}/__init__.py +0 -0
- {agno-1.8.2.dist-info → agno-2.0.0.dist-info}/WHEEL +0 -0
- {agno-1.8.2.dist-info → agno-2.0.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from os import getenv
|
|
3
|
+
from typing import Optional
|
|
4
|
+
|
|
5
|
+
from agno.knowledge.embedder.openai import OpenAIEmbedder
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@dataclass
|
|
9
|
+
class LangDBEmbedder(OpenAIEmbedder):
|
|
10
|
+
id: str = "text-embedding-ada-002"
|
|
11
|
+
dimensions: int = 1536
|
|
12
|
+
api_key: Optional[str] = getenv("LANGDB_API_KEY")
|
|
13
|
+
project_id: Optional[str] = getenv("LANGDB_PROJECT_ID")
|
|
14
|
+
base_url: Optional[str] = None
|
|
15
|
+
|
|
16
|
+
def __post_init__(self):
|
|
17
|
+
"""Set the base_url based on project_id if not provided."""
|
|
18
|
+
if not self.project_id:
|
|
19
|
+
raise ValueError("LANGDB_PROJECT_ID not set in the environment")
|
|
20
|
+
|
|
21
|
+
if not self.base_url:
|
|
22
|
+
self.base_url = f"https://api.us-east-1.langdb.ai/{self.project_id}/v1"
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from os import getenv
|
|
3
|
+
from typing import Any, Dict, List, Optional, Tuple
|
|
4
|
+
|
|
5
|
+
from agno.knowledge.embedder.base import Embedder
|
|
6
|
+
from agno.utils.log import logger
|
|
7
|
+
|
|
8
|
+
try:
|
|
9
|
+
from mistralai import Mistral # type: ignore
|
|
10
|
+
from mistralai.models.embeddingresponse import EmbeddingResponse # type: ignore
|
|
11
|
+
except ImportError:
|
|
12
|
+
logger.error("`mistralai` not installed")
|
|
13
|
+
raise
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@dataclass
|
|
17
|
+
class MistralEmbedder(Embedder):
|
|
18
|
+
id: str = "mistral-embed"
|
|
19
|
+
dimensions: int = 1024
|
|
20
|
+
# -*- Request parameters
|
|
21
|
+
request_params: Optional[Dict[str, Any]] = None
|
|
22
|
+
# -*- Client parameters
|
|
23
|
+
api_key: Optional[str] = getenv("MISTRAL_API_KEY")
|
|
24
|
+
endpoint: Optional[str] = None
|
|
25
|
+
max_retries: Optional[int] = None
|
|
26
|
+
timeout: Optional[int] = None
|
|
27
|
+
client_params: Optional[Dict[str, Any]] = None
|
|
28
|
+
# -*- Provide the Mistral Client manually
|
|
29
|
+
mistral_client: Optional[Mistral] = None
|
|
30
|
+
|
|
31
|
+
@property
|
|
32
|
+
def client(self) -> Mistral:
|
|
33
|
+
if self.mistral_client:
|
|
34
|
+
return self.mistral_client
|
|
35
|
+
|
|
36
|
+
_client_params: Dict[str, Any] = {
|
|
37
|
+
"api_key": self.api_key,
|
|
38
|
+
"endpoint": self.endpoint,
|
|
39
|
+
"max_retries": self.max_retries,
|
|
40
|
+
"timeout": self.timeout,
|
|
41
|
+
}
|
|
42
|
+
_client_params = {k: v for k, v in _client_params.items() if v is not None}
|
|
43
|
+
|
|
44
|
+
if self.client_params:
|
|
45
|
+
_client_params.update(self.client_params)
|
|
46
|
+
|
|
47
|
+
self.mistral_client = Mistral(**_client_params)
|
|
48
|
+
|
|
49
|
+
return self.mistral_client
|
|
50
|
+
|
|
51
|
+
def _response(self, text: str) -> EmbeddingResponse:
|
|
52
|
+
_request_params: Dict[str, Any] = {
|
|
53
|
+
"inputs": text,
|
|
54
|
+
"model": self.id,
|
|
55
|
+
}
|
|
56
|
+
if self.request_params:
|
|
57
|
+
_request_params.update(self.request_params)
|
|
58
|
+
response = self.client.embeddings.create(**_request_params)
|
|
59
|
+
if response is None:
|
|
60
|
+
raise ValueError("Failed to get embedding response")
|
|
61
|
+
return response
|
|
62
|
+
|
|
63
|
+
def get_embedding(self, text: str) -> List[float]:
|
|
64
|
+
try:
|
|
65
|
+
response: EmbeddingResponse = self._response(text=text)
|
|
66
|
+
if response.data and response.data[0].embedding:
|
|
67
|
+
return response.data[0].embedding
|
|
68
|
+
return []
|
|
69
|
+
except Exception as e:
|
|
70
|
+
logger.warning(f"Error getting embedding: {e}")
|
|
71
|
+
return []
|
|
72
|
+
|
|
73
|
+
def get_embedding_and_usage(self, text: str) -> Tuple[List[float], Dict[str, Any]]:
|
|
74
|
+
try:
|
|
75
|
+
response: EmbeddingResponse = self._response(text=text)
|
|
76
|
+
embedding: List[float] = (
|
|
77
|
+
response.data[0].embedding if (response.data and response.data[0].embedding) else []
|
|
78
|
+
)
|
|
79
|
+
usage: Dict[str, Any] = response.usage.model_dump() if response.usage else {}
|
|
80
|
+
return embedding, usage
|
|
81
|
+
except Exception as e:
|
|
82
|
+
logger.warning(f"Error getting embedding and usage: {e}")
|
|
83
|
+
return [], {}
|
|
84
|
+
|
|
85
|
+
async def async_get_embedding(self, text: str) -> List[float]:
|
|
86
|
+
"""Async version of get_embedding."""
|
|
87
|
+
try:
|
|
88
|
+
# Check if the client has an async version of embeddings.create
|
|
89
|
+
if hasattr(self.client.embeddings, "create_async"):
|
|
90
|
+
response: EmbeddingResponse = await self.client.embeddings.create_async(
|
|
91
|
+
inputs=text, model=self.id, **self.request_params if self.request_params else {}
|
|
92
|
+
)
|
|
93
|
+
else:
|
|
94
|
+
# Fallback to running sync method in thread executor
|
|
95
|
+
import asyncio
|
|
96
|
+
|
|
97
|
+
loop = asyncio.get_running_loop()
|
|
98
|
+
response: EmbeddingResponse = await loop.run_in_executor( # type: ignore
|
|
99
|
+
None,
|
|
100
|
+
lambda: self.client.embeddings.create(
|
|
101
|
+
inputs=text, model=self.id, **self.request_params if self.request_params else {}
|
|
102
|
+
),
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
if response.data and response.data[0].embedding:
|
|
106
|
+
return response.data[0].embedding
|
|
107
|
+
return []
|
|
108
|
+
except Exception as e:
|
|
109
|
+
logger.warning(f"Error getting embedding: {e}")
|
|
110
|
+
return []
|
|
111
|
+
|
|
112
|
+
async def async_get_embedding_and_usage(self, text: str) -> Tuple[List[float], Dict[str, Any]]:
|
|
113
|
+
"""Async version of get_embedding_and_usage."""
|
|
114
|
+
try:
|
|
115
|
+
# Check if the client has an async version of embeddings.create
|
|
116
|
+
if hasattr(self.client.embeddings, "create_async"):
|
|
117
|
+
response: EmbeddingResponse = await self.client.embeddings.create_async(
|
|
118
|
+
inputs=text, model=self.id, **self.request_params if self.request_params else {}
|
|
119
|
+
)
|
|
120
|
+
else:
|
|
121
|
+
# Fallback to running sync method in thread executor
|
|
122
|
+
import asyncio
|
|
123
|
+
|
|
124
|
+
loop = asyncio.get_running_loop()
|
|
125
|
+
response: EmbeddingResponse = await loop.run_in_executor( # type: ignore
|
|
126
|
+
None,
|
|
127
|
+
lambda: self.client.embeddings.create(
|
|
128
|
+
inputs=text, model=self.id, **self.request_params if self.request_params else {}
|
|
129
|
+
),
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
embedding: List[float] = (
|
|
133
|
+
response.data[0].embedding if (response.data and response.data[0].embedding) else []
|
|
134
|
+
)
|
|
135
|
+
usage: Dict[str, Any] = response.usage.model_dump() if response.usage else {}
|
|
136
|
+
return embedding, usage
|
|
137
|
+
except Exception as e:
|
|
138
|
+
logger.warning(f"Error getting embedding and usage: {e}")
|
|
139
|
+
return [], {}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
from dataclasses import dataclass
|
|
2
2
|
from typing import Any, Dict, List, Optional, Tuple
|
|
3
3
|
|
|
4
|
-
from agno.embedder.base import Embedder
|
|
5
|
-
from agno.utils.log import logger
|
|
4
|
+
from agno.knowledge.embedder.base import Embedder
|
|
5
|
+
from agno.utils.log import log_error, logger
|
|
6
6
|
|
|
7
7
|
try:
|
|
8
8
|
import importlib.metadata as metadata
|
|
9
9
|
|
|
10
|
+
from ollama import AsyncClient as AsyncOllamaClient
|
|
10
11
|
from ollama import Client as OllamaClient
|
|
11
12
|
from packaging import version
|
|
12
13
|
|
|
@@ -30,7 +31,7 @@ except ImportError as e:
|
|
|
30
31
|
|
|
31
32
|
except Exception as e:
|
|
32
33
|
# Catch-all for unexpected errors
|
|
33
|
-
|
|
34
|
+
log_error(f"An unexpected error occurred: {e}")
|
|
34
35
|
|
|
35
36
|
|
|
36
37
|
@dataclass
|
|
@@ -42,6 +43,7 @@ class OllamaEmbedder(Embedder):
|
|
|
42
43
|
options: Optional[Any] = None
|
|
43
44
|
client_kwargs: Optional[Dict[str, Any]] = None
|
|
44
45
|
ollama_client: Optional[OllamaClient] = None
|
|
46
|
+
async_client: Optional[AsyncOllamaClient] = None
|
|
45
47
|
|
|
46
48
|
@property
|
|
47
49
|
def client(self) -> OllamaClient:
|
|
@@ -58,6 +60,21 @@ class OllamaEmbedder(Embedder):
|
|
|
58
60
|
self.ollama_client = OllamaClient(**_ollama_params)
|
|
59
61
|
return self.ollama_client
|
|
60
62
|
|
|
63
|
+
@property
|
|
64
|
+
def aclient(self) -> AsyncOllamaClient:
|
|
65
|
+
if self.async_client:
|
|
66
|
+
return self.async_client
|
|
67
|
+
|
|
68
|
+
_ollama_params: Dict[str, Any] = {
|
|
69
|
+
"host": self.host,
|
|
70
|
+
"timeout": self.timeout,
|
|
71
|
+
}
|
|
72
|
+
_ollama_params = {k: v for k, v in _ollama_params.items() if v is not None}
|
|
73
|
+
if self.client_kwargs:
|
|
74
|
+
_ollama_params.update(self.client_kwargs)
|
|
75
|
+
self.async_client = AsyncOllamaClient(**_ollama_params)
|
|
76
|
+
return self.async_client
|
|
77
|
+
|
|
61
78
|
def _response(self, text: str) -> Dict[str, Any]:
|
|
62
79
|
kwargs: Dict[str, Any] = {}
|
|
63
80
|
if self.options is not None:
|
|
@@ -88,3 +105,37 @@ class OllamaEmbedder(Embedder):
|
|
|
88
105
|
embedding = self.get_embedding(text=text)
|
|
89
106
|
usage = None
|
|
90
107
|
return embedding, usage
|
|
108
|
+
|
|
109
|
+
async def _async_response(self, text: str) -> Dict[str, Any]:
|
|
110
|
+
"""Async version of _response using AsyncOllamaClient."""
|
|
111
|
+
kwargs: Dict[str, Any] = {}
|
|
112
|
+
if self.options is not None:
|
|
113
|
+
kwargs["options"] = self.options
|
|
114
|
+
|
|
115
|
+
response = await self.aclient.embed(input=text, model=self.id, **kwargs)
|
|
116
|
+
if response and "embeddings" in response:
|
|
117
|
+
embeddings = response["embeddings"]
|
|
118
|
+
if isinstance(embeddings, list) and len(embeddings) > 0 and isinstance(embeddings[0], list):
|
|
119
|
+
return {"embeddings": embeddings[0]} # Use the first element
|
|
120
|
+
elif isinstance(embeddings, list) and all(isinstance(x, (int, float)) for x in embeddings):
|
|
121
|
+
return {"embeddings": embeddings} # Return as-is if already flat
|
|
122
|
+
return {"embeddings": []} # Return an empty list if no valid embedding is found
|
|
123
|
+
|
|
124
|
+
async def async_get_embedding(self, text: str) -> List[float]:
|
|
125
|
+
"""Async version of get_embedding."""
|
|
126
|
+
try:
|
|
127
|
+
response = await self._async_response(text=text)
|
|
128
|
+
embedding = response.get("embeddings", [])
|
|
129
|
+
if len(embedding) != self.dimensions:
|
|
130
|
+
logger.warning(f"Expected embedding dimension {self.dimensions}, but got {len(embedding)}")
|
|
131
|
+
return []
|
|
132
|
+
return embedding
|
|
133
|
+
except Exception as e:
|
|
134
|
+
logger.warning(f"Error getting embedding: {e}")
|
|
135
|
+
return []
|
|
136
|
+
|
|
137
|
+
async def async_get_embedding_and_usage(self, text: str) -> Tuple[List[float], Optional[Dict]]:
|
|
138
|
+
"""Async version of get_embedding_and_usage."""
|
|
139
|
+
embedding = await self.async_get_embedding(text=text)
|
|
140
|
+
usage = None
|
|
141
|
+
return embedding, usage
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from typing import Any, Dict, List, Optional, Tuple
|
|
3
|
+
|
|
4
|
+
from typing_extensions import Literal
|
|
5
|
+
|
|
6
|
+
from agno.knowledge.embedder.base import Embedder
|
|
7
|
+
from agno.utils.log import logger
|
|
8
|
+
|
|
9
|
+
try:
|
|
10
|
+
from openai import AsyncOpenAI
|
|
11
|
+
from openai import OpenAI as OpenAIClient
|
|
12
|
+
from openai.types.create_embedding_response import CreateEmbeddingResponse
|
|
13
|
+
except ImportError:
|
|
14
|
+
raise ImportError("`openai` not installed")
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@dataclass
|
|
18
|
+
class OpenAIEmbedder(Embedder):
|
|
19
|
+
id: str = "text-embedding-3-small"
|
|
20
|
+
dimensions: Optional[int] = None
|
|
21
|
+
encoding_format: Literal["float", "base64"] = "float"
|
|
22
|
+
user: Optional[str] = None
|
|
23
|
+
api_key: Optional[str] = None
|
|
24
|
+
organization: Optional[str] = None
|
|
25
|
+
base_url: Optional[str] = None
|
|
26
|
+
request_params: Optional[Dict[str, Any]] = None
|
|
27
|
+
client_params: Optional[Dict[str, Any]] = None
|
|
28
|
+
openai_client: Optional[OpenAIClient] = None
|
|
29
|
+
async_client: Optional[AsyncOpenAI] = None
|
|
30
|
+
|
|
31
|
+
def __post_init__(self):
|
|
32
|
+
if self.dimensions is None:
|
|
33
|
+
self.dimensions = 3072 if self.id == "text-embedding-3-large" else 1536
|
|
34
|
+
|
|
35
|
+
@property
|
|
36
|
+
def client(self) -> OpenAIClient:
|
|
37
|
+
if self.openai_client:
|
|
38
|
+
return self.openai_client
|
|
39
|
+
|
|
40
|
+
_client_params: Dict[str, Any] = {
|
|
41
|
+
"api_key": self.api_key,
|
|
42
|
+
"organization": self.organization,
|
|
43
|
+
"base_url": self.base_url,
|
|
44
|
+
}
|
|
45
|
+
_client_params = {k: v for k, v in _client_params.items() if v is not None}
|
|
46
|
+
if self.client_params:
|
|
47
|
+
_client_params.update(self.client_params)
|
|
48
|
+
self.openai_client = OpenAIClient(**_client_params)
|
|
49
|
+
return self.openai_client
|
|
50
|
+
|
|
51
|
+
@property
|
|
52
|
+
def aclient(self) -> AsyncOpenAI:
|
|
53
|
+
if self.async_client:
|
|
54
|
+
return self.async_client
|
|
55
|
+
params = {
|
|
56
|
+
"api_key": self.api_key,
|
|
57
|
+
"organization": self.organization,
|
|
58
|
+
"base_url": self.base_url,
|
|
59
|
+
}
|
|
60
|
+
filtered_params: Dict[str, Any] = {k: v for k, v in params.items() if v is not None}
|
|
61
|
+
if self.client_params:
|
|
62
|
+
filtered_params.update(self.client_params)
|
|
63
|
+
self.async_client = AsyncOpenAI(**filtered_params)
|
|
64
|
+
return self.async_client
|
|
65
|
+
|
|
66
|
+
def response(self, text: str) -> CreateEmbeddingResponse:
|
|
67
|
+
_request_params: Dict[str, Any] = {
|
|
68
|
+
"input": text,
|
|
69
|
+
"model": self.id,
|
|
70
|
+
"encoding_format": self.encoding_format,
|
|
71
|
+
}
|
|
72
|
+
if self.user is not None:
|
|
73
|
+
_request_params["user"] = self.user
|
|
74
|
+
if self.id.startswith("text-embedding-3"):
|
|
75
|
+
_request_params["dimensions"] = self.dimensions
|
|
76
|
+
if self.request_params:
|
|
77
|
+
_request_params.update(self.request_params)
|
|
78
|
+
return self.client.embeddings.create(**_request_params)
|
|
79
|
+
|
|
80
|
+
def get_embedding(self, text: str) -> List[float]:
|
|
81
|
+
response: CreateEmbeddingResponse = self.response(text=text)
|
|
82
|
+
try:
|
|
83
|
+
return response.data[0].embedding
|
|
84
|
+
except Exception as e:
|
|
85
|
+
logger.warning(e)
|
|
86
|
+
return []
|
|
87
|
+
|
|
88
|
+
def get_embedding_and_usage(self, text: str) -> Tuple[List[float], Optional[Dict]]:
|
|
89
|
+
response: CreateEmbeddingResponse = self.response(text=text)
|
|
90
|
+
|
|
91
|
+
embedding = response.data[0].embedding
|
|
92
|
+
usage = response.usage
|
|
93
|
+
if usage:
|
|
94
|
+
return embedding, usage.model_dump()
|
|
95
|
+
return embedding, None
|
|
96
|
+
|
|
97
|
+
async def async_get_embedding(self, text: str) -> List[float]:
|
|
98
|
+
req: Dict[str, Any] = {
|
|
99
|
+
"input": text,
|
|
100
|
+
"model": self.id,
|
|
101
|
+
"encoding_format": self.encoding_format,
|
|
102
|
+
}
|
|
103
|
+
if self.user is not None:
|
|
104
|
+
req["user"] = self.user
|
|
105
|
+
if self.id.startswith("text-embedding-3"):
|
|
106
|
+
req["dimensions"] = self.dimensions
|
|
107
|
+
if self.request_params:
|
|
108
|
+
req.update(self.request_params)
|
|
109
|
+
|
|
110
|
+
try:
|
|
111
|
+
response: CreateEmbeddingResponse = await self.aclient.embeddings.create(**req)
|
|
112
|
+
return response.data[0].embedding
|
|
113
|
+
except Exception as e:
|
|
114
|
+
logger.warning(e)
|
|
115
|
+
return []
|
|
116
|
+
|
|
117
|
+
async def async_get_embedding_and_usage(self, text: str):
|
|
118
|
+
req: Dict[str, Any] = {
|
|
119
|
+
"input": text,
|
|
120
|
+
"model": self.id,
|
|
121
|
+
"encoding_format": self.encoding_format,
|
|
122
|
+
}
|
|
123
|
+
if self.user is not None:
|
|
124
|
+
req["user"] = self.user
|
|
125
|
+
if self.id.startswith("text-embedding-3"):
|
|
126
|
+
req["dimensions"] = self.dimensions
|
|
127
|
+
if self.request_params:
|
|
128
|
+
req.update(self.request_params)
|
|
129
|
+
|
|
130
|
+
response = await self.aclient.embeddings.create(**req)
|
|
131
|
+
embedding = response.data[0].embedding
|
|
132
|
+
usage = response.usage
|
|
133
|
+
return embedding, usage.model_dump() if usage else None
|
|
134
|
+
|
|
135
|
+
def get_embeddings_batch(self, texts: List[str], batch_size: int = 100) -> List[List[float]]:
|
|
136
|
+
"""
|
|
137
|
+
Get embeddings for multiple texts in batches.
|
|
138
|
+
|
|
139
|
+
Args:
|
|
140
|
+
texts: List of text strings to embed
|
|
141
|
+
batch_size: Number of texts to process in each API call (max ~2048)
|
|
142
|
+
|
|
143
|
+
Returns:
|
|
144
|
+
List of embedding vectors
|
|
145
|
+
"""
|
|
146
|
+
all_embeddings = []
|
|
147
|
+
|
|
148
|
+
for i in range(0, len(texts), batch_size):
|
|
149
|
+
batch_texts = texts[i : i + batch_size]
|
|
150
|
+
|
|
151
|
+
req: Dict[str, Any] = {
|
|
152
|
+
"input": batch_texts,
|
|
153
|
+
"model": self.id,
|
|
154
|
+
"encoding_format": self.encoding_format,
|
|
155
|
+
}
|
|
156
|
+
if self.user is not None:
|
|
157
|
+
req["user"] = self.user
|
|
158
|
+
if self.id.startswith("text-embedding-3"):
|
|
159
|
+
req["dimensions"] = self.dimensions
|
|
160
|
+
if self.request_params:
|
|
161
|
+
req.update(self.request_params)
|
|
162
|
+
|
|
163
|
+
try:
|
|
164
|
+
response: CreateEmbeddingResponse = self.client.embeddings.create(**req)
|
|
165
|
+
batch_embeddings = [data.embedding for data in response.data]
|
|
166
|
+
all_embeddings.extend(batch_embeddings)
|
|
167
|
+
except Exception as e:
|
|
168
|
+
logger.warning(f"Error in batch embedding: {e}")
|
|
169
|
+
# Fallback to individual calls for this batch
|
|
170
|
+
for text in batch_texts:
|
|
171
|
+
try:
|
|
172
|
+
embedding = self.get_embedding(text)
|
|
173
|
+
all_embeddings.append(embedding)
|
|
174
|
+
except Exception as e2:
|
|
175
|
+
logger.warning(f"Error in individual embedding fallback: {e2}")
|
|
176
|
+
all_embeddings.append([])
|
|
177
|
+
|
|
178
|
+
return all_embeddings
|
|
179
|
+
|
|
180
|
+
async def async_get_embeddings_batch(self, texts: List[str], batch_size: int = 100) -> List[List[float]]:
|
|
181
|
+
"""
|
|
182
|
+
Get embeddings for multiple texts in batches (async version).
|
|
183
|
+
|
|
184
|
+
Args:
|
|
185
|
+
texts: List of text strings to embed
|
|
186
|
+
batch_size: Number of texts to process in each API call (max ~2048)
|
|
187
|
+
|
|
188
|
+
Returns:
|
|
189
|
+
List of embedding vectors
|
|
190
|
+
"""
|
|
191
|
+
all_embeddings = []
|
|
192
|
+
|
|
193
|
+
for i in range(0, len(texts), batch_size):
|
|
194
|
+
batch_texts = texts[i : i + batch_size]
|
|
195
|
+
|
|
196
|
+
req: Dict[str, Any] = {
|
|
197
|
+
"input": batch_texts,
|
|
198
|
+
"model": self.id,
|
|
199
|
+
"encoding_format": self.encoding_format,
|
|
200
|
+
}
|
|
201
|
+
if self.user is not None:
|
|
202
|
+
req["user"] = self.user
|
|
203
|
+
if self.id.startswith("text-embedding-3"):
|
|
204
|
+
req["dimensions"] = self.dimensions
|
|
205
|
+
if self.request_params:
|
|
206
|
+
req.update(self.request_params)
|
|
207
|
+
|
|
208
|
+
try:
|
|
209
|
+
response: CreateEmbeddingResponse = await self.aclient.embeddings.create(**req)
|
|
210
|
+
batch_embeddings = [data.embedding for data in response.data]
|
|
211
|
+
all_embeddings.extend(batch_embeddings)
|
|
212
|
+
except Exception as e:
|
|
213
|
+
logger.warning(f"Error in async batch embedding: {e}")
|
|
214
|
+
# Fallback to individual async calls for this batch
|
|
215
|
+
for text in batch_texts:
|
|
216
|
+
try:
|
|
217
|
+
embedding = await self.async_get_embedding(text)
|
|
218
|
+
all_embeddings.append(embedding)
|
|
219
|
+
except Exception as e2:
|
|
220
|
+
logger.warning(f"Error in individual async embedding fallback: {e2}")
|
|
221
|
+
all_embeddings.append([])
|
|
222
|
+
|
|
223
|
+
return all_embeddings
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from dataclasses import dataclass
|
|
2
2
|
from typing import 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:
|
|
@@ -42,3 +42,18 @@ class SentenceTransformerEmbedder(Embedder):
|
|
|
42
42
|
|
|
43
43
|
def get_embedding_and_usage(self, text: str) -> Tuple[List[float], Optional[Dict]]:
|
|
44
44
|
return self.get_embedding(text=text), None
|
|
45
|
+
|
|
46
|
+
async def async_get_embedding(self, text: Union[str, List[str]]) -> List[float]:
|
|
47
|
+
"""Async version using thread executor for CPU-bound operations."""
|
|
48
|
+
import asyncio
|
|
49
|
+
|
|
50
|
+
loop = asyncio.get_event_loop()
|
|
51
|
+
# Run the CPU-bound operation in a thread executor
|
|
52
|
+
return await loop.run_in_executor(None, self.get_embedding, text)
|
|
53
|
+
|
|
54
|
+
async def async_get_embedding_and_usage(self, text: str) -> Tuple[List[float], Optional[Dict]]:
|
|
55
|
+
"""Async version using thread executor for CPU-bound operations."""
|
|
56
|
+
import asyncio
|
|
57
|
+
|
|
58
|
+
loop = asyncio.get_event_loop()
|
|
59
|
+
return await loop.run_in_executor(None, self.get_embedding_and_usage, text)
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
from dataclasses import dataclass
|
|
2
2
|
from typing import Any, 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:
|
|
8
|
+
from voyageai import AsyncClient as AsyncVoyageClient
|
|
8
9
|
from voyageai import Client as VoyageClient
|
|
9
10
|
from voyageai.object import EmbeddingsObject
|
|
10
11
|
except ImportError:
|
|
@@ -22,6 +23,7 @@ class VoyageAIEmbedder(Embedder):
|
|
|
22
23
|
timeout: Optional[float] = None
|
|
23
24
|
client_params: Optional[Dict[str, Any]] = None
|
|
24
25
|
voyage_client: Optional[VoyageClient] = None
|
|
26
|
+
async_client: Optional[AsyncVoyageClient] = None
|
|
25
27
|
|
|
26
28
|
@property
|
|
27
29
|
def client(self) -> VoyageClient:
|
|
@@ -39,6 +41,22 @@ class VoyageAIEmbedder(Embedder):
|
|
|
39
41
|
self.voyage_client = VoyageClient(**_client_params)
|
|
40
42
|
return self.voyage_client
|
|
41
43
|
|
|
44
|
+
@property
|
|
45
|
+
def aclient(self) -> AsyncVoyageClient:
|
|
46
|
+
if self.async_client:
|
|
47
|
+
return self.async_client
|
|
48
|
+
|
|
49
|
+
_client_params = {
|
|
50
|
+
"api_key": self.api_key,
|
|
51
|
+
"max_retries": self.max_retries,
|
|
52
|
+
"timeout": self.timeout,
|
|
53
|
+
}
|
|
54
|
+
_client_params = {k: v for k, v in _client_params.items() if v is not None}
|
|
55
|
+
if self.client_params:
|
|
56
|
+
_client_params.update(self.client_params)
|
|
57
|
+
self.async_client = AsyncVoyageClient(**_client_params)
|
|
58
|
+
return self.async_client
|
|
59
|
+
|
|
42
60
|
def _response(self, text: str) -> EmbeddingsObject:
|
|
43
61
|
_request_params: Dict[str, Any] = {
|
|
44
62
|
"texts": [text],
|
|
@@ -62,3 +80,33 @@ class VoyageAIEmbedder(Embedder):
|
|
|
62
80
|
embedding = response.embeddings[0]
|
|
63
81
|
usage = {"total_tokens": response.total_tokens}
|
|
64
82
|
return embedding, usage
|
|
83
|
+
|
|
84
|
+
async def _async_response(self, text: str) -> EmbeddingsObject:
|
|
85
|
+
"""Async version of _response using AsyncVoyageClient."""
|
|
86
|
+
_request_params: Dict[str, Any] = {
|
|
87
|
+
"texts": [text],
|
|
88
|
+
"model": self.id,
|
|
89
|
+
}
|
|
90
|
+
if self.request_params:
|
|
91
|
+
_request_params.update(self.request_params)
|
|
92
|
+
return await self.aclient.embed(**_request_params)
|
|
93
|
+
|
|
94
|
+
async def async_get_embedding(self, text: str) -> List[float]:
|
|
95
|
+
"""Async version of get_embedding."""
|
|
96
|
+
try:
|
|
97
|
+
response: EmbeddingsObject = await self._async_response(text=text)
|
|
98
|
+
return response.embeddings[0]
|
|
99
|
+
except Exception as e:
|
|
100
|
+
logger.warning(f"Error getting embedding: {e}")
|
|
101
|
+
return []
|
|
102
|
+
|
|
103
|
+
async def async_get_embedding_and_usage(self, text: str) -> Tuple[List[float], Optional[Dict]]:
|
|
104
|
+
"""Async version of get_embedding_and_usage."""
|
|
105
|
+
try:
|
|
106
|
+
response: EmbeddingsObject = await self._async_response(text=text)
|
|
107
|
+
embedding = response.embeddings[0]
|
|
108
|
+
usage = {"total_tokens": response.total_tokens}
|
|
109
|
+
return embedding, usage
|
|
110
|
+
except Exception as e:
|
|
111
|
+
logger.warning(f"Error getting embedding and usage: {e}")
|
|
112
|
+
return [], None
|