fix(lark): render bold titles before Unicode symbols - #5663
Conversation
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
|
This pull request has merge conflicts with Choose the remote for the base repository, not an out-of-date fork. git fetch upstream
git rebase upstream/main
# Resolve each conflict, git add the resolved files, then git rebase --continue.
git push --force-with-lease origin HEADFor a same-repository clone whose Keep the DCO |
loopx-agent
left a comment
There was a problem hiding this comment.
Reviewer: model_agent; model=gpt-6.1-sol; provider=OpenAI; declaration=runtime_reported; effort=xhigh
Approval conclusion (author-owned PR; GitHub blocks formal self-approval)
源码结论 APPROVE,绑定 head c030089de378efaa5522415899088534e13391d8。没有新增阻塞性代码问题;当前主干文档存在内容冲突,真实飞书渲染和安装态采用不由本次源码结论认证。
动机
通过飞书 Markdown 消息阅读回答的用户。标题右括号紧接全角分隔符时,旧版保留会失效的加粗边界;新版只移动标记和尾部标点,保留所有可见文字。已验证原答案不变、预览与回读一致、纯文本路径保持原行为。不增加解析器、改写原答案或扩展权限,也不证明所有飞书客户端的实际渲染。
这里修的是发送给特定 provider 的展示结构。用户原来的文字、代码及链接应当保持原样;把标题显示问题改成修改持久答案,会让后来读取结果的人拿到不同内容,因此不是可接受的修复方式。
真实飞书客户端的渲染与安装态采用仍未独立验收;本结论限当前源码切片。
改动思路
沿用已有 Lark 强调标记兼容处理:在确定的成对加粗边界处,只有尾部标点后接字词或非 ASCII 符号时,才把尾部标点移到加粗范围之外。现有 opaque 扫描继续保护 inline/fenced code、转义和链接目的地。发送、dry-run preview 与 provider 回读都经过同一归一化 owner;原始答案是输入,不是格式化结果的写回目标。
没有新增 Markdown parser、依赖、状态 owner、执行权限或 CLI。替代方案“另写解析器”会增加维护负担;保持现状则留下可复现的 provider 边界差异。在已有局部 scanner 内扩展一个 Unicode 分类条件,是更小且可独立回滚的修复。
具体改动
参考 loopx/extensions/lark/docs/realtime-conversation-readiness.md,读取的不可变版本 896cdf1278ab2358260f4b5c59b211baa3a525ac。原文 Product boundary 对 Session、audience、grants 的保留,在独立 canonical 文件读回中验证;Interactive experience to retain 的 provider 仅呈现 canonical 结果、不新增执行权得到满足;Qualification before switching 的真实安装态 provider/host 行程仍 deferred,本次不会把测试 double 当作飞书渲染资格。
关键代码讲解
_normalize_strong_line扩展既有 alphanumeric 条件,新增“非 ASCII 且 Unicode category 为 S”的分支。全角竖线和 emoji 进入修复;ASCII 符号、Unicode P 标点和普通合法边界保留。lark_markdown_post_content仍输出原有单个 md-node post,使用共享 normalizer,未改变 canonical response、locale schema 或附件语义。lark_markdown_readback_matches和 preview 检查共同使用归一化结果,拒绝 plaintext lookalike、内容变化、额外节点或意外 mention;修复并没有放松验证边界。
三文件全差异 +32/-7,包括现有 formatter、既有测试及 provider readiness 说明。58 项 formatter/reply-format/delivery 源测试独立通过;不是沿用作者的发布或 live 测试声明。
对主干的风险
最强风险是辅助 normalizer 通过而真实发送路径改变纯文本、代码或持久原答案。相同四例 fixture 经实际 reply_lark_event_inbox 与真实文件 inbox:旧 base 的 Unicode/emoji 两例未修复,head 两例均满足独立预期;content_format=text 和 opaque code 两例在两个版本均保持原文本。dry-run、send、回读使用同一 post,重复调用保留同一 idempotency key 和参数,不声称 provider double 证明外部网络去重。
另外使用 ordinary Chat 的真实 localhost HTTP、模型宿主 double 和原生文件 Turn,先持久化原 Markdown,再构造 post、重新创建 store 读回。base/head 各八个持久文件哈希不变,canonical answer 原样,均仅一次模型 Turn。九组更细的反事实覆盖 ASCII 符号、Unicode P、inline/fenced code、URL、unmatched 与已有 word-boundary 修复;错误类型的回读被拒绝。
Ruff、diff hygiene、语义 advisory 与全树 semantic smoke 通过;配置的 19 文件 kernel Mypy,以及 formatter 的 imports-skip 单文件 Mypy 均通过。无新共享状态 vocabulary,Unicode S 是 provider-local formatting 条件,不是生命周期分类。当前规则没有增加隐藏默认行为:Markdown selector 的 text 分支仍是旧行为,文档显式说明 provider 兼容和 live qualification 的边界。CI 未查询、轮询或等待。误写测试文件名的首次调用未收集测试,修正到实际仓库路径后完整 58 项通过;这是评审调用错误,没有隐藏源测试失败。
merge-tree 与平台都表明当前 readiness 文档冲突。格式化代码本身能自动合入不能替代完整集成;维护者解决冲突后应审阅新的完整 head,并保留主干已有的回复生命周期改动。
我的整体评价
这是一项 justified_increment:long_horizon 保持 canonical result、Session 和 delivery authority;user_experience 保持设置、文字、身份及恢复路径,source post 的结构修复得到验证。实际客户端的加粗效果是 intended improvement,未被本评审伪装为 independently verified rendering;如要切换 provider 或发布,就仍要过原有 live gate。
相邻边界的未来重构检查认为暂无必要增加模块:sender、preview、readback 已共同使用一个 formatter,当前小条件比引入完整 parser 更合适。原 schema、可见文字、代码/link opacity 与 plaintext selector 均有反例覆盖。批准只绑定当前 head;文档冲突解决、真实 provider journey 和安装态采用是后续各自证据边界。
English verdict: APPROVE - c030089; bounded Unicode strong-boundary repair preserves canonical Markdown, plaintext and opaque regions. Independently validated 58 relevant tests, paired public inbox counterfactuals and canonical file readback; main documentation conflicts and actual Feishu rendering remain separate qualification holds.
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
There was a problem hiding this comment.
Reviewer: model_agent; model=GPT-6; provider=OpenAI; declaration=self_reported
Approval conclusion (author-owned PR; GitHub blocks formal self-approval)
Exact head: 5663@7eb956a1a56f696fdbcc3be29221bdf79203452e; immutable base: 2c381bcd4b536d1ddf6487d33f11c59816a050e6.
源码结论 APPROVE,仅绑定完整集成 head 7eb956a1a56f696fdbcc3be29221bdf79203452e。作者账号的自评使用 COMMENTED;这不是 GitHub 的正式审批。此前 c030089 的评审不用于批准新 head。
动机
飞书标题中,右括号后紧接全角竖线或 emoji 时,加粗标记可能原样显示。本次修复已存在的 provider 展示边界,使发送、预览和读回共用同一结果;用户原文、持久答案、身份及恢复路径保持原有语义。实际客户端的视觉效果仍需安装态验证。
适用用户:通过飞书 Markdown 消息阅读回答的用户。 标题右括号紧接全角分隔符时,旧版保留会失效的加粗边界;新版只移动标记和尾部标点,保留所有可见文字。 已验证原答案不变、预览与回读一致、纯文本路径保持原行为。 不增加解析器、改写原答案或扩展权限,也不证明所有飞书客户端的实际渲染。 真实飞书客户端的渲染与安装态采用仍未独立验收;本结论限当前源码切片。
改动思路
沿用已有 bounded strong-marker scanner,仅把尾部标点后的匹配条件扩展为非 ASCII Unicode S。代码块、inline code、转义、链接目的地、不成对与歧义标记保持 opaque。新增解析器或回答改写管线会增加维护成本;目前一个共享 formatter 已覆盖 sender、preview 和 readback,无需再加框架。
具体改动
三文件完整差异 +32/-7:formatter 11 增/4 删、原有回归测试11增/3删、readiness说明10行。正常合入当前 main 后,保留主干的 timed_out 结果对账段落和本 PR 的展示说明;formatter/test blob 与旧已审 head 一致,但仍重新检查完整集成 head。
依据合入前不可变 readiness 契约:Product boundary 的 Session/Turn、受众、grants 得到保留;Interactive experience to retain 的 provider 只呈现 canonical facts 得到验证;Qualification before switching 的真实宿主与飞书行程仍 deferred,测试 double 不证明 live qualification。
_normalize_strong_line扩展原 alphanumeric 条件,明确排除 ASCII symbol 和 Unicode P;只移动分隔标记及尾部标点,保留可见文字。lark_markdown_post_content保持原单 md-node schema;provider projection 不写回 canonical answer。lark_markdown_readback_matches与 preview 使用同一归一化,继续拒绝 plaintext lookalike、改动内容、额外节点及意外 mention。
对主干的风险
最强反例是 helper 测试通过,但实际发送改写代码、纯文本或持久答案。独立相同 fixture 在当前 base 2c381bcd4b536d1ddf6487d33f11c59816a050e6 与完整 head 7eb956a1a56f696fdbcc3be29221bdf79203452e 经过真实 reply_lark_event_inbox/文件 inbox/provider double:base Unicode/emoji 两例不满足预定修复,head 四例均通过;text 与 opaque code 两个对照保持原文。重复调用保留相同 idempotency key 和参数,不声称 double 证明外部发送去重。
另经普通 Chat 实际 localhost HTTP、模型宿主 double、真实持久 Turn,再构造 post 并重新创建 store 读回:两个版本均只有一次模型 Turn、八个文件保持原样、原始答案哈希不变、没有 Goal authority;伪造 text 类型回读被拒绝。当前私聊原有 Markdown 默认保留,显式 text bypass 仍通过;这里没有把“text 默认关闭”当作前提。
完整 head 的58项相关测试、Ruff、formatter 单文件 Mypy 和配置的19文件 kernel Mypy 均通过;native premerge 5直接+11选定检查通过,0失败/警告/advisory失败,包含语义 vocabulary 与公开边界检查。无新增状态 vocabulary、CLI、迁移或权限规则。CI 未查询或等待;完整仓库 pytest、真实飞书显示与安装切换未验收。首次测试文件名/隔离源码 fixture 依赖调用错误均修正后重跑成功,没有隐藏产品测试失败。
我的整体评价
这是必要且有界的增量。long_horizon 保留原答案和 delivery authority;user_experience 的文字、设置、身份、恢复路径保持,provider post 修复得到独立验证,实际视觉改善仍需 live 证据。当前文档冲突已经解决,新的完整 head 已重新验证;没有新增阻塞性发现。回滚仅需撤销小型 formatter 修改,原始答案始终保留。批准源码收尾不等于 Bot 业务消息全部完成。
English verdict: APPROVE — 7eb956a. The bounded Unicode strong-boundary fix preserves visible text, plaintext/code opacity and canonical Session/Turn authority. Current integrated head passes58 relevant tests, paired public inbox and durable canonical counterfactuals, and native quality checks. Actual Feishu rendering and installed promotion remain separate unverified gates.
Lark post replies can display literal
**around a title when its closing bracket is followed immediately by a fullwidth separator. Extend the existing emphasis compatibility fix to non-ASCII symbols, preserving all visible text and the canonical answer. Code, URLs, ASCII punctuation, Session/grants and delivery identity retain their existing behavior; preview/readback use the same normalized post.This stays in the existing Python Lark presentation adapter. No new parser, dependency, execution owner or response schema; frontend and CLI rendering are unchanged. Update the existing realtime-readiness guide to describe this provider boundary.
Validation on head
c030089de378efaa5522415899088534e13391d8, base896cdf1278ab2358260f4b5c59b211baa3a525ac:Runtime/product change: leave merge to the maintainer and retain CI/review gates.