agno 1.7.7__py3-none-any.whl → 1.7.9__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 +247 -36
- agno/document/reader/pdf_reader.py +239 -136
- agno/document/reader/youtube_reader.py +8 -4
- agno/models/anthropic/claude.py +1 -1
- agno/models/base.py +4 -0
- agno/models/message.py +6 -2
- agno/models/openai/chat.py +3 -0
- agno/models/openai/responses.py +6 -5
- agno/run/response.py +41 -0
- agno/run/team.py +27 -0
- agno/storage/gcs_json.py +1 -1
- agno/storage/json.py +2 -1
- agno/storage/redis.py +1 -1
- agno/storage/yaml.py +1 -1
- agno/team/team.py +443 -225
- agno/tools/aws_lambda.py +10 -0
- agno/tools/function.py +21 -11
- agno/tools/googlecalendar.py +567 -121
- agno/tools/googlesheets.py +6 -1
- agno/tools/mcp.py +19 -1
- agno/utils/events.py +50 -0
- agno/utils/response.py +3 -1
- agno/vectordb/lancedb/lance_db.py +10 -2
- agno/vectordb/pgvector/pgvector.py +3 -0
- {agno-1.7.7.dist-info → agno-1.7.9.dist-info}/METADATA +1 -1
- {agno-1.7.7.dist-info → agno-1.7.9.dist-info}/RECORD +30 -30
- {agno-1.7.7.dist-info → agno-1.7.9.dist-info}/WHEEL +0 -0
- {agno-1.7.7.dist-info → agno-1.7.9.dist-info}/entry_points.txt +0 -0
- {agno-1.7.7.dist-info → agno-1.7.9.dist-info}/licenses/LICENSE +0 -0
- {agno-1.7.7.dist-info → agno-1.7.9.dist-info}/top_level.txt +0 -0
agno/tools/aws_lambda.py
CHANGED
|
@@ -26,6 +26,9 @@ class AWSLambdaTools(Toolkit):
|
|
|
26
26
|
super().__init__(name="aws-lambda", tools=tools, **kwargs)
|
|
27
27
|
|
|
28
28
|
def list_functions(self) -> str:
|
|
29
|
+
"""
|
|
30
|
+
List all AWS Lambda functions in the configured AWS account.
|
|
31
|
+
"""
|
|
29
32
|
try:
|
|
30
33
|
response = self.client.list_functions()
|
|
31
34
|
functions = [func["FunctionName"] for func in response["Functions"]]
|
|
@@ -34,6 +37,13 @@ class AWSLambdaTools(Toolkit):
|
|
|
34
37
|
return f"Error listing functions: {str(e)}"
|
|
35
38
|
|
|
36
39
|
def invoke_function(self, function_name: str, payload: str = "{}") -> str:
|
|
40
|
+
"""
|
|
41
|
+
Invoke a specific AWS Lambda function with an optional JSON payload.
|
|
42
|
+
|
|
43
|
+
Args:
|
|
44
|
+
function_name (str): The name of the Lambda function to invoke.
|
|
45
|
+
payload (str): The JSON payload to send to the function. Defaults to "{}".
|
|
46
|
+
"""
|
|
37
47
|
try:
|
|
38
48
|
response = self.client.invoke(FunctionName=function_name, Payload=payload)
|
|
39
49
|
return f"Function invoked successfully. Status code: {response['StatusCode']}, Payload: {response['Payload'].read().decode('utf-8')}"
|
agno/tools/function.py
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
from dataclasses import dataclass
|
|
2
2
|
from functools import partial
|
|
3
|
+
from importlib.metadata import version
|
|
3
4
|
from typing import Any, Callable, Dict, List, Literal, Optional, Type, TypeVar, get_type_hints
|
|
4
5
|
|
|
5
6
|
from docstring_parser import parse
|
|
7
|
+
from packaging.version import Version
|
|
6
8
|
from pydantic import BaseModel, Field, validate_call
|
|
7
9
|
|
|
8
10
|
from agno.exceptions import AgentRunException
|
|
@@ -323,11 +325,21 @@ class Function(BaseModel):
|
|
|
323
325
|
@staticmethod
|
|
324
326
|
def _wrap_callable(func: Callable) -> Callable:
|
|
325
327
|
"""Wrap a callable with Pydantic's validate_call decorator, if relevant"""
|
|
326
|
-
from inspect import isasyncgenfunction
|
|
328
|
+
from inspect import isasyncgenfunction, iscoroutinefunction
|
|
327
329
|
|
|
328
|
-
|
|
330
|
+
pydantic_version = Version(version("pydantic"))
|
|
331
|
+
|
|
332
|
+
# Don't wrap async generators validate_call
|
|
329
333
|
if isasyncgenfunction(func):
|
|
330
334
|
return func
|
|
335
|
+
|
|
336
|
+
# Don't wrap coroutines with validate_call if pydantic version is less than 2.10.0
|
|
337
|
+
if iscoroutinefunction(func) and pydantic_version < Version("2.10.0"):
|
|
338
|
+
log_debug(
|
|
339
|
+
f"Skipping validate_call for {func.__name__} because pydantic version is less than 2.10.0, please consider upgrading to pydantic 2.10.0 or higher"
|
|
340
|
+
)
|
|
341
|
+
return func
|
|
342
|
+
|
|
331
343
|
# Don't wrap callables that are already wrapped with validate_call
|
|
332
344
|
elif getattr(func, "_wrapped_for_validation", False):
|
|
333
345
|
return func
|
|
@@ -599,7 +611,7 @@ class FunctionCall(BaseModel):
|
|
|
599
611
|
|
|
600
612
|
def execute(self) -> FunctionExecutionResult:
|
|
601
613
|
"""Runs the function call."""
|
|
602
|
-
from inspect import isgenerator
|
|
614
|
+
from inspect import isgenerator, isgeneratorfunction
|
|
603
615
|
|
|
604
616
|
if self.function.entrypoint is None:
|
|
605
617
|
return FunctionExecutionResult(status="failure", error="Entrypoint is not set")
|
|
@@ -612,7 +624,7 @@ class FunctionCall(BaseModel):
|
|
|
612
624
|
entrypoint_args = self._build_entrypoint_args()
|
|
613
625
|
|
|
614
626
|
# Check cache if enabled and not a generator function
|
|
615
|
-
if self.function.cache_results and not
|
|
627
|
+
if self.function.cache_results and not isgeneratorfunction(self.function.entrypoint):
|
|
616
628
|
cache_key = self.function._get_cache_key(entrypoint_args, self.arguments)
|
|
617
629
|
cache_file = self.function._get_cache_file_path(cache_key)
|
|
618
630
|
cached_result = self.function._get_cached_result(cache_file)
|
|
@@ -718,7 +730,7 @@ class FunctionCall(BaseModel):
|
|
|
718
730
|
Similar to _build_nested_execution_chain but for async execution.
|
|
719
731
|
"""
|
|
720
732
|
from functools import reduce
|
|
721
|
-
from inspect import
|
|
733
|
+
from inspect import isasyncgenfunction, iscoroutinefunction
|
|
722
734
|
|
|
723
735
|
async def execute_entrypoint_async(name, func, args):
|
|
724
736
|
"""Execute the entrypoint function asynchronously."""
|
|
@@ -727,9 +739,7 @@ class FunctionCall(BaseModel):
|
|
|
727
739
|
arguments.update(self.arguments)
|
|
728
740
|
|
|
729
741
|
result = self.function.entrypoint(**arguments) # type: ignore
|
|
730
|
-
if iscoroutinefunction(self.function.entrypoint) and not (
|
|
731
|
-
isasyncgen(self.function.entrypoint) or isasyncgenfunction(self.function.entrypoint)
|
|
732
|
-
):
|
|
742
|
+
if iscoroutinefunction(self.function.entrypoint) and not isasyncgenfunction(self.function.entrypoint):
|
|
733
743
|
result = await result
|
|
734
744
|
return result
|
|
735
745
|
|
|
@@ -779,7 +789,7 @@ class FunctionCall(BaseModel):
|
|
|
779
789
|
|
|
780
790
|
async def aexecute(self) -> FunctionExecutionResult:
|
|
781
791
|
"""Runs the function call asynchronously."""
|
|
782
|
-
from inspect import isasyncgen, isasyncgenfunction, iscoroutinefunction, isgenerator
|
|
792
|
+
from inspect import isasyncgen, isasyncgenfunction, iscoroutinefunction, isgenerator, isgeneratorfunction
|
|
783
793
|
|
|
784
794
|
if self.function.entrypoint is None:
|
|
785
795
|
return FunctionExecutionResult(status="failure", error="Entrypoint is not set")
|
|
@@ -796,7 +806,7 @@ class FunctionCall(BaseModel):
|
|
|
796
806
|
|
|
797
807
|
# Check cache if enabled and not a generator function
|
|
798
808
|
if self.function.cache_results and not (
|
|
799
|
-
|
|
809
|
+
isasyncgenfunction(self.function.entrypoint) or isgeneratorfunction(self.function.entrypoint)
|
|
800
810
|
):
|
|
801
811
|
cache_key = self.function._get_cache_key(entrypoint_args, self.arguments)
|
|
802
812
|
cache_file = self.function._get_cache_file_path(cache_key)
|
|
@@ -818,7 +828,7 @@ class FunctionCall(BaseModel):
|
|
|
818
828
|
else:
|
|
819
829
|
result = self.function.entrypoint(**entrypoint_args, **self.arguments)
|
|
820
830
|
|
|
821
|
-
if
|
|
831
|
+
if isasyncgenfunction(self.function.entrypoint):
|
|
822
832
|
self.result = result # Store async generator directly
|
|
823
833
|
else:
|
|
824
834
|
self.result = await result
|