TypeSafe AI SDK для PHP
September 17, 2026 · View on GitHub
PHP-клиент API System One от TypeSafe AI. Позволяет задавать вопросы «да/нет», выбирать категории и оценивать текст или структурированные данные, получая типизированные ответы.
Неофициальный пакет, поддерживаемый сообществом и не связанный с компанией TypeSafe AI.
- Вопросы
Noul,ChoiceиScore, типизированные ответы и вероятности. - Синхронные и асинхронные запросы через Guzzle promises.
- Список моделей, настраиваемые повторы, таймауты и PSR-3 логирование.
Требования
- PHP 8.2 или новее в пределах PHP 8.
- Расширения PHP cURL и JSON.
- Composer 2 и API key TypeSafe для реальных запросов.
Установка
composer require butochnikov/typesafe-sdk-php:^0.1
Эта команда требует релиза, добавленного в Packagist. До публикации используйте локальную установку.
Задайте ключ в окружении:
export TYPESAFE_API_KEY='ваш-ключ'
SDK читает переменные окружения напрямую и не загружает .env автоматически.
Синхронное использование
<?php
use TypeSafe\{Choice, Noul, Score, TypeSafeClient};
require __DIR__ . '/vendor/autoload.php';
$client = new TypeSafeClient();
try {
$result = $client->systemOne(
state: ['document' => 'I was charged twice. Please help ASAP.'],
questions: [
'billing' => new Noul(instructions: 'Is this about billing?'),
'tone' => new Choice(criteria: ['calm' => null, 'angry' => null], instructions: 'Tone?'),
'urgency' => new Score(criteria: ['low', 'medium', 'high'], instructions: 'Urgency?'),
],
);
echo $result->choices['tone']->choice . PHP_EOL;
echo $result->nouls['billing']->noul . PHP_EOL;
echo $result->scores['urgency']->score . PHP_EOL;
} finally {
$client->close();
}
В SDK есть три примитива:
Noul— вероятность ответа «да», а не boolean;Choice— выбор одного из именованных вариантов;Score— ожидаемая оценка по упорядоченной шкале с нуля; она может быть дробной.
Открытому клиенту можно передавать и обычные ассоциативные массивы вопросов. Это позволяет использовать дополнительные поля API:
$result = $client->systemOne('a support ticket', [
'is_billing' => ['type' => 'noul', 'instructions' => 'Billing?'],
'tone' => ['type' => 'choice', 'criteria' => ['calm' => null, 'angry' => null]],
'priority' => ['type' => 'score', 'criteria' => ['low', 'high']],
]);
Асинхронность и параллельные запросы
AsyncTypeSafeClient возвращает GuzzleHttp\Promise\PromiseInterface, который разрешается типизированным ответом.
<?php
use TypeSafe\{AsyncTypeSafeClient, Noul};
require __DIR__ . '/vendor/autoload.php';
$client = new AsyncTypeSafeClient();
try {
$models = $client->models->list();
$answers = $client->systemOne('text', [
'q' => new Noul(instructions: 'Relevant?'),
]);
[$models, $answers] = [$models->wait(), $answers->wait()];
} finally {
$client->close();
}
Guzzle/cURL может выполнять несколько запросов одновременно. Promise поддерживает then(), обработчики ошибок, wait() и cancel(). Закрытие async-клиента отменяет ожидающие операции и безопасно при повторном вызове.
Модели и конфигурация
$client->models->list() возвращает ListModelsResponse. Карточки моделей содержат поля name, description и releaseDate.
Значения по умолчанию:
- URL API:
https://api.typesafe.ai; - модель:
jev-latest; - timeout HTTP-запроса: 10 секунд.
Явные значения конструктора и параметры конкретного вызова имеют приоритет над переменными окружения:
TYPESAFE_API_KEY;TYPESAFE_BASE_URL;TYPESAFE_DEFAULT_MODEL;TYPESAFE_LOG_LEVEL(debug,info,warn/warning,error,off).
Пустые и состоящие только из пробелов значения окружения игнорируются. Не храните API key в исходном коде или репозитории.
extraBody объединяется поверх стандартного тела запроса неглубоко, по принципу last-write-wins, и может заменить state, model или questions. extraHeaders действует только для конкретного вызова; заголовки авторизации и идентификации SDK защищены.
Для явного отключения общего ограничения времени используйте new Timeout(null). Объект Timeout также позволяет задать connect/read timeout. У Guzzle нет полного аналога фазовых timeout HTTPX для write/pool; поведение read timeout зависит от выбранного handler.
Повторные попытки и ошибки
По умолчанию RetryPolicy выполняет до двух повторных попыток для ответов 408, 429 и 5xx, сетевых ошибок и timeout. Доступны параметры maxRetries, backoffInitial, backoffMax, backoffJitter, httpStatuses, respectRetryAfter, apiConnectionError, apiTimeoutError, exceptions, predicate и общий budget timeout.
Политика, заданная для отдельного вызова, не изменяет настройки клиента.
Ошибки API преобразуются в следующие исключения:
TypeSafeBadRequestError, TypeSafeAuthenticationError, TypeSafePermissionDeniedError, TypeSafeNotFoundError, TypeSafeUnprocessableEntityError, TypeSafeRateLimitError и TypeSafeInternalServerError. Все они наследуют TypeSafeError. Сетевые ошибки представлены TypeSafeAPIConnectionError и TypeSafeAPITimeoutError.
Успешные ответы содержат типизированные DTO и доступны через $response->answers. Свойства requestId и rawHttpResponse доступны у ответа, созданного из HTTP-ответа; при отсутствии метаданных обращение к ним выбрасывает TypeSafeError. Сериализация DTO включает только wire-поля и сохраняет различие между JSON-объектами и массивами.
Логирование и собственный transport
Передайте любой PSR-3 LoggerInterface через параметр logger:. По умолчанию используется NullLogger; глобальное логирование приложения SDK не настраивает.
Debug-логи содержат wire-заголовки и body. Info-логи содержат метод, очищенный URL, статус, длительность, request id и номер retry. Значения заголовков авторизации, cookies, API keys, proxy authorization, а также заголовков с token или secret заменяются на ***.
Тела запросов и ответов намеренно не редактируются, как и в upstream SDK.
Параметр transport: принимает Guzzle handler или HandlerStack, а httpClient: — Guzzle ClientInterface. Эти параметры взаимоисключающие. Подключённые middleware, обычные headers, proxy и TLS-настройки сохраняются. SDK использует абсолютный URL, auth => null, http_errors => false и отключённые редиректы.
Если приложению нужно явно закрывать пользовательский ресурс, реализуйте CloseableTransportInterface или CloseableHttpClientInterface.
Разработка
composer validate --strict
composer install --no-interaction
composer test
composer analyse
composer check
Стандартный набор тестов работает без сети и проверяет отдельные контракты SDK. Совместимость с реальным API и полное соответствие Python SDK пока не проверены. Скрипты в examples/ выполняют реальные запросы при запуске; Composer autoload их не запускает.
Совместимость и версии
0.1.0 — первый релиз PHP-пакета на основе Python SDK 0.6.0. Версии этих пакетов независимы. Исходный commit и отличия PHP перечислены в таблице совместимости.
В серии 0.x несовместимые изменения будут повышать minor-версию, совместимые исправления — patch-версию. Ограничение ^0.1 оставляет приложение на серии 0.1.x. Изменения описываются в CHANGELOG.md, порядок выпуска — в инструкции по публикации.
Участие в разработке
К исправлениям ошибок и изменениям поведения добавляйте тест и выполняйте composer check перед отправкой pull request. Ошибки SDK обсуждаются в этом репозитории; вопросы использования сервиса — в документации TypeSafe.
Лицензия
MIT. Атрибуция Python SDK и его исходная лицензия сохранены в THIRD_PARTY_NOTICES.md.