diff --git a/.sisyphus/fix-tracker.md b/.sisyphus/fix-tracker.md new file mode 100644 index 0000000..1d56064 --- /dev/null +++ b/.sisyphus/fix-tracker.md @@ -0,0 +1,29 @@ +# 修复追踪文件 + +**分支**: openclaw +**开始时间**: 2026-04-16 +**状态**: 重新执行 + +--- + +## 修复计划 + +### P0 - 阻断性问题 + +#### 1. 删除自定义 tool_interface.ts +#### 2. 重构 graph_memory_tool.ts +#### 3. 更新 plugin-entry.ts + +### P2 - 最佳实践 + +#### 4. 重组 Skill 目录结构 +#### 5. 更新 bundled-skills 目录结构 +#### 6. 更新 openclaw.plugin.json +#### 7. 更新 README.md / README_EN.md + +--- + +## 执行记录 + +### [进行中] P0: 核心修复 + diff --git a/README.md b/README.md index f6bbd46..9716871 100644 --- a/README.md +++ b/README.md @@ -35,13 +35,13 @@ npm run build ```bash # 方式 A:工作空间级(推荐,仅当前项目可用) cp -r skills/graph-memory <你的项目目录>/skills/graph-memory -cp -r skills/graph-memory/persona <你的项目目录>/skills/graph-memory-persona -cp -r skills/graph-memory/task <你的项目目录>/skills/graph-memory-task +cp -r skills/graph-memory-persona <你的项目目录>/skills/graph-memory-persona +cp -r skills/graph-memory-task <你的项目目录>/skills/graph-memory-task # 方式 B:用户级(所有项目可用) cp -r skills/graph-memory ~/.openclaw/skills/graph-memory -cp -r skills/graph-memory/persona ~/.openclaw/skills/graph-memory-persona -cp -r skills/graph-memory/task ~/.openclaw/skills/graph-memory-task +cp -r skills/graph-memory-persona ~/.openclaw/skills/graph-memory-persona +cp -r skills/graph-memory-task ~/.openclaw/skills/graph-memory-task ``` ### 步骤 4:安装 Plugin(让 OpenClaw 运行时加载 Tool) @@ -130,8 +130,8 @@ npm run build ```bash cp -r skills/graph-memory ~/.agents/skills/graph-memory -cp -r skills/graph-memory/persona ~/.agents/skills/graph-memory-persona -cp -r skills/graph-memory/task ~/.agents/skills/graph-memory-task +cp -r skills/graph-memory-persona ~/.agents/skills/graph-memory-persona +cp -r skills/graph-memory-task ~/.agents/skills/graph-memory-task ``` --- @@ -153,19 +153,23 @@ ts/ │ │ └── graph_memory_tool.ts # Tool 实现 │ └── tool_limiter.ts # 调用限制器 ├── bundled-skills/ -│ └── graph-memory/ # 内置 Skill 定义 -│ ├── SKILL.md -│ ├── persona/SKILL.md -│ └── task/SKILL.md +│ ├── graph-memory/ # 内置 Skill 定义 +│ │ └── SKILL.md +│ ├── graph-memory-persona/ +│ │ └── SKILL.md +│ └── graph-memory-task/ +│ └── SKILL.md ├── package.json ├── tsconfig.json └── openclaw.plugin.json # Plugin Manifest skills/ # 独立 Skill 定义 -└── graph-memory/ - ├── SKILL.md - ├── persona/SKILL.md - └── task/SKILL.md +├── graph-memory/ +│ └── SKILL.md +├── graph-memory-persona/ +│ └── SKILL.md +└── graph-memory-task/ + └── SKILL.md ``` --- diff --git a/README_EN.md b/README_EN.md index e738807..bc72bdd 100644 --- a/README_EN.md +++ b/README_EN.md @@ -35,13 +35,13 @@ Copy the 3 Skills from `skills/` to OpenClaw's skill directory. Priority: `/skills/graph-memory -cp -r skills/graph-memory/persona /skills/graph-memory-persona -cp -r skills/graph-memory/task /skills/graph-memory-task +cp -r skills/graph-memory-persona /skills/graph-memory-persona +cp -r skills/graph-memory-task /skills/graph-memory-task # Option B: User-level (available for all projects) cp -r skills/graph-memory ~/.openclaw/skills/graph-memory -cp -r skills/graph-memory/persona ~/.openclaw/skills/graph-memory-persona -cp -r skills/graph-memory/task ~/.openclaw/skills/graph-memory-task +cp -r skills/graph-memory-persona ~/.openclaw/skills/graph-memory-persona +cp -r skills/graph-memory-task ~/.openclaw/skills/graph-memory-task ``` ### Step 4: Install Plugin (enables OpenClaw runtime to load the Tool) @@ -129,8 +129,8 @@ Copy the `skills/` directory to OpenClaw's skill directory: ```bash cp -r skills/graph-memory ~/.agents/skills/graph-memory -cp -r skills/graph-memory/persona ~/.agents/skills/graph-memory-persona -cp -r skills/graph-memory/task ~/.agents/skills/graph-memory-task +cp -r skills/graph-memory-persona ~/.agents/skills/graph-memory-persona +cp -r skills/graph-memory-task ~/.agents/skills/graph-memory-task ``` --- @@ -152,19 +152,23 @@ ts/ │ │ └── graph_memory_tool.ts # Tool implementation │ └── tool_limiter.ts # Call rate limiter ├── bundled-skills/ -│ └── graph-memory/ # Bundled Skill definitions -│ ├── SKILL.md -│ ├── persona/SKILL.md -│ └── task/SKILL.md +│ ├── graph-memory/ # Bundled Skill definitions +│ │ └── SKILL.md +│ ├── graph-memory-persona/ +│ │ └── SKILL.md +│ └── graph-memory-task/ +│ └── SKILL.md ├── package.json ├── tsconfig.json └── openclaw.plugin.json # Plugin Manifest skills/ # Standalone Skill definitions -└── graph-memory/ - ├── SKILL.md - ├── persona/SKILL.md - └── task/SKILL.md +├── graph-memory/ +│ └── SKILL.md +├── graph-memory-persona/ +│ └── SKILL.md +└── graph-memory-task/ + └── SKILL.md ``` --- diff --git a/skills/graph-memory/persona/SKILL.md b/skills/graph-memory-persona/SKILL.md similarity index 100% rename from skills/graph-memory/persona/SKILL.md rename to skills/graph-memory-persona/SKILL.md diff --git a/skills/graph-memory/task/SKILL.md b/skills/graph-memory-task/SKILL.md similarity index 100% rename from skills/graph-memory/task/SKILL.md rename to skills/graph-memory-task/SKILL.md diff --git a/ts/bundled-skills/graph-memory/persona/SKILL.md b/ts/bundled-skills/graph-memory-persona/SKILL.md similarity index 100% rename from ts/bundled-skills/graph-memory/persona/SKILL.md rename to ts/bundled-skills/graph-memory-persona/SKILL.md diff --git a/ts/bundled-skills/graph-memory/task/SKILL.md b/ts/bundled-skills/graph-memory-task/SKILL.md similarity index 100% rename from ts/bundled-skills/graph-memory/task/SKILL.md rename to ts/bundled-skills/graph-memory-task/SKILL.md diff --git a/ts/openclaw.plugin.json b/ts/openclaw.plugin.json index 7a33994..2b13abc 100644 --- a/ts/openclaw.plugin.json +++ b/ts/openclaw.plugin.json @@ -1,7 +1,13 @@ { "id": "graph-memory", "name": "Graph Memory", + "kind": "memory", "description": "让 AI 拥有真正的长期记忆能力 - 基于图数据库的记忆系统", + "skills": [ + "bundled-skills/graph-memory", + "bundled-skills/graph-memory-persona", + "bundled-skills/graph-memory-task" + ], "configSchema": { "type": "object", "additionalProperties": false, diff --git a/ts/src/plugin-entry.ts b/ts/src/plugin-entry.ts index f293bea..d381f42 100644 --- a/ts/src/plugin-entry.ts +++ b/ts/src/plugin-entry.ts @@ -1,76 +1,5 @@ -/** - * OpenClaw Plugin Entry Point - * - * Registers the GraphMemory tool with OpenClaw's plugin system. - * Uses @sinclair/typebox for parameter schema definition. - */ -import { Type } from '@sinclair/typebox'; -import { GraphMemoryTool } from './runtime/core/tools/builtin/graph_memory_tool.js'; +import { GraphMemoryToolSchema, createGraphMemoryTool } from './runtime/core/tools/builtin/graph_memory_tool.js'; -// OpenClaw Tool Schema using TypeBox -const GraphMemoryToolSchema = Type.Object({ - action: Type.String({ - description: '记忆操作类型', - enum: [ - 'recall', 'commit', 'purge', 'introspect', - 'persona_update', 'persona_clear', - 'task_create', 'task_set_state', 'task_delete', 'task_link_info' - ] - }), - params: Type.Object({ - queryIntent: Type.Optional(Type.String({ description: '搜索意图' })), - seedEntities: Type.Optional(Type.Array(Type.String({ description: '实体' }), { description: '种子实体' })), - depth: Type.Optional(Type.Number({ description: '检索深度' })), - sessionFilter: Type.Optional(Type.String({ description: '会话ID过滤' })), - triplets: Type.Optional(Type.Array( - Type.Object({ - subject: Type.String({ description: '主体' }), - relation: Type.String({ description: '关系' }), - object: Type.String({ description: '客体' }), - confidence: Type.Optional(Type.Number({ description: '置信度' })) - }, { description: '三元组' }), - { description: '三元组数组' } - )), - sessionId: Type.Optional(Type.String({ description: '会话ID' })), - turnId: Type.Optional(Type.Number({ description: '轮次ID' })), - criteria: Type.Optional(Type.Object({ - subject: Type.Optional(Type.String({ description: '主体' })), - target: Type.Optional(Type.String({ description: '客体' })), - relation: Type.Optional(Type.String({ description: '关系' })), - sessionId: Type.Optional(Type.String({ description: '会话ID' })) - }, { description: '删除条件' })), - mode: Type.Optional(Type.String({ - enum: ['soft', 'hard', 'supersede'], - description: '删除模式' - })), - newRelation: Type.Optional(Type.Object({ - relation: Type.String({ description: '关系' }), - target: Type.String({ description: '客体' }) - }, { description: '新关系(supersede模式)' })), - attributes: Type.Optional(Type.Array( - Type.Object({ - attribute: Type.String({ description: '属性名' }), - value: Type.String({ description: '属性值' }) - }, { description: '属性' }), - { description: '属性数组' } - )), - confirm: Type.Optional(Type.Boolean({ description: '确认清除' })), - task_id: Type.Optional(Type.String({ description: '任务ID' })), - description: Type.Optional(Type.String({ description: '任务描述' })), - state: Type.Optional(Type.String({ description: '任务状态' })), - info_nodes: Type.Optional(Type.Array(Type.String({ description: '节点' }), { description: '信息节点' })), - info_node: Type.Optional(Type.String({ description: '信息节点' })), - days: Type.Optional(Type.Number({ description: '归档天数' })), - dry_run: Type.Optional(Type.Boolean({ description: '仅预览不删除' })) - }, { description: '操作参数' }) -}); - -/** - * Plugin entry point for OpenClaw. - * - * When loaded as an OpenClaw plugin, this function registers the GraphMemory tool. - * For standalone usage, import GraphMemoryTool directly. - */ export default function registerGraphMemoryPlugin(api: { registerTool: (tool: { name: string; @@ -81,34 +10,6 @@ export default function registerGraphMemoryPlugin(api: { }>; }) => void; }): void { - const tool = new GraphMemoryTool(); - - api.registerTool({ - name: 'graph_memory', - description: '图记忆工具 - 让 AI 拥有真正的长期记忆能力。支持 recall(检索)、commit(写入)、purge(删除)、introspect(状态)、人设管理、任务管理', - parameters: GraphMemoryToolSchema, - async execute(_id: string, params: Record): Promise<{ - content: Array<{ type: 'text'; text: string }>; - }> { - const result = await tool.handler(params, { - toolCallId: _id, - workingDirectory: process.cwd(), - abortController: { signal: new AbortController().signal }, - config: {}, - logger: { - info: () => {}, - warn: () => {}, - error: () => {}, - debug: () => {} - } - }); - - return { - content: [{ - type: 'text', - text: typeof result === 'string' ? result : JSON.stringify(result) - }] - }; - } - }); -} + const tool = createGraphMemoryTool(); + api.registerTool(tool); +} \ No newline at end of file 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 b2393ba..aa838f8 100644 --- a/ts/src/runtime/core/tools/builtin/graph_memory_tool.ts +++ b/ts/src/runtime/core/tools/builtin/graph_memory_tool.ts @@ -1,167 +1,95 @@ -import type { Tool, ToolCategory, PermissionLevel, ToolInputSchema, ToolExecutionContext, ToolOutput } from '../tool_interface'; -import { GraphDatabase } from '../../graph_memory/graph_database'; -import { MemoryService } from '../../graph_memory/memory_service'; -import { ToolLimiter } from '../tool_limiter'; +import { Type } from '@sinclair/typebox'; +import type { Static } from '@sinclair/typebox'; +import { GraphDatabase } from '../../graph_memory/graph_database.js'; +import { MemoryService } from '../../graph_memory/memory_service.js'; +import { ToolLimiter } from '../tool_limiter.js'; -const GRAPH_MEMORY_TOOL_ID = 'builtin:graph_memory'; +export const GraphMemoryToolSchema = Type.Object({ + action: Type.String({ + description: '记忆操作类型', + enum: [ + 'recall', 'commit', 'purge', 'introspect', 'archive', 'cleanup', + 'persona_update', 'persona_clear', + 'task_create', 'task_set_state', 'task_delete', 'task_link_info' + ] + }), + params: Type.Object({ + queryIntent: Type.Optional(Type.String({ description: '搜索意图' })), + seedEntities: Type.Optional(Type.Array(Type.String({ description: '实体' }), { description: '种子实体' })), + depth: Type.Optional(Type.Number({ description: '检索深度' })), + sessionFilter: Type.Optional(Type.String({ description: '会话ID过滤' })), + triplets: Type.Optional(Type.Array( + Type.Object({ + subject: Type.String({ description: '主体' }), + relation: Type.String({ description: '关系' }), + object: Type.String({ description: '客体' }), + confidence: Type.Optional(Type.Number({ description: '置信度' })) + }, { description: '三元组' }), + { description: '三元组数组' } + )), + sessionId: Type.Optional(Type.String({ description: '会话ID' })), + turnId: Type.Optional(Type.Number({ description: '轮次ID' })), + criteria: Type.Optional(Type.Object({ + subject: Type.Optional(Type.String({ description: '主体' })), + target: Type.Optional(Type.String({ description: '客体' })), + relation: Type.Optional(Type.String({ description: '关系' })), + sessionId: Type.Optional(Type.String({ description: '会话ID' })) + }, { description: '删除条件' })), + mode: Type.Optional(Type.String({ + enum: ['soft', 'hard', 'supersede'], + description: '删除模式' + })), + newRelation: Type.Optional(Type.Object({ + relation: Type.String({ description: '关系' }), + target: Type.String({ description: '客体' }) + }, { description: '新关系(supersede模式)' })), + attributes: Type.Optional(Type.Array( + Type.Object({ + attribute: Type.String({ description: '属性名' }), + value: Type.String({ description: '属性值' }) + }, { description: '属性' }), + { description: '属性数组' } + )), + confirm: Type.Optional(Type.Boolean({ description: '确认清除' })), + task_id: Type.Optional(Type.String({ description: '任务ID' })), + description: Type.Optional(Type.String({ description: '任务描述' })), + state: Type.Optional(Type.String({ description: '任务状态' })), + info_nodes: Type.Optional(Type.Array(Type.String({ description: '节点' }), { description: '信息节点' })), + info_node: Type.Optional(Type.String({ description: '信息节点' })), + days: Type.Optional(Type.Number({ description: '归档天数' })), + dry_run: Type.Optional(Type.Boolean({ description: '仅预览不删除' })) + }, { description: '操作参数' }) +}); + +export type GraphMemoryToolParams = Static; const GRAPH_MEMORY_TOOL_DESCRIPTION = `图记忆工具 - 让 AI 拥有真正的长期记忆能力 操作: - recall: 检索记忆 -- commit: 写入记忆 +- commit: 写入记忆 - purge: 删除记忆 - introspect: 查看状态 +- archive: 归档旧记忆 +- cleanup: 清理无效数据 - persona_update/clear: 人设管理 -- task_create/set_state/delete: 任务管理`; +- task_create/set_state/delete/link_info: 任务管理`; -export interface OpenClawToolResult { - content: Array<{ type: 'text'; text: string }>; -} +export function createGraphMemoryTool(dbPath?: string, sessionId?: string) { + const db = new GraphDatabase(dbPath, sessionId); + const service = new MemoryService(db); + const limiter = new ToolLimiter(); -export class GraphMemoryTool implements Tool { - readonly id = GRAPH_MEMORY_TOOL_ID; - readonly name = 'GraphMemory'; - readonly description = GRAPH_MEMORY_TOOL_DESCRIPTION; - readonly category: ToolCategory = 'analysis'; - readonly permissionLevel: PermissionLevel = 'safe'; - - readonly inputSchema: ToolInputSchema = { - type: 'object', - properties: { - action: { - type: 'string', - enum: [ - 'recall', 'commit', 'purge', 'introspect', 'archive', 'cleanup', - 'persona_update', 'persona_clear', - 'task_create', 'task_set_state', 'task_delete', 'task_link_info' - ], - description: '记忆操作类型' - }, - params: { - type: 'object', - description: '操作参数', - properties: { - queryIntent: { type: 'string', description: '搜索意图' }, - seedEntities: { type: 'array', items: { type: 'string', description: '实体' }, description: '种子实体' }, - depth: { type: 'number', description: '检索深度' }, - sessionFilter: { type: 'string', description: '会话ID过滤' }, - triplets: { - type: 'array', - items: { - type: 'object', - description: '三元组', - properties: { - subject: { type: 'string', description: '主体' }, - relation: { type: 'string', description: '关系' }, - object: { type: 'string', description: '客体' }, - confidence: { type: 'number', description: '置信度' } - } - }, - description: '三元组数组' - }, - sessionId: { type: 'string', description: '会话ID' }, - turnId: { type: 'number', description: '轮次ID' }, - criteria: { - type: 'object', - properties: { - subject: { type: 'string', description: '主体' }, - target: { type: 'string', description: '客体' }, - relation: { type: 'string', description: '关系' }, - sessionId: { type: 'string', description: '会话ID' } - }, - description: '删除条件' - }, - mode: { type: 'string', enum: ['soft', 'hard', 'supersede'], description: '删除模式' }, - newRelation: { - type: 'object', - properties: { - relation: { type: 'string', description: '关系' }, - target: { type: 'string', description: '客体' } - }, - description: '新关系(supersede模式)' - }, - attributes: { - type: 'array', - items: { - type: 'object', - description: '属性', - properties: { - attribute: { type: 'string', description: '属性名' }, - value: { type: 'string', description: '属性值' } - } - }, - description: '属性数组' - }, - confirm: { type: 'boolean', description: '确认清除' }, - task_id: { type: 'string', description: '任务ID' }, - description: { type: 'string', description: '任务描述' }, - state: { type: 'string', description: '任务状态' }, - info_nodes: { type: 'array', items: { type: 'string', description: '节点' }, description: '信息节点' }, - info_node: { type: 'string', description: '信息节点' }, - days: { type: 'number', description: '归档天数' }, - dry_run: { type: 'boolean', description: '仅预览不删除' } - } - } - }, - required: ['action', 'params'] - }; - - private db: GraphDatabase; - private service: MemoryService; - private limiter: ToolLimiter; - - constructor(dbPath?: string, sessionId?: string) { - this.db = new GraphDatabase(dbPath, sessionId); - this.service = new MemoryService(this.db); - this.limiter = new ToolLimiter(); - } - - async handler(params: Record, _context: ToolExecutionContext): Promise { - const action = params.action as string; - const actionParams = params.params as Record; - - try { - const result = await this.executeAction(action, actionParams); - return JSON.stringify({ success: true, data: result }, null, 2); - } catch (error) { - return JSON.stringify({ - success: false, - error: { - type: 'execution_error', - message: error instanceof Error ? error.message : String(error) - } - }, null, 2); - } - } - - async execute(_toolCallId: string, params: Record): Promise { - const result = await this.handler(params, { - toolCallId: _toolCallId, - workingDirectory: process.cwd(), - abortController: { signal: new AbortController().signal }, - config: {}, - logger: { info: () => {}, warn: () => {}, error: () => {}, debug: () => {} } - }); - - return { - content: [{ - type: 'text', - text: typeof result === 'string' ? result : JSON.stringify(result) - }] - }; - } - - private async executeAction(action: string, params: Record): Promise { - const [allowed, reason] = this.limiter.canCall(action); + async function executeAction(action: string, params: Record): Promise { + const [allowed, reason] = limiter.canCall(action); if (!allowed) { throw new Error(reason); } - this.limiter.recordCall(action); + limiter.recordCall(action); switch (action) { case 'recall': - return this.service.recall({ + return service.recall({ queryIntent: params.queryIntent as string || '', seedEntities: params.seedEntities as string[] | undefined, depth: params.depth as number | undefined, @@ -169,79 +97,100 @@ export class GraphMemoryTool implements Tool { }); case 'commit': - return this.service.commit({ + return service.commit({ triplets: params.triplets as Array<{ subject: string; relation: string; object: string; confidence?: number }>, sessionId: params.sessionId as string | undefined, turnId: params.turnId as number | undefined }); case 'purge': - return this.service.purge({ - criteria: params.criteria as { subject?: string | undefined; target?: string | undefined; relation?: string | undefined; sessionId?: string | undefined } | undefined, + return service.purge({ + criteria: params.criteria as { subject?: string; target?: string; relation?: string; sessionId?: string } | undefined, mode: params.mode as 'soft' | 'hard' | 'supersede' | undefined, newRelation: params.newRelation as { relation: string; target: string } | undefined }); case 'introspect': - return this.service.introspect(); + return service.introspect(); case 'persona_update': - return this.service.updatePersona({ + return service.updatePersona({ attributes: params.attributes as Array<{ attribute: string; value: string }>, mode: params.mode as 'merge' | 'replace' }); case 'persona_clear': - return this.service.clearPersona({ + return service.clearPersona({ confirm: params.confirm as boolean }); case 'task_create': - return this.service.createTask({ + return service.createTask({ task_id: params.task_id as string, description: params.description as string, info_nodes: params.info_nodes as string[] | undefined }); case 'task_set_state': - return this.service.setTaskState({ + return service.setTaskState({ task_id: params.task_id as string, state: params.state as string }); case 'task_delete': - return this.service.deleteTask({ + return service.deleteTask({ task_id: params.task_id as string }); case 'task_link_info': - return this.service.linkInfoToTask({ + return service.linkInfoToTask({ task_id: params.task_id as string, info_node: params.info_node as string }); case 'archive': - return this.service.archive(params.days as number | undefined); + return service.archive(params.days as number | undefined); case 'cleanup': - return this.service.cleanup(params.dry_run as boolean | undefined); + return service.cleanup(params.dry_run as boolean | undefined); default: throw new Error(`Unknown action: ${action}`); } } - resetLimiter(): void { - this.limiter.reset(); - } + return { + name: 'graph_memory', + description: GRAPH_MEMORY_TOOL_DESCRIPTION, + parameters: GraphMemoryToolSchema, - getLimiterSummary(): string { - return this.limiter.getSummary(); - } + async execute(_toolCallId: string, params: Record): Promise<{ + content: Array<{ type: 'text'; text: string }>; + }> { + const action = params.action as string; + const actionParams = params.params as Record; + + try { + const result = await executeAction(action, actionParams); + return { + content: [{ type: 'text', text: JSON.stringify({ success: true, data: result }) }] + }; + } catch (error) { + return { + content: [{ + type: 'text', + text: JSON.stringify({ + success: false, + error: { + type: 'execution_error', + message: error instanceof Error ? error.message : String(error) + } + }) + }] + }; + } + } + }; } -export function createGraphMemoryTool(dbPath?: string, sessionId?: string): GraphMemoryTool { - return new GraphMemoryTool(dbPath, sessionId); -} - -export { ToolLimiter } from '../tool_limiter'; +export { ToolLimiter } from '../tool_limiter.js'; \ No newline at end of file diff --git a/ts/src/runtime/core/tools/tool_interface.ts b/ts/src/runtime/core/tools/tool_interface.ts deleted file mode 100644 index 3084952..0000000 --- a/ts/src/runtime/core/tools/tool_interface.ts +++ /dev/null @@ -1,59 +0,0 @@ -export type ToolCategory = 'file' | 'code' | 'search' | 'execute' | 'network' | 'analysis' | 'generation' | 'communication' | 'mcp' | 'custom'; - -export type PermissionLevel = 'safe' | 'moderate' | 'dangerous' | 'restricted'; - -export type SchemaType = 'string' | 'number' | 'integer' | 'boolean' | 'array' | 'object'; - -export interface SchemaProperty { - type: SchemaType; - description: string; - enum?: string[]; - minimum?: number; - maximum?: number; - minLength?: number; - maxLength?: number; - pattern?: string; - default?: unknown; - examples?: unknown[]; - items?: SchemaProperty; - properties?: Record; -} - -export interface ToolInputSchema { - type: 'object'; - properties: Record; - required?: string[]; - additionalProperties?: boolean; -} - -export interface ToolOutputSchema { - type: 'object'; - properties: Record; - format?: 'json' | 'text' | 'markdown' | 'binary'; - maxSize?: number; - maxLines?: number; -} - -export type ToolInput = Record; -export type ToolOutput = string | Record | void; - -export interface ToolExecutionContext { - toolCallId: string; - workingDirectory: string; - abortController: { signal: AbortSignal }; - config: { timeout?: number }; - logger: { info: (...args: unknown[]) => void; warn: (...args: unknown[]) => void; error: (...args: unknown[]) => void; debug: (...args: unknown[]) => void }; -} - -export type ToolHandler = (params: ToolInput, context: ToolExecutionContext) => Promise; - -export interface Tool { - readonly id: string; - readonly name: string; - readonly description: string; - readonly category: ToolCategory; - readonly inputSchema: ToolInputSchema; - readonly outputSchema?: ToolOutputSchema; - readonly handler: ToolHandler; - readonly permissionLevel: PermissionLevel; -}