Fix all critical issues flagged in code review

- checkpoint.py: remove debug log file (strix_checkpoint_debug.log)
  that was writing to every user's home directory on each save
- checkpoint.py: acquire _agents_lock before iterating _agent_instances
  to prevent RuntimeError on concurrent sub-agent creation/removal
- checkpoint_restore.py: register restored sub-agents in _agent_graph,
  _agent_instances, and _agent_states so send_message_to_agent can
  route to them — previously they were unreachable after resume
- tracer.py: revert Path.home() back to Path.cwd() to avoid silent
  breaking change for all users; checkpoint logic in main.py already
  uses Path.home() directly so tracer change was not needed
- cli.py / tui.py: move checkpoint_restore imports to top of file
  per PEP 8, remove noqa: E402 suppressions

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
root 2026-03-20 15:13:55 +01:00
parent 39dd85e7f0
commit 43cb418c92
5 changed files with 19 additions and 19 deletions

View file

@ -7,6 +7,7 @@ from __future__ import annotations
import asyncio
import threading
from datetime import UTC, datetime
from typing import Any
@ -91,6 +92,15 @@ def restore_sub_agents(checkpoint_data: Any, llm_config: Any) -> list[str]:
t.start()
with agents_graph_actions._agents_lock:
agents_graph_actions._running_agents[agent_id] = t
agents_graph_actions._agent_instances[agent_id] = agent
agents_graph_actions._agent_states[agent_id] = state
agents_graph_actions._agent_graph["nodes"][agent_id] = {
"status": "running",
"name": state.agent_name,
"task": state.task,
"parent_id": state.parent_id,
"started_at": datetime.now(UTC).isoformat(),
}
restored_ids.append(agent_id)
except Exception: # noqa: BLE001

View file

@ -11,6 +11,8 @@ from rich.panel import Panel
from rich.text import Text
from strix.agents.StrixAgent import StrixAgent
from strix.interface.checkpoint_restore import build_root_resume_message as _build_resume_context_message
from strix.interface.checkpoint_restore import restore_sub_agents as _restore_sub_agents
from strix.llm.config import LLMConfig
from strix.telemetry.tracer import Tracer, set_global_tracer
@ -97,8 +99,6 @@ def _replay_previous_output(
console.print()
from strix.interface.checkpoint_restore import build_root_resume_message as _build_resume_context_message # noqa: E402
from strix.interface.checkpoint_restore import restore_sub_agents as _restore_sub_agents # noqa: E402
async def run_cli(args: Any) -> None: # noqa: PLR0915

View file

@ -29,6 +29,8 @@ from textual.widgets import Button, Label, Static, TextArea, Tree
from textual.widgets.tree import TreeNode
from strix.agents.StrixAgent import StrixAgent
from strix.interface.checkpoint_restore import build_root_resume_message as _build_root_resume_message
from strix.interface.checkpoint_restore import restore_sub_agents as _restore_sub_agents_tui
from strix.interface.streaming_parser import parse_streaming_content
from strix.interface.tool_components.agent_message_renderer import AgentMessageRenderer
from strix.interface.tool_components.registry import get_tool_renderer
@ -39,10 +41,6 @@ from strix.telemetry.tracer import Tracer, set_global_tracer
logger = logging.getLogger(__name__)
from strix.interface.checkpoint_restore import build_root_resume_message as _build_root_resume_message # noqa: E402
from strix.interface.checkpoint_restore import restore_sub_agents as _restore_sub_agents_tui # noqa: E402
def get_package_version() -> str:
try:
return pkg_version("strix-agent")

View file

@ -144,7 +144,9 @@ class CheckpointManager:
try:
from strix.tools.agents_graph import agents_graph_actions
for sid, inst in list(agents_graph_actions._agent_instances.items()):
with agents_graph_actions._agents_lock:
snapshot = list(agents_graph_actions._agent_instances.items())
for sid, inst in snapshot:
s = getattr(inst, "state", None)
if s is not None and s.parent_id is not None:
sub_agent_states[sid] = (
@ -176,19 +178,9 @@ class CheckpointManager:
)
self._tmp_path.write_text(json_str, encoding="utf-8")
os.rename(self._tmp_path, self.checkpoint_path)
with open(Path.home() / "strix_checkpoint_debug.log", "a") as _dbg:
_dbg.write(f"SAVED iter={agent_state.iteration} path={self.checkpoint_path}\n")
logger.debug("[Resume] Checkpoint saved iter=%s path=%s", agent_state.iteration, self.checkpoint_path)
except Exception as e: # noqa: BLE001
try:
with open(Path.home() / "strix_checkpoint_debug.log", "a") as _dbg:
_dbg.write(
f"FAILED iter={getattr(agent_state, 'iteration', '?')} "
f"path={self.checkpoint_path} err={e}\n"
)
except Exception:
pass
logger.warning("[Resume] Checkpoint save failed (non-fatal): %s", e)
def load(self) -> "CheckpointModel | None":

View file

@ -294,7 +294,7 @@ class Tracer:
def get_run_dir(self) -> Path:
if self._run_dir is None:
runs_dir = Path.home() / "strix_runs"
runs_dir = Path.cwd() / "strix_runs"
runs_dir.mkdir(exist_ok=True)
run_dir_name = self.run_name if self.run_name else self.run_id