2026-10-20 TUE UTC 12:42 PM TPE 8:42 PM Auto-updates hourly 中文 EN
LIVE WIRE
← Back to the site changelog Site Changelog

Original commit record

Article footer credits the drafting model with a vendor mark Every article page now ends with an AI-model line: a square monogram in the vendor brand color (NVIDIA / Google / DeepSeek / Qwen / Z.ai / Mistral AI / Anthropic, matching the site square-tag style) plus the short model name, e.g. Nemotron 3 Ultra, derived from the article's writer field. Articles without a writer field simply omit the line. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

SHA
6661e3dd0ccc9af247c1d9f27f795ab260437d87
Commit date
Author
avwire
Committer
avwire

Changed files (3)

  • pipeline/build.py modified · +39 / −0
  • static/site.css modified · +8 / −0
  • templates/article.html modified · +10 / −1

Full diff

@@ -65,6 +65,7 @@\n         "delays": "今日延誤熱點機場", "autoCompiled": "自動彙整",\n         "refreshNote": "本文隨來源每小時更新", "sourcesBox": "資料來源 Sources",\n         "genNote": "本文由自動化系統彙整生成,內容以原始來源為準。",\n+        "aiModel": "AI 撰稿模型",\n         "incKicker": "Incident Database", "incTitle": "事故資料庫",\n         "incSub": "自動彙整全球民航事故與事件,資料來自各國調查機關與專業追報來源,每小時更新。",\n         "incCountLabel": "筆紀錄",\n@@ -116,6 +117,7 @@\n         "delays": "Delay hotspots today", "autoCompiled": "Auto-compiled",\n         "refreshNote": "Refreshes hourly with sources", "sourcesBox": "Sources",\n         "genNote": "This article was compiled automatically; the original sources prevail.",\n+        "aiModel": "Drafted by",\n         "incKicker": "Incident Database", "incTitle": "Incident database",\n         "incSub": "Automatically aggregated civil-aviation accidents and incidents, from state investigators and specialist trackers. Updated hourly.",\n         "incCountLabel": "records",\n@@ -258,6 +260,41 @@ def page_url(lang: str, sub: str) -> str:\n \n # ── data loading / preparation ───────────────────────────────────────────────\n \n+# Article-footer model credit: writer id -> vendor mark + short model name.\n+# The square monogram uses the vendor's brand color (site style is square\n+# tags, radius 0) - official logo artwork can replace it later if licensed.\n+_WRITER_BADGES = (\n+    ("nemotron-3-ultra", "NVIDIA", "N", "#76b900", "Nemotron 3 Ultra"),\n+    ("nemotron-3-super", "NVIDIA", "N", "#76b900", "Nemotron 3 Super"),\n+    ("nemotron", "NVIDIA", "N", "#76b900", "Nemotron"),\n+    ("deepseek-v4-pro", "DeepSeek", "D", "#4d6bfe", "DeepSeek V4 Pro"),\n+    ("deepseek", "DeepSeek", "D", "#4d6bfe", "DeepSeek"),\n+    ("gemini-3.6-flash", "Google", "G", "#4285f4", "Gemini 3.6 Flash"),\n+    ("gemini-3.5-flash", "Google", "G", "#4285f4", "Gemini 3.5 Flash"),\n+    ("gemini", "Google", "G", "#4285f4", "Gemini"),\n+    ("qwen3.5", "Qwen", "Q", "#615ced", "Qwen 3.5"),\n+    ("qwen", "Qwen", "Q", "#615ced", "Qwen"),\n+    ("glm-5.2", "Z.ai", "Z", "#141414", "GLM-5.2"),\n+    ("glm", "Z.ai", "Z", "#141414", "GLM"),\n+    ("mistral-medium-3.5", "Mistral AI", "M", "#fa500f", "Mistral Medium 3.5"),\n+    ("mistral", "Mistral AI", "M", "#fa500f", "Mistral"),\n+    ("claude-opus-5", "Anthropic", "A", "#d97757", "Claude Opus 5"),\n+    ("claude", "Anthropic", "A", "#d97757", "Claude"),\n+)\n+\n+\n+def writer_badge(writer):\n+    """{"vendor", "initial", "color", "model"} for a writer id, or None."""\n+    if not isinstance(writer, str) or ":" not in writer:\n+        return None\n+    model_id = writer.split(":", 1)[1].lower()\n+    for needle, vendor, initial, color, model in _WRITER_BADGES:\n+        if needle in model_id:\n+            return {"vendor": vendor, "initial": initial,\n+                    "color": color, "model": model}\n+    return None\n+\n+\n def prep_article(raw):\n     if not isinstance(raw, dict):\n         return None\n@@ -343,6 +380,7 @@ def side(own, other):\n         "zh": side(zh, en),\n         "en": side(en, zh),\n         "sources": sources,\n+        "writer_badge": writer_badge(raw.get("writer")),\n     }\n \n \n@@ -376,6 +414,7 @@ def art_view(a, lang: str):\n         cat_label=_bi(CATS.get(a["cat"]), lang, a["cat"]),\n         source=a["source"], time=a["time"], meta_ts=a["meta_ts"],\n         sources=a["sources"], url=page_url(lang, f"news/{a['id']}/"),\n+        writer_badge=a["writer_badge"],\n         external=False,\n     )\n     return v\n@@ -112,6 +112,14 @@ a.flash-row:hover { color: inherit; }\n \n .is-hidden { display: none !important; }\n \n+/* — article footer: AI model credit (vendor-colored square monogram) — */\n+.model-mark {\n+  width: 16px; height: 16px; flex-shrink: 0;\n+  display: inline-flex; align-items: center; justify-content: center;\n+  color: #fff; font-weight: 800; font-size: 10px; line-height: 1;\n+  border: 1px solid var(--color-divider);\n+}\n+\n /* — footer — */\n .footer-grid {\n   padding: 24px 20px 32px;\n@@ -23,7 +23,16 @@ <h6 style="margin:0 0 10px;">{{ t.sourcesBox }}</h6>\n         <span class="text-muted" style="font-size:11.5px;">{{ s.host }}</span>\n       </div>\n       {% endfor %}\n-      <div class="text-muted" style="font-size:12px;margin-top:10px;border-top:1px solid var(--color-divider);padding-top:10px;">{{ t.genNote }}</div>\n+      <div class="text-muted" style="font-size:12px;margin-top:10px;border-top:1px solid var(--color-divider);padding-top:10px;display:flex;align-items:center;gap:14px;flex-wrap:wrap;">\n+        <span>{{ t.genNote }}</span>\n+        {% if a.writer_badge %}\n+        <span style="margin-left:auto;display:inline-flex;align-items:center;gap:7px;white-space:nowrap;">\n+          <span>{{ t.aiModel }}</span>\n+          <span class="model-mark" style="background:{{ a.writer_badge.color }};" title="{{ a.writer_badge.vendor }}">{{ a.writer_badge.initial }}</span>\n+          <span style="font-weight:700;color:var(--color-text);">{{ a.writer_badge.model }}</span>\n+        </span>\n+        {% endif %}\n+      </div>\n     </div>\n   </div>\n {% endblock %}

You found a secret theme!

8-bit mode is unlocked. Refresh to add it to your theme selector.