From 16c4ed1e91c0ab22915cdd96c9fb10c2992e798a Mon Sep 17 00:00:00 2001 From: Luxferre Date: Mon, 7 Sep 2026 14:37:38 +0300 Subject: [PATCH] Ensure deterministic endpoint sorting and broaden call fallback on space errors --- gr2gw.go | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/gr2gw.go b/gr2gw.go index 3cf3923..b757651 100644 --- a/gr2gw.go +++ b/gr2gw.go @@ -18,6 +18,7 @@ import ( "net/url" "os" "regexp" + "sort" "strconv" "strings" "sync" @@ -1207,14 +1208,14 @@ func extractGradioErrorMessage(dataStr string) string { func isProtocolOrInputError(errMsg string) bool { lower := strings.ToLower(errMsg) - return strings.Contains(lower, "check gradio inputs/types") || - strings.Contains(lower, "null error") || - strings.Contains(lower, "typeerror") || - strings.Contains(lower, "missing") || - strings.Contains(lower, "required positional argument") || - strings.Contains(lower, "internal server error") || - strings.Contains(lower, "not found") || - strings.Contains(lower, "unknown upstream gradio error") + if strings.Contains(lower, "unauthorized") || + strings.Contains(lower, "forbidden") || + strings.Contains(lower, "quota exceeded") || + strings.Contains(lower, "payment required") || + strings.Contains(lower, "rate limit") { + return false + } + return true } type Streamer struct { @@ -2195,7 +2196,13 @@ func InspectSpace(client *http.Client, rawURL, userAgent string) (*SpaceDiscover // Try named endpoints from /gradio_api/info first if infoFetched && len(infoResp.NamedEndpoints) > 0 { - for epName, epInfo := range infoResp.NamedEndpoints { + epNames := make([]string, 0, len(infoResp.NamedEndpoints)) + for epName := range infoResp.NamedEndpoints { + epNames = append(epNames, epName) + } + sort.Strings(epNames) + for _, epName := range epNames { + epInfo := infoResp.NamedEndpoints[epName] cleanTarget := strings.TrimPrefix(epName, "/") var matchingDep *GradioDependency if configFetched { @@ -4200,7 +4207,8 @@ func (g *GradioGateway) ExecuteChatCompletion(w http.ResponseWriter, r *http.Req } if !latestFrame.OK { - return fmt.Errorf("upstream Gradio space returned empty or unparseable response") + log.Printf("Gradio /call returned empty or unparseable response, falling back to /queue/join protocol...") + return g.executeQueueCompletion(w, r, disc, gradioData, req, completionID, createdTime, modelName, effUA) } cleanText := latestFrame.Content @@ -4444,7 +4452,8 @@ func (g *GradioGateway) ExecuteChatCompletion(w http.ResponseWriter, r *http.Req } if !streamer.started { - return fmt.Errorf("upstream Gradio space closed stream without sending content") + log.Printf("Gradio /call closed stream without sending content, falling back to /queue/join protocol...") + return g.executeQueueCompletion(w, r, disc, gradioData, req, completionID, createdTime, modelName, effUA) } if nativeToolCallsSeen || toolFilter.emittedCall {