Download the PHP package sitehostnz/sthai without Composer
On this page you can find all versions of the php package sitehostnz/sthai. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download sitehostnz/sthai
More information about sitehostnz/sthai
Files in sitehostnz/sthai
Package sthai
Short Description PHP client for the SiteHost AI Platform: inference, embeddings and reranking
License MIT
Informations about the package sthai
sthai-php
A PHP client for the SiteHost AI Platform: inference, embeddings and reranking, with no runtime dependencies beyond ext-curl and ext-json. A port of the Python client, sthai-py, matching its functionality and wire format.
The SiteHost AI Platform
The SiteHost AI Platform serves capable open-weight models at their full context windows - not heavily quantised cut-downs - with full control over system prompts and outputs. Everything runs on SiteHost's own hardware in their own New Zealand data centres, so your data never leaves the country, and request bodies are never stored: only usage metrics are kept for billing and performance monitoring.
Models are stable targets, too: each served model has a minimum one-year retention window and at least three months' deprecation notice, with guidance on any adjustments needed.
The platform currently serves three models, one per capability (see the models page for the source of truth):
| Model | Purpose | Context window |
|---|---|---|
Qwen/Qwen3.6-27B |
Inference (chat, multimodal, thinking) | 262K |
Qwen/Qwen3-VL-Embedding-8B |
Embeddings (multimodal, Matryoshka, 4096 dims) | 32K |
Qwen/Qwen3-VL-Reranker-8B |
Reranking (multimodal, instruction-trained) | 32K |
Installation
Requires PHP 7.4 or newer with ext-curl and ext-json. Install via Composer:
On PHP 8.0+ every optional parameter can be passed as a named argument, which the examples below use. On PHP 7.4 pass them positionally.
Getting started
Create an API key in the SiteHost Control Panel (see API keys). The client reads it from the STHAI_KEY environment variable, or you can pass it explicitly:
Usage
Chat and history
chat() keeps a conversation going: each successful call appends the user and assistant turns to the client's history, and later calls send it back. The system prompt is applied per call rather than stored.
The stored history can be read with history() and restored with setHistory(), so a conversation can be persisted and picked up later. setWriteHistory(false) stops chat() recording new turns (the stored history is kept and still sent); writeHistory() reads the current setting.
historyUsage() totals token usage across the calls that built the stored history. Each call resends the conversation so far, so input tokens count what the server processed (as billed), not unique tokens. clearHistory() and setHistory() reset the tally along with the turns it covered.
Thinking models can reason before answering; the reasoning rides along on the response:
Images
Chat and embedding inputs can include images, given as URLs or local files (PNG, JPEG, GIF or WEBP - files are inlined as data URIs):
Raw image bytes can be converted with SthAI\Image::dataUriFromBytes($bytes) and passed via imageUrls (a data URI is a URL).
One-off and structured responses
response() mirrors chat() without the back-and-forth: the stored history is neither sent nor updated. structuredResponse() adds structured output - pass a JSON schema as a PHP array and the server enforces it during generation, with the decoded array returned:
The client does not re-validate the result against the schema. If the output is cut off by the token limit, or (rarely, with thinking enabled) the server skips the schema, parsing throws a SthAI\Exception\ResponseParseException naming the cause. A schema needing an empty JSON object value must use new \stdClass() rather than [] (which encodes as an empty array).
Embeddings
embed() turns one input - text, images, or both - into a single vector, the sole entry in the response's output(). The embedding model is instruction-trained: document embedding is the default, and query: true switches to the query instruction for search-style lookups. dimensions truncates the vector server-side (Matryoshka - powers of two work best):
batchEmbed() embeds many texts in one request; the response's output() is one vector per text in order:
Reranking
rerank() scores each document against a query; output() on the response is the results sorted by relevance, with each result's index mapping back to your input list:
Pass instruction: to steer relevance for a specific task; the model applies a sensible default otherwise.
Response helpers
Every inference, embedding and rerank call returns the full response object, and every response object has usage() (input/output/cached token counts) and output() (the useful payload), with toArray() exposing the complete decoded payload:
The one exception is structuredResponse(), which returns the decoded array directly; the full response from the most recent inference call remains available via lastResponse():
Sessions
Pinning requests to a server session keeps routing consistent and helps caching. Pass sessionPin: with your own identifier, or let the client generate one:
Models and health
Errors
Everything the library throws implements SthAI\Exception\SthAIException, so catching it is enough to handle anything the client can throw:
ClientException (4xx) and ApiException (5xx) both extend ApiStatusException, which carries getStatusCode(), getResponseBody(), getServerMessage() and getErrorType() (parsed from the server's error body when present). ResponseParseException, thrown by structuredResponse()'s parsing, extends ResponseException.
Development
The test suite runs entirely offline against fixtures captured from the live API (shared with sthai-py):
Licence
MIT
All versions of sthai with dependencies
ext-curl Version *
ext-json Version *