@yeaft/webchat-agent 1.0.639 → 1.0.641

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yeaft/webchat-agent",
3
- "version": "1.0.639",
3
+ "version": "1.0.641",
4
4
  "description": "Remote worker agent for Yeaft Web Code Agent — connects the native Yeaft engine, CLI providers, and workbench tools",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -312,9 +312,16 @@ export function resolvePersistedAttachmentPath(attachmentPath, opts = {}) {
312
312
  }
313
313
  }
314
314
 
315
- /** Shared bounded read for model history and browser preview. Never follows symlinks. */
316
- function readPersistedAttachment(att, opts, maxBytes) {
317
- const absPath = resolvePersistedAttachmentPath(att?.path, opts);
315
+ /**
316
+ * Read a bounded, owner-scoped attachment for host consumers, never via symlinks.
317
+ * Ownership is derived from opts, not the supplied path or attachment metadata.
318
+ * @param {string} attachmentPath
319
+ * @param {{cwd?:string, legacyRoot?:string, yeaftDir?:string, sessionId?:string}} opts
320
+ * @param {number} maxBytes
321
+ * @returns {{path:string, buffer:Buffer, modified:string}}
322
+ */
323
+ export function readPersistedAttachmentFile(attachmentPath, opts, maxBytes) {
324
+ const absPath = resolvePersistedAttachmentPath(attachmentPath, opts);
318
325
  if (!absPath) throw new Error('file missing or outside this Session / 文件缺失或不属于本会话');
319
326
  const fd = openSync(absPath, constants.O_RDONLY | (constants.O_NOFOLLOW || 0) | (constants.O_NONBLOCK || 0));
320
327
  try {
@@ -328,17 +335,23 @@ function readPersistedAttachment(att, opts, maxBytes) {
328
335
  if (!read) throw new Error('image changed while reading');
329
336
  offset += read;
330
337
  }
331
- return {
332
- data: buffer.toString('base64'),
333
- mimeType: att.mimeType || 'image/png',
334
- filename: att.name || basename(absPath),
335
- bytes: buffer.length,
336
- };
338
+ return { path: absPath, buffer, modified: stat.mtime.toISOString() };
337
339
  } finally {
338
340
  closeSync(fd);
339
341
  }
340
342
  }
341
343
 
344
+ /** Shared bounded read for model history and browser preview. Never follows symlinks. */
345
+ function readPersistedAttachment(att, opts, maxBytes) {
346
+ const { path, buffer } = readPersistedAttachmentFile(att?.path, opts, maxBytes);
347
+ return {
348
+ data: buffer.toString('base64'),
349
+ mimeType: att.mimeType || 'image/png',
350
+ filename: att.name || basename(path),
351
+ bytes: buffer.length,
352
+ };
353
+ }
354
+
342
355
  /** Short-lived web preview; missing/denied/oversized images have no preview. */
343
356
  export function persistedAttachmentPreviewPayload(att, opts = {}) {
344
357
  if (!att?.isImage || !att.path) return null;