anentrypoint-design 0.0.92 → 0.0.94

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "anentrypoint-design",
3
- "version": "0.0.92",
3
+ "version": "0.0.94",
4
4
  "description": "247420 design system SDK — webjsx + modified ripple-ui, single-file ESM bundle for reproducible use of the AnEntrypoint design.",
5
5
  "type": "module",
6
6
  "main": "./dist/247420.js",
@@ -17,7 +17,12 @@ export async function chat(h0) {
17
17
  const skills = [...h0.pi.skills.values()];
18
18
  const providers = await fetch('/api/providers').then(r => r.json()).catch(() => []);
19
19
  const configured = providers.filter(p => p.configured);
20
+ const v1Models = await fetch('/v1/models').then(r => r.json()).then(j => j.data || []).catch(() => []);
21
+ const cached = await fetch('/api/models/cached').then(r => r.json()).catch(() => ({}));
22
+ const sampler = await fetch('/api/models/sampler').then(r => r.json()).catch(() => ({ status: {} }));
23
+ (function() { const reg = window.__fd_modelPickers = window.__fd_modelPickers || {}; reg['chat.model'] = { key: 'chat.model', modelCount: v1Models.length, mountedAt: Date.now() }; window.__debug = window.__debug || {}; window.__debug.modelPickers = () => Object.values(window.__fd_modelPickers || {}); })();
20
24
  const cs = window.__fd_chatState = window.__fd_chatState || { cwd: '', skill: '', provider: '', model: '', messages: [], busy: false, sessionId: null };
25
+ try { const last = localStorage.getItem('fd-chat-model'); if (last && !cs.model) cs.model = last } catch {}
21
26
  if (!cs.cwd) cs.cwd = (getRecentPaths()[0] || '');
22
27
  const root = document.getElementById('app');
23
28
  const getMsgs = () => root.querySelector('#fd-chat-msgs');
@@ -91,8 +96,16 @@ export async function chat(h0) {
91
96
  )
92
97
  ),
93
98
  h('div', { class: 'fd-col' },
94
- h('label', { class: 'fd-label' }, 'model'),
95
- h('input', { name: 'model', type: 'text', placeholder: 'default', value: cs.model, oninput: ev => { cs.model = ev.target.value; } })
99
+ h('label', { class: 'fd-label' }, 'model · ' + v1Models.length + ' available'),
100
+ (function() {
101
+ const samplerStatus = sampler && sampler.status ? sampler.status : {};
102
+ const isUnavail = id => { const s = samplerStatus[id]; return s && s.available === false; };
103
+ const grouped = v1Models.reduce((a, m) => { const idx = String(m.id || '').indexOf('/'); const g = idx > 0 ? m.id.slice(0, idx) : (m.owned_by || 'other'); (a[g] = a[g] || []).push(m); return a; }, {});
104
+ return h('select', { name: 'model', onchange: ev => { cs.model = ev.target.value; try { localStorage.setItem('fd-chat-model', cs.model) } catch {} } },
105
+ h('option', { value: '' }, '— auto —'),
106
+ ...Object.entries(grouped).map(([g, ms]) => h('optgroup', { label: g + ' · ' + ms.length },
107
+ ...ms.map(m => h('option', { value: m.id, selected: cs.model === m.id ? 'true' : null, disabled: isUnavail(m.id) ? 'true' : null }, m.id + (isUnavail(m.id) ? ' ✕' : ''))))));
108
+ })()
96
109
  )
97
110
  ),
98
111
  h('div', { class: 'fd-chat-send-row' },
@@ -9,7 +9,7 @@ const KNOWN_FIELDS = [
9
9
  { key: 'display.tool_progress_command', label: 'tool progress command', kind: 'bool' },
10
10
  { key: 'display.background_process_notifications', label: 'bg notifications', kind: 'enum', options: ['all','errors','none'] },
11
11
  { key: 'agent.provider', label: 'agent provider', kind: 'string' },
12
- { key: 'agent.model', label: 'agent model', kind: 'string' },
12
+ { key: 'agent.model', label: 'agent model', kind: 'modelDropdown' },
13
13
  { key: 'agent.max_iterations', label: 'max iterations', kind: 'number' },
14
14
  { key: 'agent.fallback_model', label: 'fallback model', kind: 'string', nullable: true },
15
15
  { key: 'agent.save_trajectories', label: 'save trajectories', kind: 'bool' },
@@ -21,6 +21,15 @@ const KNOWN_FIELDS = [
21
21
 
22
22
  function getDot(o, p) { return p.split('.').reduce((c, k) => (c && k in c) ? c[k] : undefined, o); }
23
23
 
24
+ function registerPicker(key, modelCount) {
25
+ const reg = window.__fd_modelPickers = window.__fd_modelPickers || {};
26
+ reg[key] = { key, modelCount, mountedAt: Date.now() };
27
+ if (typeof window !== 'undefined') {
28
+ window.__debug = window.__debug || {};
29
+ window.__debug.modelPickers = () => Object.values(window.__fd_modelPickers || {});
30
+ }
31
+ }
32
+
24
33
  function commit(h0, key, value) {
25
34
  const prev = window.__fd_cfg_status = window.__fd_cfg_status || {};
26
35
  prev[key] = 'saving…';
@@ -31,10 +40,20 @@ function commit(h0, key, value) {
31
40
 
32
41
  function rerender() { if (typeof window.__fd_nav === 'function') window.__fd_nav('config'); }
33
42
 
34
- function editor(field, cur, defVal, h0, skins) {
43
+ function editor(field, cur, defVal, h0, skins, v1Models, sampler) {
35
44
  const status = (window.__fd_cfg_status || {})[field.key];
36
45
  let control;
37
- if (field.kind === 'skin') {
46
+ if (field.kind === 'modelDropdown') {
47
+ const models = Array.isArray(v1Models) ? v1Models : [];
48
+ const grouped = models.reduce((a, m) => { const idx = String(m.id || '').indexOf('/'); const g = idx > 0 ? m.id.slice(0, idx) : (m.owned_by || 'other'); (a[g] = a[g] || []).push(m); return a; }, {});
49
+ const samplerStatus = sampler && sampler.status ? sampler.status : {};
50
+ const isUnavailable = id => { const s = samplerStatus[id]; return s && s.available === false; };
51
+ control = h('select', { onchange: ev => commit(h0, field.key, ev.target.value === '' && field.nullable ? null : ev.target.value) },
52
+ h('option', { value: '', selected: !cur ? 'true' : null }, '— auto —'),
53
+ ...Object.entries(grouped).map(([g, ms]) => h('optgroup', { label: g + ' · ' + ms.length },
54
+ ...ms.map(m => h('option', { value: m.id, selected: cur === m.id ? 'true' : null, disabled: isUnavailable(m.id) ? 'true' : null }, m.id + (isUnavailable(m.id) ? ' ✕' : ''))))));
55
+ registerPicker(field.key, models.length);
56
+ } else if (field.kind === 'skin') {
38
57
  const list = skins.length ? skins : ['default'];
39
58
  control = h('select', { onchange: ev => commit(h0, field.key, ev.target.value) },
40
59
  ...list.map(s => h('option', { value: s, selected: s === cur ? 'true' : null }, s)));
@@ -119,9 +138,11 @@ export async function config(h0) {
119
138
  const skins = await fetch('/api/skins').then(r => r.json()).catch(() => ['default']);
120
139
  const provInfo = await fetch('/api/models/providers').then(r => r.json()).catch(() => ({ providers: [] }));
121
140
  const cached = await fetch('/api/models/cached').then(r => r.json()).catch(() => ({}));
141
+ const v1Models = await fetch('/v1/models').then(r => r.json()).then(j => j.data || []).catch(() => []);
142
+ const sampler = await fetch('/api/models/sampler').then(r => r.json()).catch(() => ({ status: {} }));
122
143
  const commands = typeof h0.pi.cli?.values === 'function' ? [...h0.pi.cli.values()] : [];
123
144
  const settingsPanel = Panel({ title: 'settings', count: KNOWN_FIELDS.length,
124
- children: KNOWN_FIELDS.filter(f => f.key !== 'agent.model_preference').map(f => editor(f, getDot(cfg, f.key), getDot(defaults, f.key), h0, skins)) });
145
+ children: KNOWN_FIELDS.filter(f => f.key !== 'agent.model_preference').map(f => editor(f, getDot(cfg, f.key), getDot(defaults, f.key), h0, skins, v1Models, sampler)) });
125
146
  const prefPanel = modelPrefPanel(h0, cfg, provInfo.providers || [], cached || {});
126
147
  const rawForm = Panel({ title: 'set arbitrary key (power-user)', children: Form({ fields: [
127
148
  { name: 'key', placeholder: 'dotted.key', required: true },
@@ -9,6 +9,22 @@ export async function models(h0) {
9
9
  const cfg = typeof h0.pi.config?.load === 'function' ? await h0.pi.config.load() : {};
10
10
  const providers = await fetch('/api/providers').then(r => r.json()).catch(() => []);
11
11
  const configured = providers.filter(p => p.configured);
12
+ const queues = await fetch('/api/models/queues').then(r => r.json()).catch(() => ({}));
13
+ const sampler = await fetch('/api/models/sampler').then(r => r.json()).catch(() => ({ status: {} }));
14
+ const v1Models = await fetch('/v1/models').then(r => r.json()).then(j => j.data || []).catch(() => []);
15
+ const pref = Array.isArray(cfg.agent?.model_preference) ? cfg.agent.model_preference.slice() : [];
16
+ window.__debug = window.__debug || {};
17
+ window.__debug.models = () => ({ providers, queues, ranking: pref, sampler: sampler.status || {}, v1Models: v1Models.length });
18
+ const samplerStatus = sampler.status || {};
19
+ const samplerEntries = Object.entries(samplerStatus);
20
+ const samplerOk = samplerEntries.filter(([, s]) => s && s.available !== false).length;
21
+ const samplerBad = samplerEntries.length - samplerOk;
22
+ const saveAndNav = async (next) => { await h0.pi.config.saveValue('agent.model_preference', next); if (typeof window.__fd_nav === 'function') window.__fd_nav('models'); };
23
+ const movePref = (idx, dir) => { const j = idx + dir; if (j < 0 || j >= pref.length) return; const t = pref[idx]; pref[idx] = pref[j]; pref[j] = t; saveAndNav(pref); };
24
+ const delPref = idx => { pref.splice(idx, 1); saveAndNav(pref); };
25
+ const onDragStart = (idx, ev) => { ev.dataTransfer.setData('text/plain', String(idx)); ev.dataTransfer.effectAllowed = 'move'; };
26
+ const onDragOver = ev => { ev.preventDefault(); ev.dataTransfer.dropEffect = 'move'; };
27
+ const onDrop = (target, ev) => { ev.preventDefault(); const src = Number(ev.dataTransfer.getData('text/plain')); if (!Number.isFinite(src) || src === target) return; const item = pref.splice(src, 1)[0]; pref.splice(target, 0, item); saveAndNav(pref); };
12
28
  const probeState = window.__fd_probeState = window.__fd_probeState || {};
13
29
  async function probeAll() {
14
30
  await Promise.allSettled(configured.map(async p => {
@@ -34,9 +50,34 @@ export async function models(h0) {
34
50
  ...probedPanels,
35
51
  unprobedRows.length ? Panel({ title: 'unprobed providers', count: unprobedRows.length, children: Table({ headers: ['provider','status','note'], rows: unprobedRows }) }) : null
36
52
  ].filter(Boolean);
53
+ const samplerTile = Panel({ title: 'sampler status', count: samplerEntries.length,
54
+ right: h('span', {}, Chip({ tone: 'ok', children: samplerOk + ' ok' }), ' ', Chip({ tone: samplerBad > 0 ? 'miss' : 'neutral', children: samplerBad + ' down' })),
55
+ children: samplerEntries.length === 0
56
+ ? h('span', { class: 'fd-muted' }, 'no sampler entries yet — probe a provider to populate')
57
+ : h('div', { class: 'fd-list fd-list-compact' }, ...samplerEntries.map(([k, s]) => h('div', { key: k, class: 'fd-list-row', 'data-cat': s.available === false ? 'external' : 'kit' },
58
+ h('span', { class: 'fd-list-code' }, s.available === false ? '✕' : '●'),
59
+ h('div', { class: 'fd-list-main' }, h('div', { class: 'fd-list-title fd-mono' }, k), h('div', { class: 'fd-list-sub' }, JSON.stringify(s).slice(0, 120)))))) });
60
+ const prefTile = Panel({ title: 'model preference (drag to reorder)', count: pref.length,
61
+ right: h('button', { class: 'btn', onclick: ev => { ev.preventDefault(); pref.push({ provider: '', model: '' }); saveAndNav(pref); } }, '+ add'),
62
+ children: pref.length === 0
63
+ ? h('span', { class: 'fd-muted' }, 'no preference — edit on config page or add a row above')
64
+ : h('div', { class: 'fd-list' }, ...pref.map((p, i) => h('div', {
65
+ key: 'p'+i, class: 'fd-list-row', 'data-cat': 'kit', draggable: 'true',
66
+ ondragstart: ev => onDragStart(i, ev), ondragover: onDragOver, ondrop: ev => onDrop(i, ev), style: 'cursor:move'
67
+ },
68
+ h('span', { class: 'fd-list-code' }, '⋮⋮'),
69
+ h('div', { class: 'fd-list-main' }, h('div', { class: 'fd-list-title fd-mono' }, '#' + (i+1) + ' ' + (p.provider || '?') + (p.model ? ' / ' + p.model : '')),
70
+ h('div', { class: 'fd-list-sub' }, 'drag, or use arrows')),
71
+ h('div', { class: 'fd-list-meta' },
72
+ h('button', { class: 'btn', onclick: ev => { ev.preventDefault(); movePref(i, -1); } }, '↑'),
73
+ h('button', { class: 'btn', onclick: ev => { ev.preventDefault(); movePref(i, 1); } }, '↓'),
74
+ h('button', { class: 'btn', onclick: ev => { ev.preventDefault(); delPref(i); } }, '✕')))))
75
+ });
37
76
  return [
38
- Hero({ title: 'models', body: 'pick a provider, pick a model. probe to list available models.', accent: configured.length+' configured' }),
39
- Kpi({ items: [[configured.length,'configured'],[probedPanels.length,'probed'],[providers.length-configured.length,'unconfigured']] }),
77
+ Hero({ title: 'models', body: 'pick a provider, pick a model. probe to list available models.', accent: configured.length+' configured · ' + v1Models.length + ' models' }),
78
+ Kpi({ items: [[configured.length,'configured'],[probedPanels.length,'probed'],[providers.length-configured.length,'unconfigured'],[v1Models.length,'/v1/models']] }),
79
+ samplerTile,
80
+ prefTile,
40
81
  Panel({ title: 'change active model', children: Form({ fields: [
41
82
  { name: 'provider', placeholder: 'provider', value: cfg.agent?.provider || '' },
42
83
  { name: 'model', placeholder: 'model id', value: cfg.agent?.model || '' }