Commit Graph
1862 Commits
Author SHA1 Message Date
Dushnilin 8d6041f9fa chore: remove test.uc 2026-08-12 10:50:56 +03:00
Dushnilin 3672af46d8 fix(diagnostics): type error on float conversion in ucode
Replaced non-existent \loat()\ function with unary plus coercion for string to number conversion in service_check.uc.
2026-08-12 10:50:43 +03:00
Dushnilin 2bd2fd7645 feat(diagnostics): нативная кнопка проверки сервисов
Реализована нативная проверка сервисов (watchdog, telegram, sing-box) через ucode, избавляя от внешней зависимости forkop-servicecheck.
2026-08-12 10:42:09 +03:00
Dushnilin 2b4d8cd4e0 fix(i18n): wrap Ollama and LM Studio labels in _() with English defaults and update po/pot 2026-08-11 22:29:34 +03:00
Dushnilin 1a1fd7f4c3 fix(settings): add Ollama & LM Studio to CBI settings tab options and make API key optional for local LLMs 2026-08-11 22:27:57 +03:00
Dushnilin 5db8ed7889 feat(ai-doctor): add dynamic endpoint placeholders and optional API key hint for Ollama and LM Studio 2026-08-11 22:11:48 +03:00
Dushnilin 40e185c143 i18n: actualize translation pot and po files for 1.2.74 2026-08-11 22:01:21 +03:00
Dushnilin da199c236a feat(ai-doctor): super-upgrade with Live Stepper, Root Cause Graph, Smart Fix Badges, Deep Log Inspection & Local LLM Presets 2026-08-11 22:00:20 +03:00
Dushnilin bc8a60fc73 fix(ui): hide legacy doctor repair button and make AI Doctor always clickable 2026-08-11 21:35:27 +03:00
Dushnilin 7c39a5335f ci: enable generate_release_notes in release workflow 2026-08-11 21:21:24 +03:00
Dushnilin a7c391cbdb fix(singbox): preserve cache.db across restarts and ensure parent directory 2026-08-11 21:10:07 +03:00
Dushnilin 15a4f8962e fix(ui): add close and copy buttons to AI Doctor modal footer 2026-08-11 20:15:50 +03:00
Dushnilin e140766215 fix(ci): bypass node tls validation in release step 2026-08-11 19:54:45 +03:00
Dushnilin ee44f21d77 fix(ui): remove duplicate commit sha formatting in header 2026-08-11 19:47:41 +03:00
Dushnilin 999686fea3 fix(ui): display short commit SHA next to Tachyon version in UI and constants 2026-08-11 19:06:00 +03:00
Dushnilin 4d0eb2ea6a fix(action): use explicit else block in check_tachyon for outdated_same_release 2026-08-11 18:44:54 +03:00
Dushnilin c192eb5e5e fix(updater): inline tag normalization in release_metadata_tsv to prevent ucode order warning 2026-08-11 18:36:44 +03:00
Dushnilin 680802a62d fix(updater): strip leading v prefix in tachyon_normalized_release_version 2026-08-11 18:17:56 +03:00
Dushnilin 2ef7092810 feat: Add local heuristic AI Doctor engine, DPI block analyzer, and offline fallback 2026-08-11 17:26:53 +03:00
Dushnilin f790917999 release: v1.2.70 - Tachyon AI Doctor & Agent API 2026-08-11 16:37:24 +03:00
Dushnilin 180c52ecde test: fix BusyBox portability issues in backend test suite 2026-08-11 16:33:46 +03:00
Dushnilin 3ddd321575 docs: add Hosts Engine section detailing static DNS overrides, remote host lists, and mirror retry logic 2026-08-11 16:13:34 +03:00
Dushnilin 5b6e0c6a78 docs: remove explicit year mention from AI section titles 2026-08-11 16:12:51 +03:00
Dushnilin e93928cba2 docs: overhaul README.md and README.en.md with comprehensive 2026 feature list, AI stack, Watchdog architecture, Telegram bot commands, and CLI reference 2026-08-11 16:12:14 +03:00
Dushnilin be5f41a52e feat(ai-stack-2026): add OpenAPI 3.0.3 schema, Telegram /ai_doctor & /fix integration, AI language selector, and log deduplication
- 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
2026-08-11 16:10:31 +03:00
Dushnilin 6dd085b777 feat(ai-doctor): supercharge AI Doctor with multi-fix, log context, history, and 13 quick fix codes
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
2026-08-11 16:06:19 +03:00
Dushnilin 4a6b24ef28 docs(agent): update AGENT.md with comprehensive AI Doctor and Agent API configuration guide
Details include:
- AI Doctor setup (enable, provider, model override, api key, custom url)
- Supported LLM providers and custom model options
- 9 Quick Fix repair codes
- Watchdog CLI commands
- HTTP REST Agent API read/write endpoints and auth
- cURL and SSH integration examples
2026-08-11 15:59:38 +03:00
Dushnilin 1e365a1f9b refactor(ai-doctor): replace model dropdown with free-text input
Simpler UX: user types any model name directly.
Placeholder shows the provider default so field can stay empty.
2026-08-11 12:40:23 +03:00
Dushnilin 3d48a22e3c feat(ai-doctor): add model selection per provider
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)'
2026-08-11 12:37:31 +03:00
Dushnilin af7941f839 fix(tests): replace printf|grep-qx with grep<<<var to avoid broken-pipe false failures
With set -eo pipefail, when grep -qx exits early after finding a match
printf gets SIGPIPE and returns non-zero, which with pipefail triggers the
|| fail branch even though grep returned 0 (found).
Here-string avoids the pipe entirely.
2026-08-11 12:22:28 +03:00
Dushnilin a1b1531ee8 fix(tests): update watch_recovery signature in heal_escalation.sh 2026-08-11 12:16:05 +03:00
Dushnilin 188a1b4fe8 fix(tests): update tests for watchdog refactoring
heal_suppression.sh:
- claim/release_root_cause -> wan_repair_until/singbox_repair_until
- suppressed_by_root_cause(healer, priority) -> (healer)
- driver updated to use new two-var API

heal_outcome.sh:
- watch_recovery(key, recovery_event, incident, reason) -> (key, incident, reason)
- add check that reason: field still present

heal_dns_idempotent.sh:
- replace ai_enabled mock with settings() mock
- fix suppressed_by_root_cause to single-arg signature
- fix ucode // comment (was #)
2026-08-11 11:16:25 +03:00
Dushnilin 1bf1af3783 fix: is_dns_working() -> controller.is_dns_working() in ai_heal_dns_loop 2026-08-11 11:11:05 +03:00
Dushnilin b194666b84 ponytail: chistka watchdog + event_controller
event_controller.uc:
- check_tachyon_cli_running: zamenen polnyy /proc-skan na pgrep -f
- tproxy_port(): dobavlen kesh cached_tproxy_port

watchdog.uc:
- Udaleny 7 delegatov-oborotok
- active_root_causes zamenen dvumya var wan_repair_until/singbox_repair_until
- watch_recovery: ubrano mertvoe pole event
- ai_setting/ai_enabled udaleny, UCI chitaetsya napryamuyu
- safe_call: ubran flag ai_graceful_degradation_enabled

Testy: 511/511
2026-08-11 11:00:36 +03:00
Dushnilin 7ad428ddc8 refactor(watchdog): оптимизация и устранение дублирования кода
- watchdog: удалён дублирующий check_tachyon_cli_running(), везде используется controller.check_tachyon_cli_running()
- watchdog: smart_detect_process_pending использует controller.proxy_port() вместо повторного парсинга config.json
- watchdog: удалена однострочная обёртка is_dns_dead() — заменена is_dns_working() напрямую
- watchdog: heal_proxy_connectivity требует streak >= 2 перед очисткой cache.db — устраняет ложные ночные уведомления при кратких просадках прокси-ноды
- event_controller: push_history переведён на slice() вместо ручного цикла
- event_controller: direct_ok использует тот же check_url что и proxy check — корректность при кастомном ai_proxy_health_url
- event_controller: добавлен subscription_fail_streak — одиночный таймаут сети больше не триггерит Telegram
- telegram: tg_request больше не создаёт временные файлы в /tmp — JSON передаётся напрямую через curl -d, устранена утечка tg_payload_*.json при kill процесса
- telegram: worker() при старте удаляет оставшиеся tg_payload_*.json от предыдущих сессий
- tests: исправлен шаблон mktemp в background_spawn_fds.sh — busybox не поддерживает двойное расширение (.XXXXXX.uc)
2026-08-11 08:47:47 +03:00
Dushnilin c88acdffa5 fix(dns): использовать --doh-url https://1.1.1.1/dns-query в curl при отсутствии c-ares (--dns-servers)
- В сборках OpenWrt без c-ares libcurl не поддерживает --dns-servers,
  что заставляло curl использовать системный DNS (dnsmasq).
- Во время рестарта или перед стартом sing-box dnsmasq был перенаправлен
  на неработающий порт sing-box 5335, из-за чего curl получал Could not
  resolve host (exit 6), создавая замкнутый круг и бесконечный падеж
  сервиса при скачивании подписок/списков.
- Добавлен автоматический фолбэк на DoH (--doh-url https://1.1.1.1/dns-query),
  который работает без c-ares и считывает IP адреса серверов подписок/списков
  напрямую в обход падающего системного DNS.
2026-08-10 21:42:49 +03:00
Dushnilin 8be248f9fd fix(ui): непрерывная индикация анимации на кнопке обновления без мигания
- При получении 'Another component action is already running' или сетевого
  RPC-сбоя спиннер на нажатой кнопке больше не сбрасывается сразу.
- Добавлено повторное связывание (fallback lookups) с 800ms задержкой, чтобы
  бэкенд успевал прописать запущенный job в state до снятия индикатора.
- При отслеживании запущенного задания теперь учитываются любые фоновые
  акшны для того же компонента.
2026-08-10 21:38:46 +03:00
Dushnilin dd3546f29a fix(updates): предотвратить ложный сброс индикации загрузки при переустановке одинаковых версий
- В waitComponentActionJob добавлен минимальный порог ожидания (10с)
  перед срабатыванием fallback проверки версии Tachyon. При same-release
  обновлениях (одинаковый номер версии, но новый SHA) совпадение версии
  больше не приводит к мгновенному (за 1с) снятию спиннера loading, пока
  бэкенд на самом деле только скачивает и ставит пакет.
- Расширен список транзиентных RPC ошибок (isTransientRpcError) для
  надежного перешивания перезапуска uhttpd/rpcd/ubus во время переустановки.
- Увеличен COMPONENT_ACTION_TRANSIENT_RPC_GRACE_MS до 60с.
2026-08-10 21:30:03 +03:00
Dushnilin 5cbbd0f661 fix(ui): suppress 'Already running' and DNS retry toasts
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.
2026-08-10 21:01:21 +03:00
Dushnilin 7679715fcc fix: curl --dns-servers compatibility + DNS retry on sing-box restart
- Guard --dns-servers behind runtime capability check (requires libcurl
  with c-ares). OpenWrt builds without c-ares now skip the flag silently
  instead of crashing curl with 'option not supported'.
  Affects: subscription/cache.uc, components/updates.uc

- On DNS resolution failure (curl exit 6), retry with increasing backoff
  (5s, 10s, 15s) before giving up, instead of immediately breaking.
  Fixes transient 'Could not resolve host' during sing-box restart when
  Tachyon's intercepting DNS resolver is briefly unavailable (issue #24).

- Fix stale component-action lock deadlock: pid_running now validates
  /proc/<pid>/cmdline against ucode/tachyon/sh pattern + 300s TTL.
  Background check_update exits cleanly on lock contention instead of
  emitting [error] toasts (action.uc, state.uc, initd.uc).
2026-08-10 20:48:52 +03:00
Dushnilin 9b110b226d fix(core): исправить ложное застревание блокировок компонентных действий и отключить всплывающие ошибки при фоновой проверке
- Проверять /proc/<pid>/cmdline при валидации PID (исключает ложное определение dnsmasq/sing-box как владельца блокировки при рециркуляции PID в Linux)
- Добавить автоматическую очистку зависших блокировок старше 300 секунд (TTL)
- При фоновой автоматической проверке обновлений (action == check_update) пропускать занятые блокировки без записи [error] в syslog и появления всплывающих нотификаций
2026-08-10 19:43:30 +03:00
Dushnilin 31c36118ef refactor(ui): сгруппировать все параметры Settings по вкладкам (cbi-tabgroup)
- Настройки разделены на 6 категорий: DNS, Сеть, Сервисы, Обновления, ИИ и Системные
- Устранена длинная простыня прокрутки — каждая категория открывается во вкладке
2026-08-10 19:30:51 +03:00
Dushnilin c930c15dc3 feat(ai): добавить поддержку Anthropic Claude API в AI Doctor
- В query_llm (runtime.uc) добавлена интеграция с Anthropic Messages API (https://api.anthropic.com/v1/messages) с заголовком x-api-key
- В настройки Settings и Dashboard добавлен выпадающий выбор провайдера 'Anthropic (Claude API)'
- Добавлен русский перевод для опций AI Doctor
2026-08-10 19:16:19 +03:00
Dushnilin a15490c67d i18n: добавить русский перевод для AI Agent REST API в PO файлы 2026-08-10 19:14:41 +03:00
Dushnilin 8a71a5a1a4 feat(luci): добавить поле AI Agent REST API Token в стандартную вкладку Settings
- Добавлена опция agent_api_token (AI Agent REST API Bearer Token) в CBI-форму настроек settings.js
- Сохраняет токен через стандартную кнопку Save & Apply в LuCI
2026-08-10 19:13:51 +03:00
Dushnilin 1171cee9fd feat(ui): добавить управление токеном AI Agent REST API в LuCI
- В Advanced Settings (Dashboard) добавлен новый блок 'AI Agent REST API (12 Endpoints)'
- Позволяет просматривать, изменять и генерировать Bearer Auth Token (agent_api_token) для REST API из веб-интерфейса
- Сохраняет токен в UCI (tachyon.settings.agent_api_token)
2026-08-10 19:11:48 +03:00
Dushnilin e67e8c0984 fix(package): исключить воркеры обновления из зачистки процессов при апгрейде
- kill_matching_command и цикл зачистки fd/1000 прокси в package.uc теперь пропускют процессы ucode (action.uc / updates.uc) и их предков, предотвращая выбивание воркера обновлений по SIGKILL во время prerm
- isTransientRpcError теперь учитывает 'failed to execute' в качестве транзиентной ошибки RPC при перезапуске rpcd / служб во время обновления
2026-08-10 18:57:19 +03:00
Dushnilin b11780dec3 fix: ждать TCP-готовности proxy перед загрузкой отложенных подписок
run_deferred_subscription_bootstrap теперь после проверки что процесс
sing-box запущен дополнительно проверяет что proxy-порт реально принимает
соединения (до 10x3s).

Без этого: если порт не готов в момент вызова — fallback на прямой
download, что провалится для URL доступных только через proxy.
При неудаче через 30s запускается retry worker (поведение сохранено).

Также: get_subscription_download_proxy_address делает одиночную проверку
порта — retry worker является safety net для edge cases.
2026-08-10 18:27:38 +03:00
Dushnilin f5929d24f8 fix: дождаться готовности proxy перед загрузкой подписок и списков
При обновлении sing-box Tachyon перезапускается, запускает sing-box
и сразу пытался загрузить списки/подписки через proxy 127.0.0.1:4534,
но sing-box ещё не принял соединения на этом порту.

Исправления:
- updates.uc: dns_probe_passed теперь проверяет TCP-доступность proxy
  вместо немедленного return true; ждёт до 30s (10 попыток по 3s)
- updates.uc: download_to_file при неудаче через proxy делает fallback
  на прямой download с bootstrap DNS 8.8.8.8/1.1.1.1
- cache.uc: get_subscription_download_proxy_address проверяет что proxy-порт
  реально принимает соединения, иначе переходит на прямой download
- cache.uc: download_subscription использует bootstrap DNS при прямом
  скачивании подписок (когда proxy недоступен или не настроен)
2026-08-10 18:10:36 +03:00
Dushnilin 6379361d40 chore: поднять версию до 1.2.67 2026-08-10 14:17:33 +03:00