agno 2.3.13__py3-none-any.whl → 2.3.14__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 +1131 -1402
- agno/eval/__init__.py +21 -8
- agno/knowledge/embedder/azure_openai.py +0 -1
- agno/knowledge/embedder/google.py +1 -1
- agno/models/anthropic/claude.py +4 -1
- agno/models/base.py +8 -4
- agno/models/openai/responses.py +2 -2
- agno/os/app.py +39 -0
- agno/os/interfaces/a2a/router.py +619 -9
- agno/os/interfaces/a2a/utils.py +31 -32
- agno/os/middleware/jwt.py +5 -5
- agno/os/routers/agents/schema.py +14 -1
- agno/os/routers/teams/schema.py +14 -1
- agno/os/utils.py +61 -53
- agno/reasoning/anthropic.py +85 -1
- agno/reasoning/azure_ai_foundry.py +93 -1
- agno/reasoning/deepseek.py +91 -1
- agno/reasoning/gemini.py +81 -1
- agno/reasoning/groq.py +103 -1
- agno/reasoning/manager.py +1244 -0
- agno/reasoning/ollama.py +93 -1
- agno/reasoning/openai.py +113 -1
- agno/reasoning/vertexai.py +85 -1
- agno/run/agent.py +11 -0
- agno/run/base.py +1 -1
- agno/run/team.py +11 -0
- agno/session/team.py +0 -3
- agno/team/team.py +1201 -1445
- agno/utils/events.py +69 -2
- agno/utils/hooks.py +4 -10
- agno/utils/print_response/agent.py +26 -0
- agno/utils/print_response/team.py +11 -0
- agno/utils/prompts.py +8 -6
- agno/utils/string.py +46 -0
- agno/utils/team.py +1 -1
- agno/vectordb/milvus/milvus.py +32 -3
- {agno-2.3.13.dist-info → agno-2.3.14.dist-info}/METADATA +3 -2
- {agno-2.3.13.dist-info → agno-2.3.14.dist-info}/RECORD +41 -40
- {agno-2.3.13.dist-info → agno-2.3.14.dist-info}/WHEEL +0 -0
- {agno-2.3.13.dist-info → agno-2.3.14.dist-info}/licenses/LICENSE +0 -0
- {agno-2.3.13.dist-info → agno-2.3.14.dist-info}/top_level.txt +0 -0
agno/reasoning/ollama.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from typing import List, Optional
|
|
3
|
+
from typing import AsyncIterator, Iterator, List, Optional, Tuple
|
|
4
4
|
|
|
5
5
|
from agno.models.base import Model
|
|
6
6
|
from agno.models.message import Message
|
|
@@ -65,3 +65,95 @@ async def aget_ollama_reasoning(reasoning_agent: "Agent", messages: List[Message
|
|
|
65
65
|
return Message(
|
|
66
66
|
role="assistant", content=f"<thinking>\n{reasoning_content}\n</thinking>", reasoning_content=reasoning_content
|
|
67
67
|
)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def get_ollama_reasoning_stream(
|
|
71
|
+
reasoning_agent: "Agent", # type: ignore # noqa: F821
|
|
72
|
+
messages: List[Message],
|
|
73
|
+
) -> Iterator[Tuple[Optional[str], Optional[Message]]]:
|
|
74
|
+
"""
|
|
75
|
+
Stream reasoning content from Ollama model.
|
|
76
|
+
|
|
77
|
+
For reasoning models on Ollama (qwq, deepseek-r1, etc.), we use the main content output as reasoning content.
|
|
78
|
+
|
|
79
|
+
Yields:
|
|
80
|
+
Tuple of (reasoning_content_delta, final_message)
|
|
81
|
+
- During streaming: (reasoning_content_delta, None)
|
|
82
|
+
- At the end: (None, final_message)
|
|
83
|
+
"""
|
|
84
|
+
from agno.run.agent import RunEvent
|
|
85
|
+
|
|
86
|
+
reasoning_content: str = ""
|
|
87
|
+
|
|
88
|
+
try:
|
|
89
|
+
for event in reasoning_agent.run(input=messages, stream=True, stream_intermediate_steps=True):
|
|
90
|
+
if hasattr(event, "event"):
|
|
91
|
+
if event.event == RunEvent.run_content:
|
|
92
|
+
# Check for reasoning_content attribute first (native reasoning)
|
|
93
|
+
if hasattr(event, "reasoning_content") and event.reasoning_content:
|
|
94
|
+
reasoning_content += event.reasoning_content
|
|
95
|
+
yield (event.reasoning_content, None)
|
|
96
|
+
# Use the main content as reasoning content
|
|
97
|
+
elif hasattr(event, "content") and event.content:
|
|
98
|
+
reasoning_content += event.content
|
|
99
|
+
yield (event.content, None)
|
|
100
|
+
elif event.event == RunEvent.run_completed:
|
|
101
|
+
pass
|
|
102
|
+
except Exception as e:
|
|
103
|
+
logger.warning(f"Reasoning error: {e}")
|
|
104
|
+
return
|
|
105
|
+
|
|
106
|
+
# Yield final message
|
|
107
|
+
if reasoning_content:
|
|
108
|
+
final_message = Message(
|
|
109
|
+
role="assistant",
|
|
110
|
+
content=f"<thinking>\n{reasoning_content}\n</thinking>",
|
|
111
|
+
reasoning_content=reasoning_content,
|
|
112
|
+
)
|
|
113
|
+
yield (None, final_message)
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
async def aget_ollama_reasoning_stream(
|
|
117
|
+
reasoning_agent: "Agent", # type: ignore # noqa: F821
|
|
118
|
+
messages: List[Message],
|
|
119
|
+
) -> AsyncIterator[Tuple[Optional[str], Optional[Message]]]:
|
|
120
|
+
"""
|
|
121
|
+
Stream reasoning content from Ollama model asynchronously.
|
|
122
|
+
|
|
123
|
+
For reasoning models on Ollama (qwq, deepseek-r1, etc.), we use the main content output as reasoning content.
|
|
124
|
+
|
|
125
|
+
Yields:
|
|
126
|
+
Tuple of (reasoning_content_delta, final_message)
|
|
127
|
+
- During streaming: (reasoning_content_delta, None)
|
|
128
|
+
- At the end: (None, final_message)
|
|
129
|
+
"""
|
|
130
|
+
from agno.run.agent import RunEvent
|
|
131
|
+
|
|
132
|
+
reasoning_content: str = ""
|
|
133
|
+
|
|
134
|
+
try:
|
|
135
|
+
async for event in reasoning_agent.arun(input=messages, stream=True, stream_intermediate_steps=True):
|
|
136
|
+
if hasattr(event, "event"):
|
|
137
|
+
if event.event == RunEvent.run_content:
|
|
138
|
+
# Check for reasoning_content attribute first (native reasoning)
|
|
139
|
+
if hasattr(event, "reasoning_content") and event.reasoning_content:
|
|
140
|
+
reasoning_content += event.reasoning_content
|
|
141
|
+
yield (event.reasoning_content, None)
|
|
142
|
+
# Use the main content as reasoning content
|
|
143
|
+
elif hasattr(event, "content") and event.content:
|
|
144
|
+
reasoning_content += event.content
|
|
145
|
+
yield (event.content, None)
|
|
146
|
+
elif event.event == RunEvent.run_completed:
|
|
147
|
+
pass
|
|
148
|
+
except Exception as e:
|
|
149
|
+
logger.warning(f"Reasoning error: {e}")
|
|
150
|
+
return
|
|
151
|
+
|
|
152
|
+
# Yield final message
|
|
153
|
+
if reasoning_content:
|
|
154
|
+
final_message = Message(
|
|
155
|
+
role="assistant",
|
|
156
|
+
content=f"<thinking>\n{reasoning_content}\n</thinking>",
|
|
157
|
+
reasoning_content=reasoning_content,
|
|
158
|
+
)
|
|
159
|
+
yield (None, final_message)
|
agno/reasoning/openai.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from typing import List, Optional
|
|
3
|
+
from typing import AsyncIterator, Iterator, List, Optional, Tuple
|
|
4
4
|
|
|
5
5
|
from agno.models.base import Model
|
|
6
6
|
from agno.models.message import Message
|
|
@@ -84,3 +84,115 @@ async def aget_openai_reasoning(reasoning_agent: "Agent", messages: List[Message
|
|
|
84
84
|
return Message(
|
|
85
85
|
role="assistant", content=f"<thinking>\n{reasoning_content}\n</thinking>", reasoning_content=reasoning_content
|
|
86
86
|
)
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def get_openai_reasoning_stream(
|
|
90
|
+
reasoning_agent: "Agent", # type: ignore # noqa: F821
|
|
91
|
+
messages: List[Message],
|
|
92
|
+
) -> Iterator[Tuple[Optional[str], Optional[Message]]]:
|
|
93
|
+
"""
|
|
94
|
+
Stream reasoning content from OpenAI model.
|
|
95
|
+
|
|
96
|
+
For OpenAI reasoning models, we use the main content output as reasoning content.
|
|
97
|
+
|
|
98
|
+
Yields:
|
|
99
|
+
Tuple of (reasoning_content_delta, final_message)
|
|
100
|
+
- During streaming: (reasoning_content_delta, None)
|
|
101
|
+
- At the end: (None, final_message)
|
|
102
|
+
"""
|
|
103
|
+
from agno.run.agent import RunEvent
|
|
104
|
+
|
|
105
|
+
# Update system message role to "system"
|
|
106
|
+
for message in messages:
|
|
107
|
+
if message.role == "developer":
|
|
108
|
+
message.role = "system"
|
|
109
|
+
|
|
110
|
+
reasoning_content: str = ""
|
|
111
|
+
|
|
112
|
+
try:
|
|
113
|
+
for event in reasoning_agent.run(input=messages, stream=True, stream_intermediate_steps=True):
|
|
114
|
+
if hasattr(event, "event"):
|
|
115
|
+
if event.event == RunEvent.run_content:
|
|
116
|
+
# Check for reasoning_content attribute first (native reasoning)
|
|
117
|
+
if hasattr(event, "reasoning_content") and event.reasoning_content:
|
|
118
|
+
reasoning_content += event.reasoning_content
|
|
119
|
+
yield (event.reasoning_content, None)
|
|
120
|
+
# Use the main content as reasoning content
|
|
121
|
+
elif hasattr(event, "content") and event.content:
|
|
122
|
+
reasoning_content += event.content
|
|
123
|
+
yield (event.content, None)
|
|
124
|
+
elif event.event == RunEvent.run_completed:
|
|
125
|
+
# Check for reasoning_content at completion (OpenAIResponses with reasoning_summary)
|
|
126
|
+
if hasattr(event, "reasoning_content") and event.reasoning_content:
|
|
127
|
+
# If we haven't accumulated any reasoning content yet, use this
|
|
128
|
+
if not reasoning_content:
|
|
129
|
+
reasoning_content = event.reasoning_content
|
|
130
|
+
yield (event.reasoning_content, None)
|
|
131
|
+
except Exception as e:
|
|
132
|
+
logger.warning(f"Reasoning error: {e}")
|
|
133
|
+
return
|
|
134
|
+
|
|
135
|
+
# Yield final message
|
|
136
|
+
if reasoning_content:
|
|
137
|
+
final_message = Message(
|
|
138
|
+
role="assistant",
|
|
139
|
+
content=f"<thinking>\n{reasoning_content}\n</thinking>",
|
|
140
|
+
reasoning_content=reasoning_content,
|
|
141
|
+
)
|
|
142
|
+
yield (None, final_message)
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
async def aget_openai_reasoning_stream(
|
|
146
|
+
reasoning_agent: "Agent", # type: ignore # noqa: F821
|
|
147
|
+
messages: List[Message],
|
|
148
|
+
) -> AsyncIterator[Tuple[Optional[str], Optional[Message]]]:
|
|
149
|
+
"""
|
|
150
|
+
Stream reasoning content from OpenAI model asynchronously.
|
|
151
|
+
|
|
152
|
+
For OpenAI reasoning models, we use the main content output as reasoning content.
|
|
153
|
+
|
|
154
|
+
Yields:
|
|
155
|
+
Tuple of (reasoning_content_delta, final_message)
|
|
156
|
+
- During streaming: (reasoning_content_delta, None)
|
|
157
|
+
- At the end: (None, final_message)
|
|
158
|
+
"""
|
|
159
|
+
from agno.run.agent import RunEvent
|
|
160
|
+
|
|
161
|
+
# Update system message role to "system"
|
|
162
|
+
for message in messages:
|
|
163
|
+
if message.role == "developer":
|
|
164
|
+
message.role = "system"
|
|
165
|
+
|
|
166
|
+
reasoning_content: str = ""
|
|
167
|
+
|
|
168
|
+
try:
|
|
169
|
+
async for event in reasoning_agent.arun(input=messages, stream=True, stream_intermediate_steps=True):
|
|
170
|
+
if hasattr(event, "event"):
|
|
171
|
+
if event.event == RunEvent.run_content:
|
|
172
|
+
# Check for reasoning_content attribute first (native reasoning)
|
|
173
|
+
if hasattr(event, "reasoning_content") and event.reasoning_content:
|
|
174
|
+
reasoning_content += event.reasoning_content
|
|
175
|
+
yield (event.reasoning_content, None)
|
|
176
|
+
# Use the main content as reasoning content
|
|
177
|
+
elif hasattr(event, "content") and event.content:
|
|
178
|
+
reasoning_content += event.content
|
|
179
|
+
yield (event.content, None)
|
|
180
|
+
elif event.event == RunEvent.run_completed:
|
|
181
|
+
# Check for reasoning_content at completion (OpenAIResponses with reasoning_summary)
|
|
182
|
+
if hasattr(event, "reasoning_content") and event.reasoning_content:
|
|
183
|
+
# If we haven't accumulated any reasoning content yet, use this
|
|
184
|
+
if not reasoning_content:
|
|
185
|
+
reasoning_content = event.reasoning_content
|
|
186
|
+
yield (event.reasoning_content, None)
|
|
187
|
+
except Exception as e:
|
|
188
|
+
logger.warning(f"Reasoning error: {e}")
|
|
189
|
+
return
|
|
190
|
+
|
|
191
|
+
# Yield final message
|
|
192
|
+
if reasoning_content:
|
|
193
|
+
final_message = Message(
|
|
194
|
+
role="assistant",
|
|
195
|
+
content=f"<thinking>\n{reasoning_content}\n</thinking>",
|
|
196
|
+
reasoning_content=reasoning_content,
|
|
197
|
+
)
|
|
198
|
+
yield (None, final_message)
|
agno/reasoning/vertexai.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from typing import List, Optional
|
|
3
|
+
from typing import AsyncIterator, Iterator, List, Optional, Tuple
|
|
4
4
|
|
|
5
5
|
from agno.models.base import Model
|
|
6
6
|
from agno.models.message import Message
|
|
@@ -74,3 +74,87 @@ async def aget_vertexai_reasoning(reasoning_agent: "Agent", messages: List[Messa
|
|
|
74
74
|
reasoning_content=reasoning_content,
|
|
75
75
|
redacted_reasoning_content=redacted_reasoning_content,
|
|
76
76
|
)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def get_vertexai_reasoning_stream(
|
|
80
|
+
reasoning_agent: "Agent", # type: ignore # noqa: F821
|
|
81
|
+
messages: List[Message],
|
|
82
|
+
) -> Iterator[Tuple[Optional[str], Optional[Message]]]:
|
|
83
|
+
"""
|
|
84
|
+
Stream reasoning content from VertexAI Claude model.
|
|
85
|
+
|
|
86
|
+
Yields:
|
|
87
|
+
Tuple of (reasoning_content_delta, final_message)
|
|
88
|
+
- During streaming: (reasoning_content_delta, None)
|
|
89
|
+
- At the end: (None, final_message)
|
|
90
|
+
"""
|
|
91
|
+
from agno.run.agent import RunEvent
|
|
92
|
+
|
|
93
|
+
reasoning_content: str = ""
|
|
94
|
+
redacted_reasoning_content: Optional[str] = None
|
|
95
|
+
|
|
96
|
+
try:
|
|
97
|
+
for event in reasoning_agent.run(input=messages, stream=True, stream_intermediate_steps=True):
|
|
98
|
+
if hasattr(event, "event"):
|
|
99
|
+
if event.event == RunEvent.run_content:
|
|
100
|
+
# Stream reasoning content as it arrives
|
|
101
|
+
if hasattr(event, "reasoning_content") and event.reasoning_content:
|
|
102
|
+
reasoning_content += event.reasoning_content
|
|
103
|
+
yield (event.reasoning_content, None)
|
|
104
|
+
elif event.event == RunEvent.run_completed:
|
|
105
|
+
pass
|
|
106
|
+
except Exception as e:
|
|
107
|
+
logger.warning(f"Reasoning error: {e}")
|
|
108
|
+
return
|
|
109
|
+
|
|
110
|
+
# Yield final message
|
|
111
|
+
if reasoning_content:
|
|
112
|
+
final_message = Message(
|
|
113
|
+
role="assistant",
|
|
114
|
+
content=f"<thinking>\n{reasoning_content}\n</thinking>",
|
|
115
|
+
reasoning_content=reasoning_content,
|
|
116
|
+
redacted_reasoning_content=redacted_reasoning_content,
|
|
117
|
+
)
|
|
118
|
+
yield (None, final_message)
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
async def aget_vertexai_reasoning_stream(
|
|
122
|
+
reasoning_agent: "Agent", # type: ignore # noqa: F821
|
|
123
|
+
messages: List[Message],
|
|
124
|
+
) -> AsyncIterator[Tuple[Optional[str], Optional[Message]]]:
|
|
125
|
+
"""
|
|
126
|
+
Stream reasoning content from VertexAI Claude model asynchronously.
|
|
127
|
+
|
|
128
|
+
Yields:
|
|
129
|
+
Tuple of (reasoning_content_delta, final_message)
|
|
130
|
+
- During streaming: (reasoning_content_delta, None)
|
|
131
|
+
- At the end: (None, final_message)
|
|
132
|
+
"""
|
|
133
|
+
from agno.run.agent import RunEvent
|
|
134
|
+
|
|
135
|
+
reasoning_content: str = ""
|
|
136
|
+
redacted_reasoning_content: Optional[str] = None
|
|
137
|
+
|
|
138
|
+
try:
|
|
139
|
+
async for event in reasoning_agent.arun(input=messages, stream=True, stream_intermediate_steps=True):
|
|
140
|
+
if hasattr(event, "event"):
|
|
141
|
+
if event.event == RunEvent.run_content:
|
|
142
|
+
# Stream reasoning content as it arrives
|
|
143
|
+
if hasattr(event, "reasoning_content") and event.reasoning_content:
|
|
144
|
+
reasoning_content += event.reasoning_content
|
|
145
|
+
yield (event.reasoning_content, None)
|
|
146
|
+
elif event.event == RunEvent.run_completed:
|
|
147
|
+
pass
|
|
148
|
+
except Exception as e:
|
|
149
|
+
logger.warning(f"Reasoning error: {e}")
|
|
150
|
+
return
|
|
151
|
+
|
|
152
|
+
# Yield final message
|
|
153
|
+
if reasoning_content:
|
|
154
|
+
final_message = Message(
|
|
155
|
+
role="assistant",
|
|
156
|
+
content=f"<thinking>\n{reasoning_content}\n</thinking>",
|
|
157
|
+
reasoning_content=reasoning_content,
|
|
158
|
+
redacted_reasoning_content=redacted_reasoning_content,
|
|
159
|
+
)
|
|
160
|
+
yield (None, final_message)
|
agno/run/agent.py
CHANGED
|
@@ -156,6 +156,7 @@ class RunEvent(str, Enum):
|
|
|
156
156
|
|
|
157
157
|
reasoning_started = "ReasoningStarted"
|
|
158
158
|
reasoning_step = "ReasoningStep"
|
|
159
|
+
reasoning_content_delta = "ReasoningContentDelta"
|
|
159
160
|
reasoning_completed = "ReasoningCompleted"
|
|
160
161
|
|
|
161
162
|
memory_update_started = "MemoryUpdateStarted"
|
|
@@ -373,6 +374,14 @@ class ReasoningStepEvent(BaseAgentRunEvent):
|
|
|
373
374
|
reasoning_content: str = ""
|
|
374
375
|
|
|
375
376
|
|
|
377
|
+
@dataclass
|
|
378
|
+
class ReasoningContentDeltaEvent(BaseAgentRunEvent):
|
|
379
|
+
"""Event for streaming reasoning content chunks as they arrive."""
|
|
380
|
+
|
|
381
|
+
event: str = RunEvent.reasoning_content_delta.value
|
|
382
|
+
reasoning_content: str = "" # The delta/chunk of reasoning content
|
|
383
|
+
|
|
384
|
+
|
|
376
385
|
@dataclass
|
|
377
386
|
class ReasoningCompletedEvent(BaseAgentRunEvent):
|
|
378
387
|
event: str = RunEvent.reasoning_completed.value
|
|
@@ -442,6 +451,7 @@ RunOutputEvent = Union[
|
|
|
442
451
|
PostHookCompletedEvent,
|
|
443
452
|
ReasoningStartedEvent,
|
|
444
453
|
ReasoningStepEvent,
|
|
454
|
+
ReasoningContentDeltaEvent,
|
|
445
455
|
ReasoningCompletedEvent,
|
|
446
456
|
MemoryUpdateStartedEvent,
|
|
447
457
|
MemoryUpdateCompletedEvent,
|
|
@@ -474,6 +484,7 @@ RUN_EVENT_TYPE_REGISTRY = {
|
|
|
474
484
|
RunEvent.post_hook_completed.value: PostHookCompletedEvent,
|
|
475
485
|
RunEvent.reasoning_started.value: ReasoningStartedEvent,
|
|
476
486
|
RunEvent.reasoning_step.value: ReasoningStepEvent,
|
|
487
|
+
RunEvent.reasoning_content_delta.value: ReasoningContentDeltaEvent,
|
|
477
488
|
RunEvent.reasoning_completed.value: ReasoningCompletedEvent,
|
|
478
489
|
RunEvent.memory_update_started.value: MemoryUpdateStartedEvent,
|
|
479
490
|
RunEvent.memory_update_completed.value: MemoryUpdateCompletedEvent,
|
agno/run/base.py
CHANGED
|
@@ -22,7 +22,7 @@ class RunContext:
|
|
|
22
22
|
knowledge_filters: Optional[Union[Dict[str, Any], List[FilterExpr]]] = None
|
|
23
23
|
metadata: Optional[Dict[str, Any]] = None
|
|
24
24
|
session_state: Optional[Dict[str, Any]] = None
|
|
25
|
-
output_schema: Optional[Type[BaseModel]] = None
|
|
25
|
+
output_schema: Optional[Union[Type[BaseModel], Dict[str, Any]]] = None
|
|
26
26
|
|
|
27
27
|
|
|
28
28
|
@dataclass
|
agno/run/team.py
CHANGED
|
@@ -149,6 +149,7 @@ class TeamRunEvent(str, Enum):
|
|
|
149
149
|
|
|
150
150
|
reasoning_started = "TeamReasoningStarted"
|
|
151
151
|
reasoning_step = "TeamReasoningStep"
|
|
152
|
+
reasoning_content_delta = "TeamReasoningContentDelta"
|
|
152
153
|
reasoning_completed = "TeamReasoningCompleted"
|
|
153
154
|
|
|
154
155
|
memory_update_started = "TeamMemoryUpdateStarted"
|
|
@@ -346,6 +347,14 @@ class ReasoningStepEvent(BaseTeamRunEvent):
|
|
|
346
347
|
reasoning_content: str = ""
|
|
347
348
|
|
|
348
349
|
|
|
350
|
+
@dataclass
|
|
351
|
+
class ReasoningContentDeltaEvent(BaseTeamRunEvent):
|
|
352
|
+
"""Event for streaming reasoning content chunks as they arrive."""
|
|
353
|
+
|
|
354
|
+
event: str = TeamRunEvent.reasoning_content_delta.value
|
|
355
|
+
reasoning_content: str = "" # The delta/chunk of reasoning content
|
|
356
|
+
|
|
357
|
+
|
|
349
358
|
@dataclass
|
|
350
359
|
class ReasoningCompletedEvent(BaseTeamRunEvent):
|
|
351
360
|
event: str = TeamRunEvent.reasoning_completed.value
|
|
@@ -411,6 +420,7 @@ TeamRunOutputEvent = Union[
|
|
|
411
420
|
PreHookCompletedEvent,
|
|
412
421
|
ReasoningStartedEvent,
|
|
413
422
|
ReasoningStepEvent,
|
|
423
|
+
ReasoningContentDeltaEvent,
|
|
414
424
|
ReasoningCompletedEvent,
|
|
415
425
|
MemoryUpdateStartedEvent,
|
|
416
426
|
MemoryUpdateCompletedEvent,
|
|
@@ -440,6 +450,7 @@ TEAM_RUN_EVENT_TYPE_REGISTRY = {
|
|
|
440
450
|
TeamRunEvent.post_hook_completed.value: PostHookCompletedEvent,
|
|
441
451
|
TeamRunEvent.reasoning_started.value: ReasoningStartedEvent,
|
|
442
452
|
TeamRunEvent.reasoning_step.value: ReasoningStepEvent,
|
|
453
|
+
TeamRunEvent.reasoning_content_delta.value: ReasoningContentDeltaEvent,
|
|
443
454
|
TeamRunEvent.reasoning_completed.value: ReasoningCompletedEvent,
|
|
444
455
|
TeamRunEvent.memory_update_started.value: MemoryUpdateStartedEvent,
|
|
445
456
|
TeamRunEvent.memory_update_completed.value: MemoryUpdateCompletedEvent,
|
agno/session/team.py
CHANGED
|
@@ -91,10 +91,7 @@ class TeamSession:
|
|
|
91
91
|
|
|
92
92
|
def upsert_run(self, run_response: Union[TeamRunOutput, RunOutput]):
|
|
93
93
|
"""Adds a RunOutput, together with some calculated data, to the runs list."""
|
|
94
|
-
|
|
95
94
|
messages = run_response.messages
|
|
96
|
-
if messages is None:
|
|
97
|
-
return
|
|
98
95
|
|
|
99
96
|
# Make message duration None
|
|
100
97
|
for m in messages or []:
|