anentrypoint-design 0.0.95 → 0.0.97
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/dist/247420.app.js +4 -4
- package/dist/247420.js +30 -30
- package/package.json +1 -1
- package/src/components/freddie/pages-chains.js +168 -0
- package/src/components/freddie/pages-config-edit.js +3 -0
- package/src/components/freddie.js +3 -1
- package/src/components.js +1 -1
- package/src/index.js +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "anentrypoint-design",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.97",
|
|
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",
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
// Chain editor — talks to freddie's /api/acptoapi/* bridge (which proxies
|
|
2
|
+
// to acptoapi /v1/chains). Renders builtins read-only and runtime chains
|
|
3
|
+
// fully editable. Used by both freddie's dashboard and thebird via the
|
|
4
|
+
// FREDDIE_PAGES registry.
|
|
5
|
+
import * as webjsx from '../../../vendor/webjsx/index.js';
|
|
6
|
+
import { Panel, Hero, Kpi, Form } from '../content.js';
|
|
7
|
+
import { Chip } from '../shell.js';
|
|
8
|
+
import { EmptyState } from '../files.js';
|
|
9
|
+
const h = webjsx.createElement;
|
|
10
|
+
|
|
11
|
+
async function fetchJson(url, init) {
|
|
12
|
+
const r = await fetch(url, init);
|
|
13
|
+
const ct = r.headers.get('content-type') || '';
|
|
14
|
+
const body = ct.includes('json') ? await r.json() : await r.text();
|
|
15
|
+
if (!r.ok) throw new Error(typeof body === 'string' ? body : (body.error?.message || JSON.stringify(body)));
|
|
16
|
+
return body;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
async function loadChains() {
|
|
20
|
+
return await fetchJson('/api/acptoapi/chains');
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
async function saveChain(name, links) {
|
|
24
|
+
return await fetchJson('/api/acptoapi/chains', {
|
|
25
|
+
method: 'POST',
|
|
26
|
+
headers: { 'content-type': 'application/json' },
|
|
27
|
+
body: JSON.stringify({ name, links }),
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
async function deleteChain(name) {
|
|
32
|
+
return await fetchJson('/api/acptoapi/chains/' + encodeURIComponent(name), { method: 'DELETE' });
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
async function fetchProbe() {
|
|
36
|
+
try { return await fetchJson('/api/acptoapi/probe'); }
|
|
37
|
+
catch { return { results: [] }; }
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export async function chains(h0) {
|
|
41
|
+
// State stored on window to survive page-level re-renders
|
|
42
|
+
const state = window.__fd_chains = window.__fd_chains || {
|
|
43
|
+
loaded: false, error: null, chains: {}, builtin: [], runtime: [],
|
|
44
|
+
probe: [], editing: null, draft: { name: '', links: [] }, newLink: '',
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
if (!state.loaded) {
|
|
48
|
+
try {
|
|
49
|
+
const cd = await loadChains();
|
|
50
|
+
state.chains = cd.chains || {};
|
|
51
|
+
state.builtin = cd.builtin || [];
|
|
52
|
+
state.runtime = cd.runtime || [];
|
|
53
|
+
const pl = await fetchProbe();
|
|
54
|
+
state.probe = pl.results || [];
|
|
55
|
+
state.loaded = true;
|
|
56
|
+
} catch (e) {
|
|
57
|
+
state.error = e.message;
|
|
58
|
+
state.loaded = true;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const nav = () => { if (typeof window.__fd_nav === 'function') window.__fd_nav('chains'); };
|
|
63
|
+
|
|
64
|
+
const onEdit = (name) => () => {
|
|
65
|
+
state.editing = name;
|
|
66
|
+
state.draft = { name, links: [...(state.chains[name] || [])] };
|
|
67
|
+
nav();
|
|
68
|
+
};
|
|
69
|
+
const onCancel = () => { state.editing = null; state.draft = { name: '', links: [] }; nav(); };
|
|
70
|
+
const onNew = () => { state.editing = '__new__'; state.draft = { name: '', links: [] }; nav(); };
|
|
71
|
+
const onAddLink = () => {
|
|
72
|
+
if (!state.newLink.trim()) return;
|
|
73
|
+
state.draft.links.push(state.newLink.trim());
|
|
74
|
+
state.newLink = '';
|
|
75
|
+
nav();
|
|
76
|
+
};
|
|
77
|
+
const onRemoveLink = (idx) => () => { state.draft.links.splice(idx, 1); nav(); };
|
|
78
|
+
const onSave = async () => {
|
|
79
|
+
try {
|
|
80
|
+
await saveChain(state.draft.name.trim(), state.draft.links);
|
|
81
|
+
state.loaded = false; state.editing = null;
|
|
82
|
+
nav();
|
|
83
|
+
} catch (e) { state.error = e.message; nav(); }
|
|
84
|
+
};
|
|
85
|
+
const onDelete = (name) => async () => {
|
|
86
|
+
if (state.builtin.includes(name)) return;
|
|
87
|
+
try { await deleteChain(name); state.loaded = false; nav(); }
|
|
88
|
+
catch (e) { state.error = e.message; nav(); }
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
if (state.error && !state.loaded) {
|
|
92
|
+
return [Hero({ title: 'chains', body: 'fallback chain editor', accent: 'error' }),
|
|
93
|
+
Panel({ title: 'error', children: h('span', { class: 'fd-muted' }, state.error) })];
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (state.editing) {
|
|
97
|
+
const isNew = state.editing === '__new__';
|
|
98
|
+
const isBuiltin = !isNew && state.builtin.includes(state.editing);
|
|
99
|
+
return [
|
|
100
|
+
Hero({ title: isNew ? 'new chain' : 'edit ' + state.editing, body: 'links are tried top-to-bottom', accent: isBuiltin ? 'builtin read-only' : 'editable' }),
|
|
101
|
+
Panel({ title: 'name', children: isNew
|
|
102
|
+
? h('input', { class: 'fd-input', value: state.draft.name, oninput: e => { state.draft.name = e.target.value; } })
|
|
103
|
+
: h('code', {}, state.draft.name) }),
|
|
104
|
+
Panel({ title: 'links', count: state.draft.links.length,
|
|
105
|
+
children: state.draft.links.length === 0
|
|
106
|
+
? EmptyState({ text: 'no links yet — add one below', glyph: '↳' })
|
|
107
|
+
: h('div', { class: 'fd-list' }, ...state.draft.links.map((link, i) =>
|
|
108
|
+
h('div', { key: i, class: 'fd-list-row', 'data-cat': 'kit' },
|
|
109
|
+
h('span', { class: 'fd-list-code' }, String(i + 1).padStart(2, '0')),
|
|
110
|
+
h('div', { class: 'fd-list-main' }, h('div', { class: 'fd-list-title' }, link)),
|
|
111
|
+
isBuiltin ? null : h('button', { class: 'fd-btn fd-btn-mini', onclick: onRemoveLink(i) }, 'remove')
|
|
112
|
+
)
|
|
113
|
+
)) }),
|
|
114
|
+
isBuiltin ? null : Panel({ title: 'add link', children: h('div', { class: 'fd-form-row' },
|
|
115
|
+
h('input', { class: 'fd-input', placeholder: 'provider/model (e.g. groq/llama-3.3-70b-versatile)',
|
|
116
|
+
value: state.newLink, oninput: e => { state.newLink = e.target.value; } }),
|
|
117
|
+
h('button', { class: 'fd-btn', onclick: onAddLink }, 'add')
|
|
118
|
+
) }),
|
|
119
|
+
Panel({ title: 'actions', children: h('div', { class: 'fd-form-row' },
|
|
120
|
+
isBuiltin ? null : h('button', { class: 'fd-btn fd-btn-primary', onclick: onSave }, isNew ? 'create' : 'save'),
|
|
121
|
+
h('button', { class: 'fd-btn', onclick: onCancel }, 'cancel')
|
|
122
|
+
) }),
|
|
123
|
+
];
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const allNames = Object.keys(state.chains).sort();
|
|
127
|
+
const builtinCount = state.builtin.length;
|
|
128
|
+
const runtimeCount = state.runtime.length;
|
|
129
|
+
const workingModels = state.probe.length;
|
|
130
|
+
|
|
131
|
+
return [
|
|
132
|
+
Hero({ title: 'chains', body: 'named fallback chains. callers send model=<name> to select one.', accent: allNames.length + ' total' }),
|
|
133
|
+
Kpi({ items: [[builtinCount, 'builtin'], [runtimeCount, 'runtime'], [workingModels, 'working models']] }),
|
|
134
|
+
Panel({ title: 'create', children: h('button', { class: 'fd-btn fd-btn-primary', onclick: onNew }, '+ new chain') }),
|
|
135
|
+
Panel({ title: 'chains', count: allNames.length,
|
|
136
|
+
children: allNames.length === 0
|
|
137
|
+
? EmptyState({ text: 'no chains configured', glyph: '⊞' })
|
|
138
|
+
: h('div', { class: 'fd-list' }, ...allNames.map(name => {
|
|
139
|
+
const links = state.chains[name] || [];
|
|
140
|
+
const isBuiltin = state.builtin.includes(name);
|
|
141
|
+
return h('div', { key: name, class: 'fd-list-row', 'data-cat': isBuiltin ? 'external' : 'kit' },
|
|
142
|
+
h('span', { class: 'fd-list-code' }, isBuiltin ? '◆' : '○'),
|
|
143
|
+
h('div', { class: 'fd-list-main' },
|
|
144
|
+
h('div', { class: 'fd-list-title' }, name),
|
|
145
|
+
h('div', { class: 'fd-list-sub' }, links.slice(0, 3).join(' → ') + (links.length > 3 ? ` (+${links.length - 3})` : '')),
|
|
146
|
+
),
|
|
147
|
+
h('div', { class: 'fd-list-meta' },
|
|
148
|
+
h('span', { class: 'fd-list-meta-mono' }, isBuiltin ? 'builtin' : 'runtime'),
|
|
149
|
+
h('button', { class: 'fd-btn fd-btn-mini', onclick: onEdit(name) }, isBuiltin ? 'view' : 'edit'),
|
|
150
|
+
isBuiltin ? null : h('button', { class: 'fd-btn fd-btn-mini', onclick: onDelete(name) }, 'delete'),
|
|
151
|
+
)
|
|
152
|
+
);
|
|
153
|
+
})) }),
|
|
154
|
+
Panel({ title: 'discovered models', count: workingModels,
|
|
155
|
+
right: workingModels > 0 ? Chip({ tone: 'ok', children: 'fresh' }) : Chip({ tone: 'miss', children: 'no probe' }),
|
|
156
|
+
children: workingModels === 0
|
|
157
|
+
? EmptyState({ text: 'run a probe to see working models', glyph: '✦' })
|
|
158
|
+
: h('div', { class: 'fd-list' }, ...state.probe.slice(0, 12).map(m =>
|
|
159
|
+
h('div', { key: m.provider + '/' + m.model, class: 'fd-list-row', 'data-cat': 'kit' },
|
|
160
|
+
h('span', { class: 'fd-list-code' }, m.provider.slice(0, 3)),
|
|
161
|
+
h('div', { class: 'fd-list-main' },
|
|
162
|
+
h('div', { class: 'fd-list-title' }, m.provider + '/' + m.model),
|
|
163
|
+
h('div', { class: 'fd-list-sub' }, m.ms + 'ms')
|
|
164
|
+
)
|
|
165
|
+
)
|
|
166
|
+
)) }),
|
|
167
|
+
];
|
|
168
|
+
}
|
|
@@ -8,6 +8,9 @@ const KNOWN_FIELDS = [
|
|
|
8
8
|
{ key: 'display.skin', label: 'skin', kind: 'skin' },
|
|
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
|
+
{ key: 'providers.freddie.baseUrl', label: 'freddie URL (thebird → freddie)', kind: 'string', nullable: true },
|
|
12
|
+
{ key: 'providers.openai.baseUrl', label: 'acptoapi URL (freddie → acptoapi)', kind: 'string', nullable: true },
|
|
13
|
+
{ key: 'providers.openai.model', label: 'default LLM model', kind: 'string', nullable: true },
|
|
11
14
|
{ key: 'agent.provider', label: 'agent provider', kind: 'string' },
|
|
12
15
|
{ key: 'agent.model', label: 'agent model', kind: 'modelDropdown' },
|
|
13
16
|
{ key: 'agent.max_iterations', label: 'max iterations', kind: 'number' },
|
|
@@ -5,6 +5,7 @@ export { models, cron, skills, env, tools } from './freddie/pages-config.js';
|
|
|
5
5
|
export { batch, gateway } from './freddie/pages-runtime.js';
|
|
6
6
|
export { config } from './freddie/pages-config-edit.js';
|
|
7
7
|
export { voice } from './freddie/pages-voice.js';
|
|
8
|
+
export { chains } from './freddie/pages-chains.js';
|
|
8
9
|
|
|
9
10
|
import { home, sessions, projects, agents, analytics } from './freddie/pages-core.js';
|
|
10
11
|
import { chat } from './freddie/pages-chat.js';
|
|
@@ -12,4 +13,5 @@ import { models, cron, skills, env, tools } from './freddie/pages-config.js';
|
|
|
12
13
|
import { batch, gateway } from './freddie/pages-runtime.js';
|
|
13
14
|
import { config } from './freddie/pages-config-edit.js';
|
|
14
15
|
import { voice } from './freddie/pages-voice.js';
|
|
15
|
-
|
|
16
|
+
import { chains } from './freddie/pages-chains.js';
|
|
17
|
+
export const FREDDIE_PAGES = { home, chat, voice, sessions, projects, agents, analytics, models, cron, skills, config, env, tools, batch, gateway, chains };
|
package/src/components.js
CHANGED
|
@@ -41,6 +41,6 @@ export {
|
|
|
41
41
|
} from './components/community.js';
|
|
42
42
|
|
|
43
43
|
export {
|
|
44
|
-
home, chat, sessions, projects, agents, analytics, models, cron, skills, config, env, tools, batch, gateway,
|
|
44
|
+
home, chat, sessions, projects, agents, analytics, models, cron, skills, config, env, tools, batch, gateway, chains,
|
|
45
45
|
skillLabel, getRecentPaths, saveRecentPath, renderChatMessages, FREDDIE_PAGES
|
|
46
46
|
} from './components/freddie.js';
|
package/src/index.js
CHANGED
|
@@ -49,7 +49,7 @@ export {
|
|
|
49
49
|
};
|
|
50
50
|
export const h = webjsx.createElement;
|
|
51
51
|
export const applyDiff = webjsx.applyDiff;
|
|
52
|
-
export { FREDDIE_PAGES, home, chat, sessions, projects, agents, analytics, models, cron, skills, config, env, tools, batch, gateway, skillLabel, getRecentPaths, saveRecentPath, renderChatMessages } from './components.js';
|
|
52
|
+
export { FREDDIE_PAGES, home, chat, sessions, projects, agents, analytics, models, cron, skills, config, env, tools, batch, gateway, chains, skillLabel, getRecentPaths, saveRecentPath, renderChatMessages } from './components.js';
|
|
53
53
|
export default {
|
|
54
54
|
webjsx, loadCss, scope, installStyles, mount, h, applyDiff,
|
|
55
55
|
registerDeckStage, getDeckStage, components, motion, debug, mountKit,
|