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
@@ -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.0.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,13 +153,14 @@
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
+ "lucide-react": "^0.539.0",
163
164
  "npm": "^11.5.2",
164
165
  "open": "^10.2.0",
165
166
  "prettier-plugin-svelte": "^3.4.0",
@@ -176,21 +177,21 @@
176
177
  "ws": "^8.18.3"
177
178
  },
178
179
  "devDependencies": {
179
- "@eslint/js": "^9.32.0",
180
+ "@eslint/js": "^9.33.0",
180
181
  "@tauri-apps/cli": "^2.7.1",
181
182
  "@types/react": "^18",
182
183
  "@types/react-dom": "^18",
183
184
  "@vitejs/plugin-react": "^5.0.0",
184
185
  "concurrently": "^9.2.0",
185
186
  "cross-env": "^10.0.0",
186
- "eslint": "^9.32.0",
187
+ "eslint": "^9.33.0",
187
188
  "globals": "^16.3.0",
188
189
  "npm-check-updates": "^18.0.2",
189
190
  "prettier": "^3.6.2",
190
191
  "sass": "^1.90.0",
191
192
  "ts-node": "^10.9.2",
192
193
  "typescript": "^5.9.2",
193
- "vite": "^7.1.1",
194
+ "vite": "^7.1.2",
194
195
  "vitest": "^3.2.4"
195
196
  },
196
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
- };