76 lines
3.3 KiB
Python
76 lines
3.3 KiB
Python
"""Assemblage commun aux deux lanceurs (`app.py` Cocoa, `lanceur_qt.py` Qt/Windows).
|
|
|
|
Avant ce module, `app.py` était le SEUL endroit qui savait choisir le système,
|
|
prendre le verrou d'instance, construire le transcripteur et l'overlay, puis
|
|
câbler le tout dans un `ZonzaController`. Un second lanceur qui recopierait
|
|
cette séquence créerait deux copies vouées à diverger en silence — exactement
|
|
le défaut déjà résorbé entre `engine.py` et `systeme/macos.py` (cf journal du
|
|
projet). Les deux lanceurs appellent donc les deux fonctions d'ici ; ce qui
|
|
reste propre à chacun (boucle d'événements, icône de barre, menu) reste dans
|
|
`app.py` et `lanceur_qt.py`.
|
|
|
|
Tout est injectable (`plateforme`, `run_on_main`...) pour rester testable sans
|
|
jamais ouvrir de fenêtre ni de micro : la construction du transcripteur charge
|
|
un vrai modèle, donc les tests injectent un `moteur.detecter_moteur`/
|
|
`moteur.choisir_transcripteur` doublés plutôt que de laisser tourner le vrai.
|
|
"""
|
|
import os
|
|
|
|
import moteur
|
|
from controller import ZonzaController
|
|
from core import CONFIG, modele_retenu, validate_config
|
|
from interface import classe_overlay_pour
|
|
from systeme import choisir_systeme
|
|
|
|
|
|
def acquerir_verrou(systeme, chemin_verrou=None):
|
|
"""Prend le verrou d'instance unique ; rend le handle, ou None si pris.
|
|
|
|
Une seule instance à la fois : sinon deux modèles en RAM et la même
|
|
hotkey captée deux fois (cf systeme.acquerir_verrou_instance). Le chemin
|
|
est injectable : les tests et les essais manuels d'un lanceur doivent
|
|
pouvoir viser un fichier qui n'est PAS celui de l'instance déjà en cours
|
|
de l'utilisateur.
|
|
"""
|
|
chemin = chemin_verrou or os.path.join(systeme.dossier_donnees(), "instance.lock")
|
|
return systeme.acquerir_verrou_instance(chemin)
|
|
|
|
|
|
def construire(plateforme=None, run_on_main=None, on_state=None,
|
|
detecter_moteur=None, choisir_transcripteur=None):
|
|
"""Construit le système, le transcripteur, l'overlay et le contrôleur.
|
|
|
|
Ne prend PAS le verrou (c'est le rôle d'`acquerir_verrou`, appelée à part
|
|
par le lanceur, qui décide seul de ce qu'il fait d'un refus). Ne valide
|
|
la config qu'une fois, ici, pour que les deux lanceurs en bénéficient
|
|
sans avoir à y penser.
|
|
|
|
`detecter_moteur`/`choisir_transcripteur` sont injectables : ils
|
|
permettent aux tests de construire l'assemblage entier sans charger un
|
|
vrai modèle de transcription (opération lourde, et qui échouerait sans
|
|
matériel/poids téléchargés).
|
|
"""
|
|
detecter_moteur = detecter_moteur or moteur.detecter_moteur
|
|
choisir_transcripteur = choisir_transcripteur or moteur.choisir_transcripteur
|
|
|
|
validate_config(CONFIG)
|
|
systeme = choisir_systeme(plateforme)
|
|
moteur_nom = detecter_moteur()
|
|
transcripteur = choisir_transcripteur(
|
|
nom=moteur_nom,
|
|
modele=modele_retenu(moteur_nom, CONFIG["model"]),
|
|
langue=CONFIG["language"],
|
|
amorce=CONFIG["initial_prompt"],
|
|
)
|
|
overlay = classe_overlay_pour(plateforme)()
|
|
controller = ZonzaController(
|
|
CONFIG, overlay, transcripteur, systeme, on_state=on_state,
|
|
run_on_main=run_on_main,
|
|
)
|
|
return {
|
|
"systeme": systeme,
|
|
"transcripteur": transcripteur,
|
|
"overlay": overlay,
|
|
"controller": controller,
|
|
}
|