Skip to content

klodynlov/klody-code-ai

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

201 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

🧠 Klody Code AI

Un agent de code 100 % local — privé, sécurisé, extensible — qui rivalise avec un agent cloud sur une machine perso.

Pas d'API cloud. Aucune donnée ne quitte la machine. Le cerveau (MLX/Apple Silicon), les outils, la mémoire, le RAG, et les connecteurs (Gmail, web, MCP) tournent en local.

Tests Coverage License AI MCP Commits Apple Silicon

Étude de cas technique · Architecture · Sécurité · Pour les entreprises

Status : v2.1+ stable · 699 tests · CI à gates (bandit / gitleaks / pip-audit / coverage) · cerveau MLX Qwen3.6-35B-A3B · client et serveur MCP


Pourquoi c'est intéressant

La plupart des agents de code envoient ton code et tes données dans le cloud. Klody fait l'inverse : tout s'exécute sur ta machine. Le défi technique — faire d'un modèle local (plus petit que la frontière) un agent fiable — est résolu par l'orchestration, pas par la force brute : un routeur adaptatif, une boucle ReAct qui va au bout, un sandbox isolé, et une discipline de tests/sécurité de niveau production. Le tout extensible via MCP : Klody consomme des serveurs externes (Gmail, web…) et s'expose comme serveur pour d'autres agents.

🔒 Privé par conception 100 % local. Sandbox fichiers multi-racines, fichiers sensibles bloqués partout, anti-SSRF sur le web, commits signés.
🧭 Orchestration, pas brute force Routeur (easy/medium/hard × 12 types de tâches, F1≈0,85), boucle auto-prolongée, Best-of-N conditionnel, anti-stall.
🔌 Extensible via MCP Client MCP (consomme Gmail, web, n'importe quel serveur) + serveur MCP (Cline/Zed/Continue consomment Klody).
🧰 Complet 69 outils, app desktop (Tauri/React, thème clair/sombre/auto), mémoire long terme, RAG livres, retrieval code-aware.
🖥️ Pilote ton environnement macOS (AppleScript, Spotlight, Raccourcis→HomeKit/Automator, Finder), maison connectée (MQTT : ESP32, Raspberry Pi), automatisation fichiers (renommage, organisation, sauvegarde, synchro).
🔨 Toolsmithing Klody ne se contente pas d'utiliser des outils, il les fabrique : scripts, CLI, APIs FastAPI, serveurs MCP, workflows, pipelines, plugins Klody, interfaces web — chacun livré avec son test.
⚙️ Ops & génération Introspection Docker/Kubernetes/Git (lecture seule, mutations gated), SQL SQLite sandboxé, diagrammes UML, scaffolding d'API REST/GraphQL, SDK et repository NoSQL.
Production-grade 699 tests, coverage 78 %, CI 5 jobs (sécurité + régression + contrat), branch protection + signed commits.

Architecture

flowchart TD
    U([👤 Utilisateur]) --> UI["🖥️ App desktop · Tauri 2 + React 19<br/>thème clair/sombre/auto"]
    UI <-->|WebSocket| API["⚡ FastAPI · :8000"]
    API --> ORCH

    subgraph ORCH["🧭 Adaptive Orchestrator — boucle ReAct"]
        R["Router · easy/medium/hard × 6 task_types"]
        L["Boucle auto-prolongée + anti-stall + Best-of-N"]
        R --> L
    end

    ORCH --> TOOLS
    ORCH --> MCPC["🔌 Client MCP"]
    ORCH --> LLM

    subgraph TOOLS["🧰 Outils natifs (69)"]
        direction LR
        T1["fichiers · sandbox<br/>multi-racines"]
        T2["code-aware<br/>tree-sitter + bge-m3"]
        T3["github · preview<br/>audio · skills · mémoire"]
        T4["macOS · MQTT<br/>automatisation · toolsmithing"]
    end

    MCPC -->|outils Gmail| GM["📧 Serveur MCP Gmail · :8084"]
    MCPC -->|outils Web| WB["🌐 Serveur MCP Web · :8085<br/>lecture seule · anti-SSRF"]

    subgraph LLM["🧠 LLM 100% local"]
        direction LR
        B["MLX cerveau<br/>Qwen3.6-35B · :8080"]
        C["MLX code<br/>Qwen3-Coder-30B · :8081"]
        O["Ollama fallback · :11434"]
    end

    TOOLS --> RAG["📚 LibraryBrain RAG · :8765"]
    API -.expose.-> MCPS["📡 Serveur MCP Klody · :8083<br/>(Cline · Zed · Continue le consomment)"]
Loading

Caractéristiques clés

# Feature Détail
1 100 % local & privé MLX sur Apple Silicon (Qwen3.6-35B-A3B cerveau, Qwen3-Coder-30B code). Zéro appel cloud par défaut.
2 Routeur adaptatif classifie chaque prompt → 3 difficultés × 12 task_types (edit, refactor, bug_fix, feature, explain, self_dev, review, test_gen, security, docs, perf, migrate) → budget d'itérations + planner + Best-of-N (F1≈0,85).
3 Boucle qui va au bout auto-continue quand la tâche est actionnable ; cliquet de continuation ("ok/vas-y" réutilise le routage).
4 Sandbox isolé multi-racines venv jetable par racine, ALLOWED_ROOTS, exec auto après write (py_compile/pytest).
5 Client MCP consomme n'importe quel serveur MCP ; outils exposés au LLM sous mcp__<srv>__<outil>.
6 Serveurs MCP fournis Gmail (IMAP/SMTP) + Web (fetch/search lecture seule, anti-SSRF) — branchés par une ligne de .env.
7 Serveur MCP Klody Klody = plateforme pour d'autres agents (Cline, Zed, Continue.dev).
8 Retrieval code-aware tree-sitter (symboles/refs) + embeddings bge-m3 (find_symbol, find_relevant_files). Python/JS/TS de base ; Rust/Go/Java/PHP en option (grammaires chargées dynamiquement).
9 Best-of-N + mémoire N candidats T variés + action override ; conventions auto-détectées + mémoire d'erreurs.

Stack technique

Composant Tech
Runtime Python 3.11+ · FastAPI · WebSocket
LLM cerveau MLX-LMunsloth/Qwen3.6-35B-A3B-MLX-8bit (:8080, enable_thinking=false)
LLM code MLX-LMmlx-community/Qwen3-Coder-30B-A3B-Instruct-8bit (:8081)
LLM fallback Ollamaqwen2.5-coder:32b (:11434)
Embeddings Ollamabge-m3
RAG livres LibraryBrain — sqlite-vec + FTS5 (:8765)
MCP FastMCP — Klody client et serveur ; connecteurs Gmail/Web
UI graphique klody-ui — Tauri 2 + React 19 + Tailwind 4 (repo)
Tests pytest699 tests · coverage 78 %

Installation

1. Prérequis

pip install mlx-lm              # MLX-LM (Apple Silicon recommandé)
brew install ollama ripgrep     # Ollama (embeddings + fallback), ripgrep (recherche)
pip install sqlite-vec          # optionnel (LibraryBrain)

2. Modèles

# Cerveau MLX (MoE 35B / ~3B actifs, multimodal)
huggingface-cli download unsloth/Qwen3.6-35B-A3B-MLX-8bit
# Spécialiste code (optionnel, port 8081)
huggingface-cli download mlx-community/Qwen3-Coder-30B-A3B-Instruct-8bit
# Embeddings (requis pour le retrieval)
ollama serve && ollama pull bge-m3

3. Cloner et installer

git clone https://github.com/klodynlov/klody-code-ai.git
cd klody-code-ai && python3.11 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env   # puis éditer (voir ci-dessous)

4. Configurer .env (extrait)

BACKEND=mlx
MLX_BASE_URL=http://localhost:8080/v1
MLX_MODEL=unsloth/Qwen3.6-35B-A3B-MLX-8bit
MLX_CHAT_TEMPLATE_ARGS='{"enable_thinking": false}'   # requis pour Qwen3.6 (thinking)

PROJECT_ROOT=/Users/ton-nom/mon-projet                # racine principale du sandbox
# ALLOWED_ROOTS=/Users/ton-nom/Projets:/Users/ton-nom/work   # racines supplémentaires

MAX_ITERATIONS=25                                     # plafond boucle ReAct
# Connecteurs MCP (optionnels) — Klody les découvre au démarrage
# KLODY_MCP_SERVERS={"gmail":"http://127.0.0.1:8084/mcp","web":"http://127.0.0.1:8085/mcp"}

Lancement

./scripts/start-mlx.sh                 # 1. cerveau MLX (~30-60s de chargement)
ollama serve                           # 2. embeddings
python main.py                         # 3. CLI Rich  (--resume / --session <id>)
python api/server.py                   # 4. (option) API WebSocket pour l'UI Tauri
./scripts/start-klody-mcp.sh --http    # 5. (option) exposer Klody en serveur MCP (:8083)

# Connecteurs MCP (option) :
./scripts/start-gmail-mcp.sh --http    # Gmail  (:8084) — voir .env.example
./scripts/start-web-mcp.sh   --http    # Web    (:8085) — lecture seule

Outils disponibles (69 natifs + connecteurs MCP)

Catégorie Outils
Fichiers (multi-racines) read_file, write_file, list_files, search_in_files
Code-aware find_symbol, find_references, find_relevant_files, code_graph, analyze_dependencies, generate_uml (diagramme de classes Mermaid depuis le code)
Exécution execute_command, run_in_sandbox (venv jetable par racine), run_sql (SQLite local sandboxé, lecture seule par défaut)
Ops / runtime docker_control (Docker : ps/images/inspect/logs/stats en lecture seule ; run ultra-contraint si activé), kubectl_control (introspection Kubernetes lecture seule : get, describe, logs, top…), git_control (Git : status, log, diff, show, blame… en lecture seule ; add/commit locaux si GIT_WRITE_ENABLED)
Web preview preview_code (auto-CDN + overlay erreurs JS), preview_file, list_previews
GitHub browse_repo, read_github_file, index_github_repo, clone_github_repo, extract_best_practices, create_project
Audio analyze_audio, edit_wav, mix_stems, generate_silence, convert_format, get_waveform_data
Génération generate_uml (diagramme de classes Mermaid), scaffold_api (squelette CRUD : REST FastAPI ou GraphQL Strawberry), scaffold_sdk (client Python typé httpx), scaffold_nosql (repository MongoDB pymongo)
Musique — composition (mcp__klodymusic__*) evaluer_tessiture, suggerer_tonalites, harmoniser, suggerer_accords, analyser_progression, reharmoniser, moduler, melodie_vers_midi, generer_basse, harmonies_vocales, idees_chanson, composer_demo
Musique — mixage (mcp__klodymusic__*) recommander_eq, detecter_masquage, analyser_balance_tonale, recommander_compression, recommander_saturation (dérivés des mesures objectives d'audio_analysis : LUFS, spectre, largeur stéréo, crest)
Musique — chant (mcp__klodymusic__*) evaluer_tessiture, analyser_justesse (écart en cents vs gamme), recommander_autotune (gamme/vitesse/force), harmonies_vocales
Musique — sound design (mcp__klodymusic__*) generer_preset_synth (patch synthé agnostique par rôle/caractère), organiser_banque (rangement de samples par catégorie)
Musique — DAW / voix mcp__reaper__* (pistes, FX, bus/sends, MIDI, régions, rendu stems, chaîne vocale, arrangement), mcp__vocalbrain__* (génération/entraînement de chant)
🖥️ macOS (Apple Silicon) run_applescript, spotlight_search, run_shortcut (HomeKit/Automator), list_shortcuts, reveal_in_finder
🏠 Maison / IoT mqtt_publish, mqtt_subscribe (ESP32, Raspberry Pi, Home Assistant, pont HomeKit)
🧹 Automatisation batch_rename, organize_directory, backup_directory, sync_directories (sandboxés, dry_run par défaut)
🔨 Toolsmithing scaffold_tool (script, cli, api, mcp_server, workflow, pipeline, klody_plugin, web_interface), list_tool_kinds
RAG / Skills search_books, learn_from_books, get_skills, save_skill, list_skills, delete_skill
Mémoire remember_fact, forget_fact
Connecteurs MCP mcp__gmail__* (8 outils), mcp__web__* (fetch_url, web_search), + tout serveur MCP branché

🔨 Toolsmithing — Klody fabrique ses propres outils

Le module le plus puissant : plutôt que de seulement utiliser des outils, Klody en construit de neufs, prêts à l'emploi et livrés avec leur test.

scaffold_tool(kind="mcp_server", name="capteurs maison", target_dir="~/Projets")
→ capteurs_maison/capteurs_maison_server.py  (serveur MCP FastMCP)
  capteurs_maison/test_capteurs_maison_server.py
  capteurs_maison/requirements.txt + README.md
kind Produit
python_script script CLI autonome (argparse) + test
cli CLI multi-commandes (sous-commandes) + test
api API FastAPI (health + echo) + test TestClient
mcp_server serveur MCP FastMCP branchable dans Klody + test
workflow orchestrateur d'étapes séquentielles + test
pipeline pipeline ETL (extract → transform → load) + test
klody_plugin plugin outil Klody (schéma registry + handler)
web_interface interface web statique autonome (HTML + JS)

Sécurité

  • Sandbox fichiers : accès limité aux racines autorisées (PROJECT_ROOT + ALLOWED_ROOTS) ; ..//symlinks bloqués ; fichiers sensibles refusés partout (.env .key .pem .p12 .pfx .cer .crt .ppk .p8) ; 1 Mo max/écriture.
  • Sandbox exécution : confirmation en TTY ; blocklist pré-confirmation (sudo, rm -rf /, mkfs, exfil SSH/AWS…) ; run_in_sandbox dans un venv jetable isolé.
  • SQL sandboxé (run_sql) : base SQLite confinée aux racines autorisées, lecture seule par défaut (SQL_WRITE_ENABLED) ; authorizer sqlite3 default-deny, ATTACH/VACUUM INTO/load_extension bloqués, verrou SQLITE_LIMIT_ATTACHED=0, anti-DoS (limites + échéance wall-clock), une seule instruction par appel. Contrôles issus d'un threat-model adversarial.
  • Ops en lecture seule (docker_control, kubectl_control, git_control) : introspection uniquement (Docker : ps/images/inspect/logs/stats… ; k8s : get/describe/logs/top… ; Git : status/log/diff/show/blame…), aucune mutation ; subprocess en argv (pas de shell), sous-commandes/verbes hardcodés, entrées (cible, resource, name, namespace, ref, fichier) validées par charset strict — pas d'injection de commande ni de flag (-o jsonpath, --kubeconfig, --output…) ; dépôt Git confiné aux racines autorisées ; sortie plafonnée, timeout borné. Les mutations Git (add/commit, locales et réversibles) sont désactivées par défaut (GIT_WRITE_ENABLED) ; push/pull et les opérations destructives (reset/checkout/clean/rebase) restent hors de l'outil. Le docker run (mutation) est doublement borné — DOCKER_WRITE_ENABLED et une allowlist d'images non vide — et impose un durcissement figé (aucun flag utilisateur : --network none, --cap-drop ALL, no-new-privileges, limites ressources, pas de montage) ; build/exec/rm restent exclus.
  • Web en lecture seule : fetch_url/web_search en GET, http/https only, anti-SSRF (IP privées/loopback/link-local refusées, y compris via redirection), taille plafonnée.
  • Pilotage macOS : garde plateforme (hors macOS → message clair, jamais d'exception) ; blocklist AppleScript (suppression, vidage corbeille, extinction, do shell script, contrôle UI synthétique refusés) ; reveal_in_finder/Spotlight confinés aux racines autorisées ; timeouts + sortie plafonnée.
  • Automatisation & toolsmithing : opérations de masse en dry_run par défaut (montrent le plan avant d'agir) ; fichiers sensibles exclus partout ; destinations confinées aux racines autorisées ; refus d'écraser un dossier existant. MQTT borné (écoute à timeout dur, payload plafonné, broker local par défaut).
  • Secrets : .env gitignoré, jamais hardcodés ni loggés. Commits signés (ED25519), branch protection sur main.
  • CI : bandit (HIGH), gitleaks, pip-audit --strict, gate coverage 75 %, snapshots contrat MCP/OpenAPI.

Tests & bench

python -m pytest tests/ -q                        # 699 passing
BACKEND=mlx python -m bench.run --category easy    # bench reproductible
BACKEND=mlx python -m bench.router_eval            # précision du routeur (F1 macro)

Commandes CLI

Commande Description
/help Aide
/sessions Liste / charge une session passée
/memory Mémoire courte + souvenirs long terme
/model · /model <id> Modèle actif / change à chaud
/skills Compétences mémorisées
/exit Quitte
python main.py --resume               # reprend la dernière session
python main.py --session <id-court>   # reprend une session précise

Erreurs fréquentes

Symptôme Cause / solution
APIConnectionError (MLX) Lancer ./scripts/start-mlx.sh
Connection refused (Ollama) ollama serve (requis pour les embeddings bge-m3)
model not found (MLX) huggingface-cli download unsloth/Qwen3.6-35B-A3B-MLX-8bit
Le modèle « réfléchit » sans répondre Qwen3.6 est thinkingMLX_CHAT_TEMPLATE_ARGS='{"enable_thinking": false}' dans .env
SandboxViolation Le chemin doit être sous PROJECT_ROOT/ALLOWED_ROOTS (chemins absolus existants)
Outil MCP absent Vérifier KLODY_MCP_SERVERS + serveur lancé, puis redémarrer le backend (config lue au boot)
UI Tauri figée Cmd+Shift+R ; vérifier python api/server.py sur :8000

Documentation

  • 📐 Étude de cas technique — les décisions d'ingénierie (routeur, MCP, sandbox, la saga max_tokens).
  • 🛠️ OPS — exploitation, services permanents (LaunchAgents).
  • 💼 Pour les entreprises — agents IA privés / local-first.

Licence

MIT © 2026 klodynlov

About

Agent IA CLI local — Python + Ollama + qwen2.5-coder:32b

Resources

License

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors