Spaces:
Running
Running
Download ai.js from CodeAntidote/jobalign-copilot: direct link, hf CLI and curl.
- Browser
- Download file 5.09 kB
-
https://huggingface.co/spaces/CodeAntidote/jobalign-copilot/resolve/main/ai.js
- Command line
-
hf download hf://spaces/CodeAntidote/jobalign-copilot/ai.js
-
curl -L -o ai.js https://huggingface.co/spaces/CodeAntidote/jobalign-copilot/resolve/main/ai.js
5.09 kB
| /* ========================================================= | |
| JOBALIGN AI CLIENT | |
| A product by John_D | |
| Resume generation now runs through the | |
| Cloudflare Worker backend. | |
| No local LLM download. | |
| No WebGPU. | |
| No WASM model. | |
| ========================================================= */ | |
| const JOBALIGN_BACKEND = | |
| "https://jobalign-adzuna-proxy.darbymjohn.workers.dev"; | |
| /* ========================================================= | |
| STATUS | |
| ========================================================= */ | |
| function setAIStatus( | |
| message, | |
| type = "normal" | |
| ) { | |
| const status = | |
| document.getElementById( | |
| "generationStatus" | |
| ); | |
| if (!status) { | |
| return; | |
| } | |
| let className = ""; | |
| if (type === "success") { | |
| className = | |
| "success-text"; | |
| } else if (type === "error") { | |
| className = | |
| "danger-text"; | |
| } else if (type === "warning") { | |
| className = | |
| "warning-text"; | |
| } | |
| status.innerHTML = ` | |
| <div class="status-dot"></div> | |
| <span class="${className}"> | |
| ${escapeHTML(message)} | |
| </span> | |
| `; | |
| } | |
| /* ========================================================= | |
| GENERATE RESUME | |
| ========================================================= */ | |
| async function generateResume({ | |
| resume, | |
| jobDescription, | |
| jobTitle, | |
| company, | |
| location | |
| }) { | |
| if ( | |
| !resume || | |
| resume.trim().length < 100 | |
| ) { | |
| throw new Error( | |
| "Master resume is missing." | |
| ); | |
| } | |
| if ( | |
| !jobDescription || | |
| jobDescription.trim().length < 100 | |
| ) { | |
| throw new Error( | |
| "Job description is missing." | |
| ); | |
| } | |
| setAIStatus( | |
| "Analyzing job and rebuilding resume..." | |
| ); | |
| const response = | |
| await fetch( | |
| JOBALIGN_BACKEND + "/resume", | |
| { | |
| method: | |
| "POST", | |
| headers: { | |
| "Content-Type": | |
| "application/json", | |
| "Accept": | |
| "application/json" | |
| }, | |
| body: | |
| JSON.stringify({ | |
| resume: | |
| resume, | |
| jobDescription: | |
| jobDescription, | |
| jobTitle: | |
| jobTitle, | |
| company: | |
| company, | |
| location: | |
| location | |
| }) | |
| } | |
| ); | |
| let data; | |
| try { | |
| data = | |
| await response.json(); | |
| } catch (error) { | |
| throw new Error( | |
| "Resume service returned an unreadable response." | |
| ); | |
| } | |
| if (!response.ok) { | |
| const details = | |
| data.details | |
| ? " " + data.details | |
| : ""; | |
| throw new Error( | |
| ( | |
| data.error || | |
| "Resume generation failed." | |
| ) + | |
| details | |
| ); | |
| } | |
| if ( | |
| !data.ok || | |
| !data.resume | |
| ) { | |
| throw new Error( | |
| "Resume service did not return a completed resume." | |
| ); | |
| } | |
| const generatedResume = | |
| String( | |
| data.resume | |
| ).trim(); | |
| if ( | |
| generatedResume.length < 300 | |
| ) { | |
| throw new Error( | |
| "The generated resume was incomplete." | |
| ); | |
| } | |
| setAIStatus( | |
| "Targeted resume generated", | |
| "success" | |
| ); | |
| return generatedResume; | |
| } | |
| /* ========================================================= | |
| OPTIONAL HEALTH CHECK | |
| ========================================================= */ | |
| async function checkBackend() { | |
| try { | |
| const response = | |
| await fetch( | |
| JOBALIGN_BACKEND + | |
| "/health" | |
| ); | |
| const data = | |
| await response.json(); | |
| return Boolean( | |
| response.ok && | |
| data.ok && | |
| data.aiConfigured | |
| ); | |
| } catch (error) { | |
| console.error( | |
| "JobAlign backend health check failed:", | |
| error | |
| ); | |
| return false; | |
| } | |
| } | |
| /* ========================================================= | |
| HTML SAFETY | |
| ========================================================= */ | |
| function escapeHTML( | |
| value | |
| ) { | |
| const element = | |
| document.createElement( | |
| "div" | |
| ); | |
| element.textContent = | |
| String( | |
| value || "" | |
| ); | |
| return element.innerHTML; | |
| } | |
| /* ========================================================= | |
| EXPOSE TO APP.JS | |
| ========================================================= */ | |
| window.JobAlignAI = { | |
| generateResume: | |
| generateResume, | |
| checkBackend: | |
| checkBackend, | |
| mode: | |
| "cloudflare-workers-ai" | |
| }; | |
| window.dispatchEvent( | |
| new CustomEvent( | |
| "jobalign-ai-ready" | |
| ) | |
| ); |