@mybricks/plugin-ai 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (249) hide show
  1. package/dist/_virtual/_rollupPluginBabelHelpers.js +164 -0
  2. package/dist/_virtual/_rollupPluginBabelHelpers.js.map +1 -0
  3. package/dist/agents/app.js +335 -0
  4. package/dist/agents/app.js.map +1 -0
  5. package/dist/agents/common.js +483 -0
  6. package/dist/agents/common.js.map +1 -0
  7. package/dist/agents/custom.js +16 -0
  8. package/dist/agents/custom.js.map +1 -0
  9. package/dist/agents/index.js +38 -0
  10. package/dist/agents/index.js.map +1 -0
  11. package/dist/agents/knowledges/knowledge-base.js +579 -0
  12. package/dist/agents/knowledges/knowledge-base.js.map +1 -0
  13. package/dist/agents/knowledges/knowledge-node.js +228 -0
  14. package/dist/agents/knowledges/knowledge-node.js.map +1 -0
  15. package/dist/agents/knowledges/types.js +105 -0
  16. package/dist/agents/knowledges/types.js.map +1 -0
  17. package/dist/agents/utils/config.js +229 -0
  18. package/dist/agents/utils/config.js.map +1 -0
  19. package/dist/agents/workspace/coding-manager.js +20 -0
  20. package/dist/agents/workspace/coding-manager.js.map +1 -0
  21. package/dist/agents/workspace/components-manager.js +113 -0
  22. package/dist/agents/workspace/components-manager.js.map +1 -0
  23. package/dist/agents/workspace/outline-focus.js +167 -0
  24. package/dist/agents/workspace/outline-focus.js.map +1 -0
  25. package/dist/agents/workspace/outline-info.js +430 -0
  26. package/dist/agents/workspace/outline-info.js.map +1 -0
  27. package/dist/agents/workspace/page-tree-generator.js +70 -0
  28. package/dist/agents/workspace/page-tree-generator.js.map +1 -0
  29. package/dist/agents/workspace/workspace.js +251 -0
  30. package/dist/agents/workspace/workspace.js.map +1 -0
  31. package/dist/agents/workspace-by-knowledges/providers/component-docs-provider.js +100 -0
  32. package/dist/agents/workspace-by-knowledges/providers/component-docs-provider.js.map +1 -0
  33. package/dist/agents/workspace-by-knowledges/providers/focus-info-provider.js +120 -0
  34. package/dist/agents/workspace-by-knowledges/providers/focus-info-provider.js.map +1 -0
  35. package/dist/agents/workspace-by-knowledges/providers/project-info-provider.js +146 -0
  36. package/dist/agents/workspace-by-knowledges/providers/project-info-provider.js.map +1 -0
  37. package/dist/agents/workspace-by-knowledges/test.js +242 -0
  38. package/dist/agents/workspace-by-knowledges/test.js.map +1 -0
  39. package/dist/agents/workspace-by-knowledges/utils/components-manager.js +132 -0
  40. package/dist/agents/workspace-by-knowledges/utils/components-manager.js.map +1 -0
  41. package/dist/agents/workspace-by-knowledges/utils/outline-focus.js +167 -0
  42. package/dist/agents/workspace-by-knowledges/utils/outline-focus.js.map +1 -0
  43. package/dist/agents/workspace-by-knowledges/utils/outline-info.js +430 -0
  44. package/dist/agents/workspace-by-knowledges/utils/outline-info.js.map +1 -0
  45. package/dist/agents/workspace-by-knowledges/workspace.js +169 -0
  46. package/dist/agents/workspace-by-knowledges/workspace.js.map +1 -0
  47. package/dist/api/cloud-components.js +85 -0
  48. package/dist/api/cloud-components.js.map +1 -0
  49. package/dist/api-record-replay/manager.js +168 -0
  50. package/dist/api-record-replay/manager.js.map +1 -0
  51. package/{src/api-record-replay/recorder.ts → dist/api-record-replay/recorder.js} +22 -32
  52. package/dist/api-record-replay/recorder.js.map +1 -0
  53. package/dist/api-record-replay/replayer.js +136 -0
  54. package/dist/api-record-replay/replayer.js.map +1 -0
  55. package/dist/components/attachments/index.js +124 -0
  56. package/dist/components/attachments/index.js.map +1 -0
  57. package/dist/components/attachments/index.less.js +8 -0
  58. package/dist/components/attachments/index.less.js.map +1 -0
  59. package/dist/components/icons/index.js +112 -0
  60. package/dist/components/icons/index.js.map +1 -0
  61. package/dist/components/icons/index.less.js +8 -0
  62. package/dist/components/icons/index.less.js.map +1 -0
  63. package/dist/components/mention/index.js +19 -0
  64. package/dist/components/mention/index.js.map +1 -0
  65. package/dist/components/mention/index.less.js +8 -0
  66. package/dist/components/mention/index.less.js.map +1 -0
  67. package/dist/components/messages/index.js +429 -0
  68. package/dist/components/messages/index.js.map +1 -0
  69. package/dist/components/messages/index.less.js +8 -0
  70. package/dist/components/messages/index.less.js.map +1 -0
  71. package/dist/components/sender/index.js +244 -0
  72. package/dist/components/sender/index.js.map +1 -0
  73. package/dist/components/sender/index.less.js +8 -0
  74. package/dist/components/sender/index.less.js.map +1 -0
  75. package/dist/context/RequestStatusTracker.js +44 -0
  76. package/dist/context/RequestStatusTracker.js.map +1 -0
  77. package/dist/context/index.js +45 -0
  78. package/dist/context/index.js.map +1 -0
  79. package/dist/data.js +4 -0
  80. package/dist/data.js.map +1 -0
  81. package/dist/index.js +306 -0
  82. package/dist/index.js.map +1 -0
  83. package/dist/plugin-ai/node_modules/style-inject/dist/style-inject.es.js +27 -0
  84. package/dist/plugin-ai/node_modules/style-inject/dist/style-inject.es.js.map +1 -0
  85. package/dist/plugin-ai/package.json.js +8 -0
  86. package/dist/plugin-ai/package.json.js.map +1 -0
  87. package/dist/plugin-ai/test/index.js +206 -0
  88. package/dist/plugin-ai/test/index.js.map +1 -0
  89. package/dist/preset/createTemplates.js +29 -0
  90. package/dist/preset/createTemplates.js.map +1 -0
  91. package/dist/preset/index.js +13 -0
  92. package/dist/preset/index.js.map +1 -0
  93. package/dist/preset/prompts.js +34 -0
  94. package/dist/preset/prompts.js.map +1 -0
  95. package/{src/preset/user.ts → dist/preset/user.js} +4 -3
  96. package/dist/preset/user.js.map +1 -0
  97. package/dist/requestAsStream.js +269 -0
  98. package/dist/requestAsStream.js.map +1 -0
  99. package/dist/rxai/node_modules/idb/build/index.js +277 -0
  100. package/dist/rxai/node_modules/idb/build/index.js.map +1 -0
  101. package/dist/rxai/src/agent/base.js +16 -0
  102. package/dist/rxai/src/agent/base.js.map +1 -0
  103. package/dist/rxai/src/agent/planning.js +1076 -0
  104. package/dist/rxai/src/agent/planning.js.map +1 -0
  105. package/dist/rxai/src/agent/rxai.js +254 -0
  106. package/dist/rxai/src/agent/rxai.js.map +1 -0
  107. package/dist/rxai/src/error/base.js +39 -0
  108. package/dist/rxai/src/error/base.js.map +1 -0
  109. package/dist/rxai/src/prompt/base.js +11 -0
  110. package/dist/rxai/src/prompt/base.js.map +1 -0
  111. package/dist/rxai/src/prompt/planning.js +23 -0
  112. package/dist/rxai/src/prompt/planning.js.map +1 -0
  113. package/dist/rxai/src/prompt/tool.js +14 -0
  114. package/dist/rxai/src/prompt/tool.js.map +1 -0
  115. package/dist/rxai/src/request/request.js +123 -0
  116. package/dist/rxai/src/request/request.js.map +1 -0
  117. package/dist/rxai/src/tool/getHistoryRecords.js +65 -0
  118. package/dist/rxai/src/tool/getHistoryRecords.js.map +1 -0
  119. package/dist/rxai/src/tool/util.js +424 -0
  120. package/dist/rxai/src/tool/util.js.map +1 -0
  121. package/dist/rxai/src/utils/events.js +43 -0
  122. package/dist/rxai/src/utils/events.js.map +1 -0
  123. package/dist/rxai/src/utils/idb.js +240 -0
  124. package/dist/rxai/src/utils/idb.js.map +1 -0
  125. package/dist/rxai/src/utils/retry.js +32 -0
  126. package/dist/rxai/src/utils/retry.js.map +1 -0
  127. package/dist/rxai/src/utils/uuid.js +7 -0
  128. package/dist/rxai/src/utils/uuid.js.map +1 -0
  129. package/dist/startView/components/header/header.js +12 -0
  130. package/dist/startView/components/header/header.js.map +1 -0
  131. package/dist/startView/components/header/header.less.js +8 -0
  132. package/dist/startView/components/header/header.less.js.map +1 -0
  133. package/dist/startView/index.js +62 -0
  134. package/dist/startView/index.js.map +1 -0
  135. package/dist/startView/index.less.js +8 -0
  136. package/dist/startView/index.less.js.map +1 -0
  137. package/dist/tools/analyze-and-expand-prd.js +116 -0
  138. package/dist/tools/analyze-and-expand-prd.js.map +1 -0
  139. package/dist/tools/analyze-requirement-and-components.js +208 -0
  140. package/dist/tools/analyze-requirement-and-components.js.map +1 -0
  141. package/dist/tools/answer.js +33 -0
  142. package/dist/tools/answer.js.map +1 -0
  143. package/dist/tools/build-process.js +550 -0
  144. package/dist/tools/build-process.js.map +1 -0
  145. package/dist/tools/coding-subagent-as-tool.js +101 -0
  146. package/dist/tools/coding-subagent-as-tool.js.map +1 -0
  147. package/dist/tools/generate-ui-content.js +528 -0
  148. package/dist/tools/generate-ui-content.js.map +1 -0
  149. package/dist/tools/index.js +31 -0
  150. package/dist/tools/index.js.map +1 -0
  151. package/dist/tools/open-dsl.js +49 -0
  152. package/dist/tools/open-dsl.js.map +1 -0
  153. package/dist/tools/refactor-ui-content.js +292 -0
  154. package/dist/tools/refactor-ui-content.js.map +1 -0
  155. package/dist/tools/utils.js +832 -0
  156. package/dist/tools/utils.js.map +1 -0
  157. package/dist/types/index.js +8 -0
  158. package/dist/types/index.js.map +1 -0
  159. package/dist/view/components/header/header.js +59 -0
  160. package/dist/view/components/header/header.js.map +1 -0
  161. package/dist/view/components/header/header.less.js +8 -0
  162. package/dist/view/components/header/header.less.js.map +1 -0
  163. package/dist/view/index.js +184 -0
  164. package/dist/view/index.js.map +1 -0
  165. package/dist/view/index.less.js +8 -0
  166. package/dist/view/index.less.js.map +1 -0
  167. package/package.json +28 -6
  168. package/src/agents/app.ts +0 -301
  169. package/src/agents/common.ts +0 -471
  170. package/src/agents/custom.ts +0 -14
  171. package/src/agents/index.ts +0 -37
  172. package/src/agents/knowledges/README.md +0 -614
  173. package/src/agents/knowledges/SUMMARY.md +0 -527
  174. package/src/agents/knowledges/index.ts +0 -8
  175. package/src/agents/knowledges/knowledge-base.ts +0 -565
  176. package/src/agents/knowledges/knowledge-node.ts +0 -266
  177. package/src/agents/knowledges/types.ts +0 -208
  178. package/src/agents/utils/config.ts +0 -427
  179. package/src/agents/workspace/coding-manager.ts +0 -31
  180. package/src/agents/workspace/components-manager.ts +0 -124
  181. package/src/agents/workspace/outline-focus.ts +0 -188
  182. package/src/agents/workspace/outline-info.ts +0 -520
  183. package/src/agents/workspace/page-tree-generator.ts +0 -83
  184. package/src/agents/workspace/workspace.ts +0 -319
  185. package/src/agents/workspace-by-knowledges/MIGRATION.md +0 -568
  186. package/src/agents/workspace-by-knowledges/README.md +0 -521
  187. package/src/agents/workspace-by-knowledges/index.ts +0 -11
  188. package/src/agents/workspace-by-knowledges/providers/component-docs-provider.ts +0 -92
  189. package/src/agents/workspace-by-knowledges/providers/focus-info-provider.ts +0 -131
  190. package/src/agents/workspace-by-knowledges/providers/index.ts +0 -8
  191. package/src/agents/workspace-by-knowledges/providers/project-info-provider.ts +0 -151
  192. package/src/agents/workspace-by-knowledges/test.ts +0 -240
  193. package/src/agents/workspace-by-knowledges/types.ts +0 -56
  194. package/src/agents/workspace-by-knowledges/utils/components-manager.ts +0 -145
  195. package/src/agents/workspace-by-knowledges/utils/index.ts +0 -8
  196. package/src/agents/workspace-by-knowledges/utils/outline-focus.ts +0 -178
  197. package/src/agents/workspace-by-knowledges/utils/outline-info.ts +0 -521
  198. package/src/agents/workspace-by-knowledges/workspace.ts +0 -166
  199. package/src/api/cloud-components.ts +0 -129
  200. package/src/api-record-replay/README.md +0 -187
  201. package/src/api-record-replay/index.ts +0 -11
  202. package/src/api-record-replay/manager.ts +0 -168
  203. package/src/api-record-replay/replayer.ts +0 -148
  204. package/src/components/attachments/index.less +0 -117
  205. package/src/components/attachments/index.tsx +0 -136
  206. package/src/components/icons/index.less +0 -8
  207. package/src/components/icons/index.tsx +0 -44
  208. package/src/components/index.less +0 -34
  209. package/src/components/mention/index.less +0 -23
  210. package/src/components/mention/index.tsx +0 -19
  211. package/src/components/messages/index.less +0 -1013
  212. package/src/components/messages/index.tsx +0 -519
  213. package/src/components/sender/index.less +0 -203
  214. package/src/components/sender/index.tsx +0 -298
  215. package/src/components/types.ts +0 -31
  216. package/src/constants/index.ts +0 -8
  217. package/src/context/RequestStatusTracker.ts +0 -50
  218. package/src/context/index.ts +0 -83
  219. package/src/data.ts +0 -5
  220. package/src/global.d.ts +0 -100
  221. package/src/index.tsx +0 -264
  222. package/src/mock.ts +0 -1267
  223. package/src/preset/agents.ts +0 -380
  224. package/src/preset/createTemplates.ts +0 -25
  225. package/src/preset/index.ts +0 -12
  226. package/src/preset/prompts.ts +0 -235
  227. package/src/preset/requestAsStream.ts +0 -246
  228. package/src/startView/components/header/header.less +0 -17
  229. package/src/startView/components/header/header.tsx +0 -15
  230. package/src/startView/components/index.ts +0 -1
  231. package/src/startView/index.less +0 -34
  232. package/src/startView/index.tsx +0 -61
  233. package/src/tools/analyze-and-expand-prd.ts +0 -272
  234. package/src/tools/analyze-requirement-and-components.ts +0 -589
  235. package/src/tools/answer.ts +0 -59
  236. package/src/tools/build-process.ts +0 -1174
  237. package/src/tools/coding-subagent-as-tool.ts +0 -119
  238. package/src/tools/generate-ui-content.ts +0 -1083
  239. package/src/tools/index.ts +0 -28
  240. package/src/tools/open-dsl.ts +0 -69
  241. package/src/tools/refactor-ui-content.ts +0 -801
  242. package/src/tools/type.d.ts +0 -12
  243. package/src/tools/utils.ts +0 -914
  244. package/src/types/index.ts +0 -4
  245. package/src/view/components/header/header.less +0 -51
  246. package/src/view/components/header/header.tsx +0 -60
  247. package/src/view/components/index.ts +0 -1
  248. package/src/view/index.less +0 -5
  249. package/src/view/index.tsx +0 -168
@@ -1,519 +0,0 @@
1
- import React, { useRef, useState, useEffect, useLayoutEffect } from "react"
2
- import classNames from "classnames"
3
- import { Rxai } from "@mybricks/rxai"
4
- import markdownit from 'markdown-it'
5
- import { Extension } from "../types";
6
- import { Loading, Success, Chat } from "../icons";
7
- import { AttachmentsList } from "../attachments";
8
- import { MentionTag } from "../mention";
9
- import { Mention } from "../types";
10
- import { Sender, SenderRef, SenderProps } from "../sender";
11
- import { context } from "../../context";
12
- import css from "./index.less"
13
-
14
- const md = markdownit()
15
-
16
- interface User {
17
- /** 名称 */
18
- name: string;
19
- /** 头像地址 */
20
- avatar: string;
21
- }
22
-
23
- interface MessagesParams {
24
- /** 用户信息 */
25
- user: User;
26
- /** ai助手信息 */
27
- copilot: User;
28
-
29
- rxai: Rxai;
30
-
31
- onMentionClick?: (mention: Mention) => void;
32
-
33
- onSend?: SenderProps['onSend'];
34
- }
35
-
36
- type Plans = Rxai['cacheMessages'];
37
-
38
- const Messages = (params: MessagesParams) => {
39
- const { user, rxai, copilot, onSend, onMentionClick } = params;
40
-
41
- const mainRef = useRef<HTMLElement>(null);
42
- const destroysRef = useRef<(() => void)[]>([]);
43
- const [plans, setPlans] = useState<Plans>([]);
44
-
45
- const [styleTag] = useState(() => {
46
- const styleTag = document.createElement('style')
47
- document.head.appendChild(styleTag)
48
- const prefix = `.${css['ai-chat-messages']} .${css['chat-bubble-container']}:nth-last-child(1)`;
49
- return {
50
- setStyle: (height: number) => {
51
- styleTag.innerHTML = `${prefix} {
52
- min-height: ${height - 1}px;
53
- }`
54
- },
55
- remove: () => {
56
- document.head.removeChild(styleTag);
57
- }
58
- };
59
- })
60
-
61
- useLayoutEffect(() => {
62
- destroysRef.current.push(rxai.events.on('plan', (plans) => {
63
- setPlans([...plans])
64
- }, true))
65
-
66
- styleTag.setStyle(mainRef.current!.clientHeight);
67
- }, [])
68
-
69
- useEffect(() => {
70
- const autoScroller = new AutoScroller(mainRef.current!, {
71
- resizeObserverCallback: () => {
72
- const height = mainRef.current?.clientHeight;
73
- if (height && height > 0) {
74
- styleTag.setStyle(height)
75
- }
76
- },
77
- mutationCallback: (mutations) => {
78
- const mutationRecord = mutations[0];
79
-
80
- if (mutationRecord.target === mainRef.current && mutationRecord.addedNodes.length) {
81
- mainRef.current!.scrollTop = mainRef.current!.scrollHeight;
82
- }
83
- }
84
- });
85
-
86
- return () => {
87
- autoScroller.destroy();
88
-
89
- for (const destroy of destroysRef.current) {
90
- destroy()
91
- }
92
- }
93
- }, [])
94
-
95
- return (
96
- <main ref={mainRef} className={css['ai-chat-messages']}>
97
- {plans.map((plan, index) => {
98
- return (
99
- <Bubble
100
- key={plan.id}
101
- user={user}
102
- plan={plan}
103
- copilot={copilot}
104
- onSend={onSend}
105
- onMentionClick={onMentionClick}
106
- />
107
- )
108
- })}
109
- </main>
110
- )
111
- }
112
-
113
- type Plan = Rxai['cacheMessages'][number];
114
-
115
- interface BubbleParams {
116
- user: User;
117
- copilot: User;
118
- plan: Plan;
119
- onSend?: SenderProps['onSend'];
120
- onMentionClick?: (mention: Mention) => void;
121
- }
122
- const Bubble = (params: BubbleParams) => {
123
- const { user, plan, copilot, onSend, onMentionClick } = params;
124
- const [userMessage, setUserMessage] = useState<ReturnType<Plan['getUserMessage']>>();
125
- const destroysRef = useRef<(() => void)[]>([]);
126
-
127
- useLayoutEffect(() => {
128
- destroysRef.current.push(
129
- plan.events.on('userMessage', (userMessage) => {
130
- setUserMessage(userMessage);
131
- }),
132
- )
133
- }, [])
134
-
135
- useEffect(() => {
136
- return () => {
137
- for (const destroy of destroysRef.current) {
138
- destroy()
139
- }
140
- }
141
- }, [])
142
-
143
- return userMessage && (
144
- <div className={css['chat-bubble-container']}>
145
- <BubbleUser user={user} message={userMessage} plan={plan} onMentionClick={onMentionClick}/>
146
- <BubbleCopilot copilot={copilot} plan={plan}/>
147
- <BubbleAction plan={plan} onSend={onSend}/>
148
- </div>
149
- )
150
- }
151
-
152
- const BubbleAction = (props: { plan: Plan, onSend?: SenderProps['onSend']; }) => {
153
- const { plan, onSend } = props;
154
-
155
- const destroysRef = useRef<(() => void)[]>([]);
156
- const [status, setStatus] = useState<Plan['status']>();
157
- const [showRender, setShowRender] = useState(false);
158
- const senderRef = useRef<SenderRef>(null);
159
-
160
- useLayoutEffect(() => {
161
- destroysRef.current.push(
162
- plan.events.on('status', (status) => {
163
- setStatus(status)
164
- }, true),
165
- )
166
- }, [])
167
-
168
- useEffect(() => {
169
- return () => {
170
- for (const destroy of destroysRef.current) {
171
- destroy()
172
- }
173
- }
174
- }, [])
175
-
176
- useEffect(() => {
177
- if (showRender) {
178
- senderRef.current!.setMentions((plan.extension as any).mentions || []);
179
- senderRef.current!.focus();
180
- }
181
- }, [showRender])
182
-
183
- return (
184
- <>
185
- <div className={css['chat-bubble-action']}>
186
- {/* TODO 兼容处理,没有pageId,不允许追加 */}
187
- {status !== "pending" && onSend && (plan.extension as any).mentions?.[0]?.pageId && <div
188
- className={classNames(css['chat-bubble-action-chat'], {
189
- [css['focus']]: showRender
190
- })}
191
- data-mybricks-tip={"基于本次回答继续对话"}
192
- onClick={() => {
193
- setShowRender(!showRender);
194
- }}
195
- >
196
- <Chat />
197
- </div>}
198
- </div>
199
- {showRender && (
200
- <Sender
201
- ref={senderRef}
202
- placeholder={`您好,我是${context.name},请详细描述您的需求`}
203
- onSend={(params) => {
204
- onSend!({...params, insertAfter: plan});
205
- setShowRender(false);
206
- }}
207
- />
208
- )}
209
- </>
210
- )
211
- }
212
-
213
- interface BubbleMessageParams {
214
- message: string;
215
- }
216
- const BubbleMessage = (params: BubbleMessageParams) => {
217
- const { message } = params;
218
- const messageRef = useRef<HTMLDivElement>(null);
219
-
220
- useEffect(() => {
221
- messageRef.current!.innerHTML = md.render(message);
222
- }, [message])
223
-
224
- return <span ref={messageRef} />
225
- }
226
-
227
- interface BubbleUserParams {
228
- user: User;
229
- message: ReturnType<Plan['getUserMessage']>
230
- plan: Plan;
231
- onMentionClick?: (mention: Mention) => void;
232
- }
233
-
234
- const BubbleUser = (params: BubbleUserParams) => {
235
- const { user, message, plan, onMentionClick } = params;
236
- const mentions = (plan.extension as Extension)?.mentions || [];
237
- let content = "";
238
- let attachments: Plan["options"]["attachments"] = [];
239
-
240
- if (typeof message.content === "string") {
241
- content = message.content
242
- } else {
243
- message.content.forEach((item: any) => {
244
- if (item.type === "text") {
245
- content = item.text
246
- } else if (item.type === "image_url") {
247
- attachments.push({
248
- type: "image",
249
- content: item.image_url.url
250
- });
251
- }
252
- })
253
- }
254
-
255
- return (
256
- <article className={css['chat-bubble']}>
257
- <header className={css['chat-bubble-header']}>
258
- <span className={css['chat-bubble-header-avatar']}>
259
- <img className={css['user-avatar']} src={user.avatar} />
260
- </span>
261
- <span className={css['chat-bubble-header-name']}>{user.name}</span>
262
- </header>
263
- <section className={classNames(css['chat-message-container'], css['user-message'], {
264
- [css['mention']]: mentions.length
265
- })}>
266
- {mentions.length ? (
267
- <MentionTag mention={mentions[0]} focusarea={true} onClick={onMentionClick}/>
268
- ) : null}
269
- <span>
270
- {content}
271
- </span>
272
- {attachments.length ? (
273
- <AttachmentsList className={css['attachments-list']} attachments={attachments}/>
274
- ) : null}
275
- </section>
276
- </article>
277
- )
278
- }
279
-
280
- interface BubbleCopilotParams {
281
- copilot: User;
282
- plan: Plan;
283
- }
284
- const BubbleCopilot = (params: BubbleCopilotParams) => {
285
- const { copilot, plan } = params;
286
- const destroysRef = useRef<(() => void)[]>([]);
287
- const [loading, setLoading] = useState(false);
288
- const [streamMessage, setStreamMessage] = useState("");
289
- const [summary, setSummary] = useState("");
290
- const [commands, setCommands] = useState<Plan['commands']>([]);
291
- const [error, setError] = useState("");
292
- const [planningMessage, setPlanningMessage] = useState("")
293
-
294
- useLayoutEffect(() => {
295
- destroysRef.current.push(
296
- plan.events.on('loading', (loading) => {
297
- setLoading(loading);
298
- }),
299
- plan.events.on('streamMessage', (chunk) => {
300
- setStreamMessage((streamMessage) => {
301
- return streamMessage + chunk
302
- });
303
- }),
304
- plan.events.on('summary', (summary) => {
305
- setSummary(summary);
306
- }),
307
- plan.events.on('commands', (commands) => {
308
- setCommands([...commands]);
309
- setStreamMessage("");
310
- }),
311
- plan.events.on('error', (error) => {
312
- setError(error);
313
- }),
314
- plan.events.on('planningMessage', (planningMessage) => {
315
- setPlanningMessage(planningMessage);
316
- })
317
- )
318
- }, [])
319
-
320
- useEffect(() => {
321
- return () => {
322
- for (const destroy of destroysRef.current) {
323
- destroy()
324
- }
325
- }
326
- }, [])
327
-
328
- return (
329
- <article className={css['chat-bubble']}>
330
- <header className={css['chat-bubble-header']}>
331
- {/* <span className={css['chat-bubble-header-avatar']}>
332
- <img className={css['copilot-avatar']} src={copilot.avatar} />
333
- </span> */}
334
- <span className={css['chat-bubble-header-name']}>{copilot.name}</span>
335
- </header>
336
- <section className={classNames(css['chat-message-container'], css['ai-message'])}>
337
- <div className={css['markdown-body']}>
338
- <div className={css['think']}>
339
- {planningMessage ? <BubbleMessage message={`${planningMessage}${loading ? "..." : ""}`} /> : (loading ? <span>正在思考</span> : null)}
340
- {loading && !planningMessage && <Loading />}
341
- </div>
342
- {commands.map((command, index) => {
343
- if (!command.status || command.status === "error") {
344
- return null;
345
- }
346
- return <BubbleCopilotTool key={index + command.status} command={command} last={index === commands.length - 1}/>
347
- })}
348
- {error && <BubbleError message={error} plan={plan}/>}
349
- {summary && <BubbleMessage message={summary} />}
350
- {/* {streamMessage && <BubbleMessage message={streamMessage} />} */}
351
- {/* {!streamMessage && loading && (
352
- <div className={css['think']}>
353
- <span>正在思考</span>
354
- <Loading />
355
- </div>
356
- )} */}
357
- </div>
358
- </section>
359
- </article>
360
- )
361
- }
362
-
363
- interface BubbleCopilotToolParams {
364
- command: Plan['commands'][number];
365
- last: boolean;
366
- }
367
- const BubbleCopilotTool = (params: BubbleCopilotToolParams) => {
368
- const { command, last } = params;
369
- const [message, setMessage] = useState("");
370
- const [expand, setExpand] = useState(false);
371
-
372
- useEffect(() => {
373
- if (command.status === "success") {
374
- setMessage(command.content.display || command.content.llm)
375
- if (last) {
376
- setExpand(true)
377
- }
378
- }
379
- const destory = command.events?.on("streamMessage", ({ message, status }) => {
380
- setMessage(message)
381
- if (status === "start") {
382
- setExpand(true)
383
- } else if (status === "complete") {
384
- if (!last) {
385
- setExpand(false)
386
- }
387
- }
388
- })
389
-
390
- return () => {
391
- destory?.();
392
- }
393
- }, [])
394
-
395
- const renderMessage = (shouldRender: boolean) =>
396
- shouldRender && message ? (
397
- <div
398
- className={css['ai-chat-collapsible-response']}
399
- style={{ display: expand ? "block" : "none" }}
400
- >
401
- <BubbleMessage message={message} />
402
- </div>
403
- ) : null;
404
-
405
- return (
406
- <>
407
- {renderMessage(command.status === "pending")}
408
- <div
409
- className={classNames(css['ai-chat-collapsible-code-block'], css['collapsed'])}
410
- onClick={() => {
411
- if (command.status !== "pending") {
412
- setExpand((expand) => !expand);
413
- }
414
- }}
415
- >
416
- <span className={classNames(css['code-header'], css['collapsed'])}>
417
- <span className={classNames(css['code-title'], css['collapsed'])}>{command.tool.displayName || command.tool.name}</span>
418
- {command.status === "pending" && (
419
- <span className={classNames(css['code-title-status'], css['collapsed'], css['pending'])}>
420
- <Loading />
421
- </span>
422
- )}
423
- {command.status === "success" && (
424
- <span className={classNames(css['code-title-status'], css['collapsed'], css['success'])}>
425
- <Success />
426
- </span>
427
- )}
428
- </span>
429
- </div>
430
- {renderMessage(command.status === "success")}
431
- </>
432
- )
433
- }
434
-
435
- interface BubbleErrorParams {
436
- message: string;
437
- plan: Plan;
438
- }
439
- const BubbleError = (params: BubbleErrorParams) => {
440
- const { message, plan } = params;
441
-
442
- return (
443
- <div className={css['ai-chat-error-code-block']}>
444
- <div className={css['ai-chat-error-code-block-message']}>
445
- <span>{message}</span>
446
- </div>
447
- {!plan.enableRetry ? null : (
448
- <div
449
- className={css['ai-chat-error-code-block-retry']}
450
- onClick={() => plan.retry()}
451
- >重试</div>
452
- )}
453
- </div>
454
- )
455
- }
456
-
457
- export { Messages }
458
-
459
- class AutoScroller {
460
- private isLockedToBottom: boolean = true;
461
- private resizeObserver: ResizeObserver | null = null;
462
- private mutationObserver: MutationObserver | null = null;
463
- constructor(private container: HTMLElement, private options: { resizeObserverCallback: ResizeObserverCallback, mutationCallback: MutationCallback }) {
464
- this.isLockedToBottom = true;
465
-
466
- this.init();
467
- }
468
-
469
- init() {
470
- // 监听滚动事件
471
- this.container.addEventListener('scroll', this.handleScroll.bind(this));
472
-
473
- // 使用ResizeObserver监听内容大小变化
474
- this.resizeObserver = new ResizeObserver((entries, observer) => {
475
- if (this.isLockedToBottom) {
476
- this.scrollToBottom();
477
- }
478
- this.options.resizeObserverCallback(entries, observer);
479
- });
480
-
481
- // 监听容器内部元素大小变化
482
- this.resizeObserver.observe(this.container);
483
-
484
- // 同时监听DOM变化
485
- this.mutationObserver = new MutationObserver((mutations, observer) => {
486
- if (this.isLockedToBottom) {
487
- Promise.resolve().then(() => {
488
- this.scrollToBottom();
489
- });
490
- }
491
- this.options.mutationCallback(mutations, observer);
492
- });
493
-
494
- this.mutationObserver.observe(this.container, {
495
- childList: true,
496
- subtree: true,
497
- });
498
- }
499
-
500
- handleScroll() {
501
- const isAtBottom = this.isAtBottom();
502
- this.isLockedToBottom = isAtBottom;
503
- }
504
-
505
- isAtBottom(threshold = 5) {
506
- const { scrollTop, scrollHeight, clientHeight } = this.container;
507
- return Math.abs(scrollHeight - scrollTop - clientHeight) <= threshold;
508
- }
509
-
510
- scrollToBottom() {
511
- this.container.scrollTop = this.container.scrollHeight;
512
- }
513
-
514
- destroy() {
515
- if (this.mutationObserver) this.mutationObserver.disconnect();
516
- if (this.resizeObserver) this.resizeObserver.disconnect();
517
- this.container.removeEventListener('scroll', this.handleScroll);
518
- }
519
- }
@@ -1,203 +0,0 @@
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
- }