33800 Docs

← Retour

Proposition : Ulias Org — Conversations + Intelligence + Microservices

Date : 14/02/2026 00:00 Status : EN ATTENTE VALIDATION

Vision

Transformer ulias-org d'un outil technique d'orchestration en un assistant conversationnel intelligent capable de :

Philosophie : contrecarrer la complexité par des microservices spécialisés. Chaque brique fait une chose bien, l'intelligence est dans l'orchestration.

Architecture cible

┌─────────────────────────────────────────────────────────────────────┐
│                         UTILISATEUR (CEO)                            │
│                                                                      │
│   Chat Web ◄──────────► ntfy push ◄──────────► Mobile/Desktop       │
│   (ulias-web)            (notifications)                             │
└───────────┬─────────────────────────────────────────────────────────┘
            │
            ▼
┌─────────────────────────────────────────────────────────────────────┐
│                    CONVERSATIONS SERVICE                              │
│                                                                      │
│   ┌──────────────┐  ┌──────────────┐  ┌──────────────┐             │
│   │ Conversations│  │  Messages    │  │ Attachments  │             │
│   │ (threads)    │  │  (history)   │  │ (files)      │             │
│   └──────────────┘  └──────────────┘  └──────────────┘             │
│                                                                      │
│   - CRUD conversations                                               │
│   - Persist tous les messages (user + agent + events)                │
│   - Sidebar avec liste conversations                                 │
│   - Recherche full-text dans l'historique                            │
│   - Fichiers joints par conversation                                 │
└───────────┬─────────────────────────────────────────────────────────┘
            │
            ▼
┌─────────────────────────────────────────────────────────────────────┐
│                    INTELLIGENCE LAYER                                 │
│                                                                      │
│   ┌──────────────┐  ┌──────────────┐  ┌──────────────┐             │
│   │  Classifier  │  │   Memory     │  │   Context    │             │
│   │  (triage)    │  │ (embeddings) │  │  (window)    │             │
│   └──────────────┘  └──────────────┘  └──────────────┘             │
│                                                                      │
│   Classifier : analyse le message et décide du mode                  │
│   ┌─────────────────────────────────────────────────┐               │
│   │  "quelle heure est-il ?"     → LIVE (réponse directe)          │
│   │  "check docker status"       → LIVE (1 tool call, <30s)        │
│   │  "crée-moi un site pizza"    → BRIEFING (clarification)        │
│   │  "analyse les logs du mois"  → ASYNC (solo, notifie quand fini)│
│   │  "déploie la nouvelle version"→ APPROVAL (demande permission)  │
│   └─────────────────────────────────────────────────┘               │
│                                                                      │
│   Memory : mémoire longue via embeddings (pgvector + nomic)         │
│   - Indexe chaque conversation terminée                              │
│   - Rappelle les contextes pertinents dans les futurs échanges      │
│   - "la dernière fois tu m'as dit que..." → retrouve le contexte    │
│                                                                      │
│   Context : fenêtre de contexte pour le LLM                         │
│   - Derniers N messages de la conversation en cours                  │
│   - Profil CEO (préférences, style, habitudes)                       │
│   - Résumé des conversations récentes pertinentes (via Memory)       │
└───────────┬─────────────────────────────────────────────────────────┘
            │
            ▼
┌─────────────────────────────────────────────────────────────────────┐
│                    ORCHESTRATION (ulias-org existant)                 │
│                                                                      │
│   Interpreter → Agent Router → Agent Executor → Tool Calls          │
│                                                                      │
│   31 agents, 8 teams, 36 tools                                       │
│   Pipelines : verification_chain, code_and_deploy, create_*         │
│   Mode briefing pour projets complexes                               │
└───────────┬─────────────────────────────────────────────────────────┘
            │
            ▼
┌─────────────────────────────────────────────────────────────────────┐
│                    SERVICES (microservices existants)                 │
│                                                                      │
│   connectors-api    │ ai-orchestrator  │ browser-connector           │
│   (31 APIs, SSH,    │ (GPU routing,    │ (web scraping,              │
│    VPN, Supabase)   │  10 outils IA)   │  LinkedIn)                  │
│                     │                  │                              │
│   GitLab CI/CD      │ Notifications    │ Supabase (BDD)              │
│   (code, deploy)    │ (ntfy, mail)     │ (data, auth, storage)       │
└─────────────────────────────────────────────────────────────────────┘

Plan en 3 phases


Phase 1 : Conversations (fondation)

Objectif : tout ce qui se dit est sauvegardé, on retrouve ses échanges.

1a. Schema DB — nouvelles tables

-- Conversations (threads)
CREATE TABLE agents.conversations (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  user_id TEXT NOT NULL,
  title TEXT,                    -- Auto-généré depuis le 1er message, éditable
  created_at TIMESTAMPTZ DEFAULT now(),
  updated_at TIMESTAMPTZ DEFAULT now(),
  last_message_at TIMESTAMPTZ,
  message_count INT DEFAULT 0,
  status TEXT DEFAULT 'active',  -- active, archived
  summary TEXT,                  -- Résumé auto (embedding source)
  metadata JSONB DEFAULT '{}'    -- tags, pinned, etc.
);

-- Chat messages (distinct de agents.messages qui est pour le debug LLM)
CREATE TABLE agents.chat_messages (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  conversation_id UUID NOT NULL REFERENCES agents.conversations(id) ON DELETE CASCADE,
  user_id TEXT NOT NULL,
  role TEXT NOT NULL,             -- user, assistant, system, event
  content TEXT,
  event_type TEXT,                -- objective_created, routing, tool_call, complete, etc.
  event_data JSONB,              -- Données brutes de l'événement
  objective_id UUID,             -- Lien vers l'objectif si applicable
  attachments JSONB DEFAULT '[]', -- [{name, url, type, size}]
  created_at TIMESTAMPTZ DEFAULT now()
);

CREATE INDEX idx_chat_messages_conv ON agents.chat_messages(conversation_id, created_at);
CREATE INDEX idx_conversations_user ON agents.conversations(user_id, updated_at DESC);

1b. Backend — endpoints conversations

Endpoint Méthode Description
/api/conversations GET Liste conversations (sidebar)
/api/conversations POST Nouvelle conversation
/api/conversations/:id GET Détails conversation
/api/conversations/:id PATCH Rename, archive
/api/conversations/:id DELETE Supprimer
/api/conversations/:id/messages GET Messages paginés

1c. Backend — persistance des messages

1d. Frontend — sidebar + conversations

┌──────────────────────────────────────────────────┐
│ [+] Nouvelle conversation                         │
│──────────────────────────────────────────────────│
│ 📌 Check Docker status          14/02 00:15      │
│ Création site pizza              13/02 21:30      │
│ Analyse logs nginx               13/02 19:00      │
│ ...                                               │
│──────────────────────────────────────────────────│
│              ZONE CHAT                            │
│                                                   │
│  [messages de la conversation sélectionnée]       │
│                                                   │
│──────────────────────────────────────────────────│
│ [📎] [Envoyer un message...]              [➤]    │
└──────────────────────────────────────────────────┘

1e. Fichiers à modifier

Projet Fichier Changement
ulias-org packages/server/src/db/schema.sql Tables conversations + chat_messages
ulias-org packages/server/src/db/index.ts CRUD conversations + messages
ulias-org packages/server/src/ws/handler.ts Sauvegarder messages dans chat_messages
ulias-org packages/server/src/routes/ Nouveaux endpoints conversations
ulias-org-web src/routes/index.tsx Refacto → sidebar + conversation view
ulias-org-web src/components/sidebar/ Nouveau composant sidebar conversations
ulias-org-web src/routes/layout.tsx Intégrer sidebar dans le layout

Phase 2 : Intelligence (cerveau)

Objectif : le système comprend le contexte, se souvient, et décide seul du mode d'exécution.

2a. Classifier de messages

Au lieu de tout envoyer à l'Interpreter (LLM lourd), un premier tri rapide :

type MessageMode = 'live' | 'briefing' | 'async' | 'approval' | 'chat';

function classify(message: string, context: ConversationContext): MessageMode {
  // Patterns rapides (sans LLM)
  if (isSimpleQuestion(message))     return 'chat';      // "ça va ?", "merci"
  if (isQuickAction(message))        return 'live';      // "docker ps", "status"
  if (isProjectCreation(message))    return 'briefing';  // "crée un site"
  if (needsPermission(message))      return 'approval';  // "supprime", "redémarre"

  // Heuristique sur la complexité estimée
  if (estimatedDuration(message) > 60) return 'async';   // > 1 min → mode solo

  return 'live'; // Défaut : réponse en direct
}

Comportement par mode : | Mode | Comportement | Notification | |------|-------------|--------------| | chat | Réponse LLM directe (pas d'agent, juste conversation) | Non | | live | Agent exécute, événements en temps réel dans le chat | Non | | briefing | Questions de clarification avant exécution | Non | | async | Agent travaille en solo, résultat affiché plus tard | ntfy quand fini | | approval | Demande d'approbation avant action destructive | ntfy si urgent |

2b. Mémoire conversationnelle (embeddings)

Utiliser pgvector + nomic-embed-text (déjà dispo sur GPU1) :

-- Ajouter colonne embedding aux conversations
ALTER TABLE agents.conversations ADD COLUMN embedding vector(768);

-- Index pour recherche de similarité
CREATE INDEX idx_conv_embedding ON agents.conversations
  USING ivfflat (embedding vector_cosine_ops) WITH (lists = 20);

Flow :

  1. Conversation terminée → résumer en 2-3 phrases
  2. Résumé → embedding via nomic-embed-text (GPU1)
  3. Stocker dans conversations.embedding
  4. Nouvelle conversation → embed la question → chercher les conversations similaires
  5. Injecter le contexte pertinent dans le system prompt de l'agent

Exemple :

User: "remets en place le site pizza comme la dernière fois"
→ Embedding → Recherche similarité → Trouve conversation "Création site pizza" du 13/02
→ Injecte le résumé dans le contexte de l'agent
→ L'agent sait exactement quoi faire

2c. Contexte fenêtre

Pour chaque appel LLM, construire un contexte riche :

function buildContext(conversationId: string, userId: string): SystemContext {
  return {
    // Conversation en cours (derniers 20 messages)
    recentMessages: getRecentMessages(conversationId, 20),

    // Profil CEO (préférences apprises)
    profile: getCeoProfile(userId),

    // Conversations similaires (top 3 par embedding)
    relatedConversations: searchSimilarConversations(currentMessage, 3),

    // État système (résumé)
    systemState: {
      activeObjectives: getActiveObjectives(userId),
      recentCompletions: getRecentCompletions(userId, 5),
    }
  };
}

2d. Notification bridge (async → ntfy)

Quand un objectif async se termine :

// Dans le job completion handler
if (objective.mode === 'async') {
  await notify({
    title: `✅ ${objective.title}`,
    body: truncate(result, 200),
    click: `https://ulias-web.33800.nowhere84.com/?conv=${conversationId}`,
    priority: 'default'
  });
}

Quand l'agent a besoin d'input :

if (decision.urgency === 'high' || decision.urgency === 'critical') {
  await notify({
    title: `⚠️ Décision requise`,
    body: decision.question,
    click: `https://ulias-web.33800.nowhere84.com/decisions`,
    priority: 'high'
  });
}

Phase 3 : Création universelle (usine)

Objectif : créer tout type de support numérique depuis une conversation.

3a. Pipelines de création (étendre les existants)

Pipeline Agents Résultat
create_frontend gitlab-dev → qwik-dev → pg-dev App Qwik + repo GitLab
create_backend gitlab-dev → elysia-dev → pg-dev API Elysia + repo GitLab
create_fullstack gitlab-dev → elysia-dev → pg-dev → qwik-dev App complète
create_static storage-dev → qwik-dev → storage-dev Site statique (Supabase Storage)
create_script coder Script autonome (bash, python, etc.)
create_document documenter Doc markdown, PDF, rapport
create_config coder → deployer Config infra (nginx, docker, CI/CD)
create_automation coder → deployer Cron, webhook, routine planifiée

3b. Asset management

Chaque création produit des assets liés à la conversation :

CREATE TABLE agents.conversation_assets (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  conversation_id UUID REFERENCES agents.conversations(id),
  user_id TEXT NOT NULL,
  asset_type TEXT NOT NULL,  -- repo, file, site, script, document
  name TEXT NOT NULL,
  url TEXT,                  -- URL de l'asset (GitLab, Supabase Storage, etc.)
  metadata JSONB DEFAULT '{}',
  created_at TIMESTAMPTZ DEFAULT now()
);

Affiché dans le chat comme une carte spéciale :

┌─────────────────────────────────────┐
│ 📦 Projet créé : pizza-site         │
│ GitLab : https://gitlab.../pizza    │
│ URL : https://pizza.33800.no...     │
│ [Voir] [Modifier] [Supprimer]       │
└─────────────────────────────────────┘

3c. Itération conversationnelle

Le vrai pouvoir : itérer sur les créations via la conversation.

User: "crée-moi un site vitrine pour ma pizzeria"
→ Briefing (5 questions : nom, style, pages, couleurs, contenu)
→ Pipeline create_frontend → site déployé

User: "ajoute une page menu avec les prix"
→ Contexte conversation → sait quel projet, quel repo
→ Agent modifie le code → push → déploiement auto

User: "change le rouge en bleu"
→ Idem, modification ciblée

User: "ajoute un formulaire de commande"
→ Classifier détecte que c'est plus complexe (backend nécessaire)
→ Propose d'ajouter un backend API
→ Pipeline create_backend en complément

Priorité d'implémentation

Phase Effort Impact Dépendances
1a-1c : Schema + endpoints conversations 2-3h HAUT Aucune
1d : Frontend sidebar + persistence 3-4h HAUT 1a-1c
1e : Auto-titre conversations 30min MOYEN 1a-1c
2a : Classifier de messages 2h HAUT Phase 1
2b : Mémoire embeddings 2-3h HAUT Phase 1
2c : Contexte fenêtre 1-2h HAUT 2b
2d : Notification bridge async 1h MOYEN Phase 1
3a : Nouveaux pipelines 2-3h MOYEN Phase 2
3b : Asset management 2h MOYEN Phase 1
3c : Itération conversationnelle 3-4h TRES HAUT Phase 2 + 3b

Total estimé : ~20-25h réparties sur les 3 phases.

Phase 1 seule rend déjà l'outil utilisable au quotidien.

Risques

Validation requise