Download src/media-understanding/attachments.normalize.ts from SaylorTwift/openclaw: direct link, hf CLI and curl.
- Browser
- Download file 3.15 kB
-
https://huggingface.co/SaylorTwift/openclaw/resolve/main/src/media-understanding/attachments.normalize.ts
- Command line
-
hf download hf://SaylorTwift/openclaw/src/media-understanding/attachments.normalize.ts
-
curl -L -o attachments.normalize.ts https://huggingface.co/SaylorTwift/openclaw/resolve/main/src/media-understanding/attachments.normalize.ts
3.15 kB
| // Attachment normalization converts message context media fields into typed | |
| // attachment records and classifies media kind from MIME or filename. | |
| import type { MediaKind } from "@openclaw/media-core/constants"; | |
| import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; | |
| import type { RuntimeMsgContext as MsgContext } from "../auto-reply/templating.js"; | |
| import { assertNoWindowsNetworkPath, safeFileURLToPath } from "../infra/local-file-access.js"; | |
| import { normalizeMediaFacts, resolveMediaFactKind } from "../media/media-facts.js"; | |
| import type { MediaAttachment } from "./types.js"; | |
| /** Normalizes a local attachment path while rejecting remote file URLs and Windows UNC paths. */ | |
| export function normalizeAttachmentPath(raw?: string | null): string | undefined { | |
| const value = normalizeOptionalString(raw); | |
| if (!value) { | |
| return undefined; | |
| } | |
| if (/^file:/iu.test(value)) { | |
| try { | |
| return safeFileURLToPath(value); | |
| } catch { | |
| return undefined; | |
| } | |
| } | |
| try { | |
| assertNoWindowsNetworkPath(value, "Attachment path"); | |
| } catch { | |
| return undefined; | |
| } | |
| return value; | |
| } | |
| /** Converts ordered media facts into indexed attachment records. */ | |
| export function normalizeAttachments(ctx: MsgContext): MediaAttachment[] { | |
| return normalizeMediaFacts(ctx.media) | |
| .map((fact, index) => { | |
| const attachment: MediaAttachment = { | |
| path: normalizeOptionalString(fact.path), | |
| url: normalizeOptionalString(fact.url), | |
| mime: normalizeOptionalString(fact.contentType), | |
| index, | |
| alreadyTranscribed: fact.transcribed === true, | |
| }; | |
| const kind = fact.fileName ? (resolveMediaFactKind(fact) ?? fact.kind) : fact.kind; | |
| if (kind) { | |
| attachment.kind = kind; | |
| } | |
| const fileName = normalizeOptionalString(fact.fileName); | |
| if (fileName) { | |
| attachment.fileName = fileName; | |
| } | |
| if (fact.workspaceDir) { | |
| attachment.workspaceDir = fact.workspaceDir; | |
| } | |
| return attachment; | |
| }) | |
| .filter((entry) => Boolean(entry.path ?? entry.url)); | |
| } | |
| /** Classifies an attachment by authoritative kind, MIME, then canonical filename metadata. */ | |
| export function resolveAttachmentKind(attachment: MediaAttachment): Exclude<MediaKind, "sticker"> { | |
| const kind = resolveMediaFactKind({ | |
| path: attachment.path, | |
| url: attachment.url, | |
| contentType: attachment.mime, | |
| kind: attachment.kind, | |
| }); | |
| return kind === "sticker" ? "image" : kind === "document" ? "unknown" : (kind ?? "unknown"); | |
| } | |
| /** Returns true when the attachment is classified as video media. */ | |
| export function isVideoAttachment(attachment: MediaAttachment): boolean { | |
| return resolveAttachmentKind(attachment) === "video"; | |
| } | |
| /** Returns true when the attachment is classified as audio media. */ | |
| export function isAudioAttachment(attachment: MediaAttachment): boolean { | |
| return resolveAttachmentKind(attachment) === "audio"; | |
| } | |
| /** Returns true when the attachment is classified as image media. */ | |
| export function isImageAttachment(attachment: MediaAttachment): boolean { | |
| return resolveAttachmentKind(attachment) === "image"; | |
| } | |