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
|
@@ -2,7 +2,7 @@ from dataclasses import dataclass
|
|
|
2
2
|
from os import getenv
|
|
3
3
|
from typing import Any, Dict, List, Optional, Tuple
|
|
4
4
|
|
|
5
|
-
from agno.embedder.base import Embedder
|
|
5
|
+
from agno.knowledge.embedder.base import Embedder
|
|
6
6
|
from agno.utils.log import log_error, log_info
|
|
7
7
|
|
|
8
8
|
try:
|
|
@@ -56,6 +56,11 @@ class GeminiEmbedder(Embedder):
|
|
|
56
56
|
|
|
57
57
|
return self.gemini_client
|
|
58
58
|
|
|
59
|
+
@property
|
|
60
|
+
def aclient(self) -> GeminiClient:
|
|
61
|
+
"""Returns the same client instance since Google GenAI Client supports both sync and async operations."""
|
|
62
|
+
return self.client
|
|
63
|
+
|
|
59
64
|
def _response(self, text: str) -> EmbedContentResponse:
|
|
60
65
|
# If a user provides a model id with the `models/` prefix, we need to remove it
|
|
61
66
|
_id = self.id
|
|
@@ -105,3 +110,71 @@ class GeminiEmbedder(Embedder):
|
|
|
105
110
|
except Exception as e:
|
|
106
111
|
log_error(f"Error extracting embeddings: {e}")
|
|
107
112
|
return [], usage
|
|
113
|
+
|
|
114
|
+
async def async_get_embedding(self, text: str) -> List[float]:
|
|
115
|
+
"""Async version of get_embedding using client.aio."""
|
|
116
|
+
# If a user provides a model id with the `models/` prefix, we need to remove it
|
|
117
|
+
_id = self.id
|
|
118
|
+
if _id.startswith("models/"):
|
|
119
|
+
_id = _id.split("/")[-1]
|
|
120
|
+
|
|
121
|
+
_request_params: Dict[str, Any] = {"contents": text, "model": _id, "config": {}}
|
|
122
|
+
if self.dimensions:
|
|
123
|
+
_request_params["config"]["output_dimensionality"] = self.dimensions
|
|
124
|
+
if self.task_type:
|
|
125
|
+
_request_params["config"]["task_type"] = self.task_type
|
|
126
|
+
if self.title:
|
|
127
|
+
_request_params["config"]["title"] = self.title
|
|
128
|
+
if not _request_params["config"]:
|
|
129
|
+
del _request_params["config"]
|
|
130
|
+
|
|
131
|
+
if self.request_params:
|
|
132
|
+
_request_params.update(self.request_params)
|
|
133
|
+
|
|
134
|
+
try:
|
|
135
|
+
response = await self.aclient.aio.models.embed_content(**_request_params)
|
|
136
|
+
if response.embeddings and len(response.embeddings) > 0:
|
|
137
|
+
values = response.embeddings[0].values
|
|
138
|
+
if values is not None:
|
|
139
|
+
return values
|
|
140
|
+
log_info("No embeddings found in response")
|
|
141
|
+
return []
|
|
142
|
+
except Exception as e:
|
|
143
|
+
log_error(f"Error extracting embeddings: {e}")
|
|
144
|
+
return []
|
|
145
|
+
|
|
146
|
+
async def async_get_embedding_and_usage(self, text: str) -> Tuple[List[float], Optional[Dict[str, Any]]]:
|
|
147
|
+
"""Async version of get_embedding_and_usage using client.aio."""
|
|
148
|
+
# If a user provides a model id with the `models/` prefix, we need to remove it
|
|
149
|
+
_id = self.id
|
|
150
|
+
if _id.startswith("models/"):
|
|
151
|
+
_id = _id.split("/")[-1]
|
|
152
|
+
|
|
153
|
+
_request_params: Dict[str, Any] = {"contents": text, "model": _id, "config": {}}
|
|
154
|
+
if self.dimensions:
|
|
155
|
+
_request_params["config"]["output_dimensionality"] = self.dimensions
|
|
156
|
+
if self.task_type:
|
|
157
|
+
_request_params["config"]["task_type"] = self.task_type
|
|
158
|
+
if self.title:
|
|
159
|
+
_request_params["config"]["title"] = self.title
|
|
160
|
+
if not _request_params["config"]:
|
|
161
|
+
del _request_params["config"]
|
|
162
|
+
|
|
163
|
+
if self.request_params:
|
|
164
|
+
_request_params.update(self.request_params)
|
|
165
|
+
|
|
166
|
+
try:
|
|
167
|
+
response = await self.aclient.aio.models.embed_content(**_request_params)
|
|
168
|
+
usage = None
|
|
169
|
+
if response.metadata and hasattr(response.metadata, "billable_character_count"):
|
|
170
|
+
usage = {"billable_character_count": response.metadata.billable_character_count}
|
|
171
|
+
|
|
172
|
+
if response.embeddings and len(response.embeddings) > 0:
|
|
173
|
+
values = response.embeddings[0].values
|
|
174
|
+
if values is not None:
|
|
175
|
+
return values, usage
|
|
176
|
+
log_info("No embeddings found in response")
|
|
177
|
+
return [], usage
|
|
178
|
+
except Exception as e:
|
|
179
|
+
log_error(f"Error extracting embeddings: {e}")
|
|
180
|
+
return [], usage
|
|
@@ -2,11 +2,11 @@ from dataclasses import dataclass
|
|
|
2
2
|
from os import getenv
|
|
3
3
|
from typing import Any, Dict, List, Optional, Tuple
|
|
4
4
|
|
|
5
|
-
from agno.embedder.base import Embedder
|
|
5
|
+
from agno.knowledge.embedder.base import Embedder
|
|
6
6
|
from agno.utils.log import logger
|
|
7
7
|
|
|
8
8
|
try:
|
|
9
|
-
from huggingface_hub import InferenceClient
|
|
9
|
+
from huggingface_hub import AsyncInferenceClient, InferenceClient
|
|
10
10
|
except ImportError:
|
|
11
11
|
logger.error("`huggingface-hub` not installed, please run `pip install huggingface-hub`")
|
|
12
12
|
raise
|
|
@@ -20,6 +20,7 @@ class HuggingfaceCustomEmbedder(Embedder):
|
|
|
20
20
|
api_key: Optional[str] = getenv("HUGGINGFACE_API_KEY")
|
|
21
21
|
client_params: Optional[Dict[str, Any]] = None
|
|
22
22
|
huggingface_client: Optional[InferenceClient] = None
|
|
23
|
+
async_client: Optional[AsyncInferenceClient] = None
|
|
23
24
|
|
|
24
25
|
@property
|
|
25
26
|
def client(self) -> InferenceClient:
|
|
@@ -33,6 +34,18 @@ class HuggingfaceCustomEmbedder(Embedder):
|
|
|
33
34
|
self.huggingface_client = InferenceClient(**_client_params)
|
|
34
35
|
return self.huggingface_client
|
|
35
36
|
|
|
37
|
+
@property
|
|
38
|
+
def aclient(self) -> AsyncInferenceClient:
|
|
39
|
+
if self.async_client:
|
|
40
|
+
return self.async_client
|
|
41
|
+
_client_params: Dict[str, Any] = {}
|
|
42
|
+
if self.api_key:
|
|
43
|
+
_client_params["api_key"] = self.api_key
|
|
44
|
+
if self.client_params:
|
|
45
|
+
_client_params.update(self.client_params)
|
|
46
|
+
self.async_client = AsyncInferenceClient(**_client_params)
|
|
47
|
+
return self.async_client
|
|
48
|
+
|
|
36
49
|
def _response(self, text: str):
|
|
37
50
|
return self.client.feature_extraction(text=text, model=self.id)
|
|
38
51
|
|
|
@@ -53,3 +66,24 @@ class HuggingfaceCustomEmbedder(Embedder):
|
|
|
53
66
|
|
|
54
67
|
def get_embedding_and_usage(self, text: str) -> Tuple[List[float], Optional[Dict]]:
|
|
55
68
|
return self.get_embedding(text=text), None
|
|
69
|
+
|
|
70
|
+
async def async_get_embedding(self, text: str) -> List[float]:
|
|
71
|
+
"""Async version of get_embedding using AsyncInferenceClient."""
|
|
72
|
+
response = await self.aclient.feature_extraction(text=text, model=self.id)
|
|
73
|
+
try:
|
|
74
|
+
# If already a list, return directly
|
|
75
|
+
if isinstance(response, list):
|
|
76
|
+
return response
|
|
77
|
+
# If numpy array, convert to list
|
|
78
|
+
elif hasattr(response, "tolist"):
|
|
79
|
+
return response.tolist()
|
|
80
|
+
else:
|
|
81
|
+
return list(response)
|
|
82
|
+
except Exception as e:
|
|
83
|
+
logger.warning(f"Failed to process embeddings: {e}")
|
|
84
|
+
return []
|
|
85
|
+
|
|
86
|
+
async def async_get_embedding_and_usage(self, text: str) -> Tuple[List[float], Optional[Dict]]:
|
|
87
|
+
"""Async version of get_embedding_and_usage."""
|
|
88
|
+
embedding = await self.async_get_embedding(text=text)
|
|
89
|
+
return embedding, None
|
|
@@ -4,13 +4,18 @@ 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
11
|
import requests
|
|
12
12
|
except ImportError:
|
|
13
|
-
raise ImportError("requests not installed, use pip install requests")
|
|
13
|
+
raise ImportError("`requests` not installed, use pip install requests")
|
|
14
|
+
|
|
15
|
+
try:
|
|
16
|
+
import aiohttp
|
|
17
|
+
except ImportError:
|
|
18
|
+
raise ImportError("`aiohttp` not installed, use pip install aiohttp")
|
|
14
19
|
|
|
15
20
|
|
|
16
21
|
@dataclass
|
|
@@ -71,3 +76,44 @@ class JinaEmbedder(Embedder):
|
|
|
71
76
|
except Exception as e:
|
|
72
77
|
logger.warning(f"Failed to get embedding and usage: {e}")
|
|
73
78
|
return [], None
|
|
79
|
+
|
|
80
|
+
async def _async_response(self, text: str) -> Dict[str, Any]:
|
|
81
|
+
"""Async version of _response using aiohttp."""
|
|
82
|
+
data = {
|
|
83
|
+
"model": self.id,
|
|
84
|
+
"late_chunking": self.late_chunking,
|
|
85
|
+
"dimensions": self.dimensions,
|
|
86
|
+
"embedding_type": self.embedding_type,
|
|
87
|
+
"input": [text], # Jina API expects a list
|
|
88
|
+
}
|
|
89
|
+
if self.user is not None:
|
|
90
|
+
data["user"] = self.user
|
|
91
|
+
if self.request_params:
|
|
92
|
+
data.update(self.request_params)
|
|
93
|
+
|
|
94
|
+
timeout = aiohttp.ClientTimeout(total=self.timeout) if self.timeout else None
|
|
95
|
+
|
|
96
|
+
async with aiohttp.ClientSession(timeout=timeout) as session:
|
|
97
|
+
async with session.post(self.base_url, headers=self._get_headers(), json=data) as response:
|
|
98
|
+
response.raise_for_status()
|
|
99
|
+
return await response.json()
|
|
100
|
+
|
|
101
|
+
async def async_get_embedding(self, text: str) -> List[float]:
|
|
102
|
+
"""Async version of get_embedding."""
|
|
103
|
+
try:
|
|
104
|
+
result = await self._async_response(text)
|
|
105
|
+
return result["data"][0]["embedding"]
|
|
106
|
+
except Exception as e:
|
|
107
|
+
logger.warning(f"Failed to get embedding: {e}")
|
|
108
|
+
return []
|
|
109
|
+
|
|
110
|
+
async def async_get_embedding_and_usage(self, text: str) -> Tuple[List[float], Optional[Dict]]:
|
|
111
|
+
"""Async version of get_embedding_and_usage."""
|
|
112
|
+
try:
|
|
113
|
+
result = await self._async_response(text)
|
|
114
|
+
embedding = result["data"][0]["embedding"]
|
|
115
|
+
usage = result.get("usage")
|
|
116
|
+
return embedding, usage
|
|
117
|
+
except Exception as e:
|
|
118
|
+
logger.warning(f"Failed to get embedding and usage: {e}")
|
|
119
|
+
return [], None
|
|
@@ -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
|