# TASK_PHASE_AGENT_SYSTEM_PROMPTS_MVP_v1 ## Проєкт microdao-daarion (MVP DAARION.city) ## Мета Зробити так, щоб системні промти агентів: - зберігались у реальній БД, - завантажувались через API, - редагувалися через UI на сторінці `/agents/:slug` (вкладка System Prompts). Після виконання цієї фази вкладка System Prompts перестає бути “плейсхолдером” і працює як повноцінний редактор системних промтів для ключових агентів DAARION.city. --- ## Scope - **Backend:** - Схема БД для `agent_prompts`. - Repo-методи для читання/запису. - API `GET/PUT /api/v1/agents/{agent_id}/prompts`. - RBAC-перевірки (хто може читати/редагувати). - **Frontend:** - Підключення вкладки System Prompts до API. - Редагування й збереження промтів. - **Seeds:** - Початкові промти для ключових агентів (DAARWIZZ, DARIA, DARIO, Spirit, Logic, SOUL, Helion, GREENFOOD). - **Docs:** - Оновлення OpenAPI. - Цей task-файл. --- ## 1. Аналіз поточного стану 1. Перевірити існуючий код: - Frontend: - `apps/web/src/app/agents/[agentSlug]/(tabs)/system-prompts` - Backend: - `routes_agents.py` - `repo_city.py` (або окремий репозиторій для агентів) - Data Model / API: - `microdao — Data Model & Event Catalog` - `microdao — API Specification (OpenAPI 3.1, MVP)` 2. Виявити, звідки зараз беруться (або не беруться) дані для System Prompts: - чи є тимчасові константи, - чи є неіснуючий API-виклик, - чи вкладка взагалі пустить без fetch. 3. Зробити короткий коментар у цьому файлі (або окремій нотатці) — що саме було причиною “порожніх” промтів. --- ## 2. Схема БД: `agent_prompts` ### 2.1. Додати таблицю Створити міграцію для нової таблиці: ```sql create table agent_prompts ( id text primary key, agent_id text not null references agents(id) on delete cascade, kind text not null check (kind in ('core','safety','governance','tools')), content text not null, version integer not null default 1, created_at timestamptz not null default now(), updated_at timestamptz not null default now() ); create unique index ux_agent_prompts_agent_kind on agent_prompts(agent_id, kind); create index ix_agent_prompts_agent on agent_prompts(agent_id); ``` MVP: тримаємо один активний запис на `(agent_id, kind)`. ### 2.2. Інтеграція з Data Model Оновити `microdao — Data Model & Event Catalog`: * Додати сутність `agent_prompts`: * `id`, `agent_id`, `kind`, `content`, `version`, `created_at`, `updated_at`. * Вказати зв’язок `agents 1:N agent_prompts`. --- ## 3. Backend API ### 3.1. Repo-методи У `repo_city.py` або окремому модулі для агентів: * `get_agent_prompts(agent_id: str) -> List[dict]`: * повертає список промтів по агенту (останній запис по кожному `kind`). * `upsert_agent_prompts(agent_id: str, prompts: List[dict]) -> List[dict]`: * приймає масив `{kind, content}`, * оновлює існуючі записи або створює нові. ### 3.2. Pydantic-схеми У `schemas_agents.py` (або аналогічному файлі): * `AgentPrompt` * `AgentPromptList` * `AgentPromptUpsertItem` * `AgentPromptUpsertRequest` ### 3.3. Routes У `routes_agents.py`: * `GET /api/v1/agents/{agent_id}/prompts` * `response_model=AgentPromptList` * Перевіряє, що агент існує. * RBAC: Owner/Guardian команди (або інша політика, узгоджена з RBAC-документом). * `PUT /api/v1/agents/{agent_id}/prompts` * `request_body=AgentPromptUpsertRequest` * Оновлює/створює промти. * Повертає оновлений `AgentPromptList`. ### 3.4. OpenAPI Оновити `microdao — API Specification (OpenAPI 3.1, MVP)`: ```yaml /agents/{agentId}/prompts: parameters: - name: agentId in: path required: true schema: { type: string } get: tags: [Agents] summary: Отримати системні промти агента responses: '200': description: Prompts content: application/json: schema: $ref: '#/components/schemas/AgentPromptList' put: tags: [Agents] summary: Оновити системні промти агента requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/AgentPromptUpsertRequest' responses: '200': description: Prompts content: application/json: schema: $ref: '#/components/schemas/AgentPromptList' ``` --- ## 4. Frontend: вкладка System Prompts Шлях: `apps/web/src/app/agents/[agentSlug]/(tabs)/system-prompts` ### 4.1. Data hook Створити `useAgentPrompts(agentId)`: * Використати SWR або React Query (у відповідності до існуючого підходу в проєкті). * Ендпоінт: `GET /api/v1/agents/{agent_id}/prompts`. ### 4.2. System Prompts Tab Оновити компонент вкладки так, щоб: * при `agentSlug` → завантажувався `agent` (id, name, role, …), * при наявному `agent.id` → дергався `useAgentPrompts(agent.id)`, * рендерились textarea/редактори для 4 типів: * `core`, `safety`, `governance`, `tools`, * при натисканні “Save”: * `PUT /api/v1/agents/{agent_id}/prompts` * ті `kind`, де `content` не порожній, * показувати стани `loading`, `success`, `error`. UX: * Показати невеликий description, що ці промти використовуються DAGI Router / agent runtime. * Не дозволяти редагувати, якщо немає прав (403 → показати “Read only” або помилку). --- ## 5. Seed для ключових агентів Мінімум: DAARWIZZ, DARIA, DARIO, Spirit, Logic, SOUL, Helion, GREENFOOD. Формат — будь-який твій існуючий `seed_agents.py` / SQL seed / fixture. Приклад SQL (скорочений, умовні промти): ```sql -- DAARWIZZ — глобальний оркестратор insert into agent_prompts (id, agent_id, kind, content, version) select 'ap_daarwizz_core', a.id, 'core', $$You are DAARWIZZ, the global orchestrator of DAARION.city. Coordinate specialized agents, route tasks, and preserve safety and governance constraints.$$, 1 from agents a where a.slug = 'daarwizz'; insert into agent_prompts (id, agent_id, kind, content, version) select 'ap_daarwizz_safety', a.id, 'safety', $$Always respect user consent, DAARION.city security policies, and never execute irreversible actions without explicit confirmation.$$, 1 from agents a where a.slug = 'daarwizz'; -- DARIA / DARIO — city guides insert into agent_prompts (id, agent_id, kind, content, version) select 'ap_daria_core', a.id, 'core', $$You are DARIA, a guide of DAARION.city. Explain the city, districts, MicroDAO and how to start.$$, 1 from agents a where a.slug = 'daria'; -- Spirit / Logic / SOUL — SOUL district insert into agent_prompts (id, agent_id, kind, content, version) select 'ap_soul_core', a.id, 'core', $$You are SOUL, the narrative and alignment core of DAARION.city. Maintain brand philosophy and ethics.$$, 1 from agents a where a.slug = 'soul'; insert into agent_prompts (id, agent_id, kind, content, version) select 'ap_spirit_core', a.id, 'core', $$You are Spirit, creative strategist and story weaver for DAARION.city.$$, 1 from agents a where a.slug = 'spirit'; insert into agent_prompts (id, agent_id, kind, content, version) select 'ap_logic_core', a.id, 'core', $$You are Logic, rational analyst for DAARION.city. You validate assumptions, models and numbers.$$, 1 from agents a where a.slug = 'logic'; -- Helion / GREENFOOD insert into agent_prompts (id, agent_id, kind, content, version) select 'ap_helion_core', a.id, 'core', $$You are Helion, coordinator of Energy Union district. Focus on KWT, energy RWA and grids.$$, 1 from agents a where a.slug = 'helion'; insert into agent_prompts (id, agent_id, kind, content, version) select 'ap_greenfood_core', a.id, 'core', $$You are GREENFOOD ERP agent, optimizing supply chains and cooperative logistics for craft food producers.$$, 1 from agents a where a.slug = 'greenfood-erp'; ```