vzcode 1.60.0 → 1.62.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/bootstrap-icons-BeopsB42.woff +0 -0
- package/dist/assets/bootstrap-icons-mSm7cUeB.woff2 +0 -0
- package/dist/assets/{index-DMIy-XE4.css → index-Br76WttW.css} +5 -1
- package/dist/assets/{index-S-R8oY72.js → index-vbF7Aejt.js} +174 -174
- package/dist/index.html +2 -2
- package/package.json +7 -6
- package/src/client/Icons/AdjustmentSVG.tsx +19 -0
- package/src/client/Icons/index.tsx +1 -0
- package/src/client/VZCodeContext/types.ts +13 -1
- package/src/client/VZCodeContext/useVZCodeState.ts +83 -5
- package/src/client/VZRight.tsx +6 -3
- package/src/client/VZSidebar/AIChat/ChatInput.tsx +45 -2
- package/src/client/VZSidebar/AIChat/MessageList.tsx +2 -0
- package/src/client/VZSidebar/AIChat/index.tsx +12 -0
- package/src/client/VZSidebar/EmptyState.tsx +11 -0
- package/src/client/VZSidebar/VisualEditor.tsx +295 -0
- package/src/client/VZSidebar/index.tsx +64 -0
- package/src/client/VZSidebar/styles.scss +213 -1
- package/src/client/bootstrap.ts +3 -0
- package/src/client/useActions.ts +12 -0
- package/src/client/vzReducer/closeTabReducer.test.ts +33 -21
- package/src/client/vzReducer/createInitialState.ts +1 -0
- package/src/client/vzReducer/index.ts +9 -0
- package/src/client/vzReducer/searchReducer.test.ts +1 -1
- package/src/client/vzReducer/visualEditorReducer.ts +9 -0
- package/src/server/aiChatHandler/chatOperations.ts +22 -0
- package/src/server/aiChatHandler/errorHandling.ts +17 -4
- package/src/server/aiChatHandler/index.ts +131 -67
- package/src/server/aiChatHandler/llmStreaming.ts +76 -27
- package/src/types.ts +12 -0
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-
|
|
24
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
23
|
+
<script type="module" crossorigin src="/assets/index-vbF7Aejt.js"></script>
|
|
24
|
+
<link rel="stylesheet" crossorigin href="/assets/index-Br76WttW.css">
|
|
25
25
|
</head>
|
|
26
26
|
<body>
|
|
27
27
|
<div id="root"></div>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vzcode",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.62.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/
|
|
14
|
+
"test-interactive": "cd test/sampleDirectories/visualEditor && node --import \"data:text/javascript,import { register } from 'node:module'; import { pathToFileURL } from 'node:url'; register('ts-node/esm', pathToFileURL('./'));\" ../../../src/server/index.ts",
|
|
15
15
|
"prettier": "prettier {*.*,**/*.*} --write",
|
|
16
16
|
"typecheck": "tsc --noEmit",
|
|
17
17
|
"dev": "cross-env EDITOR_PORT=5173 concurrently \"npm run test-interactive\" \"vite\"",
|
|
@@ -117,8 +117,8 @@
|
|
|
117
117
|
"@codemirror/state": "^6.5.2",
|
|
118
118
|
"@codemirror/theme-one-dark": "^6.1.3",
|
|
119
119
|
"@codemirror/view": "^6.38.1",
|
|
120
|
-
"@langchain/core": "^0.3.
|
|
121
|
-
"@langchain/openai": "^0.6.
|
|
120
|
+
"@langchain/core": "^0.3.68",
|
|
121
|
+
"@langchain/openai": "^0.6.7",
|
|
122
122
|
"@lezer/highlight": "^1.2.1",
|
|
123
123
|
"@livekit/components-react": "^2.9.14",
|
|
124
124
|
"@replit/codemirror-indentation-markers": "^6.5.3",
|
|
@@ -141,6 +141,7 @@
|
|
|
141
141
|
"@vizhub/viz-types": "^0.4.0",
|
|
142
142
|
"@vizhub/viz-utils": "^1.4.0",
|
|
143
143
|
"body-parser": "^2.2.0",
|
|
144
|
+
"bootstrap-icons": "^1.13.1",
|
|
144
145
|
"codemirror": "^6.0.2",
|
|
145
146
|
"codemirror-copilot": "^0.0.7",
|
|
146
147
|
"codemirror-ot": "^5.0.0",
|
|
@@ -166,7 +167,7 @@
|
|
|
166
167
|
"react-bootstrap": "^2.10.10",
|
|
167
168
|
"react-dom": "^18",
|
|
168
169
|
"react-markdown": "^10.1.0",
|
|
169
|
-
"react-router-dom": "^7.
|
|
170
|
+
"react-router-dom": "^7.8.0",
|
|
170
171
|
"remark-gfm": "^4.0.1",
|
|
171
172
|
"sharedb": "^5.2.2",
|
|
172
173
|
"sharedb-client-browser": "^5.2.2",
|
|
@@ -189,7 +190,7 @@
|
|
|
189
190
|
"sass": "^1.90.0",
|
|
190
191
|
"ts-node": "^10.9.2",
|
|
191
192
|
"typescript": "^5.9.2",
|
|
192
|
-
"vite": "^7.1.
|
|
193
|
+
"vite": "^7.1.1",
|
|
193
194
|
"vitest": "^3.2.4"
|
|
194
195
|
},
|
|
195
196
|
"optionalDependencies": {
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
//From Hero Icons
|
|
2
|
+
export const AdjustmentSVG = () => (
|
|
3
|
+
<svg
|
|
4
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
5
|
+
fill="none"
|
|
6
|
+
viewBox="0 0 24 24"
|
|
7
|
+
strokeWidth={1.5}
|
|
8
|
+
stroke="currentColor"
|
|
9
|
+
className="size-6"
|
|
10
|
+
width={32}
|
|
11
|
+
height={32}
|
|
12
|
+
>
|
|
13
|
+
<path
|
|
14
|
+
strokeLinecap="round"
|
|
15
|
+
strokeLinejoin="round"
|
|
16
|
+
d="M10.5 6h9.75M10.5 6a1.5 1.5 0 1 1-3 0m3 0a1.5 1.5 0 1 0-3 0M3.75 6H7.5m3 12h9.75m-9.75 0a1.5 1.5 0 0 1-3 0m3 0a1.5 1.5 0 0 0-3 0m-3.75 0H7.5m9-6h3.75m-3.75 0a1.5 1.5 0 0 1-3 0m3 0a1.5 1.5 0 0 0-3 0m-9.75 0h9.75"
|
|
17
|
+
/>
|
|
18
|
+
</svg>
|
|
19
|
+
);
|
|
@@ -90,6 +90,11 @@ export type VZCodeContextValue = {
|
|
|
90
90
|
setIsSearchOpen: (isSearchOpen: boolean) => void;
|
|
91
91
|
setSearch: (pattern: string) => void;
|
|
92
92
|
|
|
93
|
+
isVisualEditorOpen: boolean;
|
|
94
|
+
setIsVisualEditorOpen: (
|
|
95
|
+
isVisualEditorOpen: boolean,
|
|
96
|
+
) => void;
|
|
97
|
+
|
|
93
98
|
isAIChatOpen: boolean;
|
|
94
99
|
setIsAIChatOpen: (isAIChatOpen: boolean) => void;
|
|
95
100
|
aiChatFocused: boolean;
|
|
@@ -137,6 +142,8 @@ export type VZCodeContextValue = {
|
|
|
137
142
|
|
|
138
143
|
codeEditorRef: React.RefObject<HTMLDivElement>;
|
|
139
144
|
|
|
145
|
+
iframeRef: React.MutableRefObject<HTMLIFrameElement>;
|
|
146
|
+
|
|
140
147
|
connected: boolean;
|
|
141
148
|
pending: boolean;
|
|
142
149
|
|
|
@@ -164,7 +171,6 @@ export type VZCodeContextValue = {
|
|
|
164
171
|
aiChatMessage: string;
|
|
165
172
|
setAIChatMessage: (message: string) => void;
|
|
166
173
|
isLoading: boolean;
|
|
167
|
-
setIsLoading: (state: boolean) => void;
|
|
168
174
|
currentChatId: string;
|
|
169
175
|
aiErrorMessage: string | null;
|
|
170
176
|
setAIErrorMessage: (state: string | null) => void;
|
|
@@ -173,6 +179,11 @@ export type VZCodeContextValue = {
|
|
|
173
179
|
options?: Record<string, string>,
|
|
174
180
|
) => void;
|
|
175
181
|
|
|
182
|
+
// Message history navigation
|
|
183
|
+
navigateMessageHistoryUp: () => void;
|
|
184
|
+
navigateMessageHistoryDown: () => void;
|
|
185
|
+
resetMessageHistoryNavigation: () => void;
|
|
186
|
+
|
|
176
187
|
// Auto-fork functions for VizHub integration
|
|
177
188
|
autoForkAndRetryAI?: (
|
|
178
189
|
prompt: string,
|
|
@@ -233,4 +244,5 @@ export interface VZCodeProviderProps {
|
|
|
233
244
|
chatId: string;
|
|
234
245
|
canUndo: boolean;
|
|
235
246
|
}>;
|
|
247
|
+
iframeRef?: React.MutableRefObject<HTMLIFrameElement>;
|
|
236
248
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
useCallback,
|
|
3
|
+
useMemo,
|
|
3
4
|
useReducer,
|
|
4
5
|
useRef,
|
|
5
6
|
useState,
|
|
@@ -51,6 +52,7 @@ export const useVZCodeState = ({
|
|
|
51
52
|
clearStoredAIPrompt,
|
|
52
53
|
getStoredAIPrompt,
|
|
53
54
|
additionalWidgets,
|
|
55
|
+
iframeRef: externalIframeRef,
|
|
54
56
|
}: Omit<
|
|
55
57
|
VZCodeProviderProps,
|
|
56
58
|
'children'
|
|
@@ -75,6 +77,9 @@ export const useVZCodeState = ({
|
|
|
75
77
|
|
|
76
78
|
const codeEditorRef = useRef(null);
|
|
77
79
|
|
|
80
|
+
// Use external iframeRef if provided, otherwise create our own
|
|
81
|
+
const iframeRef = externalIframeRef || useRef(null);
|
|
82
|
+
|
|
78
83
|
// The error message shows errors in order of priority:
|
|
79
84
|
// * `runtimeError` - errors from runtime execution, highest priority
|
|
80
85
|
// * `prettierError` - errors from Prettier, client-side only
|
|
@@ -104,6 +109,7 @@ export const useVZCodeState = ({
|
|
|
104
109
|
theme,
|
|
105
110
|
search,
|
|
106
111
|
isSearchOpen,
|
|
112
|
+
isVisualEditorOpen,
|
|
107
113
|
isAIChatOpen,
|
|
108
114
|
aiChatFocused,
|
|
109
115
|
isSettingsOpen,
|
|
@@ -136,6 +142,7 @@ export const useVZCodeState = ({
|
|
|
136
142
|
setSearchLineVisibility,
|
|
137
143
|
setSearchFocusedIndex,
|
|
138
144
|
toggleSearchFocused,
|
|
145
|
+
setIsVisualEditorOpen,
|
|
139
146
|
setIsAIChatOpen,
|
|
140
147
|
toggleAIChatFocused,
|
|
141
148
|
setAIChatMode,
|
|
@@ -262,12 +269,72 @@ export const useVZCodeState = ({
|
|
|
262
269
|
|
|
263
270
|
const DEBUG = false;
|
|
264
271
|
|
|
265
|
-
|
|
272
|
+
// Compute isLoading based on the current chat's aiStatus
|
|
266
273
|
const [currentChatId] = useState(() => uuidv4());
|
|
274
|
+
const currentChat = content?.chats?.[currentChatId];
|
|
275
|
+
const isLoading = currentChat?.aiStatus === 'generating';
|
|
276
|
+
|
|
277
|
+
// Message history for up/down arrow navigation - using ShareDB document data
|
|
278
|
+
const messageHistory = useMemo(() => {
|
|
279
|
+
if (!currentChat?.messages) return [];
|
|
280
|
+
// Extract user messages in chronological order for history navigation
|
|
281
|
+
return currentChat.messages
|
|
282
|
+
.filter((msg) => msg.role === 'user')
|
|
283
|
+
.map((msg) => msg.content);
|
|
284
|
+
}, [currentChat?.messages]);
|
|
285
|
+
|
|
286
|
+
const [historyIndex, setHistoryIndex] = useState(-1);
|
|
287
|
+
const [currentDraft, setCurrentDraft] = useState('');
|
|
288
|
+
|
|
267
289
|
const [aiErrorMessage, setAIErrorMessage] = useState<
|
|
268
290
|
string | null
|
|
269
291
|
>(null);
|
|
270
292
|
|
|
293
|
+
// Message history navigation functions
|
|
294
|
+
const navigateMessageHistoryUp = useCallback(() => {
|
|
295
|
+
if (messageHistory.length === 0) return;
|
|
296
|
+
|
|
297
|
+
// If we're not navigating history, save current draft
|
|
298
|
+
if (historyIndex === -1) {
|
|
299
|
+
setCurrentDraft(aiChatMessage);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
const newIndex =
|
|
303
|
+
historyIndex < messageHistory.length - 1
|
|
304
|
+
? historyIndex + 1
|
|
305
|
+
: historyIndex;
|
|
306
|
+
setHistoryIndex(newIndex);
|
|
307
|
+
setAIChatMessage(
|
|
308
|
+
messageHistory[messageHistory.length - 1 - newIndex],
|
|
309
|
+
);
|
|
310
|
+
}, [messageHistory, historyIndex, aiChatMessage]);
|
|
311
|
+
|
|
312
|
+
const navigateMessageHistoryDown = useCallback(() => {
|
|
313
|
+
if (historyIndex === -1) return;
|
|
314
|
+
|
|
315
|
+
const newIndex = historyIndex - 1;
|
|
316
|
+
if (newIndex === -1) {
|
|
317
|
+
// Return to draft
|
|
318
|
+
setHistoryIndex(-1);
|
|
319
|
+
setAIChatMessage(currentDraft);
|
|
320
|
+
setCurrentDraft('');
|
|
321
|
+
} else {
|
|
322
|
+
setHistoryIndex(newIndex);
|
|
323
|
+
setAIChatMessage(
|
|
324
|
+
messageHistory[
|
|
325
|
+
messageHistory.length - 1 - newIndex
|
|
326
|
+
],
|
|
327
|
+
);
|
|
328
|
+
}
|
|
329
|
+
}, [messageHistory, historyIndex, currentDraft]);
|
|
330
|
+
|
|
331
|
+
const resetMessageHistoryNavigation = useCallback(() => {
|
|
332
|
+
if (historyIndex !== -1) {
|
|
333
|
+
setHistoryIndex(-1);
|
|
334
|
+
setCurrentDraft('');
|
|
335
|
+
}
|
|
336
|
+
}, [historyIndex]);
|
|
337
|
+
|
|
271
338
|
const handleSendMessage = useCallback(
|
|
272
339
|
async (
|
|
273
340
|
messageToSend?: string,
|
|
@@ -293,7 +360,11 @@ export const useVZCodeState = ({
|
|
|
293
360
|
|
|
294
361
|
const currentPrompt = aiChatMessage.trim();
|
|
295
362
|
setAIChatMessage('');
|
|
296
|
-
|
|
363
|
+
|
|
364
|
+
// Reset history navigation when sending a message
|
|
365
|
+
setHistoryIndex(-1);
|
|
366
|
+
setCurrentDraft('');
|
|
367
|
+
|
|
297
368
|
setAIErrorMessage(null); // Clear any previous errors
|
|
298
369
|
|
|
299
370
|
// Call backend endpoint for AI response
|
|
@@ -356,13 +427,12 @@ export const useVZCodeState = ({
|
|
|
356
427
|
}
|
|
357
428
|
|
|
358
429
|
// The backend handles all ShareDB operations for successful responses
|
|
430
|
+
// The loading state is now managed via ShareDB aiStatus
|
|
359
431
|
} catch (error) {
|
|
360
432
|
console.error('Error getting AI response:', error);
|
|
361
433
|
setAIErrorMessage(
|
|
362
434
|
'Failed to send message. Please try again.',
|
|
363
435
|
);
|
|
364
|
-
} finally {
|
|
365
|
-
setIsLoading(false);
|
|
366
436
|
}
|
|
367
437
|
},
|
|
368
438
|
[
|
|
@@ -415,6 +485,9 @@ export const useVZCodeState = ({
|
|
|
415
485
|
setSearchFocusedIndex,
|
|
416
486
|
toggleSearchFocused,
|
|
417
487
|
|
|
488
|
+
isVisualEditorOpen,
|
|
489
|
+
setIsVisualEditorOpen,
|
|
490
|
+
|
|
418
491
|
isAIChatOpen,
|
|
419
492
|
setIsAIChatOpen,
|
|
420
493
|
aiChatFocused,
|
|
@@ -463,6 +536,7 @@ export const useVZCodeState = ({
|
|
|
463
536
|
runCodeRef,
|
|
464
537
|
sidebarRef,
|
|
465
538
|
codeEditorRef,
|
|
539
|
+
iframeRef,
|
|
466
540
|
|
|
467
541
|
connected,
|
|
468
542
|
pending,
|
|
@@ -487,12 +561,16 @@ export const useVZCodeState = ({
|
|
|
487
561
|
aiChatMessage,
|
|
488
562
|
setAIChatMessage,
|
|
489
563
|
isLoading,
|
|
490
|
-
setIsLoading,
|
|
491
564
|
currentChatId,
|
|
492
565
|
aiErrorMessage,
|
|
493
566
|
setAIErrorMessage,
|
|
494
567
|
handleSendMessage,
|
|
495
568
|
|
|
569
|
+
// Message history navigation
|
|
570
|
+
navigateMessageHistoryUp,
|
|
571
|
+
navigateMessageHistoryDown,
|
|
572
|
+
resetMessageHistoryNavigation,
|
|
573
|
+
|
|
496
574
|
// Auto-fork functions for VizHub integration
|
|
497
575
|
autoForkAndRetryAI,
|
|
498
576
|
clearStoredAIPrompt,
|
package/src/client/VZRight.tsx
CHANGED
|
@@ -23,7 +23,6 @@ type ExtendedVizContent = VizContent & {
|
|
|
23
23
|
const enableIframe = true;
|
|
24
24
|
|
|
25
25
|
export const VZRight = () => {
|
|
26
|
-
const iframeRef = useRef<HTMLIFrameElement>(null);
|
|
27
26
|
const runtimeRef = useRef<VizHubRuntime | null>(null);
|
|
28
27
|
const isFirstRunRef = useRef(true);
|
|
29
28
|
const lastRunIdRef = useRef<string | undefined>(
|
|
@@ -31,8 +30,12 @@ export const VZRight = () => {
|
|
|
31
30
|
);
|
|
32
31
|
|
|
33
32
|
// Get access to the current files.
|
|
34
|
-
const {
|
|
35
|
-
|
|
33
|
+
const {
|
|
34
|
+
content,
|
|
35
|
+
handleRuntimeError,
|
|
36
|
+
clearRuntimeError,
|
|
37
|
+
iframeRef,
|
|
38
|
+
} = useContext(VZCodeContext);
|
|
36
39
|
|
|
37
40
|
const files = useMemo(
|
|
38
41
|
() =>
|
|
@@ -20,6 +20,9 @@ interface ChatInputProps {
|
|
|
20
20
|
focused: boolean;
|
|
21
21
|
aiChatMode: 'ask' | 'edit';
|
|
22
22
|
setAIChatMode: (mode: 'ask' | 'edit') => void;
|
|
23
|
+
navigateMessageHistoryUp: () => void;
|
|
24
|
+
navigateMessageHistoryDown: () => void;
|
|
25
|
+
resetMessageHistoryNavigation: () => void;
|
|
23
26
|
}
|
|
24
27
|
|
|
25
28
|
const ChatInputComponent = ({
|
|
@@ -30,6 +33,9 @@ const ChatInputComponent = ({
|
|
|
30
33
|
focused,
|
|
31
34
|
aiChatMode,
|
|
32
35
|
setAIChatMode,
|
|
36
|
+
navigateMessageHistoryUp,
|
|
37
|
+
navigateMessageHistoryDown,
|
|
38
|
+
resetMessageHistoryNavigation,
|
|
33
39
|
}: ChatInputProps) => {
|
|
34
40
|
const inputRef = useRef<HTMLTextAreaElement>(null);
|
|
35
41
|
|
|
@@ -45,9 +51,44 @@ const ChatInputComponent = ({
|
|
|
45
51
|
if (event.key === 'Enter' && !event.shiftKey) {
|
|
46
52
|
event.preventDefault();
|
|
47
53
|
onSendMessage();
|
|
54
|
+
} else if (event.key === 'ArrowUp') {
|
|
55
|
+
// Only navigate history if cursor is at the beginning of the first line
|
|
56
|
+
const textarea =
|
|
57
|
+
event.target as HTMLTextAreaElement;
|
|
58
|
+
const { selectionStart, value } = textarea;
|
|
59
|
+
const lines = value
|
|
60
|
+
.substring(0, selectionStart)
|
|
61
|
+
.split('\n');
|
|
62
|
+
|
|
63
|
+
// Check if we're at the beginning of the first line
|
|
64
|
+
if (lines.length === 1 && selectionStart === 0) {
|
|
65
|
+
event.preventDefault();
|
|
66
|
+
navigateMessageHistoryUp();
|
|
67
|
+
}
|
|
68
|
+
} else if (event.key === 'ArrowDown') {
|
|
69
|
+
// Only navigate history if cursor is at the end of the last line
|
|
70
|
+
const textarea =
|
|
71
|
+
event.target as HTMLTextAreaElement;
|
|
72
|
+
const { selectionStart, value } = textarea;
|
|
73
|
+
const remainingText =
|
|
74
|
+
value.substring(selectionStart);
|
|
75
|
+
const remainingLines = remainingText.split('\n');
|
|
76
|
+
|
|
77
|
+
// Check if we're at the end of the last line
|
|
78
|
+
if (
|
|
79
|
+
remainingLines.length === 1 &&
|
|
80
|
+
remainingLines[0] === ''
|
|
81
|
+
) {
|
|
82
|
+
event.preventDefault();
|
|
83
|
+
navigateMessageHistoryDown();
|
|
84
|
+
}
|
|
48
85
|
}
|
|
49
86
|
},
|
|
50
|
-
[
|
|
87
|
+
[
|
|
88
|
+
onSendMessage,
|
|
89
|
+
navigateMessageHistoryUp,
|
|
90
|
+
navigateMessageHistoryDown,
|
|
91
|
+
],
|
|
51
92
|
);
|
|
52
93
|
|
|
53
94
|
const handleSendClick = useCallback(() => {
|
|
@@ -57,8 +98,10 @@ const ChatInputComponent = ({
|
|
|
57
98
|
const handleChange = useCallback(
|
|
58
99
|
(event: React.ChangeEvent<HTMLTextAreaElement>) => {
|
|
59
100
|
setAIChatMessage(event.target.value);
|
|
101
|
+
// Reset history navigation when user starts typing
|
|
102
|
+
resetMessageHistoryNavigation();
|
|
60
103
|
},
|
|
61
|
-
[setAIChatMessage],
|
|
104
|
+
[setAIChatMessage, resetMessageHistoryNavigation],
|
|
62
105
|
);
|
|
63
106
|
|
|
64
107
|
return (
|
|
@@ -15,11 +15,13 @@ const MessageListComponent = ({
|
|
|
15
15
|
isLoading,
|
|
16
16
|
chatId, // Add chatId prop
|
|
17
17
|
aiScratchpad, // Add aiScratchpad prop
|
|
18
|
+
aiStatus, // Add aiStatus prop
|
|
18
19
|
}: {
|
|
19
20
|
messages: VizChatMessage[];
|
|
20
21
|
isLoading: boolean;
|
|
21
22
|
chatId?: string; // Add chatId to the type
|
|
22
23
|
aiScratchpad?: string; // Add aiScratchpad to the type
|
|
24
|
+
aiStatus?: string; // Add aiStatus to the type
|
|
23
25
|
}) => {
|
|
24
26
|
const messagesEndRef = useRef<HTMLDivElement>(null);
|
|
25
27
|
const messagesContainerRef = useRef<HTMLDivElement>(null);
|
|
@@ -23,6 +23,9 @@ export const AIChat = () => {
|
|
|
23
23
|
setAIChatMessage,
|
|
24
24
|
handleSendMessage,
|
|
25
25
|
setAIErrorMessage,
|
|
26
|
+
navigateMessageHistoryUp,
|
|
27
|
+
navigateMessageHistoryDown,
|
|
28
|
+
resetMessageHistoryNavigation,
|
|
26
29
|
} = useContext(VZCodeContext);
|
|
27
30
|
|
|
28
31
|
// Get current chat data from content
|
|
@@ -254,6 +257,15 @@ export const AIChat = () => {
|
|
|
254
257
|
focused={aiChatFocused}
|
|
255
258
|
aiChatMode={aiChatMode}
|
|
256
259
|
setAIChatMode={setAIChatMode}
|
|
260
|
+
navigateMessageHistoryUp={
|
|
261
|
+
navigateMessageHistoryUp
|
|
262
|
+
}
|
|
263
|
+
navigateMessageHistoryDown={
|
|
264
|
+
navigateMessageHistoryDown
|
|
265
|
+
}
|
|
266
|
+
resetMessageHistoryNavigation={
|
|
267
|
+
resetMessageHistoryNavigation
|
|
268
|
+
}
|
|
257
269
|
/>
|
|
258
270
|
</div>
|
|
259
271
|
</div>
|