От OpenCode нужны ровно два значения:
baseURL = https://speshu.ai/api/v1 и API-ключ. /api/v1/chat/completions совместим с OpenAI Chat Completions, поэтому в код или настройки самого агента ничего вносить не нужно. Ключ создаётся на speshu.ai/profile, подробности — в разделе Аутентификация.Ключ и идентификатор модели
Получите ключ и положите его в переменную окружения:cURL
cURL
$SPESHU_MODEL — это переменная с идентификатором, который вернул каталог. Формат ответа и параметры выбора — в разделе Модели и цены.
Конфигурация
Где лежит файл
Файлы не заменяют друг друга, а сливаются: при конфликте ключей выигрывает проектный. Формат — JSON или JSONC, схема одна:
https://opencode.ai/config.json.
Ключи из /connect OpenCode хранит отдельно, в ~/.local/share/opencode/auth.json — их не нужно класть в opencode.json.
Провайдер
Опишите в секцииprovider провайдера с пакетом @ai-sdk/openai-compatible (им OpenCode разговаривает с /chat/completions), именем для интерфейса, адресом и списком моделей:
Идентификаторы в
GET /api/v1/models часто содержат слэш — это формата группа/имя. OpenCode такой формат поддерживает: полная ссылка на такую модель состоит из трёх сегментов, <провайдер>/<группа>/<имя>. Ничего обрезать и переписывать не нужно.Сгенерировать файл из каталога
Ручной ввод списка моделей — это ровно то место, где в конфиг попадает устаревший идентификатор. Соберите секциюprovider напрямую из ответа API:
cURL
Модель по умолчанию
Чтобы не выбирать модель в диалоге каждый раз, задайте её в корне конфига:small_model — отдельная модель для служебных задач вроде генерации заголовка сессии. По умолчанию OpenCode пробует взять более дешёвую модель того же провайдера, а если её нет — основную.
Ключ двумя способами
Способ 1, рекомендуемый: команда/connect в TUI, пункт Other, идентификатор провайдера speshu, затем вставьте ключ. OpenCode сохранит его в ~/.local/share/opencode/auth.json, и в opencode.json поле options.apiKey можно убрать.
Способ 2: оставить ключ в конфиге через {env:SPESHU_API_KEY} — как в примере выше. Переменная должна быть в окружении того процесса, который запускает opencode.
Первый запрос и проверка
Запустите OpenCode в корне проекта и выберите модель командой/models: провайдер SpeShu.AI должен появиться в списке, иначе конфиг не прочитан.
1
Ключ виден OpenCode
В TUI выполните:В списке должен быть провайдер
speshu. Если его нет — команда /connect не была пройдена, а ключ не пришёл ни из auth.json, ни из {env:SPESHU_API_KEY}.2
Конфиг сошёлся
speshu с вашим baseURL и непустым ключом. Пустой ключ означает незаданную переменную окружения: подстановка {env:...} молча даёт пустую строку.3
Модель отвечает
Однострочный запуск без TUI — самый честный тест:В ответе должен появиться текст модели. Расход за этот вызов виден в
usage.cost.total_cost в ответе API и списывается с кошелька в рублях — об этом подробнее в разделе Тарификация и оплата.opencode run годится и для CI: та же команда с ключом в переменной окружения даёт неинтерактивный вызов модели. Учтите, что агент по умолчанию может править файлы и выполнять команды — ограничьте это секцией permission или укажите агента plan.Таймауты
По умолчанию OpenCode ждёт ответ 300 секунд — ровно столько же, сколько потолок запроса к/api/v1. В этом случае ошибку получит клиент, а генерация всё равно будет оплачена. Поднимите лимит в миллисекундах в options провайдера:
timeout — весь запрос, chunkTimeout — пауза между двумя соседними частями потока. Значение false снимает таймаут совсем; на агентных длинных задачах это иногда разумнее, чем подбирать число.
Потоковая передача
Отдельных настроек не нужно: OpenCode работает через AI SDK, который читает ответ инкрементально, и SpeShu.AI отдаёт поток в обычном формате SSE. Текст появляется в TUI по мере генерации. Два момента, о которых стоит знать:- Стоимость приходит в последнем кадре потока вместе с
usage, а не отдельным вызовом. Разбор кадров и момент списания — на странице Потоковая передача. - Ошибка приходит внутри потока, а не HTTP-статусом, и поток после неё обрывается без маркера
[DONE]. Если OpenCode подвис на середине ответа — скорее всего, это такой случай, а не зависшая сеть.
Инструменты
OpenCode передаёт модели набор своих инструментов — чтение и запись файлов, поиск, выполнение команд — через обычный параметрtools запроса /chat/completions. Ничего настраивать не нужно: если модель поддерживает вызов функций, агент будет ими пользоваться.
Изображения
OpenCode умеет прикреплять изображения к сообщению — перетащите файл в терминал. Перед отправкой OpenCode приводит картинку к base64 и ужимает её, если она больше порога по умолчанию (2000×2000 пикселей или около 5 МБ). Порог меняется в секцииattachment.image конфига.
Дальше работает обычная схема медиаввода: блок image_url в сообщении, модель должна принимать зрение. Требования к формату, base64 и ссылкам — в гайде Медиаввод.
Про векторный поиск
Частые проблемы
Провайдера нет в списке /models
Провайдера нет в списке /models
OpenCode не опрашивает
/api/v1/models сам: без секции models в provider.speshu в списке не появится ничего. Проверьте, что файл лежит в корне проекта или в ~/.config/opencode/, а имя — opencode.json или opencode.jsonc. Дальше — opencode debug config и поиск speshu в выводе.401 invalid_api_key при верном ключе
401 invalid_api_key при верном ключе
Ключ не подставился. Проверьте
opencode auth list: если провайдера там нет, а в конфиге стоит {env:SPESHU_API_KEY}, значит переменная не была в окружении при запуске — подстановка молча даёт пустую строку. Передайте её явно: SPESHU_API_KEY="sk-ваш-ключ" opencode. Диагностика ключа — в разделе Аутентификация.404 на любом запросе
404 на любом запросе
Проверьте адрес в
options.baseURL. Верное значение — https://speshu.ai/api/v1; без /v1 и с завершающим слэшем адрес уходит не туда, и при верных ключе и модели прилетает 404. Разбор адресов — в разделе Введение в API.404 model_not_found на модели, которая есть в каталоге
404 model_not_found на модели, которая есть в каталоге
Идентификатор в секции
models разошёлся с каталогом: OpenCode отправляет в API ровно тот ключ, что записан в конфиге. Перегенерируйте секцию командой выше и перезапустите OpenCode. Почему список устаревает молча — в разделе Модели и цены.Агент отвечает текстом, но файлы не меняет
Агент отвечает текстом, но файлы не меняет
Скорее всего, модель не возвращает
tool_calls — она не поддерживает вызов функций или он у неё отключён. Проверьте это пробным промптом и возьмите другую модель из каталога. Если дело не в модели, посмотрите секцию permission и tools конфига: там вход и запись файлов можно закрыть.422 content_too_large на длинной сессии
422 content_too_large на длинной сессии
Вход плюс зарезервированный выход не поместился в окно модели. Задайте
limit.context по фактическому context_length из каталога — иначе OpenCode неверно считает остаток контекста — либо включите автосжатие сессии: {"compaction": {"auto": true, "reserved": 10000}}. Ошибка не лечится повтором, подробности — в разделе Ошибки.Что дальше
Модели и цены
Каталог, окно контекста, стоимость
Начало работы
Полный маршрут от ключа до медиа-задачи
Вызов функций
Как устроен вызов инструментов
Потоковая передача
Кадры SSE и момент списания
