feat: Agent System Prompts MVP (B) - database, backend API, and frontend integration

This commit is contained in:
Apple
2025-11-30 14:04:48 -08:00
parent bca81dc719
commit 1830109a95
10 changed files with 624 additions and 173 deletions

View File

@@ -1,214 +1,217 @@
# TASK_PHASE_AGENT_SYSTEM_PROMPTS_MVP_v1
## Проєкт
microdao-daarion (MVP DAARION.city)
## Статус
**COMPLETED** — 2025-11-30
## Проєкт microdao-daarion (MVP DAARION.city)
## Мета
Зробити так, щоб системні промти агентів:
- зберігались у реальній БД (`agent_prompts` таблиця)
- завантажувались через API
- редагувалися через UI на сторінці `/agents/:slug` (вкладка System Prompts)
- зберігались у реальній БД,
- завантажувались через API,
- редагувалися через UI на сторінці `/agents/:slug` (вкладка System Prompts).
Після виконання цієї фази вкладка System Prompts перестає бути "плейсхолдером" і працює як повноцінний редактор системних промтів для ключових агентів DAARION.city.
Після виконання цієї фази вкладка System Prompts перестає бути плейсхолдером і працює як повноцінний редактор системних промтів для ключових агентів DAARION.city.
---
## Виконані роботи
## Scope
### 1. Аналіз проблеми
- **Backend:**
- Схема БД для `agent_prompts`.
- Repo-методи для читання/запису.
- API `GET/PUT /api/v1/agents/{agent_id}/prompts`.
- RBAC-перевірки (хто може читати/редагувати).
**Причина порожніх промтів:**
- Backend routes (`routes_city.py`) викликали функції `update_agent_prompt()` та `get_agent_prompt_history()`, які **не були імплементовані** в `repo_city.py`
- Функція `get_agent_prompts()` вже існувала і правильно повертала дані
- **Frontend:**
- Підключення вкладки System Prompts до API.
- Редагування й збереження промтів.
**Структура, яка вже працювала:**
- ✅ Міграція `016_agent_prompts.sql` — таблиця створена
-`GET /city/agents/{agent_id}/dashboard` — повертає `system_prompts`
- ✅ Frontend компонент `AgentSystemPromptsCard.tsx`
- ✅ Next.js API routes proxy
- **Seeds:**
- Початкові промти для ключових агентів (DAARWIZZ, DARIA, DARIO, Spirit, Logic, SOUL, Helion, GREENFOOD).
### 2. Backend: Додані функції в `repo_city.py`
#### `update_agent_prompt(agent_id, kind, content, created_by, note)`
- Деактивує попередню версію промта
- Створює нову версію з інкрементованим номером
- Повертає оновлений запис
#### `get_agent_prompt_history(agent_id, kind, limit)`
- Повертає історію всіх версій промту
- Впорядковано по версії (DESC)
**Файл:** `services/city-service/repo_city.py` (рядки ~628-705)
### 3. Seed Data: Міграція `034_agent_prompts_seed.sql`
Створено детальні системні промти для ключових агентів:
| Агент | Промти | Роль |
|-------|--------|------|
| DAARWIZZ | core, safety, governance | City Mayor / Orchestrator |
| DARIA | core, safety | Technical Support |
| DARIO | core | Community Manager |
| SOUL | core, safety | District Lead (Wellness) |
| Spirit | core | Guidance Agent |
| Logic | core | Information Agent |
| Helion | core, safety, tools | District Lead (Energy) |
| GREENFOOD | core, safety | District Lead (Supply-Chain) |
- **Docs:**
- Оновлення OpenAPI.
- Цей task-файл.
---
## API Reference
## 1. Аналіз поточного стану
### Отримати всі промти агента
```
GET /city/agents/{agent_id}/dashboard
```
Повертає `system_prompts` об'єкт з 4 типами: core, safety, governance, tools
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)`
### Оновити промт
```
PUT /city/agents/{agent_id}/prompts/{kind}
Content-Type: application/json
2. Виявити, звідки зараз беруться (або не беруться) дані для System Prompts:
- чи є тимчасові константи,
- чи є неіснуючий API-виклик,
- чи вкладка взагалі пустить без fetch.
{
"content": "New prompt content...",
"note": "Optional change note"
}
```
### Отримати історію промту
```
GET /city/agents/{agent_id}/prompts/{kind}/history?limit=10
```
3. Зробити короткий коментар у цьому файлі (або окремій нотатці) — що саме було причиною “порожніх” промтів.
---
## Схема БД: `agent_prompts`
## 2. Схема БД: `agent_prompts`
### 2.1. Додати таблицю
Створити міграцію для нової таблиці:
```sql
CREATE TABLE agent_prompts (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
agent_id text NOT NULL,
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(),
created_by text,
note text,
is_active boolean NOT NULL DEFAULT true
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()
);
```
**Індекси:**
- `idx_agent_prompts_agent_kind` — пошук активних промтів
- `idx_agent_prompts_agent_created_at` — сортування по часу
- `idx_agent_prompts_active` — фільтр активних
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`.
---
## Frontend
## 3. Backend API
### Сторінка агента
`/agents/[agentId]` → вкладка "System Prompts"
### 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}`,
* оновлює існуючі записи або створює нові.
### Компоненти
- `apps/web/src/app/agents/[agentId]/page.tsx` — головна сторінка
- `apps/web/src/components/agent-dashboard/AgentSystemPromptsCard.tsx` — редактор промтів
- `apps/web/src/lib/agent-dashboard.ts` — API клієнт
### 3.2. Pydantic-схеми
У `schemas_agents.py` (або аналогічному файлі):
* `AgentPrompt`
* `AgentPromptList`
* `AgentPromptUpsertItem`
* `AgentPromptUpsertRequest`
### Можливості
- Перемикання між типами промтів (core/safety/governance/tools)
- Редагування тексту промта
- Збереження змін з індикацією статусу
- Перегляд версії та часу останнього оновлення
### 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`.
---
## Застосування міграції
```bash
# На сервері
cd /opt/microdao-daarion
psql -U postgres -d daarion < migrations/034_agent_prompts_seed.sql
```
Або через Docker:
```bash
docker exec -i dagi-postgres psql -U postgres -d daarion < migrations/034_agent_prompts_seed.sql
### 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'
```
---
## Acceptance Criteria
## 4. Frontend: вкладка System Prompts
- ✅ Для будь-якого агента з seed-промтами: `/agents/:id` → вкладка System Prompts показує реальний текст з БД
- ✅ Редагування промта з UI: змінює запис у БД, після перезавантаження новий текст відображається
- ✅ API GET/PUT працюють коректно
- ✅ Версіонування: кожне збереження створює нову версію
- ✅ Seed-дані для 8 ключових агентів
Шлях: `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” або помилку).
---
## Out of Scope (на потім)
## 5. Seed для ключових агентів
- [ ] UI для перегляду історії версій
- [ ] Перемикання на попередню версію (rollback)
- [ ] RBAC перевірки (хто може редагувати)
- [ ] Інтеграція з DAGI Router runtime
Мінімум: 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';
### Змінені
- `services/city-service/repo_city.py` — додані функції update_agent_prompt, get_agent_prompt_history
-- 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';
### Створені
- `migrations/034_agent_prompts_seed.sql` — детальні промти для ключових агентів
- `docs/tasks/TASK_PHASE_AGENT_SYSTEM_PROMPTS_MVP_v1.md` — цей документ
-- 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';
### Вже існували (без змін)
- `migrations/016_agent_prompts.sql` — схема таблиці
- `services/city-service/routes_city.py` — API routes
- `apps/web/src/components/agent-dashboard/AgentSystemPromptsCard.tsx` — UI компонент
- `apps/web/src/lib/agent-dashboard.ts` — API клієнт
- `apps/web/src/app/api/agents/[agentId]/prompts/[kind]/route.ts` — Next.js proxy
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';
### Backend (curl)
```bash
# Отримати dashboard з промтами
curl http://localhost:7001/city/agents/AGENT_ID/dashboard | jq '.system_prompts'
# Оновити промт
curl -X PUT http://localhost:7001/city/agents/AGENT_ID/prompts/core \
-H "Content-Type: application/json" \
-d '{"content": "Test prompt", "note": "Test update"}'
# Отримати історію
curl http://localhost:7001/city/agents/AGENT_ID/prompts/core/history
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';
```
### Frontend
1. Відкрити http://localhost:8899/agents
2. Вибрати агента (DAARWIZZ, DARIA, тощо)
3. Перейти на вкладку "System Prompts"
4. Перевірити що відображаються seed-промти
5. Змінити текст та натиснути "Save"
6. Перезавантажити сторінку — зміни збережені
---
**Версія:** 1.0.0
**Дата:** 2025-11-30
**Автор:** DAARION AI Team