feat(settings): replicate the WorkBuddy agents panel and persist team-management preference (TODO 15)

This commit is contained in:
xiaohan.yuan committed 2026-10-17 12:58:25 +08:00
1 parent b3be45715e
commit 143516b3a8
33 files changed
+1071 -21

No files matched your search

+30
View File
@@ -0,0 +1,30 @@
/**
* 设置 → 智能体(TODO 15):只持久化「智能体团队管理」偏好。
*
* REA 依据(WorkBuddy 5.8.3,设置窗口 900×680):
* - ev_bd0f4b5dac7d4e2b89b1b050db1896c65e03b4fd1c3d3d986a8958fd9c1a9883(浅色顶部 DOM/layout/computed style + CSS 源)
* - ev_3384aa03af8a1ccdffb8e025dbd4a354636d8d6b0c207abd21e12fc5eb2ae719(深色同页)
* - ev_01940b7925326ee8e7f7e4aba661be2a17a2f876d634d4d370d01b6616a4a7fd(团队管理下拉展开:开启 / 禁用)
* - ev_1cc896e04c0cc9ceab39b0a252f4982c019305609195ad44804ae9b5fb7379a8(最终浅色顶部)
*
* 用户限定:云端服务与子代理调度本轮不处理。因此这里只保存偏好(默认开启,与原版一致),
* 多智能体自动拆分的执行器尚未接入;面板用 title 明确说明,不把偏好伪装成已生效能力。
*/
import type { AgentSettings, AgentSettingsPatch } from '@shared/types'
import { getStoredAgentSettings, setStoredAgentSettings } from './config'
export const DEFAULT_AGENT_SETTINGS: AgentSettings = { teamManagement: true }
export function normalizeAgentSettings(value: Partial<AgentSettings> | null | undefined): AgentSettings {
return { teamManagement: value?.teamManagement !== false }
}
export async function getAgentSettings(): Promise<AgentSettings> {
return normalizeAgentSettings(await getStoredAgentSettings())
}
export async function updateAgentSettings(patch: AgentSettingsPatch): Promise<AgentSettings> {
const next = normalizeAgentSettings({ ...await getAgentSettings(), ...patch })
await setStoredAgentSettings(next)
return next
}
+13 -1
View File
@@ -10,7 +10,7 @@
import { app, safeStorage } from 'electron'
import { promises as fs } from 'node:fs'
import { join } from 'node:path'
import type { GatewayConfig, GatewayConfigView, PersonalizationSettings } from '@shared/types'
import type { AgentSettings, GatewayConfig, GatewayConfigView, PersonalizationSettings } from '@shared/types'
interface StoredConfig {
speechBaseUrl?: string
@@ -28,6 +28,8 @@ interface StoredConfig {
autoLaunch?: boolean
/** 设置 → 个性化(身份、回复风格、指令、人设、长期记忆)。 */
personalization?: Partial<PersonalizationSettings>
/** 设置 → 智能体(智能体团队管理偏好)。 */
agentSettings?: Partial<AgentSettings>
}
const DEFAULTS: StoredConfig = {
@@ -131,6 +133,16 @@ export async function setStoredPersonalization(value: Partial<PersonalizationSet
await persist({ ...stored, personalization: { ...(stored.personalization ?? {}), ...value } })
}
export async function getStoredAgentSettings(): Promise<Partial<AgentSettings>> {
const stored = await load()
return stored.agentSettings ?? {}
}
export async function setStoredAgentSettings(value: Partial<AgentSettings>): Promise<void> {
const stored = await load()
await persist({ ...stored, agentSettings: { ...(stored.agentSettings ?? {}), ...value } })
}
/** 供渲染进程使用:脱敏视图 */
export async function getConfigView(): Promise<GatewayConfigView> {
const stored = await load()
+4 -1
View File
@@ -11,7 +11,7 @@ import { BrowserWindow, app, dialog, ipcMain, shell, type OpenDialogOptions } fr
import { randomUUID } from 'node:crypto'
import { unlink, writeFile } from 'node:fs/promises'
import { join } from 'node:path'
import type { ChatEvent, ChatMessage, GitBranchInfo, PersonalizationPatch, WindowState } from '@shared/types'
import type { AgentSettingsPatch, ChatEvent, ChatMessage, GitBranchInfo, PersonalizationPatch, WindowState } from '@shared/types'
import { freezeAssistantModelMetadata } from '@shared/assistant-model'
import type { ConfigPatchLike, EditAction, SendPayload, WorkspaceAttachResult } from '@shared/ipc'
import { applyAssistantEvent } from '@shared/message-parts'
@@ -35,6 +35,7 @@ import * as models from './models'
import * as workspaces from './workspaces'
import * as generalSettings from './general-settings'
import * as personalization from './personalization'
import * as agentSettings from './agent-settings'
import { prepareOmpModel } from './omp-model'
import type { CustomModelInput, ResolvedModel } from '@shared/models'
import type { SessionContext } from '@shared/workspaces'
@@ -411,6 +412,8 @@ export function registerIpc(getWindow: () => BrowserWindow | null): void {
ipcMain.handle('general:get', (_event, options?: { refreshUsage?: boolean }) => generalView(options?.refreshUsage === true))
ipcMain.handle('personalization:get', () => personalization.getPersonalization())
ipcMain.handle('personalization:update', (_event, patch: PersonalizationPatch) => personalization.updatePersonalization(patch))
ipcMain.handle('agents:get', () => agentSettings.getAgentSettings())
ipcMain.handle('agents:update', (_event, patch: AgentSettingsPatch) => agentSettings.updateAgentSettings(patch))
ipcMain.handle('general:update', async (_event, patch: { autoLaunch?: boolean; preventSleep?: boolean }) => {
if (patch.preventSleep !== undefined) {
await config.setPreventSleep(patch.preventSleep)