This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
> 本文件定義專案開發的核心準則與不可違反的規範
|
||||
> **建立日期**: 2026-01-12
|
||||
> **當前版本**: V10.50 (Vendor stockout query service extraction)
|
||||
> **當前版本**: V10.51 (Price adjustment actions require human review)
|
||||
> **最後更新**: 2026-05-01
|
||||
|
||||
---
|
||||
|
||||
4
app.py
4
app.py
@@ -95,8 +95,8 @@ except Exception as e:
|
||||
sys_log.error(f"無法檢測磁碟空間: {e}")
|
||||
|
||||
# 🚩 系統版本定義 (備份與顯示用)
|
||||
# 🚩 2026-05-01 V10.50: Vendor stockout query service extraction
|
||||
SYSTEM_VERSION = "V10.50"
|
||||
# 🚩 2026-05-01 V10.51: Price adjustment actions require human review
|
||||
SYSTEM_VERSION = "V10.51"
|
||||
|
||||
# ==========================================
|
||||
# 🔒 SQL Injection 防護函數
|
||||
|
||||
@@ -66,6 +66,7 @@ SQL漏斗(~300筆)
|
||||
- `momo-db` / `momo-postgres` 不可被 AI 自動 restart / stop / recreate。
|
||||
- raw `ai_insights` insert 必須接 `enqueue_insight_embedding()` 或可被 backfill。
|
||||
- ElephantAlpha 只做編排與 bridge,不可繞過 ADR-011 / ADR-012 / ADR-013。
|
||||
- ElephantAlpha / NemoTron 不可直接執行商品價格調整;`execute_price_adjustment`、`adjust_price` 等動作必須攔截並寫入 `human_review`,等待人工核准。
|
||||
|
||||
可觀測性:
|
||||
|
||||
|
||||
@@ -103,10 +103,20 @@ _ACTION_ZH = {
|
||||
"generate_market_analysis": "市場分析",
|
||||
"generate_pricing_strategy": "定價策略建議",
|
||||
"generate_meta_analysis": "AI 系統自我審視",
|
||||
"execute_price_adjustment": "價格調整覆核",
|
||||
"adjust_price": "調整定價",
|
||||
"send_alert": "發送告警",
|
||||
}
|
||||
|
||||
_PRICE_ADJUSTMENT_REVIEW_ACTIONS = frozenset({
|
||||
"execute_price_adjustment",
|
||||
"adjust_price",
|
||||
"apply_price_change",
|
||||
"update_price",
|
||||
"dispatch_price_update",
|
||||
"dispatch_price_updates",
|
||||
})
|
||||
|
||||
|
||||
def _zh_trigger(trigger_type: str) -> str:
|
||||
return _TRIGGER_ZH.get(trigger_type, trigger_type)
|
||||
@@ -559,7 +569,7 @@ class ElephantAlphaAutonomousEngine:
|
||||
async def _execute_step(self, step: Dict[str, Any]) -> None:
|
||||
agent_type = step.get("agent", "").lower()
|
||||
action = step.get("action", "")
|
||||
params = step.get("parameters", {})
|
||||
params = step.get("parameters") or step.get("params") or {}
|
||||
|
||||
if agent_type == "hermes" and action == "analyze_price_competition":
|
||||
return await self._run_with_timeout(
|
||||
@@ -579,7 +589,10 @@ class ElephantAlphaAutonomousEngine:
|
||||
return
|
||||
|
||||
if agent_type == "openclaw" and action in (
|
||||
"generate_strategic_analysis", "generate_weekly_strategy", "generate_market_analysis"
|
||||
"generate_strategic_analysis",
|
||||
"generate_weekly_strategy",
|
||||
"generate_market_analysis",
|
||||
"generate_pricing_strategy",
|
||||
):
|
||||
return await self._run_with_timeout(
|
||||
self._generate_strategy_report,
|
||||
@@ -608,6 +621,13 @@ class ElephantAlphaAutonomousEngine:
|
||||
timeout=SSH_COMMAND_TIMEOUT,
|
||||
)
|
||||
|
||||
if action in _PRICE_ADJUSTMENT_REVIEW_ACTIONS:
|
||||
return await self._run_with_timeout(
|
||||
self._record_price_adjustment_review,
|
||||
step,
|
||||
timeout=SSH_COMMAND_TIMEOUT,
|
||||
)
|
||||
|
||||
raise ValueError(f"Unrecognized step: agent={agent_type} action={action}")
|
||||
|
||||
# ---- Sub-services ----
|
||||
@@ -638,6 +658,64 @@ class ElephantAlphaAutonomousEngine:
|
||||
payload.setdefault("error_type", error_type)
|
||||
return auto_heal_service.handle_exception(error_type=error_type, context=payload)
|
||||
|
||||
def _record_price_adjustment_review(self, step: Dict[str, Any]) -> Dict[str, Any]:
|
||||
"""
|
||||
Price changes are business-critical. Elephant Alpha may recommend them,
|
||||
but this system records the proposal for HITL review instead of applying it.
|
||||
"""
|
||||
params = step.get("parameters") or step.get("params") or {}
|
||||
sku = (
|
||||
params.get("sku")
|
||||
or params.get("product_sku")
|
||||
or params.get("i_code")
|
||||
or params.get("item_id")
|
||||
or "unknown"
|
||||
)
|
||||
action = step.get("action", "price_adjustment")
|
||||
content = (
|
||||
f"[Elephant Alpha 價格調整覆核] AI 建議執行 {action},"
|
||||
f"商品 {sku} 已攔截直接執行並轉入人工審核。"
|
||||
)
|
||||
|
||||
session = get_session()
|
||||
try:
|
||||
row = session.execute(
|
||||
text("""
|
||||
INSERT INTO ai_insights
|
||||
(insight_type, content, confidence, created_by, status, metadata_json)
|
||||
VALUES (:type, :content, :confidence, :created_by, :status, :metadata)
|
||||
RETURNING id
|
||||
"""),
|
||||
{
|
||||
"type": "human_review",
|
||||
"content": content,
|
||||
"confidence": 0.8,
|
||||
"created_by": "elephant_alpha",
|
||||
"status": "pending",
|
||||
"metadata": json.dumps({
|
||||
"source": "price_adjustment_review",
|
||||
"step": step,
|
||||
"sku": sku,
|
||||
"reason": "price_adjustment_requires_human_approval",
|
||||
}, ensure_ascii=False),
|
||||
},
|
||||
).fetchone()
|
||||
session.commit()
|
||||
insight_id = row[0] if row else None
|
||||
if insight_id:
|
||||
try:
|
||||
from services.openclaw_learning_service import enqueue_insight_embedding
|
||||
enqueue_insight_embedding(insight_id, "human_review", content)
|
||||
except Exception as embed_err:
|
||||
self._log.warning("Embedding enqueue failed for price adjustment review: %s", embed_err)
|
||||
self._log.warning("Price adjustment intercepted for HITL review: action=%s sku=%s", action, sku)
|
||||
return {"status": "pending_review", "insight_id": insight_id, "sku": sku, "action": action}
|
||||
except Exception:
|
||||
session.rollback()
|
||||
raise
|
||||
finally:
|
||||
session.close()
|
||||
|
||||
# ---- Notification ----
|
||||
async def _notify_telegram_executed(
|
||||
self,
|
||||
|
||||
@@ -146,6 +146,22 @@ DECISION FRAMEWORK:
|
||||
6. Create detailed execution plans
|
||||
7. Monitor and adapt based on outcomes
|
||||
|
||||
ALLOWED EXECUTION ACTIONS:
|
||||
- hermes / analyze_price_competition
|
||||
- nemotron / dispatch_alert
|
||||
- openclaw / generate_strategic_analysis
|
||||
- openclaw / generate_weekly_strategy
|
||||
- openclaw / generate_market_analysis
|
||||
- openclaw / generate_pricing_strategy
|
||||
- openclaw / generate_meta_analysis
|
||||
- elephant_alpha / auto_heal
|
||||
- elephant_alpha / code_fix
|
||||
|
||||
價格調整紅線:
|
||||
- 禁止輸出 execute_price_adjustment、adjust_price、apply_price_change、update_price。
|
||||
- 若需要調價,請改輸出 openclaw / generate_pricing_strategy,並在 description 說明「需要人工核准後才能調價」。
|
||||
- 本系統不得由 AI 直接修改商品價格,只能產生建議與人工覆核項目。
|
||||
|
||||
BUSINESS CONTEXT:
|
||||
- E-commerce platform (momo-pro-system)
|
||||
- Real-time price competition monitoring
|
||||
|
||||
@@ -42,6 +42,27 @@ def test_execute_step_routes_code_fix_to_autoheal(monkeypatch):
|
||||
assert calls == [("python_exception", {"target_file": "services/example.py", "error_message": "Traceback"})]
|
||||
|
||||
|
||||
def test_execute_step_routes_price_adjustment_to_human_review(monkeypatch):
|
||||
from services.elephant_alpha_autonomous_engine import ElephantAlphaAutonomousEngine
|
||||
|
||||
calls = []
|
||||
engine = ElephantAlphaAutonomousEngine()
|
||||
monkeypatch.setattr(
|
||||
engine,
|
||||
"_record_price_adjustment_review",
|
||||
lambda step: calls.append(step) or {"status": "pending_review", "sku": "SKU-9"},
|
||||
)
|
||||
|
||||
result = asyncio.run(engine._execute_step({
|
||||
"agent": "nemotron",
|
||||
"action": "execute_price_adjustment",
|
||||
"parameters": {"sku": "SKU-9", "recommended_price": 1280},
|
||||
}))
|
||||
|
||||
assert result == {"status": "pending_review", "sku": "SKU-9"}
|
||||
assert calls[0]["parameters"]["recommended_price"] == 1280
|
||||
|
||||
|
||||
def test_autoheal_derives_python_exception_from_traceback():
|
||||
from services.auto_heal_service import AutoHealService
|
||||
|
||||
|
||||
Reference in New Issue
Block a user