Releases: mishaqp/Moru
Release list
Moru v0.1.47-pre.434
Merge pull request #105 from mishaqp/codex/sidebar-background-edges Fix full-screen chat and sidebar wallpaper alignment
Moru v0.1.46
Moru v0.1.46 — чистка кода под Android
Большая уборка мёртвого кода по всему приложению. Всё, что работало только на iOS, macOS, Windows, Linux или в браузере, удалено: на Android этот код никогда не выполнялся.
Внешне приложение не меняется. Настройки, чаты, рабочие пространства, терминал, STDIO MCP и планшетная раскладка остаются как были.
Итог в цифрах
- Код приложения: удалено около 11 900 строк Dart. Не считаются строки перевода и сгенерированная локализация.
- Файлы: удалено 32 файла кода и тестов.
- Строки перевода: удалено 428 неиспользуемых строк (на каждом из пяти языков).
- Пакеты: удалены три пакета, которые на Android не использовались:
cupertino_http,webview_windows,haptic_feedback. APK становится чуть легче.
Что удалено
Десктопные и iOS-движки
- Десктопный движок команд (запуск процессов на хосте macOS/Linux/Windows). На Android команды выполняются в PRoot, он не тронут.
- iOS-среда рабочего пространства (iSH/Alpine) и её установщик.
- Запланированные задачи:
- удалены десктопный планировщик и iOS-«подготовка» результатов заранее (около 1 000 строк);
- на Android задачи работают, как раньше, через системный планировщик;
- в редакторе задачи остались только нужные переключатели: уведомление о результате и текст результата в уведомлении.
- iOS-инструменты устройства: погода (WeatherKit), здоровье (HealthKit), напоминания (EventKit). На Android их не было в списке инструментов.
- iOS-перевод выделенного текста в коде. Меню выделения теперь стандартное.
Десктопные ветки интерфейса
- Главный экран:
- правая боковая панель, перетаскивание ширины панелей;
- панель рабочих пространств;
- обработчики удалённых горячих клавиш.
- Боковое меню: десктопные вкладки «Ассистенты / Темы», подгрузка чатов при наведении мыши, режимы только тем / только ассистентов.
- Десктопные диалоги деталей инструмента, системного промпта, просмотра изображений, выбора ассистента и группы QQ. На Android открываются те же нижние листы, что и раньше.
- Таблицы в Markdown: широкая десктопная раскладка. На телефоне таблица и раньше показывалась компактно.
- Настройки, которые Android никогда не читал: трей, сворачивание в трей, заголовок окна Linux, позиция панели тем, ширина и состояние боковых панелей.
Ветки кода
Около 300 проверок вида «если iOS / macOS / Windows / Linux / Web» по всему коду заменены их значением для Android, а ставшие недостижимыми ветки удалены.
Тесты
- Удалены тесты, которые проверяли только удалённое поведение: десктопные диалоги, iOS-подготовку задач, HealthKit и WeatherKit, десктопные вкладки меню и т. п.
- Тесты, которые перебирали платформы, теперь проверяют Android.
- Тесты редактора MCP-сервера проверяют аргументы и переменные окружения на Android, с привязкой к рабочему пространству.
- Сквозной тест отмены генерации раньше запускал команду через удалённый десктопный движок. Теперь он запускает настоящую команду через тестовый движок с тем же контрактом, так что проверка не потерялась.
Проверка
- Анализ без замечаний, полный набор Flutter-тестов.
- Проверки политики Android-only, arm64-APK и правил R8.
- CI:
- анализ, Flutter-тесты, локализация;
- Android JVM-тесты;
- сборка одного
arm64-v8aAPK, подписанного постоянным сертификатом Moru; - проверка release-APK.
Версия 0.1.46 (versionCode 47), пакет com.mishaqp.moru.
Проверка APK
{
"tag": "v0.1.46",
"version": "0.1.46",
"version_code": 47,
"package": "com.mishaqp.moru",
"abi": "arm64-v8a",
"commit": "b9203e9e6d11549f0a85c2cdeda80e9664dc20ec",
"filename": "Moru-v0.1.46-arm64-v8a-release.apk",
"sha256": "47e37c9eda0b11ec22ae56083470d8ab65cf6edc518a9f1f6199f29fbf686698",
"size_bytes": 37645875,
"certificate_sha256": "c5db7faec00b149db9406af2a714c963f9e6ad1632905e8237d04104f46182db"
}Moru v0.1.45
Moru v0.1.45 — «Стекло» как пресет
Доработка темы «Стекло» по скриншотам 0.1.44. Теперь это не отдельный слой поверх настроек, а быстрый пресет существующего «Стиля сообщений».
«Стекло» включает стиль сообщений и возвращает прежний
- При включении «Стекло» записывает в «Стиль сообщений»:
- стиль «Матовый»;
- пузыри ассистента: прозрачнее, чем раньше, со светлой обводкой;
- ваши пузыри: цвет акцента палитры темы, белый текст.
Ваша сила размытия сохраняется.
- При выключении возвращается стиль сообщений, который был до включения, со всеми вашими настройками пузырей.
- Всё можно донастроить. Пресет можно менять вручную в «Стиле сообщений», как обычный стиль.
- Нет дублей. Отдельная «Матовость» на экране «Стекло» убрана: размытие настраивается в «Стиле сообщений».
- Шапка чата размывается так же сильно, как пузыри.
Если «Стекло» было включено в 0.1.44, выключите и снова включите его, чтобы применить новый пресет. Прежнего стиля 0.1.44 не сохраняла, поэтому первое выключение оставит текущий стиль как есть.
Фон и меню
- Градиент на весь экран. Цветные пятна теперь распределены по всей высоте, а не только сверху, так что низ экрана и поле ввода тоже на цветном фоне. Это касается и градиентного фона в настройках ассистента («Фон чата»).
- Боковое меню в «Стекле» полупрозрачное: под списком чатов виден цветной фон, а не сплошная чёрная панель.
Проверка
- Новые и обновлённые тесты:
- «Стекло» записывает стиль сообщений, переживает перезапуск и при выключении возвращает прежний стиль;
- экран «Стекло» передаёт в пресет цвет акцента палитры;
- боковое меню в «Стекле» показывает цветной фон под полупрозрачной подложкой и возвращает обычный вид при выключении;
- матовые пузыри, экономный режим и матовая шапка, как в 0.1.44.
- Анализ без замечаний, полный набор Flutter-тестов.
- CI: анализ, Flutter-тесты, локализация, Android JVM-тесты, сборка одного
arm64-v8aAPK, подписанного постоянным сертификатом Moru, и проверка release-APK.
Версия 0.1.45 (versionCode 46), пакет com.mishaqp.moru.
Проверка APK
{
"tag": "v0.1.45",
"version": "0.1.45",
"version_code": 46,
"package": "com.mishaqp.moru",
"abi": "arm64-v8a",
"commit": "24166dc1d28857483e2222e4c15b568693d570b7",
"filename": "Moru-v0.1.45-arm64-v8a-release.apk",
"sha256": "9d655896502c77cc70c6262eaf56c7f59c67d437433cddb3cdaeb17a22479066",
"size_bytes": 37777327,
"certificate_sha256": "c5db7faec00b149db9406af2a714c963f9e6ad1632905e8237d04104f46182db"
}Moru v0.1.44
Moru v0.1.44 — тема «Стекло»
Новая тема в стиле Glassmorphism (матовое стекло) по макету, который вы одобрили. Классический вид не меняется, пока «Стекло» выключено.
Тема «Стекло»
Где включить: Настройки → Внешний вид → Стекло.
Что меняется, когда тема включена
- Фон. За каждым чатом плавно движутся цветные пятна. Самое крупное окрашено в акцентный цвет палитры темы. Если у ассистента задана своя картинка или свой градиент, показываются они.
- Сообщения. Пузыри становятся матовыми: полупрозрачными, с тонкой светлой обводкой. Сквозь них размыто виден фон.
- Шапка. Под ней теперь настоящее матовое стекло. Сообщения, которые уходят под шапку при прокрутке, видны размытыми, а не прячутся за копией фона.
- Поле ввода. Остаётся матовым, как и раньше.
Настройки стекла
- Матовость: мягкая, средняя (по умолчанию) или сильная. Меняет силу размытия у пузырей и шапки.
- Экономный режим. Живое размытие у шапки и пузырей отключается, остаётся только полупрозрачность. Для слабых телефонов.
Как устроено и почему не должно тормозить
-
Стекло построено на механизме, который в Moru уже был для фона ассистентов:
- фон перерисовывается не чаще 30 раз в секунду и не зависит от прокрутки;
- матовые пузыри используют заранее размытый снимок фона, а не живое размытие на каждом кадре.
-
Живое размытие есть только у шапки и поля ввода.
-
Замер прокрутки ленты (40 обменов, после разогрева, среднее по трём прогонам):
Среднее P90 Без стекла 27–30 мс ~40 мс Со стеклом 27–32 мс ~39 мс Разница в пределах шума.
-
Чего этот тест не видит. Он измеряет сборку и раскладку экрана. Стоимость самого размытия считает видеокарта телефона, в тестах её не измерить, поэтому проверьте на своём телефоне. Если будет подтормаживать, включите «Экономный режим».
Что отличается от макета
- Цвета берутся из палитры темы («Внешний вид → Тема»). Отдельного выбора акцента на экране «Стекло» нет, чтобы не дублировать палитры.
- Ответ одной карточкой. Если в стиле сообщений включено «Разделять абзацы на пузыри», ответ по-прежнему делится на пузыри: ваша настройка не меняется. Чтобы ответ был одной карточкой, как в макете, выключите её. Подсказка об этом есть на экране «Стекло».
- Расположение шапки осталось прежним: переключатель «Файлы / терминал / браузер» сверху, строка с названием чата и моделью под ним. Меняется только вид шапки.
- Своей картинки в самой теме «Стекло» нет. Картинку по-прежнему можно задать ассистенту в его настройках, и в теме «Стекло» она будет фоном.
Дальше
- Следующий раздел выберем вместе перед началом работы.
Проверка
- Новые тесты:
- настройки «Стекла» по умолчанию выключены и сохраняются;
- «Стекло» включает градиентный фон у чата без своей картинки;
- пузыри становятся матовыми с выбранной силой размытия, а в экономном режиме — без размытия;
- матовая шапка заменяет копию фона и занимает ровно высоту шапки;
- экран «Стекло» включает тему, меняет матовость и экономный режим.
- Бенчмарк
test/perf/timeline_scroll_bench.dartполучил вариант со стеклом. - Анализ без замечаний, полный набор Flutter-тестов.
- CI: анализ, Flutter-тесты, локализация, Android JVM-тесты, сборка одного
arm64-v8aAPK, подписанного постоянным сертификатом Moru, и проверка release-APK.
Версия 0.1.44 (versionCode 45), пакет com.mishaqp.moru.
Проверка APK
{
"tag": "v0.1.44",
"version": "0.1.44",
"version_code": 45,
"package": "com.mishaqp.moru",
"abi": "arm64-v8a",
"commit": "fa65d02e166a8fcd38ff41886f30340934b1b5b8",
"filename": "Moru-v0.1.44-arm64-v8a-release.apk",
"sha256": "d8d6548df1a142451a275fa234ca548ae8fb390a6288966c39dc2502614fc79e",
"size_bytes": 37770635,
"certificate_sha256": "c5db7faec00b149db9406af2a714c963f9e6ad1632905e8237d04104f46182db"
}Moru v0.1.43
Moru v0.1.43 — проход по разделу «Фоновый режим»
Что делать, выбрали перед началом работы: удалить iOS-часть раздела и заменить старое имя «Kelivo» в уведомлениях. Работа в фоне на Android не менялась.
Проход по разделу «Фоновый режим»
Удалённая iOS-часть
Раздел был написан сразу под Android и iOS. На Android работала только его часть.
-
Экран настроек фонового режима. Удалена iOS-ветка:
- Live Activities;
- выполнение с помощью геолокации и разрешение на неё;
- «тихий звук»;
- озвучивание в фоне;
- iOS-статусы;
- iOS-предупреждение.
На Android вы этих пунктов не видели. Экран: 500 → 389 строк.
-
Настройки. Удалены пять полей, которые использовал только iOS:
iosEnabled,liveActivitiesEnabled,locationEnabled,silentAudioEnabled,backgroundSpeechEnabled. Android-настройки сохраняются как были: фоновое выполнение, уведомления, приватность, капсула, живые обновления, вид капсулы. -
Разделение звука между озвучкой и микрофоном. Координатор распределял звук между озвучкой, распознаванием речи и записью. На Android он выходил сразу, ничего не делая. Удалены:
- этот механизм;
- проверка «можно ли говорить в фоне» в озвучке. На Android она всегда разрешала;
- захват звука в распознавании речи;
- пауза озвучки по iOS-правилам при уходе приложения в фон.
-
Android-часть. Удалён пустой обработчик
audioOwner, который существовал только для iOS. -
Перевод. Удалены 20 iOS-строк во всех языках. Из подсказки о времени показа завершения убрано упоминание экрана блокировки iOS.
Moru вместо Kelivo в уведомлениях
- Запасное название фоновой задачи и уведомления, когда у чата нет названия или включена приватность, теперь «Moru».
- Бегущая строка уведомления о готовом ответе: «Moru».
- Английский и китайские переводы: «Moru task», «Moru icon», «Open Moru to continue». В русском переводе имя было правильным.
Что не менялось
- Название в списке недавних приложений. Приложение передаёт системе заголовок «Kelivo» (
MaterialApp.title). Это не раздел уведомлений, отмечено на будущее. - Сетевые заголовки
User-Agent: Kelivoи внутреннее имя пакета.
Дальше
- Следующий раздел выберем вместе перед началом работы. Предложение: тема в стиле «стекло» (Glassmorphism).
Проверка
- Тесты переведены на Android:
- экран настроек фонового режима: значения по умолчанию, разрешения, выравнивание значков, маленький экран;
- сохранение независимых переключателей;
- фоновая задача ждёт перехода к озвучке после ответа и только потом завершается.
- Озвучка: iOS-тесты захвата звука заменены двумя Android-тестами:
- пауза и продолжение, пока сервер ещё не ответил;
- поздний ответ сервера не запускает озвучку после остановки.
- Тест уведомлений запланированных задач: скрытое название теперь «Moru».
- Анализ без замечаний, полный набор Flutter-тестов.
- CI: анализ, Flutter-тесты, локализация, Android JVM-тесты, сборка одного
arm64-v8aAPK, подписанного постоянным сертификатом Moru, и проверка release-APK.
Версия 0.1.43 (versionCode 44), пакет com.mishaqp.moru.
Проверка APK
{
"tag": "v0.1.43",
"version": "0.1.43",
"version_code": 44,
"package": "com.mishaqp.moru",
"abi": "arm64-v8a",
"commit": "f1c56ae627d49a4fe3e867a39df6ea4f16fd4bf2",
"filename": "Moru-v0.1.43-arm64-v8a-release.apk",
"sha256": "57e3a7d1b6d221153a1898e0ec2aa2596250374b6584c2a43a7921c2546465fb",
"size_bytes": 37769315,
"certificate_sha256": "c5db7faec00b149db9406af2a714c963f9e6ad1632905e8237d04104f46182db"
}Moru v0.1.42
Moru v0.1.42 — проход по разделу «Синтез речи»
Что делать, выбрали перед началом работы: удалить мёртвый код и разбить большие файлы раздела. Поведение озвучки и распознавания речи на Android не менялось.
Проход по разделу «Синтез речи»
Удалённый код
- Озвучка. Настройка аудиосессии iOS перед каждым куском системной озвучки.
- Плавающий плеер. Десктопный вариант сохранения аудио. На Android файл, как и раньше, сохраняется через системное окно.
- Распознавание речи. Обход особенности отладочных сборок macOS: он запрещал системное распознавание при запуске из IDE. Удалены и два теста, которые проверяли только эту macOS-ветку.
- Локальный плагин
flutter_tts. Его урезали до Android:- папка
ios/: Swift- и Objective-C-реализация, podspec; - Web-реализация
flutter_tts_web.dartиinterop_types.dart. Она не была подключена ни к одной платформе; - iOS-методы и перечисления:
setSharedInstance,autoStopSharedSession,setIosAudioCategory, категории, режимы и опции аудиосессии; - зависимость
flutter_web_plugins.
- папка
Итого: −1421 строка в плагине, −70 в приложении и тестах.
Разбиение файлов
Код перенесён без изменений.
| Файл | Было строк | Стало |
|---|---|---|
| Сервисы озвучки и распознавания | 2423 | 531 — экран, 303 — список сетевых голосов, 1115 — редактор сетевого голоса, 481 — настройки системного голоса |
| Сервисы распознавания речи | 2257 | 226 — раздел, 309 — карточки сервисов, 684 — редактор, 796 — поля и выбор локальной модели, 251 — вспомогательные функции |
Что не менялось
- Логика «можно ли говорить в фоне» в озвучке. Она связана с фоновым режимом и его тестами, это отдельный раздел.
- Найденная ошибка: сетевая озвучка оставляет временные файлы
kelivo_tts_*во временной папке. Их можно удалить в «Хранилище → Системный кэш». Исправление отложено. - Кнопки «Озвучить» под сообщениями перестраиваются на каждое обновление позиции озвучки. Отложено.
Дальше
- Следующий раздел выберем вместе перед началом работы.
Проверка
- Тесты озвучки, распознавания речи, настроек и общих виджетов: 689 прошли.
- Анализ без замечаний, полный набор Flutter-тестов.
- CI: анализ, Flutter-тесты, локализация, Android JVM-тесты, сборка одного
arm64-v8aAPK, подписанного постоянным сертификатом Moru, и проверка release-APK.
Версия 0.1.42 (versionCode 43), пакет com.mishaqp.moru.
Проверка APK
{
"tag": "v0.1.42",
"version": "0.1.42",
"version_code": 43,
"package": "com.mishaqp.moru",
"abi": "arm64-v8a",
"commit": "5ebb9fc03c08b60fd895879480970c8376d12ed0",
"filename": "Moru-v0.1.42-arm64-v8a-release.apk",
"sha256": "0b180318a589ae750dbd6e376de897d9da29943d6260feb1e8fae723450949ac",
"size_bytes": 37773351,
"certificate_sha256": "c5db7faec00b149db9406af2a714c963f9e6ad1632905e8237d04104f46182db"
}Moru v0.1.41
Moru v0.1.41 — проход по разделу «Хранилище»
Что делать, выбрали перед началом работы: удалить десктопный код и разбить файл экрана. Поведение экранов на Android не менялось.
Проход по разделу «Хранилище»
Удалённый код
- Десктопная раскладка экрана: боковое меню категорий и панель с подробностями справа.
- Десять методов очистки на главной странице: кэш, прочий кэш, системный кэш, логи, старые данные чатов, следы восстановления, вытесненные базы, шрифты, локальные модели и файлы потерянных сессий. Их вызывала только десктопная раскладка. На Android очистка всегда шла со страницы категории, там всё осталось.
- Параметр
embeddedдля встраивания экрана в десктопные настройки. - Экспорт старых файлов чатов через десктопное окно «Сохранить как». На Android экспорт всегда шёл через системное сохранение, так и осталось.
- Десктопный переход к просмотру картинок.
- Исключение локальных копий из резервного копирования iCloud и проверки «Web / не Android и не iOS» при определении свободного места.
Итого: −698 строк в lib.
Разбиение файла
storage_space_page.dart был 2941 строку. Без десктопного кода он разбит на части, код перенесён без изменений.
| Часть | Строк |
|---|---|
| Главная страница: общий размер, полоса, список категорий | 377 |
| Страница категории: подробности и очистка | 932 |
| Файлы и изображения: список, фильтры, сортировка, выбор, удаление | 739 |
| Мелкие виджеты | 222 |
Что не менялось
- Подсчёт размера. Замер на 5000 файлах в данных приложения: около 1,07 с на подсчёт, а тот же обход в фоновом потоке занимает 52 мс. Ускорение отложили, бенчмарк
test/perf/storage_usage_bench.dartостался для следующего прохода.
Дальше
- Следующий раздел выберем вместе перед началом работы.
Проверка
- Существующие тесты раздела:
- очистка «Прочего» и старых данных чатов;
- экспорт старых файлов;
- подсчёт по категориям, рабочие папки;
- очистка вложений;
- список содержимого.
- Тесты настроек и резервных копий: 653 теста прошли.
- Бенчмарк
test/perf/storage_usage_bench.dart. - Анализ без замечаний, полный набор Flutter-тестов.
- CI: анализ, Flutter-тесты, локализация, Android JVM-тесты, сборка одного
arm64-v8aAPK, подписанного постоянным сертификатом Moru, и проверка release-APK.
Версия 0.1.41 (versionCode 42), пакет com.mishaqp.moru.
Проверка APK
{
"tag": "v0.1.41",
"version": "0.1.41",
"version_code": 42,
"package": "com.mishaqp.moru",
"abi": "arm64-v8a",
"commit": "a5ec6a0bb6e80f6d54feb6fca5a463c604b80043",
"filename": "Moru-v0.1.41-arm64-v8a-release.apk",
"sha256": "7835f679a281a8a976a34bbe9953333f9921d66efbb7041f19049129b7e4ca5b",
"size_bytes": 37772967,
"certificate_sha256": "c5db7faec00b149db9406af2a714c963f9e6ad1632905e8237d04104f46182db"
}Moru v0.1.40
Moru v0.1.40 — второй проход по разделу «Провайдеры»
Что делать, выбрали перед началом работы: удалить мёртвый код и разбить большие файлы раздела. Поведение экранов не менялось, кроме одного исправления.
Проход по разделу «Провайдеры»
Исправление
- Несколько ключей. Если в окне «Добавить» один и тот же ключ встречался дважды (например,
k1, k2 k1), он добавлялся двумя одинаковыми записями. Теперь каждый новый ключ добавляется один раз. Ключи, которые уже есть в списке, по-прежнему пропускаются.
Удалённый код
- Закомментированный список провайдеров, которых нет в приложении (Hunyuan, Kimi, StepFun, MiniMax, Mistral и другие).
- Закомментированные строки вибрации и значка баланса.
- Параметр
hapticsу кнопки на экране провайдера, который ничего не делал. - Вход через OAuth:
- условие «не Android и не iOS» у кнопки «Открыть в браузере»;
- iOS-вариант возврата из браузера после входа;
- заглушка для Web.
- Вход в Claude по подписке: определение ОС для заголовка запроса. На Android там всегда было
Linux, теперь это записано прямо. - Файлы Claude: десктопный лимит 500 МБ. На телефоне лимит был и остаётся 200 МБ.
Итого по удалению: 9 файлов, −114 / +6 строк.
Разбиение файлов
Код перенесён без изменений, поменялось только расположение.
| Файл | Было строк | Стало |
|---|---|---|
| Несколько ключей | 1331 | 769 — экран, 422 — окна стратегии, добавления и редактирования ключа, 153 — кнопки |
| Выбор модели | 1801 | 1439 — лист, 167 — подготовка списка моделей, 199 — мелкие виджеты |
| Карточка модели | 1511 | 879 — карточка, 635 — вкладки, переключатели и строки |
Что не менялось
- Экраны раздела по-прежнему следят за всеми настройками. Замер (отладочный тест, 20 провайдеров): открытый список провайдеров тратит около 50 мс на каждое постороннее изменение настроек, а спрятанный под экраном провайдера — около 37 мс на каждый введённый символ ключа или адреса. Этот пункт отложили, бенчмарк
test/perf/providers_section_bench.dartостался для следующего прохода. - Поиск в выборе модели: около 83 мс на символ при 1000 моделях. Тоже отложено.
Дальше
- Следующий раздел выберем вместе перед началом работы.
Проверка
- Новые тесты на экран «Несколько ключей»:
- добавление ключей: повтор в одном вводе и уже существующий ключ не добавляются, мульти-ключ включается. На старом коде тест падает;
- выбор стратегии сохраняется;
- редактирование сохраняет имя, ключ и приоритет;
- ключ, который уже есть у провайдера, при редактировании не сохраняется.
- Бенчмарк
test/perf/providers_section_bench.dart: список провайдеров, «Модели по умолчанию», открытие и поиск в выборе модели. - Анализ без замечаний, полный набор Flutter-тестов.
- CI: анализ, Flutter-тесты, локализация, Android JVM-тесты, сборка одного
arm64-v8aAPK, подписанного постоянным сертификатом Moru, и проверка release-APK.
Версия 0.1.40 (versionCode 41), пакет com.mishaqp.moru.
Проверка APK
{
"tag": "v0.1.40",
"version": "0.1.40",
"version_code": 41,
"package": "com.mishaqp.moru",
"abi": "arm64-v8a",
"commit": "277e5fd92c9f7163c0569b34ae683ea6ae769514",
"filename": "Moru-v0.1.40-arm64-v8a-release.apk",
"sha256": "ca9f12fa9c246699dcf9eb3e0cba1396fe0c5b8239365f295be851f592c6501c",
"size_bytes": 37773447,
"certificate_sha256": "c5db7faec00b149db9406af2a714c963f9e6ad1632905e8237d04104f46182db"
}Moru v0.1.39
Moru v0.1.39 — проход по разделу «Память»
Как договорились перед началом: логику памяти и то, что она отправляет модели в чате и в фоне, не трогаем. В релиз вошли очистка раздела, показ расхода токенов и новый способ построения списка записей.
Проход по разделу «Память»
Расход токенов
В Настройки → Память появился блок «Расход токенов».
-
«Добавляется к каждому запросу». Примерно сколько токенов память добавляет в запрос у ассистента с включённой памятью, отдельно по частям:
- инструменты памяти;
- правила памяти;
- снимок памяти: профиль и глобальные записи, с учётом ограничения «записей каждого типа».
У провайдеров с кэшем промптов повторяющаяся часть стоит дешевле, это указано в подписи.
-
«Фон сегодня». Сколько фоновых вызовов памяти было сегодня (привратник, извлечение, умное добавление, профиль) и примерно сколько токенов отправлено и получено. Счётчик сохраняется между запусками и обнуляется в полночь.
-
Это только подсчёт, работа памяти не меняется. Токены оцениваются приблизительно, как в кольце контекста: около 4 символов латиницы на токен. Для русского текста реальное число токенов будет выше.
Удалённый код
- Десктопные варианты экранов памяти: диалоги вместо нижних листов (выбор, редактор записи, редактор поля профиля, редактор промптов, перенос старой памяти в новую), десктопная панель фильтров и десктопное поле поиска в списке записей.
- Параметры отступов, которые передавали только удалённые десктопные панели настроек.
- Два теста, проверявшие десктопные диалоги на macOS.
- Итого: −742 / +83 строки. На Android все экраны работают как раньше.
Список записей
Список в «Записях» теперь строится через ListView.builder: создаются только видимые карточки.
Скорость при этом не изменилась, и честно скажу, что мой прогноз («28 → 1–2 мс») был ошибочным. Замер на 500 записях показал около 25 мс в отладочном тесте и до, и после. Оказалось, что невидимые карточки не строились и раньше, а время уходит на видимые карточки и панель фильтров. Это обычная стоимость экрана, заметной проблемы в ней нет.
Что не менялось
- «Старая память» осталась.
- Всё, что память отправляет модели в каждом запросе и в фоне, осталось прежним.
Дальше
- Следующий раздел выберем вместе перед началом работы.
Проверка
- Новые тесты:
- счётчик расхода: подсчёт вызовов и токенов, сохранение между запусками, обнуление в новый день, повреждённое значение;
- блок «Расход токенов» на экране настроек памяти.
- Бенчмарки
test/perf/memory_entries_bench.dart(список на 500 записях) иtest/perf/memory_token_budget_bench.dart(размер частей памяти в запросе и в фоне). - Анализ без замечаний, полный набор Flutter-тестов.
- CI: анализ, Flutter-тесты, локализация, Android JVM-тесты, сборка одного
arm64-v8aAPK, подписанного постоянным сертификатом Moru, и проверка release-APK.
Версия 0.1.39 (versionCode 40), пакет com.mishaqp.moru.
Проверка APK
{
"tag": "v0.1.39",
"version": "0.1.39",
"version_code": 40,
"package": "com.mishaqp.moru",
"abi": "arm64-v8a",
"commit": "422cd3175f6895c1f8101088edd0f0d5b6319889",
"filename": "Moru-v0.1.39-arm64-v8a-release.apk",
"sha256": "12dc3675aeb3e1b372efa95483f3a00f13f029d3c53eb70cec6c5404ed2cf5c6",
"size_bytes": 37774875,
"certificate_sha256": "c5db7faec00b149db9406af2a714c963f9e6ad1632905e8237d04104f46182db"
}Moru v0.1.38
Moru v0.1.38 — проход по разделу «Внешний вид и поведение»
Релиз без новых функций: оптимизация, удаление ненужного кода и разбор экранов раздела. Что делать, выбрали перед началом работы.
Проход по разделу «Внешний вид и поведение»
Тема больше не перестраивает всё приложение
- Что было. Корень приложения следил за всеми настройками сразу. Любое изменение — выбор модели, переключатель инструмента, бюджет рассуждений, настройка провайдера, ширина боковой панели на планшете при перетаскивании — заново собирало светлую и тёмную темы.
- Почему это было дорого. У цветового расширения темы не было сравнения, поэтому каждая пересобранная тема считалась новой. Приложение запускало 200-миллисекундную анимацию перехода к «новой» теме, и в каждом её кадре перестраивался открытый экран.
- Что стало.
- Корень следит только за настройками темы: палитра, своя тема, динамические цвета, чистый фон, слои, шрифт, режим, язык.
- Цвета темы сравниваются по значению.
- Прокси и фоновый режим отслеживают свои настройки отдельно.
- Проверка обновлений запускается один раз после загрузки настроек.
- Замер. 40 изменений посторонней настройки:
- было: 160 кадров, 80 перестроек экрана, 12,8 мс на изменение;
- стало: 40 кадров, 0 перестроек, 0,5 мс.
- Клавиатура. Корень больше не пересобирается при открытии клавиатуры. Раньше код для «плавающего iPad» заставлял его пересобираться в каждом кадре анимации клавиатуры и каждый раз заново настраивать фоновый сервис.
Экраны раздела
- Разбиение файлов.
display_settings_page.dart(2342 строки, пять страниц в одном файле) разбит по страницам: главная, отображение в чате, рендеринг, поведение, вибрация, общие строки. От экрана стиля сообщений отделены строки настроек и превью (1322 → 570 строк в основном файле). - Подписки. Каждая страница следит только за настройками, которые показывает. Мс на одно постороннее изменение настроек (медиана):
| Экран | Было | Стало |
|---|---|---|
| Внешний вид и поведение | 17,1 | 1,5 |
| Отображение в чате | 16,8 | 0,6 |
| Рендеринг | 10,3 | 0,5 |
| Поведение | 26,7 | 0,9 |
| Стиль сообщений | 9,8 | 5,3 |
Стиль сообщений ускорился меньше, потому что его превью рисует настоящие пузыри чата, а они сами следят за настройками. Это часть чата, а не этого раздела.
Удалённый код
- Проверки «Android или iOS» и «не Web» в настройках раздела: на Android они всегда давали один ответ.
- Десктопный вариант выбора шрифта в диалоге и десктопный диалог стиля сообщений вместе с его тестом.
- Подстройка экрана под «плавающий iPad» в корне приложения.
- Запасной набор шрифтов для Windows и два теста, проверявшие только его.
- Закомментированный отладочный вывод цветов темы.
Итого по удалению: 7 файлов, −204 / +42 строки. Поведение на Android не менялось.
Мини-приложения
- В отчёте автопроверки вместо пустого
Script error.теперь показывается настоящий текст ошибки из консоли, напримерUncaught ReferenceError: initWidgets is not defined. Так WebView скрывает детали ошибок страниц, открытых из файла.
Дальше
- Следующий раздел выберем вместе перед началом работы.
Проверка
- Новые тесты:
- тема перестраивается от настроек темы (палитра, режим, шрифт) и не перестраивается от других; две темы из одних настроек равны;
- каждый переключатель на страницах «Отображение в чате», «Рендеринг» и «Вибрация» меняется после нажатия: так тест поймает поле, забытое в подписке страницы (проверено — без поля тест падает);
- автопроверка:
Script error.заменяется текстом из консоли.
- Бенчмарки
test/perf/app_theme_rebuild_bench.dartиtest/perf/display_settings_bench.dart. - Анализ без замечаний, полный набор Flutter-тестов.
- CI: анализ, Flutter-тесты, локализация, Android JVM-тесты, сборка одного
arm64-v8aAPK, подписанного постоянным сертификатом Moru, и проверка release-APK.
Версия 0.1.38 (versionCode 39), пакет com.mishaqp.moru.
Проверка APK
{
"tag": "v0.1.38",
"version": "0.1.38",
"version_code": 39,
"package": "com.mishaqp.moru",
"abi": "arm64-v8a",
"commit": "a2a0ac03f036ae0bb8df61fc29bb20034ca4a8e9",
"filename": "Moru-v0.1.38-arm64-v8a-release.apk",
"sha256": "74f1ea35be49146f47ddee237c534ed06c1394f9e1e400ec1182c899863d045d",
"size_bytes": 37773387,
"certificate_sha256": "c5db7faec00b149db9406af2a714c963f9e6ad1632905e8237d04104f46182db"
}