spoc-bot-vr/config.go

127 lines
2.8 KiB
Go

package main
import (
"context"
"encoding/json"
"fmt"
"os"
"regexp"
"strconv"
"strings"
"time"
)
type Config struct {
Port int
Debug bool
InitializeSlack bool
SlackToken string
SlackChannels []string
PostgresConn string
BasicAuthUser string
BasicAuthPassword string
FillWithTestdata bool
OllamaURL string
OllamaModel string
LocalCheckpoint string
LocalTokenizer string
AssetPattern string
DatacenterPattern string
storage Storage
queue Queue
driver Driver
ai AI
}
func newConfig(ctx context.Context) (Config, error) {
return newConfigFromEnv(ctx, os.Getenv)
}
func newConfigFromEnv(ctx context.Context, getEnv func(string) string) (Config, error) {
def := Config{
Port: 38080,
OllamaModel: "gemma:2b",
AssetPattern: `(dpg|svc|red)-[a-z0-9-]*`,
DatacenterPattern: `[a-z]{4}[a-z]*-[0-9]`,
}
var m map[string]any
if b, err := json.Marshal(def); err != nil {
return Config{}, err
} else if err := json.Unmarshal(b, &m); err != nil {
return Config{}, err
}
re := regexp.MustCompile(`[A-Z]`)
for k, v := range m {
envK := k
idxes := re.FindAllIndex([]byte(envK), -1)
for i := len(idxes) - 1; i >= 0; i-- {
idx := idxes[i]
if idx[0] > 0 {
envK = fmt.Sprintf("%s_%s", envK[:idx[0]], envK[idx[0]:])
}
}
envK = strings.ToUpper(envK)
s := getEnv(envK)
if s == "" {
continue
}
switch v.(type) {
case string:
m[k] = s
case int64, float64:
n, err := strconv.ParseFloat(s, 32)
if err != nil {
return Config{}, err
}
m[k] = n
case bool:
got, err := strconv.ParseBool(s)
if err != nil {
return Config{}, err
}
m[k] = got
case nil, []interface{}:
m[k] = strings.Split(s, ",")
default:
return Config{}, fmt.Errorf("not impl: parse %s as %T", envK, v)
}
}
var result Config
if b, err := json.Marshal(m); err != nil {
return Config{}, err
} else if err := json.Unmarshal(b, &result); err != nil {
return Config{}, err
}
result.driver = NewRAM()
if result.PostgresConn != "" {
ctx, can := context.WithTimeout(ctx, time.Second*10)
defer can()
pg, err := NewPostgres(ctx, result.PostgresConn)
if err != nil {
return Config{}, err
}
result.driver = pg
}
if result.FillWithTestdata {
if err := FillWithTestdata(ctx, result.driver, result.AssetPattern, result.DatacenterPattern); err != nil {
return Config{}, err
}
}
result.storage = NewStorage(result.driver)
result.queue = NewQueue(result.driver)
if result.OllamaURL != "" {
result.ai = NewAIOllama(result.OllamaURL, result.OllamaModel)
} else if result.LocalCheckpoint != "" && result.LocalTokenizer != "" {
result.ai = NewAILocal(result.LocalCheckpoint, result.LocalTokenizer, 0.9, 128, 0.9)
} else {
result.ai = NewAINoop()
}
return result, nil
}