mirror of
https://github.com/leonvanzyl/autocoder.git
synced 2026-01-30 06:12:06 +00:00
Add concurrent agent
This commit is contained in:
@@ -81,6 +81,7 @@ class Schedule(Base):
|
||||
# Agent configuration for scheduled runs
|
||||
yolo_mode = Column(Boolean, nullable=False, default=False)
|
||||
model = Column(String(50), nullable=True) # None = use global default
|
||||
max_concurrency = Column(Integer, nullable=False, default=3) # 1-5 concurrent agents
|
||||
|
||||
# Crash recovery tracking
|
||||
crash_count = Column(Integer, nullable=False, default=0) # Resets at window start
|
||||
@@ -104,6 +105,7 @@ class Schedule(Base):
|
||||
"enabled": self.enabled,
|
||||
"yolo_mode": self.yolo_mode,
|
||||
"model": self.model,
|
||||
"max_concurrency": self.max_concurrency,
|
||||
"crash_count": self.crash_count,
|
||||
"created_at": self.created_at.isoformat() if self.created_at else None,
|
||||
}
|
||||
@@ -275,6 +277,14 @@ def _migrate_add_schedules_tables(engine) -> None:
|
||||
)
|
||||
conn.commit()
|
||||
|
||||
# Add max_concurrency column if missing (for upgrades)
|
||||
if "max_concurrency" not in columns:
|
||||
with engine.connect() as conn:
|
||||
conn.execute(
|
||||
text("ALTER TABLE schedules ADD COLUMN max_concurrency INTEGER DEFAULT 3")
|
||||
)
|
||||
conn.commit()
|
||||
|
||||
|
||||
def create_database(project_dir: Path) -> tuple:
|
||||
"""
|
||||
|
||||
@@ -501,6 +501,12 @@ class ScheduleCreate(BaseModel):
|
||||
enabled: bool = True
|
||||
yolo_mode: bool = False
|
||||
model: str | None = None
|
||||
max_concurrency: int = Field(
|
||||
default=3,
|
||||
ge=1,
|
||||
le=5,
|
||||
description="Max concurrent agents (1-5)"
|
||||
)
|
||||
|
||||
@field_validator('model')
|
||||
@classmethod
|
||||
@@ -522,6 +528,7 @@ class ScheduleUpdate(BaseModel):
|
||||
enabled: bool | None = None
|
||||
yolo_mode: bool | None = None
|
||||
model: str | None = None
|
||||
max_concurrency: int | None = Field(None, ge=1, le=5)
|
||||
|
||||
@field_validator('model')
|
||||
@classmethod
|
||||
@@ -542,6 +549,7 @@ class ScheduleResponse(BaseModel):
|
||||
enabled: bool
|
||||
yolo_mode: bool
|
||||
model: str | None
|
||||
max_concurrency: int
|
||||
crash_count: int
|
||||
created_at: datetime
|
||||
|
||||
|
||||
@@ -368,10 +368,14 @@ class SchedulerService:
|
||||
logger.info(f"Agent already running for {project_name}, skipping scheduled start")
|
||||
return
|
||||
|
||||
logger.info(f"Starting agent for {project_name} (schedule {schedule.id}, yolo={schedule.yolo_mode})")
|
||||
logger.info(
|
||||
f"Starting agent for {project_name} "
|
||||
f"(schedule {schedule.id}, yolo={schedule.yolo_mode}, concurrency={schedule.max_concurrency})"
|
||||
)
|
||||
success, msg = await manager.start(
|
||||
yolo_mode=schedule.yolo_mode,
|
||||
model=schedule.model,
|
||||
max_concurrency=schedule.max_concurrency,
|
||||
)
|
||||
|
||||
if success:
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
*/
|
||||
|
||||
import { useState, useEffect, useRef } from 'react'
|
||||
import { Clock, Trash2, X } from 'lucide-react'
|
||||
import { Clock, GitBranch, Trash2, X } from 'lucide-react'
|
||||
import {
|
||||
useSchedules,
|
||||
useCreateSchedule,
|
||||
@@ -47,6 +47,7 @@ export function ScheduleModal({ projectName, isOpen, onClose }: ScheduleModalPro
|
||||
enabled: true,
|
||||
yolo_mode: false,
|
||||
model: null,
|
||||
max_concurrency: 3,
|
||||
})
|
||||
|
||||
const [error, setError] = useState<string | null>(null)
|
||||
@@ -124,6 +125,7 @@ export function ScheduleModal({ projectName, isOpen, onClose }: ScheduleModalPro
|
||||
enabled: true,
|
||||
yolo_mode: false,
|
||||
model: null,
|
||||
max_concurrency: 3,
|
||||
})
|
||||
} catch (err) {
|
||||
setError(err instanceof Error ? err.message : 'Failed to create schedule')
|
||||
@@ -242,6 +244,10 @@ export function ScheduleModal({ projectName, isOpen, onClose }: ScheduleModalPro
|
||||
{schedule.yolo_mode && (
|
||||
<span className="font-bold text-yellow-600">⚡ YOLO mode</span>
|
||||
)}
|
||||
<span className="flex items-center gap-1">
|
||||
<GitBranch size={12} />
|
||||
{schedule.max_concurrency}x
|
||||
</span>
|
||||
{schedule.model && <span>Model: {schedule.model}</span>}
|
||||
{schedule.crash_count > 0 && (
|
||||
<span className="text-red-600">Crashes: {schedule.crash_count}</span>
|
||||
@@ -369,6 +375,37 @@ export function ScheduleModal({ projectName, isOpen, onClose }: ScheduleModalPro
|
||||
</label>
|
||||
</div>
|
||||
|
||||
{/* Concurrency slider */}
|
||||
<div className="mb-4">
|
||||
<label className="block text-sm font-bold text-gray-700 dark:text-gray-200 mb-2">
|
||||
Concurrent Agents (1-5)
|
||||
</label>
|
||||
<div className="flex items-center gap-3">
|
||||
<GitBranch
|
||||
size={16}
|
||||
className={newSchedule.max_concurrency > 1 ? 'text-[var(--color-neo-primary)]' : 'text-gray-400'}
|
||||
/>
|
||||
<input
|
||||
type="range"
|
||||
min={1}
|
||||
max={5}
|
||||
value={newSchedule.max_concurrency}
|
||||
onChange={(e) =>
|
||||
setNewSchedule((prev) => ({ ...prev, max_concurrency: Number(e.target.value) }))
|
||||
}
|
||||
className="flex-1 h-2 accent-[var(--color-neo-primary)] cursor-pointer"
|
||||
title={`${newSchedule.max_concurrency} concurrent agent${newSchedule.max_concurrency > 1 ? 's' : ''}`}
|
||||
aria-label="Set number of concurrent agents"
|
||||
/>
|
||||
<span className="text-sm font-bold min-w-[2rem] text-center text-gray-900 dark:text-white">
|
||||
{newSchedule.max_concurrency}x
|
||||
</span>
|
||||
</div>
|
||||
<div className="text-xs text-gray-600 dark:text-gray-400 mt-1">
|
||||
Run {newSchedule.max_concurrency} agent{newSchedule.max_concurrency > 1 ? 's' : ''} in parallel for faster feature completion
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Model selection (optional) */}
|
||||
<div className="mb-6">
|
||||
<label className="block text-sm font-bold text-gray-700 dark:text-gray-200 mb-2">
|
||||
|
||||
@@ -503,6 +503,7 @@ export interface Schedule {
|
||||
enabled: boolean
|
||||
yolo_mode: boolean
|
||||
model: string | null
|
||||
max_concurrency: number // 1-5 concurrent agents
|
||||
crash_count: number
|
||||
created_at: string
|
||||
}
|
||||
@@ -514,6 +515,7 @@ export interface ScheduleCreate {
|
||||
enabled: boolean
|
||||
yolo_mode: boolean
|
||||
model: string | null
|
||||
max_concurrency: number // 1-5 concurrent agents
|
||||
}
|
||||
|
||||
export interface ScheduleUpdate {
|
||||
@@ -523,6 +525,7 @@ export interface ScheduleUpdate {
|
||||
enabled?: boolean
|
||||
yolo_mode?: boolean
|
||||
model?: string | null
|
||||
max_concurrency?: number
|
||||
}
|
||||
|
||||
export interface ScheduleListResponse {
|
||||
|
||||
Reference in New Issue
Block a user