Source code for microsoft.opentelemetry.a365.core.enricher_utils
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
"""Shared utilities for A365 span enrichers.
Provides content extraction helpers used by framework-specific enrichers
(Agent Framework, Semantic Kernel, LangChain) to convert structured OTel
messages to plain content arrays before A365 export.
"""
from __future__ import annotations
import json
def _extract_text_from_message(msg: dict, role_filter: str | None) -> list[str]:
"""Extract text content strings from a single structured message dict."""
role = msg.get("role", "")
if role_filter and role != role_filter:
return []
parts = msg.get("parts")
if not parts or not isinstance(parts, list):
return []
return [
part["content"] for part in parts if isinstance(part, dict) and part.get("type") == "text" and "content" in part
]
[docs]
def extract_content_as_string_list(messages_json: str, role_filter: str | None = None) -> str:
"""Extract content values from messages JSON and return as JSON string list.
Handles the OTel structured message format with ``"parts"`` arrays.
Only extracts text content, ignoring tool_call and tool_call_response parts.
Args:
messages_json: JSON string of messages.
role_filter: If provided, only extract content from messages with this role.
Returns:
JSON string containing only the text content values as an array,
or the original string if parsing fails.
"""
try:
messages = json.loads(messages_json)
if isinstance(messages, list):
# If already a plain list of strings, return as-is
if all(isinstance(item, str) for item in messages):
return messages_json
contents = []
for msg in messages:
if isinstance(msg, dict):
contents.extend(_extract_text_from_message(msg, role_filter))
return json.dumps(contents)
return messages_json
except (json.JSONDecodeError, TypeError):
return messages_json
[docs]
def extract_input_content(messages_json: str) -> str:
"""Extract text content from user messages only."""
return extract_content_as_string_list(messages_json, role_filter="user")
[docs]
def extract_output_content(messages_json: str) -> str:
"""Extract only assistant text content from output messages."""
return extract_content_as_string_list(messages_json, role_filter="assistant")