agno 1.7.9__tar.gz → 1.7.10__tar.gz
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-1.7.9 → agno-1.7.10}/PKG-INFO +2 -1
- {agno-1.7.9 → agno-1.7.10}/agno/agent/agent.py +1 -1
- {agno-1.7.9 → agno-1.7.10}/agno/document/reader/pdf_reader.py +69 -13
- {agno-1.7.9 → agno-1.7.10}/agno/knowledge/agent.py +68 -72
- {agno-1.7.9 → agno-1.7.10}/agno/knowledge/pdf.py +32 -8
- {agno-1.7.9 → agno-1.7.10}/agno/knowledge/pdf_url.py +13 -5
- {agno-1.7.9 → agno-1.7.10}/agno/models/openai/responses.py +30 -1
- {agno-1.7.9 → agno-1.7.10}/agno/team/team.py +15 -7
- {agno-1.7.9 → agno-1.7.10}/agno/tools/github.py +54 -18
- {agno-1.7.9 → agno-1.7.10}/agno/vectordb/weaviate/weaviate.py +84 -18
- {agno-1.7.9 → agno-1.7.10}/agno.egg-info/PKG-INFO +2 -1
- {agno-1.7.9 → agno-1.7.10}/agno.egg-info/requires.txt +1 -0
- {agno-1.7.9 → agno-1.7.10}/pyproject.toml +2 -1
- {agno-1.7.9 → agno-1.7.10}/LICENSE +0 -0
- {agno-1.7.9 → agno-1.7.10}/README.md +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/agent/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/agent/metrics.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/api/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/api/agent.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/api/api.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/api/app.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/api/evals.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/api/playground.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/api/routes.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/api/schemas/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/api/schemas/agent.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/api/schemas/app.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/api/schemas/evals.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/api/schemas/playground.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/api/schemas/response.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/api/schemas/team.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/api/schemas/user.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/api/schemas/workflows.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/api/schemas/workspace.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/api/team.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/api/user.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/api/workflows.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/api/workspace.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/app/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/app/agui/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/app/agui/app.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/app/agui/async_router.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/app/agui/sync_router.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/app/agui/utils.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/app/base.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/app/discord/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/app/discord/client.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/app/fastapi/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/app/fastapi/app.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/app/fastapi/async_router.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/app/fastapi/sync_router.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/app/playground/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/app/playground/app.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/app/playground/async_router.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/app/playground/deploy.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/app/playground/operator.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/app/playground/schemas.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/app/playground/serve.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/app/playground/settings.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/app/playground/sync_router.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/app/playground/utils.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/app/settings.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/app/slack/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/app/slack/app.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/app/slack/async_router.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/app/slack/security.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/app/slack/sync_router.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/app/utils.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/app/whatsapp/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/app/whatsapp/app.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/app/whatsapp/async_router.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/app/whatsapp/security.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/app/whatsapp/sync_router.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/cli/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/cli/auth_server.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/cli/config.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/cli/console.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/cli/credentials.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/cli/entrypoint.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/cli/operator.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/cli/settings.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/cli/ws/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/cli/ws/ws_cli.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/constants.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/debug.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/document/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/document/base.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/document/chunking/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/document/chunking/agentic.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/document/chunking/document.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/document/chunking/fixed.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/document/chunking/markdown.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/document/chunking/recursive.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/document/chunking/row.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/document/chunking/semantic.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/document/chunking/strategy.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/document/reader/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/document/reader/arxiv_reader.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/document/reader/base.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/document/reader/csv_reader.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/document/reader/docx_reader.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/document/reader/firecrawl_reader.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/document/reader/gcs/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/document/reader/gcs/pdf_reader.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/document/reader/json_reader.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/document/reader/markdown_reader.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/document/reader/s3/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/document/reader/s3/pdf_reader.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/document/reader/s3/text_reader.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/document/reader/text_reader.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/document/reader/url_reader.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/document/reader/website_reader.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/document/reader/youtube_reader.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/embedder/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/embedder/aws_bedrock.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/embedder/azure_openai.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/embedder/base.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/embedder/cohere.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/embedder/fastembed.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/embedder/fireworks.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/embedder/google.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/embedder/huggingface.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/embedder/jina.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/embedder/langdb.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/embedder/mistral.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/embedder/nebius.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/embedder/ollama.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/embedder/openai.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/embedder/sentence_transformer.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/embedder/together.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/embedder/voyageai.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/eval/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/eval/accuracy.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/eval/performance.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/eval/reliability.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/eval/utils.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/exceptions.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/file/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/file/file.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/file/local/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/file/local/csv.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/file/local/txt.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/infra/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/infra/app.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/infra/base.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/infra/context.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/infra/db_app.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/infra/resource.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/infra/resources.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/knowledge/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/knowledge/arxiv.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/knowledge/combined.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/knowledge/csv.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/knowledge/csv_url.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/knowledge/document.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/knowledge/docx.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/knowledge/firecrawl.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/knowledge/gcs/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/knowledge/gcs/base.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/knowledge/gcs/pdf.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/knowledge/json.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/knowledge/langchain.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/knowledge/light_rag.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/knowledge/llamaindex.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/knowledge/markdown.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/knowledge/pdf_bytes.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/knowledge/s3/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/knowledge/s3/base.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/knowledge/s3/pdf.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/knowledge/s3/text.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/knowledge/text.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/knowledge/url.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/knowledge/website.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/knowledge/wikipedia.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/knowledge/youtube.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/media.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/memory/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/memory/agent.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/memory/classifier.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/memory/db/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/memory/db/base.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/memory/db/mongodb.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/memory/db/postgres.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/memory/db/sqlite.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/memory/manager.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/memory/memory.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/memory/row.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/memory/summarizer.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/memory/summary.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/memory/team.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/memory/v2/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/memory/v2/db/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/memory/v2/db/base.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/memory/v2/db/firestore.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/memory/v2/db/mongodb.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/memory/v2/db/postgres.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/memory/v2/db/redis.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/memory/v2/db/schema.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/memory/v2/db/sqlite.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/memory/v2/manager.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/memory/v2/memory.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/memory/v2/schema.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/memory/v2/summarizer.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/memory/workflow.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/aimlapi/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/aimlapi/aimlapi.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/anthropic/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/anthropic/claude.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/aws/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/aws/bedrock.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/aws/claude.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/azure/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/azure/ai_foundry.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/azure/openai_chat.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/base.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/cerebras/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/cerebras/cerebras.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/cerebras/cerebras_openai.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/cohere/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/cohere/chat.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/deepinfra/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/deepinfra/deepinfra.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/deepseek/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/deepseek/deepseek.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/defaults.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/fireworks/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/fireworks/fireworks.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/google/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/google/gemini.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/groq/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/groq/groq.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/huggingface/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/huggingface/huggingface.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/ibm/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/ibm/watsonx.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/internlm/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/internlm/internlm.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/langdb/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/langdb/langdb.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/litellm/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/litellm/chat.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/litellm/litellm_openai.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/lmstudio/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/lmstudio/lmstudio.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/message.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/meta/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/meta/llama.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/meta/llama_openai.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/mistral/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/mistral/mistral.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/nebius/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/nebius/nebius.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/nvidia/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/nvidia/nvidia.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/ollama/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/ollama/chat.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/ollama/tools.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/openai/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/openai/chat.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/openai/like.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/openrouter/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/openrouter/openrouter.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/perplexity/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/perplexity/perplexity.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/portkey/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/portkey/portkey.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/response.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/sambanova/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/sambanova/sambanova.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/together/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/together/together.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/vercel/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/vercel/v0.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/vllm/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/vllm/vllm.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/xai/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/models/xai/xai.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/playground/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/playground/deploy.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/playground/playground.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/playground/serve.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/playground/settings.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/py.typed +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/reasoning/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/reasoning/azure_ai_foundry.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/reasoning/deepseek.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/reasoning/default.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/reasoning/groq.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/reasoning/helpers.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/reasoning/ollama.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/reasoning/openai.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/reasoning/step.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/reranker/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/reranker/base.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/reranker/cohere.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/reranker/infinity.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/reranker/sentence_transformer.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/run/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/run/base.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/run/messages.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/run/response.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/run/team.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/run/v2/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/run/v2/workflow.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/run/workflow.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/storage/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/storage/agent/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/storage/agent/dynamodb.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/storage/agent/json.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/storage/agent/mongodb.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/storage/agent/postgres.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/storage/agent/singlestore.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/storage/agent/sqlite.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/storage/agent/yaml.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/storage/base.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/storage/dynamodb.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/storage/firestore.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/storage/gcs_json.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/storage/json.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/storage/mongodb.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/storage/mysql.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/storage/postgres.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/storage/redis.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/storage/session/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/storage/session/agent.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/storage/session/team.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/storage/session/v2/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/storage/session/v2/workflow.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/storage/session/workflow.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/storage/singlestore.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/storage/sqlite.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/storage/workflow/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/storage/workflow/mongodb.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/storage/workflow/postgres.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/storage/workflow/sqlite.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/storage/yaml.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/team/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/agentql.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/airflow.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/api.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/apify.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/arxiv.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/aws_lambda.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/aws_ses.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/baidusearch.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/bitbucket.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/bravesearch.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/brightdata.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/browserbase.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/calcom.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/calculator.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/cartesia.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/clickup_tool.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/confluence.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/crawl4ai.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/csv_toolkit.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/dalle.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/daytona.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/decorator.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/desi_vocal.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/discord.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/docker.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/duckdb.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/duckduckgo.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/e2b.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/eleven_labs.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/email.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/evm.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/exa.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/fal.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/file.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/financial_datasets.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/firecrawl.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/function.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/giphy.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/gmail.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/google_bigquery.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/google_maps.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/googlecalendar.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/googlesearch.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/googlesheets.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/hackernews.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/jina.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/jira.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/knowledge.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/linear.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/linkup.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/local_file_system.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/lumalab.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/mcp.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/mem0.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/mlx_transcribe.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/models/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/models/azure_openai.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/models/gemini.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/models/groq.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/models/morph.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/models/nebius.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/models_labs.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/moviepy_video.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/newspaper.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/newspaper4k.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/openai.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/openbb.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/opencv.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/openweather.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/oxylabs.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/pandas.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/postgres.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/pubmed.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/python.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/reasoning.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/reddit.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/replicate.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/resend.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/scrapegraph.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/searxng.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/serpapi.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/serper.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/shell.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/slack.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/sleep.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/spider.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/sql.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/streamlit/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/streamlit/components.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/tavily.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/telegram.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/thinking.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/todoist.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/tool_registry.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/toolkit.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/trello.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/twilio.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/user_control_flow.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/valyu.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/visualization.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/webbrowser.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/webex.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/website.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/webtools.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/whatsapp.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/wikipedia.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/x.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/yfinance.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/youtube.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/zendesk.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/zep.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/tools/zoom.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/utils/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/utils/audio.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/utils/certs.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/utils/code_execution.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/utils/common.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/utils/defaults.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/utils/dttm.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/utils/enum.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/utils/env.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/utils/events.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/utils/filesystem.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/utils/format_str.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/utils/functions.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/utils/gemini.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/utils/git.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/utils/http.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/utils/json_io.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/utils/json_schema.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/utils/load_env.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/utils/location.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/utils/log.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/utils/mcp.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/utils/media.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/utils/merge_dict.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/utils/message.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/utils/models/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/utils/models/ai_foundry.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/utils/models/aws_claude.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/utils/models/claude.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/utils/models/cohere.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/utils/models/llama.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/utils/models/mistral.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/utils/models/openai_responses.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/utils/models/schema_utils.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/utils/models/watsonx.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/utils/openai.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/utils/pickle.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/utils/pprint.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/utils/prompts.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/utils/py_io.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/utils/pyproject.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/utils/resource_filter.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/utils/response.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/utils/response_iterator.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/utils/safe_formatter.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/utils/shell.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/utils/string.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/utils/timer.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/utils/tools.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/utils/web.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/utils/whatsapp.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/utils/yaml_io.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/vectordb/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/vectordb/base.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/vectordb/cassandra/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/vectordb/cassandra/cassandra.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/vectordb/cassandra/extra_param_mixin.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/vectordb/cassandra/index.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/vectordb/chroma/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/vectordb/chroma/chromadb.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/vectordb/clickhouse/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/vectordb/clickhouse/clickhousedb.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/vectordb/clickhouse/index.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/vectordb/couchbase/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/vectordb/couchbase/couchbase.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/vectordb/distance.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/vectordb/lancedb/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/vectordb/lancedb/lance_db.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/vectordb/milvus/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/vectordb/milvus/milvus.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/vectordb/mongodb/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/vectordb/mongodb/mongodb.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/vectordb/pgvector/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/vectordb/pgvector/index.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/vectordb/pgvector/pgvector.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/vectordb/pineconedb/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/vectordb/pineconedb/pineconedb.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/vectordb/qdrant/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/vectordb/qdrant/qdrant.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/vectordb/search.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/vectordb/singlestore/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/vectordb/singlestore/index.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/vectordb/singlestore/singlestore.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/vectordb/surrealdb/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/vectordb/surrealdb/surrealdb.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/vectordb/upstashdb/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/vectordb/upstashdb/upstashdb.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/vectordb/weaviate/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/vectordb/weaviate/index.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/workflow/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/workflow/v2/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/workflow/v2/condition.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/workflow/v2/loop.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/workflow/v2/parallel.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/workflow/v2/router.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/workflow/v2/step.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/workflow/v2/steps.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/workflow/v2/types.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/workflow/v2/workflow.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/workflow/workflow.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/workspace/__init__.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/workspace/config.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/workspace/enums.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/workspace/helpers.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/workspace/operator.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno/workspace/settings.py +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno.egg-info/SOURCES.txt +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno.egg-info/dependency_links.txt +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno.egg-info/entry_points.txt +0 -0
- {agno-1.7.9 → agno-1.7.10}/agno.egg-info/top_level.txt +0 -0
- {agno-1.7.9 → agno-1.7.10}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agno
|
|
3
|
-
Version: 1.7.
|
|
3
|
+
Version: 1.7.10
|
|
4
4
|
Summary: Agno: a lightweight library for building Multi-Agent Systems
|
|
5
5
|
Author-email: Ashpreet Bedi <ashpreet@agno.com>
|
|
6
6
|
License: Copyright (c) Agno, Inc.
|
|
@@ -400,6 +400,7 @@ License-File: LICENSE
|
|
|
400
400
|
Requires-Dist: docstring-parser
|
|
401
401
|
Requires-Dist: gitpython
|
|
402
402
|
Requires-Dist: httpx
|
|
403
|
+
Requires-Dist: packaging
|
|
403
404
|
Requires-Dist: pydantic-settings
|
|
404
405
|
Requires-Dist: pydantic
|
|
405
406
|
Requires-Dist: python-dotenv
|
|
@@ -6872,7 +6872,7 @@ class Agent:
|
|
|
6872
6872
|
document_name = query.replace(" ", "_").replace("?", "").replace("!", "").replace(".", "")
|
|
6873
6873
|
document_content = json.dumps({"query": query, "result": result})
|
|
6874
6874
|
log_info(f"Adding document to knowledge base: {document_name}: {document_content}")
|
|
6875
|
-
self.knowledge.
|
|
6875
|
+
self.knowledge.load_document(
|
|
6876
6876
|
document=Document(
|
|
6877
6877
|
name=document_name,
|
|
6878
6878
|
content=document_content,
|
|
@@ -7,7 +7,7 @@ from uuid import uuid4
|
|
|
7
7
|
from agno.document.base import Document
|
|
8
8
|
from agno.document.reader.base import Reader
|
|
9
9
|
from agno.utils.http import async_fetch_with_retry, fetch_with_retry
|
|
10
|
-
from agno.utils.log import log_info, logger
|
|
10
|
+
from agno.utils.log import log_error, log_info, logger
|
|
11
11
|
|
|
12
12
|
try:
|
|
13
13
|
from pypdf import PdfReader as DocumentReader # noqa: F401
|
|
@@ -177,6 +177,7 @@ class BasePDFReader(Reader):
|
|
|
177
177
|
split_on_pages: bool = True,
|
|
178
178
|
page_start_numbering_format: Optional[str] = None,
|
|
179
179
|
page_end_numbering_format: Optional[str] = None,
|
|
180
|
+
password: Optional[str] = None,
|
|
180
181
|
**kwargs,
|
|
181
182
|
):
|
|
182
183
|
if page_start_numbering_format is None:
|
|
@@ -187,6 +188,7 @@ class BasePDFReader(Reader):
|
|
|
187
188
|
self.split_on_pages = split_on_pages
|
|
188
189
|
self.page_start_numbering_format = page_start_numbering_format
|
|
189
190
|
self.page_end_numbering_format = page_end_numbering_format
|
|
191
|
+
self.password = password
|
|
190
192
|
|
|
191
193
|
super().__init__(**kwargs)
|
|
192
194
|
|
|
@@ -196,6 +198,28 @@ class BasePDFReader(Reader):
|
|
|
196
198
|
chunked_documents.extend(self.chunk_document(document))
|
|
197
199
|
return chunked_documents
|
|
198
200
|
|
|
201
|
+
def _decrypt_pdf(self, doc_reader: DocumentReader, doc_name: str, password: Optional[str] = None) -> bool:
|
|
202
|
+
if not doc_reader.is_encrypted:
|
|
203
|
+
return True
|
|
204
|
+
|
|
205
|
+
# Use provided password or fall back to instance password
|
|
206
|
+
pdf_password = password or self.password
|
|
207
|
+
if not pdf_password:
|
|
208
|
+
logger.error(f"PDF {doc_name} is password protected but no password provided")
|
|
209
|
+
return False
|
|
210
|
+
|
|
211
|
+
try:
|
|
212
|
+
decrypted_pdf = doc_reader.decrypt(pdf_password)
|
|
213
|
+
if decrypted_pdf:
|
|
214
|
+
log_info(f"Successfully decrypted PDF {doc_name} with user password")
|
|
215
|
+
return True
|
|
216
|
+
else:
|
|
217
|
+
log_error(f"Failed to decrypt PDF {doc_name}: incorrect password")
|
|
218
|
+
return False
|
|
219
|
+
except Exception as e:
|
|
220
|
+
log_error(f"Error decrypting PDF {doc_name}: {e}")
|
|
221
|
+
return False
|
|
222
|
+
|
|
199
223
|
def _create_documents(self, pdf_content: List[str], doc_name: str, use_uuid_for_id: bool, page_number_shift):
|
|
200
224
|
if self.split_on_pages:
|
|
201
225
|
shift = page_number_shift if page_number_shift is not None else 1
|
|
@@ -282,7 +306,7 @@ class BasePDFReader(Reader):
|
|
|
282
306
|
class PDFReader(BasePDFReader):
|
|
283
307
|
"""Reader for PDF files"""
|
|
284
308
|
|
|
285
|
-
def read(self, pdf: Union[str, Path, IO[Any]]) -> List[Document]:
|
|
309
|
+
def read(self, pdf: Union[str, Path, IO[Any]], password: Optional[str] = None) -> List[Document]:
|
|
286
310
|
try:
|
|
287
311
|
if isinstance(pdf, str):
|
|
288
312
|
doc_name = pdf.split("/")[-1].split(".")[0].replace(" ", "_")
|
|
@@ -299,10 +323,14 @@ class PDFReader(BasePDFReader):
|
|
|
299
323
|
logger.error(f"Error reading PDF: {e}")
|
|
300
324
|
return []
|
|
301
325
|
|
|
326
|
+
# Handle PDF decryption
|
|
327
|
+
if not self._decrypt_pdf(pdf_reader, doc_name, password):
|
|
328
|
+
return []
|
|
329
|
+
|
|
302
330
|
# Read and chunk.
|
|
303
331
|
return self._pdf_reader_to_documents(pdf_reader, doc_name, use_uuid_for_id=True)
|
|
304
332
|
|
|
305
|
-
async def async_read(self, pdf: Union[str, Path, IO[Any]]) -> List[Document]:
|
|
333
|
+
async def async_read(self, pdf: Union[str, Path, IO[Any]], password: Optional[str] = None) -> List[Document]:
|
|
306
334
|
try:
|
|
307
335
|
if isinstance(pdf, str):
|
|
308
336
|
doc_name = pdf.split("/")[-1].split(".")[0].replace(" ", "_")
|
|
@@ -319,6 +347,10 @@ class PDFReader(BasePDFReader):
|
|
|
319
347
|
logger.error(f"Error reading PDF: {e}")
|
|
320
348
|
return []
|
|
321
349
|
|
|
350
|
+
# Handle PDF decryption
|
|
351
|
+
if not self._decrypt_pdf(pdf_reader, doc_name, password):
|
|
352
|
+
return []
|
|
353
|
+
|
|
322
354
|
# Read and chunk.
|
|
323
355
|
return await self._async_pdf_reader_to_documents(pdf_reader, doc_name, use_uuid_for_id=True)
|
|
324
356
|
|
|
@@ -326,11 +358,11 @@ class PDFReader(BasePDFReader):
|
|
|
326
358
|
class PDFUrlReader(BasePDFReader):
|
|
327
359
|
"""Reader for PDF files from URL"""
|
|
328
360
|
|
|
329
|
-
def __init__(self, proxy: Optional[str] = None, **kwargs):
|
|
330
|
-
super().__init__(**kwargs)
|
|
361
|
+
def __init__(self, proxy: Optional[str] = None, password: Optional[str] = None, **kwargs):
|
|
362
|
+
super().__init__(password=password, **kwargs)
|
|
331
363
|
self.proxy = proxy
|
|
332
364
|
|
|
333
|
-
def read(self, url: str) -> List[Document]:
|
|
365
|
+
def read(self, url: str, password: Optional[str] = None) -> List[Document]:
|
|
334
366
|
if not url:
|
|
335
367
|
raise ValueError("No url provided")
|
|
336
368
|
|
|
@@ -344,10 +376,14 @@ class PDFUrlReader(BasePDFReader):
|
|
|
344
376
|
doc_name = url.split("/")[-1].split(".")[0].replace("/", "_").replace(" ", "_")
|
|
345
377
|
pdf_reader = DocumentReader(BytesIO(response.content))
|
|
346
378
|
|
|
379
|
+
# Handle PDF decryption
|
|
380
|
+
if not self._decrypt_pdf(pdf_reader, doc_name, password):
|
|
381
|
+
return []
|
|
382
|
+
|
|
347
383
|
# Read and chunk.
|
|
348
384
|
return self._pdf_reader_to_documents(pdf_reader, doc_name, use_uuid_for_id=False)
|
|
349
385
|
|
|
350
|
-
async def async_read(self, url: str) -> List[Document]:
|
|
386
|
+
async def async_read(self, url: str, password: Optional[str] = None) -> List[Document]:
|
|
351
387
|
if not url:
|
|
352
388
|
raise ValueError("No url provided")
|
|
353
389
|
|
|
@@ -364,6 +400,10 @@ class PDFUrlReader(BasePDFReader):
|
|
|
364
400
|
doc_name = url.split("/")[-1].split(".")[0].replace("/", "_").replace(" ", "_")
|
|
365
401
|
pdf_reader = DocumentReader(BytesIO(response.content))
|
|
366
402
|
|
|
403
|
+
# Handle PDF decryption
|
|
404
|
+
if not self._decrypt_pdf(pdf_reader, doc_name, password):
|
|
405
|
+
return []
|
|
406
|
+
|
|
367
407
|
# Read and chunk.
|
|
368
408
|
return await self._async_pdf_reader_to_documents(pdf_reader, doc_name, use_uuid_for_id=False)
|
|
369
409
|
|
|
@@ -371,7 +411,7 @@ class PDFUrlReader(BasePDFReader):
|
|
|
371
411
|
class PDFImageReader(BasePDFReader):
|
|
372
412
|
"""Reader for PDF files with text and images extraction"""
|
|
373
413
|
|
|
374
|
-
def read(self, pdf: Union[str, Path, IO[Any]]) -> List[Document]:
|
|
414
|
+
def read(self, pdf: Union[str, Path, IO[Any]], password: Optional[str] = None) -> List[Document]:
|
|
375
415
|
if not pdf:
|
|
376
416
|
raise ValueError("No pdf provided")
|
|
377
417
|
|
|
@@ -386,10 +426,14 @@ class PDFImageReader(BasePDFReader):
|
|
|
386
426
|
log_info(f"Reading: {doc_name}")
|
|
387
427
|
pdf_reader = DocumentReader(pdf)
|
|
388
428
|
|
|
429
|
+
# Handle PDF decryption
|
|
430
|
+
if not self._decrypt_pdf(pdf_reader, doc_name, password):
|
|
431
|
+
return []
|
|
432
|
+
|
|
389
433
|
# Read and chunk.
|
|
390
434
|
return self._pdf_reader_to_documents(pdf_reader, doc_name, read_images=True, use_uuid_for_id=False)
|
|
391
435
|
|
|
392
|
-
async def async_read(self, pdf: Union[str, Path, IO[Any]]) -> List[Document]:
|
|
436
|
+
async def async_read(self, pdf: Union[str, Path, IO[Any]], password: Optional[str] = None) -> List[Document]:
|
|
393
437
|
if not pdf:
|
|
394
438
|
raise ValueError("No pdf provided")
|
|
395
439
|
|
|
@@ -404,6 +448,10 @@ class PDFImageReader(BasePDFReader):
|
|
|
404
448
|
log_info(f"Reading: {doc_name}")
|
|
405
449
|
pdf_reader = DocumentReader(pdf)
|
|
406
450
|
|
|
451
|
+
# Handle PDF decryption
|
|
452
|
+
if not self._decrypt_pdf(pdf_reader, doc_name, password):
|
|
453
|
+
return []
|
|
454
|
+
|
|
407
455
|
# Read and chunk.
|
|
408
456
|
return await self._async_pdf_reader_to_documents(pdf_reader, doc_name, read_images=True, use_uuid_for_id=False)
|
|
409
457
|
|
|
@@ -411,11 +459,11 @@ class PDFImageReader(BasePDFReader):
|
|
|
411
459
|
class PDFUrlImageReader(BasePDFReader):
|
|
412
460
|
"""Reader for PDF files from URL with text and images extraction"""
|
|
413
461
|
|
|
414
|
-
def __init__(self, proxy: Optional[str] = None, **kwargs):
|
|
415
|
-
super().__init__(**kwargs)
|
|
462
|
+
def __init__(self, proxy: Optional[str] = None, password: Optional[str] = None, **kwargs):
|
|
463
|
+
super().__init__(password=password, **kwargs)
|
|
416
464
|
self.proxy = proxy
|
|
417
465
|
|
|
418
|
-
def read(self, url: str) -> List[Document]:
|
|
466
|
+
def read(self, url: str, password: Optional[str] = None) -> List[Document]:
|
|
419
467
|
if not url:
|
|
420
468
|
raise ValueError("No url provided")
|
|
421
469
|
|
|
@@ -430,10 +478,14 @@ class PDFUrlImageReader(BasePDFReader):
|
|
|
430
478
|
doc_name = url.split("/")[-1].split(".")[0].replace(" ", "_")
|
|
431
479
|
pdf_reader = DocumentReader(BytesIO(response.content))
|
|
432
480
|
|
|
481
|
+
# Handle PDF decryption
|
|
482
|
+
if not self._decrypt_pdf(pdf_reader, doc_name, password):
|
|
483
|
+
return []
|
|
484
|
+
|
|
433
485
|
# Read and chunk.
|
|
434
486
|
return self._pdf_reader_to_documents(pdf_reader, doc_name, read_images=True, use_uuid_for_id=False)
|
|
435
487
|
|
|
436
|
-
async def async_read(self, url: str) -> List[Document]:
|
|
488
|
+
async def async_read(self, url: str, password: Optional[str] = None) -> List[Document]:
|
|
437
489
|
if not url:
|
|
438
490
|
raise ValueError("No url provided")
|
|
439
491
|
|
|
@@ -451,5 +503,9 @@ class PDFUrlImageReader(BasePDFReader):
|
|
|
451
503
|
doc_name = url.split("/")[-1].split(".")[0].replace(" ", "_")
|
|
452
504
|
pdf_reader = DocumentReader(BytesIO(response.content))
|
|
453
505
|
|
|
506
|
+
# Handle PDF decryption
|
|
507
|
+
if not self._decrypt_pdf(pdf_reader, doc_name, password):
|
|
508
|
+
return []
|
|
509
|
+
|
|
454
510
|
# Read and chunk.
|
|
455
511
|
return await self._async_pdf_reader_to_documents(pdf_reader, doc_name, read_images=True, use_uuid_for_id=False)
|
|
@@ -50,6 +50,53 @@ class AgentKnowledge(BaseModel):
|
|
|
50
50
|
"""
|
|
51
51
|
raise NotImplementedError
|
|
52
52
|
|
|
53
|
+
def _upsert_warning(self, upsert) -> None:
|
|
54
|
+
"""Log a warning if upsert is not available"""
|
|
55
|
+
if upsert and self.vector_db is not None and not self.vector_db.upsert_available():
|
|
56
|
+
log_info(
|
|
57
|
+
f"Vector db '{self.vector_db.__class__.__module__}' does not support upsert. Falling back to insert."
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
def _load_init(self, recreate: bool, upsert: bool) -> None:
|
|
61
|
+
"""Initial setup for loading knowledge base"""
|
|
62
|
+
if self.vector_db is None:
|
|
63
|
+
logger.warning("No vector db provided")
|
|
64
|
+
return
|
|
65
|
+
|
|
66
|
+
if recreate:
|
|
67
|
+
log_info("Dropping collection")
|
|
68
|
+
self.vector_db.drop()
|
|
69
|
+
|
|
70
|
+
if not self.vector_db.exists():
|
|
71
|
+
log_info("Creating collection")
|
|
72
|
+
self.vector_db.create()
|
|
73
|
+
|
|
74
|
+
self._upsert_warning(upsert)
|
|
75
|
+
|
|
76
|
+
async def _aload_init(self, recreate: bool, upsert: bool) -> None:
|
|
77
|
+
"""Initial async setup for loading knowledge base"""
|
|
78
|
+
if self.vector_db is None:
|
|
79
|
+
logger.warning("No vector db provided")
|
|
80
|
+
return
|
|
81
|
+
|
|
82
|
+
if recreate:
|
|
83
|
+
log_info("Dropping collection")
|
|
84
|
+
try:
|
|
85
|
+
await self.vector_db.async_drop()
|
|
86
|
+
except NotImplementedError:
|
|
87
|
+
logger.warning("Vector db does not support async drop, falling back to sync drop")
|
|
88
|
+
self.vector_db.drop()
|
|
89
|
+
|
|
90
|
+
if not self.vector_db.exists():
|
|
91
|
+
log_info("Creating collection")
|
|
92
|
+
try:
|
|
93
|
+
await self.vector_db.async_create()
|
|
94
|
+
except NotImplementedError:
|
|
95
|
+
logger.warning("Vector db does not support async create, falling back to sync create")
|
|
96
|
+
self.vector_db.create()
|
|
97
|
+
|
|
98
|
+
self._upsert_warning(upsert)
|
|
99
|
+
|
|
53
100
|
def search(
|
|
54
101
|
self, query: str, num_documents: Optional[int] = None, filters: Optional[Dict[str, Any]] = None
|
|
55
102
|
) -> List[Document]:
|
|
@@ -80,7 +127,7 @@ class AgentKnowledge(BaseModel):
|
|
|
80
127
|
try:
|
|
81
128
|
return await self.vector_db.async_search(query=query, limit=_num_documents, filters=filters)
|
|
82
129
|
except NotImplementedError:
|
|
83
|
-
|
|
130
|
+
log_info("Vector db does not support async search")
|
|
84
131
|
return self.search(query=query, num_documents=_num_documents, filters=filters)
|
|
85
132
|
except Exception as e:
|
|
86
133
|
logger.error(f"Error searching for documents: {e}")
|
|
@@ -99,18 +146,10 @@ class AgentKnowledge(BaseModel):
|
|
|
99
146
|
upsert (bool): If True, upserts documents to the vector db. Defaults to False.
|
|
100
147
|
skip_existing (bool): If True, skips documents which already exist in the vector db when inserting. Defaults to True.
|
|
101
148
|
"""
|
|
149
|
+
self._load_init(recreate, upsert)
|
|
102
150
|
if self.vector_db is None:
|
|
103
|
-
logger.warning("No vector db provided")
|
|
104
151
|
return
|
|
105
152
|
|
|
106
|
-
if recreate:
|
|
107
|
-
log_info("Dropping collection")
|
|
108
|
-
self.vector_db.drop()
|
|
109
|
-
|
|
110
|
-
if not self.vector_db.exists():
|
|
111
|
-
log_info("Creating collection")
|
|
112
|
-
self.vector_db.create()
|
|
113
|
-
|
|
114
153
|
log_info("Loading knowledge base")
|
|
115
154
|
num_documents = 0
|
|
116
155
|
for document_list in self.document_lists:
|
|
@@ -123,8 +162,7 @@ class AgentKnowledge(BaseModel):
|
|
|
123
162
|
|
|
124
163
|
# Upsert documents if upsert is True and vector db supports upsert
|
|
125
164
|
if upsert and self.vector_db.upsert_available():
|
|
126
|
-
|
|
127
|
-
self.vector_db.upsert(documents=[doc], filters=doc.meta_data)
|
|
165
|
+
self.vector_db.upsert(documents=documents_to_load, filters=doc.meta_data)
|
|
128
166
|
# Insert documents
|
|
129
167
|
else:
|
|
130
168
|
# Filter out documents which already exist in the vector db
|
|
@@ -133,11 +171,10 @@ class AgentKnowledge(BaseModel):
|
|
|
133
171
|
documents_to_load = self.filter_existing_documents(document_list)
|
|
134
172
|
|
|
135
173
|
if documents_to_load:
|
|
136
|
-
|
|
137
|
-
self.vector_db.insert(documents=[doc], filters=doc.meta_data)
|
|
174
|
+
self.vector_db.insert(documents=documents_to_load, filters=doc.meta_data)
|
|
138
175
|
|
|
139
176
|
num_documents += len(documents_to_load)
|
|
140
|
-
|
|
177
|
+
log_info(f"Added {num_documents} documents to knowledge base")
|
|
141
178
|
|
|
142
179
|
async def aload(
|
|
143
180
|
self,
|
|
@@ -152,19 +189,10 @@ class AgentKnowledge(BaseModel):
|
|
|
152
189
|
upsert (bool): If True, upserts documents to the vector db. Defaults to False.
|
|
153
190
|
skip_existing (bool): If True, skips documents which already exist in the vector db when inserting. Defaults to True.
|
|
154
191
|
"""
|
|
155
|
-
|
|
192
|
+
await self._aload_init(recreate, upsert)
|
|
156
193
|
if self.vector_db is None:
|
|
157
|
-
logger.warning("No vector db provided")
|
|
158
194
|
return
|
|
159
195
|
|
|
160
|
-
if recreate:
|
|
161
|
-
log_info("Dropping collection")
|
|
162
|
-
await self.vector_db.async_drop()
|
|
163
|
-
|
|
164
|
-
if not await self.vector_db.async_exists():
|
|
165
|
-
log_info("Creating collection")
|
|
166
|
-
await self.vector_db.async_create()
|
|
167
|
-
|
|
168
196
|
log_info("Loading knowledge base")
|
|
169
197
|
num_documents = 0
|
|
170
198
|
document_iterator = self.async_document_lists
|
|
@@ -177,8 +205,7 @@ class AgentKnowledge(BaseModel):
|
|
|
177
205
|
|
|
178
206
|
# Upsert documents if upsert is True and vector db supports upsert
|
|
179
207
|
if upsert and self.vector_db.upsert_available():
|
|
180
|
-
|
|
181
|
-
await self.vector_db.async_upsert(documents=[doc], filters=doc.meta_data)
|
|
208
|
+
await self.vector_db.async_upsert(documents=documents_to_load, filters=doc.meta_data)
|
|
182
209
|
# Insert documents
|
|
183
210
|
else:
|
|
184
211
|
# Filter out documents which already exist in the vector db
|
|
@@ -187,11 +214,10 @@ class AgentKnowledge(BaseModel):
|
|
|
187
214
|
documents_to_load = await self.async_filter_existing_documents(document_list)
|
|
188
215
|
|
|
189
216
|
if documents_to_load:
|
|
190
|
-
|
|
191
|
-
await self.vector_db.async_insert(documents=[doc], filters=doc.meta_data)
|
|
217
|
+
await self.vector_db.async_insert(documents=documents_to_load, filters=doc.meta_data)
|
|
192
218
|
|
|
193
219
|
num_documents += len(documents_to_load)
|
|
194
|
-
|
|
220
|
+
log_info(f"Added {num_documents} documents to knowledge base")
|
|
195
221
|
|
|
196
222
|
def load_documents(
|
|
197
223
|
self,
|
|
@@ -208,15 +234,11 @@ class AgentKnowledge(BaseModel):
|
|
|
208
234
|
skip_existing (bool): If True, skips documents which already exist in the vector db when inserting. Defaults to True.
|
|
209
235
|
filters (Optional[Dict[str, Any]]): Filters to add to each row that can be used to limit results during querying. Defaults to None.
|
|
210
236
|
"""
|
|
211
|
-
|
|
212
|
-
log_info("Loading knowledge base")
|
|
237
|
+
self._load_init(recreate=False, upsert=upsert)
|
|
213
238
|
if self.vector_db is None:
|
|
214
|
-
logger.warning("No vector db provided")
|
|
215
239
|
return
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
self.vector_db.create()
|
|
219
|
-
|
|
240
|
+
|
|
241
|
+
log_info("Loading knowledge base")
|
|
220
242
|
# Upsert documents if upsert is True
|
|
221
243
|
if upsert and self.vector_db.upsert_available():
|
|
222
244
|
self.vector_db.upsert(documents=documents, filters=filters)
|
|
@@ -251,17 +273,11 @@ class AgentKnowledge(BaseModel):
|
|
|
251
273
|
skip_existing (bool): If True, skips documents which already exist in the vector db when inserting. Defaults to True.
|
|
252
274
|
filters (Optional[Dict[str, Any]]): Filters to add to each row that can be used to limit results during querying. Defaults to None.
|
|
253
275
|
"""
|
|
254
|
-
|
|
276
|
+
await self._aload_init(recreate=False, upsert=upsert)
|
|
255
277
|
if self.vector_db is None:
|
|
256
|
-
logger.warning("No vector db provided")
|
|
257
278
|
return
|
|
258
279
|
|
|
259
|
-
|
|
260
|
-
try:
|
|
261
|
-
await self.vector_db.async_create()
|
|
262
|
-
except NotImplementedError:
|
|
263
|
-
logger.warning("Vector db does not support async create")
|
|
264
|
-
self.vector_db.create()
|
|
280
|
+
log_info("Loading knowledge base")
|
|
265
281
|
|
|
266
282
|
# Upsert documents if upsert is True
|
|
267
283
|
if upsert and self.vector_db.upsert_available():
|
|
@@ -302,7 +318,7 @@ class AgentKnowledge(BaseModel):
|
|
|
302
318
|
else:
|
|
303
319
|
log_info("No new documents to load")
|
|
304
320
|
|
|
305
|
-
def
|
|
321
|
+
def load_document(
|
|
306
322
|
self,
|
|
307
323
|
document: Document,
|
|
308
324
|
upsert: bool = False,
|
|
@@ -414,8 +430,6 @@ class AgentKnowledge(BaseModel):
|
|
|
414
430
|
Returns:
|
|
415
431
|
List[Document]: Filtered list of documents that don't exist in the database
|
|
416
432
|
"""
|
|
417
|
-
from agno.utils.log import log_debug, log_info
|
|
418
|
-
|
|
419
433
|
if not self.vector_db:
|
|
420
434
|
log_debug("No vector database configured, skipping document filtering")
|
|
421
435
|
return documents
|
|
@@ -556,20 +570,9 @@ class AgentKnowledge(BaseModel):
|
|
|
556
570
|
self._track_metadata_structure(metadata)
|
|
557
571
|
|
|
558
572
|
# 3. Prepare vector DB
|
|
573
|
+
self._load_init(recreate, upsert=False)
|
|
559
574
|
if self.vector_db is None:
|
|
560
|
-
logger.warning("Cannot load file: No vector db provided.")
|
|
561
575
|
return False
|
|
562
|
-
|
|
563
|
-
# Recreate collection if requested
|
|
564
|
-
if recreate:
|
|
565
|
-
# log_info(f"Recreating collection.")
|
|
566
|
-
self.vector_db.drop()
|
|
567
|
-
|
|
568
|
-
# Create collection if it doesn't exist
|
|
569
|
-
if not self.vector_db.exists():
|
|
570
|
-
# log_info(f"Collection does not exist. Creating.")
|
|
571
|
-
self.vector_db.create()
|
|
572
|
-
|
|
573
576
|
return True
|
|
574
577
|
|
|
575
578
|
async def aprepare_load(
|
|
@@ -604,20 +607,9 @@ class AgentKnowledge(BaseModel):
|
|
|
604
607
|
self._track_metadata_structure(metadata)
|
|
605
608
|
|
|
606
609
|
# 3. Prepare vector DB
|
|
610
|
+
await self._aload_init(recreate, upsert=False)
|
|
607
611
|
if self.vector_db is None:
|
|
608
|
-
logger.warning("Cannot load file: No vector db provided.")
|
|
609
612
|
return False
|
|
610
|
-
|
|
611
|
-
# Recreate collection if requested
|
|
612
|
-
if recreate:
|
|
613
|
-
log_info("Recreating collection.")
|
|
614
|
-
await self.vector_db.async_drop()
|
|
615
|
-
|
|
616
|
-
# Create collection if it doesn't exist
|
|
617
|
-
if not await self.vector_db.async_exists():
|
|
618
|
-
log_info("Collection does not exist. Creating.")
|
|
619
|
-
await self.vector_db.async_create()
|
|
620
|
-
|
|
621
613
|
return True
|
|
622
614
|
|
|
623
615
|
def process_documents(
|
|
@@ -642,6 +634,8 @@ class AgentKnowledge(BaseModel):
|
|
|
642
634
|
|
|
643
635
|
log_info(f"Loading {len(documents)} documents from {source_info} with metadata: {metadata}")
|
|
644
636
|
|
|
637
|
+
self._upsert_warning(upsert)
|
|
638
|
+
|
|
645
639
|
# Decide loading strategy: upsert or insert (with optional skip)
|
|
646
640
|
if upsert and self.vector_db.upsert_available(): # type: ignore
|
|
647
641
|
log_debug(f"Upserting {len(documents)} documents.") # type: ignore
|
|
@@ -681,6 +675,8 @@ class AgentKnowledge(BaseModel):
|
|
|
681
675
|
logger.warning(f"No documents were read from {source_info}")
|
|
682
676
|
return
|
|
683
677
|
|
|
678
|
+
self._upsert_warning(upsert)
|
|
679
|
+
|
|
684
680
|
log_info(f"Loading {len(documents)} documents from {source_info} with metadata: {metadata}")
|
|
685
681
|
|
|
686
682
|
# Decide loading strategy: upsert or insert (with optional skip)
|
|
@@ -2,15 +2,22 @@ from pathlib import Path
|
|
|
2
2
|
from typing import Any, AsyncIterator, Dict, Iterator, List, Optional, Union
|
|
3
3
|
|
|
4
4
|
from pydantic import Field
|
|
5
|
+
from typing_extensions import TypedDict
|
|
5
6
|
|
|
6
7
|
from agno.document import Document
|
|
7
8
|
from agno.document.reader.pdf_reader import PDFImageReader, PDFReader
|
|
8
9
|
from agno.knowledge.agent import AgentKnowledge
|
|
9
|
-
from agno.utils.log import log_info, logger
|
|
10
|
+
from agno.utils.log import log_error, log_info, logger
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class PDFConfig(TypedDict, total=False):
|
|
14
|
+
path: str
|
|
15
|
+
password: Optional[str]
|
|
16
|
+
metadata: Optional[Dict[str, Any]]
|
|
10
17
|
|
|
11
18
|
|
|
12
19
|
class PDFKnowledgeBase(AgentKnowledge):
|
|
13
|
-
path: Optional[Union[str, Path, List[
|
|
20
|
+
path: Optional[Union[str, Path, List[PDFConfig]]] = None
|
|
14
21
|
formats: List[str] = [".pdf"]
|
|
15
22
|
exclude_files: List[str] = Field(default_factory=list)
|
|
16
23
|
reader: Union[PDFReader, PDFImageReader] = PDFReader()
|
|
@@ -24,19 +31,21 @@ class PDFKnowledgeBase(AgentKnowledge):
|
|
|
24
31
|
if isinstance(self.path, list):
|
|
25
32
|
for item in self.path:
|
|
26
33
|
if isinstance(item, dict) and "path" in item:
|
|
27
|
-
# Handle path with metadata
|
|
28
34
|
file_path = item["path"]
|
|
29
35
|
config = item.get("metadata", {})
|
|
36
|
+
file_password = item.get("password")
|
|
37
|
+
if file_password is not None and not isinstance(file_password, str):
|
|
38
|
+
file_password = None
|
|
39
|
+
|
|
30
40
|
_pdf_path = Path(file_path) # type: ignore
|
|
31
41
|
if self._is_valid_pdf(_pdf_path):
|
|
32
|
-
documents = self.reader.read(pdf=_pdf_path)
|
|
42
|
+
documents = self.reader.read(pdf=_pdf_path, password=file_password)
|
|
33
43
|
if config:
|
|
34
44
|
for doc in documents:
|
|
35
45
|
log_info(f"Adding metadata {config} to document: {doc.name}")
|
|
36
46
|
doc.meta_data.update(config) # type: ignore
|
|
37
47
|
yield documents
|
|
38
48
|
else:
|
|
39
|
-
# Handle single path
|
|
40
49
|
_pdf_path = Path(self.path)
|
|
41
50
|
if _pdf_path.is_dir():
|
|
42
51
|
for _pdf in _pdf_path.glob("**/*.pdf"):
|
|
@@ -47,7 +56,19 @@ class PDFKnowledgeBase(AgentKnowledge):
|
|
|
47
56
|
|
|
48
57
|
def _is_valid_pdf(self, path: Path) -> bool:
|
|
49
58
|
"""Helper to check if path is a valid PDF file."""
|
|
50
|
-
|
|
59
|
+
if not path.exists():
|
|
60
|
+
log_error(f"PDF file not found: {path}")
|
|
61
|
+
return False
|
|
62
|
+
if not path.is_file():
|
|
63
|
+
log_error(f"Path is not a file: {path}")
|
|
64
|
+
return False
|
|
65
|
+
if path.suffix != ".pdf":
|
|
66
|
+
log_error(f"File is not a PDF: {path}")
|
|
67
|
+
return False
|
|
68
|
+
if path.name in self.exclude_files:
|
|
69
|
+
log_error(f"PDF file excluded: {path}")
|
|
70
|
+
return False
|
|
71
|
+
return True
|
|
51
72
|
|
|
52
73
|
@property
|
|
53
74
|
async def async_document_lists(self) -> AsyncIterator[List[Document]]:
|
|
@@ -58,12 +79,15 @@ class PDFKnowledgeBase(AgentKnowledge):
|
|
|
58
79
|
if isinstance(self.path, list):
|
|
59
80
|
for item in self.path:
|
|
60
81
|
if isinstance(item, dict) and "path" in item:
|
|
61
|
-
# Handle path with metadata
|
|
62
82
|
file_path = item["path"]
|
|
63
83
|
config = item.get("metadata", {})
|
|
84
|
+
file_password = item.get("password")
|
|
85
|
+
if file_password is not None and not isinstance(file_password, str):
|
|
86
|
+
file_password = None
|
|
87
|
+
|
|
64
88
|
_pdf_path = Path(file_path) # type: ignore
|
|
65
89
|
if self._is_valid_pdf(_pdf_path):
|
|
66
|
-
documents = await self.reader.async_read(pdf=_pdf_path)
|
|
90
|
+
documents = await self.reader.async_read(pdf=_pdf_path, password=file_password)
|
|
67
91
|
if config:
|
|
68
92
|
for doc in documents:
|
|
69
93
|
log_info(f"Adding metadata {config} to document: {doc.name}")
|
|
@@ -19,18 +19,22 @@ class PDFUrlKnowledgeBase(AgentKnowledge):
|
|
|
19
19
|
|
|
20
20
|
for item in self.urls:
|
|
21
21
|
if isinstance(item, dict) and "url" in item:
|
|
22
|
-
# Handle URL with metadata
|
|
22
|
+
# Handle URL with metadata/password
|
|
23
23
|
url = item["url"]
|
|
24
24
|
config = item.get("metadata", {})
|
|
25
|
+
pdf_password = item.get("password")
|
|
26
|
+
if pdf_password is not None and not isinstance(pdf_password, str):
|
|
27
|
+
pdf_password = None
|
|
28
|
+
|
|
25
29
|
if self._is_valid_url(url): # type: ignore
|
|
26
|
-
documents = self.reader.read(url=url) # type: ignore
|
|
30
|
+
documents = self.reader.read(url=url, password=pdf_password) # type: ignore
|
|
27
31
|
if config:
|
|
28
32
|
for doc in documents:
|
|
29
33
|
log_info(f"Adding metadata {config} to document from URL: {url}")
|
|
30
34
|
doc.meta_data.update(config) # type: ignore
|
|
31
35
|
yield documents
|
|
32
36
|
else:
|
|
33
|
-
# Handle simple URL
|
|
37
|
+
# Handle simple URL - no password
|
|
34
38
|
if self._is_valid_url(item): # type: ignore
|
|
35
39
|
yield self.reader.read(url=item) # type: ignore
|
|
36
40
|
|
|
@@ -49,11 +53,15 @@ class PDFUrlKnowledgeBase(AgentKnowledge):
|
|
|
49
53
|
|
|
50
54
|
for item in self.urls:
|
|
51
55
|
if isinstance(item, dict) and "url" in item:
|
|
52
|
-
# Handle URL with metadata
|
|
56
|
+
# Handle URL with metadata/password
|
|
53
57
|
url = item["url"]
|
|
54
58
|
config = item.get("metadata", {})
|
|
59
|
+
pdf_password = item.get("password")
|
|
60
|
+
if pdf_password is not None and not isinstance(pdf_password, str):
|
|
61
|
+
pdf_password = None
|
|
62
|
+
|
|
55
63
|
if self._is_valid_url(url): # type: ignore
|
|
56
|
-
documents = await self.reader.async_read(url=url) # type: ignore
|
|
64
|
+
documents = await self.reader.async_read(url=url, password=pdf_password) # type: ignore
|
|
57
65
|
if config:
|
|
58
66
|
for doc in documents:
|
|
59
67
|
log_info(f"Adding metadata {config} to document from URL: {url}")
|