enВойти в Senler

API SDK

Что это

@aisenler/sdk-fetch — типизированный клиент публичного API Senler AI. Он генерируется из OpenAPI-спецификации и предоставляет класс AiSenlerClient, модели ответов и отдельные группы методов, например client.projects, client.agents и client.apps.

SDK предназначен прежде всего для серверных интеграций. Он также работает в окружении с глобальным fetch, но произвольный внешний сайт не сможет обращаться к production API, если его origin не разрешён политикой CORS. Проектный API-ключ и Client Secret нельзя помещать в браузерный код.

Установка

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

npm install github:SenlerBot/Senler-io-sdk#v0.1.16

Пакет требует Node.js 18+ и содержит TypeScript-декларации. Фиксированный тег нужен, чтобы новая генерация SDK не изменила контракт во время следующей установки зависимостей.

Авторизация

В accessToken передаётся только значение токена, без префикса Bearer. SDK сам добавляет заголовок Authorization: Bearer <token> ко всем запросам.

Поддерживаются два источника токена:

  • проектный API-ключ формата senler_sk_... — для интеграции с одним проектом;
  • OAuth access token приложения — для доступа, который пользователь выдал через OAuth.

Доступные методы определяются областью и правами токена. Пользовательский OAuth-токен дополнительно ограничен актуальными правами пользователя в целевом проекте или developer-приложении.

Первый запрос

Пример для проектного API-ключа или проектного OAuth-токена:

import { AiSenlerClient } from "@aisenler/sdk-fetch";

const client = new AiSenlerClient({
  accessToken: process.env.SENLER_API_TOKEN!,
});

const currentProject = await client.projects.getMe();

const agents = await client.agents.list({
  projectId: currentProject.project.id,
  limit: 20,
});

Внешней интеграции не нужен X-Session-Id: этот заголовок относится к сессии кабинета и не входит в параметры сгенерированных методов SDK.

Методы и типы

Группа клиента соответствует разделу API, а метод — операции из публичной OpenAPI-спецификации. Например:

  • client.projects — проекты;
  • client.agents — агенты;
  • client.dialogsMessaging — сообщения в диалогах;
  • client.apps — developer-приложения;
  • client.appDocumentation — документация developer-приложений.

Это примеры, а не полный каталог. Актуальные группы и сигнатуры доступны в TypeScript-подсказках установленной версии SDK, а назначение endpoint, обязательные параметры и права — в справочнике API.

Параметры метода передаются одним объектом в camelCase. SDK сам преобразует имена полей в формат JSON API и преобразует ответ в типизированную модель. Например, idempotencyKey отправляется как idempotency_key. Если обязательный параметр пропущен, TypeScript сообщает об этом при сборке, а runtime-проверка выбрасывает RequiredError.

Начиная с v0.1.15 единое обновление developer-приложения разделено по назначению. Вместо прежнего client.apps.appsUpdate используйте client.apps.updateGeneralSettings для названия, описания и сайта, client.apps.updateToolsSettings для инструментов агента и client.apps.updateEmbeddedPageSettings для встроенной страницы. Каждый метод принимает только поля своего раздела, поэтому изменение одной формы не перезаписывает соседние настройки.

В объектах доступных моделей поле supported_server_binding_modes содержит режимы MCP, совместимые с моделью и её активными подключениями к провайдерам. Используйте это поле при выборе модели для агента, а не фиксированный список совместимости на стороне интеграции.

Контракт действий приложения

В v0.1.16 пакет получил отдельные точки входа для действий приложения. Общие типы, сборщик метаданных и проверка OpenAPI доступны из @aisenler/sdk-fetch/app-actions, а декораторы NestJS — из @aisenler/sdk-fetch/app-actions/nest. NestJS остаётся необязательной peer-зависимостью и не загружается основным клиентом SDK.

После генерации OpenAPI проверьте файл или доступный URL той же версией пакета:

npx senler-app validate-openapi ./openapi.json

Команда перечисляет ошибки контракта x-senler-app-action, завершается с ненулевым кодом при ошибке и подходит для CI. Подробный порядок, поддерживаемые контексты и пример декоратора приведены в инструкции по действиям приложения.

Настройка клиента

Конструктор поддерживает следующие параметры:

  • accessToken — обязательный API-ключ или OAuth access token;
  • baseUrl — адрес API, по умолчанию https://api.senler.io; переопределение обычно нужно только для разработки и тестов;
  • fetchApi — собственная реализация fetch, если её требует runtime или тест.

Если токен обновляется вне SDK, замените его перед следующим запросом:

client.accessToken = newAccessToken;

Автоматическое обновление OAuth-токена

Автоматическое обновление предназначено для серверной OAuth-интеграции. Передайте все три значения refreshToken, clientId, clientSecret и сохраните новые токены в onTokenRefreshed:

const client = new AiSenlerClient({
  accessToken: "access_token",
  refreshToken: "refresh_token",
  clientId: "client_id",
  clientSecret: process.env.SENLER_CLIENT_SECRET!,
  onTokenRefreshed: async (newAccessToken, newRefreshToken) => {
    await saveTokensAtomically(newAccessToken, newRefreshToken);
  },
});

После ответа 401 SDK один раз вызывает POST /api/apps/oauth/token, обновляет токены, дожидается onTokenRefreshed и повторяет исходный запрос. Заранее по времени истечения токен не обновляется. Частичная конфигурация refresh-механизма не принимается TypeScript-типами.

Token endpoint заменяет refresh token после успешного обновления, поэтому сохраняйте access token и refresh token вместе. Client Secret и refresh token должны оставаться на сервере.

Ошибки

SDK экспортирует три основных класса ошибок:

  • ResponseError — API вернул неуспешный HTTP-статус; исходный Response доступен в error.response;
  • FetchError — запрос не дошёл до ответа, например из-за сетевой ошибки;
  • RequiredError — не передан обязательный параметр метода.
import {
  FetchError,
  RequiredError,
  ResponseError,
} from "@aisenler/sdk-fetch";

try {
  await client.projects.getMe();
} catch (error) {
  if (error instanceof ResponseError) {
    const details = await error.response.clone().json().catch(() => null);
    console.error(error.response.status, details);
  } else if (error instanceof RequiredError) {
    console.error("Не передан параметр:", error.field);
  } else if (error instanceof FetchError) {
    console.error("Сетевая ошибка:", error.cause);
  } else {
    throw error;
  }
}

При 401 проверьте актуальность токена; при 403 — права токена и права пользователя; при ошибке сущности — правильность projectId, ID ресурса и область доступа токена.

Справочные материалы