API / kiro-gateway /docs /ru /ARCHITECTURE.md
sshinmen's picture
Clean deploy to HF Space
bf9e111
|
Raw
History Blame Contribute Delete
46.5 kB

Архитектурный Обзор: Kiro Gateway

1. Назначение и Цели Системы

Проект представляет собой высокоуровневый прокси-шлюз, реализующий структурный паттерн проектирования "Адаптер" (Adapter).

Основная цель системы — обеспечить прозрачную совместимость между несколькими гетерогенными интерфейсами:

Поддерживаемые API форматы

API Эндпоинты Статус
OpenAI /v1/models, /v1/chat/completions ✅ Поддерживается
Anthropic /v1/messages ✅ Поддерживается

Архитектурная модель

┌─────────────────────────────────────────────────────────────────┐
│                         Клиенты                                 │
│  ┌─────────────────────┐       ┌─────────────────────┐         │
│  │  OpenAI SDK/Tools   │       │ Anthropic SDK/Tools │         │
│  │  (Cursor, Cline,    │       │ (Claude Code,       │         │
│  │   Continue, etc.)   │       │  Anthropic SDK)     │         │
│  └──────────┬──────────┘       └──────────┬──────────┘         │
└─────────────┼──────────────────────────────┼───────────────────┘
              │                              │
              ▼                              ▼
┌─────────────────────────────────────────────────────────────────┐
│                      Kiro Gateway                               │
│  ┌─────────────────────┐       ┌─────────────────────┐         │
│  │  OpenAI Adapter     │       │  Anthropic Adapter  │         │
│  │  /v1/chat/...       │       │  /v1/messages       │         │
│  └──────────┬──────────┘       └──────────┬──────────┘         │
│             └──────────────┬───────────────┘                    │
│                            ▼                                    │
│             ┌─────────────────────────────┐                     │
│             │      Core Layer             │                     │
│             │  (Общая логика конвертации) │                     │
│             └──────────────┬──────────────┘                     │
└────────────────────────────┼────────────────────────────────────┘
                             │
                             ▼
┌─────────────────────────────────────────────────────────────────┐
│                        Kiro API                                 │
│              (AWS CodeWhisperer Backend)                        │
└─────────────────────────────────────────────────────────────────┘

Система выступает в роли "переводчика", позволяя использовать любые инструменты, библиотеки и IDE-плагины, разработанные для экосистем OpenAI и Anthropic, с моделями Claude через Kiro API.

Оба API работают одновременно на одном сервере без необходимости переключения в настройках.

2. Структура Проекта

Проект организован в виде модульного Python-пакета kiro/:

kiro-gateway/
├── main.py                    # Точка входа, создание FastAPI приложения
├── requirements.txt           # Зависимости Python
├── .env.example               # Пример конфигурации окружения
│
├── kiro/              # Основной пакет
│   ├── __init__.py            # Экспорты пакета, версия
│   │
│   │   # ═══════════════════════════════════════════════════════
│   │   # SHARED LAYER - Переиспользуется всеми API
│   │   # ═══════════════════════════════════════════════════════
│   ├── config.py              # Конфигурация и константы
│   ├── auth.py                # KiroAuthManager - управление токенами
│   ├── cache.py               # ModelInfoCache - кэш моделей
│   ├── http_client.py         # HTTP клиент с retry логикой
│   ├── parsers.py             # Парсеры AWS SSE потоков
│   ├── utils.py               # Вспомогательные утилиты
│   ├── tokenizer.py           # Подсчёт токенов (tiktoken)
│   ├── debug_logger.py        # Отладочное логирование запросов
│   ├── exceptions.py          # Обработчики исключений
│   ├── thinking_parser.py     # Парсер thinking блоков
│   │
│   │   # ═══════════════════════════════════════════════════════
│   │   # CORE LAYER - Общее ядро для всех API
│   │   # ═══════════════════════════════════════════════════════
│   ├── converters_core.py     # Общая логика построения Kiro payload
│   ├── streaming_core.py      # Общая логика парсинга Kiro stream
│   │
│   │   # ═══════════════════════════════════════════════════════
│   │   # OPENAI API LAYER
│   │   # ═══════════════════════════════════════════════════════
│   ├── models_openai.py       # Pydantic модели OpenAI API
│   ├── converters_openai.py   # OpenAI → Kiro адаптер
│   ├── routes_openai.py       # FastAPI роуты OpenAI
│   ├── streaming_openai.py    # Kiro → OpenAI SSE форматтер
│   │
│   │   # ═══════════════════════════════════════════════════════
│   │   # ANTHROPIC API LAYER
│   │   # ═══════════════════════════════════════════════════════
│   ├── models_anthropic.py    # Pydantic модели Anthropic API
│   ├── converters_anthropic.py # Anthropic → Kiro адаптер
│   ├── routes_anthropic.py    # FastAPI роуты Anthropic
│   └── streaming_anthropic.py # Kiro → Anthropic SSE форматтер
│
├── tests/                     # Тесты
│   ├── conftest.py            # Pytest fixtures
│   ├── unit/                  # Юнит-тесты
│   └── integration/           # Интеграционные тесты
│
├── docs/                      # Документация
│   ├── ru/                    # Русская версия
│   └── en/                    # Английская версия
│
└── debug_logs/                # Отладочные логи (генерируются при DEBUG_LAST_REQUEST=true)

Принцип организации: Общее ядро + тонкие адаптеры

Архитектура построена на принципе максимального переиспользования кода:

Слой Назначение Файлы
Shared Layer Инфраструктура, не зависящая от формата API auth.py, http_client.py, cache.py, parsers.py, tokenizer.py
Core Layer Общая бизнес-логика конвертации converters_core.py, streaming_core.py
API Layer Тонкие адаптеры для конкретных форматов *_openai.py, *_anthropic.py

3. Архитектурная Топология и Компоненты

Система построена на базе асинхронного фреймворка FastAPI и использует событийную модель управления жизненным циклом (Lifespan Events).

3.1. Точка входа (main.py)

Файл main.py отвечает за:

  1. Конфигурацию логирования — настройка Loguru с цветным выводом
  2. Валидацию конфигурации — функция validate_configuration() проверяет:
    • Наличие файла .env
    • Наличие credentials (REFRESH_TOKEN или KIRO_CREDS_FILE)
  3. Lifespan Manager — создание и инициализация:
    • KiroAuthManager для управления токенами
    • ModelInfoCache для кэширования моделей
  4. Регистрация обработчиков ошибокvalidation_exception_handler для ошибок 422
  5. Подключение роутовapp.include_router(router)

3.2. Модуль конфигурации (kiro/config.py)

Централизованное хранение всех настроек:

Параметр Описание Значение по умолчанию
PROXY_API_KEY API ключ для доступа к прокси changeme_proxy_secret
REFRESH_TOKEN Refresh token Kiro из .env
PROFILE_ARN ARN профиля AWS CodeWhisperer из .env
REGION Регион AWS us-east-1
KIRO_CREDS_FILE Путь к JSON файлу credentials из .env
TOKEN_REFRESH_THRESHOLD Время до обновления токена 600 сек (10 мин)
MAX_RETRIES Макс. количество повторов 3
BASE_RETRY_DELAY Базовая задержка retry 1.0 сек
MODEL_CACHE_TTL TTL кэша моделей 3600 сек (1 час)
DEFAULT_MAX_INPUT_TOKENS Макс. input токенов по умолчанию 200000
TOOL_DESCRIPTION_MAX_LENGTH Макс. длина описания tool 10000 символов
DEBUG_LAST_REQUEST Включить отладочное логирование false
DEBUG_DIR Директория для debug логов debug_logs
APP_VERSION Версия приложения 0.0.0

Вспомогательные функции:

  • get_kiro_refresh_url(region) — URL для обновления токена
  • get_kiro_api_host(region) — хост основного API
  • get_kiro_q_host(region) — хост Q API
  • get_internal_model_id(external_model) — конвертация имени модели

3.3. Pydantic Модели (kiro/models_openai.py)

Модели для /v1/models

Модель Описание
OpenAIModel Описание AI модели (id, object, created, owned_by)
ModelList Список моделей для ответа endpoint

Модели для /v1/chat/completions

Модель Описание
ChatMessage Сообщение чата (role, content, tool_calls, tool_call_id)
ToolFunction Описание функции инструмента (name, description, parameters)
Tool Инструмент OpenAI формата (type, function)
ChatCompletionRequest Запрос на генерацию (model, messages, stream, tools, ...)

Модели ответов

Модель Описание
ChatCompletionChoice Один вариант ответа
ChatCompletionUsage Информация о токенах (prompt_tokens, completion_tokens, credits_used)
ChatCompletionResponse Полный ответ (non-streaming)
ChatCompletionChunk Streaming chunk
ChatCompletionChunkDelta Дельта изменений в chunk
ChatCompletionChunkChoice Вариант в streaming chunk

3.4. Управление Состоянием (State Management Layer)

KiroAuthManager (kiro/auth.py)

Роль: Stateful-синглтон, инкапсулирующий логику управления токенами Kiro.

Возможности:

  • Загрузка credentials из .env или JSON файла
  • Поддержка expiresAt для проверки времени истечения токена
  • Автоматическое обновление токена за 10 минут до истечения
  • Сохранение обновлённых токенов обратно в JSON файл
  • Поддержка разных регионов AWS
  • Генерация уникального fingerprint для User-Agent

Concurrency Control: Использует asyncio.Lock для защиты от состояния гонки.

Основные методы:

  • get_access_token() — возвращает действительный токен, обновляя при необходимости
  • force_refresh() — принудительное обновление токена (при 403)
  • is_token_expiring_soon() — проверка времени истечения

Properties:

  • profile_arn — ARN профиля
  • region — регион AWS
  • api_host — хост API для региона
  • q_host — хост Q API для региона
  • fingerprint — уникальный fingerprint машины
# Пример использования
auth_manager = KiroAuthManager(
    refresh_token="your_token",
    region="us-east-1",
    creds_file="~/.aws/sso/cache/kiro-auth-token.json"
)
token = await auth_manager.get_access_token()

ModelInfoCache (kiro/cache.py)

Роль: Потокобезопасное хранилище конфигураций моделей.

Стратегия Заполнения:

  • Lazy Loading через /ListAvailableModels
  • TTL кэша: 1 час
  • Fallback на статический список моделей

Основные методы:

  • update(models_data) — обновление кэша
  • get(model_id) — получение информации о модели
  • get_max_input_tokens(model_id) — получение лимита токенов
  • is_empty() / is_stale() — проверка состояния кэша
  • get_all_model_ids() — список всех ID моделей

3.5. Вспомогательные Утилиты (kiro/utils.py)

Функция Описание
get_machine_fingerprint() SHA256 хеш {hostname}-{username}-kiro-gateway
get_kiro_headers(auth_manager, token) Формирование заголовков для Kiro API
generate_completion_id() ID в формате chatcmpl-{uuid_hex}
generate_conversation_id() UUID для разговора
generate_tool_call_id() ID в формате call_{uuid_hex[:8]}

3.6. Слой Конвертации (kiro/converters_openai.py)

Конвертация сообщений

OpenAI messages преобразуются в Kiro conversationState:

  1. System prompt — добавляется к первому user сообщению
  2. История сообщений — полностью передаётся в history array
  3. Объединение соседних сообщений — сообщения с одинаковой ролью мерджатся
  4. Tool calls — поддержка OpenAI tools формата
  5. Tool results — корректная передача результатов вызова инструментов

Обработка длинных описаний Tools

Проблема: Kiro API возвращает ошибку 400 при слишком длинных описаниях в toolSpecification.description.

Решение: Tool Documentation Reference Pattern

  • Если description ≤ TOOL_DESCRIPTION_MAX_LENGTH → оставляем как есть
  • Если description > TOOL_DESCRIPTION_MAX_LENGTH:
    • В toolSpecification.description → ссылка: "[Full documentation in system prompt under '## Tool: {name}']"
    • В system prompt добавляется секция "## Tool: {name}" с полным описанием

Функция: process_tools_with_long_descriptions(tools)(processed_tools, tool_documentation)

Основные функции

Функция Описание
extract_text_content(content) Извлечение текста из различных форматов
merge_adjacent_messages(messages) Объединение соседних сообщений с одной ролью
build_kiro_history(messages, model_id) Построение массива history для Kiro
build_kiro_payload(request_data, conversation_id, profile_arn) Полный payload для запроса

Маппинг моделей

Внешние имена моделей преобразуются во внутренние ID Kiro:

Внешнее имя Внутренний ID Kiro
claude-opus-4-5 claude-opus-4.5
claude-opus-4-5-20251101 claude-opus-4.5
claude-haiku-4-5 claude-haiku-4.5
claude-haiku-4.5 claude-haiku-4.5 (прямой проброс)
claude-sonnet-4-5 CLAUDE_SONNET_4_5_20250929_V1_0
claude-sonnet-4-5-20250929 CLAUDE_SONNET_4_5_20250929_V1_0
claude-sonnet-4 CLAUDE_SONNET_4_20250514_V1_0
claude-sonnet-4-20250514 CLAUDE_SONNET_4_20250514_V1_0
claude-3-7-sonnet-20250219 CLAUDE_3_7_SONNET_20250219_V1_0
auto claude-sonnet-4.5 (алиас)

3.7. Слой Парсинга (kiro/parsers.py)

AwsEventStreamParser

Продвинутый парсер AWS SSE формата с поддержкой:

  • Bracket counting — корректный парсинг вложенных JSON объектов
  • Дедупликация контента — фильтрация повторяющихся событий
  • Tool calls — парсинг структурированных и bracket-style tool calls
  • Escape-последовательности — декодирование \n и других

Типы событий

Событие Описание
content Текстовый контент ответа
tool_start Начало tool call (name, toolUseId)
tool_input Продолжение input для tool call
tool_stop Завершение tool call
usage Информация о потреблении кредитов
context_usage Процент использования контекста

Вспомогательные функции

Функция Описание
find_matching_brace(text, start_pos) Поиск закрывающей скобки с учётом вложенности
parse_bracket_tool_calls(response_text) Парсинг [Called func with args: {...}]
deduplicate_tool_calls(tool_calls) Удаление дубликатов tool calls

3.8. Streaming (kiro/streaming_openai.py)

stream_kiro_to_openai

Асинхронный генератор для преобразования потока Kiro в OpenAI формат.

Функциональность:

  • Парсинг AWS SSE stream через AwsEventStreamParser
  • Формирование OpenAI chat.completion.chunk
  • Обработка tool calls (структурированных и bracket-style)
  • Вычисление usage на основе contextUsagePercentage
  • Отладочное логирование через debug_logger

collect_stream_response

Собирает полный ответ из streaming потока для non-streaming режима.

3.9. HTTP Клиент (kiro/http_client.py)

KiroHttpClient

Автоматическая обработка ошибок с exponential backoff:

Код ошибки Действие
403 Refresh токена через force_refresh() + повтор
429 Exponential backoff: BASE_RETRY_DELAY * (2 ** attempt)
5xx Exponential backoff (до MAX_RETRIES попыток)
Timeout Exponential backoff

Формула задержки: 1s, 2s, 4s (при BASE_RETRY_DELAY=1.0)

Методы:

  • request_with_retry(method, url, json_data, stream) — запрос с retry
  • close() — закрытие клиента

Поддерживает async context manager (async with).

3.10. Роуты (kiro/routes_openai.py)

Endpoint Метод Описание
/ GET Health check (status, message, version)
/health GET Детальный health check (status, timestamp, version)
/v1/models GET Список доступных моделей (требует API key)
/v1/chat/completions POST Chat completions (требует API key)

Аутентификация: Bearer token в заголовке Authorization

3.11. Обработка Исключений (kiro/exceptions.py)

Функция Описание
sanitize_validation_errors(errors) Конвертация bytes в строки для JSON-сериализации
validation_exception_handler(request, exc) Обработчик ошибок валидации Pydantic (422)

3.12. Отладочное Логирование (kiro/debug_logger.py)

Класс: DebugLogger (синглтон)

Активация: DEBUG_LAST_REQUEST=true в .env

Методы:

Метод Описание
prepare_new_request() Очистка директории для нового запроса
log_request_body(body) Сохранение входящего запроса
log_kiro_request_body(body) Сохранение запроса к Kiro API
log_raw_chunk(chunk) Дописывание сырого chunk от Kiro
log_modified_chunk(chunk) Дописывание преобразованного chunk

Файлы в debug_logs/:

  • request_body.json — входящий запрос (OpenAI формат)
  • kiro_request_body.json — запрос к Kiro API
  • response_stream_raw.txt — сырой поток от Kiro
  • response_stream_modified.txt — преобразованный поток (OpenAI формат)

3.13. Токенизатор (kiro/tokenizer.py)

Проблема: Kiro API не возвращает напрямую количество токенов. Вместо этого API предоставляет только context_usage_percentage — процент использования контекста модели.

Решение: Модуль токенизатора на базе tiktoken (библиотека OpenAI на Rust) для быстрого подсчёта токенов.

Особенности:

  • Использует кодировку cl100k_base (GPT-4), близкую к токенизации Claude
  • Коэффициент коррекции CLAUDE_CORRECTION_FACTOR = 1.15 для повышения точности
  • Ленивая инициализация для ускорения импорта
  • Fallback на грубую оценку если tiktoken недоступен

Формула расчёта токенов в ответе:

total_tokens = context_usage_percentage × max_input_tokens  (от API Kiro)
completion_tokens = tiktoken(ответ)                         (наш подсчёт)
prompt_tokens = total_tokens - completion_tokens            (вычитание)

Основные функции:

Функция Описание
count_tokens(text) Подсчёт токенов в тексте
count_message_tokens(messages) Подсчёт токенов в списке сообщений
count_tools_tokens(tools) Подсчёт токенов в определениях инструментов
estimate_request_tokens(messages, tools) Полная оценка токенов запроса

Дебаг-лог:

[Usage] claude-opus-4-5: prompt_tokens=142211 (subtraction), completion_tokens=769 (tiktoken), total_tokens=142980 (API Kiro)

Точность: ~97-99.7% по сравнению с данными от API.

3.14. Kiro API Endpoints

Все URL динамически формируются на основе региона:

  • Token Refresh: POST https://prod.{region}.auth.desktop.kiro.dev/refreshToken
  • List Models: GET https://q.{region}.amazonaws.com/ListAvailableModels
  • Generate Response: POST https://codewhisperer.{region}.amazonaws.com/generateAssistantResponse

4. Детальный Поток Данных

4.1 Общая схема (мульти-API)

┌─────────────────────────────────────────────────────────────────┐
│                         КЛИЕНТЫ                                 │
│  ┌─────────────────────┐       ┌─────────────────────┐         │
│  │  OpenAI Client      │       │  Anthropic Client   │         │
│  └──────────┬──────────┘       └──────────┬──────────┘         │
└─────────────┼──────────────────────────────┼───────────────────┘
              │                              │
              │ POST /v1/chat/completions    │ POST /v1/messages
              ▼                              ▼
┌─────────────────────────────────────────────────────────────────┐
│                      API LAYER                                  │
│  ┌─────────────────────┐       ┌─────────────────────┐         │
│  │  routes_openai.py   │       │ routes_anthropic.py │         │
│  │  Security Gate      │       │ Security Gate       │         │
│  └──────────┬──────────┘       └──────────┬──────────┘         │
│             │                              │                    │
│             ▼                              ▼                    │
│  ┌─────────────────────┐       ┌─────────────────────┐         │
│  │converters_openai.py │       │converters_anthropic │         │
│  │ Извлечение system   │       │ System уже отдельно │         │
│  │ из messages         │       │ в запросе           │         │
│  └──────────┬──────────┘       └──────────┬──────────┘         │
└─────────────┼──────────────────────────────┼───────────────────┘
              │                              │
              └──────────────┬───────────────┘
                             │
                             ▼
┌─────────────────────────────────────────────────────────────────┐
│                      CORE LAYER                                 │
│             ┌─────────────────────────────┐                     │
│             │    converters_core.py       │                     │
│             │  build_kiro_payload()       │                     │
│             │  build_kiro_history()       │                     │
│             │  process_tools()            │                     │
│             └──────────────┬──────────────┘                     │
└────────────────────────────┼────────────────────────────────────┘
                             │
                             ▼
┌─────────────────────────────────────────────────────────────────┐
│                     SHARED LAYER                                │
│  ┌─────────────────┐  ┌─────────────────┐  ┌─────────────────┐ │
│  │ KiroAuthManager │  │ KiroHttpClient  │  │  ModelInfoCache │ │
│  │   (auth.py)     │  │(http_client.py) │  │   (cache.py)    │ │
│  └────────┬────────┘  └────────┬────────┘  └─────────────────┘ │
└───────────┼────────────────────┼────────────────────────────────┘
            │                    │
            │                    │ POST /generateAssistantResponse
            │                    ▼
            │         ┌─────────────────────────────────────────┐
            │         │              Kiro API                   │
            │         └──────────────────┬──────────────────────┘
            │                            │
            │                            │ AWS SSE Stream
            │                            ▼
┌───────────┼────────────────────────────────────────────────────┐
│           │            CORE LAYER                              │
│           │  ┌─────────────────────────────┐                   │
│           │  │    streaming_core.py        │                   │
│           │  │  parse_kiro_stream()        │                   │
│           │  │  → KiroEvent objects        │                   │
│           │  └──────────────┬──────────────┘                   │
└────────────────────────────┼───────────────────────────────────┘
                             │
              ┌──────────────┴───────────────┐
              │                              │
              ▼                              ▼
┌─────────────────────────────────────────────────────────────────┐
│                      OUTPUT LAYER                               │
│  ┌─────────────────────┐       ┌─────────────────────┐         │
│  │streaming_openai.py  │       │streaming_anthropic  │         │
│  │ format_openai_sse() │       │format_anthropic_sse │         │
│  │                     │       │                     │         │
│  │ data: {...}         │       │ event: type         │         │
│  │ data: [DONE]        │       │ data: {...}         │         │
│  └──────────┬──────────┘       └──────────┬──────────┘         │
└─────────────┼──────────────────────────────┼───────────────────┘
              │                              │
              ▼                              ▼
┌─────────────────────────────────────────────────────────────────┐
│                         КЛИЕНТЫ                                 │
│  ┌─────────────────────┐       ┌─────────────────────┐         │
│  │  OpenAI Client      │       │  Anthropic Client   │         │
│  └─────────────────────┘       └─────────────────────┘         │
└─────────────────────────────────┘

4.2 Поток OpenAI API

OpenAI Client
     │ POST /v1/chat/completions
     ▼
routes_openai.py ──► converters_openai.py ──► converters_core.py
     │                                              │
     │                                              ▼
     │                                        Kiro Payload
     │                                              │
     ▼                                              ▼
KiroAuthManager ──────────────────────────► KiroHttpClient
                                                   │
                                                   ▼
                                              Kiro API
                                                   │
                                                   ▼
streaming_core.py ◄─────────────────────── AWS SSE Stream
     │
     ▼
streaming_openai.py
     │
     ▼
OpenAI SSE Format ──────────────────────► OpenAI Client

4.3 Поток Anthropic API

Anthropic Client
     │ POST /v1/messages
     ▼
routes_anthropic.py ──► converters_anthropic.py ──► converters_core.py
     │                                                    │
     │                                                    ▼
     │                                              Kiro Payload
     │                                                    │
     ▼                                                    ▼
KiroAuthManager ──────────────────────────────────► KiroHttpClient
                                                         │
                                                         ▼
                                                    Kiro API
                                                         │
                                                         ▼
streaming_core.py ◄─────────────────────────────── AWS SSE Stream
     │
     ▼
streaming_anthropic.py
     │
     ▼
Anthropic SSE Format ──────────────────────────► Anthropic Client

5. Доступные Модели

Модель Описание Credits
claude-opus-4-5 Топовая модель ~2.2
claude-opus-4-5-20251101 Топовая модель (версия) ~2.2
claude-sonnet-4-5 Улучшенная модель ~1.3
claude-sonnet-4-5-20250929 Улучшенная модель (версия) ~1.3
claude-sonnet-4 Сбалансированная модель ~1.3
claude-sonnet-4-20250514 Сбалансированная (версия) ~1.3
claude-haiku-4-5 Быстрая модель ~0.4
claude-3-7-sonnet-20250219 Legacy модель ~1.0

6. Конфигурация

Переменные окружения (.env)

# Обязательные
REFRESH_TOKEN="your_kiro_refresh_token"
PROXY_API_KEY="your_proxy_secret"

# Опциональные
PROFILE_ARN="arn:aws:codewhisperer:..."
KIRO_REGION="us-east-1"
KIRO_CREDS_FILE="~/.aws/sso/cache/kiro-auth-token.json"

# Отладка
DEBUG_LAST_REQUEST="false"
DEBUG_DIR="debug_logs"

# Лимиты
TOOL_DESCRIPTION_MAX_LENGTH="10000"

JSON файл credentials (опционально)

{
  "accessToken": "eyJ...",
  "refreshToken": "eyJ...",
  "expiresAt": "2025-01-12T23:00:00.000Z",
  "profileArn": "arn:aws:codewhisperer:us-east-1:...",
  "region": "us-east-1"
}

7. API Endpoints

7.1 Общие эндпоинты

Endpoint Метод Описание
/ GET Health check
/health GET Детальный health check

7.2 OpenAI-совместимые эндпоинты

Endpoint Метод Описание
/v1/models GET Список доступных моделей
/v1/chat/completions POST Chat completions (streaming/non-streaming)

Аутентификация: Authorization: Bearer {PROXY_API_KEY}

7.3 Anthropic-совместимые эндпоинты

Endpoint Метод Описание
/v1/messages POST Messages API (streaming/non-streaming)

Аутентификация: x-api-key: {PROXY_API_KEY} + anthropic-version: 2023-06-01

7.4 Сравнение форматов

Аспект OpenAI Anthropic
System prompt В messages с role: "system" Отдельное поле system
Content Строка или массив Всегда массив content blocks
Stop reason finish_reason: "stop" stop_reason: "end_turn"
Usage prompt_tokens, completion_tokens input_tokens, output_tokens
Streaming data: {...}\n\n + data: [DONE] event: type\ndata: {...}\n\n
Tool format {type: "function", function: {...}} {name: "...", input_schema: {...}}

8. Особенности Реализации

Tool Calling

Поддержка OpenAI-совместимого формата tools:

{
  "tools": [{
    "type": "function",
    "function": {
      "name": "get_weather",
      "description": "Get weather for a location",
      "parameters": {
        "type": "object",
        "properties": {
          "location": {"type": "string"}
        }
      }
    }
  }]
}

Streaming

Полная поддержка SSE streaming с корректным форматом OpenAI:

data: {"id":"chatcmpl-...","object":"chat.completion.chunk",...}

data: [DONE]

Отладка

При DEBUG_LAST_REQUEST=true все запросы и ответы логируются в debug_logs/:

  • request_body.json — входящий запрос
  • kiro_request_body.json — запрос к Kiro API
  • response_stream_raw.txt — сырой поток от Kiro
  • response_stream_modified.txt — преобразованный поток

9. Расширяемость

Добавление нового API формата

Модульная архитектура позволяет легко добавить поддержку других API форматов. Благодаря Core Layer, большая часть логики уже реализована.

Шаги для добавления нового формата (например, Gemini)

  1. Создать моделиmodels_gemini.py

    class GeminiRequest(BaseModel):
        """Pydantic модель запроса Gemini."""
        contents: List[GeminiContent]
        ...
    
  2. Создать адаптер конвертацииconverters_gemini.py

    from kiro.converters_core import build_kiro_payload
    
    def gemini_to_kiro(request: GeminiRequest, ...) -> dict:
        """Конвертирует Gemini запрос в Kiro payload."""
        # Извлекаем данные из Gemini формата
        system_prompt = extract_system_instruction(request)
        messages = convert_gemini_contents(request.contents)
        tools = convert_gemini_tools(request.tools)
        
        # Используем общее ядро
        return build_kiro_payload(
            messages=messages,
            system_prompt=system_prompt,
            tools=tools,
            ...
        )
    
  3. Создать форматтер streamingstreaming_gemini.py

    from kiro.streaming_core import parse_kiro_stream
    
    async def stream_to_gemini(response, ...) -> AsyncGenerator[str, None]:
        """Форматирует Kiro события в Gemini SSE."""
        async for event in parse_kiro_stream(response):
            yield format_gemini_chunk(event)
    
  4. Создать роутыroutes_gemini.py

    router = APIRouter()
    
    @router.post("/v1beta/models/{model}:generateContent")
    async def generate_content(request: GeminiRequest):
        ...
    
  5. Подключить в main.py

    from kiro.routes_gemini import router as gemini_router
    app.include_router(gemini_router)
    

Что переиспользуется автоматически

При добавлении нового формата следующие компоненты работают "из коробки":

Компонент Функциональность
auth.py Управление токенами Kiro
http_client.py HTTP с retry логикой
cache.py Кэш моделей
parsers.py Парсинг AWS SSE
tokenizer.py Подсчёт токенов
converters_core.py Построение Kiro payload
streaming_core.py Парсинг Kiro stream

10. Зависимости

Основные зависимости проекта (из requirements.txt):

Пакет Назначение
fastapi Асинхронный веб-фреймворк
uvicorn ASGI сервер
httpx Асинхронный HTTP клиент
pydantic Валидация данных и модели
python-dotenv Загрузка переменных окружения
loguru Продвинутое логирование
tiktoken Быстрый подсчёт токенов