feat: add configurable AgentRouter AI provider
This commit is contained in:
@@ -7,6 +7,18 @@ import (
|
||||
"strconv"
|
||||
)
|
||||
|
||||
const (
|
||||
AIProviderAvalAI = "avalai"
|
||||
AIProviderAgentRouter = "agentrouter"
|
||||
)
|
||||
|
||||
type Provider struct {
|
||||
Name string
|
||||
APIKey string
|
||||
BaseURL string
|
||||
Model string
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
AppEnv string
|
||||
HTTPAddr string
|
||||
@@ -23,9 +35,13 @@ type Config struct {
|
||||
AIGrowthEnabled bool
|
||||
AICoachEnabled bool
|
||||
AIPageInsightsEnabled bool
|
||||
AIProvider string
|
||||
AvalAIAPIKey string
|
||||
AvalAIBaseURL string
|
||||
AvalAIModel string
|
||||
AgentRouterAPIKey string
|
||||
AgentRouterBaseURL string
|
||||
AgentRouterModel string
|
||||
AIDailyRequestBudget int64
|
||||
AIDailyTokenBudget int64
|
||||
AIMaxConcurrent int
|
||||
@@ -39,20 +55,27 @@ type Config struct {
|
||||
|
||||
func Load() (Config, error) {
|
||||
cfg := Config{
|
||||
AppEnv: value("APP_ENV", "development"),
|
||||
HTTPAddr: value("HTTP_ADDR", "127.0.0.1:8080"),
|
||||
DatabaseURL: os.Getenv("DATABASE_URL"),
|
||||
RedisAddr: value("REDIS_ADDR", "localhost:6379"),
|
||||
RedisPassword: os.Getenv("REDIS_PASSWORD"),
|
||||
ImportPath: value("IMPORT_PATH", "data/incoming/challenge_data.csv.gz"),
|
||||
DemoUsername: value("DEMO_USERNAME", "merchant-0001"),
|
||||
DemoPassword: os.Getenv("DEMO_PASSWORD"),
|
||||
SessionSecret: os.Getenv("SESSION_SECRET"),
|
||||
CursorSecret: os.Getenv("CURSOR_SECRET"),
|
||||
FrontendOrigin: value("FRONTEND_ORIGIN", "http://localhost:5173"),
|
||||
AvalAIAPIKey: os.Getenv("AVALAI_API_KEY"),
|
||||
AvalAIBaseURL: value("AVALAI_BASE_URL", "https://api.avalai.ir"),
|
||||
AvalAIModel: value("AVALAI_MODEL", "gpt-5-mini-2025-08-07"),
|
||||
AppEnv: value("APP_ENV", "development"),
|
||||
HTTPAddr: value("HTTP_ADDR", "127.0.0.1:8080"),
|
||||
DatabaseURL: os.Getenv("DATABASE_URL"),
|
||||
RedisAddr: value("REDIS_ADDR", "localhost:6379"),
|
||||
RedisPassword: os.Getenv("REDIS_PASSWORD"),
|
||||
ImportPath: value("IMPORT_PATH", "data/incoming/challenge_data.csv.gz"),
|
||||
DemoUsername: value("DEMO_USERNAME", "merchant-0001"),
|
||||
DemoPassword: os.Getenv("DEMO_PASSWORD"),
|
||||
SessionSecret: os.Getenv("SESSION_SECRET"),
|
||||
CursorSecret: os.Getenv("CURSOR_SECRET"),
|
||||
FrontendOrigin: value("FRONTEND_ORIGIN", "http://localhost:5173"),
|
||||
AIProvider: value("AI_PROVIDER", AIProviderAvalAI),
|
||||
AvalAIAPIKey: os.Getenv("AVALAI_API_KEY"),
|
||||
AvalAIBaseURL: value("AVALAI_BASE_URL", "https://api.avalai.ir"),
|
||||
AvalAIModel: value("AVALAI_MODEL", "gpt-5-mini-2025-08-07"),
|
||||
AgentRouterAPIKey: os.Getenv("AGENTROUTER_API_KEY"),
|
||||
AgentRouterBaseURL: value("AGENTROUTER_BASE_URL", "https://agentrouter.org/v1"),
|
||||
AgentRouterModel: value("AGENTROUTER_MODEL", "gpt-5.6-sol"),
|
||||
}
|
||||
if cfg.AIProvider != AIProviderAvalAI && cfg.AIProvider != AIProviderAgentRouter {
|
||||
return Config{}, fmt.Errorf("config: unsupported AI_PROVIDER %q", cfg.AIProvider)
|
||||
}
|
||||
|
||||
var err error
|
||||
@@ -128,9 +151,13 @@ func (c Config) ValidateAPI() error {
|
||||
if c.AIMaxConcurrent < 1 || c.AICreatePerMinute < 1 || c.AIUncachedScopesPerDay < 1 {
|
||||
return errors.New("config: AI limits must be positive")
|
||||
}
|
||||
if c.AIProvider != "" && c.AIProvider != AIProviderAvalAI && c.AIProvider != AIProviderAgentRouter {
|
||||
return errors.New("config: unsupported AI provider")
|
||||
}
|
||||
if c.AppEnv == "production" && (c.AIGrowthEnabled || c.AICoachEnabled || c.AIPageInsightsEnabled) {
|
||||
if c.AvalAIAPIKey == "" || c.AvalAIModel == "" {
|
||||
return errors.New("config: enabled production AI requires AVALAI_API_KEY and AVALAI_MODEL")
|
||||
provider := c.SelectedAIProvider()
|
||||
if provider.APIKey == "" || provider.Model == "" {
|
||||
return errors.New("config: enabled production AI requires provider API key and model")
|
||||
}
|
||||
if c.AIGrowthEnabled && (c.AIDailyRequestBudget < 1 || c.AIDailyTokenBudget < 1) {
|
||||
return errors.New("config: enabled production AI requires positive daily budgets")
|
||||
@@ -145,6 +172,13 @@ func (c Config) ValidateAPI() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c Config) SelectedAIProvider() Provider {
|
||||
if c.AIProvider == AIProviderAgentRouter {
|
||||
return Provider{Name: AIProviderAgentRouter, APIKey: c.AgentRouterAPIKey, BaseURL: c.AgentRouterBaseURL, Model: c.AgentRouterModel}
|
||||
}
|
||||
return Provider{Name: AIProviderAvalAI, APIKey: c.AvalAIAPIKey, BaseURL: c.AvalAIBaseURL, Model: c.AvalAIModel}
|
||||
}
|
||||
|
||||
func (c Config) ValidateSeed() error {
|
||||
if len(c.DemoPassword) < 12 {
|
||||
return errors.New("config: DEMO_PASSWORD must contain at least 12 characters")
|
||||
|
||||
Reference in New Issue
Block a user