Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <title>🎵 Strudel.cc Code Generator</title> | |
| <style> | |
| body { font-family: sans-serif; margin: 2em; max-width: 800px; } | |
| textarea, button, pre { width: 100%; box-sizing: border-box; margin: .5em 0; } | |
| textarea { height: 3em; padding: .5em; font-family: monospace; } | |
| button { padding: .75em; font-size: 1em; } | |
| #status { font-style: italic; color: #555; } | |
| pre { background: #f7f7f7; padding: 1em; white-space: pre-wrap; word-break: break-word; } | |
| </style> | |
| </head> | |
| <body> | |
| <h1>🎵 Strudel.cc Code Generator</h1> | |
| <textarea id="prompt" placeholder="e.g. electronic"></textarea> | |
| <button id="generate" disabled>Loading model…</button> | |
| <div id="status">Initializing…</div> | |
| <h2>Generated Code</h2> | |
| <pre id="output"></pre> | |
| <script type="module"> | |
| import { pipeline, env } | |
| from 'https://cdn.jsdelivr.net/npm/@xenova/transformers@3.7.0/dist/transformers.esm.js'; | |
| // Allow Hub downloads, point to onnx wasm files: | |
| env.allowRemoteModels = true; | |
| env.backends.onnx.wasm.wasmPaths = | |
| 'https://cdn.jsdelivr.net/npm/@xenova/transformers@3.7.0/dist/onnx/'; | |
| const MODEL_ID = 'robertnetwork/strudel-small-onnx'; // ONNX version | |
| const statusEl = document.getElementById('status'); | |
| const btn = document.getElementById('generate'); | |
| const promptEl = document.getElementById('prompt'); | |
| const outputEl = document.getElementById('output'); | |
| let generator; | |
| async function init() { | |
| try { | |
| statusEl.textContent = 'Loading tokenizer and model…'; | |
| generator = await pipeline( | |
| 'text-generation', | |
| MODEL_ID, | |
| { | |
| device: 'webgpu', | |
| dtype: 'fp32', | |
| // progress_callback will receive messages like: | |
| // "Downloading tokenizer_config.json…", "Downloading pytorch_model.bin…", "Compiling WebGPU shaders…" | |
| progress_callback: msg => statusEl.textContent = msg | |
| } | |
| ); | |
| statusEl.textContent = 'Model ready! Enter a prompt and click Generate.'; | |
| btn.disabled = false; | |
| btn.textContent = '🎵 Generate'; | |
| } catch (e) { | |
| statusEl.textContent = '❌ Error loading model: ' + e; | |
| } | |
| } | |
| btn.addEventListener('click', async () => { | |
| const style = promptEl.value.trim(); | |
| if (!style) return; | |
| outputEl.textContent = ''; | |
| statusEl.textContent = 'Generating…'; | |
| btn.disabled = true; | |
| try { | |
| const instruction = | |
| 'Generate Strudel.cc JavaScript code given style tags and a prompt, without commentary or markdown.'; | |
| const prompt = `Instruction: ${instruction}\nInput: ${style}\nOutput:`; | |
| // Run the model | |
| const [ result ] = await generator(prompt, { | |
| max_length: 256, | |
| temperature: 0.7, | |
| top_p: 0.9, | |
| do_sample: true | |
| }); | |
| let text = result.generated_text || result.text || ''; | |
| if (text.includes('Output:')) { | |
| text = text.split('Output:').pop(); | |
| } | |
| outputEl.textContent = text.trim(); | |
| statusEl.textContent = 'Done!'; | |
| } catch (e) { | |
| statusEl.textContent = '❌ Generation error: ' + e; | |
| } finally { | |
| btn.disabled = false; | |
| } | |
| }); | |
| // Start loading immediately | |
| init(); | |
| </script> | |
| </body> | |
| </html> |