@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,145 @@
|
|
|
1
|
+
export class ComponentsManager {
|
|
2
|
+
private static isLoaded = false
|
|
3
|
+
private static aiComponentMap = new Map<string, any>()
|
|
4
|
+
private static namespaceAbbrevMap = new Map<string, string>() // 缩写 -> 完整namespace
|
|
5
|
+
private static abbreviationMap = new Map<string, string>() // 完整namespace -> 缩写
|
|
6
|
+
|
|
7
|
+
private static init = () => {
|
|
8
|
+
if (this.isLoaded) {
|
|
9
|
+
return
|
|
10
|
+
}
|
|
11
|
+
if (!window.__comlibs_edit_) {
|
|
12
|
+
return
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const forEachComponent = (com: any, callback: (com: any) => void) => {
|
|
16
|
+
if (com?.namespace) {
|
|
17
|
+
callback?.(com)
|
|
18
|
+
}
|
|
19
|
+
if (Array.isArray(com?.comAray)) {
|
|
20
|
+
com?.comAray.forEach((child: any) => {
|
|
21
|
+
forEachComponent(child, callback)
|
|
22
|
+
})
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
window.__comlibs_edit_.forEach((comlib: any) => {
|
|
27
|
+
forEachComponent(comlib, (com) => {
|
|
28
|
+
if (com?.ai) {
|
|
29
|
+
this.aiComponentMap.set(com.namespace, {
|
|
30
|
+
...com.ai,
|
|
31
|
+
all: com
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
const abbreviation = com.namespace
|
|
35
|
+
.replace('mybricks.normal-pc.antd5.', 'pc.')
|
|
36
|
+
.replace('mybricks.normal-pc.', 'pc.')
|
|
37
|
+
.replace('mybricks.harmony.', 'mb.')
|
|
38
|
+
.replace('mybricks.taro.', 'mb.')
|
|
39
|
+
|
|
40
|
+
// 收集缩写映射关系
|
|
41
|
+
if (abbreviation !== com.namespace) {
|
|
42
|
+
this.namespaceAbbrevMap.set(abbreviation, com.namespace)
|
|
43
|
+
this.abbreviationMap.set(com.namespace, abbreviation)
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
})
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
this.isLoaded = true
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
static getRequireComponents = (ns: string): any[] => {
|
|
53
|
+
this.init()
|
|
54
|
+
|
|
55
|
+
let res: any[] = []
|
|
56
|
+
if (this.aiComponentMap.has(ns)) {
|
|
57
|
+
const ai = this.aiComponentMap.get(ns)
|
|
58
|
+
if (Array.isArray(ai.requires)) {
|
|
59
|
+
res = res.concat(ai.requires)
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return res
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* 判断是否为布局组件(asLayout)
|
|
67
|
+
*/
|
|
68
|
+
static isLayoutComponent = (namespace: string): boolean => {
|
|
69
|
+
this.init()
|
|
70
|
+
const ai = this.aiComponentMap.get(this.getFullNamespace(namespace))
|
|
71
|
+
return !!ai?.asLayout
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* 获取所有布局组件的 namespace 缩写数组
|
|
76
|
+
*/
|
|
77
|
+
static getLayoutComponentsAbbreviationNs = (): string[] => {
|
|
78
|
+
this.init()
|
|
79
|
+
const res: string[] = []
|
|
80
|
+
|
|
81
|
+
this.aiComponentMap.forEach((ai, namespace) => {
|
|
82
|
+
if (ai?.asLayout) {
|
|
83
|
+
res.push(this.getAbbreviation(namespace))
|
|
84
|
+
}
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
return res
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* 根据完整namespace获取缩写
|
|
92
|
+
* @param namespace 完整的namespace
|
|
93
|
+
* @returns 缩写namespace,如果没有缩写则返回原namespace
|
|
94
|
+
*/
|
|
95
|
+
static getAbbreviation = (namespace: string): string => {
|
|
96
|
+
this.init()
|
|
97
|
+
return this.abbreviationMap.get(namespace) || namespace
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* 根据缩写获取完整namespace
|
|
102
|
+
* @param abbreviation 缩写
|
|
103
|
+
* @returns 完整namespace,如果没有对应的完整namespace则返回原缩写
|
|
104
|
+
*/
|
|
105
|
+
static getFullNamespace = (abbreviation: string): string => {
|
|
106
|
+
this.init()
|
|
107
|
+
return this.namespaceAbbrevMap.get(abbreviation) || abbreviation
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* 重置加载状态(用于测试或重新初始化)
|
|
112
|
+
*/
|
|
113
|
+
static reset = () => {
|
|
114
|
+
this.isLoaded = false
|
|
115
|
+
this.aiComponentMap.clear()
|
|
116
|
+
this.namespaceAbbrevMap.clear()
|
|
117
|
+
this.abbreviationMap.clear()
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
static getAiComponent(namespace: string) {
|
|
121
|
+
this.init()
|
|
122
|
+
return this.aiComponentMap.get(namespace)
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* 获取所有可用的AI组件列表
|
|
127
|
+
* @returns 组件列表,包含 namespace, name, abbreviation, description
|
|
128
|
+
*/
|
|
129
|
+
static getAllComponents(): Array<{ namespace: string; name: string; abbreviation: string; description: string }> {
|
|
130
|
+
this.init()
|
|
131
|
+
const components: Array<{ namespace: string; name: string; abbreviation: string; description: string }> = []
|
|
132
|
+
|
|
133
|
+
this.aiComponentMap.forEach((ai, namespace) => {
|
|
134
|
+
components.push({
|
|
135
|
+
namespace: namespace,
|
|
136
|
+
name: ai.all?.title || namespace,
|
|
137
|
+
abbreviation: this.getAbbreviation(namespace),
|
|
138
|
+
description: ai.all?.description || ''
|
|
139
|
+
})
|
|
140
|
+
})
|
|
141
|
+
|
|
142
|
+
return components
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { OutlineInfoManager, type OutlineNode, type SlotInfo } from './outline-info';
|
|
2
|
+
import { ComponentsManager } from './components-manager';
|
|
3
|
+
import { FocusInfo } from '../types';
|
|
4
|
+
|
|
5
|
+
class PageHierarchyGenerator {
|
|
6
|
+
static generate(outlineInfo: OutlineNode, currentFocus: FocusInfo): string {
|
|
7
|
+
const processedData = currentFocus.type === 'uiCom'
|
|
8
|
+
? this.filterToFocusedComponent(outlineInfo, currentFocus.comId!)
|
|
9
|
+
: outlineInfo;
|
|
10
|
+
|
|
11
|
+
return this.generateTreeDescription(processedData as OutlineNode, {
|
|
12
|
+
pageId: currentFocus.pageId,
|
|
13
|
+
comId: currentFocus.comId,
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
private static containsComponent(data: OutlineNode, targetId: string): boolean {
|
|
18
|
+
if (!data) return false;
|
|
19
|
+
if (data.id === targetId) return true;
|
|
20
|
+
|
|
21
|
+
if (data.slots && Array.isArray(data.slots)) {
|
|
22
|
+
return data.slots.some(slot => {
|
|
23
|
+
if (slot.components && Array.isArray(slot.components)) {
|
|
24
|
+
return slot.components.some(component => this.containsComponent(component, targetId));
|
|
25
|
+
}
|
|
26
|
+
return false;
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
private static hasChildren(data: OutlineNode): boolean {
|
|
33
|
+
if (!data?.slots || !Array.isArray(data.slots)) {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
return data.slots.some(slot => {
|
|
37
|
+
return slot.components && Array.isArray(slot.components) && slot.components.length > 0;
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
private static filterToFocusedComponent(data: OutlineNode, targetId: string): OutlineNode | null {
|
|
42
|
+
if (!data) return null;
|
|
43
|
+
|
|
44
|
+
if (data.id === targetId) {
|
|
45
|
+
return data;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (data.slots && Array.isArray(data.slots)) {
|
|
49
|
+
const filteredSlots = data.slots.map(slot => {
|
|
50
|
+
if (slot.components && Array.isArray(slot.components)) {
|
|
51
|
+
const filteredComponents = slot.components.map(component => {
|
|
52
|
+
if (this.containsComponent(component, targetId)) {
|
|
53
|
+
return this.filterToFocusedComponent(component, targetId);
|
|
54
|
+
} else {
|
|
55
|
+
const hasChildComponents = this.hasChildren(component);
|
|
56
|
+
return {
|
|
57
|
+
...component,
|
|
58
|
+
slots: undefined,
|
|
59
|
+
_hasCollapsedChildren: hasChildComponents
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
}).filter(Boolean) as OutlineNode[];
|
|
63
|
+
|
|
64
|
+
return filteredComponents.length > 0 ? { ...slot, components: filteredComponents } : null;
|
|
65
|
+
}
|
|
66
|
+
return null;
|
|
67
|
+
}).filter(Boolean) as SlotInfo[];
|
|
68
|
+
|
|
69
|
+
if (filteredSlots.length > 0) {
|
|
70
|
+
return { ...data, slots: filteredSlots };
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
private static generateTreeDescription(data: OutlineNode | OutlineNode[], focusInfo: FocusInfo, level = 0): string {
|
|
77
|
+
const indent = ' '.repeat(level);
|
|
78
|
+
let result = '';
|
|
79
|
+
|
|
80
|
+
if (!data) {
|
|
81
|
+
return '无内容,代表内容为空';
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (Array.isArray(data)) {
|
|
85
|
+
if (data.length === 0) {
|
|
86
|
+
return '无内容,代表内容为空';
|
|
87
|
+
}
|
|
88
|
+
data.forEach(item => {
|
|
89
|
+
result += this.generateTreeDescription(item, focusInfo, level);
|
|
90
|
+
});
|
|
91
|
+
return result;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (data.asRoot) {
|
|
95
|
+
if (Array.isArray(data.slots?.[0]?.components)) {
|
|
96
|
+
data.slots?.[0]?.components.forEach(component => {
|
|
97
|
+
result += this.generateTreeDescription(component, focusInfo, level);
|
|
98
|
+
});
|
|
99
|
+
return result;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (data.title) {
|
|
104
|
+
const namespace = data.def?.namespace;
|
|
105
|
+
const isFocused = data.id === focusInfo.comId ||
|
|
106
|
+
data.id === focusInfo.pageId;
|
|
107
|
+
const focusMarker = isFocused ? ' 【当前聚焦】' : '';
|
|
108
|
+
const collapsedMarker = data._hasCollapsedChildren ? ' 【子组件已折叠】' : '';
|
|
109
|
+
|
|
110
|
+
result += `${indent}- ${data.title}[id=${data.id}]${namespace ? `(${ComponentsManager.getAbbreviation(namespace)})` : ''}${focusMarker}${collapsedMarker}\n`;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (data.slots && Array.isArray(data.slots)) {
|
|
114
|
+
data.slots.forEach(slot => {
|
|
115
|
+
if (slot.components && Array.isArray(slot.components)) {
|
|
116
|
+
slot.components.forEach(component => {
|
|
117
|
+
result += this.generateTreeDescription(component, focusInfo, level + 1);
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return result;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
class FocusDescriptionGenerator {
|
|
128
|
+
static generate(currentFocus: FocusInfo): string {
|
|
129
|
+
const { pageId, comId, title, type } = currentFocus ?? {};
|
|
130
|
+
|
|
131
|
+
if (!currentFocus || (!currentFocus.pageId && !currentFocus.comId)) {
|
|
132
|
+
return '当前没有聚焦到任何页面或组件。';
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
let focusDesc = '';
|
|
136
|
+
|
|
137
|
+
switch (type) {
|
|
138
|
+
case 'uiCom':
|
|
139
|
+
focusDesc = `组件(title=${title},组件id=${comId})`;
|
|
140
|
+
break;
|
|
141
|
+
case 'page':
|
|
142
|
+
case 'section':
|
|
143
|
+
focusDesc = `页面(title=${title},页面id=${pageId})`;
|
|
144
|
+
break;
|
|
145
|
+
default:
|
|
146
|
+
focusDesc = `未知类型(title=${title})`;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
return `当前已聚焦到${focusDesc}中,后续用户的提问,关于"这个"、"此"、"整体",甚至不提主语,都是指代此元素及其子组件内容。`;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export class FocusOutlineInfoManager extends OutlineInfoManager {
|
|
154
|
+
private focusInfo: FocusInfo;
|
|
155
|
+
private focusPageOutlineInfo: OutlineNode | null;
|
|
156
|
+
|
|
157
|
+
constructor({ api, focusInfo }: { api: any, focusInfo: FocusInfo }) {
|
|
158
|
+
super({ api });
|
|
159
|
+
this.focusInfo = { ...focusInfo };
|
|
160
|
+
this.focusPageOutlineInfo = focusInfo?.pageId ? this.getPageOutline(focusInfo.pageId) : null;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
getFocusPageOutline(): OutlineNode | null {
|
|
164
|
+
return this.focusPageOutlineInfo;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
generateFocusHierarchy(): string {
|
|
168
|
+
if (!this.focusPageOutlineInfo || !this.focusInfo?.pageId) {
|
|
169
|
+
return '无内容,代表内容为空';
|
|
170
|
+
}
|
|
171
|
+
return PageHierarchyGenerator.generate(this.focusPageOutlineInfo, this.focusInfo);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
generateFocusDescription(): string {
|
|
175
|
+
return FocusDescriptionGenerator.generate(this.focusInfo);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|