refactor: enforce architectural boundaries by updating OpenClaw service imports
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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}",
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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] = []
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user