vzcode 1.39.0 → 1.41.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 (35) hide show
  1. package/dist/assets/bindings_wasm_bg-BQfW5T_2.wasm +0 -0
  2. package/dist/assets/buildWorker-B-vXZ9gA.js +579 -0
  3. package/dist/assets/index-DPAeYEiH.js +329 -0
  4. package/dist/index.html +1 -1
  5. package/package.json +16 -14
  6. package/src/client/CodeEditor/getOrCreateEditor.ts +2 -5
  7. package/src/client/CodeEditor/index.tsx +1 -1
  8. package/src/client/CodeEditor/json1PresenceDisplay.ts +28 -44
  9. package/src/client/VZRight.tsx +67 -6
  10. package/src/client/VZSidebar/AIChat/ChatInput.tsx +17 -5
  11. package/src/client/VZSidebar/AIChat/Message.tsx +21 -8
  12. package/src/client/VZSidebar/AIChat/MessageList.tsx +11 -4
  13. package/src/client/VZSidebar/AIChat/StreamingMessage.tsx +6 -1
  14. package/src/client/VZSidebar/AIChat/TypingIndicator.tsx +7 -1
  15. package/src/client/VZSidebar/AIChat/index.tsx +22 -7
  16. package/src/client/buildWorker.ts +3 -0
  17. package/src/client/usePresenceAutoFollow.ts +3 -4
  18. package/src/server/aiChatHandler/{chatOperations.js → chatOperations.ts} +5 -2
  19. package/src/server/aiChatHandler/{index.js → index.ts} +19 -9
  20. package/src/server/aiChatHandler/{llmStreaming.js → llmStreaming.ts} +16 -7
  21. package/src/server/{generateAIResponse.js → generateAIResponse.ts} +3 -2
  22. package/src/server/{handleAIAssist.js → handleAIAssist.ts} +11 -4
  23. package/src/server/{index.js → index.ts} +16 -22
  24. package/dist/assets/index-0y6ZxgSv.js +0 -327
  25. /package/src/server/aiChatHandler/{aiEditing.js → aiEditing.ts} +0 -0
  26. /package/src/server/aiChatHandler/{errorHandling.js → errorHandling.ts} +0 -0
  27. /package/src/server/aiChatHandler/{validation.js → validation.ts} +0 -0
  28. /package/src/server/{computeInitialDocument.js → computeInitialDocument.ts} +0 -0
  29. /package/src/server/{config.js → config.ts} +0 -0
  30. /package/src/server/{featureFlags.js → featureFlags.ts} +0 -0
  31. /package/src/server/{handleAIChatMessage.js → handleAIChatMessage.ts} +0 -0
  32. /package/src/server/{handleAICopilot.js → handleAICopilot.ts} +0 -0
  33. /package/src/server/{isDirectory.js → isDirectory.ts} +0 -0
  34. /package/src/server/{livekit.js → livekit.ts} +0 -0
  35. /package/src/server/{setupEnv.js → setupEnv.ts} +0 -0
@@ -8,12 +8,22 @@ import { createLLMFunction } from './llmStreaming.js';
8
8
  import { performAIEditing } from './aiEditing.js';
9
9
  import { handleError } from './errorHandling.js';
10
10
  import { createRunCodeFunction } from '../../runCode.js';
11
+ import { ShareDBDoc } from '../../types.js';
12
+ import { VizContent } from '@vizhub/viz-types';
11
13
 
12
14
  const DEBUG = false;
13
15
 
14
16
  export const handleAIChatMessage =
15
- ({ shareDBDoc, localPresence, onCreditDeduction }) =>
16
- async (req, res) => {
17
+ ({
18
+ shareDBDoc,
19
+ createVizBotLocalPresence,
20
+ onCreditDeduction,
21
+ }: {
22
+ shareDBDoc: ShareDBDoc<VizContent>;
23
+ createVizBotLocalPresence: () => any;
24
+ onCreditDeduction?: any;
25
+ }) =>
26
+ async (req: any, res: any) => {
17
27
  const { content, chatId } = req.body;
18
28
 
19
29
  if (DEBUG) {
@@ -41,7 +51,7 @@ export const handleAIChatMessage =
41
51
  // Create LLM function for streaming
42
52
  const llmFunction = createLLMFunction({
43
53
  shareDBDoc,
44
- localPresence,
54
+ createVizBotLocalPresence,
45
55
  chatId,
46
56
  });
47
57
 
@@ -52,7 +62,6 @@ export const handleAIChatMessage =
52
62
  const editResult = await performAIEditing({
53
63
  prompt: content,
54
64
  shareDBDoc,
55
- chatId,
56
65
  llmFunction,
57
66
  runCode,
58
67
  });
@@ -60,14 +69,15 @@ export const handleAIChatMessage =
60
69
  // Handle credit deduction if callback is provided
61
70
  if (
62
71
  onCreditDeduction &&
63
- editResult.upstreamCostCents
72
+ (editResult as any).upstreamCostCents
64
73
  ) {
65
74
  try {
66
75
  await onCreditDeduction({
67
- upstreamCostCents: editResult.upstreamCostCents,
68
- provider: editResult.provider,
69
- inputTokens: editResult.inputTokens,
70
- outputTokens: editResult.outputTokens,
76
+ upstreamCostCents: (editResult as any)
77
+ .upstreamCostCents,
78
+ provider: (editResult as any).provider,
79
+ inputTokens: (editResult as any).inputTokens,
80
+ outputTokens: (editResult as any).outputTokens,
71
81
  });
72
82
  } catch (creditError) {
73
83
  console.error(
@@ -16,10 +16,11 @@ const DEBUG = false;
16
16
  */
17
17
  export const createLLMFunction = ({
18
18
  shareDBDoc,
19
- localPresence,
19
+ createVizBotLocalPresence,
20
20
  chatId,
21
21
  }) => {
22
22
  return async (fullPrompt) => {
23
+ const localPresence = createVizBotLocalPresence();
23
24
  // Submit initial presence for VizBot
24
25
  const vizBotPresence = {
25
26
  username: 'VizBot',
@@ -68,7 +69,10 @@ export const createLLMFunction = ({
68
69
 
69
70
  // Define callbacks for streaming parser
70
71
  const callbacks = {
71
- onFileNameChange: (fileName, format) => {
72
+ onFileNameChange: async (
73
+ fileName: string,
74
+ format: string,
75
+ ) => {
72
76
  DEBUG &&
73
77
  console.log(
74
78
  `File changed to: ${fileName} (${format})`,
@@ -110,7 +114,7 @@ export const createLLMFunction = ({
110
114
  'Editing ' + fileName,
111
115
  );
112
116
  },
113
- onCodeLine: (line) => {
117
+ onCodeLine: async (line: string) => {
114
118
  DEBUG && console.log(`Code line: ${line}`);
115
119
 
116
120
  if (currentEditingFileId) {
@@ -153,7 +157,7 @@ export const createLLMFunction = ({
153
157
  }
154
158
  }
155
159
  },
156
- onNonCodeLine: (line) => {
160
+ onNonCodeLine: async (line: string) => {
157
161
  // We want to report a file edited only if the line is not empty,
158
162
  // because sometimes the LLMs leave a newline between the file name
159
163
  // declaration and th
@@ -175,20 +179,25 @@ export const createLLMFunction = ({
175
179
  if (chunk.content) {
176
180
  const chunkContent = String(chunk.content);
177
181
  chunks.push(chunkContent);
178
- parser.processChunk(chunkContent);
182
+ await parser.processChunk(chunkContent);
179
183
  }
180
184
 
181
185
  if (!generationId && chunk.lc_kwargs?.id) {
182
186
  generationId = chunk.lc_kwargs.id;
183
187
  }
184
188
  }
185
- parser.flushRemaining();
189
+ await parser.flushRemaining();
186
190
  reportFileEdited();
187
191
  updateAIStatus(shareDBDoc, chatId, 'Done editing.');
188
192
  updateAIScratchpad(shareDBDoc, chatId, fullContent);
189
193
 
190
194
  // Clear VizBot presence when done
191
- localPresence.destroy((error) => {
195
+ DEBUG &&
196
+ console.log(
197
+ 'AI editing done, clearing VizBot presence',
198
+ );
199
+ localPresence.submit(null, (error) => {
200
+ DEBUG && console.log('VizBot presence cleared');
192
201
  if (error) {
193
202
  console.warn(
194
203
  'VizBot presence cleanup error:',
@@ -28,7 +28,8 @@ const slowdown = false;
28
28
 
29
29
  // The options passed into the OpenAI client
30
30
  // new OpenAI(openAIOptions)
31
- const openAIOptions = {};
31
+ const openAIOptions: { apiKey?: string; baseURL?: string } =
32
+ {};
32
33
 
33
34
  // Support specifying the API key via an environment variable
34
35
  // If VZCODE_AI_API_KEY is not set, note that the OpenAI client
@@ -71,7 +72,7 @@ const opComesFromAIAssist = (ops, source) =>
71
72
 
72
73
  // Keeps track of the currently ongoing AI streams.
73
74
  // There could be many streams at the same time.
74
- const streams = {};
75
+ export const streams: Record<string, any> = {};
75
76
 
76
77
  export const generateAIResponse = async ({
77
78
  inputText,
@@ -1,9 +1,12 @@
1
- import { generateAIResponse } from './generateAIResponse.js';
1
+ import {
2
+ generateAIResponse,
3
+ streams,
4
+ } from './generateAIResponse.js';
2
5
 
3
6
  const debug = false;
4
7
 
5
8
  export const handleAIAssist =
6
- (shareDBDoc) => async (req, res) => {
9
+ (shareDBDoc: any) => async (req: any, res: any) => {
7
10
  const { inputText, insertionCursor, fileId } = req.body;
8
11
 
9
12
  if (debug) {
@@ -16,17 +19,21 @@ export const handleAIAssist =
16
19
  }
17
20
 
18
21
  try {
22
+ // Generate a unique streamId for this request
23
+ const streamId = `stream_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
24
+
19
25
  await generateAIResponse({
20
26
  inputText,
21
27
  insertionCursor,
22
28
  fileId,
29
+ streamId,
23
30
  shareDBDoc,
24
31
  });
25
32
 
26
33
  res
27
34
  .status(200)
28
35
  .send({ message: 'Operation successful!' });
29
- } catch (error) {
36
+ } catch (error: any) {
30
37
  console.error('handleAIAssist error:', error);
31
38
  res.status(500).send({
32
39
  message: 'Internal Server Error',
@@ -35,7 +42,7 @@ export const handleAIAssist =
35
42
  }
36
43
  };
37
44
 
38
- export function haltGeneration(streamId) {
45
+ export function haltGeneration(streamId: string) {
39
46
  const stream = streams[streamId];
40
47
 
41
48
  // Stream can be undefined here if the user
@@ -4,7 +4,6 @@ import bodyParser from 'body-parser';
4
4
  import express from 'express';
5
5
  import fs from 'fs';
6
6
  import http from 'http';
7
- import ngrok from 'ngrok';
8
7
  import open from 'open';
9
8
  import path from 'path';
10
9
  import ShareDB from 'sharedb';
@@ -103,9 +102,8 @@ const generateVizBotId = () => {
103
102
  return `vizbot-${timestamp}`;
104
103
  };
105
104
 
106
- const localPresence = docPresence.create(
107
- generateVizBotId(),
108
- );
105
+ const createVizBotLocalPresence = () =>
106
+ docPresence.create(generateVizBotId());
109
107
 
110
108
  shareDBDoc.create(initialDocument, json1Presence.type.uri);
111
109
 
@@ -127,7 +125,11 @@ app.post(
127
125
  app.post(
128
126
  '/ai-chat-message',
129
127
  bodyParser.json(),
130
- handleAIChatMessage({ shareDBDoc, localPresence }),
128
+ handleAIChatMessage({
129
+ shareDBDoc,
130
+ createVizBotLocalPresence,
131
+ onCreditDeduction: undefined,
132
+ }),
131
133
  );
132
134
 
133
135
  // Livekit Token Generator
@@ -335,21 +337,13 @@ shareDBDoc.subscribe(() => {
335
337
  });
336
338
 
337
339
  server.listen(port, async () => {
338
- if (process.env.NGROK_TOKEN) {
339
- (async function () {
340
- await ngrok.authtoken(process.env.NGROK_TOKEN);
341
- const url = await ngrok.connect(port);
342
- console.log(`Editor is live at ${url}`);
343
- open(url);
344
- })();
345
- } else {
346
- // Sets the port to the one specified in the environment
347
- // variable (for development) or the default port.
348
- let livePort = process.env.EDITOR_PORT || port;
349
- console.log(`EDITOR_PORT: ${process.env.EDITOR_PORT}`);
350
- console.log(
351
- `Editor is live at http://localhost:${livePort}`,
352
- );
353
- open(`http://localhost:${livePort}`);
354
- }
340
+ // Note: ngrok support can be added when the package is properly installed
341
+ // Sets the port to the one specified in the environment
342
+ // variable (for development) or the default port.
343
+ let livePort = process.env.EDITOR_PORT || port;
344
+ console.log(`EDITOR_PORT: ${process.env.EDITOR_PORT}`);
345
+ console.log(
346
+ `Editor is live at http://localhost:${livePort}`,
347
+ );
348
+ open(`http://localhost:${livePort}`);
355
349
  });