models_item.go

  1package dialog
  2
  3import (
  4	"charm.land/lipgloss/v2"
  5	"github.com/charmbracelet/catwalk/pkg/catwalk"
  6	"github.com/charmbracelet/crush/internal/ui/common"
  7	"github.com/charmbracelet/crush/internal/ui/styles"
  8	"github.com/charmbracelet/x/ansi"
  9	"github.com/sahilm/fuzzy"
 10)
 11
 12// ModelGroup represents a group of model items.
 13type ModelGroup struct {
 14	Title      string
 15	Items      []*ModelItem
 16	configured bool
 17	t          *styles.Styles
 18}
 19
 20// NewModelGroup creates a new ModelGroup.
 21func NewModelGroup(t *styles.Styles, title string, configured bool, items ...*ModelItem) ModelGroup {
 22	return ModelGroup{
 23		Title:      title,
 24		Items:      items,
 25		configured: configured,
 26		t:          t,
 27	}
 28}
 29
 30// AppendItems appends [ModelItem]s to the group.
 31func (m *ModelGroup) AppendItems(items ...*ModelItem) {
 32	m.Items = append(m.Items, items...)
 33}
 34
 35// Render implements [list.Item].
 36func (m *ModelGroup) Render(width int) string {
 37	var configured string
 38	if m.configured {
 39		configuredIcon := m.t.ToolCallSuccess.Render()
 40		configuredText := m.t.Subtle.Render("Configured")
 41		configured = configuredIcon + " " + configuredText
 42	}
 43
 44	title := " " + m.Title + " "
 45	title = ansi.Truncate(title, max(0, width-lipgloss.Width(configured)-1), "…")
 46
 47	return common.Section(m.t, title, width, configured)
 48}
 49
 50// ModelItem represents a list item for a model type.
 51type ModelItem struct {
 52	prov  catwalk.Provider
 53	model catwalk.Model
 54
 55	cache        map[int]string
 56	t            *styles.Styles
 57	m            fuzzy.Match
 58	focused      bool
 59	showProvider bool
 60}
 61
 62var _ ListItem = &ModelItem{}
 63
 64// NewModelItem creates a new ModelItem.
 65func NewModelItem(t *styles.Styles, prov catwalk.Provider, model catwalk.Model, showProvider bool) *ModelItem {
 66	return &ModelItem{
 67		prov:         prov,
 68		model:        model,
 69		t:            t,
 70		cache:        make(map[int]string),
 71		showProvider: showProvider,
 72	}
 73}
 74
 75// Filter implements ListItem.
 76func (m *ModelItem) Filter() string {
 77	return m.model.Name
 78}
 79
 80// ID implements ListItem.
 81func (m *ModelItem) ID() string {
 82	return modelKey(string(m.prov.ID), m.model.ID)
 83}
 84
 85// Render implements ListItem.
 86func (m *ModelItem) Render(width int) string {
 87	var providerInfo string
 88	if m.showProvider {
 89		providerInfo = string(m.prov.Name)
 90	}
 91	return renderItem(m.t, m.model.Name, providerInfo, m.focused, width, m.cache, &m.m)
 92}
 93
 94// SetFocused implements ListItem.
 95func (m *ModelItem) SetFocused(focused bool) {
 96	if m.focused != focused {
 97		m.cache = nil
 98	}
 99	m.focused = focused
100}
101
102// SetMatch implements ListItem.
103func (m *ModelItem) SetMatch(fm fuzzy.Match) {
104	m.cache = nil
105	m.m = fm
106}