agno 2.1.0__tar.gz → 2.1.2__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-2.1.0 → agno-2.1.2}/PKG-INFO +16 -14
- {agno-2.1.0 → agno-2.1.2}/README.md +12 -12
- {agno-2.1.0 → agno-2.1.2}/agno/agent/agent.py +13 -1
- {agno-2.1.0 → agno-2.1.2}/agno/db/base.py +8 -4
- {agno-2.1.0 → agno-2.1.2}/agno/db/dynamo/dynamo.py +69 -17
- {agno-2.1.0 → agno-2.1.2}/agno/db/firestore/firestore.py +68 -29
- {agno-2.1.0 → agno-2.1.2}/agno/db/gcs_json/gcs_json_db.py +68 -17
- {agno-2.1.0 → agno-2.1.2}/agno/db/in_memory/in_memory_db.py +83 -14
- {agno-2.1.0 → agno-2.1.2}/agno/db/json/json_db.py +79 -15
- {agno-2.1.0 → agno-2.1.2}/agno/db/mongo/mongo.py +92 -74
- {agno-2.1.0 → agno-2.1.2}/agno/db/mysql/mysql.py +17 -3
- {agno-2.1.0 → agno-2.1.2}/agno/db/postgres/postgres.py +21 -3
- {agno-2.1.0 → agno-2.1.2}/agno/db/redis/redis.py +38 -11
- {agno-2.1.0 → agno-2.1.2}/agno/db/singlestore/singlestore.py +14 -3
- {agno-2.1.0 → agno-2.1.2}/agno/db/sqlite/sqlite.py +34 -46
- agno-2.1.2/agno/db/utils.py +116 -0
- {agno-2.1.0 → agno-2.1.2}/agno/knowledge/knowledge.py +6 -0
- agno-2.1.2/agno/knowledge/reader/field_labeled_csv_reader.py +294 -0
- {agno-2.1.0 → agno-2.1.2}/agno/knowledge/reader/pdf_reader.py +28 -52
- {agno-2.1.0 → agno-2.1.2}/agno/knowledge/reader/reader_factory.py +12 -0
- {agno-2.1.0 → agno-2.1.2}/agno/memory/manager.py +12 -4
- {agno-2.1.0 → agno-2.1.2}/agno/models/anthropic/claude.py +4 -1
- {agno-2.1.0 → agno-2.1.2}/agno/models/aws/bedrock.py +52 -112
- {agno-2.1.0 → agno-2.1.2}/agno/models/openai/responses.py +1 -1
- {agno-2.1.0 → agno-2.1.2}/agno/os/app.py +24 -30
- agno-2.1.2/agno/os/interfaces/__init__.py +1 -0
- agno-2.1.2/agno/os/interfaces/a2a/__init__.py +3 -0
- agno-2.1.2/agno/os/interfaces/a2a/a2a.py +42 -0
- agno-2.1.2/agno/os/interfaces/a2a/router.py +252 -0
- agno-2.1.2/agno/os/interfaces/a2a/utils.py +924 -0
- agno-2.1.2/agno/os/interfaces/agui/agui.py +47 -0
- {agno-2.1.0 → agno-2.1.2}/agno/os/interfaces/agui/router.py +12 -0
- {agno-2.1.0 → agno-2.1.2}/agno/os/interfaces/base.py +4 -2
- {agno-2.1.0 → agno-2.1.2}/agno/os/interfaces/slack/slack.py +13 -8
- {agno-2.1.0 → agno-2.1.2}/agno/os/interfaces/whatsapp/whatsapp.py +12 -5
- {agno-2.1.0 → agno-2.1.2}/agno/os/mcp.py +1 -1
- {agno-2.1.0 → agno-2.1.2}/agno/os/router.py +39 -9
- {agno-2.1.0 → agno-2.1.2}/agno/os/routers/memory/memory.py +5 -3
- {agno-2.1.0 → agno-2.1.2}/agno/os/routers/memory/schemas.py +1 -0
- {agno-2.1.0 → agno-2.1.2}/agno/os/utils.py +36 -10
- {agno-2.1.0 → agno-2.1.2}/agno/run/base.py +2 -13
- {agno-2.1.0 → agno-2.1.2}/agno/team/team.py +13 -1
- {agno-2.1.0 → agno-2.1.2}/agno/tools/mcp.py +46 -1
- agno-2.1.2/agno/utils/merge_dict.py +41 -0
- agno-2.1.2/agno/utils/serialize.py +32 -0
- {agno-2.1.0 → agno-2.1.2}/agno/utils/streamlit.py +1 -1
- {agno-2.1.0 → agno-2.1.2}/agno/workflow/parallel.py +90 -14
- {agno-2.1.0 → agno-2.1.2}/agno/workflow/step.py +30 -27
- {agno-2.1.0 → agno-2.1.2}/agno/workflow/types.py +4 -6
- {agno-2.1.0 → agno-2.1.2}/agno/workflow/workflow.py +5 -3
- {agno-2.1.0 → agno-2.1.2}/agno.egg-info/PKG-INFO +16 -14
- {agno-2.1.0 → agno-2.1.2}/agno.egg-info/SOURCES.txt +6 -0
- {agno-2.1.0 → agno-2.1.2}/agno.egg-info/requires.txt +5 -1
- {agno-2.1.0 → agno-2.1.2}/pyproject.toml +6 -2
- agno-2.1.0/agno/db/utils.py +0 -88
- agno-2.1.0/agno/os/interfaces/agui/agui.py +0 -31
- agno-2.1.0/agno/utils/merge_dict.py +0 -20
- agno-2.1.0/agno/utils/print_response/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/LICENSE +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/agent/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/api/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/api/agent.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/api/api.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/api/evals.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/api/os.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/api/routes.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/api/schemas/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/api/schemas/agent.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/api/schemas/evals.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/api/schemas/os.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/api/schemas/response.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/api/schemas/team.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/api/schemas/utils.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/api/schemas/workflows.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/api/settings.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/api/team.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/api/workflow.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/cloud/aws/base.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/cloud/aws/s3/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/cloud/aws/s3/api_client.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/cloud/aws/s3/bucket.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/cloud/aws/s3/object.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/db/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/db/dynamo/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/db/dynamo/schemas.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/db/dynamo/utils.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/db/firestore/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/db/firestore/schemas.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/db/firestore/utils.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/db/gcs_json/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/db/gcs_json/utils.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/db/in_memory/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/db/in_memory/utils.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/db/json/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/db/json/utils.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/db/migrations/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/db/migrations/v1_to_v2.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/db/mongo/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/db/mongo/schemas.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/db/mongo/utils.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/db/mysql/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/db/mysql/schemas.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/db/mysql/utils.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/db/postgres/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/db/postgres/schemas.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/db/postgres/utils.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/db/redis/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/db/redis/schemas.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/db/redis/utils.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/db/schemas/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/db/schemas/evals.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/db/schemas/knowledge.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/db/schemas/memory.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/db/schemas/metrics.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/db/singlestore/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/db/singlestore/schemas.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/db/singlestore/utils.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/db/sqlite/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/db/sqlite/schemas.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/db/sqlite/utils.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/debug.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/eval/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/eval/accuracy.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/eval/performance.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/eval/reliability.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/eval/utils.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/exceptions.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/guardrails/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/guardrails/base.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/guardrails/openai.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/guardrails/pii.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/guardrails/prompt_injection.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/integrations/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/integrations/discord/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/integrations/discord/client.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/knowledge/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/knowledge/chunking/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/knowledge/chunking/agentic.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/knowledge/chunking/document.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/knowledge/chunking/fixed.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/knowledge/chunking/markdown.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/knowledge/chunking/recursive.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/knowledge/chunking/row.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/knowledge/chunking/semantic.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/knowledge/chunking/strategy.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/knowledge/content.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/knowledge/document/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/knowledge/document/base.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/knowledge/embedder/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/knowledge/embedder/aws_bedrock.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/knowledge/embedder/azure_openai.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/knowledge/embedder/base.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/knowledge/embedder/cohere.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/knowledge/embedder/fastembed.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/knowledge/embedder/fireworks.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/knowledge/embedder/google.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/knowledge/embedder/huggingface.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/knowledge/embedder/jina.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/knowledge/embedder/langdb.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/knowledge/embedder/mistral.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/knowledge/embedder/nebius.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/knowledge/embedder/ollama.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/knowledge/embedder/openai.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/knowledge/embedder/sentence_transformer.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/knowledge/embedder/together.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/knowledge/embedder/voyageai.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/knowledge/reader/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/knowledge/reader/arxiv_reader.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/knowledge/reader/base.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/knowledge/reader/csv_reader.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/knowledge/reader/docx_reader.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/knowledge/reader/firecrawl_reader.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/knowledge/reader/json_reader.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/knowledge/reader/markdown_reader.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/knowledge/reader/s3_reader.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/knowledge/reader/text_reader.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/knowledge/reader/web_search_reader.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/knowledge/reader/website_reader.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/knowledge/reader/wikipedia_reader.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/knowledge/reader/youtube_reader.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/knowledge/remote_content/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/knowledge/remote_content/remote_content.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/knowledge/reranker/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/knowledge/reranker/base.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/knowledge/reranker/cohere.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/knowledge/reranker/infinity.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/knowledge/reranker/sentence_transformer.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/knowledge/types.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/knowledge/utils.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/media.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/memory/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/aimlapi/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/aimlapi/aimlapi.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/anthropic/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/aws/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/aws/claude.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/azure/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/azure/ai_foundry.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/azure/openai_chat.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/base.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/cerebras/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/cerebras/cerebras.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/cerebras/cerebras_openai.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/cohere/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/cohere/chat.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/cometapi/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/cometapi/cometapi.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/dashscope/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/dashscope/dashscope.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/deepinfra/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/deepinfra/deepinfra.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/deepseek/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/deepseek/deepseek.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/defaults.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/fireworks/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/fireworks/fireworks.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/google/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/google/gemini.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/groq/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/groq/groq.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/huggingface/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/huggingface/huggingface.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/ibm/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/ibm/watsonx.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/internlm/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/internlm/internlm.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/langdb/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/langdb/langdb.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/litellm/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/litellm/chat.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/litellm/litellm_openai.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/llama_cpp/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/llama_cpp/llama_cpp.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/lmstudio/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/lmstudio/lmstudio.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/message.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/meta/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/meta/llama.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/meta/llama_openai.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/metrics.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/mistral/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/mistral/mistral.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/nebius/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/nebius/nebius.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/nexus/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/nexus/nexus.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/nvidia/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/nvidia/nvidia.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/ollama/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/ollama/chat.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/openai/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/openai/chat.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/openai/like.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/openrouter/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/openrouter/openrouter.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/perplexity/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/perplexity/perplexity.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/portkey/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/portkey/portkey.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/requesty/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/requesty/requesty.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/response.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/sambanova/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/sambanova/sambanova.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/siliconflow/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/siliconflow/siliconflow.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/together/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/together/together.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/utils.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/vercel/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/vercel/v0.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/vllm/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/vllm/vllm.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/xai/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/models/xai/xai.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/os/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/os/auth.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/os/config.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/os/interfaces/agui/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/os/interfaces/agui/utils.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/os/interfaces/slack/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/os/interfaces/slack/router.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/os/interfaces/slack/security.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/os/interfaces/whatsapp/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/os/interfaces/whatsapp/router.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/os/interfaces/whatsapp/security.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/os/middleware/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/os/middleware/jwt.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/os/routers/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/os/routers/evals/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/os/routers/evals/evals.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/os/routers/evals/schemas.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/os/routers/evals/utils.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/os/routers/health.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/os/routers/home.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/os/routers/knowledge/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/os/routers/knowledge/knowledge.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/os/routers/knowledge/schemas.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/os/routers/memory/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/os/routers/metrics/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/os/routers/metrics/metrics.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/os/routers/metrics/schemas.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/os/routers/session/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/os/routers/session/session.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/os/schema.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/os/settings.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/py.typed +0 -0
- {agno-2.1.0/agno/os/interfaces → agno-2.1.2/agno/reasoning}/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/reasoning/azure_ai_foundry.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/reasoning/deepseek.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/reasoning/default.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/reasoning/groq.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/reasoning/helpers.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/reasoning/ollama.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/reasoning/openai.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/reasoning/step.py +0 -0
- {agno-2.1.0/agno/reasoning → agno-2.1.2/agno/run}/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/run/agent.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/run/cancel.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/run/messages.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/run/team.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/run/workflow.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/session/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/session/agent.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/session/summary.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/session/team.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/session/workflow.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/team/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/agentql.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/airflow.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/api.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/apify.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/arxiv.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/aws_lambda.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/aws_ses.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/baidusearch.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/bitbucket.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/brandfetch.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/bravesearch.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/brightdata.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/browserbase.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/calcom.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/calculator.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/cartesia.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/clickup.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/confluence.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/crawl4ai.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/csv_toolkit.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/dalle.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/daytona.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/decorator.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/desi_vocal.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/discord.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/docker.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/duckdb.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/duckduckgo.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/e2b.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/eleven_labs.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/email.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/evm.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/exa.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/fal.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/file.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/file_generation.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/financial_datasets.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/firecrawl.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/function.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/giphy.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/github.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/gmail.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/google_bigquery.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/google_maps.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/googlecalendar.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/googlesearch.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/googlesheets.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/hackernews.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/jina.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/jira.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/knowledge.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/linear.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/linkup.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/local_file_system.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/lumalab.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/mcp_toolbox.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/mem0.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/memori.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/memory.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/mlx_transcribe.py +0 -0
- {agno-2.1.0/agno/run → agno-2.1.2/agno/tools/models}/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/models/azure_openai.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/models/gemini.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/models/groq.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/models/morph.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/models/nebius.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/models_labs.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/moviepy_video.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/neo4j.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/newspaper.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/newspaper4k.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/openai.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/openbb.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/opencv.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/openweather.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/oxylabs.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/pandas.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/postgres.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/pubmed.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/python.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/reasoning.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/reddit.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/replicate.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/resend.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/scrapegraph.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/searxng.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/serpapi.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/serper.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/shell.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/slack.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/sleep.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/spider.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/sql.py +0 -0
- {agno-2.1.0/agno/tools/models → agno-2.1.2/agno/tools/streamlit}/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/streamlit/components.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/tavily.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/telegram.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/todoist.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/tool_registry.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/toolkit.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/trafilatura.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/trello.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/twilio.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/user_control_flow.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/valyu.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/visualization.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/webbrowser.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/webex.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/website.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/webtools.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/whatsapp.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/wikipedia.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/workflow.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/x.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/yfinance.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/youtube.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/zendesk.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/zep.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/tools/zoom.py +0 -0
- {agno-2.1.0/agno/tools/streamlit → agno-2.1.2/agno/utils}/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/utils/audio.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/utils/certs.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/utils/code_execution.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/utils/common.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/utils/dttm.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/utils/enum.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/utils/env.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/utils/events.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/utils/format_str.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/utils/functions.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/utils/gemini.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/utils/hooks.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/utils/http.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/utils/json_schema.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/utils/knowledge.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/utils/location.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/utils/log.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/utils/mcp.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/utils/media.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/utils/message.py +0 -0
- {agno-2.1.0/agno/utils → agno-2.1.2/agno/utils/models}/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/utils/models/ai_foundry.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/utils/models/claude.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/utils/models/cohere.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/utils/models/llama.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/utils/models/mistral.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/utils/models/openai_responses.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/utils/models/schema_utils.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/utils/models/watsonx.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/utils/openai.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/utils/pickle.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/utils/pprint.py +0 -0
- {agno-2.1.0/agno/utils/models → agno-2.1.2/agno/utils/print_response}/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/utils/print_response/agent.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/utils/print_response/team.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/utils/print_response/workflow.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/utils/prompts.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/utils/reasoning.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/utils/response.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/utils/response_iterator.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/utils/safe_formatter.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/utils/shell.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/utils/string.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/utils/team.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/utils/timer.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/utils/tools.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/utils/web.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/utils/whatsapp.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/utils/yaml_io.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/vectordb/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/vectordb/base.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/vectordb/cassandra/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/vectordb/cassandra/cassandra.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/vectordb/cassandra/extra_param_mixin.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/vectordb/cassandra/index.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/vectordb/chroma/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/vectordb/chroma/chromadb.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/vectordb/clickhouse/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/vectordb/clickhouse/clickhousedb.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/vectordb/clickhouse/index.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/vectordb/couchbase/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/vectordb/couchbase/couchbase.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/vectordb/distance.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/vectordb/lancedb/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/vectordb/lancedb/lance_db.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/vectordb/langchaindb/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/vectordb/langchaindb/langchaindb.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/vectordb/lightrag/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/vectordb/lightrag/lightrag.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/vectordb/llamaindex/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/vectordb/llamaindex/llamaindexdb.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/vectordb/milvus/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/vectordb/milvus/milvus.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/vectordb/mongodb/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/vectordb/mongodb/mongodb.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/vectordb/pgvector/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/vectordb/pgvector/index.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/vectordb/pgvector/pgvector.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/vectordb/pineconedb/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/vectordb/pineconedb/pineconedb.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/vectordb/qdrant/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/vectordb/qdrant/qdrant.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/vectordb/search.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/vectordb/singlestore/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/vectordb/singlestore/index.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/vectordb/singlestore/singlestore.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/vectordb/surrealdb/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/vectordb/surrealdb/surrealdb.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/vectordb/upstashdb/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/vectordb/upstashdb/upstashdb.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/vectordb/weaviate/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/vectordb/weaviate/index.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/vectordb/weaviate/weaviate.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/workflow/__init__.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/workflow/condition.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/workflow/loop.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/workflow/router.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno/workflow/steps.py +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno.egg-info/dependency_links.txt +0 -0
- {agno-2.1.0 → agno-2.1.2}/agno.egg-info/top_level.txt +0 -0
- {agno-2.1.0 → agno-2.1.2}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agno
|
|
3
|
-
Version: 2.1.
|
|
3
|
+
Version: 2.1.2
|
|
4
4
|
Summary: Agno: a lightweight library for building Multi-Agent Systems
|
|
5
5
|
Author-email: Ashpreet Bedi <ashpreet@agno.com>
|
|
6
6
|
Project-URL: homepage, https://agno.com
|
|
@@ -23,6 +23,7 @@ Description-Content-Type: text/markdown
|
|
|
23
23
|
License-File: LICENSE
|
|
24
24
|
Requires-Dist: docstring-parser
|
|
25
25
|
Requires-Dist: gitpython
|
|
26
|
+
Requires-Dist: h11>=0.16.0
|
|
26
27
|
Requires-Dist: httpx
|
|
27
28
|
Requires-Dist: packaging
|
|
28
29
|
Requires-Dist: pydantic-settings
|
|
@@ -247,6 +248,8 @@ Requires-Dist: chonkie[st]; extra == "chonkie"
|
|
|
247
248
|
Requires-Dist: chonkie; extra == "chonkie"
|
|
248
249
|
Provides-Extra: agui
|
|
249
250
|
Requires-Dist: ag-ui-protocol; extra == "agui"
|
|
251
|
+
Provides-Extra: a2a
|
|
252
|
+
Requires-Dist: a2a-sdk; extra == "a2a"
|
|
250
253
|
Provides-Extra: huggingface
|
|
251
254
|
Requires-Dist: huggingface-hub; extra == "huggingface"
|
|
252
255
|
Provides-Extra: performance
|
|
@@ -267,7 +270,6 @@ Requires-Dist: agno[anthropic]; extra == "models"
|
|
|
267
270
|
Requires-Dist: agno[azure]; extra == "models"
|
|
268
271
|
Requires-Dist: agno[cerebras]; extra == "models"
|
|
269
272
|
Requires-Dist: agno[cohere]; extra == "models"
|
|
270
|
-
Requires-Dist: agno[infinity]; extra == "models"
|
|
271
273
|
Requires-Dist: agno[google]; extra == "models"
|
|
272
274
|
Requires-Dist: agno[groq]; extra == "models"
|
|
273
275
|
Requires-Dist: agno[ibm]; extra == "models"
|
|
@@ -379,11 +381,11 @@ Dynamic: license-file
|
|
|
379
381
|
|
|
380
382
|
## What is Agno?
|
|
381
383
|
|
|
382
|
-
[Agno](https://docs.agno.com) is a high-performance runtime for multi-agent systems. Use it to build, run and manage
|
|
384
|
+
[Agno](https://docs.agno.com) is a high-performance SDK and runtime for multi-agent systems. Use it to build, run and manage multi-agent systems in your cloud.
|
|
383
385
|
|
|
384
|
-
Agno
|
|
386
|
+
Agno is the fastest framework for building agents with built-in memory, knowledge, session management, human in the loop and best-in-class MCP support. You can put agents together as multi-agent teams or step-based agentic workflows.
|
|
385
387
|
|
|
386
|
-
In 10 lines of code, we can build an Agent that
|
|
388
|
+
In 10 lines of code, we can build an Agent that uses tools to achieve a task.
|
|
387
389
|
|
|
388
390
|
```python hackernews_agent.py
|
|
389
391
|
from agno.agent import Agent
|
|
@@ -391,22 +393,22 @@ from agno.models.anthropic import Claude
|
|
|
391
393
|
from agno.tools.hackernews import HackerNewsTools
|
|
392
394
|
|
|
393
395
|
agent = Agent(
|
|
394
|
-
model=Claude(id="claude-sonnet-4-
|
|
396
|
+
model=Claude(id="claude-sonnet-4-5"),
|
|
395
397
|
tools=[HackerNewsTools()],
|
|
396
398
|
markdown=True,
|
|
397
399
|
)
|
|
398
|
-
agent.print_response("
|
|
400
|
+
agent.print_response("Write a report on trending startups and products.", stream=True)
|
|
399
401
|
```
|
|
400
402
|
|
|
401
403
|
But the real advantage of Agno is its [AgentOS](https://docs.agno.com/agent-os/introduction) runtime:
|
|
402
404
|
|
|
403
|
-
1. You get a pre-built FastAPI app for
|
|
404
|
-
2. You also get a
|
|
405
|
-
3. Your AgentOS runs in your cloud and you get complete
|
|
405
|
+
1. You get a pre-built FastAPI app for serving your agents, teams and workflows, meaning you start building your AI product on day one. This is a remarkable advantage over other solutions.
|
|
406
|
+
2. You also get a UI that connects directly to the pre-built FastAPI app. Use it to test, monitor and manage your system. This gives you unmatched visibility and control.
|
|
407
|
+
3. Your AgentOS runs in your cloud and you get complete privacy because no data ever leaves your system. This is incredible for security conscious enterprises that can't send data to external services.
|
|
406
408
|
|
|
407
|
-
For organizations building agents, Agno provides the complete solution. You get the fastest framework for building agents (speed of development and execution), a pre-built FastAPI app that
|
|
409
|
+
For organizations building agents, Agno provides the complete solution. You get the fastest framework for building agents (speed of development and execution), a pre-built FastAPI app that get you building product on day one, and a control plane for managing your system.
|
|
408
410
|
|
|
409
|
-
We bring a novel architecture that no other framework provides, your AgentOS runs securely in your cloud, and the control plane connects directly to it from your browser. You don't need to send data to external services or pay retention costs, you get complete privacy and control.
|
|
411
|
+
We bring a novel architecture that no other framework provides, your AgentOS runs securely in your cloud, and the control plane connects directly to it from your browser. You don't need to send data to any external services or pay retention costs, you get complete privacy and control.
|
|
410
412
|
|
|
411
413
|
## Getting started
|
|
412
414
|
|
|
@@ -463,10 +465,10 @@ source .venvs/perfenv/bin/activate
|
|
|
463
465
|
# pip install openai agno langgraph langchain_openai
|
|
464
466
|
|
|
465
467
|
# Agno
|
|
466
|
-
python evals/performance/
|
|
468
|
+
python cookbook/evals/performance/instantiate_agent_with_tool.py
|
|
467
469
|
|
|
468
470
|
# LangGraph
|
|
469
|
-
python evals/performance/
|
|
471
|
+
python cookbook/evals/performance/comparison/langgraph_instantiation.py
|
|
470
472
|
```
|
|
471
473
|
|
|
472
474
|
> The following evaluation is run on an Apple M4 MacBook Pro. It also runs as a Github action on this repo.
|
|
@@ -16,11 +16,11 @@
|
|
|
16
16
|
|
|
17
17
|
## What is Agno?
|
|
18
18
|
|
|
19
|
-
[Agno](https://docs.agno.com) is a high-performance runtime for multi-agent systems. Use it to build, run and manage
|
|
19
|
+
[Agno](https://docs.agno.com) is a high-performance SDK and runtime for multi-agent systems. Use it to build, run and manage multi-agent systems in your cloud.
|
|
20
20
|
|
|
21
|
-
Agno
|
|
21
|
+
Agno is the fastest framework for building agents with built-in memory, knowledge, session management, human in the loop and best-in-class MCP support. You can put agents together as multi-agent teams or step-based agentic workflows.
|
|
22
22
|
|
|
23
|
-
In 10 lines of code, we can build an Agent that
|
|
23
|
+
In 10 lines of code, we can build an Agent that uses tools to achieve a task.
|
|
24
24
|
|
|
25
25
|
```python hackernews_agent.py
|
|
26
26
|
from agno.agent import Agent
|
|
@@ -28,22 +28,22 @@ from agno.models.anthropic import Claude
|
|
|
28
28
|
from agno.tools.hackernews import HackerNewsTools
|
|
29
29
|
|
|
30
30
|
agent = Agent(
|
|
31
|
-
model=Claude(id="claude-sonnet-4-
|
|
31
|
+
model=Claude(id="claude-sonnet-4-5"),
|
|
32
32
|
tools=[HackerNewsTools()],
|
|
33
33
|
markdown=True,
|
|
34
34
|
)
|
|
35
|
-
agent.print_response("
|
|
35
|
+
agent.print_response("Write a report on trending startups and products.", stream=True)
|
|
36
36
|
```
|
|
37
37
|
|
|
38
38
|
But the real advantage of Agno is its [AgentOS](https://docs.agno.com/agent-os/introduction) runtime:
|
|
39
39
|
|
|
40
|
-
1. You get a pre-built FastAPI app for
|
|
41
|
-
2. You also get a
|
|
42
|
-
3. Your AgentOS runs in your cloud and you get complete
|
|
40
|
+
1. You get a pre-built FastAPI app for serving your agents, teams and workflows, meaning you start building your AI product on day one. This is a remarkable advantage over other solutions.
|
|
41
|
+
2. You also get a UI that connects directly to the pre-built FastAPI app. Use it to test, monitor and manage your system. This gives you unmatched visibility and control.
|
|
42
|
+
3. Your AgentOS runs in your cloud and you get complete privacy because no data ever leaves your system. This is incredible for security conscious enterprises that can't send data to external services.
|
|
43
43
|
|
|
44
|
-
For organizations building agents, Agno provides the complete solution. You get the fastest framework for building agents (speed of development and execution), a pre-built FastAPI app that
|
|
44
|
+
For organizations building agents, Agno provides the complete solution. You get the fastest framework for building agents (speed of development and execution), a pre-built FastAPI app that get you building product on day one, and a control plane for managing your system.
|
|
45
45
|
|
|
46
|
-
We bring a novel architecture that no other framework provides, your AgentOS runs securely in your cloud, and the control plane connects directly to it from your browser. You don't need to send data to external services or pay retention costs, you get complete privacy and control.
|
|
46
|
+
We bring a novel architecture that no other framework provides, your AgentOS runs securely in your cloud, and the control plane connects directly to it from your browser. You don't need to send data to any external services or pay retention costs, you get complete privacy and control.
|
|
47
47
|
|
|
48
48
|
## Getting started
|
|
49
49
|
|
|
@@ -100,10 +100,10 @@ source .venvs/perfenv/bin/activate
|
|
|
100
100
|
# pip install openai agno langgraph langchain_openai
|
|
101
101
|
|
|
102
102
|
# Agno
|
|
103
|
-
python evals/performance/
|
|
103
|
+
python cookbook/evals/performance/instantiate_agent_with_tool.py
|
|
104
104
|
|
|
105
105
|
# LangGraph
|
|
106
|
-
python evals/performance/
|
|
106
|
+
python cookbook/evals/performance/comparison/langgraph_instantiation.py
|
|
107
107
|
```
|
|
108
108
|
|
|
109
109
|
> The following evaluation is run on an Apple M4 MacBook Pro. It also runs as a Github action on this repo.
|
|
@@ -5244,7 +5244,7 @@ class Agent:
|
|
|
5244
5244
|
|
|
5245
5245
|
# 3.2.5 Add information about agentic filters if enabled
|
|
5246
5246
|
if self.knowledge is not None and self.enable_agentic_knowledge_filters:
|
|
5247
|
-
valid_filters =
|
|
5247
|
+
valid_filters = self.knowledge.get_valid_filters()
|
|
5248
5248
|
if valid_filters:
|
|
5249
5249
|
valid_filters_str = ", ".join(valid_filters)
|
|
5250
5250
|
additional_information.append(
|
|
@@ -6420,6 +6420,12 @@ class Agent:
|
|
|
6420
6420
|
log_warning("Reasoning error. Reasoning response is empty, continuing regular session...")
|
|
6421
6421
|
break
|
|
6422
6422
|
|
|
6423
|
+
if isinstance(reasoning_agent_response.content, str):
|
|
6424
|
+
log_warning(
|
|
6425
|
+
"Reasoning error. Content is a string, not structured output. Continuing regular session..."
|
|
6426
|
+
)
|
|
6427
|
+
break
|
|
6428
|
+
|
|
6423
6429
|
if (
|
|
6424
6430
|
reasoning_agent_response.content.reasoning_steps is None
|
|
6425
6431
|
or len(reasoning_agent_response.content.reasoning_steps) == 0
|
|
@@ -6649,6 +6655,12 @@ class Agent:
|
|
|
6649
6655
|
log_warning("Reasoning error. Reasoning response is empty, continuing regular session...")
|
|
6650
6656
|
break
|
|
6651
6657
|
|
|
6658
|
+
if isinstance(reasoning_agent_response.content, str):
|
|
6659
|
+
log_warning(
|
|
6660
|
+
"Reasoning error. Content is a string, not structured output. Continuing regular session..."
|
|
6661
|
+
)
|
|
6662
|
+
break
|
|
6663
|
+
|
|
6652
6664
|
if reasoning_agent_response.content.reasoning_steps is None:
|
|
6653
6665
|
log_warning("Reasoning error. Reasoning steps are empty, continuing regular session...")
|
|
6654
6666
|
break
|
|
@@ -95,20 +95,23 @@ class BaseDb(ABC):
|
|
|
95
95
|
raise NotImplementedError
|
|
96
96
|
|
|
97
97
|
@abstractmethod
|
|
98
|
-
def delete_user_memory(self, memory_id: str) -> None:
|
|
98
|
+
def delete_user_memory(self, memory_id: str, user_id: Optional[str] = None) -> None:
|
|
99
99
|
raise NotImplementedError
|
|
100
100
|
|
|
101
101
|
@abstractmethod
|
|
102
|
-
def delete_user_memories(self, memory_ids: List[str]) -> None:
|
|
102
|
+
def delete_user_memories(self, memory_ids: List[str], user_id: Optional[str] = None) -> None:
|
|
103
103
|
raise NotImplementedError
|
|
104
104
|
|
|
105
105
|
@abstractmethod
|
|
106
|
-
def get_all_memory_topics(self) -> List[str]:
|
|
106
|
+
def get_all_memory_topics(self, user_id: Optional[str] = None) -> List[str]:
|
|
107
107
|
raise NotImplementedError
|
|
108
108
|
|
|
109
109
|
@abstractmethod
|
|
110
110
|
def get_user_memory(
|
|
111
|
-
self,
|
|
111
|
+
self,
|
|
112
|
+
memory_id: str,
|
|
113
|
+
deserialize: Optional[bool] = True,
|
|
114
|
+
user_id: Optional[str] = None,
|
|
112
115
|
) -> Optional[Union[UserMemory, Dict[str, Any]]]:
|
|
113
116
|
raise NotImplementedError
|
|
114
117
|
|
|
@@ -133,6 +136,7 @@ class BaseDb(ABC):
|
|
|
133
136
|
self,
|
|
134
137
|
limit: Optional[int] = None,
|
|
135
138
|
page: Optional[int] = None,
|
|
139
|
+
user_id: Optional[str] = None,
|
|
136
140
|
) -> Tuple[List[Dict[str, Any]], int]:
|
|
137
141
|
raise NotImplementedError
|
|
138
142
|
|
|
@@ -562,17 +562,31 @@ class DynamoDb(BaseDb):
|
|
|
562
562
|
|
|
563
563
|
# --- User Memory ---
|
|
564
564
|
|
|
565
|
-
def delete_user_memory(self, memory_id: str) -> None:
|
|
565
|
+
def delete_user_memory(self, memory_id: str, user_id: Optional[str] = None) -> None:
|
|
566
566
|
"""
|
|
567
567
|
Delete a user memory from the database.
|
|
568
568
|
|
|
569
569
|
Args:
|
|
570
570
|
memory_id: The ID of the memory to delete.
|
|
571
|
+
user_id: The ID of the user (optional, for filtering).
|
|
571
572
|
|
|
572
573
|
Raises:
|
|
573
574
|
Exception: If any error occurs while deleting the user memory.
|
|
574
575
|
"""
|
|
575
576
|
try:
|
|
577
|
+
# If user_id is provided, verify the memory belongs to the user before deleting
|
|
578
|
+
if user_id:
|
|
579
|
+
response = self.client.get_item(
|
|
580
|
+
TableName=self.memory_table_name,
|
|
581
|
+
Key={"memory_id": {"S": memory_id}},
|
|
582
|
+
)
|
|
583
|
+
item = response.get("Item")
|
|
584
|
+
if item:
|
|
585
|
+
memory_data = deserialize_from_dynamodb_item(item)
|
|
586
|
+
if memory_data.get("user_id") != user_id:
|
|
587
|
+
log_debug(f"Memory {memory_id} does not belong to user {user_id}")
|
|
588
|
+
return
|
|
589
|
+
|
|
576
590
|
self.client.delete_item(
|
|
577
591
|
TableName=self.memory_table_name,
|
|
578
592
|
Key={"memory_id": {"S": memory_id}},
|
|
@@ -583,18 +597,34 @@ class DynamoDb(BaseDb):
|
|
|
583
597
|
log_error(f"Failed to delete user memory {memory_id}: {e}")
|
|
584
598
|
raise e
|
|
585
599
|
|
|
586
|
-
def delete_user_memories(self, memory_ids: List[str]) -> None:
|
|
600
|
+
def delete_user_memories(self, memory_ids: List[str], user_id: Optional[str] = None) -> None:
|
|
587
601
|
"""
|
|
588
602
|
Delete user memories from the database in batches.
|
|
589
603
|
|
|
590
604
|
Args:
|
|
591
605
|
memory_ids: List of memory IDs to delete
|
|
606
|
+
user_id: The ID of the user (optional, for filtering).
|
|
592
607
|
|
|
593
608
|
Raises:
|
|
594
609
|
Exception: If any error occurs while deleting the user memories.
|
|
595
610
|
"""
|
|
596
611
|
|
|
597
612
|
try:
|
|
613
|
+
# If user_id is provided, filter memory_ids to only those belonging to the user
|
|
614
|
+
if user_id:
|
|
615
|
+
filtered_memory_ids = []
|
|
616
|
+
for memory_id in memory_ids:
|
|
617
|
+
response = self.client.get_item(
|
|
618
|
+
TableName=self.memory_table_name,
|
|
619
|
+
Key={"memory_id": {"S": memory_id}},
|
|
620
|
+
)
|
|
621
|
+
item = response.get("Item")
|
|
622
|
+
if item:
|
|
623
|
+
memory_data = deserialize_from_dynamodb_item(item)
|
|
624
|
+
if memory_data.get("user_id") == user_id:
|
|
625
|
+
filtered_memory_ids.append(memory_id)
|
|
626
|
+
memory_ids = filtered_memory_ids
|
|
627
|
+
|
|
598
628
|
for i in range(0, len(memory_ids), DYNAMO_BATCH_SIZE_LIMIT):
|
|
599
629
|
batch = memory_ids[i : i + DYNAMO_BATCH_SIZE_LIMIT]
|
|
600
630
|
|
|
@@ -611,6 +641,9 @@ class DynamoDb(BaseDb):
|
|
|
611
641
|
def get_all_memory_topics(self) -> List[str]:
|
|
612
642
|
"""Get all memory topics from the database.
|
|
613
643
|
|
|
644
|
+
Args:
|
|
645
|
+
user_id: The ID of the user (optional, for filtering).
|
|
646
|
+
|
|
614
647
|
Returns:
|
|
615
648
|
List[str]: List of unique memory topics.
|
|
616
649
|
"""
|
|
@@ -619,13 +652,17 @@ class DynamoDb(BaseDb):
|
|
|
619
652
|
if table_name is None:
|
|
620
653
|
return []
|
|
621
654
|
|
|
622
|
-
#
|
|
623
|
-
|
|
655
|
+
# Build filter expression for user_id if provided
|
|
656
|
+
scan_kwargs = {"TableName": table_name}
|
|
657
|
+
|
|
658
|
+
# Scan the table to get memories
|
|
659
|
+
response = self.client.scan(**scan_kwargs)
|
|
624
660
|
items = response.get("Items", [])
|
|
625
661
|
|
|
626
662
|
# Handle pagination
|
|
627
663
|
while "LastEvaluatedKey" in response:
|
|
628
|
-
|
|
664
|
+
scan_kwargs["ExclusiveStartKey"] = response["LastEvaluatedKey"]
|
|
665
|
+
response = self.client.scan(**scan_kwargs)
|
|
629
666
|
items.extend(response.get("Items", []))
|
|
630
667
|
|
|
631
668
|
# Extract topics from all memories
|
|
@@ -642,13 +679,18 @@ class DynamoDb(BaseDb):
|
|
|
642
679
|
raise e
|
|
643
680
|
|
|
644
681
|
def get_user_memory(
|
|
645
|
-
self,
|
|
682
|
+
self,
|
|
683
|
+
memory_id: str,
|
|
684
|
+
deserialize: Optional[bool] = True,
|
|
685
|
+
user_id: Optional[str] = None,
|
|
646
686
|
) -> Optional[Union[UserMemory, Dict[str, Any]]]:
|
|
647
687
|
"""
|
|
648
688
|
Get a user memory from the database as a UserMemory object.
|
|
649
689
|
|
|
650
690
|
Args:
|
|
651
691
|
memory_id: The ID of the memory to get.
|
|
692
|
+
deserialize: Whether to deserialize the memory.
|
|
693
|
+
user_id: The ID of the user (optional, for filtering).
|
|
652
694
|
|
|
653
695
|
Returns:
|
|
654
696
|
Optional[UserMemory]: The user memory data if found, None otherwise.
|
|
@@ -665,6 +707,11 @@ class DynamoDb(BaseDb):
|
|
|
665
707
|
return None
|
|
666
708
|
|
|
667
709
|
item = deserialize_from_dynamodb_item(item)
|
|
710
|
+
|
|
711
|
+
# Filter by user_id if provided
|
|
712
|
+
if user_id and item.get("user_id") != user_id:
|
|
713
|
+
return None
|
|
714
|
+
|
|
668
715
|
if not deserialize:
|
|
669
716
|
return item
|
|
670
717
|
|
|
@@ -804,6 +851,7 @@ class DynamoDb(BaseDb):
|
|
|
804
851
|
Args:
|
|
805
852
|
limit (Optional[int]): The maximum number of user stats to return.
|
|
806
853
|
page (Optional[int]): The page number.
|
|
854
|
+
user_id (Optional[str]): The ID of the user (optional, for filtering).
|
|
807
855
|
|
|
808
856
|
Returns:
|
|
809
857
|
Tuple[List[Dict[str, Any]], int]: A list of dictionaries containing user stats and total count.
|
|
@@ -823,29 +871,33 @@ class DynamoDb(BaseDb):
|
|
|
823
871
|
try:
|
|
824
872
|
table_name = self._get_table("memories")
|
|
825
873
|
|
|
826
|
-
|
|
874
|
+
# Build filter expression for user_id if provided
|
|
875
|
+
scan_kwargs = {"TableName": table_name}
|
|
876
|
+
|
|
877
|
+
response = self.client.scan(**scan_kwargs)
|
|
827
878
|
items = response.get("Items", [])
|
|
828
879
|
|
|
829
880
|
# Handle pagination
|
|
830
881
|
while "LastEvaluatedKey" in response:
|
|
831
|
-
|
|
882
|
+
scan_kwargs["ExclusiveStartKey"] = response["LastEvaluatedKey"]
|
|
883
|
+
response = self.client.scan(**scan_kwargs)
|
|
832
884
|
items.extend(response.get("Items", []))
|
|
833
885
|
|
|
834
886
|
# Aggregate stats by user_id
|
|
835
887
|
user_stats = {}
|
|
836
888
|
for item in items:
|
|
837
889
|
memory_data = deserialize_from_dynamodb_item(item)
|
|
838
|
-
|
|
890
|
+
current_user_id = memory_data.get("user_id")
|
|
839
891
|
|
|
840
|
-
if
|
|
841
|
-
if
|
|
842
|
-
user_stats[
|
|
843
|
-
"user_id":
|
|
892
|
+
if current_user_id:
|
|
893
|
+
if current_user_id not in user_stats:
|
|
894
|
+
user_stats[current_user_id] = {
|
|
895
|
+
"user_id": current_user_id,
|
|
844
896
|
"total_memories": 0,
|
|
845
897
|
"last_memory_updated_at": None,
|
|
846
898
|
}
|
|
847
899
|
|
|
848
|
-
user_stats[
|
|
900
|
+
user_stats[current_user_id]["total_memories"] += 1
|
|
849
901
|
|
|
850
902
|
updated_at = memory_data.get("updated_at")
|
|
851
903
|
if updated_at:
|
|
@@ -853,10 +905,10 @@ class DynamoDb(BaseDb):
|
|
|
853
905
|
updated_at_timestamp = int(updated_at_dt.timestamp())
|
|
854
906
|
|
|
855
907
|
if updated_at_timestamp and (
|
|
856
|
-
user_stats[
|
|
857
|
-
or updated_at_timestamp > user_stats[
|
|
908
|
+
user_stats[current_user_id]["last_memory_updated_at"] is None
|
|
909
|
+
or updated_at_timestamp > user_stats[current_user_id]["last_memory_updated_at"]
|
|
858
910
|
):
|
|
859
|
-
user_stats[
|
|
911
|
+
user_stats[current_user_id]["last_memory_updated_at"] = updated_at_timestamp
|
|
860
912
|
|
|
861
913
|
# Convert to list and apply sorting
|
|
862
914
|
stats_list = list(user_stats.values())
|
|
@@ -596,11 +596,12 @@ class FirestoreDb(BaseDb):
|
|
|
596
596
|
|
|
597
597
|
# -- Memory methods --
|
|
598
598
|
|
|
599
|
-
def delete_user_memory(self, memory_id: str):
|
|
599
|
+
def delete_user_memory(self, memory_id: str, user_id: Optional[str] = None):
|
|
600
600
|
"""Delete a user memory from the database.
|
|
601
601
|
|
|
602
602
|
Args:
|
|
603
603
|
memory_id (str): The ID of the memory to delete.
|
|
604
|
+
user_id (Optional[str]): The ID of the user (optional, for filtering).
|
|
604
605
|
|
|
605
606
|
Returns:
|
|
606
607
|
bool: True if the memory was deleted, False otherwise.
|
|
@@ -610,28 +611,41 @@ class FirestoreDb(BaseDb):
|
|
|
610
611
|
"""
|
|
611
612
|
try:
|
|
612
613
|
collection_ref = self._get_collection(table_type="memories")
|
|
613
|
-
docs = collection_ref.where(filter=FieldFilter("memory_id", "==", memory_id)).stream()
|
|
614
614
|
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
615
|
+
# If user_id is provided, verify the memory belongs to the user before deleting
|
|
616
|
+
if user_id:
|
|
617
|
+
docs = collection_ref.where(filter=FieldFilter("memory_id", "==", memory_id)).stream()
|
|
618
|
+
for doc in docs:
|
|
619
|
+
data = doc.to_dict()
|
|
620
|
+
if data.get("user_id") != user_id:
|
|
621
|
+
log_debug(f"Memory {memory_id} does not belong to user {user_id}")
|
|
622
|
+
return
|
|
623
|
+
doc.reference.delete()
|
|
624
|
+
log_debug(f"Successfully deleted user memory id: {memory_id}")
|
|
625
|
+
return
|
|
623
626
|
else:
|
|
624
|
-
|
|
627
|
+
docs = collection_ref.where(filter=FieldFilter("memory_id", "==", memory_id)).stream()
|
|
628
|
+
deleted_count = 0
|
|
629
|
+
for doc in docs:
|
|
630
|
+
doc.reference.delete()
|
|
631
|
+
deleted_count += 1
|
|
632
|
+
|
|
633
|
+
success = deleted_count > 0
|
|
634
|
+
if success:
|
|
635
|
+
log_debug(f"Successfully deleted user memory id: {memory_id}")
|
|
636
|
+
else:
|
|
637
|
+
log_debug(f"No user memory found with id: {memory_id}")
|
|
625
638
|
|
|
626
639
|
except Exception as e:
|
|
627
640
|
log_error(f"Error deleting user memory: {e}")
|
|
628
641
|
raise e
|
|
629
642
|
|
|
630
|
-
def delete_user_memories(self, memory_ids: List[str]) -> None:
|
|
643
|
+
def delete_user_memories(self, memory_ids: List[str], user_id: Optional[str] = None) -> None:
|
|
631
644
|
"""Delete user memories from the database.
|
|
632
645
|
|
|
633
646
|
Args:
|
|
634
647
|
memory_ids (List[str]): The IDs of the memories to delete.
|
|
648
|
+
user_id (Optional[str]): The ID of the user (optional, for filtering).
|
|
635
649
|
|
|
636
650
|
Raises:
|
|
637
651
|
Exception: If there is an error deleting the memories.
|
|
@@ -641,11 +655,21 @@ class FirestoreDb(BaseDb):
|
|
|
641
655
|
batch = self.db_client.batch()
|
|
642
656
|
deleted_count = 0
|
|
643
657
|
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
for
|
|
647
|
-
|
|
648
|
-
|
|
658
|
+
# If user_id is provided, filter memory_ids to only those belonging to the user
|
|
659
|
+
if user_id:
|
|
660
|
+
for memory_id in memory_ids:
|
|
661
|
+
docs = collection_ref.where(filter=FieldFilter("memory_id", "==", memory_id)).stream()
|
|
662
|
+
for doc in docs:
|
|
663
|
+
data = doc.to_dict()
|
|
664
|
+
if data.get("user_id") == user_id:
|
|
665
|
+
batch.delete(doc.reference)
|
|
666
|
+
deleted_count += 1
|
|
667
|
+
else:
|
|
668
|
+
for memory_id in memory_ids:
|
|
669
|
+
docs = collection_ref.where(filter=FieldFilter("memory_id", "==", memory_id)).stream()
|
|
670
|
+
for doc in docs:
|
|
671
|
+
batch.delete(doc.reference)
|
|
672
|
+
deleted_count += 1
|
|
649
673
|
|
|
650
674
|
batch.commit()
|
|
651
675
|
|
|
@@ -658,7 +682,9 @@ class FirestoreDb(BaseDb):
|
|
|
658
682
|
log_error(f"Error deleting memories: {e}")
|
|
659
683
|
raise e
|
|
660
684
|
|
|
661
|
-
def get_all_memory_topics(
|
|
685
|
+
def get_all_memory_topics(
|
|
686
|
+
self, create_collection_if_not_found: Optional[bool] = True
|
|
687
|
+
) -> List[str]:
|
|
662
688
|
"""Get all memory topics from the database.
|
|
663
689
|
|
|
664
690
|
Returns:
|
|
@@ -687,12 +713,15 @@ class FirestoreDb(BaseDb):
|
|
|
687
713
|
log_error(f"Exception getting all memory topics: {e}")
|
|
688
714
|
raise e
|
|
689
715
|
|
|
690
|
-
def get_user_memory(
|
|
716
|
+
def get_user_memory(
|
|
717
|
+
self, memory_id: str, deserialize: Optional[bool] = True, user_id: Optional[str] = None
|
|
718
|
+
) -> Optional[UserMemory]:
|
|
691
719
|
"""Get a memory from the database.
|
|
692
720
|
|
|
693
721
|
Args:
|
|
694
722
|
memory_id (str): The ID of the memory to get.
|
|
695
723
|
deserialize (Optional[bool]): Whether to serialize the memory. Defaults to True.
|
|
724
|
+
user_id (Optional[str]): The ID of the user (optional, for filtering).
|
|
696
725
|
|
|
697
726
|
Returns:
|
|
698
727
|
Optional[UserMemory]:
|
|
@@ -711,7 +740,14 @@ class FirestoreDb(BaseDb):
|
|
|
711
740
|
result = doc.to_dict()
|
|
712
741
|
break
|
|
713
742
|
|
|
714
|
-
if result is None
|
|
743
|
+
if result is None:
|
|
744
|
+
return None
|
|
745
|
+
|
|
746
|
+
# Filter by user_id if provided
|
|
747
|
+
if user_id and result.get("user_id") != user_id:
|
|
748
|
+
return None
|
|
749
|
+
|
|
750
|
+
if not deserialize:
|
|
715
751
|
return result
|
|
716
752
|
|
|
717
753
|
return UserMemory.from_dict(result)
|
|
@@ -818,23 +854,26 @@ class FirestoreDb(BaseDb):
|
|
|
818
854
|
"""
|
|
819
855
|
try:
|
|
820
856
|
collection_ref = self._get_collection(table_type="memories")
|
|
821
|
-
|
|
857
|
+
|
|
858
|
+
query = collection_ref.where(filter=FieldFilter("user_id", "!=", None))
|
|
859
|
+
|
|
860
|
+
docs = query.stream()
|
|
822
861
|
|
|
823
862
|
user_stats = {}
|
|
824
863
|
for doc in docs:
|
|
825
864
|
data = doc.to_dict()
|
|
826
|
-
|
|
827
|
-
if
|
|
828
|
-
if
|
|
829
|
-
user_stats[
|
|
830
|
-
"user_id":
|
|
865
|
+
current_user_id = data.get("user_id")
|
|
866
|
+
if current_user_id:
|
|
867
|
+
if current_user_id not in user_stats:
|
|
868
|
+
user_stats[current_user_id] = {
|
|
869
|
+
"user_id": current_user_id,
|
|
831
870
|
"total_memories": 0,
|
|
832
871
|
"last_memory_updated_at": 0,
|
|
833
872
|
}
|
|
834
|
-
user_stats[
|
|
873
|
+
user_stats[current_user_id]["total_memories"] += 1
|
|
835
874
|
updated_at = data.get("updated_at", 0)
|
|
836
|
-
if updated_at > user_stats[
|
|
837
|
-
user_stats[
|
|
875
|
+
if updated_at > user_stats[current_user_id]["last_memory_updated_at"]:
|
|
876
|
+
user_stats[current_user_id]["last_memory_updated_at"] = updated_at
|
|
838
877
|
|
|
839
878
|
# Convert to list and sort
|
|
840
879
|
formatted_results = list(user_stats.values())
|