package config import ( "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" "fmt" "strings" "github.com/spf13/viper" ) type Config struct { Language string `yaml:"language"` Server ServerConfig `yaml:"server"` DB DBConfig `yaml:"db"` Logger LoggerConfig `yaml:"logger"` Storage StorageConfig `yaml:"storage"` VectorDB VectorDBConfig `yaml:"vectorDB"` MCP MCPConfig `yaml:"mcp"` WxWork WxWorkConfig `yaml:"wxWork"` } func (c Config) LanguageOrDefault() string { switch strings.ToLower(strings.TrimSpace(c.Language)) { case "zh", "zh-cn", "zh_cn", "zh-hans": return "zh-CN" case "en", "en-us", "en_us": return "en-US" default: return "zh-CN" } } type WxWorkNotifyConfig struct { Enabled bool `yaml:"enabled"` ToUsers []int64 `yaml:"toUsers"` Safe bool `yaml:"safe"` EnableDuplicateCheck bool `yaml:"enableDuplicateCheck"` DuplicateCheckInterval int `yaml:"duplicateCheckInterval"` } type ServerConfig struct { Port int `yaml:"port"` FrontendURL string `yaml:"frontendUrl"` CORS CORSConfig `yaml:"cors"` } func (s ServerConfig) Address() string { if s.Port <= 0 { return ":8080" } return fmt.Sprintf(":%d", s.Port) } func (s ServerConfig) FrontendBaseURL() string { if value := strings.TrimRight(strings.TrimSpace(s.FrontendURL), "/"); value != "" { return value } return "http://127.0.0.1:3000" } type CORSConfig struct { // AllowedOrigins 是允许浏览器跨域访问的 Origin 白名单,必须包含协议和域名。 // 留空表示不允许跨域请求;同源请求通常不会携带 Origin,不受影响。 AllowedOrigins []string `yaml:"allowedOrigins"` } type DBConfig struct { Type string `yaml:"type"` DSN string `yaml:"dsn"` MaxIdleConns int `yaml:"maxIdleConns"` MaxOpenConns int `yaml:"maxOpenConns"` ConnMaxIdleTimeSeconds int `yaml:"connMaxIdleTimeSeconds"` ConnMaxLifetimeSeconds int `yaml:"connMaxLifetimeSeconds"` } type LoggerConfig struct { Level string `yaml:"level"` Format string `yaml:"format"` AddSource bool `yaml:"addSource"` } type StorageConfig struct { Default enums.AssetProvider `yaml:"default"` MaxUploadSizeMB int64 `yaml:"maxUploadSizeMB"` Local LocalStorageConfig `yaml:"local"` OSS OSSStorageConfig `yaml:"oss"` } func (s StorageConfig) MaxUploadSizeBytes() int64 { if s.MaxUploadSizeMB <= 0 { return 5 << 20 } return s.MaxUploadSizeMB << 20 } func (s StorageConfig) MaxRequestBodySizeBytes() int64 { limit := s.MaxUploadSizeBytes() return limit + (1 << 20) } type LocalStorageConfig struct { Root string `yaml:"root"` BaseURL string `yaml:"baseUrl"` } type OSSStorageConfig struct { Endpoint string `yaml:"endpoint"` Bucket string `yaml:"bucket"` AccessKeyID string `yaml:"accessKeyId"` AccessKeySecret string `yaml:"accessKeySecret"` BaseURL string `yaml:"baseUrl"` Private bool `yaml:"private"` SignedURLExpire int `yaml:"signedUrlExpireSeconds"` } type VectorDBConfig struct { Type string `yaml:"type"` Qdrant QdrantVectorDBConfig `yaml:"qdrant"` LanceDB LanceDBVectorDBConfig `yaml:"lancedb"` } type QdrantVectorDBConfig struct { Host string `yaml:"host"` GrpcPort int `yaml:"grpcPort"` APIKey string `yaml:"apiKey"` UseTLS bool `yaml:"useTls"` } type LanceDBVectorDBConfig struct { Path string `yaml:"path"` } type MCPConfig struct { Enabled bool `yaml:"enabled"` Servers map[string]MCPServerConfig `yaml:"servers"` } type MCPServerConfig struct { Enabled bool `yaml:"enabled"` Endpoint string `yaml:"endpoint"` TimeoutMS int `yaml:"timeoutMs"` Headers map[string]string `yaml:"headers"` } // WxWorkConfig defines the WeCom application used for customer-service // callbacks and notifications. Dashboard login is owned by be-system. type WxWorkConfig struct { // Enabled controls whether the WeCom SDK is initialized. Enabled bool `yaml:"enabled"` // CorpID 为企业微信公司 ID,例如 wwxxxxxxxxxxxxxxxx。 CorpID string `yaml:"corpId"` // CorpSecret 为企业微信应用 Secret,用于换取 access_token。 CorpSecret string `yaml:"corpSecret"` // AgentID 为企业微信自建应用 AgentID。 AgentID string `yaml:"agentId"` // RSAPrivateKey 为企业微信回调解密私钥。 RSAPrivateKey string `yaml:"rsaPrivateKey"` // Token 为企业微信回调 Token。 Token string `yaml:"token"` // EncodingAESKey 为企业微信消息加解密密钥。 EncodingAESKey string `yaml:"encodingAESKey"` // Notify 为企业微信应用消息通知配置。 Notify WxWorkNotifyConfig `yaml:"notify"` } func Load(path string) (*Config, error) { v := viper.New() v.SetConfigFile(path) v.SetConfigType("yaml") v.SetEnvPrefix("AGENT_DESK") v.SetEnvKeyReplacer(strings.NewReplacer(".", "_")) v.AutomaticEnv() if err := v.ReadInConfig(); err != nil { return nil, err } cfg := &Config{} if err := v.Unmarshal(cfg); err != nil { return nil, err } return cfg, nil }