feat: 重构 AI 工具分类体系

This commit is contained in:
digua
2026-03-29 23:34:44 +08:00
committed by digua
parent e099dde435
commit 346a38da5a
16 changed files with 233 additions and 155 deletions
+9 -20
View File
@@ -1,31 +1,20 @@
/**
* 内置工具目录查询
*
* 提供前端展示所需的工具名称列表
* TS 工具名称列表位于 tools/definitions/index.ts
* SQL 工具名称列表位于 tools/definitions/sql-analysis.ts。
* 基于 TOOL_REGISTRY 提供前端展示所需的工具目录(含分类信息)
*/
import { SQL_TOOL_NAMES, getSqlToolCatalog } from '../tools/definitions/sql-analysis'
import { TS_TOOL_NAMES } from '../tools/definitions'
import { TOOL_REGISTRY } from '../tools/definitions'
import type { ToolCategory } from '../tools/types'
/**
* 获取所有内置工具的名称列表(TS + SQL,供前端展示勾选列表)
*/
export function getAllBuiltinToolNames(): string[] {
return [...TS_TOOL_NAMES, ...SQL_TOOL_NAMES]
export interface BuiltinToolCatalogEntry {
name: string
category: ToolCategory
}
/**
* 获取所有内置工具的目录信息(名称 + 描述,供前端展示
* 获取所有内置工具的目录(含分类),供前端展示
*/
export function getAllBuiltinToolCatalog(): Array<{ name: string; description: string }> {
return getSqlToolCatalog()
}
/**
* 获取内置 TS 工具的名称列表
*/
export function getBuiltinTsToolNames(): string[] {
return TS_TOOL_NAMES
export function getBuiltinToolCatalog(): BuiltinToolCatalogEntry[] {
return TOOL_REGISTRY.map((e) => ({ name: e.name, category: e.category }))
}
+1 -1
View File
@@ -19,4 +19,4 @@ export {
isGeneralAssistant,
} from './manager'
export { parseAssistantFile, serializeAssistant } from './parser'
export { getBuiltinTsToolNames, getAllBuiltinToolNames, getAllBuiltinToolCatalog } from './builtinTools'
export { getBuiltinToolCatalog, type BuiltinToolCatalogEntry } from './builtinTools'
+41 -28
View File
@@ -1,33 +1,46 @@
/**
* 工具定义聚合
* 收集 definitions/ 下所有工具的 createTool 工厂函数
* 工具定义聚合 + 统一注册表
*
* TOOL_REGISTRY 是全局唯一的工具清单,驱动后端加载和前端目录展示。
* 新增工具只需在此追加一条 ToolRegistryEntry。
*/
export { createTool as createSearchMessages } from './search-messages'
export { createTool as createGetRecentMessages } from './get-recent-messages'
export { createTool as createGetMemberStats } from './get-member-stats'
export { createTool as createGetTimeStats } from './get-time-stats'
export { createTool as createGetMembers } from './get-group-members'
export { createTool as createGetMemberNameHistory } from './get-member-name-history'
export { createTool as createGetConversationBetween } from './get-conversation-between'
export { createTool as createGetMessageContext } from './get-message-context'
export { createTool as createSearchSessions } from './search-sessions'
export { createTool as createGetSessionMessages } from './get-session-messages'
export { createTool as createGetSessionSummaries } from './get-session-summaries'
export { createTool as createGetChatOverview } from './get-chat-overview'
export { sqlToolFactories, getSqlToolCatalog, SQL_TOOL_NAMES } from './sql-analysis'
import type { ToolRegistryEntry } from '../types'
export const TS_TOOL_NAMES = [
'get_chat_overview',
'search_messages',
'get_recent_messages',
'get_member_stats',
'get_time_stats',
'get_members',
'get_member_name_history',
'get_conversation_between',
'get_message_context',
'search_sessions',
'get_session_messages',
'get_session_summaries',
import { createTool as createGetChatOverview } from './get-chat-overview'
import { createTool as createSearchMessages } from './search-messages'
import { createTool as createGetRecentMessages } from './get-recent-messages'
import { createTool as createGetMessageContext } from './get-message-context'
import { createTool as createSearchSessions } from './search-sessions'
import { createTool as createGetSessionMessages } from './get-session-messages'
import { createTool as createGetMembers } from './get-group-members'
import { createTool as createGetMemberStats } from './get-member-stats'
import { createTool as createGetTimeStats } from './get-time-stats'
import { createTool as createGetMemberNameHistory } from './get-member-name-history'
import { createTool as createGetConversationBetween } from './get-conversation-between'
import { createTool as createGetSessionSummaries } from './get-session-summaries'
import { sqlToolEntries } from './sql-analysis'
export { sqlToolEntries } from './sql-analysis'
export const TOOL_REGISTRY: ToolRegistryEntry[] = [
// ==================== Core 工具(始终加载) ====================
{ name: 'get_chat_overview', factory: createGetChatOverview, category: 'core' },
{ name: 'search_messages', factory: createSearchMessages, category: 'core' },
{ name: 'get_recent_messages', factory: createGetRecentMessages, category: 'core' },
{ name: 'get_message_context', factory: createGetMessageContext, category: 'core' },
{ name: 'search_sessions', factory: createSearchSessions, category: 'core' },
{ name: 'get_session_messages', factory: createGetSessionMessages, category: 'core' },
{ name: 'get_members', factory: createGetMembers, category: 'core' },
// ==================== Analysis 工具(按需加载) ====================
{ name: 'get_member_stats', factory: createGetMemberStats, category: 'analysis' },
{ name: 'get_time_stats', factory: createGetTimeStats, category: 'analysis' },
{ name: 'get_member_name_history', factory: createGetMemberNameHistory, category: 'analysis' },
{ name: 'get_conversation_between', factory: createGetConversationBetween, category: 'analysis' },
{ name: 'get_session_summaries', factory: createGetSessionSummaries, category: 'analysis' },
// SQL 分析工具
...sqlToolEntries,
]
@@ -6,7 +6,7 @@
*/
import type { AgentTool } from '@mariozechner/pi-agent-core'
import type { ToolContext } from '../types'
import type { ToolContext, ToolRegistryEntry } from '../types'
import type { CustomSqlToolDef } from '../../assistant/types'
import { createSqlTool } from '../../assistant/sqlToolRunner'
import { t as i18nT } from '../../../i18n'
@@ -193,6 +193,15 @@ export const sqlToolFactories = SQL_TOOL_DEFS.map(
createSqlTool(def, context)
)
/**
* SQL 工具注册表条目(全部为 analysis 类别)
*/
export const sqlToolEntries: ToolRegistryEntry[] = SQL_TOOL_DEFS.map((def) => ({
name: def.name,
factory: (context: ToolContext): AgentTool<any> => createSqlTool(def, context),
category: 'analysis' as const,
}))
/**
* 所有内置 SQL 工具的名称集合(用于前端分组展示)
*/
+13 -41
View File
@@ -7,21 +7,9 @@
import type { AgentTool } from '@mariozechner/pi-agent-core'
import type { ToolContext } from './types'
import {
createSearchMessages,
createGetRecentMessages,
createGetMemberStats,
createGetTimeStats,
createGetMembers,
createGetMemberNameHistory,
createGetConversationBetween,
createGetMessageContext,
createSearchSessions,
createGetSessionMessages,
createGetSessionSummaries,
createGetChatOverview,
sqlToolFactories,
} from './definitions'
import { TOOL_REGISTRY } from './definitions'
const CORE_TOOL_NAMES = new Set(TOOL_REGISTRY.filter((e) => e.category === 'core').map((e) => e.name))
import { t as i18nT } from '../../i18n'
import { preprocessMessages, type PreprocessableMessage } from '../preprocessor'
import { formatMessageCompact } from './utils/format'
@@ -31,24 +19,6 @@ import type { SkillDef } from '../skills/types'
// 导出类型
export * from './types'
type ToolFactory = (context: ToolContext) => AgentTool<any>
const coreFactories: ToolFactory[] = [
createGetChatOverview,
createSearchMessages,
createGetRecentMessages,
createGetMemberStats,
createGetTimeStats,
createGetMembers,
createGetMemberNameHistory,
createGetConversationBetween,
createGetMessageContext,
createSearchSessions,
createGetSessionMessages,
createGetSessionSummaries,
...sqlToolFactories,
]
/**
* 将工具返回的结构化数据格式化为 LLM 友好的纯文本
*
@@ -208,21 +178,23 @@ function anonymizeMessageNames(messages: PreprocessableMessage[], ownerPlatformI
/**
* 获取所有可用的 AgentTool
*
* 根据配置动态过滤工具(如:语义搜索工具仅在启用 Embedding 时可用)
* 根据当前 locale 动态翻译工具描述
* 统一包装预处理层
* - Core 工具始终加载,不受 allowedTools 白名单影响
* - Analysis 工具仅在 allowedTools 中显式列出时才加载(opt-in)
*
* @param context 工具上下文
* @param allowedTools 工具名称白名单(为空或 undefined 时返回全部工具)
* @param allowedTools analysis 工具白名单(仅控制 analysis 工具)
*/
export function getAllTools(context: ToolContext, allowedTools?: string[]): AgentTool<any>[] {
let tools: AgentTool<any>[] = coreFactories.map((f) => f(context))
const coreTools = TOOL_REGISTRY.filter((e) => e.category === 'core').map((e) => e.factory(context))
let analysisTools: AgentTool<any>[] = []
if (allowedTools && allowedTools.length > 0) {
tools = tools.filter((t) => allowedTools.includes(t.name))
analysisTools = TOOL_REGISTRY.filter((e) => e.category === 'analysis' && allowedTools.includes(e.name)).map((e) =>
e.factory(context)
)
}
return tools.map(translateTool).map((t) => wrapWithPreprocessing(t, context))
return [...coreTools, ...analysisTools].map(translateTool).map((t) => wrapWithPreprocessing(t, context))
}
/**
@@ -272,7 +244,7 @@ export function createActivateSkillTool(
}
if (skill.tools.length > 0 && allowedTools && allowedTools.length > 0) {
const missing = skill.tools.filter((t) => !allowedTools.includes(t))
const missing = skill.tools.filter((t) => !CORE_TOOL_NAMES.has(t) && !allowedTools.includes(t))
if (missing.length > 0) {
const msg = isZh
? `当前助手缺少该技能所需的工具:${missing.join(', ')}`
+11
View File
@@ -2,8 +2,19 @@
* AI Tools 类型定义
*/
import type { AgentTool } from '@mariozechner/pi-agent-core'
import type { PreprocessConfig } from '../preprocessor'
export type ToolCategory = 'core' | 'analysis'
export type ToolFactory = (context: ToolContext) => AgentTool<any>
export interface ToolRegistryEntry {
name: string
factory: ToolFactory
category: ToolCategory
}
/** Owner 信息(当前用户在对话中的身份) */
export interface OwnerInfo {
/** Owner 的 platformId */
+3 -3
View File
@@ -673,11 +673,11 @@ export function registerAIHandlers({ win }: IpcContext): void {
}
})
ipcMain.handle('assistant:getBuiltinTsToolNames', async () => {
ipcMain.handle('assistant:getBuiltinToolCatalog', async () => {
try {
return assistantManager.getBuiltinTsToolNames()
return assistantManager.getBuiltinToolCatalog()
} catch (error) {
console.error('Failed to get builtin ts tool names:', error)
console.error('Failed to get builtin tool catalog:', error)
return []
}
})
+2 -2
View File
@@ -725,8 +725,8 @@ export const assistantApi = {
return ipcRenderer.invoke('assistant:getBuiltinCatalog')
},
getBuiltinTsToolNames: (): Promise<string[]> => {
return ipcRenderer.invoke('assistant:getBuiltinTsToolNames')
getBuiltinToolCatalog: (): Promise<Array<{ name: string; category: 'core' | 'analysis' }>> => {
return ipcRenderer.invoke('assistant:getBuiltinToolCatalog')
},
importAssistant: (builtinId: string): Promise<{ success: boolean; error?: string }> => {
+1 -1
View File
@@ -721,7 +721,7 @@ interface AssistantApi {
delete: (id: string) => Promise<{ success: boolean; error?: string }>
reset: (id: string) => Promise<{ success: boolean; error?: string }>
getBuiltinCatalog: () => Promise<BuiltinAssistantInfo[]>
getBuiltinTsToolNames: () => Promise<string[]>
getBuiltinToolCatalog: () => Promise<Array<{ name: string; category: 'core' | 'analysis' }>>
importAssistant: (builtinId: string) => Promise<{ success: boolean; error?: string }>
reimportAssistant: (id: string) => Promise<{ success: boolean; error?: string }>
importFromMd: (rawMd: string) => Promise<{ success: boolean; id?: string; error?: string }>
+18 -20
View File
@@ -49,8 +49,8 @@ description: Use when 用户希望根据一句自然语言需求创建新的 Cha
- `applicableChatTypes`
- `supportedLocales`
- 生成普通 assistant 文件时,不要写 `builtinId`
- 如果角色是通用且无需限制工具,优先省略 `allowedBuiltinTools` 字段,而不是硬塞一长串“全量工具”
- `allowedBuiltinTools` 只能使用当前真实存在的工具名,不得臆造、不得引用旧名字
- 如果角色无需分析工具,优先省略 `allowedBuiltinTools`(默认仅核心工具可用)
- `allowedBuiltinTools` 仅填写分析工具名(核心工具始终可用,无需列出),不得臆造、不得引用旧名字
- 最终写入路径固定为 `assistant/<locale>/<assistant-id>.md`
- 目标语言固定为 `zh``en``ja`
- 三个语言版本保持同一角色定位,但允许按语言做自然的本地化调整,不做机械直译
@@ -120,24 +120,22 @@ description: Use when 用户希望根据一句自然语言需求创建新的 Cha
## 工具选择规则
- 默认原则:尽量放宽,除非明显不适合该角色
- 先看角色是否真的需要工具白名单
- 若角色边界宽泛,可省略 `allowedBuiltinTools`
- 若角色边界明确,再按真实工具集合选择白名单
- 选择时优先保留完成该角色所必需的基础检索工具,例如
- 消息搜索
- 最近消息
- 上下文查看
- session 检索
- 仅在角色明显聚焦时再额外限制,例如:
-运营分析:保留群分析、排行、趋势工具
- 强情感洞察:保留互动关系、对话回顾、上下文工具
- 强客服分析:保留对话、上下文、未回复问题、消息类型工具
工具分为两类:
- **核心工具(core)**:始终启用,无需在 `allowedBuiltinTools` 中列出。包括:get_chat_overview, search_messages, get_recent_messages, get_message_context, search_sessions, get_session_messages, get_members
- **分析工具(analysis**:需在 `allowedBuiltinTools` 中显式列出才会启用
`allowedBuiltinTools` 仅用于控制分析工具,核心工具始终可用
- 若角色不需要分析工具,可省略 `allowedBuiltinTools`(默认仅核心工具可用)
- 若角色需要特定分析能力,列出所需的分析工具名称
- 仅在角色明显聚焦时选择对应的分析工具,例如:
- 强运营分析:get_member_stats, get_time_stats, member_activity_trend, silent_members
- 强情感洞察:mutual_interaction_pairs, reply_interaction_ranking, get_conversation_between
-客服分析:unanswered_messages, message_type_breakdown, get_conversation_between
生成前做一次自检:
- 是否引用了不存在的工具名
- 是否遗漏了完成该角色所需的基础工具
- `allowedBuiltinTools` 中是否误放了核心工具(核心工具无需列出)
- 是否包含明显与场景冲突的工具
## 输出模板
@@ -153,8 +151,8 @@ applicableChatTypes:
supportedLocales:
- zh
allowedBuiltinTools:
- search_messages
- get_recent_messages
- get_member_stats
- get_time_stats
presetQuestions:
- 示例问题 1
- 示例问题 2
@@ -182,7 +180,7 @@ presetQuestions:
- `name`:允许本地化,不必逐字对应
- `applicableChatTypes`:仅在能明确判断时写入;通用角色可省略
- `supportedLocales`:按文件所属语言写单元素数组
- `allowedBuiltinTools`:仅在需要限制工具范围时写入
- `allowedBuiltinTools`:仅填写需要的分析工具名(核心工具无需列出,始终可用)
- `presetQuestions`:建议 3 到 5 条,贴近该语言用户的自然表达
## 正文写法规则
@@ -220,6 +218,6 @@ presetQuestions:
- 把 assistant 产物写到 `skill/``skills/`,而不是 `assistant/`
- 机械照抄 `.docs/ai/assistantSystem.md` 的旧字段
- 在未确认中文预览前就直接落盘
-所有工具名塞进 `allowedBuiltinTools`
-核心工具名塞进 `allowedBuiltinTools`(核心工具始终可用,不需要列出)
- 多语言版本仅做逐字翻译,导致预设问题和语气不自然
- 发现同名文件已存在,却直接覆盖
@@ -39,11 +39,16 @@ const localeOptions = [
{ value: 'ja', label: '日本語' },
]
const BUILTIN_TS_TOOLS = computed(() =>
assistantStore.builtinTsToolNames.map((name) => ({
name,
description: t(`ai.assistant.builtinToolDesc.${name}`),
}))
const coreTools = computed(() =>
assistantStore.builtinToolCatalog
.filter((e) => e.category === 'core')
.map((e) => ({ name: e.name, description: t(`ai.assistant.builtinToolDesc.${e.name}`) }))
)
const analysisTools = computed(() =>
assistantStore.builtinToolCatalog
.filter((e) => e.category === 'analysis')
.map((e) => ({ name: e.name, description: t(`ai.assistant.builtinToolDesc.${e.name}`) }))
)
const form = ref({
@@ -60,8 +65,8 @@ const newQuestion = ref('')
const toolBadgeCount = computed(() => form.value.allowedBuiltinTools.length)
onMounted(async () => {
if (assistantStore.builtinTsToolNames.length === 0) {
await assistantStore.loadBuiltinTsToolNames()
if (assistantStore.builtinToolCatalog.length === 0) {
await assistantStore.loadBuiltinToolCatalog()
}
})
@@ -219,16 +224,15 @@ function toggleBuiltinTool(toolName: string) {
}
}
function isToolChecked(toolName: string): boolean {
if (form.value.allowedBuiltinTools.length === 0) return true
function isAnalysisToolChecked(toolName: string): boolean {
return form.value.allowedBuiltinTools.includes(toolName)
}
function selectAllTools() {
form.value.allowedBuiltinTools = BUILTIN_TS_TOOLS.value.map((t) => t.name)
function selectAllAnalysisTools() {
form.value.allowedBuiltinTools = analysisTools.value.map((t) => t.name)
}
function clearAllTools() {
function clearAllAnalysisTools() {
form.value.allowedBuiltinTools = []
}
@@ -427,40 +431,74 @@ function closeModal() {
</div>
<!-- 工具管理 Tab -->
<div v-show="activeTab === 'tools'" class="space-y-6">
<!-- 内置工具勾选区 -->
<div v-show="activeTab === 'tools'" class="space-y-5">
<!-- 核心工具区始终启用 -->
<div>
<div class="mb-2 flex items-center justify-between">
<h3 class="mb-1 text-sm font-medium text-gray-700 dark:text-gray-300">
{{ t('ai.assistant.config.coreTools') }}
</h3>
<p class="mb-2.5 text-[10px] text-gray-400">
{{ t('ai.assistant.config.coreToolsHint') }}
</p>
<div class="grid grid-cols-2 gap-1.5">
<label
v-for="tool in coreTools"
:key="tool.name"
class="flex items-start gap-2 rounded-md border border-gray-200 bg-gray-50/50 px-2.5 py-2 opacity-70 dark:border-gray-700 dark:bg-gray-800/30"
>
<input
type="checkbox"
checked
disabled
class="mt-0.5 h-3.5 w-3.5 shrink-0 rounded border-gray-300 text-gray-400"
/>
<div class="min-w-0">
<div class="truncate text-xs font-medium text-gray-600 dark:text-gray-400">{{ tool.name }}</div>
<div class="truncate text-[10px] text-gray-400 dark:text-gray-500">{{ tool.description }}</div>
</div>
</label>
</div>
</div>
<!-- 分析工具区按需开启 -->
<div>
<div class="mb-1 flex items-center justify-between">
<h3 class="text-sm font-medium text-gray-700 dark:text-gray-300">
{{ t('ai.assistant.config.builtinTools') }}
{{ t('ai.assistant.config.analysisTools') }}
</h3>
<div v-if="!readonly" class="flex gap-2">
<button class="text-[10px] text-primary-500 hover:text-primary-600" @click="selectAllTools">
<button
class="text-[10px] text-primary-500 hover:text-primary-600"
@click="selectAllAnalysisTools"
>
{{ t('ai.assistant.config.selectAll') }}
</button>
<span class="text-[10px] text-gray-300 dark:text-gray-600">|</span>
<button class="text-[10px] text-primary-500 hover:text-primary-600" @click="clearAllTools">
<button
class="text-[10px] text-primary-500 hover:text-primary-600"
@click="clearAllAnalysisTools"
>
{{ t('ai.assistant.config.deselectAll') }}
</button>
</div>
</div>
<p class="mb-3 text-[10px] text-gray-400">
{{ t('ai.assistant.config.builtinToolsHint') }}
<p class="mb-2.5 text-[10px] text-gray-400">
{{ t('ai.assistant.config.analysisToolsHint') }}
</p>
<div class="grid grid-cols-2 gap-1.5">
<label
v-for="tool in BUILTIN_TS_TOOLS"
v-for="tool in analysisTools"
:key="tool.name"
class="flex cursor-pointer items-start gap-2 rounded-md border px-2.5 py-2 transition-colors"
:class="
isToolChecked(tool.name)
isAnalysisToolChecked(tool.name)
? 'border-primary-200 bg-primary-50/50 dark:border-primary-800 dark:bg-primary-950/20'
: 'border-gray-200 dark:border-gray-700'
"
>
<input
type="checkbox"
:checked="form.allowedBuiltinTools.includes(tool.name)"
:checked="isAnalysisToolChecked(tool.name)"
:disabled="readonly"
class="mt-0.5 h-3.5 w-3.5 shrink-0 rounded border-gray-300 text-primary-600 focus:ring-primary-500"
@change="toggleBuiltinTool(tool.name)"
+14 -2
View File
@@ -253,6 +253,10 @@
"presetQuestions": "Preset Questions",
"addQuestion": "Add a question...",
"builtinTools": "Built-in Tools",
"coreTools": "Core Tools",
"coreToolsHint": "Essential data retrieval tools, always enabled",
"analysisTools": "Analysis Tools",
"analysisToolsHint": "Enable on demand. Only checked tools will be available to AI",
"selectAll": "Select All",
"deselectAll": "Deselect All",
"builtinToolsHint": "No selection = all tools available. Only checked tools will be enabled.",
@@ -303,13 +307,21 @@
"get_recent_messages": "Get recent messages",
"get_message_context": "Get message context",
"get_conversation_between": "Get conversation between two members",
"get_members": "Get group members",
"get_members": "Get members",
"get_member_stats": "Get member statistics",
"get_member_name_history": "Get member name history",
"get_time_stats": "Get time statistics",
"search_sessions": "Search sessions",
"get_session_messages": "Get session messages",
"get_session_summaries": "Get session summaries"
"get_session_summaries": "Get session summaries",
"message_type_breakdown": "Message type distribution",
"peak_chat_hours_by_member": "Member peak hours",
"member_activity_trend": "Member activity trend",
"silent_members": "Silent member detection",
"reply_interaction_ranking": "Reply interaction ranking",
"mutual_interaction_pairs": "Mutual interaction pairs",
"member_message_length_stats": "Message length stats",
"unanswered_messages": "Unanswered messages"
}
},
"skill": {
+14 -2
View File
@@ -253,6 +253,10 @@
"presetQuestions": "プリセット質問",
"addQuestion": "質問を追加...",
"builtinTools": "標準ツール",
"coreTools": "コアツール",
"coreToolsHint": "基本データ取得ツール、常に有効、無効化不可",
"analysisTools": "分析ツール",
"analysisToolsHint": "必要に応じて有効化。チェックしたツールのみ AI が利用可能",
"selectAll": "すべて選択",
"deselectAll": "すべて解除",
"builtinToolsHint": "何も選ばなければ全ツールを使います。選択した場合は、そのツールだけが有効になります。",
@@ -303,13 +307,21 @@
"get_recent_messages": "最近のメッセージを取得",
"get_message_context": "メッセージのコンテキストを取得",
"get_conversation_between": "2人のやり取りを取得",
"get_members": "グループメンバー一覧を取得",
"get_members": "メンバー一覧を取得",
"get_member_stats": "メンバー統計を取得",
"get_member_name_history": "メンバーの名前変更履歴を取得",
"get_time_stats": "時間統計を取得",
"search_sessions": "セッションを検索",
"get_session_messages": "セッションメッセージを取得",
"get_session_summaries": "セッション要約を取得"
"get_session_summaries": "セッション要約を取得",
"message_type_breakdown": "メッセージ種別分布",
"peak_chat_hours_by_member": "メンバー活動時間帯",
"member_activity_trend": "メンバー活動トレンド",
"silent_members": "沈黙メンバー検出",
"reply_interaction_ranking": "返信インタラクションランキング",
"mutual_interaction_pairs": "相互インタラクションペア",
"member_message_length_stats": "メッセージ長さ統計",
"unanswered_messages": "未返信メッセージ"
}
},
"skill": {
+14 -2
View File
@@ -253,6 +253,10 @@
"presetQuestions": "预设问题",
"addQuestion": "添加新问题...",
"builtinTools": "内置工具",
"coreTools": "核心工具",
"coreToolsHint": "基础数据获取工具,始终启用,不可关闭",
"analysisTools": "分析工具",
"analysisToolsHint": "按需开启的分析能力,勾选后才会对 AI 可用",
"selectAll": "全选",
"deselectAll": "全不选",
"builtinToolsHint": "不勾选任何工具 = 全部工具可用。勾选后仅开放已选工具。",
@@ -303,13 +307,21 @@
"get_recent_messages": "获取最近消息",
"get_message_context": "获取消息上下文",
"get_conversation_between": "获取两人对话",
"get_members": "获取成员列表",
"get_members": "获取成员列表",
"get_member_stats": "获取成员统计",
"get_member_name_history": "获取成员改名历史",
"get_time_stats": "获取时间统计",
"search_sessions": "搜索会话",
"get_session_messages": "获取会话消息",
"get_session_summaries": "获取会话摘要"
"get_session_summaries": "获取会话摘要",
"message_type_breakdown": "消息类型分布",
"peak_chat_hours_by_member": "成员活跃时段",
"member_activity_trend": "成员活跃趋势",
"silent_members": "沉默成员检测",
"reply_interaction_ranking": "回复互动排行",
"mutual_interaction_pairs": "互动好友配对",
"member_message_length_stats": "消息长度统计",
"unanswered_messages": "未回复消息"
}
},
"skill": {
+14 -2
View File
@@ -253,6 +253,10 @@
"presetQuestions": "預設問題",
"addQuestion": "新增問題...",
"builtinTools": "內建工具",
"coreTools": "核心工具",
"coreToolsHint": "基礎資料取得工具,始終啟用,無法關閉",
"analysisTools": "分析工具",
"analysisToolsHint": "按需開啟的分析能力,勾選後才會對 AI 可用",
"selectAll": "全選",
"deselectAll": "全不選",
"builtinToolsHint": "若未勾選任何工具,代表全部可用;勾選後僅開放所選工具。",
@@ -303,13 +307,21 @@
"get_recent_messages": "取得最近訊息",
"get_message_context": "取得訊息上下文",
"get_conversation_between": "取得兩人對話",
"get_members": "取得成員列表",
"get_members": "取得成員列表",
"get_member_stats": "取得成員統計",
"get_member_name_history": "取得成員改名歷史",
"get_time_stats": "取得時間統計",
"search_sessions": "搜尋會話",
"get_session_messages": "取得會話訊息",
"get_session_summaries": "取得會話摘要"
"get_session_summaries": "取得會話摘要",
"message_type_breakdown": "訊息類型分佈",
"peak_chat_hours_by_member": "成員活躍時段",
"member_activity_trend": "成員活躍趨勢",
"silent_members": "沉默成員偵測",
"reply_interaction_ranking": "回覆互動排行",
"mutual_interaction_pairs": "互動好友配對",
"member_message_length_stats": "訊息長度統計",
"unanswered_messages": "未回覆訊息"
}
},
"skill": {
+7 -7
View File
@@ -56,8 +56,8 @@ export const useAssistantStore = defineStore('assistant', () => {
/** @deprecated 本地内置目录已清空,保留兼容 */
const builtinCatalog = ref<BuiltinAssistantInfo[]>([])
/** 内置 TS 工具名称列表 */
const builtinTsToolNames = ref<string[]>([])
/** 内置工具目录(含分类) */
const builtinToolCatalog = ref<Array<{ name: string; category: 'core' | 'analysis' }>>([])
/** 云端市场目录 */
const cloudCatalog = ref<CloudAssistantItem[]>([])
@@ -122,11 +122,11 @@ export const useAssistantStore = defineStore('assistant', () => {
}
}
async function loadBuiltinTsToolNames(): Promise<void> {
async function loadBuiltinToolCatalog(): Promise<void> {
try {
builtinTsToolNames.value = await window.assistantApi.getBuiltinTsToolNames()
builtinToolCatalog.value = await window.assistantApi.getBuiltinToolCatalog()
} catch (error) {
console.error('[AssistantStore] Failed to load builtin ts tool names:', error)
console.error('[AssistantStore] Failed to load builtin tool catalog:', error)
}
}
@@ -311,7 +311,7 @@ export const useAssistantStore = defineStore('assistant', () => {
selectedAssistant,
isLoaded,
builtinCatalog,
builtinTsToolNames,
builtinToolCatalog,
cloudCatalog,
cloudLoading,
cloudError,
@@ -324,7 +324,7 @@ export const useAssistantStore = defineStore('assistant', () => {
hasMoreAssistants,
loadAssistants,
loadBuiltinCatalog,
loadBuiltinTsToolNames,
loadBuiltinToolCatalog,
fetchCloudCatalog,
importFromCloud,
isCloudItemImported,