TypeSafeSDK

Hex.pm HexDocs GitHub License

TypeSafeSDK

Elixir client for TypeSafe AI: evaluate text or structured state with typed questions and receive structured answers. Supports System One (POST /v1/systemone) and model listing (GET /v1/models). HTTP execution, retries, and transport are provided by Pristine 0.3.0.

Installation

def deps do
[{:typesafe_sdk, "~> 0.1.1"}]
end

Documentation

Quick start

Read credentials in your application's config/runtime.exs:

import Config
config :typesafe_sdk, api_key: System.fetch_env!("TYPESAFE_API_KEY")

Then create one reusable client and ask questions:

alias TypeSafeSDK.{Choice, Noul, Score}
client = TypeSafeSDK.new_client()
{:ok, result} =
TypeSafeSDK.system_one(
client,
%{"message" => "I was charged twice. Please fix this today."},
%{
billing: %Noul{instructions: "Is this about billing?"},
department: Choice.new(
%{"billing" => "Payments and invoices", "technical" => "Bugs and outages"},
instructions: "Which team should handle this?"
),
urgency: Score.new(
["Can wait", "This week", "Today"],
instructions: "How urgent is this?"
)
}
)
result.answers["billing"].noul
result.answers["department"].choice
result.answers["urgency"].score
result.usage.input_tokens
{:ok, available} = TypeSafeSDK.list_models(client)
Enum.map(available.models, & &1.name)

The default model is "jev-latest". A state can be a string, object, or array. Score criteria should contain at least two levels, as required by the live API. Raw question maps are also accepted, preserving future question types and extra fields. Unknown answer types are logged and skipped. Score legend and probability keys become integers in Elixir.

Configuration and errors

client = TypeSafeSDK.new_client(api_key: "your-key", timeout: 10, retry: [max_retries: 2])
case TypeSafeSDK.list_models(client, timeout: 5, retry: false) do
{:ok, response} -> response.models
{:error, %TypeSafeSDK.Error{type: type, status: status, message: message}} ->
{type, status, message}
end

Timeouts and retry backoff values are in seconds; timeout_ms is an explicit millisecond alternative. Defaults retry connection failures, timeouts, HTTP 408, 429, and every 5xx status (including 529), with two retries, exponential backoff, and a 30-second total retry budget. Retry-After and retry-after-ms are honored. Client and per-call policies can replace the retry status set or disable retries.

extra_body shallow-merges last, including replacement of state, model, or questions. extra_headers cannot replace authentication, content negotiation, user-agent, or TypeSafe SDK/runtime/retry headers. Successful responses retain request_id and raw_http_response metadata.

Library runtime modules do not read environment variables. In this checkout, config/runtime.exs reads TYPESAFE_API_KEY, TYPESAFE_BASE_URL, TYPESAFE_DEFAULT_MODEL, and TYPESAFE_LOG_LEVEL. Host applications can pass options directly or set application configuration in their own runtime.exs.

Live example

Print real model data, typed questions, structured answers, and token usage:

# With TYPESAFE_API_KEY exported, run from the repository root:
mix run examples/live_evaluation.exs

See examples/README.md for the secrets-helper command and an explanation of the output.

Tests

The default suite uses fixtures and a mocked transport through the real Pristine request pipeline. It needs no API key and makes no live API calls:

mix test

Real API tests are tagged :live and opt-in. They make billable evaluation calls:

# With TYPESAFE_API_KEY exported:
mix test --only live
# Or run the complete suite, including live tests:
mix test --include live

Generation and local development

The committed OpenAPI snapshot was fetched from https://api.typesafe.ai/openapi.json on 2026-09-16. The initial public semantic reference is Python typesafe-sdk 0.6.0. See the provenance notes for reviewed schema changes.

mix deps.get
mix typesafe.prereq
mix typesafe.refresh --project-root .
mix typesafe.generate --project-root .
mix typesafe.verify --project-root .

Review upstream and generated diffs. Edit the source plugin or handwritten modules, then regenerate; lib/typesafe_sdk/generated/ is generator-owned. Code generation tooling is compiled only in dev/test.

This is a standalone Mix application. Dependency tuples default to Hex, with the same MIX_WORKSPACE_OPS_BOOTSTRAP / workspace_dep/1 hook as the sibling SDKs for local path or Git source selection. Local Pristine 0.3.0 can satisfy the prerequisite without publishing it. No portfolio registry is required by this SDK.

See HANDOFF.md for local verification results and publication notes, and the guides for more examples.

For the three-package release order and copy/paste commands, see the publication handoff. Pristine Codegen and Testkit are checkout-only maintenance tools; publishing the unpacked SDK distribution does not require releasing those tools.