Admin : onglet IA — configuration provider, modèle et instructions Claude Code CLI #97

Closed
opened 2026-05-16 09:50:17 +00:00 by cedricAbonnel · 0 comments
Owner

Contexte

Le ticket #96 a ajouté les boutons IA dans l'éditeur (AiService.php). Pour l'instant, le provider et le modèle sont figés : Anthropic via ANTHROPIC_API_KEY dans le .env. L'admin doit permettre :

  1. De voir l'état de la configuration IA (clé présente ou non)
  2. De choisir le provider (anthropic ou claude_code)
  3. De choisir le modèle (pour Anthropic)
  4. D'avoir les commandes exactes à exécuter sur le serveur pour activer l'option Claude Code CLI

Architecture existante à connaître

Élément Emplacement
Config admin persistée DATA_PATH/site_settings.json via saveSiteSettings() (SiteSettings.php)
Onglets admin templates/admin.php + case 'admin': dans index.php
Service IA src/Service/AiService.php (créé par #96)
Clé API .envne jamais écrire dans le UI ni stocker en clair

Le pattern utilisé pour les autres onglets (ex. SMTP, Site, Recherches) :

  • Données lues dans case 'admin': if ($tab === 'xxx') { ... }$adminData['...']
  • Template rendu dans templates/admin.php via if ($tab === 'xxx'): ?> ... <?php endif; ?>
  • Sauvegarde via case 'admin_save_xxx':saveSiteSettings([...])

Modification de SiteSettings.php

Ajouter deux getters avec fallback .env :

function aiProvider(): string {
    $v = siteSettings()['ai_provider'] ?? '';
    if ($v !== '') return $v;
    return $_ENV['AI_PROVIDER'] ?? getenv('AI_PROVIDER') ?: 'anthropic';
}

function aiModel(): string {
    $v = siteSettings()['ai_model'] ?? '';
    if ($v !== '') return $v;
    return $_ENV['AI_MODEL'] ?? getenv('AI_MODEL') ?: 'claude-haiku-4-5-20251001';
}

Ajouter 'ai_provider' et 'ai_model' dans la liste $stringKeys de saveSiteSettings().


Mise à jour de AiService.php

Lire provider et modèle depuis SiteSettings plutôt que depuis .env directement :

require_once BASE_PATH . '/src/SiteSettings.php';
$this->provider = aiProvider(); // 'anthropic' | 'claude_code'
$this->model    = aiModel();

Ajouter le support Claude Code CLI dans query() :

if ($this->provider === 'claude_code') {
    $bin = '/usr/local/bin/claude';
    if (!is_executable($bin)) {
        return ['ok' => false, 'error' => 'Claude Code CLI introuvable (/usr/local/bin/claude)'];
    }
    $prompt = $systemPrompt . "\n\n" . $userMsg;
    $cmd    = $bin . ' --print ' . escapeshellarg($prompt) . ' 2>&1';
    $env    = ['HOME' => '/var/lib/claude-www', 'PATH' => '/usr/local/bin:/usr/bin:/bin'];
    $desc   = [0 => ['pipe','r'], 1 => ['pipe','w'], 2 => ['pipe','w']];
    $proc   = proc_open($cmd, $desc, $pipes, '/tmp', $env);
    if (!is_resource($proc)) return ['ok' => false, 'error' => 'proc_open échoué'];
    fclose($pipes[0]);
    $out  = stream_get_contents($pipes[1]);
    fclose($pipes[1]); fclose($pipes[2]);
    $code = proc_close($proc);
    if ($code !== 0) return ['ok' => false, 'error' => 'Claude Code exit ' . $code];
    return ['ok' => true, 'text' => trim($out)];
}

Nouvel onglet admin : /admin/ia

Navigation (templates/admin.php)

Ajouter dans la liste <ul class="nav nav-tabs"> (après l'onglet Flux) :

<li class="nav-item">
    <a class="nav-link <?= $tab === 'ia' ? 'active' : '' ?>"
       href="/admin/ia">IA</a>
</li>

Données (index.php, bloc if ($tab === 'ia'))

if ($tab === 'ia') {
    if (!isAdmin()) { http_response_code(403); exit; }
    require_once BASE_PATH . '/src/SiteSettings.php';
    $adminData['ai_provider']       = aiProvider();
    $adminData['ai_model']          = aiModel();
    $adminData['anthropic_key_set'] = (($_ENV['ANTHROPIC_API_KEY'] ?? getenv('ANTHROPIC_API_KEY') ?: '') !== '');
    $adminData['claude_cli_found']  = is_executable('/usr/local/bin/claude');
    $adminData['ai_notice']         = $_GET['notice'] ?? '';
}

Template (templates/admin.php, bloc if ($tab === 'ia'))

Section 1 — Statut

Tableau en lecture seule :

Indicateur Valeur
Clé Anthropic (ANTHROPIC_API_KEY dans .env) ✓ Configurée / ✗ Absente
Claude Code CLI (/usr/local/bin/claude) ✓ Trouvé / ✗ Absent
Provider actif valeur de aiProvider()
Modèle actif valeur de aiModel()

Section 2 — Formulaire de configuration

<form method="POST" action="/?action=admin_save_ai_config">
  <!-- Sélecteur provider (radio) : anthropic | claude_code -->
  <!-- Champ modèle (text, vide = défaut haiku) -->
  <button type="submit" class="btn btn-primary">Enregistrer</button>
</form>

Section 3 — Clé Anthropic

Bloc informatif (aucun champ de saisie — la clé reste dans .env pour des raisons de sécurité) :

⚠ La clé API Anthropic ne peut pas être saisie ici.
Elle doit être définie dans le fichier .env du serveur :

  ANTHROPIC_API_KEY=sk-ant-...

Statut actuel : ✓ Configurée  (ou ✗ Absente)

Section 4 — Claude Code CLI : procédure de mise en place

Card avec les commandes exactes à exécuter en SSH sur le serveur :

# 1. Installer Claude Code CLI (en root)
sudo npm install -g @anthropic-ai/claude-code

# Vérifier l'installation
/usr/local/bin/claude --version

# 2. Créer le répertoire HOME de www-data pour Claude
sudo mkdir -p /var/lib/claude-www
sudo chown www-data:www-data /var/lib/claude-www

# 3. Authentifier Claude en tant que www-data
sudo -u www-data HOME=/var/lib/claude-www /usr/local/bin/claude auth login
# → Suivre les instructions (OAuth navigateur ou clé API)

# 4. Vérifier que ça fonctionne
sudo -u www-data HOME=/var/lib/claude-www /usr/local/bin/claude --print "Réponds juste OK"

Statut de détection affiché en temps réel : ✓ /usr/local/bin/claude trouvé ou ✗ Introuvable — installer d'abord.


Route de sauvegarde

case 'admin_save_ai_config':
    requireAuth();
    if (!isAdmin() || $_SERVER['REQUEST_METHOD'] !== 'POST') {
        http_response_code(403); exit;
    }
    $allowedProviders = ['anthropic', 'claude_code'];
    $provider = in_array($_POST['ai_provider'] ?? '', $allowedProviders, true)
        ? $_POST['ai_provider']
        : 'anthropic';
    $ok = saveSiteSettings([
        'ai_provider' => $provider,
        'ai_model'    => trim($_POST['ai_model'] ?? ''),
    ]);
    header('Location: /admin/ia?notice=' . ($ok ? 'saved' : 'error'));
    exit;

Fichiers à créer / modifier

Fichier Action
src/SiteSettings.php Ajouter aiProvider(), aiModel() + ai_provider/ai_model dans saveSiteSettings()
src/Service/AiService.php Lire provider/modèle via SiteSettings + support Claude Code CLI
public/index.php Bloc if ($tab === 'ia') dans case 'admin' + route admin_save_ai_config
templates/admin.php Onglet IA dans nav + template du tab (4 sections)
.env.example Ajouter AI_PROVIDER=anthropic (commenté, optionnel)

Critères d'acceptation

  • Onglet « IA » visible dans /admin (admin uniquement)
  • Statut Anthropic key (configurée / absente) affiché en lecture seule
  • Statut Claude Code CLI (trouvé / introuvable) affiché
  • Sélecteur provider (anthropic / claude_code) sauvegardé dans site_settings.json
  • Champ modèle sauvegardé dans site_settings.json
  • AiService lit le provider/modèle depuis SiteSettings (avec fallback .env)
  • AiService supporte claude_code via proc_open sur /usr/local/bin/claude
  • Bloc « Instructions CLI » avec les 4 commandes copiables affiché en permanence
  • Message de confirmation après sauvegarde
## Contexte Le ticket #96 a ajouté les boutons IA dans l'éditeur (`AiService.php`). Pour l'instant, le provider et le modèle sont figés : Anthropic via `ANTHROPIC_API_KEY` dans le `.env`. L'admin doit permettre : 1. De voir l'état de la configuration IA (clé présente ou non) 2. De choisir le provider (`anthropic` ou `claude_code`) 3. De choisir le modèle (pour Anthropic) 4. D'avoir les **commandes exactes à exécuter sur le serveur** pour activer l'option Claude Code CLI --- ## Architecture existante à connaître | Élément | Emplacement | |---------|-------------| | Config admin persistée | `DATA_PATH/site_settings.json` via `saveSiteSettings()` (`SiteSettings.php`) | | Onglets admin | `templates/admin.php` + `case 'admin':` dans `index.php` | | Service IA | `src/Service/AiService.php` (créé par #96) | | Clé API | `.env` — **ne jamais écrire dans le UI ni stocker en clair** | Le pattern utilisé pour les autres onglets (ex. SMTP, Site, Recherches) : - Données lues dans `case 'admin': if ($tab === 'xxx') { ... }` → `$adminData['...']` - Template rendu dans `templates/admin.php` via `if ($tab === 'xxx'): ?> ... <?php endif; ?>` - Sauvegarde via `case 'admin_save_xxx':` → `saveSiteSettings([...])` --- ## Modification de `SiteSettings.php` Ajouter deux getters avec fallback `.env` : ```php function aiProvider(): string { $v = siteSettings()['ai_provider'] ?? ''; if ($v !== '') return $v; return $_ENV['AI_PROVIDER'] ?? getenv('AI_PROVIDER') ?: 'anthropic'; } function aiModel(): string { $v = siteSettings()['ai_model'] ?? ''; if ($v !== '') return $v; return $_ENV['AI_MODEL'] ?? getenv('AI_MODEL') ?: 'claude-haiku-4-5-20251001'; } ``` Ajouter `'ai_provider'` et `'ai_model'` dans la liste `$stringKeys` de `saveSiteSettings()`. --- ## Mise à jour de `AiService.php` Lire provider et modèle depuis `SiteSettings` plutôt que depuis `.env` directement : ```php require_once BASE_PATH . '/src/SiteSettings.php'; $this->provider = aiProvider(); // 'anthropic' | 'claude_code' $this->model = aiModel(); ``` Ajouter le support **Claude Code CLI** dans `query()` : ```php if ($this->provider === 'claude_code') { $bin = '/usr/local/bin/claude'; if (!is_executable($bin)) { return ['ok' => false, 'error' => 'Claude Code CLI introuvable (/usr/local/bin/claude)']; } $prompt = $systemPrompt . "\n\n" . $userMsg; $cmd = $bin . ' --print ' . escapeshellarg($prompt) . ' 2>&1'; $env = ['HOME' => '/var/lib/claude-www', 'PATH' => '/usr/local/bin:/usr/bin:/bin']; $desc = [0 => ['pipe','r'], 1 => ['pipe','w'], 2 => ['pipe','w']]; $proc = proc_open($cmd, $desc, $pipes, '/tmp', $env); if (!is_resource($proc)) return ['ok' => false, 'error' => 'proc_open échoué']; fclose($pipes[0]); $out = stream_get_contents($pipes[1]); fclose($pipes[1]); fclose($pipes[2]); $code = proc_close($proc); if ($code !== 0) return ['ok' => false, 'error' => 'Claude Code exit ' . $code]; return ['ok' => true, 'text' => trim($out)]; } ``` --- ## Nouvel onglet admin : `/admin/ia` ### Navigation (`templates/admin.php`) Ajouter dans la liste `<ul class="nav nav-tabs">` (après l'onglet Flux) : ```html <li class="nav-item"> <a class="nav-link <?= $tab === 'ia' ? 'active' : '' ?>" href="/admin/ia">IA</a> </li> ``` ### Données (`index.php`, bloc `if ($tab === 'ia')`) ```php if ($tab === 'ia') { if (!isAdmin()) { http_response_code(403); exit; } require_once BASE_PATH . '/src/SiteSettings.php'; $adminData['ai_provider'] = aiProvider(); $adminData['ai_model'] = aiModel(); $adminData['anthropic_key_set'] = (($_ENV['ANTHROPIC_API_KEY'] ?? getenv('ANTHROPIC_API_KEY') ?: '') !== ''); $adminData['claude_cli_found'] = is_executable('/usr/local/bin/claude'); $adminData['ai_notice'] = $_GET['notice'] ?? ''; } ``` ### Template (`templates/admin.php`, bloc `if ($tab === 'ia')`) **Section 1 — Statut** Tableau en lecture seule : | Indicateur | Valeur | |------------|--------| | Clé Anthropic (`ANTHROPIC_API_KEY` dans `.env`) | ✓ Configurée / ✗ Absente | | Claude Code CLI (`/usr/local/bin/claude`) | ✓ Trouvé / ✗ Absent | | Provider actif | valeur de `aiProvider()` | | Modèle actif | valeur de `aiModel()` | **Section 2 — Formulaire de configuration** ```html <form method="POST" action="/?action=admin_save_ai_config"> <!-- Sélecteur provider (radio) : anthropic | claude_code --> <!-- Champ modèle (text, vide = défaut haiku) --> <button type="submit" class="btn btn-primary">Enregistrer</button> </form> ``` **Section 3 — Clé Anthropic** Bloc informatif (aucun champ de saisie — la clé reste dans `.env` pour des raisons de sécurité) : ``` ⚠ La clé API Anthropic ne peut pas être saisie ici. Elle doit être définie dans le fichier .env du serveur : ANTHROPIC_API_KEY=sk-ant-... Statut actuel : ✓ Configurée (ou ✗ Absente) ``` **Section 4 — Claude Code CLI : procédure de mise en place** Card avec les commandes exactes à exécuter en SSH sur le serveur : ```bash # 1. Installer Claude Code CLI (en root) sudo npm install -g @anthropic-ai/claude-code # Vérifier l'installation /usr/local/bin/claude --version # 2. Créer le répertoire HOME de www-data pour Claude sudo mkdir -p /var/lib/claude-www sudo chown www-data:www-data /var/lib/claude-www # 3. Authentifier Claude en tant que www-data sudo -u www-data HOME=/var/lib/claude-www /usr/local/bin/claude auth login # → Suivre les instructions (OAuth navigateur ou clé API) # 4. Vérifier que ça fonctionne sudo -u www-data HOME=/var/lib/claude-www /usr/local/bin/claude --print "Réponds juste OK" ``` Statut de détection affiché en temps réel : `✓ /usr/local/bin/claude trouvé` ou `✗ Introuvable — installer d'abord`. --- ## Route de sauvegarde ```php case 'admin_save_ai_config': requireAuth(); if (!isAdmin() || $_SERVER['REQUEST_METHOD'] !== 'POST') { http_response_code(403); exit; } $allowedProviders = ['anthropic', 'claude_code']; $provider = in_array($_POST['ai_provider'] ?? '', $allowedProviders, true) ? $_POST['ai_provider'] : 'anthropic'; $ok = saveSiteSettings([ 'ai_provider' => $provider, 'ai_model' => trim($_POST['ai_model'] ?? ''), ]); header('Location: /admin/ia?notice=' . ($ok ? 'saved' : 'error')); exit; ``` --- ## Fichiers à créer / modifier | Fichier | Action | |---------|--------| | `src/SiteSettings.php` | Ajouter `aiProvider()`, `aiModel()` + `ai_provider`/`ai_model` dans `saveSiteSettings()` | | `src/Service/AiService.php` | Lire provider/modèle via `SiteSettings` + support Claude Code CLI | | `public/index.php` | Bloc `if ($tab === 'ia')` dans `case 'admin'` + route `admin_save_ai_config` | | `templates/admin.php` | Onglet IA dans nav + template du tab (4 sections) | | `.env.example` | Ajouter `AI_PROVIDER=anthropic` (commenté, optionnel) | --- ## Critères d'acceptation - [ ] Onglet « IA » visible dans `/admin` (admin uniquement) - [ ] Statut Anthropic key (configurée / absente) affiché en lecture seule - [ ] Statut Claude Code CLI (trouvé / introuvable) affiché - [ ] Sélecteur provider (`anthropic` / `claude_code`) sauvegardé dans `site_settings.json` - [ ] Champ modèle sauvegardé dans `site_settings.json` - [ ] `AiService` lit le provider/modèle depuis `SiteSettings` (avec fallback `.env`) - [ ] `AiService` supporte `claude_code` via `proc_open` sur `/usr/local/bin/claude` - [ ] Bloc « Instructions CLI » avec les 4 commandes copiables affiché en permanence - [ ] Message de confirmation après sauvegarde
Sign in to join this conversation.
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: cedricAbonnel/folio#97