1
0
Fork 0

Fix crash in settings, optimize models loading

This commit is contained in:
Pabloader 2026-04-16 07:33:22 +00:00
parent f4a8595dac
commit cc8f99084b
4 changed files with 14 additions and 28 deletions

View File

@ -119,7 +119,7 @@ export const ContentEditable = ({
ref={ref}
{...props}
contentEditable
data-placeholder={value.replaceAll('\n', '').length ? undefined : placeholder}
data-placeholder={value?.replaceAll('\n', '').length ? undefined : placeholder}
class={clsx(styles.root, autoLines && styles.autoLines, externalClass)}
onInput={handleInput}
/>

View File

@ -32,24 +32,19 @@ export const ConnectionSettings = () => {
const fetchModels = useMemo(() => async (conn: LLM.Connection | null) => {
if (!conn) return [];
const r = await LLM.getTextModels(conn);
return r.data;
}, []);
const fetchImageModels = useMemo(() => async (conn: LLM.Connection | null) => {
if (!conn) return [];
const r = await LLM.getImageModels(conn);
const r = await LLM.getModels(conn);
return r.data;
}, []);
const modelsData = useQuery(fetchModels, connectionToFetch);
const imageModelsData = useQuery(fetchImageModels, connectionToFetch);
const isLoadingModels = connectionToFetch != null && modelsData == undefined;
const textModelsData = useMemo(() => modelsData?.filter(LLM.isTextModel), [modelsData]);
const imageModelsData = useMemo(() => modelsData?.filter(LLM.isImageModel), [modelsData]);
const isLoadingModels = connectionToFetch != null && textModelsData == undefined;
const [modelFilter, setModelFilter] = useInputState("");
const groupedModels = useMemo(() => {
const sorted = (modelsData ?? []).sort((a, b) => {
const sorted = (textModelsData ?? []).sort((a, b) => {
const aWeight = Number(a.supported_parameters.includes('tools')) * 2 + Number(a.supported_parameters.includes('reasoning'));
const bWeight = Number(b.supported_parameters.includes('tools')) * 2 + Number(b.supported_parameters.includes('reasoning'));
if (aWeight !== bWeight) return bWeight - aWeight;
@ -60,7 +55,7 @@ export const ConnectionSettings = () => {
return Array.from(groups.entries())
.sort((a, b) => b[0] - a[0])
.map(([context, models]) => ({ context, models }));
}, [modelsData]);
}, [textModelsData]);
const filteredGroupedModels = useMemo(() => {
if (!modelFilter) return groupedModels;
@ -95,7 +90,7 @@ export const ConnectionSettings = () => {
const handleModelChange = (e: Event) => {
setSelectedModel(e);
const target = e.target as HTMLSelectElement;
const selectedModelInfo = modelsData?.find(m => m.id === target.value) ?? null;
const selectedModelInfo = textModelsData?.find(m => m.id === target.value) ?? null;
dispatch({ type: "SET_MODEL", model: selectedModelInfo });
};

View File

@ -105,7 +105,8 @@ export const ImageSettings = () => {
</div>
<div class={clsx(styles.formGroup, styles.formGroupFill)}>
<label class={styles.label}>Negative Prompt</label>
<ContentEditable
<textarea
rows={3}
value={negative_prompt}
onInput={setNegativePrompt}
placeholder="Things to avoid in generated images..."

View File

@ -189,8 +189,8 @@ namespace LLM {
export type ModelInfo = ModelInfoText | ModelInfoImage;
const isTextModel = (model: ModelInfo): model is ModelInfoText => ('context_length' in model);
const isImageModel = (model: ModelInfo): model is ModelInfoImage => Boolean(
export const isTextModel = (model: ModelInfo): model is ModelInfoText => ('context_length' in model);
export const isImageModel = (model: ModelInfo): model is ModelInfoImage => Boolean(
!isTextModel(model) &&
model.architecture &&
(model.architecture.output_modalities).includes('image')
@ -313,18 +313,8 @@ namespace LLM {
return e != null && typeof e === 'object' && 'data' in e && typeof e.data === 'string';
}
export async function getTextModels(connection: Connection): Promise<ModelsResponse<ModelInfoText>> {
const response = await request<ModelsResponse>(connection, '/v1/models');
response.data = response.data.filter(isTextModel);
return response as ModelsResponse<ModelInfoText>;
}
export async function getImageModels(connection: Connection): Promise<ModelsResponse<ModelInfoImage>> {
const response = await request<ModelsResponse>(connection, '/v1/models');
response.data = response.data.filter(isImageModel);
return response as ModelsResponse<ModelInfoImage>;
export async function getModels(connection: Connection): Promise<ModelsResponse<ModelInfo>> {
return request<ModelsResponse>(connection, '/v1/models');
}
export async function countTokens(connection: Connection, body: CountTokensRequest) {