diff --git a/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarChat.tsx b/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarChat.tsx
index 9bb7a9e1..31909bba 100644
--- a/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarChat.tsx
+++ b/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarChat.tsx
@@ -8,7 +8,7 @@ import React, { FormEvent, Fragment, useCallback, useEffect, useRef, useState }
import { useConfigState, useService, useThreadsState } from '../util/services.js';
import { generateDiffInstructions } from '../../../prompt/systemPrompts.js';
import { userInstructionsStr } from '../../../prompt/stringifyFiles.js';
-import { CodeSelection, CodeStagingSelection } from '../../../registerThreads.js';
+import { ChatMessage, CodeSelection, CodeStagingSelection } from '../../../registerThreads.js';
import { BlockCode } from '../markdown/BlockCode.js';
import { MarkdownRender } from '../markdown/MarkdownRender.js';
@@ -20,8 +20,6 @@ import { ErrorDisplay } from './ErrorDisplay.js';
import { LLMMessageServiceParams } from '../../../../../../../platform/void/common/llmMessageTypes.js';
import { getCmdKey } from '../../../getCmdKey.js'
-import { VSCodeDropdown } from '@vscode/webview-ui-toolkit/react';
-
// read files from VSCode
const VSReadFile = async (modelService: IModelService, uri: URI): Promise => {
const model = modelService.getModel(uri)
@@ -30,27 +28,6 @@ const VSReadFile = async (modelService: IModelService, uri: URI): Promise {
// 'unixify' path
pathStr = pathStr.replace(/[/\\]+/g, '/') // replace any / or \ or \\ with /
@@ -174,7 +151,7 @@ export const SidebarChat = () => {
const [instructions, setInstructions] = useState('') // the user's instructions
// state of chat
- const [messageStream, setMessageStream] = useState('')
+ const [messageStream, setMessageStream] = useState(null)
const [isLoading, setIsLoading] = useState(false)
const latestRequestIdRef = useRef(null)
@@ -204,8 +181,8 @@ export const SidebarChat = () => {
threadsStateService.addMessageToCurrentThread(systemPromptElt)
const userContent = userInstructionsStr(instructions, selections)
- const newHistoryElt: ChatMessage = { role: 'user', content: userContent, displayContent: instructions, selections }
- threadsStateService.addMessageToCurrentThread(newHistoryElt)
+ const userHistoryElt: ChatMessage = { role: 'user', content: userContent, displayContent: instructions, selections }
+ threadsStateService.addMessageToCurrentThread(userHistoryElt)
const currentThread = threadsStateService.getCurrentThread(threadsStateService.state) // the the instant state right now, don't wait for the React state
@@ -214,24 +191,24 @@ export const SidebarChat = () => {
const object: LLMMessageServiceParams = {
logging: { loggingName: 'Chat' },
- messages: [...(currentThread?.messages ?? []).map(m => ({ role: m.role, content: m.content })),],
+ messages: [...(currentThread?.messages ?? []).map(m => ({ role: m.role, content: m.content || '(null)' })),],
onText: ({ newText, fullText }) => setMessageStream(fullText),
onFinalMessage: ({ fullText: content }) => {
console.log('chat: running final message')
// add assistant's message to chat history, and clear selection
- const newHistoryElt: ChatMessage = { role: 'assistant', content, displayContent: content }
- threadsStateService.addMessageToCurrentThread(newHistoryElt)
- setMessageStream('')
+ const assistantHistoryElt: ChatMessage = { role: 'assistant', content, displayContent: content || null }
+ threadsStateService.addMessageToCurrentThread(assistantHistoryElt)
+ setMessageStream(null)
setIsLoading(false)
},
onError: ({ error }) => {
console.log('chat: running error', error)
// add assistant's message to chat history, and clear selection
- let content = messageStream; // just use the current content
- const newHistoryElt: ChatMessage = { role: 'assistant', content, displayContent: content, }
- threadsStateService.addMessageToCurrentThread(newHistoryElt)
+ let content = messageStream ?? ''; // just use the current content
+ const assistantHistoryElt: ChatMessage = { role: 'assistant', content, displayContent: content || null, }
+ threadsStateService.addMessageToCurrentThread(assistantHistoryElt)
setMessageStream('')
setIsLoading(false)
@@ -259,9 +236,9 @@ export const SidebarChat = () => {
sendLLMMessageService.abort(latestRequestIdRef.current)
// if messageStream was not empty, add it to the history
- const llmContent = messageStream || '(empty)'
- const newHistoryElt: ChatMessage = { role: 'assistant', content: llmContent, displayContent: messageStream, }
- threadsStateService.addMessageToCurrentThread(newHistoryElt)
+ const llmContent = messageStream ?? ''
+ const assistantHistoryElt: ChatMessage = { role: 'assistant', content: llmContent, displayContent: messageStream || null, }
+ threadsStateService.addMessageToCurrentThread(assistantHistoryElt)
setMessageStream('')
setIsLoading(false)
@@ -280,7 +257,7 @@ export const SidebarChat = () => {
)}
{/* message stream */}
-
+
{/* chatbar */}
@@ -331,7 +308,7 @@ export const SidebarChat = () => {
{
:
// submit button (up arrow)
diff --git a/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarThreadSelector.tsx b/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarThreadSelector.tsx
index 9953259d..b646e1a0 100644
--- a/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarThreadSelector.tsx
+++ b/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarThreadSelector.tsx
@@ -56,21 +56,28 @@ export const SidebarThreadSelector = () => {
let btnStringArr: string[] = []
- let msg1 = truncate(allThreads[threadId].messages[0]?.displayContent ?? '(empty)')
- btnStringArr.push(msg1)
+ const firstUserMsg = allThreads[threadId].messages.find(msg => msg.role === 'user')?.displayContent ?? ''
+ let msg1 = truncate(firstUserMsg)
+ if (msg1)
+ btnStringArr.push(msg1)
+ else
+ btnStringArr.push('""')
- let msg2 = truncate(allThreads[threadId].messages[1]?.displayContent ?? '')
+ const firstAssistantMsg = allThreads[threadId].messages.find(msg => msg.role === 'assistant')?.displayContent ?? ''
+ let msg2 = truncate(firstAssistantMsg)
if (msg2)
btnStringArr.push(msg2)
- btnStringArr.push(allThreads[threadId].messages.length + '')
+ const numMessages = allThreads[threadId].messages.filter(msg => msg.role !== 'system').length
+ if (firstUserMsg && firstAssistantMsg)
+ btnStringArr.push((numMessages - 2) + '')
const btnString = btnStringArr.join(' / ')
return (
threadsStateService.switchToThread(pastThread.id)}
title={new Date(pastThread.createdAt).toLocaleString()}
>
diff --git a/src/vs/workbench/contrib/void/browser/registerThreads.ts b/src/vs/workbench/contrib/void/browser/registerThreads.ts
index 91b3d5c4..2d1f15d3 100644
--- a/src/vs/workbench/contrib/void/browser/registerThreads.ts
+++ b/src/vs/workbench/contrib/void/browser/registerThreads.ts
@@ -23,17 +23,19 @@ export type CodeStagingSelection = {
fileURI: URI;
}
+
+// WARNING: changing this format is a big deal!!!!!! need to migrate old format to new format on users' computers so people don't get errors.
export type ChatMessage =
| {
role: 'user';
- content: string; // content sent to the llm
- displayContent: string; // content displayed to user
+ content: string | null; // content sent to the llm - yes, allowed to be '', will be replaced with (empty)
+ displayContent: string | null; // content displayed to user - yes, allowed to be '', will be ignored
selections: CodeSelection[] | null; // the user's selection
}
| {
role: 'assistant';
- content: string; // content received from LLM
- displayContent: string | undefined; // content displayed to user (this is the same as content for now)
+ content: string | null; // content received from LLM - yes, allowed to be '', will be replaced with (empty)
+ displayContent: string | null; // content displayed to user (this is the same as content for now) - yes, allowed to be '', will be ignored
}
| {
role: 'system';
@@ -133,8 +135,8 @@ class ThreadHistoryService extends Disposable implements IThreadHistoryService {
}
switchToThread(threadId: string) {
- // console.log('threadId', threadId)
- // console.log('messages', this.state.allThreads[threadId].messages)
+ console.log('threadId', threadId)
+ console.log('messages', this.state.allThreads[threadId].messages)
this._setState({ _currentThreadId: threadId }, true)
}
@@ -197,28 +199,3 @@ class ThreadHistoryService extends Disposable implements IThreadHistoryService {
registerSingleton(IThreadHistoryService, ThreadHistoryService, InstantiationType.Eager);
-
-
-// [
-// {
-// "role": "system",
-// "content": "\nYou are a coding assistant. You are given a list of relevant files `files`, a selection that the user is making `selection`, and instructions to follow `instructions`.\n\nPlease edit the selected file following the user's instructions (or, if appropriate, answer their question instead).\n\nAll changes made to files must be outputted in unified diff format.\nUnified diff format instructions:\n1. Each diff must begin with ```@@ ... @@```.\n2. Each line must start with a `+` or `-` or ` ` symbol.\n3. Make diffs more than a few lines.\n4. Make high-level diffs rather than many one-line diffs.\n\nHere's an example of unified diff format:\n\n```\n@@ ... @@\n-def factorial(n):\n- if n == 0:\n- return 1\n- else:\n- return n * factorial(n-1)\n+def factorial(number):\n+ if number == 0:\n+ return 1\n+ else:\n+ return number * factorial(number-1)\n```\n\nPlease create high-level diffs where you group edits together if they are near each other, like in the above example. Another way to represent the above example is to make many small line edits. However, this is less preferred, because the edits are not high-level. The edits are close together and should be grouped:\n\n```\n@@ ... @@ # This is less preferred because edits are close together and should be grouped:\n-def factorial(n):\n+def factorial(number):\n- if n == 0:\n+ if number == 0:\n return 1\n else:\n- return n * factorial(n-1)\n+ return number * factorial(number-1)\n```\n\n# Example 1:\n\nFILES\nselected file `test.ts`:\n```\nx = 1\n\n{{selection}}\n\nz = 3\n```\n\nSELECTION\n```const y = 2```\n\nINSTRUCTIONS\n```y = 3```\n\nEXPECTED RESULT\n\nWe should change the selection from ```y = 2``` to ```y = 3```.\n```\n@@ ... @@\n-x = 1\n-\n-y = 2\n+x = 1\n+\n+y = 3\n```\n\n# Example 2:\n\nFILES\nselected file `Sidebar.tsx`:\n```\nimport React from 'react';\nimport styles from './Sidebar.module.css';\n\ninterface SidebarProps {\n items: { label: string; href: string }[];\n onItemSelect?: (label: string) => void;\n onExtraButtonClick?: () => void;\n}\n\nconst Sidebar: React.FC = ({ items, onItemSelect, onExtraButtonClick }) => {\n return (\n \n
\n {items.map((item, index) => (\n \n {{selection}}\n className={styles.sidebarButton}\n onClick={() => onItemSelect?.(item.label)}\n >\n {item.label}\n \n \n ))}\n \n
\n Extra Action\n \n
\n );\n};\n\nexport default Sidebar;\n```\n\nSELECTION\n``` \n-\n- {items.map((item, index) => (\n-\t\n-\t onItemSelect?.(item.label)}\n-\t >\n-\t\t{item.label}\n-\t \n-\t \n- ))}\n- \n-\n- Extra Action\n- \n- \n+
\n+
\n+
\n+ Extra Action\n+
\n+
\n```\n"
-// },
-// {
-// "role": "user",
-// "content": "test",
-// "displayContent": "test",
-// "selections": null
-// },
-// {
-// "role": "assistant",
-// "content": {
-// "requestId": "49d4c9e6-5e53-4768-a77e-5c297223fa9c",
-// "fullText": "I apologize, but I don't have enough context to provide a meaningful response based on just the word \"test\". If you have a specific question or topic you'd like me to assist with, please provide more details or context so I can better understand how to help you. I'm here to engage in conversation and provide information to the best of my abilities."
-// },
-// "displayContent": {
-// "requestId": "49d4c9e6-5e53-4768-a77e-5c297223fa9c",
-// "fullText": "I apologize, but I don't have enough context to provide a meaningful response based on just the word \"test\". If you have a specific question or topic you'd like me to assist with, please provide more details or context so I can better understand how to help you. I'm here to engage in conversation and provide information to the best of my abilities."
-// }
-// }
-// ]