vzcode 0.44.0 → 0.46.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/dist/assets/{index-7MNYa9sP.css → index-0U2uzpmH.css} +1 -1
- package/dist/assets/{index-f4vqBOE4.js → index-iJQOJ5Kf.js} +38 -38
- package/dist/index.html +2 -2
- package/package.json +7 -7
- package/src/client/AIAssist/AIAssistCodeMirrorKeyMap.ts +42 -0
- package/src/client/AIAssist/AIAssistWidget/index.tsx +96 -0
- package/src/client/AIAssist/AIAssistWidget/style.scss +19 -0
- package/src/client/AIAssist/generateFilesContext.ts +25 -0
- package/src/client/AIAssist/index.ts +3 -0
- package/src/client/AIAssist/startAIAssist.ts +93 -0
- package/src/client/CodeEditor/getOrCreateEditor.ts +9 -18
- package/src/client/CodeEditor/index.tsx +0 -16
- package/src/client/CodeEditor/typeScriptCompletions.ts +1 -5
- package/src/client/CodeEditor/typeScriptLinter.ts +2 -2
- package/src/client/CodeErrorOverlay/index.tsx +23 -18
- package/src/client/Icons/SparklesSVG.tsx +31 -0
- package/src/client/Icons/StopSVG.tsx +15 -0
- package/src/client/Icons/index.tsx +2 -0
- package/src/client/VZMiddle.tsx +20 -8
- package/src/client/generateRequestId.ts +6 -0
- package/src/client/useTypeScript/index.ts +4 -0
- package/src/server/computeInitialDocument.js +26 -37
- package/src/server/config.js +24 -0
- package/src/server/featureFlags.js +7 -1
- package/src/server/generateAIResponse.js +101 -0
- package/src/server/handleAIAssist.js +11 -100
- package/src/server/index.js +50 -58
- package/src/server/setupEnv.js +18 -0
- package/src/types.ts +23 -23
- package/src/client/AIAssist.ts +0 -133
- package/src/client/AIAssistWidget/index.tsx +0 -101
- package/src/client/AIAssistWidget/style.scss +0 -10
package/src/client/AIAssist.ts
DELETED
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
import { EditorView, keymap } from '@codemirror/view';
|
|
2
|
-
import { json1Presence } from '../ot';
|
|
3
|
-
import {
|
|
4
|
-
FileId,
|
|
5
|
-
File,
|
|
6
|
-
ShareDBDoc,
|
|
7
|
-
VZCodeContent,
|
|
8
|
-
} from '../types';
|
|
9
|
-
import { generateRequestId } from './CodeEditor/typeScriptCompletions';
|
|
10
|
-
|
|
11
|
-
import { TabState } from './vzReducer';
|
|
12
|
-
|
|
13
|
-
const { insertOp, replaceOp } = json1Presence;
|
|
14
|
-
|
|
15
|
-
export const AIAssist = ({
|
|
16
|
-
shareDBDoc,
|
|
17
|
-
// The file id of the file the AI should assist with.
|
|
18
|
-
fileId,
|
|
19
|
-
tabList,
|
|
20
|
-
}: {
|
|
21
|
-
shareDBDoc: ShareDBDoc<VZCodeContent>;
|
|
22
|
-
fileId: string;
|
|
23
|
-
aiAssistEndpoint: string;
|
|
24
|
-
aiAssistOptions?: {
|
|
25
|
-
[key: string]: any;
|
|
26
|
-
};
|
|
27
|
-
tabList: Array<TabState>;
|
|
28
|
-
}) =>
|
|
29
|
-
keymap.of([
|
|
30
|
-
{
|
|
31
|
-
key: 'control-m',
|
|
32
|
-
run: (view: EditorView) => {
|
|
33
|
-
if (
|
|
34
|
-
shareDBDoc.data.aiStreams === undefined ||
|
|
35
|
-
shareDBDoc.data.aiStreams[mostRecentStreamId] ===
|
|
36
|
-
null ||
|
|
37
|
-
shareDBDoc.data.aiStreams[mostRecentStreamId]
|
|
38
|
-
?.AIStreamStatus.serverIsRunning !== true
|
|
39
|
-
) {
|
|
40
|
-
startAIAssist(view, shareDBDoc, fileId, tabList);
|
|
41
|
-
} else {
|
|
42
|
-
haltAIAssist(shareDBDoc);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
return true;
|
|
46
|
-
},
|
|
47
|
-
},
|
|
48
|
-
]);
|
|
49
|
-
|
|
50
|
-
// TODO use ref forwarding instead of `export let`
|
|
51
|
-
export let mostRecentStreamId = null;
|
|
52
|
-
|
|
53
|
-
export const startAIAssist = async (
|
|
54
|
-
view: EditorView,
|
|
55
|
-
shareDBDoc: ShareDBDoc<VZCodeContent>,
|
|
56
|
-
fileId: FileId,
|
|
57
|
-
tabList: Array<TabState>,
|
|
58
|
-
// TODO mostRecentStreamIdRef: React.MutableRefObject<string>,
|
|
59
|
-
) => {
|
|
60
|
-
const textToSend =
|
|
61
|
-
(await generateFilesContext(
|
|
62
|
-
tabList.map(
|
|
63
|
-
(tabState) =>
|
|
64
|
-
shareDBDoc.data.files[tabState.fileId],
|
|
65
|
-
),
|
|
66
|
-
)) +
|
|
67
|
-
'Current File:\n' +
|
|
68
|
-
view.state.sliceDoc(0, view.state.selection.main.to);
|
|
69
|
-
|
|
70
|
-
console.log(textToSend);
|
|
71
|
-
|
|
72
|
-
// TODO mostRecentStreamIdRef.current = generateRequestId();
|
|
73
|
-
mostRecentStreamId = generateRequestId();
|
|
74
|
-
|
|
75
|
-
if (shareDBDoc.data['aiStreams'] === undefined) {
|
|
76
|
-
shareDBDoc.submitOp(insertOp(['aiStreams'], {}), {
|
|
77
|
-
source: 'AIClient',
|
|
78
|
-
});
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
shareDBDoc.submitOp(
|
|
82
|
-
insertOp(['aiStreams', mostRecentStreamId], {
|
|
83
|
-
AIStreamStatus: {
|
|
84
|
-
clientWantsToStart: true,
|
|
85
|
-
serverIsRunning: false,
|
|
86
|
-
text: textToSend,
|
|
87
|
-
insertionCursor: view.state.selection.main.to,
|
|
88
|
-
fileId: fileId,
|
|
89
|
-
},
|
|
90
|
-
}),
|
|
91
|
-
{ source: 'AIClient' },
|
|
92
|
-
);
|
|
93
|
-
};
|
|
94
|
-
|
|
95
|
-
export const haltAIAssist = (
|
|
96
|
-
shareDBDoc: ShareDBDoc<VZCodeContent>,
|
|
97
|
-
) => {
|
|
98
|
-
const haltGenerationOp = replaceOp(
|
|
99
|
-
[
|
|
100
|
-
'aiStreams',
|
|
101
|
-
mostRecentStreamId,
|
|
102
|
-
'AIStreamStatus',
|
|
103
|
-
'clientWantsToStart',
|
|
104
|
-
],
|
|
105
|
-
true,
|
|
106
|
-
false,
|
|
107
|
-
);
|
|
108
|
-
|
|
109
|
-
shareDBDoc.submitOp(haltGenerationOp, {
|
|
110
|
-
source: 'AIClient',
|
|
111
|
-
});
|
|
112
|
-
};
|
|
113
|
-
|
|
114
|
-
export const generateFilesContext = async (
|
|
115
|
-
goodFiles: File[],
|
|
116
|
-
): Promise<string> => {
|
|
117
|
-
const input = goodFiles
|
|
118
|
-
.map((file) => {
|
|
119
|
-
const nameSubstring = file.name
|
|
120
|
-
// ?.substring(0, maxFileNameLength)
|
|
121
|
-
.trim();
|
|
122
|
-
|
|
123
|
-
const textSubstring = file.text
|
|
124
|
-
// ?.substring(0, maxFileTextLength)
|
|
125
|
-
.trim();
|
|
126
|
-
|
|
127
|
-
// Generate Markdown that AI will understand.
|
|
128
|
-
return `File \`${nameSubstring}\`:\n\`\`\`${textSubstring}\`\`\``;
|
|
129
|
-
})
|
|
130
|
-
.join('\n\n');
|
|
131
|
-
|
|
132
|
-
return input;
|
|
133
|
-
};
|
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
import { useCallback, useEffect, useState } from 'react';
|
|
2
|
-
import { Button } from '../bootstrap';
|
|
3
|
-
import './style.scss';
|
|
4
|
-
import {
|
|
5
|
-
mostRecentStreamId,
|
|
6
|
-
haltAIAssist,
|
|
7
|
-
startAIAssist,
|
|
8
|
-
} from '../AIAssist';
|
|
9
|
-
import {
|
|
10
|
-
FileId,
|
|
11
|
-
ShareDBDoc,
|
|
12
|
-
VZCodeContent,
|
|
13
|
-
} from '../../types';
|
|
14
|
-
import { EditorCache } from '../useEditorCache';
|
|
15
|
-
import { TabState } from '../vzReducer';
|
|
16
|
-
// From
|
|
17
|
-
// https://primer.style/foundations/icons/zap-24
|
|
18
|
-
const ZapSVG = () => (
|
|
19
|
-
<svg
|
|
20
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
21
|
-
viewBox="0 0 24 24"
|
|
22
|
-
width="24"
|
|
23
|
-
height="24"
|
|
24
|
-
>
|
|
25
|
-
<path d="M15.716 1.329a1.341 1.341 0 0 1 2.109 1.55L15.147 9h4.161c1.623 0 2.372 2.016 1.143 3.075L8.102 22.721a1.148 1.148 0 0 1-1.81-1.317L8.996 15H4.674c-1.619 0-2.37-2.008-1.148-3.07l12.19-10.6Zm.452 1.595L4.51 13.061a.25.25 0 0 0 .164.439h5.45a.749.749 0 0 1 .692 1.041l-2.559 6.066 11.215-9.668a.25.25 0 0 0-.164-.439H14a.75.75 0 0 1-.687-1.05Z"></path>
|
|
26
|
-
</svg>
|
|
27
|
-
);
|
|
28
|
-
|
|
29
|
-
// From Wikimedia
|
|
30
|
-
// https://commons.wikimedia.org/wiki/File:Stopsign.svg
|
|
31
|
-
const StopSVG = () => (
|
|
32
|
-
<svg
|
|
33
|
-
width="15pt"
|
|
34
|
-
height="15pt"
|
|
35
|
-
version="1.1"
|
|
36
|
-
viewBox="0 0 15 15"
|
|
37
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
38
|
-
>
|
|
39
|
-
<g transform="scale(.75)" fill="#fff" stroke="#000">
|
|
40
|
-
<path d="m17.5 0.5c1.1055 0 2 0.89453 2 2v15c0 1.1055-0.89453 2-2 2h-15c-1.1055 0-2-0.89453-2-2v-15c0-1.1055 0.89453-2 2-2z" />
|
|
41
|
-
</g>
|
|
42
|
-
</svg>
|
|
43
|
-
);
|
|
44
|
-
|
|
45
|
-
export const AIAssistWidget = ({
|
|
46
|
-
activeFileId,
|
|
47
|
-
shareDBDoc,
|
|
48
|
-
editorCache,
|
|
49
|
-
tabList,
|
|
50
|
-
}: {
|
|
51
|
-
activeFileId: FileId;
|
|
52
|
-
shareDBDoc: ShareDBDoc<VZCodeContent>;
|
|
53
|
-
editorCache: EditorCache;
|
|
54
|
-
tabList: Array<TabState>;
|
|
55
|
-
}) => {
|
|
56
|
-
const [AIAssistRunning, setAIAssistRunning] =
|
|
57
|
-
useState(false);
|
|
58
|
-
|
|
59
|
-
useEffect(() => {
|
|
60
|
-
const handleOp = (op, source) => {
|
|
61
|
-
if (op !== null && op[0] === 'aiStreams') {
|
|
62
|
-
// The check if the value is true is required
|
|
63
|
-
// because the value could be null rather than false.
|
|
64
|
-
setAIAssistRunning(
|
|
65
|
-
shareDBDoc.data.aiStreams[mostRecentStreamId]
|
|
66
|
-
?.AIStreamStatus.serverIsRunning === true,
|
|
67
|
-
);
|
|
68
|
-
}
|
|
69
|
-
};
|
|
70
|
-
shareDBDoc.on('op', handleOp);
|
|
71
|
-
|
|
72
|
-
return () => {
|
|
73
|
-
shareDBDoc.off('op', handleOp);
|
|
74
|
-
};
|
|
75
|
-
}, [shareDBDoc]);
|
|
76
|
-
|
|
77
|
-
const handleClick = useCallback(() => {
|
|
78
|
-
if (!AIAssistRunning) {
|
|
79
|
-
startAIAssist(
|
|
80
|
-
editorCache.get(activeFileId).editor,
|
|
81
|
-
shareDBDoc,
|
|
82
|
-
activeFileId,
|
|
83
|
-
tabList,
|
|
84
|
-
);
|
|
85
|
-
} else {
|
|
86
|
-
haltAIAssist(shareDBDoc);
|
|
87
|
-
}
|
|
88
|
-
}, [activeFileId, AIAssistRunning]);
|
|
89
|
-
|
|
90
|
-
return (
|
|
91
|
-
<div className="vz-code-ai-assist-widget">
|
|
92
|
-
<Button
|
|
93
|
-
variant="light"
|
|
94
|
-
title="Start AI Assist"
|
|
95
|
-
onClick={handleClick}
|
|
96
|
-
>
|
|
97
|
-
{AIAssistRunning ? <StopSVG /> : <ZapSVG />}
|
|
98
|
-
</Button>
|
|
99
|
-
</div>
|
|
100
|
-
);
|
|
101
|
-
};
|