Rework AI-Typewriter en application d'arrière-plan multi-profils

- Rollback gestion d'équations : écriture littérale caractère par caractère
  (suppression de math_format.py et de la normalisation Unicode).
- Nouveau profil par défaut 'Mathématiques (LaTeX)' : le modèle émet du
  LaTeX encadré [EQ]...[/EQ], intercepté par KeyStepper qui déclenche
  Alt+= en début d'équation et -> en fin.
- Config multi-profils dans %APPDATA%/ai-typewriter/config.json
  (ConfigStore + profils par défaut auto-créés).
- Icône de zone de notification (pystray) : Ouvrir les logs (temps réel),
  Ajouter/Modifier un profil, Gérer l'authentification, Quitter.
- Sélecteur de modèles : modèles locaux Ollama + recherche/téléchargement
  depuis la bibliothèque publique ; fournisseurs tiers (OpenAI, OpenRouter,
  Gemini, custom).
- Clés d'API stockées de façon sécurisée dans le Gestionnaire d'identifiants
  Windows via keyring (jamais en clair dans config.json).
- Tests : 44 tests verts (stepper, profils, clients IA, credentials,
  catalogue de modèles, moteur).
This commit is contained in:
Hermes Agent
2026-09-18 09:48:46 +02:00
parent d07bed60e6
commit 3e58380f80
30 changed files with 2461 additions and 491 deletions
+56 -87
View File
@@ -1,132 +1,101 @@
# ai-typewriter
# AI-Typewriter
Application Python qui lit la dernière entrée texte du presse-papier avec un raccourci global, l'envoie à un modèle IA, puis remplace chaque pression de touche suivante par le caractère suivant de la réponse.
Application Python qui tourne **en arrière-plan** (icône dans la zone de notification de Windows, aucune fenêtre au démarrage), lit le contenu du presse-papier sur un raccourci global, l'envoie à un modèle IA, puis réécrit la réponse **caractère par caractère** à chaque pression de touche physique.
Un profil spécialisé « Mathématiques (LaTeX) » marque les équations avec `[EQ]...[/EQ]` : l'application les intercepte et déclenche `Alt+=` pour ouvrir une équation (Word/OneNote) et `→` pour en sortir.
## Fonctionnement
1. L'utilisateur copie manuellement le texte à envoyer à l'IA.
1. L'utilisateur copie le texte à envoyer à l'IA.
2. Raccourci global par défaut : `Ctrl+Alt+A`.
3. L'application lit directement la dernière entrée du presse-papier, sans simuler `Ctrl+C`.
4. Le texte capturé est journalisé puis envoyé à Ollama ou Gemini.
5. Le temps de génération de la réponse est journalisé.
6. Quand la réponse arrive, le mode dactylographie s'active.
7. Chaque touche physique appuyée est interceptée et remplacée par le prochain caractère de la réponse IA.
8. Le hook clavier est libéré automatiquement après le dernier caractère.
L'application n'interprète pas les équations et ne lance pas `Alt+=`. Elle écrit uniquement le texte généré, caractère par caractère. Pour les maths, le modèle peut produire du LaTeX encadré par des marqueurs `[EQ]...[/EQ]`, puis la gestion Word peut être faite ailleurs.
3. L'application lit le presse-papier et envoie au modèle du profil actif.
4. Une icône reste disponible dans la zone de notification : elle permet d'ouvrir les journaux, d'ajouter/commuter des profils et de gérer les clés d'API.
5. Chaque touche physique appuyée ensuite écrit l'élément suivant de la réponse (caractère ou séquence d'équation).
6. Le hook clavier est libéré automatiquement à la fin de la réponse.
## Installation depuis les sources
```bash
python -m venv .venv
. .venv/bin/activate
. .venv/bin/activate # Windows : .venv\Scripts\activate
pip install -r requirements.txt
cp config.json.template config.json
pip install -e .
python main.py
```
Sous Linux, le paquet `keyboard` nécessite souvent les droits root ou l'accès aux périphériques `/dev/input`. Sous Windows, lancez l'exécutable dans une session utilisateur normale.
À la première exécution, l'application crée son fichier de configuration :
`%APPDATA%\ai-typewriter\config.json` (Linux : `~/.config/ai-typewriter/config.json`).
## Configuration
## Configuration (profils)
Copiez `config.json.template` vers `config.json` puis adaptez :
La configuration contient une liste de **profils** nommés et le profil actif. Chaque profil décrit :
```json
{
"provider": "ollama",
"model": "llama3.1",
"api_key": "",
"server_url": "http://localhost:11434",
"hotkey": "ctrl+alt+a",
"request_timeout_seconds": 300,
"math_text_format": "plain"
}
```
| Champ | Description |
|---|---|
| `name` | Libellé affiché dans les menus |
| `provider` | `ollama`, `openai`, `openrouter`, `gemini`, `custom` (OpenAI-compatible) |
| `model` | Nom du modèle (choisissable via le sélecteur) |
| `server_url` | Base de l'instance (ex. `http://localhost:11434`) |
| `credential` | Nom logique de la clé d'API (voir « Authentification ») |
| `system_prompt` | Instructions données au modèle |
| `equation_enabled` | Active l'interception des marqueurs d'équation |
| `eq_start_marker` / `eq_end_marker` | Marqueurs (défaut `[EQ]` / `[/EQ]`) |
| `eq_start_key` / `eq_end_key` | Touches déclenchées (défaut `alt+=` / `right`) |
### Ollama
Deux profils sont créés par défaut : **Général** et **Mathématiques (LaTeX)**.
```json
{
"provider": "ollama",
"model": "llama3.1",
"server_url": "http://localhost:11434"
}
```
### Profil Mathématiques (LaTeX)
### Gemini
```json
{
"provider": "gemini",
"model": "gemini-1.5-flash",
"api_key": "VOTRE_CLE",
"server_url": "https://generativelanguage.googleapis.com"
}
```
### Timeout IA
`request_timeout_seconds` vaut `300` par défaut. Si Ollama charge un gros modèle ou répond lentement, augmentez cette valeur. Mettez `0` pour désactiver le timeout côté application.
### Configuration maths LaTeX
Pour laisser le modèle générer du LaTeX tout en indiquant clairement les débuts/fins d'équations :
```bash
cp config.math-latex.template config.json
```
Cette config garde :
```json
"math_text_format": "plain"
```
Donc l'application ne transforme rien. Elle tape littéralement la réponse reçue, caractère par caractère.
Exemple de réponse demandée au modèle :
Le prompt système demande au modèle de produire du LaTeX encadré par `[EQ]...[/EQ]`, par exemple :
```text
Les racines sont [EQ]z_1 = x + iy[/EQ] et [EQ]z_2 = x - iy[/EQ].
```
Pour les fractions, intégrales, sommes, etc., le modèle peut utiliser du LaTeX standard dans les balises :
À chaque `[EQ]` l'application envoie `Alt+=` (ouvre une équation inline), tape le LaTeX littéralement, puis envoie `→` à chaque `[/EQ]`. Ce comportement est désactivé par défaut sur les autres profils (le texte est tapé tel quel).
```text
On obtient [EQ]\frac{a+b}{c+d}[/EQ] puis [EQ]\int_0^1 f(x)\,dx[/EQ].
```
## Zone de notification (icône)
Modes disponibles :
L'application se lance sans fenêtre visible. Le menu de l'icône propose :
- `plain` : mode recommandé ; injecte la réponse exactement telle que le modèle l'a renvoyée.
- `unicode` : ancien mode texte Unicode (`z_1` → `z₁`, `x^2` → `x²`) sans objet équation.
- **Ouvrir les logs** — fenêtre des journaux en temps réel (également écrits dans `%APPDATA%\ai-typewriter\logs\app.log`).
- **Ajouter un profil** — formulaire (nom, fournisseur, modèle, serveur, prompt, équations).
- **Modifier le profil** — sous-menu listant tous les profils pour choisir le profil actif.
- **Gérer l'authentification** — enregistrer les clés d'API des fournisseurs.
- **Quitter** — arrête le processus.
## Compilation
### Sélection et téléchargement des modèles
### Windows
Dans le formulaire de profil, « Choisir / télécharger… » ouvre un sélecteur qui :
Après clonage du dépôt, lancez simplement :
- liste automatiquement les modèles déjà disponibles localement (Ollama `/api/tags`) ;
- si connecté à Internet, permet de rechercher dans la bibliothèque publique d'Ollama, de vérifier un modèle exact et de lancer son téléchargement (`ollama pull`).
### Authentification des fournisseurs
Les clés d'API ne sont **jamais écrites** dans le fichier de configuration. Chaque profil référence une clé par un nom logique ; la clé est stockée de façon sécurisée dans le **Gestionnaire d'identifiants de Windows** (via `keyring`). Le menu **Gérer l'authentification** permet de les enregistrer, vérifier ou supprimer.
## Compilation (Windows)
```bat
build.bat
```
Le script crée `.venv`, installe les dépendances, nettoie les anciens artefacts puis génère un exécutable Windows autonome :
Le script crée `.venv`, installe les dépendances, puis produit un exécutable autonome **sans console** dans `dist\ai-typewriter.exe`. Il tourne directement en zone de notification.
```text
dist\ai-typewriter.exe
```
### Commande PyInstaller équivalente
## Test rapide sans hook clavier ni icône
```bash
pyinstaller --onefile --paths src --name ai-typewriter.exe main.py
python main.py --debug --ask "Résume: bonjour tout le monde"
```
L'exécutable est généré dans `dist/`. Le binaire n'est pas versionné Git.
Envoie le prompt au profil actif et imprime la réponse brute (aucune icône ni interception clavier).
## Test rapide sans hook clavier
## Tests
```bash
python main.py --config config.json --ask "Résume: bonjour tout le monde"
. .venv/bin/activate
pytest
```
La suite couvre le découpage en actions (caractères/équations), le stepper, le dépôt de profils, les clients IA (Ollama/Gemini/OpenAI), le stockage sécurisé (keyring mocké) et le catalogue de modèles — sans réel hook clavier, réseau ni Gestionnaire d'identifiants.