This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
================================================================================
|
||||
|
||||
【已完成】
|
||||
- V10.579 補 PChome 高信心 total-price safe family:SAB 私密防護舒緩噴霧 30ml 與 Herbacin 小甘菊 20ml 護手霜在同款式、同規格、無 variant/commercial gap 時可由 focused matcher 進 `exact / total_price / price_alert_exact`,讓近門檻重評能真正寫入正式比價;Herbacin 柔皙 vs 野生玫瑰等跨 variant 仍保留在 review,不放寬全域門檻。同版將 Code Review GCP-B secondary timeout 預設由 60 秒收斂到 25 秒,GCP-A preflight 不通且 GCP-B 生成卡住時更快回 deterministic local degraded,不呼叫 Gemini/111。
|
||||
- V10.578 修正 Code Review 靜態掃描 timeout 誤報:Hermes deterministic scan 對 `requests.get/post/...` 會檢查同一呼叫 block 的後續行,多行呼叫已帶 `timeout=` 時不再報「HTTP request 未設定 timeout」。避免 V10.577 的 preflight helper 因多行格式被自己誤判為 MEDIUM。
|
||||
- V10.577 補 Code Review Ollama host preflight:OpenClaw 架構評估在 explicit GCP host generate 前先以短 `/api/version` 探測健康度,GCP-A 不通時會快速跳 GCP-B,不再等 15 秒 generate timeout;仍維持 GCP-A/GCP-B 優先、111 預設禁用、Gemini hard-disabled 預設不呼叫。
|
||||
- V10.576 補 PChome backfill backlog 的型錄 lane counts,讓 `/api/ai/pchome-match/backfill/status` 也能回傳 `catalog_variant_review`、`catalog_unit_review`、`catalog_identity_review` 三條操作隊列;同版修正 `OllamaService.generate(allow_111_fallback=False)`,當 lazy resolver 快取到 111 時會強制改試 GCP-A/GCP-B allowlist,不再直接 `all 0 hosts failed`,且仍不把長分析推給 111。
|
||||
|
||||
@@ -402,7 +402,7 @@ YOUTUBE_API_KEY = os.getenv('YOUTUBE_API_KEY', '')
|
||||
# ==========================================
|
||||
# 系統版本與路徑
|
||||
# ==========================================
|
||||
SYSTEM_VERSION = "V10.578"
|
||||
SYSTEM_VERSION = "V10.579"
|
||||
LOG_FILE_PATH = os.path.join(BASE_DIR, 'logs/system.log')
|
||||
public_url = PUBLIC_URL # 用於模板顯示
|
||||
|
||||
|
||||
@@ -104,6 +104,7 @@
|
||||
- 2026-05-31 起,`V10.506` 新增市場情報 MCP Fetch Candidate Queue Writer Review Decision Approval gate:在 review decision 通過後只審核 operator human approval 摘要,要求 decision linkage、approval identity、target table、row count、dedupe keys、`approved_for_writer_preflight` approval result、decision/approval evidence refs、artifact paths、matched row exact-identity/variant/overwrite guard 與 operator confirmation 對齊;仍不讀 token、不執行 CLI、不開 DB、不寫 approval record、不寫 decision record、不更新 review_state、不寫 match result、不補 queue、不掛 scheduler,只放行到後續 writer preflight 設計。
|
||||
- 2026-05-31 起,`V10.509` 新增市場情報 MCP Fetch Candidate Queue Writer Review Decision Approval Writer Preflight gate:在 human approval 通過後只審核 operator writer preflight 摘要,要求 approval linkage、writer_preflight_id、target operation、row count、dedupe keys、approved decision 到 target review_state 的逐列映射、decision/approval/preflight evidence refs、matched row exact-identity/variant/overwrite guard 與 operator boundary;仍不讀 token、不執行 CLI、不開 DB、不寫 preflight/approval/decision/match、不更新 review_state、不補 queue、不掛 scheduler,只放行到後續 CLI review / run package 設計。
|
||||
- 2026-06-01 起,`V10.566` 新增市場情報 Professional Source Governance gate:將 robots/REP、sitemap/lastmod、JSON-LD / schema.org structured data、canonical URL、rate limit、公開資料邊界、provenance、snapshot hash 與 idempotency key 納入 source contract,並接上 `/api/market_intel/mcp_professional_source_governance`、UI preview panel、deployment readiness check 與 production smoke target;仍不抓外站、不讀 robots/sitemap、不開 DB、不寫檔、不掛 scheduler。
|
||||
- 2026-06-04 起,`V10.579` 補 PChome 高信心 total-price safe family:SAB 私密防護舒緩噴霧 30ml、Herbacin 小甘菊 20ml 護手霜在同款式同規格且無 variant/commercial gap 時可進 `exact / total_price / price_alert_exact`;跨款式反測仍擋在 review,`MIN_MATCH_SCORE` 不變。同版將 Code Review GCP-B secondary timeout 收斂到 25 秒,GCP-A/GCP-B 都慢時更快回 local degraded。
|
||||
- 2026-06-04 起,`V10.578` 修正 Code Review deterministic scan 的 timeout 判定,多行 `requests.*(... timeout=...)` 不再被誤報為未設定 timeout。
|
||||
- 2026-06-04 起,`V10.577` Code Review OpenClaw 會在 explicit Ollama host generate 前先做短 `/api/version` preflight;GCP-A 不通時快速跳 GCP-B,避免 15 秒 timeout 後才降級,且仍不呼叫 Gemini / 111。
|
||||
- 2026-06-04 起,`V10.576` 修正 GCP-only Ollama retry:caller 禁用 111 fallback 時,resolver 若回到 111 會改試 GCP-A/GCP-B allowlist,不再讓 Hermes / Code Review 類任務因 resolver 快取到 111 而 `all 0 hosts failed`。
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
## 📅 詳細更新日誌 (考古存檔)
|
||||
|
||||
### 2026-06-01:PChome 比價新鮮度操作閉環
|
||||
- **V10.579 PChome 高信心 total-price safe family + Code Review timeout 收斂**: matcher 新增 SAB 私密防護舒緩噴霧 30ml 與 Herbacin 小甘菊 20ml 護手霜的窄範圍 total-price safe 路徑。這些候選仍必須通過既有 score、hard veto、variant/commercial gap 與 overwrite protection;Herbacin 柔皙 vs 野生玫瑰跨 variant 反測維持不進正式價差。目的在不放寬 `MIN_MATCH_SCORE` 的前提下,把可證明同款的高信心 `true_low_confidence` 轉進正式比價覆蓋。同版將 Code Review GCP-B secondary timeout 預設由 60 秒收斂到 25 秒,GCP-A preflight 不通且 GCP-B 生成卡住時更快回 deterministic local degraded,不呼叫 Gemini/111。
|
||||
- **V10.578 Code Review 靜態掃描 timeout 誤報修正**: Hermes deterministic scan 對 `requests.get/post/put/delete/patch` 改檢查同一呼叫 block 的後續行,已在多行呼叫中帶 `timeout=` 時不再報「HTTP request 未設定 timeout」。這修掉 V10.577 preflight helper 被 Code Review 自己誤判為 MEDIUM 的噪音。
|
||||
- **V10.577 Code Review Ollama host preflight**: OpenClaw 架構評估在 explicit GCP host generate 前先以短 `/api/version` 探測健康度;若 GCP-A 從 188 連線 timeout,會快速跳到 GCP-B `gemma3:4b`,避免每次等 primary generate timeout。此 preflight 只作用於 Code Review Ollama-first 路徑,仍維持 111 預設禁用、Gemini hard-disabled 預設不呼叫。
|
||||
- **V10.576 PChome backlog lane 與 GCP-only Ollama retry 修補**: `/api/ai/pchome-match/backfill/status` 的 coverage 與 operation backlog 同步輸出 `catalog_variant_review`、`catalog_unit_review`、`catalog_identity_review`,讓 Dashboard 操作建議可直接跳到三條人工隊列。同版修正 `OllamaService.generate(allow_111_fallback=False)`:若 resolver 已快取到 111,會改試尚未嘗試的 GCP-A/GCP-B allowlist,不再直接 `all 0 hosts failed`,同時仍避免長分析落到 111。
|
||||
|
||||
@@ -66,7 +66,7 @@ CODE_REVIEW_OLLAMA_SECONDARY_MODEL = os.getenv(
|
||||
"gemma3:4b",
|
||||
)
|
||||
CODE_REVIEW_OLLAMA_SECONDARY_TIMEOUT = int(
|
||||
os.getenv("CODE_REVIEW_OLLAMA_SECONDARY_TIMEOUT", "60")
|
||||
os.getenv("CODE_REVIEW_OLLAMA_SECONDARY_TIMEOUT", "25")
|
||||
)
|
||||
CODE_REVIEW_OLLAMA_FALLBACK_MODEL = os.getenv(
|
||||
"CODE_REVIEW_OLLAMA_FALLBACK_MODEL",
|
||||
|
||||
@@ -535,12 +535,18 @@ FOCUSED_IDENTITY_BRANDLESS_REVIEW_REASONS = {
|
||||
"the_forest_maple_diffuser_flower_brandless",
|
||||
}
|
||||
|
||||
FOCUSED_IDENTITY_BRANDLESS_TOTAL_PRICE_REASONS = {
|
||||
"herbacin_classic_hand_cream_20ml_brandless",
|
||||
}
|
||||
|
||||
FOCUSED_IDENTITY_TOTAL_PRICE_REASONS = {
|
||||
"3w_clinic_collagen_foundation_50ml_2pack",
|
||||
"hanamisui_moisture_original_gel_1_7g_3pack",
|
||||
"hanamisui_inclear_private_gel_1_7g_3pack",
|
||||
"hanamisui_relax_lavender_gel_1_7g_3pack",
|
||||
"the_ordinary_caffeine_egcg_30ml",
|
||||
"herbacin_classic_hand_cream_20ml_brandless",
|
||||
"sab_private_spray",
|
||||
"st_clare_private_mousse_150ml_2pack",
|
||||
"st_clare_private_mousse_spray_set",
|
||||
"biopeutic_plus_aha_lotion_20_150ml",
|
||||
@@ -2239,7 +2245,6 @@ def _classify_match_quality(
|
||||
)
|
||||
or (
|
||||
focused_total_price_safe
|
||||
and brand_score >= 0.95
|
||||
and type_score >= 0.55
|
||||
and score >= 0.86
|
||||
)
|
||||
@@ -2582,9 +2587,20 @@ def score_marketplace_match(
|
||||
)
|
||||
)
|
||||
)
|
||||
focused_total_price_brand_safe = (
|
||||
brand_score >= 0.95
|
||||
or (
|
||||
focused_exact_line_reason in FOCUSED_IDENTITY_BRANDLESS_TOTAL_PRICE_REASONS
|
||||
and brand_score == 0.55
|
||||
and bool(left.brand_tokens) != bool(right.brand_tokens)
|
||||
and spec_score >= 0.85
|
||||
and token_score >= 0.70
|
||||
and sequence_score >= 0.55
|
||||
)
|
||||
)
|
||||
focused_exact_total_price_safe = (
|
||||
focused_exact_line_reason in FOCUSED_IDENTITY_TOTAL_PRICE_REASONS
|
||||
and brand_score >= 0.95
|
||||
and focused_total_price_brand_safe
|
||||
and not hard_veto
|
||||
and spec_score >= 0.45
|
||||
and token_score >= 0.30
|
||||
|
||||
@@ -226,7 +226,7 @@ def test_code_review_ollama_defaults_use_fast_local_model(monkeypatch):
|
||||
assert svc_mod.CODE_REVIEW_OLLAMA_MODEL == "qwen2.5-coder:7b"
|
||||
assert svc_mod.CODE_REVIEW_OLLAMA_TIMEOUT == 15
|
||||
assert svc_mod.CODE_REVIEW_OLLAMA_SECONDARY_MODEL == "gemma3:4b"
|
||||
assert svc_mod.CODE_REVIEW_OLLAMA_SECONDARY_TIMEOUT == 60
|
||||
assert svc_mod.CODE_REVIEW_OLLAMA_SECONDARY_TIMEOUT == 25
|
||||
assert svc_mod.CODE_REVIEW_OLLAMA_FALLBACK_MODEL == "hermes3:latest"
|
||||
assert svc_mod.CODE_REVIEW_OLLAMA_FALLBACK_TIMEOUT == 20
|
||||
assert svc_mod.CODE_REVIEW_OLLAMA_NUM_PREDICT == 384
|
||||
@@ -305,7 +305,7 @@ def test_openclaw_uses_secondary_local_model_before_gemini(monkeypatch):
|
||||
assert result == "SECONDARY-LOCAL"
|
||||
assert [call["model"] for call in calls] == ["qwen2.5-coder:7b", "gemma3:4b"]
|
||||
assert calls[0]["timeout"] == 15
|
||||
assert calls[1]["timeout"] == 60
|
||||
assert calls[1]["timeout"] == 25
|
||||
fake_claude.generate.assert_not_called()
|
||||
fake_genai.GenerativeModel.assert_not_called()
|
||||
fake_elephant.generate.assert_not_called()
|
||||
@@ -366,7 +366,7 @@ def test_openclaw_preflight_skips_dead_primary_before_generate(monkeypatch):
|
||||
assert calls == [{
|
||||
"host": ollama_mod.OLLAMA_HOST_SECONDARY,
|
||||
"model": "gemma3:4b",
|
||||
"timeout": 60,
|
||||
"timeout": 25,
|
||||
}]
|
||||
fake_claude.generate.assert_not_called()
|
||||
fake_genai.GenerativeModel.assert_not_called()
|
||||
|
||||
@@ -1946,6 +1946,7 @@ def test_marketplace_matcher_promotes_focused_low_score_exact_identity_lines():
|
||||
assert diagnostics.hard_veto is False
|
||||
assert expected_reason in diagnostics.reasons
|
||||
if expected_reason in {
|
||||
"focused_exact_identity_sab_private_spray",
|
||||
"focused_exact_identity_herb24_mist_diffuser_black",
|
||||
"focused_exact_identity_pavaruni_40_scent_oil",
|
||||
"focused_exact_identity_pavaruni_20_scent_candle",
|
||||
@@ -1956,6 +1957,44 @@ def test_marketplace_matcher_promotes_focused_low_score_exact_identity_lines():
|
||||
assert diagnostics.alert_tier == "price_alert_exact"
|
||||
|
||||
|
||||
def test_marketplace_matcher_promotes_precise_brandless_herbacin_hand_cream_to_total_price():
|
||||
from services.marketplace_product_matcher import score_marketplace_match
|
||||
|
||||
cases = [
|
||||
(
|
||||
"【Herbacin 德國小甘菊】小甘菊柔皙護手霜20ml",
|
||||
"小甘菊柔皙護手霜 20ml",
|
||||
),
|
||||
(
|
||||
"【Herbacin 德國小甘菊】小甘菊野生玫瑰護手霜20ml 條狀",
|
||||
"小甘菊野生玫瑰護手霜20ml",
|
||||
),
|
||||
]
|
||||
|
||||
for momo_name, competitor_name in cases:
|
||||
diagnostics = score_marketplace_match(momo_name, competitor_name)
|
||||
assert diagnostics.score >= 0.76
|
||||
assert diagnostics.hard_veto is False
|
||||
assert diagnostics.match_type == "exact"
|
||||
assert diagnostics.price_basis == "total_price"
|
||||
assert diagnostics.alert_tier == "price_alert_exact"
|
||||
assert "focused_exact_total_price_safe" in diagnostics.reasons
|
||||
assert "focused_exact_identity_herbacin_classic_hand_cream_20ml_brandless" in diagnostics.reasons
|
||||
|
||||
|
||||
def test_marketplace_matcher_keeps_herbacin_cross_variant_out_of_total_price():
|
||||
from services.marketplace_product_matcher import score_marketplace_match
|
||||
|
||||
diagnostics = score_marketplace_match(
|
||||
"【Herbacin 德國小甘菊】小甘菊柔皙護手霜20ml",
|
||||
"小甘菊野生玫瑰護手霜20ml",
|
||||
)
|
||||
|
||||
assert diagnostics.price_basis != "total_price"
|
||||
assert diagnostics.alert_tier != "price_alert_exact"
|
||||
assert "focused_exact_total_price_safe" not in diagnostics.reasons
|
||||
|
||||
|
||||
def test_marketplace_matcher_keeps_high_variant_low_score_lines_outside_focused_promotion():
|
||||
from services.marketplace_product_matcher import score_marketplace_match
|
||||
|
||||
|
||||
Reference in New Issue
Block a user