[2026-09-27] eagle: personal/plans/balda-mm-phase4-agents.md personal/projects/balda/balda-kraken-mm-deploy.md personal/projects/balda/balda-valera.md personal/tech/balda-go-fx-pitfalls.md personal/tech/music-broken-toload.md
This commit is contained in:
1 parent
586d9e8ffd
commit
de100184d6
5 files changed
+467
-14
No files matched your search
@@ -32,6 +32,11 @@
|
||||
> 📌 Урок метода: **прежде чем объявлять ограничение апстрима — свериться со своим
|
||||
> старым патчем.** Ключ Alex: «Это не та же проблема, что мы решали в форке?»
|
||||
> Зеркало секции скилла `devops/docker-balda-service`, добавленной 2026-09-26.
|
||||
> 🔴🔴🔴 **Добавлено 2026-09-27 (четвёртая итерация):** §«Патч tool_calls ОБНАЖИЛ двойную
|
||||
> паковку инструментов» — почему `duplicate tool` вернулся на `0.1.12`, хотя конфиг чист.
|
||||
> Ключевой инсайт: апстримный `TurnComplete: true` **маскировал** баг — агент не доходил
|
||||
> до паковки инструментов. Как только патч включил второй раунд, ADK-механика проявилась.
|
||||
> Плюс метод: §«Доказать, что код патча в образе» (распаковать OCI-слои, грепнуть бинарник).
|
||||
> Источник: работа над Mattermost-адаптером Балды (Фаза 2) + деплой на Kraken (Фаза 3).
|
||||
> Проектные доки: [[personal/projects/balda/balda-mattermost-connector]],
|
||||
> [[personal/projects/balda/balda-kraken-mm-deploy]],
|
||||
@@ -1615,3 +1620,105 @@ MM websocket frame
|
||||
`frame received` → `event decoded` → `posted event accepted` → `post accepted for processing`
|
||||
→ `conversational ingress settled` (`settlement_stage`!) → `assembled provider user content`
|
||||
→ `turn task failed`. Пока нет строки `assembled provider user content` — провайдер не виноват.
|
||||
|
||||
---
|
||||
|
||||
## 🔴🔴🔴 Патч tool_calls ОБНАЖИЛ двойную паковку инструментов (2026-09-27)
|
||||
|
||||
**Симптом.** После деплоя `balda-mm:0.1.12` (форк `runtime` с поддержкой `tool_calls`) **каждый**
|
||||
ход падает, Балда молчит:
|
||||
|
||||
```
|
||||
error … "agent run: duplicate tool: \"balda.control.shutdown\""
|
||||
warn … command failed with retryable error (delivery_attempt 1..4)
|
||||
warn … publish event "balda.v1.evt.command.in_progress": context deadline exceeded
|
||||
```
|
||||
|
||||
**Это тот же `duplicate tool`, что уже чинили через конфиг** (§13 в
|
||||
[[personal/plans/balda-mm-phase4-agents]]) — но конфиг **чист** (`balda.mcp_servers: []`,
|
||||
ID только у провайдера). Значит причина другая, и правкой конфига она не лечится.
|
||||
|
||||
### Ключевой инсайт: `TurnComplete: true` МАСКИРОВАЛ баг
|
||||
|
||||
| Образ | `TurnComplete` | Что происходило |
|
||||
|---|---|---|
|
||||
| `0.1.11` (апстримный `openai.go:107`) | жёстко `true` | агент завершался после **первого** ответа модели → инструменты **не пакались вообще** → `duplicate tool` не возникал, **но и инструменты не работали** |
|
||||
| `0.1.12` (форк) | `!hasToolCalls` | при `tool_calls` агент идёт на **второй раунд** → начинается паковка инструментов → всплывает двойная регистрация |
|
||||
|
||||
> 📌 **Формулировка для будущих сессий:** форк **не регрессия — форк диагност.** Ошибка жила
|
||||
> в связке Balda↔ADK всё время; не было только пути её вызвать. Прежде чем объявлять новый
|
||||
> патч виновником — проверить, не **обнажил** ли он dormant-баг.
|
||||
|
||||
### Механика: два независимых пути паковки в один `req.Tools`
|
||||
|
||||
`google.golang.org/adk/v2@v2.4.0`:
|
||||
|
||||
```
|
||||
base_flow.go:778 toolPreprocess() — пакует agent.Tools → req.Tools
|
||||
base_flow.go:798 toolsetPreprocess() — пакует agent.Toolsets → req.Tools
|
||||
└─ mcptoolset/tool.go:89 → toolutils.PackTool()
|
||||
toolutils.go:47-48:
|
||||
if _, ok := req.Tools[name]; ok {
|
||||
return fmt.Errorf("duplicate tool: %q", name)
|
||||
}
|
||||
```
|
||||
|
||||
- `tools_processor.go:31` — `if f.Tools != nil { return }` — защищает **только** сборку `f.Tools`,
|
||||
**не** повторный вызов `toolsetPreprocess`.
|
||||
- `PackTool` **идемпотентным не является by design** — дублировать источник нельзя.
|
||||
- Дубль возникает, если инструмент присутствует **и в `Tools`, и в одном из `Toolsets`**, либо
|
||||
в двух toolsets. Кандидат в нашем случае: `agentfactory.go:655-656` кладёт в `llmagent.Config`
|
||||
одновременно `Tools: req.Tools` и `Toolsets: toolsets` (bundled `balda` мог попасть в оба).
|
||||
|
||||
📌 `grep -rn "duplicate tool"` по репозиторию Balda **пуст** — искать в ADK
|
||||
(`$(go env GOMODCACHE)/google.golang.org/adk/v2@v2.4.0/tool/toolutils/toolutils.go`).
|
||||
|
||||
### Что исключено фактами (не проверять снова)
|
||||
|
||||
| Версия | Проверка | Итог |
|
||||
|---|---|---|
|
||||
| Конфиг дублирует MCP-ID | `balda.mcp_servers: []`, ID у провайдера | ❌ чисто |
|
||||
| Сессия накопила мусор | `/reset` **от владельца** (admin PAT) | ❌ не лечит |
|
||||
| Форк не попал в образ | `strings` бинарника из `0.1.12` | ❌ форк на месте |
|
||||
| Каталог `state.db` замусорен | уникальные ID: `builtin/balda`, `configured-mcp/executor-mcp`, `configured-mcp/obsidian` — по одному | ❌ по одной записи |
|
||||
| Bundled MCP стартует дважды | лог `bundled MCP listener started` — один раз | ❌ однократно |
|
||||
| Патч трогает сборку инструментов | `git diff v2.0.11 --stat` → только `openai.go` + тест | ❌ патч чист |
|
||||
| `ContextBroker.Wrap` добавляет инструменты | `broker.go:118-153` — только HTTP-заголовки | ❌ не источник |
|
||||
| `hostedToolsets()` дублирует серверы | `agentfactory.go:360-384` — `resolvedMCP` это **map** по `id` | ❌ дубля нет |
|
||||
|
||||
⚠️ **Ловушка ложной тревоги:** `strings state.db | grep -c '"balda"'` ≈ **112**. Это счётчик
|
||||
вхождений **подстроки**, а не серверов: `balda` есть в каждом логе, в `balda.v1.*`,
|
||||
в `balda.control.shutdown`. Считать только **уникальные** ID.
|
||||
|
||||
### Метод: доказать, что код патча попал в образ (`scratch`, shell нет)
|
||||
|
||||
```bash
|
||||
docker save balda-mm:0.1.12 -o /tmp/chk.tar
|
||||
mkdir -p /tmp/chkx && tar -xf /tmp/chk.tar -C /tmp/chkx
|
||||
# OCI-формат: слои в blobs/sha256/*, бинарник — в самом большом слое
|
||||
for f in /tmp/chkx/blobs/sha256/*; do
|
||||
file -b "$f" | grep -q gzip && tar -xzf "$f" -C /tmp/chkx 2>/dev/null
|
||||
done
|
||||
strings /tmp/chkx/usr/local/bin/balda | grep -E "tool_call_id|missing content and tool_calls"
|
||||
```
|
||||
⚠️ `tar -tf image.tar | grep ca-certificates` на OCI-образе даёт **ложный 0** — файлы внутри
|
||||
слоёв. То же и с поиском кода патча: смотреть только распакованный бинарник.
|
||||
|
||||
🔴 **Кэш сборки — реальный риск, но не засорение диска.** `COPY runtime-local/` мог подставить
|
||||
**старые исходники** без ошибки. В этот раз обошлось, потому что изменились `go.mod` и
|
||||
`Dockerfile.release` (слои инвалидировались сами). Если менять **только содержимое**
|
||||
`runtime-local/` — брать `--no-cache`, иначе тихо соберутся старые исходники.
|
||||
|
||||
### Побочный эффект откатов: долгий старт из-за WAL
|
||||
|
||||
Жёсткое убийство контейнера оставляет незакрытый `state.db-wal`. Следующий старт на `0.1.11`
|
||||
идёт **~4.5 мин** вместо ~1m11s (переигрывание WAL). **Это не зависание:** `docker logs | wc -l`
|
||||
растёт рывками, процесс висит в `do_epoll_wait` — живой.
|
||||
Признак настоящего зависания — рост лога остановился **и** нет ни одного потока в `epoll`.
|
||||
|
||||
📌 Метод чтения состояния застрявшего процесса в контейнере без shell:
|
||||
```bash
|
||||
PID=$(docker inspect balda-mm --format '{{.State.Pid}}')
|
||||
for t in $(sudo ls /proc/$PID/task); do echo -n "$t: "; sudo cat /proc/$PID/task/$t/wchan; echo; done
|
||||
```
|
||||
`do_epoll_wait` = слушает · `blk_mq_get_tag` = дисковый I/O · `futex_wait_queue` = ждёт мьютекс/канал.
|
||||
@@ -0,0 +1,102 @@
|
||||
---
|
||||
title: Битые и DRM аудиофайлы — на перезагрузку
|
||||
updated: 2026-09-26
|
||||
type: tech
|
||||
tags: [music, truenas, toload]
|
||||
related: personal/tech/yandex-music-api, personal/tech/music-tags-repair-truenas
|
||||
---
|
||||
|
||||
# Битые и DRM аудиофайлы — на перезагрузку
|
||||
|
||||
> Файлы в `/mnt/RED_2TB/storage/Music`, которые **не читаются** и подлежат
|
||||
> удалению с последующей загрузкой заново.
|
||||
> Рядом с [[personal/tech/yandex-music-api]] (выгрузка библиотеки).
|
||||
> Составлено: 2026-09-26. Источник: диагностика ffmpeg/ffprobe в контейнере `tagwriter`.
|
||||
|
||||
---
|
||||
|
||||
## Итог
|
||||
|
||||
| Категория | Файлов | Объём | Причина |
|
||||
|---|---|---|---|
|
||||
| **Битые** (контейнер разрушен) | 16 | ~152 МБ | ID3-заголовок записан поверх структуры формата |
|
||||
| **DRM** (Windows Media защита) | 13 | ~33 МБ | `License_URL` в ASF-заголовке |
|
||||
| **Итого** | **29** | **~185 МБ** | |
|
||||
|
||||
**Бэкап:** все 29 в `/mnt/RED_2TB/storage/Music/backup_raw/`.
|
||||
⚠️ **Бэкап не помогает** — файлы там идентичны диску (побиты до сессии).
|
||||
|
||||
---
|
||||
|
||||
## 1. Битые (контейнер разрушен) — 16 файлов
|
||||
|
||||
**Причина:** файл начинается с `ID3` вместо `ftyp` (m4a) / `ASF` (wma) →
|
||||
`moov atom not found` / `Invalid data found`. Структура контейнера затёрта.
|
||||
**Восстановлению не подлежит.**
|
||||
|
||||
### Infected Mushroom — (2012) Army of Mushrooms (13 m4a, ~130 МБ)
|
||||
|
||||
Папка: `!Pop, Club, Любэ/Infected Mushroom/(2012) Army of Mushrooms/`
|
||||
|
||||
| Файл | Размер |
|
||||
|---|---|
|
||||
| `01 Never Mind.m4a` | 12.5 МБ |
|
||||
| `02 Nothing to Say.m4a` | 13.0 МБ |
|
||||
| `03 Send Me an Angel.m4a` | 14.7 МБ |
|
||||
| `04 U R So Fucked.m4a` | 9.9 МБ |
|
||||
| `05 The Rat.m4a` | 15.5 МБ |
|
||||
| `06 Nation of Wusses.m4a` | 13.9 МБ |
|
||||
| `07 Wanted To.m4a` | 7.0 МБ |
|
||||
| `08 Serve My Thirst.m4a` | 13.5 МБ |
|
||||
| `09 I Shine.m4a` | 11.9 МБ |
|
||||
| `10 Drum n Bassa.m4a` | 14.4 МБ |
|
||||
| `11 The Pretender.m4a` | 13.0 МБ |
|
||||
| `12 The Messenger 2012.m4a` | 21.0 МБ |
|
||||
| `13 Swingish (Bonus Track).m4a` | 12.4 МБ |
|
||||
|
||||
**Искать:** `Infected Mushroom Army of Mushrooms 2012` (альбом целиком, MP3 320)
|
||||
|
||||
### Прочее (3 файла, ~9 МБ)
|
||||
|
||||
| Файл | Размер | Искать |
|
||||
|---|---|---|
|
||||
| `!Рэп/НТЛ/NTL - ВЕРТИТЕ ЗАДОМ_old.wma` | 1.7 МБ | НТЛ — Вертите задом |
|
||||
| `!Rock&Folk/Агата Кристи/Ближе.wma` | 2.7 МБ | Агата Кристи — Ближе |
|
||||
| `!Rock&Folk/Ундервуд/2002 Все пройдет, милая/02 - Гагарин, я вас любила.wma` | 4.3 МБ | Ундервуд — Гагарин, я вас любила |
|
||||
|
||||
---
|
||||
|
||||
## 2. DRM (Windows Media защита) — 13 файлов
|
||||
|
||||
**Причина:** в ASF-заголовке `License_URL: ...sbp=DRM&...` — файлы зашифрованы
|
||||
Windows Media DRM. Microsoft закрыл инфраструктуру выдачи лицензий → **обойти
|
||||
нельзя**. Требуется загрузка заново.
|
||||
|
||||
**Папка:** `!Рэп/НТЛ/wma/` — все 13 `Track N.wma` (1–13), ~33 МБ
|
||||
|
||||
**Искать:** `НТЛ` (группа) — альбом целиком. Файлы безымянные (`Track N`),
|
||||
названия треков неизвестны — уточнить по треклисту на источнике.
|
||||
|
||||
| Файл | Размер |
|
||||
|---|---|
|
||||
| `Track 1.wma` … `Track 13.wma` | 1.8–3.1 МБ каждый |
|
||||
|
||||
---
|
||||
|
||||
## 3. Что делать
|
||||
|
||||
1. Скачать заново по списку выше (в MP3).
|
||||
2. Теги — по общему правилу библиотеки (`tag-fix-plan` / `rebuild_summaries`).
|
||||
3. ⚠️ **Не применять массовые ID3-правки к не-MP3** — именно это разрушило
|
||||
контейнеры m4a/wma. Теги не-MP3 писать только родными инструментами формата.
|
||||
|
||||
---
|
||||
|
||||
## 4. Связанные документы
|
||||
|
||||
- [[personal/tech/yandex-music-api]] — выгрузка библиотеки Яндекс Музыки
|
||||
- [[personal/tech/music-tags-repair-truenas]] — ремонт тегов на TrueNAS
|
||||
- [[personal/tech/music-tags-final-review]] — финальное ревью
|
||||
|
||||
---
|
||||
*Создано: 2026-09-26 | Источник: диагностика 70 не-MP3 файлов в Music*
|
||||
Reference in new issue
Block a user