@assistant-ui/react-devtools 1.2.11 → 1.2.13

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.
@@ -137,12 +137,13 @@ const ScopeFilterBar = (t0) => {
137
137
  if ($[5] !== toggleEventType || $[6] !== toggleScope || $[7] !== unselectedEventTypes) {
138
138
  t2 = (t3) => {
139
139
  const [scope, types] = t3;
140
+ const allSelected = types.every((type) => !unselectedEventTypes.has(type));
140
141
  return /* @__PURE__ */ jsxs("div", {
141
142
  className: "flex flex-wrap items-center gap-1.5",
142
143
  children: [/* @__PURE__ */ jsx("button", {
143
144
  type: "button",
144
145
  onClick: () => toggleScope(types),
145
- className: clsx("rounded-md border px-1.5 py-0.5 text-[10px] font-medium transition-colors", types.every((type) => !unselectedEventTypes.has(type)) ? "bg-accent text-foreground" : "text-muted-foreground"),
146
+ className: clsx("rounded-md border px-1.5 py-0.5 text-[10px] font-medium transition-colors", allSelected ? "bg-accent text-foreground" : "text-muted-foreground"),
146
147
  children: scope
147
148
  }), types.map((eventType) => /* @__PURE__ */ jsxs("label", {
148
149
  title: eventType,
@@ -1 +1 @@
1
- {"version":3,"file":"EventLogRow.js","names":["clsx","eventScope","formatClockTime","EventLogEntry","PartDisclosure","PayloadDiff","Chip","JSONTree","EventLogRow","t0","$","_c","log","previous","showDiff","t1","timeLabel","undefined","t2","event","scope","t3","length","slice","suffix","t4","time","t5","t6","t7","t8","t9","data","t10","t11","t12","ScopeFilterBar","eventTypesByScope","unselectedEventTypes","toggleScope","toggleEventType","types","allSelected","every","type","has","map","eventType"],"sources":["../../../src/views/activity/EventLogRow.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport { eventScope, formatClockTime } from \"../../utils/common\";\nimport type { EventLogEntry } from \"../../data/types\";\nimport { PartDisclosure } from \"../message/PartDisclosure\";\nimport { PayloadDiff } from \"../runs/PayloadDiff\";\nimport { Chip, JSONTree } from \"../ui\";\n\nexport const EventLogRow = ({\n log,\n previous,\n showDiff = false,\n timeLabel,\n}: {\n log: EventLogEntry;\n previous?: EventLogEntry | undefined;\n showDiff?: boolean;\n /** Overrides the default clock time label. */\n timeLabel?: string | undefined;\n}) => {\n const scope = eventScope(log.event);\n const suffix = log.event.slice(scope.length + 1) || log.event;\n\n return (\n <div className=\"flex flex-col gap-1 py-1.5\">\n <div className=\"flex min-w-0 items-center gap-2\">\n <span className=\"text-muted-foreground w-16 shrink-0 font-mono text-[10px] tabular-nums\">\n {timeLabel ?? formatClockTime(log.time)}\n </span>\n <Chip className=\"shrink-0\">{scope}</Chip>\n <span className=\"text-foreground min-w-0 truncate text-[11px] font-medium\">\n {suffix}\n </span>\n </div>\n <div className=\"ps-[4.5rem]\">\n <PartDisclosure label=\"Payload\">\n <JSONTree value={log.data} openDepth={0} compact />\n </PartDisclosure>\n {showDiff && previous ? (\n <div className=\"mt-1\">\n <PartDisclosure label=\"Diff\">\n <PayloadDiff before={previous.data} after={log.data} />\n </PartDisclosure>\n </div>\n ) : null}\n </div>\n </div>\n );\n};\n\nexport const ScopeFilterBar = ({\n eventTypesByScope,\n unselectedEventTypes,\n toggleScope,\n toggleEventType,\n}: {\n eventTypesByScope: readonly (readonly [string, string[]])[];\n unselectedEventTypes: ReadonlySet<string>;\n toggleScope: (types: string[]) => void;\n toggleEventType: (eventType: string) => void;\n}) => {\n if (!eventTypesByScope.length) return null;\n\n return (\n <div className=\"flex flex-col gap-2 px-3 py-2\">\n {eventTypesByScope.map(([scope, types]) => {\n const allSelected = types.every(\n (type) => !unselectedEventTypes.has(type),\n );\n return (\n <div key={scope} className=\"flex flex-wrap items-center gap-1.5\">\n <button\n type=\"button\"\n onClick={() => toggleScope(types)}\n className={clsx(\n \"rounded-md border px-1.5 py-0.5 text-[10px] font-medium transition-colors\",\n allSelected\n ? \"bg-accent text-foreground\"\n : \"text-muted-foreground\",\n )}\n >\n {scope}\n </button>\n {types.map((eventType) => (\n <label\n key={eventType}\n title={eventType}\n className={clsx(\n \"flex items-center gap-1 rounded-md border px-1.5 py-0.5 text-[10px] font-medium transition-colors\",\n !unselectedEventTypes.has(eventType)\n ? \"bg-accent text-foreground\"\n : \"text-muted-foreground\",\n )}\n >\n <input\n type=\"checkbox\"\n checked={!unselectedEventTypes.has(eventType)}\n onChange={() => toggleEventType(eventType)}\n className=\"accent-foreground size-3 rounded\"\n />\n <span>{eventType.slice(scope.length + 1) || eventType}</span>\n </label>\n ))}\n </div>\n );\n })}\n </div>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"EventLogRow.js","names":["clsx","eventScope","formatClockTime","EventLogEntry","PartDisclosure","PayloadDiff","Chip","JSONTree","EventLogRow","t0","$","_c","log","previous","showDiff","t1","timeLabel","undefined","t2","event","scope","t3","length","slice","suffix","t4","time","t5","t6","t7","t8","t9","data","t10","t11","t12","ScopeFilterBar","eventTypesByScope","unselectedEventTypes","toggleScope","toggleEventType","types","allSelected","every","type","has","map","eventType"],"sources":["../../../src/views/activity/EventLogRow.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport { eventScope, formatClockTime } from \"../../utils/common\";\nimport type { EventLogEntry } from \"../../data/types\";\nimport { PartDisclosure } from \"../message/PartDisclosure\";\nimport { PayloadDiff } from \"../runs/PayloadDiff\";\nimport { Chip, JSONTree } from \"../ui\";\n\nexport const EventLogRow = ({\n log,\n previous,\n showDiff = false,\n timeLabel,\n}: {\n log: EventLogEntry;\n previous?: EventLogEntry | undefined;\n showDiff?: boolean;\n /** Overrides the default clock time label. */\n timeLabel?: string | undefined;\n}) => {\n const scope = eventScope(log.event);\n const suffix = log.event.slice(scope.length + 1) || log.event;\n\n return (\n <div className=\"flex flex-col gap-1 py-1.5\">\n <div className=\"flex min-w-0 items-center gap-2\">\n <span className=\"text-muted-foreground w-16 shrink-0 font-mono text-[10px] tabular-nums\">\n {timeLabel ?? formatClockTime(log.time)}\n </span>\n <Chip className=\"shrink-0\">{scope}</Chip>\n <span className=\"text-foreground min-w-0 truncate text-[11px] font-medium\">\n {suffix}\n </span>\n </div>\n <div className=\"ps-[4.5rem]\">\n <PartDisclosure label=\"Payload\">\n <JSONTree value={log.data} openDepth={0} compact />\n </PartDisclosure>\n {showDiff && previous ? (\n <div className=\"mt-1\">\n <PartDisclosure label=\"Diff\">\n <PayloadDiff before={previous.data} after={log.data} />\n </PartDisclosure>\n </div>\n ) : null}\n </div>\n </div>\n );\n};\n\nexport const ScopeFilterBar = ({\n eventTypesByScope,\n unselectedEventTypes,\n toggleScope,\n toggleEventType,\n}: {\n eventTypesByScope: readonly (readonly [string, string[]])[];\n unselectedEventTypes: ReadonlySet<string>;\n toggleScope: (types: string[]) => void;\n toggleEventType: (eventType: string) => void;\n}) => {\n if (!eventTypesByScope.length) return null;\n\n return (\n <div className=\"flex flex-col gap-2 px-3 py-2\">\n {eventTypesByScope.map(([scope, types]) => {\n const allSelected = types.every(\n (type) => !unselectedEventTypes.has(type),\n );\n return (\n <div key={scope} className=\"flex flex-wrap items-center gap-1.5\">\n <button\n type=\"button\"\n onClick={() => toggleScope(types)}\n className={clsx(\n \"rounded-md border px-1.5 py-0.5 text-[10px] font-medium transition-colors\",\n allSelected\n ? \"bg-accent text-foreground\"\n : \"text-muted-foreground\",\n )}\n >\n {scope}\n </button>\n {types.map((eventType) => (\n <label\n key={eventType}\n title={eventType}\n className={clsx(\n \"flex items-center gap-1 rounded-md border px-1.5 py-0.5 text-[10px] font-medium transition-colors\",\n !unselectedEventTypes.has(eventType)\n ? \"bg-accent text-foreground\"\n : \"text-muted-foreground\",\n )}\n >\n <input\n type=\"checkbox\"\n checked={!unselectedEventTypes.has(eventType)}\n onChange={() => toggleEventType(eventType)}\n className=\"accent-foreground size-3 rounded\"\n />\n <span>{eventType.slice(scope.length + 1) || eventType}</span>\n </label>\n ))}\n </div>\n );\n })}\n </div>\n );\n};\n"],"mappings":"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"}
@@ -2,12 +2,12 @@
2
2
  const formatBytes = (bytes) => {
3
3
  if (bytes === void 0 || bytes <= 0) return void 0;
4
4
  if (bytes < 1024) return `${bytes} B`;
5
- if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
6
- return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
5
+ if (bytes < 1048576) return `${(bytes / 1024).toFixed(1)} KB`;
6
+ return `${(bytes / 1048576).toFixed(1)} MB`;
7
7
  };
8
8
  /** Rough size from base64 payload (no decoding). */
9
9
  const estimateBase64Bytes = (data) => Math.max(0, Math.floor(data.length * 3 / 4));
10
- const isSafeImagePreviewUrl = (url) => url.startsWith("data:image/") || url.startsWith("https://") || url.startsWith("http://");
10
+ const isSafeImagePreviewUrl = (url) => /^data:image\//i.test(url) || /^https?:\/\//i.test(url);
11
11
  //#endregion
12
12
  export { estimateBase64Bytes, formatBytes, isSafeImagePreviewUrl };
13
13
 
@@ -1 +1 @@
1
- {"version":3,"file":"formatBytes.js","names":["formatBytes","bytes","undefined","toFixed","estimateBase64Bytes","data","Math","max","floor","length","isSafeImagePreviewUrl","url","startsWith"],"sources":["../../../src/views/attachments/formatBytes.ts"],"sourcesContent":["export const formatBytes = (bytes: number | undefined): string | undefined => {\n if (bytes === undefined || bytes <= 0) return undefined;\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n};\n\n/** Rough size from base64 payload (no decoding). */\nexport const estimateBase64Bytes = (data: string): number =>\n Math.max(0, Math.floor((data.length * 3) / 4));\n\nexport const isSafeImagePreviewUrl = (url: string): boolean =>\n url.startsWith(\"data:image/\") ||\n url.startsWith(\"https://\") ||\n url.startsWith(\"http://\");\n"],"mappings":";AAAA,MAAaA,eAAeC,UAAkD;CAC5E,IAAIA,UAAUC,KAAAA,KAAaD,SAAS,GAAG,OAAOC,KAAAA;CAC9C,IAAID,QAAQ,MAAM,OAAO,GAAGA,MAAK;CACjC,IAAIA,QAAQ,OAAO,MAAM,OAAO,IAAIA,QAAQ,KAAA,CAAME,QAAQ,CAAC,EAAC;CAC5D,OAAO,IAAIF,SAAS,OAAO,MAAA,CAAOE,QAAQ,CAAC,EAAC;AAC9C;;AAGA,MAAaC,uBAAuBC,SAClCC,KAAKC,IAAI,GAAGD,KAAKE,MAAOH,KAAKI,SAAS,IAAK,CAAC,CAAC;AAE/C,MAAaC,yBAAyBC,QACpCA,IAAIC,WAAW,aAAa,KAC5BD,IAAIC,WAAW,UAAU,KACzBD,IAAIC,WAAW,SAAS"}
1
+ {"version":3,"file":"formatBytes.js","names":["formatBytes","bytes","undefined","toFixed","estimateBase64Bytes","data","Math","max","floor","length","isSafeImagePreviewUrl","url","test"],"sources":["../../../src/views/attachments/formatBytes.ts"],"sourcesContent":["export const formatBytes = (bytes: number | undefined): string | undefined => {\n if (bytes === undefined || bytes <= 0) return undefined;\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n};\n\n/** Rough size from base64 payload (no decoding). */\nexport const estimateBase64Bytes = (data: string): number =>\n Math.max(0, Math.floor((data.length * 3) / 4));\n\nexport const isSafeImagePreviewUrl = (url: string): boolean =>\n /^data:image\\//i.test(url) || /^https?:\\/\\//i.test(url);\n"],"mappings":";AAAA,MAAaA,eAAeC,UAAkD;CAC5E,IAAIA,UAAUC,KAAAA,KAAaD,SAAS,GAAG,OAAOC,KAAAA;CAC9C,IAAID,QAAQ,MAAM,OAAO,GAAGA,MAAK;CACjC,IAAIA,QAAQ,SAAa,OAAO,IAAIA,QAAQ,KAAA,CAAME,QAAQ,CAAC,EAAC;CAC5D,OAAO,IAAIF,QAAS,QAAA,CAAcE,QAAQ,CAAC,EAAC;AAC9C;;AAGA,MAAaC,uBAAuBC,SAClCC,KAAKC,IAAI,GAAGD,KAAKE,MAAOH,KAAKI,SAAS,IAAK,CAAC,CAAC;AAE/C,MAAaC,yBAAyBC,QACpC,iBAAiBC,KAAKD,GAAG,KAAK,gBAAgBC,KAAKD,GAAG"}
@@ -18,7 +18,7 @@ const mediaFromContent = (content) => {
18
18
  if (type === "image") {
19
19
  const image = asString(part.image);
20
20
  if (image && isSafeImagePreviewUrl(image)) {
21
- const sizeBytes = image.startsWith("data:") ? estimateBase64Bytes(image.split(",", 2)[1] ?? image) : void 0;
21
+ const sizeBytes = /^data:/i.test(image) ? estimateBase64Bytes(image.split(",", 2)[1] ?? image) : void 0;
22
22
  return {
23
23
  previewUrl: image,
24
24
  ...sizeBytes !== void 0 ? { sizeBytes } : {}
@@ -1 +1 @@
1
- {"version":3,"file":"parseAttachment.js","names":["isRecord","estimateBase64Bytes","isSafeImagePreviewUrl","AttachmentPreview","AttachmentStatusPreview","asString","value","length","undefined","parseAttachmentStatus","type","reason","progress","mediaFromContent","content","previewUrl","sizeBytes","Array","isArray","part","image","startsWith","split","data","parseAttachment","name","filename","id","status","fromContent","kind","contentType","parseAttachments","map","item","filter","Boolean"],"sources":["../../../src/views/attachments/parseAttachment.ts"],"sourcesContent":["import { isRecord } from \"../../utils/common\";\nimport { estimateBase64Bytes, isSafeImagePreviewUrl } from \"./formatBytes\";\nimport type { AttachmentPreview, AttachmentStatusPreview } from \"./types\";\n\nconst asString = (value: unknown): string | undefined =>\n typeof value === \"string\" && value.length > 0 ? value : undefined;\n\nconst parseAttachmentStatus = (\n value: unknown,\n): AttachmentStatusPreview | undefined => {\n if (!isRecord(value) || typeof value.type !== \"string\") return undefined;\n return {\n type: value.type,\n ...(typeof value.reason === \"string\" ? { reason: value.reason } : {}),\n ...(typeof value.progress === \"number\" ? { progress: value.progress } : {}),\n };\n};\n\nconst mediaFromContent = (\n content: unknown,\n): { previewUrl?: string; sizeBytes?: number } => {\n if (!Array.isArray(content)) return {};\n for (const part of content) {\n if (!isRecord(part)) continue;\n const type = asString(part.type);\n if (type === \"image\") {\n const image = asString(part.image);\n if (image && isSafeImagePreviewUrl(image)) {\n const sizeBytes = image.startsWith(\"data:\")\n ? estimateBase64Bytes(image.split(\",\", 2)[1] ?? image)\n : undefined;\n return {\n previewUrl: image,\n ...(sizeBytes !== undefined ? { sizeBytes } : {}),\n };\n }\n }\n if (type === \"file\") {\n const data = asString(part.data);\n if (data) return { sizeBytes: estimateBase64Bytes(data) };\n }\n }\n return {};\n};\n\nexport const parseAttachment = (value: unknown): AttachmentPreview | null => {\n if (!isRecord(value)) return null;\n\n const name =\n asString(value.name) ??\n asString(value.filename) ??\n asString(value.id) ??\n \"(attachment)\";\n\n const status = parseAttachmentStatus(value.status);\n const fromContent = mediaFromContent(value.content);\n\n const image = asString(value.image);\n const previewUrl =\n fromContent.previewUrl ??\n (image && isSafeImagePreviewUrl(image) ? image : undefined);\n\n const data = asString(value.data);\n const sizeBytes =\n fromContent.sizeBytes ?? (data ? estimateBase64Bytes(data) : undefined);\n\n return {\n name,\n ...(asString(value.id) ? { id: asString(value.id)! } : {}),\n ...(asString(value.type) ? { kind: asString(value.type)! } : {}),\n ...(asString(value.contentType)\n ? { contentType: asString(value.contentType)! }\n : {}),\n ...(status ? { status } : {}),\n ...(previewUrl ? { previewUrl } : {}),\n ...(sizeBytes !== undefined ? { sizeBytes } : {}),\n };\n};\n\nexport const parseAttachments = (value: unknown): AttachmentPreview[] =>\n Array.isArray(value)\n ? value\n .map((item) => parseAttachment(item))\n .filter((item): item is AttachmentPreview => Boolean(item))\n : [];\n"],"mappings":";;;AAIA,MAAMK,YAAYC,UAChB,OAAOA,UAAU,YAAYA,MAAMC,SAAS,IAAID,QAAQE,KAAAA;AAE1D,MAAMC,yBACJH,UACwC;CACxC,IAAI,CAACN,SAASM,KAAK,KAAK,OAAOA,MAAMI,SAAS,UAAU,OAAOF,KAAAA;CAC/D,OAAO;EACLE,MAAMJ,MAAMI;EACZ,GAAI,OAAOJ,MAAMK,WAAW,WAAW,EAAEA,QAAQL,MAAMK,OAAO,IAAI,CAAC;EACnE,GAAI,OAAOL,MAAMM,aAAa,WAAW,EAAEA,UAAUN,MAAMM,SAAS,IAAI,CAAC;CAC3E;AACF;AAEA,MAAMC,oBACJC,YACgD;CAChD,IAAI,CAACG,MAAMC,QAAQJ,OAAO,GAAG,OAAO,CAAC;CACrC,KAAK,MAAMK,QAAQL,SAAS;EAC1B,IAAI,CAACd,SAASmB,IAAI,GAAG;EACrB,MAAMT,OAAOL,SAASc,KAAKT,IAAI;EAC/B,IAAIA,SAAS,SAAS;GACpB,MAAMU,QAAQf,SAASc,KAAKC,KAAK;GACjC,IAAIA,SAASlB,sBAAsBkB,KAAK,GAAG;IACzC,MAAMJ,YAAYI,MAAMC,WAAW,OAAO,IACtCpB,oBAAoBmB,MAAME,MAAM,KAAK,CAAC,CAAC,CAAC,MAAMF,KAAK,IACnDZ,KAAAA;IACJ,OAAO;KACLO,YAAYK;KACZ,GAAIJ,cAAcR,KAAAA,IAAY,EAAEQ,UAAU,IAAI,CAAC;IACjD;GACF;EACF;EACA,IAAIN,SAAS,QAAQ;GACnB,MAAMa,OAAOlB,SAASc,KAAKI,IAAI;GAC/B,IAAIA,MAAM,OAAO,EAAEP,WAAWf,oBAAoBsB,IAAI,EAAE;EAC1D;CACF;CACA,OAAO,CAAC;AACV;AAEA,MAAaC,mBAAmBlB,UAA6C;CAC3E,IAAI,CAACN,SAASM,KAAK,GAAG,OAAO;CAE7B,MAAMmB,OACJpB,SAASC,MAAMmB,IAAI,KACnBpB,SAASC,MAAMoB,QAAQ,KACvBrB,SAASC,MAAMqB,EAAE,KACjB;CAEF,MAAMC,SAASnB,sBAAsBH,MAAMsB,MAAM;CACjD,MAAMC,cAAchB,iBAAiBP,MAAMQ,OAAO;CAElD,MAAMM,QAAQf,SAASC,MAAMc,KAAK;CAClC,MAAML,aACJc,YAAYd,eACXK,SAASlB,sBAAsBkB,KAAK,IAAIA,QAAQZ,KAAAA;CAEnD,MAAMe,OAAOlB,SAASC,MAAMiB,IAAI;CAChC,MAAMP,YACJa,YAAYb,cAAcO,OAAOtB,oBAAoBsB,IAAI,IAAIf,KAAAA;CAE/D,OAAO;EACLiB;EACA,GAAIpB,SAASC,MAAMqB,EAAE,IAAI,EAAEA,IAAItB,SAASC,MAAMqB,EAAE,EAAG,IAAI,CAAC;EACxD,GAAItB,SAASC,MAAMI,IAAI,IAAI,EAAEoB,MAAMzB,SAASC,MAAMI,IAAI,EAAG,IAAI,CAAC;EAC9D,GAAIL,SAASC,MAAMyB,WAAW,IAC1B,EAAEA,aAAa1B,SAASC,MAAMyB,WAAW,EAAG,IAC5C,CAAC;EACL,GAAIH,SAAS,EAAEA,OAAO,IAAI,CAAC;EAC3B,GAAIb,aAAa,EAAEA,WAAW,IAAI,CAAC;EACnC,GAAIC,cAAcR,KAAAA,IAAY,EAAEQ,UAAU,IAAI,CAAC;CACjD;AACF;AAEA,MAAagB,oBAAoB1B,UAC/BW,MAAMC,QAAQZ,KAAK,IACfA,MACG2B,KAAKC,SAASV,gBAAgBU,IAAI,CAAC,CAAC,CACpCC,QAAQD,SAAoCE,QAAQF,IAAI,CAAC,IAC5D,CAAA"}
1
+ {"version":3,"file":"parseAttachment.js","names":["isRecord","estimateBase64Bytes","isSafeImagePreviewUrl","AttachmentPreview","AttachmentStatusPreview","asString","value","length","undefined","parseAttachmentStatus","type","reason","progress","mediaFromContent","content","previewUrl","sizeBytes","Array","isArray","part","image","test","split","data","parseAttachment","name","filename","id","status","fromContent","kind","contentType","parseAttachments","map","item","filter","Boolean"],"sources":["../../../src/views/attachments/parseAttachment.ts"],"sourcesContent":["import { isRecord } from \"../../utils/common\";\nimport { estimateBase64Bytes, isSafeImagePreviewUrl } from \"./formatBytes\";\nimport type { AttachmentPreview, AttachmentStatusPreview } from \"./types\";\n\nconst asString = (value: unknown): string | undefined =>\n typeof value === \"string\" && value.length > 0 ? value : undefined;\n\nconst parseAttachmentStatus = (\n value: unknown,\n): AttachmentStatusPreview | undefined => {\n if (!isRecord(value) || typeof value.type !== \"string\") return undefined;\n return {\n type: value.type,\n ...(typeof value.reason === \"string\" ? { reason: value.reason } : {}),\n ...(typeof value.progress === \"number\" ? { progress: value.progress } : {}),\n };\n};\n\nconst mediaFromContent = (\n content: unknown,\n): { previewUrl?: string; sizeBytes?: number } => {\n if (!Array.isArray(content)) return {};\n for (const part of content) {\n if (!isRecord(part)) continue;\n const type = asString(part.type);\n if (type === \"image\") {\n const image = asString(part.image);\n if (image && isSafeImagePreviewUrl(image)) {\n const sizeBytes = /^data:/i.test(image)\n ? estimateBase64Bytes(image.split(\",\", 2)[1] ?? image)\n : undefined;\n return {\n previewUrl: image,\n ...(sizeBytes !== undefined ? { sizeBytes } : {}),\n };\n }\n }\n if (type === \"file\") {\n const data = asString(part.data);\n if (data) return { sizeBytes: estimateBase64Bytes(data) };\n }\n }\n return {};\n};\n\nexport const parseAttachment = (value: unknown): AttachmentPreview | null => {\n if (!isRecord(value)) return null;\n\n const name =\n asString(value.name) ??\n asString(value.filename) ??\n asString(value.id) ??\n \"(attachment)\";\n\n const status = parseAttachmentStatus(value.status);\n const fromContent = mediaFromContent(value.content);\n\n const image = asString(value.image);\n const previewUrl =\n fromContent.previewUrl ??\n (image && isSafeImagePreviewUrl(image) ? image : undefined);\n\n const data = asString(value.data);\n const sizeBytes =\n fromContent.sizeBytes ?? (data ? estimateBase64Bytes(data) : undefined);\n\n return {\n name,\n ...(asString(value.id) ? { id: asString(value.id)! } : {}),\n ...(asString(value.type) ? { kind: asString(value.type)! } : {}),\n ...(asString(value.contentType)\n ? { contentType: asString(value.contentType)! }\n : {}),\n ...(status ? { status } : {}),\n ...(previewUrl ? { previewUrl } : {}),\n ...(sizeBytes !== undefined ? { sizeBytes } : {}),\n };\n};\n\nexport const parseAttachments = (value: unknown): AttachmentPreview[] =>\n Array.isArray(value)\n ? value\n .map((item) => parseAttachment(item))\n .filter((item): item is AttachmentPreview => Boolean(item))\n : [];\n"],"mappings":";;;AAIA,MAAMK,YAAYC,UAChB,OAAOA,UAAU,YAAYA,MAAMC,SAAS,IAAID,QAAQE,KAAAA;AAE1D,MAAMC,yBACJH,UACwC;CACxC,IAAI,CAACN,SAASM,KAAK,KAAK,OAAOA,MAAMI,SAAS,UAAU,OAAOF,KAAAA;CAC/D,OAAO;EACLE,MAAMJ,MAAMI;EACZ,GAAI,OAAOJ,MAAMK,WAAW,WAAW,EAAEA,QAAQL,MAAMK,OAAO,IAAI,CAAC;EACnE,GAAI,OAAOL,MAAMM,aAAa,WAAW,EAAEA,UAAUN,MAAMM,SAAS,IAAI,CAAC;CAC3E;AACF;AAEA,MAAMC,oBACJC,YACgD;CAChD,IAAI,CAACG,MAAMC,QAAQJ,OAAO,GAAG,OAAO,CAAC;CACrC,KAAK,MAAMK,QAAQL,SAAS;EAC1B,IAAI,CAACd,SAASmB,IAAI,GAAG;EACrB,MAAMT,OAAOL,SAASc,KAAKT,IAAI;EAC/B,IAAIA,SAAS,SAAS;GACpB,MAAMU,QAAQf,SAASc,KAAKC,KAAK;GACjC,IAAIA,SAASlB,sBAAsBkB,KAAK,GAAG;IACzC,MAAMJ,YAAY,UAAUK,KAAKD,KAAK,IAClCnB,oBAAoBmB,MAAME,MAAM,KAAK,CAAC,CAAC,CAAC,MAAMF,KAAK,IACnDZ,KAAAA;IACJ,OAAO;KACLO,YAAYK;KACZ,GAAIJ,cAAcR,KAAAA,IAAY,EAAEQ,UAAU,IAAI,CAAC;IACjD;GACF;EACF;EACA,IAAIN,SAAS,QAAQ;GACnB,MAAMa,OAAOlB,SAASc,KAAKI,IAAI;GAC/B,IAAIA,MAAM,OAAO,EAAEP,WAAWf,oBAAoBsB,IAAI,EAAE;EAC1D;CACF;CACA,OAAO,CAAC;AACV;AAEA,MAAaC,mBAAmBlB,UAA6C;CAC3E,IAAI,CAACN,SAASM,KAAK,GAAG,OAAO;CAE7B,MAAMmB,OACJpB,SAASC,MAAMmB,IAAI,KACnBpB,SAASC,MAAMoB,QAAQ,KACvBrB,SAASC,MAAMqB,EAAE,KACjB;CAEF,MAAMC,SAASnB,sBAAsBH,MAAMsB,MAAM;CACjD,MAAMC,cAAchB,iBAAiBP,MAAMQ,OAAO;CAElD,MAAMM,QAAQf,SAASC,MAAMc,KAAK;CAClC,MAAML,aACJc,YAAYd,eACXK,SAASlB,sBAAsBkB,KAAK,IAAIA,QAAQZ,KAAAA;CAEnD,MAAMe,OAAOlB,SAASC,MAAMiB,IAAI;CAChC,MAAMP,YACJa,YAAYb,cAAcO,OAAOtB,oBAAoBsB,IAAI,IAAIf,KAAAA;CAE/D,OAAO;EACLiB;EACA,GAAIpB,SAASC,MAAMqB,EAAE,IAAI,EAAEA,IAAItB,SAASC,MAAMqB,EAAE,EAAG,IAAI,CAAC;EACxD,GAAItB,SAASC,MAAMI,IAAI,IAAI,EAAEoB,MAAMzB,SAASC,MAAMI,IAAI,EAAG,IAAI,CAAC;EAC9D,GAAIL,SAASC,MAAMyB,WAAW,IAC1B,EAAEA,aAAa1B,SAASC,MAAMyB,WAAW,EAAG,IAC5C,CAAC;EACL,GAAIH,SAAS,EAAEA,OAAO,IAAI,CAAC;EAC3B,GAAIb,aAAa,EAAEA,WAAW,IAAI,CAAC;EACnC,GAAIC,cAAcR,KAAAA,IAAY,EAAEQ,UAAU,IAAI,CAAC;CACjD;AACF;AAEA,MAAagB,oBAAoB1B,UAC/BW,MAAMC,QAAQZ,KAAK,IACfA,MACG2B,KAAKC,SAASV,gBAAgBU,IAAI,CAAC,CAAC,CACpCC,QAAQD,SAAoCE,QAAQF,IAAI,CAAC,IAC5D,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"parse.d.ts","names":[],"sources":["../../../src/views/message/parse.ts"],"mappings":";;cAiBa,UAAW,MAAM,aAAa;cAK9B,kBACX,mBACC;cA2EU,YAAa,mBAAiB;cA0I9B,eACX,gBACA,kBACC"}
1
+ {"version":3,"file":"parse.d.ts","names":[],"sources":["../../../src/views/message/parse.ts"],"mappings":";;cAiBa,UAAW,MAAM,aAAa;cAK9B,kBACX,mBACC;cA2EU,YAAa,mBAAiB;cA2I9B,eACX,gBACA,kBACC"}
@@ -96,7 +96,7 @@ const parsePart = (value) => {
96
96
  const filename = asString(value.filename);
97
97
  const image = asString(value.image);
98
98
  const previewUrl = image && isSafeImagePreviewUrl(image) ? image : void 0;
99
- const sizeBytes = previewUrl?.startsWith("data:") ? estimateBase64Bytes(previewUrl.split(",", 2)[1] ?? previewUrl) : void 0;
99
+ const sizeBytes = previewUrl && /^data:/i.test(previewUrl) ? estimateBase64Bytes(previewUrl.split(",", 2)[1] ?? previewUrl) : void 0;
100
100
  return {
101
101
  type: "image",
102
102
  ...filename ? { filename } : {},
@@ -1 +1 @@
1
- {"version":3,"file":"parse.js","names":["parseAttachments","estimateBase64Bytes","isSafeImagePreviewUrl","asBool","asNumber","asString","isRecord","MessagePreview","MessageTimingPreview","MessageUsagePreview","PartPreview","PartStatusPreview","ToolCallApprovalPreview","ToolCallInterruptPreview","ToolCallPartPreview","partKey","part","index","type","toolCallId","parsePartStatus","value","undefined","reason","error","parseInterrupt","result","payload","Object","keys","length","parseApproval","id","approved","isAutomatic","parseToolCall","Record","base","status","argsText","isError","interrupt","approval","subMessageCount","Array","isArray","messages","toolName","args","artifact","mcp","modelContent","parsePart","rawType","raw","text","sourceType","title","url","filename","image","previewUrl","sizeBytes","startsWith","split","mimeType","data","audio","format","audioData","name","spec","parseTiming","streamStartTime","firstTokenTime","totalStreamTime","tokenCount","tokensPerSecond","totalChunks","toolCallCount","parseUsage","inputTokens","outputTokens","sawUsage","step","usage","input","output","stepCount","parseMessage","role","rawParts","parts","content","map","metadata","timing","steps","submittedFeedback","isOptimistic","createdAt","branchNumber","branchCount","messageIndex","attachments"],"sources":["../../../src/views/message/parse.ts"],"sourcesContent":["import { parseAttachments } from \"../attachments/parseAttachment\";\nimport {\n estimateBase64Bytes,\n isSafeImagePreviewUrl,\n} from \"../attachments/formatBytes\";\nimport { asBool, asNumber, asString, isRecord } from \"../../utils/common\";\nimport type {\n MessagePreview,\n MessageTimingPreview,\n MessageUsagePreview,\n PartPreview,\n PartStatusPreview,\n ToolCallApprovalPreview,\n ToolCallInterruptPreview,\n ToolCallPartPreview,\n} from \"./types\";\n\nexport const partKey = (part: PartPreview, index: number) =>\n part.type === \"tool-call\" && part.toolCallId\n ? `tc:${part.toolCallId}`\n : `p:${index}`;\n\nexport const parsePartStatus = (\n value: unknown,\n): PartStatusPreview | undefined => {\n if (!isRecord(value)) return undefined;\n const type = asString(value.type);\n if (!type) return undefined;\n const reason = asString(value.reason);\n return {\n type,\n ...(reason ? { reason } : {}),\n ...(\"error\" in value && value.error !== undefined\n ? { error: value.error }\n : {}),\n };\n};\n\nconst parseInterrupt = (\n value: unknown,\n): ToolCallInterruptPreview | undefined => {\n if (!isRecord(value)) return undefined;\n const type = asString(value.type);\n const result: ToolCallInterruptPreview = {\n ...(type ? { type } : {}),\n ...(\"payload\" in value ? { payload: value.payload } : {}),\n };\n return Object.keys(result).length > 0 ? result : undefined;\n};\n\nconst parseApproval = (value: unknown): ToolCallApprovalPreview | undefined => {\n if (!isRecord(value)) return undefined;\n const id = asString(value.id);\n const approved = asBool(value.approved);\n const reason = asString(value.reason);\n const isAutomatic = asBool(value.isAutomatic);\n const result: ToolCallApprovalPreview = {\n ...(id ? { id } : {}),\n ...(approved !== undefined ? { approved } : {}),\n ...(reason ? { reason } : {}),\n ...(isAutomatic !== undefined ? { isAutomatic } : {}),\n };\n return Object.keys(result).length > 0 ? result : undefined;\n};\n\nconst parseToolCall = (\n value: Record<string, unknown>,\n base: { status?: PartStatusPreview },\n): ToolCallPartPreview => {\n const argsText = asString(value.argsText);\n const isError = asBool(value.isError);\n const interrupt = parseInterrupt(value.interrupt);\n const approval = parseApproval(value.approval);\n const subMessageCount = Array.isArray(value.messages)\n ? value.messages.length\n : 0;\n\n return {\n type: \"tool-call\",\n toolCallId: asString(value.toolCallId) ?? \"\",\n toolName: asString(value.toolName) ?? \"(unknown)\",\n args: value.args,\n subMessageCount,\n ...(argsText !== undefined ? { argsText } : {}),\n ...(\"result\" in value && value.result !== undefined\n ? { result: value.result }\n : {}),\n ...(isError !== undefined ? { isError } : {}),\n ...(value.artifact !== undefined ? { artifact: value.artifact } : {}),\n ...(value.mcp !== undefined ? { mcp: value.mcp } : {}),\n ...(value.modelContent !== undefined\n ? { modelContent: value.modelContent }\n : {}),\n ...(interrupt ? { interrupt } : {}),\n ...(approval ? { approval } : {}),\n ...base,\n };\n};\n\nexport const parsePart = (value: unknown): PartPreview => {\n if (!isRecord(value)) {\n return { type: \"unknown\", rawType: typeof value, raw: value };\n }\n\n const status = parsePartStatus(value.status);\n const base = status ? { status } : {};\n const type = asString(value.type);\n\n switch (type) {\n case \"text\":\n return { type: \"text\", text: asString(value.text) ?? \"\", ...base };\n case \"reasoning\":\n return { type: \"reasoning\", text: asString(value.text) ?? \"\", ...base };\n case \"source\": {\n const sourceType = asString(value.sourceType);\n const title = asString(value.title);\n const url = asString(value.url);\n return {\n type: \"source\",\n ...(sourceType ? { sourceType } : {}),\n ...(title ? { title } : {}),\n ...(url ? { url } : {}),\n ...base,\n };\n }\n case \"image\": {\n const filename = asString(value.filename);\n const image = asString(value.image);\n const previewUrl =\n image && isSafeImagePreviewUrl(image) ? image : undefined;\n const sizeBytes = previewUrl?.startsWith(\"data:\")\n ? estimateBase64Bytes(previewUrl.split(\",\", 2)[1] ?? previewUrl)\n : undefined;\n return {\n type: \"image\",\n ...(filename ? { filename } : {}),\n ...(previewUrl ? { previewUrl } : {}),\n ...(sizeBytes !== undefined ? { sizeBytes } : {}),\n ...base,\n };\n }\n case \"file\": {\n const filename = asString(value.filename);\n const mimeType = asString(value.mimeType);\n const data = asString(value.data);\n const sizeBytes = data ? estimateBase64Bytes(data) : undefined;\n return {\n type: \"file\",\n ...(filename ? { filename } : {}),\n ...(mimeType ? { mimeType } : {}),\n ...(sizeBytes !== undefined ? { sizeBytes } : {}),\n ...base,\n };\n }\n case \"audio\": {\n const audio = isRecord(value.audio) ? value.audio : undefined;\n const format = asString(audio?.format);\n const audioData = asString(audio?.data);\n const sizeBytes = audioData ? estimateBase64Bytes(audioData) : undefined;\n return {\n type: \"audio\",\n ...(format ? { format } : {}),\n ...(sizeBytes !== undefined ? { sizeBytes } : {}),\n ...base,\n };\n }\n case \"data\": {\n const name = asString(value.name);\n return {\n type: \"data\",\n data: value.data,\n ...(name ? { name } : {}),\n ...base,\n };\n }\n case \"generative-ui\":\n return { type: \"generative-ui\", spec: value.spec, ...base };\n case \"tool-call\":\n return parseToolCall(value, base);\n default:\n return {\n type: \"unknown\",\n rawType: type ?? typeof value,\n raw: value,\n ...base,\n };\n }\n};\n\nconst parseTiming = (value: unknown): MessageTimingPreview | undefined => {\n if (!isRecord(value)) return undefined;\n\n const streamStartTime = asNumber(value.streamStartTime);\n const firstTokenTime = asNumber(value.firstTokenTime);\n const totalStreamTime = asNumber(value.totalStreamTime);\n const tokenCount = asNumber(value.tokenCount);\n const tokensPerSecond = asNumber(value.tokensPerSecond);\n const totalChunks = asNumber(value.totalChunks);\n const toolCallCount = asNumber(value.toolCallCount);\n\n const result: MessageTimingPreview = {\n ...(streamStartTime !== undefined ? { streamStartTime } : {}),\n ...(firstTokenTime !== undefined ? { firstTokenTime } : {}),\n ...(totalStreamTime !== undefined ? { totalStreamTime } : {}),\n ...(tokenCount !== undefined ? { tokenCount } : {}),\n ...(tokensPerSecond !== undefined ? { tokensPerSecond } : {}),\n ...(totalChunks !== undefined ? { totalChunks } : {}),\n ...(toolCallCount !== undefined ? { toolCallCount } : {}),\n };\n return Object.keys(result).length > 0 ? result : undefined;\n};\n\nconst parseUsage = (value: unknown): MessageUsagePreview | undefined => {\n if (!Array.isArray(value) || value.length === 0) return undefined;\n\n let inputTokens = 0;\n let outputTokens = 0;\n let sawUsage = false;\n\n for (const step of value) {\n if (!isRecord(step) || !isRecord(step.usage)) continue;\n const input = asNumber(step.usage.inputTokens);\n const output = asNumber(step.usage.outputTokens);\n if (input !== undefined) {\n inputTokens += input;\n sawUsage = true;\n }\n if (output !== undefined) {\n outputTokens += output;\n sawUsage = true;\n }\n }\n\n if (!sawUsage) return undefined;\n return { inputTokens, outputTokens, stepCount: value.length };\n};\n\nexport const parseMessage = (\n value: unknown,\n index: number,\n): MessagePreview | null => {\n if (!isRecord(value)) return null;\n\n const id = asString(value.id) ?? `message-${index}`;\n const role = asString(value.role) ?? \"unknown\";\n\n const rawParts = Array.isArray(value.parts)\n ? value.parts\n : Array.isArray(value.content)\n ? value.content\n : [];\n const parts = rawParts.map((part) => parsePart(part));\n\n const status = parsePartStatus(value.status);\n const metadata = isRecord(value.metadata) ? value.metadata : undefined;\n const timing = parseTiming(metadata?.timing);\n const usage = parseUsage(metadata?.steps);\n const submittedFeedback = isRecord(metadata?.submittedFeedback)\n ? asString(metadata.submittedFeedback.type)\n : undefined;\n const isOptimistic = asBool(metadata?.isOptimistic);\n const createdAt = asString(value.createdAt);\n const branchNumber = asNumber(value.branchNumber);\n const branchCount = asNumber(value.branchCount);\n const messageIndex = asNumber(value.index);\n\n return {\n id,\n role,\n parts,\n attachments: parseAttachments(value.attachments),\n ...(createdAt ? { createdAt } : {}),\n ...(status ? { status } : {}),\n ...(timing ? { timing } : {}),\n ...(usage ? { usage } : {}),\n ...(branchNumber !== undefined ? { branchNumber } : {}),\n ...(branchCount !== undefined ? { branchCount } : {}),\n ...(messageIndex !== undefined ? { index: messageIndex } : {}),\n ...(isOptimistic !== undefined ? { isOptimistic } : {}),\n ...(submittedFeedback ? { submittedFeedback } : {}),\n };\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"parse.js","names":["parseAttachments","estimateBase64Bytes","isSafeImagePreviewUrl","asBool","asNumber","asString","isRecord","MessagePreview","MessageTimingPreview","MessageUsagePreview","PartPreview","PartStatusPreview","ToolCallApprovalPreview","ToolCallInterruptPreview","ToolCallPartPreview","partKey","part","index","type","toolCallId","parsePartStatus","value","undefined","reason","error","parseInterrupt","result","payload","Object","keys","length","parseApproval","id","approved","isAutomatic","parseToolCall","Record","base","status","argsText","isError","interrupt","approval","subMessageCount","Array","isArray","messages","toolName","args","artifact","mcp","modelContent","parsePart","rawType","raw","text","sourceType","title","url","filename","image","previewUrl","sizeBytes","test","split","mimeType","data","audio","format","audioData","name","spec","parseTiming","streamStartTime","firstTokenTime","totalStreamTime","tokenCount","tokensPerSecond","totalChunks","toolCallCount","parseUsage","inputTokens","outputTokens","sawUsage","step","usage","input","output","stepCount","parseMessage","role","rawParts","parts","content","map","metadata","timing","steps","submittedFeedback","isOptimistic","createdAt","branchNumber","branchCount","messageIndex","attachments"],"sources":["../../../src/views/message/parse.ts"],"sourcesContent":["import { parseAttachments } from \"../attachments/parseAttachment\";\nimport {\n estimateBase64Bytes,\n isSafeImagePreviewUrl,\n} from \"../attachments/formatBytes\";\nimport { asBool, asNumber, asString, isRecord } from \"../../utils/common\";\nimport type {\n MessagePreview,\n MessageTimingPreview,\n MessageUsagePreview,\n PartPreview,\n PartStatusPreview,\n ToolCallApprovalPreview,\n ToolCallInterruptPreview,\n ToolCallPartPreview,\n} from \"./types\";\n\nexport const partKey = (part: PartPreview, index: number) =>\n part.type === \"tool-call\" && part.toolCallId\n ? `tc:${part.toolCallId}`\n : `p:${index}`;\n\nexport const parsePartStatus = (\n value: unknown,\n): PartStatusPreview | undefined => {\n if (!isRecord(value)) return undefined;\n const type = asString(value.type);\n if (!type) return undefined;\n const reason = asString(value.reason);\n return {\n type,\n ...(reason ? { reason } : {}),\n ...(\"error\" in value && value.error !== undefined\n ? { error: value.error }\n : {}),\n };\n};\n\nconst parseInterrupt = (\n value: unknown,\n): ToolCallInterruptPreview | undefined => {\n if (!isRecord(value)) return undefined;\n const type = asString(value.type);\n const result: ToolCallInterruptPreview = {\n ...(type ? { type } : {}),\n ...(\"payload\" in value ? { payload: value.payload } : {}),\n };\n return Object.keys(result).length > 0 ? result : undefined;\n};\n\nconst parseApproval = (value: unknown): ToolCallApprovalPreview | undefined => {\n if (!isRecord(value)) return undefined;\n const id = asString(value.id);\n const approved = asBool(value.approved);\n const reason = asString(value.reason);\n const isAutomatic = asBool(value.isAutomatic);\n const result: ToolCallApprovalPreview = {\n ...(id ? { id } : {}),\n ...(approved !== undefined ? { approved } : {}),\n ...(reason ? { reason } : {}),\n ...(isAutomatic !== undefined ? { isAutomatic } : {}),\n };\n return Object.keys(result).length > 0 ? result : undefined;\n};\n\nconst parseToolCall = (\n value: Record<string, unknown>,\n base: { status?: PartStatusPreview },\n): ToolCallPartPreview => {\n const argsText = asString(value.argsText);\n const isError = asBool(value.isError);\n const interrupt = parseInterrupt(value.interrupt);\n const approval = parseApproval(value.approval);\n const subMessageCount = Array.isArray(value.messages)\n ? value.messages.length\n : 0;\n\n return {\n type: \"tool-call\",\n toolCallId: asString(value.toolCallId) ?? \"\",\n toolName: asString(value.toolName) ?? \"(unknown)\",\n args: value.args,\n subMessageCount,\n ...(argsText !== undefined ? { argsText } : {}),\n ...(\"result\" in value && value.result !== undefined\n ? { result: value.result }\n : {}),\n ...(isError !== undefined ? { isError } : {}),\n ...(value.artifact !== undefined ? { artifact: value.artifact } : {}),\n ...(value.mcp !== undefined ? { mcp: value.mcp } : {}),\n ...(value.modelContent !== undefined\n ? { modelContent: value.modelContent }\n : {}),\n ...(interrupt ? { interrupt } : {}),\n ...(approval ? { approval } : {}),\n ...base,\n };\n};\n\nexport const parsePart = (value: unknown): PartPreview => {\n if (!isRecord(value)) {\n return { type: \"unknown\", rawType: typeof value, raw: value };\n }\n\n const status = parsePartStatus(value.status);\n const base = status ? { status } : {};\n const type = asString(value.type);\n\n switch (type) {\n case \"text\":\n return { type: \"text\", text: asString(value.text) ?? \"\", ...base };\n case \"reasoning\":\n return { type: \"reasoning\", text: asString(value.text) ?? \"\", ...base };\n case \"source\": {\n const sourceType = asString(value.sourceType);\n const title = asString(value.title);\n const url = asString(value.url);\n return {\n type: \"source\",\n ...(sourceType ? { sourceType } : {}),\n ...(title ? { title } : {}),\n ...(url ? { url } : {}),\n ...base,\n };\n }\n case \"image\": {\n const filename = asString(value.filename);\n const image = asString(value.image);\n const previewUrl =\n image && isSafeImagePreviewUrl(image) ? image : undefined;\n const sizeBytes =\n previewUrl && /^data:/i.test(previewUrl)\n ? estimateBase64Bytes(previewUrl.split(\",\", 2)[1] ?? previewUrl)\n : undefined;\n return {\n type: \"image\",\n ...(filename ? { filename } : {}),\n ...(previewUrl ? { previewUrl } : {}),\n ...(sizeBytes !== undefined ? { sizeBytes } : {}),\n ...base,\n };\n }\n case \"file\": {\n const filename = asString(value.filename);\n const mimeType = asString(value.mimeType);\n const data = asString(value.data);\n const sizeBytes = data ? estimateBase64Bytes(data) : undefined;\n return {\n type: \"file\",\n ...(filename ? { filename } : {}),\n ...(mimeType ? { mimeType } : {}),\n ...(sizeBytes !== undefined ? { sizeBytes } : {}),\n ...base,\n };\n }\n case \"audio\": {\n const audio = isRecord(value.audio) ? value.audio : undefined;\n const format = asString(audio?.format);\n const audioData = asString(audio?.data);\n const sizeBytes = audioData ? estimateBase64Bytes(audioData) : undefined;\n return {\n type: \"audio\",\n ...(format ? { format } : {}),\n ...(sizeBytes !== undefined ? { sizeBytes } : {}),\n ...base,\n };\n }\n case \"data\": {\n const name = asString(value.name);\n return {\n type: \"data\",\n data: value.data,\n ...(name ? { name } : {}),\n ...base,\n };\n }\n case \"generative-ui\":\n return { type: \"generative-ui\", spec: value.spec, ...base };\n case \"tool-call\":\n return parseToolCall(value, base);\n default:\n return {\n type: \"unknown\",\n rawType: type ?? typeof value,\n raw: value,\n ...base,\n };\n }\n};\n\nconst parseTiming = (value: unknown): MessageTimingPreview | undefined => {\n if (!isRecord(value)) return undefined;\n\n const streamStartTime = asNumber(value.streamStartTime);\n const firstTokenTime = asNumber(value.firstTokenTime);\n const totalStreamTime = asNumber(value.totalStreamTime);\n const tokenCount = asNumber(value.tokenCount);\n const tokensPerSecond = asNumber(value.tokensPerSecond);\n const totalChunks = asNumber(value.totalChunks);\n const toolCallCount = asNumber(value.toolCallCount);\n\n const result: MessageTimingPreview = {\n ...(streamStartTime !== undefined ? { streamStartTime } : {}),\n ...(firstTokenTime !== undefined ? { firstTokenTime } : {}),\n ...(totalStreamTime !== undefined ? { totalStreamTime } : {}),\n ...(tokenCount !== undefined ? { tokenCount } : {}),\n ...(tokensPerSecond !== undefined ? { tokensPerSecond } : {}),\n ...(totalChunks !== undefined ? { totalChunks } : {}),\n ...(toolCallCount !== undefined ? { toolCallCount } : {}),\n };\n return Object.keys(result).length > 0 ? result : undefined;\n};\n\nconst parseUsage = (value: unknown): MessageUsagePreview | undefined => {\n if (!Array.isArray(value) || value.length === 0) return undefined;\n\n let inputTokens = 0;\n let outputTokens = 0;\n let sawUsage = false;\n\n for (const step of value) {\n if (!isRecord(step) || !isRecord(step.usage)) continue;\n const input = asNumber(step.usage.inputTokens);\n const output = asNumber(step.usage.outputTokens);\n if (input !== undefined) {\n inputTokens += input;\n sawUsage = true;\n }\n if (output !== undefined) {\n outputTokens += output;\n sawUsage = true;\n }\n }\n\n if (!sawUsage) return undefined;\n return { inputTokens, outputTokens, stepCount: value.length };\n};\n\nexport const parseMessage = (\n value: unknown,\n index: number,\n): MessagePreview | null => {\n if (!isRecord(value)) return null;\n\n const id = asString(value.id) ?? `message-${index}`;\n const role = asString(value.role) ?? \"unknown\";\n\n const rawParts = Array.isArray(value.parts)\n ? value.parts\n : Array.isArray(value.content)\n ? value.content\n : [];\n const parts = rawParts.map((part) => parsePart(part));\n\n const status = parsePartStatus(value.status);\n const metadata = isRecord(value.metadata) ? value.metadata : undefined;\n const timing = parseTiming(metadata?.timing);\n const usage = parseUsage(metadata?.steps);\n const submittedFeedback = isRecord(metadata?.submittedFeedback)\n ? asString(metadata.submittedFeedback.type)\n : undefined;\n const isOptimistic = asBool(metadata?.isOptimistic);\n const createdAt = asString(value.createdAt);\n const branchNumber = asNumber(value.branchNumber);\n const branchCount = asNumber(value.branchCount);\n const messageIndex = asNumber(value.index);\n\n return {\n id,\n role,\n parts,\n attachments: parseAttachments(value.attachments),\n ...(createdAt ? { createdAt } : {}),\n ...(status ? { status } : {}),\n ...(timing ? { timing } : {}),\n ...(usage ? { usage } : {}),\n ...(branchNumber !== undefined ? { branchNumber } : {}),\n ...(branchCount !== undefined ? { branchCount } : {}),\n ...(messageIndex !== undefined ? { index: messageIndex } : {}),\n ...(isOptimistic !== undefined ? { isOptimistic } : {}),\n ...(submittedFeedback ? { submittedFeedback } : {}),\n };\n};\n"],"mappings":";;;;AAiBA,MAAae,WAAWC,MAAmBC,UACzCD,KAAKE,SAAS,eAAeF,KAAKG,aAC9B,MAAMH,KAAKG,eACX,KAAKF;AAEX,MAAaG,mBACXC,UACkC;CAClC,IAAI,CAACf,SAASe,KAAK,GAAG,OAAOC,KAAAA;CAC7B,MAAMJ,OAAOb,SAASgB,MAAMH,IAAI;CAChC,IAAI,CAACA,MAAM,OAAOI,KAAAA;CAClB,MAAMC,SAASlB,SAASgB,MAAME,MAAM;CACpC,OAAO;EACLL;EACA,GAAIK,SAAS,EAAEA,OAAO,IAAI,CAAC;EAC3B,GAAI,WAAWF,SAASA,MAAMG,UAAUF,KAAAA,IACpC,EAAEE,OAAOH,MAAMG,MAAM,IACrB,CAAC;CACP;AACF;AAEA,MAAMC,kBACJJ,UACyC;CACzC,IAAI,CAACf,SAASe,KAAK,GAAG,OAAOC,KAAAA;CAC7B,MAAMJ,OAAOb,SAASgB,MAAMH,IAAI;CAChC,MAAMQ,SAAmC;EACvC,GAAIR,OAAO,EAAEA,KAAK,IAAI,CAAC;EACvB,GAAI,aAAaG,QAAQ,EAAEM,SAASN,MAAMM,QAAQ,IAAI,CAAC;CACzD;CACA,OAAOC,OAAOC,KAAKH,MAAM,CAAC,CAACI,SAAS,IAAIJ,SAASJ,KAAAA;AACnD;AAEA,MAAMS,iBAAiBV,UAAwD;CAC7E,IAAI,CAACf,SAASe,KAAK,GAAG,OAAOC,KAAAA;CAC7B,MAAMU,KAAK3B,SAASgB,MAAMW,EAAE;CAC5B,MAAMC,WAAW9B,OAAOkB,MAAMY,QAAQ;CACtC,MAAMV,SAASlB,SAASgB,MAAME,MAAM;CACpC,MAAMW,cAAc/B,OAAOkB,MAAMa,WAAW;CAC5C,MAAMR,SAAkC;EACtC,GAAIM,KAAK,EAAEA,GAAG,IAAI,CAAC;EACnB,GAAIC,aAAaX,KAAAA,IAAY,EAAEW,SAAS,IAAI,CAAC;EAC7C,GAAIV,SAAS,EAAEA,OAAO,IAAI,CAAC;EAC3B,GAAIW,gBAAgBZ,KAAAA,IAAY,EAAEY,YAAY,IAAI,CAAC;CACrD;CACA,OAAON,OAAOC,KAAKH,MAAM,CAAC,CAACI,SAAS,IAAIJ,SAASJ,KAAAA;AACnD;AAEA,MAAMa,iBACJd,OACAgB,SACwB;CACxB,MAAME,WAAWlC,SAASgB,MAAMkB,QAAQ;CACxC,MAAMC,UAAUrC,OAAOkB,MAAMmB,OAAO;CACpC,MAAMC,YAAYhB,eAAeJ,MAAMoB,SAAS;CAChD,MAAMC,WAAWX,cAAcV,MAAMqB,QAAQ;CAC7C,MAAMC,kBAAkBC,MAAMC,QAAQxB,MAAMyB,QAAQ,IAChDzB,MAAMyB,SAAShB,SACf;CAEJ,OAAO;EACLZ,MAAM;EACNC,YAAYd,SAASgB,MAAMF,UAAU,KAAK;EAC1C4B,UAAU1C,SAASgB,MAAM0B,QAAQ,KAAK;EACtCC,MAAM3B,MAAM2B;EACZL;EACA,GAAIJ,aAAajB,KAAAA,IAAY,EAAEiB,SAAS,IAAI,CAAC;EAC7C,GAAI,YAAYlB,SAASA,MAAMK,WAAWJ,KAAAA,IACtC,EAAEI,QAAQL,MAAMK,OAAO,IACvB,CAAC;EACL,GAAIc,YAAYlB,KAAAA,IAAY,EAAEkB,QAAQ,IAAI,CAAC;EAC3C,GAAInB,MAAM4B,aAAa3B,KAAAA,IAAY,EAAE2B,UAAU5B,MAAM4B,SAAS,IAAI,CAAC;EACnE,GAAI5B,MAAM6B,QAAQ5B,KAAAA,IAAY,EAAE4B,KAAK7B,MAAM6B,IAAI,IAAI,CAAC;EACpD,GAAI7B,MAAM8B,iBAAiB7B,KAAAA,IACvB,EAAE6B,cAAc9B,MAAM8B,aAAa,IACnC,CAAC;EACL,GAAIV,YAAY,EAAEA,UAAU,IAAI,CAAC;EACjC,GAAIC,WAAW,EAAEA,SAAS,IAAI,CAAC;EAC/B,GAAGL;CACL;AACF;AAEA,MAAae,aAAa/B,UAAgC;CACxD,IAAI,CAACf,SAASe,KAAK,GACjB,OAAO;EAAEH,MAAM;EAAWmC,SAAS,OAAOhC;EAAOiC,KAAKjC;CAAM;CAG9D,MAAMiB,SAASlB,gBAAgBC,MAAMiB,MAAM;CAC3C,MAAMD,OAAOC,SAAS,EAAEA,OAAO,IAAI,CAAC;CACpC,MAAMpB,OAAOb,SAASgB,MAAMH,IAAI;CAEhC,QAAQA,MAAR;EACE,KAAK,QACH,OAAO;GAAEA,MAAM;GAAQqC,MAAMlD,SAASgB,MAAMkC,IAAI,KAAK;GAAI,GAAGlB;EAAK;EACnE,KAAK,aACH,OAAO;GAAEnB,MAAM;GAAaqC,MAAMlD,SAASgB,MAAMkC,IAAI,KAAK;GAAI,GAAGlB;EAAK;EACxE,KAAK,UAAU;GACb,MAAMmB,aAAanD,SAASgB,MAAMmC,UAAU;GAC5C,MAAMC,QAAQpD,SAASgB,MAAMoC,KAAK;GAClC,MAAMC,MAAMrD,SAASgB,MAAMqC,GAAG;GAC9B,OAAO;IACLxC,MAAM;IACN,GAAIsC,aAAa,EAAEA,WAAW,IAAI,CAAC;IACnC,GAAIC,QAAQ,EAAEA,MAAM,IAAI,CAAC;IACzB,GAAIC,MAAM,EAAEA,IAAI,IAAI,CAAC;IACrB,GAAGrB;GACL;EACF;EACA,KAAK,SAAS;GACZ,MAAMsB,WAAWtD,SAASgB,MAAMsC,QAAQ;GACxC,MAAMC,QAAQvD,SAASgB,MAAMuC,KAAK;GAClC,MAAMC,aACJD,SAAS1D,sBAAsB0D,KAAK,IAAIA,QAAQtC,KAAAA;GAClD,MAAMwC,YACJD,cAAc,UAAUE,KAAKF,UAAU,IACnC5D,oBAAoB4D,WAAWG,MAAM,KAAK,CAAC,CAAC,CAAC,MAAMH,UAAU,IAC7DvC,KAAAA;GACN,OAAO;IACLJ,MAAM;IACN,GAAIyC,WAAW,EAAEA,SAAS,IAAI,CAAC;IAC/B,GAAIE,aAAa,EAAEA,WAAW,IAAI,CAAC;IACnC,GAAIC,cAAcxC,KAAAA,IAAY,EAAEwC,UAAU,IAAI,CAAC;IAC/C,GAAGzB;GACL;EACF;EACA,KAAK,QAAQ;GACX,MAAMsB,WAAWtD,SAASgB,MAAMsC,QAAQ;GACxC,MAAMM,WAAW5D,SAASgB,MAAM4C,QAAQ;GACxC,MAAMC,OAAO7D,SAASgB,MAAM6C,IAAI;GAChC,MAAMJ,YAAYI,OAAOjE,oBAAoBiE,IAAI,IAAI5C,KAAAA;GACrD,OAAO;IACLJ,MAAM;IACN,GAAIyC,WAAW,EAAEA,SAAS,IAAI,CAAC;IAC/B,GAAIM,WAAW,EAAEA,SAAS,IAAI,CAAC;IAC/B,GAAIH,cAAcxC,KAAAA,IAAY,EAAEwC,UAAU,IAAI,CAAC;IAC/C,GAAGzB;GACL;EACF;EACA,KAAK,SAAS;GACZ,MAAM8B,QAAQ7D,SAASe,MAAM8C,KAAK,IAAI9C,MAAM8C,QAAQ7C,KAAAA;GACpD,MAAM8C,SAAS/D,SAAS8D,OAAOC,MAAM;GACrC,MAAMC,YAAYhE,SAAS8D,OAAOD,IAAI;GACtC,MAAMJ,YAAYO,YAAYpE,oBAAoBoE,SAAS,IAAI/C,KAAAA;GAC/D,OAAO;IACLJ,MAAM;IACN,GAAIkD,SAAS,EAAEA,OAAO,IAAI,CAAC;IAC3B,GAAIN,cAAcxC,KAAAA,IAAY,EAAEwC,UAAU,IAAI,CAAC;IAC/C,GAAGzB;GACL;EACF;EACA,KAAK,QAAQ;GACX,MAAMiC,OAAOjE,SAASgB,MAAMiD,IAAI;GAChC,OAAO;IACLpD,MAAM;IACNgD,MAAM7C,MAAM6C;IACZ,GAAII,OAAO,EAAEA,KAAK,IAAI,CAAC;IACvB,GAAGjC;GACL;EACF;EACA,KAAK,iBACH,OAAO;GAAEnB,MAAM;GAAiBqD,MAAMlD,MAAMkD;GAAM,GAAGlC;EAAK;EAC5D,KAAK,aACH,OAAOF,cAAcd,OAAOgB,IAAI;EAClC,SACE,OAAO;GACLnB,MAAM;GACNmC,SAASnC,QAAQ,OAAOG;GACxBiC,KAAKjC;GACL,GAAGgB;EACL;CACJ;AACF;AAEA,MAAMmC,eAAenD,UAAqD;CACxE,IAAI,CAACf,SAASe,KAAK,GAAG,OAAOC,KAAAA;CAE7B,MAAMmD,kBAAkBrE,SAASiB,MAAMoD,eAAe;CACtD,MAAMC,iBAAiBtE,SAASiB,MAAMqD,cAAc;CACpD,MAAMC,kBAAkBvE,SAASiB,MAAMsD,eAAe;CACtD,MAAMC,aAAaxE,SAASiB,MAAMuD,UAAU;CAC5C,MAAMC,kBAAkBzE,SAASiB,MAAMwD,eAAe;CACtD,MAAMC,cAAc1E,SAASiB,MAAMyD,WAAW;CAC9C,MAAMC,gBAAgB3E,SAASiB,MAAM0D,aAAa;CAElD,MAAMrD,SAA+B;EACnC,GAAI+C,oBAAoBnD,KAAAA,IAAY,EAAEmD,gBAAgB,IAAI,CAAC;EAC3D,GAAIC,mBAAmBpD,KAAAA,IAAY,EAAEoD,eAAe,IAAI,CAAC;EACzD,GAAIC,oBAAoBrD,KAAAA,IAAY,EAAEqD,gBAAgB,IAAI,CAAC;EAC3D,GAAIC,eAAetD,KAAAA,IAAY,EAAEsD,WAAW,IAAI,CAAC;EACjD,GAAIC,oBAAoBvD,KAAAA,IAAY,EAAEuD,gBAAgB,IAAI,CAAC;EAC3D,GAAIC,gBAAgBxD,KAAAA,IAAY,EAAEwD,YAAY,IAAI,CAAC;EACnD,GAAIC,kBAAkBzD,KAAAA,IAAY,EAAEyD,cAAc,IAAI,CAAC;CACzD;CACA,OAAOnD,OAAOC,KAAKH,MAAM,CAAC,CAACI,SAAS,IAAIJ,SAASJ,KAAAA;AACnD;AAEA,MAAM0D,cAAc3D,UAAoD;CACtE,IAAI,CAACuB,MAAMC,QAAQxB,KAAK,KAAKA,MAAMS,WAAW,GAAG,OAAOR,KAAAA;CAExD,IAAI2D,cAAc;CAClB,IAAIC,eAAe;CACnB,IAAIC,WAAW;CAEf,KAAK,MAAMC,QAAQ/D,OAAO;EACxB,IAAI,CAACf,SAAS8E,IAAI,KAAK,CAAC9E,SAAS8E,KAAKC,KAAK,GAAG;EAC9C,MAAMC,QAAQlF,SAASgF,KAAKC,MAAMJ,WAAW;EAC7C,MAAMM,SAASnF,SAASgF,KAAKC,MAAMH,YAAY;EAC/C,IAAII,UAAUhE,KAAAA,GAAW;GACvB2D,eAAeK;GACfH,WAAW;EACb;EACA,IAAII,WAAWjE,KAAAA,GAAW;GACxB4D,gBAAgBK;GAChBJ,WAAW;EACb;CACF;CAEA,IAAI,CAACA,UAAU,OAAO7D,KAAAA;CACtB,OAAO;EAAE2D;EAAaC;EAAcM,WAAWnE,MAAMS;CAAO;AAC9D;AAEA,MAAa2D,gBACXpE,OACAJ,UAC0B;CAC1B,IAAI,CAACX,SAASe,KAAK,GAAG,OAAO;CAE7B,MAAMW,KAAK3B,SAASgB,MAAMW,EAAE,KAAK,WAAWf;CAC5C,MAAMyE,OAAOrF,SAASgB,MAAMqE,IAAI,KAAK;CAOrC,MAAME,SALWhD,MAAMC,QAAQxB,MAAMuE,KAAK,IACtCvE,MAAMuE,QACNhD,MAAMC,QAAQxB,MAAMwE,OAAO,IACzBxE,MAAMwE,UACN,CAAA,EAAA,CACiBC,KAAK9E,SAASoC,UAAUpC,IAAI,CAAC;CAEpD,MAAMsB,SAASlB,gBAAgBC,MAAMiB,MAAM;CAC3C,MAAMyD,WAAWzF,SAASe,MAAM0E,QAAQ,IAAI1E,MAAM0E,WAAWzE,KAAAA;CAC7D,MAAM0E,SAASxB,YAAYuB,UAAUC,MAAM;CAC3C,MAAMX,QAAQL,WAAWe,UAAUE,KAAK;CACxC,MAAMC,oBAAoB5F,SAASyF,UAAUG,iBAAiB,IAC1D7F,SAAS0F,SAASG,kBAAkBhF,IAAI,IACxCI,KAAAA;CACJ,MAAM6E,eAAehG,OAAO4F,UAAUI,YAAY;CAClD,MAAMC,YAAY/F,SAASgB,MAAM+E,SAAS;CAC1C,MAAMC,eAAejG,SAASiB,MAAMgF,YAAY;CAChD,MAAMC,cAAclG,SAASiB,MAAMiF,WAAW;CAC9C,MAAMC,eAAenG,SAASiB,MAAMJ,KAAK;CAEzC,OAAO;EACLe;EACA0D;EACAE;EACAY,aAAaxG,iBAAiBqB,MAAMmF,WAAW;EAC/C,GAAIJ,YAAY,EAAEA,UAAU,IAAI,CAAC;EACjC,GAAI9D,SAAS,EAAEA,OAAO,IAAI,CAAC;EAC3B,GAAI0D,SAAS,EAAEA,OAAO,IAAI,CAAC;EAC3B,GAAIX,QAAQ,EAAEA,MAAM,IAAI,CAAC;EACzB,GAAIgB,iBAAiB/E,KAAAA,IAAY,EAAE+E,aAAa,IAAI,CAAC;EACrD,GAAIC,gBAAgBhF,KAAAA,IAAY,EAAEgF,YAAY,IAAI,CAAC;EACnD,GAAIC,iBAAiBjF,KAAAA,IAAY,EAAEL,OAAOsF,aAAa,IAAI,CAAC;EAC5D,GAAIJ,iBAAiB7E,KAAAA,IAAY,EAAE6E,aAAa,IAAI,CAAC;EACrD,GAAID,oBAAoB,EAAEA,kBAAkB,IAAI,CAAC;CACnD;AACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@assistant-ui/react-devtools",
3
- "version": "1.2.11",
3
+ "version": "1.2.13",
4
4
  "description": "React development tools for assistant-ui components",
5
5
  "keywords": [
6
6
  "assistant-ui",
@@ -48,16 +48,16 @@
48
48
  },
49
49
  "devDependencies": {
50
50
  "@tailwindcss/cli": "^4.3.3",
51
- "@types/node": "^26.1.1",
52
- "@types/react": "^19.2.17",
53
- "@types/react-dom": "^19.2.3",
51
+ "@types/node": "^26.1.2",
52
+ "@types/react": "^19.2.18",
53
+ "@types/react-dom": "^19.2.4",
54
54
  "react": "^19.2.8",
55
55
  "react-dom": "^19.2.8",
56
56
  "tailwindcss": "^4.3.3",
57
57
  "vitest": "^4.1.10",
58
- "@assistant-ui/tap": "0.9.7",
59
- "@assistant-ui/react": "0.15.0",
60
- "@assistant-ui/x-buildutils": "0.0.20"
58
+ "@assistant-ui/react": "0.15.11",
59
+ "@assistant-ui/tap": "0.9.11",
60
+ "@assistant-ui/x-buildutils": "0.0.22"
61
61
  },
62
62
  "publishConfig": {
63
63
  "access": "public",
@@ -10,6 +10,4 @@ export const estimateBase64Bytes = (data: string): number =>
10
10
  Math.max(0, Math.floor((data.length * 3) / 4));
11
11
 
12
12
  export const isSafeImagePreviewUrl = (url: string): boolean =>
13
- url.startsWith("data:image/") ||
14
- url.startsWith("https://") ||
15
- url.startsWith("http://");
13
+ /^data:image\//i.test(url) || /^https?:\/\//i.test(url);
@@ -34,4 +34,29 @@ describe("parseAttachment", () => {
34
34
  expect(result?.previewUrl).toBe("data:image/png;base64,abcd");
35
35
  expect(result?.sizeBytes).toBeGreaterThan(0);
36
36
  });
37
+
38
+ it("extracts preview and size for an uppercase data: scheme", () => {
39
+ const result = parseAttachment({
40
+ name: "shot.png",
41
+ type: "image",
42
+ content: [
43
+ {
44
+ type: "image",
45
+ image: "DATA:IMAGE/PNG;base64,abcd",
46
+ },
47
+ ],
48
+ });
49
+ expect(result?.previewUrl).toBe("DATA:IMAGE/PNG;base64,abcd");
50
+ expect(result?.sizeBytes).toBeGreaterThan(0);
51
+ });
52
+
53
+ it("accepts an uppercase HTTPS preview URL without a size estimate", () => {
54
+ const result = parseAttachment({
55
+ name: "remote.png",
56
+ type: "image",
57
+ image: "HTTPS://example.com/pic.png",
58
+ });
59
+ expect(result?.previewUrl).toBe("HTTPS://example.com/pic.png");
60
+ expect(result?.sizeBytes).toBeUndefined();
61
+ });
37
62
  });
@@ -26,7 +26,7 @@ const mediaFromContent = (
26
26
  if (type === "image") {
27
27
  const image = asString(part.image);
28
28
  if (image && isSafeImagePreviewUrl(image)) {
29
- const sizeBytes = image.startsWith("data:")
29
+ const sizeBytes = /^data:/i.test(image)
30
30
  ? estimateBase64Bytes(image.split(",", 2)[1] ?? image)
31
31
  : undefined;
32
32
  return {
@@ -99,6 +99,21 @@ describe("parsePart", () => {
99
99
  expect(part.subMessageCount).toBe(2);
100
100
  });
101
101
 
102
+ it("parses an image part with an uppercase data: scheme", () => {
103
+ const part = parsePart({
104
+ type: "image",
105
+ image: "DATA:IMAGE/PNG;base64,abcd",
106
+ filename: "shot.png",
107
+ });
108
+ expect(part).toMatchObject({
109
+ type: "image",
110
+ filename: "shot.png",
111
+ previewUrl: "DATA:IMAGE/PNG;base64,abcd",
112
+ });
113
+ if (part.type !== "image") return;
114
+ expect(part.sizeBytes).toBeGreaterThan(0);
115
+ });
116
+
102
117
  it("falls back to unknown for unrecognized part types", () => {
103
118
  const part = parsePart({ type: "mystery", foo: 1 });
104
119
  expect(part.type).toBe("unknown");
@@ -128,9 +128,10 @@ export const parsePart = (value: unknown): PartPreview => {
128
128
  const image = asString(value.image);
129
129
  const previewUrl =
130
130
  image && isSafeImagePreviewUrl(image) ? image : undefined;
131
- const sizeBytes = previewUrl?.startsWith("data:")
132
- ? estimateBase64Bytes(previewUrl.split(",", 2)[1] ?? previewUrl)
133
- : undefined;
131
+ const sizeBytes =
132
+ previewUrl && /^data:/i.test(previewUrl)
133
+ ? estimateBase64Bytes(previewUrl.split(",", 2)[1] ?? previewUrl)
134
+ : undefined;
134
135
  return {
135
136
  type: "image",
136
137
  ...(filename ? { filename } : {}),