dsh-agy-link 0.4.42 → 0.4.44

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/client.js CHANGED
@@ -121,6 +121,9 @@ window.__ModuleLoader__.load({
121
121
  "pool.label": "号池调度:",
122
122
  "pool.sequential": "顺次耗尽",
123
123
  "pool.roundRobin": "轮询均衡",
124
+ "models.label": "模型显示:",
125
+ "models.empty": "模型目录还没有可用模型,发一次对话或点“刷新额度”后再来管理",
126
+ "models.hint": "点击切换显示/隐藏;关闭的模型不在模型选择器中列出,进行中的会话不受影响。",
124
127
  "header.refreshQuota": "刷新额度",
125
128
  "header.refreshing": "刷新中",
126
129
  "console.close": "关闭(Esc)",
@@ -212,6 +215,9 @@ window.__ModuleLoader__.load({
212
215
  "pool.label": "Account-pool scheduling:",
213
216
  "pool.sequential": "Use sequentially",
214
217
  "pool.roundRobin": "Round-robin",
218
+ "models.label": "Model visibility:",
219
+ "models.empty": "No models in the catalog yet — send a message or click \"Refresh quota\", then come back to manage them",
220
+ "models.hint": "Click to show/hide. Hidden models are not listed in the model picker; ongoing sessions are unaffected.",
215
221
  "header.refreshQuota": "Refresh quota",
216
222
  "header.refreshing": "Refreshing...",
217
223
  "console.close": "Close (Esc)",
@@ -303,6 +309,9 @@ window.__ModuleLoader__.load({
303
309
  "pool.label": "Agendamento do pool de contas:",
304
310
  "pool.sequential": "Usar em sequência",
305
311
  "pool.roundRobin": "Rodízio",
312
+ "models.label": "Visibilidade dos modelos:",
313
+ "models.empty": "Ainda não há modelos no catálogo — envie uma mensagem ou clique em \"Atualizar cota\" e volte para gerenciá-los",
314
+ "models.hint": "Clique para mostrar/ocultar. Modelos ocultos não aparecem no seletor de modelos; as sessões em andamento não são afetadas.",
306
315
  "header.refreshQuota": "Atualizar cota",
307
316
  "header.refreshing": "Atualizando...",
308
317
  "console.close": "Fechar (Esc)",
@@ -394,6 +403,9 @@ window.__ModuleLoader__.load({
394
403
  "pool.label": "Programación del pool de cuentas:",
395
404
  "pool.sequential": "Usar en secuencia",
396
405
  "pool.roundRobin": "Turno rotativo",
406
+ "models.label": "Visibilidad de modelos:",
407
+ "models.empty": "Aún no hay modelos en el catálogo: envía un mensaje o haz clic en \"Actualizar cuota\" y vuelve para gestionarlos",
408
+ "models.hint": "Haz clic para mostrar/ocultar. Los modelos ocultos no aparecen en el selector de modelos; las sesiones en curso no se ven afectadas.",
397
409
  "header.refreshQuota": "Actualizar cuota",
398
410
  "header.refreshing": "Actualizando...",
399
411
  "console.close": "Cerrar (Esc)",
@@ -1345,7 +1357,7 @@ window.__ModuleLoader__.load({
1345
1357
 
1346
1358
  /* Diff stat badge (+10 -2) */
1347
1359
  .agy-tv-diff-stat {
1348
- font-family: var(--dsw-font-family-code, ui-monospace, monospace);
1360
+ font-family: var(--ds-font-family-code, ui-monospace, monospace);
1349
1361
  font-size: calc(var(--dsh-content-font-size-secondary, 13px) - 2px);
1350
1362
  color: var(--dsw-alias-label-caption, #94a3b8);
1351
1363
  margin-left: 10px;
@@ -1354,7 +1366,7 @@ window.__ModuleLoader__.load({
1354
1366
 
1355
1367
  /* Preview text */
1356
1368
  .agy-tv-preview {
1357
- font-family: var(--dsw-font-family-code, ui-monospace, monospace);
1369
+ font-family: var(--ds-font-family-code, ui-monospace, monospace);
1358
1370
  font-size: 11px;
1359
1371
  color: var(--dsw-alias-label-caption, #94a3b8);
1360
1372
  margin-left: 8px;
@@ -1375,7 +1387,7 @@ window.__ModuleLoader__.load({
1375
1387
  .agy-tv-card {
1376
1388
  border: 0.5px solid var(--dsw-alias-border-l1, #e2e8f0);
1377
1389
  background: var(--dsw-alias-markdown-code-block, #f8fafc);
1378
- font-family: var(--dsw-font-family-code, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);
1390
+ font-family: var(--ds-font-family-code, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);
1379
1391
  font-size: 12px;
1380
1392
  line-height: 1.55;
1381
1393
  border-radius: 12px;
@@ -1564,6 +1576,228 @@ window.__ModuleLoader__.load({
1564
1576
  }
1565
1577
  }
1566
1578
  //#endregion
1579
+ //#region src/client/mermaid.ts
1580
+ const MERMAID_CSS = `
1581
+ div.md-code-block[data-agy-mermaid="done"] [data-code-block-content] {
1582
+ display: none !important;
1583
+ }
1584
+ div.md-code-block[data-agy-mermaid="render"] {
1585
+ border-color: var(--dsw-alias-border-l2, #e2e8f0);
1586
+ }
1587
+ div[data-agy-mermaid-svg] {
1588
+ padding: 12px 8px;
1589
+ overflow-x: auto;
1590
+ text-align: center;
1591
+ background: var(--dsw-alias-bg-base, #ffffff);
1592
+ }
1593
+ div[data-agy-mermaid-svg] svg {
1594
+ max-width: 100%;
1595
+ height: auto;
1596
+ }
1597
+ div[data-agy-mermaid-svg][data-agy-mermaid-error] {
1598
+ text-align: left;
1599
+ color: var(--dsw-alias-label-tertiary, #64748b);
1600
+ font-size: 12px;
1601
+ white-space: pre-wrap;
1602
+ padding: 10px 12px;
1603
+ }
1604
+ `;
1605
+ const CDN_URLS = [
1606
+ "/plugins/agy-link/mermaid.min.js",
1607
+ "https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js",
1608
+ "https://unpkg.com/mermaid@11/dist/mermaid.min.js"
1609
+ ];
1610
+ let loadPromise = null;
1611
+ let loadFailedAt = 0;
1612
+ const LOAD_RETRY_MS = 6e4;
1613
+ let renderSeq = 0;
1614
+ function injectStyles$1() {
1615
+ if (typeof document === "undefined") return;
1616
+ if (document.getElementById("agy-mermaid-css")) return;
1617
+ const st = document.createElement("style");
1618
+ st.id = "agy-mermaid-css";
1619
+ st.textContent = MERMAID_CSS;
1620
+ document.head.appendChild(st);
1621
+ }
1622
+ function loadScript(src) {
1623
+ return new Promise((resolve) => {
1624
+ const s = document.createElement("script");
1625
+ s.src = src;
1626
+ s.async = true;
1627
+ const done = (ok) => {
1628
+ s.removeEventListener("load", onLoad);
1629
+ s.removeEventListener("error", onError);
1630
+ resolve(ok);
1631
+ };
1632
+ const onLoad = () => done(true);
1633
+ const onError = () => done(false);
1634
+ s.addEventListener("load", onLoad);
1635
+ s.addEventListener("error", onError);
1636
+ document.head.appendChild(s);
1637
+ setTimeout(() => done(false), 15e3);
1638
+ });
1639
+ }
1640
+ async function loadMermaid() {
1641
+ if (typeof window === "undefined") return null;
1642
+ if (window.mermaid !== void 0) return window.mermaid;
1643
+ if (loadPromise !== null) return loadPromise;
1644
+ if (Date.now() - loadFailedAt < LOAD_RETRY_MS) return null;
1645
+ loadPromise = (async () => {
1646
+ for (const url of CDN_URLS) if (await loadScript(url) && window.mermaid !== void 0) {
1647
+ try {
1648
+ window.mermaid.initialize({
1649
+ startOnLoad: false,
1650
+ securityLevel: "strict",
1651
+ theme: "neutral",
1652
+ fontFamily: "inherit"
1653
+ });
1654
+ } catch {}
1655
+ return window.mermaid;
1656
+ }
1657
+ loadFailedAt = Date.now();
1658
+ loadPromise = null;
1659
+ return null;
1660
+ })();
1661
+ return loadPromise;
1662
+ }
1663
+ /** Banner infostring text ("mermaid") identifies the fence language. */
1664
+ function fenceLang(block) {
1665
+ const text = ((block.querySelector("[data-code-block-banner] [class*=\"infostring\"]") ?? block.querySelector("[data-code-block-banner] [class*=\"language\"]") ?? block.querySelector("[data-code-block-banner]"))?.textContent ?? "").trim().toLowerCase();
1666
+ if (text !== "") return text.split(/\s+/)[0] ?? "";
1667
+ const code = block.querySelector("[data-code-block-content] code");
1668
+ const m = (code?.getAttribute("class") ?? "").match(/language-([\w-]+)/);
1669
+ if (m?.[1]) return m[1].toLowerCase();
1670
+ return (code?.getAttribute("data-language") ?? block.getAttribute("data-language") ?? "").toLowerCase();
1671
+ }
1672
+ const MERMAID_FIRST_LINE = /^(?:flowchart(?:\s+\w+)?|graph\s+(?:TB|TD|LR|RL|BT)|sequenceDiagram|classDiagram(?:-v2)?|stateDiagram(?:-v2)?|erDiagram|journey|gantt|pie|mindmap|timeline|gitGraph|sankey-beta|xychart-beta|block-beta|quadrantChart|requirementDiagram|radar-beta|C4(?:Context|Container|Component|Dynamic))\b/;
1673
+ /** Content sniff: unknown-language fences are the whole reason this module exists. */
1674
+ function looksLikeMermaidSource(source) {
1675
+ const line = source.split(/\r?\n/).find((l) => l.trim() !== "");
1676
+ return line !== void 0 && MERMAID_FIRST_LINE.test(line.trim());
1677
+ }
1678
+ function isMermaidLang(lang) {
1679
+ return lang === "mermaid" || lang === "mermaidjs" || lang.startsWith("mermaid");
1680
+ }
1681
+ const KNOWN_NON_MERMAID = /* @__PURE__ */ new Set([
1682
+ "typescript",
1683
+ "ts",
1684
+ "javascript",
1685
+ "js",
1686
+ "jsx",
1687
+ "tsx",
1688
+ "python",
1689
+ "py",
1690
+ "java",
1691
+ "c",
1692
+ "cpp",
1693
+ "c++",
1694
+ "csharp",
1695
+ "cs",
1696
+ "go",
1697
+ "golang",
1698
+ "rust",
1699
+ "rs",
1700
+ "php",
1701
+ "ruby",
1702
+ "rb",
1703
+ "swift",
1704
+ "kotlin",
1705
+ "kt",
1706
+ "scala",
1707
+ "shell",
1708
+ "bash",
1709
+ "sh",
1710
+ "zsh",
1711
+ "sql",
1712
+ "html",
1713
+ "css",
1714
+ "scss",
1715
+ "less",
1716
+ "json",
1717
+ "yaml",
1718
+ "yml",
1719
+ "xml",
1720
+ "graphql",
1721
+ "toml",
1722
+ "ini",
1723
+ "dockerfile",
1724
+ "makefile"
1725
+ ]);
1726
+ function isMermaidBlock(lang, source) {
1727
+ if (isMermaidLang(lang)) return true;
1728
+ if (KNOWN_NON_MERMAID.has(lang)) return false;
1729
+ return looksLikeMermaidSource(source);
1730
+ }
1731
+ function readSource(block) {
1732
+ return ((block.querySelector("[data-code-block-content] code") ?? block.querySelector("[data-code-block-content] pre") ?? block.querySelector("[data-code-block-content]"))?.textContent ?? "").trim();
1733
+ }
1734
+ async function renderInto(block, source) {
1735
+ block.querySelector("[data-agy-mermaid-svg]")?.remove();
1736
+ const mount = document.createElement("div");
1737
+ mount.setAttribute("data-agy-mermaid-svg", "1");
1738
+ block.appendChild(mount);
1739
+ const api = await loadMermaid();
1740
+ if (api === null) {
1741
+ block.setAttribute("data-agy-mermaid", "error");
1742
+ mount.setAttribute("data-agy-mermaid-error", "1");
1743
+ mount.textContent = "Mermaid renderer unavailable (offline). Diagram source stays below.";
1744
+ return;
1745
+ }
1746
+ try {
1747
+ renderSeq += 1;
1748
+ const id = "agy-mmd-" + renderSeq;
1749
+ const { svg } = await api.render(id, source);
1750
+ mount.innerHTML = svg;
1751
+ block.setAttribute("data-agy-mermaid", "done");
1752
+ } catch (e) {
1753
+ block.setAttribute("data-agy-mermaid", "error");
1754
+ mount.setAttribute("data-agy-mermaid-error", "1");
1755
+ mount.textContent = "Mermaid render failed: " + (e instanceof Error ? e.message : String(e));
1756
+ }
1757
+ }
1758
+ let scanTimer = null;
1759
+ function scheduleScan() {
1760
+ if (scanTimer !== null) return;
1761
+ scanTimer = setTimeout(() => {
1762
+ scanTimer = null;
1763
+ scan();
1764
+ }, 150);
1765
+ }
1766
+ function scan() {
1767
+ if (typeof document === "undefined") return;
1768
+ const blocks = document.querySelectorAll(".md-code-block");
1769
+ for (let i = 0; i < blocks.length; i++) {
1770
+ const block = blocks[i];
1771
+ if (!block) continue;
1772
+ const state = block.getAttribute("data-agy-mermaid");
1773
+ if (state === "done" || state === "busy" || state === "error") continue;
1774
+ const lang = fenceLang(block);
1775
+ const source = readSource(block);
1776
+ if (source === "") continue;
1777
+ if (!isMermaidBlock(lang, source)) continue;
1778
+ block.setAttribute("data-agy-mermaid", "busy");
1779
+ renderInto(block, source);
1780
+ }
1781
+ }
1782
+ function installMermaidRendering() {
1783
+ if (typeof window === "undefined" || typeof document === "undefined") return;
1784
+ injectStyles$1();
1785
+ const observer = new MutationObserver(() => {
1786
+ scheduleScan();
1787
+ });
1788
+ const setup = () => {
1789
+ if (document.body) {
1790
+ observer.observe(document.body, {
1791
+ childList: true,
1792
+ subtree: true
1793
+ });
1794
+ scan();
1795
+ }
1796
+ };
1797
+ if (document.readyState === "loading") window.addEventListener("DOMContentLoaded", setup, { once: true });
1798
+ else setup();
1799
+ }
1800
+ //#endregion
1567
1801
  //#region src/client/reasoning.ts
1568
1802
  const REASONING_CSS = `
1569
1803
  /* Hover affordance on thinking disclosure rows */
@@ -2528,6 +2762,12 @@ body.dark,
2528
2762
  await refresh();
2529
2763
  setLoadingAction(null);
2530
2764
  };
2765
+ const toggleModelHidden = async (id, hide) => {
2766
+ const next = new Set(status?.hiddenModels ?? []);
2767
+ if (hide) next.add(id);
2768
+ else next.delete(id);
2769
+ await setCfg("hiddenModels", Array.from(next));
2770
+ };
2531
2771
  const setPrimary = async (id) => {
2532
2772
  setLoadingAction(`primary:${id}`);
2533
2773
  await postJson("/plugins/agy-link/pool/primary", { id });
@@ -2582,6 +2822,8 @@ body.dark,
2582
2822
  };
2583
2823
  const authPhase = status?.auth?.phase ?? "unknown";
2584
2824
  const pool = status?.pool;
2825
+ const catalogModels = status?.catalogModels ?? [];
2826
+ const hiddenModelSet = new Set(status?.hiddenModels ?? []);
2585
2827
  const accounts = pool?.accounts ?? [];
2586
2828
  const isAuthed = authPhase === "ok" || accounts.length > 0;
2587
2829
  const isBusy = loadingAction !== null;
@@ -2729,12 +2971,12 @@ body.dark,
2729
2971
  color: "var(--agy-text-primary)"
2730
2972
  } }, brandIcon(FAMILY_BRAND[familyKey], 14), h("span", null, label)), renderLine(t("quota.fiveHour"), pct5h, c5h, w5h.resetText ? w5h.resetText + cdNote : cdNote.replace(/^ · /, "")), renderLine(t("quota.weekly"), pctWeekly, cWeekly, wWeekly.resetText));
2731
2973
  };
2732
- const inUseIds = new Set(Object.values(pool?.activeAccountIds ?? {}));
2974
+ const activeAccountId = pool?.activeAccountId ?? pool?.lastActiveAccountId ?? pool?.activeAccountIds?.google ?? pool?.primaryAccountId;
2733
2975
  const renderedAccountCards = accounts.map((acc) => {
2734
2976
  const isPrimary = acc.id === pool?.primaryAccountId;
2735
- const isInUse = inUseIds.has(acc.id);
2736
2977
  const hasCooldown = Object.entries(acc.cooldowns).some(([, cd]) => cd && cd.cooldownUntil > Date.now());
2737
2978
  const isAuthRequired = acc.authRequired;
2979
+ const isInUse = acc.enabled && !isAuthRequired && activeAccountId !== void 0 && activeAccountId === acc.id;
2738
2980
  const dotColor = !acc.enabled ? "#64748b" : isAuthRequired ? "#ef4444" : hasCooldown ? "#f59e0b" : "#10b981";
2739
2981
  const isEditingProxy = editingProxyId === acc.id;
2740
2982
  const isExpanded = expandedModels[acc.id] ?? false;
@@ -2798,14 +3040,17 @@ body.dark,
2798
3040
  } }, uiIcon("mail", 11, "var(--agy-badge-email-text)"), acc.email) : null, isPrimary ? h("span", { style: {
2799
3041
  ...S.badgePrimary,
2800
3042
  gap: "4px"
2801
- } }, uiIcon("star", 10, "var(--agy-badge-primary-text)"), t("status.primary")) : null, isInUse ? h("span", { style: {
2802
- ...S.badgeTag,
2803
- background: "rgba(16, 185, 129, 0.12)",
2804
- color: "#10b981",
2805
- borderColor: "rgba(16, 185, 129, 0.45)",
2806
- gap: "4px",
2807
- fontWeight: 700
2808
- } }, uiIcon("zap", 11, "#10b981"), t("status.inUse")) : null, acc.proxyUrl ? h("span", { style: {
3043
+ } }, uiIcon("star", 10, "var(--agy-badge-primary-text)"), t("status.primary")) : null, isInUse ? h("span", {
3044
+ style: {
3045
+ ...S.badgeTag,
3046
+ background: "rgba(16, 185, 129, 0.12)",
3047
+ color: "#10b981",
3048
+ borderColor: "rgba(16, 185, 129, 0.45)",
3049
+ gap: "4px",
3050
+ fontWeight: 700
3051
+ },
3052
+ title: t("status.inUse")
3053
+ }, uiIcon("zap", 11, "#10b981"), t("status.inUse")) : null, acc.proxyUrl ? h("span", { style: {
2809
3054
  ...S.badgeTag,
2810
3055
  background: "var(--agy-badge-proxy-bg)",
2811
3056
  color: "var(--agy-badge-proxy-text)",
@@ -3161,7 +3406,33 @@ body.dark,
3161
3406
  type: "button",
3162
3407
  style: pool?.mode === "round-robin" ? S.segBtnActive : S.segBtn,
3163
3408
  onClick: () => void setMode("round-robin")
3164
- }, t("pool.roundRobin")))))));
3409
+ }, t("pool.roundRobin")))), h("div", { style: {
3410
+ display: "flex",
3411
+ flexDirection: "column",
3412
+ gap: "6px"
3413
+ } }, h("span", { style: {
3414
+ color: "var(--agy-text-primary)",
3415
+ fontWeight: 600,
3416
+ fontSize: "12.5px"
3417
+ } }, t("models.label")), catalogModels.length === 0 ? h("span", { style: S.muted }, t("models.empty")) : h("div", { style: {
3418
+ display: "flex",
3419
+ flexWrap: "wrap",
3420
+ gap: "6px"
3421
+ } }, catalogModels.map((m) => {
3422
+ const isHidden = hiddenModelSet.has(m.id);
3423
+ return h("button", {
3424
+ type: "button",
3425
+ key: m.id,
3426
+ title: m.id,
3427
+ disabled: loadingAction === "config:hiddenModels",
3428
+ style: isHidden ? {
3429
+ ...S.segBtn,
3430
+ opacity: .45,
3431
+ textDecoration: "line-through"
3432
+ } : S.segBtnActive,
3433
+ onClick: () => void toggleModelHidden(m.id, !isHidden)
3434
+ }, m.name);
3435
+ })), h("span", { style: S.muted }, t("models.hint"))))));
3165
3436
  };
3166
3437
  /** Modal dialog container rendered into document.body */
3167
3438
  const AgyModalDialog = () => {
@@ -3261,13 +3532,22 @@ body.dark,
3261
3532
  clearInterval(timer);
3262
3533
  };
3263
3534
  }, []);
3264
- const accounts = (status?.pool)?.accounts ?? [];
3265
- const hasCooldown = accounts.some((a) => Object.entries(a.cooldowns).some(([, cd]) => cd && cd.cooldownUntil > Date.now()));
3535
+ const pool = status?.pool;
3536
+ const accounts = pool?.accounts ?? [];
3537
+ const rawActiveId = pool?.activeAccountId ?? pool?.lastActiveAccountId ?? pool?.activeAccountIds?.google ?? pool?.primaryAccountId;
3538
+ const activeAcc = accounts.find((a) => a.id === rawActiveId && a.enabled && !a.authRequired) ?? accounts.find((a) => a.enabled && !a.authRequired) ?? accounts[0];
3539
+ const activeHasCooldown = activeAcc ? Object.entries(activeAcc.cooldowns).some(([, cd]) => cd && cd.cooldownUntil > Date.now()) : false;
3540
+ const allInCooldown = accounts.length > 0 && accounts.every((a) => !a.enabled || a.authRequired || Object.entries(a.cooldowns).some(([, cd]) => cd && cd.cooldownUntil > Date.now()));
3266
3541
  const isAuthed = status?.auth?.phase === "ok" || accounts.length > 0;
3267
- const color = status === null ? "#64748b" : status.dormantReason ? "#f59e0b" : hasCooldown ? "#f59e0b" : isAuthed ? "#10b981" : "#f59e0b";
3542
+ const color = status === null ? "#64748b" : status.dormantReason ? "#f59e0b" : allInCooldown ? "#f59e0b" : activeHasCooldown ? "#f59e0b" : isAuthed ? "#10b981" : "#f59e0b";
3543
+ const legacyDefault = activeAcc && activeAcc.defaultAlias === void 0 && activeAcc.systemHome && activeAcc.alias === "主账号 (系统登录)";
3544
+ const displayAlias = activeAcc ? activeAcc.defaultAlias || legacyDefault ? activeAcc.systemHome ? t("account.defaultAlias") : t("account.aliasDefault", { number: accounts.indexOf(activeAcc) + 1 }) : activeAcc.alias : "";
3545
+ const activeDetail = activeAcc ? ` · ${t("status.inUse")}: ${displayAlias}${activeAcc.email ? ` (${activeAcc.email})` : ""}` : "";
3546
+ const badgeTitle = `${t("header.badgeTitle", { count: accounts.length })}${activeDetail}`;
3547
+ const buttonLabel = displayAlias ? `AGY · ${displayAlias}` : `AGY (${accounts.length})`;
3268
3548
  const badge = h("button", {
3269
3549
  type: "button",
3270
- title: t("header.badgeTitle", { count: accounts.length }),
3550
+ title: badgeTitle,
3271
3551
  className: "agy-btn",
3272
3552
  onClick: () => agyModalStore.setOpen(true),
3273
3553
  style: {
@@ -3291,7 +3571,7 @@ body.dark,
3291
3571
  height: "7px",
3292
3572
  borderRadius: "50%",
3293
3573
  background: color
3294
- } }), `AGY (${accounts.length})`);
3574
+ } }), buttonLabel);
3295
3575
  return h("div", { style: { display: "inline-block" } }, badge, portalToBody(h(AgyModalDialog, null)));
3296
3576
  };
3297
3577
  ctx.slots.inject("conversation.session.header.actions", () => {
@@ -3314,6 +3594,7 @@ body.dark,
3314
3594
  });
3315
3595
  installAgyToolView(ctx);
3316
3596
  installAutoExpandReasoning();
3597
+ installMermaidRendering();
3317
3598
  }
3318
3599
  //#endregion
3319
3600
  exports.apply = apply;