|
|
@@ -35,6 +35,7 @@ export const DetailPanel = ({
|
|
|
key={idx}
|
|
|
src={img.url}
|
|
|
alt={img.alt || "Extracted"}
|
|
|
+ referrerPolicy="no-referrer"
|
|
|
className="w-full h-20 object-cover rounded border border-gray-200 cursor-pointer hover:opacity-80 transition-opacity bg-gray-50"
|
|
|
onClick={() => setPreviewImage(img.url)}
|
|
|
/>
|
|
|
@@ -43,6 +44,41 @@ export const DetailPanel = ({
|
|
|
);
|
|
|
};
|
|
|
|
|
|
+ const renderResultImages = (imageUrls: string[]) => {
|
|
|
+ if (!imageUrls || imageUrls.length === 0) return null;
|
|
|
+ const normalized = imageUrls
|
|
|
+ .map((raw) => String(raw))
|
|
|
+ .map((raw) => raw.replace(/^[\s`'"]+|[\s`'"]+$/g, ""))
|
|
|
+ .filter((url) => url.startsWith("http") || url.startsWith("data:"));
|
|
|
+ if (normalized.length === 0) return null;
|
|
|
+ return (
|
|
|
+ <div className="grid grid-cols-4 gap-2 mt-2">
|
|
|
+ {normalized.map((url, idx) => (
|
|
|
+ <img
|
|
|
+ key={`${url}-${idx}`}
|
|
|
+ src={url}
|
|
|
+ alt={`Image ${idx + 1}`}
|
|
|
+ referrerPolicy="no-referrer"
|
|
|
+ className="w-full h-16 object-cover rounded border border-gray-200 cursor-pointer hover:opacity-80 transition-opacity bg-gray-50"
|
|
|
+ onClick={() => setPreviewImage(url)}
|
|
|
+ onError={(e) => {
|
|
|
+ (e.target as HTMLImageElement).style.display = "none";
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ ))}
|
|
|
+ </div>
|
|
|
+ );
|
|
|
+ };
|
|
|
+
|
|
|
+ const normalizeImageUrl = (raw: unknown) =>
|
|
|
+ String(raw).replace(/^[\s`'"]+|[\s`'"]+$/g, "");
|
|
|
+
|
|
|
+ const getValidImageUrls = (values: unknown[]): string[] => {
|
|
|
+ return values
|
|
|
+ .map((v) => normalizeImageUrl(v))
|
|
|
+ .filter((url) => url.startsWith("http") || url.startsWith("data:"));
|
|
|
+ };
|
|
|
+
|
|
|
const title = node ? "节点详情" : edge ? "连线详情" : "详情";
|
|
|
|
|
|
const renderMessageContent = (content: Message["content"]) => {
|
|
|
@@ -120,9 +156,7 @@ export const DetailPanel = ({
|
|
|
};
|
|
|
|
|
|
const isMessageNode = (node: Goal | Message): node is Message =>
|
|
|
- "message_id" in node ||
|
|
|
- "role" in node ||
|
|
|
- "sequence" in node;
|
|
|
+ "message_id" in node || "role" in node || "sequence" in node;
|
|
|
|
|
|
const renderKnowledge = (knowledge: Goal["knowledge"]) => {
|
|
|
if (!knowledge || knowledge.length === 0) return null;
|