monocle-apptrace 0.5.0__py3-none-any.whl → 0.5.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.
Potentially problematic release.
This version of monocle-apptrace might be problematic. Click here for more details.
- monocle_apptrace/instrumentation/common/__init__.py +7 -5
- monocle_apptrace/instrumentation/common/constants.py +95 -12
- monocle_apptrace/instrumentation/common/instrumentor.py +1 -6
- monocle_apptrace/instrumentation/common/method_wrappers.py +1 -112
- monocle_apptrace/instrumentation/common/scope_wrapper.py +126 -0
- monocle_apptrace/instrumentation/common/span_handler.py +13 -0
- monocle_apptrace/instrumentation/common/utils.py +2 -2
- monocle_apptrace/instrumentation/common/wrapper.py +113 -51
- monocle_apptrace/instrumentation/metamodel/a2a/entities/inference.py +3 -1
- monocle_apptrace/instrumentation/metamodel/adk/_helper.py +24 -0
- monocle_apptrace/instrumentation/metamodel/adk/entities/agent.py +62 -1
- monocle_apptrace/instrumentation/metamodel/adk/entities/tool.py +3 -1
- monocle_apptrace/instrumentation/metamodel/adk/methods.py +9 -2
- monocle_apptrace/instrumentation/metamodel/agents/_helper.py +5 -0
- monocle_apptrace/instrumentation/metamodel/agents/agents_processor.py +30 -8
- monocle_apptrace/instrumentation/metamodel/agents/entities/inference.py +10 -5
- monocle_apptrace/instrumentation/metamodel/agents/methods.py +3 -4
- monocle_apptrace/instrumentation/metamodel/aiohttp/entities/http.py +2 -1
- monocle_apptrace/instrumentation/metamodel/anthropic/_helper.py +3 -3
- monocle_apptrace/instrumentation/metamodel/anthropic/entities/inference.py +2 -1
- monocle_apptrace/instrumentation/metamodel/azfunc/entities/http.py +2 -1
- monocle_apptrace/instrumentation/metamodel/azureaiinference/entities/inference.py +2 -1
- monocle_apptrace/instrumentation/metamodel/botocore/entities/inference.py +2 -1
- monocle_apptrace/instrumentation/metamodel/fastapi/entities/http.py +2 -1
- monocle_apptrace/instrumentation/metamodel/finish_types.py +2 -0
- monocle_apptrace/instrumentation/metamodel/flask/entities/http.py +2 -1
- monocle_apptrace/instrumentation/metamodel/gemini/entities/inference.py +2 -1
- monocle_apptrace/instrumentation/metamodel/gemini/entities/retrieval.py +2 -1
- monocle_apptrace/instrumentation/metamodel/haystack/entities/inference.py +2 -1
- monocle_apptrace/instrumentation/metamodel/haystack/entities/retrieval.py +2 -1
- monocle_apptrace/instrumentation/metamodel/lambdafunc/entities/http.py +2 -1
- monocle_apptrace/instrumentation/metamodel/langchain/_helper.py +2 -2
- monocle_apptrace/instrumentation/metamodel/langchain/entities/inference.py +2 -1
- monocle_apptrace/instrumentation/metamodel/langchain/entities/retrieval.py +2 -1
- monocle_apptrace/instrumentation/metamodel/langgraph/_helper.py +6 -0
- monocle_apptrace/instrumentation/metamodel/langgraph/entities/inference.py +10 -5
- monocle_apptrace/instrumentation/metamodel/langgraph/langgraph_processor.py +8 -4
- monocle_apptrace/instrumentation/metamodel/langgraph/methods.py +2 -0
- monocle_apptrace/instrumentation/metamodel/litellm/entities/inference.py +2 -1
- monocle_apptrace/instrumentation/metamodel/llamaindex/entities/agent.py +9 -4
- monocle_apptrace/instrumentation/metamodel/llamaindex/entities/inference.py +2 -1
- monocle_apptrace/instrumentation/metamodel/llamaindex/entities/retrieval.py +2 -1
- monocle_apptrace/instrumentation/metamodel/mcp/_helper.py +2 -1
- monocle_apptrace/instrumentation/metamodel/mcp/entities/inference.py +3 -1
- monocle_apptrace/instrumentation/metamodel/mcp/methods.py +1 -1
- monocle_apptrace/instrumentation/metamodel/openai/_helper.py +2 -2
- monocle_apptrace/instrumentation/metamodel/openai/entities/inference.py +2 -1
- monocle_apptrace/instrumentation/metamodel/requests/entities/http.py +2 -1
- monocle_apptrace/instrumentation/metamodel/teamsai/entities/inference/teamsai_output_processor.py +2 -1
- {monocle_apptrace-0.5.0.dist-info → monocle_apptrace-0.5.1.dist-info}/METADATA +1 -1
- {monocle_apptrace-0.5.0.dist-info → monocle_apptrace-0.5.1.dist-info}/RECORD +54 -53
- {monocle_apptrace-0.5.0.dist-info → monocle_apptrace-0.5.1.dist-info}/WHEEL +0 -0
- {monocle_apptrace-0.5.0.dist-info → monocle_apptrace-0.5.1.dist-info}/licenses/LICENSE +0 -0
- {monocle_apptrace-0.5.0.dist-info → monocle_apptrace-0.5.1.dist-info}/licenses/NOTICE +0 -0
|
@@ -10,6 +10,7 @@ from opentelemetry.context import set_value, attach, detach, get_value
|
|
|
10
10
|
from opentelemetry.context import create_key, get_value, set_value
|
|
11
11
|
from opentelemetry.context.context import Context
|
|
12
12
|
from opentelemetry.trace.span import INVALID_SPAN, Span
|
|
13
|
+
from opentelemetry.trace.status import StatusCode
|
|
13
14
|
|
|
14
15
|
from monocle_apptrace.instrumentation.common.span_handler import SpanHandler
|
|
15
16
|
from monocle_apptrace.instrumentation.common.utils import (
|
|
@@ -20,7 +21,9 @@ from monocle_apptrace.instrumentation.common.utils import (
|
|
|
20
21
|
get_current_monocle_span,
|
|
21
22
|
set_monocle_span_in_context
|
|
22
23
|
)
|
|
23
|
-
from monocle_apptrace.instrumentation.common.constants import WORKFLOW_TYPE_KEY, ADD_NEW_WORKFLOW
|
|
24
|
+
from monocle_apptrace.instrumentation.common.constants import WORKFLOW_TYPE_KEY, ADD_NEW_WORKFLOW, AGENTIC_SPANS
|
|
25
|
+
from monocle_apptrace.instrumentation.common.scope_wrapper import monocle_trace_scope
|
|
26
|
+
|
|
24
27
|
logger = logging.getLogger(__name__)
|
|
25
28
|
ISOLATE_MONOCLE_SPANS = os.getenv("MONOCLE_ISOLATE_SPANS", "true").lower() == "true"
|
|
26
29
|
|
|
@@ -79,26 +82,36 @@ def monocle_wrapper_span_processor(tracer: Tracer, handler: SpanHandler, to_wrap
|
|
|
79
82
|
if SpanHandler.is_root_span(span) or add_workflow_span:
|
|
80
83
|
# Recursive call for the actual span
|
|
81
84
|
return_value, span_status = monocle_wrapper_span_processor(tracer, handler, to_wrap, wrapped, instance, source_path, False, args, kwargs)
|
|
82
|
-
span.set_status(
|
|
85
|
+
span.set_status(StatusCode.OK)
|
|
83
86
|
if not auto_close_span:
|
|
84
87
|
span.end()
|
|
85
88
|
else:
|
|
86
89
|
ex:Exception = None
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
post_process_span(handler, to_wrap, wrapped, instance, args, kwargs, ret_val, span, parent_span ,ex)
|
|
96
|
-
if not auto_close_span:
|
|
97
|
-
span.end()
|
|
98
|
-
if ex is None and not auto_close_span and to_wrap.get("output_processor") and to_wrap.get("output_processor").get("response_processor"):
|
|
99
|
-
to_wrap.get("output_processor").get("response_processor")(to_wrap, return_value, post_process_span_internal)
|
|
100
|
-
else:
|
|
90
|
+
to_wrap = get_wrapper_with_next_processor(to_wrap, handler, instance, args, kwargs)
|
|
91
|
+
if has_more_processors(to_wrap):
|
|
92
|
+
try:
|
|
93
|
+
return_value, span_status = monocle_wrapper_span_processor(tracer, handler, to_wrap, wrapped, instance, source_path, False, args, kwargs)
|
|
94
|
+
except Exception as e:
|
|
95
|
+
ex = e
|
|
96
|
+
raise
|
|
97
|
+
finally:
|
|
101
98
|
post_process_span_internal(return_value)
|
|
99
|
+
else:
|
|
100
|
+
try:
|
|
101
|
+
with SpanHandler.workflow_type(to_wrap, span):
|
|
102
|
+
return_value = wrapped(*args, **kwargs)
|
|
103
|
+
except Exception as e:
|
|
104
|
+
ex = e
|
|
105
|
+
raise
|
|
106
|
+
finally:
|
|
107
|
+
def post_process_span_internal(ret_val):
|
|
108
|
+
post_process_span(handler, to_wrap, wrapped, instance, args, kwargs, ret_val, span, parent_span ,ex)
|
|
109
|
+
if not auto_close_span:
|
|
110
|
+
span.end()
|
|
111
|
+
if ex is None and not auto_close_span and to_wrap.get("output_processor") and to_wrap.get("output_processor").get("response_processor"):
|
|
112
|
+
to_wrap.get("output_processor").get("response_processor")(to_wrap, return_value, post_process_span_internal)
|
|
113
|
+
else:
|
|
114
|
+
post_process_span_internal(return_value)
|
|
102
115
|
span_status = span.status
|
|
103
116
|
return return_value, span_status
|
|
104
117
|
|
|
@@ -117,7 +130,8 @@ def monocle_wrapper(tracer: Tracer, handler: SpanHandler, to_wrap, wrapped, inst
|
|
|
117
130
|
add_workflow_span = get_value(ADD_NEW_WORKFLOW) == True
|
|
118
131
|
token = attach(set_value(ADD_NEW_WORKFLOW, False))
|
|
119
132
|
try:
|
|
120
|
-
|
|
133
|
+
with monocle_trace_scope(get_builtin_scope_names(to_wrap)):
|
|
134
|
+
return_value, span_status = monocle_wrapper_span_processor(tracer, handler, to_wrap, wrapped, instance, source_path, add_workflow_span, args, kwargs)
|
|
121
135
|
finally:
|
|
122
136
|
detach(token)
|
|
123
137
|
return return_value
|
|
@@ -141,26 +155,36 @@ async def amonocle_wrapper_span_processor(tracer: Tracer, handler: SpanHandler,
|
|
|
141
155
|
if SpanHandler.is_root_span(span) or add_workflow_span:
|
|
142
156
|
# Recursive call for the actual span
|
|
143
157
|
return_value, span_status = await amonocle_wrapper_span_processor(tracer, handler, to_wrap, wrapped, instance, source_path, False, args, kwargs)
|
|
144
|
-
span.set_status(
|
|
158
|
+
span.set_status(StatusCode.OK)
|
|
145
159
|
if not auto_close_span:
|
|
146
160
|
span.end()
|
|
147
161
|
else:
|
|
148
162
|
ex:Exception = None
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
post_process_span(handler, to_wrap, wrapped, instance, args, kwargs, ret_val, span, parent_span, ex)
|
|
158
|
-
if not auto_close_span:
|
|
159
|
-
span.end()
|
|
160
|
-
if ex is None and not auto_close_span and to_wrap.get("output_processor") and to_wrap.get("output_processor").get("response_processor"):
|
|
161
|
-
to_wrap.get("output_processor").get("response_processor")(to_wrap, return_value, post_process_span_internal)
|
|
162
|
-
else:
|
|
163
|
+
to_wrap = get_wrapper_with_next_processor(to_wrap, handler, instance, args, kwargs)
|
|
164
|
+
if has_more_processors(to_wrap):
|
|
165
|
+
try:
|
|
166
|
+
return_value, span_status = await amonocle_wrapper_span_processor(tracer, handler, to_wrap, wrapped, instance, source_path, False, args, kwargs)
|
|
167
|
+
except Exception as e:
|
|
168
|
+
ex = e
|
|
169
|
+
raise
|
|
170
|
+
finally:
|
|
163
171
|
post_process_span_internal(return_value)
|
|
172
|
+
else:
|
|
173
|
+
try:
|
|
174
|
+
with SpanHandler.workflow_type(to_wrap, span):
|
|
175
|
+
return_value = await wrapped(*args, **kwargs)
|
|
176
|
+
except Exception as e:
|
|
177
|
+
ex = e
|
|
178
|
+
raise
|
|
179
|
+
finally:
|
|
180
|
+
def post_process_span_internal(ret_val):
|
|
181
|
+
post_process_span(handler, to_wrap, wrapped, instance, args, kwargs, ret_val, span, parent_span, ex)
|
|
182
|
+
if not auto_close_span:
|
|
183
|
+
span.end()
|
|
184
|
+
if ex is None and not auto_close_span and to_wrap.get("output_processor") and to_wrap.get("output_processor").get("response_processor"):
|
|
185
|
+
to_wrap.get("output_processor").get("response_processor")(to_wrap, return_value, post_process_span_internal)
|
|
186
|
+
else:
|
|
187
|
+
post_process_span_internal(return_value)
|
|
164
188
|
span_status = span.status
|
|
165
189
|
return return_value, span_status
|
|
166
190
|
|
|
@@ -179,28 +203,40 @@ async def amonocle_iter_wrapper_span_processor(tracer: Tracer, handler: SpanHand
|
|
|
179
203
|
# Recursive call for the actual span
|
|
180
204
|
async for item in amonocle_iter_wrapper_span_processor(tracer, handler, to_wrap, wrapped, instance, source_path, False, args, kwargs):
|
|
181
205
|
yield item
|
|
182
|
-
|
|
206
|
+
span.set_status(StatusCode.OK)
|
|
183
207
|
if not auto_close_span:
|
|
184
208
|
span.end()
|
|
185
209
|
else:
|
|
186
210
|
ex:Exception = None
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
211
|
+
to_wrap = get_wrapper_with_next_processor(to_wrap, handler, instance, args, kwargs)
|
|
212
|
+
if has_more_processors(to_wrap):
|
|
213
|
+
try:
|
|
214
|
+
async for item in amonocle_iter_wrapper_span_processor(tracer, handler, to_wrap, wrapped, instance, source_path, False, args, kwargs):
|
|
190
215
|
last_item = item
|
|
191
216
|
yield item
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
217
|
+
except Exception as e:
|
|
218
|
+
ex = e
|
|
219
|
+
raise
|
|
220
|
+
finally:
|
|
221
|
+
post_process_span(handler, to_wrap, wrapped, instance, args, kwargs, last_item, span, parent_span, ex)
|
|
222
|
+
else:
|
|
223
|
+
try:
|
|
224
|
+
with SpanHandler.workflow_type(to_wrap, span):
|
|
225
|
+
async for item in wrapped(*args, **kwargs):
|
|
226
|
+
last_item = item
|
|
227
|
+
yield item
|
|
228
|
+
except Exception as e:
|
|
229
|
+
ex = e
|
|
230
|
+
raise
|
|
231
|
+
finally:
|
|
232
|
+
def post_process_span_internal(ret_val):
|
|
233
|
+
post_process_span(handler, to_wrap, wrapped, instance, args, kwargs, ret_val, span, parent_span, ex)
|
|
234
|
+
if not auto_close_span:
|
|
235
|
+
span.end()
|
|
236
|
+
if ex is None and not auto_close_span and to_wrap.get("output_processor") and to_wrap.get("output_processor").get("response_processor"):
|
|
237
|
+
to_wrap.get("output_processor").get("response_processor")(to_wrap, None, post_process_span_internal)
|
|
238
|
+
else:
|
|
239
|
+
post_process_span_internal(last_item)
|
|
204
240
|
return
|
|
205
241
|
|
|
206
242
|
async def amonocle_wrapper(tracer: Tracer, handler: SpanHandler, to_wrap, wrapped, instance, source_path, args, kwargs):
|
|
@@ -218,7 +254,8 @@ async def amonocle_wrapper(tracer: Tracer, handler: SpanHandler, to_wrap, wrappe
|
|
|
218
254
|
add_workflow_span = get_value(ADD_NEW_WORKFLOW) == True
|
|
219
255
|
token = attach(set_value(ADD_NEW_WORKFLOW, False))
|
|
220
256
|
try:
|
|
221
|
-
|
|
257
|
+
with monocle_trace_scope(get_builtin_scope_names(to_wrap)):
|
|
258
|
+
return_value, span_status = await amonocle_wrapper_span_processor(tracer, handler, to_wrap, wrapped, instance, source_path,
|
|
222
259
|
add_workflow_span, args, kwargs)
|
|
223
260
|
finally:
|
|
224
261
|
detach(token)
|
|
@@ -244,8 +281,9 @@ async def amonocle_iter_wrapper(tracer: Tracer, handler: SpanHandler, to_wrap, w
|
|
|
244
281
|
add_workflow_span = get_value(ADD_NEW_WORKFLOW) == True
|
|
245
282
|
token = attach(set_value(ADD_NEW_WORKFLOW, False))
|
|
246
283
|
try:
|
|
247
|
-
|
|
248
|
-
|
|
284
|
+
with monocle_trace_scope(get_builtin_scope_names(to_wrap)):
|
|
285
|
+
async for item in amonocle_iter_wrapper_span_processor(tracer, handler, to_wrap, wrapped, instance, source_path, add_workflow_span, args, kwargs):
|
|
286
|
+
yield item
|
|
249
287
|
finally:
|
|
250
288
|
detach(token)
|
|
251
289
|
return
|
|
@@ -351,3 +389,27 @@ def start_as_monocle_span(tracer: Tracer, name: str, auto_close_span: bool) -> I
|
|
|
351
389
|
detach(original_span_token)
|
|
352
390
|
detach(new_monocle_token)
|
|
353
391
|
detach(monocle_span_token)
|
|
392
|
+
|
|
393
|
+
def get_builtin_scope_names(to_wrap) -> str:
|
|
394
|
+
output_processor = to_wrap.get("output_processor", None)
|
|
395
|
+
span_type = output_processor.get("type", None) if output_processor else None
|
|
396
|
+
if span_type and span_type in AGENTIC_SPANS:
|
|
397
|
+
return span_type
|
|
398
|
+
return None
|
|
399
|
+
|
|
400
|
+
def get_wrapper_with_next_processor(to_wrap, handler, instance, args, kwargs):
|
|
401
|
+
if has_more_processors(to_wrap):
|
|
402
|
+
next_output_processor_list = to_wrap.get('output_processor_list',[]).copy()
|
|
403
|
+
while len(next_output_processor_list) > 0:
|
|
404
|
+
next_output_processor = next_output_processor_list.pop(0)
|
|
405
|
+
if handler.should_skip(next_output_processor, instance, args, kwargs):
|
|
406
|
+
next_output_processor = None
|
|
407
|
+
else:
|
|
408
|
+
break
|
|
409
|
+
to_wrap = to_wrap.copy()
|
|
410
|
+
to_wrap['output_processor_list'] = next_output_processor_list
|
|
411
|
+
to_wrap['output_processor'] = next_output_processor
|
|
412
|
+
return to_wrap
|
|
413
|
+
|
|
414
|
+
def has_more_processors(to_wrap) -> bool:
|
|
415
|
+
return len(to_wrap.get('output_processor_list', [])) > 0
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
from monocle_apptrace.instrumentation.common.constants import SPAN_SUBTYPES, SPAN_TYPES
|
|
1
2
|
from monocle_apptrace.instrumentation.metamodel.a2a import _helper
|
|
2
3
|
|
|
3
4
|
A2A_CLIENT = {
|
|
4
|
-
"type":
|
|
5
|
+
"type": SPAN_TYPES.AGENTIC_INVOCATION,
|
|
6
|
+
"subtype": SPAN_SUBTYPES.ROUTING,
|
|
5
7
|
"attributes": [
|
|
6
8
|
[
|
|
7
9
|
{
|
|
@@ -84,6 +84,18 @@ def extract_agent_input(arguments: Dict[str, Any]) -> Any:
|
|
|
84
84
|
"""
|
|
85
85
|
return arguments['args'][0].user_content.parts[0].text
|
|
86
86
|
|
|
87
|
+
def extract_agent_request_input(arguments: Dict[str, Any]) -> Any:
|
|
88
|
+
"""
|
|
89
|
+
Extract the input data from agent request.
|
|
90
|
+
|
|
91
|
+
Args:
|
|
92
|
+
arguments: Dictionary containing agent call arguments
|
|
93
|
+
|
|
94
|
+
Returns:
|
|
95
|
+
Any: The extracted input data
|
|
96
|
+
"""
|
|
97
|
+
return arguments['kwargs']['new_message'].parts[0].text if 'new_message' in arguments['kwargs'] else None
|
|
98
|
+
|
|
87
99
|
def extract_agent_response(result: Any) -> Any:
|
|
88
100
|
"""
|
|
89
101
|
Extract the response data from agent result.
|
|
@@ -145,6 +157,18 @@ def get_delegating_agent(arguments) -> str:
|
|
|
145
157
|
return None
|
|
146
158
|
return from_agent
|
|
147
159
|
|
|
160
|
+
def should_skip_delegation(arguments):
|
|
161
|
+
"""
|
|
162
|
+
Determine whether to skip the delegation based on the arguments.
|
|
163
|
+
|
|
164
|
+
Args:
|
|
165
|
+
arguments: Dictionary containing agent call arguments
|
|
166
|
+
|
|
167
|
+
Returns:
|
|
168
|
+
bool: True if delegation should be skipped, False otherwise
|
|
169
|
+
"""
|
|
170
|
+
return get_delegating_agent(arguments) is None
|
|
171
|
+
|
|
148
172
|
def extract_tool_input(arguments: Dict[str, Any]) -> Any:
|
|
149
173
|
"""
|
|
150
174
|
Extract the input data from tool arguments.
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
from monocle_apptrace.instrumentation.common.constants import SPAN_SUBTYPES, SPAN_TYPES
|
|
1
2
|
from monocle_apptrace.instrumentation.metamodel.adk import _helper
|
|
2
3
|
AGENT = {
|
|
3
|
-
"type":
|
|
4
|
+
"type": SPAN_TYPES.AGENTIC_INVOCATION,
|
|
5
|
+
"subtype": SPAN_SUBTYPES.ROUTING,
|
|
4
6
|
"attributes": [
|
|
5
7
|
[
|
|
6
8
|
{
|
|
@@ -48,3 +50,62 @@ AGENT = {
|
|
|
48
50
|
}
|
|
49
51
|
]
|
|
50
52
|
}
|
|
53
|
+
|
|
54
|
+
REQUEST = {
|
|
55
|
+
"type": "agentic.request",
|
|
56
|
+
"attributes": [
|
|
57
|
+
[
|
|
58
|
+
{
|
|
59
|
+
"_comment": "agent type",
|
|
60
|
+
"attribute": "type",
|
|
61
|
+
"accessor": lambda arguments:'agent.adk'
|
|
62
|
+
}
|
|
63
|
+
],
|
|
64
|
+
],
|
|
65
|
+
"events": [
|
|
66
|
+
{
|
|
67
|
+
"name":"data.input",
|
|
68
|
+
"attributes": [
|
|
69
|
+
{
|
|
70
|
+
"_comment": "this is Agent input",
|
|
71
|
+
"attribute": "input",
|
|
72
|
+
"accessor": lambda arguments: _helper.extract_agent_request_input(arguments)
|
|
73
|
+
}
|
|
74
|
+
]
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"name":"data.output",
|
|
78
|
+
"attributes": [
|
|
79
|
+
{
|
|
80
|
+
"_comment": "this is response from LLM",
|
|
81
|
+
"attribute": "response",
|
|
82
|
+
"accessor": lambda arguments: _helper.extract_agent_response(arguments['result'])
|
|
83
|
+
}
|
|
84
|
+
]
|
|
85
|
+
}
|
|
86
|
+
]
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
DELEGATION = {
|
|
90
|
+
"type": "agentic.delegation",
|
|
91
|
+
"should_skip": lambda arguments: _helper.should_skip_delegation(arguments),
|
|
92
|
+
"attributes": [
|
|
93
|
+
[
|
|
94
|
+
{
|
|
95
|
+
"_comment": "agent type",
|
|
96
|
+
"attribute": "type",
|
|
97
|
+
"accessor": lambda arguments:'agent.adk'
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"_comment": "name of the agent",
|
|
101
|
+
"attribute": "from_agent",
|
|
102
|
+
"accessor": lambda arguments: _helper.get_delegating_agent(arguments)
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
"_comment": "name of the agent called",
|
|
106
|
+
"attribute": "to_agent",
|
|
107
|
+
"accessor": lambda arguments: _helper.get_agent_name(arguments['instance'])
|
|
108
|
+
}
|
|
109
|
+
]
|
|
110
|
+
]
|
|
111
|
+
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
from monocle_apptrace.instrumentation.common.constants import SPAN_SUBTYPES, SPAN_TYPES
|
|
1
2
|
from monocle_apptrace.instrumentation.metamodel.adk import _helper
|
|
2
3
|
TOOL = {
|
|
3
|
-
"type":
|
|
4
|
+
"type": SPAN_TYPES.AGENTIC_TOOL_INVOCATION,
|
|
5
|
+
"subtype": SPAN_SUBTYPES.ROUTING,
|
|
4
6
|
"attributes": [
|
|
5
7
|
[
|
|
6
8
|
{
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from monocle_apptrace.instrumentation.common.wrapper import task_wrapper, atask_wrapper, atask_iter_wrapper
|
|
2
2
|
from monocle_apptrace.instrumentation.metamodel.adk.entities.agent import (
|
|
3
|
-
AGENT,
|
|
3
|
+
AGENT, REQUEST, DELEGATION
|
|
4
4
|
)
|
|
5
5
|
from monocle_apptrace.instrumentation.metamodel.adk.entities.tool import (
|
|
6
6
|
TOOL
|
|
@@ -12,7 +12,7 @@ ADK_METHODS = [
|
|
|
12
12
|
"object": "BaseAgent",
|
|
13
13
|
"method": "run_async",
|
|
14
14
|
"wrapper_method": atask_iter_wrapper,
|
|
15
|
-
"
|
|
15
|
+
"output_processor_list": [DELEGATION, AGENT]
|
|
16
16
|
},
|
|
17
17
|
{
|
|
18
18
|
"package": "google.adk.tools.function_tool",
|
|
@@ -20,5 +20,12 @@ ADK_METHODS = [
|
|
|
20
20
|
"method": "run_async",
|
|
21
21
|
"wrapper_method": atask_wrapper,
|
|
22
22
|
"output_processor": TOOL,
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"package": "google.adk.runners",
|
|
26
|
+
"object": "Runner",
|
|
27
|
+
"method": "run_async",
|
|
28
|
+
"wrapper_method": atask_iter_wrapper,
|
|
29
|
+
"output_processor": REQUEST,
|
|
23
30
|
}
|
|
24
31
|
]
|
|
@@ -158,6 +158,11 @@ def get_runner_agent_name(instance) -> str:
|
|
|
158
158
|
"""Get the name of an agent."""
|
|
159
159
|
return get_name(instance)
|
|
160
160
|
|
|
161
|
+
def get_tool_type(span):
|
|
162
|
+
if (span.attributes.get("is_mcp", False)):
|
|
163
|
+
return "tool.mcp"
|
|
164
|
+
else:
|
|
165
|
+
return "tool.openai_agents"
|
|
161
166
|
|
|
162
167
|
def get_tool_name(instance) -> str:
|
|
163
168
|
"""Get the name of a tool."""
|
|
@@ -34,21 +34,42 @@ def constructor_wrapper(
|
|
|
34
34
|
|
|
35
35
|
original_func = kwargs.get("on_invoke_tool", None)
|
|
36
36
|
result = None
|
|
37
|
+
mcp_url = None
|
|
38
|
+
# kwargs.get("on_invoke_tool").args[0].params["url"]
|
|
39
|
+
if (
|
|
40
|
+
kwargs.get("on_invoke_tool")
|
|
41
|
+
and hasattr(kwargs.get("on_invoke_tool"), "args")
|
|
42
|
+
and len(kwargs.get("on_invoke_tool").args) > 0
|
|
43
|
+
and hasattr(kwargs.get("on_invoke_tool").args[0], "params")
|
|
44
|
+
):
|
|
45
|
+
mcp_url = kwargs.get("on_invoke_tool").args[0].params.get("url", None)
|
|
46
|
+
if mcp_url:
|
|
47
|
+
logger.debug(f"Using MCP URL: {mcp_url}")
|
|
37
48
|
tool_instance = SimpleNamespace(
|
|
38
49
|
name=kwargs.get("name", "unknown_tool"),
|
|
39
50
|
description=kwargs.get("description", "No description provided"),
|
|
40
51
|
)
|
|
41
52
|
if original_func and not getattr(original_func, "_monocle_wrapped", False):
|
|
42
53
|
# Now wrap the function with our instrumentation
|
|
54
|
+
|
|
43
55
|
async def wrapped_func(*func_args, **func_kwargs):
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
56
|
+
token = None
|
|
57
|
+
try:
|
|
58
|
+
if mcp_url:
|
|
59
|
+
token = attach(set_value("mcp.url", mcp_url))
|
|
60
|
+
# Use the handler to create spans when the decorated function is called
|
|
61
|
+
return await atask_wrapper(
|
|
62
|
+
tracer=tracer, handler=handler, to_wrap=to_wrap
|
|
63
|
+
)(
|
|
64
|
+
wrapped=original_func,
|
|
65
|
+
instance=tool_instance,
|
|
66
|
+
source_path=source_path,
|
|
67
|
+
args=func_args,
|
|
68
|
+
kwargs=func_kwargs,
|
|
69
|
+
)
|
|
70
|
+
finally:
|
|
71
|
+
if token:
|
|
72
|
+
detach(token)
|
|
52
73
|
|
|
53
74
|
kwargs["on_invoke_tool"] = wrapped_func
|
|
54
75
|
# Preserve function metadata
|
|
@@ -150,3 +171,4 @@ class AgentsSpanHandler(BaseSpanHandler):
|
|
|
150
171
|
return super().post_task_processing(
|
|
151
172
|
to_wrap, wrapped, instance, args, kwargs, result, ex, span, parent_span
|
|
152
173
|
)
|
|
174
|
+
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
from monocle_apptrace.instrumentation.common.constants import AGENT_REQUEST_SPAN_NAME, SPAN_SUBTYPES, SPAN_TYPES
|
|
1
2
|
from monocle_apptrace.instrumentation.metamodel.agents import _helper
|
|
2
3
|
|
|
3
4
|
AGENT = {
|
|
4
|
-
"type":
|
|
5
|
+
"type": SPAN_TYPES.AGENTIC_INVOCATION,
|
|
6
|
+
"subtype": SPAN_SUBTYPES.ROUTING,
|
|
5
7
|
"attributes": [
|
|
6
8
|
[
|
|
7
9
|
{
|
|
@@ -66,7 +68,8 @@ AGENT = {
|
|
|
66
68
|
}
|
|
67
69
|
|
|
68
70
|
AGENT_REQUEST = {
|
|
69
|
-
"type":
|
|
71
|
+
"type": AGENT_REQUEST_SPAN_NAME,
|
|
72
|
+
"subtype": SPAN_SUBTYPES.PLANNING,
|
|
70
73
|
"attributes": [
|
|
71
74
|
[
|
|
72
75
|
{
|
|
@@ -105,13 +108,14 @@ AGENT_REQUEST = {
|
|
|
105
108
|
}
|
|
106
109
|
|
|
107
110
|
TOOLS = {
|
|
108
|
-
"type":
|
|
111
|
+
"type": SPAN_TYPES.AGENTIC_TOOL_INVOCATION,
|
|
112
|
+
"subtype": SPAN_SUBTYPES.ROUTING,
|
|
109
113
|
"attributes": [
|
|
110
114
|
[
|
|
111
115
|
{
|
|
112
116
|
"_comment": "tool type",
|
|
113
117
|
"attribute": "type",
|
|
114
|
-
"accessor": lambda arguments:
|
|
118
|
+
"accessor": lambda arguments: _helper.get_tool_type(arguments["span"]),
|
|
115
119
|
},
|
|
116
120
|
{
|
|
117
121
|
"_comment": "name of the tool",
|
|
@@ -168,7 +172,8 @@ TOOLS = {
|
|
|
168
172
|
}
|
|
169
173
|
|
|
170
174
|
AGENT_DELEGATION = {
|
|
171
|
-
"type":
|
|
175
|
+
"type": SPAN_TYPES.AGENTIC_DELEGATION,
|
|
176
|
+
"subtype": SPAN_SUBTYPES.ROUTING,
|
|
172
177
|
"attributes": [
|
|
173
178
|
[
|
|
174
179
|
{
|
|
@@ -3,6 +3,7 @@ from monocle_apptrace.instrumentation.metamodel.agents.entities.inference import
|
|
|
3
3
|
AGENT,
|
|
4
4
|
AGENT_DELEGATION,
|
|
5
5
|
TOOLS,
|
|
6
|
+
AGENT_REQUEST
|
|
6
7
|
)
|
|
7
8
|
from monocle_apptrace.instrumentation.metamodel.agents.agents_processor import (
|
|
8
9
|
constructor_wrapper,
|
|
@@ -17,7 +18,7 @@ AGENTS_METHODS = [
|
|
|
17
18
|
"method": "run",
|
|
18
19
|
"wrapper_method": atask_wrapper,
|
|
19
20
|
"span_handler": "agents_agent_handler",
|
|
20
|
-
"output_processor":
|
|
21
|
+
"output_processor": AGENT_REQUEST,
|
|
21
22
|
},
|
|
22
23
|
{
|
|
23
24
|
"package": "agents.run",
|
|
@@ -25,7 +26,7 @@ AGENTS_METHODS = [
|
|
|
25
26
|
"method": "run_sync",
|
|
26
27
|
"wrapper_method": task_wrapper,
|
|
27
28
|
"span_handler": "agents_agent_handler",
|
|
28
|
-
"output_processor":
|
|
29
|
+
"output_processor": AGENT_REQUEST,
|
|
29
30
|
},
|
|
30
31
|
# AgentRunner class methods (internal runner)
|
|
31
32
|
{
|
|
@@ -42,7 +43,6 @@ AGENTS_METHODS = [
|
|
|
42
43
|
"object": "FunctionTool",
|
|
43
44
|
"method": "__init__", # Empty string means wrap the function itself
|
|
44
45
|
"wrapper_method": constructor_wrapper,
|
|
45
|
-
"span_handler": "agents_tool_handler",
|
|
46
46
|
"output_processor": TOOLS,
|
|
47
47
|
},
|
|
48
48
|
{
|
|
@@ -50,7 +50,6 @@ AGENTS_METHODS = [
|
|
|
50
50
|
"object": "Handoff",
|
|
51
51
|
"method": "__init__", # Empty string means wrap the function itself
|
|
52
52
|
"wrapper_method": handoff_constructor_wrapper,
|
|
53
|
-
"span_handler": "agents_tool_handler",
|
|
54
53
|
"output_processor": AGENT_DELEGATION,
|
|
55
54
|
},
|
|
56
55
|
]
|
|
@@ -16,7 +16,7 @@ from monocle_apptrace.instrumentation.common.utils import (
|
|
|
16
16
|
get_exception_message,
|
|
17
17
|
)
|
|
18
18
|
from monocle_apptrace.instrumentation.metamodel.finish_types import map_anthropic_finish_reason_to_finish_type
|
|
19
|
-
from monocle_apptrace.instrumentation.common.constants import AGENT_PREFIX_KEY, INFERENCE_AGENT_DELEGATION,
|
|
19
|
+
from monocle_apptrace.instrumentation.common.constants import AGENT_PREFIX_KEY, INFERENCE_AGENT_DELEGATION, INFERENCE_TURN_END, INFERENCE_TOOL_CALL
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
logger = logging.getLogger(__name__)
|
|
@@ -177,7 +177,7 @@ def agent_inference_type(arguments):
|
|
|
177
177
|
if agent_prefix and agent_prefix in assistant_message:
|
|
178
178
|
return INFERENCE_AGENT_DELEGATION
|
|
179
179
|
|
|
180
|
-
return
|
|
180
|
+
return INFERENCE_TURN_END
|
|
181
181
|
except Exception as e:
|
|
182
182
|
logger.warning("Warning: Error occurred in agent_inference_type: %s", str(e))
|
|
183
|
-
return
|
|
183
|
+
return INFERENCE_TURN_END
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
from monocle_apptrace.instrumentation.common.constants import SPAN_TYPES
|
|
1
2
|
from monocle_apptrace.instrumentation.metamodel.anthropic import (
|
|
2
3
|
_helper,
|
|
3
4
|
)
|
|
4
5
|
from monocle_apptrace.instrumentation.common.utils import (get_error_message, resolve_from_alias)
|
|
5
6
|
|
|
6
7
|
INFERENCE = {
|
|
7
|
-
"type":
|
|
8
|
+
"type": SPAN_TYPES.INFERENCE,
|
|
8
9
|
"attributes": [
|
|
9
10
|
[
|
|
10
11
|
{
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
import time
|
|
3
3
|
from types import SimpleNamespace
|
|
4
|
+
from monocle_apptrace.instrumentation.common.constants import SPAN_TYPES
|
|
4
5
|
from monocle_apptrace.instrumentation.metamodel.azureaiinference import _helper
|
|
5
6
|
from monocle_apptrace.instrumentation.common.utils import (
|
|
6
7
|
get_error_message,
|
|
@@ -133,7 +134,7 @@ def process_stream(to_wrap, response, span_processor):
|
|
|
133
134
|
|
|
134
135
|
|
|
135
136
|
INFERENCE = {
|
|
136
|
-
"type":
|
|
137
|
+
"type": SPAN_TYPES.INFERENCE,
|
|
137
138
|
"is_auto_close": lambda kwargs: kwargs.get("stream", False) is False,
|
|
138
139
|
"response_processor": process_stream,
|
|
139
140
|
"attributes": [
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
from monocle_apptrace.instrumentation.common.constants import SPAN_TYPES
|
|
1
2
|
from monocle_apptrace.instrumentation.metamodel.botocore import (
|
|
2
3
|
_helper,
|
|
3
4
|
)
|
|
4
5
|
from monocle_apptrace.instrumentation.common.utils import (get_error_message, get_llm_type, get_status,)
|
|
5
6
|
INFERENCE = {
|
|
6
|
-
"type":
|
|
7
|
+
"type": SPAN_TYPES.INFERENCE,
|
|
7
8
|
"attributes": [
|
|
8
9
|
[
|
|
9
10
|
{
|