Skip to content

Commit 11ba202

Browse files
authored
release: 0.5.0
Release 0.5.0
2 parents 1ab64f5 + f1c7dde commit 11ba202

Some content is hidden

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

58 files changed

+1165
-386
lines changed

build/entitlements.mac.plist

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
<true/>
1313
<key>com.apple.security.files.user-selected.read-only</key>
1414
<true/>
15+
<key>com.apple.security.network.client</key>
16+
<true/>
1517
<key>com.apple.security.cs.disable-library-validation</key>
1618
<true/>
1719
</dict>

electron-builder-macx64.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ productName: DeepChat
33
directories:
44
buildResources: build
55
files:
6+
- '!**/.claude/*'
7+
- '!**/.github/*'
8+
- '!**/.cursor/*'
69
- '!**/.vscode/*'
710
- '!src/*'
811
- '!test/*'
@@ -29,6 +32,9 @@ extraResources:
2932
- from: ./runtime/
3033
to: app.asar.unpacked/runtime
3134
filter: ['**/*']
35+
- from: ./resources/cdn/
36+
to: app.asar.unpacked/resources/cdn
37+
filter: ['**/*']
3238
afterSign: scripts/notarize.js
3339
afterPack: scripts/afterPack.js
3440
electronLanguages:

electron-builder.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ productName: DeepChat
33
directories:
44
buildResources: build
55
files:
6+
- '!**/.claude/*'
7+
- '!**/.github/*'
8+
- '!**/.cursor/*'
69
- '!**/.vscode/*'
710
- '!src/*'
811
- '!test/*'
@@ -30,6 +33,9 @@ extraResources:
3033
- from: ./runtime/
3134
to: app.asar.unpacked/runtime
3235
filter: ['**/*']
36+
- from: ./resources/cdn/
37+
to: app.asar.unpacked/resources/cdn
38+
filter: ['**/*']
3339
electronLanguages:
3440
- zh-CN
3541
- zh-TW

electron.vite.config.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,14 @@ export default defineConfig({
7979
return path.resolve(buildOutDir, 'monacoeditorwork')
8080
},
8181
}),
82-
vue(),
82+
vue({
83+
template: {
84+
compilerOptions: {
85+
// 将所有带短横线的标签名都视为自定义元素
86+
isCustomElement: (tag) => tag.startsWith('ui-resource-renderer')
87+
}
88+
}
89+
}),
8390
svgLoader(),
8491
vueDevTools()
8592
],

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "DeepChat",
3-
"version": "0.4.9",
3+
"version": "0.5.0",
44
"description": "DeepChat,一个简单易用的AI客户端",
55
"main": "./out/main/index.js",
66
"author": "ThinkInAIXYZ",
@@ -107,6 +107,7 @@
107107
"@iconify-json/vscode-icons": "^1.2.33",
108108
"@iconify/vue": "^5.0.0",
109109
"@lingual/i18n-check": "0.8.12",
110+
"@mcp-ui/client": "^5.13.1",
110111
"@pinia/colada": "^0.17.8",
111112
"@prettier/plugin-oxc": "^0.0.4",
112113
"@tailwindcss/typography": "^0.5.19",
@@ -171,7 +172,7 @@
171172
"vitest": "^3.2.4",
172173
"vue": "^3.5.24",
173174
"vue-i18n": "^11.1.12",
174-
"vue-renderer-markdown": "0.0.63-beta.0",
175+
"markstream-vue": "^0.0.1",
175176
"vue-router": "4",
176177
"vue-sonner": "^2.0.9",
177178
"vue-tsc": "^2.2.12",

src/main/presenter/llmProviderPresenter/agent/acpProcessManager.ts

Lines changed: 70 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -266,125 +266,92 @@ export class AcpProcessManager implements AgentProcessManager<AcpProcessHandle,
266266
processedArgs.some((arg) => typeof arg === 'string' && arg.includes(cmd))
267267
)
268268

269-
// Define allowed environment variables whitelist for Node.js/UV commands
270-
const allowedEnvVars = [
271-
'PATH',
272-
'path',
273-
'Path',
274-
'npm_config_registry',
275-
'npm_config_cache',
276-
'npm_config_prefix',
277-
'npm_config_tmp',
278-
'NPM_CONFIG_REGISTRY',
279-
'NPM_CONFIG_CACHE',
280-
'NPM_CONFIG_PREFIX',
281-
'NPM_CONFIG_TMP',
282-
'ANTHROPIC_BASE_URL',
283-
'ANTHROPIC_AUTH_TOKEN',
284-
'ANTHROPIC_MODEL',
285-
'OPENAI_BASE_URL',
286-
'OPENAI_API_KEY'
287-
]
288-
289269
const HOME_DIR = app.getPath('home')
290270
const env: Record<string, string> = {}
271+
Object.entries(process.env).forEach(([key, value]) => {
272+
if (value !== undefined && value !== '') {
273+
env[key] = value
274+
}
275+
})
291276
let pathKey = process.platform === 'win32' ? 'Path' : 'PATH'
292277
let pathValue = ''
293278

294279
if (isNodeCommand) {
295-
// Node.js/UV commands use whitelist processing
296-
if (process.env) {
297-
const existingPaths: string[] = []
298-
299-
// Collect all PATH-related values
300-
Object.entries(process.env).forEach(([key, value]) => {
301-
if (value !== undefined && value !== '') {
302-
if (['PATH', 'Path', 'path'].includes(key)) {
303-
existingPaths.push(value)
304-
} else if (allowedEnvVars.includes(key) && !['PATH', 'Path', 'path'].includes(key)) {
305-
env[key] = value
306-
}
280+
// Node.js/UV commands need full environment propagation similar to ACP init
281+
const existingPaths: string[] = []
282+
const pathKeys = ['PATH', 'Path', 'path']
283+
pathKeys.forEach((key) => {
284+
const value = env[key]
285+
if (value) {
286+
existingPaths.push(value)
287+
}
288+
})
289+
290+
// Get shell environment variables regardless of runtime choice
291+
let shellEnv: Record<string, string> = {}
292+
try {
293+
shellEnv = await getShellEnvironment()
294+
console.info(`[ACP] Retrieved shell environment variables for agent ${agent.id}`)
295+
Object.entries(shellEnv).forEach(([key, value]) => {
296+
if (value !== undefined && value !== '' && !pathKeys.includes(key)) {
297+
env[key] = value
307298
}
308299
})
300+
} catch (error) {
301+
console.warn(
302+
`[ACP] Failed to get shell environment variables for agent ${agent.id}, using fallback:`,
303+
error
304+
)
305+
}
309306

310-
// Get shell environment variables when not using builtin runtime
311-
// This ensures nvm/n/fnm/volta paths are available
312-
let shellEnv: Record<string, string> = {}
313-
if (!useBuiltinRuntime) {
314-
try {
315-
shellEnv = await getShellEnvironment()
316-
console.info(`[ACP] Retrieved shell environment variables for agent ${agent.id}`)
317-
318-
// Merge shell environment variables (except PATH which we handle separately)
319-
Object.entries(shellEnv).forEach(([key, value]) => {
320-
if (!['PATH', 'Path', 'path'].includes(key) && value) {
321-
env[key] = value
322-
}
323-
})
324-
} catch (error) {
325-
console.warn(
326-
`[ACP] Failed to get shell environment variables for agent ${agent.id}, using fallback:`,
327-
error
328-
)
329-
}
330-
}
307+
// Get shell PATH if available (priority: shell PATH > existing PATH)
308+
const shellPath = shellEnv.PATH || shellEnv.Path || shellEnv.path
309+
if (shellPath) {
310+
const shellPaths = shellPath.split(process.platform === 'win32' ? ';' : ':')
311+
existingPaths.unshift(...shellPaths)
312+
console.info(`[ACP] Using shell PATH for agent ${agent.id} (length: ${shellPath.length})`)
313+
}
331314

332-
// Get shell PATH if available (priority: shell PATH > existing PATH)
333-
const shellPath = shellEnv.PATH || shellEnv.Path
334-
if (shellPath) {
335-
// Use shell PATH as base, then merge existing paths
336-
const shellPaths = shellPath.split(process.platform === 'win32' ? ';' : ':')
337-
existingPaths.unshift(...shellPaths)
338-
console.info(`[ACP] Using shell PATH for agent ${agent.id} (length: ${shellPath.length})`)
339-
}
315+
// Get default paths
316+
const defaultPaths = this.runtimeHelper.getDefaultPaths(HOME_DIR)
340317

341-
// Get default paths
342-
const defaultPaths = this.runtimeHelper.getDefaultPaths(HOME_DIR)
343-
344-
// Merge all paths (priority: shell PATH > existing PATH > default paths)
345-
const allPaths = [...existingPaths, ...defaultPaths]
346-
// Add runtime paths only when using builtin runtime
347-
if (useBuiltinRuntime) {
348-
const uvRuntimePath = this.runtimeHelper.getUvRuntimePath()
349-
const nodeRuntimePath = this.runtimeHelper.getNodeRuntimePath()
350-
if (process.platform === 'win32') {
351-
// Windows platform only adds node and uv paths
352-
if (uvRuntimePath) {
353-
allPaths.unshift(uvRuntimePath)
354-
console.info(`[ACP] Added UV runtime path to PATH: ${uvRuntimePath}`)
355-
}
356-
if (nodeRuntimePath) {
357-
allPaths.unshift(nodeRuntimePath)
358-
console.info(`[ACP] Added Node runtime path to PATH: ${nodeRuntimePath}`)
359-
}
360-
} else {
361-
// Other platforms priority: node > uv
362-
if (uvRuntimePath) {
363-
allPaths.unshift(uvRuntimePath)
364-
console.info(`[ACP] Added UV runtime path to PATH: ${uvRuntimePath}`)
365-
}
366-
if (nodeRuntimePath) {
367-
const nodeBinPath = path.join(nodeRuntimePath, 'bin')
368-
allPaths.unshift(nodeBinPath)
369-
console.info(`[ACP] Added Node bin path to PATH: ${nodeBinPath}`)
370-
}
318+
// Merge all paths (priority: shell PATH > existing PATH > default paths)
319+
const allPaths = [...existingPaths, ...defaultPaths]
320+
// Add runtime paths only when using builtin runtime
321+
if (useBuiltinRuntime) {
322+
const uvRuntimePath = this.runtimeHelper.getUvRuntimePath()
323+
const nodeRuntimePath = this.runtimeHelper.getNodeRuntimePath()
324+
if (process.platform === 'win32') {
325+
// Windows platform only adds node and uv paths
326+
if (uvRuntimePath) {
327+
allPaths.unshift(uvRuntimePath)
328+
console.info(`[ACP] Added UV runtime path to PATH: ${uvRuntimePath}`)
329+
}
330+
if (nodeRuntimePath) {
331+
allPaths.unshift(nodeRuntimePath)
332+
console.info(`[ACP] Added Node runtime path to PATH: ${nodeRuntimePath}`)
333+
}
334+
} else {
335+
// Other platforms priority: node > uv
336+
if (uvRuntimePath) {
337+
allPaths.unshift(uvRuntimePath)
338+
console.info(`[ACP] Added UV runtime path to PATH: ${uvRuntimePath}`)
339+
}
340+
if (nodeRuntimePath) {
341+
const nodeBinPath = path.join(nodeRuntimePath, 'bin')
342+
allPaths.unshift(nodeBinPath)
343+
console.info(`[ACP] Added Node bin path to PATH: ${nodeBinPath}`)
371344
}
372345
}
373-
374-
// Normalize and set PATH
375-
const normalized = this.runtimeHelper.normalizePathEnv(allPaths)
376-
pathKey = normalized.key
377-
pathValue = normalized.value
378-
env[pathKey] = pathValue
379346
}
347+
348+
// Normalize and set PATH
349+
const normalized = this.runtimeHelper.normalizePathEnv(allPaths)
350+
pathKey = normalized.key
351+
pathValue = normalized.value
352+
env[pathKey] = pathValue
380353
} else {
381354
// Non Node.js/UV commands, preserve all system environment variables, only supplement PATH
382-
Object.entries(process.env).forEach(([key, value]) => {
383-
if (value !== undefined && value !== '') {
384-
env[key] = value
385-
}
386-
})
387-
388355
// Supplement PATH
389356
const existingPaths: string[] = []
390357
if (env.PATH) {

src/main/presenter/mcpPresenter/inMemoryServers/autoPromptingServer.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
import { Server } from '@modelcontextprotocol/sdk/server/index.js'
2-
import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js'
2+
import {
3+
CallToolRequestSchema,
4+
ListToolsRequestSchema,
5+
type CallToolRequest
6+
} from '@modelcontextprotocol/sdk/types.js'
37
import { Transport } from '@modelcontextprotocol/sdk/shared/transport.js'
48
import { z } from 'zod'
59
import { zodToJsonSchema } from 'zod-to-json-schema'
@@ -123,7 +127,7 @@ export class AutoPromptingServer {
123127
}
124128

125129
// 处理工具调用 (对应 CallToolRequestSchema)
126-
private async handleToolCall(request: z.infer<typeof CallToolRequestSchema>) {
130+
private async handleToolCall(request: CallToolRequest) {
127131
const { name, arguments: args } = request.params
128132

129133
if (name === 'list_all_prompt_template_names') {

src/main/presenter/threadPresenter/exporters/conversationExporter.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,16 @@ function exportToMarkdown(conversation: CONVERSATION, messages: Message[]): stri
138138
}
139139
lines.push('')
140140
break
141+
case 'mcp_ui_resource':
142+
if (block.mcp_ui_resource) {
143+
lines.push('### 🧩 MCP UI 资源')
144+
lines.push('')
145+
lines.push(
146+
`资源: ${block.mcp_ui_resource.uri} (${block.mcp_ui_resource.mimeType ?? ''})`
147+
)
148+
lines.push('')
149+
}
150+
break
141151
case 'image':
142152
lines.push('### 🖼️ 图片')
143153
lines.push('*[图片内容]*')
@@ -358,6 +368,17 @@ function exportToHtml(conversation: CONVERSATION, messages: Message[]): string {
358368
})
359369
)
360370
break
371+
case 'mcp_ui_resource':
372+
if (block.mcp_ui_resource) {
373+
blockLines.push(
374+
...renderTemplate(templates.assistantContent, {
375+
content: formatInlineHtml(
376+
`MCP UI 资源: ${block.mcp_ui_resource.uri} (${block.mcp_ui_resource.mimeType ?? ''})`
377+
)
378+
})
379+
)
380+
}
381+
break
361382
case 'image':
362383
blockLines.push(...renderTemplate(templates.assistantImage))
363384
break
@@ -534,6 +555,13 @@ function exportToText(conversation: CONVERSATION, messages: Message[]): string {
534555
}
535556
lines.push('')
536557
break
558+
case 'mcp_ui_resource':
559+
if (block.mcp_ui_resource) {
560+
lines.push('[MCP UI 资源]')
561+
lines.push(`${block.mcp_ui_resource.uri} (${block.mcp_ui_resource.mimeType ?? ''})`)
562+
lines.push('')
563+
}
564+
break
537565
case 'image':
538566
lines.push('[图片内容]')
539567
lines.push('')

src/main/presenter/threadPresenter/handlers/llmEventHandler.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ export class LLMEventHandler {
111111

112112
if (tool_call_response_raw && tool_call === 'end') {
113113
await this.toolCallHandler.processSearchResultsFromToolCall(state, msg, currentTime)
114+
await this.toolCallHandler.processMcpUiResourcesFromToolCall(state, msg, currentTime)
114115
}
115116

116117
if (tool_call) {

0 commit comments

Comments
 (0)