// A view of WAI Quantum's engine inside an agent host: one page, the view it // draws named by the server in , the tool's answer // given by the host (src/views/host.js). The page loads nothing and connects // nowhere; a job the service is still running is followed through the // server's own tool for that, which the host keeps from the model. import { el } from '../dom.js'; import { connect } from './host.js'; import { render, META } from './render.js'; const VIEW = document.querySelector('meta[name="wai-view"]')?.content || 'result'; const POLL = 'poll_quantum_job'; const root = document.getElementById('wq'); const body = document.body; body.dataset.view = VIEW; body.dataset.state = 'waiting'; const TITLES = { result: 'Result', receipt: 'Receipt', circuit: 'Circuit', critique: 'Critique', estimate: 'Resource estimate', target: 'Device target' }; let args = {}; function head(sub) { return el('header', { class: 'wq-head' }, el('span', { class: 'wq-name', text: 'WAI Quantum' }), el('span', { class: 'wq-what', text: TITLES[VIEW] || VIEW }), sub ? el('span', { class: 'qs-note', text: sub }) : null); } function waiting(text) { root.replaceChildren(head(), el('p', { class: 'qs-note', id: 'wq-waiting', text })); } const host = connect({ name: 'wai-quantum-views', version: '1', onInput: (a) => { args = a || {}; waiting('The tool is running; its answer appears here.'); }, onResult: (res) => show(res), onCancelled: (why) => { body.dataset.state = 'cancelled'; waiting(`The call was cancelled${why ? `: ${why}` : ''}.`); }, onContext: (ctx) => { if (ctx?.theme === 'light' || ctx?.theme === 'dark') document.documentElement.dataset.theme = ctx.theme; }, onTeardown: () => { stopped = true; }, }); let stopped = false; let polling = null; async function show(res) { const data = res?._meta?.[META] || null; const out = render(VIEW, { args, res: res || {}, data }); root.replaceChildren(head(), ...out.blocks); body.dataset.state = out.state; if (out.poll) follow(out.poll); if (out.checked) { const v = await out.checked; if (!v.error) { const what = VIEW === 'estimate' ? 'the estimate’s seal' : VIEW === 'circuit' ? 'the compile’s certificate' : 'the receipt'; host.tellModel(`The ${TITLES[VIEW].toLowerCase()} view checked ${what} on the person’s machine with the engine: ${v.valid ? 'it verifies' : 'it does NOT verify'}${v.signer ? `, signed by ${v.signer}` : ''}.`).catch(() => {}); } } } // A job the service is still running: asked after, more slowly each time, until it ends. function follow(id) { if (polling) return; let wait = 1000; polling = (async () => { while (!stopped) { await new Promise((r) => setTimeout(r, wait)); wait = Math.min(5000, wait * 1.5); let res; try { res = await host.callTool(POLL, { id }); } catch (e) { waiting(`This host would not let the view follow the job (${e.message}); get_quantum_job reads it.`); break; } const s = res?.structuredContent?.status; if (s !== 'queued' && s !== 'running') { polling = null; show(res); return; } } polling = null; })(); } // The host sizes the frame to the page. let sized = 0; new ResizeObserver(() => { cancelAnimationFrame(sized); sized = requestAnimationFrame(() => { // The content's own size, not the frame's: the host fits the frame to it. const r = root.getBoundingClientRect(); host.sizeChanged(Math.ceil(r.width), Math.ceil(r.bottom)); }); }).observe(root); waiting('Waiting for the host.'); host.start().catch((e) => { body.dataset.state = 'no-host'; waiting(`No host answered (${e.message}). This page is a view for an agent host; it draws what a tool answers.`); });