@zhin.js/agent 0.1.15 → 0.1.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (205) hide show
  1. package/README.md +80 -43
  2. package/lib/builtin/activate-skill-tool.d.ts +21 -0
  3. package/lib/builtin/activate-skill-tool.d.ts.map +1 -0
  4. package/lib/builtin/activate-skill-tool.js +57 -0
  5. package/lib/builtin/activate-skill-tool.js.map +1 -0
  6. package/lib/builtin/ask-user-tool.d.ts +28 -0
  7. package/lib/builtin/ask-user-tool.d.ts.map +1 -0
  8. package/lib/builtin/ask-user-tool.js +182 -0
  9. package/lib/builtin/ask-user-tool.js.map +1 -0
  10. package/lib/builtin/bash-tool.d.ts +23 -0
  11. package/lib/builtin/bash-tool.d.ts.map +1 -0
  12. package/lib/builtin/bash-tool.js +64 -0
  13. package/lib/builtin/bash-tool.js.map +1 -0
  14. package/lib/builtin/bing-search-html.d.ts +37 -0
  15. package/lib/builtin/bing-search-html.d.ts.map +1 -0
  16. package/lib/builtin/bing-search-html.js +116 -0
  17. package/lib/builtin/bing-search-html.js.map +1 -0
  18. package/lib/builtin/builtin-base-tool.d.ts +25 -0
  19. package/lib/builtin/builtin-base-tool.d.ts.map +1 -0
  20. package/lib/builtin/builtin-base-tool.js +30 -0
  21. package/lib/builtin/builtin-base-tool.js.map +1 -0
  22. package/lib/builtin/edit-file-tool.d.ts +13 -0
  23. package/lib/builtin/edit-file-tool.d.ts.map +1 -0
  24. package/lib/builtin/edit-file-tool.js +87 -0
  25. package/lib/builtin/edit-file-tool.js.map +1 -0
  26. package/lib/builtin/file-edit-quote-utils.d.ts +24 -0
  27. package/lib/builtin/file-edit-quote-utils.d.ts.map +1 -0
  28. package/lib/builtin/file-edit-quote-utils.js +81 -0
  29. package/lib/builtin/file-edit-quote-utils.js.map +1 -0
  30. package/lib/builtin/glob-tool.d.ts +23 -0
  31. package/lib/builtin/glob-tool.d.ts.map +1 -0
  32. package/lib/builtin/glob-tool.js +54 -0
  33. package/lib/builtin/glob-tool.js.map +1 -0
  34. package/lib/builtin/grep-tool.d.ts +23 -0
  35. package/lib/builtin/grep-tool.d.ts.map +1 -0
  36. package/lib/builtin/grep-tool.js +118 -0
  37. package/lib/builtin/grep-tool.js.map +1 -0
  38. package/lib/builtin/install-skill-tool.d.ts +24 -0
  39. package/lib/builtin/install-skill-tool.d.ts.map +1 -0
  40. package/lib/builtin/install-skill-tool.js +76 -0
  41. package/lib/builtin/install-skill-tool.js.map +1 -0
  42. package/lib/builtin/list-dir-tool.d.ts +13 -0
  43. package/lib/builtin/list-dir-tool.d.ts.map +1 -0
  44. package/lib/builtin/list-dir-tool.js +59 -0
  45. package/lib/builtin/list-dir-tool.js.map +1 -0
  46. package/lib/builtin/read-file-tool.d.ts +14 -0
  47. package/lib/builtin/read-file-tool.d.ts.map +1 -0
  48. package/lib/builtin/read-file-tool.js +77 -0
  49. package/lib/builtin/read-file-tool.js.map +1 -0
  50. package/lib/builtin/read-memory-tool.d.ts +14 -0
  51. package/lib/builtin/read-memory-tool.d.ts.map +1 -0
  52. package/lib/builtin/read-memory-tool.js +49 -0
  53. package/lib/builtin/read-memory-tool.js.map +1 -0
  54. package/lib/builtin/spawn-task-tool.d.ts +20 -0
  55. package/lib/builtin/spawn-task-tool.d.ts.map +1 -0
  56. package/lib/builtin/spawn-task-tool.js +57 -0
  57. package/lib/builtin/spawn-task-tool.js.map +1 -0
  58. package/lib/builtin/todo-read-tool.d.ts +14 -0
  59. package/lib/builtin/todo-read-tool.d.ts.map +1 -0
  60. package/lib/builtin/todo-read-tool.js +56 -0
  61. package/lib/builtin/todo-read-tool.js.map +1 -0
  62. package/lib/builtin/todo-write-tool.d.ts +14 -0
  63. package/lib/builtin/todo-write-tool.d.ts.map +1 -0
  64. package/lib/builtin/todo-write-tool.js +54 -0
  65. package/lib/builtin/todo-write-tool.js.map +1 -0
  66. package/lib/builtin/web-fetch-tool.d.ts +19 -0
  67. package/lib/builtin/web-fetch-tool.d.ts.map +1 -0
  68. package/lib/builtin/web-fetch-tool.js +89 -0
  69. package/lib/builtin/web-fetch-tool.js.map +1 -0
  70. package/lib/builtin/web-search-locale.d.ts +16 -0
  71. package/lib/builtin/web-search-locale.d.ts.map +1 -0
  72. package/lib/builtin/web-search-locale.js +73 -0
  73. package/lib/builtin/web-search-locale.js.map +1 -0
  74. package/lib/builtin/web-search-tool.d.ts +20 -0
  75. package/lib/builtin/web-search-tool.d.ts.map +1 -0
  76. package/lib/builtin/web-search-tool.js +105 -0
  77. package/lib/builtin/web-search-tool.js.map +1 -0
  78. package/lib/builtin/web-tool-utils.d.ts +4 -0
  79. package/lib/builtin/web-tool-utils.d.ts.map +1 -0
  80. package/lib/builtin/web-tool-utils.js +4 -0
  81. package/lib/builtin/web-tool-utils.js.map +1 -0
  82. package/lib/builtin/write-file-tool.d.ts +13 -0
  83. package/lib/builtin/write-file-tool.d.ts.map +1 -0
  84. package/lib/builtin/write-file-tool.js +57 -0
  85. package/lib/builtin/write-file-tool.js.map +1 -0
  86. package/lib/builtin/write-memory-tool.d.ts +14 -0
  87. package/lib/builtin/write-memory-tool.d.ts.map +1 -0
  88. package/lib/builtin/write-memory-tool.js +50 -0
  89. package/lib/builtin/write-memory-tool.js.map +1 -0
  90. package/lib/builtin-tools.d.ts +10 -11
  91. package/lib/builtin-tools.d.ts.map +1 -1
  92. package/lib/builtin-tools.js +44 -862
  93. package/lib/builtin-tools.js.map +1 -1
  94. package/lib/defaults/tools.d.ts +3 -6
  95. package/lib/defaults/tools.d.ts.map +1 -1
  96. package/lib/defaults/tools.js +3 -11
  97. package/lib/defaults/tools.js.map +1 -1
  98. package/lib/index.d.ts +28 -4
  99. package/lib/index.d.ts.map +1 -1
  100. package/lib/index.js +25 -3
  101. package/lib/index.js.map +1 -1
  102. package/lib/init/create-zhin-agent.d.ts.map +1 -1
  103. package/lib/init/create-zhin-agent.js +4 -3
  104. package/lib/init/create-zhin-agent.js.map +1 -1
  105. package/lib/init/message-media.d.ts +8 -0
  106. package/lib/init/message-media.d.ts.map +1 -0
  107. package/lib/init/message-media.js +75 -0
  108. package/lib/init/message-media.js.map +1 -0
  109. package/lib/init/output-renderer.d.ts +3 -0
  110. package/lib/init/output-renderer.d.ts.map +1 -0
  111. package/lib/init/output-renderer.js +38 -0
  112. package/lib/init/output-renderer.js.map +1 -0
  113. package/lib/init/register-ai-trigger.d.ts +1 -1
  114. package/lib/init/register-ai-trigger.d.ts.map +1 -1
  115. package/lib/init/register-ai-trigger.js +35 -159
  116. package/lib/init/register-ai-trigger.js.map +1 -1
  117. package/lib/init/register-builtin-tools.d.ts.map +1 -1
  118. package/lib/init/register-builtin-tools.js +9 -5
  119. package/lib/init/register-builtin-tools.js.map +1 -1
  120. package/lib/orchestrator/index.d.ts +2 -0
  121. package/lib/orchestrator/index.d.ts.map +1 -1
  122. package/lib/orchestrator/index.js +1 -0
  123. package/lib/orchestrator/index.js.map +1 -1
  124. package/lib/orchestrator/owner-confirm-orchestration.d.ts +26 -0
  125. package/lib/orchestrator/owner-confirm-orchestration.d.ts.map +1 -0
  126. package/lib/orchestrator/owner-confirm-orchestration.js +87 -0
  127. package/lib/orchestrator/owner-confirm-orchestration.js.map +1 -0
  128. package/lib/orchestrator/resource-registry.d.ts +1 -0
  129. package/lib/orchestrator/resource-registry.d.ts.map +1 -1
  130. package/lib/orchestrator/resource-registry.js +6 -0
  131. package/lib/orchestrator/resource-registry.js.map +1 -1
  132. package/lib/orchestrator/tool-registry.d.ts +5 -11
  133. package/lib/orchestrator/tool-registry.d.ts.map +1 -1
  134. package/lib/orchestrator/tool-registry.js +30 -75
  135. package/lib/orchestrator/tool-registry.js.map +1 -1
  136. package/lib/orchestrator/tool-selection.d.ts +39 -0
  137. package/lib/orchestrator/tool-selection.d.ts.map +1 -0
  138. package/lib/orchestrator/tool-selection.js +319 -0
  139. package/lib/orchestrator/tool-selection.js.map +1 -0
  140. package/lib/orchestrator/types.d.ts +2 -0
  141. package/lib/orchestrator/types.d.ts.map +1 -1
  142. package/lib/reserved-tools.d.ts +3 -0
  143. package/lib/reserved-tools.d.ts.map +1 -0
  144. package/lib/reserved-tools.js +30 -0
  145. package/lib/reserved-tools.js.map +1 -0
  146. package/lib/security/exec-policy.d.ts +1 -1
  147. package/lib/security/exec-policy.js +3 -3
  148. package/lib/security/exec-policy.js.map +1 -1
  149. package/lib/service.d.ts +9 -5
  150. package/lib/service.d.ts.map +1 -1
  151. package/lib/service.js +42 -36
  152. package/lib/service.js.map +1 -1
  153. package/lib/subagent.d.ts +6 -0
  154. package/lib/subagent.d.ts.map +1 -1
  155. package/lib/subagent.js +38 -15
  156. package/lib/subagent.js.map +1 -1
  157. package/lib/task-executor.d.ts +1 -0
  158. package/lib/task-executor.d.ts.map +1 -1
  159. package/lib/task-executor.js +15 -8
  160. package/lib/task-executor.js.map +1 -1
  161. package/lib/zhin-agent/builtin-tools.d.ts +1 -3
  162. package/lib/zhin-agent/builtin-tools.d.ts.map +1 -1
  163. package/lib/zhin-agent/builtin-tools.js +4 -41
  164. package/lib/zhin-agent/builtin-tools.js.map +1 -1
  165. package/lib/zhin-agent/config.d.ts +7 -0
  166. package/lib/zhin-agent/config.d.ts.map +1 -1
  167. package/lib/zhin-agent/config.js +12 -7
  168. package/lib/zhin-agent/config.js.map +1 -1
  169. package/lib/zhin-agent/context-budget.d.ts +27 -0
  170. package/lib/zhin-agent/context-budget.d.ts.map +1 -0
  171. package/lib/zhin-agent/context-budget.js +50 -0
  172. package/lib/zhin-agent/context-budget.js.map +1 -0
  173. package/lib/zhin-agent/index.d.ts +10 -0
  174. package/lib/zhin-agent/index.d.ts.map +1 -1
  175. package/lib/zhin-agent/index.js +125 -88
  176. package/lib/zhin-agent/index.js.map +1 -1
  177. package/lib/zhin-agent/model-harness.d.ts +29 -0
  178. package/lib/zhin-agent/model-harness.d.ts.map +1 -0
  179. package/lib/zhin-agent/model-harness.js +67 -0
  180. package/lib/zhin-agent/model-harness.js.map +1 -0
  181. package/lib/zhin-agent/pre-exec.d.ts +7 -0
  182. package/lib/zhin-agent/pre-exec.d.ts.map +1 -0
  183. package/lib/zhin-agent/pre-exec.js +25 -0
  184. package/lib/zhin-agent/pre-exec.js.map +1 -0
  185. package/lib/zhin-agent/prompt.d.ts +10 -8
  186. package/lib/zhin-agent/prompt.d.ts.map +1 -1
  187. package/lib/zhin-agent/prompt.js +38 -30
  188. package/lib/zhin-agent/prompt.js.map +1 -1
  189. package/lib/zhin-agent/text-sanitize.d.ts +8 -0
  190. package/lib/zhin-agent/text-sanitize.d.ts.map +1 -0
  191. package/lib/zhin-agent/text-sanitize.js +19 -0
  192. package/lib/zhin-agent/text-sanitize.js.map +1 -0
  193. package/lib/zhin-agent/tool-runtime.d.ts +31 -0
  194. package/lib/zhin-agent/tool-runtime.d.ts.map +1 -0
  195. package/lib/zhin-agent/tool-runtime.js +49 -0
  196. package/lib/zhin-agent/tool-runtime.js.map +1 -0
  197. package/package.json +8 -6
  198. package/lib/tools.d.ts +0 -45
  199. package/lib/tools.d.ts.map +0 -1
  200. package/lib/tools.js +0 -205
  201. package/lib/tools.js.map +0 -1
  202. package/lib/zhin-agent/tool-collector.d.ts +0 -22
  203. package/lib/zhin-agent/tool-collector.d.ts.map +0 -1
  204. package/lib/zhin-agent/tool-collector.js +0 -225
  205. package/lib/zhin-agent/tool-collector.js.map +0 -1
@@ -0,0 +1,118 @@
1
+ /**
2
+ * grep — 按正则搜索文件内容(ripgrep 优先,grep 回退)
3
+ */
4
+ import { exec } from 'node:child_process';
5
+ import { promisify } from 'node:util';
6
+ import * as path from 'node:path';
7
+ import { assertFileAccess, shellEscape } from '../security/file-policy.js';
8
+ import { errMsg } from '../discovery/utils.js';
9
+ import { BuiltinBaseTool } from './builtin-base-tool.js';
10
+ const defaultExecAsync = promisify(exec);
11
+ export const GREP_PARAMETERS = {
12
+ type: 'object',
13
+ properties: {
14
+ pattern: { type: 'string', description: '正则表达式' },
15
+ path: { type: 'string', description: '搜索路径(默认 .)' },
16
+ include: { type: 'string', description: '文件类型过滤(如 *.ts)' },
17
+ context: { type: 'number', description: '匹配行上下文行数(-C 参数)' },
18
+ before: { type: 'number', description: '匹配行之前显示行数(-B 参数)' },
19
+ after: { type: 'number', description: '匹配行之后显示行数(-A 参数)' },
20
+ ignore_case: { type: 'boolean', description: '大小写不敏感搜索(-i 参数)' },
21
+ multiline: { type: 'boolean', description: '多行模式,. 匹配换行(仅 ripgrep 支持)' },
22
+ limit: { type: 'number', description: '最多返回结果行数(默认 50)' },
23
+ },
24
+ required: ['pattern'],
25
+ };
26
+ export class GrepBuiltinTool extends BuiltinBaseTool {
27
+ execAsync;
28
+ name = 'grep';
29
+ description = '按正则搜索文件内容,返回匹配行和行号。优先使用 ripgrep (rg),回退到 grep。';
30
+ parameters = GREP_PARAMETERS;
31
+ kind = 'file';
32
+ constructor(execAsync = defaultExecAsync) {
33
+ super();
34
+ this.execAsync = execAsync;
35
+ this.tags.push('search', 'regex');
36
+ this.keywords.push('搜索', '查找内容', 'grep', '正则', 'rg', 'ripgrep');
37
+ }
38
+ async run(args, _context) {
39
+ const patternArg = args.pattern;
40
+ if (typeof patternArg !== 'string' || !patternArg.trim()) {
41
+ return 'Error: pattern is required';
42
+ }
43
+ try {
44
+ const searchPath = typeof args.path === 'string' && args.path.trim() ? args.path : '.';
45
+ assertFileAccess(path.resolve(process.cwd(), searchPath));
46
+ const safePattern = shellEscape(patternArg);
47
+ const safePath = shellEscape(searchPath);
48
+ const limit = typeof args.limit === 'number' && Number.isFinite(args.limit) ? args.limit : 50;
49
+ let useRipgrep = false;
50
+ try {
51
+ await this.execAsync('rg --version', { timeout: 3000 });
52
+ useRipgrep = true;
53
+ }
54
+ catch {
55
+ /* ripgrep 不可用,回退到 grep */
56
+ }
57
+ let cmd;
58
+ if (useRipgrep) {
59
+ const rgFlags = ['-n'];
60
+ if (args.ignore_case === true)
61
+ rgFlags.push('-i');
62
+ if (args.multiline === true)
63
+ rgFlags.push('-U', '--multiline-dotall');
64
+ if (typeof args.context === 'number' && Number.isFinite(args.context)) {
65
+ rgFlags.push(`-C${args.context}`);
66
+ }
67
+ else {
68
+ if (typeof args.before === 'number' && Number.isFinite(args.before)) {
69
+ rgFlags.push(`-B${args.before}`);
70
+ }
71
+ if (typeof args.after === 'number' && Number.isFinite(args.after)) {
72
+ rgFlags.push(`-A${args.after}`);
73
+ }
74
+ }
75
+ if (typeof args.include === 'string' && args.include.trim()) {
76
+ rgFlags.push(`--glob=${shellEscape(args.include)}`);
77
+ }
78
+ cmd = `rg ${rgFlags.join(' ')} ${safePattern} ${safePath} 2>/dev/null | head -${limit}`;
79
+ }
80
+ else {
81
+ const grepFlags = ['-rn'];
82
+ if (args.ignore_case === true)
83
+ grepFlags.push('-i');
84
+ if (typeof args.context === 'number' && Number.isFinite(args.context)) {
85
+ grepFlags.push(`-C${args.context}`);
86
+ }
87
+ else {
88
+ if (typeof args.before === 'number' && Number.isFinite(args.before)) {
89
+ grepFlags.push(`-B${args.before}`);
90
+ }
91
+ if (typeof args.after === 'number' && Number.isFinite(args.after)) {
92
+ grepFlags.push(`-A${args.after}`);
93
+ }
94
+ }
95
+ const includeFlag = typeof args.include === 'string' && args.include.trim()
96
+ ? `--include=${shellEscape(args.include)}`
97
+ : '';
98
+ cmd = `grep ${grepFlags.join(' ')} ${includeFlag} ${safePattern} ${safePath} 2>/dev/null | head -${limit}`;
99
+ }
100
+ const { stdout } = await this.execAsync(cmd, { cwd: process.cwd() });
101
+ const engine = useRipgrep ? '(ripgrep)' : '(grep)';
102
+ return stdout.trim()
103
+ ? `${engine}\n${stdout.trim()}`
104
+ : `No matches for '${patternArg}' ${engine}`;
105
+ }
106
+ catch (e) {
107
+ const err = e;
108
+ // rg/grep:无匹配时常为 exit code 1;Node 也可能以 number 或 string 形式携带
109
+ if (Number(err.code) === 1)
110
+ return `No matches for '${patternArg}'`;
111
+ return `Error: ${errMsg(e)}`;
112
+ }
113
+ }
114
+ }
115
+ export function createGrepTool() {
116
+ return new GrepBuiltinTool().toTool();
117
+ }
118
+ //# sourceMappingURL=grep-tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grep-tool.js","sourceRoot":"","sources":["../../src/builtin/grep-tool.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import { type Tool, type ToolContext, type ToolParametersSchema, type ToolResult } from '@zhin.js/core';
2
+ import { BuiltinBaseTool } from './builtin-base-tool.js';
3
+ export interface InstallSkillToolOptions {
4
+ /**
5
+ * 安装根目录:将创建 `<skillName>/SKILL.md`。
6
+ * 默认 `join(process.cwd(), 'skills')`(与历史行为一致)。
7
+ */
8
+ skillsInstallRoot?: string;
9
+ /** 可注入以便单测 mock */
10
+ fetchImpl?: typeof fetch;
11
+ }
12
+ export declare const INSTALL_SKILL_PARAMETERS: ToolParametersSchema;
13
+ export declare class InstallSkillBuiltinTool extends BuiltinBaseTool {
14
+ private readonly opts;
15
+ readonly name = "install_skill";
16
+ readonly description = "\u4ECE URL \u4E0B\u8F7D SKILL.md \u5E76\u5B89\u88C5\u5230\u672C\u5730 skills/ \u76EE\u5F55\u3002\u7528\u6237\u8981\u6C42\u52A0\u5165/\u5B89\u88C5/\u4E0B\u8F7D\u67D0\u4E2A\u6280\u80FD\u65F6\u4F7F\u7528";
17
+ readonly parameters: ToolParametersSchema<Record<string, any>>;
18
+ readonly kind = "skill";
19
+ constructor(opts?: InstallSkillToolOptions);
20
+ private skillsRoot;
21
+ run(args: Record<string, unknown>, _context?: ToolContext): Promise<ToolResult>;
22
+ }
23
+ export declare function createInstallSkillTool(opts?: InstallSkillToolOptions): Tool;
24
+ //# sourceMappingURL=install-skill-tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install-skill-tool.d.ts","sourceRoot":"","sources":["../../src/builtin/install-skill-tool.ts"],"names":[],"mappings":"AAKA,OAAO,EAAU,KAAK,IAAI,EAAE,KAAK,WAAW,EAAE,KAAK,oBAAoB,EAAE,KAAK,UAAU,EAAE,MAAM,eAAe,CAAC;AAEhH,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,MAAM,WAAW,uBAAuB;IACtC;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,mBAAmB;IACnB,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC1B;AAED,eAAO,MAAM,wBAAwB,EAAE,oBAStC,CAAC;AAIF,qBAAa,uBAAwB,SAAQ,eAAe;IAO9C,OAAO,CAAC,QAAQ,CAAC,IAAI;IANjC,QAAQ,CAAC,IAAI,mBAAmB;IAChC,QAAQ,CAAC,WAAW,8MACwC;IAC5D,QAAQ,CAAC,UAAU,4CAA4B;IAC/C,QAAQ,CAAC,IAAI,WAAW;gBAEK,IAAI,GAAE,uBAA4B;IAgB/D,OAAO,CAAC,UAAU;IAIZ,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;CAoCtF;AAED,wBAAgB,sBAAsB,CAAC,IAAI,CAAC,EAAE,uBAAuB,GAAG,IAAI,CAE3E"}
@@ -0,0 +1,76 @@
1
+ /**
2
+ * install_skill — 从 URL 下载 SKILL.md 并安装到本地 skills/ 目录
3
+ */
4
+ import * as fs from 'node:fs/promises';
5
+ import * as path from 'node:path';
6
+ import { Logger } from '@zhin.js/core';
7
+ import { errMsg } from '../discovery/utils.js';
8
+ import { BuiltinBaseTool } from './builtin-base-tool.js';
9
+ export const INSTALL_SKILL_PARAMETERS = {
10
+ type: 'object',
11
+ properties: {
12
+ url: {
13
+ type: 'string',
14
+ description: 'SKILL.md 文件的完整 URL(如 https://example.com/skill.md)',
15
+ },
16
+ },
17
+ required: ['url'],
18
+ };
19
+ const logger = new Logger(null, 'install-skill-tool');
20
+ export class InstallSkillBuiltinTool extends BuiltinBaseTool {
21
+ opts;
22
+ name = 'install_skill';
23
+ description = '从 URL 下载 SKILL.md 并安装到本地 skills/ 目录。用户要求加入/安装/下载某个技能时使用';
24
+ parameters = INSTALL_SKILL_PARAMETERS;
25
+ kind = 'skill';
26
+ constructor(opts = {}) {
27
+ super();
28
+ this.opts = opts;
29
+ this.tags.push('skill', 'install');
30
+ this.keywords.push('安装技能', '下载技能', '加入', '添加技能', 'install', 'skill', 'join', '学会', '学习技能');
31
+ }
32
+ skillsRoot() {
33
+ return this.opts.skillsInstallRoot ?? path.join(process.cwd(), 'skills');
34
+ }
35
+ async run(args, _context) {
36
+ const fetchFn = this.opts.fetchImpl ?? globalThis.fetch.bind(globalThis);
37
+ try {
38
+ const response = await fetchFn(args.url, {
39
+ headers: { 'User-Agent': 'Mozilla/5.0 (compatible; ZhinBot/1.0)' },
40
+ signal: AbortSignal.timeout(15000),
41
+ });
42
+ if (!response.ok)
43
+ return `Error: HTTP ${response.status} ${response.statusText}`;
44
+ const content = await response.text();
45
+ const fmMatch = content.match(/^---\s*\n([\s\S]*?)\n---/);
46
+ if (!fmMatch)
47
+ return 'Error: 无效的 SKILL.md 文件(缺少 frontmatter)';
48
+ let jsYaml;
49
+ try {
50
+ jsYaml = await import('js-yaml');
51
+ if (jsYaml.default)
52
+ jsYaml = jsYaml.default;
53
+ }
54
+ catch {
55
+ return 'Error: 无法加载 yaml 解析器';
56
+ }
57
+ const metadata = jsYaml.load(fmMatch[1]);
58
+ if (!metadata?.name)
59
+ return 'Error: SKILL.md 缺少 name 字段';
60
+ const skillName = metadata.name;
61
+ const skillDir = path.join(this.skillsRoot(), skillName);
62
+ await fs.mkdir(skillDir, { recursive: true });
63
+ const skillPath = path.join(skillDir, 'SKILL.md');
64
+ await fs.writeFile(skillPath, content, 'utf-8');
65
+ logger.info(`技能已安装: ${skillName} → ${skillPath}`);
66
+ return `✅ 技能「${skillName}」已安装到 ${skillPath}。现在可以用 activate_skill("${skillName}") 激活它。`;
67
+ }
68
+ catch (e) {
69
+ return `Error: ${errMsg(e)}`;
70
+ }
71
+ }
72
+ }
73
+ export function createInstallSkillTool(opts) {
74
+ return new InstallSkillBuiltinTool(opts).toTool();
75
+ }
76
+ //# sourceMappingURL=install-skill-tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install-skill-tool.js","sourceRoot":"","sources":["../../src/builtin/install-skill-tool.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { Tool, ToolContext, ToolParametersSchema, ToolResult } from '@zhin.js/core';
2
+ import { BuiltinBaseTool } from './builtin-base-tool.js';
3
+ export declare const LIST_DIR_PARAMETERS: ToolParametersSchema;
4
+ export declare class ListDirBuiltinTool extends BuiltinBaseTool {
5
+ readonly name = "list_dir";
6
+ readonly description = "\u5217\u51FA\u6307\u5B9A\u76EE\u5F55\u4E0B\u7684\u6587\u4EF6\u548C\u5B50\u76EE\u5F55\u540D\u79F0\u3002\u7528\u4E8E\u67E5\u770B\u76EE\u5F55\u7ED3\u6784\u3001\u6709\u54EA\u4E9B\u6587\u4EF6\u3002";
7
+ readonly parameters: ToolParametersSchema<Record<string, any>>;
8
+ readonly kind = "file";
9
+ constructor();
10
+ run(args: Record<string, unknown>, _context?: ToolContext): Promise<ToolResult>;
11
+ }
12
+ export declare function createListDirTool(): Tool;
13
+ //# sourceMappingURL=list-dir-tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-dir-tool.d.ts","sourceRoot":"","sources":["../../src/builtin/list-dir-tool.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,oBAAoB,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAGzF,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,eAAO,MAAM,mBAAmB,EAAE,oBASjC,CAAC;AAEF,qBAAa,kBAAmB,SAAQ,eAAe;IACrD,QAAQ,CAAC,IAAI,cAAc;IAC3B,QAAQ,CAAC,WAAW,sMACiB;IACrC,QAAQ,CAAC,UAAU,4CAAuB;IAC1C,QAAQ,CAAC,IAAI,UAAU;;IAmBjB,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;CAyBtF;AAED,wBAAgB,iBAAiB,IAAI,IAAI,CAExC"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * list_dir — 列出目录内容
3
+ */
4
+ import * as fs from 'node:fs/promises';
5
+ import * as path from 'node:path';
6
+ import { assertFileAccess } from '../security/file-policy.js';
7
+ import { expandHome, nodeErrToFileMessage } from '../discovery/utils.js';
8
+ import { BuiltinBaseTool } from './builtin-base-tool.js';
9
+ export const LIST_DIR_PARAMETERS = {
10
+ type: 'object',
11
+ properties: {
12
+ path: {
13
+ type: 'string',
14
+ description: '要列出的目录路径(绝对或相对项目根目录)',
15
+ },
16
+ },
17
+ required: ['path'],
18
+ };
19
+ export class ListDirBuiltinTool extends BuiltinBaseTool {
20
+ name = 'list_dir';
21
+ description = '列出指定目录下的文件和子目录名称。用于查看目录结构、有哪些文件。';
22
+ parameters = LIST_DIR_PARAMETERS;
23
+ kind = 'file';
24
+ constructor() {
25
+ super();
26
+ this.tags.push('file', 'list');
27
+ this.keywords.push('列目录', '列出目录', '目录列表', '查看目录', 'list directory', 'list dir', 'ls', 'dir', '目录内容', '有哪些文件');
28
+ }
29
+ async run(args, _context) {
30
+ const pathArg = args.path;
31
+ if (typeof pathArg !== 'string' || !pathArg.trim()) {
32
+ return 'Error: path is required';
33
+ }
34
+ try {
35
+ const dirPath = path.resolve(process.cwd(), expandHome(pathArg));
36
+ assertFileAccess(dirPath);
37
+ const stat = await fs.stat(dirPath);
38
+ if (!stat.isDirectory()) {
39
+ return `Error: Not a directory: ${pathArg}`;
40
+ }
41
+ const entries = await fs.readdir(dirPath, { withFileTypes: true });
42
+ if (entries.length === 0) {
43
+ return `Directory ${pathArg} is empty`;
44
+ }
45
+ const lines = [];
46
+ for (const e of entries.sort((a, b) => a.name.localeCompare(b.name))) {
47
+ lines.push((e.isDirectory() ? '[DIR] ' : ' ') + e.name);
48
+ }
49
+ return lines.join('\n');
50
+ }
51
+ catch (e) {
52
+ return nodeErrToFileMessage(e, pathArg, 'list');
53
+ }
54
+ }
55
+ }
56
+ export function createListDirTool() {
57
+ return new ListDirBuiltinTool().toTool();
58
+ }
59
+ //# sourceMappingURL=list-dir-tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-dir-tool.js","sourceRoot":"","sources":["../../src/builtin/list-dir-tool.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { Tool, ToolContext, ToolParametersSchema, ToolResult } from '@zhin.js/core';
2
+ import { BuiltinBaseTool } from './builtin-base-tool.js';
3
+ export declare const READ_FILE_PARAMETERS: ToolParametersSchema;
4
+ export declare class ReadFileBuiltinTool extends BuiltinBaseTool {
5
+ readonly name = "read_file";
6
+ readonly description = "\u8BFB\u53D6\u6307\u5B9A\u8DEF\u5F84\u7684\u6587\u4EF6\u5185\u5BB9\u3002\u7528\u4E8E\u67E5\u770B\u3001\u6253\u5F00\u6216\u8BFB\u53D6\u4EFB\u610F\u6587\u672C\u6587\u4EF6\u3002\u56FE\u7247\u6587\u4EF6\u8FD4\u56DE Base64 \u6570\u636E\u3002";
7
+ readonly parameters: ToolParametersSchema<Record<string, any>>;
8
+ readonly kind = "file";
9
+ constructor();
10
+ run(args: Record<string, unknown>, _context?: ToolContext): Promise<ToolResult>;
11
+ }
12
+ /** 工厂:供 createBuiltinTools 与其它入口使用 */
13
+ export declare function createReadFileTool(): Tool;
14
+ //# sourceMappingURL=read-file-tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read-file-tool.d.ts","sourceRoot":"","sources":["../../src/builtin/read-file-tool.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,oBAAoB,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAOzF,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAUzD,eAAO,MAAM,oBAAoB,EAAE,oBAWlC,CAAC;AAEF,qBAAa,mBAAoB,SAAQ,eAAe;IACtD,QAAQ,CAAC,IAAI,eAAe;IAC5B,QAAQ,CAAC,WAAW,kPAC+B;IACnD,QAAQ,CAAC,UAAU,4CAAwB;IAC3C,QAAQ,CAAC,IAAI,UAAU;;IAmBjB,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;CAoCtF;AAED,sCAAsC;AACtC,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC"}
@@ -0,0 +1,77 @@
1
+ /**
2
+ * read_file — 内置文件读取(PRD #389 竖切1)
3
+ */
4
+ import * as fs from 'node:fs/promises';
5
+ import * as path from 'node:path';
6
+ import { assertFileAccess, isBlockedDevicePath, MAX_READ_FILE_SIZE, } from '../security/file-policy.js';
7
+ import { expandHome, nodeErrToFileMessage } from '../discovery/utils.js';
8
+ import { BuiltinBaseTool } from './builtin-base-tool.js';
9
+ const IMAGE_EXTENSIONS = new Set([
10
+ '.png', '.jpg', '.jpeg', '.gif', '.webp', '.bmp', '.svg', '.ico',
11
+ ]);
12
+ function isImageFile(filePath) {
13
+ return IMAGE_EXTENSIONS.has(path.extname(filePath).toLowerCase());
14
+ }
15
+ export const READ_FILE_PARAMETERS = {
16
+ type: 'object',
17
+ properties: {
18
+ file_path: {
19
+ type: 'string',
20
+ description: '要读取的文件路径(绝对路径或相对项目根目录)',
21
+ },
22
+ offset: { type: 'number', description: '起始行号(0-based,可选,默认从第 1 行开始)' },
23
+ limit: { type: 'number', description: '最多读取行数(可选,默认全部)' },
24
+ },
25
+ required: ['file_path'],
26
+ };
27
+ export class ReadFileBuiltinTool extends BuiltinBaseTool {
28
+ name = 'read_file';
29
+ description = '读取指定路径的文件内容。用于查看、打开或读取任意文本文件。图片文件返回 Base64 数据。';
30
+ parameters = READ_FILE_PARAMETERS;
31
+ kind = 'file';
32
+ constructor() {
33
+ super();
34
+ this.tags.push('file', 'read');
35
+ this.keywords.push('读文件', '读取文件', '查看文件', '打开文件', '文件内容', 'read file', 'read', 'cat', '查看', '打开');
36
+ }
37
+ async run(args, _context) {
38
+ const filePathArg = args.file_path;
39
+ if (typeof filePathArg !== 'string' || !filePathArg.trim()) {
40
+ return 'Error: file_path is required';
41
+ }
42
+ try {
43
+ const fp = expandHome(filePathArg);
44
+ if (isBlockedDevicePath(fp)) {
45
+ return `Error: 禁止读取设备文件 ${fp}(会导致进程挂起或注入攻击)`;
46
+ }
47
+ assertFileAccess(fp);
48
+ const stat = await fs.stat(fp);
49
+ if (stat.size > MAX_READ_FILE_SIZE) {
50
+ return `Error: 文件过大 (${(stat.size / 1024 / 1024).toFixed(1)} MiB),超过 ${MAX_READ_FILE_SIZE / 1024 / 1024} MiB 限制。请使用 offset/limit 分段读取。`;
51
+ }
52
+ if (isImageFile(fp)) {
53
+ const buffer = await fs.readFile(fp);
54
+ const ext = path.extname(fp).toLowerCase().replace('.', '');
55
+ const mimeType = ext === 'jpg' ? 'jpeg' : ext === 'svg' ? 'svg+xml' : ext;
56
+ const b64 = buffer.toString('base64');
57
+ const sizeKb = (buffer.length / 1024).toFixed(1);
58
+ return `[Image: ${path.basename(fp)}, ${sizeKb} KB, type: image/${mimeType}]\ndata:image/${mimeType};base64,${b64.slice(0, 200)}...(total ${b64.length} chars)`;
59
+ }
60
+ const content = await fs.readFile(fp, 'utf-8');
61
+ const lines = content.split('\n');
62
+ const offset = typeof args.offset === 'number' ? args.offset : 0;
63
+ const limit = typeof args.limit === 'number' ? args.limit : lines.length;
64
+ const sliced = lines.slice(offset, offset + limit);
65
+ const numbered = sliced.map((line, i) => `${offset + i + 1} | ${line}`).join('\n');
66
+ return `File: ${fp} (${lines.length} lines, showing ${offset + 1}-${Math.min(offset + limit, lines.length)})\n${numbered}`;
67
+ }
68
+ catch (e) {
69
+ return nodeErrToFileMessage(e, String(filePathArg), 'read');
70
+ }
71
+ }
72
+ }
73
+ /** 工厂:供 createBuiltinTools 与其它入口使用 */
74
+ export function createReadFileTool() {
75
+ return new ReadFileBuiltinTool().toTool();
76
+ }
77
+ //# sourceMappingURL=read-file-tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read-file-tool.js","sourceRoot":"","sources":["../../src/builtin/read-file-tool.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { Tool, ToolContext, ToolParametersSchema, ToolResult } from '@zhin.js/core';
2
+ import { BuiltinBaseTool } from './builtin-base-tool.js';
3
+ export declare const READ_MEMORY_PARAMETERS: ToolParametersSchema;
4
+ export declare class ReadMemoryBuiltinTool extends BuiltinBaseTool {
5
+ private readonly dataDir;
6
+ readonly name = "read_memory";
7
+ readonly description = "\u8BFB\u53D6\u6301\u4E45\u5316\u8BB0\u5FC6\uFF08AGENTS.md\uFF09\u3002\u8BB0\u5FC6\u8DE8\u4F1A\u8BDD\u4FDD\u6301\u3002scope: global\uFF08\u5171\u4EAB\uFF09\u6216 chat\uFF08\u6309\u804A\u5929\u9694\u79BB\uFF09";
8
+ readonly parameters: ToolParametersSchema<Record<string, any>>;
9
+ readonly kind = "memory";
10
+ constructor(dataDir: string);
11
+ run(args: Record<string, unknown>, _context?: ToolContext): Promise<ToolResult>;
12
+ }
13
+ export declare function createReadMemoryTool(dataDir: string): Tool;
14
+ //# sourceMappingURL=read-memory-tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read-memory-tool.d.ts","sourceRoot":"","sources":["../../src/builtin/read-memory-tool.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,oBAAoB,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEzF,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,eAAO,MAAM,sBAAsB,EAAE,oBAWpC,CAAC;AAEF,qBAAa,qBAAsB,SAAQ,eAAe;IAO5C,OAAO,CAAC,QAAQ,CAAC,OAAO;IANpC,QAAQ,CAAC,IAAI,iBAAiB;IAC9B,QAAQ,CAAC,WAAW,qNAC0C;IAC9D,QAAQ,CAAC,UAAU,4CAA0B;IAC7C,QAAQ,CAAC,IAAI,YAAY;gBAEI,OAAO,EAAE,MAAM;IAMtC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;CAWtF;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE1D"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * read_memory — 读取持久化记忆(AGENTS.md)
3
+ */
4
+ import * as fs from 'node:fs';
5
+ import * as path from 'node:path';
6
+ import { errMsg } from '../discovery/utils.js';
7
+ import { BuiltinBaseTool } from './builtin-base-tool.js';
8
+ export const READ_MEMORY_PARAMETERS = {
9
+ type: 'object',
10
+ properties: {
11
+ scope: {
12
+ type: 'string',
13
+ description: "'global' 或 'chat'(默认 chat)",
14
+ enum: ['global', 'chat'],
15
+ },
16
+ chat_id: { type: 'string', description: '聊天 ID(chat scope 时使用)' },
17
+ },
18
+ required: ['scope'],
19
+ };
20
+ export class ReadMemoryBuiltinTool extends BuiltinBaseTool {
21
+ dataDir;
22
+ name = 'read_memory';
23
+ description = '读取持久化记忆(AGENTS.md)。记忆跨会话保持。scope: global(共享)或 chat(按聊天隔离)';
24
+ parameters = READ_MEMORY_PARAMETERS;
25
+ kind = 'memory';
26
+ constructor(dataDir) {
27
+ super();
28
+ this.dataDir = dataDir;
29
+ this.tags.push('memory', 'agents');
30
+ this.keywords.push('记忆', '记住', '回忆', '之前', '上次', 'memory');
31
+ }
32
+ async run(args, _context) {
33
+ try {
34
+ const memPath = args.scope === 'global'
35
+ ? path.join(this.dataDir, 'AGENTS.md')
36
+ : path.join(this.dataDir, 'groups', args.chat_id || 'default', 'AGENTS.md');
37
+ if (!fs.existsSync(memPath))
38
+ return 'No memory stored yet.';
39
+ return await fs.promises.readFile(memPath, 'utf-8');
40
+ }
41
+ catch (e) {
42
+ return `Error: ${errMsg(e)}`;
43
+ }
44
+ }
45
+ }
46
+ export function createReadMemoryTool(dataDir) {
47
+ return new ReadMemoryBuiltinTool(dataDir).toTool();
48
+ }
49
+ //# sourceMappingURL=read-memory-tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read-memory-tool.js","sourceRoot":"","sources":["../../src/builtin/read-memory-tool.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,MAAM,CAAC,MAAM,sBAAsB,GAAyB;IAC1D,IAAI,EAAE,QAAQ;IACd,UAAU,EAAE;QACV,KAAK,EAAE;YACL,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,4BAA4B;YACzC,IAAI,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC;SACzB;QACD,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,uBAAuB,EAAE;KAClE;IACD,QAAQ,EAAE,CAAC,OAAO,CAAC;CACpB,CAAC;AAEF,MAAM,OAAO,qBAAsB,SAAQ,eAAe;IAO3B;IANpB,IAAI,GAAG,aAAa,CAAC;IACrB,WAAW,GAClB,2DAA2D,CAAC;IACrD,UAAU,GAAG,sBAAsB,CAAC;IACpC,IAAI,GAAG,QAAQ,CAAC;IAEzB,YAA6B,OAAe;QAC1C,KAAK,EAAE,CAAC;QADmB,YAAO,GAAP,OAAO,CAAQ;QAE1C,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QACnC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;IAC7D,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,IAA6B,EAAE,QAAsB;QAC7D,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,KAAK,QAAQ;gBACrC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC;gBACtC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAG,IAAI,CAAC,OAAkB,IAAI,SAAS,EAAE,WAAW,CAAC,CAAC;YAC1F,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC;gBAAE,OAAO,uBAAuB,CAAC;YAC5D,OAAO,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACtD,CAAC;QAAC,OAAO,CAAU,EAAE,CAAC;YACpB,OAAO,UAAU,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/B,CAAC;IACH,CAAC;CACF;AAED,MAAM,UAAU,oBAAoB,CAAC,OAAe;IAClD,OAAO,IAAI,qBAAqB,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,CAAC;AACrD,CAAC"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * spawn_task — 主会话将耗时任务派给后台子 agent(与 issue #396 对齐)
3
+ */
4
+ import type { AgentTool, Tool, ToolContext, ToolParametersSchema, ToolResult } from '@zhin.js/core';
5
+ import type { SubagentManager, SubagentOrigin } from '../subagent.js';
6
+ import { BuiltinBaseTool } from './builtin-base-tool.js';
7
+ export declare const SPAWN_TASK_PARAMETERS: ToolParametersSchema;
8
+ export declare function originFromToolContext(context: ToolContext): SubagentOrigin;
9
+ export declare class SpawnTaskBuiltinTool extends BuiltinBaseTool {
10
+ private readonly sessionContext;
11
+ private readonly manager;
12
+ readonly name = "spawn_task";
13
+ readonly description = "\u5C06\u590D\u6742\u6216\u8017\u65F6\u7684\u4EFB\u52A1\u4EA4\u7ED9\u540E\u53F0\u5B50 agent \u5F02\u6B65\u5904\u7406\u3002\u5B50 agent \u62E5\u6709\u6587\u4EF6\u8BFB\u5199\u3001Shell\u3001\u7F51\u7EDC\u641C\u7D22\u7B49\u80FD\u529B\uFF0C\u5B8C\u6210\u540E\u4F1A\u81EA\u52A8\u901A\u77E5\u7528\u6237\u3002\u9002\u7528\u4E8E\u9700\u8981\u591A\u6B65\u64CD\u4F5C\u7684\u6587\u4EF6\u5904\u7406\u3001\u4EE3\u7801\u5206\u6790\u3001\u6570\u636E\u6536\u96C6\u7B49\u4EFB\u52A1\u3002";
14
+ readonly parameters: ToolParametersSchema<Record<string, any>>;
15
+ constructor(sessionContext: ToolContext, manager: SubagentManager);
16
+ toTool(): Tool;
17
+ run(args: Record<string, unknown>, _context?: ToolContext): Promise<ToolResult>;
18
+ }
19
+ export declare function createSpawnTaskTool(context: ToolContext, manager: SubagentManager): AgentTool;
20
+ //# sourceMappingURL=spawn-task-tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spawn-task-tool.d.ts","sourceRoot":"","sources":["../../src/builtin/spawn-task-tool.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,EAAE,oBAAoB,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AACpG,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACtE,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,eAAO,MAAM,qBAAqB,EAAE,oBAanC,CAAC;AAEF,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,WAAW,GAAG,cAAc,CAQ1E;AAED,qBAAa,oBAAqB,SAAQ,eAAe;IAOrD,OAAO,CAAC,QAAQ,CAAC,cAAc;IAC/B,OAAO,CAAC,QAAQ,CAAC,OAAO;IAP1B,QAAQ,CAAC,IAAI,gBAAgB;IAC7B,QAAQ,CAAC,WAAW,2dAC+E;IACnG,QAAQ,CAAC,UAAU,4CAAyB;gBAGzB,cAAc,EAAE,WAAW,EAC3B,OAAO,EAAE,eAAe;IAO3C,MAAM,IAAI,IAAI;IAMR,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;CAYtF;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,eAAe,GAAG,SAAS,CAE7F"}
@@ -0,0 +1,57 @@
1
+ import { BuiltinBaseTool } from './builtin-base-tool.js';
2
+ export const SPAWN_TASK_PARAMETERS = {
3
+ type: 'object',
4
+ properties: {
5
+ task: {
6
+ type: 'string',
7
+ description: '要交给子 agent 完成的任务描述(尽量详细,包含目标、范围、期望输出)',
8
+ },
9
+ label: {
10
+ type: 'string',
11
+ description: '任务的简短标签(用于显示,可选)',
12
+ },
13
+ },
14
+ required: ['task'],
15
+ };
16
+ export function originFromToolContext(context) {
17
+ return {
18
+ platform: context.platform || '',
19
+ botId: context.botId || '',
20
+ senderId: context.senderId || '',
21
+ sceneId: context.sceneId || '',
22
+ sceneType: context.message?.$channel?.type || 'private',
23
+ };
24
+ }
25
+ export class SpawnTaskBuiltinTool extends BuiltinBaseTool {
26
+ sessionContext;
27
+ manager;
28
+ name = 'spawn_task';
29
+ description = '将复杂或耗时的任务交给后台子 agent 异步处理。子 agent 拥有文件读写、Shell、网络搜索等能力,完成后会自动通知用户。适用于需要多步操作的文件处理、代码分析、数据收集等任务。';
30
+ parameters = SPAWN_TASK_PARAMETERS;
31
+ constructor(sessionContext, manager) {
32
+ super();
33
+ this.sessionContext = sessionContext;
34
+ this.manager = manager;
35
+ this.tags.push('agent', 'async', 'task', '后台', '子任务');
36
+ this.keywords.push('后台', '异步', '子任务', 'spawn', 'background', '并行', '独立处理');
37
+ }
38
+ toTool() {
39
+ const tool = super.toTool();
40
+ tool.source = 'builtin:context';
41
+ return tool;
42
+ }
43
+ async run(args, _context) {
44
+ const task = args.task;
45
+ const label = args.label;
46
+ if (typeof task !== 'string' || !task) {
47
+ return '请提供任务描述';
48
+ }
49
+ const origin = originFromToolContext(this.sessionContext);
50
+ const labelStr = typeof label === 'string' ? label : undefined;
51
+ return this.manager.spawn({ task, label: labelStr, origin });
52
+ }
53
+ }
54
+ export function createSpawnTaskTool(context, manager) {
55
+ return new SpawnTaskBuiltinTool(context, manager).toTool();
56
+ }
57
+ //# sourceMappingURL=spawn-task-tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spawn-task-tool.js","sourceRoot":"","sources":["../../src/builtin/spawn-task-tool.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,MAAM,CAAC,MAAM,qBAAqB,GAAyB;IACzD,IAAI,EAAE,QAAQ;IACd,UAAU,EAAE;QACV,IAAI,EAAE;YACJ,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,uCAAuC;SACrD;QACD,KAAK,EAAE;YACL,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,kBAAkB;SAChC;KACF;IACD,QAAQ,EAAE,CAAC,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,UAAU,qBAAqB,CAAC,OAAoB;IACxD,OAAO;QACL,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,EAAE;QAChC,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,EAAE;QAC1B,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,EAAE;QAChC,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,EAAE;QAC9B,SAAS,EAAE,OAAO,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,IAAI,SAAS;KACxD,CAAC;AACJ,CAAC;AAED,MAAM,OAAO,oBAAqB,SAAQ,eAAe;IAOpC;IACA;IAPV,IAAI,GAAG,YAAY,CAAC;IACpB,WAAW,GAClB,gGAAgG,CAAC;IAC1F,UAAU,GAAG,qBAAqB,CAAC;IAE5C,YACmB,cAA2B,EAC3B,OAAwB;QAEzC,KAAK,EAAE,CAAC;QAHS,mBAAc,GAAd,cAAc,CAAa;QAC3B,YAAO,GAAP,OAAO,CAAiB;QAGzC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;QACtD,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;IAC7E,CAAC;IAED,MAAM;QACJ,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;QAC5B,IAAI,CAAC,MAAM,GAAG,iBAAiB,CAAC;QAChC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,IAA6B,EAAE,QAAsB;QAC7D,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QACvB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;QACzB,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;YACtC,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,MAAM,MAAM,GAAG,qBAAqB,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAC1D,MAAM,QAAQ,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;QAE/D,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;IAC/D,CAAC;CACF;AAED,MAAM,UAAU,mBAAmB,CAAC,OAAoB,EAAE,OAAwB;IAChF,OAAO,IAAI,oBAAoB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,MAAM,EAAe,CAAC;AAC1E,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { Tool, ToolContext, ToolParametersSchema, ToolResult } from '@zhin.js/core';
2
+ import { BuiltinBaseTool } from './builtin-base-tool.js';
3
+ export declare const TODO_READ_PARAMETERS: ToolParametersSchema;
4
+ export declare class TodoReadBuiltinTool extends BuiltinBaseTool {
5
+ private readonly dataDir;
6
+ readonly name = "todo_read";
7
+ readonly description = "\u8BFB\u53D6\u5F53\u524D\u4EFB\u52A1\u8BA1\u5212\u5217\u8868\uFF0C\u7528\u4E8E\u67E5\u770B\u8FDB\u5EA6\u548C\u5F85\u529E\u4E8B\u9879";
8
+ readonly parameters: ToolParametersSchema<Record<string, any>>;
9
+ readonly kind = "plan";
10
+ constructor(dataDir: string);
11
+ run(args: Record<string, unknown>, _context?: ToolContext): Promise<ToolResult>;
12
+ }
13
+ export declare function createTodoReadTool(dataDir: string): Tool;
14
+ //# sourceMappingURL=todo-read-tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"todo-read-tool.d.ts","sourceRoot":"","sources":["../../src/builtin/todo-read-tool.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,oBAAoB,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEzF,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,eAAO,MAAM,oBAAoB,EAAE,oBASlC,CAAC;AAEF,qBAAa,mBAAoB,SAAQ,eAAe;IAM1C,OAAO,CAAC,QAAQ,CAAC,OAAO;IALpC,QAAQ,CAAC,IAAI,eAAe;IAC5B,QAAQ,CAAC,WAAW,0IAA4B;IAChD,QAAQ,CAAC,UAAU,4CAAwB;IAC3C,QAAQ,CAAC,IAAI,UAAU;gBAEM,OAAO,EAAE,MAAM;IAMtC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;CAoBtF;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAExD"}