- db.go: added SaveMetric(MetricInput) and SaveHistory(HistoryInput) methods
that write directly to MySQL; non-fatal (log-only on error)
- handlers.go (OrchestratorStream): after each SSE stream finishes, an async
goroutine saves agentMetrics (agentId, requestId, tokens, processingTimeMs,
model, toolsCalled, status) and agentHistory (userMessage, agentResponse);
both error and success paths covered; orchAgentID resolved from DB
- routers.ts (agents.chat): saveMetric() called for both success and error paths
in the Node.js direct-chat fallback (was only saving agentHistory before)
- Verified: agentMetrics row ID=2 shows processingTimeMs=2133, totalTokens=143,
model=minimax-m2.7, Cyrillic text stored correctly as UTF-8
- Chat.tsx: rewritten to use global chatStore singleton — SSE connection survives
page navigation; added StopCircle cancel button; scrolls only when near bottom
- chatStore.ts: new module-level singleton (EventTarget pattern) that holds all
conversation/console state; TextDecoder with stream:true for correct UTF-8
- handlers.go (ProvidersReload): now accepts decrypted key in request body from
Node.js so Go gateway can actually use the API key without sharing crypto logic
- providers.ts (activateProvider): sends decrypted key to gateway via
notifyGatewayReload(); seedDefaultProvider also calls notifyGatewayReload()
- seed.ts: on startup, after seeding, pushes active provider to gateway with
retry loop (5 retries × 3 s) to wait for gateway readiness
- index.ts (SSE proxy): TextDecoder('utf-8', {stream:true}) already correct;
confirmed Cyrillic text arrives ungarbled (e.g. 'Привет!' not '??????????')
- AgentDetailModal: load real models from API with loading indicator;
fallback to current agent model when API unavailable; show count badge
- AgentCreateModal: remove broken provider-filter on models list;
add loading indicator and disabled state during fetch; show count badge
- gateway/orchestrator: add resolveModel() — validates desired model
against LLM API before use; auto-fallback to first available model
to prevent 401/404 errors (fixes glm-5 unauthorized in chat)
- gateway/orchestrator: add ModelWarning field to ChatResult struct
- gateway-proxy.ts: add modelWarning field to GatewayChatResult
- Chat.tsx: display modelWarning as amber badge next to model name
- todo.md: add Phase 16 section with bug fixes and tech debt notes
Реализовано:
- gateway/internal/docker/client.go: Docker API клиент через unix socket (/var/run/docker.sock)
- IsSwarmActive(), GetSwarmInfo(), ListNodes(), ListContainers(), GetContainerStats()
- CalcCPUPercent() для расчёта CPU%
- gateway/internal/api/handlers.go: новые endpoints
- GET /api/nodes: список Swarm нод или standalone Docker хост
- GET /api/nodes/stats: live CPU/RAM статистика контейнеров
- POST /api/tools/execute: выполнение инструментов
- gateway/cmd/gateway/main.go: зарегистрированы новые маршруты
- server/gateway-proxy.ts: добавлены getGatewayNodes() и getGatewayNodeStats()
- server/routers.ts: добавлен nodes router (nodes.list, nodes.stats)
- client/src/pages/Nodes.tsx: полностью переписан на реальные данные
- Auto-refresh: 10s для нод, 15s для статистики контейнеров
- Swarm mode: показывает все ноды кластера
- Standalone mode: показывает локальный Docker хост + контейнеры
- CPU/RAM gauges из реальных docker stats
- Error state при недоступном Gateway
- Loading skeleton
- server/nodes.test.ts: 14 новых vitest тестов
- Все 51 тест пройдены