Skip to content

Commit 8441ce4

Browse files
authored
refactor(mcp): retire expired mcp servers (#1400)
* refactor(mcp): retire meeting server * fix(agent): use session vision for screenshots * refactor(vision): unify session image analysis * fix(main): harden vision resolution * fix(main): cancel nested vision work
1 parent ef353a1 commit 8441ce4

File tree

56 files changed

+1626
-941
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+1626
-941
lines changed
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Dead Code Batch 3
2+
3+
- Purpose: archive retired MCP runtime code that is no longer part of the active in-memory server set.
4+
- Archived at: 2026-03-26
5+
- Rationale: `meetingServer.ts` has been removed from live MCP registration and default config, but is retained in source form for precise rollback if the feature is rebuilt later.
6+
7+
## Archived Paths
8+
9+
- `src/main/presenter/mcpPresenter/inMemoryServers/meetingServer.ts`
10+
11+
## Notes
12+
13+
- This directory is not part of the runtime, build, typecheck, or test target set.
14+
- Restore by moving files back to their original paths only if a future audit proves the retired MCP server is needed again.

src/main/presenter/mcpPresenter/inMemoryServers/meetingServer.ts renamed to archives/code/dead-code-batch-3/src/main/presenter/mcpPresenter/inMemoryServers/meetingServer.ts

File renamed without changes.

scripts/generate-i18n-types.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import fs from 'fs'
22
import path from 'path'
3-
import { fileURLToPath } from 'url'
3+
import { fileURLToPath, pathToFileURL } from 'url'
44

55
const __filename = fileURLToPath(import.meta.url)
66
const __dirname = path.dirname(__filename)
@@ -57,6 +57,6 @@ async function main() {
5757
}
5858

5959
// 仅需要在本地开发时执行
60-
if (import.meta.url === `file://${process.argv[1]}`) {
60+
if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
6161
main()
6262
}

src/main/events.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -219,11 +219,6 @@ export const TRAY_EVENTS = {
219219
CHECK_FOR_UPDATES: 'tray:check-for-updates' // 托盘检查更新
220220
}
221221

222-
// MCP会议专用事件
223-
export const MEETING_EVENTS = {
224-
INSTRUCTION: 'mcp:meeting-instruction' // 主进程向渲染进程发送指令
225-
}
226-
227222
// 悬浮按钮相关事件
228223
export const FLOATING_BUTTON_EVENTS = {
229224
CLICKED: 'floating-button:clicked', // 悬浮按钮被点击

src/main/presenter/configPresenter/index.ts

Lines changed: 75 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ interface IAppSettings {
102102
enableSkills?: boolean // Skills system global toggle
103103
hooksNotifications?: HooksNotificationsSettings // Hooks & notifications settings
104104
defaultModel?: { providerId: string; modelId: string } // Default model for new conversations
105-
defaultVisionModel?: { providerId: string; modelId: string } // Default vision model for image tools
105+
defaultVisionModel?: { providerId: string; modelId: string } // Legacy vision model setting for migration only
106106
defaultProjectPath?: string | null
107107
acpRegistryMigrationVersion?: number
108108
unifiedAgentsMigrationVersion?: number
@@ -153,6 +153,15 @@ const isModelSelection = (value: unknown): value is ModelSelection => {
153153
return typeof record.providerId === 'string' && typeof record.modelId === 'string'
154154
}
155155

156+
const normalizeKnownModelId = (modelId: string): string => {
157+
const normalizedModelId = modelId.trim().toLowerCase()
158+
return normalizedModelId.replace(/^models\//, '')
159+
}
160+
161+
const normalizeKnownProviderId = (providerId: string): string =>
162+
modelCapabilities.resolveProviderId(providerId.trim().toLowerCase()) ||
163+
providerId.trim().toLowerCase()
164+
156165
export const getAnthropicModelSelectionKeysToClear = (
157166
settings: Partial<
158167
Record<
@@ -362,6 +371,7 @@ export class ConfigPresenter implements IConfigPresenter {
362371
setAgentRepository(agentRepository: AgentRepository): void {
363372
this.agentRepository = agentRepository
364373
this.initializeUnifiedAgents()
374+
this.migrateLegacyDefaultVisionModelToBuiltinAgent()
365375
}
366376

367377
private getAgentRepositoryOrThrow(): AgentRepository {
@@ -396,6 +406,35 @@ export class ConfigPresenter implements IConfigPresenter {
396406
this.syncRegistryAgentsToRepository()
397407
}
398408

409+
private migrateLegacyDefaultVisionModelToBuiltinAgent(): void {
410+
const legacySelection = this.store.get('defaultVisionModel') as unknown
411+
if (legacySelection === undefined) {
412+
return
413+
}
414+
415+
const builtinVisionModel = this.getBuiltinDeepChatConfig().visionModel
416+
417+
if (
418+
isModelSelection(legacySelection) &&
419+
(!builtinVisionModel?.providerId || !builtinVisionModel?.modelId)
420+
) {
421+
const providerId = legacySelection.providerId.trim()
422+
const modelId = legacySelection.modelId.trim()
423+
424+
if (providerId && modelId) {
425+
this.updateBuiltinDeepChatConfig({
426+
visionModel: {
427+
providerId,
428+
modelId
429+
}
430+
})
431+
}
432+
}
433+
434+
this.store.delete('defaultVisionModel')
435+
eventBus.sendToMain(CONFIG_EVENTS.SETTING_CHANGED, 'defaultVisionModel', undefined)
436+
}
437+
399438
private buildLegacyBuiltinDeepChatConfig(): DeepChatAgentConfig {
400439
const defaultModel = this.store.get('defaultModel') as ModelSelection | undefined
401440
const assistantModel = this.store.get('assistantModel') as ModelSelection | undefined
@@ -760,7 +799,9 @@ export class ConfigPresenter implements IConfigPresenter {
760799
const keysToClear = getAnthropicModelSelectionKeysToClear({
761800
defaultModel: this.getSetting('defaultModel'),
762801
assistantModel: this.getSetting('assistantModel'),
763-
defaultVisionModel: this.getSetting('defaultVisionModel'),
802+
defaultVisionModel: this.store.get('defaultVisionModel') as
803+
| { providerId: string; modelId: string }
804+
| undefined,
764805
preferredModel: this.getSetting('preferredModel')
765806
})
766807

@@ -780,9 +821,6 @@ export class ConfigPresenter implements IConfigPresenter {
780821
if (key === 'assistantModel') {
781822
return this.getBuiltinDeepChatConfig().assistantModel as T | undefined
782823
}
783-
if (key === 'defaultVisionModel') {
784-
return this.getDefaultVisionModel() as T | undefined
785-
}
786824
if (key === 'default_system_prompt') {
787825
return this.getBuiltinDeepChatConfig().systemPrompt as T | undefined
788826
}
@@ -808,10 +846,6 @@ export class ConfigPresenter implements IConfigPresenter {
808846
eventBus.sendToMain(CONFIG_EVENTS.SETTING_CHANGED, key, value)
809847
return
810848
}
811-
if (key === 'defaultVisionModel') {
812-
this.setDefaultVisionModel(value as { providerId: string; modelId: string } | undefined)
813-
return
814-
}
815849
if (key === 'default_system_prompt') {
816850
this.updateBuiltinDeepChatConfig({
817851
systemPrompt: typeof value === 'string' ? value : ''
@@ -1015,6 +1049,26 @@ export class ConfigPresenter implements IConfigPresenter {
10151049
return this.providerModelHelper.getCustomModels(providerId)
10161050
}
10171051

1052+
isKnownModel(providerId: string, modelId: string): boolean {
1053+
const normalizedProviderId = normalizeKnownProviderId(providerId)
1054+
const normalizedModelId = normalizeKnownModelId(modelId)
1055+
1056+
if (!normalizedProviderId || !normalizedModelId) {
1057+
return false
1058+
}
1059+
1060+
const hasKnownModel = (models: Array<{ id: string }> | undefined): boolean =>
1061+
Array.isArray(models) &&
1062+
models.some((model) => normalizeKnownModelId(model.id) === normalizedModelId)
1063+
1064+
return (
1065+
this.hasUserModelConfig(normalizedModelId, normalizedProviderId) ||
1066+
hasKnownModel(this.getProviderModels(normalizedProviderId)) ||
1067+
hasKnownModel(this.getCustomModels(normalizedProviderId)) ||
1068+
hasKnownModel(this.getDbProviderModels(normalizedProviderId))
1069+
)
1070+
}
1071+
10181072
setCustomModels(providerId: string, models: MODEL_META[]): void {
10191073
this.providerModelHelper.setCustomModels(providerId, models)
10201074
}
@@ -1688,6 +1742,18 @@ export class ConfigPresenter implements IConfigPresenter {
16881742
)
16891743
}
16901744

1745+
async agentSupportsCapability(agentId: string, capability: 'vision'): Promise<boolean> {
1746+
if (capability !== 'vision') {
1747+
return false
1748+
}
1749+
1750+
const agentConfig = await this.resolveDeepChatAgentConfig(agentId)
1751+
const providerId = agentConfig.visionModel?.providerId?.trim()
1752+
const modelId = agentConfig.visionModel?.modelId?.trim()
1753+
1754+
return Boolean(providerId && modelId && this.getModelConfig(modelId, providerId)?.vision)
1755+
}
1756+
16911757
async createDeepChatAgent(input: CreateDeepChatAgentInput): Promise<Agent> {
16921758
const created = this.getAgentRepositoryOrThrow().createDeepChatAgent(input)
16931759
this.notifyAcpAgentsChanged()
@@ -2312,32 +2378,6 @@ export class ConfigPresenter implements IConfigPresenter {
23122378
eventBus.sendToMain(CONFIG_EVENTS.SETTING_CHANGED, 'defaultModel', model)
23132379
}
23142380

2315-
getDefaultVisionModel(): { providerId: string; modelId: string } | undefined {
2316-
const selection = this.getBuiltinDeepChatConfig().visionModel
2317-
if (selection?.providerId && selection?.modelId) {
2318-
return {
2319-
providerId: selection.providerId,
2320-
modelId: selection.modelId
2321-
}
2322-
}
2323-
return this.store.get('defaultVisionModel') as
2324-
| { providerId: string; modelId: string }
2325-
| undefined
2326-
}
2327-
2328-
setDefaultVisionModel(model: { providerId: string; modelId: string } | undefined): void {
2329-
this.updateBuiltinDeepChatConfig({
2330-
visionModel:
2331-
model?.providerId && model?.modelId
2332-
? {
2333-
providerId: model.providerId,
2334-
modelId: model.modelId
2335-
}
2336-
: null
2337-
})
2338-
eventBus.sendToMain(CONFIG_EVENTS.SETTING_CHANGED, 'defaultVisionModel', model)
2339-
}
2340-
23412381
getDefaultProjectPath(): string | null {
23422382
const path = this.getSetting<string | null>('defaultProjectPath')
23432383
return path?.trim() ? path.trim() : null

src/main/presenter/configPresenter/mcpConfHelper.ts

Lines changed: 23 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -165,16 +165,6 @@ const DEFAULT_INMEMORY_SERVERS: Record<string, Omit<MCPServerConfig, 'enabled'>>
165165
},
166166
disable: false
167167
},
168-
imageServer: {
169-
args: [],
170-
descriptions: 'Image processing MCP service',
171-
icons: '🖼️',
172-
autoApprove: ['read_image_base64', 'read_multiple_images_base64'], // Auto-approve reading, require confirmation for uploads
173-
type: 'inmemory' as MCPServerType,
174-
command: 'image', // We need to map this command to the ImageServer class later
175-
env: {},
176-
disable: false
177-
},
178168
ragflowKnowledge: {
179169
args: [],
180170
descriptions: 'DeepChat内置RAGFlow知识库检索服务',
@@ -258,16 +248,6 @@ const DEFAULT_INMEMORY_SERVERS: Record<string, Omit<MCPServerConfig, 'enabled'>>
258248
env: {},
259249
disable: false
260250
},
261-
'deepchat-inmemory/meeting-server': {
262-
args: [],
263-
descriptions: 'DeepChat内置会议服务,用于组织多Agent讨论',
264-
icons: '👥',
265-
autoApprove: ['all'],
266-
type: 'inmemory' as MCPServerType,
267-
command: 'deepchat-inmemory/meeting-server',
268-
env: {},
269-
disable: false
270-
},
271251
// Merge platform-specific services
272252
...PLATFORM_SPECIFIC_SERVERS
273253
}
@@ -384,15 +364,35 @@ export class McpConfHelper {
384364
private removeDeprecatedBuiltInServers(
385365
servers: Record<string, MCPServerConfig>
386366
): Record<string, MCPServerConfig> {
387-
const deprecatedBuiltInServers = ['powerpack']
367+
const deprecatedBuiltInServers = [
368+
'powerpack',
369+
'deepchat-inmemory/meeting-server',
370+
'imageServer'
371+
]
372+
let hasChanges = false
373+
const removedBuiltInServers = new Set(this.getRemovedBuiltInServers())
374+
let removedListChanged = false
388375

389376
for (const serverName of deprecatedBuiltInServers) {
390377
if (servers[serverName]) {
391378
console.log(`Removing deprecated built-in MCP service: ${serverName}`)
392379
delete servers[serverName]
380+
hasChanges = true
381+
}
382+
383+
if (removedBuiltInServers.delete(serverName)) {
384+
removedListChanged = true
393385
}
394386
}
395387

388+
if (hasChanges) {
389+
this.mcpStore.set('mcpServers', servers)
390+
}
391+
392+
if (removedListChanged) {
393+
this.setRemovedBuiltInServers(Array.from(removedBuiltInServers))
394+
}
395+
396396
return servers
397397
}
398398

@@ -913,15 +913,9 @@ export class McpConfHelper {
913913
}
914914

915915
try {
916-
const mcpServers = this.mcpStore.get('mcpServers') || {}
917-
918-
if (mcpServers.powerpack) {
919-
console.log('Removing deprecated powerpack MCP server')
920-
delete mcpServers.powerpack
921-
this.mcpStore.set('mcpServers', mcpServers)
922-
}
916+
this.removeDeprecatedBuiltInServers(this.mcpStore.get('mcpServers') || {})
923917
} catch (error) {
924-
console.error('Error occurred while removing deprecated powerpack server:', error)
918+
console.error('Error occurred while removing deprecated built-in MCP servers:', error)
925919
}
926920

927921
// 升级后检查并添加平台特有服务

src/main/presenter/deepchatAgentPresenter/dispatch.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -679,6 +679,20 @@ export async function executeTools(
679679
}
680680
}
681681

682+
if (hooks?.normalizeToolResult) {
683+
toolRawData = {
684+
...toolRawData,
685+
content: await hooks.normalizeToolResult({
686+
sessionId: io.sessionId,
687+
toolCallId: tc.id,
688+
toolName: tc.name,
689+
toolArgs: tc.arguments,
690+
content: toolRawData.content,
691+
isError: toolRawData.isError === true
692+
})
693+
}
694+
}
695+
682696
const searchPayload = extractSearchPayload(
683697
toolRawData.content,
684698
toolContext.name,

0 commit comments

Comments
 (0)