# FlowDeck Agent — Intégration & Fonctionnement > **Version:** 1.0 · **Date:** 2026-07-20 · **Auteur:** Hermes-Deepin > **Cible:** Agent IA natif pour FlowDeck, inspiré de Notion Agent (2026) > **Prérequis:** FlowDeck v4.0.x · FastAPI · SQLite · Gitea/GitHub --- ## Table des matières 1. [Vision & Objectifs](#1-vision--objectifs) 2. [Concept : de l'IA qui répond à l'IA qui réalise](#2-concept) 3. [Positionnement dans l'architecture FlowDeck](#3-positionnement) 4. [Placement dans l'interface (sidebar 🤖 Agents)](#4-placement-interface) 5. [Boucle d'exécution de l'agent](#5-boucle-dexécution) 6. [Sources de contexte FlowDeck](#6-sources-de-contexte) 7. [Modèle de données (nouvelles tables)](#7-modèle-de-données) 8. [Routes & API Agent](#8-routes--api) 9. [Le service AgentEngine](#9-service-agentengine) 10. [Système d'outils (Tools)](#10-système-doutils) 11. [Permissions & sécurité](#11-permissions--sécurité) 12. [Custom Agents & déclencheurs](#12-custom-agents) 13. [Skills réutilisables](#13-skills) 14. [Cas d'usage FlowDeck](#14-cas-dusage) 15. [Plan de migration](#15-plan-de-migration) 16. [Limitations](#16-limitations) --- ## 1. Vision & Objectifs FlowDeck Agent transforme FlowDeck d'un clone Notion **passif** (où l'utilisateur crée manuellement collections, pages, propriétés) en un espace de travail **agentique** où une IA peut : - Comprendre un objectif exprimé en langage naturel - Lire le contexte du workspace (collections, pages, propriétés, issues Gitea) - Planifier une suite d'actions - **Exécuter** ces actions via l'API interne (créer collections, pages, propriétés, vues, sync Gitea) - Retourner un résultat consolidé L'agent réutilise l'infrastructure existante : **il n'appelle pas directement la DB**, il passe par les mêmes routers FastAPI (`/db/*`, `/board/api/*`) que l'utilisateur, garantissant cohérence, validation et respect du `PermissionManager`. Cette fonctionnalité concrétise la ligne `v5.0.0 — AI Assistants` de la roadmap, en s'inspirant directement du modèle Notion Agent. --- ## 2. Concept : de l'IA qui répond à l'IA qui réalise {#2-concept} Assistant classique : Utilisateur → Prompt → Réponse texte FlowDeck Agent : Utilisateur → Objectif → Planification → Collecte contexte → Actions API → Résultat | Notion AI | FlowDeck Agent | |-----------|----------------| | Répond, résume, réécrit | Planifie, recherche, **agit** | | Bloc de texte | Crée collections, pages, propriétés, vues | | Sans état | Historique de conversation + snapshots | | Aucune action DB | Modifie le workspace via routers FastAPI | --- ## 3. Positionnement dans l'architecture FlowDeck {#3-positionnement} L'agent s'insère comme un **nouveau service** et un **nouveau router**, sans modifier le cœur existant. ``` ┌──────────────────────────────────────────────────────────────────┐ │ CLIENT (Browser) │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ agent_panel.html — Panneau conversation (Alpine.js) │ │ │ │ agent_message.html — Fragment message (HTMX streaming) │ │ │ └─────────────────────────────────────────────────────────┘ │ └──────────────────────────┬───────────────────────────────────────┘ │ HTTP (SSE stream / JSON) ┌──────────────────────────▼───────────────────────────────────────┐ │ FASTAPI (Python 3.11+) │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ ROUTERS │ │ │ │ ├─ agent.py ← NOUVEAU /api/agent/* │ │ │ │ └─ (existants: board.py, api.py, collections.py, ...) │ │ │ └─────────────────────────────────────────────────────────┘ │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ SERVICES │ │ │ │ ├─ AgentEngine ← NOUVEAU (orchestrateur) │ │ │ │ ├─ ToolRegistry ← NOUVEAU (outils actionnables) │ │ │ │ ├─ LLMClient ← NOUVEAU (GPT/Claude/Gemini/local) │ │ │ │ ├─ ContextBuilder ← NOUVEAU (collecte workspace) │ │ │ │ ├─ SearchEngine (réutilisé — FTS5) │ │ │ │ ├─ PermissionManager (réutilisé — ACL) │ │ │ │ └─ GiteaClient (réutilisé — API Gitea) │ │ │ └─────────────────────────────────────────────────────────┘ │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ DATA LAYER — SQLite │ │ │ │ ├─ agents ← NOUVEAU │ │ │ │ ├─ agent_conversations ← NOUVEAU │ │ │ │ ├─ agent_messages ← NOUVEAU │ │ │ │ ├─ agent_actions ← NOUVEAU (journal audit) │ │ │ │ ├─ agent_skills ← NOUVEAU │ │ │ │ └─ (tables existantes: collections, pages, ...) │ │ │ └─────────────────────────────────────────────────────────┘ │ └──────────────────────────┬───────────────────────────────────────┘ │ HTTPS ┌──────────────────┴──────────────────┐ ▼ ▼ ┌──────────────────┐ ┌──────────────────────────┐ │ GITEA API REST │ │ PROVIDER LLM │ │ (contexte issues)│ │ OpenAI / Anthropic / │ │ │ │ Gemini / Ollama local │ └──────────────────┘ └──────────────────────────┘ ``` **Principe clé — Tool-calling en boucle fermée :** Le `LLMClient` ne touche jamais la base. Il émet des *intentions d'outil* (function calls). L'`AgentEngine` les traduit en appels HTTP internes vers les routers existants, exécutés avec la session et les permissions de l'utilisateur. --- ## 4. Placement dans l'interface (sidebar 🤖 Agents) {#4-placement-interface} Le sidebar FlowDeck contient déjà une entrée **🤖 Agents** (voir ARCHITECTURE §5.2). Elle devient le point d'entrée de l'agent. ``` ┌────────────┬─────────────────────────────────────────────────┐ │ SIDEBAR │ CONTENU PRINCIPAL │ │ │ │ │ 🕒 Recents │ ┌─ Page / Collection courante ──────────────┐ │ │ ⭐ Favoris │ │ │ │ │ 🤖 Agents ◄┼── clic ouvre le panneau agent (droite) │ │ │ 👥 Shared │ └────────────────────────────────────────────┘ │ │ │ ┌────────────┐ │ │ │ │ 🤖 Agent │ │ │ │ ├────────────┤ │ │ │ │ Historique │ │ │ │ │ Réponses │ │ │ │ │ ───────── │ │ │ │ │ @Sources │ │ │ │ │ 📎 Fichier │ │ │ │ │ [Modèle ▾] │ │ │ │ │ [Saisie... ]│ │ │ │ └────────────┘ │ └────────────┴─────────────────────────────────────────────────┘ ``` Deux modes d'accès, comme Notion Agent : - **Icône flottante** (coin inférieur droit) — accès global rapide - **Section 🤖 Agents** du sidebar — liste des agents (personnel + custom) L'affichage de la section 🤖 Agents est déjà prévu dans les 3 scénarios de compte (A/B/C) — voir ARCHITECTURE §6.5.4 : **toujours visible**. --- ## 5. Boucle d'exécution de l'agent {#5-boucle-dexécution} Adaptation du modèle Notion (Compréhension → Contexte → Raisonnement → Action) à l'architecture FlowDeck : ``` Utilisateur formule un objectif │ ▼ ┌─────────────────────────────────────────────┐ │ 1. COMPRÉHENSION (AgentEngine) │ │ Parse objectif + instructions custom │ └──────────────────┬──────────────────────────┘ ▼ ┌─────────────────────────────────────────────┐ │ 2. COLLECTE CONTEXTE (ContextBuilder) │ │ - Page/collection courante (cookie ws) │ │ - @mentions explicites │ │ - SearchEngine FTS5 (pages pertinentes) │ │ - Issues Gitea liées (GiteaClient) │ │ - Fichiers joints │ │ ⚠ filtré par PermissionManager │ └──────────────────┬──────────────────────────┘ ▼ ┌─────────────────────────────────────────────┐ │ 3. RAISONNEMENT (LLMClient + ToolRegistry) │ │ LLM reçoit: objectif + contexte + schéma │ │ des outils disponibles (function calling) │ │ → émet un plan / une intention d'outil │ └──────────────────┬──────────────────────────┘ ▼ ┌─────────────────────────────────────────────┐ │ 4. ACTION (AgentEngine → routers FastAPI) │ │ Exécute l'appel outil → route interne │ │ POST /db → create_collection │ │ POST /db/{id}/properties → add_property │ │ POST /db/{id}/pages → create_page │ │ Journalise dans agent_actions │ └──────────────────┬──────────────────────────┘ ▼ Résultat outil réinjecté dans le LLM │ ┌────────┴────────┐ │ Objectif atteint?│ └────┬────────┬────┘ non │ │ oui │ ▼ (retour étape 3) ┌─────────────────────────────┐ │ 5. RÉSULTAT consolidé + lien │ │ vers les objets créés │ └─────────────────────────────┘ ``` Cette boucle **ReAct** (Reason + Act) se répète jusqu'à `max_iterations` (défaut : 12) ou atteinte de l'objectif. --- ## 6. Sources de contexte FlowDeck {#6-sources-de-contexte} Correspondance avec les sources Notion Agent, adaptées aux entités FlowDeck : | Source Notion | Équivalent FlowDeck | Mécanisme | |---------------|---------------------|-----------| | Pages, sous-pages | `pages`, `collection_pages` (parent_id) | `SearchEngine` FTS5 + lecture directe | | Bases de données | `collections` + `collection_properties` | Lecture schéma `schema_json` | | Wikis / docs internes | Blocs éditeur (`content_json`) | Parsing blocs | | Jira | **Issues Gitea/GitHub** | `GiteaClient` (issues, labels, milestones) | | Slack / Drive | Fichiers uploadés (`/api/files/`) | Lecture `files` property | | Fichiers joints | Upload local-workspace | PDF/MD parsing | | `@Projet Alpha` | `@collection` / `@page` / `@repo` | Résolution de mention | **Résolution des mentions** — L'utilisateur peut cibler : @collection:Roadmap → force le contexte sur une collection @page:123 → une page précise @repo:bruno/flowdeck → issues d'un repo Gitea @ws → workspace courant complet Le `ContextBuilder` respecte strictement le `PermissionManager` : l'agent ne voit **que** ce que l'utilisateur peut voir (même token, mêmes ACL — voir ARCHITECTURE §6.2). --- ## 7. Modèle de données (nouvelles tables) {#7-modèle-de-données} ```sql -- Définition d'un agent (personnel ou custom) CREATE TABLE agents ( id INTEGER PRIMARY KEY AUTOINCREMENT, workspace_id INTEGER REFERENCES workspaces(id), name TEXT NOT NULL DEFAULT 'FlowDeck Agent', icon TEXT DEFAULT '🤖', agent_type TEXT NOT NULL DEFAULT 'personal', -- 'personal' | 'custom' description TEXT DEFAULT '', -- Instructions personnalisées (ton, format, règles métier) system_instructions TEXT DEFAULT '', -- Modèle IA par défaut model TEXT DEFAULT 'claude-opus-4-8', -- gpt-* | claude-* | gemini-* | ollama:* -- Périmètre custom agent : collections/repos autorisés scope_json TEXT NOT NULL DEFAULT '{}', -- {collections:[3,7], repos:["bruno/flowdeck"], tools:["create_page"]} -- Déclencheurs (custom agents) trigger_json TEXT NOT NULL DEFAULT '{}', -- {type:"schedule", cron:"0 9 * * 1"} | {type:"webhook", event:"issue.opened"} is_active BOOLEAN NOT NULL DEFAULT 1, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, created_by INTEGER REFERENCES users(id), UNIQUE(workspace_id, name) ); -- Conversations (fils de discussion, comme Notion history) CREATE TABLE agent_conversations ( id INTEGER PRIMARY KEY AUTOINCREMENT, agent_id INTEGER NOT NULL REFERENCES agents(id) ON DELETE CASCADE, user_id INTEGER NOT NULL REFERENCES users(id), title TEXT DEFAULT 'New conversation', -- Contexte de départ (page/collection ouverte à l'invocation) context_json TEXT NOT NULL DEFAULT '{}', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); -- Messages d'une conversation CREATE TABLE agent_messages ( id INTEGER PRIMARY KEY AUTOINCREMENT, conversation_id INTEGER NOT NULL REFERENCES agent_conversations(id) ON DELETE CASCADE, role TEXT NOT NULL, -- 'user' | 'assistant' | 'tool' | 'system' content TEXT NOT NULL DEFAULT '', -- Pour role='tool' : nom de l'outil + payload + résultat tool_calls_json TEXT DEFAULT '[]', model TEXT, tokens_used INTEGER DEFAULT 0, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); -- Journal d'audit : CHAQUE action modifiant le workspace CREATE TABLE agent_actions ( id INTEGER PRIMARY KEY AUTOINCREMENT, conversation_id INTEGER NOT NULL REFERENCES agent_conversations(id) ON DELETE CASCADE, tool_name TEXT NOT NULL, -- create_collection | create_page | add_property | ... target_type TEXT, -- collection | page | property | view | issue target_id TEXT, payload_json TEXT NOT NULL DEFAULT '{}', result_json TEXT NOT NULL DEFAULT '{}', status TEXT NOT NULL DEFAULT 'success', -- success | error | reverted -- Snapshot avant modification → permet le rollback undo_snapshot_json TEXT DEFAULT '{}', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, executed_by INTEGER REFERENCES users(id) ); -- Skills réutilisables (mini-prompts) CREATE TABLE agent_skills ( id INTEGER PRIMARY KEY AUTOINCREMENT, workspace_id INTEGER REFERENCES workspaces(id), name TEXT NOT NULL, -- "Génération de PRD", "Analyse SWOT", "Préparation sprint" description TEXT DEFAULT '', prompt_template TEXT NOT NULL, -- Outils que la skill peut invoquer allowed_tools_json TEXT NOT NULL DEFAULT '[]', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, created_by INTEGER REFERENCES users(id), UNIQUE(workspace_id, name) ); CREATE INDEX idx_agent_conv_user ON agent_conversations(user_id, updated_at); CREATE INDEX idx_agent_msg_conv ON agent_messages(conversation_id, created_at); CREATE INDEX idx_agent_action_conv ON agent_actions(conversation_id); Intégration au diagramme de relations existant users ──1:N──► agent_conversations ──1:N──► agent_messages │ │ │ └──1:N──► agent_actions ──► (collections/pages/...) │ workspaces ──1:N──► agents ──1:N──► agent_conversations │ └──1:N──► agent_skills ``` ## 8. Routes & API Agent {#8-routes--api} Nouveau router agent.py, préfixe /api/agent. # Agents (définitions) ``` GET /api/agent → Liste agents du workspace POST /api/agent → Créer custom agent GET /api/agent/{agent_id} → Détail agent PUT /api/agent/{agent_id} → Update (instructions, scope, model) DELETE /api/agent/{agent_id} → Supprimer custom agent ``` # Conversations ``` GET /api/agent/conversations → Historique des conversations POST /api/agent/conversations → Nouvelle conversation GET /api/agent/conversations/{id} → Messages d'une conversation DELETE /api/agent/conversations/{id} → Supprimer conversation ``` # Exécution (cœur) ``` POST /api/agent/conversations/{id}/run → Envoyer un objectif (SSE stream) body: {message, model?, mentions?, files?, skill_id?} → stream: reasoning → tool_call → tool_result → ... → final ``` # Actions & audit ``` GET /api/agent/conversations/{id}/actions → Journal des actions POST /api/agent/actions/{action_id}/undo → Annuler une action (rollback) ``` # Skills ``` GET /api/agent/skills → Liste skills POST /api/agent/skills → Créer skill POST /api/agent/skills/{id}/apply → Appliquer une skill ``` # Custom agents — déclencheurs ``` POST /api/agent/{agent_id}/trigger → Déclenchement manuel ``` # (déclenchement auto via scheduler interne + webhooks.py) Streaming — La route /run renvoie un flux Server-Sent Events (SSE) pour afficher en temps réel le raisonnement et chaque action, à la manière de l'interface conversationnelle Notion. Le frontend (Alpine.js) consomme le flux et met à jour agent_panel.html. ------------------------- ## 9. Le service AgentEngine {#9-service-agentengine} Orchestrateur central. Pseudo-implémentation : ``` class AgentEngine: """Orchestrateur ReAct pour FlowDeck Agent.""" def __init__(self, db, user, request): self.db = db self.user = user self.request = request # pour réutiliser session/cookies self.llm = LLMClient() self.tools = ToolRegistry(db, user, request) self.ctx = ContextBuilder(db, user) self.perms = PermissionManager(db, user) async def run(self, conversation_id, objective, *, model=None, mentions=None, files=None, skill_id=None): agent = self._load_agent(conversation_id) model = model or agent.model # 1. COMPRÉHENSION + instructions custom + skill system = self._build_system_prompt(agent, skill_id) # 2. COLLECTE CONTEXTE (respecte permissions) context = await self.ctx.build( workspace=self._active_workspace(), mentions=mentions, files=files, ) messages = [ {"role": "system", "content": system}, {"role": "user", "content": f"{objective}\n\n# Contexte\n{context}"}, ] # 3-4. BOUCLE RAISONNEMENT ↔ ACTION for _ in range(MAX_ITERATIONS): # défaut 12 response = await self.llm.complete( model=model, messages=messages, tools=self.tools.schema(scope=agent.scope), # function calling stream=True, ) yield {"type": "reasoning", "content": response.text} if not response.tool_calls: yield {"type": "final", "content": response.text} break for call in response.tool_calls: # Vérif permission AVANT exécution self.perms.assert_can(call.tool, call.args) result = await self.tools.execute(call.tool, call.args) # Journal d'audit + snapshot rollback self._log_action(conversation_id, call, result) yield {"type": "action", "tool": call.tool, "target": result.get("target"), "status": result["status"]} messages.append({"role": "tool", "name": call.tool, "content": result}) ``` Points clés : - stream=True → SSE vers le frontend - Chaque tool_call passe par PermissionManager.assert_can() avant exécution - Chaque action modifiant la DB écrit un agent_actions avec undo_snapshot_json → rollback possible - La boucle réutilise le même token Gitea que l'utilisateur (via user_tokens) ------------------------- 10. Système d'outils (Tools) {#10-système-doutils} Les outils sont des wrappers autour des routers FastAPI existants — l'agent ne réinvente rien. | Outil | Route interne appelée | Ce que ça fait | |-------|----------------------|----------------| | `search_workspace` | `SearchEngine` (FTS5) | Recherche full-text pages/collections | | `read_collection` | `GET /db/{id}` | Lit schéma + pages d'une collection | | `read_page` | `GET /db/{c}/pages/{p}` | Lit une page + propriétés + blocs | | `create_collection` | `POST /db` | Crée une database | | `add_property` | `POST /db/{id}/properties` | Ajoute une propriété typée | | `create_view` | `POST /db/{id}/views` | Crée une vue (table/board/calendar…) | | `create_page` | `POST /db/{id}/pages` | Crée une page + valeurs propriétés | | `update_page` | `PUT /db/{c}/pages/{p}` | Modifie propriétés/contenu | | `write_blocks` | `POST /board/api/pages/{id}/blocks` | Écrit du contenu (éditeur de blocs) | | `add_relation` | `POST /db/{id}/properties` (type relation) | Lie deux collections | | `create_sub_item` | `POST /db/{c}/pages/{p}/sub-items` | Crée un sub-item | | `add_dependency` | `POST /db/{c}/pages/{p}/dependencies` | Ajoute blocks/blocked_by | | `sync_gitea` | `POST /board/api/sync/{o}/{r}` | Synchronise issues ↔ collection | | `read_gitea_issues` | `GiteaClient` | Lit issues/labels/milestones | | `create_gitea_issue` | `POST /api/issues/{o}/{r}` | Crée une issue Gitea | | `apply_template` | `POST /db/{id}/templates/{t}/apply` | Applique un template | Schéma d'un outil (function calling) exposé au LLM : ``` { "name": "create_page", "description": "Crée une page dans une collection FlowDeck avec ses valeurs de propriétés.", "parameters": { "type": "object", "properties": { "collection_id": {"type": "integer"}, "title": {"type": "string"}, "property_values": { "type": "object", "description": "Map property_id → valeur (respecte le type)" } }, "required": ["collection_id", "title"] } } ``` Filtrage par scope — Pour un custom agent, ToolRegistry.schema(scope=...) ne renvoie que les outils autorisés dans agents.scope_json.tools, et limite les cibles aux collections/repos de scope_json. ------------------------- ## 11. Permissions & sécurité {#11-permissions--sécurité} L'agent agit avec les permissions de l'utilisateur, jamais au-delà (principe Notion Agent : « mêmes permissions que l'utilisateur »). ``` ┌───────────────────────────────────────────────────────────┐ │ GARDE-FOUS AGENT │ │ │ │ 1. Identité → session utilisateur + user_tokens │ │ 2. ACL → PermissionManager.assert_can() par outil│ │ 3. Scope custom → scope_json limite collections/repos │ │ 4. Database lock → collection is_locked ⇒ outils write KO │ │ 5. Audit → agent_actions journalise TOUT │ │ 6. Rollback → undo_snapshot_json par action │ │ 7. Rate limiting → RateLimiter (middleware existant) │ │ 8. Confirmation → actions destructives ⇒ approbation UI │ └───────────────────────────────────────────────────────────┘ ``` Mode approbation — Configurable par agent : - auto : l'agent exécute directement (création de contenu) - confirm : actions destructives (delete_page, sync massif) demandent une confirmation dans le panneau avant exécution Cohérent avec le modèle de rôles workspace (owner/admin/editor/commenter/viewer, ARCHITECTURE §6.2) : un agent lancé par un viewer ne peut que lire. ------------------------- ## 12. Custom Agents & déclencheurs {#12-custom-agents} Comme Notion (Custom Agents 2026), FlowDeck distingue : | Type | Portée | Exemple | |------|--------|---------| | **Personal Agent** | Généraliste, tout le workspace visible | Assistant quotidien | | **Custom Agent** | Spécialisé, scope restreint, déclencheurs | Agent Reporting, Agent Support | Déclencheurs (agents.trigger_json) : ``` type: "manual" → bouton dans l'UI type: "schedule" → cron interne (ex: "0 9 * * 1" = lundi 9h) type: "webhook" → branché sur webhooks.py (issue.opened, issue.closed…) ``` Exemples de custom agents FlowDeck : - Agent Reporting — chaque lundi, scanne toutes les collections, produit une page « Rapport hebdo » avec KPI - Agent Gitea Triage — à issue.opened, classe l'issue dans la bonne collection et remplit ses propriétés - Agent Sprint — prépare une collection sprint depuis les issues du milestone courant Le scheduler s'appuie sur le lifespan FastAPI (main.py) et les webhooks réutilisent le router webhooks.py existant. ------------------------- ## 13. Skills réutilisables {#13-skills} Une skill est un mini-prompt paramétrable + liste d'outils autorisés (table agent_skills). ``` Skill "Préparation de sprint" ├─ prompt_template: │ "Analyse les issues ouvertes du repo {repo}, crée une collection │ sprint '{sprint_name}', ajoute les propriétés Status/Priority/Assignee, │ importe chaque issue comme page, groupe en vue Board." ├─ allowed_tools: [read_gitea_issues, create_collection, │ add_property, create_page, create_view] └─ Invocation: POST /api/agent/skills/{id}/apply ``` Autres skills livrées par défaut : Analyse SWOT, Génération de compte-rendu, Génération de PRD, Synthèse GitHub/Gitea. ------------------------- ## 14. Cas d'usage FlowDeck {#14-cas-dusage} Gestion de produit > « Crée une roadmap Q3 à partir des issues du repo bruno/flowdeck » ``` L'agent : read_gitea_issues → create_collection("Roadmap Q3") → add_property(Status, Priority, DueDate) → create_page × N → create_view(timeline). Développement logiciel ``` > « Analyse les bugs des 6 derniers mois et crée un plan d'amélioration » ``` sync_gitea → search_workspace → analyse LLM → create_collection("Plan qualité") → create_page (causes, actions) → add_dependency. Direction ``` > « Génère les OKR du prochain trimestre depuis nos objectifs actuels » ``` read_collection(Objectifs) → raisonnement → create_collection("OKR Q4") → create_page × N. Multi-étapes (comme Notion) ``` > « Résume les notes de réunion du trimestre et crée les tâches de suivi » ``` search_workspace(meetings) → synthèse → write_blocks (page résumé) → create_page × N (tâches) dans la collection Tasks. ``` ------------------------- ## 15. Plan de migration {#15-plan-de-migration} Phase 1 — Fondations DB & Service 1. Créer tables agents, agent_conversations, agent_messages, agent_actions, agent_skills 2. Implémenter LLMClient (abstraction multi-provider) 3. Implémenter ContextBuilder (réutilise SearchEngine) Phase 2 — Tool-calling 1. ToolRegistry : wrappers read-only d'abord (search, read_*) 2. Ajouter outils write (create_collection, create_page, ...) 3. Brancher PermissionManager.assert_can() sur chaque outil 4. Journal agent_actions + snapshots rollback Phase 3 — Interface 1. agent_panel.html (Alpine.js) branché sur section 🤖 Agents 2. Streaming SSE (/run) 3. Icône flottante coin inférieur droit 4. Affichage temps réel reasoning + actions Phase 4 — Personnalisation 1. Instructions custom par agent 2. Skills (table + /apply) 3. Sélecteur de modèle (GPT/Claude/Gemini/Ollama) ✅ (v4.10.1 : selects provider/modèle dans le panneau + config admin runtime DB-backed `llm_config`, `/api/agent/providers` GET/PATCH, `/api/agent/providers/test`) Phase 5 — Custom Agents 1. Scope + trigger_json 2. Scheduler (lifespan FastAPI) 3. Déclencheurs webhook (via webhooks.py) 4. Mode approbation (auto/confirm) ✅ (v4.10.0) > **Note numérotation** — ce document suit l'ordre historique d'implémentation. > Le plan officiel à 5 phases de `ROADMAP.md` se lit : phase 3 « Outils avancés » ✅ v4.10.0 · > phase 4 « Autonomie » (agents, skills, déclencheurs) ✅ v4.10.0 · > **phase 5 « Plateforme » ✅ v6.6.0** — API publique `/api/v2/agents/*` (run synchrone JSON, > journal + rollback, `trigger` externe), marketplace de skills (export/import portable, > galerie de 6 presets, section « Galerie » dans la palette `/` du panneau) et webhooks de cycle de vie > `agent.run.started` → `agent.run.finished` | `agent.run.failed`. > Référence : `docs/API_GUIDE_V6.md` §2.4 · tests : `tests/test_v66_agent_api.py`. ------------------------- ## 16. Limitations {#16-limitations} Alignées sur les limites connues de Notion Agent, adaptées à FlowDeck. L'agent ne peut pas : - Modifier les paramètres du workspace (/workspace/{id}/settings) - Gérer les membres / rôles (workspace_members) - Gérer l'authentification ou les intégrations OAuth (connexion/déconnexion Gitea/GitHub) - Publier ou partager publiquement une page sans confirmation utilisateur (/api/pages/{id}/publish, /share) - Modifier une collection verrouillée (is_locked = 1) - Agir au-delà des permissions de l'utilisateur qui l'invoque - Supprimer définitivement (hard delete) sans mode confirm ------------------------- Résumé FlowDeck Agent porte le modèle Notion Agent dans FlowDeck en réutilisant l'infrastructure existante : - Un service AgentEngine orchestrant une boucle ReAct (raisonnement ↔ action) - Des outils qui sont de simples wrappers des routers FastAPI existants (/db/*, /board/api/*, Gitea) - Un contexte collecté via SearchEngine + GiteaClient, filtré par PermissionManager - Un audit complet (agent_actions) avec rollback - Custom Agents, skills et déclencheurs pour l'automatisation Le passage de « l'IA qui répond » à « l'IA qui réalise le travail » se fait sans réécrire FlowDeck : l'agent agit comme un utilisateur privilégié mais contraint, à travers les mêmes portes que l'interface humaine. J'ai créé le document `Flowdeck_Agent_integration.md`. Points saillants de l'intégration proposée : - **Réutilisation maximale** : l'agent n'accède jamais directement à SQLite — il appelle les routers FastAPI existants (`/db/*`, `/board/api/*`, `GiteaClient`), ce qui garantit validation, cohérence et respect du `PermissionManager`. - **Boucle ReAct** : Compréhension → Contexte → Raisonnement → Action, calquée sur le fonctionnement de Notion Agent mais mappée sur vos entités (`collections`, `collection_pages`, issues Gitea). - **5 nouvelles tables** seulement (`agents`, `agent_conversations`, `agent_messages`, `agent_actions`, `agent_skills`), plus un router `agent.py` et 4 services. - **Sécurité** : audit complet avec `undo_snapshot_json` pour rollback, respect des rôles workspace, mode `confirm` pour les actions destructives. - **Custom Agents + Skills + déclencheurs** (cron via `lifespan`, webhooks via votre `webhooks.py` existant).