@fe-free/ai 4.1.29 → 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 CHANGED
@@ -1,5 +1,14 @@
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
+
3
12
  ## 4.1.29
4
13
 
5
14
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fe-free/ai",
3
- "version": "4.1.29",
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.29"
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.29",
33
- "@fe-free/tool": "4.1.29"
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",
@@ -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';
File without changes