Skip to content

fix(settings): preserve preset agents when saving custom agents#1908

Merged
piorpua merged 2 commits intomainfrom
fix/issue-1898
Mar 30, 2026
Merged

fix(settings): preserve preset agents when saving custom agents#1908
piorpua merged 2 commits intomainfrom
fix/issue-1898

Conversation

@kaizhou-lab
Copy link
Copy Markdown
Collaborator

Summary

  • Fix custom agent save overwriting all preset assistants in acp.customAgents config
  • Integrate orphaned InlineAgentEditor into LocalAgents tab with add/edit/delete/toggle support
  • All save operations now read the full config array (preserving presets) before writing back

Related Issues

Closes #1898

Root Cause

The old CustomAcpAgent component loaded agents with agents.filter(!isPreset), then wrote [...customAgents, newAgent] back to acp.customAgents — silently deleting all preset assistants from the config. After a page refresh, the assistant list appeared empty because all preset entries were gone.

Test Plan

  • Unit tests pass (LocalAgents.dom.test.tsx updated with 6 tests)
  • Type check passes
  • Lint and format pass

The old CustomAcpAgent component loaded only non-preset agents into
its local state, then wrote that subset back to acp.customAgents on
save — silently deleting all preset assistants from the config array.

This fix integrates InlineAgentEditor into LocalAgents and ensures
every save/delete/toggle operation reads the full config (including
presets) before writing back, preventing data loss.
@piorpua
Copy link
Copy Markdown
Contributor

piorpua commented Mar 30, 2026

Code Review:fix(settings): preserve preset agents when saving custom agents (#1908)

变更概述

本 PR 修复了 LocalAgents 组件中一个数据丢失 bug:原 CustomAcpAgent 组件在保存时只写回过滤后的 customAgents,导致 preset 配置被覆盖清空。PR 同时将孤立的 InlineAgentEditor 集成到 LocalAgents tab,并为所有写操作统一改用"先读全量、再写回"模式。变更涉及 LocalAgents.tsx 和对应的 DOM 测试文件。


方案评估

结论:✅ 方案合理

根本原因分析准确,修复直接。"先读全量 config、再追加/更新/删除、再写回"的模式能可靠防止 preset 数据丢失,且与项目现有 ConfigStorage 用法一致。将 InlineAgentEditor 集成到同一组件是合理的内聚化改动,无过度工程化问题。


问题清单

🟡 MEDIUM — 关键测试用例未实际验证 preset 保留逻辑

文件tests/unit/LocalAgents.dom.test.tsx,第 210–247 行

问题代码

it('saves custom agent while preserving preset agents in config', async () => {
  // ...
  // Click add button
  const addButton = screen.getByText('settings.addCustomAgentTitle');
  await act(async () => {
    fireEvent.click(addButton);
  });

  // The critical assertion is in the save callback logic:
  // ...
  expect(mockConfigGet).toHaveBeenCalledWith('acp.customAgents');
});

问题说明:测试名称声称验证"保存时保留 preset agents",但实际断言 expect(mockConfigGet).toHaveBeenCalledWith('acp.customAgents') 在组件挂载时(loadCustomAgentsuseEffect)就已成立,与点击 Add 按钮无关。测试注释也坦承"cannot directly trigger save"——即核心修复逻辑(handleSaveAgent 写回时包含 preset)实际上未被测试到。若该函数发生回归,现有测试仍会通过。

修复建议:通过触发 InlineAgentEditoronSave prop,断言 ConfigStorage.set 被调用时的参数包含 preset:

it('saves custom agent while preserving preset agents in config', async () => {
  const presetAgent = { id: 'cowork', name: 'Cowork', isPreset: true, enabled: true, context: 'test' };
  mockConfigGet.mockResolvedValue([presetAgent]);

  await act(async () => {
    render(<LocalAgents />);
  });

  // Click add to show InlineAgentEditor, fill fields, submit
  // ...

  // Core assertion: ConfigStorage.set must be called with presets preserved
  expect(mockConfigSet).toHaveBeenCalledWith(
    'acp.customAgents',
    expect.arrayContaining([
      expect.objectContaining({ id: 'cowork', isPreset: true }),
      expect.objectContaining({ name: 'New Agent' }),
    ])
  );
});

🔵 LOW — Oxlint no-map-spread 警告与项目不可变性原则冲突

文件src/renderer/pages/settings/AgentSettings/LocalAgents.tsx,第 119 行

问题代码

const updatedAgents = allAgents.map((a) => (a.id === agent.id ? { ...a, enabled } : a));

问题说明:Oxlint 的 no-map-spread 规则对此行报 warning,建议改用 Object.assign 以避免每次迭代分配新对象。但项目编码规范明确要求不可变性("NEVER mutate"),而 Object.assign 的第一个参数会被原地修改,与规范相悖。两者存在配置冲突。

修复建议:在 .oxlintrc.json 中显式关闭此规则并说明原因,或保持现状并接受该 warning。


汇总

# 严重级别 文件 问题
1 🟡 MEDIUM tests/unit/LocalAgents.dom.test.tsx:210 关键测试用例未实际验证 preset 保留逻辑,断言恒真
2 🔵 LOW src/renderer/pages/settings/AgentSettings/LocalAgents.tsx:119 no-map-spread lint 警告与不可变性原则冲突,需对齐配置

结论

⚠️ 有条件批准 — 修复逻辑本身正确,但核心 bug 修复缺乏有效的单元测试覆盖,建议补全后合并。


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

CONCLUSION: CONDITIONAL
IS_CRITICAL_PATH: false
PR_NUMBER: 1908

@piorpua piorpua added bot:ready-to-fix CONDITIONAL review done, waiting for bot fix bot:fixing Fix in progress (mutex) and removed bot:reviewing Review in progress (mutex) bot:ready-to-fix CONDITIONAL review done, waiting for bot fix labels Mar 30, 2026
- Replace weak indirect assertion in preset-preservation test with a
  direct save trigger via mocked InlineAgentEditor, asserting that
  ConfigStorage.set receives both the existing preset agent and the
  new custom agent in the written array
- Apply oxlint autofix: use Array.toSorted() instead of sort() in
  SpeechToTextService

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

piorpua commented Mar 30, 2026

PR Fix 验证报告

原始 PR: #1908
修复方式: 直接推送到 fix/issue-1898

# 严重级别 文件 问题 修复方式 状态
1 🟡 MEDIUM tests/unit/LocalAgents.dom.test.tsx:210 关键测试用例未实际验证 preset 保留逻辑,断言恒真 新增 InlineAgentEditor mock,触发 onSave 后断言 ConfigStorage.set 被调用时包含 preset 和新 agent ✅ 已修复

总结: ✅ 已修复 1 个 | 🔵 LOW 问题已跳过

🔵 LOW 级别问题(no-map-spread lint 警告)已跳过(不阻塞合并)。

@piorpua piorpua enabled auto-merge (squash) March 30, 2026 08:19
@piorpua piorpua added bot:done Auto-merged by bot and removed bot:fixing Fix in progress (mutex) labels Mar 30, 2026
@piorpua piorpua merged commit 9c839d1 into main Mar 30, 2026
14 of 17 checks passed
@piorpua piorpua deleted the fix/issue-1898 branch March 30, 2026 08:25
piorpua pushed a commit that referenced this pull request Mar 30, 2026
Hide the Custom Agents section (header, add button, list, InlineAgentEditor)
and all related state/handlers that were introduced in #1908.
Update the LocalAgents test suite to remove tests covering the removed UI.
piorpua added a commit that referenced this pull request Mar 30, 2026
Hide the Custom Agents section (header, add button, list, InlineAgentEditor)
and all related state/handlers that were introduced in #1908.
Update the LocalAgents test suite to remove tests covering the removed UI.

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.

[Bug]: webui 添加并开启自定义agent后,新建会话页和助手页所以助手列表都没有了

2 participants