@yefengr/pi-reach 0.0.5 → 0.0.7

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 (53) hide show
  1. package/dist/attachments/safe-files.d.ts +10 -0
  2. package/dist/attachments/safe-files.js +44 -2
  3. package/dist/attachments/safe-files.js.map +1 -1
  4. package/dist/attachments/storage-path.d.ts +4 -0
  5. package/dist/attachments/storage-path.js +47 -0
  6. package/dist/attachments/storage-path.js.map +1 -0
  7. package/dist/attachments/store.js +23 -5
  8. package/dist/attachments/store.js.map +1 -1
  9. package/dist/files/content-type.d.ts +16 -0
  10. package/dist/files/content-type.js +98 -0
  11. package/dist/files/content-type.js.map +1 -0
  12. package/dist/files/image-structure.d.ts +21 -0
  13. package/dist/files/image-structure.js +269 -0
  14. package/dist/files/image-structure.js.map +1 -0
  15. package/dist/files/publications.d.ts +26 -0
  16. package/dist/files/publications.js +136 -0
  17. package/dist/files/publications.js.map +1 -0
  18. package/dist/files/publish-tool.d.ts +23 -0
  19. package/dist/files/publish-tool.js +70 -0
  20. package/dist/files/publish-tool.js.map +1 -0
  21. package/dist/files/reader.d.ts +66 -0
  22. package/dist/files/reader.js +416 -0
  23. package/dist/files/reader.js.map +1 -0
  24. package/dist/files/safe-open.d.ts +22 -0
  25. package/dist/files/safe-open.js +119 -0
  26. package/dist/files/safe-open.js.map +1 -0
  27. package/dist/index.js +12 -17
  28. package/dist/index.js.map +1 -1
  29. package/dist/runtime/file_binding.d.ts +25 -0
  30. package/dist/runtime/file_binding.js +49 -0
  31. package/dist/runtime/file_binding.js.map +1 -0
  32. package/dist/runtime/session_frame_router.d.ts +11 -0
  33. package/dist/runtime/session_frame_router.js +25 -0
  34. package/dist/runtime/session_frame_router.js.map +1 -0
  35. package/dist/timeline/runtime.d.ts +1 -1
  36. package/dist/timeline/runtime.js +26 -54
  37. package/dist/timeline/runtime.js.map +1 -1
  38. package/dist/timeline/system_event.d.ts +7 -0
  39. package/dist/timeline/system_event.js +58 -0
  40. package/dist/timeline/system_event.js.map +1 -0
  41. package/dist/timeline/tool_lifecycle.js +8 -2
  42. package/dist/timeline/tool_lifecycle.js.map +1 -1
  43. package/dist/timeline/v2_service.js +3 -0
  44. package/dist/timeline/v2_service.js.map +1 -1
  45. package/dist/vendor/protocol/session/files.d.ts +83 -0
  46. package/dist/vendor/protocol/session/files.js +162 -0
  47. package/dist/vendor/protocol/session/frames.d.ts +293 -18
  48. package/dist/vendor/protocol/session/frames.js +52 -2
  49. package/dist/vendor/protocol/session/index.d.ts +1 -0
  50. package/dist/vendor/protocol/session/index.js +1 -0
  51. package/dist/vendor/protocol/session/schema.d.ts +2 -2
  52. package/dist/vendor/protocol/session/schema.js +2 -0
  53. package/package.json +2 -2
@@ -0,0 +1,269 @@
1
+ import { FileAccessError } from "./safe-open.js";
2
+ export const MAX_INSPECTION_READS = 4096;
3
+ const MAX_STRUCTURE_STEPS = 4096;
4
+ const MAX_METADATA_BYTES = 64 * 1024;
5
+ const PNG_ANCILLARY = new Set(["cHRM", "gAMA", "iCCP", "sBIT", "sRGB", "bKGD", "hIST", "tRNS", "pHYs", "sPLT", "tIME", "iTXt", "tEXt", "zTXt", "eXIf", "cICP", "mDCV", "cLLI"]);
6
+ /** 只读取结构元数据;压缩数据按长度跳过,不认证像素内容或 CRC。 */
7
+ export class ImageStructureReader {
8
+ handle;
9
+ head;
10
+ byteLength;
11
+ reads;
12
+ steps = 0;
13
+ metadataBytes = 0;
14
+ constructor(handle, head, byteLength, reads) {
15
+ this.handle = handle;
16
+ this.head = head;
17
+ this.byteLength = byteLength;
18
+ this.reads = reads;
19
+ }
20
+ step() { return ++this.steps <= MAX_STRUCTURE_STEPS; }
21
+ async get(position, length) {
22
+ if (!Number.isSafeInteger(position) || position < 0 || length < 0 || position + length > this.byteLength)
23
+ return undefined;
24
+ if (position + length <= this.head.length)
25
+ return this.head.subarray(position, position + length);
26
+ const buffer = Buffer.alloc(length);
27
+ let offset = Math.max(0, Math.min(length, this.head.length - position));
28
+ if (offset)
29
+ this.head.copy(buffer, 0, position, position + offset);
30
+ while (offset < length) {
31
+ const requested = length - offset;
32
+ // 按请求字节计费,短 read 也不能反复请求而突破 metadata I/O 预算。
33
+ if (this.reads >= MAX_INSPECTION_READS || this.metadataBytes + requested > MAX_METADATA_BYTES)
34
+ return undefined;
35
+ this.reads++;
36
+ this.metadataBytes += requested;
37
+ const { bytesRead } = await this.handle.read(buffer, offset, requested, position + offset);
38
+ if (bytesRead === 0)
39
+ throw new FileAccessError("file_changed");
40
+ if (!Number.isInteger(bytesRead) || bytesRead < 0 || bytesRead > requested)
41
+ throw new FileAccessError("io_error");
42
+ offset += bytesRead;
43
+ }
44
+ return buffer;
45
+ }
46
+ }
47
+ function pngHeader(head) {
48
+ if (head.length < 33 || head.readUInt32BE(8) !== 13 || head.toString("latin1", 12, 16) !== "IHDR")
49
+ return undefined;
50
+ const depths = { 0: [1, 2, 4, 8, 16], 2: [8, 16], 3: [1, 2, 4, 8], 4: [8, 16], 6: [8, 16] };
51
+ if (!depths[head[25]]?.includes(head[24]) || head[26] !== 0 || head[27] !== 0 || head[28] > 1)
52
+ return undefined;
53
+ const width = head.readUInt32BE(16);
54
+ const height = head.readUInt32BE(20);
55
+ if (width === 0 || height === 0 || width > 0x7fffffff || height > 0x7fffffff)
56
+ return undefined;
57
+ return { width, height };
58
+ }
59
+ export async function staticPng(reader) {
60
+ const dimensions = pngHeader(reader.head);
61
+ if (!dimensions)
62
+ return undefined;
63
+ let position = 33;
64
+ let dataSeen = false;
65
+ let dataStarted = false;
66
+ let dataEnded = false;
67
+ let paletteSeen = false;
68
+ while (position < reader.byteLength && reader.step()) {
69
+ const header = await reader.get(position, 8);
70
+ if (!header)
71
+ return undefined;
72
+ const length = header.readUInt32BE(0);
73
+ const type = header.toString("latin1", 4, 8);
74
+ const end = position + 12 + length;
75
+ if (length > 0x7fffffff || end > reader.byteLength)
76
+ return undefined;
77
+ // 动画声明在任何位置都不能放行;IEND 后也不得保留浏览器可解释的尾部。
78
+ if (["acTL", "fcTL", "fdAT"].includes(type))
79
+ return undefined;
80
+ if (type === "IEND") {
81
+ if (length !== 0 || !dataSeen || end !== reader.byteLength)
82
+ return undefined;
83
+ return await reader.get(position + 8, 4) ? dimensions : undefined;
84
+ }
85
+ if (type === "IDAT") {
86
+ if (dataEnded || (reader.head[25] === 3 && !paletteSeen))
87
+ return undefined;
88
+ dataStarted = true;
89
+ if (length > 0)
90
+ dataSeen = true;
91
+ }
92
+ else {
93
+ if (dataStarted)
94
+ dataEnded = true;
95
+ if (type === "PLTE") {
96
+ if (paletteSeen || dataStarted || !length || length > 768 || length % 3 || [0, 4].includes(reader.head[25]))
97
+ return undefined;
98
+ paletteSeen = true;
99
+ }
100
+ else if (!PNG_ANCILLARY.has(type))
101
+ return undefined;
102
+ }
103
+ // 中间 payload/checksum 按长度跳过,最终 IEND checksum 稀疏读确认 EOF。
104
+ position = end;
105
+ }
106
+ return undefined;
107
+ }
108
+ function webpPayload(type, data) {
109
+ if (type === "VP8 ") {
110
+ if (data.length < 10 || data[0] & 1 || data.toString("hex", 3, 6) !== "9d012a")
111
+ return undefined;
112
+ return { width: data.readUInt16LE(6) & 0x3fff, height: data.readUInt16LE(8) & 0x3fff };
113
+ }
114
+ if (data.length < 5 || data[0] !== 0x2f)
115
+ return undefined;
116
+ const bits = data.readUInt32LE(1);
117
+ if (bits >>> 29 !== 0)
118
+ return undefined;
119
+ return { width: (bits & 0x3fff) + 1, height: ((bits >>> 14) & 0x3fff) + 1 };
120
+ }
121
+ export async function staticWebp(reader) {
122
+ if (reader.head.readUInt32LE(4) + 8 !== reader.byteLength)
123
+ return undefined;
124
+ let position = 12;
125
+ let canvas;
126
+ let dimensions;
127
+ let flags = 0;
128
+ let imageType;
129
+ const seen = new Set();
130
+ let losslessAlpha = false;
131
+ while (position < reader.byteLength && reader.step()) {
132
+ const header = await reader.get(position, 8);
133
+ if (!header)
134
+ return undefined;
135
+ const type = header.toString("latin1", 0, 4);
136
+ const length = header.readUInt32LE(4);
137
+ const start = position + 8;
138
+ const end = start + length + (length & 1);
139
+ if (end > reader.byteLength || seen.has(type) || type === "ANIM" || type === "ANMF")
140
+ return undefined;
141
+ seen.add(type);
142
+ if (type === "VP8X") {
143
+ const data = length === 10 && position === 12 ? await reader.get(start, 10) : undefined;
144
+ if (!data || data[0] & 0xc3 || data[1] || data[2] || data[3])
145
+ return undefined;
146
+ flags = data[0];
147
+ canvas = { width: data.readUIntLE(4, 3) + 1, height: data.readUIntLE(7, 3) + 1 };
148
+ }
149
+ else if (type === "VP8 " || type === "VP8L") {
150
+ if (dimensions || (seen.has("ALPH") && type !== "VP8 "))
151
+ return undefined;
152
+ const required = type === "VP8 " ? 10 : 5;
153
+ const data = length >= required ? await reader.get(start, required) : undefined;
154
+ if (!data)
155
+ return undefined;
156
+ dimensions = webpPayload(type, data);
157
+ if (!dimensions || !dimensions.width || !dimensions.height)
158
+ return undefined;
159
+ imageType = type;
160
+ losslessAlpha = type === "VP8L" && !!(data[4] & 0x10);
161
+ if (canvas && (canvas.width !== dimensions.width || canvas.height !== dimensions.height))
162
+ return undefined;
163
+ }
164
+ else if (type === "ICCP" || type === "ALPH" || type === "EXIF" || type === "XMP ") {
165
+ if (!canvas || !length)
166
+ return undefined;
167
+ if ((type === "ICCP" || type === "ALPH") && dimensions)
168
+ return undefined;
169
+ if ((type === "EXIF" || type === "XMP ") && !dimensions)
170
+ return undefined;
171
+ if (type === "ALPH") {
172
+ const data = await reader.get(start, 1);
173
+ if (!data || data[0] & 0xc0 || (data[0] & 3) > 1 || ((data[0] >> 4) & 3) > 1)
174
+ return undefined;
175
+ }
176
+ }
177
+ else
178
+ return undefined;
179
+ if (length & 1) {
180
+ const padding = await reader.get(end - 1, 1);
181
+ if (!padding || padding[0] !== 0)
182
+ return undefined;
183
+ }
184
+ position = end;
185
+ }
186
+ if (position !== reader.byteLength || !dimensions)
187
+ return undefined;
188
+ if (canvas && (Boolean(flags & 0x20) !== seen.has("ICCP") || Boolean(flags & 0x08) !== seen.has("EXIF")
189
+ || Boolean(flags & 0x04) !== seen.has("XMP ") || Boolean(flags & 0x10) !== (seen.has("ALPH") || losslessAlpha)))
190
+ return undefined;
191
+ if (!canvas && (seen.size !== 1 || (imageType !== "VP8 " && imageType !== "VP8L")))
192
+ return undefined;
193
+ // 即使最后一个压缩 payload 没有 padding,也确认声明的文件末字节存在。
194
+ return await reader.get(reader.byteLength - 1, 1) ? dimensions : undefined;
195
+ }
196
+ export function staticGif(head, byteLength) {
197
+ // GIF 的压缩块不能稀疏跳过证明帧数;超过已有头预算时仅提供下载。
198
+ if (head.length !== byteLength || head.length < 13)
199
+ return undefined;
200
+ const dimensions = { width: head.readUInt16LE(6), height: head.readUInt16LE(8) };
201
+ if (!dimensions.width || !dimensions.height)
202
+ return undefined;
203
+ const globalTable = !!(head[10] & 0x80);
204
+ let position = 13 + (globalTable ? 3 * 2 ** ((head[10] & 7) + 1) : 0);
205
+ let steps = 0;
206
+ let frames = 0;
207
+ let controlPending = false;
208
+ const step = () => ++steps <= MAX_STRUCTURE_STEPS;
209
+ const subblocks = (requireData) => {
210
+ let dataSeen = false;
211
+ while (position < head.length && step()) {
212
+ const length = head[position++];
213
+ if (!length)
214
+ return !requireData || dataSeen;
215
+ dataSeen = true;
216
+ position += length;
217
+ if (position > head.length)
218
+ return false;
219
+ }
220
+ return false;
221
+ };
222
+ while (position < head.length && step()) {
223
+ const type = head[position++];
224
+ if (type === 0x3b)
225
+ return frames === 1 && !controlPending && position === head.length ? dimensions : undefined;
226
+ if (type === 0x21) {
227
+ const label = head[position++];
228
+ if (label === 0xf9) {
229
+ if (controlPending || position + 6 > head.length || head[position] !== 4 || head[position + 5] !== 0)
230
+ return undefined;
231
+ const packed = head[position + 1];
232
+ if (packed & 0xe0 || ((packed >> 2) & 7) > 3)
233
+ return undefined;
234
+ controlPending = true;
235
+ position += 6;
236
+ }
237
+ else if (label === 0xfe) {
238
+ if (!subblocks(false))
239
+ return undefined;
240
+ }
241
+ else {
242
+ // Plain Text 可产生额外渲染;应用扩展语义未知,不能证明静态。
243
+ return undefined;
244
+ }
245
+ continue;
246
+ }
247
+ if (type !== 0x2c || ++frames !== 1 || position + 9 > head.length)
248
+ return undefined;
249
+ const left = head.readUInt16LE(position);
250
+ const top = head.readUInt16LE(position + 2);
251
+ const width = head.readUInt16LE(position + 4);
252
+ const height = head.readUInt16LE(position + 6);
253
+ const packed = head[position + 8];
254
+ if (!width || !height || left + width > dimensions.width || top + height > dimensions.height || packed & 0x18)
255
+ return undefined;
256
+ const localTable = !!(packed & 0x80);
257
+ if (!globalTable && !localTable)
258
+ return undefined;
259
+ position += 9 + (localTable ? 3 * 2 ** ((packed & 7) + 1) : 0);
260
+ if (position >= head.length || head[position] < 2 || head[position] > 8)
261
+ return undefined;
262
+ position++;
263
+ if (!subblocks(true))
264
+ return undefined;
265
+ controlPending = false;
266
+ }
267
+ return undefined;
268
+ }
269
+ //# sourceMappingURL=image-structure.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image-structure.js","sourceRoot":"","sources":["../../src/files/image-structure.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import { type SessionManager } from "@earendil-works/pi-coding-agent";
2
+ import { type PublishedFileMetadata } from "../vendor/protocol/session/index.js";
3
+ import { z } from "zod";
4
+ export declare const PUBLISHED_FILE_TOOL_NAME: "publish_file";
5
+ export type ConfirmedPublication = {
6
+ id: string;
7
+ sourcePath: string;
8
+ metadata: PublishedFileMetadata;
9
+ groupId?: string;
10
+ timestamp: number;
11
+ branchPosition: number;
12
+ };
13
+ /** 只存于原生 custom;不能把此 schema 当作 wire payload。 */
14
+ export declare const publicationDataSchema: z.ZodObject<{
15
+ file_name: z.ZodString;
16
+ mime_type: z.ZodString;
17
+ byte_length: z.ZodNumber;
18
+ tool_call_id: z.ZodString;
19
+ source_path: z.ZodString;
20
+ group_id: z.ZodOptional<z.ZodString>;
21
+ }, z.core.$strict>;
22
+ /**
23
+ * 原生成功 toolResult 是确认点,且 custom/result 两者均须已落盘。
24
+ * 失败 append 留下的内部孤立记录无资格;不尝试回滚 SDK 的 append-only 树。
25
+ */
26
+ export declare function collectPublications(manager: SessionManager): Map<string, ConfirmedPublication>;
@@ -0,0 +1,136 @@
1
+ import { readFileSync, statSync } from "node:fs";
2
+ import { isAbsolute, resolve } from "node:path";
3
+ import { isDeepStrictEqual } from "node:util";
4
+ import { parseSessionEntries } from "@earendil-works/pi-coding-agent";
5
+ import { idSchema, PUBLISHED_FILE_TYPE, publishedFileMetadataSchema } from "../vendor/protocol/session/index.js";
6
+ import { z } from "zod";
7
+ export const PUBLISHED_FILE_TOOL_NAME = "publish_file";
8
+ /** 只存于原生 custom;不能把此 schema 当作 wire payload。 */
9
+ export const publicationDataSchema = publishedFileMetadataSchema.extend({
10
+ source_path: z.string().min(1).refine((path) => !path.includes("\0") && isAbsolute(path) && resolve(path) === path),
11
+ group_id: idSchema.optional(),
12
+ }).strict();
13
+ const resultDetailsSchema = z.object({ publication_id: idSchema }).strict();
14
+ // 一个 manager 最多保留一个文件的解析结果;manager 回收时缓存随之回收。
15
+ const diskProofs = new WeakMap();
16
+ function sameFile(left, right) {
17
+ return left.dev === right.dev && left.ino === right.ino && left.size === right.size
18
+ && left.mtimeNs === right.mtimeNs && left.ctimeNs === right.ctimeNs;
19
+ }
20
+ function diskEntries(manager) {
21
+ try {
22
+ const path = manager.getSessionFile();
23
+ if (!path)
24
+ return null;
25
+ const before = statSync(path, { bigint: true });
26
+ if (!before.isFile())
27
+ return null;
28
+ const cached = diskProofs.get(manager);
29
+ if (cached?.path === path && sameFile(cached.stat, before))
30
+ return cached.entries;
31
+ const entries = parseSessionEntries(readFileSync(path, "utf8"));
32
+ const after = statSync(path, { bigint: true });
33
+ if (!after.isFile() || !sameFile(before, after))
34
+ return null;
35
+ diskProofs.set(manager, { path, stat: after, entries });
36
+ return entries;
37
+ }
38
+ catch {
39
+ diskProofs.delete(manager);
40
+ return null;
41
+ }
42
+ }
43
+ function record(value) {
44
+ return typeof value === "object" && value !== null && !Array.isArray(value);
45
+ }
46
+ /** JSONL 不存 undefined 字段;比较完整原生记录而非只比较 publication_id。 */
47
+ function samePersistedEntry(current, persisted) {
48
+ return isDeepStrictEqual(JSON.parse(JSON.stringify(current)), persisted);
49
+ }
50
+ function addByCall(map, callId, value) {
51
+ if (typeof callId !== "string")
52
+ return;
53
+ const matches = map.get(callId) ?? [];
54
+ matches.push(value);
55
+ map.set(callId, matches);
56
+ }
57
+ /**
58
+ * 原生成功 toolResult 是确认点,且 custom/result 两者均须已落盘。
59
+ * 失败 append 留下的内部孤立记录无资格;不尝试回滚 SDK 的 append-only 树。
60
+ */
61
+ export function collectPublications(manager) {
62
+ const confirmed = new Map();
63
+ try {
64
+ const persisted = diskEntries(manager);
65
+ if (!persisted)
66
+ return confirmed;
67
+ const headers = persisted.filter((entry) => record(entry) && entry.type === "session");
68
+ const header = manager.getHeader();
69
+ if (headers.length !== 1 || persisted[0] !== headers[0] || !header
70
+ || header.id !== manager.getSessionId() || !samePersistedEntry(header, headers[0]))
71
+ return confirmed;
72
+ const diskById = new Map();
73
+ for (const entry of persisted) {
74
+ if (!record(entry) || !idSchema.safeParse(entry.id).success || diskById.has(entry.id))
75
+ return confirmed;
76
+ diskById.set(entry.id, entry);
77
+ }
78
+ const branch = manager.getBranch();
79
+ const customs = new Map();
80
+ const results = new Map();
81
+ const branchIds = new Set();
82
+ const persistedPrefixes = [];
83
+ let persistedPrefix = true;
84
+ for (let index = 0; index < branch.length; index++) {
85
+ const entry = branch[index];
86
+ if (branchIds.has(entry.id) || entry.parentId !== (index === 0 ? null : branch[index - 1].id))
87
+ return confirmed;
88
+ branchIds.add(entry.id);
89
+ const diskEntry = diskById.get(entry.id);
90
+ persistedPrefix = persistedPrefix && diskEntry?.type === entry.type
91
+ && "parentId" in diskEntry && diskEntry.parentId === entry.parentId;
92
+ persistedPrefixes.push(persistedPrefix);
93
+ if (entry.type === "custom" && entry.customType === PUBLISHED_FILE_TYPE) {
94
+ addByCall(customs, record(entry.data) ? entry.data.tool_call_id : undefined, { entry, index });
95
+ }
96
+ else if (entry.type === "message" && entry.message.role === "toolResult" && entry.message.toolName === PUBLISHED_FILE_TOOL_NAME) {
97
+ addByCall(results, entry.message.toolCallId, { entry, index });
98
+ }
99
+ }
100
+ const candidates = [];
101
+ for (const [callId, matches] of customs) {
102
+ const tools = results.get(callId);
103
+ if (matches.length !== 1 || tools?.length !== 1)
104
+ continue;
105
+ const custom = matches[0];
106
+ const result = tools[0];
107
+ const data = publicationDataSchema.safeParse(custom.entry.data);
108
+ const message = result.entry.message;
109
+ if (!data.success || message.role !== "toolResult" || message.isError !== false
110
+ || result.index <= custom.index || !persistedPrefixes[result.index])
111
+ continue;
112
+ const details = resultDetailsSchema.safeParse(message.details);
113
+ const timestamp = Date.parse(custom.entry.timestamp);
114
+ if (!details.success || details.data.publication_id !== custom.entry.id || !Number.isFinite(timestamp) || timestamp < 0)
115
+ continue;
116
+ if (!samePersistedEntry(custom.entry, diskById.get(custom.entry.id))
117
+ || !samePersistedEntry(result.entry, diskById.get(result.entry.id)))
118
+ continue;
119
+ const { source_path, group_id, ...metadata } = data.data;
120
+ candidates.push({
121
+ id: custom.entry.id, sourcePath: source_path, metadata, timestamp,
122
+ ...(group_id === undefined ? {} : { groupId: group_id }),
123
+ branchPosition: result.index + 0.5,
124
+ });
125
+ }
126
+ candidates.sort((left, right) => left.branchPosition - right.branchPosition);
127
+ for (const candidate of candidates)
128
+ confirmed.set(candidate.id, candidate);
129
+ return confirmed;
130
+ }
131
+ catch {
132
+ // 不可信或无法读取的原生记录只能拒绝资格,不能降级为内存证明。
133
+ return new Map();
134
+ }
135
+ }
136
+ //# sourceMappingURL=publications.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"publications.js","sourceRoot":"","sources":["../../src/files/publications.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import type { SessionManager, ToolDefinition } from "@earendil-works/pi-coding-agent";
2
+ import { Type } from "typebox";
3
+ declare const parameters: Type.TObject<{
4
+ path: Type.TString;
5
+ }>;
6
+ export type PublishFileToolOptions = {
7
+ getManager: () => SessionManager | null;
8
+ isCurrent: () => boolean;
9
+ getGeneration: () => number;
10
+ getGroupId: () => string | null;
11
+ /** 仅在共享资源账目中完成 inspection 并关闭句柄后 resolve。 */
12
+ inspect: (absolutePath: string) => Promise<{
13
+ sourcePath: string;
14
+ fileName: string;
15
+ mimeType: string;
16
+ byteLength: number;
17
+ }>;
18
+ };
19
+ export type PublishFileToolDetails = {
20
+ publication_id: string;
21
+ };
22
+ export declare function createPublishFileTool(options: PublishFileToolOptions): ToolDefinition<typeof parameters, PublishFileToolDetails>;
23
+ export {};
@@ -0,0 +1,70 @@
1
+ import { resolve } from "node:path";
2
+ import { statSync } from "node:fs";
3
+ import { PUBLISHED_FILE_TYPE } from "../vendor/protocol/session/index.js";
4
+ import { Type } from "typebox";
5
+ import { publicationDataSchema, PUBLISHED_FILE_TOOL_NAME } from "./publications.js";
6
+ const parameters = Type.Object({ path: Type.String({ minLength: 1 }) }, { additionalProperties: false });
7
+ const FAILURE_TEXT = "文件发布失败";
8
+ function storedSession(manager, file) {
9
+ try {
10
+ return manager.isPersisted() && !!file && statSync(file).isFile();
11
+ }
12
+ catch {
13
+ return false;
14
+ }
15
+ }
16
+ export function createPublishFileTool(options) {
17
+ // SDK sequential 是调度约束;此门禁也阻止意外重入或嵌套直接调用。
18
+ let executing = false;
19
+ return {
20
+ name: PUBLISHED_FILE_TOOL_NAME,
21
+ label: "发布文件",
22
+ description: "仅发布面向用户交付的成果,或用户明确要求的文件;不要自动发布所有读取、修改或临时文件。已授权 PWA 可能自动获取受支持的小图片。path 相对当前工作目录或为绝对路径,允许项目外的普通文件;只保存引用,不复制原件。",
23
+ parameters,
24
+ executionMode: "sequential",
25
+ async execute(toolCallId, args, signal, _onUpdate, ctx) {
26
+ if (executing)
27
+ throw new Error(FAILURE_TEXT);
28
+ executing = true;
29
+ try {
30
+ const manager = options.getManager();
31
+ const generation = options.getGeneration();
32
+ const groupId = options.getGroupId();
33
+ if (!manager)
34
+ throw new Error(FAILURE_TEXT);
35
+ const sessionId = manager.getSessionId();
36
+ const sessionFile = manager.getSessionFile();
37
+ const valid = () => options.isCurrent() && !signal?.aborted && !ctx.signal?.aborted
38
+ && options.getGeneration() === generation && options.getManager() === manager
39
+ && ctx.sessionManager === manager && ctx.sessionManager.getSessionId() === sessionId
40
+ && manager.getSessionId() === sessionId && manager.getSessionFile() === sessionFile
41
+ && storedSession(manager, sessionFile);
42
+ if (!valid() || typeof args.path !== "string" || !args.path || args.path.includes("\0"))
43
+ throw new Error(FAILURE_TEXT);
44
+ const inspected = await options.inspect(resolve(ctx.cwd, args.path));
45
+ const data = publicationDataSchema.parse({
46
+ source_path: inspected.sourcePath,
47
+ file_name: inspected.fileName,
48
+ mime_type: inspected.mimeType,
49
+ byte_length: inspected.byteLength,
50
+ tool_call_id: toolCallId,
51
+ ...(groupId === null ? {} : { group_id: groupId }),
52
+ });
53
+ if (!valid())
54
+ throw new Error(FAILURE_TEXT);
55
+ const text = `已发布文件引用:${data.file_name} · ${data.mime_type} · ${data.byte_length} B`;
56
+ const publicationId = manager.appendCustomEntry(PUBLISHED_FILE_TYPE, data);
57
+ // append 后没有可失败的 await;正式资格由随后落盘的成功原生 toolResult 建立。
58
+ return { content: [{ type: "text", text }], details: { publication_id: publicationId } };
59
+ }
60
+ catch {
61
+ // SDK 会将 throw 转为 isError;不把内部路径或 I/O 异常暴露给消息与日志。
62
+ throw new Error(FAILURE_TEXT);
63
+ }
64
+ finally {
65
+ executing = false;
66
+ }
67
+ },
68
+ };
69
+ }
70
+ //# sourceMappingURL=publish-tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"publish-tool.js","sourceRoot":"","sources":["../../src/files/publish-tool.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,66 @@
1
+ import { type ClientFrame, type ServerFrame } from "../vendor/protocol/session/index.js";
2
+ export type FileScope = {
3
+ ownerId: string;
4
+ channelId: string;
5
+ runtimeId: string;
6
+ sessionId: string;
7
+ generation: number;
8
+ };
9
+ type Request = Extract<ClientFrame, {
10
+ type: "file_open" | "file_read" | "file_close";
11
+ }>;
12
+ type Response = Extract<ServerFrame, {
13
+ type: "file_opened" | "file_chunk" | "file_closed" | "file_error";
14
+ }>;
15
+ type Options = {
16
+ resolve: (scope: FileScope, publicationId: string) => {
17
+ sourcePath: string;
18
+ } | null | Promise<{
19
+ sourcePath: string;
20
+ } | null>;
21
+ isCurrent: (scope: FileScope) => boolean;
22
+ idleMs?: number;
23
+ maxResources?: number;
24
+ };
25
+ /** 所有异步任务共享额度;失效不等于内核 I/O 已停止或句柄已关闭。 */
26
+ export declare class FileReaderRuntime {
27
+ private readonly options;
28
+ private readonly resources;
29
+ private readonly opens;
30
+ private readonly idleMs;
31
+ private readonly maxResources;
32
+ private timer?;
33
+ private timerDeadline?;
34
+ private disposed;
35
+ constructor(options: Options);
36
+ get resourceCount(): number;
37
+ private reserve;
38
+ private schedule;
39
+ private invalidate;
40
+ private assertCurrent;
41
+ private eligible;
42
+ private checked;
43
+ private release;
44
+ private closeHandle;
45
+ private cleanup;
46
+ private finish;
47
+ private reply;
48
+ private failure;
49
+ handle(frame: Request, suppliedScope: FileScope): Promise<Response>;
50
+ private open;
51
+ private openResponse;
52
+ private openTask;
53
+ private verify;
54
+ private readTask;
55
+ private read;
56
+ inspectForPublication(path: string): Promise<{
57
+ sourcePath: string;
58
+ fileName: string;
59
+ mimeType: string;
60
+ byteLength: number;
61
+ }>;
62
+ private inspectTask;
63
+ closeWhere(predicate: (scope: FileScope) => boolean): Promise<void>;
64
+ dispose(): Promise<void>;
65
+ }
66
+ export {};