Spaces:
Running
Running
| (function () { | |
| "use strict"; | |
| var sharedQid = null; | |
| function esc(value) { | |
| return String(value === null || value === undefined ? "" : value) | |
| .replace(/&/g, "&").replace(/</g, "<") | |
| .replace(/>/g, ">").replace(/"/g, """); | |
| } | |
| function text(value) { | |
| if (value === null || value === undefined) return ""; | |
| if (typeof value === "string") return value; | |
| return JSON.stringify(value, null, 2); | |
| } | |
| function inputText(event) { | |
| var value = event && event.input; | |
| if (value === null || value === undefined) return ""; | |
| if (typeof value !== "object" || Array.isArray(value)) return text(value); | |
| var keys = Object.keys(value); | |
| if (keys.length === 1 && typeof value[keys[0]] === "string") return value[keys[0]]; | |
| return JSON.stringify(value, null, 2); | |
| } | |
| function humanBytes(length) { | |
| if (length < 1024) return length + " B"; | |
| if (length < 1024 * 1024) return (length / 1024).toFixed(1) + " KB"; | |
| return (length / (1024 * 1024)).toFixed(2) + " MB"; | |
| } | |
| function toolStep(index, event, resultEvent) { | |
| var name = event.name || "tool"; | |
| var input = inputText(event); | |
| var output = resultEvent ? text(resultEvent.content) : ""; | |
| var collapsed = output.length > 2000; | |
| return '<div class="pretty-step tool tool-' + esc(name) + '">' + | |
| '<div class="pretty-step-head"><span class="pretty-step-index">' + index + | |
| '</span><span class="pretty-kind">tool</span><span class="pretty-tool-pill">' + | |
| esc(name) + "</span></div>" + | |
| (input ? '<div class="pretty-label">Input</div><pre class="pretty-input">' + | |
| esc(input) + "</pre>" : "") + | |
| (resultEvent ? '<div class="pretty-label">Output <span>' + | |
| humanBytes(output.length) + '</span></div><div class="pretty-output-wrap' + | |
| (collapsed ? " collapsed" : "") + '"><pre class="pretty-output">' + | |
| esc(output) + "</pre>" + | |
| (collapsed ? '<button type="button" class="pretty-output-toggle">Expand output ▾</button>' : "") + | |
| "</div>" : "") + | |
| "</div>"; | |
| } | |
| function messageStep(index, event) { | |
| var content = text(event.content).trim(); | |
| if (!content) return ""; | |
| return '<div class="pretty-step model"><div class="pretty-step-head">' + | |
| '<span class="pretty-step-index">' + index + | |
| '</span><span class="pretty-kind">model</span></div>' + | |
| '<div class="pretty-model-text">' + esc(content) + "</div></div>"; | |
| } | |
| function otherStep(index, event) { | |
| var content = text(event.content || event.input || event); | |
| return '<div class="pretty-step other"><div class="pretty-step-head">' + | |
| '<span class="pretty-step-index">' + index + '</span><span class="pretty-kind">' + | |
| esc(event.type || "event") + "</span></div>" + | |
| '<pre class="pretty-output">' + esc(content) + "</pre></div>"; | |
| } | |
| function render(events, label) { | |
| events = events || []; | |
| if (!events.length) return ""; | |
| var parts = []; | |
| var step = 0; | |
| for (var i = 0; i < events.length; i++) { | |
| var event = events[i] || {}; | |
| if (event.type === "tool_call") { | |
| step++; | |
| var next = events[i + 1]; | |
| parts.push(toolStep(step, event, next && next.type === "tool_result" ? next : null)); | |
| if (next && next.type === "tool_result") i++; | |
| } else if (event.type === "tool_result") { | |
| step++; | |
| parts.push(toolStep(step, { name: "tool" }, event)); | |
| } else if (["text", "llm_response", "assistant", "model"].indexOf(event.type) >= 0) { | |
| step++; | |
| parts.push(messageStep(step, event)); | |
| } else if (event.type !== "done") { | |
| step++; | |
| parts.push(otherStep(step, event)); | |
| } | |
| } | |
| return '<details class="pretty-trajectory"><summary>' + | |
| esc(label || "Agent trajectory") + " · " + events.length + | |
| ' events</summary><div class="pretty-steps">' + parts.join("") + "</div></details>"; | |
| } | |
| function bind(container) { | |
| if (!container) return; | |
| container.querySelectorAll(".pretty-output-toggle").forEach(function (button) { | |
| button.addEventListener("click", function () { | |
| var wrap = button.closest(".pretty-output-wrap"); | |
| var collapsed = wrap.classList.toggle("collapsed"); | |
| button.textContent = collapsed ? "Expand output ▾" : "Collapse output ▴"; | |
| }); | |
| }); | |
| } | |
| function goldItems(value) { | |
| var values = Array.isArray(value) ? value : [value]; | |
| return values.filter(function (item) { | |
| return item !== null && item !== undefined && String(item).trim() !== ""; | |
| }).map(function (item) { | |
| if (typeof item === "object") { | |
| return item.answer_text || item.value || item.name || JSON.stringify(item); | |
| } | |
| return String(item); | |
| }); | |
| } | |
| function gold(value, label) { | |
| var values = goldItems(value); | |
| return '<div class="compact-gold"><span class="compact-gold-label">' + | |
| esc(label || "Gold") + (values.length > 1 ? " · " + values.length : "") + | |
| '</span><div class="compact-gold-pills">' + | |
| (values.length ? values.map(function (item) { | |
| return '<span class="compact-gold-pill" title="' + esc(item) + '">' + | |
| esc(item) + "</span>"; | |
| }).join("") : '<span class="compact-gold-empty">none</span>') + | |
| "</div></div>"; | |
| } | |
| function supporting(label, html, count) { | |
| return '<details class="compact-supporting"><summary>' + esc(label) + | |
| (count !== undefined ? " · " + count : "") + | |
| '</summary><div class="compact-supporting-body">' + html + "</div></details>"; | |
| } | |
| window.TrajectoryUI = { | |
| render: render, | |
| bind: bind, | |
| gold: gold, | |
| supporting: supporting, | |
| setQid: function (qid) { if (qid !== null && qid !== undefined) sharedQid = String(qid); }, | |
| getQid: function () { return sharedQid; }, | |
| }; | |
| })(); | |