| const tools = [ |
| { |
| type: "function", |
| function: { |
| name: "terminal", |
| description: "Run a shell command. This demo displays the request but does not execute it.", |
| parameters: { |
| type: "object", |
| properties: { command: { type: "string", description: "The command to run." } }, |
| required: ["command"], |
| }, |
| }, |
| }, |
| { |
| type: "function", |
| function: { |
| name: "read_file", |
| description: "Read a UTF-8 text file. This demo only displays the requested path.", |
| parameters: { |
| type: "object", |
| properties: { path: { type: "string", description: "Path of the file to read." } }, |
| required: ["path"], |
| }, |
| }, |
| }, |
| { |
| type: "function", |
| function: { |
| name: "web_search", |
| description: "Search the web. This demo displays the query but does not send it.", |
| parameters: { |
| type: "object", |
| properties: { query: { type: "string", description: "The search query." } }, |
| required: ["query"], |
| }, |
| }, |
| }, |
| ]; |
|
|
| const $ = (selector) => document.querySelector(selector); |
| const runButton = $("#run"); |
| const status = $("#status"); |
| const answer = $("#answer"); |
| const calls = $("#calls"); |
| const latency = $("#latency"); |
|
|
| function parseValue(value) { |
| const trimmed = value.trim(); |
| try { return JSON.parse(trimmed); } catch { return trimmed; } |
| } |
|
|
| function parseAtem(text) { |
| const parsed = []; |
| const invokes = text.matchAll(/<atem:invoke\s+name="([^"]+)">([\s\S]*?)<\/atem:invoke>/g); |
| for (const match of invokes) { |
| const argumentsObject = {}; |
| for (const parameter of match[2].matchAll(/<atem:parameter\s+name="([^"]+)">([\s\S]*?)<\/atem:parameter>/g)) { |
| argumentsObject[parameter[1]] = parseValue(parameter[2]); |
| } |
| parsed.push({ name: match[1], arguments: argumentsObject }); |
| } |
| return parsed; |
| } |
|
|
| function normalizeCalls(message) { |
| if (Array.isArray(message.tool_calls) && message.tool_calls.length) { |
| return message.tool_calls.map((call) => { |
| let argumentsObject = call.function?.arguments ?? {}; |
| if (typeof argumentsObject === "string") { |
| try { argumentsObject = JSON.parse(argumentsObject); } catch { argumentsObject = { raw: argumentsObject }; } |
| } |
| return { name: call.function?.name ?? "unknown", arguments: argumentsObject }; |
| }); |
| } |
| return parseAtem(message.content ?? ""); |
| } |
|
|
| function visibleContent(content) { |
| if (!content) return "No user-facing answer was produced. See the proposed tool call below."; |
| const withoutCalls = content.replace(/<atem:function_calls>[\s\S]*?<\/atem:function_calls>/g, ""); |
| const withoutProtocol = withoutCalls.replace(/<\|[^>]+\|>/g, "").replace(/^\s*to=[^<\n]+/, "").trim(); |
| return withoutProtocol || "No user-facing answer was produced. See the proposed tool call below."; |
| } |
|
|
| async function generate() { |
| const endpoint = $("#endpoint").value.trim().replace(/\/+$/, ""); |
| const prompt = $("#prompt").value.trim(); |
| if (!endpoint || !prompt) { |
| status.textContent = "Enter both a public endpoint and a request."; |
| return; |
| } |
|
|
| runButton.disabled = true; |
| status.textContent = ""; |
| latency.textContent = "Generating…"; |
| const started = performance.now(); |
| try { |
| const response = await fetch(`${endpoint}/v1/chat/completions`, { |
| method: "POST", |
| headers: { "Content-Type": "application/json" }, |
| body: JSON.stringify({ |
| model: "muse-glimmer-30b", |
| messages: [ |
| { |
| role: "system", |
| content: `You are a helpful AI assistant. Reasoning strength: ${$("#reasoning").value}. Use a tool only when necessary. Never claim a tool succeeded because this demo does not execute tools. Confirm destructive actions.`, |
| }, |
| { role: "user", content: prompt }, |
| ], |
| tools, |
| temperature: Number($("#temperature").value), |
| top_p: 0.95, |
| max_tokens: Number($("#maxTokens").value), |
| }), |
| }); |
| const payload = await response.json().catch(() => ({})); |
| if (!response.ok) throw new Error(payload.error?.message || `Endpoint returned HTTP ${response.status}.`); |
| const message = payload.choices?.[0]?.message; |
| if (!message) throw new Error("The endpoint response did not contain choices[0].message."); |
|
|
| const proposed = normalizeCalls(message); |
| answer.textContent = visibleContent(message.content); |
| answer.classList.remove("empty"); |
| calls.textContent = JSON.stringify(proposed, null, 2); |
| latency.textContent = `${((performance.now() - started) / 1000).toFixed(1)} s · ${payload.usage?.completion_tokens ?? "?"} tokens`; |
| } catch (error) { |
| status.textContent = `${error.message} Check endpoint reachability, HTTPS, and CORS.`; |
| latency.textContent = "Request failed"; |
| } finally { |
| runButton.disabled = false; |
| } |
| } |
|
|
| runButton.addEventListener("click", generate); |
| $("#prompt").addEventListener("keydown", (event) => { |
| if ((event.ctrlKey || event.metaKey) && event.key === "Enter") generate(); |
| }); |
| document.querySelectorAll("[data-prompt]").forEach((button) => { |
| button.addEventListener("click", () => { $("#prompt").value = button.dataset.prompt; }); |
| }); |
|
|