@@ -419,12 +419,18 @@ def _extract_and_validate_structured_content(self, tool: DbTool, tool_result: "T
419419 """
420420 Extract structured content (if any) and validate it against ``tool.output_schema``.
421421
422+ Args:
423+ tool: The tool with an optional output schema to validate against.
424+ tool_result: The tool result containing content to validate.
425+ candidate: Optional structured payload to validate. If not provided, will attempt
426+ to parse the first TextContent item as JSON.
427+
422428 Behavior:
423429 - If ``candidate`` is provided it is used as the structured payload to validate.
424430 - Otherwise the method will try to parse the first ``TextContent`` item in
425431 ``tool_result.content`` as JSON and use that as the candidate.
426432 - If no output schema is declared on the tool the method returns True (nothing to validate).
427- - On successful validation the parsed value is attached to ``tool_result.structuredContent ``.
433+ - On successful validation the parsed value is attached to ``tool_result.structured_content ``.
428434 When structured content is present and valid callers may drop textual ``content`` in favour
429435 of the structured payload.
430436 - On validation failure the method sets ``tool_result.content`` to a single ``TextContent``
@@ -446,7 +452,7 @@ def _extract_and_validate_structured_content(self, tool: DbTool, tool_result: "T
446452 >>> service._extract_and_validate_structured_content(tool, r)
447453 True
448454
449- >>> # Valid candidate provided -> attaches structuredContent and returns True
455+ >>> # Valid candidate provided -> attaches structured_content and returns True
450456 >>> tool = type(
451457 ... "T",
452458 ... (object,),
@@ -455,7 +461,7 @@ def _extract_and_validate_structured_content(self, tool: DbTool, tool_result: "T
455461 >>> r = ToolResult(content=[])
456462 >>> service._extract_and_validate_structured_content(tool, r, candidate={"foo": "bar"})
457463 True
458- >>> r.structuredContent == {"foo": "bar"}
464+ >>> r.structured_content == {"foo": "bar"}
459465 True
460466
461467 >>> # Invalid candidate -> returns False, marks result as error and emits details
@@ -522,9 +528,9 @@ def _extract_and_validate_structured_content(self, tool: DbTool, tool_result: "T
522528
523529 # Attach structured content
524530 try :
525- setattr (tool_result , "structuredContent " , structured )
531+ setattr (tool_result , "structured_content " , structured )
526532 except Exception :
527- logger .debug ("Failed to set structuredContent on ToolResult" )
533+ logger .debug ("Failed to set structured_content on ToolResult" )
528534
529535 # Validate using jsonschema
530536 try :
@@ -543,10 +549,10 @@ def _extract_and_validate_structured_content(self, tool: DbTool, tool_result: "T
543549 except Exception :
544550 tool_result .content = [TextContent (type = "text" , text = str (details ))]
545551 tool_result .is_error = True
546- logger .debug (f"structuredContent validation failed for tool { getattr (tool , 'name' , '<unknown>' )} : { details } " )
552+ logger .debug (f"structured_content validation failed for tool { getattr (tool , 'name' , '<unknown>' )} : { details } " )
547553 return False
548554 except Exception as exc : # pragma: no cover - defensive
549- logger .error (f"Error extracting/validating structuredContent : { exc } " )
555+ logger .error (f"Error extracting/validating structured_content : { exc } " )
550556 return False
551557
552558 async def register_tool (
@@ -1201,7 +1207,7 @@ async def invoke_tool(self, db: Session, name: str, arguments: Dict[str, Any], r
12011207 filtered_response = extract_using_jq (result , tool .jsonpath_filter )
12021208 tool_result = ToolResult (content = [TextContent (type = "text" , text = json .dumps (filtered_response , indent = 2 ))])
12031209 success = True
1204-
1210+
12051211 # If output schema is present, validate and attach structured content
12061212 if getattr (tool , "output_schema" , None ):
12071213 valid = self ._extract_and_validate_structured_content (tool , tool_result , candidate = filtered_response )
@@ -1865,15 +1871,6 @@ async def _invoke_a2a_tool(self, db: Session, tool: DbTool, arguments: Dict[str,
18651871 content = [TextContent (type = "text" , text = f"A2A agent error: { error_message } " )]
18661872 result = ToolResult (content = content , is_error = True )
18671873
1868- # If output schema is present, validate and attach structured content
1869- if getattr (tool , "output_schema" , None ):
1870- # Prefer the raw response_data when available as the structured candidate
1871- candidate = response_data if isinstance (response_data , (dict , list )) else None
1872- try :
1873- valid = self ._extract_and_validate_structured_content (tool , result , candidate = candidate )
1874-
1875- except Exception :
1876- logger .debug ("Validation check failed for A2A result" )
18771874 # Note: Metrics are recorded by the calling invoke_tool method, not here
18781875 return result
18791876
0 commit comments