merge.go RawHistoryFolder
1package provider
2
3// MergeCatalog returns the baked-in catalog overlaid with live entries.
4// Precedence per id: live > catalog; speculative entries are promoted
5// to non-speculative when a matching live id appears.
6//
7// Unknown live ids (not in the static catalog) are appended at the end
8// with placeholder prices so they still render in the picker. Prices
9// can be populated later from a richer catalog source.
10func MergeCatalog(live []Model) []Model {
11 return MergeCatalogForProviders(live, nil)
12}
13
14// MergeCatalogForProviders merges live entries and omits baked-in models for
15// providers whose live catalog is authoritative. This is needed for
16// account-scoped catalogs, where a static fallback could otherwise expose a
17// model the signed-in account cannot use.
18func MergeCatalogForProviders(live []Model, authoritativeProviders []string) []Model {
19 byKey := func(p, id string) string { return p + "/" + id }
20 authoritative := make(map[string]bool, len(authoritativeProviders))
21 for _, name := range authoritativeProviders {
22 authoritative[name] = true
23 }
24
25 staticIndex := make(map[string]Model, len(Catalog))
26 staticOrder := make([]string, 0, len(Catalog))
27 for _, m := range Catalog {
28 m.Source = "catalog"
29 k := byKey(m.Provider, m.ID)
30 staticIndex[k] = m
31 if !authoritative[m.Provider] {
32 staticOrder = append(staticOrder, k)
33 }
34 }
35
36 // Promote/overwrite from live.
37 for _, l := range live {
38 k := byKey(l.Provider, l.ID)
39 if s, ok := staticIndex[k]; ok {
40 // Preserve static pricing and output limits while allowing live
41 // discovery to supply the account's current display and context
42 // metadata.
43 s.Source = "live"
44 s.Speculative = false
45 if l.DisplayName != "" {
46 s.DisplayName = l.DisplayName
47 }
48 if l.ContextWindow > 0 {
49 s.ContextWindow = l.ContextWindow
50 }
51 staticIndex[k] = s
52 if authoritative[l.Provider] {
53 staticOrder = append(staticOrder, k)
54 }
55 } else {
56 // New live id we'd never heard of. Best-effort defaults.
57 if l.DisplayName == "" {
58 l.DisplayName = l.ID
59 }
60 staticIndex[k] = l
61 staticOrder = append(staticOrder, k)
62 }
63 }
64
65 out := make([]Model, 0, len(staticOrder))
66 for _, k := range staticOrder {
67 out = append(out, staticIndex[k])
68 }
69 return out
70}