fix: remove nextRun recalculation from getAgents() that blocked cron
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 42s
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 42s
The getAgents() function was recalculating nextRun to future dates when it found past values. This prevented the cron scheduler from ever finding due agents (nextRun <= now was always false since getAgents had already pushed it to the future). Also fix toast polling: use null sentinel for agents without initial actions so first execution is still detected. Limit cron to 3 agents per cycle and add logging. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -91,16 +91,15 @@ export function AgentsPageClient({
|
||||
}, [])
|
||||
|
||||
// Track latest action per agent to detect new executions
|
||||
const prevActionsRef = useRef<Record<string, string>>({})
|
||||
// null = agent tracked with no initial actions, undefined = not tracked yet
|
||||
const prevActionsRef = useRef<Record<string, string | null>>({})
|
||||
|
||||
// Poll every 30s to detect agent executions and show toast notifications
|
||||
useEffect(() => {
|
||||
// Initialize tracking from initial data
|
||||
// Initialize tracking from initial data — use null for agents without actions
|
||||
// so we can still detect their FIRST execution
|
||||
for (const agent of initialAgents) {
|
||||
const lastAction = agent.actions[0]
|
||||
if (lastAction) {
|
||||
prevActionsRef.current[agent.id] = lastAction.id
|
||||
}
|
||||
prevActionsRef.current[agent.id] = agent.actions[0]?.id ?? null
|
||||
}
|
||||
|
||||
const interval = setInterval(async () => {
|
||||
@@ -112,8 +111,11 @@ export function AgentsPageClient({
|
||||
if (!lastAction) continue
|
||||
|
||||
const prevId = prevActionsRef.current[agent.id]
|
||||
if (prevId && prevId !== lastAction.id) {
|
||||
// New action detected
|
||||
// undefined = agent not in initial list (created by someone else, skip)
|
||||
if (prevId === undefined) continue
|
||||
|
||||
if (prevId !== lastAction.id) {
|
||||
// New execution detected (first action ever, or new run)
|
||||
if (lastAction.status === 'success') {
|
||||
toast.success(t('agents.toasts.autoRunSuccess', { name: agent.name }))
|
||||
} else if (lastAction.status === 'failure') {
|
||||
|
||||
@@ -206,26 +206,6 @@ export async function getAgents() {
|
||||
orderBy: { createdAt: 'desc' }
|
||||
})
|
||||
|
||||
// Fix stale nextRun: recalculate if in the past for scheduled agents
|
||||
const now = new Date()
|
||||
for (const agent of agents) {
|
||||
if (agent.frequency !== 'manual' && agent.nextRun && new Date(agent.nextRun) < now) {
|
||||
const nextRun = calculateNextRun({
|
||||
frequency: agent.frequency,
|
||||
scheduledTime: agent.scheduledTime,
|
||||
scheduledDay: agent.scheduledDay,
|
||||
timezone: agent.timezone,
|
||||
})
|
||||
if (nextRun) {
|
||||
await prisma.agent.update({
|
||||
where: { id: agent.id },
|
||||
data: { nextRun },
|
||||
})
|
||||
agent.nextRun = nextRun
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return agents
|
||||
} catch (error) {
|
||||
console.error('Error fetching agents:', error)
|
||||
|
||||
@@ -46,10 +46,12 @@ export async function POST(request: NextRequest) {
|
||||
return NextResponse.json({ success: true, executed: 0 })
|
||||
}
|
||||
|
||||
console.log(`[CronAgents] Found ${dueAgents.length} due agent(s)`)
|
||||
|
||||
const results: { id: string; success: boolean; error?: string }[] = []
|
||||
|
||||
// Execute agents sequentially to avoid overwhelming the AI provider
|
||||
for (const agent of dueAgents) {
|
||||
// Execute agents sequentially (max 3 per cycle) to avoid overwhelming the AI provider
|
||||
for (const agent of dueAgents.slice(0, 3)) {
|
||||
try {
|
||||
const { executeAgent } = await import('@/lib/ai/services/agent-executor.service')
|
||||
const result = await executeAgent(agent.id, agent.userId)
|
||||
|
||||
Reference in New Issue
Block a user