File size: 2,300 Bytes
efa45a8
 
00054da
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
efa45a8
5e0d30d
00054da
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
import { pipeline, env } from "@xenova/transformers";

const MODEL_ID = "onnx-community/orpheus-3b-0.1-ft-ONNX";

const modal       = document.getElementById("modal");
const modalText   = document.getElementById("modal-text");
const progressBar = document.getElementById("progress-fill");
const inputEl     = document.getElementById("input-text");
const btnEl       = document.getElementById("generate-btn");
const loadingEl   = document.getElementById("loading-text");
const outputEl    = document.getElementById("output-text");

let generator = null;

// Set up ONNX WASM paths (optional)
env.backends.onnx.wasm.wasmPaths = "https://cdn.jsdelivr.net/npm/@xenova/transformers@2.17.2/dist/";
env.useWasmCPU();

btnEl.addEventListener("click", async () => {
  const prompt = inputEl.value.trim();
  if (!prompt) return;

  btnEl.disabled = true;
  outputEl.textContent = "";
  loadingEl.textContent = "";

  // Show downloading modal
  modal.classList.remove("hidden");
  progressBar.style.width = "0%";
  modalText.textContent = "Loading model... 0%";

  // Load (or reuse) pipeline with progress callback :contentReference[oaicite:0]{index=0}
  if (!generator) {
    generator = await pipeline("text2text-generation", MODEL_ID, {
      progress_callback: (args) => {
        if (args.status === "progress") {
          const pct = Math.floor(args.progress * 100);
          progressBar.style.width = pct + "%";
          modalText.textContent = `Loading model... ${pct}%`;
        }
      },
    });
  }

  // Hide modal
  modalText.textContent = "Model ready!";
  await new Promise((r) => setTimeout(r, 300));
  modal.classList.add("hidden");

  // Stream tokens as they generate :contentReference[oaicite:1]{index=1}
  loadingEl.classList.remove("hidden");
  await generator(prompt, {
    max_length: 256,
    callback_function: (beams) => {
      // beams may be an array of { token, text, ... }
      // append the latest token or text
      const tok = typeof beams === "string"
        ? beams
        : (beams[0]?.text || beams[0]?.token || "");
      loadingEl.textContent += tok;
    },
  });

  // Final output from the pipeline
  const [res] = await generator(prompt, { max_length: 0 });
  loadingEl.classList.add("hidden");
  outputEl.textContent = res.generated_text;

  btnEl.disabled