Some checks are pending
build-and-push / image (push) Waiting to run
- Implemented demand pane for managing trend-driven design jobs. - Created diffusion pane for generating images via Stable Diffusion. - Added inbox pane for sweeping and routing artifacts through the CxAI inbox classifier. - Developed items pane for CRUD operations against /api/items. - Introduced lang pane for running language pipelines. - Established mac pane for macOS app distribution information. - Integrated slack pane for sending messages and displaying diagnostics. - Built system pane for process introspection and version information. - Launched tools pane for browsing and invoking MCP tools. - Set up websocket pane for connecting to the /ws/echo service.
76 lines
3.2 KiB
JavaScript
76 lines
3.2 KiB
JavaScript
// panes/lang.js — language pipelines (LangChain-ish sidecar).
|
|
import { registerPane } from '../app.js';
|
|
import { jget, jpost, escapeHtml } from '../lib/api.js';
|
|
import { fmtJSON, err } from '../lib/ui.js';
|
|
|
|
const TPL = `
|
|
<div class="pane-head">
|
|
<div><div class="title">Lang</div><div class="sub">Run language pipelines.</div></div>
|
|
<div class="grow"></div>
|
|
<span class="muted" id="lang-status">—</span>
|
|
</div>
|
|
<div class="grid cols-2">
|
|
<div class="card">
|
|
<div class="card-title"><h2>Pipelines</h2></div>
|
|
<div id="lang-pipelines" class="mb-3">…</div>
|
|
<div class="grid gap-3">
|
|
<label class="field"><span class="lbl">Pipeline</span><select class="input" id="lang-pipeline"></select></label>
|
|
<label class="field"><span class="lbl">Input (JSON)</span><textarea class="input" id="lang-input" rows="6">{}</textarea></label>
|
|
<div class="btn-row">
|
|
<button class="btn btn-primary" id="lang-run">Run</button>
|
|
<button class="btn btn-secondary" id="lang-health">Health</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="card">
|
|
<div class="card-title"><h2>Result</h2></div>
|
|
<pre id="lang-result" class="muted">—</pre>
|
|
</div>
|
|
</div>
|
|
`;
|
|
|
|
async function refresh(host) {
|
|
try {
|
|
const r = await jget('/api/lang/pipelines');
|
|
const items = r.pipelines || [];
|
|
host.querySelector('#lang-pipelines').innerHTML = items.map(p =>
|
|
`<div class="row"><div class="grow"><div class="ttl mono">${escapeHtml(p.name)}</div><div class="desc">${escapeHtml(p.description || '')}</div></div></div>`
|
|
).join('') || '<div class="muted" style="padding:12px">no pipelines</div>';
|
|
const sel = host.querySelector('#lang-pipeline');
|
|
if (sel && sel.children.length === 0) {
|
|
sel.innerHTML = items.map(p => `<option value="${escapeHtml(p.name)}">${escapeHtml(p.name)}</option>`).join('');
|
|
}
|
|
host.querySelector('#lang-status').textContent = 'ok';
|
|
} catch (e) {
|
|
host.querySelector('#lang-status').textContent = 'upstream unavailable: ' + e.message;
|
|
}
|
|
}
|
|
|
|
registerPane('lang', {
|
|
label: 'Lang',
|
|
init(host) {
|
|
host.innerHTML = TPL;
|
|
host.querySelector('#lang-run').addEventListener('click', async () => {
|
|
const name = host.querySelector('#lang-pipeline').value;
|
|
let input;
|
|
try { input = JSON.parse(host.querySelector('#lang-input').value || '{}'); }
|
|
catch (e) { return err(`bad JSON: ${e.message}`); }
|
|
host.querySelector('#lang-status').textContent = 'running…';
|
|
try {
|
|
const r = await jpost(`/api/lang/pipelines/${encodeURIComponent(name)}`, { input });
|
|
host.querySelector('#lang-result').textContent = fmtJSON(r);
|
|
host.querySelector('#lang-status').textContent = `ok · ${r.duration_ms ?? '?'}ms`;
|
|
} catch (e) {
|
|
host.querySelector('#lang-result').textContent = fmtJSON(e.body ?? { error: e.message });
|
|
host.querySelector('#lang-status').textContent = `error ${e.status ?? ''}`;
|
|
}
|
|
});
|
|
host.querySelector('#lang-health').addEventListener('click', async () => {
|
|
try { host.querySelector('#lang-result').textContent = fmtJSON(await jget('/api/lang/healthz')); }
|
|
catch (e) { host.querySelector('#lang-result').textContent = e.message; }
|
|
});
|
|
refresh(host);
|
|
},
|
|
refresh,
|
|
});
|