// Command failover demonstrates ordered failover chains with health // tracking — including the README's flagship examples: a plain chain and // the same chain with a registered alias expanded inline at the tail. package main import ( "context" "flag" "fmt" "log" "gitea.stevedudenhoeffer.com/steve/majordomo" ) func main() { flag.Parse() reg := majordomo.New() reg.RegisterAlias("thinking", "anthropic/opus-4.8,ollama-cloud/minimax-m3:cloud") // Plain chain: try head-to-tail. One transient blip on a target is // retried in place; repeated failures bench the target (exponential // cooldown) and the chain advances. plain := "ollama-cloud/minimax-m3:cloud,ollama-cloud/kimi-k2.6:cloud,anthropic/opus-4.8" // Same chain with the registered alias appended: "thinking" expands // inline as the tail (duplicates are dropped, first occurrence wins). withAlias := plain + ",thinking" for _, spec := range []string{plain, withAlias} { m, err := reg.Parse(spec) if err != nil { log.Fatalf("parse %q: %v", spec, err) } resp, err := m.Generate(context.Background(), majordomo.Request{ Messages: []majordomo.Message{majordomo.UserText("In one sentence: why do failover chains beat single targets?")}, }) if err != nil { // The joined error names every target and why it failed. log.Fatalf("chain exhausted:\n%v", err) } fmt.Printf("spec: %s\n served by %s: %s\n\n", spec, resp.Model, resp.Text()) } }