confluent/ConfluentTranslator/server.js
StillHammer 6fe6c7867e Ajout onglet Lexique + structure JSON modulaire
- Ajout onglet "Lexique" dans ConfluentTranslator
  - Recherche en temps réel à chaque lettre tapée
  - Sélecteur Proto/Ancien Confluent
  - Affichage français → confluent avec compteur
  - Endpoint /lexique dans server.js

- Structure modulaire lexique-ancien/ (21 fichiers)
  - Format ultra-flexible : normalisation FR, multi-traductions, métadonnées
  - 20 domaines thématiques (castes, lieux, émotions, actions...)
  - ~500-600 mots à remplir (listés en commentaire _mots_a_gerer)

- Structure modulaire lexique-proto/ (6 fichiers)
  - Racines monosyllabiques primitives
  - ~150-200 racines à remplir
  - README explicatif des différences Proto/Ancien

Format JSON supporte :
- Synonymes FR (chevaux → cheval)
- Plusieurs traductions CF par mot FR
- Compositions avec racines + sens littéral
- Évolution Proto → Ancien

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-27 12:52:07 +08:00

93 lines
2.5 KiB
JavaScript

require('dotenv').config({ path: '../.env' });
const express = require('express');
const path = require('path');
const fs = require('fs');
const { Anthropic } = require('@anthropic-ai/sdk');
const OpenAI = require('openai');
const app = express();
const PORT = 3000;
app.use(express.json());
app.use(express.static('public'));
// Load prompts
const protoPrompt = fs.readFileSync(path.join(__dirname, 'prompts', 'proto-system.txt'), 'utf-8');
const ancienPrompt = fs.readFileSync(path.join(__dirname, 'prompts', 'ancien-system.txt'), 'utf-8');
// Load lexique
const lexiquePath = path.join(__dirname, '..', 'data', 'lexique-francais-confluent.json');
let lexiqueData = null;
try {
lexiqueData = JSON.parse(fs.readFileSync(lexiquePath, 'utf-8'));
} catch (error) {
console.error('Error loading lexique:', error.message);
}
// Lexique endpoint
app.get('/lexique', (req, res) => {
if (!lexiqueData) {
return res.status(500).json({ error: 'Lexique not loaded' });
}
res.json(lexiqueData);
});
// Translation endpoint
app.post('/translate', async (req, res) => {
const { text, target, provider, model } = req.body;
if (!text || !target || !provider || !model) {
return res.status(400).json({ error: 'Missing parameters' });
}
const systemPrompt = target === 'proto' ? protoPrompt : ancienPrompt;
try {
let translation;
if (provider === 'anthropic') {
const anthropic = new Anthropic({
apiKey: process.env.ANTHROPIC_API_KEY,
});
const message = await anthropic.messages.create({
model: model,
max_tokens: 1024,
system: systemPrompt,
messages: [
{ role: 'user', content: text }
]
});
translation = message.content[0].text;
} else if (provider === 'openai') {
const openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
});
const completion = await openai.chat.completions.create({
model: model,
messages: [
{ role: 'system', content: systemPrompt },
{ role: 'user', content: text }
]
});
translation = completion.choices[0].message.content;
} else {
return res.status(400).json({ error: 'Unknown provider' });
}
res.json({ translation });
} catch (error) {
console.error('Translation error:', error);
res.status(500).json({ error: error.message });
}
});
app.listen(PORT, () => {
console.log(`ConfluentTranslator running on http://localhost:${PORT}`);
});