From fa484893b9557cc985b0d21d8c27f3524bb6e3ab Mon Sep 17 00:00:00 2001 From: ogt Date: Thu, 25 Jun 2026 19:25:22 +0800 Subject: [PATCH] fix: hide runtime terms on governance pages --- config.py | 2 +- docs/AI_INTELLIGENCE_MODULE_SOT.md | 1 + routes/admin_observability_routes.py | 6 +++--- templates/admin/_observability_labels.html | 8 ++++---- templates/admin/agent_orchestration.html | 6 +++--- templates/admin/ai_calls_dashboard.html | 6 +++--- templates/admin/budget.html | 2 +- templates/admin/host_health.html | 12 ++++++------ templates/ai_history.html | 2 +- templates/vendor_stockout_import_v2.html | 8 ++++---- templates/vendor_stockout_vendor_management_v2.html | 6 +++--- tests/test_admin_observability_routes.py | 6 +++--- tests/test_pchome_revenue_growth_service.py | 2 +- web/static/js/observability-charts.js | 8 ++++---- 14 files changed, 38 insertions(+), 37 deletions(-) diff --git a/config.py b/config.py index ff56b16..0fb27ea 100644 --- a/config.py +++ b/config.py @@ -402,7 +402,7 @@ YOUTUBE_API_KEY = os.getenv('YOUTUBE_API_KEY', '') # ========================================== # 系統版本與路徑 # ========================================== -SYSTEM_VERSION = "V10.697" +SYSTEM_VERSION = "V10.698" LOG_FILE_PATH = os.path.join(BASE_DIR, 'logs/system.log') public_url = PUBLIC_URL # 用於模板顯示 diff --git a/docs/AI_INTELLIGENCE_MODULE_SOT.md b/docs/AI_INTELLIGENCE_MODULE_SOT.md index 354b181..fb68177 100644 --- a/docs/AI_INTELLIGENCE_MODULE_SOT.md +++ b/docs/AI_INTELLIGENCE_MODULE_SOT.md @@ -774,3 +774,4 @@ POSTGRES_HOST=momo-db | 2026-06-25 | 匯入任務列表只顯示處置提醒 | V10.695 起 `/auto_import` 任務列表不再把 `error_message` 原文當主要欄位顯示,而是由 `buildImportActionHint()` 轉成 Google Drive 授權、當日業績明細檔、重新匯入或通知維護人員等下一步,避免重啟後瀏覽器/授權/同步技術錯誤直接暴露給營運使用者。 | | 2026-06-25 | 系統設定匯入提示不得顯示資料表或日誌口徑 | V10.696 起 `/system_settings` 不再用 `realtime_sales_monthly` 判斷前端提示,也不再顯示「資料落點、檢查日誌、發生系統錯誤」等內部口徑;所有匯入與備份失敗提示統一走 `toImportActionMessage()`,轉成重新授權、改用正確業績報表、重新匯入或通知維護人員。 | | 2026-06-25 | 分析與建議頁必須使用 PChome 作戰流程語言 | V10.697 起 `/sales_analysis`、`/monthly_summary_analysis`、`/ai_recommend` 頁首與主要操作區統一使用「主推、守價、補比價、成長缺口、毛利貢獻、品類結構」等營運語言;前台不得把 AI 模型、權杖、資料庫、欄位、英文指標縮寫或內部錯誤作為使用者主訊息。 | +| 2026-06-25 | 治理與匯入頁也不得外露模型/權杖/欄位口徑 | V10.698 起缺貨匯入、供應商窗口、AI 歷史、預算、AI 流量、AI 分工與主機健康頁統一改用「必要資料、用量、建議引擎、建議路徑、雲端備援、AI 建議服務」等前台可讀詞,避免使用者在營運頁看到 raw model、token、欄位或模型品牌。 | diff --git a/routes/admin_observability_routes.py b/routes/admin_observability_routes.py index 4c13752..aa380c4 100644 --- a/routes/admin_observability_routes.py +++ b/routes/admin_observability_routes.py @@ -61,7 +61,7 @@ _PPT_INTERNAL_ERROR_MARKERS = ( _PPT_PUBLIC_REPLACEMENTS = ( ('AiderHeal', '修復流程'), ('RAG', '知識建議'), - ('Ollama', 'AI 模型服務'), + ('Ollama', 'AI 建議服務'), ('minicpm-v', '視覺模型'), ('LibreOffice', '轉檔服務'), ('runtime', '執行條件'), @@ -198,10 +198,10 @@ def _build_ai_call_recent_row(row): if provider == 'gemini': if caller in _GEMINI_BACKUP_CALLER_DISPLAY: caller_display = _GEMINI_BACKUP_CALLER_DISPLAY[caller] - route_badges.append('Gemini 備援') + route_badges.append('雲端備援') route_badges.append('舊 caller') elif caller in _GEMINI_BACKUP_CALLERS or caller.endswith('_gemini'): - route_badges.append('Gemini 備援') + route_badges.append('雲端備援') else: route_badges.append('ADR-028 鎖定/升級') diff --git a/templates/admin/_observability_labels.html b/templates/admin/_observability_labels.html index 059f952..58f5da0 100644 --- a/templates/admin/_observability_labels.html +++ b/templates/admin/_observability_labels.html @@ -116,11 +116,11 @@ {% macro provider(value, fallback='未分類供應商') -%} {%- set labels = { - 'gcp_ollama': '主力 AI 模型', - 'ollama_secondary': '備援 AI 模型', - 'ollama_111': '第三 AI 模型', + 'gcp_ollama': '主力建議路徑', + 'ollama_secondary': '備援建議路徑', + 'ollama_111': '第三建議路徑', 'nim_via_elephant': 'NIM Elephant', - 'gemini': 'Gemini', + 'gemini': '雲端備援', 'claude': 'Claude', 'nim': 'NIM', 'openrouter': 'OpenRouter', diff --git a/templates/admin/agent_orchestration.html b/templates/admin/agent_orchestration.html index a13bf6c..e400fd6 100644 --- a/templates/admin/agent_orchestration.html +++ b/templates/admin/agent_orchestration.html @@ -9,15 +9,15 @@
-
AI 分工指揮台 · {{ hours }} 小時視窗

AI 分工指揮台

確認 AI 分工、本地模型、知識命中與工具編排是否支撐業績決策。

{% if overall %}
呼叫總量
{{ "{:,}".format(overall.total_calls) }}{{ "{:,}".format(overall.total_tokens) }} 用量
本地模型占比
{{ "%.0f"|format(overall.local_pct) }}%{{ "{:,}".format(overall.local_calls) }} 次本地呼叫
付費成本
${{ "%.2f"|format(overall.total_cost) }}{{ "{:,}".format(overall.paid_calls) }} 次付費呼叫
知識命中率
{{ "%.0f"|format(overall.rag_rate) }}%{{ "{:,}".format(overall.rag_hits) }} 次命中
{% endif %}
+
AI 分工指揮台 · {{ hours }} 小時視窗

AI 分工指揮台

確認 AI 分工、建議路徑、知識命中與工具編排是否支撐業績決策。

{% if overall %}
呼叫總量
{{ "{:,}".format(overall.total_calls) }}{{ "{:,}".format(overall.total_tokens) }} 用量
主力路徑占比
{{ "%.0f"|format(overall.local_pct) }}%{{ "{:,}".format(overall.local_calls) }} 次主力呼叫
付費成本
${{ "%.2f"|format(overall.total_cost) }}{{ "{:,}".format(overall.paid_calls) }} 次付費呼叫
知識命中率
{{ "%.0f"|format(overall.rag_rate) }}%{{ "{:,}".format(overall.rag_hits) }} 次命中
{% endif %}
{% if error %}
{{ error }}
{% endif %}
-
AI 分工矩陣

模型、工具與知識命中矩陣

{% for ag in agent_matrix %}{% endfor %}
分工呼叫成本本地模型付費工具知識錯誤耗時
{{ ag.label }}{{ ag.desc }}{% if ag.calls > 0 %}{{ "{:,}".format(ag.calls) }}{{ "{:,}".format(ag.tokens) }} 用量{% else %}{% endif %}{% if ag.calls > 0 %}${{ "%.2f"|format(ag.cost) }}{% else %}{% endif %}{% if ag.calls > 0 %}{{ "%.0f"|format(ag.ollama_pct) }}%主力 {{ ag.ollama_gcp_a }} · 備援 {{ ag.ollama_gcp_b }} · 第三 {{ ag.ollama_111 }}{% else %}{% endif %}{% if ag.calls > 0 %}{{ "%.0f"|format(ag.paid_pct) }}%Gemini {{ ag.gemini }}{% if ag.other_paid %} · 其他 {{ ag.other_paid }}{% endif %}{% else %}{% endif %}{% if ag.calls > 0 %}{{ "%.1f"|format(ag.mcp_rate) }}%{{ ag.mcp_calls }}{% else %}{% endif %}{% if ag.calls > 0 %}{{ "%.1f"|format(ag.rag_rate) }}%{{ ag.rag_hits }}{% else %}{% endif %}{% if ag.calls > 0 %}{{ "%.1f"|format(ag.error_rate) }}%{{ ag.errors }}{% else %}{% endif %}{% if ag.calls > 0 %}{{ ag.avg_ms }} ms{% else %}{% endif %}
+
AI 分工矩陣

建議路徑、工具與知識命中矩陣

{% for ag in agent_matrix %}{% endfor %}
分工呼叫成本主力路徑付費工具知識錯誤耗時
{{ ag.label }}{{ ag.desc }}{% if ag.calls > 0 %}{{ "{:,}".format(ag.calls) }}{{ "{:,}".format(ag.tokens) }} 用量{% else %}{% endif %}{% if ag.calls > 0 %}${{ "%.2f"|format(ag.cost) }}{% else %}{% endif %}{% if ag.calls > 0 %}{{ "%.0f"|format(ag.ollama_pct) }}%主力 {{ ag.ollama_gcp_a }} · 備援 {{ ag.ollama_gcp_b }} · 第三 {{ ag.ollama_111 }}{% else %}{% endif %}{% if ag.calls > 0 %}{{ "%.0f"|format(ag.paid_pct) }}%雲端備援 {{ ag.gemini }}{% if ag.other_paid %} · 其他 {{ ag.other_paid }}{% endif %}{% else %}{% endif %}{% if ag.calls > 0 %}{{ "%.1f"|format(ag.mcp_rate) }}%{{ ag.mcp_calls }}{% else %}{% endif %}{% if ag.calls > 0 %}{{ "%.1f"|format(ag.rag_rate) }}%{{ ag.rag_hits }}{% else %}{% endif %}{% if ag.calls > 0 %}{{ "%.1f"|format(ag.error_rate) }}%{{ ag.errors }}{% else %}{% endif %}{% if ag.calls > 0 %}{{ ag.avg_ms }} ms{% else %}{% endif %}
diff --git a/templates/admin/ai_calls_dashboard.html b/templates/admin/ai_calls_dashboard.html index 2f78338..1fd018b 100644 --- a/templates/admin/ai_calls_dashboard.html +++ b/templates/admin/ai_calls_dashboard.html @@ -118,14 +118,14 @@ {% if by_model %}
-
模型成本

依模型細分

-
{% for m in by_model %}{% endfor %}
模型供應商呼叫用量成本耗時錯誤
{{ m.model[:35] }}{{ obs_label.provider(m.provider) }}{{ "{:,}".format(m.calls) }}{{ "{:,}".format(m.tokens) }}${{ "%.4f"|format(m.cost) }}{{ m.avg_ms }} ms{% if m.errors > 0 %}{{ m.errors }}{% else %}0{% endif %}
+
路徑成本

依建議路徑細分

+
{% for m in by_model %}{% endfor %}
建議路徑供應商呼叫用量成本耗時錯誤
{{ obs_label.provider(m.provider) }}{{ obs_label.provider(m.provider) }}{{ "{:,}".format(m.calls) }}{{ "{:,}".format(m.tokens) }}${{ "%.4f"|format(m.cost) }}{{ m.avg_ms }} ms{% if m.errors > 0 %}{{ m.errors }}{% else %}0{% endif %}
{% endif %}
最近呼叫

最近呼叫 100 筆

-
{% for r in recent %}{% endfor %}
編號時間呼叫端供應商模型輸入輸出耗時狀態成本標記
{{ r.id }}{{ r.called_at }}{{ r.caller_display or r.caller }}{% if r.caller_display and r.caller_display != r.caller %}
原始:{{ r.caller }}{% endif %}
{{ obs_label.provider(r.provider) }}{{ r.model[:25] }}{{ r.in_tokens }}{{ r.out_tokens }}{{ r.duration_ms }}{{ obs_label.status(r.status, '-') }}${{ "%.4f"|format(r.cost) }}{% for badge in r.route_badges %}{{ badge }}{% endfor %}{% if r.cache_hit %}快取{% endif %}{% if r.rag_hit %}知識命中{% endif %}
+
{% for r in recent %}{% endfor %}
編號時間呼叫端供應商建議路徑輸入輸出耗時狀態成本標記
{{ r.id }}{{ r.called_at }}{{ r.caller_display or r.caller }}{% if r.caller_display and r.caller_display != r.caller %}
原始:{{ r.caller }}{% endif %}
{{ obs_label.provider(r.provider) }}{{ obs_label.provider(r.provider) }}{{ r.in_tokens }}{{ r.out_tokens }}{{ r.duration_ms }}{{ obs_label.status(r.status, '-') }}${{ "%.4f"|format(r.cost) }}{% for badge in r.route_badges %}{{ badge }}{% endfor %}{% if r.cache_hit %}快取{% endif %}{% if r.rag_hit %}知識命中{% endif %}

AI 流量控制塔

diff --git a/templates/admin/budget.html b/templates/admin/budget.html index 7ef70ae..3b47bc9 100644 --- a/templates/admin/budget.html +++ b/templates/admin/budget.html @@ -70,7 +70,7 @@ {% endif %} {% if top_cost_callers %} -
燃燒率

Top 5 燒錢呼叫端

{% set max_cost = (top_cost_callers | map(attribute='cost') | max) or 1 %}{% for c in top_cost_callers %}
{{ c.caller }}${{ "%.2f"|format(c.cost) }}
{{ "{:,}".format(c.calls) }} 次呼叫 · {{ "{:,}".format(c.tokens) }} 權杖
{% endfor %}
+
燃燒率

Top 5 燒錢呼叫端

{% set max_cost = (top_cost_callers | map(attribute='cost') | max) or 1 %}{% for c in top_cost_callers %}
{{ c.caller }}${{ "%.2f"|format(c.cost) }}
{{ "{:,}".format(c.calls) }} 次呼叫 · {{ "{:,}".format(c.tokens) }} 用量
{% endfor %}
{% endif %} diff --git a/templates/admin/host_health.html b/templates/admin/host_health.html index 4a489b1..56b793e 100644 --- a/templates/admin/host_health.html +++ b/templates/admin/host_health.html @@ -59,11 +59,11 @@
-
基礎設施生命線 · AI 模型 / 工具服務 / 自癒
+
基礎設施生命線 · AI 建議服務 / 工具服務 / 自癒

基礎設施生命線

-

先看 AI 模型、工具服務與自癒是否正常,避免 AI 建議與比價流程中斷。

+

先看 AI 建議服務、工具服務與自癒是否正常,避免 AI 建議與比價流程中斷。

-
AI 模型離線
{{ down.count }}{{ ollama_hosts|length }} 台即時探測
+
建議服務離線
{{ down.count }}{{ ollama_hosts|length }} 台即時探測
AIOps 未解
{{ aiops_summary.incidents_open if aiops_summary else '—' }}7 日事件未解決
自癒成功率
{{ "%.0f"|format(aiops_summary.heal_success_rate) if aiops_summary else '—' }}{% if aiops_summary %}%{% endif %}近 7 日自癒成功率
節流供應商
{{ throttled.count }}成本節流供應商
@@ -74,7 +74,7 @@
-
模型服務

AI 模型主機

+
建議服務

AI 建議服務主機

{{ '需要處理' if down.count > 0 else '全部在線' }}
@@ -157,11 +157,11 @@
-
事件紀錄

最近 10 筆事件

{% if recent_incidents %}{% set task_labels = {'ElephantAlphaAutonomousEngine': 'AI 自癒監控', 'run_icaim_analysis_task': '市場分析任務'} %}{% set error_labels = {'ollama_unhealthy': 'AI 模型主機不穩', 'scheduler_task_failure': '排程任務異常', 'crawler_timeout': '資料擷取逾時', 'python_exception': '程式例外'} %}{% for i in recent_incidents %}{% endfor %}
時間任務問題等級狀態處置提醒
{{ i.created_at }}{{ task_labels.get(i.task_name, '系統任務') }}{{ error_labels.get(i.error_type, '系統異常') }}{{ i.severity }}{{ i.status }}{% if i.error_type == 'ollama_unhealthy' %}AI 模型主機暫時不穩,已進入自癒監控。{% elif i.error_type == 'python_exception' %}資料流程發生程式例外,需由修復流程處理。{% elif i.error_type == 'scheduler_task_failure' %}排程任務異常,需確認下次執行是否恢復。{% else %}系統事件已記錄,請依狀態追蹤後續是否恢復。{% endif %}
{% else %}
尚無事件紀錄
{% endif %}
+
事件紀錄

最近 10 筆事件

{% if recent_incidents %}{% set task_labels = {'ElephantAlphaAutonomousEngine': 'AI 自癒監控', 'run_icaim_analysis_task': '市場分析任務'} %}{% set error_labels = {'ollama_unhealthy': 'AI 建議服務不穩', 'scheduler_task_failure': '排程任務異常', 'crawler_timeout': '資料擷取逾時', 'python_exception': '程式例外'} %}{% for i in recent_incidents %}{% endfor %}
時間任務問題等級狀態處置提醒
{{ i.created_at }}{{ task_labels.get(i.task_name, '系統任務') }}{{ error_labels.get(i.error_type, '系統異常') }}{{ i.severity }}{{ i.status }}{% if i.error_type == 'ollama_unhealthy' %}AI 建議服務暫時不穩,已進入自癒監控。{% elif i.error_type == 'python_exception' %}資料流程發生程式例外,需由修復流程處理。{% elif i.error_type == 'scheduler_task_failure' %}排程任務異常,需確認下次執行是否恢復。{% else %}系統事件已記錄,請依狀態追蹤後續是否恢復。{% endif %}
{% else %}
尚無事件紀錄
{% endif %}
自癒紀錄

最近 10 筆自癒

{% if recent_heals %}{% for h in recent_heals %}{% endfor %}
時間動作結果耗時細節
{{ h.created_at }}{{ h.action_type or '—' }}{% if h.result == 'success' %}成功{% elif h.result == 'failed' %}失敗{% else %}{{ h.result }}{% endif %}{{ h.duration_ms }} ms{{ h.action_detail }}
{% else %}
尚無自癒紀錄
{% endif %}
diff --git a/templates/ai_history.html b/templates/ai_history.html index 254db7a..7c7b7ca 100644 --- a/templates/ai_history.html +++ b/templates/ai_history.html @@ -564,7 +564,7 @@ function renderHistory(items) {
- ${item.model_name || '-'} + 建議引擎 ${item.generation_duration ? `${item.generation_duration}秒` : ''} ${item.input_style ? `${item.input_style}` : ''}
diff --git a/templates/vendor_stockout_import_v2.html b/templates/vendor_stockout_import_v2.html index 3fe2d73..f1fa07e 100644 --- a/templates/vendor_stockout_import_v2.html +++ b/templates/vendor_stockout_import_v2.html @@ -54,13 +54,13 @@