| import './input.css'; |
|
|
| import { oauthLoginUrl, oauthHandleRedirectIfPresent } from "@huggingface/hub"; |
| import { InferenceClient } from "@huggingface/inference"; |
| import { Client } from "@gradio/client"; |
|
|
| let activeInMemoryUserToken = null; |
| let internalBlobURL = null; |
| let targetDownloadBlobURL = null; |
| let cachedRawText = ""; |
|
|
| let activeGradioJobHandle = null; |
| let currentAbortController = null; |
| let globalInferenceTimeoutId = null; |
| let studioRegistryData = null; |
|
|
| const MAX_FILE_SIZE_MB = 25; |
| const COMPUTATION_TIMEOUT_MS = 300000; |
|
|
| const embeddedFallbackRegistry = { |
| registryVersion: "local-fallback-v1", |
| models: { |
| text: [{ id: "meta-llama/Meta-Llama-3-8B-Instruct:fastest", name: "Llama 3 8B Instruct (Fallback)", transport: "serverless", apiStrategy: "chatStream", inputType: "text", mimeConstraints: [], capabilities: { stream: true, copy: true } }], |
| image: [{ id: "black-forest-labs/FLUX.1-schnell", name: "FLUX.1 Schnell (Fallback)", transport: "serverless", apiStrategy: "textToImage", inputType: "text", mimeConstraints: [], capabilities: { download: true } }], |
| video: [], audio: [], vision: [] |
| } |
| }; |
|
|
| window.addEventListener('DOMContentLoaded', async () => { |
| document.getElementById('loginButton').addEventListener('click', () => oauthLoginUrl().then(url => window.location.href = url)); |
| document.getElementById('logoutBtn').addEventListener('click', purgeLifetimeSessionState); |
| document.getElementById('generateBtn').addEventListener('click', triggerInferenceEngineLifecycle); |
| document.getElementById('copyBtn').addEventListener('click', writeTextToClipboardSecurely); |
| document.getElementById('cancelBtn').addEventListener('click', killActiveInferencePipelines); |
| document.getElementById('modelSelector').addEventListener('change', runDynamicInputMIMEChecks); |
| |
| ['text', 'image', 'video', 'audio', 'vision'].forEach(domain => { |
| document.getElementById(`btn-tab-${domain}`).addEventListener('click', () => switchTab(domain)); |
| }); |
|
|
| await bootstrapApplicationStudio(); |
| }); |
|
|
| function validateRegistrySchema(data) { |
| if (!data || typeof data !== 'object') return false; |
| if (typeof data.registryVersion !== 'string') return false; |
| if (!data.models || typeof data.models !== 'object') return false; |
| return ['text', 'image', 'video', 'audio', 'vision'].every(key => Array.isArray(data.models[key] || [])); |
| } |
|
|
| async function bootstrapApplicationStudio() { |
| try { |
| const networkFetch = await fetch('/registry.json'); |
| if (!networkFetch.ok) throw new Error("Server metadata returned irregular structural states."); |
| const parsedConfig = await networkFetch.json(); |
| |
| if (validateRegistrySchema(parsedConfig)) { |
| studioRegistryData = parsedConfig; |
| console.log("Registry Version Loaded:", studioRegistryData.registryVersion); |
| } else { |
| throw new Error("Registry data structurally violated schema blueprints."); |
| } |
| } catch (fallbackError) { |
| console.warn("External registry verification failed. Injecting embedded fallback maps...", fallbackError); |
| studioRegistryData = embeddedFallbackRegistry; |
| } |
|
|
| try { |
| const parsedOAuth = await oauthHandleRedirectIfPresent(); |
| let activeToken = sessionStorage.getItem("hf_transient_token"); |
|
|
| if (parsedOAuth?.accessToken) { |
| activeToken = parsedOAuth.accessToken; |
| sessionStorage.setItem("hf_transient_token", activeToken); |
| window.history.replaceState({}, document.title, window.location.pathname); |
| } |
| |
| if (activeToken) { |
| activeInMemoryUserToken = activeToken; |
| document.getElementById('authOverlay').classList.add('hidden'); |
| document.getElementById('appContainer').classList.remove('hidden'); |
| switchTab('text'); |
| } |
| } catch (err) { console.error("Identity validation sequence crashed:", err); } |
| } |
|
|
| function purgeLifetimeSessionState() { |
| sessionStorage.removeItem("hf_transient_token"); |
| activeInMemoryUserToken = null; |
| clearActiveBlobAllocations(); |
| window.location.href = window.location.origin + window.location.pathname; |
| } |
|
|
| function clearActiveBlobAllocations() { |
| document.getElementById('imageOutput').removeAttribute('src'); |
| document.getElementById('audioOutput').removeAttribute('src'); |
| document.getElementById('videoOutput').removeAttribute('src'); |
| if (internalBlobURL) { URL.revokeObjectURL(internalBlobURL); internalBlobURL = null; } |
| if (targetDownloadBlobURL) { URL.revokeObjectURL(targetDownloadBlobURL); targetDownloadBlobURL = null; } |
| } |
|
|
| function switchTab(domain) { |
| if (!studioRegistryData) return; |
| document.getElementById('activeDomainContext').value = domain; |
| |
| ['text', 'image', 'video', 'audio', 'vision'].forEach(d => { |
| const node = document.getElementById(`btn-tab-${d}`); |
| node.className = (d === domain) |
| ? "w-full flex items-center gap-3 px-3 py-2.5 rounded-xl bg-indigo-600 text-white text-sm font-medium transition cursor-pointer" |
| : "w-full flex items-center gap-3 px-3 py-2.5 rounded-xl text-gray-400 hover:bg-gray-800 hover:text-gray-200 text-sm font-medium transition cursor-pointer"; |
| }); |
|
|
| const picker = document.getElementById('modelSelector'); |
| picker.innerHTML = ''; |
| const categoryModels = studioRegistryData.models[domain] || []; |
| |
| if (!categoryModels.length) { |
| runDynamicInputMIMEChecks(); |
| resetViewportStateDisplays(); |
| renderViewTagId('stateEmptyCategory'); |
| return; |
| } |
|
|
| categoryModels.forEach((model, index) => { |
| const item = document.createElement('option'); |
| item.value = model.id; |
| item.innerText = model.name; |
| item.setAttribute('data-index', index); |
| picker.appendChild(item); |
| }); |
|
|
| runDynamicInputMIMEChecks(); |
| resetViewportStateDisplays(); |
| } |
|
|
| function getActiveModelMetadata() { |
| if (!studioRegistryData) return null; |
| const domain = document.getElementById('activeDomainContext').value; |
| const picker = document.getElementById('modelSelector'); |
| const selection = picker.options[picker.selectedIndex]; |
| if (!selection) return null; |
| return studioRegistryData.models[domain][selection.getAttribute('data-index')]; |
| } |
|
|
| function runDynamicInputMIMEChecks() { |
| const meta = getActiveModelMetadata(); |
| const targetGrid = document.getElementById('mediaUploadContainer'); |
| const targetLabel = document.getElementById('uploadInputLabel'); |
| const fileField = document.getElementById('mediaFileInput'); |
|
|
| fileField.value = ""; |
|
|
| if (meta && meta.inputType.endsWith("File")) { |
| targetGrid.classList.remove('hidden'); |
| fileField.accept = meta.inputType.startsWith("audio") ? "audio/*" : "image/*"; |
| targetLabel.innerText = `Select Target Input Resource File (${meta.mimeConstraints.join(', ') || '*/*'}):`; |
| } else { |
| targetGrid.classList.add('hidden'); |
| } |
| } |
|
|
| function resetViewportStateDisplays() { |
| document.getElementById('copyBtn').classList.add('hidden'); |
| document.getElementById('downloadBtn').classList.add('hidden'); |
| document.getElementById('cancelBtn').classList.add('hidden'); |
| renderViewTagId('statePlaceholder'); |
| } |
|
|
| function renderViewTagId(viewId) { |
| ['statePlaceholder', 'stateLoading', 'stateEmptyCategory', 'textOutput', 'imageOutput', 'audioOutput', 'videoOutput'].forEach(id => { |
| const node = document.getElementById(id); |
| if (id === viewId) node.classList.remove('hidden'); |
| else node.classList.add('hidden'); |
| }); |
| } |
|
|
| function killActiveInferencePipelines() { |
| if (globalInferenceTimeoutId) { clearTimeout(globalInferenceTimeoutId); globalInferenceTimeoutId = null; } |
| if (activeGradioJobHandle) { |
| try { activeGradioJobHandle.cancel(); } catch(e) { console.error("Remote cancellation error logs:", e); } |
| activeGradioJobHandle = null; |
| } |
| if (currentAbortController) currentAbortController.abort(); |
| } |
|
|
| function extractDeepNestedValue(obj, dotPathString) { |
| if (!dotPathString) return obj; |
| return dotPathString.split('.').reduce((acc, currentCursor) => { |
| const indexMatch = currentCursor.match(/^(\w+)\[(\d+)\]$/); |
| if (indexMatch) { |
| const [, prop, idx] = indexMatch; |
| return acc?.[prop]?.[parseInt(idx, 10)]; |
| } |
| return acc?.[currentCursor]; |
| }, obj); |
| } |
|
|
| function normalizeError(err) { |
| const report = { title: "Execution Fault", message: "An unhandled error has halted processing.", retryable: true }; |
| if (err.name === 'AbortError' || err.message === 'TIMEOUT_TRIGGERED') { |
| report.title = "Pipeline Terminated"; |
| report.message = err.message === 'TIMEOUT_TRIGGERED' |
| ? "Inference execution ceiling hit. Remote cluster computation dropped automatically after 5 minutes." |
| : "The active request was canceled via explicit control commands."; |
| return report; |
| } |
| const dataStr = (err.message || String(err)).toLowerCase(); |
| if (err.status === 429 || dataStr.includes("429") || dataStr.includes("limit")) { |
| report.title = "Quota Limit Reached"; |
| report.message = "Your account has depleted its available serverless execution allocations."; |
| return report; |
| } |
| report.message = err.message || JSON.stringify(err); |
| return report; |
| } |
|
|
| function constructDynamicPayload(templateStructure, textPrompt, binaryFile) { |
| const recurseAndTransform = (element) => { |
| if (element === "$file") return binaryFile; |
| if (element === "$text") return textPrompt; |
| if (Array.isArray(element)) return element.map(recurseAndTransform); |
| if (element !== null && typeof element === "object") { |
| const clonedOutputMap = {}; |
| for (const key in element) { clonedOutputMap[key] = recurseAndTransform(element[key]); } |
| return clonedOutputMap; |
| } |
| return element; |
| }; |
| return recurseAndTransform(templateStructure); |
| } |
|
|
| function routeMediaByContentType(contentTypeString, fallbackUrl) { |
| const type = contentTypeString.toLowerCase(); |
| if (type.includes('video/')) { |
| document.getElementById('videoOutput').src = fallbackUrl; |
| renderViewTagId('videoOutput'); |
| } else if (type.includes('audio/')) { |
| document.getElementById('audioOutput').src = fallbackUrl; |
| renderViewTagId('audioOutput'); |
| } else { |
| document.getElementById('imageOutput').src = fallbackUrl; |
| renderViewTagId('imageOutput'); |
| } |
| } |
|
|
| function sniffTypeFromUrlExtensions(urlString) { |
| const clearUrl = urlString.split('?')[0].toLowerCase(); |
| if (clearUrl.endsWith('.mp4') || clearUrl.endsWith('.webm')) return "video/mp4"; |
| if (clearUrl.endsWith('.mp3') || clearUrl.endsWith('.wav')) return "audio/mpeg"; |
| return "image/png"; |
| } |
|
|
| const runStrategies = { |
| chatStream: async (hf, meta, prompt, file, signal) => { |
| const node = document.getElementById('textOutput'); |
| node.innerText = ""; cachedRawText = ""; |
| renderViewTagId('textOutput'); |
|
|
| try { |
| const stream = await hf.chatCompletionStream({ model: meta.id, messages: [{ role: "user", content: prompt }], max_tokens: 1000 }, { signal }); |
| for await (const chunk of stream) { |
| cachedRawText += chunk.choices[0]?.delta?.content || ""; |
| node.innerText = cachedRawText; |
| } |
| } catch (err) { |
| if (err.name === 'AbortError') throw err; |
| const fallbackCompletion = await hf.chatCompletion({ model: meta.id, messages: [{ role: "user", content: prompt }], max_tokens: 1000 }, { signal }); |
| cachedRawText = fallbackCompletion.choices[0].message.content; |
| node.innerText = cachedRawText; |
| } |
| if (meta.capabilities.copy) document.getElementById('copyBtn').classList.remove('hidden'); |
| }, |
|
|
| textToImage: async (hf, meta, prompt, file, signal) => { |
| const blob = await hf.textToImage({ model: meta.id, inputs: prompt, parameters: { guidance_scale: 7.5 } }, { signal }); |
| if (internalBlobURL) URL.revokeObjectURL(internalBlobURL); |
| internalBlobURL = URL.createObjectURL(blob); |
| document.getElementById('imageOutput').src = internalBlobURL; |
| renderViewTagId('imageOutput'); |
| if (meta.capabilities.download) setupSecureDownloadLink(internalBlobURL, "image/png"); |
| }, |
|
|
| textToAudio: async (hf, meta, prompt, file, signal) => { |
| const blob = await hf.textToSpeech({ model: meta.id, inputs: prompt }, { signal }); |
| if (internalBlobURL) URL.revokeObjectURL(internalBlobURL); |
| internalBlobURL = URL.createObjectURL(blob); |
| document.getElementById('audioOutput').src = internalBlobURL; |
| renderViewTagId('audioOutput'); |
| if (meta.capabilities.download) setupSecureDownloadLink(internalBlobURL, "audio/mpeg"); |
| }, |
|
|
| audioToText: async (hf, meta, prompt, file, signal) => { |
| const res = await hf.automaticSpeechRecognition({ model: meta.id, data: file }, { signal }); |
| cachedRawText = res.text || "No text structures resolved."; |
| document.getElementById('textOutput').innerText = cachedRawText; |
| renderViewTagId('textOutput'); |
| if (meta.capabilities.copy) document.getElementById('copyBtn').classList.remove('hidden'); |
| }, |
|
|
| imageToText: async (hf, meta, prompt, file, signal) => { |
| const res = await hf.imageToText({ model: meta.id, data: file }, { signal }); |
| cachedRawText = res.generated_text || "Zero descriptions extracted."; |
| document.getElementById('textOutput').innerText = cachedRawText; |
| renderViewTagId('textOutput'); |
| if (meta.capabilities.copy) document.getElementById('copyBtn').classList.remove('hidden'); |
| }, |
|
|
| imageChat: async (hf, meta, prompt, file, signal) => { |
| if (file && file.size > 10 * 1024 * 1024) throw new Error("Target upload matrix breaches supported 10MB parameters."); |
|
|
| document.getElementById('textOutput').innerText = "Encoding file layers..."; |
| renderViewTagId('textOutput'); |
|
|
| const base64Str = await executeBase64FileConversion(file); |
| const res = await hf.chatCompletion({ |
| model: meta.id, |
| messages: [{ role: "user", content: [{ type: "text", text: prompt || "Analyze image metrics." }, { type: "image_url", image_url: { url: base64Str } }] }], |
| max_tokens: 600 |
| }, { signal }); |
|
|
| cachedRawText = res.choices[0].message.content; |
| document.getElementById('textOutput').innerText = cachedRawText; |
| if (meta.capabilities.copy) document.getElementById('copyBtn').classList.remove('hidden'); |
| }, |
|
|
| gradioBridge: async (hf, meta, prompt, file, signal) => { |
| document.getElementById('loadingStatusText').innerText = "Acquiring ZeroGPU compute nodes..."; |
| |
| const clientInstance = await Client.connect(meta.id); |
| const executionTarget = meta.endpoint ?? meta.fnIndex; |
| const payloadArray = constructDynamicPayload(meta.inputsStructure, prompt, file); |
| const operationalArguments = Array.isArray(payloadArray) ? payloadArray : [payloadArray]; |
|
|
| await new Promise((resolve, reject) => { |
| activeGradioJobHandle = clientInstance.submit(executionTarget, [...operationalArguments]); |
| |
| signal.addEventListener('abort', () => { |
| if (activeGradioJobHandle) activeGradioJobHandle.cancel(); |
| reject(new DOMException("Aborted", "AbortError")); |
| }, { once: true }); |
|
|
| activeGradioJobHandle.on("success", async (dataOutput) => { |
| try { |
| const directMediaUrl = extractDeepNestedValue(dataOutput, meta.outputSelector); |
| if (!directMediaUrl) throw new Error("Output path extraction parameters mismatch structural properties returned."); |
|
|
| let detectedMimeType = null; |
| try { |
| const probe = await fetch(directMediaUrl, { method: 'HEAD', signal }); |
| if (!probe.ok) throw new Error("HEAD query rejected."); |
| detectedMimeType = probe.headers.get("content-type"); |
| } catch (_) { |
| console.warn("HEAD check blocked. Using fallback matching standard rules..."); |
| } |
|
|
| if (!detectedMimeType) detectedMimeType = sniffTypeFromUrlExtensions(directMediaUrl); |
| routeMediaByContentType(detectedMimeType, directMediaUrl); |
| |
| if (meta.capabilities.download) setupSecureDownloadLink(directMediaUrl, detectedMimeType); |
| resolve(); |
| } catch(e) { reject(e); } |
| }); |
|
|
| activeGradioJobHandle.on("error", (errContext) => reject(new Error(errContext?.message || "Remote ZeroGPU cluster crash detected."))); |
| }); |
| } |
| }; |
|
|
| async function triggerInferenceEngineLifecycle() { |
| if (!activeInMemoryUserToken) return alert("System Rejection: Active identity parameters missing."); |
|
|
| const prompt = document.getElementById('promptInput').value.trim(); |
| const file = document.getElementById('mediaFileInput').files[0]; |
| const meta = getActiveModelMetadata(); |
|
|
| if (!meta) return; |
|
|
| if (meta.inputType.endsWith("File")) { |
| if (!file) return alert("Validation Failed: This target parameter requires an attached media context file."); |
| const fileSizeMB = file.size / (1024 * 1024); |
| if (fileSizeMB > MAX_FILE_SIZE_MB) return alert(`Validation Failed: Capped limit max bounds are ${MAX_FILE_SIZE_MB}MB.`); |
| if (meta.mimeConstraints.length > 0 && !meta.mimeConstraints.includes(file.type)) { |
| return alert(`Validation Failed: Invalid format. Expected parameters: ${meta.mimeConstraints.join(', ')}`); |
| } |
| } else { |
| if (meta.inputType === "text" && !prompt) return alert("Validation Failed: Workstation prompts are currently un-assigned."); |
| } |
|
|
| clearActiveBlobAllocations(); |
| resetViewportStateDisplays(); |
|
|
| currentAbortController = new AbortController(); |
| document.getElementById('cancelBtn').classList.remove('hidden'); |
| renderViewTagId('stateLoading'); |
| document.getElementById('loadingStatusText').innerText = "Streaming operational variables..."; |
|
|
| globalInferenceTimeoutId = setTimeout(() => { |
| if (currentAbortController) { |
| killActiveInferencePipelines(); |
| alert("[Studio Timeout] Computation exceeded the global 5-minute allocation window."); |
| resetViewportStateDisplays(); |
| } |
| }, COMPUTATION_TIMEOUT_MS); |
|
|
| try { |
| const clientWrapper = new InferenceClient(activeInMemoryUserToken); |
| const targetedRunner = runStrategies[meta.apiStrategy || "gradioBridge"]; |
| await targetedRunner(clientWrapper, meta, prompt, file, currentAbortController.signal); |
| } catch (err) { |
| console.error("Execution loop dropped:", err); |
| const profile = normalizeError(err); |
| alert(`[${profile.title}] ${profile.message}`); |
| resetViewportStateDisplays(); |
| } finally { |
| if (globalInferenceTimeoutId) { clearTimeout(globalInferenceTimeoutId); globalInferenceTimeoutId = null; } |
| currentAbortController = null; |
| activeGradioJobHandle = null; |
| document.getElementById('cancelBtn').classList.add('hidden'); |
| } |
| } |
|
|
| function setupSecureDownloadLink(targetUrl, incomingMimeType) { |
| const anchorNode = document.getElementById('downloadBtn'); |
| anchorNode.classList.remove('hidden'); |
| |
| const mimeMap = { "audio/mpeg": "mp3", "audio/mp3": "mp3", "image/png": "png", "image/jpeg": "jpg", "image/webp": "webp", "video/mp4": "mp4", "audio/wav": "wav" }; |
| const cleanExtension = mimeMap[incomingMimeType] || incomingMimeType.split('/')[1]?.split(';')[0] || "bin"; |
| const generatedFilename = `generation.${cleanExtension}`; |
|
|
| anchorNode.onclick = async (e) => { |
| e.preventDefault(); |
| const originalText = anchorNode.innerText; |
| try { |
| anchorNode.innerText = "⏳ Preparing Byte Streams..."; |
| anchorNode.style.pointerEvents = "none"; |
| |
| const fetchStream = await fetch(targetUrl); |
| if (!fetchStream.ok) throw new Error("CORS origin restrictions blocked asset retrieval operations."); |
| const blobData = await fetchStream.blob(); |
| |
| if (targetDownloadBlobURL) URL.revokeObjectURL(targetDownloadBlobURL); |
| targetDownloadBlobURL = URL.createObjectURL(blobData); |
| |
| anchorNode.href = targetDownloadBlobURL; |
| anchorNode.setAttribute("download", generatedFilename); |
| |
| const transientAnchor = document.createElement('a'); |
| transientAnchor.href = targetDownloadBlobURL; |
| transientAnchor.download = generatedFilename; |
| document.body.appendChild(transientAnchor); |
| transientAnchor.click(); |
| document.body.removeChild(transientAnchor); |
| } catch (e) { |
| console.error("Download fallback sequence routing triggered...", e); |
| window.open(targetUrl, '_blank', 'noopener,noreferrer'); |
| } finally { |
| anchorNode.innerText = originalText; |
| anchorNode.style.pointerEvents = "auto"; |
| } |
| }; |
| } |
|
|
| async function writeTextToClipboardSecurely() { |
| if (!cachedRawText) return; |
| try { |
| if (navigator.clipboard && window.isSecureContext) { |
| await navigator.clipboard.writeText(cachedRawText); |
| confirmSuccessTextStyles(); |
| return; |
| } |
| } catch (e) { console.warn("Clipboard mapping context fallbacks initialized..."); } |
| |
| const area = document.createElement("textarea"); |
| area.value = cachedRawText; area.style.position = "fixed"; area.style.left = "-9999px"; |
| document.body.appendChild(area); area.select(); area.setSelectionRange(0, 99999); |
| try { |
| if (document.execCommand("copy")) confirmSuccessTextStyles(); |
| } catch (err) { alert("Clipboard actions blocked on this browser context configuration."); } |
| document.body.removeChild(area); |
| } |
|
|
| function confirmSuccessTextStyles() { |
| const btn = document.getElementById('copyBtn'); btn.innerText = "💥 Copied!"; |
| setTimeout(() => { btn.innerText = "📋 Copy Text"; }, 2000); |
| } |
|
|
| function executeBase64FileConversion(file) { |
| return new Promise((resolve, reject) => { |
| const reader = new FileReader(); reader.readAsDataURL(file); |
| reader.onload = () => resolve(reader.result); reader.onerror = e => reject(e); |
| }); |
| } |