- Agent REST API (agent_api.uc): Added GET /openapi.json returning OpenAPI 3.0.3 spec for ChatGPT Custom GPTs, N8N, Dify, and LLM Agents
- AI Doctor (runtime.uc): Added compress_log_snippet() for deduplicating repeated log entries and ai_doctor_lang support (ru/en prompt selection)
- Telegram Bot (telegram.uc): Added /ai_doctor and /fix commands with Inline Keyboards for instant quick-fix execution
- Settings (renderAdvancedSettings.ts, settings.js): Added AI Doctor Language selector (ru/en)
- Documentation: Updated README.md and README.en.md with 2026 AI features
Backend (runtime.uc, agent_api.uc, tachyon CLI):
- Enrich AI Doctor LLM context with Watchdog state (OOM, streaks, active repairs) and last 15 critical log lines
- Support multi-fix parsing (quick_fixes array) and comma-separated FIX tags
- Add persistent history saving to /tmp/ai_doctor_last.json and ai_doctor_last endpoint
- Expand quick fix codes from 9 to 13 (added clear_dns_cache, update_subscriptions, reset_firewall, restart_network)
- Implement apply_quick_fix CLI command and REST API endpoint
Frontend (fe-app-tachyon, LuCI main.js):
- Add AI Doctor action button in Diagnostics tab
- Add shell methods aiDoctor, aiDoctorLast, applyQuickFix
- Render AI Doctor modal with Multi-Fix buttons and 'Fix All' option
- Integrate toast notifications and state updates
Backend (runtime.uc):
- query_llm() accepts model_override (5th param), falls back to provider default
- ai_doctor() reads ai_doctor_model from UCI and passes to query_llm
Frontend (renderAdvancedSettings.ts):
- aiDoctorModel state field (type / init / load / save)
- Model dropdown per provider with sensible defaults:
openai: gpt-4o-mini(default)/gpt-4o/gpt-4.1-mini/gpt-4.1/o4-mini
anthropic: claude-3-5-haiku(default)/claude-3-5-sonnet/claude-3-7-sonnet
deepseek: deepseek-chat(default)/deepseek-reasoner
custom: free-text input
- Switching provider resets model to '' (use new provider default)
Legacy LuCI (settings.js):
- ai_doctor_model Value field with placeholder '(provider default)'
- При получении 'Another component action is already running' или сетевого
RPC-сбоя спиннер на нажатой кнопке больше не сбрасывается сразу.
- Добавлено повторное связывание (fallback lookups) с 800ms задержкой, чтобы
бэкенд успевал прописать запущенный job в state до снятия индикатора.
- При отслеживании запущенного задания теперь учитываются любые фоновые
акшны для того же компонента.
- В waitComponentActionJob добавлен минимальный порог ожидания (10с)
перед срабатыванием fallback проверки версии Tachyon. При same-release
обновлениях (одинаковый номер версии, но новый SHA) совпадение версии
больше не приводит к мгновенному (за 1с) снятию спиннера loading, пока
бэкенд на самом деле только скачивает и ставит пакет.
- Расширен список транзиентных RPC ошибок (isTransientRpcError) для
надежного перешивания перезапуска uhttpd/rpcd/ubus во время переустановки.
- Увеличен COMPONENT_ACTION_TRANSIENT_RPC_GRACE_MS до 60с.
Lock contention ('Another component action is already running') is an
expected transient state — user clicked a button while a previous action
was still in flight. Showing [error] toast confuses users into thinking
something broke. Filter it from the log watcher notification pipeline.
Also suppress DNS retry debug lines (issue #24 retry logs) from showing
as error toasts.
Added tests for both suppressed patterns.
- В query_llm (runtime.uc) добавлена интеграция с Anthropic Messages API (https://api.anthropic.com/v1/messages) с заголовком x-api-key
- В настройки Settings и Dashboard добавлен выпадающий выбор провайдера 'Anthropic (Claude API)'
- Добавлен русский перевод для опций AI Doctor
- Добавлена опция agent_api_token (AI Agent REST API Bearer Token) в CBI-форму настроек settings.js
- Сохраняет токен через стандартную кнопку Save & Apply в LuCI
- kill_matching_command и цикл зачистки fd/1000 прокси в package.uc теперь пропускют процессы ucode (action.uc / updates.uc) и их предков, предотвращая выбивание воркера обновлений по SIGKILL во время prerm
- isTransientRpcError теперь учитывает 'failed to execute' в качестве транзиентной ошибки RPC при перезапуске rpcd / служб во время обновления
- get_proxy_args() теперь поддерживает опцию UCI bot_proxy_section:
если sing-box запущен и секция указана, переключает GLOBAL outbound через REST API
- Исправлен краш 'left-hand side expression is null' при обработке
callback_query без поля from (например channel_post callbacks)
- В LuCI settings.js добавлен ListValue 'bot_proxy_section' с выпадающим
списком активных секций (паттерн аналогичен download_via_proxy_section)
- Локализация: ru/tachyon.po и templates/tachyon.pot синхронизированы
- Пересборка main.js через npm run build
Переводы для "Rebuilt release" и "Installed build → Available build"
были добавлены в исходный каталог после locales:distribute, поэтому
копия в luci-app-tachyon/po/ru разошлась и тест luci_localization
падал на cmp исходного и упакованного каталогов.
opkg считает пакет уже установленным при равенстве версий, поэтому
пересборка под тем же тегом молча не применялась: задание завершалось
успехом, билд оставался старым. Добавлен --force-reinstall в
pkg_install_files_command (opkg) и в install.sh; apk не тронут, он
всегда пишет переданный файл.
Детект пересборки больше не зависит только от SHA, которого нет в
релизах старше f974e4a0: добавлен отпечаток билда по published_at и
метаданным ipk-ассета, решение вынесено в tachyon_build_differs с
префиксным сравнением SHA разной длины. Отпечаток установленного
билда пишется в state-файл и попадает в extra.
Telegram уведомляет о пересборках: check_notified_updates пропускает
outdated_same_release, дедуп идёт по версии и SHA, текст показывает
короткие SHA вместо пары одинаковых версий.
Кэш проверки обновлений сохраняет current_sha из результата действия
вместо безусловного latest, иначе неудачная установка выглядела как
"актуально".
Фронт пересобран из TS, ручная правка main.js снята. Добавлен
describeSameReleaseBuild с фолбэк-текстом, когда SHA недоступен.
UI (section.js):
- showUrlTestSettingsModal и showPriorityLevelSettingsModal: предзагрузка
кэша outbound-имён до открытия модала — CBINamedSection.render() не
вызывает section.load(), из-за чего DynamicList рендерился без данных
- renderStackedJsonSettingsModal: вызов map.load() перед map.render()
LuCI ACL (luci-app-tachyon.json):
- Добавлены пути /tmp/run/tachyon/... наряду с /var/run/tachyon/...
На OpenWrt /var — симлинк на /tmp; rpcd резолвит симлинки перед
проверкой ACL, поэтому /var/run/... никогда не давал прав чтения
и fs.read() возвращал PermissionError
Postinstall (50_luci-tachyon):
- Добавлен перезапуск rpcd после установки пакета, чтобы новые ACL
вступали в силу без ручного logout/login в LuCI
Telegram-бот (telegram.uc):
- handle_toggle_mac(): блокировка/разблокировка устройств теперь
через правила firewall (fw4), а не через UCI blocked_macs
- /cb команда: разрешение токенизированных коллбэков для oversized
inline-клавиатур (лимит Telegram 64 байта на callback_data)
- /qh_start, /qh_end: интерактивная настройка часов тихого режима
- in_quiet_hours() и daily report: исправлен localtime(time())
вместо clock() — clock() возвращает [сек, мксек], а не tm-структуру
- Уведомления об обновлениях: current_version вместо installed_version
- Описание команды /restart исправлено
Backend (api.uc, state.uc):
- http_probe(): выделена функция с проверкой HTTP-статуса
(curl выходит 0 даже при 4xx/5xx — теперь проверяем код явно)
- run_speedtest(): учёт curl exit status
- Math.random() заменён на clock()[1] (Math недоступен без import)
- current_year(): убрано +1900 — localtime().year уже полный год