7h. ECHO Codex — Éditeur de Code Souverain

ECHO Codex est un environnement d'édition de code complet, entièrement intégré dans Open WebUI. Il associe un éditeur Monaco (le même moteur que VS Code) à un dépôt Git local (via dulwich, Python pur, sans binaire Git externe) et à une assistance AI (sous-chat Gemini via call_cascade()). Chaque conversation dispose de son propre espace de stockage isolé, persistent et versionné.

💡 Architecture en trois couches

ECHO Codex repose sur trois composants distincts qui coopèrent :

Architecture Codex [Interaction Components]
flowchart TD U([Utilisateur]) -->|HUD interactif| ACT[echo_codex_action.py
HUD + Monaco + WYSIWYG] LLM[Gemini] -->|Tool Calls| TOOL[echo_codex_tool.py
9 Fonctions LLM] ACT --> |Python ↔ JS Promise| GIT[echo_codex_git.py
CodexRepo dulwich] TOOL --> GIT GIT --> |CRUD + Git| FS[Vault Codex
/users/id/files/codex/] GIT --> |Proprioception| DB[(SQLite codex_docs)] classDef frontend fill:#4a1d96,stroke:#8b5cf6,color:#f8fafc classDef backend fill:#1e293b,stroke:#475569,color:#f8fafc classDef db fill:#0f172a,stroke:#3b82f6,color:#f8fafc class ACT frontend class TOOL,GIT backend class FS,DB db

Stockage — Le Vault Codex

Chaque conversation dispose d'un dépôt Git dédié, isolé dans le Vault utilisateur :

Chemin du dépôt Codex par conversation
/app/backend/data/users/{user_id}/files/codex/{chat_id}/
├── .git/           ← Dépôt Git dulwich (Python pur, pas de binaire git requis)
├── mon_script.py
├── config.yaml
└── README.md

La constante CODEX_DIR_NAME = "codex" (echo_constants.py) définit le nom du sous-dossier. L'isolation est garantie par user_id et chat_id : un utilisateur ne peut jamais accéder au Codex d'un autre, ni à celui d'une autre conversation.

Registre SQLite — codex_docs

Chaque fichier créé ou modifié est enregistré dans la table codex_docs de la base {chat_id}.db (EchoStateManager). Ce registre sert à deux fins : injection dans le vecteur proprioceptif (registre_codex) et statistiques rapides sans accès disque.

ColonneTypeDescription
filenameTEXT (PK)Nom du fichier (clé primaire)
languageTEXTLangage Monaco détecté depuis l'extension
linesINTEGERNombre de lignes au dernier commit
last_commitTEXTHash court (12 chars) du dernier commit
commit_msgTEXTMessage du dernier commit
created_atINTEGERTimestamp Unix de création
updated_atINTEGERTimestamp Unix de dernière modification

⚙️ Détection de langage — CodexRepo.detect_language()

Méthode statique qui mappe l'extension du fichier vers l'identifiant Monaco Editor. La table de correspondance CODEX_LANG_MAP (echo_constants.py) couvre plus de 30 langages : Python, JavaScript, TypeScript, C/C++, Rust, Go, Java, SQL, Shell, PowerShell, HTML, CSS, JSON, YAML, TOML, Markdown, etc. Fallback : plaintext.

Classe CodexRepo (echo_codex_git.py)

Abstraction autour de la bibliothèque dulwich (implémentation Python pure de Git). Elle évite toute dépendance à un binaire git dans le conteneur.

Opérations CRUD

MéthodeDescription
commit_file(filename, content, message) Écrit le contenu sur disque, indexe le fichier et crée un commit. Retourne le hash SHA du commit (str).
read_file(filename, start_line, end_line) Lit le contenu d'un fichier. Sans plage : fichier complet. Avec start/end : tranche [start, end] (1-indexed, inclusif). Retourne {"content", "total_lines", "range"}.
delete_file(filename, message) Supprime le fichier avec porcelain.rm() et crée un commit. Retourne le hash ou None si fichier inexistant.
list_files() Liste tous les fichiers trackés (hors .git/). Retourne [{"filename", "lang", "lines", "size_bytes"}] trié alphabétiquement.
search_in_file(filename, pattern, is_regex) Recherche un pattern (littéral ou regex). Retourne [{"line_number", "line_content"}]. Limité à 50 résultats.

Historique Git

MéthodeDescription
get_log(filename, limit) Retourne l'historique des commits. Si filename fourni, filtre les commits touchant ce fichier. Retourne [{"hash", "hash_full", "message", "author", "timestamp"}].
get_file_at_commit(filename, commit_hash) Lit le contenu d'un fichier à un commit donné (checkout virtuel sans modifier le working tree). Utilisé pour la navigation historique ◀ ▶ dans le HUD.
get_file_history_index(filename) Retourne la liste ordonnée des commits touchant un fichier (du plus ancien au plus récent). Structure l'index de navigation du HUD.
get_diff(commit_a, commit_b) Diff unifié entre deux commits. Si commit_b est None, diff commit_a contre son parent.

Administration

MéthodeDescription
reset_all() Supprime entièrement le dépôt (shutil.rmtree). Irréversible. Déclenché par l'action Reset du HUD.
get_repo_stats() Retourne {"total_files", "total_commits", "total_size_bytes", "last_commit_hash", "last_commit_message"}.

Outil LLM — echo_codex_tool.py (9 fonctions)

Ces fonctions sont exposées à Gemini comme Tool Calls. Le modèle peut les invoquer autonomement pendant une conversation pour interagir avec les fichiers du Codex.

Fonction Cas d'usage principal Paramètres clés
create_codex Créer un nouveau fichier avec contenu initial filename, content, commit_msg (optionnel)
edit_codex Écraser ou modifier un fichier existant filename, content, commit_msg (optionnel)
read_codex Lire tout ou partie d'un fichier filename, start_line (opt.), end_line (opt.)
search_codex Chercher un pattern pour cibler une zone avant lecture filename, query, is_regex (opt.)
summarize_codex Synthèse technique structurée via API Gemini filename
list_codex Inventaire de tous les fichiers (nom, lang, lignes, taille)
delete_codex Supprimer un fichier (commit de suppression) filename
history_codex Afficher l'historique Git global ou d'un fichier spécifique filename (opt.), limit (défaut 20)
restore_codex Restaurer un fichier à un commit antérieur (crée un nouveau commit de restauration) filename, commit_hash

💡 Stratégie de lecture pour les grands fichiers

La docstring de read_codex recommande une approche en deux temps pour les fichiers de plus de 300 lignes :

  1. summarize_codex : distillation via Gemini → vue d'ensemble (architecture, classes, dépendances) sans saturer le contexte.
  2. search_codex : localiser la zone d'intérêt (numéros de ligne).
  3. read_codex(start_line, end_line) : lecture chirurgicale de la plage ciblée.

Distillation dans summarize_codex

summarize_codex appelle EchoGeminiClient.call_distillation() avec le prompt CODEX_SUMMARIZE_PROMPT (défini dans echo_constants.py). La sortie est limitée à 8192 tokens.

Structure du résumé généré — CODEX_SUMMARIZE_PROMPT
1. Objectif et rôle du fichier
2. Architecture : classes, fonctions, structures principales
3. Dépendances et imports
4. Patterns et conventions utilisés
5. Points d'attention, complexité, dette technique éventuelle

Action HUD — echo_codex_action.py (v1.8)

L'Action ECHO Codex injecte un éditeur Monaco complet directement dans le DOM d'Open WebUI. C'est un HUD draggable et redimensionnable qui communique en temps réel avec le backend Python via le Pattern Promise (__event_call__).

Architecture HUD

Le HUD est généré par EchoUI._generate_codex_js() (echo_ui.py). Il s'agit d'un script JS auto-exécutable (IIFE) injecté une seule fois dans le DOM, qui charge Monaco Editor depuis CDN (monaco-editor@0.52.0 sur jsDelivr).

Zone du HUDDescription
File Tree (panneau gauche) Liste dynamique des fichiers du Codex triés par mtime. Clic → chargement dans l'éditeur. Clic droit → Renommage natif (OS/Git). Icône × → suppression. Icône + → nouveau fichier.
Monaco Editor (zone centrale) Éditeur Monaco avec panneau de prévisualisation WYSIWYG intégré (rendu HTML/Markdown). Bouton de sauvegarde explicite. Ctrl+S → sauvegarde + commit immédiat.
Barre d'état Affiche le fichier courant, le hash du dernier commit, ou le hash de la version consultée (mode historique).
Panneau AI (bas) Champ instruction, sélecteur modèle (LITE/FLASH/PRO), boutons d'actions rapides prédéfinies, bouton Appliquer.
Barre de navigation historique Boutons ◀ ▶ pour naviguer commit par commit. Mode read-only visuel (fond différent). Bouton Restaurer.
Barre Diff (Accept/Reject) Affichée après une édition AI : vue diff côte-à-côte (original vs. proposition). Accepter → commit. Rejeter → retour HEAD.

Boucle événementielle bidirectionnelle

La boucle Python est une boucle while True bloquée sur une Promise JS. Chaque interaction utilisateur dans le HUD résout la Promise et renvoie un dictionnaire { action: "...", filename: "...", content: "...", ... } au backend Python.

Action JSTraitement Python
closeSortie de la boucle.
saveCodexRepo.commit_file() + state.save_codex_record() + notification JS echoCodexNotify('saved').
ai_editAppel _codex_ai_edit()call_cascade()echoCodexShowDiff().
accept_diffcommit_file() + echoCodexNotify('committed') + rechargement contenu.
reject_diffechoCodexRevertDiff() + rechargement contenu HEAD.
uploadImport fichier PC → commit_file() + refresh tree.
downloadLecture fichier → echoCodexDownload(name, content) (téléchargement navigateur).
history_prev / history_nextget_file_at_commit()echoCodexLoadVersion() (mode read-only).
history_restorecommit_file() avec message "Restore from {hash}" + echoCodexNotify('restored').
new_filecommit_file(filename, "", "Create ...") + refresh tree.
load_fileread_file()echoCodexSetContent().
rename_filerepo.rename_file(old, new) + mise à jour codex_docs + refresh tree.
delete_filedelete_file() + delete_codex_record() + refresh tree + auto-switch vers premier fichier.
resetrepo.reset_all() + state.clear_codex_records() + echoCodexReset() (destroy HUD) + sortie boucle.
refreshlist_files()echoCodexRefreshTree() + rechargement fichier courant.

Édition AI — _codex_ai_edit()

La méthode privée _codex_ai_edit() orchestre un sub-chat dédié (sans historique, sans pensées) pour modifier le code. Elle retourne (texte_modifié, model_key_effectif) ou None en cas d'échec.

Prompt envoyé au LLM lors d'une édition AI
## Document complet
```{lang}
{content complet du fichier}
```

## Sélection ciblée   ← uniquement si l'utilisateur a sélectionné du texte
```{lang}
{selection}
```

## Instruction
{instruction de l'utilisateur}

Le système prompt (CODEX_EDIT_SYSTEM_PROMPT dans echo_constants.py) impose au LLM de retourner uniquement le fichier complet modifié, sans explication, sans bloc Markdown enveloppant. Le code Python nettoie les backticks parasites résiduels. La cascade (call_cascade()) gère le clamping politique et le basculement LITE/FLASH/PRO selon la disponibilité des modèles.

Actions rapides prédéfinies (CODEX_QUICK_ACTIONS)

L'utilisateur peut déclencher des transformations courantes via des boutons dans le panneau AI, sans rédiger d'instruction manuelle. Ces raccourcis sont définis dans echo_constants.py :

BoutonInstruction envoyée au LLM
shorterRaccourcis ce code/texte sans changer la logique ni le comportement.
longerDéveloppe avec plus de détails, commentaires et documentation.
commentAjoute des commentaires explicatifs clairs et concis.
uncommentSupprime tous les commentaires du code. Ne conserve que le code exécutable.
refactorRefactorise pour plus de lisibilité, maintenabilité et respect des conventions.
fixIdentifie et corrige les bugs potentiels. Explique chaque correction dans un commentaire.
testsGénère les tests unitaires pertinents pour ce code.
optimizeOptimise les performances sans changer l'interface publique.

API JS globale (callable depuis Python)

Le HUD expose ses fonctions de contrôle sur window pour être appelées depuis les pushes Python via __event_call__({ type: "execute", data: { code } }) :

Fonction JSRôle
window.echoCodexNotify(type, msg)Affiche une notification dans la barre d'état. Types : 'saved', 'committed', 'restored', générique.
window.echoCodexSetContent(content, filename)Charge un contenu dans l'éditeur Monaco et met à jour le sélecteur de langage.
window.echoCodexShowDiff(modifiedContent)Active le mode Diff (MonacoDiffEditor côte-à-côte) avec le contenu proposé.
window.echoCodexRevertDiff()Quitte le mode Diff et restaure l'éditeur normal.
window.echoCodexRefreshTree(newFiles)Met à jour la liste des fichiers dans le file tree.
window.echoCodexLoadVersion(content, info, idx, total)Active le mode historique read-only avec le contenu d'un commit donné.
window.echoCodexExitHistory()Quitte le mode historique et restaure l'éditeur normal.
window.echoCodexDownload(name, content)Déclenche le téléchargement natif du navigateur (Blob URL).
window.echoCodexSetModel(modelKey)Repositionne le sélecteur de modèle dans le panneau AI (feedback cascade).
window.echoCodexReset()Supprime entièrement le HUD du DOM.
window.echoCodexResolve({action, ...})Résout la Promise en cours (retour utilisateur → Python).

Proprioception — registre_codex

Le Filtre (new_context_filter.py v7.12) injecte automatiquement un registre des fichiers Codex dans le vecteur d'état environnement_contexte (AEC) à chaque tour de conversation. Gemini dispose ainsi d'une vue à jour de l'état du Codex sans avoir à appeler list_codex.

Extrait YAML — registre_codex dans environnement_contexte
registre_codex:
  - id: "mon_script.py"
    lang: "python"
    lines: 142
    last_commit: "feat: add error handler"
  - id: "config.yaml"
    lang: "yaml"
    lines: 38
    last_commit: "chore: update timeout"

⚠️ Règle d'Or — Consulter le registre avant toute opération

Le modèle doit consulter registre_codex pour vérifier l'existence d'un fichier avant d'appeler read_codex, edit_codex ou delete_codex. Cette règle évite les erreurs 404 inutiles et les tentatives de création de doublons.

Tableau récapitulatif des composants

Composant Fichier Version Rôle
CodexRepo 14-owui-libs/echo_codex_git.py 1.0 Gestion dépôt Git dulwich (CRUD, historique, diff)
Outil LLM Codex 12-owui-tools/echo_codex_tool.py 1.0 9 Tool Calls exposés à Gemini
Action HUD Codex 13-owui-actions/echo_codex_action.py 1.8 Éditeur Monaco interactif avec WYSIWYG (priorité 5)
_generate_codex_js() 14-owui-libs/echo_ui.py Générateur du HUD JS Monaco
Constantes Codex 14-owui-libs/echo_constants.py §1.4 5.4 CODEX_DIR_NAME, CODEX_LANG_MAP, prompts, actions rapides
Table codex_docs 14-owui-libs/echo_utils.py 7.21 Registre SQLite par conversation (CRUD + injection AEC)
registre_codex 11-owui-filters/new_context_filter.py 7.18 Injection proprioceptive dans environnement_contexte

✅ Exactitude — version 5.166.x

Les informations de cette page sont entièrement extraites du code source : echo_codex_git.py, echo_codex_tool.py, echo_codex_action.py, echo_ui.py, echo_constants.py (§1.4), echo_utils.py (v7.21) et new_context_filter.py (v7.12). Toute divergence avec ce document est à résoudre en faveur du code source.

← Visual Intelligence    Delegate Sub-Agent ➔