vzcode 2.22.0 → 2.26.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 (44) hide show
  1. package/dist/assets/{buildWorker-Bi6wsfQk.js → buildWorker-DylWm2VX.js} +64 -72
  2. package/dist/assets/index-CkFweu5-.js +403 -0
  3. package/dist/assets/{index-fSroLVgi.css → index-Dyt9tpmu.css} +1 -5
  4. package/dist/assets/{worker-BSzbM0Uo.js → worker-VPLhQVba.js} +230 -230
  5. package/dist/assets/worker-b9bkZkXK.js +116 -0
  6. package/dist/assets/{worker-Cm3I3tnR.js → worker-k7HZ3t-V.js} +3 -20
  7. package/dist/index.html +2 -2
  8. package/dist/llm-streaming-server/chatOperations.js +19 -0
  9. package/dist/llm-streaming-server/llmStreaming.js +21 -14
  10. package/dist/server/aiChatHandler/index.js +6 -3
  11. package/package.json +23 -22
  12. package/src/llm-streaming-server/chatOperations.ts +27 -0
  13. package/src/llm-streaming-server/llmStreaming.ts +27 -14
  14. package/src/llm-streaming-ui/components/Message.tsx +8 -7
  15. package/src/llm-streaming-ui/components/MessageList.tsx +5 -0
  16. package/src/llm-streaming-ui/components/index.tsx +2 -2
  17. package/src/llm-streaming-ui/components/styles.scss +10 -0
  18. package/src/server/aiChatHandler/index.ts +9 -1
  19. package/src/types.ts +1 -0
  20. package/dist/assets/index-CfDs-dAu.js +0 -476
  21. package/dist/assets/worker-KiuLM-X4.js +0 -136
  22. package/dist/server/aiChatHandler/aiEditing.js +0 -58
  23. package/dist/server/aiChatHandler/chatOperations.js +0 -494
  24. package/dist/server/aiChatHandler/errorHandling.js +0 -49
  25. package/dist/server/aiChatHandler/llmStreaming.js +0 -265
  26. package/dist/server/aiChatHandler/validation.js +0 -19
  27. package/src/client/VZSidebar/AIChat/ChatInput.tsx +0 -237
  28. package/src/client/VZSidebar/AIChat/DiffView.scss +0 -173
  29. package/src/client/VZSidebar/AIChat/DiffView.tsx +0 -236
  30. package/src/client/VZSidebar/AIChat/FileEditingIndicator.tsx +0 -89
  31. package/src/client/VZSidebar/AIChat/IndividualFileDiff.tsx +0 -86
  32. package/src/client/VZSidebar/AIChat/JumpToLatestButton.tsx +0 -64
  33. package/src/client/VZSidebar/AIChat/Message.tsx +0 -145
  34. package/src/client/VZSidebar/AIChat/MessageList.tsx +0 -241
  35. package/src/client/VZSidebar/AIChat/ThinkingScratchpad.tsx +0 -42
  36. package/src/client/VZSidebar/AIChat/TypingIndicator.tsx +0 -19
  37. package/src/client/VZSidebar/AIChat/index.tsx +0 -388
  38. package/src/client/VZSidebar/AIChat/styles.scss +0 -831
  39. package/src/client/VZSidebar/AIChat/useSpeechRecognition.ts +0 -116
  40. package/src/server/aiChatHandler/aiEditing.ts +0 -102
  41. package/src/server/aiChatHandler/chatOperations.ts +0 -655
  42. package/src/server/aiChatHandler/errorHandling.ts +0 -66
  43. package/src/server/aiChatHandler/llmStreaming.ts +0 -403
  44. package/src/server/aiChatHandler/validation.ts +0 -24
package/dist/index.html CHANGED
@@ -20,8 +20,8 @@
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-CfDs-dAu.js"></script>
24
- <link rel="stylesheet" crossorigin href="/assets/index-fSroLVgi.css">
23
+ <script type="module" crossorigin src="/assets/index-CkFweu5-.js"></script>
24
+ <link rel="stylesheet" crossorigin href="/assets/index-Dyt9tpmu.css">
25
25
  </head>
26
26
  <body>
27
27
  <div id="root"></div>
@@ -402,6 +402,25 @@ export const updateStreamingStatus = (shareDBDoc, chatId, status, isStreaming =
402
402
  });
403
403
  shareDBDoc.submitOp(op);
404
404
  };
405
+ /**
406
+ * Sets the model for a chat when AI generation starts
407
+ */
408
+ export const setChatModel = (shareDBDoc, chatId, model) => {
409
+ DEBUG &&
410
+ console.log(`ChatOperations: Setting model: "${model}" for chatId: ${chatId}`);
411
+ const op = diff(shareDBDoc.data, {
412
+ ...shareDBDoc.data,
413
+ chats: {
414
+ ...shareDBDoc.data.chats,
415
+ [chatId]: {
416
+ ...shareDBDoc.data.chats[chatId],
417
+ model: model,
418
+ updatedAt: dateToTimestamp(new Date()),
419
+ },
420
+ },
421
+ });
422
+ shareDBDoc.submitOp(op);
423
+ };
405
424
  /**
406
425
  * Finalizes streaming message and clears streaming state
407
426
  */
@@ -1,7 +1,7 @@
1
1
  import OpenAI from 'openai';
2
2
  import { parseMarkdownFiles, StreamingMarkdownParser, } from 'llm-code-format';
3
3
  import { mergeFileChanges } from 'editcodewithai';
4
- import { updateFiles, updateAIScratchpad, createStreamingAIMessage, addStreamingEvent, updateStreamingStatus, finalizeStreamingMessage, } from './chatOperations.js';
4
+ import { updateFiles, updateAIScratchpad, createStreamingAIMessage, addStreamingEvent, updateStreamingStatus, finalizeStreamingMessage, setChatModel, } from './chatOperations.js';
5
5
  import { formatFiles } from '../server/prettier.js';
6
6
  // Verbose logs
7
7
  const DEBUG = false;
@@ -22,9 +22,15 @@ export const createLLMFunction = ({ shareDBDoc, chatId,
22
22
  enableReasoningTokens = false, model, aiRequestOptions, }) => {
23
23
  return async (fullPrompt) => {
24
24
  // Create OpenRouter client for reasoning token support
25
+ const apiKey = aiRequestOptions?.apiKey ||
26
+ process.env.VZCODE_EDIT_WITH_AI_API_KEY;
27
+ if (!apiKey) {
28
+ console.warn('[LLMStreaming] OpenAI API Key not found');
29
+ }
25
30
  const openRouterClient = new OpenAI({
26
- apiKey: process.env.VZCODE_EDIT_WITH_AI_API_KEY,
27
- baseURL: process.env.VZCODE_EDIT_WITH_AI_BASE_URL ||
31
+ apiKey: apiKey,
32
+ baseURL: aiRequestOptions?.baseURL ||
33
+ process.env.VZCODE_EDIT_WITH_AI_BASE_URL ||
28
34
  'https://openrouter.ai/api/v1',
29
35
  defaultHeaders: {
30
36
  'HTTP-Referer': 'https://vizhub.com',
@@ -36,8 +42,14 @@ enableReasoningTokens = false, model, aiRequestOptions, }) => {
36
42
  let currentEditingFileName = null;
37
43
  let accumulatedTextChunk = '';
38
44
  let currentFileContent = '';
45
+ // Stream the response with reasoning tokens
46
+ const modelName = model ||
47
+ process.env.VZCODE_EDIT_WITH_AI_MODEL_NAME ||
48
+ 'anthropic/claude-haiku-4.5';
39
49
  // Create streaming AI message
40
50
  createStreamingAIMessage(shareDBDoc, chatId);
51
+ // Set the model being used for this chat
52
+ setChatModel(shareDBDoc, chatId, modelName);
41
53
  // Set initial content generation status
42
54
  updateStreamingStatus(shareDBDoc, chatId, 'Formulating a plan...');
43
55
  // Helper to get original file content
@@ -145,25 +157,20 @@ enableReasoningTokens = false, model, aiRequestOptions, }) => {
145
157
  const parser = new StreamingMarkdownParser(callbacks);
146
158
  const chunks = [];
147
159
  let reasoningContent = '';
148
- // Stream the response with reasoning tokens
149
- const modelName = model ||
150
- process.env.VZCODE_EDIT_WITH_AI_MODEL_NAME ||
151
- 'anthropic/claude-3.5-sonnet';
152
160
  // Configure reasoning tokens based on enableReasoningTokens flag
153
161
  const requestConfig = {
154
162
  model: modelName,
155
163
  messages: [{ role: 'user', content: fullPrompt }],
156
- usage: { include: true },
157
164
  stream: true,
158
165
  ...aiRequestOptions,
159
166
  };
160
167
  // Only include reasoning configuration if reasoning tokens are enabled
161
- if (enableReasoningTokens) {
162
- requestConfig.reasoning = {
163
- effort: 'low',
164
- exclude: false,
165
- };
166
- }
168
+ // if (enableReasoningTokens) {
169
+ // requestConfig.reasoning = {
170
+ // effort: 'low',
171
+ // exclude: false,
172
+ // };
173
+ // }
167
174
  const stream = await openRouterClient.chat.completions.create(requestConfig);
168
175
  let reasoningStarted = false;
169
176
  let contentStarted = false;
@@ -7,7 +7,7 @@ import { createRunCodeFunction } from '../../runCode.js';
7
7
  import { createSubmitOperation } from '../../submitOperation.js';
8
8
  import { getGenerationMetadata } from 'editcodewithai';
9
9
  const DEBUG = false;
10
- export const handleAIChatMessage = ({ shareDBDoc, onCreditDeduction, model, aiRequestOptions, }) => async (req, res) => {
10
+ export const handleAIChatMessage = ({ shareDBDoc, onCreditDeduction, model, aiRequestOptions, enableReasoningTokens, }) => async (req, res) => {
11
11
  const { content, chatId } = req.body;
12
12
  if (DEBUG) {
13
13
  console.log('[handleAIChatMessage] content:', content, 'chatId:', chatId, 'shareDBDoc:', shareDBDoc);
@@ -31,6 +31,7 @@ export const handleAIChatMessage = ({ shareDBDoc, onCreditDeduction, model, aiRe
31
31
  content,
32
32
  model,
33
33
  aiRequestOptions,
34
+ enableReasoningTokens,
34
35
  onCreditDeduction,
35
36
  }).catch((error) => {
36
37
  console.error('Background AI processing error:', error);
@@ -45,12 +46,13 @@ export const handleAIChatMessage = ({ shareDBDoc, onCreditDeduction, model, aiRe
45
46
  /**
46
47
  * Processes the AI request asynchronously in the background
47
48
  */
48
- const processAIRequestAsync = async ({ shareDBDoc, chatId, content, model, aiRequestOptions, onCreditDeduction, }) => {
49
+ const processAIRequestAsync = async ({ shareDBDoc, chatId, content, model, aiRequestOptions, enableReasoningTokens, onCreditDeduction, }) => {
49
50
  try {
50
51
  // Create LLM function for streaming
51
52
  const llmFunction = createLLMFunction({
52
53
  shareDBDoc,
53
54
  chatId,
55
+ enableReasoningTokens: enableReasoningTokens ?? true,
54
56
  model,
55
57
  aiRequestOptions,
56
58
  });
@@ -68,7 +70,8 @@ const processAIRequestAsync = async ({ shareDBDoc, chatId, content, model, aiReq
68
70
  if (onCreditDeduction && editResult.generationId) {
69
71
  try {
70
72
  await onCreditDeduction(await getGenerationMetadata({
71
- apiKey: process.env.VZCODE_EDIT_WITH_AI_API_KEY,
73
+ apiKey: aiRequestOptions?.apiKey ||
74
+ process.env.VZCODE_EDIT_WITH_AI_API_KEY,
72
75
  generationId: editResult.generationId,
73
76
  }));
74
77
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vzcode",
3
- "version": "2.22.0",
3
+ "version": "2.26.0",
4
4
  "description": "Multiplayer code editor system",
5
5
  "main": "src/index.ts",
6
6
  "type": "module",
@@ -11,7 +11,7 @@
11
11
  ],
12
12
  "scripts": {
13
13
  "test": "vitest run",
14
- "test-interactive": "cd test/sampleDirectories/playground && node --import \"data:text/javascript,import { register } from 'node:module'; import { pathToFileURL } from 'node:url'; register('ts-node/esm', pathToFileURL('./'));\" ../../../src/server/index.ts",
14
+ "test-interactive": "cd test/sampleDirectories/playground && tsx ../../../src/server/index.ts",
15
15
  "prettier": "prettier {*.*,**/*.*} --write",
16
16
  "typecheck": "tsc --noEmit",
17
17
  "lint": "eslint . --ext .js,.ts,.tsx",
@@ -110,7 +110,7 @@
110
110
  },
111
111
  "homepage": "https://github.com/vizhub-core/vzcode#readme",
112
112
  "dependencies": {
113
- "@codemirror/autocomplete": "^6.19.1",
113
+ "@codemirror/autocomplete": "^6.20.0",
114
114
  "@codemirror/lang-css": "^6.3.1",
115
115
  "@codemirror/lang-html": "^6.4.11",
116
116
  "@codemirror/lang-javascript": "^6.2.4",
@@ -119,11 +119,11 @@
119
119
  "@codemirror/lint": "^6.9.2",
120
120
  "@codemirror/state": "^6.5.2",
121
121
  "@codemirror/theme-one-dark": "^6.1.3",
122
- "@codemirror/view": "^6.38.6",
123
- "@langchain/core": "^1.0.3",
124
- "@langchain/openai": "^1.0.0",
122
+ "@codemirror/view": "^6.38.8",
123
+ "@langchain/core": "^1.1.0",
124
+ "@langchain/openai": "^1.1.3",
125
125
  "@lezer/highlight": "^1.2.3",
126
- "@livekit/components-react": "^2.9.15",
126
+ "@livekit/components-react": "^2.9.16",
127
127
  "@replit/codemirror-indentation-markers": "^6.5.3",
128
128
  "@replit/codemirror-interact": "^6.3.1",
129
129
  "@replit/codemirror-lang-svelte": "^6.0.0",
@@ -143,7 +143,7 @@
143
143
  "@vizhub/runtime": "^4.5.0",
144
144
  "@vizhub/viz-types": "^0.5.0",
145
145
  "@vizhub/viz-utils": "^1.5.0",
146
- "body-parser": "^2.2.0",
146
+ "body-parser": "^2.2.1",
147
147
  "bootstrap-icons": "^1.13.1",
148
148
  "codemirror": "^6.0.2",
149
149
  "codemirror-copilot": "^0.0.7",
@@ -162,17 +162,17 @@
162
162
  "ignore": "^7.0.5",
163
163
  "json0-ot-diff": "^1.1.2",
164
164
  "jszip": "^3.10.1",
165
- "livekit-server-sdk": "^2.14.0",
165
+ "livekit-server-sdk": "^2.14.2",
166
166
  "llm-code-format": "^3.1.0",
167
- "lucide-react": "^0.553.0",
168
- "npm": "^11.6.2",
169
- "open": "^10.2.0",
167
+ "lucide-react": "^0.555.0",
168
+ "npm": "^11.6.4",
169
+ "open": "^11.0.0",
170
170
  "prettier-plugin-svelte": "^3.4.0",
171
171
  "react": "^18",
172
172
  "react-bootstrap": "^2.10.10",
173
173
  "react-dom": "^18",
174
174
  "react-markdown": "^10.1.0",
175
- "react-router-dom": "^7.9.5",
175
+ "react-router-dom": "^7.9.6",
176
176
  "remark-gfm": "^4.0.1",
177
177
  "sharedb": "^5.2.2",
178
178
  "sharedb-client-browser": "^5.2.2",
@@ -182,13 +182,13 @@
182
182
  },
183
183
  "devDependencies": {
184
184
  "@eslint/js": "^9.39.1",
185
- "@tauri-apps/cli": "^2.9.3",
185
+ "@tauri-apps/cli": "^2.9.4",
186
186
  "@types/d3-color": "^3.1.3",
187
187
  "@types/react": "^18",
188
188
  "@types/react-dom": "^18",
189
- "@typescript-eslint/eslint-plugin": "^8.46.3",
190
- "@typescript-eslint/parser": "^8.46.3",
191
- "@vitejs/plugin-react": "^5.1.0",
189
+ "@typescript-eslint/eslint-plugin": "^8.48.0",
190
+ "@typescript-eslint/parser": "^8.48.0",
191
+ "@vitejs/plugin-react": "^5.1.1",
192
192
  "concurrently": "^9.2.1",
193
193
  "cross-env": "^10.1.0",
194
194
  "eslint": "^9.39.1",
@@ -198,14 +198,15 @@
198
198
  "globals": "^16.5.0",
199
199
  "npm-check-updates": "^19.1.2",
200
200
  "prettier": "^3.6.2",
201
- "sass": "^1.93.3",
201
+ "sass": "^1.94.2",
202
202
  "ts-node": "^10.9.2",
203
+ "tsx": "^4.20.6",
203
204
  "typescript": "^5.9.3",
204
- "vite": "^7.2.2",
205
- "vitest": "^4.0.8"
205
+ "vite": "^7.2.4",
206
+ "vitest": "^4.0.14"
206
207
  },
207
208
  "optionalDependencies": {
208
- "@rollup/rollup-darwin-arm64": "^4.53.1",
209
- "@rollup/rollup-win32-x64-msvc": "^4.53.1"
209
+ "@rollup/rollup-darwin-arm64": "^4.53.3",
210
+ "@rollup/rollup-win32-x64-msvc": "^4.53.3"
210
211
  }
211
212
  }
@@ -543,6 +543,33 @@ export const updateStreamingStatus = (
543
543
  shareDBDoc.submitOp(op);
544
544
  };
545
545
 
546
+ /**
547
+ * Sets the model for a chat when AI generation starts
548
+ */
549
+ export const setChatModel = (
550
+ shareDBDoc: ShareDBDoc<ExtendedVizContent>,
551
+ chatId: VizChatId,
552
+ model: string,
553
+ ) => {
554
+ DEBUG &&
555
+ console.log(
556
+ `ChatOperations: Setting model: "${model}" for chatId: ${chatId}`,
557
+ );
558
+
559
+ const op = diff(shareDBDoc.data, {
560
+ ...shareDBDoc.data,
561
+ chats: {
562
+ ...shareDBDoc.data.chats,
563
+ [chatId]: {
564
+ ...shareDBDoc.data.chats[chatId],
565
+ model: model,
566
+ updatedAt: dateToTimestamp(new Date()),
567
+ },
568
+ },
569
+ });
570
+ shareDBDoc.submitOp(op);
571
+ };
572
+
546
573
  /**
547
574
  * Finalizes streaming message and clears streaming state
548
575
  */
@@ -16,6 +16,7 @@ import {
16
16
  addStreamingEvent,
17
17
  updateStreamingStatus,
18
18
  finalizeStreamingMessage,
19
+ setChatModel,
19
20
  } from './chatOperations.js';
20
21
  import {
21
22
  ShareDBDoc,
@@ -56,9 +57,19 @@ export const createLLMFunction = ({
56
57
  }) => {
57
58
  return async (fullPrompt: string) => {
58
59
  // Create OpenRouter client for reasoning token support
60
+ const apiKey =
61
+ aiRequestOptions?.apiKey ||
62
+ process.env.VZCODE_EDIT_WITH_AI_API_KEY;
63
+ if (!apiKey) {
64
+ console.warn(
65
+ '[LLMStreaming] OpenAI API Key not found',
66
+ );
67
+ }
68
+
59
69
  const openRouterClient = new OpenAI({
60
- apiKey: process.env.VZCODE_EDIT_WITH_AI_API_KEY,
70
+ apiKey: apiKey,
61
71
  baseURL:
72
+ aiRequestOptions?.baseURL ||
62
73
  process.env.VZCODE_EDIT_WITH_AI_BASE_URL ||
63
74
  'https://openrouter.ai/api/v1',
64
75
  defaultHeaders: {
@@ -73,9 +84,18 @@ export const createLLMFunction = ({
73
84
  let accumulatedTextChunk = '';
74
85
  let currentFileContent = '';
75
86
 
87
+ // Stream the response with reasoning tokens
88
+ const modelName =
89
+ model ||
90
+ process.env.VZCODE_EDIT_WITH_AI_MODEL_NAME ||
91
+ 'anthropic/claude-haiku-4.5';
92
+
76
93
  // Create streaming AI message
77
94
  createStreamingAIMessage(shareDBDoc, chatId);
78
95
 
96
+ // Set the model being used for this chat
97
+ setChatModel(shareDBDoc, chatId, modelName);
98
+
79
99
  // Set initial content generation status
80
100
  updateStreamingStatus(
81
101
  shareDBDoc,
@@ -232,28 +252,21 @@ export const createLLMFunction = ({
232
252
  const chunks = [];
233
253
  let reasoningContent = '';
234
254
 
235
- // Stream the response with reasoning tokens
236
- const modelName =
237
- model ||
238
- process.env.VZCODE_EDIT_WITH_AI_MODEL_NAME ||
239
- 'anthropic/claude-3.5-sonnet';
240
-
241
255
  // Configure reasoning tokens based on enableReasoningTokens flag
242
256
  const requestConfig: any = {
243
257
  model: modelName,
244
258
  messages: [{ role: 'user', content: fullPrompt }],
245
- usage: { include: true },
246
259
  stream: true,
247
260
  ...aiRequestOptions,
248
261
  };
249
262
 
250
263
  // Only include reasoning configuration if reasoning tokens are enabled
251
- if (enableReasoningTokens) {
252
- requestConfig.reasoning = {
253
- effort: 'low',
254
- exclude: false,
255
- };
256
- }
264
+ // if (enableReasoningTokens) {
265
+ // requestConfig.reasoning = {
266
+ // effort: 'low',
267
+ // exclude: false,
268
+ // };
269
+ // }
257
270
 
258
271
  const stream = await (
259
272
  openRouterClient.chat.completions.create as any
@@ -13,7 +13,7 @@ import { DiffView, DiffViewRef } from './DiffView';
13
13
  import { UnifiedFilesDiff } from '../../utils/fileDiff';
14
14
  import { enableDiffView } from '../../client/featureFlags';
15
15
 
16
- const DEBUG = false;
16
+ const DEBUG = true;
17
17
 
18
18
  interface MessageProps {
19
19
  id: string;
@@ -26,6 +26,7 @@ interface MessageProps {
26
26
  showAdditionalWidgets?: boolean;
27
27
  isStreaming?: boolean;
28
28
  diffData?: UnifiedFilesDiff;
29
+ model?: string; // The LLM model used for this message (assistant only)
29
30
  }
30
31
 
31
32
  export const Message = forwardRef<
@@ -45,18 +46,13 @@ export const Message = forwardRef<
45
46
  showAdditionalWidgets = false,
46
47
  isStreaming = false,
47
48
  diffData,
49
+ model,
48
50
  },
49
51
  ref,
50
52
  ) => {
51
53
  const { additionalWidgets, handleSendMessage } =
52
54
  useContext(VZCodeContext);
53
55
 
54
- DEBUG &&
55
- console.log(
56
- 'StreamingMessage: Rendered with events:',
57
- events,
58
- );
59
-
60
56
  // Memoize date formatting to avoid repeated computation
61
57
  const formattedTime = useMemo(() => {
62
58
  return timestampToDate(timestamp).toLocaleTimeString(
@@ -76,6 +72,11 @@ export const Message = forwardRef<
76
72
  return (
77
73
  <div className={messageClassName}>
78
74
  <div className="ai-chat-message-content">
75
+ {/* Model indicator for assistant messages */}
76
+ {role === 'assistant' && model && (
77
+ <div className="model-indicator">{model}</div>
78
+ )}
79
+
79
80
  {/* Render regular content for non-streaming messages */}
80
81
  {content && (
81
82
  <Markdown remarkPlugins={[remarkGfm]}>
@@ -20,6 +20,7 @@ const MessageListComponent = ({
20
20
  chatId, // Add chatId prop
21
21
  aiScratchpad, // Add aiScratchpad prop
22
22
  currentStatus, // Add current status prop
23
+ model, // Add model prop
23
24
  onNewEvent,
24
25
  onJumpToLatest,
25
26
  beforeRender,
@@ -30,6 +31,7 @@ const MessageListComponent = ({
30
31
  chatId?: string; // Add chatId to the type
31
32
  aiScratchpad?: string; // Add aiScratchpad to the type
32
33
  currentStatus?: string; // Add current status to the type
34
+ model?: string; // Add model to the type
33
35
  onNewEvent: (targetElement?: HTMLElement) => void;
34
36
  onJumpToLatest: (targetElement?: HTMLElement) => void;
35
37
  beforeRender: () => number;
@@ -192,6 +194,9 @@ const MessageListComponent = ({
192
194
  showAdditionalWidgets={showAdditionalWidgets}
193
195
  isStreaming={isStreamingMessage}
194
196
  diffData={(msg as any).diffData}
197
+ model={
198
+ msg.role === 'assistant' ? model : undefined
199
+ }
195
200
  ref={
196
201
  isLastMessage && (msg as any).diffData
197
202
  ? diffViewRef
@@ -92,9 +92,8 @@ export const AIChat = () => {
92
92
  const aiScratchpad = currentChat?.aiScratchpad;
93
93
  const currentStatus = (currentChat as ExtendedVizChat)
94
94
  ?.currentStatus;
95
+ const model = (currentChat as ExtendedVizChat)?.model;
95
96
 
96
- // Debug logging for AI status
97
- DEBUG && console.log('AIChat: currentChat:', currentChat);
98
97
  DEBUG && console.log('AIChat: aiStatus:', aiStatus);
99
98
  DEBUG &&
100
99
  console.log(
@@ -332,6 +331,7 @@ export const AIChat = () => {
332
331
  chatId={selectedChatId || currentChatId}
333
332
  aiScratchpad={aiScratchpad}
334
333
  currentStatus={currentStatus}
334
+ model={model}
335
335
  onNewEvent={onNewEvent}
336
336
  onJumpToLatest={onJumpToLatest}
337
337
  beforeRender={beforeRender}
@@ -314,6 +314,16 @@
314
314
  padding: 0 1em;
315
315
  }
316
316
 
317
+ .model-indicator {
318
+ opacity: 0.6;
319
+ font-size: 0.7rem;
320
+ color: var(--vscode-descriptionForeground);
321
+ padding: 0.25rem 0.5rem;
322
+ font-family: var(--vscode-editor-font-family);
323
+ letter-spacing: 0.3px;
324
+ margin-bottom: 0.5rem;
325
+ }
326
+
317
327
  padding: 10px 12px;
318
328
  font-size: 14px;
319
329
  line-height: 1.4;
@@ -25,11 +25,13 @@ export const handleAIChatMessage =
25
25
  onCreditDeduction,
26
26
  model,
27
27
  aiRequestOptions,
28
+ enableReasoningTokens,
28
29
  }: {
29
30
  shareDBDoc: ShareDBDoc<VizContent>;
30
31
  onCreditDeduction?: any;
31
32
  model?: string;
32
33
  aiRequestOptions?: any;
34
+ enableReasoningTokens?: boolean;
33
35
  }) =>
34
36
  async (req: any, res: any) => {
35
37
  const { content, chatId } = req.body;
@@ -68,6 +70,7 @@ export const handleAIChatMessage =
68
70
  content,
69
71
  model,
70
72
  aiRequestOptions,
73
+ enableReasoningTokens,
71
74
  onCreditDeduction,
72
75
  }).catch((error) => {
73
76
  console.error(
@@ -91,6 +94,7 @@ const processAIRequestAsync = async ({
91
94
  content,
92
95
  model,
93
96
  aiRequestOptions,
97
+ enableReasoningTokens,
94
98
  onCreditDeduction,
95
99
  }: {
96
100
  shareDBDoc: ShareDBDoc<VizContent>;
@@ -98,6 +102,7 @@ const processAIRequestAsync = async ({
98
102
  content: string;
99
103
  model?: string;
100
104
  aiRequestOptions?: any;
105
+ enableReasoningTokens?: boolean;
101
106
  onCreditDeduction?: any;
102
107
  }) => {
103
108
  try {
@@ -105,6 +110,7 @@ const processAIRequestAsync = async ({
105
110
  const llmFunction = createLLMFunction({
106
111
  shareDBDoc,
107
112
  chatId,
113
+ enableReasoningTokens: enableReasoningTokens ?? true,
108
114
  model,
109
115
  aiRequestOptions,
110
116
  });
@@ -127,7 +133,9 @@ const processAIRequestAsync = async ({
127
133
  try {
128
134
  await onCreditDeduction(
129
135
  await getGenerationMetadata({
130
- apiKey: process.env.VZCODE_EDIT_WITH_AI_API_KEY,
136
+ apiKey:
137
+ aiRequestOptions?.apiKey ||
138
+ process.env.VZCODE_EDIT_WITH_AI_API_KEY,
131
139
  generationId: editResult.generationId,
132
140
  }),
133
141
  );
package/src/types.ts CHANGED
@@ -261,6 +261,7 @@ export interface ExtendedVizChat extends VizChat {
261
261
  streamingEvents?: StreamingEvent[];
262
262
  currentStatus?: string;
263
263
  isStreaming?: boolean;
264
+ model?: string; // The LLM model used for this chat
264
265
  }
265
266
 
266
267
  // Extended VizChatMessage with progressive rendering support