Add task IDs (T-1, T-2, ...) for tracking and debugging
Every PrimaryTask and SubTask gets a unique auto-incrementing ID. All log messages now include the task ID: T-1 NEW: Following GavRocket (stack depth: 1) T-2 INTERRUPT: Fighting spider T-2 COMPLETE: Fighting spider T-1 RESUMED: Following GavRocket T-3 NEW: Checking inventory (stack depth: 2) T-1 PAUSED: Following GavRocket T-3 COMPLETE: Checking inventory T-1 RESUMED: Following GavRocket Makes it easy to track which task is which and debug the stack. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
7363e8589f
commit
1872d0b89a
2 changed files with 16 additions and 9 deletions
|
|
@ -416,7 +416,8 @@ class DougBrain(QObject):
|
|||
if subtask.description:
|
||||
current = self._tasks.current_task
|
||||
priority_name = current.priority.name if current else "?"
|
||||
log.info(f"[{priority_name}] {subtask.description}")
|
||||
tid = current.task_id if current else 0
|
||||
log.info(f"T-{tid} [{priority_name}] {subtask.description}")
|
||||
|
||||
self._action_sent_time = time.time()
|
||||
|
||||
|
|
|
|||
|
|
@ -15,11 +15,15 @@ import time
|
|||
from dataclasses import dataclass, field
|
||||
from enum import IntEnum
|
||||
from typing import Any, Optional
|
||||
import itertools
|
||||
|
||||
from dougbot.utils.logging import get_logger
|
||||
|
||||
log = get_logger("core.tasks")
|
||||
|
||||
# Global task ID counter
|
||||
_task_counter = itertools.count(1)
|
||||
|
||||
|
||||
class Priority(IntEnum):
|
||||
"""Task priority levels. Higher = more urgent."""
|
||||
|
|
@ -51,6 +55,7 @@ class SubTask:
|
|||
status: TaskStatus = TaskStatus.PENDING
|
||||
timeout: float = 30.0
|
||||
started_at: float = 0.0
|
||||
task_id: int = field(default_factory=lambda: next(_task_counter))
|
||||
|
||||
@property
|
||||
def is_expired(self) -> bool:
|
||||
|
|
@ -67,6 +72,7 @@ class PrimaryTask:
|
|||
"""
|
||||
name: str
|
||||
priority: Priority
|
||||
task_id: int = field(default_factory=lambda: next(_task_counter))
|
||||
description: str = ""
|
||||
source: str = "self" # "player" or "self"
|
||||
source_player: str = "" # Who gave the command
|
||||
|
|
@ -141,7 +147,7 @@ class PrimaryTask:
|
|||
def __str__(self):
|
||||
st = self.current_subtask()
|
||||
step_info = f" → {st.description}" if st else ""
|
||||
return f"[{self.priority.name}] {self.description}{step_info}"
|
||||
return f"T-{self.task_id} [{self.priority.name}] {self.description}{step_info}"
|
||||
|
||||
|
||||
class TaskStack:
|
||||
|
|
@ -204,7 +210,7 @@ class TaskStack:
|
|||
# Pause the current top task
|
||||
if self._stack and self._stack[-1].status == TaskStatus.ACTIVE:
|
||||
self._stack[-1].status = TaskStatus.PAUSED
|
||||
log.info(f"Pausing: {self._stack[-1].description}")
|
||||
log.info(f"T-{self._stack[-1].task_id} PAUSED: {self._stack[-1].description}")
|
||||
|
||||
# Push new task
|
||||
task.status = TaskStatus.ACTIVE
|
||||
|
|
@ -215,7 +221,7 @@ class TaskStack:
|
|||
while len(self._stack) > self.MAX_DEPTH:
|
||||
self._stack.pop(0)
|
||||
|
||||
log.info(f"New task: {task.description} (stack depth: {len(self._stack)})")
|
||||
log.info(f"T-{task.task_id} NEW: {task.description} (stack depth: {len(self._stack)})")
|
||||
return True
|
||||
|
||||
def interrupt(self, task: PrimaryTask):
|
||||
|
|
@ -226,7 +232,7 @@ class TaskStack:
|
|||
self._interruption = task
|
||||
task.status = TaskStatus.ACTIVE
|
||||
task.started_at = time.time()
|
||||
log.info(f"Interrupt: {task.description}")
|
||||
log.info(f"T-{task.task_id} INTERRUPT: {task.description}")
|
||||
|
||||
def complete_interruption(self):
|
||||
"""Clear the current interruption, resume stack."""
|
||||
|
|
@ -258,12 +264,12 @@ class TaskStack:
|
|||
self._completed_names.append(top.name)
|
||||
if len(self._completed_names) > 20:
|
||||
self._completed_names.pop(0)
|
||||
log.info(f"Task complete: {top.description}")
|
||||
log.info(f"T-{top.task_id} COMPLETE: {top.description}")
|
||||
|
||||
# Resume the task below if any
|
||||
if self._stack:
|
||||
self._stack[-1].status = TaskStatus.ACTIVE
|
||||
log.info(f"Resuming: {self._stack[-1].description}")
|
||||
log.info(f"T-{self._stack[-1].task_id} RESUMED: {self._stack[-1].description}")
|
||||
|
||||
def fail_current(self):
|
||||
"""Fail current subtask but don't kill the primary task."""
|
||||
|
|
@ -296,10 +302,10 @@ class TaskStack:
|
|||
|
||||
if self._stack:
|
||||
removed = self._stack.pop()
|
||||
log.info(f"Task cancelled: {removed.description}")
|
||||
log.info(f"T-{removed.task_id} CANCELLED: {removed.description}")
|
||||
if self._stack:
|
||||
self._stack[-1].status = TaskStatus.ACTIVE
|
||||
log.info(f"Resuming: {self._stack[-1].description}")
|
||||
log.info(f"T-{self._stack[-1].task_id} RESUMED: {self._stack[-1].description}")
|
||||
|
||||
def cancel_all(self):
|
||||
"""Clear everything."""
|
||||
|
|
|
|||
Loading…
Reference in a new issue