package lmcli import ( "fmt" "os" "path/filepath" "git.mlow.ca/mlow/lmcli/pkg/lmcli/model" "git.mlow.ca/mlow/lmcli/pkg/lmcli/provider" "git.mlow.ca/mlow/lmcli/pkg/lmcli/provider/anthropic" "git.mlow.ca/mlow/lmcli/pkg/lmcli/provider/openai" "git.mlow.ca/mlow/lmcli/pkg/lmcli/tools" "git.mlow.ca/mlow/lmcli/pkg/util/tty" "gorm.io/driver/sqlite" "gorm.io/gorm" ) type Context struct { Config *Config Store ConversationStore Chroma *tty.ChromaHighlighter EnabledTools []model.Tool } func NewContext() (*Context, error) { configFile := filepath.Join(configDir(), "config.yaml") config, err := NewConfig(configFile) if err != nil { Fatal("%v\n", err) } databaseFile := filepath.Join(dataDir(), "conversations.db") db, err := gorm.Open(sqlite.Open(databaseFile), &gorm.Config{}) if err != nil { return nil, fmt.Errorf("Error establishing connection to store: %v", err) } store, err := NewSQLStore(db) if err != nil { Fatal("%v\n", err) } chroma := tty.NewChromaHighlighter("markdown", *config.Chroma.Formatter, *config.Chroma.Style) var enabledTools []model.Tool for _, toolName := range *config.Tools.EnabledTools { tool, ok := tools.AvailableTools[toolName] if ok { enabledTools = append(enabledTools, tool) } } return &Context{config, store, chroma, enabledTools}, nil } func (c *Context) GetModels() (models []string) { for _, m := range *c.Config.Anthropic.Models { models = append(models, m) } for _, m := range *c.Config.OpenAI.Models { models = append(models, m) } return } func (c *Context) GetCompletionProvider(model string) (provider.ChatCompletionClient, error) { for _, m := range *c.Config.Anthropic.Models { if m == model { anthropic := &anthropic.AnthropicClient{ APIKey: *c.Config.Anthropic.APIKey, } return anthropic, nil } } for _, m := range *c.Config.OpenAI.Models { if m == model { openai := &openai.OpenAIClient{ APIKey: *c.Config.OpenAI.APIKey, } return openai, nil } } return nil, fmt.Errorf("unknown model: %s", model) } func configDir() string { var configDir string xdgConfigHome := os.Getenv("XDG_CONFIG_HOME") if xdgConfigHome != "" { configDir = filepath.Join(xdgConfigHome, "lmcli") } else { userHomeDir, _ := os.UserHomeDir() configDir = filepath.Join(userHomeDir, ".config/lmcli") } os.MkdirAll(configDir, 0755) return configDir } func dataDir() string { var dataDir string xdgDataHome := os.Getenv("XDG_DATA_HOME") if xdgDataHome != "" { dataDir = filepath.Join(xdgDataHome, "lmcli") } else { userHomeDir, _ := os.UserHomeDir() dataDir = filepath.Join(userHomeDir, ".local/share/lmcli") } os.MkdirAll(dataDir, 0755) return dataDir } func Fatal(format string, args ...any) { fmt.Fprintf(os.Stderr, format, args...) os.Exit(1) } func Warn(format string, args ...any) { fmt.Fprintf(os.Stderr, format, args...) }