Some checks failed
Deploy to Production / Build and Deploy (push) Failing after 3s
- Nouveau endpoint POST /api/agents/run-for-note : crée un agent one-shot (slide-generator ou excalidraw-generator) avec la note courante comme source et l'exécute immédiatement - ContextualAIChat : prop noteId + section "Générer depuis cette note" avec deux boutons gradient (violet=slides, cyan=diagramme), spinner pendant la génération, bouton de téléchargement .pptx ou lien "Ouvrir dans le Lab" après succès - note-editor.tsx : passage de note.id à ContextualAIChat - i18n fr/en : nouvelles clés ai.generate.* Co-authored-by: Cursor <cursoragent@cursor.com>
87 lines
2.6 KiB
TypeScript
87 lines
2.6 KiB
TypeScript
import { NextRequest, NextResponse } from 'next/server'
|
|
import { auth } from '@/lib/auth'
|
|
import { prisma } from '@/lib/prisma'
|
|
|
|
type GenerateType = 'slide-generator' | 'excalidraw-generator'
|
|
|
|
const TYPE_DEFAULTS: Record<GenerateType, {
|
|
role: string
|
|
tools: string[]
|
|
maxSteps: number
|
|
}> = {
|
|
'slide-generator': {
|
|
role: 'Crée une présentation PowerPoint professionnelle et visuelle à partir du contenu de la note fournie.',
|
|
tools: JSON.stringify(['note_search', 'note_read', 'generate_pptx']),
|
|
maxSteps: 8,
|
|
},
|
|
'excalidraw-generator': {
|
|
role: 'Génère un diagramme Excalidraw clair et professionnel à partir du contenu de la note fournie.',
|
|
tools: JSON.stringify(['note_search', 'note_read', 'generate_excalidraw']),
|
|
maxSteps: 6,
|
|
},
|
|
}
|
|
|
|
export async function POST(req: NextRequest) {
|
|
const session = await auth()
|
|
if (!session?.user?.id) {
|
|
return NextResponse.json({ error: 'Non autorisé' }, { status: 401 })
|
|
}
|
|
const userId = session.user.id
|
|
|
|
const body = await req.json()
|
|
const { noteId, type, theme, style } = body as {
|
|
noteId: string
|
|
type: GenerateType
|
|
theme?: string
|
|
style?: string
|
|
}
|
|
|
|
if (!noteId || !type || !TYPE_DEFAULTS[type]) {
|
|
return NextResponse.json({ error: 'Paramètres invalides' }, { status: 400 })
|
|
}
|
|
|
|
// Verify note belongs to user
|
|
const note = await prisma.note.findFirst({
|
|
where: { id: noteId, userId },
|
|
select: { id: true, title: true, notebookId: true },
|
|
})
|
|
if (!note) {
|
|
return NextResponse.json({ error: 'Note introuvable' }, { status: 404 })
|
|
}
|
|
|
|
const defaults = TYPE_DEFAULTS[type]
|
|
const agentName = type === 'slide-generator'
|
|
? `Slides — ${(note.title || 'Note').substring(0, 40)}`
|
|
: `Diagramme — ${(note.title || 'Note').substring(0, 40)}`
|
|
|
|
// Create a dedicated one-shot agent for this note
|
|
const agent = await prisma.agent.create({
|
|
data: {
|
|
name: agentName,
|
|
type,
|
|
role: defaults.role,
|
|
tools: defaults.tools,
|
|
maxSteps: defaults.maxSteps,
|
|
frequency: 'manual',
|
|
isEnabled: true,
|
|
sourceNoteIds: JSON.stringify([noteId]),
|
|
targetNotebookId: note.notebookId ?? undefined,
|
|
slideTheme: theme ?? 'vibrant_tech',
|
|
slideStyle: style ?? 'soft',
|
|
userId,
|
|
},
|
|
})
|
|
|
|
try {
|
|
const { executeAgent } = await import('@/lib/ai/services/agent-executor.service')
|
|
const result = await executeAgent(agent.id, userId)
|
|
return NextResponse.json(result)
|
|
} catch (err) {
|
|
console.error('[run-for-note] executeAgent error:', err)
|
|
return NextResponse.json(
|
|
{ success: false, error: err instanceof Error ? err.message : 'Erreur inconnue' },
|
|
{ status: 500 },
|
|
)
|
|
}
|
|
}
|