mirror of
https://github.com/voideditor/void
synced 2026-05-24 09:58:23 +00:00
misc
This commit is contained in:
parent
661eba3ae9
commit
aa835d468b
10 changed files with 139 additions and 281 deletions
|
|
@ -3,185 +3,106 @@
|
|||
* Licensed under the Apache License, Version 2.0. See LICENSE.txt for more information.
|
||||
*--------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Emitter, Event } from '../../../../base/common/event.js';
|
||||
import { Disposable } from '../../../../base/common/lifecycle.js';
|
||||
// import { URI } from '../../../../base/common/uri.js';
|
||||
import { InstantiationType, registerSingleton } from '../../../../platform/instantiation/common/extensions.js';
|
||||
import { createDecorator } from '../../../../platform/instantiation/common/instantiation.js';
|
||||
// import { IToolService, ToolService } from '../common/toolsService.js';
|
||||
// 1. search(ai)
|
||||
// - tool use to find all possible changes
|
||||
// - if search only: is this file related to the search?
|
||||
// - if search + replace: should I modify this file?
|
||||
// 2. replace(ai)
|
||||
// - what changes to make?
|
||||
// 3. postprocess errors
|
||||
// -fastapply changes simultaneously
|
||||
// -iterate on syntax errors (all files can be changed from a syntax error, not just the one with the error)
|
||||
|
||||
|
||||
// private async _searchUsingAI({ searchClause }: { searchClause: string }) {
|
||||
|
||||
export type ChatMessageLocation = {
|
||||
threadId: string;
|
||||
messageIdx: number;
|
||||
}
|
||||
// // const relevantURIs: URI[] = []
|
||||
// // const gatherPrompt = `\
|
||||
// // asdasdas
|
||||
// // `
|
||||
// // const filterPrompt = `\
|
||||
// // Is this file relevant?
|
||||
// // `
|
||||
|
||||
|
||||
export type SearchAndReplaceBlock = {
|
||||
search: string;
|
||||
replace: string;
|
||||
}
|
||||
// // // optimizations (DO THESE LATER!!!!!!)
|
||||
// // // if tool includes a uri in uriSet, skip it obviously
|
||||
// // let uriSet = new Set<URI>()
|
||||
// // // gather
|
||||
// // let messages = []
|
||||
// // while (true) {
|
||||
// // const result = await new Promise((res, rej) => {
|
||||
// // sendLLMMessage({
|
||||
// // messages,
|
||||
// // tools: ['search'],
|
||||
// // onFinalMessage: ({ result: r, }) => {
|
||||
// // res(r)
|
||||
// // },
|
||||
// // onError: (error) => {
|
||||
// // rej(error)
|
||||
// // }
|
||||
// // })
|
||||
// // })
|
||||
|
||||
// service that manages state
|
||||
export type ApplyState = {
|
||||
[applyBoxId: string]: {
|
||||
searchAndReplaceBlocks: SearchAndReplaceBlock;
|
||||
}
|
||||
}
|
||||
// // messages.push({ role: 'tool', content: turnToString(result) })
|
||||
|
||||
// the purpose of this service is to generate search and replace blocks for a given codeblock `codeblockId` and on a file `fileName` and version `fileVersion`
|
||||
// // sendLLMMessage({
|
||||
// // messages: { 'Output ': result },
|
||||
// // onFinalMessage: (r) => {
|
||||
// // // output is file1\nfile2\nfile3\n...
|
||||
// // }
|
||||
// // })
|
||||
|
||||
export interface IFastApplyService {
|
||||
readonly _serviceBrand: undefined;
|
||||
// // uriSet.add(...)
|
||||
// // }
|
||||
|
||||
// readonly state: ApplyState; // readonly to the user
|
||||
// setState(newState: Partial<ApplyState>): void;
|
||||
// onDidChangeState: Event<void>;
|
||||
}
|
||||
// // // writes
|
||||
// // if (!replaceClause) return
|
||||
|
||||
export const IVoidFastApplyService = createDecorator<IFastApplyService>('voidFastApplyService');
|
||||
class VoidFastApplyService extends Disposable implements IFastApplyService {
|
||||
_serviceBrand: undefined;
|
||||
|
||||
// static readonly ID = 'voidFastApplyService';
|
||||
|
||||
private readonly _onDidChangeState = new Emitter<void>();
|
||||
readonly onDidChangeState: Event<void> = this._onDidChangeState.event;
|
||||
|
||||
|
||||
// state
|
||||
// state: ApplyState
|
||||
|
||||
constructor(
|
||||
// @IToolService private readonly toolService: ToolService
|
||||
) {
|
||||
super()
|
||||
|
||||
// initial state
|
||||
// this.state = { currentUri: undefined }
|
||||
}
|
||||
|
||||
setState(newState: Partial<ApplyState>) {
|
||||
|
||||
// this.state = { ...this.state, ...newState }
|
||||
this._onDidChangeState.fire()
|
||||
}
|
||||
|
||||
aiSearch(searchStr: string) {
|
||||
|
||||
}
|
||||
|
||||
aiReplace(searchStr: string, replaceStr: string) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
// 1. search(ai)
|
||||
// - tool use to find all possible changes
|
||||
// - if search only: is this file related to the search?
|
||||
// - if search + replace: should I modify this file?
|
||||
// 2. replace(ai)
|
||||
// - what changes to make?
|
||||
// 3. postprocess errors
|
||||
// -fastapply changes simultaneously
|
||||
// -iterate on syntax errors (all files can be changed from a syntax error, not just the one with the error)
|
||||
|
||||
|
||||
// private async _searchUsingAI({ searchClause }: { searchClause: string }) {
|
||||
|
||||
// // const relevantURIs: URI[] = []
|
||||
// // const gatherPrompt = `\
|
||||
// // asdasdas
|
||||
// // `
|
||||
// // const filterPrompt = `\
|
||||
// // Is this file relevant?
|
||||
// // `
|
||||
|
||||
|
||||
// // // optimizations (DO THESE LATER!!!!!!)
|
||||
// // // if tool includes a uri in uriSet, skip it obviously
|
||||
// // let uriSet = new Set<URI>()
|
||||
// // // gather
|
||||
// // let messages = []
|
||||
// // while (true) {
|
||||
// // const result = await new Promise((res, rej) => {
|
||||
// // sendLLMMessage({
|
||||
// // messages,
|
||||
// // tools: ['search'],
|
||||
// // onFinalMessage: ({ result: r, }) => {
|
||||
// // res(r)
|
||||
// // },
|
||||
// // onError: (error) => {
|
||||
// // rej(error)
|
||||
// // }
|
||||
// // })
|
||||
// // })
|
||||
|
||||
// // messages.push({ role: 'tool', content: turnToString(result) })
|
||||
|
||||
// // sendLLMMessage({
|
||||
// // messages: { 'Output ': result },
|
||||
// // onFinalMessage: (r) => {
|
||||
// // // output is file1\nfile2\nfile3\n...
|
||||
// // }
|
||||
// // })
|
||||
|
||||
// // uriSet.add(...)
|
||||
// // }
|
||||
|
||||
// // // writes
|
||||
// // if (!replaceClause) return
|
||||
|
||||
// // for (const uri of uriSet) {
|
||||
// // // in future, batch these
|
||||
// // applyWorkflow({ uri, applyStr: replaceClause })
|
||||
// // }
|
||||
// // for (const uri of uriSet) {
|
||||
// // // in future, batch these
|
||||
// // applyWorkflow({ uri, applyStr: replaceClause })
|
||||
// // }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// // while (true) {
|
||||
// // const result = new Promise((res, rej) => {
|
||||
// // sendLLMMessage({
|
||||
// // messages,
|
||||
// // tools: ['search'],
|
||||
// // onResult: (r) => {
|
||||
// // res(r)
|
||||
// // }
|
||||
// // })
|
||||
// // })
|
||||
// // while (true) {
|
||||
// // const result = new Promise((res, rej) => {
|
||||
// // sendLLMMessage({
|
||||
// // messages,
|
||||
// // tools: ['search'],
|
||||
// // onResult: (r) => {
|
||||
// // res(r)
|
||||
// // }
|
||||
// // })
|
||||
// // })
|
||||
|
||||
// // messages.push(result)
|
||||
// // messages.push(result)
|
||||
|
||||
// // }
|
||||
// // }
|
||||
|
||||
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
// private async _replaceUsingAI({ searchClause, replaceClause, relevantURIs }: { searchClause: string, replaceClause: string, relevantURIs: URI[] }) {
|
||||
// private async _replaceUsingAI({ searchClause, replaceClause, relevantURIs }: { searchClause: string, replaceClause: string, relevantURIs: URI[] }) {
|
||||
|
||||
// for (const uri of relevantURIs) {
|
||||
// for (const uri of relevantURIs) {
|
||||
|
||||
// uri
|
||||
// uri
|
||||
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
|
||||
// // should I change this file?
|
||||
// // if so what changes to make?
|
||||
// // should I change this file?
|
||||
// // if so what changes to make?
|
||||
|
||||
|
||||
|
||||
// // fast apply the changes
|
||||
// }
|
||||
// // fast apply the changes
|
||||
// }
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
registerSingleton(IVoidFastApplyService, VoidFastApplyService, InstantiationType.Eager);
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
import { URI } from '../../../../../base/common/uri.js';
|
||||
import { filenameToVscodeLanguage } from '../helpers/detectLanguage.js';
|
||||
import { CodeSelection, StagingSelectionItem, FileSelection } from '../chatThreadService.js';
|
||||
import { CodeSelection, StagingSelectionItem, FileSelection } from '../../common/chatThreadService.js';
|
||||
import { IModelService } from '../../../../../editor/common/services/model.js';
|
||||
import { os } from '../helpers/systemInfo.js';
|
||||
import { IVoidFileService } from '../../common/voidFileService.js';
|
||||
|
|
|
|||
|
|
@ -6,10 +6,14 @@
|
|||
import React, { JSX } from 'react'
|
||||
import { marked, MarkedToken, Token } from 'marked'
|
||||
import { BlockCode } from './BlockCode.js'
|
||||
import { ChatMessageLocation, } from '../../../aiRegexService.js'
|
||||
import { nameToVscodeLanguage } from '../../../helpers/detectLanguage.js'
|
||||
import { ApplyBlockHoverButtons } from './ApplyBlockHoverButtons.js'
|
||||
|
||||
export type ChatMessageLocation = {
|
||||
threadId: string;
|
||||
messageIdx: number;
|
||||
}
|
||||
|
||||
|
||||
type ApplyBoxLocation = ChatMessageLocation & { tokenIdx: string }
|
||||
|
||||
|
|
|
|||
|
|
@ -7,10 +7,10 @@ import React, { ButtonHTMLAttributes, FormEvent, FormHTMLAttributes, Fragment, K
|
|||
|
||||
|
||||
import { useAccessor, useSidebarState, useChatThreadsState, useChatThreadsStreamState, useUriState, useSettingsState } from '../util/services.js';
|
||||
import { ChatMessage, StagingSelectionItem, ToolMessage } from '../../../chatThreadService.js';
|
||||
import { ChatMessage, StagingSelectionItem, ToolMessage } from '../../../../common/chatThreadService.js';
|
||||
|
||||
import { BlockCode } from '../markdown/BlockCode.js';
|
||||
import { ChatMarkdownRender } from '../markdown/ChatMarkdownRender.js';
|
||||
import { ChatMarkdownRender, ChatMessageLocation } from '../markdown/ChatMarkdownRender.js';
|
||||
import { URI } from '../../../../../../../base/common/uri.js';
|
||||
import { IDisposable } from '../../../../../../../base/common/lifecycle.js';
|
||||
import { ErrorDisplay } from './ErrorDisplay.js';
|
||||
|
|
@ -24,7 +24,7 @@ import { VOID_OPEN_SETTINGS_ACTION_ID } from '../../../voidSettingsPane.js';
|
|||
import { ChevronRight, Pencil, X } from 'lucide-react';
|
||||
import { FeatureName, isFeatureNameDisabled } from '../../../../../../../workbench/contrib/void/common/voidSettingsTypes.js';
|
||||
import { WarningBox } from '../void-settings-tsx/WarningBox.js';
|
||||
import { ChatMessageLocation } from '../../../aiRegexService.js';
|
||||
|
||||
import { ToolCallReturnType, ToolName } from '../../../../common/toolsService.js';
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
*--------------------------------------------------------------------------------------*/
|
||||
|
||||
import React, { useState, useEffect, useCallback } from 'react'
|
||||
import { ThreadStreamState, ThreadsState } from '../../../chatThreadService.js'
|
||||
import { ThreadStreamState,IChatThreadService, ThreadsState } from '../../../../common/chatThreadService.js'
|
||||
import { RefreshableProviderName, SettingsOfProvider } from '../../../../../../../workbench/contrib/void/common/voidSettingsTypes.js'
|
||||
import { IDisposable } from '../../../../../../../base/common/lifecycle.js'
|
||||
import { VoidSidebarState } from '../../../sidebarStateService.js'
|
||||
|
|
@ -29,7 +29,6 @@ import { IEditCodeService, URIStreamState } from '../../../editCodeService.js';
|
|||
import { IVoidUriStateService } from '../../../voidUriStateService.js';
|
||||
import { IQuickEditStateService } from '../../../quickEditStateService.js';
|
||||
import { ISidebarStateService } from '../../../sidebarStateService.js';
|
||||
import { IChatThreadService } from '../../../chatThreadService.js';
|
||||
import { IInstantiationService } from '../../../../../../../platform/instantiation/common/instantiation.js'
|
||||
import { ICodeEditorService } from '../../../../../../../editor/browser/services/codeEditorService.js'
|
||||
import { ICommandService } from '../../../../../../../platform/commands/common/commands.js'
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import { ServicesAccessor } from '../../../../editor/browser/editorExtensions.js
|
|||
|
||||
import { KeybindingWeight } from '../../../../platform/keybinding/common/keybindingsRegistry.js';
|
||||
import { ContextKeyExpr } from '../../../../platform/contextkey/common/contextkey.js';
|
||||
import { StagingSelectionItem, IChatThreadService } from './chatThreadService.js';
|
||||
import { StagingSelectionItem, IChatThreadService } from '../common/chatThreadService.js';
|
||||
|
||||
import { ICodeEditorService } from '../../../../editor/browser/services/codeEditorService.js';
|
||||
import { IRange } from '../../../../editor/common/core/range.js';
|
||||
|
|
|
|||
|
|
@ -15,8 +15,6 @@ import './sidebarStateService.js'
|
|||
// register quick edit (Ctrl+K)
|
||||
import './quickEditActions.js'
|
||||
|
||||
// register Thread History
|
||||
import './chatThreadService.js'
|
||||
|
||||
// register Autocomplete
|
||||
import './autocompleteService.js'
|
||||
|
|
@ -56,3 +54,7 @@ import '../common/voidUpdateService.js'
|
|||
|
||||
// tools
|
||||
import '../common/toolsService.js'
|
||||
|
||||
// register Thread History
|
||||
import '../common/chatThreadService.js'
|
||||
|
||||
|
|
|
|||
|
|
@ -11,12 +11,12 @@ import { IStorageService, StorageScope, StorageTarget } from '../../../../platfo
|
|||
import { URI } from '../../../../base/common/uri.js';
|
||||
import { Emitter, Event } from '../../../../base/common/event.js';
|
||||
import { IRange } from '../../../../editor/common/core/range.js';
|
||||
import { ILLMMessageService } from '../common/llmMessageService.js';
|
||||
import { chat_userMessageContent, chat_systemMessage, chat_userMessageContentWithAllFilesToo as chat_userMessageContentWithAllFiles, chat_selectionsString } from './prompt/prompts.js';
|
||||
import { InternalToolInfo, IToolsService, ToolCallReturnType, ToolFns, ToolName, voidTools } from '../common/toolsService.js';
|
||||
import { toLLMChatMessage } from '../common/llmMessageTypes.js';
|
||||
import { ILLMMessageService } from './llmMessageService.js';
|
||||
import { chat_userMessageContent, chat_systemMessage, chat_userMessageContentWithAllFilesToo as chat_userMessageContentWithAllFiles, chat_selectionsString } from '../browser/prompt/prompts.js';
|
||||
import { InternalToolInfo, IToolsService, ToolCallReturnType, ToolFns, ToolName, voidTools } from './toolsService.js';
|
||||
import { toLLMChatMessage } from './llmMessageTypes.js';
|
||||
import { IWorkspaceContextService } from '../../../../platform/workspace/common/workspace.js';
|
||||
import { IVoidFileService } from '../common/voidFileService.js';
|
||||
import { IVoidFileService } from './voidFileService.js';
|
||||
import { generateUuid } from '../../../../base/common/uuid.js';
|
||||
|
||||
|
||||
|
|
@ -101,7 +101,6 @@ export type ChatThreads = {
|
|||
|
||||
type ThreadType = ChatThreads[string]
|
||||
|
||||
const defaultThreadState: ThreadType['state'] = { stagingSelections: [], focusedMessageIdx: undefined, isCheckedOfSelectionId: {} }
|
||||
|
||||
export type ThreadsState = {
|
||||
allThreads: ChatThreads;
|
||||
|
|
@ -134,10 +133,7 @@ const newThreadObject = () => {
|
|||
} satisfies ChatThreads[string]
|
||||
}
|
||||
|
||||
const THREAD_VERSION_KEY = 'void.chatThreadVersion'
|
||||
const LATEST_THREAD_VERSION = 'v2'
|
||||
|
||||
const THREAD_STORAGE_KEY = 'void.chatThreadStorage'
|
||||
export const THREAD_STORAGE_KEY = 'void.chatThreadStorage'
|
||||
|
||||
|
||||
type ChatMode = 'agent' | 'chat'
|
||||
|
|
@ -200,35 +196,11 @@ class ChatThreadService extends Disposable implements IChatThreadService {
|
|||
@IWorkspaceContextService private readonly _workspaceContextService: IWorkspaceContextService,
|
||||
) {
|
||||
super()
|
||||
this.state = { allThreads: {}, currentThreadId: null as unknown as string } // default state
|
||||
|
||||
const readThreads = this._readAllThreads() || {}
|
||||
|
||||
setInterval(() => {
|
||||
const thread = this.getCurrentThread()
|
||||
if (!thread) return
|
||||
|
||||
// print out all staging selections for all messages
|
||||
for (const message of thread.messages) {
|
||||
if (message.role === 'user' && message.state.stagingSelections.length > 0) {
|
||||
console.log('Message staging selections:', message.state.stagingSelections)
|
||||
}
|
||||
}
|
||||
// also print thread-level staging selections
|
||||
if (thread.state.stagingSelections.length > 0) {
|
||||
console.log('Thread staging selections:', thread.state.stagingSelections)
|
||||
}
|
||||
}, 1000)
|
||||
|
||||
const oldVersionNum = this._storageService.get(THREAD_VERSION_KEY, StorageScope.APPLICATION)
|
||||
|
||||
|
||||
const readThreads = this._readAllThreads()
|
||||
const updatedThreads = this._updatedThreadsToVersion(readThreads, oldVersionNum)
|
||||
|
||||
if (updatedThreads !== null) {
|
||||
this._storeAllThreads(updatedThreads)
|
||||
}
|
||||
|
||||
const allThreads = updatedThreads ?? readThreads
|
||||
const allThreads = readThreads
|
||||
this.state = {
|
||||
allThreads: allThreads,
|
||||
currentThreadId: null as unknown as string, // gets set in startNewThread()
|
||||
|
|
@ -236,9 +208,6 @@ class ChatThreadService extends Disposable implements IChatThreadService {
|
|||
|
||||
// always be in a thread
|
||||
this.openNewThread()
|
||||
|
||||
this._storageService.store(THREAD_VERSION_KEY, LATEST_THREAD_VERSION, StorageScope.APPLICATION, StorageTarget.USER)
|
||||
|
||||
}
|
||||
|
||||
// !!! this is important for properly restoring URIs from storage
|
||||
|
|
@ -251,10 +220,10 @@ class ChatThreadService extends Disposable implements IChatThreadService {
|
|||
});
|
||||
}
|
||||
|
||||
private _readAllThreads(): ChatThreads {
|
||||
private _readAllThreads(): ChatThreads | null {
|
||||
const threadsStr = this._storageService.get(THREAD_STORAGE_KEY, StorageScope.APPLICATION);
|
||||
if (!threadsStr) {
|
||||
return {};
|
||||
return null
|
||||
}
|
||||
return this._convertThreadDataFromStorage(threadsStr);
|
||||
}
|
||||
|
|
@ -270,48 +239,6 @@ class ChatThreadService extends Disposable implements IChatThreadService {
|
|||
}
|
||||
|
||||
|
||||
// returns if should update
|
||||
private _updatedThreadsToVersion(oldThreadsObject: any, oldVersion: string | undefined): ChatThreads | null {
|
||||
|
||||
if (!oldVersion) {
|
||||
|
||||
// unknown, just reset chat?
|
||||
return null
|
||||
}
|
||||
|
||||
/** v1 -> v2
|
||||
- threads.state.currentStagingSelections: CodeStagingSelection[] | null;
|
||||
+ thread[threadIdx].state
|
||||
+ message.state
|
||||
+ chatMessage.staging: StagingInfo | null
|
||||
*/
|
||||
else if (oldVersion === 'v1') {
|
||||
const threads = oldThreadsObject as Omit<ChatThreads, 'staging' | 'focusedMessageIdx'>
|
||||
// update the threads
|
||||
for (const thread of Object.values(threads)) {
|
||||
if (!thread.state) {
|
||||
thread.state = defaultThreadState
|
||||
}
|
||||
for (const chatMessage of Object.values(thread.messages)) {
|
||||
if (chatMessage.role === 'user' && !chatMessage.state) {
|
||||
chatMessage.state = defaultMessageState
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// push the update
|
||||
return threads
|
||||
}
|
||||
else if (oldVersion === 'v2') {
|
||||
return null
|
||||
}
|
||||
|
||||
// up to date
|
||||
return null
|
||||
|
||||
}
|
||||
|
||||
|
||||
// this should be the only place this.state = ... appears besides constructor
|
||||
private _setState(state: Partial<ThreadsState>, affectsCurrent: boolean) {
|
||||
this.state = {
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
* Licensed under the Apache License, Version 2.0. See LICENSE.txt for more information.
|
||||
*--------------------------------------------------------------------------------------*/
|
||||
|
||||
import { ChatMessage } from '../browser/chatThreadService.js'
|
||||
import { ChatMessage } from './chatThreadService.js'
|
||||
import { InternalToolInfo, ToolName } from './toolsService.js'
|
||||
import { FeatureName, ProviderName, SettingsOfProvider } from './voidSettingsTypes.js'
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ type SetModelSelectionOfFeatureFn = <K extends FeatureName>(
|
|||
options?: { doNotApplyEffects?: true }
|
||||
) => Promise<void>;
|
||||
|
||||
type SetGlobalSettingFn = <T extends GlobalSettingName, >(settingName: T, newVal: GlobalSettings[T]) => void;
|
||||
type SetGlobalSettingFn = <T extends GlobalSettingName>(settingName: T, newVal: GlobalSettings[T]) => void;
|
||||
|
||||
export type ModelOption = { name: string, selection: ModelSelection }
|
||||
|
||||
|
|
@ -49,6 +49,8 @@ export interface IVoidSettingsService {
|
|||
readonly state: VoidSettingsState; // in order to play nicely with react, you should immutably change state
|
||||
readonly waitForInitState: Promise<void>;
|
||||
|
||||
readAndInitializeState: (providedState?: VoidSettingsState) => Promise<void>;
|
||||
|
||||
onDidChangeState: Event<void>;
|
||||
|
||||
setSettingOfProvider: SetSettingOfProviderFn;
|
||||
|
|
@ -168,6 +170,8 @@ class VoidSettingsService extends Disposable implements IVoidSettingsService {
|
|||
readonly onDidChangeState: Event<void> = this._onDidChangeState.event; // this is primarily for use in react, so react can listen + update on state changes
|
||||
|
||||
state: VoidSettingsState;
|
||||
|
||||
private readonly _resolver: () => void
|
||||
waitForInitState: Promise<void> // await this if you need a valid state initially
|
||||
|
||||
constructor(
|
||||
|
|
@ -181,56 +185,57 @@ class VoidSettingsService extends Disposable implements IVoidSettingsService {
|
|||
|
||||
// at the start, we haven't read the partial config yet, but we need to set state to something
|
||||
this.state = defaultState()
|
||||
|
||||
let resolver: () => void = () => { }
|
||||
this.waitForInitState = new Promise((res, rej) => resolver = res)
|
||||
this._resolver = resolver
|
||||
|
||||
// read and update the actual state immediately
|
||||
this._readState().then(readS => {
|
||||
this.readAndInitializeState()
|
||||
}
|
||||
|
||||
// the stored data structure might be outdated, so we need to update it here (can do a more general solution later when we need to)
|
||||
const newSettingsOfProvider = {
|
||||
// A HACK BECAUSE WE ADDED DEEPSEEK (did not exist before, comes before readS)
|
||||
...{ deepseek: defaultSettingsOfProvider.deepseek },
|
||||
async readAndInitializeState(providedState?: VoidSettingsState) {
|
||||
// If providedState is given, use it instead of reading from storage
|
||||
const readS = providedState || await this._readState();
|
||||
|
||||
// A HACK BECAUSE WE ADDED XAI (did not exist before, comes before readS)
|
||||
...{ xAI: defaultSettingsOfProvider.xAI },
|
||||
// the stored data structure might be outdated, so we need to update it here
|
||||
const newSettingsOfProvider = {
|
||||
// A HACK BECAUSE WE ADDED DEEPSEEK (did not exist before, comes before readS)
|
||||
...{ deepseek: defaultSettingsOfProvider.deepseek },
|
||||
|
||||
// A HACK BECAUSE WE ADDED VLLM (did not exist before, comes before readS)
|
||||
...{ vLLM: defaultSettingsOfProvider.vLLM },
|
||||
// A HACK BECAUSE WE ADDED XAI (did not exist before, comes before readS)
|
||||
...{ xAI: defaultSettingsOfProvider.xAI },
|
||||
|
||||
// A HACK BECAUSE WE ADDED VLLM (did not exist before, comes before readS)
|
||||
...{ vLLM: defaultSettingsOfProvider.vLLM },
|
||||
|
||||
...readS.settingsOfProvider,
|
||||
...readS.settingsOfProvider,
|
||||
|
||||
// A HACK BECAUSE WE ADDED NEW GEMINI MODELS (existed before, comes after readS)
|
||||
gemini: {
|
||||
...readS.settingsOfProvider.gemini,
|
||||
models: [
|
||||
...readS.settingsOfProvider.gemini.models,
|
||||
...defaultSettingsOfProvider.gemini.models.filter(m => /* if cant find the model in readS (yes this is O(n^2), very small) */ !readS.settingsOfProvider.gemini.models.find(m2 => m2.modelName === m.modelName))
|
||||
]
|
||||
}
|
||||
// A HACK BECAUSE WE ADDED NEW GEMINI MODELS (existed before, comes after readS)
|
||||
gemini: {
|
||||
...readS.settingsOfProvider.gemini,
|
||||
models: [
|
||||
...readS.settingsOfProvider.gemini.models,
|
||||
...defaultSettingsOfProvider.gemini.models.filter(m => /* if cant find the model in readS (yes this is O(n^2), very small) */ !readS.settingsOfProvider.gemini.models.find(m2 => m2.modelName === m.modelName))
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
const newModelSelectionOfFeature = {
|
||||
// A HACK BECAUSE WE ADDED FastApply
|
||||
...{ 'Apply': null },
|
||||
...readS.modelSelectionOfFeature,
|
||||
}
|
||||
const newModelSelectionOfFeature = {
|
||||
// A HACK BECAUSE WE ADDED FastApply
|
||||
...{ 'Apply': null },
|
||||
...readS.modelSelectionOfFeature,
|
||||
};
|
||||
|
||||
readS = {
|
||||
...readS,
|
||||
settingsOfProvider: newSettingsOfProvider,
|
||||
modelSelectionOfFeature: newModelSelectionOfFeature,
|
||||
}
|
||||
const finalState = {
|
||||
...readS,
|
||||
settingsOfProvider: newSettingsOfProvider,
|
||||
modelSelectionOfFeature: newModelSelectionOfFeature,
|
||||
};
|
||||
|
||||
this.state = _validatedState(readS)
|
||||
|
||||
resolver()
|
||||
this._onDidChangeState.fire()
|
||||
})
|
||||
this.state = _validatedState(finalState);
|
||||
|
||||
|
||||
this._resolver();
|
||||
this._onDidChangeState.fire();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue