feat(rpg): dynamically display parallel coder instance count (x2, x3) on active dev desk
This commit is contained in:
+12
-3
@@ -722,6 +722,7 @@
|
|||||||
agents[key].state = agentData.state;
|
agents[key].state = agentData.state;
|
||||||
agents[key].currentTask = agentData.currentTask;
|
agents[key].currentTask = agentData.currentTask;
|
||||||
agents[key].lastAction = agentData.lastAction;
|
agents[key].lastAction = agentData.lastAction;
|
||||||
|
agents[key].parallelCount = agentData.parallelCount || 0;
|
||||||
if (agentData.liveLog && agentData.liveLog.length > 0) {
|
if (agentData.liveLog && agentData.liveLog.length > 0) {
|
||||||
agents[key].liveLog = agentData.liveLog;
|
agents[key].liveLog = agentData.liveLog;
|
||||||
}
|
}
|
||||||
@@ -1416,15 +1417,23 @@
|
|||||||
ctx.fillText("💾 DELEGATE", x - 6, y + 3 + bounce);
|
ctx.fillText("💾 DELEGATE", x - 6, y + 3 + bounce);
|
||||||
|
|
||||||
} else if (agent.state === 'WORKING') {
|
} else if (agent.state === 'WORKING') {
|
||||||
|
const count = agent.parallelCount || 1;
|
||||||
|
const bubbleW = (count > 1) ? 54 : 40;
|
||||||
ctx.fillStyle = "#064e3b";
|
ctx.fillStyle = "#064e3b";
|
||||||
ctx.fillRect(x - 10, y - 10, 40, 20);
|
ctx.fillRect(x - 10, y - 10, bubbleW, 20);
|
||||||
ctx.strokeStyle = "#34d399";
|
ctx.strokeStyle = (count > 1) ? "#facc15" : "#34d399";
|
||||||
ctx.lineWidth = 1.5;
|
ctx.lineWidth = 1.5;
|
||||||
ctx.strokeRect(x - 10, y - 10, 40, 20);
|
ctx.strokeRect(x - 10, y - 10, bubbleW, 20);
|
||||||
ctx.font = "10px 'Press Start 2P'";
|
ctx.font = "10px 'Press Start 2P'";
|
||||||
ctx.fillStyle = "#34d399";
|
ctx.fillStyle = "#34d399";
|
||||||
ctx.fillText("</>", x - 4, y + 4);
|
ctx.fillText("</>", x - 4, y + 4);
|
||||||
|
|
||||||
|
if (count > 1) {
|
||||||
|
ctx.font = "10px 'Press Start 2P'";
|
||||||
|
ctx.fillStyle = "#facc15";
|
||||||
|
ctx.fillText(`x${count}`, x + 24, y + 4);
|
||||||
|
}
|
||||||
|
|
||||||
} else if (agent.state === 'THINKING') {
|
} else if (agent.state === 'THINKING') {
|
||||||
const bob = Math.sin(time * 0.01) * 2;
|
const bob = Math.sin(time * 0.01) * 2;
|
||||||
ctx.fillStyle = "#713f12";
|
ctx.fillStyle = "#713f12";
|
||||||
|
|||||||
@@ -232,9 +232,8 @@ class RealtimeRPGHandler(http.server.SimpleHTTPRequestHandler):
|
|||||||
lead_last_pulse_seconds = 999
|
lead_last_pulse_seconds = 999
|
||||||
lead_recent_logs = []
|
lead_recent_logs = []
|
||||||
|
|
||||||
coder_session_active = False
|
coder_sessions = []
|
||||||
coder_task_desc = ""
|
active_coder_count = 0
|
||||||
coder_recent_logs = []
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
search_patterns = [
|
search_patterns = [
|
||||||
@@ -248,7 +247,7 @@ class RealtimeRPGHandler(http.server.SimpleHTTPRequestHandler):
|
|||||||
|
|
||||||
rollout_files = sorted(all_rollout_files, key=os.path.getmtime, reverse=True)
|
rollout_files = sorted(all_rollout_files, key=os.path.getmtime, reverse=True)
|
||||||
|
|
||||||
for rf in rollout_files[:10]:
|
for rf in rollout_files[:15]:
|
||||||
age_seconds = round(time.time() - os.path.getmtime(rf), 1)
|
age_seconds = round(time.time() - os.path.getmtime(rf), 1)
|
||||||
with open(rf, 'r') as fp:
|
with open(rf, 'r') as fp:
|
||||||
lines = fp.readlines()
|
lines = fp.readlines()
|
||||||
@@ -300,11 +299,14 @@ class RealtimeRPGHandler(http.server.SimpleHTTPRequestHandler):
|
|||||||
session_prompt = first_prompt or "Heartbeat / Backlog Monitoring"
|
session_prompt = first_prompt or "Heartbeat / Backlog Monitoring"
|
||||||
|
|
||||||
# Map to specific agent
|
# Map to specific agent
|
||||||
if session_role == "coder" and not coder_session_active:
|
if session_role == "coder":
|
||||||
if not is_completed and age_seconds < 60:
|
if not is_completed and age_seconds < 60:
|
||||||
coder_session_active = True
|
active_coder_count += 1
|
||||||
coder_task_desc = session_prompt[:120]
|
coder_sessions.append({
|
||||||
coder_recent_logs = recent_logs
|
"task": session_prompt[:120],
|
||||||
|
"logs": recent_logs,
|
||||||
|
"age": age_seconds
|
||||||
|
})
|
||||||
elif session_role == "lead" and not lead_heartbeat_active:
|
elif session_role == "lead" and not lead_heartbeat_active:
|
||||||
lead_last_pulse_seconds = age_seconds
|
lead_last_pulse_seconds = age_seconds
|
||||||
if not is_completed and age_seconds < 60:
|
if not is_completed and age_seconds < 60:
|
||||||
@@ -321,23 +323,27 @@ class RealtimeRPGHandler(http.server.SimpleHTTPRequestHandler):
|
|||||||
status["lead_heartbeat"] = {"error": str(e), "is_beating": False, "last_pulse_seconds_ago": 999}
|
status["lead_heartbeat"] = {"error": str(e), "is_beating": False, "last_pulse_seconds_ago": 999}
|
||||||
|
|
||||||
# 4. Derive Agent RPG States STRICTLY for target_project
|
# 4. Derive Agent RPG States STRICTLY for target_project
|
||||||
# Coder 1
|
# Coder 1 (supports multi-instance count x2, x3)
|
||||||
if "coder-tasks" in latest_active_tasks:
|
if "coder-tasks" in latest_active_tasks:
|
||||||
task = latest_active_tasks["coder-tasks"]
|
task = latest_active_tasks["coder-tasks"]
|
||||||
status["agents"]["coder1"]["state"] = "WORKING"
|
status["agents"]["coder1"]["state"] = "WORKING"
|
||||||
status["agents"]["coder1"]["currentTask"] = f"Task #{task.get('issueNumber', '')}: {task.get('title', 'Coding')}"
|
status["agents"]["coder1"]["currentTask"] = f"Task #{task.get('issueNumber', '')}: {task.get('title', 'Coding')}"
|
||||||
status["agents"]["coder1"]["lastAction"] = "BullMQ: Active Code Session"
|
status["agents"]["coder1"]["lastAction"] = "BullMQ: Active Code Session"
|
||||||
status["agents"]["coder1"]["liveLog"] = ["git checkout feature-branch", "npm run test", "git commit -m 'feat: implementation'"]
|
status["agents"]["coder1"]["liveLog"] = ["git checkout feature-branch", "npm run test", "git commit -m 'feat: implementation'"]
|
||||||
elif coder_session_active:
|
status["agents"]["coder1"]["parallelCount"] = max(1, active_coder_count)
|
||||||
|
elif active_coder_count > 0:
|
||||||
status["agents"]["coder1"]["state"] = "WORKING"
|
status["agents"]["coder1"]["state"] = "WORKING"
|
||||||
status["agents"]["coder1"]["currentTask"] = f"Aktiv: {coder_task_desc or 'Coding Session'}"
|
primary_coder = coder_sessions[0]
|
||||||
status["agents"]["coder1"]["lastAction"] = "OpenClaw Coder Turn Active"
|
status["agents"]["coder1"]["currentTask"] = f"Aktiv ({active_coder_count}x): {primary_coder['task'] or 'Coding Session'}"
|
||||||
status["agents"]["coder1"]["liveLog"] = coder_recent_logs or ["Implementing feature / bugfix..."]
|
status["agents"]["coder1"]["lastAction"] = f"OpenClaw Coder Turn ({active_coder_count} parallel)"
|
||||||
|
status["agents"]["coder1"]["liveLog"] = primary_coder["logs"] or ["Implementing feature / bugfix..."]
|
||||||
|
status["agents"]["coder1"]["parallelCount"] = active_coder_count
|
||||||
else:
|
else:
|
||||||
status["agents"]["coder1"]["state"] = "IDLE"
|
status["agents"]["coder1"]["state"] = "IDLE"
|
||||||
status["agents"]["coder1"]["currentTask"] = f"Keine offenen Tasks in {target_project}"
|
status["agents"]["coder1"]["currentTask"] = f"Keine offenen Tasks in {target_project}"
|
||||||
status["agents"]["coder1"]["lastAction"] = "Idle / Bereit"
|
status["agents"]["coder1"]["lastAction"] = "Idle / Bereit"
|
||||||
status["agents"]["coder1"]["liveLog"] = ["Wartet auf neue Queue-Aufgaben..."]
|
status["agents"]["coder1"]["liveLog"] = ["Wartet auf neue Queue-Aufgaben..."]
|
||||||
|
status["agents"]["coder1"]["parallelCount"] = 0
|
||||||
|
|
||||||
# Coder 2 (Tester / Staging)
|
# Coder 2 (Tester / Staging)
|
||||||
if "tester-tasks" in latest_active_tasks or "deployments" in latest_active_tasks:
|
if "tester-tasks" in latest_active_tasks or "deployments" in latest_active_tasks:
|
||||||
|
|||||||
Reference in New Issue
Block a user