vzcode 2.3.0 → 2.4.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.
- package/package.json +3 -2
- package/src/cli.ts +208 -0
- package/src/client/AIAssist/AIAssistCodeMirrorKeyMap.ts +42 -0
- package/src/client/AIAssist/AIAssistWidget/index.tsx +135 -0
- package/src/client/AIAssist/AIAssistWidget/style.scss +47 -0
- package/src/client/AIAssist/Spinner.jsx +76 -0
- package/src/client/AIAssist/formatFile.ts +27 -0
- package/src/client/AIAssist/generateFilesContext.ts +25 -0
- package/src/client/AIAssist/index.ts +2 -0
- package/src/client/AIAssist/startAIAssist.ts +95 -0
- package/src/client/App/index.tsx +152 -0
- package/src/client/App/style.scss +82 -0
- package/src/client/App/usePending.ts +51 -0
- package/src/client/App/useShareDB.ts +161 -0
- package/src/client/CodeEditor/Copilot/index.ts +74 -0
- package/src/client/CodeEditor/InteractiveWidgets/boolToggler.ts +12 -0
- package/src/client/CodeEditor/InteractiveWidgets/colorPicker.ts +68 -0
- package/src/client/CodeEditor/InteractiveWidgets/colorsInTextPlugin.ts +174 -0
- package/src/client/CodeEditor/InteractiveWidgets/highlightWidgets.ts +79 -0
- package/src/client/CodeEditor/InteractiveWidgets/index.ts +44 -0
- package/src/client/CodeEditor/InteractiveWidgets/markdownCheckboxToggler.ts +12 -0
- package/src/client/CodeEditor/InteractiveWidgets/numberDragger.ts +20 -0
- package/src/client/CodeEditor/InteractiveWidgets/rotateWidget.ts +143 -0
- package/src/client/CodeEditor/InteractiveWidgets/urlClicker.test.ts +48 -0
- package/src/client/CodeEditor/InteractiveWidgets/urlClicker.ts +12 -0
- package/src/client/CodeEditor/InteractiveWidgets/vec2Slider.ts +25 -0
- package/src/client/CodeEditor/basicSetup.ts +73 -0
- package/src/client/CodeEditor/getOrCreateEditor.tsx +615 -0
- package/src/client/CodeEditor/index.tsx +202 -0
- package/src/client/CodeEditor/json1PresenceBroadcast.ts +41 -0
- package/src/client/CodeEditor/json1PresenceDisplay.ts +350 -0
- package/src/client/CodeEditor/rainbowBrackets.ts +122 -0
- package/src/client/CodeEditor/style.scss +156 -0
- package/src/client/CodeEditor/typescriptExtension/worker.ts +32 -0
- package/src/client/CodeErrorOverlay/index.tsx +77 -0
- package/src/client/CodeErrorOverlay/style.scss +33 -0
- package/src/client/Fonts/fonts.ts +8 -0
- package/src/client/Icons/AdjustmentSVG.tsx +19 -0
- package/src/client/Icons/BugSVG.tsx +20 -0
- package/src/client/Icons/CloseSVG.tsx +19 -0
- package/src/client/Icons/CssSVG.tsx +16 -0
- package/src/client/Icons/DirectoryArrowSVG.tsx +19 -0
- package/src/client/Icons/EditSVG.tsx +19 -0
- package/src/client/Icons/FileSVG.tsx +19 -0
- package/src/client/Icons/FolderSVG.tsx +20 -0
- package/src/client/Icons/GearSVG.tsx +16 -0
- package/src/client/Icons/HtmlSVG.tsx +16 -0
- package/src/client/Icons/JavaScriptSVG.tsx +16 -0
- package/src/client/Icons/JsonSVG.tsx +16 -0
- package/src/client/Icons/MarkdownSVG.tsx +16 -0
- package/src/client/Icons/MicOffSVG.tsx +35 -0
- package/src/client/Icons/MicSVG.tsx +25 -0
- package/src/client/Icons/NewSVG.tsx +19 -0
- package/src/client/Icons/PinSVG.tsx +14 -0
- package/src/client/Icons/PlaySVG.tsx +16 -0
- package/src/client/Icons/QuestionMarkSVG.tsx +18 -0
- package/src/client/Icons/ReactSVG.tsx +16 -0
- package/src/client/Icons/SearchSVG.tsx +20 -0
- package/src/client/Icons/SparklesSVG.tsx +23 -0
- package/src/client/Icons/SplitEditorSVG.tsx +34 -0
- package/src/client/Icons/StopSVG.tsx +15 -0
- package/src/client/Icons/SvelteSVG.tsx +16 -0
- package/src/client/Icons/TrashSVG.tsx +19 -0
- package/src/client/Icons/TypeScriptSVG.tsx +16 -0
- package/src/client/Icons/index.tsx +26 -0
- package/src/client/ImageViewer/index.tsx +91 -0
- package/src/client/ImageViewer/style.scss +41 -0
- package/src/client/PresenceNotifications/PresenceNotifications.test.ts +134 -0
- package/src/client/PresenceNotifications/index.tsx +158 -0
- package/src/client/PresenceNotifications/style.scss +17 -0
- package/src/client/RunCodeWidget/index.tsx +117 -0
- package/src/client/RunCodeWidget/style.scss +24 -0
- package/src/client/SplitPaneResizeContext.tsx +159 -0
- package/src/client/TabList/Tab.tsx +73 -0
- package/src/client/TabList/index.tsx +35 -0
- package/src/client/TabList/style.scss +51 -0
- package/src/client/VZCodeContext/index.tsx +29 -0
- package/src/client/VZCodeContext/types.ts +248 -0
- package/src/client/VZCodeContext/useVZCodeState.ts +602 -0
- package/src/client/VZKeyboardShortcutsDoc.tsx +148 -0
- package/src/client/VZLeft.tsx +28 -0
- package/src/client/VZMiddle.tsx +172 -0
- package/src/client/VZResizer/index.tsx +128 -0
- package/src/client/VZResizer/styles.scss +33 -0
- package/src/client/VZRight.tsx +113 -0
- package/src/client/VZSettings.tsx +275 -0
- package/src/client/VZSidebar/AIChat/ChatInput.tsx +243 -0
- package/src/client/VZSidebar/AIChat/DiffView.scss +136 -0
- package/src/client/VZSidebar/AIChat/DiffView.tsx +176 -0
- package/src/client/VZSidebar/AIChat/Message.tsx +79 -0
- package/src/client/VZSidebar/AIChat/MessageList.tsx +190 -0
- package/src/client/VZSidebar/AIChat/StreamingMessage.tsx +35 -0
- package/src/client/VZSidebar/AIChat/ThinkingScratchpad.tsx +156 -0
- package/src/client/VZSidebar/AIChat/TypingIndicator.tsx +19 -0
- package/src/client/VZSidebar/AIChat/index.tsx +357 -0
- package/src/client/VZSidebar/AIChat/styles.scss +646 -0
- package/src/client/VZSidebar/AIChat/useSpeechRecognition.ts +117 -0
- package/src/client/VZSidebar/CreateDirModal.tsx +111 -0
- package/src/client/VZSidebar/CreateFileModal.tsx +111 -0
- package/src/client/VZSidebar/DeleteConfirmationModal.tsx +76 -0
- package/src/client/VZSidebar/DirectoryListing.tsx +89 -0
- package/src/client/VZSidebar/EmptyState.tsx +11 -0
- package/src/client/VZSidebar/FileListing.tsx +91 -0
- package/src/client/VZSidebar/FileTypeIcon.tsx +49 -0
- package/src/client/VZSidebar/Item.tsx +237 -0
- package/src/client/VZSidebar/Listing.tsx +47 -0
- package/src/client/VZSidebar/Search.tsx +527 -0
- package/src/client/VZSidebar/VisualEditor.tsx +282 -0
- package/src/client/VZSidebar/VoiceChatModal.tsx +121 -0
- package/src/client/VZSidebar/aiCopyPaste.ts +199 -0
- package/src/client/VZSidebar/index.tsx +728 -0
- package/src/client/VZSidebar/styles.scss +612 -0
- package/src/client/VZSidebar/useDragAndDrop.tsx +408 -0
- package/src/client/bootstrap.ts +26 -0
- package/src/client/buildWorker.ts +3 -0
- package/src/client/featureFlags.ts +8 -0
- package/src/client/generateRequestId.ts +6 -0
- package/src/client/getFileTree.ts +53 -0
- package/src/client/index.ts +19 -0
- package/src/client/main.jsx +10 -0
- package/src/client/presenceColor.ts +8 -0
- package/src/client/shouldTriggerRun.ts +31 -0
- package/src/client/sortFileTree.ts +21 -0
- package/src/client/tabsSearchParameters.test.ts +79 -0
- package/src/client/tabsSearchParameters.ts +137 -0
- package/src/client/themes/index.ts +7 -0
- package/src/client/themes/themes.ts +77 -0
- package/src/client/themes/uiwImports.ts +32 -0
- package/src/client/themes/useDynamicTheme.ts +29 -0
- package/src/client/themes/vizhubTheme/colors.ts +80 -0
- package/src/client/themes/vizhubTheme/index.ts +193 -0
- package/src/client/useActions.ts +288 -0
- package/src/client/useESLint/index.ts +72 -0
- package/src/client/useESLint/worker.ts +113 -0
- package/src/client/useEditorCache.ts +35 -0
- package/src/client/useFileCRUD.ts +228 -0
- package/src/client/useKeyboardShortcuts.ts +451 -0
- package/src/client/useOpenDirectories.ts +99 -0
- package/src/client/usePresenceAutoFollow.ts +85 -0
- package/src/client/usePrettier/index.ts +178 -0
- package/src/client/usePrettier/worker.ts +109 -0
- package/src/client/useRunCode.tsx +15 -0
- package/src/client/useRuntimeError.ts +32 -0
- package/src/client/useSubmitOperation.ts +15 -0
- package/src/client/useURLSync.ts +137 -0
- package/src/client/usernameLocalStorage.ts +43 -0
- package/src/client/utils/fileExtension.ts +10 -0
- package/src/client/utils/isImageFile.ts +12 -0
- package/src/client/vzReducer/aiChatReducer.ts +44 -0
- package/src/client/vzReducer/closeTabReducer.test.ts +205 -0
- package/src/client/vzReducer/closeTabsReducer.ts +96 -0
- package/src/client/vzReducer/createInitialState.ts +38 -0
- package/src/client/vzReducer/editorNoLongerWantsFocusReducer.ts +9 -0
- package/src/client/vzReducer/findPane.ts +19 -0
- package/src/client/vzReducer/index.ts +250 -0
- package/src/client/vzReducer/openTabReducer.test.ts +127 -0
- package/src/client/vzReducer/openTabReducer.ts +74 -0
- package/src/client/vzReducer/searchReducer.test.ts +292 -0
- package/src/client/vzReducer/searchReducer.ts +181 -0
- package/src/client/vzReducer/setActiveFileIdReducer.ts +28 -0
- package/src/client/vzReducer/setActiveFileLeftRightReducer.ts +76 -0
- package/src/client/vzReducer/setIsDocOpenReducer.ts +9 -0
- package/src/client/vzReducer/setIsSettingsOpenReducer.ts +9 -0
- package/src/client/vzReducer/setThemeReducer.ts +9 -0
- package/src/client/vzReducer/setUsernameReducer.ts +9 -0
- package/src/client/vzReducer/splitCurrentPaneReducer.ts +66 -0
- package/src/client/vzReducer/toggleAutoFollowReducer.ts +12 -0
- package/src/client/vzReducer/updatePane.ts +40 -0
- package/src/client/vzReducer/updatePresenceIndicatorReducer.ts +30 -0
- package/src/client/vzReducer/visualEditorReducer.ts +9 -0
- package/src/ot.ts +24 -0
- package/src/randomId.ts +15 -0
- package/src/reactRouterExports.ts +15 -0
- package/src/runCode.ts +27 -0
- package/src/server/aiChatHandler/aiEditing.ts +151 -0
- package/src/server/aiChatHandler/chatOperations.ts +476 -0
- package/src/server/aiChatHandler/errorHandling.ts +66 -0
- package/src/server/aiChatHandler/index.ts +199 -0
- package/src/server/aiChatHandler/llmStreaming.ts +419 -0
- package/src/server/aiChatHandler/validation.ts +24 -0
- package/src/server/computeInitialDocument.ts +220 -0
- package/src/server/config.ts +24 -0
- package/src/server/featureFlags.ts +8 -0
- package/src/server/generateAIResponse.ts +188 -0
- package/src/server/handleAIAssist.ts +53 -0
- package/src/server/handleAIChatMessage.ts +2 -0
- package/src/server/handleAICopilot.ts +97 -0
- package/src/server/index.ts +379 -0
- package/src/server/isDirectory.ts +1 -0
- package/src/server/livekit.ts +24 -0
- package/src/server/prettier.ts +115 -0
- package/src/server/setupEnv.ts +8 -0
- package/src/submitOperation.ts +25 -0
- package/src/types.ts +205 -0
- package/src/utils/fileDiff.ts +117 -0
- package/src/vite-env.d.ts +10 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Pane, PaneId, TabState } from '../../types';
|
|
2
|
+
import { VizFileId } from '@vizhub/viz-types';
|
|
3
|
+
|
|
4
|
+
// Immutable update pattern for updating a pane's tab list.
|
|
5
|
+
export const updatePane = ({
|
|
6
|
+
pane,
|
|
7
|
+
activePaneId,
|
|
8
|
+
newTabList,
|
|
9
|
+
newActiveFileId,
|
|
10
|
+
}: {
|
|
11
|
+
pane: Pane;
|
|
12
|
+
activePaneId: PaneId;
|
|
13
|
+
newTabList?: Array<TabState>;
|
|
14
|
+
newActiveFileId?: VizFileId | null;
|
|
15
|
+
}): Pane =>
|
|
16
|
+
pane.type === 'splitPane'
|
|
17
|
+
? {
|
|
18
|
+
...pane,
|
|
19
|
+
children: pane.children.map((child) =>
|
|
20
|
+
updatePane({
|
|
21
|
+
pane: child,
|
|
22
|
+
activePaneId,
|
|
23
|
+
newTabList,
|
|
24
|
+
newActiveFileId,
|
|
25
|
+
}),
|
|
26
|
+
),
|
|
27
|
+
}
|
|
28
|
+
: pane.id === activePaneId
|
|
29
|
+
? {
|
|
30
|
+
...pane,
|
|
31
|
+
tabList:
|
|
32
|
+
newTabList !== undefined
|
|
33
|
+
? newTabList
|
|
34
|
+
: pane.tabList,
|
|
35
|
+
activeFileId:
|
|
36
|
+
newActiveFileId !== undefined
|
|
37
|
+
? newActiveFileId
|
|
38
|
+
: pane.activeFileId,
|
|
39
|
+
}
|
|
40
|
+
: pane;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { VZAction, VZState } from '.';
|
|
2
|
+
|
|
3
|
+
export const updatePresenceIndicatorReducer = (
|
|
4
|
+
state: VZState,
|
|
5
|
+
action: VZAction,
|
|
6
|
+
): VZState => {
|
|
7
|
+
if (action.type === 'update_presence_indicator') {
|
|
8
|
+
// True if there's already an entry for this user.
|
|
9
|
+
const needsUpdate =
|
|
10
|
+
state.sidebarPresenceIndicators.find(
|
|
11
|
+
(d) =>
|
|
12
|
+
d.username === action.presenceIndicator.username,
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
return {
|
|
16
|
+
...state,
|
|
17
|
+
sidebarPresenceIndicators: needsUpdate
|
|
18
|
+
? state.sidebarPresenceIndicators.map((d) =>
|
|
19
|
+
d.username === action.presenceIndicator.username
|
|
20
|
+
? action.presenceIndicator
|
|
21
|
+
: d,
|
|
22
|
+
)
|
|
23
|
+
: [
|
|
24
|
+
...state.sidebarPresenceIndicators,
|
|
25
|
+
action.presenceIndicator,
|
|
26
|
+
],
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
return state;
|
|
30
|
+
};
|
package/src/ot.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// Operational Transformation (OT) utilities.
|
|
2
|
+
// This file is the central point where the OT types are imported.
|
|
3
|
+
// Localized to one file so it's easy to change it in future.
|
|
4
|
+
import OTJSON1Presence from 'sharedb-client-browser/dist/ot-json1-presence-umd.cjs';
|
|
5
|
+
import jsondiff from 'json0-ot-diff';
|
|
6
|
+
import diffMatchPatch from 'diff-match-patch';
|
|
7
|
+
|
|
8
|
+
export const { json1Presence, textUnicode } =
|
|
9
|
+
OTJSON1Presence;
|
|
10
|
+
|
|
11
|
+
// The OT type used throughout the codebase.
|
|
12
|
+
export const otType = json1Presence.type;
|
|
13
|
+
|
|
14
|
+
// Applies an OT op to an object.
|
|
15
|
+
export const apply = otType.apply;
|
|
16
|
+
|
|
17
|
+
export const diff = (a, b) =>
|
|
18
|
+
jsondiff(
|
|
19
|
+
a,
|
|
20
|
+
b,
|
|
21
|
+
diffMatchPatch,
|
|
22
|
+
json1Presence,
|
|
23
|
+
textUnicode,
|
|
24
|
+
);
|
package/src/randomId.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// Generate a random ID string consisting of digits.
|
|
2
|
+
const numDigits = 8;
|
|
3
|
+
export const randomId = () => {
|
|
4
|
+
let randomString = '';
|
|
5
|
+
for (let i = 0; i < numDigits; i++) {
|
|
6
|
+
randomString += Math.floor(Math.random() * 10);
|
|
7
|
+
}
|
|
8
|
+
return randomString;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
// const probabilityOfCollision =
|
|
12
|
+
// 1 - Math.pow(1 - 1 / Math.pow(10, numDigits), numRuns);
|
|
13
|
+
// Using this formula, the probability of generating the same ID twice
|
|
14
|
+
// when using 8 digits and running the code 1000 times is approximately
|
|
15
|
+
// 0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// The React Router exports have been a pain to deal with.
|
|
2
|
+
// After upgrading Node and React Router, there were random errors.
|
|
3
|
+
// And we want to migrate soon from `react-router-dom` to `react-router`,
|
|
4
|
+
// so the exports are centralized here.
|
|
5
|
+
import * as reactRouterDOM from 'react-router-dom';
|
|
6
|
+
|
|
7
|
+
export const {
|
|
8
|
+
useSearchParams,
|
|
9
|
+
|
|
10
|
+
// This actually is the only thing that works.
|
|
11
|
+
// It looks crazy, but it works.
|
|
12
|
+
// - reactRouterDOM.default works for Vite SSR build
|
|
13
|
+
// - reactRouterDOM works for Vite frontend build
|
|
14
|
+
// @ts-ignore
|
|
15
|
+
} = reactRouterDOM.default || reactRouterDOM;
|
package/src/runCode.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { generateRunId } from '@vizhub/viz-utils';
|
|
2
|
+
import { SubmitOperation } from './types';
|
|
3
|
+
import { VizContent } from '@vizhub/viz-types';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Creates a runCode function that triggers code execution by changing the `runId` in the content.
|
|
7
|
+
* This works for both client-side (with submitOperation) and server-side (with ShareDB document).
|
|
8
|
+
*/
|
|
9
|
+
export const createRunCodeFunction =
|
|
10
|
+
(submitOperation: SubmitOperation) => () => {
|
|
11
|
+
submitOperation((content: VizContent) => ({
|
|
12
|
+
...content,
|
|
13
|
+
runId: generateRunId(),
|
|
14
|
+
}));
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Creates a runCodeRef object compatible with React refs.
|
|
19
|
+
* This is useful for maintaining compatibility with existing code that expects a ref.
|
|
20
|
+
*/
|
|
21
|
+
export const createRunCodeRef = (
|
|
22
|
+
submitOperation: SubmitOperation,
|
|
23
|
+
) => {
|
|
24
|
+
return {
|
|
25
|
+
current: createRunCodeFunction(submitOperation),
|
|
26
|
+
};
|
|
27
|
+
};
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import {
|
|
2
|
+
assembleFullPrompt,
|
|
3
|
+
prepareFilesForPrompt,
|
|
4
|
+
} from 'editcodewithai';
|
|
5
|
+
import { formatMarkdownFiles } from 'llm-code-format';
|
|
6
|
+
import {
|
|
7
|
+
createFilesSnapshot,
|
|
8
|
+
generateFilesUnifiedDiff,
|
|
9
|
+
} from '../../utils/fileDiff.js';
|
|
10
|
+
import { formatFiles } from '../prettier.js';
|
|
11
|
+
import { createSubmitOperation } from '../../submitOperation.js';
|
|
12
|
+
import { VizContent } from '@vizhub/viz-types';
|
|
13
|
+
|
|
14
|
+
// Dev flag for waiting 1 second before starting the LLM function.
|
|
15
|
+
// Useful for debugging and testing purposes, e.g. checking the typing indicator.
|
|
16
|
+
const delayStart = false;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Performs AI chat without editing - just generates a response
|
|
20
|
+
*/
|
|
21
|
+
export const performAIChat = async ({
|
|
22
|
+
prompt,
|
|
23
|
+
shareDBDoc,
|
|
24
|
+
llmFunction,
|
|
25
|
+
}) => {
|
|
26
|
+
const preparedFiles = prepareFilesForPrompt(
|
|
27
|
+
shareDBDoc.data.files,
|
|
28
|
+
);
|
|
29
|
+
const filesContext = formatMarkdownFiles(preparedFiles);
|
|
30
|
+
|
|
31
|
+
// 2. Assemble the final prompt for Q&A mode
|
|
32
|
+
const fullPrompt = assembleFullPrompt({
|
|
33
|
+
filesContext,
|
|
34
|
+
prompt,
|
|
35
|
+
editFormat: 'whole',
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
if (delayStart) {
|
|
39
|
+
await new Promise((resolve) =>
|
|
40
|
+
setTimeout(resolve, 1000),
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Call the LLM function which will handle streaming but won't edit files
|
|
45
|
+
const result = await llmFunction(fullPrompt);
|
|
46
|
+
|
|
47
|
+
return {
|
|
48
|
+
content: result.content,
|
|
49
|
+
generationId: result.generationId,
|
|
50
|
+
diffData: {}, // No file changes in ask mode
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Performs AI editing operations using streaming with incremental OT operations
|
|
56
|
+
*/
|
|
57
|
+
export const performAIEditing = async ({
|
|
58
|
+
prompt,
|
|
59
|
+
shareDBDoc,
|
|
60
|
+
llmFunction,
|
|
61
|
+
runCode,
|
|
62
|
+
}) => {
|
|
63
|
+
// 1. Capture the current state of files before editing
|
|
64
|
+
const beforeFiles = createFilesSnapshot(
|
|
65
|
+
shareDBDoc.data.files,
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
const preparedFiles = prepareFilesForPrompt(
|
|
69
|
+
shareDBDoc.data.files,
|
|
70
|
+
);
|
|
71
|
+
const filesContext = formatMarkdownFiles(preparedFiles);
|
|
72
|
+
|
|
73
|
+
// 2. Assemble the final prompt
|
|
74
|
+
const fullPrompt = assembleFullPrompt({
|
|
75
|
+
filesContext,
|
|
76
|
+
prompt,
|
|
77
|
+
editFormat: 'whole',
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
if (delayStart) {
|
|
81
|
+
await new Promise((resolve) =>
|
|
82
|
+
setTimeout(resolve, 1000),
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Call the LLM function which will handle streaming and incremental file updates
|
|
87
|
+
const result = await llmFunction(fullPrompt);
|
|
88
|
+
|
|
89
|
+
// 3. Run Prettier on changed files before running code
|
|
90
|
+
const afterLLMFiles = createFilesSnapshot(
|
|
91
|
+
shareDBDoc.data.files,
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
// Find files that were changed by the AI
|
|
95
|
+
const changedFileIds = Object.keys(afterLLMFiles).filter(
|
|
96
|
+
(fileId) =>
|
|
97
|
+
beforeFiles[fileId]?.text !==
|
|
98
|
+
afterLLMFiles[fileId]?.text,
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
if (changedFileIds.length > 0) {
|
|
102
|
+
// Format the changed files
|
|
103
|
+
const formattedFiles = await formatFiles(
|
|
104
|
+
shareDBDoc.data.files,
|
|
105
|
+
changedFileIds,
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
// Apply formatted versions to shareDBDoc if formatting succeeded
|
|
109
|
+
if (Object.keys(formattedFiles).length > 0) {
|
|
110
|
+
const submitOperation =
|
|
111
|
+
createSubmitOperation(shareDBDoc);
|
|
112
|
+
submitOperation((document: VizContent) => {
|
|
113
|
+
const updatedFiles = { ...document.files };
|
|
114
|
+
|
|
115
|
+
// Apply each formatted file
|
|
116
|
+
Object.entries(formattedFiles).forEach(
|
|
117
|
+
([fileId, formattedText]) => {
|
|
118
|
+
if (updatedFiles[fileId]) {
|
|
119
|
+
updatedFiles[fileId] = {
|
|
120
|
+
...updatedFiles[fileId],
|
|
121
|
+
text: formattedText,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
},
|
|
125
|
+
);
|
|
126
|
+
|
|
127
|
+
return {
|
|
128
|
+
...document,
|
|
129
|
+
files: updatedFiles,
|
|
130
|
+
};
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
runCode();
|
|
136
|
+
|
|
137
|
+
// 4. Capture the state of files after editing and formatting, then generate diff
|
|
138
|
+
const afterFiles = createFilesSnapshot(
|
|
139
|
+
shareDBDoc.data.files,
|
|
140
|
+
);
|
|
141
|
+
const diffData = generateFilesUnifiedDiff(
|
|
142
|
+
beforeFiles,
|
|
143
|
+
afterFiles,
|
|
144
|
+
);
|
|
145
|
+
|
|
146
|
+
return {
|
|
147
|
+
content: result.content,
|
|
148
|
+
generationId: result.generationId,
|
|
149
|
+
diffData,
|
|
150
|
+
};
|
|
151
|
+
};
|