add model download CLI command
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
@@ -403,6 +404,7 @@ func modelCmd() *cobra.Command {
|
||||
}
|
||||
|
||||
cmd.AddCommand(modelListCmd())
|
||||
cmd.AddCommand(modelDownloadCmd())
|
||||
|
||||
return cmd
|
||||
}
|
||||
@@ -527,3 +529,60 @@ func printModelLine(m provider.Model) {
|
||||
|
||||
fmt.Println(line)
|
||||
}
|
||||
|
||||
func modelDownloadCmd() *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: "download <model-name>",
|
||||
Short: "Download a local model (e.g. whisper models)",
|
||||
Args: cobra.ExactArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
return runModelDownload(cmd.Context(), args[0])
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func runModelDownload(ctx context.Context, modelName string) error {
|
||||
// find the model across all providers
|
||||
model, _, err := provider.FindModelByID(modelName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unknown model: %s", modelName)
|
||||
}
|
||||
|
||||
// check if it needs download (local model)
|
||||
if !model.NeedsDownload() {
|
||||
fmt.Printf("model '%s' is a cloud model and does not require download\n", modelName)
|
||||
return nil
|
||||
}
|
||||
|
||||
// check if already installed
|
||||
if whisper.IsInstalled(modelName) {
|
||||
path := whisper.GetModelPath(modelName)
|
||||
fmt.Printf("model '%s' is already installed at %s\n", modelName, path)
|
||||
return nil
|
||||
}
|
||||
|
||||
// download with progress
|
||||
fmt.Printf("downloading %s", modelName)
|
||||
if model.LocalInfo != nil && model.LocalInfo.Size != "" {
|
||||
fmt.Printf(" (%s)", model.LocalInfo.Size)
|
||||
}
|
||||
fmt.Println("...")
|
||||
|
||||
var lastPercent int
|
||||
err = whisper.Download(ctx, modelName, func(downloaded, total int64) {
|
||||
if total > 0 {
|
||||
percent := int(downloaded * 100 / total)
|
||||
if percent >= lastPercent+10 {
|
||||
fmt.Printf("%d%% ", percent)
|
||||
lastPercent = percent
|
||||
}
|
||||
}
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("download failed: %w", err)
|
||||
}
|
||||
|
||||
path := whisper.GetModelPath(modelName)
|
||||
fmt.Printf("\ndownload complete: %s\n", path)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -245,4 +245,14 @@ Started: Sun Feb 1 12:22:47 AM CET 2026
|
||||
- For local models: shows [x] if installed via whisper.IsInstalled(), [ ] if not
|
||||
- Shows: Model ID, Description, [streaming] tag if applicable, [size] for local models
|
||||
- Groups output by provider with headers
|
||||
- All tests passing, typecheck passes
|
||||
|
||||
### Task 25: Add model download CLI command
|
||||
- Created `modelDownloadCmd()` subcommand with Use: 'download <model-name>'
|
||||
- Uses `provider.FindModelByID()` to search all providers for model
|
||||
- Checks `model.NeedsDownload()` - if false, prints 'cloud model, does not require download'
|
||||
- Checks `whisper.IsInstalled()` - if true, prints 'already installed at {path}'
|
||||
- Downloads with progress callback showing percentage (10%, 20%, ...)
|
||||
- Prints success message with full model path
|
||||
- Tested: cloud model rejection, unknown model error, download with progress, already installed
|
||||
- All tests passing, typecheck passes
|
||||
+1
-1
@@ -596,7 +596,7 @@
|
||||
"Shows error for cloud models that don't need download",
|
||||
"Typecheck passes"
|
||||
],
|
||||
"passes": false
|
||||
"passes": true
|
||||
},
|
||||
{
|
||||
"title": "Add model remove CLI command",
|
||||
|
||||
Reference in New Issue
Block a user