vzcode 2.2.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 (220) 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-CpxqGhXj.js → index-DuUjtrt6.js} +150 -150
  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 +22 -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/MicOffSVG.tsx +0 -35
  79. package/src/client/Icons/MicSVG.tsx +0 -25
  80. package/src/client/Icons/NewSVG.tsx +0 -19
  81. package/src/client/Icons/PinSVG.tsx +0 -14
  82. package/src/client/Icons/PlaySVG.tsx +0 -16
  83. package/src/client/Icons/QuestionMarkSVG.tsx +0 -18
  84. package/src/client/Icons/ReactSVG.tsx +0 -16
  85. package/src/client/Icons/SearchSVG.tsx +0 -20
  86. package/src/client/Icons/SparklesSVG.tsx +0 -23
  87. package/src/client/Icons/SplitEditorSVG.tsx +0 -34
  88. package/src/client/Icons/StopSVG.tsx +0 -15
  89. package/src/client/Icons/SvelteSVG.tsx +0 -16
  90. package/src/client/Icons/TrashSVG.tsx +0 -19
  91. package/src/client/Icons/TypeScriptSVG.tsx +0 -16
  92. package/src/client/Icons/index.tsx +0 -26
  93. package/src/client/ImageViewer/index.tsx +0 -91
  94. package/src/client/ImageViewer/style.scss +0 -41
  95. package/src/client/PresenceNotifications/PresenceNotifications.test.ts +0 -134
  96. package/src/client/PresenceNotifications/index.tsx +0 -158
  97. package/src/client/PresenceNotifications/style.scss +0 -17
  98. package/src/client/RunCodeWidget/index.tsx +0 -117
  99. package/src/client/RunCodeWidget/style.scss +0 -24
  100. package/src/client/SplitPaneResizeContext.tsx +0 -159
  101. package/src/client/TabList/Tab.tsx +0 -73
  102. package/src/client/TabList/index.tsx +0 -35
  103. package/src/client/TabList/style.scss +0 -51
  104. package/src/client/VZCodeContext/index.tsx +0 -29
  105. package/src/client/VZCodeContext/types.ts +0 -249
  106. package/src/client/VZCodeContext/useVZCodeState.ts +0 -584
  107. package/src/client/VZKeyboardShortcutsDoc.tsx +0 -148
  108. package/src/client/VZLeft.tsx +0 -28
  109. package/src/client/VZMiddle.tsx +0 -172
  110. package/src/client/VZResizer/index.tsx +0 -128
  111. package/src/client/VZResizer/styles.scss +0 -33
  112. package/src/client/VZRight.tsx +0 -113
  113. package/src/client/VZSettings.tsx +0 -275
  114. package/src/client/VZSidebar/AIChat/ChatInput.tsx +0 -239
  115. package/src/client/VZSidebar/AIChat/DiffView.scss +0 -136
  116. package/src/client/VZSidebar/AIChat/DiffView.tsx +0 -176
  117. package/src/client/VZSidebar/AIChat/Message.tsx +0 -143
  118. package/src/client/VZSidebar/AIChat/MessageList.tsx +0 -205
  119. package/src/client/VZSidebar/AIChat/StreamingMessage.tsx +0 -35
  120. package/src/client/VZSidebar/AIChat/ThinkingScratchpad.tsx +0 -156
  121. package/src/client/VZSidebar/AIChat/TypingIndicator.tsx +0 -19
  122. package/src/client/VZSidebar/AIChat/index.tsx +0 -273
  123. package/src/client/VZSidebar/AIChat/styles.scss +0 -627
  124. package/src/client/VZSidebar/AIChat/useSpeechRecognition.ts +0 -117
  125. package/src/client/VZSidebar/CreateDirModal.tsx +0 -111
  126. package/src/client/VZSidebar/CreateFileModal.tsx +0 -111
  127. package/src/client/VZSidebar/DeleteConfirmationModal.tsx +0 -76
  128. package/src/client/VZSidebar/DirectoryListing.tsx +0 -89
  129. package/src/client/VZSidebar/EmptyState.tsx +0 -11
  130. package/src/client/VZSidebar/FileListing.tsx +0 -91
  131. package/src/client/VZSidebar/FileTypeIcon.tsx +0 -49
  132. package/src/client/VZSidebar/Item.tsx +0 -237
  133. package/src/client/VZSidebar/Listing.tsx +0 -47
  134. package/src/client/VZSidebar/Search.tsx +0 -527
  135. package/src/client/VZSidebar/VisualEditor.tsx +0 -282
  136. package/src/client/VZSidebar/VoiceChatModal.tsx +0 -121
  137. package/src/client/VZSidebar/aiCopyPaste.ts +0 -199
  138. package/src/client/VZSidebar/index.tsx +0 -728
  139. package/src/client/VZSidebar/styles.scss +0 -612
  140. package/src/client/VZSidebar/useDragAndDrop.tsx +0 -408
  141. package/src/client/bootstrap.ts +0 -26
  142. package/src/client/buildWorker.ts +0 -3
  143. package/src/client/featureFlags.ts +0 -8
  144. package/src/client/generateRequestId.ts +0 -6
  145. package/src/client/getFileTree.ts +0 -53
  146. package/src/client/index.ts +0 -19
  147. package/src/client/main.jsx +0 -10
  148. package/src/client/presenceColor.ts +0 -8
  149. package/src/client/shouldTriggerRun.ts +0 -31
  150. package/src/client/sortFileTree.ts +0 -21
  151. package/src/client/tabsSearchParameters.test.ts +0 -79
  152. package/src/client/tabsSearchParameters.ts +0 -137
  153. package/src/client/themes/index.ts +0 -7
  154. package/src/client/themes/themes.ts +0 -77
  155. package/src/client/themes/uiwImports.ts +0 -32
  156. package/src/client/themes/useDynamicTheme.ts +0 -29
  157. package/src/client/themes/vizhubTheme/colors.ts +0 -80
  158. package/src/client/themes/vizhubTheme/index.ts +0 -193
  159. package/src/client/useActions.ts +0 -288
  160. package/src/client/useESLint/index.ts +0 -72
  161. package/src/client/useESLint/worker.ts +0 -113
  162. package/src/client/useEditorCache.ts +0 -35
  163. package/src/client/useFileCRUD.ts +0 -228
  164. package/src/client/useKeyboardShortcuts.ts +0 -451
  165. package/src/client/useOpenDirectories.ts +0 -99
  166. package/src/client/usePresenceAutoFollow.ts +0 -85
  167. package/src/client/usePrettier/index.ts +0 -178
  168. package/src/client/usePrettier/worker.ts +0 -109
  169. package/src/client/useRunCode.tsx +0 -15
  170. package/src/client/useRuntimeError.ts +0 -32
  171. package/src/client/useSubmitOperation.ts +0 -15
  172. package/src/client/useURLSync.ts +0 -137
  173. package/src/client/usernameLocalStorage.ts +0 -43
  174. package/src/client/utils/fileExtension.ts +0 -10
  175. package/src/client/utils/isImageFile.ts +0 -12
  176. package/src/client/vzReducer/aiChatReducer.ts +0 -44
  177. package/src/client/vzReducer/closeTabReducer.test.ts +0 -205
  178. package/src/client/vzReducer/closeTabsReducer.ts +0 -96
  179. package/src/client/vzReducer/createInitialState.ts +0 -38
  180. package/src/client/vzReducer/editorNoLongerWantsFocusReducer.ts +0 -9
  181. package/src/client/vzReducer/findPane.ts +0 -19
  182. package/src/client/vzReducer/index.ts +0 -250
  183. package/src/client/vzReducer/openTabReducer.test.ts +0 -127
  184. package/src/client/vzReducer/openTabReducer.ts +0 -74
  185. package/src/client/vzReducer/searchReducer.test.ts +0 -292
  186. package/src/client/vzReducer/searchReducer.ts +0 -181
  187. package/src/client/vzReducer/setActiveFileIdReducer.ts +0 -28
  188. package/src/client/vzReducer/setActiveFileLeftRightReducer.ts +0 -76
  189. package/src/client/vzReducer/setIsDocOpenReducer.ts +0 -9
  190. package/src/client/vzReducer/setIsSettingsOpenReducer.ts +0 -9
  191. package/src/client/vzReducer/setThemeReducer.ts +0 -9
  192. package/src/client/vzReducer/setUsernameReducer.ts +0 -9
  193. package/src/client/vzReducer/splitCurrentPaneReducer.ts +0 -66
  194. package/src/client/vzReducer/toggleAutoFollowReducer.ts +0 -12
  195. package/src/client/vzReducer/updatePane.ts +0 -40
  196. package/src/client/vzReducer/updatePresenceIndicatorReducer.ts +0 -30
  197. package/src/client/vzReducer/visualEditorReducer.ts +0 -9
  198. package/src/reactRouterExports.ts +0 -15
  199. package/src/runCode.ts +0 -27
  200. package/src/server/aiChatHandler/aiEditing.ts +0 -152
  201. package/src/server/aiChatHandler/chatOperations.ts +0 -510
  202. package/src/server/aiChatHandler/errorHandling.ts +0 -66
  203. package/src/server/aiChatHandler/index.ts +0 -200
  204. package/src/server/aiChatHandler/llmStreaming.ts +0 -419
  205. package/src/server/aiChatHandler/undoHandler.ts +0 -97
  206. package/src/server/aiChatHandler/validation.ts +0 -24
  207. package/src/server/computeInitialDocument.ts +0 -220
  208. package/src/server/generateAIResponse.ts +0 -188
  209. package/src/server/handleAIAssist.ts +0 -53
  210. package/src/server/handleAIChatUndo.ts +0 -2
  211. package/src/server/handleAICopilot.ts +0 -97
  212. package/src/server/index.ts +0 -388
  213. package/src/server/livekit.ts +0 -24
  214. package/src/server/prettier.ts +0 -115
  215. package/src/submitOperation.ts +0 -25
  216. package/src/types.ts +0 -205
  217. package/src/utils/fileDiff.ts +0 -117
  218. package/src/vite-env.d.ts +0 -10
  219. /package/{src/server/handleAIChatMessage.ts → dist/server/handleAIChatMessage.js} +0 -0
  220. /package/{src/server/isDirectory.ts → dist/server/isDirectory.js} +0 -0
@@ -0,0 +1,66 @@
1
+ import { createTwoFilesPatch } from 'diff';
2
+ /**
3
+ * Generate a unified diff for a single file using the diff library
4
+ */
5
+ export function generateFileUnifiedDiff(fileId, fileName, beforeContent, afterContent) {
6
+ // Only generate diff if there are actual changes
7
+ if (beforeContent === afterContent) {
8
+ return '';
9
+ }
10
+ // Use the diff library's createTwoFilesPatch function to generate unified diff
11
+ const unifiedDiff = createTwoFilesPatch(fileName, fileName, beforeContent, afterContent, '', '', { context: 3 });
12
+ return unifiedDiff;
13
+ }
14
+ /**
15
+ * Generate unified diffs for multiple files
16
+ */
17
+ export function generateFilesUnifiedDiff(beforeFiles, afterFiles) {
18
+ const result = {};
19
+ const allFileIds = new Set([
20
+ ...Object.keys(beforeFiles),
21
+ ...Object.keys(afterFiles),
22
+ ]);
23
+ for (const fileId of allFileIds) {
24
+ const beforeFile = beforeFiles[fileId];
25
+ const afterFile = afterFiles[fileId];
26
+ const beforeContent = beforeFile?.text || '';
27
+ const afterContent = afterFile?.text || '';
28
+ const fileName = afterFile?.name || beforeFile?.name || fileId;
29
+ const unifiedDiff = generateFileUnifiedDiff(fileId, fileName, beforeContent, afterContent);
30
+ // Only include files that have changes
31
+ if (unifiedDiff) {
32
+ result[fileId] = unifiedDiff;
33
+ }
34
+ }
35
+ return result;
36
+ }
37
+ /**
38
+ * Create a snapshot of current files for diff comparison
39
+ */
40
+ export function createFilesSnapshot(files) {
41
+ return JSON.parse(JSON.stringify(files));
42
+ }
43
+ /**
44
+ * Parse unified diff to extract basic statistics
45
+ */
46
+ export function parseUnifiedDiffStats(unifiedDiff) {
47
+ const lines = unifiedDiff.split('\n');
48
+ let additions = 0;
49
+ let deletions = 0;
50
+ for (const line of lines) {
51
+ if (line.startsWith('+') && !line.startsWith('+++')) {
52
+ additions++;
53
+ }
54
+ else if (line.startsWith('-') &&
55
+ !line.startsWith('---')) {
56
+ deletions++;
57
+ }
58
+ }
59
+ return { additions, deletions };
60
+ }
61
+ /**
62
+ * Combine multiple unified diffs into a single diff string
63
+ */
64
+ export function combineUnifiedDiffs(unifiedDiffs) {
65
+ return Object.values(unifiedDiffs).join('\n');
66
+ }
package/package.json CHANGED
@@ -1,13 +1,12 @@
1
1
  {
2
2
  "name": "vzcode",
3
- "version": "2.2.0",
3
+ "version": "2.3.0",
4
4
  "description": "Multiplayer code editor system",
5
5
  "main": "src/index.ts",
6
6
  "type": "module",
7
- "bin": "src/server/index.ts",
7
+ "bin": "dist/cli.js",
8
8
  "files": [
9
- "dist/**",
10
- "src/**"
9
+ "dist/**"
11
10
  ],
12
11
  "scripts": {
13
12
  "test": "vitest run",
@@ -15,8 +14,9 @@
15
14
  "prettier": "prettier {*.*,**/*.*} --write",
16
15
  "typecheck": "tsc --noEmit",
17
16
  "dev": "cross-env EDITOR_PORT=5173 concurrently \"npm run test-interactive\" \"vite\"",
18
- "build": "vite build",
19
- "build-release": "vite build --mode release",
17
+ "build": "vite build && npm run build:server",
18
+ "build:server": "tsc --project tsconfig.server.json",
19
+ "build-release": "vite build --mode release && npm run build:server",
20
20
  "preview": "concurrently \"npm run test-interactive\" \"vite preview\"",
21
21
  "tauri": "tauri",
22
22
  "tauri:dev": "tauri dev",
@@ -117,7 +117,7 @@
117
117
  "@codemirror/state": "^6.5.2",
118
118
  "@codemirror/theme-one-dark": "^6.1.3",
119
119
  "@codemirror/view": "^6.38.1",
120
- "@langchain/core": "^0.3.68",
120
+ "@langchain/core": "^0.3.70",
121
121
  "@langchain/openai": "^0.6.7",
122
122
  "@lezer/highlight": "^1.2.1",
123
123
  "@livekit/components-react": "^2.9.14",
@@ -127,17 +127,17 @@
127
127
  "@replit/codemirror-vscode-keymap": "^6.0.2",
128
128
  "@teamwork/websocket-json-stream": "^2.0.0",
129
129
  "@typescript/vfs": "^1.6.1",
130
- "@uiw/codemirror-theme-abcdef": "^4.24.2",
131
- "@uiw/codemirror-theme-dracula": "^4.24.2",
132
- "@uiw/codemirror-theme-eclipse": "^4.24.2",
133
- "@uiw/codemirror-theme-github": "^4.24.2",
134
- "@uiw/codemirror-theme-material": "^4.24.2",
135
- "@uiw/codemirror-theme-nord": "^4.24.2",
136
- "@uiw/codemirror-theme-okaidia": "^4.24.2",
137
- "@uiw/codemirror-theme-xcode": "^4.24.2",
138
- "@uiw/codemirror-themes": "^4.24.2",
130
+ "@uiw/codemirror-theme-abcdef": "^4.25.1",
131
+ "@uiw/codemirror-theme-dracula": "^4.25.1",
132
+ "@uiw/codemirror-theme-eclipse": "^4.25.1",
133
+ "@uiw/codemirror-theme-github": "^4.25.1",
134
+ "@uiw/codemirror-theme-material": "^4.25.1",
135
+ "@uiw/codemirror-theme-nord": "^4.25.1",
136
+ "@uiw/codemirror-theme-okaidia": "^4.25.1",
137
+ "@uiw/codemirror-theme-xcode": "^4.25.1",
138
+ "@uiw/codemirror-themes": "^4.25.1",
139
139
  "@valtown/codemirror-ts": "^2.3.1",
140
- "@vizhub/runtime": "^4.3.0",
140
+ "@vizhub/runtime": "^4.4.0",
141
141
  "@vizhub/viz-types": "^0.4.0",
142
142
  "@vizhub/viz-utils": "^1.4.0",
143
143
  "body-parser": "^2.2.0",
@@ -153,12 +153,12 @@
153
153
  "diff2html": "^3.4.52",
154
154
  "dotenv": "^17.2.1",
155
155
  "editcodewithai": "^2.3.0",
156
- "eslint-linter-browserify": "^9.32.0",
156
+ "eslint-linter-browserify": "^9.33.0",
157
157
  "express": "^5.1.0",
158
158
  "ignore": "^7.0.5",
159
159
  "json0-ot-diff": "^1.1.2",
160
160
  "jszip": "^3.10.1",
161
- "livekit-server-sdk": "^2.13.1",
161
+ "livekit-server-sdk": "^2.13.2",
162
162
  "llm-code-format": "^3.0.0",
163
163
  "lucide-react": "^0.539.0",
164
164
  "npm": "^11.5.2",
@@ -177,21 +177,21 @@
177
177
  "ws": "^8.18.3"
178
178
  },
179
179
  "devDependencies": {
180
- "@eslint/js": "^9.32.0",
180
+ "@eslint/js": "^9.33.0",
181
181
  "@tauri-apps/cli": "^2.7.1",
182
182
  "@types/react": "^18",
183
183
  "@types/react-dom": "^18",
184
184
  "@vitejs/plugin-react": "^5.0.0",
185
185
  "concurrently": "^9.2.0",
186
186
  "cross-env": "^10.0.0",
187
- "eslint": "^9.32.0",
187
+ "eslint": "^9.33.0",
188
188
  "globals": "^16.3.0",
189
189
  "npm-check-updates": "^18.0.2",
190
190
  "prettier": "^3.6.2",
191
191
  "sass": "^1.90.0",
192
192
  "ts-node": "^10.9.2",
193
193
  "typescript": "^5.9.2",
194
- "vite": "^7.1.1",
194
+ "vite": "^7.1.2",
195
195
  "vitest": "^3.2.4"
196
196
  },
197
197
  "optionalDependencies": {
@@ -1,42 +0,0 @@
1
- import { EditorView, keymap } from '@codemirror/view';
2
- import { ShareDBDoc, TabState } from '../../types';
3
- import { VizContent } from '@vizhub/viz-types';
4
-
5
- export const AIAssistCodeMirrorKeyMap = ({
6
- shareDBDoc,
7
- fileId,
8
- tabList,
9
- }: {
10
- shareDBDoc: ShareDBDoc<VizContent>;
11
- fileId: string;
12
- tabList: Array<TabState>;
13
- }) =>
14
- keymap.of([
15
- {
16
- key: 'control-m',
17
- run: (view: EditorView) => {
18
- // if (
19
- // shareDBDoc.data.aiStreams === undefined ||
20
- // shareDBDoc.data.aiStreams[mostRecentStreamId] ===
21
- // null ||
22
- // shareDBDoc.data.aiStreams[mostRecentStreamId]
23
- // ?.AIStreamStatus.serverIsRunning !== true
24
- // ) {
25
-
26
- // TODO handle starting it
27
- // startAIAssist({
28
- // view,
29
- // shareDBDoc,
30
- // fileId,
31
- // tabList,
32
- // });
33
-
34
- // TODO handle stopping it
35
- // } else {
36
- // haltAIAssist(shareDBDoc);
37
- // }
38
-
39
- return true;
40
- },
41
- },
42
- ]);
@@ -1,135 +0,0 @@
1
- import { useCallback, useContext, useState } from 'react';
2
- import { OverlayTrigger, Tooltip } from '../../bootstrap';
3
- import { PaneId, TabState } from '../../../types';
4
- import { VizFileId } from '@vizhub/viz-types';
5
- import { VZCodeContext } from '../../VZCodeContext';
6
- import {
7
- RequestId,
8
- generateRequestId,
9
- } from '../../generateRequestId';
10
- import { SparklesSVG } from '../../Icons';
11
- import { startAIAssist } from '../startAIAssist';
12
- import { editorCacheKey } from '../../useEditorCache';
13
- import { Spinner } from '../Spinner';
14
- import './style.scss';
15
-
16
- const enableStopGeneration = false;
17
-
18
- export const AIAssistWidget = ({
19
- aiAssistEndpoint,
20
- aiAssistOptions,
21
- aiAssistTooltipText = 'Start AI Assist',
22
- aiAssistClickOverride,
23
- activeFileId,
24
- tabList,
25
- paneId,
26
- }: {
27
- aiAssistEndpoint: string;
28
- aiAssistOptions: { [key: string]: string };
29
- aiAssistTooltipText?: string;
30
- aiAssistClickOverride?: () => void;
31
- activeFileId: VizFileId;
32
- tabList: Array<TabState>;
33
- paneId: PaneId;
34
- }) => {
35
- const {
36
- shareDBDoc,
37
- editorCache,
38
- runPrettierRef,
39
- runCodeRef,
40
- } = useContext(VZCodeContext);
41
-
42
- // The stream ID of the most recent request.
43
- // * If `null`, no request has been made yet.
44
- // * If non-null, a request has been made, and the
45
- // server is processing it.
46
- const [aiStreamId, setAiStreamId] =
47
- useState<RequestId | null>(null);
48
-
49
- const handleClick = useCallback(async () => {
50
- const isCurrentlyGenerationg = aiStreamId !== null;
51
- if (isCurrentlyGenerationg) {
52
- // TODO stop generation
53
- } else {
54
- const newAiStreamId = generateRequestId();
55
- setAiStreamId(newAiStreamId);
56
-
57
- // Wait for generation to finish.
58
- await startAIAssist({
59
- view: editorCache.get(
60
- editorCacheKey(activeFileId, paneId),
61
- ).editor,
62
- shareDBDoc,
63
- fileId: activeFileId,
64
- tabList,
65
- aiStreamId: newAiStreamId,
66
- aiAssistEndpoint,
67
- aiAssistOptions,
68
- });
69
-
70
- // Introduce a delay before running Prettier
71
- // and the code, to give the ShareDB ops a chance
72
- // to be applied and to propagate via WebSockets
73
- // to the client. This is necessary because sometimes
74
- // the ShareDB ops from the AI assist actually don't
75
- // reach the client until AFTER the response comes back
76
- // from `await startAIAssist`.
77
- await new Promise((resolve) =>
78
- setTimeout(resolve, 1000),
79
- );
80
-
81
- // Trigger a Prettier run after the AI Assist.
82
- const runPrettier = runPrettierRef.current;
83
- if (runPrettier !== null) {
84
- runPrettier();
85
- }
86
-
87
- // Run the code after the AI Assist.
88
- const runCode = runCodeRef.current;
89
- if (runCode !== null) {
90
- runCode();
91
- }
92
-
93
- // Handles the case that the user has started,
94
- // stopped, and started again before the first request
95
- // has finished, by comparing the current stream ID
96
- // with the stream ID that was active when the request
97
- // was started.
98
- setAiStreamId((currentAIStreamId) =>
99
- currentAIStreamId === newAiStreamId
100
- ? null
101
- : currentAIStreamId,
102
- );
103
- }
104
- }, [activeFileId, paneId, aiStreamId]);
105
-
106
- const showWidget = enableStopGeneration
107
- ? true
108
- : aiStreamId === null;
109
-
110
- return (
111
- <div className="vz-code-ai-assist-widget">
112
- {aiStreamId ? (
113
- <Spinner /> // Show spinner when aiStreamId is not null
114
- ) : (
115
- showWidget && (
116
- <OverlayTrigger
117
- placement="left"
118
- overlay={
119
- <Tooltip id="ai-assist-widget-tooltip">
120
- {aiAssistTooltipText}
121
- </Tooltip>
122
- }
123
- >
124
- <i
125
- className="icon-button icon-button-dark"
126
- onClick={aiAssistClickOverride || handleClick}
127
- >
128
- <SparklesSVG />
129
- </i>
130
- </OverlayTrigger>
131
- )
132
- )}
133
- </div>
134
- );
135
- };
@@ -1,47 +0,0 @@
1
- .vz-code-ai-assist-widget {
2
- position: absolute;
3
- // bottom: 32px;
4
- // right: 32px;
5
- bottom: 16px;
6
- right: 16px;
7
- color: var(--vh-color-caution-01);
8
- }
9
-
10
- .vh-spinner {
11
- display: flex;
12
- height: 100%;
13
- flex-direction: column;
14
- align-items: center;
15
- justify-content: center;
16
- overflow: hidden;
17
- }
18
-
19
- /* Fade in after a delay */
20
- /* https://stackoverflow.com/questions/29846224/css-animation-with-delay-and-opacity */
21
- .vh-spinner.fade-in svg {
22
- animation: 1s linear 0s normal forwards 1 fadein;
23
- }
24
-
25
- @keyframes fadein {
26
- 0% {
27
- opacity: 0;
28
- }
29
- 50% {
30
- opacity: 0;
31
- }
32
- 100% {
33
- opacity: 1;
34
- }
35
- }
36
-
37
- /* Infinite rotation */
38
- /* https://stackoverflow.com/questions/6410730/css-endless-rotation-animation */
39
- .vh-spinner-dots {
40
- animation: rotate 3s linear infinite;
41
- }
42
-
43
- @keyframes rotate {
44
- to {
45
- transform: rotate(360deg);
46
- }
47
- }
@@ -1,76 +0,0 @@
1
- // From https://github.com/vizhub-core/vizhub/commit/6ca078935b9771dc6e05a6065bcfd522a4724dcf
2
- import { useEffect, useState } from 'react';
3
- import './AIAssistWidget/style.scss';
4
-
5
- // const minRadius = 4;
6
- // const maxRadius = 10;
7
- // const numDots = 8;
8
- // const wheelRadius = 40;
9
- // const round = (number) => Math.floor(number * 100) / 100;
10
- // const dots = [];
11
- // for (let i = 0; i < numDots; i++) {
12
- // const angle = (i / numDots) * Math.PI * 2;
13
- // dots.push({
14
- // x: round(Math.cos(angle) * wheelRadius),
15
- // y: round(Math.sin(angle) * wheelRadius),
16
- // r: round(
17
- // minRadius +
18
- // (i / (numDots - 1)) * (maxRadius - minRadius),
19
- // ),
20
- // });
21
- // }
22
- // console.log(JSON.stringify(dots));
23
-
24
- // Hardcoded to avoid the computation.
25
- const dots = [
26
- { x: 40, y: 0, r: 4 },
27
- { x: 28.28, y: 28.28, r: 4.85 },
28
- { x: 0, y: 40, r: 5.71 },
29
- { x: -28.29, y: 28.28, r: 6.57 },
30
- { x: -40, y: 0, r: 7.42 },
31
- { x: -28.29, y: -28.29, r: 8.28 },
32
- { x: -0.01, y: -40, r: 9.14 },
33
- { x: 28.28, y: -28.29, r: 10 },
34
- ];
35
-
36
- // From https://bl.ocks.org/curran/685fa8300650c4324d571c6b0ecc55de
37
- // And vizhub-v2/packages/neoFrontend/src/LoadingScreen/index.js
38
- export const Spinner = ({
39
- height = 40,
40
- fill = 'currentcolor',
41
- fadeIn = true,
42
- }) => {
43
- const [show, setShow] = useState(false);
44
-
45
- // Avoid SSR of all the SVG elements.
46
- useEffect(() => {
47
- setShow(true);
48
- }, []);
49
-
50
- return (
51
- show && (
52
- <div
53
- className={`vh-spinner${fadeIn ? ' fade-in' : ''}`}
54
- >
55
- <svg
56
- height={height}
57
- viewBox="0 0 100 100"
58
- style={{ opacity: 1 }}
59
- >
60
- <g transform="translate(50, 50)" fill={fill}>
61
- <g className="vh-spinner-dots">
62
- {dots.map(({ x, y, r }, i) => (
63
- <circle
64
- key={i}
65
- cx={x}
66
- cy={y}
67
- r={r}
68
- ></circle>
69
- ))}
70
- </g>
71
- </g>
72
- </svg>
73
- </div>
74
- )
75
- );
76
- };
@@ -1,27 +0,0 @@
1
- import { VizFile } from '@vizhub/viz-types';
2
-
3
- const maxFileNameLength = 100;
4
- const maxFileTextLength = 2000;
5
-
6
- // Formats a file for the prompt.
7
- export const formatFile = (
8
- file: VizFile,
9
- truncateText = true,
10
- ) => {
11
- const nameTruncated = file.name
12
- ?.substring(0, maxFileNameLength)
13
- .trim();
14
-
15
- const textTruncated = (
16
- truncateText
17
- ? file.text?.substring(0, maxFileTextLength)
18
- : file.text
19
- ).trim();
20
-
21
- return [
22
- '`' + nameTruncated + '`:',
23
- '```',
24
- textTruncated,
25
- '```',
26
- ].join('\n');
27
- };
@@ -1,25 +0,0 @@
1
- // import { File } from '../../types';
2
-
3
- // const maxFileNameLength = 100;
4
- // const maxFileTextLength = 2000;
5
-
6
- // export const generateFilesContext = (
7
- // goodFiles: Array<File>,
8
- // ): string => {
9
- // const input = goodFiles
10
- // .map((file) => {
11
- // const nameSubstring = file.name
12
- // ?.substring(0, maxFileNameLength)
13
- // .trim();
14
-
15
- // const textSubstring = file.text
16
- // ?.substring(0, maxFileTextLength)
17
- // .trim();
18
-
19
- // // Generate Markdown that AI will understand.
20
- // return `File \`${nameSubstring}\`:\n\`\`\`${textSubstring}\`\`\``;
21
- // })
22
- // .join('\n\n');
23
-
24
- // return input;
25
- // };
@@ -1,2 +0,0 @@
1
- export { AIAssistWidget } from './AIAssistWidget';
2
- export { AIAssistCodeMirrorKeyMap } from './AIAssistCodeMirrorKeyMap';
@@ -1,95 +0,0 @@
1
- import { EditorView } from 'codemirror';
2
- import { ShareDBDoc, TabState } from '../../types';
3
- import {
4
- VizFile,
5
- VizFileId,
6
- VizContent,
7
- } from '@vizhub/viz-types';
8
- import { RequestId } from '../generateRequestId';
9
- import { formatFile } from './formatFile';
10
-
11
- const debug = false;
12
-
13
- // Enables inclusion of code from open tabs as context.
14
- const enableTabContext = false;
15
-
16
- const defaultAIAssistEndpoint = '/ai-assist';
17
-
18
- export const startAIAssist = async ({
19
- view,
20
- shareDBDoc,
21
- fileId,
22
- tabList,
23
- aiAssistEndpoint = defaultAIAssistEndpoint,
24
- aiAssistOptions = {},
25
- aiStreamId,
26
- }: {
27
- view: EditorView;
28
- shareDBDoc: ShareDBDoc<VizContent>;
29
- fileId: VizFileId;
30
- tabList: Array<TabState>;
31
- aiAssistEndpoint?: string;
32
- aiAssistOptions?: {
33
- [key: string]: any;
34
- };
35
- aiStreamId: RequestId;
36
- }) => {
37
- const currentFileName =
38
- shareDBDoc.data.files[fileId].name;
39
-
40
- // Generate a version of the current file with a
41
- // <FILL_ME> in the middle.
42
- const prefix = view.state.sliceDoc(
43
- 0,
44
- view.state.selection.main.from,
45
- );
46
- const suffix = view.state.sliceDoc(
47
- view.state.selection.main.to,
48
- );
49
- const combinedText = prefix + '<FILL_ME>' + suffix;
50
- const currentFile = {
51
- name: currentFileName,
52
- text: combinedText,
53
- };
54
-
55
- const insertionCursor = view.state.selection.main.to;
56
-
57
- // The main prompt is the current file, plus the context files.
58
- let inputText = formatFile(currentFile, false);
59
-
60
- if (enableTabContext) {
61
- inputText +=
62
- '\n\n' +
63
- tabList
64
- .filter((tabState) => tabState.fileId !== fileId)
65
- .map((tabState) =>
66
- formatFile(
67
- shareDBDoc.data.files[tabState.fileId],
68
- ),
69
- )
70
- .join('\n\n');
71
- }
72
-
73
- const response = await fetch(aiAssistEndpoint, {
74
- method: 'POST',
75
- headers: {
76
- 'Content-Type': 'application/json',
77
- },
78
- body: JSON.stringify({
79
- ...aiAssistOptions,
80
- inputText,
81
- fileId,
82
- insertionCursor,
83
- aiStreamId,
84
- }),
85
- });
86
-
87
- const responseJson = await response.json();
88
-
89
- if (responseJson.error) {
90
- console.error(
91
- '[startAIAssist] error from server:',
92
- responseJson.error,
93
- );
94
- }
95
- };