Spaces: - Perplexity-like UI with collaboration features - Space detail page with threads/members tabs - Invite members via email, role management - New space creation with icon/color picker Model selector: - Added Ollama client for free Auto model - GooSeek 1.0 via Timeweb (tariff-based) - Frontend model dropdown in ChatInput Auth & Infrastructure: - Fixed auth-svc missing from Dockerfile.all - Removed duplicate ratelimit_tiered.go (conflict) - Added Redis to api-gateway for rate limiting - Fixed Next.js proxy for local development UI improvements: - Redesigned login button in sidebar (gradient) - Settings page with tabs (account/billing/prefs) - Auth pages visual refresh Made-with: Cursor
202 lines
5.8 KiB
Go
202 lines
5.8 KiB
Go
package config
|
|
|
|
import (
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/joho/godotenv"
|
|
)
|
|
|
|
type Config struct {
|
|
Environment string
|
|
LogLevel string
|
|
|
|
// Service ports
|
|
APIGatewayPort int
|
|
ChatSvcPort int
|
|
AgentSvcPort int
|
|
SearchSvcPort int
|
|
LLMSvcPort int
|
|
ScraperSvcPort int
|
|
AdminSvcPort int
|
|
|
|
// Service URLs
|
|
ChatSvcURL string
|
|
AgentSvcURL string
|
|
SearchSvcURL string
|
|
LLMSvcURL string
|
|
ScraperSvcURL string
|
|
MemorySvcURL string
|
|
LibrarySvcURL string
|
|
AdminSvcURL string
|
|
|
|
// External services
|
|
SearXNGURL string
|
|
SearXNGFallbackURL []string
|
|
Crawl4AIURL string
|
|
RedisURL string
|
|
DatabaseURL string
|
|
DiscoverSvcURL string
|
|
CollectionSvcURL string
|
|
FileSvcURL string
|
|
ThreadSvcURL string
|
|
ComputerSvcURL string
|
|
FinanceHeatmapURL string
|
|
LearningSvcURL string
|
|
|
|
// MinIO / S3 storage
|
|
MinioEndpoint string
|
|
MinioAccessKey string
|
|
MinioSecretKey string
|
|
MinioBucket string
|
|
MinioUseSSL bool
|
|
|
|
// Auth
|
|
JWTSecret string
|
|
AuthSvcURL string
|
|
|
|
// LLM defaults
|
|
DefaultLLMProvider string
|
|
DefaultLLMModel string
|
|
OpenAIAPIKey string
|
|
AnthropicAPIKey string
|
|
GeminiAPIKey string
|
|
|
|
// Timeweb Cloud AI
|
|
TimewebAPIBaseURL string
|
|
TimewebAgentAccessID string
|
|
TimewebAPIKey string
|
|
TimewebProxySource string
|
|
|
|
// Ollama (local LLM)
|
|
OllamaBaseURL string
|
|
OllamaModelKey string
|
|
|
|
// Timeouts
|
|
HTTPTimeout time.Duration
|
|
LLMTimeout time.Duration
|
|
ScrapeTimeout time.Duration
|
|
SearchTimeout time.Duration
|
|
|
|
// CORS
|
|
AllowedOrigins []string
|
|
}
|
|
|
|
var cfg *Config
|
|
|
|
func Load() (*Config, error) {
|
|
_ = godotenv.Load()
|
|
_ = godotenv.Load("../.env")
|
|
_ = godotenv.Load("../../.env")
|
|
|
|
cfg = &Config{
|
|
Environment: getEnv("ENVIRONMENT", "production"),
|
|
LogLevel: getEnv("LOG_LEVEL", "info"),
|
|
|
|
APIGatewayPort: getEnvInt("API_GATEWAY_PORT", 3015),
|
|
ChatSvcPort: getEnvInt("CHAT_SVC_PORT", 3005),
|
|
AgentSvcPort: getEnvInt("AGENT_SVC_PORT", 3018),
|
|
SearchSvcPort: getEnvInt("SEARCH_SVC_PORT", 3001),
|
|
LLMSvcPort: getEnvInt("LLM_SVC_PORT", 3020),
|
|
ScraperSvcPort: getEnvInt("SCRAPER_SVC_PORT", 3021),
|
|
AdminSvcPort: getEnvInt("ADMIN_SVC_PORT", 3040),
|
|
|
|
ChatSvcURL: getEnv("CHAT_SVC_URL", "http://localhost:3005"),
|
|
AgentSvcURL: getEnv("MASTER_AGENTS_SVC_URL", "http://localhost:3018"),
|
|
SearchSvcURL: getEnv("SEARCH_SVC_URL", "http://localhost:3001"),
|
|
LLMSvcURL: getEnv("LLM_SVC_URL", "http://localhost:3020"),
|
|
ScraperSvcURL: getEnv("SCRAPER_SVC_URL", "http://localhost:3021"),
|
|
MemorySvcURL: getEnv("MEMORY_SVC_URL", ""),
|
|
LibrarySvcURL: getEnv("LIBRARY_SVC_URL", "http://localhost:3009"),
|
|
AdminSvcURL: getEnv("ADMIN_SVC_URL", "http://localhost:3040"),
|
|
|
|
SearXNGURL: getEnv("SEARXNG_URL", "http://searxng:8080"),
|
|
SearXNGFallbackURL: strings.Split(getEnv("SEARXNG_FALLBACK_URL", ""), ","),
|
|
Crawl4AIURL: getEnv("CRAWL4AI_URL", "http://crawl4ai:11235"),
|
|
RedisURL: getEnv("REDIS_URL", "redis://localhost:6379"),
|
|
DatabaseURL: getEnv("DATABASE_URL", ""),
|
|
DiscoverSvcURL: getEnv("DISCOVER_SVC_URL", "http://localhost:3002"),
|
|
CollectionSvcURL: getEnv("COLLECTION_SVC_URL", "http://localhost:3025"),
|
|
FileSvcURL: getEnv("FILE_SVC_URL", "http://localhost:3026"),
|
|
ThreadSvcURL: getEnv("THREAD_SVC_URL", "http://localhost:3027"),
|
|
ComputerSvcURL: getEnv("COMPUTER_SVC_URL", "http://localhost:3030"),
|
|
FinanceHeatmapURL: getEnv("FINANCE_HEATMAP_SVC_URL", "http://localhost:3033"),
|
|
LearningSvcURL: getEnv("LEARNING_SVC_URL", "http://localhost:3034"),
|
|
|
|
MinioEndpoint: getEnv("MINIO_ENDPOINT", "minio:9000"),
|
|
MinioAccessKey: getEnv("MINIO_ACCESS_KEY", "minioadmin"),
|
|
MinioSecretKey: getEnv("MINIO_SECRET_KEY", "minioadmin"),
|
|
MinioBucket: getEnv("MINIO_BUCKET", "gooseek"),
|
|
MinioUseSSL: getEnv("MINIO_USE_SSL", "false") == "true",
|
|
|
|
JWTSecret: getEnv("JWT_SECRET", ""),
|
|
AuthSvcURL: getEnv("AUTH_SVC_URL", ""),
|
|
|
|
DefaultLLMProvider: getEnv("DEFAULT_LLM_PROVIDER", "openai"),
|
|
DefaultLLMModel: getEnv("DEFAULT_LLM_MODEL", "gpt-4o-mini"),
|
|
OpenAIAPIKey: getEnv("OPENAI_API_KEY", ""),
|
|
AnthropicAPIKey: getEnv("ANTHROPIC_API_KEY", ""),
|
|
GeminiAPIKey: getEnv("GEMINI_API_KEY", ""),
|
|
|
|
TimewebAPIBaseURL: getEnv("TIMEWEB_API_BASE_URL", "https://api.timeweb.cloud"),
|
|
TimewebAgentAccessID: getEnv("TIMEWEB_AGENT_ACCESS_ID", ""),
|
|
TimewebAPIKey: getEnv("TIMEWEB_API_KEY", ""),
|
|
TimewebProxySource: getEnv("TIMEWEB_X_PROXY_SOURCE", "gooseek"),
|
|
|
|
OllamaBaseURL: getEnv("OLLAMA_BASE_URL", "http://ollama:11434"),
|
|
OllamaModelKey: getEnv("OLLAMA_MODEL", "llama3.2"),
|
|
|
|
HTTPTimeout: time.Duration(getEnvInt("HTTP_TIMEOUT_MS", 60000)) * time.Millisecond,
|
|
LLMTimeout: time.Duration(getEnvInt("LLM_TIMEOUT_MS", 120000)) * time.Millisecond,
|
|
ScrapeTimeout: time.Duration(getEnvInt("SCRAPE_TIMEOUT_MS", 25000)) * time.Millisecond,
|
|
SearchTimeout: time.Duration(getEnvInt("SEARCH_TIMEOUT_MS", 10000)) * time.Millisecond,
|
|
|
|
AllowedOrigins: parseOrigins(getEnv("ALLOWED_ORIGINS", "*")),
|
|
}
|
|
|
|
return cfg, nil
|
|
}
|
|
|
|
func Get() *Config {
|
|
if cfg == nil {
|
|
cfg, _ = Load()
|
|
}
|
|
return cfg
|
|
}
|
|
|
|
func getEnv(key, defaultValue string) string {
|
|
if value := os.Getenv(key); value != "" {
|
|
return value
|
|
}
|
|
return defaultValue
|
|
}
|
|
|
|
func getEnvInt(key string, defaultValue int) int {
|
|
if value := os.Getenv(key); value != "" {
|
|
if i, err := strconv.Atoi(value); err == nil {
|
|
return i
|
|
}
|
|
}
|
|
return defaultValue
|
|
}
|
|
|
|
func GetEnvInt(key string, defaultValue int) int {
|
|
return getEnvInt(key, defaultValue)
|
|
}
|
|
|
|
func parseOrigins(s string) []string {
|
|
if s == "*" {
|
|
return []string{"*"}
|
|
}
|
|
origins := strings.Split(s, ",")
|
|
result := make([]string, 0, len(origins))
|
|
for _, o := range origins {
|
|
if trimmed := strings.TrimSpace(o); trimmed != "" {
|
|
result = append(result, trimmed)
|
|
}
|
|
}
|
|
return result
|
|
}
|