plugin-build-guide-block 1.0.1 → 1.0.3

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.
Files changed (125) hide show
  1. package/dist/client/UserGuideBlock.d.ts +2 -0
  2. package/dist/client/UserGuideBlockInitializer.d.ts +2 -0
  3. package/dist/client/UserGuideBlockProvider.d.ts +2 -0
  4. package/dist/client/UserGuideManager.d.ts +2 -0
  5. package/dist/client/components/BuildButton.d.ts +2 -0
  6. package/dist/client/components/LLMServiceSelect.d.ts +2 -0
  7. package/dist/client/components/ModelSelect.d.ts +2 -0
  8. package/dist/client/components/StatusTag.d.ts +2 -0
  9. package/dist/client/index.d.ts +1 -0
  10. package/dist/client/index.js +1 -1
  11. package/dist/client/models/UserGuideBlockModel.d.ts +3 -0
  12. package/dist/client/models/index.d.ts +11 -0
  13. package/dist/client/plugin.d.ts +5 -0
  14. package/dist/client/schemas/spacesSchema.d.ts +305 -0
  15. package/dist/index.d.ts +2 -0
  16. package/dist/node_modules/sanitize-html/LICENSE +7 -0
  17. package/dist/node_modules/sanitize-html/index.js +7 -0
  18. package/dist/node_modules/sanitize-html/node_modules/nanoid/async/index.browser.cjs +34 -0
  19. package/dist/node_modules/sanitize-html/node_modules/nanoid/async/index.browser.js +34 -0
  20. package/dist/node_modules/sanitize-html/node_modules/nanoid/async/index.cjs +35 -0
  21. package/dist/node_modules/sanitize-html/node_modules/nanoid/async/index.d.ts +56 -0
  22. package/dist/node_modules/sanitize-html/node_modules/nanoid/async/index.js +35 -0
  23. package/dist/node_modules/sanitize-html/node_modules/nanoid/async/index.native.js +26 -0
  24. package/dist/node_modules/sanitize-html/node_modules/nanoid/async/package.json +12 -0
  25. package/dist/node_modules/sanitize-html/node_modules/nanoid/bin/nanoid.cjs +55 -0
  26. package/dist/node_modules/sanitize-html/node_modules/nanoid/index.browser.cjs +34 -0
  27. package/dist/node_modules/sanitize-html/node_modules/nanoid/index.browser.js +34 -0
  28. package/dist/node_modules/sanitize-html/node_modules/nanoid/index.cjs +45 -0
  29. package/dist/node_modules/sanitize-html/node_modules/nanoid/index.d.cts +91 -0
  30. package/dist/node_modules/sanitize-html/node_modules/nanoid/index.d.ts +91 -0
  31. package/dist/node_modules/sanitize-html/node_modules/nanoid/index.js +45 -0
  32. package/dist/node_modules/sanitize-html/node_modules/nanoid/nanoid.js +1 -0
  33. package/dist/node_modules/sanitize-html/node_modules/nanoid/non-secure/index.cjs +21 -0
  34. package/dist/node_modules/sanitize-html/node_modules/nanoid/non-secure/index.d.ts +33 -0
  35. package/dist/node_modules/sanitize-html/node_modules/nanoid/non-secure/index.js +21 -0
  36. package/dist/node_modules/sanitize-html/node_modules/nanoid/non-secure/package.json +6 -0
  37. package/dist/node_modules/sanitize-html/node_modules/nanoid/package.json +88 -0
  38. package/dist/node_modules/sanitize-html/node_modules/nanoid/url-alphabet/index.cjs +3 -0
  39. package/dist/node_modules/sanitize-html/node_modules/nanoid/url-alphabet/index.js +3 -0
  40. package/dist/node_modules/sanitize-html/node_modules/nanoid/url-alphabet/package.json +6 -0
  41. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/at-rule.d.ts +115 -0
  42. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/at-rule.js +25 -0
  43. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/comment.d.ts +67 -0
  44. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/comment.js +13 -0
  45. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/container.d.ts +452 -0
  46. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/container.js +439 -0
  47. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/css-syntax-error.d.ts +248 -0
  48. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/css-syntax-error.js +100 -0
  49. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/declaration.d.ts +148 -0
  50. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/declaration.js +24 -0
  51. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/document.d.ts +68 -0
  52. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/document.js +33 -0
  53. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/fromJSON.d.ts +9 -0
  54. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/fromJSON.js +54 -0
  55. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/input.d.ts +194 -0
  56. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/input.js +248 -0
  57. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/lazy-result.d.ts +190 -0
  58. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/lazy-result.js +550 -0
  59. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/list.d.ts +57 -0
  60. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/list.js +58 -0
  61. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/map-generator.js +359 -0
  62. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/no-work-result.d.ts +46 -0
  63. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/no-work-result.js +135 -0
  64. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/node.d.ts +536 -0
  65. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/node.js +381 -0
  66. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/parse.d.ts +9 -0
  67. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/parse.js +42 -0
  68. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/parser.js +610 -0
  69. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/postcss.d.mts +72 -0
  70. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/postcss.d.ts +441 -0
  71. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/postcss.js +101 -0
  72. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/previous-map.d.ts +81 -0
  73. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/previous-map.js +142 -0
  74. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/processor.d.ts +115 -0
  75. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/processor.js +67 -0
  76. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/result.d.ts +206 -0
  77. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/result.js +42 -0
  78. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/root.d.ts +86 -0
  79. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/root.js +61 -0
  80. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/rule.d.ts +113 -0
  81. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/rule.js +27 -0
  82. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/stringifier.d.ts +46 -0
  83. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/stringifier.js +353 -0
  84. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/stringify.d.ts +9 -0
  85. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/stringify.js +11 -0
  86. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/symbols.js +5 -0
  87. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/terminal-highlight.js +70 -0
  88. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/tokenize.js +266 -0
  89. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/warn-once.js +13 -0
  90. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/warning.d.ts +147 -0
  91. package/dist/node_modules/sanitize-html/node_modules/postcss/lib/warning.js +37 -0
  92. package/dist/node_modules/sanitize-html/node_modules/postcss/node_modules/.bin/nanoid +15 -0
  93. package/dist/node_modules/sanitize-html/node_modules/postcss/node_modules/.bin/nanoid.cmd +7 -0
  94. package/dist/node_modules/sanitize-html/node_modules/postcss/package.json +88 -0
  95. package/dist/node_modules/sanitize-html/package.json +1 -0
  96. package/dist/server/actions/build.d.ts +2 -0
  97. package/dist/server/actions/getHtml.d.ts +2 -0
  98. package/dist/server/collections/ai-build-guide-spaces.d.ts +2 -0
  99. package/dist/server/index.d.ts +1 -0
  100. package/dist/server/plugin.d.ts +11 -0
  101. package/package.json +9 -1
  102. package/src/client/UserGuideBlock.tsx +53 -0
  103. package/src/client/UserGuideBlockInitializer.tsx +26 -0
  104. package/src/client/UserGuideBlockProvider.tsx +12 -0
  105. package/src/client/UserGuideManager.tsx +133 -0
  106. package/src/client/client.d.ts +249 -0
  107. package/src/client/components/BuildButton.tsx +43 -0
  108. package/src/client/components/LLMServiceSelect.tsx +44 -0
  109. package/src/client/components/ModelSelect.tsx +41 -0
  110. package/src/client/components/StatusTag.tsx +17 -0
  111. package/src/client/index.tsx +1 -0
  112. package/src/client/models/UserGuideBlockModel.ts +47 -0
  113. package/src/client/models/index.ts +12 -0
  114. package/src/client/plugin.tsx +30 -0
  115. package/src/client/schemas/spacesSchema.ts +305 -0
  116. package/src/index.ts +2 -0
  117. package/src/locale/en-US.json +27 -0
  118. package/src/locale/vi-VN.json +27 -0
  119. package/src/locale/zh-CN.json +27 -0
  120. package/src/server/actions/build.ts +171 -0
  121. package/src/server/actions/getHtml.ts +26 -0
  122. package/src/server/collections/.gitkeep +0 -0
  123. package/src/server/collections/ai-build-guide-spaces.ts +49 -0
  124. package/src/server/index.ts +1 -0
  125. package/src/server/plugin.ts +42 -0
@@ -0,0 +1,305 @@
1
+ export const spacesSchema = {
2
+ type: 'object',
3
+ properties: {
4
+ page: {
5
+ type: 'void',
6
+ 'x-component': 'Page',
7
+ 'x-component-props': {
8
+ ghost: true,
9
+ },
10
+ properties: {
11
+ actions: {
12
+ type: 'void',
13
+ 'x-component': 'ActionBar',
14
+ 'x-component-props': {
15
+ style: {
16
+ marginBottom: 16,
17
+ },
18
+ },
19
+ properties: {
20
+ create: {
21
+ type: 'void',
22
+ 'x-component': 'Action',
23
+ 'x-component-props': {
24
+ type: 'primary',
25
+ title: '{{t("Create space")}}',
26
+ icon: 'PlusOutlined',
27
+ },
28
+ properties: {
29
+ drawer: {
30
+ type: 'void',
31
+ 'x-component': 'Action.Drawer',
32
+ 'x-component-props': {
33
+ title: '{{t("Create space")}}',
34
+ },
35
+ properties: {
36
+ form: {
37
+ type: 'void',
38
+ 'x-component': 'FormV2',
39
+ 'x-use-component-props': 'useCreateFormProps',
40
+ properties: {
41
+ title: {
42
+ type: 'string',
43
+ title: '{{t("Title")}}',
44
+ required: true,
45
+ 'x-decorator': 'FormItem',
46
+ 'x-component': 'Input',
47
+ },
48
+ llmService: {
49
+ type: 'string',
50
+ title: '{{t("LLM Service")}}',
51
+ required: true,
52
+ 'x-decorator': 'FormItem',
53
+ 'x-component': 'LLMServiceSelect',
54
+ },
55
+ model: {
56
+ type: 'string',
57
+ title: '{{t("Model")}}',
58
+ required: true,
59
+ 'x-decorator': 'FormItem',
60
+ 'x-component': 'ModelSelect',
61
+ 'x-reactions': {
62
+ dependencies: ['llmService'],
63
+ fulfill: {
64
+ state: {
65
+ value: '{{$deps[0] ? $self.value : undefined}}'
66
+ }
67
+ }
68
+ }
69
+ },
70
+ systemPrompt: {
71
+ type: 'string',
72
+ title: '{{t("System Prompt")}}',
73
+ 'x-decorator': 'FormItem',
74
+ 'x-component': 'Input.TextArea',
75
+ 'x-component-props': {
76
+ rows: 4,
77
+ },
78
+ default: 'You are an expert technical writer. Please generate a comprehensive HTML user guide based on the provided documents. Ensure the output is valid HTML and does not include Markdown syntax like ```html blocks.',
79
+ },
80
+ documents: {
81
+ type: 'array',
82
+ title: '{{t("Documents")}}',
83
+ 'x-decorator': 'FormItem',
84
+ 'x-component': 'Upload.Attachment',
85
+ 'x-component-props': {
86
+ multiple: true,
87
+ action: 'attachments:create',
88
+ maxCount: 10,
89
+ },
90
+ },
91
+ footer: {
92
+ type: 'void',
93
+ 'x-component': 'Action.Drawer.Footer',
94
+ properties: {
95
+ cancel: {
96
+ type: 'void',
97
+ title: '{{t("Cancel")}}',
98
+ 'x-component': 'Action',
99
+ 'x-use-component-props': 'useCancelActionProps',
100
+ },
101
+ submit: {
102
+ type: 'void',
103
+ title: '{{t("Submit")}}',
104
+ 'x-component': 'Action',
105
+ 'x-use-component-props': 'useCreateActionProps',
106
+ },
107
+ },
108
+ },
109
+ },
110
+ },
111
+ },
112
+ },
113
+ },
114
+ },
115
+ },
116
+ },
117
+ table: {
118
+ type: 'array',
119
+ 'x-decorator': 'TableBlockProvider',
120
+ 'x-use-decorator-props': 'useTableBlockProps',
121
+ 'x-component': 'TableV2',
122
+ 'x-component-props': {
123
+ rowKey: 'id',
124
+ rowSelection: {
125
+ type: 'checkbox',
126
+ },
127
+ },
128
+ properties: {
129
+ title: {
130
+ type: 'void',
131
+ 'x-decorator': 'TableV2.Column.Decorator',
132
+ 'x-component': 'TableV2.Column',
133
+ properties: {
134
+ title: {
135
+ type: 'string',
136
+ 'x-component': 'CollectionField',
137
+ 'x-read-pretty': true,
138
+ },
139
+ },
140
+ },
141
+ status: {
142
+ type: 'void',
143
+ 'x-decorator': 'TableV2.Column.Decorator',
144
+ 'x-component': 'TableV2.Column',
145
+ properties: {
146
+ status: {
147
+ type: 'string',
148
+ 'x-component': 'StatusTag',
149
+ 'x-read-pretty': true,
150
+ },
151
+ },
152
+ },
153
+ buildLog: {
154
+ type: 'void',
155
+ 'x-decorator': 'TableV2.Column.Decorator',
156
+ 'x-component': 'TableV2.Column',
157
+ properties: {
158
+ buildLog: {
159
+ type: 'string',
160
+ 'x-component': 'CollectionField',
161
+ 'x-read-pretty': true,
162
+ },
163
+ },
164
+ },
165
+ actions: {
166
+ type: 'void',
167
+ title: '{{t("Actions")}}',
168
+ 'x-decorator': 'TableV2.Column.Decorator',
169
+ 'x-component': 'TableV2.Column',
170
+ properties: {
171
+ actions: {
172
+ type: 'void',
173
+ 'x-component': 'Space',
174
+ 'x-component-props': {
175
+ split: '|',
176
+ },
177
+ properties: {
178
+ build: {
179
+ type: 'void',
180
+ 'x-component': 'BuildButton',
181
+ },
182
+ update: {
183
+ type: 'void',
184
+ title: '{{t("Edit")}}',
185
+ 'x-component': 'Action.Link',
186
+ 'x-component-props': {
187
+ type: 'primary',
188
+ },
189
+ properties: {
190
+ drawer: {
191
+ type: 'void',
192
+ 'x-component': 'Action.Drawer',
193
+ 'x-component-props': {
194
+ title: '{{t("Edit space")}}',
195
+ },
196
+ properties: {
197
+ form: {
198
+ type: 'void',
199
+ 'x-component': 'FormV2',
200
+ 'x-use-component-props': 'useEditFormProps',
201
+ properties: {
202
+ title: {
203
+ type: 'string',
204
+ title: '{{t("Title")}}',
205
+ required: true,
206
+ 'x-decorator': 'FormItem',
207
+ 'x-component': 'Input',
208
+ },
209
+ llmService: {
210
+ type: 'string',
211
+ title: '{{t("LLM Service")}}',
212
+ required: true,
213
+ 'x-decorator': 'FormItem',
214
+ 'x-component': 'LLMServiceSelect',
215
+ },
216
+ model: {
217
+ type: 'string',
218
+ title: '{{t("Model")}}',
219
+ required: true,
220
+ 'x-decorator': 'FormItem',
221
+ 'x-component': 'ModelSelect',
222
+ },
223
+ systemPrompt: {
224
+ type: 'string',
225
+ title: '{{t("System Prompt")}}',
226
+ 'x-decorator': 'FormItem',
227
+ 'x-component': 'Input.TextArea',
228
+ 'x-component-props': {
229
+ rows: 4,
230
+ },
231
+ },
232
+ documents: {
233
+ type: 'array',
234
+ title: '{{t("Documents")}}',
235
+ 'x-decorator': 'FormItem',
236
+ 'x-component': 'Upload.Attachment',
237
+ 'x-component-props': {
238
+ multiple: true,
239
+ action: 'attachments:create',
240
+ maxCount: 10,
241
+ },
242
+ },
243
+ generatedHtml: {
244
+ type: 'string',
245
+ title: '{{t("Generated HTML")}}',
246
+ 'x-decorator': 'FormItem',
247
+ 'x-component': 'Input.TextArea',
248
+ 'x-component-props': {
249
+ rows: 6,
250
+ },
251
+ 'x-read-pretty': true,
252
+ },
253
+ buildLog: {
254
+ type: 'string',
255
+ title: '{{t("Build Log")}}',
256
+ 'x-decorator': 'FormItem',
257
+ 'x-component': 'Input.TextArea',
258
+ 'x-read-pretty': true,
259
+ },
260
+ footer: {
261
+ type: 'void',
262
+ 'x-component': 'Action.Drawer.Footer',
263
+ properties: {
264
+ cancel: {
265
+ type: 'void',
266
+ title: '{{t("Cancel")}}',
267
+ 'x-component': 'Action',
268
+ 'x-use-component-props': 'useCancelActionProps',
269
+ },
270
+ submit: {
271
+ type: 'void',
272
+ title: '{{t("Submit")}}',
273
+ 'x-component': 'Action',
274
+ 'x-use-component-props': 'useUpdateActionProps',
275
+ },
276
+ },
277
+ },
278
+ },
279
+ },
280
+ },
281
+ },
282
+ },
283
+ },
284
+ delete: {
285
+ type: 'void',
286
+ title: '{{t("Delete")}}',
287
+ 'x-component': 'Action.Link',
288
+ 'x-use-component-props': 'useDestroyActionProps',
289
+ 'x-component-props': {
290
+ confirm: {
291
+ title: '{{t("Delete")}}',
292
+ content: '{{t("Are you sure you want to delete this space?")}}',
293
+ },
294
+ },
295
+ },
296
+ },
297
+ },
298
+ },
299
+ },
300
+ },
301
+ },
302
+ },
303
+ },
304
+ },
305
+ };
package/src/index.ts ADDED
@@ -0,0 +1,2 @@
1
+ export * from './server';
2
+ export { default } from './server';
@@ -0,0 +1,27 @@
1
+ {
2
+ "Build Guide Block": "Build Guide Block",
3
+ "User guide block setting": "User guide block setting",
4
+ "Edit user guide settings": "Edit user guide settings",
5
+ "Space": "Space",
6
+ "User Guide": "User Guide",
7
+ "Create space": "Create space",
8
+ "Title": "Title",
9
+ "LLM Service": "LLM Service",
10
+ "Model": "Model",
11
+ "System Prompt": "System Prompt",
12
+ "Documents": "Documents",
13
+ "Cancel": "Cancel",
14
+ "Submit": "Submit",
15
+ "Actions": "Actions",
16
+ "Edit": "Edit",
17
+ "Edit space": "Edit space",
18
+ "Generated HTML": "Generated HTML",
19
+ "Build Log": "Build Log",
20
+ "Delete": "Delete",
21
+ "Saved successfully": "Saved successfully",
22
+ "Please select a User Guide Space in block settings": "Please select a User Guide Space in block settings",
23
+ "Build": "Build",
24
+ "Build started": "Build started",
25
+ "Build failed": "Build failed",
26
+ "Are you sure you want to delete this space?": "Are you sure you want to delete this space?"
27
+ }
@@ -0,0 +1,27 @@
1
+ {
2
+ "Build Guide Block": "Block Hướng dẫn sử dụng",
3
+ "User guide block setting": "Cài đặt Block Hướng dẫn",
4
+ "Edit user guide settings": "Chỉnh sửa cài đặt",
5
+ "Space": "Không gian (Space)",
6
+ "User Guide": "Hướng dẫn sử dụng",
7
+ "Create space": "Tạo Space",
8
+ "Title": "Tiêu đề",
9
+ "LLM Service": "Dịch vụ LLM",
10
+ "Model": "Mô hình (Model)",
11
+ "System Prompt": "Prompt hệ thống",
12
+ "Documents": "Tài liệu",
13
+ "Cancel": "Hủy",
14
+ "Submit": "Xác nhận",
15
+ "Actions": "Hành động",
16
+ "Edit": "Sửa",
17
+ "Edit space": "Sửa Space",
18
+ "Generated HTML": "HTML Đã tạo",
19
+ "Build Log": "Log quá trình Build",
20
+ "Delete": "Xóa",
21
+ "Saved successfully": "Lưu thành công",
22
+ "Please select a User Guide Space in block settings": "Vui lòng chọn Space trong cài đặt block",
23
+ "Build": "Tạo",
24
+ "Build started": "Đã bắt đầu tạo",
25
+ "Build failed": "Tạo thất bại",
26
+ "Are you sure you want to delete this space?": "Bạn có chắc chắn muốn xóa Space này không?"
27
+ }
@@ -0,0 +1,27 @@
1
+ {
2
+ "Build Guide Block": "生成指南区块",
3
+ "User guide block setting": "用户指南区块设置",
4
+ "Edit user guide settings": "编辑用户指南设置",
5
+ "Space": "空间",
6
+ "User Guide": "用户指南",
7
+ "Create space": "创建空间",
8
+ "Title": "标题",
9
+ "LLM Service": "大语言模型服务",
10
+ "Model": "模型",
11
+ "System Prompt": "系统提示词",
12
+ "Documents": "文档",
13
+ "Cancel": "取消",
14
+ "Submit": "提交",
15
+ "Actions": "操作",
16
+ "Edit": "编辑",
17
+ "Edit space": "编辑空间",
18
+ "Generated HTML": "生成的 HTML",
19
+ "Build Log": "构建日志",
20
+ "Delete": "删除",
21
+ "Saved successfully": "保存成功",
22
+ "Please select a User Guide Space in block settings": "请在区块设置中选择一个用户指南空间",
23
+ "Build": "构建",
24
+ "Build started": "构建已开始",
25
+ "Build failed": "构建失败",
26
+ "Are you sure you want to delete this space?": "确定要删除此空间吗?"
27
+ }
@@ -0,0 +1,171 @@
1
+ import { Context, Next } from '@nocobase/actions';
2
+ import { Repository } from '@nocobase/database';
3
+ import sanitizeHtml from 'sanitize-html';
4
+ // @ts-ignore
5
+ import { PluginAIServer } from '@nocobase/plugin-ai';
6
+ // @ts-ignore
7
+ import { PluginFileManagerServer } from '@nocobase/plugin-file-manager';
8
+ import { HumanMessage, SystemMessage } from '@langchain/core/messages';
9
+ import axios from 'axios';
10
+ import fs from 'fs';
11
+ import path from 'path';
12
+
13
+ async function fetchFileContent(app: any, file: any): Promise<string> {
14
+ const fileManager = app.pm.get('file-manager') as PluginFileManagerServer;
15
+ if (!fileManager) return '';
16
+ const url = await fileManager.getFileURL(file);
17
+
18
+ try {
19
+ if (url.startsWith('http')) {
20
+ const response = await axios.get(url, { responseType: 'text', timeout: 15000 });
21
+ return response.data;
22
+ } else {
23
+ let localPath = url;
24
+ if (process.env.APP_PUBLIC_PATH && localPath.startsWith(process.env.APP_PUBLIC_PATH)) {
25
+ localPath = localPath.slice(process.env.APP_PUBLIC_PATH.length);
26
+ }
27
+ localPath = path.join(process.cwd(), localPath);
28
+ const data = await fs.promises.readFile(localPath, 'utf8');
29
+ return data;
30
+ }
31
+ } catch (err) {
32
+ app.log.error(`Failed to read file content for document ${file.id}`, err);
33
+ return `[Failed to read document: ${file.filename}]`;
34
+ }
35
+ }
36
+
37
+ export async function build(ctx: Context, next: Next) {
38
+ const { filterByTk } = ctx.action.params;
39
+ const repository = ctx.db.getRepository('aiBuildGuideSpaces') as Repository;
40
+
41
+ const space = await repository.findById(filterByTk);
42
+
43
+ if (!space) {
44
+ ctx.throw(404, 'Space not found');
45
+ }
46
+
47
+ // Capture the long-lived Application reference — NOT the per-request ctx
48
+ const app = ctx.app;
49
+ const db = ctx.db;
50
+
51
+ try {
52
+ // 1. Set status to building
53
+ await repository.update({
54
+ filterByTk,
55
+ values: {
56
+ status: 'building',
57
+ buildLog: null,
58
+ },
59
+ });
60
+
61
+ // 2. Run the LLM pipeline asynchronously (fire-and-forget)
62
+ const bgPromise = (async () => {
63
+ const bgRepo = db.getRepository('aiBuildGuideSpaces') as Repository;
64
+
65
+ // 2a. Extract Document contexts
66
+ const documents = await space.getDocuments();
67
+ let documentsText = '';
68
+
69
+ if (documents && documents.length > 0) {
70
+ const texts = await Promise.all(
71
+ documents.map(async (doc) => {
72
+ const content = await fetchFileContent(app, doc);
73
+ return `--- Document: ${doc.filename} ---\n${content}\n`;
74
+ })
75
+ );
76
+ documentsText = texts.join('\n');
77
+ }
78
+
79
+ // 2b. Connect to LLM via plugin-ai
80
+ const aiPlugin = app.pm.get('ai') as PluginAIServer;
81
+ if (!aiPlugin) {
82
+ throw new Error('Plugin AI is not available');
83
+ }
84
+
85
+ const { llmService, model, systemPrompt } = space.get();
86
+
87
+ if (!llmService || !model) {
88
+ throw new Error('LLM Service or model is missing in space configuration');
89
+ }
90
+
91
+ const serviceData = await aiPlugin.aiManager.getLLMService({ llmService, model });
92
+ const provider = serviceData.provider;
93
+
94
+ const messages = [];
95
+ if (systemPrompt) {
96
+ messages.push(new SystemMessage(systemPrompt));
97
+ }
98
+
99
+ const instruction = `Please generate an HTML user guide based on the following documents. Output ONLY valid HTML without Markdown blocks.\n\nDocuments:\n${documentsText}`;
100
+ messages.push(new HumanMessage(instruction));
101
+
102
+ const response = await provider.chatModel.invoke(messages);
103
+ let rawHtml = typeof response.content === 'string' ? response.content : JSON.stringify(response.content);
104
+
105
+ // Strip markdown code block if present
106
+ rawHtml = rawHtml.replace(/^```html\s*/, '').replace(/```\s*$/, '');
107
+
108
+ // 2c. Sanitize HTML output
109
+ const cleanHtml = sanitizeHtml(rawHtml, {
110
+ allowedTags: [
111
+ 'div', 'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6',
112
+ 'ul', 'ol', 'li', 'table', 'thead', 'tbody', 'tr', 'td', 'th',
113
+ 'a', 'img', 'span', 'strong', 'em', 'code', 'pre', 'blockquote', 'br', 'hr'
114
+ ],
115
+ allowedAttributes: {
116
+ 'a': ['href', 'target'],
117
+ 'img': ['src', 'alt', 'width', 'height'],
118
+ '*': ['style', 'class']
119
+ },
120
+ allowedStyles: {
121
+ '*': {
122
+ 'color': [/^\#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/, /^rgb/, /^rgba/],
123
+ 'background-color': [/^\#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/, /^rgb/, /^rgba/],
124
+ 'text-align': [/^left$/, /^right$/, /^center$/, /^justify$/],
125
+ 'font-size': [/^\d+(?:px|em|%)$/]
126
+ }
127
+ }
128
+ });
129
+
130
+ // 2d. Save generated HTML
131
+ await bgRepo.update({
132
+ filterByTk,
133
+ values: {
134
+ generatedHtml: cleanHtml,
135
+ status: 'completed',
136
+ },
137
+ });
138
+ })();
139
+
140
+ // Ensure background errors are caught and persisted
141
+ bgPromise.catch(async (error) => {
142
+ app.log.error('Build Guide Background Error', error);
143
+ try {
144
+ const bgRepo = db.getRepository('aiBuildGuideSpaces') as Repository;
145
+ await bgRepo.update({
146
+ filterByTk,
147
+ values: {
148
+ status: 'error',
149
+ buildLog: error.message || String(error),
150
+ },
151
+ });
152
+ } catch (updateErr) {
153
+ app.log.error('Failed to persist build error status', updateErr);
154
+ }
155
+ });
156
+
157
+ ctx.body = { status: 'building' };
158
+ } catch (error) {
159
+ app.log.error('Build Guide Error', error);
160
+ await repository.update({
161
+ filterByTk,
162
+ values: {
163
+ status: 'error',
164
+ buildLog: error.message || String(error),
165
+ },
166
+ });
167
+ ctx.throw(500, error.message || 'Error occurred during build');
168
+ }
169
+
170
+ await next();
171
+ }
@@ -0,0 +1,26 @@
1
+ import { Context, Next } from '@nocobase/actions';
2
+ import { Repository } from '@nocobase/database';
3
+
4
+ export async function getHtml(ctx: Context, next: Next) {
5
+ const { filterByTk } = ctx.action.params;
6
+ const { resourceName } = ctx.action;
7
+ const repository = ctx.db.getRepository<any>(resourceName) as Repository;
8
+ const model = await repository.findById(filterByTk);
9
+
10
+ if (!model) {
11
+ ctx.throw(404, 'User Guide not found');
12
+ }
13
+
14
+ if (model.get('status') !== 'completed') {
15
+ ctx.throw(400, 'User Guide is not ready yet');
16
+ }
17
+
18
+ ctx.body = model.get('generatedHtml') || '';
19
+ ctx.withoutDataWrapping = true;
20
+
21
+ ctx.set({
22
+ 'Content-Type': 'text/html; charset=UTF-8',
23
+ });
24
+
25
+ await next();
26
+ }
File without changes
@@ -0,0 +1,49 @@
1
+ import { defineCollection } from '@nocobase/database';
2
+
3
+ export default defineCollection({
4
+ namespace: 'build-guide-block.ai-build-guide-spaces',
5
+ name: 'aiBuildGuideSpaces',
6
+ migrationRules: ['overwrite', 'schema-only'],
7
+ timestamps: true,
8
+ fields: [
9
+ {
10
+ type: 'uid',
11
+ name: 'id',
12
+ primaryKey: true,
13
+ },
14
+ {
15
+ type: 'string',
16
+ name: 'title',
17
+ },
18
+ {
19
+ type: 'string',
20
+ name: 'llmService',
21
+ },
22
+ {
23
+ type: 'string',
24
+ name: 'model',
25
+ },
26
+ {
27
+ type: 'text',
28
+ name: 'systemPrompt',
29
+ },
30
+ {
31
+ type: 'text',
32
+ name: 'generatedHtml',
33
+ },
34
+ {
35
+ type: 'string',
36
+ name: 'status',
37
+ defaultValue: 'draft',
38
+ },
39
+ {
40
+ type: 'text',
41
+ name: 'buildLog',
42
+ },
43
+ {
44
+ type: 'belongsToMany',
45
+ name: 'documents',
46
+ target: 'attachments',
47
+ },
48
+ ],
49
+ });
@@ -0,0 +1 @@
1
+ export { default } from './plugin';