Search by

butochnikov / typesafe-sdk-php

Butochnikov

PHP client for TypeSafe AI System One with typed questions, synchronous and asynchronous requests.

Package info

github.com/Butochnikov/typesafe-sdk-php

Documentation

pkg:composer/butochnikov/typesafe-sdk-php

Statistics

Installs: 17

Dependents: 1

Suggesters: 0

Stars: 0

Open Issues: 0

v0.1.0 2026-09-17 02:48 UTC

This package is auto-updated.

Last update: 2026-09-17 03:28:20 UTC


README

Русская версия документации

PHP client for the TypeSafe AI System One API. Ask yes/no questions, select categories, and score text or structured data with typed responses.

Community-maintained and unofficial; this package is not affiliated with TypeSafe AI.

  • Noul, Choice and Score questions with typed answers and probabilities.
  • Synchronous calls and asynchronous requests through Guzzle promises.
  • Model discovery, configurable retries and timeouts, and PSR-3 logging.

Requirements

  • PHP 8.2 or later in the PHP 8 series.
  • PHP cURL and JSON extensions.
  • Composer 2 and a TypeSafe API key for live requests.

Install

composer require butochnikov/typesafe-sdk-php:^0.1

This command requires a release indexed on Packagist. To use the source before publication, see local installation.

Set your API key in the environment:

export TYPESAFE_API_KEY='your-api-key'

The SDK reads environment variables directly; it does not load .env files.

Synchronous use

<?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();
}

Noul returns the probability of a yes answer, not a boolean. Score returns an expected score on a zero-based rubric and can be fractional. With an open client, you can also pass raw question arrays containing additional API fields:

$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']],
]);

Async and concurrency

AsyncTypeSafeClient returns a GuzzleHttp\Promise\PromiseInterface that resolves to a typed response.

<?php

use TypeSafe\{AsyncTypeSafeClient, Noul};

require __DIR__ . '/vendor/autoload.php';

$client = new AsyncTypeSafeClient();
try {
    $a = $client->models->list();
    $b = $client->systemOne('text', ['q' => new Noul(instructions: 'Relevant?')]);
    [$models, $answers] = [$a->wait(), $b->wait()];
} finally {
    $client->close();
}

Guzzle/cURL can keep several operations in flight. A promise supports then(), rejection handlers, wait(), and cancel(). Closing the async client cancels pending operations and is idempotent.

Models and configuration

$client->models->list() returns ListModelsResponse; model cards expose name, description, and releaseDate. Defaults are https://api.typesafe.ai, jev-latest, and 10 seconds. Explicit constructor/per-call values take precedence over these environment variables:

TYPESAFE_API_KEY, TYPESAFE_BASE_URL, TYPESAFE_DEFAULT_MODEL, and TYPESAFE_LOG_LEVEL (debug, info, warn/warning, error, off). Empty environment values are ignored. Never put an API key in source control.

extraBody is a shallow, last-write-wins merge and may replace state, model, or questions. extraHeaders is similarly per call, but authentication and SDK identity headers are protected. Timeout can explicitly request unlimited total time (new Timeout(null)) and optionally configure connect/read settings. Guzzle has no exact HTTPX write/pool timeout equivalent; read handling depends on the selected handler.

Retries and errors

RetryPolicy defaults to two retries for 408, 429, and 5xx responses, API connection errors, and timeouts. It supports maxRetries, backoffInitial, backoffMax, backoffJitter, httpStatuses, respectRetryAfter, apiConnectionError, apiTimeoutError, exceptions, predicate, and a per-call timeout budget. A per-call policy does not mutate client state. API failures are mapped to TypeSafeBadRequestError, TypeSafeAuthenticationError, TypeSafePermissionDeniedError, TypeSafeNotFoundError, TypeSafeUnprocessableEntityError, TypeSafeRateLimitError, and TypeSafeInternalServerError, all derived from TypeSafeError. Network failures are TypeSafeAPIConnectionError or TypeSafeAPITimeoutError.

Successful responses expose typed DTOs and $response->answers. requestId and rawHttpResponse are available after parsing a raw response; accessing absent metadata throws TypeSafeError. DTO serialization contains only wire fields and preserves JSON objects versus arrays.

Logging and custom transport

Pass any PSR-3 LoggerInterface as logger:. The SDK uses NullLogger by default and does not configure global handlers. Debug logs include wire headers/body; info logs include method, sanitized URL, status, duration, request id, and retry. Header values for authorization, cookies, API keys, token/secret names, and proxy authorization are replaced with ***. Request/response bodies are deliberately not redacted, matching upstream behavior.

transport: accepts a Guzzle handler or HandlerStack; httpClient: accepts a Guzzle ClientInterface. They are mutually exclusive. Injected middleware, ordinary headers, proxy, and TLS settings are retained, while SDK requests use an absolute URL, auth => null, http_errors => false, and disabled redirects. Implement CloseableTransportInterface or CloseableHttpClientInterface when an application-owned resource needs explicit close handling.

Development

composer validate --strict
composer install --no-interaction
composer test
composer analyse
composer check

The default suite is offline and covers selected SDK contracts. Live API compatibility and exhaustive equivalence with the Python SDK have not been verified. Files in examples/ make live requests when executed; Composer autoload does not run them.

Compatibility and versioning

Version 0.1.0 is the initial PHP release, based on the Python SDK 0.6.0. The two packages have independent version numbers. See the compatibility notes for the upstream revision and PHP-specific behavior.

During 0.x development, breaking changes will increment the minor version; compatible fixes will increment the patch version. Use ^0.1 to stay on the 0.1.x series. Changes are recorded in CHANGELOG.md. See the publishing guide for the release process.

Contributing

Include a focused test with bug fixes or behavior changes and run composer check before submitting a pull request. Report SDK issues in this repository; use TypeSafe's documentation for service and API guidance.

License

Licensed under the MIT License. Upstream attribution and the original license are preserved in THIRD_PARTY_NOTICES.md.