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

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,
]

View File

@@ -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 工具的名称集合(用于前端分组展示)
*/

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(', ')}`

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 */