# Swapper Service - Інтеграція в кабінети Node #1 та Node #2 **Дата:** 2025-11-22 **Статус:** ✅ Готово до інтеграції --- ## 📋 Крок 1: Запуск Swapper Service ### Node #2 (MacBook - Development) #### Варіант A: Docker (якщо Docker запущений) ```bash cd /Users/apple/github-projects/microdao-daarion # Запустити Swapper Service docker-compose up -d swapper-service # Перевірити статус docker-compose ps swapper-service # Перевірити логи docker-compose logs -f swapper-service # Перевірити health curl http://localhost:8890/health ``` #### Варіант B: Локально (без Docker) ```bash cd /Users/apple/github-projects/microdao-daarion/services/swapper-service # Запустити скрипт (створює venv та встановлює залежності) ./start.sh ``` #### Варіант C: Вручну ```bash cd /Users/apple/github-projects/microdao-daarion/services/swapper-service # Створити virtual environment python3 -m venv venv source venv/bin/activate # Встановити залежності pip install -r requirements.txt # Налаштувати змінні оточення export OLLAMA_BASE_URL=http://localhost:11434 export SWAPPER_CONFIG_PATH=./config/swapper_config.yaml export SWAPPER_MODE=single-active # Запустити python3 -m uvicorn app.main:app --host 0.0.0.0 --port 8890 ``` ### Node #1 (Production Server) ```bash # SSH до сервера ssh root@144.76.224.179 # Перейти в директорію проекту cd /opt/microdao-daarion # Оновити код git pull origin main # Запустити Swapper Service docker-compose up -d swapper-service # Перевірити статус docker-compose ps swapper-service curl http://localhost:8890/health ``` --- ## 📋 Крок 2: Перевірка роботи ### Тест 1: Health Check ```bash curl http://localhost:8890/health ``` **Очікуваний результат:** ```json { "status": "healthy", "service": "swapper-service", "active_model": null, "mode": "single-active" } ``` ### Тест 2: Status для кабінету ```bash curl http://localhost:8890/api/cabinet/swapper/status | python3 -m json.tool ``` **Очікуваний результат:** ```json { "service": "swapper-service", "status": "healthy", "mode": "single-active", "active_model": null, "total_models": 8, "available_models": [ "deepseek-r1-70b", "qwen2.5-coder-32b", "gemma2-27b", ... ], "loaded_models": [], "models": [...] } ``` ### Тест 3: Метрики ```bash curl http://localhost:8890/api/cabinet/swapper/metrics/summary | python3 -m json.tool ``` --- ## 📋 Крок 3: Інтеграція в кабінети ### 3.1 Додати Swapper секцію в Sidebar **Файл:** `src/components/AdminConsole/Sidebar.tsx` (або аналогічний) ```typescript const menuItems = [ { id: 'overview', label: 'Overview', icon: 'dashboard' }, { id: 'members', label: 'Members & Roles', icon: 'users' }, { id: 'agents', label: 'Agents', icon: 'robot' }, { id: 'swapper', label: 'Swapper Service', icon: 'swap' }, // ← Додати це { id: 'settings', label: 'Settings', icon: 'settings' }, ]; ``` ### 3.2 Створити Swapper сторінку **Файл:** `src/pages/Admin/SwapperPage.tsx` ```typescript import React from 'react'; import { SwapperPage } from '@/services/swapper-service/cabinet-integration'; import '@/services/swapper-service/cabinet-integration.css'; export default function SwapperAdminPage() { return ; } ``` ### 3.3 Додати маршрут **Файл:** `src/routes/admin.tsx` (або аналогічний) ```typescript import SwapperAdminPage from '@/pages/Admin/SwapperPage'; const adminRoutes = [ { path: '/admin/overview', component: OverviewPage }, { path: '/admin/members', component: MembersPage }, { path: '/admin/agents', component: AgentsPage }, { path: '/admin/swapper', component: SwapperAdminPage }, // ← Додати це { path: '/admin/settings', component: SettingsPage }, ]; ``` ### 3.4 Налаштувати API URL **Файл:** `.env.local` (або `.env`) ```bash # Node #2 (MacBook - Development) NEXT_PUBLIC_SWAPPER_URL=http://localhost:8890 # Node #1 (Production Server) NEXT_PUBLIC_SWAPPER_URL=http://swapper-service:8890 # або через Nginx proxy: NEXT_PUBLIC_SWAPPER_URL=https://gateway.daarion.city/api/swapper ``` ### 3.5 Копіювати компоненти ```bash # Копіювати компоненти в проект cp services/swapper-service/cabinet-integration.tsx src/components/Swapper/ cp services/swapper-service/cabinet-integration.css src/styles/swapper.css ``` --- ## 📋 Крок 4: Альтернативна інтеграція (якщо немає React) ### 4.1 Vanilla JavaScript **Файл:** `public/swapper-dashboard.html` ```html Swapper Service Dashboard
``` ### 4.2 Vue.js компонент **Файл:** `src/components/Swapper/SwapperStatus.vue` ```vue ``` --- ## 📋 Крок 5: Інтеграція через Node Registry (опціонально) Якщо використовується Node Registry Service, можна додати Swapper статус туди: **Файл:** `services/node-registry/app/main.py` ```python @app.get("/api/nodes/{node_id}/swapper") async def get_node_swapper_status(node_id: str): """Get Swapper Service status for a node""" # Determine Swapper URL based on node if node_id == "node-2-macbook-m4max": swapper_url = "http://localhost:8890" elif node_id == "node-1-hetzner-gex44": swapper_url = "http://swapper-service:8890" else: raise HTTPException(404, "Node not found") async with httpx.AsyncClient() as client: response = await client.get(f"{swapper_url}/api/cabinet/swapper/status") return response.json() ``` --- ## 📋 Крок 6: Додати в Overview сторінку Додати Swapper статус на головну сторінку Overview: **Файл:** `src/pages/Admin/Overview.tsx` ```typescript import { SwapperStatusCard } from '@/services/swapper-service/cabinet-integration'; export default function OverviewPage() { return (

DAO Overview

{/* Existing overview content */} {/* Add Swapper status widget */}
); } ``` --- ## 🧪 Тестування інтеграції ### 1. Перевірити API доступність ```bash # З браузера або curl curl http://localhost:8890/api/cabinet/swapper/status ``` ### 2. Перевірити CORS (якщо frontend на іншому порту) Якщо frontend на іншому порту (наприклад, 3000), переконайтеся що CORS налаштовано: **Файл:** `services/swapper-service/app/main.py` ```python app.add_middleware( CORSMiddleware, allow_origins=["http://localhost:3000", "https://daarion.city"], # ← Додати ваші домени allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) ``` ### 3. Перевірити в браузері 1. Відкрити кабінет 2. Перейти на `/admin/swapper` 3. Перевірити що дані завантажуються 4. Перевірити що кнопки Load/Unload працюють --- ## 🐛 Troubleshooting ### Проблема: API не доступний **Рішення:** ```bash # Перевірити чи Swapper запущений curl http://localhost:8890/health # Перевірити логи docker logs swapper-service # або tail -f /tmp/swapper.log ``` ### Проблема: CORS помилка **Рішення:** Додати ваш домен в `allow_origins` в `app/main.py` ### Проблема: Компоненти не відображаються **Рішення:** 1. Перевірити що файли скопійовані 2. Перевірити імпорти 3. Перевірити консоль браузера на помилки --- ## ✅ Чеклист інтеграції - [ ] Swapper Service запущений - [ ] API доступний (`/health` працює) - [ ] Компоненти скопійовані в проект - [ ] Маршрут додано в роутер - [ ] Sidebar оновлено - [ ] API URL налаштовано - [ ] CORS налаштовано (якщо потрібно) - [ ] Тестування в браузері пройдено --- **Last Updated:** 2025-11-22 **Status:** ✅ Готово до інтеграції **Next:** Виконати кроки вище для Node #1 та Node #2