1
1
from abc import ABC , abstractmethod
2
2
from typing import Any , AsyncGenerator , List , Mapping , Sequence
3
3
4
- from autogen_core import CancellationToken , ComponentBase
4
+ from autogen_core import CancellationToken , ComponentBase , trace_create_agent_span , trace_invoke_agent_span
5
5
from pydantic import BaseModel
6
6
7
7
from ..base import ChatAgent , Response , TaskResult
@@ -39,10 +39,15 @@ class BaseChatAgent(ChatAgent, ABC, ComponentBase[BaseModel]):
39
39
component_type = "agent"
40
40
41
41
def __init__ (self , name : str , description : str ) -> None :
42
- self ._name = name
43
- if self ._name .isidentifier () is False :
44
- raise ValueError ("The agent name must be a valid Python identifier." )
45
- self ._description = description
42
+ """Initialize the agent with a name and description."""
43
+ with trace_create_agent_span (
44
+ agent_name = name ,
45
+ agent_description = description ,
46
+ ):
47
+ self ._name = name
48
+ if self ._name .isidentifier () is False :
49
+ raise ValueError ("The agent name must be a valid Python identifier." )
50
+ self ._description = description
46
51
47
52
@property
48
53
def name (self ) -> str :
@@ -110,34 +115,38 @@ async def run(
110
115
cancellation_token : CancellationToken | None = None ,
111
116
) -> TaskResult :
112
117
"""Run the agent with the given task and return the result."""
113
- if cancellation_token is None :
114
- cancellation_token = CancellationToken ()
115
- input_messages : List [BaseChatMessage ] = []
116
- output_messages : List [BaseAgentEvent | BaseChatMessage ] = []
117
- if task is None :
118
- pass
119
- elif isinstance (task , str ):
120
- text_msg = TextMessage (content = task , source = "user" )
121
- input_messages .append (text_msg )
122
- output_messages .append (text_msg )
123
- elif isinstance (task , BaseChatMessage ):
124
- input_messages .append (task )
125
- output_messages .append (task )
126
- else :
127
- if not task :
128
- raise ValueError ("Task list cannot be empty." )
129
- # Task is a sequence of messages.
130
- for msg in task :
131
- if isinstance (msg , BaseChatMessage ):
132
- input_messages .append (msg )
133
- output_messages .append (msg )
134
- else :
135
- raise ValueError (f"Invalid message type in sequence: { type (msg )} " )
136
- response = await self .on_messages (input_messages , cancellation_token )
137
- if response .inner_messages is not None :
138
- output_messages += response .inner_messages
139
- output_messages .append (response .chat_message )
140
- return TaskResult (messages = output_messages )
118
+ with trace_invoke_agent_span (
119
+ agent_name = self .name ,
120
+ agent_description = self .description ,
121
+ ):
122
+ if cancellation_token is None :
123
+ cancellation_token = CancellationToken ()
124
+ input_messages : List [BaseChatMessage ] = []
125
+ output_messages : List [BaseAgentEvent | BaseChatMessage ] = []
126
+ if task is None :
127
+ pass
128
+ elif isinstance (task , str ):
129
+ text_msg = TextMessage (content = task , source = "user" )
130
+ input_messages .append (text_msg )
131
+ output_messages .append (text_msg )
132
+ elif isinstance (task , BaseChatMessage ):
133
+ input_messages .append (task )
134
+ output_messages .append (task )
135
+ else :
136
+ if not task :
137
+ raise ValueError ("Task list cannot be empty." )
138
+ # Task is a sequence of messages.
139
+ for msg in task :
140
+ if isinstance (msg , BaseChatMessage ):
141
+ input_messages .append (msg )
142
+ output_messages .append (msg )
143
+ else :
144
+ raise ValueError (f"Invalid message type in sequence: { type (msg )} " )
145
+ response = await self .on_messages (input_messages , cancellation_token )
146
+ if response .inner_messages is not None :
147
+ output_messages += response .inner_messages
148
+ output_messages .append (response .chat_message )
149
+ return TaskResult (messages = output_messages )
141
150
142
151
async def run_stream (
143
152
self ,
@@ -147,42 +156,46 @@ async def run_stream(
147
156
) -> AsyncGenerator [BaseAgentEvent | BaseChatMessage | TaskResult , None ]:
148
157
"""Run the agent with the given task and return a stream of messages
149
158
and the final task result as the last item in the stream."""
150
- if cancellation_token is None :
151
- cancellation_token = CancellationToken ()
152
- input_messages : List [BaseChatMessage ] = []
153
- output_messages : List [BaseAgentEvent | BaseChatMessage ] = []
154
- if task is None :
155
- pass
156
- elif isinstance (task , str ):
157
- text_msg = TextMessage (content = task , source = "user" )
158
- input_messages .append (text_msg )
159
- output_messages .append (text_msg )
160
- yield text_msg
161
- elif isinstance (task , BaseChatMessage ):
162
- input_messages .append (task )
163
- output_messages .append (task )
164
- yield task
165
- else :
166
- if not task :
167
- raise ValueError ("Task list cannot be empty." )
168
- for msg in task :
169
- if isinstance (msg , BaseChatMessage ):
170
- input_messages .append (msg )
171
- output_messages .append (msg )
172
- yield msg
173
- else :
174
- raise ValueError (f"Invalid message type in sequence: { type (msg )} " )
175
- async for message in self .on_messages_stream (input_messages , cancellation_token ):
176
- if isinstance (message , Response ):
177
- yield message .chat_message
178
- output_messages .append (message .chat_message )
179
- yield TaskResult (messages = output_messages )
159
+ with trace_invoke_agent_span (
160
+ agent_name = self .name ,
161
+ agent_description = self .description ,
162
+ ):
163
+ if cancellation_token is None :
164
+ cancellation_token = CancellationToken ()
165
+ input_messages : List [BaseChatMessage ] = []
166
+ output_messages : List [BaseAgentEvent | BaseChatMessage ] = []
167
+ if task is None :
168
+ pass
169
+ elif isinstance (task , str ):
170
+ text_msg = TextMessage (content = task , source = "user" )
171
+ input_messages .append (text_msg )
172
+ output_messages .append (text_msg )
173
+ yield text_msg
174
+ elif isinstance (task , BaseChatMessage ):
175
+ input_messages .append (task )
176
+ output_messages .append (task )
177
+ yield task
180
178
else :
181
- yield message
182
- if isinstance (message , ModelClientStreamingChunkEvent ):
183
- # Skip the model client streaming chunk events.
184
- continue
185
- output_messages .append (message )
179
+ if not task :
180
+ raise ValueError ("Task list cannot be empty." )
181
+ for msg in task :
182
+ if isinstance (msg , BaseChatMessage ):
183
+ input_messages .append (msg )
184
+ output_messages .append (msg )
185
+ yield msg
186
+ else :
187
+ raise ValueError (f"Invalid message type in sequence: { type (msg )} " )
188
+ async for message in self .on_messages_stream (input_messages , cancellation_token ):
189
+ if isinstance (message , Response ):
190
+ yield message .chat_message
191
+ output_messages .append (message .chat_message )
192
+ yield TaskResult (messages = output_messages )
193
+ else :
194
+ yield message
195
+ if isinstance (message , ModelClientStreamingChunkEvent ):
196
+ # Skip the model client streaming chunk events.
197
+ continue
198
+ output_messages .append (message )
186
199
187
200
@abstractmethod
188
201
async def on_reset (self , cancellation_token : CancellationToken ) -> None :
0 commit comments