MCPcopy
hub / github.com/coder/mux / readAttachFileFromPath

Function readAttachFileFromPath

src/node/utils/attachments/readAttachmentFromPath.ts:264–339  ·  view source on GitHub ↗
(
  args: ReadAttachmentFromPathArgs
)

Source from the content-addressed store, hash-verified

262}
263
264export async function readAttachFileFromPath(
265 args: ReadAttachmentFromPathArgs
266): Promise<AttachFileFromPathResult> {
267 assert(
268 typeof args.path === "string" && args.path.trim().length > 0,
269 "attach_file requires a path"
270 );
271
272 const { resolvedPath } = resolvePathWithinCwd(args.path, args.cwd, args.runtime);
273 const fileStat = await statRegularFile(args, resolvedPath);
274 const filename = getFallbackFilename(resolvedPath, args.filename);
275 const mediaType = getSupportedAttachmentMediaType({
276 mediaType: args.mediaType,
277 // Infer the attachment type from the source path, not the display filename override.
278 // Callers may intentionally rename the attachment to a presentation-only label.
279 filename: resolvedPath,
280 });
281
282 if (mediaType == null) {
283 const displayMediaTypeCandidate = getDisplayFileMediaTypeCandidate(args, resolvedPath);
284 if (displayMediaTypeCandidate == null) {
285 throw createUnsupportedAttachmentError(args, resolvedPath);
286 }
287 if (fileStat.size > MAX_ATTACH_FILE_SIZE_BYTES) {
288 throw new Error(
289 `${getErrorMessage(createUnsupportedAttachmentError(args, resolvedPath))}. Could not show file to user: ${buildTooLargeMessage(fileStat.size)}`
290 );
291 }
292
293 const bytes = await readRegularFileBytes(args, resolvedPath, fileStat.size);
294 if (displayMediaTypeCandidate.requireBinaryContent && isLikelyTextFile(bytes)) {
295 throw createUnsupportedAttachmentError(args, resolvedPath);
296 }
297
298 return {
299 type: "display",
300 file: createLoadedFile({
301 data: bytes,
302 mediaType: displayMediaTypeCandidate.mediaType,
303 filename,
304 resolvedPath,
305 }),
306 };
307 }
308
309 const bytes = await readRegularFileBytes(args, resolvedPath, fileStat.size);
310
311 if (mediaType === SVG_MEDIA_TYPE) {
312 const svgText = bytes.toString("utf8");
313 if (svgText.length > MAX_SVG_TEXT_CHARS) {
314 throw new Error(
315 `SVG attachments must be ${MAX_SVG_TEXT_CHARS.toLocaleString()} characters or less (this one is ${svgText.length.toLocaleString()}).`
316 );
317 }
318 }
319
320 let attachmentBytes = bytes;
321 let attachmentMediaType = mediaType;

Callers 2

createAttachFileToolFunction · 0.90
readAttachmentFromPathFunction · 0.85

Calls 14

resolvePathWithinCwdFunction · 0.90
getErrorMessageFunction · 0.90
statRegularFileFunction · 0.85
getFallbackFilenameFunction · 0.85
buildTooLargeMessageFunction · 0.85
readRegularFileBytesFunction · 0.85
isLikelyTextFileFunction · 0.85

Tested by

no test coverage detected