ExTypesafe (ExTypesafe v0.2.0)

Copy Markdown View Source

Elixir client for the TypeSafe AI API.

TypeSafe evaluates typed questions against a state and returns structured answers your code can branch on directly — no text parsing required.

Question types

ModuleTypeReturns
ExTypesafe.Question.Noulnoulnoul float (0 = no, 1 = yes)
ExTypesafe.Question.Choicechoicechoice string + probabilities + confidence
ExTypesafe.Question.Scorescorescore + legend + probabilities + confidence

Quickstart

# Configure once (reads TYPESAFE_API_KEY from env by default)
client = ExTypesafe.Client.new()

# Build typed questions. Atom keys are retained in the response.
questions = %{
  is_urgent: ExTypesafe.Question.noul("Does this convey urgency?"),
  department: ExTypesafe.Question.choice(
    "Which team should handle this?",
    %{billing: "Payments, invoicing, refunds", technical: "Bugs, outages, integrations"}
  ),
  frustration: ExTypesafe.Question.score(
    "How frustrated is the customer?",
    ["Calm", "Frustrated", "Very angry"]
  )
}

state = "Hi, my payouts have been failing for 3 days. I'm losing sales. Please help!"

case ExTypesafe.system_one(client, state, questions) do
  {:ok, response} ->
    response.answers.is_urgent.noul       #=> 0.97
    response.answers.department.choice    #=> "billing"
    response.answers.frustration.score    #=> 1.83
    response.scores.frustration.legend    #=> %{"0" => "Calm", ...}

  {:error, error} ->
    IO.inspect(error)
end

Configuration

See ExTypesafe.Client.new/1 and ExTypesafe.Config for all options.

Environment variables are supported:

VariableConfiguresDefault
TYPESAFE_API_KEYAPI key (required)—
TYPESAFE_BASE_URLAPI root URLhttps://api.typesafe.ai
TYPESAFE_DEFAULT_MODELDefault modeljev-latest

Retries

429 Too Many Requests, 529 Overloaded, and transport-level connection failures are retried automatically with capped exponential backoff. Numeric Retry-After (delta seconds) and retry-after-ms headers are honored when within the configured cap. Configure :max_retries, :retry_delay_ms, and :max_retry_delay_ms on the client or per call. A transport retry can repeat a POST if the connection fails after the server receives it.

Summary

Types

A typed question struct or raw question map for forward-compatible API fields.

A non-empty map or caller-defined struct of atom or string question keys to questions.

The content to evaluate: a string, map, or list.

Functions

Evaluates typed questions against a state using the TypeSafe systemone endpoint.

Types

question()

@type question() :: ExTypesafe.Question.t() | map()

A typed question struct or raw question map for forward-compatible API fields.

questions()

@type questions() :: %{required(String.t() | atom()) => question()} | struct()

A non-empty map or caller-defined struct of atom or string question keys to questions.

state()

@type state() :: String.t() | map() | list()

The content to evaluate: a string, map, or list.

Functions

system_one(client, state, questions, opts \\ [])

@spec system_one(ExTypesafe.Client.t(), state(), questions(), keyword()) ::
  {:ok, ExTypesafe.Response.t()} | {:error, ExTypesafe.Error.t()}

Evaluates typed questions against a state using the TypeSafe systemone endpoint.

All questions in the map are evaluated in parallel and in isolation against the same state in a single API call. Atom question keys are restored in response.answers, while string question keys remain strings.

Returns {:ok, ExTypesafe.Response.t()} or {:error, ExTypesafe.Error.t()}.

Parameters

  • client — A client built with ExTypesafe.Client.new/1.
  • state — The content to evaluate: a plain string for text, or a map/list for structured data (e.g. chat logs, records, application state).
  • questions — A non-empty map or caller-defined struct of arbitrary atom or string keys to question structs or raw question maps. Struct containers are normalized without their __struct__ field and omit nil fields, and answers are returned under the same key form.
  • opts — Optional keyword list:
    • :model — Override the client's default model for this request.
    • :extra_body — Map of forward-compatible request fields. Core request fields take precedence.
    • :max_retries — Override the client's retry count for this request.
    • :retry_delay_ms — Override the initial retry delay for this request.
    • :max_retry_delay_ms — Override the maximum retry delay for this request.

Examples

client = ExTypesafe.Client.new(api_key: "ts-...")

{:ok, response} = ExTypesafe.system_one(client, "I can't log in!", %{
  is_urgent: ExTypesafe.Question.noul("Does this convey urgency?")
})

response.answers.is_urgent.noul  #=> 0.88

String question keys remain strings:

{:ok, response} = ExTypesafe.system_one(client, "I can't log in!", %{
  "is_urgent" => ExTypesafe.Question.noul("Does this convey urgency?")
})

response.answers["is_urgent"].noul  #=> 0.88