feat(web-shell): add assistant turn footer slot - #6611
Conversation
|
Thanks for the PR! Template looks good ✓ — all required headings present (What/Why/Reviewer Test Plan/Risk & Scope/Linked Issues/中文说明). Problem: web-shell integrators need to attach turn-level UI to a completed answer without forking or reimplementing the message list. This is a real use case for the customization API — not a theoretical concern, and consistent with how the existing 8+ renderer hooks work. Direction: well-aligned. The CHANGELOG shows a steady stream of web-shell customization hooks over recent releases (custom at-mention panel, onSessionChange callbacks, external split controls, etc.). This follows that exact pattern — define a renderer type, wire it through context, render at the right spot. No product-direction concerns. Size: 132 production lines (additions + deletions), 285 test lines, 0 generated. Not a core module (web-shell only). Scope is appropriate. Approach: focused and minimal. Every change serves the stated goal — type definitions, prop threading, turn-id tracking, rendering, exports. No drive-by refactors or scope creep. The Moving on to code review. 🔍 中文说明感谢贡献! 模板完整 ✓ — 所有必要标题齐全(What/Why/Reviewer Test Plan/Risk & Scope/Linked Issues/中文说明)。 问题:web-shell 集成方需要在已完成回答后附加 turn 级 UI,但不希望 fork 或重写消息列表。这是自定义 API 的真实需求——不是理论性顾虑,与已有的 8+ 个 renderer hook 模式一致。 方向:对齐良好。CHANGELOG 显示近期版本持续增加 web-shell 自定义钩子(自定义 @提及面板、onSessionChange 回调、外部分屏控制等)。本 PR 完全遵循该模式——定义 renderer 类型、通过 context 传递、在正确位置渲染。无产品方向顾虑。 规模:132 行生产代码(增删合计),285 行测试代码,0 行生成代码。非核心模块(仅 web-shell)。范围适当。 方案:聚焦且最小化。每处改动都服务于目标——类型定义、prop 传递、turn-id 追踪、渲染、导出。无顺手重构或范围蔓延。 进入代码审查 🔍 — Qwen Code · qwen3.7-max |
Code ReviewIndependent proposal: to add a post-turn footer slot, I'd define a renderer type receiving turn id and message metadata, add it to Findings:
No blockers found. TestingThis is a library customization hook consumed programmatically by web-shell integrators — there's no standalone CLI binary to drive in tmux. Verification is through unit tests, build, and lint. Unit tests (targeted — new feature tests)Full suite (regression check)The 5 failures are all in ESLintAll green. ✅ 中文说明代码审查独立方案:要添加 turn 后的 footer 插槽,我会定义一个接收 turn id 和消息元数据的 renderer 类型,添加到 发现:
未发现阻断问题。 测试这是一个由 web-shell 集成方以编程方式消费的库自定义钩子——没有独立的 CLI 可以在 tmux 中驱动。验证通过单元测试、构建和 lint 完成。 全部通过 ✅(5 个 build-artifact 失败为预存问题,缺少 dist/index.js) — Qwen Code · qwen3.7-max |
|
This PR is a clean, well-scoped addition to the web-shell customization API. The implementation matches what I'd have written independently — define the renderer type, track turn ids via a Map, thread the prop through the component tree, render only on completed turns. Every change in the diff earns its place. The test coverage is solid: the new test cases cover the happy path (footer renders on completed turns with correct turn id), multi-turn mapping (each turn gets its own turn id), streaming suppression (no footer on active turns), and the no-assistant-message case. All 1292 existing tests still pass. The author's follow-up commit (d28dc4f) addressed the prior review's substantive suggestions — adding a two-turn regression test and JSDoc for turnId — while reasonably declining the suggestion-level items to keep scope tight. That judgment call was correct. Approving. ✅ 中文说明这个 PR 是对 web-shell 自定义 API 的干净、范围合理的补充。实现方式与我的独立方案一致——定义 renderer 类型、通过 Map 追踪 turn id、在组件树中传递 prop、仅在已完成的 turn 上渲染。diff 中的每处改动都有存在的理由。 测试覆盖扎实:新测试用例覆盖了正常路径(已完成 turn 渲染 footer 并使用正确的 turn id)、多 turn 映射(每个 turn 获得自己的 turn id)、流式抑制(活跃 turn 不渲染 footer)和无 assistant 消息情况。全部 1292 个现有测试仍然通过。 作者的后续提交 (d28dc4f) 处理了之前审查的实质性建议——增加两轮回归测试和 turnId 的 JSDoc——同时合理地拒绝了建议级别的项目以保持范围紧凑。这个判断是正确的。 批准 ✅ — Qwen Code · qwen3.7-max |
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
LGTM, looks ready to ship. ✅
|
No new Suggestion-level findings this round — all prior suggestions have been addressed or superseded. — qwen3.7-max via Qwen Code /review |
9946acb to
6a872e6
Compare
|
Please do not rebase or force-push to an active PR as it invalidates existing review comments. Note for future reference, the bots always squash all changes into a single commit automatically as part of the integration. 中文请勿对活跃的 PR 执行 rebase 或 force-push,因为这会使已有的评审评论失效。另外,供日后参考:作为集成流程的一部分,机器人始终会自动将所有改动压缩(squash)为单个提交。 |
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
Reviewed — no new blockers this round. Two prior Critical findings (ErrorBoundary gap and memo comparator omission) remain open. Suggestion-level recommendations are in the Suggestion summary comment below.
|
Follow-up pushed in d28dc4f. Handled from the suggestion summary:
I intentionally left the custom footer placement unchanged. This slot is meant to be a content-adjacent custom area after the assistant answer body; the built-in copy/branch/timestamp row is hover chrome. Moving the custom content after that action row would change the UX semantics and expand the PR beyond the requested hook. Verification:
|
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
Reviewed — no blockers. Suggestion-level recommendations are in the Suggestion summary comment below.
|
Reviewed the latest suggestion-only follow-up. I am not changing code for these:
The prior Critical threads are resolved/outdated after d28dc4f. The remaining blocking check is the existing Ubuntu CI failure in |
|
@qwen-code /triage |
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
LGTM, looks ready to ship. ✅
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
No issues found. LGTM! ✅
— qwen3.7-max via Qwen Code /review
What this PR does
Adds a WebShell customization hook that lets embedders render extra React content after a completed turn's final assistant message and before the built-in assistant timestamp/actions area.
Why it's needed
Some WebShell integrations need to attach turn-level UI to the completed answer without forking or reimplementing the message list. This keeps the default transcript behavior unchanged while providing a focused extension point for host-owned content.
Reviewer Test Plan
How to verify
Confirm that WebShell still renders final assistant actions in the same location by default, and that a caller can provide
renderAssistantTurnFooterto render custom content for a completed turn. The renderer should receive the completed turn id plus metadata for the final assistant message, and should not run for an in-progress latest turn.Evidence (Before & After)
N/A. This PR adds a WebShell extension point and targeted DOM tests rather than changing the default visible UI.
Tested on
Environment (optional)
Local macOS validation passed:
npx eslint packages/web-shell/client/App.tsx packages/web-shell/client/customization.tsx packages/web-shell/client/index.ts packages/web-shell/client/index.tsx packages/web-shell/client/components/MessageList.tsx packages/web-shell/client/components/MessageList.dom.test.tsx packages/web-shell/client/components/MessageItem.tsx packages/web-shell/client/components/MessageItem.dom.test.tsx packages/web-shell/client/components/messages/AssistantMessage.tsx;npm run test --workspace=packages/web-shell -- MessageList.dom.test.tsx MessageList.test.ts MessageItem.dom.test.tsx;npm run build --workspace=packages/web-shell. Fullnpm run preflightwas also run on this branch; it completed clean/install/format/lint/build/typecheck, then failed duringpackages/clitest:cion CLI-side assertions outside this WebShell change (src/commands/extensions/list.test.tslocalization output andsrc/ui/auth/AuthDialog.test.tsxselection/navigation expectations). Later workspaces continued and passed.Risk & Scope
npm run preflightdoes not currently pass in this checkout because of CLI-sidetest:cifailures outside this WebShell change.Linked Issues
N/A
中文说明
What this PR does
为 WebShell 增加一个自定义扩展点,允许宿主在每轮已完成对话的最终 assistant 消息后、内置时间和操作区之前渲染额外 React 内容。
Why it's needed
部分 WebShell 集成方需要在已完成回答后附加 turn 级 UI,但不希望 fork 或重写消息列表。这个改动保持默认 transcript 行为不变,同时提供一个聚焦的宿主扩展点。
Reviewer Test Plan
How to verify
确认默认情况下 WebShell 的最终 assistant 操作区仍在原位置展示;当调用方传入
renderAssistantTurnFooter时,可以为已完成 turn 渲染自定义内容。renderer 应收到已完成 turn id 和最终 assistant 消息元信息,并且不应在仍在进行中的最新 turn 上触发。Evidence (Before & After)
N/A。这个 PR 增加的是 WebShell 扩展点和对应 DOM 测试,不改变默认可见 UI。
Tested on
Environment (optional)
本地 macOS 验证已通过:
npx eslint packages/web-shell/client/App.tsx packages/web-shell/client/customization.tsx packages/web-shell/client/index.ts packages/web-shell/client/index.tsx packages/web-shell/client/components/MessageList.tsx packages/web-shell/client/components/MessageList.dom.test.tsx packages/web-shell/client/components/MessageItem.tsx packages/web-shell/client/components/MessageItem.dom.test.tsx packages/web-shell/client/components/messages/AssistantMessage.tsx;npm run test --workspace=packages/web-shell -- MessageList.dom.test.tsx MessageList.test.ts MessageItem.dom.test.tsx;npm run build --workspace=packages/web-shell。本分支也已运行完整npm run preflight;该命令完成了 clean/install/format/lint/build/typecheck,随后在packages/cli的test:ci阶段失败,失败点是本次 WebShell 改动范围外的 CLI 侧断言(src/commands/extensions/list.test.ts本地化输出,以及src/ui/auth/AuthDialog.test.tsx选择/导航期望)。后续 workspace 继续执行并通过。Risk & Scope
npm run preflight因本次 WebShell 改动范围外的 CLI 侧test:ci失败而未通过。Linked Issues
N/A