Skip to content

About

simple llm proxy

Resources

Contributing

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

backend-adapter — Anthropic API ↔ [OI] Backend Proxy

backend router and endpoint adapter: [AN] Messages <-> [OI]-compatible backends for AI agents

v1.0.1 — HTTP-прокси-адаптер, позволяющий работать агентам с Anthropic-совместимым API ([CC], QwenCode) через бэкенд LLM, который реализует [OI]-совместимый API (/v1/chat/completions), но некорректно реализует протокол Anthropic Messages API.

[CC] / QwenCode  ←--Anthropic API-->  adapter (localhost:9999)  ←--[OI] API-->  LLM Backend

Поддерживаемые клиенты

  • [CC] — docs/claude_code.md: модель передаётся по имени в запросе, объявлять её заранее не нужно.
  • QwenCode — docs/qwen-code.md: модели объявляются заранее в modelProviders, зато у каждой может быть своё контекстное окно.
  • Codex CLI — docs/codex.md: работает через Responses API (wire_api = "responses"), переключение модели командой /model <имя>.
  • Любой другой клиент — Anthropic Messages API (/v1/messages) и [OI]-совместимые клиенты (/v1/chat/completions, /v1/responses), см. docs/routing.md.

Проблемы, которые решает адаптер

  1. System messages. Бэкенд кластеризует system messages в конец диалога — адаптер собирает их в одно сообщение в начале.
  2. Format mismatch. Клиент отправляет запросы в формате Anthropic Messages API, а бэкенд ожидает [OI] Chat Completions. Адаптер выполняет двунаправленную конвертацию (сообщения, инструменты, tool choice).
  3. Model compatibility. Позволяет использовать модели Qwen (например qwen3.6-35b-a3b) через [CC] и QwenCode.
  4. Qwen tool_calls fallback. Модели Qwen иногда возвращают вызовы инструментов в текстовом формате с JSON внутри XML-подобных тегов — адаптер автоматически парсит этот формат.

Возможности

  • Прозрачное проксирование: ретраи/таймауты, конвертация Anthropic ↔ [OI] (в т.ч. стриминг SSE), маскирование секретов в логах. С v0.9.9 — адаптивный ретрай при reasoning_budget_exhausted (HTTP 502): адаптер поднимает max_tokens и немедленно повторяет запрос, не отдавая ошибку клиенту (ADAPTER_REASONING_RETRY, ADAPTER_REASONING_MIN_TOKENS). Входные эндпоинты (v0.9.0): наряду с /v1/messages адаптер принимает /v1/chat/completions и /v1/responses; TARGET-переменные (ADAPTER_*_TARGET) задают режим обработки для каждого входа — прямое преобразование в указанный формат (конверсии messages→completions, messages→messages — сортировка system, responses→responses и responses→completions — с поддержкой команды /model, completions→completions — дословная копия E→E), passthrough (дословная передача: тело и SSE-поток возвращаются как есть) или выключение входа (none). С v1.0.0 дефолты всех трёх входов — completions: из коробки работают [CC], [OI]-клиенты и Codex.
  • Логирование и наблюдаемость: консольные debug-блоки [...] печатаются всегда (с обрезкой до ADAPTER_LOG_TRIM; 0 — без обрезки); файловая запись per-session логов (session-*.log/*.jsonl, *.parts дампы) — по ADAPTER_DEBUG_ENABLE=1 в подпапку log/ корня данных ADAPTER_DATA_ROOT (дефолт ~/.ba, совпадает с домашней папкой --root), файлы несут полные строки без обрезки; per-session JSON/YAML-дампы всех логгируемых частей пишутся тем же флагом (v0.9.10), и тем же флагом в фоне (тихий период ADAPTER_ARTIFACT_DEBOUNCE) пересобирается дерево артефактов сессии — запрос прокси рендер не ждёт; .err-файлы инцидентов (v0.9.0) — при финальном ответе клиенту 4xx/5xx реального прокси-запроса пишутся в ту же директорию безусловно (полные запрос и ошибка, без обрезки по TRIM, вне ADAPTER_DEBUG_ENABLE; redact по умолчанию). С v0.9.5 .err фиксирует ошибки уровня адаптера, не дошедшие до бэкенда (отказы маршрутизации disabled/reject, 400 валидации модели, 501); с v0.9.7 право на блок определяется распознанным входным путём (_req_ctx.err_eligible) и не зависит от ADAPTER_SESSIONS_TABLE, а покрытие расширено на 500 (необработанное исключение), 501 неподдерживаемых HTTP-методов и обрыв потока mid-stream (final_status=200, пометка mid-stream abort). Счётчик «Ошибок» в таблице /sessions — ссылка на этот файл.
  • WEBUI (поднимается всегда, флага отключения нет):
    • / — статус-страница: шапка «Backend-Adapter Version <x.x.x>» с иконками-навигацией 🔃 (перепроверить бэкенды, POST /) / 🗂 (/sessions) / 📋 (/session) / 🔧 (/config), LLM-эндпоинты, таблица «Models in use» с live-счётчиками вызовов/токенов и колонкой Cost (по тарифам ADAPTER_MODELS_TARIFFS; ставится live-поллингом через innerHTML — cost_html с сервера); действия строки — иконки-кнопки ⏪ (сбросить счётчики) / 🗑 (удалить строку); проверка бэкендов по кнопке-иконке 🔃 (перечитывает ADAPTER_BACKEND_CONFIG без рестарта);
    • /sessions — таблица сессий агентов (v0.9.5): строки-кортежи (session, agent, model, backend, route) с колонкой входного эндпойнта, счётчиком ошибок-ссылкой на .err-файл (открывается в новом окне) и пер-сессионными выпадающими списками Log / TARGET (наследуют общие настройки, пока не заданы явно); действия строки — ⏪ (сбросить счётчики только этой строки) / 🗑 (удалить строку); ссылка 🗂 со статус-страницы открывается в новом окне, обратная ссылка «Статус 📊» — в текущем;
    • /session — просмотр сессий (*.parts, дерево артефактов, hash8-алиасы; обратная ссылка «Статус 📊»);
    • /config — переключение объёма debug-записи на лету (runtime-пул; обратная ссылка «Статус 📊»);
    • /healthz, /health, /live, /ready — health-check для оркестрации;
    • Prometheus-экспортёр (ADAPTER_EXPORTER_ENABLE=1, отдельный слушатель, дефолт 127.0.0.1:9100).
  • Мониторинг использования: таблица использованных моделей персистентна (model-usage.yaml в подпапке var/ корня данных ADAPTER_DATA_ROOT), счётчики строки обнуляются (⏪) и строка удаляется из таблицы и файла (🗑) по кнопкам/API (POST /api/model-usage/reset, /delete).

Quick start

# 1. Клонировать репозиторий
git clone https://github.com/alekseybb197/backend-adapter.git
cd backend-adapter

# 2. Установить зависимости (единственная внешняя — PyYAML)
pip install -r requirements.txt

# 3. Скопировать и заполнить env-файл и YAML-конфиг бэкенда
cp docs/samples/sample.adapter.env  adapter.env
cp docs/samples/sample.adapter.yaml adapter.yaml
#    (в adapter.env: токен ADAPTER_BACKEND_KEY_LLM_SERVICE и пути)

# 4. Загрузить env-переменные
source adapter.env

# 5. Запустить адаптер
python3 backend-adapter.py

# 6. В другом терминале запустить клиент
claude                 # Claude Code — см. docs/claude_code.md
qwen                   # QwenCode   — см. docs/qwen-code.md

Вариант через домашнюю папку (v0.9.11–v0.9.13): вместо шагов 3-4 разметьте домашнюю папку ~/.ba одной командой и запускайте с --root (дом и корень данных совпадают — log/ и var/ лежат прямо в <root>):

python3 backend-adapter.py --install          # создать ~/.ba со всеми конфигами
# или сразу с одним бэкендом (v0.9.13):
python3 backend-adapter.py --install --root ~/.ba \
    --name demo --base https://llm.example.com --key ADAPTER_DEMO_KEY
$EDITOR ~/.ba/adapter.env                     # вписать токен бэкенда
python3 backend-adapter.py --check --root ~/.ba   # проверить конфиги (exit 1 при ошибке типов)
python3 backend-adapter.py --root ~/.ba       # запуск с настройками из дома

Повторный --install не теряет прежние файлы: существующий файл уходит в <файл>.bak, после чего перезаписывается свежим из шаблона.

Дом можно не указывать: без --root адаптер ищет его сам — сначала в текущей папке, затем в ~/.ba (признак — adapter.env или adapter.yaml); первый найденный становится домом. Явные переменные окружения всегда побеждают.

Ключи CLI: --version/-v, --help/-h/-?, --root <путь>, --install, --install --name/--base/--key (только вместе), --check (подробности — docs/install.md §4.5).

Подробная инструкция: docs/install.md

Документация

Файл Описание
docs/install.md Установка, конфигурация, systemd/launchd, troubleshooting
docs/claude_code.md Настройка клиента [CC]: профиль, проектные настройки, статус-строка, модели и контекст
docs/qwen-code.md Настройка клиента QwenCode: modelProviders, модели с разным контекстным окном, id сессии
docs/codex.md Настройка клиента Codex CLI: Responses API, config.toml, переключение модели командой /model
docs/routing.md Настройка входных эндпоинтов и маршрутизации (TARGET): принципы, реализованное, перспективы
docs/environment.md Полный справочник всех env-переменных
docs/logging.md Конфигурация логирования и trace
docs/sanitizing.md Санитизация и маскирование секретов
docs/architecture.md Архитектура, диаграмма компонентов, lifecycle запросов
docs/webui.md WEBUI и API: страницы /, /sessions, /session, /config, /api/*, секция «Models in use» (live-счётчики) и таблица сессий с пер-сессионными настройками
docs/adr/ Архитектурные решения (ADR): действующие решения, предложения, порядок принятия

Структура проекта

backend-adapter/
├── backend-adapter.py          # Точка входа (__version__)
├── backend_adapter/            # Доменный пакет (38 модулей, включая __init__.py)
│   ├── config.py               # Парсинг env, multi-backend YAML, фоновые проверки
│   ├── server.py               # HTTP-сервер (три входа + TARGET-маршрутизация)
│   ├── routing.py              # Входные эндпоинты/TARGET: decide() по TARGET
│   ├── convert.py              # Конвертация сообщений/инструментов
│   ├── streaming.py            # SSE streaming: конверсия + passthrough E→E relay
│   ├── tracer.py               # JSONL trace-логирование
│   ├── session_log.py          # Per-session логи с FIFO eviction
│   ├── session_registry.py     # Таблица сессий (страница /sessions): строка-кортеж
│   ├── session_settings.py     # Пер-сессионные переопределения Log/TARGET
│   ├── state_store.py          # Перманентный runtime-пул (state.yaml, v0.9.6)
│   ├── env_validate.py         # Строгая валидация env при старте (v0.9.6)
│   ├── env_check.py            # Офлайн-диагностика --check: типы и устаревшие (v0.9.13)
│   ├── daemon.py               # Detach (double fork)
│   ├── shutdown.py             # Обработка Ctrl-C/SIGTERM
│   ├── logger.py               # Консольные debug-логи (безусловны)
│   ├── redact.py               # Маскирование секретов
│   ├── webserver.py            # WEBUI-ядро (роутинг эндпойнтов, serve(), CLI)
│   ├── webui_status.py         # WEBUI "/": статус-страница, usage-таблица, /api/*
│   ├── webui_sessions.py       # WEBUI "/sessions": таблица сессий + /api/sessions/*
│   ├── webui_errors.py         # WEBUI "/errors/<имя>": превью .err-файла сессии
│   ├── webui_ops.py            # WEBUI health: /healthz /health /live /ready
│   ├── webui_config_api.py     # WEBUI "/config": runtime-конфиг
│   ├── prometheus_exporter.py  # Метрики /metrics (отдельный слушатель)
│   ├── session_viewer.py       # WEBUI "/session": просмотр *.parts сессий
│   ├── model_usage.py          # Персистентный учёт использованных моделей, тарифы
│   ├── probe_json.py           # JSON-результат опроса списка моделей в var/
│   ├── cli.py                  # CLI-утилиты (runpy-трамплин команды backend-adapter)
│   ├── cli_args.py             # Разбор argv: --version/--help/--root/--install/--check (v0.9.13)
│   ├── templates.py            # Встроенные шаблоны дефолтов для --install (v0.9.12)
│   ├── artifact_tree*.py       # Генерация дерева артефактов (8 модулей)
│   ├── artifact_refresh.py     # Фоновая дебаунсная отрисовка артефактов (v0.9.10)
│   └── __init__.py             # Lazy-прокси глобалов config/logger/tracer на старте
├── docs/                       # Документация
│   ├── samples/                # Примеры конфигов: sample.adapter.env (env-файл),
│   │                           #   sample.adapter.yaml (YAML бэкендов),
│   │                           #   sample.tariffs.yaml (тарифы моделей),
│   │                           #   backend-adapter.service + com.user.backend-adapter.plist
│   │                           #   (шаблоны systemd/launchd для запуска из исходников)
│   ├── claude_code/            # Локальные настройки клиента [CC] (settings/statusline)
│   ├── qwen-code/              # Локальные настройки клиента QwenCode (settings)
│   └── codex/                  # Локальные настройки клиента Codex CLI (config.toml)
├── molecule/                   # molecule-тесты install.sh (Linux, ubuntu 24.04):
│                               #   install — установка/обновление бинарника;
│                               #   service — системный systemd, обновление и --delete
└── requirements.txt            # Зависимости (единственная — PyYAML)

GitHub · Changelog

About

simple llm proxy

Resources

Contributing

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages