|
38 | 38 | tracer = trace.get_tracer('gcp.vertex.agent')
|
39 | 39 |
|
40 | 40 |
|
| 41 | +def _safe_json_serialize(obj) -> str: |
| 42 | + """Convert any Python object to a JSON-serializable type or string. |
| 43 | +
|
| 44 | + Args: |
| 45 | + obj: The object to serialize. |
| 46 | +
|
| 47 | + Returns: |
| 48 | + The JSON-serialized object string or <non-serializable> if the object cannot be serialized. |
| 49 | + """ |
| 50 | + |
| 51 | + try: |
| 52 | + # Try direct JSON serialization first |
| 53 | + return json.dumps( |
| 54 | + obj, ensure_ascii=False, default=lambda o: '<not serializable>' |
| 55 | + ) |
| 56 | + except (TypeError, OverflowError): |
| 57 | + return '<not serializable>' |
| 58 | + |
| 59 | + |
41 | 60 | def trace_tool_call(
|
42 | 61 | tool: BaseTool,
|
43 | 62 | args: dict[str, Any],
|
@@ -69,11 +88,14 @@ def trace_tool_call(
|
69 | 88 |
|
70 | 89 | if not isinstance(tool_response, dict):
|
71 | 90 | tool_response = {'result': tool_response}
|
72 |
| - span.set_attribute('gcp.vertex.agent.tool_call_args', json.dumps(args)) |
| 91 | + span.set_attribute( |
| 92 | + 'gcp.vertex.agent.tool_call_args', |
| 93 | + _safe_json_serialize(args), |
| 94 | + ) |
73 | 95 | span.set_attribute('gcp.vertex.agent.event_id', function_response_event.id)
|
74 | 96 | span.set_attribute(
|
75 | 97 | 'gcp.vertex.agent.tool_response',
|
76 |
| - json.dumps(tool_response), |
| 98 | + _safe_json_serialize(tool_response), |
77 | 99 | )
|
78 | 100 | # Setting empty llm request and response (as UI expect these) while not
|
79 | 101 | # applicable for tool_response.
|
@@ -159,10 +181,7 @@ def trace_call_llm(
|
159 | 181 | # Consider removing once GenAI SDK provides a way to record this info.
|
160 | 182 | span.set_attribute(
|
161 | 183 | 'gcp.vertex.agent.llm_request',
|
162 |
| - json.dumps( |
163 |
| - _build_llm_request_for_trace(llm_request), |
164 |
| - default=lambda o: '<not serializable>', |
165 |
| - ), |
| 184 | + _safe_json_serialize(_build_llm_request_for_trace(llm_request)), |
166 | 185 | )
|
167 | 186 | # Consider removing once GenAI SDK provides a way to record this info.
|
168 | 187 |
|
@@ -201,7 +220,7 @@ def trace_send_data(
|
201 | 220 | # information still needs to be recorded by the Agent Development Kit.
|
202 | 221 | span.set_attribute(
|
203 | 222 | 'gcp.vertex.agent.data',
|
204 |
| - json.dumps([ |
| 223 | + _safe_json_serialize([ |
205 | 224 | types.Content(role=content.role, parts=content.parts).model_dump(
|
206 | 225 | exclude_none=True
|
207 | 226 | )
|
|
0 commit comments