Skip to content

Commit 5b4fb7b

Browse files
fix(server): music регистрируется по факту старта, а не по наличию токена
ensureMcpConfig вызывался до startYnisonAndVerify, поэтому при неудачном старте ynison.js (занятый порт, упавший bun) в конфиг всё равно попадала секция music с живым bearer: модель получала шесть инструментов, которые не отвечают. Теперь запись идёт после проверки порта и получает ynisonToken.takeIf { ynisonStarted }: неудачный старт снимает секцию (syncMusicEntry с null её удаляет), как и было задумано в комментарии рядом. Порядок "до startServe" сохранён - serve читает конфиг при инициализации MCP. Проверено на устройстве: секция music в opencode.jsonc на месте (url http://127.0.0.1:4200/mcp, timeout 180000), mcp connected server=music tools=10, плюс memory, mobile_tools и moltbook.
1 parent 66ec130 commit 5b4fb7b

3 files changed

Lines changed: 28 additions & 13 deletions

File tree

‎CHANGELOG.md‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -581,6 +581,17 @@ ChatOverlay разобран на четыре файла (25.10.2026)
581581
- Проверено на устройстве: до правки ~1 обрыв в 13 с, после установки — 0 обрывов за
582582
3,5 минуты, `mcp connected server=music` на старте.
583583

584+
Музыка регистрируется в конфиге по результату старта, а не по наличию токена (26.10.2026)
585+
- `ensureMcpConfig` вызывался до `startYnisonAndVerify`, поэтому при неудачном старте
586+
`ynison.js` (занятый порт, упавший bun) в конфиг всё равно попадала секция `music`
587+
с живым bearer — модель получала шесть инструментов, которые не отвечают.
588+
- Теперь запись идёт после проверки порта и получает `ynisonToken.takeIf { ynisonStarted }`:
589+
неудачный старт снимает секцию (`syncMusicEntry` с `null` её удаляет), как и было
590+
задумано в комментарии рядом. Порядок «до `startServe`» сохранён — serve читает
591+
конфиг при инициализации MCP.
592+
- Проверено на устройстве: секция `music` в `opencode.jsonc` на месте (`url`
593+
`http://127.0.0.1:4200/mcp`, `timeout` 180000), `mcp connected server=music`.
594+
584595
---
585596

586597
## Стек и зависимости

‎app/src/main/java/org/opencode/mobile/server/RuntimeManager.kt‎

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -289,18 +289,6 @@ class RuntimeManager(
289289
MoltbookToken.remember(context, moltbookToken)
290290
}
291291

292-
// Регистрируем локальную память в конфиге serve как remote MCP
293-
// (иначе serve о ней не знает — индикатор «0 MCP», инструменты
294-
// памяти недоступны модели). До старта serve: он читает конфиг
295-
// при инициализации MCP. Не фатал — память продолжит работать
296-
// как TCP-сервер, просто без регистрации.
297-
OpencodeRuntime.ensureMcpConfig(
298-
memoryToken,
299-
ynisonToken,
300-
moltbookStarted,
301-
ModelRoutingPrefs.read(context),
302-
)
303-
304292
// Локальная память MCP как HTTP/TCP-сервер (MEMORY_PORT) — ДО serve.
305293
// Не стартовала/умерла — НЕ фатал: serve продолжит, статус DEGRADED.
306294
// Живой process != поднятая память: startMemoryServer возвращает процесс,
@@ -344,6 +332,22 @@ class RuntimeManager(
344332
}
345333
}
346334

335+
// Регистрируем MCP в конфиге serve (иначе serve о них не знает — индикатор
336+
// «0 MCP», инструменты недоступны модели). Строго до старта serve: он читает
337+
// конфиг при инициализации MCP, позже записанная секция уже не подхватится.
338+
//
339+
// Музыка регистрируется по РЕЗУЛЬТАТУ старта, а не по наличию токена.
340+
// Токен создаётся раньше (см. выше) и говорит только о подключённом аккаунте:
341+
// если ynison.js не открыл порт, запись в конфиге отдавала модели шесть
342+
// инструментов, которые не отвечают. syncMusicEntry с null эту запись снимает.
343+
// Не фатал — память продолжит работать как TCP-сервер, просто без регистрации.
344+
OpencodeRuntime.ensureMcpConfig(
345+
memoryToken,
346+
ynisonToken.takeIf { ynisonStarted },
347+
moltbookStarted,
348+
ModelRoutingPrefs.read(context),
349+
)
350+
347351
emit { copy(stage = RuntimeStage.STARTING_SERVER) }
348352
val proc =
349353
OpencodeRuntime.startServe(

‎docs/ROADMAP.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -354,4 +354,4 @@ SAW-грантом (после `adb install -r` accessibility на ColorOS сб
354354
| 2. Сеть без прокси | **Выполнен** — встроенный `Ipv4Proxy` (CONNECT, IPv4-first); туннели к context7/grep/npm открываются автоматически. Legacy `connect_proxy.py` удалён (26.09) |
355355
| 3. STT turbo на CPU | **Почти готов** — int8-encoder ~2× fp32, **VAD-чанкинг внедрён (первые слова 1–2 s)**, бенч на устройстве прогнан (24.09), **VAD-пороги измерены** (26.09, `56034e9`: `MIN_RMS=0.015` подтверждён свипом 6 порогов × 5 SNR), **WER-счётка готова и покрыта 13 тестами** (26.09, `c7256c1`). Осталось: наполнить корпус доверенными расшифровками и прогнать на устройстве |
356356
| 4. Безопасность и память | **Выполнен** — Basic Auth (401 без пароля), локальная память MCP (`ensureMcpConfig`, фикс «0 MCP»), протокольная диагностика, e2e чистой установки пройден |
357-
| 5. День 2: тесты + расследования | **P0 закрыт (25.10.2026):** `AppInstallBridgeTest.kt` — 10 тестов, JSON-формы вынесены в `AppInstallWire`/`MediaWire`; JS-часть уже была покрыта `ynison-bridge.test.mjs` и `SessionControlEnumContractTest`. **P2-мелочи закрыты (25.10):** `/v1/media/apps` читает `query`/`limit` из query-строки через валидатор, мёртвый `MEDIA_ACTIONS` удалён. **P1 не закрыт:** effective-конфиг MCP найден (25.10 — пишет `ensureMcpConfig`, поле `timeout` есть в схеме 2.0.27), блокировка регистрации music при подключённом moltbook найдена и исправлена (25.10, `hasManagedMcpBlock`/`planMusicEntry` — узнавали секцию целиком), замер таймаута закрыт (25.10: вызов умирает за 18,5 с на go-away 503, а не на 180 с; бан теперь узнаётся, соблюдается и переживает рестарт), seed/mirror-цикл `ensurePhone()` ждёт живого Ynison |
357+
| 5. День 2: тесты + расследования | **P0 закрыт (25.10.2026):** `AppInstallBridgeTest.kt` — 10 тестов, JSON-формы вынесены в `AppInstallWire`/`MediaWire`; JS-часть уже была покрыта `ynison-bridge.test.mjs` и `SessionControlEnumContractTest`. **P2-мелочи закрыты (25.10):** `/v1/media/apps` читает `query`/`limit` из query-строки через валидатор, мёртвый `MEDIA_ACTIONS` удалён. **P1 не закрыт:** effective-конфиг MCP найден (25.10 — пишет `ensureMcpConfig`, поле `timeout` есть в схеме 2.0.27), блокировка регистрации music при подключённом moltbook найдена и исправлена (25.10, `hasManagedMcpBlock`/`planMusicEntry` — узнавали секцию целиком), замер таймаута закрыт (25.10: вызов умирает за 18,5 с на go-away 503, а не на 180 с; бан теперь узнаётся, соблюдается и переживает рестарт), seed/mirror-цикл `ensurePhone()` ждёт живого Ynison. **Регистрация музыки по факту старта (26.10):** `ensureMcpConfig` перенесён после `startYnisonAndVerify` и получает `ynisonToken.takeIf { ynisonStarted }` — неудачный старт снимает секцию, а не оставляет модели шесть инструментов, которые не отвечают. **Шторм переподключений закрыт (26.10):** 1632 обрыва `server=music` за 7 часов — это и был «неизвестный вызов в 22:54», лечится `server.timeout(req, 0)` + keepalive, см. выше |

0 commit comments

Comments
 (0)