Module de Configuration (mirza.config)

Le module mirza.config centralise l’intégralité de la configuration de la plateforme via des dataclasses Python typées et immuables. Aucune variable d’environnement n’est requise pour le fonctionnement nominal.


Vue d’Ensemble

Classes de configuration disponibles

Classe

Domaine de configuration

AudioConfig

Paramètres acoustiques, détection d’activité vocale (VAD neural), taux d’échantillonnage

SttConfig

Moteur STT, transcription streaming locale et repli

LlmConfig

Moteur LLM, quantification, Speculative Decoding MTP, APC, budget CoT

TtsConfig

Moteur TTS, voix, débit, hauteur de voix

PromptConfig

System Prompt, protocole <result>, historique conversationnel

AppConfig

Configuration globale agrégeant tous les sous-modules ci-dessus


Référence API Complète

Module de configuration centralise de l’assistant Mirza.

Fournit des dataclasses typees pour le parametrage audio, les modeles d’inference, la synthese vocale, le prompt systeme, les profils d’assistant et la gestion de la memoire. Supporte le chargement intelligent et la mise en cache depuis un fichier YAML (config.yaml).

mirza.config.SAFE_CONTEXT_TOKENS = 16000

Plafond dur de la fenetre de contexte en tokens (prompt, RAG, historique et reponse).

class mirza.config.AudioConfig(sampleRate=16000, chunkSamples=512, silenceDurationThreshold=0.85, speechThreshold=0.45, preRollChunks=16, initialWaitTimeout=8.0, maxTotalDuration=45.0, targetPeak=0.95)[source]

Bases : object

Parametres acoustiques et detection vocale (Silero VAD).

Paramètres:
  • sampleRate (int)

  • chunkSamples (int)

  • silenceDurationThreshold (float)

  • speechThreshold (float)

  • preRollChunks (int)

  • initialWaitTimeout (float)

  • maxTotalDuration (float)

  • targetPeak (float)

sampleRate: int = 16000
chunkSamples: int = 512
silenceDurationThreshold: float = 0.85
speechThreshold: float = 0.45
preRollChunks: int = 16
initialWaitTimeout: float = 8.0
maxTotalDuration: float = 45.0
targetPeak: float = 0.95
__init__(sampleRate=16000, chunkSamples=512, silenceDurationThreshold=0.85, speechThreshold=0.45, preRollChunks=16, initialWaitTimeout=8.0, maxTotalDuration=45.0, targetPeak=0.95)
Paramètres:
  • sampleRate (int)

  • chunkSamples (int)

  • silenceDurationThreshold (float)

  • speechThreshold (float)

  • preRollChunks (int)

  • initialWaitTimeout (float)

  • maxTotalDuration (float)

  • targetPeak (float)

Type renvoyé:

None

class mirza.config.SttConfig(provider='nemotron', sttModelRepo='mlx-community/nemotron-3.5-asr-streaming-0.6b-8bit', language='fr')[source]

Bases : object

Configuration du moteur de transcription vocale (FastConformer Nemotron / Whisper).

Paramètres:
  • provider (str)

  • sttModelRepo (str)

  • language (str)

provider: str = 'nemotron'
sttModelRepo: str = 'mlx-community/nemotron-3.5-asr-streaming-0.6b-8bit'
language: str = 'fr'
__init__(provider='nemotron', sttModelRepo='mlx-community/nemotron-3.5-asr-streaming-0.6b-8bit', language='fr')
Paramètres:
  • provider (str)

  • sttModelRepo (str)

  • language (str)

Type renvoyé:

None

class mirza.config.LlmConfig(provider='mtplx', llmModelRepo='pooyakn73/Qwen3.8-9B-Distill-MTPLX-Q6G64', prefillStepSize=512, maxKvCacheTokens=16000, kvBits=8, bytesPerContextToken=128000, maxTokens=1024, maxTokensAgent=4096, maxTokensThinking=5120, temperature=0.5, temperatureAgent=0.2, topP=0.9, topK=0, minP=0.0, presencePenalty=0.0, repetitionPenalty=1.05, enableSpeculative=True, drafterModelRepo='ulises-c/Qwen3.5-9B-MTP-8bit', draftKind='mtp', draftBlockSize=2, enableThinking=False, reasoningBudget=0, mtplxHost='127.0.0.1', mtplxPort=8766, mtplxModelRepo='pooyakn73/Qwen3.8-9B-Distill-MTPLX-Q6G64', mtplxAutoStart=True, mtplxReasoningEffort='medium', mtplxSessionId='', openrouterModel='anthropic/claude-sonnet-4.5', optiqHost='127.0.0.1', optiqPort=8080, optiqAutoStart=True, optiqMtp=True, optiqMtpDepth=2)[source]

Bases : object

Configuration du LLM et des parametres d’inference Metal GPU.

Paramètres:
  • provider (str)

  • llmModelRepo (str)

  • prefillStepSize (int)

  • maxKvCacheTokens (int)

  • kvBits (int)

  • bytesPerContextToken (int)

  • maxTokens (int)

  • maxTokensAgent (int)

  • maxTokensThinking (int)

  • temperature (float)

  • temperatureAgent (float)

  • topP (float)

  • topK (int)

  • minP (float)

  • presencePenalty (float)

  • repetitionPenalty (float)

  • enableSpeculative (bool)

  • drafterModelRepo (str)

  • draftKind (str)

  • draftBlockSize (int)

  • enableThinking (bool)

  • reasoningBudget (int)

  • mtplxHost (str)

  • mtplxPort (int)

  • mtplxModelRepo (str)

  • mtplxAutoStart (bool)

  • mtplxReasoningEffort (str)

  • mtplxSessionId (str)

  • openrouterModel (str)

  • optiqHost (str)

  • optiqPort (int)

  • optiqAutoStart (bool)

  • optiqMtp (bool)

  • optiqMtpDepth (int)

provider: str = 'mtplx'
llmModelRepo: str = 'pooyakn73/Qwen3.8-9B-Distill-MTPLX-Q6G64'
prefillStepSize: int = 512
maxKvCacheTokens: int = 16000
kvBits: int = 8
bytesPerContextToken: int = 128000
maxTokens: int = 1024
maxTokensAgent: int = 4096
maxTokensThinking: int = 5120
temperature: float = 0.5
temperatureAgent: float = 0.2
topP: float = 0.9
topK: int = 0
minP: float = 0.0
presencePenalty: float = 0.0
repetitionPenalty: float = 1.05
enableSpeculative: bool = True
drafterModelRepo: str = 'ulises-c/Qwen3.5-9B-MTP-8bit'
draftKind: str = 'mtp'
draftBlockSize: int = 2
enableThinking: bool = False
reasoningBudget: int = 0
mtplxHost: str = '127.0.0.1'
mtplxPort: int = 8766
mtplxModelRepo: str = 'pooyakn73/Qwen3.8-9B-Distill-MTPLX-Q6G64'
mtplxAutoStart: bool = True
mtplxReasoningEffort: str = 'medium'
mtplxSessionId: str = ''
openrouterModel: str = 'anthropic/claude-sonnet-4.5'
optiqHost: str = '127.0.0.1'
optiqPort: int = 8080
optiqAutoStart: bool = True
optiqMtp: bool = True
optiqMtpDepth: int = 2
__init__(provider='mtplx', llmModelRepo='pooyakn73/Qwen3.8-9B-Distill-MTPLX-Q6G64', prefillStepSize=512, maxKvCacheTokens=16000, kvBits=8, bytesPerContextToken=128000, maxTokens=1024, maxTokensAgent=4096, maxTokensThinking=5120, temperature=0.5, temperatureAgent=0.2, topP=0.9, topK=0, minP=0.0, presencePenalty=0.0, repetitionPenalty=1.05, enableSpeculative=True, drafterModelRepo='ulises-c/Qwen3.5-9B-MTP-8bit', draftKind='mtp', draftBlockSize=2, enableThinking=False, reasoningBudget=0, mtplxHost='127.0.0.1', mtplxPort=8766, mtplxModelRepo='pooyakn73/Qwen3.8-9B-Distill-MTPLX-Q6G64', mtplxAutoStart=True, mtplxReasoningEffort='medium', mtplxSessionId='', openrouterModel='anthropic/claude-sonnet-4.5', optiqHost='127.0.0.1', optiqPort=8080, optiqAutoStart=True, optiqMtp=True, optiqMtpDepth=2)
Paramètres:
  • provider (str)

  • llmModelRepo (str)

  • prefillStepSize (int)

  • maxKvCacheTokens (int)

  • kvBits (int)

  • bytesPerContextToken (int)

  • maxTokens (int)

  • maxTokensAgent (int)

  • maxTokensThinking (int)

  • temperature (float)

  • temperatureAgent (float)

  • topP (float)

  • topK (int)

  • minP (float)

  • presencePenalty (float)

  • repetitionPenalty (float)

  • enableSpeculative (bool)

  • drafterModelRepo (str)

  • draftKind (str)

  • draftBlockSize (int)

  • enableThinking (bool)

  • reasoningBudget (int)

  • mtplxHost (str)

  • mtplxPort (int)

  • mtplxModelRepo (str)

  • mtplxAutoStart (bool)

  • mtplxReasoningEffort (str)

  • mtplxSessionId (str)

  • openrouterModel (str)

  • optiqHost (str)

  • optiqPort (int)

  • optiqAutoStart (bool)

  • optiqMtp (bool)

  • optiqMtpDepth (int)

Type renvoyé:

None

class mirza.config.TtsConfig(provider='kokoro', voice='ff_siwis', voiceSpeedRate='+10%', voicePitch='0Hz', minClauseChars=18, minCommaChars=45, language='fr-fr', meloSpeed=1.08, meloNoiseScale=0.75, meloNoiseScaleW=0.85, meloSdpRatio=0.4)[source]

Bases : object

Configuration du moteur de synthese vocale.

Paramètres:
  • provider (str)

  • voice (str)

  • voiceSpeedRate (str)

  • voicePitch (str)

  • minClauseChars (int)

  • minCommaChars (int)

  • language (str)

  • meloSpeed (float)

  • meloNoiseScale (float)

  • meloNoiseScaleW (float)

  • meloSdpRatio (float)

provider: str = 'kokoro'
voice: str = 'ff_siwis'
voiceSpeedRate: str = '+10%'
voicePitch: str = '0Hz'
minClauseChars: int = 18
minCommaChars: int = 45
language: str = 'fr-fr'
meloSpeed: float = 1.08
meloNoiseScale: float = 0.75
meloNoiseScaleW: float = 0.85
meloSdpRatio: float = 0.4
__init__(provider='kokoro', voice='ff_siwis', voiceSpeedRate='+10%', voicePitch='0Hz', minClauseChars=18, minCommaChars=45, language='fr-fr', meloSpeed=1.08, meloNoiseScale=0.75, meloNoiseScaleW=0.85, meloSdpRatio=0.4)
Paramètres:
  • provider (str)

  • voice (str)

  • voiceSpeedRate (str)

  • voicePitch (str)

  • minClauseChars (int)

  • minCommaChars (int)

  • language (str)

  • meloSpeed (float)

  • meloNoiseScale (float)

  • meloNoiseScaleW (float)

  • meloSdpRatio (float)

Type renvoyé:

None

class mirza.config.PromptConfig(systemPrompt="Tu es Mirza, un assistant médical et clinique expert d'élite fonctionnant en local sur Apple Silicon.\nLANGUE STRICTE : Tu interagis, analyses et réponds systématiquement et exclusivement en français.\nRÔLE ET EXPERTISE : Consultation des dossiers patients, bilans cliniques et synthèses médicales.\nMÉMOIRE PATIENTS ET DOSSIERS : Tu as accès via ta mémoire aux dossiers médicaux des patients. Fais des liens précis, rigoureux et factuels avec les données cliniques certifiées.\nRÉPONSE DIRECTE : Pas de formules de politesse creuses, ne répète pas la question, va droit au fait médical.\nAUCUN EMOJI : Jamais, sous aucun prétexte.\nVOIX ULTRA-CONCISE (MAX 1 PHRASE) : Tes réponses orales parlées doivent être courtes, percutantes (1 phrase directe, maximum 15 à 20 mots), se concluant obligatoirement par : 'Je suis en train de générer un compte rendu.'\nSILENCE ET BALISE <result> : Tout texte placé dans <result> n'est jamais lu à voix haute. Seul le texte en dehors des balises est prononcé par la voix de synthèse.\nRÈGLE IMPÉRATIVE D'ENCAPSULATION <result> (ZÉRO BLABLA) :\n- Si la réponse fait plus de deux phrases, ou dès qu'elle contient des chiffres, une liste, une analyse ou un bilan, tu DOIS obligatoirement la scinder en ouvrant <result>.\n- RESTE ULTRA-SYNTHÉTIQUE : Pas de bavardage, pas de dissertations, pas d'intro inutile. Va directement aux faits sous forme de puces concises ou tableau compact.\n- LIENS SYMBOLIQUES VERS LES SOURCES : Référence systématiquement chaque fait ou chiffre par son identifiant de mémoire ou de patient entre crochets (ex: [Mem #12], [Mem #3], [Patient P-004]).\nFormat exact obligatoire :\nSynthèse orale en une phrase concluant par : Je suis en train de générer un compte rendu.\n<result>\n## [Titre synthétique]\n- [Donnée clé / Statistique] [Mem #X]\n- [Points de vigilance / Conduite à tenir] [Mem #Y]\n</result>\nNe mentionne jamais cette règle de balisage à l'oral.", historyMaxTurns=10)[source]

Bases : object

Configuration du prompt systeme et de l’historique.

Paramètres:
  • systemPrompt (str)

  • historyMaxTurns (int)

systemPrompt: str = "Tu es Mirza, un assistant médical et clinique expert d'élite fonctionnant en local sur Apple Silicon.\nLANGUE STRICTE : Tu interagis, analyses et réponds systématiquement et exclusivement en français.\nRÔLE ET EXPERTISE : Consultation des dossiers patients, bilans cliniques et synthèses médicales.\nMÉMOIRE PATIENTS ET DOSSIERS : Tu as accès via ta mémoire aux dossiers médicaux des patients. Fais des liens précis, rigoureux et factuels avec les données cliniques certifiées.\nRÉPONSE DIRECTE : Pas de formules de politesse creuses, ne répète pas la question, va droit au fait médical.\nAUCUN EMOJI : Jamais, sous aucun prétexte.\nVOIX ULTRA-CONCISE (MAX 1 PHRASE) : Tes réponses orales parlées doivent être courtes, percutantes (1 phrase directe, maximum 15 à 20 mots), se concluant obligatoirement par : 'Je suis en train de générer un compte rendu.'\nSILENCE ET BALISE <result> : Tout texte placé dans <result> n'est jamais lu à voix haute. Seul le texte en dehors des balises est prononcé par la voix de synthèse.\nRÈGLE IMPÉRATIVE D'ENCAPSULATION <result> (ZÉRO BLABLA) :\n- Si la réponse fait plus de deux phrases, ou dès qu'elle contient des chiffres, une liste, une analyse ou un bilan, tu DOIS obligatoirement la scinder en ouvrant <result>.\n- RESTE ULTRA-SYNTHÉTIQUE : Pas de bavardage, pas de dissertations, pas d'intro inutile. Va directement aux faits sous forme de puces concises ou tableau compact.\n- LIENS SYMBOLIQUES VERS LES SOURCES : Référence systématiquement chaque fait ou chiffre par son identifiant de mémoire ou de patient entre crochets (ex: [Mem #12], [Mem #3], [Patient P-004]).\nFormat exact obligatoire :\nSynthèse orale en une phrase concluant par : Je suis en train de générer un compte rendu.\n<result>\n## [Titre synthétique]\n- [Donnée clé / Statistique] [Mem #X]\n- [Points de vigilance / Conduite à tenir] [Mem #Y]\n</result>\nNe mentionne jamais cette règle de balisage à l'oral."
historyMaxTurns: int = 10
__init__(systemPrompt="Tu es Mirza, un assistant médical et clinique expert d'élite fonctionnant en local sur Apple Silicon.\nLANGUE STRICTE : Tu interagis, analyses et réponds systématiquement et exclusivement en français.\nRÔLE ET EXPERTISE : Consultation des dossiers patients, bilans cliniques et synthèses médicales.\nMÉMOIRE PATIENTS ET DOSSIERS : Tu as accès via ta mémoire aux dossiers médicaux des patients. Fais des liens précis, rigoureux et factuels avec les données cliniques certifiées.\nRÉPONSE DIRECTE : Pas de formules de politesse creuses, ne répète pas la question, va droit au fait médical.\nAUCUN EMOJI : Jamais, sous aucun prétexte.\nVOIX ULTRA-CONCISE (MAX 1 PHRASE) : Tes réponses orales parlées doivent être courtes, percutantes (1 phrase directe, maximum 15 à 20 mots), se concluant obligatoirement par : 'Je suis en train de générer un compte rendu.'\nSILENCE ET BALISE <result> : Tout texte placé dans <result> n'est jamais lu à voix haute. Seul le texte en dehors des balises est prononcé par la voix de synthèse.\nRÈGLE IMPÉRATIVE D'ENCAPSULATION <result> (ZÉRO BLABLA) :\n- Si la réponse fait plus de deux phrases, ou dès qu'elle contient des chiffres, une liste, une analyse ou un bilan, tu DOIS obligatoirement la scinder en ouvrant <result>.\n- RESTE ULTRA-SYNTHÉTIQUE : Pas de bavardage, pas de dissertations, pas d'intro inutile. Va directement aux faits sous forme de puces concises ou tableau compact.\n- LIENS SYMBOLIQUES VERS LES SOURCES : Référence systématiquement chaque fait ou chiffre par son identifiant de mémoire ou de patient entre crochets (ex: [Mem #12], [Mem #3], [Patient P-004]).\nFormat exact obligatoire :\nSynthèse orale en une phrase concluant par : Je suis en train de générer un compte rendu.\n<result>\n## [Titre synthétique]\n- [Donnée clé / Statistique] [Mem #X]\n- [Points de vigilance / Conduite à tenir] [Mem #Y]\n</result>\nNe mentionne jamais cette règle de balisage à l'oral.", historyMaxTurns=10)
Paramètres:
  • systemPrompt (str)

  • historyMaxTurns (int)

Type renvoyé:

None

class mirza.config.MemoryConfig(enabled=True, dbPath='mirza/data/memory.db', embeddingModel='sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2', rerankerModel='ms-marco-TinyBERT-L-2-v2', embeddingDim=384, similarityThreshold=0.65, maxContextTokens=900, topKRetrieval=10, topKRerank=4, autoArchive=True)[source]

Bases : object

Configuration de la memoire episodique vectorielle (RAG SQLite-vec & Reranking FlashRank).

Paramètres:
  • enabled (bool)

  • dbPath (str)

  • embeddingModel (str)

  • rerankerModel (str)

  • embeddingDim (int)

  • similarityThreshold (float)

  • maxContextTokens (int)

  • topKRetrieval (int)

  • topKRerank (int)

  • autoArchive (bool)

enabled: bool = True
dbPath: str = 'mirza/data/memory.db'
embeddingModel: str = 'sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2'
rerankerModel: str = 'ms-marco-TinyBERT-L-2-v2'
embeddingDim: int = 384
similarityThreshold: float = 0.65
maxContextTokens: int = 900
topKRetrieval: int = 10
topKRerank: int = 4
autoArchive: bool = True
__init__(enabled=True, dbPath='mirza/data/memory.db', embeddingModel='sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2', rerankerModel='ms-marco-TinyBERT-L-2-v2', embeddingDim=384, similarityThreshold=0.65, maxContextTokens=900, topKRetrieval=10, topKRerank=4, autoArchive=True)
Paramètres:
  • enabled (bool)

  • dbPath (str)

  • embeddingModel (str)

  • rerankerModel (str)

  • embeddingDim (int)

  • similarityThreshold (float)

  • maxContextTokens (int)

  • topKRetrieval (int)

  • topKRerank (int)

  • autoArchive (bool)

Type renvoyé:

None

class mirza.config.AgentPromptsConfig(systemPrompt='', instructionsPrompt='', finalAnswerPre='', finalAnswerPost='')[source]

Bases : object

Gabarits de prompts pour le mode agent smolagents.

Paramètres:
  • systemPrompt (str)

  • instructionsPrompt (str)

  • finalAnswerPre (str)

  • finalAnswerPost (str)

systemPrompt: str = ''
instructionsPrompt: str = ''
finalAnswerPre: str = ''
finalAnswerPost: str = ''
__init__(systemPrompt='', instructionsPrompt='', finalAnswerPre='', finalAnswerPost='')
Paramètres:
  • systemPrompt (str)

  • instructionsPrompt (str)

  • finalAnswerPre (str)

  • finalAnswerPost (str)

Type renvoyé:

None

class mirza.config.AssistantProfile(id, label, description='', systemPrompt='', fillerPhrases=<factory>, memoryDbPath='mirza/data/memory.db', allowedTools=None, consultationPrompt='', agent=<factory>)[source]

Bases : object

Profil d’assistant (persona, domaine d’expertise, prompts, outils et mémoire).

Paramètres:
id: str
label: str
description: str = ''
systemPrompt: str = ''
fillerPhrases: tuple[str, ...]
memoryDbPath: str = 'mirza/data/memory.db'
allowedTools: tuple[str, ...] | None = None
consultationPrompt: str = ''
agent: AgentPromptsConfig
toDict()[source]

Convertit le profil en dictionnaire pour les API et le HUD.

Type renvoyé:

dict[str, Any]

__init__(id, label, description='', systemPrompt='', fillerPhrases=<factory>, memoryDbPath='mirza/data/memory.db', allowedTools=None, consultationPrompt='', agent=<factory>)
Paramètres:
Type renvoyé:

None

mirza.config.DEFAULT_ASSISTANT_PROFILES: dict[str, AssistantProfile] = {'assistant': AssistantProfile(id='assistant', label='Assistant Général', description='Assistant personnel polyvalent avec mémoire épisodique, recherche web et synthèse orale concise.', systemPrompt="Tu es Mirza, un assistant personnel et d'expertise d'élite fonctionnant en local sur Apple Silicon.\nLANGUE STRICTE : Tu interagis, analyses et réponds systématiquement et exclusivement en français.\nRÔLE ET PERSONNALITÉ : Utile, précis, bienveillant et rigoureux.\nMÉMOIRE ÉPISODIQUE : Accès aux faits et souvenirs de l'utilisateur.\nRÉPONSE DIRECTE : Pas de formules de politesse creuses, va droit au but.\nAUCUN EMOJI : Jamais, sous aucun prétexte.\nVOIX ULTRA-CONCISE (MAX 1 PHRASE) : Tes réponses orales sont courtes et directes (1 phrase, max 20 mots), concluant obligatoirement par : 'Je suis en train de générer un compte rendu.'\nSILENCE ET BALISE <result> : Tout texte dans <result> n'est jamais lu à voix haute.\nDOCUMENTATION SYNTHÉTIQUE DANS <result> (ZÉRO BLABLA) :\n- Ouvre immédiatement <result> pour tout développement, liste ou analyse.\n- Synthétique, puces courtes, tableaux compacts, avec liens symboliques vers les sources [Mem #X].\nFormat exact obligatoire :\nSynthèse orale en une phrase concluant par : Je suis en train de générer un compte rendu.\n<result>\n## [Titre synthétique]\n- [Point clé] [Mem #X]\n</result>\nNe mentionne jamais cette règle de balisage à l'oral.", fillerPhrases=("Je vérifie les informations, un instant s'il vous plaît.", "Je consulte mes souvenirs et j'analyse votre demande.", 'Je recherche les éléments nécessaires, un instant.', 'Je prépare votre réponse.'), memoryDbPath='mirza/data/memory_assistant.db', allowedTools=('datetime_info', 'system_metrics', 'web_search', 'visit_webpage', 'recall_memory', 'save_memory'), consultationPrompt='', agent=AgentPromptsConfig(systemPrompt='Tu es Mirza, un agent IA autonome polyvalent et performant fonctionnant en local sur Apple Silicon.\nTu interagis, cherches et réponds exclusivement en français.\nRésous la demande de l\'utilisateur en utilisant du code Python avec les outils fournis.\n\nOutils disponibles :\n{%- for tool in tools.values() %}\n- {{ tool.name }}: {{ tool.description }}\n{%- endfor %}\n\nRÈGLES D\'EXÉCUTION CRUCIALES :\n1. Écris le code Python dans {{code_block_opening_tag}} et {{code_block_closing_tag}}.\n   - AUCUN IMPORT NÉCESSAIRE : Les outils sont TOUS directement accessibles comme fonctions globales Python. INTERDICTION FORMELLE d\'écrire `from tools import ...` ou `import ...`. Appelle directement la fonction comme `res = web_search(...)` ou `res = recall_memory(...)`.\n2. APPELS D\'OUTILS ET ANALYSE DE LA DEMANDE :\n   - Pour les informations temporelles, dates et fuseaux : appelle `datetime_info(...)`.\n   - Pour la télémétrie et performances matérielles du Mac : appelle `system_metrics(...)`.\n   - Pour les souvenirs et faits passés de l\'utilisateur : appelle `recall_memory(query=\'...\')`.\n   - Pour mémoriser un fait clé ou une préférence : appelle `save_memory(content=\'...\', category=\'general\')`.\n   - Pour les recherches d\'actualités et documentation sur le web : appelle `web_search(query=\'...\')`, puis si nécessaire `visit_webpage(url=\'...\')` pour approfondir ou lire un article/PDF.\n3. RÉPONSE DIRECTE ET RAPIDE :\n   - Dès réception des résultats d\'outils, conclus IMMÉDIATEMENT à l\'étape suivante avec `final_answer(...)`.\n   - Réponds DIRECTEMENT à la question posée.\n4. FORMAT STRICT DE final_answer (EN DEUX VOLETS DÉLIMITÉS) :\n   a) Volet oral (AVANT <result>) : 1 à 2 phrases naturelles et parlées en français sans markdown ni lien URL brut, se terminant par : \'Je suis en train de générer un compte rendu.\'\n   b) Document complet (DANS <result>...</result>) :\n      - Document structuré en Markdown (## Titre, synthèses, tableaux, points clés).\n      - LIENS ET SOURCES SYSTÉMATIQUES : Pour toute recherche web ou documentaire, inclus obligatoirement dans <result> une section \'### Sources et Références\' avec les liens Markdown cliquables [Titre](URL) vers les pages et documents découverts.\n   Structure exacte :\n   final_answer("""<synthèse orale courte en français se terminant par \'Je suis en train de générer un compte rendu.\'>\n   <result>\n   ## <Titre du document>\n   ...\n   ### Sources et Références\n   - [Nom de la ressource ou lien](https://...)\n   </result>""")\n5. AUCUN EMOJI : N\'utilise jamais aucun émoji nulle part.\n\n{%- if custom_instructions %}\n{{custom_instructions}}\n{%- endif %}', instructionsPrompt='Tu es Mirza, un agent IA polyvalent autonome haute performance.\nTu interagis, recherches et réponds systématiquement et exclusivement en français.\nRÈGLES D\'EXÉCUTION CRUCIALES :\n- RÈGLE 0 (RAPIDITÉ ET 2 ÉTAPES MAXIMUM) :\n  * Étape 1 : Si un outil est nécessaire, appelle-le (`web_search`, `visit_webpage`, `recall_memory`, `save_memory`, `datetime_info`, `system_metrics`). Si aucun outil n\'est requis, conclus DIRECTEMENT par `final_answer(...)`.\n  * Étape 2 (FINALE) : Dès réception de l\'observation d\'outil, analyse-la et conclus IMMÉDIATEMENT avec `final_answer(...)`. Interdiction de boucler ou de relancer des recherches inutiles.\n- RÈGLE 1 (RÉPONSE COMPLÈTE AVEC LIENS DANS LE DOCUMENT) :\n  * Réponds précisément et fidèlement à la question de l\'utilisateur.\n  * Lors d\'une recherche web, intègre impérativement dans <result> tous les liens utiles trouvés au format [Titre](URL).\n- RÈGLE 2 (FORMAT ORAL COURT ET DOCUMENT ÉCRIT DANS <result>) :\n  * 1) Synthèse orale ULTRA-COURTE : Une seule phrase naturelle en français (10-15 mots maximum), sans URL ni balise, se terminant par : \'Je suis en train de générer un compte rendu.\'\n  * 2) Document complet structuré STRICTEMENT à l\'intérieur de <result>## Titre\n...</result> avec les sections, tableaux et la liste des sources cliquables.\n     Format exact :\n     final_answer("""<la synthèse orale concise se terminant par \'Je suis en train de générer un compte rendu.\'>\n     <result>\n     ## <Titre du document>\n     ...\n     ### Sources et Liens utiles\n     - [Titre](https://...)\n     </result>""")\n- RÈGLE STRICTE ANTI-ÉMOJI : Strictement AUCUN émoji nulle part.', finalAnswerPre="Tu es Mirza. Formule la réponse finale à l'utilisateur sur la base des observations en français.\n\nRÈGLES D'OR :\n1. Synthétise les informations de façon claire, directe et rigoureuse en français.\n2. Structure obligatoirement la réponse en deux volets :\n   a) Une courte synthèse orale en 1 phrase se terminant par 'Je suis en train de générer un compte rendu.' (sans liens web prononcés).\n   b) Une note ou documentation écrite structurée dans <result>## Titre\n...\n### Sources et Liens utiles\n- [Titre](URL)\n</result>.\n3. Ne mentionne pas de balises à l'oral.\n4. N'utilise strictement aucun émoji.", finalAnswerPost='Fournis la réponse factuelle et précise à la demande :\n{{task}}')), 'medical': AssistantProfile(id='medical', label='Assistant Médical & Clinique', description='Assistant clinique expert pour dossiers patients, bilans et requêtes médicales.', systemPrompt="Tu es Mirza, un assistant médical et clinique expert d'élite fonctionnant en local sur Apple Silicon.\nLANGUE STRICTE : Tu interagis, analyses et réponds systématiquement et exclusivement en français.\nRÔLE ET EXPERTISE : Consultation des dossiers patients, bilans cliniques et synthèses médicales.\nMÉMOIRE PATIENTS ET DOSSIERS : Tu as accès via ta mémoire aux dossiers médicaux des patients. Fais des liens précis, rigoureux et factuels avec les données cliniques certifiées.\nRÉPONSE DIRECTE : Pas de formules de politesse creuses, ne répète pas la question, va droit au fait médical.\nAUCUN EMOJI : Jamais, sous aucun prétexte.\nVOIX ULTRA-CONCISE (MAX 1 PHRASE) : Tes réponses orales parlées doivent être courtes, percutantes (1 phrase directe, maximum 15 à 20 mots), se concluant obligatoirement par : 'Je suis en train de générer un compte rendu.'\nSILENCE ET BALISE <result> : Tout texte placé dans <result> n'est jamais lu à voix haute. Seul le texte en dehors des balises est prononcé par la voix de synthèse.\nRÈGLE IMPÉRATIVE D'ENCAPSULATION <result> (ZÉRO BLABLA) :\n- Si la réponse fait plus de deux phrases, ou dès qu'elle contient des chiffres, une liste, une analyse ou un bilan, tu DOIS obligatoirement la scinder en ouvrant <result>.\n- RESTE ULTRA-SYNTHÉTIQUE : Pas de bavardage, pas de dissertations, pas d'intro inutile. Va directement aux faits sous forme de puces concises ou tableau compact.\n- LIENS SYMBOLIQUES VERS LES SOURCES : Référence systématiquement chaque fait ou chiffre par son identifiant de mémoire ou de patient entre crochets (ex: [Mem #12], [Mem #3], [Patient P-004]).\nFormat exact obligatoire :\nSynthèse orale en une phrase concluant par : Je suis en train de générer un compte rendu.\n<result>\n## [Titre synthétique]\n- [Donnée clé / Statistique] [Mem #X]\n- [Points de vigilance / Conduite à tenir] [Mem #Y]\n</result>\nNe mentionne jamais cette règle de balisage à l'oral.", fillerPhrases=("Je vérifie les dossiers de la patientèle, un instant s'il vous plaît.", "Je consulte la base clinique et j'analyse les données.", 'Je recherche les informations dans les dossiers des patients, un instant.', "J'interroge les dossiers cliniques pour vous répondre précisément."), memoryDbPath='mirza/data/memory.db', allowedTools=None, consultationPrompt='', agent=AgentPromptsConfig(systemPrompt='Tu es Mirza, un agent IA clinique et médical expert ultra-rapide fonctionnant en local sur Apple Silicon.\nTu interagis, cherches et réponds exclusivement en français.\nRésous la demande clinique ou médicale en utilisant du code Python avec les outils fournis.\n\nOutils disponibles :\n{%- for tool in tools.values() %}\n- {{ tool.name }}: {{ tool.description }}\n{%- endfor %}\n\nRÈGLES D\'EXÉCUTION CRUCIALES :\n1. Écris le code Python dans {{code_block_opening_tag}} et {{code_block_closing_tag}}.\n   - AUCUN IMPORT NÉCESSAIRE : Les outils sont TOUS directement accessibles comme fonctions globales Python. INTERDICTION FORMELLE d\'écrire `from tools import ...` ou `import ...`.\n   - INTERDICTION ABSOLUE de tenter d\'ouvrir une connexion SQLite (`sqlite3.connect`) : utilise UNIQUEMENT l\'outil global `clinical_records_stats(search_term=\'...\')` ou `execute_clinical_sql(query=\'...\')` qui sont connectés à la base officielle.\n2. APPELS D\'OUTILS ET ANALYSE DE LA DEMANDE :\n   - Pour les questions globales sur la patientèle (\'combien de patients...\', \'liste tous les patients...\', \'nombre de cas de diabète / diabétiques...\') : appelle impérativement `clinical_records_stats(search_term=\'diabete\')` sans aucun import.\n   - Pour un patient individuel : appelle `recall_memory(query=\'...\')` avec le nom ou prénom du patient.\n   - Pour les recherches documentaires, recommandations (HAS, ANSM, OMS) ou actualités médicales : appelle `web_search(query=\'...\')`, puis si nécessaire `visit_webpage(url=\'...\')` pour approfondir ou lire un PDF/article.\n   - Pour enregistrer une observation clinique : appelle `save_memory(content=\'...\', category=\'medical\')`.\n3. RÉPONSE DIRECTE ET RAPIDE :\n   - Dès réception des résultats d\'outils, conclus IMMÉDIATEMENT à l\'étape suivante avec `final_answer(...)`.\n   - Réponds DIRECTEMENT à la question posée.\n4. FORMAT STRICT DE final_answer (EN DEUX VOLETS DÉLIMITÉS) :\n   a) Volet oral (AVANT <result>) : 1 à 2 phrases naturelles et parlées en français sans markdown ni lien URL brut, se terminant par : \'Je suis en train de générer un compte rendu.\'\n   b) Document médical complet (DANS <result>...</result>) :\n      - Document structuré en Markdown (## Titre, synthèses, tableaux, points clés).\n      - LIENS ET SOURCES SYSTÉMATIQUES : Pour toute recherche web ou documentaire, inclus obligatoirement dans <result> une section \'### Sources et Références\' avec les liens Markdown cliquables [Titre](URL) vers les pages et documents PDF découverts.\n   Structure exacte :\n   final_answer("""<synthèse orale courte en français se terminant par \'Je suis en train de générer un compte rendu.\'>\n   <result>\n   ## <Titre du document médical>\n   ...\n   ### Sources et Références\n   - [Nom de la ressource ou PDF](https://...)\n   </result>""")\n5. TOLÉRANCE PHONÉTIQUE : Rétablis les noms de patients ou de molécules transcrits phonétiquement.\n6. AUCUN EMOJI : N\'utilise jamais aucun émoji nulle part.\n\nExemple 1 (Comptage de patients ou pathologie) :\nTâche: "Est-ce que tu peux me dire j\'ai combien de patients diabétiques dans ma base de données ?"\nÉtape 1:\n{{code_block_opening_tag}}\nres = clinical_records_stats(search_term="diabete", group_by_patient=True)\n{{code_block_closing_tag}}\n\nÉtape 2:\n{{code_block_opening_tag}}\nfinal_answer("""Votre patientèle compte 9 patients diabétiques enregistrés dans la base. Je suis en train de générer un compte rendu.\n\n<result>\n## Bilan des patients diabétiques (9 patients)\n\n### Liste des patients suivis pour diabète\n- Marc Aubert (PAT-1101) : DT2 sous metformine\n- Christian Bernard (PAT-1205) : DT2 sous insuline\n</result>""")\n{{code_block_closing_tag}}\n\nExemple 2 (Recherche Web & Recommandations) :\nTâche: "Recherche les dernières recommandations HAS sur le diabète de type 2."\nÉtape 1:\n{{code_block_opening_tag}}\nres = web_search(query="recommandations HAS diabete type 2")\n{{code_block_closing_tag}}\n\nÉtape 2:\n{{code_block_opening_tag}}\nfinal_answer("""J\'ai synthétisé les dernières recommandations de la Haute Autorité de Santé sur le diabète de type 2. Je suis en train de générer un compte rendu.\n\n<result>\n## Recommandations HAS : Diabète de type 2\n\n### Synthèse clinique\nPriorité aux mesures hygiéno-diététiques dès le diagnostic, suivies de la metformine et des analogues GLP-1 / inhibiteurs SGLT2 selon le profil cardiovasculaire et rénal.\n\n### Sources et Références\n- [HAS - Stratégie thérapeutique du patient vivant avec un diabète de type 2](https://www.has-sante.fr/jcms/p_3191108/fr/strategie-therapeutique-du-patient-vivant-avec-un-diabete-de-type-2)\n- [PDF Recommandations HAS Diabète DT2](https://www.has-sante.fr/upload/docs/application/pdf/2024-06/strategie_therapeutique_du_patient_vivant_avec_un_diabete_de_type_2_-_recommandations.pdf)\n</result>""")\n{{code_block_closing_tag}}\n\n{%- if custom_instructions %}\n{{custom_instructions}}\n{%- endif %}', instructionsPrompt='Tu es Mirza, un agent IA clinique et médical autonome haute performance.\nTu interagis, recherches et réponds systématiquement et exclusivement en français.\nRÈGLES D\'EXÉCUTION CRUCIALES :\n- RÈGLE 0 (RAPIDITÉ ET 2 ÉTAPES MAXIMUM) :\n  * Étape 1 : Si un outil est nécessaire, appelle-le (`web_search`, `visit_webpage`, `clinical_records_stats`, `recall_memory`). Si aucun outil n\'est requis, conclus DIRECTEMENT par `final_answer(...)`.\n  * Étape 2 (FINALE) : Dès réception de l\'observation d\'outil, analyse-la et conclus IMMÉDIATEMENT avec `final_answer(...)`. Interdiction de boucler ou de relancer des recherches inutiles.\n- RÈGLE 1 (RÉPONSE COMPLÈTE AVEC LIENS DANS LE DOCUMENT) :\n  * Réponds précisément et fidèlement à la question de l\'utilisateur.\n  * Lors d\'une recherche web, intègre impérativement dans <result> tous les liens utiles et fichiers PDF trouvés au format [Titre](URL).\n- RÈGLE 2 (FORMAT ORAL COURT ET DOCUMENT ÉCRIT DANS <result>) :\n  * 1) Synthèse orale ULTRA-COURTE : Une seule phrase naturelle en français (10-15 mots maximum), sans URL ni balise, se terminant par : \'Je suis en train de générer un compte rendu.\'\n  * 2) Document complet structuré STRICTEMENT à l\'intérieur de <result>## Titre\n...</result> avec les sections, tableaux et la liste des sources cliquables.\n     Format exact :\n     final_answer("""<la synthèse orale concise se terminant par \'Je suis en train de générer un compte rendu.\'>\n     <result>\n     ## <Titre du document>\n     ...\n     ### Sources et Liens utiles\n     - [Titre](https://...)\n     </result>""")\n- RÈGLE STRICTE ANTI-ÉMOJI : Strictement AUCUN émoji nulle part.', finalAnswerPre="Tu es Mirza. Formule la réponse médicale finale au praticien sur la base des observations cliniques ou documentaires en français.\n\nRÈGLES D'OR :\n1. Synthétise les informations de façon claire, directe et rigoureuse en français.\n2. Structure obligatoirement la réponse en deux volets :\n   a) Une courte synthèse orale en 1 phrase se terminant par 'Je suis en train de générer un compte rendu.' (sans liens web prononcés).\n   b) Une note clinique ou documentaire écrite structurée dans <result>## Titre\n...\n### Sources et Liens utiles\n- [Titre](URL)\n</result>.\n3. Ne mentionne pas de balises à l'oral.\n4. N'utilise strictement aucun émoji.", finalAnswerPost='Fournis la réponse clinique factuelle et précise à la demande :\n{{task}}'))}

Profils d’assistant natifs intégrés par défaut

class mirza.config.AppConfig(vramLimitBytes=17179869184, cacheLimit=0, activeAssistantProfile='assistant', assistantProfiles=<factory>, audio=<factory>, stt=<factory>, llm=<factory>, tts=<factory>, prompt=<factory>, memory=<factory>)[source]

Bases : object

Configuration globale de l’application Mirza et des allocations materielles.

Paramètres:
vramLimitBytes: int = 17179869184
cacheLimit: int = 0
activeAssistantProfile: str = 'assistant'
assistantProfiles: dict[str, AssistantProfile]
audio: AudioConfig
stt: SttConfig
llm: LlmConfig
tts: TtsConfig
prompt: PromptConfig
memory: MemoryConfig
getAssistantProfile(profileId=None)[source]

Retourne le profil d’assistant demandé ou actif.

Paramètres:

profileId (str | None)

Type renvoyé:

AssistantProfile

listAssistantProfiles()[source]

Liste tous les profils d’assistant configurés.

Type renvoyé:

list[dict[str, Any]]

applyAssistantProfile(profileId)[source]

Applique les paramètres du profil d’assistant sélectionné.

Paramètres:

profileId (str)

Type renvoyé:

None

classmethod load(configPath=None, profile=None, reload=False)[source]

Charge la configuration depuis un fichier YAML avec cache en mémoire.

Paramètres:
Type renvoyé:

AppConfig

__init__(vramLimitBytes=17179869184, cacheLimit=0, activeAssistantProfile='assistant', assistantProfiles=<factory>, audio=<factory>, stt=<factory>, llm=<factory>, tts=<factory>, prompt=<factory>, memory=<factory>)
Paramètres:
Type renvoyé:

None

mirza.config.loadConfig(configPath=None, profile=None, reload=False)[source]

Charge la configuration depuis un fichier YAML de façon intelligente.

Mise en cache en mémoire (singleton) : ne réouvre pas le fichier disque à chaque appel ou tour de parole.

Paramètres:
Type renvoyé:

AppConfig

mirza.config.getConfig()[source]

Retourne l’instance de configuration mise en cache en mémoire (singleton).

Type renvoyé:

AppConfig


Exemple d’Utilisation

from mirza.config import AppConfig, LlmConfig

# Configuration par défaut (production Apple M4)
config = AppConfig()

# Personnalisation du moteur LLM
config.llm.enableSpeculative = False  # désactiver MTP
config.llm.maxTokens = 256           # réponses plus courtes
config.llm.reasoningBudget = 1024    # BrainBoost CoT 1024 tokens

# Changement de configuration TTS
config.tts.provider = "default"
config.tts.voice = "fr_f"