@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.cjs.js
CHANGED
|
@@ -158,7 +158,10 @@ var Attachments_default = React10.forwardRef(({ fileUpload, fileUploadConfig, fi
|
|
|
158
158
|
const uploadedFile = data[0];
|
|
159
159
|
let previewUrl = uploadedFile.id;
|
|
160
160
|
if (uploadedFile.conversationId && uploadedFile.path) {
|
|
161
|
-
previewUrl = chatStore.config.services.request.getPreviewUrl(
|
|
161
|
+
previewUrl = chatStore.config.services.request.getPreviewUrl({
|
|
162
|
+
path: uploadedFile.path,
|
|
163
|
+
workspaceId: uploadedFile.conversationId
|
|
164
|
+
});
|
|
162
165
|
}
|
|
163
166
|
setAttachedFiles(
|
|
164
167
|
getAttachedFiles().map((f) => {
|
|
@@ -251,8 +254,12 @@ var index_module_default = {
|
|
|
251
254
|
promptEditorPlaceholder: "index_module_promptEditorPlaceholder",
|
|
252
255
|
resourceSelect: "index_module_resourceSelect",
|
|
253
256
|
fileMenu: "index_module_fileMenu",
|
|
257
|
+
fileMenuGroup: "index_module_fileMenuGroup",
|
|
258
|
+
fileMenuGroupTitle: "index_module_fileMenuGroupTitle",
|
|
259
|
+
fileMenuEmpty: "index_module_fileMenuEmpty",
|
|
254
260
|
fileMenuItem: "index_module_fileMenuItem",
|
|
255
261
|
fileMenuItemActive: "index_module_fileMenuItemActive",
|
|
262
|
+
fileIcon: "index_module_fileIcon",
|
|
256
263
|
fileName: "index_module_fileName",
|
|
257
264
|
resourceTag: "index_module_resourceTag"
|
|
258
265
|
};
|
|
@@ -260,6 +267,16 @@ var index_module_default = {
|
|
|
260
267
|
// src/core/constants.ts
|
|
261
268
|
var CONV_MODE = {
|
|
262
269
|
PROD: 1};
|
|
270
|
+
var TOKEN_KEY = "NS-TOKEN";
|
|
271
|
+
var tokenManager = common.createTokenManager({
|
|
272
|
+
key: TOKEN_KEY
|
|
273
|
+
});
|
|
274
|
+
var redirectUrl = () => {
|
|
275
|
+
const path = localStorage.getItem("SIGNPATH");
|
|
276
|
+
common.emit("jumpLink", { url: `/uc${path || "/sign-in"}` });
|
|
277
|
+
};
|
|
278
|
+
|
|
279
|
+
// src/core/utils.ts
|
|
263
280
|
var classifyTime = (timestamp) => {
|
|
264
281
|
const now = dayjs__default.default();
|
|
265
282
|
const target = dayjs__default.default(timestamp);
|
|
@@ -306,27 +323,52 @@ var getFileIcon = (extension, fontSize = 24) => {
|
|
|
306
323
|
}
|
|
307
324
|
return createIcon(icons.FileUnknownOutlined, "#94a3b8");
|
|
308
325
|
};
|
|
309
|
-
|
|
310
|
-
|
|
326
|
+
var getFileUrl = (params, baseUrl, url) => {
|
|
327
|
+
const data = {
|
|
328
|
+
[TOKEN_KEY]: tokenManager.get(),
|
|
329
|
+
workspaceType: "conversation" /* CONVERSATION */,
|
|
330
|
+
...params
|
|
331
|
+
};
|
|
332
|
+
return common.buildUrlParams(data, url || `${baseUrl}/files/access`);
|
|
333
|
+
};
|
|
334
|
+
function GroupPicker({
|
|
335
|
+
groups,
|
|
311
336
|
selectedIndex,
|
|
312
337
|
onSelect,
|
|
313
338
|
onHover
|
|
314
339
|
}) {
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
"
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
340
|
+
const itemRefs = React10.useRef([]);
|
|
341
|
+
let currentIndex = -1;
|
|
342
|
+
React10.useEffect(() => {
|
|
343
|
+
itemRefs.current[selectedIndex]?.scrollIntoView({
|
|
344
|
+
block: "nearest"
|
|
345
|
+
});
|
|
346
|
+
}, [groups, selectedIndex]);
|
|
347
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: index_module_default.fileMenu, role: "listbox", children: groups.map(({ group, options }) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: index_module_default.fileMenuGroup, children: [
|
|
348
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: index_module_default.fileMenuGroupTitle, children: group.label }),
|
|
349
|
+
options.length ? options.map((option) => {
|
|
350
|
+
currentIndex += 1;
|
|
351
|
+
const optionIndex = currentIndex;
|
|
352
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
353
|
+
"div",
|
|
354
|
+
{
|
|
355
|
+
ref: (element) => {
|
|
356
|
+
itemRefs.current[optionIndex] = element;
|
|
357
|
+
},
|
|
358
|
+
role: "option",
|
|
359
|
+
"aria-selected": optionIndex === selectedIndex,
|
|
360
|
+
className: `${index_module_default.fileMenuItem} ${optionIndex === selectedIndex ? index_module_default.fileMenuItemActive : ""}`,
|
|
361
|
+
onMouseEnter: () => onHover(optionIndex),
|
|
362
|
+
onClick: () => onSelect(group, option),
|
|
363
|
+
children: [
|
|
364
|
+
option.ext && /* @__PURE__ */ jsxRuntime.jsx("span", { className: index_module_default.fileIcon, children: getFileIcon(option.ext, 14) }),
|
|
365
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: index_module_default.fileName, children: option.label })
|
|
366
|
+
]
|
|
367
|
+
},
|
|
368
|
+
`${group.value}-${option.value}`
|
|
369
|
+
);
|
|
370
|
+
}) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: index_module_default.fileMenuEmpty, children: "\u6682\u65E0\u6570\u636E" })
|
|
371
|
+
] }, group.value)) });
|
|
330
372
|
}
|
|
331
373
|
function ResourcePickerMenu({
|
|
332
374
|
anchorElementRef,
|
|
@@ -375,7 +417,6 @@ function ResourceTag({ resource }) {
|
|
|
375
417
|
formatResourceName(resource.resourceName)
|
|
376
418
|
] }) });
|
|
377
419
|
}
|
|
378
|
-
var EMPTY_CASCADE_OPTION_VALUE = "__empty__";
|
|
379
420
|
var VariableNode = class _VariableNode extends lexical.DecoratorNode {
|
|
380
421
|
__resourceLabel;
|
|
381
422
|
__resourceType;
|
|
@@ -466,34 +507,25 @@ var VariableNode = class _VariableNode extends lexical.DecoratorNode {
|
|
|
466
507
|
function $createVariableNode(resourceLabel, resourceName, resourceType, resourceId) {
|
|
467
508
|
return new VariableNode(resourceLabel, resourceName, resourceType, resourceId);
|
|
468
509
|
}
|
|
469
|
-
var
|
|
470
|
-
|
|
510
|
+
var ResourceOption = class extends LexicalTypeaheadMenuPlugin.MenuOption {
|
|
511
|
+
group;
|
|
471
512
|
item;
|
|
472
513
|
/**
|
|
473
|
-
*
|
|
514
|
+
* 将分组列表中的资源节点包装成 Lexical 菜单选项对象。
|
|
474
515
|
*/
|
|
475
|
-
constructor(
|
|
476
|
-
super(`${
|
|
477
|
-
this.
|
|
516
|
+
constructor(group, item) {
|
|
517
|
+
super(`${group.value}:${item.value}`);
|
|
518
|
+
this.group = group;
|
|
478
519
|
this.item = item;
|
|
479
520
|
}
|
|
480
521
|
};
|
|
481
|
-
var FileOption = class extends LexicalTypeaheadMenuPlugin.MenuOption {
|
|
482
|
-
file;
|
|
483
|
-
/**
|
|
484
|
-
* 将文件列表项包装成 Lexical 菜单选项对象。
|
|
485
|
-
*/
|
|
486
|
-
constructor(file) {
|
|
487
|
-
super(file.value);
|
|
488
|
-
this.file = file;
|
|
489
|
-
}
|
|
490
|
-
};
|
|
491
522
|
function VariablePickerPlugin({ commandConfig = {} }) {
|
|
492
523
|
const [editor] = LexicalComposerContext.useLexicalComposerContext();
|
|
493
524
|
const chatStore = useChatStore();
|
|
494
525
|
const [commandDataSource, setCommandDataSource] = React10.useState(commandConfig);
|
|
495
526
|
const [queryString, setQueryString] = React10.useState(null);
|
|
496
527
|
const [isEditorFocused, setIsEditorFocused] = React10.useState(false);
|
|
528
|
+
const [menuResetKey, setMenuResetKey] = React10.useState(0);
|
|
497
529
|
const blurTimerRef = React10.useRef(null);
|
|
498
530
|
React10.useEffect(() => {
|
|
499
531
|
const unregister = utils.mergeRegister(
|
|
@@ -510,6 +542,7 @@ function VariablePickerPlugin({ commandConfig = {} }) {
|
|
|
510
542
|
lexical.BLUR_COMMAND,
|
|
511
543
|
() => {
|
|
512
544
|
setIsEditorFocused(false);
|
|
545
|
+
setMenuResetKey((current) => current + 1);
|
|
513
546
|
return false;
|
|
514
547
|
},
|
|
515
548
|
lexical.COMMAND_PRIORITY_LOW
|
|
@@ -524,6 +557,7 @@ function VariablePickerPlugin({ commandConfig = {} }) {
|
|
|
524
557
|
setCommandDataSource(commandConfig);
|
|
525
558
|
}, [commandConfig]);
|
|
526
559
|
const commandKey = queryString?.[0] || "";
|
|
560
|
+
const searchKeyword = queryString?.slice(commandKey.length).trim().toLocaleLowerCase() || "";
|
|
527
561
|
const categoryConfig = React10.useMemo(
|
|
528
562
|
() => ({
|
|
529
563
|
skill: {
|
|
@@ -541,58 +575,82 @@ function VariablePickerPlugin({ commandConfig = {} }) {
|
|
|
541
575
|
}),
|
|
542
576
|
[chatStore]
|
|
543
577
|
);
|
|
544
|
-
const commandOptions = React10.useMemo(() => {
|
|
545
|
-
if (!isEditorFocused) return [];
|
|
546
|
-
return (commandDataSource[commandKey]?.dataSource || []).flatMap(
|
|
547
|
-
(category) => category.children?.filter((item) => !item.disabled).map((item) => new CascadeOption(category, item)) || []
|
|
548
|
-
);
|
|
549
|
-
}, [commandDataSource, commandKey, isEditorFocused]);
|
|
550
578
|
const formatDataSource = React10.useCallback(
|
|
551
579
|
(items, category) => {
|
|
552
580
|
const currentCategoryConfig = categoryConfig[category.value];
|
|
553
|
-
if (!items.length)
|
|
554
|
-
return [
|
|
555
|
-
{
|
|
556
|
-
value: EMPTY_CASCADE_OPTION_VALUE,
|
|
557
|
-
label: "\u6682\u65E0\u6570\u636E",
|
|
558
|
-
isLeaf: true,
|
|
559
|
-
disabled: true
|
|
560
|
-
}
|
|
561
|
-
];
|
|
562
|
-
}
|
|
581
|
+
if (!items.length) return [];
|
|
563
582
|
return items.map((item) => ({
|
|
564
583
|
value: item.id,
|
|
565
|
-
label: currentCategoryConfig?.getLabel(item) || item.name
|
|
584
|
+
label: currentCategoryConfig?.getLabel(item) || item.name,
|
|
585
|
+
children: []
|
|
566
586
|
}));
|
|
567
587
|
},
|
|
568
588
|
[categoryConfig]
|
|
569
589
|
);
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
(
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
+
React10.useEffect(() => {
|
|
591
|
+
let isUnmounted = false;
|
|
592
|
+
const initializeCommandDataSource = async () => {
|
|
593
|
+
const nextEntries = await Promise.all(
|
|
594
|
+
Object.entries(commandConfig).map(async ([trigger, currentCommandConfig]) => {
|
|
595
|
+
const nextDataSource = await Promise.all(
|
|
596
|
+
(currentCommandConfig.dataSource || []).map(async (category) => {
|
|
597
|
+
const normalizedChildren = category.children || [];
|
|
598
|
+
const nextCategory = {
|
|
599
|
+
...category,
|
|
600
|
+
children: normalizedChildren
|
|
601
|
+
};
|
|
602
|
+
const currentCategoryConfig = categoryConfig[category.value];
|
|
603
|
+
if (!currentCategoryConfig) {
|
|
604
|
+
return nextCategory;
|
|
605
|
+
}
|
|
606
|
+
if (normalizedChildren.length) {
|
|
607
|
+
return nextCategory;
|
|
608
|
+
}
|
|
609
|
+
const response = await currentCategoryConfig.load();
|
|
610
|
+
const items = response.data || [];
|
|
611
|
+
return {
|
|
612
|
+
...nextCategory,
|
|
613
|
+
children: formatDataSource(items, category)
|
|
614
|
+
};
|
|
615
|
+
})
|
|
616
|
+
);
|
|
617
|
+
return [
|
|
618
|
+
trigger,
|
|
619
|
+
{
|
|
620
|
+
...currentCommandConfig,
|
|
621
|
+
dataSource: nextDataSource
|
|
622
|
+
}
|
|
623
|
+
];
|
|
624
|
+
})
|
|
625
|
+
);
|
|
626
|
+
if (isUnmounted) return;
|
|
627
|
+
setCommandDataSource(Object.fromEntries(nextEntries));
|
|
628
|
+
};
|
|
629
|
+
initializeCommandDataSource();
|
|
630
|
+
return () => {
|
|
631
|
+
isUnmounted = true;
|
|
632
|
+
};
|
|
633
|
+
}, [categoryConfig, commandConfig, formatDataSource]);
|
|
634
|
+
const commandGroups = React10.useMemo(() => {
|
|
635
|
+
if (!isEditorFocused) return [];
|
|
636
|
+
return (commandDataSource[commandKey]?.dataSource || []).map((group) => {
|
|
637
|
+
const options = group.children || [];
|
|
638
|
+
if (!searchKeyword) return { group, options };
|
|
639
|
+
return {
|
|
640
|
+
group,
|
|
641
|
+
options: options.filter((option) => option.label.toLocaleLowerCase().includes(searchKeyword))
|
|
642
|
+
};
|
|
643
|
+
}).filter(({ options }) => !searchKeyword || options.length);
|
|
644
|
+
}, [commandDataSource, commandKey, isEditorFocused, searchKeyword]);
|
|
645
|
+
const commandOptions = React10.useMemo(
|
|
646
|
+
() => commandGroups.flatMap(({ group, options }) => options.map((item) => new ResourceOption(group, item))),
|
|
647
|
+
[commandGroups]
|
|
590
648
|
);
|
|
591
649
|
const onSelectOption = React10.useCallback(
|
|
592
650
|
(selectedOption, nodeToReplace, closeMenu, matchingString) => {
|
|
593
|
-
const resource = selectedOption
|
|
594
|
-
const resourceLabel = selectedOption
|
|
595
|
-
const resourceType = selectedOption
|
|
651
|
+
const resource = selectedOption.item;
|
|
652
|
+
const resourceLabel = selectedOption.group.label;
|
|
653
|
+
const resourceType = selectedOption.group.value;
|
|
596
654
|
editor.update(() => {
|
|
597
655
|
const variableNode = $createVariableNode(resourceLabel, resource.label, resourceType, resource.value);
|
|
598
656
|
if (nodeToReplace) {
|
|
@@ -602,7 +660,7 @@ function VariablePickerPlugin({ commandConfig = {} }) {
|
|
|
602
660
|
});
|
|
603
661
|
closeMenu();
|
|
604
662
|
},
|
|
605
|
-
[
|
|
663
|
+
[editor]
|
|
606
664
|
);
|
|
607
665
|
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
608
666
|
LexicalTypeaheadMenuPlugin.LexicalTypeaheadMenuPlugin,
|
|
@@ -616,40 +674,24 @@ function VariablePickerPlugin({ commandConfig = {} }) {
|
|
|
616
674
|
if (!match) return null;
|
|
617
675
|
return { leadOffset: match.index, matchingString: match[0], replaceableString: match[0] };
|
|
618
676
|
},
|
|
619
|
-
options: commandOptions
|
|
620
|
-
menuRenderFn: (anchorElementRef, { selectedIndex, setHighlightedIndex, selectOptionAndCleanUp }
|
|
621
|
-
if (!anchorElementRef.current) return null;
|
|
677
|
+
options: commandOptions,
|
|
678
|
+
menuRenderFn: (anchorElementRef, { selectedIndex, setHighlightedIndex, selectOptionAndCleanUp }) => {
|
|
679
|
+
if (!isEditorFocused || !anchorElementRef.current || searchKeyword && !commandGroups.length) return null;
|
|
622
680
|
return ReactDOM__namespace.createPortal(
|
|
623
|
-
/* @__PURE__ */ jsxRuntime.
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
const option = commandOptions.find(
|
|
633
|
-
(currentOption) => currentOption.category.value === categoryValue && currentOption.item.value === itemValue
|
|
634
|
-
);
|
|
635
|
-
if (option) selectOptionAndCleanUp(option);
|
|
636
|
-
}
|
|
637
|
-
}
|
|
638
|
-
),
|
|
639
|
-
commandDataSource[matchingString]?.component === "list" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
640
|
-
FilePickerMenu,
|
|
641
|
-
{
|
|
642
|
-
options: commandDataSource[matchingString]?.dataSource || [],
|
|
643
|
-
selectedIndex: selectedIndex ?? 0,
|
|
644
|
-
onHover: setHighlightedIndex,
|
|
645
|
-
onSelect: (option) => selectOptionAndCleanUp(new FileOption(option))
|
|
646
|
-
}
|
|
647
|
-
)
|
|
648
|
-
] }),
|
|
681
|
+
/* @__PURE__ */ jsxRuntime.jsx(ResourcePickerMenu, { anchorElementRef, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
682
|
+
GroupPicker,
|
|
683
|
+
{
|
|
684
|
+
groups: commandGroups,
|
|
685
|
+
selectedIndex: selectedIndex ?? 0,
|
|
686
|
+
onHover: setHighlightedIndex,
|
|
687
|
+
onSelect: (group, option) => selectOptionAndCleanUp(new ResourceOption(group, option))
|
|
688
|
+
}
|
|
689
|
+
) }),
|
|
649
690
|
anchorElementRef.current
|
|
650
691
|
);
|
|
651
692
|
}
|
|
652
|
-
}
|
|
693
|
+
},
|
|
694
|
+
menuResetKey
|
|
653
695
|
) });
|
|
654
696
|
}
|
|
655
697
|
function InitialStatePlugin({ value }) {
|
|
@@ -872,14 +914,6 @@ var ChatSender_default = React10.forwardRef(
|
|
|
872
914
|
);
|
|
873
915
|
}
|
|
874
916
|
);
|
|
875
|
-
var TOKEN_KEY = "NS-TOKEN";
|
|
876
|
-
var tokenManager = common.createTokenManager({
|
|
877
|
-
key: TOKEN_KEY
|
|
878
|
-
});
|
|
879
|
-
var redirectUrl = () => {
|
|
880
|
-
const path = localStorage.getItem("SIGNPATH");
|
|
881
|
-
common.emit("jumpLink", { url: `/uc${path || "/sign-in"}` });
|
|
882
|
-
};
|
|
883
917
|
var createChatService = (request, config) => {
|
|
884
918
|
const fetchModelList = () => {
|
|
885
919
|
return request.get(`/providers/models/type/llm`);
|
|
@@ -920,14 +954,8 @@ var createChatService = (request, config) => {
|
|
|
920
954
|
signal
|
|
921
955
|
});
|
|
922
956
|
};
|
|
923
|
-
const getPreviewUrl = (
|
|
924
|
-
|
|
925
|
-
path,
|
|
926
|
-
[TOKEN_KEY]: tokenManager.get(),
|
|
927
|
-
workspaceId: conversationId,
|
|
928
|
-
workspaceType: "conversation" /* CONVERSATION */
|
|
929
|
-
};
|
|
930
|
-
return common.buildUrlParams(params, `${config?.baseURL}/files/access`);
|
|
957
|
+
const getPreviewUrl = (params) => {
|
|
958
|
+
return getFileUrl(params, config?.baseURL);
|
|
931
959
|
};
|
|
932
960
|
const docQuery = (params) => {
|
|
933
961
|
return request.get(`/library/cloud/document?${params}`);
|
|
@@ -2736,7 +2764,10 @@ var PreviewLink_default = ({ data, loading, message: message2, ...rest }) => {
|
|
|
2736
2764
|
const fileName = getLinkFileName(href);
|
|
2737
2765
|
const suffix = common.getFileSuffixName(fileName);
|
|
2738
2766
|
chatStore.setPreview({
|
|
2739
|
-
fileUrl: chatStore.config.services.request.getPreviewUrl(
|
|
2767
|
+
fileUrl: chatStore.config.services.request.getPreviewUrl({
|
|
2768
|
+
path: href,
|
|
2769
|
+
workspaceId: message2.conversationId
|
|
2770
|
+
}),
|
|
2740
2771
|
fileName,
|
|
2741
2772
|
suffix
|
|
2742
2773
|
});
|
|
@@ -3260,6 +3291,135 @@ var A2uiComponents = {
|
|
|
3260
3291
|
ReportViewer
|
|
3261
3292
|
};
|
|
3262
3293
|
|
|
3294
|
+
// src/components/CustomComponents/A2uiRuntime/controller/extract.ts
|
|
3295
|
+
var A2UI_TAG_REGEX = /<A2UI\s+id="([^"]*)"\s*>([\s\S]*?)<\/A2UI>/g;
|
|
3296
|
+
function hasA2uiTag(text) {
|
|
3297
|
+
return typeof text === "string" && text.includes("<A2UI");
|
|
3298
|
+
}
|
|
3299
|
+
function parseA2uiTagsFromText(text) {
|
|
3300
|
+
if (!hasA2uiTag(text)) return [];
|
|
3301
|
+
const tags = [];
|
|
3302
|
+
const regex = new RegExp(A2UI_TAG_REGEX);
|
|
3303
|
+
let match;
|
|
3304
|
+
while ((match = regex.exec(text)) !== null) {
|
|
3305
|
+
const tagId = match[1];
|
|
3306
|
+
const json = match[2].trim();
|
|
3307
|
+
if (!json) continue;
|
|
3308
|
+
try {
|
|
3309
|
+
const parsed = JSON.parse(json);
|
|
3310
|
+
const commands = Array.isArray(parsed) ? parsed : [parsed];
|
|
3311
|
+
if (commands.length) tags.push({ tagId, commands });
|
|
3312
|
+
} catch {
|
|
3313
|
+
}
|
|
3314
|
+
}
|
|
3315
|
+
return tags;
|
|
3316
|
+
}
|
|
3317
|
+
function stripA2uiTags(text) {
|
|
3318
|
+
if (!hasA2uiTag(text)) return text;
|
|
3319
|
+
let result = text.replace(A2UI_TAG_REGEX, "");
|
|
3320
|
+
result = result.replace(/<A2UI\b[\s\S]*$/, "");
|
|
3321
|
+
return result.trim();
|
|
3322
|
+
}
|
|
3323
|
+
function splitA2uiTextSegments(text) {
|
|
3324
|
+
if (typeof text !== "string" || !text.includes("<A2UI")) {
|
|
3325
|
+
return text ? [{ type: "text", content: text }] : [];
|
|
3326
|
+
}
|
|
3327
|
+
const segments = [];
|
|
3328
|
+
const regex = new RegExp(A2UI_TAG_REGEX);
|
|
3329
|
+
let lastIndex = 0;
|
|
3330
|
+
let match;
|
|
3331
|
+
while ((match = regex.exec(text)) !== null) {
|
|
3332
|
+
if (match.index > lastIndex) {
|
|
3333
|
+
const before = text.slice(lastIndex, match.index);
|
|
3334
|
+
if (before) segments.push({ type: "text", content: before });
|
|
3335
|
+
}
|
|
3336
|
+
const json = match[2].trim();
|
|
3337
|
+
if (json) {
|
|
3338
|
+
try {
|
|
3339
|
+
const parsed = JSON.parse(json);
|
|
3340
|
+
const commands = Array.isArray(parsed) ? parsed : [parsed];
|
|
3341
|
+
const surfaceIds = commands.map((cmd) => String(cmd?.createSurface?.surfaceId || "").trim()).filter(Boolean);
|
|
3342
|
+
if (surfaceIds.length) {
|
|
3343
|
+
segments.push({ type: "a2ui", surfaceIds });
|
|
3344
|
+
}
|
|
3345
|
+
} catch {
|
|
3346
|
+
}
|
|
3347
|
+
}
|
|
3348
|
+
lastIndex = regex.lastIndex;
|
|
3349
|
+
}
|
|
3350
|
+
if (lastIndex < text.length) {
|
|
3351
|
+
let remaining = text.slice(lastIndex);
|
|
3352
|
+
remaining = remaining.replace(/<A2UI\b[\s\S]*$/, "");
|
|
3353
|
+
if (remaining) segments.push({ type: "text", content: remaining });
|
|
3354
|
+
}
|
|
3355
|
+
return segments.length ? segments : [];
|
|
3356
|
+
}
|
|
3357
|
+
function extractInlineSurfaceIdsFromMessage(message2) {
|
|
3358
|
+
const surfaceIds = /* @__PURE__ */ new Set();
|
|
3359
|
+
const items = Array.isArray(message2?.content) ? message2.content : [];
|
|
3360
|
+
for (const item of items) {
|
|
3361
|
+
if (item?.type !== "text") continue;
|
|
3362
|
+
const text = item.messageContent || item.text || "";
|
|
3363
|
+
if (typeof text !== "string" || !text.includes("<A2UI")) continue;
|
|
3364
|
+
const tags = parseA2uiTagsFromText(text);
|
|
3365
|
+
for (const tag of tags) {
|
|
3366
|
+
for (const cmd of tag.commands) {
|
|
3367
|
+
const sid = String(cmd?.createSurface?.surfaceId || "").trim();
|
|
3368
|
+
if (sid) surfaceIds.add(sid);
|
|
3369
|
+
}
|
|
3370
|
+
}
|
|
3371
|
+
}
|
|
3372
|
+
return surfaceIds;
|
|
3373
|
+
}
|
|
3374
|
+
function extractDismissedSurfaceIdsFromMessages(messages) {
|
|
3375
|
+
const lastCreateIndexBySurface = /* @__PURE__ */ new Map();
|
|
3376
|
+
const lastActionIndexBySurface = /* @__PURE__ */ new Map();
|
|
3377
|
+
for (let messageIndex = 0; messageIndex < messages.length; messageIndex++) {
|
|
3378
|
+
const message2 = messages[messageIndex];
|
|
3379
|
+
const items = Array.isArray(message2?.content) ? message2.content : [];
|
|
3380
|
+
for (const item of items) {
|
|
3381
|
+
if (message2?.role !== 1) {
|
|
3382
|
+
if (item?.type === "a2uiCommand" && item.command) {
|
|
3383
|
+
const surfaceId = String(item.command?.createSurface?.surfaceId || "").trim();
|
|
3384
|
+
if (surfaceId) lastCreateIndexBySurface.set(surfaceId, messageIndex);
|
|
3385
|
+
}
|
|
3386
|
+
if (item?.type === "text") {
|
|
3387
|
+
const text = item.messageContent || item.text || "";
|
|
3388
|
+
if (typeof text === "string" && text.includes("<A2UI")) {
|
|
3389
|
+
const tags = parseA2uiTagsFromText(text);
|
|
3390
|
+
for (const tag of tags) {
|
|
3391
|
+
for (const cmd of tag.commands) {
|
|
3392
|
+
const surfaceId = String(cmd?.createSurface?.surfaceId || "").trim();
|
|
3393
|
+
if (surfaceId) lastCreateIndexBySurface.set(surfaceId, messageIndex);
|
|
3394
|
+
}
|
|
3395
|
+
}
|
|
3396
|
+
}
|
|
3397
|
+
}
|
|
3398
|
+
}
|
|
3399
|
+
if (message2?.role === 1 && item?.type === "text") {
|
|
3400
|
+
const text = item.messageContent || item.text || "";
|
|
3401
|
+
if (typeof text !== "string" || !text.includes("a2ui_action.v1")) continue;
|
|
3402
|
+
try {
|
|
3403
|
+
const parsed = JSON.parse(text.trim());
|
|
3404
|
+
if (parsed?.type !== "a2ui_action.v1") continue;
|
|
3405
|
+
const surfaceId = String(parsed.surfaceId || "").trim();
|
|
3406
|
+
if (!surfaceId) continue;
|
|
3407
|
+
lastActionIndexBySurface.set(surfaceId, messageIndex);
|
|
3408
|
+
} catch {
|
|
3409
|
+
}
|
|
3410
|
+
}
|
|
3411
|
+
}
|
|
3412
|
+
}
|
|
3413
|
+
const dismissed = [];
|
|
3414
|
+
for (const [surfaceId, actionIndex] of lastActionIndexBySurface) {
|
|
3415
|
+
const createIndex = lastCreateIndexBySurface.get(surfaceId);
|
|
3416
|
+
if (createIndex === void 0 || actionIndex > createIndex) {
|
|
3417
|
+
dismissed.push(surfaceId);
|
|
3418
|
+
}
|
|
3419
|
+
}
|
|
3420
|
+
return dismissed;
|
|
3421
|
+
}
|
|
3422
|
+
|
|
3263
3423
|
// src/components/CustomComponents/A2uiRuntime/controller/meta.ts
|
|
3264
3424
|
function readProp(current, props, key) {
|
|
3265
3425
|
return current[key] ?? props?.[key];
|
|
@@ -3427,19 +3587,8 @@ function inferModelPathFromSurfaceCommands(surfaceId, commands) {
|
|
|
3427
3587
|
});
|
|
3428
3588
|
return commonParentPath(paths);
|
|
3429
3589
|
}
|
|
3430
|
-
function isSubmitLikeActionName(name) {
|
|
3431
|
-
const trimmed = typeof name === "string" ? name.trim() : "";
|
|
3432
|
-
return trimmed === "submit" || trimmed === "confirm" || trimmed.startsWith("submit_") || trimmed.endsWith(".confirm");
|
|
3433
|
-
}
|
|
3434
|
-
function isCancelLikeActionName(name) {
|
|
3435
|
-
const trimmed = typeof name === "string" ? name.trim() : "";
|
|
3436
|
-
return trimmed === "cancel" || trimmed === "qf.cancel" || trimmed.endsWith(".cancel");
|
|
3437
|
-
}
|
|
3438
3590
|
function shouldOptimisticallyDismissSurface(actionName, context) {
|
|
3439
|
-
|
|
3440
|
-
if (actionName === "qf.submit" || actionName === "qf.cancel") return true;
|
|
3441
|
-
const submitFlag = context?.submit;
|
|
3442
|
-
return submitFlag === true;
|
|
3591
|
+
return true;
|
|
3443
3592
|
}
|
|
3444
3593
|
function buildDispatchContext(surfaceId, rawContext, commands) {
|
|
3445
3594
|
let normalizedContext = normalizeActionContext(rawContext);
|
|
@@ -3738,6 +3887,7 @@ function buildWizardUpdateComponentsCommand(schema, stepId) {
|
|
|
3738
3887
|
function createA2uiRuntimeState() {
|
|
3739
3888
|
return {
|
|
3740
3889
|
processedMessageCursors: [],
|
|
3890
|
+
processedTagIds: [],
|
|
3741
3891
|
serverCommands: [],
|
|
3742
3892
|
localCommands: [],
|
|
3743
3893
|
anchorIndexBySurface: {},
|
|
@@ -3797,6 +3947,57 @@ function initializeWizardSurface(state, surfaceId, effects, nextWizardSteps) {
|
|
|
3797
3947
|
nextWizardSteps[surfaceId] = firstStepId.trim();
|
|
3798
3948
|
}
|
|
3799
3949
|
}
|
|
3950
|
+
function processA2uiCommand(cmd, messageIndex, messageId, nextState, effects, deletedSurfaceIds, nextWizardSteps) {
|
|
3951
|
+
nextState.serverCommands.push(cmd);
|
|
3952
|
+
nextState.lastA2uiHost = { id: messageId, index: messageIndex };
|
|
3953
|
+
const surfaceId = extractSurfaceId2(cmd);
|
|
3954
|
+
if (!surfaceId) return;
|
|
3955
|
+
if (cmd?.createSurface) {
|
|
3956
|
+
nextState.anchorIndexBySurface[surfaceId] = messageIndex;
|
|
3957
|
+
} else if (nextState.anchorIndexBySurface[surfaceId] === void 0 && !cmd?.deleteSurface) {
|
|
3958
|
+
nextState.anchorIndexBySurface[surfaceId] = messageIndex;
|
|
3959
|
+
}
|
|
3960
|
+
if (cmd?.createSurface) {
|
|
3961
|
+
nextState.latestCreateCommandIndexBySurface[surfaceId] = nextState.serverCommands.length - 1;
|
|
3962
|
+
nextState.optimisticallyDismissedSurfaceIds = nextState.optimisticallyDismissedSurfaceIds.filter((id) => id !== surfaceId);
|
|
3963
|
+
initializeWizardSurface(nextState, surfaceId, effects, nextWizardSteps);
|
|
3964
|
+
}
|
|
3965
|
+
if (cmd?.updateDataModel) {
|
|
3966
|
+
const { path, value } = cmd.updateDataModel;
|
|
3967
|
+
if (typeof path === "string" && path.trim() && value && typeof value === "object" && !Array.isArray(value)) {
|
|
3968
|
+
effects.push({ type: "write-model", modelPath: path, values: value });
|
|
3969
|
+
}
|
|
3970
|
+
}
|
|
3971
|
+
if (cmd?.deleteSurface) {
|
|
3972
|
+
deletedSurfaceIds.add(surfaceId);
|
|
3973
|
+
const modelPath = nextState.modelPathBySurface[surfaceId];
|
|
3974
|
+
if (modelPath) effects.push({ type: "clear-model", modelPath });
|
|
3975
|
+
delete nextState.initializedWizardRevisionBySurface[surfaceId];
|
|
3976
|
+
delete nextState.modelPathBySurface[surfaceId];
|
|
3977
|
+
}
|
|
3978
|
+
}
|
|
3979
|
+
function scanA2uiTagsFromMessages(messages, processedTagIds) {
|
|
3980
|
+
const newTags = [];
|
|
3981
|
+
const newTagIds = [];
|
|
3982
|
+
for (let messageIndex = 0; messageIndex < messages.length; messageIndex += 1) {
|
|
3983
|
+
const message2 = messages[messageIndex];
|
|
3984
|
+
const messageId = String(message2?.messageId ?? messageIndex);
|
|
3985
|
+
const items = Array.isArray(message2?.content) ? message2.content : [];
|
|
3986
|
+
for (const item of items) {
|
|
3987
|
+
if (item?.type !== "text") continue;
|
|
3988
|
+
const text = item.messageContent || item.text || "";
|
|
3989
|
+
if (typeof text !== "string" || !text.includes("<A2UI")) continue;
|
|
3990
|
+
const tags = parseA2uiTagsFromText(text);
|
|
3991
|
+
for (const tag of tags) {
|
|
3992
|
+
if (processedTagIds.has(tag.tagId)) continue;
|
|
3993
|
+
processedTagIds.add(tag.tagId);
|
|
3994
|
+
newTagIds.push(tag.tagId);
|
|
3995
|
+
newTags.push({ commands: tag.commands, messageIndex, messageId });
|
|
3996
|
+
}
|
|
3997
|
+
}
|
|
3998
|
+
}
|
|
3999
|
+
return { newTags, newTagIds };
|
|
4000
|
+
}
|
|
3800
4001
|
function reduceA2uiRuntimeMessages(state, messages) {
|
|
3801
4002
|
const { shouldReplayAll, pendingItems, nextCursors } = diffConversationMessages(messages || [], state.processedMessageCursors);
|
|
3802
4003
|
const itemsToProcess = shouldReplayAll ? messages.flatMap((message2, messageIndex) => {
|
|
@@ -3804,11 +4005,14 @@ function reduceA2uiRuntimeMessages(state, messages) {
|
|
|
3804
4005
|
const items = Array.isArray(message2?.content) ? message2.content : [];
|
|
3805
4006
|
return items.map((item) => ({ messageIndex, messageId, item }));
|
|
3806
4007
|
}) : pendingItems;
|
|
3807
|
-
|
|
4008
|
+
const tagProcessedSet = new Set(shouldReplayAll ? [] : state.processedTagIds);
|
|
4009
|
+
const { newTags, newTagIds } = scanA2uiTagsFromMessages(messages || [], tagProcessedSet);
|
|
4010
|
+
if (!shouldReplayAll && itemsToProcess.length === 0 && newTags.length === 0) {
|
|
3808
4011
|
return { state, effects: [] };
|
|
3809
4012
|
}
|
|
3810
4013
|
const nextState = shouldReplayAll ? createA2uiRuntimeState() : { ...state };
|
|
3811
4014
|
nextState.processedMessageCursors = shouldReplayAll ? [] : [...state.processedMessageCursors];
|
|
4015
|
+
nextState.processedTagIds = shouldReplayAll ? [] : [...state.processedTagIds, ...newTagIds];
|
|
3812
4016
|
nextState.serverCommands = shouldReplayAll ? [] : [...state.serverCommands];
|
|
3813
4017
|
nextState.localCommands = shouldReplayAll ? [] : [...state.localCommands];
|
|
3814
4018
|
nextState.anchorIndexBySurface = shouldReplayAll ? {} : { ...state.anchorIndexBySurface };
|
|
@@ -3831,24 +4035,13 @@ function reduceA2uiRuntimeMessages(state, messages) {
|
|
|
3831
4035
|
}
|
|
3832
4036
|
return;
|
|
3833
4037
|
}
|
|
3834
|
-
if (item?.type
|
|
3835
|
-
|
|
3836
|
-
|
|
3837
|
-
|
|
3838
|
-
|
|
3839
|
-
|
|
3840
|
-
nextState
|
|
3841
|
-
}
|
|
3842
|
-
if (item.command?.createSurface) {
|
|
3843
|
-
nextState.latestCreateCommandIndexBySurface[surfaceId] = nextState.serverCommands.length - 1;
|
|
3844
|
-
initializeWizardSurface(nextState, surfaceId, effects, nextWizardSteps);
|
|
3845
|
-
}
|
|
3846
|
-
if (item.command?.deleteSurface) {
|
|
3847
|
-
deletedSurfaceIds.add(surfaceId);
|
|
3848
|
-
const modelPath = nextState.modelPathBySurface[surfaceId];
|
|
3849
|
-
if (modelPath) effects.push({ type: "clear-model", modelPath });
|
|
3850
|
-
delete nextState.initializedWizardRevisionBySurface[surfaceId];
|
|
3851
|
-
delete nextState.modelPathBySurface[surfaceId];
|
|
4038
|
+
if (item?.type === "a2uiCommand" && item.command) {
|
|
4039
|
+
processA2uiCommand(item.command, messageIndex, messageId, nextState, effects, deletedSurfaceIds, nextWizardSteps);
|
|
4040
|
+
}
|
|
4041
|
+
});
|
|
4042
|
+
newTags.forEach(({ commands, messageIndex, messageId }) => {
|
|
4043
|
+
for (const cmd of commands) {
|
|
4044
|
+
processA2uiCommand(cmd, messageIndex, messageId, nextState, effects, deletedSurfaceIds, nextWizardSteps);
|
|
3852
4045
|
}
|
|
3853
4046
|
});
|
|
3854
4047
|
nextState.processedMessageCursors = shouldReplayAll ? messages.map((message2, messageIndex) => ({
|
|
@@ -3868,7 +4061,7 @@ function reduceA2uiRuntimeMessages(state, messages) {
|
|
|
3868
4061
|
return { state: nextState, effects };
|
|
3869
4062
|
}
|
|
3870
4063
|
function reduceA2uiRuntimeAction(state, input) {
|
|
3871
|
-
const { surfaceId, actionName
|
|
4064
|
+
const { surfaceId, actionName} = input;
|
|
3872
4065
|
if (!surfaceId) {
|
|
3873
4066
|
return { state, handled: actionName === "wizard.next" || actionName === "wizard.back" };
|
|
3874
4067
|
}
|
|
@@ -3898,9 +4091,6 @@ function reduceA2uiRuntimeAction(state, input) {
|
|
|
3898
4091
|
if (actionName === "wizard.next" || actionName === "wizard.back") {
|
|
3899
4092
|
return { state, handled: true };
|
|
3900
4093
|
}
|
|
3901
|
-
if (!shouldOptimisticallyDismissSurface(actionName, rawContext)) {
|
|
3902
|
-
return { state, handled: false };
|
|
3903
|
-
}
|
|
3904
4094
|
if (state.optimisticallyDismissedSurfaceIds.includes(surfaceId)) {
|
|
3905
4095
|
return { state, handled: false };
|
|
3906
4096
|
}
|
|
@@ -3965,12 +4155,20 @@ function useA2uiController(params) {
|
|
|
3965
4155
|
applyA2uiRuntimeEffects(result.effects);
|
|
3966
4156
|
setRuntimeState(result.state);
|
|
3967
4157
|
}, [conversationMessages, conversationId]);
|
|
3968
|
-
const
|
|
4158
|
+
const permanentDismissedSurfaceIds = React10.useMemo(
|
|
4159
|
+
() => extractDismissedSurfaceIdsFromMessages(conversationMessages || []),
|
|
4160
|
+
[conversationMessages]
|
|
4161
|
+
);
|
|
4162
|
+
const mergedDismissedSurfaceIds = React10.useMemo(
|
|
4163
|
+
() => Array.from(/* @__PURE__ */ new Set([...dismissedSurfaceIds || [], ...permanentDismissedSurfaceIds])),
|
|
4164
|
+
[dismissedSurfaceIds, permanentDismissedSurfaceIds]
|
|
4165
|
+
);
|
|
4166
|
+
const view = React10.useMemo(() => selectA2uiRuntimeView(runtimeState, mergedDismissedSurfaceIds), [runtimeState, mergedDismissedSurfaceIds]);
|
|
3969
4167
|
const handleRuntimeAction = React10.useCallback((payload) => {
|
|
3970
4168
|
const surfaceId = String(payload?.surfaceId || payload?.cardId || "");
|
|
3971
4169
|
const name = String(payload?.name || payload?.event?.name || "").trim();
|
|
3972
4170
|
const rawContext = payload?.context || payload?.event?.context || {};
|
|
3973
|
-
const runtimeActionResult = reduceA2uiRuntimeAction(runtimeRef.current, { surfaceId, actionName: name
|
|
4171
|
+
const runtimeActionResult = reduceA2uiRuntimeAction(runtimeRef.current, { surfaceId, actionName: name});
|
|
3974
4172
|
if (runtimeActionResult.state !== runtimeRef.current) {
|
|
3975
4173
|
runtimeRef.current = runtimeActionResult.state;
|
|
3976
4174
|
setRuntimeState(runtimeActionResult.state);
|
|
@@ -3997,26 +4195,26 @@ var A2uiRuntimeContext = React10__namespace.default.createContext({
|
|
|
3997
4195
|
function useA2uiRuntimeView() {
|
|
3998
4196
|
return React10__namespace.default.useContext(A2uiRuntimeContext);
|
|
3999
4197
|
}
|
|
4000
|
-
function A2uiMessageCards({ messageIndex }) {
|
|
4198
|
+
function A2uiMessageCards({ messageIndex, message: message2 }) {
|
|
4001
4199
|
const { surfaceIdsByMessageIndex } = useA2uiRuntimeView();
|
|
4002
|
-
const
|
|
4200
|
+
const allSurfaceIds = surfaceIdsByMessageIndex[messageIndex] || [];
|
|
4201
|
+
const inlineSurfaceIds = message2 ? extractInlineSurfaceIdsFromMessage(message2) : /* @__PURE__ */ new Set();
|
|
4202
|
+
const surfaceIds = allSurfaceIds.filter((id) => !inlineSurfaceIds.has(id));
|
|
4003
4203
|
if (!surfaceIds.length) return null;
|
|
4004
4204
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { children: surfaceIds.map((surfaceId) => /* @__PURE__ */ jsxRuntime.jsx(XCard.Card, { id: surfaceId }, surfaceId)) });
|
|
4005
4205
|
}
|
|
4006
4206
|
|
|
4007
4207
|
// src/components/CustomComponents/A2uiRuntime/renderer/protocol.ts
|
|
4008
|
-
function
|
|
4208
|
+
function isSubmitLikeActionName(name) {
|
|
4009
4209
|
const normalized = String(name || "").trim();
|
|
4010
4210
|
return normalized === "submit" || normalized === "confirm" || normalized.startsWith("submit_") || normalized.endsWith(".confirm");
|
|
4011
4211
|
}
|
|
4012
|
-
function
|
|
4212
|
+
function isCancelLikeActionName(name) {
|
|
4013
4213
|
const normalized = String(name || "").trim();
|
|
4014
4214
|
return normalized === "cancel" || normalized === "qf.cancel" || normalized.endsWith(".cancel");
|
|
4015
4215
|
}
|
|
4016
4216
|
function shouldDismissA2uiSurface(name, context) {
|
|
4017
|
-
|
|
4018
|
-
if (name === "qf.submit" || name === "qf.cancel") return true;
|
|
4019
|
-
return context?.submit === true;
|
|
4217
|
+
return true;
|
|
4020
4218
|
}
|
|
4021
4219
|
function normalizeA2uiActionPayload(payload) {
|
|
4022
4220
|
return {
|
|
@@ -4050,7 +4248,7 @@ function isQuestionActionPayload(payload) {
|
|
|
4050
4248
|
const mode = payload.context?.form_mode;
|
|
4051
4249
|
if (payload.name === "qf.submit" || payload.name === "qf.cancel") return true;
|
|
4052
4250
|
if (payload.name.startsWith("qf.")) return true;
|
|
4053
|
-
return typeof mode === "string" && mode.toLowerCase() === "ephemeral" ?
|
|
4251
|
+
return typeof mode === "string" && mode.toLowerCase() === "ephemeral" ? isSubmitLikeActionName(payload.name) || isCancelLikeActionName(payload.name) : false;
|
|
4054
4252
|
}
|
|
4055
4253
|
function formatActionValue(value, displayOverride) {
|
|
4056
4254
|
if (typeof displayOverride === "string" && displayOverride.trim()) return displayOverride.trim();
|
|
@@ -4060,7 +4258,7 @@ function formatActionValue(value, displayOverride) {
|
|
|
4060
4258
|
return String(value);
|
|
4061
4259
|
}
|
|
4062
4260
|
function buildQuestionSummary(payload) {
|
|
4063
|
-
if (
|
|
4261
|
+
if (isCancelLikeActionName(payload.name)) return "Question: \u5DF2\u53D6\u6D88";
|
|
4064
4262
|
const values = payload.context.values && typeof payload.context.values === "object" && !Array.isArray(payload.context.values) ? payload.context.values : payload.context;
|
|
4065
4263
|
const labels = payload.context.labels && typeof payload.context.labels === "object" && !Array.isArray(payload.context.labels) ? payload.context.labels : {};
|
|
4066
4264
|
const valueLabels = payload.context.valueLabels && typeof payload.context.valueLabels === "object" && !Array.isArray(payload.context.valueLabels) ? payload.context.valueLabels : {};
|
|
@@ -4082,10 +4280,22 @@ function formatA2uiActionDisplayText(payload) {
|
|
|
4082
4280
|
back_to_params: "\u5DF2\u8FD4\u56DE\u4FEE\u6539\u53C2\u6570",
|
|
4083
4281
|
confirm: "\u5DF2\u786E\u8BA4\u521B\u5EFA"
|
|
4084
4282
|
};
|
|
4085
|
-
|
|
4283
|
+
let actionLabel = actionLabels[payload.name];
|
|
4284
|
+
if (!actionLabel) {
|
|
4285
|
+
if (payload.name.startsWith("confirm_")) {
|
|
4286
|
+
actionLabel = "\u5DF2\u9009\u62E9";
|
|
4287
|
+
} else if (payload.name.startsWith("submit_")) {
|
|
4288
|
+
actionLabel = "\u5DF2\u63D0\u4EA4";
|
|
4289
|
+
} else {
|
|
4290
|
+
actionLabel = `\u5DF2\u63D0\u4EA4\u52A8\u4F5C (${payload.name})`;
|
|
4291
|
+
}
|
|
4292
|
+
}
|
|
4293
|
+
const isConfirmLike = payload.name.startsWith("confirm_");
|
|
4086
4294
|
const details = Object.entries(values).filter(([, value]) => value !== null && value !== void 0 && value !== "").map(([key, value]) => {
|
|
4295
|
+
const formatted = formatActionValue(value, valueLabels[key]);
|
|
4296
|
+
if (isConfirmLike) return formatted;
|
|
4087
4297
|
const label = typeof labels[key] === "string" && String(labels[key]).trim() ? String(labels[key]).trim() : key;
|
|
4088
|
-
return `${label}: ${
|
|
4298
|
+
return `${label}: ${formatted}`;
|
|
4089
4299
|
});
|
|
4090
4300
|
return details.length ? `${actionLabel}\uFF1A${details.join("\uFF1B ")}` : actionLabel;
|
|
4091
4301
|
}
|
|
@@ -4183,66 +4393,46 @@ function readContextModelPath(context) {
|
|
|
4183
4393
|
const path = context?.model && typeof context.model === "object" ? context.model.path : "";
|
|
4184
4394
|
return typeof path === "string" ? path.trim() : "";
|
|
4185
4395
|
}
|
|
4186
|
-
function
|
|
4187
|
-
|
|
4188
|
-
|
|
4189
|
-
|
|
4190
|
-
const nextCursors = [];
|
|
4191
|
-
const pendingItems = [];
|
|
4192
|
-
for (let messageIndex = 0; messageIndex < messages.length; messageIndex += 1) {
|
|
4193
|
-
const message2 = messages[messageIndex];
|
|
4194
|
-
const messageId = String(message2?.messageId ?? messageIndex);
|
|
4396
|
+
function buildLatestCommandIndexBySurface(messages) {
|
|
4397
|
+
const indexBySurface = {};
|
|
4398
|
+
let commandIndex = -1;
|
|
4399
|
+
for (const message2 of messages) {
|
|
4195
4400
|
const items = Array.isArray(message2?.content) ? message2.content : [];
|
|
4196
|
-
const
|
|
4197
|
-
|
|
4198
|
-
|
|
4199
|
-
|
|
4200
|
-
|
|
4201
|
-
|
|
4202
|
-
|
|
4401
|
+
for (const item of items) {
|
|
4402
|
+
if (item?.type === "a2uiCommand" && item.command) {
|
|
4403
|
+
commandIndex += 1;
|
|
4404
|
+
const surfaceId = extractSurfaceId3(item.command);
|
|
4405
|
+
if (surfaceId) indexBySurface[surfaceId] = commandIndex;
|
|
4406
|
+
continue;
|
|
4407
|
+
}
|
|
4408
|
+
if (item?.type === "text") {
|
|
4409
|
+
const text = item.messageContent || item.text || "";
|
|
4410
|
+
if (typeof text !== "string" || !text.includes("<A2UI")) continue;
|
|
4411
|
+
const tags = parseA2uiTagsFromText(text);
|
|
4412
|
+
for (const tag of tags) {
|
|
4413
|
+
for (const cmd of tag.commands) {
|
|
4414
|
+
commandIndex += 1;
|
|
4415
|
+
const surfaceId = extractSurfaceId3(cmd);
|
|
4416
|
+
if (surfaceId) indexBySurface[surfaceId] = commandIndex;
|
|
4417
|
+
}
|
|
4418
|
+
}
|
|
4419
|
+
}
|
|
4203
4420
|
}
|
|
4204
|
-
nextCursors.push({ messageId, contentLength: items.length });
|
|
4205
4421
|
}
|
|
4206
|
-
return
|
|
4422
|
+
return indexBySurface;
|
|
4207
4423
|
}
|
|
4208
4424
|
function A2uiRuntimeProvider({ messages, children }) {
|
|
4209
4425
|
const chatStore = useChatStore();
|
|
4210
4426
|
const conversationState = valtio.useSnapshot(chatStore.conversation);
|
|
4211
4427
|
const conversationId = conversationState.active.id;
|
|
4212
|
-
const processedMessageCursorsRef = React10__namespace.default.useRef([]);
|
|
4213
|
-
const latestCommandIndexBySurfaceRef = React10__namespace.default.useRef({});
|
|
4214
|
-
const commandIndexRef = React10__namespace.default.useRef(-1);
|
|
4215
4428
|
const [latestCommandIndexBySurface, setLatestCommandIndexBySurface] = React10__namespace.default.useState({});
|
|
4216
4429
|
const [dismissedAtBySurface, setDismissedAtBySurface] = React10__namespace.default.useState({});
|
|
4217
4430
|
React10__namespace.default.useEffect(() => {
|
|
4218
|
-
processedMessageCursorsRef.current = [];
|
|
4219
|
-
latestCommandIndexBySurfaceRef.current = {};
|
|
4220
|
-
commandIndexRef.current = -1;
|
|
4221
4431
|
setLatestCommandIndexBySurface({});
|
|
4222
4432
|
setDismissedAtBySurface({});
|
|
4223
4433
|
}, [conversationId]);
|
|
4224
4434
|
React10__namespace.default.useEffect(() => {
|
|
4225
|
-
|
|
4226
|
-
const itemsToProcess = shouldReplayAll ? messages.flatMap((message2) => {
|
|
4227
|
-
const items = Array.isArray(message2?.content) ? message2.content : [];
|
|
4228
|
-
return items.map((item) => ({ item }));
|
|
4229
|
-
}) : pendingItems;
|
|
4230
|
-
if (!shouldReplayAll && itemsToProcess.length === 0) return;
|
|
4231
|
-
const nextLatestCommandIndexBySurface = shouldReplayAll ? {} : { ...latestCommandIndexBySurfaceRef.current };
|
|
4232
|
-
let nextCommandIndex = shouldReplayAll ? -1 : commandIndexRef.current;
|
|
4233
|
-
itemsToProcess.forEach(({ item }) => {
|
|
4234
|
-
if (item?.type !== "a2uiCommand" || !item.command) return;
|
|
4235
|
-
nextCommandIndex += 1;
|
|
4236
|
-
const surfaceId = extractSurfaceId3(item.command);
|
|
4237
|
-
if (surfaceId) nextLatestCommandIndexBySurface[surfaceId] = nextCommandIndex;
|
|
4238
|
-
});
|
|
4239
|
-
processedMessageCursorsRef.current = shouldReplayAll ? messages.map((message2, messageIndex) => ({
|
|
4240
|
-
messageId: String(message2?.messageId ?? messageIndex),
|
|
4241
|
-
contentLength: Array.isArray(message2?.content) ? message2.content.length : 0
|
|
4242
|
-
})) : nextCursors;
|
|
4243
|
-
latestCommandIndexBySurfaceRef.current = nextLatestCommandIndexBySurface;
|
|
4244
|
-
commandIndexRef.current = nextCommandIndex;
|
|
4245
|
-
setLatestCommandIndexBySurface(nextLatestCommandIndexBySurface);
|
|
4435
|
+
setLatestCommandIndexBySurface(buildLatestCommandIndexBySurface(messages));
|
|
4246
4436
|
}, [messages]);
|
|
4247
4437
|
const dismissedSurfaceIds = React10__namespace.default.useMemo(() => {
|
|
4248
4438
|
return Object.entries(dismissedAtBySurface).filter(([surfaceId, dismissedAt]) => (latestCommandIndexBySurface[surfaceId] ?? -1) <= dismissedAt).map(([surfaceId]) => surfaceId);
|
|
@@ -4299,11 +4489,13 @@ function A2uiRenderer(props) {
|
|
|
4299
4489
|
var FilesNode = React10__namespace.default.memo(({ item }) => {
|
|
4300
4490
|
const chatStore = useChatStore();
|
|
4301
4491
|
const configState = valtio.useSnapshot(chatStore.config);
|
|
4302
|
-
valtio.useSnapshot(chatStore.agent);
|
|
4303
4492
|
const conversationState = valtio.useSnapshot(chatStore.conversation);
|
|
4304
4493
|
const fileItems = React10.useMemo(() => {
|
|
4305
4494
|
return (item.files || []).map((file) => {
|
|
4306
|
-
const previewUrl = configState.services.request.getPreviewUrl(
|
|
4495
|
+
const previewUrl = configState.services.request.getPreviewUrl({
|
|
4496
|
+
path: file.path,
|
|
4497
|
+
workspaceId: conversationState.active.id
|
|
4498
|
+
});
|
|
4307
4499
|
let fileType = "file";
|
|
4308
4500
|
const ext = file.ext?.toLowerCase() || "";
|
|
4309
4501
|
if (["jpg", "jpeg", "png", "gif", "bmp", "webp", "svg", "webp"].includes(ext)) {
|
|
@@ -4369,14 +4561,37 @@ function QuestionSummary({ content }) {
|
|
|
4369
4561
|
] });
|
|
4370
4562
|
}
|
|
4371
4563
|
var TextNode2 = React10__namespace.default.memo(
|
|
4372
|
-
({
|
|
4373
|
-
|
|
4374
|
-
|
|
4375
|
-
|
|
4564
|
+
({
|
|
4565
|
+
item,
|
|
4566
|
+
role,
|
|
4567
|
+
customComponents,
|
|
4568
|
+
message: message2,
|
|
4569
|
+
messageIndex = -1
|
|
4570
|
+
}) => {
|
|
4571
|
+
const { surfaceIdsByMessageIndex } = useA2uiRuntimeView();
|
|
4572
|
+
const rawContent = toA2uiDisplayText(role, item?.messageContent);
|
|
4573
|
+
const segments = splitA2uiTextSegments(rawContent);
|
|
4574
|
+
const visibleSurfaceIds = messageIndex >= 0 ? new Set(surfaceIdsByMessageIndex[messageIndex] || []) : null;
|
|
4575
|
+
const firstSeg = segments[0];
|
|
4576
|
+
const isPureText = segments.length === 0 || segments.length === 1 && firstSeg.type === "text";
|
|
4577
|
+
if (isPureText) {
|
|
4578
|
+
const content = firstSeg && firstSeg.type === "text" ? firstSeg.content : "";
|
|
4579
|
+
if (typeof content === "string" && content.startsWith("Question:")) {
|
|
4580
|
+
return /* @__PURE__ */ jsxRuntime.jsx(QuestionSummary, { content });
|
|
4581
|
+
}
|
|
4582
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
4583
|
+
!!item.reasoningContent && /* @__PURE__ */ jsxRuntime.jsx(xV2.Think, { title: "\u6DF1\u5EA6\u601D\u8003", children: item.reasoningContent }),
|
|
4584
|
+
!!content && /* @__PURE__ */ jsxRuntime.jsx(XMarkdown_default, { message: message2, components: customComponents, content })
|
|
4585
|
+
] });
|
|
4376
4586
|
}
|
|
4377
4587
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
4378
4588
|
!!item.reasoningContent && /* @__PURE__ */ jsxRuntime.jsx(xV2.Think, { title: "\u6DF1\u5EA6\u601D\u8003", children: item.reasoningContent }),
|
|
4379
|
-
|
|
4589
|
+
segments.map((seg, i) => {
|
|
4590
|
+
if (seg.type === "text") {
|
|
4591
|
+
return seg.content.trim() ? /* @__PURE__ */ jsxRuntime.jsx(XMarkdown_default, { message: message2, components: customComponents, content: seg.content }, `text-${i}`) : null;
|
|
4592
|
+
}
|
|
4593
|
+
return seg.surfaceIds.filter((sid) => !visibleSurfaceIds || visibleSurfaceIds.has(sid)).map((sid) => /* @__PURE__ */ jsxRuntime.jsx(XCard.Card, { id: sid }, `a2ui-${i}-${sid}`));
|
|
4594
|
+
})
|
|
4380
4595
|
] });
|
|
4381
4596
|
}
|
|
4382
4597
|
);
|
|
@@ -4604,6 +4819,12 @@ var MessageRender_default = React10__namespace.default.memo(({ role, message: me
|
|
|
4604
4819
|
if (item.type === "plan") {
|
|
4605
4820
|
return !shouldHideA2uiPlan(item);
|
|
4606
4821
|
}
|
|
4822
|
+
if (item.type === "text") {
|
|
4823
|
+
const rawText = item.messageContent || item.text || "";
|
|
4824
|
+
const visibleText = stripA2uiTags(rawText);
|
|
4825
|
+
const hasA2uiTag2 = typeof rawText === "string" && rawText.includes("<A2UI");
|
|
4826
|
+
return !!visibleText.trim() || !!item.reasoningContent || hasA2uiTag2;
|
|
4827
|
+
}
|
|
4607
4828
|
return true;
|
|
4608
4829
|
});
|
|
4609
4830
|
}, [loading, message2.content]);
|
|
@@ -4632,7 +4853,7 @@ var MessageRender_default = React10__namespace.default.memo(({ role, message: me
|
|
|
4632
4853
|
content: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
4633
4854
|
item.type === "runStarted" && /* @__PURE__ */ jsxRuntime.jsx(RunStartedNode, { loading }, `flow-start-${index}`),
|
|
4634
4855
|
(item.type === "toolCall" || item.type === "toolResult") && /* @__PURE__ */ jsxRuntime.jsx(tool_call_item_default, { item }, `tool-call-${item.toolCallId || index}`),
|
|
4635
|
-
item.type === "text" && /* @__PURE__ */ jsxRuntime.jsx(TextNode2, { item, role: message2.role, customComponents, message: message2 }, `message-${index}`),
|
|
4856
|
+
item.type === "text" && /* @__PURE__ */ jsxRuntime.jsx(TextNode2, { item, role: message2.role, customComponents, message: message2, messageIndex }, `message-${index}`),
|
|
4636
4857
|
item.type === "stepError" && (item.errorMessage ? /* @__PURE__ */ jsxRuntime.jsx(XMarkdown_default, { message: message2, components: customComponents, content: item.errorMessage }) : null),
|
|
4637
4858
|
item.type === "files" && /* @__PURE__ */ jsxRuntime.jsx(FilesNode, { item }, `files-${index}`),
|
|
4638
4859
|
item.type === "plan" && /* @__PURE__ */ jsxRuntime.jsx(A2uiPlanNode, { item }, `plan-${index}`)
|
|
@@ -4642,7 +4863,7 @@ var MessageRender_default = React10__namespace.default.memo(({ role, message: me
|
|
|
4642
4863
|
);
|
|
4643
4864
|
}),
|
|
4644
4865
|
quoteMsg && /* @__PURE__ */ jsxRuntime.jsx(QuoteMsgNode, { quoteMsg, role }),
|
|
4645
|
-
messageIndex >= 0 ? /* @__PURE__ */ jsxRuntime.jsx(A2uiMessageCards, { messageIndex }) : null
|
|
4866
|
+
messageIndex >= 0 ? /* @__PURE__ */ jsxRuntime.jsx(A2uiMessageCards, { messageIndex, message: message2 }) : null
|
|
4646
4867
|
] });
|
|
4647
4868
|
});
|
|
4648
4869
|
var WelcomeItem_default = ({ icon = true, title = true, description = true, prompts = true }) => {
|
|
@@ -5587,5 +5808,7 @@ var layouts_default = React10.forwardRef(({ theme: theme4, params, hooks, layout
|
|
|
5587
5808
|
exports.Attachments = Attachments_default;
|
|
5588
5809
|
exports.ChatCopilot = layouts_default;
|
|
5589
5810
|
exports.ChatSender = ChatSender_default;
|
|
5811
|
+
exports.getFileIcon = getFileIcon;
|
|
5812
|
+
exports.getFileUrl = getFileUrl;
|
|
5590
5813
|
//# sourceMappingURL=index.cjs.js.map
|
|
5591
5814
|
//# sourceMappingURL=index.cjs.js.map
|