# config.nim # Module de gestion de la configuration import std/[json, os, strutils, strformat] type LLMModelConfig* = object name*: string systemRole*: string systemContent*: string userRole*: string userContentTemplate*: string isActive*: bool AppConfig* = object apiUrl*: string apiMonitorUrl*: string models*: seq[LLMModelConfig] activeModelName*: string debugModeActive*: bool proc getActiveModel*(config: AppConfig): LLMModelConfig = ## Retourne le modèle actif de la configuration # D'abord essayer de trouver le modèle correspondant au activeModelName for model in config.models: if model.name == config.activeModelName: echo fmt"Utilisation du modèle spécifié dans activeModelName: {model.name}" return model # Si le modèle actif n'est pas trouvé par nom, chercher un modèle avec isActive=true for model in config.models: if model.isActive: echo fmt"Utilisation du premier modèle marqué comme actif: {model.name}" return model # Si aucun modèle actif n'est trouvé, retourner le premier modèle disponible if config.models.len > 0: echo fmt"Aucun modèle actif trouvé, utilisation du premier modèle disponible: {config.models[0].name}" return config.models[0] # Si aucun modèle n'est configuré, retourner une configuration par défaut echo "Aucun modèle configuré, utilisation de la configuration par défaut" result = LLMModelConfig( name: "default", systemRole: "system", systemContent: "Vous êtes un assistant spécialisé dans l'analyse de contenu Markdown. Vous devez extraire ou générer le titre, la description et les tags pertinents pour le document, et les retourner dans un format YAML.", userRole: "user", userContentTemplate: """Analysez ce document Markdown et générez un titre, une description concise et des tags pertinents. Répondez UNIQUEMENT avec un bloc YAML qui commence et finit par '---', inscrire 5 à 10 tags, et contenant: - title: un titre pertinent - description: une description concise - tags: une liste de mots-clés pertinents (avec tirets) Document à analyser: {content}""", isActive: true ) proc defaultConfig*(): AppConfig = ## Crée une configuration par défaut result = AppConfig( apiUrl: "http://192.168.20.163:2222/v1/chat/completions", apiMonitorUrl: "http://192.168.20.163:2222/v1/models", activeModelName: "gemma-3-4b-it", debugModeActive: false ) # Ajouter le modèle gemma par défaut result.models.add(LLMModelConfig( name: "gemma-3-4b-it", systemRole: "system", systemContent: "Vous êtes un assistant spécialisé dans l'analyse de contenu Markdown. Vous devez extraire ou générer le titre, la description et les tags pertinents pour le document, et les retourner dans un format YAML.", userRole: "user", userContentTemplate: """Analysez ce document Markdown et générez un titre, une description concise et des tags pertinents. Répondez UNIQUEMENT avec un bloc YAML qui commence et finit par '---', inscrire 5 à 10 tags, et contenant: - title: un titre pertinent - description: une description concise - tags: une liste de mots-clés pertinents (avec tirets) Document à analyser: {content}""", isActive: true )) proc loadConfig*(configFilePath: string): AppConfig = ## Charge la configuration depuis un fichier JSON ## Si le fichier n'existe pas, crée une configuration par défaut if not fileExists(configFilePath): result = defaultConfig() return try: let jsonNode = parseFile(configFilePath) # Initialiser result avec une configuration vide result = AppConfig() # Charger l'URL de l'API if jsonNode.hasKey("apiUrl"): result.apiUrl = jsonNode["apiUrl"].getStr() else: result.apiUrl = "http://192.168.20.163:2222/v1/chat/completions" # Charger l'URL de vérification des modèles if jsonNode.hasKey("apiMonitorUrl"): result.apiMonitorUrl = jsonNode["apiMonitorUrl"].getStr() else: result.apiMonitorUrl = "http://192.168.20.163:2222/v1/models" # Charger le modèle actif if jsonNode.hasKey("activeModelName"): result.activeModelName = jsonNode["activeModelName"].getStr() # Charger l'option de mode debug if jsonNode.hasKey("debugModeActive"): result.debugModeActive = jsonNode["debugModeActive"].getBool() else: result.debugModeActive = false # Charger les modèles if jsonNode.hasKey("models") and jsonNode["models"].kind == JArray: for modelNode in jsonNode["models"]: var model = LLMModelConfig() if modelNode.hasKey("name"): model.name = modelNode["name"].getStr() if modelNode.hasKey("systemRole"): model.systemRole = modelNode["systemRole"].getStr() if modelNode.hasKey("systemContent"): model.systemContent = modelNode["systemContent"].getStr() if modelNode.hasKey("userRole"): model.userRole = modelNode["userRole"].getStr() if modelNode.hasKey("userContentTemplate"): model.userContentTemplate = modelNode["userContentTemplate"].getStr() if modelNode.hasKey("isActive"): model.isActive = modelNode["isActive"].getBool() if model.isActive and result.activeModelName == "": result.activeModelName = model.name result.models.add(model) except: echo "Erreur lors du chargement de la configuration, utilisation des valeurs par défaut" result = defaultConfig() # Si aucun modèle n'est présent, ajouter le modèle par défaut if result.models.len == 0: result = defaultConfig() # Vérifier que le modèle actif existe var modelExists = false for model in result.models: if model.name == result.activeModelName: modelExists = true break # Si le modèle actif n'existe pas, définir le premier modèle comme actif if not modelExists and result.models.len > 0: result.activeModelName = result.models[0].name proc saveConfig*(config: AppConfig, configFilePath: string): bool = ## Sauvegarde la configuration dans un fichier JSON try: var jsonNode = %* { "apiUrl": config.apiUrl, "apiMonitorUrl": config.apiMonitorUrl, "activeModelName": config.activeModelName, "debugModeActive": config.debugModeActive, "models": [] } for model in config.models: jsonNode["models"].add(%* { "name": model.name, "systemRole": model.systemRole, "systemContent": model.systemContent, "userRole": model.userRole, "userContentTemplate": model.userContentTemplate, "isActive": model.name == config.activeModelName }) # Créer le répertoire si nécessaire let configDir = configFilePath.splitPath().head if not dirExists(configDir): createDir(configDir) writeFile(configFilePath, pretty(jsonNode)) return true except: echo "Erreur lors de la sauvegarde de la configuration" return false proc formatUserContent*(model: LLMModelConfig, content: string): string = ## Formate le contenu utilisateur en remplaçant la variable {content} return model.userContentTemplate.replace("{content}", content) # Variable globale pour contrôler le mode debug var globalDebugMode* = false proc setGlobalDebugMode*(mode: bool) = ## Définit le mode debug global globalDebugMode = mode proc debugLog*(config: AppConfig, message: string) = ## Affiche un message de debug uniquement si le mode debug est activé if config.debugModeActive: echo fmt"[DEBUG] {message}" proc debugLog*(message: string) = ## Affiche un message de debug uniquement si le mode debug global est activé if globalDebugMode: echo fmt"[DEBUG] {message}"