Skip to content

Commit 83c5c57

Browse files
committed
refactor: extract computeModeDefaults to shared and use lodash uniq
- Move duplicated `computeModeDefaults` function to shared.tsx - Replace custom `unique` function with lodash `uniq` for consistency - Both PermissionModeSettings and ToolsAndMCPSettings now import from shared
1 parent 04f6ccd commit 83c5c57

File tree

3 files changed

+37
-65
lines changed

3 files changed

+37
-65
lines changed

src/renderer/src/pages/settings/AgentSettings/PermissionModeSettings.tsx

Lines changed: 3 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import type {
44
GetAgentResponse,
55
GetAgentSessionResponse,
66
PermissionMode,
7-
Tool,
87
UpdateAgentBaseForm,
98
UpdateAgentFunction,
109
UpdateAgentSessionFunction
@@ -16,7 +15,7 @@ import type { FC } from 'react'
1615
import { useCallback, useMemo, useState } from 'react'
1716
import { useTranslation } from 'react-i18next'
1817

19-
import { SettingsContainer, SettingsItem, SettingsTitle } from './shared'
18+
import { computeModeDefaults, SettingsContainer, SettingsItem, SettingsTitle, uniq } from './shared'
2019

2120
type PermissionModeSettingsProps =
2221
| {
@@ -32,35 +31,6 @@ type AgentConfigurationState = AgentConfiguration & Record<string, unknown>
3231

3332
const defaultConfiguration: AgentConfigurationState = AgentConfigurationSchema.parse({})
3433

35-
/**
36-
* Computes the list of tool IDs that should be automatically approved for a given permission mode.
37-
*/
38-
export const computeModeDefaults = (mode: PermissionMode, tools: Tool[]): string[] => {
39-
const defaultToolIds = tools.filter((tool) => !tool.requirePermissions).map((tool) => tool.id)
40-
switch (mode) {
41-
case 'acceptEdits':
42-
return [
43-
...defaultToolIds,
44-
'Edit',
45-
'MultiEdit',
46-
'NotebookEdit',
47-
'Write',
48-
'Bash(mkdir:*)',
49-
'Bash(touch:*)',
50-
'Bash(rm:*)',
51-
'Bash(mv:*)',
52-
'Bash(cp:*)'
53-
]
54-
case 'bypassPermissions':
55-
return tools.map((tool) => tool.id)
56-
case 'default':
57-
case 'plan':
58-
return defaultToolIds
59-
}
60-
}
61-
62-
export const unique = (values: string[]) => Array.from(new Set(values))
63-
6434
export const PermissionModeSettings: FC<PermissionModeSettingsProps> = ({ agentBase, update }) => {
6535
const { t } = useTranslation()
6636
const [isUpdatingMode, setIsUpdatingMode] = useState(false)
@@ -78,7 +48,7 @@ export const PermissionModeSettings: FC<PermissionModeSettingsProps> = ({ agentB
7848
const approvedToolIds = useMemo(() => {
7949
const allowed = agentBase?.allowed_tools ?? []
8050
const sanitized = allowed.filter((id) => availableTools.some((tool) => tool.id === id))
81-
const merged = unique([...sanitized, ...autoToolIds])
51+
const merged = uniq([...sanitized, ...autoToolIds])
8252
return merged
8353
}, [agentBase?.allowed_tools, autoToolIds, availableTools])
8454
const userAddedIds = useMemo(() => {
@@ -91,7 +61,7 @@ export const PermissionModeSettings: FC<PermissionModeSettingsProps> = ({ agentB
9161
return
9262
}
9363
const defaults = computeModeDefaults(nextMode, availableTools)
94-
const merged = unique([...defaults, ...userAddedIds])
64+
const merged = uniq([...defaults, ...userAddedIds])
9565
const removedDefaults = autoToolIds.filter((id) => !defaults.includes(id))
9666

9767
const applyChange = async () => {

src/renderer/src/pages/settings/AgentSettings/ToolsAndMCPSettings.tsx

Lines changed: 3 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ import type {
44
AgentConfiguration,
55
GetAgentResponse,
66
GetAgentSessionResponse,
7-
PermissionMode,
8-
Tool,
97
UpdateAgentBaseForm,
108
UpdateAgentFunction,
119
UpdateAgentSessionFunction
@@ -17,7 +15,7 @@ import type { FC } from 'react'
1715
import { useCallback, useMemo, useState } from 'react'
1816
import { useTranslation } from 'react-i18next'
1917

20-
import { SettingsContainer, SettingsItem, SettingsTitle } from './shared'
18+
import { computeModeDefaults, SettingsContainer, SettingsItem, SettingsTitle, uniq } from './shared'
2119

2220
type ToolsAndMCPSettingsProps =
2321
| {
@@ -33,32 +31,6 @@ type AgentConfigurationState = AgentConfiguration & Record<string, unknown>
3331

3432
const defaultConfiguration: AgentConfigurationState = AgentConfigurationSchema.parse({})
3533

36-
const computeModeDefaults = (mode: PermissionMode, tools: Tool[]): string[] => {
37-
const defaultToolIds = tools.filter((tool) => !tool.requirePermissions).map((tool) => tool.id)
38-
switch (mode) {
39-
case 'acceptEdits':
40-
return [
41-
...defaultToolIds,
42-
'Edit',
43-
'MultiEdit',
44-
'NotebookEdit',
45-
'Write',
46-
'Bash(mkdir:*)',
47-
'Bash(touch:*)',
48-
'Bash(rm:*)',
49-
'Bash(mv:*)',
50-
'Bash(cp:*)'
51-
]
52-
case 'bypassPermissions':
53-
return tools.map((tool) => tool.id)
54-
case 'default':
55-
case 'plan':
56-
return defaultToolIds
57-
}
58-
}
59-
60-
const unique = (values: string[]) => Array.from(new Set(values))
61-
6234
export const ToolsAndMCPSettings: FC<ToolsAndMCPSettingsProps> = ({ agentBase, update }) => {
6335
const { t } = useTranslation()
6436
const { mcpServers: allServers } = useMCPServers()
@@ -75,7 +47,7 @@ export const ToolsAndMCPSettings: FC<ToolsAndMCPSettingsProps> = ({ agentBase, u
7547
const approvedToolIds = useMemo(() => {
7648
const allowed = agentBase?.allowed_tools ?? []
7749
const sanitized = allowed.filter((id) => availableTools.some((tool) => tool.id === id))
78-
const merged = unique([...sanitized, ...autoToolIds])
50+
const merged = uniq([...sanitized, ...autoToolIds])
7951
return merged
8052
}, [agentBase?.allowed_tools, autoToolIds, availableTools])
8153
const selectedMcpIds = useMemo(() => agentBase?.mcps ?? [], [agentBase?.mcps])
@@ -107,7 +79,7 @@ export const ToolsAndMCPSettings: FC<ToolsAndMCPSettingsProps> = ({ agentBase, u
10779
}
10880
setIsUpdatingTools(true)
10981
const next = isApproved ? [...approvedToolIds, toolId] : approvedToolIds.filter((id) => id !== toolId)
110-
const sanitized = unique(next.filter((id) => availableTools.some((tool) => tool.id === id)).concat(autoToolIds))
82+
const sanitized = uniq(next.filter((id) => availableTools.some((tool) => tool.id === id)).concat(autoToolIds))
11183
try {
11284
await update({ id: agentBase.id, allowed_tools: sanitized } satisfies UpdateAgentBaseForm)
11385
} finally {

src/renderer/src/pages/settings/AgentSettings/shared.tsx

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,45 @@ import EmojiIcon from '@renderer/components/EmojiIcon'
22
import type { ScrollbarProps } from '@renderer/components/Scrollbar'
33
import Scrollbar from '@renderer/components/Scrollbar'
44
import { getAgentTypeLabel } from '@renderer/i18n/label'
5-
import type { AgentEntity, AgentSessionEntity } from '@renderer/types'
5+
import type { AgentEntity, AgentSessionEntity, PermissionMode, Tool } from '@renderer/types'
66
import { cn } from '@renderer/utils'
77
import { Menu, Modal } from 'antd'
8+
import { uniq } from 'lodash'
89
import type { ReactNode } from 'react'
910
import React from 'react'
1011
import styled from 'styled-components'
1112

1213
import { SettingDivider } from '..'
1314

15+
/**
16+
* Computes the list of tool IDs that should be automatically approved for a given permission mode.
17+
*/
18+
export const computeModeDefaults = (mode: PermissionMode, tools: Tool[]): string[] => {
19+
const defaultToolIds = tools.filter((tool) => !tool.requirePermissions).map((tool) => tool.id)
20+
switch (mode) {
21+
case 'acceptEdits':
22+
return [
23+
...defaultToolIds,
24+
'Edit',
25+
'MultiEdit',
26+
'NotebookEdit',
27+
'Write',
28+
'Bash(mkdir:*)',
29+
'Bash(touch:*)',
30+
'Bash(rm:*)',
31+
'Bash(mv:*)',
32+
'Bash(cp:*)'
33+
]
34+
case 'bypassPermissions':
35+
return tools.map((tool) => tool.id)
36+
case 'default':
37+
case 'plan':
38+
return defaultToolIds
39+
}
40+
}
41+
42+
export { uniq }
43+
1444
export interface SettingsTitleProps extends React.ComponentPropsWithRef<'div'> {
1545
contentAfter?: ReactNode
1646
}

0 commit comments

Comments
 (0)