agno 2.0.0rc2__py3-none-any.whl → 2.3.0__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 +6009 -2874
- agno/api/api.py +2 -0
- agno/api/os.py +1 -1
- agno/culture/__init__.py +3 -0
- agno/culture/manager.py +956 -0
- agno/db/async_postgres/__init__.py +3 -0
- agno/db/base.py +385 -6
- agno/db/dynamo/dynamo.py +388 -81
- agno/db/dynamo/schemas.py +47 -10
- agno/db/dynamo/utils.py +63 -4
- agno/db/firestore/firestore.py +435 -64
- agno/db/firestore/schemas.py +11 -0
- agno/db/firestore/utils.py +102 -4
- agno/db/gcs_json/gcs_json_db.py +384 -42
- agno/db/gcs_json/utils.py +60 -26
- agno/db/in_memory/in_memory_db.py +351 -66
- agno/db/in_memory/utils.py +60 -2
- agno/db/json/json_db.py +339 -48
- agno/db/json/utils.py +60 -26
- agno/db/migrations/manager.py +199 -0
- agno/db/migrations/v1_to_v2.py +510 -37
- agno/db/migrations/versions/__init__.py +0 -0
- agno/db/migrations/versions/v2_3_0.py +938 -0
- agno/db/mongo/__init__.py +15 -1
- agno/db/mongo/async_mongo.py +2036 -0
- agno/db/mongo/mongo.py +653 -76
- agno/db/mongo/schemas.py +13 -0
- agno/db/mongo/utils.py +80 -8
- agno/db/mysql/mysql.py +687 -25
- agno/db/mysql/schemas.py +61 -37
- agno/db/mysql/utils.py +60 -2
- agno/db/postgres/__init__.py +2 -1
- agno/db/postgres/async_postgres.py +2001 -0
- agno/db/postgres/postgres.py +676 -57
- agno/db/postgres/schemas.py +43 -18
- agno/db/postgres/utils.py +164 -2
- agno/db/redis/redis.py +344 -38
- agno/db/redis/schemas.py +18 -0
- agno/db/redis/utils.py +60 -2
- agno/db/schemas/__init__.py +2 -1
- agno/db/schemas/culture.py +120 -0
- agno/db/schemas/memory.py +13 -0
- agno/db/singlestore/schemas.py +26 -1
- agno/db/singlestore/singlestore.py +687 -53
- agno/db/singlestore/utils.py +60 -2
- agno/db/sqlite/__init__.py +2 -1
- agno/db/sqlite/async_sqlite.py +2371 -0
- agno/db/sqlite/schemas.py +24 -0
- agno/db/sqlite/sqlite.py +774 -85
- agno/db/sqlite/utils.py +168 -5
- agno/db/surrealdb/__init__.py +3 -0
- agno/db/surrealdb/metrics.py +292 -0
- agno/db/surrealdb/models.py +309 -0
- agno/db/surrealdb/queries.py +71 -0
- agno/db/surrealdb/surrealdb.py +1361 -0
- agno/db/surrealdb/utils.py +147 -0
- agno/db/utils.py +50 -22
- agno/eval/accuracy.py +50 -43
- agno/eval/performance.py +6 -3
- agno/eval/reliability.py +6 -3
- agno/eval/utils.py +33 -16
- agno/exceptions.py +68 -1
- agno/filters.py +354 -0
- agno/guardrails/__init__.py +6 -0
- agno/guardrails/base.py +19 -0
- agno/guardrails/openai.py +144 -0
- agno/guardrails/pii.py +94 -0
- agno/guardrails/prompt_injection.py +52 -0
- agno/integrations/discord/client.py +1 -0
- agno/knowledge/chunking/agentic.py +13 -10
- agno/knowledge/chunking/fixed.py +1 -1
- agno/knowledge/chunking/semantic.py +40 -8
- agno/knowledge/chunking/strategy.py +59 -15
- agno/knowledge/embedder/aws_bedrock.py +9 -4
- agno/knowledge/embedder/azure_openai.py +54 -0
- agno/knowledge/embedder/base.py +2 -0
- agno/knowledge/embedder/cohere.py +184 -5
- agno/knowledge/embedder/fastembed.py +1 -1
- agno/knowledge/embedder/google.py +79 -1
- agno/knowledge/embedder/huggingface.py +9 -4
- agno/knowledge/embedder/jina.py +63 -0
- agno/knowledge/embedder/mistral.py +78 -11
- agno/knowledge/embedder/nebius.py +1 -1
- agno/knowledge/embedder/ollama.py +13 -0
- agno/knowledge/embedder/openai.py +37 -65
- agno/knowledge/embedder/sentence_transformer.py +8 -4
- agno/knowledge/embedder/vllm.py +262 -0
- agno/knowledge/embedder/voyageai.py +69 -16
- agno/knowledge/knowledge.py +595 -187
- agno/knowledge/reader/base.py +9 -2
- agno/knowledge/reader/csv_reader.py +8 -10
- agno/knowledge/reader/docx_reader.py +5 -6
- agno/knowledge/reader/field_labeled_csv_reader.py +290 -0
- agno/knowledge/reader/json_reader.py +6 -5
- agno/knowledge/reader/markdown_reader.py +13 -13
- agno/knowledge/reader/pdf_reader.py +43 -68
- agno/knowledge/reader/pptx_reader.py +101 -0
- agno/knowledge/reader/reader_factory.py +51 -6
- agno/knowledge/reader/s3_reader.py +3 -15
- agno/knowledge/reader/tavily_reader.py +194 -0
- agno/knowledge/reader/text_reader.py +13 -13
- agno/knowledge/reader/web_search_reader.py +2 -43
- agno/knowledge/reader/website_reader.py +43 -25
- agno/knowledge/reranker/__init__.py +3 -0
- agno/knowledge/types.py +9 -0
- agno/knowledge/utils.py +20 -0
- agno/media.py +339 -266
- agno/memory/manager.py +336 -82
- agno/models/aimlapi/aimlapi.py +2 -2
- agno/models/anthropic/claude.py +183 -37
- agno/models/aws/bedrock.py +52 -112
- agno/models/aws/claude.py +33 -1
- agno/models/azure/ai_foundry.py +33 -15
- agno/models/azure/openai_chat.py +25 -8
- agno/models/base.py +1011 -566
- agno/models/cerebras/cerebras.py +19 -13
- agno/models/cerebras/cerebras_openai.py +8 -5
- agno/models/cohere/chat.py +27 -1
- agno/models/cometapi/__init__.py +5 -0
- agno/models/cometapi/cometapi.py +57 -0
- agno/models/dashscope/dashscope.py +1 -0
- agno/models/deepinfra/deepinfra.py +2 -2
- agno/models/deepseek/deepseek.py +2 -2
- agno/models/fireworks/fireworks.py +2 -2
- agno/models/google/gemini.py +110 -37
- agno/models/groq/groq.py +28 -11
- agno/models/huggingface/huggingface.py +2 -1
- agno/models/internlm/internlm.py +2 -2
- agno/models/langdb/langdb.py +4 -4
- agno/models/litellm/chat.py +18 -1
- agno/models/litellm/litellm_openai.py +2 -2
- agno/models/llama_cpp/__init__.py +5 -0
- agno/models/llama_cpp/llama_cpp.py +22 -0
- agno/models/message.py +143 -4
- agno/models/meta/llama.py +27 -10
- agno/models/meta/llama_openai.py +5 -17
- agno/models/nebius/nebius.py +6 -6
- agno/models/nexus/__init__.py +3 -0
- agno/models/nexus/nexus.py +22 -0
- agno/models/nvidia/nvidia.py +2 -2
- agno/models/ollama/chat.py +60 -6
- agno/models/openai/chat.py +102 -43
- agno/models/openai/responses.py +103 -106
- agno/models/openrouter/openrouter.py +41 -3
- agno/models/perplexity/perplexity.py +4 -5
- agno/models/portkey/portkey.py +3 -3
- agno/models/requesty/__init__.py +5 -0
- agno/models/requesty/requesty.py +52 -0
- agno/models/response.py +81 -5
- agno/models/sambanova/sambanova.py +2 -2
- agno/models/siliconflow/__init__.py +5 -0
- agno/models/siliconflow/siliconflow.py +25 -0
- agno/models/together/together.py +2 -2
- agno/models/utils.py +254 -8
- agno/models/vercel/v0.py +2 -2
- agno/models/vertexai/__init__.py +0 -0
- agno/models/vertexai/claude.py +96 -0
- agno/models/vllm/vllm.py +1 -0
- agno/models/xai/xai.py +3 -2
- agno/os/app.py +543 -175
- agno/os/auth.py +24 -14
- agno/os/config.py +1 -0
- agno/os/interfaces/__init__.py +1 -0
- agno/os/interfaces/a2a/__init__.py +3 -0
- agno/os/interfaces/a2a/a2a.py +42 -0
- agno/os/interfaces/a2a/router.py +250 -0
- agno/os/interfaces/a2a/utils.py +924 -0
- agno/os/interfaces/agui/agui.py +23 -7
- agno/os/interfaces/agui/router.py +27 -3
- agno/os/interfaces/agui/utils.py +242 -142
- agno/os/interfaces/base.py +6 -2
- agno/os/interfaces/slack/router.py +81 -23
- agno/os/interfaces/slack/slack.py +29 -14
- agno/os/interfaces/whatsapp/router.py +11 -4
- agno/os/interfaces/whatsapp/whatsapp.py +14 -7
- agno/os/mcp.py +111 -54
- agno/os/middleware/__init__.py +7 -0
- agno/os/middleware/jwt.py +233 -0
- agno/os/router.py +556 -139
- agno/os/routers/evals/evals.py +71 -34
- agno/os/routers/evals/schemas.py +31 -31
- agno/os/routers/evals/utils.py +6 -5
- agno/os/routers/health.py +31 -0
- agno/os/routers/home.py +52 -0
- agno/os/routers/knowledge/knowledge.py +185 -38
- agno/os/routers/knowledge/schemas.py +82 -22
- agno/os/routers/memory/memory.py +158 -53
- agno/os/routers/memory/schemas.py +20 -16
- agno/os/routers/metrics/metrics.py +20 -8
- agno/os/routers/metrics/schemas.py +16 -16
- agno/os/routers/session/session.py +499 -38
- agno/os/schema.py +308 -198
- agno/os/utils.py +401 -41
- agno/reasoning/anthropic.py +80 -0
- agno/reasoning/azure_ai_foundry.py +2 -2
- agno/reasoning/deepseek.py +2 -2
- agno/reasoning/default.py +3 -1
- agno/reasoning/gemini.py +73 -0
- agno/reasoning/groq.py +2 -2
- agno/reasoning/ollama.py +2 -2
- agno/reasoning/openai.py +7 -2
- agno/reasoning/vertexai.py +76 -0
- agno/run/__init__.py +6 -0
- agno/run/agent.py +266 -112
- agno/run/base.py +53 -24
- agno/run/team.py +252 -111
- agno/run/workflow.py +156 -45
- agno/session/agent.py +105 -89
- agno/session/summary.py +65 -25
- agno/session/team.py +176 -96
- agno/session/workflow.py +406 -40
- agno/team/team.py +3854 -1692
- agno/tools/brightdata.py +3 -3
- agno/tools/cartesia.py +3 -5
- agno/tools/dalle.py +9 -8
- agno/tools/decorator.py +4 -2
- agno/tools/desi_vocal.py +2 -2
- agno/tools/duckduckgo.py +15 -11
- agno/tools/e2b.py +20 -13
- agno/tools/eleven_labs.py +26 -28
- agno/tools/exa.py +21 -16
- agno/tools/fal.py +4 -4
- agno/tools/file.py +153 -23
- agno/tools/file_generation.py +350 -0
- agno/tools/firecrawl.py +4 -4
- agno/tools/function.py +257 -37
- agno/tools/giphy.py +2 -2
- agno/tools/gmail.py +238 -14
- agno/tools/google_drive.py +270 -0
- agno/tools/googlecalendar.py +36 -8
- agno/tools/googlesheets.py +20 -5
- agno/tools/jira.py +20 -0
- agno/tools/knowledge.py +3 -3
- agno/tools/lumalab.py +3 -3
- agno/tools/mcp/__init__.py +10 -0
- agno/tools/mcp/mcp.py +331 -0
- agno/tools/mcp/multi_mcp.py +347 -0
- agno/tools/mcp/params.py +24 -0
- agno/tools/mcp_toolbox.py +284 -0
- agno/tools/mem0.py +11 -17
- agno/tools/memori.py +1 -53
- agno/tools/memory.py +419 -0
- 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 +7 -7
- agno/tools/models_labs.py +25 -15
- agno/tools/notion.py +204 -0
- agno/tools/openai.py +4 -9
- agno/tools/opencv.py +3 -3
- agno/tools/parallel.py +314 -0
- agno/tools/replicate.py +7 -7
- agno/tools/scrapegraph.py +58 -31
- agno/tools/searxng.py +2 -2
- agno/tools/serper.py +2 -2
- agno/tools/slack.py +18 -3
- agno/tools/spider.py +2 -2
- agno/tools/tavily.py +146 -0
- agno/tools/whatsapp.py +1 -1
- agno/tools/workflow.py +278 -0
- agno/tools/yfinance.py +12 -11
- agno/utils/agent.py +820 -0
- agno/utils/audio.py +27 -0
- agno/utils/common.py +90 -1
- agno/utils/events.py +222 -7
- agno/utils/gemini.py +181 -23
- agno/utils/hooks.py +57 -0
- agno/utils/http.py +111 -0
- agno/utils/knowledge.py +12 -5
- agno/utils/log.py +1 -0
- agno/utils/mcp.py +95 -5
- agno/utils/media.py +188 -10
- agno/utils/merge_dict.py +22 -1
- agno/utils/message.py +60 -0
- agno/utils/models/claude.py +40 -11
- agno/utils/models/cohere.py +1 -1
- agno/utils/models/watsonx.py +1 -1
- agno/utils/openai.py +1 -1
- agno/utils/print_response/agent.py +105 -21
- agno/utils/print_response/team.py +103 -38
- agno/utils/print_response/workflow.py +251 -34
- agno/utils/reasoning.py +22 -1
- agno/utils/serialize.py +32 -0
- agno/utils/streamlit.py +16 -10
- agno/utils/string.py +41 -0
- agno/utils/team.py +98 -9
- agno/utils/tools.py +1 -1
- agno/vectordb/base.py +23 -4
- agno/vectordb/cassandra/cassandra.py +65 -9
- agno/vectordb/chroma/chromadb.py +182 -38
- agno/vectordb/clickhouse/clickhousedb.py +64 -11
- agno/vectordb/couchbase/couchbase.py +105 -10
- agno/vectordb/lancedb/lance_db.py +183 -135
- agno/vectordb/langchaindb/langchaindb.py +25 -7
- agno/vectordb/lightrag/lightrag.py +17 -3
- agno/vectordb/llamaindex/__init__.py +3 -0
- agno/vectordb/llamaindex/llamaindexdb.py +46 -7
- agno/vectordb/milvus/milvus.py +126 -9
- agno/vectordb/mongodb/__init__.py +7 -1
- agno/vectordb/mongodb/mongodb.py +112 -7
- agno/vectordb/pgvector/pgvector.py +142 -21
- agno/vectordb/pineconedb/pineconedb.py +80 -8
- agno/vectordb/qdrant/qdrant.py +125 -39
- agno/vectordb/redis/__init__.py +9 -0
- agno/vectordb/redis/redisdb.py +694 -0
- agno/vectordb/singlestore/singlestore.py +111 -25
- agno/vectordb/surrealdb/surrealdb.py +31 -5
- agno/vectordb/upstashdb/upstashdb.py +76 -8
- agno/vectordb/weaviate/weaviate.py +86 -15
- agno/workflow/__init__.py +2 -0
- agno/workflow/agent.py +299 -0
- agno/workflow/condition.py +112 -18
- agno/workflow/loop.py +69 -10
- agno/workflow/parallel.py +266 -118
- agno/workflow/router.py +110 -17
- agno/workflow/step.py +645 -136
- agno/workflow/steps.py +65 -6
- agno/workflow/types.py +71 -33
- agno/workflow/workflow.py +2113 -300
- agno-2.3.0.dist-info/METADATA +618 -0
- agno-2.3.0.dist-info/RECORD +577 -0
- agno-2.3.0.dist-info/licenses/LICENSE +201 -0
- agno/knowledge/reader/url_reader.py +0 -128
- agno/tools/googlesearch.py +0 -98
- agno/tools/mcp.py +0 -610
- agno/utils/models/aws_claude.py +0 -170
- agno-2.0.0rc2.dist-info/METADATA +0 -355
- agno-2.0.0rc2.dist-info/RECORD +0 -515
- agno-2.0.0rc2.dist-info/licenses/LICENSE +0 -375
- {agno-2.0.0rc2.dist-info → agno-2.3.0.dist-info}/WHEEL +0 -0
- {agno-2.0.0rc2.dist-info → agno-2.3.0.dist-info}/top_level.txt +0 -0
agno/utils/audio.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import base64
|
|
2
2
|
import os
|
|
3
|
+
import wave
|
|
3
4
|
|
|
4
5
|
from agno.utils.log import log_info
|
|
5
6
|
|
|
@@ -20,3 +21,29 @@ def write_audio_to_file(audio, filename: str):
|
|
|
20
21
|
with open(filename, "wb") as f:
|
|
21
22
|
f.write(wav_bytes)
|
|
22
23
|
log_info(f"Audio file saved to {filename}")
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def write_wav_audio_to_file(
|
|
27
|
+
filename: str, pcm_data: bytes, channels: int = 1, rate: int = 24000, sample_width: int = 2
|
|
28
|
+
):
|
|
29
|
+
"""
|
|
30
|
+
Create a WAV file from raw PCM audio data.
|
|
31
|
+
|
|
32
|
+
Args:
|
|
33
|
+
filename: The filepath to save the WAV file to
|
|
34
|
+
pcm_data: Raw PCM audio data as bytes
|
|
35
|
+
channels: Number of audio channels (1 for mono, 2 for stereo)
|
|
36
|
+
rate: Sample rate in Hz (e.g., 24000, 44100, 48000)
|
|
37
|
+
sample_width: Sample width in bytes (1, 2, or 4)
|
|
38
|
+
"""
|
|
39
|
+
# Create directory if it doesn't exist
|
|
40
|
+
if os.path.dirname(filename):
|
|
41
|
+
os.makedirs(os.path.dirname(filename), exist_ok=True)
|
|
42
|
+
|
|
43
|
+
with wave.open(filename, "wb") as wf:
|
|
44
|
+
wf.setnchannels(channels)
|
|
45
|
+
wf.setsampwidth(sample_width)
|
|
46
|
+
wf.setframerate(rate)
|
|
47
|
+
wf.writeframes(pcm_data)
|
|
48
|
+
|
|
49
|
+
log_info(f"WAV file saved to {filename}")
|
agno/utils/common.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from dataclasses import asdict
|
|
2
|
-
from typing import Any, List, Optional, Type
|
|
2
|
+
from typing import Any, List, Optional, Set, Type, Union, get_type_hints
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
def isinstanceany(obj: Any, class_list: List[Type]) -> bool:
|
|
@@ -41,3 +41,92 @@ def nested_model_dump(value):
|
|
|
41
41
|
elif isinstance(value, list):
|
|
42
42
|
return [nested_model_dump(item) for item in value]
|
|
43
43
|
return value
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def is_typed_dict(cls: Type[Any]) -> bool:
|
|
47
|
+
"""Check if a class is a TypedDict"""
|
|
48
|
+
return (
|
|
49
|
+
hasattr(cls, "__annotations__")
|
|
50
|
+
and hasattr(cls, "__total__")
|
|
51
|
+
and hasattr(cls, "__required_keys__")
|
|
52
|
+
and hasattr(cls, "__optional_keys__")
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def check_type_compatibility(value: Any, expected_type: Type) -> bool:
|
|
57
|
+
"""Basic type compatibility checking."""
|
|
58
|
+
from typing import get_args, get_origin
|
|
59
|
+
|
|
60
|
+
# Handle None/Optional types
|
|
61
|
+
if value is None:
|
|
62
|
+
return (
|
|
63
|
+
type(None) in get_args(expected_type) if hasattr(expected_type, "__args__") else expected_type is type(None)
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
# Handle Union types (including Optional)
|
|
67
|
+
origin = get_origin(expected_type)
|
|
68
|
+
if origin is Union:
|
|
69
|
+
return any(check_type_compatibility(value, arg) for arg in get_args(expected_type))
|
|
70
|
+
|
|
71
|
+
# Handle List types
|
|
72
|
+
if origin is list or expected_type is list:
|
|
73
|
+
if not isinstance(value, list):
|
|
74
|
+
return False
|
|
75
|
+
if origin is list and get_args(expected_type):
|
|
76
|
+
element_type = get_args(expected_type)[0]
|
|
77
|
+
return all(check_type_compatibility(item, element_type) for item in value)
|
|
78
|
+
return True
|
|
79
|
+
|
|
80
|
+
if expected_type in (str, int, float, bool):
|
|
81
|
+
return isinstance(value, expected_type)
|
|
82
|
+
|
|
83
|
+
if expected_type is Any:
|
|
84
|
+
return True
|
|
85
|
+
|
|
86
|
+
try:
|
|
87
|
+
return isinstance(value, expected_type)
|
|
88
|
+
except TypeError:
|
|
89
|
+
return True
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def validate_typed_dict(data: dict, schema_cls) -> dict:
|
|
93
|
+
"""Validate input data against a TypedDict schema."""
|
|
94
|
+
if not isinstance(data, dict):
|
|
95
|
+
raise ValueError(f"Expected dict for TypedDict {schema_cls.__name__}, got {type(data)}")
|
|
96
|
+
|
|
97
|
+
# Get type hints from the TypedDict
|
|
98
|
+
try:
|
|
99
|
+
type_hints = get_type_hints(schema_cls)
|
|
100
|
+
except Exception as e:
|
|
101
|
+
raise ValueError(f"Could not get type hints for TypedDict {schema_cls.__name__}: {e}")
|
|
102
|
+
|
|
103
|
+
# Get required and optional keys
|
|
104
|
+
required_keys: Set[str] = getattr(schema_cls, "__required_keys__", set())
|
|
105
|
+
optional_keys: Set[str] = getattr(schema_cls, "__optional_keys__", set())
|
|
106
|
+
all_keys = required_keys | optional_keys
|
|
107
|
+
|
|
108
|
+
# Check for missing required fields
|
|
109
|
+
missing_required = required_keys - set(data.keys())
|
|
110
|
+
if missing_required:
|
|
111
|
+
raise ValueError(f"Missing required fields in TypedDict {schema_cls.__name__}: {missing_required}")
|
|
112
|
+
|
|
113
|
+
# Check for unexpected fields
|
|
114
|
+
unexpected_fields = set(data.keys()) - all_keys
|
|
115
|
+
if unexpected_fields:
|
|
116
|
+
raise ValueError(f"Unexpected fields in TypedDict {schema_cls.__name__}: {unexpected_fields}")
|
|
117
|
+
|
|
118
|
+
# Basic type checking for provided fields
|
|
119
|
+
validated_data = {}
|
|
120
|
+
for field_name, value in data.items():
|
|
121
|
+
if field_name in type_hints:
|
|
122
|
+
expected_type = type_hints[field_name]
|
|
123
|
+
|
|
124
|
+
# Handle simple type checking
|
|
125
|
+
if not check_type_compatibility(value, expected_type):
|
|
126
|
+
raise ValueError(
|
|
127
|
+
f"Field '{field_name}' expected type {expected_type}, got {type(value)} with value {value}"
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
validated_data[field_name] = value
|
|
131
|
+
|
|
132
|
+
return validated_data
|
agno/utils/events.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
from typing import Any, List, Optional
|
|
1
|
+
from typing import Any, Dict, List, Optional, Union
|
|
2
2
|
|
|
3
|
-
from agno.media import
|
|
3
|
+
from agno.media import Audio, Image
|
|
4
4
|
from agno.models.message import Citations
|
|
5
5
|
from agno.models.response import ToolExecution
|
|
6
6
|
from agno.reasoning.step import ReasoningStep
|
|
@@ -11,17 +11,27 @@ from agno.run.agent import (
|
|
|
11
11
|
OutputModelResponseStartedEvent,
|
|
12
12
|
ParserModelResponseCompletedEvent,
|
|
13
13
|
ParserModelResponseStartedEvent,
|
|
14
|
+
PostHookCompletedEvent,
|
|
15
|
+
PostHookStartedEvent,
|
|
16
|
+
PreHookCompletedEvent,
|
|
17
|
+
PreHookStartedEvent,
|
|
14
18
|
ReasoningCompletedEvent,
|
|
15
19
|
ReasoningStartedEvent,
|
|
16
20
|
ReasoningStepEvent,
|
|
17
21
|
RunCancelledEvent,
|
|
18
22
|
RunCompletedEvent,
|
|
23
|
+
RunContentCompletedEvent,
|
|
19
24
|
RunContentEvent,
|
|
20
25
|
RunContinuedEvent,
|
|
21
26
|
RunErrorEvent,
|
|
27
|
+
RunEvent,
|
|
28
|
+
RunInput,
|
|
22
29
|
RunOutput,
|
|
30
|
+
RunOutputEvent,
|
|
23
31
|
RunPausedEvent,
|
|
24
32
|
RunStartedEvent,
|
|
33
|
+
SessionSummaryCompletedEvent,
|
|
34
|
+
SessionSummaryStartedEvent,
|
|
25
35
|
ToolCallCompletedEvent,
|
|
26
36
|
ToolCallStartedEvent,
|
|
27
37
|
)
|
|
@@ -31,17 +41,25 @@ from agno.run.team import OutputModelResponseCompletedEvent as TeamOutputModelRe
|
|
|
31
41
|
from agno.run.team import OutputModelResponseStartedEvent as TeamOutputModelResponseStartedEvent
|
|
32
42
|
from agno.run.team import ParserModelResponseCompletedEvent as TeamParserModelResponseCompletedEvent
|
|
33
43
|
from agno.run.team import ParserModelResponseStartedEvent as TeamParserModelResponseStartedEvent
|
|
44
|
+
from agno.run.team import PostHookCompletedEvent as TeamPostHookCompletedEvent
|
|
45
|
+
from agno.run.team import PostHookStartedEvent as TeamPostHookStartedEvent
|
|
46
|
+
from agno.run.team import PreHookCompletedEvent as TeamPreHookCompletedEvent
|
|
47
|
+
from agno.run.team import PreHookStartedEvent as TeamPreHookStartedEvent
|
|
34
48
|
from agno.run.team import ReasoningCompletedEvent as TeamReasoningCompletedEvent
|
|
35
49
|
from agno.run.team import ReasoningStartedEvent as TeamReasoningStartedEvent
|
|
36
50
|
from agno.run.team import ReasoningStepEvent as TeamReasoningStepEvent
|
|
37
51
|
from agno.run.team import RunCancelledEvent as TeamRunCancelledEvent
|
|
38
52
|
from agno.run.team import RunCompletedEvent as TeamRunCompletedEvent
|
|
53
|
+
from agno.run.team import RunContentCompletedEvent as TeamRunContentCompletedEvent
|
|
39
54
|
from agno.run.team import RunContentEvent as TeamRunContentEvent
|
|
40
55
|
from agno.run.team import RunErrorEvent as TeamRunErrorEvent
|
|
41
56
|
from agno.run.team import RunStartedEvent as TeamRunStartedEvent
|
|
42
|
-
from agno.run.team import
|
|
57
|
+
from agno.run.team import SessionSummaryCompletedEvent as TeamSessionSummaryCompletedEvent
|
|
58
|
+
from agno.run.team import SessionSummaryStartedEvent as TeamSessionSummaryStartedEvent
|
|
59
|
+
from agno.run.team import TeamRunEvent, TeamRunInput, TeamRunOutput, TeamRunOutputEvent
|
|
43
60
|
from agno.run.team import ToolCallCompletedEvent as TeamToolCallCompletedEvent
|
|
44
61
|
from agno.run.team import ToolCallStartedEvent as TeamToolCallStartedEvent
|
|
62
|
+
from agno.session.summary import SessionSummary
|
|
45
63
|
|
|
46
64
|
|
|
47
65
|
def create_team_run_started_event(from_run_response: TeamRunOutput) -> TeamRunStartedEvent:
|
|
@@ -76,6 +94,7 @@ def create_team_run_completed_event(from_run_response: TeamRunOutput) -> TeamRun
|
|
|
76
94
|
content_type=from_run_response.content_type, # type: ignore
|
|
77
95
|
reasoning_content=from_run_response.reasoning_content, # type: ignore
|
|
78
96
|
citations=from_run_response.citations, # type: ignore
|
|
97
|
+
model_provider_data=from_run_response.model_provider_data, # type: ignore
|
|
79
98
|
images=from_run_response.images, # type: ignore
|
|
80
99
|
videos=from_run_response.videos, # type: ignore
|
|
81
100
|
audio=from_run_response.audio, # type: ignore
|
|
@@ -87,6 +106,7 @@ def create_team_run_completed_event(from_run_response: TeamRunOutput) -> TeamRun
|
|
|
87
106
|
member_responses=from_run_response.member_responses, # type: ignore
|
|
88
107
|
metadata=from_run_response.metadata, # type: ignore
|
|
89
108
|
metrics=from_run_response.metrics, # type: ignore
|
|
109
|
+
session_state=from_run_response.session_state, # type: ignore
|
|
90
110
|
)
|
|
91
111
|
|
|
92
112
|
|
|
@@ -100,6 +120,7 @@ def create_run_completed_event(from_run_response: RunOutput) -> RunCompletedEven
|
|
|
100
120
|
content_type=from_run_response.content_type, # type: ignore
|
|
101
121
|
reasoning_content=from_run_response.reasoning_content, # type: ignore
|
|
102
122
|
citations=from_run_response.citations, # type: ignore
|
|
123
|
+
model_provider_data=from_run_response.model_provider_data, # type: ignore
|
|
103
124
|
images=from_run_response.images, # type: ignore
|
|
104
125
|
videos=from_run_response.videos, # type: ignore
|
|
105
126
|
audio=from_run_response.audio, # type: ignore
|
|
@@ -110,6 +131,7 @@ def create_run_completed_event(from_run_response: RunOutput) -> RunCompletedEven
|
|
|
110
131
|
reasoning_messages=from_run_response.reasoning_messages, # type: ignore
|
|
111
132
|
metadata=from_run_response.metadata, # type: ignore
|
|
112
133
|
metrics=from_run_response.metrics, # type: ignore
|
|
134
|
+
session_state=from_run_response.session_state, # type: ignore
|
|
113
135
|
)
|
|
114
136
|
|
|
115
137
|
|
|
@@ -175,6 +197,114 @@ def create_run_cancelled_event(from_run_response: RunOutput, reason: str) -> Run
|
|
|
175
197
|
)
|
|
176
198
|
|
|
177
199
|
|
|
200
|
+
def create_pre_hook_started_event(
|
|
201
|
+
from_run_response: RunOutput, pre_hook_name: Optional[str] = None, run_input: Optional[RunInput] = None
|
|
202
|
+
) -> PreHookStartedEvent:
|
|
203
|
+
from copy import deepcopy
|
|
204
|
+
|
|
205
|
+
return PreHookStartedEvent(
|
|
206
|
+
session_id=from_run_response.session_id,
|
|
207
|
+
agent_id=from_run_response.agent_id, # type: ignore
|
|
208
|
+
agent_name=from_run_response.agent_name, # type: ignore
|
|
209
|
+
run_id=from_run_response.run_id,
|
|
210
|
+
pre_hook_name=pre_hook_name,
|
|
211
|
+
run_input=deepcopy(run_input),
|
|
212
|
+
)
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
def create_team_pre_hook_started_event(
|
|
216
|
+
from_run_response: TeamRunOutput, pre_hook_name: Optional[str] = None, run_input: Optional[TeamRunInput] = None
|
|
217
|
+
) -> TeamPreHookStartedEvent:
|
|
218
|
+
from copy import deepcopy
|
|
219
|
+
|
|
220
|
+
return TeamPreHookStartedEvent(
|
|
221
|
+
session_id=from_run_response.session_id,
|
|
222
|
+
team_id=from_run_response.team_id, # type: ignore
|
|
223
|
+
team_name=from_run_response.team_name, # type: ignore
|
|
224
|
+
run_id=from_run_response.run_id,
|
|
225
|
+
pre_hook_name=pre_hook_name,
|
|
226
|
+
run_input=deepcopy(run_input),
|
|
227
|
+
)
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
def create_pre_hook_completed_event(
|
|
231
|
+
from_run_response: RunOutput, pre_hook_name: Optional[str] = None, run_input: Optional[RunInput] = None
|
|
232
|
+
) -> PreHookCompletedEvent:
|
|
233
|
+
from copy import deepcopy
|
|
234
|
+
|
|
235
|
+
return PreHookCompletedEvent(
|
|
236
|
+
session_id=from_run_response.session_id,
|
|
237
|
+
agent_id=from_run_response.agent_id, # type: ignore
|
|
238
|
+
agent_name=from_run_response.agent_name, # type: ignore
|
|
239
|
+
run_id=from_run_response.run_id,
|
|
240
|
+
pre_hook_name=pre_hook_name,
|
|
241
|
+
run_input=deepcopy(run_input),
|
|
242
|
+
)
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
def create_team_pre_hook_completed_event(
|
|
246
|
+
from_run_response: TeamRunOutput, pre_hook_name: Optional[str] = None, run_input: Optional[TeamRunInput] = None
|
|
247
|
+
) -> TeamPreHookCompletedEvent:
|
|
248
|
+
from copy import deepcopy
|
|
249
|
+
|
|
250
|
+
return TeamPreHookCompletedEvent(
|
|
251
|
+
session_id=from_run_response.session_id,
|
|
252
|
+
team_id=from_run_response.team_id, # type: ignore
|
|
253
|
+
team_name=from_run_response.team_name, # type: ignore
|
|
254
|
+
run_id=from_run_response.run_id,
|
|
255
|
+
pre_hook_name=pre_hook_name,
|
|
256
|
+
run_input=deepcopy(run_input),
|
|
257
|
+
)
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
def create_post_hook_started_event(
|
|
261
|
+
from_run_response: RunOutput, post_hook_name: Optional[str] = None
|
|
262
|
+
) -> PostHookStartedEvent:
|
|
263
|
+
return PostHookStartedEvent(
|
|
264
|
+
session_id=from_run_response.session_id,
|
|
265
|
+
agent_id=from_run_response.agent_id, # type: ignore
|
|
266
|
+
agent_name=from_run_response.agent_name, # type: ignore
|
|
267
|
+
run_id=from_run_response.run_id,
|
|
268
|
+
post_hook_name=post_hook_name,
|
|
269
|
+
)
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
def create_team_post_hook_started_event(
|
|
273
|
+
from_run_response: TeamRunOutput, post_hook_name: Optional[str] = None
|
|
274
|
+
) -> TeamPostHookStartedEvent:
|
|
275
|
+
return TeamPostHookStartedEvent(
|
|
276
|
+
session_id=from_run_response.session_id,
|
|
277
|
+
team_id=from_run_response.team_id, # type: ignore
|
|
278
|
+
team_name=from_run_response.team_name, # type: ignore
|
|
279
|
+
run_id=from_run_response.run_id,
|
|
280
|
+
post_hook_name=post_hook_name,
|
|
281
|
+
)
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
def create_post_hook_completed_event(
|
|
285
|
+
from_run_response: RunOutput, post_hook_name: Optional[str] = None
|
|
286
|
+
) -> PostHookCompletedEvent:
|
|
287
|
+
return PostHookCompletedEvent(
|
|
288
|
+
session_id=from_run_response.session_id,
|
|
289
|
+
agent_id=from_run_response.agent_id, # type: ignore
|
|
290
|
+
agent_name=from_run_response.agent_name, # type: ignore
|
|
291
|
+
run_id=from_run_response.run_id,
|
|
292
|
+
post_hook_name=post_hook_name,
|
|
293
|
+
)
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
def create_team_post_hook_completed_event(
|
|
297
|
+
from_run_response: TeamRunOutput, post_hook_name: Optional[str] = None
|
|
298
|
+
) -> TeamPostHookCompletedEvent:
|
|
299
|
+
return TeamPostHookCompletedEvent(
|
|
300
|
+
session_id=from_run_response.session_id,
|
|
301
|
+
team_id=from_run_response.team_id, # type: ignore
|
|
302
|
+
team_name=from_run_response.team_name, # type: ignore
|
|
303
|
+
run_id=from_run_response.run_id,
|
|
304
|
+
post_hook_name=post_hook_name,
|
|
305
|
+
)
|
|
306
|
+
|
|
307
|
+
|
|
178
308
|
def create_memory_update_started_event(from_run_response: RunOutput) -> MemoryUpdateStartedEvent:
|
|
179
309
|
return MemoryUpdateStartedEvent(
|
|
180
310
|
session_id=from_run_response.session_id,
|
|
@@ -211,6 +341,50 @@ def create_team_memory_update_completed_event(from_run_response: TeamRunOutput)
|
|
|
211
341
|
)
|
|
212
342
|
|
|
213
343
|
|
|
344
|
+
def create_team_session_summary_started_event(
|
|
345
|
+
from_run_response: TeamRunOutput,
|
|
346
|
+
) -> TeamSessionSummaryStartedEvent:
|
|
347
|
+
return TeamSessionSummaryStartedEvent(
|
|
348
|
+
session_id=from_run_response.session_id,
|
|
349
|
+
team_id=from_run_response.team_id, # type: ignore
|
|
350
|
+
team_name=from_run_response.team_name, # type: ignore
|
|
351
|
+
run_id=from_run_response.run_id,
|
|
352
|
+
)
|
|
353
|
+
|
|
354
|
+
|
|
355
|
+
def create_team_session_summary_completed_event(
|
|
356
|
+
from_run_response: TeamRunOutput, session_summary: Optional[SessionSummary] = None
|
|
357
|
+
) -> TeamSessionSummaryCompletedEvent:
|
|
358
|
+
return TeamSessionSummaryCompletedEvent(
|
|
359
|
+
session_id=from_run_response.session_id,
|
|
360
|
+
team_id=from_run_response.team_id, # type: ignore
|
|
361
|
+
team_name=from_run_response.team_name, # type: ignore
|
|
362
|
+
run_id=from_run_response.run_id,
|
|
363
|
+
session_summary=session_summary,
|
|
364
|
+
)
|
|
365
|
+
|
|
366
|
+
|
|
367
|
+
def create_session_summary_started_event(from_run_response: RunOutput) -> SessionSummaryStartedEvent:
|
|
368
|
+
return SessionSummaryStartedEvent(
|
|
369
|
+
session_id=from_run_response.session_id,
|
|
370
|
+
agent_id=from_run_response.agent_id, # type: ignore
|
|
371
|
+
agent_name=from_run_response.agent_name, # type: ignore
|
|
372
|
+
run_id=from_run_response.run_id,
|
|
373
|
+
)
|
|
374
|
+
|
|
375
|
+
|
|
376
|
+
def create_session_summary_completed_event(
|
|
377
|
+
from_run_response: RunOutput, session_summary: Optional[SessionSummary] = None
|
|
378
|
+
) -> SessionSummaryCompletedEvent:
|
|
379
|
+
return SessionSummaryCompletedEvent(
|
|
380
|
+
session_id=from_run_response.session_id,
|
|
381
|
+
agent_id=from_run_response.agent_id, # type: ignore
|
|
382
|
+
agent_name=from_run_response.agent_name, # type: ignore
|
|
383
|
+
run_id=from_run_response.run_id,
|
|
384
|
+
session_summary=session_summary,
|
|
385
|
+
)
|
|
386
|
+
|
|
387
|
+
|
|
214
388
|
def create_reasoning_started_event(from_run_response: RunOutput) -> ReasoningStartedEvent:
|
|
215
389
|
return ReasoningStartedEvent(
|
|
216
390
|
session_id=from_run_response.session_id,
|
|
@@ -343,9 +517,10 @@ def create_run_output_content_event(
|
|
|
343
517
|
content_type: Optional[str] = None,
|
|
344
518
|
reasoning_content: Optional[str] = None,
|
|
345
519
|
redacted_reasoning_content: Optional[str] = None,
|
|
520
|
+
model_provider_data: Optional[Dict[str, Any]] = None,
|
|
346
521
|
citations: Optional[Citations] = None,
|
|
347
|
-
response_audio: Optional[
|
|
348
|
-
image: Optional[
|
|
522
|
+
response_audio: Optional[Audio] = None,
|
|
523
|
+
image: Optional[Image] = None,
|
|
349
524
|
) -> RunContentEvent:
|
|
350
525
|
thinking_combined = (reasoning_content or "") + (redacted_reasoning_content or "")
|
|
351
526
|
|
|
@@ -364,6 +539,7 @@ def create_run_output_content_event(
|
|
|
364
539
|
additional_input=from_run_response.additional_input,
|
|
365
540
|
reasoning_steps=from_run_response.reasoning_steps,
|
|
366
541
|
reasoning_messages=from_run_response.reasoning_messages,
|
|
542
|
+
model_provider_data=model_provider_data,
|
|
367
543
|
)
|
|
368
544
|
|
|
369
545
|
|
|
@@ -374,8 +550,9 @@ def create_team_run_output_content_event(
|
|
|
374
550
|
reasoning_content: Optional[str] = None,
|
|
375
551
|
redacted_reasoning_content: Optional[str] = None,
|
|
376
552
|
citations: Optional[Citations] = None,
|
|
377
|
-
|
|
378
|
-
|
|
553
|
+
model_provider_data: Optional[Dict[str, Any]] = None,
|
|
554
|
+
response_audio: Optional[Audio] = None,
|
|
555
|
+
image: Optional[Image] = None,
|
|
379
556
|
) -> TeamRunContentEvent:
|
|
380
557
|
thinking_combined = (reasoning_content or "") + (redacted_reasoning_content or "")
|
|
381
558
|
|
|
@@ -388,6 +565,7 @@ def create_team_run_output_content_event(
|
|
|
388
565
|
content_type=content_type or "str",
|
|
389
566
|
reasoning_content=thinking_combined,
|
|
390
567
|
citations=citations,
|
|
568
|
+
model_provider_data=model_provider_data,
|
|
391
569
|
response_audio=response_audio,
|
|
392
570
|
image=image,
|
|
393
571
|
references=from_run_response.references, # type: ignore
|
|
@@ -397,6 +575,28 @@ def create_team_run_output_content_event(
|
|
|
397
575
|
)
|
|
398
576
|
|
|
399
577
|
|
|
578
|
+
def create_run_content_completed_event(
|
|
579
|
+
from_run_response: RunOutput,
|
|
580
|
+
) -> RunContentCompletedEvent:
|
|
581
|
+
return RunContentCompletedEvent(
|
|
582
|
+
session_id=from_run_response.session_id,
|
|
583
|
+
agent_id=from_run_response.agent_id, # type: ignore
|
|
584
|
+
agent_name=from_run_response.agent_name, # type: ignore
|
|
585
|
+
run_id=from_run_response.run_id,
|
|
586
|
+
)
|
|
587
|
+
|
|
588
|
+
|
|
589
|
+
def create_team_run_content_completed_event(
|
|
590
|
+
from_run_response: TeamRunOutput,
|
|
591
|
+
) -> TeamRunContentCompletedEvent:
|
|
592
|
+
return TeamRunContentCompletedEvent(
|
|
593
|
+
session_id=from_run_response.session_id,
|
|
594
|
+
team_id=from_run_response.team_id, # type: ignore
|
|
595
|
+
team_name=from_run_response.team_name, # type: ignore
|
|
596
|
+
run_id=from_run_response.run_id,
|
|
597
|
+
)
|
|
598
|
+
|
|
599
|
+
|
|
400
600
|
def create_parser_model_response_started_event(
|
|
401
601
|
from_run_response: RunOutput,
|
|
402
602
|
) -> ParserModelResponseStartedEvent:
|
|
@@ -479,3 +679,18 @@ def create_team_output_model_response_completed_event(
|
|
|
479
679
|
team_name=from_run_response.team_name, # type: ignore
|
|
480
680
|
run_id=from_run_response.run_id,
|
|
481
681
|
)
|
|
682
|
+
|
|
683
|
+
|
|
684
|
+
def handle_event(
|
|
685
|
+
event: Union[RunOutputEvent, TeamRunOutputEvent],
|
|
686
|
+
run_response: Union[RunOutput, TeamRunOutput],
|
|
687
|
+
events_to_skip: Optional[List[Union[RunEvent, TeamRunEvent]]] = None,
|
|
688
|
+
store_events: bool = False,
|
|
689
|
+
) -> Union[RunOutputEvent, TeamRunOutputEvent]:
|
|
690
|
+
# We only store events that are not run_response_content events
|
|
691
|
+
events_to_skip = [event.value for event in events_to_skip] if events_to_skip else []
|
|
692
|
+
if store_events and event.event not in events_to_skip:
|
|
693
|
+
if run_response.events is None:
|
|
694
|
+
run_response.events = []
|
|
695
|
+
run_response.events.append(event) # type: ignore
|
|
696
|
+
return event
|