Documentation
¶
Overview ¶
Package classify defines task-oriented inference interfaces for non-LLM workloads. The primary surface is classifier interfaces — audio / text / image / video — that each take input bytes and return []LabelScore (categorical, ranked by confidence). Backends (HuggingFace Inference API, ONNX, Replicate, …) implement one or more of these; eval handlers depend on the task interface, never on the backend.
Parallel to runtime/tts and runtime/stt: each is a task interface with multiple backends behind it. runtime/providers handles chat completion (Predict); classify covers classification.
Embedder lives here for convenience — the HuggingFace Inference API exposes embedding (feature-extraction) models through the same endpoint family as classification models, so the HF backend satisfies Embedder as a side effect. It is NOT the canonical home for embedding providers. OpenAI, VoyageAI, and similar dedicated embedding APIs continue to register under `role: embedding` via the runtime/providers Embed() interface; cosine-similarity-style handlers depend on that path. Future embedder backends that happen to live in runtime/classify (e.g. an HF-hosted embedding model) are bridged into the same handler path via adapters, not by relocating providers. Treat Embedder here as a convenience surface, not a migration target.
TopicClassifier is the exception to the bytes-in/[]LabelScore-out shape: it takes a structured TopicRequest (a policy plus the message under judgment) and returns a TopicDecision, because a topic-scope verdict is not a ranked label set.
Index ¶
- Constants
- func RegisterBackend(reg *Registry, id string, b Backend) []string
- func RegisterBackendDefaulting(reg *Registry, id string, b Backend) []string
- func RegisterFactory(providerType string, f Factory)
- func RegisteredTypes() []string
- func ResolveCredential(ctx context.Context, providerType string, cfgDir string, ...) (credentials.Credential, error)
- func WithRegistry(ctx context.Context, r *Registry) context.Context
- type AudioChunk
- type AudioClassifier
- type AudioOptions
- type AudioStreamOptions
- type Backend
- type EmbedOptions
- type Embedder
- type Factory
- type ImageClassifier
- type ImageOptions
- type LabelScore
- type LabelScoreEvent
- type ProviderSpec
- type Registry
- func (r *Registry) AudioClassifier(id string) (AudioClassifier, error)
- func (r *Registry) Embedder(id string) (Embedder, error)
- func (r *Registry) ImageClassifier(id string) (ImageClassifier, error)
- func (r *Registry) RegisterAudio(id string, c AudioClassifier)
- func (r *Registry) RegisterEmbedder(id string, e Embedder)
- func (r *Registry) RegisterImage(id string, c ImageClassifier)
- func (r *Registry) RegisterText(id string, c TextClassifier)
- func (r *Registry) RegisterTopic(id string, c TopicClassifier)
- func (r *Registry) RegisterVideo(id string, c VideoClassifier)
- func (r *Registry) SetDefaultAudio(id string) error
- func (r *Registry) SetDefaultEmbedder(id string) error
- func (r *Registry) SetDefaultImage(id string) error
- func (r *Registry) SetDefaultText(id string) error
- func (r *Registry) SetDefaultTopic(id string) error
- func (r *Registry) SetDefaultVideo(id string) error
- func (r *Registry) TextClassifier(id string) (TextClassifier, error)
- func (r *Registry) TopicClassifier(id string) (TopicClassifier, error)
- func (r *Registry) VideoClassifier(id string) (VideoClassifier, error)
- type RegistryDefaults
- type StreamingAudioClassifier
- type StreamingVideoClassifier
- type TextClassifier
- type TextOptions
- type TopicClassifier
- type TopicDecision
- type TopicExamples
- type TopicPolicy
- type TopicRequest
- type TopicResult
- type TopicTurn
- type VideoClassifier
- type VideoOptions
Constants ¶
const ( SmallTalkAllow = "allow" SmallTalkDeny = "deny" )
Small-talk dispositions. A policy says whether greetings, thanks and pleasantries — which match no listed subject — count as in scope.
Variables ¶
This section is empty.
Functions ¶
func RegisterBackend ¶
RegisterBackend registers b under id against every task interface it implements, returning the task labels registered (e.g. ["audio", "text"]). A backend that satisfies no task interface registers nothing and returns an empty slice. Shared by BuildRegistry and the SDK's programmatic options so the type-assert logic lives in one place.
It does not touch defaults. Callers that register incrementally — one provider per SDK option, with nothing running afterwards to assign defaults — want RegisterBackendDefaulting instead.
func RegisterBackendDefaulting ¶ added in v2.2.0
RegisterBackendDefaulting registers b exactly as RegisterBackend does and, for every task interface it implements, claims that task's default when no default is set yet. Returns the task labels registered.
Use it wherever backends arrive one at a time and nothing runs afterwards to assign defaults — the SDK's WithInferenceProvider / WithClassifier options and the `role: inference` config path. Without it a backend registers successfully and then every handler lookup that doesn't name an explicit id fails with "no default classifier".
BuildRegistry deliberately keeps RegisterBackend plus its own applyDefaults pass: it sees the whole spec list up front, so it can honor an explicit RegistryDefaults entry over the first-declared one. The two paths agree on first-wins whenever no explicit default is given.
func RegisterFactory ¶
RegisterFactory registers a factory for the given provider type. Typically called from a per-backend package init().
func RegisteredTypes ¶
func RegisteredTypes() []string
RegisteredTypes returns the inference provider types with a registered factory, sorted. Use it to check a configured type before CreateFromSpec rather than constructing and parsing the error.
func ResolveCredential ¶
func ResolveCredential( ctx context.Context, providerType string, cfgDir string, cred *credentials.CredentialConfig, ) (credentials.Credential, error)
ResolveCredential is a thin wrapper around base.ResolveCredential, matching tts.ResolveCredential / stt.ResolveCredential.
Types ¶
type AudioChunk ¶
type AudioChunk struct {
// PCM is the raw PCM audio bytes for this chunk. Format
// declared by the parent AudioStreamOptions.
PCM []byte
// Final marks the last chunk; backends may flush state.
Final bool
}
AudioChunk is a single packet in a streaming audio classification request. Backends that stream consume these from a channel until it closes.
type AudioClassifier ¶
type AudioClassifier interface {
ClassifyAudio(ctx context.Context, audio []byte, opts AudioOptions) ([]LabelScore, error)
}
AudioClassifier classifies a single audio clip into one or more labeled scores. Required interface for every backend that supports audio (HF base, Hume, Deepgram, ONNX).
Implementations must be safe for concurrent use; the registry hands the same instance to multiple eval handlers.
type AudioOptions ¶
type AudioOptions struct {
// Model is the backend-specific model identifier (e.g.
// "superb/wav2vec2-base-superb-er" on HuggingFace).
Model string
// Language is an optional ISO-639-1 hint (e.g. "en"). Only used
// by backends that route by language.
Language string
// SampleRate is the source audio sample rate in Hz. Backends
// that can resample internally use this to drive it. The
// shipped HuggingFace backend does NOT resample — handlers
// are expected to deliver audio at the rate the target model
// wants (typically 16 kHz mono for SER models). The field is
// kept on the options struct so future backends (ONNX, Hume,
// etc.) that do resample have a place to read the source rate
// from without growing a per-backend option type.
SampleRate int
// MIMEType is the audio container / codec hint (e.g. "audio/wav",
// "audio/L16"). Backends that need explicit format selection use
// this; others ignore.
MIMEType string
}
AudioOptions carries per-call knobs for audio classification. Backends ignore fields they don't support; consumers set what matters for their target model.
type AudioStreamOptions ¶
type AudioStreamOptions struct {
AudioOptions
// ChunkInterval is the source's emit cadence; backends use it
// to size analysis windows and stamp output timestamps.
ChunkInterval time.Duration
}
AudioStreamOptions carries the framing contract for a streaming audio classification request.
type Backend ¶
type Backend = any
Backend is whatever a factory returns: a value that implements one or more of the task interfaces (AudioClassifier, TextClassifier, …). RegisterBackend type-asserts it against each. It is intentionally an alias for any — there is no method common to all task interfaces.
func CreateFromSpec ¶
func CreateFromSpec(spec ProviderSpec) (Backend, error)
CreateFromSpec builds a Backend for the spec's Type.
type EmbedOptions ¶
type EmbedOptions struct {
// Model is the backend-specific model identifier (e.g.
// "voyage-3", "text-embedding-3-large").
Model string
// Dimensions optionally requests truncation to a specific
// dimensionality. Backend ignores if not supported.
Dimensions int
// InputType disambiguates query vs document embedding for
// asymmetric models (e.g. Voyage's `query` / `document`).
// Empty = backend default.
InputType string
}
EmbedOptions carries per-call knobs for text embedding.
type Embedder ¶
type Embedder interface {
Embed(ctx context.Context, inputs []string, opts EmbedOptions) ([][]float32, error)
}
Embedder turns text inputs into dense vectors. Co-located with the classifiers because it shares the same shape (task interface + multiple backends + registry lookup) and because moving embeddings here breaks the historical dependency between runtime/evals/handlers/cosine_similarity.go and concrete provider packages.
The current cosine_similarity handler reads pre-computed embeddings from EvalContext.Metadata — it doesn't call an Embedder directly. Migrating to this interface is queued (see phase 2 of the inference abstraction proposal); the interface lives here from day one so the migration doesn't introduce a new package later.
type Factory ¶
Factory builds a Backend from a spec. Per-backend packages register one via init() (see runtime/classify/backends/hf/register.go) so this package never imports them.
type ImageClassifier ¶
type ImageClassifier interface {
ClassifyImage(ctx context.Context, img []byte, opts ImageOptions) ([]LabelScore, error)
}
ImageClassifier classifies a single still image. Visual content moderation (NSFW, violence, brand safety), scene tagging, object recognition all go through this. No streaming sibling — a still image is a single inference.
type ImageOptions ¶
type ImageOptions struct {
// Model is the backend-specific model identifier (e.g.
// "Falconsai/nsfw_image_detection" on HuggingFace).
Model string
// MIMEType is the image format hint (e.g. "image/png", "image/jpeg").
MIMEType string
}
ImageOptions carries per-call knobs for image classification.
type LabelScore ¶
LabelScore pairs a classifier label with a confidence score in [0, 1]. Backends return slices of these sorted by descending score where the model supports ranking; the caller treats the order as hint only and looks up by Label when checking expected values.
type LabelScoreEvent ¶
type LabelScoreEvent struct {
Timestamp time.Duration
Window time.Duration
Scores []LabelScore
}
LabelScoreEvent is one window's worth of classification output from a streaming backend. Timestamp is relative to the start of the input stream.
type ProviderSpec ¶
type ProviderSpec = base.CapabilitySpec
ProviderSpec is the runtime form of an inference-provider declaration. Aliased to base.CapabilitySpec so the field shape is shared with the TTS, STT, embedding, and image factories (id/type/model/base_url/ credential/additional_config).
type Registry ¶
type Registry struct {
// contains filtered or unexported fields
}
Registry holds named classifier and embedder instances keyed by an id supplied at config time (e.g. "hf", "hf-azure", "onnx-local"). Eval handlers look up by id; the id-to-backend mapping is the only thing the handler config needs to know about.
Backends register themselves into a Registry at engine startup; the registry then travels with context.Context to handlers via WithRegistry / FromContext.
func BuildRegistry ¶
func BuildRegistry(specs []ProviderSpec, defaults RegistryDefaults) (*Registry, error)
BuildRegistry constructs a Registry from specs, registering each backend against every task interface it implements, then applies defaults. For any task with no explicit default, the first-declared provider implementing it becomes the default (first-wins, matching STT/TTS service defaults). Returns (nil, nil) when specs is empty — classification is optional; callers that don't use it must not require a token.
func FromContext ¶
FromContext returns the Registry attached to ctx, or nil if none. Eval handlers that don't find a registry fall back to a "skipped" result rather than failing — classification is an optional feature of the runtime, not a hard dependency.
func NewRegistry ¶
func NewRegistry() *Registry
NewRegistry returns an empty Registry. Backends are added via RegisterAudio / RegisterText / etc.; defaults are set with the SetDefault* methods.
func (*Registry) AudioClassifier ¶
func (r *Registry) AudioClassifier(id string) (AudioClassifier, error)
AudioClassifier resolves by id, falling back to the configured default when id is empty. Returns a non-nil error when nothing matches.
func (*Registry) ImageClassifier ¶
func (r *Registry) ImageClassifier(id string) (ImageClassifier, error)
ImageClassifier resolves by id with default fallback.
func (*Registry) RegisterAudio ¶
func (r *Registry) RegisterAudio(id string, c AudioClassifier)
RegisterAudio adds an AudioClassifier under the given id. Calling twice with the same id replaces the previous instance.
func (*Registry) RegisterEmbedder ¶
RegisterEmbedder adds an Embedder.
func (*Registry) RegisterImage ¶
func (r *Registry) RegisterImage(id string, c ImageClassifier)
RegisterImage adds an ImageClassifier.
func (*Registry) RegisterText ¶
func (r *Registry) RegisterText(id string, c TextClassifier)
RegisterText adds a TextClassifier.
func (*Registry) RegisterTopic ¶ added in v2.2.0
func (r *Registry) RegisterTopic(id string, c TopicClassifier)
RegisterTopic adds a TopicClassifier.
func (*Registry) RegisterVideo ¶
func (r *Registry) RegisterVideo(id string, c VideoClassifier)
RegisterVideo adds a VideoClassifier.
func (*Registry) SetDefaultAudio ¶
SetDefaultAudio names the AudioClassifier used when a handler doesn't pass an explicit id. The id must already be registered.
func (*Registry) SetDefaultEmbedder ¶
SetDefaultEmbedder names the default Embedder.
func (*Registry) SetDefaultImage ¶
SetDefaultImage names the default ImageClassifier.
func (*Registry) SetDefaultText ¶
SetDefaultText names the default TextClassifier.
func (*Registry) SetDefaultTopic ¶ added in v2.2.0
SetDefaultTopic names the default TopicClassifier.
func (*Registry) SetDefaultVideo ¶
SetDefaultVideo names the default VideoClassifier.
func (*Registry) TextClassifier ¶
func (r *Registry) TextClassifier(id string) (TextClassifier, error)
TextClassifier resolves by id with default fallback.
func (*Registry) TopicClassifier ¶ added in v2.2.0
func (r *Registry) TopicClassifier(id string) (TopicClassifier, error)
TopicClassifier resolves by id with default fallback.
func (*Registry) VideoClassifier ¶
func (r *Registry) VideoClassifier(id string) (VideoClassifier, error)
VideoClassifier resolves by id with default fallback.
type RegistryDefaults ¶
type RegistryDefaults struct {
AudioClassifier string
TextClassifier string
ImageClassifier string
VideoClassifier string
Embedder string
TopicClassifier string
}
RegistryDefaults pins which provider id serves each task when a handler doesn't name one. Mirrors config.InferenceDefaults but lives in runtime so both Arena and the SDK map onto it.
type StreamingAudioClassifier ¶
type StreamingAudioClassifier interface {
AudioClassifier
ClassifyAudioStream(
ctx context.Context,
chunks <-chan AudioChunk,
opts AudioStreamOptions,
) (<-chan LabelScoreEvent, error)
}
StreamingAudioClassifier is the optional capability for live classification — Hume, Deepgram, and locally-windowed ONNX implement it; HF Inference API base does not. Eval handlers that only need end-of-turn classification depend on AudioClassifier; hooks and guardrails that react mid-call type-assert to this.
type StreamingVideoClassifier ¶
type StreamingVideoClassifier interface {
VideoClassifier
ClassifyVideoStream(
ctx context.Context,
chunks <-chan struct{},
opts VideoOptions,
) (<-chan LabelScoreEvent, error)
}
StreamingVideoClassifier is the optional capability for live video classification (mostly a future concern — agentic-UI replay, security camera streams). No MVP backend implements it; the interface stays in the package so the synchronous one doesn't break when a streaming consumer arrives.
type TextClassifier ¶
type TextClassifier interface {
ClassifyText(ctx context.Context, text string, opts TextOptions) ([]LabelScore, error)
}
TextClassifier classifies a single text string. Toxicity, sentiment, emotion-from-text, intent, language detection — anything that takes text in and returns labeled scores.
Text inputs aren't temporally extended, so there's no streaming sibling. Batch text classification (many strings at once) goes through repeated calls — backends that support batching internally can pool requests.
type TextOptions ¶
type TextOptions struct {
// Model is the backend-specific model identifier (e.g.
// "unitary/toxic-bert" on HuggingFace).
Model string
// Language is an optional ISO-639-1 hint.
Language string
// MultiLabel asks the backend to return scores for every label
// rather than a single best one. Useful for toxicity panels
// (toxic, severe_toxic, obscene, …) where multiple may apply.
MultiLabel bool
}
TextOptions carries per-call knobs for text classification.
type TopicClassifier ¶ added in v2.2.0
type TopicClassifier interface {
ClassifyTopic(ctx context.Context, req TopicRequest) (TopicResult, error)
}
TopicClassifier decides whether a user message falls inside a declared conversational scope. The sixth task interface in this package; see the package doc for how backends bind to tasks.
type TopicDecision ¶ added in v2.2.0
type TopicDecision string
TopicDecision is a classifier's verdict about one user message.
const ( // TopicAllow means the message falls inside the declared scope. TopicAllow TopicDecision = "allow" // TopicDeny means the message falls outside it. TopicDeny TopicDecision = "deny" // TopicUnknown means the backend could not decide: an unreachable // service, or a response that did not parse. Callers map it to a // policy-configured outcome rather than guessing. TopicUnknown TopicDecision = "unknown" )
type TopicExamples ¶ added in v2.2.0
TopicExamples is an optional labeled corpus. It is a classification aid, not configuration: backends may fold it into a prompt or ignore it.
type TopicPolicy ¶ added in v2.2.0
type TopicPolicy struct {
// Description is the application's purpose in prose. Required — an
// allow-list alone reads as keywords to a semantic classifier.
Description string
// Allowed lists in-scope subjects. Required and non-empty: policy is
// default-deny, so an empty list would block everything.
Allowed []string
// Disallowed lists explicit exclusions. Optional.
Disallowed []string
// SmallTalk is SmallTalkAllow or SmallTalkDeny.
SmallTalk string
// Examples is an optional labeled corpus.
Examples TopicExamples
}
TopicPolicy is a declared conversational scope, in the pack author's own words. It is deliberately structured rather than a free-text criteria string: a chat-shaped backend renders it into a prompt, while a future embedding or ONNX backend can consume the same fields directly, and neither requires the pack to change.
type TopicRequest ¶ added in v2.2.0
type TopicRequest struct {
Policy TopicPolicy
History []TopicTurn
// Message is the user message under judgment. Prior in-scope history
// must not implicitly authorize it.
Message string
}
TopicRequest is one classification: judge Message against Policy, using History only to resolve references.
type TopicResult ¶ added in v2.2.0
type TopicResult struct {
Decision TopicDecision
// Confidence is populated only by a backend that genuinely has one.
// A label-emitting model does not, and must leave it nil rather than
// manufacture a number callers might threshold on.
Confidence *float64
// Reason is the backend's explanation where it supplies one.
Reason string
// Raw is the backend's unparsed answer, for diagnostics.
Raw string
}
TopicResult is a classifier's answer.
type TopicTurn ¶ added in v2.2.0
TopicTurn is one prior conversation turn flattened to role and plain text.
Deliberately not types.Message: assistant text lives on Content while user text can live in Parts, and the extraction helper belongs with the eval handlers. Flattening at the caller keeps this package free of a types dependency and stops every backend re-implementing the same extraction.
type VideoClassifier ¶
type VideoClassifier interface {
ClassifyVideo(ctx context.Context, video []byte, opts VideoOptions) ([]LabelScore, error)
}
VideoClassifier classifies a video clip. Two physical shapes:
- Whole-clip backends (e.g. HuggingFace Video Classification API) accept the full clip and return labels for it.
- Decomposing backends extract the audio track and frame-sample stills, route those through AudioClassifier + ImageClassifier, and aggregate the per-modality scores. The interface is the same; backends choose the implementation.
VideoOptions.FrameSampleRate and .ExtractAudio steer decomposing backends; whole-clip backends ignore them.
type VideoOptions ¶
type VideoOptions struct {
// Model is the backend-specific model identifier.
Model string
// MIMEType is the video container hint (e.g. "video/mp4").
MIMEType string
// FrameSampleRate is the per-second frame extraction rate used
// by decomposing backends (audio + sampled image classifier).
// Whole-clip backends ignore this. 0 = backend default.
FrameSampleRate float64
// ExtractAudio toggles whether decomposing backends route the
// audio track through their AudioClassifier as well as their
// ImageClassifier. Default false.
ExtractAudio bool
}
VideoOptions carries per-call knobs for video classification.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
backends
|
|
|
all
Package all blank-imports every classify backend so their factories self-register.
|
Package all blank-imports every classify backend so their factories self-register. |
|
hf
Package hf implements the runtime/classify interfaces against the HuggingFace Inference API.
|
Package hf implements the runtime/classify interfaces against the HuggingFace Inference API. |
|
topiccontrol
Package topiccontrol implements classify.TopicClassifier against NVIDIA's Llama-3.1-NemoGuard-8B TopicControl model, served by NIM over an OpenAI-compatible chat-completions endpoint.
|
Package topiccontrol implements classify.TopicClassifier against NVIDIA's Llama-3.1-NemoGuard-8B TopicControl model, served by NIM over an OpenAI-compatible chat-completions endpoint. |