diff --git a/README.md b/README.md
index 4a6c54b3..80ef54ee 100644
--- a/README.md
+++ b/README.md
@@ -17,7 +17,7 @@
[🚀 Quick Start](#-quick-start) • [💡 Features](#-key-features) • [📖 Setup](#-setup-guide) • [🌐 Website](https://9router.com)
- [🇻🇳 Tiếng Việt](./i18n/README.vi.md) • [🇨🇳 中文](./i18n/README.zh-CN.md) • [🇯🇵 日本語](./i18n/README.ja-JP.md)
+ [🇻🇳 Tiếng Việt](./i18n/README.vi.md) • [🇨🇳 中文](./i18n/README.zh-CN.md) • [🇯🇵 日本語](./i18n/README.ja-JP.md) • [🇷🇺 Русский](./i18n/README.ru.md)
---
diff --git a/i18n/README.ru.md b/i18n/README.ru.md
new file mode 100644
index 00000000..01ed17b4
--- /dev/null
+++ b/i18n/README.ru.md
@@ -0,0 +1,1311 @@
+
+

+
+ # 9Router - Free AI Router
+
+ **Никогда не прекращайте кодить. Автоматическая маршрутизация к БЕСПЛАТНЫМ и дешёвым AI-моделям с умным механизмом резервирования.**
+
+ **Бесплатный AI-провайдер для OpenClaw.**
+
+
+
+
+
+ [](https://www.npmjs.com/package/9router)
+ [](https://www.npmjs.com/package/9router)
+ [](https://github.com/decolua/9router/blob/main/LICENSE)
+
+ [🚀 Быстрый старт](#-quick-start) • [💡 Возможности](#-key-features) • [📖 Установка](#-setup-guide) • [🌐 Сайт](https://9router.com)
+
+
+---
+
+## 🤔 Почему 9Router?
+
+**Перестаньте тратить деньги и упираться в лимиты:**
+
+- ❌ Квота подписки сгорает каждый месяц, не будучи израсходованной
+- ❌ Ограничение скорости (rate limit) прерывает вас прямо во время работы
+- ❌ Дорогие API ($20-50/мес за каждого провайдера)
+- ❌ Приходится вручную переключаться между провайдерами
+
+**9Router решает это:**
+
+- ✅ **Максимум из подписки** — Отслеживает квоту, использует каждый бит до сброса
+- ✅ **Автоматическое резервирование** — Подписка → Дёшево → Бесплатно, нулевой простой
+- ✅ **Несколько аккаунтов** — Round-robin по аккаунтам каждого провайдера
+- ✅ **Универсальность** — Работает с Claude Code, Codex, Gemini CLI, Cursor, Cline, любым CLI-инструментом
+
+---
+
+## 🔄 Как это работает
+
+```
+┌─────────────┐
+│ Your CLI │ (Claude Code, Codex, Gemini CLI, OpenClaw, Cursor, Cline...)
+│ Tool │
+└──────┬──────┘
+ │ http://localhost:20128/v1
+ ↓
+┌────────────────────────────────────────┐
+│ 9Router (Smart Router) │
+│ • Format translation (OpenAI ↔ Claude) │
+│ • Quota tracking │
+│ • Auto token refresh │
+└──────┬──────────────────────────────────┘
+ │
+ ├─→ [Tier 1: SUBSCRIPTION] Claude Code, Codex, Gemini CLI
+ │ ↓ quota exhausted
+ ├─→ [Tier 2: CHEAP] GLM ($0.6/1M), MiniMax ($0.2/1M)
+ │ budget limit
+ └─→ [Tier 3: FREE] iFlow, Qwen, Kiro (unlimited)
+
+Result: Never stop coding, minimal cost
+```
+
+---
+
+## ⚡ Быстрый старт
+
+**1. Глобальная установка:**
+
+```bash
+npm install -g 9router
+9router
+```
+
+🎉 Панель управления откроется на `http://localhost:20128`
+
+**2. Подключите БЕСПЛАТНОГО провайдера (без подписки):**
+
+Панель управления → Providers → Подключить **Claude Code** или **Antigravity** → Вход через OAuth → Готово!
+
+**3. Используйте в вашем CLI-инструменте:**
+
+```
+Настройки Claude Code/Codex/Gemini CLI/OpenClaw/Cursor/Cline:
+ Endpoint: http://localhost:20128/v1
+ API Key: [скопируйте из панели управления]
+ Model: if/kimi-k2-thinking
+```
+
+**Готово!** Начинайте кодить с БЕСПЛАТНЫМИ AI-моделями.
+
+**Альтернатива: запуск из исходников (этот репозиторий):**
+
+Пакет этого репозитория приватный (`9router-app`), поэтому запуск из исходников/Docker — это ожидаемый путь локальной разработки.
+
+```bash
+cp .env.example .env
+npm install
+PORT=20128 NEXT_PUBLIC_BASE_URL=http://localhost:20128 npm run dev
+```
+
+Режим Production:
+
+```bash
+npm run build
+PORT=20128 HOSTNAME=0.0.0.0 NEXT_PUBLIC_BASE_URL=http://localhost:20128 npm run start
+```
+
+URL по умолчанию:
+- Панель управления: `http://localhost:20128/dashboard`
+- OpenAI-совместимый API: `http://localhost:20128/v1`
+
+---
+
+## 🎥 Видео-руководство
+
+
+
+### 📺 Полное руководство по настройке - 9Router + Claude Code БЕСПЛАТНО
+
+[](https://www.youtube.com/watch?v=raEyZPg5xE0)
+
+**🎬 Полное пошаговое руководство:**
+- ✅ Установка и настройка 9Router
+- ✅ Настройка Claude Sonnet 4.5 БЕСПЛАТНО
+- ✅ Интеграция с Claude Code
+- ✅ Тестирование кода вживую
+
+**⏱️ Длительность:** 20 минут | **👥 Автор:** Сообщество разработчиков
+
+[▶️ Смотреть на YouTube](https://www.youtube.com/watch?v=o3qYCyjrFYg)
+
+
+
+---
+
+## 🛠️ Поддерживаемые CLI-инструменты
+
+9Router бесшовно работает со всеми основными AI-инструментами для кодинга:
+
+
+
+---
+
+## Поддерживаемые провайдеры
+
+### 🔐 OAuth-провайдеры
+
+
+
+### 🆓 Бесплатные провайдеры
+
+
+
+### 🔑 Провайдеры с API Key (40+)
+
+
+
+---
+
+## 💡 Ключевые возможности
+
+| Возможность | Что делает | Почему это важно |
+|---------|--------------|----------------|
+| 🎯 **Smart 3-Tier Fallback** | Авто-маршрутизация: Подписка → Дёшево → Бесплатно | Никогда не прекращайте кодить, нулевой простой |
+| 📊 **Отслеживание квоты в реальном времени** | Живой подсчёт токенов + обратный отсчёт до сброса | Максимум ценности из подписки |
+| 🔄 **Трансляция форматов** | OpenAI ↔ Claude ↔ Gemini бесшовно | Работает с любым CLI-инструментом |
+| 👥 **Поддержка нескольких аккаунтов** | Несколько аккаунтов на каждого провайдера | Балансировка нагрузки + резервирование |
+| 🔄 **Авто-обновление токена** | OAuth-токены обновляются автоматически | Не нужно входить вручную заново |
+| 🎨 **Пользовательские комбо** | Создавайте безграничные комбинации моделей | Настройте резервирование под себя |
+| 📝 **Логирование запросов** | Режим отладки с полным логом запросов/ответов | Лёгкая диагностика проблем |
+| 💾 **Облачная синхронизация** | Синхронизация конфигурации между устройствами | Одинаковые настройки везде |
+| 📊 **Аналитика использования** | Отслеживание токенов, затрат, трендов во времени | Оптимизация расходов |
+| 🌐 **Развёртывание где угодно** | Localhost, VPS, Docker, Cloudflare Workers | Гибкие варианты развёртывания |
+
+
+📖 Подробности о возможностях
+
+### 🎯 Smart 3-Tier Fallback
+
+Создавайте комбо с автоматическим резервированием:
+
+```
+Combo: "my-coding-stack"
+ 1. cc/claude-opus-4-6 (ваша подписка)
+ 2. glm/glm-4.7 (дешёвый бэкап, $0.6/1M)
+ 3. if/kimi-k2-thinking (бесплатное резервирование)
+
+→ Автопереключение при исчерпании квоты или ошибке
+```
+
+### 📊 Отслеживание квоты в реальном времени
+
+- Потребление токенов по каждому провайдеру
+- Обратный отсчёт до сброса (5 часов, ежедневно, еженедельно)
+- Оценка затрат для платных уровней
+- Ежемесячный отчёт о расходах
+
+### 🔄 Трансляция форматов
+
+Бесшовная трансляция между форматами:
+- **OpenAI** ↔ **Claude** ↔ **Gemini** ↔ **OpenAI Responses**
+- Ваш CLI-инструмент отправляет формат OpenAI → 9Router транслирует → Провайдер получает родной формат
+- Работает с любым инструментом, поддерживающим пользовательский эндпоинт OpenAI
+
+### 👥 Поддержка нескольких аккаунтов
+
+- Добавляйте несколько аккаунтов на каждого провайдера
+- Round-robin или маршрутизация по приоритету автоматически
+- Резервирование на следующий аккаунт при достижении квоты
+
+### 🔄 Авто-обновление токена
+
+- OAuth-токены автоматически обновляются до истечения срока
+- Не нужна повторная ручная аутентификация
+- Бесшовный опыт со всеми провайдерами
+
+### 🎨 Пользовательские комбо
+
+- Создавайте безграничные комбинации моделей
+- Сочетайте уровни подписки, дешёвые и бесплатные
+- Называйте комбо для удобного доступа
+- Делитесь комбо между устройствами через облачную синхронизацию
+
+### 📝 Логирование запросов
+
+- Включите режим отладки для просмотра полного лога запросов/ответов
+- Отслеживайте вызовы API, заголовки и payload
+- Диагностируйте проблемы интеграции
+- Экспортируйте логи для анализа
+
+### 💾 Облачная синхронизация
+
+- Синхронизация провайдеров, комбо и настроек между устройствами
+- Автоматическая фоновая синхронизация
+- Безопасное зашифрованное хранилище
+- Доступ к настройкам откуда угодно
+
+#### Заметки о облачном рантайме
+
+- Приоритет серверным облачным переменным в production-окружении:
+ - `BASE_URL` (внутренний callback URL, используемый планировщиком синхронизации)
+ - `CLOUD_URL` (база эндпоинта облачной синхронизации)
+- `NEXT_PUBLIC_BASE_URL` и `NEXT_PUBLIC_CLOUD_URL` по-прежнему поддерживаются для совместимости/UI, но серверный рантайм теперь приоритезирует `BASE_URL`/`CLOUD_URL`.
+- Запросы облачной синхронизации теперь используют тайм-аут + fail-fast поведение, чтобы избежать зависания UI при недоступности DNS/облачной сети.
+
+### 📊 Аналитика использования
+
+- Отслеживание использования токенов по провайдеру и модели
+- Оценка затрат и тренды расходов
+- Ежемесячные отчёты и инсайты
+- Оптимизация ваших AI-расходов
+
+> **💡 ВАЖНО - Понимание «Затрат» на панели управления:**
+>
+> «Затраты», показанные в Аналитике использования, предназначены **только для отслеживания и сравнения**.
+> Сам 9Router **никогда ничего не взимает** с вас. Вы платите напрямую провайдерам (если используете платные сервисы).
+>
+> **Пример:** Если на панели показано «общие затраты $290» при использовании моделей iFlow, это представляет
+> сумму, которую вы заплатили бы при прямом использовании платного API. Ваши фактические затраты = **$0** (iFlow бесплатен без ограничений).
+>
+> Считайте это «трекером экономии», показывающим, сколько вы экономите, используя бесплатные модели или
+> маршрутизацию через 9Router!
+
+### 🌐 Развёртывание где угодно
+
+- 💻 **Localhost** — По умолчанию, работает офлайн
+- ☁️ **VPS/Cloud** — Общий доступ между устройствами
+- 🐳 **Docker** — Развёртывание одной командой
+- 🚀 **Cloudflare Workers** — Глобальная edge-сеть
+
+
+
+---
+
+## 💰 Обзор цен
+
+| Уровень | Провайдер | Стоимость | Сброс квоты | Лучше всего для |
+|------|----------|------|-------------|----------|
+| **💳 ПОДПИСКА** | Claude Code (Pro) | $20/мес | 5ч + еженедельно | Уже подписаны |
+| | Codex (Plus/Pro) | $20-200/мес | 5ч + еженедельно | Пользователи OpenAI |
+| | Gemini CLI | **БЕСПЛАТНО** | 180K/мес + 1K/день | Для всех! |
+| | GitHub Copilot | $10-19/мес | Ежемесячно | Пользователи GitHub |
+| **💰 ДЁШЕВО** | GLM-4.7 | $0.6/1M | 10:00 ежедневно | Бюджетный бэкап |
+| | MiniMax M2.1 | $0.2/1M | Скользящие 5 часов | Самый дешёвый вариант |
+| | Kimi K2 | $9/мес фикс. | 10M токенов/мес | Предсказуемая стоимость |
+| **🆓 БЕСПЛАТНО** | iFlow | $0 | Без ограничений | 8 бесплатных моделей |
+| | Qwen | $0 | Без ограничений | 3 бесплатные модели |
+| | Kiro | $0 | Без ограничений | Claude бесплатно |
+
+**💡 Профи-совет:** Начните с комбо Gemini CLI (180K бесплатно/мес) + iFlow (без ограничений бесплатно) = $0 затрат!
+
+---
+
+### 📊 Понимание затрат и оплаты в 9Router
+
+**Реальность оплаты 9Router:**
+
+✅ **Софт 9Router = БЕСПЛАТНО навсегда** (открытый код, никогда не взимает плату)
+✅ **«Затраты» на панели = Только для отображения/отслеживания** (не реальный счёт)
+✅ **Вы платите напрямую провайдерам** (подписка или плата за API)
+✅ **БЕСПЛАТНЫЕ провайдеры остаются БЕСПЛАТНЫМИ** (iFlow, Kiro, Qwen = $0 без ограничений)
+❌ **9Router никогда не выставляет счёт** и не списывает с вашей карты
+
+**Как работает отображение затрат:**
+
+Панель показывает **оценочные затраты**, как если бы вы напрямую использовали платный API. Это **не оплата** — это инструмент сравнения, показывающий вашу экономию.
+
+**Пример сценария:**
+```
+Показано на панели:
+• Всего запросов: 1,662
+• Всего токенов: 47M
+• Отображаемые затраты: $290
+
+Реальная проверка:
+• Провайдер: iFlow (БЕСПЛАТНО без ограничений)
+• Фактическая оплата: $0.00
+• Значение $290: Сумма, которую вы СЭКОНОМИЛИ, используя бесплатные модели!
+```
+
+**Правила оплаты:**
+- **Провайдеры подписки** (Claude Code, Codex): Платите им напрямую через их сайт
+- **Дешёвые провайдеры** (GLM, MiniMax): Платите им напрямую, 9Router только маршрутизирует
+- **БЕСПЛАТНЫЕ провайдеры** (iFlow, Kiro, Qwen): Действительно бесплатны навсегда, без скрытых платежей
+- **9Router**: Никогда ничего не взимает, никогда
+
+---
+
+## 🎯 Сценарии использования
+
+### Сценарий 1: «У меня подписка Claude Pro»
+
+**Проблема:** Квота сгорает неиспользованной, rate limit при интенсивной работе
+
+**Решение:**
+```
+Combo: "maximize-claude"
+ 1. cc/claude-opus-4-6 (полное использование подписки)
+ 2. glm/glm-4.7 (дешёвый бэкап при исчерпании квоты)
+ 3. if/kimi-k2-thinking (бесплатное аварийное резервирование)
+
+Месячная стоимость: $20 (подписка) + ~$5 (бэкап) = $25 итого
+против $20 + упирание в лимит = разочарование
+```
+
+### Сценарий 2: «Хочу нулевые затраты»
+
+**Проблема:** Не могу позволить подписку, нужен надёжный AI-кодинг
+
+**Решение:**
+```
+Combo: "free-forever"
+ 1. gc/gemini-3-flash (180K бесплатно/мес)
+ 2. if/kimi-k2-thinking (без ограничений бесплатно)
+ 3. qw/qwen3-coder-plus (без ограничений бесплатно)
+
+Месячная стоимость: $0
+Качество: Production-ready модели
+```
+
+### Сценарий 3: «Нужно кодить 24/7, без перерывов»
+
+**Проблема:** Дедлайны, нельзя допустить простоя
+
+**Решение:**
+```
+Combo: "always-on"
+ 1. cc/claude-opus-4-6 (лучшее качество)
+ 2. cx/gpt-5.2-codex (вторая подписка)
+ 3. glm/glm-4.7 (дёшево, ежедневный сброс)
+ 4. minimax/MiniMax-M2.1 (самый дешёвый, сброс 5ч)
+ 5. if/kimi-k2-thinking (бесплатно без ограничений)
+
+Результат: 5 слоёв резервирования = нулевой простой
+Месячная стоимость: $20-200 (подписки) + $10-20 (бэкап)
+```
+
+### Сценарий 4: «Хочу БЕСПЛАТНЫЙ AI в OpenClaw»
+
+**Проблема:** Нужен AI-ассистент в мессенджерах (WhatsApp, Telegram, Slack...), полностью бесплатно
+
+**Решение:**
+```
+Combo: "openclaw-free"
+ 1. if/glm-4.7 (без ограничений бесплатно)
+ 2. if/minimax-m2.1 (без ограничений бесплатно)
+ 3. if/kimi-k2-thinking (без ограничений бесплатно)
+
+Месячная стоимость: $0
+Доступ через: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
+```
+
+---
+
+## ❓ Часто задаваемые вопросы
+
+
+📊 Почему моя панель показывает высокие затраты?
+
+Панель отслеживает ваше использование токенов и показывает **оценочные затраты**, как если бы вы напрямую использовали платный API. Это **не реальная оплата** — это справка, показывающая, сколько вы экономите, используя бесплатные модели или существующие подписки через 9Router.
+
+**Пример:**
+- **Панель показывает:** «Общие затраты $290»
+- **Реальность:** Вы используете iFlow (БЕСПЛАТНО без ограничений)
+- **Ваши фактические затраты:** **$0.00**
+- **Значение $290:** Сумма, которую вы **экономите**, используя бесплатные модели вместо платного API!
+
+Отображение затрат — это «трекер экономии», помогающий понять паттерны использования и возможности оптимизации.
+
+
+
+
+💳 Взимает ли с меня плату 9Router?
+
+**Нет.** 9Router — это бесплатное ПО с открытым кодом, работающее на вашем собственном компьютере. Оно никогда ничего с вас не взимает.
+
+**Вы платите только:**
+- ✅ **Провайдерам подписки** (Claude Code $20/мес, Codex $20-200/мес) → Платите им напрямую на их сайте
+- ✅ **Дешёвым провайдерам** (GLM, MiniMax) → Платите им напрямую, 9Router только маршрутизирует ваши запросы
+- ❌ **Самому 9Router** → **Никогда ничего не взимает, никогда**
+
+9Router — это локальный прокси/роутер. У него нет вашей кредитной карты, он не может выставлять счета и не имеет платёжной системы. Это полностью бесплатное ПО.
+
+
+
+
+🆓 Действительно ли БЕСПЛАТНЫЕ провайдеры безлимитны?
+
+**Да!** Провайдеры, отмеченные как БЕСПЛАТНЫЕ (iFlow, Kiro, Qwen), действительно безлимитны и **без скрытых платежей**.
+
+Это бесплатные сервисы, предоставляемые соответствующими компаниями:
+- **iFlow**: Бесплатный безлимитный доступ к 8+ моделям через OAuth
+- **Kiro**: Бесплатные безлимитные модели Claude через AWS Builder ID
+- **Qwen**: Бесплатный безлимитный доступ к моделям Qwen через аутентификацию устройства
+
+9Router только маршрутизирует ваши запросы к ним — никаких «ловушек» или будущих платежей. Это действительно бесплатные сервисы, а 9Router облегчает их использование с поддержкой резервирования.
+
+**Примечание:** Некоторые провайдеры подписки (Antigravity, GitHub Copilot) могут иметь бесплатные пробные периоды, которые позже становятся платными, но об этом чётко уведомляют сами провайдеры, а не 9Router.
+
+
+
+
+💰 Как минимизировать мои реальные AI-затраты?
+
+**Стратегия «Бесплатное в приоритете»:**
+
+1. **Начните со 100% бесплатного комбо:**
+ ```
+ 1. gc/gemini-3-flash (180K/мес бесплатно от Google)
+ 2. if/kimi-k2-thinking (без ограничений бесплатно от iFlow)
+ 3. qw/qwen3-coder-plus (без ограничений бесплатно от Qwen)
+ ```
+ **Стоимость: $0/мес**
+
+2. **Добавьте дешёвый бэкап** только при необходимости:
+ ```
+ 4. glm/glm-4.7 ($0.6/1M токенов)
+ ```
+ **Доп. стоимость:** Платите только за то, что фактически используете
+
+3. **Используйте провайдеров подписки в последнюю очередь:**
+ - Только если они у вас уже есть
+ - 9Router помогает максимизировать их ценность через отслеживание квоты
+
+**Результат:** Большинство пользователей могут работать за $0/мес, используя только бесплатные уровни!
+
+
+
+
+📈 Что если моё использование внезапно вырастет?
+
+Умный механизм резервирования 9Router предотвращает неожиданные расходы:
+
+**Сценарий:** Вы в спринте кодинга и превышаете квоты
+
+**Без 9Router:**
+- ❌ Упёрлись в rate limit → Работа остановилась → Разочарование
+- ❌ Или: Случайно накопили огромный счёт за API
+
+**С 9Router:**
+- ✅ Подписка упёрлась в лимит → Авторезервирование на дешёвый уровень
+- ✅ Дешёвый уровень становится дорогим → Авторезервирование на бесплатный уровень
+- ✅ Никогда не прекращаете кодить → Предсказуемая стоимость
+
+**Вы контролируете:** Установите лимиты расходов на каждого провайдера в панели, и 9Router будет их соблюдать.
+
+
+
+---
+
+## 📖 Руководство по настройке
+
+
+🔐 Провайдеры подписки (Максимум ценности)
+
+### Claude Code (Pro/Max)
+
+```bash
+Панель управления → Providers → Подключить Claude Code
+→ Вход через OAuth → Авто-обновление токена
+→ Отслеживание квоты 5 часов + еженедельно
+
+Модели:
+ cc/claude-opus-4-6
+ cc/claude-sonnet-4-5-20250929
+ cc/claude-haiku-4-5-20251001
+```
+
+**Профи-совет:** Используйте Opus для сложных задач, Sonnet для скорости. 9Router отслеживает квоту для каждой модели!
+
+### OpenAI Codex (Plus/Pro)
+
+```bash
+Панель управления → Providers → Подключить Codex
+→ Вход через OAuth (порт 1455)
+→ Сброс 5 часов + еженедельно
+
+Модели:
+ cx/gpt-5.2-codex
+ cx/gpt-5.1-codex-max
+```
+
+### Gemini CLI (БЕСПЛАТНО 180K/мес!)
+
+```bash
+Панель управления → Providers → Подключить Gemini CLI
+→ Google OAuth
+→ 180K запросов/мес + 1K/день
+
+Модели:
+ gc/gemini-3-flash-preview
+ gc/gemini-2.5-pro
+```
+
+**Лучшая ценность:** Огромный бесплатный уровень! Используйте его перед платными уровнями.
+
+### GitHub Copilot
+
+```bash
+Панель управления → Providers → Подключить GitHub
+→ OAuth через GitHub
+→ Ежемесячный сброс (1-го числа месяца)
+
+Модели:
+ gh/gpt-5
+ gh/claude-4.5-sonnet
+ gh/gemini-3-pro
+```
+
+
+
+
+💰 Дешёвые провайдеры (Бэкап)
+
+### GLM-4.7 (Ежедневный сброс, $0.6/1M)
+
+1. Регистрация: [Zhipu AI](https://open.bigmodel.cn/)
+2. Получите API key из Coding Plan
+3. Панель управления → Добавить API Key:
+ - Провайдер: `glm`
+ - API Key: `your-key`
+
+**Использование:** `glm/glm-4.7`
+
+**Профи-совет:** Coding Plan даёт втрое больше квоты за 1/7 стоимости! Сброс ежедневно в 10:00.
+
+### MiniMax M2.1 (Сброс 5ч, $0.20/1M)
+
+1. Регистрация: [MiniMax](https://www.minimax.io/)
+2. Получите API key
+3. Панель управления → Добавить API Key
+
+**Использование:** `minimax/MiniMax-M2.1`
+
+**Профи-совет:** Самый дешёвый вариант для длинного контекста (1M)!
+
+### Kimi K2 ($9/мес фиксированно)
+
+1. Регистрация: [Moonshot AI](https://platform.moonshot.ai/)
+2. Получите API key
+3. Панель управления → Добавить API Key
+
+**Использование:** `kimi/kimi-latest`
+
+**Профи-совет:** Фиксированные $9/мес за 10M токенов = реальная стоимость $0.90/1M!
+
+
+
+
+🆓 БЕСПЛАТНЫЕ провайдеры (Аварийное резервирование)
+
+### iFlow (8 БЕСПЛАТНЫХ моделей)
+
+```bash
+Панель управления → Подключить iFlow
+→ Вход через OAuth iFlow
+→ Безлимитное использование
+
+Модели:
+ if/kimi-k2-thinking
+ if/qwen3-coder-plus
+ if/glm-4.7
+ if/minimax-m2
+ if/deepseek-r1
+```
+
+### Qwen (3 БЕСПЛАТНЫЕ модели)
+
+```bash
+Панель управления → Подключить Qwen
+→ Авторизация по коду устройства
+→ Безлимитное использование
+
+Модели:
+ qw/qwen3-coder-plus
+ qw/qwen3-coder-flash
+```
+
+### Kiro (БЕСПЛАТНЫЙ Claude)
+
+```bash
+Панель управления → Подключить Kiro
+→ AWS Builder ID или Google/GitHub
+→ Безлимитное использование
+
+Модели:
+ kr/claude-sonnet-4.5
+ kr/claude-haiku-4.5
+```
+
+
+
+
+🎨 Создание комбо
+
+### Пример 1: Максимум из подписки → Дешёвый бэкап
+
+```
+Панель управления → Combos → Создать новое
+
+Имя: premium-coding
+Модели:
+ 1. cc/claude-opus-4-6 (Основная подписка)
+ 2. glm/glm-4.7 (Дешёвый бэкап, $0.6/1M)
+ 3. minimax/MiniMax-M2.1 (Самое дешёвое резервирование, $0.20/1M)
+
+Использование в CLI: premium-coding
+
+Пример месячной стоимости (100M токенов):
+ 80M через Claude (подписка): $0 дополнительно
+ 15M через GLM: $9
+ 5M через MiniMax: $1
+ Итого: $10 + ваша подписка
+```
+
+### Пример 2: Только бесплатно (Нулевая стоимость)
+
+```
+Имя: free-combo
+Модели:
+ 1. gc/gemini-3-flash-preview (180K бесплатно/мес)
+ 2. if/kimi-k2-thinking (без ограничений)
+ 3. qw/qwen3-coder-plus (без ограничений)
+
+Стоимость: $0 навсегда!
+```
+
+
+
+
+🔧 Интеграция CLI
+
+### Cursor IDE
+
+```
+Settings → Models → Advanced:
+ OpenAI API Base URL: http://localhost:20128/v1
+ OpenAI API Key: [из панели управления 9router]
+ Model: cc/claude-opus-4-6
+```
+
+Или используйте комбо: `premium-coding`
+
+### Claude Code
+
+Отредактируйте `~/.claude/config.json`:
+
+```json
+{
+ "anthropic_api_base": "http://localhost:20128/v1",
+ "anthropic_api_key": "your-9router-api-key"
+}
+```
+
+### Codex CLI
+
+```bash
+export OPENAI_BASE_URL="http://localhost:20128"
+export OPENAI_API_KEY="your-9router-api-key"
+
+codex "ваш промпт"
+```
+
+### OpenClaw
+
+**Вариант 1 — Панель управления (рекомендуется):**
+
+```
+Панель управления → CLI Tools → OpenClaw → Выбрать модель → Применить
+```
+
+**Вариант 2 — Вручную:** Отредактируйте `~/.openclaw/openclaw.json`:
+
+```json
+{
+ "agents": {
+ "defaults": {
+ "model": {
+ "primary": "9router/if/glm-4.7"
+ }
+ }
+ },
+ "models": {
+ "providers": {
+ "9router": {
+ "baseUrl": "http://127.0.0.1:20128/v1",
+ "apiKey": "sk_9router",
+ "api": "openai-completions",
+ "models": [
+ {
+ "id": "if/glm-4.7",
+ "name": "glm-4.7"
+ }
+ ]
+ }
+ }
+ }
+}
+```
+
+> **Примечание:** OpenClaw работает только с локальным 9Router. Используйте `127.0.0.1` вместо `localhost`, чтобы избежать проблем с разрешением имён.
+
+### Cline / Continue / RooCode
+
+```
+Provider: OpenAI Compatible
+Base URL: http://localhost:20128/v1
+API Key: [из панели управления]
+Model: cc/claude-opus-4-6
+```
+
+
+
+
+🚀 Развёртывание
+
+### Развёртывание на VPS
+
+```bash
+# Clone and install
+git clone https://github.com/decolua/9router.git
+cd 9router
+npm install
+npm run build
+
+# Configure
+export JWT="your-secure-secret-change-this"
+export INITIAL_PASSWORD="your-password"
+export DATA_DIR="/var/lib/9router"
+export PORT="20128"
+export HOSTNAME="0.0.0.0"
+export NODE_ENV="production"
+export NEXT_PUBLIC_BASE_URL="http://localhost:20128"
+export NEXT_PUBLIC_CLOUD_URL="https://9router.com"
+export API_KEY_SECRET="endpoint-proxy-api-key-secret"
+export MACHINE_ID_SALT="endpoint-proxy-salt"
+
+# Start
+npm run start
+
+# Or use PM2
+npm install -g pm2
+pm2 start --name 9router -- start
+pm2 save
+pm2 startup
+```
+
+### Docker
+
+```bash
+# Build image (from repository root)
+docker build -t 9router .
+
+# Run container (command used in current setup)
+docker run -d \
+ --name 9router \
+ -p 20128:20128 \
+ --env-file /root/dev/9router/.env \
+ -v 9router-data:/app/data \
+ -v 9router-usage:/root/.9router \
+ 9router
+```
+
+Портативная команда (если вы уже в корне репозитория):
+
+```bash
+docker run -d \
+ --name 9router \
+ -p 20128:20128 \
+ --env-file ./.env \
+ -v 9router-data:/app/data \
+ -v 9router-usage:/root/.9router \
+ 9router
+```
+
+Значения по умолчанию контейнера:
+- `PORT=20128`
+- `HOSTNAME=0.0.0.0`
+
+Полезные команды:
+
+```bash
+docker logs -f 9router
+docker restart 9router
+docker stop 9router && docker rm 9router
+```
+
+### Переменные окружения
+
+| Переменная | По умолчанию | Описание |
+|----------|---------|-------------|
+| `JWT_SECRET` | Автогенерация (`~/.9router/jwt-secret`) | Секрет подписи JWT для cookie аутентификации панели (задайте для общего доступа между инстансами) |
+| `INITIAL_PASSWORD` | `123456` | Пароль первого входа при отсутствии сохранённого хеша |
+| `DATA_DIR` | `~/.9router` | Расположение основной БД приложения (`db.json`) |
+| `PORT` | framework default | Порт сервиса (`20128` в примерах) |
+| `HOSTNAME` | framework default | Bind host (Docker по умолчанию `0.0.0.0`) |
+| `NODE_ENV` | runtime default | Установите `production` для развёртывания |
+| `BASE_URL` | `http://localhost:20128` | Внутренний серверный базовый URL для задач облачной синхронизации |
+| `CLOUD_URL` | `https://9router.com` | Серверный базовый URL эндпоинта облачной синхронизации |
+| `NEXT_PUBLIC_BASE_URL` | `http://localhost:3000` | Обратно совместимый/публичный базовый URL (приоритет `BASE_URL` для серверного рантайма) |
+| `NEXT_PUBLIC_CLOUD_URL` | `https://9router.com` | Обратно совместимый/публичный облачный URL (приоритет `CLOUD_URL` для серверного рантайма) |
+| `API_KEY_SECRET` | `endpoint-proxy-api-key-secret` | HMAC-секрет для генерируемых API-ключей |
+| `MACHINE_ID_SALT` | `endpoint-proxy-salt` | Соль для стабильного хеширования ID машины |
+| `ENABLE_REQUEST_LOGS` | `false` | Включить лог запросов/ответов в `logs/` |
+| `AUTH_COOKIE_SECURE` | `false` | Принудительный `Secure` cookie аутентификации (задайте `true` за HTTPS reverse proxy) |
+| `REQUIRE_API_KEY` | `false` | Требовать Bearer API key на маршрутах `/v1/*` (рекомендуется для развёртываний с выходом в интернет) |
+| `HTTP_PROXY`, `HTTPS_PROXY`, `ALL_PROXY`, `NO_PROXY` | empty | Опциональный исходящий прокси для вызовов к провайдерам |
+
+Примечания:
+- Прокси-переменные в нижнем регистре также поддерживаются: `http_proxy`, `https_proxy`, `all_proxy`, `no_proxy`.
+- `.env` не запекается в Docker-образ (`.dockerignore`); подавайте runtime-конфигурацию через `--env-file` или `-e`.
+- В Windows для разрешения путей локального хранилища может использоваться `APPDATA`.
+- `INSTANCE_NAME` встречается в старых docs/env-шаблонах, но сейчас в рантайме не используется.
+
+### Runtime-файлы и хранилище
+
+- Основное состояние приложения: `${DATA_DIR}/db.json` (провайдеры, комбо, alias, ключи, настройки), управляется `src/lib/localDb.js`.
+- История использования и логи: `~/.9router/usage.json` и `~/.9router/log.txt`, управляется `src/lib/usageDb.js`.
+- Опциональные логи запросов/транслятора: `/logs/...` при `ENABLE_REQUEST_LOGS=true`.
+- Хранилище использования следует логике пути `~/.9router` и независимо от `DATA_DIR`.
+
+
+
+---
+
+## 📊 Доступные модели
+
+
+Показать все доступные модели
+
+**Claude Code (`cc/`)** - Pro/Max:
+- `cc/claude-opus-4-6`
+- `cc/claude-sonnet-4-5-20250929`
+- `cc/claude-haiku-4-5-20251001`
+
+**Codex (`cx/`)** - Plus/Pro:
+- `cx/gpt-5.2-codex`
+- `cx/gpt-5.1-codex-max`
+
+**Gemini CLI (`gc/`)** - БЕСПЛАТНО:
+- `gc/gemini-3-flash-preview`
+- `gc/gemini-2.5-pro`
+
+**GitHub Copilot (`gh/`)**:
+- `gh/gpt-5`
+- `gh/claude-4.5-sonnet`
+
+**GLM (`glm/`)** - $0.6/1M:
+- `glm/glm-4.7`
+
+**MiniMax (`minimax/`)** - $0.2/1M:
+- `minimax/MiniMax-M2.1`
+
+**iFlow (`if/`)** - БЕСПЛАТНО:
+- `if/kimi-k2-thinking`
+- `if/qwen3-coder-plus`
+- `if/deepseek-r1`
+
+**Qwen (`qw/`)** - БЕСПЛАТНО:
+- `qw/qwen3-coder-plus`
+- `qw/qwen3-coder-flash`
+
+**Kiro (`kr/`)** - БЕСПЛАТНО:
+- `kr/claude-sonnet-4.5`
+- `kr/claude-haiku-4.5`
+
+
+
+---
+
+## 🐛 Устранение неполадок
+
+**"Language model did not provide messages"**
+- Исчерпана квота провайдера → Проверьте трекер квоты на панели
+- Решение: Используйте резервирование комбо или переключитесь на более дешёвый уровень
+
+**Ограничение скорости (Rate limiting)**
+- Исчерпана квота подписки → Резервирование на GLM/MiniMax
+- Добавьте комбо: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking`
+
+**OAuth-токен истёк**
+- Автообновление 9Router
+- Если проблема сохраняется: Панель управления → Провайдеры → Переподключить
+
+**Высокие затраты**
+- Проверьте статистику использования в панели
+- Переключите основную модель на GLM/MiniMax
+- Используйте бесплатные уровни (Gemini CLI, iFlow) для некритичных задач
+
+**Панель открывается на неверном порту**
+- Установите `PORT=20128` и `NEXT_PUBLIC_BASE_URL=http://localhost:20128`
+
+**Ошибки облачной синхронизации**
+- Убедитесь, что `BASE_URL` указывает на ваш работающий инстанс (например, `http://localhost:20128`)
+- Убедитесь, что `CLOUD_URL` указывает на ожидаемый облачный эндпоинт (например, `https://9router.com`)
+- По возможности держите значения `NEXT_PUBLIC_*` согласованными с серверными значениями.
+
+**Облачный эндпоинт `stream=false` возвращает 500 (`Unexpected token 'd'...`)**
+- Симптом обычно появляется на публичном облачном эндпоинте (`https://9router.com/v1`) для непотоковых (non-streaming) вызовов.
+- Корневая причина: upstream возвращает SSE-payload (`data: ...`), тогда как клиент ожидает JSON.
+- Обходное решение: используйте `stream=true` для прямых вызовов в облако.
+- Локальный рантайм 9Router включает резервирование SSE→JSON для непотоковых вызовов, когда upstream возвращает `text/event-stream`.
+
+**Облако сообщает о подключении, но запрос всё равно падает с `Invalid API key`**
+- Создайте новый ключ в локальной панели (`/api/keys`) и запустите облачную синхронизацию (`Enable Cloud`, затем `Sync Now`).
+- Старые/несинхронизированные ключи могут возвращать `401` в облаке, даже если локальный эндпоинт работает.
+
+**Первый вход не работает**
+- Проверьте `INITIAL_PASSWORD` в `.env`
+- Если не задан, резервный пароль — `123456`
+
+**Нет логов запросов в `logs/`**
+- Установите `ENABLE_REQUEST_LOGS=true`
+
+---
+
+## 🛠️ Tech Stack
+
+- **Runtime**: Node.js 20+
+- **Framework**: Next.js 16
+- **UI**: React 19 + Tailwind 4
+- **Database**: LowDB (на основе JSON-файлов)
+- **Streaming**: Server-Sent Events (SSE)
+- **Auth**: OAuth 2.0 (PKCE) + JWT + API Keys
+
+---
+
+## 📝 Справочник по API
+
+### Chat Completions
+
+```bash
+POST http://localhost:20128/v1/chat/completions
+Authorization: Bearer your-api-key
+Content-Type: application/json
+
+{
+ "model": "cc/claude-opus-4-6",
+ "messages": [
+ {"role": "user", "content": "Напиши функцию для..."}
+ ],
+ "stream": true
+}
+```
+
+### Список моделей
+
+```bash
+GET http://localhost:20128/v1/models
+Authorization: Bearer your-api-key
+
+→ Возвращает все модели + комбо в формате OpenAI
+```
+
+### Совместимые эндпоинты
+
+- `POST /v1/chat/completions`
+- `POST /v1/messages`
+- `POST /v1/responses`
+- `GET /v1/models`
+- `POST /v1/messages/count_tokens`
+- `GET /v1beta/models`
+- `POST /v1beta/models/{...path}` (Gemini-style `generateContent`)
+- `POST /v1/api/chat` (путь конвертации в стиле Ollama)
+
+### Скрипты облачной аутентификации
+
+Добавлены тестовые скрипты в `tester/security/`:
+
+- `tester/security/test-docker-hardening.sh`
+ - Собирает Docker-образ и проверяет hardening-проверки (`/api/cloud/auth` auth guard, `REQUIRE_API_KEY`, безопасное поведение cookie аутентификации).
+- `tester/security/test-cloud-openai-compatible.sh`
+ - Отправляет OpenAI-совместимый запрос напрямую на облачный эндпоинт (`https://9router.com/v1/chat/completions`) с указанной моделью/ключом.
+- `tester/security/test-cloud-sync-and-call.sh`
+ - End-to-end процесс: создание локального ключа → включение/синхронизация облака → вызов облачного эндпоинта с повтором.
+ - Включает резервную проверку с `stream=true`, чтобы отличить ошибки аутентификации от проблем разбора потока.
+
+Заметки по безопасности для облачных тестовых скриптов:
+
+- Никогда не хардкодьте реальные API-ключи в скриптах/коммитах.
+- Передавайте ключи только через переменные окружения:
+ - `API_KEY`, `CLOUD_API_KEY` или `OPENAI_API_KEY` (поддерживается `test-cloud-openai-compatible.sh`)
+- Пример:
+
+```bash
+OPENAI_API_KEY="your-cloud-key" bash tester/security/test-cloud-openai-compatible.sh
+```
+
+Ожидаемое поведение по результатам недавней проверки:
+
+- Локально (`http://127.0.0.1:20128/v1/chat/completions`): работает с `stream=false` и `stream=true`.
+- Docker-рантайм (тот же API-путь, экспонируемый контейнером): hardening-проверки проходят, cloud auth guard работает, строгий режим API-ключа работает при включении.
+- Публичный облачный эндпоинт (`https://9router.com/v1/chat/completions`):
+ - `stream=true`: ожидается успех (возвращает SSE-чанки).
+ - `stream=false`: может падать с `500` + ошибкой разбора (`Unexpected token 'd'`), когда upstream возвращает SSE-контент для непотокового клиентского пути.
+
+### API управления и панели
+
+- Аутентификация/настройки: `/api/auth/login`, `/api/auth/logout`, `/api/settings`, `/api/settings/require-login`
+- Управление провайдерами: `/api/providers`, `/api/providers/[id]`, `/api/providers/[id]/test`, `/api/providers/[id]/models`, `/api/providers/validate`, `/api/provider-n*`
+- OAuth-потоки: `/api/oauth/[provider]/[action]` (+ специфичные для провайдеров импорты, такие как Cursor/Kiro)
+- Конфигурация маршрутизации: `/api/models/alias`, `/api/combos*`, `/api/keys*`, `/api/pricing`
+- Использование/логи: `/api/usage/history`, `/api/usage/logs`, `/api/usage/request-logs`, `/api/usage/[connectionId]`
+- Облачная синхронизация: `/api/sync/cloud`, `/api/sync/initialize`, `/api/cloud/*`
+- Помощники CLI: `/api/cli-tools/claude-settings`, `/api/cli-tools/codex-settings`, `/api/cli-tools/droid-settings`, `/api/cli-tools/openclaw-settings`
+
+### Поведение аутентификации
+
+- Маршруты панели (`/dashboard/*`) используют защиту cookie `auth_token`.
+- Вход использует сохранённый хеш пароля при наличии; иначе откатывается к `INITIAL_PASSWORD`.
+- `requireLogin` можно переключить через `/api/settings/require-login`.
+
+### Обработка запросов (высокоуровнево)
+
+1. Клиент отправляет запрос на `/v1/*`.
+2. Обработчик маршрута вызывает `handleChat` (`src/sse/handlers/chat.js`).
+3. Модель разрешается (прямой провайдер/модель или разрешение alias/combo).
+4. Учётные данные выбираются из локальной БД с фильтром доступности аккаунта.
+5. `handleChatCore` (`open-sse/handlers/chatCore.js`) определяет формат и транслирует запрос.
+6. Исполнитель провайдера отправляет upstream-запрос.
+7. Поток при необходимости транслируется обратно в клиентский формат.
+8. Использование/логи записываются (`src/lib/usageDb.js`).
+9. Резервирование применяется при ошибках провайдера/аккаунта/модели по правилам комбо.
+
+Полный справочник по архитектуре: [`docs/ARCHITECTURE.md`](../docs/ARCHITECTURE.md)
+
+---
+
+## 📧 Поддержка
+
+- **Сайт**: [9router.com](https://9router.com)
+- **GitHub**: [github.com/decolua/9router](https://github.com/decolua/9router)
+- **Issues**: [github.com/decolua/9router/issues](https://github.com/decolua/9router/issues)
+
+---
+
+## 👥 Контрибьюторы
+
+Спасибо всем, кто помогает делать 9Router лучше!
+
+[](https://github.com/decolua/9router/graphs/contributors)
+
+---
+
+## 📊 Star Chart
+
+[](https://starchart.cc/decolua/9router)
+
+### Как внести вклад
+
+1. Сделайте форк репозитория
+2. Создайте свою feature-ветку (`git checkout -b feature/amazing-feature`)
+3. Закоммитьте изменения (`git commit -m 'Add amazing feature'`)
+4. Запушьте в ветку (`git push origin feature/amazing-feature`)
+5. Откройте Pull Request
+
+См. [Pull Requests](https://github.com/decolua/9router/pulls) для подробных инструкций.
+
+---
+
+## 🔀 Форки
+
+**[OmniRoute](https://github.com/diegosouzapw/OmniRoute)** — Полнофункциональный TypeScript-форк 9Router. Добавляет 36+ провайдеров, авторезервирование на 4 уровнях, мультимодальный API (изображения, embedding, аудио, TTS), circuit breaker, семантическое кеширование, оценку LLM и доработанную панель. 368+ юнит-тестов. Доступен через npm.
+
+---
+
+## 🙏 Благодарности
+
+Особая благодарность **CLIProxyAPI** — оригинальной Go-реализации, вдохновившей этот JavaScript-порт.
+
+---
+
+## 📄 Лицензия
+
+Лицензия MIT — см. [LICENSE](../LICENSE) для деталей.
+
+---
+
+
+ Создано с ❤️ для разработчиков, которые кодят 24/7
+
diff --git a/tester/translator/testFromFile.js b/tester/translator/testFromFile.js
deleted file mode 100755
index 298548e9..00000000
--- a/tester/translator/testFromFile.js
+++ /dev/null
@@ -1,148 +0,0 @@
-#!/usr/bin/env node
-
-/**
- * Test sending request from converted file directly to provider
- * Usage:
- * node testFromFile.js
- * node testFromFile.js data/claude-to-kiro/3_converted_request.json
- */
-
-const fs = require("fs");
-const path = require("path");
-
-const args = process.argv.slice(2);
-
-if (args.length === 0 || args[0] === "--help" || args[0] === "-h") {
- console.log("");
- console.log("🧪 Test From File - Send converted request to provider");
- console.log("");
- console.log("Usage:");
- console.log(" node testFromFile.js ");
- console.log("");
- console.log("Examples:");
- console.log(" node testFromFile.js data/claude-to-kiro/3_converted_request.json");
- console.log(" node testFromFile.js ../logs/openai_codex_xxx/3_converted_request.json");
- console.log("");
- console.log("File format:");
- console.log(" {");
- console.log(" \"url\": \"https://api.provider.com/...\",");
- console.log(" \"headers\": { ... },");
- console.log(" \"body\": { ... }");
- console.log(" }");
- console.log("");
- process.exit(0);
-}
-
-const filePath = args[0];
-const fullPath = path.isAbsolute(filePath) ? filePath : path.join(process.cwd(), filePath);
-
-if (!fs.existsSync(fullPath)) {
- console.error(`❌ File not found: ${fullPath}`);
- process.exit(1);
-}
-
-// Load request data
-let data;
-try {
- data = JSON.parse(fs.readFileSync(fullPath, "utf8"));
-} catch (err) {
- console.error(`❌ Failed to parse JSON: ${err.message}`);
- process.exit(1);
-}
-
-const { url, headers, body } = data;
-
-if (!url || !headers || !body) {
- console.error("❌ Invalid file format. Expected: { url, headers, body }");
- process.exit(1);
-}
-
-// Display request info
-console.log("\n🚀 Sending Request from File\n");
-console.log(`📁 File: ${filePath}`);
-console.log(`🌐 URL: ${url}`);
-console.log(`📋 Headers:`);
-Object.entries(headers).forEach(([k, v]) => {
- if (k.toLowerCase().includes("auth") || k.toLowerCase().includes("key") || k.toLowerCase().includes("bearer")) {
- const str = String(v);
- if (str.length > 20) {
- console.log(` ${k}: ${str.slice(0, 20)}...`);
- } else {
- console.log(` ${k}: ${str}`);
- }
- } else {
- console.log(` ${k}: ${v}`);
- }
-});
-
-console.log(`\n📊 Request Body:`);
-console.log(` Model: ${body.model || "N/A"}`);
-console.log(` Messages: ${body.messages?.length || 0}`);
-console.log(` Tools: ${body.tools?.length || 0}`);
-console.log(` Stream: ${body.stream || false}`);
-
-// Send request
-(async () => {
- try {
- console.log("\n🚀 Sending request...");
-
- const response = await fetch(url, {
- method: "POST",
- headers,
- body: JSON.stringify(body)
- });
-
- console.log(`\n📥 Response: ${response.status} ${response.statusText}`);
-
- if (!response.ok) {
- const errorText = await response.text();
- console.error(`\n❌ Error response:\n${errorText}`);
- process.exit(1);
- }
-
- const isStreaming = body.stream || response.headers.get("content-type")?.includes("text/event-stream");
-
- if (isStreaming) {
- console.log("\n📡 Streaming response...\n");
-
- const reader = response.body.getReader();
- const decoder = new TextDecoder();
- let chunkCount = 0;
- let buffer = "";
-
- while (true) {
- const { done, value } = await reader.read();
- if (done) break;
-
- buffer += decoder.decode(value, { stream: true });
- const lines = buffer.split("\n");
- buffer = lines.pop(); // Keep incomplete line in buffer
-
- for (const line of lines) {
- if (line.trim()) {
- process.stdout.write(line + "\n");
- chunkCount++;
- }
- }
- }
-
- // Process any remaining data
- if (buffer.trim()) {
- process.stdout.write(buffer + "\n");
- }
-
- console.log(`\n\n✅ Received ${chunkCount} chunks`);
- } else {
- const responseData = await response.json();
- console.log("\n📦 Response:");
- console.log(JSON.stringify(responseData, null, 2));
- }
-
- } catch (err) {
- console.error("\n❌ Request failed:", err.message);
- if (process.env.DEBUG) {
- console.error(err.stack);
- }
- process.exit(1);
- }
-})();