Files
zWorkFlow/tests
Belugary eba9a9d4cd feat: 解析微信位置消息 (base_type=48) + decode_location MCP 工具 (#124)
位置消息 (base_type=48) 老逻辑命中 _format_message_text 的 elif base_type != 1 兜底, 以 raw XML 形态进 get_chat_history. 一条 location XML 平均 12-15 个 attr (poiBusinessHour / poiPhone / adcode / buildingId / floorName / infourl / fromusername / maptype / scale / version 等), LLM context 里堆机器字段而看不到 "用户分享了哪里" 的核心语义.

修复 (双层模式, 跟 #83 namecard / #85 transfer / #100 refer 一致):
- _extract_location_info: 解析 <location> 节点为 dict, 全部 17 个 attr + lat/lng (x/y 数值化) + category_top
- _is_location_poiname_placeholder: 检测客户端在用户手扔图钉时的占位符 [位置] / [Location]
- _format_location_text: 单行渲染只挑 3 个信号 (poiCategoryTips 主类 → 前缀, poiname, label), fallback chain
- decode_location MCP 工具: 给 LLM 拿全部字段 (POI id / 电话 / 营业时间 / 价格 / 城市 / 区划码 / 经纬度), 兼容跨分片场景

字段语义基于 1411 条真实样本统计指导分类决策 (修了 #121 自撤的核心教训 — 没逐字段过语义就套 #83 模板). 关键差异:
- poiid (#121 错丢) → 80% 出现率, deeplink 种子, 结构化保留
- infourl (#121 没充分论证就丢) → 1411 样本 0% 非空, render 丢 / structured 防御性留
- poiCategoryTips (#121 未识别) → 渲染前缀
- poiPhone (#121 未识别) → 22% 非空商家电话, 结构化保留
- poiname=[位置] 占位符 (#121 未处理) → 检测并 fallback 到 label

测试: tests/test_location_message.py 18 case, 5 个全合成 fixture (POI 名/地址/城市/坐标/电话/poiid 全部占位符, 不绑定任何真实地理数据). 18/18 全过. baseline 309 → 327.

Closes #121
2026-05-26 16:54:43 +08:00
..