Skip to content

Repository files navigation

Agent Tetris · NOOA

Однооконный Tetris, в котором фигурой управляет модель через NVIDIA NOOA. Игра не использует таймер: каждый тик длится ровно столько, сколько модели нужно на ответ.

Цикл одного тика:

  1. Движок рендерит PNG и точную текстовую сетку игрового поля.
  2. Выбранный адаптер отправляет совместимый формат, компактное состояние и пользовательский промпт в модель.
  3. PredictStrategy валидирует ответ по строгой Pydantic-схеме.
  4. Ровно одна команда применяется к фигуре, затем выполняется один шаг гравитации.

NOOA здесь работает в single-shot режиме и не исполняет сгенерированный моделью Python-код.

Безопасность: приложение отправляет игровое состояние и выбранный режим представления в настроенный пользователем LLM endpoint. Не помещайте в prompt, provider-конфиг или логи секреты и персональные данные. API-ключи хранятся только локально — через environment variables или config/providers.local.json.

Запуск

Требования: macOS/Linux и uv. Для локальных Gemma нужен LM Studio server на http://localhost:1234; для Eliza — непустой ~/.tokens/eliza_token.

cd ~/programming/my/tetris-agent-lab
uv sync
uv run tetris-agent

Меню модели содержит:

  • LM Studio · google/gemma-4-12b — изображение или текстовая сетка;
  • LM Studio · google/gemma-4-31b — изображение или текстовая сетка;
  • Eliza · qwen/qwen3.7-max — только текстовая сетка, поскольку endpoint модели объявляет text→text и отвергает image input.
  • Настраиваемые OpenAI-compatible провайдеры из config/providers.local.json. Для них появляется редактируемое поле поиска и кнопка ОБНОВИТЬ /MODELS. Список загружается с provider-specific /models, а режим изображения доступен только моделям с capabilities.vision=true (или совпавшим с fallback-pattern).

Локальный конфиг намеренно находится в .gitignore и не попадает в коммиты. Рабочий пример структуры лежит в config/providers.example.json:

{
  "openai_compatible_providers": [
    {
      "key": "my-provider",
      "label": "My Provider",
      "base_url": "https://api.example.com/v1",
      "api_key": "replace-me",
      "models_path": "models",
      "default_model": "model-id",
      "default_vision": false,
      "vision_model_patterns": ["vision", "-vl"]
    }
  ]
}

Вместо api_key можно указать api_key_env; путь к конфигу переопределяется через TETRIS_AGENT_PROVIDERS_CONFIG. Локальному файлу рекомендуется mode 0600. Текущая настройка AnyModel использует https://anymodel.org/v1; /models на момент проверки вернул 101 модель, из них 50 с vision. Стартовая проверенная модель — gc/gemini-2.5-flash-lite.

По умолчанию выбрана Gemma 4 12B в режиме изображения. Если выбранная локальная модель скачана, но не загружена, адаптер загрузит её через native LM Studio API с контекстом 8192 токенов.

Настройка без изменения кода:

LM_STUDIO_MODEL=google/gemma-4-31b uv run tetris-agent
LM_STUDIO_BASE_URL=http://localhost:1234/v1 uv run tetris-agent
LM_STUDIO_CONTEXT_LENGTH=16384 uv run tetris-agent
ELIZA_TOKEN=... uv run tetris-agent  # необязательная альтернатива token-файлу

В UI нет клавиатурного или ручного управления фигурой: только Start/Stop и редактируемый промпт. Опциональная тень места приземления выключена по умолчанию; галочка доступна только между играми и одновременно управляет UI и PNG модели. Галочка «Включить историю» также доступна только между играми. По умолчанию она выключена: каждый тик получает свежий разговорный контекст без прошлых ответов, recent_actions и previous_note. При включении один NOOA-агент и его чат сохраняются до Stop/Game Over, поэтому модель видит прошлые наблюдения и собственные ответы. Длинная история, особенно с PNG, увеличивает контекст, задержку и расход памяти модели. Solid-блоки — зафиксированные клетки и текущая фигура. Справа ведётся журнал ответов: список тиков переключает показанный JSON. Пока выбран последний тик, список автоматически следует за новыми ответами; выбор старого тика приостанавливает auto-follow.

Текстовая сетка всегда содержит 20 строк по 10 клеток: . — пусто, заглавные IOTSZJL — зафиксированные блоки, @ — текущая падающая фигура, * — опциональная тень. Все четыре координаты текущей фигуры перечисляются отдельно, включая клетки выше видимого поля. Также observation содержит число закреплённых клеток, высоты и дыры колонок, а для допустимых прямых приземлений — точные конечные клетки и метрики. Это снимает с text-only модели ненадёжный мысленный расчёт геометрии; команда остаётся решением агента.

JSON-протокол

Модель обязана вернуть объект вида:

{"action":"rotate_cw","note":"Flatten the right side"}

action допускает только:

  • left, right
  • rotate_cw, rotate_ccw
  • soft_drop, hard_drop
  • wait

Лишние поля, неизвестные действия и note длиннее 160 символов отвергаются. NOOA делает до трёх попыток исправить невалидный структурированный ответ.

Проверки

uv run pytest
uv run ruff check .
uv run python scripts/smoke_ui.py
uv run python scripts/smoke_lmstudio.py
uv run python scripts/smoke_provider.py --profile eliza-qwen-3-7-max --mode text_grid
uv run python scripts/smoke_provider.py --profile eliza-qwen-3-7-max --mode text_grid --history --ticks 2
uv run python scripts/smoke_provider.py --profile openai-compatible:anymodel --mode image --ticks 1
uv run python scripts/smoke_provider.py --profile openai-compatible:anymodel --model am/gemma-4-31b-it --mode image --ticks 1

Две последние команды выполняют реальные provider-запросы. Каждая игровая сессия пишется в logs/session-*.jsonl; логи не коммитятся.

Структура

  • game.py — детерминированный Tetris state machine.
  • render.py — синхронные PNG и text-grid представления поля.
  • placement.py — точный анализ и ранжирование конечных приземлений text-grid.
  • protocol.py — строгий JSON-контракт.
  • prompts.py — полный редактируемый prompt с правилами и стратегией размещения.
  • adapters/base.py — универсальный порт провайдера.
  • adapters/catalog.py — подключённые модели и capability-матрица.
  • adapters/nooa_openai.py — общий OpenAI-compatible NOOA-движок.
  • adapters/lmstudio.py, adapters/eliza.py — provider-specific подключение.
  • adapters/openai_compatible.py/models, capability parsing и generic adapter.
  • provider_config.py — безопасная загрузка локального provider-конфига.
  • runner.py — прерываемый пошаговый цикл.
  • app.py — единственное окно PySide6.
  • DEVLOG.md — журнал разработки, решений и известных ограничений.

Лицензия

Код этого репозитория распространяется по Apache License 2.0. Сторонние Python-пакеты и внешние LLM-провайдеры сохраняют собственные условия; подробности — в THIRD_PARTY_NOTICES.md.

About

Игровой бенчмарк визуальных и интеллектуальных способностей LLM: прохождение Tetris через NVIDIA NOOA.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages