fix: runAgent fire-and-forget + polling sur la page /agents
Some checks failed
Deploy to Production / Build and Deploy (push) Has been cancelled
Some checks failed
Deploy to Production / Build and Deploy (push) Has been cancelled
Le bouton Play des cartes agents appelait runAgent (Server Action) qui
attendait executeAgent (~2-5 min) → spinner bloqué sans résultat.
- runAgent retourne immédiatement { success, agentId }
- agent-card.tsx lance un polling toutes les 3s sur GET
/api/agents/run-for-note?agentId= jusqu'au statut terminal
- Toast persistant Sonner pendant la génération, mis à jour au résultat
- Cleanup automatique du polling au démontage
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -19,6 +19,7 @@ export async function createAgent(data: {
|
||||
role: string
|
||||
sourceUrls?: string[]
|
||||
sourceNotebookId?: string
|
||||
sourceNoteIds?: string[]
|
||||
targetNotebookId?: string
|
||||
frequency?: string
|
||||
tools?: string[]
|
||||
@@ -28,6 +29,8 @@ export async function createAgent(data: {
|
||||
scheduledTime?: string
|
||||
scheduledDay?: number
|
||||
timezone?: string
|
||||
slideTheme?: string
|
||||
slideStyle?: string
|
||||
}) {
|
||||
const session = await auth()
|
||||
if (!session?.user?.id) {
|
||||
@@ -43,6 +46,7 @@ export async function createAgent(data: {
|
||||
role: data.role,
|
||||
sourceUrls: data.sourceUrls ? JSON.stringify(data.sourceUrls) : null,
|
||||
sourceNotebookId: data.sourceNotebookId || null,
|
||||
sourceNoteIds: data.sourceNoteIds ? JSON.stringify(data.sourceNoteIds) : null,
|
||||
targetNotebookId: data.targetNotebookId || null,
|
||||
frequency: data.frequency || 'manual',
|
||||
tools: data.tools ? JSON.stringify(data.tools) : '[]',
|
||||
@@ -52,6 +56,8 @@ export async function createAgent(data: {
|
||||
scheduledTime: data.scheduledTime || '08:00',
|
||||
scheduledDay: data.scheduledDay ?? null,
|
||||
timezone: data.timezone || null,
|
||||
slideTheme: data.slideTheme || null,
|
||||
slideStyle: data.slideStyle || null,
|
||||
userId: session.user.id,
|
||||
}
|
||||
})
|
||||
@@ -88,6 +94,7 @@ export async function updateAgent(id: string, data: {
|
||||
role?: string
|
||||
sourceUrls?: string[]
|
||||
sourceNotebookId?: string | null
|
||||
sourceNoteIds?: string[] | null
|
||||
targetNotebookId?: string | null
|
||||
frequency?: string
|
||||
isEnabled?: boolean
|
||||
@@ -98,6 +105,8 @@ export async function updateAgent(id: string, data: {
|
||||
scheduledTime?: string
|
||||
scheduledDay?: number | null
|
||||
timezone?: string
|
||||
slideTheme?: string | null
|
||||
slideStyle?: string | null
|
||||
}) {
|
||||
const session = await auth()
|
||||
if (!session?.user?.id) {
|
||||
@@ -117,6 +126,7 @@ export async function updateAgent(id: string, data: {
|
||||
if (data.role !== undefined) updateData.role = data.role
|
||||
if (data.sourceUrls !== undefined) updateData.sourceUrls = JSON.stringify(data.sourceUrls)
|
||||
if (data.sourceNotebookId !== undefined) updateData.sourceNotebookId = data.sourceNotebookId
|
||||
if (data.sourceNoteIds !== undefined) updateData.sourceNoteIds = data.sourceNoteIds ? JSON.stringify(data.sourceNoteIds) : null
|
||||
if (data.targetNotebookId !== undefined) updateData.targetNotebookId = data.targetNotebookId
|
||||
if (data.frequency !== undefined) updateData.frequency = data.frequency
|
||||
if (data.isEnabled !== undefined) updateData.isEnabled = data.isEnabled
|
||||
@@ -127,6 +137,8 @@ export async function updateAgent(id: string, data: {
|
||||
if (data.scheduledTime !== undefined) updateData.scheduledTime = data.scheduledTime
|
||||
if (data.scheduledDay !== undefined) updateData.scheduledDay = data.scheduledDay
|
||||
if (data.timezone !== undefined) updateData.timezone = data.timezone
|
||||
if (data.slideTheme !== undefined) updateData.slideTheme = data.slideTheme
|
||||
if (data.slideStyle !== undefined) updateData.slideStyle = data.slideStyle
|
||||
|
||||
// Recalculate nextRun when scheduling fields change
|
||||
const shouldRecalcNextRun =
|
||||
@@ -220,21 +232,21 @@ export async function runAgent(id: string) {
|
||||
if (!session?.user?.id) {
|
||||
throw new Error('Non autorise')
|
||||
}
|
||||
const userId = session.user.id
|
||||
|
||||
try {
|
||||
const { executeAgent } = await import('@/lib/ai/services/agent-executor.service')
|
||||
const result = await executeAgent(id, session.user.id)
|
||||
revalidatePath('/agents')
|
||||
revalidatePath('/')
|
||||
return result
|
||||
} catch (error) {
|
||||
console.error('Error running agent:', error)
|
||||
return {
|
||||
success: false,
|
||||
actionId: '',
|
||||
error: error instanceof Error ? error.message : 'Erreur inconnue'
|
||||
}
|
||||
// Verify ownership
|
||||
const agent = await prisma.agent.findUnique({ where: { id }, select: { id: true, userId: true } })
|
||||
if (!agent || agent.userId !== userId) {
|
||||
return { success: false, agentId: id, error: 'Agent introuvable' }
|
||||
}
|
||||
|
||||
// Fire and forget — return immediately so the UI doesn't block
|
||||
import('@/lib/ai/services/agent-executor.service')
|
||||
.then(({ executeAgent }) => executeAgent(id, userId))
|
||||
.then(() => { /* revalidation is handled client-side via polling */ })
|
||||
.catch(err => console.error('[runAgent] Background error:', err))
|
||||
|
||||
return { success: true, agentId: id, status: 'running' }
|
||||
}
|
||||
|
||||
// --- History ---
|
||||
|
||||
Reference in New Issue
Block a user