@alicloud/appflow-chat 0.0.4 → 0.0.5-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/appflow-chat.cjs.js +157 -162
- package/dist/appflow-chat.esm.js +12355 -11870
- package/dist/types/index.d.ts +169 -0
- package/package.json +1 -1
- package/src/components/HumanVerify/CustomParamsRenderer/ArrayField.tsx +6 -4
- package/src/components/HumanVerify/CustomParamsRenderer/EnumField.tsx +5 -3
- package/src/components/HumanVerify/CustomParamsRenderer/FieldRenderer.tsx +6 -4
- package/src/components/HumanVerify/CustomParamsRenderer/FileField.tsx +38 -30
- package/src/components/HumanVerify/CustomParamsRenderer/ObjectField.tsx +4 -2
- package/src/components/HumanVerify/CustomParamsRenderer/TimeField.tsx +3 -1
- package/src/components/HumanVerify/HistoryCard.tsx +6 -4
- package/src/components/HumanVerify/HumanVerify.tsx +5 -3
- package/src/components/MessageBubble.tsx +4 -2
- package/src/components/RichMessageBubble.tsx +4 -2
- package/src/core/RichBubbleContent.tsx +4 -2
- package/src/core/SourceContent.tsx +5 -3
- package/src/core/WebSearchContent.tsx +3 -1
- package/src/i18n/LocaleContext.tsx +70 -0
- package/src/i18n/index.ts +16 -0
- package/src/i18n/translate.ts +42 -0
- package/src/i18n/useTranslation.ts +39 -0
- package/src/i18n/utils.ts +67 -0
- package/src/index.ts +25 -0
- package/src/locales/en-US.ts +77 -0
- package/src/locales/index.ts +7 -0
- package/src/locales/types.ts +35 -0
- package/src/locales/zh-CN.ts +78 -0
- package/src/markdown/components/Chart.tsx +3 -1
- package/src/markdown/components/Mermaid.tsx +8 -6
- package/src/markdown/index.tsx +15 -14
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 中文词条(默认语言)
|
|
3
|
+
*
|
|
4
|
+
* 该文件作为 Locale 类型的基准结构,所有其他语言文件必须实现相同的 key 结构。
|
|
5
|
+
* 新增文案时优先在此处添加,再补齐其他语言文件。
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const zhCN = {
|
|
9
|
+
common: {
|
|
10
|
+
loading: '加载中...',
|
|
11
|
+
confirm: '确定',
|
|
12
|
+
cancel: '取消',
|
|
13
|
+
submit: '提交',
|
|
14
|
+
retry: '重试',
|
|
15
|
+
copy: '复制',
|
|
16
|
+
copied: '已复制',
|
|
17
|
+
placeholderSelect: '请选择',
|
|
18
|
+
},
|
|
19
|
+
humanVerify: {
|
|
20
|
+
requiredAll: '请填写所有必填项',
|
|
21
|
+
submitted: '已提交',
|
|
22
|
+
pending: '待提交',
|
|
23
|
+
placeholder: {
|
|
24
|
+
input: '请输入{title}',
|
|
25
|
+
select: '请选择',
|
|
26
|
+
},
|
|
27
|
+
file: {
|
|
28
|
+
supportAll: '支持所有文件格式',
|
|
29
|
+
supportFormats: '支持 {formats} 格式',
|
|
30
|
+
uploadButton: '选择文件',
|
|
31
|
+
uploading: '上传中',
|
|
32
|
+
upload: '上传',
|
|
33
|
+
defaultFileName: '文件',
|
|
34
|
+
maxSizeError: '文件大小不能超过 {size}',
|
|
35
|
+
uploadFailed: '文件上传失败',
|
|
36
|
+
tokenFailed: '获取上传凭证失败',
|
|
37
|
+
uploaderNotConfigured: '上传功能未配置',
|
|
38
|
+
uploadMethodNotConfigured: '文件上传方法未配置',
|
|
39
|
+
getFileIdFailed: '获取文件ID失败',
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
webSearch: {
|
|
43
|
+
title: '搜索结果',
|
|
44
|
+
foundPages: '已搜索到{count}个网页',
|
|
45
|
+
},
|
|
46
|
+
source: {
|
|
47
|
+
title: '参考资料',
|
|
48
|
+
answerFrom: '回答来源:',
|
|
49
|
+
imageFrom: '图片来源:',
|
|
50
|
+
},
|
|
51
|
+
rich: {
|
|
52
|
+
stepLabel: '步骤{index}:',
|
|
53
|
+
emptyContent: '暂无内容',
|
|
54
|
+
},
|
|
55
|
+
markdown: {
|
|
56
|
+
copyCode: '复制代码',
|
|
57
|
+
copied: '已复制!',
|
|
58
|
+
copy: '复制',
|
|
59
|
+
copiedShort: '已复制',
|
|
60
|
+
deepThinking: '深度思考',
|
|
61
|
+
chartLoading: '图表加载中...',
|
|
62
|
+
tableLoading: '表格加载中...',
|
|
63
|
+
tableLoadFailed: '表格数据加载失败,请检查数据格式',
|
|
64
|
+
chartLoadFailed: '图表数据加载失败,请检查数据格式',
|
|
65
|
+
mermaidLoadFailed: 'Mermaid 库加载失败',
|
|
66
|
+
mermaidNotLoaded: 'Mermaid 未正确加载',
|
|
67
|
+
mermaidRenderFailed: 'Mermaid 图表渲染失败',
|
|
68
|
+
},
|
|
69
|
+
message: {
|
|
70
|
+
like: '点赞',
|
|
71
|
+
dislike: '点踩',
|
|
72
|
+
regenerate: '重新生成',
|
|
73
|
+
copy: '复制',
|
|
74
|
+
copied: '已复制',
|
|
75
|
+
},
|
|
76
|
+
} as const;
|
|
77
|
+
|
|
78
|
+
export default zhCN;
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import React, { useEffect, useRef, useState } from 'react';
|
|
3
3
|
import { useRichBubbleContext } from '@/context/RichBubble';
|
|
4
4
|
import loadEchartsScript from '@/utils/loadEcharts';
|
|
5
|
+
import { useTranslation } from '@/i18n';
|
|
5
6
|
|
|
6
7
|
interface Iprops {
|
|
7
8
|
options: any;
|
|
@@ -10,6 +11,7 @@ interface Iprops {
|
|
|
10
11
|
export const Chart: React.FC<Iprops> = ({
|
|
11
12
|
options,
|
|
12
13
|
}) => {
|
|
14
|
+
const { t } = useTranslation();
|
|
13
15
|
const chartContainerRef = useRef(null);
|
|
14
16
|
const chartInstanceRef = useRef(null);
|
|
15
17
|
const [isEchartsLoaded, setIsEchartsLoaded] = useState(false);
|
|
@@ -99,7 +101,7 @@ export const Chart: React.FC<Iprops> = ({
|
|
|
99
101
|
color: '#666'
|
|
100
102
|
}}
|
|
101
103
|
>
|
|
102
|
-
|
|
104
|
+
{t('markdown.chartLoading')}
|
|
103
105
|
</div>
|
|
104
106
|
);
|
|
105
107
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React, { useEffect, useRef, useState } from 'react';
|
|
2
2
|
import loadMermaidScript from '@/utils/loadMermaid';
|
|
3
|
+
import { useTranslation } from '@/i18n';
|
|
3
4
|
|
|
4
5
|
interface IProps {
|
|
5
6
|
code: string;
|
|
@@ -37,6 +38,7 @@ const isMermaidCodeComplete = (code: string): boolean => {
|
|
|
37
38
|
};
|
|
38
39
|
|
|
39
40
|
export const Mermaid: React.FC<IProps> = ({ code }) => {
|
|
41
|
+
const { t } = useTranslation();
|
|
40
42
|
const containerRef = useRef<HTMLDivElement>(null);
|
|
41
43
|
const [svg, setSvg] = useState<string>('');
|
|
42
44
|
const [error, setError] = useState<string>('');
|
|
@@ -55,7 +57,7 @@ export const Mermaid: React.FC<IProps> = ({ code }) => {
|
|
|
55
57
|
setIsMermaidLoaded(true);
|
|
56
58
|
} catch (error) {
|
|
57
59
|
console.error('mermaid加载失败:', error);
|
|
58
|
-
setError('
|
|
60
|
+
setError(t('markdown.mermaidLoadFailed'));
|
|
59
61
|
setIsLoading(false);
|
|
60
62
|
}
|
|
61
63
|
};
|
|
@@ -78,7 +80,7 @@ export const Mermaid: React.FC<IProps> = ({ code }) => {
|
|
|
78
80
|
|
|
79
81
|
const mermaid = (window as any).mermaid;
|
|
80
82
|
if (!mermaid) {
|
|
81
|
-
setError('
|
|
83
|
+
setError(t('markdown.mermaidNotLoaded'));
|
|
82
84
|
setIsLoading(false);
|
|
83
85
|
return;
|
|
84
86
|
}
|
|
@@ -143,7 +145,7 @@ export const Mermaid: React.FC<IProps> = ({ code }) => {
|
|
|
143
145
|
} else {
|
|
144
146
|
// 流式输出结束后,如果仍然有错误,才显示错误
|
|
145
147
|
console.error('Mermaid 渲染错误:', err);
|
|
146
|
-
setError(err?.message || '
|
|
148
|
+
setError(err?.message || t('markdown.mermaidRenderFailed'));
|
|
147
149
|
}
|
|
148
150
|
} finally {
|
|
149
151
|
setIsLoading(false);
|
|
@@ -176,7 +178,7 @@ export const Mermaid: React.FC<IProps> = ({ code }) => {
|
|
|
176
178
|
marginBottom: '10px',
|
|
177
179
|
}}
|
|
178
180
|
>
|
|
179
|
-
|
|
181
|
+
{t('markdown.chartLoading')}
|
|
180
182
|
</div>
|
|
181
183
|
);
|
|
182
184
|
}
|
|
@@ -202,7 +204,7 @@ export const Mermaid: React.FC<IProps> = ({ code }) => {
|
|
|
202
204
|
marginBottom: '8px'
|
|
203
205
|
}}
|
|
204
206
|
>
|
|
205
|
-
|
|
207
|
+
{t('markdown.mermaidRenderFailed')}
|
|
206
208
|
</div>
|
|
207
209
|
<div
|
|
208
210
|
style={{
|
|
@@ -238,7 +240,7 @@ export const Mermaid: React.FC<IProps> = ({ code }) => {
|
|
|
238
240
|
marginBottom: '10px',
|
|
239
241
|
}}
|
|
240
242
|
>
|
|
241
|
-
|
|
243
|
+
{t('markdown.chartLoading')}
|
|
242
244
|
</div>
|
|
243
245
|
);
|
|
244
246
|
}
|
package/src/markdown/index.tsx
CHANGED
|
@@ -14,6 +14,7 @@ import { convertTableDataToMarkdown } from './utils/dataProcessor';
|
|
|
14
14
|
import Loading from './components/Loading';
|
|
15
15
|
import Error from './components/Error';
|
|
16
16
|
import Mermaid from './components/Mermaid';
|
|
17
|
+
import { useTranslation } from '@/i18n';
|
|
17
18
|
|
|
18
19
|
export interface MarkdownViewProps {
|
|
19
20
|
/** Markdown 内容 */
|
|
@@ -32,6 +33,7 @@ export const MarkdownView: React.FC<MarkdownViewProps> = ({
|
|
|
32
33
|
content,
|
|
33
34
|
waitingMessage = '',
|
|
34
35
|
}) => {
|
|
36
|
+
const { t } = useTranslation();
|
|
35
37
|
|
|
36
38
|
// markdown扩展配置
|
|
37
39
|
const markdownOptions: Options = useMemo(() => ({
|
|
@@ -43,11 +45,10 @@ export const MarkdownView: React.FC<MarkdownViewProps> = ({
|
|
|
43
45
|
return (
|
|
44
46
|
<Image
|
|
45
47
|
style={{
|
|
46
|
-
maxWidth: '
|
|
47
|
-
maxHeight: '
|
|
48
|
-
objectFit: 'contain',
|
|
48
|
+
maxWidth: '100%',
|
|
49
|
+
maxHeight: '600px',
|
|
49
50
|
}}
|
|
50
|
-
src={props.src}
|
|
51
|
+
src={props.src}
|
|
51
52
|
alt={props.alt}
|
|
52
53
|
preview={{ zIndex: 1100 }}
|
|
53
54
|
/>
|
|
@@ -57,7 +58,7 @@ export const MarkdownView: React.FC<MarkdownViewProps> = ({
|
|
|
57
58
|
// 判断是否为行内代码
|
|
58
59
|
// 行内代码没有 className,且 inline 为 true
|
|
59
60
|
const isInline = inline || (!className && !node?.properties?.className);
|
|
60
|
-
|
|
61
|
+
|
|
61
62
|
if (isInline) {
|
|
62
63
|
// 行内代码 - 使用简单的 <code> 标签样式
|
|
63
64
|
return (
|
|
@@ -98,12 +99,12 @@ export const MarkdownView: React.FC<MarkdownViewProps> = ({
|
|
|
98
99
|
// 检查是否是流式输出导致的解析错误
|
|
99
100
|
if (!isValidJSON(String(props?.children))) {
|
|
100
101
|
return (
|
|
101
|
-
<Loading text={'
|
|
102
|
+
<Loading text={t('markdown.tableLoading')} />
|
|
102
103
|
);
|
|
103
104
|
}
|
|
104
105
|
// 真实错误的处理
|
|
105
106
|
console.error("ant_table数据解析错误:", error);
|
|
106
|
-
return <Error text={'
|
|
107
|
+
return <Error text={t('markdown.tableLoadFailed')} />;
|
|
107
108
|
}
|
|
108
109
|
}
|
|
109
110
|
|
|
@@ -142,7 +143,7 @@ export const MarkdownView: React.FC<MarkdownViewProps> = ({
|
|
|
142
143
|
} catch (configError) {
|
|
143
144
|
// 图表配置解析错误
|
|
144
145
|
console.error("图表配置解析错误:", configError);
|
|
145
|
-
return <Error text={'
|
|
146
|
+
return <Error text={t('markdown.chartLoadFailed')} />;
|
|
146
147
|
}
|
|
147
148
|
} catch (error: any) {
|
|
148
149
|
// 如果是流式输出导致的json解析错误,显示加载状态
|
|
@@ -152,7 +153,7 @@ export const MarkdownView: React.FC<MarkdownViewProps> = ({
|
|
|
152
153
|
|
|
153
154
|
// 其他真实错误的处理
|
|
154
155
|
console.error("图表数据解析错误:", error);
|
|
155
|
-
return <Error text={'
|
|
156
|
+
return <Error text={t('markdown.chartLoadFailed')} />;
|
|
156
157
|
}
|
|
157
158
|
}
|
|
158
159
|
|
|
@@ -174,9 +175,8 @@ export const MarkdownView: React.FC<MarkdownViewProps> = ({
|
|
|
174
175
|
<>
|
|
175
176
|
<Image
|
|
176
177
|
style={{
|
|
177
|
-
maxWidth: '
|
|
178
|
-
maxHeight: '
|
|
179
|
-
objectFit: 'contain',
|
|
178
|
+
maxWidth: '100%',
|
|
179
|
+
maxHeight: '600px',
|
|
180
180
|
}}
|
|
181
181
|
src={image.properties.src}
|
|
182
182
|
className="max-w-full h-auto align-middle border-none rounded-lg shadow-md hover:shadow-lg transition-shadow duration-300 ease-in-out mt-2 mb-2"
|
|
@@ -201,7 +201,7 @@ export const MarkdownView: React.FC<MarkdownViewProps> = ({
|
|
|
201
201
|
</a>
|
|
202
202
|
),
|
|
203
203
|
},
|
|
204
|
-
}), []);
|
|
204
|
+
}), [t]);
|
|
205
205
|
|
|
206
206
|
// 检查是否是完整的JSON字符串
|
|
207
207
|
const isValidJSON = (str: string) => {
|
|
@@ -216,9 +216,10 @@ export const MarkdownView: React.FC<MarkdownViewProps> = ({
|
|
|
216
216
|
|
|
217
217
|
// 将think标签转换为details标签
|
|
218
218
|
const convertThinkToDetails = (content: string) => {
|
|
219
|
+
const summary = t('markdown.deepThinking');
|
|
219
220
|
return content?.replace(
|
|
220
221
|
/<think>([\s\S]*?)<\/think>/g,
|
|
221
|
-
|
|
222
|
+
`<details open><summary>${summary}</summary><pre class="think">$1</pre></details>\n\n`
|
|
222
223
|
);
|
|
223
224
|
};
|
|
224
225
|
|