From 53d69409944344d40e8a3239e65f8b6ab72bb1d2 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 17 Apr 2026 13:08:18 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=20AI=20=E5=B7=A5?= =?UTF-8?q?=E5=85=B7=E8=B0=83=E7=94=A8=E7=9A=84=E4=B8=A4=E4=B8=AA=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 问题1: AI 生成的参数格式与工具期望不一致 - 改进工具 description,添加 commit 操作的三元组格式说明和示例 - 完善 input_schema,详细描述 triplets 的 subject/relation/object 字段 - 在 description 中明确说明必填字段 问题2: 工具名称格式不符合 API 要求 - OpenAI/DeepSeek API 要求工具名称符合 ^[a-zA-Z0-9_-]+$ - 内部 ID "builtin:graph_memory" 含冒号,不符合要求 - 添加 apiName 属性提供 API 兼容名称 "graph_memory" - 添加 mapToolIdToApiName/mapApiNameToToolId 映射函数 同时修正 import 路径:waterflow/... -> waterflow-ts/dist/... --- .../core/graph_memory/graph_database.ts | 4 +- .../core/tools/builtin/graph_memory_tool.ts | 77 +++++++++++++++---- ts/src/runtime/core/tools/builtin/index.ts | 13 ++-- ts/src/types/waterflow.d.ts | 28 ++++--- 4 files changed, 89 insertions(+), 33 deletions(-) diff --git a/ts/src/runtime/core/graph_memory/graph_database.ts b/ts/src/runtime/core/graph_memory/graph_database.ts index bed9089..d52e01a 100644 --- a/ts/src/runtime/core/graph_memory/graph_database.ts +++ b/ts/src/runtime/core/graph_memory/graph_database.ts @@ -1,5 +1,5 @@ import initSqlJs, { type Database as SqlJsDatabase } from 'sql.js'; -import type { Platform } from 'waterflow/platform/types'; +import type { Platform } from 'waterflow-ts/dist/platform/types.js'; import type { Entity, Relation, RecallParams, CommitParams, PurgeParams, RecallResult, CommitResult, PurgeResult, MemoryStats } from './types'; import { getConfig } from './config'; @@ -16,7 +16,7 @@ export class GraphDatabase { private async initDatabase(): Promise { const SQL = await initSqlJs(); - const { getPlatform } = await import('waterflow/platform'); + const { getPlatform } = await import('waterflow-ts/dist/platform/index.js'); this._platform = getPlatform(); try { diff --git a/ts/src/runtime/core/tools/builtin/graph_memory_tool.ts b/ts/src/runtime/core/tools/builtin/graph_memory_tool.ts index c2f8626..0cb00d7 100644 --- a/ts/src/runtime/core/tools/builtin/graph_memory_tool.ts +++ b/ts/src/runtime/core/tools/builtin/graph_memory_tool.ts @@ -1,22 +1,73 @@ -import type { Tool, ToolCategory, PermissionLevel, ToolInputSchema, ToolOutput, ToolInput, ToolExecutionContext } from 'waterflow/runtime/core/tools/tool_interface'; +import type { Tool, ToolCategory, PermissionLevel, ToolInputSchema, ToolOutput, ToolInput, ToolExecutionContext } from 'waterflow-ts/dist/runtime/core/tools/tool_interface.js'; import { GraphDatabase } from '../../graph_memory/graph_database'; import { MemoryService } from '../../graph_memory/memory_service'; const GRAPH_MEMORY_TOOL_ID = 'builtin:graph_memory'; +const GRAPH_MEMORY_TOOL_API_NAME = 'graph_memory'; // API 兼容名称(不含冒号,符合 ^[a-zA-Z0-9_-]+$ 要求) + +/** + * 工具名称映射工具 - 用于处理 API 对工具名称格式的限制 + * OpenAI/DeepSeek API 要求工具名称符合 ^[a-zA-Z0-9_-]+$ 正则表达式 + * 而 TrulyMEM 的内部 ID 使用 "builtin:xxx" 格式(含冒号) + */ + +/** + * 将内部工具 ID 映射为 API 兼容名称 + * @param toolId 内部工具 ID,如 "builtin:graph_memory" + * @returns API 兼容名称,如 "graph_memory" + */ +export function mapToolIdToApiName(toolId: string): string { + // 移除 "builtin:" 前缀 + if (toolId.startsWith('builtin:')) { + return toolId.slice(8); + } + // 其他前缀也移除(如 "mcp:", "plugin:") + const colonIndex = toolId.indexOf(':'); + if (colonIndex > 0) { + return toolId.slice(colonIndex + 1); + } + return toolId; +} + +/** + * 将 API 返回的工具名称映射回内部 ID + * @param apiName API 返回的工具名称,如 "graph_memory" + * @param prefix 内部 ID 前缀,默认 "builtin:" + * @returns 内部工具 ID,如 "builtin:graph_memory" + */ +export function mapApiNameToToolId(apiName: string, prefix = 'builtin:'): string { + // 如果已经是完整 ID 格式,直接返回 + if (apiName.includes(':')) { + return apiName; + } + return `${prefix}${apiName}`; +} const GRAPH_MEMORY_TOOL_DESCRIPTION = `图记忆工具 - 让 AI 拥有真正的长期记忆能力 操作: -- recall: 检索记忆 -- commit: 写入记忆 -- purge: 删除记忆 -- introspect: 查看状态 +- recall: 检索记忆 - 提供 queryIntent (搜索意图) 和可选的 seedEntities +- commit: 写入记忆 - 必须使用 triplets 数组格式,每个三元组包含 subject, relation, object +- purge: 删除记忆 - 提供 criteria 指定删除条件 +- introspect: 查看状态 - 无参数 - persona_update/clear: 人设管理 -- task_create/set_state/delete: 任务管理`; +- task_create/set_state/delete: 任务管理 + +【commit 操作的三元组格式】 +triplets 必须是数组,每个元素是 {subject, relation, object, confidence} 格式: +示例: {"action":"commit","params":{"triplets":[{"subject":"Alice","relation":"is a","object":"engineer","confidence":0.95}]}} +- subject: 实体名称 (如用户名、技术名称) +- relation: 关系描述 (如 "is a", "likes", "knows") +- object: 目标实体 (如职业、爱好、技术) +- confidence: 置信度 0-1 (可选,默认0.9) + +【recall 操作】 +示例: {"action":"recall","params":{"queryIntent":"用户的学习偏好","seedEntities":["Alice"]}}`; export class GraphMemoryTool implements Tool { readonly id = GRAPH_MEMORY_TOOL_ID; readonly name = 'GraphMemory'; + readonly apiName = GRAPH_MEMORY_TOOL_API_NAME; readonly description = GRAPH_MEMORY_TOOL_DESCRIPTION; readonly category: ToolCategory = 'analysis'; readonly permissionLevel: PermissionLevel = 'safe'; @@ -44,17 +95,17 @@ export class GraphMemoryTool implements Tool { sessionFilter: { type: 'string', description: '会话ID过滤' }, triplets: { type: 'array', + description: '知识三元组数组。每个三元组描述 subject-relation-object 关系,用于存储记忆知识。', items: { type: 'object', - description: '三元组', + description: '三元组: {subject, relation, object, confidence} - subject/relation/object 必填', properties: { - subject: { type: 'string', description: '主体' }, - relation: { type: 'string', description: '关系' }, - object: { type: 'string', description: '客体' }, - confidence: { type: 'number', description: '置信度' } + subject: { type: 'string', description: '主体实体,如人名、技术名称等' }, + relation: { type: 'string', description: '关系描述,如 "is a", "likes", "knows", "uses" 等' }, + object: { type: 'string', description: '客体实体,如职业、爱好、技术名称等' }, + confidence: { type: 'number', description: '置信度 (0-1),默认 0.9', default: 0.9 } } - }, - description: '三元组数组' + } }, sessionId: { type: 'string', description: '会话ID' }, turnId: { type: 'number', description: '轮次ID' }, diff --git a/ts/src/runtime/core/tools/builtin/index.ts b/ts/src/runtime/core/tools/builtin/index.ts index a15ef76..fe290f7 100644 --- a/ts/src/runtime/core/tools/builtin/index.ts +++ b/ts/src/runtime/core/tools/builtin/index.ts @@ -1,8 +1,9 @@ -import type { Tool } from 'waterflow/runtime/core/tools/tool_interface'; -import type { Platform } from 'waterflow/platform/types'; -import { GraphMemoryTool, createGraphMemoryTool } from './graph_memory_tool'; +import type { Tool } from 'waterflow-ts/dist/runtime/core/tools/tool_interface.js'; +import type { Platform } from 'waterflow-ts/dist/platform/types.js'; +import type { ToolRegistry } from 'waterflow-ts/dist/runtime/core/tools/tool_registry.js'; +import { GraphMemoryTool, createGraphMemoryTool, mapToolIdToApiName, mapApiNameToToolId } from './graph_memory_tool'; -export { GraphMemoryTool, createGraphMemoryTool }; +export { GraphMemoryTool, createGraphMemoryTool, mapToolIdToApiName, mapApiNameToToolId }; export function registerGraphMemoryTool( registry: { register: (tool: Tool) => void }, @@ -11,8 +12,8 @@ export function registerGraphMemoryTool( registry.register(createGraphMemoryTool(sessionId)); } -export async function installTrulyMEM(platform: Platform, sessionId?: string) { - const { initializeToolRegistry } = await import('waterflow/runtime/core/tools/builtin'); +export async function installTrulyMEM(platform: Platform, sessionId?: string): Promise { + const { initializeToolRegistry } = await import('waterflow-ts/dist/runtime/core/tools/builtin/index.js'); const registry = initializeToolRegistry(platform); registerGraphMemoryTool(registry, sessionId); return registry; diff --git a/ts/src/types/waterflow.d.ts b/ts/src/types/waterflow.d.ts index 867d8d9..91d7785 100644 --- a/ts/src/types/waterflow.d.ts +++ b/ts/src/types/waterflow.d.ts @@ -1,5 +1,5 @@ declare module 'waterflow/platform' { - import type { Platform, CreatePlatformOptions, PlatformCapabilities } from 'waterflow/platform/types'; + import type { Platform, CreatePlatformOptions, PlatformCapabilities } from 'waterflow-ts/platform/types'; export function getPlatform(): Platform; export function hasCapability(capability: keyof PlatformCapabilities): boolean; export function initPlatform(options?: CreatePlatformOptions): Platform; @@ -259,6 +259,7 @@ declare module 'waterflow/platform/types' { export interface Tool { readonly id: string; readonly name: string; + readonly apiName?: string; readonly description: string; readonly category: ToolCategory; readonly inputSchema: ToolInputSchema; @@ -346,6 +347,7 @@ declare module 'waterflow/platform/types' { export interface BuiltinTool { readonly id: string; readonly name: string; + readonly apiName?: string; readonly description: string; readonly category: ToolCategory; readonly inputSchema: ToolInputSchema; @@ -355,13 +357,13 @@ declare module 'waterflow/platform/types' { } declare module 'waterflow/runtime/core/tools/tool_interface' { - import type { PlatformAbortController } from 'waterflow/platform/types'; - import type { AgentId } from 'waterflow/shared/types/agent'; - import type { WorkflowRunner } from 'waterflow/runtime/core/workflow/types'; - import type { WorkflowRegistryImpl } from 'waterflow/runtime/core/workflow/workflow_registry'; - import type { AgentRegistryImpl } from 'waterflow/runtime/core/workflow/agent_registry'; - import type { AgentExecutor } from 'waterflow/runtime/core/agent/agent_executor'; - import type { MCPClient } from 'waterflow/runtime/core/tools/mcp/mcp_client'; + import type { PlatformAbortController } from 'waterflow-ts/platform/types'; + import type { AgentId } from 'waterflow-ts/shared/types/agent'; + import type { WorkflowRunner } from 'waterflow-ts/runtime/core/workflow/types'; + import type { WorkflowRegistryImpl } from 'waterflow-ts/runtime/core/workflow/workflow_registry'; + import type { AgentRegistryImpl } from 'waterflow-ts/runtime/core/workflow/agent_registry'; + import type { AgentExecutor } from 'waterflow-ts/runtime/core/agent/agent_executor'; + import type { MCPClient } from 'waterflow-ts/runtime/core/tools/mcp/mcp_client'; export type ToolCategory = | 'file' @@ -403,6 +405,7 @@ declare module 'waterflow/runtime/core/tools/tool_interface' { suggestedSource?: 'context' | 'literal' | 'file'; items?: SchemaProperty; properties?: Record; + required?: string[]; additionalProperties?: boolean | SchemaProperty; } @@ -503,6 +506,7 @@ declare module 'waterflow/runtime/core/tools/tool_interface' { export interface Tool { readonly id: string; readonly name: string; + readonly apiName?: string; readonly description: string; readonly category: ToolCategory; readonly inputSchema: ToolInputSchema; @@ -564,9 +568,9 @@ declare module 'waterflow/runtime/core/tools/tool_interface' { } declare module 'waterflow/runtime/core/tools/builtin' { - import type { Platform } from 'waterflow/platform/types'; - import type { Tool } from 'waterflow/runtime/core/tools/tool_interface'; - import { ToolRegistry } from 'waterflow/runtime/core/tools/tool_registry'; + import type { Platform } from 'waterflow-ts/platform/types'; + import type { Tool } from 'waterflow-ts/runtime/core/tools/tool_interface'; + import { ToolRegistry } from 'waterflow-ts/runtime/core/tools/tool_registry'; export const FRAMEWORK_TOOLS: Tool[]; export function initializeToolRegistry(platform: Platform): ToolRegistry; @@ -574,7 +578,7 @@ declare module 'waterflow/runtime/core/tools/builtin' { } declare module 'waterflow/runtime/core/tools/tool_registry' { - import type { Tool, ToolCategory, ToolInput } from 'waterflow/runtime/core/tools/tool_interface'; + import type { Tool, ToolCategory, ToolInput } from 'waterflow-ts/runtime/core/tools/tool_interface'; export interface ValidationResult { valid: boolean;