mirror of
https://github.com/mudler/LocalAI.git
synced 2026-09-21 21:54:52 -04:00
* feat(chat): template.system_messages_after_first — merge or forward late system turns Tokenizer chat templates such as Qwen3.8 / Qwen3.8-Flash-Next raise 'System message must be at the beginning' for system-role messages that appear after the leading system block, while agent frameworks (cogito tool selection and adjustment prompts) legitimately append system instructions mid-conversation. Every such request failed with a 500 (48 errors in one 10-task agent run). New per-model option template.system_messages_after_first: merge fold late system turns into the leading system message user forward them as user-role turns at their original position Default (unset) keeps the current pass-through behaviour. Fixes #11876 Assisted-by: Claude:claude-fable-5-1 Signed-off-by: Stefan Walcz <stefan.walcz@walcz.de> * docs(model-config): document template.system_messages_after_first Assisted-by: Claude:claude-fable-5-1 Signed-off-by: Stefan Walcz <stefan.walcz@walcz.de> * fix(config/meta): register template.system_messages_after_first in the field registry TestAllFieldsHaveRegistryEntries requires every model-config field to have a registry entry. Adds the entry (templates section, select component) and the option list for the new field so the coverage gate passes. Assisted-by: Claude:claude-fable-5-1 Signed-off-by: Stefan Walcz <stefan.walcz@walcz.de> --------- Signed-off-by: Stefan Walcz <stefan.walcz@walcz.de>
111 lines
4.2 KiB
Go
111 lines
4.2 KiB
Go
package meta
|
|
|
|
// Dynamic autocomplete provider constants (runtime lookup required).
|
|
const (
|
|
ProviderBackends = "backends"
|
|
ProviderModels = "models"
|
|
ProviderModelsChat = "models:chat"
|
|
ProviderModelsTTS = "models:tts"
|
|
ProviderModelsTranscript = "models:transcript"
|
|
ProviderModelsVAD = "models:vad"
|
|
ProviderModelsScore = "models:score"
|
|
)
|
|
|
|
// Static option lists embedded directly in field metadata.
|
|
|
|
var QuantizationOptions = []FieldOption{
|
|
{Value: "q4_0", Label: "Q4_0"},
|
|
{Value: "q4_1", Label: "Q4_1"},
|
|
{Value: "q5_0", Label: "Q5_0"},
|
|
{Value: "q5_1", Label: "Q5_1"},
|
|
{Value: "q8_0", Label: "Q8_0"},
|
|
{Value: "q2_K", Label: "Q2_K"},
|
|
{Value: "q3_K_S", Label: "Q3_K_S"},
|
|
{Value: "q3_K_M", Label: "Q3_K_M"},
|
|
{Value: "q3_K_L", Label: "Q3_K_L"},
|
|
{Value: "q4_K_S", Label: "Q4_K_S"},
|
|
{Value: "q4_K_M", Label: "Q4_K_M"},
|
|
{Value: "q5_K_S", Label: "Q5_K_S"},
|
|
{Value: "q5_K_M", Label: "Q5_K_M"},
|
|
{Value: "q6_K", Label: "Q6_K"},
|
|
}
|
|
|
|
var CacheTypeOptions = []FieldOption{
|
|
{Value: "f16", Label: "F16"},
|
|
{Value: "f32", Label: "F32"},
|
|
{Value: "q8_0", Label: "Q8_0"},
|
|
{Value: "q4_0", Label: "Q4_0"},
|
|
{Value: "q4_1", Label: "Q4_1"},
|
|
{Value: "q5_0", Label: "Q5_0"},
|
|
{Value: "q5_1", Label: "Q5_1"},
|
|
}
|
|
|
|
var DiffusersPipelineOptions = []FieldOption{
|
|
{Value: "StableDiffusionPipeline", Label: "StableDiffusionPipeline"},
|
|
{Value: "StableDiffusionImg2ImgPipeline", Label: "StableDiffusionImg2ImgPipeline"},
|
|
{Value: "StableDiffusionXLPipeline", Label: "StableDiffusionXLPipeline"},
|
|
{Value: "StableDiffusionXLImg2ImgPipeline", Label: "StableDiffusionXLImg2ImgPipeline"},
|
|
{Value: "StableDiffusionDepth2ImgPipeline", Label: "StableDiffusionDepth2ImgPipeline"},
|
|
{Value: "DiffusionPipeline", Label: "DiffusionPipeline"},
|
|
{Value: "StableVideoDiffusionPipeline", Label: "StableVideoDiffusionPipeline"},
|
|
}
|
|
|
|
// UsecaseOptions must stay in sync with GetAllModelConfigUsecases in
|
|
// core/config/model_config.go — a value missing here is silently
|
|
// inaccessible from the model editor, which is how `score` (the router
|
|
// classifier usecase) hid for an entire release.
|
|
var UsecaseOptions = []FieldOption{
|
|
{Value: "chat", Label: "Chat"},
|
|
{Value: "completion", Label: "Completion"},
|
|
{Value: "edit", Label: "Edit"},
|
|
{Value: "embeddings", Label: "Embeddings"},
|
|
{Value: "rerank", Label: "Rerank"},
|
|
{Value: "score", Label: "Score (Router Classifier)"},
|
|
{Value: "image", Label: "Image"},
|
|
{Value: "vision", Label: "Vision"},
|
|
{Value: "detection", Label: "Detection"},
|
|
{Value: "depth", Label: "Depth"},
|
|
{Value: "face_recognition", Label: "Face Recognition"},
|
|
{Value: "transcript", Label: "Transcript"},
|
|
{Value: "diarization", Label: "Diarization"},
|
|
{Value: "sound_classification", Label: "Sound Classification"},
|
|
{Value: "speaker_recognition", Label: "Speaker Recognition"},
|
|
{Value: "tts", Label: "TTS"},
|
|
{Value: "sound_generation", Label: "Sound Generation"},
|
|
{Value: "audio_transform", Label: "Audio Transform"},
|
|
{Value: "realtime_audio", Label: "Realtime Audio"},
|
|
{Value: "tokenize", Label: "Tokenize"},
|
|
{Value: "vad", Label: "VAD"},
|
|
{Value: "video", Label: "Video"},
|
|
}
|
|
|
|
// ModalityOptions enumerates the values accepted by known modality fields.
|
|
var ModalityOptions = []FieldOption{
|
|
{Value: "text", Label: "Text"},
|
|
{Value: "image", Label: "Image"},
|
|
{Value: "audio", Label: "Audio"},
|
|
{Value: "video", Label: "Video"},
|
|
}
|
|
|
|
var DiffusersSchedulerOptions = []FieldOption{
|
|
{Value: "ddim", Label: "DDIM"},
|
|
{Value: "ddpm", Label: "DDPM"},
|
|
{Value: "pndm", Label: "PNDM"},
|
|
{Value: "lms", Label: "LMS"},
|
|
{Value: "euler", Label: "Euler"},
|
|
{Value: "euler_a", Label: "Euler A"},
|
|
{Value: "dpm_multistep", Label: "DPM Multistep"},
|
|
{Value: "dpm_singlestep", Label: "DPM Singlestep"},
|
|
{Value: "heun", Label: "Heun"},
|
|
{Value: "unipc", Label: "UniPC"},
|
|
}
|
|
|
|
// SystemMessagesAfterFirstOptions are the values of template.system_messages_after_first:
|
|
// how system messages that appear after the first turn are handled before the chat
|
|
// template runs (empty = pass through unchanged, which strict Jinja templates reject).
|
|
var SystemMessagesAfterFirstOptions = []FieldOption{
|
|
{Value: "", Label: "Pass through (default)"},
|
|
{Value: "merge", Label: "Merge into the first system message"},
|
|
{Value: "user", Label: "Forward as user messages"},
|
|
}
|