@runtypelabs/persona 3.20.0 → 3.21.0
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/dist/animations/glyph-cycle.d.cts +1 -1
- package/dist/animations/glyph-cycle.d.ts +1 -1
- package/dist/animations/{types-cwY5HaFD.d.cts → types-CWPIj66R.d.cts} +19 -1
- package/dist/animations/{types-cwY5HaFD.d.ts → types-CWPIj66R.d.ts} +19 -1
- package/dist/animations/wipe.d.cts +1 -1
- package/dist/animations/wipe.d.ts +1 -1
- package/dist/index.cjs +46 -46
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +19 -1
- package/dist/index.d.ts +19 -1
- package/dist/index.global.js +72 -72
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +46 -46
- package/dist/index.js.map +1 -1
- package/dist/theme-editor.cjs +260 -0
- package/dist/theme-editor.d.cts +19 -1
- package/dist/theme-editor.d.ts +19 -1
- package/dist/theme-editor.js +260 -0
- package/package.json +1 -1
- package/src/client.test.ts +521 -0
- package/src/client.ts +150 -1
- package/src/components/message-bubble.test.ts +192 -0
- package/src/components/message-bubble.ts +200 -0
- package/src/types.ts +27 -2
package/dist/theme-editor.cjs
CHANGED
|
@@ -3790,6 +3790,28 @@ var SequenceReorderBuffer = class {
|
|
|
3790
3790
|
// src/client.ts
|
|
3791
3791
|
var DEFAULT_ENDPOINT = "https://api.runtype.com/v1/dispatch";
|
|
3792
3792
|
var DEFAULT_CLIENT_API_BASE = "https://api.runtype.com";
|
|
3793
|
+
function filenameFromMediaType(mediaType) {
|
|
3794
|
+
var _a, _b;
|
|
3795
|
+
const lower = mediaType.toLowerCase();
|
|
3796
|
+
const knownExtensions = {
|
|
3797
|
+
"application/pdf": "pdf",
|
|
3798
|
+
"application/json": "json",
|
|
3799
|
+
"application/zip": "zip",
|
|
3800
|
+
"text/plain": "txt",
|
|
3801
|
+
"text/csv": "csv",
|
|
3802
|
+
"text/markdown": "md"
|
|
3803
|
+
};
|
|
3804
|
+
const ext = knownExtensions[lower];
|
|
3805
|
+
if (ext) return `attachment.${ext}`;
|
|
3806
|
+
const slash = lower.indexOf("/");
|
|
3807
|
+
if (slash > 0) {
|
|
3808
|
+
const subtype = (_b = (_a = lower.slice(slash + 1).split(";")[0]) == null ? void 0 : _a.trim()) != null ? _b : "";
|
|
3809
|
+
if (subtype && subtype !== "octet-stream" && /^[a-z0-9.+-]+$/i.test(subtype)) {
|
|
3810
|
+
return `attachment.${subtype}`;
|
|
3811
|
+
}
|
|
3812
|
+
}
|
|
3813
|
+
return "attachment";
|
|
3814
|
+
}
|
|
3793
3815
|
var hasValidContent = (message) => {
|
|
3794
3816
|
if (message.contentParts && message.contentParts.length > 0) {
|
|
3795
3817
|
return true;
|
|
@@ -5742,6 +5764,89 @@ var AgentWidgetClient = class {
|
|
|
5742
5764
|
}
|
|
5743
5765
|
}
|
|
5744
5766
|
}
|
|
5767
|
+
} else if (payloadType === "agent_media") {
|
|
5768
|
+
const rawMedia = Array.isArray(payload.media) ? payload.media : [];
|
|
5769
|
+
const mediaContentParts = [];
|
|
5770
|
+
for (const part of rawMedia) {
|
|
5771
|
+
if (!part || typeof part !== "object") continue;
|
|
5772
|
+
const rec = part;
|
|
5773
|
+
const partType = typeof rec.type === "string" ? rec.type : void 0;
|
|
5774
|
+
const rawMediaType = typeof rec.mediaType === "string" ? rec.mediaType.toLowerCase() : "";
|
|
5775
|
+
let src = null;
|
|
5776
|
+
let mediaType = "";
|
|
5777
|
+
if (partType === "media") {
|
|
5778
|
+
const data = typeof rec.data === "string" ? rec.data : void 0;
|
|
5779
|
+
if (!data) continue;
|
|
5780
|
+
mediaType = rawMediaType.length > 0 ? rawMediaType : "application/octet-stream";
|
|
5781
|
+
src = `data:${mediaType};base64,${data}`;
|
|
5782
|
+
} else if (partType === "image-url") {
|
|
5783
|
+
const url = typeof rec.url === "string" ? rec.url : void 0;
|
|
5784
|
+
if (!url) continue;
|
|
5785
|
+
mediaType = rawMediaType;
|
|
5786
|
+
src = url;
|
|
5787
|
+
} else if (partType === "file-url") {
|
|
5788
|
+
const url = typeof rec.url === "string" ? rec.url : void 0;
|
|
5789
|
+
if (!url) continue;
|
|
5790
|
+
mediaType = rawMediaType;
|
|
5791
|
+
src = url;
|
|
5792
|
+
} else {
|
|
5793
|
+
continue;
|
|
5794
|
+
}
|
|
5795
|
+
if (!src) continue;
|
|
5796
|
+
if (partType === "image-url" || mediaType.startsWith("image/")) {
|
|
5797
|
+
mediaContentParts.push({
|
|
5798
|
+
type: "image",
|
|
5799
|
+
image: src,
|
|
5800
|
+
...mediaType ? { mimeType: mediaType } : {}
|
|
5801
|
+
});
|
|
5802
|
+
} else if (mediaType.startsWith("audio/")) {
|
|
5803
|
+
mediaContentParts.push({
|
|
5804
|
+
type: "audio",
|
|
5805
|
+
audio: src,
|
|
5806
|
+
mimeType: mediaType
|
|
5807
|
+
});
|
|
5808
|
+
} else if (mediaType.startsWith("video/")) {
|
|
5809
|
+
mediaContentParts.push({
|
|
5810
|
+
type: "video",
|
|
5811
|
+
video: src,
|
|
5812
|
+
mimeType: mediaType
|
|
5813
|
+
});
|
|
5814
|
+
} else {
|
|
5815
|
+
const resolvedMediaType = mediaType || "application/octet-stream";
|
|
5816
|
+
mediaContentParts.push({
|
|
5817
|
+
type: "file",
|
|
5818
|
+
data: src,
|
|
5819
|
+
mimeType: resolvedMediaType,
|
|
5820
|
+
filename: filenameFromMediaType(resolvedMediaType)
|
|
5821
|
+
});
|
|
5822
|
+
}
|
|
5823
|
+
}
|
|
5824
|
+
if (mediaContentParts.length > 0) {
|
|
5825
|
+
const seq = nextSequence();
|
|
5826
|
+
const toolCallIdRaw = payload.toolCallId;
|
|
5827
|
+
const mediaIdSuffix = typeof toolCallIdRaw === "string" && toolCallIdRaw.length > 0 ? `${toolCallIdRaw}-${seq}` : String(seq);
|
|
5828
|
+
const mediaMessage = {
|
|
5829
|
+
id: `agent-media-${mediaIdSuffix}`,
|
|
5830
|
+
role: "assistant",
|
|
5831
|
+
content: "",
|
|
5832
|
+
contentParts: mediaContentParts,
|
|
5833
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
5834
|
+
streaming: false,
|
|
5835
|
+
sequence: seq,
|
|
5836
|
+
agentMetadata: {
|
|
5837
|
+
executionId: payload.executionId,
|
|
5838
|
+
iteration: payload.iteration
|
|
5839
|
+
}
|
|
5840
|
+
};
|
|
5841
|
+
emitMessage(mediaMessage);
|
|
5842
|
+
const prevAssistant = assistantMessage;
|
|
5843
|
+
if (prevAssistant) {
|
|
5844
|
+
prevAssistant.streaming = false;
|
|
5845
|
+
emitMessage(prevAssistant);
|
|
5846
|
+
}
|
|
5847
|
+
assistantMessage = null;
|
|
5848
|
+
assistantMessageRef.current = null;
|
|
5849
|
+
}
|
|
5745
5850
|
} else if (payloadType === "agent_iteration_complete") {
|
|
5746
5851
|
} else if (payloadType === "agent_reflection" || payloadType === "agent_reflect") {
|
|
5747
5852
|
const reflectionId = `agent-reflection-${payload.executionId}-${payload.iteration}`;
|
|
@@ -11122,6 +11227,19 @@ var isSafeImageSrc = (src) => {
|
|
|
11122
11227
|
if (!src.includes(":")) return true;
|
|
11123
11228
|
return false;
|
|
11124
11229
|
};
|
|
11230
|
+
var isSafeMediaSrc = (src) => {
|
|
11231
|
+
const lower = src.toLowerCase();
|
|
11232
|
+
if (lower.startsWith("javascript:")) return false;
|
|
11233
|
+
if (lower.startsWith("data:text/html")) return false;
|
|
11234
|
+
if (lower.startsWith("data:text/javascript")) return false;
|
|
11235
|
+
if (lower.startsWith("data:text/xml")) return false;
|
|
11236
|
+
if (lower.startsWith("data:application/xhtml")) return false;
|
|
11237
|
+
if (lower.startsWith("data:image/svg+xml")) return false;
|
|
11238
|
+
if (/^(?:https?|blob):/i.test(src)) return true;
|
|
11239
|
+
if (lower.startsWith("data:")) return true;
|
|
11240
|
+
if (!src.includes(":")) return true;
|
|
11241
|
+
return false;
|
|
11242
|
+
};
|
|
11125
11243
|
var MESSAGE_IMAGE_PREVIEW_MAX_WIDTH_PX = 320;
|
|
11126
11244
|
var MESSAGE_IMAGE_PREVIEW_MAX_HEIGHT_PX = 320;
|
|
11127
11245
|
var getMessageImageParts = (message) => {
|
|
@@ -11132,6 +11250,24 @@ var getMessageImageParts = (message) => {
|
|
|
11132
11250
|
(part) => part.type === "image" && typeof part.image === "string" && part.image.trim().length > 0
|
|
11133
11251
|
);
|
|
11134
11252
|
};
|
|
11253
|
+
var getMessageAudioParts = (message) => {
|
|
11254
|
+
if (!message.contentParts || message.contentParts.length === 0) return [];
|
|
11255
|
+
return message.contentParts.filter(
|
|
11256
|
+
(part) => part.type === "audio" && typeof part.audio === "string" && part.audio.trim().length > 0
|
|
11257
|
+
);
|
|
11258
|
+
};
|
|
11259
|
+
var getMessageVideoParts = (message) => {
|
|
11260
|
+
if (!message.contentParts || message.contentParts.length === 0) return [];
|
|
11261
|
+
return message.contentParts.filter(
|
|
11262
|
+
(part) => part.type === "video" && typeof part.video === "string" && part.video.trim().length > 0
|
|
11263
|
+
);
|
|
11264
|
+
};
|
|
11265
|
+
var getMessageFileParts = (message) => {
|
|
11266
|
+
if (!message.contentParts || message.contentParts.length === 0) return [];
|
|
11267
|
+
return message.contentParts.filter(
|
|
11268
|
+
(part) => part.type === "file" && typeof part.data === "string" && part.data.trim().length > 0
|
|
11269
|
+
);
|
|
11270
|
+
};
|
|
11135
11271
|
var createMessageImagePreviews = (imageParts, hasVisibleText, onPreviewFailed) => {
|
|
11136
11272
|
if (imageParts.length === 0) return null;
|
|
11137
11273
|
try {
|
|
@@ -11200,6 +11336,109 @@ var createMessageImagePreviews = (imageParts, hasVisibleText, onPreviewFailed) =
|
|
|
11200
11336
|
return null;
|
|
11201
11337
|
}
|
|
11202
11338
|
};
|
|
11339
|
+
var createMessageAudioPreviews = (audioParts) => {
|
|
11340
|
+
if (audioParts.length === 0) return null;
|
|
11341
|
+
try {
|
|
11342
|
+
const container = createElement(
|
|
11343
|
+
"div",
|
|
11344
|
+
"persona-flex persona-flex-col persona-gap-2"
|
|
11345
|
+
);
|
|
11346
|
+
container.setAttribute("data-message-attachments", "audio");
|
|
11347
|
+
let visible = 0;
|
|
11348
|
+
audioParts.forEach((part) => {
|
|
11349
|
+
if (!isSafeMediaSrc(part.audio)) return;
|
|
11350
|
+
const audioElement = createElement("audio");
|
|
11351
|
+
audioElement.controls = true;
|
|
11352
|
+
audioElement.preload = "metadata";
|
|
11353
|
+
audioElement.src = part.audio;
|
|
11354
|
+
audioElement.style.display = "block";
|
|
11355
|
+
audioElement.style.width = "100%";
|
|
11356
|
+
audioElement.style.maxWidth = `${MESSAGE_IMAGE_PREVIEW_MAX_WIDTH_PX}px`;
|
|
11357
|
+
container.appendChild(audioElement);
|
|
11358
|
+
visible += 1;
|
|
11359
|
+
});
|
|
11360
|
+
if (visible === 0) {
|
|
11361
|
+
container.remove();
|
|
11362
|
+
return null;
|
|
11363
|
+
}
|
|
11364
|
+
return container;
|
|
11365
|
+
} catch {
|
|
11366
|
+
return null;
|
|
11367
|
+
}
|
|
11368
|
+
};
|
|
11369
|
+
var createMessageVideoPreviews = (videoParts) => {
|
|
11370
|
+
if (videoParts.length === 0) return null;
|
|
11371
|
+
try {
|
|
11372
|
+
const container = createElement(
|
|
11373
|
+
"div",
|
|
11374
|
+
"persona-flex persona-flex-col persona-gap-2"
|
|
11375
|
+
);
|
|
11376
|
+
container.setAttribute("data-message-attachments", "video");
|
|
11377
|
+
let visible = 0;
|
|
11378
|
+
videoParts.forEach((part) => {
|
|
11379
|
+
if (!isSafeMediaSrc(part.video)) return;
|
|
11380
|
+
const videoElement = createElement("video");
|
|
11381
|
+
videoElement.controls = true;
|
|
11382
|
+
videoElement.preload = "metadata";
|
|
11383
|
+
videoElement.src = part.video;
|
|
11384
|
+
videoElement.style.display = "block";
|
|
11385
|
+
videoElement.style.width = "100%";
|
|
11386
|
+
videoElement.style.maxWidth = `${MESSAGE_IMAGE_PREVIEW_MAX_WIDTH_PX}px`;
|
|
11387
|
+
videoElement.style.maxHeight = `${MESSAGE_IMAGE_PREVIEW_MAX_HEIGHT_PX}px`;
|
|
11388
|
+
videoElement.style.borderRadius = "10px";
|
|
11389
|
+
videoElement.style.backgroundColor = "var(--persona-attachment-image-bg, var(--persona-container, #f3f4f6))";
|
|
11390
|
+
container.appendChild(videoElement);
|
|
11391
|
+
visible += 1;
|
|
11392
|
+
});
|
|
11393
|
+
if (visible === 0) {
|
|
11394
|
+
container.remove();
|
|
11395
|
+
return null;
|
|
11396
|
+
}
|
|
11397
|
+
return container;
|
|
11398
|
+
} catch {
|
|
11399
|
+
return null;
|
|
11400
|
+
}
|
|
11401
|
+
};
|
|
11402
|
+
var createMessageFilePreviews = (fileParts) => {
|
|
11403
|
+
if (fileParts.length === 0) return null;
|
|
11404
|
+
try {
|
|
11405
|
+
const container = createElement(
|
|
11406
|
+
"div",
|
|
11407
|
+
"persona-flex persona-flex-col persona-gap-2"
|
|
11408
|
+
);
|
|
11409
|
+
container.setAttribute("data-message-attachments", "files");
|
|
11410
|
+
let visible = 0;
|
|
11411
|
+
fileParts.forEach((part) => {
|
|
11412
|
+
if (!isSafeMediaSrc(part.data)) return;
|
|
11413
|
+
const link = createElement("a");
|
|
11414
|
+
link.href = part.data;
|
|
11415
|
+
link.download = part.filename;
|
|
11416
|
+
link.target = "_blank";
|
|
11417
|
+
link.rel = "noopener noreferrer";
|
|
11418
|
+
link.textContent = part.filename;
|
|
11419
|
+
link.className = "persona-message-file-attachment";
|
|
11420
|
+
link.style.display = "inline-flex";
|
|
11421
|
+
link.style.alignItems = "center";
|
|
11422
|
+
link.style.gap = "6px";
|
|
11423
|
+
link.style.padding = "6px 10px";
|
|
11424
|
+
link.style.borderRadius = "8px";
|
|
11425
|
+
link.style.fontSize = "0.875rem";
|
|
11426
|
+
link.style.textDecoration = "underline";
|
|
11427
|
+
link.style.backgroundColor = "var(--persona-attachment-file-bg, var(--persona-container, #f3f4f6))";
|
|
11428
|
+
link.style.border = "1px solid var(--persona-attachment-file-border, var(--persona-border, #e5e7eb))";
|
|
11429
|
+
link.style.color = "inherit";
|
|
11430
|
+
container.appendChild(link);
|
|
11431
|
+
visible += 1;
|
|
11432
|
+
});
|
|
11433
|
+
if (visible === 0) {
|
|
11434
|
+
container.remove();
|
|
11435
|
+
return null;
|
|
11436
|
+
}
|
|
11437
|
+
return container;
|
|
11438
|
+
} catch {
|
|
11439
|
+
return null;
|
|
11440
|
+
}
|
|
11441
|
+
};
|
|
11203
11442
|
var createTypingIndicator = () => {
|
|
11204
11443
|
const container = document.createElement("div");
|
|
11205
11444
|
container.className = "persona-flex persona-items-center persona-space-x-1 persona-h-5 persona-mt-2";
|
|
@@ -11530,6 +11769,27 @@ var createStandardBubble = (message, transform, layoutConfig, actionsConfig, act
|
|
|
11530
11769
|
textContentDiv.style.display = "";
|
|
11531
11770
|
}
|
|
11532
11771
|
}
|
|
11772
|
+
const audioParts = getMessageAudioParts(message);
|
|
11773
|
+
if (audioParts.length > 0) {
|
|
11774
|
+
const audioPreviews = createMessageAudioPreviews(audioParts);
|
|
11775
|
+
if (audioPreviews) {
|
|
11776
|
+
bubble.appendChild(audioPreviews);
|
|
11777
|
+
}
|
|
11778
|
+
}
|
|
11779
|
+
const videoParts = getMessageVideoParts(message);
|
|
11780
|
+
if (videoParts.length > 0) {
|
|
11781
|
+
const videoPreviews = createMessageVideoPreviews(videoParts);
|
|
11782
|
+
if (videoPreviews) {
|
|
11783
|
+
bubble.appendChild(videoPreviews);
|
|
11784
|
+
}
|
|
11785
|
+
}
|
|
11786
|
+
const fileParts = getMessageFileParts(message);
|
|
11787
|
+
if (fileParts.length > 0) {
|
|
11788
|
+
const filePreviews = createMessageFilePreviews(fileParts);
|
|
11789
|
+
if (filePreviews) {
|
|
11790
|
+
bubble.appendChild(filePreviews);
|
|
11791
|
+
}
|
|
11792
|
+
}
|
|
11533
11793
|
bubble.appendChild(contentDiv);
|
|
11534
11794
|
if (showTimestamp && timestampPosition === "below" && message.createdAt) {
|
|
11535
11795
|
const timestamp = createTimestamp(message, timestampConfig);
|
package/dist/theme-editor.d.cts
CHANGED
|
@@ -728,10 +728,28 @@ type FileContentPart = {
|
|
|
728
728
|
mimeType: string;
|
|
729
729
|
filename: string;
|
|
730
730
|
};
|
|
731
|
+
/**
|
|
732
|
+
* Audio content part for multi-modal messages
|
|
733
|
+
* Supports base64 data URIs or URLs
|
|
734
|
+
*/
|
|
735
|
+
type AudioContentPart = {
|
|
736
|
+
type: 'audio';
|
|
737
|
+
audio: string;
|
|
738
|
+
mimeType?: string;
|
|
739
|
+
};
|
|
740
|
+
/**
|
|
741
|
+
* Video content part for multi-modal messages
|
|
742
|
+
* Supports base64 data URIs or URLs
|
|
743
|
+
*/
|
|
744
|
+
type VideoContentPart = {
|
|
745
|
+
type: 'video';
|
|
746
|
+
video: string;
|
|
747
|
+
mimeType?: string;
|
|
748
|
+
};
|
|
731
749
|
/**
|
|
732
750
|
* Union type for all content part types
|
|
733
751
|
*/
|
|
734
|
-
type ContentPart = TextContentPart | ImageContentPart | FileContentPart;
|
|
752
|
+
type ContentPart = TextContentPart | ImageContentPart | FileContentPart | AudioContentPart | VideoContentPart;
|
|
735
753
|
/**
|
|
736
754
|
* Message content can be a simple string or an array of content parts
|
|
737
755
|
*/
|
package/dist/theme-editor.d.ts
CHANGED
|
@@ -728,10 +728,28 @@ type FileContentPart = {
|
|
|
728
728
|
mimeType: string;
|
|
729
729
|
filename: string;
|
|
730
730
|
};
|
|
731
|
+
/**
|
|
732
|
+
* Audio content part for multi-modal messages
|
|
733
|
+
* Supports base64 data URIs or URLs
|
|
734
|
+
*/
|
|
735
|
+
type AudioContentPart = {
|
|
736
|
+
type: 'audio';
|
|
737
|
+
audio: string;
|
|
738
|
+
mimeType?: string;
|
|
739
|
+
};
|
|
740
|
+
/**
|
|
741
|
+
* Video content part for multi-modal messages
|
|
742
|
+
* Supports base64 data URIs or URLs
|
|
743
|
+
*/
|
|
744
|
+
type VideoContentPart = {
|
|
745
|
+
type: 'video';
|
|
746
|
+
video: string;
|
|
747
|
+
mimeType?: string;
|
|
748
|
+
};
|
|
731
749
|
/**
|
|
732
750
|
* Union type for all content part types
|
|
733
751
|
*/
|
|
734
|
-
type ContentPart = TextContentPart | ImageContentPart | FileContentPart;
|
|
752
|
+
type ContentPart = TextContentPart | ImageContentPart | FileContentPart | AudioContentPart | VideoContentPart;
|
|
735
753
|
/**
|
|
736
754
|
* Message content can be a simple string or an array of content parts
|
|
737
755
|
*/
|
package/dist/theme-editor.js
CHANGED
|
@@ -3679,6 +3679,28 @@ var SequenceReorderBuffer = class {
|
|
|
3679
3679
|
// src/client.ts
|
|
3680
3680
|
var DEFAULT_ENDPOINT = "https://api.runtype.com/v1/dispatch";
|
|
3681
3681
|
var DEFAULT_CLIENT_API_BASE = "https://api.runtype.com";
|
|
3682
|
+
function filenameFromMediaType(mediaType) {
|
|
3683
|
+
var _a, _b;
|
|
3684
|
+
const lower = mediaType.toLowerCase();
|
|
3685
|
+
const knownExtensions = {
|
|
3686
|
+
"application/pdf": "pdf",
|
|
3687
|
+
"application/json": "json",
|
|
3688
|
+
"application/zip": "zip",
|
|
3689
|
+
"text/plain": "txt",
|
|
3690
|
+
"text/csv": "csv",
|
|
3691
|
+
"text/markdown": "md"
|
|
3692
|
+
};
|
|
3693
|
+
const ext = knownExtensions[lower];
|
|
3694
|
+
if (ext) return `attachment.${ext}`;
|
|
3695
|
+
const slash = lower.indexOf("/");
|
|
3696
|
+
if (slash > 0) {
|
|
3697
|
+
const subtype = (_b = (_a = lower.slice(slash + 1).split(";")[0]) == null ? void 0 : _a.trim()) != null ? _b : "";
|
|
3698
|
+
if (subtype && subtype !== "octet-stream" && /^[a-z0-9.+-]+$/i.test(subtype)) {
|
|
3699
|
+
return `attachment.${subtype}`;
|
|
3700
|
+
}
|
|
3701
|
+
}
|
|
3702
|
+
return "attachment";
|
|
3703
|
+
}
|
|
3682
3704
|
var hasValidContent = (message) => {
|
|
3683
3705
|
if (message.contentParts && message.contentParts.length > 0) {
|
|
3684
3706
|
return true;
|
|
@@ -5631,6 +5653,89 @@ var AgentWidgetClient = class {
|
|
|
5631
5653
|
}
|
|
5632
5654
|
}
|
|
5633
5655
|
}
|
|
5656
|
+
} else if (payloadType === "agent_media") {
|
|
5657
|
+
const rawMedia = Array.isArray(payload.media) ? payload.media : [];
|
|
5658
|
+
const mediaContentParts = [];
|
|
5659
|
+
for (const part of rawMedia) {
|
|
5660
|
+
if (!part || typeof part !== "object") continue;
|
|
5661
|
+
const rec = part;
|
|
5662
|
+
const partType = typeof rec.type === "string" ? rec.type : void 0;
|
|
5663
|
+
const rawMediaType = typeof rec.mediaType === "string" ? rec.mediaType.toLowerCase() : "";
|
|
5664
|
+
let src = null;
|
|
5665
|
+
let mediaType = "";
|
|
5666
|
+
if (partType === "media") {
|
|
5667
|
+
const data = typeof rec.data === "string" ? rec.data : void 0;
|
|
5668
|
+
if (!data) continue;
|
|
5669
|
+
mediaType = rawMediaType.length > 0 ? rawMediaType : "application/octet-stream";
|
|
5670
|
+
src = `data:${mediaType};base64,${data}`;
|
|
5671
|
+
} else if (partType === "image-url") {
|
|
5672
|
+
const url = typeof rec.url === "string" ? rec.url : void 0;
|
|
5673
|
+
if (!url) continue;
|
|
5674
|
+
mediaType = rawMediaType;
|
|
5675
|
+
src = url;
|
|
5676
|
+
} else if (partType === "file-url") {
|
|
5677
|
+
const url = typeof rec.url === "string" ? rec.url : void 0;
|
|
5678
|
+
if (!url) continue;
|
|
5679
|
+
mediaType = rawMediaType;
|
|
5680
|
+
src = url;
|
|
5681
|
+
} else {
|
|
5682
|
+
continue;
|
|
5683
|
+
}
|
|
5684
|
+
if (!src) continue;
|
|
5685
|
+
if (partType === "image-url" || mediaType.startsWith("image/")) {
|
|
5686
|
+
mediaContentParts.push({
|
|
5687
|
+
type: "image",
|
|
5688
|
+
image: src,
|
|
5689
|
+
...mediaType ? { mimeType: mediaType } : {}
|
|
5690
|
+
});
|
|
5691
|
+
} else if (mediaType.startsWith("audio/")) {
|
|
5692
|
+
mediaContentParts.push({
|
|
5693
|
+
type: "audio",
|
|
5694
|
+
audio: src,
|
|
5695
|
+
mimeType: mediaType
|
|
5696
|
+
});
|
|
5697
|
+
} else if (mediaType.startsWith("video/")) {
|
|
5698
|
+
mediaContentParts.push({
|
|
5699
|
+
type: "video",
|
|
5700
|
+
video: src,
|
|
5701
|
+
mimeType: mediaType
|
|
5702
|
+
});
|
|
5703
|
+
} else {
|
|
5704
|
+
const resolvedMediaType = mediaType || "application/octet-stream";
|
|
5705
|
+
mediaContentParts.push({
|
|
5706
|
+
type: "file",
|
|
5707
|
+
data: src,
|
|
5708
|
+
mimeType: resolvedMediaType,
|
|
5709
|
+
filename: filenameFromMediaType(resolvedMediaType)
|
|
5710
|
+
});
|
|
5711
|
+
}
|
|
5712
|
+
}
|
|
5713
|
+
if (mediaContentParts.length > 0) {
|
|
5714
|
+
const seq = nextSequence();
|
|
5715
|
+
const toolCallIdRaw = payload.toolCallId;
|
|
5716
|
+
const mediaIdSuffix = typeof toolCallIdRaw === "string" && toolCallIdRaw.length > 0 ? `${toolCallIdRaw}-${seq}` : String(seq);
|
|
5717
|
+
const mediaMessage = {
|
|
5718
|
+
id: `agent-media-${mediaIdSuffix}`,
|
|
5719
|
+
role: "assistant",
|
|
5720
|
+
content: "",
|
|
5721
|
+
contentParts: mediaContentParts,
|
|
5722
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
5723
|
+
streaming: false,
|
|
5724
|
+
sequence: seq,
|
|
5725
|
+
agentMetadata: {
|
|
5726
|
+
executionId: payload.executionId,
|
|
5727
|
+
iteration: payload.iteration
|
|
5728
|
+
}
|
|
5729
|
+
};
|
|
5730
|
+
emitMessage(mediaMessage);
|
|
5731
|
+
const prevAssistant = assistantMessage;
|
|
5732
|
+
if (prevAssistant) {
|
|
5733
|
+
prevAssistant.streaming = false;
|
|
5734
|
+
emitMessage(prevAssistant);
|
|
5735
|
+
}
|
|
5736
|
+
assistantMessage = null;
|
|
5737
|
+
assistantMessageRef.current = null;
|
|
5738
|
+
}
|
|
5634
5739
|
} else if (payloadType === "agent_iteration_complete") {
|
|
5635
5740
|
} else if (payloadType === "agent_reflection" || payloadType === "agent_reflect") {
|
|
5636
5741
|
const reflectionId = `agent-reflection-${payload.executionId}-${payload.iteration}`;
|
|
@@ -11125,6 +11230,19 @@ var isSafeImageSrc = (src) => {
|
|
|
11125
11230
|
if (!src.includes(":")) return true;
|
|
11126
11231
|
return false;
|
|
11127
11232
|
};
|
|
11233
|
+
var isSafeMediaSrc = (src) => {
|
|
11234
|
+
const lower = src.toLowerCase();
|
|
11235
|
+
if (lower.startsWith("javascript:")) return false;
|
|
11236
|
+
if (lower.startsWith("data:text/html")) return false;
|
|
11237
|
+
if (lower.startsWith("data:text/javascript")) return false;
|
|
11238
|
+
if (lower.startsWith("data:text/xml")) return false;
|
|
11239
|
+
if (lower.startsWith("data:application/xhtml")) return false;
|
|
11240
|
+
if (lower.startsWith("data:image/svg+xml")) return false;
|
|
11241
|
+
if (/^(?:https?|blob):/i.test(src)) return true;
|
|
11242
|
+
if (lower.startsWith("data:")) return true;
|
|
11243
|
+
if (!src.includes(":")) return true;
|
|
11244
|
+
return false;
|
|
11245
|
+
};
|
|
11128
11246
|
var MESSAGE_IMAGE_PREVIEW_MAX_WIDTH_PX = 320;
|
|
11129
11247
|
var MESSAGE_IMAGE_PREVIEW_MAX_HEIGHT_PX = 320;
|
|
11130
11248
|
var getMessageImageParts = (message) => {
|
|
@@ -11135,6 +11253,24 @@ var getMessageImageParts = (message) => {
|
|
|
11135
11253
|
(part) => part.type === "image" && typeof part.image === "string" && part.image.trim().length > 0
|
|
11136
11254
|
);
|
|
11137
11255
|
};
|
|
11256
|
+
var getMessageAudioParts = (message) => {
|
|
11257
|
+
if (!message.contentParts || message.contentParts.length === 0) return [];
|
|
11258
|
+
return message.contentParts.filter(
|
|
11259
|
+
(part) => part.type === "audio" && typeof part.audio === "string" && part.audio.trim().length > 0
|
|
11260
|
+
);
|
|
11261
|
+
};
|
|
11262
|
+
var getMessageVideoParts = (message) => {
|
|
11263
|
+
if (!message.contentParts || message.contentParts.length === 0) return [];
|
|
11264
|
+
return message.contentParts.filter(
|
|
11265
|
+
(part) => part.type === "video" && typeof part.video === "string" && part.video.trim().length > 0
|
|
11266
|
+
);
|
|
11267
|
+
};
|
|
11268
|
+
var getMessageFileParts = (message) => {
|
|
11269
|
+
if (!message.contentParts || message.contentParts.length === 0) return [];
|
|
11270
|
+
return message.contentParts.filter(
|
|
11271
|
+
(part) => part.type === "file" && typeof part.data === "string" && part.data.trim().length > 0
|
|
11272
|
+
);
|
|
11273
|
+
};
|
|
11138
11274
|
var createMessageImagePreviews = (imageParts, hasVisibleText, onPreviewFailed) => {
|
|
11139
11275
|
if (imageParts.length === 0) return null;
|
|
11140
11276
|
try {
|
|
@@ -11203,6 +11339,109 @@ var createMessageImagePreviews = (imageParts, hasVisibleText, onPreviewFailed) =
|
|
|
11203
11339
|
return null;
|
|
11204
11340
|
}
|
|
11205
11341
|
};
|
|
11342
|
+
var createMessageAudioPreviews = (audioParts) => {
|
|
11343
|
+
if (audioParts.length === 0) return null;
|
|
11344
|
+
try {
|
|
11345
|
+
const container = createElement(
|
|
11346
|
+
"div",
|
|
11347
|
+
"persona-flex persona-flex-col persona-gap-2"
|
|
11348
|
+
);
|
|
11349
|
+
container.setAttribute("data-message-attachments", "audio");
|
|
11350
|
+
let visible = 0;
|
|
11351
|
+
audioParts.forEach((part) => {
|
|
11352
|
+
if (!isSafeMediaSrc(part.audio)) return;
|
|
11353
|
+
const audioElement = createElement("audio");
|
|
11354
|
+
audioElement.controls = true;
|
|
11355
|
+
audioElement.preload = "metadata";
|
|
11356
|
+
audioElement.src = part.audio;
|
|
11357
|
+
audioElement.style.display = "block";
|
|
11358
|
+
audioElement.style.width = "100%";
|
|
11359
|
+
audioElement.style.maxWidth = `${MESSAGE_IMAGE_PREVIEW_MAX_WIDTH_PX}px`;
|
|
11360
|
+
container.appendChild(audioElement);
|
|
11361
|
+
visible += 1;
|
|
11362
|
+
});
|
|
11363
|
+
if (visible === 0) {
|
|
11364
|
+
container.remove();
|
|
11365
|
+
return null;
|
|
11366
|
+
}
|
|
11367
|
+
return container;
|
|
11368
|
+
} catch {
|
|
11369
|
+
return null;
|
|
11370
|
+
}
|
|
11371
|
+
};
|
|
11372
|
+
var createMessageVideoPreviews = (videoParts) => {
|
|
11373
|
+
if (videoParts.length === 0) return null;
|
|
11374
|
+
try {
|
|
11375
|
+
const container = createElement(
|
|
11376
|
+
"div",
|
|
11377
|
+
"persona-flex persona-flex-col persona-gap-2"
|
|
11378
|
+
);
|
|
11379
|
+
container.setAttribute("data-message-attachments", "video");
|
|
11380
|
+
let visible = 0;
|
|
11381
|
+
videoParts.forEach((part) => {
|
|
11382
|
+
if (!isSafeMediaSrc(part.video)) return;
|
|
11383
|
+
const videoElement = createElement("video");
|
|
11384
|
+
videoElement.controls = true;
|
|
11385
|
+
videoElement.preload = "metadata";
|
|
11386
|
+
videoElement.src = part.video;
|
|
11387
|
+
videoElement.style.display = "block";
|
|
11388
|
+
videoElement.style.width = "100%";
|
|
11389
|
+
videoElement.style.maxWidth = `${MESSAGE_IMAGE_PREVIEW_MAX_WIDTH_PX}px`;
|
|
11390
|
+
videoElement.style.maxHeight = `${MESSAGE_IMAGE_PREVIEW_MAX_HEIGHT_PX}px`;
|
|
11391
|
+
videoElement.style.borderRadius = "10px";
|
|
11392
|
+
videoElement.style.backgroundColor = "var(--persona-attachment-image-bg, var(--persona-container, #f3f4f6))";
|
|
11393
|
+
container.appendChild(videoElement);
|
|
11394
|
+
visible += 1;
|
|
11395
|
+
});
|
|
11396
|
+
if (visible === 0) {
|
|
11397
|
+
container.remove();
|
|
11398
|
+
return null;
|
|
11399
|
+
}
|
|
11400
|
+
return container;
|
|
11401
|
+
} catch {
|
|
11402
|
+
return null;
|
|
11403
|
+
}
|
|
11404
|
+
};
|
|
11405
|
+
var createMessageFilePreviews = (fileParts) => {
|
|
11406
|
+
if (fileParts.length === 0) return null;
|
|
11407
|
+
try {
|
|
11408
|
+
const container = createElement(
|
|
11409
|
+
"div",
|
|
11410
|
+
"persona-flex persona-flex-col persona-gap-2"
|
|
11411
|
+
);
|
|
11412
|
+
container.setAttribute("data-message-attachments", "files");
|
|
11413
|
+
let visible = 0;
|
|
11414
|
+
fileParts.forEach((part) => {
|
|
11415
|
+
if (!isSafeMediaSrc(part.data)) return;
|
|
11416
|
+
const link = createElement("a");
|
|
11417
|
+
link.href = part.data;
|
|
11418
|
+
link.download = part.filename;
|
|
11419
|
+
link.target = "_blank";
|
|
11420
|
+
link.rel = "noopener noreferrer";
|
|
11421
|
+
link.textContent = part.filename;
|
|
11422
|
+
link.className = "persona-message-file-attachment";
|
|
11423
|
+
link.style.display = "inline-flex";
|
|
11424
|
+
link.style.alignItems = "center";
|
|
11425
|
+
link.style.gap = "6px";
|
|
11426
|
+
link.style.padding = "6px 10px";
|
|
11427
|
+
link.style.borderRadius = "8px";
|
|
11428
|
+
link.style.fontSize = "0.875rem";
|
|
11429
|
+
link.style.textDecoration = "underline";
|
|
11430
|
+
link.style.backgroundColor = "var(--persona-attachment-file-bg, var(--persona-container, #f3f4f6))";
|
|
11431
|
+
link.style.border = "1px solid var(--persona-attachment-file-border, var(--persona-border, #e5e7eb))";
|
|
11432
|
+
link.style.color = "inherit";
|
|
11433
|
+
container.appendChild(link);
|
|
11434
|
+
visible += 1;
|
|
11435
|
+
});
|
|
11436
|
+
if (visible === 0) {
|
|
11437
|
+
container.remove();
|
|
11438
|
+
return null;
|
|
11439
|
+
}
|
|
11440
|
+
return container;
|
|
11441
|
+
} catch {
|
|
11442
|
+
return null;
|
|
11443
|
+
}
|
|
11444
|
+
};
|
|
11206
11445
|
var createTypingIndicator = () => {
|
|
11207
11446
|
const container = document.createElement("div");
|
|
11208
11447
|
container.className = "persona-flex persona-items-center persona-space-x-1 persona-h-5 persona-mt-2";
|
|
@@ -11533,6 +11772,27 @@ var createStandardBubble = (message, transform, layoutConfig, actionsConfig, act
|
|
|
11533
11772
|
textContentDiv.style.display = "";
|
|
11534
11773
|
}
|
|
11535
11774
|
}
|
|
11775
|
+
const audioParts = getMessageAudioParts(message);
|
|
11776
|
+
if (audioParts.length > 0) {
|
|
11777
|
+
const audioPreviews = createMessageAudioPreviews(audioParts);
|
|
11778
|
+
if (audioPreviews) {
|
|
11779
|
+
bubble.appendChild(audioPreviews);
|
|
11780
|
+
}
|
|
11781
|
+
}
|
|
11782
|
+
const videoParts = getMessageVideoParts(message);
|
|
11783
|
+
if (videoParts.length > 0) {
|
|
11784
|
+
const videoPreviews = createMessageVideoPreviews(videoParts);
|
|
11785
|
+
if (videoPreviews) {
|
|
11786
|
+
bubble.appendChild(videoPreviews);
|
|
11787
|
+
}
|
|
11788
|
+
}
|
|
11789
|
+
const fileParts = getMessageFileParts(message);
|
|
11790
|
+
if (fileParts.length > 0) {
|
|
11791
|
+
const filePreviews = createMessageFilePreviews(fileParts);
|
|
11792
|
+
if (filePreviews) {
|
|
11793
|
+
bubble.appendChild(filePreviews);
|
|
11794
|
+
}
|
|
11795
|
+
}
|
|
11536
11796
|
bubble.appendChild(contentDiv);
|
|
11537
11797
|
if (showTimestamp && timestampPosition === "below" && message.createdAt) {
|
|
11538
11798
|
const timestamp = createTimestamp(message, timestampConfig);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@runtypelabs/persona",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.21.0",
|
|
4
4
|
"description": "Themeable, pluggable streaming agent widget for websites, in plain JS with support for voice input and reasoning / tool output.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.cjs",
|