-
Notifications
You must be signed in to change notification settings - Fork 4
/
init.go
218 lines (182 loc) · 5.98 KB
/
init.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
// Package main provides the initialization and setup functions for the application.
package main
import (
"embed"
"fmt"
"os"
"os/exec"
"path/filepath"
"github.com/blevesearch/bleve/v2"
"github.com/pterm/pterm"
)
// embedFS embeds the necessary files for the application.
//
//go:embed public/* pkg/llm/local/bin/*
var embedFS embed.FS
// initializeApplication initializes the application with the given configuration.
func initializeApplication(config *AppConfig) {
createDataDirectory(config.DataPath)
initializeServer(config.DataPath)
initializeDatabase(config)
initializeDefaultProject(config)
initializeSearchIndex(config.DataPath)
downloadDefaultImageModel(config)
}
// createDataDirectory creates the data directory and removes the temporary directory if it exists.
func createDataDirectory(dataPath string) {
if err := os.MkdirAll(dataPath, 0755); err != nil {
logFatalError("Error creating data directory", err)
}
tmpDir := filepath.Join(dataPath, "web", "public", "tmp")
if err := os.RemoveAll(tmpDir); err != nil {
pterm.Error.Println("Error deleting tmp directory:", err)
}
}
// initializeServer initializes the server by setting up necessary directories and files.
func initializeServer(dataPath string) {
if _, err := initServer(dataPath); err != nil {
logFatalError("Error initializing server", err)
}
pterm.Info.Println("Server initialized")
}
// initializeDatabase initializes the SQLite database and performs auto-migration.
func initializeDatabase(config *AppConfig) {
var err error
sqliteDB, err = NewSQLiteDB(config.DataPath)
if err != nil {
logFatalError("Failed to initialize database", err)
}
err = sqliteDB.AutoMigrate(
&Project{},
&ModelParams{},
&ImageModel{},
&SelectedModels{},
&Chat{},
&URLTracking{},
&Assistant{},
)
if err != nil {
logFatalError("Failed to auto-migrate database", err)
}
pterm.Info.Println("Database initialized")
}
// initializeDefaultProject initializes the default project based on the configuration.
func initializeDefaultProject(config *AppConfig) {
currentProject = config.DefaultProjectConfig
err := sqliteDB.CreateProject(¤tProject)
if err != nil {
pterm.Info.Println("Default project already exists")
}
projects, err := sqliteDB.ListProjects()
if err != nil {
logFatalError("Failed to list projects", err)
}
displayProjects(projects)
}
// initializeSearchIndex initializes the search index using Bleve.
func initializeSearchIndex(dataPath string) {
searchDB := filepath.Join(dataPath, "search.bleve")
var err error
if _, err := os.Stat(searchDB); os.IsNotExist(err) {
mapping := bleve.NewIndexMapping()
searchIndex, err = bleve.New(searchDB, mapping)
if err != nil {
logFatalError("Failed to create search index", err)
}
} else {
searchIndex, err = bleve.Open(searchDB)
if err != nil {
logFatalError("Failed to open search index", err)
}
}
if err != nil {
logFatalError("Failed to initialize search index", err)
}
}
// loadModelParams loads the model parameters from the configuration and saves them to the database.
func loadModelParams(config *AppConfig) ([]ModelParams, error) {
var modelParams []ModelParams
for _, model := range config.LanguageModels {
modelParam := createModelParam(&model, config.DataPath)
modelParams = append(modelParams, modelParam)
}
if err := LoadModelDataToDB(sqliteDB, modelParams); err != nil {
return nil, err
}
displayModelParams(modelParams)
return modelParams, nil
}
// displayModelParams displays the model parameters in a table format.
func displayModelParams(modelParams []ModelParams) {
tableData := [][]string{{"Model Name", "Context Size", "Downloaded"}}
for _, param := range modelParams {
tableData = append(tableData, []string{
param.Name,
fmt.Sprintf("%d", param.Options.CtxSize),
fmt.Sprintf("%t", param.Downloaded),
})
}
pterm.DefaultTable.WithData(tableData).WithHasHeader().WithStyle(pterm.NewStyle(pterm.FgCyan)).Render()
}
// downloadDefaultImageModel downloads the default image model based on the configuration.
func downloadDefaultImageModel(config *AppConfig) {
if err := DownloadDefaultImageModel(config); err != nil {
pterm.Error.Println("Failed to download default image model:", err)
}
}
// initServer initializes the server by setting up necessary directories and files.
func initServer(configPath string) (string, error) {
if err := setupDirectory(configPath, "web", "public"); err != nil {
return "", err
}
if err := setupDirectory(configPath, "gguf", "pkg/llm/local/bin"); err != nil {
return "", err
}
if err := setupComfyUI(configPath); err != nil {
return "", err
}
if err := setupComfyUIEssentials(configPath); err != nil {
return "", err
}
if err := setupImpactPack(configPath); err != nil {
return "", err
}
if err := setupComfyUImtb(configPath); err != nil {
return "", err
}
// Needs work, finish in future commit
// if err := setupKolors(configPath); err != nil {
// return "", err
// }
return configPath, nil
}
// setupDirectory creates a directory and copies files into it.
func setupDirectory(configPath, dirName, srcDir string) error {
dirPath := filepath.Join(configPath, dirName)
if err := os.MkdirAll(dirPath, 0755); err != nil {
return fmt.Errorf("failed to create directory %s: %w", dirPath, err)
}
if err := CopyFiles(embedFS, srcDir, dirPath); err != nil {
return fmt.Errorf("failed to copy files to %s: %w", dirPath, err)
}
return setExecutablePermissions(dirPath)
}
// installPythonRequirements installs Python requirements from a requirements.txt file.
func installPythonRequirements(reqPath string) error {
cmd := exec.Command("pip3", "install", "-r", reqPath)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
return cmd.Run()
}
// setExecutablePermissions sets executable permissions on all files in a directory.
func setExecutablePermissions(dirPath string) error {
return filepath.Walk(dirPath, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if info.IsDir() {
return nil
}
return os.Chmod(path, 0755)
})
}