mirror of
https://github.com/direct-img/direct-img.link.git
synced 2026-10-13 16:35:20 +00:00
ai.direct-img.link serves images from the AuroraIMG-6M API on our Dokploy server (github.com/direct-img/AuroraIMG-6M) instead of searching. It takes ?src= (auroraimg-6m, case-insensitive, the default and only source for now) and ?i=, where each i gets its own seed derived from the query, so it's a different image of the same prompt. It has its own daily limit (AI_DAILY_LIMIT) and AI: cache keys / ai/ R2 prefix. Failed generations aren't cached, since they're likely temporary. On direct-img.link and free.direct-img.link, a search that finds nothing (or fewer than i working images) now serves an AI image of the query instead of bad.webp. It's kept for 24h like failures were, so a later search can still find a real image; bad.webp is only served if the AI image fails too. Its ttl is stored in KV and R2 metadata so cache hits and deduped waiters send a matching max-age. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
35 lines
1.6 KiB
JavaScript
35 lines
1.6 KiB
JavaScript
// AI images for ai.direct-img.link, and the fallback when a search finds nothing
|
|
const SOURCES = { "auroraimg-6m": auroraImage };
|
|
export const DEFAULT_AI_SOURCE = "auroraimg-6m";
|
|
|
|
// ?src= on ai.*, case-insensitive. Returns null if invalid.
|
|
export function parseAiSource(searchParams) {
|
|
const src = searchParams.get("src")?.toLowerCase() || DEFAULT_AI_SOURCE;
|
|
return Object.hasOwn(SOURCES, src) ? src : null;
|
|
}
|
|
|
|
// Same result shape as fetchImage: { success, buffer, contentType } or { success: false, reason }
|
|
export async function aiImage(src, query, i, env) {
|
|
try {
|
|
return await SOURCES[src](query, await seedFor(query, i), env);
|
|
} catch (err) {
|
|
return { success: false, reason: err.name === "TimeoutError" ? "Timeout" : err.message };
|
|
}
|
|
}
|
|
|
|
// Deterministic per query and i, so each ?i= is a different image of the same prompt and repeats are identical
|
|
async function seedFor(query, i) {
|
|
return new DataView(await crypto.subtle.digest("SHA-256", new TextEncoder().encode(`${query}\n${i}`))).getUint32(0);
|
|
}
|
|
|
|
// AuroraIMG-6M on our Dokploy server: https://github.com/direct-img/AuroraIMG-6M
|
|
async function auroraImage(query, seed, env) {
|
|
if (!env.AURORA_API_KEY) return { success: false, reason: "AURORA_API_KEY not set" };
|
|
const res = await fetch(`https://aurora.direct-img.link/generate?${new URLSearchParams({ prompt: query, seed })}`, {
|
|
headers: { Authorization: `Bearer ${env.AURORA_API_KEY}` },
|
|
signal: AbortSignal.timeout(15000),
|
|
});
|
|
if (!res.ok) return { success: false, reason: `HTTP ${res.status}` };
|
|
return { success: true, buffer: await res.arrayBuffer(), contentType: res.headers.get("content-type") };
|
|
}
|