Skip to content

feat(guid): polish assistant homepage UX and agent switching#1941

Merged
piorpua merged 14 commits intomainfrom
feat/assistant-homepage-interactions
Mar 31, 2026
Merged

feat(guid): polish assistant homepage UX and agent switching#1941
piorpua merged 14 commits intomainfrom
feat/assistant-homepage-interactions

Conversation

@ringringlin
Copy link
Copy Markdown
Collaborator

@ringringlin ringringlin commented Mar 30, 2026

Summary

This PR improves the assistant homepage experience and related interactions:

  • Refines visual hierarchy and spacing on the assistant homepage.
  • Keeps the assistant detail entry on homepage and preserves drawer-based detail flow.
  • Adds an inline Agent switcher near example prompts, with real preset-agent linkage.
  • Improves sidebar search entry alignment and hover behavior.
  • Updates related i18n keys and locale copy used by this flow.

Why

Users should be able to understand:

  • which assistant they are currently in,
  • which underlying agent is active,
  • and where to switch/view details,

without leaving the homepage.

Technical Notes

  • Branch is based on latest origin/main to minimize merge conflict risk.
  • In this environment, oxlint and oxfmt binaries are unavailable, so lint/format scripts could not be executed locally.

@piorpua piorpua added the bot:reviewing Review in progress (mutex) label Mar 30, 2026
@piorpua
Copy link
Copy Markdown
Contributor

piorpua commented Mar 30, 2026

CI 检查未通过

以下 job 在本次自动化 review 时未通过,请修复:

Job 结论
Code Quality ❌ FAILURE
Unit Tests (ubuntu-latest) ❌ FAILURE
Unit Tests (macos-14) ❌ FAILURE
Unit Tests (windows-2022) ❌ FAILURE

本次自动化 review 暂缓,待 CI 全部通过后将重新处理。

@piorpua piorpua added bot:ci-waiting CI failed and author notified — snoozed until new commits are pushed and removed bot:reviewing Review in progress (mutex) labels Mar 30, 2026
…, add split-button agent switcher

- Replace active dot with agent backend logo (Gemini, Claude, etc.) in PresetAgentTag
- Add inner divider between agent logo and assistant avatar for visual clarity
- Left area of tag triggers agent type switcher dropdown; right × always closes
- Lift agent switcher logic from AssistantSelectionArea to GuidPage
- Add border to PresetAgentTag for better theme/dark mode visibility
- Add :root block to retroma-obsidian-book-2.css to satisfy preset CSS test requirements
- Register retroma-obsidian-book-2 in cssThemePresets test expected list
When user clicks "New Chat" from the sidebar, navigate to /guid reuses the
mounted GuidPage component so state was not cleared. Use location.key in a
useEffect to reset selected agent, input, and description expanded state.
@piorpua piorpua added bot:reviewing Review in progress (mutex) bot:ci-waiting CI failed and author notified — snoozed until new commits are pushed and removed bot:ci-waiting CI failed and author notified — snoozed until new commits are pushed bot:reviewing Review in progress (mutex) labels Mar 31, 2026
IceyLiu added 6 commits March 31, 2026 21:49
- Restructure hero title row with back button, edit button, and agent type
  dropdown using unified BUILTIN_AGENT_OPTIONS and useAssistantBackends
- Add inline description expand/collapse with overflow detection
- Add agent logo icons to all agent type selectors across homepage and settings
- Add Down chevron indicators to model/agent selector buttons
- Implement collapsed sidebar layout with centered icon-only buttons
- Reduce expanded sidebar element sizes for better proportion
- Replace workspace collapse chevron with folder open/close icons
- Compact search modal input (52px → 38px) with rounded corners
- Add hover-based expand/collapse to SkillsMarketBanner
- Move custom model hint from add-model modal to model list header
- Remove agent tab content default padding, unify form item spacing
- Route AgentPillBar + to settings/agent?tab=remote
@piorpua piorpua added bot:reviewing Review in progress (mutex) and removed bot:ci-waiting CI failed and author notified — snoozed until new commits are pushed labels Mar 31, 2026
@piorpua
Copy link
Copy Markdown
Contributor

piorpua commented Mar 31, 2026

Code Review:feat(guid): polish assistant homepage UX and agent switching (#1941)

变更概述

本 PR 对 assistant 主页(GuidPage)进行了大幅 UX 重构:新增 Hero 标题区控制栏(返回按钮、编辑入口、Agent 切换 Dropdown)、description 折叠展开逻辑、以及 SkillsMarketBanner 悬停展开效果。同时将 Agent 类型切换逻辑从 AssistantSelectionArea 上移至 GuidPage,并新增两个 CSS 主题预设文件。


方案评估

结论⚠️ 方案有缺陷

整体方向合理——将 Agent 切换逻辑上移到 GuidPage 统一管理、减少 prop drilling 是正确重构路径。但在上移过程中,旧版的错误处理被丢掉,且原本通过 modalTree 变量复用的 JSX 被展开为两份重复副本,引入了维护风险。此外 selectedAssistantForSwitcher 的查找逻辑与同文件的 selectedAssistantRecord 不一致,可能导致 Dropdown 选中态显示错误。


问题清单

🟠 HIGH — Agent 切换失败时无用户反馈

文件src/renderer/pages/guid/GuidPage.tsx,第 388–403 行

问题代码

const handlePresetAgentTypeSwitch = useCallback(
  async (nextType: string) => {
    const customAgentId = agentSelection.selectedAgentInfo?.customAgentId;
    if (!customAgentId || nextType === currentPresetAgentType) return;
    const agents = ((await ConfigStorage.get('acp.customAgents')) || []) as AcpBackendConfig[];
    const idx = agents.findIndex((a) => a.id === customAgentId);
    if (idx < 0) return;
    const updated = [...agents];
    updated[idx] = { ...updated[idx], presetAgentType: nextType as PresetAgentType };
    await ConfigStorage.set('acp.customAgents', updated);
    await agentSelection.refreshCustomAgents();
    const agentName = ACP_BACKENDS_ALL[nextType as PresetAgentType]?.name || nextType;
    Message.success(t('guid.switchedToAgent', { agent: agentName }));
  },
  [agentSelection, currentPresetAgentType]
);

问题说明:此函数无 try/catch,调用方只用 .catch(err => console.error(...)) 静默处理。旧版 AssistantSelectionArea.tsx 有完整的错误处理并显示 Message.error toast,新版回归后用户操作失败无任何提示。

修复建议

const handlePresetAgentTypeSwitch = useCallback(
  async (nextType: string) => {
    const customAgentId = agentSelection.selectedAgentInfo?.customAgentId;
    if (!customAgentId || nextType === currentPresetAgentType) return;
    try {
      const agents = ((await ConfigStorage.get('acp.customAgents')) || []) as AcpBackendConfig[];
      const idx = agents.findIndex((a) => a.id === customAgentId);
      if (idx < 0) {
        Message.warning(t('common.failed', { defaultValue: 'Failed' }));
        return;
      }
      const updated = [...agents];
      updated[idx] = { ...updated[idx], presetAgentType: nextType as PresetAgentType };
      await ConfigStorage.set('acp.customAgents', updated);
      await agentSelection.refreshCustomAgents();
      const agentName = ACP_BACKENDS_ALL[nextType as PresetAgentType]?.name || nextType;
      Message.success(t('guid.switchedToAgent', { agent: agentName }));
    } catch (error) {
      console.error('[GuidPage] Failed to switch preset agent type:', error);
      Message.error(t('common.failed', { defaultValue: 'Failed' }));
    }
  },
  [agentSelection, currentPresetAgentType, t]
);

🟠 HIGH — AssistantSelectionArea 模态树 JSX 重复

文件src/renderer/pages/guid/components/AssistantSelectionArea.tsx,第 200–295 行(预设助手视图)和第 349–440 行(默认视图)

问题说明:原有的 modalTree 变量将 AssistantEditDrawer、DeleteAssistantModal、AddSkillsModal、SkillConfirmModals、AddCustomPathModal 这 5 个 modal 提取为公共节点,避免重复。本次重构删除了该变量,将完全相同的 ~90 行 JSX 写了两遍。任何后续对 modal 的修改(新增 prop、更改回调逻辑)都需要同步修改两处,容易遗漏。

修复建议:恢复 modalTree 提取方式,或将 modal tree 单独抽成子组件:

const modalTree = (
  <>
    {agentMessageContext}
    <AssistantEditDrawer ... />
    <DeleteAssistantModal ... />
    <AddSkillsModal ... />
    <SkillConfirmModals ... />
    <AddCustomPathModal ... />
  </>
);

// 在两处 return 语句末尾直接使用 {modalTree}

🟡 MEDIUM — selectedAssistantForSwitcher 不处理 builtin- 前缀

文件src/renderer/pages/guid/GuidPage.tsx,第 364–366 行

问题代码

const selectedAssistantForSwitcher = useMemo(() => {
  if (!agentSelection.isPresetAgent || !agentSelection.selectedAgentInfo?.customAgentId) return undefined;
  return agentSelection.customAgents.find((a) => a.id === agentSelection.selectedAgentInfo?.customAgentId);
}, [...]);

问题说明:同文件的 selectedAssistantRecord 使用 candidates Set(同时匹配 selectedIdbuiltin-strippedId)来处理 ID 的 builtin- 前缀变体。而 selectedAssistantForSwitcher 只做精确匹配。当 customAgentIdcustomAgents 中存储的 ID 存在前缀差异时,selectedAssistantForSwitcher 返回 undefined,导致 currentPresetAgentType 降级为 'gemini',Dropdown 中 ✓ 选中态显示错误。

修复建议:复用 selectedAssistantRecord 来获取 currentPresetAgentType

const currentPresetAgentType =
  (selectedAssistantRecord?.presetAgentType as PresetAgentType | undefined) || 'gemini';

删除 selectedAssistantForSwitcher memo。


🔵 LOW — handlePresetAgentTypeSwitch useCallback 缺少 t 依赖

文件src/renderer/pages/guid/GuidPage.tsx,第 402 行

问题代码

[agentSelection, currentPresetAgentType]  // t 未列入依赖

问题说明:函数体内使用了 t,依赖数组中未声明。虽然 react-i18next 的 t 引用在大多数情况下稳定,切换语言时仍可能使用旧版本的 t 函数(stale closure)。修复方式:在依赖数组中加入 t


汇总

# 严重级别 文件 问题
1 🟠 HIGH GuidPage.tsx:388 Agent 切换失败无用户 toast 反馈
2 🟠 HIGH AssistantSelectionArea.tsx:200,349 模态树 JSX 重复 ~90 行×2
3 🟡 MEDIUM GuidPage.tsx:364 selectedAssistantForSwitcher 不处理 builtin- 前缀导致 Dropdown ✓ 错位
4 🔵 LOW GuidPage.tsx:402 useCallback deps 缺少 t

结论

⚠️ 有条件批准 — 存在 2 个 HIGH 问题和 1 个 MEDIUM 问题,修复后可合并。主要功能实现正确,UX 重构方向合理。


本报告由本地 pr-review skill 生成,包含完整项目上下文,无截断限制。

CONCLUSION: CONDITIONAL
IS_CRITICAL_PATH: false
CRITICAL_PATH_FILES: (none)
PR_NUMBER: 1941

@piorpua piorpua added bot:ready-to-fix CONDITIONAL review done, waiting for bot fix and removed bot:reviewing Review in progress (mutex) labels Mar 31, 2026
@piorpua piorpua added bot:fixing Fix in progress (mutex) and removed bot:ready-to-fix CONDITIONAL review done, waiting for bot fix labels Mar 31, 2026
- Add try/catch to handlePresetAgentTypeSwitch with Message.error toast on failure
- Fix currentPresetAgentType to use selectedAssistantRecord (handles builtin- prefix)
- Extract modal tree into const to eliminate ~90-line JSX duplication

Review follow-up for #1941
@piorpua
Copy link
Copy Markdown
Contributor

piorpua commented Mar 31, 2026

PR Fix 验证报告

原始 PR: #1941
修复方式: 直接推送到 feat/assistant-homepage-interactions

# 严重级别 文件 问题 修复方式 状态
1 🟠 HIGH `GuidPage.tsx:388` Agent 切换失败无用户 toast 反馈 添加 try/catch,失败时显示 `Message.error`,并将 `t` 加入依赖数组 ✅ 已修复
2 🟠 HIGH `AssistantSelectionArea.tsx:200,349` 模态树 JSX 重复 ~90 行×2 提取为 `const modalTree`,两处 return 均使用 `{modalTree}` ✅ 已修复
3 🟡 MEDIUM `GuidPage.tsx:364` selectedAssistantForSwitcher 不处理 builtin- 前缀 删除 `selectedAssistantForSwitcher` memo,直接用 `selectedAssistantRecord?.presetAgentType` ✅ 已修复

总结: ✅ 已修复 3 个 | ❌ 未能修复 0 个

🔵 LOW 级别问题已跳过(不阻塞合并,修复优先级低)。

@piorpua piorpua enabled auto-merge (squash) March 31, 2026 15:27
@piorpua piorpua added bot:done Auto-merged by bot and removed bot:fixing Fix in progress (mutex) labels Mar 31, 2026
@piorpua piorpua merged commit e92d6d0 into main Mar 31, 2026
15 of 17 checks passed
@piorpua piorpua deleted the feat/assistant-homepage-interactions branch March 31, 2026 15:35
mingxuanzi pushed a commit to mingxuanzi/AionUi that referenced this pull request Apr 1, 2026
…AI#1941)

* feat(guid): polish assistant homepage interactions and agent switcher

* refactor(guid): replace green dot with agent logo in preset agent tag, add split-button agent switcher

- Replace active dot with agent backend logo (Gemini, Claude, etc.) in PresetAgentTag
- Add inner divider between agent logo and assistant avatar for visual clarity
- Left area of tag triggers agent type switcher dropdown; right × always closes
- Lift agent switcher logic from AssistantSelectionArea to GuidPage
- Add border to PresetAgentTag for better theme/dark mode visibility
- Add :root block to retroma-obsidian-book-2.css to satisfy preset CSS test requirements
- Register retroma-obsidian-book-2 in cssThemePresets test expected list

* fix(tests): add retroma-obsidian-book-2-1-dark to preset CSS test whitelist and add required :root block

* feat(guid): expand/collapse assistant description inline, show details button only when expanded

* feat(guid): reset agent selection and input state on new chat navigation

When user clicks "New Chat" from the sidebar, navigate to /guid reuses the
mounted GuidPage component so state was not cleared. Use location.key in a
useEffect to reset selected agent, input, and description expanded state.

* fix(tests): add retroma-nocturne-parchment to preset CSS test whitelist and add [data-theme=dark] block

* feat(guid): show toast after manually switching preset agent type

* feat(guid): refine homepage hero, sidebar, search modal, and settings UI

- Restructure hero title row with back button, edit button, and agent type
  dropdown using unified BUILTIN_AGENT_OPTIONS and useAssistantBackends
- Add inline description expand/collapse with overflow detection
- Add agent logo icons to all agent type selectors across homepage and settings
- Add Down chevron indicators to model/agent selector buttons
- Implement collapsed sidebar layout with centered icon-only buttons
- Reduce expanded sidebar element sizes for better proportion
- Replace workspace collapse chevron with folder open/close icons
- Compact search modal input (52px → 38px) with rounded corners
- Add hover-based expand/collapse to SkillsMarketBanner
- Move custom model hint from add-model modal to model list header
- Remove agent tab content default padding, unify form item spacing
- Route AgentPillBar + to settings/agent?tab=remote

* style: auto-format theme preset CSS files

* fix(guid): use i18n name for assistant hero title

* fix(i18n): remove duplicate shortTitle keys in conversation locale files

* fix(tests): update AgentPillBar test for remote agent tab navigation

* fix(guid): address review issues from PR iOfficeAI#1941

- Add try/catch to handlePresetAgentTypeSwitch with Message.error toast on failure
- Fix currentPresetAgentType to use selectedAssistantRecord (handles builtin- prefix)
- Extract modal tree into const to eliminate ~90-line JSX duplication

Review follow-up for iOfficeAI#1941

---------

Co-authored-by: Waili(瓦砾) <[email protected]>
Co-authored-by: zynx <>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bot:done Auto-merged by bot

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants