(ctx context.Context, systemState *system.SystemState, nameOverride string, config *ModelConfig, configOverrides map[string]any, downloadStatus func(string, string, string, float64), enforceScan bool)
| 159 | } |
| 160 | |
| 161 | func InstallModel(ctx context.Context, systemState *system.SystemState, nameOverride string, config *ModelConfig, configOverrides map[string]any, downloadStatus func(string, string, string, float64), enforceScan bool) (*lconfig.ModelConfig, error) { |
| 162 | basePath := systemState.Model.ModelsPath |
| 163 | // Create base path if it doesn't exist |
| 164 | err := os.MkdirAll(basePath, 0750) |
| 165 | if err != nil { |
| 166 | return nil, fmt.Errorf("failed to create base path: %v", err) |
| 167 | } |
| 168 | |
| 169 | if len(configOverrides) > 0 { |
| 170 | xlog.Debug("Config overrides", "overrides", configOverrides) |
| 171 | } |
| 172 | |
| 173 | // Download files and verify their SHA |
| 174 | for i, file := range config.Files { |
| 175 | // Check for cancellation before each file |
| 176 | select { |
| 177 | case <-ctx.Done(): |
| 178 | return nil, ctx.Err() |
| 179 | default: |
| 180 | } |
| 181 | |
| 182 | xlog.Debug("Checking file exists and matches SHA", "filename", file.Filename) |
| 183 | |
| 184 | if err := utils.VerifyPath(file.Filename, basePath); err != nil { |
| 185 | return nil, err |
| 186 | } |
| 187 | |
| 188 | // Create file path |
| 189 | filePath := filepath.Join(basePath, file.Filename) |
| 190 | |
| 191 | if enforceScan { |
| 192 | scanResults, err := downloader.HuggingFaceScan(downloader.URI(file.URI)) |
| 193 | if err != nil && errors.Is(err, downloader.ErrUnsafeFilesFound) { |
| 194 | xlog.Error("Contains unsafe file(s)!", "model", config.Name, "clamAV", scanResults.ClamAVInfectedFiles, "pickles", scanResults.DangerousPickles) |
| 195 | return nil, err |
| 196 | } |
| 197 | } |
| 198 | uri := downloader.URI(file.URI) |
| 199 | if err := uri.DownloadFileWithContext(ctx, filePath, file.SHA256, i, len(config.Files), downloadStatus); err != nil { |
| 200 | return nil, err |
| 201 | } |
| 202 | } |
| 203 | |
| 204 | // Write prompt template contents to separate files |
| 205 | for _, template := range config.PromptTemplates { |
| 206 | if err := utils.VerifyPath(template.Name+".tmpl", basePath); err != nil { |
| 207 | return nil, err |
| 208 | } |
| 209 | // Create file path |
| 210 | filePath := filepath.Join(basePath, template.Name+".tmpl") |
| 211 | |
| 212 | // Create parent directory |
| 213 | err := os.MkdirAll(filepath.Dir(filePath), 0750) |
| 214 | if err != nil { |
| 215 | return nil, fmt.Errorf("failed to create parent directory for prompt template %q: %v", template.Name, err) |
| 216 | } |
| 217 | // Create and write file content |
| 218 | err = os.WriteFile(filePath, []byte(template.Content), 0644) |
no test coverage detected