monocle-apptrace 0.5.0b1__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/exporters/file_exporter.py +2 -1
- monocle_apptrace/instrumentation/common/__init__.py +7 -5
- monocle_apptrace/instrumentation/common/constants.py +103 -12
- monocle_apptrace/instrumentation/common/instrumentor.py +1 -6
- monocle_apptrace/instrumentation/common/method_wrappers.py +10 -125
- monocle_apptrace/instrumentation/common/scope_wrapper.py +126 -0
- monocle_apptrace/instrumentation/common/span_handler.py +32 -8
- monocle_apptrace/instrumentation/common/utils.py +34 -3
- monocle_apptrace/instrumentation/common/wrapper.py +208 -41
- monocle_apptrace/instrumentation/common/wrapper_method.py +9 -1
- monocle_apptrace/instrumentation/metamodel/a2a/entities/inference.py +3 -1
- monocle_apptrace/instrumentation/metamodel/adk/__init__.py +0 -0
- monocle_apptrace/instrumentation/metamodel/adk/_helper.py +206 -0
- monocle_apptrace/instrumentation/metamodel/adk/entities/agent.py +111 -0
- monocle_apptrace/instrumentation/metamodel/adk/entities/tool.py +59 -0
- monocle_apptrace/instrumentation/metamodel/adk/methods.py +31 -0
- monocle_apptrace/instrumentation/metamodel/agents/__init__.py +0 -0
- monocle_apptrace/instrumentation/metamodel/agents/_helper.py +225 -0
- monocle_apptrace/instrumentation/metamodel/agents/agents_processor.py +174 -0
- monocle_apptrace/instrumentation/metamodel/agents/entities/__init__.py +0 -0
- monocle_apptrace/instrumentation/metamodel/agents/entities/inference.py +196 -0
- monocle_apptrace/instrumentation/metamodel/agents/methods.py +55 -0
- monocle_apptrace/instrumentation/metamodel/aiohttp/entities/http.py +2 -1
- monocle_apptrace/instrumentation/metamodel/anthropic/_helper.py +82 -5
- monocle_apptrace/instrumentation/metamodel/anthropic/entities/inference.py +6 -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/fastapi/methods.py +18 -18
- monocle_apptrace/instrumentation/metamodel/finish_types.py +79 -1
- monocle_apptrace/instrumentation/metamodel/flask/entities/http.py +2 -1
- monocle_apptrace/instrumentation/metamodel/gemini/entities/inference.py +7 -3
- monocle_apptrace/instrumentation/metamodel/gemini/entities/retrieval.py +2 -1
- monocle_apptrace/instrumentation/metamodel/gemini/methods.py +8 -1
- monocle_apptrace/instrumentation/metamodel/haystack/_helper.py +64 -0
- monocle_apptrace/instrumentation/metamodel/haystack/entities/inference.py +12 -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 +18 -0
- monocle_apptrace/instrumentation/metamodel/langchain/entities/inference.py +6 -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 +11 -4
- monocle_apptrace/instrumentation/metamodel/langgraph/methods.py +27 -23
- monocle_apptrace/instrumentation/metamodel/litellm/__init__.py +0 -0
- monocle_apptrace/instrumentation/metamodel/litellm/_helper.py +89 -0
- monocle_apptrace/instrumentation/metamodel/litellm/entities/__init__.py +0 -0
- monocle_apptrace/instrumentation/metamodel/litellm/entities/inference.py +109 -0
- monocle_apptrace/instrumentation/metamodel/litellm/methods.py +19 -0
- 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/llamaindex/llamaindex_processor.py +14 -3
- monocle_apptrace/instrumentation/metamodel/llamaindex/methods.py +1 -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/mcp_processor.py +0 -5
- monocle_apptrace/instrumentation/metamodel/mcp/methods.py +1 -1
- monocle_apptrace/instrumentation/metamodel/openai/_helper.py +110 -5
- monocle_apptrace/instrumentation/metamodel/openai/entities/inference.py +59 -13
- monocle_apptrace/instrumentation/metamodel/requests/entities/http.py +2 -1
- monocle_apptrace/instrumentation/metamodel/teamsai/_helper.py +12 -1
- monocle_apptrace/instrumentation/metamodel/teamsai/entities/inference/teamsai_output_processor.py +12 -1
- {monocle_apptrace-0.5.0b1.dist-info → monocle_apptrace-0.5.1.dist-info}/METADATA +15 -10
- {monocle_apptrace-0.5.0b1.dist-info → monocle_apptrace-0.5.1.dist-info}/RECORD +70 -53
- {monocle_apptrace-0.5.0b1.dist-info → monocle_apptrace-0.5.1.dist-info}/WHEEL +0 -0
- {monocle_apptrace-0.5.0b1.dist-info → monocle_apptrace-0.5.1.dist-info}/licenses/LICENSE +0 -0
- {monocle_apptrace-0.5.0b1.dist-info → monocle_apptrace-0.5.1.dist-info}/licenses/NOTICE +0 -0
|
@@ -9,6 +9,8 @@ from monocle_apptrace.instrumentation.common.utils import (
|
|
|
9
9
|
get_exception_message,
|
|
10
10
|
get_status_code,
|
|
11
11
|
)
|
|
12
|
+
from monocle_apptrace.instrumentation.metamodel.finish_types import map_haystack_finish_reason_to_finish_type
|
|
13
|
+
|
|
12
14
|
logger = logging.getLogger(__name__)
|
|
13
15
|
|
|
14
16
|
|
|
@@ -153,3 +155,65 @@ def update_output_span_events(results):
|
|
|
153
155
|
if len(output_arg_text) > 100:
|
|
154
156
|
output_arg_text = output_arg_text[:100] + "..."
|
|
155
157
|
return output_arg_text
|
|
158
|
+
|
|
159
|
+
def extract_finish_reason(arguments):
|
|
160
|
+
"""Extract finish_reason from Haystack response."""
|
|
161
|
+
try:
|
|
162
|
+
# Handle exception cases first
|
|
163
|
+
if arguments.get("exception") is not None:
|
|
164
|
+
return "error"
|
|
165
|
+
|
|
166
|
+
response = arguments.get("result")
|
|
167
|
+
if response is None:
|
|
168
|
+
return None
|
|
169
|
+
|
|
170
|
+
# Direct finish_reason attribute
|
|
171
|
+
if hasattr(response, "finish_reason") and response.finish_reason:
|
|
172
|
+
return response.finish_reason
|
|
173
|
+
|
|
174
|
+
if isinstance(response,dict) and 'meta' in response and response['meta'] and len(response['meta']) > 0:
|
|
175
|
+
metadata = response['meta'][0]
|
|
176
|
+
if isinstance(metadata, dict):
|
|
177
|
+
# Check for finish_reason in metadata
|
|
178
|
+
if "finish_reason" in metadata:
|
|
179
|
+
return metadata["finish_reason"]
|
|
180
|
+
|
|
181
|
+
if isinstance(response,dict) and 'replies' in response and response['replies'] and len(response['replies']) > 0:
|
|
182
|
+
metadata = response['replies'][0]
|
|
183
|
+
if hasattr(metadata,'meta') and metadata.meta:
|
|
184
|
+
if "finish_reason" in metadata.meta:
|
|
185
|
+
return metadata.meta["finish_reason"]
|
|
186
|
+
|
|
187
|
+
# Check if response has generation_info
|
|
188
|
+
if hasattr(response, "generation_info") and response.generation_info:
|
|
189
|
+
finish_reason = response.generation_info.get("finish_reason")
|
|
190
|
+
if finish_reason:
|
|
191
|
+
return finish_reason
|
|
192
|
+
|
|
193
|
+
# Check if response has llm_output (batch responses)
|
|
194
|
+
if hasattr(response, "llm_output") and response.llm_output:
|
|
195
|
+
finish_reason = response.llm_output.get("finish_reason")
|
|
196
|
+
if finish_reason:
|
|
197
|
+
return finish_reason
|
|
198
|
+
|
|
199
|
+
# For AIMessage responses, check additional_kwargs
|
|
200
|
+
if hasattr(response, "additional_kwargs") and response.additional_kwargs:
|
|
201
|
+
finish_reason = response.additional_kwargs.get("finish_reason")
|
|
202
|
+
if finish_reason:
|
|
203
|
+
return finish_reason
|
|
204
|
+
|
|
205
|
+
# For generation responses with choices (similar to OpenAI structure)
|
|
206
|
+
if hasattr(response, "choices") and response.choices:
|
|
207
|
+
choice = response.choices[0]
|
|
208
|
+
if hasattr(choice, "finish_reason"):
|
|
209
|
+
return choice.finish_reason
|
|
210
|
+
|
|
211
|
+
# Fallback: if no finish_reason found, default to "stop" (success)
|
|
212
|
+
return "stop"
|
|
213
|
+
except Exception as e:
|
|
214
|
+
logger.warning("Warning: Error occurred in extract_finish_reason: %s", str(e))
|
|
215
|
+
return None
|
|
216
|
+
|
|
217
|
+
def map_finish_reason_to_finish_type(finish_reason):
|
|
218
|
+
"""Map Haystack finish_reason to finish_type using Haystack mapping."""
|
|
219
|
+
return map_haystack_finish_reason_to_finish_type(finish_reason)
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
from monocle_apptrace.instrumentation.common.constants import SPAN_TYPES
|
|
1
2
|
from monocle_apptrace.instrumentation.metamodel.haystack import (
|
|
2
3
|
_helper,
|
|
3
4
|
)
|
|
4
5
|
from monocle_apptrace.instrumentation.common.utils import get_error_message, get_llm_type
|
|
5
6
|
|
|
6
7
|
INFERENCE = {
|
|
7
|
-
"type":
|
|
8
|
+
"type": SPAN_TYPES.INFERENCE_FRAMEWORK,
|
|
8
9
|
"attributes": [
|
|
9
10
|
[
|
|
10
11
|
{
|
|
@@ -75,6 +76,16 @@ INFERENCE = {
|
|
|
75
76
|
"_comment": "this is metadata usage from LLM",
|
|
76
77
|
"accessor": lambda arguments: _helper.update_span_from_llm_response(arguments['result'],
|
|
77
78
|
arguments['instance'])
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"attribute": "finish_reason",
|
|
82
|
+
"accessor": lambda arguments: _helper.extract_finish_reason(arguments)
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
"attribute": "finish_type",
|
|
86
|
+
"accessor": lambda arguments: _helper.map_finish_reason_to_finish_type(
|
|
87
|
+
_helper.extract_finish_reason(arguments)
|
|
88
|
+
)
|
|
78
89
|
}
|
|
79
90
|
]
|
|
80
91
|
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
from monocle_apptrace.instrumentation.common.constants import SPAN_TYPES
|
|
1
2
|
from monocle_apptrace.instrumentation.metamodel.haystack import (_helper, )
|
|
2
3
|
from monocle_apptrace.instrumentation.common.utils import get_attribute
|
|
3
4
|
|
|
4
5
|
RETRIEVAL = {
|
|
5
|
-
"type":
|
|
6
|
+
"type": SPAN_TYPES.RETRIEVAL,
|
|
6
7
|
"attributes": [
|
|
7
8
|
[
|
|
8
9
|
{
|
|
@@ -4,6 +4,8 @@ and assistant messages from various input formats.
|
|
|
4
4
|
"""
|
|
5
5
|
|
|
6
6
|
import logging
|
|
7
|
+
from opentelemetry.context import get_value
|
|
8
|
+
from monocle_apptrace.instrumentation.common.constants import AGENT_PREFIX_KEY, INFERENCE_AGENT_DELEGATION, INFERENCE_TURN_END, INFERENCE_TOOL_CALL
|
|
7
9
|
from monocle_apptrace.instrumentation.common.utils import (
|
|
8
10
|
Option,
|
|
9
11
|
get_json_dumps,
|
|
@@ -44,6 +46,22 @@ def extract_messages(args):
|
|
|
44
46
|
except Exception as e:
|
|
45
47
|
logger.warning("Warning: Error occurred in extract_messages: %s", str(e))
|
|
46
48
|
return []
|
|
49
|
+
def agent_inference_type(arguments):
|
|
50
|
+
"""Extract agent inference type from arguments."""
|
|
51
|
+
try:
|
|
52
|
+
if get_value(AGENT_PREFIX_KEY):
|
|
53
|
+
agent_prefix = get_value(AGENT_PREFIX_KEY)
|
|
54
|
+
if hasattr(arguments['result'], "tool_calls") and arguments['result'].tool_calls:
|
|
55
|
+
tool_call = arguments['result'].tool_calls[0] if arguments['result'].tool_calls else None
|
|
56
|
+
if tool_call and 'name' in tool_call and tool_call["name"].startswith(agent_prefix):
|
|
57
|
+
return INFERENCE_AGENT_DELEGATION
|
|
58
|
+
else:
|
|
59
|
+
return INFERENCE_TOOL_CALL
|
|
60
|
+
return INFERENCE_TURN_END
|
|
61
|
+
|
|
62
|
+
except Exception as e:
|
|
63
|
+
logger.warning("Warning: Error occurred in agent_inference_type: %s", str(e))
|
|
64
|
+
return None
|
|
47
65
|
|
|
48
66
|
def extract_assistant_message(arguments):
|
|
49
67
|
status = get_status_code(arguments)
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
from monocle_apptrace.instrumentation.common.constants import SPAN_TYPES
|
|
1
2
|
from monocle_apptrace.instrumentation.metamodel.langchain import (
|
|
2
3
|
_helper,
|
|
3
4
|
)
|
|
4
5
|
from monocle_apptrace.instrumentation.common.utils import get_error_message, resolve_from_alias, get_llm_type, get_status, get_status_code
|
|
5
6
|
|
|
6
7
|
INFERENCE = {
|
|
7
|
-
"type":
|
|
8
|
+
"type": SPAN_TYPES.INFERENCE_FRAMEWORK,
|
|
8
9
|
"attributes": [
|
|
9
10
|
[
|
|
10
11
|
{
|
|
@@ -78,6 +79,10 @@ INFERENCE = {
|
|
|
78
79
|
"accessor": lambda arguments: _helper.map_finish_reason_to_finish_type(
|
|
79
80
|
_helper.extract_finish_reason(arguments)
|
|
80
81
|
)
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"attribute": "inference_sub_type",
|
|
85
|
+
"accessor": lambda arguments: _helper.agent_inference_type(arguments)
|
|
81
86
|
}
|
|
82
87
|
]
|
|
83
88
|
}
|
|
@@ -76,6 +76,12 @@ def get_name(instance):
|
|
|
76
76
|
def get_agent_name(instance) -> str:
|
|
77
77
|
return get_name(instance)
|
|
78
78
|
|
|
79
|
+
def get_tool_type(span):
|
|
80
|
+
if (span.attributes.get("is_mcp", False)):
|
|
81
|
+
return "tool.mcp"
|
|
82
|
+
else:
|
|
83
|
+
return "tool.langgraph"
|
|
84
|
+
|
|
79
85
|
def get_tool_name(instance) -> str:
|
|
80
86
|
return get_name(instance)
|
|
81
87
|
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
from monocle_apptrace.instrumentation.common.constants import AGENT_REQUEST_SPAN_NAME, SPAN_SUBTYPES, SPAN_TYPES
|
|
1
2
|
from monocle_apptrace.instrumentation.metamodel.langgraph import (
|
|
2
3
|
_helper
|
|
3
4
|
)
|
|
4
5
|
|
|
5
6
|
AGENT = {
|
|
6
|
-
"type":
|
|
7
|
+
"type": SPAN_TYPES.AGENTIC_INVOCATION,
|
|
8
|
+
"subtype": SPAN_SUBTYPES.ROUTING,
|
|
7
9
|
"attributes": [
|
|
8
10
|
[
|
|
9
11
|
{
|
|
@@ -48,7 +50,8 @@ AGENT = {
|
|
|
48
50
|
}
|
|
49
51
|
|
|
50
52
|
AGENT_REQUEST = {
|
|
51
|
-
"type":
|
|
53
|
+
"type": AGENT_REQUEST_SPAN_NAME,
|
|
54
|
+
"subtype": SPAN_SUBTYPES.PLANNING,
|
|
52
55
|
"attributes": [
|
|
53
56
|
[
|
|
54
57
|
{
|
|
@@ -83,13 +86,14 @@ AGENT_REQUEST = {
|
|
|
83
86
|
}
|
|
84
87
|
|
|
85
88
|
TOOLS = {
|
|
86
|
-
"type":
|
|
89
|
+
"type": SPAN_TYPES.AGENTIC_TOOL_INVOCATION,
|
|
90
|
+
"subtype": SPAN_SUBTYPES.ROUTING,
|
|
87
91
|
"attributes": [
|
|
88
92
|
[
|
|
89
93
|
{
|
|
90
94
|
"_comment": "tool type",
|
|
91
95
|
"attribute": "type",
|
|
92
|
-
"accessor": lambda arguments:
|
|
96
|
+
"accessor": lambda arguments: _helper.get_tool_type(arguments['span'])
|
|
93
97
|
},
|
|
94
98
|
{
|
|
95
99
|
"_comment": "name of the tool",
|
|
@@ -140,7 +144,8 @@ TOOLS = {
|
|
|
140
144
|
}
|
|
141
145
|
|
|
142
146
|
AGENT_DELEGATION = {
|
|
143
|
-
"type":
|
|
147
|
+
"type": SPAN_TYPES.AGENTIC_DELEGATION,
|
|
148
|
+
"subtype": SPAN_SUBTYPES.ROUTING,
|
|
144
149
|
"attributes": [
|
|
145
150
|
[
|
|
146
151
|
{
|
|
@@ -1,16 +1,23 @@
|
|
|
1
|
-
from opentelemetry.context import set_value, attach, detach
|
|
1
|
+
from opentelemetry.context import set_value, attach, detach, get_value
|
|
2
|
+
from monocle_apptrace.instrumentation.common.constants import AGENT_PREFIX_KEY, SCOPE_NAME
|
|
2
3
|
from monocle_apptrace.instrumentation.common.span_handler import SpanHandler
|
|
3
4
|
from monocle_apptrace.instrumentation.metamodel.langgraph._helper import (
|
|
4
|
-
get_name, is_root_agent_name, is_delegation_tool, LANGGRAPTH_AGENT_NAME_KEY
|
|
5
|
-
|
|
5
|
+
DELEGATION_NAME_PREFIX, get_name, is_root_agent_name, is_delegation_tool, LANGGRAPTH_AGENT_NAME_KEY
|
|
6
6
|
)
|
|
7
7
|
from monocle_apptrace.instrumentation.metamodel.langgraph.entities.inference import (
|
|
8
8
|
AGENT_DELEGATION, AGENT_REQUEST
|
|
9
9
|
)
|
|
10
|
+
from monocle_apptrace.instrumentation.common.scope_wrapper import start_scope, stop_scope
|
|
10
11
|
|
|
11
12
|
class LanggraphAgentHandler(SpanHandler):
|
|
12
13
|
def pre_tracing(self, to_wrap, wrapped, instance, args, kwargs):
|
|
13
|
-
|
|
14
|
+
context = set_value(LANGGRAPTH_AGENT_NAME_KEY, get_name(instance))
|
|
15
|
+
context = set_value(AGENT_PREFIX_KEY, DELEGATION_NAME_PREFIX, context)
|
|
16
|
+
scope_name = AGENT_REQUEST.get("type")
|
|
17
|
+
if scope_name is not None and is_root_agent_name(instance) and get_value(scope_name, context) is None:
|
|
18
|
+
return start_scope(scope_name, scope_value=None, context=context)
|
|
19
|
+
else:
|
|
20
|
+
return attach(context)
|
|
14
21
|
|
|
15
22
|
def post_tracing(self, to_wrap, wrapped, instance, args, kwargs, result, token):
|
|
16
23
|
if token is not None:
|
|
@@ -1,38 +1,42 @@
|
|
|
1
1
|
from monocle_apptrace.instrumentation.common.wrapper import task_wrapper, atask_wrapper
|
|
2
2
|
from monocle_apptrace.instrumentation.metamodel.langgraph.entities.inference import (
|
|
3
|
-
AGENT,
|
|
3
|
+
AGENT,
|
|
4
|
+
TOOLS,
|
|
4
5
|
)
|
|
6
|
+
|
|
5
7
|
LANGGRAPH_METHODS = [
|
|
6
8
|
{
|
|
7
9
|
"package": "langgraph.graph.state",
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
"span_handler":"langgraph_agent_handler",
|
|
12
|
-
|
|
10
|
+
"object": "CompiledStateGraph",
|
|
11
|
+
"method": "invoke",
|
|
12
|
+
"wrapper_method": task_wrapper,
|
|
13
|
+
"span_handler": "langgraph_agent_handler",
|
|
14
|
+
"scope_name": "agent.invocation",
|
|
15
|
+
"output_processor": AGENT,
|
|
13
16
|
},
|
|
14
17
|
{
|
|
15
18
|
"package": "langgraph.graph.state",
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
"span_handler":"langgraph_agent_handler",
|
|
20
|
-
|
|
19
|
+
"object": "CompiledStateGraph",
|
|
20
|
+
"method": "ainvoke",
|
|
21
|
+
"wrapper_method": atask_wrapper,
|
|
22
|
+
"span_handler": "langgraph_agent_handler",
|
|
23
|
+
"scope_name": "agent.invocation",
|
|
24
|
+
"output_processor": AGENT,
|
|
21
25
|
},
|
|
22
26
|
{
|
|
23
27
|
"package": "langchain_core.tools.base",
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
"span_handler":"langgraph_tool_handler",
|
|
28
|
-
|
|
28
|
+
"object": "BaseTool",
|
|
29
|
+
"method": "run",
|
|
30
|
+
"wrapper_method": task_wrapper,
|
|
31
|
+
"span_handler": "langgraph_tool_handler",
|
|
32
|
+
"output_processor": TOOLS,
|
|
29
33
|
},
|
|
30
34
|
{
|
|
31
35
|
"package": "langchain_core.tools.base",
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
"span_handler":"langgraph_tool_handler",
|
|
36
|
-
|
|
37
|
-
},
|
|
38
|
-
]
|
|
36
|
+
"object": "BaseTool",
|
|
37
|
+
"method": "arun",
|
|
38
|
+
"wrapper_method": atask_wrapper,
|
|
39
|
+
"span_handler": "langgraph_tool_handler",
|
|
40
|
+
"output_processor": TOOLS,
|
|
41
|
+
},
|
|
42
|
+
]
|
|
File without changes
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This module provides utility functions for extracting system, user,
|
|
3
|
+
and assistant messages from various input formats.
|
|
4
|
+
"""
|
|
5
|
+
import json
|
|
6
|
+
import logging
|
|
7
|
+
from monocle_apptrace.instrumentation.common.utils import (
|
|
8
|
+
Option,
|
|
9
|
+
get_json_dumps,
|
|
10
|
+
try_option,
|
|
11
|
+
get_exception_message,
|
|
12
|
+
get_status_code,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
logger = logging.getLogger(__name__)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def extract_messages(kwargs):
|
|
19
|
+
"""Extract system and user messages"""
|
|
20
|
+
try:
|
|
21
|
+
messages = []
|
|
22
|
+
if 'messages' in kwargs and len(kwargs['messages']) > 0:
|
|
23
|
+
for msg in kwargs['messages']:
|
|
24
|
+
if msg.get('content') and msg.get('role'):
|
|
25
|
+
messages.append({msg['role']: msg['content']})
|
|
26
|
+
|
|
27
|
+
return [get_json_dumps(message) for message in messages]
|
|
28
|
+
except Exception as e:
|
|
29
|
+
logger.warning("Warning: Error occurred in extract_messages: %s", str(e))
|
|
30
|
+
return []
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def extract_assistant_message(arguments):
|
|
34
|
+
try:
|
|
35
|
+
messages = []
|
|
36
|
+
status = get_status_code(arguments)
|
|
37
|
+
if status == 'success' or status == 'completed':
|
|
38
|
+
response = arguments["result"]
|
|
39
|
+
if (response is not None and hasattr(response, "choices") and len(response.choices) > 0):
|
|
40
|
+
if hasattr(response.choices[0], "message"):
|
|
41
|
+
role = (
|
|
42
|
+
response.choices[0].message.role
|
|
43
|
+
if hasattr(response.choices[0].message, "role")
|
|
44
|
+
else "assistant"
|
|
45
|
+
)
|
|
46
|
+
messages.append({role: response.choices[0].message.content})
|
|
47
|
+
return get_json_dumps(messages[0]) if messages else ""
|
|
48
|
+
else:
|
|
49
|
+
if arguments["exception"] is not None:
|
|
50
|
+
return get_exception_message(arguments)
|
|
51
|
+
elif hasattr(arguments["result"], "error"):
|
|
52
|
+
return arguments["result"].error
|
|
53
|
+
|
|
54
|
+
except (IndexError, AttributeError) as e:
|
|
55
|
+
logger.warning(
|
|
56
|
+
"Warning: Error occurred in extract_assistant_message: %s", str(e)
|
|
57
|
+
)
|
|
58
|
+
return None
|
|
59
|
+
|
|
60
|
+
def extract_provider_name(url):
|
|
61
|
+
"""Extract host from a URL string (e.g., https://api.openai.com/v1/ -> api.openai.com)"""
|
|
62
|
+
if not url:
|
|
63
|
+
return None
|
|
64
|
+
return url.split("//")[-1].split("/")[0]
|
|
65
|
+
|
|
66
|
+
def resolve_from_alias(my_map, alias):
|
|
67
|
+
"""Find a alias that is not none from list of aliases"""
|
|
68
|
+
|
|
69
|
+
for i in alias:
|
|
70
|
+
if i in my_map.keys():
|
|
71
|
+
return my_map[i]
|
|
72
|
+
return None
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def update_span_from_llm_response(response):
|
|
76
|
+
meta_dict = {}
|
|
77
|
+
token_usage = None
|
|
78
|
+
if response is not None:
|
|
79
|
+
if token_usage is None and hasattr(response, "usage") and response.usage is not None:
|
|
80
|
+
token_usage = response.usage
|
|
81
|
+
elif token_usage is None and hasattr(response, "response_metadata"):
|
|
82
|
+
token_usage = getattr(response.response_metadata, "token_usage", None) \
|
|
83
|
+
if hasattr(response.response_metadata, "token_usage") \
|
|
84
|
+
else response.response_metadata.get("token_usage", None)
|
|
85
|
+
if token_usage is not None:
|
|
86
|
+
meta_dict.update({"completion_tokens": getattr(token_usage, "completion_tokens", None) or getattr(token_usage, "output_tokens", None)})
|
|
87
|
+
meta_dict.update({"prompt_tokens": getattr(token_usage, "prompt_tokens", None) or getattr(token_usage, "input_tokens", None)})
|
|
88
|
+
meta_dict.update({"total_tokens": getattr(token_usage, "total_tokens")})
|
|
89
|
+
return meta_dict
|
|
File without changes
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
from monocle_apptrace.instrumentation.common.constants import SPAN_TYPES
|
|
2
|
+
from monocle_apptrace.instrumentation.metamodel.litellm import (
|
|
3
|
+
_helper,
|
|
4
|
+
)
|
|
5
|
+
from monocle_apptrace.instrumentation.common.utils import (
|
|
6
|
+
get_error_message,
|
|
7
|
+
resolve_from_alias,
|
|
8
|
+
get_llm_type,
|
|
9
|
+
)
|
|
10
|
+
INFERENCE = {
|
|
11
|
+
"type": SPAN_TYPES.INFERENCE,
|
|
12
|
+
"attributes": [
|
|
13
|
+
[
|
|
14
|
+
{
|
|
15
|
+
"_comment": "provider type ,name , deployment , inference_endpoint",
|
|
16
|
+
"attribute": "type",
|
|
17
|
+
"accessor": lambda arguments: "inference."
|
|
18
|
+
+ (get_llm_type(arguments['instance']) or 'generic')
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"attribute": "provider_name",
|
|
22
|
+
"accessor": lambda arguments: _helper.extract_provider_name(
|
|
23
|
+
resolve_from_alias(
|
|
24
|
+
arguments["kwargs"],
|
|
25
|
+
["azure_endpoint", "api_base", "endpoint"],
|
|
26
|
+
)
|
|
27
|
+
),
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"attribute": "deployment",
|
|
31
|
+
"accessor": lambda arguments: resolve_from_alias(
|
|
32
|
+
arguments["kwargs"].__dict__,
|
|
33
|
+
[
|
|
34
|
+
"engine",
|
|
35
|
+
"azure_deployment",
|
|
36
|
+
"deployment_name",
|
|
37
|
+
"deployment_id",
|
|
38
|
+
"deployment",
|
|
39
|
+
],
|
|
40
|
+
),
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"attribute": "inference_endpoint",
|
|
44
|
+
"accessor": lambda arguments: resolve_from_alias(
|
|
45
|
+
arguments["kwargs"],
|
|
46
|
+
["azure_endpoint", "api_base", "endpoint"],
|
|
47
|
+
)
|
|
48
|
+
},
|
|
49
|
+
],
|
|
50
|
+
[
|
|
51
|
+
{
|
|
52
|
+
"_comment": "LLM Model",
|
|
53
|
+
"attribute": "name",
|
|
54
|
+
"accessor": lambda arguments: resolve_from_alias(
|
|
55
|
+
arguments["kwargs"],
|
|
56
|
+
["model", "model_name", "endpoint_name", "deployment_name"],
|
|
57
|
+
),
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"attribute": "type",
|
|
61
|
+
"accessor": lambda arguments: "model.llm."
|
|
62
|
+
+ resolve_from_alias(
|
|
63
|
+
arguments["kwargs"],
|
|
64
|
+
["model", "model_name", "endpoint_name", "deployment_name"],
|
|
65
|
+
),
|
|
66
|
+
},
|
|
67
|
+
],
|
|
68
|
+
],
|
|
69
|
+
"events": [
|
|
70
|
+
{
|
|
71
|
+
"name": "data.input",
|
|
72
|
+
"attributes": [
|
|
73
|
+
{
|
|
74
|
+
"_comment": "this is instruction and user query to LLM",
|
|
75
|
+
"attribute": "input",
|
|
76
|
+
"accessor": lambda arguments: _helper.extract_messages(
|
|
77
|
+
arguments["kwargs"]
|
|
78
|
+
),
|
|
79
|
+
}
|
|
80
|
+
],
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
"name": "data.output",
|
|
84
|
+
"attributes": [
|
|
85
|
+
|
|
86
|
+
{
|
|
87
|
+
"attribute": "error_code",
|
|
88
|
+
"accessor": lambda arguments: get_error_message(arguments)
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
"_comment": "this is result from LLM",
|
|
92
|
+
"attribute": "response",
|
|
93
|
+
"accessor": lambda arguments: _helper.extract_assistant_message(arguments),
|
|
94
|
+
}
|
|
95
|
+
],
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
"name": "metadata",
|
|
99
|
+
"attributes": [
|
|
100
|
+
{
|
|
101
|
+
"_comment": "this is metadata usage from LLM",
|
|
102
|
+
"accessor": lambda arguments: _helper.update_span_from_llm_response(
|
|
103
|
+
arguments["result"]
|
|
104
|
+
),
|
|
105
|
+
}
|
|
106
|
+
],
|
|
107
|
+
},
|
|
108
|
+
],
|
|
109
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from monocle_apptrace.instrumentation.common.wrapper import atask_wrapper, task_wrapper
|
|
2
|
+
from monocle_apptrace.instrumentation.metamodel.litellm.entities.inference import INFERENCE
|
|
3
|
+
|
|
4
|
+
LITELLM_METHODS = [
|
|
5
|
+
{
|
|
6
|
+
"package": "litellm.llms.openai.openai",
|
|
7
|
+
"object": "OpenAIChatCompletion",
|
|
8
|
+
"method": "completion",
|
|
9
|
+
"wrapper_method": task_wrapper,
|
|
10
|
+
"output_processor": INFERENCE
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"package": "litellm.llms.azure.azure",
|
|
14
|
+
"object": "AzureChatCompletion",
|
|
15
|
+
"method": "completion",
|
|
16
|
+
"wrapper_method": task_wrapper,
|
|
17
|
+
"output_processor": INFERENCE
|
|
18
|
+
}
|
|
19
|
+
]
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
from monocle_apptrace.instrumentation.common.constants import AGENT_REQUEST_SPAN_NAME, SPAN_SUBTYPES, SPAN_TYPES
|
|
1
2
|
from monocle_apptrace.instrumentation.metamodel.llamaindex import (
|
|
2
3
|
_helper,
|
|
3
4
|
)
|
|
4
5
|
|
|
5
6
|
AGENT = {
|
|
6
|
-
"type":
|
|
7
|
+
"type": SPAN_TYPES.AGENTIC_INVOCATION,
|
|
8
|
+
"subtype": SPAN_SUBTYPES.ROUTING,
|
|
7
9
|
"attributes": [
|
|
8
10
|
[
|
|
9
11
|
{
|
|
@@ -49,7 +51,8 @@ AGENT = {
|
|
|
49
51
|
}
|
|
50
52
|
|
|
51
53
|
AGENT_REQUEST = {
|
|
52
|
-
"type":
|
|
54
|
+
"type": AGENT_REQUEST_SPAN_NAME,
|
|
55
|
+
"subtype": SPAN_SUBTYPES.PLANNING,
|
|
53
56
|
"attributes": [
|
|
54
57
|
[
|
|
55
58
|
{
|
|
@@ -84,7 +87,8 @@ AGENT_REQUEST = {
|
|
|
84
87
|
}
|
|
85
88
|
|
|
86
89
|
TOOLS = {
|
|
87
|
-
"type":
|
|
90
|
+
"type": SPAN_TYPES.AGENTIC_TOOL_INVOCATION,
|
|
91
|
+
"subtype": SPAN_SUBTYPES.ROUTING,
|
|
88
92
|
"attributes": [
|
|
89
93
|
[
|
|
90
94
|
{
|
|
@@ -141,7 +145,8 @@ TOOLS = {
|
|
|
141
145
|
}
|
|
142
146
|
|
|
143
147
|
AGENT_DELEGATION = {
|
|
144
|
-
"type":
|
|
148
|
+
"type": SPAN_TYPES.AGENTIC_DELEGATION,
|
|
149
|
+
"subtype": SPAN_SUBTYPES.ROUTING,
|
|
145
150
|
"attributes": [
|
|
146
151
|
[
|
|
147
152
|
{
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
from monocle_apptrace.instrumentation.common.constants import SPAN_TYPES
|
|
1
2
|
from monocle_apptrace.instrumentation.metamodel.llamaindex import (
|
|
2
3
|
_helper,
|
|
3
4
|
)
|
|
4
5
|
from monocle_apptrace.instrumentation.common.utils import get_error_message, resolve_from_alias, get_llm_type, get_status, get_status_code
|
|
5
6
|
|
|
6
7
|
INFERENCE = {
|
|
7
|
-
"type":
|
|
8
|
+
"type": SPAN_TYPES.INFERENCE_FRAMEWORK,
|
|
8
9
|
"attributes": [
|
|
9
10
|
[
|
|
10
11
|
{
|