@gt-fe/eap-runtime 0.0.25 → 0.0.27

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.
@@ -28,7 +28,7 @@ export interface SnapshotSkillRef {
28
28
  name?: string;
29
29
  version?: string;
30
30
  description?: string;
31
- /** 可选:对应 skill 清单文件内容 sha256 */
31
+ /** 可选;Runtime 加载不比对。完整性由 Agent 包 / Hosting 预装负责 */
32
32
  sha256?: string;
33
33
  }
34
34
  export interface AgentSnapshotMeta {
@@ -583,15 +583,6 @@ export class FileSystemDeploymentSnapshot {
583
583
  }
584
584
  if (!manifest || !manifestPath)
585
585
  continue;
586
- const isUserOverridePath = bundlePath.includes('/users/') || bundlePath.includes('\\users\\');
587
- const isAuthorOverlay = extraRoots.some((root) => root && isPathInside(root, bundlePath));
588
- if (ref.sha256 &&
589
- !isUserOverridePath &&
590
- !isAuthorOverlay &&
591
- manifestPath.endsWith('.json')) {
592
- const actual = await sha256OfFile(manifestPath);
593
- await warnIfDigestMismatch(ref.sha256, actual, `skill ${ref.skillId}`, { path: manifestPath }, this.flags.requireChecksum || isRequireChecksum());
594
- }
595
586
  const skillId = String(ref.skillId);
596
587
  return {
597
588
  skillId,
@@ -34,16 +34,29 @@ function harnessDefinitions() {
34
34
  manifest: {
35
35
  id: 'builtin:read_file',
36
36
  name: 'read_file',
37
- description: '读取当前用户目录或预装 tools/skills 内的文本。要用某个技能时读该技能文件夹下的 SKILL.md。超限会截断并注明。',
37
+ description: '读取文本文件,成功时工具结果就是文件正文(纯文本,不是 JSON)。可读当前用户目录或预装 tools/skills;要用技能时读该技能目录下的 SKILL.md。大文件先整段读,若被截断(正文末尾会注明 truncated),再用 offset/limit 分段。路径越权或文件不存在会失败。不要用来读图/PDF 等二进制。写文件请用 write_file 或 append_to_file。',
38
38
  ...common,
39
39
  },
40
40
  inputSchema: {
41
41
  type: 'object',
42
+ additionalProperties: false,
42
43
  required: ['path'],
43
44
  properties: {
44
- path: { type: 'string', description: '相对工作目录或技能根的路径' },
45
- offset: { type: 'integer', description: '从第几行开始读,从 1 起。省略则从头。' },
46
- limit: { type: 'integer', description: '最多读多少行。省略则读到末尾或字节上限。' },
45
+ path: {
46
+ type: 'string',
47
+ minLength: 1,
48
+ description: '相对路径,例如 notes/todo.md 或 some-skill/SKILL.md。不能用 .. 跳出允许目录。',
49
+ },
50
+ offset: {
51
+ type: 'integer',
52
+ minimum: 1,
53
+ description: '从第几行开始读,从 1 起。省略则从头。只在大文件分段时用。',
54
+ },
55
+ limit: {
56
+ type: 'integer',
57
+ minimum: 1,
58
+ description: '最多读多少行。省略则读到末尾或字节上限。只在大文件分段时用。',
59
+ },
47
60
  },
48
61
  },
49
62
  },
@@ -53,15 +66,49 @@ function harnessDefinitions() {
53
66
  manifest: {
54
67
  id: 'builtin:write_file',
55
68
  name: 'write_file',
56
- description: '写入当前用户目录(含用户自己的 skills)。预装 tools / skills 只读。',
69
+ description: '把文本整份写入当前用户目录(含用户自己的 skills)。没有该文件则创建;已有文件会整份换成 content,不是改某一行。只要在末尾加内容请用 append_to_file。不能写预装 tools/skills,不能写 .assembly.json 等平台文件。成功时工具结果是 JSON:{"ok":true,"path":"相对用户目录的路径","bytesWritten":字节数}。路径越权或禁写文件名会失败。',
57
70
  ...common,
58
71
  },
59
72
  inputSchema: {
60
73
  type: 'object',
74
+ additionalProperties: false,
61
75
  required: ['path', 'content'],
62
76
  properties: {
63
- path: { type: 'string' },
64
- content: { type: 'string' },
77
+ path: {
78
+ type: 'string',
79
+ minLength: 1,
80
+ description: '相对当前用户目录的路径,例如 notes/todo.md。不能写预装 tools/skills。',
81
+ },
82
+ content: {
83
+ type: 'string',
84
+ description: '文件的完整新内容。会覆盖原文件全部内容。',
85
+ },
86
+ },
87
+ },
88
+ },
89
+ {
90
+ toolId: 'builtin:append_to_file',
91
+ name: 'append_to_file',
92
+ manifest: {
93
+ id: 'builtin:append_to_file',
94
+ name: 'append_to_file',
95
+ description: '在当前用户目录的文件末尾追加文本,不覆盖已有内容。没有该文件则创建。不要用它整份改写文件,那是 write_file。不能写预装 tools/skills,不能写 .assembly.json 等平台文件。成功时工具结果是 JSON:{"ok":true,"path":"相对用户目录的路径","bytesWritten":本次追加字节数}。路径越权或禁写文件名会失败。',
96
+ ...common,
97
+ },
98
+ inputSchema: {
99
+ type: 'object',
100
+ additionalProperties: false,
101
+ required: ['path', 'content'],
102
+ properties: {
103
+ path: {
104
+ type: 'string',
105
+ minLength: 1,
106
+ description: '相对当前用户目录的路径,例如 notes/todo.md。不能写预装 tools/skills。',
107
+ },
108
+ content: {
109
+ type: 'string',
110
+ description: '接到文件末尾的文本。不会删除或替换原有内容。',
111
+ },
65
112
  },
66
113
  },
67
114
  },
@@ -199,10 +246,10 @@ export function resolveJailRoots(options) {
199
246
  }
200
247
  return roots;
201
248
  }
202
- async function writeFileNoFollow(target, content) {
249
+ async function writeFileNoFollow(target, content, append = false) {
203
250
  const flags = fsConstants.O_WRONLY |
204
251
  fsConstants.O_CREAT |
205
- fsConstants.O_TRUNC |
252
+ (append ? fsConstants.O_APPEND : fsConstants.O_TRUNC) |
206
253
  (fsConstants.O_NOFOLLOW ?? 0);
207
254
  let handle;
208
255
  try {
@@ -216,7 +263,8 @@ async function writeFileNoFollow(target, content) {
216
263
  throw err;
217
264
  }
218
265
  try {
219
- await handle.writeFile(content, 'utf8');
266
+ const { bytesWritten } = await handle.write(content, undefined, 'utf8');
267
+ return bytesWritten;
220
268
  }
221
269
  finally {
222
270
  await handle.close();
@@ -408,7 +456,9 @@ export class HarnessPrimitiveExecutor {
408
456
  case 'read_file':
409
457
  return await this.readFile(request);
410
458
  case 'write_file':
411
- return await this.writeFile(request);
459
+ return await this.writeFile(request, false);
460
+ case 'append_to_file':
461
+ return await this.writeFile(request, true);
412
462
  case 'execute_command':
413
463
  return await this.executeCommand(request);
414
464
  default:
@@ -420,7 +470,7 @@ export class HarnessPrimitiveExecutor {
420
470
  }
421
471
  }
422
472
  async readFile(request) {
423
- const filePath = String(request.arguments.path ?? request.arguments.file ?? '');
473
+ const filePath = String(request.arguments.path ?? '');
424
474
  const workdir = this.workdirFor(request);
425
475
  const located = locateSkillRelativeRead(filePath, workdir, request.skillDir, this.extraRootsFor(request));
426
476
  const target = resolveJailedPath(located.path, this.rootsFor(request), {
@@ -459,7 +509,7 @@ export class HarnessPrimitiveExecutor {
459
509
  }
460
510
  return ok(request, text);
461
511
  }
462
- async writeFile(request) {
512
+ async writeFile(request, append) {
463
513
  const filePath = String(request.arguments.path ?? '');
464
514
  const content = String(request.arguments.content ?? '');
465
515
  const workdir = this.requireWorkdir(request);
@@ -474,8 +524,8 @@ export class HarnessPrimitiveExecutor {
474
524
  if (PROTECTED_WRITE_NAMES.has(path.basename(recast))) {
475
525
  throw new Error(`禁止写入平台文件:${path.basename(recast)}`);
476
526
  }
477
- await writeFileNoFollow(recast, content);
478
- return ok(request, JSON.stringify({ ok: true, path: path.relative(workdir, recast) }));
527
+ const bytesWritten = await writeFileNoFollow(recast, content, append);
528
+ return ok(request, JSON.stringify({ ok: true, path: path.relative(workdir, recast), bytesWritten }));
479
529
  }
480
530
  async executeCommand(request) {
481
531
  const command = substituteSkillDir(String(request.arguments.command ?? '').trim(), request.skillDir);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gt-fe/eap-runtime",
3
- "version": "0.0.25",
3
+ "version": "0.0.27",
4
4
  "description": "Enterprise Agent Platform — Runtime核心:Graph执行引擎、Task生命周期、Session管理、Checkpoint持久化",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -20,7 +20,7 @@
20
20
  "ioredis": "^5.4.0",
21
21
  "pg": "^8.13.0",
22
22
  "yaml": "^2.6.1",
23
- "@gt-fe/eap-contracts": "0.0.14"
23
+ "@gt-fe/eap-contracts": "0.0.15"
24
24
  },
25
25
  "publishConfig": {
26
26
  "registry": "https://registry.npmjs.org/",