Configure OpenClaw admission from bridge config
This commit is contained in:
parent
e27995a85b
commit
b39c9ec084
@ -12,6 +12,11 @@ upstream:
|
||||
gateway_url: "ws://127.0.0.1:18789/"
|
||||
opencode_url: "ws://127.0.0.1:38992"
|
||||
|
||||
openclaw_gateway:
|
||||
max_active: 2
|
||||
max_queued: 20
|
||||
queue_timeout: "10m"
|
||||
|
||||
# Legacy/Reference structure (Normally managed via code constants or environment)
|
||||
bridge:
|
||||
listenAddr: 127.0.0.1:8787
|
||||
|
||||
@ -13,7 +13,7 @@ func (s *Server) Bootstrap() {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
config, providerCatalog, providerOrder := newProductionProviderCatalog()
|
||||
config, providerCatalog, providerOrder := newProductionProviderCatalogFromConfig(s.config)
|
||||
s.config = config
|
||||
s.providerOrder = providerOrder
|
||||
|
||||
@ -40,16 +40,16 @@ func (s *Server) Bootstrap() {
|
||||
ProviderCatalog: make([]any, 0),
|
||||
GatewayProviders: []any{
|
||||
map[string]any{
|
||||
"providerId": "openclaw",
|
||||
"label": "OpenClaw",
|
||||
"targets": []string{"gateway"},
|
||||
"providerId": "openclaw",
|
||||
"label": "OpenClaw",
|
||||
"targets": []string{"gateway"},
|
||||
"providerDisplay": map[string]any{"logoEmoji": "🦞"},
|
||||
},
|
||||
},
|
||||
AvailableExecutionTargets: []any{"agent", "gateway"},
|
||||
ProviderProbeSummary: make([]any, 0),
|
||||
}
|
||||
|
||||
|
||||
for _, id := range providerOrder {
|
||||
p, ok := providerCatalog[id]
|
||||
if !ok || !p.Enabled {
|
||||
|
||||
@ -24,6 +24,13 @@ type BridgeConfig struct {
|
||||
GeminiURL string `yaml:"gemini_url"`
|
||||
HermesURL string `yaml:"hermes_url"`
|
||||
} `yaml:"upstream"`
|
||||
OpenClawGateway OpenClawGatewayConfig `yaml:"openclaw_gateway"`
|
||||
}
|
||||
|
||||
type OpenClawGatewayConfig struct {
|
||||
MaxActive *int `yaml:"max_active"`
|
||||
MaxQueued *int `yaml:"max_queued"`
|
||||
QueueTimeout string `yaml:"queue_timeout"`
|
||||
}
|
||||
|
||||
func loadBridgeConfig() *BridgeConfig {
|
||||
@ -65,7 +72,13 @@ func bridgeSharedAuthToken() string {
|
||||
}
|
||||
|
||||
func newProductionProviderCatalog() (*BridgeConfig, map[string]syncedProvider, []string) {
|
||||
config := loadBridgeConfig()
|
||||
return newProductionProviderCatalogFromConfig(loadBridgeConfig())
|
||||
}
|
||||
|
||||
func newProductionProviderCatalogFromConfig(config *BridgeConfig) (*BridgeConfig, map[string]syncedProvider, []string) {
|
||||
if config == nil {
|
||||
config = &BridgeConfig{}
|
||||
}
|
||||
authorizationHeader := bridgeUpstreamAuthorizationHeader()
|
||||
|
||||
providers := []struct {
|
||||
|
||||
@ -32,17 +32,24 @@ type openClawGatewayAdmissionGate struct {
|
||||
queued int
|
||||
}
|
||||
|
||||
func newOpenClawGatewayAdmissionGateFromEnv() *openClawGatewayAdmissionGate {
|
||||
maxActive := envInt("XWORKMATE_BRIDGE_OPENCLAW_GATEWAY_MAX_ACTIVE", defaultOpenClawGatewayMaxActive)
|
||||
func newOpenClawGatewayAdmissionGate(config *BridgeConfig) *openClawGatewayAdmissionGate {
|
||||
admissionConfig := OpenClawGatewayConfig{}
|
||||
if config != nil {
|
||||
admissionConfig = config.OpenClawGateway
|
||||
}
|
||||
maxActive := admissionInt(admissionConfig.MaxActive, "XWORKMATE_BRIDGE_OPENCLAW_GATEWAY_MAX_ACTIVE", defaultOpenClawGatewayMaxActive)
|
||||
if maxActive < 1 {
|
||||
log.Printf("level=warn component=openclaw_gateway event=invalid_admission_config key=%q value=%d", "max_active", maxActive)
|
||||
maxActive = defaultOpenClawGatewayMaxActive
|
||||
}
|
||||
maxQueued := envInt("XWORKMATE_BRIDGE_OPENCLAW_GATEWAY_MAX_QUEUED", defaultOpenClawGatewayMaxQueued)
|
||||
maxQueued := admissionInt(admissionConfig.MaxQueued, "XWORKMATE_BRIDGE_OPENCLAW_GATEWAY_MAX_QUEUED", defaultOpenClawGatewayMaxQueued)
|
||||
if maxQueued < 0 {
|
||||
log.Printf("level=warn component=openclaw_gateway event=invalid_admission_config key=%q value=%d", "max_queued", maxQueued)
|
||||
maxQueued = defaultOpenClawGatewayMaxQueued
|
||||
}
|
||||
timeout := envDuration("XWORKMATE_BRIDGE_OPENCLAW_GATEWAY_QUEUE_TIMEOUT", defaultOpenClawGatewayQueueWait)
|
||||
timeout := admissionDuration(admissionConfig.QueueTimeout, "queue_timeout", "XWORKMATE_BRIDGE_OPENCLAW_GATEWAY_QUEUE_TIMEOUT", defaultOpenClawGatewayQueueWait)
|
||||
if timeout <= 0 {
|
||||
log.Printf("level=warn component=openclaw_gateway event=invalid_admission_config key=%q value=%q", "queue_timeout", timeout.String())
|
||||
timeout = defaultOpenClawGatewayQueueWait
|
||||
}
|
||||
return &openClawGatewayAdmissionGate{
|
||||
@ -53,6 +60,26 @@ func newOpenClawGatewayAdmissionGateFromEnv() *openClawGatewayAdmissionGate {
|
||||
}
|
||||
}
|
||||
|
||||
func admissionInt(configValue *int, envKey string, fallback int) int {
|
||||
if configValue != nil {
|
||||
return *configValue
|
||||
}
|
||||
return envInt(envKey, fallback)
|
||||
}
|
||||
|
||||
func admissionDuration(configValue string, configKey string, envKey string, fallback time.Duration) time.Duration {
|
||||
raw := strings.TrimSpace(configValue)
|
||||
if raw == "" {
|
||||
return envDuration(envKey, fallback)
|
||||
}
|
||||
value, err := time.ParseDuration(raw)
|
||||
if err != nil {
|
||||
log.Printf("level=warn component=openclaw_gateway event=invalid_duration_config key=%q value=%q", configKey, raw)
|
||||
return fallback
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
func (g *openClawGatewayAdmissionGate) acquire(
|
||||
ctx context.Context,
|
||||
notifyQueued func(position int, queued int),
|
||||
|
||||
46
internal/acp/openclaw_gateway_admission_test.go
Normal file
46
internal/acp/openclaw_gateway_admission_test.go
Normal file
@ -0,0 +1,46 @@
|
||||
package acp
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestOpenClawGatewayAdmissionGateUsesConfigValues(t *testing.T) {
|
||||
maxActive := 3
|
||||
maxQueued := 7
|
||||
gate := newOpenClawGatewayAdmissionGate(&BridgeConfig{
|
||||
OpenClawGateway: OpenClawGatewayConfig{
|
||||
MaxActive: &maxActive,
|
||||
MaxQueued: &maxQueued,
|
||||
QueueTimeout: "45s",
|
||||
},
|
||||
})
|
||||
|
||||
if gate.maxActive != 3 {
|
||||
t.Fatalf("expected max active from config, got %d", gate.maxActive)
|
||||
}
|
||||
if gate.maxQueued != 7 {
|
||||
t.Fatalf("expected max queued from config, got %d", gate.maxQueued)
|
||||
}
|
||||
if gate.timeout != 45*time.Second {
|
||||
t.Fatalf("expected queue timeout from config, got %s", gate.timeout)
|
||||
}
|
||||
}
|
||||
|
||||
func TestOpenClawGatewayAdmissionGateFallsBackToEnvWithoutConfig(t *testing.T) {
|
||||
t.Setenv("XWORKMATE_BRIDGE_OPENCLAW_GATEWAY_MAX_ACTIVE", "4")
|
||||
t.Setenv("XWORKMATE_BRIDGE_OPENCLAW_GATEWAY_MAX_QUEUED", "0")
|
||||
t.Setenv("XWORKMATE_BRIDGE_OPENCLAW_GATEWAY_QUEUE_TIMEOUT", "30s")
|
||||
|
||||
gate := newOpenClawGatewayAdmissionGate(&BridgeConfig{})
|
||||
|
||||
if gate.maxActive != 4 {
|
||||
t.Fatalf("expected max active from env, got %d", gate.maxActive)
|
||||
}
|
||||
if gate.maxQueued != 0 {
|
||||
t.Fatalf("expected max queued from env, got %d", gate.maxQueued)
|
||||
}
|
||||
if gate.timeout != 30*time.Second {
|
||||
t.Fatalf("expected queue timeout from env, got %s", gate.timeout)
|
||||
}
|
||||
}
|
||||
@ -42,11 +42,13 @@ func newHTTPServer(addr string, handler http.Handler) *http.Server {
|
||||
}
|
||||
|
||||
func NewServer() *Server {
|
||||
config := loadBridgeConfig()
|
||||
s := &Server{
|
||||
sessions: make(map[string]*session),
|
||||
config: config,
|
||||
allowedOrigins: shared.ParseAllowedOrigins(shared.EnvOrDefault("ACP_ALLOWED_ORIGINS", "https://xworkmate.svc.plus,http://localhost:*,http://127.0.0.1:*")),
|
||||
authService: service.NewStaticTokenAuthService(shared.EnvOrDefault("BRIDGE_AUTH_TOKEN", "")),
|
||||
openClawGate: newOpenClawGatewayAdmissionGateFromEnv(),
|
||||
openClawGate: newOpenClawGatewayAdmissionGate(config),
|
||||
}
|
||||
s.Bootstrap()
|
||||
return s
|
||||
|
||||
Loading…
Reference in New Issue
Block a user