package cli import ( "encoding/json" "fmt" "strings" "github.com/spf13/cobra" "gitea.mynodes.xyz/ilker/llmgw/internal/agent/provision" "gitea.mynodes.xyz/ilker/llmgw/internal/control/adminapi" "gitea.mynodes.xyz/ilker/llmgw/internal/control/catalog" "gitea.mynodes.xyz/ilker/llmgw/internal/settings" ) func newModelPresetsCmd(client func() *ctlClient, asJSON *bool) *cobra.Command { c := &cobra.Command{ Use: "presets", Short: "The models that come with llmgw: whether each fits and is here", Long: "Each is a catalog entry whose workflow, custom nodes, packages and licence\n" + "were found and tried, and whose profile says the card it needs rather than\n" + "a class, so it places on any site's cards. Add one with\n" + "`llmgw ctl model add NAME`.\n\n" + "While presets.auto is on, the leader adds one by itself when a card fits it\n" + "and the catalog has nothing that makes what it makes; one somebody removed\n" + "is not added again by itself.", Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, _ []string) error { var v adminapi.PresetsView err := client().get(cmd.Context(), "/api/v1/presets", &v) if err != nil && !olderControlPlane(err) { return err } if *asJSON && err == nil { return emitJSON(v) } w := tabTo(cmd.OutOrStdout()) if err != nil { // A control plane from before it kept them: what this // release has, with nothing about the cluster. fmt.Fprintln(w, "NAME\tMAKES\tCARD\tLICENCE\tWHAT IT IS FOR") for _, p := range catalog.Presets() { fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\n", p.Model.Name, p.Makes, presetCard(p.Model), presetLicence(p.Model), p.Model.Description) } return w.Flush() } fmt.Fprintln(w, "NAME\tMAKES\tCARD\tLICENCE\tFITS\tHERE\tWHAT IT IS FOR") for _, p := range v.Presets { fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\t%s\t%s\n", p.Name, p.Makes, p.Card, licenceText(p.Licence), orDash(strings.Join(p.FitsClasses, ",")), presetState(p), p.Description) } if err := w.Flush(); err != nil { return err } if v.Auto { fmt.Fprintln(cmd.OutOrStdout(), "\nAdded by themselves where a card fits (presets.auto); "+ "llmgw ctl model presets auto off stops it.") } else { fmt.Fprintln(cmd.OutOrStdout(), "\nNot added by themselves; llmgw ctl model presets auto on starts it.") } return nil }, } c.AddCommand(&cobra.Command{ Use: "auto on|off", Short: "Whether the leader adds a preset by itself where a card fits it", Args: cobra.ExactArgs(1), ValidArgs: []string{"on", "off"}, RunE: func(cmd *cobra.Command, args []string) error { if args[0] != "on" && args[0] != "off" { return fmt.Errorf("on or off, not %q", args[0]) } body, _ := json.Marshal(adminapi.PresetsAutoRequest{On: args[0] == "on"}) var v adminapi.PresetsView if err := client().put(cmd.Context(), "/api/v1/presets/auto", body, &v); err != nil { return err } if v.Auto { fmt.Fprintln(cmd.OutOrStdout(), "Presets are added by themselves where a card fits.") } else { fmt.Fprintln(cmd.OutOrStdout(), "Presets are no longer added by themselves.") } return nil }, }) return c } // olderControlPlane is an error from a control plane that has no such path: // one from before it was added. func olderControlPlane(err error) bool { s := err.Error() return strings.Contains(s, "answered with a page") || strings.HasPrefix(s, "404 Not Found: 404 page not found") } func presetState(p adminapi.PresetView) string { switch { case p.InCatalog && p.AddedBy == "auto": return "added by itself" case p.InCatalog && p.AddedBy != "": return "added by " + p.AddedBy case p.InCatalog: return "here" case p.Declined: return "removed; stays out" } return "—" } func licenceText(l catalog.License) string { if l.Commercial != nil && !*l.Commercial { return l.Name + ", not commercial" } return l.Name } func presetCard(m catalog.Model) string { if len(m.Profiles) == 0 || m.Profiles[0].GPU == nil { return "—" } return m.Profiles[0].GPU.String() } func presetLicence(m catalog.Model) string { if m.License == nil { return "—" } l := m.License.Name if c := m.License.Commercial; c != nil && !*c { l += ", not commercial" } return l } // ensureComfyUI has the nodes install ComfyUI for a model that needs it, // unless the cluster names a version already, or none on purpose. func ensureComfyUI(cmd *cobra.Command, client func() *ctlClient, model string) error { out := cmd.OutOrStdout() path := []string{"engines", catalog.EngineComfyUI} var cur adminapi.SettingsView if err := client().get(cmd.Context(), "/api/v1/settings", &cur); err != nil { return err } doc, err := settings.FromBytes("settings", []byte(cur.Body)) if err != nil { return err } version := provision.ComfyUIVersion() if n := doc.Node(path); n != nil { if n.Value == "" { fmt.Fprintf(out, "engines.comfyui is set to none, so the nodes install no ComfyUI for it: set a version "+ "(llmgw ctl config set engines.comfyui %s) or name one installed by hand in agent.yaml\n", version) } return nil } fmt.Fprintf(out, "Nodes with an NVIDIA GPU install ComfyUI %s for it, about 10 GB each:\n", version) if err := doc.SetYAML(path, version); err != nil { return err } b, err := doc.Bytes() if err != nil { return err } return putSettings(cmd, client, cur, b, "ComfyUI for "+model) }