feat: Agent System Prompts MVP (B) - database, backend API, and frontend integration
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user