typesafe

package module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 18, 2026 License: MIT Imports: 15 Imported by: 0

README

TypeSafe AI Go SDK

CI PkgGoDev

A client for TypeSafe AI. The wire format and default retry behavior follow the Python SDK v0.6.0, with a smaller, Go-native API.

Quick start

Requires Go 1.26 or later. The module declares go 1.26 as its minimum; CI tests that version and the latest stable release.

go get github.com/RadixILS-Dev/typesafe-sdk-go
export TYPESAFE_API_KEY='your-api-key'

Import github.com/RadixILS-Dev/typesafe-sdk-go as package typesafe:

client, err := typesafe.NewClient()
if err != nil {
    log.Fatal(err)
}
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()

result, err := client.SystemOne(ctx, "I was charged twice. Please help ASAP.", typesafe.Questions{
    "billing": typesafe.Noul{Instructions: "Is this about billing?"},
    "tone": typesafe.Choice{
        Instructions: "What is the tone?",
        Criteria: map[string]string{"calm": "", "angry": ""},
    },
    "urgency": typesafe.Score{
        Instructions: "How urgent is this?",
        Criteria: []string{"low", "medium", "high"},
    },
})
if err != nil {
    log.Fatal(err)
}
fmt.Println(result.Nouls["billing"].Noul, result.Choices["tone"].Choice, result.Scores["urgency"].Score)

The complete program is in examples/basic/main.go. go run ./examples/basic makes a real API request.

Configuration

NewClient() uses environment variables and defaults. For explicit settings:

client, err := typesafe.NewClient(
    typesafe.WithAPIKey("your-api-key"),
    typesafe.WithModel("jev-latest"),
    typesafe.WithMaxAttempts(1), // No retries.
)

WithAPIKey, WithBaseURL, and WithModel override TYPESAFE_API_KEY, TYPESAFE_BASE_URL, and TYPESAFE_DEFAULT_MODEL. Options apply in order; the last option for a setting wins. Blank environment values are ignored. The defaults are https://api.typesafe.ai and jev-latest; an API key is required. WithMaxAttempts accepts a positive total attempt count (default three).

The default HTTP client has a 10-second timeout per attempt and does not follow redirects. Use WithHTTPClient to control timeouts, redirects, transport, or instrumentation. It is used unchanged, not copied, reconfigured, or closed; a supplied client with a zero timeout has no per-attempt timeout. Contexts bound the entire call, including retry waits. Clients are safe for concurrent calls; do not mutate a shared HTTP client or request data during use.

Questions and results

Questions maps names to Noul, Choice, Score, or raw JSON objects. Typed questions add their own type tags. State, instructions, and descriptions can contain structured JSON. For example, Choice.Criteria accepts map[string]any{"billing": nil} and Score.Criteria accepts []any.

Nil optional fields are omitted; explicit empty strings remain empty strings, not JSON null. Raw question objects (map[string]any) are sent unchanged. The API validates question schemas, including empty questions and score rubrics. Serialization errors are returned before sending.

Results contain Nouls, Choices, Scores, Model, Usage, and RequestID:

  • Noul: Noul is the probability of yes.
  • Choice: Choice, Confidence, and label-keyed Probabilities.
  • Score: Score, Confidence, and integer-keyed Legend and Probabilities.
  • Usage: *int64 counts distinguish missing values from zero.

RawAnswers retains every answer's original JSON, including unknown types and extra fields. Unknown types do not appear in the typed maps. Use normal Go map lookup checks when an answer may be absent. Missing or malformed required fields in known answers return an error instead of silently becoming zero values.

Model listing is a direct call:

models, err := client.ListModels(ctx)
// models.Models contains Name, Description, and ReleaseDate.

Convenience methods

These helpers use SystemOne, including the client's model, retries, and context handling. Both state and instructions accept text or structured JSON.

Method Purpose Result
Pick(ctx, state, instructions, candidates) Select a supplied span, or typesafe.NoneChoice ("none") ChoiceAnswer, error
Classify(ctx, state, instructions, options) Select from a fixed label set; no automatic fallback ChoiceAnswer, error
IsTrue(ctx, state, instructions) Evaluate a yes/no question float64, error — probability of yes
document := "Invoice total: USD 42.00"

picked, err := client.Pick(ctx, document, "Which amount is the invoice total?",
    []string{"USD 42.00", "USD 21.00"})
if err != nil {
    log.Fatal(err)
}
fmt.Println(picked.Choice, picked.Confidence)

classified, err := client.Classify(ctx, document, "Which currency is used?",
    []string{"USD", "EUR", "GBP"})
if err != nil {
    log.Fatal(err)
}
fmt.Println(classified.Choice, classified.Confidence)

probability, err := client.IsTrue(ctx, document, "Does this state an invoice total?")
if err != nil {
    log.Fatal(err)
}
fmt.Println(probability)

Pick does not extract candidate spans; the caller supplies them. Candidate text is preserved exactly, without trimming or normalization. The label "none" is reserved in Pick; passing it as a candidate returns an error. It is allowed as an ordinary label in Classify. Duplicate labels collapse into one option, just as they do in the Python cookbook's dictionaries. An empty candidate list still makes a request containing only the no-match option; an empty classification list is sent to the API for validation.

Choice results also include Probabilities. A missing/wrong-type answer or a selection outside the supplied options returns ResponseError, not a silent zero value. IsTrue does not apply a threshold. These are single-question calls; use SystemOne when batching questions or accessing usage and raw responses.

Candidate extraction example

examples/extraction/main.go finds email addresses with a regex, deduplicates them in document order, and uses Pick to select the receipt destination and From address independently. Normalization stays in application code, after selection.

For the sample document, the intended selections are dana.personal@gmail.com for the receipt and dana.whit@acme-corp.com for the sender. Actual selections and confidence values come from the model; the example handles a no-match result.

Examples

Every example is a runnable program in its own package. All of them make real API requests and need TYPESAFE_API_KEY.

Example Demonstrates
examples/basic One SystemOne call with a Noul, Choice, and Score question
examples/claims Many Noul questions in one call over a JSON claim file, cross-checked offline
examples/extraction Regex candidates plus Pick per role, with no-match handling
examples/phone Pick and Classify over one shared candidate list
# Each needs TYPESAFE_API_KEY and makes live calls.
go run ./examples/basic

The parts that can be checked offline are plain functions with their own tests:

go test ./examples/...   # offline helpers only; no API access

examples/claims shows the pattern for a batch of related yes/no questions: one SystemOne call carries the whole claim file, each answer keeps its own probability, and the answers that can be computed from the file (dates, amounts, coverage flags) are recomputed in Go and compared. Any DISAGREE line, and any answer missing from the response, is reported rather than defaulted.

Runnable, offline godoc examples, including *APIError handling, live in example_test.go and appear on pkg.go.dev.

Retries and errors

The client retries HTTP 408, 429, 5xx, and transport/read failures, up to the attempt limit set by WithMaxAttempts. Backoff starts at 500 ms, doubles up to 5 seconds, and subtracts up to 25% jitter. retry-after-ms takes precedence over Retry-After (seconds or HTTP date). A fixed 30-second scheduling budget prevents starting a retry whose delay would reach that budget; it does not interrupt an in-flight request. Use a context deadline for a hard limit. Caller cancellation is never retried.

  • *APIError exposes StatusCode, Message, Body, Headers, and RequestID.
  • *ResponseError identifies invalid response data by FieldPath and RequestID.
  • Transport and context errors preserve their native causes for errors.Is and errors.As; inspect net.Error for transport timeouts.

Errors are returned to the caller to handle or log. The SDK does not install a logger or log request bodies, credentials, or headers.

Development

go build ./...        # library and examples
go test -race ./...
go vet ./...
gofmt -l .            # must print nothing
staticcheck ./...     # optional; CI runs it

Tests use local servers and injected transports, not the live TypeSafe API, so they pass offline and under -race. Only the programs under examples/ make real requests, and only when you run them.

CI (.github/workflows/ci.yml) runs all of the above on Go 1.26 and the latest stable release, checks that go.mod is tidy, and rejects a release tag whose name does not match the Version constant. See CONTRIBUTING.md for the release checklist, CHANGELOG.md for released changes, and SECURITY.md for reporting issues and credential guidance.

Documentation

Overview

Package typesafe provides a Go client for the TypeSafe AI System One API.

Create a client with NewClient, then ask named Noul, Choice, and Score questions with Client.SystemOne. Clients may be shared by concurrent goroutines. Each call accepts a context that controls the entire operation, including retries.

Index

Examples

Constants

View Source
const (
	DefaultBaseURL = "https://api.typesafe.ai"
	DefaultModel   = "jev-latest"
	Version        = "0.1.0"
)
View Source
const NoneChoice = "none"

NoneChoice is Pick's fallback when none of the candidate spans fits.

Variables

This section is empty.

Functions

This section is empty.

Types

type APIError

type APIError struct {
	StatusCode int
	Body       any
	Headers    http.Header
	RequestID  string
	Endpoint   string
	Message    string
}

APIError describes an unsuccessful HTTP response. Use errors.As to inspect it and StatusCode to distinguish authentication, rate limits, and other failures.

Example
package main

import (
	"bytes"
	"context"
	"errors"
	"fmt"
	"io"
	"log"
	"net/http"

	"github.com/RadixILS-Dev/typesafe-sdk-go"
)

// stubTransport returns canned JSON so these examples run offline and print
// deterministic output. Real programs can omit WithHTTPClient and use the
// SDK's default client, or supply their own for timeouts and instrumentation.
type stubTransport struct {
	status  int
	body    string
	headers http.Header
}

func (s stubTransport) RoundTrip(request *http.Request) (*http.Response, error) {
	headers := s.headers.Clone()
	if headers == nil {
		headers = http.Header{}
	}
	status := s.status
	if status == 0 {
		status = http.StatusOK
	}
	return &http.Response{
		StatusCode: status,
		Status:     fmt.Sprintf("%d %s", status, http.StatusText(status)),
		Header:     headers,
		Body:       io.NopCloser(bytes.NewBufferString(s.body)),
		Request:    request,
	}, nil
}

func stubClient(status int, headers http.Header, body string) *http.Client {
	return &http.Client{Transport: stubTransport{status: status, body: body, headers: headers}}
}

func main() {
	responseHeaders := http.Header{}
	responseHeaders.Set("X-TypeSafe-Request-ID", "req-42")
	responseHeaders.Set("Retry-After", "2")

	client, err := typesafe.NewClient(
		typesafe.WithAPIKey("your-api-key"),
		typesafe.WithMaxAttempts(1), // Disable retries to inspect the first response.
		typesafe.WithHTTPClient(stubClient(http.StatusTooManyRequests, responseHeaders,
			`{"message":"Rate limit exceeded"}`)),
	)
	if err != nil {
		log.Fatal(err)
	}

	_, err = client.ListModels(context.Background())
	var api *typesafe.APIError
	switch {
	case errors.As(err, &api) && api.StatusCode == http.StatusTooManyRequests:
		fmt.Printf("%d %s (request %s, retry after %ss)\n",
			api.StatusCode, api.Message, api.RequestID, api.Headers.Get("Retry-After"))
	case err != nil:
		log.Fatal(err)
	}
}
Output:
429 Rate limit exceeded (request req-42, retry after 2s)

func (*APIError) Error

func (e *APIError) Error() string

type Choice

type Choice struct {
	Instructions any `json:"instructions,omitempty"`
	Criteria     any `json:"criteria"`
}

Choice selects a named option. Criteria accepts map[string]string for simple descriptions or map[string]any for structured descriptions and nil values. Empty strings are sent as empty strings, not converted to JSON null.

func (Choice) MarshalJSON

func (q Choice) MarshalJSON() ([]byte, error)

type ChoiceAnswer

type ChoiceAnswer struct {
	Choice        string
	Confidence    float64
	Probabilities map[string]float64
}

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client can be reused by concurrent goroutines. Configuration is fixed at construction.

func NewClient

func NewClient(options ...ClientOption) (*Client, error)

NewClient creates a client using environment variables and SDK defaults. Options override those settings in order; the last option for a setting wins. It does not mutate or close a supplied HTTP client, or make network requests.

Example
package main

import (
	"fmt"
	"log"

	"github.com/RadixILS-Dev/typesafe-sdk-go"
)

func main() {
	client, err := typesafe.NewClient(typesafe.WithAPIKey("your-api-key"))
	if err != nil {
		log.Fatal(err)
	}
	// Configuration is fixed at construction; the client is safe to share.
	fmt.Println("client ready:", client != nil)
}
Output:
client ready: true

func (*Client) Classify

func (c *Client) Classify(ctx context.Context, state any, instructions any, options []string) (ChoiceAnswer, error)

Classify selects one of the supplied labels without adding a no-match option. State and instructions may be text or structured JSON.

func (*Client) IsTrue

func (c *Client) IsTrue(ctx context.Context, state any, instructions any) (float64, error)

IsTrue returns the probability of yes, not a thresholded boolean. State and instructions may be text or structured JSON.

Example
package main

import (
	"bytes"
	"context"
	"fmt"
	"io"
	"log"
	"net/http"

	"github.com/RadixILS-Dev/typesafe-sdk-go"
)

// stubTransport returns canned JSON so these examples run offline and print
// deterministic output. Real programs can omit WithHTTPClient and use the
// SDK's default client, or supply their own for timeouts and instrumentation.
type stubTransport struct {
	status  int
	body    string
	headers http.Header
}

func (s stubTransport) RoundTrip(request *http.Request) (*http.Response, error) {
	headers := s.headers.Clone()
	if headers == nil {
		headers = http.Header{}
	}
	status := s.status
	if status == 0 {
		status = http.StatusOK
	}
	return &http.Response{
		StatusCode: status,
		Status:     fmt.Sprintf("%d %s", status, http.StatusText(status)),
		Header:     headers,
		Body:       io.NopCloser(bytes.NewBufferString(s.body)),
		Request:    request,
	}, nil
}

func stubClient(status int, headers http.Header, body string) *http.Client {
	return &http.Client{Transport: stubTransport{status: status, body: body, headers: headers}}
}

func main() {
	client, err := typesafe.NewClient(
		typesafe.WithAPIKey("your-api-key"),
		typesafe.WithHTTPClient(stubClient(http.StatusOK, nil,
			`{"model":"jev-latest","usage":{},"answers":{"q":{"type":"noul","noul":0.77}}}`)),
	)
	if err != nil {
		log.Fatal(err)
	}

	probability, err := client.IsTrue(context.Background(), "Invoice total: USD 42.00", "Does this state an invoice total?")
	if err != nil {
		log.Fatal(err)
	}
	// IsTrue returns a probability, not a thresholded boolean.
	fmt.Printf("%.2f\n", probability)
}
Output:
0.77

func (*Client) ListModels

func (c *Client) ListModels(ctx context.Context) (*ListModelsResponse, error)

ListModels lists the models available to the account.

Example
package main

import (
	"bytes"
	"context"
	"fmt"
	"io"
	"log"
	"net/http"

	"github.com/RadixILS-Dev/typesafe-sdk-go"
)

// stubTransport returns canned JSON so these examples run offline and print
// deterministic output. Real programs can omit WithHTTPClient and use the
// SDK's default client, or supply their own for timeouts and instrumentation.
type stubTransport struct {
	status  int
	body    string
	headers http.Header
}

func (s stubTransport) RoundTrip(request *http.Request) (*http.Response, error) {
	headers := s.headers.Clone()
	if headers == nil {
		headers = http.Header{}
	}
	status := s.status
	if status == 0 {
		status = http.StatusOK
	}
	return &http.Response{
		StatusCode: status,
		Status:     fmt.Sprintf("%d %s", status, http.StatusText(status)),
		Header:     headers,
		Body:       io.NopCloser(bytes.NewBufferString(s.body)),
		Request:    request,
	}, nil
}

func stubClient(status int, headers http.Header, body string) *http.Client {
	return &http.Client{Transport: stubTransport{status: status, body: body, headers: headers}}
}

func main() {
	client, err := typesafe.NewClient(
		typesafe.WithAPIKey("your-api-key"),
		typesafe.WithHTTPClient(stubClient(http.StatusOK, nil,
			`{"models":[{"name":"jev-latest","description":"Fastest model","release_date":"2026-09-14"}]}`)),
	)
	if err != nil {
		log.Fatal(err)
	}

	models, err := client.ListModels(context.Background())
	if err != nil {
		log.Fatal(err)
	}
	for _, model := range models.Models {
		fmt.Printf("%s released %s\n", model.Name, model.ReleaseDate)
	}
}
Output:
jev-latest released 2026-09-14

func (*Client) Pick

func (c *Client) Pick(ctx context.Context, state any, instructions any, candidates []string) (ChoiceAnswer, error)

Pick selects a candidate span verbatim, or NoneChoice if none fits. Candidates must not include the reserved NoneChoice label. It does not find spans in state; the caller supplies them. State and instructions may be text or structured JSON.

Example
package main

import (
	"bytes"
	"context"
	"fmt"
	"io"
	"log"
	"net/http"

	"github.com/RadixILS-Dev/typesafe-sdk-go"
)

// stubTransport returns canned JSON so these examples run offline and print
// deterministic output. Real programs can omit WithHTTPClient and use the
// SDK's default client, or supply their own for timeouts and instrumentation.
type stubTransport struct {
	status  int
	body    string
	headers http.Header
}

func (s stubTransport) RoundTrip(request *http.Request) (*http.Response, error) {
	headers := s.headers.Clone()
	if headers == nil {
		headers = http.Header{}
	}
	status := s.status
	if status == 0 {
		status = http.StatusOK
	}
	return &http.Response{
		StatusCode: status,
		Status:     fmt.Sprintf("%d %s", status, http.StatusText(status)),
		Header:     headers,
		Body:       io.NopCloser(bytes.NewBufferString(s.body)),
		Request:    request,
	}, nil
}

func stubClient(status int, headers http.Header, body string) *http.Client {
	return &http.Client{Transport: stubTransport{status: status, body: body, headers: headers}}
}

func main() {
	client, err := typesafe.NewClient(
		typesafe.WithAPIKey("your-api-key"),
		typesafe.WithHTTPClient(stubClient(http.StatusOK, nil,
			`{"model":"jev-latest","usage":{},"answers":{"q":{"type":"choice","choice":"USD 42.00","confidence":0.91,"probabilities":{"USD 42.00":0.91,"USD 21.00":0.09,"none":0.00}}}}`)),
	)
	if err != nil {
		log.Fatal(err)
	}

	answer, err := client.Pick(context.Background(), "Invoice total: USD 42.00",
		"Which amount is the invoice total?", []string{"USD 42.00", "USD 21.00"})
	if err != nil {
		log.Fatal(err)
	}
	if answer.Choice == typesafe.NoneChoice {
		fmt.Println("no candidate matched")
		return
	}
	// The winning candidate is returned verbatim, without trimming or rewriting.
	fmt.Printf("%s (%.2f)\n", answer.Choice, answer.Confidence)
}
Output:
USD 42.00 (0.91)

func (*Client) SystemOne

func (c *Client) SystemOne(ctx context.Context, state any, questions Questions) (*SystemOneResponse, error)

SystemOne evaluates named questions against JSON-serializable state. Question validation belongs to the API. The context bounds the entire call, including retry waits; each attempt sends the same encoded body.

Example
package main

import (
	"bytes"
	"context"
	"fmt"
	"io"
	"log"
	"net/http"

	"github.com/RadixILS-Dev/typesafe-sdk-go"
)

// stubTransport returns canned JSON so these examples run offline and print
// deterministic output. Real programs can omit WithHTTPClient and use the
// SDK's default client, or supply their own for timeouts and instrumentation.
type stubTransport struct {
	status  int
	body    string
	headers http.Header
}

func (s stubTransport) RoundTrip(request *http.Request) (*http.Response, error) {
	headers := s.headers.Clone()
	if headers == nil {
		headers = http.Header{}
	}
	status := s.status
	if status == 0 {
		status = http.StatusOK
	}
	return &http.Response{
		StatusCode: status,
		Status:     fmt.Sprintf("%d %s", status, http.StatusText(status)),
		Header:     headers,
		Body:       io.NopCloser(bytes.NewBufferString(s.body)),
		Request:    request,
	}, nil
}

func stubClient(status int, headers http.Header, body string) *http.Client {
	return &http.Client{Transport: stubTransport{status: status, body: body, headers: headers}}
}

const systemOneBody = `{"model":"jev-latest","usage":{"input_tokens":12,"output_tokens":3},"answers":{
	"billing":{"type":"noul","noul":0.98},
	"tone":{"type":"choice","choice":"angry","confidence":0.9,"probabilities":{"calm":0.1,"angry":0.9}},
	"urgency":{"type":"score","score":1.7,"confidence":0.8,"legend":{"0":"low","1":"medium","2":"high"},"probabilities":{"0":0.1,"1":0.1,"2":0.8}}}}`

func main() {
	client, err := typesafe.NewClient(
		typesafe.WithAPIKey("your-api-key"),
		typesafe.WithHTTPClient(stubClient(http.StatusOK, nil, systemOneBody)),
	)
	if err != nil {
		log.Fatal(err)
	}

	result, err := client.SystemOne(context.Background(), "I was charged twice. Please help ASAP.", typesafe.Questions{
		"billing": typesafe.Noul{Instructions: "Is this about billing?"},
		"tone": typesafe.Choice{
			Instructions: "What is the tone?",
			Criteria:     map[string]string{"calm": "", "angry": ""},
		},
		"urgency": typesafe.Score{
			Instructions: "How urgent is this?",
			Criteria:     []string{"low", "medium", "high"},
		},
	})
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("billing  %.2f\n", result.Nouls["billing"].Noul)
	fmt.Printf("tone     %s\n", result.Choices["tone"].Choice)
	fmt.Printf("urgency  %.1f\n", result.Scores["urgency"].Score)
	fmt.Printf("tokens   %d in / %d out\n", *result.Usage.InputTokens, *result.Usage.OutputTokens)
}
Output:
billing  0.98
tone     angry
urgency  1.7
tokens   12 in / 3 out

type ClientOption

type ClientOption func(*clientConfig)

ClientOption configures a client at construction.

func WithAPIKey

func WithAPIKey(key string) ClientOption

WithAPIKey overrides TYPESAFE_API_KEY.

func WithBaseURL

func WithBaseURL(url string) ClientOption

WithBaseURL overrides TYPESAFE_BASE_URL and the default API URL.

func WithHTTPClient

func WithHTTPClient(client *http.Client) ClientOption

WithHTTPClient uses the supplied non-nil client unchanged, including its timeout and redirect policy. The SDK does not mutate or close it.

func WithMaxAttempts

func WithMaxAttempts(attempts int) ClientOption

WithMaxAttempts sets the total number of attempts, including the initial request. The default is three; one disables retries. Must be positive.

func WithModel

func WithModel(model string) ClientOption

WithModel overrides TYPESAFE_DEFAULT_MODEL and the default model.

type ListModelsResponse

type ListModelsResponse struct {
	RequestID string
	Models    []ModelMetadata
}

type ModelMetadata

type ModelMetadata struct {
	Name        string
	Description string
	ReleaseDate string
}

type Noul

type Noul struct {
	Instructions any `json:"instructions,omitempty"`
	Criteria     any `json:"criteria,omitempty"`
}

Noul asks a yes/no question. Instructions may be a string, JSON object, or array. Nil optional fields are omitted; explicit empty strings are preserved.

func (Noul) MarshalJSON

func (q Noul) MarshalJSON() ([]byte, error)

type NoulAnswer

type NoulAnswer struct{ Noul float64 }

type NoulCriteria

type NoulCriteria map[string]any

NoulCriteria describes the "true" and "false" outcomes. Values may be strings, JSON objects, arrays, or nil. Extra keys are passed through to the API.

type Questions

type Questions map[string]any

Questions maps names to Noul, Choice, Score, or raw JSON question objects. Values are serialized unchanged; the API validates their shape.

Example

Questions are plain Go values: typed questions add their own "type" tag, and descriptions may be structured JSON. The API validates the result.

package main

import (
	"encoding/json"
	"fmt"
	"log"

	"github.com/RadixILS-Dev/typesafe-sdk-go"
)

func main() {
	questions := typesafe.Questions{
		"fraud": typesafe.Noul{
			Instructions: map[string]any{"question": "Is this refund suspicious?", "rules": []string{"Ignore tone."}},
			Criteria:     typesafe.NoulCriteria{"true": "Suspicious", "false": "Ordinary"},
		},
		"queue": typesafe.Choice{
			Instructions: "Which team should handle this?",
			Criteria:     map[string]any{"billing": nil, "chargeback": "Disputed card payment"},
		},
	}
	data, err := json.Marshal(questions)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(string(data))
}
Output:
{"fraud":{"type":"noul","instructions":{"question":"Is this refund suspicious?","rules":["Ignore tone."]},"criteria":{"false":"Ordinary","true":"Suspicious"}},"queue":{"type":"choice","instructions":"Which team should handle this?","criteria":{"billing":null,"chargeback":"Disputed card payment"}}}

type ResponseError

type ResponseError struct {
	FieldPath string
	RequestID string
	Err       error
}

ResponseError identifies missing or malformed required data in a successful response. Err preserves the underlying JSON error when available.

func (*ResponseError) Error

func (e *ResponseError) Error() string

func (*ResponseError) Unwrap

func (e *ResponseError) Unwrap() error

type Score

type Score struct {
	Instructions any `json:"instructions,omitempty"`
	Criteria     any `json:"criteria"`
}

Score evaluates an ordered rubric, with levels starting at zero. Criteria accepts []string or a slice/array of JSON descriptions (for example []any). The API validates the rubric.

func (Score) MarshalJSON

func (q Score) MarshalJSON() ([]byte, error)

type ScoreAnswer

type ScoreAnswer struct {
	Score         float64
	Confidence    float64
	Legend        map[int]any
	Probabilities map[int]float64
}

type SystemOneResponse

type SystemOneResponse struct {
	Model      string
	Usage      Usage
	RequestID  string
	RawAnswers map[string]json.RawMessage
	Nouls      map[string]NoulAnswer
	Choices    map[string]ChoiceAnswer
	Scores     map[string]ScoreAnswer
}

SystemOneResponse groups recognized answers by type. RawAnswers contains every answer, including unknown types and extra fields, without silently dropping data.

type Usage

type Usage struct {
	InputTokens  *int64 `json:"input_tokens"`
	OutputTokens *int64 `json:"output_tokens"`
}

Usage distinguishes unreported token counts (nil) from zero.

Directories

Path Synopsis
examples
basic command
claims command
This example adjudicates an auto-insurance claim: fourteen grounded yes/no questions go to SystemOne in a single call over one JSON claim file, and the answers are then cross-checked against arithmetic computed offline from that same file.
This example adjudicates an auto-insurance claim: fourteen grounded yes/no questions go to SystemOne in a single call over one JSON claim file, and the answers are then cross-checked against arithmetic computed offline from that same file.
extraction command
This example finds candidate strings in code, then asks TypeSafe which role each candidate plays.
This example finds candidate strings in code, then asks TypeSafe which role each candidate plays.
phone command
This example selects a phone number with Pick and an office country with Classify.
This example selects a phone number with Pick and an office country with Classify.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL