Maksim Totmin 338bd80a95 fix: use provider block's own vision model on legacy fallback
When falling back to a provider block (providerID / legacy ludmila-ai),
prefer the model flagged attachment:true in that block instead of the
Google-default options.model. Prevents sending 'gemini-2.5-flash' to the
ludmila endpoint which expects 'gemini/gemini-2.5-flash'.
2026-08-04 20:44:14 +07:00

Opencode Vision Bridge Plugin

Этот плагин позволяет Opencode работать с изображениями, даже если активная модель не поддерживает мультимодальность. Он перехватывает изображения, отправляет их в vision-модель для анализа, а затем заменяет изображение текстовым описанием в контексте диалога.

Распознавание выполняется через Google Gemini API (OpenAI-совместимый эндпоинт), модель по умолчанию — gemini-2.5-flash. Если активная модель сама умеет видеть изображения (помечена "attachment": true в конфиге), картинки передаются ей напрямую без распознавания.

Требования

  • API-ключ Google Gemini. Получить бесплатно: Google AI Studio.
  • Сетевой доступ к generativelanguage.googleapis.com.

Установка

1. Добавьте плагин в ~/.config/opencode/opencode.json

В секцию plugin добавьте запись (tuple-форма с опциями):

{
  "plugin": [
    // ... другие плагины
    [
      "git+https://git.totmin.ru/en2zmax/vision-bridge.git",
      {
        "baseURL": "https://generativelanguage.googleapis.com/v1beta/openai",
        "apiKey": "{env:GEMINI_API_KEY}",
        "model": "gemini-2.5-flash"
      }
    ]
  ]
}

apiKey можно указать явной строкой, шаблоном {env:ИМЯ_ПЕРЕМЕННОЙ} — либо не указывать вовсе, тогда плагин возьмёт его из GEMINI_API_KEY.

2. Задайте API-ключ

export GEMINI_API_KEY=ВАШ_КЛЮЧ

Добавьте это в ~/.bashrc / ~/.zshrc, чтобы ключ был доступен при каждом запуске.

3. (Опционально) Зарегистрируйте провайдера Google

Нужно только если вы хотите использовать модель gemini-2.5-flash как основную или для vision-сабагента:

{
  "provider": {
    "google": {
      "npm": "@ai-sdk/google",
      "name": "Google",
      "options": {
        "apiKey": "{env:GEMINI_API_KEY}"
      },
      "models": {
        "gemini-2.5-flash": {}
      }
    }
  }
}

4. Скопируйте файл субагента

Субагенты не загружаются из npm-пакетов, поэтому скопируйте файл vision.md в соответствующий каталог:

cp agents/vision.md ~/.config/opencode/agents/vision.md

Субагент использует модель google/gemini-2.5-flash.

5. Перезапустите Opencode

Изменения в конфигурации применяются только после перезапуска Opencode.

Подключение другого OpenAI-совместимого сервиса

Плагин универсален: подойдёт любой сервис с эндпоинтом /chat/completions. Достаточно поменять опции:

  • OpenAI: baseURL: "https://api.openai.com/v1", model: "gpt-4o-mini", apiKey: "{env:OPENAI_API_KEY}".
  • Любой OpenAI-совместимый прокси — аналогично.

Опции плагина

Опция По умолчанию Назначение
baseURL https://generativelanguage.googleapis.com/v1beta/openai Эндпоинт /chat/completions
apiKey process.env.GEMINI_API_KEY Ключ API (поддерживает {env:VAR})
model gemini-2.5-flash Модель распознавания
providerID ludmila-ai (legacy) Читать настройки из блока provider конфига opencode
visionModels модели с attachment: true ID моделей, которые видят изображения нативно

Пример конфигурации (examples/opencode.json)

{
  "$schema": "https://opencode.ai/config.json",
  "plugin": [
    "opencode-browser",
    [
      "git+https://git.totmin.ru/en2zmax/vision-bridge.git",
      {
        "baseURL": "https://generativelanguage.googleapis.com/v1beta/openai",
        "apiKey": "{env:GEMINI_API_KEY}",
        "model": "gemini-2.5-flash"
      }
    ]
  ],
  "provider": {
    "google": {
      "npm": "@ai-sdk/google",
      "name": "Google",
      "options": {
        "apiKey": "{env:GEMINI_API_KEY}"
      },
      "models": {
        "gemini-2.5-flash": {}
      }
    }
  },
  "agent": {
    "vision": {
      "mode": "subagent",
      "model": "google/gemini-2.5-flash",
      "description": "Анализ изображений и скриншотов (OCR текста или разбор UI)",
      "permission": {
        "read": "allow",
        "glob": "allow",
        "external_directory": "allow",
        "edit": "deny",
        "bash": "deny"
      }
    }
  }
}
S
Description
No description provided
Readme
47 KiB
Languages
TypeScript 100%