File size: 5,035 Bytes
3380f8e
065cfda
3380f8e
065cfda
ca40114
3380f8e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ca40114
3380f8e
 
 
 
 
 
 
ca40114
3380f8e
 
 
 
 
 
 
 
 
 
 
 
 
065cfda
3380f8e
 
 
 
 
 
 
 
ca40114
3380f8e
 
 
 
 
 
065cfda
3380f8e
 
 
 
 
 
 
 
065cfda
3380f8e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
065cfda
3380f8e
 
 
 
065cfda
3380f8e
065cfda
3380f8e
 
 
 
 
 
 
 
065cfda
3380f8e
 
 
 
 
 
065cfda
3380f8e
 
 
 
 
 
 
 
 
 
3c5da9c
3380f8e
 
 
 
3c5da9c
3380f8e
 
 
 
 
 
 
 
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/* static/index.js  –  FULL FILE
   ----------------------------------------------------------
   AnyCoder AI front‑end logic
   ---------------------------------------------------------- */

/* ~~~~~~~~~~~~~ 1.  MODEL & LANGUAGE LISTS  ~~~~~~~~~~~~~ */
export const AVAILABLE_MODELS = [
  { name: "Qwen/Qwen3‑32B",            id: "Qwen/Qwen3-32B" },
  { name: "Moonshot Kimi‑K2",          id: "moonshotai/Kimi-K2-Instruct", provider: "groq" },
  { name: "DeepSeek V3",               id: "deepseek-ai/DeepSeek-V3-0324" },
  { name: "DeepSeek R1",               id: "deepseek-ai/DeepSeek-R1-0528" },
  { name: "ERNIE‑4.5‑VL",              id: "baidu/ERNIE-4.5-VL-424B-A47B-Base-PT" },
  { name: "MiniMax M1",                id: "MiniMaxAI/MiniMax-M1-80k" },
  { name: "Qwen3‑235B‑A22B",           id: "Qwen/Qwen3-235B-A22B" },
  { name: "SmolLM3‑3B",                id: "HuggingFaceTB/SmolLM3-3B" },
  { name: "GLM‑4.1V‑9B‑Thinking",      id: "THUDM/GLM-4.1V-9B-Thinking" },
  { name: "OpenAI GPT‑4",              id: "openai/gpt-4",                  provider: "openai" },
  { name: "Gemini Pro",                id: "gemini/pro",                   provider: "gemini" },
  { name: "Fireworks V1",              id: "fireworks-ai/fireworks-v1",    provider: "fireworks" },
  // keep this array in sync with models.py if you add more!
];

const LANGUAGES = [
  "python","c","cpp","markdown","latex","json","html","css",
  "javascript","jinja2","typescript","yaml","dockerfile","shell",
  "r","sql","sql-msSQL","sql-mySQL","sql-mariaDB","sql-sqlite",
  "sql-cassandra","sql-plSQL","sql-hive","sql-pgSQL","sql-gql",
  "sql-gpSQL","sql-sparkSQL","sql-esper"
];

/* ~~~~~~~~~~~~~ 2.  DOM REFERENCES  ~~~~~~~~~~~~~ */
const $ = (q) => document.querySelector(q);
const modelSelect  = $('#model');
const promptInput  = $('#prompt');
const fileInput    = $('#reference-file');
const websiteInput = $('#website-url');
const langSelect   = $('#language');
const webSearchChk = $('#web-search');
const codeOut      = $('#code-output');
const previewFrame = $('#preview');
const historyList  = $('#history-list');
const genBtn       = $('#generate');
const clearBtn     = $('#clear');

/* ~~~~~~~~~~~~~ 3.  POPULATE SELECTS  ~~~~~~~~~~~~~ */
AVAILABLE_MODELS.forEach(m => {
  const opt = document.createElement('option');
  opt.value = m.id;
  opt.textContent = m.name;
  opt.dataset.provider = m.provider || '';
  modelSelect.appendChild(opt);
});

LANGUAGES.forEach(lang => {
  const opt = document.createElement('option');
  opt.value = lang;
  opt.textContent = lang;
  langSelect.appendChild(opt);
});

/* ~~~~~~~~~~~~~ 4.  TAB HANDLING  ~~~~~~~~~~~~~ */
document.querySelectorAll('.tabs[role="tablist"] button')
  .forEach(btn => btn.addEventListener('click', () => {
    const tabs   = btn.parentElement.querySelectorAll('[role="tab"]');
    const panels = btn.parentElement.parentElement.querySelectorAll('[role="tabpanel"]');
    tabs.forEach(t => { t.setAttribute('aria-selected', t === btn); });
    panels.forEach(p => { p.hidden = p.id !== btn.getAttribute('aria-controls'); });
  }));

/* ~~~~~~~~~~~~~ 5.  CLEAR SESSION  ~~~~~~~~~~~~~ */
clearBtn.addEventListener('click', () => {
  promptInput.value = '';
  fileInput.value = '';
  websiteInput.value = '';
  codeOut.textContent = '';
  previewFrame.srcdoc = '';
  historyList.innerHTML = '';
});

/* ~~~~~~~~~~~~~ 6.  HISTORY HELPER  ~~~~~~~~~~~~~ */
function logHistory(text) {
  const li = document.createElement('li');
  li.textContent = `${new Date().toLocaleTimeString()} – ${text.slice(0,40)}…`;
  historyList.prepend(li);
}

/* ~~~~~~~~~~~~~ 7.  GENERATE → BACKEND  ~~~~~~~~~~~~~ */
genBtn.addEventListener('click', async () => {
  const prompt = promptInput.value.trim();
  if (!prompt) { alert('Please provide a prompt.'); return; }

  genBtn.disabled = true; genBtn.textContent = 'Generating…';

  /* assemble payload */
  const body = {
    prompt,
    model_id: modelSelect.value,
    language: langSelect.value,
    web_search: webSearchChk.checked,
    website_url: websiteInput.value || null
  };

  /* optional file */
  if (fileInput.files.length) {
    const file = fileInput.files[0];
    body.file_name = file.name;
    body.file_data = await file.text();
  }

  /* post to Gradio back‑end */
  try {
    const res  = await fetch('/run/predict', {
      method: 'POST',
      headers: { 'Content-Type':'application/json' },
      body:   JSON.stringify(body)
    });
    if (!res.ok) throw new Error(await res.text());
    const { data } = await res.json();  // Gradio wraps result in {data:[...]}
    const [code]  = data;

    codeOut.textContent = code;
    previewFrame.srcdoc = langSelect.value === 'html'
      ? code
      : `<pre style="white-space:pre-wrap">${code.replace(/</g,'&lt;')}</pre>`;

    logHistory(prompt);
  } catch (err) {
    console.error(err);
    codeOut.textContent = `/* ERROR: ${err.message} */`;
  } finally {
    genBtn.disabled = false; genBtn.textContent = 'Generate Code';
  }
});