agno 2.3.26__py3-none-any.whl → 2.4.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/__init__.py +4 -0
- agno/agent/agent.py +1368 -541
- agno/agent/remote.py +13 -0
- agno/db/base.py +339 -0
- agno/db/postgres/async_postgres.py +116 -12
- agno/db/postgres/postgres.py +1242 -25
- agno/db/postgres/schemas.py +48 -1
- agno/db/sqlite/async_sqlite.py +119 -4
- agno/db/sqlite/schemas.py +51 -0
- agno/db/sqlite/sqlite.py +1186 -13
- agno/db/utils.py +37 -1
- agno/integrations/discord/client.py +12 -1
- agno/knowledge/__init__.py +4 -0
- agno/knowledge/chunking/code.py +1 -1
- agno/knowledge/chunking/semantic.py +1 -1
- agno/knowledge/chunking/strategy.py +4 -0
- agno/knowledge/filesystem.py +412 -0
- agno/knowledge/knowledge.py +3722 -2182
- agno/knowledge/protocol.py +134 -0
- agno/knowledge/reader/arxiv_reader.py +2 -2
- agno/knowledge/reader/base.py +9 -7
- agno/knowledge/reader/csv_reader.py +236 -13
- agno/knowledge/reader/docx_reader.py +2 -2
- agno/knowledge/reader/field_labeled_csv_reader.py +169 -5
- agno/knowledge/reader/firecrawl_reader.py +2 -2
- agno/knowledge/reader/json_reader.py +2 -2
- agno/knowledge/reader/markdown_reader.py +2 -2
- agno/knowledge/reader/pdf_reader.py +5 -4
- agno/knowledge/reader/pptx_reader.py +2 -2
- agno/knowledge/reader/reader_factory.py +118 -1
- agno/knowledge/reader/s3_reader.py +2 -2
- agno/knowledge/reader/tavily_reader.py +2 -2
- agno/knowledge/reader/text_reader.py +2 -2
- agno/knowledge/reader/web_search_reader.py +2 -2
- agno/knowledge/reader/website_reader.py +5 -3
- agno/knowledge/reader/wikipedia_reader.py +2 -2
- agno/knowledge/reader/youtube_reader.py +2 -2
- agno/knowledge/remote_content/__init__.py +29 -0
- agno/knowledge/remote_content/config.py +204 -0
- agno/knowledge/remote_content/remote_content.py +74 -17
- agno/knowledge/utils.py +37 -29
- agno/learn/__init__.py +6 -0
- agno/learn/machine.py +35 -0
- agno/learn/schemas.py +82 -11
- agno/learn/stores/__init__.py +3 -0
- agno/learn/stores/decision_log.py +1156 -0
- agno/learn/stores/learned_knowledge.py +6 -6
- agno/models/anthropic/claude.py +24 -0
- agno/models/aws/bedrock.py +20 -0
- agno/models/base.py +60 -6
- agno/models/cerebras/cerebras.py +34 -2
- agno/models/cohere/chat.py +25 -0
- agno/models/google/gemini.py +50 -5
- agno/models/litellm/chat.py +38 -0
- agno/models/n1n/__init__.py +3 -0
- agno/models/n1n/n1n.py +57 -0
- agno/models/openai/chat.py +25 -1
- agno/models/openrouter/openrouter.py +46 -0
- agno/models/perplexity/perplexity.py +2 -0
- agno/models/response.py +16 -0
- agno/os/app.py +83 -44
- agno/os/interfaces/slack/router.py +10 -1
- agno/os/interfaces/whatsapp/router.py +6 -0
- agno/os/middleware/__init__.py +2 -0
- agno/os/middleware/trailing_slash.py +27 -0
- agno/os/router.py +1 -0
- agno/os/routers/agents/router.py +29 -16
- agno/os/routers/agents/schema.py +6 -4
- agno/os/routers/components/__init__.py +3 -0
- agno/os/routers/components/components.py +475 -0
- agno/os/routers/evals/schemas.py +4 -3
- agno/os/routers/health.py +3 -3
- agno/os/routers/knowledge/knowledge.py +128 -3
- agno/os/routers/knowledge/schemas.py +12 -0
- agno/os/routers/memory/schemas.py +4 -2
- agno/os/routers/metrics/metrics.py +9 -11
- 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/teams/router.py +20 -8
- agno/os/routers/teams/schema.py +6 -4
- agno/os/routers/traces/traces.py +5 -5
- agno/os/routers/workflows/router.py +38 -11
- agno/os/routers/workflows/schema.py +1 -1
- agno/os/schema.py +92 -26
- agno/os/utils.py +84 -19
- agno/reasoning/anthropic.py +2 -2
- agno/reasoning/azure_ai_foundry.py +2 -2
- agno/reasoning/deepseek.py +2 -2
- agno/reasoning/default.py +6 -7
- agno/reasoning/gemini.py +2 -2
- agno/reasoning/helpers.py +6 -7
- agno/reasoning/manager.py +4 -10
- agno/reasoning/ollama.py +2 -2
- agno/reasoning/openai.py +2 -2
- agno/reasoning/vertexai.py +2 -2
- agno/registry/__init__.py +3 -0
- agno/registry/registry.py +68 -0
- agno/run/agent.py +59 -0
- agno/run/base.py +7 -0
- agno/run/team.py +57 -0
- agno/skills/agent_skills.py +10 -3
- agno/team/__init__.py +3 -1
- agno/team/team.py +1165 -330
- agno/tools/duckduckgo.py +25 -71
- agno/tools/exa.py +0 -21
- agno/tools/function.py +35 -83
- agno/tools/knowledge.py +9 -4
- agno/tools/mem0.py +11 -10
- agno/tools/memory.py +47 -46
- agno/tools/parallel.py +0 -7
- agno/tools/reasoning.py +30 -23
- agno/tools/tavily.py +4 -1
- agno/tools/websearch.py +93 -0
- agno/tools/website.py +1 -1
- agno/tools/wikipedia.py +1 -1
- agno/tools/workflow.py +48 -47
- agno/utils/agent.py +42 -5
- agno/utils/events.py +160 -2
- agno/utils/print_response/agent.py +0 -31
- agno/utils/print_response/team.py +0 -2
- agno/utils/print_response/workflow.py +0 -2
- agno/utils/team.py +61 -11
- agno/vectordb/lancedb/lance_db.py +4 -1
- agno/vectordb/mongodb/mongodb.py +1 -1
- agno/vectordb/pgvector/pgvector.py +3 -3
- agno/vectordb/qdrant/qdrant.py +4 -4
- agno/workflow/__init__.py +3 -1
- agno/workflow/condition.py +0 -21
- agno/workflow/loop.py +0 -21
- agno/workflow/parallel.py +0 -21
- agno/workflow/router.py +0 -21
- agno/workflow/step.py +117 -24
- agno/workflow/steps.py +0 -21
- agno/workflow/workflow.py +427 -63
- {agno-2.3.26.dist-info → agno-2.4.1.dist-info}/METADATA +49 -76
- {agno-2.3.26.dist-info → agno-2.4.1.dist-info}/RECORD +140 -126
- {agno-2.3.26.dist-info → agno-2.4.1.dist-info}/WHEEL +1 -1
- {agno-2.3.26.dist-info → agno-2.4.1.dist-info}/licenses/LICENSE +0 -0
- {agno-2.3.26.dist-info → agno-2.4.1.dist-info}/top_level.txt +0 -0
agno/reasoning/manager.py
CHANGED
|
@@ -14,7 +14,6 @@ from dataclasses import dataclass, field
|
|
|
14
14
|
from enum import Enum
|
|
15
15
|
from typing import (
|
|
16
16
|
TYPE_CHECKING,
|
|
17
|
-
Any,
|
|
18
17
|
AsyncIterator,
|
|
19
18
|
Callable,
|
|
20
19
|
Dict,
|
|
@@ -29,6 +28,7 @@ from typing import (
|
|
|
29
28
|
from agno.models.base import Model
|
|
30
29
|
from agno.models.message import Message
|
|
31
30
|
from agno.reasoning.step import NextAction, ReasoningStep, ReasoningSteps
|
|
31
|
+
from agno.run.base import RunContext
|
|
32
32
|
from agno.run.messages import RunMessages
|
|
33
33
|
from agno.tools import Toolkit
|
|
34
34
|
from agno.tools.function import Function
|
|
@@ -87,9 +87,7 @@ class ReasoningConfig:
|
|
|
87
87
|
telemetry: bool = True
|
|
88
88
|
debug_mode: bool = False
|
|
89
89
|
debug_level: Literal[1, 2] = 1
|
|
90
|
-
|
|
91
|
-
dependencies: Optional[Dict[str, Any]] = None
|
|
92
|
-
metadata: Optional[Dict[str, Any]] = None
|
|
90
|
+
run_context: Optional[RunContext] = None
|
|
93
91
|
|
|
94
92
|
|
|
95
93
|
@dataclass
|
|
@@ -161,9 +159,7 @@ class ReasoningManager:
|
|
|
161
159
|
telemetry=self.config.telemetry,
|
|
162
160
|
debug_mode=self.config.debug_mode,
|
|
163
161
|
debug_level=self.config.debug_level,
|
|
164
|
-
|
|
165
|
-
dependencies=self.config.dependencies,
|
|
166
|
-
metadata=self.config.metadata,
|
|
162
|
+
run_context=self.config.run_context,
|
|
167
163
|
)
|
|
168
164
|
|
|
169
165
|
def _get_default_reasoning_agent(self, model: Model) -> Optional["Agent"]:
|
|
@@ -183,9 +179,7 @@ class ReasoningManager:
|
|
|
183
179
|
telemetry=self.config.telemetry,
|
|
184
180
|
debug_mode=self.config.debug_mode,
|
|
185
181
|
debug_level=self.config.debug_level,
|
|
186
|
-
|
|
187
|
-
dependencies=self.config.dependencies,
|
|
188
|
-
metadata=self.config.metadata,
|
|
182
|
+
run_context=self.config.run_context,
|
|
189
183
|
)
|
|
190
184
|
|
|
191
185
|
def is_native_reasoning_model(self, model: Optional[Model] = None) -> bool:
|
agno/reasoning/ollama.py
CHANGED
|
@@ -86,7 +86,7 @@ def get_ollama_reasoning_stream(
|
|
|
86
86
|
reasoning_content: str = ""
|
|
87
87
|
|
|
88
88
|
try:
|
|
89
|
-
for event in reasoning_agent.run(input=messages, stream=True,
|
|
89
|
+
for event in reasoning_agent.run(input=messages, stream=True, stream_events=True):
|
|
90
90
|
if hasattr(event, "event"):
|
|
91
91
|
if event.event == RunEvent.run_content:
|
|
92
92
|
# Check for reasoning_content attribute first (native reasoning)
|
|
@@ -132,7 +132,7 @@ async def aget_ollama_reasoning_stream(
|
|
|
132
132
|
reasoning_content: str = ""
|
|
133
133
|
|
|
134
134
|
try:
|
|
135
|
-
async for event in reasoning_agent.arun(input=messages, stream=True,
|
|
135
|
+
async for event in reasoning_agent.arun(input=messages, stream=True, stream_events=True):
|
|
136
136
|
if hasattr(event, "event"):
|
|
137
137
|
if event.event == RunEvent.run_content:
|
|
138
138
|
# Check for reasoning_content attribute first (native reasoning)
|
agno/reasoning/openai.py
CHANGED
|
@@ -112,7 +112,7 @@ def get_openai_reasoning_stream(
|
|
|
112
112
|
reasoning_content: str = ""
|
|
113
113
|
|
|
114
114
|
try:
|
|
115
|
-
for event in reasoning_agent.run(input=messages, stream=True,
|
|
115
|
+
for event in reasoning_agent.run(input=messages, stream=True, stream_events=True):
|
|
116
116
|
if hasattr(event, "event"):
|
|
117
117
|
if event.event == RunEvent.run_content:
|
|
118
118
|
# Check for reasoning_content attribute first (native reasoning)
|
|
@@ -168,7 +168,7 @@ async def aget_openai_reasoning_stream(
|
|
|
168
168
|
reasoning_content: str = ""
|
|
169
169
|
|
|
170
170
|
try:
|
|
171
|
-
async for event in reasoning_agent.arun(input=messages, stream=True,
|
|
171
|
+
async for event in reasoning_agent.arun(input=messages, stream=True, stream_events=True):
|
|
172
172
|
if hasattr(event, "event"):
|
|
173
173
|
if event.event == RunEvent.run_content:
|
|
174
174
|
# Check for reasoning_content attribute first (native reasoning)
|
agno/reasoning/vertexai.py
CHANGED
|
@@ -94,7 +94,7 @@ def get_vertexai_reasoning_stream(
|
|
|
94
94
|
redacted_reasoning_content: Optional[str] = None
|
|
95
95
|
|
|
96
96
|
try:
|
|
97
|
-
for event in reasoning_agent.run(input=messages, stream=True,
|
|
97
|
+
for event in reasoning_agent.run(input=messages, stream=True, stream_events=True):
|
|
98
98
|
if hasattr(event, "event"):
|
|
99
99
|
if event.event == RunEvent.run_content:
|
|
100
100
|
# Stream reasoning content as it arrives
|
|
@@ -136,7 +136,7 @@ async def aget_vertexai_reasoning_stream(
|
|
|
136
136
|
redacted_reasoning_content: Optional[str] = None
|
|
137
137
|
|
|
138
138
|
try:
|
|
139
|
-
async for event in reasoning_agent.arun(input=messages, stream=True,
|
|
139
|
+
async for event in reasoning_agent.arun(input=messages, stream=True, stream_events=True):
|
|
140
140
|
if hasattr(event, "event"):
|
|
141
141
|
if event.event == RunEvent.run_content:
|
|
142
142
|
# Stream reasoning content as it arrives
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
from dataclasses import dataclass, field
|
|
2
|
+
from functools import cached_property
|
|
3
|
+
from typing import Any, Callable, Dict, List, Optional, Type
|
|
4
|
+
from uuid import uuid4
|
|
5
|
+
|
|
6
|
+
from pydantic import BaseModel
|
|
7
|
+
|
|
8
|
+
from agno.db.base import BaseDb
|
|
9
|
+
from agno.models.base import Model
|
|
10
|
+
from agno.tools.function import Function
|
|
11
|
+
from agno.tools.toolkit import Toolkit
|
|
12
|
+
from agno.vectordb.base import VectorDb
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@dataclass
|
|
16
|
+
class Registry:
|
|
17
|
+
"""
|
|
18
|
+
Registry is used to manage non serializable objects like tools, models, databases and vector databases.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
name: Optional[str] = None
|
|
22
|
+
description: Optional[str] = None
|
|
23
|
+
id: str = field(default_factory=lambda: str(uuid4()))
|
|
24
|
+
tools: List[Any] = field(default_factory=list)
|
|
25
|
+
models: List[Model] = field(default_factory=list)
|
|
26
|
+
dbs: List[BaseDb] = field(default_factory=list)
|
|
27
|
+
vector_dbs: List[VectorDb] = field(default_factory=list)
|
|
28
|
+
schemas: List[Type[BaseModel]] = field(default_factory=list)
|
|
29
|
+
|
|
30
|
+
@cached_property
|
|
31
|
+
def _entrypoint_lookup(self) -> Dict[str, Callable]:
|
|
32
|
+
lookup: Dict[str, Callable] = {}
|
|
33
|
+
for tool in self.tools:
|
|
34
|
+
if isinstance(tool, Toolkit):
|
|
35
|
+
for func in tool.functions.values():
|
|
36
|
+
if func.entrypoint is not None:
|
|
37
|
+
lookup[func.name] = func.entrypoint
|
|
38
|
+
elif isinstance(tool, Function):
|
|
39
|
+
if tool.entrypoint is not None:
|
|
40
|
+
lookup[tool.name] = tool.entrypoint
|
|
41
|
+
elif callable(tool):
|
|
42
|
+
lookup[tool.__name__] = tool
|
|
43
|
+
return lookup
|
|
44
|
+
|
|
45
|
+
def rehydrate_function(self, func_dict: Dict[str, Any]) -> Function:
|
|
46
|
+
"""Reconstruct a Function from dict, reattaching its entrypoint."""
|
|
47
|
+
func = Function.from_dict(func_dict)
|
|
48
|
+
func.entrypoint = self._entrypoint_lookup.get(func.name)
|
|
49
|
+
return func
|
|
50
|
+
|
|
51
|
+
def get_schema(self, name: str) -> Optional[Type[BaseModel]]:
|
|
52
|
+
"""Get a schema by name."""
|
|
53
|
+
if self.schemas:
|
|
54
|
+
return next((s for s in self.schemas if s.__name__ == name), None)
|
|
55
|
+
return None
|
|
56
|
+
|
|
57
|
+
def get_db(self, db_id: str) -> Optional[BaseDb]:
|
|
58
|
+
"""Get a database by id from the registry.
|
|
59
|
+
|
|
60
|
+
Args:
|
|
61
|
+
db_id: The database id to look up
|
|
62
|
+
|
|
63
|
+
Returns:
|
|
64
|
+
The database instance if found, None otherwise
|
|
65
|
+
"""
|
|
66
|
+
if self.dbs:
|
|
67
|
+
return next((db for db in self.dbs if db.id == db_id), None)
|
|
68
|
+
return None
|
agno/run/agent.py
CHANGED
|
@@ -172,6 +172,12 @@ class RunEvent(str, Enum):
|
|
|
172
172
|
output_model_response_started = "OutputModelResponseStarted"
|
|
173
173
|
output_model_response_completed = "OutputModelResponseCompleted"
|
|
174
174
|
|
|
175
|
+
model_request_started = "ModelRequestStarted"
|
|
176
|
+
model_request_completed = "ModelRequestCompleted"
|
|
177
|
+
|
|
178
|
+
compression_started = "CompressionStarted"
|
|
179
|
+
compression_completed = "CompressionCompleted"
|
|
180
|
+
|
|
175
181
|
custom_event = "CustomEvent"
|
|
176
182
|
|
|
177
183
|
|
|
@@ -349,6 +355,7 @@ class MemoryUpdateStartedEvent(BaseAgentRunEvent):
|
|
|
349
355
|
@dataclass
|
|
350
356
|
class MemoryUpdateCompletedEvent(BaseAgentRunEvent):
|
|
351
357
|
event: str = RunEvent.memory_update_completed.value
|
|
358
|
+
memories: Optional[List[Any]] = None
|
|
352
359
|
|
|
353
360
|
|
|
354
361
|
@dataclass
|
|
@@ -433,9 +440,53 @@ class OutputModelResponseCompletedEvent(BaseAgentRunEvent):
|
|
|
433
440
|
event: str = RunEvent.output_model_response_completed.value
|
|
434
441
|
|
|
435
442
|
|
|
443
|
+
@dataclass
|
|
444
|
+
class ModelRequestStartedEvent(BaseAgentRunEvent):
|
|
445
|
+
"""Event sent when a model request is about to be made"""
|
|
446
|
+
|
|
447
|
+
event: str = RunEvent.model_request_started.value
|
|
448
|
+
model: Optional[str] = None
|
|
449
|
+
model_provider: Optional[str] = None
|
|
450
|
+
|
|
451
|
+
|
|
452
|
+
@dataclass
|
|
453
|
+
class ModelRequestCompletedEvent(BaseAgentRunEvent):
|
|
454
|
+
"""Event sent when a model request has completed"""
|
|
455
|
+
|
|
456
|
+
event: str = RunEvent.model_request_completed.value
|
|
457
|
+
model: Optional[str] = None
|
|
458
|
+
model_provider: Optional[str] = None
|
|
459
|
+
input_tokens: Optional[int] = None
|
|
460
|
+
output_tokens: Optional[int] = None
|
|
461
|
+
total_tokens: Optional[int] = None
|
|
462
|
+
time_to_first_token: Optional[float] = None
|
|
463
|
+
reasoning_tokens: Optional[int] = None
|
|
464
|
+
cache_read_tokens: Optional[int] = None
|
|
465
|
+
cache_write_tokens: Optional[int] = None
|
|
466
|
+
|
|
467
|
+
|
|
468
|
+
@dataclass
|
|
469
|
+
class CompressionStartedEvent(BaseAgentRunEvent):
|
|
470
|
+
"""Event sent when tool result compression is about to start"""
|
|
471
|
+
|
|
472
|
+
event: str = RunEvent.compression_started.value
|
|
473
|
+
|
|
474
|
+
|
|
475
|
+
@dataclass
|
|
476
|
+
class CompressionCompletedEvent(BaseAgentRunEvent):
|
|
477
|
+
"""Event sent when tool result compression has completed"""
|
|
478
|
+
|
|
479
|
+
event: str = RunEvent.compression_completed.value
|
|
480
|
+
tool_results_compressed: Optional[int] = None
|
|
481
|
+
original_size: Optional[int] = None
|
|
482
|
+
compressed_size: Optional[int] = None
|
|
483
|
+
|
|
484
|
+
|
|
436
485
|
@dataclass
|
|
437
486
|
class CustomEvent(BaseAgentRunEvent):
|
|
438
487
|
event: str = RunEvent.custom_event.value
|
|
488
|
+
# tool_call_id for ToolExecution
|
|
489
|
+
tool_call_id: Optional[str] = None
|
|
439
490
|
|
|
440
491
|
def __init__(self, **kwargs):
|
|
441
492
|
# Store arbitrary attributes directly on the instance
|
|
@@ -472,6 +523,10 @@ RunOutputEvent = Union[
|
|
|
472
523
|
ParserModelResponseCompletedEvent,
|
|
473
524
|
OutputModelResponseStartedEvent,
|
|
474
525
|
OutputModelResponseCompletedEvent,
|
|
526
|
+
ModelRequestStartedEvent,
|
|
527
|
+
ModelRequestCompletedEvent,
|
|
528
|
+
CompressionStartedEvent,
|
|
529
|
+
CompressionCompletedEvent,
|
|
475
530
|
CustomEvent,
|
|
476
531
|
]
|
|
477
532
|
|
|
@@ -506,6 +561,10 @@ RUN_EVENT_TYPE_REGISTRY = {
|
|
|
506
561
|
RunEvent.parser_model_response_completed.value: ParserModelResponseCompletedEvent,
|
|
507
562
|
RunEvent.output_model_response_started.value: OutputModelResponseStartedEvent,
|
|
508
563
|
RunEvent.output_model_response_completed.value: OutputModelResponseCompletedEvent,
|
|
564
|
+
RunEvent.model_request_started.value: ModelRequestStartedEvent,
|
|
565
|
+
RunEvent.model_request_completed.value: ModelRequestCompletedEvent,
|
|
566
|
+
RunEvent.compression_started.value: CompressionStartedEvent,
|
|
567
|
+
RunEvent.compression_completed.value: CompressionCompletedEvent,
|
|
509
568
|
RunEvent.custom_event.value: CustomEvent,
|
|
510
569
|
}
|
|
511
570
|
|
agno/run/base.py
CHANGED
|
@@ -18,6 +18,9 @@ class RunContext:
|
|
|
18
18
|
session_id: str
|
|
19
19
|
user_id: Optional[str] = None
|
|
20
20
|
|
|
21
|
+
workflow_id: Optional[str] = None
|
|
22
|
+
workflow_name: Optional[str] = None
|
|
23
|
+
|
|
21
24
|
dependencies: Optional[Dict[str, Any]] = None
|
|
22
25
|
knowledge_filters: Optional[Union[Dict[str, Any], List[FilterExpr]]] = None
|
|
23
26
|
metadata: Optional[Dict[str, Any]] = None
|
|
@@ -52,6 +55,7 @@ class BaseRunOutputEvent:
|
|
|
52
55
|
"metrics",
|
|
53
56
|
"run_input",
|
|
54
57
|
"requirements",
|
|
58
|
+
"memories",
|
|
55
59
|
]
|
|
56
60
|
}
|
|
57
61
|
|
|
@@ -142,6 +146,9 @@ class BaseRunOutputEvent:
|
|
|
142
146
|
if hasattr(self, "requirements") and self.requirements is not None:
|
|
143
147
|
_dict["requirements"] = [req.to_dict() if hasattr(req, "to_dict") else req for req in self.requirements]
|
|
144
148
|
|
|
149
|
+
if hasattr(self, "memories") and self.memories is not None:
|
|
150
|
+
_dict["memories"] = [mem.to_dict() if hasattr(mem, "to_dict") else mem for mem in self.memories]
|
|
151
|
+
|
|
145
152
|
return _dict
|
|
146
153
|
|
|
147
154
|
def to_json(self, separators=(", ", ": "), indent: Optional[int] = 2) -> str:
|
agno/run/team.py
CHANGED
|
@@ -165,6 +165,12 @@ class TeamRunEvent(str, Enum):
|
|
|
165
165
|
output_model_response_started = "TeamOutputModelResponseStarted"
|
|
166
166
|
output_model_response_completed = "TeamOutputModelResponseCompleted"
|
|
167
167
|
|
|
168
|
+
model_request_started = "TeamModelRequestStarted"
|
|
169
|
+
model_request_completed = "TeamModelRequestCompleted"
|
|
170
|
+
|
|
171
|
+
compression_started = "TeamCompressionStarted"
|
|
172
|
+
compression_completed = "TeamCompressionCompleted"
|
|
173
|
+
|
|
168
174
|
custom_event = "CustomEvent"
|
|
169
175
|
|
|
170
176
|
|
|
@@ -322,6 +328,7 @@ class MemoryUpdateStartedEvent(BaseTeamRunEvent):
|
|
|
322
328
|
@dataclass
|
|
323
329
|
class MemoryUpdateCompletedEvent(BaseTeamRunEvent):
|
|
324
330
|
event: str = TeamRunEvent.memory_update_completed.value
|
|
331
|
+
memories: Optional[List[Any]] = None
|
|
325
332
|
|
|
326
333
|
|
|
327
334
|
@dataclass
|
|
@@ -406,6 +413,48 @@ class OutputModelResponseCompletedEvent(BaseTeamRunEvent):
|
|
|
406
413
|
event: str = TeamRunEvent.output_model_response_completed.value
|
|
407
414
|
|
|
408
415
|
|
|
416
|
+
@dataclass
|
|
417
|
+
class ModelRequestStartedEvent(BaseTeamRunEvent):
|
|
418
|
+
"""Event sent when a model request is about to be made"""
|
|
419
|
+
|
|
420
|
+
event: str = TeamRunEvent.model_request_started.value
|
|
421
|
+
model: Optional[str] = None
|
|
422
|
+
model_provider: Optional[str] = None
|
|
423
|
+
|
|
424
|
+
|
|
425
|
+
@dataclass
|
|
426
|
+
class ModelRequestCompletedEvent(BaseTeamRunEvent):
|
|
427
|
+
"""Event sent when a model request has completed"""
|
|
428
|
+
|
|
429
|
+
event: str = TeamRunEvent.model_request_completed.value
|
|
430
|
+
model: Optional[str] = None
|
|
431
|
+
model_provider: Optional[str] = None
|
|
432
|
+
input_tokens: Optional[int] = None
|
|
433
|
+
output_tokens: Optional[int] = None
|
|
434
|
+
total_tokens: Optional[int] = None
|
|
435
|
+
time_to_first_token: Optional[float] = None
|
|
436
|
+
reasoning_tokens: Optional[int] = None
|
|
437
|
+
cache_read_tokens: Optional[int] = None
|
|
438
|
+
cache_write_tokens: Optional[int] = None
|
|
439
|
+
|
|
440
|
+
|
|
441
|
+
@dataclass
|
|
442
|
+
class CompressionStartedEvent(BaseTeamRunEvent):
|
|
443
|
+
"""Event sent when tool result compression is about to start"""
|
|
444
|
+
|
|
445
|
+
event: str = TeamRunEvent.compression_started.value
|
|
446
|
+
|
|
447
|
+
|
|
448
|
+
@dataclass
|
|
449
|
+
class CompressionCompletedEvent(BaseTeamRunEvent):
|
|
450
|
+
"""Event sent when tool result compression has completed"""
|
|
451
|
+
|
|
452
|
+
event: str = TeamRunEvent.compression_completed.value
|
|
453
|
+
tool_results_compressed: Optional[int] = None
|
|
454
|
+
original_size: Optional[int] = None
|
|
455
|
+
compressed_size: Optional[int] = None
|
|
456
|
+
|
|
457
|
+
|
|
409
458
|
@dataclass
|
|
410
459
|
class CustomEvent(BaseTeamRunEvent):
|
|
411
460
|
event: str = TeamRunEvent.custom_event.value
|
|
@@ -441,6 +490,10 @@ TeamRunOutputEvent = Union[
|
|
|
441
490
|
ParserModelResponseCompletedEvent,
|
|
442
491
|
OutputModelResponseStartedEvent,
|
|
443
492
|
OutputModelResponseCompletedEvent,
|
|
493
|
+
ModelRequestStartedEvent,
|
|
494
|
+
ModelRequestCompletedEvent,
|
|
495
|
+
CompressionStartedEvent,
|
|
496
|
+
CompressionCompletedEvent,
|
|
444
497
|
CustomEvent,
|
|
445
498
|
]
|
|
446
499
|
|
|
@@ -472,6 +525,10 @@ TEAM_RUN_EVENT_TYPE_REGISTRY = {
|
|
|
472
525
|
TeamRunEvent.parser_model_response_completed.value: ParserModelResponseCompletedEvent,
|
|
473
526
|
TeamRunEvent.output_model_response_started.value: OutputModelResponseStartedEvent,
|
|
474
527
|
TeamRunEvent.output_model_response_completed.value: OutputModelResponseCompletedEvent,
|
|
528
|
+
TeamRunEvent.model_request_started.value: ModelRequestStartedEvent,
|
|
529
|
+
TeamRunEvent.model_request_completed.value: ModelRequestCompletedEvent,
|
|
530
|
+
TeamRunEvent.compression_started.value: CompressionStartedEvent,
|
|
531
|
+
TeamRunEvent.compression_completed.value: CompressionCompletedEvent,
|
|
475
532
|
TeamRunEvent.custom_event.value: CustomEvent,
|
|
476
533
|
}
|
|
477
534
|
|
agno/skills/agent_skills.py
CHANGED
|
@@ -106,10 +106,17 @@ class Skills:
|
|
|
106
106
|
"- **Scripts**: Executable code templates you can use or adapt",
|
|
107
107
|
"- **References**: Supporting documentation (guides, cheatsheets, examples)",
|
|
108
108
|
"",
|
|
109
|
-
"##
|
|
110
|
-
"Skill
|
|
109
|
+
"## IMPORTANT: How to Use Skills",
|
|
110
|
+
"**Skill names are NOT callable functions.** You cannot call a skill directly by its name.",
|
|
111
|
+
"Instead, you MUST use the provided skill access tools:",
|
|
112
|
+
"",
|
|
113
|
+
"1. `get_skill_instructions(skill_name)` - Load the full instructions for a skill",
|
|
114
|
+
"2. `get_skill_reference(skill_name, reference_path)` - Access specific documentation",
|
|
115
|
+
"3. `get_skill_script(skill_name, script_path, execute=False)` - Read or run scripts",
|
|
116
|
+
"",
|
|
117
|
+
"## Progressive Discovery Workflow",
|
|
111
118
|
"1. **Browse**: Review the skill summaries below to understand what's available",
|
|
112
|
-
"2. **Load**: When a task matches a skill,
|
|
119
|
+
"2. **Load**: When a task matches a skill, call `get_skill_instructions(skill_name)` first",
|
|
113
120
|
"3. **Reference**: Use `get_skill_reference` to access specific documentation as needed",
|
|
114
121
|
"4. **Scripts**: Use `get_skill_script` to read or execute scripts from a skill",
|
|
115
122
|
"",
|
agno/team/__init__.py
CHANGED
|
@@ -16,7 +16,7 @@ from agno.run.team import (
|
|
|
16
16
|
ToolCallStartedEvent,
|
|
17
17
|
)
|
|
18
18
|
from agno.team.remote import RemoteTeam
|
|
19
|
-
from agno.team.team import Team
|
|
19
|
+
from agno.team.team import Team, get_team_by_id, get_teams
|
|
20
20
|
|
|
21
21
|
__all__ = [
|
|
22
22
|
"Team",
|
|
@@ -36,4 +36,6 @@ __all__ = [
|
|
|
36
36
|
"ReasoningCompletedEvent",
|
|
37
37
|
"ToolCallStartedEvent",
|
|
38
38
|
"ToolCallCompletedEvent",
|
|
39
|
+
"get_team_by_id",
|
|
40
|
+
"get_teams",
|
|
39
41
|
]
|