Documentation
¶
Overview ¶
Package systemone is a client for the TypeSafe System One API.
A request sends one state and a set of typed questions; the response carries one answer per question. Questions are values you declare once and reuse:
type Dept string
const (
Billing Dept = "billing"
Technical Dept = "technical"
)
var (
dept = systemone.NewChoice[Dept]("department", "Which team should handle this?",
systemone.Option(Billing, "Payments, invoicing, refunds"),
systemone.Option(Technical, "Bugs, outages, integrations"),
)
urgent = systemone.NewNoul("is_urgent", "Does this convey urgency?")
)
res, err := client.Ask(ctx, "Help! My payouts have been failing for 3 days.", dept, urgent)
if err != nil {
return err
}
d, err := dept.From(res) // ChoiceAnswer[Dept]
u, err := urgent.From(res) // NoulAnswer
Reading an answer through its question handle is the only way to reach it, so the option type, the level type, and the answer type are all checked at compile time.
See https://docs.typesafe.ai for the concepts behind state, questions, probabilities, and confidence.
This is an unofficial, community-maintained client, not built, endorsed, or supported by TypeSafe.
Example ¶
Independent questions about the same state go in one request. They are answered in parallel and cannot see one another's answers.
package main
import (
"context"
"fmt"
"log"
"github.com/justintout/systemone"
)
// Questions are values. Declare them once and reuse them across requests.
type Team string
const (
TeamBilling Team = "billing"
TeamTechnical Team = "technical"
TeamSales Team = "sales"
)
type Anger int
var (
team = systemone.NewChoice[Team]("team", "Which team should handle this message?",
systemone.Option(TeamBilling, "Payments, invoicing, refunds"),
systemone.Option(TeamTechnical, "Bugs, outages, integrations"),
systemone.Option(TeamSales, "Pricing, upgrades, new accounts"),
)
timeSensitive = systemone.NewNoul("time_sensitive", "Does this convey urgency?",
systemone.Yes("Explicitly time-sensitive"),
systemone.No("No urgency expressed"),
)
anger = systemone.NewScore[Anger]("anger", "How frustrated is the customer?",
systemone.Levels[Anger]("Calm and matter-of-fact", "Visibly frustrated", "Angry, threatening to leave"),
)
)
func main() {
client, err := systemone.New()
if err != nil {
log.Fatal(err)
}
ticket := map[string]any{
"subject": "Payouts failing",
"body": "Help! My payouts have been failing for 3 days and nobody has replied.",
"plan": "enterprise",
}
res, err := client.Ask(context.Background(), ticket, team, timeSensitive, anger)
if err != nil {
log.Fatal(err)
}
t, err := team.From(res)
if err != nil {
log.Fatal(err)
}
u, err := timeSensitive.From(res)
if err != nil {
log.Fatal(err)
}
a, err := anger.From(res)
if err != nil {
log.Fatal(err)
}
fmt.Println(t.Value, t.Confidence, u.Yes(0.8), a.Level, a.Describe())
}
Output:
Example (CompositeScoring) ¶
Score each dimension on its own, then combine with weights your code owns. Changing a weight reranks existing answers without a new request.
package main
import (
"context"
"fmt"
"log"
"github.com/justintout/systemone"
"github.com/justintout/systemone/pattern"
)
// Questions are values. Declare them once and reuse them across requests.
type Team string
const (
TeamBilling Team = "billing"
TeamTechnical Team = "technical"
TeamSales Team = "sales"
)
type Anger int
var (
timeSensitive = systemone.NewNoul("time_sensitive", "Does this convey urgency?",
systemone.Yes("Explicitly time-sensitive"),
systemone.No("No urgency expressed"),
)
anger = systemone.NewScore[Anger]("anger", "How frustrated is the customer?",
systemone.Levels[Anger]("Calm and matter-of-fact", "Visibly frustrated", "Angry, threatening to leave"),
)
)
func main() {
client, err := systemone.New()
if err != nil {
log.Fatal(err)
}
res, err := client.Ask(context.Background(), "resume text", anger, timeSensitive)
if err != nil {
log.Fatal(err)
}
a, _ := anger.From(res)
u, _ := timeSensitive.From(res)
priority := pattern.Composite(
pattern.Weigh(a, 0.7),
pattern.WeighNoul(u, 0.3),
)
fmt.Printf("priority %.2f\n", priority)
}
Output:
Example (ConfidenceGatedRouting) ¶
Confidence says whether to act on an answer, not whether the answer is right. Gate riskier actions at a higher bar.
package main
import (
"context"
"fmt"
"log"
"github.com/justintout/systemone"
"github.com/justintout/systemone/pattern"
)
// Questions are values. Declare them once and reuse them across requests.
type Team string
const (
TeamBilling Team = "billing"
TeamTechnical Team = "technical"
TeamSales Team = "sales"
)
type Anger int
var team = systemone.NewChoice[Team]("team", "Which team should handle this message?",
systemone.Option(TeamBilling, "Payments, invoicing, refunds"),
systemone.Option(TeamTechnical, "Bugs, outages, integrations"),
systemone.Option(TeamSales, "Pricing, upgrades, new accounts"),
)
func main() {
client, err := systemone.New()
if err != nil {
log.Fatal(err)
}
res, err := client.Ask(context.Background(), "Move everything into savings.", team)
if err != nil {
log.Fatal(err)
}
t, err := team.From(res)
if err != nil {
log.Fatal(err)
}
switch (pattern.Thresholds{Medium: 0.6, High: 0.85}).Band(t.Confidence) {
case pattern.High:
fmt.Println("route to", t.Value)
case pattern.Medium:
fmt.Println("confirm with the customer, then route to", t.Value)
case pattern.Low:
fmt.Println("hand to a support agent")
}
}
Output:
Index ¶
- Constants
- Variables
- type Choice
- type ChoiceAnswer
- type ChoiceOption
- type Client
- type ClientOption
- func WithAPIKey(key string) ClientOption
- func WithBaseURL(rawURL string) ClientOption
- func WithHTTPClient(hc *http.Client) ClientOption
- func WithHeader(key, value string) ClientOption
- func WithLogLevel(level slog.Level) ClientOption
- func WithLogger(log *slog.Logger) ClientOption
- func WithModel(model string) ClientOption
- func WithRetry(p RetryPolicy) ClientOption
- func WithTimeout(d time.Duration) ClientOption
- func WithUserAgent(ua string) ClientOption
- type Content
- type Error
- type Model
- type Noul
- type NoulAnswer
- type NoulOption
- type Question
- type QuestionError
- type Request
- type Response
- type RetryPolicy
- type Score
- type ScoreAnswer
- type ScoreOption
- type Usage
Examples ¶
Constants ¶
const ( APIKeyEnv = "TYPESAFE_API_KEY" BaseURLEnv = "TYPESAFE_BASE_URL" DefaultModelEnv = "TYPESAFE_DEFAULT_MODEL" LogLevelEnv = "TYPESAFE_LOG_LEVEL" )
Environment variables read when the matching option is not given.
const ( DefaultBaseURL = "https://api.typesafe.ai" DefaultModel = "jev-latest" DefaultTimeout = 10 * time.Second )
Client defaults.
const ( MinScoreLevels = 2 MaxScoreLevels = 10 )
Score level count limits the API enforces.
const LevelOff = slog.Level(math.MaxInt32)
LevelOff disables logging. It sits above every level slog defines, so no record is ever enabled.
const MaxChoiceOptions = 255
MaxChoiceOptions is the largest number of options the API accepts on one Choice question.
const NoTimeout = -1 * time.Nanosecond
NoTimeout removes the per-attempt bound from a call when given as a Request.Timeout. Any negative duration does the same.
Variables ¶
var ( ErrInvalidRequest = errors.New("systemone: invalid request") ErrAuthentication = errors.New("systemone: authentication failed") ErrPermissionDenied = errors.New("systemone: permission denied") ErrNotFound = errors.New("systemone: not found") ErrUnprocessable = errors.New("systemone: request failed validation") ErrRateLimit = errors.New("systemone: rate limit exceeded") ErrOverloaded = errors.New("systemone: service overloaded") ErrServer = errors.New("systemone: server error") )
Sentinels for classifying an *Error with errors.Is:
if errors.Is(err, systemone.ErrRateLimit) { ... }
ErrServer also matches ErrOverloaded, since 529 is a server status.
var ( // ErrNoAnswer means the response carries no answer under the question's ID. ErrNoAnswer = errors.New("no answer for question") // ErrAnswerType means the answer under that ID is of a different primitive. ErrAnswerType = errors.New("answer is of a different question type") // ErrIncompleteAnswer means the answer arrived without a field the API // documents as required, so it cannot be read without inventing a value. ErrIncompleteAnswer = errors.New("answer is missing a required field") )
Errors returned when reading an answer out of a Response.
var ErrNoAPIKey = errors.New("systemone: no API key")
ErrNoAPIKey is returned by New when no API key is given and APIKeyEnv is unset.
Functions ¶
This section is empty.
Types ¶
type Choice ¶
type Choice[T ~string] struct { // contains filtered or unexported fields }
Choice asks the model to pick one option from a set you define. T is the Go type of the options, so both the declared set and the answer are checked at compile time:
type Dept string
const (
Billing Dept = "billing"
Technical Dept = "technical"
)
var dept = systemone.NewChoice[Dept]("department", "Which team should handle this?",
systemone.Option(Billing, "Payments, invoicing, refunds"),
systemone.Option(Technical, "Bugs, outages, integrations"),
)
See https://docs.typesafe.ai/primitives/choice.
func NewChoice ¶
func NewChoice[T ~string](id string, instructions Content, opts ...ChoiceOption[T]) *Choice[T]
NewChoice builds a Choice question. A build error, such as a duplicate option, is reported by the Client call that sends the question rather than here, so questions can be declared as package-level variables.
func (*Choice[T]) From ¶
func (q *Choice[T]) From(r *Response) (ChoiceAnswer[T], error)
From reads this question's answer out of a response. It returns a *QuestionError wrapping ErrNoAnswer when the response has no answer under the question's ID, or ErrAnswerType when that answer is a different primitive.
type ChoiceAnswer ¶
type ChoiceAnswer[T ~string] struct { // Value is the highest-probability option. Value T // Probabilities maps every declared option to its probability. They sum to 1. Probabilities map[T]float64 // Confidence is how concentrated Probabilities is, from 0 to 1. It says // whether to act on Value, not whether Value is correct. See // https://docs.typesafe.ai/confidence. Confidence float64 }
ChoiceAnswer is the answer to a Choice question.
func (ChoiceAnswer[T]) Probability ¶
func (a ChoiceAnswer[T]) Probability(option T) float64
Probability returns the probability of one option, or 0 if the answer does not carry it.
func (ChoiceAnswer[T]) Ranked ¶
func (a ChoiceAnswer[T]) Ranked() []T
Ranked returns the options ordered by descending probability. Equal probabilities are ordered by option name so the result is stable.
type ChoiceOption ¶
type ChoiceOption[T ~string] interface { // contains filtered or unexported methods }
ChoiceOption configures a Choice during construction.
func Option ¶
func Option[T ~string](value T, description Content) ChoiceOption[T]
Option declares one selectable option and the rubric that describes it. A nil description sends the option with no extra detail. The description may be a string or any JSON-encodable structure; see https://docs.typesafe.ai/primitives/advanced.
func Options ¶
func Options[T ~string](values ...T) ChoiceOption[T]
Options declares several options at once, none of them described. Use it when the option names carry the whole meaning.
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client sends requests to the System One API. It is safe for concurrent use.
func New ¶
func New(opts ...ClientOption) (*Client, error)
New builds a client. Without options it reads the API key from APIKeyEnv, the base URL from BaseURLEnv, and the default model from DefaultModelEnv.
func (*Client) Ask ¶
Ask evaluates state against questions using the client's default model. It is Client.Do for the common case.
type ClientOption ¶
type ClientOption interface {
// contains filtered or unexported methods
}
ClientOption configures a Client. Explicit options take precedence over environment variables, which take precedence over the defaults.
func WithAPIKey ¶
func WithAPIKey(key string) ClientOption
WithAPIKey sets the API key, overriding APIKeyEnv.
func WithBaseURL ¶
func WithBaseURL(rawURL string) ClientOption
WithBaseURL sets the API root, overriding BaseURLEnv. Endpoint paths are appended to it.
func WithHTTPClient ¶
func WithHTTPClient(hc *http.Client) ClientOption
WithHTTPClient sets the HTTP client used for every request. Use it to configure transport, proxies, or connection pooling. The client's own Timeout field, if set, bounds the whole call including retries, which is separate from WithTimeout.
func WithHeader ¶
func WithHeader(key, value string) ClientOption
WithHeader adds a header sent on every request. A Request header of the same name replaces it for that request, except for Authorization, Accept, Content-Type and User-Agent, which the client always sets itself. WithUserAgent changes the last of those.
func WithLogLevel ¶
func WithLogLevel(level slog.Level) ClientOption
WithLogLevel sets the level WithLogger logs at, overriding LogLevelEnv. Pass LevelOff to disable logging without removing the logger.
func WithLogger ¶
func WithLogger(log *slog.Logger) ClientOption
WithLogger sends one record per HTTP attempt to log. The client logs nothing until this option is given, so it stays quiet inside a library by default.
The level comes from LogLevelEnv, which accepts debug, info, warn, error and off, and defaults to info; WithLogLevel overrides it. At info each record is a summary: method, URL, attempt, duration, status, and request ID. At debug it also carries headers and bodies.
Credential headers are redacted. Bodies are not, and the request body holds the state, so debug logging writes whatever you are evaluating to the log.
func WithModel ¶
func WithModel(model string) ClientOption
WithModel sets the model used when a request does not name one, overriding DefaultModelEnv. See https://docs.typesafe.ai/models.
func WithRetry ¶
func WithRetry(p RetryPolicy) ClientOption
WithRetry turns on retries. The client does not retry by default; pass DefaultRetry for a sensible policy.
Example ¶
Retries are off by default. Turn them on with a policy you can tune.
package main
import (
"log"
"time"
"github.com/justintout/systemone"
)
func main() {
policy := systemone.DefaultRetry()
policy.MaxRetries = 4
policy.MaxBackoff = 10 * time.Second
client, err := systemone.New(
systemone.WithRetry(policy),
systemone.WithTimeout(30*time.Second),
)
if err != nil {
log.Fatal(err)
}
_ = client
}
Output:
func WithTimeout ¶
func WithTimeout(d time.Duration) ClientOption
WithTimeout bounds one attempt, not the whole call. A zero duration removes the bound. The default is DefaultTimeout.
func WithUserAgent ¶
func WithUserAgent(ua string) ClientOption
WithUserAgent replaces the default User-Agent header.
type Content ¶
type Content = any
Content is the body of a question's instructions or of a single criterion. A string covers most questions. Any value that encodes to a JSON object or array is also accepted, which lets a question carry named data it refers to by backticked path. See https://docs.typesafe.ai/primitives/advanced.
type Error ¶
type Error struct {
// StatusCode is the HTTP status code.
StatusCode int
// RequestID is the x-typesafe-request-id response header, empty if absent.
RequestID string
// Body is the raw response body, which describes the offending field on a
// 422. It is not parsed, because the API does not contract its shape.
Body []byte
// Header is the response header.
Header http.Header
// RetryAfter is the wait the server asked for, or 0 if it asked for none.
RetryAfter time.Duration
}
Error is an unsuccessful HTTP response from the API.
Example ¶
Classify an HTTP failure by its status.
package main
import (
"context"
"errors"
"fmt"
"log"
"github.com/justintout/systemone"
)
// Questions are values. Declare them once and reuse them across requests.
type Team string
const (
TeamBilling Team = "billing"
TeamTechnical Team = "technical"
TeamSales Team = "sales"
)
type Anger int
var team = systemone.NewChoice[Team]("team", "Which team should handle this message?",
systemone.Option(TeamBilling, "Payments, invoicing, refunds"),
systemone.Option(TeamTechnical, "Bugs, outages, integrations"),
systemone.Option(TeamSales, "Pricing, upgrades, new accounts"),
)
func main() {
client, err := systemone.New()
if err != nil {
log.Fatal(err)
}
_, err = client.Ask(context.Background(), "state", team)
var apiErr *systemone.Error
switch {
case err == nil:
case errors.Is(err, systemone.ErrRateLimit):
fmt.Println("back off and retry")
case errors.Is(err, systemone.ErrUnprocessable):
// The body names the offending field.
errors.As(err, &apiErr)
fmt.Println("bad question:", string(apiErr.Body))
default:
fmt.Println(err)
}
}
Output:
type Model ¶
type Model struct {
Name string
Description string
// ReleaseDate is when the model or alias was released. It is the zero time
// when the API omits it.
//
// The API sends RFC 3339, for example 2026-09-10T18:38:01.391457+00:00,
// despite the SDK documentation showing a bare YYYY-MM-DD date.
ReleaseDate time.Time
}
Model describes a model or alias the account may send in a request.
type Noul ¶
type Noul struct {
// contains filtered or unexported fields
}
Noul asks a yes/no question and returns the probability that the answer is yes. A value near 0.5 means yes and no are close to equally likely, not that the condition half holds; see https://docs.typesafe.ai/primitives/noul.
var urgent = systemone.NewNoul("is_urgent", "Does this convey urgency?",
systemone.Yes("Explicitly time-sensitive"),
systemone.No("No urgency expressed"),
)
Use one Noul per label when several labels may apply at once.
func NewNoul ¶
func NewNoul(id string, instructions Content, opts ...NoulOption) *Noul
NewNoul builds a Noul question. Criteria are optional; describe both sides when the boundary between yes and no is subtle.
func (*Noul) From ¶
func (q *Noul) From(r *Response) (NoulAnswer, error)
From reads this question's answer out of a response. It returns a *QuestionError wrapping ErrNoAnswer when the response has no answer under the question's ID, or ErrAnswerType when that answer is a different primitive.
type NoulAnswer ¶
type NoulAnswer struct {
// Value is the probability that the answer is yes, from 0 to 1.
Value float64
}
NoulAnswer is the answer to a Noul question. Noul answers carry no confidence: the probability is the whole answer.
func (NoulAnswer) Yes ¶
func (a NoulAnswer) Yes(threshold float64) bool
Yes reports whether the probability of yes is at least threshold. Pick the threshold from your own data and the cost of being wrong.
type NoulOption ¶
type NoulOption interface {
// contains filtered or unexported methods
}
NoulOption configures a Noul during construction.
func Yes ¶
func Yes(description Content) NoulOption
Yes describes what a yes, a value near 1, means.
type Question ¶
type Question interface {
// ID is the key the question is sent under and the answer comes back under.
ID() string
// contains filtered or unexported methods
}
Question is one typed question in a request. The three implementations are Choice, Score and Noul; the interface is closed.
type QuestionError ¶
QuestionError reports a question that cannot be sent as built.
func (*QuestionError) Error ¶
func (e *QuestionError) Error() string
func (*QuestionError) Unwrap ¶
func (e *QuestionError) Unwrap() error
type Request ¶
type Request struct {
// State is the content to evaluate: a string, or any value that encodes to
// a JSON object or array. See https://docs.typesafe.ai/concepts/state.
State any
// Questions are asked in one call and answered in parallel. They cannot see
// one another's answers.
Questions []Question
// Model overrides the client default for this request.
Model string
// Header adds or replaces headers for this request. Authorization, Accept,
// Content-Type and User-Agent are set by the client after this is applied,
// so they cannot be overridden here; see [WithUserAgent].
Header http.Header
// Retry overrides the client's retry policy for this request. A nil Retry
// inherits it; a zero RetryPolicy turns retries off for this call alone.
Retry *RetryPolicy
// Timeout overrides the client's per-attempt timeout for this request. Zero
// inherits it, and [NoTimeout] removes the bound. To bound the whole call
// including retries, give ctx a deadline.
Timeout time.Duration
}
Request is one evaluation: a state, the questions to ask about it, and how to send them.
type Response ¶
type Response struct {
// Model is the versioned model that answered, even when the request named
// an alias such as jev-latest.
Model string
// Usage is the token count for the request.
Usage Usage
// RequestID is the x-typesafe-request-id response header, empty if absent.
RequestID string
// contains filtered or unexported fields
}
Response is the result of one evaluation. Answers are read through the question handles that produced them: Choice.From, Score.From, Noul.From.
type RetryPolicy ¶
type RetryPolicy struct {
// MaxRetries is how many attempts follow the first one.
MaxRetries int
// InitialBackoff is the wait before the first retry. It doubles each
// attempt up to MaxBackoff.
InitialBackoff time.Duration
// MaxBackoff caps the wait between attempts.
MaxBackoff time.Duration
// Jitter spreads each wait by up to this fraction in either direction, so
// concurrent clients do not retry in lockstep. 0.25 means plus or minus a
// quarter of the computed wait. It must be between 0 and 1: above 1 the
// spread exceeds the delay and produces a negative wait.
Jitter float64
// Retry reports whether a response with this status should be retried. A
// nil Retry retries 408, 429, and every 5xx.
Retry func(status int) bool
// RetryTransportError retries a request that failed without a response,
// including a per-attempt timeout.
RetryTransportError bool
// RespectRetryAfter uses the server's retry-after header in place of the
// computed backoff when the response carries one.
RespectRetryAfter bool
}
RetryPolicy controls whether the client retries a failed attempt. The zero value performs no retries, which is the client default; pass DefaultRetry to WithRetry to turn retries on.
Retries apply to the whole request, including transport failures, so a retried request may be evaluated more than once by the service.
func DefaultRetry ¶
func DefaultRetry() RetryPolicy
DefaultRetry is the policy to start from: two retries with exponential backoff from 500ms, capped at 5s, honoring retry-after.
type Score ¶
type Score[T ~int] struct { // contains filtered or unexported fields }
Score rates the state along ordered levels you define and returns a probability-weighted position across them. T is an integer type whose constants are the levels, declared from lowest to highest starting at zero:
type Frustration int
const (
Calm Frustration = iota
Frustrated
VeryAngry
)
var frustration = systemone.NewScore[Frustration]("frustration", "How frustrated is the customer?",
systemone.Level(Calm, "Calm"),
systemone.Level(Frustrated, "Frustrated"),
systemone.Level(VeryAngry, "Very angry"),
)
Each level description must describe a concrete situation and stand on its own. See https://docs.typesafe.ai/primitives/score.
func NewScore ¶
func NewScore[T ~int](id string, instructions Content, opts ...ScoreOption[T]) *Score[T]
NewScore builds a Score question.
func (*Score[T]) From ¶
func (q *Score[T]) From(r *Response) (ScoreAnswer[T], error)
From reads this question's answer out of a response. It returns a *QuestionError wrapping ErrNoAnswer when the response has no answer under the question's ID, or ErrAnswerType when that answer is a different primitive.
type ScoreAnswer ¶
type ScoreAnswer[T ~int] struct { // Value is the probability-weighted position across the levels. It can land // between two levels, so it is a float rather than a T. Value float64 // Level is the single most probable level. It can differ from rounding // Value when the distribution is lopsided. Level T // Probabilities maps every level to its probability. They sum to 1. Probabilities map[T]float64 // Legend maps every level back to the description that was sent for it. // The API echoes the description as it was sent, so a level declared with // a structured description comes back structured. A response may carry // fewer entries than the question declared, so it does not give the scale. Legend map[T]Content // LevelCount is how many levels the question declared. It comes from the // question, not the response, and is what [ScoreAnswer.Normalized] divides // by. A ScoreAnswer built by hand must set it. LevelCount int // Confidence is how concentrated Probabilities is, from 0 to 1. See // https://docs.typesafe.ai/confidence. Confidence float64 }
ScoreAnswer is the answer to a Score question.
func (ScoreAnswer[T]) Describe ¶
func (a ScoreAnswer[T]) Describe() string
Describe returns the description ScoreAnswer.Level was sent with, as text. A level declared with a structured description is rendered as JSON; reach into ScoreAnswer.Legend to read its fields.
func (ScoreAnswer[T]) Normalized ¶
func (a ScoreAnswer[T]) Normalized() float64
Normalized maps Value onto 0 to 1, dividing by the highest declared level. Use it to put scores with different level counts on one scale before combining them. It returns 0 when LevelCount is unset, which only happens on a ScoreAnswer that did not come from Score.From.
func (ScoreAnswer[T]) Probability ¶
func (a ScoreAnswer[T]) Probability(level T) float64
Probability returns the probability of one level, or 0 if the answer does not carry it.
type ScoreOption ¶
type ScoreOption[T ~int] interface { // contains filtered or unexported methods }
ScoreOption configures a Score during construction.
func Level ¶
func Level[T ~int](level T, description Content) ScoreOption[T]
Level declares one level and its description. Levels are sent as an ordered array, so level must equal the position it is declared in: the first Level must be 0, the second 1, and so on. A mismatch fails the request rather than silently shifting the scale.
func Levels ¶
func Levels[T ~int](descriptions ...Content) ScoreOption[T]
Levels declares every level at once, in order from lowest to highest. The level values are the positions in the list.
type Usage ¶
Usage is the token count the request was billed on. Only input tokens are charged; see https://docs.typesafe.ai/models.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
examples
|
|
|
triage
command
Command triage is the support-ticket example from the TypeSafe quick start, written with this SDK.
|
Command triage is the support-ticket example from the TypeSafe quick start, written with this SDK. |
|
internal
|
|
|
releasebot
command
Command releasebot works out whether the changes since the last release are worth publishing, and whether they may break existing callers.
|
Command releasebot works out whether the changes since the last release are worth publishing, and whether they may break existing callers. |
|
Package pattern composes System One answers into the shapes the TypeSafe docs describe: confidence-gated routing, composite scoring, and walking a taxonomy one Choice at a time.
|
Package pattern composes System One answers into the shapes the TypeSafe docs describe: confidence-gated routing, composite scoring, and walking a taxonomy one Choice at a time. |