Commit graph

35 commits

Author SHA1 Message Date
Hermes Team
87d83251bb feat(router): integrate local LLM provider (llama.cpp/vLLM/Ollama) with zero quotas (A25) 2026-08-24 14:00:25 +07:00
Hermes Team
ef6a9e1acd fix: веб-сервер не запускался на Windows, диаграмма тормозила при перетаскивании
Три дефекта из установки владельца на вторую машину.

1. Веб-сервер падал сразу: «web server process terminated unexpectedly».
   Установщик ставит в venv Hermes только customtkinter, pillow, pyyaml и
   psutil — fastapi и uvicorn отсутствовали в списке вовсе. Добавлены во
   все шесть мест: проверка, сообщение, pip, uv, перепроверка.
   Поэтому на Windows открывался только десктоп: веб физически не мог
   стартовать.

2. Лаунчер показывал голое «terminated unexpectedly» без причины — та же
   болезнь, что у кода 12. Теперь перехватывает вывод процесса и выводит
   последние строки ошибки в окне.

3. Окно тормозило при перетаскивании и продолжало двигаться несколько
   секунд после отпускания мыши. _RouteDiagram перерисовывал всю канву на
   КАЖДОЕ событие <Configure>, а при перетаскивании их сотни; очередь не
   успевала разгребаться. Гашение в приложении существовало, но
   _handle_debounced_resize был пустой заглушкой.
   Перерисовка сведена к одной после затишья. Замерено: 199 событий
   давали 199 перерисовок, теперь 4.

Тесты: 373 passed, ruff чисто. Установщик пересобран.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-24 09:59:41 +07:00
Hermes Team
1e1b81665b feat(router): profile auth self-healing, honest model validation, and manual model refresh (A23) 2026-08-24 02:02:28 +07:00
Hermes Team
ae813a991b feat(antigravity): implement native agy login, profile isolation, and protect global ~/.gemini (A22) 2026-08-23 23:57:57 +07:00
Hermes Team
e42f262b6d feat(A15): веб-API, общий ActionExecutor и порт путей на Linux
Работа A15 выполнена, но не закоммичена: git в его окружении был
недоступен. Восстановлена ревьюером из рабочего каталога.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-23 19:45:13 +07:00
Hermes Team
99af66d717 feat(ui): A12 — компактные карточки аккаунтов, доступность причин Н/Д, упорядочивание провайдеров и тест службы моделей 2026-08-23 13:30:20 +07:00
Hermes Team
cdfd9f1c8d Merge antigravity/quotas-models-migration (A9)
Проверено исполнением на живой конфигурации владельца.

Принято:
- миграция конфигурации работает: 16 -> 22 профиля, claude и grok
  получили по 3 слота, find_free_slot возвращает существующие профили по
  всем пяти провайдерам. Это снимает корень жалобы «при подключении
  грока ошибка»;
- резервная копия router_profiles.yaml.bak_<ts> создаётся, десять
  профилей antigravity не изменены ни в одном поле, комментарии не
  потеряны;
- квоты grok и opencode-go честно отдают None с причиной вместо
  правдоподобных чисел;
- флаг /repair и /reinstall задействован (строка 979), предупреждение
  CS0219 при сборке исчезло;
- граница зоны Codex не нарушена, правка плагина 2d62d39 сохранена.

Исправлено при слиянии:

1. Служба обнаружения моделей была недостижима. A9 создал
   model_discovery_service.py, интерфейс импортирует model_discovery.
   Импорт обёрнут в except ImportError, поэтому расхождение не давало
   ошибки — выбор моделей просто оставался пустым навсегда. Добавлена
   согласованная точка входа model_discovery.py.

2. Служба отдаёт discovered_at, каталог искал fetched_at/updated_at.
   Каталог научен понимать discovered_at.

3. tests/test_ui_routing_graph.py закреплял выдуманный список моделей
   ("grok-3"). A9 верно убрал литералы, и тест начал падать. Тест
   приведён к честному поведению: до обнаружения профиль остаётся без
   моделей. Файл в зоне Codex, которому A9 запрещено было её трогать.

Тесты: 307 passed, 2 skipped, ruff чисто.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-23 12:57:49 +07:00
Hermes Team
7468c7cc8b feat: add cockpit-style model and card controls 2026-08-23 10:54:08 +07:00
Hermes Team
b625b0f3e5 Merge codex/usability-fixes into review/a8 (A8 + B6/B7)
Сводит две работы: A8 (Antigravity — запуск, развёртывание, самопроверка)
и codex/usability-fixes (B6 граф маршрутизации + B7 дефекты живого прогона,
плюс живой сбор квот).

Проверено исполнением на реальных аккаунтах владельца: квоты Antigravity
теперь приходят от провайдера (source=provider_api) по всем шести
авторизованным профилям с разными числами — ag-w2 показывает 37.4%
остатка недельного пула Claude/GPT. OpenCode Go честно отдаёт None
с причиной.

Разрешение конфликтов:

1. do_test_profile — оба агента чинили P0-3 по-разному. Сохранены обе
   правки: проверка просроченной авторизации (A8) поверх локальной
   проверки runtime без вызова модели (Codex).

2. _finish в мастере — взята содержательная версия Codex (проверка слота,
   создание определения профиля, внесение в маршрутизацию, сброс
   cooldown), но её хвост обёрнут так, чтобы сбой в журналировании или
   on_complete не оставлял окно открытым. Регрессия 7090c8a закрыта
   тестом и продолжает проходить.

Исправлено при слиянии: A8 проверял status.get("expired"), тогда как ключ
называется is_expired. Проверка была мертва изначально — её прикрывал
контроль в адаптере, и это вскрылось только когда Codex убрал вызов
адаптера из «Теста»: протухший аккаунт получал зелёную галочку.

Тесты: 288 passed, 2 skipped, ruff чисто.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-23 01:12:31 +07:00
Hermes Team
17c266339f fix: restore weekly quotas and reconcile live health 2026-08-23 00:15:18 +07:00
Hermes Team
7d77877358 fix: show live quotas in fixed account cards 2026-08-22 23:45:37 +07:00
Hermes Team
40b3466558 fix: complete B7 live usability flows 2026-08-22 22:30:41 +07:00
Hermes Team
7090c8ae6f fix(wizard): «Завершить подключение» не закрывало окно
_finish первой же строкой вызывал EventLogService.log_event — метода с
таким именем у сервиса нет, есть log(category, message, details, level).
AttributeError уходил в обработчик Tk, а под pythonw консоли нет, поэтому
для владельца кнопка просто не работала: окно оставалось открытым,
on_complete не вызывался, аккаунт не попадал в маршрутизацию.

Вызов приведён к настоящему API. Журналирование и обратный вызов
обёрнуты так, чтобы сбой в них не запирал пользователя в мастере, —
закрытие окна не должно зависеть от побочных действий.

Воспроизведено и проверено исполнением: до правки winfo_exists=1 и
on_complete не вызван, после — окно уничтожено, результат передан.

Тесты: 252 passed в venv Hermes. Единственный сбой
(test_oauth_lifecycle::test_f_copy_before_open_browser, TclError) и
FAILED релизного гейта воспроизводятся на чистом main и к этой правке
отношения не имеют.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-22 21:43:51 +07:00
Hermes Team
f0461bc539 fix: repair account setup and routing actions 2026-08-22 21:13:02 +07:00
Hermes Team
4c45a1c73c feat: add working routing graph editor 2026-08-22 21:13:01 +07:00
Hermes Team
312f699085 fix(ui): align dashboard and navigation with approved mockup 2026-08-21 19:32:53 +07:00
Hermes Team
e4843b5a39 feat(ui): implement approved three-theme mockup redesign 2026-08-21 19:06:46 +07:00
Hermes Team
95d80268f4 feat(ui): wire state contract v1.1 fields 2026-08-21 09:04:53 +07:00
Hermes Team
d0d15ae99a feat(ui): complete redesign phases 2 through 6 2026-08-21 08:41:50 +07:00
39b1f928f4 fix(wizard): restore Antigravity OAuth by matching the 3-tuple session API
0d9005f changed start_profile_oauth to return (session_id, auth_url, port) and
updated the tests, but not its callers. The wizard still unpacked two values, so
every Antigravity connection raised ValueError inside _init_antigravity_oauth,
the handler swallowed it, and the authorization URL never appeared — the primary
onboarding flow has been dead since that commit.

Also stores the listener port as wizard.oauth_port, which the single-session
invariance test reads to prove that repeat "open browser" clicks reuse the
existing listener instead of binding a new one.

Both defects were caught only by tests that the headless run skips, which is why
they survived several reviews.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-21 08:00:42 +07:00
a7027b42d5 refactor(ui): centralize design tokens and complete the component library
PHASE 1 of the UI redesign. Adds semantic colour roles that keep brand gold out
of health states, layout and typography aliases so views stop hand-rolling
padding, and the reusable widgets the redesign depends on: PlanBadge, QuotaBar,
QuotaBucketWidget (stable key plus in-place update), SearchField, FilterButton,
ActionButton, IconButton, EmptyState, RouteTargetWidget, AccountCardWidget,
AgentCardWidget, ConfirmDialog, Toast, plus ellipsize/tooltip helpers for long
account identities.

test_unknown_quota_is_supported_explicitly compared inspect's resolved
annotation object against source strings, so it could only pass while being
skipped; components.py has no `from __future__ import annotations`. Rewritten
to assert through typing.get_args that QuotaBar.set_value accepts None.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 23:35:10 +07:00
a9c04b75a2 fix(ui): repair startup crash in TeamView and tighten the headless guard
Launching the app died with "'dict' object has no attribute 'readiness'".
TeamView.__init__ forwarded its legacy app_state dict into update_data(snapshot),
whose guard only handled None, so {} reached snapshot.readiness. TeamView is the
default view, so the window never appeared.

Fixes the call site and hardens every snapshot guard to fall back on anything
that is not a HubSnapshot. Adds tests/test_view_startup_contract.py, which
checks both conditions statically and therefore runs headless; verified to fail
on the pre-fix sources.

The GUI-import invariant previously matched the literal string "customtkinter",
which missed modules pulling it transitively. Rewritten over the AST, it
immediately found test_codex_opencode_wizard.py importing router.ui.components
without pytest.importorskip — the same defect that took the release gate down
once before, hidden until now behind conftest's name-based skip.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 23:22:19 +07:00
63c0385f5c fix: repair seven undefined names and make CI ruff step meaningful
`ruff check .` failed on every push since CI was added (1221 findings), so the
job aborted before pytest and the release gate ever ran. Adds [tool.ruff]
selecting bug-catching rules only (E9, F63, F7, F82, F811); style and
modernization rules stay off until their ~1200 findings are burned down.

That selection immediately surfaced seven live defects:
- hermes_hub_app: HubModal used but never imported, so the "Назначить" role
  modal raised NameError — the handler added to close an earlier review
  finding could never open.
- hermes_hub_app: three `after(0, lambda: ...(e))` callbacks referencing the
  except-bound name, which Python unbinds at block exit, so every UI error
  path raised NameError instead of reporting the error.
- auto_assigner: build_team_hierarchy referenced an undefined `is_main` and
  crashed on every call.
- ui/assets and live_provision_and_validate: annotations naming Any/Tuple
  without importing them.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 22:28:08 +07:00
Hermes Team
42eddb3627 fix(quota, oauth): enforce data truthfulness, honest quota sources, and fail-closed OAuth
- Removed fabricated used_percent numbers and fake *_api source tags from quota_collector.py
- Marked quota snapshot sources as baseline/estimated and added visual estimation indicators in accounts_view.py
- Eliminated silent fallback on fake user_code/device_code in codex_oauth.py and grok_oauth.py
- Gated mock OAuth sessions strictly behind HERMES_HUB_DEV_MODE=1 with visible UI warnings
- Documented Google, OpenAI, xAI, and Claude OAuth clients in docs/OAUTH_CLIENT.md
- Relocated unused gui_server.py and gui_cockpit.html to legacy/
- Added test_data_truthfulness_and_oauth_security.py covering fail-closed and source truthfulness invariants
- Verified 98 passed tests (100%) and 7/7 release gate checks
2026-08-20 22:11:57 +07:00
Hermes Team
0c511cd3b6 feat(hub): Plan A stabilization, refresh architecture, delta UI, and capability routing
- Implemented HubSnapshot and central HubStateStore for normalized in-memory state caching (<0.05ms)
- Refactored AccountsView and RoutingView with reusable AccountCardWidget and RoutingRoleWidget to eliminate widget recreation
- Implemented central HermesRefreshScheduler with 5s tick, concurrency throttling, dedup, and spread initial delays
- Added typed EventBus with thread-safe UI main loop dispatching via root.after
- Implemented dynamic ModelRegistry with capability-based role requirements and multi-dimensional scoring
- Integrated Antigravity separate quota buckets (Claude vs Gemini) and same-account model fallback
- Enhanced SessionAffinityTracker with TTL expiration and LRU capacity bounds
- Eliminated long subprocess holding of _CM_LOCK and ensured Windows credential restoration in finally block
- Added FastAPI REST contracts in gui_server.py as foundation for future Tauri frontend
- Verified 100% pass across all 91 pytest tests and 7/7 release gate criteria
2026-08-20 21:20:51 +07:00
Hermes Team
2b8b709ac9 feat: multi-provider accounts, tariffs, quota buckets, Claude & Grok integration 2026-08-20 21:02:13 +07:00
Hermes Team
3aae1a8def feat(wizard): support Codex OAuth/API Key & OpenCode Go with clipboard UX 2026-08-20 20:31:59 +07:00
Hermes Team
249a88867c feat(oauth): adopt Cockpit Tools model with immediate URL readiness, manual callback fallback, and race protection 2026-08-20 20:17:37 +07:00
Hermes Team
0d9005f55b fix(oauth): eliminate ERR_CONNECTION_REFUSED, guarantee immediate listener binding, single session reuse, and diagnostic logging 2026-08-20 19:59:49 +07:00
Hermes Team
925e6c6687 fix(router): correct spare assignment and error presentation 2026-08-20 17:21:30 +07:00
Hermes Team
65482e8eee fix(router): address review findings B1-B4 and S1-S9 with full regression suite 2026-08-20 17:04:49 +07:00
Hermes Team
7926de9ad2 feat(release): recovery stabilization, built-in updater, release gate, and v0.1.1 release pipeline 2026-08-20 16:29:35 +07:00
Hermes Team
2a97e80a3e fix: close P0 release blockers 2026-08-20 16:25:11 +07:00
Hermes Team
7609ad87c2 feat(hub): product stabilization, native windows ux v3, provider icons, and architecture roadmap 2026-08-20 11:01:52 +07:00
Hermes Team
e66248ab09 feat: initialize standalone Hermes Hub 2026-08-20 10:53:49 +07:00