From 026b21f7798d41716cf2ecf0be503c93f182dacd Mon Sep 17 00:00:00 2001 From: Faisal Amir Date: Tue, 5 Aug 2025 21:21:41 +0700 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8feat:=20jinja=20template=20customize?= =?UTF-8?q?=20per=20model=20instead=20provider=20level=20(#6053)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- extensions/llamacpp-extension/settings.json | 12 ----- web-app/src/containers/ModelSetting.tsx | 10 +++- web-app/src/hooks/useModelProvider.ts | 54 +++++++++++++++++++-- web-app/src/lib/predefined.ts | 14 +++++- 4 files changed, 71 insertions(+), 19 deletions(-) diff --git a/extensions/llamacpp-extension/settings.json b/extensions/llamacpp-extension/settings.json index 363822f9a..46c4995ff 100644 --- a/extensions/llamacpp-extension/settings.json +++ b/extensions/llamacpp-extension/settings.json @@ -25,18 +25,6 @@ "controllerType": "checkbox", "controllerProps": { "value": true } }, - { - "key": "chat_template", - "title": "Custom Jinja Chat template", - "description": "Custom Jinja chat_template to be used for the model", - "controllerType": "input", - "controllerProps": { - "value": "", - "placeholder": "e.g., {% for message in messages %}...{% endfor %} (default is read from GGUF)", - "type": "text", - "textAlign": "right" - } - }, { "key": "threads", "title": "Threads", diff --git a/web-app/src/containers/ModelSetting.tsx b/web-app/src/containers/ModelSetting.tsx index d54e406b2..9d8406801 100644 --- a/web-app/src/containers/ModelSetting.tsx +++ b/web-app/src/containers/ModelSetting.tsx @@ -71,7 +71,7 @@ export function ModelSetting({ }) // Call debounced stopModel only when updating ctx_len or ngl - if (key === 'ctx_len' || key === 'ngl') { + if (key === 'ctx_len' || key === 'ngl' || key === 'chat_template') { debouncedStopModel(model.id) } } @@ -101,9 +101,15 @@ export function ModelSetting({
{Object.entries(model.settings || {}).map(([key, value]) => { const config = value as ProviderSetting + return (
-
+

{config.title}

diff --git a/web-app/src/hooks/useModelProvider.ts b/web-app/src/hooks/useModelProvider.ts index bfcb4e3a5..e6c1ae74c 100644 --- a/web-app/src/hooks/useModelProvider.ts +++ b/web-app/src/hooks/useModelProvider.ts @@ -2,6 +2,7 @@ import { create } from 'zustand' import { persist, createJSONStorage } from 'zustand/middleware' import { localStorageKey } from '@/constants/localStorage' import { sep } from '@tauri-apps/api/path' +import { modelSettings } from '@/lib/predefined' type ModelProviderState = { providers: ModelProvider[] @@ -211,8 +212,21 @@ export const useModelProvider = create()( name: localStorageKey.modelProvider, storage: createJSONStorage(() => localStorage), migrate: (persistedState: unknown, version: number) => { - const state = persistedState as ModelProviderState - + const state = persistedState as ModelProviderState & { + providers: Array< + ModelProvider & { + models: Array< + Model & { + settings?: Record & { + chatTemplate?: string + chat_template?: string + } + } + > + } + > + } + // Migration for cont_batching description update (version 0 -> 1) if (version === 0 && state?.providers) { state.providers = state.providers.map((provider) => { @@ -221,7 +235,8 @@ export const useModelProvider = create()( if (setting.key === 'cont_batching') { return { ...setting, - description: 'Enable continuous batching (a.k.a dynamic batching) for concurrent requests.' + description: + 'Enable continuous batching (a.k.a dynamic batching) for concurrent requests.', } } return setting @@ -230,9 +245,40 @@ export const useModelProvider = create()( return provider }) } + + // Migration for chatTemplate key to chat_template (version 1 -> 2) + if (version === 1 && state?.providers) { + state.providers.forEach((provider) => { + if (provider.models) { + provider.models.forEach((model) => { + // Initialize settings if it doesn't exist + if (!model.settings) { + model.settings = {} + } + + // Migrate chatTemplate key to chat_template + if (model.settings.chatTemplate) { + model.settings.chat_template = model.settings.chatTemplate + delete model.settings.chatTemplate + } + + // Add missing chat_template setting if it doesn't exist + if (!model.settings.chat_template) { + model.settings.chat_template = { + ...modelSettings.chatTemplate, + controller_props: { + ...modelSettings.chatTemplate.controller_props, + }, + } + } + }) + } + }) + } + return state }, - version: 1, + version: 2, } ) ) diff --git a/web-app/src/lib/predefined.ts b/web-app/src/lib/predefined.ts index a87493722..1d73fbacc 100644 --- a/web-app/src/lib/predefined.ts +++ b/web-app/src/lib/predefined.ts @@ -22,7 +22,6 @@ export const modelSettings = { type: 'number', }, }, - temperature: { key: 'temperature', title: 'Temperature', @@ -121,4 +120,17 @@ export const modelSettings = { type: 'number', }, }, + chatTemplate: { + key: 'chat_template', + title: 'Custom Jinja Chat template', + description: 'Custom Jinja chat_template to be used for the model', + controller_type: 'textarea', + controller_props: { + value: '', + placeholder: + 'e.g., {% for message in messages %}...{% endfor %} (default is read from GGUF)', + type: 'text', + textAlign: 'right', + }, + }, }