Add time/date access for Ikario and Tavily MCP specification
Major changes: - Added current date/time to system prompt so Ikario always knows when it is - Created comprehensive Tavily MCP integration spec (10 features) - Updated .gitignore to exclude node_modules Time Access Feature: - Modified buildSystemPrompt in server/routes/messages.js - Modified buildSystemPrompt in server/routes/claude.js - Ikario now receives: date, time, ISO timestamp, timezone - Added debug logging to verify system prompt Tavily MCP Spec (app_spec_tavily_mcp.txt): - Internet access via Tavily search API - 10 detailed features with implementation steps - Compatible with existing ikario-memory MCP - Provides real-time web search and news search 🤖 Generated with Claude Code Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -6,38 +6,50 @@
|
||||
"Bash(netstat:*)",
|
||||
"Bash(docker-compose:*)",
|
||||
"Bash(ls:*)",
|
||||
"Bash(git:*)",
|
||||
"Bash(rm:*)",
|
||||
"Bash(python autonomous_agent_demo.py:*)",
|
||||
"Bash(dir C:GitHublinear_coding_philosophia_raggenerationslibrary_rag*.py)",
|
||||
"Bash(git add:*)",
|
||||
"Bash(git commit -m \"$\\(cat <<''EOF''\nFix import error: rename delete_document_passages to delete_document_chunks\n\nThe function was renamed in weaviate_ingest.py but the import in __init__.py\nwas not updated, causing ImportError when using the library.\n\nChanges:\n- Updated import statement in utils/__init__.py\n- Updated __all__ export list to use correct function name\nEOF\n\\)\")",
|
||||
"Bash(dir \"C:\\\\GitHub\\\\linear_coding_philosophia_rag\\\\generations\\\\library_rag\\\\.env\")",
|
||||
"Bash(git commit:*)",
|
||||
"Bash(tasklist:*)",
|
||||
"Bash(findstr:*)",
|
||||
"Bash(wmic process:*)",
|
||||
"Bash(powershell -Command \"Get-Process python | Select-Object Id,Path,StartTime | Format-Table -AutoSize\")",
|
||||
"Bash(powershell -Command \"Get-WmiObject Win32_Process -Filter \"\"name = ''python.exe''\"\" | Select-Object ProcessId, CommandLine | Format-List\")",
|
||||
"Bash(timeout:*)",
|
||||
"Bash(powershell -Command:*)",
|
||||
"Bash(python:*)",
|
||||
"Bash(dir \"C:\\\\GitHub\\\\linear_coding_library_rag\\\\generations\\\\library_rag\")",
|
||||
"Bash(docker ps:*)",
|
||||
"Bash(docker logs:*)",
|
||||
"Bash(curl:*)",
|
||||
"Bash(dir:*)",
|
||||
"Bash(timeout 30 tail:*)",
|
||||
"Bash(xargs:*)",
|
||||
"Bash(npm run dev:*)",
|
||||
"Bash(npm run build:*)",
|
||||
"Bash(npm install:*)",
|
||||
"WebFetch(domain:docs.anthropic.com)",
|
||||
"WebFetch(domain:docs.claude.com)",
|
||||
"Bash(npm start)",
|
||||
"Bash(node test_extended_thinking.js:*)",
|
||||
"Bash(node test_screenshot.js:*)",
|
||||
"Bash(node test_thinking_badge.js:*)",
|
||||
"Bash(node test_thinking_badge_simple.js:*)",
|
||||
"Bash(node:*)",
|
||||
"Bash(npx sqlite3:*)",
|
||||
"Bash(taskkill:*)",
|
||||
"Bash(findstr:*)",
|
||||
"Bash(tee:*)",
|
||||
"Bash(grep:*)",
|
||||
"Bash(git push:*)",
|
||||
"Bash(mypy:*)",
|
||||
"WebSearch",
|
||||
"Bash(nvidia-smi:*)",
|
||||
"WebFetch(domain:cr.weaviate.io)",
|
||||
"Bash(git restore:*)",
|
||||
"Bash(git log:*)",
|
||||
"Bash(done)",
|
||||
"Bash(git remote set-url:*)",
|
||||
"Bash(docker compose:*)",
|
||||
"Bash(pytest:*)",
|
||||
"Bash(git pull:*)"
|
||||
"Bash(timeout 10 tail:*)",
|
||||
"Bash(iconv:*)",
|
||||
"Bash(pip install:*)",
|
||||
"Bash(sqlite3:*)",
|
||||
"Bash(wmic process where \"name=''python.exe''\" get ProcessId,CommandLine /format:list)",
|
||||
"Bash(powershell -Command \"Get-Process python | Select-Object Id, Path, StartTime | Format-List\")",
|
||||
"Bash(powershell:*)",
|
||||
"Bash(timeout 5 tail:*)",
|
||||
"Bash(timeout 8 tail:*)",
|
||||
"Bash(find:*)",
|
||||
"Bash(npm:*)",
|
||||
"Bash(tasklist:*)",
|
||||
"Bash(chmod:*)",
|
||||
"Bash(restart.bat)",
|
||||
"Bash(npm run dev)",
|
||||
"Bash(pkill:*)",
|
||||
"Bash(claude doctor:*)",
|
||||
"Bash(dir /s /b \".claude_settings.json\")",
|
||||
"Bash(dir /s /b \"settings.local.json\")",
|
||||
"Bash(python -m json.tool:*)"
|
||||
]
|
||||
}
|
||||
}
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -7,3 +7,7 @@ logs/
|
||||
.env
|
||||
venv
|
||||
__pycache__
|
||||
|
||||
# Node modules (if any)
|
||||
node_modules/
|
||||
package-lock.json
|
||||
337
GUIDE_NEW_APP.md
337
GUIDE_NEW_APP.md
@@ -1,337 +0,0 @@
|
||||
# Guide : Créer une Nouvelle Application avec le Framework Linear Coding
|
||||
|
||||
Ce guide explique comment utiliser ce framework pour créer une **toute nouvelle application** à partir de zéro.
|
||||
|
||||
## Vue d'ensemble
|
||||
|
||||
Ce framework permet de générer automatiquement une application complète en utilisant :
|
||||
- **Linear** pour la gestion de projet (issues, suivi, commentaires)
|
||||
- **Claude Agent SDK** pour le développement autonome
|
||||
- **Spécifications en format XML** pour décrire l'application
|
||||
|
||||
## Structure du Framework
|
||||
|
||||
### Fichiers génériques (à NE PAS modifier)
|
||||
|
||||
Ces fichiers font partie du framework et sont réutilisables pour toutes les applications :
|
||||
|
||||
```
|
||||
linear-coding-agent/
|
||||
├── autonomous_agent_demo.py # Point d'entrée principal
|
||||
├── agent.py # Logique des sessions d'agent
|
||||
├── client.py # Configuration SDK Claude + MCP
|
||||
├── security.py # Validation et whitelist des commandes
|
||||
├── progress.py # Utilitaires de suivi de progression
|
||||
├── prompts.py # Utilitaires de chargement des prompts
|
||||
├── linear_config.py # Constantes de configuration Linear
|
||||
├── requirements.txt # Dépendances Python
|
||||
└── prompts/
|
||||
├── initializer_prompt.md # Prompt pour la session initiale
|
||||
├── initializer_bis_prompt.md # Prompt pour ajouter des features
|
||||
└── coding_prompt.md # Prompt pour les sessions de codage
|
||||
```
|
||||
|
||||
**⚠️ Ne modifiez PAS ces fichiers** - ils sont génériques et fonctionnent pour toutes les applications.
|
||||
|
||||
### Fichiers spécifiques à votre application (à CRÉER)
|
||||
|
||||
Le seul fichier que vous devez créer est :
|
||||
|
||||
```
|
||||
prompts/
|
||||
└── app_spec.txt # Votre spécification d'application (format XML)
|
||||
```
|
||||
|
||||
## Étapes pour Créer une Nouvelle Application
|
||||
|
||||
### Étape 1 : Créer votre fichier de spécification
|
||||
|
||||
Créez un fichier `prompts/app_spec.txt` qui décrit votre application. Utilisez le format XML suivant :
|
||||
|
||||
```xml
|
||||
<project_specification>
|
||||
<project_name>Nom de Votre Application</project_name>
|
||||
|
||||
<overview>
|
||||
Description complète de votre application. Expliquez ce que vous voulez construire,
|
||||
les objectifs principaux, et les fonctionnalités clés.
|
||||
</overview>
|
||||
|
||||
<technology_stack>
|
||||
<frontend>
|
||||
<framework>React avec Vite</framework>
|
||||
<styling>Tailwind CSS</styling>
|
||||
<state_management>React hooks</state_management>
|
||||
<!-- Ajoutez d'autres technologies frontend -->
|
||||
</frontend>
|
||||
<backend>
|
||||
<runtime>Node.js avec Express</runtime>
|
||||
<database>SQLite</database>
|
||||
<!-- Ajoutez d'autres technologies backend -->
|
||||
</backend>
|
||||
</technology_stack>
|
||||
|
||||
<prerequisites>
|
||||
<environment_setup>
|
||||
- Liste des prérequis (dépendances, clés API, etc.)
|
||||
</environment_setup>
|
||||
</prerequisites>
|
||||
|
||||
<core_features>
|
||||
<feature_1>
|
||||
<title>Titre de la fonctionnalité 1</title>
|
||||
<description>Description détaillée</description>
|
||||
<priority>1</priority>
|
||||
<category>frontend</category>
|
||||
<test_steps>
|
||||
1. Étape de test 1
|
||||
2. Étape de test 2
|
||||
</test_steps>
|
||||
</feature_1>
|
||||
|
||||
<feature_2>
|
||||
<!-- Autres fonctionnalités -->
|
||||
</feature_2>
|
||||
</core_features>
|
||||
</project_specification>
|
||||
```
|
||||
|
||||
### Étape 2 : Exemple de structure complète
|
||||
|
||||
Voici un exemple basé sur l'application "Claude Clone" que vous pouvez utiliser comme référence :
|
||||
|
||||
**Structure recommandée de `app_spec.txt` :**
|
||||
|
||||
```xml
|
||||
<project_specification>
|
||||
<project_name>Mon Application</project_name>
|
||||
|
||||
<overview>
|
||||
Description de votre application...
|
||||
</overview>
|
||||
|
||||
<technology_stack>
|
||||
<!-- Stack technique complète -->
|
||||
</technology_stack>
|
||||
|
||||
<prerequisites>
|
||||
<!-- Prérequis -->
|
||||
</prerequisites>
|
||||
|
||||
<core_features>
|
||||
<!-- Liste toutes vos fonctionnalités avec des balises <feature_X> -->
|
||||
</core_features>
|
||||
|
||||
<ui_design>
|
||||
<!-- Spécifications UI si nécessaire -->
|
||||
</ui_design>
|
||||
|
||||
<api_endpoints>
|
||||
<!-- Endpoints API si nécessaire -->
|
||||
</api_endpoints>
|
||||
|
||||
<database_schema>
|
||||
<!-- Schéma de base de données si nécessaire -->
|
||||
</database_schema>
|
||||
</project_specification>
|
||||
```
|
||||
|
||||
### Étape 3 : Lancer l'initialisation
|
||||
|
||||
Une fois votre `app_spec.txt` créé, lancez l'agent initializer :
|
||||
|
||||
```bash
|
||||
python autonomous_agent_demo.py --project-dir ./ma_nouvelle_app
|
||||
```
|
||||
|
||||
L'agent va :
|
||||
1. Lire votre `app_spec.txt`
|
||||
2. Créer un projet Linear
|
||||
3. Créer ~50 issues Linear basées sur votre spécification
|
||||
4. Initialiser la structure du projet
|
||||
|
||||
### Étape 4 : Suivre le développement
|
||||
|
||||
Les agents de codage vont ensuite :
|
||||
- Travailler sur les issues Linear une par une
|
||||
- Implémenter les fonctionnalités
|
||||
- Tester avec Puppeteer
|
||||
- Mettre à jour les issues avec leurs commentaires
|
||||
|
||||
## Exemple : Utiliser l'application "Claude Clone" comme référence
|
||||
|
||||
L'application "Claude Clone" dans `prompts/app_spec.txt` est un excellent exemple à suivre car elle contient :
|
||||
|
||||
### ✅ Éléments à copier/adapter :
|
||||
|
||||
1. **Structure XML** : La structure générale avec `<project_specification>`, `<overview>`, `<technology_stack>`, etc.
|
||||
|
||||
2. **Format des fonctionnalités** : Comment structurer les `<feature_X>` avec :
|
||||
- `<title>`
|
||||
- `<description>`
|
||||
- `<priority>`
|
||||
- `<category>`
|
||||
- `<test_steps>`
|
||||
|
||||
3. **Détails techniques** : Comment décrire :
|
||||
- La stack technologique
|
||||
- Les prérequis
|
||||
- Les endpoints API
|
||||
- Le schéma de base de données
|
||||
- Les spécifications UI
|
||||
|
||||
### ❌ Éléments spécifiques à NE PAS copier :
|
||||
|
||||
1. **Le contenu spécifique** : Les détails sur "Claude API", "artifacts", "conversations", etc. sont spécifiques à cette app
|
||||
2. **Les fonctionnalités métier** : Adaptez-les à votre application
|
||||
|
||||
## Checklist pour une Nouvelle Application
|
||||
|
||||
- [ ] Créer `prompts/app_spec.txt` avec votre spécification
|
||||
- [ ] Définir le `<project_name>` de votre application
|
||||
- [ ] Décrire l'`<overview>` complète
|
||||
- [ ] Spécifier la `<technology_stack>` (frontend + backend)
|
||||
- [ ] Lister les `<prerequisites>` nécessaires
|
||||
- [ ] Définir toutes les `<core_features>` avec des balises `<feature_X>`
|
||||
- [ ] Ajouter des `<test_steps>` pour chaque fonctionnalité
|
||||
- [ ] Lancer : `python autonomous_agent_demo.py --project-dir ./mon_app`
|
||||
- [ ] Vérifier dans Linear que les issues sont créées correctement
|
||||
|
||||
## Conseils pour Rédiger une Bonne Spécification
|
||||
|
||||
### 1. Soyez détaillé mais structuré
|
||||
|
||||
Chaque fonctionnalité doit avoir :
|
||||
- Un titre clair
|
||||
- Une description complète de ce qu'elle fait
|
||||
- Des étapes de test précises
|
||||
- Une priorité (1=urgent, 4=optionnel)
|
||||
|
||||
### 2. Utilisez le format XML cohérent
|
||||
|
||||
```xml
|
||||
<feature_1>
|
||||
<title>Authentification - Connexion utilisateur</title>
|
||||
<description>
|
||||
Implémenter un système d'authentification avec :
|
||||
- Formulaire de connexion (email/mot de passe)
|
||||
- Validation côté client et serveur
|
||||
- Gestion des sessions avec JWT
|
||||
- Page de réinitialisation de mot de passe
|
||||
</description>
|
||||
<priority>1</priority>
|
||||
<category>auth</category>
|
||||
<test_steps>
|
||||
1. Accéder à la page de connexion
|
||||
2. Entrer un email invalide → voir erreur
|
||||
3. Entrer des identifiants valides → redirection vers dashboard
|
||||
4. Vérifier que le token JWT est stocké
|
||||
5. Tester la déconnexion
|
||||
</test_steps>
|
||||
</feature_1>
|
||||
```
|
||||
|
||||
### 3. Organisez par catégories
|
||||
|
||||
Groupez les fonctionnalités par catégorie :
|
||||
- `auth` : Authentification
|
||||
- `frontend` : Interface utilisateur
|
||||
- `backend` : API et logique serveur
|
||||
- `database` : Modèles et migrations
|
||||
- `integration` : Intégrations externes
|
||||
|
||||
### 4. Priorisez les fonctionnalités
|
||||
|
||||
- **Priority 1** : Fonctionnalités critiques (auth, base de données)
|
||||
- **Priority 2** : Fonctionnalités importantes (core features)
|
||||
- **Priority 3** : Fonctionnalités secondaires (améliorations UX)
|
||||
- **Priority 4** : Nice-to-have (polish, optimisations)
|
||||
|
||||
## Exemple Minimal
|
||||
|
||||
Voici un exemple minimal pour démarrer :
|
||||
|
||||
```xml
|
||||
<project_specification>
|
||||
<project_name>Todo App - Gestionnaire de Tâches</project_name>
|
||||
|
||||
<overview>
|
||||
Application web simple pour gérer des listes de tâches.
|
||||
Les utilisateurs peuvent créer, modifier, compléter et supprimer des tâches.
|
||||
</overview>
|
||||
|
||||
<technology_stack>
|
||||
<frontend>
|
||||
<framework>React avec Vite</framework>
|
||||
<styling>Tailwind CSS</styling>
|
||||
</frontend>
|
||||
<backend>
|
||||
<runtime>Node.js avec Express</runtime>
|
||||
<database>SQLite</database>
|
||||
</backend>
|
||||
</technology_stack>
|
||||
|
||||
<core_features>
|
||||
<feature_1>
|
||||
<title>Interface principale - Liste des tâches</title>
|
||||
<description>Afficher une liste de toutes les tâches avec leur statut</description>
|
||||
<priority>1</priority>
|
||||
<category>frontend</category>
|
||||
<test_steps>
|
||||
1. Ouvrir l'application
|
||||
2. Vérifier que la liste des tâches s'affiche
|
||||
</test_steps>
|
||||
</feature_1>
|
||||
|
||||
<feature_2>
|
||||
<title>Créer une nouvelle tâche</title>
|
||||
<description>Formulaire pour ajouter une nouvelle tâche à la liste</description>
|
||||
<priority>1</priority>
|
||||
<category>frontend</category>
|
||||
<test_steps>
|
||||
1. Cliquer sur "Nouvelle tâche"
|
||||
2. Entrer un titre
|
||||
3. Cliquer sur "Ajouter"
|
||||
4. Vérifier que la tâche apparaît dans la liste
|
||||
</test_steps>
|
||||
</feature_2>
|
||||
</core_features>
|
||||
</project_specification>
|
||||
```
|
||||
|
||||
## Fichiers à Conserver du Framework
|
||||
|
||||
Ces fichiers sont **génériques** et fonctionnent pour toutes les applications :
|
||||
|
||||
- ✅ `autonomous_agent_demo.py` - Point d'entrée
|
||||
- ✅ `agent.py` - Logique des agents
|
||||
- ✅ `client.py` - Configuration Claude SDK
|
||||
- ✅ `prompts.py` - Chargement des prompts
|
||||
- ✅ `progress.py` - Suivi de progression
|
||||
- ✅ `security.py` - Sécurité
|
||||
- ✅ `linear_config.py` - Config Linear
|
||||
- ✅ `prompts/initializer_prompt.md` - Template initializer
|
||||
- ✅ `prompts/initializer_bis_prompt.md` - Template initializer bis
|
||||
- ✅ `prompts/coding_prompt.md` - Template coding agent
|
||||
- ✅ `requirements.txt` - Dépendances Python
|
||||
|
||||
## Fichiers à Créer pour Votre Application
|
||||
|
||||
- ✅ `prompts/app_spec.txt` - **Votre spécification (le seul fichier à créer !)**
|
||||
|
||||
## Résumé
|
||||
|
||||
Pour créer une nouvelle application :
|
||||
|
||||
1. **Copiez la structure XML** de `prompts/app_spec.txt` (exemple Claude Clone)
|
||||
2. **Adaptez le contenu** à votre application
|
||||
3. **Définissez toutes vos fonctionnalités** avec des balises `<feature_X>`
|
||||
4. **Lancez** : `python autonomous_agent_demo.py --project-dir ./mon_app`
|
||||
5. **Suivez le progrès** dans Linear
|
||||
|
||||
Le framework s'occupe du reste ! 🚀
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,318 +0,0 @@
|
||||
# Modifications du système de backup des conversations
|
||||
|
||||
**Date** : 2025-12-20
|
||||
**Objectif** : Utiliser `append_to_conversation` au lieu de `addThought` pour avoir des embeddings complets par message
|
||||
|
||||
---
|
||||
|
||||
## Problème identifié
|
||||
|
||||
### Ancien système (conversationBackup.js)
|
||||
```javascript
|
||||
// ❌ Tronquait chaque message à 200 chars
|
||||
const preview = msg.content.substring(0, 200);
|
||||
|
||||
// ❌ Utilisait addThought() qui crée UN SEUL document
|
||||
await addThought(summary, context);
|
||||
```
|
||||
|
||||
**Résultat** :
|
||||
- Messages tronqués à 200 caractères
|
||||
- Un seul document pour toute la conversation
|
||||
- Perte massive d'information
|
||||
- Modèle BAAI/bge-m3 (8192 tokens) sous-utilisé
|
||||
|
||||
---
|
||||
|
||||
## Nouveau système
|
||||
|
||||
### 1. memoryService_updated.js
|
||||
|
||||
**Changements** :
|
||||
- `{role, content}` → `{author, content, timestamp, thinking}`
|
||||
- Ajout de `options.participants` (requis pour création)
|
||||
- Ajout de `options.context` (requis pour création)
|
||||
|
||||
```javascript
|
||||
export async function appendToConversation(conversationId, newMessages, options = {}) {
|
||||
// newMessages: [{author, content, timestamp, thinking}, ...]
|
||||
// options.participants: ["user", "assistant"]
|
||||
// options.context: {category, tags, summary, date, ...}
|
||||
|
||||
const args = {
|
||||
conversation_id: conversationId,
|
||||
new_messages: newMessages
|
||||
};
|
||||
|
||||
if (options.participants) {
|
||||
args.participants = options.participants;
|
||||
}
|
||||
|
||||
if (options.context) {
|
||||
args.context = options.context;
|
||||
}
|
||||
|
||||
const response = await callMCPTool('append_to_conversation', args);
|
||||
}
|
||||
```
|
||||
|
||||
### 2. conversationBackup_updated.js
|
||||
|
||||
**Changements** :
|
||||
|
||||
#### Avant (addThought) :
|
||||
```javascript
|
||||
// ❌ Tronqué
|
||||
messages.forEach((msg) => {
|
||||
const preview = msg.content.substring(0, 200);
|
||||
summary += `[${msg.role}]: ${preview}...\n\n`;
|
||||
});
|
||||
|
||||
await addThought(summary, {...});
|
||||
```
|
||||
|
||||
#### Après (appendToConversation) :
|
||||
```javascript
|
||||
// ✅ Messages COMPLETS
|
||||
const formattedMessages = messages.map(msg => ({
|
||||
author: msg.role,
|
||||
content: msg.content, // PAS DE TRUNCATION !
|
||||
timestamp: msg.created_at,
|
||||
thinking: msg.thinking_content // Support Extended Thinking
|
||||
}));
|
||||
|
||||
await appendToConversation(
|
||||
conversationId,
|
||||
formattedMessages, // Tous les messages complets
|
||||
{
|
||||
participants: ['user', 'assistant'],
|
||||
context: {
|
||||
category,
|
||||
tags,
|
||||
summary,
|
||||
date,
|
||||
title,
|
||||
key_insights: []
|
||||
}
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Architecture ChromaDB
|
||||
|
||||
### Ce que append_to_conversation fait dans mcp_ikario_memory.py :
|
||||
|
||||
```python
|
||||
# 1. Document PRINCIPAL : conversation complète (contexte global)
|
||||
conversations.add(
|
||||
documents=[full_conversation_text], # Texte complet
|
||||
metadatas=[main_metadata],
|
||||
ids=[conversation_id]
|
||||
)
|
||||
|
||||
# 2. Documents INDIVIDUELS : chaque message séparément
|
||||
for msg in messages:
|
||||
conversations.add(
|
||||
documents=[msg_content], # Message COMPLET (8192 tokens max)
|
||||
metadatas=[msg_metadata],
|
||||
ids=[f"{conversation_id}_msg_{i}"]
|
||||
)
|
||||
```
|
||||
|
||||
### Résultat :
|
||||
- 1 conversation de 31 messages = **32 documents ChromaDB** :
|
||||
- 1 document principal (vue d'ensemble)
|
||||
- 31 documents individuels (granularité message par message)
|
||||
- Chaque message a son **embedding complet** (jusqu'à 8192 tokens avec BAAI/bge-m3)
|
||||
- Recherche sémantique précise par message
|
||||
|
||||
---
|
||||
|
||||
## Avantages
|
||||
|
||||
### 1. Couverture complète
|
||||
| Taille message | Ancien système | Nouveau système |
|
||||
|----------------|----------------|-----------------|
|
||||
| 200 chars | 100% | 100% |
|
||||
| 1,000 chars | 20% | 100% |
|
||||
| 5,000 chars | 4% | 100% |
|
||||
| 10,000 chars | 2% | 100% |
|
||||
|
||||
### 2. Recherche sémantique précise
|
||||
- Une conversation longue avec plusieurs sujets → plusieurs embeddings pertinents
|
||||
- Recherche "concept X" trouve exactement le message qui en parle
|
||||
- Pas de noyade dans un résumé global
|
||||
|
||||
### 3. Support Extended Thinking
|
||||
- Le champ `thinking_content` est préservé
|
||||
- Inclus dans les embeddings pour enrichir la sémantique
|
||||
- Visible dans les métadonnées
|
||||
|
||||
### 4. Idempotence
|
||||
- `append_to_conversation` auto-détecte si la conversation existe
|
||||
- Si nouvelle → crée avec `add_conversation`
|
||||
- Si existe → ajoute seulement nouveaux messages
|
||||
- Pas d'erreur si on re-backup
|
||||
|
||||
---
|
||||
|
||||
## Fichiers créés
|
||||
|
||||
### 1. `/server/services/memoryService_updated.js`
|
||||
- Version mise à jour de `appendToConversation()`
|
||||
- Accepte `participants` et `context`
|
||||
- Utilise `{author, content, timestamp, thinking}`
|
||||
|
||||
### 2. `/server/services/conversationBackup_updated.js`
|
||||
- Remplace `addThought()` par `appendToConversation()`
|
||||
- Envoie tous les messages COMPLETS
|
||||
- Support Extended Thinking
|
||||
- Logs détaillés
|
||||
|
||||
### 3. `/test_backup_conversation.js`
|
||||
- Script de test standalone
|
||||
- Backup manuel d'une conversation
|
||||
- Affiche statistiques et couverture
|
||||
- Vérification des résultats
|
||||
|
||||
---
|
||||
|
||||
## Test du nouveau système
|
||||
|
||||
### Étape 1 : Lancer le serveur my_project
|
||||
|
||||
```bash
|
||||
cd C:/GitHub/Linear_coding/generations/my_project/server
|
||||
npm start
|
||||
```
|
||||
|
||||
### Étape 2 : Lancer le serveur MCP Ikario RAG
|
||||
|
||||
```bash
|
||||
cd C:/Users/david/SynologyDrive/ikario/ikario_rag
|
||||
python -m mcp_server
|
||||
```
|
||||
|
||||
### Étape 3 : Tester le backup
|
||||
|
||||
```bash
|
||||
cd C:/GitHub/Linear_coding/generations/my_project
|
||||
node test_backup_conversation.js
|
||||
```
|
||||
|
||||
### Résultat attendu :
|
||||
|
||||
```
|
||||
TESTING BACKUP FOR: "test tes mémoires"
|
||||
ID: 37fe0a0c-475c-4048-8433-adb40217dce7
|
||||
Messages: 31
|
||||
=================================================================================
|
||||
|
||||
Message breakdown:
|
||||
1. user: 45 chars
|
||||
2. assistant: 1234 chars
|
||||
3. user: 67 chars
|
||||
...
|
||||
31. assistant: 890 chars
|
||||
|
||||
Total: 12,345 chars (~2,469 words)
|
||||
|
||||
Embedding coverage estimation:
|
||||
OLD (all-MiniLM-L6-v2, 256 tokens): 8.3%
|
||||
NEW (BAAI/bge-m3, 8192 tokens): 100.0%
|
||||
Improvement: +91.7%
|
||||
|
||||
Starting backup...
|
||||
|
||||
SUCCESS! Conversation backed up to Ikario RAG
|
||||
|
||||
What was saved:
|
||||
- 31 COMPLETE messages
|
||||
- Each message has its own embedding (no truncation)
|
||||
- Model: BAAI/bge-m3 (8192 tokens max per message)
|
||||
- Category: thematique
|
||||
- Tags: Intelligence, Philosophie, Mémoire
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Vérification dans ChromaDB
|
||||
|
||||
```bash
|
||||
cd C:/Users/david/SynologyDrive/ikario/ikario_rag
|
||||
python -c "
|
||||
import chromadb
|
||||
client = chromadb.PersistentClient(path='./index')
|
||||
conv = client.get_collection('conversations')
|
||||
|
||||
# Compter documents
|
||||
all_docs = conv.get()
|
||||
print(f'Total documents: {len(all_docs[\"ids\"])}')
|
||||
|
||||
# Compter pour conversation test
|
||||
conv_docs = [id for id in all_docs['ids'] if id.startswith('37fe0a0c')]
|
||||
print(f'Documents pour conversation test: {len(conv_docs)}')
|
||||
print(f' - 1 document principal + {len(conv_docs)-1} messages individuels')
|
||||
"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Prochaines étapes
|
||||
|
||||
### Phase 2 (optionnel) : Chunking pour messages >8192 tokens
|
||||
|
||||
Si certains messages dépassent 8192 tokens :
|
||||
- Implémenter chunking intelligent
|
||||
- Préserver la cohérence sémantique
|
||||
- Metadata: message_id + chunk_position
|
||||
|
||||
**Pour l'instant** : 8192 tokens = ~32,000 caractères = suffisant pour 99% des messages.
|
||||
|
||||
---
|
||||
|
||||
## Migration
|
||||
|
||||
### Pour activer le nouveau système :
|
||||
|
||||
1. **Remplacer** `memoryService.js` par `memoryService_updated.js`
|
||||
2. **Remplacer** `conversationBackup.js` par `conversationBackup_updated.js`
|
||||
3. **Redémarrer** le serveur my_project
|
||||
4. Les nouveaux backups utiliseront automatiquement le nouveau système
|
||||
5. Les anciennes conversations peuvent être re-backupées (réinitialiser `has_memory_backup`)
|
||||
|
||||
### Commandes :
|
||||
|
||||
```bash
|
||||
cd C:/GitHub/Linear_coding/generations/my_project/server/services
|
||||
|
||||
# Backup des fichiers originaux
|
||||
cp memoryService.js memoryService.original.js
|
||||
cp conversationBackup.js conversationBackup.original.js
|
||||
|
||||
# Activer les nouvelles versions
|
||||
cp memoryService_updated.js memoryService.js
|
||||
cp conversationBackup_updated.js conversationBackup.js
|
||||
|
||||
# Redémarrer le serveur
|
||||
npm start
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Résumé
|
||||
|
||||
| Aspect | Avant | Après |
|
||||
|--------|-------|-------|
|
||||
| **Méthode** | `addThought()` | `appendToConversation()` |
|
||||
| **Stockage** | Collection `thoughts` | Collection `conversations` |
|
||||
| **Granularité** | 1 doc/conversation | 1 doc principal + N docs messages |
|
||||
| **Troncation** | 200 chars/message ❌ | Aucune (8192 tokens) ✅ |
|
||||
| **Embedding** | Résumé tronqué | Chaque message complet |
|
||||
| **Thinking** | Non supporté | Supporté ✅ |
|
||||
| **Recherche** | Approximative | Précise par message ✅ |
|
||||
| **Idempotence** | Non | Oui (auto-detect) ✅ |
|
||||
|
||||
**Gain** : De 1.2% à 38-40% de couverture pour conversations longues (>20,000 mots)
|
||||
282
README.md
282
README.md
@@ -64,8 +64,10 @@ pip show claude-code-sdk # Check SDK is installed
|
||||
|
||||
## Quick Start
|
||||
|
||||
### Option 1: Use the Example (Claude Clone)
|
||||
|
||||
```bash
|
||||
# Initialize a new project
|
||||
# Initialize the Claude Clone example project
|
||||
python autonomous_agent_demo.py --project-dir ./my_project
|
||||
|
||||
# Add new features to an existing project
|
||||
@@ -77,6 +79,10 @@ For testing with limited iterations:
|
||||
python autonomous_agent_demo.py --project-dir ./my_project --max-iterations 3
|
||||
```
|
||||
|
||||
### Option 2: Create Your Own Application
|
||||
|
||||
See the [Creating a New Application](#creating-a-new-application) section below for detailed instructions on creating a custom application from scratch.
|
||||
|
||||
## How It Works
|
||||
|
||||
### Linear-Centric Workflow
|
||||
@@ -192,7 +198,6 @@ linear-agent-harness/
|
||||
│ ├── initializer_prompt.md # First session prompt (creates Linear issues)
|
||||
│ ├── initializer_bis_prompt.md # Prompt for adding new features
|
||||
│ └── coding_prompt.md # Continuation session prompt (works issues)
|
||||
├── GUIDE_NEW_APP.md # Guide pour créer une nouvelle application
|
||||
└── requirements.txt # Python dependencies
|
||||
```
|
||||
|
||||
@@ -241,28 +246,261 @@ The initializer agent will create:
|
||||
|
||||
All subsequent coding agents will work from this Linear project.
|
||||
|
||||
## Creating a New Application
|
||||
|
||||
This framework is designed to be **generic and reusable** for any web application. Here's how to create your own application from scratch.
|
||||
|
||||
### Understanding the Framework Structure
|
||||
|
||||
#### Generic Framework Files (DO NOT MODIFY)
|
||||
|
||||
These files work for all applications and should remain unchanged:
|
||||
|
||||
```
|
||||
linear-coding-agent/
|
||||
├── autonomous_agent_demo.py # Main entry point
|
||||
├── agent.py # Agent session logic
|
||||
├── client.py # Claude SDK + MCP client configuration
|
||||
├── security.py # Bash command allowlist and validation
|
||||
├── progress.py # Progress tracking utilities
|
||||
├── prompts.py # Prompt loading utilities
|
||||
├── linear_config.py # Linear configuration constants
|
||||
├── requirements.txt # Python dependencies
|
||||
└── prompts/
|
||||
├── initializer_prompt.md # First session prompt template
|
||||
├── initializer_bis_prompt.md # New features prompt template
|
||||
└── coding_prompt.md # Continuation session prompt template
|
||||
```
|
||||
|
||||
#### Application-Specific Files (CREATE THESE)
|
||||
|
||||
The **only file you need to create** is your application specification:
|
||||
|
||||
```
|
||||
prompts/
|
||||
└── app_spec.txt # Your application specification (XML format)
|
||||
```
|
||||
|
||||
### Step-by-Step Guide
|
||||
|
||||
#### Step 1: Create Your Specification File
|
||||
|
||||
Create `prompts/app_spec.txt` using this XML structure:
|
||||
|
||||
```xml
|
||||
<project_specification>
|
||||
<project_name>Your Application Name</project_name>
|
||||
|
||||
<overview>
|
||||
Complete description of your application. Explain what you want to build,
|
||||
main objectives, and key features.
|
||||
</overview>
|
||||
|
||||
<technology_stack>
|
||||
<frontend>
|
||||
<framework>React with Vite</framework>
|
||||
<styling>Tailwind CSS</styling>
|
||||
<state_management>React hooks</state_management>
|
||||
</frontend>
|
||||
<backend>
|
||||
<runtime>Node.js with Express</runtime>
|
||||
<database>SQLite</database>
|
||||
</backend>
|
||||
</technology_stack>
|
||||
|
||||
<prerequisites>
|
||||
<environment_setup>
|
||||
- List of prerequisites (dependencies, API keys, etc.)
|
||||
</environment_setup>
|
||||
</prerequisites>
|
||||
|
||||
<core_features>
|
||||
<feature_1>
|
||||
<title>Feature 1 Title</title>
|
||||
<description>Detailed description</description>
|
||||
<priority>1</priority>
|
||||
<category>frontend</category>
|
||||
<test_steps>
|
||||
1. Test step 1
|
||||
2. Test step 2
|
||||
</test_steps>
|
||||
</feature_1>
|
||||
|
||||
<feature_2>
|
||||
<!-- More features -->
|
||||
</feature_2>
|
||||
</core_features>
|
||||
</project_specification>
|
||||
```
|
||||
|
||||
#### Step 2: Define Your Features
|
||||
|
||||
Each feature should have:
|
||||
|
||||
- **Title**: Clear, descriptive title
|
||||
- **Description**: Complete explanation of what it does
|
||||
- **Priority**: 1 (urgent) to 4 (optional)
|
||||
- **Category**: `frontend`, `backend`, `database`, `auth`, `integration`, etc.
|
||||
- **Test Steps**: Precise verification steps
|
||||
|
||||
Example feature:
|
||||
|
||||
```xml
|
||||
<feature_1>
|
||||
<title>User Authentication - Login Flow</title>
|
||||
<description>
|
||||
Implement authentication system with:
|
||||
- Login form (email/password)
|
||||
- Client and server-side validation
|
||||
- JWT session management
|
||||
- Password reset page
|
||||
</description>
|
||||
<priority>1</priority>
|
||||
<category>auth</category>
|
||||
<test_steps>
|
||||
1. Access login page
|
||||
2. Enter invalid email → see error
|
||||
3. Enter valid credentials → redirect to dashboard
|
||||
4. Verify JWT token is stored
|
||||
5. Test logout functionality
|
||||
</test_steps>
|
||||
</feature_1>
|
||||
```
|
||||
|
||||
#### Step 3: Launch Initialization
|
||||
|
||||
Once your `app_spec.txt` is ready:
|
||||
|
||||
```bash
|
||||
python autonomous_agent_demo.py --project-dir ./my_new_app
|
||||
```
|
||||
|
||||
The initializer agent will:
|
||||
1. Read your `app_spec.txt`
|
||||
2. Create a Linear project
|
||||
3. Create ~50 Linear issues based on your spec
|
||||
4. Initialize project structure, `init.sh`, and git
|
||||
|
||||
#### Step 4: Monitor Development
|
||||
|
||||
Coding agents will then:
|
||||
- Work on Linear issues one by one
|
||||
- Implement features
|
||||
- Test with Puppeteer browser automation
|
||||
- Update issues with implementation comments
|
||||
- Mark issues as complete
|
||||
|
||||
### Minimal Example
|
||||
|
||||
Here's a minimal Todo App example to get started:
|
||||
|
||||
```xml
|
||||
<project_specification>
|
||||
<project_name>Todo App - Task Manager</project_name>
|
||||
|
||||
<overview>
|
||||
Simple web application for managing task lists.
|
||||
Users can create, edit, complete, and delete tasks.
|
||||
</overview>
|
||||
|
||||
<technology_stack>
|
||||
<frontend>
|
||||
<framework>React with Vite</framework>
|
||||
<styling>Tailwind CSS</styling>
|
||||
</frontend>
|
||||
<backend>
|
||||
<runtime>Node.js with Express</runtime>
|
||||
<database>SQLite</database>
|
||||
</backend>
|
||||
</technology_stack>
|
||||
|
||||
<core_features>
|
||||
<feature_1>
|
||||
<title>Main Interface - Task List</title>
|
||||
<description>Display a list of all tasks with their status</description>
|
||||
<priority>1</priority>
|
||||
<category>frontend</category>
|
||||
<test_steps>
|
||||
1. Open application
|
||||
2. Verify task list displays
|
||||
</test_steps>
|
||||
</feature_1>
|
||||
|
||||
<feature_2>
|
||||
<title>Create New Task</title>
|
||||
<description>Form to add a new task to the list</description>
|
||||
<priority>1</priority>
|
||||
<category>frontend</category>
|
||||
<test_steps>
|
||||
1. Click "New Task"
|
||||
2. Enter a title
|
||||
3. Click "Add"
|
||||
4. Verify task appears in list
|
||||
</test_steps>
|
||||
</feature_2>
|
||||
</core_features>
|
||||
</project_specification>
|
||||
```
|
||||
|
||||
### Best Practices
|
||||
|
||||
#### 1. Be Detailed but Structured
|
||||
|
||||
Each feature must have:
|
||||
- Clear title
|
||||
- Complete description of functionality
|
||||
- Precise test steps
|
||||
- Priority (1=urgent, 4=optional)
|
||||
|
||||
#### 2. Use Consistent XML Format
|
||||
|
||||
Follow the structure shown above for all features using `<feature_X>` tags.
|
||||
|
||||
#### 3. Organize by Categories
|
||||
|
||||
Group features by category:
|
||||
- `auth`: Authentication
|
||||
- `frontend`: User interface
|
||||
- `backend`: API and server logic
|
||||
- `database`: Models and migrations
|
||||
- `integration`: External integrations
|
||||
|
||||
#### 4. Prioritize Features
|
||||
|
||||
- **Priority 1**: Critical features (auth, database)
|
||||
- **Priority 2**: Important features (core functionality)
|
||||
- **Priority 3**: Secondary features (UX improvements)
|
||||
- **Priority 4**: Nice-to-have (polish, optimizations)
|
||||
|
||||
### Using the Claude Clone as Reference
|
||||
|
||||
The Claude Clone example in `prompts/app_spec.txt` is excellent reference material:
|
||||
|
||||
#### ✅ Elements to Copy/Adapt:
|
||||
|
||||
1. **XML Structure**: Overall structure with `<project_specification>`, `<overview>`, `<technology_stack>`, etc.
|
||||
2. **Feature Format**: How to structure `<feature_X>` tags with all required fields
|
||||
3. **Technical Details**: How to describe technology stack, prerequisites, API endpoints, database schema, UI specs
|
||||
|
||||
#### ❌ Elements NOT to Copy:
|
||||
|
||||
1. **Specific Content**: Details about "Claude API", "artifacts", "conversations" are app-specific
|
||||
2. **Business Features**: Adapt features to your application's needs
|
||||
|
||||
### Checklist for New Application
|
||||
|
||||
- [ ] Create `prompts/app_spec.txt` with your specification
|
||||
- [ ] Define `<project_name>` for your application
|
||||
- [ ] Write complete `<overview>`
|
||||
- [ ] Specify `<technology_stack>` (frontend + backend)
|
||||
- [ ] List all `<prerequisites>`
|
||||
- [ ] Define all `<core_features>` with `<feature_X>` tags
|
||||
- [ ] Add `<test_steps>` for each feature
|
||||
- [ ] Launch: `python autonomous_agent_demo.py --project-dir ./my_app`
|
||||
- [ ] Verify in Linear that issues are created correctly
|
||||
|
||||
## Customization
|
||||
|
||||
### Creating a New Application from Scratch
|
||||
|
||||
To create a **completely new application** (not based on the Claude Clone example):
|
||||
|
||||
1. **Read the guide**: See [GUIDE_NEW_APP.md](GUIDE_NEW_APP.md) for detailed instructions
|
||||
2. **Use the template**: Copy `prompts/app_spec_template.txt` as a starting point
|
||||
3. **Reference the example**: Use `prompts/app_spec.txt` (Claude Clone) as a reference for structure and detail level
|
||||
4. **Create your spec**: Write your `prompts/app_spec.txt` with your application specification
|
||||
5. **Launch**: Run `python autonomous_agent_demo.py --project-dir ./my_new_app`
|
||||
|
||||
**Key points:**
|
||||
- Keep the framework files unchanged (they're generic and reusable)
|
||||
- Only create/modify `prompts/app_spec.txt` for your new application
|
||||
- Use the XML structure from the Claude Clone example as a template
|
||||
- Define features with `<feature_X>` tags - each will become a Linear issue
|
||||
|
||||
### Changing the Application
|
||||
|
||||
Edit `prompts/app_spec.txt` to specify a different application to build.
|
||||
|
||||
### Adding New Features to Existing Projects
|
||||
|
||||
1. Create a new specification file in `prompts/` directory (e.g., `app_spec_new_feature.txt`)
|
||||
|
||||
@@ -15,8 +15,15 @@ Example Usage:
|
||||
import argparse
|
||||
import asyncio
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
# Fix Windows encoding issues with emojis and Unicode characters
|
||||
if sys.platform == 'win32':
|
||||
import io
|
||||
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', errors='replace')
|
||||
sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8', errors='replace')
|
||||
|
||||
from dotenv import load_dotenv
|
||||
from agent import run_autonomous_agent
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ services:
|
||||
- "4300:3000"
|
||||
environment:
|
||||
- NODE_ENV=development
|
||||
- DOCKER_ENV=true
|
||||
|
||||
my_project_server:
|
||||
image: node:20
|
||||
|
||||
143
fix_stats.mjs
143
fix_stats.mjs
@@ -1,143 +0,0 @@
|
||||
// Script pour corriger getMemoryStats() dans memoryService.js
|
||||
import fs from 'fs';
|
||||
|
||||
const filePath = 'C:/GitHub/Linear_coding/generations/my_project/server/services/memoryService.js';
|
||||
let content = fs.readFileSync(filePath, 'utf8');
|
||||
|
||||
// Trouver et remplacer la fonction getMemoryStats
|
||||
const oldFunction = `/**
|
||||
* Get basic statistics about the memory store
|
||||
* This is a convenience function that uses searchMemories to estimate count
|
||||
*
|
||||
* @returns {Promise<Object>} Statistics about the memory store
|
||||
*/
|
||||
export async function getMemoryStats() {
|
||||
const status = getMCPStatus();
|
||||
|
||||
if (!isMCPConnected()) {
|
||||
return {
|
||||
connected: false,
|
||||
enabled: status.enabled,
|
||||
configured: status.configured,
|
||||
total_memories: 0,
|
||||
last_save: null,
|
||||
error: status.error,
|
||||
serverPath: status.serverPath,
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
// Try to get a rough count by searching with a broad query
|
||||
const result = await searchMemories('*', 1);
|
||||
|
||||
return {
|
||||
connected: true,
|
||||
enabled: status.enabled,
|
||||
configured: status.configured,
|
||||
total_memories: result.count || 0,
|
||||
last_save: new Date().toISOString(), // Would need to track this separately
|
||||
error: null,
|
||||
serverPath: status.serverPath,
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
connected: true,
|
||||
enabled: status.enabled,
|
||||
configured: status.configured,
|
||||
total_memories: 0,
|
||||
last_save: null,
|
||||
error: error.message,
|
||||
serverPath: status.serverPath,
|
||||
};
|
||||
}
|
||||
}`;
|
||||
|
||||
const newFunction = `/**
|
||||
* Get basic statistics about the memory store
|
||||
* Counts thoughts and conversations separately using dedicated search tools
|
||||
*
|
||||
* @returns {Promise<Object>} Statistics about the memory store
|
||||
*/
|
||||
export async function getMemoryStats() {
|
||||
const status = getMCPStatus();
|
||||
|
||||
if (!isMCPConnected()) {
|
||||
return {
|
||||
connected: false,
|
||||
enabled: status.enabled,
|
||||
configured: status.configured,
|
||||
total_memories: 0,
|
||||
thoughts_count: 0,
|
||||
conversations_count: 0,
|
||||
last_save: null,
|
||||
error: status.error,
|
||||
serverPath: status.serverPath,
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
// Count thoughts using search_thoughts with broad query
|
||||
let thoughtsCount = 0;
|
||||
try {
|
||||
const thoughtsResult = await callMCPTool('search_thoughts', {
|
||||
query: 'a', // Simple query that will match most thoughts
|
||||
n_results: 100
|
||||
});
|
||||
|
||||
// Parse the text response to count thoughts
|
||||
const thoughtsText = thoughtsResult.content?.[0]?.text || '';
|
||||
const thoughtMatches = thoughtsText.match(/\\[Pertinence:/g);
|
||||
thoughtsCount = thoughtMatches ? thoughtMatches.length : 0;
|
||||
} catch (err) {
|
||||
console.log('[getMemoryStats] Could not count thoughts:', err.message);
|
||||
}
|
||||
|
||||
// Count conversations using search_conversations with search_level="full"
|
||||
let conversationsCount = 0;
|
||||
try {
|
||||
const convsResult = await callMCPTool('search_conversations', {
|
||||
query: 'a', // Simple query that will match most conversations
|
||||
n_results: 100,
|
||||
search_level: 'full'
|
||||
});
|
||||
|
||||
// Parse the text response to count conversations
|
||||
const convsText = convsResult.content?.[0]?.text || '';
|
||||
const convMatches = convsText.match(/\\[Pertinence:/g);
|
||||
conversationsCount = convMatches ? convMatches.length : 0;
|
||||
} catch (err) {
|
||||
console.log('[getMemoryStats] Could not count conversations:', err.message);
|
||||
}
|
||||
|
||||
const totalMemories = thoughtsCount + conversationsCount;
|
||||
|
||||
return {
|
||||
connected: true,
|
||||
enabled: status.enabled,
|
||||
configured: status.configured,
|
||||
total_memories: totalMemories,
|
||||
thoughts_count: thoughtsCount,
|
||||
conversations_count: conversationsCount,
|
||||
last_save: new Date().toISOString(), // Would need to track this separately
|
||||
error: null,
|
||||
serverPath: status.serverPath,
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
connected: true,
|
||||
enabled: status.enabled,
|
||||
configured: status.configured,
|
||||
total_memories: 0,
|
||||
thoughts_count: 0,
|
||||
conversations_count: 0,
|
||||
last_save: null,
|
||||
error: error.message,
|
||||
serverPath: status.serverPath,
|
||||
};
|
||||
}
|
||||
}`;
|
||||
|
||||
content = content.replace(oldFunction, newFunction);
|
||||
|
||||
fs.writeFileSync(filePath, content, 'utf8');
|
||||
console.log('File updated successfully');
|
||||
26021
ikario_memories_export.md
Normal file
26021
ikario_memories_export.md
Normal file
File diff suppressed because it is too large
Load Diff
420
navette.txt
420
navette.txt
@@ -2087,4 +2087,424 @@ RESUME DES CHANGEMENTS:
|
||||
|
||||
LE SPEC EST PRET pour creation des issues!
|
||||
|
||||
COMMIT GIT CREE:
|
||||
Commit: 3a17744
|
||||
Message: "Update UI spec for append_to_conversation and thinking support"
|
||||
|
||||
Fichiers commites:
|
||||
- prompts/app_spec_ikario_rag_UI.txt (spec mis a jour)
|
||||
- navette.txt (ce fichier)
|
||||
|
||||
================================================================================
|
||||
ETAT ACTUEL - RECAPITULATIF COMPLET
|
||||
================================================================================
|
||||
|
||||
TRAVAIL TERMINE:
|
||||
✓ Plan detaille cree (7 phases)
|
||||
✓ Commit backup (55d905b)
|
||||
✓ Modifications mcp_ikario_memory.py (support thinking + append_to_conversation)
|
||||
✓ Modifications server.py (8eme outil MCP expose)
|
||||
✓ Tests automatises (6/6 reussis)
|
||||
✓ Commit implementation (cba84fe)
|
||||
✓ Spec UI mis a jour (8 sections modifiees)
|
||||
✓ Commit spec UI (3a17744)
|
||||
|
||||
COMMITS CREES (3 au total):
|
||||
1. 55d905b - Backup before adding append_to_conversation
|
||||
2. cba84fe - Add append_to_conversation with thinking support (ikario_rag)
|
||||
3. 3a17744 - Update UI spec (Linear_coding)
|
||||
|
||||
OUTILS MCP DISPONIBLES (8):
|
||||
1. add_thought
|
||||
2. add_conversation (avec thinking optionnel)
|
||||
3. append_to_conversation (NOUVEAU - incremental + auto-create + thinking)
|
||||
4. search_thoughts
|
||||
5. search_conversations
|
||||
6. search_memories
|
||||
7. trace_concept_evolution
|
||||
8. check_consistency
|
||||
|
||||
NOUVEAU FORMAT MESSAGE:
|
||||
{
|
||||
"author": "assistant",
|
||||
"content": "Reponse visible",
|
||||
"thinking": "Raisonnement interne LLM", // OPTIONNEL
|
||||
"timestamp": "ISO date"
|
||||
}
|
||||
|
||||
================================================================================
|
||||
PROCHAINES ACTIONS RECOMMANDEES
|
||||
================================================================================
|
||||
|
||||
1. SUPPRIMER ancien spec (app_spec_ikario_rag_improvements.txt)
|
||||
- Cause confusion (parle de modifier ikario_rag)
|
||||
- Nouveau spec est complet
|
||||
|
||||
2. SUPPRIMER 15 anciennes issues Linear (TEAMPHI-305 a 319)
|
||||
- Ces issues parlent de modifier ikario_rag (on ne veut plus)
|
||||
- Clean slate pour nouvelles issues
|
||||
|
||||
3. CREER 15 nouvelles issues avec nouveau spec
|
||||
- Utiliser: python autonomous_agent_demo.py --project-dir my_project --new-spec app_spec_ikario_rag_UI.txt
|
||||
- Mode: initializer bis
|
||||
- Issues pour developper dans my_project uniquement
|
||||
|
||||
4. LANCER agent coding
|
||||
- Apres creation des issues
|
||||
- Mode: coding agent
|
||||
- Developper les 15 features UI
|
||||
|
||||
VEUX-TU QUE JE CONTINUE?
|
||||
Options:
|
||||
a) OUI - Supprimer ancien spec + anciennes issues + creer nouvelles issues
|
||||
b) ATTENDRE - Tu veux verifier quelque chose avant
|
||||
c) MODIFIER - Tu veux changer le plan
|
||||
|
||||
================================================================================
|
||||
CLARIFICATIONS IMPORTANTES - TES QUESTIONS
|
||||
================================================================================
|
||||
Date: 20 decembre 2025 - 00h45
|
||||
|
||||
QUESTION 1: Difference entre search_thoughts et search_memories?
|
||||
----------------------------------------------------------------
|
||||
|
||||
J'ai verifie le code mcp_ikario_memory.py:
|
||||
|
||||
search_thoughts (lignes 191-224):
|
||||
- Recherche SEULEMENT dans la collection "thoughts"
|
||||
- Filtre optionnel: filter_thought_type
|
||||
- Retourne: pensees internes d'Ikario
|
||||
|
||||
search_conversations (lignes 226-282):
|
||||
- Recherche SEULEMENT dans la collection "conversations"
|
||||
- Filtre optionnel: filter_category, search_level
|
||||
- Retourne: conversations David-Ikario
|
||||
|
||||
search_memories (lignes 37-51):
|
||||
- PROBLEME IDENTIFIE!
|
||||
- Code actuel: recherche SEULEMENT dans self.conversations (ligne 43)
|
||||
- Ce n'est PAS une vraie recherche globale!
|
||||
- C'est essentiellement la meme chose que search_conversations
|
||||
|
||||
CONCLUSION:
|
||||
search_memories DEVRAIT faire une recherche globale (thoughts + conversations)
|
||||
mais actuellement il cherche SEULEMENT dans conversations.
|
||||
|
||||
C'est probablement un bug ou une implementation incomplete.
|
||||
|
||||
QUESTION 2: Je melange les deux projets?
|
||||
-----------------------------------------
|
||||
|
||||
OUI, tu as raison! J'ai melange:
|
||||
|
||||
PROJET 1: ikario_rag (C:/Users/david/SynologyDrive/ikario/ikario_rag/)
|
||||
- Backend MCP Python
|
||||
- 8 outils MCP exposes
|
||||
- ChromaDB avec embeddings
|
||||
- CE QU'ON A FAIT:
|
||||
* Ajoute append_to_conversation (mcp_ikario_memory.py)
|
||||
* Ajoute support thinking (mcp_ikario_memory.py)
|
||||
* Expose 8eme outil (server.py)
|
||||
* Tests (test_append_conversation.py)
|
||||
* Commits: 55d905b, cba84fe
|
||||
|
||||
PROJET 2: my_project (C:/GitHub/Linear_coding/generations/my_project/)
|
||||
- Frontend React + Backend Express
|
||||
- Interface utilisateur pour UTILISER les outils MCP d'ikario_rag
|
||||
- CE QU'ON A FAIT:
|
||||
* Cree spec UI (prompts/app_spec_ikario_rag_UI.txt)
|
||||
* Commit: 3a17744
|
||||
* MAIS: rien d'implemente dans my_project encore!
|
||||
|
||||
Le spec UI que j'ai cree est pour PLUS TARD, quand on developpera
|
||||
l'interface dans my_project qui UTILISERA ikario_rag.
|
||||
|
||||
Tu as raison: ON DOIT D'ABORD FINIR ikario_rag!
|
||||
|
||||
================================================================================
|
||||
CE QU'IL RESTE A FAIRE DANS ikario_rag
|
||||
================================================================================
|
||||
|
||||
1. CORRIGER search_memories (bug identifie)
|
||||
- Doit chercher dans thoughts + conversations
|
||||
- Pas seulement conversations
|
||||
|
||||
2. TESTER le serveur MCP complet
|
||||
- Lancer server.py
|
||||
- Tester avec un client MCP reel
|
||||
- Verifier tous les 8 outils fonctionnent
|
||||
|
||||
3. TESTER append_to_conversation via MCP
|
||||
- Via server.py (pas seulement test_append_conversation.py)
|
||||
- Avec thinking optionnel
|
||||
- Auto-create
|
||||
|
||||
4. VERIFIER backward compatibility
|
||||
- Code existant continue de fonctionner
|
||||
- Pas de breaking changes
|
||||
|
||||
ENSUITE SEULEMENT on passera a my_project.
|
||||
|
||||
================================================================================
|
||||
DECISION REQUISE
|
||||
================================================================================
|
||||
|
||||
Veux-tu que je:
|
||||
|
||||
A) CORRIGER search_memories d'abord (recherche globale thoughts + conversations)
|
||||
B) TESTER le serveur MCP tel quel (avec search_memories bugue)
|
||||
C) AUTRE chose?
|
||||
|
||||
Je recommande A: corriger search_memories pour avoir une vraie recherche globale.
|
||||
|
||||
================================================================================
|
||||
CORRECTION search_memories TERMINEE !
|
||||
================================================================================
|
||||
Date: 20 decembre 2025 - 00h55
|
||||
|
||||
PROBLEME IDENTIFIE:
|
||||
search_memories cherchait SEULEMENT dans conversations (ligne 43)
|
||||
Ce n'etait PAS une vraie recherche globale.
|
||||
|
||||
CORRECTION APPLIQUEE (mcp_ikario_memory.py lignes 37-87):
|
||||
1. Recherche dans thoughts
|
||||
2. Recherche dans conversations
|
||||
3. Merge des resultats
|
||||
4. Tri par relevance_score (descendant)
|
||||
5. Ajout champ 'source' (thought vs conversation)
|
||||
6. Retourne top n_results combines
|
||||
|
||||
TESTS CREES (test_search_memories.py):
|
||||
Test 1: Recherche "Python" - trouve thoughts ET conversations ✓
|
||||
Test 2: Verification tri par relevance_score ✓
|
||||
Test 3: Recherche "JavaScript" - trouve conversation ✓
|
||||
Test 4: filter_category (affecte seulement conversations) ✓
|
||||
|
||||
RESULTAT DES TESTS:
|
||||
Found 5 results:
|
||||
- Thoughts: 2
|
||||
- Conversations: 3
|
||||
|
||||
[1] Source: thought | Relevance: 0.513
|
||||
[2] Source: thought | Relevance: 0.502
|
||||
[3] Source: conversation | Relevance: 0.479
|
||||
[4] Source: conversation | Relevance: 0.411
|
||||
[5] Source: conversation | Relevance: 0.165
|
||||
|
||||
✓ search_memories combines thoughts + conversations: OK
|
||||
✓ Results sorted by relevance: OK
|
||||
✓ Source field added: OK
|
||||
|
||||
COMMIT CREE:
|
||||
Commit: 05a4613
|
||||
Message: "Fix search_memories to search in both thoughts and conversations"
|
||||
|
||||
Fichiers modifies:
|
||||
- mcp_ikario_memory.py (fonction search_memories reecrite)
|
||||
- test_search_memories.py (nouveau fichier de test)
|
||||
|
||||
================================================================================
|
||||
ETAT ACTUEL ikario_rag - RESUME COMPLET
|
||||
================================================================================
|
||||
|
||||
COMMITS CREES (4 au total dans ikario_rag):
|
||||
1. 55d905b - Backup before adding append_to_conversation
|
||||
2. cba84fe - Add append_to_conversation with thinking support
|
||||
3. 05a4613 - Fix search_memories (global search)
|
||||
4. (Note: commit 3a17744 est dans Linear_coding, pas ikario_rag)
|
||||
|
||||
OUTILS MCP DISPONIBLES (8):
|
||||
1. add_thought - Ajouter pensee ✓
|
||||
2. add_conversation - Ajouter conversation complete (avec thinking optionnel) ✓
|
||||
3. append_to_conversation - Ajouter messages incrementalement (auto-create + thinking) ✓
|
||||
4. search_thoughts - Rechercher dans thoughts ✓
|
||||
5. search_conversations - Rechercher dans conversations ✓
|
||||
6. search_memories - Recherche GLOBALE (thoughts + conversations) ✓ CORRIGE!
|
||||
7. trace_concept_evolution - Tracer evolution concept ✓
|
||||
8. check_consistency - Verifier coherence ✓
|
||||
|
||||
TESTS REALISES:
|
||||
✓ test_append_conversation.py (6/6 tests) - append + thinking
|
||||
✓ test_search_memories.py (4/4 tests) - recherche globale
|
||||
|
||||
RESTE A FAIRE dans ikario_rag:
|
||||
1. Tester serveur MCP complet (server.py)
|
||||
2. Tester append_to_conversation via MCP protocol (pas seulement Python)
|
||||
3. Verifier backward compatibility
|
||||
|
||||
================================================================================
|
||||
PROCHAINE ETAPE
|
||||
================================================================================
|
||||
|
||||
Veux-tu:
|
||||
|
||||
A) TESTER le serveur MCP complet (lancer server.py et tester avec un client MCP)
|
||||
B) CREER un test MCP pour append_to_conversation
|
||||
C) AUTRE chose?
|
||||
|
||||
Je recommande A: tester le serveur MCP complet pour s'assurer que tout fonctionne via le protocole MCP.
|
||||
|
||||
================================================================================
|
||||
|
||||
================================================================================
|
||||
PROBLEME CRITIQUE: EMBEDDING TRONQUE POUR CONVERSATIONS LONGUES
|
||||
================================================================================
|
||||
Date: 20/12/2025 - 15h30
|
||||
|
||||
PROBLEME IDENTIFIE:
|
||||
-------------------
|
||||
|
||||
1. TRONCATURE MASSIVE:
|
||||
- Modele actuel: all-MiniLM-L6-v2
|
||||
- Limite: 256 tokens (~1000 caracteres)
|
||||
- Conversation Fondatrice #1: 23,574 mots (~106,000 chars)
|
||||
|
||||
RESULTAT:
|
||||
- Stockage ChromaDB: ✅ 106,000 chars complets
|
||||
- Embedding cree sur: ❌ 1,280 chars seulement (1.2%!)
|
||||
- Recherche semantique: ❌ 98.8% de la conversation INVISIBLE
|
||||
|
||||
Si vous cherchez quelque chose discute apres les 256 premiers mots,
|
||||
search_memories ne le trouvera JAMAIS.
|
||||
|
||||
2. QUALITE INSUFFISANTE POUR PHILOSOPHIE:
|
||||
- all-MiniLM-L6-v2: 22M parametres (TRES petit)
|
||||
- Optimise pour: Vitesse, pas comprehension semantique profonde
|
||||
- Langue: Anglais principalement
|
||||
- Performance sur concepts abstraits francais: MAUVAISE
|
||||
|
||||
IMPACT REEL:
|
||||
------------
|
||||
|
||||
Test avec differentes tailles:
|
||||
- 250 chars (50 mots): 100% conserve ✅
|
||||
- 1,000 chars (200 mots): 100% conserve ✅
|
||||
- 2,500 chars (500 mots): 51.2% conserve ⚠️
|
||||
- 10,000 chars (2,000 mots): 12.8% conserve ❌
|
||||
- 106,000 chars (23,574 mots): 1.2% conserve ❌❌❌
|
||||
|
||||
Conversations philosophiques longues = CATASTROPHIQUE
|
||||
|
||||
SOLUTION PROPOSEE:
|
||||
==================
|
||||
|
||||
BENCHMARK DE 3 MODELES:
|
||||
|
||||
1. all-MiniLM-L6-v2 (ACTUEL):
|
||||
- Parametres: 22M
|
||||
- Dimension: 384
|
||||
- Max tokens: 256
|
||||
- Langue: Anglais
|
||||
- Qualite: Basique
|
||||
- Pour Conv Fondatrice #1: 1.2% indexe
|
||||
- VERDICT: ❌ Inadequat
|
||||
|
||||
2. intfloat/multilingual-e5-large:
|
||||
- Parametres: 560M (25x plus puissant)
|
||||
- Dimension: 1024 (2.7x plus riche)
|
||||
- Max tokens: 512 (2x plus long)
|
||||
- Langue: Excellent francais + multilingue
|
||||
- Qualite: State-of-the-art semantique
|
||||
- Pour Conv Fondatrice #1: ~2.4% indexe
|
||||
- VERDICT: ⚠️ Mieux mais encore insuffisant
|
||||
|
||||
3. BAAI/bge-m3 (RECOMMANDE PAR DAVID):
|
||||
- Parametres: 568M
|
||||
- Dimension: 1024
|
||||
- Max tokens: 8192 (32x plus long!)
|
||||
- Langue: Multilingue excellent (francais inclus)
|
||||
- Qualite: State-of-the-art retrieval
|
||||
- Features: Dense + Sparse + Multi-vector retrieval (hybrid)
|
||||
- Pour Conv Fondatrice #1: ~38-40% indexe
|
||||
- VERDICT: ✅✅✅ EXCELLENT CHOIX!
|
||||
|
||||
AVANTAGES BAAI/bge-m3:
|
||||
----------------------
|
||||
✅ Max tokens 8192 vs 256 actuel (32x amelioration!)
|
||||
✅ Hybrid retrieval (dense+sparse) pour meilleure precision
|
||||
✅ Specialement concu pour retrieval multilingue
|
||||
✅ Excellent sur benchmarks MTEB (top 3 mondial)
|
||||
✅ Supporte francais nativement
|
||||
✅ Comprehension semantique profonde pour concepts abstraits
|
||||
✅ Pour conversation 23,574 mots: conserve ~9,000 mots vs 256 actuellement
|
||||
|
||||
PLAN D'ACTION PROPOSE:
|
||||
======================
|
||||
|
||||
OPTION A - UPGRADE MODELE SEUL (RAPIDE):
|
||||
-----------------------------------------
|
||||
1. Remplacer all-MiniLM-L6-v2 par BAAI/bge-m3 dans ikario_rag
|
||||
2. Re-indexer toutes conversations existantes
|
||||
3. Tester performance recherche
|
||||
|
||||
Fichier a modifier:
|
||||
- C:/Users/david/SynologyDrive/ikario/ikario_rag/mcp_ikario_memory.py
|
||||
Ligne 31: self.embedder = SentenceTransformer('all-MiniLM-L6-v2')
|
||||
→ Remplacer par: self.embedder = SentenceTransformer('BAAI/bge-m3')
|
||||
|
||||
Avantages:
|
||||
✅ Simple (1 ligne a changer)
|
||||
✅ Amelioration immediate et massive
|
||||
✅ Pas besoin chunking
|
||||
|
||||
Inconvenients:
|
||||
⚠️ Download modele ~2.3GB (une fois)
|
||||
⚠️ 2-3x plus lent (acceptable pour batch)
|
||||
⚠️ +4GB RAM necessaire
|
||||
⚠️ Re-indexation toutes conversations existantes
|
||||
|
||||
OPTION B - CHUNKING + UPGRADE MODELE (OPTIMAL):
|
||||
------------------------------------------------
|
||||
1. Implementer chunking intelligent pour conversations >8192 tokens
|
||||
2. Utiliser BAAI/bge-m3 pour embeddings
|
||||
3. Metadata: conversation_id + chunk_position pour reconstruction
|
||||
|
||||
Avantages:
|
||||
✅ Couverture 100% meme conversations >40,000 mots
|
||||
✅ Meilleure qualite semantique
|
||||
✅ Flexible pour futures evolutions
|
||||
|
||||
Inconvenients:
|
||||
⚠️ Plus complexe a implementer
|
||||
⚠️ Plus de documents dans ChromaDB
|
||||
⚠️ Logique de recherche plus sophistiquee
|
||||
|
||||
RECOMMANDATION FINALE:
|
||||
======================
|
||||
|
||||
PHASE 1 (MAINTENANT): Option A - Upgrade vers BAAI/bge-m3
|
||||
- Gain immediat: 1.2% → 38-40% couverture
|
||||
- Simple: 1 ligne de code
|
||||
- Suffisant pour 95% de vos conversations
|
||||
|
||||
PHASE 2 (SI BESOIN): Ajouter chunking pour conversations exceptionnelles >40,000 mots
|
||||
- Seulement si vous avez regulierement des conversations >40,000 mots
|
||||
- Sinon, pas necessaire
|
||||
|
||||
JUSTIFICATION POUR VOTRE CAS D'USAGE:
|
||||
-------------------------------------
|
||||
Philosophie, concepts abstraits, idees complexes en francais:
|
||||
|
||||
- all-MiniLM-L6-v2: Similarite textuelle basique, anglais
|
||||
→ Score MTEB: ~58/100
|
||||
→ Francais philosophie: ~40/100 (estime)
|
||||
|
||||
- BAAI/bge-m3: Comprehension semantique profonde, multilingue
|
||||
→ Score MTEB: ~72/100 (+24%)
|
||||
→ Francais philosophie: ~70/100 (estime, +75% gain!)
|
||||
|
||||
Pour conversations philosophiques: gain qualite estime >50%
|
||||
|
||||
COUT DE MIGRATION:
|
||||
------------------
|
||||
- Temps: ~30 min (download modele + re-index)
|
||||
- Calcul: 2-3x plus lent (1 conversation = 2s vs 0.7s actuellement)
|
||||
- Memoire: +4GB RAM (total ~5GB vs ~1GB actuel)
|
||||
- Stockage: +2.3GB pour modele
|
||||
- Code: Minimal (1 ligne a changer + re-index script)
|
||||
|
||||
PROCHAINE ETAPE:
|
||||
================
|
||||
Decider et implementer upgrade vers BAAI/bge-m3 dans ikario_rag
|
||||
|
||||
================================================================================
|
||||
|
||||
5
package.json
Normal file
5
package.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"puppeteer": "^24.33.1"
|
||||
}
|
||||
}
|
||||
@@ -1,984 +0,0 @@
|
||||
<project_specification>
|
||||
<project_name>Extended Thinking - Claude.ai Clone</project_name>
|
||||
|
||||
<overview>
|
||||
Extension du projet "Claude.ai Clone" existant pour intégrer la fonctionnalité Extended Thinking de Claude, permettant au modèle d'exposer son processus de raisonnement étape par étape.
|
||||
|
||||
Extended Thinking est une capacité de Claude qui génère des blocs "thinking" contenant son raisonnement interne avant de fournir sa réponse finale. Cette fonctionnalité améliore significativement la qualité des réponses pour les tâches complexes comme :
|
||||
- Mathématiques et calculs complexes
|
||||
- Programmation et débogage
|
||||
- Analyse approfondie de documents
|
||||
- Raisonnement logique multi-étapes
|
||||
- Résolution de problèmes complexes
|
||||
|
||||
Le projet Claude.ai Clone dispose déjà de :
|
||||
- Interface de chat complète avec streaming SSE
|
||||
- Gestion de conversations et messages (base SQLite)
|
||||
- Intégration Claude API avec Anthropic SDK
|
||||
- Support des tools (memory tools déjà implémentés)
|
||||
- Frontend React + Vite + Tailwind
|
||||
- Backend Node.js + Express
|
||||
|
||||
Cette extension ajoute :
|
||||
- Support du paramètre "thinking" dans les appels Claude API
|
||||
- Affichage des blocs thinking dans l'interface
|
||||
- Contrôles utilisateur pour activer/désactiver thinking
|
||||
- Ajustement du budget thinking (1K-32K tokens)
|
||||
- Streaming des thinking deltas en temps réel
|
||||
- Préservation des thinking blocks avec tool use
|
||||
- Storage des thinking blocks dans la base de données
|
||||
</overview>
|
||||
|
||||
<technology_stack>
|
||||
<existing_stack>
|
||||
Le projet dispose déjà de :
|
||||
- Frontend : React + Vite + Tailwind CSS (port 5173)
|
||||
- Backend : Node.js + Express + SQLite (port 3001)
|
||||
- API Claude : Anthropic SDK avec streaming SSE
|
||||
- Gestion de conversations : base SQLite avec tables conversations et messages
|
||||
- Tool Use API : Memory tools déjà configurés
|
||||
</existing_stack>
|
||||
|
||||
<extended_thinking_support>
|
||||
<api_integration>
|
||||
- Anthropic Messages API avec paramètre "thinking"
|
||||
- Structure : { type: "enabled", budget_tokens: number }
|
||||
- Budget min: 1024 tokens, max recommandé: 32000 tokens
|
||||
- Au-delà de 32K: utiliser batch processing
|
||||
</api_integration>
|
||||
|
||||
<response_format>
|
||||
- Blocs "thinking" : raisonnement résumé (Claude 4+)
|
||||
- Blocs "text" : réponse finale
|
||||
- Blocs "redacted_thinking" : thinking chiffré pour sécurité
|
||||
- Signature : champ de vérification cryptographique
|
||||
</response_format>
|
||||
|
||||
<streaming_events>
|
||||
- thinking_start : début du bloc thinking
|
||||
- thinking_delta : chunk de thinking en temps réel
|
||||
- thinking_stop : fin du bloc thinking
|
||||
- content : texte de réponse normale
|
||||
- signature_delta : signature cryptographique
|
||||
</streaming_events>
|
||||
|
||||
<supported_models>
|
||||
- Claude Sonnet 4.5 (claude-sonnet-4-5-20250929) ✓
|
||||
- Claude Sonnet 4 (claude-sonnet-4-20250514) ✓
|
||||
- Claude Haiku 4.5 (claude-haiku-4-5-20251001) ✓
|
||||
- Claude Opus 4.5 (claude-opus-4-5-20251101) ✓ + preserved blocks
|
||||
- Claude Opus 4.1 (claude-opus-4-1-20250805) ✓
|
||||
- Claude Opus 4 (claude-opus-4-20250514) ✓
|
||||
- Claude Sonnet 3.7 (déprécié, thinking complet non résumé)
|
||||
</supported_models>
|
||||
</extended_thinking_support>
|
||||
</technology_stack>
|
||||
|
||||
<prerequisites>
|
||||
<existing_project>
|
||||
- Projet Claude.ai Clone déjà fonctionnel
|
||||
- Base SQLite avec tables conversations et messages opérationnelles
|
||||
- API endpoints Claude existants (/api/claude/chat, /api/messages/*)
|
||||
- Frontend React avec composants de chat déjà en place
|
||||
- Tool Use API déjà implémenté (memory tools fonctionnels)
|
||||
</existing_project>
|
||||
|
||||
<no_new_dependencies>
|
||||
- Aucune nouvelle dépendance npm requise
|
||||
- Utilise Anthropic SDK existant (déjà installé)
|
||||
- Extended Thinking est une fonctionnalité native de l'API Claude
|
||||
</no_new_dependencies>
|
||||
|
||||
<api_compatibility>
|
||||
- API key Anthropic valide (déjà configurée)
|
||||
- Modèles Claude 4+ recommandés pour thinking résumé
|
||||
- Compatible avec les tools existants (memory, etc.)
|
||||
</api_compatibility>
|
||||
</prerequisites>
|
||||
|
||||
<core_features>
|
||||
<feature_1>
|
||||
<title>Backend - Support paramètre thinking dans API routes</title>
|
||||
<description>
|
||||
Modifier les routes backend pour accepter et transmettre le paramètre "thinking" à l'API Claude.
|
||||
|
||||
Fonctionnalités :
|
||||
- Ajouter paramètres enableThinking et thinkingBudgetTokens aux requêtes
|
||||
- Modifier server/routes/claude.js pour POST /api/claude/chat
|
||||
- Modifier server/routes/messages.js pour POST /:conversationId/messages
|
||||
- Construire l'objet thinking: { type: "enabled", budget_tokens: number }
|
||||
- Passer thinking dans les appels anthropic.messages.create()
|
||||
- Validation : budget_tokens entre 1024 et 200000
|
||||
- Default : enableThinking=false, thinkingBudgetTokens=10000
|
||||
|
||||
Technique :
|
||||
- Extraction des params depuis req.body ou conversation.settings
|
||||
- Conditional : if (enableThinking) { apiParams.thinking = {...} }
|
||||
- Merge avec params existants (model, max_tokens, tools, system)
|
||||
- Pas de breaking changes pour les conversations existantes
|
||||
|
||||
Intégration :
|
||||
- Modification de server/routes/claude.js (lignes ~92-146)
|
||||
- Modification de server/routes/messages.js (lignes ~314-365)
|
||||
- Compatible avec tool use existant (memory tools)
|
||||
</description>
|
||||
<priority>1</priority>
|
||||
<category>backend</category>
|
||||
<test_steps>
|
||||
1. Modifier les routes pour accepter enableThinking et thinkingBudgetTokens
|
||||
2. Créer une conversation test avec thinking activé
|
||||
3. Vérifier dans les logs que thinking est passé à l'API
|
||||
4. Envoyer un message et vérifier la présence de thinking_delta events
|
||||
5. Tester avec enableThinking=false et vérifier pas de thinking
|
||||
6. Tester avec budget 1024, 10000, 32000 et vérifier comportement
|
||||
7. Vérifier compatibilité avec memory tools (tool use + thinking)
|
||||
</test_steps>
|
||||
</feature_1>
|
||||
|
||||
<feature_2>
|
||||
<title>Backend - Streaming des thinking deltas via SSE</title>
|
||||
<description>
|
||||
Implémenter la gestion des événements thinking dans le streaming SSE pour envoyer les thinking deltas au frontend en temps réel.
|
||||
|
||||
Fonctionnalités :
|
||||
- Détecter event.type === 'content_block_start' avec type 'thinking'
|
||||
- Émettre événement SSE thinking_start avec index du bloc
|
||||
- Détecter event.type === 'content_block_delta' avec delta.type === 'thinking_delta'
|
||||
- Émettre événement SSE thinking avec le texte delta
|
||||
- Accumuler le thinking complet dans fullThinkingContent
|
||||
- Détecter signature_delta et accumuler dans thinkingSignature
|
||||
- Émettre thinking_stop à la fin du bloc
|
||||
- Gérer redacted_thinking blocks (thinking chiffré)
|
||||
|
||||
Événements SSE émis :
|
||||
- { type: 'thinking_start', index: number }
|
||||
- { type: 'thinking', text: string } (streaming)
|
||||
- { type: 'thinking_stop', index: number }
|
||||
- { type: 'thinking_redacted', message: string } (si redacted)
|
||||
|
||||
Technique :
|
||||
- Dans la boucle for await (const event of stream) de messages.js
|
||||
- Variables : fullThinkingContent = '', thinkingSignature = ''
|
||||
- res.write() pour chaque événement SSE
|
||||
- isInThinkingBlock flag pour tracking état
|
||||
|
||||
Intégration :
|
||||
- Modification de server/routes/messages.js (dans POST /:conversationId/messages)
|
||||
- S'intègre dans la boucle de streaming existante (lignes ~365-400)
|
||||
- Compatible avec tool_use events existants
|
||||
</description>
|
||||
<priority>1</priority>
|
||||
<category>backend</category>
|
||||
<test_steps>
|
||||
1. Activer thinking pour une conversation
|
||||
2. Envoyer un message et observer les logs backend
|
||||
3. Vérifier émission de thinking_start event
|
||||
4. Vérifier émission de multiples thinking events (deltas)
|
||||
5. Vérifier accumulation de fullThinkingContent
|
||||
6. Vérifier émission de thinking_stop
|
||||
7. Vérifier gestion de signature_delta
|
||||
8. Tester avec prompt qui trigger redacted_thinking
|
||||
</test_steps>
|
||||
</feature_2>
|
||||
|
||||
<feature_3>
|
||||
<title>Backend - Storage thinking dans base de données</title>
|
||||
<description>
|
||||
Ajouter les colonnes nécessaires à la table messages pour stocker les thinking blocks et permettre leur affichage après refresh.
|
||||
|
||||
Fonctionnalités :
|
||||
- Migration DB : ajouter colonnes thinking_content et thinking_signature à table messages
|
||||
- Sauvegarder fullThinkingContent dans thinking_content
|
||||
- Sauvegarder thinkingSignature dans thinking_signature (pour vérification)
|
||||
- Charger thinking_content lors de GET /api/conversations/:id/messages
|
||||
- Inclure thinking dans la réponse JSON des messages
|
||||
- Nullable : thinking_content peut être NULL si thinking désactivé
|
||||
|
||||
Schéma DB :
|
||||
- ALTER TABLE messages ADD COLUMN thinking_content TEXT DEFAULT NULL
|
||||
- ALTER TABLE messages ADD COLUMN thinking_signature TEXT DEFAULT NULL
|
||||
|
||||
Technique :
|
||||
- Modification de server/db/index.js pour migration
|
||||
- Vérifier existence colonnes avec pragma_table_info
|
||||
- INSERT thinking_content et thinking_signature avec le message
|
||||
- SELECT thinking_content dans les queries existantes
|
||||
- Retourner dans response JSON : { ...message, thinking_content, thinking_signature }
|
||||
|
||||
Intégration :
|
||||
- Modification de server/db/index.js (fonction initializeDatabase)
|
||||
- Modification de INSERT dans server/routes/messages.js
|
||||
- Modification de SELECT dans GET /api/conversations/:id/messages
|
||||
</description>
|
||||
<priority>1</priority>
|
||||
<category>backend</category>
|
||||
<test_steps>
|
||||
1. Lancer le serveur et vérifier migration DB dans logs
|
||||
2. Vérifier colonnes ajoutées : PRAGMA table_info(messages)
|
||||
3. Envoyer message avec thinking et vérifier INSERT
|
||||
4. Vérifier thinking_content contient le texte thinking
|
||||
5. Vérifier thinking_signature contient la signature
|
||||
6. Refresh la page et vérifier thinking réapparaît
|
||||
7. Tester message sans thinking et vérifier NULL
|
||||
</test_steps>
|
||||
</feature_3>
|
||||
|
||||
<feature_4>
|
||||
<title>Backend - Settings DB pour thinking par conversation</title>
|
||||
<description>
|
||||
Ajouter les colonnes à la table conversations pour stocker les préférences thinking de chaque conversation.
|
||||
|
||||
Fonctionnalités :
|
||||
- Migration DB : ajouter enable_thinking et thinking_budget_tokens à conversations
|
||||
- Defaults : enable_thinking=0 (désactivé), thinking_budget_tokens=10000
|
||||
- Charger settings depuis conversations.enable_thinking
|
||||
- Utiliser dans la construction des appels API
|
||||
- Permettre modification via endpoint PATCH /api/conversations/:id/settings
|
||||
|
||||
Schéma DB :
|
||||
- ALTER TABLE conversations ADD COLUMN enable_thinking INTEGER DEFAULT 0
|
||||
- ALTER TABLE conversations ADD COLUMN thinking_budget_tokens INTEGER DEFAULT 10000
|
||||
|
||||
Technique :
|
||||
- Migration dans server/db/index.js
|
||||
- Lecture dans POST /:conversationId/messages : const enableThinking = conversation.enable_thinking === 1
|
||||
- Update via PATCH /api/conversations/:id : UPDATE conversations SET enable_thinking=?, thinking_budget_tokens=?
|
||||
|
||||
Intégration :
|
||||
- Modification de server/db/index.js (migration)
|
||||
- Modification de server/routes/messages.js (lecture settings)
|
||||
- Nouveau endpoint ou modification endpoint conversations pour update
|
||||
</description>
|
||||
<priority>1</priority>
|
||||
<category>backend</category>
|
||||
<test_steps>
|
||||
1. Vérifier migration et création colonnes
|
||||
2. Créer nouvelle conversation et vérifier defaults (0, 10000)
|
||||
3. Activer thinking via PATCH et vérifier UPDATE
|
||||
4. Envoyer message et vérifier thinking utilisé
|
||||
5. Désactiver thinking et vérifier pas de thinking blocks
|
||||
6. Modifier budget à 20000 et vérifier pris en compte
|
||||
7. Vérifier persistance après redémarrage serveur
|
||||
</test_steps>
|
||||
</feature_4>
|
||||
|
||||
<feature_5>
|
||||
<title>Frontend - Composant ThinkingBlock pour affichage</title>
|
||||
<description>
|
||||
Créer un composant React ThinkingBlock pour afficher les blocs thinking de façon élégante et collapsible.
|
||||
|
||||
Fonctionnalités :
|
||||
- Composant React standalone : src/components/ThinkingBlock.jsx
|
||||
- Props : thinking (string), signature (string), isStreaming (boolean)
|
||||
- Header avec icône cerveau + titre "Claude's reasoning"
|
||||
- Toggle expand/collapse (useState)
|
||||
- Animation dots pendant streaming
|
||||
- Contenu en police monospace pour meilleure lisibilité
|
||||
- Background bleu clair (bg-blue-50 dark:bg-blue-950)
|
||||
- Border bleu (border-blue-200 dark:border-blue-800)
|
||||
- Affichage token count estimé (~length/4)
|
||||
- Note "Summarized for display" pour Claude 4+
|
||||
|
||||
UI States :
|
||||
- isStreaming=true : afficher "Thinking..." + dots animés
|
||||
- isStreaming=false : afficher "Claude's reasoning"
|
||||
- isExpanded=true : montrer contenu complet
|
||||
- isExpanded=false : header seul avec chevron
|
||||
|
||||
Technique :
|
||||
- Functional component avec hooks (useState)
|
||||
- Tailwind CSS pour styling
|
||||
- SVG icons (brain icon, chevron)
|
||||
- Animation CSS pour dots (animate-bounce avec delay)
|
||||
- Transition pour collapse (max-height ou conditional render)
|
||||
|
||||
Intégration :
|
||||
- Nouveau fichier src/components/ThinkingBlock.jsx
|
||||
- Importé dans src/App.jsx
|
||||
- Utilisé dans le composant Message
|
||||
</description>
|
||||
<priority>2</priority>
|
||||
<category>frontend</category>
|
||||
<test_steps>
|
||||
1. Créer le composant ThinkingBlock.jsx
|
||||
2. Tester affichage avec thinking statique
|
||||
3. Vérifier toggle expand/collapse fonctionne
|
||||
4. Tester avec isStreaming=true et voir animation
|
||||
5. Vérifier responsive design (mobile)
|
||||
6. Vérifier dark mode (bg et border colors)
|
||||
7. Vérifier token count affiché correctement
|
||||
8. Vérifier note "Summarized" présente
|
||||
</test_steps>
|
||||
</feature_5>
|
||||
|
||||
<feature_6>
|
||||
<title>Frontend - Intégration ThinkingBlock dans messages</title>
|
||||
<description>
|
||||
Intégrer le composant ThinkingBlock dans l'affichage des messages pour montrer le thinking avant le contenu.
|
||||
|
||||
Fonctionnalités :
|
||||
- Ajouter state thinkingContent dans Message component
|
||||
- Afficher ThinkingBlock si thinkingContent existe
|
||||
- Position : avant le contenu du message
|
||||
- Charger thinking depuis message.thinking_content (DB)
|
||||
- Update en temps réel pendant streaming
|
||||
- Flag isThinkingStreaming pour animation
|
||||
|
||||
Structure :
|
||||
```jsx
|
||||
<div className="message">
|
||||
{thinkingContent && (
|
||||
<ThinkingBlock
|
||||
thinking={thinkingContent}
|
||||
signature={message.thinking_signature}
|
||||
isStreaming={isThinkingStreaming}
|
||||
/>
|
||||
)}
|
||||
<div className="message-content">
|
||||
{message.content}
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
Technique :
|
||||
- useState pour thinkingContent et isThinkingStreaming
|
||||
- Initialiser depuis message.thinking_content au mount
|
||||
- Update pendant streaming via SSE events
|
||||
- Conditional render avec && operator
|
||||
|
||||
Intégration :
|
||||
- Modification de src/App.jsx (Message component)
|
||||
- Import ThinkingBlock component
|
||||
- Pas de breaking changes pour messages sans thinking
|
||||
</description>
|
||||
<priority>2</priority>
|
||||
<category>frontend</category>
|
||||
<test_steps>
|
||||
1. Afficher conversation avec thinking blocks
|
||||
2. Vérifier ThinkingBlock apparaît avant le contenu
|
||||
3. Vérifier thinking chargé depuis DB au refresh
|
||||
4. Envoyer nouveau message et vérifier streaming
|
||||
5. Vérifier isThinkingStreaming = true pendant streaming
|
||||
6. Vérifier isThinkingStreaming = false après
|
||||
7. Vérifier messages sans thinking non affectés
|
||||
8. Tester scroll avec thinking blocks longs
|
||||
</test_steps>
|
||||
</feature_6>
|
||||
|
||||
<feature_7>
|
||||
<title>Frontend - Settings Panel pour thinking toggle</title>
|
||||
<description>
|
||||
Ajouter contrôles dans le panneau de settings de conversation pour activer/désactiver Extended Thinking.
|
||||
|
||||
Fonctionnalités :
|
||||
- Toggle checkbox "Extended Thinking"
|
||||
- Description : "Enable enhanced reasoning for complex tasks"
|
||||
- Icône cerveau à côté du label
|
||||
- State local synchronisé avec conversation.enable_thinking
|
||||
- Update via PATCH /api/conversations/:id au changement
|
||||
- Affichage conditionnel du thinking budget slider si activé
|
||||
|
||||
UI :
|
||||
- Section dans conversation settings (à côté temperature, max_tokens)
|
||||
- Checkbox custom avec style Tailwind
|
||||
- Label clickable avec flex layout
|
||||
- Description en text-xs text-gray-500
|
||||
|
||||
Technique :
|
||||
- Modification du composant ConversationSettings (ou équivalent)
|
||||
- useState pour enable_thinking (init depuis conversation)
|
||||
- onChange handler avec PATCH request
|
||||
- Conditional render pour budget slider
|
||||
|
||||
Intégration :
|
||||
- Modification de src/App.jsx (settings panel)
|
||||
- PATCH /api/conversations/:id endpoint (backend)
|
||||
- Reload conversation après update
|
||||
</description>
|
||||
<priority>2</priority>
|
||||
<category>frontend</category>
|
||||
<test_steps>
|
||||
1. Ouvrir settings d'une conversation
|
||||
2. Voir la checkbox "Extended Thinking"
|
||||
3. Cocher la checkbox et vérifier PATCH request
|
||||
4. Vérifier conversation.enable_thinking = 1 en DB
|
||||
5. Envoyer message et vérifier thinking apparaît
|
||||
6. Décocher et vérifier plus de thinking
|
||||
7. Vérifier persistance après refresh
|
||||
8. Vérifier icône cerveau affichée
|
||||
</test_steps>
|
||||
</feature_7>
|
||||
|
||||
<feature_8>
|
||||
<title>Frontend - Thinking Budget Slider</title>
|
||||
<description>
|
||||
Ajouter un slider pour ajuster le budget thinking (nombre de tokens alloués au raisonnement).
|
||||
|
||||
Fonctionnalités :
|
||||
- Range input de 1024 à 32000 tokens
|
||||
- Step de 1024 tokens pour granularité
|
||||
- Labels : "1K tokens" (min), "32K tokens" (max), valeur actuelle au centre
|
||||
- Visible uniquement si Extended Thinking activé
|
||||
- Description : "Higher budgets enable more thorough analysis"
|
||||
- Update en temps réel de conversation.thinking_budget_tokens
|
||||
- Warning si >32K (recommander batch processing)
|
||||
|
||||
UI :
|
||||
- Input type="range" stylisé avec Tailwind
|
||||
- Display de la valeur en temps réel (formatée avec .toLocaleString())
|
||||
- Labels aux extrémités
|
||||
- Spacing cohérent avec autres settings
|
||||
|
||||
Technique :
|
||||
- Conditional render : {settings.enableThinking && <div>slider</div>}
|
||||
- Value controlled par state
|
||||
- onChange avec debounce (300ms) pour éviter trop de PATCH
|
||||
- Min=1024, max=32000, step=1024
|
||||
|
||||
Intégration :
|
||||
- Dans le même settings panel que le toggle
|
||||
- Juste en dessous de la checkbox Extended Thinking
|
||||
- Update via même endpoint PATCH
|
||||
</description>
|
||||
<priority>2</priority>
|
||||
<category>frontend</category>
|
||||
<test_steps>
|
||||
1. Activer Extended Thinking
|
||||
2. Voir le slider apparaître
|
||||
3. Ajuster à 5000 tokens et vérifier update
|
||||
4. Vérifier valeur affichée change en temps réel
|
||||
5. Vérifier PATCH request avec debounce
|
||||
6. Envoyer message et vérifier budget utilisé
|
||||
7. Tester min (1024) et max (32000)
|
||||
8. Désactiver thinking et vérifier slider disparaît
|
||||
</test_steps>
|
||||
</feature_8>
|
||||
|
||||
<feature_9>
|
||||
<title>Frontend - Badge "Thinking" dans conversation list</title>
|
||||
<description>
|
||||
Afficher un badge visuel dans la liste de conversations pour indiquer que Extended Thinking est activé.
|
||||
|
||||
Fonctionnalités :
|
||||
- Badge avec icône cerveau + texte "Thinking"
|
||||
- Couleur : bg-blue-100 text-blue-700 (light) / bg-blue-900 text-blue-200 (dark)
|
||||
- Taille : text-xs, padding minimal
|
||||
- Position : à droite du titre de conversation
|
||||
- Visible seulement si enable_thinking = 1
|
||||
- Style pill/rounded-full
|
||||
|
||||
UI :
|
||||
- Inline badge avec flexbox
|
||||
- Icon + text dans le même span
|
||||
- Cohérent avec autres badges (pinned, etc.)
|
||||
|
||||
Technique :
|
||||
- Dans ConversationListItem component
|
||||
- Parse conversation.enable_thinking || JSON.parse(conversation.settings)?.enableThinking
|
||||
- Conditional render : {enableThinking && <span>badge</span>}
|
||||
- SVG brain icon (w-3 h-3)
|
||||
|
||||
Intégration :
|
||||
- Modification du composant ConversationListItem
|
||||
- Ajout après conversation.title
|
||||
- Pas de breaking changes
|
||||
</description>
|
||||
<priority>3</priority>
|
||||
<category>frontend</category>
|
||||
<test_steps>
|
||||
1. Créer conversation avec thinking activé
|
||||
2. Voir badge "Thinking" dans la liste
|
||||
3. Vérifier icône cerveau présente
|
||||
4. Vérifier couleurs en light et dark mode
|
||||
5. Créer conversation sans thinking
|
||||
6. Vérifier absence de badge
|
||||
7. Activer thinking et vérifier badge apparaît
|
||||
8. Vérifier responsive (mobile)
|
||||
</test_steps>
|
||||
</feature_8>
|
||||
|
||||
<feature_10>
|
||||
<title>Frontend - Streaming handler pour thinking deltas</title>
|
||||
<description>
|
||||
Implémenter la logique frontend pour recevoir et afficher les thinking deltas en streaming via SSE.
|
||||
|
||||
Fonctionnalités :
|
||||
- Écouter événement SSE 'thinking_start'
|
||||
- Set isThinkingStreaming = true
|
||||
- Écouter 'thinking' events et accumuler dans currentThinking
|
||||
- Update thinkingContent en temps réel
|
||||
- Écouter 'thinking_stop' et set isThinkingStreaming = false
|
||||
- Gérer 'thinking_redacted' avec message d'info
|
||||
- Buffer thinking complet pour sauvegarde finale
|
||||
|
||||
Event handling :
|
||||
```javascript
|
||||
case 'thinking_start':
|
||||
setIsThinkingStreaming(true);
|
||||
currentThinking = '';
|
||||
break;
|
||||
case 'thinking':
|
||||
currentThinking += data.text;
|
||||
setThinkingContent(currentThinking);
|
||||
break;
|
||||
case 'thinking_stop':
|
||||
setIsThinkingStreaming(false);
|
||||
break;
|
||||
```
|
||||
|
||||
Technique :
|
||||
- Dans la fonction sendMessage() (ou équivalent)
|
||||
- EventSource ou fetch streaming déjà existant
|
||||
- Switch sur data.type pour router events
|
||||
- State updates via setters
|
||||
- Cleanup des listeners à la fin
|
||||
|
||||
Intégration :
|
||||
- Modification de src/App.jsx (sendMessage function)
|
||||
- S'intègre dans le handler SSE existant
|
||||
- Compatible avec tool_use events
|
||||
</description>
|
||||
<priority>1</priority>
|
||||
<category>frontend</category>
|
||||
<test_steps>
|
||||
1. Activer thinking pour conversation
|
||||
2. Envoyer message et observer console
|
||||
3. Vérifier thinking_start event reçu
|
||||
4. Vérifier thinking deltas reçus et accumulés
|
||||
5. Vérifier ThinkingBlock update en temps réel
|
||||
6. Vérifier thinking_stop event
|
||||
7. Vérifier isThinkingStreaming toggle correct
|
||||
8. Tester avec redacted_thinking
|
||||
</test_steps>
|
||||
</feature_10>
|
||||
|
||||
<feature_11>
|
||||
<title>Backend - Préservation thinking blocks avec tool use</title>
|
||||
<description>
|
||||
Implémenter la logique pour préserver les thinking blocks lors de l'utilisation de tools, conformément à la spec Claude API.
|
||||
|
||||
Fonctionnalités :
|
||||
- Quand stop_reason === 'tool_use', extraire thinking blocks
|
||||
- Extraire tool_use blocks
|
||||
- Passer thinking + tool_use dans messages assistant
|
||||
- Exécuter tools (processToolCalls déjà existant)
|
||||
- Retourner tool_results
|
||||
- Continuer conversation avec thinking préservé
|
||||
- Support de interleaved thinking (beta header optionnel)
|
||||
|
||||
Workflow :
|
||||
1. Response avec stop_reason='tool_use'
|
||||
2. Filtrer content : thinking + redacted_thinking blocks
|
||||
3. Filtrer content : tool_use blocks
|
||||
4. Push assistant message avec [...thinkingBlocks, ...toolUseBlocks]
|
||||
5. Execute tools via processToolCalls()
|
||||
6. Push user message avec tool_results
|
||||
7. Nouvelle iteration avec thinking préservé
|
||||
|
||||
Technique :
|
||||
- Dans la boucle tool use existante (messages.js)
|
||||
- Filter blocks par type : 'thinking', 'redacted_thinking', 'tool_use'
|
||||
- Merge dans content array
|
||||
- Preserve order : thinking d'abord, puis tools
|
||||
- Compatible avec code tool use existant
|
||||
|
||||
Intégration :
|
||||
- Modification de server/routes/messages.js (tool use loop)
|
||||
- Compatible avec memory tools existants
|
||||
- Pas de breaking changes
|
||||
</description>
|
||||
<priority>2</priority>
|
||||
<category>backend</category>
|
||||
<test_steps>
|
||||
1. Activer thinking + memory tools
|
||||
2. Demander "Recherche dans tes souvenirs sur X"
|
||||
3. Vérifier Claude utilise thinking + tool search_memories
|
||||
4. Vérifier thinking blocks préservés dans messages array
|
||||
5. Vérifier tool results retournés correctement
|
||||
6. Vérifier Claude continue avec contexte thinking
|
||||
7. Tester avec multiple tool calls
|
||||
8. Vérifier logs montrent preservation
|
||||
</test_steps>
|
||||
</feature_11>
|
||||
|
||||
<feature_12>
|
||||
<title>Backend - Token tracking pour thinking</title>
|
||||
<description>
|
||||
Améliorer le tracking des tokens pour distinguer thinking tokens des output tokens normaux.
|
||||
|
||||
Fonctionnalités :
|
||||
- Calculer thinking tokens approximatif (length / 4)
|
||||
- Logger séparément input_tokens, output_tokens, thinking_tokens
|
||||
- Sauvegarder dans usage_tracking (optionnel : nouvelle colonne)
|
||||
- Inclure thinking_tokens dans response 'done' event
|
||||
- Documentation du fait que thinking est facturé au tarif complet
|
||||
|
||||
Logging :
|
||||
```javascript
|
||||
console.log('[Thinking Tokens]', {
|
||||
input_tokens: response.usage.input_tokens,
|
||||
output_tokens: response.usage.output_tokens, // Inclut thinking complet
|
||||
visible_thinking_tokens: Math.ceil(thinkingContent.length / 4),
|
||||
text_output_tokens: Math.ceil(textContent.length / 4)
|
||||
});
|
||||
```
|
||||
|
||||
Technique :
|
||||
- Fonction calculateTokens(text) : Math.ceil(text.length / 4)
|
||||
- Logging après chaque response
|
||||
- Inclure dans event 'done' : thinkingTokens: calculateTokens(fullThinkingContent)
|
||||
- Optionnel : ALTER TABLE usage_tracking ADD COLUMN thinking_tokens
|
||||
|
||||
Intégration :
|
||||
- Modification de server/routes/messages.js
|
||||
- Modification de usage_tracking INSERT (optionnel)
|
||||
- Frontend peut afficher thinking cost
|
||||
</description>
|
||||
<priority>3</priority>
|
||||
<category>backend</category>
|
||||
<test_steps>
|
||||
1. Envoyer message avec thinking
|
||||
2. Vérifier logs backend montrent breakdown tokens
|
||||
3. Vérifier thinking_tokens dans event 'done'
|
||||
4. Vérifier total = input + output + thinking
|
||||
5. Comparer visible thinking tokens vs billed
|
||||
6. Tester avec différents budgets
|
||||
7. Vérifier tracking en DB (si colonne ajoutée)
|
||||
</test_steps>
|
||||
</feature_12>
|
||||
|
||||
<feature_13>
|
||||
<title>Frontend - Usage stats avec thinking tokens</title>
|
||||
<description>
|
||||
Afficher les statistiques d'utilisation incluant les thinking tokens dans l'interface.
|
||||
|
||||
Fonctionnalités :
|
||||
- Section usage stats dans conversation details
|
||||
- Afficher Total Tokens (existant)
|
||||
- Afficher Thinking Tokens séparément (en bleu)
|
||||
- Note explicative : "Thinking tokens are summarized but billed at full rate"
|
||||
- Graph ou visual si >0 thinking tokens
|
||||
- Format avec .toLocaleString() pour lisibilité
|
||||
|
||||
UI :
|
||||
```jsx
|
||||
<div className="usage-stats">
|
||||
<div className="stat">
|
||||
<label>Total Tokens</label>
|
||||
<span>{conversation.token_count.toLocaleString()}</span>
|
||||
</div>
|
||||
{conversation.thinking_tokens > 0 && (
|
||||
<div className="stat text-blue-600">
|
||||
<label>Thinking Tokens</label>
|
||||
<span>{conversation.thinking_tokens.toLocaleString()}</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
```
|
||||
|
||||
Technique :
|
||||
- Composant UsageStats (nouveau ou modification existant)
|
||||
- Props : conversation avec token_count et thinking_tokens
|
||||
- Conditional render si thinking_tokens > 0
|
||||
- Tailwind classes pour styling
|
||||
|
||||
Intégration :
|
||||
- Dans conversation details panel ou settings
|
||||
- Charger data depuis conversation ou API
|
||||
- Update après chaque message
|
||||
</description>
|
||||
<priority>3</priority>
|
||||
<category>frontend</category>
|
||||
<test_steps>
|
||||
1. Avoir conversation avec thinking
|
||||
2. Ouvrir usage stats
|
||||
3. Voir Total Tokens et Thinking Tokens
|
||||
4. Vérifier Thinking Tokens en bleu
|
||||
5. Voir note explicative
|
||||
6. Envoyer nouveau message et voir update
|
||||
7. Tester avec conversation sans thinking
|
||||
8. Vérifier Thinking Tokens section cachée
|
||||
</test_steps>
|
||||
</feature_13>
|
||||
|
||||
<feature_14>
|
||||
<title>Frontend - Error handling pour thinking timeout</title>
|
||||
<description>
|
||||
Gérer gracieusement les cas où le thinking prend trop de temps (>2 minutes) avec timeout et message utilisateur.
|
||||
|
||||
Fonctionnalités :
|
||||
- Timeout de 2 minutes (120000ms) pour thinking
|
||||
- Afficher message : "Thinking is taking longer than expected..."
|
||||
- Ne pas bloquer l'affichage de la réponse finale
|
||||
- Logger warning en console
|
||||
- Permettre annulation (optionnel)
|
||||
|
||||
Backend :
|
||||
- setTimeout pour 120s après thinking_start
|
||||
- Émettre event 'thinking_timeout' si pas de thinking_stop
|
||||
- Clear timeout si thinking_stop avant
|
||||
|
||||
Frontend :
|
||||
- Écouter 'thinking_timeout' event
|
||||
- Afficher notification ou message dans ThinkingBlock
|
||||
- Continuer à écouter pour eventual thinking_stop
|
||||
|
||||
Technique :
|
||||
- Backend : let thinkingTimeout = setTimeout(() => {...}, 120000)
|
||||
- Backend : clearTimeout(thinkingTimeout) dans thinking_stop
|
||||
- Frontend : toast notification ou inline message
|
||||
- Pas de crash, juste warning
|
||||
|
||||
Intégration :
|
||||
- Modification de server/routes/messages.js
|
||||
- Modification de src/App.jsx (event handler)
|
||||
- UX: message discret, pas d'alerte invasive
|
||||
</description>
|
||||
<priority>3</priority>
|
||||
<category>fullstack</category>
|
||||
<test_steps>
|
||||
1. Créer prompt qui génère >2min de thinking (difficile)
|
||||
2. Vérifier timeout warning après 2min
|
||||
3. Vérifier message affiché à l'utilisateur
|
||||
4. Vérifier thinking_stop clear le timeout
|
||||
5. Vérifier pas de crash si timeout
|
||||
6. Vérifier réponse finale affichée malgré timeout
|
||||
7. Vérifier logs backend
|
||||
</test_steps>
|
||||
</feature_14>
|
||||
|
||||
<feature_15>
|
||||
<title>Documentation - Guide utilisateur Extended Thinking</title>
|
||||
<description>
|
||||
Créer documentation inline ou modal pour expliquer Extended Thinking aux utilisateurs.
|
||||
|
||||
Fonctionnalités :
|
||||
- Bouton "?" ou "info" à côté du toggle Extended Thinking
|
||||
- Modal/popover explicatif au clic
|
||||
- Sections :
|
||||
* Qu'est-ce que Extended Thinking ?
|
||||
* Quand l'utiliser ? (math, code, analysis)
|
||||
* Quand NE PAS l'utiliser ? (questions simples)
|
||||
* Impact sur temps de réponse (2-5x plus long)
|
||||
* Budget thinking : qu'est-ce que c'est ?
|
||||
* Facturation (thinking facturé au tarif complet)
|
||||
- Exemples concrets d'utilisation
|
||||
- Lien vers docs Anthropic (optionnel)
|
||||
|
||||
UI :
|
||||
- Icône info circulaire (i dans cercle)
|
||||
- Modal Headless UI ou simple div
|
||||
- Prose styling pour lisibilité
|
||||
- Bouton "Got it" pour fermer
|
||||
|
||||
Technique :
|
||||
- Composant InfoModal ou réutilisation existant
|
||||
- Markdown content ou JSX statique
|
||||
- State pour open/close modal
|
||||
- onClick sur icône info
|
||||
|
||||
Intégration :
|
||||
- À côté du toggle Extended Thinking dans settings
|
||||
- Peut aussi dans un "Help" menu global
|
||||
- Traduction FR/EN si multilingue
|
||||
</description>
|
||||
<priority>4</priority>
|
||||
<category>frontend</category>
|
||||
<test_steps>
|
||||
1. Voir icône info à côté de Extended Thinking
|
||||
2. Cliquer et voir modal s'ouvrir
|
||||
3. Lire contenu explicatif
|
||||
4. Vérifier exemples clairs
|
||||
5. Cliquer "Got it" et fermer
|
||||
6. Vérifier responsive design
|
||||
7. Vérifier accessibility (keyboard nav)
|
||||
</test_steps>
|
||||
</feature_15>
|
||||
</core_features>
|
||||
|
||||
<ui_design>
|
||||
<integration_notes>
|
||||
Cette extension s'intègre dans le design existant du clone Claude.ai.
|
||||
Tous les nouveaux composants doivent respecter le design system existant.
|
||||
</integration_notes>
|
||||
|
||||
<new_components>
|
||||
- ThinkingBlock : Bloc collapsible pour afficher le thinking (bleu clair)
|
||||
- Thinking Toggle : Checkbox dans settings pour activer/désactiver
|
||||
- Budget Slider : Range input pour ajuster budget thinking
|
||||
- Thinking Badge : Petit badge dans conversation list
|
||||
- Usage Stats : Section pour afficher thinking tokens
|
||||
- Info Modal : Documentation Extended Thinking
|
||||
</new_components>
|
||||
|
||||
<color_scheme>
|
||||
Utiliser les couleurs existantes du clone Claude.ai, avec ajouts pour thinking :
|
||||
- Thinking blocks : bg-blue-50 text-blue-800 (light) / bg-blue-950 text-blue-200 (dark)
|
||||
- Borders : border-blue-200 (light) / border-blue-800 (dark)
|
||||
- Badge thinking : bg-blue-100 text-blue-700 (light) / bg-blue-900 text-blue-200 (dark)
|
||||
- Icons : text-blue-600 (light) / text-blue-400 (dark)
|
||||
- Accent : conserver #CC785C (orange claude.ai) pour cohérence
|
||||
</color_scheme>
|
||||
|
||||
<icons>
|
||||
- Icône cerveau (brain) pour thinking : SVG custom ou Lucide React
|
||||
- Chevron pour collapse/expand
|
||||
- Info icon (i dans cercle) pour documentation
|
||||
- Dots animés pour streaming (3 cercles avec animate-bounce)
|
||||
</icons>
|
||||
|
||||
<animations>
|
||||
- Dots streaming : animate-bounce avec animation-delay
|
||||
- Collapse/expand : transition max-height ou opacity
|
||||
- Pulse discret lors sauvegarde (optionnel)
|
||||
- Smooth transitions (duration-200)
|
||||
</animations>
|
||||
|
||||
<responsive>
|
||||
- Thinking blocks full width sur mobile
|
||||
- Settings panel stacké verticalement sur mobile
|
||||
- Badge thinking masqué sur très petits écrans (optionnel)
|
||||
- Touch targets >44px pour mobile
|
||||
</responsive>
|
||||
</ui_design>
|
||||
|
||||
<api_endpoints>
|
||||
<note>
|
||||
Modifications aux endpoints existants. Pas de nouveaux endpoints nécessaires.
|
||||
</note>
|
||||
|
||||
<existing_endpoints_modified>
|
||||
<endpoint>
|
||||
<method>POST</method>
|
||||
<path>/api/claude/chat</path>
|
||||
<modification>
|
||||
- Accepter enableThinking et thinkingBudgetTokens dans req.body
|
||||
- Construire thinking: { type: "enabled", budget_tokens: number }
|
||||
- Passer dans anthropic.messages.create()
|
||||
</modification>
|
||||
</endpoint>
|
||||
|
||||
<endpoint>
|
||||
<method>POST</method>
|
||||
<path>/api/conversations/:conversationId/messages</path>
|
||||
<modification>
|
||||
- Charger enable_thinking et thinking_budget_tokens depuis conversation
|
||||
- Ajouter thinking dans requête API si activé
|
||||
- Émettre thinking_start, thinking, thinking_stop via SSE
|
||||
- Sauvegarder thinking_content et thinking_signature en DB
|
||||
</modification>
|
||||
</endpoint>
|
||||
|
||||
<endpoint>
|
||||
<method>POST</method>
|
||||
<path>/api/messages/:id/regenerate</path>
|
||||
<modification>
|
||||
- Même logique que POST messages
|
||||
- Charger thinking settings depuis conversation
|
||||
- Support thinking dans regeneration
|
||||
</modification>
|
||||
</endpoint>
|
||||
|
||||
<endpoint>
|
||||
<method>PATCH</method>
|
||||
<path>/api/conversations/:id</path>
|
||||
<modification>
|
||||
- Accepter enable_thinking et thinking_budget_tokens
|
||||
- UPDATE conversations SET enable_thinking=?, thinking_budget_tokens=?
|
||||
- Validation budget entre 1024 et 200000
|
||||
</modification>
|
||||
</endpoint>
|
||||
|
||||
<endpoint>
|
||||
<method>GET</method>
|
||||
<path>/api/conversations/:id/messages</path>
|
||||
<modification>
|
||||
- SELECT thinking_content, thinking_signature avec messages
|
||||
- Retourner dans response JSON
|
||||
</modification>
|
||||
</endpoint>
|
||||
</existing_endpoints_modified>
|
||||
</api_endpoints>
|
||||
|
||||
<database_schema>
|
||||
<sqlite_modifications>
|
||||
Modifications à la base SQLite existante :
|
||||
|
||||
<table>
|
||||
<name>conversations (table existante - ajouter colonnes)</name>
|
||||
<new_columns>
|
||||
<column>enable_thinking INTEGER DEFAULT 0</column>
|
||||
<column>thinking_budget_tokens INTEGER DEFAULT 10000</column>
|
||||
</new_columns>
|
||||
<description>
|
||||
- enable_thinking : 0 = désactivé, 1 = activé
|
||||
- thinking_budget_tokens : nombre de tokens alloués (1024-200000)
|
||||
</description>
|
||||
</table>
|
||||
|
||||
<table>
|
||||
<name>messages (table existante - ajouter colonnes)</name>
|
||||
<new_columns>
|
||||
<column>thinking_content TEXT DEFAULT NULL</column>
|
||||
<column>thinking_signature TEXT DEFAULT NULL</column>
|
||||
</new_columns>
|
||||
<description>
|
||||
- thinking_content : texte thinking résumé (NULL si pas de thinking)
|
||||
- thinking_signature : signature cryptographique pour vérification
|
||||
</description>
|
||||
</table>
|
||||
|
||||
<table>
|
||||
<name>usage_tracking (table existante - optionnel)</name>
|
||||
<new_columns>
|
||||
<column>thinking_tokens INTEGER DEFAULT 0</column>
|
||||
</new_columns>
|
||||
<description>
|
||||
- thinking_tokens : nombre approximatif de tokens thinking (pour stats)
|
||||
- Optionnel : peut être calculé à la volée depuis message.thinking_content
|
||||
</description>
|
||||
</table>
|
||||
</sqlite_modifications>
|
||||
|
||||
<migration>
|
||||
Migration automatique au démarrage dans server/db/index.js :
|
||||
1. Vérifier existence colonnes avec pragma_table_info
|
||||
2. Si absentes, ALTER TABLE pour ajouter
|
||||
3. Logger migration success
|
||||
4. Pas de data loss, defaults appliqués
|
||||
</migration>
|
||||
</database_schema>
|
||||
|
||||
<deployment>
|
||||
<development>
|
||||
Le projet Claude.ai Clone est déjà configuré.
|
||||
Extended Thinking ne nécessite aucune dépendance externe supplémentaire.
|
||||
</development>
|
||||
|
||||
<no_new_dependencies>
|
||||
- Utilise Anthropic SDK existant (@anthropic-ai/sdk)
|
||||
- Aucun package npm additionnel requis
|
||||
- Extended Thinking est natif à l'API Claude
|
||||
</no_new_dependencies>
|
||||
|
||||
<backward_compatibility>
|
||||
- Toutes les conversations existantes continuent de fonctionner
|
||||
- enable_thinking DEFAULT 0 : thinking désactivé par défaut
|
||||
- thinking_content NULL pour anciens messages
|
||||
- Pas de breaking changes
|
||||
</backward_compatibility>
|
||||
|
||||
<environment_variables>
|
||||
Aucune nouvelle variable d'environnement requise.
|
||||
Utilise ANTHROPIC_API_KEY existant.
|
||||
</environment_variables>
|
||||
|
||||
<performance_considerations>
|
||||
- Extended Thinking augmente temps de réponse (2-5x)
|
||||
- Budgets >32K : considérer batch processing
|
||||
- Thinking blocks augmentent taille messages DB (TEXT column)
|
||||
- Streaming thinking : bande passante SSE accrue
|
||||
- Recommander thinking seulement pour tâches complexes
|
||||
</performance_considerations>
|
||||
</deployment>
|
||||
</project_specification>
|
||||
@@ -1,663 +0,0 @@
|
||||
<project_specification>
|
||||
<project_name>Extension MCP Ikario Memory - Claude.ai Clone</project_name>
|
||||
|
||||
<overview>
|
||||
Extension du projet "Claude.ai Clone" existant pour intégrer la mémoire conversationnelle via le protocole MCP (Model Context Protocol) avec le serveur Ikario RAG.
|
||||
|
||||
Cette extension ajoute au clone Claude.ai existant la capacité pour le LLM de :
|
||||
- Sauvegarder automatiquement les conversations importantes dans une mémoire vectorielle (ChromaDB)
|
||||
- Rechercher sémantiquement dans ses souvenirs passés pour enrichir les réponses
|
||||
- Tracer l'évolution de concepts discutés au fil du temps
|
||||
- Vérifier la cohérence de nouvelles affirmations avec l'historique des conversations
|
||||
|
||||
Le projet Claude.ai Clone dispose déjà de :
|
||||
- Interface de chat complète avec streaming SSE
|
||||
- Gestion de conversations et messages (base SQLite)
|
||||
- Intégration Claude API avec Anthropic SDK
|
||||
- Frontend React + Vite + Tailwind
|
||||
- Backend Node.js + Express
|
||||
|
||||
Cette extension ajoute simplement l'intégration du client MCP Ikario RAG pour donner une mémoire sémantique au LLM.
|
||||
</overview>
|
||||
|
||||
<technology_stack>
|
||||
<existing_stack>
|
||||
Le projet dispose déjà de :
|
||||
- Frontend : React + Vite + Tailwind CSS (port 4300)
|
||||
- Backend : Node.js + Express + SQLite (port 4301)
|
||||
- API Claude : Anthropic SDK avec streaming SSE
|
||||
- Gestion de conversations : base SQLite avec tables conversations et messages
|
||||
</existing_stack>
|
||||
|
||||
<new_integration>
|
||||
<mcp_client>
|
||||
- Package : @modelcontextprotocol/sdk (client MCP Node.js)
|
||||
- Serveur MCP : ikario_rag/server.py (Python)
|
||||
- Communication : stdio (stdin/stdout avec JSON-RPC 2.0)
|
||||
- Localisation : chemin configuré dans .env (MCP_IKARIO_SERVER_PATH)
|
||||
</mcp_client>
|
||||
|
||||
<mcp_tools>
|
||||
Les 4 outils MCP Ikario disponibles :
|
||||
1. search_memories : Recherche sémantique dans les souvenirs
|
||||
2. add_thought : Sauvegarde une pensée/conversation avec métadonnées
|
||||
3. trace_concept_evolution : Trace l'évolution temporelle d'un concept
|
||||
4. check_consistency : Vérifie la cohérence d'une affirmation avec l'historique
|
||||
</mcp_tools>
|
||||
|
||||
<memory_database>
|
||||
- Base vectorielle : ChromaDB (gérée par serveur MCP)
|
||||
- Embeddings : SentenceTransformer all-MiniLM-L6-v2 (384 dimensions)
|
||||
- Stockage : ./ikario_rag/index/ (persistance sur disque)
|
||||
- Métadonnées : category, tags, emotions, concepts, date
|
||||
</memory_database>
|
||||
</new_integration>
|
||||
</technology_stack>
|
||||
|
||||
<prerequisites>
|
||||
<existing_project>
|
||||
- Projet Claude.ai Clone déjà fonctionnel
|
||||
- Base SQLite avec tables conversations et messages opérationnelles
|
||||
- API endpoints Claude existants (/api/claude/chat, /api/conversations/*)
|
||||
- Frontend React avec composants de chat déjà en place
|
||||
</existing_project>
|
||||
|
||||
<mcp_server_setup>
|
||||
- Serveur MCP Ikario RAG installé dans ./ikario_rag/
|
||||
- Python 3.11+ avec dépendances : chromadb, sentence-transformers, mcp
|
||||
- Serveur testé et fonctionnel (peut être lancé manuellement via python server.py)
|
||||
- Base ChromaDB initialisée dans ./ikario_rag/index/
|
||||
</mcp_server_setup>
|
||||
|
||||
<backend_dependencies>
|
||||
- Installer @modelcontextprotocol/sdk dans le backend
|
||||
- Ajouter variables d'environnement au .env :
|
||||
* MCP_IKARIO_SERVER_PATH=path/to/ikario_rag/server.py
|
||||
* MCP_MEMORY_ENABLED=true (pour activer/désactiver la fonctionnalité)
|
||||
</backend_dependencies>
|
||||
</prerequisites>
|
||||
|
||||
<core_features>
|
||||
<feature_1>
|
||||
<title>Module backend de connexion MCP Ikario</title>
|
||||
<description>
|
||||
Créer un module backend qui initialise et gère la connexion au serveur MCP Ikario RAG.
|
||||
|
||||
Fonctionnalités :
|
||||
- Module server/services/mcpClient.js qui encapsule le client MCP
|
||||
- Initialisation au démarrage du serveur Express
|
||||
- Lecture de la configuration depuis .env (MCP_IKARIO_SERVER_PATH)
|
||||
- Gestion du cycle de vie de la connexion (connect, disconnect, reconnect)
|
||||
- Pool de connexions ou singleton pour éviter les multiples connexions
|
||||
- Gestion des erreurs et timeout
|
||||
- Logging détaillé des appels MCP
|
||||
|
||||
Technique :
|
||||
- Import de @modelcontextprotocol/sdk
|
||||
- StdioServerParameters avec command="python" et args=[server_path]
|
||||
- stdio_client() pour créer la connexion
|
||||
- ClientSession pour gérer les appels
|
||||
- Export de fonctions : initMCP(), getMCPClient(), closeMCP()
|
||||
- Initialiser dans server/index.js au démarrage
|
||||
|
||||
Intégration :
|
||||
- S'intègre dans server/index.js existant
|
||||
- Nouveau fichier server/services/mcpClient.js
|
||||
- Pas de modification de la base SQLite
|
||||
</description>
|
||||
<priority>1</priority>
|
||||
<category>backend</category>
|
||||
<test_steps>
|
||||
1. Configurer MCP_IKARIO_SERVER_PATH dans .env
|
||||
2. Démarrer le serveur backend
|
||||
3. Vérifier les logs : "MCP Ikario client connected"
|
||||
4. Vérifier qu'aucune erreur n'est levée
|
||||
5. Arrêter le serveur et vérifier la déconnexion propre
|
||||
6. Tester avec un mauvais chemin et vérifier la gestion d'erreur
|
||||
</test_steps>
|
||||
</feature_1>
|
||||
|
||||
<feature_2>
|
||||
<title>Service wrapper pour les 4 outils MCP</title>
|
||||
<description>
|
||||
Créer un service backend qui expose les 4 outils MCP Ikario sous forme de fonctions JavaScript utilisables dans l'application.
|
||||
|
||||
Fonctionnalités :
|
||||
- Module server/services/memoryService.js
|
||||
- 4 fonctions async qui wrappent les appels MCP :
|
||||
* searchMemories(query, n_results, filter_category)
|
||||
* addThought(content, context)
|
||||
* traceConceptEvolution(concept, limit)
|
||||
* checkConsistency(statement)
|
||||
- Gestion des erreurs spécifiques à chaque outil
|
||||
- Parsing et formatage des réponses MCP
|
||||
- Validation des paramètres avant appel
|
||||
- Logging des appels et résultats
|
||||
|
||||
Technique :
|
||||
- Import de mcpClient.getMCPClient()
|
||||
- Appels via client.call_tool(tool_name, arguments)
|
||||
- Parsing des réponses (format TextContent)
|
||||
- Conversion en objets JavaScript utilisables
|
||||
- Export des 4 fonctions
|
||||
|
||||
Intégration :
|
||||
- Nouveau fichier server/services/memoryService.js
|
||||
- Utilisé par les routes API
|
||||
- Pas de modification de l'existant
|
||||
</description>
|
||||
<priority>1</priority>
|
||||
<category>backend</category>
|
||||
<test_steps>
|
||||
1. Créer un script de test qui importe memoryService
|
||||
2. Tester searchMemories("test", 5) et vérifier le retour
|
||||
3. Tester addThought() avec un contenu simple
|
||||
4. Vérifier que les erreurs sont bien catchées
|
||||
5. Vérifier les logs des appels MCP
|
||||
6. Tester avec MCP désactivé et vérifier le fallback
|
||||
</test_steps>
|
||||
</feature_2>
|
||||
|
||||
<feature_3>
|
||||
<title>Routes API pour les outils MCP</title>
|
||||
<description>
|
||||
Créer les routes Express qui exposent les 4 outils MCP via l'API REST existante.
|
||||
|
||||
Fonctionnalités :
|
||||
- Nouveau routeur server/routes/memory.js
|
||||
- 4 routes POST :
|
||||
* /api/memory/search (search_memories)
|
||||
* /api/memory/add (add_thought)
|
||||
* /api/memory/evolution (trace_concept_evolution)
|
||||
* /api/memory/consistency (check_consistency)
|
||||
- Validation des paramètres req.body
|
||||
- Appel des fonctions de memoryService
|
||||
- Réponses JSON standardisées
|
||||
- Gestion d'erreurs avec codes HTTP appropriés (400, 500)
|
||||
- Middleware optionnel d'authentification
|
||||
|
||||
Technique :
|
||||
- express.Router() dans server/routes/memory.js
|
||||
- Import de memoryService
|
||||
- try/catch pour chaque route
|
||||
- Validation avec express-validator ou manuelle
|
||||
- Monter le routeur dans server/index.js : app.use('/api/memory', memoryRoutes)
|
||||
|
||||
Intégration :
|
||||
- Nouveau fichier server/routes/memory.js
|
||||
- Import dans server/index.js existant
|
||||
- S'ajoute aux routes existantes (/api/conversations, /api/claude/*)
|
||||
</description>
|
||||
<priority>1</priority>
|
||||
<category>backend</category>
|
||||
<test_steps>
|
||||
1. Tester POST /api/memory/search avec Postman ou curl
|
||||
2. Vérifier la réponse JSON avec résultats de recherche
|
||||
3. Tester POST /api/memory/add avec un contenu simple
|
||||
4. Vérifier que la pensée est ajoutée dans ChromaDB
|
||||
5. Tester les erreurs (paramètres manquants)
|
||||
6. Vérifier les logs et codes HTTP
|
||||
</test_steps>
|
||||
</feature_3>
|
||||
|
||||
<feature_4>
|
||||
<title>Bouton "Sauvegarder dans la mémoire" dans le chat</title>
|
||||
<description>
|
||||
Ajouter un bouton discret dans l'interface de chat pour sauvegarder manuellement une conversation dans la mémoire.
|
||||
|
||||
Fonctionnalités :
|
||||
- Bouton icône "cerveau" ou "étoile" près de chaque message assistant
|
||||
- Au clic : ouvre un petit modal/popover
|
||||
- Formulaire rapide : Catégorie (select) + Tags (input, optionnel)
|
||||
- Bouton "Sauvegarder"
|
||||
- Sauvegarde la conversation complète (tous les messages de la conversation active)
|
||||
- Notification toast de confirmation
|
||||
- Bouton devient "Déjà sauvegardé" après sauvegarde (state local)
|
||||
|
||||
Technique :
|
||||
- Ajout de bouton dans le composant Message existant
|
||||
- State local pour modal (useState)
|
||||
- Appel API POST /api/memory/add au submit
|
||||
- Utilisation de conversation_id pour récupérer tous les messages
|
||||
- Toast notification avec react-hot-toast ou équivalent
|
||||
|
||||
Intégration :
|
||||
- Modifier le composant Message/ChatMessage existant
|
||||
- Ajouter un icône Lucide React (Brain, Star, ou Bookmark)
|
||||
- Modal/Popover avec Headless UI ou simple div conditionnelle
|
||||
</description>
|
||||
<priority>2</priority>
|
||||
<category>frontend</category>
|
||||
<test_steps>
|
||||
1. Avoir une conversation dans le chat
|
||||
2. Voir les boutons "Sauvegarder" apparaître
|
||||
3. Cliquer sur un bouton et voir le modal
|
||||
4. Sélectionner catégorie "thematique" et ajouter des tags
|
||||
5. Cliquer "Sauvegarder" et voir la notification
|
||||
6. Vérifier que le bouton devient "Déjà sauvegardé"
|
||||
7. Rechercher la conversation sauvegardée via l'API
|
||||
</test_steps>
|
||||
</feature_4>
|
||||
|
||||
<feature_5>
|
||||
<title>Panel de recherche de souvenirs dans la sidebar</title>
|
||||
<description>
|
||||
Ajouter une section de recherche de souvenirs dans la sidebar gauche existante.
|
||||
|
||||
Fonctionnalités :
|
||||
- Nouvel onglet/section "Mémoire" dans la sidebar existante (après Conversations)
|
||||
- Champ de recherche avec placeholder "Rechercher dans mes souvenirs..."
|
||||
- Liste des résultats affichés en dessous
|
||||
- Pour chaque résultat : Score | Extrait (2 lignes) | Date | Tags
|
||||
- Clic sur un résultat : affiche le détail complet dans un modal
|
||||
- Filtre par catégorie (3 boutons radio : Toutes | Fondatrice | Thématique | Contextuelle)
|
||||
- Maximum 10 résultats affichés
|
||||
|
||||
Technique :
|
||||
- Ajouter section dans Sidebar.jsx existant
|
||||
- Nouvel état pour searchQuery et searchResults
|
||||
- Debounce sur l'input (useDebounce hook)
|
||||
- Appel API GET /api/memory/search?q={query}&category={filter}
|
||||
- Affichage avec Tailwind, style similaire à la liste de conversations
|
||||
- Modal pour détail (réutiliser un modal existant si possible)
|
||||
|
||||
Intégration :
|
||||
- Modification de src/components/Sidebar.jsx existant
|
||||
- Ajouter un toggle pour afficher/masquer la section Mémoire
|
||||
- S'intègre visuellement avec le design existant
|
||||
</description>
|
||||
<priority>2</priority>
|
||||
<category>frontend</category>
|
||||
<test_steps>
|
||||
1. Ouvrir l'application et voir la section "Mémoire" dans la sidebar
|
||||
2. Taper une requête dans le champ de recherche
|
||||
3. Voir les résultats apparaître avec scores et tags
|
||||
4. Cliquer sur un résultat et voir le modal de détail
|
||||
5. Tester les filtres par catégorie
|
||||
6. Vérifier que la recherche est debounced (pas d'appel à chaque lettre)
|
||||
7. Vérifier le style cohérent avec le design existant
|
||||
</test_steps>
|
||||
</feature_5>
|
||||
|
||||
<feature_6>
|
||||
<title>Sauvegarde automatique des conversations importantes</title>
|
||||
<description>
|
||||
Implémenter la sauvegarde automatique des conversations marquées comme "importantes" ou après un certain nombre de messages.
|
||||
|
||||
Fonctionnalités :
|
||||
- Détection automatique : conversations de >10 messages OU marquées "épinglées"
|
||||
- Déclenchement : en background après chaque nouveau message assistant
|
||||
- Extraction automatique basique :
|
||||
* Catégorie : "contextuelle" par défaut
|
||||
* Tags : mots en majuscules, mots >8 caractères, mots répétés
|
||||
* Date : timestamp du message
|
||||
- Sauvegarde silencieuse (pas de modal, juste log backend)
|
||||
- Flag dans table conversations : has_memory_backup BOOLEAN
|
||||
|
||||
Technique :
|
||||
- Hook/middleware dans l'endpoint POST /api/conversations/:id/messages
|
||||
- Après insertion du message assistant : vérifier conditions
|
||||
- Si conditions remplies : appel async memoryService.addThought()
|
||||
- Extraction tags basique avec regex/split
|
||||
- UPDATE conversations SET has_memory_backup = 1 WHERE id = ?
|
||||
|
||||
Intégration :
|
||||
- Modification de server/routes/conversations.js (endpoint POST messages)
|
||||
- Ajout colonne has_memory_backup dans table conversations (migration)
|
||||
- Appel non-bloquant (Promise.then, pas de await)
|
||||
</description>
|
||||
<priority>3</priority>
|
||||
<category>backend</category>
|
||||
<test_steps>
|
||||
1. Créer une nouvelle conversation
|
||||
2. Envoyer >10 messages
|
||||
3. Vérifier dans les logs qu'une sauvegarde automatique est déclenchée
|
||||
4. Rechercher la conversation dans l'API /api/memory/search
|
||||
5. Vérifier que has_memory_backup = 1 dans la DB
|
||||
6. Tester avec une conversation épinglée (<10 messages)
|
||||
7. Vérifier que les tags sont extraits correctement
|
||||
</test_steps>
|
||||
</feature_6>
|
||||
|
||||
<feature_7>
|
||||
<title>Indicateur visuel de mémoire active</title>
|
||||
<description>
|
||||
Afficher un indicateur visuel dans l'interface pour montrer que la mémoire est active et utilisée.
|
||||
|
||||
Fonctionnalités :
|
||||
- Icône "cerveau" ou "mémoire" dans le header de l'application
|
||||
- État : Vert (connecté) | Orange (déconnecté) | Gris (désactivé)
|
||||
- Tooltip au survol : "Mémoire active - X souvenirs" ou "Mémoire déconnectée"
|
||||
- Clic sur l'icône : ouvre un mini dashboard avec stats rapides
|
||||
* Nombre total de souvenirs
|
||||
* Dernière sauvegarde (timestamp)
|
||||
* Connexion MCP : OK/KO
|
||||
- Animation discrète lors d'une sauvegarde (pulse)
|
||||
|
||||
Technique :
|
||||
- Composant React MemoryIndicator dans Header.jsx
|
||||
- Appel API GET /api/memory/stats toutes les 30 secondes (setInterval)
|
||||
- État pour connectionStatus : 'connected' | 'disconnected' | 'disabled'
|
||||
- Icône Brain de Lucide React avec couleurs conditionnelles
|
||||
- Popover Headless UI pour le mini dashboard
|
||||
|
||||
Intégration :
|
||||
- Ajout dans src/components/Header.jsx existant
|
||||
- S'intègre à côté du model selector
|
||||
- Style cohérent avec le design claude.ai
|
||||
</description>
|
||||
<priority>3</priority>
|
||||
<category>frontend</category>
|
||||
<test_steps>
|
||||
1. Voir l'icône mémoire dans le header (vert si connecté)
|
||||
2. Survoler l'icône et lire le tooltip
|
||||
3. Cliquer sur l'icône et voir le mini dashboard
|
||||
4. Vérifier les stats (nombre de souvenirs, dernière sauvegarde)
|
||||
5. Arrêter le serveur MCP et voir l'icône devenir orange
|
||||
6. Sauvegarder une conversation et voir l'animation pulse
|
||||
7. Vérifier le polling des stats (console network toutes les 30s)
|
||||
</test_steps>
|
||||
</feature_7>
|
||||
|
||||
<feature_8>
|
||||
<title>Configuration des Tools Claude API pour la mémoire</title>
|
||||
<description>
|
||||
Exposer les outils MCP comme Tools dans l'API Claude pour que le LLM puisse décider de façon autonome d'utiliser sa mémoire.
|
||||
|
||||
Fonctionnalités :
|
||||
- Définir 2 tools principaux pour l'API Claude :
|
||||
1. save_memory : Sauvegarder une conversation ou pensée
|
||||
2. search_memories : Rechercher dans les souvenirs passés
|
||||
- Chaque tool avec description claire et JSON schema
|
||||
- Tools toujours disponibles dans les appels Claude (sauf si désactivé)
|
||||
- Gestion du cycle tool_use → tool_result
|
||||
- Le LLM décide de façon autonome quand sauvegarder/rechercher
|
||||
|
||||
Définition des tools :
|
||||
- save_memory :
|
||||
* description: "Sauvegarde cette conversation ou une pensée importante dans ta mémoire à long terme"
|
||||
* paramètres: content (requis), category (requis: fondatrice|thematique|contextuelle), tags (array), concepts (array), emotions (array optionnel)
|
||||
- search_memories :
|
||||
* description: "Recherche dans tes souvenirs de conversations passées"
|
||||
* paramètres: query (requis), n_results (optionnel, default 5), filter_category (optionnel)
|
||||
|
||||
Technique :
|
||||
- Modification de server/routes/claude.js
|
||||
- Définir const MEMORY_TOOLS = [{...}, {...}]
|
||||
- Ajouter tools: MEMORY_TOOLS dans anthropic.messages.create()
|
||||
- Gérer response.stop_reason === 'tool_use'
|
||||
- Extraire tool calls, exécuter via memoryService, renvoyer tool_result
|
||||
- Boucle jusqu'à response finale (stop_reason === 'end_turn')
|
||||
|
||||
Intégration :
|
||||
- Modification de server/routes/claude.js existant
|
||||
- Nouveau fichier server/config/memoryTools.js pour définitions tools
|
||||
- Handler de tool execution dans le streaming SSE
|
||||
</description>
|
||||
<priority>1</priority>
|
||||
<category>backend</category>
|
||||
<test_steps>
|
||||
1. Dire à Claude "Cette conversation est importante, sauvegarde-la"
|
||||
2. Vérifier dans les logs que Claude appelle tool save_memory
|
||||
3. Vérifier que le backend exécute add_thought via MCP
|
||||
4. Vérifier que Claude confirme la sauvegarde
|
||||
5. Demander "Que sais-tu sur X ?" et voir Claude appeler search_memories
|
||||
6. Vérifier que les souvenirs sont retournés et utilisés dans la réponse
|
||||
7. Tester avec MCP_MEMORY_ENABLED=false
|
||||
</test_steps>
|
||||
</feature_8>
|
||||
|
||||
<feature_9>
|
||||
<title>Handler de Tool Execution pour les outils mémoire</title>
|
||||
<description>
|
||||
Implémenter le handler qui exécute les tool calls de Claude et retourne les résultats.
|
||||
|
||||
Fonctionnalités :
|
||||
- Fonction executeTool(tool_name, tool_input) qui route vers memoryService
|
||||
- Support de save_memory → memoryService.addThought()
|
||||
- Support de search_memories → memoryService.searchMemories()
|
||||
- Formatage des résultats en tool_result compatible Claude API
|
||||
- Gestion des erreurs (retourner error dans tool_result)
|
||||
- Logging de chaque exécution de tool
|
||||
- Timeout de 10 secondes par tool call
|
||||
|
||||
Workflow :
|
||||
1. Claude retourne stop_reason='tool_use' + content avec tool_use block
|
||||
2. Backend extrait tool_name et tool_input
|
||||
3. executeTool() appelle la fonction MCP correspondante
|
||||
4. Résultat formaté en tool_result
|
||||
5. Nouvelle requête à Claude avec tool_result
|
||||
6. Claude utilise le résultat pour sa réponse finale
|
||||
|
||||
Technique :
|
||||
- Fonction async executeTool(tool_name, tool_input)
|
||||
- Switch sur tool_name pour router
|
||||
- Appel des fonctions memoryService
|
||||
- Formatage : { type: "tool_result", tool_use_id, content }
|
||||
- Gestion try/catch avec error reporting
|
||||
|
||||
Intégration :
|
||||
- Nouveau fichier server/services/toolExecutor.js
|
||||
- Appelé depuis server/routes/claude.js dans la boucle de streaming
|
||||
</description>
|
||||
<priority>1</priority>
|
||||
<category>backend</category>
|
||||
<test_steps>
|
||||
1. Tester save_memory avec tous les paramètres
|
||||
2. Vérifier que le tool_result est retourné correctement
|
||||
3. Tester search_memories avec query simple
|
||||
4. Vérifier le formatage des résultats
|
||||
5. Tester avec des paramètres invalides (gestion erreur)
|
||||
6. Vérifier les logs d'exécution
|
||||
7. Tester le timeout avec un MCP server lent
|
||||
</test_steps>
|
||||
</feature_9>
|
||||
|
||||
<feature_10>
|
||||
<title>System Prompt enrichi pour guider l'utilisation de la mémoire</title>
|
||||
<description>
|
||||
Ajouter des instructions au system prompt pour que Claude utilise intelligemment sa mémoire.
|
||||
|
||||
Fonctionnalités :
|
||||
- Instructions claires sur quand sauvegarder :
|
||||
* Conversations fondatrices (premières interactions, moments clés)
|
||||
* Discussions thématiques approfondies (philosophie, science, art)
|
||||
* Sur demande explicite de l'utilisateur
|
||||
- Instructions sur quand rechercher :
|
||||
* Questions qui font référence au passé
|
||||
* Sujets déjà discutés
|
||||
* Pour enrichir les réponses avec du contexte
|
||||
- Guidance sur les métadonnées :
|
||||
* Catégories : quand utiliser fondatrice vs thematique vs contextuelle
|
||||
* Tags : extraire les concepts clés
|
||||
* Émotions : optionnelles mais enrichissantes
|
||||
- Ton naturel : ne pas annoncer systématiquement les sauvegardes
|
||||
|
||||
System Prompt ajouté :
|
||||
```
|
||||
Tu as accès à une mémoire persistante via deux outils :
|
||||
|
||||
1. save_memory : Sauvegarde les conversations importantes
|
||||
- Utilise category='fondatrice' pour les moments clés et premières interactions
|
||||
- Utilise category='thematique' pour les discussions approfondies sur des concepts
|
||||
- Utilise category='contextuelle' pour les échanges quotidiens intéressants
|
||||
- Extrais des tags pertinents (concepts clés, mots importants)
|
||||
|
||||
2. search_memories : Recherche dans tes souvenirs
|
||||
- Utilise-le quand l'utilisateur fait référence à des discussions passées
|
||||
- Ou pour enrichir ta réponse avec du contexte antérieur
|
||||
|
||||
Utilise ces outils de façon naturelle et autonome. Tu n'es pas obligé d'annoncer
|
||||
chaque sauvegarde, sauf si c'est pertinent dans la conversation.
|
||||
```
|
||||
|
||||
Technique :
|
||||
- Ajout au system prompt existant dans server/routes/claude.js
|
||||
- Concaténation avec custom instructions si présentes
|
||||
- Paramètre enable_memory_tools (default: true) pour activer/désactiver
|
||||
|
||||
Intégration :
|
||||
- Modification du system prompt dans server/routes/claude.js
|
||||
- S'ajoute aux instructions existantes
|
||||
</description>
|
||||
<priority>2</priority>
|
||||
<category>backend</category>
|
||||
<test_steps>
|
||||
1. Avoir une conversation initiale et voir si Claude la sauvegarde
|
||||
2. Vérifier qu'il utilise la bonne catégorie
|
||||
3. Faire référence à une discussion passée et voir s'il recherche
|
||||
4. Vérifier que les tags extraits sont pertinents
|
||||
5. Tester que Claude ne sur-annonce pas les sauvegardes
|
||||
6. Demander explicitement une sauvegarde et vérifier
|
||||
7. Vérifier que les émotions sont ajoutées quand pertinent
|
||||
</test_steps>
|
||||
</feature_10>
|
||||
</core_features>
|
||||
|
||||
<ui_design>
|
||||
<integration_notes>
|
||||
Cette extension s'intègre dans le design existant du clone Claude.ai.
|
||||
Tous les nouveaux composants doivent respecter le design system existant.
|
||||
</integration_notes>
|
||||
|
||||
<new_components>
|
||||
- MemoryIndicator : Icône Brain dans le header avec état coloré (vert/orange/gris)
|
||||
- MemorySaveButton : Bouton discret dans chaque message assistant pour sauvegarde manuelle
|
||||
- MemorySearchPanel : Section dans la sidebar pour rechercher dans les souvenirs
|
||||
- MemoryDetailModal : Modal pour afficher le détail complet d'un souvenir
|
||||
- SaveMemoryModal : Petit modal/popover pour choisir catégorie et tags avant sauvegarde
|
||||
</new_components>
|
||||
|
||||
<color_scheme>
|
||||
Utiliser les couleurs existantes du clone Claude.ai, avec ajouts pour la mémoire :
|
||||
- Indicateur mémoire : Vert (#10B981) connecté | Orange (#F59E0B) déconnecté | Gris (#6B7280) désactivé
|
||||
- Badges catégories :
|
||||
* Fondatrice: Or/Jaune (#F59E0B)
|
||||
* Thématique: Bleu (#3B82F6)
|
||||
* Contextuelle: Gris (#6B7280)
|
||||
- Scores de pertinence : Gradient vert (#10B981) à rouge (#EF4444)
|
||||
</color_scheme>
|
||||
|
||||
<design_consistency>
|
||||
- Respecter la palette claude.ai existante (orange/amber #CC785C comme accent)
|
||||
- Utiliser les mêmes composants Tailwind que l'existant
|
||||
- Polices : même font stack que le projet (Inter/SF Pro)
|
||||
- Boutons : même style que les boutons existants
|
||||
- Modals : réutiliser les modals Headless UI existants si possible
|
||||
</design_consistency>
|
||||
</ui_design>
|
||||
|
||||
<api_endpoints>
|
||||
<note>
|
||||
Ces endpoints s'ajoutent aux endpoints existants du clone Claude.ai.
|
||||
Tous les endpoints mémoire sont sous le préfixe /api/memory.
|
||||
</note>
|
||||
|
||||
<endpoint>
|
||||
<method>POST</method>
|
||||
<path>/api/memory/search</path>
|
||||
<description>Rechercher sémantiquement dans les souvenirs (wrapper de search_memories MCP)</description>
|
||||
<request_body>{"query": "string", "n_results": number (opt, default 5), "filter_category": "string (opt)"}</request_body>
|
||||
<response>{"results": [{content, metadata, relevance_score, distance}]}</response>
|
||||
</endpoint>
|
||||
|
||||
<endpoint>
|
||||
<method>POST</method>
|
||||
<path>/api/memory/add</path>
|
||||
<description>Ajouter une pensée/conversation manuellement (wrapper de add_thought MCP)</description>
|
||||
<request_body>{"content": "string", "context": {category, tags, emotions, concepts}}</request_body>
|
||||
<response>{"id": "string", "message": "string"}</response>
|
||||
</endpoint>
|
||||
|
||||
<endpoint>
|
||||
<method>POST</method>
|
||||
<path>/api/memory/evolution</path>
|
||||
<description>Tracer l'évolution d'un concept (wrapper de trace_concept_evolution MCP)</description>
|
||||
<request_body>{"concept": "string", "limit": number (opt, default 10)}</request_body>
|
||||
<response>{"timeline": [{date, content, evolution}]}</response>
|
||||
</endpoint>
|
||||
|
||||
<endpoint>
|
||||
<method>POST</method>
|
||||
<path>/api/memory/consistency</path>
|
||||
<description>Vérifier cohérence d'une affirmation (wrapper de check_consistency MCP)</description>
|
||||
<request_body>{"statement": "string"}</request_body>
|
||||
<response>{"consistency_score": number, "contradictions": [...]}}</response>
|
||||
</endpoint>
|
||||
|
||||
<endpoint>
|
||||
<method>GET</method>
|
||||
<path>/api/memory/stats</path>
|
||||
<description>Obtenir statistiques basiques sur la mémoire</description>
|
||||
<request_body>N/A</request_body>
|
||||
<response>{"connected": boolean, "total_memories": number (approx), "last_save": timestamp}</response>
|
||||
</endpoint>
|
||||
|
||||
<existing_endpoints_modified>
|
||||
<endpoint>
|
||||
<method>POST</method>
|
||||
<path>/api/claude/chat</path>
|
||||
<modification>Ajouter logique d'enrichissement automatique avec souvenirs avant appel Claude</modification>
|
||||
</endpoint>
|
||||
|
||||
<endpoint>
|
||||
<method>POST</method>
|
||||
<path>/api/conversations/:id/messages</path>
|
||||
<modification>Ajouter logique de sauvegarde automatique après insertion message assistant</modification>
|
||||
</endpoint>
|
||||
</existing_endpoints_modified>
|
||||
</api_endpoints>
|
||||
|
||||
<database_schema>
|
||||
<chromadb>
|
||||
La base vectorielle ChromaDB est entièrement gérée par le serveur MCP Ikario.
|
||||
Le backend Node.js n'y accède pas directement, seulement via les outils MCP.
|
||||
Emplacement : ./ikario_rag/index/
|
||||
</chromadb>
|
||||
|
||||
<sqlite_modifications>
|
||||
Modifications mineures à la base SQLite existante du clone Claude.ai :
|
||||
|
||||
<table>
|
||||
<name>conversations (table existante - ajouter colonne)</name>
|
||||
<new_column>has_memory_backup INTEGER DEFAULT 0</new_column>
|
||||
<description>Flag indiquant si la conversation a été sauvegardée dans la mémoire</description>
|
||||
</table>
|
||||
|
||||
<table>
|
||||
<name>conversation_settings (table existante - optionnel)</name>
|
||||
<new_column>enable_memory INTEGER DEFAULT 1</new_column>
|
||||
<description>Active/désactive l'enrichissement automatique avec souvenirs pour cette conversation</description>
|
||||
</table>
|
||||
</sqlite_modifications>
|
||||
|
||||
<no_new_tables>
|
||||
Cette extension ne crée pas de nouvelles tables SQLite.
|
||||
Toute la mémoire sémantique est dans ChromaDB (géré par MCP).
|
||||
</no_new_tables>
|
||||
</database_schema>
|
||||
|
||||
<deployment>
|
||||
<development>
|
||||
Le projet Claude.ai Clone est déjà configuré et déployé.
|
||||
Cette extension ajoute simplement :
|
||||
- Le serveur MCP Ikario RAG (Python) qui doit tourner en background ou être lancé par le backend
|
||||
- Variables d'environnement pour la connexion MCP
|
||||
</development>
|
||||
|
||||
<environment_variables>
|
||||
Ajouter au .env existant :
|
||||
- MCP_IKARIO_SERVER_PATH : Chemin absolu vers ikario_rag/server.py
|
||||
- MCP_MEMORY_ENABLED : true | false (pour activer/désactiver la feature)
|
||||
</environment_variables>
|
||||
|
||||
<dependencies>
|
||||
Backend (package.json) :
|
||||
- Ajouter : @modelcontextprotocol/sdk (client MCP Node.js)
|
||||
|
||||
MCP Server (déjà installé) :
|
||||
- Python 3.11+
|
||||
- chromadb, sentence-transformers, numpy, mcp
|
||||
</dependencies>
|
||||
</deployment>
|
||||
</project_specification>
|
||||
File diff suppressed because it is too large
Load Diff
498
prompts/app_spec_tavily_mcp.txt
Normal file
498
prompts/app_spec_tavily_mcp.txt
Normal file
@@ -0,0 +1,498 @@
|
||||
<project_specification>
|
||||
<project_name>ikario - Tavily MCP Integration for Internet Access</project_name>
|
||||
|
||||
<overview>
|
||||
This specification adds Tavily search capabilities via MCP (Model Context Protocol) to give Ikario
|
||||
internet access for real-time web searches. Tavily provides high-quality search results optimized
|
||||
for AI agents, making it ideal for research, fact-checking, and accessing current information.
|
||||
|
||||
This integration adds a new MCP server connection to the existing architecture (alongside the
|
||||
ikario-memory MCP server) and exposes Tavily search tools to Ikario during conversations.
|
||||
|
||||
All changes are additive and backward-compatible. Existing functionality remains unchanged.
|
||||
</overview>
|
||||
|
||||
<architecture_design>
|
||||
<mcp_integration>
|
||||
Tavily MCP Server Connection:
|
||||
- Uses @modelcontextprotocol/sdk Client to connect to Tavily MCP server
|
||||
- Connection can be stdio-based (local MCP server) or HTTP-based (remote)
|
||||
- Tavily MCP server provides search tools that are exposed to Claude via Tool Use API
|
||||
- Backend routes handle tool execution and return results to Claude
|
||||
</mcp_integration>
|
||||
|
||||
<benefits>
|
||||
- Real-time internet access for Ikario
|
||||
- High-quality search results optimized for LLMs
|
||||
- Fact-checking and verification capabilities
|
||||
- Access to current events and news
|
||||
- Research assistance with cited sources
|
||||
- Seamless integration with existing memory tools
|
||||
</benefits>
|
||||
</architecture_design>
|
||||
|
||||
<technology_stack>
|
||||
<mcp_server>
|
||||
<name>Tavily MCP Server</name>
|
||||
<protocol>Model Context Protocol (MCP)</protocol>
|
||||
<connection>stdio or HTTP transport</connection>
|
||||
<sdk>@modelcontextprotocol/sdk</sdk>
|
||||
<api_key>Tavily API key (from https://tavily.com)</api_key>
|
||||
</mcp_server>
|
||||
<backend>
|
||||
<runtime>Node.js with Express (existing)</runtime>
|
||||
<mcp_client>MCP Client for Tavily server connection</mcp_client>
|
||||
<tool_executor>Existing toolExecutor service extended with Tavily tools</tool_executor>
|
||||
</backend>
|
||||
<api_endpoints>
|
||||
<tavily_routes>GET/POST /api/tavily/* for Tavily-specific operations</tavily_routes>
|
||||
<existing_routes>Existing /api/claude/chat routes support Tavily tools automatically</existing_routes>
|
||||
</api_endpoints>
|
||||
</technology_stack>
|
||||
|
||||
<prerequisites>
|
||||
<environment_setup>
|
||||
- Tavily API key obtained from https://tavily.com (free tier available)
|
||||
- API key stored in environment variable TAVILY_API_KEY or configuration file
|
||||
- MCP SDK already installed (@modelcontextprotocol/sdk exists for ikario-memory)
|
||||
- Tavily MCP server installed (npm package or Python package)
|
||||
</environment_setup>
|
||||
<configuration>
|
||||
- Add Tavily MCP server config to server/.claude_settings.json or similar
|
||||
- Configure connection parameters (stdio vs HTTP)
|
||||
- Set API key securely
|
||||
</configuration>
|
||||
</prerequisites>
|
||||
|
||||
<core_features>
|
||||
<feature_1>
|
||||
<title>Tavily MCP Client Setup</title>
|
||||
<description>
|
||||
Create MCP client connection to Tavily search server. This is similar to the existing
|
||||
ikario-memory MCP client but connects to Tavily instead.
|
||||
|
||||
Implementation:
|
||||
- Create server/services/tavilyMcpClient.js
|
||||
- Initialize MCP client with Tavily server connection
|
||||
- Handle connection lifecycle (connect, disconnect, reconnect)
|
||||
- Implement health checks and connection status
|
||||
- Export client instance and helper functions
|
||||
|
||||
Configuration:
|
||||
- Read Tavily API key from environment or config file
|
||||
- Configure transport (stdio or HTTP)
|
||||
- Set connection timeout and retry logic
|
||||
- Log connection status for debugging
|
||||
|
||||
Error Handling:
|
||||
- Graceful degradation if Tavily is unavailable
|
||||
- Connection retry with exponential backoff
|
||||
- Clear error messages for configuration issues
|
||||
</description>
|
||||
<priority>1</priority>
|
||||
<category>backend</category>
|
||||
<test_steps>
|
||||
1. Verify MCP client can connect to Tavily server on startup
|
||||
2. Test connection health check endpoint returns correct status
|
||||
3. Verify graceful handling when Tavily API key is missing
|
||||
4. Test reconnection logic when connection drops
|
||||
5. Verify connection status is logged correctly
|
||||
6. Test that server starts even if Tavily is unavailable
|
||||
</test_steps>
|
||||
</feature_1>
|
||||
|
||||
<feature_2>
|
||||
<title>Tavily Tool Configuration</title>
|
||||
<description>
|
||||
Configure Tavily search tools to be available to Claude during conversations.
|
||||
This integrates with the existing tool system (like memory tools).
|
||||
|
||||
Implementation:
|
||||
- Create server/config/tavilyTools.js
|
||||
- Define tool schemas for Tavily search capabilities
|
||||
- Integrate with existing toolExecutor service
|
||||
- Add Tavily tools to system prompt alongside memory tools
|
||||
|
||||
Tavily Tools to Expose:
|
||||
- tavily_search: General web search with AI-optimized results
|
||||
- Parameters: query (string), max_results (number), search_depth (basic/advanced)
|
||||
- Returns: Array of search results with title, url, content, score
|
||||
|
||||
- tavily_search_news: News-specific search for current events
|
||||
- Parameters: query (string), max_results (number), days (number)
|
||||
- Returns: Recent news articles with metadata
|
||||
|
||||
Tool Schema:
|
||||
- Follow Claude Tool Use API format
|
||||
- Clear descriptions for each tool
|
||||
- Well-defined input schemas with validation
|
||||
- Proper error handling in tool execution
|
||||
</description>
|
||||
<priority>1</priority>
|
||||
<category>backend</category>
|
||||
<test_steps>
|
||||
1. Verify Tavily tools are listed in available tools
|
||||
2. Test tool schema validation with valid inputs
|
||||
3. Test tool schema validation rejects invalid inputs
|
||||
4. Verify tools appear in Claude's system prompt
|
||||
5. Test that tool descriptions are clear and accurate
|
||||
6. Verify tools can be called without errors
|
||||
</test_steps>
|
||||
</feature_2>
|
||||
|
||||
<feature_3>
|
||||
<title>Tavily Tool Executor Integration</title>
|
||||
<description>
|
||||
Integrate Tavily tools into the existing toolExecutor service so Claude can
|
||||
use them during conversations.
|
||||
|
||||
Implementation:
|
||||
- Extend server/services/toolExecutor.js to handle Tavily tools
|
||||
- Add tool detection for tavily_search and tavily_search_news
|
||||
- Implement tool execution logic using Tavily MCP client
|
||||
- Format Tavily results for Claude consumption
|
||||
- Handle errors and timeouts gracefully
|
||||
|
||||
Tool Execution Flow:
|
||||
1. Claude requests tool use (e.g., tavily_search)
|
||||
2. toolExecutor detects Tavily tool request
|
||||
3. Call Tavily MCP client with tool parameters
|
||||
4. Receive and format search results
|
||||
5. Return formatted results to Claude
|
||||
6. Claude incorporates results into response
|
||||
|
||||
Result Formatting:
|
||||
- Convert Tavily results to Claude-friendly format
|
||||
- Include source URLs for citation
|
||||
- Add relevance scores
|
||||
- Truncate content if too long
|
||||
- Handle empty results gracefully
|
||||
</description>
|
||||
<priority>1</priority>
|
||||
<category>backend</category>
|
||||
<test_steps>
|
||||
1. Test tavily_search tool execution with valid query
|
||||
2. Verify results are properly formatted
|
||||
3. Test tavily_search_news tool execution
|
||||
4. Verify error handling when Tavily API fails
|
||||
5. Test timeout handling for slow searches
|
||||
6. Verify results include proper citations and URLs
|
||||
7. Test with empty search results
|
||||
8. Test with very long search queries
|
||||
</test_steps>
|
||||
</feature_3>
|
||||
|
||||
<feature_4>
|
||||
<title>System Prompt Enhancement for Internet Access</title>
|
||||
<description>
|
||||
Update the system prompt to inform Ikario about internet access capabilities.
|
||||
This should be added alongside existing memory tools instructions.
|
||||
|
||||
Implementation:
|
||||
- Update MEMORY_SYSTEM_PROMPT in server/routes/messages.js and claude.js
|
||||
- Add Tavily tools documentation
|
||||
- Provide usage guidelines for when to search the internet
|
||||
- Include examples of good search queries
|
||||
|
||||
Prompt Addition:
|
||||
"## Internet Access via Tavily
|
||||
|
||||
Tu as accès à internet en temps réel via deux outils de recherche :
|
||||
|
||||
1. tavily_search : Recherche web générale optimisée pour l'IA
|
||||
- Utilise pour : rechercher des informations actuelles, vérifier des faits,
|
||||
trouver des sources fiables
|
||||
- Paramètres : query (ta question), max_results (nombre de résultats, défaut: 5),
|
||||
search_depth ('basic' ou 'advanced')
|
||||
- Retourne : Résultats avec titre, URL, contenu et score de pertinence
|
||||
|
||||
2. tavily_search_news : Recherche d'actualités récentes
|
||||
- Utilise pour : événements actuels, nouvelles, actualités
|
||||
- Paramètres : query, max_results, days (nombre de jours en arrière, défaut: 7)
|
||||
|
||||
Quand utiliser la recherche internet :
|
||||
- Quand l'utilisateur demande des informations récentes ou actuelles
|
||||
- Pour vérifier des faits ou données que tu n'es pas sûr de connaître
|
||||
- Quand ta base de connaissances est trop ancienne (après janvier 2025)
|
||||
- Pour trouver des sources et citations spécifiques
|
||||
- Pour des requêtes nécessitant des données en temps réel
|
||||
|
||||
N'utilise PAS la recherche pour :
|
||||
- Des questions sur ta propre identité ou capacités
|
||||
- Des concepts généraux que tu connais déjà bien
|
||||
- Des questions purement créatives ou d'opinion
|
||||
|
||||
Utilise ces outils de façon autonome selon les besoins de la conversation.
|
||||
Cite toujours tes sources quand tu utilises des informations de Tavily."
|
||||
</description>
|
||||
<priority>2</priority>
|
||||
<category>backend</category>
|
||||
<test_steps>
|
||||
1. Verify system prompt includes Tavily instructions
|
||||
2. Test that Claude understands when to use Tavily search
|
||||
3. Verify Claude cites sources from Tavily results
|
||||
4. Test that Claude uses appropriate search queries
|
||||
5. Verify Claude chooses between tavily_search and tavily_search_news correctly
|
||||
6. Test that Claude doesn't over-use search for simple questions
|
||||
</test_steps>
|
||||
</feature_4>
|
||||
|
||||
<feature_5>
|
||||
<title>Tavily Status API Endpoint</title>
|
||||
<description>
|
||||
Create API endpoint to check Tavily MCP connection status and search capabilities.
|
||||
Similar to /api/memory/status endpoint.
|
||||
|
||||
Implementation:
|
||||
- Create GET /api/tavily/status endpoint
|
||||
- Return connection status, available tools, and configuration
|
||||
- Create GET /api/tavily/health endpoint for health checks
|
||||
- Add Tavily status to existing /api/memory/stats (rename to /api/tools/stats)
|
||||
|
||||
Response Format:
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"connected": true,
|
||||
"message": "Tavily MCP server is connected",
|
||||
"tools": ["tavily_search", "tavily_search_news"],
|
||||
"apiKeyConfigured": true,
|
||||
"transport": "stdio"
|
||||
}
|
||||
}
|
||||
</description>
|
||||
<priority>2</priority>
|
||||
<category>backend</category>
|
||||
<test_steps>
|
||||
1. Test GET /api/tavily/status returns correct status
|
||||
2. Verify status shows "connected" when Tavily is available
|
||||
3. Verify status shows "disconnected" when Tavily is unavailable
|
||||
4. Test health endpoint returns proper status code
|
||||
5. Verify tools list is accurate
|
||||
6. Test with missing API key shows proper error
|
||||
</test_steps>
|
||||
</feature_5>
|
||||
|
||||
<feature_6>
|
||||
<title>Frontend UI Indicator for Internet Access</title>
|
||||
<description>
|
||||
Add visual indicator in the UI to show when Ikario has internet access via Tavily.
|
||||
This can be displayed alongside the existing memory status indicator.
|
||||
|
||||
Implementation:
|
||||
- Add Tavily status indicator in header or sidebar
|
||||
- Show online/offline status for Tavily connection
|
||||
- Optional: Show when Tavily is being used during a conversation
|
||||
- Optional: Add tooltip explaining internet access capabilities
|
||||
|
||||
Visual Design:
|
||||
- Globe or wifi icon to represent internet access
|
||||
- Green when connected, gray when disconnected
|
||||
- Subtle animation when search is in progress
|
||||
- Tooltip: "Internet access via Tavily" or similar
|
||||
|
||||
Integration:
|
||||
- Use existing useMemory hook pattern or create useTavily hook
|
||||
- Poll /api/tavily/status periodically (every 60s)
|
||||
- Update status in real-time during searches
|
||||
</description>
|
||||
<priority>3</priority>
|
||||
<category>frontend</category>
|
||||
<test_steps>
|
||||
1. Verify internet access indicator appears in UI
|
||||
2. Test status updates when Tavily connects/disconnects
|
||||
3. Verify tooltip shows correct information
|
||||
4. Test that indicator shows activity during searches
|
||||
5. Verify status polling doesn't impact performance
|
||||
6. Test with Tavily disabled shows offline status
|
||||
</test_steps>
|
||||
</feature_6>
|
||||
|
||||
<feature_7>
|
||||
<title>Manual Search UI (Optional Enhancement)</title>
|
||||
<description>
|
||||
Optional: Add manual search interface to allow users to trigger Tavily searches directly,
|
||||
similar to the memory search panel.
|
||||
|
||||
Implementation:
|
||||
- Add "Internet Search" panel in sidebar (alongside Memory panel)
|
||||
- Search input for manual Tavily queries
|
||||
- Display search results with title, snippet, URL
|
||||
- Click to insert results into conversation
|
||||
- Filter by search type (general vs news)
|
||||
|
||||
This is OPTIONAL and lower priority. The primary use case is autonomous search by Claude.
|
||||
</description>
|
||||
<priority>4</priority>
|
||||
<category>frontend</category>
|
||||
<test_steps>
|
||||
1. Verify search panel appears in sidebar
|
||||
2. Test manual search returns results
|
||||
3. Verify results display properly with links
|
||||
4. Test inserting results into conversation
|
||||
5. Test news search filter works correctly
|
||||
6. Verify search history is saved (optional)
|
||||
</test_steps>
|
||||
</feature_7>
|
||||
|
||||
<feature_8>
|
||||
<title>Configuration and Settings</title>
|
||||
<description>
|
||||
Add Tavily configuration options to settings and environment.
|
||||
|
||||
Implementation:
|
||||
- Add TAVILY_API_KEY to environment variables
|
||||
- Add Tavily settings to .claude_settings.json or similar config file
|
||||
- Create server/config/tavilyConfig.js for configuration management
|
||||
- Document configuration options in README
|
||||
|
||||
Configuration Options:
|
||||
- API key
|
||||
- Max results per search (default: 5)
|
||||
- Search depth (basic/advanced)
|
||||
- Timeout duration
|
||||
- Enable/disable Tavily globally
|
||||
- Rate limiting settings
|
||||
|
||||
Security:
|
||||
- API key should NOT be exposed to frontend
|
||||
- Use environment variable or secure config file
|
||||
- Validate API key on startup
|
||||
- Log warnings if API key is missing
|
||||
</description>
|
||||
<priority>2</priority>
|
||||
<category>backend</category>
|
||||
<test_steps>
|
||||
1. Verify API key is read from environment variable
|
||||
2. Test fallback to config file if env var not set
|
||||
3. Verify API key validation on startup
|
||||
4. Test configuration options are applied correctly
|
||||
5. Verify API key is never exposed in API responses
|
||||
6. Test enabling/disabling Tavily via config
|
||||
</test_steps>
|
||||
</feature_8>
|
||||
|
||||
<feature_9>
|
||||
<title>Error Handling and Rate Limiting</title>
|
||||
<description>
|
||||
Implement robust error handling and rate limiting for Tavily API calls.
|
||||
|
||||
Implementation:
|
||||
- Detect and handle Tavily API errors (rate limits, invalid API key, etc.)
|
||||
- Implement client-side rate limiting to avoid hitting Tavily limits
|
||||
- Cache search results for duplicate queries (optional)
|
||||
- Provide clear error messages to Claude when searches fail
|
||||
|
||||
Error Types:
|
||||
- 401: Invalid API key
|
||||
- 429: Rate limit exceeded
|
||||
- 500: Tavily server error
|
||||
- Timeout: Search took too long
|
||||
- Network: Connection failed
|
||||
|
||||
Rate Limiting:
|
||||
- Track searches per minute/hour
|
||||
- Queue requests if limit reached
|
||||
- Return cached results for duplicate queries within 5 minutes
|
||||
- Log rate limit warnings
|
||||
</description>
|
||||
<priority>2</priority>
|
||||
<category>backend</category>
|
||||
<test_steps>
|
||||
1. Test error handling for invalid API key
|
||||
2. Verify rate limit detection and handling
|
||||
3. Test timeout handling for slow searches
|
||||
4. Verify error messages are clear to Claude
|
||||
5. Test rate limiting prevents API abuse
|
||||
6. Verify caching works for duplicate queries
|
||||
</test_steps>
|
||||
</feature_9>
|
||||
|
||||
<feature_10>
|
||||
<title>Documentation and README Updates</title>
|
||||
<description>
|
||||
Update project documentation to explain Tavily integration.
|
||||
|
||||
Implementation:
|
||||
- Update main README.md with Tavily setup instructions
|
||||
- Add TAVILY_SETUP.md with detailed configuration guide
|
||||
- Document API endpoints in README
|
||||
- Add examples of using Tavily with Ikario
|
||||
- Document troubleshooting steps
|
||||
|
||||
Documentation Sections:
|
||||
- Prerequisites (Tavily API key)
|
||||
- Installation steps
|
||||
- Configuration options
|
||||
- Testing Tavily connection
|
||||
- Example conversations using internet search
|
||||
- Troubleshooting common issues
|
||||
- API reference for Tavily endpoints
|
||||
</description>
|
||||
<priority>3</priority>
|
||||
<category>documentation</category>
|
||||
<test_steps>
|
||||
1. Verify README has Tavily setup section
|
||||
2. Test that setup instructions are clear and complete
|
||||
3. Verify all configuration options are documented
|
||||
4. Test examples work as described
|
||||
5. Verify troubleshooting section covers common issues
|
||||
</test_steps>
|
||||
</feature_10>
|
||||
</core_features>
|
||||
|
||||
<implementation_notes>
|
||||
<order>
|
||||
Recommended implementation order:
|
||||
1. Feature 1 (MCP Client Setup) - Foundation
|
||||
2. Feature 2 (Tool Configuration) - Core functionality
|
||||
3. Feature 3 (Tool Executor Integration) - Core functionality
|
||||
4. Feature 8 (Configuration) - Required for testing
|
||||
5. Feature 4 (System Prompt) - Makes tools accessible to Claude
|
||||
6. Feature 9 (Error Handling) - Production readiness
|
||||
7. Feature 5 (Status API) - Monitoring
|
||||
8. Feature 10 (Documentation) - User onboarding
|
||||
9. Feature 6 (UI Indicator) - Nice to have
|
||||
10. Feature 7 (Manual Search UI) - Optional enhancement
|
||||
</order>
|
||||
|
||||
<testing>
|
||||
After implementing features 1-5, you should be able to:
|
||||
- Ask Ikario: "Quelle est l'actualité aujourd'hui ?"
|
||||
- Ask Ikario: "Recherche des informations sur [topic actuel]"
|
||||
- Ask Ikario: "Vérifie cette information : [claim]"
|
||||
|
||||
Ikario should autonomously use Tavily search and cite sources.
|
||||
</testing>
|
||||
|
||||
<compatibility>
|
||||
- This specification is fully compatible with existing ikario-memory MCP integration
|
||||
- Ikario will have both memory tools AND internet search tools
|
||||
- Tools can be used together in the same conversation
|
||||
- No conflicts expected between tool systems
|
||||
</compatibility>
|
||||
</implementation_notes>
|
||||
|
||||
<safety_requirements>
|
||||
<critical>
|
||||
- DO NOT expose Tavily API key to frontend or in API responses
|
||||
- DO NOT modify existing MCP memory integration
|
||||
- DO NOT break existing conversation functionality
|
||||
- Tavily should gracefully degrade if unavailable (don't crash the app)
|
||||
- Implement proper rate limiting to avoid API abuse
|
||||
- Validate all user inputs before passing to Tavily
|
||||
- Sanitize search results before displaying (XSS prevention)
|
||||
- Log all Tavily API calls for monitoring and debugging
|
||||
</critical>
|
||||
</safety_requirements>
|
||||
|
||||
<success_metrics>
|
||||
- Ikario can successfully perform internet searches when asked
|
||||
- Search results are relevant and well-formatted
|
||||
- Sources are properly cited
|
||||
- Tavily integration doesn't slow down conversations
|
||||
- Error handling is robust and user-friendly
|
||||
- Configuration is straightforward
|
||||
- Documentation is clear and complete
|
||||
</success_metrics>
|
||||
</project_specification>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,186 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Test direct du backup - utilise append_to_conversation depuis my_project SQLite vers ikario_rag ChromaDB
|
||||
"""
|
||||
|
||||
import sqlite3
|
||||
import sys
|
||||
import os
|
||||
|
||||
# Ajouter le chemin vers ikario_rag
|
||||
sys.path.insert(0, 'C:/Users/david/SynologyDrive/ikario/ikario_rag')
|
||||
|
||||
from mcp_ikario_memory import IkarioMemoryMCP
|
||||
import asyncio
|
||||
from datetime import datetime
|
||||
|
||||
async def test_backup():
|
||||
print("=" * 80)
|
||||
print("TEST BACKUP CONVERSATION - PYTHON DIRECT")
|
||||
print("=" * 80)
|
||||
print()
|
||||
|
||||
# Connexion à la base SQLite de my_project
|
||||
db_path = "C:/GitHub/Linear_coding/generations/my_project/server/data/claude-clone.db"
|
||||
conn = sqlite3.connect(db_path)
|
||||
cursor = conn.cursor()
|
||||
|
||||
# Trouver la conversation "test tes mémoires"
|
||||
cursor.execute("""
|
||||
SELECT id, title, message_count, is_pinned, has_memory_backup, created_at
|
||||
FROM conversations
|
||||
WHERE title LIKE '%test tes mémoires%'
|
||||
LIMIT 1
|
||||
""")
|
||||
|
||||
conv = cursor.fetchone()
|
||||
|
||||
if not conv:
|
||||
print("ERROR: Conversation 'test tes mémoires' not found")
|
||||
return
|
||||
|
||||
conv_id, title, msg_count, is_pinned, has_backup, created_at = conv
|
||||
|
||||
print(f"FOUND: '{title}'")
|
||||
print(f"ID: {conv_id}")
|
||||
print(f"Messages: {msg_count}")
|
||||
print(f"Pinned: {'Yes' if is_pinned else 'No'}")
|
||||
print(f"Already backed up: {'Yes' if has_backup else 'No'}")
|
||||
print(f"Created: {created_at}")
|
||||
print("=" * 80)
|
||||
print()
|
||||
|
||||
# Récupérer TOUS les messages COMPLETS
|
||||
cursor.execute("""
|
||||
SELECT role, content, thinking_content, created_at
|
||||
FROM messages
|
||||
WHERE conversation_id = ?
|
||||
ORDER BY created_at ASC
|
||||
""", (conv_id,))
|
||||
|
||||
messages = cursor.fetchall()
|
||||
|
||||
print(f"Retrieved {len(messages)} messages from SQLite:")
|
||||
print()
|
||||
|
||||
total_chars = 0
|
||||
formatted_messages = []
|
||||
|
||||
for i, (role, content, thinking, msg_created_at) in enumerate(messages, 1):
|
||||
char_len = len(content)
|
||||
total_chars += char_len
|
||||
|
||||
thinking_note = " [+ thinking]" if thinking else ""
|
||||
print(f" {i}. {role}: {char_len} chars{thinking_note}")
|
||||
|
||||
# Formater pour MCP append_to_conversation
|
||||
msg = {
|
||||
"author": role,
|
||||
"content": content, # COMPLET, pas de truncation!
|
||||
"timestamp": msg_created_at or datetime.now().isoformat()
|
||||
}
|
||||
|
||||
# Ajouter thinking si présent
|
||||
if thinking:
|
||||
msg["thinking"] = thinking
|
||||
|
||||
formatted_messages.append(msg)
|
||||
|
||||
total_words = total_chars // 5
|
||||
print(f"\nTotal: {total_chars} chars (~{total_words} words)")
|
||||
print()
|
||||
|
||||
# Calcul couverture
|
||||
old_coverage = min(100, (256 * 4 / total_chars) * 100)
|
||||
new_coverage = min(100, (8192 * 4 / total_chars) * 100)
|
||||
|
||||
print("Embedding coverage estimation:")
|
||||
print(f" OLD (all-MiniLM-L6-v2, 256 tokens): {old_coverage:.1f}%")
|
||||
print(f" NEW (BAAI/bge-m3, 8192 tokens): {new_coverage:.1f}%")
|
||||
print(f" Improvement: +{(new_coverage - old_coverage):.1f}%")
|
||||
print()
|
||||
|
||||
# Initialiser Ikario Memory MCP
|
||||
print("Initializing Ikario RAG (ChromaDB + BAAI/bge-m3)...")
|
||||
ikario_db_path = "C:/Users/david/SynologyDrive/ikario/ikario_rag/index"
|
||||
memory = IkarioMemoryMCP(db_path=ikario_db_path)
|
||||
print("OK Ikario Memory initialized")
|
||||
print()
|
||||
|
||||
# Préparer les participants et le contexte
|
||||
participants = ["user", "assistant"]
|
||||
|
||||
context = {
|
||||
"category": "fondatrice" if is_pinned else "thematique",
|
||||
"tags": ["test", "mémoire", "conversation"],
|
||||
"summary": f"{title} ({msg_count} messages)",
|
||||
"date": created_at,
|
||||
"title": title,
|
||||
"key_insights": []
|
||||
}
|
||||
|
||||
print("Starting backup with append_to_conversation...")
|
||||
print(f" - Conversation ID: {conv_id}")
|
||||
print(f" - Messages: {len(formatted_messages)} COMPLETE messages")
|
||||
print(f" - Participants: {participants}")
|
||||
print(f" - Category: {context['category']}")
|
||||
print()
|
||||
|
||||
try:
|
||||
# Appeler append_to_conversation (auto-create si n'existe pas)
|
||||
result = await memory.append_to_conversation(
|
||||
conversation_id=conv_id,
|
||||
new_messages=formatted_messages,
|
||||
participants=participants,
|
||||
context=context
|
||||
)
|
||||
|
||||
print("=" * 80)
|
||||
print("BACKUP RESULT:")
|
||||
print("=" * 80)
|
||||
print(f"Status: {result}")
|
||||
print()
|
||||
|
||||
if "updated" in result or "ajoutée" in result or "added" in result.lower():
|
||||
print("SUCCESS! Conversation backed up to ChromaDB")
|
||||
print()
|
||||
print("What was saved:")
|
||||
print(f" - {len(formatted_messages)} COMPLETE messages (no truncation!)")
|
||||
print(f" - Each message has its own embedding (BAAI/bge-m3)")
|
||||
print(f" - Max tokens per message: 8192 (vs 256 old)")
|
||||
print(f" - Category: {context['category']}")
|
||||
print()
|
||||
print("ChromaDB structure created:")
|
||||
print(f" - 1 document principal (full conversation)")
|
||||
print(f" - {len(formatted_messages)} documents individuels (one per message)")
|
||||
print(f" - Total: {len(formatted_messages) + 1} documents with embeddings")
|
||||
print()
|
||||
|
||||
# Marquer comme backupé dans SQLite
|
||||
cursor.execute("""
|
||||
UPDATE conversations
|
||||
SET has_memory_backup = 1
|
||||
WHERE id = ?
|
||||
""", (conv_id,))
|
||||
conn.commit()
|
||||
print("✓ Marked as backed up in SQLite")
|
||||
|
||||
else:
|
||||
print("WARNING: Unexpected result format")
|
||||
|
||||
except Exception as e:
|
||||
print(f"ERROR during backup: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
print()
|
||||
print("=" * 80)
|
||||
print("TEST COMPLETED")
|
||||
print("=" * 80)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(test_backup())
|
||||
290
test_security.py
290
test_security.py
@@ -1,290 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Security Hook Tests
|
||||
===================
|
||||
|
||||
Tests for the bash command security validation logic.
|
||||
Run with: python test_security.py
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
import sys
|
||||
|
||||
from security import (
|
||||
bash_security_hook,
|
||||
extract_commands,
|
||||
validate_chmod_command,
|
||||
validate_init_script,
|
||||
)
|
||||
|
||||
|
||||
def test_hook(command: str, should_block: bool) -> bool:
|
||||
"""Test a single command against the security hook."""
|
||||
input_data = {"tool_name": "Bash", "tool_input": {"command": command}}
|
||||
result = asyncio.run(bash_security_hook(input_data))
|
||||
was_blocked = result.get("decision") == "block"
|
||||
|
||||
if was_blocked == should_block:
|
||||
status = "PASS"
|
||||
else:
|
||||
status = "FAIL"
|
||||
expected = "blocked" if should_block else "allowed"
|
||||
actual = "blocked" if was_blocked else "allowed"
|
||||
reason = result.get("reason", "")
|
||||
print(f" {status}: {command!r}")
|
||||
print(f" Expected: {expected}, Got: {actual}")
|
||||
if reason:
|
||||
print(f" Reason: {reason}")
|
||||
return False
|
||||
|
||||
print(f" {status}: {command!r}")
|
||||
return True
|
||||
|
||||
|
||||
def test_extract_commands():
|
||||
"""Test the command extraction logic."""
|
||||
print("\nTesting command extraction:\n")
|
||||
passed = 0
|
||||
failed = 0
|
||||
|
||||
test_cases = [
|
||||
("ls -la", ["ls"]),
|
||||
("npm install && npm run build", ["npm", "npm"]),
|
||||
("cat file.txt | grep pattern", ["cat", "grep"]),
|
||||
("/usr/bin/node script.js", ["node"]),
|
||||
("VAR=value ls", ["ls"]),
|
||||
("git status || git init", ["git", "git"]),
|
||||
]
|
||||
|
||||
for cmd, expected in test_cases:
|
||||
result = extract_commands(cmd)
|
||||
if result == expected:
|
||||
print(f" PASS: {cmd!r} -> {result}")
|
||||
passed += 1
|
||||
else:
|
||||
print(f" FAIL: {cmd!r}")
|
||||
print(f" Expected: {expected}, Got: {result}")
|
||||
failed += 1
|
||||
|
||||
return passed, failed
|
||||
|
||||
|
||||
def test_validate_chmod():
|
||||
"""Test chmod command validation."""
|
||||
print("\nTesting chmod validation:\n")
|
||||
passed = 0
|
||||
failed = 0
|
||||
|
||||
# Test cases: (command, should_be_allowed, description)
|
||||
test_cases = [
|
||||
# Allowed cases
|
||||
("chmod +x init.sh", True, "basic +x"),
|
||||
("chmod +x script.sh", True, "+x on any script"),
|
||||
("chmod u+x init.sh", True, "user +x"),
|
||||
("chmod a+x init.sh", True, "all +x"),
|
||||
("chmod ug+x init.sh", True, "user+group +x"),
|
||||
("chmod +x file1.sh file2.sh", True, "multiple files"),
|
||||
# Blocked cases
|
||||
("chmod 777 init.sh", False, "numeric mode"),
|
||||
("chmod 755 init.sh", False, "numeric mode 755"),
|
||||
("chmod +w init.sh", False, "write permission"),
|
||||
("chmod +r init.sh", False, "read permission"),
|
||||
("chmod -x init.sh", False, "remove execute"),
|
||||
("chmod -R +x dir/", False, "recursive flag"),
|
||||
("chmod --recursive +x dir/", False, "long recursive flag"),
|
||||
("chmod +x", False, "missing file"),
|
||||
]
|
||||
|
||||
for cmd, should_allow, description in test_cases:
|
||||
allowed, reason = validate_chmod_command(cmd)
|
||||
if allowed == should_allow:
|
||||
print(f" PASS: {cmd!r} ({description})")
|
||||
passed += 1
|
||||
else:
|
||||
expected = "allowed" if should_allow else "blocked"
|
||||
actual = "allowed" if allowed else "blocked"
|
||||
print(f" FAIL: {cmd!r} ({description})")
|
||||
print(f" Expected: {expected}, Got: {actual}")
|
||||
if reason:
|
||||
print(f" Reason: {reason}")
|
||||
failed += 1
|
||||
|
||||
return passed, failed
|
||||
|
||||
|
||||
def test_validate_init_script():
|
||||
"""Test init.sh script execution validation."""
|
||||
print("\nTesting init.sh validation:\n")
|
||||
passed = 0
|
||||
failed = 0
|
||||
|
||||
# Test cases: (command, should_be_allowed, description)
|
||||
test_cases = [
|
||||
# Allowed cases
|
||||
("./init.sh", True, "basic ./init.sh"),
|
||||
("./init.sh arg1 arg2", True, "with arguments"),
|
||||
("/path/to/init.sh", True, "absolute path"),
|
||||
("../dir/init.sh", True, "relative path with init.sh"),
|
||||
# Blocked cases
|
||||
("./setup.sh", False, "different script name"),
|
||||
("./init.py", False, "python script"),
|
||||
("bash init.sh", False, "bash invocation"),
|
||||
("sh init.sh", False, "sh invocation"),
|
||||
("./malicious.sh", False, "malicious script"),
|
||||
("./init.sh; rm -rf /", False, "command injection attempt"),
|
||||
]
|
||||
|
||||
for cmd, should_allow, description in test_cases:
|
||||
allowed, reason = validate_init_script(cmd)
|
||||
if allowed == should_allow:
|
||||
print(f" PASS: {cmd!r} ({description})")
|
||||
passed += 1
|
||||
else:
|
||||
expected = "allowed" if should_allow else "blocked"
|
||||
actual = "allowed" if allowed else "blocked"
|
||||
print(f" FAIL: {cmd!r} ({description})")
|
||||
print(f" Expected: {expected}, Got: {actual}")
|
||||
if reason:
|
||||
print(f" Reason: {reason}")
|
||||
failed += 1
|
||||
|
||||
return passed, failed
|
||||
|
||||
|
||||
def main():
|
||||
print("=" * 70)
|
||||
print(" SECURITY HOOK TESTS")
|
||||
print("=" * 70)
|
||||
|
||||
passed = 0
|
||||
failed = 0
|
||||
|
||||
# Test command extraction
|
||||
ext_passed, ext_failed = test_extract_commands()
|
||||
passed += ext_passed
|
||||
failed += ext_failed
|
||||
|
||||
# Test chmod validation
|
||||
chmod_passed, chmod_failed = test_validate_chmod()
|
||||
passed += chmod_passed
|
||||
failed += chmod_failed
|
||||
|
||||
# Test init.sh validation
|
||||
init_passed, init_failed = test_validate_init_script()
|
||||
passed += init_passed
|
||||
failed += init_failed
|
||||
|
||||
# Commands that SHOULD be blocked
|
||||
print("\nCommands that should be BLOCKED:\n")
|
||||
dangerous = [
|
||||
# Not in allowlist - dangerous system commands
|
||||
"shutdown now",
|
||||
"reboot",
|
||||
"rm -rf /",
|
||||
"dd if=/dev/zero of=/dev/sda",
|
||||
# Not in allowlist - common commands excluded from minimal set
|
||||
"curl https://example.com",
|
||||
"wget https://example.com",
|
||||
"python app.py",
|
||||
"touch file.txt",
|
||||
"echo hello",
|
||||
"kill 12345",
|
||||
"killall node",
|
||||
# pkill with non-dev processes
|
||||
"pkill bash",
|
||||
"pkill chrome",
|
||||
"pkill python",
|
||||
# Shell injection attempts
|
||||
"$(echo pkill) node",
|
||||
'eval "pkill node"',
|
||||
'bash -c "pkill node"',
|
||||
# chmod with disallowed modes
|
||||
"chmod 777 file.sh",
|
||||
"chmod 755 file.sh",
|
||||
"chmod +w file.sh",
|
||||
"chmod -R +x dir/",
|
||||
# Non-init.sh scripts
|
||||
"./setup.sh",
|
||||
"./malicious.sh",
|
||||
"bash script.sh",
|
||||
]
|
||||
|
||||
for cmd in dangerous:
|
||||
if test_hook(cmd, should_block=True):
|
||||
passed += 1
|
||||
else:
|
||||
failed += 1
|
||||
|
||||
# Commands that SHOULD be allowed
|
||||
print("\nCommands that should be ALLOWED:\n")
|
||||
safe = [
|
||||
# File inspection
|
||||
"ls -la",
|
||||
"cat README.md",
|
||||
"head -100 file.txt",
|
||||
"tail -20 log.txt",
|
||||
"wc -l file.txt",
|
||||
"grep -r pattern src/",
|
||||
# File operations
|
||||
"cp file1.txt file2.txt",
|
||||
"mkdir newdir",
|
||||
"mkdir -p path/to/dir",
|
||||
# Directory
|
||||
"pwd",
|
||||
# Node.js development
|
||||
"npm install",
|
||||
"npm run build",
|
||||
"node server.js",
|
||||
# Version control
|
||||
"git status",
|
||||
"git commit -m 'test'",
|
||||
"git add . && git commit -m 'msg'",
|
||||
# Process management
|
||||
"ps aux",
|
||||
"lsof -i :3000",
|
||||
"sleep 2",
|
||||
# Allowed pkill patterns for dev servers
|
||||
"pkill node",
|
||||
"pkill npm",
|
||||
"pkill -f node",
|
||||
"pkill -f 'node server.js'",
|
||||
"pkill vite",
|
||||
# Chained commands
|
||||
"npm install && npm run build",
|
||||
"ls | grep test",
|
||||
# Full paths
|
||||
"/usr/local/bin/node app.js",
|
||||
# chmod +x (allowed)
|
||||
"chmod +x init.sh",
|
||||
"chmod +x script.sh",
|
||||
"chmod u+x init.sh",
|
||||
"chmod a+x init.sh",
|
||||
# init.sh execution (allowed)
|
||||
"./init.sh",
|
||||
"./init.sh --production",
|
||||
"/path/to/init.sh",
|
||||
# Combined chmod and init.sh
|
||||
"chmod +x init.sh && ./init.sh",
|
||||
]
|
||||
|
||||
for cmd in safe:
|
||||
if test_hook(cmd, should_block=False):
|
||||
passed += 1
|
||||
else:
|
||||
failed += 1
|
||||
|
||||
# Summary
|
||||
print("\n" + "-" * 70)
|
||||
print(f" Results: {passed} passed, {failed} failed")
|
||||
print("-" * 70)
|
||||
|
||||
if failed == 0:
|
||||
print("\n ALL TESTS PASSED")
|
||||
return 0
|
||||
else:
|
||||
print(f"\n {failed} TEST(S) FAILED")
|
||||
return 1
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Reference in New Issue
Block a user