Skip to content
Closed
24 changes: 13 additions & 11 deletions code_puppy/command_line/core_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,20 +77,22 @@ def handle_cd_command(command: str) -> bool:
if os.path.isdir(target):
os.chdir(target)
emit_success(f"Changed directory to: {target}")
# Reload the agent so the system prompt and project-local
# AGENT.md rules reflect the new working directory. Without
# this, the LLM keeps receiving stale path information for the
# remainder of the session (the PydanticAgent instructions are
# baked in at construction time and never refreshed otherwise).

# Reload the agent to pick up new working directory context
# This ensures AGENTS.md is re-read and system prompt is updated
try:
from code_puppy.agents.agent_manager import get_current_agent

get_current_agent().reload_code_generation_agent()

current_agent = get_current_agent()
if current_agent:
# Clear cached puppy rules so AGENTS.md is re-read from new directory
current_agent._puppy_rules = None
# Reload agent to rebuild system prompt with new working directory
current_agent.reload_code_generation_agent()
emit_info("Agent context updated for new directory")
except Exception as e:
emit_warning(
f"Directory changed, but agent reload failed: {e}. "
"You may need to run /agent or /model to force a refresh."
)
# Non-fatal: directory change succeeded even if reload failed
emit_error(f"Warning: Could not reload agent context: {e}")
else:
Comment thread
coderabbitai[bot] marked this conversation as resolved.
emit_error(f"Not a directory: {dirname}")
return True
Expand Down
56 changes: 56 additions & 0 deletions tests/command_line/test_core_commands_extended.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,62 @@ def test_cd_listing_with_permission_error(self):
args, kwargs = mock_error.call_args
assert "Access denied" in args[0]

def test_cd_reloads_agent_context(self):
"""Test that /cd reloads agent to pick up new directory context (AGENTS.md, etc)."""
from unittest.mock import MagicMock

mock_agent = MagicMock()
mock_agent._puppy_rules = "old cached rules"

with patch("code_puppy.messaging.emit_success"):
with patch("code_puppy.messaging.emit_info"):
with patch("os.path.expanduser", side_effect=lambda x: x):
with patch("os.path.isabs", return_value=True):
with patch("os.path.isdir", return_value=True):
with patch("os.chdir"):
with patch(
"code_puppy.agents.agent_manager.get_current_agent",
return_value=mock_agent
):
result = handle_cd_command("/cd /new/dir")

# Verify directory changed
assert result is True

# Verify agent cache was cleared
assert mock_agent._puppy_rules is None

# Verify agent was reloaded
mock_agent.reload_code_generation_agent.assert_called_once()

def test_cd_handles_agent_reload_failure_gracefully(self):
"""Test that /cd continues even if agent reload fails."""
from unittest.mock import MagicMock

mock_agent = MagicMock()
mock_agent.reload_code_generation_agent.side_effect = Exception("Reload failed")

with patch("code_puppy.messaging.emit_success"):
with patch("code_puppy.messaging.emit_error") as mock_error:
with patch("os.path.expanduser", side_effect=lambda x: x):
with patch("os.path.isabs", return_value=True):
with patch("os.path.isdir", return_value=True):
with patch("os.chdir"):
with patch(
"code_puppy.agents.agent_manager.get_current_agent",
return_value=mock_agent
):
result = handle_cd_command("/cd /new/dir")

# Directory change should still succeed
assert result is True

# Error should be emitted about reload failure
assert mock_error.called
error_msg = mock_error.call_args[0][0]
assert "Warning" in error_msg
assert "Could not reload agent context" in error_msg

def test_cd_with_nonexistent_parent(self):
"""Test cd command with path containing nonexistent parent directories."""
with patch("code_puppy.messaging.emit_error") as mock_error:
Expand Down
Loading