agno 2.0.0rc1__py3-none-any.whl → 2.0.1__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/agent.py +101 -140
- agno/db/mongo/mongo.py +8 -3
- agno/eval/accuracy.py +12 -5
- agno/knowledge/chunking/strategy.py +14 -14
- agno/knowledge/knowledge.py +156 -120
- agno/knowledge/reader/arxiv_reader.py +5 -5
- agno/knowledge/reader/csv_reader.py +6 -77
- agno/knowledge/reader/docx_reader.py +5 -5
- agno/knowledge/reader/firecrawl_reader.py +5 -5
- agno/knowledge/reader/json_reader.py +5 -5
- agno/knowledge/reader/markdown_reader.py +31 -9
- agno/knowledge/reader/pdf_reader.py +10 -123
- agno/knowledge/reader/reader_factory.py +65 -72
- agno/knowledge/reader/s3_reader.py +44 -114
- agno/knowledge/reader/text_reader.py +5 -5
- agno/knowledge/reader/url_reader.py +75 -31
- agno/knowledge/reader/web_search_reader.py +6 -29
- agno/knowledge/reader/website_reader.py +5 -5
- agno/knowledge/reader/wikipedia_reader.py +5 -5
- agno/knowledge/reader/youtube_reader.py +6 -6
- agno/knowledge/reranker/__init__.py +9 -0
- agno/knowledge/utils.py +10 -10
- agno/media.py +269 -268
- agno/models/aws/bedrock.py +3 -7
- agno/models/base.py +50 -54
- agno/models/google/gemini.py +11 -10
- agno/models/message.py +4 -4
- agno/models/ollama/chat.py +1 -1
- agno/models/openai/chat.py +33 -14
- agno/models/response.py +5 -5
- agno/os/app.py +40 -29
- agno/os/mcp.py +39 -59
- agno/os/router.py +547 -16
- agno/os/routers/evals/evals.py +197 -12
- agno/os/routers/knowledge/knowledge.py +428 -14
- agno/os/routers/memory/memory.py +250 -28
- agno/os/routers/metrics/metrics.py +125 -7
- agno/os/routers/session/session.py +393 -25
- agno/os/schema.py +55 -2
- agno/run/agent.py +37 -28
- agno/run/base.py +9 -19
- agno/run/team.py +110 -19
- agno/run/workflow.py +41 -28
- agno/team/team.py +808 -1080
- agno/tools/brightdata.py +3 -3
- agno/tools/cartesia.py +3 -5
- agno/tools/dalle.py +7 -4
- agno/tools/desi_vocal.py +2 -2
- agno/tools/e2b.py +6 -6
- agno/tools/eleven_labs.py +3 -3
- agno/tools/fal.py +4 -4
- agno/tools/function.py +7 -7
- agno/tools/giphy.py +2 -2
- agno/tools/lumalab.py +3 -3
- agno/tools/mcp.py +1 -2
- agno/tools/models/azure_openai.py +2 -2
- agno/tools/models/gemini.py +3 -3
- agno/tools/models/groq.py +3 -5
- agno/tools/models/nebius.py +2 -2
- agno/tools/models_labs.py +5 -5
- agno/tools/openai.py +4 -9
- agno/tools/opencv.py +3 -3
- agno/tools/replicate.py +7 -7
- agno/utils/events.py +5 -5
- agno/utils/gemini.py +1 -1
- agno/utils/log.py +52 -2
- agno/utils/mcp.py +57 -5
- agno/utils/models/aws_claude.py +1 -1
- agno/utils/models/claude.py +0 -8
- agno/utils/models/cohere.py +1 -1
- agno/utils/models/watsonx.py +1 -1
- agno/utils/openai.py +1 -1
- agno/utils/print_response/team.py +177 -73
- agno/utils/streamlit.py +27 -0
- agno/vectordb/lancedb/lance_db.py +82 -25
- agno/workflow/step.py +7 -7
- agno/workflow/types.py +13 -13
- agno/workflow/workflow.py +37 -28
- {agno-2.0.0rc1.dist-info → agno-2.0.1.dist-info}/METADATA +140 -1
- {agno-2.0.0rc1.dist-info → agno-2.0.1.dist-info}/RECORD +83 -84
- agno-2.0.1.dist-info/licenses/LICENSE +201 -0
- agno/knowledge/reader/gcs_reader.py +0 -67
- agno-2.0.0rc1.dist-info/licenses/LICENSE +0 -375
- {agno-2.0.0rc1.dist-info → agno-2.0.1.dist-info}/WHEEL +0 -0
- {agno-2.0.0rc1.dist-info → agno-2.0.1.dist-info}/top_level.txt +0 -0
|
@@ -21,11 +21,11 @@ class TextReader(Reader):
|
|
|
21
21
|
def get_supported_chunking_strategies(self) -> List[ChunkingStrategyType]:
|
|
22
22
|
"""Get the list of supported chunking strategies for Text readers."""
|
|
23
23
|
return [
|
|
24
|
-
ChunkingStrategyType.
|
|
25
|
-
ChunkingStrategyType.
|
|
26
|
-
ChunkingStrategyType.
|
|
27
|
-
ChunkingStrategyType.
|
|
28
|
-
ChunkingStrategyType.
|
|
24
|
+
ChunkingStrategyType.FIXED_SIZE_CHUNKER,
|
|
25
|
+
ChunkingStrategyType.AGENTIC_CHUNKER,
|
|
26
|
+
ChunkingStrategyType.DOCUMENT_CHUNKER,
|
|
27
|
+
ChunkingStrategyType.RECURSIVE_CHUNKER,
|
|
28
|
+
ChunkingStrategyType.SEMANTIC_CHUNKER,
|
|
29
29
|
]
|
|
30
30
|
|
|
31
31
|
@classmethod
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
from io import BytesIO
|
|
2
|
+
from os.path import basename
|
|
3
|
+
from pathlib import Path
|
|
1
4
|
from typing import List, Optional
|
|
2
5
|
from urllib.parse import urlparse
|
|
3
6
|
|
|
@@ -7,6 +10,8 @@ from agno.knowledge.chunking.fixed import FixedSizeChunking
|
|
|
7
10
|
from agno.knowledge.chunking.strategy import ChunkingStrategy, ChunkingStrategyType
|
|
8
11
|
from agno.knowledge.document.base import Document
|
|
9
12
|
from agno.knowledge.reader.base import Reader
|
|
13
|
+
from agno.knowledge.reader.csv_reader import CSVReader
|
|
14
|
+
from agno.knowledge.reader.pdf_reader import PDFReader
|
|
10
15
|
from agno.knowledge.types import ContentType
|
|
11
16
|
from agno.utils.http import async_fetch_with_retry, fetch_with_retry
|
|
12
17
|
from agno.utils.log import log_debug
|
|
@@ -25,31 +30,43 @@ class URLReader(Reader):
|
|
|
25
30
|
def get_supported_chunking_strategies(self) -> List[ChunkingStrategyType]:
|
|
26
31
|
"""Get the list of supported chunking strategies for URL readers."""
|
|
27
32
|
return [
|
|
28
|
-
ChunkingStrategyType.
|
|
29
|
-
ChunkingStrategyType.
|
|
30
|
-
ChunkingStrategyType.
|
|
31
|
-
ChunkingStrategyType.
|
|
32
|
-
ChunkingStrategyType.
|
|
33
|
+
ChunkingStrategyType.FIXED_SIZE_CHUNKER,
|
|
34
|
+
ChunkingStrategyType.AGENTIC_CHUNKER,
|
|
35
|
+
ChunkingStrategyType.DOCUMENT_CHUNKER,
|
|
36
|
+
ChunkingStrategyType.RECURSIVE_CHUNKER,
|
|
37
|
+
ChunkingStrategyType.SEMANTIC_CHUNKER,
|
|
33
38
|
]
|
|
34
39
|
|
|
35
40
|
@classmethod
|
|
36
41
|
def get_supported_content_types(self) -> List[ContentType]:
|
|
37
42
|
return [ContentType.URL]
|
|
38
43
|
|
|
39
|
-
def read(
|
|
44
|
+
def read(
|
|
45
|
+
self, url: str, id: Optional[str] = None, name: Optional[str] = None, password: Optional[str] = None
|
|
46
|
+
) -> List[Document]:
|
|
40
47
|
if not url:
|
|
41
48
|
raise ValueError("No url provided")
|
|
42
49
|
|
|
43
50
|
log_debug(f"Reading: {url}")
|
|
51
|
+
|
|
44
52
|
# Retry the request up to 3 times with exponential backoff
|
|
45
53
|
response = fetch_with_retry(url, proxy=self.proxy)
|
|
46
54
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
55
|
+
documents = self._create_documents(
|
|
56
|
+
url=url, text=response.text, content=response.content, id=id, name=name, password=password
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
if not self.chunk:
|
|
60
|
+
return documents
|
|
61
|
+
|
|
62
|
+
chunked_documents = []
|
|
63
|
+
for document in documents:
|
|
64
|
+
chunked_documents.append(self.chunk_document(document))
|
|
65
|
+
return [doc for sublist in chunked_documents for doc in sublist]
|
|
51
66
|
|
|
52
|
-
async def async_read(
|
|
67
|
+
async def async_read(
|
|
68
|
+
self, url: str, id: Optional[str] = None, name: Optional[str] = None, password: Optional[str] = None
|
|
69
|
+
) -> List[Document]:
|
|
53
70
|
"""Async version of read method"""
|
|
54
71
|
if not url:
|
|
55
72
|
raise ValueError("No url provided")
|
|
@@ -59,26 +76,53 @@ class URLReader(Reader):
|
|
|
59
76
|
async with httpx.AsyncClient(**client_args) as client: # type: ignore
|
|
60
77
|
response = await async_fetch_with_retry(url, client=client)
|
|
61
78
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
79
|
+
documents = self._create_documents(
|
|
80
|
+
url=url, text=response.text, content=response.content, id=id, name=name, password=password
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
if not self.chunk:
|
|
84
|
+
return documents
|
|
85
|
+
|
|
86
|
+
return await self.chunk_documents_async(documents)
|
|
66
87
|
|
|
67
|
-
def
|
|
68
|
-
self,
|
|
69
|
-
|
|
88
|
+
def _create_documents(
|
|
89
|
+
self,
|
|
90
|
+
url: str,
|
|
91
|
+
text: str,
|
|
92
|
+
content: bytes,
|
|
93
|
+
id: Optional[str] = None,
|
|
94
|
+
name: Optional[str] = None,
|
|
95
|
+
password: Optional[str] = None,
|
|
96
|
+
) -> List[Document]:
|
|
70
97
|
"""Helper method to create a document from URL content"""
|
|
98
|
+
|
|
99
|
+
# Determine file extension from URL
|
|
71
100
|
parsed_url = urlparse(url)
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
101
|
+
url_path = Path(parsed_url.path) # type: ignore
|
|
102
|
+
file_extension = url_path.suffix.lower()
|
|
103
|
+
|
|
104
|
+
# Read the document using the appropriate reader
|
|
105
|
+
if file_extension == ".csv":
|
|
106
|
+
filename = basename(parsed_url.path) or "data.csv"
|
|
107
|
+
return CSVReader().read(file=BytesIO(content), name=filename)
|
|
108
|
+
elif file_extension == ".pdf":
|
|
109
|
+
if password:
|
|
110
|
+
return PDFReader().read(pdf=BytesIO(content), name=name, password=password)
|
|
111
|
+
else:
|
|
112
|
+
return PDFReader().read(pdf=BytesIO(content), name=name)
|
|
113
|
+
else:
|
|
114
|
+
doc_name = name or parsed_url.path.strip("/").replace("/", "_").replace(" ", "_")
|
|
115
|
+
if not doc_name:
|
|
116
|
+
doc_name = parsed_url.netloc
|
|
117
|
+
if not doc_name:
|
|
118
|
+
doc_name = url
|
|
119
|
+
|
|
120
|
+
return [
|
|
121
|
+
Document(
|
|
122
|
+
name=doc_name,
|
|
123
|
+
id=id or doc_name,
|
|
124
|
+
meta_data={"url": url},
|
|
125
|
+
content=text,
|
|
126
|
+
size=len(text),
|
|
127
|
+
)
|
|
128
|
+
]
|
|
@@ -11,7 +11,6 @@ from agno.knowledge.chunking.semantic import SemanticChunking
|
|
|
11
11
|
from agno.knowledge.chunking.strategy import ChunkingStrategy, ChunkingStrategyType
|
|
12
12
|
from agno.knowledge.document.base import Document
|
|
13
13
|
from agno.knowledge.reader.base import Reader
|
|
14
|
-
from agno.knowledge.reader.url_reader import URLReader
|
|
15
14
|
from agno.knowledge.types import ContentType
|
|
16
15
|
from agno.utils.log import log_debug, logger
|
|
17
16
|
|
|
@@ -48,30 +47,25 @@ class WebSearchReader(Reader):
|
|
|
48
47
|
|
|
49
48
|
# Internal state
|
|
50
49
|
_visited_urls: Set[str] = field(default_factory=set)
|
|
51
|
-
_url_reader: Optional[URLReader] = None
|
|
52
50
|
_last_search_time: float = field(default=0.0, init=False)
|
|
53
51
|
|
|
54
52
|
# Override default chunking strategy
|
|
55
53
|
chunking_strategy: Optional[ChunkingStrategy] = SemanticChunking()
|
|
56
54
|
|
|
57
|
-
def __post_init__(self):
|
|
58
|
-
"""Initialize the URL reader and chunking strategy after dataclass initialization"""
|
|
59
|
-
self._url_reader = URLReader()
|
|
60
|
-
|
|
61
55
|
@classmethod
|
|
62
56
|
def get_supported_chunking_strategies(self) -> List[ChunkingStrategyType]:
|
|
63
57
|
"""Get the list of supported chunking strategies for Web Search readers."""
|
|
64
58
|
return [
|
|
65
|
-
ChunkingStrategyType.
|
|
66
|
-
ChunkingStrategyType.
|
|
67
|
-
ChunkingStrategyType.
|
|
68
|
-
ChunkingStrategyType.
|
|
69
|
-
ChunkingStrategyType.
|
|
59
|
+
ChunkingStrategyType.AGENTIC_CHUNKER,
|
|
60
|
+
ChunkingStrategyType.DOCUMENT_CHUNKER,
|
|
61
|
+
ChunkingStrategyType.RECURSIVE_CHUNKER,
|
|
62
|
+
ChunkingStrategyType.SEMANTIC_CHUNKER,
|
|
63
|
+
ChunkingStrategyType.FIXED_SIZE_CHUNKER,
|
|
70
64
|
]
|
|
71
65
|
|
|
72
66
|
@classmethod
|
|
73
67
|
def get_supported_content_types(self) -> List[ContentType]:
|
|
74
|
-
return [ContentType.
|
|
68
|
+
return [ContentType.TOPIC]
|
|
75
69
|
|
|
76
70
|
def _respect_rate_limits(self):
|
|
77
71
|
"""Ensure we don't exceed rate limits"""
|
|
@@ -328,23 +322,6 @@ class WebSearchReader(Reader):
|
|
|
328
322
|
self._visited_urls.add(url)
|
|
329
323
|
|
|
330
324
|
try:
|
|
331
|
-
# Use the URL reader for async fetching
|
|
332
|
-
if self._url_reader:
|
|
333
|
-
docs = await self._url_reader.async_read(url)
|
|
334
|
-
if docs:
|
|
335
|
-
# Use the first document and add search metadata
|
|
336
|
-
doc = docs[0]
|
|
337
|
-
doc.meta_data.update(
|
|
338
|
-
{
|
|
339
|
-
"search_title": result.get("title", ""),
|
|
340
|
-
"search_description": result.get("description", ""),
|
|
341
|
-
"source": "web_search",
|
|
342
|
-
"search_engine": self.search_engine,
|
|
343
|
-
}
|
|
344
|
-
)
|
|
345
|
-
return doc
|
|
346
|
-
|
|
347
|
-
# Fallback to manual async fetching
|
|
348
325
|
headers = {"User-Agent": self.user_agent}
|
|
349
326
|
async with httpx.AsyncClient(timeout=self.request_timeout) as client:
|
|
350
327
|
response = await client.get(url, headers=headers, follow_redirects=True)
|
|
@@ -52,11 +52,11 @@ class WebsiteReader(Reader):
|
|
|
52
52
|
def get_supported_chunking_strategies(self) -> List[ChunkingStrategyType]:
|
|
53
53
|
"""Get the list of supported chunking strategies for Website readers."""
|
|
54
54
|
return [
|
|
55
|
-
ChunkingStrategyType.
|
|
56
|
-
ChunkingStrategyType.
|
|
57
|
-
ChunkingStrategyType.
|
|
58
|
-
ChunkingStrategyType.
|
|
59
|
-
ChunkingStrategyType.
|
|
55
|
+
ChunkingStrategyType.AGENTIC_CHUNKER,
|
|
56
|
+
ChunkingStrategyType.DOCUMENT_CHUNKER,
|
|
57
|
+
ChunkingStrategyType.RECURSIVE_CHUNKER,
|
|
58
|
+
ChunkingStrategyType.SEMANTIC_CHUNKER,
|
|
59
|
+
ChunkingStrategyType.FIXED_SIZE_CHUNKER,
|
|
60
60
|
]
|
|
61
61
|
|
|
62
62
|
@classmethod
|
|
@@ -26,11 +26,11 @@ class WikipediaReader(Reader):
|
|
|
26
26
|
def get_supported_chunking_strategies(self) -> List[ChunkingStrategyType]:
|
|
27
27
|
"""Get the list of supported chunking strategies for Wikipedia readers."""
|
|
28
28
|
return [
|
|
29
|
-
ChunkingStrategyType.
|
|
30
|
-
ChunkingStrategyType.
|
|
31
|
-
ChunkingStrategyType.
|
|
32
|
-
ChunkingStrategyType.
|
|
33
|
-
ChunkingStrategyType.
|
|
29
|
+
ChunkingStrategyType.FIXED_SIZE_CHUNKER,
|
|
30
|
+
ChunkingStrategyType.AGENTIC_CHUNKER,
|
|
31
|
+
ChunkingStrategyType.DOCUMENT_CHUNKER,
|
|
32
|
+
ChunkingStrategyType.RECURSIVE_CHUNKER,
|
|
33
|
+
ChunkingStrategyType.SEMANTIC_CHUNKER,
|
|
34
34
|
]
|
|
35
35
|
|
|
36
36
|
@classmethod
|
|
@@ -26,16 +26,16 @@ class YouTubeReader(Reader):
|
|
|
26
26
|
def get_supported_chunking_strategies(self) -> List[ChunkingStrategyType]:
|
|
27
27
|
"""Get the list of supported chunking strategies for YouTube readers."""
|
|
28
28
|
return [
|
|
29
|
-
ChunkingStrategyType.
|
|
30
|
-
ChunkingStrategyType.
|
|
31
|
-
ChunkingStrategyType.
|
|
32
|
-
ChunkingStrategyType.
|
|
33
|
-
ChunkingStrategyType.
|
|
29
|
+
ChunkingStrategyType.RECURSIVE_CHUNKER,
|
|
30
|
+
ChunkingStrategyType.AGENTIC_CHUNKER,
|
|
31
|
+
ChunkingStrategyType.DOCUMENT_CHUNKER,
|
|
32
|
+
ChunkingStrategyType.SEMANTIC_CHUNKER,
|
|
33
|
+
ChunkingStrategyType.FIXED_SIZE_CHUNKER,
|
|
34
34
|
]
|
|
35
35
|
|
|
36
36
|
@classmethod
|
|
37
37
|
def get_supported_content_types(self) -> List[ContentType]:
|
|
38
|
-
return [ContentType.
|
|
38
|
+
return [ContentType.YOUTUBE]
|
|
39
39
|
|
|
40
40
|
def read(self, url: str, name: Optional[str] = None) -> List[Document]:
|
|
41
41
|
try:
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
from agno.knowledge.reranker.cohere import CohereReranker
|
|
2
|
+
from agno.knowledge.reranker.infinity import InfinityReranker
|
|
3
|
+
from agno.knowledge.reranker.sentence_transformer import SentenceTransformerReranker
|
|
4
|
+
|
|
5
|
+
__all__ = [
|
|
6
|
+
"CohereReranker",
|
|
7
|
+
"InfinityReranker",
|
|
8
|
+
"SentenceTransformerReranker",
|
|
9
|
+
]
|
agno/knowledge/utils.py
CHANGED
|
@@ -11,23 +11,23 @@ def _get_chunker_class(strategy_type):
|
|
|
11
11
|
|
|
12
12
|
# Map strategy types to their corresponding classes
|
|
13
13
|
strategy_class_mapping = {
|
|
14
|
-
ChunkingStrategyType.
|
|
14
|
+
ChunkingStrategyType.AGENTIC_CHUNKER: lambda: _import_class(
|
|
15
15
|
"agno.knowledge.chunking.agentic", "AgenticChunking"
|
|
16
16
|
),
|
|
17
|
-
ChunkingStrategyType.
|
|
17
|
+
ChunkingStrategyType.DOCUMENT_CHUNKER: lambda: _import_class(
|
|
18
18
|
"agno.knowledge.chunking.document", "DocumentChunking"
|
|
19
19
|
),
|
|
20
|
-
ChunkingStrategyType.
|
|
20
|
+
ChunkingStrategyType.RECURSIVE_CHUNKER: lambda: _import_class(
|
|
21
21
|
"agno.knowledge.chunking.recursive", "RecursiveChunking"
|
|
22
22
|
),
|
|
23
|
-
ChunkingStrategyType.
|
|
23
|
+
ChunkingStrategyType.SEMANTIC_CHUNKER: lambda: _import_class(
|
|
24
24
|
"agno.knowledge.chunking.semantic", "SemanticChunking"
|
|
25
25
|
),
|
|
26
|
-
ChunkingStrategyType.
|
|
26
|
+
ChunkingStrategyType.FIXED_SIZE_CHUNKER: lambda: _import_class(
|
|
27
27
|
"agno.knowledge.chunking.fixed", "FixedSizeChunking"
|
|
28
28
|
),
|
|
29
|
-
ChunkingStrategyType.
|
|
30
|
-
ChunkingStrategyType.
|
|
29
|
+
ChunkingStrategyType.ROW_CHUNKER: lambda: _import_class("agno.knowledge.chunking.row", "RowChunking"),
|
|
30
|
+
ChunkingStrategyType.MARKDOWN_CHUNKER: lambda: _import_class(
|
|
31
31
|
"agno.knowledge.chunking.markdown", "MarkdownChunking"
|
|
32
32
|
),
|
|
33
33
|
}
|
|
@@ -61,8 +61,8 @@ def get_reader_info(reader_key: str) -> Dict:
|
|
|
61
61
|
|
|
62
62
|
return {
|
|
63
63
|
"id": reader_key,
|
|
64
|
-
"name": reader_key.
|
|
65
|
-
"description":
|
|
64
|
+
"name": "".join(word.capitalize() for word in reader_key.split("_")) + "Reader",
|
|
65
|
+
"description": reader_instance.description,
|
|
66
66
|
"chunking_strategies": [
|
|
67
67
|
strategy.value for strategy in supported_strategies
|
|
68
68
|
], # Convert enums to string values
|
|
@@ -132,7 +132,7 @@ def get_chunker_info(chunker_key: str) -> Dict:
|
|
|
132
132
|
return {
|
|
133
133
|
"key": chunker_key,
|
|
134
134
|
"class_name": class_name,
|
|
135
|
-
"name":
|
|
135
|
+
"name": chunker_key,
|
|
136
136
|
"description": docstring.strip(),
|
|
137
137
|
"strategy_type": strategy_type.value,
|
|
138
138
|
}
|