Skip to content

# 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. Перевірити існуючий код:
2. Frontend:
   - `apps/web/src/app/agents/[agentSlug]/(tabs)/system-prompts`
3. Backend:
   - `routes_agents.py`
   - `repo_city.py` (або окремий репозиторій для агентів)

4. Data Model / API:

   - `microdao — Data Model & Event Catalog`
   - `microdao — API Specification (OpenAPI 3.1, MVP)`

5. Виявити, звідки зараз беруться (або не беруться) дані для System Prompts:

6. чи є тимчасові константи,
7. чи є неіснуючий API-виклик,

8. чи вкладка взагалі пустить без fetch.

9. Зробити короткий коментар у цьому файлі (або окремій нотатці) — що саме було причиною “порожніх” промтів.

## 2. Схема БД: `agent_prompts`

### 2.1. Додати таблицю

Створити міграцію для нової таблиці:

    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)`:

    /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 (скорочений, умовні промти):

    -- 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';