systemone

package
v1.2.7 Latest Latest
Warning

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

Go to latest
Published: Oct 2, 2026 License: MIT Imports: 14 Imported by: 0

Documentation

Overview

Package systemone implements a client for the System One (Jev) decision protocol, `POST {baseURL}/v1/systemone`, served by Ollama >= 0.35, TypeSafe Jev and Jev-compatible gateways, plus the decision-provider layer (discovery, health, warm-up) built on top of it.

The package deliberately does not depend on internal/config: callers pass plain Options.

Index

Constants

View Source
const (
	// MaxBodyBytes is the request body cap enforced by Ollama (and locally).
	MaxBodyBytes = 64 * 1024
	// MaxQuestions is the maximum number of questions per request.
	MaxQuestions = 64
	// MinChoiceCriteria / MaxChoiceCriteria bound a choice question.
	MinChoiceCriteria = 2
	MaxChoiceCriteria = 26
	// DefaultTimeout is used when Options.Timeout is zero.
	DefaultTimeout = 30 * time.Second
)
View Source
const DefaultHealthTTL = 30 * time.Second

DefaultHealthTTL is the health cache lifetime.

View Source
const OllamaPullHint = "ollama pull tev1:0.8b"

OllamaPullHint is the suggestion shown when no decision model is installed.

Variables

View Source
var (
	// ErrUnreachable means the backend could not be contacted (connection refused, DNS, ...).
	ErrUnreachable = errors.New("systemone: backend unreachable")
	// ErrUnauthorized maps HTTP 401/403.
	ErrUnauthorized = errors.New("systemone: unauthorized")
	// ErrModelNotFound maps HTTP 404.
	ErrModelNotFound = errors.New("systemone: model not found")
	// ErrBadRequest maps HTTP 400 (including Ollama ":cloud" models).
	ErrBadRequest = errors.New("systemone: bad request")
	// ErrTooLarge maps HTTP 413 and the local 64 KiB body cap.
	ErrTooLarge = errors.New("systemone: request too large")
	// ErrRateLimited maps HTTP 429.
	ErrRateLimited = errors.New("systemone: rate limited")
	// ErrServer maps HTTP 5xx.
	ErrServer = errors.New("systemone: server error")
	// ErrTimeout means the per-call deadline elapsed.
	ErrTimeout = errors.New("systemone: timeout")
	// ErrMalformedResponse means the body was not valid JSON, an answer was
	// missing, or a choice is not among the question criteria.
	ErrMalformedResponse = errors.New("systemone: malformed response")

	// ErrUnavailable is a convenience class: errors.Is(err, ErrUnavailable) is
	// true for ErrUnreachable and ErrServer.
	ErrUnavailable = errors.New("systemone: backend unavailable")
	// ErrMalformed is an alias of ErrMalformedResponse.
	ErrMalformed = ErrMalformedResponse
)

Sentinel errors returned (wrapped in *APIError) by the System One client. Use errors.Is to classify a failure.

View Source
var SuggestedOllamaModels = []string{"tev1:0.8b", "tev1", "nimble"}

SuggestedOllamaModels are the decision models Pando offers to pull.

Functions

func IsSuggestedOllamaModel

func IsSuggestedOllamaModel(name string) bool

IsSuggestedOllamaModel reports whether name is a suggested decision model (an exact suggestion or another tag of a suggested model family).

func MissingSuggestedOllamaModels

func MissingSuggestedOllamaModels(installed []string) []string

MissingSuggestedOllamaModels returns the suggested models absent from installed (compared case-insensitively, with or without a ":latest" tag).

func Warmup

func Warmup(ctx context.Context, p DecisionProvider, model string) error

Warmup loads the router model into memory. For Ollama it sends one tiny request carrying keep_alive so the model stays resident; remote providers need no warm-up and this is a no-op.

Types

type APIError

type APIError struct {
	Status  int
	Message string
	Kind    error
}

APIError is the concrete error type returned by the client. Status is the HTTP status (0 when no response was received), Kind one of the sentinels.

func (*APIError) Error

func (e *APIError) Error() string

func (*APIError) Is

func (e *APIError) Is(target error) bool

Is additionally matches the ErrUnavailable class.

func (*APIError) Unwrap

func (e *APIError) Unwrap() error

Unwrap exposes the sentinel kind to errors.Is / errors.As.

type Answer

type Answer struct {
	Type          string             `json:"type"`
	Choice        string             `json:"choice"`
	Probabilities map[string]float64 `json:"probabilities"`
	Confidence    float64            `json:"confidence"`
	Score         *float64           `json:"score,omitempty"`
}

Answer is the decoded answer to one question.

type Client

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

Client talks to a System One endpoint. It is safe for concurrent use and never retries.

func NewClient

func NewClient(o Options) *Client

NewClient builds a Client.

func (*Client) BaseURL

func (c *Client) BaseURL() string

BaseURL returns the configured root URL.

func (*Client) Decide

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

Decide sends one System One request. No internal retry is performed.

func (*Client) DecideLenient

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

DecideLenient is Decide without the per-question answer check: a missing answer or a choice outside the criteria is returned as is, so a caller that asked several questions can judge each answer on its own.

func (*Client) KeepAlive

func (c *Client) KeepAlive() string

KeepAlive returns the configured Ollama keep_alive.

func (*Client) Timeout

func (c *Client) Timeout() time.Duration

Timeout returns the per-call bound.

type Criterion

type Criterion struct {
	Key         string
	Description *string
}

Criterion is one ordered entry of a choice question. A nil Description marshals as JSON null.

func NewCriterion

func NewCriterion(key, description string) Criterion

NewCriterion builds a Criterion; an empty description becomes null.

type DecisionModel

type DecisionModel struct {
	ID            string   `json:"id"`
	Name          string   `json:"name"`
	ContextWindow int      `json:"contextWindow,omitempty"`
	Capabilities  []string `json:"capabilities,omitempty"`
}

DecisionModel describes a model usable as a router.

type DecisionProvider

type DecisionProvider interface {
	Kind() ProviderKind
	Client() *Client
	// ListDecisionModels lists router candidates. showAll returns every model
	// the backend exposes instead of only decision models.
	ListDecisionModels(ctx context.Context, showAll bool) ([]DecisionModel, ListStatus, error)
	// Health probes reachability, auth, version, model presence and latency.
	Health(ctx context.Context, model string) HealthReport
	// ContextBudget returns the router model's context budget in tokens.
	ContextBudget(ctx context.Context, model string) int
}

DecisionProvider is a System One backend.

func NewProvider

func NewProvider(kind ProviderKind, o Options) (DecisionProvider, error)

NewProvider builds the provider for kind.

type HealthCache

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

HealthCache memoises HealthReports per (kind, baseURL, key fingerprint, model) so that status polling does not hammer the backend.

func NewHealthCache

func NewHealthCache(ttl time.Duration) *HealthCache

NewHealthCache builds a cache; ttl <= 0 uses DefaultHealthTTL.

func (*HealthCache) Get

Get returns a cached report or probes the provider.

func (*HealthCache) Invalidate

func (h *HealthCache) Invalidate()

Invalidate drops every cached report (call on config change).

type HealthReport

type HealthReport struct {
	OK         bool         `json:"ok"`
	Kind       ProviderKind `json:"kind"`
	Model      string       `json:"model"`
	Version    string       `json:"version,omitempty"`
	Reachable  bool         `json:"reachable"`
	Authorized bool         `json:"authorized"`
	VersionOK  bool         `json:"versionOK"`
	ModelFound bool         `json:"modelPresent"`
	IsDecision bool         `json:"isDecisionModel"`
	Remote     bool         `json:"remote"`
	LatencyMs  int64        `json:"latencyMs"`
	Problems   []string     `json:"problems"`
}

HealthReport is the outcome of a provider health probe.

type ListStatus

type ListStatus string

ListStatus qualifies the result of ListDecisionModels.

const (
	// ListFiltered: the list is authoritative (only decision models).
	ListFiltered ListStatus = "filtered"
	// ListUnfiltered: the backend exposes no decision metadata; the list was
	// narrowed heuristically (or is the raw catalogue) and the UI may offer
	// the full list via showAll.
	ListUnfiltered ListStatus = "unfiltered"
	// ListUnsupported: the backend cannot list models; the id must be typed.
	ListUnsupported ListStatus = "unsupported"
)

type Options

type Options struct {
	BaseURL string            // root URL, without /v1/systemone
	APIKey  string            // optional; sent as "Authorization: Bearer <key>"
	Headers map[string]string // extra headers sent on every request
	Timeout time.Duration     // per-call bound; DefaultTimeout when zero
	// HTTPClient overrides the transport (tests). Timeout is enforced through
	// the request context, not through HTTPClient.Timeout.
	HTTPClient *http.Client

	// Provider-level knobs (ignored by the raw client).
	KeepAlive     string // Ollama keep_alive for probes/warm-up; default "30m"
	ContextBudget int    // default context budget (tokens) for custom providers
}

Options configures a Client.

type ProviderKind

type ProviderKind string

ProviderKind identifies a decision backend.

const (
	KindOllama   ProviderKind = "ollama"
	KindTypeSafe ProviderKind = "typesafe"
	KindCustom   ProviderKind = "custom"
)

type Question

type Question struct {
	Type         string // "choice", "noul" or "score"
	Instructions any    // string | object | array; required by the server
	Criteria     []Criterion
	// Extra holds additional type-specific fields merged into the question
	// object (e.g. score bounds).
	Extra map[string]any
}

Question is one System One question. Criteria is an ordered slice because the order of criteria is significant to the model; it marshals as a JSON object preserving insertion order.

func (Question) MarshalJSON

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

MarshalJSON emits {"type":..,"instructions":..,"criteria":{ordered}, ...extra}.

type Request

type Request struct {
	Model     string              `json:"model"`
	State     any                 `json:"state"`
	Questions map[string]Question `json:"questions"`
	KeepAlive string              `json:"keep_alive,omitempty"`
}

Request is the System One request body.

type Response

type Response struct {
	Model   string            `json:"model"`
	Answers map[string]Answer `json:"answers"`
	Usage   Usage             `json:"usage"`
}

Response is the System One response body.

type Usage

type Usage struct {
	InputTokens  int      `json:"input_tokens"`
	OutputTokens int      `json:"output_tokens"`
	Cost         *float64 `json:"cost,omitempty"`
}

Usage reports token usage and, on gateways, the cost.

Directories

Path Synopsis
Package systemonetest provides a scriptable fake System One server that emulates Ollama 0.35 and Jev-compatible remote gateways.
Package systemonetest provides a scriptable fake System One server that emulates Ollama 0.35 and Jev-compatible remote gateways.

Jump to

Keyboard shortcuts

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