@malette/agent-sdk 0.1.1-alpha.0 → 0.1.2
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 +2740 -158
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2735 -160
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +1463 -1997
- package/package.json +7 -5
package/dist/index.mjs
CHANGED
|
@@ -4,7 +4,7 @@ import { create } from 'zustand';
|
|
|
4
4
|
import { devtools } from 'zustand/middleware';
|
|
5
5
|
import * as React20 from 'react';
|
|
6
6
|
import React20__default, { memo, useState, useMemo, useEffect, createContext, useCallback, useRef, useImperativeHandle, useContext } from 'react';
|
|
7
|
-
import { Loader2, Check, AlertCircle, ChevronUp, ChevronDown, ExternalLink, Download, Bot, Users, X, Copy, Image, Maximize2, Clock, Sparkles, AlertTriangle, Play, Pencil, Square, RotateCcw, SkipForward, FileText, Code2, FileJson, FileCode, CheckCheck, Eye, Zap, ChevronRight, Lightbulb, RefreshCw, Trash2, ImageIcon, GripVertical, Minimize2, Smartphone, Tablet, Monitor, Globe, PanelLeft, ArrowLeft, Settings, CheckCircle2, Brain, UserCheck, Shield, User, Plus, PanelLeftClose, Search, MessageSquare, ImagePlus, Send, HelpCircle, Lock, Calendar, Link, Share2, Wand2,
|
|
7
|
+
import { Loader2, Check, AlertCircle, ChevronUp, ChevronDown, ExternalLink, Download, Bot, Users, X, Copy, Image, Maximize2, Clock, Sparkles, AlertTriangle, Play, Pencil, Square, RotateCcw, SkipForward, FileText, Code2, FileJson, FileCode, CheckCheck, Eye, Video, Zap, ChevronRight, Lightbulb, RefreshCw, Trash2, ImageIcon, GripVertical, Minimize2, Smartphone, Tablet, Monitor, Globe, FileImage, ChevronLeft, LayoutGrid, Undo2, Redo2, Save, PanelLeft, ArrowLeft, Settings, CheckCircle2, Brain, UserCheck, Shield, User, Plus, PanelLeftClose, Search, MessageSquare, Unlink, ImagePlus, Send, HelpCircle, Lock, Calendar, Link, Share2, Wand2, Mic, CheckCircle, ListOrdered, Ban, Pause, Tag, Folder, EyeOff, FileEdit, BookOpen, Edit, XCircle, ArrowRight } from 'lucide-react';
|
|
8
8
|
import ReactMarkdown from 'react-markdown';
|
|
9
9
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
10
10
|
import { useShallow } from 'zustand/react/shallow';
|
|
@@ -12,6 +12,7 @@ import * as DialogPrimitive from '@radix-ui/react-dialog';
|
|
|
12
12
|
import { Slot } from '@radix-ui/react-slot';
|
|
13
13
|
import * as ScrollAreaPrimitive from '@radix-ui/react-scroll-area';
|
|
14
14
|
import 'react-dom';
|
|
15
|
+
import { marked } from 'marked';
|
|
15
16
|
|
|
16
17
|
// src/lib/fetch.ts
|
|
17
18
|
async function fetcher(input, init, isServer = false) {
|
|
@@ -398,6 +399,52 @@ AI\u56DE\u590D\u6458\u8981\uFF1A${assistantMessage.slice(0, 200)}` : ""}`
|
|
|
398
399
|
return userMessage.slice(0, 20) + (userMessage.length > 20 ? "..." : "");
|
|
399
400
|
}
|
|
400
401
|
}
|
|
402
|
+
var artifactService = {
|
|
403
|
+
/**
|
|
404
|
+
* 获取会话的所有产物列表
|
|
405
|
+
*/
|
|
406
|
+
list: async (sessionId) => {
|
|
407
|
+
return fetcher(`${API_BASE}/sessions/${sessionId}/artifacts`);
|
|
408
|
+
},
|
|
409
|
+
/**
|
|
410
|
+
* 获取产物详情
|
|
411
|
+
*/
|
|
412
|
+
get: async (artifactId) => {
|
|
413
|
+
return fetcher(`${API_BASE}/artifacts/${artifactId}`);
|
|
414
|
+
},
|
|
415
|
+
/**
|
|
416
|
+
* 更新产物内容(用户编辑后保存)
|
|
417
|
+
*/
|
|
418
|
+
updateContent: async (artifactId, content) => {
|
|
419
|
+
return fetcher(`${API_BASE}/artifacts/${artifactId}/content`, {
|
|
420
|
+
method: "PUT",
|
|
421
|
+
body: JSON.stringify({ content })
|
|
422
|
+
});
|
|
423
|
+
},
|
|
424
|
+
/**
|
|
425
|
+
* 删除产物
|
|
426
|
+
*/
|
|
427
|
+
delete: async (artifactId) => {
|
|
428
|
+
return fetcher(`${API_BASE}/artifacts/${artifactId}`, {
|
|
429
|
+
method: "DELETE"
|
|
430
|
+
});
|
|
431
|
+
},
|
|
432
|
+
/**
|
|
433
|
+
* 获取产物版本历史
|
|
434
|
+
*/
|
|
435
|
+
getVersions: async (artifactId) => {
|
|
436
|
+
return fetcher(`${API_BASE}/artifacts/${artifactId}/versions`);
|
|
437
|
+
},
|
|
438
|
+
/**
|
|
439
|
+
* 回滚到指定版本
|
|
440
|
+
*/
|
|
441
|
+
revert: async (artifactId, version) => {
|
|
442
|
+
return fetcher(`${API_BASE}/artifacts/${artifactId}/revert`, {
|
|
443
|
+
method: "POST",
|
|
444
|
+
body: JSON.stringify({ version })
|
|
445
|
+
});
|
|
446
|
+
}
|
|
447
|
+
};
|
|
401
448
|
var shareService = {
|
|
402
449
|
/**
|
|
403
450
|
* 创建分享链接
|
|
@@ -786,6 +833,9 @@ var useAgentStore = create()(
|
|
|
786
833
|
subAgents: [],
|
|
787
834
|
tools: [],
|
|
788
835
|
skills: [],
|
|
836
|
+
artifacts: {},
|
|
837
|
+
artifactOrder: [],
|
|
838
|
+
activeArtifactId: null,
|
|
789
839
|
// ============ Session Actions ============
|
|
790
840
|
setSessions: (sessions) => set({ sessions }, false, "setSessions"),
|
|
791
841
|
setTools: (tools) => set({ tools }, false, "setTools"),
|
|
@@ -1150,19 +1200,99 @@ var useAgentStore = create()(
|
|
|
1150
1200
|
false,
|
|
1151
1201
|
"setActiveSubAgent"
|
|
1152
1202
|
),
|
|
1203
|
+
// ============ Artifact Actions ============
|
|
1204
|
+
upsertArtifact: (artifact) => set(
|
|
1205
|
+
(state) => {
|
|
1206
|
+
const isNew = !state.artifacts[artifact.id];
|
|
1207
|
+
return {
|
|
1208
|
+
artifacts: {
|
|
1209
|
+
...state.artifacts,
|
|
1210
|
+
[artifact.id]: artifact
|
|
1211
|
+
},
|
|
1212
|
+
artifactOrder: isNew ? [...state.artifactOrder, artifact.id] : state.artifactOrder
|
|
1213
|
+
};
|
|
1214
|
+
},
|
|
1215
|
+
false,
|
|
1216
|
+
"upsertArtifact"
|
|
1217
|
+
),
|
|
1218
|
+
updateArtifactContent: (artifactId, content, source) => set(
|
|
1219
|
+
(state) => {
|
|
1220
|
+
const existing = state.artifacts[artifactId];
|
|
1221
|
+
if (!existing) return state;
|
|
1222
|
+
return {
|
|
1223
|
+
artifacts: {
|
|
1224
|
+
...state.artifacts,
|
|
1225
|
+
[artifactId]: {
|
|
1226
|
+
...existing,
|
|
1227
|
+
currentContent: content,
|
|
1228
|
+
version: existing.version + 1,
|
|
1229
|
+
gmtModified: (/* @__PURE__ */ new Date()).toISOString()
|
|
1230
|
+
}
|
|
1231
|
+
}
|
|
1232
|
+
};
|
|
1233
|
+
},
|
|
1234
|
+
false,
|
|
1235
|
+
"updateArtifactContent"
|
|
1236
|
+
),
|
|
1237
|
+
setActiveArtifact: (artifactId) => set(
|
|
1238
|
+
{ activeArtifactId: artifactId },
|
|
1239
|
+
false,
|
|
1240
|
+
"setActiveArtifact"
|
|
1241
|
+
),
|
|
1242
|
+
removeArtifact: (artifactId) => set(
|
|
1243
|
+
(state) => {
|
|
1244
|
+
const { [artifactId]: _, ...remaining } = state.artifacts;
|
|
1245
|
+
return {
|
|
1246
|
+
artifacts: remaining,
|
|
1247
|
+
artifactOrder: state.artifactOrder.filter((id) => id !== artifactId),
|
|
1248
|
+
activeArtifactId: state.activeArtifactId === artifactId ? null : state.activeArtifactId
|
|
1249
|
+
};
|
|
1250
|
+
},
|
|
1251
|
+
false,
|
|
1252
|
+
"removeArtifact"
|
|
1253
|
+
),
|
|
1254
|
+
clearArtifacts: () => set(
|
|
1255
|
+
{ artifacts: {}, artifactOrder: [], activeArtifactId: null },
|
|
1256
|
+
false,
|
|
1257
|
+
"clearArtifacts"
|
|
1258
|
+
),
|
|
1259
|
+
setArtifacts: (artifacts) => set(
|
|
1260
|
+
{
|
|
1261
|
+
artifacts: artifacts.reduce((acc, a) => {
|
|
1262
|
+
acc[a.id] = a;
|
|
1263
|
+
return acc;
|
|
1264
|
+
}, {}),
|
|
1265
|
+
artifactOrder: artifacts.map((a) => a.id)
|
|
1266
|
+
},
|
|
1267
|
+
false,
|
|
1268
|
+
"setArtifacts"
|
|
1269
|
+
),
|
|
1270
|
+
reorderArtifacts: (fromIndex, toIndex) => set(
|
|
1271
|
+
(state) => {
|
|
1272
|
+
const newOrder = [...state.artifactOrder];
|
|
1273
|
+
const [movedId] = newOrder.splice(fromIndex, 1);
|
|
1274
|
+
newOrder.splice(toIndex, 0, movedId);
|
|
1275
|
+
return { artifactOrder: newOrder };
|
|
1276
|
+
},
|
|
1277
|
+
false,
|
|
1278
|
+
"reorderArtifacts"
|
|
1279
|
+
),
|
|
1153
1280
|
// ============ 复合操作 ============
|
|
1154
1281
|
startNewChat: (sessionId) => {
|
|
1155
1282
|
set(
|
|
1156
1283
|
(state) => ({
|
|
1157
1284
|
messages: [],
|
|
1158
|
-
chatUI: initialChatUIState
|
|
1285
|
+
chatUI: initialChatUIState,
|
|
1286
|
+
artifacts: {},
|
|
1287
|
+
artifactOrder: [],
|
|
1288
|
+
activeArtifactId: null
|
|
1159
1289
|
}),
|
|
1160
1290
|
false,
|
|
1161
1291
|
"startNewChat"
|
|
1162
1292
|
);
|
|
1163
1293
|
},
|
|
1164
1294
|
resetChatState: () => set(
|
|
1165
|
-
{ chatUI: initialChatUIState },
|
|
1295
|
+
{ chatUI: initialChatUIState, artifacts: {}, artifactOrder: [], activeArtifactId: null },
|
|
1166
1296
|
false,
|
|
1167
1297
|
"resetChatState"
|
|
1168
1298
|
)
|
|
@@ -1189,6 +1319,23 @@ var useCurrentSession = () => useAgentStore((state) => state.currentSession);
|
|
|
1189
1319
|
var useSessions = () => useAgentStore((state) => state.sessions);
|
|
1190
1320
|
var useSubAgents = () => useAgentStore((state) => state.subAgents);
|
|
1191
1321
|
var useChatUI = () => useAgentStore((state) => state.chatUI);
|
|
1322
|
+
var useArtifacts = () => useAgentStore((state) => state.artifacts);
|
|
1323
|
+
var useActiveArtifactId = () => useAgentStore((state) => state.activeArtifactId);
|
|
1324
|
+
var useActiveArtifact = () => {
|
|
1325
|
+
const artifacts = useAgentStore((state) => state.artifacts);
|
|
1326
|
+
const activeId = useAgentStore((state) => state.activeArtifactId);
|
|
1327
|
+
return activeId ? artifacts[activeId] ?? null : null;
|
|
1328
|
+
};
|
|
1329
|
+
var useArtifactList = () => {
|
|
1330
|
+
const artifacts = useAgentStore((state) => state.artifacts);
|
|
1331
|
+
const artifactOrder = useAgentStore((state) => state.artifactOrder);
|
|
1332
|
+
const ordered = artifactOrder.map((id) => artifacts[id]).filter(Boolean);
|
|
1333
|
+
const unordered = Object.values(artifacts).filter(
|
|
1334
|
+
(a) => !artifactOrder.includes(a.id)
|
|
1335
|
+
);
|
|
1336
|
+
return [...ordered, ...unordered];
|
|
1337
|
+
};
|
|
1338
|
+
var useArtifactOrder = () => useAgentStore((state) => state.artifactOrder);
|
|
1192
1339
|
var useSessionsLoading = () => useAgentStore((state) => state.sessionsLoading);
|
|
1193
1340
|
var findMessageById = (messageId) => {
|
|
1194
1341
|
return useAgentStore.getState().messages.find((m) => m.messageId === messageId);
|
|
@@ -1377,7 +1524,11 @@ function useSSE(options) {
|
|
|
1377
1524
|
setShowPlanConfirmDialog,
|
|
1378
1525
|
setShowHumanInputDialog,
|
|
1379
1526
|
setWaitingStepId,
|
|
1380
|
-
clearPlanState
|
|
1527
|
+
clearPlanState,
|
|
1528
|
+
// Artifact actions
|
|
1529
|
+
upsertArtifact,
|
|
1530
|
+
updateArtifactContent,
|
|
1531
|
+
setActiveArtifact
|
|
1381
1532
|
} = useAgentStore();
|
|
1382
1533
|
const clearHeartbeatTimeout = useCallback(() => {
|
|
1383
1534
|
if (heartbeatTimeoutRef.current) {
|
|
@@ -1575,6 +1726,37 @@ function useSSE(options) {
|
|
|
1575
1726
|
});
|
|
1576
1727
|
return;
|
|
1577
1728
|
}
|
|
1729
|
+
if (eventType === "artifact_created") {
|
|
1730
|
+
const sessionId = useAgentStore.getState().currentSession?.sessionId;
|
|
1731
|
+
if (data.artifactId && sessionId) {
|
|
1732
|
+
const artifactType = data.type || "code";
|
|
1733
|
+
const artifactEntry = {
|
|
1734
|
+
id: data.artifactId,
|
|
1735
|
+
sessionId,
|
|
1736
|
+
type: artifactType,
|
|
1737
|
+
title: data.title || "Untitled",
|
|
1738
|
+
currentContent: data.content || "",
|
|
1739
|
+
language: data.language,
|
|
1740
|
+
version: 1,
|
|
1741
|
+
source: "tool",
|
|
1742
|
+
sourceId: data.sourceToolCallId,
|
|
1743
|
+
metadata: data.metadata,
|
|
1744
|
+
gmtCreate: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1745
|
+
gmtModified: (/* @__PURE__ */ new Date()).toISOString()
|
|
1746
|
+
};
|
|
1747
|
+
upsertArtifact(artifactEntry);
|
|
1748
|
+
setActiveArtifact(data.artifactId);
|
|
1749
|
+
console.log("[SSE] Artifact created:", data.artifactId, data.title);
|
|
1750
|
+
}
|
|
1751
|
+
return;
|
|
1752
|
+
}
|
|
1753
|
+
if (eventType === "artifact_updated") {
|
|
1754
|
+
if (data.artifactId && data.content) {
|
|
1755
|
+
updateArtifactContent(data.artifactId, data.content, "ai");
|
|
1756
|
+
console.log("[SSE] Artifact updated:", data.artifactId, "version:", data.version);
|
|
1757
|
+
}
|
|
1758
|
+
return;
|
|
1759
|
+
}
|
|
1578
1760
|
const rawToolCalls = data.toolCalls || data.tool_calls || data.actions || [];
|
|
1579
1761
|
const normalizedToolCalls = rawToolCalls.length > 0 ? normalizeToolCalls2(rawToolCalls) : void 0;
|
|
1580
1762
|
let finalToolCalls = normalizedToolCalls;
|
|
@@ -2280,7 +2462,7 @@ function useSSE(options) {
|
|
|
2280
2462
|
try {
|
|
2281
2463
|
console.log("[SSE] Step 1: Sending message...");
|
|
2282
2464
|
const response = await messageService.sendStream(
|
|
2283
|
-
{ sessionId, content, frontendTools: sendOptions?.frontendTools },
|
|
2465
|
+
{ sessionId, content, frontendTools: sendOptions?.frontendTools, artifactContext: sendOptions?.artifactContext },
|
|
2284
2466
|
abortControllerRef.current.signal
|
|
2285
2467
|
);
|
|
2286
2468
|
const reader = response.body?.getReader();
|
|
@@ -2420,6 +2602,92 @@ function useSSE(options) {
|
|
|
2420
2602
|
isConnected
|
|
2421
2603
|
};
|
|
2422
2604
|
}
|
|
2605
|
+
var CHANNEL_ID = "adic-agent-canvas-bridge";
|
|
2606
|
+
function useCanvasBridge(options = {}) {
|
|
2607
|
+
const {
|
|
2608
|
+
canvasIframeRef,
|
|
2609
|
+
targetOrigin = "*",
|
|
2610
|
+
enabled = false,
|
|
2611
|
+
onArtifactSelected,
|
|
2612
|
+
onArtifactContentChanged
|
|
2613
|
+
} = options;
|
|
2614
|
+
const optionsRef = useRef(options);
|
|
2615
|
+
optionsRef.current = options;
|
|
2616
|
+
const postToCanvas = useCallback((type, payload) => {
|
|
2617
|
+
const iframe = canvasIframeRef?.current;
|
|
2618
|
+
if (!iframe?.contentWindow) {
|
|
2619
|
+
console.warn("[CanvasBridge] Canvas iframe not available");
|
|
2620
|
+
return;
|
|
2621
|
+
}
|
|
2622
|
+
const envelope = {
|
|
2623
|
+
channel: CHANNEL_ID,
|
|
2624
|
+
message: {
|
|
2625
|
+
type,
|
|
2626
|
+
payload,
|
|
2627
|
+
timestamp: Date.now()
|
|
2628
|
+
}
|
|
2629
|
+
};
|
|
2630
|
+
iframe.contentWindow.postMessage(envelope, targetOrigin);
|
|
2631
|
+
console.log("[CanvasBridge] Sent:", type, payload.artifactId || payload.artifact?.id);
|
|
2632
|
+
}, [canvasIframeRef, targetOrigin]);
|
|
2633
|
+
useEffect(() => {
|
|
2634
|
+
if (!enabled) return;
|
|
2635
|
+
const handleMessage = (event) => {
|
|
2636
|
+
if (targetOrigin !== "*" && event.origin !== targetOrigin) return;
|
|
2637
|
+
const envelope = event.data;
|
|
2638
|
+
if (!envelope || envelope.channel !== CHANNEL_ID) return;
|
|
2639
|
+
const { type, payload } = envelope.message;
|
|
2640
|
+
console.log("[CanvasBridge] Received:", type, payload);
|
|
2641
|
+
switch (type) {
|
|
2642
|
+
case "artifact_selected": {
|
|
2643
|
+
if (payload.artifactId) {
|
|
2644
|
+
optionsRef.current.onArtifactSelected?.(payload.artifactId);
|
|
2645
|
+
useAgentStore.getState().setActiveArtifact(payload.artifactId);
|
|
2646
|
+
}
|
|
2647
|
+
break;
|
|
2648
|
+
}
|
|
2649
|
+
case "artifact_content_changed": {
|
|
2650
|
+
if (payload.artifactId && payload.content !== void 0) {
|
|
2651
|
+
optionsRef.current.onArtifactContentChanged?.(payload.artifactId, payload.content);
|
|
2652
|
+
useAgentStore.getState().updateArtifactContent(
|
|
2653
|
+
payload.artifactId,
|
|
2654
|
+
payload.content,
|
|
2655
|
+
"user"
|
|
2656
|
+
);
|
|
2657
|
+
}
|
|
2658
|
+
break;
|
|
2659
|
+
}
|
|
2660
|
+
default:
|
|
2661
|
+
console.log("[CanvasBridge] Unknown message type:", type);
|
|
2662
|
+
}
|
|
2663
|
+
};
|
|
2664
|
+
window.addEventListener("message", handleMessage);
|
|
2665
|
+
return () => window.removeEventListener("message", handleMessage);
|
|
2666
|
+
}, [enabled, targetOrigin]);
|
|
2667
|
+
const notifyArtifactCreated = useCallback((artifact) => {
|
|
2668
|
+
if (!enabled) return;
|
|
2669
|
+
postToCanvas("artifact_created", { artifact });
|
|
2670
|
+
}, [enabled, postToCanvas]);
|
|
2671
|
+
const notifyArtifactUpdated = useCallback((artifact) => {
|
|
2672
|
+
if (!enabled) return;
|
|
2673
|
+
postToCanvas("artifact_updated", { artifact });
|
|
2674
|
+
}, [enabled, postToCanvas]);
|
|
2675
|
+
const notifyArtifactDeleted = useCallback((artifactId) => {
|
|
2676
|
+
if (!enabled) return;
|
|
2677
|
+
postToCanvas("artifact_deleted", { artifactId });
|
|
2678
|
+
}, [enabled, postToCanvas]);
|
|
2679
|
+
const syncAllArtifacts = useCallback(() => {
|
|
2680
|
+
if (!enabled) return;
|
|
2681
|
+
const artifacts = Object.values(useAgentStore.getState().artifacts);
|
|
2682
|
+
postToCanvas("artifacts_sync", { artifacts });
|
|
2683
|
+
}, [enabled, postToCanvas]);
|
|
2684
|
+
return {
|
|
2685
|
+
notifyArtifactCreated,
|
|
2686
|
+
notifyArtifactUpdated,
|
|
2687
|
+
notifyArtifactDeleted,
|
|
2688
|
+
syncAllArtifacts
|
|
2689
|
+
};
|
|
2690
|
+
}
|
|
2423
2691
|
|
|
2424
2692
|
// src/hooks/sseConnection.ts
|
|
2425
2693
|
var SSE_HEARTBEAT_TIMEOUT2 = 45e3;
|
|
@@ -2882,14 +3150,14 @@ function getParamsSummary(params, maxItems = 2) {
|
|
|
2882
3150
|
}
|
|
2883
3151
|
function generateToolCallDescription(toolName, params) {
|
|
2884
3152
|
const formatted = formatParameters(params);
|
|
2885
|
-
const
|
|
3153
|
+
const prompt2 = formatted.find((p) => p.key === "prompt" || p.key === "query" || p.key === "content");
|
|
2886
3154
|
const image2 = formatted.find((p) => p.key === "image" || p.key === "image_url" || p.key === "imageUrl");
|
|
2887
3155
|
const style = formatted.find((p) => p.key === "style");
|
|
2888
3156
|
formatted.find((p) => p.key === "width" || p.key === "size");
|
|
2889
3157
|
const toolLower = toolName.toLowerCase();
|
|
2890
3158
|
if (toolLower.includes("generate") || toolLower.includes("image") || toolLower.includes("art")) {
|
|
2891
|
-
if (
|
|
2892
|
-
return `\u751F\u6210\u56FE\u50CF\uFF1A${
|
|
3159
|
+
if (prompt2) {
|
|
3160
|
+
return `\u751F\u6210\u56FE\u50CF\uFF1A${prompt2.displayValue.slice(0, 50)}${prompt2.displayValue.length > 50 ? "..." : ""}`;
|
|
2893
3161
|
}
|
|
2894
3162
|
if (style) {
|
|
2895
3163
|
return `\u751F\u6210 ${style.displayValue} \u98CE\u683C\u7684\u56FE\u50CF`;
|
|
@@ -2897,14 +3165,14 @@ function generateToolCallDescription(toolName, params) {
|
|
|
2897
3165
|
return "\u751F\u6210\u56FE\u50CF";
|
|
2898
3166
|
}
|
|
2899
3167
|
if (toolLower.includes("search") || toolLower.includes("query")) {
|
|
2900
|
-
if (
|
|
2901
|
-
return `\u641C\u7D22\uFF1A${
|
|
3168
|
+
if (prompt2) {
|
|
3169
|
+
return `\u641C\u7D22\uFF1A${prompt2.displayValue}`;
|
|
2902
3170
|
}
|
|
2903
3171
|
return "\u6267\u884C\u641C\u7D22";
|
|
2904
3172
|
}
|
|
2905
3173
|
if (toolLower.includes("translate")) {
|
|
2906
|
-
if (
|
|
2907
|
-
return `\u7FFB\u8BD1\uFF1A${
|
|
3174
|
+
if (prompt2) {
|
|
3175
|
+
return `\u7FFB\u8BD1\uFF1A${prompt2.displayValue.slice(0, 30)}...`;
|
|
2908
3176
|
}
|
|
2909
3177
|
return "\u6267\u884C\u7FFB\u8BD1";
|
|
2910
3178
|
}
|
|
@@ -2914,8 +3182,8 @@ function generateToolCallDescription(toolName, params) {
|
|
|
2914
3182
|
}
|
|
2915
3183
|
return "\u6267\u884C\u5206\u6790";
|
|
2916
3184
|
}
|
|
2917
|
-
if (
|
|
2918
|
-
return
|
|
3185
|
+
if (prompt2) {
|
|
3186
|
+
return prompt2.displayValue.slice(0, 60) + (prompt2.displayValue.length > 60 ? "..." : "");
|
|
2919
3187
|
}
|
|
2920
3188
|
const paramCount = formatted.length;
|
|
2921
3189
|
if (paramCount === 0) {
|
|
@@ -6910,7 +7178,6 @@ var createAssetFromSource = (options) => {
|
|
|
6910
7178
|
var resolveAssetForDisplay = async (asset, config) => {
|
|
6911
7179
|
let working = asset;
|
|
6912
7180
|
const strategy = config?.asset;
|
|
6913
|
-
console.log("Resolving asset for display:", asset, "with strategy:", strategy);
|
|
6914
7181
|
if (strategy?.resolve && !working.url) {
|
|
6915
7182
|
working = await strategy.resolve(working);
|
|
6916
7183
|
}
|
|
@@ -6925,6 +7192,9 @@ var resolveAssetForDisplay = async (asset, config) => {
|
|
|
6925
7192
|
if (resolved) return resolved;
|
|
6926
7193
|
}
|
|
6927
7194
|
if (working.url) {
|
|
7195
|
+
if (working.url.includes("industryai")) {
|
|
7196
|
+
working.url = working.url.split("?")[0];
|
|
7197
|
+
}
|
|
6928
7198
|
return {
|
|
6929
7199
|
url: working.url,
|
|
6930
7200
|
hdUrl: working.url,
|
|
@@ -6934,7 +7204,7 @@ var resolveAssetForDisplay = async (asset, config) => {
|
|
|
6934
7204
|
return null;
|
|
6935
7205
|
};
|
|
6936
7206
|
|
|
6937
|
-
//
|
|
7207
|
+
// node_modules/clsx/dist/clsx.mjs
|
|
6938
7208
|
function r(e) {
|
|
6939
7209
|
var t, f, n = "";
|
|
6940
7210
|
if ("string" == typeof e || "number" == typeof e) n += e;
|
|
@@ -10543,7 +10813,7 @@ var MessageImageInternal = memo(function MessageImageInternal2({ src, alt, class
|
|
|
10543
10813
|
/* @__PURE__ */ jsx("span", { children: "\u56FE\u7247\u52A0\u8F7D\u5931\u8D25" })
|
|
10544
10814
|
] });
|
|
10545
10815
|
}
|
|
10546
|
-
return /* @__PURE__ */ jsxs("div", { className: "relative
|
|
10816
|
+
return /* @__PURE__ */ jsxs("div", { className: "relative inline-block max-w-full overflow-hidden rounded-lg my-2", children: [
|
|
10547
10817
|
previewUrl && /* @__PURE__ */ jsx(
|
|
10548
10818
|
ImagePreviewComp,
|
|
10549
10819
|
{
|
|
@@ -10551,7 +10821,7 @@ var MessageImageInternal = memo(function MessageImageInternal2({ src, alt, class
|
|
|
10551
10821
|
onClose: () => setPreviewUrl(null)
|
|
10552
10822
|
}
|
|
10553
10823
|
),
|
|
10554
|
-
!loaded && /* @__PURE__ */ jsx("div", { className: "
|
|
10824
|
+
!loaded && /* @__PURE__ */ jsx("div", { className: "bg-zinc-800 animate-pulse rounded-lg", style: { minHeight: "100px", minWidth: "150px" } }),
|
|
10555
10825
|
/* @__PURE__ */ jsx(
|
|
10556
10826
|
"img",
|
|
10557
10827
|
{
|
|
@@ -10561,23 +10831,284 @@ var MessageImageInternal = memo(function MessageImageInternal2({ src, alt, class
|
|
|
10561
10831
|
onLoad: handleLoad,
|
|
10562
10832
|
onError: handleError,
|
|
10563
10833
|
onClick: () => setPreviewUrl(src),
|
|
10564
|
-
className: cn(
|
|
10565
|
-
|
|
10834
|
+
className: cn(
|
|
10835
|
+
"rounded-lg cursor-zoom-in max-w-full h-auto block",
|
|
10836
|
+
className,
|
|
10837
|
+
!loaded && "opacity-0 absolute"
|
|
10838
|
+
),
|
|
10839
|
+
style: { maxHeight: "400px", objectFit: "contain" }
|
|
10566
10840
|
}
|
|
10567
10841
|
)
|
|
10568
10842
|
] });
|
|
10569
10843
|
});
|
|
10570
10844
|
var MessageVideoInternal = memo(function MessageVideoInternal2({ src, className }) {
|
|
10571
|
-
|
|
10572
|
-
|
|
10573
|
-
|
|
10574
|
-
|
|
10575
|
-
|
|
10576
|
-
|
|
10577
|
-
|
|
10578
|
-
|
|
10845
|
+
const videoRef = React20__default.useRef(null);
|
|
10846
|
+
const canvasRef = React20__default.useRef(null);
|
|
10847
|
+
const [posterUrl, setPosterUrl] = useState(null);
|
|
10848
|
+
const [isHovering, setIsHovering] = useState(false);
|
|
10849
|
+
const [isPlaying, setIsPlaying] = useState(false);
|
|
10850
|
+
const [isMuted, setIsMuted] = useState(true);
|
|
10851
|
+
const [duration, setDuration] = useState(0);
|
|
10852
|
+
const [currentTime, setCurrentTime] = useState(0);
|
|
10853
|
+
const [isFullPlaying, setIsFullPlaying] = useState(false);
|
|
10854
|
+
const hoverTimerRef = React20__default.useRef(null);
|
|
10855
|
+
const VideoPreviewComp = useComponent("VideoPreview") || VideoPreviewInternal;
|
|
10856
|
+
const [showPreview, setShowPreview] = useState(false);
|
|
10857
|
+
useEffect(() => {
|
|
10858
|
+
const video = document.createElement("video");
|
|
10859
|
+
video.crossOrigin = "anonymous";
|
|
10860
|
+
video.preload = "metadata";
|
|
10861
|
+
video.muted = true;
|
|
10862
|
+
video.addEventListener("loadeddata", () => {
|
|
10863
|
+
video.currentTime = Math.min(0.5, video.duration * 0.1);
|
|
10864
|
+
});
|
|
10865
|
+
video.addEventListener("seeked", () => {
|
|
10866
|
+
try {
|
|
10867
|
+
const canvas = document.createElement("canvas");
|
|
10868
|
+
canvas.width = video.videoWidth;
|
|
10869
|
+
canvas.height = video.videoHeight;
|
|
10870
|
+
const ctx = canvas.getContext("2d");
|
|
10871
|
+
if (ctx) {
|
|
10872
|
+
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
|
|
10873
|
+
const dataUrl = canvas.toDataURL("image/jpeg", 0.8);
|
|
10874
|
+
setPosterUrl(dataUrl);
|
|
10875
|
+
}
|
|
10876
|
+
} catch {
|
|
10877
|
+
}
|
|
10878
|
+
video.remove();
|
|
10879
|
+
});
|
|
10880
|
+
video.addEventListener("error", () => {
|
|
10881
|
+
video.remove();
|
|
10882
|
+
});
|
|
10883
|
+
video.src = src;
|
|
10884
|
+
video.load();
|
|
10885
|
+
return () => {
|
|
10886
|
+
video.remove();
|
|
10887
|
+
};
|
|
10888
|
+
}, [src]);
|
|
10889
|
+
const handleLoadedMetadata = () => {
|
|
10890
|
+
const video = videoRef.current;
|
|
10891
|
+
if (video) {
|
|
10892
|
+
setDuration(video.duration);
|
|
10579
10893
|
}
|
|
10580
|
-
|
|
10894
|
+
};
|
|
10895
|
+
const handleTimeUpdate = () => {
|
|
10896
|
+
const video = videoRef.current;
|
|
10897
|
+
if (video) {
|
|
10898
|
+
setCurrentTime(video.currentTime);
|
|
10899
|
+
}
|
|
10900
|
+
};
|
|
10901
|
+
const handleMouseEnter = () => {
|
|
10902
|
+
setIsHovering(true);
|
|
10903
|
+
if (isFullPlaying) return;
|
|
10904
|
+
hoverTimerRef.current = setTimeout(() => {
|
|
10905
|
+
const video = videoRef.current;
|
|
10906
|
+
if (video) {
|
|
10907
|
+
video.muted = true;
|
|
10908
|
+
video.currentTime = 0;
|
|
10909
|
+
video.play().then(() => setIsPlaying(true)).catch(() => {
|
|
10910
|
+
});
|
|
10911
|
+
}
|
|
10912
|
+
}, 300);
|
|
10913
|
+
};
|
|
10914
|
+
const handleMouseLeave = () => {
|
|
10915
|
+
setIsHovering(false);
|
|
10916
|
+
if (hoverTimerRef.current) {
|
|
10917
|
+
clearTimeout(hoverTimerRef.current);
|
|
10918
|
+
hoverTimerRef.current = null;
|
|
10919
|
+
}
|
|
10920
|
+
if (!isFullPlaying) {
|
|
10921
|
+
const video = videoRef.current;
|
|
10922
|
+
if (video) {
|
|
10923
|
+
video.pause();
|
|
10924
|
+
video.currentTime = 0;
|
|
10925
|
+
setIsPlaying(false);
|
|
10926
|
+
}
|
|
10927
|
+
}
|
|
10928
|
+
};
|
|
10929
|
+
const handleClick = (e) => {
|
|
10930
|
+
e.stopPropagation();
|
|
10931
|
+
const video = videoRef.current;
|
|
10932
|
+
if (!video) return;
|
|
10933
|
+
if (isFullPlaying) {
|
|
10934
|
+
video.pause();
|
|
10935
|
+
setIsPlaying(false);
|
|
10936
|
+
setIsFullPlaying(false);
|
|
10937
|
+
} else {
|
|
10938
|
+
video.muted = isMuted;
|
|
10939
|
+
video.play().then(() => {
|
|
10940
|
+
setIsPlaying(true);
|
|
10941
|
+
setIsFullPlaying(true);
|
|
10942
|
+
}).catch(() => {
|
|
10943
|
+
});
|
|
10944
|
+
}
|
|
10945
|
+
};
|
|
10946
|
+
const handleToggleMute = (e) => {
|
|
10947
|
+
e.stopPropagation();
|
|
10948
|
+
const video = videoRef.current;
|
|
10949
|
+
if (video) {
|
|
10950
|
+
video.muted = !isMuted;
|
|
10951
|
+
setIsMuted(!isMuted);
|
|
10952
|
+
}
|
|
10953
|
+
};
|
|
10954
|
+
const handleProgressClick = (e) => {
|
|
10955
|
+
e.stopPropagation();
|
|
10956
|
+
const video = videoRef.current;
|
|
10957
|
+
if (!video || !duration) return;
|
|
10958
|
+
const rect = e.currentTarget.getBoundingClientRect();
|
|
10959
|
+
const ratio = Math.max(0, Math.min(1, (e.clientX - rect.left) / rect.width));
|
|
10960
|
+
video.currentTime = ratio * duration;
|
|
10961
|
+
setCurrentTime(ratio * duration);
|
|
10962
|
+
};
|
|
10963
|
+
const formatTime2 = (seconds) => {
|
|
10964
|
+
const mins = Math.floor(seconds / 60);
|
|
10965
|
+
const secs = Math.floor(seconds % 60);
|
|
10966
|
+
return `${mins}:${secs.toString().padStart(2, "0")}`;
|
|
10967
|
+
};
|
|
10968
|
+
const progressPercent = duration > 0 ? currentTime / duration * 100 : 0;
|
|
10969
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
10970
|
+
showPreview && /* @__PURE__ */ jsx(VideoPreviewComp, { src, onClose: () => setShowPreview(false) }),
|
|
10971
|
+
/* @__PURE__ */ jsxs(
|
|
10972
|
+
"div",
|
|
10973
|
+
{
|
|
10974
|
+
className: cn(
|
|
10975
|
+
"my-2 relative rounded-xl overflow-hidden bg-black group/video cursor-pointer",
|
|
10976
|
+
"border border-zinc-800/60 agent-sdk-light:border-zinc-200",
|
|
10977
|
+
"transition-shadow duration-200 hover:shadow-xl hover:shadow-black/20",
|
|
10978
|
+
className
|
|
10979
|
+
),
|
|
10980
|
+
style: { maxHeight: "400px", maxWidth: "100%" },
|
|
10981
|
+
onMouseEnter: handleMouseEnter,
|
|
10982
|
+
onMouseLeave: handleMouseLeave,
|
|
10983
|
+
onClick: handleClick,
|
|
10984
|
+
children: [
|
|
10985
|
+
posterUrl && !isPlaying && /* @__PURE__ */ jsx(
|
|
10986
|
+
"img",
|
|
10987
|
+
{
|
|
10988
|
+
src: posterUrl,
|
|
10989
|
+
alt: "Video cover",
|
|
10990
|
+
className: "absolute inset-0 w-full h-full object-contain z-[1]"
|
|
10991
|
+
}
|
|
10992
|
+
),
|
|
10993
|
+
/* @__PURE__ */ jsx(
|
|
10994
|
+
"video",
|
|
10995
|
+
{
|
|
10996
|
+
ref: videoRef,
|
|
10997
|
+
src,
|
|
10998
|
+
muted: isMuted,
|
|
10999
|
+
playsInline: true,
|
|
11000
|
+
preload: "metadata",
|
|
11001
|
+
onLoadedMetadata: handleLoadedMetadata,
|
|
11002
|
+
onTimeUpdate: handleTimeUpdate,
|
|
11003
|
+
onEnded: () => {
|
|
11004
|
+
setIsPlaying(false);
|
|
11005
|
+
setIsFullPlaying(false);
|
|
11006
|
+
},
|
|
11007
|
+
className: cn(
|
|
11008
|
+
"w-full max-h-[400px] object-contain",
|
|
11009
|
+
!isPlaying && posterUrl && "opacity-0"
|
|
11010
|
+
)
|
|
11011
|
+
}
|
|
11012
|
+
),
|
|
11013
|
+
/* @__PURE__ */ jsx("canvas", { ref: canvasRef, className: "hidden" }),
|
|
11014
|
+
!isFullPlaying && /* @__PURE__ */ jsx("div", { className: cn(
|
|
11015
|
+
"absolute inset-0 z-[2] flex items-center justify-center",
|
|
11016
|
+
"bg-gradient-to-t from-black/50 via-transparent to-transparent",
|
|
11017
|
+
"transition-opacity duration-200",
|
|
11018
|
+
isHovering && isPlaying ? "opacity-0" : "opacity-100"
|
|
11019
|
+
), children: /* @__PURE__ */ jsx("div", { className: cn(
|
|
11020
|
+
"w-14 h-14 rounded-full bg-white/20 backdrop-blur-md",
|
|
11021
|
+
"flex items-center justify-center",
|
|
11022
|
+
"transition-all duration-200",
|
|
11023
|
+
"group-hover/video:scale-110 group-hover/video:bg-white/30",
|
|
11024
|
+
"shadow-lg shadow-black/20"
|
|
11025
|
+
), children: /* @__PURE__ */ jsx("svg", { width: "22", height: "22", viewBox: "0 0 24 24", fill: "white", className: "ml-1", children: /* @__PURE__ */ jsx("path", { d: "M8 5v14l11-7z" }) }) }) }),
|
|
11026
|
+
/* @__PURE__ */ jsxs("div", { className: cn(
|
|
11027
|
+
"absolute bottom-0 left-0 right-0 z-[3]",
|
|
11028
|
+
"bg-gradient-to-t from-black/80 via-black/40 to-transparent",
|
|
11029
|
+
"px-3 pb-2.5 pt-8",
|
|
11030
|
+
"transition-opacity duration-200",
|
|
11031
|
+
isHovering || isFullPlaying ? "opacity-100" : "opacity-0"
|
|
11032
|
+
), children: [
|
|
11033
|
+
/* @__PURE__ */ jsx(
|
|
11034
|
+
"div",
|
|
11035
|
+
{
|
|
11036
|
+
className: "w-full h-1 bg-white/20 rounded-full mb-2 cursor-pointer group/progress",
|
|
11037
|
+
onClick: handleProgressClick,
|
|
11038
|
+
children: /* @__PURE__ */ jsx(
|
|
11039
|
+
"div",
|
|
11040
|
+
{
|
|
11041
|
+
className: "h-full bg-[#d8ff00] rounded-full relative transition-all duration-75",
|
|
11042
|
+
style: { width: `${progressPercent}%` },
|
|
11043
|
+
children: /* @__PURE__ */ jsx("div", { className: "absolute right-0 top-1/2 -translate-y-1/2 w-3 h-3 bg-[#d8ff00] rounded-full opacity-0 group-hover/progress:opacity-100 transition-opacity shadow-md" })
|
|
11044
|
+
}
|
|
11045
|
+
)
|
|
11046
|
+
}
|
|
11047
|
+
),
|
|
11048
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
11049
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
11050
|
+
/* @__PURE__ */ jsx(
|
|
11051
|
+
"button",
|
|
11052
|
+
{
|
|
11053
|
+
onClick: handleClick,
|
|
11054
|
+
className: "p-1 text-white/80 hover:text-white transition-colors",
|
|
11055
|
+
children: isPlaying ? /* @__PURE__ */ jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "currentColor", children: [
|
|
11056
|
+
/* @__PURE__ */ jsx("rect", { x: "6", y: "4", width: "4", height: "16", rx: "1" }),
|
|
11057
|
+
/* @__PURE__ */ jsx("rect", { x: "14", y: "4", width: "4", height: "16", rx: "1" })
|
|
11058
|
+
] }) : /* @__PURE__ */ jsx("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ jsx("path", { d: "M8 5v14l11-7z" }) })
|
|
11059
|
+
}
|
|
11060
|
+
),
|
|
11061
|
+
/* @__PURE__ */ jsx(
|
|
11062
|
+
"button",
|
|
11063
|
+
{
|
|
11064
|
+
onClick: handleToggleMute,
|
|
11065
|
+
className: "p-1 text-white/80 hover:text-white transition-colors",
|
|
11066
|
+
children: isMuted ? /* @__PURE__ */ jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
11067
|
+
/* @__PURE__ */ jsx("polygon", { points: "11 5 6 9 2 9 2 15 6 15 11 19 11 5" }),
|
|
11068
|
+
/* @__PURE__ */ jsx("line", { x1: "23", y1: "9", x2: "17", y2: "15" }),
|
|
11069
|
+
/* @__PURE__ */ jsx("line", { x1: "17", y1: "9", x2: "23", y2: "15" })
|
|
11070
|
+
] }) : /* @__PURE__ */ jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
11071
|
+
/* @__PURE__ */ jsx("polygon", { points: "11 5 6 9 2 9 2 15 6 15 11 19 11 5" }),
|
|
11072
|
+
/* @__PURE__ */ jsx("path", { d: "M19.07 4.93a10 10 0 0 1 0 14.14" }),
|
|
11073
|
+
/* @__PURE__ */ jsx("path", { d: "M15.54 8.46a5 5 0 0 1 0 7.07" })
|
|
11074
|
+
] })
|
|
11075
|
+
}
|
|
11076
|
+
),
|
|
11077
|
+
/* @__PURE__ */ jsxs("span", { className: "text-[11px] text-white/60 font-mono tabular-nums", children: [
|
|
11078
|
+
formatTime2(currentTime),
|
|
11079
|
+
" / ",
|
|
11080
|
+
formatTime2(duration)
|
|
11081
|
+
] })
|
|
11082
|
+
] }),
|
|
11083
|
+
/* @__PURE__ */ jsx(
|
|
11084
|
+
"button",
|
|
11085
|
+
{
|
|
11086
|
+
onClick: (e) => {
|
|
11087
|
+
e.stopPropagation();
|
|
11088
|
+
const video = videoRef.current;
|
|
11089
|
+
if (video) {
|
|
11090
|
+
video.pause();
|
|
11091
|
+
setIsPlaying(false);
|
|
11092
|
+
setIsFullPlaying(false);
|
|
11093
|
+
}
|
|
11094
|
+
setShowPreview(true);
|
|
11095
|
+
},
|
|
11096
|
+
className: "p-1 text-white/60 hover:text-white transition-colors",
|
|
11097
|
+
title: "\u5168\u5C4F\u9884\u89C8",
|
|
11098
|
+
children: /* @__PURE__ */ jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
11099
|
+
/* @__PURE__ */ jsx("polyline", { points: "15 3 21 3 21 9" }),
|
|
11100
|
+
/* @__PURE__ */ jsx("polyline", { points: "9 21 3 21 3 15" }),
|
|
11101
|
+
/* @__PURE__ */ jsx("line", { x1: "21", y1: "3", x2: "14", y2: "10" }),
|
|
11102
|
+
/* @__PURE__ */ jsx("line", { x1: "3", y1: "21", x2: "10", y2: "14" })
|
|
11103
|
+
] })
|
|
11104
|
+
}
|
|
11105
|
+
)
|
|
11106
|
+
] })
|
|
11107
|
+
] })
|
|
11108
|
+
]
|
|
11109
|
+
}
|
|
11110
|
+
)
|
|
11111
|
+
] });
|
|
10581
11112
|
});
|
|
10582
11113
|
var ImagePreviewInternal = memo(function ImagePreviewInternal2({
|
|
10583
11114
|
src,
|
|
@@ -12223,6 +12754,7 @@ var ToolResultRenderer = memo(function ToolResultRenderer2({
|
|
|
12223
12754
|
result,
|
|
12224
12755
|
mediaUrls,
|
|
12225
12756
|
config,
|
|
12757
|
+
toolCallData,
|
|
12226
12758
|
onOpenArtifact
|
|
12227
12759
|
}) {
|
|
12228
12760
|
const [imgLoaded, setImgLoaded] = useState({});
|
|
@@ -12289,32 +12821,134 @@ var ToolResultRenderer = memo(function ToolResultRenderer2({
|
|
|
12289
12821
|
}
|
|
12290
12822
|
),
|
|
12291
12823
|
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
12292
|
-
hasMedia && /* @__PURE__ */
|
|
12293
|
-
|
|
12294
|
-
|
|
12295
|
-
|
|
12296
|
-
|
|
12297
|
-
|
|
12298
|
-
|
|
12299
|
-
|
|
12300
|
-
|
|
12824
|
+
hasMedia && /* @__PURE__ */ jsx("div", { className: "p-2", children: (() => {
|
|
12825
|
+
const totalMedia = imageUrls.length + videoUrls.length;
|
|
12826
|
+
const isMultiple = totalMedia > 1;
|
|
12827
|
+
const buildMediaMetadata = (mediaIndex) => {
|
|
12828
|
+
if (!toolCallData) return void 0;
|
|
12829
|
+
const resultAny = toolCallData.result;
|
|
12830
|
+
const metadata = {};
|
|
12831
|
+
if (toolCallData.name) metadata.toolName = toolCallData.name;
|
|
12832
|
+
if (resultAny?.relation?.toolName) metadata.toolName = resultAny.relation.toolName;
|
|
12833
|
+
if (toolCallData.arguments) metadata.generationParams = toolCallData.arguments;
|
|
12834
|
+
if (resultAny?.relation) metadata.relation = resultAny.relation;
|
|
12835
|
+
if (resultAny?.taskId) metadata.taskId = resultAny.taskId;
|
|
12836
|
+
const work = resultAny?.works?.[mediaIndex];
|
|
12837
|
+
if (work) {
|
|
12838
|
+
if (work.publicId) metadata.workId = work.publicId;
|
|
12839
|
+
if (work.fileId) metadata.fileId = work.fileId;
|
|
12301
12840
|
}
|
|
12302
|
-
|
|
12303
|
-
|
|
12304
|
-
|
|
12305
|
-
/* @__PURE__ */
|
|
12306
|
-
"
|
|
12841
|
+
return metadata;
|
|
12842
|
+
};
|
|
12843
|
+
return /* @__PURE__ */ jsxs("div", { className: isMultiple ? "grid grid-cols-2 gap-2" : "flex", children: [
|
|
12844
|
+
videoUrls.map((video, i) => /* @__PURE__ */ jsxs(
|
|
12845
|
+
"div",
|
|
12307
12846
|
{
|
|
12308
|
-
|
|
12309
|
-
|
|
12310
|
-
|
|
12311
|
-
|
|
12312
|
-
|
|
12313
|
-
|
|
12314
|
-
|
|
12315
|
-
|
|
12316
|
-
|
|
12317
|
-
|
|
12847
|
+
className: `relative group/media overflow-hidden rounded-lg bg-black ${isMultiple ? "aspect-square" : "max-h-[375px]"}`,
|
|
12848
|
+
children: [
|
|
12849
|
+
/* @__PURE__ */ jsx(
|
|
12850
|
+
MessageVideoInternal,
|
|
12851
|
+
{
|
|
12852
|
+
src: video.hdUrl || video.url,
|
|
12853
|
+
className: isMultiple ? "w-full h-full object-cover" : "max-h-[375px] max-w-full object-contain"
|
|
12854
|
+
}
|
|
12855
|
+
),
|
|
12856
|
+
/* @__PURE__ */ 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: [
|
|
12857
|
+
onOpenArtifact && /* @__PURE__ */ jsxs(
|
|
12858
|
+
"button",
|
|
12859
|
+
{
|
|
12860
|
+
onClick: (e) => {
|
|
12861
|
+
e.stopPropagation();
|
|
12862
|
+
const resultAny = toolCallData?.result;
|
|
12863
|
+
const displayName = resultAny?.relation?.toolName || toolCallData?.name || "\u89C6\u9891\u751F\u6210";
|
|
12864
|
+
onOpenArtifact({
|
|
12865
|
+
type: "video",
|
|
12866
|
+
title: `${displayName} #${i + 1}`,
|
|
12867
|
+
content: video.hdUrl || video.url,
|
|
12868
|
+
metadata: buildMediaMetadata(imageUrls.length + i)
|
|
12869
|
+
});
|
|
12870
|
+
},
|
|
12871
|
+
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",
|
|
12872
|
+
children: [
|
|
12873
|
+
/* @__PURE__ */ jsx(Sparkles, { size: 12 }),
|
|
12874
|
+
"\u67E5\u770B\u8BE6\u60C5"
|
|
12875
|
+
]
|
|
12876
|
+
}
|
|
12877
|
+
),
|
|
12878
|
+
/* @__PURE__ */ jsx(
|
|
12879
|
+
"button",
|
|
12880
|
+
{
|
|
12881
|
+
onClick: (e) => {
|
|
12882
|
+
e.stopPropagation();
|
|
12883
|
+
window.open(video.hdUrl || video.url, "_blank");
|
|
12884
|
+
},
|
|
12885
|
+
className: "p-1.5 text-white/80 hover:text-white bg-white/15 hover:bg-white/25 backdrop-blur-sm rounded-md transition-colors",
|
|
12886
|
+
title: "\u65B0\u7A97\u53E3\u6253\u5F00",
|
|
12887
|
+
children: /* @__PURE__ */ jsx(Video, { size: 14 })
|
|
12888
|
+
}
|
|
12889
|
+
)
|
|
12890
|
+
] })
|
|
12891
|
+
]
|
|
12892
|
+
},
|
|
12893
|
+
`video-${i}`
|
|
12894
|
+
)),
|
|
12895
|
+
imageUrls.map((img, i) => /* @__PURE__ */ jsxs(
|
|
12896
|
+
"div",
|
|
12897
|
+
{
|
|
12898
|
+
className: `relative group/media overflow-hidden rounded-lg bg-black ${isMultiple ? "aspect-square" : "max-h-[375px]"}`,
|
|
12899
|
+
children: [
|
|
12900
|
+
!imgLoaded[i] && /* @__PURE__ */ jsx("div", { className: "bg-zinc-800 animate-pulse flex items-center justify-center w-full aspect-square", children: /* @__PURE__ */ jsx("div", { className: "animate-spin rounded-full h-5 w-5 border-b-2 border-[#d8ff00]" }) }),
|
|
12901
|
+
/* @__PURE__ */ jsx(
|
|
12902
|
+
"img",
|
|
12903
|
+
{
|
|
12904
|
+
src: img.url,
|
|
12905
|
+
alt: "Generated",
|
|
12906
|
+
onLoad: () => handleImgLoad(i),
|
|
12907
|
+
className: `cursor-zoom-in ${imgLoaded[i] ? "" : "hidden"} ${isMultiple ? "w-full h-full object-cover" : "max-h-[375px] max-w-full h-auto object-contain"}`,
|
|
12908
|
+
onClick: () => setPreviewUrl(img.hdUrl)
|
|
12909
|
+
}
|
|
12910
|
+
),
|
|
12911
|
+
imgLoaded[i] && /* @__PURE__ */ 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: [
|
|
12912
|
+
onOpenArtifact && /* @__PURE__ */ jsxs(
|
|
12913
|
+
"button",
|
|
12914
|
+
{
|
|
12915
|
+
onClick: (e) => {
|
|
12916
|
+
e.stopPropagation();
|
|
12917
|
+
const resultAny = toolCallData?.result;
|
|
12918
|
+
const displayName = resultAny?.relation?.toolName || toolCallData?.name || "\u56FE\u7247\u751F\u6210";
|
|
12919
|
+
onOpenArtifact({
|
|
12920
|
+
type: "image",
|
|
12921
|
+
title: `${displayName} #${i + 1}`,
|
|
12922
|
+
content: img.hdUrl || img.url,
|
|
12923
|
+
metadata: buildMediaMetadata(i)
|
|
12924
|
+
});
|
|
12925
|
+
},
|
|
12926
|
+
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",
|
|
12927
|
+
children: [
|
|
12928
|
+
/* @__PURE__ */ jsx(Sparkles, { size: 12 }),
|
|
12929
|
+
"\u67E5\u770B\u8BE6\u60C5"
|
|
12930
|
+
]
|
|
12931
|
+
}
|
|
12932
|
+
),
|
|
12933
|
+
/* @__PURE__ */ jsx(
|
|
12934
|
+
"button",
|
|
12935
|
+
{
|
|
12936
|
+
onClick: (e) => {
|
|
12937
|
+
e.stopPropagation();
|
|
12938
|
+
setPreviewUrl(img.hdUrl);
|
|
12939
|
+
},
|
|
12940
|
+
className: "p-1.5 text-white/80 hover:text-white bg-white/15 hover:bg-white/25 backdrop-blur-sm rounded-md transition-colors",
|
|
12941
|
+
title: "\u653E\u5927\u9884\u89C8",
|
|
12942
|
+
children: /* @__PURE__ */ jsx(Image, { size: 14 })
|
|
12943
|
+
}
|
|
12944
|
+
)
|
|
12945
|
+
] })
|
|
12946
|
+
]
|
|
12947
|
+
},
|
|
12948
|
+
`img-${i}`
|
|
12949
|
+
))
|
|
12950
|
+
] });
|
|
12951
|
+
})() }),
|
|
12318
12952
|
hasCustomResponses && customResult
|
|
12319
12953
|
] })
|
|
12320
12954
|
] });
|
|
@@ -12440,6 +13074,7 @@ var ToolCallCard3 = memo(function ToolCallCard4({
|
|
|
12440
13074
|
result: toolCall.result,
|
|
12441
13075
|
mediaUrls,
|
|
12442
13076
|
config,
|
|
13077
|
+
toolCallData: toolCall,
|
|
12443
13078
|
defaultExpanded: false,
|
|
12444
13079
|
onOpenArtifact
|
|
12445
13080
|
}
|
|
@@ -12710,7 +13345,7 @@ var ComponentPendingCard = memo(function ComponentPendingCard2({
|
|
|
12710
13345
|
})() })
|
|
12711
13346
|
] });
|
|
12712
13347
|
});
|
|
12713
|
-
var ThoughtTimelineCard = memo(function ThoughtTimelineCard2({ thought, config, isLoading = false }) {
|
|
13348
|
+
var ThoughtTimelineCard = memo(function ThoughtTimelineCard2({ thought, config, isLoading = false, skipImages = false }) {
|
|
12714
13349
|
const [expanded, setExpanded] = useState(true);
|
|
12715
13350
|
const { showItemTime } = useAgentStore();
|
|
12716
13351
|
const thoughtType = thought?.type || "";
|
|
@@ -12734,9 +13369,9 @@ var ThoughtTimelineCard = memo(function ThoughtTimelineCard2({ thought, config,
|
|
|
12734
13369
|
return null;
|
|
12735
13370
|
}
|
|
12736
13371
|
if (thought?.raw && Array.isArray(thought.raw)) {
|
|
12737
|
-
const hasConfirmationEvent = thought.raw.some((
|
|
12738
|
-
const type =
|
|
12739
|
-
return excludedTypes.includes(type) ||
|
|
13372
|
+
const hasConfirmationEvent = thought.raw.some((r3) => {
|
|
13373
|
+
const type = r3?.type || "";
|
|
13374
|
+
return excludedTypes.includes(type) || r3?.content && (r3.content.includes('"type":"tool_confirmed"') || r3.content.includes('"type":"component_submitted"') || r3.content.includes("\u7528\u6237\u786E\u8BA4\u6267\u884C\u5DE5\u5177\u8C03\u7528"));
|
|
12740
13375
|
});
|
|
12741
13376
|
if (hasConfirmationEvent) {
|
|
12742
13377
|
return null;
|
|
@@ -12748,12 +13383,19 @@ var ThoughtTimelineCard = memo(function ThoughtTimelineCard2({ thought, config,
|
|
|
12748
13383
|
if (!cleaned || !cleaned.trim()) return null;
|
|
12749
13384
|
return /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsxs("div", { className: "px-3 py-2", children: [
|
|
12750
13385
|
/* @__PURE__ */ jsx("div", { className: "", children: /* @__PURE__ */ jsxs("div", { className: "text-sm leading-relaxed prose prose-invert prose-sm max-w-none [&_*]:break-words", children: [
|
|
12751
|
-
/* @__PURE__ */ jsx(MarkdownContent, { content: cleaned, skipImages
|
|
13386
|
+
/* @__PURE__ */ jsx(MarkdownContent, { content: cleaned, skipImages, config, variant: "thought" }),
|
|
12752
13387
|
isLoading && /* @__PURE__ */ jsx("span", { className: "inline-block w-2 h-4 ml-0.5 bg-[#d8ff00] animate-pulse rounded-sm" })
|
|
12753
13388
|
] }) }),
|
|
12754
13389
|
thought?.raw?.length > 0 && showItemTime && /* @__PURE__ */ jsx("div", { className: "text-xs text-zinc-500 mt-2", children: new Date(
|
|
12755
13390
|
thought.raw[thought.raw.length - 1]?.gmt_create || thought.raw[thought.raw.length - 1]?.gmtCreate || thought.raw[thought.raw.length - 1]?.timestamp || ""
|
|
12756
|
-
).toLocaleTimeString("zh-CN", {
|
|
13391
|
+
).toLocaleTimeString("zh-CN", {
|
|
13392
|
+
year: "numeric",
|
|
13393
|
+
month: "2-digit",
|
|
13394
|
+
day: "2-digit",
|
|
13395
|
+
hour: "2-digit",
|
|
13396
|
+
minute: "2-digit",
|
|
13397
|
+
second: "2-digit"
|
|
13398
|
+
}) })
|
|
12757
13399
|
] }) });
|
|
12758
13400
|
});
|
|
12759
13401
|
var COMPONENT_TAGS_TO_STRIP = [
|
|
@@ -13753,7 +14395,8 @@ ${m.content}`;
|
|
|
13753
14395
|
}
|
|
13754
14396
|
var ThoughtBlockItem = memo(function ThoughtBlockItem2({
|
|
13755
14397
|
content,
|
|
13756
|
-
config
|
|
14398
|
+
config,
|
|
14399
|
+
skipImages = false
|
|
13757
14400
|
}) {
|
|
13758
14401
|
const [expanded, setExpanded] = useState(false);
|
|
13759
14402
|
const lineCount = useMemo(() => content.split("\n").length, [content]);
|
|
@@ -13766,7 +14409,7 @@ var ThoughtBlockItem = memo(function ThoughtBlockItem2({
|
|
|
13766
14409
|
"text-sm text-zinc-400 leading-relaxed prose prose-invert prose-sm max-w-none [&_*]:break-words",
|
|
13767
14410
|
shouldToggle && !expanded ? "max-h-[3.5em] overflow-hidden" : ""
|
|
13768
14411
|
),
|
|
13769
|
-
children: /* @__PURE__ */ jsx(MarkdownContent, { content, skipImages
|
|
14412
|
+
children: /* @__PURE__ */ jsx(MarkdownContent, { content, skipImages, config, variant: "thought" })
|
|
13770
14413
|
}
|
|
13771
14414
|
),
|
|
13772
14415
|
shouldToggle && /* @__PURE__ */ jsx(
|
|
@@ -13952,7 +14595,6 @@ var MessageBubble = memo(function MessageBubble2({
|
|
|
13952
14595
|
const shouldShowAvatar = isUser ? showUserAvatar : showAssistantAvatar;
|
|
13953
14596
|
const shouldShowName = isUser ? showUserName : showAssistantName;
|
|
13954
14597
|
const shouldShowDescription = isUser ? showUserDescription : showAssistantDescription;
|
|
13955
|
-
console.log("[MessageBubble] \u6E32\u67D3\u6D88\u606F\u6C14\u6CE1, config?.identity:", config?.identity);
|
|
13956
14598
|
const resolveFileName = (url) => {
|
|
13957
14599
|
try {
|
|
13958
14600
|
const pathname = new URL(url, "http://dummy").pathname;
|
|
@@ -14013,7 +14655,8 @@ var MessageBubble = memo(function MessageBubble2({
|
|
|
14013
14655
|
{
|
|
14014
14656
|
thought: item.data,
|
|
14015
14657
|
config,
|
|
14016
|
-
isLoading: showLoadingCursor
|
|
14658
|
+
isLoading: showLoadingCursor,
|
|
14659
|
+
skipImages: hasToolCallImages
|
|
14017
14660
|
},
|
|
14018
14661
|
item.id
|
|
14019
14662
|
);
|
|
@@ -14113,7 +14756,8 @@ var MessageBubble = memo(function MessageBubble2({
|
|
|
14113
14756
|
ThoughtBlockItem,
|
|
14114
14757
|
{
|
|
14115
14758
|
content: block.content,
|
|
14116
|
-
config
|
|
14759
|
+
config,
|
|
14760
|
+
skipImages: hasToolCallImages
|
|
14117
14761
|
},
|
|
14118
14762
|
`${block.ts}-${index}`
|
|
14119
14763
|
)),
|
|
@@ -14158,15 +14802,23 @@ var MessageBubble = memo(function MessageBubble2({
|
|
|
14158
14802
|
const isVideo = att.type === "video" || att.type?.startsWith("video/") || isVideoUrl2(att.url);
|
|
14159
14803
|
const isImage2 = att.type === "image" || att.type?.startsWith("image/") || !isVideo && /\.(jpg|jpeg|png|gif|webp|bmp|svg)(\?|#|$)/i.test(att.url);
|
|
14160
14804
|
const fileName = att.name || resolveFileName(att.url);
|
|
14805
|
+
if (att.url.includes("industryai")) {
|
|
14806
|
+
att.url = att.url.split("?")[0];
|
|
14807
|
+
}
|
|
14808
|
+
const assets = config?.asset?.transform?.({
|
|
14809
|
+
type: att.type,
|
|
14810
|
+
url: att.url,
|
|
14811
|
+
name: fileName
|
|
14812
|
+
}) || { url: att.url, type: att.type };
|
|
14161
14813
|
if (isImage2 || isVideo) {
|
|
14162
14814
|
return /* @__PURE__ */ jsxs(
|
|
14163
14815
|
"button",
|
|
14164
14816
|
{
|
|
14165
14817
|
type: "button",
|
|
14166
|
-
onClick: () => setPreviewMedia({ url:
|
|
14818
|
+
onClick: () => setPreviewMedia({ url: assets.url, isVideo }),
|
|
14167
14819
|
className: "group/att relative w-[88px] h-[88px] rounded-lg overflow-hidden border border-zinc-700/40 bg-zinc-900/60 hover:border-zinc-500/60 transition-colors",
|
|
14168
14820
|
children: [
|
|
14169
|
-
isVideo ? /* @__PURE__ */ jsx(MessageVideoComp, { src:
|
|
14821
|
+
isVideo ? /* @__PURE__ */ jsx(MessageVideoComp, { src: assets.url, className: "w-full h-full object-cover" }) : /* @__PURE__ */ jsx(MessageImageComp, { src: att.url, alt: fileName, className: "w-full h-full object-cover" }),
|
|
14170
14822
|
/* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-black/20 opacity-0 group-hover/att:opacity-100 transition-opacity" })
|
|
14171
14823
|
]
|
|
14172
14824
|
},
|
|
@@ -14271,7 +14923,14 @@ var MessageBubble = memo(function MessageBubble2({
|
|
|
14271
14923
|
]
|
|
14272
14924
|
}
|
|
14273
14925
|
) }),
|
|
14274
|
-
message.gmtCreate && !isStreaming && /* @__PURE__ */ jsx("div", { className: "text-zinc-600 text-[10px] mt-1", children: new Date(message.gmtCreate).toLocaleTimeString("zh-CN", {
|
|
14926
|
+
message.gmtCreate && !isStreaming && /* @__PURE__ */ jsx("div", { className: "text-zinc-600 text-[10px] mt-1 opacity-0 group-hover:opacity-100 transition-opacity", children: new Date(message.gmtCreate).toLocaleTimeString("zh-CN", {
|
|
14927
|
+
year: "numeric",
|
|
14928
|
+
month: "2-digit",
|
|
14929
|
+
day: "2-digit",
|
|
14930
|
+
hour: "2-digit",
|
|
14931
|
+
minute: "2-digit",
|
|
14932
|
+
second: "2-digit"
|
|
14933
|
+
}) })
|
|
14275
14934
|
] })
|
|
14276
14935
|
] });
|
|
14277
14936
|
});
|
|
@@ -15146,9 +15805,24 @@ var DialogDescription = React20.forwardRef(({ className, ...props }, ref) => /*
|
|
|
15146
15805
|
));
|
|
15147
15806
|
DialogDescription.displayName = DialogPrimitive.Description.displayName;
|
|
15148
15807
|
|
|
15808
|
+
// ../../node_modules/clsx/dist/clsx.mjs
|
|
15809
|
+
function r2(e) {
|
|
15810
|
+
var t, f, n = "";
|
|
15811
|
+
if ("string" == typeof e || "number" == typeof e) n += e;
|
|
15812
|
+
else if ("object" == typeof e) if (Array.isArray(e)) {
|
|
15813
|
+
var o = e.length;
|
|
15814
|
+
for (t = 0; t < o; t++) e[t] && (f = r2(e[t])) && (n && (n += " "), n += f);
|
|
15815
|
+
} else for (f in e) e[f] && (n && (n += " "), n += f);
|
|
15816
|
+
return n;
|
|
15817
|
+
}
|
|
15818
|
+
function clsx2() {
|
|
15819
|
+
for (var e, t, f = 0, n = "", o = arguments.length; f < o; f++) (e = arguments[f]) && (t = r2(e)) && (n && (n += " "), n += t);
|
|
15820
|
+
return n;
|
|
15821
|
+
}
|
|
15822
|
+
|
|
15149
15823
|
// ../../node_modules/class-variance-authority/dist/index.mjs
|
|
15150
15824
|
var falsyToString = (value) => typeof value === "boolean" ? `${value}` : value === 0 ? "0" : value;
|
|
15151
|
-
var cx =
|
|
15825
|
+
var cx = clsx2;
|
|
15152
15826
|
var cva = (base, config) => (props) => {
|
|
15153
15827
|
var _config_compoundVariants;
|
|
15154
15828
|
if ((config === null || config === void 0 ? void 0 : config.variants) == null) return cx(base, props === null || props === void 0 ? void 0 : props.class, props === null || props === void 0 ? void 0 : props.className);
|
|
@@ -15966,10 +16640,10 @@ var Observer = class {
|
|
|
15966
16640
|
});
|
|
15967
16641
|
}
|
|
15968
16642
|
};
|
|
15969
|
-
this.custom = (
|
|
16643
|
+
this.custom = (jsx59, data) => {
|
|
15970
16644
|
const id = (data == null ? void 0 : data.id) || toastsCounter++;
|
|
15971
16645
|
this.create({
|
|
15972
|
-
jsx:
|
|
16646
|
+
jsx: jsx59(id),
|
|
15973
16647
|
id,
|
|
15974
16648
|
...data
|
|
15975
16649
|
});
|
|
@@ -18470,7 +19144,57 @@ var ToolbarButton = memo(function ToolbarButton2({
|
|
|
18470
19144
|
}
|
|
18471
19145
|
);
|
|
18472
19146
|
});
|
|
18473
|
-
var
|
|
19147
|
+
var artifactTypeConfig = {
|
|
19148
|
+
html: {
|
|
19149
|
+
icon: Globe,
|
|
19150
|
+
label: "HTML",
|
|
19151
|
+
color: "text-orange-400",
|
|
19152
|
+
bgColor: "bg-orange-500/10"
|
|
19153
|
+
},
|
|
19154
|
+
svg: {
|
|
19155
|
+
icon: Globe,
|
|
19156
|
+
label: "SVG",
|
|
19157
|
+
color: "text-orange-300",
|
|
19158
|
+
bgColor: "bg-orange-500/10"
|
|
19159
|
+
},
|
|
19160
|
+
markdown: {
|
|
19161
|
+
icon: FileText,
|
|
19162
|
+
label: "Markdown",
|
|
19163
|
+
color: "text-blue-400",
|
|
19164
|
+
bgColor: "bg-blue-500/10"
|
|
19165
|
+
},
|
|
19166
|
+
json: {
|
|
19167
|
+
icon: FileJson,
|
|
19168
|
+
label: "JSON",
|
|
19169
|
+
color: "text-yellow-400",
|
|
19170
|
+
bgColor: "bg-yellow-500/10"
|
|
19171
|
+
},
|
|
19172
|
+
code: {
|
|
19173
|
+
icon: FileCode,
|
|
19174
|
+
label: "Code",
|
|
19175
|
+
color: "text-purple-400",
|
|
19176
|
+
bgColor: "bg-purple-500/10"
|
|
19177
|
+
},
|
|
19178
|
+
text: {
|
|
19179
|
+
icon: FileText,
|
|
19180
|
+
label: "Text",
|
|
19181
|
+
color: "text-zinc-400",
|
|
19182
|
+
bgColor: "bg-zinc-500/10"
|
|
19183
|
+
},
|
|
19184
|
+
image: {
|
|
19185
|
+
icon: FileImage,
|
|
19186
|
+
label: "Image",
|
|
19187
|
+
color: "text-green-400",
|
|
19188
|
+
bgColor: "bg-green-500/10"
|
|
19189
|
+
},
|
|
19190
|
+
video: {
|
|
19191
|
+
icon: Video,
|
|
19192
|
+
label: "Video",
|
|
19193
|
+
color: "text-pink-400",
|
|
19194
|
+
bgColor: "bg-pink-500/10"
|
|
19195
|
+
}
|
|
19196
|
+
};
|
|
19197
|
+
var CodeBlock3 = memo(function CodeBlock4({
|
|
18474
19198
|
code: code3,
|
|
18475
19199
|
language,
|
|
18476
19200
|
showLineNumbers = true
|
|
@@ -18758,38 +19482,1305 @@ memo(function JsonPreview2({ content }) {
|
|
|
18758
19482
|
}
|
|
18759
19483
|
return /* @__PURE__ */ jsx(CodeBlock3, { code: formattedJson, language: "json" });
|
|
18760
19484
|
});
|
|
18761
|
-
var
|
|
18762
|
-
|
|
18763
|
-
|
|
18764
|
-
|
|
18765
|
-
|
|
18766
|
-
|
|
18767
|
-
|
|
18768
|
-
|
|
18769
|
-
|
|
18770
|
-
|
|
18771
|
-
|
|
18772
|
-
|
|
18773
|
-
|
|
18774
|
-
|
|
18775
|
-
|
|
18776
|
-
|
|
18777
|
-
|
|
18778
|
-
|
|
18779
|
-
},
|
|
18780
|
-
|
|
18781
|
-
|
|
18782
|
-
|
|
18783
|
-
|
|
18784
|
-
|
|
18785
|
-
|
|
18786
|
-
|
|
18787
|
-
|
|
18788
|
-
|
|
18789
|
-
|
|
18790
|
-
|
|
18791
|
-
|
|
18792
|
-
|
|
19485
|
+
var CodeEditor = memo(function CodeEditor2({
|
|
19486
|
+
code: code3,
|
|
19487
|
+
language,
|
|
19488
|
+
onChange
|
|
19489
|
+
}) {
|
|
19490
|
+
const textareaRef = useRef(null);
|
|
19491
|
+
const handleKeyDown = useCallback((e) => {
|
|
19492
|
+
if (e.key === "Tab") {
|
|
19493
|
+
e.preventDefault();
|
|
19494
|
+
const textarea = e.currentTarget;
|
|
19495
|
+
const start = textarea.selectionStart;
|
|
19496
|
+
const end = textarea.selectionEnd;
|
|
19497
|
+
const newValue = code3.substring(0, start) + " " + code3.substring(end);
|
|
19498
|
+
onChange(newValue);
|
|
19499
|
+
requestAnimationFrame(() => {
|
|
19500
|
+
textarea.selectionStart = textarea.selectionEnd = start + 2;
|
|
19501
|
+
});
|
|
19502
|
+
}
|
|
19503
|
+
}, [code3, onChange]);
|
|
19504
|
+
return /* @__PURE__ */ jsxs("div", { className: "h-full flex flex-col bg-zinc-950 agent-sdk-light:bg-white", children: [
|
|
19505
|
+
/* @__PURE__ */ jsx("div", { className: "flex items-center justify-between px-4 py-2 border-b border-zinc-800/50 agent-sdk-light:border-zinc-200 bg-zinc-900/30 agent-sdk-light:bg-zinc-50 flex-shrink-0", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
19506
|
+
/* @__PURE__ */ jsx(Pencil, { size: 12, className: "text-[#d8ff00]" }),
|
|
19507
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs text-[#d8ff00] font-medium", children: "\u7F16\u8F91\u6A21\u5F0F" }),
|
|
19508
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs text-zinc-500 agent-sdk-light:text-zinc-600 font-mono uppercase ml-2", children: language || "text" })
|
|
19509
|
+
] }) }),
|
|
19510
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1 overflow-hidden", children: /* @__PURE__ */ jsx(
|
|
19511
|
+
"textarea",
|
|
19512
|
+
{
|
|
19513
|
+
ref: textareaRef,
|
|
19514
|
+
value: code3,
|
|
19515
|
+
onChange: (e) => onChange(e.target.value),
|
|
19516
|
+
onKeyDown: handleKeyDown,
|
|
19517
|
+
className: "w-full h-full p-4 bg-zinc-950 agent-sdk-light:bg-white text-xs font-mono text-zinc-300 agent-sdk-light:text-zinc-800 leading-relaxed resize-none focus:outline-none",
|
|
19518
|
+
spellCheck: false,
|
|
19519
|
+
autoComplete: "off",
|
|
19520
|
+
autoCorrect: "off",
|
|
19521
|
+
autoCapitalize: "off"
|
|
19522
|
+
}
|
|
19523
|
+
) })
|
|
19524
|
+
] });
|
|
19525
|
+
});
|
|
19526
|
+
function useResolvedMediaUrl(content, options) {
|
|
19527
|
+
const { fileId, type = "image", config } = options || {};
|
|
19528
|
+
const [resolvedUrl, setResolvedUrl] = useState(content);
|
|
19529
|
+
const [resolvedHdUrl, setResolvedHdUrl] = useState(content);
|
|
19530
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
19531
|
+
useEffect(() => {
|
|
19532
|
+
let active = true;
|
|
19533
|
+
setIsLoading(true);
|
|
19534
|
+
const resolve = async () => {
|
|
19535
|
+
const httpUrl = isHttpUrl(content) ? content : void 0;
|
|
19536
|
+
const asset = createAssetFromSource({
|
|
19537
|
+
fileId: fileId || (!httpUrl ? content : void 0),
|
|
19538
|
+
fileUrl: httpUrl,
|
|
19539
|
+
type
|
|
19540
|
+
});
|
|
19541
|
+
if (!asset) {
|
|
19542
|
+
if (active) {
|
|
19543
|
+
setResolvedUrl(content);
|
|
19544
|
+
setResolvedHdUrl(content);
|
|
19545
|
+
setIsLoading(false);
|
|
19546
|
+
}
|
|
19547
|
+
return;
|
|
19548
|
+
}
|
|
19549
|
+
const resolved = await resolveAssetForDisplay(asset, config);
|
|
19550
|
+
if (!active) return;
|
|
19551
|
+
if (resolved) {
|
|
19552
|
+
setResolvedUrl(resolved.url);
|
|
19553
|
+
setResolvedHdUrl(resolved.hdUrl || resolved.url);
|
|
19554
|
+
} else {
|
|
19555
|
+
setResolvedUrl(content);
|
|
19556
|
+
setResolvedHdUrl(content);
|
|
19557
|
+
}
|
|
19558
|
+
setIsLoading(false);
|
|
19559
|
+
};
|
|
19560
|
+
resolve();
|
|
19561
|
+
return () => {
|
|
19562
|
+
active = false;
|
|
19563
|
+
};
|
|
19564
|
+
}, [content, fileId, type, config]);
|
|
19565
|
+
return { url: resolvedUrl, hdUrl: resolvedHdUrl, isLoading };
|
|
19566
|
+
}
|
|
19567
|
+
function useResolvedThumbnailUrl(content, options) {
|
|
19568
|
+
const { fileId, type = "image", config, enabled = true } = options || {};
|
|
19569
|
+
const [url, setUrl] = useState(null);
|
|
19570
|
+
useEffect(() => {
|
|
19571
|
+
if (!enabled || !content) {
|
|
19572
|
+
setUrl(null);
|
|
19573
|
+
return;
|
|
19574
|
+
}
|
|
19575
|
+
if (type === "video") {
|
|
19576
|
+
setUrl(null);
|
|
19577
|
+
return;
|
|
19578
|
+
}
|
|
19579
|
+
let active = true;
|
|
19580
|
+
const resolve = async () => {
|
|
19581
|
+
const httpUrl = isHttpUrl(content) ? content : void 0;
|
|
19582
|
+
const asset = createAssetFromSource({
|
|
19583
|
+
fileId: fileId || (!httpUrl ? content : void 0),
|
|
19584
|
+
fileUrl: httpUrl,
|
|
19585
|
+
type
|
|
19586
|
+
});
|
|
19587
|
+
if (!asset) {
|
|
19588
|
+
if (active) setUrl(isHttpUrl(content) ? content : null);
|
|
19589
|
+
return;
|
|
19590
|
+
}
|
|
19591
|
+
const resolved = await resolveAssetForDisplay(asset, config);
|
|
19592
|
+
if (!active) return;
|
|
19593
|
+
setUrl(resolved?.url || (isHttpUrl(content) ? content : null));
|
|
19594
|
+
};
|
|
19595
|
+
resolve();
|
|
19596
|
+
return () => {
|
|
19597
|
+
active = false;
|
|
19598
|
+
};
|
|
19599
|
+
}, [content, fileId, type, config, enabled]);
|
|
19600
|
+
return url;
|
|
19601
|
+
}
|
|
19602
|
+
var ImageArtifactPreview = memo(function ImageArtifactPreview2({
|
|
19603
|
+
content,
|
|
19604
|
+
metadata,
|
|
19605
|
+
config
|
|
19606
|
+
}) {
|
|
19607
|
+
const [isZoomed, setIsZoomed] = useState(false);
|
|
19608
|
+
const [showInfo, setShowInfo] = useState(true);
|
|
19609
|
+
const [imgNaturalSize, setImgNaturalSize] = useState(null);
|
|
19610
|
+
const [copied, setCopied] = useState(null);
|
|
19611
|
+
const { hdUrl: resolvedHdUrl } = useResolvedMediaUrl(content, {
|
|
19612
|
+
fileId: metadata?.fileId,
|
|
19613
|
+
type: "image",
|
|
19614
|
+
config
|
|
19615
|
+
});
|
|
19616
|
+
const generationParams = metadata?.generationParams;
|
|
19617
|
+
const toolName = metadata?.toolName;
|
|
19618
|
+
const relation = metadata?.relation;
|
|
19619
|
+
const handleCopy = useCallback(async (text3, label) => {
|
|
19620
|
+
try {
|
|
19621
|
+
await navigator.clipboard.writeText(text3);
|
|
19622
|
+
setCopied(label);
|
|
19623
|
+
setTimeout(() => setCopied(null), 2e3);
|
|
19624
|
+
} catch {
|
|
19625
|
+
}
|
|
19626
|
+
}, []);
|
|
19627
|
+
const handleDownload = useCallback(() => {
|
|
19628
|
+
const link2 = document.createElement("a");
|
|
19629
|
+
link2.href = resolvedHdUrl;
|
|
19630
|
+
link2.download = `generated-${Date.now()}.png`;
|
|
19631
|
+
link2.target = "_blank";
|
|
19632
|
+
document.body.appendChild(link2);
|
|
19633
|
+
link2.click();
|
|
19634
|
+
document.body.removeChild(link2);
|
|
19635
|
+
}, [resolvedHdUrl]);
|
|
19636
|
+
const formatParamKey = (key) => {
|
|
19637
|
+
const keyMap = {
|
|
19638
|
+
content: "Prompt",
|
|
19639
|
+
width: "\u5BBD\u5EA6",
|
|
19640
|
+
height: "\u9AD8\u5EA6",
|
|
19641
|
+
batchSize: "\u751F\u6210\u6570\u91CF",
|
|
19642
|
+
steps: "\u6B65\u6570",
|
|
19643
|
+
cfg_scale: "CFG Scale",
|
|
19644
|
+
seed: "\u79CD\u5B50",
|
|
19645
|
+
sampler: "\u91C7\u6837\u5668",
|
|
19646
|
+
model: "\u6A21\u578B",
|
|
19647
|
+
negative_prompt: "\u53CD\u5411\u63D0\u793A\u8BCD",
|
|
19648
|
+
style: "\u98CE\u683C",
|
|
19649
|
+
quality: "\u8D28\u91CF"
|
|
19650
|
+
};
|
|
19651
|
+
return keyMap[key] || key.replace(/([A-Z])/g, " $1").replace(/_/g, " ").replace(/^./, (s) => s.toUpperCase());
|
|
19652
|
+
};
|
|
19653
|
+
const promptText = generationParams?.content ? String(generationParams.content) : null;
|
|
19654
|
+
const otherParams = generationParams ? Object.entries(generationParams).filter(([key]) => key !== "content") : [];
|
|
19655
|
+
return /* @__PURE__ */ jsxs("div", { className: "h-full flex flex-col bg-zinc-950 agent-sdk-light:bg-white", children: [
|
|
19656
|
+
/* @__PURE__ */ 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: [
|
|
19657
|
+
/* @__PURE__ */ jsx("div", { className: "absolute inset-0 opacity-[0.03]", style: {
|
|
19658
|
+
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%)",
|
|
19659
|
+
backgroundSize: "20px 20px",
|
|
19660
|
+
backgroundPosition: "0 0, 0 10px, 10px -10px, -10px 0px"
|
|
19661
|
+
} }),
|
|
19662
|
+
/* @__PURE__ */ jsx(
|
|
19663
|
+
"div",
|
|
19664
|
+
{
|
|
19665
|
+
className: cn2(
|
|
19666
|
+
"relative transition-transform duration-300 cursor-zoom-in z-10",
|
|
19667
|
+
isZoomed && "cursor-zoom-out scale-[2] z-50"
|
|
19668
|
+
),
|
|
19669
|
+
onClick: () => setIsZoomed((prev) => !prev),
|
|
19670
|
+
children: /* @__PURE__ */ jsx(
|
|
19671
|
+
"img",
|
|
19672
|
+
{
|
|
19673
|
+
src: resolvedHdUrl,
|
|
19674
|
+
alt: "Generated image",
|
|
19675
|
+
className: "max-w-full max-h-[60vh] object-contain rounded-lg shadow-2xl",
|
|
19676
|
+
loading: "lazy",
|
|
19677
|
+
onLoad: (e) => {
|
|
19678
|
+
const img = e.target;
|
|
19679
|
+
setImgNaturalSize({ width: img.naturalWidth, height: img.naturalHeight });
|
|
19680
|
+
}
|
|
19681
|
+
}
|
|
19682
|
+
)
|
|
19683
|
+
}
|
|
19684
|
+
),
|
|
19685
|
+
/* @__PURE__ */ jsxs("div", { className: "absolute top-4 right-4 flex items-center gap-1.5 z-20", children: [
|
|
19686
|
+
/* @__PURE__ */ jsx(
|
|
19687
|
+
"button",
|
|
19688
|
+
{
|
|
19689
|
+
onClick: () => setShowInfo((prev) => !prev),
|
|
19690
|
+
className: cn2(
|
|
19691
|
+
"p-2 rounded-lg backdrop-blur-sm transition-colors",
|
|
19692
|
+
showInfo ? "bg-[#d8ff00]/20 text-[#d8ff00]" : "bg-black/30 text-white/70 hover:text-white hover:bg-black/50"
|
|
19693
|
+
),
|
|
19694
|
+
title: showInfo ? "\u9690\u85CF\u8BE6\u60C5" : "\u663E\u793A\u8BE6\u60C5",
|
|
19695
|
+
children: /* @__PURE__ */ jsx(FileText, { size: 16 })
|
|
19696
|
+
}
|
|
19697
|
+
),
|
|
19698
|
+
/* @__PURE__ */ jsx(
|
|
19699
|
+
"button",
|
|
19700
|
+
{
|
|
19701
|
+
onClick: handleDownload,
|
|
19702
|
+
className: "p-2 bg-black/30 text-white/70 hover:text-white hover:bg-black/50 rounded-lg backdrop-blur-sm transition-colors",
|
|
19703
|
+
title: "\u4E0B\u8F7D\u56FE\u7247",
|
|
19704
|
+
children: /* @__PURE__ */ jsx(Download, { size: 16 })
|
|
19705
|
+
}
|
|
19706
|
+
)
|
|
19707
|
+
] }),
|
|
19708
|
+
imgNaturalSize && /* @__PURE__ */ 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: [
|
|
19709
|
+
/* @__PURE__ */ jsx(FileImage, { size: 12, className: "text-white/60" }),
|
|
19710
|
+
/* @__PURE__ */ jsxs("span", { className: "text-[11px] text-white/80 font-mono", children: [
|
|
19711
|
+
imgNaturalSize.width,
|
|
19712
|
+
" \xD7 ",
|
|
19713
|
+
imgNaturalSize.height
|
|
19714
|
+
] })
|
|
19715
|
+
] })
|
|
19716
|
+
] }),
|
|
19717
|
+
showInfo && (generationParams || toolName) && /* @__PURE__ */ 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__ */ jsxs("div", { className: "px-5 py-4 space-y-4", children: [
|
|
19718
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
19719
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2.5", children: [
|
|
19720
|
+
/* @__PURE__ */ jsx("div", { className: "w-7 h-7 rounded-lg bg-[#d8ff00]/10 flex items-center justify-center", children: /* @__PURE__ */ jsx(Sparkles, { size: 14, className: "text-[#d8ff00]" }) }),
|
|
19721
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
19722
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-medium text-zinc-200 agent-sdk-light:text-zinc-800", children: toolName || "\u56FE\u7247\u751F\u6210" }),
|
|
19723
|
+
relation?.workflowCode && /* @__PURE__ */ jsx("span", { className: "ml-2 text-[10px] text-zinc-500 font-mono bg-zinc-800/50 agent-sdk-light:bg-zinc-200 px-1.5 py-0.5 rounded", children: relation.workflowCode })
|
|
19724
|
+
] })
|
|
19725
|
+
] }),
|
|
19726
|
+
metadata?.taskId && /* @__PURE__ */ jsxs("span", { className: "text-[10px] text-zinc-600 font-mono", children: [
|
|
19727
|
+
"Task: ",
|
|
19728
|
+
metadata.taskId
|
|
19729
|
+
] })
|
|
19730
|
+
] }),
|
|
19731
|
+
promptText && /* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
19732
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
19733
|
+
/* @__PURE__ */ jsx("span", { className: "text-[10px] text-zinc-500 uppercase tracking-wider font-medium", children: "Prompt" }),
|
|
19734
|
+
/* @__PURE__ */ jsx(
|
|
19735
|
+
"button",
|
|
19736
|
+
{
|
|
19737
|
+
onClick: () => handleCopy(promptText, "prompt"),
|
|
19738
|
+
className: "text-[10px] text-zinc-500 hover:text-zinc-300 transition-colors flex items-center gap-1",
|
|
19739
|
+
children: copied === "prompt" ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
19740
|
+
/* @__PURE__ */ jsx(CheckCheck, { size: 10, className: "text-green-400" }),
|
|
19741
|
+
" \u5DF2\u590D\u5236"
|
|
19742
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
19743
|
+
/* @__PURE__ */ jsx(Copy, { size: 10 }),
|
|
19744
|
+
" \u590D\u5236"
|
|
19745
|
+
] })
|
|
19746
|
+
}
|
|
19747
|
+
)
|
|
19748
|
+
] }),
|
|
19749
|
+
/* @__PURE__ */ jsx("div", { className: "p-3 bg-zinc-800/50 agent-sdk-light:bg-zinc-100 rounded-lg border border-zinc-700/30 agent-sdk-light:border-zinc-200", children: /* @__PURE__ */ jsx("p", { className: "text-xs text-zinc-300 agent-sdk-light:text-zinc-700 leading-relaxed whitespace-pre-wrap", children: promptText }) })
|
|
19750
|
+
] }),
|
|
19751
|
+
otherParams.length > 0 && /* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
19752
|
+
/* @__PURE__ */ jsx("span", { className: "text-[10px] text-zinc-500 uppercase tracking-wider font-medium", children: "\u53C2\u6570" }),
|
|
19753
|
+
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 sm:grid-cols-3 gap-2", children: otherParams.map(([key, value]) => {
|
|
19754
|
+
const displayValue = String(value);
|
|
19755
|
+
if (displayValue.length > 100) return null;
|
|
19756
|
+
return /* @__PURE__ */ jsxs(
|
|
19757
|
+
"div",
|
|
19758
|
+
{
|
|
19759
|
+
className: "flex flex-col gap-0.5 p-2 bg-zinc-800/30 agent-sdk-light:bg-zinc-100 rounded-lg border border-zinc-700/20 agent-sdk-light:border-zinc-200",
|
|
19760
|
+
children: [
|
|
19761
|
+
/* @__PURE__ */ jsx("span", { className: "text-[10px] text-zinc-500 agent-sdk-light:text-zinc-500", children: formatParamKey(key) }),
|
|
19762
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs text-zinc-200 agent-sdk-light:text-zinc-800 font-mono font-medium truncate", title: displayValue, children: displayValue })
|
|
19763
|
+
]
|
|
19764
|
+
},
|
|
19765
|
+
key
|
|
19766
|
+
);
|
|
19767
|
+
}) })
|
|
19768
|
+
] }),
|
|
19769
|
+
(metadata?.fileId || metadata?.workId) && /* @__PURE__ */ jsx("div", { className: "pt-2 border-t border-zinc-800/30 agent-sdk-light:border-zinc-200", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-4 text-[10px] text-zinc-600", children: [
|
|
19770
|
+
metadata.workId && /* @__PURE__ */ jsxs("span", { children: [
|
|
19771
|
+
"ID: ",
|
|
19772
|
+
/* @__PURE__ */ jsx("span", { className: "font-mono text-zinc-500", children: metadata.workId })
|
|
19773
|
+
] }),
|
|
19774
|
+
metadata.fileId && /* @__PURE__ */ jsxs("span", { className: "truncate max-w-[200px]", title: metadata.fileId, children: [
|
|
19775
|
+
"File: ",
|
|
19776
|
+
/* @__PURE__ */ jsx("span", { className: "font-mono text-zinc-500", children: metadata.fileId })
|
|
19777
|
+
] })
|
|
19778
|
+
] }) })
|
|
19779
|
+
] }) })
|
|
19780
|
+
] });
|
|
19781
|
+
});
|
|
19782
|
+
var VideoArtifactPreview = memo(function VideoArtifactPreview2({
|
|
19783
|
+
content,
|
|
19784
|
+
metadata,
|
|
19785
|
+
config
|
|
19786
|
+
}) {
|
|
19787
|
+
const { hdUrl: resolvedUrl } = useResolvedMediaUrl(content, {
|
|
19788
|
+
fileId: metadata?.fileId,
|
|
19789
|
+
type: "video",
|
|
19790
|
+
config
|
|
19791
|
+
});
|
|
19792
|
+
const videoRef = useRef(null);
|
|
19793
|
+
const progressRef = useRef(null);
|
|
19794
|
+
const [isPlaying, setIsPlaying] = useState(false);
|
|
19795
|
+
const [isMuted, setIsMuted] = useState(false);
|
|
19796
|
+
const [duration, setDuration] = useState(0);
|
|
19797
|
+
const [currentTime, setCurrentTime] = useState(0);
|
|
19798
|
+
const [volume, setVolume] = useState(1);
|
|
19799
|
+
const [isLoaded, setIsLoaded] = useState(false);
|
|
19800
|
+
const [showVolumeSlider, setShowVolumeSlider] = useState(false);
|
|
19801
|
+
const [posterUrl, setPosterUrl] = useState(null);
|
|
19802
|
+
const [isDraggingProgress, setIsDraggingProgress] = useState(false);
|
|
19803
|
+
const generationParams = metadata?.generationParams;
|
|
19804
|
+
const toolName = metadata?.toolName;
|
|
19805
|
+
useEffect(() => {
|
|
19806
|
+
const video = document.createElement("video");
|
|
19807
|
+
video.crossOrigin = "anonymous";
|
|
19808
|
+
video.preload = "metadata";
|
|
19809
|
+
video.muted = true;
|
|
19810
|
+
video.addEventListener("loadeddata", () => {
|
|
19811
|
+
video.currentTime = Math.min(0.5, video.duration * 0.1);
|
|
19812
|
+
});
|
|
19813
|
+
video.addEventListener("seeked", () => {
|
|
19814
|
+
try {
|
|
19815
|
+
const canvas = document.createElement("canvas");
|
|
19816
|
+
canvas.width = video.videoWidth;
|
|
19817
|
+
canvas.height = video.videoHeight;
|
|
19818
|
+
const ctx = canvas.getContext("2d");
|
|
19819
|
+
if (ctx) {
|
|
19820
|
+
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
|
|
19821
|
+
setPosterUrl(canvas.toDataURL("image/jpeg", 0.8));
|
|
19822
|
+
}
|
|
19823
|
+
} catch {
|
|
19824
|
+
}
|
|
19825
|
+
video.remove();
|
|
19826
|
+
});
|
|
19827
|
+
video.addEventListener("error", () => video.remove());
|
|
19828
|
+
video.src = resolvedUrl;
|
|
19829
|
+
video.load();
|
|
19830
|
+
return () => {
|
|
19831
|
+
video.remove();
|
|
19832
|
+
};
|
|
19833
|
+
}, [resolvedUrl]);
|
|
19834
|
+
const handleLoadedMetadata = () => {
|
|
19835
|
+
const video = videoRef.current;
|
|
19836
|
+
if (video) {
|
|
19837
|
+
setDuration(video.duration);
|
|
19838
|
+
setIsLoaded(true);
|
|
19839
|
+
}
|
|
19840
|
+
};
|
|
19841
|
+
const handleTimeUpdate = () => {
|
|
19842
|
+
if (!isDraggingProgress && videoRef.current) {
|
|
19843
|
+
setCurrentTime(videoRef.current.currentTime);
|
|
19844
|
+
}
|
|
19845
|
+
};
|
|
19846
|
+
const togglePlay = useCallback(() => {
|
|
19847
|
+
const video = videoRef.current;
|
|
19848
|
+
if (!video) return;
|
|
19849
|
+
if (isPlaying) {
|
|
19850
|
+
video.pause();
|
|
19851
|
+
setIsPlaying(false);
|
|
19852
|
+
} else {
|
|
19853
|
+
video.play().then(() => setIsPlaying(true)).catch(() => {
|
|
19854
|
+
});
|
|
19855
|
+
}
|
|
19856
|
+
}, [isPlaying]);
|
|
19857
|
+
const toggleMute = useCallback(() => {
|
|
19858
|
+
const video = videoRef.current;
|
|
19859
|
+
if (video) {
|
|
19860
|
+
video.muted = !isMuted;
|
|
19861
|
+
setIsMuted(!isMuted);
|
|
19862
|
+
}
|
|
19863
|
+
}, [isMuted]);
|
|
19864
|
+
const handleVolumeChange = useCallback((e) => {
|
|
19865
|
+
const newVolume = parseFloat(e.target.value);
|
|
19866
|
+
setVolume(newVolume);
|
|
19867
|
+
if (videoRef.current) {
|
|
19868
|
+
videoRef.current.volume = newVolume;
|
|
19869
|
+
if (newVolume === 0) {
|
|
19870
|
+
setIsMuted(true);
|
|
19871
|
+
videoRef.current.muted = true;
|
|
19872
|
+
} else if (isMuted) {
|
|
19873
|
+
setIsMuted(false);
|
|
19874
|
+
videoRef.current.muted = false;
|
|
19875
|
+
}
|
|
19876
|
+
}
|
|
19877
|
+
}, [isMuted]);
|
|
19878
|
+
const handleProgressClick = useCallback((e) => {
|
|
19879
|
+
const video = videoRef.current;
|
|
19880
|
+
const bar = progressRef.current;
|
|
19881
|
+
if (!video || !bar || !duration) return;
|
|
19882
|
+
const rect = bar.getBoundingClientRect();
|
|
19883
|
+
const ratio = Math.max(0, Math.min(1, (e.clientX - rect.left) / rect.width));
|
|
19884
|
+
video.currentTime = ratio * duration;
|
|
19885
|
+
setCurrentTime(ratio * duration);
|
|
19886
|
+
}, [duration]);
|
|
19887
|
+
const handleProgressDrag = useCallback((e) => {
|
|
19888
|
+
if (!isDraggingProgress) return;
|
|
19889
|
+
const bar = progressRef.current;
|
|
19890
|
+
if (!bar || !duration) return;
|
|
19891
|
+
const rect = bar.getBoundingClientRect();
|
|
19892
|
+
const ratio = Math.max(0, Math.min(1, (e.clientX - rect.left) / rect.width));
|
|
19893
|
+
setCurrentTime(ratio * duration);
|
|
19894
|
+
}, [isDraggingProgress, duration]);
|
|
19895
|
+
const handleProgressDragEnd = useCallback(() => {
|
|
19896
|
+
if (isDraggingProgress && videoRef.current) {
|
|
19897
|
+
videoRef.current.currentTime = currentTime;
|
|
19898
|
+
}
|
|
19899
|
+
setIsDraggingProgress(false);
|
|
19900
|
+
}, [isDraggingProgress, currentTime]);
|
|
19901
|
+
useEffect(() => {
|
|
19902
|
+
if (!isDraggingProgress) return;
|
|
19903
|
+
const handleMouseUp = () => handleProgressDragEnd();
|
|
19904
|
+
const handleMouseMove = (e) => {
|
|
19905
|
+
const bar = progressRef.current;
|
|
19906
|
+
if (!bar || !duration) return;
|
|
19907
|
+
const rect = bar.getBoundingClientRect();
|
|
19908
|
+
const ratio = Math.max(0, Math.min(1, (e.clientX - rect.left) / rect.width));
|
|
19909
|
+
setCurrentTime(ratio * duration);
|
|
19910
|
+
};
|
|
19911
|
+
window.addEventListener("mouseup", handleMouseUp);
|
|
19912
|
+
window.addEventListener("mousemove", handleMouseMove);
|
|
19913
|
+
return () => {
|
|
19914
|
+
window.removeEventListener("mouseup", handleMouseUp);
|
|
19915
|
+
window.removeEventListener("mousemove", handleMouseMove);
|
|
19916
|
+
};
|
|
19917
|
+
}, [isDraggingProgress, duration, handleProgressDragEnd]);
|
|
19918
|
+
const handleDownload = useCallback(() => {
|
|
19919
|
+
const link2 = document.createElement("a");
|
|
19920
|
+
link2.href = resolvedUrl;
|
|
19921
|
+
link2.download = `video-${Date.now()}.mp4`;
|
|
19922
|
+
document.body.appendChild(link2);
|
|
19923
|
+
link2.click();
|
|
19924
|
+
document.body.removeChild(link2);
|
|
19925
|
+
}, [resolvedUrl]);
|
|
19926
|
+
const formatTime2 = (seconds) => {
|
|
19927
|
+
const mins = Math.floor(seconds / 60);
|
|
19928
|
+
const secs = Math.floor(seconds % 60);
|
|
19929
|
+
return `${mins}:${secs.toString().padStart(2, "0")}`;
|
|
19930
|
+
};
|
|
19931
|
+
const progressPercent = duration > 0 ? currentTime / duration * 100 : 0;
|
|
19932
|
+
return /* @__PURE__ */ jsxs("div", { className: "h-full flex flex-col bg-zinc-950 agent-sdk-light:bg-white", children: [
|
|
19933
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1 overflow-hidden flex items-center justify-center bg-black relative group/player", children: [
|
|
19934
|
+
posterUrl && !isPlaying && !currentTime && /* @__PURE__ */ jsx(
|
|
19935
|
+
"img",
|
|
19936
|
+
{
|
|
19937
|
+
src: posterUrl,
|
|
19938
|
+
alt: "Video cover",
|
|
19939
|
+
className: "absolute inset-0 w-full h-full object-contain z-[1]"
|
|
19940
|
+
}
|
|
19941
|
+
),
|
|
19942
|
+
/* @__PURE__ */ jsx(
|
|
19943
|
+
"video",
|
|
19944
|
+
{
|
|
19945
|
+
ref: videoRef,
|
|
19946
|
+
src: resolvedUrl,
|
|
19947
|
+
muted: isMuted,
|
|
19948
|
+
playsInline: true,
|
|
19949
|
+
preload: "metadata",
|
|
19950
|
+
onLoadedMetadata: handleLoadedMetadata,
|
|
19951
|
+
onTimeUpdate: handleTimeUpdate,
|
|
19952
|
+
onEnded: () => setIsPlaying(false),
|
|
19953
|
+
onClick: togglePlay,
|
|
19954
|
+
className: cn2(
|
|
19955
|
+
"max-w-full max-h-full object-contain cursor-pointer",
|
|
19956
|
+
!isPlaying && posterUrl && !currentTime && "opacity-0"
|
|
19957
|
+
)
|
|
19958
|
+
}
|
|
19959
|
+
),
|
|
19960
|
+
!isPlaying && /* @__PURE__ */ jsx(
|
|
19961
|
+
"div",
|
|
19962
|
+
{
|
|
19963
|
+
className: "absolute inset-0 z-[2] flex items-center justify-center cursor-pointer",
|
|
19964
|
+
onClick: togglePlay,
|
|
19965
|
+
children: /* @__PURE__ */ jsx("div", { className: cn2(
|
|
19966
|
+
"w-16 h-16 rounded-full bg-white/15 backdrop-blur-md",
|
|
19967
|
+
"flex items-center justify-center",
|
|
19968
|
+
"transition-all duration-200",
|
|
19969
|
+
"group-hover/player:scale-110 group-hover/player:bg-white/25",
|
|
19970
|
+
"shadow-2xl shadow-black/30"
|
|
19971
|
+
), children: /* @__PURE__ */ jsx("svg", { width: "26", height: "26", viewBox: "0 0 24 24", fill: "white", className: "ml-1", children: /* @__PURE__ */ jsx("path", { d: "M8 5v14l11-7z" }) }) })
|
|
19972
|
+
}
|
|
19973
|
+
),
|
|
19974
|
+
/* @__PURE__ */ jsxs("div", { className: cn2(
|
|
19975
|
+
"absolute bottom-0 left-0 right-0 z-[3]",
|
|
19976
|
+
"bg-gradient-to-t from-black/90 via-black/50 to-transparent",
|
|
19977
|
+
"px-4 pb-3 pt-10",
|
|
19978
|
+
"transition-opacity duration-300",
|
|
19979
|
+
"opacity-0 group-hover/player:opacity-100",
|
|
19980
|
+
isPlaying ? "" : "opacity-100"
|
|
19981
|
+
), children: [
|
|
19982
|
+
/* @__PURE__ */ jsx(
|
|
19983
|
+
"div",
|
|
19984
|
+
{
|
|
19985
|
+
ref: progressRef,
|
|
19986
|
+
className: "w-full h-1.5 bg-white/20 rounded-full mb-3 cursor-pointer group/progress hover:h-2 transition-all",
|
|
19987
|
+
onClick: handleProgressClick,
|
|
19988
|
+
onMouseDown: () => setIsDraggingProgress(true),
|
|
19989
|
+
onMouseMove: handleProgressDrag,
|
|
19990
|
+
children: /* @__PURE__ */ jsx(
|
|
19991
|
+
"div",
|
|
19992
|
+
{
|
|
19993
|
+
className: "h-full bg-[#d8ff00] rounded-full relative",
|
|
19994
|
+
style: { width: `${progressPercent}%` },
|
|
19995
|
+
children: /* @__PURE__ */ jsx("div", { className: "absolute right-0 top-1/2 -translate-y-1/2 w-3.5 h-3.5 bg-[#d8ff00] rounded-full opacity-0 group-hover/progress:opacity-100 transition-opacity shadow-lg -mr-1.5" })
|
|
19996
|
+
}
|
|
19997
|
+
)
|
|
19998
|
+
}
|
|
19999
|
+
),
|
|
20000
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
20001
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
20002
|
+
/* @__PURE__ */ jsx("button", { onClick: togglePlay, className: "p-1 text-white/90 hover:text-white transition-colors", children: isPlaying ? /* @__PURE__ */ jsxs("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "currentColor", children: [
|
|
20003
|
+
/* @__PURE__ */ jsx("rect", { x: "6", y: "4", width: "4", height: "16", rx: "1" }),
|
|
20004
|
+
/* @__PURE__ */ jsx("rect", { x: "14", y: "4", width: "4", height: "16", rx: "1" })
|
|
20005
|
+
] }) : /* @__PURE__ */ jsx("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ jsx("path", { d: "M8 5v14l11-7z" }) }) }),
|
|
20006
|
+
/* @__PURE__ */ jsxs(
|
|
20007
|
+
"div",
|
|
20008
|
+
{
|
|
20009
|
+
className: "flex items-center gap-1.5 relative",
|
|
20010
|
+
onMouseEnter: () => setShowVolumeSlider(true),
|
|
20011
|
+
onMouseLeave: () => setShowVolumeSlider(false),
|
|
20012
|
+
children: [
|
|
20013
|
+
/* @__PURE__ */ jsx("button", { onClick: toggleMute, className: "p-1 text-white/80 hover:text-white transition-colors", children: isMuted || volume === 0 ? /* @__PURE__ */ jsxs("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
20014
|
+
/* @__PURE__ */ jsx("polygon", { points: "11 5 6 9 2 9 2 15 6 15 11 19 11 5" }),
|
|
20015
|
+
/* @__PURE__ */ jsx("line", { x1: "23", y1: "9", x2: "17", y2: "15" }),
|
|
20016
|
+
/* @__PURE__ */ jsx("line", { x1: "17", y1: "9", x2: "23", y2: "15" })
|
|
20017
|
+
] }) : /* @__PURE__ */ jsxs("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
20018
|
+
/* @__PURE__ */ jsx("polygon", { points: "11 5 6 9 2 9 2 15 6 15 11 19 11 5" }),
|
|
20019
|
+
/* @__PURE__ */ jsx("path", { d: "M19.07 4.93a10 10 0 0 1 0 14.14" }),
|
|
20020
|
+
/* @__PURE__ */ jsx("path", { d: "M15.54 8.46a5 5 0 0 1 0 7.07" })
|
|
20021
|
+
] }) }),
|
|
20022
|
+
showVolumeSlider && /* @__PURE__ */ jsx(
|
|
20023
|
+
"input",
|
|
20024
|
+
{
|
|
20025
|
+
type: "range",
|
|
20026
|
+
min: "0",
|
|
20027
|
+
max: "1",
|
|
20028
|
+
step: "0.05",
|
|
20029
|
+
value: isMuted ? 0 : volume,
|
|
20030
|
+
onChange: handleVolumeChange,
|
|
20031
|
+
className: "w-20 h-1 appearance-none bg-white/20 rounded-full cursor-pointer accent-[#d8ff00]"
|
|
20032
|
+
}
|
|
20033
|
+
)
|
|
20034
|
+
]
|
|
20035
|
+
}
|
|
20036
|
+
),
|
|
20037
|
+
/* @__PURE__ */ jsxs("span", { className: "text-xs text-white/60 font-mono tabular-nums", children: [
|
|
20038
|
+
formatTime2(currentTime),
|
|
20039
|
+
" / ",
|
|
20040
|
+
formatTime2(duration)
|
|
20041
|
+
] })
|
|
20042
|
+
] }),
|
|
20043
|
+
/* @__PURE__ */ jsx("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsx(
|
|
20044
|
+
"button",
|
|
20045
|
+
{
|
|
20046
|
+
onClick: handleDownload,
|
|
20047
|
+
className: "p-1.5 text-white/60 hover:text-white transition-colors",
|
|
20048
|
+
title: "\u4E0B\u8F7D\u89C6\u9891",
|
|
20049
|
+
children: /* @__PURE__ */ jsx(Download, { size: 16 })
|
|
20050
|
+
}
|
|
20051
|
+
) })
|
|
20052
|
+
] })
|
|
20053
|
+
] })
|
|
20054
|
+
] }),
|
|
20055
|
+
generationParams && /* @__PURE__ */ jsx("div", { className: "flex-shrink-0 border-t border-zinc-800/50 agent-sdk-light:border-zinc-200 bg-zinc-900/50 agent-sdk-light:bg-zinc-50", children: /* @__PURE__ */ jsxs("div", { className: "px-4 py-3", children: [
|
|
20056
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mb-2", children: [
|
|
20057
|
+
/* @__PURE__ */ jsx(Sparkles, { size: 12, className: "text-[#d8ff00]" }),
|
|
20058
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-zinc-300 agent-sdk-light:text-zinc-700", children: toolName || "\u751F\u6210\u53C2\u6570" })
|
|
20059
|
+
] }),
|
|
20060
|
+
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 gap-x-4 gap-y-1.5", children: Object.entries(generationParams).map(([key, value]) => {
|
|
20061
|
+
const displayValue = String(value);
|
|
20062
|
+
if (displayValue.length > 80) return null;
|
|
20063
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-xs", children: [
|
|
20064
|
+
/* @__PURE__ */ jsx("span", { className: "text-zinc-500 agent-sdk-light:text-zinc-500 capitalize", children: key.replace(/([A-Z])/g, " $1").replace(/^./, (s) => s.toUpperCase()) }),
|
|
20065
|
+
/* @__PURE__ */ jsx("span", { className: "text-zinc-300 agent-sdk-light:text-zinc-700 font-mono", children: displayValue })
|
|
20066
|
+
] }, key);
|
|
20067
|
+
}) }),
|
|
20068
|
+
generationParams.content && String(generationParams.content).length > 0 && /* @__PURE__ */ jsxs("div", { className: "mt-2 pt-2 border-t border-zinc-800/30 agent-sdk-light:border-zinc-200", children: [
|
|
20069
|
+
/* @__PURE__ */ jsx("span", { className: "text-[10px] text-zinc-500 agent-sdk-light:text-zinc-500 uppercase tracking-wider", children: "Prompt" }),
|
|
20070
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-zinc-300 agent-sdk-light:text-zinc-700 mt-1 leading-relaxed line-clamp-3", children: String(generationParams.content) })
|
|
20071
|
+
] })
|
|
20072
|
+
] }) })
|
|
20073
|
+
] });
|
|
20074
|
+
});
|
|
20075
|
+
function htmlToMarkdown(element) {
|
|
20076
|
+
const lines = [];
|
|
20077
|
+
function processNode(node2, listDepth = 0) {
|
|
20078
|
+
if (node2.nodeType === Node.TEXT_NODE) {
|
|
20079
|
+
return node2.textContent || "";
|
|
20080
|
+
}
|
|
20081
|
+
if (node2.nodeType !== Node.ELEMENT_NODE) return "";
|
|
20082
|
+
const el = node2;
|
|
20083
|
+
const tag = el.tagName.toLowerCase();
|
|
20084
|
+
const childContent = () => {
|
|
20085
|
+
let result = "";
|
|
20086
|
+
el.childNodes.forEach((child) => {
|
|
20087
|
+
result += processNode(child, listDepth);
|
|
20088
|
+
});
|
|
20089
|
+
return result;
|
|
20090
|
+
};
|
|
20091
|
+
switch (tag) {
|
|
20092
|
+
case "h1":
|
|
20093
|
+
return `# ${childContent().trim()}
|
|
20094
|
+
|
|
20095
|
+
`;
|
|
20096
|
+
case "h2":
|
|
20097
|
+
return `## ${childContent().trim()}
|
|
20098
|
+
|
|
20099
|
+
`;
|
|
20100
|
+
case "h3":
|
|
20101
|
+
return `### ${childContent().trim()}
|
|
20102
|
+
|
|
20103
|
+
`;
|
|
20104
|
+
case "h4":
|
|
20105
|
+
return `#### ${childContent().trim()}
|
|
20106
|
+
|
|
20107
|
+
`;
|
|
20108
|
+
case "h5":
|
|
20109
|
+
return `##### ${childContent().trim()}
|
|
20110
|
+
|
|
20111
|
+
`;
|
|
20112
|
+
case "h6":
|
|
20113
|
+
return `###### ${childContent().trim()}
|
|
20114
|
+
|
|
20115
|
+
`;
|
|
20116
|
+
case "p": {
|
|
20117
|
+
const inner = childContent().trim();
|
|
20118
|
+
return inner ? `${inner}
|
|
20119
|
+
|
|
20120
|
+
` : "\n";
|
|
20121
|
+
}
|
|
20122
|
+
case "br":
|
|
20123
|
+
return "\n";
|
|
20124
|
+
case "strong":
|
|
20125
|
+
case "b":
|
|
20126
|
+
return `**${childContent()}**`;
|
|
20127
|
+
case "em":
|
|
20128
|
+
case "i":
|
|
20129
|
+
return `*${childContent()}*`;
|
|
20130
|
+
case "del":
|
|
20131
|
+
case "s":
|
|
20132
|
+
return `~~${childContent()}~~`;
|
|
20133
|
+
case "code": {
|
|
20134
|
+
if (el.parentElement?.tagName.toLowerCase() === "pre") {
|
|
20135
|
+
return childContent();
|
|
20136
|
+
}
|
|
20137
|
+
return `\`${childContent()}\``;
|
|
20138
|
+
}
|
|
20139
|
+
case "pre": {
|
|
20140
|
+
const codeEl = el.querySelector("code");
|
|
20141
|
+
const codeContent = codeEl ? codeEl.textContent || "" : el.textContent || "";
|
|
20142
|
+
const langClass = codeEl?.className?.match(/language-(\w+)/);
|
|
20143
|
+
const lang = langClass ? langClass[1] : "";
|
|
20144
|
+
return `\`\`\`${lang}
|
|
20145
|
+
${codeContent.trim()}
|
|
20146
|
+
\`\`\`
|
|
20147
|
+
|
|
20148
|
+
`;
|
|
20149
|
+
}
|
|
20150
|
+
case "blockquote": {
|
|
20151
|
+
const inner = childContent().trim();
|
|
20152
|
+
return inner.split("\n").map((line) => `> ${line}`).join("\n") + "\n\n";
|
|
20153
|
+
}
|
|
20154
|
+
case "ul": {
|
|
20155
|
+
let result = "";
|
|
20156
|
+
el.childNodes.forEach((child) => {
|
|
20157
|
+
if (child.tagName?.toLowerCase() === "li") {
|
|
20158
|
+
const indent2 = " ".repeat(listDepth);
|
|
20159
|
+
const liContent = processListItem(child, listDepth);
|
|
20160
|
+
result += `${indent2}- ${liContent}
|
|
20161
|
+
`;
|
|
20162
|
+
}
|
|
20163
|
+
});
|
|
20164
|
+
return listDepth === 0 ? result + "\n" : result;
|
|
20165
|
+
}
|
|
20166
|
+
case "ol": {
|
|
20167
|
+
let result = "";
|
|
20168
|
+
let index = 1;
|
|
20169
|
+
el.childNodes.forEach((child) => {
|
|
20170
|
+
if (child.tagName?.toLowerCase() === "li") {
|
|
20171
|
+
const indent2 = " ".repeat(listDepth);
|
|
20172
|
+
const liContent = processListItem(child, listDepth);
|
|
20173
|
+
result += `${indent2}${index}. ${liContent}
|
|
20174
|
+
`;
|
|
20175
|
+
index++;
|
|
20176
|
+
}
|
|
20177
|
+
});
|
|
20178
|
+
return listDepth === 0 ? result + "\n" : result;
|
|
20179
|
+
}
|
|
20180
|
+
case "li": {
|
|
20181
|
+
return childContent();
|
|
20182
|
+
}
|
|
20183
|
+
case "a": {
|
|
20184
|
+
const href = el.getAttribute("href") || "";
|
|
20185
|
+
const text3 = childContent();
|
|
20186
|
+
return `[${text3}](${href})`;
|
|
20187
|
+
}
|
|
20188
|
+
case "img": {
|
|
20189
|
+
const src = el.getAttribute("src") || "";
|
|
20190
|
+
const alt = el.getAttribute("alt") || "";
|
|
20191
|
+
return ``;
|
|
20192
|
+
}
|
|
20193
|
+
case "hr":
|
|
20194
|
+
return "---\n\n";
|
|
20195
|
+
case "table": {
|
|
20196
|
+
return processTable(el) + "\n";
|
|
20197
|
+
}
|
|
20198
|
+
case "input": {
|
|
20199
|
+
if (el.getAttribute("type") === "checkbox") {
|
|
20200
|
+
return el.hasAttribute("checked") ? "[x] " : "[ ] ";
|
|
20201
|
+
}
|
|
20202
|
+
return "";
|
|
20203
|
+
}
|
|
20204
|
+
case "div":
|
|
20205
|
+
case "span":
|
|
20206
|
+
case "section":
|
|
20207
|
+
case "article":
|
|
20208
|
+
case "main":
|
|
20209
|
+
case "header":
|
|
20210
|
+
case "footer":
|
|
20211
|
+
return childContent();
|
|
20212
|
+
default:
|
|
20213
|
+
return childContent();
|
|
20214
|
+
}
|
|
20215
|
+
}
|
|
20216
|
+
function processListItem(li, depth, _ordered) {
|
|
20217
|
+
let textParts = [];
|
|
20218
|
+
let subLists = "";
|
|
20219
|
+
li.childNodes.forEach((child) => {
|
|
20220
|
+
const childTag = child.tagName?.toLowerCase();
|
|
20221
|
+
if (childTag === "ul" || childTag === "ol") {
|
|
20222
|
+
subLists += processNode(child, depth + 1);
|
|
20223
|
+
} else {
|
|
20224
|
+
textParts.push(processNode(child, depth));
|
|
20225
|
+
}
|
|
20226
|
+
});
|
|
20227
|
+
let result = textParts.join("").trim();
|
|
20228
|
+
if (subLists) {
|
|
20229
|
+
result += "\n" + subLists;
|
|
20230
|
+
}
|
|
20231
|
+
return result;
|
|
20232
|
+
}
|
|
20233
|
+
function processTable(table) {
|
|
20234
|
+
const rows = [];
|
|
20235
|
+
table.querySelectorAll("tr").forEach((tr) => {
|
|
20236
|
+
const cells = [];
|
|
20237
|
+
tr.querySelectorAll("th, td").forEach((cell) => {
|
|
20238
|
+
cells.push((cell.textContent || "").trim());
|
|
20239
|
+
});
|
|
20240
|
+
rows.push(cells);
|
|
20241
|
+
});
|
|
20242
|
+
if (rows.length === 0) return "";
|
|
20243
|
+
const colCount = Math.max(...rows.map((r3) => r3.length));
|
|
20244
|
+
const colWidths = Array(colCount).fill(3);
|
|
20245
|
+
rows.forEach((row) => {
|
|
20246
|
+
row.forEach((cell, i) => {
|
|
20247
|
+
colWidths[i] = Math.max(colWidths[i], cell.length);
|
|
20248
|
+
});
|
|
20249
|
+
});
|
|
20250
|
+
let result = "";
|
|
20251
|
+
rows.forEach((row, rowIndex) => {
|
|
20252
|
+
const paddedCells = Array(colCount).fill("").map((_, i) => {
|
|
20253
|
+
const cell = row[i] || "";
|
|
20254
|
+
return cell.padEnd(colWidths[i]);
|
|
20255
|
+
});
|
|
20256
|
+
result += `| ${paddedCells.join(" | ")} |
|
|
20257
|
+
`;
|
|
20258
|
+
if (rowIndex === 0) {
|
|
20259
|
+
const separators = colWidths.map((w) => "-".repeat(w));
|
|
20260
|
+
result += `| ${separators.join(" | ")} |
|
|
20261
|
+
`;
|
|
20262
|
+
}
|
|
20263
|
+
});
|
|
20264
|
+
return result;
|
|
20265
|
+
}
|
|
20266
|
+
element.childNodes.forEach((child) => {
|
|
20267
|
+
lines.push(processNode(child));
|
|
20268
|
+
});
|
|
20269
|
+
return lines.join("").replace(/\n{3,}/g, "\n\n").trim() + "\n";
|
|
20270
|
+
}
|
|
20271
|
+
var MarkdownEditor = memo(function MarkdownEditor2({
|
|
20272
|
+
content,
|
|
20273
|
+
onChange,
|
|
20274
|
+
config
|
|
20275
|
+
}) {
|
|
20276
|
+
const editorRef = useRef(null);
|
|
20277
|
+
const textareaRef = useRef(null);
|
|
20278
|
+
const [isSourceMode, setIsSourceMode] = useState(false);
|
|
20279
|
+
const isInternalUpdate = useRef(false);
|
|
20280
|
+
const lastMarkdownRef = useRef(content);
|
|
20281
|
+
const contentToHtml = useCallback((markdown) => {
|
|
20282
|
+
return marked.parse(markdown, { breaks: true, gfm: true });
|
|
20283
|
+
}, []);
|
|
20284
|
+
useEffect(() => {
|
|
20285
|
+
if (isSourceMode) return;
|
|
20286
|
+
if (isInternalUpdate.current) {
|
|
20287
|
+
isInternalUpdate.current = false;
|
|
20288
|
+
return;
|
|
20289
|
+
}
|
|
20290
|
+
if (editorRef.current && content !== lastMarkdownRef.current) {
|
|
20291
|
+
const html2 = contentToHtml(content);
|
|
20292
|
+
editorRef.current.innerHTML = html2;
|
|
20293
|
+
lastMarkdownRef.current = content;
|
|
20294
|
+
}
|
|
20295
|
+
}, [content, isSourceMode, contentToHtml]);
|
|
20296
|
+
useEffect(() => {
|
|
20297
|
+
if (editorRef.current && !isSourceMode) {
|
|
20298
|
+
const html2 = contentToHtml(content);
|
|
20299
|
+
editorRef.current.innerHTML = html2;
|
|
20300
|
+
}
|
|
20301
|
+
}, []);
|
|
20302
|
+
const handleInput = useCallback(() => {
|
|
20303
|
+
if (!editorRef.current) return;
|
|
20304
|
+
const markdown = htmlToMarkdown(editorRef.current);
|
|
20305
|
+
lastMarkdownRef.current = markdown;
|
|
20306
|
+
isInternalUpdate.current = true;
|
|
20307
|
+
onChange(markdown);
|
|
20308
|
+
}, [onChange]);
|
|
20309
|
+
const execCommand = useCallback((command, value) => {
|
|
20310
|
+
editorRef.current?.focus();
|
|
20311
|
+
document.execCommand(command, false, value);
|
|
20312
|
+
requestAnimationFrame(() => handleInput());
|
|
20313
|
+
}, [handleInput]);
|
|
20314
|
+
const formatBlock = useCallback((tag) => {
|
|
20315
|
+
execCommand("formatBlock", tag);
|
|
20316
|
+
}, [execCommand]);
|
|
20317
|
+
const insertHorizontalRule = useCallback(() => {
|
|
20318
|
+
execCommand("insertHorizontalRule");
|
|
20319
|
+
}, [execCommand]);
|
|
20320
|
+
const insertLink = useCallback(() => {
|
|
20321
|
+
const selection = window.getSelection();
|
|
20322
|
+
const selectedText = selection?.toString() || "\u94FE\u63A5\u6587\u672C";
|
|
20323
|
+
const url = prompt("\u8BF7\u8F93\u5165\u94FE\u63A5\u5730\u5740:", "https://");
|
|
20324
|
+
if (url) {
|
|
20325
|
+
if (selection && selection.rangeCount > 0) {
|
|
20326
|
+
const range = selection.getRangeAt(0);
|
|
20327
|
+
range.deleteContents();
|
|
20328
|
+
const anchor = document.createElement("a");
|
|
20329
|
+
anchor.href = url;
|
|
20330
|
+
anchor.textContent = selectedText;
|
|
20331
|
+
range.insertNode(anchor);
|
|
20332
|
+
range.setStartAfter(anchor);
|
|
20333
|
+
range.collapse(true);
|
|
20334
|
+
selection.removeAllRanges();
|
|
20335
|
+
selection.addRange(range);
|
|
20336
|
+
}
|
|
20337
|
+
requestAnimationFrame(() => handleInput());
|
|
20338
|
+
}
|
|
20339
|
+
}, [handleInput]);
|
|
20340
|
+
const insertImage = useCallback(() => {
|
|
20341
|
+
const url = prompt("\u8BF7\u8F93\u5165\u56FE\u7247\u5730\u5740:", "https://");
|
|
20342
|
+
if (url) {
|
|
20343
|
+
execCommand("insertImage", url);
|
|
20344
|
+
}
|
|
20345
|
+
}, [execCommand]);
|
|
20346
|
+
const insertCodeBlock = useCallback(() => {
|
|
20347
|
+
const editor = editorRef.current;
|
|
20348
|
+
if (!editor) return;
|
|
20349
|
+
const selection = window.getSelection();
|
|
20350
|
+
if (selection && selection.rangeCount > 0) {
|
|
20351
|
+
const range = selection.getRangeAt(0);
|
|
20352
|
+
const pre = document.createElement("pre");
|
|
20353
|
+
const code3 = document.createElement("code");
|
|
20354
|
+
code3.textContent = selection.toString() || "\u4EE3\u7801\u5185\u5BB9";
|
|
20355
|
+
pre.appendChild(code3);
|
|
20356
|
+
range.deleteContents();
|
|
20357
|
+
range.insertNode(pre);
|
|
20358
|
+
const paragraph2 = document.createElement("p");
|
|
20359
|
+
paragraph2.innerHTML = "<br>";
|
|
20360
|
+
pre.parentNode?.insertBefore(paragraph2, pre.nextSibling);
|
|
20361
|
+
range.setStart(paragraph2, 0);
|
|
20362
|
+
range.collapse(true);
|
|
20363
|
+
selection.removeAllRanges();
|
|
20364
|
+
selection.addRange(range);
|
|
20365
|
+
}
|
|
20366
|
+
requestAnimationFrame(() => handleInput());
|
|
20367
|
+
}, [handleInput]);
|
|
20368
|
+
const handleKeyDown = useCallback((e) => {
|
|
20369
|
+
const isMod = e.metaKey || e.ctrlKey;
|
|
20370
|
+
if (isMod && e.key === "b") {
|
|
20371
|
+
e.preventDefault();
|
|
20372
|
+
execCommand("bold");
|
|
20373
|
+
} else if (isMod && e.key === "i") {
|
|
20374
|
+
e.preventDefault();
|
|
20375
|
+
execCommand("italic");
|
|
20376
|
+
} else if (isMod && e.key === "u") {
|
|
20377
|
+
e.preventDefault();
|
|
20378
|
+
execCommand("underline");
|
|
20379
|
+
} else if (isMod && e.key === "e") {
|
|
20380
|
+
e.preventDefault();
|
|
20381
|
+
const selection = window.getSelection();
|
|
20382
|
+
if (selection && selection.rangeCount > 0) {
|
|
20383
|
+
const selectedText = selection.toString() || "code";
|
|
20384
|
+
execCommand("insertHTML", `<code>${selectedText}</code>`);
|
|
20385
|
+
}
|
|
20386
|
+
} else if (e.key === "Tab") {
|
|
20387
|
+
e.preventDefault();
|
|
20388
|
+
execCommand("insertHTML", " ");
|
|
20389
|
+
}
|
|
20390
|
+
}, [execCommand]);
|
|
20391
|
+
const handleSourceKeyDown = useCallback((e) => {
|
|
20392
|
+
if (e.key === "Tab") {
|
|
20393
|
+
e.preventDefault();
|
|
20394
|
+
const textarea = e.currentTarget;
|
|
20395
|
+
const start = textarea.selectionStart;
|
|
20396
|
+
const end = textarea.selectionEnd;
|
|
20397
|
+
const newValue = content.substring(0, start) + " " + content.substring(end);
|
|
20398
|
+
onChange(newValue);
|
|
20399
|
+
requestAnimationFrame(() => {
|
|
20400
|
+
textarea.selectionStart = textarea.selectionEnd = start + 2;
|
|
20401
|
+
});
|
|
20402
|
+
}
|
|
20403
|
+
}, [content, onChange]);
|
|
20404
|
+
const toggleSourceMode = useCallback(() => {
|
|
20405
|
+
if (isSourceMode) {
|
|
20406
|
+
setIsSourceMode(false);
|
|
20407
|
+
requestAnimationFrame(() => {
|
|
20408
|
+
if (editorRef.current) {
|
|
20409
|
+
const html2 = contentToHtml(content);
|
|
20410
|
+
editorRef.current.innerHTML = html2;
|
|
20411
|
+
lastMarkdownRef.current = content;
|
|
20412
|
+
}
|
|
20413
|
+
});
|
|
20414
|
+
} else {
|
|
20415
|
+
if (editorRef.current) {
|
|
20416
|
+
const markdown = htmlToMarkdown(editorRef.current);
|
|
20417
|
+
lastMarkdownRef.current = markdown;
|
|
20418
|
+
isInternalUpdate.current = true;
|
|
20419
|
+
onChange(markdown);
|
|
20420
|
+
}
|
|
20421
|
+
setIsSourceMode(true);
|
|
20422
|
+
}
|
|
20423
|
+
}, [isSourceMode, content, contentToHtml, onChange]);
|
|
20424
|
+
const toolbarGroups = useMemo(() => [
|
|
20425
|
+
{
|
|
20426
|
+
items: [
|
|
20427
|
+
{ icon: /* @__PURE__ */ jsx("span", { className: "font-bold text-[11px]", children: "B" }), label: "\u52A0\u7C97 (\u2318B)", onClick: () => execCommand("bold") },
|
|
20428
|
+
{ icon: /* @__PURE__ */ jsx("span", { className: "italic text-[11px]", children: "I" }), label: "\u659C\u4F53 (\u2318I)", onClick: () => execCommand("italic") },
|
|
20429
|
+
{ icon: /* @__PURE__ */ jsx("span", { className: "line-through text-[11px]", children: "S" }), label: "\u5220\u9664\u7EBF", onClick: () => execCommand("strikeThrough") },
|
|
20430
|
+
{ icon: /* @__PURE__ */ jsx(Code2, { size: 13 }), label: "\u884C\u5185\u4EE3\u7801 (\u2318E)", onClick: () => {
|
|
20431
|
+
const selection = window.getSelection();
|
|
20432
|
+
const text3 = selection?.toString() || "code";
|
|
20433
|
+
execCommand("insertHTML", `<code>${text3}</code>`);
|
|
20434
|
+
} }
|
|
20435
|
+
]
|
|
20436
|
+
},
|
|
20437
|
+
{
|
|
20438
|
+
items: [
|
|
20439
|
+
{ icon: /* @__PURE__ */ jsx("span", { className: "text-[11px] font-bold", children: "H1" }), label: "\u4E00\u7EA7\u6807\u9898", onClick: () => formatBlock("h1") },
|
|
20440
|
+
{ icon: /* @__PURE__ */ jsx("span", { className: "text-[11px] font-bold", children: "H2" }), label: "\u4E8C\u7EA7\u6807\u9898", onClick: () => formatBlock("h2") },
|
|
20441
|
+
{ icon: /* @__PURE__ */ jsx("span", { className: "text-[11px] font-bold", children: "H3" }), label: "\u4E09\u7EA7\u6807\u9898", onClick: () => formatBlock("h3") }
|
|
20442
|
+
]
|
|
20443
|
+
},
|
|
20444
|
+
{
|
|
20445
|
+
items: [
|
|
20446
|
+
{ icon: /* @__PURE__ */ jsx("span", { className: "text-[11px]", children: "\u2022" }), label: "\u65E0\u5E8F\u5217\u8868", onClick: () => execCommand("insertUnorderedList") },
|
|
20447
|
+
{ icon: /* @__PURE__ */ jsx("span", { className: "text-[11px]", children: "1." }), label: "\u6709\u5E8F\u5217\u8868", onClick: () => execCommand("insertOrderedList") },
|
|
20448
|
+
{ icon: /* @__PURE__ */ jsx("span", { className: "text-[11px]", children: "\u275D" }), label: "\u5F15\u7528", onClick: () => formatBlock("blockquote") }
|
|
20449
|
+
]
|
|
20450
|
+
},
|
|
20451
|
+
{
|
|
20452
|
+
items: [
|
|
20453
|
+
{ icon: /* @__PURE__ */ jsx("span", { className: "text-[11px]", children: "\u2014" }), label: "\u5206\u5272\u7EBF", onClick: insertHorizontalRule },
|
|
20454
|
+
{ icon: /* @__PURE__ */ jsx(Globe, { size: 13 }), label: "\u94FE\u63A5", onClick: insertLink },
|
|
20455
|
+
{ icon: /* @__PURE__ */ jsx(FileImage, { size: 13 }), label: "\u56FE\u7247", onClick: insertImage },
|
|
20456
|
+
{ icon: /* @__PURE__ */ jsx(Code2, { size: 13, className: "opacity-60" }), label: "\u4EE3\u7801\u5757", onClick: insertCodeBlock }
|
|
20457
|
+
]
|
|
20458
|
+
}
|
|
20459
|
+
], [execCommand, formatBlock, insertHorizontalRule, insertLink, insertImage, insertCodeBlock]);
|
|
20460
|
+
return /* @__PURE__ */ jsxs("div", { className: "h-full flex flex-col bg-zinc-950 agent-sdk-light:bg-white", children: [
|
|
20461
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-0.5 px-3 py-1.5 border-b border-zinc-800/50 agent-sdk-light:border-zinc-200 bg-zinc-900/50 agent-sdk-light:bg-zinc-50 flex-shrink-0 overflow-x-auto", style: { scrollbarWidth: "none" }, children: [
|
|
20462
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 mr-2", children: [
|
|
20463
|
+
/* @__PURE__ */ jsx(Pencil, { size: 12, className: "text-[#d8ff00]" }),
|
|
20464
|
+
/* @__PURE__ */ jsx("span", { className: "text-[11px] text-[#d8ff00] font-medium whitespace-nowrap", children: isSourceMode ? "Markdown \u6E90\u7801" : "\u5BCC\u6587\u672C\u7F16\u8F91" })
|
|
20465
|
+
] }),
|
|
20466
|
+
/* @__PURE__ */ jsx("div", { className: "h-4 w-px bg-zinc-700/50 agent-sdk-light:bg-zinc-300 mx-1" }),
|
|
20467
|
+
!isSourceMode && toolbarGroups.map((group, groupIndex) => /* @__PURE__ */ jsxs(React20__default.Fragment, { children: [
|
|
20468
|
+
group.items.map((action, actionIndex) => /* @__PURE__ */ jsx(
|
|
20469
|
+
"button",
|
|
20470
|
+
{
|
|
20471
|
+
onClick: action.onClick,
|
|
20472
|
+
className: "p-1.5 min-w-[28px] h-7 flex items-center justify-center text-zinc-400 agent-sdk-light:text-zinc-600 hover:text-zinc-100 agent-sdk-light:hover:text-zinc-900 hover:bg-zinc-700/50 agent-sdk-light:hover:bg-zinc-200 rounded transition-colors",
|
|
20473
|
+
title: action.label,
|
|
20474
|
+
children: action.icon
|
|
20475
|
+
},
|
|
20476
|
+
actionIndex
|
|
20477
|
+
)),
|
|
20478
|
+
groupIndex < toolbarGroups.length - 1 && /* @__PURE__ */ jsx("div", { className: "h-4 w-px bg-zinc-700/50 agent-sdk-light:bg-zinc-300 mx-0.5" })
|
|
20479
|
+
] }, groupIndex)),
|
|
20480
|
+
/* @__PURE__ */ jsx("div", { className: "h-4 w-px bg-zinc-700/50 agent-sdk-light:bg-zinc-300 mx-1 ml-auto" }),
|
|
20481
|
+
/* @__PURE__ */ jsxs(
|
|
20482
|
+
"button",
|
|
20483
|
+
{
|
|
20484
|
+
onClick: toggleSourceMode,
|
|
20485
|
+
className: cn2(
|
|
20486
|
+
"p-1.5 flex items-center gap-1 text-[11px] rounded transition-colors whitespace-nowrap",
|
|
20487
|
+
isSourceMode ? "bg-[#d8ff00]/10 text-[#d8ff00]" : "text-zinc-400 agent-sdk-light:text-zinc-600 hover:text-zinc-100 agent-sdk-light:hover:text-zinc-900 hover:bg-zinc-700/50 agent-sdk-light:hover:bg-zinc-200"
|
|
20488
|
+
),
|
|
20489
|
+
title: isSourceMode ? "\u5207\u6362\u5230\u5BCC\u6587\u672C\u6A21\u5F0F" : "\u5207\u6362\u5230\u6E90\u7801\u6A21\u5F0F",
|
|
20490
|
+
children: [
|
|
20491
|
+
isSourceMode ? /* @__PURE__ */ jsx(Eye, { size: 13 }) : /* @__PURE__ */ jsx(Code2, { size: 13 }),
|
|
20492
|
+
/* @__PURE__ */ jsx("span", { className: "hidden sm:inline", children: isSourceMode ? "\u5BCC\u6587\u672C" : "\u6E90\u7801" })
|
|
20493
|
+
]
|
|
20494
|
+
}
|
|
20495
|
+
)
|
|
20496
|
+
] }),
|
|
20497
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1 min-h-0 overflow-hidden", children: isSourceMode ? (
|
|
20498
|
+
/* 源码编辑模式 */
|
|
20499
|
+
/* @__PURE__ */ jsx(
|
|
20500
|
+
"textarea",
|
|
20501
|
+
{
|
|
20502
|
+
ref: textareaRef,
|
|
20503
|
+
value: content,
|
|
20504
|
+
onChange: (e) => onChange(e.target.value),
|
|
20505
|
+
onKeyDown: handleSourceKeyDown,
|
|
20506
|
+
className: "w-full h-full p-5 bg-zinc-950 agent-sdk-light:bg-white text-sm text-zinc-300 agent-sdk-light:text-zinc-800 leading-[1.8] resize-none focus:outline-none",
|
|
20507
|
+
style: { fontFamily: '"SF Mono", "Fira Code", "JetBrains Mono", Menlo, Monaco, monospace' },
|
|
20508
|
+
spellCheck: false,
|
|
20509
|
+
autoComplete: "off",
|
|
20510
|
+
autoCorrect: "off",
|
|
20511
|
+
autoCapitalize: "off",
|
|
20512
|
+
placeholder: "\u7F16\u5199 Markdown \u6E90\u7801..."
|
|
20513
|
+
}
|
|
20514
|
+
)
|
|
20515
|
+
) : (
|
|
20516
|
+
/* WYSIWYG 富文本编辑模式 */
|
|
20517
|
+
/* @__PURE__ */ jsx(
|
|
20518
|
+
"div",
|
|
20519
|
+
{
|
|
20520
|
+
ref: editorRef,
|
|
20521
|
+
contentEditable: true,
|
|
20522
|
+
suppressContentEditableWarning: true,
|
|
20523
|
+
onInput: handleInput,
|
|
20524
|
+
onKeyDown: handleKeyDown,
|
|
20525
|
+
className: "w-full h-full p-5 overflow-auto bg-zinc-950 agent-sdk-light:bg-white text-sm text-zinc-300 agent-sdk-light:text-zinc-800 leading-[1.8] focus:outline-none prose prose-invert prose-zinc agent-sdk-light:prose prose-sm max-w-none\n [&_h1]:text-2xl [&_h1]:font-bold [&_h1]:text-zinc-100 [&_h1]:agent-sdk-light:text-zinc-900 [&_h1]:mb-4 [&_h1]:mt-6 [&_h1]:border-b [&_h1]:border-zinc-800/30 [&_h1]:agent-sdk-light:border-zinc-200 [&_h1]:pb-2\n [&_h2]:text-xl [&_h2]:font-bold [&_h2]:text-zinc-200 [&_h2]:agent-sdk-light:text-zinc-800 [&_h2]:mb-3 [&_h2]:mt-5\n [&_h3]:text-lg [&_h3]:font-semibold [&_h3]:text-zinc-200 [&_h3]:agent-sdk-light:text-zinc-800 [&_h3]:mb-2 [&_h3]:mt-4\n [&_p]:mb-3 [&_p]:leading-relaxed\n [&_strong]:text-zinc-100 [&_strong]:agent-sdk-light:text-zinc-900 [&_strong]:font-semibold\n [&_em]:text-zinc-300 [&_em]:agent-sdk-light:text-zinc-700\n [&_code]:bg-zinc-800/60 [&_code]:agent-sdk-light:bg-zinc-100 [&_code]:text-[#d8ff00] [&_code]:agent-sdk-light:text-pink-600 [&_code]:px-1.5 [&_code]:py-0.5 [&_code]:rounded [&_code]:text-[13px] [&_code]:font-mono\n [&_pre]:bg-zinc-900/80 [&_pre]:agent-sdk-light:bg-zinc-50 [&_pre]:border [&_pre]:border-zinc-800/50 [&_pre]:agent-sdk-light:border-zinc-200 [&_pre]:rounded-lg [&_pre]:p-4 [&_pre]:my-3 [&_pre]:overflow-x-auto\n [&_pre_code]:bg-transparent [&_pre_code]:p-0 [&_pre_code]:text-zinc-300 [&_pre_code]:agent-sdk-light:text-zinc-800\n [&_blockquote]:border-l-3 [&_blockquote]:border-[#d8ff00]/40 [&_blockquote]:pl-4 [&_blockquote]:my-3 [&_blockquote]:text-zinc-400 [&_blockquote]:agent-sdk-light:text-zinc-600 [&_blockquote]:italic\n [&_ul]:list-disc [&_ul]:pl-6 [&_ul]:my-2\n [&_ol]:list-decimal [&_ol]:pl-6 [&_ol]:my-2\n [&_li]:mb-1\n [&_a]:text-[#d8ff00] [&_a]:agent-sdk-light:text-blue-600 [&_a]:underline [&_a]:underline-offset-2\n [&_hr]:border-zinc-700/50 [&_hr]:agent-sdk-light:border-zinc-300 [&_hr]:my-6\n [&_img]:max-w-full [&_img]:rounded-lg [&_img]:my-3\n [&_table]:w-full [&_table]:border-collapse [&_table]:my-3\n [&_th]:border [&_th]:border-zinc-700/50 [&_th]:agent-sdk-light:border-zinc-300 [&_th]:px-3 [&_th]:py-2 [&_th]:bg-zinc-800/30 [&_th]:agent-sdk-light:bg-zinc-100 [&_th]:text-left [&_th]:font-medium\n [&_td]:border [&_td]:border-zinc-700/50 [&_td]:agent-sdk-light:border-zinc-300 [&_td]:px-3 [&_td]:py-2",
|
|
20526
|
+
"data-placeholder": "\u5F00\u59CB\u7F16\u5199\u5185\u5BB9..."
|
|
20527
|
+
}
|
|
20528
|
+
)
|
|
20529
|
+
) })
|
|
20530
|
+
] });
|
|
20531
|
+
});
|
|
20532
|
+
var ArtifactThumbnail = memo(function ArtifactThumbnail2({
|
|
20533
|
+
artifact,
|
|
20534
|
+
config
|
|
20535
|
+
}) {
|
|
20536
|
+
const typeConf = artifactTypeConfig[artifact.type] || artifactTypeConfig.text;
|
|
20537
|
+
const TypeIcon = typeConf.icon;
|
|
20538
|
+
const isMedia = artifact.type === "image" || artifact.type === "video";
|
|
20539
|
+
const thumbnailUrl = useResolvedThumbnailUrl(
|
|
20540
|
+
artifact.currentContent,
|
|
20541
|
+
{
|
|
20542
|
+
fileId: artifact.metadata?.fileId,
|
|
20543
|
+
type: artifact.type,
|
|
20544
|
+
config,
|
|
20545
|
+
enabled: isMedia
|
|
20546
|
+
}
|
|
20547
|
+
);
|
|
20548
|
+
if (isMedia && thumbnailUrl) {
|
|
20549
|
+
return /* @__PURE__ */ jsx(
|
|
20550
|
+
"img",
|
|
20551
|
+
{
|
|
20552
|
+
src: thumbnailUrl,
|
|
20553
|
+
alt: "",
|
|
20554
|
+
className: "w-6 h-6 rounded object-cover flex-shrink-0",
|
|
20555
|
+
loading: "lazy"
|
|
20556
|
+
}
|
|
20557
|
+
);
|
|
20558
|
+
}
|
|
20559
|
+
return /* @__PURE__ */ jsx("div", { className: cn2("w-6 h-6 rounded flex items-center justify-center flex-shrink-0", typeConf.bgColor), children: /* @__PURE__ */ jsx(TypeIcon, { size: 12, className: typeConf.color }) });
|
|
20560
|
+
});
|
|
20561
|
+
var ArtifactTabs = memo(function ArtifactTabs2({
|
|
20562
|
+
artifacts,
|
|
20563
|
+
activeId,
|
|
20564
|
+
onSwitch,
|
|
20565
|
+
onClose,
|
|
20566
|
+
onReorder,
|
|
20567
|
+
config
|
|
20568
|
+
}) {
|
|
20569
|
+
const scrollContainerRef = useRef(null);
|
|
20570
|
+
const [canScrollLeft, setCanScrollLeft] = useState(false);
|
|
20571
|
+
const [canScrollRight, setCanScrollRight] = useState(false);
|
|
20572
|
+
const [showAllPanel, setShowAllPanel] = useState(false);
|
|
20573
|
+
const allPanelRef = useRef(null);
|
|
20574
|
+
const [dragState, setDragState] = useState({ draggingId: null, dragOverId: null, dragStartX: 0, isDragging: false });
|
|
20575
|
+
const checkScrollState = useCallback(() => {
|
|
20576
|
+
const container = scrollContainerRef.current;
|
|
20577
|
+
if (!container) return;
|
|
20578
|
+
setCanScrollLeft(container.scrollLeft > 2);
|
|
20579
|
+
setCanScrollRight(container.scrollLeft < container.scrollWidth - container.clientWidth - 2);
|
|
20580
|
+
}, []);
|
|
20581
|
+
useEffect(() => {
|
|
20582
|
+
checkScrollState();
|
|
20583
|
+
const container = scrollContainerRef.current;
|
|
20584
|
+
if (!container) return;
|
|
20585
|
+
container.addEventListener("scroll", checkScrollState, { passive: true });
|
|
20586
|
+
const resizeObserver = new ResizeObserver(checkScrollState);
|
|
20587
|
+
resizeObserver.observe(container);
|
|
20588
|
+
return () => {
|
|
20589
|
+
container.removeEventListener("scroll", checkScrollState);
|
|
20590
|
+
resizeObserver.disconnect();
|
|
20591
|
+
};
|
|
20592
|
+
}, [checkScrollState, artifacts.length]);
|
|
20593
|
+
useEffect(() => {
|
|
20594
|
+
if (!showAllPanel) return;
|
|
20595
|
+
const handleClickOutside = (e) => {
|
|
20596
|
+
if (allPanelRef.current && !allPanelRef.current.contains(e.target)) {
|
|
20597
|
+
setShowAllPanel(false);
|
|
20598
|
+
}
|
|
20599
|
+
};
|
|
20600
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
20601
|
+
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
20602
|
+
}, [showAllPanel]);
|
|
20603
|
+
const scrollBy = useCallback((direction) => {
|
|
20604
|
+
const container = scrollContainerRef.current;
|
|
20605
|
+
if (!container) return;
|
|
20606
|
+
const scrollAmount = 200;
|
|
20607
|
+
container.scrollBy({
|
|
20608
|
+
left: direction === "left" ? -scrollAmount : scrollAmount,
|
|
20609
|
+
behavior: "smooth"
|
|
20610
|
+
});
|
|
20611
|
+
}, []);
|
|
20612
|
+
const handleDragStart = useCallback((e, artifactId) => {
|
|
20613
|
+
e.dataTransfer.effectAllowed = "move";
|
|
20614
|
+
e.dataTransfer.setData("text/plain", artifactId);
|
|
20615
|
+
setDragState((prev) => ({ ...prev, draggingId: artifactId, dragStartX: e.clientX, isDragging: true }));
|
|
20616
|
+
}, []);
|
|
20617
|
+
const handleDragOver = useCallback((e, artifactId) => {
|
|
20618
|
+
e.preventDefault();
|
|
20619
|
+
e.dataTransfer.dropEffect = "move";
|
|
20620
|
+
setDragState((prev) => ({ ...prev, dragOverId: artifactId }));
|
|
20621
|
+
}, []);
|
|
20622
|
+
const handleDragEnd = useCallback(() => {
|
|
20623
|
+
setDragState({ draggingId: null, dragOverId: null, dragStartX: 0, isDragging: false });
|
|
20624
|
+
}, []);
|
|
20625
|
+
const handleDrop = useCallback((e, targetId) => {
|
|
20626
|
+
e.preventDefault();
|
|
20627
|
+
const sourceId = e.dataTransfer.getData("text/plain");
|
|
20628
|
+
if (!sourceId || sourceId === targetId || !onReorder) {
|
|
20629
|
+
handleDragEnd();
|
|
20630
|
+
return;
|
|
20631
|
+
}
|
|
20632
|
+
const fromIndex = artifacts.findIndex((a) => a.id === sourceId);
|
|
20633
|
+
const toIndex = artifacts.findIndex((a) => a.id === targetId);
|
|
20634
|
+
if (fromIndex !== -1 && toIndex !== -1 && fromIndex !== toIndex) {
|
|
20635
|
+
onReorder(fromIndex, toIndex);
|
|
20636
|
+
}
|
|
20637
|
+
handleDragEnd();
|
|
20638
|
+
}, [artifacts, onReorder, handleDragEnd]);
|
|
20639
|
+
const handleCloseTab = useCallback((e, artifactId) => {
|
|
20640
|
+
e.stopPropagation();
|
|
20641
|
+
if (!onClose) return;
|
|
20642
|
+
if (artifactId === activeId && artifacts.length > 1) {
|
|
20643
|
+
const currentIndex = artifacts.findIndex((a) => a.id === artifactId);
|
|
20644
|
+
const nextIndex = currentIndex < artifacts.length - 1 ? currentIndex + 1 : currentIndex - 1;
|
|
20645
|
+
if (nextIndex >= 0 && nextIndex < artifacts.length) {
|
|
20646
|
+
onSwitch(artifacts[nextIndex].id);
|
|
20647
|
+
}
|
|
20648
|
+
}
|
|
20649
|
+
onClose(artifactId);
|
|
20650
|
+
}, [onClose, activeId, artifacts, onSwitch]);
|
|
20651
|
+
if (artifacts.length <= 1) return null;
|
|
20652
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex items-center border-b border-zinc-800/50 agent-sdk-light:border-zinc-200 bg-zinc-950/50 agent-sdk-light:bg-zinc-100 flex-shrink-0 relative", children: [
|
|
20653
|
+
canScrollLeft && /* @__PURE__ */ jsx(
|
|
20654
|
+
"button",
|
|
20655
|
+
{
|
|
20656
|
+
onClick: () => scrollBy("left"),
|
|
20657
|
+
className: "flex-shrink-0 p-1 text-zinc-500 hover:text-zinc-300 hover:bg-zinc-800/50 transition-colors z-10",
|
|
20658
|
+
children: /* @__PURE__ */ jsx(ChevronLeft, { size: 14 })
|
|
20659
|
+
}
|
|
20660
|
+
),
|
|
20661
|
+
/* @__PURE__ */ jsx(
|
|
20662
|
+
"div",
|
|
20663
|
+
{
|
|
20664
|
+
ref: scrollContainerRef,
|
|
20665
|
+
className: "flex items-center gap-0.5 px-1 py-1 overflow-x-auto flex-1 min-w-0",
|
|
20666
|
+
style: { scrollbarWidth: "none", msOverflowStyle: "none" },
|
|
20667
|
+
children: artifacts.map((artifact) => {
|
|
20668
|
+
const typeConf = artifactTypeConfig[artifact.type] || artifactTypeConfig.text;
|
|
20669
|
+
const isActive = artifact.id === activeId;
|
|
20670
|
+
const isDragging = dragState.draggingId === artifact.id;
|
|
20671
|
+
const isDragOver = dragState.dragOverId === artifact.id && dragState.draggingId !== artifact.id;
|
|
20672
|
+
const TypeIcon = typeConf.icon;
|
|
20673
|
+
return /* @__PURE__ */ jsxs(
|
|
20674
|
+
"div",
|
|
20675
|
+
{
|
|
20676
|
+
draggable: !!onReorder,
|
|
20677
|
+
onDragStart: (e) => handleDragStart(e, artifact.id),
|
|
20678
|
+
onDragOver: (e) => handleDragOver(e, artifact.id),
|
|
20679
|
+
onDragEnd: handleDragEnd,
|
|
20680
|
+
onDrop: (e) => handleDrop(e, artifact.id),
|
|
20681
|
+
onClick: () => onSwitch(artifact.id),
|
|
20682
|
+
className: cn2(
|
|
20683
|
+
"group/tab flex items-center gap-1 pl-2.5 pr-1 py-1 text-xs rounded-md transition-all whitespace-nowrap flex-shrink-0 cursor-pointer select-none",
|
|
20684
|
+
isActive ? "bg-zinc-800 text-zinc-100 agent-sdk-light:bg-zinc-200 agent-sdk-light:text-zinc-900" : "text-zinc-500 agent-sdk-light:text-zinc-600 hover:text-zinc-300 agent-sdk-light:hover:text-zinc-900 hover:bg-zinc-800/50 agent-sdk-light:hover:bg-zinc-200/50",
|
|
20685
|
+
isDragging && "opacity-40",
|
|
20686
|
+
isDragOver && "ring-1 ring-[#d8ff00]/50",
|
|
20687
|
+
onReorder && "cursor-grab active:cursor-grabbing"
|
|
20688
|
+
),
|
|
20689
|
+
title: artifact.title,
|
|
20690
|
+
children: [
|
|
20691
|
+
/* @__PURE__ */ jsx(TypeIcon, { size: 12, className: cn2("flex-shrink-0", isActive ? typeConf.color : "") }),
|
|
20692
|
+
/* @__PURE__ */ jsx("span", { className: "max-w-[120px] truncate", children: artifact.title }),
|
|
20693
|
+
onClose && /* @__PURE__ */ jsx(
|
|
20694
|
+
"button",
|
|
20695
|
+
{
|
|
20696
|
+
onClick: (e) => handleCloseTab(e, artifact.id),
|
|
20697
|
+
className: cn2(
|
|
20698
|
+
"ml-0.5 p-0.5 rounded transition-colors flex-shrink-0",
|
|
20699
|
+
isActive ? "text-zinc-400 hover:text-zinc-100 hover:bg-zinc-700" : "text-transparent group-hover/tab:text-zinc-500 hover:!text-zinc-300 hover:!bg-zinc-700"
|
|
20700
|
+
),
|
|
20701
|
+
title: "\u5173\u95ED",
|
|
20702
|
+
children: /* @__PURE__ */ jsx(X, { size: 10 })
|
|
20703
|
+
}
|
|
20704
|
+
)
|
|
20705
|
+
]
|
|
20706
|
+
},
|
|
20707
|
+
artifact.id
|
|
20708
|
+
);
|
|
20709
|
+
})
|
|
20710
|
+
}
|
|
20711
|
+
),
|
|
20712
|
+
canScrollRight && /* @__PURE__ */ jsx(
|
|
20713
|
+
"button",
|
|
20714
|
+
{
|
|
20715
|
+
onClick: () => scrollBy("right"),
|
|
20716
|
+
className: "flex-shrink-0 p-1 text-zinc-500 hover:text-zinc-300 hover:bg-zinc-800/50 transition-colors z-10",
|
|
20717
|
+
children: /* @__PURE__ */ jsx(ChevronRight, { size: 14 })
|
|
20718
|
+
}
|
|
20719
|
+
),
|
|
20720
|
+
artifacts.length > 0 && /* @__PURE__ */ jsxs("div", { className: "relative flex-shrink-0", ref: allPanelRef, children: [
|
|
20721
|
+
/* @__PURE__ */ jsx(
|
|
20722
|
+
"button",
|
|
20723
|
+
{
|
|
20724
|
+
onClick: () => setShowAllPanel((prev) => !prev),
|
|
20725
|
+
className: cn2(
|
|
20726
|
+
"p-1.5 mr-1 text-zinc-500 hover:text-zinc-300 hover:bg-zinc-800/50 rounded transition-colors",
|
|
20727
|
+
showAllPanel && "bg-zinc-800 text-zinc-300"
|
|
20728
|
+
),
|
|
20729
|
+
title: "\u5168\u90E8\u4EA7\u7269",
|
|
20730
|
+
children: /* @__PURE__ */ jsx(LayoutGrid, { size: 14 })
|
|
20731
|
+
}
|
|
20732
|
+
),
|
|
20733
|
+
showAllPanel && /* @__PURE__ */ jsxs("div", { className: "absolute right-0 top-full mt-1 z-50 w-72 max-h-80 overflow-y-auto bg-zinc-900 agent-sdk-light:bg-white border border-zinc-700 agent-sdk-light:border-zinc-300 rounded-lg shadow-xl", children: [
|
|
20734
|
+
/* @__PURE__ */ jsx("div", { className: "px-3 py-2 border-b border-zinc-800 agent-sdk-light:border-zinc-200", children: /* @__PURE__ */ jsxs("span", { className: "text-xs font-medium text-zinc-400 agent-sdk-light:text-zinc-600", children: [
|
|
20735
|
+
"\u5168\u90E8\u4EA7\u7269 (",
|
|
20736
|
+
artifacts.length,
|
|
20737
|
+
")"
|
|
20738
|
+
] }) }),
|
|
20739
|
+
/* @__PURE__ */ jsx("div", { className: "p-1.5 grid grid-cols-1 gap-0.5", children: artifacts.map((artifact) => {
|
|
20740
|
+
const typeConf = artifactTypeConfig[artifact.type] || artifactTypeConfig.text;
|
|
20741
|
+
const isActive = artifact.id === activeId;
|
|
20742
|
+
typeConf.icon;
|
|
20743
|
+
return /* @__PURE__ */ jsxs(
|
|
20744
|
+
"button",
|
|
20745
|
+
{
|
|
20746
|
+
onClick: () => {
|
|
20747
|
+
onSwitch(artifact.id);
|
|
20748
|
+
setShowAllPanel(false);
|
|
20749
|
+
},
|
|
20750
|
+
className: cn2(
|
|
20751
|
+
"flex items-center gap-2.5 px-2.5 py-2 text-xs rounded-md transition-all w-full text-left",
|
|
20752
|
+
isActive ? "bg-zinc-800 text-zinc-100 agent-sdk-light:bg-zinc-100 agent-sdk-light:text-zinc-900" : "text-zinc-400 agent-sdk-light:text-zinc-600 hover:text-zinc-200 agent-sdk-light:hover:text-zinc-900 hover:bg-zinc-800/50 agent-sdk-light:hover:bg-zinc-100"
|
|
20753
|
+
),
|
|
20754
|
+
children: [
|
|
20755
|
+
/* @__PURE__ */ jsx(ArtifactThumbnail, { artifact, config }),
|
|
20756
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
20757
|
+
/* @__PURE__ */ jsx("div", { className: "truncate font-medium", children: artifact.title }),
|
|
20758
|
+
/* @__PURE__ */ jsxs("div", { className: "text-[10px] text-zinc-600 agent-sdk-light:text-zinc-500 mt-0.5", children: [
|
|
20759
|
+
typeConf.label,
|
|
20760
|
+
artifact.language && artifact.language !== artifact.type && ` \u2022 ${artifact.language}`
|
|
20761
|
+
] })
|
|
20762
|
+
] }),
|
|
20763
|
+
onClose && /* @__PURE__ */ jsx(
|
|
20764
|
+
"button",
|
|
20765
|
+
{
|
|
20766
|
+
onClick: (e) => {
|
|
20767
|
+
e.stopPropagation();
|
|
20768
|
+
handleCloseTab(e, artifact.id);
|
|
20769
|
+
},
|
|
20770
|
+
className: "p-1 text-zinc-600 hover:text-zinc-300 hover:bg-zinc-700 rounded transition-colors flex-shrink-0",
|
|
20771
|
+
title: "\u5173\u95ED",
|
|
20772
|
+
children: /* @__PURE__ */ jsx(X, { size: 12 })
|
|
20773
|
+
}
|
|
20774
|
+
)
|
|
20775
|
+
]
|
|
20776
|
+
},
|
|
20777
|
+
artifact.id
|
|
20778
|
+
);
|
|
20779
|
+
}) })
|
|
20780
|
+
] })
|
|
20781
|
+
] })
|
|
20782
|
+
] });
|
|
20783
|
+
});
|
|
18793
20784
|
var ArtifactViewer = memo(function ArtifactViewer2({
|
|
18794
20785
|
artifact,
|
|
18795
20786
|
isOpen,
|
|
@@ -18798,41 +20789,127 @@ var ArtifactViewer = memo(function ArtifactViewer2({
|
|
|
18798
20789
|
defaultView = "preview",
|
|
18799
20790
|
isFullscreen,
|
|
18800
20791
|
onFullscreenToggle,
|
|
18801
|
-
embedded = false
|
|
20792
|
+
embedded = false,
|
|
20793
|
+
artifacts = [],
|
|
20794
|
+
activeArtifactId,
|
|
20795
|
+
onSwitchArtifact,
|
|
20796
|
+
onCloseArtifact,
|
|
20797
|
+
onReorderArtifacts,
|
|
20798
|
+
onContentChange,
|
|
20799
|
+
onSave
|
|
18802
20800
|
}) {
|
|
18803
20801
|
const [viewMode, setViewMode] = useState(defaultView);
|
|
20802
|
+
const [isEditing, setIsEditing] = useState(false);
|
|
20803
|
+
const [editContent, setEditContent] = useState("");
|
|
20804
|
+
const [undoStack, setUndoStack] = useState([]);
|
|
20805
|
+
const [redoStack, setRedoStack] = useState([]);
|
|
18804
20806
|
useEffect(() => {
|
|
18805
20807
|
if (artifact) {
|
|
18806
|
-
if (artifact.type === "html" || artifact.type === "markdown") {
|
|
20808
|
+
if (artifact.type === "html" || artifact.type === "markdown" || artifact.type === "svg") {
|
|
18807
20809
|
setViewMode("preview");
|
|
18808
20810
|
} else {
|
|
18809
20811
|
setViewMode("code");
|
|
18810
20812
|
}
|
|
20813
|
+
setIsEditing(false);
|
|
20814
|
+
setEditContent(artifact.content);
|
|
20815
|
+
setUndoStack([]);
|
|
20816
|
+
setRedoStack([]);
|
|
18811
20817
|
}
|
|
18812
20818
|
}, [artifact?.id]);
|
|
20819
|
+
useEffect(() => {
|
|
20820
|
+
if (artifact && !isEditing) {
|
|
20821
|
+
setEditContent(artifact.content);
|
|
20822
|
+
}
|
|
20823
|
+
}, [artifact?.content, isEditing]);
|
|
18813
20824
|
if (!artifact) return null;
|
|
18814
|
-
const typeConfig = artifactTypeConfig[artifact.type];
|
|
18815
|
-
const canPreview = artifact.type === "html" || artifact.type === "markdown";
|
|
20825
|
+
const typeConfig = artifactTypeConfig[artifact.type] || artifactTypeConfig.text;
|
|
20826
|
+
const canPreview = artifact.type === "html" || artifact.type === "markdown" || artifact.type === "svg";
|
|
20827
|
+
const canEdit = artifact.type !== "image" && artifact.type !== "video";
|
|
20828
|
+
const handleStartEdit = () => {
|
|
20829
|
+
setEditContent(artifact.content);
|
|
20830
|
+
setUndoStack([artifact.content]);
|
|
20831
|
+
setRedoStack([]);
|
|
20832
|
+
setIsEditing(true);
|
|
20833
|
+
setViewMode("code");
|
|
20834
|
+
};
|
|
20835
|
+
const handleEditChange = (newContent) => {
|
|
20836
|
+
setUndoStack((prev) => [...prev, editContent]);
|
|
20837
|
+
setRedoStack([]);
|
|
20838
|
+
setEditContent(newContent);
|
|
20839
|
+
onContentChange?.(newContent);
|
|
20840
|
+
};
|
|
20841
|
+
const handleUndo = () => {
|
|
20842
|
+
if (undoStack.length === 0) return;
|
|
20843
|
+
const previous2 = undoStack[undoStack.length - 1];
|
|
20844
|
+
setUndoStack((prev) => prev.slice(0, -1));
|
|
20845
|
+
setRedoStack((prev) => [...prev, editContent]);
|
|
20846
|
+
setEditContent(previous2);
|
|
20847
|
+
onContentChange?.(previous2);
|
|
20848
|
+
};
|
|
20849
|
+
const handleRedo = () => {
|
|
20850
|
+
if (redoStack.length === 0) return;
|
|
20851
|
+
const next = redoStack[redoStack.length - 1];
|
|
20852
|
+
setRedoStack((prev) => prev.slice(0, -1));
|
|
20853
|
+
setUndoStack((prev) => [...prev, editContent]);
|
|
20854
|
+
setEditContent(next);
|
|
20855
|
+
onContentChange?.(next);
|
|
20856
|
+
};
|
|
20857
|
+
const handleSave = () => {
|
|
20858
|
+
onSave?.(artifact.id, editContent);
|
|
20859
|
+
setIsEditing(false);
|
|
20860
|
+
};
|
|
20861
|
+
const handleCancelEdit = () => {
|
|
20862
|
+
setEditContent(artifact.content);
|
|
20863
|
+
setIsEditing(false);
|
|
20864
|
+
};
|
|
20865
|
+
const displayContent = isEditing ? editContent : artifact.content;
|
|
18816
20866
|
const renderContent = () => {
|
|
20867
|
+
if (isEditing) {
|
|
20868
|
+
if (artifact.type === "markdown") {
|
|
20869
|
+
return /* @__PURE__ */ jsx(
|
|
20870
|
+
MarkdownEditor,
|
|
20871
|
+
{
|
|
20872
|
+
content: editContent,
|
|
20873
|
+
onChange: handleEditChange,
|
|
20874
|
+
config
|
|
20875
|
+
}
|
|
20876
|
+
);
|
|
20877
|
+
}
|
|
20878
|
+
return /* @__PURE__ */ jsx(
|
|
20879
|
+
CodeEditor,
|
|
20880
|
+
{
|
|
20881
|
+
code: editContent,
|
|
20882
|
+
language: artifact.language || artifact.type,
|
|
20883
|
+
onChange: handleEditChange
|
|
20884
|
+
}
|
|
20885
|
+
);
|
|
20886
|
+
}
|
|
20887
|
+
if (artifact.type === "image") {
|
|
20888
|
+
return /* @__PURE__ */ jsx(ImageArtifactPreview, { content: displayContent, metadata: artifact.metadata, config });
|
|
20889
|
+
}
|
|
20890
|
+
if (artifact.type === "video") {
|
|
20891
|
+
return /* @__PURE__ */ jsx(VideoArtifactPreview, { content: displayContent, metadata: artifact.metadata, config });
|
|
20892
|
+
}
|
|
18817
20893
|
if (viewMode === "code" || !canPreview) {
|
|
18818
20894
|
return /* @__PURE__ */ jsx(
|
|
18819
20895
|
CodeBlock3,
|
|
18820
20896
|
{
|
|
18821
|
-
code:
|
|
20897
|
+
code: displayContent,
|
|
18822
20898
|
language: artifact.language || artifact.type
|
|
18823
20899
|
}
|
|
18824
20900
|
);
|
|
18825
20901
|
}
|
|
18826
20902
|
switch (artifact.type) {
|
|
18827
20903
|
case "html":
|
|
18828
|
-
|
|
20904
|
+
case "svg":
|
|
20905
|
+
return /* @__PURE__ */ jsx(HtmlPreview3, { content: displayContent });
|
|
18829
20906
|
case "markdown":
|
|
18830
|
-
return /* @__PURE__ */ jsx(MarkdownPreview, { content:
|
|
20907
|
+
return /* @__PURE__ */ jsx(MarkdownPreview, { content: displayContent, config });
|
|
18831
20908
|
default:
|
|
18832
20909
|
return /* @__PURE__ */ jsx(
|
|
18833
20910
|
CodeBlock3,
|
|
18834
20911
|
{
|
|
18835
|
-
code:
|
|
20912
|
+
code: displayContent,
|
|
18836
20913
|
language: artifact.language || artifact.type
|
|
18837
20914
|
}
|
|
18838
20915
|
);
|
|
@@ -18855,26 +20932,79 @@ var ArtifactViewer = memo(function ArtifactViewer2({
|
|
|
18855
20932
|
] })
|
|
18856
20933
|
] }),
|
|
18857
20934
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
18858
|
-
|
|
18859
|
-
|
|
18860
|
-
|
|
18861
|
-
|
|
18862
|
-
|
|
18863
|
-
|
|
18864
|
-
|
|
18865
|
-
|
|
18866
|
-
|
|
18867
|
-
|
|
18868
|
-
|
|
18869
|
-
|
|
18870
|
-
|
|
18871
|
-
|
|
18872
|
-
|
|
18873
|
-
|
|
18874
|
-
|
|
18875
|
-
|
|
18876
|
-
|
|
18877
|
-
|
|
20935
|
+
isEditing ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
20936
|
+
/* @__PURE__ */ jsx(
|
|
20937
|
+
"button",
|
|
20938
|
+
{
|
|
20939
|
+
onClick: handleUndo,
|
|
20940
|
+
disabled: undoStack.length === 0,
|
|
20941
|
+
className: "p-1.5 text-zinc-500 hover:text-zinc-300 hover:bg-zinc-800 rounded-lg transition-colors disabled:opacity-30 disabled:cursor-not-allowed",
|
|
20942
|
+
title: "\u64A4\u9500",
|
|
20943
|
+
children: /* @__PURE__ */ jsx(Undo2, { size: 14 })
|
|
20944
|
+
}
|
|
20945
|
+
),
|
|
20946
|
+
/* @__PURE__ */ jsx(
|
|
20947
|
+
"button",
|
|
20948
|
+
{
|
|
20949
|
+
onClick: handleRedo,
|
|
20950
|
+
disabled: redoStack.length === 0,
|
|
20951
|
+
className: "p-1.5 text-zinc-500 hover:text-zinc-300 hover:bg-zinc-800 rounded-lg transition-colors disabled:opacity-30 disabled:cursor-not-allowed",
|
|
20952
|
+
title: "\u91CD\u505A",
|
|
20953
|
+
children: /* @__PURE__ */ jsx(Redo2, { size: 14 })
|
|
20954
|
+
}
|
|
20955
|
+
),
|
|
20956
|
+
/* @__PURE__ */ jsxs(
|
|
20957
|
+
"button",
|
|
20958
|
+
{
|
|
20959
|
+
onClick: handleSave,
|
|
20960
|
+
className: "flex items-center gap-1 px-2.5 py-1 text-xs bg-[#d8ff00] hover:bg-[#e5ff4d] text-black rounded-lg transition-colors font-medium",
|
|
20961
|
+
title: "\u4FDD\u5B58",
|
|
20962
|
+
children: [
|
|
20963
|
+
/* @__PURE__ */ jsx(Save, { size: 12 }),
|
|
20964
|
+
"\u4FDD\u5B58"
|
|
20965
|
+
]
|
|
20966
|
+
}
|
|
20967
|
+
),
|
|
20968
|
+
/* @__PURE__ */ jsx(
|
|
20969
|
+
"button",
|
|
20970
|
+
{
|
|
20971
|
+
onClick: handleCancelEdit,
|
|
20972
|
+
className: "px-2.5 py-1 text-xs text-zinc-400 hover:text-zinc-200 hover:bg-zinc-800 rounded-lg transition-colors",
|
|
20973
|
+
title: "\u53D6\u6D88\u7F16\u8F91",
|
|
20974
|
+
children: "\u53D6\u6D88"
|
|
20975
|
+
}
|
|
20976
|
+
)
|
|
20977
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
20978
|
+
canEdit && onContentChange && /* @__PURE__ */ jsx(
|
|
20979
|
+
"button",
|
|
20980
|
+
{
|
|
20981
|
+
onClick: handleStartEdit,
|
|
20982
|
+
className: "p-1.5 text-zinc-500 agent-sdk-light:text-zinc-600 hover:text-zinc-300 agent-sdk-light:hover:text-zinc-900 hover:bg-zinc-800 agent-sdk-light:hover:bg-zinc-200 rounded-lg transition-colors",
|
|
20983
|
+
title: "\u7F16\u8F91",
|
|
20984
|
+
children: /* @__PURE__ */ jsx(Pencil, { size: 14 })
|
|
20985
|
+
}
|
|
20986
|
+
),
|
|
20987
|
+
onFullscreenToggle && /* @__PURE__ */ jsx(
|
|
20988
|
+
"button",
|
|
20989
|
+
{
|
|
20990
|
+
onClick: onFullscreenToggle,
|
|
20991
|
+
className: "p-1.5 text-zinc-500 agent-sdk-light:text-zinc-600 hover:text-zinc-300 agent-sdk-light:hover:text-zinc-900 hover:bg-zinc-800 agent-sdk-light:hover:bg-zinc-200 rounded-lg transition-colors",
|
|
20992
|
+
title: isFullscreen ? "\u9000\u51FA\u5168\u5C4F" : "\u5168\u5C4F",
|
|
20993
|
+
children: isFullscreen ? /* @__PURE__ */ jsx(Minimize2, { size: 14 }) : /* @__PURE__ */ jsx(Maximize2, { size: 14 })
|
|
20994
|
+
}
|
|
20995
|
+
),
|
|
20996
|
+
canPreview && /* @__PURE__ */ jsx(
|
|
20997
|
+
ViewTabs,
|
|
20998
|
+
{
|
|
20999
|
+
activeView: viewMode,
|
|
21000
|
+
onViewChange: (v) => setViewMode(v),
|
|
21001
|
+
views: [
|
|
21002
|
+
{ id: "preview", label: "Preview", icon: /* @__PURE__ */ jsx(Eye, { size: 12 }) },
|
|
21003
|
+
{ id: "code", label: "Code", icon: /* @__PURE__ */ jsx(Code2, { size: 12 }) }
|
|
21004
|
+
]
|
|
21005
|
+
}
|
|
21006
|
+
)
|
|
21007
|
+
] }),
|
|
18878
21008
|
/* @__PURE__ */ jsx(
|
|
18879
21009
|
"button",
|
|
18880
21010
|
{
|
|
@@ -18889,6 +21019,16 @@ var ArtifactViewer = memo(function ArtifactViewer2({
|
|
|
18889
21019
|
)
|
|
18890
21020
|
] })
|
|
18891
21021
|
] }),
|
|
21022
|
+
onSwitchArtifact && /* @__PURE__ */ jsx(
|
|
21023
|
+
ArtifactTabs,
|
|
21024
|
+
{
|
|
21025
|
+
artifacts,
|
|
21026
|
+
activeId: activeArtifactId ?? artifact.id,
|
|
21027
|
+
onSwitch: onSwitchArtifact,
|
|
21028
|
+
onClose: onCloseArtifact,
|
|
21029
|
+
onReorder: onReorderArtifacts
|
|
21030
|
+
}
|
|
21031
|
+
),
|
|
18892
21032
|
/* @__PURE__ */ jsx("div", { className: "flex-1 overflow-hidden", children: renderContent() })
|
|
18893
21033
|
] });
|
|
18894
21034
|
}
|
|
@@ -18934,6 +21074,145 @@ var ArtifactViewer = memo(function ArtifactViewer2({
|
|
|
18934
21074
|
}
|
|
18935
21075
|
);
|
|
18936
21076
|
});
|
|
21077
|
+
|
|
21078
|
+
// src/utils/artifactExtractor.ts
|
|
21079
|
+
function getMediaTypeFromParamType(paramType) {
|
|
21080
|
+
const upper = paramType?.toUpperCase();
|
|
21081
|
+
if (upper === "IMAGE") return "image";
|
|
21082
|
+
if (upper === "VIDEO") return "video";
|
|
21083
|
+
return null;
|
|
21084
|
+
}
|
|
21085
|
+
function inferMediaTypeFromUrl(url) {
|
|
21086
|
+
if (!url) return null;
|
|
21087
|
+
const lower = url.toLowerCase();
|
|
21088
|
+
if (/\.(jpg|jpeg|png|gif|webp|svg|bmp)(\?|#|$)/.test(lower)) return "image";
|
|
21089
|
+
if (/\.(mp4|mov|webm|avi|mkv|m4v)(\?|#|$)/.test(lower)) return "video";
|
|
21090
|
+
if (/\.(jpg|jpeg|png|gif|webp)/.test(lower)) return "image";
|
|
21091
|
+
if (/\.(mp4|mov|webm)/.test(lower)) return "video";
|
|
21092
|
+
return null;
|
|
21093
|
+
}
|
|
21094
|
+
function extractArtifactsFromToolCall(toolCall, sessionId, messageId) {
|
|
21095
|
+
const artifacts = [];
|
|
21096
|
+
if (!toolCall || toolCall.status?.toLowerCase() !== "completed") return artifacts;
|
|
21097
|
+
const result = toolCall.result;
|
|
21098
|
+
if (!result) return artifacts;
|
|
21099
|
+
const toolName = result?.relation?.toolName || toolCall.name || "AI Tool";
|
|
21100
|
+
const args = toolCall.arguments || {};
|
|
21101
|
+
if (result.works && Array.isArray(result.works)) {
|
|
21102
|
+
result.works.forEach((work, index) => {
|
|
21103
|
+
const paramType = work.customResponse?.paramType;
|
|
21104
|
+
const fileId = work.fileId;
|
|
21105
|
+
const fileUrl = work.fileUrl || work.customResponse?.url;
|
|
21106
|
+
if (!fileId && !fileUrl) return;
|
|
21107
|
+
const mediaType = getMediaTypeFromParamType(paramType) || (fileUrl ? inferMediaTypeFromUrl(fileUrl) : null) || (fileId ? inferMediaTypeFromUrl(fileId) : null);
|
|
21108
|
+
if (!mediaType) return;
|
|
21109
|
+
const artifactId = work.publicId || `media-${toolCall.id}-${index}`;
|
|
21110
|
+
artifacts.push({
|
|
21111
|
+
id: artifactId,
|
|
21112
|
+
sessionId,
|
|
21113
|
+
type: mediaType,
|
|
21114
|
+
title: `${toolName} #${index + 1}`,
|
|
21115
|
+
// 优先存 fileId,resolveAssetForDisplay 会将其转换为可用 URL
|
|
21116
|
+
currentContent: fileId || fileUrl,
|
|
21117
|
+
version: 1,
|
|
21118
|
+
source: "tool",
|
|
21119
|
+
sourceId: toolCall.id,
|
|
21120
|
+
metadata: {
|
|
21121
|
+
toolName,
|
|
21122
|
+
generationParams: args,
|
|
21123
|
+
messageId,
|
|
21124
|
+
workflowCode: result.workflowCode,
|
|
21125
|
+
taskId: result.taskId,
|
|
21126
|
+
fileId: work.fileId,
|
|
21127
|
+
fileUrl: work.fileUrl
|
|
21128
|
+
},
|
|
21129
|
+
gmtCreate: (/* @__PURE__ */ new Date()).toISOString(),
|
|
21130
|
+
gmtModified: (/* @__PURE__ */ new Date()).toISOString()
|
|
21131
|
+
});
|
|
21132
|
+
});
|
|
21133
|
+
}
|
|
21134
|
+
if (artifacts.length === 0 && result.outputs?.images) {
|
|
21135
|
+
const imgUrl = typeof result.outputs.images === "string" ? result.outputs.images : null;
|
|
21136
|
+
if (imgUrl) {
|
|
21137
|
+
artifacts.push({
|
|
21138
|
+
id: `media-${toolCall.id}-output`,
|
|
21139
|
+
sessionId,
|
|
21140
|
+
type: "image",
|
|
21141
|
+
title: `${toolName}`,
|
|
21142
|
+
currentContent: imgUrl,
|
|
21143
|
+
version: 1,
|
|
21144
|
+
source: "tool",
|
|
21145
|
+
sourceId: toolCall.id,
|
|
21146
|
+
metadata: {
|
|
21147
|
+
toolName,
|
|
21148
|
+
generationParams: args,
|
|
21149
|
+
messageId
|
|
21150
|
+
},
|
|
21151
|
+
gmtCreate: (/* @__PURE__ */ new Date()).toISOString(),
|
|
21152
|
+
gmtModified: (/* @__PURE__ */ new Date()).toISOString()
|
|
21153
|
+
});
|
|
21154
|
+
}
|
|
21155
|
+
}
|
|
21156
|
+
if (result.works && Array.isArray(result.works)) {
|
|
21157
|
+
result.works.forEach((work, index) => {
|
|
21158
|
+
if (work.customResponse?.value) {
|
|
21159
|
+
const parsed = detectContentType(work.customResponse.value);
|
|
21160
|
+
if (parsed.content && parsed.type !== "text") {
|
|
21161
|
+
artifacts.push({
|
|
21162
|
+
id: `content-${toolCall.id}-${index}`,
|
|
21163
|
+
sessionId,
|
|
21164
|
+
type: parsed.type,
|
|
21165
|
+
title: parsed.title || `${toolName} - ${parsed.type.toUpperCase()}`,
|
|
21166
|
+
currentContent: parsed.content,
|
|
21167
|
+
language: parsed.language,
|
|
21168
|
+
version: 1,
|
|
21169
|
+
source: "tool",
|
|
21170
|
+
sourceId: toolCall.id,
|
|
21171
|
+
metadata: {
|
|
21172
|
+
toolName,
|
|
21173
|
+
messageId
|
|
21174
|
+
},
|
|
21175
|
+
gmtCreate: (/* @__PURE__ */ new Date()).toISOString(),
|
|
21176
|
+
gmtModified: (/* @__PURE__ */ new Date()).toISOString()
|
|
21177
|
+
});
|
|
21178
|
+
}
|
|
21179
|
+
}
|
|
21180
|
+
});
|
|
21181
|
+
}
|
|
21182
|
+
return artifacts;
|
|
21183
|
+
}
|
|
21184
|
+
function extractArtifactsFromMessages(messages, sessionId) {
|
|
21185
|
+
const allArtifacts = [];
|
|
21186
|
+
const seenIds = /* @__PURE__ */ new Set();
|
|
21187
|
+
for (const message of messages) {
|
|
21188
|
+
if (message.role !== "assistant") continue;
|
|
21189
|
+
const toolCalls = message.extraData?.tool_calls || [];
|
|
21190
|
+
for (const tc of toolCalls) {
|
|
21191
|
+
const extracted = extractArtifactsFromToolCall(tc, sessionId, message.messageId);
|
|
21192
|
+
for (const artifact of extracted) {
|
|
21193
|
+
if (!seenIds.has(artifact.id)) {
|
|
21194
|
+
seenIds.add(artifact.id);
|
|
21195
|
+
allArtifacts.push(artifact);
|
|
21196
|
+
}
|
|
21197
|
+
}
|
|
21198
|
+
}
|
|
21199
|
+
const thoughts = message.extraData?.thoughts || message.thoughts || [];
|
|
21200
|
+
for (const thought of thoughts) {
|
|
21201
|
+
if (thought.toolCalls) {
|
|
21202
|
+
for (const tc of thought.toolCalls) {
|
|
21203
|
+
const extracted = extractArtifactsFromToolCall(tc, sessionId, message.messageId);
|
|
21204
|
+
for (const artifact of extracted) {
|
|
21205
|
+
if (!seenIds.has(artifact.id)) {
|
|
21206
|
+
seenIds.add(artifact.id);
|
|
21207
|
+
allArtifacts.push(artifact);
|
|
21208
|
+
}
|
|
21209
|
+
}
|
|
21210
|
+
}
|
|
21211
|
+
}
|
|
21212
|
+
}
|
|
21213
|
+
}
|
|
21214
|
+
return allArtifacts;
|
|
21215
|
+
}
|
|
18937
21216
|
var Field = ({ label, value }) => /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-3 text-xs text-zinc-400", children: [
|
|
18938
21217
|
/* @__PURE__ */ jsx("span", { children: label }),
|
|
18939
21218
|
/* @__PURE__ */ jsx("span", { className: "text-zinc-200 truncate max-w-[60%]", children: value ?? "-" })
|
|
@@ -19265,7 +21544,9 @@ function ChatInputArea({
|
|
|
19265
21544
|
onSend,
|
|
19266
21545
|
onStop,
|
|
19267
21546
|
isStreaming,
|
|
19268
|
-
config
|
|
21547
|
+
config,
|
|
21548
|
+
activeArtifact,
|
|
21549
|
+
onDetachArtifact
|
|
19269
21550
|
}) {
|
|
19270
21551
|
const textareaRef = useRef(null);
|
|
19271
21552
|
const fileInputRef = useRef(null);
|
|
@@ -19346,6 +21627,20 @@ function ChatInputArea({
|
|
|
19346
21627
|
};
|
|
19347
21628
|
return /* @__PURE__ */ jsx("div", { className: "bg-zinc-950 px-4 py-4 flex-shrink-0", children: /* @__PURE__ */ jsxs("div", { className: "max-w-3xl mx-auto", children: [
|
|
19348
21629
|
/* @__PURE__ */ jsxs("div", { className: "relative bg-zinc-900 border border-zinc-800 rounded-2xl shadow-lg shadow-black/20 focus-within:border-zinc-700 focus-within:shadow-xl focus-within:shadow-black/30 transition-all duration-200", children: [
|
|
21630
|
+
activeArtifact && /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2 px-4 pt-3 pb-1", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 px-2.5 py-1 bg-zinc-800/80 rounded-lg text-xs", children: [
|
|
21631
|
+
/* @__PURE__ */ jsx(FileCode, { size: 12, className: "text-[#d8ff00] flex-shrink-0" }),
|
|
21632
|
+
/* @__PURE__ */ jsx("span", { className: "text-zinc-400", children: "\u5173\u8054\u4EA7\u7269\uFF1A" }),
|
|
21633
|
+
/* @__PURE__ */ jsx("span", { className: "text-zinc-200 font-medium max-w-[200px] truncate", children: activeArtifact.title }),
|
|
21634
|
+
onDetachArtifact && /* @__PURE__ */ jsx(
|
|
21635
|
+
"button",
|
|
21636
|
+
{
|
|
21637
|
+
onClick: onDetachArtifact,
|
|
21638
|
+
className: "p-0.5 text-zinc-500 hover:text-zinc-300 rounded transition-colors",
|
|
21639
|
+
title: "\u53D6\u6D88\u5173\u8054",
|
|
21640
|
+
children: /* @__PURE__ */ jsx(Unlink, { size: 10 })
|
|
21641
|
+
}
|
|
21642
|
+
)
|
|
21643
|
+
] }) }),
|
|
19349
21644
|
images.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-3 p-4 pb-2", children: images.map((img, i) => /* @__PURE__ */ jsxs("div", { className: "relative group", children: [
|
|
19350
21645
|
/* @__PURE__ */ jsx(
|
|
19351
21646
|
"img",
|
|
@@ -19510,6 +21805,188 @@ var DragHandle = React20__default.memo(function DragHandle2({
|
|
|
19510
21805
|
}
|
|
19511
21806
|
);
|
|
19512
21807
|
});
|
|
21808
|
+
var artifactTypeIconMap = {
|
|
21809
|
+
html: Globe,
|
|
21810
|
+
svg: Globe,
|
|
21811
|
+
markdown: FileText,
|
|
21812
|
+
json: FileJson,
|
|
21813
|
+
code: FileCode,
|
|
21814
|
+
text: FileText,
|
|
21815
|
+
image: FileImage,
|
|
21816
|
+
video: Video
|
|
21817
|
+
};
|
|
21818
|
+
var ArtifactBarItemThumbnail = memo(function ArtifactBarItemThumbnail2({
|
|
21819
|
+
artifact,
|
|
21820
|
+
config
|
|
21821
|
+
}) {
|
|
21822
|
+
const TypeIcon = artifactTypeIconMap[artifact.type] || FileText;
|
|
21823
|
+
const isMedia = artifact.type === "image" || artifact.type === "video";
|
|
21824
|
+
const thumbnailUrl = useResolvedThumbnailUrl(
|
|
21825
|
+
artifact.currentContent,
|
|
21826
|
+
{
|
|
21827
|
+
fileId: artifact.metadata?.fileId,
|
|
21828
|
+
type: artifact.type,
|
|
21829
|
+
config,
|
|
21830
|
+
enabled: isMedia
|
|
21831
|
+
}
|
|
21832
|
+
);
|
|
21833
|
+
if (isMedia && thumbnailUrl) {
|
|
21834
|
+
return /* @__PURE__ */ jsx(
|
|
21835
|
+
"img",
|
|
21836
|
+
{
|
|
21837
|
+
src: thumbnailUrl,
|
|
21838
|
+
alt: "",
|
|
21839
|
+
className: "w-10 h-10 rounded-lg object-cover flex-shrink-0 border border-zinc-700/50 agent-sdk-light:border-zinc-300",
|
|
21840
|
+
loading: "lazy"
|
|
21841
|
+
}
|
|
21842
|
+
);
|
|
21843
|
+
}
|
|
21844
|
+
return /* @__PURE__ */ jsx("div", { className: "w-10 h-10 rounded-lg bg-zinc-800/50 agent-sdk-light:bg-zinc-100 flex items-center justify-center flex-shrink-0 border border-zinc-700/30 agent-sdk-light:border-zinc-300", children: /* @__PURE__ */ jsx(TypeIcon, { size: 18, className: "text-zinc-400 agent-sdk-light:text-zinc-500" }) });
|
|
21845
|
+
});
|
|
21846
|
+
var ArtifactBarMiniThumbnail = memo(function ArtifactBarMiniThumbnail2({
|
|
21847
|
+
artifact,
|
|
21848
|
+
config
|
|
21849
|
+
}) {
|
|
21850
|
+
const TypeIcon = artifactTypeIconMap[artifact.type] || FileText;
|
|
21851
|
+
const isMedia = artifact.type === "image" || artifact.type === "video";
|
|
21852
|
+
const thumbnailUrl = useResolvedThumbnailUrl(
|
|
21853
|
+
artifact.currentContent,
|
|
21854
|
+
{
|
|
21855
|
+
fileId: artifact.metadata?.fileId,
|
|
21856
|
+
type: artifact.type,
|
|
21857
|
+
config,
|
|
21858
|
+
enabled: isMedia
|
|
21859
|
+
}
|
|
21860
|
+
);
|
|
21861
|
+
if (isMedia && thumbnailUrl) {
|
|
21862
|
+
return /* @__PURE__ */ jsx(
|
|
21863
|
+
"img",
|
|
21864
|
+
{
|
|
21865
|
+
src: thumbnailUrl,
|
|
21866
|
+
alt: "",
|
|
21867
|
+
className: "w-6 h-6 rounded border border-zinc-700 agent-sdk-light:border-zinc-300 object-cover",
|
|
21868
|
+
loading: "lazy"
|
|
21869
|
+
}
|
|
21870
|
+
);
|
|
21871
|
+
}
|
|
21872
|
+
return /* @__PURE__ */ jsx("div", { className: "w-6 h-6 rounded border border-zinc-700 agent-sdk-light:border-zinc-300 bg-zinc-800 agent-sdk-light:bg-zinc-200 flex items-center justify-center", children: /* @__PURE__ */ jsx(TypeIcon, { size: 10, className: "text-zinc-400" }) });
|
|
21873
|
+
});
|
|
21874
|
+
var ArtifactBar = React20__default.memo(function ArtifactBar2({
|
|
21875
|
+
artifacts,
|
|
21876
|
+
onOpenArtifact,
|
|
21877
|
+
config
|
|
21878
|
+
}) {
|
|
21879
|
+
const [expanded, setExpanded] = useState(false);
|
|
21880
|
+
const barRef = useRef(null);
|
|
21881
|
+
useEffect(() => {
|
|
21882
|
+
if (!expanded) return;
|
|
21883
|
+
const handleClickOutside = (e) => {
|
|
21884
|
+
if (barRef.current && !barRef.current.contains(e.target)) {
|
|
21885
|
+
setExpanded(false);
|
|
21886
|
+
}
|
|
21887
|
+
};
|
|
21888
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
21889
|
+
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
21890
|
+
}, [expanded]);
|
|
21891
|
+
if (artifacts.length === 0) return null;
|
|
21892
|
+
const imageCount = artifacts.filter((a) => a.type === "image").length;
|
|
21893
|
+
const codeCount = artifacts.filter((a) => ["code", "html", "svg", "json"].includes(a.type)).length;
|
|
21894
|
+
const docCount = artifacts.filter((a) => ["markdown", "text"].includes(a.type)).length;
|
|
21895
|
+
const videoCount = artifacts.filter((a) => a.type === "video").length;
|
|
21896
|
+
return /* @__PURE__ */ jsxs("div", { ref: barRef, className: "relative flex-shrink-0 mx-auto max-w-md", children: [
|
|
21897
|
+
expanded && /* @__PURE__ */ jsxs("div", { className: "absolute bottom-full left-0 right-0 mb-1 z-30 max-h-[50vh] overflow-y-auto bg-zinc-900/95 agent-sdk-light:bg-white/95 backdrop-blur-md border border-zinc-700/50 agent-sdk-light:border-zinc-300 rounded-xl shadow-2xl", children: [
|
|
21898
|
+
/* @__PURE__ */ jsxs("div", { className: "px-4 py-3 border-b border-zinc-800/50 agent-sdk-light:border-zinc-200 flex items-center justify-between", children: [
|
|
21899
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
21900
|
+
/* @__PURE__ */ jsx(LayoutGrid, { size: 14, className: "text-[#d8ff00]" }),
|
|
21901
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-medium text-zinc-200 agent-sdk-light:text-zinc-800", children: "\u5168\u90E8\u4EA7\u7269" }),
|
|
21902
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs text-zinc-500 bg-zinc-800/50 agent-sdk-light:bg-zinc-200 px-1.5 py-0.5 rounded-full", children: artifacts.length })
|
|
21903
|
+
] }),
|
|
21904
|
+
/* @__PURE__ */ jsx(
|
|
21905
|
+
"button",
|
|
21906
|
+
{
|
|
21907
|
+
onClick: () => setExpanded(false),
|
|
21908
|
+
className: "p-1 text-zinc-500 hover:text-zinc-300 agent-sdk-light:hover:text-zinc-700 rounded transition-colors",
|
|
21909
|
+
children: /* @__PURE__ */ jsx(ChevronDown, { size: 16 })
|
|
21910
|
+
}
|
|
21911
|
+
)
|
|
21912
|
+
] }),
|
|
21913
|
+
/* @__PURE__ */ jsx("div", { className: "p-2 grid grid-cols-1 gap-1", children: artifacts.map((artifact) => {
|
|
21914
|
+
return /* @__PURE__ */ jsxs(
|
|
21915
|
+
"button",
|
|
21916
|
+
{
|
|
21917
|
+
onClick: () => {
|
|
21918
|
+
onOpenArtifact(artifact.id);
|
|
21919
|
+
setExpanded(false);
|
|
21920
|
+
},
|
|
21921
|
+
className: "flex items-center gap-3 px-3 py-2.5 rounded-lg text-left w-full hover:bg-zinc-800/60 agent-sdk-light:hover:bg-zinc-100 transition-colors group",
|
|
21922
|
+
children: [
|
|
21923
|
+
/* @__PURE__ */ jsx(ArtifactBarItemThumbnail, { artifact, config }),
|
|
21924
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
21925
|
+
/* @__PURE__ */ jsx("div", { className: "text-sm text-zinc-200 agent-sdk-light:text-zinc-800 truncate font-medium group-hover:text-white agent-sdk-light:group-hover:text-zinc-900", children: artifact.title }),
|
|
21926
|
+
/* @__PURE__ */ jsxs("div", { className: "text-[11px] text-zinc-500 agent-sdk-light:text-zinc-500 mt-0.5", children: [
|
|
21927
|
+
artifact.type.toUpperCase(),
|
|
21928
|
+
artifact.language && artifact.language !== artifact.type && ` \u2022 ${artifact.language}`
|
|
21929
|
+
] })
|
|
21930
|
+
] })
|
|
21931
|
+
]
|
|
21932
|
+
},
|
|
21933
|
+
artifact.id
|
|
21934
|
+
);
|
|
21935
|
+
}) })
|
|
21936
|
+
] }),
|
|
21937
|
+
/* @__PURE__ */ jsx("div", { className: "px-3 py-2 border-t border-zinc-800/30 agent-sdk-light:border-zinc-200/50 bg-zinc-900/30 agent-sdk-light:bg-zinc-50/50", children: /* @__PURE__ */ jsxs(
|
|
21938
|
+
"button",
|
|
21939
|
+
{
|
|
21940
|
+
onClick: () => setExpanded((prev) => !prev),
|
|
21941
|
+
className: "w-full flex items-center gap-2.5 px-3 py-2 rounded-lg bg-zinc-800/40 agent-sdk-light:bg-zinc-100 hover:bg-zinc-800/60 agent-sdk-light:hover:bg-zinc-200/80 border border-zinc-700/30 agent-sdk-light:border-zinc-300/50 transition-colors group",
|
|
21942
|
+
children: [
|
|
21943
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
21944
|
+
/* @__PURE__ */ jsx(Sparkles, { size: 14, className: "text-[#d8ff00]" }),
|
|
21945
|
+
/* @__PURE__ */ jsxs("span", { className: "text-xs font-medium text-zinc-300 agent-sdk-light:text-zinc-700", children: [
|
|
21946
|
+
artifacts.length,
|
|
21947
|
+
" \u4E2A\u4EA7\u7269"
|
|
21948
|
+
] })
|
|
21949
|
+
] }),
|
|
21950
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 flex-1 min-w-0", children: [
|
|
21951
|
+
imageCount > 0 && /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1 text-[10px] text-zinc-500 bg-zinc-700/30 agent-sdk-light:bg-zinc-200 px-1.5 py-0.5 rounded", children: [
|
|
21952
|
+
/* @__PURE__ */ jsx(FileImage, { size: 10 }),
|
|
21953
|
+
" ",
|
|
21954
|
+
imageCount
|
|
21955
|
+
] }),
|
|
21956
|
+
codeCount > 0 && /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1 text-[10px] text-zinc-500 bg-zinc-700/30 agent-sdk-light:bg-zinc-200 px-1.5 py-0.5 rounded", children: [
|
|
21957
|
+
/* @__PURE__ */ jsx(FileCode, { size: 10 }),
|
|
21958
|
+
" ",
|
|
21959
|
+
codeCount
|
|
21960
|
+
] }),
|
|
21961
|
+
docCount > 0 && /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1 text-[10px] text-zinc-500 bg-zinc-700/30 agent-sdk-light:bg-zinc-200 px-1.5 py-0.5 rounded", children: [
|
|
21962
|
+
/* @__PURE__ */ jsx(FileText, { size: 10 }),
|
|
21963
|
+
" ",
|
|
21964
|
+
docCount
|
|
21965
|
+
] }),
|
|
21966
|
+
videoCount > 0 && /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1 text-[10px] text-zinc-500 bg-zinc-700/30 agent-sdk-light:bg-zinc-200 px-1.5 py-0.5 rounded", children: [
|
|
21967
|
+
/* @__PURE__ */ jsx(Video, { size: 10 }),
|
|
21968
|
+
" ",
|
|
21969
|
+
videoCount
|
|
21970
|
+
] })
|
|
21971
|
+
] }),
|
|
21972
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center -space-x-1.5", children: [
|
|
21973
|
+
artifacts.slice(0, 4).map((artifact) => {
|
|
21974
|
+
return /* @__PURE__ */ jsx(ArtifactBarMiniThumbnail, { artifact, config }, artifact.id);
|
|
21975
|
+
}),
|
|
21976
|
+
artifacts.length > 4 && /* @__PURE__ */ jsx("div", { className: "w-6 h-6 rounded border border-zinc-700 agent-sdk-light:border-zinc-300 bg-zinc-800 agent-sdk-light:bg-zinc-200 flex items-center justify-center", children: /* @__PURE__ */ jsxs("span", { className: "text-[9px] text-zinc-400", children: [
|
|
21977
|
+
"+",
|
|
21978
|
+
artifacts.length - 4
|
|
21979
|
+
] }) })
|
|
21980
|
+
] }),
|
|
21981
|
+
/* @__PURE__ */ jsx(ChevronUp, { size: 14, className: cn2(
|
|
21982
|
+
"text-zinc-500 transition-transform flex-shrink-0",
|
|
21983
|
+
expanded && "rotate-180"
|
|
21984
|
+
) })
|
|
21985
|
+
]
|
|
21986
|
+
}
|
|
21987
|
+
) })
|
|
21988
|
+
] });
|
|
21989
|
+
});
|
|
19513
21990
|
var AgentChat = React20__default.forwardRef(({
|
|
19514
21991
|
agentId,
|
|
19515
21992
|
projectId,
|
|
@@ -19552,7 +22029,7 @@ var AgentChat = React20__default.forwardRef(({
|
|
|
19552
22029
|
ComponentRegistry: mergedRegistry
|
|
19553
22030
|
};
|
|
19554
22031
|
}, [config?.components, outerComponents]);
|
|
19555
|
-
const { sessions, setSessions, currentSession, setCurrentSession, addSession, removeSession, tools: _tools, setTools, setSkills, setShowItemTime } = useAgentStore();
|
|
22032
|
+
const { sessions, setSessions, currentSession, setCurrentSession, addSession, removeSession, tools: _tools, setTools, setSkills, setShowItemTime, artifacts, artifactOrder, activeArtifactId, upsertArtifact, updateArtifactContent, setActiveArtifact, removeArtifact, clearArtifacts, setArtifacts, reorderArtifacts } = useAgentStore();
|
|
19556
22033
|
const [loading, setLoading] = useState(true);
|
|
19557
22034
|
const [messagesLoading, setMessagesLoading] = useState(false);
|
|
19558
22035
|
const [collapsed, setCollapsed] = useState(false);
|
|
@@ -19564,7 +22041,23 @@ var AgentChat = React20__default.forwardRef(({
|
|
|
19564
22041
|
const lastUserMessageRef = useRef("");
|
|
19565
22042
|
const [shareModalOpen, setShareModalOpen] = useState(false);
|
|
19566
22043
|
const [shareSession, setShareSession] = useState(null);
|
|
19567
|
-
const
|
|
22044
|
+
const artifactList = useMemo(() => {
|
|
22045
|
+
const ordered = artifactOrder.map((id) => artifacts[id]).filter(Boolean);
|
|
22046
|
+
const unordered = Object.values(artifacts).filter(
|
|
22047
|
+
(a) => !artifactOrder.includes(a.id)
|
|
22048
|
+
);
|
|
22049
|
+
return [...ordered, ...unordered];
|
|
22050
|
+
}, [artifacts, artifactOrder]);
|
|
22051
|
+
const activeArtifact = activeArtifactId ? artifacts[activeArtifactId] ?? null : null;
|
|
22052
|
+
const currentArtifact = activeArtifact ? {
|
|
22053
|
+
id: activeArtifact.id,
|
|
22054
|
+
type: activeArtifact.type,
|
|
22055
|
+
title: activeArtifact.title,
|
|
22056
|
+
content: activeArtifact.currentContent,
|
|
22057
|
+
language: activeArtifact.language,
|
|
22058
|
+
source: activeArtifact.sourceId,
|
|
22059
|
+
metadata: activeArtifact.metadata
|
|
22060
|
+
} : null;
|
|
19568
22061
|
const [isArtifactFullscreen, setIsArtifactFullscreen] = useState(false);
|
|
19569
22062
|
const [artifactPanelWidth, setArtifactPanelWidth] = useState(50);
|
|
19570
22063
|
const [isDragging, setIsDragging] = useState(false);
|
|
@@ -19590,7 +22083,11 @@ var AgentChat = React20__default.forwardRef(({
|
|
|
19590
22083
|
const deltaX = dragStartRef.current.startX - e.clientX;
|
|
19591
22084
|
const deltaPercent = deltaX / containerWidth * 100;
|
|
19592
22085
|
const newWidth = dragStartRef.current.startWidth + deltaPercent;
|
|
19593
|
-
const
|
|
22086
|
+
const minChatPx = 350;
|
|
22087
|
+
const minArtifactPx = 400;
|
|
22088
|
+
const maxArtifactPercent = (containerWidth - minChatPx) / containerWidth * 100;
|
|
22089
|
+
const minArtifactPercent = minArtifactPx / containerWidth * 100;
|
|
22090
|
+
const clampedWidth = Math.max(minArtifactPercent, Math.min(maxArtifactPercent, newWidth));
|
|
19594
22091
|
setArtifactPanelWidth(clampedWidth);
|
|
19595
22092
|
};
|
|
19596
22093
|
const handleMouseUp = () => {
|
|
@@ -19612,38 +22109,52 @@ var AgentChat = React20__default.forwardRef(({
|
|
|
19612
22109
|
setShowItemTime(showItemTime);
|
|
19613
22110
|
}, [showItemTime]);
|
|
19614
22111
|
const handleOpenArtifact = useCallback((data) => {
|
|
19615
|
-
if (
|
|
19616
|
-
|
|
22112
|
+
if (activeArtifact && activeArtifact.currentContent === data.content && activeArtifact.type === data.type) {
|
|
22113
|
+
setActiveArtifact(null);
|
|
19617
22114
|
setIsArtifactFullscreen(false);
|
|
19618
22115
|
return;
|
|
19619
22116
|
}
|
|
19620
|
-
const
|
|
19621
|
-
|
|
19622
|
-
|
|
19623
|
-
|
|
19624
|
-
|
|
19625
|
-
|
|
19626
|
-
|
|
19627
|
-
|
|
19628
|
-
|
|
19629
|
-
|
|
22117
|
+
const existingArtifact = Object.values(artifacts).find(
|
|
22118
|
+
(a) => a.currentContent === data.content && a.type === data.type
|
|
22119
|
+
);
|
|
22120
|
+
if (existingArtifact) {
|
|
22121
|
+
setActiveArtifact(existingArtifact.id);
|
|
22122
|
+
} else {
|
|
22123
|
+
const sessionId = currentSession?.sessionId || "";
|
|
22124
|
+
const newArtifactEntry = {
|
|
22125
|
+
id: `artifact-${Date.now()}`,
|
|
22126
|
+
sessionId,
|
|
22127
|
+
type: data.type,
|
|
22128
|
+
title: data.title,
|
|
22129
|
+
currentContent: data.content,
|
|
22130
|
+
language: data.language,
|
|
22131
|
+
metadata: data.metadata,
|
|
22132
|
+
version: 1,
|
|
22133
|
+
source: "llm",
|
|
22134
|
+
gmtCreate: (/* @__PURE__ */ new Date()).toISOString(),
|
|
22135
|
+
gmtModified: (/* @__PURE__ */ new Date()).toISOString()
|
|
22136
|
+
};
|
|
22137
|
+
upsertArtifact(newArtifactEntry);
|
|
22138
|
+
setActiveArtifact(newArtifactEntry.id);
|
|
22139
|
+
}
|
|
22140
|
+
}, [activeArtifact, artifacts, currentSession, upsertArtifact, setActiveArtifact]);
|
|
19630
22141
|
const handleCloseArtifact = useCallback(() => {
|
|
19631
|
-
|
|
22142
|
+
setActiveArtifact(null);
|
|
19632
22143
|
setIsArtifactFullscreen(false);
|
|
19633
|
-
}, []);
|
|
22144
|
+
}, [setActiveArtifact]);
|
|
19634
22145
|
useEffect(() => {
|
|
19635
22146
|
const handleKeyDown = (e) => {
|
|
19636
|
-
if (e.key === "Escape" &&
|
|
22147
|
+
if (e.key === "Escape" && activeArtifactId) {
|
|
19637
22148
|
if (isArtifactFullscreen) {
|
|
19638
22149
|
setIsArtifactFullscreen(false);
|
|
19639
22150
|
} else {
|
|
19640
|
-
|
|
22151
|
+
setActiveArtifact(null);
|
|
19641
22152
|
}
|
|
19642
22153
|
}
|
|
19643
22154
|
};
|
|
19644
22155
|
document.addEventListener("keydown", handleKeyDown);
|
|
19645
22156
|
return () => document.removeEventListener("keydown", handleKeyDown);
|
|
19646
|
-
}, [
|
|
22157
|
+
}, [activeArtifactId, isArtifactFullscreen, setActiveArtifact]);
|
|
19647
22158
|
const handleToggleArtifactFullscreen = useCallback(() => {
|
|
19648
22159
|
setIsArtifactFullscreen((prev) => !prev);
|
|
19649
22160
|
}, []);
|
|
@@ -19845,8 +22356,9 @@ var AgentChat = React20__default.forwardRef(({
|
|
|
19845
22356
|
addSession(s);
|
|
19846
22357
|
setCurrentSession(s);
|
|
19847
22358
|
useAgentStore.getState().setMessages([]);
|
|
22359
|
+
clearArtifacts();
|
|
19848
22360
|
}
|
|
19849
|
-
}, [projectId, agentId]);
|
|
22361
|
+
}, [projectId, agentId, clearArtifacts]);
|
|
19850
22362
|
const handlePrompt = useCallback(async (p) => {
|
|
19851
22363
|
await handleNew();
|
|
19852
22364
|
setInput(p);
|
|
@@ -19857,10 +22369,29 @@ var AgentChat = React20__default.forwardRef(({
|
|
|
19857
22369
|
onSessionIdChange?.(s.sessionId);
|
|
19858
22370
|
setMobileOpen(false);
|
|
19859
22371
|
useAgentStore.getState().setMessages([]);
|
|
22372
|
+
clearArtifacts();
|
|
19860
22373
|
setMessagesLoading(true);
|
|
19861
|
-
await
|
|
22374
|
+
await Promise.all([
|
|
22375
|
+
loadMessages(s.sessionId),
|
|
22376
|
+
artifactService.list(s.sessionId).then((res) => {
|
|
22377
|
+
if (res.success && res.data && res.data.length > 0) {
|
|
22378
|
+
setArtifacts(res.data);
|
|
22379
|
+
}
|
|
22380
|
+
}).catch((err) => {
|
|
22381
|
+
console.error("[AgentChat] Load artifacts failed:", err);
|
|
22382
|
+
})
|
|
22383
|
+
]);
|
|
22384
|
+
const currentArtifacts = useAgentStore.getState().artifacts;
|
|
22385
|
+
if (Object.keys(currentArtifacts).length === 0) {
|
|
22386
|
+
const currentMessages = useAgentStore.getState().messages;
|
|
22387
|
+
const extracted = extractArtifactsFromMessages(currentMessages, s.sessionId);
|
|
22388
|
+
if (extracted.length > 0) {
|
|
22389
|
+
console.log("[AgentChat] Fallback: extracted", extracted.length, "artifacts from messages");
|
|
22390
|
+
extracted.forEach((artifact) => upsertArtifact(artifact));
|
|
22391
|
+
}
|
|
22392
|
+
}
|
|
19862
22393
|
setMessagesLoading(false);
|
|
19863
|
-
}, []);
|
|
22394
|
+
}, [clearArtifacts, setArtifacts, upsertArtifact]);
|
|
19864
22395
|
const handleDelete2 = useCallback(async (id) => {
|
|
19865
22396
|
toast("\u5220\u9664\u6B64\u5BF9\u8BDD\uFF1F", {
|
|
19866
22397
|
action: {
|
|
@@ -19956,8 +22487,14 @@ var AgentChat = React20__default.forwardRef(({
|
|
|
19956
22487
|
}
|
|
19957
22488
|
});
|
|
19958
22489
|
setImages([]);
|
|
19959
|
-
|
|
19960
|
-
|
|
22490
|
+
const currentActiveArtifact = activeArtifactId ? artifacts[activeArtifactId] : null;
|
|
22491
|
+
const artifactContext = currentActiveArtifact ? {
|
|
22492
|
+
artifactId: currentActiveArtifact.id,
|
|
22493
|
+
title: currentActiveArtifact.title,
|
|
22494
|
+
currentContent: currentActiveArtifact.currentContent
|
|
22495
|
+
} : void 0;
|
|
22496
|
+
await sendMessage(currentSession.sessionId, messageContent, { artifactContext });
|
|
22497
|
+
}, [input, images, currentSession, sendMessage, config, activeArtifactId, artifacts]);
|
|
19961
22498
|
const sendTextMessage = useCallback(async (content) => {
|
|
19962
22499
|
if (!content.trim()) return;
|
|
19963
22500
|
if (!currentSession) return;
|
|
@@ -20122,6 +22659,13 @@ var AgentChat = React20__default.forwardRef(({
|
|
|
20122
22659
|
onOpenArtifact: handleOpenArtifact
|
|
20123
22660
|
}
|
|
20124
22661
|
),
|
|
22662
|
+
artifactList.length > 0 && !currentArtifact && /* @__PURE__ */ jsx(
|
|
22663
|
+
ArtifactBar,
|
|
22664
|
+
{
|
|
22665
|
+
artifacts: artifactList,
|
|
22666
|
+
onOpenArtifact: (id) => setActiveArtifact(id)
|
|
22667
|
+
}
|
|
22668
|
+
),
|
|
20125
22669
|
!hideInput && /* @__PURE__ */ jsx(
|
|
20126
22670
|
ChatInputArea,
|
|
20127
22671
|
{
|
|
@@ -20132,7 +22676,9 @@ var AgentChat = React20__default.forwardRef(({
|
|
|
20132
22676
|
onSend: handleSend,
|
|
20133
22677
|
onStop: handleStop,
|
|
20134
22678
|
isStreaming: isCurrentSessionStreaming,
|
|
20135
|
-
config
|
|
22679
|
+
config,
|
|
22680
|
+
activeArtifact,
|
|
22681
|
+
onDetachArtifact: () => setActiveArtifact(null)
|
|
20136
22682
|
}
|
|
20137
22683
|
)
|
|
20138
22684
|
]
|
|
@@ -20171,7 +22717,36 @@ var AgentChat = React20__default.forwardRef(({
|
|
|
20171
22717
|
config,
|
|
20172
22718
|
isFullscreen: isArtifactFullscreen,
|
|
20173
22719
|
onFullscreenToggle: handleToggleArtifactFullscreen,
|
|
20174
|
-
embedded: true
|
|
22720
|
+
embedded: true,
|
|
22721
|
+
artifacts: artifactList,
|
|
22722
|
+
activeArtifactId,
|
|
22723
|
+
onSwitchArtifact: (id) => setActiveArtifact(id),
|
|
22724
|
+
onCloseArtifact: (id) => {
|
|
22725
|
+
removeArtifact(id);
|
|
22726
|
+
if (artifactList.length <= 1) {
|
|
22727
|
+
setIsArtifactFullscreen(false);
|
|
22728
|
+
}
|
|
22729
|
+
},
|
|
22730
|
+
onReorderArtifacts: reorderArtifacts,
|
|
22731
|
+
onContentChange: (content) => {
|
|
22732
|
+
if (activeArtifactId) {
|
|
22733
|
+
updateArtifactContent(activeArtifactId, content, "user");
|
|
22734
|
+
}
|
|
22735
|
+
},
|
|
22736
|
+
onSave: async (artifactId, content) => {
|
|
22737
|
+
try {
|
|
22738
|
+
const res = await artifactService.updateContent(artifactId, content);
|
|
22739
|
+
if (res.success) {
|
|
22740
|
+
updateArtifactContent(artifactId, content, "user");
|
|
22741
|
+
toast.success("\u4EA7\u7269\u5DF2\u4FDD\u5B58");
|
|
22742
|
+
} else {
|
|
22743
|
+
toast.error("\u4FDD\u5B58\u5931\u8D25");
|
|
22744
|
+
}
|
|
22745
|
+
} catch (err) {
|
|
22746
|
+
console.error("[AgentChat] Save artifact failed:", err);
|
|
22747
|
+
toast.error("\u4FDD\u5B58\u4EA7\u7269\u5931\u8D25");
|
|
22748
|
+
}
|
|
22749
|
+
}
|
|
20175
22750
|
}
|
|
20176
22751
|
)
|
|
20177
22752
|
]
|
|
@@ -20647,6 +23222,6 @@ function ShareReplayPage({ shareId, onNavigateBack }) {
|
|
|
20647
23222
|
] });
|
|
20648
23223
|
}
|
|
20649
23224
|
|
|
20650
|
-
export { AgentChat_default as AgentChat, ChatWindow_default as ChatWindow, ComponentProvider, HumanInputDialog_default as HumanInputDialog, ImagePreview, MAX_RECONNECT_ATTEMPTS2 as MAX_RECONNECT_ATTEMPTS, MessageBubble_default as MessageBubble, MessageImage, MessageVideo, MultiAgentThoughts_default as MultiAgentThoughts, ParameterDisplay, PlanCard_default as PlanCard, PlanConfirmDialog_default as PlanConfirmDialog, PlanProgressPanel_default as PlanProgressPanel, RECONNECT_BASE_DELAY2 as RECONNECT_BASE_DELAY, SSE_HEARTBEAT_TIMEOUT2 as SSE_HEARTBEAT_TIMEOUT, SaveTemplateDialog_default as SaveTemplateDialog, ShareModal, ShareReplayPage, StreamingJsonDisplay, TemplateSelector_default as TemplateSelector, TemplateSourceBadge_default as TemplateSourceBadge, TemplateVariableDialog_default as TemplateVariableDialog, ThinkingProcess, ToolConfirmCard, ToolConfirmDialog, UpdateTemplateDialog_default as UpdateTemplateDialog, VoiceInput, VoiceInputButton, VoiceRecordingModal, VoiceWaveform, agentService, agentSkillService, agentToolService, calculateReconnectDelay, componentService, confirmAllPendingToolCalls, createAndStartSession, createHeartbeatManager, createReconnectManager, createStreamReader, embedding, extractJsonContent, extractThinkingContent, extractToolCalls, filterMediaAttachments, findMessageById, findSessionById, formatParameters, generateSSEId, generateSessionTitle, generateToolCallDescription, getCurrentSessionMessages, getFileUrl, getHDImageUrl, getImageUrl, getOSSClient, getParamsSummary, getSessionCurrentThoughts, getSessionPendingToolCalls, getSessionWithMessages, getToolCallDisplayStatus, getToolCallStatusPriority, hasExecutingToolCalls, hasPendingToolCalls, hasWaitingConfirmation, isConversationActive, isCurrentlyThinking, isImageUrl, isMechanicalSummary, isPendingToolCallsForSession, isVideoUrl3 as isVideoUrl, llmService, looksLikeJson, mergeToolCalls, messageService, normalizeToolCall, normalizeToolCalls, parseSSELine2 as parseSSELine, parseThinkingContent, parseThoughts, planService, rejectAllPendingToolCalls, resolveMediaUrl, sessionService, shareService, templateService, toolCallService, uploadOSS, useActiveSubAgent, useAgentStore, useChatError, useChatUI, useComponent, useComponents, useCurrentSession, useCurrentThoughts, useCurrentThoughtsSessionId, useIsStreaming, useIsThinking, useMessages, usePendingComponents, usePendingComponentsSessionId, usePendingFrontendToolCalls, usePendingFrontendToolCallsSessionId, usePendingToolCalls, usePendingToolCallsSessionId, useSSE, useSessions, useSessionsLoading, useStreamingContent, useStreamingSessionId, useSubAgents, useVoiceRecognition };
|
|
23225
|
+
export { AgentChat_default as AgentChat, ChatWindow_default as ChatWindow, ComponentProvider, HumanInputDialog_default as HumanInputDialog, ImagePreview, MAX_RECONNECT_ATTEMPTS2 as MAX_RECONNECT_ATTEMPTS, MessageBubble_default as MessageBubble, MessageImage, MessageVideo, MultiAgentThoughts_default as MultiAgentThoughts, ParameterDisplay, PlanCard_default as PlanCard, PlanConfirmDialog_default as PlanConfirmDialog, PlanProgressPanel_default as PlanProgressPanel, RECONNECT_BASE_DELAY2 as RECONNECT_BASE_DELAY, SSE_HEARTBEAT_TIMEOUT2 as SSE_HEARTBEAT_TIMEOUT, SaveTemplateDialog_default as SaveTemplateDialog, ShareModal, ShareReplayPage, StreamingJsonDisplay, TemplateSelector_default as TemplateSelector, TemplateSourceBadge_default as TemplateSourceBadge, TemplateVariableDialog_default as TemplateVariableDialog, ThinkingProcess, ToolConfirmCard, ToolConfirmDialog, UpdateTemplateDialog_default as UpdateTemplateDialog, VoiceInput, VoiceInputButton, VoiceRecordingModal, VoiceWaveform, agentService, agentSkillService, agentToolService, artifactService, calculateReconnectDelay, componentService, confirmAllPendingToolCalls, createAndStartSession, createHeartbeatManager, createReconnectManager, createStreamReader, embedding, extractJsonContent, extractThinkingContent, extractToolCalls, filterMediaAttachments, findMessageById, findSessionById, formatParameters, generateSSEId, generateSessionTitle, generateToolCallDescription, getCurrentSessionMessages, getFileUrl, getHDImageUrl, getImageUrl, getOSSClient, getParamsSummary, getSessionCurrentThoughts, getSessionPendingToolCalls, getSessionWithMessages, getToolCallDisplayStatus, getToolCallStatusPriority, hasExecutingToolCalls, hasPendingToolCalls, hasWaitingConfirmation, isConversationActive, isCurrentlyThinking, isImageUrl, isMechanicalSummary, isPendingToolCallsForSession, isVideoUrl3 as isVideoUrl, llmService, looksLikeJson, mergeToolCalls, messageService, normalizeToolCall, normalizeToolCalls, parseSSELine2 as parseSSELine, parseThinkingContent, parseThoughts, planService, rejectAllPendingToolCalls, resolveMediaUrl, sessionService, shareService, templateService, toolCallService, uploadOSS, useActiveArtifact, useActiveArtifactId, useActiveSubAgent, useAgentStore, useArtifactList, useArtifactOrder, useArtifacts, useCanvasBridge, useChatError, useChatUI, useComponent, useComponents, useCurrentSession, useCurrentThoughts, useCurrentThoughtsSessionId, useIsStreaming, useIsThinking, useMessages, usePendingComponents, usePendingComponentsSessionId, usePendingFrontendToolCalls, usePendingFrontendToolCallsSessionId, usePendingToolCalls, usePendingToolCallsSessionId, useSSE, useSessions, useSessionsLoading, useStreamingContent, useStreamingSessionId, useSubAgents, useVoiceRecognition };
|
|
20651
23226
|
//# sourceMappingURL=index.mjs.map
|
|
20652
23227
|
//# sourceMappingURL=index.mjs.map
|