Description
XMLFormatParser — the format parser that handles the <seed:tool_call> / <answer> XML output style — builds its
fast-xml-parser instance with only ignoreAttributes: false:
// multimodal/gui-agent/action-parser/src/FomatParsers.ts:37-41
const builder = new XMLBuilder();
const parser = new XMLParser({
ignoreAttributes: false,
});
const object = parser.parse(text);
so fast-xml-parser's default parseTagValue: true still applies, and any tag whose text happens to look like a
number comes back as a JS number instead of a string.
Everything downstream is string-typed, so a numeric tag value is either dropped without a trace or reaches a
.trim() / .replace() call on a number:
FomatParsers.ts:63-70 — content: value as string pushes the raw value straight into finished.inputs. The cast
is unsound; this is where the number enters the typed layer.
ActionParserHelper.standardizeActionInputsFromXMLObject() (ActionParserHelper.ts:536-571) declares
Record<string, string> and branches only on typeof value === 'string' and
value && typeof value === 'object', so a numeric parameter tag matches neither and is discarded silently.
ActionParserHelper.standardizeAction() (ActionParserHelper.ts:313 and :335, roughInputStrValue.trim()) and
parseCoordinates() (:379-380, params.trim()) both declare string parameters.
serializeAction() (multimodal/gui-agent/shared/src/utils/actions.ts:14-44) has no numeric branch for
finished, so the action serializes as finished(unsupported).
multimodal/gui-agent/agent-sdk/src/ToolCallEngine.ts:163,167,185-187 stores the value into
finishMessage: string | null and then calls content.replace(...).
Reproduction
Measured on main (c2ad42e3) through the public entry point new DefaultActionParser().parsePrediction(...),
with @gui-agent/action-parser@0.3.0 and fast-xml-parser@4.5.3 as pinned by multimodal/pnpm-lock.yaml.
Input 1:
actions: {"type":"finished","inputs":{"content":42}}
rawActionStrings: ["finished(unsupported)"]
ToolCallEngine.ts:187 -> TypeError: content.replace is not a function
Input 2:
actions: {"type":"finished","inputs":{"content":7}} # leading zeros lost
rawActionStrings: ["finished(unsupported)"]
ToolCallEngine.ts:187 -> TypeError: content.replace is not a function
Input 3:
<seed:tool_call>
<function=type>
<parameter=content>123456</parameter>
</function>
</seed:tool_call>
actions: {"type":"type","inputs":{}} # the text to type is gone
rawActionStrings: ["type()"]
Input 4:
<think>42</think>
<answer>done</answer>
reasoningContent: "" # XMLBuilder().build(42) === "" (FomatParsers.ts:59),
# normalized to undefined at DefaultActionParser.ts:96
Expected
A model that answers with a bare number, or emits a numeric-looking parameter such as a verification code, should keep
its payload:
actions: {"type":"finished","inputs":{"content":"42"}}
rawActionStrings: ["finished(content='42')"]
Root cause / proposed fix
This is a single construction site. Setting parseTagValue: false on FomatParsers.ts:38-40 restores the string
contract that the rest of the pipeline already declares, and no conversion is needed anywhere downstream —
parseCoordinates() already runs its own Number.parseFloat on the string it receives.
Nothing pins the current coercing behaviour. Searching the whole multimodal/ tree for an XML tag whose text is a bare
number (an answer, a parameter=content, a duration, or anything else) matches no existing fixture or test, and none
of the 141 currently open PRs modifies anything under multimodal/gui-agent/action-parser/.
Environment
- Package:
@gui-agent/action-parser@0.3.0 (multimodal/gui-agent/action-parser)
- Branch:
main at c2ad42e3
- Node 24, pnpm workspace,
fast-xml-parser@4.5.3
Description
XMLFormatParser— the format parser that handles the<seed:tool_call>/<answer>XML output style — builds itsfast-xml-parserinstance with onlyignoreAttributes: false:so
fast-xml-parser's defaultparseTagValue: truestill applies, and any tag whose text happens to look like anumber comes back as a JS
numberinstead of astring.Everything downstream is string-typed, so a numeric tag value is either dropped without a trace or reaches a
.trim()/.replace()call on a number:FomatParsers.ts:63-70—content: value as stringpushes the raw value straight intofinished.inputs. The castis unsound; this is where the number enters the typed layer.
ActionParserHelper.standardizeActionInputsFromXMLObject()(ActionParserHelper.ts:536-571) declaresRecord<string, string>and branches only ontypeof value === 'string'andvalue && typeof value === 'object', so a numeric parameter tag matches neither and is discarded silently.ActionParserHelper.standardizeAction()(ActionParserHelper.ts:313and:335,roughInputStrValue.trim()) andparseCoordinates()(:379-380,params.trim()) both declarestringparameters.serializeAction()(multimodal/gui-agent/shared/src/utils/actions.ts:14-44) has no numeric branch forfinished, so the action serializes asfinished(unsupported).multimodal/gui-agent/agent-sdk/src/ToolCallEngine.ts:163,167,185-187stores the value intofinishMessage: string | nulland then callscontent.replace(...).Reproduction
Measured on
main(c2ad42e3) through the public entry pointnew DefaultActionParser().parsePrediction(...),with
@gui-agent/action-parser@0.3.0andfast-xml-parser@4.5.3as pinned bymultimodal/pnpm-lock.yaml.Input 1:
Input 2:
Input 3:
Input 4:
Expected
A model that answers with a bare number, or emits a numeric-looking parameter such as a verification code, should keep
its payload:
Root cause / proposed fix
This is a single construction site. Setting
parseTagValue: falseonFomatParsers.ts:38-40restores the stringcontract that the rest of the pipeline already declares, and no conversion is needed anywhere downstream —
parseCoordinates()already runs its ownNumber.parseFloaton the string it receives.Nothing pins the current coercing behaviour. Searching the whole
multimodal/tree for an XML tag whose text is a barenumber (an
answer, aparameter=content, a duration, or anything else) matches no existing fixture or test, and noneof the 141 currently open PRs modifies anything under
multimodal/gui-agent/action-parser/.Environment
@gui-agent/action-parser@0.3.0(multimodal/gui-agent/action-parser)mainatc2ad42e3fast-xml-parser@4.5.3