mirror of
https://github.com/leonvanzyl/autocoder.git
synced 2026-04-03 11:13:08 +00:00
feat: add dedicated testing agents and enhanced parallel orchestration
Introduce a new testing agent architecture that runs regression tests independently from coding agents, improving quality assurance in parallel mode. Key changes: Testing Agent System: - Add testing_prompt.template.md for dedicated testing agent role - Add feature_mark_failing MCP tool for regression detection - Add --agent-type flag to select initializer/coding/testing mode - Remove regression testing from coding prompt (now handled by testing agents) Parallel Orchestrator Enhancements: - Add testing agent spawning with configurable ratio (--testing-agent-ratio) - Add comprehensive debug logging system (DebugLog class) - Improve database session management to prevent stale reads - Add engine.dispose() calls to refresh connections after subprocess commits - Fix f-string linting issues (remove unnecessary f-prefixes) UI Improvements: - Add testing agent mascot (Chip) to AgentAvatar - Enhance AgentCard to display testing agent status - Add testing agent ratio slider in SettingsModal - Update WebSocket handling for testing agent updates - Improve ActivityFeed to show testing agent activity API & Server Updates: - Add testing_agent_ratio to settings schema and endpoints - Update process manager to support testing agent type - Enhance WebSocket messages for agent_update events Template Changes: - Delete coding_prompt_yolo.template.md (consolidated into main prompt) - Update initializer_prompt.template.md with improved structure - Streamline coding_prompt.template.md workflow Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
import { MessageCircle, ScrollText, X, Copy, Check } from 'lucide-react'
|
||||
import { MessageCircle, ScrollText, X, Copy, Check, Code, FlaskConical } from 'lucide-react'
|
||||
import { useState } from 'react'
|
||||
import { createPortal } from 'react-dom'
|
||||
import { AgentAvatar } from './AgentAvatar'
|
||||
import type { ActiveAgent, AgentLogEntry } from '../lib/types'
|
||||
import type { ActiveAgent, AgentLogEntry, AgentType } from '../lib/types'
|
||||
|
||||
interface AgentCardProps {
|
||||
agent: ActiveAgent
|
||||
@@ -50,9 +50,28 @@ function getStateColor(state: ActiveAgent['state']): string {
|
||||
}
|
||||
}
|
||||
|
||||
// Get agent type badge config
|
||||
function getAgentTypeBadge(agentType: AgentType): { label: string; className: string; icon: typeof Code } {
|
||||
if (agentType === 'testing') {
|
||||
return {
|
||||
label: 'TEST',
|
||||
className: 'bg-purple-100 text-purple-700 border-purple-300',
|
||||
icon: FlaskConical,
|
||||
}
|
||||
}
|
||||
// Default to coding
|
||||
return {
|
||||
label: 'CODE',
|
||||
className: 'bg-blue-100 text-blue-700 border-blue-300',
|
||||
icon: Code,
|
||||
}
|
||||
}
|
||||
|
||||
export function AgentCard({ agent, onShowLogs }: AgentCardProps) {
|
||||
const isActive = ['thinking', 'working', 'testing'].includes(agent.state)
|
||||
const hasLogs = agent.logs && agent.logs.length > 0
|
||||
const typeBadge = getAgentTypeBadge(agent.agentType || 'coding')
|
||||
const TypeIcon = typeBadge.icon
|
||||
|
||||
return (
|
||||
<div
|
||||
@@ -62,6 +81,20 @@ export function AgentCard({ agent, onShowLogs }: AgentCardProps) {
|
||||
transition-all duration-300
|
||||
`}
|
||||
>
|
||||
{/* Agent type badge */}
|
||||
<div className="flex justify-end mb-1">
|
||||
<span
|
||||
className={`
|
||||
inline-flex items-center gap-1 px-1.5 py-0.5 text-[10px] font-bold
|
||||
uppercase tracking-wide rounded border
|
||||
${typeBadge.className}
|
||||
`}
|
||||
>
|
||||
<TypeIcon size={10} />
|
||||
{typeBadge.label}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* Header with avatar and name */}
|
||||
<div className="flex items-center gap-2 mb-2">
|
||||
<AgentAvatar name={agent.agentName} state={agent.state} size="sm" />
|
||||
@@ -122,6 +155,8 @@ interface AgentLogModalProps {
|
||||
|
||||
export function AgentLogModal({ agent, logs, onClose }: AgentLogModalProps) {
|
||||
const [copied, setCopied] = useState(false)
|
||||
const typeBadge = getAgentTypeBadge(agent.agentType || 'coding')
|
||||
const TypeIcon = typeBadge.icon
|
||||
|
||||
const handleCopy = async () => {
|
||||
const logText = logs
|
||||
@@ -159,9 +194,21 @@ export function AgentLogModal({ agent, logs, onClose }: AgentLogModalProps) {
|
||||
<div className="flex items-center gap-3">
|
||||
<AgentAvatar name={agent.agentName} state={agent.state} size="sm" />
|
||||
<div>
|
||||
<h2 className="font-display font-bold text-lg">
|
||||
{agent.agentName} Logs
|
||||
</h2>
|
||||
<div className="flex items-center gap-2">
|
||||
<h2 className="font-display font-bold text-lg">
|
||||
{agent.agentName} Logs
|
||||
</h2>
|
||||
<span
|
||||
className={`
|
||||
inline-flex items-center gap-1 px-1.5 py-0.5 text-[10px] font-bold
|
||||
uppercase tracking-wide rounded border
|
||||
${typeBadge.className}
|
||||
`}
|
||||
>
|
||||
<TypeIcon size={10} />
|
||||
{typeBadge.label}
|
||||
</span>
|
||||
</div>
|
||||
<p className="text-sm text-neo-text-secondary">
|
||||
Feature #{agent.featureId}: {agent.featureName}
|
||||
</p>
|
||||
|
||||
Reference in New Issue
Block a user