@zero-library/chat-copilot 3.1.5 → 3.1.7
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.cjs.js +448 -225
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.css +25 -41
- package/dist/index.css.map +1 -1
- package/dist/index.d.mts +14 -5
- package/dist/index.d.ts +14 -5
- package/dist/index.esm.js +449 -228
- package/dist/index.esm.js.map +1 -1
- package/package.json +3 -3
package/dist/index.esm.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { CloudUploadOutlined, PaperClipOutlined, createFromIconfontCN, LoadingOutlined, EnterOutlined, DownloadOutlined, CloseOutlined, PlayCircleOutlined, CopyOutlined, DotChartOutlined, LikeOutlined, DislikeOutlined, ToolOutlined, SearchOutlined, UpOutlined, DownOutlined, PlusOutlined, CommentOutlined, RedoOutlined, DeleteOutlined, ClockCircleOutlined, CheckCircleOutlined, FileImageOutlined, FilePdfOutlined, FileWordOutlined, FileExcelOutlined, FilePptOutlined, FileZipOutlined, FileTextOutlined, FileUnknownOutlined } from '@ant-design/icons';
|
|
2
2
|
import { Attachments, Sender, FileCard, Bubble, Think, XProvider, Mermaid, CodeHighlighter, Welcome, Prompts, Conversations } from '@ant-design/x-v2';
|
|
3
|
-
import { useRefState, useDebounce,
|
|
4
|
-
import { App, Badge, Button, Flex, Typography, Tooltip, Layout, Tag, Spin, Splitter,
|
|
3
|
+
import { useRefState, useDebounce, createTokenManager, useSyncInput, isEmptyObj, markdownToText, RenderWrapper, shouldRender, isFunction, downloadFile, LuyaFilePreview, MarkdownEditor, useDeepEffect, isObject, useWebSocket, isNullOrUnDef, isNumber, getFileSuffixName, FileIcon, copyText, LazyComponent, isBoolean, UserAvatar, htmlToMarkdown, buildUrlParams, isExternal, deepCopy, transforms, deepMerge, createRequest, HttpStatus, isArray, isString, transform, emit, getWebSocketUrl, safeParseJson } from '@zero-library/common';
|
|
4
|
+
import { App, Badge, Button, Flex, Typography, Tooltip, Layout, Tag, Spin, Splitter, Image as Image$1, Popover, Skeleton, Alert, theme, Collapse, Divider as Divider$1, Select as Select$1, Avatar, Space, Drawer, Empty, Modal, Checkbox, Input, message, List, Card, Table, Progress as Progress$1, Switch as Switch$1 } from 'antd';
|
|
5
5
|
import * as React10 from 'react';
|
|
6
6
|
import React10__default, { createContext, forwardRef, useRef, useEffect, useImperativeHandle, useMemo, useCallback, memo, useState, useContext, useLayoutEffect } from 'react';
|
|
7
7
|
import { useSnapshot, proxy } from 'valtio';
|
|
@@ -129,7 +129,10 @@ var Attachments_default = forwardRef(({ fileUpload, fileUploadConfig, fileList =
|
|
|
129
129
|
const uploadedFile = data[0];
|
|
130
130
|
let previewUrl = uploadedFile.id;
|
|
131
131
|
if (uploadedFile.conversationId && uploadedFile.path) {
|
|
132
|
-
previewUrl = chatStore.config.services.request.getPreviewUrl(
|
|
132
|
+
previewUrl = chatStore.config.services.request.getPreviewUrl({
|
|
133
|
+
path: uploadedFile.path,
|
|
134
|
+
workspaceId: uploadedFile.conversationId
|
|
135
|
+
});
|
|
133
136
|
}
|
|
134
137
|
setAttachedFiles(
|
|
135
138
|
getAttachedFiles().map((f) => {
|
|
@@ -222,8 +225,12 @@ var index_module_default = {
|
|
|
222
225
|
promptEditorPlaceholder: "index_module_promptEditorPlaceholder",
|
|
223
226
|
resourceSelect: "index_module_resourceSelect",
|
|
224
227
|
fileMenu: "index_module_fileMenu",
|
|
228
|
+
fileMenuGroup: "index_module_fileMenuGroup",
|
|
229
|
+
fileMenuGroupTitle: "index_module_fileMenuGroupTitle",
|
|
230
|
+
fileMenuEmpty: "index_module_fileMenuEmpty",
|
|
225
231
|
fileMenuItem: "index_module_fileMenuItem",
|
|
226
232
|
fileMenuItemActive: "index_module_fileMenuItemActive",
|
|
233
|
+
fileIcon: "index_module_fileIcon",
|
|
227
234
|
fileName: "index_module_fileName",
|
|
228
235
|
resourceTag: "index_module_resourceTag"
|
|
229
236
|
};
|
|
@@ -231,6 +238,16 @@ var index_module_default = {
|
|
|
231
238
|
// src/core/constants.ts
|
|
232
239
|
var CONV_MODE = {
|
|
233
240
|
PROD: 1};
|
|
241
|
+
var TOKEN_KEY = "NS-TOKEN";
|
|
242
|
+
var tokenManager = createTokenManager({
|
|
243
|
+
key: TOKEN_KEY
|
|
244
|
+
});
|
|
245
|
+
var redirectUrl = () => {
|
|
246
|
+
const path = localStorage.getItem("SIGNPATH");
|
|
247
|
+
emit("jumpLink", { url: `/uc${path || "/sign-in"}` });
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
// src/core/utils.ts
|
|
234
251
|
var classifyTime = (timestamp) => {
|
|
235
252
|
const now = dayjs();
|
|
236
253
|
const target = dayjs(timestamp);
|
|
@@ -277,27 +294,52 @@ var getFileIcon = (extension, fontSize = 24) => {
|
|
|
277
294
|
}
|
|
278
295
|
return createIcon(FileUnknownOutlined, "#94a3b8");
|
|
279
296
|
};
|
|
280
|
-
|
|
281
|
-
|
|
297
|
+
var getFileUrl = (params, baseUrl, url) => {
|
|
298
|
+
const data = {
|
|
299
|
+
[TOKEN_KEY]: tokenManager.get(),
|
|
300
|
+
workspaceType: "conversation" /* CONVERSATION */,
|
|
301
|
+
...params
|
|
302
|
+
};
|
|
303
|
+
return buildUrlParams(data, url || `${baseUrl}/files/access`);
|
|
304
|
+
};
|
|
305
|
+
function GroupPicker({
|
|
306
|
+
groups,
|
|
282
307
|
selectedIndex,
|
|
283
308
|
onSelect,
|
|
284
309
|
onHover
|
|
285
310
|
}) {
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
"
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
311
|
+
const itemRefs = useRef([]);
|
|
312
|
+
let currentIndex = -1;
|
|
313
|
+
useEffect(() => {
|
|
314
|
+
itemRefs.current[selectedIndex]?.scrollIntoView({
|
|
315
|
+
block: "nearest"
|
|
316
|
+
});
|
|
317
|
+
}, [groups, selectedIndex]);
|
|
318
|
+
return /* @__PURE__ */ jsx("div", { className: index_module_default.fileMenu, role: "listbox", children: groups.map(({ group, options }) => /* @__PURE__ */ jsxs("div", { className: index_module_default.fileMenuGroup, children: [
|
|
319
|
+
/* @__PURE__ */ jsx("div", { className: index_module_default.fileMenuGroupTitle, children: group.label }),
|
|
320
|
+
options.length ? options.map((option) => {
|
|
321
|
+
currentIndex += 1;
|
|
322
|
+
const optionIndex = currentIndex;
|
|
323
|
+
return /* @__PURE__ */ jsxs(
|
|
324
|
+
"div",
|
|
325
|
+
{
|
|
326
|
+
ref: (element) => {
|
|
327
|
+
itemRefs.current[optionIndex] = element;
|
|
328
|
+
},
|
|
329
|
+
role: "option",
|
|
330
|
+
"aria-selected": optionIndex === selectedIndex,
|
|
331
|
+
className: `${index_module_default.fileMenuItem} ${optionIndex === selectedIndex ? index_module_default.fileMenuItemActive : ""}`,
|
|
332
|
+
onMouseEnter: () => onHover(optionIndex),
|
|
333
|
+
onClick: () => onSelect(group, option),
|
|
334
|
+
children: [
|
|
335
|
+
option.ext && /* @__PURE__ */ jsx("span", { className: index_module_default.fileIcon, children: getFileIcon(option.ext, 14) }),
|
|
336
|
+
/* @__PURE__ */ jsx("span", { className: index_module_default.fileName, children: option.label })
|
|
337
|
+
]
|
|
338
|
+
},
|
|
339
|
+
`${group.value}-${option.value}`
|
|
340
|
+
);
|
|
341
|
+
}) : /* @__PURE__ */ jsx("div", { className: index_module_default.fileMenuEmpty, children: "\u6682\u65E0\u6570\u636E" })
|
|
342
|
+
] }, group.value)) });
|
|
301
343
|
}
|
|
302
344
|
function ResourcePickerMenu({
|
|
303
345
|
anchorElementRef,
|
|
@@ -346,7 +388,6 @@ function ResourceTag({ resource }) {
|
|
|
346
388
|
formatResourceName(resource.resourceName)
|
|
347
389
|
] }) });
|
|
348
390
|
}
|
|
349
|
-
var EMPTY_CASCADE_OPTION_VALUE = "__empty__";
|
|
350
391
|
var VariableNode = class _VariableNode extends DecoratorNode {
|
|
351
392
|
__resourceLabel;
|
|
352
393
|
__resourceType;
|
|
@@ -437,34 +478,25 @@ var VariableNode = class _VariableNode extends DecoratorNode {
|
|
|
437
478
|
function $createVariableNode(resourceLabel, resourceName, resourceType, resourceId) {
|
|
438
479
|
return new VariableNode(resourceLabel, resourceName, resourceType, resourceId);
|
|
439
480
|
}
|
|
440
|
-
var
|
|
441
|
-
|
|
481
|
+
var ResourceOption = class extends MenuOption {
|
|
482
|
+
group;
|
|
442
483
|
item;
|
|
443
484
|
/**
|
|
444
|
-
*
|
|
485
|
+
* 将分组列表中的资源节点包装成 Lexical 菜单选项对象。
|
|
445
486
|
*/
|
|
446
|
-
constructor(
|
|
447
|
-
super(`${
|
|
448
|
-
this.
|
|
487
|
+
constructor(group, item) {
|
|
488
|
+
super(`${group.value}:${item.value}`);
|
|
489
|
+
this.group = group;
|
|
449
490
|
this.item = item;
|
|
450
491
|
}
|
|
451
492
|
};
|
|
452
|
-
var FileOption = class extends MenuOption {
|
|
453
|
-
file;
|
|
454
|
-
/**
|
|
455
|
-
* 将文件列表项包装成 Lexical 菜单选项对象。
|
|
456
|
-
*/
|
|
457
|
-
constructor(file) {
|
|
458
|
-
super(file.value);
|
|
459
|
-
this.file = file;
|
|
460
|
-
}
|
|
461
|
-
};
|
|
462
493
|
function VariablePickerPlugin({ commandConfig = {} }) {
|
|
463
494
|
const [editor] = useLexicalComposerContext();
|
|
464
495
|
const chatStore = useChatStore();
|
|
465
496
|
const [commandDataSource, setCommandDataSource] = useState(commandConfig);
|
|
466
497
|
const [queryString, setQueryString] = useState(null);
|
|
467
498
|
const [isEditorFocused, setIsEditorFocused] = useState(false);
|
|
499
|
+
const [menuResetKey, setMenuResetKey] = useState(0);
|
|
468
500
|
const blurTimerRef = useRef(null);
|
|
469
501
|
useEffect(() => {
|
|
470
502
|
const unregister = mergeRegister(
|
|
@@ -481,6 +513,7 @@ function VariablePickerPlugin({ commandConfig = {} }) {
|
|
|
481
513
|
BLUR_COMMAND,
|
|
482
514
|
() => {
|
|
483
515
|
setIsEditorFocused(false);
|
|
516
|
+
setMenuResetKey((current) => current + 1);
|
|
484
517
|
return false;
|
|
485
518
|
},
|
|
486
519
|
COMMAND_PRIORITY_LOW
|
|
@@ -495,6 +528,7 @@ function VariablePickerPlugin({ commandConfig = {} }) {
|
|
|
495
528
|
setCommandDataSource(commandConfig);
|
|
496
529
|
}, [commandConfig]);
|
|
497
530
|
const commandKey = queryString?.[0] || "";
|
|
531
|
+
const searchKeyword = queryString?.slice(commandKey.length).trim().toLocaleLowerCase() || "";
|
|
498
532
|
const categoryConfig = useMemo(
|
|
499
533
|
() => ({
|
|
500
534
|
skill: {
|
|
@@ -512,58 +546,82 @@ function VariablePickerPlugin({ commandConfig = {} }) {
|
|
|
512
546
|
}),
|
|
513
547
|
[chatStore]
|
|
514
548
|
);
|
|
515
|
-
const commandOptions = useMemo(() => {
|
|
516
|
-
if (!isEditorFocused) return [];
|
|
517
|
-
return (commandDataSource[commandKey]?.dataSource || []).flatMap(
|
|
518
|
-
(category) => category.children?.filter((item) => !item.disabled).map((item) => new CascadeOption(category, item)) || []
|
|
519
|
-
);
|
|
520
|
-
}, [commandDataSource, commandKey, isEditorFocused]);
|
|
521
549
|
const formatDataSource = useCallback(
|
|
522
550
|
(items, category) => {
|
|
523
551
|
const currentCategoryConfig = categoryConfig[category.value];
|
|
524
|
-
if (!items.length)
|
|
525
|
-
return [
|
|
526
|
-
{
|
|
527
|
-
value: EMPTY_CASCADE_OPTION_VALUE,
|
|
528
|
-
label: "\u6682\u65E0\u6570\u636E",
|
|
529
|
-
isLeaf: true,
|
|
530
|
-
disabled: true
|
|
531
|
-
}
|
|
532
|
-
];
|
|
533
|
-
}
|
|
552
|
+
if (!items.length) return [];
|
|
534
553
|
return items.map((item) => ({
|
|
535
554
|
value: item.id,
|
|
536
|
-
label: currentCategoryConfig?.getLabel(item) || item.name
|
|
555
|
+
label: currentCategoryConfig?.getLabel(item) || item.name,
|
|
556
|
+
children: []
|
|
537
557
|
}));
|
|
538
558
|
},
|
|
539
559
|
[categoryConfig]
|
|
540
560
|
);
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
(
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
+
useEffect(() => {
|
|
562
|
+
let isUnmounted = false;
|
|
563
|
+
const initializeCommandDataSource = async () => {
|
|
564
|
+
const nextEntries = await Promise.all(
|
|
565
|
+
Object.entries(commandConfig).map(async ([trigger, currentCommandConfig]) => {
|
|
566
|
+
const nextDataSource = await Promise.all(
|
|
567
|
+
(currentCommandConfig.dataSource || []).map(async (category) => {
|
|
568
|
+
const normalizedChildren = category.children || [];
|
|
569
|
+
const nextCategory = {
|
|
570
|
+
...category,
|
|
571
|
+
children: normalizedChildren
|
|
572
|
+
};
|
|
573
|
+
const currentCategoryConfig = categoryConfig[category.value];
|
|
574
|
+
if (!currentCategoryConfig) {
|
|
575
|
+
return nextCategory;
|
|
576
|
+
}
|
|
577
|
+
if (normalizedChildren.length) {
|
|
578
|
+
return nextCategory;
|
|
579
|
+
}
|
|
580
|
+
const response = await currentCategoryConfig.load();
|
|
581
|
+
const items = response.data || [];
|
|
582
|
+
return {
|
|
583
|
+
...nextCategory,
|
|
584
|
+
children: formatDataSource(items, category)
|
|
585
|
+
};
|
|
586
|
+
})
|
|
587
|
+
);
|
|
588
|
+
return [
|
|
589
|
+
trigger,
|
|
590
|
+
{
|
|
591
|
+
...currentCommandConfig,
|
|
592
|
+
dataSource: nextDataSource
|
|
593
|
+
}
|
|
594
|
+
];
|
|
595
|
+
})
|
|
596
|
+
);
|
|
597
|
+
if (isUnmounted) return;
|
|
598
|
+
setCommandDataSource(Object.fromEntries(nextEntries));
|
|
599
|
+
};
|
|
600
|
+
initializeCommandDataSource();
|
|
601
|
+
return () => {
|
|
602
|
+
isUnmounted = true;
|
|
603
|
+
};
|
|
604
|
+
}, [categoryConfig, commandConfig, formatDataSource]);
|
|
605
|
+
const commandGroups = useMemo(() => {
|
|
606
|
+
if (!isEditorFocused) return [];
|
|
607
|
+
return (commandDataSource[commandKey]?.dataSource || []).map((group) => {
|
|
608
|
+
const options = group.children || [];
|
|
609
|
+
if (!searchKeyword) return { group, options };
|
|
610
|
+
return {
|
|
611
|
+
group,
|
|
612
|
+
options: options.filter((option) => option.label.toLocaleLowerCase().includes(searchKeyword))
|
|
613
|
+
};
|
|
614
|
+
}).filter(({ options }) => !searchKeyword || options.length);
|
|
615
|
+
}, [commandDataSource, commandKey, isEditorFocused, searchKeyword]);
|
|
616
|
+
const commandOptions = useMemo(
|
|
617
|
+
() => commandGroups.flatMap(({ group, options }) => options.map((item) => new ResourceOption(group, item))),
|
|
618
|
+
[commandGroups]
|
|
561
619
|
);
|
|
562
620
|
const onSelectOption = useCallback(
|
|
563
621
|
(selectedOption, nodeToReplace, closeMenu, matchingString) => {
|
|
564
|
-
const resource = selectedOption
|
|
565
|
-
const resourceLabel = selectedOption
|
|
566
|
-
const resourceType = selectedOption
|
|
622
|
+
const resource = selectedOption.item;
|
|
623
|
+
const resourceLabel = selectedOption.group.label;
|
|
624
|
+
const resourceType = selectedOption.group.value;
|
|
567
625
|
editor.update(() => {
|
|
568
626
|
const variableNode = $createVariableNode(resourceLabel, resource.label, resourceType, resource.value);
|
|
569
627
|
if (nodeToReplace) {
|
|
@@ -573,7 +631,7 @@ function VariablePickerPlugin({ commandConfig = {} }) {
|
|
|
573
631
|
});
|
|
574
632
|
closeMenu();
|
|
575
633
|
},
|
|
576
|
-
[
|
|
634
|
+
[editor]
|
|
577
635
|
);
|
|
578
636
|
return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(
|
|
579
637
|
LexicalTypeaheadMenuPlugin,
|
|
@@ -587,40 +645,24 @@ function VariablePickerPlugin({ commandConfig = {} }) {
|
|
|
587
645
|
if (!match) return null;
|
|
588
646
|
return { leadOffset: match.index, matchingString: match[0], replaceableString: match[0] };
|
|
589
647
|
},
|
|
590
|
-
options: commandOptions
|
|
591
|
-
menuRenderFn: (anchorElementRef, { selectedIndex, setHighlightedIndex, selectOptionAndCleanUp }
|
|
592
|
-
if (!anchorElementRef.current) return null;
|
|
648
|
+
options: commandOptions,
|
|
649
|
+
menuRenderFn: (anchorElementRef, { selectedIndex, setHighlightedIndex, selectOptionAndCleanUp }) => {
|
|
650
|
+
if (!isEditorFocused || !anchorElementRef.current || searchKeyword && !commandGroups.length) return null;
|
|
593
651
|
return ReactDOM.createPortal(
|
|
594
|
-
/* @__PURE__ */
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
const option = commandOptions.find(
|
|
604
|
-
(currentOption) => currentOption.category.value === categoryValue && currentOption.item.value === itemValue
|
|
605
|
-
);
|
|
606
|
-
if (option) selectOptionAndCleanUp(option);
|
|
607
|
-
}
|
|
608
|
-
}
|
|
609
|
-
),
|
|
610
|
-
commandDataSource[matchingString]?.component === "list" && /* @__PURE__ */ jsx(
|
|
611
|
-
FilePickerMenu,
|
|
612
|
-
{
|
|
613
|
-
options: commandDataSource[matchingString]?.dataSource || [],
|
|
614
|
-
selectedIndex: selectedIndex ?? 0,
|
|
615
|
-
onHover: setHighlightedIndex,
|
|
616
|
-
onSelect: (option) => selectOptionAndCleanUp(new FileOption(option))
|
|
617
|
-
}
|
|
618
|
-
)
|
|
619
|
-
] }),
|
|
652
|
+
/* @__PURE__ */ jsx(ResourcePickerMenu, { anchorElementRef, children: /* @__PURE__ */ jsx(
|
|
653
|
+
GroupPicker,
|
|
654
|
+
{
|
|
655
|
+
groups: commandGroups,
|
|
656
|
+
selectedIndex: selectedIndex ?? 0,
|
|
657
|
+
onHover: setHighlightedIndex,
|
|
658
|
+
onSelect: (group, option) => selectOptionAndCleanUp(new ResourceOption(group, option))
|
|
659
|
+
}
|
|
660
|
+
) }),
|
|
620
661
|
anchorElementRef.current
|
|
621
662
|
);
|
|
622
663
|
}
|
|
623
|
-
}
|
|
664
|
+
},
|
|
665
|
+
menuResetKey
|
|
624
666
|
) });
|
|
625
667
|
}
|
|
626
668
|
function InitialStatePlugin({ value }) {
|
|
@@ -843,14 +885,6 @@ var ChatSender_default = forwardRef(
|
|
|
843
885
|
);
|
|
844
886
|
}
|
|
845
887
|
);
|
|
846
|
-
var TOKEN_KEY = "NS-TOKEN";
|
|
847
|
-
var tokenManager = createTokenManager({
|
|
848
|
-
key: TOKEN_KEY
|
|
849
|
-
});
|
|
850
|
-
var redirectUrl = () => {
|
|
851
|
-
const path = localStorage.getItem("SIGNPATH");
|
|
852
|
-
emit("jumpLink", { url: `/uc${path || "/sign-in"}` });
|
|
853
|
-
};
|
|
854
888
|
var createChatService = (request, config) => {
|
|
855
889
|
const fetchModelList = () => {
|
|
856
890
|
return request.get(`/providers/models/type/llm`);
|
|
@@ -891,14 +925,8 @@ var createChatService = (request, config) => {
|
|
|
891
925
|
signal
|
|
892
926
|
});
|
|
893
927
|
};
|
|
894
|
-
const getPreviewUrl = (
|
|
895
|
-
|
|
896
|
-
path,
|
|
897
|
-
[TOKEN_KEY]: tokenManager.get(),
|
|
898
|
-
workspaceId: conversationId,
|
|
899
|
-
workspaceType: "conversation" /* CONVERSATION */
|
|
900
|
-
};
|
|
901
|
-
return buildUrlParams(params, `${config?.baseURL}/files/access`);
|
|
928
|
+
const getPreviewUrl = (params) => {
|
|
929
|
+
return getFileUrl(params, config?.baseURL);
|
|
902
930
|
};
|
|
903
931
|
const docQuery = (params) => {
|
|
904
932
|
return request.get(`/library/cloud/document?${params}`);
|
|
@@ -2707,7 +2735,10 @@ var PreviewLink_default = ({ data, loading, message: message2, ...rest }) => {
|
|
|
2707
2735
|
const fileName = getLinkFileName(href);
|
|
2708
2736
|
const suffix = getFileSuffixName(fileName);
|
|
2709
2737
|
chatStore.setPreview({
|
|
2710
|
-
fileUrl: chatStore.config.services.request.getPreviewUrl(
|
|
2738
|
+
fileUrl: chatStore.config.services.request.getPreviewUrl({
|
|
2739
|
+
path: href,
|
|
2740
|
+
workspaceId: message2.conversationId
|
|
2741
|
+
}),
|
|
2711
2742
|
fileName,
|
|
2712
2743
|
suffix
|
|
2713
2744
|
});
|
|
@@ -3231,6 +3262,135 @@ var A2uiComponents = {
|
|
|
3231
3262
|
ReportViewer
|
|
3232
3263
|
};
|
|
3233
3264
|
|
|
3265
|
+
// src/components/CustomComponents/A2uiRuntime/controller/extract.ts
|
|
3266
|
+
var A2UI_TAG_REGEX = /<A2UI\s+id="([^"]*)"\s*>([\s\S]*?)<\/A2UI>/g;
|
|
3267
|
+
function hasA2uiTag(text) {
|
|
3268
|
+
return typeof text === "string" && text.includes("<A2UI");
|
|
3269
|
+
}
|
|
3270
|
+
function parseA2uiTagsFromText(text) {
|
|
3271
|
+
if (!hasA2uiTag(text)) return [];
|
|
3272
|
+
const tags = [];
|
|
3273
|
+
const regex = new RegExp(A2UI_TAG_REGEX);
|
|
3274
|
+
let match;
|
|
3275
|
+
while ((match = regex.exec(text)) !== null) {
|
|
3276
|
+
const tagId = match[1];
|
|
3277
|
+
const json = match[2].trim();
|
|
3278
|
+
if (!json) continue;
|
|
3279
|
+
try {
|
|
3280
|
+
const parsed = JSON.parse(json);
|
|
3281
|
+
const commands = Array.isArray(parsed) ? parsed : [parsed];
|
|
3282
|
+
if (commands.length) tags.push({ tagId, commands });
|
|
3283
|
+
} catch {
|
|
3284
|
+
}
|
|
3285
|
+
}
|
|
3286
|
+
return tags;
|
|
3287
|
+
}
|
|
3288
|
+
function stripA2uiTags(text) {
|
|
3289
|
+
if (!hasA2uiTag(text)) return text;
|
|
3290
|
+
let result = text.replace(A2UI_TAG_REGEX, "");
|
|
3291
|
+
result = result.replace(/<A2UI\b[\s\S]*$/, "");
|
|
3292
|
+
return result.trim();
|
|
3293
|
+
}
|
|
3294
|
+
function splitA2uiTextSegments(text) {
|
|
3295
|
+
if (typeof text !== "string" || !text.includes("<A2UI")) {
|
|
3296
|
+
return text ? [{ type: "text", content: text }] : [];
|
|
3297
|
+
}
|
|
3298
|
+
const segments = [];
|
|
3299
|
+
const regex = new RegExp(A2UI_TAG_REGEX);
|
|
3300
|
+
let lastIndex = 0;
|
|
3301
|
+
let match;
|
|
3302
|
+
while ((match = regex.exec(text)) !== null) {
|
|
3303
|
+
if (match.index > lastIndex) {
|
|
3304
|
+
const before = text.slice(lastIndex, match.index);
|
|
3305
|
+
if (before) segments.push({ type: "text", content: before });
|
|
3306
|
+
}
|
|
3307
|
+
const json = match[2].trim();
|
|
3308
|
+
if (json) {
|
|
3309
|
+
try {
|
|
3310
|
+
const parsed = JSON.parse(json);
|
|
3311
|
+
const commands = Array.isArray(parsed) ? parsed : [parsed];
|
|
3312
|
+
const surfaceIds = commands.map((cmd) => String(cmd?.createSurface?.surfaceId || "").trim()).filter(Boolean);
|
|
3313
|
+
if (surfaceIds.length) {
|
|
3314
|
+
segments.push({ type: "a2ui", surfaceIds });
|
|
3315
|
+
}
|
|
3316
|
+
} catch {
|
|
3317
|
+
}
|
|
3318
|
+
}
|
|
3319
|
+
lastIndex = regex.lastIndex;
|
|
3320
|
+
}
|
|
3321
|
+
if (lastIndex < text.length) {
|
|
3322
|
+
let remaining = text.slice(lastIndex);
|
|
3323
|
+
remaining = remaining.replace(/<A2UI\b[\s\S]*$/, "");
|
|
3324
|
+
if (remaining) segments.push({ type: "text", content: remaining });
|
|
3325
|
+
}
|
|
3326
|
+
return segments.length ? segments : [];
|
|
3327
|
+
}
|
|
3328
|
+
function extractInlineSurfaceIdsFromMessage(message2) {
|
|
3329
|
+
const surfaceIds = /* @__PURE__ */ new Set();
|
|
3330
|
+
const items = Array.isArray(message2?.content) ? message2.content : [];
|
|
3331
|
+
for (const item of items) {
|
|
3332
|
+
if (item?.type !== "text") continue;
|
|
3333
|
+
const text = item.messageContent || item.text || "";
|
|
3334
|
+
if (typeof text !== "string" || !text.includes("<A2UI")) continue;
|
|
3335
|
+
const tags = parseA2uiTagsFromText(text);
|
|
3336
|
+
for (const tag of tags) {
|
|
3337
|
+
for (const cmd of tag.commands) {
|
|
3338
|
+
const sid = String(cmd?.createSurface?.surfaceId || "").trim();
|
|
3339
|
+
if (sid) surfaceIds.add(sid);
|
|
3340
|
+
}
|
|
3341
|
+
}
|
|
3342
|
+
}
|
|
3343
|
+
return surfaceIds;
|
|
3344
|
+
}
|
|
3345
|
+
function extractDismissedSurfaceIdsFromMessages(messages) {
|
|
3346
|
+
const lastCreateIndexBySurface = /* @__PURE__ */ new Map();
|
|
3347
|
+
const lastActionIndexBySurface = /* @__PURE__ */ new Map();
|
|
3348
|
+
for (let messageIndex = 0; messageIndex < messages.length; messageIndex++) {
|
|
3349
|
+
const message2 = messages[messageIndex];
|
|
3350
|
+
const items = Array.isArray(message2?.content) ? message2.content : [];
|
|
3351
|
+
for (const item of items) {
|
|
3352
|
+
if (message2?.role !== 1) {
|
|
3353
|
+
if (item?.type === "a2uiCommand" && item.command) {
|
|
3354
|
+
const surfaceId = String(item.command?.createSurface?.surfaceId || "").trim();
|
|
3355
|
+
if (surfaceId) lastCreateIndexBySurface.set(surfaceId, messageIndex);
|
|
3356
|
+
}
|
|
3357
|
+
if (item?.type === "text") {
|
|
3358
|
+
const text = item.messageContent || item.text || "";
|
|
3359
|
+
if (typeof text === "string" && text.includes("<A2UI")) {
|
|
3360
|
+
const tags = parseA2uiTagsFromText(text);
|
|
3361
|
+
for (const tag of tags) {
|
|
3362
|
+
for (const cmd of tag.commands) {
|
|
3363
|
+
const surfaceId = String(cmd?.createSurface?.surfaceId || "").trim();
|
|
3364
|
+
if (surfaceId) lastCreateIndexBySurface.set(surfaceId, messageIndex);
|
|
3365
|
+
}
|
|
3366
|
+
}
|
|
3367
|
+
}
|
|
3368
|
+
}
|
|
3369
|
+
}
|
|
3370
|
+
if (message2?.role === 1 && item?.type === "text") {
|
|
3371
|
+
const text = item.messageContent || item.text || "";
|
|
3372
|
+
if (typeof text !== "string" || !text.includes("a2ui_action.v1")) continue;
|
|
3373
|
+
try {
|
|
3374
|
+
const parsed = JSON.parse(text.trim());
|
|
3375
|
+
if (parsed?.type !== "a2ui_action.v1") continue;
|
|
3376
|
+
const surfaceId = String(parsed.surfaceId || "").trim();
|
|
3377
|
+
if (!surfaceId) continue;
|
|
3378
|
+
lastActionIndexBySurface.set(surfaceId, messageIndex);
|
|
3379
|
+
} catch {
|
|
3380
|
+
}
|
|
3381
|
+
}
|
|
3382
|
+
}
|
|
3383
|
+
}
|
|
3384
|
+
const dismissed = [];
|
|
3385
|
+
for (const [surfaceId, actionIndex] of lastActionIndexBySurface) {
|
|
3386
|
+
const createIndex = lastCreateIndexBySurface.get(surfaceId);
|
|
3387
|
+
if (createIndex === void 0 || actionIndex > createIndex) {
|
|
3388
|
+
dismissed.push(surfaceId);
|
|
3389
|
+
}
|
|
3390
|
+
}
|
|
3391
|
+
return dismissed;
|
|
3392
|
+
}
|
|
3393
|
+
|
|
3234
3394
|
// src/components/CustomComponents/A2uiRuntime/controller/meta.ts
|
|
3235
3395
|
function readProp(current, props, key) {
|
|
3236
3396
|
return current[key] ?? props?.[key];
|
|
@@ -3398,19 +3558,8 @@ function inferModelPathFromSurfaceCommands(surfaceId, commands) {
|
|
|
3398
3558
|
});
|
|
3399
3559
|
return commonParentPath(paths);
|
|
3400
3560
|
}
|
|
3401
|
-
function isSubmitLikeActionName(name) {
|
|
3402
|
-
const trimmed = typeof name === "string" ? name.trim() : "";
|
|
3403
|
-
return trimmed === "submit" || trimmed === "confirm" || trimmed.startsWith("submit_") || trimmed.endsWith(".confirm");
|
|
3404
|
-
}
|
|
3405
|
-
function isCancelLikeActionName(name) {
|
|
3406
|
-
const trimmed = typeof name === "string" ? name.trim() : "";
|
|
3407
|
-
return trimmed === "cancel" || trimmed === "qf.cancel" || trimmed.endsWith(".cancel");
|
|
3408
|
-
}
|
|
3409
3561
|
function shouldOptimisticallyDismissSurface(actionName, context) {
|
|
3410
|
-
|
|
3411
|
-
if (actionName === "qf.submit" || actionName === "qf.cancel") return true;
|
|
3412
|
-
const submitFlag = context?.submit;
|
|
3413
|
-
return submitFlag === true;
|
|
3562
|
+
return true;
|
|
3414
3563
|
}
|
|
3415
3564
|
function buildDispatchContext(surfaceId, rawContext, commands) {
|
|
3416
3565
|
let normalizedContext = normalizeActionContext(rawContext);
|
|
@@ -3709,6 +3858,7 @@ function buildWizardUpdateComponentsCommand(schema, stepId) {
|
|
|
3709
3858
|
function createA2uiRuntimeState() {
|
|
3710
3859
|
return {
|
|
3711
3860
|
processedMessageCursors: [],
|
|
3861
|
+
processedTagIds: [],
|
|
3712
3862
|
serverCommands: [],
|
|
3713
3863
|
localCommands: [],
|
|
3714
3864
|
anchorIndexBySurface: {},
|
|
@@ -3768,6 +3918,57 @@ function initializeWizardSurface(state, surfaceId, effects, nextWizardSteps) {
|
|
|
3768
3918
|
nextWizardSteps[surfaceId] = firstStepId.trim();
|
|
3769
3919
|
}
|
|
3770
3920
|
}
|
|
3921
|
+
function processA2uiCommand(cmd, messageIndex, messageId, nextState, effects, deletedSurfaceIds, nextWizardSteps) {
|
|
3922
|
+
nextState.serverCommands.push(cmd);
|
|
3923
|
+
nextState.lastA2uiHost = { id: messageId, index: messageIndex };
|
|
3924
|
+
const surfaceId = extractSurfaceId2(cmd);
|
|
3925
|
+
if (!surfaceId) return;
|
|
3926
|
+
if (cmd?.createSurface) {
|
|
3927
|
+
nextState.anchorIndexBySurface[surfaceId] = messageIndex;
|
|
3928
|
+
} else if (nextState.anchorIndexBySurface[surfaceId] === void 0 && !cmd?.deleteSurface) {
|
|
3929
|
+
nextState.anchorIndexBySurface[surfaceId] = messageIndex;
|
|
3930
|
+
}
|
|
3931
|
+
if (cmd?.createSurface) {
|
|
3932
|
+
nextState.latestCreateCommandIndexBySurface[surfaceId] = nextState.serverCommands.length - 1;
|
|
3933
|
+
nextState.optimisticallyDismissedSurfaceIds = nextState.optimisticallyDismissedSurfaceIds.filter((id) => id !== surfaceId);
|
|
3934
|
+
initializeWizardSurface(nextState, surfaceId, effects, nextWizardSteps);
|
|
3935
|
+
}
|
|
3936
|
+
if (cmd?.updateDataModel) {
|
|
3937
|
+
const { path, value } = cmd.updateDataModel;
|
|
3938
|
+
if (typeof path === "string" && path.trim() && value && typeof value === "object" && !Array.isArray(value)) {
|
|
3939
|
+
effects.push({ type: "write-model", modelPath: path, values: value });
|
|
3940
|
+
}
|
|
3941
|
+
}
|
|
3942
|
+
if (cmd?.deleteSurface) {
|
|
3943
|
+
deletedSurfaceIds.add(surfaceId);
|
|
3944
|
+
const modelPath = nextState.modelPathBySurface[surfaceId];
|
|
3945
|
+
if (modelPath) effects.push({ type: "clear-model", modelPath });
|
|
3946
|
+
delete nextState.initializedWizardRevisionBySurface[surfaceId];
|
|
3947
|
+
delete nextState.modelPathBySurface[surfaceId];
|
|
3948
|
+
}
|
|
3949
|
+
}
|
|
3950
|
+
function scanA2uiTagsFromMessages(messages, processedTagIds) {
|
|
3951
|
+
const newTags = [];
|
|
3952
|
+
const newTagIds = [];
|
|
3953
|
+
for (let messageIndex = 0; messageIndex < messages.length; messageIndex += 1) {
|
|
3954
|
+
const message2 = messages[messageIndex];
|
|
3955
|
+
const messageId = String(message2?.messageId ?? messageIndex);
|
|
3956
|
+
const items = Array.isArray(message2?.content) ? message2.content : [];
|
|
3957
|
+
for (const item of items) {
|
|
3958
|
+
if (item?.type !== "text") continue;
|
|
3959
|
+
const text = item.messageContent || item.text || "";
|
|
3960
|
+
if (typeof text !== "string" || !text.includes("<A2UI")) continue;
|
|
3961
|
+
const tags = parseA2uiTagsFromText(text);
|
|
3962
|
+
for (const tag of tags) {
|
|
3963
|
+
if (processedTagIds.has(tag.tagId)) continue;
|
|
3964
|
+
processedTagIds.add(tag.tagId);
|
|
3965
|
+
newTagIds.push(tag.tagId);
|
|
3966
|
+
newTags.push({ commands: tag.commands, messageIndex, messageId });
|
|
3967
|
+
}
|
|
3968
|
+
}
|
|
3969
|
+
}
|
|
3970
|
+
return { newTags, newTagIds };
|
|
3971
|
+
}
|
|
3771
3972
|
function reduceA2uiRuntimeMessages(state, messages) {
|
|
3772
3973
|
const { shouldReplayAll, pendingItems, nextCursors } = diffConversationMessages(messages || [], state.processedMessageCursors);
|
|
3773
3974
|
const itemsToProcess = shouldReplayAll ? messages.flatMap((message2, messageIndex) => {
|
|
@@ -3775,11 +3976,14 @@ function reduceA2uiRuntimeMessages(state, messages) {
|
|
|
3775
3976
|
const items = Array.isArray(message2?.content) ? message2.content : [];
|
|
3776
3977
|
return items.map((item) => ({ messageIndex, messageId, item }));
|
|
3777
3978
|
}) : pendingItems;
|
|
3778
|
-
|
|
3979
|
+
const tagProcessedSet = new Set(shouldReplayAll ? [] : state.processedTagIds);
|
|
3980
|
+
const { newTags, newTagIds } = scanA2uiTagsFromMessages(messages || [], tagProcessedSet);
|
|
3981
|
+
if (!shouldReplayAll && itemsToProcess.length === 0 && newTags.length === 0) {
|
|
3779
3982
|
return { state, effects: [] };
|
|
3780
3983
|
}
|
|
3781
3984
|
const nextState = shouldReplayAll ? createA2uiRuntimeState() : { ...state };
|
|
3782
3985
|
nextState.processedMessageCursors = shouldReplayAll ? [] : [...state.processedMessageCursors];
|
|
3986
|
+
nextState.processedTagIds = shouldReplayAll ? [] : [...state.processedTagIds, ...newTagIds];
|
|
3783
3987
|
nextState.serverCommands = shouldReplayAll ? [] : [...state.serverCommands];
|
|
3784
3988
|
nextState.localCommands = shouldReplayAll ? [] : [...state.localCommands];
|
|
3785
3989
|
nextState.anchorIndexBySurface = shouldReplayAll ? {} : { ...state.anchorIndexBySurface };
|
|
@@ -3802,24 +4006,13 @@ function reduceA2uiRuntimeMessages(state, messages) {
|
|
|
3802
4006
|
}
|
|
3803
4007
|
return;
|
|
3804
4008
|
}
|
|
3805
|
-
if (item?.type
|
|
3806
|
-
|
|
3807
|
-
|
|
3808
|
-
|
|
3809
|
-
|
|
3810
|
-
|
|
3811
|
-
nextState
|
|
3812
|
-
}
|
|
3813
|
-
if (item.command?.createSurface) {
|
|
3814
|
-
nextState.latestCreateCommandIndexBySurface[surfaceId] = nextState.serverCommands.length - 1;
|
|
3815
|
-
initializeWizardSurface(nextState, surfaceId, effects, nextWizardSteps);
|
|
3816
|
-
}
|
|
3817
|
-
if (item.command?.deleteSurface) {
|
|
3818
|
-
deletedSurfaceIds.add(surfaceId);
|
|
3819
|
-
const modelPath = nextState.modelPathBySurface[surfaceId];
|
|
3820
|
-
if (modelPath) effects.push({ type: "clear-model", modelPath });
|
|
3821
|
-
delete nextState.initializedWizardRevisionBySurface[surfaceId];
|
|
3822
|
-
delete nextState.modelPathBySurface[surfaceId];
|
|
4009
|
+
if (item?.type === "a2uiCommand" && item.command) {
|
|
4010
|
+
processA2uiCommand(item.command, messageIndex, messageId, nextState, effects, deletedSurfaceIds, nextWizardSteps);
|
|
4011
|
+
}
|
|
4012
|
+
});
|
|
4013
|
+
newTags.forEach(({ commands, messageIndex, messageId }) => {
|
|
4014
|
+
for (const cmd of commands) {
|
|
4015
|
+
processA2uiCommand(cmd, messageIndex, messageId, nextState, effects, deletedSurfaceIds, nextWizardSteps);
|
|
3823
4016
|
}
|
|
3824
4017
|
});
|
|
3825
4018
|
nextState.processedMessageCursors = shouldReplayAll ? messages.map((message2, messageIndex) => ({
|
|
@@ -3839,7 +4032,7 @@ function reduceA2uiRuntimeMessages(state, messages) {
|
|
|
3839
4032
|
return { state: nextState, effects };
|
|
3840
4033
|
}
|
|
3841
4034
|
function reduceA2uiRuntimeAction(state, input) {
|
|
3842
|
-
const { surfaceId, actionName
|
|
4035
|
+
const { surfaceId, actionName} = input;
|
|
3843
4036
|
if (!surfaceId) {
|
|
3844
4037
|
return { state, handled: actionName === "wizard.next" || actionName === "wizard.back" };
|
|
3845
4038
|
}
|
|
@@ -3869,9 +4062,6 @@ function reduceA2uiRuntimeAction(state, input) {
|
|
|
3869
4062
|
if (actionName === "wizard.next" || actionName === "wizard.back") {
|
|
3870
4063
|
return { state, handled: true };
|
|
3871
4064
|
}
|
|
3872
|
-
if (!shouldOptimisticallyDismissSurface(actionName, rawContext)) {
|
|
3873
|
-
return { state, handled: false };
|
|
3874
|
-
}
|
|
3875
4065
|
if (state.optimisticallyDismissedSurfaceIds.includes(surfaceId)) {
|
|
3876
4066
|
return { state, handled: false };
|
|
3877
4067
|
}
|
|
@@ -3936,12 +4126,20 @@ function useA2uiController(params) {
|
|
|
3936
4126
|
applyA2uiRuntimeEffects(result.effects);
|
|
3937
4127
|
setRuntimeState(result.state);
|
|
3938
4128
|
}, [conversationMessages, conversationId]);
|
|
3939
|
-
const
|
|
4129
|
+
const permanentDismissedSurfaceIds = useMemo(
|
|
4130
|
+
() => extractDismissedSurfaceIdsFromMessages(conversationMessages || []),
|
|
4131
|
+
[conversationMessages]
|
|
4132
|
+
);
|
|
4133
|
+
const mergedDismissedSurfaceIds = useMemo(
|
|
4134
|
+
() => Array.from(/* @__PURE__ */ new Set([...dismissedSurfaceIds || [], ...permanentDismissedSurfaceIds])),
|
|
4135
|
+
[dismissedSurfaceIds, permanentDismissedSurfaceIds]
|
|
4136
|
+
);
|
|
4137
|
+
const view = useMemo(() => selectA2uiRuntimeView(runtimeState, mergedDismissedSurfaceIds), [runtimeState, mergedDismissedSurfaceIds]);
|
|
3940
4138
|
const handleRuntimeAction = useCallback((payload) => {
|
|
3941
4139
|
const surfaceId = String(payload?.surfaceId || payload?.cardId || "");
|
|
3942
4140
|
const name = String(payload?.name || payload?.event?.name || "").trim();
|
|
3943
4141
|
const rawContext = payload?.context || payload?.event?.context || {};
|
|
3944
|
-
const runtimeActionResult = reduceA2uiRuntimeAction(runtimeRef.current, { surfaceId, actionName: name
|
|
4142
|
+
const runtimeActionResult = reduceA2uiRuntimeAction(runtimeRef.current, { surfaceId, actionName: name});
|
|
3945
4143
|
if (runtimeActionResult.state !== runtimeRef.current) {
|
|
3946
4144
|
runtimeRef.current = runtimeActionResult.state;
|
|
3947
4145
|
setRuntimeState(runtimeActionResult.state);
|
|
@@ -3968,26 +4166,26 @@ var A2uiRuntimeContext = React10__default.createContext({
|
|
|
3968
4166
|
function useA2uiRuntimeView() {
|
|
3969
4167
|
return React10__default.useContext(A2uiRuntimeContext);
|
|
3970
4168
|
}
|
|
3971
|
-
function A2uiMessageCards({ messageIndex }) {
|
|
4169
|
+
function A2uiMessageCards({ messageIndex, message: message2 }) {
|
|
3972
4170
|
const { surfaceIdsByMessageIndex } = useA2uiRuntimeView();
|
|
3973
|
-
const
|
|
4171
|
+
const allSurfaceIds = surfaceIdsByMessageIndex[messageIndex] || [];
|
|
4172
|
+
const inlineSurfaceIds = message2 ? extractInlineSurfaceIdsFromMessage(message2) : /* @__PURE__ */ new Set();
|
|
4173
|
+
const surfaceIds = allSurfaceIds.filter((id) => !inlineSurfaceIds.has(id));
|
|
3974
4174
|
if (!surfaceIds.length) return null;
|
|
3975
4175
|
return /* @__PURE__ */ jsx("div", { children: surfaceIds.map((surfaceId) => /* @__PURE__ */ jsx(XCard.Card, { id: surfaceId }, surfaceId)) });
|
|
3976
4176
|
}
|
|
3977
4177
|
|
|
3978
4178
|
// src/components/CustomComponents/A2uiRuntime/renderer/protocol.ts
|
|
3979
|
-
function
|
|
4179
|
+
function isSubmitLikeActionName(name) {
|
|
3980
4180
|
const normalized = String(name || "").trim();
|
|
3981
4181
|
return normalized === "submit" || normalized === "confirm" || normalized.startsWith("submit_") || normalized.endsWith(".confirm");
|
|
3982
4182
|
}
|
|
3983
|
-
function
|
|
4183
|
+
function isCancelLikeActionName(name) {
|
|
3984
4184
|
const normalized = String(name || "").trim();
|
|
3985
4185
|
return normalized === "cancel" || normalized === "qf.cancel" || normalized.endsWith(".cancel");
|
|
3986
4186
|
}
|
|
3987
4187
|
function shouldDismissA2uiSurface(name, context) {
|
|
3988
|
-
|
|
3989
|
-
if (name === "qf.submit" || name === "qf.cancel") return true;
|
|
3990
|
-
return context?.submit === true;
|
|
4188
|
+
return true;
|
|
3991
4189
|
}
|
|
3992
4190
|
function normalizeA2uiActionPayload(payload) {
|
|
3993
4191
|
return {
|
|
@@ -4021,7 +4219,7 @@ function isQuestionActionPayload(payload) {
|
|
|
4021
4219
|
const mode = payload.context?.form_mode;
|
|
4022
4220
|
if (payload.name === "qf.submit" || payload.name === "qf.cancel") return true;
|
|
4023
4221
|
if (payload.name.startsWith("qf.")) return true;
|
|
4024
|
-
return typeof mode === "string" && mode.toLowerCase() === "ephemeral" ?
|
|
4222
|
+
return typeof mode === "string" && mode.toLowerCase() === "ephemeral" ? isSubmitLikeActionName(payload.name) || isCancelLikeActionName(payload.name) : false;
|
|
4025
4223
|
}
|
|
4026
4224
|
function formatActionValue(value, displayOverride) {
|
|
4027
4225
|
if (typeof displayOverride === "string" && displayOverride.trim()) return displayOverride.trim();
|
|
@@ -4031,7 +4229,7 @@ function formatActionValue(value, displayOverride) {
|
|
|
4031
4229
|
return String(value);
|
|
4032
4230
|
}
|
|
4033
4231
|
function buildQuestionSummary(payload) {
|
|
4034
|
-
if (
|
|
4232
|
+
if (isCancelLikeActionName(payload.name)) return "Question: \u5DF2\u53D6\u6D88";
|
|
4035
4233
|
const values = payload.context.values && typeof payload.context.values === "object" && !Array.isArray(payload.context.values) ? payload.context.values : payload.context;
|
|
4036
4234
|
const labels = payload.context.labels && typeof payload.context.labels === "object" && !Array.isArray(payload.context.labels) ? payload.context.labels : {};
|
|
4037
4235
|
const valueLabels = payload.context.valueLabels && typeof payload.context.valueLabels === "object" && !Array.isArray(payload.context.valueLabels) ? payload.context.valueLabels : {};
|
|
@@ -4053,10 +4251,22 @@ function formatA2uiActionDisplayText(payload) {
|
|
|
4053
4251
|
back_to_params: "\u5DF2\u8FD4\u56DE\u4FEE\u6539\u53C2\u6570",
|
|
4054
4252
|
confirm: "\u5DF2\u786E\u8BA4\u521B\u5EFA"
|
|
4055
4253
|
};
|
|
4056
|
-
|
|
4254
|
+
let actionLabel = actionLabels[payload.name];
|
|
4255
|
+
if (!actionLabel) {
|
|
4256
|
+
if (payload.name.startsWith("confirm_")) {
|
|
4257
|
+
actionLabel = "\u5DF2\u9009\u62E9";
|
|
4258
|
+
} else if (payload.name.startsWith("submit_")) {
|
|
4259
|
+
actionLabel = "\u5DF2\u63D0\u4EA4";
|
|
4260
|
+
} else {
|
|
4261
|
+
actionLabel = `\u5DF2\u63D0\u4EA4\u52A8\u4F5C (${payload.name})`;
|
|
4262
|
+
}
|
|
4263
|
+
}
|
|
4264
|
+
const isConfirmLike = payload.name.startsWith("confirm_");
|
|
4057
4265
|
const details = Object.entries(values).filter(([, value]) => value !== null && value !== void 0 && value !== "").map(([key, value]) => {
|
|
4266
|
+
const formatted = formatActionValue(value, valueLabels[key]);
|
|
4267
|
+
if (isConfirmLike) return formatted;
|
|
4058
4268
|
const label = typeof labels[key] === "string" && String(labels[key]).trim() ? String(labels[key]).trim() : key;
|
|
4059
|
-
return `${label}: ${
|
|
4269
|
+
return `${label}: ${formatted}`;
|
|
4060
4270
|
});
|
|
4061
4271
|
return details.length ? `${actionLabel}\uFF1A${details.join("\uFF1B ")}` : actionLabel;
|
|
4062
4272
|
}
|
|
@@ -4154,66 +4364,46 @@ function readContextModelPath(context) {
|
|
|
4154
4364
|
const path = context?.model && typeof context.model === "object" ? context.model.path : "";
|
|
4155
4365
|
return typeof path === "string" ? path.trim() : "";
|
|
4156
4366
|
}
|
|
4157
|
-
function
|
|
4158
|
-
|
|
4159
|
-
|
|
4160
|
-
|
|
4161
|
-
const nextCursors = [];
|
|
4162
|
-
const pendingItems = [];
|
|
4163
|
-
for (let messageIndex = 0; messageIndex < messages.length; messageIndex += 1) {
|
|
4164
|
-
const message2 = messages[messageIndex];
|
|
4165
|
-
const messageId = String(message2?.messageId ?? messageIndex);
|
|
4367
|
+
function buildLatestCommandIndexBySurface(messages) {
|
|
4368
|
+
const indexBySurface = {};
|
|
4369
|
+
let commandIndex = -1;
|
|
4370
|
+
for (const message2 of messages) {
|
|
4166
4371
|
const items = Array.isArray(message2?.content) ? message2.content : [];
|
|
4167
|
-
const
|
|
4168
|
-
|
|
4169
|
-
|
|
4170
|
-
|
|
4171
|
-
|
|
4172
|
-
|
|
4173
|
-
|
|
4372
|
+
for (const item of items) {
|
|
4373
|
+
if (item?.type === "a2uiCommand" && item.command) {
|
|
4374
|
+
commandIndex += 1;
|
|
4375
|
+
const surfaceId = extractSurfaceId3(item.command);
|
|
4376
|
+
if (surfaceId) indexBySurface[surfaceId] = commandIndex;
|
|
4377
|
+
continue;
|
|
4378
|
+
}
|
|
4379
|
+
if (item?.type === "text") {
|
|
4380
|
+
const text = item.messageContent || item.text || "";
|
|
4381
|
+
if (typeof text !== "string" || !text.includes("<A2UI")) continue;
|
|
4382
|
+
const tags = parseA2uiTagsFromText(text);
|
|
4383
|
+
for (const tag of tags) {
|
|
4384
|
+
for (const cmd of tag.commands) {
|
|
4385
|
+
commandIndex += 1;
|
|
4386
|
+
const surfaceId = extractSurfaceId3(cmd);
|
|
4387
|
+
if (surfaceId) indexBySurface[surfaceId] = commandIndex;
|
|
4388
|
+
}
|
|
4389
|
+
}
|
|
4390
|
+
}
|
|
4174
4391
|
}
|
|
4175
|
-
nextCursors.push({ messageId, contentLength: items.length });
|
|
4176
4392
|
}
|
|
4177
|
-
return
|
|
4393
|
+
return indexBySurface;
|
|
4178
4394
|
}
|
|
4179
4395
|
function A2uiRuntimeProvider({ messages, children }) {
|
|
4180
4396
|
const chatStore = useChatStore();
|
|
4181
4397
|
const conversationState = useSnapshot(chatStore.conversation);
|
|
4182
4398
|
const conversationId = conversationState.active.id;
|
|
4183
|
-
const processedMessageCursorsRef = React10__default.useRef([]);
|
|
4184
|
-
const latestCommandIndexBySurfaceRef = React10__default.useRef({});
|
|
4185
|
-
const commandIndexRef = React10__default.useRef(-1);
|
|
4186
4399
|
const [latestCommandIndexBySurface, setLatestCommandIndexBySurface] = React10__default.useState({});
|
|
4187
4400
|
const [dismissedAtBySurface, setDismissedAtBySurface] = React10__default.useState({});
|
|
4188
4401
|
React10__default.useEffect(() => {
|
|
4189
|
-
processedMessageCursorsRef.current = [];
|
|
4190
|
-
latestCommandIndexBySurfaceRef.current = {};
|
|
4191
|
-
commandIndexRef.current = -1;
|
|
4192
4402
|
setLatestCommandIndexBySurface({});
|
|
4193
4403
|
setDismissedAtBySurface({});
|
|
4194
4404
|
}, [conversationId]);
|
|
4195
4405
|
React10__default.useEffect(() => {
|
|
4196
|
-
|
|
4197
|
-
const itemsToProcess = shouldReplayAll ? messages.flatMap((message2) => {
|
|
4198
|
-
const items = Array.isArray(message2?.content) ? message2.content : [];
|
|
4199
|
-
return items.map((item) => ({ item }));
|
|
4200
|
-
}) : pendingItems;
|
|
4201
|
-
if (!shouldReplayAll && itemsToProcess.length === 0) return;
|
|
4202
|
-
const nextLatestCommandIndexBySurface = shouldReplayAll ? {} : { ...latestCommandIndexBySurfaceRef.current };
|
|
4203
|
-
let nextCommandIndex = shouldReplayAll ? -1 : commandIndexRef.current;
|
|
4204
|
-
itemsToProcess.forEach(({ item }) => {
|
|
4205
|
-
if (item?.type !== "a2uiCommand" || !item.command) return;
|
|
4206
|
-
nextCommandIndex += 1;
|
|
4207
|
-
const surfaceId = extractSurfaceId3(item.command);
|
|
4208
|
-
if (surfaceId) nextLatestCommandIndexBySurface[surfaceId] = nextCommandIndex;
|
|
4209
|
-
});
|
|
4210
|
-
processedMessageCursorsRef.current = shouldReplayAll ? messages.map((message2, messageIndex) => ({
|
|
4211
|
-
messageId: String(message2?.messageId ?? messageIndex),
|
|
4212
|
-
contentLength: Array.isArray(message2?.content) ? message2.content.length : 0
|
|
4213
|
-
})) : nextCursors;
|
|
4214
|
-
latestCommandIndexBySurfaceRef.current = nextLatestCommandIndexBySurface;
|
|
4215
|
-
commandIndexRef.current = nextCommandIndex;
|
|
4216
|
-
setLatestCommandIndexBySurface(nextLatestCommandIndexBySurface);
|
|
4406
|
+
setLatestCommandIndexBySurface(buildLatestCommandIndexBySurface(messages));
|
|
4217
4407
|
}, [messages]);
|
|
4218
4408
|
const dismissedSurfaceIds = React10__default.useMemo(() => {
|
|
4219
4409
|
return Object.entries(dismissedAtBySurface).filter(([surfaceId, dismissedAt]) => (latestCommandIndexBySurface[surfaceId] ?? -1) <= dismissedAt).map(([surfaceId]) => surfaceId);
|
|
@@ -4270,11 +4460,13 @@ function A2uiRenderer(props) {
|
|
|
4270
4460
|
var FilesNode = React10__default.memo(({ item }) => {
|
|
4271
4461
|
const chatStore = useChatStore();
|
|
4272
4462
|
const configState = useSnapshot(chatStore.config);
|
|
4273
|
-
useSnapshot(chatStore.agent);
|
|
4274
4463
|
const conversationState = useSnapshot(chatStore.conversation);
|
|
4275
4464
|
const fileItems = useMemo(() => {
|
|
4276
4465
|
return (item.files || []).map((file) => {
|
|
4277
|
-
const previewUrl = configState.services.request.getPreviewUrl(
|
|
4466
|
+
const previewUrl = configState.services.request.getPreviewUrl({
|
|
4467
|
+
path: file.path,
|
|
4468
|
+
workspaceId: conversationState.active.id
|
|
4469
|
+
});
|
|
4278
4470
|
let fileType = "file";
|
|
4279
4471
|
const ext = file.ext?.toLowerCase() || "";
|
|
4280
4472
|
if (["jpg", "jpeg", "png", "gif", "bmp", "webp", "svg", "webp"].includes(ext)) {
|
|
@@ -4340,14 +4532,37 @@ function QuestionSummary({ content }) {
|
|
|
4340
4532
|
] });
|
|
4341
4533
|
}
|
|
4342
4534
|
var TextNode2 = React10__default.memo(
|
|
4343
|
-
({
|
|
4344
|
-
|
|
4345
|
-
|
|
4346
|
-
|
|
4535
|
+
({
|
|
4536
|
+
item,
|
|
4537
|
+
role,
|
|
4538
|
+
customComponents,
|
|
4539
|
+
message: message2,
|
|
4540
|
+
messageIndex = -1
|
|
4541
|
+
}) => {
|
|
4542
|
+
const { surfaceIdsByMessageIndex } = useA2uiRuntimeView();
|
|
4543
|
+
const rawContent = toA2uiDisplayText(role, item?.messageContent);
|
|
4544
|
+
const segments = splitA2uiTextSegments(rawContent);
|
|
4545
|
+
const visibleSurfaceIds = messageIndex >= 0 ? new Set(surfaceIdsByMessageIndex[messageIndex] || []) : null;
|
|
4546
|
+
const firstSeg = segments[0];
|
|
4547
|
+
const isPureText = segments.length === 0 || segments.length === 1 && firstSeg.type === "text";
|
|
4548
|
+
if (isPureText) {
|
|
4549
|
+
const content = firstSeg && firstSeg.type === "text" ? firstSeg.content : "";
|
|
4550
|
+
if (typeof content === "string" && content.startsWith("Question:")) {
|
|
4551
|
+
return /* @__PURE__ */ jsx(QuestionSummary, { content });
|
|
4552
|
+
}
|
|
4553
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4554
|
+
!!item.reasoningContent && /* @__PURE__ */ jsx(Think, { title: "\u6DF1\u5EA6\u601D\u8003", children: item.reasoningContent }),
|
|
4555
|
+
!!content && /* @__PURE__ */ jsx(XMarkdown_default, { message: message2, components: customComponents, content })
|
|
4556
|
+
] });
|
|
4347
4557
|
}
|
|
4348
4558
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4349
4559
|
!!item.reasoningContent && /* @__PURE__ */ jsx(Think, { title: "\u6DF1\u5EA6\u601D\u8003", children: item.reasoningContent }),
|
|
4350
|
-
|
|
4560
|
+
segments.map((seg, i) => {
|
|
4561
|
+
if (seg.type === "text") {
|
|
4562
|
+
return seg.content.trim() ? /* @__PURE__ */ jsx(XMarkdown_default, { message: message2, components: customComponents, content: seg.content }, `text-${i}`) : null;
|
|
4563
|
+
}
|
|
4564
|
+
return seg.surfaceIds.filter((sid) => !visibleSurfaceIds || visibleSurfaceIds.has(sid)).map((sid) => /* @__PURE__ */ jsx(XCard.Card, { id: sid }, `a2ui-${i}-${sid}`));
|
|
4565
|
+
})
|
|
4351
4566
|
] });
|
|
4352
4567
|
}
|
|
4353
4568
|
);
|
|
@@ -4575,6 +4790,12 @@ var MessageRender_default = React10__default.memo(({ role, message: message2, me
|
|
|
4575
4790
|
if (item.type === "plan") {
|
|
4576
4791
|
return !shouldHideA2uiPlan(item);
|
|
4577
4792
|
}
|
|
4793
|
+
if (item.type === "text") {
|
|
4794
|
+
const rawText = item.messageContent || item.text || "";
|
|
4795
|
+
const visibleText = stripA2uiTags(rawText);
|
|
4796
|
+
const hasA2uiTag2 = typeof rawText === "string" && rawText.includes("<A2UI");
|
|
4797
|
+
return !!visibleText.trim() || !!item.reasoningContent || hasA2uiTag2;
|
|
4798
|
+
}
|
|
4578
4799
|
return true;
|
|
4579
4800
|
});
|
|
4580
4801
|
}, [loading, message2.content]);
|
|
@@ -4603,7 +4824,7 @@ var MessageRender_default = React10__default.memo(({ role, message: message2, me
|
|
|
4603
4824
|
content: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4604
4825
|
item.type === "runStarted" && /* @__PURE__ */ jsx(RunStartedNode, { loading }, `flow-start-${index}`),
|
|
4605
4826
|
(item.type === "toolCall" || item.type === "toolResult") && /* @__PURE__ */ jsx(tool_call_item_default, { item }, `tool-call-${item.toolCallId || index}`),
|
|
4606
|
-
item.type === "text" && /* @__PURE__ */ jsx(TextNode2, { item, role: message2.role, customComponents, message: message2 }, `message-${index}`),
|
|
4827
|
+
item.type === "text" && /* @__PURE__ */ jsx(TextNode2, { item, role: message2.role, customComponents, message: message2, messageIndex }, `message-${index}`),
|
|
4607
4828
|
item.type === "stepError" && (item.errorMessage ? /* @__PURE__ */ jsx(XMarkdown_default, { message: message2, components: customComponents, content: item.errorMessage }) : null),
|
|
4608
4829
|
item.type === "files" && /* @__PURE__ */ jsx(FilesNode, { item }, `files-${index}`),
|
|
4609
4830
|
item.type === "plan" && /* @__PURE__ */ jsx(A2uiPlanNode, { item }, `plan-${index}`)
|
|
@@ -4613,7 +4834,7 @@ var MessageRender_default = React10__default.memo(({ role, message: message2, me
|
|
|
4613
4834
|
);
|
|
4614
4835
|
}),
|
|
4615
4836
|
quoteMsg && /* @__PURE__ */ jsx(QuoteMsgNode, { quoteMsg, role }),
|
|
4616
|
-
messageIndex >= 0 ? /* @__PURE__ */ jsx(A2uiMessageCards, { messageIndex }) : null
|
|
4837
|
+
messageIndex >= 0 ? /* @__PURE__ */ jsx(A2uiMessageCards, { messageIndex, message: message2 }) : null
|
|
4617
4838
|
] });
|
|
4618
4839
|
});
|
|
4619
4840
|
var WelcomeItem_default = ({ icon = true, title = true, description = true, prompts = true }) => {
|
|
@@ -5555,6 +5776,6 @@ var layouts_default = forwardRef(({ theme: theme4, params, hooks, layout, config
|
|
|
5555
5776
|
] }) }) }) });
|
|
5556
5777
|
});
|
|
5557
5778
|
|
|
5558
|
-
export { Attachments_default as Attachments, layouts_default as ChatCopilot, ChatSender_default as ChatSender };
|
|
5779
|
+
export { Attachments_default as Attachments, layouts_default as ChatCopilot, ChatSender_default as ChatSender, getFileIcon, getFileUrl };
|
|
5559
5780
|
//# sourceMappingURL=index.esm.js.map
|
|
5560
5781
|
//# sourceMappingURL=index.esm.js.map
|