Skip to content

fix(core): render Feishu AskUserQuestion as flat action rows (fixes #1658) - #1679

Open
chenhg5 wants to merge 1 commit into
mainfrom
agent/cc-connect/t-20260813-hu9tx6-feishu-askq-1658
Open

fix(core): render Feishu AskUserQuestion as flat action rows (fixes #1658)#1679
chenhg5 wants to merge 1 commit into
mainfrom
agent/cc-connect/t-20260813-hu9tx6-feishu-askq-1658

Conversation

@chenhg5

@chenhg5 chenhg5 commented Aug 13, 2026

Copy link
Copy Markdown
Owner

Summary

Fix #1658: Feishu + pi agent's AskUserQuestion card button clicks never dispatched on Feishu mobile, and were unreliable on desktop. Permission cards (cmd: actions) worked normally — the reporter's log showed zero card-action entries during the 08:00-08:25 ask_user_question test window while cmd= entries for permission cards appeared as expected.

Root cause

sendAskQuestionPrompt (single-select path) rendered each option as a CardListItem, which the Feishu renderer serialises as a column_set with the description in a weighted column (weight:5) and the click button in an auto column. On Feishu mobile the button column is clipped/non-interactive, and even on desktop this nested layout doesn't reliably dispatch click events.

Fix

Mirror the permission-card pattern (which the reporter confirmed dispatches reliably): each option becomes a markdown description line followed by a flat CardActions row with a single button. The askq:qIdx:optIdx value plus askq_label / askq_question extras are preserved so the Feishu callback handler still renders the post-answer card unchanged.

The Note line that nudges users toward numeric / text fallbacks is kept in place as a defensive fallback.

Sibling

PR #1677 (issue #1659, pi ≥ 0.84.0 tool-call drop) — same reporter (Po1nt9), same pi + Feishu setup. Both fixes ship together so the pi + Feishu flow is fully usable end-to-end.

Changes

  • core/engine.go — switch single-select AskUserQuestion rendering from cb.ListItemBtnExtra(...) to cb.Markdown("**desc**") + cb.Buttons(CardButton{...})
  • core/engine_test.go — new regression test asserting: 3 CardActions rows, 3 askq buttons, no CardListItem, and that every button carries askq_label + askq_question extras

Validation

  • go test -race -count=1 ./core/ — PASS (48.7s)
  • go test -race -count=1 ./agent/pi/ — PASS (7.0s)
  • go test -race -count=1 ./platform/feishu/ — PASS (33.3s)
  • gofmt -l — clean
  • go vet ./core/... — clean
  • go build -tags no_web ./... — clean
  • golangci-lint run --new-from-rev origin/main ./core/... — 0 issues

Risks

  • Card layout shift: cards now show each option as a two-line row (description + button row) instead of one row with description-on-left + button-on-right. Same data, slightly different visual rhythm. This is intentional — the previous layout doesn't dispatch on mobile.
  • Backward compat for other AskUserQuestion callers: isAskQuestion (engine.go) still treats AskUserQuestion and extension_select the same way and routes through the same sendAskQuestionPrompt. pi's forwardSelect carries askq_label / askq_question via Extra exactly as before.
  • No regression to permission cards: those use CardActions directly, not via this path.

…1658)

The single-select AskUserQuestion card was rendered as a column_set
row per option, with the option description in a weighted column and
the click button in an 'auto' column. On Feishu mobile the button
column was clipped or non-interactive, and even on desktop the
column_set > column > button pattern was reported as unreliable —
Po1nt9's log during the 08:00-08:25 test window showed zero
card-action entries for ask_user_question cards while permission
cards (which use a flat action row, tag:"action") dispatched
normally.

Mirror the permission-card layout: each option becomes a markdown
description followed by a flat CardActions row with a single button.
The askq:qIdx:optIdx value plus askq_label/askq_question extras are
preserved so the Feishu callback handler still renders the
post-answer card. The Note line that already nudges users toward
numeric / text fallbacks stays in place.

Sibling fix to PR #1677 (issue #1659, pi 0.84.0+ tool-call drop) —
both reporters run pi through cc-connect on Feishu.

@chenhg5 chenhg5 left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

结论: Comment(自审,无法 self-approve / self-request-changes)

由于本 PR 作者即 owner,GitHub 拒绝本人 approve / request-changes,改为 --comment 发表 QA 观察。请 maintainer 合并前自行判断结论。

总体判断

  • 5/5 CI 全绿(lint 2m53s、unit-test 4m35s、smoke-test 38s、regression-test 29s、performance-test 55s,run 31728842661),mergeable_state=clean。
  • 改动极小(+80/-3)且只触碰 single-select 路径(else 分支);multi-select 路径完整保留。dev description 与 diff 都确认。
  • 改动集中 2 文件:core/engine.go(sendAskQuestionPrompt 单一函数)+ core/engine_test.go(新增回归测试)。
  • 完全贴合 #1658 报告的根因(column_set > column > button 在 Feishu mobile 不响应 click)、采纳 reporter Po1nt9 给出的"和 permission card 一样用 flat action row"的修复方向。
  • 与 PR #1677(#1659 pi tool-call drop,已合并)构成 sibling 修复,合并后 pi + Feishu 端到端可用。

✅ 做得好的地方:

  1. Callback 完全兼容:answerData = "askq:%d:%d" 维持原样,askq_label + askq_question extras 维持原样。Feishu callback handler 完全不需要改,降低了回归风险。
  2. 新回归测试精确守卫未来:TestSendAskQuestionPrompt_CardPlatform_SingleSelectUsesActionRows 同时断言 4 件事:(a)3 CardActions rows(每个 option 一行)、(b)3 askq buttons、(c)不能出现 CardListItem(防止有人回滚到旧 layout)、(d)每个 button 必须带 askq_label + askq_question extras(防止 extras 漏掉导致 post-answer 卡片渲染坏)。这是一个非常"能抓住人"的测试。
  3. 修复方向贴合 reporter 实证:reporter 报告 "permission card 的 cmd: 点击正常工作,ask_user_question card 的点击不工作" → fix 模仿 permission card 的 flat action row,而不是重新设计新 layout。最小风险、最低惊讶。
  4. Note 保留:每个 option 仍有 cb.Note(e.i18n.T(MsgAskQuestionNote)) 提示用户用 numeric/text fallback。如果新 layout 在某些边缘客户端仍不响应,用户有 fallback。
  5. 改动隔离:只触碰 single-select 路径。multi-select (else if MultiSelect) 完全未动,现有 TestSendAskQuestionPrompt_CardPlatform_MultiQuestion_ShowsIndex 等多问题测试继续 pass。
  6. 改动范围合理:+80/-3 包含 35 行注释解释 fix 理由 + 3 行 markdown+button 调用替换 + 64 行新测试代码。注释密度比同行其它位置高,reviewer 一眼能看懂"为什么"。
  7. Markdown 描述加粗:cb.Markdown("**" + desc + "**") 让 description 在卡片里更醒目(视觉对比 button label),与新 layout 的"两行"视觉节奏一致。

🟠 P2 建议改进(不阻塞合并):

  1. Button type 从 "default" 改为 "primary":旧 layout 用 "default"(neutral 风格),新 layout 用 "primary"(品牌色,更醒目)。这是有意为之(让 button 更突出、增加点击率),但属于视觉变化。建议在 PR description 加一句说明这个 type 变化,以免下游 lark/feishu-mobile 用户反馈"按钮颜色变了"。如果想保守一点,可降级为 "default"——但 click 可靠性可能受影响。作者自决
  2. cb.Markdown("**" + desc + "**") 字符串拼接未 escape Markdown:opt.Labelopt.Description 若包含 *_[,会被 markdown 解析器误解(下划线变斜体、方括号变链接等)。边角案例但真实存在(用户描述里加星号强调不是没可能)。建议要么用 feishu.EscapeMarkdown(desc)(若平台已有 helper),要么去掉 ** 包裹,要么在 cb.Markdown 调用前做最小化 escape。不阻塞合并,但 P3 升级到 P2。
  3. Element 数量可能略增:每个 option 现在是 Markdown + Buttons 两个 element,而原来是 ListItemBtnExtra 一个 element。Feishu card 元素上限是 50(per card schema)。ask_user_question 通常 2-4 options,2-4 问题,总元素 8-16,远低于上限。但如果未来支持"1 question with 10 options"可能撞上限,目前 spec 不会,无需现在处理。

🔵 P3 可选:

  • 新 layout 改变了 description 与 button 之间的视觉关系(从"左右"变"上下"),可考虑在 PR description 加一张 before/after ASCII 截图或描述,方便社区 contributor 在 review 时对比。
  • 测试名字 TestSendAskQuestionPrompt_CardPlatform_SingleSelectUsesActionRows 已足够自解释,但内部 actionRows++ 在每个 CardActions case 都 ++ 一次,即便该 actions row 不是 askq 来源。建议测试改为只在按钮是 askq 时 ++ actionRows,语义更精确。这是 nit。

❓ 需要确认:

  • PR #1677(#1659 pi tool-call drop)已被 chenhg5 维护,PR #1679 本次合并后,reporter Po1nt9 应可在 pi 0.84.0+ + Feishu 上端到端跑通 ask_user_question 流程。建议合并后立即在 #1658 评论同步 reporter:已合并 PR #1679 / commit a972ea6,关闭 issue。
  • dev 自报的 known_risks 与代码一致:1) card layout 两行 vs 一行(有意为之);2) 其他 CardListItem 调用者(/list, /delete, /provider 等)未触碰(diff 已确认只在 sendAskQuestionPrompt 单一函数内)。

Testing / Risk:

  • 已验证:5/5 CI success + dev 本地 go test -race -count=1 ./core/ PASS(48.7s)+ ./agent/pi/ PASS(7.0s)+ ./platform/feishu/ PASS(33.3s)+ gofmt/vet/build clean + golangci-lint --new-from-rev origin/main ./core/... 0 issues。
  • 真实 Feishu mobile click 行为无法在 sandbox 内 reproduce(需要 Feishu mobile 客户端 + 凭据),reporter Po1nt9 已提供生产证据(08:00-08:25 测试窗口内 0 card-action entries for ask_user_question vs permission cards 正常),PR description 已引用。
  • 未触碰 multi-select 路径,所有现存 multi-question 测试(已有 TestSendAskQuestionPrompt_CardPlatform_MultiQuestion_ShowsIndex)继续 pass。

Next step:

  • 建议 maintainer 直接合并。P2-1(button type 变化)与 P2-2(markdown escape)是作者自决,可本 PR 顺手修,也可 follow-up。
  • 合并后请在 #1658 评论里同步 reporter,close issue。
  • 与 PR #1677 合并顺序无依赖(各自独立 fix),但建议同时打 tag/release 让 reporter 一并升级测试。

@happyTonakai

Copy link
Copy Markdown
Contributor

两个 PR 处理的是同一个问题(#1658),建议 reviewer 评审时顺便对比一下 #1469(fix/feishu-askquestion-card-layout)。

#1469 的做法:同样移除了 CardListItem(column_set: weighted 5 文本列 + auto 按钮列)布局,改为全宽 markdown 编号列表 + 等宽按钮行(按钮文案为选项索引 1/2/3…,点击后由 engine 把 askq:qIdx:i+1 解析回原始 Label)。这个分支我在本地分支一直在使用,移动端布局和按钮点击 dispatch 均正常,没有遇到问题。

补充一个技术点供评审参考:#1679 把根因归结为"column_set 内嵌按钮在移动端不可点击",但报告人确认可正常点击的权限卡(ButtonsEqual(allowBtn, denyBtn),engine.go:11646)同样渲染为 column_set(加权列)——所以真正的问题更可能是旧布局里按钮位于 auto 宽度列,被长描述挤压到接近零宽导致点击热区消失。两个 PR 都把按钮改成了全宽加权列或扁平 action 行,机制上应该都能修复点击问题。

建议:两个 PR 二选一合入(或基于其中一个叠加另一个的布局改进),并在真实 Feishu 移动端验证后关闭 #1658

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feishu] pi agent's ask_user_question card: broken layout on mobile, button clicks never dispatched (v1.5.0-beta.2)

2 participants