From c812f0882ee4bc50f060d9af403b61cb1d0d9966 Mon Sep 17 00:00:00 2001 From: Levi Neely Date: Tue, 28 Apr 2026 18:47:34 +0200 Subject: [PATCH] freeloader: fix 404 tool_unsupported detection and FIFO-drain recovery - backend: add HTTP 404 and "no endpoints found" to isToolUnsupported so OpenRouter 404s are correctly classified as tool_unsupported - core: drain FIFO on error return from executeTurn so freeloader's resubmitted prompt (queued via fifo.in while running) is picked up Co-Authored-By: Claude Sonnet 4.6 --- pkg/agent/core.go | 4 ++++ pkg/backend/backend.go | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/pkg/agent/core.go b/pkg/agent/core.go index e375a52..dbdd53b 100644 --- a/pkg/agent/core.go +++ b/pkg/agent/core.go @@ -987,6 +987,10 @@ func (s *agent) executeTurn(ctx context.Context, input string, handler EventHand s.session.messages = snapMessages } handler(Event{Role: "error", Content: err.Error()}) + // Drain one FIFO item — the turnError hook may have queued a recovery prompt. + if next, ok := s.fifo.Pop(); ok { + return next + } return "" } diff --git a/pkg/backend/backend.go b/pkg/backend/backend.go index 4b76af2..b53bdcb 100644 --- a/pkg/backend/backend.go +++ b/pkg/backend/backend.go @@ -159,7 +159,7 @@ func streamRequest(client *http.Client, req *http.Request, label string, parseFn if resp.StatusCode == http.StatusBadRequest && isContextOverflow(msg) { return nil, &ContextOverflowError{Message: fmt.Sprintf("%s HTTP %d: %s", label, resp.StatusCode, msg)} } - if (resp.StatusCode == http.StatusBadRequest || resp.StatusCode == http.StatusUnprocessableEntity) && isToolUnsupported(msg) { + if (resp.StatusCode == http.StatusBadRequest || resp.StatusCode == http.StatusUnprocessableEntity || resp.StatusCode == http.StatusNotFound) && isToolUnsupported(msg) { return nil, &ToolUnsupportedError{Message: fmt.Sprintf("%s HTTP %d: %s", label, resp.StatusCode, msg)} } return nil, fmt.Errorf("%s HTTP %d: %s", label, resp.StatusCode, msg) @@ -184,6 +184,7 @@ func isToolUnsupported(body string) bool { "does not support function", "tool_use is not enabled", "not support tool", + "no endpoints found that support tool", } lower := strings.ToLower(body) for _, m := range markers {