fix: use node http for cron scheduler + add toast notifications
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 40s

- Replace wget with node http.request in entrypoint (guaranteed
  available, better error handling)
- Add 30s polling in agents page to detect new agent executions
- Show toast notification when an agent finishes (success or failure)
- Add logging in scheduler for visibility in docker logs

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-04-26 12:39:09 +02:00
parent 17e4a58da2
commit 1b4c6123c2
4 changed files with 56 additions and 5 deletions

View File

@@ -5,7 +5,7 @@
* Main client component for the agents page.
*/
import { useState, useCallback, useMemo } from 'react'
import { useState, useCallback, useMemo, useEffect, useRef } from 'react'
import { Plus, Bot, LifeBuoy, Search } from 'lucide-react'
import { toast } from 'sonner'
import { useLanguage } from '@/lib/i18n'
@@ -84,11 +84,49 @@ export function AgentsPageClient({
try {
const updated = await getAgents()
setAgents(updated)
return updated
} catch {
// Silent
return null
}
}, [])
// Track latest action per agent to detect new executions
const prevActionsRef = useRef<Record<string, string>>({})
// Poll every 30s to detect agent executions and show toast notifications
useEffect(() => {
// Initialize tracking from initial data
for (const agent of initialAgents) {
const lastAction = agent.actions[0]
if (lastAction) {
prevActionsRef.current[agent.id] = lastAction.id
}
}
const interval = setInterval(async () => {
const updated = await refreshAgents()
if (!updated) return
for (const agent of updated) {
const lastAction = agent.actions[0]
if (!lastAction) continue
const prevId = prevActionsRef.current[agent.id]
if (prevId && prevId !== lastAction.id) {
// New action detected
if (lastAction.status === 'success') {
toast.success(t('agents.toasts.autoRunSuccess', { name: agent.name }))
} else if (lastAction.status === 'failure') {
toast.error(t('agents.toasts.autoRunError', { name: agent.name }))
}
}
prevActionsRef.current[agent.id] = lastAction.id
}
}, 30000)
return () => clearInterval(interval)
}, [])
const handleToggle = useCallback((id: string, isEnabled: boolean) => {
setAgents(prev => prev.map(a => a.id === id ? { ...a, isEnabled } : a))
}, [])

View File

@@ -8,7 +8,16 @@ node ./node_modules/prisma/build/index.js migrate deploy
(
sleep 60
while true; do
wget -q -O /dev/null --post-data='' "http://localhost:3000/api/cron/agents" 2>/dev/null || true
node -e "
const http = require('http');
const req = http.request('http://localhost:3000/api/cron/agents', { method: 'POST' }, (res) => {
let body = '';
res.on('data', (d) => body += d);
res.on('end', () => console.log('[Scheduler] Cron response:', res.statusCode, body));
});
req.on('error', (e) => console.error('[Scheduler] Cron error:', e.message));
req.end();
" 2>&1 || true
sleep 300
done
) &

View File

@@ -1296,7 +1296,9 @@
"toggleError": "Error toggling agent",
"installSuccess": "\"{name}\" installed",
"installError": "Error during installation",
"saveError": "Error saving"
"saveError": "Error saving",
"autoRunSuccess": "Agent \"{name}\" executed automatically with success",
"autoRunError": "Agent \"{name}\" failed during automatic execution"
},
"templates": {
"title": "Templates",

View File

@@ -1292,7 +1292,9 @@
"toggleError": "Erreur lors du changement",
"installSuccess": "\"{name}\" installé",
"installError": "Erreur lors de l'installation",
"saveError": "Erreur lors de la sauvegarde"
"saveError": "Erreur lors de la sauvegarde",
"autoRunSuccess": "L'agent \"{name}\" s'est exécuté automatiquement avec succès",
"autoRunError": "L'agent \"{name}\" a échoué lors de l'exécution automatique"
},
"templates": {
"title": "Templates",