refactor: streamline agent lifecycle management with new DB service helpers
This commit is contained in:
89
backend/app/services/openclaw/gateway_dispatch.py
Normal file
89
backend/app/services/openclaw/gateway_dispatch.py
Normal file
@@ -0,0 +1,89 @@
|
||||
"""DB-backed gateway config resolution and message dispatch helpers.
|
||||
|
||||
This module exists to keep `app.api.*` thin: APIs should call OpenClaw services, not
|
||||
directly orchestrate gateway RPC calls.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from uuid import uuid4
|
||||
|
||||
from fastapi import HTTPException, status
|
||||
|
||||
from app.models.boards import Board
|
||||
from app.models.gateways import Gateway
|
||||
from app.services.openclaw.db_service import OpenClawDBService
|
||||
from app.services.openclaw.gateway_rpc import GatewayConfig as GatewayClientConfig
|
||||
from app.services.openclaw.gateway_rpc import OpenClawGatewayError, ensure_session, send_message
|
||||
|
||||
|
||||
class GatewayDispatchService(OpenClawDBService):
|
||||
"""Resolve gateway config for boards and dispatch messages to agent sessions."""
|
||||
|
||||
async def optional_gateway_config_for_board(
|
||||
self,
|
||||
board: Board,
|
||||
) -> GatewayClientConfig | None:
|
||||
if board.gateway_id is None:
|
||||
return None
|
||||
gateway = await Gateway.objects.by_id(board.gateway_id).first(self.session)
|
||||
if gateway is None or not gateway.url:
|
||||
return None
|
||||
return GatewayClientConfig(url=gateway.url, token=gateway.token)
|
||||
|
||||
async def require_gateway_config_for_board(
|
||||
self,
|
||||
board: Board,
|
||||
) -> tuple[Gateway, GatewayClientConfig]:
|
||||
if board.gateway_id is None:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
|
||||
detail="Board is not attached to a gateway",
|
||||
)
|
||||
gateway = await Gateway.objects.by_id(board.gateway_id).first(self.session)
|
||||
if gateway is None or not gateway.url:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
|
||||
detail="Gateway is not configured for this board",
|
||||
)
|
||||
return gateway, GatewayClientConfig(url=gateway.url, token=gateway.token)
|
||||
|
||||
async def send_agent_message(
|
||||
self,
|
||||
*,
|
||||
session_key: str,
|
||||
config: GatewayClientConfig,
|
||||
agent_name: str,
|
||||
message: str,
|
||||
deliver: bool = False,
|
||||
) -> None:
|
||||
await ensure_session(session_key, config=config, label=agent_name)
|
||||
await send_message(message, session_key=session_key, config=config, deliver=deliver)
|
||||
|
||||
async def try_send_agent_message(
|
||||
self,
|
||||
*,
|
||||
session_key: str,
|
||||
config: GatewayClientConfig,
|
||||
agent_name: str,
|
||||
message: str,
|
||||
deliver: bool = False,
|
||||
) -> OpenClawGatewayError | None:
|
||||
try:
|
||||
await self.send_agent_message(
|
||||
session_key=session_key,
|
||||
config=config,
|
||||
agent_name=agent_name,
|
||||
message=message,
|
||||
deliver=deliver,
|
||||
)
|
||||
except OpenClawGatewayError as exc:
|
||||
return exc
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def resolve_trace_id(correlation_id: str | None, *, prefix: str) -> str:
|
||||
normalized = (correlation_id or "").strip()
|
||||
if normalized:
|
||||
return normalized
|
||||
return f"{prefix}:{uuid4().hex[:12]}"
|
||||
Reference in New Issue
Block a user