Files
elmer/doc/opus-fix-plan.md
T

6.7 KiB

План правок по отчётам Опуса

31 мая 2026 · ветка opus-fixes · порядок: по критичности + зависимостям


Этап 1. Сервер (elmer/) — 4 правки

1.1 🔴 api/db.py — WAL + закрытие соединений + request_id

Файл: api/db.py Строки: класс Database, методы _init_schema(), save_session()

  • Добавить PRAGMA journal_mode=WAL и busy_timeout=30000
  • Добавить колонку request_id TEXT UNIQUE в sessions
  • Метод close() и контекстный менеджер (__enter__/__exit__)
  • save_session() — проверять request_id на дубликат, возвращать кэшированный диагноз
  • Индекс idx_sessions_request_id

1.2 🔴 api/routes.py — идемпотентность upload + /ping-llm без LLM

Файл: api/routes.py Строки: upload_session(), ping_llm()

  • upload_session() — принимать request_id из JSON, возвращать кэш при дубликате
  • upload_session() — закрывать db через контекстный менеджер
  • upload_session() — не отдавать str(e) наружу, логировать, клиенту — обобщённый текст
  • /ping-llm — кэшировать результат на 60с, не вызывать LLM на каждый GET

1.3 🔴 obd/protocol.py — сброс буфера + не затирать ERROR

Файл: obd/protocol.py Строки: _write(), send()

  • _write()self._ser.reset_input_buffer() перед записью
  • send()if self._state == State.BUSY: self._state = State.READY (не безусловно)

1.4 🟡 brain/client.py — таймаут из конфига + модель

Файл: brain/client.py Строки: Diagnoser.__init__(), Diagnoser.ask()

  • DEFAULT_MODEL"gpt-oss-120b"
  • timeout — параметр конструктора (по умолчанию 180)
  • Комментарии: убрать «DeepSeek»

Этап 2. Сервер (elmer/) — улучшения (без 🔴 но важные)

2.1 🟡 api/routes.py — импорты наверх + кэш конфига

Файл: api/routes.py, api/config.py

  • Поднять импорты (from brain.client import Diagnoser и др.) на уровень модуля
  • api/config.py@lru_cache(maxsize=1) на load()

2.2 🟡 api/routes.py — история /chat через роли

Файл: api/routes.py Строки: chat()

  • Передавать историю как массив messages с ролями, а не строкой «Водитель:/Автоэксперт:»

2.3 🟡 brain/client.py — обработка ошибок LLM

Файл: brain/client.py

  • Различать Timeout, HTTPError(429), HTTPError(5xx), HTTPError(4xx)
  • Не отдавать детали исключения наружу

Этап 3. Android (elmer-android/) — 6 правок

3.1 🔴 ServerClient.kt — request_id + идемпотентность

Файл: app/src/main/java/ru/elmer/client/server/ServerClient.kt Строки: uploadSession()

  • Генерировать UUID один раз до цикла ретраев
  • Добавить "request_id" в JSON-тело
  • Добавить заголовок Idempotency-Key

3.2 🔴 ServerClient.kt + build.gradle.kts — X-Api-Key

Файлы: ServerClient.kt, app/build.gradle.kts

  • build.gradle.ktsbuildConfigField("String", "API_KEY", ...)
  • ServerClient — добавлять X-Api-Key во все запросы
  • MainActivity.sendToLlm() и startTest() — тоже X-Api-Key

3.3 🔴 ElmProtocol.kt — не затирать ERROR + дренаж буфера

Файл: app/src/main/java/ru/elmer/client/elm/ElmProtocol.kt Строки: sendCommand(), write()

  • sendCommand()if (state == State.BUSY) state = State.READY
  • write()while (input.available() > 0) input.read() перед записью

3.4 🔴 SessionDb.kt — безопасная миграция + индекс

Файл: app/src/main/java/ru/elmer/client/db/SessionDb.kt Строки: onUpgrade(), onCreate()

  • onUpgrade()ALTER TABLE вместо DROP TABLE
  • Индекс idx_resp_session ON responses(session_id)

3.5 🔴 MainActivity.kt — /ping-llm без LLM + двойной receiver + chatHistory

Файл: app/src/main/java/ru/elmer/client/ui/MainActivity.kt Строки: startTest(), sendToLlm(), receiver-регистрация

  • startTest() — троттлить /ping-llm (не чаще раза в 60с), предупреждать
  • Убрать дублирующий receiver statusReceiver (оставить scriptStatusReceiver)
  • chatHistory сохранять в onSaveInstanceState (JSON)

3.6 🔴 ScriptRunnerService.kt — null intent + мёртвый paused + try/finally

Файл: app/src/main/java/ru/elmer/client/script/ScriptRunnerService.kt Строки: onStartCommand(), executeScript()

  • onStartCommand()if (intent == null) { stopSelf(); return START_NOT_STICKY }
  • Убрать мёртвый флаг paused и ACTION_RESUME (или доделать паузу)
  • executeScript()try/finally вокруг progress.stop()

Этап 4. Android (elmer-android/) — улучшения

4.1 🟡 ServerClient.kt — exponential backoff

Файл: ServerClient.kt

  • (1 shl (attempt-1)) * 1000 + Random.nextLong(0, 500) вместо фиксированных 2000

4.2 🟡 MainActivity.kt — единый HTTP-клиент

Файл: MainActivity.kt

  • sendToLlm() и startTest() перевести на OkHttp (через ServerClient)

4.3 🟡 ScriptRunnerService.kt — вынести хост в константу

Файл: ScriptRunnerService.kt, MainActivity.kt

  • obdai.ruBuildConfig.SERVER_HOST или константа

Порядок выполнения

Этап 1 (сервер 🔴) → коммит
Этап 2 (сервер 🟡) → коммит
Этап 3 (Android 🔴) → коммит
Этап 4 (Android 🟡) → коммит

После каждого этапа — проверка: python run.py (сервер), сборка APK (Android).