feat(media): Phase 8.G noeuds-ecoles + popup RAG info + lien Bonpote + migration Nebius
- CartePensees: noeuds ecole visibles (cercles proportionnels count auteurs, cliquables, emit select-ecole) - CartePensees: collision D3 ajustee pour repulsion auteurs autour des noeuds ecole - FicheEcole: nouveau composant modal (liste auteurs ingeres/non-ingeres, interroger RAG) - media: header lien Bonpote V2 cliquable + bouton i info RAG - media: popup FRACAS (description RAG, 662 dimensions, 3 couches, localStorage 1ere visite) - media: FicheEcole branchee (select-ecole, select-auteur-from-ecole, interroger-ecole) - ChatbotPensees: suppression mention corpusCount hardcoded (double source de verite) - chatbot, chatbot-v2, chatbot-reseaux, chatbot-taff: migration Mistral -> Nebius DeepSeek-V3.2 - nuxt.config: ajout nebiusApiKey runtime config Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -82,18 +82,18 @@ export default defineEventHandler(async (event) => {
|
||||
|
||||
const systemPrompt = SYSTEM_PROMPT.replace('{{STRUCTURES_JSON}}', JSON.stringify(context, null, 0))
|
||||
|
||||
const mistralApiKey = config.mistralApiKey as string
|
||||
if (!mistralApiKey) throw createError({ statusCode: 500, message: 'Clé API Mistral manquante.' })
|
||||
const nebiusApiKey = config.nebiusApiKey as string
|
||||
if (!nebiusApiKey) throw createError({ statusCode: 500, message: 'Clé API Nebius manquante.' })
|
||||
|
||||
let mistralRaw: string
|
||||
try {
|
||||
const res = await $fetch<{ choices: { message: { content: string } }[] }>(
|
||||
'https://api.mistral.ai/v1/chat/completions',
|
||||
'https://api.tokenfactory.nebius.com/v1/chat/completions',
|
||||
{
|
||||
method: 'POST',
|
||||
headers: { Authorization: `Bearer ${mistralApiKey}`, 'Content-Type': 'application/json' },
|
||||
headers: { Authorization: `Bearer ${nebiusApiKey}`, 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
model: 'mistral-small-latest',
|
||||
model: 'deepseek-ai/DeepSeek-V3.2',
|
||||
temperature: 0.3,
|
||||
max_tokens: 700,
|
||||
response_format: { type: 'json_object' },
|
||||
|
||||
@@ -91,20 +91,20 @@ export default defineEventHandler(async (event) => {
|
||||
|
||||
const systemPrompt = SYSTEM_PROMPT.replace('{{PLATEFORMES_JSON}}', JSON.stringify(context, null, 0))
|
||||
|
||||
const mistralApiKey = config.mistralApiKey as string
|
||||
if (!mistralApiKey) {
|
||||
throw createError({ statusCode: 500, statusMessage: 'Clé API Mistral manquante.' })
|
||||
const nebiusApiKey = config.nebiusApiKey as string
|
||||
if (!nebiusApiKey) {
|
||||
throw createError({ statusCode: 500, statusMessage: 'Clé API Nebius manquante.' })
|
||||
}
|
||||
|
||||
let mistralRaw: string
|
||||
try {
|
||||
const res = await $fetch<{ choices: { message: { content: string } }[] }>(
|
||||
'https://api.mistral.ai/v1/chat/completions',
|
||||
'https://api.tokenfactory.nebius.com/v1/chat/completions',
|
||||
{
|
||||
method: 'POST',
|
||||
headers: { Authorization: `Bearer ${mistralApiKey}`, 'Content-Type': 'application/json' },
|
||||
headers: { Authorization: `Bearer ${nebiusApiKey}`, 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
model: 'mistral-small-latest',
|
||||
model: 'deepseek-ai/DeepSeek-V3.2',
|
||||
temperature: 0.3,
|
||||
max_tokens: 700,
|
||||
response_format: { type: 'json_object' },
|
||||
|
||||
@@ -145,19 +145,22 @@ export default defineEventHandler(async (event) => {
|
||||
|
||||
const systemPrompt = SYSTEM_PROMPT_V2.replace('{{CONTEXTE_RAG}}', contextStr)
|
||||
|
||||
// 7. Mistral Small - génération réponse
|
||||
// 7. Nebius DeepSeek-V3.2 - génération réponse
|
||||
const nebiusApiKey = config.nebiusApiKey as string
|
||||
if (!nebiusApiKey) throw createError({ statusCode: 500, statusMessage: 'Clé API Nebius manquante.' })
|
||||
|
||||
let mistralRaw: string
|
||||
try {
|
||||
const mistralRes = await $fetch<{
|
||||
const nebiusRes = await $fetch<{
|
||||
choices: { message: { content: string } }[]
|
||||
}>('https://api.mistral.ai/v1/chat/completions', {
|
||||
}>('https://api.tokenfactory.nebius.com/v1/chat/completions', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Authorization: `Bearer ${mistralApiKey}`,
|
||||
Authorization: `Bearer ${nebiusApiKey}`,
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
model: 'mistral-small-latest',
|
||||
model: 'deepseek-ai/DeepSeek-V3.2',
|
||||
temperature: 0.3,
|
||||
max_tokens: 600,
|
||||
response_format: { type: 'json_object' },
|
||||
@@ -167,10 +170,10 @@ export default defineEventHandler(async (event) => {
|
||||
]
|
||||
})
|
||||
})
|
||||
mistralRaw = mistralRes.choices?.[0]?.message?.content ?? '{}'
|
||||
mistralRaw = nebiusRes.choices?.[0]?.message?.content ?? '{}'
|
||||
} catch (e: any) {
|
||||
console.error('[chatbot-v2] Erreur Mistral Small :', e?.message ?? e)
|
||||
throw createError({ statusCode: 502, statusMessage: 'Erreur appel Mistral Small.' })
|
||||
console.error('[chatbot-v2] Erreur Nebius DeepSeek :', e?.message ?? e)
|
||||
throw createError({ statusCode: 502, statusMessage: 'Erreur appel Nebius DeepSeek.' })
|
||||
}
|
||||
|
||||
// 8. Parse JSON
|
||||
|
||||
@@ -247,13 +247,13 @@ export default defineEventHandler(async (event) => {
|
||||
JSON.stringify(fichesContext, null, 0),
|
||||
)
|
||||
|
||||
// 6. Appel Mistral Small
|
||||
const mistralApiKey = config.mistralApiKey as string
|
||||
// 6. Appel Nebius DeepSeek-V3.2
|
||||
const nebiusApiKey = config.nebiusApiKey as string
|
||||
|
||||
if (!mistralApiKey) {
|
||||
if (!nebiusApiKey) {
|
||||
throw createError({
|
||||
statusCode: 500,
|
||||
statusMessage: 'Clé API Mistral manquante.',
|
||||
statusMessage: 'Clé API Nebius manquante.',
|
||||
})
|
||||
}
|
||||
|
||||
@@ -262,17 +262,17 @@ export default defineEventHandler(async (event) => {
|
||||
let tokensOut = 0
|
||||
|
||||
try {
|
||||
const mistralRes = await $fetch<{
|
||||
const nebiusRes = await $fetch<{
|
||||
choices: { message: { content: string } }[]
|
||||
usage?: { prompt_tokens: number; completion_tokens: number }
|
||||
}>('https://api.mistral.ai/v1/chat/completions', {
|
||||
}>('https://api.tokenfactory.nebius.com/v1/chat/completions', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Authorization: `Bearer ${mistralApiKey}`,
|
||||
Authorization: `Bearer ${nebiusApiKey}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
model: 'mistral-small-latest',
|
||||
model: 'deepseek-ai/DeepSeek-V3.2',
|
||||
temperature: 0.3,
|
||||
max_tokens: 600,
|
||||
response_format: { type: 'json_object' },
|
||||
@@ -283,11 +283,11 @@ export default defineEventHandler(async (event) => {
|
||||
}),
|
||||
})
|
||||
|
||||
mistralRaw = mistralRes.choices?.[0]?.message?.content ?? '{}'
|
||||
tokensIn = mistralRes.usage?.prompt_tokens ?? 0
|
||||
tokensOut = mistralRes.usage?.completion_tokens ?? 0
|
||||
mistralRaw = nebiusRes.choices?.[0]?.message?.content ?? '{}'
|
||||
tokensIn = nebiusRes.usage?.prompt_tokens ?? 0
|
||||
tokensOut = nebiusRes.usage?.completion_tokens ?? 0
|
||||
} catch (e: any) {
|
||||
console.error('[chatbot] Erreur Mistral Small:', e?.message ?? e)
|
||||
console.error('[chatbot] Erreur Nebius DeepSeek:', e?.message ?? e)
|
||||
throw createError({
|
||||
statusCode: 502,
|
||||
statusMessage: 'Erreur appel IA — réessaie dans quelques instants.',
|
||||
|
||||
Reference in New Issue
Block a user