@axiom-lattice/react-sdk 1.0.45 → 1.0.50

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.mjs CHANGED
@@ -89,7 +89,7 @@ function useChat(threadId, options = {}) {
89
89
  stopStreamingRef.current = null;
90
90
  }
91
91
  const { input, command, streaming = true } = data;
92
- const { message, files, ...rest } = input || {};
92
+ const { message: message2, files, ...rest } = input || {};
93
93
  setState((prev) => ({
94
94
  ...prev,
95
95
  isLoading: true,
@@ -98,7 +98,7 @@ function useChat(threadId, options = {}) {
98
98
  }));
99
99
  const userMessage = {
100
100
  id: Date.now().toString(),
101
- content: message || command?.resume?.message || "",
101
+ content: message2 || command?.resume?.message || "",
102
102
  files,
103
103
  role: "human"
104
104
  };
@@ -198,6 +198,10 @@ function useChat(threadId, options = {}) {
198
198
  if (!threadId) {
199
199
  return;
200
200
  }
201
+ if (stopStreamingRef.current) {
202
+ stopStreamingRef.current();
203
+ stopStreamingRef.current = null;
204
+ }
201
205
  setState((prev) => ({ ...prev, isLoading: true, error: null }));
202
206
  try {
203
207
  const fetchedMessages = await client.getMessages({
@@ -211,6 +215,35 @@ function useChat(threadId, options = {}) {
211
215
  messages: chunkMessageMerger.current.getMessages(),
212
216
  isLoading: false
213
217
  }));
218
+ if (options.enableResumeStream && fetchedMessages.length > 0) {
219
+ const lastMessage = fetchedMessages[fetchedMessages.length - 1];
220
+ const lastContent = typeof lastMessage.content === "string" ? lastMessage.content : JSON.stringify(lastMessage.content || "");
221
+ const stopResumeStream = client.resumeStream(
222
+ {
223
+ threadId,
224
+ messageId: lastMessage.id,
225
+ knownContent: lastContent,
226
+ pollInterval: options.resumeStreamPollInterval || 100
227
+ },
228
+ handleStreamEvent,
229
+ () => {
230
+ setState((prev) => ({
231
+ ...prev,
232
+ isLoading: false
233
+ }));
234
+ stopStreamingRef.current = null;
235
+ },
236
+ (error) => {
237
+ console.error("Resume stream error:", error);
238
+ setState((prev) => ({
239
+ ...prev,
240
+ error
241
+ }));
242
+ stopStreamingRef.current = null;
243
+ }
244
+ );
245
+ stopStreamingRef.current = stopResumeStream;
246
+ }
214
247
  } catch (error) {
215
248
  setState((prev) => ({
216
249
  ...prev,
@@ -219,7 +252,13 @@ function useChat(threadId, options = {}) {
219
252
  }));
220
253
  }
221
254
  },
222
- [client, threadId]
255
+ [
256
+ client,
257
+ threadId,
258
+ options.enableResumeStream,
259
+ options.resumeStreamPollInterval,
260
+ handleStreamEvent
261
+ ]
223
262
  );
224
263
  const clearMessages = useCallback(() => {
225
264
  chunkMessageMerger.current.reset();
@@ -488,8 +527,1699 @@ function useAgentGraph() {
488
527
 
489
528
  // src/index.ts
490
529
  export * from "@axiom-lattice/protocols";
530
+
531
+ // src/components/GenUI/MDResponse.tsx
532
+ import ReactMarkdown from "react-markdown";
533
+ import { Prism } from "react-syntax-highlighter";
534
+ import { dark } from "react-syntax-highlighter/dist/cjs/styles/prism";
535
+ import remarkGfm from "remark-gfm";
536
+ import { useMemo as useMemo2, useRef as useRef4, useState as useState7 } from "react";
537
+ import { createStyles as createStyles4 } from "antd-style";
538
+ import rehypeRaw from "rehype-raw";
539
+
540
+ // src/components/GenUI/elements/confirm_feedback.tsx
541
+ import { Button, Card, Space, Tag, Typography } from "antd";
542
+ import { useState as useState5 } from "react";
543
+ import { createStyles } from "antd-style";
544
+ import { jsx as jsx2, jsxs } from "react/jsx-runtime";
545
+ var { Text } = Typography;
546
+ var useStyle = createStyles(({ token, css }) => ({
547
+ card: css`
548
+ max-width: 1200px;
549
+ background: linear-gradient(
550
+ 919deg,
551
+ rgb(232 67 157 / 8%),
552
+ rgb(250 235 206 / 28%) 43%
553
+ );
554
+ `
555
+ }));
556
+ var ConfirmFeedback = ({
557
+ data,
558
+ eventHandler,
559
+ interactive = true
560
+ }) => {
561
+ const { message: message2, type, config, feedback, options } = data ?? {};
562
+ const [clicked, setClicked] = useState5(false);
563
+ const { styles } = useStyle();
564
+ return /* @__PURE__ */ jsx2(Card, { size: "small", className: `shadow-sm ${styles.card}`, bordered: false, children: /* @__PURE__ */ jsxs(Space, { direction: "vertical", style: { width: "100%" }, children: [
565
+ /* @__PURE__ */ jsx2(
566
+ Tag,
567
+ {
568
+ bordered: false,
569
+ color: "orange",
570
+ style: {
571
+ fontSize: 14,
572
+ fontWeight: "bold",
573
+ background: "#ffffff8f",
574
+ padding: 4,
575
+ borderRadius: 8
576
+ },
577
+ children: "\u8BF7\u6C42\u786E\u8BA4"
578
+ }
579
+ ),
580
+ /* @__PURE__ */ jsx2(MDResponse, { content: message2 }),
581
+ options ? /* @__PURE__ */ jsx2(Space, { style: { justifyContent: "flex-end", width: "100%" }, children: options?.map((option) => /* @__PURE__ */ jsx2(
582
+ Button,
583
+ {
584
+ title: option.description,
585
+ disabled: !interactive || clicked || feedback,
586
+ style: {
587
+ border: feedback?.data?.action === option.value ? "2px dashed rgb(74 73 77)" : "none"
588
+ },
589
+ onClick: () => {
590
+ setClicked(true);
591
+ eventHandler(
592
+ "confirm_feedback",
593
+ { action: option.value, config },
594
+ option.label
595
+ );
596
+ },
597
+ children: option.label
598
+ },
599
+ option.value
600
+ )) }) : /* @__PURE__ */ jsxs(Space, { style: { justifyContent: "flex-end", width: "100%" }, children: [
601
+ /* @__PURE__ */ jsx2(
602
+ Button,
603
+ {
604
+ disabled: !interactive || clicked || feedback,
605
+ style: {
606
+ border: feedback?.data?.action === "yes" ? "2px dashed rgb(74 73 77)" : "none"
607
+ },
608
+ type: "primary",
609
+ onClick: () => {
610
+ setClicked(true);
611
+ eventHandler(
612
+ "confirm_feedback",
613
+ {
614
+ action: "yes",
615
+ config
616
+ },
617
+ "\u786E\u8BA4"
618
+ );
619
+ },
620
+ children: "\u786E\u8BA4"
621
+ }
622
+ ),
623
+ /* @__PURE__ */ jsx2(
624
+ Button,
625
+ {
626
+ disabled: !interactive || clicked || feedback,
627
+ type: "default",
628
+ style: {
629
+ border: feedback?.data?.action === "no" ? "2px dashed rgb(74 73 77)" : "none"
630
+ },
631
+ onClick: () => {
632
+ setClicked(true);
633
+ eventHandler(
634
+ "confirm_feedback",
635
+ {
636
+ action: "no",
637
+ config
638
+ },
639
+ "\u62D2\u7EDD"
640
+ );
641
+ },
642
+ children: "\u62D2\u7EDD"
643
+ }
644
+ )
645
+ ] })
646
+ ] }) });
647
+ };
648
+
649
+ // src/components/GenUI/elements/generic_data_table.tsx
650
+ import { Table as Table2, Typography as Typography2, Button as Button2, Flex, Space as Space2 } from "antd";
651
+ import { useState as useState6 } from "react";
652
+ import { DownloadOutlined, ExpandAltOutlined } from "@ant-design/icons";
653
+ import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
654
+ var { Text: Text2 } = Typography2;
655
+ var GenericDataTable = ({
656
+ data,
657
+ eventHandler,
658
+ interactive = true,
659
+ default_open_in_side_app = true
660
+ }) => {
661
+ const { dataSource, message: message2 } = data ?? {};
662
+ const [expandedRowKeys, setExpandedRowKeys] = useState6([]);
663
+ const processedData = dataSource?.map((item, index) => ({
664
+ ...item,
665
+ key: `${index}_${JSON.stringify(item).slice(0, 20)}`
666
+ })) || [];
667
+ const generateColumns = (dataItem) => {
668
+ if (!dataItem || typeof dataItem !== "object") {
669
+ return [];
670
+ }
671
+ return Object.keys(dataItem).filter((key) => key !== "key" && key !== "expandItem").map((key) => ({
672
+ title: formatColumnTitle(key),
673
+ dataIndex: key,
674
+ key,
675
+ width: 150,
676
+ sorter: (a, b) => {
677
+ const aVal = a[key];
678
+ const bVal = b[key];
679
+ if (aVal === null || aVal === void 0) return 1;
680
+ if (bVal === null || bVal === void 0) return -1;
681
+ if (typeof aVal === "number" && typeof bVal === "number") {
682
+ return aVal - bVal;
683
+ }
684
+ const aDate = new Date(aVal);
685
+ const bDate = new Date(bVal);
686
+ if (!isNaN(aDate.getTime()) && !isNaN(bDate.getTime())) {
687
+ return aDate.getTime() - bDate.getTime();
688
+ }
689
+ return String(aVal).localeCompare(String(bVal), "zh-CN");
690
+ },
691
+ render: (value) => {
692
+ if (value === null || value === void 0) {
693
+ return "-";
694
+ }
695
+ if (typeof value === "object") {
696
+ return JSON.stringify(value);
697
+ }
698
+ return String(value);
699
+ }
700
+ }));
701
+ };
702
+ const formatColumnTitle = (key) => {
703
+ return key.replace(/([A-Z])/g, " $1").replace(/_/g, " ").replace(/^./, (str) => str.toUpperCase()).trim();
704
+ };
705
+ const columns = processedData.length > 0 ? generateColumns(processedData[0]) : [];
706
+ const expandedRowRender = (record) => {
707
+ const expandItem = record.expandItem;
708
+ if (!expandItem) {
709
+ return null;
710
+ }
711
+ return /* @__PURE__ */ jsxs2("div", { style: { padding: "16px" }, children: [
712
+ expandItem.content && /* @__PURE__ */ jsxs2("div", { style: { marginBottom: "16px" }, children: [
713
+ /* @__PURE__ */ jsx3(Text2, { strong: true, style: { display: "block", marginBottom: "8px" }, children: "\u8BE6\u7EC6\u4FE1\u606F:" }),
714
+ /* @__PURE__ */ jsx3(MDResponse, { content: expandItem.content })
715
+ ] }),
716
+ expandItem.dataSource && expandItem.dataSource.length > 0 && /* @__PURE__ */ jsxs2("div", { children: [
717
+ /* @__PURE__ */ jsx3(Text2, { strong: true, style: { display: "block", marginBottom: "8px" }, children: "\u5B50\u8868\u6570\u636E:" }),
718
+ /* @__PURE__ */ jsx3(
719
+ GenericDataTable,
720
+ {
721
+ component_key: `nested_${record.key}`,
722
+ data: {
723
+ dataSource: expandItem.dataSource,
724
+ message: void 0
725
+ },
726
+ eventHandler,
727
+ interactive
728
+ }
729
+ )
730
+ ] })
731
+ ] });
732
+ };
733
+ const exportToExcel = () => {
734
+ if (!processedData || processedData.length === 0) return;
735
+ console.warn("Export to Excel not implemented in SDK yet (requires xlsx dependency)");
736
+ };
737
+ const hasExpandableRows = processedData.some((item) => item.expandItem);
738
+ return /* @__PURE__ */ jsx3(
739
+ Table2,
740
+ {
741
+ size: "small",
742
+ title: () => /* @__PURE__ */ jsxs2(Flex, { justify: "space-between", align: "center", children: [
743
+ /* @__PURE__ */ jsx3(Space2, { children: /* @__PURE__ */ jsx3(Text2, { strong: true, style: { fontSize: 16 }, children: message2 || "" }) }),
744
+ /* @__PURE__ */ jsxs2(Space2, { children: [
745
+ /* @__PURE__ */ jsx3(
746
+ Button2,
747
+ {
748
+ type: "text",
749
+ size: "small",
750
+ icon: /* @__PURE__ */ jsx3(DownloadOutlined, {}),
751
+ onClick: exportToExcel,
752
+ disabled: !processedData || processedData.length === 0,
753
+ children: "\u5BFC\u51FAExcel"
754
+ }
755
+ ),
756
+ eventHandler && default_open_in_side_app && /* @__PURE__ */ jsxs2(
757
+ Button2,
758
+ {
759
+ type: "link",
760
+ size: "small",
761
+ onClick: () => {
762
+ eventHandler(
763
+ "__open_side_app",
764
+ {
765
+ component_key: "generic_data_table",
766
+ message: message2 || "",
767
+ data: { dataSource, message: message2 },
768
+ size: "large"
769
+ },
770
+ ""
771
+ );
772
+ },
773
+ children: [
774
+ /* @__PURE__ */ jsx3(ExpandAltOutlined, {}),
775
+ "\u5C55\u5F00"
776
+ ]
777
+ }
778
+ )
779
+ ] })
780
+ ] }),
781
+ dataSource: processedData,
782
+ columns,
783
+ pagination: {
784
+ pageSize: 10,
785
+ showSizeChanger: true,
786
+ showQuickJumper: true,
787
+ showTotal: (total, range) => `\u7B2C ${range[0]}-${range[1]} \u6761/\u5171 ${total} \u6761`
788
+ },
789
+ scroll: { x: "max-content" },
790
+ expandable: hasExpandableRows ? {
791
+ expandedRowRender,
792
+ expandedRowKeys,
793
+ onExpandedRowsChange: (keys) => setExpandedRowKeys(keys),
794
+ rowExpandable: (record) => !!record.expandItem
795
+ } : void 0,
796
+ rowKey: "key",
797
+ bordered: true
798
+ }
799
+ );
800
+ };
801
+
802
+ // src/components/GenUI/elements/generic_data_table_side_app.tsx
803
+ import { jsx as jsx4 } from "react/jsx-runtime";
804
+ var GenericDataTableSideApp = (props) => {
805
+ return /* @__PURE__ */ jsx4(GenericDataTable, { ...props, default_open_in_side_app: false });
806
+ };
807
+
808
+ // src/components/GenUI/elements/ToolCall.tsx
809
+ import { Collapse, Typography as Typography4, Flex as Flex2 } from "antd";
810
+ import CollapsePanel from "antd/es/collapse/CollapsePanel";
811
+ import {
812
+ CheckCircleOutlined,
813
+ LoadingOutlined,
814
+ InfoCircleOutlined
815
+ } from "@ant-design/icons";
816
+
817
+ // src/components/GenUI/elements/ToolCard.tsx
818
+ import { Card as Card3, Typography as Typography3, Space as Space3, Tag as Tag2 } from "antd";
819
+ import { createStyles as createStyles2 } from "antd-style";
820
+ import { ToolOutlined, CodeOutlined } from "@ant-design/icons";
821
+ import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
822
+ var { Text: Text3, Title } = Typography3;
823
+ var useStyle2 = createStyles2(({ token, css }) => ({
824
+ card: css`
825
+ max-width: 500px;
826
+ background: linear-gradient(
827
+ 135deg,
828
+ rgba(24, 144, 255, 0.05) 0%,
829
+ rgba(135, 208, 104, 0.05) 100%
830
+ );
831
+ border: 1px solid ${token.colorBorderSecondary};
832
+ border-radius: 12px;
833
+ transition: all 0.3s ease;
834
+ &:hover {
835
+ border-color: ${token.colorPrimary};
836
+ box-shadow: 0 4px 12px rgba(24, 144, 255, 0.15);
837
+ transform: translateY(-2px);
838
+ }
839
+ `,
840
+ header: css`
841
+ border-bottom: 1px solid ${token.colorBorderSecondary};
842
+ margin-bottom: 12px;
843
+ padding-bottom: 8px;
844
+ `,
845
+ toolName: css`
846
+ color: ${token.colorPrimary};
847
+ font-weight: 600;
848
+ font-size: 16px;
849
+ `,
850
+ parameterGrid: css`
851
+ display: grid;
852
+ gap: 8px;
853
+ margin-top: 8px;
854
+ `,
855
+ parameterItem: css`
856
+ background: ${token.colorBgContainer};
857
+ border: 1px solid ${token.colorBorderSecondary};
858
+ border-radius: 6px;
859
+ padding: 8px 12px;
860
+ transition: background-color 0.2s ease;
861
+ &:hover {
862
+ background: ${token.colorBgTextHover};
863
+ }
864
+ `,
865
+ parameterName: css`
866
+ color: ${token.colorTextSecondary};
867
+ font-size: 12px;
868
+ font-weight: 500;
869
+ margin-bottom: 4px;
870
+ `,
871
+ parameterValue: css`
872
+ color: ${token.colorText};
873
+ font-family: "SF Mono", "Monaco", "Inconsolata", "Roboto Mono", monospace;
874
+ font-size: 13px;
875
+ word-break: break-all;
876
+ line-height: 1.4;
877
+ `,
878
+ typeTag: css`
879
+ font-size: 10px;
880
+ border-radius: 4px;
881
+ margin-left: 8px;
882
+ `
883
+ }));
884
+ var ToolCard = ({
885
+ data,
886
+ component_key,
887
+ eventHandler,
888
+ interactive = true
889
+ }) => {
890
+ const { styles } = useStyle2();
891
+ if (!data || !data.name) {
892
+ return /* @__PURE__ */ jsx5(Card3, { size: "small", className: styles.card, bordered: false, children: /* @__PURE__ */ jsx5(Text3, { type: "secondary", children: "Invalid tool data" }) });
893
+ }
894
+ const formatToolName = (name) => {
895
+ return name.replace(/([a-z])([A-Z])/g, "$1 $2").split(/[_-]/).map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
896
+ };
897
+ const formatParameterValue = (value) => {
898
+ if (value === null || value === void 0) {
899
+ return "null";
900
+ }
901
+ if (typeof value === "object") {
902
+ try {
903
+ const jsonStr = JSON.stringify(value, null, 2);
904
+ return jsonStr.length > 100 ? JSON.stringify(value) : jsonStr;
905
+ } catch {
906
+ return String(value);
907
+ }
908
+ }
909
+ if (typeof value === "string" && value.length > 150) {
910
+ return value.substring(0, 150) + "...";
911
+ }
912
+ return String(value);
913
+ };
914
+ const getTypeColor = (value) => {
915
+ const type = typeof value;
916
+ switch (type) {
917
+ case "string":
918
+ return "blue";
919
+ case "number":
920
+ return "green";
921
+ case "boolean":
922
+ return "orange";
923
+ case "object":
924
+ return value === null ? "default" : "purple";
925
+ default:
926
+ return "default";
927
+ }
928
+ };
929
+ const getTypeLabel = (value) => {
930
+ if (value === null) return "null";
931
+ if (Array.isArray(value)) return "array";
932
+ return typeof value;
933
+ };
934
+ const hasParameters = data.parameters && Object.keys(data.parameters).length > 0;
935
+ return /* @__PURE__ */ jsxs3(
936
+ Card3,
937
+ {
938
+ size: "small",
939
+ className: styles.card,
940
+ bordered: false,
941
+ bodyStyle: { padding: "16px" },
942
+ children: [
943
+ /* @__PURE__ */ jsxs3("div", { className: styles.header, children: [
944
+ /* @__PURE__ */ jsxs3(Space3, { align: "center", children: [
945
+ /* @__PURE__ */ jsx5(ToolOutlined, { style: { color: "#1890ff", fontSize: "18px" } }),
946
+ /* @__PURE__ */ jsx5(Title, { level: 5, className: styles.toolName, style: { margin: 0 }, children: formatToolName(data.name) }),
947
+ data.type && /* @__PURE__ */ jsx5(Tag2, { color: "blue", className: styles.typeTag, children: data.type })
948
+ ] }),
949
+ data.description && /* @__PURE__ */ jsx5(
950
+ Text3,
951
+ {
952
+ type: "secondary",
953
+ style: { fontSize: "13px", marginTop: "4px", display: "block" },
954
+ children: data.description
955
+ }
956
+ )
957
+ ] }),
958
+ hasParameters ? /* @__PURE__ */ jsxs3("div", { children: [
959
+ /* @__PURE__ */ jsxs3(Space3, { align: "center", style: { marginBottom: "12px" }, children: [
960
+ /* @__PURE__ */ jsx5(CodeOutlined, { style: { color: "#52c41a", fontSize: "14px" } }),
961
+ /* @__PURE__ */ jsxs3(Text3, { strong: true, style: { fontSize: "14px" }, children: [
962
+ "Parameters (",
963
+ Object.keys(data.parameters).length,
964
+ ")"
965
+ ] })
966
+ ] }),
967
+ /* @__PURE__ */ jsx5("div", { className: styles.parameterGrid, children: Object.entries(data.parameters).map(([key, value], index) => /* @__PURE__ */ jsxs3("div", { className: styles.parameterItem, children: [
968
+ /* @__PURE__ */ jsx5("div", { className: styles.parameterName, children: /* @__PURE__ */ jsxs3(Space3, { align: "center", children: [
969
+ /* @__PURE__ */ jsx5("span", { children: key }),
970
+ /* @__PURE__ */ jsx5(
971
+ Tag2,
972
+ {
973
+ color: getTypeColor(value),
974
+ style: { fontSize: "10px", marginLeft: "auto" },
975
+ children: getTypeLabel(value)
976
+ }
977
+ )
978
+ ] }) }),
979
+ /* @__PURE__ */ jsx5("div", { className: styles.parameterValue, children: formatParameterValue(value) })
980
+ ] }, index)) })
981
+ ] }) : /* @__PURE__ */ jsxs3(Space3, { align: "center", children: [
982
+ /* @__PURE__ */ jsx5(CodeOutlined, { style: { color: "#d9d9d9", fontSize: "14px" } }),
983
+ /* @__PURE__ */ jsx5(Text3, { type: "secondary", style: { fontSize: "13px" }, children: "No parameters" })
984
+ ] })
985
+ ]
986
+ }
987
+ );
988
+ };
989
+
990
+ // src/components/GenUI/elements/ToolCall.tsx
991
+ import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
992
+ function getStatusIcon(status) {
993
+ switch (status) {
994
+ case "success":
995
+ return /* @__PURE__ */ jsx6(CheckCircleOutlined, { style: { color: "#52c41a" } });
996
+ case "error":
997
+ return /* @__PURE__ */ jsx6(InfoCircleOutlined, { style: { color: "#ff4d4f" } });
998
+ default:
999
+ return /* @__PURE__ */ jsx6(LoadingOutlined, { style: { color: "#1890ff" } });
1000
+ }
1001
+ }
1002
+ var ToolCall = ({ data }) => {
1003
+ const toolCallData = data;
1004
+ const formatToolName = (name) => {
1005
+ return name.replace(/([a-z])([A-Z])/g, "$1 $2").split(/[_-]/).map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
1006
+ };
1007
+ const formatArgsPreview = (args) => {
1008
+ try {
1009
+ const argsStr = Object.values(args).map((value) => {
1010
+ const valueStr = typeof value === "object" ? JSON.stringify(value).substring(0, 50) + (JSON.stringify(value).length > 50 ? "..." : "") : String(value).substring(0, 50) + (String(value).length > 50 ? "..." : "");
1011
+ return valueStr;
1012
+ }).join(" ");
1013
+ const result = argsStr.length > 100 ? argsStr.substring(0, 100) + "..." : argsStr;
1014
+ return result.replaceAll("\n", " ");
1015
+ } catch (e) {
1016
+ return "Error parsing args";
1017
+ }
1018
+ };
1019
+ const header = /* @__PURE__ */ jsxs4(Flex2, { align: "center", wrap: "wrap", children: [
1020
+ /* @__PURE__ */ jsx6(Typography4.Text, { strong: true, children: formatToolName(toolCallData.name) }),
1021
+ /* @__PURE__ */ jsx6(
1022
+ Typography4.Text,
1023
+ {
1024
+ type: "secondary",
1025
+ style: { fontSize: "12px", marginLeft: "8px" },
1026
+ children: formatArgsPreview(toolCallData.args)
1027
+ }
1028
+ )
1029
+ ] });
1030
+ const toolCardData = {
1031
+ name: toolCallData.name,
1032
+ parameters: toolCallData.args,
1033
+ type: "tool_call"
1034
+ };
1035
+ const content = /* @__PURE__ */ jsxs4("div", { style: { marginTop: "8px" }, children: [
1036
+ /* @__PURE__ */ jsx6(
1037
+ ToolCard,
1038
+ {
1039
+ data: toolCardData,
1040
+ component_key: `${toolCallData.id}-params`,
1041
+ eventHandler: () => {
1042
+ },
1043
+ interactive: false
1044
+ }
1045
+ ),
1046
+ toolCallData.response && /* @__PURE__ */ jsxs4("div", { style: { marginTop: "12px" }, children: [
1047
+ /* @__PURE__ */ jsx6(
1048
+ Typography4.Text,
1049
+ {
1050
+ strong: true,
1051
+ style: { fontSize: "12px", marginBottom: "8px", display: "block" },
1052
+ children: "Response:"
1053
+ }
1054
+ ),
1055
+ /* @__PURE__ */ jsx6(MDResponse, { content: toolCallData.response })
1056
+ ] })
1057
+ ] });
1058
+ const expandIcon = ({ isActive }) => {
1059
+ return getStatusIcon(toolCallData.status);
1060
+ };
1061
+ return /* @__PURE__ */ jsx6(
1062
+ Collapse,
1063
+ {
1064
+ size: "small",
1065
+ bordered: false,
1066
+ defaultActiveKey: [],
1067
+ expandIcon,
1068
+ children: /* @__PURE__ */ jsx6(
1069
+ CollapsePanel,
1070
+ {
1071
+ header,
1072
+ style: { minWidth: 400 },
1073
+ children: content
1074
+ },
1075
+ toolCallData.id
1076
+ )
1077
+ }
1078
+ );
1079
+ };
1080
+
1081
+ // src/components/GenUI/elements/Todo.tsx
1082
+ import { Card as Card4, List, Typography as Typography5, Space as Space5 } from "antd";
1083
+ import { createStyles as createStyles3 } from "antd-style";
1084
+ import {
1085
+ CheckCircleOutlined as CheckCircleOutlined2,
1086
+ ClockCircleOutlined,
1087
+ LoadingOutlined as LoadingOutlined2
1088
+ } from "@ant-design/icons";
1089
+ import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
1090
+ var { Text: Text4 } = Typography5;
1091
+ var useStyle3 = createStyles3(({ token, css }) => ({
1092
+ card: css`
1093
+ max-width: 1200px;
1094
+ background: linear-gradient(
1095
+ 919deg,
1096
+ rgb(67 232 157 / 8%),
1097
+ rgb(206 250 235 / 28%) 43%
1098
+ );
1099
+ `,
1100
+ todoItem: css`
1101
+ padding: 8px 0;
1102
+ border-bottom: 1px solid ${token.colorBorderSecondary};
1103
+ &:last-child {
1104
+ border-bottom: none;
1105
+ }
1106
+ `,
1107
+ completed: css`
1108
+ opacity: 0.7;
1109
+ `,
1110
+ inProgress: css`
1111
+ font-weight: 500;
1112
+ `,
1113
+ pending: css`
1114
+ opacity: 0.8;
1115
+ `
1116
+ }));
1117
+ var Todo = ({
1118
+ data,
1119
+ component_key,
1120
+ eventHandler,
1121
+ interactive = true
1122
+ }) => {
1123
+ const { styles } = useStyle3();
1124
+ const getStatusIcon3 = (status) => {
1125
+ switch (status) {
1126
+ case "completed":
1127
+ return /* @__PURE__ */ jsx7(CheckCircleOutlined2, { style: { color: "#52c41a" } });
1128
+ case "in_progress":
1129
+ return /* @__PURE__ */ jsx7(LoadingOutlined2, { style: { color: "#1890ff" } });
1130
+ case "pending":
1131
+ return /* @__PURE__ */ jsx7(ClockCircleOutlined, { style: { color: "gray" } });
1132
+ default:
1133
+ return null;
1134
+ }
1135
+ };
1136
+ const getStatusColor = (status) => {
1137
+ switch (status) {
1138
+ case "completed":
1139
+ return "success";
1140
+ case "in_progress":
1141
+ return "processing";
1142
+ case "pending":
1143
+ return "warning";
1144
+ default:
1145
+ return "default";
1146
+ }
1147
+ };
1148
+ const getStatusText = (status) => {
1149
+ switch (status) {
1150
+ case "completed":
1151
+ return "Completed";
1152
+ case "in_progress":
1153
+ return "In Progress";
1154
+ case "pending":
1155
+ return "Pending";
1156
+ default:
1157
+ return status;
1158
+ }
1159
+ };
1160
+ const getItemClassName = (status) => {
1161
+ switch (status) {
1162
+ case "completed":
1163
+ return styles.completed;
1164
+ case "in_progress":
1165
+ return styles.inProgress;
1166
+ case "pending":
1167
+ return styles.pending;
1168
+ default:
1169
+ return "";
1170
+ }
1171
+ };
1172
+ if (!data || !Array.isArray(data)) {
1173
+ return /* @__PURE__ */ jsx7(
1174
+ Card4,
1175
+ {
1176
+ size: "small",
1177
+ className: `shadow-sm ${styles.card}`,
1178
+ bordered: false,
1179
+ children: /* @__PURE__ */ jsx7(Text4, { type: "secondary", children: "No todo items available" })
1180
+ }
1181
+ );
1182
+ }
1183
+ return /* @__PURE__ */ jsx7(Card4, { size: "small", className: `shadow-sm ${styles.card}`, bordered: false, children: /* @__PURE__ */ jsxs5(Space5, { direction: "vertical", style: { width: "100%" }, children: [
1184
+ /* @__PURE__ */ jsx7(
1185
+ List,
1186
+ {
1187
+ size: "small",
1188
+ dataSource: data,
1189
+ renderItem: (item, index) => /* @__PURE__ */ jsx7(
1190
+ List.Item,
1191
+ {
1192
+ className: `${styles.todoItem} ${getItemClassName(item.status)}`,
1193
+ children: /* @__PURE__ */ jsxs5(Space5, { align: "center", style: { width: "100%" }, children: [
1194
+ getStatusIcon3(item.status),
1195
+ /* @__PURE__ */ jsx7(Text4, { style: { flex: 1 }, children: item.content })
1196
+ ] })
1197
+ }
1198
+ )
1199
+ }
1200
+ ),
1201
+ /* @__PURE__ */ jsxs5(Text4, { type: "secondary", style: { fontSize: 12 }, children: [
1202
+ "Total items: ",
1203
+ data.length,
1204
+ " | Completed:",
1205
+ " ",
1206
+ data.filter((item) => item.status === "completed").length,
1207
+ " | In Progress:",
1208
+ " ",
1209
+ data.filter((item) => item.status === "in_progress").length,
1210
+ " | Pending: ",
1211
+ data.filter((item) => item.status === "pending").length
1212
+ ] })
1213
+ ] }) });
1214
+ };
1215
+
1216
+ // src/components/GenUI/elements/index.tsx
1217
+ var elements = {
1218
+ action_show_attachments_uploader: {
1219
+ card_view: () => null,
1220
+ action: (data) => {
1221
+ console.log(data);
1222
+ }
1223
+ },
1224
+ generic_data_table: {
1225
+ card_view: GenericDataTable,
1226
+ side_app_view: GenericDataTableSideApp
1227
+ },
1228
+ confirm: {
1229
+ card_view: ConfirmFeedback
1230
+ },
1231
+ tool_call: {
1232
+ card_view: ToolCall
1233
+ },
1234
+ tool_card: {
1235
+ card_view: ToolCard
1236
+ },
1237
+ todo_list: {
1238
+ card_view: Todo
1239
+ }
1240
+ };
1241
+ var getElement = (language) => {
1242
+ if (language && elements[language]) {
1243
+ return elements[language];
1244
+ }
1245
+ return null;
1246
+ };
1247
+ var regsiterElement = (language, ElementMeta) => {
1248
+ console.log("regsiterElement", language, ElementMeta);
1249
+ elements[language] = ElementMeta;
1250
+ return ElementMeta;
1251
+ };
1252
+
1253
+ // src/components/GenUI/MDMermaid.tsx
1254
+ import mermaid from "mermaid";
1255
+ import { useEffect as useEffect4, useRef as useRef3 } from "react";
1256
+ import { v4 } from "uuid";
1257
+ import { jsx as jsx8 } from "react/jsx-runtime";
1258
+ var MDMermaid = ({ children = [] }) => {
1259
+ const domId = useRef3(`dom${v4()}`);
1260
+ const code = String(children);
1261
+ const target = useRef3(null);
1262
+ const targetInternal = useRef3(null);
1263
+ useEffect4(() => {
1264
+ if (target.current && code) {
1265
+ mermaid.initialize({
1266
+ startOnLoad: true,
1267
+ theme: "default",
1268
+ securityLevel: "loose",
1269
+ themeCSS: `
1270
+ g.classGroup rect {
1271
+ fill: #282a36;
1272
+ stroke: #6272a4;
1273
+ }
1274
+ g.classGroup text {
1275
+ fill: #f8f8f2;
1276
+ }
1277
+ g.classGroup line {
1278
+ stroke: #f8f8f2;
1279
+ stroke-width: 0.5;
1280
+ }
1281
+ .classLabel .box {
1282
+ stroke: #21222c;
1283
+ stroke-width: 3;
1284
+ fill: #21222c;
1285
+ opacity: 1;
1286
+ }
1287
+ .classLabel .label {
1288
+ fill: #f1fa8c;
1289
+ }
1290
+ .relation {
1291
+ stroke: #ff79c6;
1292
+ stroke-width: 1;
1293
+ }
1294
+ #compositionStart, #compositionEnd {
1295
+ fill: #bd93f9;
1296
+ stroke: #bd93f9;
1297
+ stroke-width: 1;
1298
+ }
1299
+ #aggregationEnd, #aggregationStart {
1300
+ fill: #21222c;
1301
+ stroke: #50fa7b;
1302
+ stroke-width: 1;
1303
+ }
1304
+ #dependencyStart, #dependencyEnd {
1305
+ fill: #00bcd4;
1306
+ stroke: #00bcd4;
1307
+ stroke-width: 1;
1308
+ }
1309
+ #extensionStart, #extensionEnd {
1310
+ fill: #f8f8f2;
1311
+ stroke: #f8f8f2;
1312
+ stroke-width: 1;
1313
+ }
1314
+ `,
1315
+ fontFamily: "Fira Code",
1316
+ sequence: { showSequenceNumbers: true }
1317
+ });
1318
+ mermaid.render(domId.current, code, target.current).then((result) => {
1319
+ target.current.innerHTML = result.svg;
1320
+ }).catch((error) => {
1321
+ console.log(error);
1322
+ });
1323
+ }
1324
+ }, [code]);
1325
+ return /* @__PURE__ */ jsx8("div", { style: { minWidth: 750 }, ref: target, children: /* @__PURE__ */ jsx8("code", { id: domId.current, style: { display: "none" } }) });
1326
+ };
1327
+
1328
+ // src/components/GenUI/MDResponse.tsx
1329
+ import { jsx as jsx9 } from "react/jsx-runtime";
1330
+ var SyntaxHighlighter = Prism;
1331
+ var useStyles = createStyles4(({ token, css }) => ({
1332
+ markdownTableContainer: css`
1333
+ overflow-x: auto;
1334
+ width: 100%;
1335
+ `,
1336
+ markdownTable: css`
1337
+ width: 100%;
1338
+ border-collapse: collapse;
1339
+ margin: 16px 0;
1340
+ border-radius: ${token.borderRadius}px;
1341
+ overflow: hidden;
1342
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
1343
+ white-space: nowrap;
1344
+ `,
1345
+ markdownTh: css`
1346
+ background: ${token.colorFillAlter};
1347
+ padding: 12px 16px;
1348
+ text-align: left;
1349
+ font-weight: 600;
1350
+ border-bottom: 1px solid ${token.colorBorder};
1351
+ color: ${token.colorTextHeading};
1352
+ font-size: ${token.fontSize}px;
1353
+ `,
1354
+ markdownTd: css`
1355
+ padding: 12px 16px;
1356
+ border-bottom: 1px solid ${token.colorBorder};
1357
+ color: ${token.colorText};
1358
+ font-size: ${token.fontSize}px;
1359
+
1360
+ &:last-child {
1361
+ border-right: none;
1362
+ }
1363
+ `,
1364
+ markdownTr: css`
1365
+ &:hover {
1366
+ background: ${token.colorFillTertiary};
1367
+ }
1368
+
1369
+ &:last-child td {
1370
+ border-bottom: none;
1371
+ }
1372
+ `,
1373
+ markdownContainer: css`
1374
+ white-space: normal;
1375
+
1376
+ /* 为整个markdown内容添加基础样式 */
1377
+ h1,
1378
+ h2,
1379
+ h3,
1380
+ h4,
1381
+ h5,
1382
+ h6 {
1383
+ color: ${token.colorTextHeading};
1384
+ margin-top: 24px;
1385
+ margin-bottom: 16px;
1386
+ }
1387
+
1388
+ p {
1389
+ color: ${token.colorText};
1390
+ line-height: 1.6;
1391
+ margin-bottom: 16px;
1392
+ }
1393
+
1394
+ blockquote {
1395
+ border-left: 4px solid ${token.colorPrimary};
1396
+ background: ${token.colorFillAlter};
1397
+ padding: 16px;
1398
+ margin: 16px 0;
1399
+ border-radius: 0 ${token.borderRadius}px ${token.borderRadius}px 0;
1400
+ }
1401
+
1402
+ code:not(pre code) {
1403
+ background: ${token.colorFillAlter};
1404
+ padding: 2px 6px;
1405
+ border-radius: ${token.borderRadius}px;
1406
+ font-family: ${token.fontFamilyCode};
1407
+ color: ${token.colorError};
1408
+ }
1409
+ `
1410
+ }));
1411
+ var MDResponse = ({
1412
+ content = "",
1413
+ context,
1414
+ embeddedLink,
1415
+ interactive,
1416
+ userData,
1417
+ noGenUI,
1418
+ eventHandler
1419
+ }) => {
1420
+ const { styles } = useStyles();
1421
+ const config = useMemo2(
1422
+ () => ({
1423
+ components: {
1424
+ a({ node, ...props }) {
1425
+ if (embeddedLink) {
1426
+ return /* @__PURE__ */ jsx9(IFrameCard, { src: props.href });
1427
+ } else return /* @__PURE__ */ jsx9("a", { ...props });
1428
+ },
1429
+ table({ node, ...props }) {
1430
+ return /* @__PURE__ */ jsx9("div", { className: styles.markdownTableContainer, children: /* @__PURE__ */ jsx9("table", { className: styles.markdownTable, ...props }) });
1431
+ },
1432
+ th({ node, ...props }) {
1433
+ return /* @__PURE__ */ jsx9("th", { className: styles.markdownTh, ...props });
1434
+ },
1435
+ td({ node, ...props }) {
1436
+ return /* @__PURE__ */ jsx9("td", { className: styles.markdownTd, ...props });
1437
+ },
1438
+ tr({ node, ...props }) {
1439
+ return /* @__PURE__ */ jsx9("tr", { className: styles.markdownTr, ...props });
1440
+ },
1441
+ code({ children, className, node, ...rest }) {
1442
+ const match = /language-(\w+)/.exec(className || "");
1443
+ const language = match?.[1];
1444
+ if (language) {
1445
+ const Element = getElement(language)?.card_view;
1446
+ if (Element) {
1447
+ let childrenData;
1448
+ try {
1449
+ childrenData = JSON.parse(children);
1450
+ } catch (error) {
1451
+ }
1452
+ return /* @__PURE__ */ jsx9(
1453
+ Element,
1454
+ {
1455
+ interactive,
1456
+ component_key: language,
1457
+ data: childrenData,
1458
+ eventHandler: (e, data, message2, agent) => {
1459
+ eventHandler?.(e, data, message2, agent);
1460
+ }
1461
+ }
1462
+ );
1463
+ }
1464
+ switch (language) {
1465
+ case "mermaid":
1466
+ return /* @__PURE__ */ jsx9(MDMermaid, { children });
1467
+ default:
1468
+ return /* @__PURE__ */ jsx9(
1469
+ SyntaxHighlighter,
1470
+ {
1471
+ ...rest,
1472
+ PreTag: "div",
1473
+ language,
1474
+ style: dark,
1475
+ children: String(children).replace(/\n$/, "")
1476
+ }
1477
+ );
1478
+ }
1479
+ } else {
1480
+ return /* @__PURE__ */ jsx9("code", { ...rest, className, children });
1481
+ }
1482
+ }
1483
+ },
1484
+ remarkPlugins: [remarkGfm],
1485
+ rehypePlugins: [rehypeRaw]
1486
+ }),
1487
+ [userData, interactive, embeddedLink, styles]
1488
+ );
1489
+ return /* @__PURE__ */ jsx9("div", { className: styles.markdownContainer, children: /* @__PURE__ */ jsx9(ReactMarkdown, { ...config, children: content }) });
1490
+ };
1491
+ var MDViewFormItem = ({ value }) => {
1492
+ return /* @__PURE__ */ jsx9(MDResponse, { content: value || "" });
1493
+ };
1494
+ var IFrameCard = ({ src }) => {
1495
+ const containerRef = useRef4(null);
1496
+ const [width, setWidth] = useState7("640px");
1497
+ const [height, setHeight] = useState7("320px");
1498
+ const valid_images = [
1499
+ "jpg",
1500
+ "jpeg",
1501
+ "png",
1502
+ "gif",
1503
+ "bmp",
1504
+ "svg",
1505
+ "tif",
1506
+ "tiff",
1507
+ "webp"
1508
+ ];
1509
+ if (!src) {
1510
+ return null;
1511
+ }
1512
+ const spitedSrc = src.split(".");
1513
+ if (valid_images.includes(spitedSrc[spitedSrc.length - 1].toLowerCase())) {
1514
+ return /* @__PURE__ */ jsx9("div", { children: /* @__PURE__ */ jsx9("img", { src, style: { width: "100%" } }) });
1515
+ } else {
1516
+ return /* @__PURE__ */ jsx9("div", { children: /* @__PURE__ */ jsx9("a", { href: src, target: "_black", children: src }) });
1517
+ }
1518
+ };
1519
+
1520
+ // src/components/Chat/Chating.tsx
1521
+ import {
1522
+ CloudUploadOutlined,
1523
+ PaperClipOutlined
1524
+ } from "@ant-design/icons";
1525
+ import {
1526
+ Attachments,
1527
+ Bubble,
1528
+ Prompts,
1529
+ Sender,
1530
+ Welcome
1531
+ } from "@ant-design/x";
1532
+ import {
1533
+ Avatar,
1534
+ Badge,
1535
+ Button as Button3,
1536
+ Flex as Flex3,
1537
+ Space as Space6,
1538
+ message
1539
+ } from "antd";
1540
+ import ErrorBoundary from "antd/es/alert/ErrorBoundary";
1541
+ import React2, {
1542
+ memo,
1543
+ useCallback as useCallback5,
1544
+ useEffect as useEffect5,
1545
+ useMemo as useMemo3,
1546
+ useRef as useRef5,
1547
+ useState as useState8
1548
+ } from "react";
1549
+ import { useTranslation } from "react-i18next";
1550
+ import { Fragment, jsx as jsx10, jsxs as jsxs6 } from "react/jsx-runtime";
1551
+ var LazyBubble = ({
1552
+ message: message2,
1553
+ renderContent,
1554
+ autoLoadRightPanel
1555
+ }) => {
1556
+ const ref = useRef5(null);
1557
+ const [isVisible, setIsVisible] = useState8(false);
1558
+ const [wasEverVisible, setWasEverVisible] = useState8(false);
1559
+ useEffect5(() => {
1560
+ const observer = new IntersectionObserver(
1561
+ ([entry]) => {
1562
+ const visible = entry.isIntersecting;
1563
+ setIsVisible(visible);
1564
+ if (visible && !wasEverVisible) {
1565
+ setWasEverVisible(true);
1566
+ }
1567
+ },
1568
+ { threshold: 0.1 }
1569
+ );
1570
+ if (ref.current) {
1571
+ observer.observe(ref.current);
1572
+ }
1573
+ return () => {
1574
+ if (ref.current) {
1575
+ observer.unobserve(ref.current);
1576
+ }
1577
+ };
1578
+ }, [wasEverVisible]);
1579
+ useEffect5(() => {
1580
+ autoLoadRightPanel?.();
1581
+ }, []);
1582
+ const getPlaceholder = () => {
1583
+ const estimatedHeight = message2.content ? Math.min(100, message2.content.length / 5) : 100;
1584
+ return /* @__PURE__ */ jsx10("div", { style: { height: `${estimatedHeight}px`, minHeight: "50px" } });
1585
+ };
1586
+ return /* @__PURE__ */ jsx10(ErrorBoundary, { children: /* @__PURE__ */ jsx10("div", { ref, style: { width: "100%" }, children: isVisible || wasEverVisible ? renderContent(message2) : getPlaceholder() }) });
1587
+ };
1588
+ var MemoizedBubbleList = memo(
1589
+ ({
1590
+ items,
1591
+ roles,
1592
+ className
1593
+ }) => /* @__PURE__ */ jsx10(
1594
+ Bubble.List,
1595
+ {
1596
+ autoScroll: true,
1597
+ items,
1598
+ roles,
1599
+ className
1600
+ },
1601
+ "messages"
1602
+ )
1603
+ );
1604
+ MemoizedBubbleList.displayName = "MemoizedBubbleList";
1605
+ var Chating = ({
1606
+ avatar,
1607
+ name,
1608
+ description,
1609
+ default_submit_message,
1610
+ tenant_id,
1611
+ messages,
1612
+ isLoading,
1613
+ sendMessage,
1614
+ stopStreaming,
1615
+ onOpenSidePanel,
1616
+ onReminderClick,
1617
+ styles,
1618
+ reminderCount,
1619
+ handleMDResponseEvent,
1620
+ senderPromptsItems,
1621
+ extra,
1622
+ attachment_placeholder,
1623
+ extraMeta = []
1624
+ }) => {
1625
+ const { t } = useTranslation();
1626
+ const [content, setContent] = useState8("");
1627
+ const [attachedFiles, setAttachedFiles] = useState8([]);
1628
+ const [headerOpen, setHeaderOpen] = useState8(false);
1629
+ const attachmentsRef = useRef5(null);
1630
+ const senderRef = React2.useRef(null);
1631
+ useEffect5(() => {
1632
+ regsiterElement("action_show_attachments_uploader", {
1633
+ card_view: () => null,
1634
+ action: (data) => {
1635
+ console.log(data);
1636
+ setHeaderOpen(true);
1637
+ }
1638
+ });
1639
+ }, []);
1640
+ const messageLengthRef = useRef5(messages?.length ?? 0);
1641
+ useEffect5(() => {
1642
+ if (messages?.length) {
1643
+ messageLengthRef.current = messages?.length;
1644
+ }
1645
+ }, [messages?.length]);
1646
+ const renderContent = useCallback5(
1647
+ (message2) => {
1648
+ const { content: content2, files, id } = message2;
1649
+ try {
1650
+ const json = JSON.parse(content2);
1651
+ if (json.action && json.message) {
1652
+ return /* @__PURE__ */ jsx10(
1653
+ MDResponse,
1654
+ {
1655
+ content: json.message,
1656
+ eventHandler: handleMDResponseEvent
1657
+ }
1658
+ );
1659
+ }
1660
+ } catch (error) {
1661
+ }
1662
+ const tool_calls_md = message2.tool_calls?.map((tool_call) => {
1663
+ return `\`\`\`tool_call
1664
+ ${JSON.stringify(tool_call)}
1665
+ \`\`\``;
1666
+ }) || [];
1667
+ const content_md = [content2, ...tool_calls_md].join("\n");
1668
+ return /* @__PURE__ */ jsx10(Space6, { direction: "vertical", style: { width: "100%" }, children: /* @__PURE__ */ jsx10(
1669
+ MDResponse,
1670
+ {
1671
+ content: content_md,
1672
+ eventHandler: handleMDResponseEvent
1673
+ }
1674
+ ) });
1675
+ },
1676
+ [handleMDResponseEvent]
1677
+ );
1678
+ const items = useMemo3(
1679
+ () => messages.map((message2, index) => ({
1680
+ key: message2.id,
1681
+ role: message2.role,
1682
+ typing: false,
1683
+ content: /* @__PURE__ */ jsx10(
1684
+ LazyBubble,
1685
+ {
1686
+ message: message2,
1687
+ renderContent,
1688
+ autoLoadRightPanel: () => {
1689
+ const { content: content2, role } = message2;
1690
+ const isNewAddedMessage = messageLengthRef.current > 1 && messageLengthRef.current + 1 === messages.length;
1691
+ if (index === messages.length - 1 && isNewAddedMessage && role === "ai") {
1692
+ try {
1693
+ const match = content2?.match(
1694
+ /```([\w_]*)\n({.*?}|[^`]*)\n```/m
1695
+ );
1696
+ const type = match?.[1];
1697
+ const data = match?.[2];
1698
+ const jsonData = data ? JSON.parse(data) : {};
1699
+ if (type) {
1700
+ const element = getElement(type);
1701
+ if (element?.side_app_view) {
1702
+ onOpenSidePanel({
1703
+ component_key: type,
1704
+ data: jsonData
1705
+ });
1706
+ } else if (element?.action) {
1707
+ element.action(jsonData);
1708
+ }
1709
+ }
1710
+ } catch (error) {
1711
+ console.error(error);
1712
+ }
1713
+ }
1714
+ }
1715
+ }
1716
+ )
1717
+ })),
1718
+ [messages, renderContent, onOpenSidePanel]
1719
+ );
1720
+ const isArchiveFile = (file) => {
1721
+ const zipMimeTypes = ["application/zip"];
1722
+ const rarMimeTypes = [
1723
+ "application/vnd.rar",
1724
+ "application/x-rar-compressed",
1725
+ "application/rar"
1726
+ ];
1727
+ const archiveMimeTypes = [...zipMimeTypes, ...rarMimeTypes];
1728
+ return archiveMimeTypes.includes(file.type) || file.name.toLowerCase().endsWith(".zip") || file.name.toLowerCase().endsWith(".rar");
1729
+ };
1730
+ const onSubmit = (nextContent) => {
1731
+ if (!nextContent && attachedFiles.length === 0) return;
1732
+ if (attachedFiles.filter((f) => f.status !== "done").length > 0) {
1733
+ message.warning("\u6587\u4EF6\u8FD8\u5728\u4E0A\u4F20\u4E2D...");
1734
+ return;
1735
+ }
1736
+ if (!nextContent && attachedFiles.length > 0) {
1737
+ nextContent = default_submit_message || "\u8BB0\u8D26";
1738
+ }
1739
+ const files = attachedFiles.map(
1740
+ (file) => isArchiveFile(file) ? {
1741
+ name: file.response.zipFileName || file.response.rarFileName,
1742
+ id: file.response.zipFileId || file.response.rarFileId,
1743
+ totalFiles: file.response.totalFiles,
1744
+ processedFiles: file.response.processedFiles,
1745
+ skippedFiles: file.response.skippedFiles,
1746
+ type: file.name.toLowerCase().endsWith(".rar") ? "application/rar" : "application/zip",
1747
+ files: file.response?.results?.map((r) => ({
1748
+ name: r.fileName,
1749
+ path: r.filePath,
1750
+ id: r.fileId
1751
+ }))
1752
+ } : {
1753
+ name: file.name,
1754
+ id: file.response.id
1755
+ }
1756
+ );
1757
+ const files_md = files.length > 0 ? [
1758
+ "",
1759
+ "\u6211\u5DF2\u7ECF\u63D0\u4EA4\u4E86\u4EE5\u4E0B\u6587\u4EF6\uFF1A",
1760
+ "```attachments",
1761
+ JSON.stringify(files),
1762
+ "```"
1763
+ ].join("\n") : "";
1764
+ sendMessage({ input: { message: nextContent + files_md, files } });
1765
+ setContent("");
1766
+ setAttachedFiles([]);
1767
+ setHeaderOpen(false);
1768
+ };
1769
+ const onPromptsItemClick = (info) => {
1770
+ onSubmit(info.data.description);
1771
+ };
1772
+ const onChange = (info) => {
1773
+ if (!headerOpen) {
1774
+ setHeaderOpen(true);
1775
+ }
1776
+ if (info.file?.response?.error || info.file.status === "error") {
1777
+ message.error(
1778
+ `${info.file.name} file upload failed.${info.file?.response?.message}`
1779
+ );
1780
+ }
1781
+ setAttachedFiles(info.fileList);
1782
+ if (info.file.status === "done") {
1783
+ console.log(`${info.file.name} file uploaded successfully`);
1784
+ }
1785
+ };
1786
+ const beforeUpload = (file) => {
1787
+ const isLessThan20MB = file.size / 1024 / 1024 < 20;
1788
+ if (!isLessThan20MB) {
1789
+ message.error(
1790
+ `File must be smaller than 20MB! ${file.name} is too large.`
1791
+ );
1792
+ return false;
1793
+ }
1794
+ return true;
1795
+ };
1796
+ const attachmentsNode = /* @__PURE__ */ jsx10(Badge, { dot: attachedFiles.length > 0 && !headerOpen, children: /* @__PURE__ */ jsx10(
1797
+ Button3,
1798
+ {
1799
+ type: "text",
1800
+ icon: /* @__PURE__ */ jsx10(PaperClipOutlined, {}),
1801
+ onClick: () => setHeaderOpen(!headerOpen)
1802
+ }
1803
+ ) });
1804
+ const senderHeader = /* @__PURE__ */ jsx10(
1805
+ Sender.Header,
1806
+ {
1807
+ title: "Attachments",
1808
+ open: headerOpen,
1809
+ onOpenChange: setHeaderOpen,
1810
+ styles: {
1811
+ content: {
1812
+ padding: 0
1813
+ }
1814
+ },
1815
+ forceRender: true,
1816
+ children: /* @__PURE__ */ jsx10(
1817
+ Attachments,
1818
+ {
1819
+ ref: attachmentsRef,
1820
+ items: attachedFiles,
1821
+ action: `/api/file_storage/upload?path=temp`,
1822
+ headers: {
1823
+ "x-tenant-id": tenant_id
1824
+ },
1825
+ getDropContainer: () => {
1826
+ const dropContainer = document.querySelector(".fina_chat");
1827
+ return dropContainer;
1828
+ },
1829
+ onDrop: (e) => {
1830
+ console.log(e);
1831
+ },
1832
+ onChange,
1833
+ beforeUpload,
1834
+ showUploadList: true,
1835
+ multiple: true,
1836
+ maxCount: 10,
1837
+ placeholder: (type) => ({
1838
+ icon: /* @__PURE__ */ jsx10(CloudUploadOutlined, {}),
1839
+ title: "\u4E0A\u4F20\u6587\u4EF6",
1840
+ description: attachment_placeholder
1841
+ })
1842
+ }
1843
+ )
1844
+ }
1845
+ );
1846
+ const roles = {
1847
+ ai: {
1848
+ placement: "start",
1849
+ typing: false,
1850
+ variant: "filled",
1851
+ styles: {
1852
+ content: {
1853
+ background: "transparent",
1854
+ padding: 0
1855
+ // "linear-gradient(149deg, rgb(160 17 2170 / 18%), rgb(226 176 176 / 18%) 43%)",
1856
+ }
1857
+ }
1858
+ },
1859
+ human: {
1860
+ placement: "end",
1861
+ variant: "filled",
1862
+ styles: {
1863
+ content: {
1864
+ maxWidth: "70%",
1865
+ background: "linear-gradient(1777deg, rgba(153, 164, 255, 0.38), rgb(231 243 248 / 38%) 27%)"
1866
+ }
1867
+ }
1868
+ }
1869
+ };
1870
+ const extraMetaComponents = useMemo3(() => {
1871
+ if (extraMeta?.length > 0) {
1872
+ return extraMeta.map((meta) => {
1873
+ const Element = getElement(meta.id)?.card_view;
1874
+ if (Element) {
1875
+ let childrenData;
1876
+ try {
1877
+ } catch (error) {
1878
+ }
1879
+ return /* @__PURE__ */ jsx10(
1880
+ Element,
1881
+ {
1882
+ component_key: meta.id,
1883
+ data: childrenData,
1884
+ eventHandler: (e, data, message2, agent) => {
1885
+ handleMDResponseEvent?.(e, data, message2, agent);
1886
+ }
1887
+ },
1888
+ meta.id
1889
+ );
1890
+ }
1891
+ });
1892
+ }
1893
+ return void 0;
1894
+ }, [extraMeta]);
1895
+ return /* @__PURE__ */ jsxs6(Fragment, { children: [
1896
+ /* @__PURE__ */ jsxs6("div", { children: [
1897
+ /* @__PURE__ */ jsx10(
1898
+ Welcome,
1899
+ {
1900
+ style: { padding: 8 },
1901
+ variant: "borderless",
1902
+ description,
1903
+ icon: /* @__PURE__ */ jsx10(Avatar, { src: avatar || "/images/avatar.jpeg", size: 48 }),
1904
+ title: name || "Fina",
1905
+ extra: extra || extraMetaComponents && /* @__PURE__ */ jsx10(Space6, { align: "center", style: { marginRight: 16 }, children: extraMetaComponents })
1906
+ }
1907
+ ),
1908
+ /* @__PURE__ */ jsx10(
1909
+ "div",
1910
+ {
1911
+ style: {
1912
+ background: "linear-gradient(rgba(41, 42, 45, .8) 0%, rgba(41, 42, 45, 0) 100%)"
1913
+ }
1914
+ }
1915
+ )
1916
+ ] }),
1917
+ items.length > 0 ? /* @__PURE__ */ jsx10(
1918
+ MemoizedBubbleList,
1919
+ {
1920
+ items,
1921
+ roles,
1922
+ className: styles.messages
1923
+ }
1924
+ ) : /* @__PURE__ */ jsx10("div", { style: { flex: 1 } }),
1925
+ isLoading ? /* @__PURE__ */ jsx10("div", { children: /* @__PURE__ */ jsx10(Bubble, { loading: isLoading, variant: "borderless" }) }) : /* @__PURE__ */ jsx10(Prompts, { items: senderPromptsItems, onItemClick: onPromptsItemClick }),
1926
+ /* @__PURE__ */ jsx10(
1927
+ Sender,
1928
+ {
1929
+ allowSpeech: true,
1930
+ ref: senderRef,
1931
+ value: content,
1932
+ header: senderHeader,
1933
+ onSubmit,
1934
+ onCancel: stopStreaming,
1935
+ onChange: setContent,
1936
+ prefix: attachmentsNode,
1937
+ loading: isLoading,
1938
+ className: styles.sender,
1939
+ actions: (ori, { components }) => {
1940
+ const { SendButton, LoadingButton } = components;
1941
+ return /* @__PURE__ */ jsx10(Flex3, { justify: "space-between", align: "center", children: isLoading ? /* @__PURE__ */ jsx10(LoadingButton, { type: "default" }) : /* @__PURE__ */ jsx10(
1942
+ SendButton,
1943
+ {
1944
+ type: "primary",
1945
+ disabled: !content && attachedFiles.length === 0,
1946
+ onClick: () => onSubmit(content)
1947
+ }
1948
+ ) });
1949
+ },
1950
+ onPasteFile: (_, files) => {
1951
+ Array.from(files).forEach((file) => {
1952
+ attachmentsRef.current?.upload(file);
1953
+ });
1954
+ setHeaderOpen(true);
1955
+ }
1956
+ }
1957
+ )
1958
+ ] });
1959
+ };
1960
+
1961
+ // src/components/Chat/ThinkingChain.tsx
1962
+ import {
1963
+ CheckCircleOutlined as CheckCircleOutlined3,
1964
+ InfoCircleOutlined as InfoCircleOutlined2,
1965
+ LoadingOutlined as LoadingOutlined3
1966
+ } from "@ant-design/icons";
1967
+ import {
1968
+ ThoughtChain
1969
+ } from "@ant-design/x";
1970
+ import { jsx as jsx11 } from "react/jsx-runtime";
1971
+ function getStatusIcon2(status) {
1972
+ switch (status) {
1973
+ case "success":
1974
+ return /* @__PURE__ */ jsx11(CheckCircleOutlined3, {});
1975
+ case "error":
1976
+ return /* @__PURE__ */ jsx11(InfoCircleOutlined2, {});
1977
+ case "pending":
1978
+ return /* @__PURE__ */ jsx11(LoadingOutlined3, {});
1979
+ default:
1980
+ return /* @__PURE__ */ jsx11(CheckCircleOutlined3, {});
1981
+ }
1982
+ }
1983
+ var ThinkingChain = ({ message: message2 }) => {
1984
+ const title = message2.name || message2.content.split("\n")[0];
1985
+ const items = [
1986
+ {
1987
+ key: message2.id,
1988
+ title,
1989
+ content: /* @__PURE__ */ jsx11(MDResponse, { content: message2.content }),
1990
+ status: message2.status,
1991
+ icon: getStatusIcon2(message2.status)
1992
+ }
1993
+ ];
1994
+ return /* @__PURE__ */ jsx11(
1995
+ ThoughtChain,
1996
+ {
1997
+ items,
1998
+ collapsible: message2.status === "success" ? true : false,
1999
+ size: "small"
2000
+ }
2001
+ );
2002
+ };
2003
+ var ThinkingChainGroup = ({ message: message2 }) => {
2004
+ const title = "\u601D\u8003\u8FC7\u7A0B";
2005
+ const children = message2.items?.map((item) => ({
2006
+ key: item.id,
2007
+ title: item.name || item.content.split("\n")[0],
2008
+ content: /* @__PURE__ */ jsx11(MDResponse, { content: item.content }),
2009
+ status: item.status,
2010
+ icon: getStatusIcon2(item.status)
2011
+ }));
2012
+ return /* @__PURE__ */ jsx11(ThoughtChain, { items: children, collapsible: true, size: "small" });
2013
+ };
2014
+
2015
+ // src/components/Chat/SideAppViewBrowser.tsx
2016
+ import {
2017
+ CloseOutlined,
2018
+ CompressOutlined,
2019
+ ExpandOutlined,
2020
+ FullscreenOutlined
2021
+ } from "@ant-design/icons";
2022
+ import { Button as Button4, Tabs } from "antd";
2023
+ import { createStyles as createStyles5 } from "antd-style";
2024
+ import { useEffect as useEffect6, useState as useState9 } from "react";
2025
+ import { jsx as jsx12, jsxs as jsxs7 } from "react/jsx-runtime";
2026
+ var useStyle4 = createStyles5(({ token, css }) => {
2027
+ return {
2028
+ tabContainer: css`
2029
+ .ant-tabs-content-holder {
2030
+ overflow: hidden;
2031
+ height: 100%;
2032
+ }
2033
+ .ant-tabs-content {
2034
+ overflow: hidden;
2035
+ height: 100%;
2036
+ }
2037
+ .ant-tabs-content > div {
2038
+ overflow: auto;
2039
+ height: 100%;
2040
+ }
2041
+ `
2042
+ };
2043
+ });
2044
+ var EmptySideAppView = ({ component_key, data }) => {
2045
+ return /* @__PURE__ */ jsxs7("div", { children: [
2046
+ /* @__PURE__ */ jsx12("p", { children: "\u672A\u627E\u5230\u5BF9\u5E94\u7684\u7EC4\u4EF6\u89C6\u56FE" }),
2047
+ /* @__PURE__ */ jsx12("pre", { children: JSON.stringify({ component_key, data }, null, 2) })
2048
+ ] });
2049
+ };
2050
+ var SideAppViewBrowser = ({
2051
+ open_uri,
2052
+ eventHandler,
2053
+ onClose,
2054
+ onChangeSize
2055
+ }) => {
2056
+ const { styles } = useStyle4();
2057
+ const [activeKey, setActiveKey] = useState9(JSON.stringify(open_uri));
2058
+ const [currentSize, setCurrentSize] = useState9(open_uri.size || "large");
2059
+ const [items, setItems] = useState9([]);
2060
+ const add = (key, label, children) => {
2061
+ const newActiveKey = key;
2062
+ const newPanes = [...items];
2063
+ newPanes.push({ label, children, key: newActiveKey });
2064
+ setItems(newPanes);
2065
+ setActiveKey(newActiveKey);
2066
+ };
2067
+ const remove = (targetKey) => {
2068
+ let newActiveKey = activeKey;
2069
+ let lastIndex = -1;
2070
+ items.forEach((item, i) => {
2071
+ if (item.key === targetKey) {
2072
+ lastIndex = i - 1;
2073
+ }
2074
+ });
2075
+ const newPanes = items.filter((item) => item.key !== targetKey);
2076
+ if (newPanes.length && newActiveKey === targetKey) {
2077
+ if (lastIndex >= 0) {
2078
+ newActiveKey = newPanes[lastIndex].key;
2079
+ } else {
2080
+ newActiveKey = newPanes[0].key;
2081
+ }
2082
+ }
2083
+ if (newPanes.length === 0) {
2084
+ onClose();
2085
+ return;
2086
+ }
2087
+ setItems(newPanes);
2088
+ setActiveKey(newActiveKey);
2089
+ };
2090
+ const onEdit = (targetKey, action) => {
2091
+ if (action === "remove") {
2092
+ remove(targetKey);
2093
+ }
2094
+ };
2095
+ useEffect6(() => {
2096
+ const SideAppView = getElement(open_uri.component_key).side_app_view || EmptySideAppView;
2097
+ const key = JSON.stringify(open_uri);
2098
+ if (items.find((item) => item.key === key)) {
2099
+ setActiveKey(key);
2100
+ return;
2101
+ }
2102
+ add(
2103
+ key,
2104
+ open_uri.message || open_uri.data.message || "\u672A\u547D\u540D",
2105
+ /* @__PURE__ */ jsx12(
2106
+ SideAppView,
2107
+ {
2108
+ component_key: open_uri.component_key,
2109
+ data: open_uri.data,
2110
+ eventHandler
2111
+ }
2112
+ )
2113
+ );
2114
+ }, [open_uri]);
2115
+ useEffect6(() => {
2116
+ if (open_uri.size && open_uri.size !== currentSize) {
2117
+ setCurrentSize(open_uri.size);
2118
+ }
2119
+ }, [open_uri.size]);
2120
+ const onChange = (newActiveKey) => {
2121
+ setActiveKey(newActiveKey);
2122
+ };
2123
+ const handleSizeChange = () => {
2124
+ const sizeOrder = [
2125
+ // 先不支持小屏和中间屏
2126
+ // "small",
2127
+ // "middle",
2128
+ "large",
2129
+ "full"
2130
+ ];
2131
+ const currentIndex = sizeOrder.indexOf(currentSize);
2132
+ const nextSize = sizeOrder[(currentIndex + 1) % sizeOrder.length];
2133
+ setCurrentSize(nextSize);
2134
+ onChangeSize(nextSize);
2135
+ };
2136
+ const getSizeLabel = (size) => {
2137
+ switch (size) {
2138
+ case "small":
2139
+ return "\u5C0F";
2140
+ case "middle":
2141
+ return "\u4E2D";
2142
+ case "large":
2143
+ return "\u5927";
2144
+ case "full":
2145
+ return "\u5168\u5C4F";
2146
+ default:
2147
+ return "\u4E2D";
2148
+ }
2149
+ };
2150
+ const getSizeIcon = (size) => {
2151
+ switch (size) {
2152
+ case "middle":
2153
+ return /* @__PURE__ */ jsx12(CompressOutlined, {});
2154
+ case "large":
2155
+ return /* @__PURE__ */ jsx12(ExpandOutlined, {});
2156
+ case "full":
2157
+ return /* @__PURE__ */ jsx12(FullscreenOutlined, {});
2158
+ default:
2159
+ return /* @__PURE__ */ jsx12(ExpandOutlined, {});
2160
+ }
2161
+ };
2162
+ return /* @__PURE__ */ jsx12(
2163
+ Tabs,
2164
+ {
2165
+ className: styles.tabContainer,
2166
+ type: "editable-card",
2167
+ style: { height: "100%" },
2168
+ hideAdd: true,
2169
+ tabBarExtraContent: {
2170
+ right: /* @__PURE__ */ jsxs7("div", { style: { display: "flex", gap: "4px" }, children: [
2171
+ /* @__PURE__ */ jsx12(
2172
+ Button4,
2173
+ {
2174
+ style: { margin: "8px 0" },
2175
+ size: "large",
2176
+ type: "text",
2177
+ icon: getSizeIcon(currentSize),
2178
+ onClick: handleSizeChange,
2179
+ title: `\u5F53\u524D\u5C3A\u5BF8: ${getSizeLabel(currentSize)}, \u70B9\u51FB\u5207\u6362`
2180
+ }
2181
+ ),
2182
+ /* @__PURE__ */ jsx12(
2183
+ Button4,
2184
+ {
2185
+ style: { margin: "8px 0" },
2186
+ size: "large",
2187
+ type: "text",
2188
+ icon: /* @__PURE__ */ jsx12(CloseOutlined, {}),
2189
+ onClick: () => {
2190
+ onClose();
2191
+ }
2192
+ }
2193
+ )
2194
+ ] })
2195
+ },
2196
+ onChange,
2197
+ activeKey,
2198
+ onEdit,
2199
+ items
2200
+ }
2201
+ );
2202
+ };
2203
+
2204
+ // src/components/Chat/context.tsx
2205
+ import { createContext as createContext2 } from "react";
2206
+ var chatContext = createContext2({
2207
+ eventHandler: (component_key, data, message2) => {
2208
+ }
2209
+ });
491
2210
  export {
492
2211
  AxiomLatticeProvider,
2212
+ Chating,
2213
+ MDMermaid,
2214
+ MDResponse,
2215
+ MDViewFormItem,
2216
+ SideAppViewBrowser,
2217
+ ThinkingChain,
2218
+ ThinkingChainGroup,
2219
+ chatContext,
2220
+ elements,
2221
+ getElement,
2222
+ regsiterElement,
493
2223
  useAgentGraph,
494
2224
  useAgentState,
495
2225
  useAxiomLattice,