TypeSafe.Response (typesafe_ai v0.1.1)

Copy Markdown View Source

A successful evaluation returned by TypeSafe.system_one/2.

  • :model is the actual model identifier returned by the service, which may differ from an alias supplied in the request.
  • :answers maps the original string question IDs to TypeSafe.Answer.Choice, TypeSafe.Answer.Score, or TypeSafe.Answer.Noul structs.
  • :usage contains :input_tokens and :output_tokens, non-negative integers reported for this successful evaluation. It does not aggregate prior attempts or provide billing information for failed requests.

Each requested question must have an answer of the matching type. The client rejects missing/extra answers, invalid values, or inconsistent probability keys as :invalid_response. Dynamic IDs and labels remain strings.

case TypeSafe.system_one(MyApp.TypeSafe,
       state: "Please refund me",
       questions: %{"refund" => TypeSafe.noul("Refund requested?")}) do
  {:ok, %TypeSafe.Response{answers: %{"refund" => answer}}} -> answer.noul
  {:error, %TypeSafe.Error{kind: kind}} -> {:failed, kind}
end

Summary

Types

t()

Model, typed answers, and token usage for one successful attempt.

Advanced integration

Decodes a complete JSON response against a validated question schema.

Types

t()

@type t() :: %TypeSafe.Response{
  answers: %{
    required(String.t()) =>
      TypeSafe.Answer.Choice.t()
      | TypeSafe.Answer.Score.t()
      | TypeSafe.Answer.Noul.t()
  },
  model: String.t(),
  usage: %{input_tokens: non_neg_integer(), output_tokens: non_neg_integer()}
}

Model, typed answers, and token usage for one successful attempt.

Advanced integration

decode(body, schema)

@spec decode(binary(), map()) :: {:ok, t()} | {:error, TypeSafe.Error.t()}

Decodes a complete JSON response against a validated question schema.

Obtain schema from TypeSafe.Question.to_wire/1; it uses atom field keys, not the string field keys produced by decoding a request's JSON. Normal client calls handle decoding automatically.

Validates required fields, answer types, value ranges, and distribution keys. Probability sums tolerate rounding within 0.02 of 1. Returns a typed response or {:error, %TypeSafe.Error{kind: :invalid_response}}, omitting the raw body.

Examples

iex> {:ok, schema} = TypeSafe.Question.to_wire(%{"refund" => TypeSafe.noul("Refund requested?")})
iex> body = ~s({"model":"jev-example","answers":{"refund":{"type":"noul","noul":0.9}},"usage":{"input_tokens":10,"output_tokens":2}})
iex> {:ok, response} = TypeSafe.Response.decode(body, schema)
iex> response.answers["refund"].noul
0.9
iex> response.usage
%{input_tokens: 10, output_tokens: 2}