vzcode 2.13.0 → 2.14.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-858eZSOF.js → index-AX9wEDr7.js} +38 -34
- package/dist/index.html +1 -1
- package/dist/server/aiChatHandler/aiEditing.js +4 -4
- package/dist/server/aiChatHandler/index.js +8 -13
- package/dist/server/aiChatHandler/llmStreaming.js +4 -45
- package/dist/server/index.js +0 -9
- package/package.json +3 -3
- package/src/server/aiChatHandler/aiEditing.ts +4 -4
- package/src/server/aiChatHandler/index.ts +8 -17
- package/src/server/aiChatHandler/llmStreaming.ts +4 -63
- package/src/server/index.ts +0 -17
package/dist/index.html
CHANGED
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap"
|
|
21
21
|
rel="stylesheet"
|
|
22
22
|
/>
|
|
23
|
-
<script type="module" crossorigin src="/assets/index-
|
|
23
|
+
<script type="module" crossorigin src="/assets/index-AX9wEDr7.js"></script>
|
|
24
24
|
<link rel="stylesheet" crossorigin href="/assets/index-DLm5FQ0E.css">
|
|
25
25
|
</head>
|
|
26
26
|
<body>
|
|
@@ -10,8 +10,8 @@ const delayStart = false;
|
|
|
10
10
|
* Performs AI chat without editing - just generates a response
|
|
11
11
|
*/
|
|
12
12
|
export const performAIChat = async ({ prompt, shareDBDoc, llmFunction, }) => {
|
|
13
|
-
const
|
|
14
|
-
const filesContext = formatMarkdownFiles(
|
|
13
|
+
const { files } = prepareFilesForPrompt(shareDBDoc.data.files);
|
|
14
|
+
const filesContext = formatMarkdownFiles(files);
|
|
15
15
|
// 2. Assemble the final prompt for Q&A mode
|
|
16
16
|
const fullPrompt = assembleFullPrompt({
|
|
17
17
|
filesContext,
|
|
@@ -35,8 +35,8 @@ export const performAIChat = async ({ prompt, shareDBDoc, llmFunction, }) => {
|
|
|
35
35
|
export const performAIEditing = async ({ prompt, shareDBDoc, llmFunction, runCode, }) => {
|
|
36
36
|
// 1. Capture the current state of files before editing
|
|
37
37
|
const beforeFiles = createFilesSnapshot(shareDBDoc.data.files);
|
|
38
|
-
const
|
|
39
|
-
const filesContext = formatMarkdownFiles(
|
|
38
|
+
const { files } = prepareFilesForPrompt(shareDBDoc.data.files);
|
|
39
|
+
const filesContext = formatMarkdownFiles(files);
|
|
40
40
|
// 2. Assemble the final prompt
|
|
41
41
|
const fullPrompt = assembleFullPrompt({
|
|
42
42
|
filesContext,
|
|
@@ -5,8 +5,9 @@ import { performAIEditing, performAIChat, } from './aiEditing.js';
|
|
|
5
5
|
import { handleError, handleBackgroundError, } from './errorHandling.js';
|
|
6
6
|
import { createRunCodeFunction } from '../../runCode.js';
|
|
7
7
|
import { createSubmitOperation } from '../../submitOperation.js';
|
|
8
|
+
import { getGenerationMetadata } from 'editcodewithai';
|
|
8
9
|
const DEBUG = false;
|
|
9
|
-
export const handleAIChatMessage = ({ shareDBDoc,
|
|
10
|
+
export const handleAIChatMessage = ({ shareDBDoc, onCreditDeduction, getCurrentCommitId, model, aiRequestOptions, }) => async (req, res) => {
|
|
10
11
|
const { content, chatId, mode = 'edit' } = req.body;
|
|
11
12
|
if (DEBUG) {
|
|
12
13
|
console.log('[handleAIChatMessage] content:', content, 'chatId:', chatId, 'shareDBDoc:', shareDBDoc);
|
|
@@ -31,7 +32,6 @@ export const handleAIChatMessage = ({ shareDBDoc, createAIEditLocalPresence, onC
|
|
|
31
32
|
chatId,
|
|
32
33
|
content,
|
|
33
34
|
mode,
|
|
34
|
-
createAIEditLocalPresence,
|
|
35
35
|
getCurrentCommitId,
|
|
36
36
|
model,
|
|
37
37
|
aiRequestOptions,
|
|
@@ -49,7 +49,7 @@ export const handleAIChatMessage = ({ shareDBDoc, createAIEditLocalPresence, onC
|
|
|
49
49
|
/**
|
|
50
50
|
* Processes the AI request asynchronously in the background
|
|
51
51
|
*/
|
|
52
|
-
const processAIRequestAsync = async ({ shareDBDoc, chatId, content, mode,
|
|
52
|
+
const processAIRequestAsync = async ({ shareDBDoc, chatId, content, mode, getCurrentCommitId, model, aiRequestOptions, onCreditDeduction, }) => {
|
|
53
53
|
try {
|
|
54
54
|
// Capture the current commit ID before making changes (for VizHub integration)
|
|
55
55
|
const beforeCommitId = getCurrentCommitId
|
|
@@ -58,7 +58,6 @@ const processAIRequestAsync = async ({ shareDBDoc, chatId, content, mode, create
|
|
|
58
58
|
// Create LLM function for streaming
|
|
59
59
|
const llmFunction = createLLMFunction({
|
|
60
60
|
shareDBDoc,
|
|
61
|
-
createAIEditLocalPresence,
|
|
62
61
|
chatId,
|
|
63
62
|
model,
|
|
64
63
|
aiRequestOptions,
|
|
@@ -85,16 +84,12 @@ const processAIRequestAsync = async ({ shareDBDoc, chatId, content, mode, create
|
|
|
85
84
|
addDiffToAIMessage(shareDBDoc, chatId, editResult.diffData, beforeCommitId);
|
|
86
85
|
}
|
|
87
86
|
// Handle credit deduction if callback is provided
|
|
88
|
-
if (onCreditDeduction &&
|
|
89
|
-
editResult.upstreamCostCents) {
|
|
87
|
+
if (onCreditDeduction && editResult.generationId) {
|
|
90
88
|
try {
|
|
91
|
-
await onCreditDeduction({
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
inputTokens: editResult.inputTokens,
|
|
96
|
-
outputTokens: editResult.outputTokens,
|
|
97
|
-
});
|
|
89
|
+
await onCreditDeduction(await getGenerationMetadata({
|
|
90
|
+
apiKey: process.env.VZCODE_EDIT_WITH_AI_API_KEY,
|
|
91
|
+
generationId: editResult.generationId,
|
|
92
|
+
}));
|
|
98
93
|
}
|
|
99
94
|
catch (creditError) {
|
|
100
95
|
console.error('Credit deduction error:', creditError);
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { parseMarkdownFiles, StreamingMarkdownParser, } from 'llm-code-format';
|
|
2
|
-
import OpenAI from 'openai';
|
|
3
1
|
import fs from 'fs';
|
|
2
|
+
import OpenAI from 'openai';
|
|
3
|
+
import { parseMarkdownFiles, StreamingMarkdownParser, } from 'llm-code-format';
|
|
4
|
+
import { mergeFileChanges } from 'editcodewithai';
|
|
4
5
|
import { generateRunId } from '@vizhub/viz-utils';
|
|
5
6
|
import { updateAIStatus, createAIMessage, updateAIMessageContent, finalizeAIMessage, ensureFileExists, clearFileContent, appendLineToFile, updateFiles, updateAIScratchpad, } from './chatOperations.js';
|
|
6
|
-
import { mergeFileChanges } from 'editcodewithai';
|
|
7
7
|
import { diff } from '../../ot.js';
|
|
8
8
|
const DEBUG = false;
|
|
9
9
|
// Useful for testing/debugging the streaming behavior
|
|
@@ -32,15 +32,12 @@ const enableStreamingEditing = false;
|
|
|
32
32
|
/**
|
|
33
33
|
* Creates and configures the LLM function for streaming with reasoning tokens
|
|
34
34
|
*/
|
|
35
|
-
export const createLLMFunction = ({ shareDBDoc,
|
|
35
|
+
export const createLLMFunction = ({ shareDBDoc, chatId,
|
|
36
36
|
// Feature flag to enable/disable reasoning tokens.
|
|
37
37
|
// When false, reasoning tokens are not requested from the API
|
|
38
38
|
// and reasoning content is not processed in the streaming response.
|
|
39
39
|
enableReasoningTokens = false, model, aiRequestOptions, }) => {
|
|
40
40
|
return async (fullPrompt) => {
|
|
41
|
-
const localPresence = enableStreamingEditing
|
|
42
|
-
? createAIEditLocalPresence()
|
|
43
|
-
: null;
|
|
44
41
|
// Create OpenRouter client for reasoning token support
|
|
45
42
|
const openRouterClient = new OpenAI({
|
|
46
43
|
apiKey: process.env.VZCODE_EDIT_WITH_AI_API_KEY,
|
|
@@ -123,33 +120,6 @@ enableReasoningTokens = false, model, aiRequestOptions, }) => {
|
|
|
123
120
|
if (currentEditingFileId) {
|
|
124
121
|
// Apply OT operation for this line immediately
|
|
125
122
|
appendLineToFile(shareDBDoc, currentEditingFileId, line);
|
|
126
|
-
// Update AI presence to show cursor at the end of the file
|
|
127
|
-
const currentFile = shareDBDoc.data.files[currentEditingFileId];
|
|
128
|
-
if (currentFile && currentFile.text) {
|
|
129
|
-
const textLength = currentFile.text.length;
|
|
130
|
-
const filePresence = {
|
|
131
|
-
username: 'AI Editor',
|
|
132
|
-
start: [
|
|
133
|
-
'files',
|
|
134
|
-
currentEditingFileId,
|
|
135
|
-
'text',
|
|
136
|
-
textLength,
|
|
137
|
-
],
|
|
138
|
-
end: [
|
|
139
|
-
'files',
|
|
140
|
-
currentEditingFileId,
|
|
141
|
-
'text',
|
|
142
|
-
textLength,
|
|
143
|
-
],
|
|
144
|
-
};
|
|
145
|
-
if (localPresence) {
|
|
146
|
-
localPresence.submit(filePresence, (error) => {
|
|
147
|
-
if (error) {
|
|
148
|
-
console.warn('AI Editor line presence submission error:', error);
|
|
149
|
-
}
|
|
150
|
-
});
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
123
|
}
|
|
154
124
|
},
|
|
155
125
|
onNonCodeLine: async (line) => {
|
|
@@ -238,17 +208,6 @@ enableReasoningTokens = false, model, aiRequestOptions, }) => {
|
|
|
238
208
|
throttledUpdateAIMessageContent.flush();
|
|
239
209
|
// Finalize the AI message by clearing temporary fields
|
|
240
210
|
finalizeAIMessage(shareDBDoc, chatId);
|
|
241
|
-
// Clear AI Editor presence when done
|
|
242
|
-
DEBUG &&
|
|
243
|
-
console.log('AI editing done, clearing AI Editor presence');
|
|
244
|
-
if (localPresence) {
|
|
245
|
-
localPresence.submit(null, (error) => {
|
|
246
|
-
DEBUG && console.log('AI Editor presence cleared');
|
|
247
|
-
if (error) {
|
|
248
|
-
console.warn('AI Editor presence cleanup error:', error);
|
|
249
|
-
}
|
|
250
|
-
});
|
|
251
|
-
}
|
|
252
211
|
// If streaming editing is not enabled, we need to
|
|
253
212
|
// apply all the edits at once
|
|
254
213
|
if (!enableStreamingEditing) {
|
package/dist/server/index.js
CHANGED
|
@@ -78,14 +78,6 @@ app.use(express.static(dir));
|
|
|
78
78
|
// which is a representation of files on disk.
|
|
79
79
|
const shareDBConnection = shareDBBackend.connect();
|
|
80
80
|
const shareDBDoc = shareDBConnection.get('documents', '1');
|
|
81
|
-
// Set up presence for AI editing following the same pattern as useShareDB.ts
|
|
82
|
-
const docPresence = shareDBConnection.getDocPresence('documents', '1');
|
|
83
|
-
// Create local presence for AI editing with a unique ID
|
|
84
|
-
const generateAIEditId = () => {
|
|
85
|
-
const timestamp = Date.now().toString(36);
|
|
86
|
-
return `ai-edit-${timestamp}`;
|
|
87
|
-
};
|
|
88
|
-
const createAIEditLocalPresence = () => docPresence.create(generateAIEditId());
|
|
89
81
|
shareDBDoc.create(initialDocument, json1Presence.type.uri);
|
|
90
82
|
// Handle AI Assist requests.
|
|
91
83
|
app.post('/ai-assist', bodyParser.json(), handleAIAssist(shareDBDoc));
|
|
@@ -94,7 +86,6 @@ app.post('/ai-copilot', bodyParser.json(), handleAICopilot());
|
|
|
94
86
|
// Handle AI Chat Message requests.
|
|
95
87
|
app.post('/ai-chat-message', bodyParser.json(), handleAIChatMessage({
|
|
96
88
|
shareDBDoc,
|
|
97
|
-
createAIEditLocalPresence,
|
|
98
89
|
onCreditDeduction: undefined,
|
|
99
90
|
}));
|
|
100
91
|
// Livekit Token Generator
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vzcode",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.14.0",
|
|
4
4
|
"description": "Multiplayer code editor system",
|
|
5
5
|
"main": "src/index.ts",
|
|
6
6
|
"type": "module",
|
|
@@ -156,7 +156,7 @@
|
|
|
156
156
|
"diff-match-patch": "^1.0.5",
|
|
157
157
|
"diff2html": "^3.4.52",
|
|
158
158
|
"dotenv": "^17.2.2",
|
|
159
|
-
"editcodewithai": "^2.
|
|
159
|
+
"editcodewithai": "^2.4.0",
|
|
160
160
|
"eslint-linter-browserify": "^9.34.0",
|
|
161
161
|
"express": "^5.1.0",
|
|
162
162
|
"ignore": "^7.0.5",
|
|
@@ -165,7 +165,7 @@
|
|
|
165
165
|
"livekit-server-sdk": "^2.13.3",
|
|
166
166
|
"llm-code-format": "^3.0.0",
|
|
167
167
|
"lucide-react": "^0.542.0",
|
|
168
|
-
"npm": "^11.
|
|
168
|
+
"npm": "^11.6.0",
|
|
169
169
|
"open": "^10.2.0",
|
|
170
170
|
"prettier-plugin-svelte": "^3.4.0",
|
|
171
171
|
"react": "^18",
|
|
@@ -23,10 +23,10 @@ export const performAIChat = async ({
|
|
|
23
23
|
shareDBDoc,
|
|
24
24
|
llmFunction,
|
|
25
25
|
}) => {
|
|
26
|
-
const
|
|
26
|
+
const { files } = prepareFilesForPrompt(
|
|
27
27
|
shareDBDoc.data.files,
|
|
28
28
|
);
|
|
29
|
-
const filesContext = formatMarkdownFiles(
|
|
29
|
+
const filesContext = formatMarkdownFiles(files);
|
|
30
30
|
|
|
31
31
|
// 2. Assemble the final prompt for Q&A mode
|
|
32
32
|
const fullPrompt = assembleFullPrompt({
|
|
@@ -65,10 +65,10 @@ export const performAIEditing = async ({
|
|
|
65
65
|
shareDBDoc.data.files,
|
|
66
66
|
);
|
|
67
67
|
|
|
68
|
-
const
|
|
68
|
+
const { files } = prepareFilesForPrompt(
|
|
69
69
|
shareDBDoc.data.files,
|
|
70
70
|
);
|
|
71
|
-
const filesContext = formatMarkdownFiles(
|
|
71
|
+
const filesContext = formatMarkdownFiles(files);
|
|
72
72
|
|
|
73
73
|
// 2. Assemble the final prompt
|
|
74
74
|
const fullPrompt = assembleFullPrompt({
|
|
@@ -19,20 +19,19 @@ import { createRunCodeFunction } from '../../runCode.js';
|
|
|
19
19
|
import { ShareDBDoc } from '../../types.js';
|
|
20
20
|
import { VizContent } from '@vizhub/viz-types';
|
|
21
21
|
import { createSubmitOperation } from '../../submitOperation.js';
|
|
22
|
+
import { getGenerationMetadata } from 'editcodewithai';
|
|
22
23
|
|
|
23
24
|
const DEBUG = false;
|
|
24
25
|
|
|
25
26
|
export const handleAIChatMessage =
|
|
26
27
|
({
|
|
27
28
|
shareDBDoc,
|
|
28
|
-
createAIEditLocalPresence,
|
|
29
29
|
onCreditDeduction,
|
|
30
30
|
getCurrentCommitId,
|
|
31
31
|
model,
|
|
32
32
|
aiRequestOptions,
|
|
33
33
|
}: {
|
|
34
34
|
shareDBDoc: ShareDBDoc<VizContent>;
|
|
35
|
-
createAIEditLocalPresence: () => any;
|
|
36
35
|
onCreditDeduction?: any;
|
|
37
36
|
getCurrentCommitId?: () => string | null;
|
|
38
37
|
model?: string;
|
|
@@ -77,7 +76,6 @@ export const handleAIChatMessage =
|
|
|
77
76
|
chatId,
|
|
78
77
|
content,
|
|
79
78
|
mode,
|
|
80
|
-
createAIEditLocalPresence,
|
|
81
79
|
getCurrentCommitId,
|
|
82
80
|
model,
|
|
83
81
|
aiRequestOptions,
|
|
@@ -103,7 +101,6 @@ const processAIRequestAsync = async ({
|
|
|
103
101
|
chatId,
|
|
104
102
|
content,
|
|
105
103
|
mode,
|
|
106
|
-
createAIEditLocalPresence,
|
|
107
104
|
getCurrentCommitId,
|
|
108
105
|
model,
|
|
109
106
|
aiRequestOptions,
|
|
@@ -113,7 +110,6 @@ const processAIRequestAsync = async ({
|
|
|
113
110
|
chatId: string;
|
|
114
111
|
content: string;
|
|
115
112
|
mode: string;
|
|
116
|
-
createAIEditLocalPresence: () => any;
|
|
117
113
|
getCurrentCommitId?: () => string | null;
|
|
118
114
|
model?: string;
|
|
119
115
|
aiRequestOptions?: any;
|
|
@@ -128,7 +124,6 @@ const processAIRequestAsync = async ({
|
|
|
128
124
|
// Create LLM function for streaming
|
|
129
125
|
const llmFunction = createLLMFunction({
|
|
130
126
|
shareDBDoc,
|
|
131
|
-
createAIEditLocalPresence,
|
|
132
127
|
chatId,
|
|
133
128
|
model,
|
|
134
129
|
aiRequestOptions,
|
|
@@ -168,18 +163,14 @@ const processAIRequestAsync = async ({
|
|
|
168
163
|
}
|
|
169
164
|
|
|
170
165
|
// Handle credit deduction if callback is provided
|
|
171
|
-
if (
|
|
172
|
-
onCreditDeduction &&
|
|
173
|
-
(editResult as any).upstreamCostCents
|
|
174
|
-
) {
|
|
166
|
+
if (onCreditDeduction && editResult.generationId) {
|
|
175
167
|
try {
|
|
176
|
-
await onCreditDeduction(
|
|
177
|
-
|
|
178
|
-
.
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
});
|
|
168
|
+
await onCreditDeduction(
|
|
169
|
+
await getGenerationMetadata({
|
|
170
|
+
apiKey: process.env.VZCODE_EDIT_WITH_AI_API_KEY,
|
|
171
|
+
generationId: editResult.generationId,
|
|
172
|
+
}),
|
|
173
|
+
);
|
|
183
174
|
} catch (creditError) {
|
|
184
175
|
console.error(
|
|
185
176
|
'Credit deduction error:',
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import OpenAI from 'openai';
|
|
1
3
|
import {
|
|
2
4
|
parseMarkdownFiles,
|
|
3
5
|
StreamingMarkdownParser,
|
|
4
6
|
} from 'llm-code-format';
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
+
import { mergeFileChanges } from 'editcodewithai';
|
|
8
|
+
import { VizChatId, VizContent } from '@vizhub/viz-types';
|
|
7
9
|
import { generateRunId } from '@vizhub/viz-utils';
|
|
8
10
|
import {
|
|
9
11
|
updateAIStatus,
|
|
@@ -16,9 +18,7 @@ import {
|
|
|
16
18
|
updateFiles,
|
|
17
19
|
updateAIScratchpad,
|
|
18
20
|
} from './chatOperations.js';
|
|
19
|
-
import { mergeFileChanges } from 'editcodewithai';
|
|
20
21
|
import { diff } from '../../ot.js';
|
|
21
|
-
import { VizChatId, VizContent } from '@vizhub/viz-types';
|
|
22
22
|
import { ShareDBDoc } from '../../types.js';
|
|
23
23
|
|
|
24
24
|
const DEBUG = false;
|
|
@@ -54,7 +54,6 @@ const enableStreamingEditing = false;
|
|
|
54
54
|
*/
|
|
55
55
|
export const createLLMFunction = ({
|
|
56
56
|
shareDBDoc,
|
|
57
|
-
createAIEditLocalPresence,
|
|
58
57
|
chatId,
|
|
59
58
|
// Feature flag to enable/disable reasoning tokens.
|
|
60
59
|
// When false, reasoning tokens are not requested from the API
|
|
@@ -64,17 +63,12 @@ export const createLLMFunction = ({
|
|
|
64
63
|
aiRequestOptions,
|
|
65
64
|
}: {
|
|
66
65
|
shareDBDoc: ShareDBDoc<VizContent>;
|
|
67
|
-
createAIEditLocalPresence: () => any;
|
|
68
66
|
chatId: VizChatId;
|
|
69
67
|
enableReasoningTokens?: boolean;
|
|
70
68
|
model?: string;
|
|
71
69
|
aiRequestOptions?: any;
|
|
72
70
|
}) => {
|
|
73
71
|
return async (fullPrompt: string) => {
|
|
74
|
-
const localPresence = enableStreamingEditing
|
|
75
|
-
? createAIEditLocalPresence()
|
|
76
|
-
: null;
|
|
77
|
-
|
|
78
72
|
// Create OpenRouter client for reasoning token support
|
|
79
73
|
const openRouterClient = new OpenAI({
|
|
80
74
|
apiKey: process.env.VZCODE_EDIT_WITH_AI_API_KEY,
|
|
@@ -198,42 +192,6 @@ export const createLLMFunction = ({
|
|
|
198
192
|
currentEditingFileId,
|
|
199
193
|
line,
|
|
200
194
|
);
|
|
201
|
-
|
|
202
|
-
// Update AI presence to show cursor at the end of the file
|
|
203
|
-
const currentFile =
|
|
204
|
-
shareDBDoc.data.files[currentEditingFileId];
|
|
205
|
-
if (currentFile && currentFile.text) {
|
|
206
|
-
const textLength = currentFile.text.length;
|
|
207
|
-
const filePresence = {
|
|
208
|
-
username: 'AI Editor',
|
|
209
|
-
start: [
|
|
210
|
-
'files',
|
|
211
|
-
currentEditingFileId,
|
|
212
|
-
'text',
|
|
213
|
-
textLength,
|
|
214
|
-
],
|
|
215
|
-
end: [
|
|
216
|
-
'files',
|
|
217
|
-
currentEditingFileId,
|
|
218
|
-
'text',
|
|
219
|
-
textLength,
|
|
220
|
-
],
|
|
221
|
-
};
|
|
222
|
-
|
|
223
|
-
if (localPresence) {
|
|
224
|
-
localPresence.submit(
|
|
225
|
-
filePresence,
|
|
226
|
-
(error) => {
|
|
227
|
-
if (error) {
|
|
228
|
-
console.warn(
|
|
229
|
-
'AI Editor line presence submission error:',
|
|
230
|
-
error,
|
|
231
|
-
);
|
|
232
|
-
}
|
|
233
|
-
},
|
|
234
|
-
);
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
195
|
}
|
|
238
196
|
},
|
|
239
197
|
onNonCodeLine: async (line: string) => {
|
|
@@ -348,23 +306,6 @@ export const createLLMFunction = ({
|
|
|
348
306
|
// Finalize the AI message by clearing temporary fields
|
|
349
307
|
finalizeAIMessage(shareDBDoc, chatId);
|
|
350
308
|
|
|
351
|
-
// Clear AI Editor presence when done
|
|
352
|
-
DEBUG &&
|
|
353
|
-
console.log(
|
|
354
|
-
'AI editing done, clearing AI Editor presence',
|
|
355
|
-
);
|
|
356
|
-
if (localPresence) {
|
|
357
|
-
localPresence.submit(null, (error) => {
|
|
358
|
-
DEBUG && console.log('AI Editor presence cleared');
|
|
359
|
-
if (error) {
|
|
360
|
-
console.warn(
|
|
361
|
-
'AI Editor presence cleanup error:',
|
|
362
|
-
error,
|
|
363
|
-
);
|
|
364
|
-
}
|
|
365
|
-
});
|
|
366
|
-
}
|
|
367
|
-
|
|
368
309
|
// If streaming editing is not enabled, we need to
|
|
369
310
|
// apply all the edits at once
|
|
370
311
|
if (!enableStreamingEditing) {
|
package/src/server/index.ts
CHANGED
|
@@ -14,7 +14,6 @@ import { computeInitialDocument } from './computeInitialDocument.js';
|
|
|
14
14
|
import { handleAIAssist } from './handleAIAssist.js';
|
|
15
15
|
import { handleAICopilot } from './handleAICopilot.js';
|
|
16
16
|
import { handleAIChatMessage } from './handleAIChatMessage.js';
|
|
17
|
-
|
|
18
17
|
import { isDirectory } from './isDirectory.js';
|
|
19
18
|
import { createToken } from './livekit.js';
|
|
20
19
|
import './setupEnv.js';
|
|
@@ -100,21 +99,6 @@ app.use(express.static(dir));
|
|
|
100
99
|
const shareDBConnection = shareDBBackend.connect();
|
|
101
100
|
const shareDBDoc = shareDBConnection.get('documents', '1');
|
|
102
101
|
|
|
103
|
-
// Set up presence for AI editing following the same pattern as useShareDB.ts
|
|
104
|
-
const docPresence = shareDBConnection.getDocPresence(
|
|
105
|
-
'documents',
|
|
106
|
-
'1',
|
|
107
|
-
);
|
|
108
|
-
|
|
109
|
-
// Create local presence for AI editing with a unique ID
|
|
110
|
-
const generateAIEditId = () => {
|
|
111
|
-
const timestamp = Date.now().toString(36);
|
|
112
|
-
return `ai-edit-${timestamp}`;
|
|
113
|
-
};
|
|
114
|
-
|
|
115
|
-
const createAIEditLocalPresence = () =>
|
|
116
|
-
docPresence.create(generateAIEditId());
|
|
117
|
-
|
|
118
102
|
shareDBDoc.create(initialDocument, json1Presence.type.uri);
|
|
119
103
|
|
|
120
104
|
// Handle AI Assist requests.
|
|
@@ -137,7 +121,6 @@ app.post(
|
|
|
137
121
|
bodyParser.json(),
|
|
138
122
|
handleAIChatMessage({
|
|
139
123
|
shareDBDoc,
|
|
140
|
-
createAIEditLocalPresence,
|
|
141
124
|
onCreditDeduction: undefined,
|
|
142
125
|
}),
|
|
143
126
|
);
|