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.
Files changed (140) hide show
  1. agno/agent/__init__.py +4 -0
  2. agno/agent/agent.py +1368 -541
  3. agno/agent/remote.py +13 -0
  4. agno/db/base.py +339 -0
  5. agno/db/postgres/async_postgres.py +116 -12
  6. agno/db/postgres/postgres.py +1242 -25
  7. agno/db/postgres/schemas.py +48 -1
  8. agno/db/sqlite/async_sqlite.py +119 -4
  9. agno/db/sqlite/schemas.py +51 -0
  10. agno/db/sqlite/sqlite.py +1186 -13
  11. agno/db/utils.py +37 -1
  12. agno/integrations/discord/client.py +12 -1
  13. agno/knowledge/__init__.py +4 -0
  14. agno/knowledge/chunking/code.py +1 -1
  15. agno/knowledge/chunking/semantic.py +1 -1
  16. agno/knowledge/chunking/strategy.py +4 -0
  17. agno/knowledge/filesystem.py +412 -0
  18. agno/knowledge/knowledge.py +3722 -2182
  19. agno/knowledge/protocol.py +134 -0
  20. agno/knowledge/reader/arxiv_reader.py +2 -2
  21. agno/knowledge/reader/base.py +9 -7
  22. agno/knowledge/reader/csv_reader.py +236 -13
  23. agno/knowledge/reader/docx_reader.py +2 -2
  24. agno/knowledge/reader/field_labeled_csv_reader.py +169 -5
  25. agno/knowledge/reader/firecrawl_reader.py +2 -2
  26. agno/knowledge/reader/json_reader.py +2 -2
  27. agno/knowledge/reader/markdown_reader.py +2 -2
  28. agno/knowledge/reader/pdf_reader.py +5 -4
  29. agno/knowledge/reader/pptx_reader.py +2 -2
  30. agno/knowledge/reader/reader_factory.py +118 -1
  31. agno/knowledge/reader/s3_reader.py +2 -2
  32. agno/knowledge/reader/tavily_reader.py +2 -2
  33. agno/knowledge/reader/text_reader.py +2 -2
  34. agno/knowledge/reader/web_search_reader.py +2 -2
  35. agno/knowledge/reader/website_reader.py +5 -3
  36. agno/knowledge/reader/wikipedia_reader.py +2 -2
  37. agno/knowledge/reader/youtube_reader.py +2 -2
  38. agno/knowledge/remote_content/__init__.py +29 -0
  39. agno/knowledge/remote_content/config.py +204 -0
  40. agno/knowledge/remote_content/remote_content.py +74 -17
  41. agno/knowledge/utils.py +37 -29
  42. agno/learn/__init__.py +6 -0
  43. agno/learn/machine.py +35 -0
  44. agno/learn/schemas.py +82 -11
  45. agno/learn/stores/__init__.py +3 -0
  46. agno/learn/stores/decision_log.py +1156 -0
  47. agno/learn/stores/learned_knowledge.py +6 -6
  48. agno/models/anthropic/claude.py +24 -0
  49. agno/models/aws/bedrock.py +20 -0
  50. agno/models/base.py +60 -6
  51. agno/models/cerebras/cerebras.py +34 -2
  52. agno/models/cohere/chat.py +25 -0
  53. agno/models/google/gemini.py +50 -5
  54. agno/models/litellm/chat.py +38 -0
  55. agno/models/n1n/__init__.py +3 -0
  56. agno/models/n1n/n1n.py +57 -0
  57. agno/models/openai/chat.py +25 -1
  58. agno/models/openrouter/openrouter.py +46 -0
  59. agno/models/perplexity/perplexity.py +2 -0
  60. agno/models/response.py +16 -0
  61. agno/os/app.py +83 -44
  62. agno/os/interfaces/slack/router.py +10 -1
  63. agno/os/interfaces/whatsapp/router.py +6 -0
  64. agno/os/middleware/__init__.py +2 -0
  65. agno/os/middleware/trailing_slash.py +27 -0
  66. agno/os/router.py +1 -0
  67. agno/os/routers/agents/router.py +29 -16
  68. agno/os/routers/agents/schema.py +6 -4
  69. agno/os/routers/components/__init__.py +3 -0
  70. agno/os/routers/components/components.py +475 -0
  71. agno/os/routers/evals/schemas.py +4 -3
  72. agno/os/routers/health.py +3 -3
  73. agno/os/routers/knowledge/knowledge.py +128 -3
  74. agno/os/routers/knowledge/schemas.py +12 -0
  75. agno/os/routers/memory/schemas.py +4 -2
  76. agno/os/routers/metrics/metrics.py +9 -11
  77. agno/os/routers/metrics/schemas.py +10 -6
  78. agno/os/routers/registry/__init__.py +3 -0
  79. agno/os/routers/registry/registry.py +337 -0
  80. agno/os/routers/teams/router.py +20 -8
  81. agno/os/routers/teams/schema.py +6 -4
  82. agno/os/routers/traces/traces.py +5 -5
  83. agno/os/routers/workflows/router.py +38 -11
  84. agno/os/routers/workflows/schema.py +1 -1
  85. agno/os/schema.py +92 -26
  86. agno/os/utils.py +84 -19
  87. agno/reasoning/anthropic.py +2 -2
  88. agno/reasoning/azure_ai_foundry.py +2 -2
  89. agno/reasoning/deepseek.py +2 -2
  90. agno/reasoning/default.py +6 -7
  91. agno/reasoning/gemini.py +2 -2
  92. agno/reasoning/helpers.py +6 -7
  93. agno/reasoning/manager.py +4 -10
  94. agno/reasoning/ollama.py +2 -2
  95. agno/reasoning/openai.py +2 -2
  96. agno/reasoning/vertexai.py +2 -2
  97. agno/registry/__init__.py +3 -0
  98. agno/registry/registry.py +68 -0
  99. agno/run/agent.py +59 -0
  100. agno/run/base.py +7 -0
  101. agno/run/team.py +57 -0
  102. agno/skills/agent_skills.py +10 -3
  103. agno/team/__init__.py +3 -1
  104. agno/team/team.py +1165 -330
  105. agno/tools/duckduckgo.py +25 -71
  106. agno/tools/exa.py +0 -21
  107. agno/tools/function.py +35 -83
  108. agno/tools/knowledge.py +9 -4
  109. agno/tools/mem0.py +11 -10
  110. agno/tools/memory.py +47 -46
  111. agno/tools/parallel.py +0 -7
  112. agno/tools/reasoning.py +30 -23
  113. agno/tools/tavily.py +4 -1
  114. agno/tools/websearch.py +93 -0
  115. agno/tools/website.py +1 -1
  116. agno/tools/wikipedia.py +1 -1
  117. agno/tools/workflow.py +48 -47
  118. agno/utils/agent.py +42 -5
  119. agno/utils/events.py +160 -2
  120. agno/utils/print_response/agent.py +0 -31
  121. agno/utils/print_response/team.py +0 -2
  122. agno/utils/print_response/workflow.py +0 -2
  123. agno/utils/team.py +61 -11
  124. agno/vectordb/lancedb/lance_db.py +4 -1
  125. agno/vectordb/mongodb/mongodb.py +1 -1
  126. agno/vectordb/pgvector/pgvector.py +3 -3
  127. agno/vectordb/qdrant/qdrant.py +4 -4
  128. agno/workflow/__init__.py +3 -1
  129. agno/workflow/condition.py +0 -21
  130. agno/workflow/loop.py +0 -21
  131. agno/workflow/parallel.py +0 -21
  132. agno/workflow/router.py +0 -21
  133. agno/workflow/step.py +117 -24
  134. agno/workflow/steps.py +0 -21
  135. agno/workflow/workflow.py +427 -63
  136. {agno-2.3.26.dist-info → agno-2.4.1.dist-info}/METADATA +49 -76
  137. {agno-2.3.26.dist-info → agno-2.4.1.dist-info}/RECORD +140 -126
  138. {agno-2.3.26.dist-info → agno-2.4.1.dist-info}/WHEEL +1 -1
  139. {agno-2.3.26.dist-info → agno-2.4.1.dist-info}/licenses/LICENSE +0 -0
  140. {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
- session_state: Optional[Dict[str, Any]] = None
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
- session_state=self.config.session_state,
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
- session_state=self.config.session_state,
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, stream_intermediate_steps=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, stream_intermediate_steps=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, stream_intermediate_steps=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, stream_intermediate_steps=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)
@@ -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, stream_intermediate_steps=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, stream_intermediate_steps=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,3 @@
1
+ from agno.registry.registry import Registry
2
+
3
+ __all__ = ["Registry"]
@@ -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
 
@@ -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
- "## Progressive Discovery",
110
- "Skill information is designed to be loaded on-demand to keep your context focused:",
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, use `get_skill_instructions` to load full guidance",
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
  ]