@gt-fe/eap-runtime 0.0.30 → 0.0.32

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 (41) hide show
  1. package/dist/api/handlers/invoke.handler.js +9 -5
  2. package/dist/api/handlers/stream.handler.js +15 -4
  3. package/dist/common/index.d.ts +1 -0
  4. package/dist/common/index.js +1 -0
  5. package/dist/common/user-root.d.ts +8 -0
  6. package/dist/common/user-root.js +19 -0
  7. package/dist/graph/adapters/langgraph.adapter.js +57 -10
  8. package/dist/graph/adapters/skill-entry-span.d.ts +4 -2
  9. package/dist/graph/adapters/skill-entry-span.js +10 -3
  10. package/dist/graph/adapters/skill-read.d.ts +18 -2
  11. package/dist/graph/adapters/skill-read.js +66 -31
  12. package/dist/graph/contracts/executable-graph.d.ts +7 -1
  13. package/dist/graph/nodes/tool-node.d.ts +6 -1
  14. package/dist/graph/nodes/tool-node.js +18 -3
  15. package/dist/registry/deployment-snapshot.d.ts +1 -1
  16. package/dist/registry/deployment-snapshot.js +6 -3
  17. package/dist/registry/skill-tree.d.ts +1 -1
  18. package/dist/registry/skill-tree.js +11 -6
  19. package/dist/runtime/agent-runtime.js +36 -5
  20. package/dist/session/persist-turn-messages.d.ts +13 -6
  21. package/dist/session/persist-turn-messages.js +4 -0
  22. package/dist/sse/events/tool-events.d.ts +29 -0
  23. package/dist/tool/harness-command.d.ts +1 -1
  24. package/dist/tool/harness-command.js +8 -7
  25. package/dist/tool/harness-primitives.d.ts +4 -10
  26. package/dist/tool/harness-primitives.js +189 -130
  27. package/dist/tool/index.d.ts +2 -0
  28. package/dist/tool/index.js +2 -0
  29. package/dist/tool/inject-public-artifact-links.d.ts +32 -0
  30. package/dist/tool/inject-public-artifact-links.js +142 -0
  31. package/dist/tool/skill-relative-read.d.ts +14 -0
  32. package/dist/tool/skill-relative-read.js +98 -0
  33. package/dist/tool/static-artifact-url.d.ts +66 -0
  34. package/dist/tool/static-artifact-url.js +561 -0
  35. package/dist/tool/system-prompt-builder.js +8 -4
  36. package/dist/tool/tool-event-emitter.d.ts +2 -1
  37. package/dist/tool/tool-event-emitter.js +30 -18
  38. package/dist/tool/tool-executor.interface.d.ts +13 -1
  39. package/dist/tool/tool-result-injector.d.ts +3 -3
  40. package/dist/tool/tool-result-injector.js +7 -3
  41. package/package.json +2 -2
@@ -0,0 +1,14 @@
1
+ export declare function userReadBase(workdir: string | undefined): string | undefined;
2
+ /**
3
+ * 相对 read_file:`技能名/文件`、全库唯一命中、显式 skillDir,否则用户目录。
4
+ */
5
+ export declare function locateSkillRelativeRead(filePath: string, workdir: string | undefined, skillDir: string | undefined, extraRoots?: string[]): {
6
+ path: string;
7
+ relativeBase: string | undefined;
8
+ };
9
+ /** 定位符落到实际文件:绝对路径原样;相对路径按 locateSkillRelativeRead 的包根拼接。 */
10
+ export declare function resolveSkillReadTarget(filePath: string, opts?: {
11
+ workdir?: string;
12
+ skillDir?: string;
13
+ extraRoots?: string[];
14
+ }): string;
@@ -0,0 +1,98 @@
1
+ /**
2
+ * read_file 相对路径如何落到技能包:Harness 读文件与 Trace 判定入口共用。
3
+ */
4
+ import { existsSync, readdirSync, realpathSync } from 'node:fs';
5
+ import path from 'node:path';
6
+ function tryRealpath(p) {
7
+ try {
8
+ return realpathSync(p);
9
+ }
10
+ catch {
11
+ return undefined;
12
+ }
13
+ }
14
+ export function userReadBase(workdir) {
15
+ return workdir?.trim()
16
+ ? (tryRealpath(path.resolve(workdir)) ?? path.resolve(workdir))
17
+ : undefined;
18
+ }
19
+ function isSkillPackageDir(dir) {
20
+ return existsSync(path.join(dir, 'SKILL.md')) || existsSync(path.join(dir, 'skill.md'));
21
+ }
22
+ function skillPackageRoots(roots) {
23
+ const out = [];
24
+ const seen = new Set();
25
+ const add = (dir) => {
26
+ if (seen.has(dir))
27
+ return;
28
+ seen.add(dir);
29
+ out.push(dir);
30
+ };
31
+ for (const root of roots) {
32
+ const resolved = path.resolve(root);
33
+ if (isSkillPackageDir(resolved)) {
34
+ add(resolved);
35
+ continue;
36
+ }
37
+ let entries;
38
+ try {
39
+ entries = readdirSync(resolved, { withFileTypes: true });
40
+ }
41
+ catch {
42
+ continue;
43
+ }
44
+ for (const ent of entries) {
45
+ if (!ent.isDirectory())
46
+ continue;
47
+ const child = path.join(resolved, ent.name);
48
+ if (isSkillPackageDir(child))
49
+ add(child);
50
+ }
51
+ }
52
+ return out;
53
+ }
54
+ /**
55
+ * 相对 read_file:`技能名/文件`、全库唯一命中、显式 skillDir,否则用户目录。
56
+ */
57
+ export function locateSkillRelativeRead(filePath, workdir, skillDir, extraRoots) {
58
+ const trimmed = filePath.trim();
59
+ const userBase = userReadBase(workdir);
60
+ if (!trimmed || path.isAbsolute(trimmed))
61
+ return { path: trimmed, relativeBase: userBase };
62
+ const packages = skillPackageRoots([
63
+ ...(skillDir?.trim() ? [skillDir] : []),
64
+ ...(extraRoots ?? []),
65
+ ]);
66
+ const slash = trimmed.replace(/\\/g, '/');
67
+ const segs = slash.split('/').filter(Boolean);
68
+ if (segs.length >= 2) {
69
+ const hit = packages.find((pkg) => path.basename(pkg) === segs[0]);
70
+ if (hit)
71
+ return { path: segs.slice(1).join('/'), relativeBase: hit };
72
+ }
73
+ const matches = packages.filter((pkg) => existsSync(path.resolve(pkg, trimmed)));
74
+ if (matches.length === 1)
75
+ return { path: trimmed, relativeBase: matches[0] };
76
+ const skillBase = skillDir?.trim() ? path.resolve(skillDir) : undefined;
77
+ if (skillBase && existsSync(path.resolve(skillBase, trimmed))) {
78
+ return { path: trimmed, relativeBase: skillBase };
79
+ }
80
+ return { path: trimmed, relativeBase: userBase };
81
+ }
82
+ /** 定位符落到实际文件:绝对路径原样;相对路径按 locateSkillRelativeRead 的包根拼接。 */
83
+ export function resolveSkillReadTarget(filePath, opts) {
84
+ const trimmed = filePath.trim();
85
+ if (!trimmed)
86
+ return '';
87
+ const located = locateSkillRelativeRead(trimmed, opts?.workdir, opts?.skillDir, opts?.extraRoots);
88
+ if (path.isAbsolute(trimmed)) {
89
+ const resolved = path.resolve(trimmed);
90
+ return (tryRealpath(resolved) ?? resolved).replace(/\\/g, '/').replace(/\/+$/, '');
91
+ }
92
+ if (located.relativeBase) {
93
+ const resolved = path.resolve(located.relativeBase, located.path);
94
+ return (tryRealpath(resolved) ?? resolved).replace(/\\/g, '/').replace(/\/+$/, '');
95
+ }
96
+ const resolved = path.resolve(trimmed);
97
+ return (tryRealpath(resolved) ?? resolved).replace(/\\/g, '/').replace(/\/+$/, '');
98
+ }
@@ -0,0 +1,66 @@
1
+ /**
2
+ * 用户产物公开副本:files/ 工作稿 → public/ 时间戳 copy;拼 Hosting /static url。
3
+ * @see docs/design/user-artifact-delivery.md
4
+ */
5
+ /** 与 contracts `DEFAULT_BUILTIN_MAX_WRITE_BYTES` 同值;本地编译不依赖未发版 contracts */
6
+ export declare const DEFAULT_MAX_WRITE_BYTES: number;
7
+ export declare const PUBLIC_DIR_MODE = 493;
8
+ export declare const PUBLIC_FILE_MODE = 420;
9
+ export declare const MAX_SNAPSHOT_ENUM = 5000;
10
+ export declare const MAX_SNAPSHOT_URLS = 20;
11
+ export declare const MAX_PUBLIC_NAME_ATTEMPTS = 8;
12
+ export declare const PUBLIC_EXTENSIONS: Set<string>;
13
+ export type ArtifactEnv = NodeJS.ProcessEnv | Record<string, string | undefined>;
14
+ export type PublishedArtifact = {
15
+ fileName: string;
16
+ fileType: string;
17
+ size: number;
18
+ url?: string;
19
+ absPath: string;
20
+ /** 工作稿相对 `files/` 的路径 */
21
+ sourceRel?: string;
22
+ };
23
+ export declare function staticBaseUrlFromEnv(env?: ArtifactEnv): string | undefined;
24
+ export declare function preinstallRootFromEnv(env?: ArtifactEnv): string | undefined;
25
+ export declare function encodePublicRel(rel: string): string;
26
+ export declare function isPublicUserArtifactRel(rel: string): boolean;
27
+ export declare function publicArtifactUrl(absPath: string, env?: ArtifactEnv): string | undefined;
28
+ export declare function publicTimeSuffix(now?: Date, withMs?: boolean): string;
29
+ export declare function stripPublicSuffix(name: string): string;
30
+ export declare function extensionOf(name: string): string;
31
+ export declare function isPublicExtension(name: string): boolean;
32
+ export declare function isSnapshotJunkName(name: string): boolean;
33
+ export declare function mkdirChmod(dir: string, mode?: number): Promise<void>;
34
+ /** 四槽 `skills/` `work/` `files/` `public/`,目录 0755(与 Hosting `ensureUserWorkspace` 对齐)。 */
35
+ export declare function ensureUserSlots(userDir: string): Promise<{
36
+ filesDir: string;
37
+ workDir: string;
38
+ publicDir: string;
39
+ skillsDir: string;
40
+ }>;
41
+ export declare function allocPublicBasename(publicDir: string, srcFile: string, originalBasename: string): Promise<string | undefined>;
42
+ export declare function allocPublicDir(publicDir: string, srcDir: string, originalDirName: string): Promise<string | undefined>;
43
+ export declare function publishFromFiles(userDir: string, relFromFiles: string[], env?: ArtifactEnv): Promise<PublishedArtifact[]>;
44
+ export type FilesWalkEntry = {
45
+ rel: string;
46
+ size: number;
47
+ mtimeMs: number;
48
+ ctimeMs: number;
49
+ };
50
+ export declare function walkFilesTree(filesDir: string): Promise<{
51
+ entries: Map<string, FilesWalkEntry>;
52
+ truncated: boolean;
53
+ }>;
54
+ export declare function snapshotCandidates(before: Map<string, FilesWalkEntry>, after: Map<string, FilesWalkEntry>, maxWriteBytes?: number): {
55
+ rels: string[];
56
+ skippedOversize: number;
57
+ };
58
+ export type UserProductSlot = 'files' | 'skills';
59
+ export type ResolvedUserProductPath = {
60
+ abs: string;
61
+ jsonPath: string;
62
+ slot: UserProductSlot;
63
+ relFromFiles?: string;
64
+ };
65
+ export declare function resolveUserProductPath(requested: string, userDir: string, kind: 'write' | 'cwd' | 'read'): ResolvedUserProductPath;
66
+ export declare function maxWriteBytesFromEnv(env?: ArtifactEnv): number;