fetcher_ollama.go

v0.5.0
Doc Versions Source
1
package tui
2
3
import (
4
	"encoding/json"
5
6
	"sourcecraft.dev/bigbes/claudio/cache"
7
	ollamaAPI "sourcecraft.dev/bigbes/claudio/ollama"
8
)
9
10
type ollamaFetcher struct {
11
	apiKey  string
12
	baseURL string
13
	provKey string
14
}
15
16
func (f ollamaFetcher) ProviderKey() string { return f.provKey }
17
18
func (f ollamaFetcher) FetchAndCategorize(cdb *cache.DB) (CategorizedResult, error) {
19
	var models []ollamaAPI.OllamaModel
20
21
	// Try cache.
22
	if cdb != nil {
23
		if data, ok := cdb.GetModels(f.provKey); ok {
24
			if json.Unmarshal(data, &models) != nil {
25
				models = nil
26
			}
27
		}
28
	}
29
30
	// Fetch from API on cache miss.
31
	if models == nil {
32
		var err error
33
		models, err = ollamaAPI.ListModels(f.baseURL, f.apiKey)
34
		if err != nil {
35
			return CategorizedResult{}, err
36
		}
37
		saveCacheModels(cdb, f.provKey, models)
38
	}
39
40
	// Fetch context lengths and capabilities via /api/show (cached per model+modified_at).
41
	ollamaAPI.FetchModelDetails(models, f.baseURL, f.apiKey, f.provKey, cdb)
42
43
	// For cloud instances, group by provider; for local instances, group by family.
44
	var families []string
45
	var grouped map[string][]ollamaAPI.OllamaModel
46
	if f.provKey == "ollama-cloud" {
47
		// Fetch popular model names from ollama.com (cached).
48
		var popularNames []string
49
		if cdb != nil {
50
			if data, ok := cdb.GetModels("ollama-cloud-popular"); ok {
51
				_ = json.Unmarshal(data, &popularNames)
52
			}
53
		}
54
		if len(popularNames) == 0 {
55
			if names, err := ollamaAPI.FetchPopularNames(); err == nil && len(names) > 0 {
56
				popularNames = names
57
				saveCacheModels(cdb, "ollama-cloud-popular", popularNames)
58
			}
59
		}
60
		families, grouped = ollamaAPI.CategorizeByProvider(models, popularNames)
61
	} else {
62
		families, grouped = ollamaAPI.CategorizeModels(models)
63
	}
64
65
	items := make(map[string][]PickerItem)
66
	for fam, oms := range grouped {
67
		for _, om := range oms {
68
			items[fam] = append(items[fam], PickerItem{ID: om.Name, Name: om.DisplayName(), ContextLength: om.ContextLength})
69
		}
70
	}
71
72
	result := CategorizedResult{Families: families, Items: items}
73
74
	// Prepend "Recent" category from provider-scoped used models.
75
	if cdb != nil {
76
		if used, err := cdb.UsedModelsForProvider(f.provKey); err == nil && len(used) > 0 {
77
			var usedItems []PickerItem
78
			for _, u := range used {
79
				usedItems = append(usedItems, PickerItem{ID: u.ID, Name: u.Name})
80
			}
81
			result.Items[recentCategory] = usedItems
82
			result.Families = append([]string{recentCategory, ollamaAPI.SeparatorCategory}, result.Families...)
83
		}
84
	}
85
86
	return result, nil
87
}
88

Source Files