fetch.go

v0.6.1
Doc Versions Source
1
package tui
2
3
import (
4
	"encoding/json"
5
	"errors"
6
	"fmt"
7
8
	tea "github.com/charmbracelet/bubbletea"
9
	"sourcecraft.dev/bigbes/claudio/provider/vkproxy"
10
)
11
12
var errZipNotFound = fmt.Errorf("claude-code-config.zip not found")
13
14
func (m Model) loadVKProxyModels(forceRefresh bool) ([]vkproxy.ProxyModel, error) {
15
	// Try cache first (unless forcing refresh).
16
	if !forceRefresh && m.cache != nil {
17
		if data, ok := m.cache.GetModels("vkproxy"); ok {
18
			var models []vkproxy.ProxyModel
19
			if json.Unmarshal(data, &models) == nil && len(models) > 0 {
20
				return models, nil
21
			}
22
		}
23
	}
24
25
	// Parse from zip.
26
	zipPath := vkproxy.FindZip()
27
	if zipPath == "" {
28
		return nil, errZipNotFound
29
	}
30
	return m.loadVKProxyModelsFromPath(zipPath)
31
}
32
33
func (m Model) loadVKProxyModelsFromPath(zipPath string) ([]vkproxy.ProxyModel, error) {
34
	models, err := vkproxy.ParseZip(zipPath)
35
	if err != nil {
36
		return nil, err
37
	}
38
	if len(models) == 0 {
39
		return nil, fmt.Errorf("no models found in zip")
40
	}
41
42
	// Update cache.
43
	if m.cache != nil {
44
		if data, err := json.Marshal(models); err == nil {
45
			_ = m.cache.SetModels("vkproxy", data)
46
		}
47
	}
48
	return models, nil
49
}
50
51
func (m Model) startVKProxyPicker() (tea.Model, tea.Cmd) {
52
	return m.startVKProxyPickerWithRefresh(false)
53
}
54
55
func (m Model) startVKProxyPickerWithRefresh(forceRefresh bool) (tea.Model, tea.Cmd) {
56
	models, err := m.loadVKProxyModels(forceRefresh)
57
	if errors.Is(err, errZipNotFound) {
58
		return m.showZipFilePicker()
59
	}
60
	if err != nil {
61
		m.modelsErr = err
62
		m.phase = phaseSelect
63
		return m, nil
64
	}
65
	return m.showVKProxyModels(models)
66
}
67
68
func (m Model) showVKProxyModels(models []vkproxy.ProxyModel) (tea.Model, tea.Cmd) {
69
	// Save common config (auth, base_url, env) from first model.
70
	pc := m.cfg.Providers["vkproxy"]
71
	pc.APIKey = models[0].AuthToken
72
	pc.BaseURL = models[0].BaseURL
73
	if pc.Env == nil {
74
		pc.Env = make(map[string]string)
75
	}
76
	if models[0].CustomHeaders != "" {
77
		pc.Env["ANTHROPIC_CUSTOM_HEADERS"] = models[0].CustomHeaders
78
	}
79
	if models[0].ProxyUser != "" {
80
		pc.Env["VK_LLM_PROXY_USER"] = models[0].ProxyUser
81
	}
82
	m.cfg.Providers["vkproxy"] = pc
83
	m.cfg.ActiveProvider = "vkproxy"
84
85
	// Group models by provider for the two-column picker.
86
	providers, grouped := vkproxy.GroupByProvider(models)
87
	familyMap := make(map[string][]PickerItem)
88
	for prov, pms := range grouped {
89
		for _, pm := range pms {
90
			familyMap[prov] = append(familyMap[prov], PickerItem{
91
				ID:            pm.ModelID,
92
				Name:          pm.Name,
93
				ContextLength: pm.ContextWindow,
94
			})
95
		}
96
	}
97
98
	m.phase = phaseSelectModel
99
	m.pickerProvider = "vkproxy"
100
	m.families = providers
101
	m.familyModels = familyMap
102
	m.preSelectModel()
103
	return m, nil
104
}
105

Source Files