fix: #3618731 Send input violations without the typed data root prefix
Closes #3618731 (closed)
Stacked on !24 (merged). The first commit is !24 (merged)'s; review the second. I'll rebase once !24 (merged) merges.
ToolApi::execute() built the input violation failure from (string) $violations. ConstraintViolationList::__toString() prefixes every violation with its root: a typed data class name, or a bare : when the root is empty, as in the issue. Two invalid list items read like this:
Tool plugin execution failed: Object(Drupal\Core\TypedData\Plugin\DataType\StringData):
Input fields: (item 0) This value should be of the correct primitive type.
Object(Drupal\Core\TypedData\Plugin\DataType\StringData):
Input fields: (item 1) This value should be of the correct primitive type.Each message already names its input and item, so this MR joins getMessage() from each violation, one per line, the way Tool API does for output violations since tool#3583057 (closed). The messages still go through PlainTextOutput::renderFromHtml() from !24 (merged).
Tool plugin execution failed:
Input fields: (item 0) This value should be of the correct primitive type.
Input fields: (item 1) This value should be of the correct primitive type.Testing
ToolApiFailureResultTest::testViolationMessagesOnePerLine sends two invalid items to mcp_server_test:multiple_string_input and checks the exact text. It fails without the fix with the output above.