[cross-feature coupling] agent_loop and tool_implementations import route internals directly #674

Closed
opened 2026-06-02 23:40:46 +02:00 by sleepy · 1 comment
Owner

Cross-feature coupling: agent_loop imports routes internals directly

AGENTS.md rule: "No cross-feature dependencies without explicit interfaces."

Violation 1: Route import in agent_loop

src/agent_loop.py:814:

from routes.prefs_routes import _load_for_user as _load_prefs

This directly imports a private function (_load_for_user) from the routes layer into the core agent loop. Routes are an HTTP-layer concern; the agent loop is a core logic concern.

Violation 2: Service layer import in agent_loop

src/agent_loop.py:820:

from services.memory.skills import SkillsManager

And src/agent_loop.py:1012:

from services.memory.skills import SkillsManager

The agent loop directly instantiates SkillsManager instead of going through an interface.

Violation 3: Route import in tool_implementations

src/tool_implementations.py imports from routes.contacts_routes (lines ~3810):

from routes import contacts_routes as cc

Then calls private helpers: cc._fetch_contacts, cc._create_contact, cc._update_contact, cc._delete_contact.

Why this matters

  • If routes.prefs_routes changes its private API, the agent loop silently breaks
  • The tool system is coupled to the HTTP routing layer
  • No interface / protocol separates concerns

Suggested fix

  • Create service-layer functions in a shared module (e.g. src/services/preferences.py) with typed interfaces
  • Routes call the service layer; agent loop calls the same service layer
  • Neither depends on the other's internals
## Cross-feature coupling: agent_loop imports routes internals directly AGENTS.md rule: _"No cross-feature dependencies without explicit interfaces."_ ### Violation 1: Route import in agent_loop `src/agent_loop.py:814`: ```python from routes.prefs_routes import _load_for_user as _load_prefs ``` This directly imports a **private function** (`_load_for_user`) from the routes layer into the core agent loop. Routes are an HTTP-layer concern; the agent loop is a core logic concern. ### Violation 2: Service layer import in agent_loop `src/agent_loop.py:820`: ```python from services.memory.skills import SkillsManager ``` And `src/agent_loop.py:1012`: ```python from services.memory.skills import SkillsManager ``` The agent loop directly instantiates `SkillsManager` instead of going through an interface. ### Violation 3: Route import in tool_implementations `src/tool_implementations.py` imports from `routes.contacts_routes` (lines ~3810): ```python from routes import contacts_routes as cc ``` Then calls private helpers: `cc._fetch_contacts`, `cc._create_contact`, `cc._update_contact`, `cc._delete_contact`. ### Why this matters - If `routes.prefs_routes` changes its private API, the agent loop silently breaks - The tool system is coupled to the HTTP routing layer - No interface / protocol separates concerns ### Suggested fix - Create service-layer functions in a shared module (e.g. `src/services/preferences.py`) with typed interfaces - Routes call the service layer; agent loop calls the same service layer - Neither depends on the other's internals
Author
Owner

Fixed via PR #904 — removed private route aliases, expanded contacts_helpers.py as public service facade, updated all callers.

Fixed via PR #904 — removed private route aliases, expanded contacts_helpers.py as public service facade, updated all callers.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
sleepy/odysseus#674
No description provided.