mirror of
https://github.com/enricoros/big-AGI.git
synced 2026-05-10 21:50:14 -07:00
useLLMSelect: 10-100x faster on many models
This commit is contained in:
@@ -17,6 +17,7 @@ import { FormLabelStart } from './FormLabelStart';
|
||||
|
||||
|
||||
// configuration
|
||||
const LLM_SELECT_REDUCE_OPTIONS = 10; // optimization: number of options over which only the selected is kept when closed (we'll have special notes for accessibility)
|
||||
const LLM_SELECT_SHOW_REASONING_ICON = false;
|
||||
|
||||
|
||||
@@ -46,6 +47,7 @@ const _slotProps = {
|
||||
} as const,
|
||||
} as const,
|
||||
button: {
|
||||
'aria-description': 'Options may be filtered when closed. Open dropdown to see all options.',
|
||||
sx: {
|
||||
// show the full name on the button
|
||||
whiteSpace: 'inherit',
|
||||
@@ -70,7 +72,7 @@ interface LLMSelectOptions {
|
||||
*
|
||||
* @param llmId (required) the LLM id
|
||||
* @param setLlmId (required) the function to set the LLM id
|
||||
* @param options (optional) any arrray of options
|
||||
* @param options (optional) any array of options
|
||||
*/
|
||||
export function useLLMSelect(
|
||||
llmId: undefined | DLLMId | null, // undefined: not set at all, null: has the meaning of no-llm-wanted here
|
||||
@@ -78,6 +80,9 @@ export function useLLMSelect(
|
||||
options: LLMSelectOptions,
|
||||
): [DLLM | null, React.JSX.Element | null, React.FunctionComponent<SvgIconProps> | undefined] {
|
||||
|
||||
// state
|
||||
const [controlledOpen, setControlledOpen] = React.useState(false);
|
||||
|
||||
// external state
|
||||
const _filteredLLMs = useVisibleLLMs(llmId);
|
||||
|
||||
@@ -89,11 +94,17 @@ export function useLLMSelect(
|
||||
|
||||
|
||||
// memo LLM Options
|
||||
|
||||
const optimizeToSingleVisibleId = (!controlledOpen && _filteredLLMs.length > LLM_SELECT_REDUCE_OPTIONS) ? llmId : null; // id to keep visible when optimizing
|
||||
|
||||
const optionsArray = React.useMemo(() => {
|
||||
// create the option items
|
||||
let formerVendor: IModelVendor | null = null;
|
||||
return _filteredLLMs.reduce((acc, llm, _index) => {
|
||||
|
||||
if (optimizeToSingleVisibleId && llm.id !== optimizeToSingleVisibleId)
|
||||
return acc;
|
||||
|
||||
const vendor = findModelVendor(llm.vId);
|
||||
const vendorChanged = vendor !== formerVendor;
|
||||
if (vendorChanged)
|
||||
@@ -101,7 +112,7 @@ export function useLLMSelect(
|
||||
|
||||
// add separators if the vendor changed (and more than one vendor)
|
||||
const addSeparator = vendorChanged && formerVendor !== null;
|
||||
if (addSeparator)
|
||||
if (addSeparator && !optimizeToSingleVisibleId)
|
||||
acc.push(<ListDivider key={'llm-sep-' + llm.id}>{vendor?.name}</ListDivider>);
|
||||
|
||||
// the option component
|
||||
@@ -127,7 +138,7 @@ export function useLLMSelect(
|
||||
|
||||
return acc;
|
||||
}, [] as React.JSX.Element[]);
|
||||
}, [_filteredLLMs, noIcons]);
|
||||
}, [_filteredLLMs, noIcons, optimizeToSingleVisibleId]);
|
||||
|
||||
|
||||
const onSelectChange = React.useCallback((_event: unknown, value: DLLMId | null) => value && setLlmId(value), [setLlmId]);
|
||||
@@ -143,6 +154,8 @@ export function useLLMSelect(
|
||||
size={larger ? undefined : 'sm'}
|
||||
disabled={disabled}
|
||||
onChange={onSelectChange}
|
||||
listboxOpen={controlledOpen}
|
||||
onListboxOpenChange={setControlledOpen}
|
||||
placeholder={placeholder}
|
||||
slotProps={_slotProps}
|
||||
endDecorator={autoRefreshDomain ?
|
||||
@@ -158,7 +171,7 @@ export function useLLMSelect(
|
||||
</Select>
|
||||
{/*</Box>*/}
|
||||
</FormControl>
|
||||
), [autoRefreshDomain, disabled, isHorizontal, isReasoning, label, larger, llmId, onSelectChange, optionsArray, placeholder]);
|
||||
), [autoRefreshDomain, controlledOpen, disabled, isHorizontal, isReasoning, label, larger, llmId, onSelectChange, optionsArray, placeholder]);
|
||||
|
||||
// Memo the vendor icon for the chat LLM
|
||||
const chatLLMVendorIconFC = React.useMemo(() => {
|
||||
|
||||
Reference in New Issue
Block a user