Files
microdao-daarion/docs/tasks/PHASE3_MASTER_TASK.md
Apple 744c149300
Some checks failed
Build and Deploy Docs / build-and-deploy (push) Has been cancelled
Add automated session logging system
- Created logs/ structure (sessions, operations, incidents)
- Added session-start/log/end scripts
- Installed Git hooks for auto-logging commits/pushes
- Added shell integration for zsh
- Created CHANGELOG.md
- Documented today's session (2026-01-10)
2026-01-10 04:53:17 -08:00

516 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# TASK: PHASE 3 — LLM PROXY + MEMORY ORCHESTRATOR + TOOLCORE
**Goal:**
Зробити агентів DAARION по-справжньому розумними та інструментальними:
- єдиний LLM Proxy з підтримкою кількох провайдерів і локальних моделей;
- Memory Orchestrator, який дає єдиний API для памʼяті агентів;
- Toolcore — реєстр інструментів і безпечне виконання tools для агентів.
**PHASE 3 = інфраструктура мислення й дії для Agent Runtime.**
**Existing (assume from Phase 12):**
- messaging-service, matrix-gateway, Messenger UI.
- agent-filter, DAGI Router (router.invoke.agent).
- agent-runtime (використовує /internal/llm/proxy та /internal/agent-memory/*, але поки можуть бути stubs).
- базова БД (users, microdaos, agents, channels, messages, etc.).
- NATS JetStream, PostgreSQL, docker-compose.
**Deliverables:**
1. services/llm-proxy/ — LLM Router + Providers + Logging.
2. services/memory-orchestrator/ — єдиний API для памʼяті агентів.
3. services/toolcore/ — registry + execution engine для tools.
4. Інтеграція з agent-runtime.
5. Оновлення docker-compose та docs.
---
## 1) SERVICE: LLM PROXY (services/llm-proxy)
**Create folder:**
```
services/llm-proxy/
main.py
models.py
router.py
providers/
__init__.py
openai_provider.py
deepseek_provider.py
local_provider.py
config.yaml
middlewares.py
logging_middleware.py
Dockerfile
requirements.txt
README.md
```
### 1.1 API
**Base URL (internal-only):**
- `POST /internal/llm/proxy`
**Request (v1):**
```json
{
"model": "gpt-4.1-mini",
"messages": [
{ "role": "system", "content": "..." },
{ "role": "user", "content": "..." }
],
"metadata": {
"agent_id": "agent:sofia",
"microdao_id": "microdao:7",
"channel_id": "..."
}
}
```
**Response:**
```json
{
"content": "текст відповіді",
"usage": {
"prompt_tokens": 123,
"completion_tokens": 45,
"total_tokens": 168
},
"provider": "openai",
"model_resolved": "gpt-4.1-mini"
}
```
**Optional (stub for later):**
- `/internal/llm/batch`
- `/internal/llm/stream` (можна залишити TODO)
### 1.2 Model routing (router.py)
Створити модуль:
```python
def route_model(logical_model: str) -> ProviderConfig:
# Читає зі структури в config.yaml
# Напр.:
# - gpt-4.1-mini → OpenAI (gpt-4.1-mini)
# - deepseek-r1 → DeepSeek API
# - dagi-local-8b → Local provider (Ollama / vllm)
```
**config.yaml (приклад):**
```yaml
providers:
openai:
base_url: "https://api.openai.com/v1"
api_key_env: "OPENAI_API_KEY"
deepseek:
base_url: "https://api.deepseek.com/v1"
api_key_env: "DEEPSEEK_API_KEY"
local:
base_url: "http://local-llm:8000"
models:
gpt-4.1-mini:
provider: "openai"
name: "gpt-4.1-mini"
deepseek-r1:
provider: "deepseek"
name: "deepseek-r1"
dagi-local-8b:
provider: "local"
name: "qwen2.5-8b-instruct"
```
### 1.3 Providers (providers/*.py)
Кожен провайдер:
```python
class BaseProvider(Protocol):
async def chat(self, messages: list[ChatMessage], model_name: str, **kwargs) -> LLMResponse: ...
```
**Файли:**
- `providers/openai_provider.py`
- `providers/deepseek_provider.py`
- `providers/local_provider.py`
Вони:
- отримують normalized messages,
- викликають відповідний API/endpoint,
- повертають LLMResponse (контент + usage).
**Local provider:**
- для Phase 3 можна зробити простий HTTP-запит до існуючого локального сервісу (Ollama/vLLM), або stub.
### 1.4 Logging & limits (middlewares.py, logging_middleware.py)
Добавити:
- простий rate limit per-agent (стабово, через in-memory або Redis stub).
- логування викликів:
- agent_id, microdao_id, model, latency, tokens.
- TODO hooks для Billing/Usage Engine (на майбутнє).
### 1.5 README.md
Описати:
- підтримувані моделі та мапінг,
- як додати нового провайдера,
- як викликати /internal/llm/proxy з інших сервісів (особливо agent-runtime).
---
## 2) SERVICE: MEMORY ORCHESTRATOR (services/memory-orchestrator)
**Goal:**
Єдиний API для роботи з памʼяттю:
- short-term (канальний контекст / event log),
- mid-term (agent memory / RAG embedding store),
- long-term (knowledge base, docs, roadmaps).
**Create folder:**
```
services/memory-orchestrator/
main.py
models.py
router.py
backends/
__init__.py
short_term_pg.py
vector_store_pg.py
kb_filesystem.py
embedding_client.py
config.yaml
Dockerfile
requirements.txt
README.md
```
### 2.1 API
**Base URL:**
- `POST /internal/agent-memory/query`
- `POST /internal/agent-memory/store`
- `POST /internal/agent-memory/summarize` (optional v1)
**Request /query:**
```json
{
"agent_id": "agent:sofia",
"microdao_id": "microdao:7",
"channel_id": "optional",
"query": "коротко, які були останні зміни в цьому microDAO?",
"limit": 5
}
```
**Response:**
```json
{
"items": [
{
"id": "mem-123",
"kind": "conversation | kb | task | dao-event",
"score": 0.87,
"content": "Текст фрагменту памʼяті",
"meta": {
"source": "channel:...",
"timestamp": "..."
}
}
]
}
```
**Request /store:**
```json
{
"agent_id": "agent:sofia",
"microdao_id": "microdao:7",
"channel_id": "optional",
"kind": "conversation | kb | task | dao-event",
"content": {
"user_message": "...",
"agent_reply": "..."
}
}
```
**Response:**
```json
{ "ok": true, "id": "mem-123" }
```
### 2.2 Backends
**backends/short_term_pg.py:**
- зберігає сирі events (або посилання на messages) в PostgreSQL, якщо треба окремо від messenger.
**backends/vector_store_pg.py:**
- використовує embeddings (через embedding_client.py) і зберігає в таблиці:
```sql
agent_memories (id, agent_id, microdao_id, embedding vector, content, meta)
```
- простий cosine similarity пошук.
**backends/kb_filesystem.py:**
- stub для long-term знань (roadmaps, docs), можна залишити TODO.
### 2.3 Embedding client (embedding_client.py)
- Простий клієнт до існуючої embedding-моделі (наприклад, BGE-M3 чи інша) через /internal/embedding/proxy або безпосередньо.
- Якщо embedding-сервіс не описаний — зробити stub + TODO.
### 2.4 Integration points
**agent-runtime:**
- замінити прямі виклики agent-memory на:
- `POST /internal/agent-memory/query`
- `POST /internal/agent-memory/store`
Надалі можна буде підʼєднати:
- microDAO knowledge,
- DAO events,
- roadmaps.
---
## 3) SERVICE: TOOLCORE (services/toolcore)
**Goal:**
Єдина точка для:
- реєстрації tools (інструментів агентів),
- перевірки дозволів,
- виконання tools та повернення результату агенту.
**Create folder:**
```
services/toolcore/
main.py
models.py
router.py
registry.py
executors/
__init__.py
http_executor.py
python_executor.py (optional)
config.yaml
Dockerfile
requirements.txt
README.md
```
### 3.1 Data model
**models.py:**
```python
class ToolDefinition(BaseModel):
id: str # "projects.list"
name: str
description: str
input_schema: dict # JSON Schema
output_schema: dict # JSON Schema
executor: Literal["http", "python"]
target: str # HTTP URL or python path
allowed_agents: list[str] | None
class ToolCallRequest(BaseModel):
tool_id: str
agent_id: str
microdao_id: str
args: dict
context: dict | None = None
class ToolCallResult(BaseModel):
ok: bool
result: dict | None = None
error: str | None = None
```
### 3.2 API
**HTTP (internal):**
- `GET /internal/tools`
→ список доступних tools
- `POST /internal/tools/call`
Body: ToolCallRequest
Behavior:
- перевірити, чи agent_id має право на tool_id (allowed_agents).
- знайти ToolDefinition.
- виконати через відповідний executor.
- повернути ToolCallResult.
### 3.3 Executors
**executors/http_executor.py:**
- викликає target як HTTP endpoint (POST з args + context).
- хендлінг помилок та таймаутів.
**executors/python_executor.py (optional):**
- allows direct call of internal python functions (у v1 можна залишити TODO або мінімальний stub).
### 3.4 Registry (registry.py)
Початок — з config.yaml (static registry):
**config.yaml:**
```yaml
tools:
- id: "projects.list"
name: "List projects"
description: "Повертає список проєктів microDAO."
input_schema:
type: "object"
properties:
microdao_id: { type: "string" }
required: ["microdao_id"]
output_schema:
type: "array"
items: { type: "object" }
executor: "http"
target: "http://projects-service:8000/internal/tools/projects.list"
allowed_agents: ["agent:sofia", "agent:pm", "agent:cto"]
```
**Registry API:**
- load from config.yaml at startup
- later можна зробити DB-backed registry.
### 3.5 NATS (optional для Phase 3)
Можна додати:
- subject: `tool.request`
- subject: `tool.response`
Але для Phase 3 достатньо HTTP-контракту, який викликає agent-runtime.
---
## 4) INTEGRATION: agent-runtime + LLM Proxy + Memory + Toolcore
**Update agent-runtime:**
### 4.1 Використовувати LLM Proxy
Замість прямого виклику будь-яких LLM:
- завжди викликати:
```http
POST /internal/llm/proxy
{
"model": "<logical model from agent blueprint>",
"messages": [...],
"metadata": {
"agent_id": ...,
"microdao_id": ...,
"channel_id": ...
}
}
```
### 4.2 Використовувати Memory Orchestrator
При channel_message:
- контекст:
`GET /internal/messaging/channels/{channelId}/messages?limit=50`
- памʼять:
`POST /internal/agent-memory/query`
- запис:
`POST /internal/agent-memory/store` після відповіді.
### 4.3 Виклик tools
Якщо в blueprint агента передбачені tools:
- парсити вихід LLM (JSON/structured) або через simple convention (наприклад, спеціальний формат "TOOL: projects.list {...}").
- для кожного tool call:
```http
POST /internal/tools/call
{
"tool_id": "...",
"agent_id": "...",
"microdao_id": "...",
"args": {...}
}
```
- включати результати tools у наступний LLM виклик як контекст.
- (На Phase 3 можна реалізувати один-два прості tools: projects.list, followups.create.)
---
## 5) DOCKER + DOCS
### 5.1 docker-compose
Додати new services:
- llm-proxy
- memory-orchestrator
- toolcore
Переконатися, що:
- вони в тій же мережі, що agent-runtime, messaging-service, NATS, DB;
- є healthcheck-и (GET /health).
### 5.2 Документація
Додати/оновити:
- `docs/LLM_PROXY_SPEC.md`
- `docs/MEMORY_ORCHESTRATOR_SPEC.md`
- `docs/TOOLCORE_SPEC.md`
- оновити `docs/INDEX.md` (додати посилання на ці три сервіси).
- в PHASE2_READY.md або окремому PHASE3_READY.md описати нову архітектуру agent pipeline.
---
## 6) ACCEPTANCE CRITERIA
### 1) LLM Proxy:
- ✅ /internal/llm/proxy приймає запити, повертає відповіді.
- ✅ Принаймні 2 логічні моделі працюють (наприклад, один remote, один local.stub).
- ✅ Логуються виклики per-agent.
### 2) Memory Orchestrator:
- ✅ /internal/agent-memory/query повертає релевантні фрагменти (можна з простим vector search або stub).
- ✅ /internal/agent-memory/store зберігає нові entries.
- ✅ agent-runtime успішно використовує його при відповіді.
### 3) Toolcore:
- ✅ /internal/tools повертає список інструментів.
- ✅ /internal/tools/call виконує хоча б один реальний tool (HTTP executor).
- ✅ agent-runtime може викликати хоча б один tool впродовж свого pipeline.
### 4) End-to-end:
- ✅ Агент у Messenger:
- читає контекст (messages + memory),
- викликає LLM через LLM Proxy,
- за потреби викликає tool через Toolcore,
- повертає відповідь у канал.
- ✅ Для одного демо-агента (наприклад, Sofia-Prime) цей ланцюг стабільно працює.
---
## END OF TASK
**Estimated Time:** 6-8 weeks
**Priority:** High
**Dependencies:** Phase 2 complete
**Version:** 1.0.0
**Date:** 2025-11-24