feat: Go backend, enhanced search, new widgets, Docker deploy

Major changes:
- Add Go backend (backend/) with microservices architecture
- Enhanced master-agents-svc: reranker, content-classifier, stealth-crawler,
  proxy-manager, media-search, fastClassifier, language detection
- New web-svc widgets: KnowledgeCard, ProductCard, ProfileCard, VideoCard,
  UnifiedCard, CardGallery, InlineImageGallery, SourcesPanel, RelatedQuestions
- Improved discover-svc with discover-db integration
- Docker deployment improvements (Caddyfile, vendor.sh, BUILD.md)
- Library-svc: project_id schema migration
- Remove deprecated finance-svc and travel-svc
- Localization improvements across services

Made-with: Cursor
This commit is contained in:
home
2026-02-27 04:15:32 +03:00
parent 328d968f3f
commit 06fe57c765
285 changed files with 53132 additions and 1871 deletions

View File

@@ -0,0 +1,173 @@
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
// Service URLs
ChatSvcURL string
AgentSvcURL string
SearchSvcURL string
LLMSvcURL string
ScraperSvcURL string
MemorySvcURL string
LibrarySvcURL 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
// 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
// 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),
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"),
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"),
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"),
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 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
}