package llm import ( "context" "fmt" ) // Router calls Primary first; on any error falls back to Fallback, then to // Tertiary. Fallback and Tertiary may each be nil — a nil tier is skipped and // the chain returns the errors accumulated so far. type Router struct { Primary *Client Fallback *Client Tertiary *Client } // Complete implements pipeline.CompleteFunc, routing through Primary, then // Fallback, then Tertiary — trying each configured tier in order and // returning the first success. func (r *Router) Complete(ctx context.Context, system, user string) (string, error) { out, err := r.Primary.Complete(ctx, system, user) if err == nil { return out, nil } if r.Fallback == nil { return "", fmt.Errorf("primary llm: %w", err) } out, err2 := r.Fallback.Complete(ctx, system, user) if err2 == nil { return out, nil } if r.Tertiary == nil { return "", fmt.Errorf("primary llm: %w; fallback llm: %v", err, err2) } out, err3 := r.Tertiary.Complete(ctx, system, user) if err3 != nil { return "", fmt.Errorf("primary llm: %w; fallback llm: %v; tertiary llm: %v", err, err2, err3) } return out, nil }