TypeSafe → SIE
SIE serves TypeSafe’s System One API at POST /v1/systemone. Code written
with the TypeSafe SDK runs on SIE unchanged: noul, choice and score
questions, text, object and conversation states, models.list() and the
async client. You point the SDK at SIE and name an SIE decision model.
client = TypeSafeClient(model="jev-latest")client = TypeSafeClient( api_key="sk-sie-…", base_url="https://api.superlinked.com", model="fastino/GLiNER2.5-Decide",)export TYPESAFE_BASE_URL=https://api.superlinked.comexport TYPESAFE_API_KEY=$SIE_API_KEYexport TYPESAFE_DEFAULT_MODEL=fastino/GLiNER2.5-DecideThe Python and TypeScript SDKs both read the three TYPESAFE_* variables,
so code that builds its client from the environment needs no edit at all.
The base URL is the API root: the SDK adds /v1/systemone itself.
Before
Section titled “Before”from typesafe_sdk import Choice, Noul, Score, TypeSafeClient
TICKET = "I was charged twice for my March invoice. Please refund one of the charges today."
with TypeSafeClient(model="jev-latest") as client: response = client.system_one( state=TICKET, questions={ "spam": Noul(instructions="Is this message unsolicited spam?"), "intent": Choice( instructions="What does the customer want?", criteria={ "billing": "payments, invoices or refunds", "technical": "something is broken", "other": None, }, ), "urgency": Score( instructions="How urgent is this request?", criteria=["can wait", "this week", "today"], ), }, )
print(response.nouls["spam"].noul)print(response.choices["intent"].choice)print(response.scores["urgency"].score)import { TypeSafeClient, choice, noul, score } from "@typesafe-ai/sdk";
const TICKET = "I was charged twice for my March invoice. Please refund one of the charges today.";
const client = new TypeSafeClient({ defaultModel: "jev-latest" });const { answers } = await client.systemOne({ state: TICKET, questions: { spam: noul("Is this message unsolicited spam?"), intent: choice("What does the customer want?", { billing: "payments, invoices or refunds", technical: "something is broken", other: null, }), urgency: score("How urgent is this request?", ["can wait", "this week", "today"]), },});
console.log(answers.spam.noul, answers.intent.choice, answers.urgency.score);Only the client changes. The questions and the way you read the answers stay as they are.
from typesafe_sdk import Choice, Noul, Score, TypeSafeClient
TICKET = "I was charged twice for my March invoice. Please refund one of the charges today."
with TypeSafeClient( api_key="sk-sie-…", base_url="https://api.superlinked.com", model="fastino/GLiNER2.5-Decide",) as client: response = client.system_one( state=TICKET, questions={ "spam": Noul(instructions="Is this message unsolicited spam?"), "intent": Choice( instructions="What does the customer want?", criteria={ "billing": "payments, invoices or refunds", "technical": "something is broken", "other": None, }, ), "urgency": Score( instructions="How urgent is this request?", criteria=["can wait", "this week", "today"], ), }, )
print(response.nouls["spam"].noul)print(response.choices["intent"].choice)print(response.scores["urgency"].score)import { TypeSafeClient, choice, noul, score } from "@typesafe-ai/sdk";
const TICKET = "I was charged twice for my March invoice. Please refund one of the charges today.";
const client = new TypeSafeClient({ apiKey: "sk-sie-…", baseURL: "https://api.superlinked.com", defaultModel: "fastino/GLiNER2.5-Decide",});const { answers } = await client.systemOne({ state: TICKET, questions: { spam: noul("Is this message unsolicited spam?"), intent: choice("What does the customer want?", { billing: "payments, invoices or refunds", technical: "something is broken", other: null, }), urgency: score("How urgent is this request?", ["can wait", "this week", "today"]), },});
console.log(answers.spam.noul, answers.intent.choice, answers.urgency.score);Choosing a model
Section titled “Choosing a model”/v1/systemone answers with SIE’s decision models. Each reads a fixed
window of tokens per row:
| Model | Window | What shares it |
|---|---|---|
fastino/GLiNER2.5-Decide | 512 tokens | All of a request’s questions (at most 256 tokens) and the state |
fastino/GLiNER2.5-Decide-1B | 2,048 tokens | All of the questions (at most 512 tokens) and the state; for longer text |
fastino/GLiNER2.5-multi-Decide | 2,048 tokens | As Decide-1B, multilingual |
convaiinnovations/laya-typed-decisions | 1,024 tokens | One question and the state, per question |
convaiinnovations/laya-multilingual | 1,024 tokens | As above, multilingual |
convaiinnovations/laya | 512 tokens | As above |
GLiNER2.5-Decide runs on SIE Serverless. Self-hosted SIE serves all six.
What differs from TypeSafe’s hosted API
Section titled “What differs from TypeSafe’s hosted API”- Model names. SIE takes its own model ids and has no aliases such as
jev-latest. Set the model on the client, inTYPESAFE_DEFAULT_MODEL, or per call withmodel=. - Score levels. A score question takes 1 to 10 levels.
- Input that does not fit. SIE refuses a state or question set that does
not fit the model’s window with
422, which the Python SDK raises asTypeSafeUnprocessableEntityError. It never truncates text. Use a model with a longer window for long states. - Other models.
models.list()lists every model the server serves. Asystem_onecall with a model that does not answer typed questions gets422. - Loading. A model that is still loading answers
503with aRetry-Afterheader.
Run it yourself
Section titled “Run it yourself”GLiNER2.5-Decide is a 340M-parameter encoder, so a CPU serves it:
docker run -p 8080:8080 ghcr.io/superlinked/sie-server:latest-cpu-transformers5
export TYPESAFE_BASE_URL=http://localhost:8080export TYPESAFE_DEFAULT_MODEL=fastino/GLiNER2.5-Decideexport TYPESAFE_API_KEY=local # a local server checks no keyThe first request downloads and loads the model. The
systemone-local example
in the SIE repository runs the TypeSafe SDK through every feature that reaches
the server and reports each case.
Also calling OpenAI’s Decisions API? See OpenAI Decisions → SIE.