vzcode 2.0.0 → 2.3.0

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 (218) hide show
  1. package/dist/assets/{buildWorker-Dsx6rOdK.js → buildWorker-wLkQ0yz1.js} +64 -64
  2. package/dist/assets/{index-BM8tDh6M.css → index-BoFeK4GL.css} +1 -1
  3. package/dist/assets/{index-BgqNq-ww.js → index-DuUjtrt6.js} +107 -107
  4. package/dist/assets/{worker-BeBZGG1n.js → worker-DHxSPM7N.js} +78 -78
  5. package/dist/cli.js +113 -0
  6. package/dist/index.html +2 -2
  7. package/{src/ot.ts → dist/ot.js} +2 -14
  8. package/{src/randomId.ts → dist/randomId.js} +5 -6
  9. package/dist/runCode.js +20 -0
  10. package/dist/server/aiChatHandler/aiEditing.js +89 -0
  11. package/dist/server/aiChatHandler/chatOperations.js +360 -0
  12. package/dist/server/aiChatHandler/errorHandling.js +49 -0
  13. package/dist/server/aiChatHandler/index.js +112 -0
  14. package/dist/server/aiChatHandler/llmStreaming.js +284 -0
  15. package/dist/server/aiChatHandler/validation.js +19 -0
  16. package/dist/server/computeInitialDocument.js +146 -0
  17. package/{src/server/config.ts → dist/server/config.js} +4 -7
  18. package/{src/server/featureFlags.ts → dist/server/featureFlags.js} +0 -3
  19. package/dist/server/generateAIResponse.js +129 -0
  20. package/dist/server/handleAIAssist.js +39 -0
  21. package/dist/server/handleAICopilot.js +81 -0
  22. package/dist/server/index.js +297 -0
  23. package/dist/server/livekit.js +17 -0
  24. package/dist/server/prettier.js +90 -0
  25. package/{src/server/setupEnv.ts → dist/server/setupEnv.js} +1 -2
  26. package/dist/submitOperation.js +14 -0
  27. package/dist/types.js +1 -0
  28. package/dist/utils/fileDiff.js +66 -0
  29. package/package.json +23 -22
  30. package/src/client/AIAssist/AIAssistCodeMirrorKeyMap.ts +0 -42
  31. package/src/client/AIAssist/AIAssistWidget/index.tsx +0 -135
  32. package/src/client/AIAssist/AIAssistWidget/style.scss +0 -47
  33. package/src/client/AIAssist/Spinner.jsx +0 -76
  34. package/src/client/AIAssist/formatFile.ts +0 -27
  35. package/src/client/AIAssist/generateFilesContext.ts +0 -25
  36. package/src/client/AIAssist/index.ts +0 -2
  37. package/src/client/AIAssist/startAIAssist.ts +0 -95
  38. package/src/client/App/index.tsx +0 -153
  39. package/src/client/App/style.scss +0 -82
  40. package/src/client/App/usePending.ts +0 -51
  41. package/src/client/App/useShareDB.ts +0 -161
  42. package/src/client/CodeEditor/Copilot/index.ts +0 -74
  43. package/src/client/CodeEditor/InteractiveWidgets/boolToggler.ts +0 -12
  44. package/src/client/CodeEditor/InteractiveWidgets/colorPicker.ts +0 -68
  45. package/src/client/CodeEditor/InteractiveWidgets/colorsInTextPlugin.ts +0 -174
  46. package/src/client/CodeEditor/InteractiveWidgets/highlightWidgets.ts +0 -79
  47. package/src/client/CodeEditor/InteractiveWidgets/index.ts +0 -44
  48. package/src/client/CodeEditor/InteractiveWidgets/markdownCheckboxToggler.ts +0 -12
  49. package/src/client/CodeEditor/InteractiveWidgets/numberDragger.ts +0 -20
  50. package/src/client/CodeEditor/InteractiveWidgets/rotateWidget.ts +0 -143
  51. package/src/client/CodeEditor/InteractiveWidgets/urlClicker.test.ts +0 -48
  52. package/src/client/CodeEditor/InteractiveWidgets/urlClicker.ts +0 -12
  53. package/src/client/CodeEditor/InteractiveWidgets/vec2Slider.ts +0 -25
  54. package/src/client/CodeEditor/basicSetup.ts +0 -73
  55. package/src/client/CodeEditor/getOrCreateEditor.tsx +0 -615
  56. package/src/client/CodeEditor/index.tsx +0 -202
  57. package/src/client/CodeEditor/json1PresenceBroadcast.ts +0 -41
  58. package/src/client/CodeEditor/json1PresenceDisplay.ts +0 -350
  59. package/src/client/CodeEditor/rainbowBrackets.ts +0 -122
  60. package/src/client/CodeEditor/style.scss +0 -156
  61. package/src/client/CodeEditor/typescriptExtension/worker.ts +0 -32
  62. package/src/client/CodeErrorOverlay/index.tsx +0 -77
  63. package/src/client/CodeErrorOverlay/style.scss +0 -33
  64. package/src/client/Fonts/fonts.ts +0 -8
  65. package/src/client/Icons/AdjustmentSVG.tsx +0 -19
  66. package/src/client/Icons/BugSVG.tsx +0 -20
  67. package/src/client/Icons/CloseSVG.tsx +0 -19
  68. package/src/client/Icons/CssSVG.tsx +0 -16
  69. package/src/client/Icons/DirectoryArrowSVG.tsx +0 -19
  70. package/src/client/Icons/EditSVG.tsx +0 -19
  71. package/src/client/Icons/FileSVG.tsx +0 -19
  72. package/src/client/Icons/FolderSVG.tsx +0 -20
  73. package/src/client/Icons/GearSVG.tsx +0 -16
  74. package/src/client/Icons/HtmlSVG.tsx +0 -16
  75. package/src/client/Icons/JavaScriptSVG.tsx +0 -16
  76. package/src/client/Icons/JsonSVG.tsx +0 -16
  77. package/src/client/Icons/MarkdownSVG.tsx +0 -16
  78. package/src/client/Icons/MicSVG.tsx +0 -25
  79. package/src/client/Icons/NewSVG.tsx +0 -19
  80. package/src/client/Icons/PinSVG.tsx +0 -14
  81. package/src/client/Icons/PlaySVG.tsx +0 -16
  82. package/src/client/Icons/QuestionMarkSVG.tsx +0 -18
  83. package/src/client/Icons/ReactSVG.tsx +0 -16
  84. package/src/client/Icons/SearchSVG.tsx +0 -20
  85. package/src/client/Icons/SparklesSVG.tsx +0 -23
  86. package/src/client/Icons/SplitEditorSVG.tsx +0 -34
  87. package/src/client/Icons/StopSVG.tsx +0 -15
  88. package/src/client/Icons/SvelteSVG.tsx +0 -16
  89. package/src/client/Icons/TrashSVG.tsx +0 -19
  90. package/src/client/Icons/TypeScriptSVG.tsx +0 -16
  91. package/src/client/Icons/index.tsx +0 -24
  92. package/src/client/ImageViewer/index.tsx +0 -91
  93. package/src/client/ImageViewer/style.scss +0 -41
  94. package/src/client/PresenceNotifications/PresenceNotifications.test.ts +0 -134
  95. package/src/client/PresenceNotifications/index.tsx +0 -158
  96. package/src/client/PresenceNotifications/style.scss +0 -17
  97. package/src/client/RunCodeWidget/index.tsx +0 -117
  98. package/src/client/RunCodeWidget/style.scss +0 -24
  99. package/src/client/SplitPaneResizeContext.tsx +0 -159
  100. package/src/client/TabList/Tab.tsx +0 -73
  101. package/src/client/TabList/index.tsx +0 -35
  102. package/src/client/TabList/style.scss +0 -51
  103. package/src/client/VZCodeContext/index.tsx +0 -29
  104. package/src/client/VZCodeContext/types.ts +0 -249
  105. package/src/client/VZCodeContext/useVZCodeState.ts +0 -584
  106. package/src/client/VZKeyboardShortcutsDoc.tsx +0 -148
  107. package/src/client/VZLeft.tsx +0 -28
  108. package/src/client/VZMiddle.tsx +0 -172
  109. package/src/client/VZResizer/index.tsx +0 -128
  110. package/src/client/VZResizer/styles.scss +0 -33
  111. package/src/client/VZRight.tsx +0 -113
  112. package/src/client/VZSettings.tsx +0 -275
  113. package/src/client/VZSidebar/AIChat/ChatInput.tsx +0 -196
  114. package/src/client/VZSidebar/AIChat/DiffView.scss +0 -136
  115. package/src/client/VZSidebar/AIChat/DiffView.tsx +0 -176
  116. package/src/client/VZSidebar/AIChat/Message.tsx +0 -143
  117. package/src/client/VZSidebar/AIChat/MessageList.tsx +0 -205
  118. package/src/client/VZSidebar/AIChat/StreamingMessage.tsx +0 -35
  119. package/src/client/VZSidebar/AIChat/ThinkingScratchpad.tsx +0 -156
  120. package/src/client/VZSidebar/AIChat/TypingIndicator.tsx +0 -19
  121. package/src/client/VZSidebar/AIChat/index.tsx +0 -273
  122. package/src/client/VZSidebar/AIChat/styles.scss +0 -627
  123. package/src/client/VZSidebar/CreateDirModal.tsx +0 -111
  124. package/src/client/VZSidebar/CreateFileModal.tsx +0 -111
  125. package/src/client/VZSidebar/DeleteConfirmationModal.tsx +0 -76
  126. package/src/client/VZSidebar/DirectoryListing.tsx +0 -89
  127. package/src/client/VZSidebar/EmptyState.tsx +0 -11
  128. package/src/client/VZSidebar/FileListing.tsx +0 -91
  129. package/src/client/VZSidebar/FileTypeIcon.tsx +0 -49
  130. package/src/client/VZSidebar/Item.tsx +0 -237
  131. package/src/client/VZSidebar/Listing.tsx +0 -47
  132. package/src/client/VZSidebar/Search.tsx +0 -527
  133. package/src/client/VZSidebar/VisualEditor.tsx +0 -295
  134. package/src/client/VZSidebar/VoiceChatModal.tsx +0 -121
  135. package/src/client/VZSidebar/aiCopyPaste.ts +0 -199
  136. package/src/client/VZSidebar/index.tsx +0 -728
  137. package/src/client/VZSidebar/styles.scss +0 -612
  138. package/src/client/VZSidebar/useDragAndDrop.tsx +0 -408
  139. package/src/client/bootstrap.ts +0 -26
  140. package/src/client/buildWorker.ts +0 -3
  141. package/src/client/featureFlags.ts +0 -8
  142. package/src/client/generateRequestId.ts +0 -6
  143. package/src/client/getFileTree.ts +0 -53
  144. package/src/client/index.ts +0 -19
  145. package/src/client/main.jsx +0 -10
  146. package/src/client/presenceColor.ts +0 -8
  147. package/src/client/shouldTriggerRun.ts +0 -31
  148. package/src/client/sortFileTree.ts +0 -21
  149. package/src/client/tabsSearchParameters.test.ts +0 -79
  150. package/src/client/tabsSearchParameters.ts +0 -137
  151. package/src/client/themes/index.ts +0 -7
  152. package/src/client/themes/themes.ts +0 -77
  153. package/src/client/themes/uiwImports.ts +0 -32
  154. package/src/client/themes/useDynamicTheme.ts +0 -29
  155. package/src/client/themes/vizhubTheme/colors.ts +0 -80
  156. package/src/client/themes/vizhubTheme/index.ts +0 -193
  157. package/src/client/useActions.ts +0 -288
  158. package/src/client/useESLint/index.ts +0 -72
  159. package/src/client/useESLint/worker.ts +0 -113
  160. package/src/client/useEditorCache.ts +0 -35
  161. package/src/client/useFileCRUD.ts +0 -228
  162. package/src/client/useKeyboardShortcuts.ts +0 -451
  163. package/src/client/useOpenDirectories.ts +0 -99
  164. package/src/client/usePresenceAutoFollow.ts +0 -85
  165. package/src/client/usePrettier/index.ts +0 -178
  166. package/src/client/usePrettier/worker.ts +0 -109
  167. package/src/client/useRunCode.tsx +0 -15
  168. package/src/client/useRuntimeError.ts +0 -32
  169. package/src/client/useSubmitOperation.ts +0 -15
  170. package/src/client/useURLSync.ts +0 -137
  171. package/src/client/usernameLocalStorage.ts +0 -43
  172. package/src/client/utils/fileExtension.ts +0 -10
  173. package/src/client/utils/isImageFile.ts +0 -12
  174. package/src/client/vzReducer/aiChatReducer.ts +0 -44
  175. package/src/client/vzReducer/closeTabReducer.test.ts +0 -205
  176. package/src/client/vzReducer/closeTabsReducer.ts +0 -96
  177. package/src/client/vzReducer/createInitialState.ts +0 -38
  178. package/src/client/vzReducer/editorNoLongerWantsFocusReducer.ts +0 -9
  179. package/src/client/vzReducer/findPane.ts +0 -19
  180. package/src/client/vzReducer/index.ts +0 -250
  181. package/src/client/vzReducer/openTabReducer.test.ts +0 -127
  182. package/src/client/vzReducer/openTabReducer.ts +0 -74
  183. package/src/client/vzReducer/searchReducer.test.ts +0 -292
  184. package/src/client/vzReducer/searchReducer.ts +0 -181
  185. package/src/client/vzReducer/setActiveFileIdReducer.ts +0 -28
  186. package/src/client/vzReducer/setActiveFileLeftRightReducer.ts +0 -76
  187. package/src/client/vzReducer/setIsDocOpenReducer.ts +0 -9
  188. package/src/client/vzReducer/setIsSettingsOpenReducer.ts +0 -9
  189. package/src/client/vzReducer/setThemeReducer.ts +0 -9
  190. package/src/client/vzReducer/setUsernameReducer.ts +0 -9
  191. package/src/client/vzReducer/splitCurrentPaneReducer.ts +0 -66
  192. package/src/client/vzReducer/toggleAutoFollowReducer.ts +0 -12
  193. package/src/client/vzReducer/updatePane.ts +0 -40
  194. package/src/client/vzReducer/updatePresenceIndicatorReducer.ts +0 -30
  195. package/src/client/vzReducer/visualEditorReducer.ts +0 -9
  196. package/src/reactRouterExports.ts +0 -15
  197. package/src/runCode.ts +0 -27
  198. package/src/server/aiChatHandler/aiEditing.ts +0 -152
  199. package/src/server/aiChatHandler/chatOperations.ts +0 -510
  200. package/src/server/aiChatHandler/errorHandling.ts +0 -66
  201. package/src/server/aiChatHandler/index.ts +0 -200
  202. package/src/server/aiChatHandler/llmStreaming.ts +0 -419
  203. package/src/server/aiChatHandler/undoHandler.ts +0 -97
  204. package/src/server/aiChatHandler/validation.ts +0 -24
  205. package/src/server/computeInitialDocument.ts +0 -220
  206. package/src/server/generateAIResponse.ts +0 -188
  207. package/src/server/handleAIAssist.ts +0 -53
  208. package/src/server/handleAIChatUndo.ts +0 -2
  209. package/src/server/handleAICopilot.ts +0 -97
  210. package/src/server/index.ts +0 -388
  211. package/src/server/livekit.ts +0 -24
  212. package/src/server/prettier.ts +0 -115
  213. package/src/submitOperation.ts +0 -25
  214. package/src/types.ts +0 -205
  215. package/src/utils/fileDiff.ts +0 -117
  216. package/src/vite-env.d.ts +0 -10
  217. /package/{src/server/handleAIChatMessage.ts → dist/server/handleAIChatMessage.js} +0 -0
  218. /package/{src/server/isDirectory.ts → dist/server/isDirectory.js} +0 -0
@@ -1,510 +0,0 @@
1
- import {
2
- dateToTimestamp,
3
- generateRunId,
4
- } from '@vizhub/viz-utils';
5
- import { randomId } from '../../randomId.js';
6
- import { ShareDBDoc } from '../../types.js';
7
- import { diff } from '../../ot.js';
8
- import {
9
- VizChatId,
10
- VizContent,
11
- VizFileId,
12
- VizFiles,
13
- } from '@vizhub/viz-types';
14
-
15
- /**
16
- * Ensures the chats object exists in the ShareDB document
17
- */
18
- export const ensureChatsExist = (shareDBDoc) => {
19
- if (!shareDBDoc.data.chats) {
20
- const op = diff(shareDBDoc.data, {
21
- ...shareDBDoc.data,
22
- chats: {},
23
- });
24
- shareDBDoc.submitOp(op);
25
- }
26
- };
27
-
28
- /**
29
- * Ensures a specific chat exists in the ShareDB document
30
- */
31
- export const ensureChatExists = (
32
- shareDBDoc: ShareDBDoc<VizContent>,
33
- chatId: VizChatId,
34
- ) => {
35
- if (!shareDBDoc.data.chats[chatId]) {
36
- const op = diff(shareDBDoc.data, {
37
- ...shareDBDoc.data,
38
- chats: {
39
- ...shareDBDoc.data.chats,
40
- [chatId]: {
41
- id: chatId,
42
- messages: [],
43
- createdAt: dateToTimestamp(new Date()),
44
- updatedAt: dateToTimestamp(new Date()),
45
- },
46
- },
47
- });
48
- shareDBDoc.submitOp(op);
49
- }
50
- };
51
-
52
- /**
53
- * Adds a user message to the chat
54
- */
55
- export const addUserMessage = (
56
- shareDBDoc: ShareDBDoc<VizContent>,
57
- chatId: VizChatId,
58
- content: string,
59
- ) => {
60
- const userMessage = {
61
- id: `user-${Date.now()}`,
62
- role: 'user',
63
- content: content,
64
- timestamp: dateToTimestamp(new Date()),
65
- };
66
-
67
- const userMessageOp = diff(shareDBDoc.data, {
68
- ...shareDBDoc.data,
69
- chats: {
70
- ...shareDBDoc.data.chats,
71
- [chatId]: {
72
- ...shareDBDoc.data.chats[chatId],
73
- messages: [
74
- ...shareDBDoc.data.chats[chatId].messages,
75
- userMessage,
76
- ],
77
- updatedAt: dateToTimestamp(new Date()),
78
- },
79
- },
80
- });
81
- shareDBDoc.submitOp(userMessageOp);
82
-
83
- return userMessage;
84
- };
85
-
86
- /**
87
- * Updates AI status in the chat
88
- */
89
- export const updateAIStatus = (
90
- shareDBDoc: ShareDBDoc<VizContent>,
91
- chatId: VizChatId,
92
- status: string,
93
- ) => {
94
- const op = diff(shareDBDoc.data, {
95
- ...shareDBDoc.data,
96
- chats: {
97
- ...shareDBDoc.data.chats,
98
- [chatId]: {
99
- ...shareDBDoc.data.chats[chatId],
100
- aiStatus: status,
101
- },
102
- },
103
- });
104
- shareDBDoc.submitOp(op);
105
- };
106
-
107
- /**
108
- * Updates AI scratchpad content
109
- */
110
- export const updateAIScratchpad = (
111
- shareDBDoc: ShareDBDoc<VizContent>,
112
- chatId: VizChatId,
113
- content: string,
114
- ) => {
115
- const op = diff(shareDBDoc.data, {
116
- ...shareDBDoc.data,
117
- chats: {
118
- ...shareDBDoc.data.chats,
119
- [chatId]: {
120
- ...shareDBDoc.data.chats[chatId],
121
- aiScratchpad: content,
122
- },
123
- },
124
- });
125
-
126
- // op is `null` if there are no changes
127
- // This can happen if the content is the same as before
128
- // In that case, we don't need to submit an operation
129
- if (op) {
130
- shareDBDoc.submitOp(op);
131
- }
132
- };
133
-
134
- /**
135
- * Clears AI scratchpad and updates status
136
- */
137
- export const clearAIScratchpadAndStatus = (
138
- shareDBDoc: ShareDBDoc<VizContent>,
139
- chatId: VizChatId,
140
- status: string,
141
- ) => {
142
- const op = diff(shareDBDoc.data, {
143
- ...shareDBDoc.data,
144
- chats: {
145
- ...shareDBDoc.data.chats,
146
- [chatId]: {
147
- ...shareDBDoc.data.chats[chatId],
148
- aiScratchpad: undefined,
149
- aiStatus: status,
150
- },
151
- },
152
- });
153
- shareDBDoc.submitOp(op);
154
- };
155
-
156
- /**
157
- * Creates an initial empty AI message for streaming
158
- */
159
- export const createAIMessage = (
160
- shareDBDoc: ShareDBDoc<VizContent>,
161
- chatId: VizChatId,
162
- ) => {
163
- const aiMessage = {
164
- id: `assistant-${Date.now()}`,
165
- role: 'assistant',
166
- content: '',
167
- timestamp: dateToTimestamp(new Date()),
168
- };
169
-
170
- const messageOp = diff(shareDBDoc.data, {
171
- ...shareDBDoc.data,
172
- chats: {
173
- ...shareDBDoc.data.chats,
174
- [chatId]: {
175
- ...shareDBDoc.data.chats[chatId],
176
- messages: [
177
- ...shareDBDoc.data.chats[chatId].messages,
178
- aiMessage,
179
- ],
180
- updatedAt: dateToTimestamp(new Date()),
181
- },
182
- },
183
- });
184
- shareDBDoc.submitOp(messageOp);
185
-
186
- return aiMessage.id;
187
- };
188
-
189
- /**
190
- * Updates the content of an AI message during streaming
191
- */
192
- export const updateAIMessageContent = (
193
- shareDBDoc: ShareDBDoc<VizContent>,
194
- chatId: VizChatId,
195
- messageId: string,
196
- content: string,
197
- ) => {
198
- const chat = shareDBDoc.data.chats[chatId];
199
- const messageIndex = chat.messages.findIndex(
200
- (msg) => msg.id === messageId,
201
- );
202
-
203
- if (messageIndex === -1) {
204
- console.warn(
205
- `AI message with id ${messageId} not found`,
206
- );
207
- return;
208
- }
209
-
210
- const updatedMessages = [...chat.messages];
211
- updatedMessages[messageIndex] = {
212
- ...updatedMessages[messageIndex],
213
- content,
214
- };
215
-
216
- const messageOp = diff(shareDBDoc.data, {
217
- ...shareDBDoc.data,
218
- chats: {
219
- ...shareDBDoc.data.chats,
220
- [chatId]: {
221
- ...chat,
222
- messages: updatedMessages,
223
- updatedAt: dateToTimestamp(new Date()),
224
- },
225
- },
226
- });
227
- shareDBDoc.submitOp(messageOp);
228
- };
229
-
230
- /**
231
- * Sets the AI status for a chat
232
- */
233
- export const setAIStatus = (
234
- shareDBDoc: ShareDBDoc<VizContent>,
235
- chatId: VizChatId,
236
- status: string | undefined,
237
- ) => {
238
- const op = diff(shareDBDoc.data, {
239
- ...shareDBDoc.data,
240
- chats: {
241
- ...shareDBDoc.data.chats,
242
- [chatId]: {
243
- ...shareDBDoc.data.chats[chatId],
244
- aiStatus: status,
245
- updatedAt: dateToTimestamp(new Date()),
246
- },
247
- },
248
- });
249
- shareDBDoc.submitOp(op);
250
- };
251
-
252
- /**
253
- * Finalizes an AI message by clearing temporary fields
254
- */
255
- export const finalizeAIMessage = (
256
- shareDBDoc: ShareDBDoc<VizContent>,
257
- chatId: VizChatId,
258
- ) => {
259
- const op = diff(shareDBDoc.data, {
260
- ...shareDBDoc.data,
261
- chats: {
262
- ...shareDBDoc.data.chats,
263
- [chatId]: {
264
- ...shareDBDoc.data.chats[chatId],
265
- aiScratchpad: undefined,
266
- aiStatus: undefined,
267
- updatedAt: dateToTimestamp(new Date()),
268
- },
269
- },
270
- });
271
- shareDBDoc.submitOp(op);
272
- };
273
-
274
- /**
275
- * Adds diff data to the most recent AI message
276
- */
277
- export const addDiffToAIMessage = (
278
- shareDBDoc: ShareDBDoc<VizContent>,
279
- chatId: VizChatId,
280
- diffData: any,
281
- beforeFiles?: VizFiles, // Optional snapshot for undo functionality (legacy)
282
- beforeCommitId?: string, // Commit ID before AI changes for VizHub integration
283
- ) => {
284
- const chat = shareDBDoc.data.chats[chatId];
285
- const messages = [...chat.messages];
286
-
287
- // Find the most recent AI message
288
- const lastAIMessageIndex = messages.length - 1;
289
- if (
290
- lastAIMessageIndex >= 0 &&
291
- messages[lastAIMessageIndex].role === 'assistant'
292
- ) {
293
- const newMessage = {
294
- ...messages[lastAIMessageIndex],
295
- diffData,
296
- ...(beforeFiles && { beforeFiles }), // Add beforeFiles only if provided (legacy)
297
- ...(beforeCommitId && { beforeCommitId }), // Add beforeCommitId for VizHub integration
298
- };
299
- // Use type assertion to extend the message with diffData
300
- (messages[lastAIMessageIndex] as any) = newMessage;
301
-
302
- const messageOp = diff(shareDBDoc.data, {
303
- ...shareDBDoc.data,
304
- chats: {
305
- ...shareDBDoc.data.chats,
306
- [chatId]: {
307
- ...chat,
308
- messages,
309
- updatedAt: dateToTimestamp(new Date()),
310
- },
311
- },
312
- });
313
-
314
- shareDBDoc.submitOp(messageOp);
315
- }
316
- };
317
-
318
- /**
319
- * Adds an AI response message to the chat (legacy function, kept for compatibility)
320
- */
321
- export const addAIMessage = (
322
- shareDBDoc: ShareDBDoc<VizContent>,
323
- chatId: VizChatId,
324
- content?: string,
325
- ) => {
326
- const aiResponse = {
327
- id: Date.now() + 1,
328
- role: 'assistant',
329
- content: content || 'AI edit completed successfully.',
330
- timestamp: dateToTimestamp(new Date()),
331
- };
332
-
333
- const messageOp = diff(shareDBDoc.data, {
334
- ...shareDBDoc.data,
335
- chats: {
336
- ...shareDBDoc.data.chats,
337
- [chatId]: {
338
- ...shareDBDoc.data.chats[chatId],
339
- messages: [
340
- ...shareDBDoc.data.chats[chatId].messages,
341
- aiResponse,
342
- ],
343
- updatedAt: dateToTimestamp(new Date()),
344
- aiStatus: undefined,
345
- },
346
- },
347
- });
348
- shareDBDoc.submitOp(messageOp);
349
-
350
- return aiResponse;
351
- };
352
-
353
- /**
354
- * Updates files in the ShareDB document
355
- */
356
- export const updateFiles = (
357
- shareDBDoc: ShareDBDoc<VizContent>,
358
- files: VizFiles,
359
- ) => {
360
- const filesOp = diff(shareDBDoc.data, {
361
- ...shareDBDoc.data,
362
- files,
363
- });
364
- shareDBDoc.submitOp(filesOp);
365
- };
366
-
367
- /**
368
- * Finds a file ID by searching for a matching file name
369
- */
370
- export const resolveFileId = (
371
- fileName: string,
372
- shareDBDoc: any,
373
- ) => {
374
- const files = shareDBDoc.data.files;
375
-
376
- // Search through all files to find matching name
377
- for (const [fileId, file] of Object.entries(files)) {
378
- if ((file as any).name === fileName) {
379
- return fileId;
380
- }
381
- }
382
-
383
- // If file doesn't exist, return null
384
- return null;
385
- };
386
-
387
- /**
388
- * Creates a new file with a random ID
389
- */
390
- export const createNewFile = (
391
- shareDBDoc: ShareDBDoc<VizContent>,
392
- fileName: string,
393
- ) => {
394
- // Generate a new random file ID
395
- const newFileId = randomId();
396
-
397
- const newState = {
398
- ...shareDBDoc.data,
399
- files: {
400
- ...shareDBDoc.data.files,
401
- [newFileId]: {
402
- name: fileName,
403
- text: '',
404
- },
405
- },
406
- };
407
-
408
- const op = diff(shareDBDoc.data, newState);
409
- shareDBDoc.submitOp(op);
410
- return newFileId;
411
- };
412
-
413
- /**
414
- * Ensures a file exists, creating it if necessary
415
- */
416
- export const ensureFileExists = (shareDBDoc, fileName) => {
417
- let fileId = resolveFileId(fileName, shareDBDoc);
418
-
419
- if (!fileId) {
420
- // File doesn't exist, create it
421
- fileId = createNewFile(shareDBDoc, fileName);
422
- }
423
-
424
- return fileId;
425
- };
426
-
427
- /**
428
- * Clears the content of a file
429
- */
430
- export const clearFileContent = (
431
- shareDBDoc: ShareDBDoc<VizContent>,
432
- fileId: VizFileId,
433
- ) => {
434
- const currentFile = shareDBDoc.data.files[fileId];
435
-
436
- if (currentFile && currentFile.text) {
437
- // Clear the file content
438
- const newState = {
439
- ...shareDBDoc.data,
440
- files: {
441
- ...shareDBDoc.data.files,
442
- [fileId]: {
443
- ...currentFile,
444
- text: '',
445
- },
446
- },
447
- };
448
-
449
- const op = diff(shareDBDoc.data, newState);
450
- shareDBDoc.submitOp(op);
451
- }
452
- };
453
-
454
- /**
455
- * Appends a line to a file using OT operations
456
- */
457
- export const appendLineToFile = (
458
- shareDBDoc: ShareDBDoc<VizContent>,
459
- fileId: VizFileId,
460
- line: string,
461
- ) => {
462
- const currentFile = shareDBDoc.data.files[fileId];
463
- const currentContent = currentFile?.text || '';
464
- const newContent = currentContent + line + '\n';
465
-
466
- const newDocState = {
467
- ...shareDBDoc.data,
468
- files: {
469
- ...shareDBDoc.data.files,
470
- [fileId]: {
471
- ...currentFile,
472
- text: newContent,
473
- },
474
- },
475
- };
476
-
477
- shareDBDoc.submitOp(diff(shareDBDoc.data, newDocState));
478
- };
479
-
480
- /**
481
- * Undoes the last AI edit by restoring files and removing the AI message
482
- */
483
- export const undoAIEdit = (
484
- shareDBDoc: ShareDBDoc<VizContent>,
485
- chatId: VizChatId,
486
- messageId: string,
487
- beforeFiles: VizFiles,
488
- ) => {
489
- const chat = shareDBDoc.data.chats[chatId];
490
- const messages = chat.messages.filter(
491
- (msg) => msg.id !== messageId,
492
- );
493
-
494
- const op = diff(shareDBDoc.data, {
495
- ...shareDBDoc.data,
496
- files: beforeFiles,
497
- chats: {
498
- ...shareDBDoc.data.chats,
499
- [chatId]: {
500
- ...chat,
501
- messages,
502
- updatedAt: dateToTimestamp(new Date()),
503
- },
504
- },
505
- // Trigger a re-run
506
- runId: generateRunId(),
507
- });
508
-
509
- shareDBDoc.submitOp(op);
510
- };
@@ -1,66 +0,0 @@
1
- import { dateToTimestamp } from '@vizhub/viz-utils';
2
- import { diff } from '../../ot.js';
3
-
4
- /**
5
- * Handles errors by adding an error message to the chat and clearing AI state
6
- */
7
- export const handleError = (
8
- shareDBDoc,
9
- chatId,
10
- error,
11
- res,
12
- ) => {
13
- console.error('[handleAIChatMessage] error:', error);
14
-
15
- // Clear scratchpad and add error message on error
16
- try {
17
- const errorResponse = {
18
- id: `error-${Date.now()}`,
19
- role: 'assistant',
20
- content:
21
- 'Sorry, I encountered an error while processing your message. Please try again.',
22
- timestamp: dateToTimestamp(new Date()),
23
- };
24
-
25
- const errorOp = diff(shareDBDoc.data, {
26
- ...shareDBDoc.data,
27
- chats: {
28
- ...shareDBDoc.data.chats,
29
- [chatId]: {
30
- ...shareDBDoc.data.chats[chatId],
31
- messages: [
32
- ...shareDBDoc.data.chats[chatId].messages,
33
- errorResponse,
34
- ],
35
- aiScratchpad: undefined,
36
- aiStatus: undefined,
37
- updatedAt: dateToTimestamp(new Date()),
38
- },
39
- },
40
- });
41
- shareDBDoc.submitOp(errorOp);
42
- } catch (opError) {
43
- console.error(
44
- '[handleAIChatMessage] error handling error state:',
45
- opError,
46
- );
47
- }
48
-
49
- if (res) {
50
- res.status(500).json({
51
- error: 'Internal server error',
52
- message: error.message,
53
- });
54
- }
55
- };
56
-
57
- /**
58
- * Handles errors in background processing (without HTTP response)
59
- */
60
- export const handleBackgroundError = (
61
- shareDBDoc,
62
- chatId,
63
- error,
64
- ) => {
65
- handleError(shareDBDoc, chatId, error, null);
66
- };