Reapply "don't require pulling stubs for cloud models"

This reverts commit 97d2f05a6d.
This commit is contained in:
Jeffrey Morgan
2026-03-03 13:17:10 -08:00
committed by GitHub
parent e8fcb29586
commit 799e51d419
23 changed files with 2849 additions and 114 deletions

View File

@@ -14,6 +14,7 @@ import (
"github.com/ollama/ollama/api"
internalcloud "github.com/ollama/ollama/internal/cloud"
"github.com/ollama/ollama/internal/modelref"
"github.com/ollama/ollama/progress"
"github.com/spf13/cobra"
)
@@ -324,12 +325,7 @@ func SelectModelWithSelector(ctx context.Context, selector SingleSelector) (stri
// If the selected model isn't installed, pull it first
if !existingModels[selected] {
if cloudModels[selected] {
// Cloud models only pull a small manifest; no confirmation needed
if err := pullModel(ctx, client, selected); err != nil {
return "", fmt.Errorf("failed to pull %s: %w", selected, err)
}
} else {
if !isCloudModelName(selected) {
msg := fmt.Sprintf("Download %s?", selected)
if ok, err := confirmPrompt(msg); err != nil {
return "", err
@@ -524,7 +520,7 @@ func selectModelsWithSelectors(ctx context.Context, name, current string, single
var toPull []string
for _, m := range selected {
if !existingModels[m] {
if !existingModels[m] && !isCloudModelName(m) {
toPull = append(toPull, m)
}
}
@@ -550,12 +546,28 @@ func selectModelsWithSelectors(ctx context.Context, name, current string, single
return selected, nil
}
// TODO(parthsareen): consolidate pull logic from call sites
func pullIfNeeded(ctx context.Context, client *api.Client, existingModels map[string]bool, model string) error {
if existingModels[model] {
if isCloudModelName(model) || existingModels[model] {
return nil
}
msg := fmt.Sprintf("Download %s?", model)
if ok, err := confirmPrompt(msg); err != nil {
return confirmAndPull(ctx, client, model)
}
// TODO(parthsareen): pull this out to tui package
// ShowOrPull checks if a model exists via client.Show and offers to pull it if not found.
func ShowOrPull(ctx context.Context, client *api.Client, model string) error {
if _, err := client.Show(ctx, &api.ShowRequest{Model: model}); err == nil {
return nil
}
if isCloudModelName(model) {
return nil
}
return confirmAndPull(ctx, client, model)
}
func confirmAndPull(ctx context.Context, client *api.Client, model string) error {
if ok, err := confirmPrompt(fmt.Sprintf("Download %s?", model)); err != nil {
return err
} else if !ok {
return errCancelled
@@ -567,26 +579,6 @@ func pullIfNeeded(ctx context.Context, client *api.Client, existingModels map[st
return nil
}
// TODO(parthsareen): pull this out to tui package
// ShowOrPull checks if a model exists via client.Show and offers to pull it if not found.
func ShowOrPull(ctx context.Context, client *api.Client, model string) error {
if _, err := client.Show(ctx, &api.ShowRequest{Model: model}); err == nil {
return nil
}
// Cloud models only pull a small manifest; skip the download confirmation
// TODO(parthsareen): consolidate with cloud config changes
if strings.HasSuffix(model, "cloud") {
return pullModel(ctx, client, model)
}
if ok, err := confirmPrompt(fmt.Sprintf("Download %s?", model)); err != nil {
return err
} else if !ok {
return errCancelled
}
fmt.Fprintf(os.Stderr, "\n")
return pullModel(ctx, client, model)
}
func listModels(ctx context.Context) ([]ModelItem, map[string]bool, map[string]bool, *api.Client, error) {
client, err := api.ClientFromEnvironment()
if err != nil {
@@ -731,10 +723,8 @@ func syncAliases(ctx context.Context, client *api.Client, ac AliasConfigurer, na
}
aliases["primary"] = model
if isCloudModel(ctx, client, model) {
if aliases["fast"] == "" || !isCloudModel(ctx, client, aliases["fast"]) {
aliases["fast"] = model
}
if isCloudModelName(model) {
aliases["fast"] = model
} else {
delete(aliases, "fast")
}
@@ -1020,7 +1010,7 @@ Examples:
existingAliases = aliases
// Ensure cloud models are authenticated
if isCloudModel(cmd.Context(), client, model) {
if isCloudModelName(model) {
if err := ensureAuth(cmd.Context(), client, map[string]bool{model: true}, []string{model}); err != nil {
return err
}
@@ -1209,7 +1199,7 @@ func buildModelList(existing []modelInfo, preChecked []string, current string) (
// When user has no models, preserve recommended order.
notInstalled := make(map[string]bool)
for i := range items {
if !existingModels[items[i].Name] {
if !existingModels[items[i].Name] && !cloudModels[items[i].Name] {
notInstalled[items[i].Name] = true
var parts []string
if items[i].Description != "" {
@@ -1303,7 +1293,8 @@ func IsCloudModelDisabled(ctx context.Context, name string) bool {
}
func isCloudModelName(name string) bool {
return strings.HasSuffix(name, ":cloud") || strings.HasSuffix(name, "-cloud")
// TODO(drifkin): Replace this wrapper with inlining once things stabilize a bit
return modelref.HasExplicitCloudSource(name)
}
func filterCloudModels(existing []modelInfo) []modelInfo {