Add the Rakestrawhome built-in backend
This commit is contained in:
16
backends.go
16
backends.go
@@ -9,6 +9,10 @@ import (
|
|||||||
// backend.
|
// backend.
|
||||||
const BackendOpenRouter = backend.OpenRouterID
|
const BackendOpenRouter = backend.OpenRouterID
|
||||||
|
|
||||||
|
// BackendRakestrawHome is the reserved ID of Promptkit's built-in
|
||||||
|
// Rakestrawhome backend.
|
||||||
|
const BackendRakestrawHome = backend.RakestrawHomeID
|
||||||
|
|
||||||
// BackendLocal is the case-sensitive conventional ID used by [LocalBackend].
|
// BackendLocal is the case-sensitive conventional ID used by [LocalBackend].
|
||||||
// It is not a built-in or reserved backend and must be registered with
|
// It is not a built-in or reserved backend and must be registered with
|
||||||
// [WithBackend].
|
// [WithBackend].
|
||||||
@@ -20,7 +24,7 @@ const BackendLocal = "local"
|
|||||||
// to this configuration value do not break source compatibility.
|
// to this configuration value do not break source compatibility.
|
||||||
type Backend struct {
|
type Backend struct {
|
||||||
// ID is the stable, case-sensitive registry key. NewEngine trims it and
|
// ID is the stable, case-sensitive registry key. NewEngine trims it and
|
||||||
// requires a non-blank value. BackendOpenRouter is reserved.
|
// requires a non-blank value. Built-in backend IDs are reserved.
|
||||||
ID string
|
ID string
|
||||||
// Endpoint is the OpenAI-compatible base endpoint. NewEngine trims it and
|
// Endpoint is the OpenAI-compatible base endpoint. NewEngine trims it and
|
||||||
// requires an absolute HTTP or HTTPS URL with a host and without user
|
// requires an absolute HTTP or HTTPS URL with a host and without user
|
||||||
@@ -74,11 +78,11 @@ func LocalBackend(endpoint string, concurrencyLimit int) Backend {
|
|||||||
//
|
//
|
||||||
// Registrations accumulate in option order. Every normalized ID must be unique
|
// Registrations accumulate in option order. Every normalized ID must be unique
|
||||||
// across consumer registrations and built-ins; a duplicate or invalid
|
// across consumer registrations and built-ins; a duplicate or invalid
|
||||||
// definition makes NewEngine fail with ErrInvalidConfig. In particular,
|
// definition makes NewEngine fail with ErrInvalidConfig. Built-in IDs,
|
||||||
// BackendOpenRouter cannot be replaced. The immutable registration is scoped
|
// including [BackendOpenRouter] and [BackendRakestrawHome], cannot be
|
||||||
// to the resulting Engine and cannot be enumerated, replaced, removed, or
|
// replaced. The immutable registration is scoped to the resulting Engine and
|
||||||
// mutated after construction. WithBackend does not install package-global
|
// cannot be enumerated, replaced, removed, or mutated after construction.
|
||||||
// state.
|
// WithBackend does not install package-global state.
|
||||||
func WithBackend(backend Backend) Option {
|
func WithBackend(backend Backend) Option {
|
||||||
queueCapacity := 0
|
queueCapacity := 0
|
||||||
queueCapacitySet := backend.QueueCapacity != nil
|
queueCapacitySet := backend.QueueCapacity != nil
|
||||||
|
|||||||
@@ -123,6 +123,8 @@ The stage is complete when both exact built-ins are published through the same
|
|||||||
immutable registry path, both IDs are reserved, and existing custom-backend and
|
immutable registry path, both IDs are reserved, and existing custom-backend and
|
||||||
OpenRouter behavior remains green.
|
OpenRouter behavior remains green.
|
||||||
|
|
||||||
|
**Status:** Complete.
|
||||||
|
|
||||||
## Stage 2: Add the Built-In Profile and Prove Assembly
|
## Stage 2: Add the Built-In Profile and Prove Assembly
|
||||||
|
|
||||||
### Objective
|
### Objective
|
||||||
|
|||||||
@@ -18,12 +18,20 @@ const (
|
|||||||
// OpenRouterID is the reserved ID of Promptkit's built-in OpenRouter
|
// OpenRouterID is the reserved ID of Promptkit's built-in OpenRouter
|
||||||
// backend.
|
// backend.
|
||||||
OpenRouterID = "openrouter"
|
OpenRouterID = "openrouter"
|
||||||
|
// RakestrawHomeID is the reserved ID of Promptkit's built-in Rakestrawhome
|
||||||
|
// backend.
|
||||||
|
RakestrawHomeID = "rakestrawhome"
|
||||||
|
|
||||||
openRouterEndpoint = "https://openrouter.ai/api/v1"
|
openRouterEndpoint = "https://openrouter.ai/api/v1"
|
||||||
openRouterAPIKeyEnv = "OPENROUTER_API_KEY"
|
openRouterAPIKeyEnv = "OPENROUTER_API_KEY"
|
||||||
|
|
||||||
openRouterConcurrencyLimit = 16
|
openRouterConcurrencyLimit = 16
|
||||||
defaultQueueCapacity = 1024
|
|
||||||
|
rakestrawHomeEndpoint = "https://inference.ai.rakestrawhome.com/v1"
|
||||||
|
rakestrawHomeAPIKeyEnv = "RAKESTRAWHOME_INFERENCE_API_KEY"
|
||||||
|
|
||||||
|
rakestrawHomeConcurrencyLimit = 4
|
||||||
|
defaultQueueCapacity = 1024
|
||||||
)
|
)
|
||||||
|
|
||||||
// ErrBackendNotFound identifies a registry lookup for an unknown backend ID.
|
// ErrBackendNotFound identifies a registry lookup for an unknown backend ID.
|
||||||
@@ -36,20 +44,16 @@ type Registry struct {
|
|||||||
backends map[string]domain.Backend
|
backends map[string]domain.Backend
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewRegistry constructs a registry containing the built-in OpenRouter
|
// NewRegistry constructs a registry containing the built-in definitions
|
||||||
// definition followed by the supplied additions. Every ID must be unique.
|
// followed by the supplied additions. Every ID must be unique.
|
||||||
func NewRegistry(additions []domain.Backend) (*Registry, error) {
|
func NewRegistry(additions []domain.Backend) (*Registry, error) {
|
||||||
|
builtIns := builtInBackends()
|
||||||
registry := &Registry{
|
registry := &Registry{
|
||||||
backends: make(map[string]domain.Backend, len(additions)+1),
|
backends: make(map[string]domain.Backend, len(builtIns)+len(additions)),
|
||||||
}
|
}
|
||||||
|
|
||||||
definitions := make([]domain.Backend, 0, len(additions)+1)
|
definitions := make([]domain.Backend, 0, len(builtIns)+len(additions))
|
||||||
definitions = append(definitions, domain.Backend{
|
definitions = append(definitions, builtIns...)
|
||||||
ID: OpenRouterID,
|
|
||||||
Endpoint: openRouterEndpoint,
|
|
||||||
APIKeyEnv: openRouterAPIKeyEnv,
|
|
||||||
ConcurrencyLimit: openRouterConcurrencyLimit,
|
|
||||||
})
|
|
||||||
definitions = append(definitions, additions...)
|
definitions = append(definitions, additions...)
|
||||||
|
|
||||||
for _, definition := range definitions {
|
for _, definition := range definitions {
|
||||||
@@ -71,6 +75,23 @@ func NewRegistry(additions []domain.Backend) (*Registry, error) {
|
|||||||
return registry, nil
|
return registry, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func builtInBackends() []domain.Backend {
|
||||||
|
return []domain.Backend{
|
||||||
|
{
|
||||||
|
ID: OpenRouterID,
|
||||||
|
Endpoint: openRouterEndpoint,
|
||||||
|
APIKeyEnv: openRouterAPIKeyEnv,
|
||||||
|
ConcurrencyLimit: openRouterConcurrencyLimit,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: RakestrawHomeID,
|
||||||
|
Endpoint: rakestrawHomeEndpoint,
|
||||||
|
APIKeyEnv: rakestrawHomeAPIKeyEnv,
|
||||||
|
ConcurrencyLimit: rakestrawHomeConcurrencyLimit,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// GetBackend returns a defensive copy of the backend registered with id.
|
// GetBackend returns a defensive copy of the backend registered with id.
|
||||||
func (r *Registry) GetBackend(id string) (domain.Backend, error) {
|
func (r *Registry) GetBackend(id string) (domain.Backend, error) {
|
||||||
if r == nil {
|
if r == nil {
|
||||||
|
|||||||
@@ -11,32 +11,63 @@ import (
|
|||||||
|
|
||||||
const validEndpoint = "https://backend.example/v1"
|
const validEndpoint = "https://backend.example/v1"
|
||||||
|
|
||||||
func TestRegistryIncludesExactOpenRouterDefinition(t *testing.T) {
|
func TestRegistryIncludesExactBuiltInDefinitions(t *testing.T) {
|
||||||
registry, err := backend.NewRegistry(nil)
|
registry, err := backend.NewRegistry(nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("construct registry: %v", err)
|
t.Fatalf("construct registry: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
definition, err := registry.GetBackend(backend.OpenRouterID)
|
tests := []struct {
|
||||||
if err != nil {
|
name string
|
||||||
t.Fatalf("look up OpenRouter: %v", err)
|
id string
|
||||||
|
endpoint string
|
||||||
|
apiKeyEnv string
|
||||||
|
concurrent int
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "OpenRouter",
|
||||||
|
id: backend.OpenRouterID,
|
||||||
|
endpoint: "https://openrouter.ai/api/v1",
|
||||||
|
apiKeyEnv: "OPENROUTER_API_KEY",
|
||||||
|
concurrent: 16,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Rakestrawhome",
|
||||||
|
id: backend.RakestrawHomeID,
|
||||||
|
endpoint: "https://inference.ai.rakestrawhome.com/v1",
|
||||||
|
apiKeyEnv: "RAKESTRAWHOME_INFERENCE_API_KEY",
|
||||||
|
concurrent: 4,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
if definition.ID != "openrouter" ||
|
for _, tc := range tests {
|
||||||
definition.Endpoint != "https://openrouter.ai/api/v1" ||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
definition.APIKeyEnv != "OPENROUTER_API_KEY" ||
|
definition, err := registry.GetBackend(tc.id)
|
||||||
definition.ConcurrencyLimit != 16 ||
|
if err != nil {
|
||||||
definition.QueueCapacity != 1024 ||
|
t.Fatalf("look up built-in: %v", err)
|
||||||
!definition.QueueCapacitySet ||
|
}
|
||||||
definition.ExtraParams != nil {
|
if definition.ID != tc.id ||
|
||||||
t.Fatalf("unexpected OpenRouter definition: %#v", definition)
|
definition.Endpoint != tc.endpoint ||
|
||||||
|
definition.APIKeyEnv != tc.apiKeyEnv ||
|
||||||
|
definition.ConcurrencyLimit != tc.concurrent ||
|
||||||
|
definition.QueueCapacity != 1024 ||
|
||||||
|
!definition.QueueCapacitySet ||
|
||||||
|
definition.ExtraParams != nil {
|
||||||
|
t.Fatalf("unexpected built-in definition: %#v", definition)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
policies := registry.CapacityPolicies()
|
policies := registry.CapacityPolicies()
|
||||||
if len(policies) != 1 ||
|
if len(policies) != 2 ||
|
||||||
policies["openrouter"] != (domain.BackendCapacityPolicy{
|
policies[backend.OpenRouterID] != (domain.BackendCapacityPolicy{
|
||||||
ConcurrencyLimit: 16,
|
ConcurrencyLimit: 16,
|
||||||
QueueCapacity: 1024,
|
QueueCapacity: 1024,
|
||||||
|
}) ||
|
||||||
|
policies[backend.RakestrawHomeID] != (domain.BackendCapacityPolicy{
|
||||||
|
ConcurrencyLimit: 4,
|
||||||
|
QueueCapacity: 1024,
|
||||||
}) {
|
}) {
|
||||||
t.Fatalf("unexpected OpenRouter capacity policies: %#v", policies)
|
t.Fatalf("unexpected built-in capacity policies: %#v", policies)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,11 +140,12 @@ func TestRegistryNormalizesUniqueAdditionsAndIsolatesMutations(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
policies := registry.CapacityPolicies()
|
policies := registry.CapacityPolicies()
|
||||||
if len(policies) != 2 {
|
if len(policies) != 3 {
|
||||||
t.Fatalf("unexpected capacity policy count: %#v", policies)
|
t.Fatalf("unexpected capacity policy count: %#v", policies)
|
||||||
}
|
}
|
||||||
policies["custom"] = domain.BackendCapacityPolicy{}
|
policies["custom"] = domain.BackendCapacityPolicy{}
|
||||||
delete(policies, backend.OpenRouterID)
|
delete(policies, backend.OpenRouterID)
|
||||||
|
delete(policies, backend.RakestrawHomeID)
|
||||||
againPolicies := registry.CapacityPolicies()
|
againPolicies := registry.CapacityPolicies()
|
||||||
if againPolicies["custom"] != (domain.BackendCapacityPolicy{
|
if againPolicies["custom"] != (domain.BackendCapacityPolicy{
|
||||||
ConcurrencyLimit: 3,
|
ConcurrencyLimit: 3,
|
||||||
@@ -122,7 +154,10 @@ func TestRegistryNormalizesUniqueAdditionsAndIsolatesMutations(t *testing.T) {
|
|||||||
t.Fatalf("capacity policy map mutated registry state: %#v", againPolicies)
|
t.Fatalf("capacity policy map mutated registry state: %#v", againPolicies)
|
||||||
}
|
}
|
||||||
if _, ok := againPolicies[backend.OpenRouterID]; !ok {
|
if _, ok := againPolicies[backend.OpenRouterID]; !ok {
|
||||||
t.Fatalf("capacity policy deletion mutated registry state: %#v", againPolicies)
|
t.Fatalf("OpenRouter capacity policy deletion mutated registry state: %#v", againPolicies)
|
||||||
|
}
|
||||||
|
if _, ok := againPolicies[backend.RakestrawHomeID]; !ok {
|
||||||
|
t.Fatalf("Rakestrawhome capacity policy deletion mutated registry state: %#v", againPolicies)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -242,11 +277,14 @@ func TestNewRegistryRejectsDuplicateIDs(t *testing.T) {
|
|||||||
wantID string
|
wantID string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "built-in collision after normalization",
|
name: "OpenRouter collision after normalization",
|
||||||
additions: []domain.Backend{{
|
additions: []domain.Backend{{ID: " openrouter "}},
|
||||||
ID: " openrouter ",
|
wantID: backend.OpenRouterID,
|
||||||
}},
|
},
|
||||||
wantID: "openrouter",
|
{
|
||||||
|
name: "Rakestrawhome collision after normalization",
|
||||||
|
additions: []domain.Backend{{ID: " rakestrawhome "}},
|
||||||
|
wantID: backend.RakestrawHomeID,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "consumer collision after normalization",
|
name: "consumer collision after normalization",
|
||||||
|
|||||||
@@ -784,9 +784,12 @@ func TestBackendRegistrationRejectsInvalidAndDuplicateDefinitions(t *testing.T)
|
|||||||
{ID: " custom ", Endpoint: "http://one.example/v1"},
|
{ID: " custom ", Endpoint: "http://one.example/v1"},
|
||||||
{ID: "custom", Endpoint: "http://two.example/v1"},
|
{ID: "custom", Endpoint: "http://two.example/v1"},
|
||||||
}},
|
}},
|
||||||
{name: "reserved built-in id", backends: []promptkit.Backend{{
|
{name: "reserved OpenRouter ID", backends: []promptkit.Backend{{
|
||||||
ID: promptkit.BackendOpenRouter, Endpoint: "http://replacement.example/v1",
|
ID: promptkit.BackendOpenRouter, Endpoint: "http://replacement.example/v1",
|
||||||
}}},
|
}}},
|
||||||
|
{name: "reserved Rakestrawhome ID", backends: []promptkit.Backend{{
|
||||||
|
ID: promptkit.BackendRakestrawHome, Endpoint: "http://replacement.example/v1",
|
||||||
|
}}},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
|
|||||||
Reference in New Issue
Block a user