refactor: enforce architectural boundaries by updating OpenClaw service imports

This commit is contained in:
Abhimanyu Saharan
2026-02-10 15:14:45 +05:30
parent 6311418dcf
commit 42b061f72d
9 changed files with 111 additions and 104 deletions

View File

@@ -25,7 +25,6 @@ from app.core.config import settings
from app.core.time import utcnow
from app.db.pagination import paginate
from app.db.session import async_session_maker, get_session
from app.integrations.openclaw_gateway import OpenClawGatewayError
from app.models.agents import Agent
from app.models.board_group_memory import BoardGroupMemory
from app.models.board_groups import BoardGroup
@@ -35,6 +34,7 @@ from app.schemas.board_group_memory import BoardGroupMemoryCreate, BoardGroupMem
from app.schemas.pagination import DefaultLimitOffsetPage
from app.services.mentions import extract_mentions, matches_agent_mention
from app.services.openclaw.shared import (
GatewayTransportError,
optional_gateway_config_for_board,
send_gateway_agent_message,
)
@@ -250,7 +250,7 @@ async def _notify_group_target(
agent_name=agent.name,
message=message,
)
except OpenClawGatewayError:
except GatewayTransportError:
return

View File

@@ -15,7 +15,6 @@ from app.core.time import utcnow
from app.db import crud
from app.db.pagination import paginate
from app.db.session import get_session
from app.integrations.openclaw_gateway import OpenClawGatewayError
from app.models.agents import Agent
from app.models.board_group_memory import BoardGroupMemory
from app.models.board_groups import BoardGroup
@@ -32,6 +31,7 @@ from app.schemas.view_models import BoardGroupSnapshot
from app.services.board_group_snapshot import build_group_snapshot
from app.services.openclaw.constants import DEFAULT_HEARTBEAT_CONFIG
from app.services.openclaw.provisioning import sync_gateway_agent_heartbeats
from app.services.openclaw.shared import GatewayTransportError
from app.services.organizations import (
OrganizationContext,
board_access_filter,
@@ -270,7 +270,7 @@ async def _sync_gateway_heartbeats(
continue
try:
await sync_gateway_agent_heartbeats(gateway, gateway_agents)
except OpenClawGatewayError:
except GatewayTransportError:
failed_agent_ids.extend([agent.id for agent in gateway_agents])
return failed_agent_ids

View File

@@ -23,14 +23,14 @@ from app.core.config import settings
from app.core.time import utcnow
from app.db.pagination import paginate
from app.db.session import async_session_maker, get_session
from app.integrations.openclaw_gateway import GatewayConfig as GatewayClientConfig
from app.integrations.openclaw_gateway import OpenClawGatewayError
from app.models.agents import Agent
from app.models.board_memory import BoardMemory
from app.schemas.board_memory import BoardMemoryCreate, BoardMemoryRead
from app.schemas.pagination import DefaultLimitOffsetPage
from app.services.mentions import extract_mentions, matches_agent_mention
from app.services.openclaw.shared import (
GatewayClientConfig,
GatewayTransportError,
optional_gateway_config_for_board,
send_gateway_agent_message,
)
@@ -124,7 +124,7 @@ async def _send_control_command(
message=command,
deliver=True,
)
except OpenClawGatewayError:
except GatewayTransportError:
continue
@@ -215,7 +215,7 @@ async def _notify_chat_targets(
agent_name=agent.name,
message=message,
)
except OpenClawGatewayError:
except GatewayTransportError:
continue

View File

@@ -20,7 +20,6 @@ from app.core.time import utcnow
from app.db import crud
from app.db.pagination import paginate
from app.db.session import get_session
from app.integrations.openclaw_gateway import OpenClawGatewayError
from app.models.activity_events import ActivityEvent
from app.models.agents import Agent
from app.models.approvals import Approval
@@ -41,6 +40,7 @@ from app.schemas.view_models import BoardGroupSnapshot, BoardSnapshot
from app.services.board_group_snapshot import build_board_group_snapshot
from app.services.board_snapshot import build_board_snapshot
from app.services.openclaw.provisioning import cleanup_agent
from app.services.openclaw.shared import GatewayTransportError
from app.services.organizations import OrganizationContext, board_access_filter
if TYPE_CHECKING:
@@ -288,7 +288,7 @@ async def delete_board(
try:
for agent in agents:
await cleanup_agent(agent, config)
except OpenClawGatewayError as exc:
except GatewayTransportError as exc:
raise HTTPException(
status_code=status.HTTP_502_BAD_GATEWAY,
detail=f"Gateway cleanup failed: {exc}",

View File

@@ -28,8 +28,6 @@ from app.core.time import utcnow
from app.db import crud
from app.db.pagination import paginate
from app.db.session import async_session_maker, get_session
from app.integrations.openclaw_gateway import GatewayConfig as GatewayClientConfig
from app.integrations.openclaw_gateway import OpenClawGatewayError
from app.models.activity_events import ActivityEvent
from app.models.agents import Agent
from app.models.approvals import Approval
@@ -44,6 +42,8 @@ from app.schemas.tasks import TaskCommentCreate, TaskCommentRead, TaskCreate, Ta
from app.services.activity_log import record_activity
from app.services.mentions import extract_mentions, matches_agent_mention
from app.services.openclaw.shared import (
GatewayClientConfig,
GatewayTransportError,
optional_gateway_config_for_board,
send_gateway_agent_message,
)
@@ -376,7 +376,7 @@ async def _notify_agent_on_task_assign(
task_id=task.id,
)
await session.commit()
except OpenClawGatewayError as exc:
except GatewayTransportError as exc:
record_activity(
session,
event_type="task.assignee_notify_failed",
@@ -447,7 +447,7 @@ async def _notify_lead_on_task_create(
task_id=task.id,
)
await session.commit()
except OpenClawGatewayError as exc:
except GatewayTransportError as exc:
record_activity(
session,
event_type="task.lead_notify_failed",
@@ -502,7 +502,7 @@ async def _notify_lead_on_task_unassigned(
task_id=task.id,
)
await session.commit()
except OpenClawGatewayError as exc:
except GatewayTransportError as exc:
record_activity(
session,
event_type="task.lead_unassigned_notify_failed",
@@ -1057,7 +1057,7 @@ async def _notify_task_comment_targets(
"If you are mentioned but not assigned, reply in the task "
"thread but do not change task status."
)
with suppress(OpenClawGatewayError):
with suppress(GatewayTransportError):
await _send_agent_task_message(
session_key=agent.openclaw_session_id,
config=config,

View File

@@ -1,88 +1,7 @@
"""OpenClaw lifecycle services package."""
"""OpenClaw lifecycle package.
from .admin_service import (
AbstractGatewayMainAgentManager,
DefaultGatewayMainAgentManager,
GatewayAdminLifecycleService,
)
from .agent_service import (
AbstractProvisionExecution,
ActorContextLike,
AgentLifecycleService,
AgentUpdateOptions,
AgentUpdateProvisionRequest,
AgentUpdateProvisionTarget,
BoardAgentProvisionExecution,
MainAgentProvisionExecution,
)
from .constants import DEFAULT_CHANNEL_HEARTBEAT_VISIBILITY, DEFAULT_HEARTBEAT_CONFIG
from .coordination_service import AbstractGatewayMessagingService, GatewayCoordinationService
from .exceptions import (
GatewayErrorPolicy,
GatewayOperation,
map_gateway_error_message,
map_gateway_error_to_http_exception,
)
from .onboarding_service import BoardOnboardingMessagingService
from .provisioning import (
AgentProvisionRequest,
LeadAgentOptions,
LeadAgentRequest,
MainAgentProvisionRequest,
ProvisionOptions,
cleanup_agent,
ensure_board_lead_agent,
patch_gateway_agent_heartbeats,
provision_agent,
provision_main_agent,
sync_gateway_agent_heartbeats,
)
from .session_service import GatewaySessionService, GatewayTemplateSyncQuery
from .shared import (
GatewayAgentIdentity,
optional_gateway_config_for_board,
require_gateway_config_for_board,
resolve_trace_id,
send_gateway_agent_message,
)
Import concrete modules directly (for example: ``app.services.openclaw.agent_service``)
to keep architectural boundaries explicit.
"""
__all__ = [
"AbstractGatewayMainAgentManager",
"DefaultGatewayMainAgentManager",
"GatewayAdminLifecycleService",
"AbstractProvisionExecution",
"ActorContextLike",
"AgentLifecycleService",
"AgentUpdateOptions",
"AgentUpdateProvisionRequest",
"AgentUpdateProvisionTarget",
"BoardAgentProvisionExecution",
"MainAgentProvisionExecution",
"DEFAULT_CHANNEL_HEARTBEAT_VISIBILITY",
"DEFAULT_HEARTBEAT_CONFIG",
"AbstractGatewayMessagingService",
"GatewayCoordinationService",
"GatewayErrorPolicy",
"GatewayOperation",
"map_gateway_error_message",
"map_gateway_error_to_http_exception",
"BoardOnboardingMessagingService",
"AgentProvisionRequest",
"LeadAgentOptions",
"LeadAgentRequest",
"MainAgentProvisionRequest",
"ProvisionOptions",
"cleanup_agent",
"ensure_board_lead_agent",
"patch_gateway_agent_heartbeats",
"provision_agent",
"provision_main_agent",
"sync_gateway_agent_heartbeats",
"GatewaySessionService",
"GatewayTemplateSyncQuery",
"GatewayAgentIdentity",
"optional_gateway_config_for_board",
"require_gateway_config_for_board",
"resolve_trace_id",
"send_gateway_agent_message",
]
__all__: list[str] = []

View File

@@ -8,8 +8,8 @@ from uuid import UUID, uuid4
from fastapi import HTTPException, status
from app.integrations.openclaw_gateway import GatewayConfig as GatewayClientConfig
from app.integrations.openclaw_gateway import ensure_session, send_message
from app.integrations.openclaw_gateway import GatewayConfig as _GatewayClientConfig
from app.integrations.openclaw_gateway import OpenClawGatewayError, ensure_session, send_message
from app.models.boards import Board
from app.models.gateways import Gateway
from app.services.openclaw.constants import (
@@ -22,6 +22,9 @@ if TYPE_CHECKING:
from sqlmodel.ext.asyncio.session import AsyncSession
GatewayClientConfig = _GatewayClientConfig
class GatewayAgentIdentity:
"""Naming and identity rules for Mission Control gateway-main agents."""
@@ -87,6 +90,28 @@ async def send_gateway_agent_message(
await send_message(message, session_key=session_key, config=config, deliver=deliver)
async def send_gateway_agent_message_safe(
*,
session_key: str,
config: GatewayClientConfig,
agent_name: str,
message: str,
deliver: bool = False,
) -> GatewayTransportError | None:
"""Best-effort gateway dispatch returning transport error when one occurs."""
try:
await send_gateway_agent_message(
session_key=session_key,
config=config,
agent_name=agent_name,
message=message,
deliver=deliver,
)
except GatewayTransportError as exc:
return exc
return None
def resolve_trace_id(correlation_id: str | None, *, prefix: str) -> str:
"""Resolve a stable trace id from correlation id or generate a scoped fallback."""
normalized = (correlation_id or "").strip()
@@ -96,3 +121,6 @@ def resolve_trace_id(correlation_id: str | None, *, prefix: str) -> str:
logger = logging.getLogger(__name__)
# Keep integration exceptions behind the OpenClaw service boundary.
GatewayTransportError = OpenClawGatewayError