@gt-fe/eap-runtime 0.0.30 → 0.0.31

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 (36) 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 +30 -3
  8. package/dist/graph/adapters/skill-read.js +13 -4
  9. package/dist/graph/contracts/executable-graph.d.ts +7 -1
  10. package/dist/graph/nodes/tool-node.d.ts +4 -1
  11. package/dist/graph/nodes/tool-node.js +15 -1
  12. package/dist/registry/deployment-snapshot.d.ts +1 -1
  13. package/dist/registry/deployment-snapshot.js +6 -3
  14. package/dist/registry/skill-tree.d.ts +1 -1
  15. package/dist/registry/skill-tree.js +11 -6
  16. package/dist/runtime/agent-runtime.js +36 -5
  17. package/dist/session/persist-turn-messages.d.ts +13 -6
  18. package/dist/session/persist-turn-messages.js +4 -0
  19. package/dist/sse/events/tool-events.d.ts +29 -0
  20. package/dist/tool/harness-command.d.ts +1 -1
  21. package/dist/tool/harness-command.js +8 -7
  22. package/dist/tool/harness-primitives.d.ts +3 -3
  23. package/dist/tool/harness-primitives.js +185 -60
  24. package/dist/tool/index.d.ts +2 -0
  25. package/dist/tool/index.js +2 -0
  26. package/dist/tool/inject-public-artifact-links.d.ts +32 -0
  27. package/dist/tool/inject-public-artifact-links.js +142 -0
  28. package/dist/tool/static-artifact-url.d.ts +66 -0
  29. package/dist/tool/static-artifact-url.js +561 -0
  30. package/dist/tool/system-prompt-builder.js +8 -4
  31. package/dist/tool/tool-event-emitter.d.ts +2 -1
  32. package/dist/tool/tool-event-emitter.js +30 -18
  33. package/dist/tool/tool-executor.interface.d.ts +8 -1
  34. package/dist/tool/tool-result-injector.d.ts +3 -3
  35. package/dist/tool/tool-result-injector.js +7 -3
  36. package/package.json +2 -2
@@ -0,0 +1,142 @@
1
+ /**
2
+ * 本轮带 url 的公开副本 → 助手正文末尾 GFM 链接。
3
+ * stream / streamResumeHitl / stream.handler / invoke.handler 共用。
4
+ */
5
+ function escapeMdLinkText(text) {
6
+ return text.replace(/\\/g, '\\\\').replace(/([\[\]()])/g, '\\$1');
7
+ }
8
+ function addLink(out, seen, fileName, url) {
9
+ const href = url.trim();
10
+ if (!href || seen.has(href))
11
+ return;
12
+ seen.add(href);
13
+ out.push({ fileName: fileName.trim() || href, url: href });
14
+ }
15
+ function parseContentLinks(content, out, seen) {
16
+ if (typeof content !== 'string' || !content.trim())
17
+ return;
18
+ const first = content.split('\n', 1)[0] ?? '';
19
+ try {
20
+ const parsed = JSON.parse(first);
21
+ if (Array.isArray(parsed.publicFiles)) {
22
+ for (const item of parsed.publicFiles) {
23
+ if (!item || typeof item !== 'object')
24
+ continue;
25
+ const row = item;
26
+ if (typeof row.url === 'string') {
27
+ const name = (typeof row.fileName === 'string' && row.fileName) ||
28
+ (typeof row.path === 'string' && row.path) ||
29
+ 'file';
30
+ addLink(out, seen, name, row.url);
31
+ }
32
+ }
33
+ return;
34
+ }
35
+ if (parsed.ok === true && typeof parsed.url === 'string') {
36
+ const name = typeof parsed.path === 'string' ? parsed.path : 'file';
37
+ addLink(out, seen, name, parsed.url);
38
+ }
39
+ }
40
+ catch {
41
+ // 非 JSON 行忽略
42
+ }
43
+ }
44
+ export function mergeArtifactLinks(...groups) {
45
+ const out = [];
46
+ const seen = new Set();
47
+ for (const group of groups) {
48
+ for (const item of group)
49
+ addLink(out, seen, item.fileName, item.url);
50
+ }
51
+ return out;
52
+ }
53
+ export function collectPublicArtifactLinks(results) {
54
+ const out = [];
55
+ const seen = new Set();
56
+ for (const result of results) {
57
+ if (result.file?.url) {
58
+ addLink(out, seen, result.file.fileName ?? result.file.url, result.file.url);
59
+ }
60
+ for (const f of result.files ?? []) {
61
+ if (f?.url)
62
+ addLink(out, seen, f.fileName ?? f.url, f.url);
63
+ }
64
+ parseContentLinks(result.content, out, seen);
65
+ }
66
+ return out;
67
+ }
68
+ export function collectPublicArtifactLinksFromEvent(eventType, payload, bucket) {
69
+ if (!payload || typeof payload !== 'object')
70
+ return;
71
+ const p = payload;
72
+ const seen = new Set(bucket.map((l) => l.url));
73
+ if (eventType === 'file.created' && typeof p.url === 'string') {
74
+ addLink(bucket, seen, typeof p.fileName === 'string' ? p.fileName : p.url, p.url);
75
+ return;
76
+ }
77
+ if (eventType === 'tool.result' || eventType === 'tool.error') {
78
+ const extra = collectPublicArtifactLinks([
79
+ { content: p.content, file: p.file, files: p.files },
80
+ ]);
81
+ for (const link of extra)
82
+ addLink(bucket, seen, link.fileName, link.url);
83
+ }
84
+ }
85
+ export function toolResultHasArtifacts(result) {
86
+ if (result.file?.url)
87
+ return true;
88
+ if ((result.files ?? []).some((f) => Boolean(f?.url)))
89
+ return true;
90
+ if (typeof result.content !== 'string' || !result.content.trim())
91
+ return false;
92
+ const first = result.content.split('\n', 1)[0] ?? '';
93
+ try {
94
+ const parsed = JSON.parse(first);
95
+ if (Array.isArray(parsed.publicFiles) && parsed.publicFiles.length > 0)
96
+ return true;
97
+ if (parsed.ok === true && typeof parsed.url === 'string' && parsed.url)
98
+ return true;
99
+ }
100
+ catch {
101
+ return false;
102
+ }
103
+ return false;
104
+ }
105
+ export function applyInjectedAssistant(messages, injected, links) {
106
+ if (!injected || links.length === 0)
107
+ return messages;
108
+ let idx = -1;
109
+ for (let i = messages.length - 1; i >= 0; i--) {
110
+ const m = messages[i];
111
+ if (m.role !== 'assistant')
112
+ continue;
113
+ if (!m.content.trim())
114
+ continue;
115
+ idx = i;
116
+ break;
117
+ }
118
+ if (idx >= 0) {
119
+ const copy = messages.slice();
120
+ copy[idx] = { ...copy[idx], content: injected };
121
+ return copy;
122
+ }
123
+ return [...messages, { role: 'assistant', content: injected }];
124
+ }
125
+ export function injectPublicArtifactLinks(visibleText, artifacts) {
126
+ const seen = new Set();
127
+ const lines = [];
128
+ for (const item of artifacts) {
129
+ const url = item.url.trim();
130
+ if (!url || seen.has(url))
131
+ continue;
132
+ seen.add(url);
133
+ if (visibleText.includes(url))
134
+ continue;
135
+ lines.push(`[${escapeMdLinkText(item.fileName)}](${url})`);
136
+ }
137
+ if (lines.length === 0)
138
+ return { injected: visibleText, suffix: '' };
139
+ const block = lines.join('\n');
140
+ const suffix = visibleText ? `\n\n${block}` : block;
141
+ return { injected: `${visibleText}${suffix}`, suffix };
142
+ }
@@ -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;