mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-27 01:22:10 +03:00
feat(providers): optional AI Horde API key and live image catalog (#10542)
* feat(providers): optional AI Horde API key and live image catalog Allow a registered Horde key on the no-auth connection and send it for chat and image jobs. List only image models that currently have workers, and generate through Horde's native async API. # Conflicts: # open-sse/config/imageRegistry.ts # src/app/(dashboard)/dashboard/providers/[id]/ProviderDetailPageClient.tsx # src/shared/constants/providers.ts # src/sse/services/auth.ts * fix(providers): validate AI Horde keys against find_user The OpenAI-compatible /v1/models probe returns 200 for any Bearer token on oai.aihorde.net, so Check always succeeded. Use Horde's /v2/find_user lookup instead; an empty key still counts as the optional anonymous path. * chore(changelog): name the AI Horde fragment for #10542 * fix(images): harden AI Horde optional-key selection and outbound fetches - Optional-key selection now honors connection health (rate-limit cooldown and terminal/unavailable test status) before handing a stored key back, rotating to the next healthy key or falling back to the anonymous no-auth path instead of using an unhealthy stored key. - Route the Horde submit/check/status/cancel and catalog calls through the repository's bounded outbound-fetch helper (timeout, no more bare fetch()) and route R2 image downloads through the established bounded remote-image fetch (SSRF host guard, DNS-rebinding pin, streaming byte cap, redirect limit) instead of an unbounded fetch(). - Extend the generation deadline to cover the full request lifecycle (catalog freshness check, submit, polling, and image download), and add a regression test proving that exceeding the deadline issues a DELETE cancel to Horde's API rather than only timing out locally. Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> --------- Co-authored-by: pqr <pqr@soraka.ititti.es> Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
This commit is contained in:
@@ -22,6 +22,7 @@ import {
|
||||
getAllImageModels,
|
||||
isRegisteredImageModel,
|
||||
} from "@omniroute/open-sse/config/imageRegistry";
|
||||
import { aiHordeImageCatalog } from "@omniroute/open-sse/services/aihordeImageCatalog";
|
||||
import { getAllRerankModels } from "@omniroute/open-sse/config/rerankRegistry";
|
||||
import { getAllAudioModels } from "@omniroute/open-sse/config/audioRegistry";
|
||||
import { getAllModerationModels } from "@omniroute/open-sse/config/moderationRegistry";
|
||||
@@ -1163,7 +1164,15 @@ async function buildUnifiedModelsResponseCore(
|
||||
});
|
||||
}
|
||||
|
||||
// Add image models (filtered by active providers)
|
||||
// Add image models (filtered by active providers).
|
||||
// AI Horde image workers come and go — refresh the live detector first.
|
||||
if (isProviderActive("aihorde")) {
|
||||
try {
|
||||
await aiHordeImageCatalog.ensureFresh();
|
||||
} catch {
|
||||
// Keep the last good snapshot (or none) if Horde is unreachable.
|
||||
}
|
||||
}
|
||||
for (const imgModel of getAllImageModels()) {
|
||||
if (!isProviderActive(imgModel.provider)) continue;
|
||||
const rawModelId = getSpecialtyModelRelativeId(imgModel.id, imgModel.provider);
|
||||
|
||||
Reference in New Issue
Block a user