fix: add 5s timeout to fetchCompatibleModelIds and skip upstream connections (#541)

The fetchCompatibleModelIds() function had no timeout on its fetch() call,
causing /v1/models to hang indefinitely when an openai-compatible provider
was unreachable or slow to respond.

Additionally, upstream/cross-instance connections (provider IDs containing
a UUID suffix like openai-compatible-chat-XXXXXXXX) would trigger recursive
/models fetches between instances, creating infinite loops.

Fixes:
- Add AbortController with 5-second timeout to the fetch() call
- Skip dynamic model fetching for upstream/cross-instance connections
  (detected by UUID suffix pattern in provider ID)
- Existing try/catch already handles abort errors gracefully

Co-authored-by: Agent Zero <agent@agent-zero.local>
This commit is contained in:
Omar Nahhas Sanchez
2026-04-10 06:30:07 +03:00
committed by GitHub
parent 878cdf302b
commit 838d9a7a04

View File

@@ -7,6 +7,9 @@ const parseOpenAIStyleModels = (data) => {
return data?.data || data?.models || data?.results || [];
};
// Matches provider IDs that are upstream/cross-instance connections (contain a UUID suffix)
const UPSTREAM_CONNECTION_RE = /[-_][0-9a-f]{8,}$/i;
async function fetchCompatibleModelIds(connection) {
if (!connection?.apiKey) return [];
@@ -37,11 +40,15 @@ async function fetchCompatibleModelIds(connection) {
}
try {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 5000);
const response = await fetch(url, {
method: "GET",
headers,
cache: "no-store",
signal: controller.signal,
});
clearTimeout(timeoutId);
if (!response.ok) return [];
@@ -167,7 +174,7 @@ export async function GET() {
)
: providerModels.map((model) => model.id);
if (isCompatibleProvider && rawModelIds.length === 0) {
if (isCompatibleProvider && rawModelIds.length === 0 && !UPSTREAM_CONNECTION_RE.test(providerId)) {
rawModelIds = await fetchCompatibleModelIds(conn);
}