# TASK_PHASE_AGENT_MANAGEMENT_v1 ## Title TASK_PHASE_AGENT_MANAGEMENT_v1 — Agent Create/Delete + Crew Teams Integration ## 1. Overview Implement full lifecycle management for DAARION agents: * Create agent * Delete agent * Assign to: * Node * MicroDAO * District (city zone) * Crew (team) * Prepare room integration for CrewAI teams (each crew has its own room). This task **does not** change runtime orchestration logic (NATS, Router, etc.) — only registry & UI. --- ## 2. Current State * Database: * Table `agents` already exists (used by city-service). * There is a `sync-node2-dagi-agents.py` script populating 50 agents for NODE2 from `agents_city_mapping.yaml`. * Backend: * `repo_city.get_node_agents(node_id)` returns agents for Node Cabinet. * `repo_city.get_agents(...)` provides listing for `/agents` UI. * Existing fields: * `node_id` * `district` * `primary_room_slug` * `model` * `is_public` * `home_node_id` * `home_microdao_id` * `crew_team_key` * Frontend: * `/agents` page lists agents with: * status (online/offline) * node badge (НОДА1 / НОДА2) * visibility badges (Personal / Public) * `/agents/[slug]` has Identity tab with visibility toggles. * No button to create or delete an agent from UI. --- ## 3. Goals 1. **Create agent** from UI: * Minimal form. * Pre-fill microDAO/context when creation initiated from MicroDAO. 2. **Delete agent** from UI: * Soft-delete (mark as deleted/archived). 3. **Crew / Team attribute**: * Each agent may belong to a `crew_team_key`. 4. Prepare for **Crew rooms** integration: * For each crew (unique `crew_team_key`) we can later auto-create a room. --- ## 4. Database & Backend Tasks ### 4.1. Verify agents table fields Existing fields to use: * `node_id` - which node agent belongs to * `home_node_id` - home node * `home_microdao_id` - home MicroDAO * `district` - city district key * `crew_team_key` - crew/team key * `is_archived` - soft delete flag * `deleted_at` - deletion timestamp ### 4.2. Models & Repo `services/city-service/models_city.py`: ```python class CreateAgentRequest(BaseModel): slug: str display_name: str kind: str = "assistant" role: Optional[str] model: Optional[str] node_id: Optional[str] home_microdao_id: Optional[str] district: Optional[str] crew_team_key: Optional[str] is_public: bool = False avatar_url: Optional[str] color_hint: Optional[str] ``` `services/city-service/repo_city.py`: ```python async def create_agent(data: dict) -> dict: """Create new agent in database""" pool = await get_pool() # INSERT INTO agents ... async def delete_agent(agent_id: str) -> bool: """Soft delete agent (set is_archived=true, deleted_at=now())""" pool = await get_pool() # UPDATE agents SET is_archived = true, deleted_at = NOW() WHERE id = $1 ``` ### 4.3. API routes `services/city-service/routes_city.py`: ```python @router.post("/city/agents") async def create_agent(body: CreateAgentRequest): """Create new agent""" # Validate slug uniqueness # Insert into database # Return created agent @router.delete("/city/agents/{agent_id}") async def delete_agent(agent_id: str): """Soft delete agent""" # Set is_archived = true, deleted_at = now() return {"ok": True, "message": "Agent archived"} ``` --- ## 5. Frontend Tasks Files: * `apps/web/src/app/agents/page.tsx` * `apps/web/src/app/agents/new/page.tsx` (new) * `apps/web/src/app/microdao/[slug]/page.tsx` * `apps/web/src/app/agents/[agentId]/page.tsx` ### 5.1. API client ```ts // lib/api/agents.ts export async function createAgent(payload: CreateAgentPayload) { return apiClient.post('/city/agents', payload); } export async function deleteAgent(id: string) { return apiClient.delete(`/city/agents/${id}`); } ``` ### 5.2. "New Agent" page 1. On `/agents` page: * Add button `+ Новий агент` in header. * Click → navigate to `/agents/new`. 2. New page `/agents/new`: Form fields: * Ім'я (`display_name`, required) * Slug (auto-generated from name, editable) * Роль / Title (optional) * Тип агента (`kind`: orchestrator, assistant, specialist, etc.) * Нода (select: NODE1, NODE2 — fetch from `/nodes`) * MicroDAO (dropdown, fetch from `/microdao`) * Район (dropdown: leadership, security, engineering, etc.) * Команда / Crew (free text or dropdown) * Модель (optional: list of Swapper models) * Видимість: * `is_public` (switch, default false) * Аватар URL (optional) * Колір (optional color picker) On submit: * POST `/city/agents` * Redirect to `/agents/[slug]`. ### 5.3. "Create Agent" from MicroDAO On `/microdao/[slug]`: * In "Агенти MicroDAO" section, add button: ```tsx ``` * On `/agents/new`: * If query `?microdao=...` present — pre-fill MicroDAO field. ### 5.4. Delete Agent action On `/agents/[agentId]`: * Add "Видалити агента" button in settings/danger section. Flow: * Confirm dialog: "Видалити агента? Його не буде видно у місті." * On confirm → `DELETE /city/agents/{id}`. * After success: redirect to `/agents` with toast. --- ## 6. Crew Teams (Preparation) This task prepares data for Crew rooms: * Each agent can have `crew_team_key`. * Display `crew_team_key` as badge on agent card. * Later: auto-create room for each unique `crew_team_key`. --- ## 7. Acceptance Criteria 1. `/agents` page has `+ Новий агент` button. 2. `/agents/new` allows creating a new agent. 3. `/microdao/[slug]` has "Створити агента" button. 4. `/agents/[agentId]` has "Видалити агента" button. 5. Deleted agents disappear from listings. 6. `crew_team_key` is visible on agent cards.