Перейти к основному содержанию
OpenCode — терминальный агент для работы с кодом: он читает проект, редактирует файлы, выполняет команды и ведёт диалог по шагам. Провайдера он берёт из каталога моделей и из конфигурации, поэтому подключение к SpeShu.AI сводится к описанию одного OpenAI-совместимого провайдера — адреса шлюза, ключа и списка моделей.
От OpenCode нужны ровно два значения: baseURL = https://speshu.ai/api/v1 и API-ключ. /api/v1/chat/completions совместим с OpenAI Chat Completions, поэтому в код или настройки самого агента ничего вносить не нужно. Ключ создаётся на speshu.ai/profile, подробности — в разделе Аутентификация.

Ключ и идентификатор модели

Получите ключ и положите его в переменную окружения:
Проверьте, что ключ принят — запрос баланса не стоит токенов:
cURL
Теперь возьмите идентификатор модели из каталога:
cURL
Идентификаторы текстовых моделей не зашивайте в код: состав каталога меняется, модели переименовываются и отключаются, а зашитый в конфиг идентификатор начинает падать с 404 model_not_found без предупреждения. В OpenCode это особенно заметно — список моделей провайдера хранится в конфиге, а не подтягивается автоматически, и потому молча устаревает.
Ниже $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
В сгенерированном файле стоит "{env:SPESHU_API_KEY}", а не сам ключ — файл можно коммитить. Перезапустите генерацию вручную, когда увидите 404 model_not_found в списке моделей: это сигнал, что каталог разошёлся с конфигом.

Модель по умолчанию

Чтобы не выбирать модель в диалоге каждый раз, задайте её в корне конфига:
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 реальную задачу, убедитесь на пробном промпте, что модель возвращает tool_calls. Формат вызова и разбор аргументов — в гайде Вызов функций.

Изображения

OpenCode умеет прикреплять изображения к сообщению — перетащите файл в терминал. Перед отправкой OpenCode приводит картинку к base64 и ужимает её, если она больше порога по умолчанию (2000×2000 пикселей или около 5 МБ). Порог меняется в секции attachment.image конфига. Дальше работает обычная схема медиаввода: блок image_url в сообщении, модель должна принимать зрение. Требования к формату, base64 и ссылкам — в гайде Медиаввод.
Генерацию изображений, видео и музыки OpenCode не делает: таких инструментов у него нет. Медиа-задачи создаются прямым вызовом API — оплата при создании, результат по опросу. Формат конверта — в разделе Создать задачу.

Про векторный поиск

Эндпоинта эмбеддингов у SpeShu.AI нет: /embeddings в /api/v1 не существует. Собственный поиск по проекту в OpenCode эмбеддингов не использует — он опирается на поиск по файлам и LSP, так что базовая работа агента от этого не страдает. Но если вы добавите свой инструмент, MCP-сервер или плагин, которому нужен векторный индекс, его придётся увести на другого провайдера отдельной конфигурацией: заменить эндпоинт нечем, такой вызов вернёт 404.

Частые проблемы

OpenCode не опрашивает /api/v1/models сам: без секции models в provider.speshu в списке не появится ничего. Проверьте, что файл лежит в корне проекта или в ~/.config/opencode/, а имя — opencode.json или opencode.jsonc. Дальше — opencode debug config и поиск speshu в выводе.
Ключ не подставился. Проверьте opencode auth list: если провайдера там нет, а в конфиге стоит {env:SPESHU_API_KEY}, значит переменная не была в окружении при запуске — подстановка молча даёт пустую строку. Передайте её явно: SPESHU_API_KEY="sk-ваш-ключ" opencode. Диагностика ключа — в разделе Аутентификация.
Проверьте адрес в options.baseURL. Верное значение — https://speshu.ai/api/v1; без /v1 и с завершающим слэшем адрес уходит не туда, и при верных ключе и модели прилетает 404. Разбор адресов — в разделе Введение в API.
Идентификатор в секции models разошёлся с каталогом: OpenCode отправляет в API ровно тот ключ, что записан в конфиге. Перегенерируйте секцию командой выше и перезапустите OpenCode. Почему список устаревает молча — в разделе Модели и цены.
Скорее всего, модель не возвращает tool_calls — она не поддерживает вызов функций или он у неё отключён. Проверьте это пробным промптом и возьмите другую модель из каталога. Если дело не в модели, посмотрите секцию permission и tools конфига: там вход и запись файлов можно закрыть.
Вход плюс зарезервированный выход не поместился в окно модели. Задайте limit.context по фактическому context_length из каталога — иначе OpenCode неверно считает остаток контекста — либо включите автосжатие сессии: {"compaction": {"auto": true, "reserved": 10000}}. Ошибка не лечится повтором, подробности — в разделе Ошибки.
Полная таблица кодов, три формата ошибок и цикл повторов — на странице Ошибки, таймауты и квоты — в разделе Лимиты.

Что дальше

Модели и цены

Каталог, окно контекста, стоимость

Начало работы

Полный маршрут от ключа до медиа-задачи

Вызов функций

Как устроен вызов инструментов

Потоковая передача

Кадры SSE и момент списания