agno 2.2.13__py3-none-any.whl → 2.4.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- agno/agent/__init__.py +6 -0
- agno/agent/agent.py +5252 -3145
- agno/agent/remote.py +525 -0
- agno/api/api.py +2 -0
- agno/client/__init__.py +3 -0
- agno/client/a2a/__init__.py +10 -0
- agno/client/a2a/client.py +554 -0
- agno/client/a2a/schemas.py +112 -0
- agno/client/a2a/utils.py +369 -0
- agno/client/os.py +2669 -0
- agno/compression/__init__.py +3 -0
- agno/compression/manager.py +247 -0
- agno/culture/manager.py +2 -2
- agno/db/base.py +927 -6
- agno/db/dynamo/dynamo.py +788 -2
- agno/db/dynamo/schemas.py +128 -0
- agno/db/dynamo/utils.py +26 -3
- agno/db/firestore/firestore.py +674 -50
- agno/db/firestore/schemas.py +41 -0
- agno/db/firestore/utils.py +25 -10
- agno/db/gcs_json/gcs_json_db.py +506 -3
- agno/db/gcs_json/utils.py +14 -2
- agno/db/in_memory/in_memory_db.py +203 -4
- agno/db/in_memory/utils.py +14 -2
- agno/db/json/json_db.py +498 -2
- agno/db/json/utils.py +14 -2
- agno/db/migrations/manager.py +199 -0
- agno/db/migrations/utils.py +19 -0
- agno/db/migrations/v1_to_v2.py +54 -16
- agno/db/migrations/versions/__init__.py +0 -0
- agno/db/migrations/versions/v2_3_0.py +977 -0
- agno/db/mongo/async_mongo.py +1013 -39
- agno/db/mongo/mongo.py +684 -4
- agno/db/mongo/schemas.py +48 -0
- agno/db/mongo/utils.py +17 -0
- agno/db/mysql/__init__.py +2 -1
- agno/db/mysql/async_mysql.py +2958 -0
- agno/db/mysql/mysql.py +722 -53
- agno/db/mysql/schemas.py +77 -11
- agno/db/mysql/utils.py +151 -8
- agno/db/postgres/async_postgres.py +1254 -137
- agno/db/postgres/postgres.py +2316 -93
- agno/db/postgres/schemas.py +153 -21
- agno/db/postgres/utils.py +22 -7
- agno/db/redis/redis.py +531 -3
- agno/db/redis/schemas.py +36 -0
- agno/db/redis/utils.py +31 -15
- agno/db/schemas/evals.py +1 -0
- agno/db/schemas/memory.py +20 -9
- agno/db/singlestore/schemas.py +70 -1
- agno/db/singlestore/singlestore.py +737 -74
- agno/db/singlestore/utils.py +13 -3
- agno/db/sqlite/async_sqlite.py +1069 -89
- agno/db/sqlite/schemas.py +133 -1
- agno/db/sqlite/sqlite.py +2203 -165
- agno/db/sqlite/utils.py +21 -11
- agno/db/surrealdb/models.py +25 -0
- agno/db/surrealdb/surrealdb.py +603 -1
- agno/db/utils.py +60 -0
- agno/eval/__init__.py +26 -3
- agno/eval/accuracy.py +25 -12
- agno/eval/agent_as_judge.py +871 -0
- agno/eval/base.py +29 -0
- agno/eval/performance.py +10 -4
- agno/eval/reliability.py +22 -13
- agno/eval/utils.py +2 -1
- agno/exceptions.py +42 -0
- agno/hooks/__init__.py +3 -0
- agno/hooks/decorator.py +164 -0
- agno/integrations/discord/client.py +13 -2
- agno/knowledge/__init__.py +4 -0
- agno/knowledge/chunking/code.py +90 -0
- agno/knowledge/chunking/document.py +65 -4
- agno/knowledge/chunking/fixed.py +4 -1
- agno/knowledge/chunking/markdown.py +102 -11
- agno/knowledge/chunking/recursive.py +2 -2
- agno/knowledge/chunking/semantic.py +130 -48
- agno/knowledge/chunking/strategy.py +18 -0
- agno/knowledge/embedder/azure_openai.py +0 -1
- agno/knowledge/embedder/google.py +1 -1
- agno/knowledge/embedder/mistral.py +1 -1
- agno/knowledge/embedder/nebius.py +1 -1
- agno/knowledge/embedder/openai.py +16 -12
- agno/knowledge/filesystem.py +412 -0
- agno/knowledge/knowledge.py +4261 -1199
- agno/knowledge/protocol.py +134 -0
- agno/knowledge/reader/arxiv_reader.py +3 -2
- agno/knowledge/reader/base.py +9 -7
- agno/knowledge/reader/csv_reader.py +91 -42
- agno/knowledge/reader/docx_reader.py +9 -10
- agno/knowledge/reader/excel_reader.py +225 -0
- agno/knowledge/reader/field_labeled_csv_reader.py +38 -48
- agno/knowledge/reader/firecrawl_reader.py +3 -2
- agno/knowledge/reader/json_reader.py +16 -22
- agno/knowledge/reader/markdown_reader.py +15 -14
- agno/knowledge/reader/pdf_reader.py +33 -28
- agno/knowledge/reader/pptx_reader.py +9 -10
- agno/knowledge/reader/reader_factory.py +135 -1
- agno/knowledge/reader/s3_reader.py +8 -16
- agno/knowledge/reader/tavily_reader.py +3 -3
- agno/knowledge/reader/text_reader.py +15 -14
- agno/knowledge/reader/utils/__init__.py +17 -0
- agno/knowledge/reader/utils/spreadsheet.py +114 -0
- agno/knowledge/reader/web_search_reader.py +8 -65
- agno/knowledge/reader/website_reader.py +16 -13
- agno/knowledge/reader/wikipedia_reader.py +36 -3
- agno/knowledge/reader/youtube_reader.py +3 -2
- agno/knowledge/remote_content/__init__.py +33 -0
- agno/knowledge/remote_content/config.py +266 -0
- agno/knowledge/remote_content/remote_content.py +105 -17
- agno/knowledge/utils.py +76 -22
- agno/learn/__init__.py +71 -0
- agno/learn/config.py +463 -0
- agno/learn/curate.py +185 -0
- agno/learn/machine.py +725 -0
- agno/learn/schemas.py +1114 -0
- agno/learn/stores/__init__.py +38 -0
- agno/learn/stores/decision_log.py +1156 -0
- agno/learn/stores/entity_memory.py +3275 -0
- agno/learn/stores/learned_knowledge.py +1583 -0
- agno/learn/stores/protocol.py +117 -0
- agno/learn/stores/session_context.py +1217 -0
- agno/learn/stores/user_memory.py +1495 -0
- agno/learn/stores/user_profile.py +1220 -0
- agno/learn/utils.py +209 -0
- agno/media.py +22 -6
- agno/memory/__init__.py +14 -1
- agno/memory/manager.py +223 -8
- agno/memory/strategies/__init__.py +15 -0
- agno/memory/strategies/base.py +66 -0
- agno/memory/strategies/summarize.py +196 -0
- agno/memory/strategies/types.py +37 -0
- agno/models/aimlapi/aimlapi.py +17 -0
- agno/models/anthropic/claude.py +434 -59
- agno/models/aws/bedrock.py +121 -20
- agno/models/aws/claude.py +131 -274
- agno/models/azure/ai_foundry.py +10 -6
- agno/models/azure/openai_chat.py +33 -10
- agno/models/base.py +1162 -561
- agno/models/cerebras/cerebras.py +120 -24
- agno/models/cerebras/cerebras_openai.py +21 -2
- agno/models/cohere/chat.py +65 -6
- agno/models/cometapi/cometapi.py +18 -1
- agno/models/dashscope/dashscope.py +2 -3
- agno/models/deepinfra/deepinfra.py +18 -1
- agno/models/deepseek/deepseek.py +69 -3
- agno/models/fireworks/fireworks.py +18 -1
- agno/models/google/gemini.py +959 -89
- agno/models/google/utils.py +22 -0
- agno/models/groq/groq.py +48 -18
- agno/models/huggingface/huggingface.py +17 -6
- agno/models/ibm/watsonx.py +16 -6
- agno/models/internlm/internlm.py +18 -1
- agno/models/langdb/langdb.py +13 -1
- agno/models/litellm/chat.py +88 -9
- agno/models/litellm/litellm_openai.py +18 -1
- agno/models/message.py +24 -5
- agno/models/meta/llama.py +40 -13
- agno/models/meta/llama_openai.py +22 -21
- agno/models/metrics.py +12 -0
- agno/models/mistral/mistral.py +8 -4
- agno/models/n1n/__init__.py +3 -0
- agno/models/n1n/n1n.py +57 -0
- agno/models/nebius/nebius.py +6 -7
- agno/models/nvidia/nvidia.py +20 -3
- agno/models/ollama/__init__.py +2 -0
- agno/models/ollama/chat.py +17 -6
- agno/models/ollama/responses.py +100 -0
- agno/models/openai/__init__.py +2 -0
- agno/models/openai/chat.py +117 -26
- agno/models/openai/open_responses.py +46 -0
- agno/models/openai/responses.py +110 -32
- agno/models/openrouter/__init__.py +2 -0
- agno/models/openrouter/openrouter.py +67 -2
- agno/models/openrouter/responses.py +146 -0
- agno/models/perplexity/perplexity.py +19 -1
- agno/models/portkey/portkey.py +7 -6
- agno/models/requesty/requesty.py +19 -2
- agno/models/response.py +20 -2
- agno/models/sambanova/sambanova.py +20 -3
- agno/models/siliconflow/siliconflow.py +19 -2
- agno/models/together/together.py +20 -3
- agno/models/vercel/v0.py +20 -3
- agno/models/vertexai/claude.py +124 -4
- agno/models/vllm/vllm.py +19 -14
- agno/models/xai/xai.py +19 -2
- agno/os/app.py +467 -137
- agno/os/auth.py +253 -5
- agno/os/config.py +22 -0
- agno/os/interfaces/a2a/a2a.py +7 -6
- agno/os/interfaces/a2a/router.py +635 -26
- agno/os/interfaces/a2a/utils.py +32 -33
- agno/os/interfaces/agui/agui.py +5 -3
- agno/os/interfaces/agui/router.py +26 -16
- agno/os/interfaces/agui/utils.py +97 -57
- agno/os/interfaces/base.py +7 -7
- agno/os/interfaces/slack/router.py +16 -7
- agno/os/interfaces/slack/slack.py +7 -7
- agno/os/interfaces/whatsapp/router.py +35 -7
- agno/os/interfaces/whatsapp/security.py +3 -1
- agno/os/interfaces/whatsapp/whatsapp.py +11 -8
- agno/os/managers.py +326 -0
- agno/os/mcp.py +652 -79
- agno/os/middleware/__init__.py +4 -0
- agno/os/middleware/jwt.py +718 -115
- agno/os/middleware/trailing_slash.py +27 -0
- agno/os/router.py +105 -1558
- agno/os/routers/agents/__init__.py +3 -0
- agno/os/routers/agents/router.py +655 -0
- agno/os/routers/agents/schema.py +288 -0
- agno/os/routers/components/__init__.py +3 -0
- agno/os/routers/components/components.py +475 -0
- agno/os/routers/database.py +155 -0
- agno/os/routers/evals/evals.py +111 -18
- agno/os/routers/evals/schemas.py +38 -5
- agno/os/routers/evals/utils.py +80 -11
- agno/os/routers/health.py +3 -3
- agno/os/routers/knowledge/knowledge.py +284 -35
- agno/os/routers/knowledge/schemas.py +14 -2
- agno/os/routers/memory/memory.py +274 -11
- agno/os/routers/memory/schemas.py +44 -3
- agno/os/routers/metrics/metrics.py +30 -15
- agno/os/routers/metrics/schemas.py +10 -6
- agno/os/routers/registry/__init__.py +3 -0
- agno/os/routers/registry/registry.py +337 -0
- agno/os/routers/session/session.py +143 -14
- agno/os/routers/teams/__init__.py +3 -0
- agno/os/routers/teams/router.py +550 -0
- agno/os/routers/teams/schema.py +280 -0
- agno/os/routers/traces/__init__.py +3 -0
- agno/os/routers/traces/schemas.py +414 -0
- agno/os/routers/traces/traces.py +549 -0
- agno/os/routers/workflows/__init__.py +3 -0
- agno/os/routers/workflows/router.py +757 -0
- agno/os/routers/workflows/schema.py +139 -0
- agno/os/schema.py +157 -584
- agno/os/scopes.py +469 -0
- agno/os/settings.py +3 -0
- agno/os/utils.py +574 -185
- agno/reasoning/anthropic.py +85 -1
- agno/reasoning/azure_ai_foundry.py +93 -1
- agno/reasoning/deepseek.py +102 -2
- agno/reasoning/default.py +6 -7
- agno/reasoning/gemini.py +87 -3
- agno/reasoning/groq.py +109 -2
- agno/reasoning/helpers.py +6 -7
- agno/reasoning/manager.py +1238 -0
- agno/reasoning/ollama.py +93 -1
- agno/reasoning/openai.py +115 -1
- agno/reasoning/vertexai.py +85 -1
- agno/registry/__init__.py +3 -0
- agno/registry/registry.py +68 -0
- agno/remote/__init__.py +3 -0
- agno/remote/base.py +581 -0
- agno/run/__init__.py +2 -4
- agno/run/agent.py +134 -19
- agno/run/base.py +49 -1
- agno/run/cancel.py +65 -52
- agno/run/cancellation_management/__init__.py +9 -0
- agno/run/cancellation_management/base.py +78 -0
- agno/run/cancellation_management/in_memory_cancellation_manager.py +100 -0
- agno/run/cancellation_management/redis_cancellation_manager.py +236 -0
- agno/run/requirement.py +181 -0
- agno/run/team.py +111 -19
- agno/run/workflow.py +2 -1
- agno/session/agent.py +57 -92
- agno/session/summary.py +1 -1
- agno/session/team.py +62 -115
- agno/session/workflow.py +353 -57
- agno/skills/__init__.py +17 -0
- agno/skills/agent_skills.py +377 -0
- agno/skills/errors.py +32 -0
- agno/skills/loaders/__init__.py +4 -0
- agno/skills/loaders/base.py +27 -0
- agno/skills/loaders/local.py +216 -0
- agno/skills/skill.py +65 -0
- agno/skills/utils.py +107 -0
- agno/skills/validator.py +277 -0
- agno/table.py +10 -0
- agno/team/__init__.py +5 -1
- agno/team/remote.py +447 -0
- agno/team/team.py +3769 -2202
- agno/tools/brandfetch.py +27 -18
- agno/tools/browserbase.py +225 -16
- agno/tools/crawl4ai.py +3 -0
- agno/tools/duckduckgo.py +25 -71
- agno/tools/exa.py +0 -21
- agno/tools/file.py +14 -13
- agno/tools/file_generation.py +12 -6
- agno/tools/firecrawl.py +15 -7
- agno/tools/function.py +94 -113
- agno/tools/google_bigquery.py +11 -2
- agno/tools/google_drive.py +4 -3
- agno/tools/knowledge.py +9 -4
- agno/tools/mcp/mcp.py +301 -18
- agno/tools/mcp/multi_mcp.py +269 -14
- agno/tools/mem0.py +11 -10
- agno/tools/memory.py +47 -46
- agno/tools/mlx_transcribe.py +10 -7
- agno/tools/models/nebius.py +5 -5
- agno/tools/models_labs.py +20 -10
- agno/tools/nano_banana.py +151 -0
- agno/tools/parallel.py +0 -7
- agno/tools/postgres.py +76 -36
- agno/tools/python.py +14 -6
- agno/tools/reasoning.py +30 -23
- agno/tools/redshift.py +406 -0
- agno/tools/shopify.py +1519 -0
- agno/tools/spotify.py +919 -0
- agno/tools/tavily.py +4 -1
- agno/tools/toolkit.py +253 -18
- agno/tools/websearch.py +93 -0
- agno/tools/website.py +1 -1
- agno/tools/wikipedia.py +1 -1
- agno/tools/workflow.py +56 -48
- agno/tools/yfinance.py +12 -11
- agno/tracing/__init__.py +12 -0
- agno/tracing/exporter.py +161 -0
- agno/tracing/schemas.py +276 -0
- agno/tracing/setup.py +112 -0
- agno/utils/agent.py +251 -10
- agno/utils/cryptography.py +22 -0
- agno/utils/dttm.py +33 -0
- agno/utils/events.py +264 -7
- agno/utils/hooks.py +111 -3
- agno/utils/http.py +161 -2
- agno/utils/mcp.py +49 -8
- agno/utils/media.py +22 -1
- agno/utils/models/ai_foundry.py +9 -2
- agno/utils/models/claude.py +20 -5
- agno/utils/models/cohere.py +9 -2
- agno/utils/models/llama.py +9 -2
- agno/utils/models/mistral.py +4 -2
- agno/utils/os.py +0 -0
- agno/utils/print_response/agent.py +99 -16
- agno/utils/print_response/team.py +223 -24
- agno/utils/print_response/workflow.py +0 -2
- agno/utils/prompts.py +8 -6
- agno/utils/remote.py +23 -0
- agno/utils/response.py +1 -13
- agno/utils/string.py +91 -2
- agno/utils/team.py +62 -12
- agno/utils/tokens.py +657 -0
- agno/vectordb/base.py +15 -2
- agno/vectordb/cassandra/cassandra.py +1 -1
- agno/vectordb/chroma/__init__.py +2 -1
- agno/vectordb/chroma/chromadb.py +468 -23
- agno/vectordb/clickhouse/clickhousedb.py +1 -1
- agno/vectordb/couchbase/couchbase.py +6 -2
- agno/vectordb/lancedb/lance_db.py +7 -38
- agno/vectordb/lightrag/lightrag.py +7 -6
- agno/vectordb/milvus/milvus.py +118 -84
- agno/vectordb/mongodb/__init__.py +2 -1
- agno/vectordb/mongodb/mongodb.py +14 -31
- agno/vectordb/pgvector/pgvector.py +120 -66
- agno/vectordb/pineconedb/pineconedb.py +2 -19
- agno/vectordb/qdrant/__init__.py +2 -1
- agno/vectordb/qdrant/qdrant.py +33 -56
- agno/vectordb/redis/__init__.py +2 -1
- agno/vectordb/redis/redisdb.py +19 -31
- agno/vectordb/singlestore/singlestore.py +17 -9
- agno/vectordb/surrealdb/surrealdb.py +2 -38
- agno/vectordb/weaviate/__init__.py +2 -1
- agno/vectordb/weaviate/weaviate.py +7 -3
- agno/workflow/__init__.py +5 -1
- agno/workflow/agent.py +2 -2
- agno/workflow/condition.py +12 -10
- agno/workflow/loop.py +28 -9
- agno/workflow/parallel.py +21 -13
- agno/workflow/remote.py +362 -0
- agno/workflow/router.py +12 -9
- agno/workflow/step.py +261 -36
- agno/workflow/steps.py +12 -8
- agno/workflow/types.py +40 -77
- agno/workflow/workflow.py +939 -213
- {agno-2.2.13.dist-info → agno-2.4.3.dist-info}/METADATA +134 -181
- agno-2.4.3.dist-info/RECORD +677 -0
- {agno-2.2.13.dist-info → agno-2.4.3.dist-info}/WHEEL +1 -1
- agno/tools/googlesearch.py +0 -98
- agno/tools/memori.py +0 -339
- agno-2.2.13.dist-info/RECORD +0 -575
- {agno-2.2.13.dist-info → agno-2.4.3.dist-info}/licenses/LICENSE +0 -0
- {agno-2.2.13.dist-info → agno-2.4.3.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING, Optional
|
|
4
|
+
|
|
5
|
+
from pydantic import BaseModel, ConfigDict
|
|
6
|
+
|
|
7
|
+
if TYPE_CHECKING:
|
|
8
|
+
from agno.knowledge.remote_content.remote_content import (
|
|
9
|
+
AzureBlobContent,
|
|
10
|
+
GCSContent,
|
|
11
|
+
GitHubContent,
|
|
12
|
+
S3Content,
|
|
13
|
+
SharePointContent,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class RemoteContentConfig(BaseModel):
|
|
18
|
+
"""Base configuration for remote content sources."""
|
|
19
|
+
|
|
20
|
+
id: str
|
|
21
|
+
name: str
|
|
22
|
+
metadata: Optional[dict] = None
|
|
23
|
+
|
|
24
|
+
model_config = ConfigDict(extra="allow")
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class S3Config(RemoteContentConfig):
|
|
28
|
+
"""Configuration for AWS S3 content source."""
|
|
29
|
+
|
|
30
|
+
bucket_name: str
|
|
31
|
+
region: Optional[str] = None
|
|
32
|
+
aws_access_key_id: Optional[str] = None
|
|
33
|
+
aws_secret_access_key: Optional[str] = None
|
|
34
|
+
prefix: Optional[str] = None
|
|
35
|
+
|
|
36
|
+
def file(self, key: str) -> "S3Content":
|
|
37
|
+
"""Create a content reference for a specific file.
|
|
38
|
+
|
|
39
|
+
Args:
|
|
40
|
+
key: The S3 object key (path to file).
|
|
41
|
+
|
|
42
|
+
Returns:
|
|
43
|
+
S3Content configured with this source's credentials.
|
|
44
|
+
"""
|
|
45
|
+
from agno.knowledge.remote_content.remote_content import S3Content
|
|
46
|
+
|
|
47
|
+
return S3Content(
|
|
48
|
+
bucket_name=self.bucket_name,
|
|
49
|
+
key=key,
|
|
50
|
+
config_id=self.id,
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
def folder(self, prefix: str) -> "S3Content":
|
|
54
|
+
"""Create a content reference for a folder (prefix).
|
|
55
|
+
|
|
56
|
+
Args:
|
|
57
|
+
prefix: The S3 prefix (folder path).
|
|
58
|
+
|
|
59
|
+
Returns:
|
|
60
|
+
S3Content configured with this source's credentials.
|
|
61
|
+
"""
|
|
62
|
+
from agno.knowledge.remote_content.remote_content import S3Content
|
|
63
|
+
|
|
64
|
+
return S3Content(
|
|
65
|
+
bucket_name=self.bucket_name,
|
|
66
|
+
prefix=prefix,
|
|
67
|
+
config_id=self.id,
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
class GcsConfig(RemoteContentConfig):
|
|
72
|
+
"""Configuration for Google Cloud Storage content source."""
|
|
73
|
+
|
|
74
|
+
bucket_name: str
|
|
75
|
+
project: Optional[str] = None
|
|
76
|
+
credentials_path: Optional[str] = None
|
|
77
|
+
prefix: Optional[str] = None
|
|
78
|
+
|
|
79
|
+
def file(self, blob_name: str) -> "GCSContent":
|
|
80
|
+
"""Create a content reference for a specific file.
|
|
81
|
+
|
|
82
|
+
Args:
|
|
83
|
+
blob_name: The GCS blob name (path to file).
|
|
84
|
+
|
|
85
|
+
Returns:
|
|
86
|
+
GCSContent configured with this source's credentials.
|
|
87
|
+
"""
|
|
88
|
+
from agno.knowledge.remote_content.remote_content import GCSContent
|
|
89
|
+
|
|
90
|
+
return GCSContent(
|
|
91
|
+
bucket_name=self.bucket_name,
|
|
92
|
+
blob_name=blob_name,
|
|
93
|
+
config_id=self.id,
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
def folder(self, prefix: str) -> "GCSContent":
|
|
97
|
+
"""Create a content reference for a folder (prefix).
|
|
98
|
+
|
|
99
|
+
Args:
|
|
100
|
+
prefix: The GCS prefix (folder path).
|
|
101
|
+
|
|
102
|
+
Returns:
|
|
103
|
+
GCSContent configured with this source's credentials.
|
|
104
|
+
"""
|
|
105
|
+
from agno.knowledge.remote_content.remote_content import GCSContent
|
|
106
|
+
|
|
107
|
+
return GCSContent(
|
|
108
|
+
bucket_name=self.bucket_name,
|
|
109
|
+
prefix=prefix,
|
|
110
|
+
config_id=self.id,
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
class SharePointConfig(RemoteContentConfig):
|
|
115
|
+
"""Configuration for SharePoint content source."""
|
|
116
|
+
|
|
117
|
+
tenant_id: str
|
|
118
|
+
client_id: str
|
|
119
|
+
client_secret: str
|
|
120
|
+
hostname: str
|
|
121
|
+
site_path: Optional[str] = None
|
|
122
|
+
site_id: Optional[str] = None # Full site ID (e.g., "contoso.sharepoint.com,guid1,guid2")
|
|
123
|
+
folder_path: Optional[str] = None
|
|
124
|
+
|
|
125
|
+
def file(self, file_path: str, site_path: Optional[str] = None) -> "SharePointContent":
|
|
126
|
+
"""Create a content reference for a specific file.
|
|
127
|
+
|
|
128
|
+
Args:
|
|
129
|
+
file_path: Path to the file in SharePoint.
|
|
130
|
+
site_path: Optional site path override.
|
|
131
|
+
|
|
132
|
+
Returns:
|
|
133
|
+
SharePointContent configured with this source's credentials.
|
|
134
|
+
"""
|
|
135
|
+
from agno.knowledge.remote_content.remote_content import SharePointContent
|
|
136
|
+
|
|
137
|
+
return SharePointContent(
|
|
138
|
+
config_id=self.id,
|
|
139
|
+
file_path=file_path,
|
|
140
|
+
site_path=site_path or self.site_path,
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
def folder(self, folder_path: str, site_path: Optional[str] = None) -> "SharePointContent":
|
|
144
|
+
"""Create a content reference for a folder.
|
|
145
|
+
|
|
146
|
+
Args:
|
|
147
|
+
folder_path: Path to the folder in SharePoint.
|
|
148
|
+
site_path: Optional site path override.
|
|
149
|
+
|
|
150
|
+
Returns:
|
|
151
|
+
SharePointContent configured with this source's credentials.
|
|
152
|
+
"""
|
|
153
|
+
from agno.knowledge.remote_content.remote_content import SharePointContent
|
|
154
|
+
|
|
155
|
+
return SharePointContent(
|
|
156
|
+
config_id=self.id,
|
|
157
|
+
folder_path=folder_path,
|
|
158
|
+
site_path=site_path or self.site_path,
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
class GitHubConfig(RemoteContentConfig):
|
|
163
|
+
"""Configuration for GitHub content source."""
|
|
164
|
+
|
|
165
|
+
repo: str
|
|
166
|
+
token: Optional[str] = None
|
|
167
|
+
branch: Optional[str] = None
|
|
168
|
+
path: Optional[str] = None
|
|
169
|
+
|
|
170
|
+
def file(self, file_path: str, branch: Optional[str] = None) -> "GitHubContent":
|
|
171
|
+
"""Create a content reference for a specific file.
|
|
172
|
+
|
|
173
|
+
Args:
|
|
174
|
+
file_path: Path to the file in the repository.
|
|
175
|
+
branch: Optional branch override.
|
|
176
|
+
|
|
177
|
+
Returns:
|
|
178
|
+
GitHubContent configured with this source's credentials.
|
|
179
|
+
"""
|
|
180
|
+
from agno.knowledge.remote_content.remote_content import GitHubContent
|
|
181
|
+
|
|
182
|
+
return GitHubContent(
|
|
183
|
+
config_id=self.id,
|
|
184
|
+
file_path=file_path,
|
|
185
|
+
branch=branch or self.branch,
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
def folder(self, folder_path: str, branch: Optional[str] = None) -> "GitHubContent":
|
|
189
|
+
"""Create a content reference for a folder.
|
|
190
|
+
|
|
191
|
+
Args:
|
|
192
|
+
folder_path: Path to the folder in the repository.
|
|
193
|
+
branch: Optional branch override.
|
|
194
|
+
|
|
195
|
+
Returns:
|
|
196
|
+
GitHubContent configured with this source's credentials.
|
|
197
|
+
"""
|
|
198
|
+
from agno.knowledge.remote_content.remote_content import GitHubContent
|
|
199
|
+
|
|
200
|
+
return GitHubContent(
|
|
201
|
+
config_id=self.id,
|
|
202
|
+
folder_path=folder_path,
|
|
203
|
+
branch=branch or self.branch,
|
|
204
|
+
)
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
class AzureBlobConfig(RemoteContentConfig):
|
|
208
|
+
"""Configuration for Azure Blob Storage content source.
|
|
209
|
+
|
|
210
|
+
Uses Azure AD client credentials flow for authentication.
|
|
211
|
+
|
|
212
|
+
Required Azure AD App Registration permissions:
|
|
213
|
+
- Storage Blob Data Reader (or Contributor) role on the storage account
|
|
214
|
+
|
|
215
|
+
Example:
|
|
216
|
+
```python
|
|
217
|
+
config = AzureBlobConfig(
|
|
218
|
+
id="company-docs",
|
|
219
|
+
name="Company Documents",
|
|
220
|
+
tenant_id=os.getenv("AZURE_TENANT_ID"),
|
|
221
|
+
client_id=os.getenv("AZURE_CLIENT_ID"),
|
|
222
|
+
client_secret=os.getenv("AZURE_CLIENT_SECRET"),
|
|
223
|
+
storage_account=os.getenv("AZURE_STORAGE_ACCOUNT_NAME"),
|
|
224
|
+
container=os.getenv("AZURE_CONTAINER_NAME"),
|
|
225
|
+
)
|
|
226
|
+
```
|
|
227
|
+
"""
|
|
228
|
+
|
|
229
|
+
tenant_id: str
|
|
230
|
+
client_id: str
|
|
231
|
+
client_secret: str
|
|
232
|
+
storage_account: str
|
|
233
|
+
container: str
|
|
234
|
+
prefix: Optional[str] = None
|
|
235
|
+
|
|
236
|
+
def file(self, blob_name: str) -> "AzureBlobContent":
|
|
237
|
+
"""Create a content reference for a specific blob (file).
|
|
238
|
+
|
|
239
|
+
Args:
|
|
240
|
+
blob_name: The blob name (path to file in container).
|
|
241
|
+
|
|
242
|
+
Returns:
|
|
243
|
+
AzureBlobContent configured with this source's credentials.
|
|
244
|
+
"""
|
|
245
|
+
from agno.knowledge.remote_content.remote_content import AzureBlobContent
|
|
246
|
+
|
|
247
|
+
return AzureBlobContent(
|
|
248
|
+
config_id=self.id,
|
|
249
|
+
blob_name=blob_name,
|
|
250
|
+
)
|
|
251
|
+
|
|
252
|
+
def folder(self, prefix: str) -> "AzureBlobContent":
|
|
253
|
+
"""Create a content reference for a folder (prefix).
|
|
254
|
+
|
|
255
|
+
Args:
|
|
256
|
+
prefix: The blob prefix (folder path).
|
|
257
|
+
|
|
258
|
+
Returns:
|
|
259
|
+
AzureBlobContent configured with this source's credentials.
|
|
260
|
+
"""
|
|
261
|
+
from agno.knowledge.remote_content.remote_content import AzureBlobContent
|
|
262
|
+
|
|
263
|
+
return AzureBlobContent(
|
|
264
|
+
config_id=self.id,
|
|
265
|
+
prefix=prefix,
|
|
266
|
+
)
|
|
@@ -14,21 +14,23 @@ class S3Content:
|
|
|
14
14
|
key: Optional[str] = None,
|
|
15
15
|
object: Optional[S3Object] = None,
|
|
16
16
|
prefix: Optional[str] = None,
|
|
17
|
+
config_id: Optional[str] = None,
|
|
17
18
|
):
|
|
18
19
|
self.bucket_name = bucket_name
|
|
19
20
|
self.bucket = bucket
|
|
20
21
|
self.key = key
|
|
21
22
|
self.object = object
|
|
22
23
|
self.prefix = prefix
|
|
24
|
+
self.config_id = config_id
|
|
23
25
|
|
|
24
26
|
if bucket_name is None and bucket is None:
|
|
25
27
|
raise ValueError("Either bucket_name or bucket must be provided")
|
|
26
|
-
if key is None and object is None:
|
|
27
|
-
raise ValueError("Either key or
|
|
28
|
+
if key is None and object is None and prefix is None:
|
|
29
|
+
raise ValueError("Either key, object, or prefix must be provided")
|
|
28
30
|
if bucket_name is not None and bucket is not None:
|
|
29
31
|
raise ValueError("Either bucket_name or bucket must be provided, not both")
|
|
30
|
-
if
|
|
31
|
-
raise ValueError("
|
|
32
|
+
if sum(x is not None for x in [key, object, prefix]) > 1:
|
|
33
|
+
raise ValueError("Only one of key, object, or prefix should be provided")
|
|
32
34
|
|
|
33
35
|
if self.bucket_name is not None:
|
|
34
36
|
self.bucket = S3Bucket(name=self.bucket_name)
|
|
@@ -40,6 +42,7 @@ class S3Content:
|
|
|
40
42
|
"key": self.key,
|
|
41
43
|
"object": self.object,
|
|
42
44
|
"prefix": self.prefix,
|
|
45
|
+
"config_id": self.config_id,
|
|
43
46
|
}
|
|
44
47
|
|
|
45
48
|
|
|
@@ -51,19 +54,13 @@ class GCSContent:
|
|
|
51
54
|
bucket_name: Optional[str] = None,
|
|
52
55
|
blob_name: Optional[str] = None,
|
|
53
56
|
prefix: Optional[str] = None,
|
|
57
|
+
config_id: Optional[str] = None,
|
|
54
58
|
):
|
|
55
|
-
# Import Google Cloud Storage only when actually needed
|
|
56
|
-
try:
|
|
57
|
-
from google.cloud import storage # type: ignore
|
|
58
|
-
except ImportError:
|
|
59
|
-
raise ImportError(
|
|
60
|
-
"The `google-cloud-storage` package is not installed. Please install it via `pip install google-cloud-storage`."
|
|
61
|
-
)
|
|
62
|
-
|
|
63
59
|
self.bucket = bucket
|
|
64
60
|
self.bucket_name = bucket_name
|
|
65
61
|
self.blob_name = blob_name
|
|
66
62
|
self.prefix = prefix
|
|
63
|
+
self.config_id = config_id
|
|
67
64
|
|
|
68
65
|
if self.bucket is None and self.bucket_name is None:
|
|
69
66
|
raise ValueError("No bucket or bucket_name provided")
|
|
@@ -72,17 +69,108 @@ class GCSContent:
|
|
|
72
69
|
if self.blob_name is None and self.prefix is None:
|
|
73
70
|
raise ValueError("Either blob_name or prefix must be provided")
|
|
74
71
|
|
|
75
|
-
if self.bucket is None:
|
|
76
|
-
client = storage.Client()
|
|
77
|
-
self.bucket = client.bucket(self.bucket_name)
|
|
78
|
-
|
|
79
72
|
def get_config(self):
|
|
80
73
|
return {
|
|
81
74
|
"bucket": self.bucket,
|
|
82
75
|
"bucket_name": self.bucket_name,
|
|
83
76
|
"blob_name": self.blob_name,
|
|
84
77
|
"prefix": self.prefix,
|
|
78
|
+
"config_id": self.config_id,
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
@dataclass
|
|
83
|
+
class SharePointContent:
|
|
84
|
+
"""Content reference for SharePoint files."""
|
|
85
|
+
|
|
86
|
+
def __init__(
|
|
87
|
+
self,
|
|
88
|
+
config_id: str,
|
|
89
|
+
file_path: Optional[str] = None,
|
|
90
|
+
folder_path: Optional[str] = None,
|
|
91
|
+
site_path: Optional[str] = None,
|
|
92
|
+
drive_id: Optional[str] = None,
|
|
93
|
+
):
|
|
94
|
+
self.config_id = config_id
|
|
95
|
+
self.file_path = file_path
|
|
96
|
+
self.folder_path = folder_path
|
|
97
|
+
self.site_path = site_path
|
|
98
|
+
self.drive_id = drive_id
|
|
99
|
+
|
|
100
|
+
if self.file_path is None and self.folder_path is None:
|
|
101
|
+
raise ValueError("Either file_path or folder_path must be provided")
|
|
102
|
+
if self.file_path is not None and self.folder_path is not None:
|
|
103
|
+
raise ValueError("Provide either file_path or folder_path, not both")
|
|
104
|
+
|
|
105
|
+
def get_config(self):
|
|
106
|
+
return {
|
|
107
|
+
"config_id": self.config_id,
|
|
108
|
+
"file_path": self.file_path,
|
|
109
|
+
"folder_path": self.folder_path,
|
|
110
|
+
"site_path": self.site_path,
|
|
111
|
+
"drive_id": self.drive_id,
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
@dataclass
|
|
116
|
+
class GitHubContent:
|
|
117
|
+
"""Content reference for GitHub files."""
|
|
118
|
+
|
|
119
|
+
def __init__(
|
|
120
|
+
self,
|
|
121
|
+
config_id: str,
|
|
122
|
+
file_path: Optional[str] = None,
|
|
123
|
+
folder_path: Optional[str] = None,
|
|
124
|
+
branch: Optional[str] = None,
|
|
125
|
+
):
|
|
126
|
+
self.config_id = config_id
|
|
127
|
+
self.file_path = file_path
|
|
128
|
+
self.folder_path = folder_path
|
|
129
|
+
self.branch = branch
|
|
130
|
+
|
|
131
|
+
if self.file_path is None and self.folder_path is None:
|
|
132
|
+
raise ValueError("Either file_path or folder_path must be provided")
|
|
133
|
+
if self.file_path is not None and self.folder_path is not None:
|
|
134
|
+
raise ValueError("Provide either file_path or folder_path, not both")
|
|
135
|
+
|
|
136
|
+
def get_config(self):
|
|
137
|
+
return {
|
|
138
|
+
"config_id": self.config_id,
|
|
139
|
+
"file_path": self.file_path,
|
|
140
|
+
"folder_path": self.folder_path,
|
|
141
|
+
"branch": self.branch,
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
@dataclass
|
|
146
|
+
class AzureBlobContent:
|
|
147
|
+
"""Content reference for Azure Blob Storage files.
|
|
148
|
+
|
|
149
|
+
Used with AzureBlobConfig to load files from Azure Blob Storage containers.
|
|
150
|
+
Supports loading single blobs or entire prefixes (folders).
|
|
151
|
+
"""
|
|
152
|
+
|
|
153
|
+
def __init__(
|
|
154
|
+
self,
|
|
155
|
+
config_id: str,
|
|
156
|
+
blob_name: Optional[str] = None,
|
|
157
|
+
prefix: Optional[str] = None,
|
|
158
|
+
):
|
|
159
|
+
self.config_id = config_id
|
|
160
|
+
self.blob_name = blob_name
|
|
161
|
+
self.prefix = prefix
|
|
162
|
+
|
|
163
|
+
if self.blob_name is None and self.prefix is None:
|
|
164
|
+
raise ValueError("Either blob_name or prefix must be provided")
|
|
165
|
+
if self.blob_name is not None and self.prefix is not None:
|
|
166
|
+
raise ValueError("Provide either blob_name or prefix, not both")
|
|
167
|
+
|
|
168
|
+
def get_config(self):
|
|
169
|
+
return {
|
|
170
|
+
"config_id": self.config_id,
|
|
171
|
+
"blob_name": self.blob_name,
|
|
172
|
+
"prefix": self.prefix,
|
|
85
173
|
}
|
|
86
174
|
|
|
87
175
|
|
|
88
|
-
RemoteContent = Union[S3Content, GCSContent]
|
|
176
|
+
RemoteContent = Union[S3Content, GCSContent, SharePointContent, GitHubContent, AzureBlobContent]
|
agno/knowledge/utils.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
from typing import Dict, List
|
|
1
|
+
from typing import Any, Dict, List, Optional
|
|
2
2
|
|
|
3
|
+
from agno.knowledge.reader.base import Reader
|
|
3
4
|
from agno.knowledge.reader.reader_factory import ReaderFactory
|
|
4
5
|
from agno.knowledge.types import ContentType
|
|
5
6
|
from agno.utils.log import log_debug
|
|
@@ -14,6 +15,7 @@ def _get_chunker_class(strategy_type):
|
|
|
14
15
|
ChunkingStrategyType.AGENTIC_CHUNKER: lambda: _import_class(
|
|
15
16
|
"agno.knowledge.chunking.agentic", "AgenticChunking"
|
|
16
17
|
),
|
|
18
|
+
ChunkingStrategyType.CODE_CHUNKER: lambda: _import_class("agno.knowledge.chunking.code", "CodeChunking"),
|
|
17
19
|
ChunkingStrategyType.DOCUMENT_CHUNKER: lambda: _import_class(
|
|
18
20
|
"agno.knowledge.chunking.document", "DocumentChunking"
|
|
19
21
|
),
|
|
@@ -47,26 +49,28 @@ def _import_class(module_name: str, class_name: str):
|
|
|
47
49
|
|
|
48
50
|
|
|
49
51
|
def get_reader_info(reader_key: str) -> Dict:
|
|
50
|
-
"""Get information about a reader without instantiating it.
|
|
51
|
-
|
|
52
|
+
"""Get information about a reader without instantiating it.
|
|
53
|
+
|
|
54
|
+
Uses class methods and static metadata from ReaderFactory to avoid
|
|
55
|
+
the overhead of creating reader instances.
|
|
56
|
+
"""
|
|
52
57
|
try:
|
|
53
|
-
|
|
58
|
+
# Get the reader CLASS without instantiation
|
|
59
|
+
reader_class = ReaderFactory.get_reader_class(reader_key)
|
|
54
60
|
|
|
55
|
-
#
|
|
56
|
-
|
|
57
|
-
reader_class = reader_instance.__class__
|
|
61
|
+
# Get metadata from static registry (no instantiation needed)
|
|
62
|
+
metadata = ReaderFactory.READER_METADATA.get(reader_key, {})
|
|
58
63
|
|
|
59
|
-
|
|
60
|
-
|
|
64
|
+
# Call class methods directly (no instance needed)
|
|
65
|
+
supported_strategies = reader_class.get_supported_chunking_strategies() # type: ignore[attr-defined]
|
|
66
|
+
supported_content_types = reader_class.get_supported_content_types() # type: ignore[attr-defined]
|
|
61
67
|
|
|
62
68
|
return {
|
|
63
69
|
"id": reader_key,
|
|
64
|
-
"name": ""
|
|
65
|
-
"description":
|
|
66
|
-
"chunking_strategies": [
|
|
67
|
-
|
|
68
|
-
], # Convert enums to string values
|
|
69
|
-
"content_types": [ct.value for ct in supported_content_types], # Convert enums to string values
|
|
70
|
+
"name": metadata.get("name", reader_class.__name__),
|
|
71
|
+
"description": metadata.get("description", f"{reader_class.__name__} reader"),
|
|
72
|
+
"chunking_strategies": [strategy.value for strategy in supported_strategies],
|
|
73
|
+
"content_types": [ct.value for ct in supported_content_types],
|
|
70
74
|
}
|
|
71
75
|
except ImportError as e:
|
|
72
76
|
# Skip readers with missing dependencies
|
|
@@ -75,31 +79,79 @@ def get_reader_info(reader_key: str) -> Dict:
|
|
|
75
79
|
raise ValueError(f"Unknown reader: {reader_key}. Error: {str(e)}")
|
|
76
80
|
|
|
77
81
|
|
|
78
|
-
def
|
|
79
|
-
"""Get information about
|
|
82
|
+
def get_reader_info_from_instance(reader: Reader, reader_id: str) -> Dict:
|
|
83
|
+
"""Get information about a reader instance."""
|
|
84
|
+
try:
|
|
85
|
+
reader_class = reader.__class__
|
|
86
|
+
supported_strategies = reader_class.get_supported_chunking_strategies()
|
|
87
|
+
supported_content_types = reader_class.get_supported_content_types()
|
|
88
|
+
|
|
89
|
+
return {
|
|
90
|
+
"id": reader_id,
|
|
91
|
+
"name": getattr(reader, "name", reader_class.__name__),
|
|
92
|
+
"description": getattr(reader, "description", f"Custom {reader_class.__name__}"),
|
|
93
|
+
"chunking_strategies": [strategy.value for strategy in supported_strategies],
|
|
94
|
+
"content_types": [ct.value for ct in supported_content_types],
|
|
95
|
+
}
|
|
96
|
+
except Exception as e:
|
|
97
|
+
raise ValueError(f"Failed to get info for reader '{reader_id}': {str(e)}")
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def get_all_readers_info(knowledge_instance: Optional[Any] = None) -> List[Dict]:
|
|
101
|
+
"""Get information about all available readers, including custom readers from a Knowledge instance.
|
|
102
|
+
|
|
103
|
+
Custom readers are added first and take precedence over factory readers with the same ID.
|
|
104
|
+
|
|
105
|
+
Args:
|
|
106
|
+
knowledge_instance: Optional Knowledge instance to include custom readers from.
|
|
107
|
+
|
|
108
|
+
Returns:
|
|
109
|
+
List of reader info dictionaries (custom readers first, then factory readers).
|
|
110
|
+
"""
|
|
80
111
|
readers_info = []
|
|
112
|
+
seen_ids: set = set()
|
|
113
|
+
|
|
114
|
+
# 1. Add custom readers FIRST (they take precedence over factory readers)
|
|
115
|
+
if knowledge_instance is not None:
|
|
116
|
+
custom_readers = knowledge_instance.get_readers()
|
|
117
|
+
if isinstance(custom_readers, dict):
|
|
118
|
+
for reader_id, reader in custom_readers.items():
|
|
119
|
+
try:
|
|
120
|
+
reader_info = get_reader_info_from_instance(reader, reader_id)
|
|
121
|
+
readers_info.append(reader_info)
|
|
122
|
+
seen_ids.add(reader_id)
|
|
123
|
+
except ValueError as e:
|
|
124
|
+
log_debug(f"Skipping custom reader '{reader_id}': {e}")
|
|
125
|
+
continue
|
|
126
|
+
|
|
127
|
+
# 2. Add factory readers (skip if custom reader with same ID already exists)
|
|
81
128
|
keys = ReaderFactory.get_all_reader_keys()
|
|
82
129
|
for key in keys:
|
|
130
|
+
if key in seen_ids:
|
|
131
|
+
# Custom reader with this ID already added, skip factory version
|
|
132
|
+
continue
|
|
83
133
|
try:
|
|
84
134
|
reader_info = get_reader_info(key)
|
|
85
135
|
readers_info.append(reader_info)
|
|
86
136
|
except ValueError as e:
|
|
87
137
|
# Skip readers with missing dependencies or other issues
|
|
88
|
-
# Log the error but don't fail the entire request
|
|
89
138
|
log_debug(f"Skipping reader '{key}': {e}")
|
|
90
139
|
continue
|
|
140
|
+
|
|
91
141
|
return readers_info
|
|
92
142
|
|
|
93
143
|
|
|
94
|
-
def get_content_types_to_readers_mapping() -> Dict[str, List[str]]:
|
|
144
|
+
def get_content_types_to_readers_mapping(knowledge_instance: Optional[Any] = None) -> Dict[str, List[str]]:
|
|
95
145
|
"""Get mapping of content types to list of reader IDs that support them.
|
|
96
146
|
|
|
147
|
+
Args:
|
|
148
|
+
knowledge_instance: Optional Knowledge instance to include custom readers from.
|
|
149
|
+
|
|
97
150
|
Returns:
|
|
98
151
|
Dictionary mapping content type strings (ContentType enum values) to list of reader IDs.
|
|
99
152
|
"""
|
|
100
153
|
content_type_mapping: Dict[str, List[str]] = {}
|
|
101
|
-
readers_info = get_all_readers_info()
|
|
102
|
-
|
|
154
|
+
readers_info = get_all_readers_info(knowledge_instance)
|
|
103
155
|
for reader_info in readers_info:
|
|
104
156
|
reader_id = reader_info["id"]
|
|
105
157
|
content_types = reader_info.get("content_types", [])
|
|
@@ -107,7 +159,9 @@ def get_content_types_to_readers_mapping() -> Dict[str, List[str]]:
|
|
|
107
159
|
for content_type in content_types:
|
|
108
160
|
if content_type not in content_type_mapping:
|
|
109
161
|
content_type_mapping[content_type] = []
|
|
110
|
-
|
|
162
|
+
# Avoid duplicates
|
|
163
|
+
if reader_id not in content_type_mapping[content_type]:
|
|
164
|
+
content_type_mapping[content_type].append(reader_id)
|
|
111
165
|
|
|
112
166
|
return content_type_mapping
|
|
113
167
|
|
agno/learn/__init__.py
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Agno Learning Module
|
|
3
|
+
====================
|
|
4
|
+
Gives agents the ability to learn and remember.
|
|
5
|
+
|
|
6
|
+
Main Components:
|
|
7
|
+
- LearningMachine: Unified learning system
|
|
8
|
+
- Config: Configuration for learning types
|
|
9
|
+
- Schemas: Data structures for learning types
|
|
10
|
+
- Stores: Storage backends for learning types
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from agno.learn.config import (
|
|
14
|
+
DecisionLogConfig,
|
|
15
|
+
EntityMemoryConfig,
|
|
16
|
+
LearnedKnowledgeConfig,
|
|
17
|
+
LearningMode,
|
|
18
|
+
MemoriesConfig,
|
|
19
|
+
SessionContextConfig,
|
|
20
|
+
UserMemoryConfig,
|
|
21
|
+
UserProfileConfig,
|
|
22
|
+
)
|
|
23
|
+
from agno.learn.machine import LearningMachine
|
|
24
|
+
from agno.learn.schemas import (
|
|
25
|
+
DecisionLog,
|
|
26
|
+
EntityMemory,
|
|
27
|
+
LearnedKnowledge,
|
|
28
|
+
Memories,
|
|
29
|
+
SessionContext,
|
|
30
|
+
UserProfile,
|
|
31
|
+
)
|
|
32
|
+
from agno.learn.stores import (
|
|
33
|
+
DecisionLogStore,
|
|
34
|
+
EntityMemoryStore,
|
|
35
|
+
LearnedKnowledgeStore,
|
|
36
|
+
LearningStore,
|
|
37
|
+
MemoriesStore,
|
|
38
|
+
SessionContextStore,
|
|
39
|
+
UserMemoryStore,
|
|
40
|
+
UserProfileStore,
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
__all__ = [
|
|
44
|
+
# Main class
|
|
45
|
+
"LearningMachine",
|
|
46
|
+
# Configs
|
|
47
|
+
"LearningMode",
|
|
48
|
+
"UserProfileConfig",
|
|
49
|
+
"UserMemoryConfig",
|
|
50
|
+
"MemoriesConfig", # Backwards compatibility alias
|
|
51
|
+
"EntityMemoryConfig",
|
|
52
|
+
"SessionContextConfig",
|
|
53
|
+
"LearnedKnowledgeConfig",
|
|
54
|
+
"DecisionLogConfig", # Phase 2
|
|
55
|
+
# Schemas
|
|
56
|
+
"UserProfile",
|
|
57
|
+
"Memories",
|
|
58
|
+
"EntityMemory",
|
|
59
|
+
"SessionContext",
|
|
60
|
+
"LearnedKnowledge",
|
|
61
|
+
"DecisionLog", # Phase 2
|
|
62
|
+
# Stores
|
|
63
|
+
"LearningStore",
|
|
64
|
+
"UserProfileStore",
|
|
65
|
+
"UserMemoryStore",
|
|
66
|
+
"MemoriesStore", # Backwards compatibility alias
|
|
67
|
+
"SessionContextStore",
|
|
68
|
+
"LearnedKnowledgeStore",
|
|
69
|
+
"EntityMemoryStore",
|
|
70
|
+
"DecisionLogStore", # Phase 2
|
|
71
|
+
]
|