@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.
Files changed (93) hide show
  1. package/package.json +7 -2
  2. package/src/agents/app.ts +188 -60
  3. package/src/agents/common.ts +428 -68
  4. package/src/agents/custom.ts +14 -0
  5. package/src/agents/index.ts +31 -1
  6. package/src/agents/knowledges/README.md +614 -0
  7. package/src/agents/knowledges/SUMMARY.md +527 -0
  8. package/src/agents/knowledges/index.ts +8 -0
  9. package/src/agents/knowledges/knowledge-base.ts +565 -0
  10. package/src/agents/knowledges/knowledge-node.ts +266 -0
  11. package/src/agents/knowledges/types.ts +208 -0
  12. package/src/agents/utils/config.ts +427 -0
  13. package/src/agents/workspace/coding-manager.ts +31 -0
  14. package/src/agents/workspace/components-manager.ts +124 -0
  15. package/src/agents/workspace/outline-focus.ts +188 -0
  16. package/src/agents/workspace/outline-info.ts +520 -0
  17. package/src/agents/workspace/page-tree-generator.ts +83 -0
  18. package/src/agents/workspace/workspace.ts +319 -0
  19. package/src/agents/workspace-by-knowledges/MIGRATION.md +568 -0
  20. package/src/agents/workspace-by-knowledges/README.md +521 -0
  21. package/src/agents/workspace-by-knowledges/index.ts +11 -0
  22. package/src/agents/workspace-by-knowledges/providers/component-docs-provider.ts +92 -0
  23. package/src/agents/workspace-by-knowledges/providers/focus-info-provider.ts +131 -0
  24. package/src/agents/workspace-by-knowledges/providers/index.ts +8 -0
  25. package/src/agents/workspace-by-knowledges/providers/project-info-provider.ts +151 -0
  26. package/src/agents/workspace-by-knowledges/test.ts +240 -0
  27. package/src/agents/workspace-by-knowledges/types.ts +56 -0
  28. package/src/agents/workspace-by-knowledges/utils/components-manager.ts +145 -0
  29. package/src/agents/workspace-by-knowledges/utils/index.ts +8 -0
  30. package/src/agents/workspace-by-knowledges/utils/outline-focus.ts +178 -0
  31. package/src/agents/workspace-by-knowledges/utils/outline-info.ts +521 -0
  32. package/src/agents/workspace-by-knowledges/workspace.ts +166 -0
  33. package/src/api/cloud-components.ts +129 -0
  34. package/src/api-record-replay/README.md +187 -0
  35. package/src/api-record-replay/index.ts +11 -0
  36. package/src/api-record-replay/manager.ts +168 -0
  37. package/src/api-record-replay/recorder.ts +117 -0
  38. package/src/api-record-replay/replayer.ts +148 -0
  39. package/src/components/attachments/index.less +117 -0
  40. package/src/components/attachments/index.tsx +136 -0
  41. package/src/components/icons/index.tsx +21 -1
  42. package/src/components/index.less +34 -0
  43. package/src/components/mention/index.less +23 -0
  44. package/src/components/mention/index.tsx +19 -0
  45. package/src/components/messages/index.less +444 -237
  46. package/src/components/messages/index.tsx +371 -88
  47. package/src/components/sender/index.less +203 -0
  48. package/src/components/sender/index.tsx +298 -0
  49. package/src/components/types.ts +31 -0
  50. package/src/constants/index.ts +8 -0
  51. package/src/context/RequestStatusTracker.ts +50 -0
  52. package/src/context/index.ts +68 -6
  53. package/src/{types.d.ts → global.d.ts} +40 -5
  54. package/src/index.tsx +212 -32
  55. package/src/preset/agents.ts +380 -0
  56. package/src/preset/createTemplates.ts +25 -0
  57. package/src/preset/index.ts +12 -0
  58. package/src/preset/prompts.ts +235 -0
  59. package/src/preset/requestAsStream.ts +246 -0
  60. package/src/preset/user.ts +6 -0
  61. package/src/startView/components/header/header.less +17 -0
  62. package/src/startView/components/header/header.tsx +15 -0
  63. package/src/startView/components/index.ts +1 -0
  64. package/src/startView/index.less +22 -204
  65. package/src/startView/index.tsx +35 -203
  66. package/src/tools/analyze-and-expand-prd.ts +192 -86
  67. package/src/tools/analyze-requirement-and-components.ts +589 -0
  68. package/src/tools/answer.ts +59 -0
  69. package/src/tools/build-process.ts +1174 -0
  70. package/src/tools/coding-subagent-as-tool.ts +119 -0
  71. package/src/tools/generate-ui-content.ts +1083 -0
  72. package/src/tools/index.ts +22 -19
  73. package/src/tools/open-dsl.ts +69 -0
  74. package/src/tools/refactor-ui-content.ts +801 -0
  75. package/src/tools/utils.ts +880 -28
  76. package/src/types/index.ts +4 -0
  77. package/src/view/components/header/header.less +36 -2
  78. package/src/view/components/header/header.tsx +47 -2
  79. package/src/view/components/index.ts +0 -2
  80. package/src/view/index.tsx +158 -8
  81. package/src/tools/answer-user.ts +0 -35
  82. package/src/tools/focus-element.ts +0 -47
  83. package/src/tools/generate-page.ts +0 -750
  84. package/src/tools/get-component-info-by-ids.ts +0 -166
  85. package/src/tools/get-component-info.ts +0 -53
  86. package/src/tools/get-components-doc-and-prd.ts +0 -137
  87. package/src/tools/get-focus-mybricks-dsl.ts +0 -26
  88. package/src/tools/get-mybricks-dsl.ts +0 -73
  89. package/src/tools/modify-component.ts +0 -385
  90. package/src/view/components/messages/messages.less +0 -228
  91. package/src/view/components/messages/messages.tsx +0 -172
  92. package/src/view/components/sender/sender.less +0 -44
  93. package/src/view/components/sender/sender.tsx +0 -62
@@ -1,111 +1,471 @@
1
1
  import { context } from './../context';
2
- import { MYBRICKS_TOOLS, MyBricksHelper } from "./../tools"
2
+ import { MYBRICKS_TOOLS } from "./../tools"
3
3
 
4
+ import { WorkSpace } from './workspace/workspace'
5
+ import { FocusOutlineInfoManager, FocusInfo } from './workspace/outline-focus'
6
+
7
+ import { ComponentsManager } from './workspace/components-manager'
8
+ import { getAgentConfigs } from './utils/config'
9
+
10
+ import { CodingManager } from './workspace/coding-manager'
11
+
12
+ const getFocusInfo = (focus: any) => {
13
+ const focusInfo: FocusInfo = {
14
+ pageId: focus?.pageId,
15
+ comId: focus?.comId,
16
+ title: focus?.title,
17
+ type: focus?.type,
18
+ focusArea: focus?.focusArea
19
+ };
20
+
21
+ if (focus.type === "logicCom") {
22
+ focusInfo.pageId = focus.rootFrameId;
23
+ focusInfo.diagramId = focus.diagramId;
24
+ }
25
+
26
+ return focusInfo;
27
+ }
28
+
29
+ const getTargetId = (focus: FocusInfo) => {
30
+ if (['uiCom', 'logicCom'].includes(focus.type!)) {
31
+ return focus.comId
32
+ }
33
+
34
+ return focus.pageId;
35
+ }
4
36
 
5
37
  export const requestCommonAgent = (params: any) => {
6
38
 
7
39
  return new Promise((resolve, reject) => {
8
- const prompts = context.prompts;
40
+ // agents 配置中获取提示词配置,优先使用参数传入的,否则使用 context 中的
41
+ const agents = params.agents || context.agents;
42
+ const agentConfig = getAgentConfigs(agents, 'page');
43
+
44
+ const currentFocus = params.focus || context.currentFocus;
45
+ const focusInfo = getFocusInfo(currentFocus);
46
+
47
+ const targetType = focusInfo.type;
48
+ const targetId = getTargetId(focusInfo);
49
+ const targetPageId = focusInfo.pageId;
50
+
51
+ if (!targetPageId) {
52
+ return reject('缺少聚焦页面id')
53
+ }
54
+
55
+ const outlineInfoManager = new FocusOutlineInfoManager({
56
+ api: context.api,
57
+ focusInfo
58
+ });
59
+
60
+ const componentIdToTitleMap = targetPageId
61
+ ? outlineInfoManager.getComponentIdToTitleMap(targetPageId)
62
+ : new Map<string, string>();
63
+
64
+ const workspace = new WorkSpace({ currentFocus: focusInfo } as any, {
65
+ getAllPageInfo() {
66
+ return (context.api.global.api as any).getAllPageInfo()
67
+ },
68
+ getComponentDoc(namespace: string) {
69
+ return (context.api?.global?.api?.getComEditorPrompts ?? context.api?.uiCom?.api?.getComEditorPrompts)?.(namespace)
70
+ }
71
+ } as any, outlineInfoManager)
72
+
73
+ const codingManager = new CodingManager({
74
+ pageId: targetPageId,
75
+ attachments: params.attachments,
76
+ getJsxById: (id: string) => workspace.getJsxById(id),
77
+ });
78
+
79
+ let onProgress = params.onProgress;
80
+
81
+ const historyFocusDesc = generateHistoryFocusDescription(focusInfo);
82
+ const focusEleDesc = generateFocusTargetDescription(focusInfo);
83
+ if (targetType === "uiCom") {
84
+ onProgress = context.api.uiCom.api.getComOnProcess(targetId)?.onProgress
85
+ } else if (targetType === "page") {
86
+ onProgress = context.api.page.api.getPageOnProcess(targetId)?.onProgress
87
+ }
88
+
89
+ onProgress?.('start')
90
+
91
+ const hasAttachment = typeof params?.message !== 'string';
92
+
93
+ // workspace.openDocument('u_qLciw]')
9
94
 
10
- const targetId = context.currentFocus?.type === 'uiCom' ? context.currentFocus?.comId : context.currentFocus?.pageId
95
+ // workspace.openDocument('u_ADKKC')
96
+
97
+ // workspace.openDocument('u_ZJ_bn')
98
+
99
+ // workspace.openDocument('u_ADKKC')
100
+ // workspace.openDocument('u_XZL9q')
101
+
102
+ // workspace.openDocument('u_k_1dW')
103
+ // workspace.openDocument('u_ADKKC')
104
+
105
+ // // 页面
106
+ // workspace.openDocument('u_yjFHf')
107
+ // workspace.openDocument('u_tycgh')
108
+
109
+ // // 页面 + 组件
110
+ // workspace.openDocument('u_yjFHf')
111
+ // workspace.openDocument('u_ADKKC')
112
+
113
+ // return console.log(workspace.getProjectStruct())
114
+
115
+ // try {
116
+ // workspace.openDocument(targetPageId)
117
+
118
+ // return console.log(workspace.getProjectStruct())
119
+
120
+ // workspace.openComponentDoc('mybricks.normal-pc.antd5.form-container')
121
+ // return console.log(workspace.getComponentsDocs());
122
+ // } catch (error) {
123
+ // console.error(error)
124
+ // }
125
+ // return
11
126
 
12
- params?.onProgress?.('start')
13
127
 
14
128
  context.rxai.requestAI({
15
129
  ...params,
16
130
  message: params?.message,
17
- key: targetId,
131
+ blockId: targetId,
132
+ // enableLog: true,
18
133
  emits: {
19
134
  write: () => { },
20
135
  complete: () => {
21
136
  resolve('complete')
22
- params?.onProgress?.("complete");
137
+ onProgress?.("complete");
138
+ console.log('common complete')
23
139
  },
24
140
  error: () => {
25
141
  reject('error')
26
- params?.onProgress?.("error");
142
+ onProgress?.("error");
143
+ console.log('common error')
27
144
  },
28
145
  cancel: () => {},
29
146
  },
30
147
  tools: [
31
- MYBRICKS_TOOLS.GetComponentsDocAndPrd({
32
- allowComponents: context.api?.global?.api?.getAllComDefPrompts?.(),
33
- examples: prompts.prdExamplesPrompts,
34
- canvasWidth: prompts.canvasWidth,
35
- queryComponentsDocsByNamespaces: (namespaces) => {
36
- return namespaces.reduce((acc, cur) => {
37
- return acc + '\n' + context.api?.uiCom?.api?.getComEditorPrompts?.(cur.namespace)
38
- }, '')
39
- }
148
+ MYBRICKS_TOOLS.OpenDsl({
149
+ onOpen(id) {
150
+ workspace.openDocument(id)
151
+ },
40
152
  }),
41
- MYBRICKS_TOOLS.GeneratePage({
42
- getFocusRootComponentDoc: () => context.api?.page?.api?.getPageContainerPrompts?.(targetId) as string,
43
- getTargetId: () => targetId as string,
44
- appendPrompt: prompts.systemAppendPrompts,
45
- examples: prompts.generatePageActionExamplesPrompts,
153
+ MYBRICKS_TOOLS.AnalyzeRequirementAndComponents({
154
+ allowComponents: context.designer?.getAllComDefPrompts?.() || "",
155
+ ...agentConfig?.getToolParams(MYBRICKS_TOOLS.AnalyzeRequirementAndComponents.toolName),
156
+ onComponentDocOpen: (namespace) => {
157
+ workspace.openComponentDoc(namespace)
158
+ },
159
+ appendPrompt: agentConfig?.attentions,
160
+ deviceType: context.deviceType,
161
+ }),
162
+ MYBRICKS_TOOLS.GenerateUiContent({
163
+ getRootComponentDoc: () => context.api?.page?.api?.getPageContainerPrompts?.(targetPageId) as string,
164
+ getTargetId: () => targetPageId as string,
165
+ getRootIdByPageId(pageId: string) {
166
+ return outlineInfoManager.getPageMetaInfo(pageId)?.rootId
167
+ },
168
+ componentIdToTitleMap,
169
+ appendPrompt: agentConfig?.attentions,
170
+ ...agentConfig?.getToolParams(MYBRICKS_TOOLS.GenerateUiContent.toolName),
46
171
  onActions: (actions, status) => {
47
- context.api?.page?.api?.updatePage?.(targetId, actions, status)
172
+ return context.designer?.updatePage?.(targetPageId, actions, status)
48
173
  },
49
174
  onClearPage: () => {
50
- context.api?.page?.api?.clearPageContent?.(targetId)
51
- }
175
+ context.api?.page?.api?.clearPageContent?.(targetPageId)
176
+ },
177
+ onAddCodingBlock(com) {
178
+ codingManager.addCodingCom(com);
179
+ },
52
180
  }),
53
- // MYBRICKS_TOOLS.GetMybricksDSL({
54
- // getContext: (id, type) => {
55
- // if (type === 'page') {
56
- // return api?.page?.api?.getPageDSLPrompts?.(id)?.toDSL?.()?.replaceAll(`slots.${id}`, 'canvas') as string
57
- // }
58
- // return api?.uiCom?.api?.getComDSLPrompts?.(id) as string
59
- // },
60
- // }),
61
- MYBRICKS_TOOLS.GetFocusMybricksDSL({
62
- id: targetId as string,
63
- getFocusContext() {
64
- if (context.currentFocus?.type === 'page') {
65
- return context.api?.page?.api?.getPageDSLPrompts?.(targetId)?.toDSL?.()?.replaceAll(`slots.${targetId}`, 'canvas') as string
181
+ // MYBRICKS_TOOLS.GenerateUiContent({
182
+ // getRootComponentDoc: () => context.api?.page?.api?.getPageContainerPrompts?.(targetPageId) as string,
183
+ // getTargetId: () => targetPageId as string,
184
+ // getRootIdByPageId(pageId: string) {
185
+ // return outlineInfoManager.getPageMetaInfo(pageId)?.rootId
186
+ // },
187
+ // componentIdToTitleMap,
188
+ // appendPrompt: `<对于当前搭建有以下特殊上下文>
189
+ // <搭建画布信息>
190
+ // 当前正在搭建各类智能穿戴设备的表盘,画布的宽度和高度我们限制为466*466,所有内容必须使用*绝对定位*布局绘制到画布上。
191
+
192
+ // 注意:根组件的布局必须设置position=absolute(绝对定位)和具体的宽高。
193
+ // </搭建画布信息>
194
+ // </对于当前搭建有以下特殊上下文>`,
195
+ // examples: `<example>
196
+ // <user_query>搭建一个科技风表盘</user_query>
197
+ // <assistant_response>
198
+ // 好的,我们来实现一个科技风的表盘,搭建过程如下:
199
+ // 1. 首先,必须配置合理的表盘宽度和高度、标题、布局以及样式;
200
+ // 2. 其次搭建各类元素,将各类表盘元素放置到合适的位置;
201
+
202
+ // ${fileFormat({
203
+ // content: `["_root_",":root","setLayout",{"height": 466, "width": "466"}]
204
+ // ["_root_",":root","doConfig",{"path":"root/标题","value":"科技风表盘"}]
205
+ // ["_root_",":root","doConfig",{"path":"root/布局","value":{"position": "absolute"}}]
206
+ // ["_root_",":root","doConfig",{"path":"root/样式","value":{"background":"linear-gradient(135deg, #0c0c0c 0%, #1a1a2e 50%, #16213e 100%)"}}]
207
+ // ["_root_","_rootSlot_","addChild",{"title":"电池图标显示","ns":"somelib.battery","comId":"u_digital_time","layout":{"position":"absolute","top":10,"left":300},"configs":[]}]
208
+ // `,
209
+ // fileName: '生成科技风表盘操作步骤.json'
210
+ // })}
211
+
212
+ // 注意:
213
+ // - 表盘所有元素必须由自由布局绘制而成
214
+ // </assistant_response>
215
+ // </example>`,
216
+ // onActions: (actions, status) => {
217
+ // context.api?.page?.api?.updatePage?.(targetPageId, actions, status)
218
+ // },
219
+ // onClearPage: () => {
220
+ // context.api?.page?.api?.clearPageContent?.(targetPageId)
221
+ // }
222
+ // }),
223
+ MYBRICKS_TOOLS.RefactorUiContent({
224
+ onActions: (actions, status, type) => {
225
+ if (!status) {
226
+ return
227
+ }
228
+
229
+ // 只有聚焦到组件上,且第一个操作ID是组件ID,且父组件不为页面ID,才会触发组件级更新
230
+ if (targetType === 'uiCom' && targetId && type === 'uiCom') {
231
+ const parentId = workspace.focusPageOutlineInfo
232
+ ? outlineInfoManager.findParentNodeByComId(
233
+ workspace.focusPageOutlineInfo,
234
+ targetId as string
235
+ )?.id
236
+ : undefined;
237
+
238
+ if (parentId && parentId !== targetPageId) {
239
+ return context.designer?.updateUiCom?.(parentId, actions, status)
240
+ }
66
241
  }
67
- return context.api?.uiCom?.api?.getComDSLPrompts?.(targetId) as string
242
+
243
+ return context.designer?.updatePage?.(targetPageId, actions, status)
68
244
  },
69
- }),
70
- MYBRICKS_TOOLS.GetComponentsInfoByIds({
71
- getPageJson(id) {
72
- return context.api?.page?.api?.getOutlineInfo(id)
245
+ componentIdToTitleMap,
246
+ appendPrompt: agentConfig?.attentions,
247
+ getRootComponentDoc: () => context.api?.page?.api?.getPageContainerPrompts?.(targetPageId) as string,
248
+ getTargetId: () => targetPageId as string,
249
+ getFocusElementHasChildren() {
250
+ if (!['page', 'logicCom', 'section'].includes(currentFocus?.type) && targetId) {
251
+ const json = outlineInfoManager.getUiComOutline(targetId)
252
+ if (!json.slots || (Array.isArray(json.slots) && json.slots.length === 0)) {
253
+ return false
254
+ }
255
+ }
256
+ return true
73
257
  },
74
- getComInfo(namespace) {
75
- return context.api?.uiCom?.api?.getComEditorPrompts?.(namespace)
258
+ getFocusElementAiRole() {
259
+ if (focusInfo?.type === "uiCom") {
260
+ const comInfo = context.api.uiCom.api.getOutlineInfo(focusInfo.comId);
261
+ const aiComponent = ComponentsManager.getAiComponent(comInfo.def.namespace);
262
+ return aiComponent?.prompts?.aiRole;
263
+ }
264
+ return null
265
+ },
266
+ getComIds() {
267
+ const comIds: string[] = [];
268
+
269
+ outlineInfoManager.getComponentIdToTitleMap(targetPageId).forEach((value, key) => {
270
+ comIds.push(key);
271
+ })
272
+
273
+ return comIds;
274
+ }
275
+ }),
276
+ MYBRICKS_TOOLS.Answer({}),
277
+ MYBRICKS_TOOLS.CodingSubagentAsTool({
278
+ codingManager,
279
+ onStart: () => {
280
+ context.designer?.updatePage?.(targetPageId, [], 'start')
76
281
  },
77
- getComJson(id) {
78
- return context.api?.uiCom?.api?.getOutlineInfo(id)
282
+ onComplete: () => {
283
+ context.designer?.updatePage?.(targetPageId, [], 'complete')
79
284
  },
285
+ onError: () => {
286
+ context.designer?.updatePage?.(targetPageId, [], 'complete')
287
+ },
80
288
  }),
81
- // MYBRICKS_TOOLS.GetComponentInfo({
82
- // getComInfo(id) {
83
- // return context.api?.uiCom?.api?.getComPrompts?.(id)?.replace(/当前组件的情况/g, `组件${id}的信息`) as string
84
- // },
85
- // }),
86
- MYBRICKS_TOOLS.ModifyComponent({
87
- onActions: (id, actions) => {
88
- context.api?.uiCom?.api?.updateCom?.(id, actions)
89
- }
289
+ MYBRICKS_TOOLS.BuildProcess({
290
+ // getComId: () => focusInfo.comId,
291
+ getPageId: () => focusInfo.pageId,
292
+ getComponentOutlineInfo: () => {
293
+ const { type, comId } = focusInfo
294
+ if (type === "uiCom") {
295
+ return {
296
+ type,
297
+ outlineInfo: context.api?.uiCom?.api?.getOutlineInfo(comId)
298
+ }
299
+ } else if (type === "logicCom") {
300
+ return {
301
+ type,
302
+ outlineInfo: context.api?.logicCom?.api?.getOutlineInfo(comId)
303
+ }
304
+ }
305
+ },
306
+ getPageOutlineInfo: () => context.api?.page?.api?.getOutlineInfo(focusInfo.pageId),
307
+ getAllPageInfo() {
308
+ return context.api?.global?.api?.getAllPageInfo()
309
+ },
310
+ createDiagram: (...args: any) => {
311
+ // console.log("[createDiagram - args]", args)
312
+ return context.designer?.createDiagram?.(...args)
313
+ },
314
+ updateDiagram: (...args: any) => {
315
+ // console.log("[updateDiagram - args]", args)
316
+ return context.designer?.updateDiagram?.(...args)
317
+ },
318
+ getDiagramInfo: (...args: any) => {
319
+ if (!args[0]) {
320
+ if (focusInfo.diagramId) {
321
+ return {
322
+ id: focusInfo.diagramId
323
+ }
324
+ }
325
+
326
+ return null
327
+ }
328
+ return context.designer?.getDiagramInfo?.(...args)
329
+ },
330
+ updatePage: (...args: any) => {
331
+ return context.designer?.updatePage?.(focusInfo.pageId, ...args)
332
+ },
333
+ updateCom: (...args: any) => {
334
+ return context.designer?.updateLogicCom?.(...args)
335
+ },
90
336
  }),
91
337
  ],
92
- presetMessages: [
93
- {
94
- role: 'user',
95
- content: `检测到聚焦位置发生变化`
96
- },
338
+ planningCheck: (tools: any[]) => {
339
+ const toolNames = tools.map(tool => tool[1]);
340
+ const resultTools = [...tools];
341
+
342
+ // 规则1: 如果 信息获取类 在最后一个,则添加一个 answer
343
+ const infoToolNames = [MYBRICKS_TOOLS.OpenDsl.toolName, MYBRICKS_TOOLS.AnalyzeRequirementAndComponents.toolName];
344
+ if (toolNames.length > 0 && infoToolNames.includes(toolNames[toolNames.length - 1])) {
345
+ resultTools.push(['node', MYBRICKS_TOOLS.Answer.toolName]);
346
+ return resultTools
347
+ }
348
+
349
+ // 规则2: 如果 生成页面 前面没有获取需求,则添加一个需求分析
350
+ const generatePageIndex = toolNames.indexOf(MYBRICKS_TOOLS.GenerateUiContent.toolName);
351
+ if (generatePageIndex > -1) {
352
+ const requirementTools = [MYBRICKS_TOOLS.AnalyzeRequirementAndComponents.toolName, MYBRICKS_TOOLS.OpenDsl.toolName];
353
+ const hasRequirement = toolNames.slice(0, generatePageIndex).some(name => requirementTools.includes(name));
354
+
355
+ if (!hasRequirement) {
356
+ resultTools.splice(generatePageIndex, 0, ['node', MYBRICKS_TOOLS.AnalyzeRequirementAndComponents.toolName]);
357
+ return resultTools
358
+ }
359
+ // 规则2b: 生成页面后添加「代码开发」步骤(由 planningCheck 注入)
360
+ const hasCodingSubagent = resultTools.some((t: any) => t[1] === MYBRICKS_TOOLS.CodingSubagentAsTool.toolName);
361
+ if (!hasCodingSubagent) {
362
+ const insertIndex = resultTools.findIndex((t: any) => t[1] === MYBRICKS_TOOLS.GenerateUiContent.toolName) + 1;
363
+ resultTools.splice(insertIndex, 0, ['node', MYBRICKS_TOOLS.CodingSubagentAsTool.toolName]);
364
+ }
365
+ }
366
+
367
+ // 规则3: 如果 修改 前面没有 open-dsl-document,则添加一个
368
+ const refactorIndex = toolNames.indexOf(MYBRICKS_TOOLS.RefactorUiContent.toolName);
369
+ if (refactorIndex > -1) {
370
+ const hasOpenDsl = toolNames.slice(0, refactorIndex).includes(MYBRICKS_TOOLS.OpenDsl.toolName);
371
+
372
+ if (!hasOpenDsl) {
373
+ resultTools.splice(refactorIndex, 0, ['node', MYBRICKS_TOOLS.OpenDsl.toolName, { ids: targetPageId }]);
374
+ return resultTools
375
+ }
376
+ }
377
+
378
+ const buildProcessIndex = toolNames.indexOf(MYBRICKS_TOOLS.BuildProcess.toolName);
379
+ if (buildProcessIndex > -1) {
380
+ // 搭建流程前需要需求分析和组件选型
381
+ const requirementTools = [MYBRICKS_TOOLS.AnalyzeRequirementAndComponents.toolName];
382
+ const hasRequirement = toolNames.slice(0, generatePageIndex).some(name => requirementTools.includes(name));
383
+
384
+ if (!hasRequirement) {
385
+ resultTools.splice(generatePageIndex, 0, ['node', MYBRICKS_TOOLS.AnalyzeRequirementAndComponents.toolName, {mode: "refactor"}]);
386
+ return resultTools
387
+ }
388
+ }
389
+
390
+ return resultTools
391
+ },
392
+ formatUserMessage: (text: string) => {
393
+ return `对于聚焦元素${focusEleDesc},用户提出的消息为:
394
+ <用户消息>
395
+ ${text}
396
+ </用户消息>`
397
+ },
398
+ presetHistoryMessages: [
97
399
  {
98
400
  role: 'assistant',
99
- content: `当前已聚焦到${context.currentFocus?.type === 'uiCom' ? `组件(id=${context.currentFocus?.comId})` : `页面(title=${context.currentFocus?.title},id=${context.currentFocus?.pageId})`}中,后续用户的提问,关于”这个“、“此”,甚至不提主语,都是指代此元素。
100
- <当前聚焦元素的内容简介>
101
- ${MyBricksHelper.getTreeDescriptionByJson(context.currentFocus?.type === 'uiCom' ? context.api?.uiCom?.api?.getOutlineInfo(context.currentFocus?.comId) : context.api?.page?.api?.getOutlineInfo(context.currentFocus?.pageId))}
102
-
103
- > 如果内容不为空,代表组件通过插槽放置有子组件,如果内容为空,则代表此组件没有任何子组件。
104
- </当前聚焦元素的内容简介>
105
- `
401
+ content: historyFocusDesc
402
+ }
403
+ ],
404
+ presetMessages: () => {
405
+ const projectStruct = workspace.getProjectStruct();
406
+ const componentsDocs = workspace.getComponentsDocs();
407
+ const hasComponentsDocs = workspace.hasComponentsDocs();
408
+
409
+ // 合并内容
410
+ let projectInfo = projectStruct;
411
+ if (hasComponentsDocs) {
412
+ projectInfo = `${projectStruct}\n\n${componentsDocs}`;
106
413
  }
107
- ]
414
+
415
+ return [
416
+ {
417
+ role: 'user',
418
+ content: `<当前项目信息>\n${projectInfo}\n</当前项目信息>`
419
+ },
420
+ {
421
+ role: 'assistant',
422
+ content: hasComponentsDocs
423
+ ? '收到,谢谢你提供的项目信息和组件文档,我会根据这些信息完成任务~'
424
+ : '收到,谢谢你提供的项目信息,我会根据这些信息完成任务~'
425
+ },
426
+ ]
427
+ },
108
428
  });
109
429
  })
430
+ }
431
+
432
+
433
+ function generateHistoryFocusDescription(currentFocus: Partial<FocusInfo> = {}) {
434
+ const { pageId, comId, title, type } = currentFocus ?? {}
435
+
436
+ // 定义聚焦元素的描述部分
437
+ let focusDesc = '';
438
+
439
+ // 判断当前聚焦元素类型
440
+ if (type === 'uiCom') {
441
+ focusDesc = `组件(title=${title},组件id=${comId})`;
442
+ } else if (type === 'page') {
443
+ focusDesc = `画布(title=${title},画布id=${pageId})`;
444
+ } else if (type === 'section') {
445
+ focusDesc = `画布(title=${title},画布id=${pageId})`;
446
+ } else if (type === "logicCom") {
447
+ focusDesc = `计算组件(title=${title},组件id=${comId})`;
448
+ }
449
+
450
+ return `对于${focusDesc}`;
451
+ }
110
452
 
453
+ function generateFocusTargetDescription(currentFocus: Partial<FocusInfo> = {}) {
454
+ const { pageId, comId, title, type, focusArea } = currentFocus ?? {}
455
+
456
+ // 定义聚焦元素的描述部分
457
+ let focusDesc = '';
458
+
459
+ // 判断当前聚焦元素类型
460
+ if (type === 'uiCom') {
461
+ focusDesc = `组件(title=${title},组件id=${comId},选中区域=${focusArea ? focusArea.selector : ":root"})`;
462
+ } else if (type === 'page') {
463
+ focusDesc = `画布(title=${title},画布id=${pageId})`;
464
+ } else if (type === 'section') {
465
+ focusDesc = `画布(title=${title},画布id=${pageId})`;
466
+ } else if (type === "logicCom") {
467
+ focusDesc = `计算组件(title=${title},组件id=${comId})`;
468
+ }
469
+
470
+ return focusDesc;
111
471
  }
@@ -0,0 +1,14 @@
1
+
2
+ import { context } from '../context'
3
+ import { AbstractAgent } from "./utils/config"
4
+
5
+ export function requestVibeCodingAgent(params: any, focus: any) {
6
+ const agent = context.agents!.find((agent) => agent instanceof AbstractAgent && agent.type === "vibeCoding");
7
+ if (agent) {
8
+ return (agent as AbstractAgent).request({
9
+ key: params.key,
10
+ params,
11
+ focus
12
+ });
13
+ }
14
+ }
@@ -1,7 +1,37 @@
1
1
  import { requestGenerateCanvasAgent } from './app'
2
2
  import { requestCommonAgent } from './common'
3
+ import { requestVibeCodingAgent } from './custom'
4
+ import { getAgentInstance } from './utils/config'
5
+ import { context } from '../context'
6
+
7
+ /**
8
+ * 统一的 agent 请求入口
9
+ * 根据 focus 类型自动选择使用自定义 agent 或默认的 requestCommonAgent
10
+ */
11
+ export const requestAgent = (params: any) => {
12
+ const type = context.currentFocus?.type;
13
+
14
+ if (context.currentFocus?.vibeCoding) {
15
+ return requestVibeCodingAgent({
16
+ ...params,
17
+ key: `${context.pluginParams.key}_${context.currentFocus!.pageId}_${context.currentFocus!.comId}`,
18
+ }, {...context.currentFocus});
19
+ }
20
+
21
+ // 检查是否有匹配的自定义 agent
22
+ const customAgent = type ? getAgentInstance(context.agents, type) : null;
23
+
24
+ if (customAgent) {
25
+ // 如果找到匹配的自定义 agent,调用其 request 方法
26
+ return customAgent.request(params);
27
+ } else {
28
+ // 否则使用默认的 requestCommonAgent
29
+ return requestCommonAgent(params);
30
+ }
31
+ }
3
32
 
4
33
  export const Agents = {
5
34
  requestGenerateCanvasAgent,
6
- requestCommonAgent
35
+ requestCommonAgent,
36
+ requestAgent
7
37
  }