@malette/agent-sdk 0.1.3-beta.7 → 0.1.3-beta.9

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/index.js CHANGED
@@ -890,7 +890,7 @@ function getCacheKey(text3) {
890
890
  return text3.slice(0, 200);
891
891
  }
892
892
  async function submitGenerateTask(text3) {
893
- const response = await fetch("/api/v1/ai/design/generate", {
893
+ const response = await fetcher("/api/v1/ai/design/generate", {
894
894
  method: "POST",
895
895
  headers: { "content-type": "application/json" },
896
896
  credentials: "include",
@@ -904,11 +904,10 @@ async function submitGenerateTask(text3) {
904
904
  version: "0.1.0"
905
905
  })
906
906
  });
907
- if (!response.ok) {
907
+ if (!response.success) {
908
908
  throw new Error(`TTS generate request failed: ${response.status}`);
909
909
  }
910
- const result = await response.json();
911
- const data = result.data ?? result;
910
+ const data = response.data;
912
911
  console.log("[TTS] Generate task submitted:", data);
913
912
  const publicId = data?.publicId || data?.recordVO?.publicId || (typeof data === "string" ? data : null);
914
913
  if (!publicId) {
@@ -1607,6 +1606,7 @@ var useAgentStore = zustand.create()(
1607
1606
  ...state.artifacts,
1608
1607
  [artifactId]: {
1609
1608
  ...existing,
1609
+ source,
1610
1610
  currentContent: content,
1611
1611
  version: existing.version + 1,
1612
1612
  gmtModified: (/* @__PURE__ */ new Date()).toISOString()
@@ -7862,6 +7862,7 @@ var MessageVideoInternal = React16.memo(function MessageVideoInternal2({ src, cl
7862
7862
  const [duration, setDuration] = React16.useState(0);
7863
7863
  const [currentTime, setCurrentTime] = React16.useState(0);
7864
7864
  const [isFullPlaying, setIsFullPlaying] = React16.useState(false);
7865
+ const [aspectRatio, setAspectRatio] = React16.useState(16 / 9);
7865
7866
  const hoverTimerRef = React16__namespace.default.useRef(null);
7866
7867
  const VideoPreviewComp = useComponent("VideoPreview") || VideoPreviewInternal;
7867
7868
  const [showPreview, setShowPreview] = React16.useState(false);
@@ -7901,6 +7902,9 @@ var MessageVideoInternal = React16.memo(function MessageVideoInternal2({ src, cl
7901
7902
  const video = videoRef.current;
7902
7903
  if (video) {
7903
7904
  setDuration(video.duration);
7905
+ if (video.videoWidth && video.videoHeight) {
7906
+ setAspectRatio(video.videoWidth / video.videoHeight);
7907
+ }
7904
7908
  }
7905
7909
  };
7906
7910
  const handleTimeUpdate = () => {
@@ -7983,13 +7987,16 @@ var MessageVideoInternal = React16.memo(function MessageVideoInternal2({ src, cl
7983
7987
  "div",
7984
7988
  {
7985
7989
  className: cn(
7986
- "my-2 relative inline-block rounded-xl overflow-hidden bg-black group/video cursor-pointer",
7990
+ "my-2 relative rounded-xl overflow-hidden bg-black group/video cursor-pointer",
7987
7991
  "border border-zinc-800/60 agent-sdk-light:border-zinc-200",
7988
7992
  "transition-shadow duration-200 hover:shadow-xl hover:shadow-black/20",
7989
7993
  "max-w-full",
7990
7994
  className
7991
7995
  ),
7992
- style: { maxHeight: "400px" },
7996
+ style: {
7997
+ maxHeight: "400px",
7998
+ aspectRatio
7999
+ },
7993
8000
  onMouseEnter: handleMouseEnter,
7994
8001
  onMouseLeave: handleMouseLeave,
7995
8002
  onClick: handleClick,
@@ -8017,7 +8024,7 @@ var MessageVideoInternal = React16.memo(function MessageVideoInternal2({ src, cl
8017
8024
  setIsFullPlaying(false);
8018
8025
  },
8019
8026
  className: cn(
8020
- "w-full max-h-[400px] object-contain",
8027
+ "absolute inset-0 w-full h-full object-contain",
8021
8028
  !isPlaying && posterUrl && "opacity-0"
8022
8029
  )
8023
8030
  }
@@ -13284,6 +13291,175 @@ var ElegantJsonRenderer = React16.memo(function ElegantJsonRenderer2({
13284
13291
  expanded && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-3 bg-zinc-900/30 text-xs font-mono overflow-x-auto max-h-80 overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsx(JsonValue, { value: data, depth: 0 }) })
13285
13292
  ] });
13286
13293
  });
13294
+ var MediaGrid = React16.memo(function MediaGrid2({
13295
+ imageUrls,
13296
+ videoUrls,
13297
+ imgLoaded,
13298
+ onImgLoad,
13299
+ onPreview,
13300
+ onOpenArtifact,
13301
+ buildMediaMetadata,
13302
+ toolDisplayName
13303
+ }) {
13304
+ const totalCount = imageUrls.length + videoUrls.length;
13305
+ const renderMediaItem = (type, media, index, className, showOverlay = true) => {
13306
+ const globalIndex = type === "video" ? index : videoUrls.length + index;
13307
+ const isLoaded = type === "video" || imgLoaded[index];
13308
+ return /* @__PURE__ */ jsxRuntime.jsxs(
13309
+ "div",
13310
+ {
13311
+ className: `relative group/media overflow-hidden rounded-lg bg-zinc-900 ${className}`,
13312
+ children: [
13313
+ type === "image" && !imgLoaded[index] && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 bg-zinc-800/80 flex items-center justify-center z-10", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-2", children: [
13314
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative w-8 h-8", children: [
13315
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 rounded-full border-2 border-zinc-700" }),
13316
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 rounded-full border-2 border-t-[#d8ff00] animate-spin" })
13317
+ ] }),
13318
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-zinc-500", children: "\u52A0\u8F7D\u4E2D..." })
13319
+ ] }) }),
13320
+ type === "video" ? /* @__PURE__ */ jsxRuntime.jsx(
13321
+ MessageVideoInternal,
13322
+ {
13323
+ src: media.hdUrl || media.url,
13324
+ className: "w-full h-full object-cover"
13325
+ }
13326
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
13327
+ "img",
13328
+ {
13329
+ src: media.url,
13330
+ alt: "Generated",
13331
+ onLoad: () => onImgLoad(index),
13332
+ className: `w-full h-full object-cover cursor-zoom-in transition-opacity duration-300 ${imgLoaded[index] ? "opacity-100" : "opacity-0"}`,
13333
+ onClick: () => onPreview(media.hdUrl || media.url)
13334
+ }
13335
+ ),
13336
+ showOverlay && type === "image" && isLoaded && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute bottom-0 left-0 right-0 p-1.5 bg-gradient-to-t from-black/80 to-transparent opacity-0 group-hover/media:opacity-100 transition-opacity duration-200 flex items-center justify-between z-20", children: [
13337
+ onOpenArtifact && /* @__PURE__ */ jsxRuntime.jsxs(
13338
+ "button",
13339
+ {
13340
+ onClick: (e) => {
13341
+ e.stopPropagation();
13342
+ onOpenArtifact({
13343
+ type,
13344
+ title: `${toolDisplayName || "\u56FE\u7247\u751F\u6210"} #${globalIndex + 1}`,
13345
+ content: media.hdUrl || media.url,
13346
+ metadata: buildMediaMetadata(globalIndex)
13347
+ });
13348
+ },
13349
+ className: "flex items-center gap-1 px-2 py-1 text-[10px] font-medium text-white bg-white/20 hover:bg-white/30 backdrop-blur-sm rounded transition-colors",
13350
+ children: [
13351
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Sparkles, { size: 10 }),
13352
+ "\u8BE6\u60C5"
13353
+ ]
13354
+ }
13355
+ ),
13356
+ /* @__PURE__ */ jsxRuntime.jsx(
13357
+ "button",
13358
+ {
13359
+ onClick: (e) => {
13360
+ e.stopPropagation();
13361
+ onPreview(media.hdUrl || media.url);
13362
+ },
13363
+ className: "p-1 text-white/80 hover:text-white bg-white/20 hover:bg-white/30 backdrop-blur-sm rounded transition-colors",
13364
+ title: "\u653E\u5927\u9884\u89C8",
13365
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Image, { size: 12 })
13366
+ }
13367
+ )
13368
+ ] }),
13369
+ showOverlay && type === "video" && onOpenArtifact && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute top-0 left-0 right-0 p-1.5 bg-gradient-to-b from-black/70 to-transparent opacity-0 group-hover/media:opacity-100 transition-opacity duration-200 flex items-center justify-end z-20", children: /* @__PURE__ */ jsxRuntime.jsxs(
13370
+ "button",
13371
+ {
13372
+ onClick: (e) => {
13373
+ e.stopPropagation();
13374
+ onOpenArtifact({
13375
+ type,
13376
+ title: `${toolDisplayName || "\u89C6\u9891\u751F\u6210"} #${globalIndex + 1}`,
13377
+ content: media.hdUrl || media.url,
13378
+ metadata: buildMediaMetadata(globalIndex)
13379
+ });
13380
+ },
13381
+ className: "flex items-center gap-1 px-2 py-1 text-[10px] font-medium text-white bg-white/20 hover:bg-white/30 backdrop-blur-sm rounded transition-colors",
13382
+ children: [
13383
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Sparkles, { size: 10 }),
13384
+ "\u8BE6\u60C5"
13385
+ ]
13386
+ }
13387
+ ) })
13388
+ ]
13389
+ },
13390
+ `${type}-${index}`
13391
+ );
13392
+ };
13393
+ const allMedia = [
13394
+ ...videoUrls.map((v, i) => ({ type: "video", media: v, index: i })),
13395
+ ...imageUrls.map((img, i) => ({ type: "image", media: img, index: i }))
13396
+ ];
13397
+ if (totalCount === 1) {
13398
+ const item = allMedia[0];
13399
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-w-[280px]", children: renderMediaItem(item.type, item.media, item.index, "aspect-[4/3] max-h-[210px]") });
13400
+ }
13401
+ if (totalCount === 2) {
13402
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 gap-1.5 max-w-[320px]", children: allMedia.map(
13403
+ (item) => renderMediaItem(item.type, item.media, item.index, "aspect-square")
13404
+ ) });
13405
+ }
13406
+ if (totalCount === 3) {
13407
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-3 gap-1.5 max-w-[360px]", children: [
13408
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "col-span-2 row-span-2", children: renderMediaItem(allMedia[0].type, allMedia[0].media, allMedia[0].index, "aspect-square h-full") }),
13409
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1.5", children: [
13410
+ renderMediaItem(allMedia[1].type, allMedia[1].media, allMedia[1].index, "aspect-square"),
13411
+ renderMediaItem(allMedia[2].type, allMedia[2].media, allMedia[2].index, "aspect-square")
13412
+ ] })
13413
+ ] });
13414
+ }
13415
+ if (totalCount === 4) {
13416
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 gap-1.5 max-w-[280px]", children: allMedia.map(
13417
+ (item) => renderMediaItem(item.type, item.media, item.index, "aspect-square")
13418
+ ) });
13419
+ }
13420
+ if (totalCount <= 6) {
13421
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-3 gap-1.5 max-w-[320px]", children: allMedia.map(
13422
+ (item) => renderMediaItem(item.type, item.media, item.index, "aspect-square")
13423
+ ) });
13424
+ }
13425
+ if (totalCount <= 9) {
13426
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-3 gap-1.5 max-w-[320px]", children: allMedia.slice(0, 9).map(
13427
+ (item) => renderMediaItem(item.type, item.media, item.index, "aspect-square")
13428
+ ) });
13429
+ }
13430
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-3 gap-1.5 max-w-[320px]", children: [
13431
+ allMedia.slice(0, 8).map(
13432
+ (item) => renderMediaItem(item.type, item.media, item.index, "aspect-square")
13433
+ ),
13434
+ /* @__PURE__ */ jsxRuntime.jsxs(
13435
+ "div",
13436
+ {
13437
+ className: "aspect-square relative rounded-lg overflow-hidden cursor-pointer group/more",
13438
+ onClick: () => onPreview(allMedia[8].media.hdUrl || allMedia[8].media.url),
13439
+ children: [
13440
+ allMedia[8].type === "image" ? /* @__PURE__ */ jsxRuntime.jsx(
13441
+ "img",
13442
+ {
13443
+ src: allMedia[8].media.url,
13444
+ alt: "More",
13445
+ className: "w-full h-full object-cover"
13446
+ }
13447
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
13448
+ MessageVideoInternal,
13449
+ {
13450
+ src: allMedia[8].media.hdUrl || allMedia[8].media.url,
13451
+ className: "w-full h-full object-cover"
13452
+ }
13453
+ ),
13454
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 bg-black/60 flex items-center justify-center group-hover/more:bg-black/70 transition-colors", children: /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-white text-lg font-semibold", children: [
13455
+ "+",
13456
+ totalCount - 8
13457
+ ] }) })
13458
+ ]
13459
+ }
13460
+ )
13461
+ ] });
13462
+ });
13287
13463
  var ToolResultRenderer = React16.memo(function ToolResultRenderer2({
13288
13464
  result,
13289
13465
  mediaUrls,
@@ -13343,6 +13519,21 @@ var ToolResultRenderer = React16.memo(function ToolResultRenderer2({
13343
13519
  const handleImgLoad = (index) => {
13344
13520
  setImgLoaded((prev) => ({ ...prev, [index]: true }));
13345
13521
  };
13522
+ const buildMediaMetadata = (mediaIndex) => {
13523
+ if (!toolCallData) return void 0;
13524
+ const resultAny = toolCallData.result;
13525
+ const metadata = {};
13526
+ metadata.toolName = toolCallData?.displayName || toolCallData?.name || "\u5DE5\u5177\u8C03\u7528";
13527
+ if (toolCallData.arguments) metadata.generationParams = toolCallData.arguments;
13528
+ if (resultAny?.relation) metadata.relation = resultAny.relation;
13529
+ if (resultAny?.taskId) metadata.taskId = resultAny.taskId;
13530
+ const work = resultAny?.works?.[mediaIndex];
13531
+ if (work) {
13532
+ if (work.publicId) metadata.workId = work.publicId;
13533
+ if (work.fileId) metadata.fileId = work.fileId;
13534
+ }
13535
+ return metadata;
13536
+ };
13346
13537
  if (!hasMedia && !hasFilteredResult && !hasCustomResponses) {
13347
13538
  return null;
13348
13539
  }
@@ -13355,134 +13546,19 @@ var ToolResultRenderer = React16.memo(function ToolResultRenderer2({
13355
13546
  }
13356
13547
  ),
13357
13548
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
13358
- hasMedia && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-2", children: (() => {
13359
- const totalMedia = imageUrls.length + videoUrls.length;
13360
- const isMultiple = totalMedia > 1;
13361
- const buildMediaMetadata = (mediaIndex) => {
13362
- if (!toolCallData) return void 0;
13363
- const resultAny = toolCallData.result;
13364
- const metadata = {};
13365
- if (toolCallData.name) metadata.toolName = toolCallData.name;
13366
- if (resultAny?.relation?.toolName) metadata.toolName = resultAny.relation.toolName;
13367
- if (toolCallData.arguments) metadata.generationParams = toolCallData.arguments;
13368
- if (resultAny?.relation) metadata.relation = resultAny.relation;
13369
- if (resultAny?.taskId) metadata.taskId = resultAny.taskId;
13370
- const work = resultAny?.works?.[mediaIndex];
13371
- if (work) {
13372
- if (work.publicId) metadata.workId = work.publicId;
13373
- if (work.fileId) metadata.fileId = work.fileId;
13374
- }
13375
- return metadata;
13376
- };
13377
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: isMultiple ? "grid grid-cols-2 gap-2" : "flex", children: [
13378
- videoUrls.map((video, i) => /* @__PURE__ */ jsxRuntime.jsxs(
13379
- "div",
13380
- {
13381
- className: `relative group/media overflow-hidden rounded-lg bg-black ${isMultiple ? "aspect-square" : "max-h-[375px]"}`,
13382
- children: [
13383
- /* @__PURE__ */ jsxRuntime.jsx(
13384
- MessageVideoInternal,
13385
- {
13386
- src: video.hdUrl || video.url,
13387
- className: isMultiple ? "w-full h-full object-cover" : "max-h-[375px] max-w-full object-contain"
13388
- }
13389
- ),
13390
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute bottom-0 left-0 right-0 p-2 bg-gradient-to-t from-black/70 to-transparent opacity-0 group-hover/media:opacity-100 transition-opacity duration-200 flex items-center justify-between z-[10]", children: [
13391
- onOpenArtifact && /* @__PURE__ */ jsxRuntime.jsxs(
13392
- "button",
13393
- {
13394
- onClick: (e) => {
13395
- e.stopPropagation();
13396
- const resultAny = toolCallData?.result;
13397
- const displayName = resultAny?.relation?.toolName || toolCallData?.name || "\u89C6\u9891\u751F\u6210";
13398
- onOpenArtifact({
13399
- type: "video",
13400
- title: `${displayName} #${i + 1}`,
13401
- content: video.hdUrl || video.url,
13402
- metadata: buildMediaMetadata(imageUrls.length + i)
13403
- });
13404
- },
13405
- className: "flex items-center gap-1.5 px-2.5 py-1.5 text-[11px] font-medium text-white bg-white/15 hover:bg-white/25 backdrop-blur-sm rounded-md transition-colors",
13406
- children: [
13407
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Sparkles, { size: 12 }),
13408
- "\u67E5\u770B\u8BE6\u60C5"
13409
- ]
13410
- }
13411
- ),
13412
- /* @__PURE__ */ jsxRuntime.jsx(
13413
- "button",
13414
- {
13415
- onClick: (e) => {
13416
- e.stopPropagation();
13417
- window.open(video.hdUrl || video.url, "_blank");
13418
- },
13419
- className: "p-1.5 text-white/80 hover:text-white bg-white/15 hover:bg-white/25 backdrop-blur-sm rounded-md transition-colors",
13420
- title: "\u65B0\u7A97\u53E3\u6253\u5F00",
13421
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Video, { size: 14 })
13422
- }
13423
- )
13424
- ] })
13425
- ]
13426
- },
13427
- `video-${i}`
13428
- )),
13429
- imageUrls.map((img, i) => /* @__PURE__ */ jsxRuntime.jsxs(
13430
- "div",
13431
- {
13432
- className: `relative group/media overflow-hidden rounded-lg bg-black ${isMultiple ? "aspect-square" : "max-h-[375px]"}`,
13433
- children: [
13434
- !imgLoaded[i] && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-zinc-800 animate-pulse flex items-center justify-center w-full aspect-square", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "animate-spin rounded-full h-5 w-5 border-b-2 border-[#d8ff00]" }) }),
13435
- /* @__PURE__ */ jsxRuntime.jsx(
13436
- "img",
13437
- {
13438
- src: img.url,
13439
- alt: "Generated",
13440
- onLoad: () => handleImgLoad(i),
13441
- className: `cursor-zoom-in ${imgLoaded[i] ? "" : "hidden"} ${isMultiple ? "w-full h-full object-cover" : "max-h-[375px] max-w-full h-auto object-contain"}`,
13442
- onClick: () => setPreviewUrl(img.hdUrl)
13443
- }
13444
- ),
13445
- imgLoaded[i] && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute bottom-0 left-0 right-0 p-2 bg-gradient-to-t from-black/70 to-transparent opacity-0 group-hover/media:opacity-100 transition-opacity duration-200 flex items-center justify-between", children: [
13446
- onOpenArtifact && /* @__PURE__ */ jsxRuntime.jsxs(
13447
- "button",
13448
- {
13449
- onClick: (e) => {
13450
- e.stopPropagation();
13451
- const resultAny = toolCallData?.result;
13452
- const displayName = resultAny?.relation?.toolName || toolCallData?.name || "\u56FE\u7247\u751F\u6210";
13453
- onOpenArtifact({
13454
- type: "image",
13455
- title: `${displayName} #${i + 1}`,
13456
- content: img.hdUrl || img.url,
13457
- metadata: buildMediaMetadata(i)
13458
- });
13459
- },
13460
- className: "flex items-center gap-1.5 px-2.5 py-1.5 text-[11px] font-medium text-white bg-white/15 hover:bg-white/25 backdrop-blur-sm rounded-md transition-colors",
13461
- children: [
13462
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Sparkles, { size: 12 }),
13463
- "\u67E5\u770B\u8BE6\u60C5"
13464
- ]
13465
- }
13466
- ),
13467
- /* @__PURE__ */ jsxRuntime.jsx(
13468
- "button",
13469
- {
13470
- onClick: (e) => {
13471
- e.stopPropagation();
13472
- setPreviewUrl(img.hdUrl);
13473
- },
13474
- className: "p-1.5 text-white/80 hover:text-white bg-white/15 hover:bg-white/25 backdrop-blur-sm rounded-md transition-colors",
13475
- title: "\u653E\u5927\u9884\u89C8",
13476
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Image, { size: 14 })
13477
- }
13478
- )
13479
- ] })
13480
- ]
13481
- },
13482
- `img-${i}`
13483
- ))
13484
- ] });
13485
- })() }),
13549
+ hasMedia && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-2", children: /* @__PURE__ */ jsxRuntime.jsx(
13550
+ MediaGrid,
13551
+ {
13552
+ imageUrls,
13553
+ videoUrls,
13554
+ imgLoaded,
13555
+ onImgLoad: handleImgLoad,
13556
+ onPreview: setPreviewUrl,
13557
+ onOpenArtifact,
13558
+ buildMediaMetadata,
13559
+ toolDisplayName: toolCallData?.displayName
13560
+ }
13561
+ ) }),
13486
13562
  hasCustomResponses && customResult
13487
13563
  ] })
13488
13564
  ] });
@@ -13618,7 +13694,10 @@ var ToolCallCard = React16.memo(function ToolCallCard2({
13618
13694
  result: toolCall.result,
13619
13695
  mediaUrls,
13620
13696
  config,
13621
- toolCallData: toolCall,
13697
+ toolCallData: {
13698
+ ...toolCall,
13699
+ displayName: toolDisplayName
13700
+ },
13622
13701
  defaultExpanded: false,
13623
13702
  onOpenArtifact
13624
13703
  }
@@ -22009,23 +22088,115 @@ function useResolvedThumbnailUrl(content, options) {
22009
22088
  }, [content, fileId, type, config, enabled]);
22010
22089
  return url;
22011
22090
  }
22091
+ var MIN_ZOOM = 10;
22092
+ var MAX_ZOOM = 500;
22093
+ var ZOOM_STEP = 10;
22094
+ var WHEEL_ZOOM_FACTOR = 0.1;
22012
22095
  var ImageArtifactPreview = React16.memo(function ImageArtifactPreview2({
22013
22096
  content,
22014
22097
  metadata,
22015
22098
  config
22016
22099
  }) {
22017
- const [isZoomed, setIsZoomed] = React16.useState(false);
22018
22100
  const [showInfo, setShowInfo] = React16.useState(true);
22019
22101
  const [imgNaturalSize, setImgNaturalSize] = React16.useState(null);
22020
22102
  const [copied, setCopied] = React16.useState(null);
22103
+ const [zoom, setZoom] = React16.useState(100);
22104
+ const [fitZoom, setFitZoom] = React16.useState(100);
22105
+ const [isDragging, setIsDragging] = React16.useState(false);
22106
+ const [dragStart, setDragStart] = React16.useState({ x: 0, y: 0 });
22107
+ const [scrollStart, setScrollStart] = React16.useState({ x: 0, y: 0 });
22108
+ const containerRef = React16.useRef(null);
22109
+ const scrollRef = React16.useRef(null);
22110
+ const imageRef = React16.useRef(null);
22021
22111
  const { hdUrl: resolvedHdUrl } = useResolvedMediaUrl(content, {
22022
22112
  fileId: metadata?.fileId,
22023
22113
  type: "image",
22024
22114
  config
22025
22115
  });
22026
- const generationParams = metadata?.generationParams;
22116
+ const generationParams = metadata?.generationParams || metadata;
22027
22117
  const toolName = metadata?.toolName;
22028
22118
  const relation = metadata?.relation;
22119
+ const calculateFitZoom = React16.useCallback(() => {
22120
+ if (!containerRef.current || !imgNaturalSize) return 100;
22121
+ const container = containerRef.current;
22122
+ const padding = 48;
22123
+ const availableWidth = container.clientWidth - padding;
22124
+ const availableHeight = container.clientHeight - padding;
22125
+ const scaleX = availableWidth / imgNaturalSize.width;
22126
+ const scaleY = availableHeight / imgNaturalSize.height;
22127
+ return Math.min(scaleX, scaleY, 1) * 100;
22128
+ }, [imgNaturalSize]);
22129
+ const handleImageLoad = React16.useCallback((e) => {
22130
+ const img = e.target;
22131
+ const naturalSize = { width: img.naturalWidth, height: img.naturalHeight };
22132
+ setImgNaturalSize(naturalSize);
22133
+ }, []);
22134
+ React16.useEffect(() => {
22135
+ if (imgNaturalSize && containerRef.current) {
22136
+ const fit = calculateFitZoom();
22137
+ setFitZoom(fit);
22138
+ setZoom(fit);
22139
+ requestAnimationFrame(() => {
22140
+ if (scrollRef.current) {
22141
+ const el = scrollRef.current;
22142
+ el.scrollLeft = (el.scrollWidth - el.clientWidth) / 2;
22143
+ el.scrollTop = (el.scrollHeight - el.clientHeight) / 2;
22144
+ }
22145
+ });
22146
+ }
22147
+ }, [imgNaturalSize, calculateFitZoom]);
22148
+ const setZoomWithCenter = React16.useCallback((newZoom, centerX, centerY) => {
22149
+ const clampedZoom = Math.max(MIN_ZOOM, Math.min(MAX_ZOOM, newZoom));
22150
+ if (scrollRef.current && imgNaturalSize) {
22151
+ const el = scrollRef.current;
22152
+ const oldZoom = zoom;
22153
+ const cx2 = centerX ?? el.clientWidth / 2;
22154
+ const cy = centerY ?? el.clientHeight / 2;
22155
+ const imgX = (el.scrollLeft + cx2) / (oldZoom / 100);
22156
+ const imgY = (el.scrollTop + cy) / (oldZoom / 100);
22157
+ setZoom(clampedZoom);
22158
+ requestAnimationFrame(() => {
22159
+ el.scrollLeft = imgX * (clampedZoom / 100) - cx2;
22160
+ el.scrollTop = imgY * (clampedZoom / 100) - cy;
22161
+ });
22162
+ } else {
22163
+ setZoom(clampedZoom);
22164
+ }
22165
+ }, [zoom, imgNaturalSize]);
22166
+ const handleWheel = React16.useCallback((e) => {
22167
+ if (e.ctrlKey || e.metaKey) {
22168
+ e.preventDefault();
22169
+ const rect = scrollRef.current?.getBoundingClientRect();
22170
+ const centerX = rect ? e.clientX - rect.left : void 0;
22171
+ const centerY = rect ? e.clientY - rect.top : void 0;
22172
+ const delta = -e.deltaY * WHEEL_ZOOM_FACTOR;
22173
+ setZoomWithCenter(zoom * (1 + delta / 100), centerX, centerY);
22174
+ }
22175
+ }, [zoom, setZoomWithCenter]);
22176
+ const handleMouseDown = React16.useCallback((e) => {
22177
+ if (e.button === 0 && scrollRef.current) {
22178
+ setIsDragging(true);
22179
+ setDragStart({ x: e.clientX, y: e.clientY });
22180
+ setScrollStart({ x: scrollRef.current.scrollLeft, y: scrollRef.current.scrollTop });
22181
+ e.preventDefault();
22182
+ }
22183
+ }, []);
22184
+ const handleMouseMove = React16.useCallback((e) => {
22185
+ if (isDragging && scrollRef.current) {
22186
+ scrollRef.current.scrollLeft = scrollStart.x - (e.clientX - dragStart.x);
22187
+ scrollRef.current.scrollTop = scrollStart.y - (e.clientY - dragStart.y);
22188
+ }
22189
+ }, [isDragging, dragStart, scrollStart]);
22190
+ const handleMouseUp = React16.useCallback(() => {
22191
+ setIsDragging(false);
22192
+ }, []);
22193
+ const handleDoubleClick = React16.useCallback(() => {
22194
+ if (Math.abs(zoom - fitZoom) < 1) {
22195
+ setZoomWithCenter(100);
22196
+ } else {
22197
+ setZoomWithCenter(fitZoom);
22198
+ }
22199
+ }, [zoom, fitZoom, setZoomWithCenter]);
22029
22200
  const handleCopy = React16.useCallback(async (text3, label) => {
22030
22201
  try {
22031
22202
  await navigator.clipboard.writeText(text3);
@@ -22043,6 +22214,20 @@ var ImageArtifactPreview = React16.memo(function ImageArtifactPreview2({
22043
22214
  link2.click();
22044
22215
  document.body.removeChild(link2);
22045
22216
  }, [resolvedHdUrl]);
22217
+ const handleZoomIn = React16.useCallback(() => {
22218
+ setZoomWithCenter(Math.ceil((zoom + ZOOM_STEP) / ZOOM_STEP) * ZOOM_STEP);
22219
+ }, [zoom, setZoomWithCenter]);
22220
+ const handleZoomOut = React16.useCallback(() => {
22221
+ setZoomWithCenter(Math.floor((zoom - ZOOM_STEP) / ZOOM_STEP) * ZOOM_STEP);
22222
+ }, [zoom, setZoomWithCenter]);
22223
+ const handleFitToScreen = React16.useCallback(() => {
22224
+ setZoomWithCenter(fitZoom);
22225
+ }, [fitZoom, setZoomWithCenter]);
22226
+ const handleActualSize = React16.useCallback(() => {
22227
+ setZoomWithCenter(100);
22228
+ }, [setZoomWithCenter]);
22229
+ const displayWidth = imgNaturalSize ? imgNaturalSize.width * (zoom / 100) : 0;
22230
+ const displayHeight = imgNaturalSize ? imgNaturalSize.height * (zoom / 100) : 0;
22046
22231
  const formatParamKey = (key) => {
22047
22232
  const keyMap = {
22048
22233
  content: "Prompt",
@@ -22063,67 +22248,188 @@ var ImageArtifactPreview = React16.memo(function ImageArtifactPreview2({
22063
22248
  const promptText = generationParams?.content ? String(generationParams.content) : null;
22064
22249
  const otherParams = generationParams ? Object.entries(generationParams).filter(([key]) => key !== "content") : [];
22065
22250
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "h-full flex flex-col bg-zinc-950 agent-sdk-light:bg-white", children: [
22066
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 overflow-auto flex items-center justify-center p-6 bg-zinc-950 agent-sdk-light:bg-zinc-50 relative", children: [
22067
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 opacity-[0.03]", style: {
22068
- backgroundImage: "linear-gradient(45deg, #808080 25%, transparent 25%), linear-gradient(-45deg, #808080 25%, transparent 25%), linear-gradient(45deg, transparent 75%, #808080 75%), linear-gradient(-45deg, transparent 75%, #808080 75%)",
22069
- backgroundSize: "20px 20px",
22070
- backgroundPosition: "0 0, 0 10px, 10px -10px, -10px 0px"
22071
- } }),
22072
- /* @__PURE__ */ jsxRuntime.jsx(
22073
- "div",
22074
- {
22075
- className: cn3(
22076
- "relative transition-transform duration-300 cursor-zoom-in z-10",
22077
- isZoomed && "cursor-zoom-out scale-[2] z-50"
22078
- ),
22079
- onClick: () => setIsZoomed((prev) => !prev),
22080
- children: /* @__PURE__ */ jsxRuntime.jsx(
22081
- "img",
22251
+ /* @__PURE__ */ jsxRuntime.jsxs(
22252
+ "div",
22253
+ {
22254
+ ref: containerRef,
22255
+ className: "flex-1 relative bg-zinc-950 agent-sdk-light:bg-zinc-50 overflow-hidden",
22256
+ children: [
22257
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 opacity-[0.03] pointer-events-none", style: {
22258
+ backgroundImage: "linear-gradient(45deg, #808080 25%, transparent 25%), linear-gradient(-45deg, #808080 25%, transparent 25%), linear-gradient(45deg, transparent 75%, #808080 75%), linear-gradient(-45deg, transparent 75%, #808080 75%)",
22259
+ backgroundSize: "20px 20px",
22260
+ backgroundPosition: "0 0, 0 10px, 10px -10px, -10px 0px"
22261
+ } }),
22262
+ !imgNaturalSize && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 flex items-center justify-center z-10", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-4", children: [
22263
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative w-48 h-36 rounded-xl bg-zinc-800/60 overflow-hidden border border-zinc-700/30", children: [
22264
+ /* @__PURE__ */ jsxRuntime.jsx(
22265
+ "div",
22266
+ {
22267
+ className: "absolute inset-0 bg-gradient-to-r from-transparent via-zinc-600/20 to-transparent",
22268
+ style: {
22269
+ animation: "shimmer 1.5s ease-in-out infinite"
22270
+ }
22271
+ }
22272
+ ),
22273
+ /* @__PURE__ */ jsxRuntime.jsx("style", { children: `
22274
+ @keyframes shimmer {
22275
+ 0% { transform: translateX(-100%); }
22276
+ 100% { transform: translateX(100%); }
22277
+ }
22278
+ ` }),
22279
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.FileImage, { size: 32, className: "text-zinc-600" }) })
22280
+ ] }),
22281
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
22282
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative w-5 h-5", children: [
22283
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 rounded-full border-2 border-zinc-700" }),
22284
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 rounded-full border-2 border-t-[#d8ff00] animate-spin" })
22285
+ ] }),
22286
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-zinc-500", children: "\u52A0\u8F7D\u4E2D..." })
22287
+ ] })
22288
+ ] }) }),
22289
+ /* @__PURE__ */ jsxRuntime.jsx(
22290
+ "div",
22082
22291
  {
22083
- src: resolvedHdUrl,
22084
- alt: "Generated image",
22085
- className: "max-w-full max-h-[60vh] object-contain rounded-lg shadow-2xl",
22086
- loading: "lazy",
22087
- onLoad: (e) => {
22088
- const img = e.target;
22089
- setImgNaturalSize({ width: img.naturalWidth, height: img.naturalHeight });
22090
- }
22292
+ ref: scrollRef,
22293
+ className: cn3(
22294
+ "absolute inset-0 overflow-auto",
22295
+ isDragging ? "cursor-grabbing" : "cursor-grab",
22296
+ !imgNaturalSize && "invisible"
22297
+ // 加载完成前隐藏
22298
+ ),
22299
+ onWheel: handleWheel,
22300
+ onMouseDown: handleMouseDown,
22301
+ onMouseMove: handleMouseMove,
22302
+ onMouseUp: handleMouseUp,
22303
+ onMouseLeave: handleMouseUp,
22304
+ onDoubleClick: handleDoubleClick,
22305
+ children: /* @__PURE__ */ jsxRuntime.jsx(
22306
+ "div",
22307
+ {
22308
+ className: "flex items-center justify-center",
22309
+ style: {
22310
+ minWidth: "100%",
22311
+ minHeight: "100%",
22312
+ width: displayWidth > 0 ? Math.max(displayWidth + 48, scrollRef.current?.clientWidth || 0) : "100%",
22313
+ height: displayHeight > 0 ? Math.max(displayHeight + 48, scrollRef.current?.clientHeight || 0) : "100%",
22314
+ padding: "24px"
22315
+ },
22316
+ children: /* @__PURE__ */ jsxRuntime.jsx(
22317
+ "img",
22318
+ {
22319
+ ref: imageRef,
22320
+ src: resolvedHdUrl,
22321
+ alt: "Generated image",
22322
+ className: cn3(
22323
+ "rounded-lg shadow-2xl select-none transition-opacity duration-300",
22324
+ imgNaturalSize ? "opacity-100" : "opacity-0"
22325
+ ),
22326
+ draggable: false,
22327
+ style: {
22328
+ width: displayWidth > 0 ? displayWidth : "auto",
22329
+ height: displayHeight > 0 ? displayHeight : "auto",
22330
+ maxWidth: "none",
22331
+ maxHeight: "none"
22332
+ },
22333
+ onLoad: handleImageLoad
22334
+ }
22335
+ )
22336
+ }
22337
+ )
22091
22338
  }
22092
- )
22093
- }
22094
- ),
22095
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute top-4 right-4 flex items-center gap-1.5 z-20", children: [
22096
- /* @__PURE__ */ jsxRuntime.jsx(
22097
- "button",
22098
- {
22099
- onClick: () => setShowInfo((prev) => !prev),
22100
- className: cn3(
22101
- "p-2 rounded-lg backdrop-blur-sm transition-colors",
22102
- showInfo ? "bg-[#d8ff00]/20 text-[#d8ff00]" : "bg-black/30 text-white/70 hover:text-white hover:bg-black/50"
22339
+ ),
22340
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute top-3 right-3 flex items-center gap-1 z-50", children: [
22341
+ /* @__PURE__ */ jsxRuntime.jsx(
22342
+ "button",
22343
+ {
22344
+ onClick: () => setShowInfo((prev) => !prev),
22345
+ className: cn3(
22346
+ "p-2 rounded-lg backdrop-blur-md transition-all",
22347
+ showInfo ? "bg-[#d8ff00]/20 text-[#d8ff00] shadow-lg shadow-[#d8ff00]/10" : "bg-zinc-900/70 text-zinc-400 hover:text-white hover:bg-zinc-800/80"
22348
+ ),
22349
+ title: showInfo ? "\u9690\u85CF\u8BE6\u60C5" : "\u663E\u793A\u8BE6\u60C5",
22350
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.FileText, { size: 15 })
22351
+ }
22103
22352
  ),
22104
- title: showInfo ? "\u9690\u85CF\u8BE6\u60C5" : "\u663E\u793A\u8BE6\u60C5",
22105
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.FileText, { size: 16 })
22106
- }
22107
- ),
22108
- /* @__PURE__ */ jsxRuntime.jsx(
22109
- "button",
22110
- {
22111
- onClick: handleDownload,
22112
- className: "p-2 bg-black/30 text-white/70 hover:text-white hover:bg-black/50 rounded-lg backdrop-blur-sm transition-colors",
22113
- title: "\u4E0B\u8F7D\u56FE\u7247",
22114
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Download, { size: 16 })
22115
- }
22116
- )
22117
- ] }),
22118
- imgNaturalSize && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute bottom-4 left-4 z-20 flex items-center gap-2 px-2.5 py-1.5 bg-black/40 backdrop-blur-sm rounded-lg", children: [
22119
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.FileImage, { size: 12, className: "text-white/60" }),
22120
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-[11px] text-white/80 font-mono", children: [
22121
- imgNaturalSize.width,
22122
- " \xD7 ",
22123
- imgNaturalSize.height
22124
- ] })
22125
- ] })
22126
- ] }),
22353
+ /* @__PURE__ */ jsxRuntime.jsx(
22354
+ "button",
22355
+ {
22356
+ onClick: handleDownload,
22357
+ className: "p-2 bg-zinc-900/70 text-zinc-400 hover:text-white hover:bg-zinc-800/80 rounded-lg backdrop-blur-md transition-all",
22358
+ title: "\u4E0B\u8F7D\u539F\u56FE",
22359
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Download, { size: 15 })
22360
+ }
22361
+ )
22362
+ ] }),
22363
+ imgNaturalSize && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute bottom-3 left-3 z-50 flex items-center gap-1.5 px-2.5 py-1.5 bg-zinc-900/80 backdrop-blur-md rounded-lg border border-zinc-700/50", children: [
22364
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.FileImage, { size: 12, className: "text-zinc-500" }),
22365
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-[11px] text-zinc-300 font-mono", children: [
22366
+ imgNaturalSize.width,
22367
+ " \xD7 ",
22368
+ imgNaturalSize.height
22369
+ ] })
22370
+ ] }),
22371
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute bottom-3 left-1/2 -translate-x-1/2 z-50", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-0.5 px-1.5 py-1 bg-zinc-900/90 backdrop-blur-md rounded-xl border border-zinc-700/50 shadow-xl", children: [
22372
+ /* @__PURE__ */ jsxRuntime.jsx(
22373
+ "button",
22374
+ {
22375
+ onClick: handleZoomOut,
22376
+ disabled: zoom <= MIN_ZOOM,
22377
+ className: "p-1.5 text-zinc-400 hover:text-white hover:bg-zinc-700/50 disabled:opacity-30 disabled:cursor-not-allowed rounded-lg transition-all",
22378
+ title: "\u7F29\u5C0F (Ctrl+\u6EDA\u8F6E)",
22379
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Minus, { size: 14, strokeWidth: 2 })
22380
+ }
22381
+ ),
22382
+ /* @__PURE__ */ jsxRuntime.jsxs(
22383
+ "button",
22384
+ {
22385
+ onClick: handleActualSize,
22386
+ className: "min-w-[52px] px-2 py-1 text-[11px] font-medium text-zinc-200 hover:text-white hover:bg-zinc-700/50 rounded-lg transition-all font-mono",
22387
+ title: "\u70B9\u51FB\u6062\u590D 100%",
22388
+ children: [
22389
+ Math.round(zoom),
22390
+ "%"
22391
+ ]
22392
+ }
22393
+ ),
22394
+ /* @__PURE__ */ jsxRuntime.jsx(
22395
+ "button",
22396
+ {
22397
+ onClick: handleZoomIn,
22398
+ disabled: zoom >= MAX_ZOOM,
22399
+ className: "p-1.5 text-zinc-400 hover:text-white hover:bg-zinc-700/50 disabled:opacity-30 disabled:cursor-not-allowed rounded-lg transition-all",
22400
+ title: "\u653E\u5927 (Ctrl+\u6EDA\u8F6E)",
22401
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { size: 14, strokeWidth: 2 })
22402
+ }
22403
+ ),
22404
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-px h-4 bg-zinc-700/50 mx-0.5" }),
22405
+ /* @__PURE__ */ jsxRuntime.jsx(
22406
+ "button",
22407
+ {
22408
+ onClick: handleFitToScreen,
22409
+ className: cn3(
22410
+ "p-1.5 rounded-lg transition-all",
22411
+ Math.abs(zoom - fitZoom) < 1 ? "text-[#d8ff00] bg-[#d8ff00]/10" : "text-zinc-400 hover:text-white hover:bg-zinc-700/50"
22412
+ ),
22413
+ title: "\u9002\u5E94\u5C4F\u5E55",
22414
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Maximize, { size: 13, strokeWidth: 2 })
22415
+ }
22416
+ ),
22417
+ /* @__PURE__ */ jsxRuntime.jsx(
22418
+ "button",
22419
+ {
22420
+ onClick: handleActualSize,
22421
+ className: cn3(
22422
+ "p-1.5 rounded-lg transition-all",
22423
+ Math.abs(zoom - 100) < 1 ? "text-[#d8ff00] bg-[#d8ff00]/10" : "text-zinc-400 hover:text-white hover:bg-zinc-700/50"
22424
+ ),
22425
+ title: "\u539F\u59CB\u5C3A\u5BF8 (100%)",
22426
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RotateCcw, { size: 13, strokeWidth: 2 })
22427
+ }
22428
+ )
22429
+ ] }) })
22430
+ ]
22431
+ }
22432
+ ),
22127
22433
  showInfo && (generationParams || toolName) && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-shrink-0 border-t border-zinc-800/50 agent-sdk-light:border-zinc-200 bg-zinc-900/80 agent-sdk-light:bg-zinc-50 max-h-[40%] overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-5 py-4 space-y-4", children: [
22128
22434
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
22129
22435
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2.5", children: [
@@ -23655,6 +23961,7 @@ function Sidebar({
23655
23961
  onNew,
23656
23962
  agentName,
23657
23963
  agentType,
23964
+ agentIcon,
23658
23965
  collapsed,
23659
23966
  onToggle
23660
23967
  }) {
@@ -23678,7 +23985,7 @@ function Sidebar({
23678
23985
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-3 border-b border-zinc-800/50", children: [
23679
23986
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between mb-3", children: [
23680
23987
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 min-w-0", children: [
23681
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-7 h-7 rounded-lg bg-[#d8ff00]/10 flex items-center justify-center flex-shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Bot, { size: 14, className: "text-[#d8ff00]" }) }),
23988
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-7 h-7 rounded-lg bg-[#d8ff00]/10 flex items-center justify-center flex-shrink-0", children: agentIcon ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: getImageUrl(agentIcon), alt: "Agent Icon", className: "w-7 h-7 rounded-lg" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Bot, { size: 14, className: "text-[#d8ff00]" }) }),
23682
23989
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium text-white truncate", children: agentName || "Agent" })
23683
23990
  ] }),
23684
23991
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex gap-0.5", children: /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: onToggle, className: "p-1.5 text-zinc-500 hover:text-zinc-300 hover:bg-zinc-800 rounded-lg", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.PanelLeftClose, { size: 14 }) }) })
@@ -24350,7 +24657,11 @@ function useArtifactPanel({ currentSessionId }) {
24350
24657
  return;
24351
24658
  }
24352
24659
  const existingArtifact = Object.values(artifacts).find(
24353
- (a) => a.currentContent === data.content && a.type === data.type
24660
+ (a) => {
24661
+ const sameContent = a.currentContent === data.content && a.type === data.type;
24662
+ const sameId = a?.metadata?.workId === data.metadata?.workId;
24663
+ return sameContent || sameId;
24664
+ }
24354
24665
  );
24355
24666
  if (existingArtifact) {
24356
24667
  setActiveArtifact(existingArtifact.id);
@@ -25198,6 +25509,7 @@ var AgentChat = React16__namespace.default.forwardRef(({
25198
25509
  tools: _tools,
25199
25510
  setTools,
25200
25511
  setSkills,
25512
+ mainAgentIcon,
25201
25513
  setShowItemTime,
25202
25514
  setSubAgentConfigs,
25203
25515
  setMainAgentPublicId,
@@ -25490,6 +25802,7 @@ var AgentChat = React16__namespace.default.forwardRef(({
25490
25802
  onNew: handleNew,
25491
25803
  agentName,
25492
25804
  agentType,
25805
+ agentIcon: mainAgentIcon,
25493
25806
  collapsed,
25494
25807
  onToggle: () => setCollapsed(!collapsed)
25495
25808
  }
@@ -25518,7 +25831,7 @@ var AgentChat = React16__namespace.default.forwardRef(({
25518
25831
  "div",
25519
25832
  {
25520
25833
  ref: containerRef,
25521
- className: "flex-1 flex min-h-0 relative",
25834
+ className: "flex-1 relative min-h-0",
25522
25835
  "data-artifact-container": true,
25523
25836
  children: [
25524
25837
  isDragging && /* @__PURE__ */ jsxRuntime.jsx(
@@ -25532,20 +25845,20 @@ var AgentChat = React16__namespace.default.forwardRef(({
25532
25845
  "div",
25533
25846
  {
25534
25847
  className: cn3(
25535
- "flex flex-col min-h-0 overflow-hidden",
25536
- !isDragging && "transition-[width,opacity,transform] duration-300 ease-out",
25537
- isArtifactFullscreen ? "w-0 min-w-0 opacity-0 -translate-x-4" : currentArtifact ? "min-w-[350px]" : "w-full"
25848
+ "flex flex-col min-h-0 h-full overflow-hidden",
25849
+ !isDragging && "transition-[width,opacity] duration-300 ease-out",
25850
+ isArtifactFullscreen ? "w-0 opacity-0 pointer-events-none" : currentArtifact ? "min-w-[350px]" : "w-full"
25538
25851
  ),
25539
25852
  style: currentArtifact && !isArtifactFullscreen ? { width: `${100 - artifactPanelWidth}%` } : void 0,
25540
25853
  children: [
25541
- showHeader && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 h-12 px-3 border-b border-zinc-800/50 bg-zinc-950/80 backdrop-blur-sm flex-shrink-0", children: [
25854
+ showHeader ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 h-12 px-3 border-b border-zinc-800/50 bg-zinc-950/80 backdrop-blur-sm flex-shrink-0", children: [
25542
25855
  /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: () => setMobileOpen(true), className: "lg:hidden p-1.5 text-zinc-500 hover:text-zinc-300 hover:bg-zinc-800 rounded-lg", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.PanelLeft, { size: 18 }) }),
25543
25856
  onNavigateBack && /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: onNavigateBack, className: "p-1.5 text-zinc-500 hover:text-zinc-300 hover:bg-zinc-800 rounded-lg", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowLeft, { size: 18 }) }),
25544
25857
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-4 w-px bg-zinc-800 mx-1" }),
25545
25858
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-zinc-300 font-medium", children: agentName || "Agent" }),
25546
25859
  agentType && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-zinc-600 bg-zinc-800/50 px-1.5 py-0.5 rounded", children: agentType === "BUILTIN" ? "\u5185\u7F6E" : agentType === "EXTERNAL" ? "\u5916\u90E8" : "\u591AAgent" }),
25547
25860
  onNavigateToSettings && /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: onNavigateToSettings, className: "ml-auto p-1.5 text-zinc-500 hover:text-zinc-300 hover:bg-zinc-800 rounded-lg", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Settings, { size: 18 }) })
25548
- ] }),
25861
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: () => setMobileOpen(true), className: "lg:hidden p-1.5 text-zinc-500 hover:text-zinc-300 hover:bg-zinc-800 rounded-lg w-8", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.PanelLeft, { size: 18 }) }),
25549
25862
  /* @__PURE__ */ jsxRuntime.jsx(
25550
25863
  ChatWindow_default,
25551
25864
  {
@@ -25623,9 +25936,9 @@ var AgentChat = React16__namespace.default.forwardRef(({
25623
25936
  "div",
25624
25937
  {
25625
25938
  className: cn3(
25626
- "flex-shrink-0 overflow-hidden h-full relative",
25939
+ "absolute right-0 top-0 h-full overflow-hidden",
25627
25940
  !isDragging && "transition-[width,opacity] duration-300 ease-out",
25628
- currentArtifact ? isArtifactFullscreen ? "w-full min-w-0 border-l-0" : "min-w-[400px]" : "w-0 min-w-0 opacity-0"
25941
+ currentArtifact ? isArtifactFullscreen ? "w-full" : "min-w-[400px]" : "w-0 opacity-0"
25629
25942
  ),
25630
25943
  style: currentArtifact && !isArtifactFullscreen ? { width: `${artifactPanelWidth}%` } : void 0,
25631
25944
  children: [
@@ -25655,21 +25968,18 @@ var AgentChat = React16__namespace.default.forwardRef(({
25655
25968
  }
25656
25969
  },
25657
25970
  onReorderArtifacts: (fromIndex, toIndex) => {
25658
- const newOrder = [...artifactList.map((a) => a.id)];
25659
- const [moved] = newOrder.splice(fromIndex, 1);
25660
- newOrder.splice(toIndex, 0, moved);
25661
- reorderArtifacts(newOrder);
25971
+ reorderArtifacts(fromIndex, toIndex);
25662
25972
  },
25663
25973
  onContentChange: (content) => {
25664
25974
  if (activeArtifact) {
25665
- updateArtifactContent(activeArtifact.id, content);
25975
+ updateArtifactContent(activeArtifact.id, content, "user");
25666
25976
  }
25667
25977
  },
25668
25978
  onSave: async (artifactId, content) => {
25669
25979
  try {
25670
25980
  const res = await artifactService.updateContent(artifactId, content);
25671
25981
  if (res.success) {
25672
- updateArtifactContent(artifactId, content);
25982
+ updateArtifactContent(artifactId, content, "user");
25673
25983
  toast.success("\u4EA7\u7269\u5DF2\u4FDD\u5B58");
25674
25984
  } else {
25675
25985
  toast.error("\u4FDD\u5B58\u5931\u8D25");