Decodes one wire answer against the question that produced it, and turns any answer into a routing decision.
Decoding needs the question (to know which type is expected, and — for
Score — to supply the levels a label and index are read against) and the
TypeSafe.Keys registry built for the request (to hand ids and Choice
options back under the caller's own atoms or strings, never by calling
String.to_atom/1 on anything the API sent).
gate/2, yes?/2, and confidence/1 work the same way across all three
answer types, so a caller who only cares about "should I trust this"
doesn't need to branch on which question it was.
Summary
Functions
The confidence value gate/2 uses: max(noul, 1 - noul) for Noul, and the
wire confidence for Choice and Score.
Decodes one answer from the wire answers object.
Routes an answer into :act, :review, or :escalate by comparing
confidence/1 against two thresholds.
Whether a Noul answer clears a probability threshold. Defaults to 0.5.
Types
@type t() :: TypeSafe.Answer.Noul.t() | TypeSafe.Answer.Choice.t() | TypeSafe.Answer.Score.t()
Functions
The confidence value gate/2 uses: max(noul, 1 - noul) for Noul, and the
wire confidence for Choice and Score.
The API returns no confidence for a Noul answer, only the probability, so
the Noul value is this library's convention rather than something the model
reported. It reads distance from 0.5 as certainty: 0.92 and 0.08 both give
0.92, and 0.5 gives 0.5. That makes a Noul comparable to a Choice or Score
in gate/2, but it is not the same measurement, so do not tune one
threshold against numbers from the other.
@spec decode(map(), String.t(), TypeSafe.Question.t(), TypeSafe.Keys.t()) :: {:ok, t()} | {:error, TypeSafe.Error.t()}
Decodes one answer from the wire answers object.
wire_id is the string key the answer was found under; question is the
normalized question it answers. A question/raw_answer type mismatch, an
unrecognized "type", or a missing or invalid field all decode to an
Error.unexpected/2.
Routes an answer into :act, :review, or :escalate by comparing
confidence/1 against two thresholds.
Both :act and :review are required. Raises ArgumentError if :act is
lower than :review, since that would make the review band unreachable.
@spec yes?(TypeSafe.Answer.Noul.t(), number()) :: boolean()
Whether a Noul answer clears a probability threshold. Defaults to 0.5.
Noul answers only. A Choice or Score answer has no yes/no reading, so it
raises FunctionClauseError rather than inventing one; use gate/2 or
compare the fields you care about instead.