Files
ai-agent/internal/config/config.go
2026-03-19 21:46:12 +01:00

134 lines
3.6 KiB
Go
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// config.go Konfiguration, Clients und gemeinsame Verbindungen
package config
import (
"fmt"
"log"
"os"
openai "github.com/sashabaranov/go-openai"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"gopkg.in/yaml.v3"
)
type Config struct {
Qdrant struct {
Host string `yaml:"host"`
Port string `yaml:"port"`
APIKey string `yaml:"api_key"`
Collection string `yaml:"collection"`
} `yaml:"qdrant"`
Embedding struct {
URL string `yaml:"url"`
Model string `yaml:"model"`
Dimensions uint64 `yaml:"dimensions"`
} `yaml:"embedding"`
Chat struct {
URL string `yaml:"url"`
Model string `yaml:"model"`
} `yaml:"chat"`
Discord struct {
Token string `yaml:"token"`
GuildID string `yaml:"guild_id"`
} `yaml:"discord"`
Email struct {
Host string `yaml:"host"`
Port int `yaml:"port"`
User string `yaml:"user"`
Password string `yaml:"password"`
TLS bool `yaml:"tls"`
StartTLS bool `yaml:"starttls"`
Folder string `yaml:"folder"`
Model string `yaml:"model"` // Optional: überschreibt chat.model für Email-Zusammenfassungen
} `yaml:"email"`
Tasks struct {
StorePath string `yaml:"store_path"`
} `yaml:"tasks"`
Daemon struct {
ChannelID string `yaml:"channel_id"`
EmailIntervalMin int `yaml:"email_interval_min"`
TaskReminderHour int `yaml:"task_reminder_hour"`
} `yaml:"daemon"`
BrainRoot string `yaml:"brain_root"`
TopK uint64 `yaml:"top_k"`
ScoreThreshold float32 `yaml:"score_threshold"`
}
var Cfg Config
// NewQdrantConn öffnet eine gRPC-Verbindung zur Qdrant-Instanz.
// Der Aufrufer ist verantwortlich für conn.Close().
func NewQdrantConn() *grpc.ClientConn {
conn, err := grpc.Dial(
fmt.Sprintf("%s:%s", Cfg.Qdrant.Host, Cfg.Qdrant.Port),
grpc.WithTransportCredentials(insecure.NewCredentials()),
)
if err != nil {
log.Fatalf("❌ Qdrant Verbindung fehlgeschlagen: %v", err)
}
return conn
}
// NewEmbeddingClient erstellt einen Client für LocalAI (Embeddings).
func NewEmbeddingClient() *openai.Client {
c := openai.DefaultConfig("localai")
c.BaseURL = Cfg.Embedding.URL
return openai.NewClientWithConfig(c)
}
// NewChatClient erstellt einen Client für Chat-Completion (LocalAI).
func NewChatClient() *openai.Client {
c := openai.DefaultConfig("localai")
c.BaseURL = Cfg.Chat.URL
return openai.NewClientWithConfig(c)
}
// LoadConfig liest config.yml aus dem aktuellen Verzeichnis und validiert Pflichtfelder.
func LoadConfig() {
data, err := os.ReadFile("config.yml")
if err != nil {
log.Fatalf("❌ config.yml nicht gefunden: %v\n Lege config.yml im selben Verzeichnis an.", err)
}
if err := yaml.Unmarshal(data, &Cfg); err != nil {
log.Fatalf("❌ config.yml ungültig: %v", err)
}
validateConfig()
}
// validateConfig prüft Pflichtfelder und gibt früh eine klare Fehlermeldung.
func validateConfig() {
var errs []string
if Cfg.Qdrant.Host == "" {
errs = append(errs, "qdrant.host fehlt")
}
if Cfg.Qdrant.Port == "" {
errs = append(errs, "qdrant.port fehlt")
}
if Cfg.Embedding.URL == "" {
errs = append(errs, "embedding.url fehlt")
}
if Cfg.Embedding.Model == "" {
errs = append(errs, "embedding.model fehlt")
}
if Cfg.Chat.URL == "" {
errs = append(errs, "chat.url fehlt")
}
if Cfg.Chat.Model == "" {
errs = append(errs, "chat.model fehlt")
}
if len(errs) > 0 {
for _, e := range errs {
log.Printf("❌ config.yml: %s", e)
}
log.Fatal("❌ Konfiguration unvollständig Bot wird nicht gestartet.")
}
}