Skip to content

Conversation

@roomote
Copy link
Contributor

@roomote roomote bot commented Jan 27, 2026

Related GitHub Issue

Closes: #11011

Roo Code Task Context (Optional)

N/A

Description

Some API providers (like kie.ai with Gemini 3 Pro) do not fully support native function calling and instead output XML-formatted tool calls in text responses. Previously, these were rejected with an error message. This PR adds support for parsing these XML tool calls and executing them as a fallback.

Key Implementation Details:

  1. New XmlToolCallParser class (src/core/assistant-message/XmlToolCallParser.ts):

    • Parses XML tool calls from text content (e.g., <read_file><path>src/file.ts</path></read_file>)
    • Converts them to the ToolUse format used by the existing tool execution infrastructure
    • Generates synthetic tool call IDs (toolu_*) for native protocol compatibility
    • Maintains document order when multiple tool calls are present
    • Handles CDATA sections and multi-line content
  2. Modified presentAssistantMessage (src/core/assistant-message/presentAssistantMessage.ts):

    • When XML tool markup is detected in a text block (non-partial), parse it instead of showing an error
    • Inject parsed tool uses into assistantMessageContent for normal execution
    • Display any remaining non-tool text to the user

Design Choices:

  • Only parse XML on complete (non-partial) blocks to avoid issues during streaming
  • Preserve existing behavior for native tool calling - XML parsing is only a fallback
  • Tools are extracted in document order to maintain intended execution sequence

Test Procedure

  1. Unit Tests Added: 32 comprehensive tests for XmlToolCallParser:

    • Detection of XML tool markup
    • Parsing of all supported tools (read_file, execute_command, write_to_file, etc.)
    • Multiple tool calls in sequence
    • Edge cases (empty params, whitespace, CDATA, code blocks)
    • Tool alias resolution
  2. Test Commands:

    cd src && npx vitest run core/assistant-message/__tests__/XmlToolCallParser.spec.ts
  3. Manual Testing: Configure an OpenAI-compatible provider that outputs XML tool calls (like kie.ai) and verify tools execute correctly.

Pre-Submission Checklist

  • Issue Linked: This PR is linked to an approved GitHub Issue (see "Related GitHub Issue" above).
  • Scope: My changes are focused on the linked issue (one major feature/fix per PR).
  • Self-Review: I have performed a thorough self-review of my code.
  • Testing: New and/or updated tests have been added to cover my changes (if applicable).
  • Documentation Impact: I have considered if my changes require documentation updates (see "Documentation Updates" section below).
  • Contribution Guidelines: I have read and agree to the Contributor Guidelines.

Screenshots / Videos

N/A - No UI changes

Documentation Updates

  • No documentation updates are required.

Additional Notes

This addresses the feedback from @kangarko in issue #11011 who suggested adapting to the Gemini 3 Pro scheme that kie.ai uses, rather than just improving error messages (which was done in PR #11012).

Get in Touch

N/A - Bot submission

Some API providers (like kie.ai with Gemini 3 Pro) do not fully support
native function calling and instead output XML-formatted tool calls in
text responses. This change adds support for parsing these XML tool calls
and executing them as a fallback.

Changes:
- Add XmlToolCallParser to parse XML tool calls from text content
- Modify presentAssistantMessage to detect and parse XML tool calls
  instead of rejecting them with an error
- Add comprehensive tests for the XmlToolCallParser

Fixes #11011
@roomote
Copy link
Contributor Author

roomote bot commented Jan 27, 2026

Rooviewer Clock   See task on Roo Cloud

Review complete. Found 2 issues to address:

  • parseXmlToolCalls should strip code blocks before parsing (inconsistent with containsXmlToolMarkup which does strip them)
  • Dead code: run_slash_command case in buildNativeArgs is unreachable since the tool is not in XML_TOOL_NAMES

Mention @roomote in a comment to request specific changes to this pull request or fix all unresolved issues.

Comment on lines +95 to +119
public static parseXmlToolCalls(text: string): XmlToolCallParseResult {
// Collect all matches with their positions to maintain document order
const matches: Array<{
position: number
fullMatch: string
innerContent: string
toolName: string
}> = []

// Find all tool matches across all tool names
for (const toolName of XML_TOOL_NAMES) {
// Pattern to match complete tool tags: <tool_name>...</tool_name>
// Uses a non-greedy match for content to handle multiple tool calls
const regex = new RegExp(`<${toolName}>([\\s\\S]*?)</${toolName}>`, "gi")

let match
while ((match = regex.exec(text)) !== null) {
matches.push({
position: match.index,
fullMatch: match[0],
innerContent: match[1],
toolName,
})
}
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unlike containsXmlToolMarkup() which strips code blocks before detection, this method parses XML tool calls from the raw text without stripping code blocks first. When text contains both a code block with example tool calls AND an actual tool call outside, both will be parsed and executed. For example, if the model shows an example <read_file> in a code block while also making an actual <read_file> call, both would be extracted. Consider stripping code blocks before parsing, similar to the detection logic.

Fix it with Roo Code or mention @roomote and request a fix.

Comment on lines +381 to +390
case "run_slash_command": {
const command = get("command")
if (command !== undefined) {
return {
command,
args: get("args"),
}
}
return undefined
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This case is unreachable because run_slash_command is not included in XML_TOOL_NAMES. Since the parser only processes tools from that list, this handler will never execute. Consider removing this dead code or adding run_slash_command to XML_TOOL_NAMES if XML parsing for this tool is intended.

Fix it with Roo Code or mention @roomote and request a fix.

@roomote
Copy link
Contributor Author

roomote bot commented Jan 27, 2026

Closing in favor of PR #11014, which contains the proper fix with the openAiStrictToolMode setting. This PR (XML fallback parsing) was an intermediate attempt before understanding the root cause.

@roomote roomote bot closed this Jan 27, 2026
@github-project-automation github-project-automation bot moved this from New to Done in Roo Code Roadmap Jan 27, 2026
@github-project-automation github-project-automation bot moved this from Triage to Done in Roo Code Roadmap Jan 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

[BUG] Gemini 3 error on kie.ai

1 participant