Prhub

#48034 [Rust Frontend] Tolerate whitespace before the outer brace in JSON tool-call parsers

原始 PR 作者 tahsintunan 合并时间 2026-07-15 19:03 文件变更 3 提交数 2 评论 2 代码增减 +105 / -2

执行摘要

Rust JSON 工具调用解析器容忍外层花括号前空白

Python's json.loads 能容忍参数对象闭花括号与外部闭花括号之间的空白,但 Rust 解析器未跳过该空白导致解析失败。PR 旨在实现与 Python 相同的行为。

值得关注其设计模式:通过最小化修改(增加 ws0)使 Rust 解析器与 Python 标准库行为对齐,对需跨语言保持一致的解析器设计有参考价值。

讨论亮点

无实质性讨论。PR 仅经 BugenZhao 审核批准,Claude bot 自动评论(来自 fork 的 PR 未自动审查)。

实现拆解

  1. 通用 JSON 解析器rust/src/parser/src/tool/json/mod.rs):在 tool_call_close_event 中将 literal("}") 替换为 seq!(_: ws0, _: literal("}")),在解析闭合花括号前先跳过可选空白。
  2. Llama JSON 解析器rust/src/parser/src/tool/json/llama.rs):对 tool_call_close_event 做相同修改,保持行为一致。
  3. 单元测试:为两个解析器分别新增测试函数(json_tool_call_tolerates_whitespace_before_outer_bracellama_tolerates_whitespace_before_outer_brace),验证完整输入与跨分块输入均能正确解析带空白的工具调用。
  4. 集成测试rust/src/chat/src/output/default/unified.rs):添加 unified_stream_parses_formatted_tool_call_without_latch 测试,确保在统一流解析器中格式化工具调用不会触发 parse-error latch,避免后续调用被转为文本。
文件 模块 状态 重要度
rust/src/parser/src/tool/json/mod.rs 解析器 modified 6.62
rust/src/parser/src/tool/json/llama.rs 解析器 modified 6.57
rust/src/chat/src/output/default/unified.rs 聊天模块 modified 6.45

关键符号

tool_call_close_event (mod.rs) tool_call_close_event (llama.rs) json_tool_call_tolerates_whitespace_before_outer_brace llama_tolerates_whitespace_before_outer_brace unified_stream_parses_formatted_tool_call_without_latch

关键源码片段

rust/src/parser/src/tool/json/mod.rs core-logic

通用 JSON 工具调用解析器的核心修复文件,修改 `tool_call_close_event` 以跳过外部花括号前空白,并添加对应的单元测试。

/// 解析 marker 包裹的 JSON 工具调用的闭合标记。
/// 现在在解析外部 `}` 前跳过可选空白,以与 Python json.loads 行为对齐。
fn tool_call_close_event(
    input: &mut JsonToolInput<'_>,
    config: JsonToolCallConfig,
) -> ModalResult<JsonToolCallEvent> {
    // seq! 组合子依次执行 ws0 ( 跳过空白 ) 和 literal("}") ( 匹配闭合花括号 )
    seq!(_: ws0, _: literal("}")).parse_next(input)?;    match config.delimiter {
        Some(delimiter) => alt((
            |input: &mut JsonToolInput<'_>| tool_call_end_event(input, config),
            |input: &mut JsonToolInput<'_>| tool_call_delimiter_event(input, delimiter),
        ))
        .parse_next(input),
        None => tool_call_end_event(input, config),
    }
}
rust/src/parser/src/tool/json/llama.rs core-logic

Llama JSON 工具调用解析器的核心修复文件,同样修改 `tool_call_close_event` 添加空白跳过,并添加回归测试。

/// 解析一个 Llama JSON 工具调用的外部闭合花括号。
/// 前加 ws0 以跳过可能存在的空白字符,保持与通用解析器行为一致。
fn tool_call_close_event(input: &mut JsonToolInput<'_>) -> ModalResult<LlamaJsonEvent> {
    seq!(_: ws0, _: literal("}"))
        .value(LlamaJsonEvent::ToolCallClose)
        .parse_next(input)
}

评论区精华

没有提炼出高价值讨论线程

当前评论区没有形成足够清晰的争议点或结论,后续有更多讨论时会体现在这里。

风险与影响

低风险。修改仅涉及工具调用解析闭环花括号处,在 literal("}") 前增加 ws0 跳过空白,不影响其他解析路径。流式 Partial 模式下 ws0 可能返回 Incomplete,但测试已覆盖跨分块场景,确认处理正确。

影响 Rust 前端的工具调用解析功能。用户使用 pretty-printed JSON 格式时不再解析失败,行为与 Python 一致。影响范围局限于 Rust 解析模块,不涉及其他组件。

边缘场景 流式兼容

关联 Issue

未识别关联 Issue

当前没有检测到明确关联的 Issue 链接,后续同步到相关引用后会出现在这里。

完整报告

参与讨论