Skip to content

Commit 39adfff

Browse files
committed
发布 6.0.2
1 parent fb7935a commit 39adfff

11 files changed

Lines changed: 100 additions & 26 deletions

File tree

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,19 @@
1010
### 变更
1111
- 暂无
1212

13+
## [6.0.2] - 2026-05-16
14+
15+
### 新增
16+
- Agent 支持注入已连接 MCP 服务的工具 schema,并可在对话中带入选中的 Skill 内容。
17+
- 新增会话导出卡片入口,完善 Agent 页面里的会话导出体验。
18+
19+
### 优化
20+
- 重构缓存路径获取逻辑,统一通过独立路径函数解析缓存位置。
21+
- 增强 Agent 作用域会话与内置工具协同能力。
22+
23+
### 修复
24+
- 修复通讯录导出预览中普通联系人被 `local_type` 误过滤,导致默认只勾选好友时左侧列表显示“暂无联系人”的问题。
25+
1326
## [6.0.1] - 2026-05-14
1427

1528
### 修复

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
**一款现代化的微信聊天记录查看与分析工具**
88

99
[![License](https://img.shields.io/badge/license-CC--BY--NC--SA--4.0-blue.svg)](LICENSE)
10-
[![Version](https://img.shields.io/badge/version-6.0.1-green.svg)](package.json)
10+
[![Version](https://img.shields.io/badge/version-6.0.2-green.svg)](package.json)
1111
[![Platform](https://img.shields.io/badge/platform-Windows-0078D6.svg?logo=windows)]()
1212
[![Electron](https://img.shields.io/badge/Electron-39-47848F.svg?logo=electron)]()
1313
[![React](https://img.shields.io/badge/React-19-61DAFB.svg?logo=react)]()

electron/main/ipc/agentHandlers.ts

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,7 @@ export function registerAgentHandlers(ctx: MainProcessContext): void {
239239
readLimit?: number
240240
enabledTools?: Array<{ type: string; function: { name: string; description?: string; parameters?: Record<string, unknown> } }>
241241
scopedSessions?: Array<{ id: string; name: string }>
242+
skillIds?: string[]
242243
}) => {
243244
const requestId = options.requestId?.trim() || genRequestId()
244245
if (requestMap.has(requestId)) {
@@ -289,7 +290,19 @@ export function registerAgentHandlers(ctx: MainProcessContext): void {
289290
}
290291
try {
291292
const { BUILTIN_TOOL_SCHEMAS } = await import('../../services/agentBuiltinTools')
292-
const mergedTools = [...BUILTIN_TOOL_SCHEMAS, ...(options.enabledTools || [])]
293+
const { mcpClientService } = await import('../../services/mcpClientService')
294+
const mcpToolSchemas = mcpClientService.getConnectedToolSchemas()
295+
.flatMap(({ serverName, tools }) =>
296+
tools.map(tool => ({
297+
type: 'function' as const,
298+
function: {
299+
name: `${serverName}__${tool.name}`,
300+
description: tool.description || '',
301+
parameters: (tool.inputSchema as Record<string, unknown>) ?? { type: 'object', properties: {} },
302+
}
303+
}))
304+
)
305+
const mergedTools = [...BUILTIN_TOOL_SCHEMAS, ...mcpToolSchemas, ...(options.enabledTools || [])]
293306

294307
const suffixParts: string[] = []
295308
if (options.scopedSessions && options.scopedSessions.length > 0) {
@@ -299,6 +312,15 @@ export function registerAgentHandlers(ctx: MainProcessContext): void {
299312
if (options.commandHint) {
300313
suffixParts.push(options.commandHint)
301314
}
315+
if (options.skillIds && options.skillIds.length > 0) {
316+
const { skillManagerService } = await import('../../services/skillManagerService')
317+
for (const skillId of options.skillIds) {
318+
const r = skillManagerService.readSkillContent(skillId)
319+
if (r.success && r.content) {
320+
suffixParts.push(r.content)
321+
}
322+
}
323+
}
302324
const systemPromptSuffix = suffixParts.length > 0 ? suffixParts.join('\n\n') : undefined
303325

304326
assistantText = await agentChatService.sendMessage({

electron/preload.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -741,6 +741,7 @@ contextBridge.exposeInMainWorld('electronAPI', {
741741
readLimit?: number
742742
enabledTools?: Array<{ type: string; function: { name: string; description?: string; parameters?: Record<string, unknown> } }>
743743
scopedSessions?: Array<{ id: string; name: string }>
744+
skillIds?: string[]
744745
}) => ipcRenderer.invoke('agent:sendMessage', opts),
745746

746747
cancel: (requestId: string) => ipcRenderer.invoke('agent:cancel', requestId),

electron/services/chatService.ts

Lines changed: 42 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,44 @@ export interface ContactInfo {
3737
lastContactTime?: number
3838
}
3939

40+
const SYSTEM_CONTACT_USERNAMES = new Set([
41+
'filehelper',
42+
'fmessage',
43+
'floatbottle',
44+
'medianote',
45+
'newsapp',
46+
'qmessage',
47+
'qqmail',
48+
'weixin',
49+
'brandsessionholder',
50+
'brandservicesessionholder',
51+
'notifymessage',
52+
'opencustomerservicemsg',
53+
'notification_messages',
54+
'userexperience_alarm'
55+
])
56+
57+
function isSystemContactUsername(username: string): boolean {
58+
const lower = username.trim().toLowerCase()
59+
if (!lower) return true
60+
if (SYSTEM_CONTACT_USERNAMES.has(lower)) return true
61+
return lower.startsWith('fake_') || lower.includes('@kefu.openim') || lower.includes('service_')
62+
}
63+
64+
function detectContactInfoType(username: string, row: Record<string, any>): ContactInfo['type'] | null {
65+
const lower = username.trim().toLowerCase()
66+
if (isSystemContactUsername(lower)) return null
67+
if (lower.includes('@chatroom')) return 'group'
68+
if (lower.startsWith('gh_')) return 'official'
69+
70+
const rawType = row.local_type ?? row.type
71+
const numericType = rawType === null || rawType === undefined || rawType === '' ? Number.NaN : Number(rawType)
72+
if (Number.isFinite(numericType) && numericType === 3) return 'official'
73+
74+
// 不同微信版本的 contact.local_type 含义不稳定;普通个人号在排除系统号后应作为好友保留。
75+
return 'friend'
76+
}
77+
4078
export interface Message {
4179
localId: number
4280
serverId: number
@@ -607,11 +645,13 @@ class ChatService extends EventEmitter {
607645
const hasBigHeadUrl = columnNames.includes('big_head_url')
608646
const hasSmallHeadUrl = columnNames.includes('small_head_url')
609647
const hasLocalType = columnNames.includes('local_type')
648+
const hasType = columnNames.includes('type')
610649

611650
const selectCols = ['username', 'remark', 'nick_name', 'alias', 'quan_pin', 'flag']
612651
if (hasBigHeadUrl) selectCols.push('big_head_url')
613652
if (hasSmallHeadUrl) selectCols.push('small_head_url')
614653
if (hasLocalType) selectCols.push('local_type')
654+
if (hasType) selectCols.push('type')
615655

616656
const rows = await dbAdapter.all<any>(
617657
'contact',
@@ -620,27 +660,13 @@ class ChatService extends EventEmitter {
620660
)
621661

622662
const contacts: ContactInfo[] = []
623-
const excludeNames = ['medianote', 'floatbottle', 'qmessage', 'qqmail', 'fmessage']
624663

625664
for (const row of rows) {
626665
const username = row.username || ''
627666
if (!username) continue
628667

629-
let type: 'friend' | 'group' | 'official' | 'former_friend' | 'other' = 'other'
630-
const localType = hasLocalType ? (row.local_type || 0) : 0
631-
const quanPin = row.quan_pin || ''
632-
633-
if (username.includes('@chatroom')) {
634-
type = 'group'
635-
} else if (username.startsWith('gh_')) {
636-
type = 'official'
637-
} else if (/^(?!.*(gh_|@chatroom)).*$/.test(username) && localType === 1 && !excludeNames.includes(username)) {
638-
type = 'friend'
639-
} else if (/^(?!.*(gh_|@chatroom)).*$/.test(username) && localType === 0 && quanPin) {
640-
type = 'former_friend'
641-
} else {
642-
continue
643-
}
668+
const type = detectContactInfoType(username, row)
669+
if (!type) continue
644670

645671
const displayName = row.remark || row.nick_name || row.alias || username
646672
let avatarUrl: string | undefined

electron/services/mcpClientService.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,16 @@ export class McpClientService {
309309
return results
310310
}
311311

312+
getConnectedToolSchemas(): Array<{ serverName: string; tools: McpToolInfo[] }> {
313+
const result: Array<{ serverName: string; tools: McpToolInfo[] }> = []
314+
for (const [name, conn] of this.connections) {
315+
if (conn.tools.length > 0) {
316+
result.push({ serverName: name, tools: conn.tools })
317+
}
318+
}
319+
return result
320+
}
321+
312322
async restoreSavedConnections(): Promise<void> {
313323
const configs = loadConfigs()
314324
const targets = Object.entries(configs)

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "ciphertalk",
3-
"version": "6.0.1",
3+
"version": "6.0.2",
44
"description": "密语 - 微信聊天记录查看工具",
55
"author": "ILoveBingLu",
66
"license": "CC-BY-NC-SA-4.0",

src/pages/agent/components/ChatInput.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import type { McpServerStatus } from '../../../hooks/useMcpSkillsData'
1717
import type { AgentSkill, AttachedResource, McpServer, SlashCommand } from '../types'
1818

1919
interface Props {
20-
onSend: (text: string, attached: AttachedResource[], readLimit: number) => void
20+
onSend: (text: string, attached: AttachedResource[], readLimit: number, skillIds: string[]) => void
2121
disabled?: boolean
2222
suggestions: string[]
2323
slashCommands: SlashCommand[]
@@ -151,7 +151,7 @@ export function ChatInput({
151151
const submit = () => {
152152
const text = value.trim()
153153
if (!text || disabled) return
154-
onSend(text, attached, readLimit)
154+
onSend(text, attached, readLimit, [...enabledSkills])
155155
setValue('')
156156
setAttached([])
157157
closeAll()
@@ -189,7 +189,7 @@ export function ChatInput({
189189
{suggestions.length ? (
190190
<div className="agent-suggestions">
191191
{suggestions.map(suggestion => (
192-
<button key={suggestion} type="button" onClick={() => onSend(suggestion, [], readLimit)} disabled={disabled}>
192+
<button key={suggestion} type="button" onClick={() => onSend(suggestion, [], readLimit, [])} disabled={disabled}>
193193
<Sparkles size={12} />
194194
{suggestion}
195195
</button>

src/pages/agent/hooks/useAgentChat.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -529,7 +529,7 @@ export function useAgentChat() {
529529
}
530530
}, [])
531531

532-
const send = async (text: string, attached?: AttachedResource[], readLimit = 500) => {
532+
const send = async (text: string, attached?: AttachedResource[], readLimit = 500, skillIds?: string[]) => {
533533
lastReadLimitRef.current = readLimit
534534
const trimmed = text.trim()
535535
if (!trimmed || loading) return
@@ -655,7 +655,8 @@ export function useAgentChat() {
655655
enableThinking: forceThinking ?? providerSettings.enableThinking,
656656
commandHint,
657657
readLimit,
658-
scopedSessions: scopedSessions.length > 0 ? scopedSessions : undefined
658+
scopedSessions: scopedSessions.length > 0 ? scopedSessions : undefined,
659+
skillIds: skillIds && skillIds.length > 0 ? skillIds : undefined,
659660
})
660661

661662
if (!result.success) {

0 commit comments

Comments
 (0)