fix thread history persistence

This commit is contained in:
Andrew 2024-10-14 18:07:16 -07:00
parent 8c9eeaa133
commit fb69afd5c4
5 changed files with 28 additions and 23 deletions

View file

@ -20,6 +20,7 @@ export class SidebarWebviewProvider implements vscode.WebviewViewProvider {
private readonly _extensionUri: vscode.Uri
private _webviewView?: vscode.WebviewView; // only used inside onDidChangeConfiguration
private _webviewDeps: string[] = [];
constructor(context: vscode.ExtensionContext) {
// const extensionPath = context.extensionPath // the directory where the extension is installed, might be useful later... was included in webviewProvider code
@ -30,8 +31,10 @@ export class SidebarWebviewProvider implements vscode.WebviewViewProvider {
if (!temp_res) throw new Error("sidebar provider: resolver was undefined")
this._res = temp_res
// if it affects one of the config items webview depends on, update the webview
// TODO should be able to move this entirely to React - make updateWebviewHTML mount once, and then send updates via postMessage from then on
vscode.workspace.onDidChangeConfiguration(event => {
if (event.affectsConfiguration('void.ollama.endpoint')) {
if (this._webviewDeps.map(dep => event.affectsConfiguration(dep)).some(v => !!v)) {
if (this._webviewView) {
this.updateWebviewHTML(this._webviewView.webview);
}
@ -39,12 +42,18 @@ export class SidebarWebviewProvider implements vscode.WebviewViewProvider {
});
}
// this is updated
private updateWebviewHTML(webview: vscode.Webview) {
const allowed_urls = ['https://api.anthropic.com', 'https://api.openai.com', 'https://api.greptile.com'];
this._webviewDeps = []
const ollamaEndpoint: string | undefined = vscode.workspace.getConfiguration('void.ollama').get('endpoint');
this._webviewDeps.push('void.ollama.endpoint');
if (ollamaEndpoint)
allowed_urls.push(ollamaEndpoint);
const openAICompatibleEndpoint: string | undefined = vscode.workspace.getConfiguration('void.openAICompatible').get('endpoint');
this._webviewDeps.push('void.openAICompatible.endpoint');
if (openAICompatibleEndpoint)
allowed_urls.push(openAICompatibleEndpoint);

View file

@ -143,13 +143,8 @@ export function activate(context: vscode.ExtensionContext) {
await approvalCodeLensProvider.addNewApprovals(editor, suggestedEdits)
}
else if (m.type === 'getApiConfig') {
context.workspaceState.update('allThreads', {})
const apiConfig = getApiConfig()
console.log('Api config:', apiConfig)
webview.postMessage({ type: 'apiConfig', apiConfig } satisfies WebviewMessage)
}
else if (m.type === 'getAllThreads') {
const threads: ChatThreads = context.workspaceState.get('allThreads') ?? {}

View file

@ -9,7 +9,7 @@ import BlockCode from "./markdown/BlockCode";
import * as vscode from 'vscode'
import { SelectedFiles } from "./components/SelectedFiles";
import { useChat } from "./chatContext";
import { useThreads } from "./threadsContext";
const filesStr = (fullFiles: File[]) => {
@ -69,7 +69,7 @@ const ChatBubble = ({ chatMessage }: { chatMessage: ChatMessage }) => {
}
const ThreadSelector = ({ onClose }: { onClose: () => void }) => {
const { allThreads, currentThread, switchToThread } = useChat()
const { allThreads, currentThread, switchToThread } = useThreads()
return (
<div className="flex flex-col space-y-1">
<div className="text-right">
@ -109,7 +109,7 @@ const ThreadSelector = ({ onClose }: { onClose: () => void }) => {
const Sidebar = () => {
const { allThreads, currentThread, addMessageToHistory, startNewThread, } = useChat()
const { allThreads, currentThread, addMessageToHistory, startNewThread, } = useThreads()
// state of current message
const [selection, setSelection] = useState<Selection | null>(null) // the code the user is selecting

View file

@ -1,7 +1,7 @@
import * as React from "react"
import * as ReactDOM from "react-dom/client"
import Sidebar from "./Sidebar"
import { ChatProvider } from "./chatContext"
import { ThreadsProvider } from "./threadsContext"
// mount the sidebar on the id="root" element
if (typeof document === "undefined") {
@ -9,12 +9,12 @@ if (typeof document === "undefined") {
}
const rootElement = document.getElementById("root")!
console.log("root Element", rootElement)
console.log("Void root Element:", rootElement)
const extension = (
<ChatProvider>
<ThreadsProvider>
<Sidebar />
</ChatProvider>
</ThreadsProvider>
)
const root = ReactDOM.createRoot(rootElement)
root.render(extension)

View file

@ -3,7 +3,7 @@ import { ChatMessage, ChatThreads } from "../shared_types"
import { awaitVSCodeResponse, getVSCodeAPI } from "./getVscodeApi"
type ChatContextValue = {
type ThreadsContextValue = {
readonly allThreads: ChatThreads | null,
readonly currentThread: ChatThreads[string] | null;
addMessageToHistory: (message: ChatMessage) => void;
@ -11,7 +11,7 @@ type ChatContextValue = {
startNewThread: () => void;
}
const ChatContext = createContext<ChatContextValue>({} as ChatContextValue)
const ThreadsContext = createContext<ThreadsContextValue>(undefined as unknown as ThreadsContextValue)
const createNewThread = () => ({
id: new Date().getTime().toString(),
@ -33,7 +33,7 @@ const useInstantState = <T,>(initVal: T) => {
}
function ChatProvider({ children }: { children: ReactNode }) {
export function ThreadsProvider({ children }: { children: ReactNode }) {
const [allThreads, setAllThreads] = useInstantState<ChatThreads>({})
const [currentThreadId, setCurrentThreadId] = useInstantState<string | null>(null)
@ -41,12 +41,14 @@ function ChatProvider({ children }: { children: ReactNode }) {
useEffect(() => {
getVSCodeAPI().postMessage({ type: "getAllThreads" })
awaitVSCodeResponse('allThreads')
.then(response => { setAllThreads(response.threads) })
.then(response => {
setAllThreads(response.threads)
})
}, [setAllThreads])
return (
<ChatContext.Provider
<ThreadsContext.Provider
value={{
allThreads: allThreads.current,
currentThread: currentThreadId.current === null || allThreads.current === null ? null : allThreads.current[currentThreadId.current],
@ -84,16 +86,15 @@ function ChatProvider({ children }: { children: ReactNode }) {
}}
>
{children}
</ChatContext.Provider>
</ThreadsContext.Provider>
)
}
function useChat(): ChatContextValue {
const context = useContext<ChatContextValue>(ChatContext)
export function useThreads(): ThreadsContextValue {
const context = useContext<ThreadsContextValue>(ThreadsContext)
if (context === undefined) {
throw new Error("useChat must be used within a ChatProvider")
throw new Error("useThreads must be used within a ThreadsProvider")
}
return context
}
export { ChatProvider, useChat }