Files
promptkit/backends.go

132 lines
5.4 KiB
Go

package promptkit
import (
"gitea.maximumdirect.net/eric/ConfigKit"
"gitea.maximumdirect.net/eric/promptkit/internal/backend"
)
// BackendOpenRouter is the conventional ID for an OpenRouter backend.
const BackendOpenRouter = backend.OpenRouterID
// BackendRakestrawHome is the conventional ID for a Rakestrawhome backend.
const BackendRakestrawHome = backend.RakestrawHomeID
// BackendLocal is a conventional ID for a caller-configured local backend.
const BackendLocal = "local"
// BackendConfig is a presence-aware convenience value for a keyed backend
// definition. Nil pointer fields are omitted, while non-nil pointers preserve
// explicit zero or blank values. A nil ExtraParams map is omitted; a non-nil
// empty map supplies an empty mapping. A nil SmokeTests pointer is omitted; a
// non-nil pointer supplies a smoke_tests mapping. Use raw ConfigKit Mapping
// inputs for explicit null. BackendConfig has no stable JSON representation.
type BackendConfig struct {
// Endpoint is the required absolute HTTP(S) base URL after all layers merge.
Endpoint *string
// APIKeyEnv optionally names an environment variable, not a credential.
APIKeyEnv *string
// ConcurrencyLimit is zero for unlimited generation; negative is invalid.
ConcurrencyLimit *int
// QueueCapacity defaults to 1024 for positive concurrency when omitted.
// An explicit value, including zero, requires positive concurrency.
QueueCapacity *int
// ExtraParams supplies JSON-compatible provider request defaults.
ExtraParams map[string]any
// SmokeTests supplies optional diagnostic defaults and HTTP probe settings.
SmokeTests *BackendSmokeTestConfig
}
// BackendSmokeTestConfig contains optional diagnostic settings associated with
// a backend. Nil nested fields are omitted by BackendSource.
type BackendSmokeTestConfig struct {
// DefaultProfile is the exact profile ID selected as the backend's
// diagnostic inference default. A supplied value must not be blank; the ID
// is resolved only when that default is selected.
DefaultProfile *string
// Reachability optionally selects a full HTTP destination for reachability
// diagnostics. A nil endpoint uses the effective backend endpoint.
Reachability *ReachabilityProbeConfig
// Authentication optionally declares a named authentication diagnostic.
// A supplied object requires Kind.
Authentication *AuthenticationProbeConfig
}
// ReachabilityProbeConfig configures an optional reachability destination.
type ReachabilityProbeConfig struct {
// Endpoint is an absolute HTTP(S) URL, including any desired path or query.
// Nil selects the effective backend endpoint; an explicit blank value is
// invalid.
Endpoint *string
}
// AuthenticationProbeConfig configures an optional named authentication
// diagnostic.
type AuthenticationProbeConfig struct {
// Kind selects the authentication adapter. Supported values are "none" and
// "openrouter_key"; surrounding whitespace and case are normalized.
Kind *string
// Endpoint is an absolute HTTP(S) URL, including any desired path or query.
// Nil selects the adapter's backend-relative destination; an explicit blank
// value is invalid.
Endpoint *string
}
// BackendSource creates a labeled ConfigKit mapping from keyed backend values.
// It encodes fields without validating them; NewEngine validates the final
// effective configuration after all selected source layers are combined.
// Mapping captures a copy of supported input values at creation; unsupported
// values fail when the source is loaded.
func BackendSource(label string, backends map[string]BackendConfig) configkit.Source {
definitions := make(map[string]any, len(backends))
for id, config := range backends {
fields := make(map[string]any)
if config.Endpoint != nil {
fields["endpoint"] = *config.Endpoint
}
if config.APIKeyEnv != nil {
fields["api_key_env"] = *config.APIKeyEnv
}
if config.ConcurrencyLimit != nil {
fields["concurrency_limit"] = *config.ConcurrencyLimit
}
if config.QueueCapacity != nil {
fields["queue_capacity"] = *config.QueueCapacity
}
if config.ExtraParams != nil {
fields["extra_params"] = providerMapForMapping(config.ExtraParams)
}
if config.SmokeTests != nil {
smokeTests := make(map[string]any)
if config.SmokeTests.DefaultProfile != nil {
smokeTests["default_profile"] = *config.SmokeTests.DefaultProfile
}
if config.SmokeTests.Reachability != nil {
reachability := make(map[string]any)
if config.SmokeTests.Reachability.Endpoint != nil {
reachability["endpoint"] = *config.SmokeTests.Reachability.Endpoint
}
smokeTests["reachability"] = reachability
}
if config.SmokeTests.Authentication != nil {
authentication := make(map[string]any)
if config.SmokeTests.Authentication.Kind != nil {
authentication["kind"] = *config.SmokeTests.Authentication.Kind
}
if config.SmokeTests.Authentication.Endpoint != nil {
authentication["endpoint"] = *config.SmokeTests.Authentication.Endpoint
}
smokeTests["authentication"] = authentication
}
fields["smoke_tests"] = smokeTests
}
definitions[id] = fields
}
return configkit.Mapping(label, map[string]any{"backends": definitions})
}
// LocalBackend supplies endpoint and concurrency pointers for a caller-chosen
// backend ID; it does not select an ID or validate either value.
func LocalBackend(endpoint string, concurrencyLimit int) BackendConfig {
return BackendConfig{Endpoint: &endpoint, ConcurrencyLimit: &concurrencyLimit}
}