169 lines
4.4 KiB
Go
169 lines
4.4 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"regexp"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
type Config struct {
|
|
Port int
|
|
Debug bool
|
|
InitializeSlack bool
|
|
SlackToken string
|
|
SlackChannels []string
|
|
DriverConn string
|
|
BasicAuthUser string
|
|
BasicAuthPassword string
|
|
FillWithTestdata bool
|
|
OllamaUrl string
|
|
OllamaModel string
|
|
RecapPromptIntro string
|
|
RecapPrompt string
|
|
AssetPattern string
|
|
DatacenterPattern string
|
|
EventNamePattern string
|
|
driver Driver
|
|
storage Storage
|
|
ai AI
|
|
slackToModelPipeline Pipeline
|
|
slackScrapePipeline Pipeline
|
|
modelToPersistencePipeline Pipeline
|
|
persistenceToRecapPipeline Pipeline
|
|
}
|
|
|
|
var (
|
|
renderAssetPattern = `(dpg|svc|red)-[a-z0-9-]*[a-z0-9]|ip-[0-9]+-[0-9]+-[0-9]+-[0-9]+\.[a-z]+-[a-z]+-[0-9]+\.compute\.internal`
|
|
renderDatacenterPattern = `[a-z]{4}[a-z]*-[0-9]`
|
|
renderEventNamePattern = `(\[[^\]]*\] *)?(?P<result>.*)`
|
|
)
|
|
|
|
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: "llama3",
|
|
AssetPattern: renderAssetPattern,
|
|
DatacenterPattern: renderDatacenterPattern,
|
|
EventNamePattern: renderEventNamePattern,
|
|
RecapPromptIntro: "A Slack thread began with the following original post.",
|
|
RecapPrompt: "What is the summary of the responses to the Slack thread consisting of the following messages? Limit the summary to one sentence. Do not include any leading text. Be as brief as possible. No context is needed.",
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
ctx, can := context.WithTimeout(ctx, time.Minute)
|
|
defer can()
|
|
|
|
driver, err := NewDriver(ctx, result.DriverConn)
|
|
if err != nil {
|
|
return Config{}, err
|
|
}
|
|
result.driver = driver
|
|
if !result.FillWithTestdata {
|
|
//} else if err := result.driver.FillWithTestdata(ctx, result.AssetPattern, result.DatacenterPattern, result.EventNamePattern); err != nil {
|
|
} else {
|
|
return Config{}, errors.New("not impl")
|
|
}
|
|
if result.Debug {
|
|
log.Printf("connected to driver at %s (%s @%s)", result.DriverConn, result.driver.engine, result.driver.conn)
|
|
}
|
|
|
|
storage, err := NewStorage(ctx, result.driver)
|
|
if err != nil {
|
|
return Config{}, err
|
|
}
|
|
result.storage = storage
|
|
|
|
if result.OllamaUrl != "" {
|
|
result.ai = NewAIOllama(result.OllamaUrl, result.OllamaModel)
|
|
} else {
|
|
result.ai = NewAINoop()
|
|
}
|
|
|
|
slackToModelPipeline, err := NewSlackToModelPipeline(ctx, result)
|
|
if err != nil {
|
|
return Config{}, err
|
|
}
|
|
result.slackToModelPipeline = slackToModelPipeline
|
|
|
|
modelToPersistencePipeline, err := NewModelToPersistencePipeline(ctx, result)
|
|
if err != nil {
|
|
return Config{}, err
|
|
}
|
|
result.modelToPersistencePipeline = modelToPersistencePipeline
|
|
|
|
slackScrapePipeline, err := NewSlackScrapePipeline(ctx, result)
|
|
if err != nil {
|
|
return Config{}, err
|
|
}
|
|
result.slackScrapePipeline = slackScrapePipeline
|
|
|
|
persistenceToRecapPipeline, err := NewPersistenceToRecapPipeline(ctx, result)
|
|
if err != nil {
|
|
return Config{}, err
|
|
}
|
|
result.persistenceToRecapPipeline = persistenceToRecapPipeline
|
|
|
|
return result, nil
|
|
}
|