@zhin.js/core 1.0.37 → 1.0.39

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 (204) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/README.md +57 -3
  3. package/lib/adapter.d.ts +11 -0
  4. package/lib/adapter.d.ts.map +1 -1
  5. package/lib/adapter.js +61 -0
  6. package/lib/adapter.js.map +1 -1
  7. package/lib/ai/index.d.ts +3 -39
  8. package/lib/ai/index.d.ts.map +1 -1
  9. package/lib/ai/index.js +2 -44
  10. package/lib/ai/index.js.map +1 -1
  11. package/lib/ai/providers/anthropic.d.ts.map +1 -1
  12. package/lib/ai/providers/anthropic.js +2 -0
  13. package/lib/ai/providers/anthropic.js.map +1 -1
  14. package/lib/ai/providers/openai.d.ts.map +1 -1
  15. package/lib/ai/providers/openai.js +8 -0
  16. package/lib/ai/providers/openai.js.map +1 -1
  17. package/lib/ai/types.d.ts +5 -3
  18. package/lib/ai/types.d.ts.map +1 -1
  19. package/lib/built/ai-trigger.js.map +1 -1
  20. package/lib/built/common-adapter-tools.d.ts +55 -0
  21. package/lib/built/common-adapter-tools.d.ts.map +1 -0
  22. package/lib/built/common-adapter-tools.js +158 -0
  23. package/lib/built/common-adapter-tools.js.map +1 -0
  24. package/lib/built/dispatcher.d.ts.map +1 -1
  25. package/lib/built/dispatcher.js +50 -46
  26. package/lib/built/dispatcher.js.map +1 -1
  27. package/lib/built/skill.d.ts.map +1 -1
  28. package/lib/built/skill.js +0 -1
  29. package/lib/built/skill.js.map +1 -1
  30. package/lib/built/tool.d.ts +3 -3
  31. package/lib/built/tool.d.ts.map +1 -1
  32. package/lib/built/tool.js.map +1 -1
  33. package/lib/feature.d.ts +16 -1
  34. package/lib/feature.d.ts.map +1 -1
  35. package/lib/feature.js +41 -2
  36. package/lib/feature.js.map +1 -1
  37. package/lib/index.d.ts +1 -0
  38. package/lib/index.d.ts.map +1 -1
  39. package/lib/index.js +2 -0
  40. package/lib/index.js.map +1 -1
  41. package/lib/plugin.d.ts +38 -1
  42. package/lib/plugin.d.ts.map +1 -1
  43. package/lib/plugin.js +73 -22
  44. package/lib/plugin.js.map +1 -1
  45. package/lib/scheduler/scheduler.js +1 -1
  46. package/lib/scheduler/scheduler.js.map +1 -1
  47. package/lib/types.d.ts +43 -28
  48. package/lib/types.d.ts.map +1 -1
  49. package/lib/utils.d.ts +12 -3
  50. package/lib/utils.d.ts.map +1 -1
  51. package/lib/utils.js +64 -54
  52. package/lib/utils.js.map +1 -1
  53. package/package.json +5 -5
  54. package/src/adapter.ts +85 -5
  55. package/src/ai/index.ts +8 -186
  56. package/src/ai/providers/anthropic.ts +1 -0
  57. package/src/ai/providers/openai.ts +5 -1
  58. package/src/ai/types.ts +6 -4
  59. package/src/built/ai-trigger.ts +2 -2
  60. package/src/built/common-adapter-tools.ts +207 -0
  61. package/src/built/dispatcher.ts +51 -52
  62. package/src/built/skill.ts +3 -4
  63. package/src/built/tool.ts +3 -3
  64. package/src/feature.ts +45 -2
  65. package/src/index.ts +2 -0
  66. package/src/plugin.ts +92 -31
  67. package/src/scheduler/scheduler.ts +1 -1
  68. package/src/types.ts +39 -28
  69. package/src/utils.ts +63 -52
  70. package/tests/ai/setup.ts +2 -2
  71. package/tests/utils.test.ts +1 -3
  72. package/lib/ai/agent.d.ts +0 -130
  73. package/lib/ai/agent.d.ts.map +0 -1
  74. package/lib/ai/agent.js +0 -702
  75. package/lib/ai/agent.js.map +0 -1
  76. package/lib/ai/bootstrap.d.ts +0 -91
  77. package/lib/ai/bootstrap.d.ts.map +0 -1
  78. package/lib/ai/bootstrap.js +0 -243
  79. package/lib/ai/bootstrap.js.map +0 -1
  80. package/lib/ai/builtin-tools.d.ts +0 -59
  81. package/lib/ai/builtin-tools.d.ts.map +0 -1
  82. package/lib/ai/builtin-tools.js +0 -777
  83. package/lib/ai/builtin-tools.js.map +0 -1
  84. package/lib/ai/compaction.d.ts +0 -132
  85. package/lib/ai/compaction.d.ts.map +0 -1
  86. package/lib/ai/compaction.js +0 -370
  87. package/lib/ai/compaction.js.map +0 -1
  88. package/lib/ai/context-manager.d.ts +0 -213
  89. package/lib/ai/context-manager.d.ts.map +0 -1
  90. package/lib/ai/context-manager.js +0 -313
  91. package/lib/ai/context-manager.js.map +0 -1
  92. package/lib/ai/conversation-memory.d.ts +0 -181
  93. package/lib/ai/conversation-memory.d.ts.map +0 -1
  94. package/lib/ai/conversation-memory.js +0 -581
  95. package/lib/ai/conversation-memory.js.map +0 -1
  96. package/lib/ai/cron-engine.d.ts +0 -92
  97. package/lib/ai/cron-engine.d.ts.map +0 -1
  98. package/lib/ai/cron-engine.js +0 -278
  99. package/lib/ai/cron-engine.js.map +0 -1
  100. package/lib/ai/follow-up.d.ts +0 -131
  101. package/lib/ai/follow-up.d.ts.map +0 -1
  102. package/lib/ai/follow-up.js +0 -265
  103. package/lib/ai/follow-up.js.map +0 -1
  104. package/lib/ai/hooks.d.ts +0 -143
  105. package/lib/ai/hooks.d.ts.map +0 -1
  106. package/lib/ai/hooks.js +0 -108
  107. package/lib/ai/hooks.js.map +0 -1
  108. package/lib/ai/init.d.ts +0 -30
  109. package/lib/ai/init.d.ts.map +0 -1
  110. package/lib/ai/init.js +0 -686
  111. package/lib/ai/init.js.map +0 -1
  112. package/lib/ai/output.d.ts +0 -93
  113. package/lib/ai/output.d.ts.map +0 -1
  114. package/lib/ai/output.js +0 -176
  115. package/lib/ai/output.js.map +0 -1
  116. package/lib/ai/rate-limiter.d.ts +0 -38
  117. package/lib/ai/rate-limiter.d.ts.map +0 -1
  118. package/lib/ai/rate-limiter.js +0 -86
  119. package/lib/ai/rate-limiter.js.map +0 -1
  120. package/lib/ai/service.d.ts +0 -88
  121. package/lib/ai/service.d.ts.map +0 -1
  122. package/lib/ai/service.js +0 -285
  123. package/lib/ai/service.js.map +0 -1
  124. package/lib/ai/session.d.ts +0 -186
  125. package/lib/ai/session.d.ts.map +0 -1
  126. package/lib/ai/session.js +0 -443
  127. package/lib/ai/session.js.map +0 -1
  128. package/lib/ai/subagent.d.ts +0 -50
  129. package/lib/ai/subagent.d.ts.map +0 -1
  130. package/lib/ai/subagent.js +0 -144
  131. package/lib/ai/subagent.js.map +0 -1
  132. package/lib/ai/tone-detector.d.ts +0 -19
  133. package/lib/ai/tone-detector.d.ts.map +0 -1
  134. package/lib/ai/tone-detector.js +0 -72
  135. package/lib/ai/tone-detector.js.map +0 -1
  136. package/lib/ai/tools.d.ts +0 -45
  137. package/lib/ai/tools.d.ts.map +0 -1
  138. package/lib/ai/tools.js +0 -206
  139. package/lib/ai/tools.js.map +0 -1
  140. package/lib/ai/user-profile.d.ts +0 -56
  141. package/lib/ai/user-profile.d.ts.map +0 -1
  142. package/lib/ai/user-profile.js +0 -130
  143. package/lib/ai/user-profile.js.map +0 -1
  144. package/lib/ai/zhin-agent/builtin-tools.d.ts +0 -17
  145. package/lib/ai/zhin-agent/builtin-tools.d.ts.map +0 -1
  146. package/lib/ai/zhin-agent/builtin-tools.js +0 -220
  147. package/lib/ai/zhin-agent/builtin-tools.js.map +0 -1
  148. package/lib/ai/zhin-agent/config.d.ts +0 -54
  149. package/lib/ai/zhin-agent/config.d.ts.map +0 -1
  150. package/lib/ai/zhin-agent/config.js +0 -76
  151. package/lib/ai/zhin-agent/config.js.map +0 -1
  152. package/lib/ai/zhin-agent/exec-policy.d.ts +0 -20
  153. package/lib/ai/zhin-agent/exec-policy.d.ts.map +0 -1
  154. package/lib/ai/zhin-agent/exec-policy.js +0 -71
  155. package/lib/ai/zhin-agent/exec-policy.js.map +0 -1
  156. package/lib/ai/zhin-agent/index.d.ts +0 -70
  157. package/lib/ai/zhin-agent/index.d.ts.map +0 -1
  158. package/lib/ai/zhin-agent/index.js +0 -404
  159. package/lib/ai/zhin-agent/index.js.map +0 -1
  160. package/lib/ai/zhin-agent/prompt.d.ts +0 -21
  161. package/lib/ai/zhin-agent/prompt.d.ts.map +0 -1
  162. package/lib/ai/zhin-agent/prompt.js +0 -111
  163. package/lib/ai/zhin-agent/prompt.js.map +0 -1
  164. package/lib/ai/zhin-agent/tool-collector.d.ts +0 -22
  165. package/lib/ai/zhin-agent/tool-collector.d.ts.map +0 -1
  166. package/lib/ai/zhin-agent/tool-collector.js +0 -218
  167. package/lib/ai/zhin-agent/tool-collector.js.map +0 -1
  168. package/src/ai/agent.ts +0 -831
  169. package/src/ai/bootstrap.ts +0 -309
  170. package/src/ai/builtin-tools.ts +0 -849
  171. package/src/ai/compaction.ts +0 -529
  172. package/src/ai/context-manager.ts +0 -440
  173. package/src/ai/conversation-memory.ts +0 -774
  174. package/src/ai/cron-engine.ts +0 -337
  175. package/src/ai/follow-up.ts +0 -357
  176. package/src/ai/hooks.ts +0 -223
  177. package/src/ai/init.ts +0 -762
  178. package/src/ai/output.ts +0 -261
  179. package/src/ai/rate-limiter.ts +0 -129
  180. package/src/ai/service.ts +0 -331
  181. package/src/ai/session.ts +0 -544
  182. package/src/ai/subagent.ts +0 -209
  183. package/src/ai/tone-detector.ts +0 -89
  184. package/src/ai/tools.ts +0 -218
  185. package/src/ai/user-profile.ts +0 -181
  186. package/src/ai/zhin-agent/builtin-tools.ts +0 -247
  187. package/src/ai/zhin-agent/config.ts +0 -113
  188. package/src/ai/zhin-agent/exec-policy.ts +0 -78
  189. package/src/ai/zhin-agent/index.ts +0 -512
  190. package/src/ai/zhin-agent/prompt.ts +0 -131
  191. package/src/ai/zhin-agent/tool-collector.ts +0 -243
  192. package/tests/ai/agent.test.ts +0 -614
  193. package/tests/ai/context-manager.test.ts +0 -413
  194. package/tests/ai/conversation-memory.test.ts +0 -128
  195. package/tests/ai/follow-up.test.ts +0 -175
  196. package/tests/ai/integration.test.ts +0 -584
  197. package/tests/ai/output.test.ts +0 -128
  198. package/tests/ai/rate-limiter.test.ts +0 -108
  199. package/tests/ai/session.test.ts +0 -375
  200. package/tests/ai/subagent.test.ts +0 -270
  201. package/tests/ai/tone-detector.test.ts +0 -80
  202. package/tests/ai/tools-builtin.test.ts +0 -346
  203. package/tests/ai/user-profile.test.ts +0 -73
  204. package/tests/ai/zhin-agent.test.ts +0 -177
@@ -1,309 +0,0 @@
1
- /**
2
- * Workspace Bootstrap Files
3
- *
4
- * Injectable prompt files inspired by OpenClaw's workspace bootstrap design:
5
- *
6
- * AGENTS.md — persistent memory / instructions (AI read-write)
7
- * SOUL.md — persona definition (read-only)
8
- * TOOLS.md — tool usage guidelines (read-only)
9
- *
10
- * Key design:
11
- * 1. mtime-based file cache to avoid redundant disk reads
12
- * 2. Missing files are silently skipped
13
- * 3. Per-file and total size limits to prevent prompt injection
14
- * 4. Unified ContextFile format for system prompt injection
15
- */
16
-
17
- import * as fs from 'fs';
18
- import * as path from 'path';
19
- import { Logger } from '@zhin.js/logger';
20
-
21
- const logger = new Logger(null, 'Bootstrap');
22
-
23
- // ============================================================================
24
- // 常量
25
- // ============================================================================
26
-
27
- /** 支持的引导文件名(顺序:SOUL → AGENTS → TOOLS) */
28
- export const BOOTSTRAP_FILENAMES = [
29
- 'SOUL.md',
30
- 'AGENTS.md',
31
- 'TOOLS.md',
32
- ] as const;
33
-
34
- export type BootstrapFileName = typeof BOOTSTRAP_FILENAMES[number];
35
-
36
- /** 单文件最大字符数(默认 16KB) */
37
- const DEFAULT_MAX_CHARS = 16 * 1024;
38
-
39
- /** 所有引导文件总最大字符数(默认 48KB) */
40
- const DEFAULT_TOTAL_MAX_CHARS = 48 * 1024;
41
-
42
- // ============================================================================
43
- // 类型
44
- // ============================================================================
45
-
46
- /** 引导文件信息 */
47
- export interface BootstrapFile {
48
- name: BootstrapFileName;
49
- path: string;
50
- content?: string;
51
- missing: boolean;
52
- }
53
-
54
- /** 上下文文件(用于注入到 system prompt) */
55
- export interface ContextFile {
56
- path: string;
57
- content: string;
58
- }
59
-
60
- // ============================================================================
61
- // 文件缓存(基于 mtime)
62
- // ============================================================================
63
-
64
- const fileCache = new Map<string, { content: string; mtimeMs: number }>();
65
-
66
- /**
67
- * 读文件,带 mtime 缓存
68
- */
69
- async function readFileWithCache(filePath: string): Promise<string> {
70
- try {
71
- const stats = await fs.promises.stat(filePath);
72
- const mtimeMs = stats.mtimeMs;
73
- const cached = fileCache.get(filePath);
74
-
75
- if (cached && cached.mtimeMs === mtimeMs) {
76
- return cached.content;
77
- }
78
-
79
- const content = await fs.promises.readFile(filePath, 'utf-8');
80
- fileCache.set(filePath, { content, mtimeMs });
81
- return content;
82
- } catch {
83
- fileCache.delete(filePath);
84
- throw new Error(`Failed to read file: ${filePath}`);
85
- }
86
- }
87
-
88
- /**
89
- * 清除文件缓存(热重载时调用)
90
- */
91
- export function clearBootstrapCache(): void {
92
- fileCache.clear();
93
- }
94
-
95
- // ============================================================================
96
- // 文件加载
97
- // ============================================================================
98
-
99
- /**
100
- * 获取数据目录
101
- */
102
- function getDataDir(workspaceDir?: string): string {
103
- const cwd = workspaceDir || process.cwd();
104
- return path.join(cwd, 'data');
105
- }
106
-
107
- /**
108
- * 获取文件制长期记忆目录(data/memory),不存在则创建
109
- */
110
- export function getMemoryDir(workspaceDir?: string): string {
111
- const dir = path.join(getDataDir(workspaceDir), 'memory');
112
- if (!fs.existsSync(dir)) {
113
- fs.mkdirSync(dir, { recursive: true });
114
- }
115
- return dir;
116
- }
117
-
118
- function todayDate(): string {
119
- return new Date().toISOString().split('T')[0];
120
- }
121
-
122
- /**
123
- * 读取文件制长期记忆 + 当日笔记,拼成注入 system prompt 的字符串(与 miniclawd 一致)
124
- * 同步读取,供 buildRichSystemPrompt 等同步调用
125
- */
126
- export function getFileMemoryContext(workspaceDir?: string): string {
127
- const memoryDir = getMemoryDir(workspaceDir);
128
- const parts: string[] = [];
129
-
130
- const memoryFile = path.join(memoryDir, 'MEMORY.md');
131
- if (fs.existsSync(memoryFile)) {
132
- try {
133
- const longTerm = fs.readFileSync(memoryFile, 'utf-8').trim();
134
- if (longTerm) parts.push('## Long-term Memory\n' + longTerm);
135
- } catch {
136
- // ignore read errors
137
- }
138
- }
139
-
140
- const todayFile = path.join(memoryDir, `${todayDate()}.md`);
141
- if (fs.existsSync(todayFile)) {
142
- try {
143
- const today = fs.readFileSync(todayFile, 'utf-8').trim();
144
- if (today) parts.push("## Today's Notes\n" + today);
145
- } catch {
146
- // ignore read errors
147
- }
148
- }
149
-
150
- return parts.length > 0 ? parts.join('\n\n') : '';
151
- }
152
-
153
- /**
154
- * 加载工作区引导文件
155
- *
156
- * 搜索顺序:项目根目录 → data/ 目录
157
- */
158
- export async function loadBootstrapFiles(
159
- workspaceDir?: string,
160
- ): Promise<BootstrapFile[]> {
161
- const cwd = workspaceDir || process.cwd();
162
- const dataDir = getDataDir(cwd);
163
-
164
- const result: BootstrapFile[] = [];
165
-
166
- for (const name of BOOTSTRAP_FILENAMES) {
167
- // 优先项目根目录
168
- const rootPath = path.join(cwd, name);
169
- const dataPath = path.join(dataDir, name);
170
-
171
- let found = false;
172
- for (const filePath of [rootPath, dataPath]) {
173
- try {
174
- const content = await readFileWithCache(filePath);
175
- result.push({ name, path: filePath, content, missing: false });
176
- found = true;
177
- break; // 找到就不再搜索
178
- } catch {
179
- // 继续尝试下一个路径
180
- }
181
- }
182
-
183
- if (!found) {
184
- result.push({ name, path: rootPath, missing: true });
185
- }
186
- }
187
-
188
- return result;
189
- }
190
-
191
- /**
192
- * 将引导文件转为上下文文件列表(用于注入到 system prompt)
193
- *
194
- * 自动裁剪超长内容,跳过缺失文件
195
- */
196
- export function buildContextFiles(
197
- bootstrapFiles: BootstrapFile[],
198
- options?: {
199
- maxChars?: number;
200
- totalMaxChars?: number;
201
- },
202
- ): ContextFile[] {
203
- const maxChars = options?.maxChars ?? DEFAULT_MAX_CHARS;
204
- const totalMaxChars = options?.totalMaxChars ?? DEFAULT_TOTAL_MAX_CHARS;
205
-
206
- const contextFiles: ContextFile[] = [];
207
- let totalChars = 0;
208
-
209
- for (const file of bootstrapFiles) {
210
- if (file.missing || !file.content) continue;
211
-
212
- let content = file.content.trim();
213
- if (!content) continue;
214
-
215
- // 单文件裁剪
216
- if (content.length > maxChars) {
217
- content = content.slice(0, maxChars) + '\n...(truncated)';
218
- logger.warn(`Bootstrap file ${file.name} exceeds ${maxChars} chars, truncated`);
219
- }
220
-
221
- // 总量限制
222
- if (totalChars + content.length > totalMaxChars) {
223
- logger.warn(`Bootstrap total exceeds ${totalMaxChars} chars, skipping ${file.name}`);
224
- break;
225
- }
226
-
227
- contextFiles.push({ path: file.name, content });
228
- totalChars += content.length;
229
- }
230
-
231
- return contextFiles;
232
- }
233
-
234
- /**
235
- * 加载 SOUL.md 人格定义
236
- */
237
- export async function loadSoulPersona(workspaceDir?: string): Promise<string | null> {
238
- const files = await loadBootstrapFiles(workspaceDir);
239
- const soulFile = files.find(f => f.name === 'SOUL.md' && !f.missing);
240
- return soulFile?.content?.trim() || null;
241
- }
242
-
243
- /**
244
- * 加载 TOOLS.md 工具使用指引
245
- */
246
- export async function loadToolsGuide(workspaceDir?: string): Promise<string | null> {
247
- const files = await loadBootstrapFiles(workspaceDir);
248
- const toolsFile = files.find(f => f.name === 'TOOLS.md' && !f.missing);
249
- return toolsFile?.content?.trim() || null;
250
- }
251
-
252
- /**
253
- * 加载 AGENTS.md 持久化记忆
254
- */
255
- export async function loadAgentsMemory(workspaceDir?: string): Promise<string | null> {
256
- const files = await loadBootstrapFiles(workspaceDir);
257
- const agentsFile = files.find(f => f.name === 'AGENTS.md' && !f.missing);
258
- return agentsFile?.content?.trim() || null;
259
- }
260
-
261
- // ============================================================================
262
- // System Prompt 构建帮助函数
263
- // ============================================================================
264
-
265
- /**
266
- * 构建引导文件上下文段(注入到 system prompt 末尾)
267
- *
268
- * 格式与 OpenClaw 一致:
269
- * ```
270
- * # Project Context
271
- *
272
- * The following project context files have been loaded:
273
- * If SOUL.md is present, embody its persona and tone.
274
- *
275
- * ## SOUL.md
276
- *
277
- * <content>
278
- *
279
- * ## TOOLS.md
280
- *
281
- * <content>
282
- * ```
283
- */
284
- export function buildBootstrapContextSection(contextFiles: ContextFile[]): string {
285
- if (contextFiles.length === 0) return '';
286
-
287
- const hasSoul = contextFiles.some(f =>
288
- f.path.toLowerCase().endsWith('soul.md'),
289
- );
290
-
291
- const lines: string[] = [
292
- '# Project Context',
293
- '',
294
- 'The following project context files have been loaded:',
295
- ];
296
-
297
- if (hasSoul) {
298
- lines.push(
299
- 'If SOUL.md is present, embody its persona and tone. Avoid generic responses.',
300
- );
301
- }
302
- lines.push('');
303
-
304
- for (const file of contextFiles) {
305
- lines.push(`## ${file.path}`, '', file.content, '');
306
- }
307
-
308
- return lines.join('\n');
309
- }