jev

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Oct 6, 2026 License: MIT Imports: 16 Imported by: 0

Documentation

Overview

Package jev is the typed client for TypeSafe AI's closed-set SystemOne API (https://api.typesafe.ai/v1/systemone). Jev is a classifier, not an LLM: callers send state text plus a set of typed questions and get back one typed answer per question.

Failures carry an Error whose Code mirrors the ralph exit-code taxonomy: CodeDeclined (1), CodeTransport (2) and CodeRejected (3).

Index

Constants

View Source
const (
	DefaultEndpoint   = "https://api.typesafe.ai/v1/systemone"
	DefaultModel      = "jev-latest"
	DefaultTimeout    = 4000 * time.Millisecond
	DefaultMaxRetries = 2

	// MaxTokens is the request budget; BytesPerToken is the deliberately
	// conservative estimate (jev is unreliable at counting itself).
	MaxTokens     = 32000
	BytesPerToken = 4

	TransportFixture = "fixture"
)
View Source
const MaxChoiceOptions = 255

MaxChoiceOptions is the per-question cap on choice criteria entries.

Variables

View Source
var ErrNoAnswers = errors.New("response missing answers")

ErrNoAnswers is returned when a response body lacks the `answers` object.

Functions

func IsLiteralJSON

func IsLiteralJSON(s string) bool

IsLiteralJSON reports whether s, once trimmed, is literal JSON text (a quoted string, an object or an array) that [wireText] would embed on the wire as-is rather than wrap as a plain string. A caller redacting a State or Instructions value before it reaches the wire can use this to choose JSON-aware redaction over plain-string redaction for the same text.

func Null

func Null() json.RawMessage

Null is the JSON null criteria value: the option or level speaks for itself and needs no further description.

func Str

func Str(s string) json.RawMessage

Str wraps a plain string as a criteria value: the ergonomic default for a Choice, Noul or Score criteria entry.

Types

type Answer

type Answer interface {
	// contains filtered or unexported methods
}

Answer is a sealed set: NoulAnswer, ChoiceAnswer and ScoreAnswer.

type Attempt

type Attempt struct {
	Model         string
	Status        int
	Success       bool
	Usage         Usage
	UsageReported bool
}

type Breaker

type Breaker interface {
	IsOpen() bool
	// Open force-opens the breaker (config errors: HTTP 401/422).
	Open(reason string)
	// RecordFailure counts a failure; two consecutive failures open it.
	RecordFailure(reason string)
	RecordSuccess()
}

Breaker is the circuit breaker the client consults and updates. The persistent implementation lives in internal/breaker; MemoryBreaker is the default.

type ChoiceAnswer

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

ChoiceAnswer is the answer to a choice question.

type ChoiceQuestion

type ChoiceQuestion struct {
	Instructions string
	Criteria     map[string]json.RawMessage
}

ChoiceQuestion asks for one of a closed set of options. Criteria is required: option label to description, where each description is a plain string (the ergonomic default), or arbitrary JSON (object, array or null when the label alone is self-explanatory).

func (ChoiceQuestion) MarshalJSON

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

type Client

type Client struct {
	Config Config
	// Key returns the API key; it is only called for live transport.
	Key     func() (string, error)
	HTTP    *http.Client
	Breaker Breaker
	// Sleep is the backoff wait; defaults to a context-aware time.Sleep.
	Sleep func(ctx context.Context, d time.Duration)
	// ObserveAttempt receives accounting metadata for every transport attempt.
	// It never receives request or response content.
	ObserveAttempt func(Attempt)
}

Client posts questions to SystemOne.

func New

func New(cfg Config, key func() (string, error)) *Client

New returns a Client with a MemoryBreaker and default HTTP client.

func (*Client) Ask

func (c *Client) Ask(ctx context.Context, req Request) (*Response, error)

Ask validates req, then posts it (or replays a fixture) and returns the strictly decoded response. All errors are *Error.

type Code

type Code int

Code is the failure taxonomy shared with ralph's exit codes.

const (
	// CodeDeclined means jev is unavailable and the caller should silently
	// fall back (breaker open, unknown question set).
	CodeDeclined Code = 1
	// CodeTransport covers transport, HTTP and protocol errors.
	CodeTransport Code = 2
	// CodeRejected means the input was rejected before any network use.
	CodeRejected Code = 3
)

func CodeOf

func CodeOf(err error) Code

CodeOf returns the taxonomy code of err, or 0 if it is not an *Error.

type Config

type Config struct {
	Endpoint   string
	Model      string
	Timeout    time.Duration
	MaxRetries int
	// Transport is "" (live HTTPS) or TransportFixture.
	Transport  string
	FixtureDir string
}

Config holds client settings, normally read from JEVKIT_* variables.

func ConfigFromEnv

func ConfigFromEnv(getenv func(string) string) Config

ConfigFromEnv builds a Config from getenv (os.Getenv in production): JEVKIT_ENDPOINT, JEVKIT_MODEL, JEVKIT_TIMEOUT_MS, JEVKIT_MAX_RETRIES, JEVKIT_TRANSPORT and JEVKIT_FIXTURE_DIR.

type Error

type Error struct {
	Code   Code
	Reason string
	// Config marks errors that retrying cannot fix (HTTP 401/422).
	Config bool
	Err    error
}

Error is the error type returned by the client.

func (*Error) Error

func (e *Error) Error() string

func (*Error) Unwrap

func (e *Error) Unwrap() error

type MemoryBreaker

type MemoryBreaker struct {
	Reason string
	// contains filtered or unexported fields
}

MemoryBreaker is an in-process Breaker.

func (*MemoryBreaker) IsOpen

func (b *MemoryBreaker) IsOpen() bool

func (*MemoryBreaker) Open

func (b *MemoryBreaker) Open(reason string)

func (*MemoryBreaker) RecordFailure

func (b *MemoryBreaker) RecordFailure(reason string)

func (*MemoryBreaker) RecordSuccess

func (b *MemoryBreaker) RecordSuccess()

type NoulAnswer

type NoulAnswer struct{ Noul float64 }

NoulAnswer is the answer to a noul question.

type NoulQuestion

type NoulQuestion struct {
	Instructions string
	Criteria     map[string]json.RawMessage
}

NoulQuestion asks a yes/no style question answered with a value in [0,1]. Criteria is optional: it may hold a "true" and/or a "false" entry, each a plain string (the ergonomic default), or arbitrary JSON (object, array or null).

func (NoulQuestion) MarshalJSON

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

type Question

type Question interface {
	// contains filtered or unexported methods
}

Question is a sealed set: NoulQuestion, ChoiceQuestion and ScoreQuestion.

type Request

type Request struct {
	QuestionSetID string `json:"-"`
	// State is a plain string (the ergonomic default) or literal JSON text
	// (a quoted string, an object or an array); see [wireText].
	State     string              `json:"-"`
	Model     string              `json:"model"`
	Questions map[string]Question `json:"questions"`
}

Request is one SystemOne call. QuestionSetID is local routing metadata (fixture lookup, decision records); it is never serialized onto the wire.

func (Request) MarshalJSON

func (r Request) MarshalJSON() ([]byte, error)

MarshalJSON encodes the wire body: State is expanded per [wireText] and QuestionSetID never appears.

func (Request) Validate

func (r Request) Validate() error

Validate checks req against the local typed schema, without making a request: at least one question, each with a non-empty id and a valid question body per its own kind (Choice 1-255 distinct criteria keys, Score 2-10 ordered levels, valid JSON criteria value types, and so on). Client.Ask also calls this before it builds the wire body, so a caller that validates first only sees the same rejection earlier and offline.

type Response

type Response struct {
	Model         string
	Answers       map[string]Answer
	Usage         Usage
	UsageReported bool
}

Response is a decoded SystemOne response.

func DecodeResponse

func DecodeResponse(data []byte) (*Response, error)

DecodeResponse strictly decodes a response body: it must be a JSON object with an `answers` object whose members are recognizable typed answers.

type ScoreAnswer

type ScoreAnswer struct {
	Score        float64
	Confidence   float64
	Legend       []string
	Distribution map[string]float64
	// Raw fields retain response shapes that the typed display fields do not
	// understand yet, so offline calibration can replay them without loss.
	RawLegend       json.RawMessage
	RawDistribution json.RawMessage
}

ScoreAnswer is the answer to a score question. Legend and Distribution are populated only when SystemOne returns them: Legend is the ordered level labels (low to high) and Distribution maps each label to its probability.

type ScoreQuestion

type ScoreQuestion struct {
	Instructions string
	Criteria     []json.RawMessage
}

ScoreQuestion asks for a numeric score against an ordered rubric. Criteria is required: 2-10 levels ordered low to high, each a plain string (the ergonomic default) or arbitrary JSON (object or array).

func (ScoreQuestion) MarshalJSON

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

type Usage

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

Usage reports token accounting from the API.

Jump to

Keyboard shortcuts

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