auto-dev-agent / utils /error_cache.py
Siva sai Yadav
ready for HuggingFace Space deployment
8edee29
Raw
History Blame Contribute Delete
3.71 kB
"""
utils/error_cache.py
--------------------
Error classification cache for AutoDevAgent.
Tracks error fingerprints (cache_keys) across debug iterations within
a single pipeline run. When the same error appears in consecutive
iterations, the debug agent has already tried one fix that did not work
β€” continuing with the same strategy is pointless.
When a repeated error is detected, the DebugAgent escalates to a
fundamentally different fix strategy rather than patching the same line.
Design:
- Keyed by the normalised error fingerprint (cache_key from
ErrorClassification, e.g. "NameError:x_not_defined").
- Records the count of how many times each key has been seen.
- "Repeated" means seen more than once β€” i.e. the same error
appeared in at least two consecutive iterations.
- Reset between pipeline runs so state does not bleed across tasks.
Usage:
from utils.error_cache import ErrorCache
cache = ErrorCache()
cache.record("NameError:x_not_defined")
cache.is_repeated("NameError:x_not_defined") # False (seen once)
cache.record("NameError:x_not_defined")
cache.is_repeated("NameError:x_not_defined") # True (seen twice)
cache.reset()
"""
import logging
from collections import defaultdict
logger = logging.getLogger(__name__)
class ErrorCache:
"""
Tracks how many times each error fingerprint has been seen.
One instance is created per module (in debug_agent.py) and shared
across all DebugAgent calls within a session. Call reset() at the
start of each new pipeline run to clear stale state.
Attributes:
_counts: Dict mapping cache_key β†’ number of times seen.
"""
def __init__(self) -> None:
"""Initialise an empty cache."""
self._counts: dict[str, int] = defaultdict(int)
def record(self, cache_key: str) -> None:
"""
Record one occurrence of an error fingerprint.
Args:
cache_key: Normalised error fingerprint from ErrorClassification.
e.g. "NameError:x_not_defined"
"""
self._counts[cache_key] += 1
logger.debug(
"ErrorCache recorded '%s' (count: %d)",
cache_key,
self._counts[cache_key],
)
def is_repeated(self, cache_key: str) -> bool:
"""
Return True if this error has been seen more than once.
A count of 1 means it appeared this iteration for the first time.
A count of 2+ means a previous fix attempt did not resolve it.
Args:
cache_key: Normalised error fingerprint to check.
Returns:
True if seen more than once, False otherwise.
"""
return self._counts[cache_key] > 1
def count(self, cache_key: str) -> int:
"""
Return how many times an error fingerprint has been seen.
Args:
cache_key: Normalised error fingerprint to look up.
Returns:
Integer count, 0 if never seen.
"""
return self._counts[cache_key]
def reset(self) -> None:
"""
Clear all recorded error counts.
Call this at the start of each new pipeline run to prevent
error state from one task bleeding into the next.
"""
cleared = len(self._counts)
self._counts.clear()
logger.debug("ErrorCache reset β€” cleared %d entries", cleared)
def summary(self) -> dict[str, int]:
"""
Return a snapshot of all recorded error counts.
Useful for session history logging and debugging.
Returns:
Dict of cache_key β†’ count for all recorded errors.
"""
return dict(self._counts)