File size: 1,635 Bytes
1f1908e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
// Coding-model picker for the Settings page. A trimmed modelBar: no engine selector and
// no cache/delete controls (these are ZeroGPU sidecars with no browser download). Drives
// the shared codingModel.js store, so the Skill Forge uses whatever is chosen here.
import {
  listCodingModels, getCodingModelId, setCodingModel, currentCodingModel, onCodingModelChange,
} from '/web/codingModel.js'

function el(tag, props = {}, kids = []) {
  const n = document.createElement(tag)
  for (const [k, v] of Object.entries(props)) {
    if (k === 'class') n.className = v
    else if (k.startsWith('on') && typeof v === 'function') n.addEventListener(k.slice(2), v)
    else if (v != null) n.setAttribute(k, v)
  }
  for (const kid of [].concat(kids)) if (kid != null) n.append(kid)
  return n
}

export function mountCodingModelBar(host, { onChange } = {}) {
  const sel = el('select', { class: 'model-select' })
  const info = el('div', { class: 'model-info' })
  host.append(el('div', { class: 'model-bar' }, [
    el('label', { class: 'persona-label' }, 'Model'),
    sel,
    el('div', { class: 'model-row' }, [info]),
  ]))

  function render() {
    sel.replaceChildren(...listCodingModels().map((m) =>
      el('option', { value: m.id }, `${m.label}${m.params ? ` · ${m.params}` : ''}`)))
    sel.value = getCodingModelId()
    const m = currentCodingModel()
    info.textContent = [m.params, m.backend, m.note].filter(Boolean).join(' · ')
  }

  sel.addEventListener('change', () => { setCodingModel(sel.value); render(); onChange && onChange(sel.value) })
  onCodingModelChange(render)
  render()
  return { refresh: render }
}