SOVREGAI ECONOMY

Платформа разрабатывается

ДОКУМЕНТАЦИЯ API

Интерфейс, который уже существует.

Справочник закрытого Gateway в backend версии 0.4.0. Для примеров нужна разрешённая закрытая среда и Bearer-ключ с необходимыми scopes. Сам сайт эти маршруты не вызывает.

Платформа разрабатываетсяНА ЭТОЙ СТРАНИЦЕ

Авторизация и доступ

Передавайте Bearer-ключ в заголовке Authorization. Оба маршрута каталога требуют models:read, оценка — usage:estimate. Учётные данные ограничены по правам и сроку и могут быть отозваны. Не помещайте ключ в URL или код браузера.

Три реализованных маршрута

Сейчас включена модель mock-extractive-v1. Её описание содержит provider_id, model_id, capabilities, limits и simulated. Возможность text.generate относится к адаптеру и не означает наличия публичного маршрута выполнения.

Справочник Gateway
МаршрутНеобходимый scope
GET/api/v1/modelsmodels:read
GET/api/v1/models/{model_id}models:read
POST/api/v1/models/{model_id}/estimateusage:estimate

Получить каталог и оценить расход

Пример Python использует стандартную библиотеку. SOVREG_API_BASE должен указывать на ваш разрешённый закрытый API, SOVREG_API_TOKEN — содержать ключ с нужными scopes. Это переменные среды оператора; сайт не просит их вводить.

Python · существующий закрытый API
import json
import os
from urllib.error import HTTPError, URLError
from urllib.request import Request, urlopen

# Use only an authorised private API and a scoped credential.
base = os.environ["SOVREG_API_BASE"].rstrip("/")
token = os.environ["SOVREG_API_TOKEN"]

def request(path, payload=None):
    data = None if payload is None else json.dumps(payload).encode("utf-8")
    req = Request(
        base + path,
        data=data,
        headers={
            "Authorization": "Bearer " + token,
            "Content-Type": "application/json",
        },
    )
    try:
        with urlopen(req, timeout=10) as response:
            return json.load(response)
    except HTTPError as error:
        raise RuntimeError(f"API returned HTTP {error.code}") from None
    except (URLError, TimeoutError):
        raise RuntimeError("Private API is unavailable") from None

catalogue = request("/api/v1/models")
print([item["model_id"] for item in catalogue["items"]])

estimate = request(
    "/api/v1/models/mock-extractive-v1/estimate",
    {"text": "First second third", "max_output_tokens": 2},
)
assert estimate["financial_quote"] is False
assert estimate["estimate"]["simulated"] is True
print(estimate["estimate"])

Оценка расхода не является котировкой

POST принимает text и max_output_tokens. Ответ содержит верхнюю границу условного расхода по словам и financial_quote=false. Он не создаёт резюме и не резервирует, не выпускает и не списывает кредиты.

  • text: непустой текст, не более 8192 UTF-8 байтов и 2048 слов, разделённых пробелами.
  • max_output_tokens: целое число от 1 до 256, по умолчанию 64. Логические, дробные значения и лишние поля отклоняются.
  • Общий предел тела API — 16 KiB. Экранирование JSON может достичь его раньше предела текста.
  • Оценка — читающая операция без Idempotency-Key. Авторизованный вызов всё равно создаёт безопасную запись аудита.
Запрос оценки
{
  "text": "First second third",
  "max_output_tokens": 2
}
Пример ответа по текущему интерфейсу
{
  "model_id": "mock-extractive-v1",
  "estimate": {
    "input_tokens_upper_bound": 3,
    "output_tokens_cap": 2,
    "additional_cost_cap": "0",
    "estimation_method": "mock_whitespace_words",
    "simulated": true
  },
  "financial_quote": false
}

Обрабатывайте ошибки явно

Не подменяйте ошибку или неизвестную оценку нулевым расходом. Ошибка авторизации может содержать только detail: поле доменного code есть не у каждого ответа.

401
Учётные данные отсутствуют, недействительны или просрочены.
403
У ключа нет необходимого разрешения scope.
404
Запрошенной модели нет во включённом каталоге.
411
Для изменяющего HTTP-метода нужен Content-Length; Node fetch выставляет его для JSON-тела.
413
JSON-тело превышает общий предел 16 KiB.
422
Неверные поля, типы или превышение ограничений входа.
429
Достигнут лимит частоты запросов API.
503
Закрытый сервис или его база данных недоступны.

Типизированный клиент для закрытого серверного кода

В репозитории есть адаптер трёх описанных маршрутов только для Node.js. Ему явно передаются адрес API и источник ограниченного ключа; публичный сайт его не импортирует и не активирует.

  • listModels, getModel и estimateUsage проверяют ответы по текущему контракту Gateway.
  • Дедлайн и AbortSignal охватывают получение ключа, транспорт и чтение ответа. Автоматических повторов нет.
  • GatewayClientError содержит нормализованный код и, если доступны, HTTP-статус, ID запроса и Retry-After в секундах. Ключи, исходный текст и тела ошибок сервера в нём не сохраняются.
  • Адаптер не реализует публичную авторизацию пользователей, вычисления, платежи или финансовую котировку.
TypeScript · закрытая интеграция Node.js
// Trusted Node.js code in a private application, never a browser component.
import {
  createPrivateGatewayClient,
  GatewayClientError,
} from "@/lib/private-gateway/client";

const baseUrl = process.env.SOVREG_API_BASE;
if (!baseUrl) throw new Error("Private API origin is not configured");

const client = createPrivateGatewayClient({
  baseUrl,
  timeoutMs: 5000,
  getCredential: () => {
    const value = process.env.SOVREG_API_TOKEN;
    if (!value) throw new Error("Scoped credential is unavailable");
    return value;
  },
});

try {
  const catalogue = await client.listModels();
  const model = await client.getModel("mock-extractive-v1");
  const result = await client.estimateUsage(model.model_id, {
    text: "First second third",
    max_output_tokens: 2,
  });
  // result.financial_quote is false; result.estimate.simulated is true.
  console.log(catalogue.items.length, result.estimate.input_tokens_upper_bound);
} catch (error) {
  if (error instanceof GatewayClientError) {
    // Only normalised fields, never credentials, prompt or raw response.
    console.error(error.code, error.status);
  } else {
    throw error;
  }
}
Состояние разработки