Some checks failed
Deploy to Production / Build and Deploy (push) Failing after 1m7s
Replaced ~100+ hardcoded French and English text strings across 30+ components with proper i18n t() calls. Added 57 new translation keys to all 15 locale files (ar, de, en, es, fa, fr, hi, it, ja, ko, nl, pl, pt, ru, zh). Key changes: - contextual-ai-chat.tsx: 30 French strings → t() (actions, toasts, labels, placeholders) - ai-chat.tsx: 15 French/English strings → t() (header, tabs, welcome, insights, history) - note-inline-editor.tsx: 20 French fallbacks removed (toolbar, save status, checklist) - lab-skeleton.tsx: French loading text → t() - admin-header.tsx, header.tsx, editor-connections-section.tsx: French fallbacks removed - New AI chat component, agent cards, sidebar, settings panel i18n cleanup Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
120 lines
4.6 KiB
TypeScript
120 lines
4.6 KiB
TypeScript
import { NextRequest, NextResponse } from 'next/server'
|
|
import { getTagsProvider } from '@/lib/ai/factory'
|
|
import { getSystemConfig } from '@/lib/config'
|
|
import { auth } from '@/auth'
|
|
import { getAISettings } from '@/app/actions/ai-settings'
|
|
import { z } from 'zod'
|
|
|
|
const requestSchema = z.object({
|
|
content: z.string().min(1, "Le contenu ne peut pas être vide"),
|
|
})
|
|
|
|
export async function POST(req: NextRequest) {
|
|
try {
|
|
// Check authentication and user setting
|
|
const session = await auth()
|
|
if (session?.user?.id) {
|
|
const settings = await getAISettings(session.user.id)
|
|
if (settings.titleSuggestions === false) {
|
|
return NextResponse.json({ suggestions: [] })
|
|
}
|
|
}
|
|
|
|
|
|
const body = await req.json()
|
|
const { content } = requestSchema.parse(body)
|
|
|
|
// Vérifier qu'il y a au moins 10 mots
|
|
const wordCount = content.split(/\s+/).length
|
|
|
|
if (wordCount < 10) {
|
|
return NextResponse.json(
|
|
{ error: 'Le contenu doit avoir au moins 10 mots' },
|
|
{ status: 400 }
|
|
)
|
|
}
|
|
|
|
const config = await getSystemConfig()
|
|
const provider = getTagsProvider(config)
|
|
|
|
// Détecter la langue du contenu (simple détection basée sur les caractères et mots)
|
|
const hasNonLatinChars = /[\u0400-\u04FF\u0600-\u06FF\u4E00-\u9FFF\u0E00-\u0E7F]/.test(content)
|
|
const isPersian = /[\u0600-\u06FF]/.test(content)
|
|
const isChinese = /[\u4E00-\u9FFF]/.test(content)
|
|
const isRussian = /[\u0400-\u04FF]/.test(content)
|
|
const isArabic = /[\u0600-\u06FF]/.test(content)
|
|
|
|
// Détection du français par des mots et caractères caractéristiques
|
|
const frenchWords = /\b(le|la|les|un|une|des|et|ou|mais|donc|pour|dans|sur|avec|sans|très|plus|moins|tout|tous|toute|toutes|ce|cette|ces|mon|ma|mes|ton|ta|tes|son|sa|ses|notre|nos|votre|vos|leur|leurs|je|tu|il|elle|nous|vous|ils|elles|est|sont|été|être|avoir|faire|aller|venir|voir|savoir|pouvoir|vouloir|falloir|comme|que|qui|dont|où|quand|pourquoi|comment|quel|quelle|quels|quelles)\b/i
|
|
const frenchAccents = /[éèêàâôûùïüç]/i
|
|
const isFrench = frenchWords.test(content) || frenchAccents.test(content)
|
|
|
|
// Déterminer la langue du prompt système
|
|
let promptLanguage = 'en'
|
|
let responseLanguage = 'English'
|
|
|
|
if (isFrench) {
|
|
promptLanguage = 'fr' // Français
|
|
responseLanguage = 'French'
|
|
} else if (isPersian) {
|
|
promptLanguage = 'fa' // Persan
|
|
responseLanguage = 'Persian'
|
|
} else if (isChinese) {
|
|
promptLanguage = 'zh' // Chinois
|
|
responseLanguage = 'Chinese'
|
|
} else if (isRussian) {
|
|
promptLanguage = 'ru' // Russe
|
|
responseLanguage = 'Russian'
|
|
} else if (isArabic) {
|
|
promptLanguage = 'ar' // Arabe
|
|
responseLanguage = 'Arabic'
|
|
}
|
|
|
|
// Générer des titres appropriés basés sur le contenu
|
|
const titlePrompt = promptLanguage === 'en'
|
|
? `You are a title generator. Generate 3 concise, descriptive titles for the following content.
|
|
|
|
IMPORTANT INSTRUCTIONS:
|
|
- Use ONLY the content provided below between the CONTENT_START and CONTENT_END markers
|
|
- Do NOT use any external knowledge or training data
|
|
- Focus on the main topics and themes in THIS SPECIFIC content
|
|
- Be specific to what is actually discussed
|
|
|
|
CONTENT_START: ${content.substring(0, 500)} CONTENT_END
|
|
|
|
Respond ONLY with a JSON array: [{"title": "title1", "confidence": 0.95}, {"title": "title2", "confidence": 0.85}, {"title": "title3", "confidence": 0.75}]`
|
|
: `Tu es un générateur de titres. Génère 3 titres concis et descriptifs pour le contenu suivant en ${responseLanguage}.
|
|
|
|
INSTRUCTIONS IMPORTANTES :
|
|
- Utilise SEULEMENT le contenu fourni entre les marqueurs CONTENT_START et CONTENT_END
|
|
- N'utilise AUCUNE connaissance externe ou données d'entraînement
|
|
- Concentre-toi sur les sujets principaux et thèmes de CE CONTENU SPÉCIFIQUE
|
|
- Sois spécifique à ce qui est réellement discuté
|
|
|
|
CONTENT_START: ${content.substring(0, 500)} CONTENT_END
|
|
|
|
Réponds SEULEMENT avec un tableau JSON: [{"title": "titre1", "confidence": 0.95}, {"title": "titre2", "confidence": 0.85}, {"title": "titre3", "confidence": 0.75}]`
|
|
|
|
const titles = await provider.generateTitles(titlePrompt)
|
|
|
|
// Créer les suggestions
|
|
const suggestions = titles.map((t: any) => ({
|
|
title: t.title,
|
|
confidence: Math.round(t.confidence * 100),
|
|
reasoning: `Basé sur le contenu`
|
|
}))
|
|
|
|
return NextResponse.json({ suggestions })
|
|
} catch (error: any) {
|
|
|
|
if (error instanceof z.ZodError) {
|
|
return NextResponse.json({ error: error.issues }, { status: 400 })
|
|
}
|
|
|
|
return NextResponse.json(
|
|
{ error: error.message || 'Erreur lors de la génération des titres' },
|
|
{ status: 500 }
|
|
)
|
|
}
|
|
}
|