# Changelog — FlowDeck ## v4.15.2 (2026-09-06) — Agent : skills multi-épinglés en bulles + chips de contexte cliquables > Les skills s'épinglent désormais au contexte **comme les mentions @** (bulles « / » purples dans > l'éditeur du chat), on peut en associer **plusieurs** à un même post, et chaque bulle de contexte > référencée s'ouvre d'un clic comme document courant. ### Améliorations - **Skills en bulles** : sélectionner un skill (menu `/`, intégré *ou* enregistré) ajoute une vraie bulle dans le composer, comportement identique aux mentions `@`. La bulle d'un skill intégré greffe son modèle de demande dans le texte ; plusieurs skills peuvent coexister. - **Plusieurs skills par post** : l'API `/run` accepte `skill_ids` (tableau) et l'engine injecte tous leurs prompts dans les instructions système (`skill_id` reste supporté pour la rétro-compatibilité). - **Chips de contexte cliquables** : cliquer sur une bulle de contexte (`@ document / page / base`) ouvre l'élément comme document courant — `document:`/`page:` → `/pages/`, `collection:` → `/db/`. Le bouton « ✕ » retire toujours la bulle (sans ouvrir). - Envoi possible avec uniquement des skills (sans texte) : « Applique le(s) skill(s) sélectionné(s)… ». ### Correctifs - L'écriture du chat (`send`) renvoie désormais tous les `skill_id` épinglés via `skill_ids`. ## v4.15.1 (2026-09-06) — Agent : réparation des conversations réelles (protocole tool_calls) > Le chatbot ne « répondait » plus : avec un fournisseur réel, dès qu'un **outil** était appelé la passe > suivante était refusée par l'API (message assistant sans ses `tool_calls`) et l'agent retombait > silencieusement sur le **mock hors-ligne**, qui se contentait de répéter la question. ### Correctifs - **Protocole tool-calling conforme** (`agent_engine.py`) : le message assistant qui annonce un appel d'outil transporte désormais ses `tool_calls` (avec `id`), et chaque résultat d'outil répond avec le `tool_call_id` correspondant (y compris en cas de refus/permission). Le run se poursuit alors correctement et se termine par une vraie réponse du modèle. - **Plus de repli silencieux** (`llm_client.py`) : quand un fournisseur **réel** configuré échoue, l'erreur remonte (événement SSE `error`) au lieu de produire silencieusement un écho hors-ligne. Le mock n'est utilisé que si le fournisseur est réellement non configuré (`offline` / pas de clé). - Les `tool_calls` analysés conservent leur `id` et les arguments bruts (`arguments_raw`). - Test de régression `test_engine_tool_protocol_messages`. ## v4.15.0 (2026-09-06) — Agent : actions sous chaque réponse, mentions @ & skills / > Le panneau FlowDeck Agent gagne l'expérience « type Notion AI » : chaque réponse de l'agent expose > des actions rapides (copier, insérer dans la page, feedback 👍/👎), on peut **épingler au contexte** > plusieurs documents / pages / bases via la commande **@** (ou le bouton **+**), et la commande **/** > propose des **skills** de travail réutilisables en plus des commandes admin existantes. ### Sous chaque réponse de l'agent - **⧉ / ➕ / 👍 / 👎** : boutons **à icônes seules** (infobulle au survol) — copier la réponse, insérer dans la page ouverte, feedback 👍/👎 enregistré en base. - Le bandeau statique « Contexte : … » du haut du panneau est supprimé. ### Contexte épinglé — commande « @ » / bouton « + » (style Notion AI) - Le composeur est maintenant un éditeur **contenteditable** : les références sélectionnées s'insèrent **inline** comme des pastilles cliquables (icône + nom) directement dans le message. - Au-dessus du composeur, une **barre de contexte groupée** rassemble les fichiers épinglés (rangée documents, icônes 📄) et les **skills** (rangée séparée, icône ✨), chacun retirable. - **@** ouvre le sélecteur (icône + titre + chemin) listant documents, pages et bases ; l'élément choisi devient un jeton inline **et** une puce de contexte. **+** épingle un élément au contexte sans l'insérer inline. Les puces persistent jusqu'au retrait (et sont vidées en nouveau chat). - **Contexte d'ouverture** : ouvrir l'agent sur un document (`/pages/:id`) ou une base (`/db/:id`) ajoute automatiquement ce contexte comme **mention** (puce épinglée) — plus de bandeau statique. - À l'envoi, chaque référence est transmise comme **mention** ; le backend résout son **contenu réel**. ### Skills — commande « / » - Le menu **/** liste les **skills intégrés** (research, resume, brainstorm, plan, meeting-note, livrable…), les **skills enregistrés** (table `agent_skills`) et les commandes admin classiques. - Un skill intégré pré-remplit le composeur d'un modèle à compléter ; un skill en base s'épingle en chip et est appliqué via `skill_id` à chaque envoi. - Navigation clavier (↑/↓/Entrée/Échap) dans les menus ; aucun envoi parasite pour « / » seul. ### Infra & API - Nouvelle table `agent_feedback` (rating, conversation/message, extrait, commentaire). - `GET /api/agent/mentions?q=` : recherche des éléments mentionnables du workspace. - `POST /api/agent/feedback` : enregistre un retour 👍/👎. - `VERSION` → 4.15.0 ; `app/main.py` version → 4.15.0. ## v4.14.0 (2026-09-06) — Agent : création de documents dans un espace + nouveaux outils & titre auto > L'agent sait enfin **créer, lire, modifier et supprimer des documents** (pages éditeur) **dans un > espace de travail** — la demande « crée un document « Projet » dans le workspace « TEST WS 1 » » > ne se termine plus par un simple `search_workspace` vide. Il liste aussi les espaces, et **renomme > automatiquement les conversations** avec un titre descriptif au lieu de « Nouvelle conversation ». ### Outils (nouveaux / corrigés) - **`create_document`** : crée une page éditeur (`pages`) dans un espace (par `workspace_id` ou `workspace_name`), avec contenu Markdown optionnel — snapshot d'undo. - **`read_document`** : lit un document (titre + contenu + métadonnées). - **`read_workspaces`** : liste les espaces accessibles (rôle, nb de documents/collections). - **`delete_document`** : suppression → corbeille (`deleted_at`), annulable (`softdelete`). - **`write_blocks`** étendu : renommage de titre et/ou écriture des blocs ; undo restaure titre + contenu. - **`search_workspace`** étendu : recherche désormais aussi les **documents** et les **espaces de travail**. ### Contexte & planification - Contexte de l'agent enrichi : sections « Documents » et « Espaces de travail » (avec ids) pour que le LLM cible le bon espace. Guide mis à jour. Mock hors-ligne : détection « créer un document dans un espace » / « lister les espaces ». ### Conversations - Auto-titre : après la première exécution d'une conversation encore nommée « Nouvelle conversation », l'agent génère un titre descriptif (déterministe, hors-ligne sûr) ; l'historique devient navigable. ### UX - Indication claire dans le composeur du panneau : **Entrée ↵ = envoyer · Maj+Entrée = nouvelle ligne** (le comportement existait déjà, il est maintenant visible + placeholder mis à jour). ### Infra - `VERSION` → 4.14.0 ; `app/main.py` version → 4.14.0. ## v4.13.2 (2026-09-06) — Saisie libre « écrire un texte » → proposition à appliquer au document > Quand un **document est ouvert** et qu'on tape directement une demande de **rédaction/contenu** > dans le chat (« Écrire un texte sur… », « Rédige… », « Résume… », « Traduis… »), la requête est > maintenant routée vers la **génération de texte** (sans outils) et affichée comme **proposition > à appliquer ou rejeter** — au lieu d'un `search_workspace` puis d'un simple « Objectif traité ». > « Traduire » remplace le contenu de la page ; les autres demandes l'insèrent en fin de page. ### Fix - Envoi libre avec contexte document : détection d'intention de contenu (écrire/rédiger/générer/ résumer/traduire/améliorer/note de réunion/texte sur/série…) → `POST /api/agent/generate` + aperçu « ✓ Appliquer au document / ✕ Rejeter ». - Mock : « écrire » (infinitif) reconnu comme verbe de rédaction. ### Infra - `VERSION` → 4.13.2 ; `app/main.py` version → 4.13.2. ## v4.13.1 (2026-09-06) — Corrections actions contenu Agent & aperçu à approuver > Corrige les actions de contenu sur document (« Résumer », « Traduire cette page », « Proposer > des améliorations », « Créer une note de réunion ») qui partaient en recherche (`search_workspace`) > sans retour utile, et ajoute un flux **aperçu des changements → Appliquer / Rejeter**. ### Fix - **Le contenu du document n'est plus interprété comme des intentions d'outil** : le planificateur (mock) n'analyse que l'objectif de l'utilisateur, jamais le texte injecté dans `# Contexte`. Un document contenant « recherche », « collection », etc. ne déclenche plus `search_workspace` / `create_collection` intempestifs. - **Ask AI** n'emprunte plus le canal outil : il utilise la génération de texte directe. ### Added - **Endpoint `POST /api/agent/generate`** : génération de texte **sans outils** (l'IA répond à partir du contexte du document fourni, sans chercher/créer dans le workspace). - **Aperçu & approbation** : les actions de contenu sur document affichent la **proposition** de l'agent dans le panneau avec boutons **« ✓ Appliquer au document » / « ✕ Rejeter »**. Appliquer insère la proposition (mode `insert`) ou **remplace** le contenu de la page (mode `replace` pour « Traduire cette page ») via `window.fdApplyDocument()` ; rejeter la conserve sans modification. En mode hors-ligne, l'action explique que la modification nécessite un modèle connecté (pas d'application accidentelle). ### Infra - `VERSION` → 4.13.1 ; `app/main.py` version → 4.13.1. ## v4.13.0 (2026-09-06) — Agent : panneau « Notion AI », ouverture fiable (Ctrl+J) & contexte universel > Refonte complète du panneau Agent (style Notion AI) : ouverture/fermeture **fiable** (API > `window.fdAgent.open/close/toggle`, bouton flottant + sidebar « Agents » + raccourci `Ctrl/Cmd+J`), > **contexte détecté et épinglé à l'ouverture** (document en cours, bibliothèque, My Tasks, > espaces, base de données, board, corbeille…) et sélecteur **fournisseur + modèle** intégré à la > zone de saisie. ### Added - **Ouverture robuste** : `window.fdAgent.open()/close()/toggle()` appliquent l'état directement (classe `.open` + attribut) ; FAB, entrée « Agents » du sidebar, icône Chat et `fdAgent.ask` ouvrent explicitement le panneau (fini le toggle silencieux). Raccourci **`Ctrl/Cmd+J`** global. - **Contexte universel `window.FlowDeckCtx`** : détection par priorité — (1) marqueur d'écran (`window.fdViewContext` / `data-fd-context`), (2) **document ouvert** (éditeur : titre + contenu des blocs), (3) **route** de l'application (Accueil, Bibliothèque, Corbeille, My Tasks, Espaces, Espace local/Gitea, Base `/db`, Board, Notes, Paramètres…). Le contexte est **épinglé à l'ouverture** du panneau, affiché en chip (« Contexte : … ») et **rafraîchi** automatiquement si l'utilisateur ouvre un autre document avant d'envoyer. - **Fournisseur & modèle affichés** : sous-titre du panneau `Provider · Modèle` (ex. `OpenAI · gpt-4o`) dès qu'un modèle réel fonctionnel est sélectionné ; « hors-ligne (mock) » n'apparaît que lorsqu'aucun fournisseur actif n'existe. Sélecteurs provider → modèle regroupés dans une pastille « Auto · » au-dessus de la zone de saisie. - **Actions rapides contextuelles** (état vide) en français selon la section : Résumer / Traduire / Améliorer un document, Créer une note de réunion, Analyser une base, Mes tâches / planifier, ou guides « Comment utiliser FlowDeck ? » et création de collection/board. ### Changed - **Panneau redessiné façon Notion AI** : largeur 470 px, en-tête « How can I help you today? », icône avatar, ligne de contexte, historique, grande `textarea` arrondie auto-redimensionnable (jusqu'à ~220 px) avec toolbar (`+`-équivalent, contexte, modèle, flèche d'envoi) et sélection de modèle en popover. ### Infra - `VERSION` → 4.13.0 ; `app/main.py` version → 4.13.0. ## v4.12.1 (2026-09-05) — Corrections configuration Agent & IA + AI Meeting Note > Correctifs UI sur la section **Settings → Agent & IA** et remplacement de l'ancien bouton > « AI meeting note » (qui insérait du texte) par une vraie **boîte de réunion interactive**. ### Fix - **Champs « Clé API »** : le `x-text` embarquait le SVG de l'icône œil dans l'attribut HTML, ce qui cassait l'attribut et laissait du texte résiduel (`sk-…': '👁'" style="top:50%;">`). Les boutons d'affichage/masquage utilisent désormais deux `` avec l'icône en contenu. - **Champs « URL API »** : pré-remplis avec l'URL réellement utilisée par l'application (base par défaut du fournisseur, ex. `https://api.openai.com/v1`) quand aucune URL personnalisée n'est stockée — exposée via `base_url` dans `/api/agent/providers` (fournisseur par défaut + au changement de provider). ### Changed - **AI Meeting Note** : le bouton « Get started » ne génère plus du texte via l'agent. Il crée un bloc **`meeting`** interactif dans la page (page renommée « Meeting @date » si vide) : - Étape 1 — consentement (moi-même / message audio auto) + « Start transcribing » ; - Étape 2 — transcription **live** via Web Speech API (fr-FR, horodatée), boutons Pause / Stop, fallback « sans audio » (transcript à saisir/coller) si le navigateur ne supporte pas ; - Étape 3 — onglets Notes / Transcript / Summary, bouton « Générer le résumé » (helper headless `window.fdAgent.generate` sur le FlowDeck Agent) produisant Résumé / Décisions / Action items, copie presse-papiers et « Nouvelle transcription ». - Persistance du bloc et de son état dans la page (champ `meeting` ajouté aux blocs sauvegardés). ### Infra - `VERSION` → 4.12.1 ; `app/main.py` version → 4.12.1. ## v4.12.0 (2026-09-05) — Agent & IA : refonte des réglages, fournisseurs activés/fonctionnels dans le panneau, contexte document & guide > Refonte de la section **Settings → Agent & IA** pour la rendre plus claire, et aligne le panneau > Agent sur la réalité de la configuration : **seuls les fournisseurs configurés ET dont le test de > connexion a réussi** sont proposés (avant, tous les fournisseurs connus apparaissaient, même non > configurés). Le panneau sait aussi sur quel **document** l'utilisateur travaille et peut guider > sur l'utilisation de l'application quand aucun document n'est ouvert. ### Added - **Vérification des fournisseurs** : colonnes `verified` / `verified_at` / `last_error` sur `user_llm_keys` et `llm_config` (migration automatique au démarrage). Un fournisseur est « fonctionnel » après un test de connexion réussi ou un chargement de modèles réussi. - **Endpoint non-admin** `POST /api/agent/keys/{provider}/test` : teste la clé enregistrée de l'utilisateur (sans mock) et met à jour l'état `verified` ; l'endpoint admin `/providers/test` marque le fournisseur par défaut de l'espace. - **`/api/agent/providers` enrichi** : chaque provider expose `configured`, `verified`, `functional`, `last_error` et `source` (user/global/open) ; `default_provider` + `default_verified` en tête de réponse. - **Panneau Agent** : les listes fournisseur/modèle ne contiennent plus que les providers **activés et fonctionnels** (+ mode hors-ligne). Bandeau « Aucun fournisseur activé » avec lien vers les réglages et rappel des clés « à tester » le cas échéant. - **Contexte document** : le panneau joint automatiquement la page ouverte (titre + contenu des blocs) à chaque requête — l'agent peut interagir avec le document courant. - **Guide d'utilisation** : le prompt système intègre un guide FlowDeck concis pour répondre aux questions « comment faire… ? » (pages, collections/vues, Gitea, corbeille, réglages…) lorsqu'aucun document n'est fourni. ### Changed - **Settings → Agent & IA refondu** : carte de statut (prêt / N fournisseurs actifs / mode hors-ligne), cartes de fournisseurs avec badges d'état, erreur du dernier test, boutons « Enregistrer & tester », « Tester », « Modèles », « Supprimer » et encart d'aide. - Le bouton **Save configuration** admin gagne un rappel « Tester la connexion » pour activer le fournisseur pour tous ; changer de clé réinitialise la vérification. ### Fix - Saisie clé : une clé vide conserve désormais l'existante aussi pour la config globale (au lieu de l'effacer), et un changement de clé invalide l'ancien statut `verified`. ### Infra - `VERSION` → 4.12.0 ; `app/main.py` version → 4.12.0. ## v4.11.1 (2026-09-05) — Correction & intégration des points d'entrée IA > Aligne les entrées AI de l'interface sur le FlowDeck Agent (alignement Guide Notion AI) et corrige > les trois boutons qui ne fonctionnaient pas : **Ask AI**, **AI meeting note** (toolbar « Get > started » de l'éditeur de page) et le **bouton rond flottant FlowDeck Agent** (coin bas-droit). ### Fix - **Bouton flottant Agent 🤖 (coin bas-droit)** : le chat restait inerte tant qu'aucune conversation n'existait (`send()` retournait silencieusement sans `currentConv`). Ajout d'une création de conversation **lazy** (`ensureConversation()`) effectuée avant chaque envoi — la 1ère saisie crée la conversation puis l'exécute (mode offline ou LLM réel). - **Mode hors-ligne plus utile** : le mock LLM (`_draft_reply`) génère désormais un **vrai contenu structuré** pour les demandes de rédaction de page (« Ask AI », titre détecté via « intitulée ») et les **AI meeting notes** (squelette Résumé / Décisions / Action items), au lieu de se contenter de renvoyer le prompt tel quel — les boutons produisent donc du contenu même sans clé API. - **« Ask AI » & « AI meeting note »** : ne faisaient qu'insérer du texte placeholder (« Ask AI to write... » / « AI Meeting Note ») sans aucun appel IA. Ils déclenchent désormais une **génération inline réelle** via le FlowDeck Agent : - méthodes `askAI()` / `meetingNote()` / `aiRun()` / `applyAIBlocks()` sur l'éditeur de page ; - un prompt contextuel est envoyé au panneau agent (exposition d'`window.fdAgent.ask`) ; - la réponse (`event final` du flux SSE) est **insérée automatiquement dans la page** sous forme de blocs édités (hook `window.__fdInsertAI`). - Un état `aiBusy` évite les doubles envois pendant la génération. ### Infra - `VERSION` → 4.11.1. ## v4.11.0 (2026-09-05) — Agent IA : clés API par utilisateur & chargement dynamique des modèles > Suite de v4.10.1 : migre la config LLM d'un **global admin** vers des **credentials par > utilisateur**. Chacun peut enregistrer plusieurs provider + clé API dans son profil, les modèles > disponibles sont **chargés automatiquement depuis le fournisseur**, et le provider/modèle actif > d'une conversation se pilote **directement dans le chat** via des commandes slash. ### Added - **Clés par utilisateur** : table `user_llm_keys` (UNIQUE(user_id, provider)) + service `app/services/llm_config.py` : `get_user_llm_key`, `list_user_llm_keys` (masqué), `upsert_user_llm_key`, `delete_user_llm_key`. Une clé vide conserve l'existante. - **Chargement dynamique des modèles** : `fetch_provider_models()` (httpx) — GET `{base}/models` pour OpenAI-compatible (Bearer), headers `x-api-key`/`anthropic-version` (Anthropic), `x-goog-api-key` (Gemini) ; stockés dans `models_json` et fusionnés dans `GET /providers`. - **Endpoints API** (tout utilisateur authentifié) : - `GET /api/agent/keys`, `PUT/DELETE /api/agent/keys/{provider}`, - `POST /api/agent/keys/{provider}/models` (fallback sur la clé stockée, pas de fuite de clé), - `PATCH /api/agent/conversations/{id}` (title / provider / model — commande slash). - **`POST /run`** : utilise la clé API de l'utilisateur pour le provider de la conversation (sinon config globale / `.env` / offline mock). - **UI Settings → Agent & IA** (visible pour tous, plus seulement admin) : carte par provider (clé API masquée, URL API, « Charger les modèles » en live, modèle par défaut, Enregistrer / Supprimer). La config globale reste admin sous « Configuration globale ». - **Commandes slash dans le panel agent** : `/help`, `/providers`, `/keys`, `/provider `, `/model ` — menu de suggestions live, appliquées via `PATCH` et sans appel LLM. ### Infra - `VERSION` → 4.11.0 ; migration idempotente (création table `user_llm_keys` + index). ### Tests - **239 tests verts** (+7 : CRUD clés + masquage des secrets, isolation par utilisateur, provider invalide, fetch modèles (clé stockée / body gagnant / erreur), PATCH conversation, `/run` utilise la clé de l'utilisateur). > Comble le trou UX de v4.10.0 : l'utilisateur pouvait discuter avec l'agent mais **ne pouvait > configurer ni provider ni modèle**. Ajout d'un sélecteur provider/modèle dans le panneau, d'une > config runtime persistée en base (table `llm_config`) et d'un écran admin avec test de connexion. ### Added - **Sélecteur provider/modèle dans le panneau agent** (`agent_panel.html`) : deux `