@wendellresearch-ai/benchwarmers 0.6.5 → 0.6.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/VERSION CHANGED
@@ -1 +1 @@
1
- 0.6.5
1
+ 0.6.6
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wendellresearch-ai/benchwarmers",
3
- "version": "0.6.5",
3
+ "version": "0.6.6",
4
4
  "description": "Self-hosted panel gateway for LLMs: ask a collection of models at once, keep every answer side by side, rotate explorer models in, and let your verdicts pick the next panel.",
5
5
  "mcpName": "io.github.WendellResearch-AI/benchwarmers",
6
6
  "license": "MIT",
package/serve.py CHANGED
@@ -2150,9 +2150,10 @@ def first_run() -> str:
2150
2150
  text = ("Pick a model your endpoints serve. Onboarding registers it, probes it (4 calls) and runs"
2151
2151
  " the internal suite, so it takes minutes and spends calls.")
2152
2152
  elif not bench_collections.load():
2153
- step, head, label = "collection", "Make your first collection", "New collection"
2154
- text = ("The models a panel always asks, and what it is for. Callers then ask for"
2155
- f" bench/<name> through the gateway at {esc(gateway_url())}.")
2153
+ step, head, label = "collection", "Make your first collection", "Make bench/core"
2154
+ text = ("The models a panel always asks, and what it is for. It opens filled in as bench/core, the"
2155
+ " name the set-ups on Clients use, with the models you onboarded ticked: change anything,"
2156
+ f" then save. Callers ask for it through the gateway at {esc(gateway_url())}.")
2156
2157
  else:
2157
2158
  return ""
2158
2159
  return (f"<section class='problems' id='first-run' data-step='{step}' aria-labelledby='first-head'>"
@@ -5790,7 +5791,9 @@ class Handler(gateway.Handler):
5790
5791
  if self.path == "/api/needs": # after an action there: that page, not the whole one
5791
5792
  with locked.snapshot():
5792
5793
  groups, auto = open_actions()
5793
- self._json(200, {"html": actions_page(groups, auto), "count": open_count(groups)})
5794
+ # `first`: first run's next step now ("" when set up), so a step done goes at once.
5795
+ self._json(200, {"html": actions_page(groups, auto), "count": open_count(groups),
5796
+ "first": first_run()})
5794
5797
  return
5795
5798
  if path == "/api/pane": # a tab's page, when first opened (bench.js load)
5796
5799
  key = q.get("tab", [""])[0]
package/ui/bench.js CHANGED
@@ -864,6 +864,7 @@
864
864
  count.textContent = n.count;
865
865
  tab.setAttribute('aria-label', tab.firstChild.textContent + ', ' + n.count + ' open');
866
866
  }
867
+ if ('first' in n) showFirst(n.first);
867
868
  }).catch(function () { location.reload(); }); // could not ask: the old way
868
869
  }
869
870
  // A retired model's rows grey out and hide behind Show retired, as the
@@ -1945,15 +1946,33 @@
1945
1946
  // ---- first run: no endpoint yet, no model, no collection (serve.first_run) -
1946
1947
  // Each waits for its page: it may not have arrived yet.
1947
1948
  var first = $('first-run');
1949
+ // A step done (an endpoint added, a model onboarded, a collection saved) moves first run on
1950
+ // at once: refreshNeeds hands its next step, or "" when the install is set up.
1951
+ function showFirst(html) {
1952
+ var now = $('first-run');
1953
+ if ((now ? now.outerHTML : '') === (html || '')) return;
1954
+ if (now) now.remove();
1955
+ if (html) document.querySelector('main').insertAdjacentHTML('afterbegin', html);
1956
+ first = $('first-run');
1957
+ }
1948
1958
  function firstStep() {
1949
1959
  if (first.dataset.step === 'onboard') { $('onboard-open').click(); return; }
1950
- if (first.dataset.step === 'collection') { show('collections').then(function () { $('c-new').click(); }); return; }
1960
+ // The first collection comes filled in as bench/core, the name the docs, CLIENTS.md and
1961
+ // the Clients page use: up to four of the models just onboarded ticked (two to four is
1962
+ // what a panel wants), never an image generator. Nothing is made until it is saved.
1963
+ if (first.dataset.step === 'collection') {
1964
+ show('collections').then(function () {
1965
+ var members = C.models.filter(function (a) { return fact(a).role !== 'image'; }).slice(0, 4);
1966
+ fillForm(null, {name: 'core', description: 'General second opinions: any question, several models at once.',
1967
+ tags: ['general', 'second-opinion'], members: members});
1968
+ c.name.focus();
1969
+ });
1970
+ return;
1971
+ }
1951
1972
  show('endpoints').then(function () { openEndpoint('add'); });
1952
1973
  }
1953
- if (first) {
1954
- $('first-go').addEventListener('click', firstStep);
1955
- if (first.dataset.step === 'endpoint') firstStep(); // straight into Add: an empty bench offers nothing else
1956
- }
1974
+ on('click', 'first-go', firstStep); // on the document: a new step brings a new button
1975
+ if (first && first.dataset.step === 'endpoint') firstStep(); // straight into Add: an empty bench offers nothing else
1957
1976
 
1958
1977
  // ---- collections: what the bench gateway runs together (its own tab) -----
1959
1978
  // Its elements, the popup's too, are in the page: found again each time it arrives.
@@ -2150,13 +2169,16 @@
2150
2169
  open = null;
2151
2170
  }
2152
2171
  on('close', 'c-form', function () { open = null; });
2153
- function fillForm(row) {
2172
+ // `row`: a saved collection, opened to edit. `draft`: a new one's values filled in
2173
+ // beforehand (first run's core), still new until saved.
2174
+ function fillForm(row, draft) {
2154
2175
  c.errors.textContent = ''; c.done.textContent = ''; c.status.textContent = '';
2155
2176
  open = row ? row.name : null; c.del.hidden = !row;
2156
2177
  c.head.textContent = row ? 'bench/' + row.name : 'New collection';
2157
2178
  if (!c.form.open) c.form.showModal();
2158
- c.name.value = row ? row.name : ''; c.name.readOnly = !!row;
2159
- c.desc.value = row ? row.description : ''; c.tags.value = row ? row.tags.join(', ') : '';
2179
+ var src = row || draft;
2180
+ c.name.value = src ? src.name : ''; c.name.readOnly = !!row;
2181
+ c.desc.value = src ? src.description : ''; c.tags.value = src ? src.tags.join(', ') : '';
2160
2182
  c.adHoc.checked = !!row && row.ad_hoc;
2161
2183
  c.ownCalls.value = row && row.max_calls !== undefined ? row.max_calls : '';
2162
2184
  c.ownExp.value = row && row.max_explorers !== undefined ? row.max_explorers : '';
@@ -2164,7 +2186,7 @@
2164
2186
  drawTagPicks();
2165
2187
  c.find.value = ''; c.show.value = ''; c.prov.value = '';
2166
2188
  $('c-refresh-out').textContent = '';
2167
- drawMembers(row ? row.members : []);
2189
+ drawMembers(src ? src.members : []);
2168
2190
  c.shape.textContent = '';
2169
2191
  c.shape.appendChild(el('option', {value: ''}, 'automatic'));
2170
2192
  C.shapes.forEach(function (s) {
@@ -2299,6 +2321,7 @@
2299
2321
  // above the list, as onboarding and retiring do.
2300
2322
  function finished(message) {
2301
2323
  c.done.textContent = message; c.status.textContent = message; loadCollections(true);
2324
+ refreshNeeds(); // first run's last step may be done
2302
2325
  setTimeout(closeForm, 1200);
2303
2326
  }
2304
2327
  on('click', 'c-delete', function () {