Labels on AgentConfig + auto-assign by labels
Some checks failed
Deploy Tracker / deploy (push) Failing after 4s

- AgentConfig.labels ARRAY(String) field
- Auto-assign matches task labels ↔ agent labels (not capabilities)
- labels in AgentConfigOut, auth.ok, config.updated
This commit is contained in:
markov 2026-02-28 00:47:09 +01:00
parent 009789ad8b
commit c1fd50f28c
6 changed files with 11 additions and 2 deletions

View File

@ -35,6 +35,7 @@ def member_out(m: Member) -> MemberOut:
if m.agent_config:
agent_cfg = AgentConfigOut(
capabilities=m.agent_config.capabilities or [],
labels=m.agent_config.labels or [],
chat_listen=m.agent_config.chat_listen,
task_listen=m.agent_config.task_listen,
prompt=m.agent_config.prompt,

View File

@ -23,6 +23,7 @@ router = APIRouter(tags=["members"])
class AgentConfigSchema(BaseModel):
capabilities: list[str] = []
labels: list[str] = []
chat_listen: str = ListenMode.MENTIONS
task_listen: str = ListenMode.MENTIONS
prompt: str | None = None
@ -130,6 +131,7 @@ async def create_member(req: MemberCreate, db: AsyncSession = Depends(get_db)):
if req.agent_config:
agent_cfg = AgentConfigOut(
capabilities=req.agent_config.capabilities,
labels=req.agent_config.labels,
chat_listen=req.agent_config.chat_listen,
task_listen=req.agent_config.task_listen,
prompt=req.agent_config.prompt,
@ -167,6 +169,8 @@ async def update_member(member_id: str, req: MemberUpdate, db: AsyncSession = De
ac = req.agent_config
if ac.capabilities is not None:
member.agent_config.capabilities = ac.capabilities
if ac.labels is not None:
member.agent_config.labels = ac.labels
if ac.chat_listen is not None:
member.agent_config.chat_listen = ac.chat_listen
if ac.task_listen is not None:
@ -195,6 +199,7 @@ async def update_member(member_id: str, req: MemberUpdate, db: AsyncSession = De
"task_listen": ac.task_listen,
"max_concurrent_tasks": ac.max_concurrent_tasks,
"capabilities": ac.capabilities or [],
"labels": ac.labels or [],
},
})

View File

@ -82,6 +82,7 @@ class MessageOut(BaseModel):
class AgentConfigOut(BaseModel):
capabilities: list[str] = []
labels: list[str] = []
chat_listen: str
task_listen: str
prompt: str | None = None

View File

@ -308,8 +308,8 @@ async def create_task(
)
)
for agent, config in agents_q:
caps = config.capabilities or []
if any(label in caps for label in req.labels):
agent_labels = config.labels or []
if any(label in agent_labels for label in req.labels):
task.assignee_id = agent.id
task.watcher_ids = [agent.id]
break

View File

@ -44,6 +44,7 @@ class AgentConfig(Base):
UUID(as_uuid=True), ForeignKey("members.id"), nullable=False, unique=True
)
capabilities: Mapped[list[str]] = mapped_column(ARRAY(String), default=list)
labels: Mapped[list[str]] = mapped_column(ARRAY(String), default=list) # for auto-assign matching
chat_listen: Mapped[str] = mapped_column(String(20), default=ListenMode.MENTIONS) # all | mentions | none
task_listen: Mapped[str] = mapped_column(String(20), default=ListenMode.MENTIONS) # all | mentions | none
prompt: Mapped[str | None] = mapped_column(Text)

View File

@ -265,6 +265,7 @@ async def _authenticate(ws: WebSocket, token: str, on_behalf_of: str | None = No
"task_listen": ac.task_listen,
"max_concurrent_tasks": ac.max_concurrent_tasks,
"capabilities": ac.capabilities or [],
"labels": ac.labels or [],
}
await ws.send_json({