@fe-free/ai 4.1.28 → 4.1.30
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/CHANGELOG.md +18 -0
- package/package.json +4 -4
- package/src/ai.stories.tsx +2 -1
- package/src/helper/complete.ts +90 -0
- package/src/index.ts +1 -0
- package/src/m_sender/record.tsx +11 -7
- package/src/messages/message_actions.tsx +2 -2
- /package/src/{helper.tsx → helper/index.tsx} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# @fe-free/ai
|
|
2
2
|
|
|
3
|
+
## 4.1.30
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- feat: ai
|
|
8
|
+
- @fe-free/core@4.1.30
|
|
9
|
+
- @fe-free/icons@4.1.30
|
|
10
|
+
- @fe-free/tool@4.1.30
|
|
11
|
+
|
|
12
|
+
## 4.1.29
|
|
13
|
+
|
|
14
|
+
### Patch Changes
|
|
15
|
+
|
|
16
|
+
- feat: ai
|
|
17
|
+
- @fe-free/core@4.1.29
|
|
18
|
+
- @fe-free/icons@4.1.29
|
|
19
|
+
- @fe-free/tool@4.1.29
|
|
20
|
+
|
|
3
21
|
## 4.1.28
|
|
4
22
|
|
|
5
23
|
### Patch Changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fe-free/ai",
|
|
3
|
-
"version": "4.1.
|
|
3
|
+
"version": "4.1.30",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "./src/index.ts",
|
|
6
6
|
"author": "",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"lodash-es": "^4.17.21",
|
|
20
20
|
"uuid": "^13.0.0",
|
|
21
21
|
"zustand": "^4.5.7",
|
|
22
|
-
"@fe-free/core": "4.1.
|
|
22
|
+
"@fe-free/core": "4.1.30"
|
|
23
23
|
},
|
|
24
24
|
"peerDependencies": {
|
|
25
25
|
"antd": "^5.27.1",
|
|
@@ -29,8 +29,8 @@
|
|
|
29
29
|
"i18next-icu": "^2.4.1",
|
|
30
30
|
"react": "^19.2.0",
|
|
31
31
|
"react-i18next": "^16.4.0",
|
|
32
|
-
"@fe-free/icons": "4.1.
|
|
33
|
-
"@fe-free/tool": "4.1.
|
|
32
|
+
"@fe-free/icons": "4.1.30",
|
|
33
|
+
"@fe-free/tool": "4.1.30"
|
|
34
34
|
},
|
|
35
35
|
"scripts": {
|
|
36
36
|
"test": "echo \"Error: no test specified\" && exit 1",
|
package/src/ai.stories.tsx
CHANGED
|
@@ -129,7 +129,7 @@ function Component() {
|
|
|
129
129
|
Add New Session
|
|
130
130
|
</Button>
|
|
131
131
|
</div>
|
|
132
|
-
<div className="h-[
|
|
132
|
+
<div className="h-[500px] w-[500px] max-w-full border border-red-500">
|
|
133
133
|
<Chat
|
|
134
134
|
end={
|
|
135
135
|
<div
|
|
@@ -141,6 +141,7 @@ function Component() {
|
|
|
141
141
|
console.log('onBlur');
|
|
142
142
|
}}
|
|
143
143
|
>
|
|
144
|
+
<div>这里是 suggestion 区域这里是 suggestion 区域</div>
|
|
144
145
|
<MSender
|
|
145
146
|
value={senderValue}
|
|
146
147
|
onChange={(v) => setSenderValue(v)}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
function completeHtml(partialHtml?: string) {
|
|
2
|
+
if (!partialHtml) {
|
|
3
|
+
return '';
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
// 创建一个临时容器来解析 HTML
|
|
7
|
+
const tempDiv = document.createElement('div');
|
|
8
|
+
tempDiv.innerHTML = partialHtml;
|
|
9
|
+
|
|
10
|
+
// 浏览器会自动修正不匹配的标签(如自动闭合、忽略无效标签等)
|
|
11
|
+
// 但 innerHTML 不会包含 <html>, <head>, <body> 等顶层结构
|
|
12
|
+
// 所以我们手动构建一个完整文档
|
|
13
|
+
|
|
14
|
+
// 提取 head 内容(如果有 <head> 标签,通常不会出现在片段中,但以防万一)
|
|
15
|
+
let headContent = '';
|
|
16
|
+
const headMatch = partialHtml.match(/<head[^>]*>([\s\S]*?)<\/head>/i);
|
|
17
|
+
if (headMatch) {
|
|
18
|
+
headContent = headMatch[1] || '';
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// 使用 tempDiv.innerHTML 获取浏览器修正后的 body 内容
|
|
22
|
+
const bodyContent = tempDiv.innerHTML;
|
|
23
|
+
|
|
24
|
+
// 构建完整 HTML
|
|
25
|
+
const fullHtml = `<!DOCTYPE html>
|
|
26
|
+
<html>
|
|
27
|
+
<head>
|
|
28
|
+
<meta charset="utf-8">
|
|
29
|
+
${headContent}
|
|
30
|
+
</head>
|
|
31
|
+
<body>
|
|
32
|
+
${bodyContent}
|
|
33
|
+
</body>
|
|
34
|
+
</html>`;
|
|
35
|
+
|
|
36
|
+
return fullHtml;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function completeJson(partialJson?: string): string {
|
|
40
|
+
if (!partialJson) {
|
|
41
|
+
return '';
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
let result = partialJson.trim();
|
|
45
|
+
|
|
46
|
+
const stack: string[] = [];
|
|
47
|
+
let inString = false;
|
|
48
|
+
let escape = false;
|
|
49
|
+
|
|
50
|
+
for (let i = 0; i < result.length; i++) {
|
|
51
|
+
const char = result[i];
|
|
52
|
+
|
|
53
|
+
if (inString) {
|
|
54
|
+
if (escape) {
|
|
55
|
+
escape = false;
|
|
56
|
+
} else if (char === '\\') {
|
|
57
|
+
escape = true;
|
|
58
|
+
} else if (char === '"') {
|
|
59
|
+
inString = false;
|
|
60
|
+
}
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (char === '"') {
|
|
65
|
+
inString = true;
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (char === '{') stack.push('}');
|
|
70
|
+
else if (char === '[') stack.push(']');
|
|
71
|
+
else if (char === '}' || char === ']') stack.pop();
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// 1️⃣ 如果字符串没闭合,补一个 "
|
|
75
|
+
if (inString) {
|
|
76
|
+
result += '"';
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// 2️⃣ 去掉末尾非法逗号
|
|
80
|
+
result = result.replace(/,\s*([}\]])/g, '$1');
|
|
81
|
+
|
|
82
|
+
// 3️⃣ 补齐所有缺失的 } 或 ]
|
|
83
|
+
while (stack.length) {
|
|
84
|
+
result += stack.pop();
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return result;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export { completeHtml, completeJson };
|
package/src/index.ts
CHANGED
|
@@ -2,6 +2,7 @@ import './style.scss';
|
|
|
2
2
|
export { Chat } from './chat';
|
|
3
3
|
export { FileView, FileViewList } from './files';
|
|
4
4
|
export { generateUUID } from './helper';
|
|
5
|
+
export { completeHtml, completeJson } from './helper/complete';
|
|
5
6
|
export { MSender } from './m_sender';
|
|
6
7
|
export type { MSenderProps, MSenderRef } from './m_sender';
|
|
7
8
|
export { CustomMarkdown, Markdown } from './markdown';
|
package/src/m_sender/record.tsx
CHANGED
|
@@ -10,7 +10,7 @@ import type { MSenderProps } from './types';
|
|
|
10
10
|
function RecordAction(
|
|
11
11
|
props: MSenderProps & { setType; refText: RefObject<HTMLTextAreaElement | null> },
|
|
12
12
|
) {
|
|
13
|
-
const { allowSpeech, setType, refText } = props;
|
|
13
|
+
const { allowSpeech, setType, refText, loading } = props;
|
|
14
14
|
|
|
15
15
|
const containerRef = useRef<HTMLDivElement>(null);
|
|
16
16
|
const touchStartYRef = useRef<number>(0);
|
|
@@ -25,6 +25,10 @@ function RecordAction(
|
|
|
25
25
|
// 阻止默认行为,避免触发文本选择、上下文菜单等
|
|
26
26
|
e.preventDefault();
|
|
27
27
|
|
|
28
|
+
if (loading) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
|
|
28
32
|
await allowSpeech?.onRecordStart?.();
|
|
29
33
|
|
|
30
34
|
const touch = e.touches[0];
|
|
@@ -35,7 +39,7 @@ function RecordAction(
|
|
|
35
39
|
|
|
36
40
|
setIsRecording(true);
|
|
37
41
|
},
|
|
38
|
-
[allowSpeech],
|
|
42
|
+
[allowSpeech, loading],
|
|
39
43
|
);
|
|
40
44
|
|
|
41
45
|
const handleTouchMove = useCallback(
|
|
@@ -71,7 +75,7 @@ function RecordAction(
|
|
|
71
75
|
async (e: TouchEvent) => {
|
|
72
76
|
e.preventDefault();
|
|
73
77
|
|
|
74
|
-
//
|
|
78
|
+
// 没有录音,不继续
|
|
75
79
|
if (!isRecording) {
|
|
76
80
|
return;
|
|
77
81
|
}
|
|
@@ -140,10 +144,10 @@ function RecordAction(
|
|
|
140
144
|
{isRecording ? (
|
|
141
145
|
<>
|
|
142
146
|
<RecordLoading count={30} gap={4} />
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
<div className="
|
|
146
|
-
|
|
147
|
+
<div className="absolute left-0 right-0 top-0 -mt-[50px] flex h-[50px] items-end justify-center bg-white pb-2 text-03">
|
|
148
|
+
{isCancel && <div className="text-red08">松开取消</div>}
|
|
149
|
+
{!isCancel && <div className="text-03">松开发送 上移取消</div>}
|
|
150
|
+
</div>
|
|
147
151
|
</>
|
|
148
152
|
) : (
|
|
149
153
|
<div className="text-base text-white">按住说话</div>
|
|
@@ -117,7 +117,7 @@ function MessageActionOfDislike({
|
|
|
117
117
|
);
|
|
118
118
|
}
|
|
119
119
|
|
|
120
|
-
function
|
|
120
|
+
function MessageActionOfLikeAndDislike({
|
|
121
121
|
value: propsValue,
|
|
122
122
|
onChange,
|
|
123
123
|
className,
|
|
@@ -160,7 +160,7 @@ const MessageActions = {
|
|
|
160
160
|
Copy: MessageActionOfCopy,
|
|
161
161
|
Like: MessageActionOfLike,
|
|
162
162
|
Dislike: MessageActionOfDislike,
|
|
163
|
-
|
|
163
|
+
LikeAndDislike: MessageActionOfLikeAndDislike,
|
|
164
164
|
};
|
|
165
165
|
|
|
166
166
|
export { MessageActions };
|
|
File without changes
|