Documentation
¶
Overview ¶
Package typesafe is an unofficial Go client for the TypeSafe AI System One API (https://docs.typesafe.ai). It is a community-maintained port of the concepts in TypeSafe's official Python (typesafe_sdk) and JavaScript (@typesafe-ai/sdk) SDKs; it is not published or endorsed by TypeSafe AI.
System One models such as Jev evaluate a state against a set of typed questions (Noul, Choice, Score) and return calibrated, structured answers instead of generated text. See https://docs.typesafe.ai/concepts/system-one for background.
Quick start ¶
client, err := typesafe.NewClient() // reads TYPESAFE_API_KEY from the environment
if err != nil {
log.Fatal(err)
}
resp, err := client.SystemOne(ctx, typesafe.SystemOneRequest{
State: "Help! My payouts have been failing for 3 days.",
Questions: typesafe.Questions{
"is_urgent": typesafe.Noul("Does this convey urgency?"),
},
})
if err != nil {
log.Fatal(err)
}
fmt.Println(resp.Answers["is_urgent"].(typesafe.NoulAnswer).Noul)
Index ¶
- Constants
- type APIError
- type AbortError
- type Answer
- type AuthenticationError
- type BadRequestError
- type ChoiceAnswer
- type ChoiceQuestion
- type Client
- func (c *Client) BaseURL() string
- func (c *Client) DefaultModel() string
- func (c *Client) ListModels(ctx context.Context, opts ...RequestOption) (*ListModelsResponse, error)
- func (c *Client) RetryPolicy() RetryPolicy
- func (c *Client) SystemOne(ctx context.Context, req SystemOneRequest, opts ...RequestOption) (*Response, error)
- func (c *Client) Timeout() time.Duration
- type ConnectionError
- type InternalServerError
- type ListModelsResponse
- type LogLevel
- type Logger
- type ModelMetadata
- type NotFoundError
- type NoulAnswer
- type NoulCriteria
- type NoulQuestion
- type Option
- func WithAPIKey(key string) Option
- func WithBaseURL(baseURL string) Option
- func WithDefaultModel(model string) Option
- func WithHTTPClient(hc *http.Client) Option
- func WithHeader(key, value string) Option
- func WithLogLevel(level LogLevel) Option
- func WithLogger(l Logger) Option
- func WithRetryPolicy(policy RetryPolicy) Option
- func WithTimeout(d time.Duration) Option
- type PermissionDeniedError
- type Question
- type Questions
- type RateLimitError
- type RequestOption
- type Response
- type ResponseValidationError
- type RetryPolicy
- type ScoreAnswer
- type ScoreQuestion
- type StdLogger
- type SystemOneRequest
- type TimeoutError
- type UnprocessableEntityError
- type Usage
Constants ¶
const ( // APIKeyEnvVar holds the TypeSafe API key. APIKeyEnvVar = "TYPESAFE_API_KEY" // BaseURLEnvVar overrides the API base URL. BaseURLEnvVar = "TYPESAFE_BASE_URL" // DefaultModelEnvVar overrides the model used when a request omits one. DefaultModelEnvVar = "TYPESAFE_DEFAULT_MODEL" // LogLevelEnvVar controls SDK log verbosity (debug, info, warn, error, off). LogLevelEnvVar = "TYPESAFE_LOG_LEVEL" )
Environment variable names read by NewClient. Explicit Options always take precedence over these; empty or whitespace-only values are ignored, mirroring the official Python and JavaScript SDKs.
const ( // DefaultBaseURL is the production TypeSafe API root. DefaultBaseURL = "https://api.typesafe.ai" // DefaultModel is the model used when a request and the client both omit one. DefaultModel = "jev-latest" )
SDK-wide defaults.
const Version = "1.0.0"
Version is the SDK release version. Keep this in sync with the git tag (prefixed with "v", e.g. v1.0.0) and CHANGELOG.md when cutting a release.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type APIError ¶
type APIError struct {
// StatusCode is the HTTP status code returned by the server.
StatusCode int
// Status is the HTTP status text, e.g. "429 Too Many Requests".
Status string
// Body is the raw response body. It is the server's JSON error body when
// the response is JSON, or the raw bytes otherwise.
Body []byte
// Headers holds the full set of response headers.
Headers http.Header
// Method and URL identify the request that failed, with no credentials,
// query parameters, or fragment.
Method string
URL string
}
APIError is returned when the TypeSafe API responds with a non-2xx status after any configured retries. Callers that need a specific category (rate limiting, auth, validation, ...) should use errors.As against the wrapper types below (AuthenticationError, RateLimitError, and so on), which all embed *APIError.
type AbortError ¶
AbortError is returned when the caller's context is cancelled while a request is in flight.
func (*AbortError) Error ¶
func (e *AbortError) Error() string
func (*AbortError) Unwrap ¶
func (e *AbortError) Unwrap() error
type Answer ¶
type Answer interface {
// Type returns the wire "type" discriminator, e.g. "noul".
Type() string
// contains filtered or unexported methods
}
Answer is implemented by NoulAnswer, ChoiceAnswer, and ScoreAnswer. Use a type switch, or the Response.Noul/Choice/Score accessors, to read a specific answer.
type AuthenticationError ¶
type AuthenticationError struct{ *APIError }
AuthenticationError wraps a 401 response: authentication failed (missing or invalid API key).
func (*AuthenticationError) Unwrap ¶
func (e *AuthenticationError) Unwrap() error
Unwrap allows errors.As/errors.Is to reach the underlying *APIError.
type BadRequestError ¶
type BadRequestError struct{ *APIError }
BadRequestError wraps a 400 response: the request was invalid.
func (*BadRequestError) Unwrap ¶
func (e *BadRequestError) Unwrap() error
Unwrap allows errors.As/errors.Is to reach the underlying *APIError.
type ChoiceAnswer ¶
type ChoiceAnswer struct {
// Choice is the highest-probability option.
Choice string `json:"choice"`
// Probabilities maps every option defined in the question's criteria to
// its probability; the values sum to 1.
Probabilities map[string]float64 `json:"probabilities"`
// Confidence is derived from the probability distribution, from 0 to 1.
Confidence float64 `json:"confidence"`
}
ChoiceAnswer is the answer to a ChoiceQuestion.
func (ChoiceAnswer) Type ¶
func (ChoiceAnswer) Type() string
type ChoiceQuestion ¶
type ChoiceQuestion struct {
// Instructions describes what the model should decide.
Instructions any
// Criteria maps each option name to a rubric description. Use nil for an
// option that needs no extra detail.
Criteria map[string]any
}
ChoiceQuestion picks one option from a defined set. See https://docs.typesafe.ai/primitives/choice.
func Choice ¶
func Choice(instructions string, criteria map[string]any) ChoiceQuestion
Choice builds a Choice question from plain-text instructions and a map of option name to rubric description (string, nil, or a structured value).
func ChoiceStrings ¶
func ChoiceStrings(instructions string, criteria map[string]string) ChoiceQuestion
ChoiceStrings is a convenience for the common case where every option's rubric is a plain string.
func (ChoiceQuestion) MarshalJSON ¶
func (q ChoiceQuestion) MarshalJSON() ([]byte, error)
MarshalJSON implements json.Marshaler.
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client is a client for the TypeSafe AI System One API. Construct one with NewClient. A *Client is safe for concurrent use by multiple goroutines.
func NewClient ¶
NewClient builds a Client, reading TYPESAFE_API_KEY, TYPESAFE_BASE_URL, TYPESAFE_DEFAULT_MODEL, and TYPESAFE_LOG_LEVEL from the environment. Empty or whitespace-only environment values are ignored. Returns an error if no API key is available or the base URL is malformed.
func (*Client) DefaultModel ¶
DefaultModel returns the model used when a request omits one.
func (*Client) ListModels ¶
func (c *Client) ListModels(ctx context.Context, opts ...RequestOption) (*ListModelsResponse, error)
ListModels returns the models available to the account, as accepted by the model field.
func (*Client) RetryPolicy ¶
func (c *Client) RetryPolicy() RetryPolicy
RetryPolicy returns the client's default retry policy.
func (*Client) SystemOne ¶
func (c *Client) SystemOne(ctx context.Context, req SystemOneRequest, opts ...RequestOption) (*Response, error)
SystemOne evaluates State against Questions and returns typed answers, one per question, keyed by the id you chose in SystemOneRequest.Questions.
resp, err := client.SystemOne(ctx, typesafe.SystemOneRequest{
State: "I was charged twice. Please help.",
Questions: typesafe.Questions{
"billing": typesafe.Noul("Is this about billing?"),
},
})
type ConnectionError ¶
type ConnectionError struct {
// Method and URL identify the request that failed, with no credentials,
// query parameters, or fragment.
Method string
URL string
// Err is the underlying error, if any (net.Error, *url.Error, ...).
Err error
}
ConnectionError is returned when a request could not reach the server or lost its connection while reading the response (DNS failure, TCP reset, TLS error, or a body that closes before it finishes).
func (*ConnectionError) Error ¶
func (e *ConnectionError) Error() string
func (*ConnectionError) Unwrap ¶
func (e *ConnectionError) Unwrap() error
type InternalServerError ¶
type InternalServerError struct{ *APIError }
InternalServerError wraps a 5xx response: the server failed to process the request.
func (*InternalServerError) Unwrap ¶
func (e *InternalServerError) Unwrap() error
Unwrap allows errors.As/errors.Is to reach the underlying *APIError.
type ListModelsResponse ¶
type ListModelsResponse struct {
Models []ModelMetadata `json:"models"`
// RequestID is the x-typesafe-request-id response header, or "" if absent.
RequestID string `json:"-"`
}
ListModelsResponse is the result of ListModels.
type Logger ¶
type Logger interface {
Debugf(format string, args ...any)
Infof(format string, args ...any)
Warnf(format string, args ...any)
Errorf(format string, args ...any)
}
Logger is a minimal logging interface the Client can be configured with via WithLogger. Adapt any structured logger (zap, slog, logrus) to this interface with a small wrapper.
type ModelMetadata ¶
type ModelMetadata struct {
// Name is the model ID or alias, as accepted by the model field.
Name string `json:"name"`
// Description explains what the model is for.
Description string `json:"description"`
// ReleaseDate is when the model or alias was released.
ReleaseDate string `json:"release_date"`
}
ModelMetadata describes a model or alias accepted by the model field.
type NotFoundError ¶
type NotFoundError struct{ *APIError }
NotFoundError wraps a 404 response: the resource was not found.
func (*NotFoundError) Unwrap ¶
func (e *NotFoundError) Unwrap() error
Unwrap allows errors.As/errors.Is to reach the underlying *APIError.
type NoulAnswer ¶
type NoulAnswer struct {
// Noul is the probability the answer is yes, from 0 to 1.
Noul float64 `json:"noul"`
}
NoulAnswer is the answer to a NoulQuestion.
func (NoulAnswer) Type ¶
func (NoulAnswer) Type() string
type NoulCriteria ¶
NoulCriteria describes what a yes and a no answer mean for a NoulQuestion. Either field may hold a string or a structured value.
type NoulQuestion ¶
type NoulQuestion struct {
// Instructions is the yes/no question or statement to evaluate. It is
// usually a string, but accepts any JSON-marshalable value for structured
// instructions.
Instructions any
// Criteria optionally clarifies what a "true" and "false" answer mean.
// Leave nil when the instructions are unambiguous on their own.
Criteria *NoulCriteria
}
NoulQuestion asks a yes/no question and returns the probability the answer is yes. See https://docs.typesafe.ai/primitives/noul.
func Noul ¶
func Noul(instructions string) NoulQuestion
Noul builds a yes/no question from plain-text instructions. Chain WithCriteria to clarify a subtle yes/no boundary.
func (NoulQuestion) MarshalJSON ¶
func (q NoulQuestion) MarshalJSON() ([]byte, error)
MarshalJSON implements json.Marshaler.
func (NoulQuestion) WithCriteria ¶
func (q NoulQuestion) WithCriteria(trueDesc, falseDesc any) NoulQuestion
WithCriteria returns a copy of q with true/false descriptions attached.
type Option ¶
type Option func(*clientConfig)
Option configures a Client built by NewClient. Explicit Options always take precedence over environment variables, which take precedence over SDK defaults.
func WithAPIKey ¶
WithAPIKey sets the API key, overriding TYPESAFE_API_KEY.
func WithBaseURL ¶
WithBaseURL sets the API root, overriding TYPESAFE_BASE_URL. Trailing slashes are removed.
func WithDefaultModel ¶
WithDefaultModel sets the model used when a request omits one, overriding TYPESAFE_DEFAULT_MODEL.
func WithHTTPClient ¶
WithHTTPClient sets the underlying *http.Client used to send requests. The client's own Timeout field is ignored; use WithTimeout or a per-call RequestOption to control the per-attempt deadline instead, so retries can apply the timeout to each attempt independently.
func WithHeader ¶
WithHeader adds a header sent with every request, in addition to Authorization, Content-Type, and User-Agent.
func WithLogLevel ¶
WithLogLevel sets the minimum level the logger receives, overriding TYPESAFE_LOG_LEVEL. Default: LogLevelWarn.
func WithLogger ¶
WithLogger sets the logger used for SDK diagnostics (retry attempts, backoff delays). Defaults to a no-op logger.
func WithRetryPolicy ¶
func WithRetryPolicy(policy RetryPolicy) Option
WithRetryPolicy sets the client's default retry policy. Start from DefaultRetryPolicy and override only the fields you need.
func WithTimeout ¶
WithTimeout sets the per-attempt HTTP timeout. Default: 10s.
type PermissionDeniedError ¶
type PermissionDeniedError struct{ *APIError }
PermissionDeniedError wraps a 403 response: access was denied.
func (*PermissionDeniedError) Unwrap ¶
func (e *PermissionDeniedError) Unwrap() error
Unwrap allows errors.As/errors.Is to reach the underlying *APIError.
type Question ¶
type Question interface {
// contains filtered or unexported methods
}
Question is implemented by NoulQuestion, ChoiceQuestion, and ScoreQuestion. Use the Noul, Choice, and Score constructors to build one, or construct a struct literal directly for structured instructions/criteria (see https://docs.typesafe.ai/primitives/advanced for the JSON shapes accepted).
type Questions ¶
Questions is a named set of questions evaluated together against the same state in a single SystemOne call. Keys are caller-chosen ids; the matching Answer is returned under the same key. Keys are never sent to the model.
type RateLimitError ¶
type RateLimitError struct {
*APIError
// RetryAfter is the server's requested wait, parsed from the Retry-After
// or retry-after-ms headers. Zero means the server did not specify one.
RetryAfter time.Duration
}
RateLimitError wraps a 429 response: the caller exceeded its rate limit.
func (*RateLimitError) Unwrap ¶
func (e *RateLimitError) Unwrap() error
Unwrap allows errors.As/errors.Is to reach the underlying *APIError.
type RequestOption ¶
type RequestOption func(*requestConfig)
RequestOption configures a single API call, overriding the client's defaults for that call only.
func WithRequestHeader ¶
func WithRequestHeader(key, value string) RequestOption
WithRequestHeader sets a header for a single call, overriding any client-level header with the same name.
func WithRequestRetryPolicy ¶
func WithRequestRetryPolicy(policy RetryPolicy) RequestOption
WithRequestRetryPolicy overrides the retry policy for a single call.
func WithRequestTimeout ¶
func WithRequestTimeout(d time.Duration) RequestOption
WithRequestTimeout overrides the per-attempt timeout for a single call.
type Response ¶
type Response struct {
// Model is the model that produced the answers.
Model string `json:"model"`
// Answers holds one entry per question, keyed by the id you chose when
// building the request.
Answers map[string]Answer `json:"-"`
// Usage reports token counts, when the API reports them.
Usage Usage `json:"usage"`
// RequestID is the x-typesafe-request-id response header, or "" if absent.
RequestID string `json:"-"`
// Header holds the full set of response headers.
Header http.Header `json:"-"`
}
Response is the result of a SystemOne call: one Answer per question, keyed by the same ids used in the request's Questions.
func (*Response) Choice ¶
func (r *Response) Choice(name string) (ChoiceAnswer, error)
Choice returns the ChoiceAnswer for name, or an error if it is missing or a different answer type.
func (*Response) Noul ¶
func (r *Response) Noul(name string) (NoulAnswer, error)
Noul returns the NoulAnswer for name, or an error if it is missing or a different answer type.
func (*Response) Score ¶
func (r *Response) Score(name string) (ScoreAnswer, error)
Score returns the ScoreAnswer for name, or an error if it is missing or a different answer type.
func (*Response) UnmarshalJSON ¶
UnmarshalJSON implements json.Unmarshaler, decoding each answer into its concrete type based on its "type" field.
type ResponseValidationError ¶
type ResponseValidationError struct {
// FieldPath is a dotted path to the offending field, such as
// "answers.tone.confidence".
FieldPath string
// Body is the raw response body that failed validation.
Body []byte
Err error
}
ResponseValidationError is returned when the server responds with a 2xx status but the body is missing or structurally invalid data required to build a typed result, such as an answer whose type does not match its question.
func (*ResponseValidationError) Error ¶
func (e *ResponseValidationError) Error() string
func (*ResponseValidationError) Unwrap ¶
func (e *ResponseValidationError) Unwrap() error
type RetryPolicy ¶
type RetryPolicy struct {
// MaxRetries is the maximum number of retries after the initial attempt.
// Zero disables retries. Default: 2.
MaxRetries int
// BackoffInitial is the first backoff delay, doubled on each subsequent
// attempt up to BackoffMax. Default: 500ms.
BackoffInitial time.Duration
// BackoffMax is the maximum backoff delay. Default: 5s.
BackoffMax time.Duration
// BackoffJitter is the fraction of each backoff delay randomly subtracted,
// from 0 to 1. Default: 0.25.
BackoffJitter float64
// HTTPStatuses is the set of HTTP status codes that are retried. Default:
// 408, 429, and 500-599.
HTTPStatuses map[int]bool
// RespectRetryAfter honors the Retry-After and retry-after-ms response
// headers (capped by MaxRetryAfter) instead of the computed backoff.
// Default: true.
RespectRetryAfter bool
// MaxRetryAfter is the maximum server-requested delay that will be
// honored; longer delays fall back to the computed backoff. Default: 60s.
MaxRetryAfter time.Duration
// RetryConnectionErrors retries requests that fail before receiving a
// response (DNS, TCP, TLS). Default: true.
RetryConnectionErrors bool
// RetryTimeoutErrors retries requests that exceed their per-attempt
// timeout. Default: true.
RetryTimeoutErrors bool
// Timeout is the total retry budget across the initial attempt and all
// retries, including backoff delays. Zero disables the budget. Default: 30s.
Timeout time.Duration
}
RetryPolicy configures how the client retries failed requests. The zero value is not usable directly; construct one with DefaultRetryPolicy and override the fields you need.
Partial overrides passed via WithRetryPolicy on a per-call RequestOption inherit unset fields from the client's policy; there is no automatic merging for a hand-built RetryPolicy, so start from DefaultRetryPolicy.
func DefaultRetryPolicy ¶
func DefaultRetryPolicy() RetryPolicy
DefaultRetryPolicy returns the SDK's default retry configuration, matching the official Python and JavaScript SDKs.
type ScoreAnswer ¶
type ScoreAnswer struct {
// Score is the probability-weighted result across the rubric's levels; it
// may fall between two integer levels.
Score float64 `json:"score"`
// Legend maps each integer level (as a string key, e.g. "0") back to the
// level description supplied in the question.
Legend map[string]any `json:"legend"`
// Probabilities maps each integer level (as a string key) to its
// probability; the values sum to 1.
Probabilities map[string]float64 `json:"probabilities"`
// Confidence is derived from the probability distribution, from 0 to 1.
Confidence float64 `json:"confidence"`
}
ScoreAnswer is the answer to a ScoreQuestion.
func (ScoreAnswer) Type ¶
func (ScoreAnswer) Type() string
type ScoreQuestion ¶
type ScoreQuestion struct {
// Instructions describes what the model should rate.
Instructions any
// Criteria is an ordered list of level descriptions; at least two levels
// are required. Level index 0 is the low end of the scale.
Criteria []any
}
ScoreQuestion rates the state along an ordered rubric. See https://docs.typesafe.ai/primitives/score.
func Score ¶
func Score(instructions string, levels ...any) ScoreQuestion
Score builds a Score question from plain-text instructions and at least two ordered level descriptions (strings or structured values).
func (ScoreQuestion) MarshalJSON ¶
func (q ScoreQuestion) MarshalJSON() ([]byte, error)
MarshalJSON implements json.Marshaler.
type StdLogger ¶
type StdLogger struct {
// contains filtered or unexported fields
}
StdLogger adapts the standard library's *log.Logger to the Logger interface, for quick debugging via WithLogger(typesafe.NewStdLogger(nil)).
func NewStdLogger ¶
NewStdLogger wraps l (or log.Default() if nil) as a Logger.
type SystemOneRequest ¶
type SystemOneRequest struct {
// State is the content to evaluate: a string, or JSON-marshalable
// structured data (object or array). See
// https://docs.typesafe.ai/concepts/state.
State any
// Questions is the named set of questions to answer about State. Must
// contain at least one entry.
Questions Questions
// Model overrides the client's default model for this call.
Model string
}
SystemOneRequest is the input to Client.SystemOne.
type TimeoutError ¶
type TimeoutError struct {
ConnectionError
// Timeout is the per-attempt timeout that was exceeded.
Timeout time.Duration
}
TimeoutError is returned when a request exceeds its configured per-attempt timeout. It is a *ConnectionError so errors.As(&ConnectionError{}) matches both; use errors.As(&TimeoutError{}) to distinguish a timeout specifically.
func (*TimeoutError) Error ¶
func (e *TimeoutError) Error() string
type UnprocessableEntityError ¶
type UnprocessableEntityError struct{ *APIError }
UnprocessableEntityError wraps a 422 response: the request failed server validation, for example a missing required field or a malformed question.
func (*UnprocessableEntityError) Unwrap ¶
func (e *UnprocessableEntityError) Unwrap() error
Unwrap allows errors.As/errors.Is to reach the underlying *APIError.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
examples
|
|
|
models
command
Command models lists the models available to the account.
|
Command models lists the models available to the account. |
|
quickstart
command
Command quickstart sends a single SystemOne call combining all three question primitives (Noul, Choice, Score) and prints the typed answers.
|
Command quickstart sends a single SystemOne call combining all three question primitives (Noul, Choice, Score) and prints the typed answers. |
|
retry
command
Command retry shows how to customize retry behavior, both for the whole client and for a single call, and how to inspect a rate-limit error.
|
Command retry shows how to customize retry behavior, both for the whole client and for a single call, and how to inspect a rate-limit error. |