- Replace hard-coded `MAX_REPL_STEPS` death-limit with a dynamic Checkpoint Interval. - Introduce 4-phase state machine: `PLANNING`, `EXECUTING`, `TRAJECTORY_CHECK`, and `PIVOTING`. - Add Trajectory Checks allowing the agent to self-assess progress against defined success criteria to extend its execution budget. - Implement Hard (wipe strategy/kernel) and Soft (retry step) Pivoting logic. - Establish persistent notebook-style kernel (flushed only on Hard Pivots). - Upgrade sandbox safety with strict import whitelisting, dunder blocking, and taint tracking. **bugfix: - logging_config.py: Add markdown_it to suppressed logger list - utils.py: Rewrite save_agent_trace for delta-based logging - edge_rlm.py: Add last_trace_msg_count tracking and pass deltas at all 3 call sites
57 lines
1.8 KiB
Python
57 lines
1.8 KiB
Python
import json
|
|
import logging
|
|
import logging.handlers
|
|
from datetime import datetime, timezone
|
|
from rich.logging import RichHandler
|
|
|
|
|
|
class JSONFormatter(logging.Formatter):
|
|
def format(self, record):
|
|
log_entry = {
|
|
"timestamp": datetime.now(timezone.utc).isoformat(),
|
|
"level": record.levelname,
|
|
"logger": record.name,
|
|
"message": record.getMessage(),
|
|
"module": record.module,
|
|
"function": record.funcName,
|
|
"line": record.lineno,
|
|
}
|
|
standard_keys = set(logging.LogRecord("", 0, "", 0, "", (), None).__dict__.keys())
|
|
for key, value in record.__dict__.items():
|
|
if key not in standard_keys and key not in ("message", "msg", "args"):
|
|
log_entry[key] = value
|
|
if record.exc_info and record.exc_info[0]:
|
|
log_entry["exception"] = self.formatException(record.exc_info)
|
|
return json.dumps(log_entry, default=str, ensure_ascii=False)
|
|
|
|
|
|
def setup_logging(level=logging.INFO, log_file=None):
|
|
for lib_name in ("urllib3", "requests", "http.client", "markdown", "Markdown", "markdown_it"):
|
|
logging.getLogger(lib_name).setLevel(logging.WARNING)
|
|
|
|
handlers = [
|
|
RichHandler(
|
|
rich_tracebacks=True,
|
|
show_path=False,
|
|
log_time_format="[%H:%M:%S]",
|
|
markup=True,
|
|
)
|
|
]
|
|
|
|
if log_file:
|
|
file_handler = logging.handlers.RotatingFileHandler(
|
|
log_file, maxBytes=10_000_000, backupCount=3, encoding="utf-8"
|
|
)
|
|
file_handler.setFormatter(JSONFormatter())
|
|
handlers.append(file_handler)
|
|
|
|
logging.basicConfig(
|
|
level=level,
|
|
format="%(message)s",
|
|
datefmt="[%X]",
|
|
handlers=handlers,
|
|
)
|
|
|
|
if level == logging.DEBUG:
|
|
logging.getLogger(__name__).debug("[dim]Debug mode active.[/dim]")
|