|
15 | 15 |
|
16 | 16 | from langchain_core.tracers import BaseTracer, LangChainTracer |
17 | 17 | from langchain_core.tracers.schemas import Run |
| 18 | +from microsoft_agents_a365.observability.core.constants import ( |
| 19 | + GEN_AI_AGENT_NAME_KEY, |
| 20 | + INVOKE_AGENT_OPERATION_NAME, |
| 21 | +) |
18 | 22 | from microsoft_agents_a365.observability.core.inference_operation_type import InferenceOperationType |
19 | 23 | from microsoft_agents_a365.observability.core.utils import ( |
20 | 24 | DictWithLock, |
|
37 | 41 | function_calls, |
38 | 42 | input_messages, |
39 | 43 | invocation_parameters, |
| 44 | + invoke_agent_input_message, |
| 45 | + invoke_agent_output_message, |
40 | 46 | llm_provider, |
41 | 47 | metadata, |
42 | 48 | model_name, |
43 | 49 | output_messages, |
44 | 50 | prompts, |
| 51 | + set_execution_type, |
45 | 52 | token_counts, |
46 | 53 | tools, |
47 | 54 | ) |
@@ -111,8 +118,17 @@ def _start_trace(self, run: Run) -> None: |
111 | 118 | # We can't use real time because the handler may be |
112 | 119 | # called in a background thread. |
113 | 120 | start_time_utc_nano = as_utc_nano(run.start_time) |
| 121 | + |
| 122 | + # Determine span name based on run type |
| 123 | + if run.run_type == "chain" and run.name == "LangGraph": |
| 124 | + span_name = f"invoke_agent {run.name}" |
| 125 | + elif run.run_type.lower() == "tool": |
| 126 | + span_name = f"execute_tool {run.name}" |
| 127 | + else: |
| 128 | + span_name = run.name |
| 129 | + |
114 | 130 | span = self._tracer.start_span( |
115 | | - name=run.name, |
| 131 | + name=span_name, |
116 | 132 | context=parent_context, |
117 | 133 | start_time=start_time_utc_nano, |
118 | 134 | ) |
@@ -197,27 +213,52 @@ def _update_span(span: Span, run: Run) -> None: |
197 | 213 | else: |
198 | 214 | span.set_status(trace_api.Status(trace_api.StatusCode.ERROR, run.error)) |
199 | 215 |
|
| 216 | + span.set_attributes(dict(get_attributes_from_context())) |
| 217 | + |
200 | 218 | if run.run_type == "llm" and run.outputs.get("llm_output").get("id").startswith("chat"): |
201 | 219 | span.update_name(f"{InferenceOperationType.CHAT.value.lower()} {span.name}") |
202 | | - elif run.run_type.lower() == "tool": |
203 | | - span.update_name(f"execute_tool {span.name}") |
204 | | - span.set_attributes(dict(get_attributes_from_context())) |
205 | | - span.set_attributes( |
206 | | - dict( |
207 | | - flatten( |
208 | | - chain( |
209 | | - add_operation_type(run), |
210 | | - prompts(run.inputs), |
211 | | - input_messages(run.inputs), |
212 | | - output_messages(run.outputs), |
213 | | - invocation_parameters(run), |
214 | | - llm_provider(run.extra), |
215 | | - model_name(run.outputs, run.extra), |
216 | | - token_counts(run.outputs), |
217 | | - function_calls(run.outputs), |
218 | | - tools(run), |
219 | | - metadata(run), |
| 220 | + is_invoke_agent = span.name.startswith(INVOKE_AGENT_OPERATION_NAME) |
| 221 | + |
| 222 | + # If this is an invoke_agent span, update span name with agent name |
| 223 | + if is_invoke_agent: |
| 224 | + agent_name = None |
| 225 | + if hasattr(span, "_attributes") and span._attributes: |
| 226 | + agent_name = span._attributes.get(GEN_AI_AGENT_NAME_KEY) |
| 227 | + if agent_name: |
| 228 | + span.update_name(f"{INVOKE_AGENT_OPERATION_NAME} {agent_name}") |
| 229 | + |
| 230 | + # For invoke_agent spans, add input/output messages |
| 231 | + if is_invoke_agent: |
| 232 | + span.set_attributes( |
| 233 | + dict( |
| 234 | + flatten( |
| 235 | + chain( |
| 236 | + set_execution_type(), |
| 237 | + add_operation_type(run), |
| 238 | + invoke_agent_input_message(run.inputs), |
| 239 | + invoke_agent_output_message(run.outputs), |
| 240 | + metadata(run), |
| 241 | + ) |
| 242 | + ) |
| 243 | + ) |
| 244 | + ) |
| 245 | + else: |
| 246 | + span.set_attributes( |
| 247 | + dict( |
| 248 | + flatten( |
| 249 | + chain( |
| 250 | + add_operation_type(run), |
| 251 | + prompts(run.inputs), |
| 252 | + input_messages(run.inputs), |
| 253 | + output_messages(run.outputs), |
| 254 | + invocation_parameters(run), |
| 255 | + llm_provider(run.extra), |
| 256 | + model_name(run.outputs, run.extra), |
| 257 | + token_counts(run.outputs), |
| 258 | + function_calls(run.outputs), |
| 259 | + tools(run), |
| 260 | + metadata(run), |
| 261 | + ) |
220 | 262 | ) |
221 | 263 | ) |
222 | 264 | ) |
223 | | - ) |
|
0 commit comments