Project Files
src / config.ts
import {createConfigSchematics} from "@lmstudio/sdk";
import {setLanguage, t, type SupportedLanguage} from "./i18n";
/**
* Language code to display text mapping
* Centralized configuration for language options
*/
const LANGUAGE_OPTIONS: Record<SupportedLanguage, string> = {
"en": "English (en)",
"zh-TW": "繁體中文 (zh-TW)",
"ja": "日本語 (ja)"
};
/**
* Default embedding models
* Ordered by speed (fast to slow)
*/
export const DEFAULT_EMBEDDING_MODELS = [
"nomic-ai/nomic-embed-text-v1.5-GGUF", // Built-in, fast, English
"NathanMad/sentence-transformers_all-MiniLM-L12-v2-gguf", // Lightweight
"groonga/gte-large-Q4_K_M-GGUF", // Balanced
"lm-kit/bge-m3-gguf" // Multilingual, Chinese support
];
/**
* Get display text for a language code
*/
export function getLanguageDisplayText(langCode: SupportedLanguage): string {
return LANGUAGE_OPTIONS[langCode];
}
/**
* Get all language options as an array
*/
export function getLanguageOptions(): string[] {
return Object.values(LANGUAGE_OPTIONS);
}
/**
* Map display text to language code
* Handles the conversion from user-friendly display text to internal language codes
*/
export function parseLanguageFromDisplay(displayValue: string): SupportedLanguage {
// Find the language code by matching display text
for (const [code, display] of Object.entries(LANGUAGE_OPTIONS)) {
if (displayValue === display) {
return code as SupportedLanguage;
}
}
// Legacy fallback: parse from parentheses (e.g., "English (en)" -> "en")
const match = displayValue.match(/\(([^)]+)\)/);
if (match) {
const code = match[1] as SupportedLanguage;
if (code in LANGUAGE_OPTIONS) {
return code;
}
}
// Fallback to English if parsing fails
return "en";
}
export const createDynamicConfig = (modelChoices: string[], systemLanguage: SupportedLanguage) => {
// Use system language for config UI
setLanguage(systemLanguage);
const translations = t();
const safeChoices = (Array.isArray(modelChoices) && modelChoices.length > 0)
? modelChoices
: DEFAULT_EMBEDDING_MODELS;
return createConfigSchematics()
.field(
"language",
"select",
{
displayName: translations.config.messageLanguage.displayName,
subtitle: translations.config.messageLanguage.subtitle,
options: getLanguageOptions(),
},
getLanguageDisplayText(systemLanguage),
)
.field(
"embeddingModelPath",
"select",
{
displayName: translations.config.embeddingModel.displayName,
subtitle: translations.config.embeddingModel.subtitle,
options: safeChoices,
},
safeChoices[0],
)
.field(
"customEmbeddingModelPath",
"string",
{
displayName: translations.config.customEmbeddingModel.displayName,
subtitle: translations.config.customEmbeddingModel.subtitle,
},
"",
)
.field(
"contextUsageThreshold",
"numeric",
{
min: 0.1,
max: 1.0,
displayName: translations.config.contextThreshold.displayName,
subtitle: translations.config.contextThreshold.subtitle,
slider: {min: 0.1, max: 1.0, step: 0.05},
},
0.7,
)
.field(
"retrievalLimit",
"numeric",
{
int: true,
min: 1,
displayName: translations.config.retrievalLimit.displayName,
subtitle: translations.config.retrievalLimit.subtitle,
slider: {min: 1, max: 15, step: 1},
},
5,
)
.field(
"retrievalAffinityThreshold",
"numeric",
{
min: 0.0,
max: 1.0,
displayName: translations.config.affinityThreshold.displayName,
subtitle: translations.config.affinityThreshold.subtitle,
slider: {min: 0.0, max: 1.0, step: 0.01},
},
0.4,
)
.field(
"enableDebugLogging",
"boolean",
{
displayName: translations.config.enableDebugLogging.displayName,
subtitle: translations.config.enableDebugLogging.subtitle,
},
false,
)
.field(
"debugLogPath",
"string",
{
displayName: translations.config.debugLogPath.displayName,
subtitle: translations.config.debugLogPath.subtitle,
},
"./logs/lmstudio-debug.log",
)
.build();
};
export const CONFIG_KEYS = {
LANGUAGE: "language",
MODEL_PATH: "embeddingModelPath",
CUSTOM_MODEL_PATH: "customEmbeddingModelPath",
CONTEXT_THRESHOLD: "contextUsageThreshold",
LIMIT: "retrievalLimit",
THRESHOLD: "retrievalAffinityThreshold",
ENABLE_DEBUG: "enableDebugLogging",
DEBUG_LOG_PATH: "debugLogPath",
} as const;