[2026-09-26] eagle: personal/plans/balda-mm-phase4-agents.md personal/tech/balda-go-fx-pitfalls.md
This commit is contained in:
1 parent
aa5b66a442
commit
593b867467
2 files changed
+97
-2
No files matched your search
@@ -17,6 +17,8 @@
|
||||
| 5 | Связка Балда → мост | ✅ конфиг `type: http`, образ 0.2.0, `tools/list` из docker-сети |
|
||||
| 6 | Obsidian MCP для Балды | ✅ контейнер `obsidian-mcp` на Kraken + `type: sse` в конфиге (транспорт проверен) |
|
||||
| 6a | Инструменты MCP в сессии Балды | ✅ **исправлено 2026-09-26** — Mattermost-классификатор добавлен в `ScopeResolver` (`app.go` + `preflight.go`), образ `balda-mm:0.1.11`, `session_memory.enabled: true`. См. §12 |
|
||||
| 6b | Дубль MCP-ID → `duplicate tool`, Балда молчала | ✅ **исправлено 2026-09-26** — список ID только у провайдера, `balda.mcp_servers: []`; без пересборки образа. См. §13 |
|
||||
| 6c | Structured-output память на `deepseek-chat` | ⚠️ open: `dead_letter / model_failure` — память не наполняется, ответы работают. См. §13 |
|
||||
| 7 | Приёмка от аккаунта Alex | 🔴 блокер: авторизация CLI |
|
||||
|
||||
---
|
||||
@@ -301,6 +303,10 @@ lsof -nP -iTCP:8790 -sTCP:LISTEN
|
||||
игнорирует (правильно), в логе `dropping posted event: bot not mentioned`:
|
||||
`docker exec mattermost mmctl --local token generate admin …`.
|
||||
И **не забывать `@balda`** в тексте поста.
|
||||
🔴 **Продолжение (§13):** после фикса классификатора всплыл второй дефект — дубль MCP-ID
|
||||
в двух секциях → `duplicate tool` → ход падал, Балда молчала. Список ID оставлен **только
|
||||
у провайдера**. И третий, неблокирующий: память на `deepseek-chat` не наполняется
|
||||
(`dead_letter / model_failure`).
|
||||
4. 🔴 Логин CLI (Alex вручную) — без него сквозная приёмка невозможна.
|
||||
5. 🔴 **Завести Access Application** на `agents-bridge.qentra.top` — сейчас туннель
|
||||
отвечает 200 без авторизации (проверено). Защита — только `X-Bridge-Secret`.
|
||||
@@ -530,8 +536,65 @@ Balda bot started. Press Ctrl+C to stop.
|
||||
→ перечисляет obsidian и executor-mcp как ИНСТРУМЕНТЫ
|
||||
```
|
||||
|
||||
⚠️ На момент записи **живой ответ Балды ещё не подтверждён** — проверка за Alex'ом.
|
||||
Статус шага 6a: код+деплой ✅, приёмка ⏳.
|
||||
---
|
||||
|
||||
## 13. 🔴 Второй дефект того же включения: `duplicate tool` (2026-09-26, та же сессия)
|
||||
|
||||
**Симптом после деплоя 0.1.11:** `/reset` больше **не падает** (классификатор работает — звено 2
|
||||
исправлено), но Балда **молчит** на обычное сообщение. В логе на каждый пост:
|
||||
|
||||
```
|
||||
error … "agent run: duplicate tool: \"balda.control.shutdown\""
|
||||
warn … command failed with retryable error (delivery_attempt 1..5)
|
||||
warn … command deadlettered (terminal:unclassified)
|
||||
```
|
||||
|
||||
**Причина:** ID MCP-серверов были перечислены **дважды** — в `balda.mcp_servers` **и** в
|
||||
`runtime.providers.deepseek.mcp_servers`. Эффективный набор = **объединение**, поэтому
|
||||
bundled-`balda` подключался второй раз, и его инструмент `balda.control.shutdown`
|
||||
регистрировался повторно.
|
||||
|
||||
**Где падает:** не в Балде, а в **`google.golang.org/adk`**:
|
||||
```go
|
||||
// $(go env GOMODCACHE)/google.golang.org/adk/v2@v2.4.0/tool/toolutils/toolutils.go:47-48
|
||||
if _, ok := req.Tools[name]; ok {
|
||||
return fmt.Errorf("duplicate tool: %q", name)
|
||||
}
|
||||
```
|
||||
📌 `grep -rn "duplicate tool"` по репозиторию Balda **пуст** — искать надо в ADK. Дедупликация
|
||||
в `session/manager.go:251-270` чистит **ID серверов**, но не повторную регистрацию **инструментов**.
|
||||
|
||||
**Фикс — конфиг, без пересборки образа:** список ID держим **только у провайдера**.
|
||||
```yaml
|
||||
balda:
|
||||
mcp_servers: [] # 🔴 пусто — иначе дубль
|
||||
runtime:
|
||||
providers:
|
||||
deepseek:
|
||||
mcp_servers:
|
||||
- executor-mcp
|
||||
- obsidian
|
||||
```
|
||||
Бэкап: `config.yaml.bak-nodedup-<ts>`. Применено `docker compose up -d --force-recreate`.
|
||||
|
||||
⚠️ **Третий (не блокирующий) дефект того же включения:** `session_memory.enabled: true`
|
||||
активирует structured-output derivation памяти, и `deepseek-chat` не отдаёт нужную схему:
|
||||
```
|
||||
warn … operation=dead_letter kind=boundary.v1 error_code=model_failure
|
||||
error: output does not match schema: (root): output is required
|
||||
```
|
||||
→ `session-memory capability retry limit exhausted`, 7 попыток. Ответы работают,
|
||||
**память не наполняется**. Отдельная задача: либо модель со structured output, либо
|
||||
политика derivation без structured-выхода.
|
||||
|
||||
### Статус после §13
|
||||
|
||||
| Проверка | Результат |
|
||||
|---|---|
|
||||
| `SessionMCPBinder` в DI-графе | ✅ `provided` |
|
||||
| старт без ошибок классификатора | ✅ `session memory … started` |
|
||||
| `duplicate tool` после фикса конфига | ✅ в логах чисто (после recreate) |
|
||||
| живой ответ Балды на `@balda …` | ⏳ за Alex'ом |
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -182,6 +182,38 @@ func(broker *sessionmemorymcp.ContextBroker, enabled bool) baldaagent.SessionMCP
|
||||
effective = bundled(balda) + runtime.providers.<id>.mcp_servers + balda.mcp_servers
|
||||
```
|
||||
|
||||
🔴 **Не перечислять ID серверов ДВАЖДЫ** (`balda.mcp_servers` **и**
|
||||
`runtime.providers.<id>.mcp_servers`) — эффективный набор это **объединение**, и каждый
|
||||
сервер подключается дважды. Симптом — ход падает ещё до вызова модели:
|
||||
|
||||
```
|
||||
error … "agent run: duplicate tool: \"balda.control.shutdown\""
|
||||
→ в чате тишина; в логе `turn task failed` + `command deadlettered` (5 попыток)
|
||||
```
|
||||
|
||||
Источник ошибки — библиотека ADK, не Балда:
|
||||
```go
|
||||
// google.golang.org/adk/v2/tool/toolutils/toolutils.go:47-48
|
||||
if _, ok := req.Tools[name]; ok {
|
||||
return fmt.Errorf("duplicate tool: %q", name)
|
||||
}
|
||||
```
|
||||
🔴 **`duplicate tool` в исходниках Balda не найти** (`grep` пустой) — это `google.golang.org/adk`.
|
||||
Искать в `$(go env GOMODCACHE)/google.golang.org/adk/`, а не в репозитории.
|
||||
📌 Правило: держать список ID в **одном** месте — у провайдера; `balda.mcp_servers: []`.
|
||||
Слияние в `session/manager.go:251-270` дедуплицирует **ID**, но не защищает от
|
||||
повторной регистрации **инструментов** уже подключённого сервера.
|
||||
|
||||
⚠️ **`session_memory.enabled: true` тянет за собой structured-output память.** На
|
||||
`deepseek-chat` worker памяти не может отдать нужную JSON-схему:
|
||||
```
|
||||
warn … session-memory capability retry limit exhausted
|
||||
operation=dead_letter kind=boundary.v1 error_code=model_failure
|
||||
error: output does not match schema: (root): output is required
|
||||
```
|
||||
7 попыток → dead letter. Ответы бота при этом работают, но **память не наполняется**.
|
||||
Не блокер для MCP; отдельный дефект совместимости модели и схемы derivation.
|
||||
|
||||
---
|
||||
|
||||
## 🔴 Сброс падающих тестов: сначала `git stash`, потом слово «регрессия»
|
||||
|
||||
Reference in new issue
Block a user