Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions archives/code/dead-code-batch-3/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Dead Code Batch 3

- Purpose: archive retired MCP runtime code that is no longer part of the active in-memory server set.
- Archived at: 2026-03-26
- 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.

## Archived Paths

- `src/main/presenter/mcpPresenter/inMemoryServers/meetingServer.ts`

## Notes

- This directory is not part of the runtime, build, typecheck, or test target set.
- Restore by moving files back to their original paths only if a future audit proves the retired MCP server is needed again.
4 changes: 2 additions & 2 deletions scripts/generate-i18n-types.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import fs from 'fs'
import path from 'path'
import { fileURLToPath } from 'url'
import { fileURLToPath, pathToFileURL } from 'url'

const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)
Expand Down Expand Up @@ -57,6 +57,6 @@ async function main() {
}

// 仅需要在本地开发时执行
if (import.meta.url === `file://${process.argv[1]}`) {
if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
main()
}
5 changes: 0 additions & 5 deletions src/main/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -219,11 +219,6 @@ export const TRAY_EVENTS = {
CHECK_FOR_UPDATES: 'tray:check-for-updates' // 托盘检查更新
}

// MCP会议专用事件
export const MEETING_EVENTS = {
INSTRUCTION: 'mcp:meeting-instruction' // 主进程向渲染进程发送指令
}

// 悬浮按钮相关事件
export const FLOATING_BUTTON_EVENTS = {
CLICKED: 'floating-button:clicked', // 悬浮按钮被点击
Expand Down
110 changes: 75 additions & 35 deletions src/main/presenter/configPresenter/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ interface IAppSettings {
enableSkills?: boolean // Skills system global toggle
hooksNotifications?: HooksNotificationsSettings // Hooks & notifications settings
defaultModel?: { providerId: string; modelId: string } // Default model for new conversations
defaultVisionModel?: { providerId: string; modelId: string } // Default vision model for image tools
defaultVisionModel?: { providerId: string; modelId: string } // Legacy vision model setting for migration only
defaultProjectPath?: string | null
acpRegistryMigrationVersion?: number
unifiedAgentsMigrationVersion?: number
Expand Down Expand Up @@ -153,6 +153,15 @@ const isModelSelection = (value: unknown): value is ModelSelection => {
return typeof record.providerId === 'string' && typeof record.modelId === 'string'
}

const normalizeKnownModelId = (modelId: string): string => {
const normalizedModelId = modelId.trim().toLowerCase()
return normalizedModelId.replace(/^models\//, '')
}

const normalizeKnownProviderId = (providerId: string): string =>
modelCapabilities.resolveProviderId(providerId.trim().toLowerCase()) ||
providerId.trim().toLowerCase()

export const getAnthropicModelSelectionKeysToClear = (
settings: Partial<
Record<
Expand Down Expand Up @@ -362,6 +371,7 @@ export class ConfigPresenter implements IConfigPresenter {
setAgentRepository(agentRepository: AgentRepository): void {
this.agentRepository = agentRepository
this.initializeUnifiedAgents()
this.migrateLegacyDefaultVisionModelToBuiltinAgent()
}

private getAgentRepositoryOrThrow(): AgentRepository {
Expand Down Expand Up @@ -396,6 +406,35 @@ export class ConfigPresenter implements IConfigPresenter {
this.syncRegistryAgentsToRepository()
}

private migrateLegacyDefaultVisionModelToBuiltinAgent(): void {
const legacySelection = this.store.get('defaultVisionModel') as unknown
if (legacySelection === undefined) {
return
}

const builtinVisionModel = this.getBuiltinDeepChatConfig().visionModel

if (
isModelSelection(legacySelection) &&
(!builtinVisionModel?.providerId || !builtinVisionModel?.modelId)
) {
const providerId = legacySelection.providerId.trim()
const modelId = legacySelection.modelId.trim()

if (providerId && modelId) {
this.updateBuiltinDeepChatConfig({
visionModel: {
providerId,
modelId
}
})
}
}

this.store.delete('defaultVisionModel')
eventBus.sendToMain(CONFIG_EVENTS.SETTING_CHANGED, 'defaultVisionModel', undefined)
}

private buildLegacyBuiltinDeepChatConfig(): DeepChatAgentConfig {
const defaultModel = this.store.get('defaultModel') as ModelSelection | undefined
const assistantModel = this.store.get('assistantModel') as ModelSelection | undefined
Expand Down Expand Up @@ -760,7 +799,9 @@ export class ConfigPresenter implements IConfigPresenter {
const keysToClear = getAnthropicModelSelectionKeysToClear({
defaultModel: this.getSetting('defaultModel'),
assistantModel: this.getSetting('assistantModel'),
defaultVisionModel: this.getSetting('defaultVisionModel'),
defaultVisionModel: this.store.get('defaultVisionModel') as
| { providerId: string; modelId: string }
| undefined,
preferredModel: this.getSetting('preferredModel')
})

Expand All @@ -780,9 +821,6 @@ export class ConfigPresenter implements IConfigPresenter {
if (key === 'assistantModel') {
return this.getBuiltinDeepChatConfig().assistantModel as T | undefined
}
if (key === 'defaultVisionModel') {
return this.getDefaultVisionModel() as T | undefined
}
if (key === 'default_system_prompt') {
return this.getBuiltinDeepChatConfig().systemPrompt as T | undefined
}
Expand All @@ -808,10 +846,6 @@ export class ConfigPresenter implements IConfigPresenter {
eventBus.sendToMain(CONFIG_EVENTS.SETTING_CHANGED, key, value)
return
}
if (key === 'defaultVisionModel') {
this.setDefaultVisionModel(value as { providerId: string; modelId: string } | undefined)
return
}
if (key === 'default_system_prompt') {
this.updateBuiltinDeepChatConfig({
systemPrompt: typeof value === 'string' ? value : ''
Expand Down Expand Up @@ -1015,6 +1049,26 @@ export class ConfigPresenter implements IConfigPresenter {
return this.providerModelHelper.getCustomModels(providerId)
}

isKnownModel(providerId: string, modelId: string): boolean {
const normalizedProviderId = normalizeKnownProviderId(providerId)
const normalizedModelId = normalizeKnownModelId(modelId)

if (!normalizedProviderId || !normalizedModelId) {
return false
}

const hasKnownModel = (models: Array<{ id: string }> | undefined): boolean =>
Array.isArray(models) &&
models.some((model) => normalizeKnownModelId(model.id) === normalizedModelId)

return (
this.hasUserModelConfig(normalizedModelId, normalizedProviderId) ||
hasKnownModel(this.getProviderModels(normalizedProviderId)) ||
hasKnownModel(this.getCustomModels(normalizedProviderId)) ||
hasKnownModel(this.getDbProviderModels(normalizedProviderId))
)
}

setCustomModels(providerId: string, models: MODEL_META[]): void {
this.providerModelHelper.setCustomModels(providerId, models)
}
Expand Down Expand Up @@ -1688,6 +1742,18 @@ export class ConfigPresenter implements IConfigPresenter {
)
}

async agentSupportsCapability(agentId: string, capability: 'vision'): Promise<boolean> {
if (capability !== 'vision') {
return false
}

const agentConfig = await this.resolveDeepChatAgentConfig(agentId)
const providerId = agentConfig.visionModel?.providerId?.trim()
const modelId = agentConfig.visionModel?.modelId?.trim()

return Boolean(providerId && modelId && this.getModelConfig(modelId, providerId)?.vision)
}

async createDeepChatAgent(input: CreateDeepChatAgentInput): Promise<Agent> {
const created = this.getAgentRepositoryOrThrow().createDeepChatAgent(input)
this.notifyAcpAgentsChanged()
Expand Down Expand Up @@ -2312,32 +2378,6 @@ export class ConfigPresenter implements IConfigPresenter {
eventBus.sendToMain(CONFIG_EVENTS.SETTING_CHANGED, 'defaultModel', model)
}

getDefaultVisionModel(): { providerId: string; modelId: string } | undefined {
const selection = this.getBuiltinDeepChatConfig().visionModel
if (selection?.providerId && selection?.modelId) {
return {
providerId: selection.providerId,
modelId: selection.modelId
}
}
return this.store.get('defaultVisionModel') as
| { providerId: string; modelId: string }
| undefined
}

setDefaultVisionModel(model: { providerId: string; modelId: string } | undefined): void {
this.updateBuiltinDeepChatConfig({
visionModel:
model?.providerId && model?.modelId
? {
providerId: model.providerId,
modelId: model.modelId
}
: null
})
eventBus.sendToMain(CONFIG_EVENTS.SETTING_CHANGED, 'defaultVisionModel', model)
}

getDefaultProjectPath(): string | null {
const path = this.getSetting<string | null>('defaultProjectPath')
return path?.trim() ? path.trim() : null
Expand Down
52 changes: 23 additions & 29 deletions src/main/presenter/configPresenter/mcpConfHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,16 +165,6 @@ const DEFAULT_INMEMORY_SERVERS: Record<string, Omit<MCPServerConfig, 'enabled'>>
},
disable: false
},
imageServer: {
args: [],
descriptions: 'Image processing MCP service',
icons: '🖼️',
autoApprove: ['read_image_base64', 'read_multiple_images_base64'], // Auto-approve reading, require confirmation for uploads
type: 'inmemory' as MCPServerType,
command: 'image', // We need to map this command to the ImageServer class later
env: {},
disable: false
},
ragflowKnowledge: {
args: [],
descriptions: 'DeepChat内置RAGFlow知识库检索服务',
Expand Down Expand Up @@ -258,16 +248,6 @@ const DEFAULT_INMEMORY_SERVERS: Record<string, Omit<MCPServerConfig, 'enabled'>>
env: {},
disable: false
},
'deepchat-inmemory/meeting-server': {
args: [],
descriptions: 'DeepChat内置会议服务,用于组织多Agent讨论',
icons: '👥',
autoApprove: ['all'],
type: 'inmemory' as MCPServerType,
command: 'deepchat-inmemory/meeting-server',
env: {},
disable: false
},
// Merge platform-specific services
...PLATFORM_SPECIFIC_SERVERS
}
Expand Down Expand Up @@ -384,15 +364,35 @@ export class McpConfHelper {
private removeDeprecatedBuiltInServers(
servers: Record<string, MCPServerConfig>
): Record<string, MCPServerConfig> {
const deprecatedBuiltInServers = ['powerpack']
const deprecatedBuiltInServers = [
'powerpack',
'deepchat-inmemory/meeting-server',
'imageServer'
]
let hasChanges = false
const removedBuiltInServers = new Set(this.getRemovedBuiltInServers())
let removedListChanged = false

for (const serverName of deprecatedBuiltInServers) {
if (servers[serverName]) {
console.log(`Removing deprecated built-in MCP service: ${serverName}`)
delete servers[serverName]
hasChanges = true
}

if (removedBuiltInServers.delete(serverName)) {
removedListChanged = true
}
}

if (hasChanges) {
this.mcpStore.set('mcpServers', servers)
}

if (removedListChanged) {
this.setRemovedBuiltInServers(Array.from(removedBuiltInServers))
}

return servers
}

Expand Down Expand Up @@ -913,15 +913,9 @@ export class McpConfHelper {
}

try {
const mcpServers = this.mcpStore.get('mcpServers') || {}

if (mcpServers.powerpack) {
console.log('Removing deprecated powerpack MCP server')
delete mcpServers.powerpack
this.mcpStore.set('mcpServers', mcpServers)
}
this.removeDeprecatedBuiltInServers(this.mcpStore.get('mcpServers') || {})
} catch (error) {
console.error('Error occurred while removing deprecated powerpack server:', error)
console.error('Error occurred while removing deprecated built-in MCP servers:', error)
}

// 升级后检查并添加平台特有服务
Expand Down
14 changes: 14 additions & 0 deletions src/main/presenter/deepchatAgentPresenter/dispatch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -679,6 +679,20 @@ export async function executeTools(
}
}

if (hooks?.normalizeToolResult) {
toolRawData = {
...toolRawData,
content: await hooks.normalizeToolResult({
sessionId: io.sessionId,
toolCallId: tc.id,
toolName: tc.name,
toolArgs: tc.arguments,
content: toolRawData.content,
isError: toolRawData.isError === true
})
}
}

const searchPayload = extractSearchPayload(
toolRawData.content,
toolContext.name,
Expand Down
Loading
Loading