From 806ec939e53739a0f7020e129d3e4c88ad73fb17 Mon Sep 17 00:00:00 2001 From: mp Date: Mon, 23 Dec 2024 02:34:23 -0800 Subject: [PATCH] ux for providers --- .../void/common/refreshModelService.ts | 8 +- .../void/common/voidSettingsService.ts | 4 +- .../platform/void/common/voidSettingsTypes.ts | 18 +-- .../react/src/sidebar-tsx/SidebarChat.tsx | 2 +- .../void/browser/react/src/util/inputs.tsx | 4 +- .../react/src/void-settings-tsx/Settings.tsx | 120 ++++++++++++------ 6 files changed, 102 insertions(+), 54 deletions(-) diff --git a/src/vs/platform/void/common/refreshModelService.ts b/src/vs/platform/void/common/refreshModelService.ts index 123a12c7..3859a82a 100644 --- a/src/vs/platform/void/common/refreshModelService.ts +++ b/src/vs/platform/void/common/refreshModelService.ts @@ -32,8 +32,8 @@ export type RefreshModelStateOfProvider = Record { let modelOptions: ModelOption[] = [] for (const providerName of providerNames) { const providerConfig = settingsOfProvider[providerName] - if (!providerConfig.enabled) continue // if disabled, don't display model options + if (!providerConfig._enabled) continue // if disabled, don't display model options for (const { modelName, isHidden } of providerConfig.models) { if (isHidden) continue modelOptions.push({ text: `${modelName} (${providerName})`, value: { providerName, modelName } }) @@ -151,7 +151,7 @@ class VoidSettingsService extends Disposable implements IVoidSettingsService { const newFeatureFlags = this.state.featureFlagSettings // if changed models or enabled a provider, recompute models list - const modelsListChanged = settingName === 'models' || settingName === 'enabled' + const modelsListChanged = settingName === 'models' || settingName === '_enabled' const newModelsList = modelsListChanged ? _computeModelOptions(newSettingsOfProvider) : this.state._modelOptions const newState: VoidSettingsState = { diff --git a/src/vs/platform/void/common/voidSettingsTypes.ts b/src/vs/platform/void/common/voidSettingsTypes.ts index 1b1b2ff7..22cbdcc2 100644 --- a/src/vs/platform/void/common/voidSettingsTypes.ts +++ b/src/vs/platform/void/common/voidSettingsTypes.ts @@ -137,7 +137,7 @@ export const customSettingNamesOfProvider = (providerName: ProviderName) => { type CommonProviderSettings = { - enabled: boolean | undefined, // undefined initially + _enabled: boolean | undefined, // undefined initially, computed when user types in all fields models: VoidModelInfo[], } @@ -240,7 +240,7 @@ export const displayInfoOfSettingName = (providerName: ProviderName, settingName undefined, } } - else if (settingName === 'enabled') { + else if (settingName === '_enabled') { return { title: '(never)', placeholder: '(never)', @@ -293,13 +293,13 @@ export const voidInitModelOptions = { // used when waiting and for a type reference export const defaultSettingsOfProvider: SettingsOfProvider = { anthropic: { - enabled: undefined, + _enabled: undefined, ...defaultCustomSettings, ...defaultProviderSettings.anthropic, ...voidInitModelOptions.anthropic, }, openAI: { - enabled: undefined, + _enabled: undefined, ...defaultCustomSettings, ...defaultProviderSettings.openAI, ...voidInitModelOptions.openAI, @@ -308,31 +308,31 @@ export const defaultSettingsOfProvider: SettingsOfProvider = { ...defaultCustomSettings, ...defaultProviderSettings.gemini, ...voidInitModelOptions.gemini, - enabled: undefined, + _enabled: undefined, }, groq: { ...defaultCustomSettings, ...defaultProviderSettings.groq, ...voidInitModelOptions.groq, - enabled: undefined, + _enabled: undefined, }, ollama: { ...defaultCustomSettings, ...defaultProviderSettings.ollama, ...voidInitModelOptions.ollama, - enabled: undefined, + _enabled: undefined, }, openRouter: { ...defaultCustomSettings, ...defaultProviderSettings.openRouter, ...voidInitModelOptions.openRouter, - enabled: undefined, + _enabled: undefined, }, openAICompatible: { ...defaultCustomSettings, ...defaultProviderSettings.openAICompatible, ...voidInitModelOptions.openAICompatible, - enabled: undefined, + _enabled: undefined, }, } 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 269b6351..363c3630 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 @@ -134,7 +134,7 @@ export const ButtonStop = ({ className, ...props }: ButtonHTMLAttributes - + } diff --git a/src/vs/workbench/contrib/void/browser/react/src/util/inputs.tsx b/src/vs/workbench/contrib/void/browser/react/src/util/inputs.tsx index 4eccb09f..31710236 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/util/inputs.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/util/inputs.tsx @@ -312,8 +312,8 @@ export const VoidCodeEditor = ({ initValue, language }: { initValue: string, lan alwaysConsumeMouseWheel: false, vertical: 'auto', horizontal: 'auto', - // verticalScrollbarSize: 3, - // horizontalScrollbarSize: 3, + verticalScrollbarSize: 0, + horizontalScrollbarSize: 0, }, scrollBeyondLastLine: false, diff --git a/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx b/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx index 583e6f56..11411198 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx @@ -1,12 +1,23 @@ import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react' import { InputBox } from '../../../../../../../base/browser/ui/inputbox/inputBox.js' -import { ProviderName, SettingName, displayInfoOfSettingName, providerNames, VoidModelInfo, featureFlagNames, displayInfoOfFeatureFlag, customSettingNamesOfProvider, RefreshableProviderName, refreshableProviderNames, displayInfoOfProviderName } from '../../../../../../../platform/void/common/voidSettingsTypes.js' +import { ProviderName, SettingName, displayInfoOfSettingName, providerNames, VoidModelInfo, featureFlagNames, displayInfoOfFeatureFlag, customSettingNamesOfProvider, RefreshableProviderName, refreshableProviderNames, displayInfoOfProviderName, defaultProviderSettings } from '../../../../../../../platform/void/common/voidSettingsTypes.js' import ErrorBoundary from '../sidebar-tsx/ErrorBoundary.js' import { VoidCheckBox, VoidInputBox, VoidSelectBox, VoidSwitch } from '../util/inputs.js' import { useAccessor, useIsDark, useRefreshModelListener, useRefreshModelState, useSettingsState } from '../util/services.js' import { X, RefreshCw, Loader2, Check } from 'lucide-react' import { ChatMarkdownRender } from '../markdown/ChatMarkdownRender.js' +const SubtleButton = ({ onClick, text, icon, disabled }: { onClick: () => void, text: string, icon: React.ReactNode, disabled: boolean }) => { + + return
+ + + {text} + +
+} // models @@ -34,14 +45,12 @@ const RefreshModelButton = ({ providerName }: { providerName: RefreshableProvide const isRefreshing = state === 'refreshing' const { title: providerTitle } = displayInfoOfProviderName(providerName) - return
- - { - justFinished ? `${providerTitle} Models are up-to-date!` : `Refresh Models List for ${providerTitle}.` - } -
+ return { refreshModelService.refreshModels(providerName) }} + text={justFinished ? `${providerTitle} Models are up-to-date!` : `Refresh Models List for ${providerTitle}.`} + icon={isRefreshing ? : (justFinished ? : )} + disabled={isRefreshing || justFinished} + /> } const RefreshableModels = () => { @@ -49,7 +58,7 @@ const RefreshableModels = () => { const buttons = refreshableProviderNames.map(providerName => { - if (!settingsState.settingsOfProvider[providerName].enabled) return null + if (!settingsState.settingsOfProvider[providerName]._enabled) return null return }) @@ -162,7 +171,7 @@ export const ModelDump = () => { for (let providerName of providerNames) { const providerSettings = settingsState.settingsOfProvider[providerName] // if (!providerSettings.enabled) continue - modelDump.push(...providerSettings.models.map(model => ({ ...model, providerName, providerEnabled: !!providerSettings.enabled }))) + modelDump.push(...providerSettings.models.map(model => ({ ...model, providerName, providerEnabled: !!providerSettings._enabled }))) } // sort by hidden @@ -231,10 +240,27 @@ const ProviderSetting = ({ providerName, settingName }: { providerName: Provider const syncInstance = () => { const settingsAtProvider = voidSettingsService.state.settingsOfProvider[providerName]; const stateVal = settingsAtProvider[settingName as SettingName] + // console.log('SYNCING TO', providerName, settingName, stateVal) weChangedTextRef = true instance.value = stateVal as string weChangedTextRef = false + + const isEverySettingPresent = Object.keys(defaultProviderSettings[providerName]).every(key => { + return !!settingsAtProvider[key as keyof typeof settingsAtProvider] + }) + + const shouldEnable = isEverySettingPresent && !settingsAtProvider._enabled // enable if all settings are present and not already enabled + const shouldDisable = !isEverySettingPresent && settingsAtProvider._enabled + + if (shouldEnable) { + voidSettingsService.setSettingOfProvider(providerName, '_enabled', true) + } + + if (shouldDisable) { + voidSettingsService.setSettingOfProvider(providerName, '_enabled', false) + } + } syncInstance() const disposable = voidSettingsService.onDidChangeState(syncInstance) @@ -251,21 +277,22 @@ const ProviderSetting = ({ providerName, settingName }: { providerName: Provider } const SettingsForProvider = ({ providerName }: { providerName: ProviderName }) => { - const voidSettingsState = useSettingsState() - const accessor = useAccessor() - const voidSettingsService = accessor.get('IVoidSettingsService') + // const voidSettingsState = useSettingsState() + // const accessor = useAccessor() + // const voidSettingsService = accessor.get('IVoidSettingsService') - const { enabled } = voidSettingsState.settingsOfProvider[providerName] + // const { enabled } = voidSettingsState.settingsOfProvider[providerName] const settingNames = customSettingNamesOfProvider(providerName) const { title: providerTitle } = displayInfoOfProviderName(providerName) return
+

{providerTitle}

{/* enable provider switch */} - { @@ -273,7 +300,7 @@ const SettingsForProvider = ({ providerName }: { providerName: ProviderName }) = voidSettingsService.setSettingOfProvider(providerName, 'enabled', !enabledRef) }, [voidSettingsService, providerName])} size='sm+' - /> + /> */}
@@ -282,7 +309,7 @@ const SettingsForProvider = ({ providerName }: { providerName: ProviderName }) = return })}
-
+ } @@ -294,29 +321,49 @@ export const VoidProviderSettings = () => { } +// export const VoidFeatureFlagSettings = () => { +// const accessor = useAccessor() +// const voidSettingsService = accessor.get('IVoidSettingsService') +// const voidSettingsState = useSettingsState() + +// return <> +// {featureFlagNames.map((flagName) => { +// const value = voidSettingsState.featureFlagSettings[flagName] +// const { description } = displayInfoOfFeatureFlag(flagName) +// return
+//
+// { voidSettingsService.setFeatureFlag(flagName, !value) }} +// /> +//

{description}

+//
+//
+// })} +// +// } export const VoidFeatureFlagSettings = () => { + + const accessor = useAccessor() const voidSettingsService = accessor.get('IVoidSettingsService') const voidSettingsState = useSettingsState() - return <> - {featureFlagNames.map((flagName) => { - const value = voidSettingsState.featureFlagSettings[flagName] - const { description } = displayInfoOfFeatureFlag(flagName) - return
-
- { voidSettingsService.setFeatureFlag(flagName, !value) }} - /> -

{description}

-
-
- })} - + return featureFlagNames.map((flagName) => { + + const enabled = voidSettingsState.featureFlagSettings[flagName] + const { description } = displayInfoOfFeatureFlag(flagName) + + return { voidSettingsService.setFeatureFlag(flagName, !enabled) }} + text={description} + icon={enabled ? : } + disabled={false} + /> + }) } @@ -359,20 +406,21 @@ export const Settings = () => {

Providers

+

Models

+ -

{ setTab('features') }}>Features

- + {/* */}