refactor(agent): remove unused board ensure functionality and related classes

This commit is contained in:
Abhimanyu Saharan
2026-02-07 16:57:14 +05:30
parent 19869d98ae
commit 117048d637
3 changed files with 4 additions and 124 deletions

View File

@@ -5,7 +5,6 @@ from typing import Any, cast
from uuid import UUID
from fastapi import APIRouter, Depends, HTTPException, Query, status
from sqlalchemy import func
from sqlmodel import col, select
from sqlmodel.ext.asyncio.session import AsyncSession
@@ -43,8 +42,6 @@ from app.schemas.board_onboarding import BoardOnboardingAgentUpdate, BoardOnboar
from app.schemas.boards import BoardRead
from app.schemas.common import OkResponse
from app.schemas.gateway_coordination import (
GatewayBoardEnsureRequest,
GatewayBoardEnsureResponse,
GatewayLeadBroadcastBoardResult,
GatewayLeadBroadcastRequest,
GatewayLeadBroadcastResponse,
@@ -84,13 +81,6 @@ async def _gateway_config(session: AsyncSession, board: Board) -> GatewayClientC
return GatewayClientConfig(url=gateway.url, token=gateway.token)
def _slugify(value: str) -> str:
import re
slug = re.sub(r"[^a-z0-9]+", "-", value.lower()).strip("-")
return slug or "board"
async def _require_gateway_main(
session: AsyncSession,
agent: Agent,
@@ -594,90 +584,6 @@ async def ask_user_via_gateway_main(
)
@router.post("/gateway/boards/ensure", response_model=GatewayBoardEnsureResponse)
async def ensure_gateway_board(
payload: GatewayBoardEnsureRequest,
session: AsyncSession = Depends(get_session),
agent_ctx: AgentAuthContext = Depends(get_agent_auth_context),
) -> GatewayBoardEnsureResponse:
gateway, config = await _require_gateway_main(session, agent_ctx.agent)
requested_name = payload.name.strip()
requested_slug = _slugify(payload.slug.strip() if payload.slug else requested_name)
# Try slug match first, then case-insensitive name match.
existing = (
await session.exec(
select(Board)
.where(col(Board.gateway_id) == gateway.id)
.where(col(Board.slug) == requested_slug)
)
).first()
if existing is None:
existing = (
await session.exec(
select(Board)
.where(col(Board.gateway_id) == gateway.id)
.where(func.lower(col(Board.name)) == requested_name.lower())
)
).first()
created = False
board = existing
if board is None:
slug = requested_slug
suffix = 2
while True:
conflict = (
await session.exec(
select(Board.id)
.where(col(Board.gateway_id) == gateway.id)
.where(col(Board.slug) == slug)
)
).first()
if conflict is None:
break
slug = f"{requested_slug}-{suffix}"
suffix += 1
board = Board(
name=requested_name,
slug=slug,
gateway_id=gateway.id,
board_type=payload.board_type,
objective=payload.objective.strip() if payload.objective else None,
success_metrics=payload.success_metrics,
target_date=payload.target_date,
goal_confirmed=False,
goal_source="gateway_main_agent",
)
session.add(board)
await session.commit()
await session.refresh(board)
created = True
lead, lead_created = await ensure_board_lead_agent(
session,
board=board,
gateway=gateway,
config=config,
user=None,
agent_name=payload.lead_agent_name.strip() if payload.lead_agent_name else None,
identity_profile=payload.lead_identity_profile,
action="provision",
)
return GatewayBoardEnsureResponse(
created=created,
lead_created=lead_created,
board_id=board.id,
lead_agent_id=lead.id,
board_name=board.name,
board_slug=board.slug,
lead_agent_name=lead.name,
)
@router.post(
"/gateway/boards/{board_id}/lead/message",
response_model=GatewayLeadMessageResponse,

View File

@@ -1,6 +1,5 @@
from __future__ import annotations
from datetime import datetime
from typing import Literal
from uuid import UUID
@@ -9,29 +8,6 @@ from sqlmodel import Field, SQLModel
from app.schemas.common import NonEmptyStr
class GatewayBoardEnsureRequest(SQLModel):
name: NonEmptyStr
slug: str | None = None
board_type: Literal["goal", "general"] = "goal"
objective: str | None = None
success_metrics: dict[str, object] | None = None
target_date: datetime | None = None
lead_agent_name: str | None = None
lead_identity_profile: dict[str, str] | None = None
class GatewayBoardEnsureResponse(SQLModel):
created: bool = False
lead_created: bool = False
board_id: UUID
lead_agent_id: UUID | None = None
# Convenience fields for callers that don't want to re-fetch.
board_name: str
board_slug: str
lead_agent_name: str | None = None
class GatewayLeadMessageRequest(SQLModel):
kind: Literal["question", "handoff"] = "question"
correlation_id: str | None = None

View File

@@ -29,19 +29,17 @@ Do this immediately. Do not ask permission to read your workspace.
## Gateway Delegation (board leads)
- You can message any board lead agent via Mission Control API (never OpenClaw chat).
- If the requested board does not exist, you must create it and provision its lead agent first.
- You cannot create boards. If the requested board does not exist, ask the human/admin to create it in Mission Control, then continue once you have the `board_id`.
- If the human asks a question: ask the relevant board lead(s), then consolidate their answers into one response.
- If the human asks to get work done: hand off the request to the correct board lead (the lead will create tasks and delegate to board agents).
Ensure (create if needed) a board + lead:
List boards (to find `board_id`):
```bash
curl -s -X POST "$BASE_URL/api/v1/agent/gateway/boards/ensure" \
curl -s -X GET "$BASE_URL/api/v1/agent/boards" \
-H "X-Agent-Token: $AUTH_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"<Board Name>","slug":"<optional-slug>","board_type":"goal","objective":"<optional>","success_metrics":null,"target_date":null}'
```
Send a question or handoff to a board lead:
Send a question or handoff to a board lead (auto-provisions the lead agent if missing):
```bash
curl -s -X POST "$BASE_URL/api/v1/agent/gateway/boards/<BOARD_ID>/lead/message" \
-H "X-Agent-Token: $AUTH_TOKEN" \