ollama refreshes!

This commit is contained in:
Andrew Pareles 2024-12-13 00:41:34 -08:00
parent 1365400f21
commit e2d39fe4b1
19 changed files with 271 additions and 116 deletions

View file

@ -1,32 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Glass Devtools, Inc. All rights reserved.
* Void Editor additions licensed under the AGPL 3.0 License.
*--------------------------------------------------------------------------------------------*/
import { ProxyChannel } from '../../../base/parts/ipc/common/ipc.js';
import { IMainProcessService } from '../../ipc/common/mainProcessService.js';
import { InstantiationType, registerSingleton } from '../../instantiation/common/extensions.js';
import { IMetricsService } from '../common/metricsService.js';
// BROWSER IMPLEMENTATION, calls channel
export class MetricsService implements IMetricsService {
readonly _serviceBrand: undefined;
private readonly metricsService: IMetricsService;
constructor(
@IMainProcessService mainProcessService: IMainProcessService // (only usable on client side)
) {
this.metricsService = ProxyChannel.toService<IMetricsService>(mainProcessService.getChannel('void-channel-metrics'));
}
// call capture on the channel
capture(...params: Parameters<IMetricsService['capture']>) {
this.metricsService.capture(...params);
}
}
registerSingleton(IMetricsService, MetricsService, InstantiationType.Eager);

View file

@ -1,12 +0,0 @@
// --- browser ---
// metrics
import '../browser/metricsService.js'
// --- common ---
// llmMessage
import '../browser/llmMessageService.js'
// voidConfig
import '../common/voidConfigService.js'

View file

@ -3,7 +3,7 @@
* Void Editor additions licensed under the AGPL 3.0 License.
*--------------------------------------------------------------------------------------------*/
import { EventLLMMessageOnTextParams, EventLLMMessageOnErrorParams, EventLLMMessageOnFinalMessageParams, ServiceSendLLMMessageParams, MainLLMMessageParams, MainLLMMessageAbortParams, ServiceOllamaListParams, EventOllamaListOnSuccessParams, EventOllamaListOnErrorParams, MainOllamaListParams } from '../common/llmMessageTypes.js';
import { EventLLMMessageOnTextParams, EventLLMMessageOnErrorParams, EventLLMMessageOnFinalMessageParams, ServiceSendLLMMessageParams, MainLLMMessageParams, MainLLMMessageAbortParams, ServiceOllamaListParams, EventOllamaListOnSuccessParams, EventOllamaListOnErrorParams, MainOllamaListParams } from './llmMessageTypes.js';
import { IChannel } from '../../../base/parts/ipc/common/ipc.js';
import { IMainProcessService } from '../../ipc/common/mainProcessService.js';
import { InstantiationType, registerSingleton } from '../../instantiation/common/extensions.js';
@ -11,21 +11,19 @@ import { generateUuid } from '../../../base/common/uuid.js';
import { createDecorator } from '../../instantiation/common/instantiation.js';
import { Event } from '../../../base/common/event.js';
import { Disposable } from '../../../base/common/lifecycle.js';
import { IVoidConfigStateService } from '../common/voidConfigService.js';
import { IVoidConfigStateService } from './voidConfigService.js';
// import { INotificationService } from '../../notification/common/notification.js';
// BROWSER IMPLEMENTATION
// calls channel to implement features
export const ILLMMessageService = createDecorator<ILLMMessageService>('llmMessageService');
// defines an interface that node/ creates and browser/ uses
export interface ILLMMessageService {
readonly _serviceBrand: undefined;
sendLLMMessage: (params: ServiceSendLLMMessageParams) => string | null;
abort: (requestId: string) => void;
ollamaList: (params: ServiceOllamaListParams) => void;
}
export class LLMMessageService extends Disposable implements ILLMMessageService {
readonly _serviceBrand: undefined;
@ -52,8 +50,7 @@ export class LLMMessageService extends Disposable implements ILLMMessageService
// const service = ProxyChannel.toService<LLMMessageChannel>(mainProcessService.getChannel('void-channel-sendLLMMessage')); // lets you call it like a service
this.channel = this.mainProcessService.getChannel('void-channel-llmMessageService')
// this sets up an IPC channel and takes a few ms, so we set up listeners immediately and add hooks to them instead
// .listen sets up an IPC channel and takes a few ms, so we set up listeners immediately and add hooks to them instead
// llm
this._register((this.channel.listen('onText_llm') satisfies Event<EventLLMMessageOnTextParams>)(e => {
this.onTextHooks_llm[e.requestId]?.(e)
@ -74,6 +71,7 @@ export class LLMMessageService extends Disposable implements ILLMMessageService
this._register((this.channel.listen('onError_ollama') satisfies Event<EventOllamaListOnErrorParams>)(e => {
this.onError_ollama[e.requestId]?.(e)
}))
}
sendLLMMessage(params: ServiceSendLLMMessageParams) {
@ -114,6 +112,7 @@ export class LLMMessageService extends Disposable implements ILLMMessageService
this._onRequestIdDone(requestId)
}
ollamaList = (params: ServiceOllamaListParams) => {
const { onSuccess, onError, ...proxyParams } = params
@ -132,6 +131,7 @@ export class LLMMessageService extends Disposable implements ILLMMessageService
}
_onRequestIdDone(requestId: string) {
delete this.onTextHooks_llm[requestId]
delete this.onFinalMessageHooks_llm[requestId]
@ -142,5 +142,5 @@ export class LLMMessageService extends Disposable implements ILLMMessageService
}
}
registerSingleton(ILLMMessageService, LLMMessageService, InstantiationType.Delayed);
registerSingleton(ILLMMessageService, LLMMessageService, InstantiationType.Eager);

View file

@ -106,7 +106,7 @@ interface ModelDetails {
quantization_level: string;
}
type ModelResponse = {
export type ModelResponse = {
name: string;
modified_at: Date;
size: number;
@ -121,7 +121,7 @@ type ModelResponse = {
export type OllamaListParams = {
settingsOfProvider: SettingsOfProvider;
onSuccess: (param: { models: ModelResponse[] }) => void;
onError: (param: { error: any }) => void;
onError: (param: { error: string }) => void;
}
export type ServiceOllamaListParams = {

View file

@ -4,6 +4,9 @@
*--------------------------------------------------------------------------------------------*/
import { createDecorator } from '../../instantiation/common/instantiation.js';
import { ProxyChannel } from '../../../base/parts/ipc/common/ipc.js';
import { IMainProcessService } from '../../ipc/common/mainProcessService.js';
import { InstantiationType, registerSingleton } from '../../instantiation/common/extensions.js';
export interface IMetricsService {
readonly _serviceBrand: undefined;
@ -13,3 +16,24 @@ export interface IMetricsService {
export const IMetricsService = createDecorator<IMetricsService>('metricsService');
// implemented by calling channel
export class MetricsService implements IMetricsService {
readonly _serviceBrand: undefined;
private readonly metricsService: IMetricsService;
constructor(
@IMainProcessService mainProcessService: IMainProcessService // (only usable on client side)
) {
this.metricsService = ProxyChannel.toService<IMetricsService>(mainProcessService.getChannel('void-channel-metrics'));
}
// call capture on the channel
capture(...params: Parameters<IMetricsService['capture']>) {
this.metricsService.capture(...params);
}
}
registerSingleton(IMetricsService, MetricsService, InstantiationType.Eager);

View file

@ -0,0 +1,96 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Glass Devtools, Inc. All rights reserved.
* Void Editor additions licensed under the AGPL 3.0 License.
*--------------------------------------------------------------------------------------------*/
import { createDecorator } from '../../instantiation/common/instantiation.js';
import { InstantiationType, registerSingleton } from '../../instantiation/common/extensions.js';
import { IVoidConfigStateService } from './voidConfigService.js';
import { ILLMMessageService } from './llmMessageService.js';
import { Emitter, Event } from '../../../base/common/event.js';
import { Disposable } from '../../../base/common/lifecycle.js';
export type RefreshModelState = 'done' | 'loading'
export interface IRefreshModelService {
readonly _serviceBrand: undefined;
refreshOllamaModels(): void;
onDidChangeState: Event<void>;
state: RefreshModelState;
}
export const IRefreshModelService = createDecorator<IRefreshModelService>('RefreshModelService');
export class RefreshModelService extends Disposable implements IRefreshModelService {
readonly _serviceBrand: undefined;
private readonly _onDidChangeState = new Emitter<void>();
readonly onDidChangeState: Event<void> = this._onDidChangeState.event; // this is primarily for use in react, so react can listen + update on state changes
constructor(
@IVoidConfigStateService private readonly voidConfigStateService: IVoidConfigStateService,
@ILLMMessageService private readonly llmMessageService: ILLMMessageService,
) {
super()
// on mount, refresh ollama models
this.refreshOllamaModels()
// every time ollama.enabled changes, refresh ollama models
let prevVal: string = this.voidConfigStateService.state.settingsOfProvider.ollama.enabled
this._register(
this.voidConfigStateService.onDidChangeState(() => {
const newVal = this.voidConfigStateService.state.settingsOfProvider.ollama.enabled
if (prevVal !== newVal)
this.refreshOllamaModels()
prevVal = newVal
})
)
}
state: RefreshModelState = 'done'
private _timeoutId: NodeJS.Timeout | null = null
private _cancelTimeout = () => {
if (this._timeoutId) {
clearTimeout(this._timeoutId)
this._timeoutId = null
}
}
async refreshOllamaModels() {
// cancel any existing poll
this._cancelTimeout()
// if ollama is disabled, obivously done
if (this.voidConfigStateService.state.settingsOfProvider.ollama.enabled !== 'true') {
this._setState('done')
return
}
// start loading models
this._setState('loading')
this.llmMessageService.ollamaList({
onSuccess: ({ models }) => {
this.voidConfigStateService.setSettingOfProvider('ollama', 'models', models.map(model => model.name))
this._setState('done')
},
onError: ({ error }) => {
// poll
console.log('retrying ollamaList:', error)
this._timeoutId = setTimeout(() => this.refreshOllamaModels(), 5000)
}
})
}
private _setState(state: RefreshModelState) {
this.state = state
this._onDidChangeState.fire()
}
}
registerSingleton(IRefreshModelService, RefreshModelService, InstantiationType.Eager);

View file

@ -0,0 +1,11 @@
// llmMessage
import './llmMessageService.js'
// voidConfig
import './voidConfigService.js'
// refreshModel
import './refreshModelService.js'
// metrics
import './metricsService.js'

View file

@ -10,15 +10,15 @@ import { IEncryptionService } from '../../encryption/common/encryptionService.js
import { registerSingleton, InstantiationType } from '../../instantiation/common/extensions.js';
import { createDecorator } from '../../instantiation/common/instantiation.js';
import { IStorageService, StorageScope, StorageTarget } from '../../storage/common/storage.js';
import { defaultVoidProviderState, FeatureName, ProviderName, ModelSelectionOfFeature, SettingsOfProvider } from './voidConfigTypes.js';
import { defaultVoidProviderState, FeatureName, ProviderName, ModelSelectionOfFeature, SettingsOfProvider, SettingName } from './voidConfigTypes.js';
const STORAGE_KEY = 'void.voidConfigStateII'
type SetSettingOfProviderFn = <K extends ProviderName>(
providerName: K,
option: keyof SettingsOfProvider[K],
newVal: string
type SetSettingOfProviderFn = <S extends SettingName>(
providerName: ProviderName,
settingName: S,
newVal: SettingsOfProvider[ProviderName][S extends keyof SettingsOfProvider[ProviderName] ? S : never],
) => Promise<void>;
type SetModelSelectionOfFeature = <K extends FeatureName>(
@ -52,7 +52,7 @@ const defaultState = () => {
export const IVoidConfigStateService = createDecorator<IVoidConfigStateService>('VoidConfigStateService');
class VoidConfigStateService extends Disposable implements IVoidConfigStateService {
class VoidConfigService extends Disposable implements IVoidConfigStateService {
_serviceBrand: undefined;
private readonly _onDidChangeState = new Emitter<void>();
@ -75,7 +75,10 @@ class VoidConfigStateService extends Disposable implements IVoidConfigStateServi
this.state = defaultState()
// read and update the actual state immediately
this._readVoidConfigState().then(voidConfigState => { this._setState(voidConfigState, 'initialState') })
this._readVoidConfigState().then(voidConfigState => {
this._setState(voidConfigState)
this._onDidGetInitState.fire()
})
}
@ -95,16 +98,16 @@ class VoidConfigStateService extends Disposable implements IVoidConfigStateServi
this._storageService.store(STORAGE_KEY, encryptedVoidConfigStr, StorageScope.APPLICATION, StorageTarget.USER);
}
setSettingOfProvider: SetSettingOfProviderFn = async (providerName, option, newVal) => {
setSettingOfProvider: SetSettingOfProviderFn = async (providerName, settingName, newVal) => {
const newState: VoidConfigState = {
...this.state,
settingsOfProvider: {
...this.state.settingsOfProvider,
[providerName]: {
...this.state.settingsOfProvider[providerName],
[option]: newVal,
[settingName]: newVal,
}
}
},
}
// console.log('NEW STATE I', JSON.stringify(newState, null, 2))
@ -129,14 +132,11 @@ class VoidConfigStateService extends Disposable implements IVoidConfigStateServi
// internal function to update state, should be called every time state changes
private async _setState(voidConfigState: VoidConfigState, type: 'usual' | 'initialState' = 'usual') {
private async _setState(voidConfigState: VoidConfigState) {
this.state = voidConfigState
if (type === 'usual')
this._onDidChangeState.fire()
else if (type === 'initialState')
this._onDidGetInitState.fire()
this._onDidChangeState.fire()
}
}
registerSingleton(IVoidConfigStateService, VoidConfigStateService, InstantiationType.Eager);
registerSingleton(IVoidConfigStateService, VoidConfigService, InstantiationType.Eager);

View file

@ -42,7 +42,7 @@ export const voidInitModelOptions = {
models: defaultOpenAIModels,
},
ollama: {
models: [],//getDefaultOllamaModels,
models: [],
},
openRouter: {
models: [], // any string
@ -164,7 +164,7 @@ export const displayInfoOfSettingName = (providerName: ProviderName, settingName
}
// used when waiting and for a type reference
export const defaultVoidProviderState: SettingsOfProvider = {
anthropic: {
...voidProviderDefaults.anthropic,

View file

@ -4,21 +4,35 @@
*--------------------------------------------------------------------------------------------*/
import { Ollama } from 'ollama';
import { _InternalOllamaListFnType, _InternalSendLLMMessageFnType } from '../../common/llmMessageTypes.js';
import { _InternalOllamaListFnType, _InternalSendLLMMessageFnType, ModelResponse } from '../../common/llmMessageTypes.js';
import { parseMaxTokensStr } from './util.js';
export const ollamaList: _InternalOllamaListFnType = async ({ onSuccess, onError, settingsOfProvider }) => {
const thisConfig = settingsOfProvider.ollama
const ollama = new Ollama({ host: thisConfig.endpoint })
ollama.list()
.then((response) => {
const { models } = response
onSuccess({ models })
})
.catch((error) => {
console.error('getDefaultOllamaModels: error:', error)
onError(error)
})
export const ollamaList: _InternalOllamaListFnType = async ({ onSuccess: onSuccess_, onError: onError_, settingsOfProvider }) => {
const onSuccess = ({ models }: { models: ModelResponse[] }) => {
onSuccess_({ models })
}
const onError = ({ error }: { error: string }) => {
onError_({ error })
}
try {
const thisConfig = settingsOfProvider.ollama
const ollama = new Ollama({ host: thisConfig.endpoint })
ollama.list()
.then((response) => {
const { models } = response
onSuccess({ models })
})
.catch((error) => {
onError({ error: error + '' })
})
}
catch (error) {
onError({ error: error + '' })
}
}

View file

@ -31,8 +31,7 @@ export class LLMMessageChannel implements IServerChannel {
// stupidly, channels can't take in @IService
constructor(
private readonly metricsService: IMetricsService,
) {
}
) { }
// browser uses this to listen for changes
listen(_: unknown, event: string): Event<any> {

View file

@ -3,10 +3,10 @@
* Void Editor additions licensed under the AGPL 3.0 License.
*--------------------------------------------------------------------------------------------*/
import { useCallback, useEffect, useRef } from 'react'
import { useCallback, useEffect, useRef, useState } from 'react'
import { FeatureName, featureNames, ProviderName, providerNames } from '../../../../../../../platform/void/common/voidConfigTypes.js'
import { dummyModelData } from '../../../../../../../platform/void/common/voidConfigModelDefaults.js'
import { useConfigState, useService } from '../util/services.js'
import { useConfigState, useRefreshModelState, useService } from '../util/services.js'
import { VoidSelectBox } from './inputs.js'
import { SelectBox } from '../../../../../../../base/browser/ui/selectBox/selectBox.js'
@ -59,8 +59,18 @@ export const ModelSelectionOfFeature = ({ featureName }: { featureName: FeatureN
}, [voidConfigService, modelOptions, featureName])}
/>}
{/* <h1>Settings - {featureName}</h1> */}
{/* {models.map(([providerName, model], i) => <p key={i}>{providerName} - {model}</p>)} */}
</>
}
const RefreshModels = () => {
const refreshModelState = useRefreshModelState()
const refreshModelService = useService('refreshModelService')
return <>
<button onClick={() => refreshModelService.refreshOllamaModels()}>
refresh
</button>
{refreshModelState === 'loading' ? 'loading...' : '✅'}
</>
}
@ -70,6 +80,8 @@ export const ModelSelectionSettings = () => {
key={featureName}
featureName={featureName}
/>)}
<RefreshModels />
</>
}

View file

@ -4,14 +4,14 @@
*--------------------------------------------------------------------------------------------*/
import React, { Fragment, useCallback, useEffect, useRef, useState } from 'react'
import { titleOfProviderName, displayInfoOfSettingName, ProviderName, providerNames, featureNames } from '../../../../../../../platform/void/common/voidConfigTypes.js'
import { titleOfProviderName, displayInfoOfSettingName, ProviderName, providerNames, featureNames, SettingsOfProvider, SettingName, defaultVoidProviderState } from '../../../../../../../platform/void/common/voidConfigTypes.js'
import { VoidInputBox } from './inputs.js'
import { useConfigState, useService } from '../util/services.js'
import { InputBox } from '../../../../../../../base/browser/ui/inputbox/inputBox.js'
import ErrorBoundary from './ErrorBoundary.js'
const Setting = ({ providerName, settingName }: { providerName: ProviderName, settingName: any }) => {
const Setting = ({ providerName, settingName }: { providerName: ProviderName, settingName: SettingName }) => {
const { title, type, placeholder } = displayInfoOfSettingName(providerName, settingName)
const voidConfigService = useService('configStateService')
@ -22,6 +22,7 @@ const Setting = ({ providerName, settingName }: { providerName: ProviderName, se
<VoidInputBox
placeholder={placeholder}
onChangeText={useCallback((newVal) => {
voidConfigService.setSettingOfProvider(providerName, settingName, newVal)
// if we just disabeld this provider, we should unselect all models that use it
if (settingName === 'enabled' && newVal !== 'true') {
@ -54,10 +55,12 @@ const Setting = ({ providerName, settingName }: { providerName: ProviderName, se
const SettingsForProvider = ({ providerName }: { providerName: ProviderName }) => {
const voidConfigState = useConfigState()
const { models, ...others } = voidConfigState[providerName]
return <>
<h1 className='text-xl'>{titleOfProviderName(providerName)}</h1>
{/* settings besides models (e.g. api key) */}
{Object.keys(others).map((settingName, i) => {
{Object.keys(others).map((sName, i) => {
const settingName = sName as keyof typeof others
return <Setting key={settingName} providerName={providerName} settingName={settingName} />
})}
</>

View file

@ -15,8 +15,10 @@ export const mountFnGenerator = (Component: React.FC) => (rootElement: HTMLEleme
return
}
_registerServices(services)
const disposables = _registerServices(services)
const root = ReactDOM.createRoot(rootElement)
root.render(<Component />);
return disposables
}

View file

@ -7,6 +7,8 @@ import { useState, useEffect } from 'react'
import { VoidSidebarState, ReactServicesType } from '../../../registerSidebar.js'
import { ThreadsState } from '../../../registerThreads.js'
import { SettingsOfProvider } from '../../../../../../../platform/void/common/voidConfigTypes.js'
import { RefreshModelState } from '../../../../../../../platform/void/common/refreshModelService.js'
import { IDisposable } from '../../../../../../../base/common/lifecycle.js'
// normally to do this you'd use a useEffect that calls .onDidChangeState(), but useEffect mounts too late and misses initial state changes
@ -17,11 +19,13 @@ let services: ReactServicesType
let sidebarState: VoidSidebarState
let threadsState: ThreadsState
let settingsOfProvider: SettingsOfProvider
let refreshModelState: RefreshModelState
// React listens by adding a setState function to these:
const sidebarStateListeners: Set<(s: VoidSidebarState) => void> = new Set()
const threadsStateListeners: Set<(s: ThreadsState) => void> = new Set()
const settingsOfProviderListeners: Set<(s: SettingsOfProvider) => void> = new Set()
const refreshModelStateListeners: Set<(s: RefreshModelState) => void> = new Set()
// must call this before you can use any of the hooks below
// this should only be called ONCE! this is the only place you don't need to dispose onDidChange. If you use state.onDidChange anywhere else, make sure to dispose it!
@ -30,30 +34,47 @@ let wasCalled = false
export const _registerServices = (services_: ReactServicesType) => {
const disposables: IDisposable[] = []
if (wasCalled) console.error(`⚠️ Void _registerServices was called again! It should only be called once.`)
wasCalled = true
services = services_
const { sidebarStateService, configStateService, threadsStateService, } = services
const { sidebarStateService, configStateService, threadsStateService, refreshModelService } = services
sidebarState = sidebarStateService.state
sidebarStateService.onDidChangeState(() => {
sidebarState = sidebarStateService.state
sidebarStateListeners.forEach(l => l(sidebarState))
})
disposables.push(
sidebarStateService.onDidChangeState(() => {
sidebarState = sidebarStateService.state
sidebarStateListeners.forEach(l => l(sidebarState))
})
)
threadsState = threadsStateService.state
threadsStateService.onDidChangeCurrentThread(() => {
threadsState = threadsStateService.state
threadsStateListeners.forEach(l => l(threadsState))
})
disposables.push(
threadsStateService.onDidChangeCurrentThread(() => {
threadsState = threadsStateService.state
threadsStateListeners.forEach(l => l(threadsState))
})
)
settingsOfProvider = configStateService.state.settingsOfProvider
configStateService.onDidChangeState(() => {
settingsOfProvider = configStateService.state.settingsOfProvider
settingsOfProviderListeners.forEach(l => l(settingsOfProvider))
})
disposables.push(
configStateService.onDidChangeState(() => {
settingsOfProvider = configStateService.state.settingsOfProvider
settingsOfProviderListeners.forEach(l => l(settingsOfProvider))
})
)
refreshModelState = refreshModelService.state
disposables.push(
refreshModelService.onDidChangeState(() => {
refreshModelState = refreshModelService.state
refreshModelStateListeners.forEach(l => l(refreshModelState))
})
)
return disposables
}
@ -96,3 +117,14 @@ export const useThreadsState = () => {
}, [ss])
return s
}
export const useRefreshModelState = () => {
const [s, ss] = useState(refreshModelState)
useEffect(() => {
ss(refreshModelState)
refreshModelStateListeners.add(ss)
return () => { refreshModelStateListeners.delete(ss) }
}, [ss])
return s
}

View file

@ -12,7 +12,7 @@ import { Position } from '../../../../editor/common/core/position.js';
import { InlineCompletion, InlineCompletionContext } from '../../../../editor/common/languages.js';
import { CancellationToken } from '../../../../base/common/cancellation.js';
import { Range } from '../../../../editor/common/core/range.js';
import { ILLMMessageService } from '../../../../platform/void/browser/llmMessageService.js';
import { ILLMMessageService } from '../../../../platform/void/common/llmMessageService.js';
import { IEditorService } from '../../../services/editor/common/editorService.js';
import { isCodeEditor } from '../../../../editor/browser/editorBrowser.js';
import { EditorResourceAccessor } from '../../../common/editor.js';

View file

@ -29,7 +29,7 @@ import * as dom from '../../../../base/browser/dom.js';
import { Widget } from '../../../../base/browser/ui/widget.js';
import { URI } from '../../../../base/common/uri.js';
import { LLMFeatureSelection, ServiceSendLLMMessageParams } from '../../../../platform/void/common/llmMessageTypes.js';
import { ILLMMessageService } from '../../../../platform/void/browser/llmMessageService.js';
import { ILLMMessageService } from '../../../../platform/void/common/llmMessageService.js';
// gets converted to --vscode-void-greenBG, see void.css

View file

@ -25,7 +25,7 @@ import { IViewPaneOptions, ViewPane } from '../../../browser/parts/views/viewPan
import { IContextKeyService } from '../../../../platform/contextkey/common/contextkey.js';
import { createDecorator, IInstantiationService } from '../../../../platform/instantiation/common/instantiation.js';
import { Disposable } from '../../../../base/common/lifecycle.js';
import { Disposable, IDisposable } from '../../../../base/common/lifecycle.js';
import { Emitter, Event } from '../../../../base/common/event.js';
import { IThreadHistoryService } from './registerThreads.js';
import { IConfigurationService } from '../../../../platform/configuration/common/configuration.js';
@ -42,10 +42,11 @@ import { IVoidConfigStateService } from '../../../../platform/void/common/voidCo
import { IFileService } from '../../../../platform/files/common/files.js';
import { IInlineDiffsService } from './registerInlineDiffs.js';
import { IModelService } from '../../../../editor/common/services/model.js';
import { ILLMMessageService } from '../../../../platform/void/browser/llmMessageService.js';
import { ILLMMessageService } from '../../../../platform/void/common/llmMessageService.js';
import { IClipboardService } from '../../../../platform/clipboard/common/clipboardService.js';
import { IViewsService } from '../../../services/views/common/viewsService.js';
import { InstantiationType, registerSingleton } from '../../../../platform/instantiation/common/extensions.js';
import { IRefreshModelService } from '../../../../platform/void/common/refreshModelService.js';
// compare against search.contribution.ts and debug.contribution.ts, scm.contribution.ts (source control)
@ -64,6 +65,7 @@ export type ReactServicesType = {
inlineDiffService: IInlineDiffsService;
llmMessageService: ILLMMessageService;
clipboardService: IClipboardService;
refreshModelService: IRefreshModelService;
themeService: IThemeService,
hoverService: IHoverService,
@ -113,10 +115,14 @@ class VoidSidebarViewPane extends ViewPane {
clipboardService: accessor.get(IClipboardService),
themeService: accessor.get(IThemeService),
hoverService: accessor.get(IHoverService),
refreshModelService: accessor.get(IRefreshModelService),
contextViewService: accessor.get(IContextViewService),
contextMenuService: accessor.get(IContextMenuService),
}
mountFn(parent, services);
// mount react
const disposables: IDisposable[] | undefined = mountFn(parent, services);
disposables?.forEach(d => this._register(d))
});
}

View file

@ -17,7 +17,7 @@ import './browser/workbench.contribution.js';
//#region --- Void
// Void added this:
import './contrib/void/browser/void.contribution.js';
import '../platform/void/browser/void.contribution.js';
import '../platform/void/common/void.contribution.js';
//#endregion