@mybricks/plugin-ai 0.0.1 → 0.0.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/package.json +7 -2
- package/src/agents/app.ts +188 -60
- package/src/agents/common.ts +428 -68
- package/src/agents/custom.ts +14 -0
- package/src/agents/index.ts +31 -1
- package/src/agents/knowledges/README.md +614 -0
- package/src/agents/knowledges/SUMMARY.md +527 -0
- package/src/agents/knowledges/index.ts +8 -0
- package/src/agents/knowledges/knowledge-base.ts +565 -0
- package/src/agents/knowledges/knowledge-node.ts +266 -0
- package/src/agents/knowledges/types.ts +208 -0
- package/src/agents/utils/config.ts +427 -0
- package/src/agents/workspace/coding-manager.ts +31 -0
- package/src/agents/workspace/components-manager.ts +124 -0
- package/src/agents/workspace/outline-focus.ts +188 -0
- package/src/agents/workspace/outline-info.ts +520 -0
- package/src/agents/workspace/page-tree-generator.ts +83 -0
- package/src/agents/workspace/workspace.ts +319 -0
- package/src/agents/workspace-by-knowledges/MIGRATION.md +568 -0
- package/src/agents/workspace-by-knowledges/README.md +521 -0
- package/src/agents/workspace-by-knowledges/index.ts +11 -0
- package/src/agents/workspace-by-knowledges/providers/component-docs-provider.ts +92 -0
- package/src/agents/workspace-by-knowledges/providers/focus-info-provider.ts +131 -0
- package/src/agents/workspace-by-knowledges/providers/index.ts +8 -0
- package/src/agents/workspace-by-knowledges/providers/project-info-provider.ts +151 -0
- package/src/agents/workspace-by-knowledges/test.ts +240 -0
- package/src/agents/workspace-by-knowledges/types.ts +56 -0
- package/src/agents/workspace-by-knowledges/utils/components-manager.ts +145 -0
- package/src/agents/workspace-by-knowledges/utils/index.ts +8 -0
- package/src/agents/workspace-by-knowledges/utils/outline-focus.ts +178 -0
- package/src/agents/workspace-by-knowledges/utils/outline-info.ts +521 -0
- package/src/agents/workspace-by-knowledges/workspace.ts +166 -0
- package/src/api/cloud-components.ts +129 -0
- package/src/api-record-replay/README.md +187 -0
- package/src/api-record-replay/index.ts +11 -0
- package/src/api-record-replay/manager.ts +168 -0
- package/src/api-record-replay/recorder.ts +117 -0
- package/src/api-record-replay/replayer.ts +148 -0
- package/src/components/attachments/index.less +117 -0
- package/src/components/attachments/index.tsx +136 -0
- package/src/components/icons/index.tsx +21 -1
- package/src/components/index.less +34 -0
- package/src/components/mention/index.less +23 -0
- package/src/components/mention/index.tsx +19 -0
- package/src/components/messages/index.less +444 -237
- package/src/components/messages/index.tsx +371 -88
- package/src/components/sender/index.less +203 -0
- package/src/components/sender/index.tsx +298 -0
- package/src/components/types.ts +31 -0
- package/src/constants/index.ts +8 -0
- package/src/context/RequestStatusTracker.ts +50 -0
- package/src/context/index.ts +68 -6
- package/src/{types.d.ts → global.d.ts} +40 -5
- package/src/index.tsx +212 -32
- package/src/preset/agents.ts +380 -0
- package/src/preset/createTemplates.ts +25 -0
- package/src/preset/index.ts +12 -0
- package/src/preset/prompts.ts +235 -0
- package/src/preset/requestAsStream.ts +246 -0
- package/src/preset/user.ts +6 -0
- package/src/startView/components/header/header.less +17 -0
- package/src/startView/components/header/header.tsx +15 -0
- package/src/startView/components/index.ts +1 -0
- package/src/startView/index.less +22 -204
- package/src/startView/index.tsx +35 -203
- package/src/tools/analyze-and-expand-prd.ts +192 -86
- package/src/tools/analyze-requirement-and-components.ts +589 -0
- package/src/tools/answer.ts +59 -0
- package/src/tools/build-process.ts +1174 -0
- package/src/tools/coding-subagent-as-tool.ts +119 -0
- package/src/tools/generate-ui-content.ts +1083 -0
- package/src/tools/index.ts +22 -19
- package/src/tools/open-dsl.ts +69 -0
- package/src/tools/refactor-ui-content.ts +801 -0
- package/src/tools/utils.ts +880 -28
- package/src/types/index.ts +4 -0
- package/src/view/components/header/header.less +36 -2
- package/src/view/components/header/header.tsx +47 -2
- package/src/view/components/index.ts +0 -2
- package/src/view/index.tsx +158 -8
- package/src/tools/answer-user.ts +0 -35
- package/src/tools/focus-element.ts +0 -47
- package/src/tools/generate-page.ts +0 -750
- package/src/tools/get-component-info-by-ids.ts +0 -166
- package/src/tools/get-component-info.ts +0 -53
- package/src/tools/get-components-doc-and-prd.ts +0 -137
- package/src/tools/get-focus-mybricks-dsl.ts +0 -26
- package/src/tools/get-mybricks-dsl.ts +0 -73
- package/src/tools/modify-component.ts +0 -385
- package/src/view/components/messages/messages.less +0 -228
- package/src/view/components/messages/messages.tsx +0 -172
- package/src/view/components/sender/sender.less +0 -44
- package/src/view/components/sender/sender.tsx +0 -62
|
@@ -0,0 +1,380 @@
|
|
|
1
|
+
import { fileFormat } from "@mybricks/rxai";
|
|
2
|
+
import { SingleInstanceAgent } from "../agents/utils/config";
|
|
3
|
+
import { MYBRICKS_TOOLS } from "./../tools";
|
|
4
|
+
import { context } from "../context";
|
|
5
|
+
import { PromiseStack } from "../tools/utils";
|
|
6
|
+
|
|
7
|
+
export const agents = [
|
|
8
|
+
new SingleInstanceAgent({
|
|
9
|
+
name: '智能组件助手',
|
|
10
|
+
type: 'mybricks.basic-comlib.ai-mix', // 这个需要和focus里面的type对应上
|
|
11
|
+
goal: '根据用户需要,开发可运行在MyBricks平台的组件',
|
|
12
|
+
backstory: `基于React + Less`,
|
|
13
|
+
tools: (params: any) => {
|
|
14
|
+
const promiseStack = new PromiseStack();
|
|
15
|
+
const { focus } = params;
|
|
16
|
+
const FILENAME_TO_ACTION: Record<string, string> = {
|
|
17
|
+
"index.jsx": "编写组件runtime代码",
|
|
18
|
+
"index.less": "编写组件样式代码",
|
|
19
|
+
"inputs.json": "更新组件输入项",
|
|
20
|
+
"outputs.json": "更新组件输出项",
|
|
21
|
+
"configs.json": "更新组件配置项"
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
return [
|
|
25
|
+
{
|
|
26
|
+
name: 'generate-mybricks-component', // 唯一key
|
|
27
|
+
displayName: '编写组件代码', // 这个用于ui展示
|
|
28
|
+
description: '编写MyBricks平台的组件代码', // 工具摘要,用于ai规划使用
|
|
29
|
+
getPrompts: (params: any) => {
|
|
30
|
+
const comInfo = context.api.uiCom.api.getOutlineInfo(focus.comId);
|
|
31
|
+
return `你是一个专业的前端开发者,专注于MyBricks生态的组件开发,精通React + Less技术栈,熟练使用echarts-for-react三方库,能够严格遵循规范完成组件的运行时、样式、输入项、输出项、配置项的开发,精准响应用户的组件开发需求。
|
|
32
|
+
|
|
33
|
+
<限制使用的技术栈和三方库>
|
|
34
|
+
技术栈
|
|
35
|
+
- React
|
|
36
|
+
- Less
|
|
37
|
+
|
|
38
|
+
三方库
|
|
39
|
+
- echarts-for-react
|
|
40
|
+
|
|
41
|
+
除上述技术栈和三方库外,禁止使用其他任何技术栈和三方库。
|
|
42
|
+
</限制使用的技术栈和三方库>
|
|
43
|
+
|
|
44
|
+
<如何编写MyBricks组件>
|
|
45
|
+
<编写组件runtime代码>
|
|
46
|
+
- 基于React框架编写组件的运行时代码
|
|
47
|
+
- 返回组件runtime代码字符串示例
|
|
48
|
+
${fileFormat({
|
|
49
|
+
content: `import React from 'react';
|
|
50
|
+
import './index.less';
|
|
51
|
+
|
|
52
|
+
export default function Button() {
|
|
53
|
+
return (
|
|
54
|
+
<button className="button">按钮</button>
|
|
55
|
+
);
|
|
56
|
+
}`,
|
|
57
|
+
fileName: 'index.jsx'
|
|
58
|
+
})}
|
|
59
|
+
</编写组件runtime代码>
|
|
60
|
+
|
|
61
|
+
<编写组件样式代码>
|
|
62
|
+
- 基于Less框架编写组件的样式代码
|
|
63
|
+
- 返回组件样式代码字符串示例
|
|
64
|
+
${fileFormat({
|
|
65
|
+
content: `.button {
|
|
66
|
+
background-color: #000;
|
|
67
|
+
color: #fff;
|
|
68
|
+
}`,
|
|
69
|
+
fileName: 'index.less'
|
|
70
|
+
})}
|
|
71
|
+
</编写组件样式代码>
|
|
72
|
+
|
|
73
|
+
<更新组件的输入项>
|
|
74
|
+
- 输入项用于外部调用组件的各类api,实现外部对组件的动态修改
|
|
75
|
+
- 返回内容格式以Typescript的形式说明如下
|
|
76
|
+
\`\`\`typescript
|
|
77
|
+
interface Params {
|
|
78
|
+
id: string; // 输入项id
|
|
79
|
+
title: string; // 输入项语义化名称
|
|
80
|
+
/**
|
|
81
|
+
* 操作类型
|
|
82
|
+
* undefined - 根据是否存在id判断是添加或更新
|
|
83
|
+
* delete - 删除id对应的输入项
|
|
84
|
+
*/
|
|
85
|
+
updateType: "delete" | undefined;
|
|
86
|
+
}
|
|
87
|
+
\`\`\`
|
|
88
|
+
- 返回内容示例示例
|
|
89
|
+
1. 添加
|
|
90
|
+
${fileFormat({
|
|
91
|
+
content: `[{"id":"语义化的输入项id","title":"语义化的输入项标题"}]`,
|
|
92
|
+
fileName: 'inputs.json'
|
|
93
|
+
})}
|
|
94
|
+
2. 修改,除了id以外的字段均为可选项
|
|
95
|
+
${fileFormat({
|
|
96
|
+
content: `[{"id":"需要修改的输入项id","title":"修改的输入项标题"}]`,
|
|
97
|
+
fileName: 'inputs.json'
|
|
98
|
+
})}
|
|
99
|
+
3. 删除,只需要id和updateType
|
|
100
|
+
${fileFormat({
|
|
101
|
+
content: `[{"id":"需要删除的输入项id","updateType":"delete"}]`,
|
|
102
|
+
fileName: 'inputs.json'
|
|
103
|
+
})}
|
|
104
|
+
- 更新输入项后按需同步<编写组件runtime代码>
|
|
105
|
+
</更新组件的输入项>
|
|
106
|
+
|
|
107
|
+
<更新组件的输出项>
|
|
108
|
+
- 添加组件的输出项,用于组件内各类事件触发时向外输出内容
|
|
109
|
+
- 返回内容格式以Typescript的形式说明如下
|
|
110
|
+
\`\`\`typescript
|
|
111
|
+
interface Params {
|
|
112
|
+
id: string; // 输出项id
|
|
113
|
+
title: string; // 输出项语义化名称
|
|
114
|
+
/**
|
|
115
|
+
* 操作类型
|
|
116
|
+
* undefined - 根据是否存在id判断是添加或更新
|
|
117
|
+
* delete - 删除id对应的输出项
|
|
118
|
+
*/
|
|
119
|
+
updateType: "delete" | undefined;
|
|
120
|
+
}
|
|
121
|
+
\`\`\`
|
|
122
|
+
- 返回内容示例示例
|
|
123
|
+
1. 添加
|
|
124
|
+
${fileFormat({
|
|
125
|
+
content: `[{"id":"语义化的输出项id","title":"语义化的输出项标题"}]`,
|
|
126
|
+
fileName: 'outputs.json'
|
|
127
|
+
})}
|
|
128
|
+
2. 修改,除了id以外的字段均为可选项
|
|
129
|
+
${fileFormat({
|
|
130
|
+
content: `[{"id":"需要修改的输出项id","title":"修改的输出项标题"}]`,
|
|
131
|
+
fileName: 'outputs.json'
|
|
132
|
+
})}
|
|
133
|
+
3. 删除,只需要id和updateType
|
|
134
|
+
${fileFormat({
|
|
135
|
+
content: `[{"id":"需要删除的输出项id","updateType":"delete"}]`,
|
|
136
|
+
fileName: 'outputs.json'
|
|
137
|
+
})}
|
|
138
|
+
- 更新输出项后按需同步<编写组件runtime代码>
|
|
139
|
+
</更新组件的输出项>
|
|
140
|
+
|
|
141
|
+
<更新组件的配置项>
|
|
142
|
+
- 配置项用于组件的静态数据配置编辑,渲染时通过组件入参*data*读取配置内容
|
|
143
|
+
- 返回内容格式以Typescript的形式说明如下
|
|
144
|
+
\`\`\`typescript
|
|
145
|
+
type Params = TextParams | StyleParams;
|
|
146
|
+
/**
|
|
147
|
+
* 操作类型
|
|
148
|
+
* undefined - 根据是否存在key判断是添加或更新
|
|
149
|
+
* delete - 删除key对应的配置项
|
|
150
|
+
*/
|
|
151
|
+
type UpdateType = "delete" | undefined;
|
|
152
|
+
|
|
153
|
+
interface ConfigBase {
|
|
154
|
+
/** 配置项的语义化标题 */
|
|
155
|
+
title: string;
|
|
156
|
+
/** 唯一的key,没有业务语义,用于查询对应的配置项 */
|
|
157
|
+
key: string;
|
|
158
|
+
updateType: UpdateType;
|
|
159
|
+
/**
|
|
160
|
+
* css选择器,表达需要对哪一块区域进行编辑。
|
|
161
|
+
* 如果是对组件整体配置,默认使用*:root*,需要与元素的className对应。
|
|
162
|
+
* 注意只能使用*类选择器*,禁止其它任何形式的选择器。
|
|
163
|
+
*/
|
|
164
|
+
selector: string;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* 文本类型配置
|
|
169
|
+
*/
|
|
170
|
+
interface TextParams extends ConfigBase {
|
|
171
|
+
type: "text";
|
|
172
|
+
/** 需要配置的语义化字段,对应到组件的入参的*data[fieldName]* */
|
|
173
|
+
fieldName: string;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* 样式配置
|
|
178
|
+
*/
|
|
179
|
+
interface StyleParams extends ConfigBase {
|
|
180
|
+
type: "style";
|
|
181
|
+
/** 样式编辑器配置 */
|
|
182
|
+
option: {
|
|
183
|
+
/**
|
|
184
|
+
* 需要支持的配置内容
|
|
185
|
+
* font - 字体配置
|
|
186
|
+
* background - 背景配置
|
|
187
|
+
*/
|
|
188
|
+
options: string[];
|
|
189
|
+
/** 样式作用于目标元素的 css selector,多个target代表样式同时作用于多个目标元素 */
|
|
190
|
+
target: string[];
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
\`\`\`
|
|
194
|
+
- 返回内容示例示例
|
|
195
|
+
1. 添加
|
|
196
|
+
${fileFormat({
|
|
197
|
+
content: '[{"type":"配置项类型","title":"语义化的配置项标题","fieldName":"fieldName","key":"key","selector":"selector"}]',
|
|
198
|
+
fileName: 'configs.json'
|
|
199
|
+
})}
|
|
200
|
+
2. 修改,除了key以外的字段均为可选项
|
|
201
|
+
${fileFormat({
|
|
202
|
+
content: '[{"type":"配置项类型","title":"语义化的配置项标题","fieldName":"fieldName","key":"key","selector":"selector"}]',
|
|
203
|
+
fileName: 'configs.json'
|
|
204
|
+
})}
|
|
205
|
+
3. 删除,只需要key和updateType
|
|
206
|
+
${fileFormat({
|
|
207
|
+
content: '[{"key":"需要删除的配置项key","updateType":"delete"}]',
|
|
208
|
+
fileName: 'configs.json'
|
|
209
|
+
})}
|
|
210
|
+
- 更新配置项后按需同步<编写组件runtime代码>
|
|
211
|
+
</更新组件的配置项>
|
|
212
|
+
|
|
213
|
+
注意:
|
|
214
|
+
- 当没有数据类型的配置项(非样式配置)时,禁止使用入参*data*,只有配置项才需要从*data*中获取对应的值
|
|
215
|
+
- 无论修改了什么内容,都要分析是否有相关的内容需要改造,例如runtime代码内没有调用outputs了,是否同步删除组件的输出项
|
|
216
|
+
</如何编写MyBricks组件>
|
|
217
|
+
|
|
218
|
+
<当前组件内容>
|
|
219
|
+
runtime代码:
|
|
220
|
+
${fileFormat({
|
|
221
|
+
content: `${decodeURIComponent(comInfo.data._sourceRenderCode || "")}`,
|
|
222
|
+
fileName: 'index.jsx'
|
|
223
|
+
})}
|
|
224
|
+
|
|
225
|
+
样式代码:
|
|
226
|
+
${fileFormat({
|
|
227
|
+
content: `${decodeURIComponent(comInfo.data._sourceStyleCode || "")}`,
|
|
228
|
+
fileName: 'index.less'
|
|
229
|
+
})}
|
|
230
|
+
|
|
231
|
+
输入项:
|
|
232
|
+
${fileFormat({
|
|
233
|
+
content: `${JSON.stringify(comInfo.data.inputs || [])}`,
|
|
234
|
+
fileName: 'inputs.json'
|
|
235
|
+
})}
|
|
236
|
+
|
|
237
|
+
输出项:
|
|
238
|
+
${fileFormat({
|
|
239
|
+
content: `${JSON.stringify(comInfo.data.outputs || [])}`,
|
|
240
|
+
fileName: 'outputs.json'
|
|
241
|
+
})}
|
|
242
|
+
|
|
243
|
+
配置项:
|
|
244
|
+
${fileFormat({
|
|
245
|
+
content: `${JSON.stringify(comInfo.data.configs || [])}`,
|
|
246
|
+
fileName: 'configs.json'
|
|
247
|
+
})}
|
|
248
|
+
</当前组件内容>
|
|
249
|
+
|
|
250
|
+
<开发须知>
|
|
251
|
+
- 对于开发过程中使用到的占位图片,可以使用以下服务,根据其用途选择合适的来源
|
|
252
|
+
- https://placehold.co/600x400/orange/ffffff?text=hello,可以配置一个橙色背景带白色hello文字的色块占位图片。
|
|
253
|
+
- https://ai.mybricks.world/image-search?term=搜索词&w=宽&h=高,可以配置一个高质量的摄影图片。
|
|
254
|
+
- 当要求根据附件中的图片进行开发、还原时,需要分析元素结构、区块结构、布局、颜色、文字、内边距、外边距、圆角等视觉信息,并输出分析结果,为后续的代码编写提供依据。
|
|
255
|
+
- 编辑任何内容前,都需要说明原因以及即将修改的内容是什么。
|
|
256
|
+
</开发须知>
|
|
257
|
+
|
|
258
|
+
<输出规范>
|
|
259
|
+
- 无需添加修改说明类表述,如「以下是修改后的内容」「根据要求修改如下」「根据要求新增如下」等。
|
|
260
|
+
- 禁止出现文件名,代码块标识等与文件无关的内容。
|
|
261
|
+
</输出规范>
|
|
262
|
+
|
|
263
|
+
<注意>
|
|
264
|
+
- 按需开发,保持最简实现。
|
|
265
|
+
- 当需求不涉及样式修改时,禁止返回<编写组件样式代码>内容。
|
|
266
|
+
- 当需求修改不涉及元素变更、样式名称变更、输入、输出、配置时,禁止返回<编写组件runtime代码>内容。
|
|
267
|
+
- 当需求中没有提及输入项,禁止返回<更新组件的输入项>内容。
|
|
268
|
+
- 当需求中没有提及输出项,禁止返回<更新组件的输出项>内容。
|
|
269
|
+
- 当需求中没有提及配置项,禁止返回<更新组件的配置项>内容。
|
|
270
|
+
</注意>
|
|
271
|
+
`
|
|
272
|
+
},
|
|
273
|
+
stream(params: any) {
|
|
274
|
+
const { files, replaceContent, status } = params;
|
|
275
|
+
const filesLastIndex = files.length - 1;
|
|
276
|
+
let result = replaceContent;
|
|
277
|
+
files.forEach((file: any, index: number) => {
|
|
278
|
+
const { fileName } = file;
|
|
279
|
+
if (index === filesLastIndex && status !== 'complete') {
|
|
280
|
+
if (result.endsWith(fileName)) {
|
|
281
|
+
result = result.replace(fileName, "正在" + FILENAME_TO_ACTION[fileName] + "...");
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
result = result.replace(fileName, FILENAME_TO_ACTION[fileName] + "完成");
|
|
286
|
+
})
|
|
287
|
+
return result;
|
|
288
|
+
},
|
|
289
|
+
execute: async (params: any) => {
|
|
290
|
+
console.log("[生成组件代码 - execute]", params);
|
|
291
|
+
console.log("[focus]", focus)
|
|
292
|
+
const { files, replaceContent } = params;
|
|
293
|
+
const actions: any[] = [];
|
|
294
|
+
const { comId, pageId } = focus;
|
|
295
|
+
|
|
296
|
+
files.forEach((file: any) => {
|
|
297
|
+
const { fileName, content } = file;
|
|
298
|
+
switch (file.fileName) {
|
|
299
|
+
case "index.jsx":
|
|
300
|
+
actions.push({
|
|
301
|
+
comId,
|
|
302
|
+
type: "doConfig",
|
|
303
|
+
target: ":root",
|
|
304
|
+
params: {
|
|
305
|
+
path: "组件runtime代码",
|
|
306
|
+
value: content
|
|
307
|
+
}
|
|
308
|
+
})
|
|
309
|
+
break
|
|
310
|
+
case "index.less":
|
|
311
|
+
actions.push({
|
|
312
|
+
comId,
|
|
313
|
+
type: "doConfig",
|
|
314
|
+
target: ":root",
|
|
315
|
+
params: {
|
|
316
|
+
path: "组件样式代码",
|
|
317
|
+
value: content
|
|
318
|
+
}
|
|
319
|
+
})
|
|
320
|
+
break
|
|
321
|
+
case "inputs.json":
|
|
322
|
+
actions.push({
|
|
323
|
+
comId,
|
|
324
|
+
type: "doConfig",
|
|
325
|
+
target: ":root",
|
|
326
|
+
params: {
|
|
327
|
+
path: "更新输入项",
|
|
328
|
+
value: JSON.parse(content)
|
|
329
|
+
}
|
|
330
|
+
});
|
|
331
|
+
break;
|
|
332
|
+
case "outputs.json":
|
|
333
|
+
actions.push({
|
|
334
|
+
comId,
|
|
335
|
+
type: "doConfig",
|
|
336
|
+
target: ":root",
|
|
337
|
+
params: {
|
|
338
|
+
path: "更新输出项",
|
|
339
|
+
value: JSON.parse(content)
|
|
340
|
+
}
|
|
341
|
+
});
|
|
342
|
+
break;
|
|
343
|
+
case "configs.json":
|
|
344
|
+
actions.push({
|
|
345
|
+
comId,
|
|
346
|
+
type: "doConfig",
|
|
347
|
+
target: ":root",
|
|
348
|
+
params: {
|
|
349
|
+
path: "更新配置项",
|
|
350
|
+
value: JSON.parse(content)
|
|
351
|
+
}
|
|
352
|
+
});
|
|
353
|
+
break;
|
|
354
|
+
default:
|
|
355
|
+
break;
|
|
356
|
+
}
|
|
357
|
+
})
|
|
358
|
+
|
|
359
|
+
promiseStack.add(() => {
|
|
360
|
+
context.designer?.updatePage?.(pageId, [], 'start');
|
|
361
|
+
})
|
|
362
|
+
promiseStack.add(() => {
|
|
363
|
+
context.designer?.updatePage?.(pageId, actions, 'ing');
|
|
364
|
+
})
|
|
365
|
+
promiseStack.add(() => {
|
|
366
|
+
context.designer?.updatePage?.(pageId, [], 'complete');
|
|
367
|
+
})
|
|
368
|
+
|
|
369
|
+
return files.reduce((pre: string, file: any) => {
|
|
370
|
+
return pre.replace(file.fileName, FILENAME_TO_ACTION[file.fileName] + "完成");
|
|
371
|
+
}, replaceContent)
|
|
372
|
+
},
|
|
373
|
+
// aiRole: "expert",
|
|
374
|
+
// aiRole: "architect",
|
|
375
|
+
},
|
|
376
|
+
MYBRICKS_TOOLS.Answer({})
|
|
377
|
+
]
|
|
378
|
+
},
|
|
379
|
+
})
|
|
380
|
+
]
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export const createTemplates = {
|
|
2
|
+
page: ({ title }: any) => {
|
|
3
|
+
return {
|
|
4
|
+
type: "normal",
|
|
5
|
+
title: title,
|
|
6
|
+
template: {
|
|
7
|
+
namespace: 'mybricks.harmony.systemPage',
|
|
8
|
+
deletable: false,
|
|
9
|
+
asRoot: true,
|
|
10
|
+
data: {
|
|
11
|
+
useTabBar: false,
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
inputs: [
|
|
15
|
+
{
|
|
16
|
+
id: "open",
|
|
17
|
+
title: "打开",
|
|
18
|
+
schema: {
|
|
19
|
+
type: "object",
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
],
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { user } from "./user"
|
|
2
|
+
import { prompts } from "./prompts"
|
|
3
|
+
import { createRequestAsStream } from "./requestAsStream"
|
|
4
|
+
import { createTemplates } from './createTemplates'
|
|
5
|
+
|
|
6
|
+
export default {
|
|
7
|
+
name: '智能助手',
|
|
8
|
+
user,
|
|
9
|
+
prompts,
|
|
10
|
+
createRequestAsStream,
|
|
11
|
+
createTemplates,
|
|
12
|
+
}
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
import { fileFormat } from "@mybricks/rxai";
|
|
2
|
+
import { DeviceType } from './../types';
|
|
3
|
+
|
|
4
|
+
function systemAppendPrompts () {
|
|
5
|
+
return `
|
|
6
|
+
<对于当前搭建有以下特殊上下文>
|
|
7
|
+
<搭建画布信息>
|
|
8
|
+
当前搭建画布的宽度为375,所有元素的尺寸需要关注此信息,且尽可能自适应宽度进行布局。
|
|
9
|
+
比如:
|
|
10
|
+
1.布局需要自适应画布宽度,考虑100%通栏,要么配置宽度+间距;
|
|
11
|
+
2.配置上下左右和宽度高度时,一定要基于画布尺寸进行合理的计算;
|
|
12
|
+
特殊地,系统已经内置了底部导航栏和顶部导航栏,仅关注页面内容即可,不用实现此部分内容。
|
|
13
|
+
最后,必须给页面设置页面高度。
|
|
14
|
+
</搭建画布信息>
|
|
15
|
+
|
|
16
|
+
<允许使用的图标>
|
|
17
|
+
airplane_fill
|
|
18
|
+
alarm_fill_1
|
|
19
|
+
arrow_clockwise
|
|
20
|
+
arrow_counterclockwise
|
|
21
|
+
arrow_counterclockwise_clock
|
|
22
|
+
arrow_down_right_and_arrow_up_left
|
|
23
|
+
arrow_left
|
|
24
|
+
arrow_right
|
|
25
|
+
arrow_right_up_and_square
|
|
26
|
+
arrow_up_left_and_arrow_down_right
|
|
27
|
+
arrow_up_to_line
|
|
28
|
+
arrowshape_turn_up_right_fill
|
|
29
|
+
backward_end_fill
|
|
30
|
+
battery
|
|
31
|
+
battery_75percent
|
|
32
|
+
bell_fill
|
|
33
|
+
bluetooth
|
|
34
|
+
bluetooth_slash
|
|
35
|
+
bookmark
|
|
36
|
+
calendar
|
|
37
|
+
camera
|
|
38
|
+
camera_fill
|
|
39
|
+
checkmark
|
|
40
|
+
checkmark_circle
|
|
41
|
+
checkmark_circle_fill
|
|
42
|
+
checkmark_square
|
|
43
|
+
checkmark_square_fill
|
|
44
|
+
chevron_down
|
|
45
|
+
chevron_left
|
|
46
|
+
chevron_right
|
|
47
|
+
chevron_up
|
|
48
|
+
clock
|
|
49
|
+
dial
|
|
50
|
+
doc_plaintext
|
|
51
|
+
doc_plaintext_and_pencil
|
|
52
|
+
doc_text_badge_arrow_up
|
|
53
|
+
doc_text_badge_magnifyingglass
|
|
54
|
+
ellipsis_message
|
|
55
|
+
envelope
|
|
56
|
+
eye
|
|
57
|
+
eye_slash
|
|
58
|
+
fast_forward
|
|
59
|
+
folder
|
|
60
|
+
folder_badge_plus
|
|
61
|
+
forward_end_fill
|
|
62
|
+
gearshape
|
|
63
|
+
hand_thumbsup_fill
|
|
64
|
+
headphones_fill
|
|
65
|
+
heart
|
|
66
|
+
heart_fill
|
|
67
|
+
heart_slash
|
|
68
|
+
house
|
|
69
|
+
house_fill
|
|
70
|
+
line_viewfinder
|
|
71
|
+
list_square_bill
|
|
72
|
+
livephoto
|
|
73
|
+
lock
|
|
74
|
+
lock_open
|
|
75
|
+
magnifyingglass
|
|
76
|
+
message
|
|
77
|
+
message_on_message
|
|
78
|
+
mic
|
|
79
|
+
music
|
|
80
|
+
music_note_list
|
|
81
|
+
paintpalette
|
|
82
|
+
paperclip
|
|
83
|
+
pause
|
|
84
|
+
picture
|
|
85
|
+
picture_2
|
|
86
|
+
picture_damage
|
|
87
|
+
play_circle_fill
|
|
88
|
+
play_fill
|
|
89
|
+
play_round_rectangle_fill
|
|
90
|
+
play_video
|
|
91
|
+
plus
|
|
92
|
+
qrcode
|
|
93
|
+
record_circle
|
|
94
|
+
resolution_video
|
|
95
|
+
save
|
|
96
|
+
share
|
|
97
|
+
template
|
|
98
|
+
text_clipboard
|
|
99
|
+
timer
|
|
100
|
+
trash
|
|
101
|
+
wifi
|
|
102
|
+
worldclock
|
|
103
|
+
xmark
|
|
104
|
+
</允许使用的图标>
|
|
105
|
+
</对于当前搭建有以下特殊上下文>`
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function prdExamplesPrompts () {
|
|
109
|
+
return `
|
|
110
|
+
<example>
|
|
111
|
+
<user_query>根据图片搭建页面</user_query>
|
|
112
|
+
<assistant_response>
|
|
113
|
+
好的,经过对图片的全面分析,结论如下:
|
|
114
|
+
${fileFormat({
|
|
115
|
+
content: `**themes**
|
|
116
|
+
界面采用简约的卡片式布局,整体背景采用浅紫色,内容区域使用纯白色背景,营造出清爽简洁的视觉效果。
|
|
117
|
+
|
|
118
|
+
**layout**
|
|
119
|
+
界面总体采用从上往下的纵向流式布局,顶部内容通栏,每个区块以圆角卡片的形式呈现,底部通栏为固定布局;
|
|
120
|
+
1. 顶部区域为通栏,中间居中展示一个图标 + 标题;
|
|
121
|
+
2. 导航区域为两行四列的导航入口;
|
|
122
|
+
3. 套餐区域为横向三列的均分布局卡片;
|
|
123
|
+
3.1 卡片内所有文本元素从上到下依次排列,右上角可能存在一个圆形的角标;
|
|
124
|
+
4. 联系人区域是居左的标题 + 居右的联系人详情,联系人详情包含头像和昵称,以及一个可选择箭头;
|
|
125
|
+
5. 结算区域是固定的底部内容,包含左侧的价格计算+右侧的支付按钮;
|
|
126
|
+
|
|
127
|
+
**colors**
|
|
128
|
+
界面主色调为明亮的蓝紫色,用于突出按钮和重要文字。背景采用柔和的浅紫色,搭配纯白色的内容区域,形成层次分明的视觉层级。
|
|
129
|
+
|
|
130
|
+
**attention**
|
|
131
|
+
注意以下细节:
|
|
132
|
+
- 截图中的总体背景没有意义,可以考虑去掉;
|
|
133
|
+
- 注意各区块间距,顶部通栏就不要使用外间距了;
|
|
134
|
+
- 卡片中字体内容较丰富,注意字体大小,不要换行和重叠;
|
|
135
|
+
- 图片中的电话区域选择与输入手机号为一体设计、整体圆角;
|
|
136
|
+
- 验证码区域的获取验证码按钮为蓝色,按钮文字为白色;
|
|
137
|
+
|
|
138
|
+
**risk**
|
|
139
|
+
参考图片宽度为720像素,目标画布宽度为375像素,我们需要对元素尺寸进行合理的缩放,所以在搭建时需要注意内容不要溢出画布,主要关注以下部分:
|
|
140
|
+
1. 导航区域为两行四列的网格均分布局,两行使用换行来实现,同时内容需要考虑固定宽度,避免超出画布;
|
|
141
|
+
2. 套餐区域中的卡片为三列的均分布局,其中卡片的内容信息较丰富,建议固定宽高,同时将文本字体减少至10px;
|
|
142
|
+
3. “适合各种活动的场地”为动态内容,注意配置文本字体极小,并且配置溢出能力,避免换行;
|
|
143
|
+
4. 底部居左部分内容宽度缩小后会超过一半,注意将字体调整至极小,避免遮挡右侧内容;
|
|
144
|
+
5. 右侧图标 + 文本横向排列时,注意文本宽度,防止遮挡图标;`,
|
|
145
|
+
fileName: 'XX页面需求文档.md'
|
|
146
|
+
})}
|
|
147
|
+
|
|
148
|
+
推荐采用以下组件进行搭建:
|
|
149
|
+
${fileFormat({
|
|
150
|
+
content: `[
|
|
151
|
+
{
|
|
152
|
+
"namespace": "mybricks.somelib.card"
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
"namespace": "mybricks.somelib.icon"
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
"namespace": "mybricks.somelib.text"
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
"namespace": "mybricks.somelib.button"
|
|
162
|
+
}
|
|
163
|
+
]`,
|
|
164
|
+
fileName: 'XX页面所需要的组件信息.json'
|
|
165
|
+
})}
|
|
166
|
+
</assistant_response>
|
|
167
|
+
</example>`
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function generatePageActionExamplesPrompts() {
|
|
171
|
+
return `
|
|
172
|
+
<example>
|
|
173
|
+
<user_query>搭建一个个人中心页面框架</user_query>
|
|
174
|
+
<assistant_response>
|
|
175
|
+
首先,必须根据页面内容设置一个合适的页面的高度。
|
|
176
|
+
其次,必须对页面布局设置一个合理的布局。
|
|
177
|
+
然后
|
|
178
|
+
基于用户当前的选择上下文,我们来实现一个个人中心页面框架,由于是框架,所以我仅给出主体部分,思考过程如下:
|
|
179
|
+
1. 搭建页面时一般用从上到下的楼层化搭建方式,我们推荐在页面最外层设置为flex的垂直布局,设置子组件的左右margin以及高度,这样好调整位置;
|
|
180
|
+
2. 将页面从上到下分成顶部信息、个人信息、中间入口、底部按钮四个部分;
|
|
181
|
+
3. 个人信息部分,图文编排卡片,用flex布局实现左右布局;
|
|
182
|
+
4. 中间入口是竖排的入口,为了方便上下调整,我们可以使用flex布局;
|
|
183
|
+
5. 底部居下固定的修改个人信息的按钮;
|
|
184
|
+
|
|
185
|
+
${fileFormat({
|
|
186
|
+
content: `["_root_",":root","setLayout",{"height": 820}]
|
|
187
|
+
["_root_",":root","doConfig",{"path":"root/标题","value":"个人中心页面框架"}]
|
|
188
|
+
["_root_",":root","doConfig",{"path":"root/布局","value":{"display":"flex","flexDirection":"column","alignItems":"center"}}]
|
|
189
|
+
["_root_",":root","doConfig",{"path":"root/样式","style":{"background":"#F5F5F5"}}]
|
|
190
|
+
["_root_","_rootSlot_","addChild",{"title":"顶部信息","ns":"some.banner","comId":"u_top32","layout":{"width":"100%","height":80,"marginTop":8,"marginLeft":12,"marginRight":12},"configs":[{"path":"常规/布局","value":{"display":"flex"}}]}]
|
|
191
|
+
["_root_","_rootSlot_","addChild",{"title":"个人信息","ns":"some.container","comId":"u_a2fer","layout":{"width":"100%","height":100,"marginLeft":8,"marginRight":8},"configs":[{"path":"常规/布局","value":{"display":"flex","flexDirection":"row","justifyContent":"space-between","alignItems":"center"}}]}]
|
|
192
|
+
["u_a2fer", "content", "addChild",{"title":"头像","ns":"some.avatar","comId":"u_avatar1","layout":{"width":64,"height":64},"configs":[]}]
|
|
193
|
+
["u_a2fer", "content", "addChild",{"title":"用户信息","ns":"some.container","comId":"u_info4","ignore":true,"layout":{"width":"fit-content","height":"fit-content"},"configs":[{"path":"常规/布局","value":{"display":"flex","flexDirection":"row","alignItems":"center"}}]}]
|
|
194
|
+
["_root_","_rootSlot_","addChild",{"title":"中间入口","ns":"some.container","comId":"u_iiusd7","layout":{"width":"100%","height":200,"marginLeft":8,"marginRight":8},"configs":[{"path":"常规/布局","value":{"display":"flex","flexDirection":"column"}}]}]
|
|
195
|
+
["_root_","_rootSlot_","addChild",{"title":"底部固定按钮","comId":"u_btm21","ns":"some.container","layout":{"width":"100%","height":84,"position":"fixed","bottom":0,"left":0},"configs":[{"path":"常规/布局","value":{"display":"flex"}}]}]`,
|
|
196
|
+
fileName: '生成个人中心页面操作步骤.json'
|
|
197
|
+
})}
|
|
198
|
+
|
|
199
|
+
注意:
|
|
200
|
+
- 用户信息布局组件父组件为布局组件,且仅承担布局功能,不承担样式、点击功能,我们添加ignore标记来优化。
|
|
201
|
+
</assistant_response>
|
|
202
|
+
</example>
|
|
203
|
+
|
|
204
|
+
<example>
|
|
205
|
+
<user_query>添加一个一行三列的导航</user_query>
|
|
206
|
+
<assistant_response>
|
|
207
|
+
好的,一行三列的导航考察的是我们布局的关键知识,一行三列,就是均分布局,均分我们一般选择使用flex布局。
|
|
208
|
+
所以提供一个flex容器,确定子组件的宽度,并将内容平铺上去。
|
|
209
|
+
|
|
210
|
+
首先,必须根据页面内容设置一个合适的页面的高度。
|
|
211
|
+
其次,必须对页面布局设置一个合理的布局。
|
|
212
|
+
|
|
213
|
+
${fileFormat({
|
|
214
|
+
content: `["_root_",":root","setLayout",{"height": 360}]
|
|
215
|
+
["_root_",":root","doConfig",{"path":"root/标题","value":"一行三列的导航"}]
|
|
216
|
+
["_root_",":root","doConfig",{"path":"root/布局","value":{"display":"flex","flexDirection":"column","alignItems":"center"}}]
|
|
217
|
+
["_root_","_rootSlot_","addChild",{"title":"Flex容器","ns":"some.container","comId":"u_iiusd7","layout":{"width":"100%","height":200,"marginLeft":8,"marginRight":8},"configs":[{"path":"常规/布局","value":{"display":"flex","flexDirection":"row","justifyContent":"space-between","alignItems":"center","flexWrap":"wrap"}}]}]
|
|
218
|
+
["u_iiusd7","content","addChild",{"title":"导航1","ns":"some.icon","comId":"u_icon1","layout":{"width":120,"height":120,"marginTop":8},"configs":[{"path":"样式/文本","style":{"background":"#0000FF"}}]}]`,
|
|
219
|
+
fileName: '一行三列导航操作步骤.json'
|
|
220
|
+
})}
|
|
221
|
+
|
|
222
|
+
注意:
|
|
223
|
+
- 这个Flex容器是根组件的直接子组件,所以不允许添加ignore标记。
|
|
224
|
+
</assistant_response>
|
|
225
|
+
</example>`
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
const prompts = {
|
|
229
|
+
systemAppendPrompts: systemAppendPrompts(),
|
|
230
|
+
prdExamplesPrompts: prdExamplesPrompts(),
|
|
231
|
+
generatePageActionExamplesPrompts: generatePageActionExamplesPrompts(),
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
export { prompts }
|
|
235
|
+
|