Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,10 @@ translate: ## Extract, update and compile translations
done

run: ## Run iac-code
uv run iac-code
IAC_CODE_INSTRUCTION_MEMORY_FILE=IAC-CODE.md uv run iac-code

dev: ## Run iac-code in debug mode
uv run iac-code --debug
IAC_CODE_INSTRUCTION_MEMORY_FILE=IAC-CODE.md uv run iac-code --debug

clean: ## Clean build artifacts
rm -rf .ruff_cache .pytest_cache dist build htmlcov .coverage coverage.xml
Expand Down
12 changes: 8 additions & 4 deletions src/iac_code/acp/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@
logger = logging.getLogger(__name__)


def _runtime_command_memory_manager(runtime: object) -> object | None:
return getattr(runtime, "legacy_memory_manager", None) or getattr(runtime, "memory_manager", None)


class ACPServer:
def __init__(self) -> None:
self.conn: acp.Client | None = None
Expand Down Expand Up @@ -161,7 +165,7 @@ async def new_session(
self.conn,
mcp_configs=mcp_configs,
metrics=self.metrics,
memory_manager=getattr(runtime, "memory_manager", None),
memory_manager=_runtime_command_memory_manager(runtime),
)
self.sessions[session.id] = session
self.metrics.record_session_created()
Expand Down Expand Up @@ -303,7 +307,7 @@ async def load_session(
self.conn,
mcp_configs=mcp_configs,
metrics=self.metrics,
memory_manager=getattr(runtime, "memory_manager", None),
memory_manager=_runtime_command_memory_manager(runtime),
)
self.sessions[session_id] = session
self.metrics.record_session_created()
Expand Down Expand Up @@ -372,7 +376,7 @@ async def fork_session(
self.conn,
mcp_configs=mcp_configs,
metrics=self.metrics,
memory_manager=getattr(runtime, "memory_manager", None),
memory_manager=_runtime_command_memory_manager(runtime),
)
self.sessions[new_session_id] = session
self.metrics.record_session_created()
Expand Down Expand Up @@ -482,7 +486,7 @@ async def resume_session(
self.conn,
mcp_configs=mcp_configs,
metrics=self.metrics,
memory_manager=getattr(runtime, "memory_manager", None),
memory_manager=_runtime_command_memory_manager(runtime),
)
self.sessions[resolved_session_id] = session
self.metrics.record_session_created()
Expand Down
12 changes: 11 additions & 1 deletion src/iac_code/acp/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,14 @@
from iac_code.acp.state import TurnState
from iac_code.acp.tools import ACPTerminalBashTool
from iac_code.acp.types import ACPContentBlock
from iac_code.agent.message import Message, TextBlock, ThinkingBlock, ToolResultBlock, ToolUseBlock
from iac_code.agent.message import (
Message,
TextBlock,
ThinkingBlock,
ToolResultBlock,
ToolUseBlock,
is_recalled_memory_message,
)
from iac_code.services.telemetry import use_session_id
from iac_code.state.app_state import lookup_permission, record_permission
from iac_code.types.permissions import PermissionDecision
Expand Down Expand Up @@ -64,6 +71,9 @@ def _history_message_to_updates(msg: Message) -> list[Any]:
``ToolCallProgress``.
* **user** tool-result blocks are emitted as completed ``ToolCallProgress``.
"""
if is_recalled_memory_message(msg):
return []

updates: list[Any] = []
content = msg.content

Expand Down
19 changes: 11 additions & 8 deletions src/iac_code/acp/slash_registry.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
"""ACP slash command registry.

Manages commands supported over the ACP protocol.
Only /compact, /clear, /debug, /memory, and /rename are allowed;
all other slash commands are rejected with a clear message.
Only /compact, /clear, /debug, /memory-folder, and /rename are executable;
all other slash commands are rejected with a clear message listing public
commands only.
"""

from __future__ import annotations
Expand All @@ -15,7 +16,9 @@

logger = logging.getLogger(__name__)

ACP_SUPPORTED_COMMANDS: frozenset[str] = frozenset({"compact", "clear", "debug", "memory", "rename"})
ACP_EXECUTABLE_COMMANDS: frozenset[str] = frozenset({"compact", "clear", "debug", "memory-folder", "rename"})
ACP_PUBLIC_COMMANDS: frozenset[str] = frozenset({"compact", "clear", "debug", "rename"})
ACP_SUPPORTED_COMMANDS = ACP_EXECUTABLE_COMMANDS


class ACPSlashRegistry:
Expand All @@ -33,16 +36,16 @@ def is_slash_command(self, text: str) -> bool:
async def execute(self, text: str, agent_loop, **context) -> str:
"""Execute a slash command and return the result text.

If the command is not in :data:`ACP_SUPPORTED_COMMANDS`, returns a
rejection message listing available commands.
If the command is not in :data:`ACP_EXECUTABLE_COMMANDS`, returns a
rejection message listing public commands.
"""
stripped = text.strip()
parts = stripped[1:].split(None, 1)
cmd_name = parts[0].lower() if parts else ""
args_str = parts[1] if len(parts) > 1 else ""

if cmd_name not in ACP_SUPPORTED_COMMANDS:
supported = ", ".join(f"/{c}" for c in sorted(ACP_SUPPORTED_COMMANDS))
if cmd_name not in ACP_EXECUTABLE_COMMANDS:
supported = ", ".join(f"/{c}" for c in sorted(ACP_PUBLIC_COMMANDS))
return _("Command '/{cmd_name}' is not supported over ACP. Supported commands: {supported}").format(
cmd_name=cmd_name, supported=supported
)
Expand All @@ -53,7 +56,7 @@ async def execute(self, text: str, agent_loop, **context) -> str:
return await self._handle_clear(agent_loop)
if cmd_name == "debug":
return self._handle_debug(args_str)
if cmd_name == "memory":
if cmd_name == "memory-folder":
return self._handle_memory(args_str, context.get("memory_manager"))
if cmd_name == "rename":
return self._handle_rename(args_str, agent_loop)
Expand Down
Loading
Loading