Duibonduil commited on
Commit
245956f
·
verified ·
1 Parent(s): 6d41e9e

Upload 3 files

Browse files
aworld/cmd/web/webui/src/pages/components/BubbleItem/index.less ADDED
File without changes
aworld/cmd/web/webui/src/pages/components/BubbleItem/index.tsx ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React from "react";
2
+ import ReactMarkdown from "react-markdown";
3
+ import { extractToolCards } from "./utils";
4
+ import CardDefault from "./cardDefault";
5
+ import CardLinkList from "./cardLinkList";
6
+
7
+ interface BubbleItemProps {
8
+ data: string;
9
+ }
10
+
11
+ const BubbleItem: React.FC<BubbleItemProps> = ({ data }) => {
12
+ const { segments } = extractToolCards(data);
13
+ console.log(segments)
14
+ return (
15
+ <div className="card">
16
+ {segments.map((segment, index) => {
17
+ if (segment.type === 'text') {
18
+ return (
19
+ <ReactMarkdown key={`text-${index}`}>
20
+ {segment.content}
21
+ </ReactMarkdown>
22
+ );
23
+ } else if (segment.type === 'tool_card') {
24
+ const cardType = segment.data?.card_type;
25
+ if (cardType === 'tool_call_card_link_list') {
26
+ return <CardLinkList key={`tool-${index}`} data={segment.data} />;
27
+ } else {
28
+ return <CardDefault key={`tool-${index}`} data={segment.data} />;
29
+ }
30
+ }
31
+ })}
32
+ </div>
33
+ );
34
+ };
35
+
36
+ export default BubbleItem;
aworld/cmd/web/webui/src/pages/components/BubbleItem/utils.ts ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ export interface ToolCardData {
2
+ tool_type: string;
3
+ tool_name: string;
4
+ function_name: string;
5
+ tool_call_id: string;
6
+ arguments: string;
7
+ results: string;
8
+ card_type: string;
9
+ card_data: any;
10
+ }
11
+
12
+ type ContentSegment =
13
+ | { type: 'text'; content: string }
14
+ | { type: 'tool_card'; data: ToolCardData; raw: string };
15
+
16
+ export interface ParsedContent {
17
+ segments: ContentSegment[];
18
+ }
19
+
20
+ export const extractToolCards = (content: string): ParsedContent => {
21
+ const toolCardRegex = /(.*?)(```tool_card\s*({[\s\S]*?})\s*```)/gs;
22
+ const segments: ContentSegment[] = [];
23
+ let lastIndex = 0;
24
+
25
+ let match;
26
+ while ((match = toolCardRegex.exec(content)) !== null) {
27
+ const [, textBefore, fullToolCard, toolCardJson] = match;
28
+
29
+ // 添加文本内容
30
+ if (textBefore) {
31
+ segments.push({
32
+ type: 'text',
33
+ content: textBefore.trim()
34
+ });
35
+ }
36
+
37
+ // 添加工具卡片
38
+ try {
39
+ segments.push({
40
+ type: 'tool_card',
41
+ data: JSON.parse(toolCardJson),
42
+ raw: fullToolCard.trim()
43
+ });
44
+ } catch (e) {
45
+ console.error('Failed to parse tool_card JSON:', e);
46
+ // 如果解析失败,仍保留原始文本
47
+ segments.push({
48
+ type: 'text',
49
+ content: fullToolCard.trim()
50
+ });
51
+ }
52
+
53
+ lastIndex = toolCardRegex.lastIndex;
54
+ }
55
+
56
+ // 添加最后剩余的文本内容
57
+ const remainingText = content.slice(lastIndex);
58
+ if (remainingText.trim()) {
59
+ segments.push({
60
+ type: 'text',
61
+ content: remainingText.trim()
62
+ });
63
+ }
64
+
65
+ return { segments };
66
+ };