refactor: streamline agent lifecycle management with new DB service helpers

This commit is contained in:
Abhimanyu Saharan
2026-02-11 01:13:10 +05:30
parent f4161494d9
commit f1038acf44
17 changed files with 377 additions and 350 deletions

View 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]}"