From 431bb5a0c93dc126d831b7c29848aad13436a78a Mon Sep 17 00:00:00 2001 From: HomeAgent Agent Date: Sun, 13 Sep 2026 22:17:45 +0800 Subject: [PATCH] =?UTF-8?q?refactor(tooldefs):=20buildToolDefs=20614?= =?UTF-8?q?=E2=86=92273=20=E8=A1=8C=EF=BC=88=E6=8A=BD=20toolDef=20?= =?UTF-8?q?=E5=8A=A9=E6=89=8B=EF=BC=8Cschema=20=E5=BD=A2=E7=8A=B6=E4=B8=8D?= =?UTF-8?q?=E5=8F=98=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 原实现每条工具都是 4 层嵌套的 map[string]interface{} 字面量(约 20 行/条), 40+ 条堆成 614 行的巨型函数。新增 toolDef(name, desc, props, required...) 助手消除外层样板;所有 name/description/properties/required 文本**逐字保留** (用 go/ast 定位原样搬迁,非重新键入),schema 形状与 JSON 输出不变。 验证:go build ./... / go vet / go test ./internal/agent/core/ 全绿; AST 实测 614→273 行,非测试函数 ≥300 行数由 4 降到 3。 --- internal/agent/core/tooldefs.go | 693 +++++++++----------------------- 1 file changed, 188 insertions(+), 505 deletions(-) diff --git a/internal/agent/core/tooldefs.go b/internal/agent/core/tooldefs.go index 4877651..cc7ab28 100644 --- a/internal/agent/core/tooldefs.go +++ b/internal/agent/core/tooldefs.go @@ -208,6 +208,30 @@ func (a *Agent) buildToolCatalog() string { return sb.String() } +// toolDef 构造一个 OpenAI function-call 工具 schema。 +// +// 存在的理由:这张工具表里每一条原本都是 4 层嵌套的 +// map[string]interface{} 字面量(约 20 行/条);本助手把它压成一次调用, +// 只消除重复、不改变 schema 形状——properties 原样保留(空表仍序列化为 {}), +// required 为空则整个键省略。 +func toolDef(name, description string, properties map[string]interface{}, required ...string) map[string]interface{} { + params := map[string]interface{}{ + "type": "object", + "properties": properties, + } + if len(required) > 0 { + params["required"] = required + } + return map[string]interface{}{ + "type": "function", + "function": map[string]interface{}{ + "name": name, + "description": description, + "parameters": params, + }, + } +} + func (a *Agent) buildToolDefs() []interface{} { var tools []interface{} @@ -244,371 +268,134 @@ func (a *Agent) buildToolDefs() []interface{} { } if a.personaStore != nil { - tools = append(tools, map[string]interface{}{ - "type": "function", - "function": map[string]interface{}{ - "name": "persona_set", - "description": "【首启人格】落地用户的人格选择并记录「已经问过」。仅在用户明确答复后调用:默认用 mode=default;自定义用 mode=custom 并把人格内容放进 content;用户说以后再说用 mode=later。", - "parameters": map[string]interface{}{ - "type": "object", - "properties": map[string]interface{}{ - "mode": map[string]interface{}{"type": "string", "description": "default | custom | later"}, - "content": map[string]interface{}{"type": "string", "description": "自定义人格内容(mode=custom 时必填)"}, - }, - "required": []string{"mode"}, - }, - }, - }) + tools = append(tools, toolDef("persona_set", "【首启人格】落地用户的人格选择并记录「已经问过」。仅在用户明确答复后调用:默认用 mode=default;自定义用 mode=custom 并把人格内容放进 content;用户说以后再说用 mode=later。", map[string]interface{}{ + "mode": map[string]interface{}{"type": "string", "description": "default | custom | later"}, + "content": map[string]interface{}{"type": "string", "description": "自定义人格内容(mode=custom 时必填)"}, + }, "mode")) } if a.memory != nil { - tools = append(tools, map[string]interface{}{ - "type": "function", - "function": map[string]interface{}{ - "name": "memory_merge", - "description": "【记忆清理】合并两个同义实体。将所有关系从 source 重定向到 target,然后彻底删除 source。注意:实体删除后不可恢复,合并前请确认语义一致。", - "parameters": map[string]interface{}{ - "type": "object", - "properties": map[string]interface{}{ - "source": map[string]interface{}{"type": "string", "description": "被合并的实体名(合并后消失)"}, - "target": map[string]interface{}{"type": "string", "description": "保留的实体名"}, - }, - "required": []string{"source", "target"}, - }, - }, - }) - tools = append(tools, map[string]interface{}{ - "type": "function", - "function": map[string]interface{}{ - "name": "memory_delete_entity", - "description": "【记忆清理】彻底删除指定实体及其所有关联关系。用于清理无用的噪音实体,如 mentionCount=0 的孤立实体、distiller 自动产生的垃圾节点、确认无用的旧数据。此操作不可恢复。", - "parameters": map[string]interface{}{ - "type": "object", - "properties": map[string]interface{}{ - "name": map[string]interface{}{"type": "string", "description": "要删除的实体名称"}, - }, - "required": []string{"name"}, - }, - }, - }) - tools = append(tools, map[string]interface{}{ - "type": "function", - "function": map[string]interface{}{ - "name": "memory_block_merge", - "description": "【记忆清理】标记两个实体在指定轮次内不尝试合并,用于阻止误判。当 LLM 判断两个实体虽然相似但不是同一事物时,使用此工具阻止后续心跳自动推送合并候选。每次心跳扫描双方计数各减一,归零后恢复候选资格。", - "parameters": map[string]interface{}{ - "type": "object", - "properties": map[string]interface{}{ - "entity_a": map[string]interface{}{"type": "string", "description": "第一个实体名"}, - "entity_b": map[string]interface{}{"type": "string", "description": "第二个实体名"}, - "rounds": map[string]interface{}{"type": "integer", "description": "阻止轮次数(每次心跳各减一,归零后恢复)"}, - }, - "required": []string{"entity_a", "entity_b", "rounds"}, - }, - }, - }) - tools = append(tools, map[string]interface{}{ - "type": "function", - "function": map[string]interface{}{ - "name": "memory_purge", - "description": "【记忆清理】删除记忆库中符合条件的垃圾关系和数据。当用户要求整理记忆时,用 memory_introspect 发现低质量实体后,用此工具批量删除。如 @merged 后缀的残留实体、mentionCount=0 的孤立实体、distiller 自动生成的噪音关系等。支持软删(soft)和物理删除(hard)。", - "parameters": map[string]interface{}{ - "type": "object", - "properties": map[string]interface{}{ - "subject_contains": map[string]interface{}{"type": "string", "description": "主体名包含的关键词,如 '@merged' 可清理已合并残留"}, - "relation_type": map[string]interface{}{"type": "string", "description": "关系类型,如 '提及'、'回应'"}, - "target_contains": map[string]interface{}{"type": "string", "description": "客体名包含的关键词"}, - "mode": map[string]interface{}{"type": "string", "description": "soft(标记删除)/ hard(物理删除)", "default": "soft"}, - }, - }, - }, - }) - tools = append(tools, map[string]interface{}{ - "type": "function", - "function": map[string]interface{}{ - "name": "memory_edit", - "description": "【记忆清理】编辑单条记忆关系:删除旧的 relation 并写入新的。用于修正错误的实体名或关系类型。", - "parameters": map[string]interface{}{ - "type": "object", - "properties": map[string]interface{}{ - "old_subject": map[string]interface{}{"type": "string", "description": "旧主体名"}, - "old_relation": map[string]interface{}{"type": "string", "description": "旧关系类型"}, - "old_object": map[string]interface{}{"type": "string", "description": "旧客体名"}, - "new_subject": map[string]interface{}{"type": "string", "description": "新主体名(不填则不变)"}, - "new_relation": map[string]interface{}{"type": "string", "description": "新关系类型(不填则不变)"}, - "new_object": map[string]interface{}{"type": "string", "description": "新客体名(不填则不变)"}, - }, - "required": []string{"old_subject", "old_relation", "old_object"}, - }, - }, - }) + tools = append(tools, toolDef("memory_merge", "【记忆清理】合并两个同义实体。将所有关系从 source 重定向到 target,然后彻底删除 source。注意:实体删除后不可恢复,合并前请确认语义一致。", map[string]interface{}{ + "source": map[string]interface{}{"type": "string", "description": "被合并的实体名(合并后消失)"}, + "target": map[string]interface{}{"type": "string", "description": "保留的实体名"}, + }, "source", "target")) + tools = append(tools, toolDef("memory_delete_entity", "【记忆清理】彻底删除指定实体及其所有关联关系。用于清理无用的噪音实体,如 mentionCount=0 的孤立实体、distiller 自动产生的垃圾节点、确认无用的旧数据。此操作不可恢复。", map[string]interface{}{ + "name": map[string]interface{}{"type": "string", "description": "要删除的实体名称"}, + }, "name")) + tools = append(tools, toolDef("memory_block_merge", "【记忆清理】标记两个实体在指定轮次内不尝试合并,用于阻止误判。当 LLM 判断两个实体虽然相似但不是同一事物时,使用此工具阻止后续心跳自动推送合并候选。每次心跳扫描双方计数各减一,归零后恢复候选资格。", map[string]interface{}{ + "entity_a": map[string]interface{}{"type": "string", "description": "第一个实体名"}, + "entity_b": map[string]interface{}{"type": "string", "description": "第二个实体名"}, + "rounds": map[string]interface{}{"type": "integer", "description": "阻止轮次数(每次心跳各减一,归零后恢复)"}, + }, "entity_a", "entity_b", "rounds")) + tools = append(tools, toolDef("memory_purge", "【记忆清理】删除记忆库中符合条件的垃圾关系和数据。当用户要求整理记忆时,用 memory_introspect 发现低质量实体后,用此工具批量删除。如 @merged 后缀的残留实体、mentionCount=0 的孤立实体、distiller 自动生成的噪音关系等。支持软删(soft)和物理删除(hard)。", map[string]interface{}{ + "subject_contains": map[string]interface{}{"type": "string", "description": "主体名包含的关键词,如 '@merged' 可清理已合并残留"}, + "relation_type": map[string]interface{}{"type": "string", "description": "关系类型,如 '提及'、'回应'"}, + "target_contains": map[string]interface{}{"type": "string", "description": "客体名包含的关键词"}, + "mode": map[string]interface{}{"type": "string", "description": "soft(标记删除)/ hard(物理删除)", "default": "soft"}, + })) + tools = append(tools, toolDef("memory_edit", "【记忆清理】编辑单条记忆关系:删除旧的 relation 并写入新的。用于修正错误的实体名或关系类型。", map[string]interface{}{ + "old_subject": map[string]interface{}{"type": "string", "description": "旧主体名"}, + "old_relation": map[string]interface{}{"type": "string", "description": "旧关系类型"}, + "old_object": map[string]interface{}{"type": "string", "description": "旧客体名"}, + "new_subject": map[string]interface{}{"type": "string", "description": "新主体名(不填则不变)"}, + "new_relation": map[string]interface{}{"type": "string", "description": "新关系类型(不填则不变)"}, + "new_object": map[string]interface{}{"type": "string", "description": "新客体名(不填则不变)"}, + }, "old_subject", "old_relation", "old_object")) } if a.knowledge != nil { - tools = append(tools, map[string]interface{}{ - "type": "function", - "function": map[string]interface{}{ - "name": "knowledge_search", - "description": "搜索知识库。输入查询关键词,返回相关知识内容。", - "parameters": map[string]interface{}{ - "type": "object", - "properties": map[string]interface{}{ - "query": map[string]interface{}{"type": "string", "description": "查询关键词"}, - "top_k": map[string]interface{}{"type": "integer", "description": "返回数量", "default": 5}, - }, - "required": []string{"query"}, - }, - }, - }) - tools = append(tools, map[string]interface{}{ - "type": "function", - "function": map[string]interface{}{ - "name": "knowledge_list", - "description": "列出知识库中所有知识分类。", - "parameters": map[string]interface{}{ - "type": "object", - "properties": map[string]interface{}{}, - }, - }, - }) + tools = append(tools, toolDef("knowledge_search", "搜索知识库。输入查询关键词,返回相关知识内容。", map[string]interface{}{ + "query": map[string]interface{}{"type": "string", "description": "查询关键词"}, + "top_k": map[string]interface{}{"type": "integer", "description": "返回数量", "default": 5}, + }, "query")) + tools = append(tools, toolDef("knowledge_list", "列出知识库中所有知识分类。", map[string]interface{}{})) } if a.knowledge != nil { - tools = append(tools, map[string]interface{}{ - "type": "function", - "function": map[string]interface{}{ - "name": "knowledge_create", - "description": "创建新知识。将知识写入知识库(knowledge/目录),自动向量化索引。", - "parameters": map[string]interface{}{ - "type": "object", - "properties": map[string]interface{}{ - "name": map[string]interface{}{"type": "string", "description": "知识名称(用作目录名)"}, - "content": map[string]interface{}{"type": "string", "description": "知识内容,支持 Markdown"}, - }, - "required": []string{"name", "content"}, - }, - }, - }) - tools = append(tools, map[string]interface{}{ - "type": "function", - "function": map[string]interface{}{ - "name": "knowledge_delete", - "description": "删除知识库中的指定知识条目。", - "parameters": map[string]interface{}{ - "type": "object", - "properties": map[string]interface{}{ - "name": map[string]interface{}{"type": "string", "description": "要删除的知识名称"}, - }, - "required": []string{"name"}, - }, - }, - }) + tools = append(tools, toolDef("knowledge_create", "创建新知识。将知识写入知识库(knowledge/目录),自动向量化索引。", map[string]interface{}{ + "name": map[string]interface{}{"type": "string", "description": "知识名称(用作目录名)"}, + "content": map[string]interface{}{"type": "string", "description": "知识内容,支持 Markdown"}, + }, "name", "content")) + tools = append(tools, toolDef("knowledge_delete", "删除知识库中的指定知识条目。", map[string]interface{}{ + "name": map[string]interface{}{"type": "string", "description": "要删除的知识名称"}, + }, "name")) } if a.docStore != nil { - tools = append(tools, map[string]interface{}{ - "type": "function", - "function": map[string]interface{}{ - "name": "doc_query", - "description": "查询文档记忆。输入查询内容,返回相关文档摘要。", - "parameters": map[string]interface{}{ - "type": "object", - "properties": map[string]interface{}{ - "query": map[string]interface{}{"type": "string", "description": "查询内容"}, - "top_k": map[string]interface{}{"type": "integer", "description": "返回数量", "default": 3}, - }, - "required": []string{"query"}, - }, + tools = append(tools, toolDef("doc_query", "查询文档记忆。输入查询内容,返回相关文档摘要。", map[string]interface{}{ + "query": map[string]interface{}{"type": "string", "description": "查询内容"}, + "top_k": map[string]interface{}{"type": "integer", "description": "返回数量", "default": 3}, + }, "query")) + tools = append(tools, toolDef("doc_commit", "提交一条文档记忆。将重要信息显式写入文档记忆层。", map[string]interface{}{ + "content": map[string]interface{}{"type": "string", "description": "文档内容"}, + "summary": map[string]interface{}{"type": "string", "description": "摘要(可选)"}, + "tags": map[string]interface{}{ + "type": "array", + "description": "标签列表", + "items": map[string]interface{}{"type": "string"}, }, - }) - tools = append(tools, map[string]interface{}{ - "type": "function", - "function": map[string]interface{}{ - "name": "doc_commit", - "description": "提交一条文档记忆。将重要信息显式写入文档记忆层。", - "parameters": map[string]interface{}{ - "type": "object", - "properties": map[string]interface{}{ - "content": map[string]interface{}{"type": "string", "description": "文档内容"}, - "summary": map[string]interface{}{"type": "string", "description": "摘要(可选)"}, - "tags": map[string]interface{}{ - "type": "array", - "description": "标签列表", - "items": map[string]interface{}{"type": "string"}, - }, - "media_digests": map[string]interface{}{ - "type": "array", - "description": "可选:这篇文档关联的媒体 digest(对话或 memory_recall 的「关联媒体」里显示的十六进制串,短的即可)。填了以后检索到这篇文档就能看到并取回原图/音频。", - "items": map[string]interface{}{"type": "string"}, - }, - }, - "required": []string{"content"}, - }, + "media_digests": map[string]interface{}{ + "type": "array", + "description": "可选:这篇文档关联的媒体 digest(对话或 memory_recall 的「关联媒体」里显示的十六进制串,短的即可)。填了以后检索到这篇文档就能看到并取回原图/音频。", + "items": map[string]interface{}{"type": "string"}, }, - }) + }, "content")) } if a.social != nil { - tools = append(tools, map[string]interface{}{ - "type": "function", - "function": map[string]interface{}{ - "name": "person_query", - "description": "查询指定人物的完整档案(特质+社交关系)。用于了解一个人的性格、喜好、背景和社交圈。", - "parameters": map[string]interface{}{ - "type": "object", - "properties": map[string]interface{}{ - "name": map[string]interface{}{"type": "string", "description": "人物名称"}, - }, - "required": []string{"name"}, - }, - }, - }) - tools = append(tools, map[string]interface{}{ - "type": "function", - "function": map[string]interface{}{ - "name": "person_set_trait", - "description": "记录/更新一个人的特质(性格、喜好、习惯等)。例如:person_set_trait(name=\"张三\", trait=\"喜欢\", value=\"红色\")。如果该特质已存在则覆盖。", - "parameters": map[string]interface{}{ - "type": "object", - "properties": map[string]interface{}{ - "name": map[string]interface{}{"type": "string", "description": "人物名称"}, - "trait": map[string]interface{}{"type": "string", "description": "特质名称,如:喜欢、性格、职业、年龄"}, - "value": map[string]interface{}{"type": "string", "description": "特质值,如:红色、开朗、工程师、25岁"}, - }, - "required": []string{"name", "trait", "value"}, - }, - }, - }) - tools = append(tools, map[string]interface{}{ - "type": "function", - "function": map[string]interface{}{ - "name": "person_relate", - "description": "记录两个人之间的社交关系。例如:person_relate(person_a=\"张三\", relation=\"朋友\", person_b=\"李四\")。关系是双向的。", - "parameters": map[string]interface{}{ - "type": "object", - "properties": map[string]interface{}{ - "person_a": map[string]interface{}{"type": "string", "description": "人物A"}, - "relation": map[string]interface{}{"type": "string", "description": "关系类型,如:朋友、家人、同事、邻居、同学"}, - "person_b": map[string]interface{}{"type": "string", "description": "人物B"}, - }, - "required": []string{"person_a", "relation", "person_b"}, - }, - }, - }) - tools = append(tools, map[string]interface{}{ - "type": "function", - "function": map[string]interface{}{ - "name": "person_network", - "description": "查询某人的社交网络(多度关系)。显示该人物周围的相关人物及其关系和特质。", - "parameters": map[string]interface{}{ - "type": "object", - "properties": map[string]interface{}{ - "name": map[string]interface{}{"type": "string", "description": "人物名称"}, - "depth": map[string]interface{}{"type": "integer", "description": "关系深度(默认2)", "default": 2}, - }, - "required": []string{"name"}, - }, - }, - }) + tools = append(tools, toolDef("person_query", "查询指定人物的完整档案(特质+社交关系)。用于了解一个人的性格、喜好、背景和社交圈。", map[string]interface{}{ + "name": map[string]interface{}{"type": "string", "description": "人物名称"}, + }, "name")) + tools = append(tools, toolDef("person_set_trait", "记录/更新一个人的特质(性格、喜好、习惯等)。例如:person_set_trait(name=\"张三\", trait=\"喜欢\", value=\"红色\")。如果该特质已存在则覆盖。", map[string]interface{}{ + "name": map[string]interface{}{"type": "string", "description": "人物名称"}, + "trait": map[string]interface{}{"type": "string", "description": "特质名称,如:喜欢、性格、职业、年龄"}, + "value": map[string]interface{}{"type": "string", "description": "特质值,如:红色、开朗、工程师、25岁"}, + }, "name", "trait", "value")) + tools = append(tools, toolDef("person_relate", "记录两个人之间的社交关系。例如:person_relate(person_a=\"张三\", relation=\"朋友\", person_b=\"李四\")。关系是双向的。", map[string]interface{}{ + "person_a": map[string]interface{}{"type": "string", "description": "人物A"}, + "relation": map[string]interface{}{"type": "string", "description": "关系类型,如:朋友、家人、同事、邻居、同学"}, + "person_b": map[string]interface{}{"type": "string", "description": "人物B"}, + }, "person_a", "relation", "person_b")) + tools = append(tools, toolDef("person_network", "查询某人的社交网络(多度关系)。显示该人物周围的相关人物及其关系和特质。", map[string]interface{}{ + "name": map[string]interface{}{"type": "string", "description": "人物名称"}, + "depth": map[string]interface{}{"type": "integer", "description": "关系深度(默认2)", "default": 2}, + }, "name")) } if a.pluginReg != nil && a.pluginDir != "" { - tools = append(tools, map[string]interface{}{ - "type": "function", - "function": map[string]interface{}{ - "name": "plgreload", - "description": "重载 plugins/ 目录的所有插件。扫描目录变更,原子化替换 IO 设备。", - "parameters": map[string]interface{}{ - "type": "object", - "properties": map[string]interface{}{}, - }, - }, - }) + tools = append(tools, toolDef("plgreload", "重载 plugins/ 目录的所有插件。扫描目录变更,原子化替换 IO 设备。", map[string]interface{}{})) } // 按插件动态拉取工具定义(避免全量注入提示词污染) - tools = append(tools, map[string]interface{}{ - "type": "function", - "function": map[string]interface{}{ - "name": "get_plugin_tools", - "description": "获取指定插件的完整工具定义(名称/参数/用途)。参数 plugin_name 传插件名(见系统提示的【可用工具能力】列表)。省略时返回全部插件的工具摘要。", - "parameters": map[string]interface{}{ - "type": "object", - "properties": map[string]interface{}{ - "plugin_name": map[string]interface{}{"type": "string", "description": "插件名,如 qq / remotedevice / weather", "default": ""}, - }, - }, - }, - }) + tools = append(tools, toolDef("get_plugin_tools", "获取指定插件的完整工具定义(名称/参数/用途)。参数 plugin_name 传插件名(见系统提示的【可用工具能力】列表)。省略时返回全部插件的工具摘要。", map[string]interface{}{ + "plugin_name": map[string]interface{}{"type": "string", "description": "插件名,如 qq / remotedevice / weather", "default": ""}, + })) - tools = append(tools, map[string]interface{}{ - "type": "function", - "function": map[string]interface{}{ - "name": "spawn_child", - "description": "启动一个异步子 Agent 执行独立任务。子 Agent 后台运行,不阻塞当前对话。完成后系统会自动通知你,届时请调用 child_result 工具查看输出。\n使用时机:多个互不依赖的子任务(如同时查三个网站、分别处理多个文件)应并行 spawn 多个子 Agent,不要自己串行逐个执行;长耗时任务(批量处理、多轮搜索)也应交给子 Agent,避免阻塞对话。", - "parameters": map[string]interface{}{ - "type": "object", - "properties": map[string]interface{}{ - "task": map[string]interface{}{ - "type": "string", - "description": "要子 Agent 完成的任务描述。请描述清晰、完整,包含所有必要背景。", - }, - "max_turns": map[string]interface{}{ - "type": "integer", - "description": "子 Agent 最大工具轮数(默认 5,范围 1-30)。复杂任务可调高。", - }, - }, - "required": []string{"task"}, - }, + tools = append(tools, toolDef("spawn_child", "启动一个异步子 Agent 执行独立任务。子 Agent 后台运行,不阻塞当前对话。完成后系统会自动通知你,届时请调用 child_result 工具查看输出。\n使用时机:多个互不依赖的子任务(如同时查三个网站、分别处理多个文件)应并行 spawn 多个子 Agent,不要自己串行逐个执行;长耗时任务(批量处理、多轮搜索)也应交给子 Agent,避免阻塞对话。", map[string]interface{}{ + "task": map[string]interface{}{ + "type": "string", + "description": "要子 Agent 完成的任务描述。请描述清晰、完整,包含所有必要背景。", }, - }) - tools = append(tools, map[string]interface{}{ - "type": "function", - "function": map[string]interface{}{ - "name": "child_result", - "description": "查询异步子 Agent 的执行结果。当收到'子任务已完成'的通知后,调用此工具获取输出。", - "parameters": map[string]interface{}{ - "type": "object", - "properties": map[string]interface{}{ - "task_id": map[string]interface{}{ - "type": "string", - "description": "spawn_child 返回的任务 ID,如 child_1", - }, - }, - "required": []string{"task_id"}, - }, + "max_turns": map[string]interface{}{ + "type": "integer", + "description": "子 Agent 最大工具轮数(默认 5,范围 1-30)。复杂任务可调高。", }, - }) + }, "task")) + tools = append(tools, toolDef("child_result", "查询异步子 Agent 的执行结果。当收到'子任务已完成'的通知后,调用此工具获取输出。", map[string]interface{}{ + "task_id": map[string]interface{}{ + "type": "string", + "description": "spawn_child 返回的任务 ID,如 child_1", + }, + }, "task_id")) if a.providerManager != nil { - tools = append(tools, map[string]interface{}{ - "type": "function", - "function": map[string]interface{}{ - "name": "llm_list_sources", - "description": "列出所有可用的 LLM 源(如 deepseek、openai、ollama),每个源有对应的 Lua 适配器和配置。如需切换 LLM 源,请使用 llm_set_source。", - "parameters": map[string]interface{}{ - "type": "object", - "properties": map[string]interface{}{}, - }, + tools = append(tools, toolDef("llm_list_sources", "列出所有可用的 LLM 源(如 deepseek、openai、ollama),每个源有对应的 Lua 适配器和配置。如需切换 LLM 源,请使用 llm_set_source。", map[string]interface{}{})) + tools = append(tools, toolDef("llm_set_source", "切换当前 LLM 源到指定名称。变更立即生效,后续对话将使用新的 LLM 源。源名称可通过 llm_list_sources 查看。", map[string]interface{}{ + "name": map[string]interface{}{ + "type": "string", + "description": "LLM 源名称(如 deepseek、openai、ollama)", }, - }) - tools = append(tools, map[string]interface{}{ - "type": "function", - "function": map[string]interface{}{ - "name": "llm_set_source", - "description": "切换当前 LLM 源到指定名称。变更立即生效,后续对话将使用新的 LLM 源。源名称可通过 llm_list_sources 查看。", - "parameters": map[string]interface{}{ - "type": "object", - "properties": map[string]interface{}{ - "name": map[string]interface{}{ - "type": "string", - "description": "LLM 源名称(如 deepseek、openai、ollama)", - }, - }, - "required": []string{"name"}, - }, - }, - }) + }, "name")) } channels := a.io.ListChannels() @@ -627,196 +414,92 @@ func (a *Agent) buildToolDefs() []interface{} { desc = ch.Name + " 输出通道" } - tools = append(tools, map[string]interface{}{ - "type": "function", - "function": map[string]interface{}{ - "name": "output_send__" + ch.Name, - "description": desc + "。能力: " + capStr + "。payload 为消息载荷(type 默认 text,可省略),meta 为 JSON 发送元数据。用 _help 查看 meta 格式与 type 枚举。", - "parameters": map[string]interface{}{ - "type": "object", - "properties": map[string]interface{}{ - "payload": map[string]interface{}{ - "type": "string", - "description": "消息载荷。type=text 时填文字,type=file/image 时填 URL 或路径", - }, - "meta": map[string]interface{}{ - "type": "string", - "description": "JSON 对象,包含发送所需的元数据。用 output_send__" + ch.Name + "_help 查看 meta 格式", - }, - "type": map[string]interface{}{ - "type": "string", - "description": "载荷类型,默认 text;其它枚举用 channel._help 查看", - }, - }, - "required": []string{"payload"}, - }, + tools = append(tools, toolDef("output_send__"+ch.Name, desc+"。能力: "+capStr+"。payload 为消息载荷(type 默认 text,可省略),meta 为 JSON 发送元数据。用 _help 查看 meta 格式与 type 枚举。", map[string]interface{}{ + "payload": map[string]interface{}{ + "type": "string", + "description": "消息载荷。type=text 时填文字,type=file/image 时填 URL 或路径", }, - }) + "meta": map[string]interface{}{ + "type": "string", + "description": "JSON 对象,包含发送所需的元数据。用 output_send__" + ch.Name + "_help 查看 meta 格式", + }, + "type": map[string]interface{}{ + "type": "string", + "description": "载荷类型,默认 text;其它枚举用 channel._help 查看", + }, + }, "payload")) - tools = append(tools, map[string]interface{}{ - "type": "function", - "function": map[string]interface{}{ - "name": "output_send__" + ch.Name + "_help", - "description": "查看 " + ch.Name + " 输出通道的 meta 格式说明和 type 枚举", - "parameters": map[string]interface{}{ - "type": "object", - "properties": map[string]interface{}{}, - }, - }, - }) + tools = append(tools, toolDef("output_send__"+ch.Name+"_help", "查看 "+ch.Name+" 输出通道的 meta 格式说明和 type 枚举", map[string]interface{}{})) } - tools = append(tools, map[string]interface{}{ - "type": "function", - "function": map[string]interface{}{ - "name": "output_list_channels", - "description": "列出所有可用输出通道及其能力(如 text/file/image/audio)和对应的输出门工具名称。", - "parameters": map[string]interface{}{ - "type": "object", - "properties": map[string]interface{}{}, - }, - }, - }) + tools = append(tools, toolDef("output_list_channels", "列出所有可用输出通道及其能力(如 text/file/image/audio)和对应的输出门工具名称。", map[string]interface{}{})) // 父侧:驻留子控制面(单工具多动作,见设计 §7)。 if a.parentID == "" { - tools = append(tools, map[string]interface{}{ - "type": "function", - "function": map[string]interface{}{ - "name": "resident_agents", - "description": "管理驻留子 agent(长期派驻的下属):list 列出 / create 创建(划入 inputch + " + - "授权输出通道 + 注入任务提示词)/ send 发送消息(对子而言是 L4 中断,取消其当前状态并插入新消息)" + - "/ inspect 查看其 inputch 处理表(不打断它)/ compress 压缩其上下文(保留语义,子继续存在)" + - "/ reclaim 回收(父选哪些纳入主记忆,然后取消该子)/ destroy 立刻销毁并移除。", - "parameters": map[string]interface{}{ - "type": "object", - "properties": map[string]interface{}{ - "action": map[string]interface{}{ - "type": "string", - "enum": []string{"list", "create", "send", "inspect", "compress", "reclaim", "destroy"}, - }, - "id": map[string]interface{}{"type": "string", "description": "驻留子 id"}, - "task_prompt": map[string]interface{}{"type": "string", "description": "create:在固定提示词之上注入的任务提示词"}, - "input_chs": map[string]interface{}{"type": "string", "description": "create:划入的 inputch(逗号分隔)"}, - "allowed_outputs": map[string]interface{}{"type": "string", "description": "create:授权的输出通道(逗号分隔;留空=完整授权)"}, - "capacity": map[string]interface{}{"type": "number", "description": "create:划入 inputch 的队列容量"}, - "temp_path": map[string]interface{}{"type": "string", "description": "create:temp 图记忆路径(留空则用 data_dir/residents//graph.db)"}, - "text": map[string]interface{}{"type": "string", "description": "send:要发给子 agent 的消息"}, - }, - "required": []string{"action"}, - }, + tools = append(tools, toolDef("resident_agents", "管理驻留子 agent(长期派驻的下属):list 列出 / create 创建(划入 inputch + "+ + "授权输出通道 + 注入任务提示词)/ send 发送消息(对子而言是 L4 中断,取消其当前状态并插入新消息)"+ + "/ inspect 查看其 inputch 处理表(不打断它)/ compress 压缩其上下文(保留语义,子继续存在)"+ + "/ reclaim 回收(父选哪些纳入主记忆,然后取消该子)/ destroy 立刻销毁并移除。", map[string]interface{}{ + "action": map[string]interface{}{ + "type": "string", + "enum": []string{"list", "create", "send", "inspect", "compress", "reclaim", "destroy"}, }, - }) + "id": map[string]interface{}{"type": "string", "description": "驻留子 id"}, + "task_prompt": map[string]interface{}{"type": "string", "description": "create:在固定提示词之上注入的任务提示词"}, + "input_chs": map[string]interface{}{"type": "string", "description": "create:划入的 inputch(逗号分隔)"}, + "allowed_outputs": map[string]interface{}{"type": "string", "description": "create:授权的输出通道(逗号分隔;留空=完整授权)"}, + "capacity": map[string]interface{}{"type": "number", "description": "create:划入 inputch 的队列容量"}, + "temp_path": map[string]interface{}{"type": "string", "description": "create:temp 图记忆路径(留空则用 data_dir/residents//graph.db)"}, + "text": map[string]interface{}{"type": "string", "description": "send:要发给子 agent 的消息"}, + }, "action")) } // 子侧(驻留子):主动汇报(L3)与主动写处理表。 if a.parentID != "" { - tools = append(tools, map[string]interface{}{ - "type": "function", - "function": map[string]interface{}{ - "name": "notify_parent", - "description": "向主 agent 汇报(以 L3 中断投给它)。用于主动报告进展/结论,而不是等它来问。", - "parameters": map[string]interface{}{ - "type": "object", - "properties": map[string]interface{}{"text": map[string]interface{}{"type": "string", "description": "汇报内容"}}, - "required": []string{"text"}, - }, - }, - }) - tools = append(tools, map[string]interface{}{ - "type": "function", - "function": map[string]interface{}{ - "name": "inputch_note", - "description": "为**本轮** inputch 主动写入处理信息(主 agent 会查这张表判断你的进度)。" + - "写了就不会再被系统自动记录;不写则本轮结束时系统自动写。", - "parameters": map[string]interface{}{ - "type": "object", - "properties": map[string]interface{}{"text": map[string]interface{}{"type": "string", "description": "本轮处理信息摘要"}}, - "required": []string{"text"}, - }, - }, - }) + tools = append(tools, toolDef("notify_parent", "向主 agent 汇报(以 L3 中断投给它)。用于主动报告进展/结论,而不是等它来问。", map[string]interface{}{"text": map[string]interface{}{"type": "string", "description": "汇报内容"}}, "text")) + tools = append(tools, toolDef("inputch_note", "为**本轮** inputch 主动写入处理信息(主 agent 会查这张表判断你的进度)。"+ + "写了就不会再被系统自动记录;不写则本轮结束时系统自动写。", map[string]interface{}{"text": map[string]interface{}{"type": "string", "description": "本轮处理信息摘要"}}, "text")) } - tools = append(tools, map[string]interface{}{ - "type": "function", - "function": map[string]interface{}{ - "name": "input_channels", - "description": "查看 inputch(最基本的输入路由单位):哪些已注册、谁注册的、" + - "各自划给了哪个 agent、容量与记忆策略。单工具多视图。", - "parameters": map[string]interface{}{ - "type": "object", - "properties": map[string]interface{}{ - "view": map[string]interface{}{ - "type": "string", - "description": "all=全部已注册(默认)| mine=划给本 agent 的 | " + - "unassigned=尚未划出的 | by_agent=按归属分组的划分总览 | detail=单个详情", - "enum": []string{"all", "mine", "unassigned", "by_agent", "detail"}, - }, - "name": map[string]interface{}{ - "type": "string", - "description": "view=detail 时必填:inputch 名", - }, - }, - }, + tools = append(tools, toolDef("input_channels", "查看 inputch(最基本的输入路由单位):哪些已注册、谁注册的、"+ + "各自划给了哪个 agent、容量与记忆策略。单工具多视图。", map[string]interface{}{ + "view": map[string]interface{}{ + "type": "string", + "description": "all=全部已注册(默认)| mine=划给本 agent 的 | " + + "unassigned=尚未划出的 | by_agent=按归属分组的划分总览 | detail=单个详情", + "enum": []string{"all", "mine", "unassigned", "by_agent", "detail"}, }, - }) + "name": map[string]interface{}{ + "type": "string", + "description": "view=detail 时必填:inputch 名", + }, + })) if a.pendingMedia != nil { - tools = append(tools, map[string]interface{}{ - "type": "function", - "function": map[string]interface{}{ - "name": "describe_image", - "description": "描述当前用户上传的图片内容。使用配置的多模态模型或默认 LLM 进行识别。调用此工具后你将获得图片的详细文字描述。", - "parameters": map[string]interface{}{ - "type": "object", - "properties": map[string]interface{}{ - "provider": map[string]interface{}{ - "type": "string", - "description": "可选:用于图片描述的 LLM 源名称,不填则使用默认模型", - }, - "detail": map[string]interface{}{ - "type": "string", - "description": "描述详细程度: high / low / auto", - "default": "high", - }, - }, - }, + tools = append(tools, toolDef("describe_image", "描述当前用户上传的图片内容。使用配置的多模态模型或默认 LLM 进行识别。调用此工具后你将获得图片的详细文字描述。", map[string]interface{}{ + "provider": map[string]interface{}{ + "type": "string", + "description": "可选:用于图片描述的 LLM 源名称,不填则使用默认模型", }, - }) - tools = append(tools, map[string]interface{}{ - "type": "function", - "function": map[string]interface{}{ - "name": "transcribe_audio", - "description": "转写当前用户上传的音频内容为文字。使用配置的多模态模型或默认 LLM 进行语音识别。", - "parameters": map[string]interface{}{ - "type": "object", - "properties": map[string]interface{}{ - "provider": map[string]interface{}{ - "type": "string", - "description": "可选:用于音频转写的 LLM 源名称,不填则使用默认模型", - }, - }, - }, + "detail": map[string]interface{}{ + "type": "string", + "description": "描述详细程度: high / low / auto", + "default": "high", }, - }) + })) + tools = append(tools, toolDef("transcribe_audio", "转写当前用户上传的音频内容为文字。使用配置的多模态模型或默认 LLM 进行语音识别。", map[string]interface{}{ + "provider": map[string]interface{}{ + "type": "string", + "description": "可选:用于音频转写的 LLM 源名称,不填则使用默认模型", + }, + })) if a.inputCfg.Image.OCREnabled { - tools = append(tools, map[string]interface{}{ - "type": "function", - "function": map[string]interface{}{ - "name": "ocr_image", - "description": "对当前用户上传的图片执行 OCR 文字识别,提取图片中的文字内容。适用于截图、文档照片、菜单等场景。", - "parameters": map[string]interface{}{ - "type": "object", - "properties": map[string]interface{}{ - "language": map[string]interface{}{ - "type": "string", - "description": "OCR 语言(如 chi_sim+eng),默认自动", - }, - }, - }, + tools = append(tools, toolDef("ocr_image", "对当前用户上传的图片执行 OCR 文字识别,提取图片中的文字内容。适用于截图、文档照片、菜单等场景。", map[string]interface{}{ + "language": map[string]interface{}{ + "type": "string", + "description": "OCR 语言(如 chi_sim+eng),默认自动", }, - }) + })) } }