Description
With basic observability enabled, I created an agent (FoundryChatClient) that uses the code_interpreter_tool via OpenTelemetry. When running the agent, a JSON serialization error happened saying it couldn't serialize the OOTB tool.
To fix it, I had to create a method to patch the serialization, but it should've worked OOTB:
def patch_code_interpreter_otel_definition() -> None:
"""Avoid SDK telemetry serialization failures for Foundry code interpreter tools."""
import agent_framework.observability as observability
if getattr(observability, "_code_interpreter_otel_patch_applied", False):
return
original = observability._otel_definition_from_mapping
def _otel_definition_from_mapping(raw: Mapping[str, Any]) -> dict[str, Any] | None:
if raw.get("type") == "code_interpreter":
return {"type": "code_interpreter", "name": "code_interpreter"}
return original(raw)
observability._otel_definition_from_mapping = _otel_definition_from_mapping
setattr(observability, "_code_interpreter_otel_patch_applied", True)
Code Sample
####### CLIENT FILE - JUST INSTANTIATES THE CLIENT
@asynccontextmanager
async def foundry_client() -> AsyncGenerator[FoundryChatClient, None]:
"""Create a Foundry client for one chat session."""
async with AzureCliCredential() as credential:
client = FoundryChatClient(
credential=credential, # connection via Managed Id (RBAC), safer than keys
project_endpoint=os.getenv("FOUNDRY_PROJECT_ENDPOINT"),
model=os.getenv("FOUNDRY_MODEL"),
)
# configure observability/tracing on Azure AI Foundry, integrated with Azure Monitor
await client.configure_azure_monitor(
enable_live_metrics=os.getenv("ENABLE_LIVE_METRICS", "False").lower() == "true",
enable_sensitive_data=os.getenv("ENABLE_SENSITIVE_DATA", "False").lower() == "true",
)
yield client
#### AGENT FILE, LEVERAGING THE CLIENT
class AgentV1(AgentBase):
"""Agent v1 - all tools available and freedom to choose any tool"""
def __init__(self, chat_client: FoundryChatClient, name: str = "agent_v1") -> None:
"""Initialize the agent."""
super().__init__(chat_client=chat_client, name=name)
def get_agent(self) -> Agent:
"""Get the agent instance."""
tools: list[Any] = [
get_post_text,
get_pre_text,
get_table,
self.chat_client.get_code_interpreter_tool(), # sandboxed code interpreter defaulting to jupyter container
]
return Agent(
client=self.chat_client,
name=self.name,
instructions=self.instructions,
description="Agent v1 - all tools available and freedom to choose any tool",
tools=tools,
context_providers=[InMemoryHistoryProvider('memory')],
default_options=FoundryChatOptions(
prompt_cache_retention="24h", # prompt caching for 24h, lowers costs
tool_choice="auto",
# parallel tool calls when possible, mapped to Agents SDK parallel_tool_calls
allow_multiple_tool_calls=True,
reasoning={
'effort': 'medium',
'summary': 'auto'
},
max_tokens=int(os.getenv("FOUNDRY_MAX_TOKENS", 8000)),
)
)
async def run(
self,
message: str,
session: AgentSession,
doc: dict[str, Any],
) -> str:
"""Run the agent, default implementation."""
response: AgentResponse[Result] = await self.get_agent().run(
session=session,
messages=message,
function_invocation_kwargs=doc, # doc in run context for tool calls with no LLM processing
options={"response_format": Result}, # structured outputs for more accurate results
)
return response.text
On main.py, I have (
enable_console_exporters=os.getenv("ENABLE_CONSOLE_EXPORTERS", "False").lower() == "true",
)
And a call to `run()`
When calling `AgentV1.run(...)` the error happened.
Error Messages / Stack Traces
File "/mnt/scratch/repos/ignawacc/ignawacc/.venv/lib/python3.12/site-packages/agent_framework/_agents.py", line 1717, in run
return super_run(
^^^^^^^^^^
File "/mnt/scratch/repos/ignawacc/ignawacc/.venv/lib/python3.12/site-packages/agent_framework/_middleware.py", line 1371, in run
return super().run( # type: ignore[misc, no-any-return]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/mnt/scratch/repos/ignawacc/ignawacc/.venv/lib/python3.12/site-packages/agent_framework/observability.py", line 2061, in run
return self._trace_agent_invocation(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/mnt/scratch/repos/ignawacc/ignawacc/.venv/lib/python3.12/site-packages/agent_framework/observability.py", line 1770, in _trace_agent_invocation
attributes = _get_span_attributes(
^^^^^^^^^^^^^^^^^^^^^
File "/mnt/scratch/repos/ignawacc/ignawacc/.venv/lib/python3.12/site-packages/agent_framework/observability.py", line 2495, in _get_span_attributes
result = transform_func(value) if transform_func else value
^^^^^^^^^^^^^^^^^^^^^
File "/mnt/scratch/repos/ignawacc/ignawacc/.venv/lib/python3.12/site-packages/agent_framework/observability.py", line 2460, in <lambda>
lambda tools: json.dumps(tools_dict, ensure_ascii=False) if (tools_dict := _tools_to_dict(tools)) else None,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.12/json/__init__.py", line 238, in dumps
**kw).encode(obj)
^^^^^^^^^^^
File "/usr/lib/python3.12/json/encoder.py", line 200, in encode
chunks = self.iterencode(o, _one_shot=True)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.12/json/encoder.py", line 258, in iterencode
return _iterencode(o, 0)
^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.12/json/encoder.py", line 180, in default
raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type AutoCodeInterpreterToolParam is not JSON serializable
Package Versions
agent-framework>=1.10.0
Python Version
Python 3.12
Additional Context
No response
Description
With basic observability enabled, I created an agent (
FoundryChatClient) that uses thecode_interpreter_toolvia OpenTelemetry. When running the agent, a JSON serialization error happened saying it couldn't serialize the OOTB tool.To fix it, I had to create a method to patch the serialization, but it should've worked OOTB:
Code Sample
Error Messages / Stack Traces
Package Versions
agent-framework>=1.10.0
Python Version
Python 3.12
Additional Context
No response