You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tooling.apache.org by gs...@apache.org on 2026/08/11 20:28:03 UTC
(tooling-llmao) 02/02: Fix Models detail modal empty fields from multiline notes.
This is an automated email from the ASF dual-hosted git repository.
gstein pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tooling-llmao.git
commit 59d4b08296dc4c8705827a66925041bac669df74
Author: Greg Stein <gs...@gmail.com>
AuthorDate: Tue Aug 11 15:27:56 2026 -0500
Fix Models detail modal empty fields from multiline notes.
Collapse free-text to one line for HTML data-* attributes so EZT/HTML
escaping can keep attributes intact. Simplify hosting_label to use the
redacted row; harden boolean data-attribute checks in JS.
Co-authored-by: Grok <gr...@x.ai>
---
llmao/models.py | 42 +++++++++++++++++++++++++-----------------
static/js/llmao.js | 12 ++++++------
tests/test_models.py | 3 +++
3 files changed, 34 insertions(+), 23 deletions(-)
diff --git a/llmao/models.py b/llmao/models.py
index 41272ce..a7c8650 100644
--- a/llmao/models.py
+++ b/llmao/models.py
@@ -59,7 +59,15 @@ _SUPPLY_PATH_KEYS = frozenset({
})
+def _oneline(s: Any) -> str:
+ """Collapse whitespace so values stay safe in single-line HTML attributes."""
+ if s is None or s is False:
+ return ""
+ return " ".join(str(s).split())
+
+
def _hosting_label(m: Dict[str, Any]) -> str:
+ """Public hosting class (not partnership detail). Prefer self_hosted flag."""
if m.get("self_hosted") is True:
return "Self-hosted"
if m.get("self_hosted") is False:
@@ -82,40 +90,40 @@ def ux_models(
When ``reveal_supply`` is False (normal committers), omit fields that
describe procurement, weight paths, or commercial partnerships.
+
+ Free-text is collapsed to one line for HTML data-* attributes (EZT
+ HTML-escapes quotes; embedded newlines still break attributes).
"""
rows = []
for m in public_models(path, cfg=cfg):
if not reveal_supply:
m = {k: v for k, v in m.items() if k not in _SUPPLY_PATH_KEYS}
- name = m.get("model_name") or ""
- display = m.get("display_name") or name
+ name = _oneline(m.get("model_name"))
+ display = _oneline(m.get("display_name")) or name
ctx = m.get("context_window")
rows.append({
"model_name": name,
"display_name": display,
- "hosting_label": _hosting_label(m if reveal_supply else {
- **m,
- "self_hosted": m.get("self_hosted"),
- }),
+ "hosting_label": _hosting_label(m),
"self_hosted": bool(m.get("self_hosted")),
"context_window": ctx if ctx is not None else "—",
- "license": m.get("license") or "—",
- "modality": m.get("modality") or "",
+ "license": _oneline(m.get("license")) or "—",
+ "modality": _oneline(m.get("modality")),
"supports_thinking": bool(m.get("supports_thinking")),
"thinks_by_default": bool(m.get("thinks_by_default")),
- "openness": m.get("openness") or "",
- "notes": m.get("notes") or "",
+ "openness": _oneline(m.get("openness")),
+ "notes": _oneline(m.get("notes")),
"reveal_supply": reveal_supply,
# Admin-only supply fields (empty strings when redacted)
- "provider": (m.get("provider") or "") if reveal_supply else "",
+ "provider": _oneline(m.get("provider")) if reveal_supply else "",
"weights_distribution": (
- m.get("weights_distribution") or ""
- ) if reveal_supply else "",
+ _oneline(m.get("weights_distribution")) if reveal_supply else ""
+ ),
"training_data_provenance": (
- m.get("training_data_provenance") or ""
- ) if reveal_supply else "",
+ _oneline(m.get("training_data_provenance")) if reveal_supply else ""
+ ),
"provenance_record": (
- m.get("provenance_record") or ""
- ) if reveal_supply else "",
+ _oneline(m.get("provenance_record")) if reveal_supply else ""
+ ),
})
return rows
diff --git a/static/js/llmao.js b/static/js/llmao.js
index 5d40345..e468349 100644
--- a/static/js/llmao.js
+++ b/static/js/llmao.js
@@ -33,10 +33,11 @@ document.addEventListener("DOMContentLoaded", function () {
set("mdLicense", btn.getAttribute("data-license"));
set("mdModality", btn.getAttribute("data-modality"));
set("mdOpenness", btn.getAttribute("data-openness"));
- var thinking = btn.getAttribute("data-thinking") === "True" ||
- btn.getAttribute("data-thinking") === "true";
- var thinksDefault = btn.getAttribute("data-thinks-default") === "True" ||
- btn.getAttribute("data-thinks-default") === "true";
+ function truthy(v) {
+ return v === "True" || v === "true" || v === "1" || v === "yes";
+ }
+ var thinking = truthy(btn.getAttribute("data-thinking"));
+ var thinksDefault = truthy(btn.getAttribute("data-thinks-default"));
var thinkText = thinking
? (thinksDefault ? "Supported (on by default)" : "Supported (off by default)")
: "Not advertised";
@@ -44,8 +45,7 @@ document.addEventListener("DOMContentLoaded", function () {
set("mdNotes", btn.getAttribute("data-notes"));
var supply = document.getElementById("mdSupplyBlock");
- var reveal = btn.getAttribute("data-reveal-supply") === "True" ||
- btn.getAttribute("data-reveal-supply") === "true";
+ var reveal = truthy(btn.getAttribute("data-reveal-supply"));
if (supply) {
if (reveal) {
supply.classList.remove("d-none");
diff --git a/tests/test_models.py b/tests/test_models.py
index 261274e..63a86e6 100644
--- a/tests/test_models.py
+++ b/tests/test_models.py
@@ -56,9 +56,12 @@ def test_ux_models_redacts_supply_path_for_non_admins():
assert r["provider"] == ""
assert r["weights_distribution"] == ""
assert r["hosting_label"] in ("Self-hosted", "External", "—")
+ # Free-text flattened for data-* attributes (no raw newlines).
+ assert "\n" not in r["notes"]
for f in full:
# Example inventory includes weights_distribution for self-host models.
assert f.get("weights_distribution") or f.get("provider")
+ assert "\n" not in f["notes"]
def test_litellm_deployment_preserves_model_info_extras():
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@tooling.apache.org
For additional commands, e-mail: commits-help@tooling.apache.org