Files

14 KiB

Architecture 3615-KXKM

"Le medium est le message, et ton terminal a deja compris." -- electron rare

"Saboteurs of big daddy mainframe" -- VNS Matrix, 1991

Vue d'ensemble

graph TB
    subgraph Client["Frontend React/Vite — UI Minitel 3615"]
        UI[MinitelFrame CRT]
        Chat[Chat.tsx]
        Voice[VoiceChat push-to-talk]
        Compose[ComposePage + progress bar]
        Imagine[ImaginePage + viewer]
        Media[MediaExplorer gallery/playlist]
        Admin[AdminPage]
    end

    subgraph API["API Express + WebSocket :3333"]
        WS[ws-chat.ts — Handler WS]
        CMD[ws-commands.ts — /compose /imagine /web]
        ROUTER[ws-conversation-router.ts — pickResponders + @mention]
        LLM[ws-ollama.ts — Stream + Tools + Think-strip]
        MULTI[ws-multimodal.ts — TTS HTTP + Vision]
        TOOLS[mcp-tools.ts — web_search, image_generate, rag_search]
        MSTORE[media-store.ts — Persistance media]
        CTX[context-store.ts — Contexte JSONL 4000ch]
        RAG[rag.ts — LightRAG + local fallback]
        REST[Routes REST — session, personas, media]
    end

    subgraph Infra["Services Infrastructure"]
        OLLAMA["Ollama natif :11434\nqwen3:8b · mistral:7b · qwen3-vl:8b"]
        PG[(PostgreSQL 16 :5432)]
        SEARX[SearXNG :8080]
    end

    subgraph MLStack["ML / Génération"]
        TTS[TTS Sidecar :9100\nproxy Chatterbox + Piper fallback]
        CBOX[Chatterbox Docker :9200\nGPU voice cloning]
        LRAG[LightRAG :9621\nGraph RAG knowledge graph]
        COMFY[ComfyUI SDXL\nstable2.kxkm.net]
    end

    subgraph Worker["Worker GPU"]
        ENGINE[Node Engine — DAG exec]
        TRAIN[Training Unsloth/TRL]
    end

    subgraph DAW["openDIAW.be — Audio/Music AI"]
        BRIDGE[AI Bridge :8301\n17 backends]
        KOKORO[Kokoro TTS :9201\n12 voix]
        ACESTEP[ACE-Step :9200\nMusique IA]
        PIPER[Piper/Chatterbox :9100]
        DEMUCS[Demucs + Matchering]
        FFSYNTH[ffmpeg synth\ndrone/grain/glitch/circus/honk]
        OPENDAW[openDIAW.be Studio\n9 instruments DSP]
    end

    subgraph External["Hors cluster"]
        STABLE[StableView :3000\ninterface séparée]
    end

    Chat -- "WS message/command" --> WS
    Voice -- "WS upload audio" --> WS
    Compose -- "WS /compose /drone /kokoro" --> CMD
    Imagine -- "WS /imagine" --> CMD
    Media -- "REST /api/v2/media" --> REST

    WS --> ROUTER --> LLM --> OLLAMA
    ROUTER --> CTX
    ROUTER --> RAG
    LLM -- "tool_call web_search" --> TOOLS --> SEARX
    LLM -- "tool_call image_generate" --> TOOLS --> COMFY
    LLM -- "tool_call rag_search" --> TOOLS --> LRAG
    LLM -- "TTS" --> MULTI --> TTS --> CBOX
    LLM -- "Vision qwen3-vl:8b" --> MULTI --> OLLAMA
    RAG -- "query hybrid" --> LRAG --> OLLAMA
    CMD -- "/imagine" --> COMFY
    CMD -- "/web" --> SEARX
    CMD -- "save" --> MSTORE
    CMD -- "/drone /circus /honk /kokoro" --> BRIDGE
    REST -- "/api/v2/ai-bridge/*" --> BRIDGE
    REST --> PG
    ENGINE --> TRAIN --> OLLAMA
    BRIDGE --> KOKORO
    BRIDGE --> ACESTEP
    BRIDGE --> PIPER
    BRIDGE --> DEMUCS
    BRIDGE --> FFSYNTH
    BRIDGE --> OLLAMA
    OPENDAW -- "fetch AI Bridge" --> BRIDGE

Flux chat — séquence complète

sequenceDiagram
    participant U as User (Browser)
    participant WS as WebSocket Server
    participant PR as pickResponders
    participant Ph as Pharmacius (routeur)
    participant Sh as Sherlock (web_search)
    participant Sp as Spécialiste @mention
    participant CTX as ContextStore
    participant RAG as RAG (LightRAG)
    participant TTS as TTS Sidecar :9100
    participant OL as Ollama

    U->>WS: message "cherche des infos sur Xenakis"
    WS->>WS: broadcast user message to all clients
    WS->>CTX: addToContext(channel, user, text)

    Note over WS,PR: pickResponders: @mention direct → persona mentionnée<br/>sinon → Pharmacius (routeur par défaut)

    WS->>PR: pickResponders(text, personas)
    PR-->>WS: [Pharmacius]

    WS->>CTX: getContextString(channel)
    CTX-->>WS: contexte conversationnel (4000 chars)
    WS->>RAG: search(text, 2 results)
    RAG-->>WS: chunks pertinents du manifeste

    WS->>OL: streamOllamaChat(Pharmacius, enrichedText)
    Note over Ph,OL: Pharmacius: max 2 phrases, no tools<br/>Routage → @Sherlock pour recherche web
    OL-->>WS: stream chunks
    WS->>WS: stripThinking + broadcast "message" (final replaces chunks)
    WS->>CTX: addToContext(channel, Pharmacius, fullText)

    Note over WS: Détecte @Sherlock → inter-persona chain<br/>depth+1, délai 2000ms, max depth=3

    WS->>OL: streamOllamaChatWithTools(Sherlock, contextMessage, [web_search, rag_search])
    OL-->>WS: tool_call: web_search("Xenakis")
    WS->>Sh: executeTool(web_search)
    Sh->>WS: SearXNG query → 5 résultats
    WS->>OL: tool result → continue generation
    OL-->>WS: stream chunks (analyse des résultats)
    WS->>WS: broadcast final message to all clients
    WS->>CTX: addToContext(channel, Sherlock, fullText)

    Note over WS,CTX: Memory update: every 5 messages per persona<br/>LLM extracts facts + summary → data/v2-local/persona-memory/{personaId}.json<br/>(legacy mirror: data/persona-memory/{nick}.json)

    opt TTS_ENABLED=1
        WS->>TTS: POST /synthesize {nick, text}
        TTS->>TTS: Chatterbox GPU :9200 (voice cloning)
        TTS-->>WS: audio WAV
        WS->>U: audio base64 broadcast
    end

Routing Pharmacius → Spécialistes

graph LR
    Ph((Pharmacius<br/>routeur))

    subgraph Son["Son / Musique"]
        Schaeffer[Schaeffer<br/>musique concrète]
        Radigue[Radigue<br/>drones]
        Oliveros[Oliveros<br/>deep listening]
        Eno[Eno<br/>composition]
    end

    subgraph Pensee["Pensée / Philosophie"]
        Batty[Batty<br/>existentiel]
        Foucault[Foucault<br/>pouvoir]
        Deleuze[Deleuze<br/>concepts]
    end

    subgraph Politique["Politique / Résistance"]
        Swartz[Swartz<br/>hacktivisme]
        Bookchin[Bookchin<br/>écologie]
        LeGuin[LeGuin<br/>SF/utopie]
    end

    subgraph Tech["Tech / Science"]
        Turing[Turing<br/>code/hack]
        Hypatia[Hypatia<br/>science]
        Curie[Curie<br/>science]
        Sherlock[Sherlock<br/>web_search]
    end

    subgraph Arts["Arts vivants / Visuels"]
        Merzbow[Merzbow<br/>noise/glitch]
        Cage[Cage<br/>silence]
        Ikeda[Ikeda<br/>data art]
        Picasso[Picasso<br/>image_generate]
        TeamLab[TeamLab<br/>immersif]
        Demoscene[Demoscene<br/>demoscene]
    end

    subgraph Scene["Scène / Corps"]
        RoyalDeLuxe[RoyalDeLuxe<br/>arts de la rue]
        Decroux[Decroux<br/>mime]
        Mnouchkine[Mnouchkine<br/>théâtre]
        Pina[Pina<br/>danse]
        Grotowski[Grotowski<br/>rituel]
        Fratellini[Fratellini<br/>clown]
    end

    subgraph Transversal["Transversal"]
        Haraway[Haraway<br/>cyborg/féminisme]
        SunRa[SunRa<br/>afrofuturisme]
        Bjork[Bjork<br/>pop/nature]
        Fuller[Fuller<br/>design]
        Tarkovski[Tarkovski<br/>cinéma]
        Oram[Oram<br/>électronique/DIY]
    end

    Ph --> Son
    Ph --> Pensee
    Ph --> Politique
    Ph --> Tech
    Ph --> Arts
    Ph --> Scene
    Ph --> Transversal

    style Ph fill:#00e676,color:#000
    style Sherlock fill:#ff7043,color:#000
    style Picasso fill:#ffd54f,color:#000

Services production (kxkm-ai)

# Service Port Type Stack Health Rôle
1 API V2 :3333 Docker Node.js (network_mode: host) GET /api/v2/health Express + WebSocket chat + React SPA
2 PostgreSQL :5432 Docker postgres:16-alpine pg_isready Persistence sessions, personas, graphs
3 SearXNG :8080 Docker searxng/searxng wget / Recherche web self-hosted (Google, Bing, DDG)
4 Chatterbox :9200 Docker GPU ghcr.io/devnen/chatterbox-tts-server GET /get_predefined_voices TTS voice cloning GPU
5 TTS Sidecar :9100 systemd Python (network_mode: host) — Proxy Chatterbox + Piper fallback
6 LightRAG :9621 Docker Python 3.12 (lightrag-hku, network_mode: host) GET /health Graph RAG, knowledge graph (Ollama backend)
7 Ollama :11434 Natif RTX 4090 (systemd) GET /api/tags LLM inference: qwen3:8b, mistral:7b, qwen3-vl:8b
8 Worker host Docker Node.js (GPU passthrough) — Node Engine DAG execution, training
9 Docling :9400 Docker Python (Docling REST) GET /health PDF/document parsing (tables, layout, OCR)
10 Reranker :9500 Docker Python (bge-reranker-v2-m3) GET /health Cross-encoder reranking for RAG results
11 ComfyUI ext Externe stable2.kxkm.net — Image gen SDXL
12 StableView :3000 Externe Séparé — Interface visualisation (hors cluster)
13 Discord Bot — Docker Node.js (network_mode: host) — Bridge chat KXKM → Discord
14 Discord Voice — Docker Node.js + Python STT — STT → Personas → TTS en vocal

Command Flow

graph TD
    User[User Input] --> Parser{Message Type?}
    Parser -->|/command| CommandHandler
    Parser -->|message| ChatHandler
    Parser -->|upload| UploadHandler

    CommandHandler --> |/web| SearXNG[SearXNG :8080]
    CommandHandler --> |/imagine| ComfyUI[ComfyUI SDXL]
    CommandHandler --> |/compose| ACEStep[ACE-Step via TTS :9100]
    CommandHandler --> |/status| PerfMetrics[Perf Metrics + nvidia-smi]
    CommandHandler --> |/memory| PersonaMemory[Persona Memory JSON]
    CommandHandler --> |/models| OllamaAPI[Ollama /api/tags + /api/ps]
    CommandHandler --> |/context| ContextStore[Context Store JSONL]
    CommandHandler --> |/join /channels| ChannelMgr[Channel Manager]
    CommandHandler --> |/nick /who| UserMgr[User Manager]
    CommandHandler --> |/reload| PersonaDB[Persona DB Refresh]

    ChatHandler --> pickResponders[pickResponders]
    pickResponders --> TopicRouting[Pharmacius Topic Routing]
    TopicRouting --> OllamaStream[Ollama Stream + Tools]
    OllamaStream --> ChunkBroadcast[Chunk Broadcast seq++]
    OllamaStream --> InterPersona{@mention detected?}
    InterPersona -->|yes, depth < 3| pickResponders

    UploadHandler --> MIMEValidation[MIME Magic Bytes]
    MIMEValidation -->|image/*| Vision[Vision qwen3-vl:8b]
    MIMEValidation -->|audio/*| STT[STT faster-whisper]
    MIMEValidation -->|text/* pdf| TextExtract[Text Extraction]
    MIMEValidation -->|office| Docling[Docling :9400]
    Vision --> ChatHandler
    STT --> ChatHandler
    TextExtract --> ChatHandler
    Docling --> ChatHandler

Data Flow

graph LR
    Chat[Chat Message] --> Context[Context Store JSONL]
    Chat --> RAG[RAG Search]
    RAG --> Embeddings[nomic-embed-text]
    RAG --> LightRAG[LightRAG :9621]
    RAG --> Reranker[bge-reranker :9500]
    Chat --> Memory[Persona Memory JSON]
    Memory -->|every 5 msgs| Ollama[Ollama qwen3:8b]
    Context -->|compaction| Ollama
    Chat --> Log[Chat Log JSONL]
    Log --> Analytics[/api/v2/analytics]
    Log --> DPO[DPO Export]
    Log --> HTMLExport[HTML Export]

Feature Map

mindmap
  root((3615 KXKM))
    Chat
      WebSocket temps réel
      33 personas IA
      Routing @mention inter-persona
      Contexte conversationnel 4000ch
      RAG manifeste
      Historique JSONL
      Tab-completion nicks/commands
      Sidebar personas collapsible
    Voix
      Push-to-talk (maintenir)
      STT faster-whisper
      TTS piper-tts 26 voix
      Level meter temps réel
      Auto-stop silence 2s
      Audio queue + replay
    Génération
      /compose ACE-Step musique
      /imagine ComfyUI SDXL
      Progress bars animées
      Persistance media (disk)
      Médiathèque gallery/playlist
    Admin
      Node Engine (DAG graphs)
      Training LoRA/QLoRA
      DPO pipeline
      Analytics chat
      Persona CRUD + feedback
    Infrastructure
      Docker Bookworm + Python
      Ollama natif (RTX 4090)
      PostgreSQL 16
      SearXNG self-hosted
      TTS sidecar HTTP
      Discord bot bridge
    UI
      Minitel 1B fullscreen
      Mosaïques VIDEOTEX
      CRT scanlines + vignette
      Raccourcis F1-F7
      Responsive 4 breakpoints
      Animation modem 3615

Modules (LOC)

Module LOC Tests Rôle
apps/api 5200 1000 Backend API + WebSocket
apps/web 4800 800 Frontend React
apps/worker 956 230 Worker GPU Node Engine
packages/core 172 86 Types, IDs, permissions
packages/auth 159 157 Scrypt, sessions, RBAC
packages/chat-domain 262 279 Messages, channels, commands
packages/persona-domain 988 259 Personas, feedback, editorial
packages/node-engine 1499 605 DAG execution, training
packages/storage 1219 669 PostgreSQL repos
packages/ui 134 29 Theme, colors, CSS vars
packages/tui 209 108 ANSI formatting, tables
scripts 37 fichiers - TTS, training, migration
Total ~15600 425 tests

Bugs critiques identifiés (audit 2026-03-18)

# Sévérité Module Description
1 HIGH context-store.ts Race condition sur enforceLimits pendant compaction
2 MEDIUM ws-conversation-router.ts Maps persona unbounded (memory leak)
3 MEDIUM ws-commands.ts Temp files non nettoyés si compose timeout
4 MEDIUM Chat.tsx Memory leak /ulla (setTimeout non tracked)
5 MEDIUM ComposePage/ImaginePage WebSocket non fermé au unmount
6 LOW AdminPage.tsx Champ password UI mort (jamais envoyé)
7 LOW routes/session.ts Token comparison timing-attack (===)

Env vars

Variable Default Requis
V2_API_PORT 4180 Non
OLLAMA_URL localhost:11434 Non
DATABASE_URL - Prod only
TTS_ENABLED 0 Non
TTS_URL localhost:9100 Non
VISION_MODEL qwen3-vl:8b Non
COMFYUI_URL stable2.kxkm.net Non
SEARXNG_URL localhost:8080 Non
LIGHTRAG_URL localhost:9621 Non
RERANKER_URL localhost:9500 Non
PYTHON_BIN python3 Non
MAX_OLLAMA_CONCURRENT 3 Non
MAX_GENERAL_RESPONDERS 1 Non
ADMIN_TOKEN - Non
ADMIN_SUBNET - Non
ADMIN_BOOTSTRAP_TOKEN - Non
KXKM_LOCAL_DATA_DIR data Non
WEB_DIST_PATH apps/web/dist Non
NODE_ENV - Non
DEBUG 0 Non