@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
@@ -0,0 +1,203 @@
1
+ @import url(../index.less);
2
+
3
+ .container {
4
+ padding: 8px;
5
+
6
+ .editor {
7
+ z-index: 13;
8
+ position: relative;
9
+ background-color: #ffffff;
10
+ border: solid 1px rgba(0, 0, 0, .13);
11
+ width: 100%;
12
+ // border-radius: 20px;
13
+ border-radius: 12px;
14
+ box-shadow: 0 5px 16px -4px #00000012;
15
+ color: rgba(0, 0, 0, .9);
16
+ cursor: default;
17
+
18
+ &.noMentions {
19
+ background-color: #f7f7f7;
20
+ .inputPlaceholder {
21
+ color: rgba(0, 0, 0, .4) !important;
22
+ }
23
+ }
24
+
25
+ &:focus-within {
26
+ border-color: var(--mybricks-color-primary);
27
+ }
28
+
29
+ .mentions {
30
+ padding: 8px 8px 0 8px;
31
+ display: flex;
32
+ align-items: center;
33
+ gap: 4px;
34
+
35
+ span {
36
+ font-size: 12px;
37
+ line-height: 20px;
38
+ white-space: nowrap;
39
+ }
40
+
41
+ .focusarea {
42
+ color: var(--mybricks-color-primary);
43
+ }
44
+
45
+ .vibeCoding {
46
+ color: var(--mybricks-color-primary);
47
+ }
48
+ }
49
+
50
+ .topArea {
51
+ padding: 8px;
52
+ box-shadow: 0 .5px 0 0 rgba(0, 0, 0, .13);
53
+ }
54
+
55
+ .input {
56
+ // padding: 12px 16px 10px;
57
+ padding: 8px 8px 10px;
58
+ // line-height: 20px;
59
+ line-height: 1.5;
60
+ min-height: 60px;
61
+ position: relative;
62
+
63
+ .inputEditorContainer {
64
+ font-size: 12px;
65
+ max-height: 140px;
66
+ // scrollbar-width: none;
67
+ position: relative;
68
+ min-height: inherit;
69
+ overflow: auto;
70
+
71
+ .scroll-bar();
72
+
73
+ .inputEditor {
74
+ user-select: text;
75
+ white-space: pre-wrap;
76
+ word-break: break-word;
77
+ width: 100%;
78
+ max-height: fit-content;
79
+ min-height: inherit;
80
+ overflow: hidden;
81
+ outline: none;
82
+ cursor: text;
83
+
84
+ &[contentEditable="false"] {
85
+ cursor: default;
86
+ }
87
+ }
88
+
89
+ .inputPlaceholder {
90
+ position: absolute;
91
+ overflow: hidden;
92
+ text-overflow: ellipsis;
93
+ // top: 1px;
94
+ // left: 1px;
95
+ top: 0;
96
+ left: 0;
97
+ user-select: none;
98
+ pointer-events: none;
99
+ color: rgba(0, 0, 0, .6);
100
+ }
101
+ }
102
+ }
103
+
104
+ .editorAction {
105
+ display: flex;
106
+ justify-content: space-between;
107
+ align-items: flex-end;
108
+ padding: 0 8px;
109
+ margin-top: 2px;
110
+ margin-bottom: 8px;
111
+ position: relative;
112
+
113
+ .leftArea {
114
+ display: flex;
115
+ align-items: center;
116
+ gap: 4px;
117
+
118
+ .attachmentButton {
119
+ overflow: hidden;
120
+ display: flex;
121
+ align-items: center;
122
+ justify-content: center;
123
+ // width: 32px;
124
+ // border-radius: 20px;
125
+ // height: 32px;
126
+ width: 25px;
127
+ height: 25px;
128
+ border-radius: 50%;
129
+ cursor: pointer;
130
+
131
+ svg {
132
+ width: 18px;
133
+ height: 18px;
134
+ color: rgba(0, 0, 0, .6);
135
+ }
136
+
137
+ &:hover {
138
+ background-color: rgba(0, 0, 0, .09);
139
+ }
140
+
141
+ input {
142
+ display: none;
143
+ }
144
+ }
145
+
146
+ &.disabled {
147
+
148
+ opacity: 0.5;
149
+ .attachmentButton {
150
+ cursor: default;
151
+ &:hover {
152
+ background-color: transparent;
153
+ }
154
+ }
155
+ }
156
+ }
157
+
158
+ .rightArea {
159
+ display: flex;
160
+ align-items: center;
161
+
162
+ .sendButtonContainer {
163
+ cursor: pointer;
164
+ background-color: var(--mybricks-color-primary);
165
+ // border-radius: 12px;
166
+ // border-radius: 6px;
167
+ border-radius: 50%;
168
+ display: flex;
169
+ align-items: center;
170
+ color: rgba(255, 255, 255, .9);
171
+
172
+ .sendButton {
173
+ overflow: hidden;
174
+ display: flex;
175
+ align-items: center;
176
+ justify-content: center;
177
+ // width: 32px;
178
+ // height: 32px;
179
+ width: 25px;
180
+ height: 25px;
181
+
182
+ svg {
183
+ width: 11px;
184
+ height: 11px;
185
+ }
186
+ }
187
+
188
+ .loadingButton {
189
+ svg {
190
+ width: 11px;
191
+ height: 11px;
192
+ }
193
+ }
194
+ }
195
+
196
+ .disabled {
197
+ cursor: default;
198
+ opacity: 0.5;
199
+ }
200
+ }
201
+ }
202
+ }
203
+ }
@@ -0,0 +1,298 @@
1
+ import React, { useEffect, useRef, useState, useImperativeHandle, PropsWithoutRef, forwardRef } from "react"
2
+ import classNames from "classnames";
3
+ import { message } from "antd";
4
+ import { Attachment, Loading, Send, Code } from "../icons";
5
+ import { MentionTag } from "../mention";
6
+ import { AttachmentsList } from "../attachments";
7
+ import { Mention, Attachments } from "../types";
8
+ import css from "./index.less"
9
+
10
+ const readFileToBase64 = (file: File): Promise<string> => {
11
+ return new Promise((resolve, reject) => {
12
+ const reader = new FileReader();
13
+ reader.onload = function (event) {
14
+ if (event.target) {
15
+ const base64 = event.target.result as string;
16
+ resolve(base64);
17
+ } else {
18
+ reject(event);
19
+ }
20
+ };
21
+ reader.onerror = function (event) {
22
+ reject(event);
23
+ };
24
+ reader.readAsDataURL(file);
25
+ })
26
+ }
27
+
28
+ interface SenderProps {
29
+ onSend: (message: {
30
+ message: string;
31
+ attachments: Attachments;
32
+ mentions: Mention[];
33
+ [key: string]: any;
34
+ }) => void;
35
+ onMentionClick?: (mention: Mention) => void;
36
+ loading?: boolean;
37
+ placeholder?: string;
38
+ attachmentsPrompt?: string;
39
+ disabled?: boolean;
40
+ onBlur?: () => void;
41
+ mode?: "mention"
42
+ }
43
+
44
+ interface SenderRef {
45
+ focus: () => void;
46
+ // TODO: 目前仅展示聚焦组件且单个比较简单直接set即可,后续可通过输入框@唤起选择多个
47
+ setMentions: (mentions: Mention[]) => void;
48
+ }
49
+
50
+ const Sender = forwardRef<SenderRef, SenderProps>((props, ref) => {
51
+ const { loading, placeholder = "请输入", disabled, onMentionClick, onBlur, attachmentsPrompt, mode } = props;
52
+ const inputEditorRef = useRef<HTMLDivElement>(null);
53
+ const [isComposing, setIsComposing] = useState(false);
54
+ const [inputContent, setInputContent] = useState<string | null>(null);
55
+ const [attachments, setAttachments] = useState<Attachments>([]);
56
+ const [mentions, setMentions] = useState<Mention[]>([]);
57
+ const [vibeCoding, setVibeCoding] = useState(false);
58
+
59
+ useImperativeHandle(ref, () => {
60
+ return {
61
+ focus: () => {
62
+ inputEditorRef.current!.focus()
63
+ },
64
+ setMentions: (mentions) => {
65
+ setMentions(mentions)
66
+ setVibeCoding(mentions[0]?.vibeCoding || false);
67
+ },
68
+ };
69
+ }, []);
70
+
71
+ const send = () => {
72
+ const inputContent = inputEditorRef.current!.textContent;
73
+ if (inputContent && !loading && !disabled) {
74
+ props.onSend({
75
+ message: inputContent,
76
+ attachments,
77
+ mentions,
78
+ })
79
+
80
+ setAttachments([]);
81
+ setInputContent("");
82
+ inputEditorRef.current!.textContent = "";
83
+ }
84
+ }
85
+
86
+ const onInput = () => {
87
+ setInputContent(inputEditorRef.current!.textContent)
88
+ }
89
+
90
+ const onKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {
91
+ if (event.key === "Enter") {
92
+ if (isComposing) {
93
+ return;
94
+ }
95
+
96
+ if (event.shiftKey) {
97
+
98
+ } else {
99
+ event.preventDefault();
100
+ send();
101
+ }
102
+ }
103
+ }
104
+
105
+ const onCompositionStart = () => {
106
+ setIsComposing(true);
107
+ }
108
+
109
+ const onCompositionEnd = () => {
110
+ setIsComposing(false);
111
+ }
112
+
113
+ /** 检查附件数量是否超出限制,超出返回 true */
114
+ const checkAttachmentsLimit = () => {
115
+ if (attachments.length > 1) {
116
+ message.info("当前只能上传两张图片");
117
+ return true;
118
+ }
119
+ return false;
120
+ }
121
+
122
+ const updateAttachmentsByFile = (file: File) => {
123
+ if (file.size > 5000 * 1024) {
124
+ message.info(`当前文件大小 ${(file.size / 1024).toFixed(2)}K,超过了5000K,建议您截取页面中的某个区域作为附件`)
125
+ return;
126
+ }
127
+ readFileToBase64(file)
128
+ .then((base64) => {
129
+ setAttachments((attachments) => {
130
+ return [...attachments, { type: "image", content: base64 }]
131
+ })
132
+ if (!inputContent && attachmentsPrompt) {
133
+ setInputContent(attachmentsPrompt);
134
+ const selection = window.getSelection();
135
+
136
+ if (!selection?.rangeCount) {
137
+ return;
138
+ }
139
+
140
+ const range = selection.getRangeAt(0);
141
+ const textNode = document.createTextNode(attachmentsPrompt);
142
+ range.insertNode(textNode);
143
+ range.setStartAfter(textNode);
144
+ range.setEndAfter(textNode);
145
+ }
146
+ })
147
+ .catch((event) => {
148
+ console.error("[@mybricks/plugin-ai - 上传附件失败]", event);
149
+ message.error("[@mybricks/plugin-ai - 上传附件失败]");
150
+ })
151
+ }
152
+
153
+ const uploadAttachment = () => {
154
+ if (loading || disabled) {
155
+ return;
156
+ }
157
+ if (checkAttachmentsLimit()) {
158
+ return;
159
+ }
160
+ const fileInput = document.createElement('input');
161
+ fileInput.type = 'file';
162
+ fileInput.accept = 'image/*';
163
+
164
+ fileInput.addEventListener('change', function (e) {
165
+ const target = e.target as HTMLInputElement;
166
+ if (!target) {
167
+ return;
168
+ }
169
+ const file = target.files?.[0];
170
+
171
+ if (file) {
172
+ if (!file.type.startsWith('image/')) {
173
+ return;
174
+ }
175
+
176
+ updateAttachmentsByFile(file);
177
+ }
178
+ });
179
+
180
+ fileInput.click();
181
+ };
182
+
183
+ const onPaste = (event: React.ClipboardEvent<HTMLDivElement>) => {
184
+ event.preventDefault();
185
+ if (loading || disabled) {
186
+ return;
187
+ }
188
+ const file = event.clipboardData.files[0];
189
+ if (file?.type.startsWith('image/')) {
190
+ if (checkAttachmentsLimit()) {
191
+ return;
192
+ }
193
+ updateAttachmentsByFile(file);
194
+ } else {
195
+ const content = event.clipboardData.getData('text/plain');
196
+
197
+ if (!content) {
198
+ return;
199
+ }
200
+
201
+ const selection = window.getSelection();
202
+
203
+ if (!selection?.rangeCount) {
204
+ return;
205
+ }
206
+
207
+ const range = selection.getRangeAt(0);
208
+ range.deleteContents();
209
+ const textNode = document.createTextNode(content);
210
+ range.insertNode(textNode);
211
+ range.setStartAfter(textNode);
212
+ range.setEndAfter(textNode);
213
+
214
+ setInputContent(inputEditorRef.current!.textContent)
215
+ }
216
+ }
217
+
218
+ const onAttachmentsDelete = (index: number) => {
219
+ setAttachments((attachments) => {
220
+ attachments.splice(index, 1)
221
+ return [...attachments]
222
+ })
223
+ }
224
+
225
+ return (
226
+ <div className={css.container}>
227
+ <div className={classNames(css.editor, {
228
+ [css.noMentions]: mode === "mention" && !mentions.length
229
+ })}>
230
+ {attachments.length ? (
231
+ <div className={css.topArea}>
232
+ <AttachmentsList attachments={attachments} onDelete={onAttachmentsDelete}/>
233
+ </div>
234
+ ) : null}
235
+ {mentions.length ? (
236
+ <div className={css.mentions}>
237
+ <span>对于</span>
238
+ <MentionTag mention={mentions[0]} onClick={onMentionClick} />
239
+ <span>{(mentions[0].type === "page" ? "页面" : "组件") + (mentions[0].focusArea ? "的" : "")}</span>
240
+ {mentions[0].focusArea ? (
241
+ <span className={css.focusarea}>
242
+ {mentions[0].focusArea.title || "区域"}
243
+ </span>
244
+ ) : null}
245
+ {/* {vibeCoding ? <span className={css.vibeCoding}>(开发中)</span> : null} */}
246
+ {/* {mentions.map((mention) => {
247
+ return <MentionTag key={mention.id} mention={mention} onClick={onMentionClick} />
248
+ })} */}
249
+ </div>
250
+ ) : null}
251
+ <div className={css.input}>
252
+ <div className={css.inputEditorContainer}>
253
+ <div
254
+ ref={inputEditorRef}
255
+ className={css.inputEditor}
256
+ contentEditable={disabled ? false : true}
257
+ onKeyDown={onKeyDown}
258
+ onCompositionStart={onCompositionStart}
259
+ onCompositionEnd={onCompositionEnd}
260
+ onInput={onInput}
261
+ onPaste={onPaste}
262
+ onBlur={onBlur}
263
+ ></div>
264
+ {!inputContent && <div className={css.inputPlaceholder}>
265
+ {placeholder}
266
+ </div>}
267
+ </div>
268
+ </div>
269
+ <div className={css.editorAction}>
270
+ <div className={classNames(css.leftArea, {
271
+ [css.disabled]: loading || disabled
272
+ })}>
273
+ <div className={css.attachmentButton} onClick={uploadAttachment}>
274
+ <Attachment />
275
+ </div>
276
+ {/* {attachments.length ? (
277
+ <AttachmentsList attachments={attachments} onDelete={onAttachmentsDelete}/>
278
+ ) : null} */}
279
+ </div>
280
+ <div className={css.rightArea}>
281
+ <div className={classNames(css.sendButtonContainer, {
282
+ [css.disabled]: !inputContent || loading || disabled
283
+ })} onClick={send}>
284
+ <div className={classNames(css.sendButton, {
285
+ [css.loadingButton]: loading
286
+ })}>
287
+ {loading ? <Loading /> : <Send />}
288
+ </div>
289
+ </div>
290
+ </div>
291
+ </div>
292
+ </div>
293
+ </div>
294
+ )
295
+ })
296
+
297
+ export { Sender }
298
+ export type { SenderRef, SenderProps }
@@ -0,0 +1,31 @@
1
+ interface Mention {
2
+ /** 唯一ID */
3
+ id?: string;
4
+ /** 展示用 */
5
+ name?: string;
6
+
7
+
8
+ /** 区域才会有 */
9
+ focusArea?: {
10
+ selector: string;
11
+ title: string;
12
+ }
13
+ comId: string;
14
+ pageId: string;
15
+ title: string;
16
+ /** 类型,组件、页面 */
17
+ type: "page" | "uiCom";
18
+ /** 是否为 vibeCoding 状态(代码编辑模式) */
19
+ vibeCoding?: boolean;
20
+ }
21
+
22
+ interface Extension {
23
+ mentions: Mention[]
24
+ }
25
+
26
+ type Attachments = {
27
+ type: "image";
28
+ content: string;
29
+ }[]
30
+
31
+ export type { Mention, Extension, Attachments }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * 是否启用辅助标记
3
+ *
4
+ * 启用后,辅助标记会被保留在最终的actions.json文件中
5
+ * 禁用后,辅助标记会被删除
6
+ */
7
+ export const ENABLED_ACTION_TAGS = true;
8
+
@@ -0,0 +1,50 @@
1
+ import { Events } from "@mybricks/rxai"
2
+
3
+ interface RequestStatus {
4
+ state: "pending" | "fulfilled" | "rejected";
5
+ result: any;
6
+ }
7
+ class RequestStatusTracker {
8
+ private requests = new Map<string, RequestStatus>();
9
+ events = new Events<{promise: {
10
+ id: string;
11
+ status: RequestStatus
12
+ }}>();
13
+ constructor() {}
14
+
15
+ track(id: string, promise: Promise<any>) {
16
+ const status: RequestStatus = {
17
+ state: "pending",
18
+ result: null,
19
+ }
20
+ this.events.emit("promise", {
21
+ id,
22
+ status,
23
+ })
24
+
25
+ promise.then((result) => {
26
+ status.state = "fulfilled";
27
+ status.result = result
28
+ }).catch((error) => {
29
+ status.state = "rejected";
30
+ status.result = error
31
+ console.error(error);
32
+ }).finally(() => {
33
+ this.events.emit("promise", {
34
+ id,
35
+ status,
36
+ })
37
+ })
38
+
39
+ this.requests.set(id, status);
40
+ }
41
+
42
+ getStatus(id: string) {
43
+ return this.requests.get(id) || {
44
+ state: "fulfilled",
45
+ result: null
46
+ };
47
+ }
48
+ }
49
+
50
+ export { RequestStatusTracker };
@@ -1,21 +1,83 @@
1
- import { Rxai } from "@mybricks/rxai"
1
+ import { Rxai, Events, IDB } from "@mybricks/rxai"
2
+ import { RequestStatusTracker } from "./RequestStatusTracker";
3
+ import { DeviceType } from './../types';
4
+ import type { AgentConfigParams } from '../agents/utils/config';
2
5
 
3
6
  class Context {
7
+
8
+ /** UI展示名称 */
9
+ name!: string
10
+
4
11
  rxai!: Rxai
12
+ globalRxai!: Rxai
5
13
  currentFocus?: AiServiceFocusParams;
6
14
  api!: AiServiceAPI;
15
+ aiViewAPI!: AiViewApi;
16
+
17
+ /** 设计器 API(带记录功能) */
18
+ designer?: {
19
+ createPage?: (id: string, title: string, config?: any) => Promise<{ id: string; onProgress: Function; }>;
20
+ createCanvas?: () => Promise<{ id: string; title: string; }>;
21
+ updatePage?: (...params: any[]) => Promise<void>;
22
+ updateUiCom?: (...params: any[]) => Promise<void>;
23
+ updateLogicCom?: (...params: any[]) => Promise<void>;
24
+ createDiagram?: (...params: any[]) => Promise<{ id: string; title: string }>;
25
+ updateDiagram?: (...params: any[]) => Promise<void>;
26
+ getDiagramInfo?: (...params: any[]) => any;
27
+ getDiagramInfoByVarId?: (...params: any[]) => any;
28
+ getDiagramInfoByListenerInfo?: (...params: any[]) => any;
29
+ getAllComDefPrompts: () => string;
30
+ };
7
31
 
8
- /** 应用传入的系统提示词 */
9
- prompts?: any;
32
+ /** Agent 配置 */
33
+ agents: AgentConfigParams[] = [];
10
34
 
11
- createRxai(options: ConstructorParameters<typeof Rxai>[0]) {
35
+ /** 是否多画布 */
36
+ isMutiCanvas: boolean = true
37
+
38
+ userConfig?: {
39
+ useCloudComponents: boolean;
40
+ enabledActionTags: boolean;
41
+ }
42
+
43
+ get useCloudComponents() {
44
+ return this.userConfig?.useCloudComponents ?? false;
45
+ }
46
+
47
+ get enabledActionTags() {
48
+ return this.userConfig?.enabledActionTags ?? true;
49
+ }
50
+
51
+ deviceType: DeviceType = DeviceType.Mobile
52
+
53
+ /** 应用传入的创建页面模板 */
54
+ createTemplates?: {
55
+ page: any
56
+ }
57
+
58
+ events = new Events<{
59
+ aiViewDisplay: boolean;
60
+ focus: AiServiceFocusParams | undefined;
61
+ }>();
62
+
63
+ createRxai(options: ConstructorParameters<typeof Rxai>[0] & { key: number }) {
12
64
  if (!this.rxai) {
13
- this.rxai = new Rxai(options)
65
+ this.rxai = new Rxai({
66
+ ...options,
67
+ idb: options.key ? new IDB({
68
+ dbName: "@mybricks/plugin-ai/messages",
69
+ key: options.key
70
+ }) : undefined
71
+ })
72
+ this.globalRxai = new Rxai(options)
14
73
  }
15
74
  }
75
+
76
+ requestStatusTracker = new RequestStatusTracker();
77
+
78
+ pluginParams: any = {};
16
79
  }
17
80
 
18
81
  const context = new Context();
19
82
 
20
83
  export { context };
21
-