| 855 | ]; |
| 856 | |
| 857 | function initTrace(host) { |
| 858 | if (!host) return; |
| 859 | host.innerHTML = ""; |
| 860 | host.classList.add("lc-trace"); |
| 861 | |
| 862 | // Compute depth from parent chain |
| 863 | const byId = {}; |
| 864 | TRACE_SPANS.forEach((s) => (byId[s.id] = s)); |
| 865 | function depthOf(id, memo) { |
| 866 | if (!memo) memo = {}; |
| 867 | if (memo[id] != null) return memo[id]; |
| 868 | const s = byId[id]; |
| 869 | if (!s || s.parent == null) memo[id] = 0; |
| 870 | else memo[id] = depthOf(s.parent, memo) + 1; |
| 871 | return memo[id]; |
| 872 | } |
| 873 | const memo = {}; |
| 874 | const depths = {}; |
| 875 | TRACE_SPANS.forEach((s) => (depths[s.id] = depthOf(s.id, memo))); |
| 876 | const maxDepth = Math.max.apply(null, Object.values(depths)); |
| 877 | const totalMs = Math.max.apply(null, TRACE_SPANS.map((s) => s.start + s.dur)); |
| 878 | |
| 879 | const ROW_H = 26; |
| 880 | const PAD_TOP = 14; |
| 881 | const PAD_RIGHT = 16; |
| 882 | const INDENT = 14; |
| 883 | const padLeft = 200 + maxDepth * INDENT; |
| 884 | const W = 720; |
| 885 | const H = PAD_TOP * 2 + ROW_H * TRACE_SPANS.length + 24; |
| 886 | |
| 887 | host.appendChild(htmlEl("div", { class: "lc-trace__head" }, [ |
| 888 | htmlEl("span", { class: "lc-mono" }, "trace · session sess_3f0b… · orchestrator + 3 sub-agents"), |
| 889 | htmlEl("span", { class: "lc-mono lc-muted" }, totalMs.toLocaleString() + " ms total"), |
| 890 | ])); |
| 891 | |
| 892 | const svg = svgEl("svg", { viewBox: `0 0 ${W} ${H}`, width: "100%", role: "img", "aria-label": "Multi-agent trace waterfall" }); |
| 893 | host.appendChild(svg); |
| 894 | |
| 895 | // Axis ticks |
| 896 | const tickCount = 5; |
| 897 | for (let i = 0; i <= tickCount; i++) { |
| 898 | const ms = (totalMs / tickCount) * i; |
| 899 | const x = padLeft + (ms / totalMs) * (W - padLeft - PAD_RIGHT); |
| 900 | svg.appendChild(svgEl("line", { x1: x, x2: x, y1: PAD_TOP, y2: H - 4, stroke: "var(--md-default-fg-color--lightest)", "stroke-width": "0.6" })); |
| 901 | const t = svgEl("text", { x, y: H - 6, "text-anchor": "middle", "font-family": "var(--md-code-font-family)", "font-size": "9", fill: "var(--md-default-fg-color--light)" }); |
| 902 | t.textContent = Math.round(ms) + " ms"; |
| 903 | svg.appendChild(t); |
| 904 | } |
| 905 | |
| 906 | function spanColor(name) { |
| 907 | if (name.indexOf("execute_tool") === 0) return "var(--md-primary-fg-color)"; |
| 908 | if (name.indexOf("generate_content") === 0) return "#fbbc04"; |
| 909 | if (name.indexOf("invoke_agent") === 0) return "var(--md-primary-fg-color--dark)"; |
| 910 | return "var(--md-default-fg-color--light)"; |
| 911 | } |
| 912 | |
| 913 | // Hover detail strip below the SVG. |
| 914 | const detail = htmlEl("div", { class: "lc-trace__detail" }); |