強化 EA JSON fallback 與 EDM cache 自癒
Some checks failed
CD Pipeline / deploy (push) Has been cancelled

This commit is contained in:
OoO
2026-05-21 18:58:52 +08:00
committed by AiderHeal Bot
parent 31f88898c2
commit 5a5f268358
9 changed files with 288 additions and 22 deletions

View File

@@ -15,6 +15,7 @@ Position: Super Orchestrator above Hermes/NemoTron/OpenClaw
import os
import json
import asyncio
from json import JSONDecodeError
from datetime import datetime, timedelta
from typing import Dict, List, Any, Optional
from dataclasses import dataclass
@@ -241,8 +242,22 @@ BUSINESS OBJECTIVE: Optimize e-commerce performance through intelligent automati
if not response.success:
raise RuntimeError(response.error)
# Parse and validate response
decision_data = json.loads(response.content)
# Parse and validate response. Some NIM-compatible models still wrap
# JSON in fenced blocks or prepend reasoning text even with json_mode.
try:
decision_data = self._extract_json_object(response.content)
except ValueError as parse_error:
logger.warning(
"[ElephantAlpha] Coordination JSON parse failed; using evidence fallback. "
"model=%s error=%s preview=%r",
response.model,
parse_error,
(response.content or "")[:240],
)
return self._fallback_decision(
business_context,
reason="Elephant Alpha 回應不是可解析 JSON已改用實證 fallback。",
)
decision = self._parse_strategic_decision(decision_data)
# Log decision for learning
@@ -253,7 +268,46 @@ BUSINESS OBJECTIVE: Optimize e-commerce performance through intelligent automati
except Exception as e:
logger.error(f"[ElephantAlpha] Coordination failed: {e}")
# Fallback to conservative decision
return self._fallback_decision(business_context)
return self._fallback_decision(
business_context,
reason=f"Elephant Alpha 協調失敗:{type(e).__name__}",
)
@staticmethod
def _extract_json_object(raw: str) -> Dict[str, Any]:
"""Extract one JSON object from tolerant LLM output."""
text_value = (raw or "").strip()
if not text_value:
raise ValueError("empty response")
if text_value.startswith("```"):
lines = text_value.splitlines()
if lines and lines[0].strip().startswith("```"):
lines = lines[1:]
if lines and lines[-1].strip().startswith("```"):
lines = lines[:-1]
text_value = "\n".join(lines).strip()
try:
parsed = json.loads(text_value)
if isinstance(parsed, dict):
return parsed
raise ValueError("JSON root is not an object")
except JSONDecodeError:
pass
decoder = json.JSONDecoder()
for idx, char in enumerate(text_value):
if char != "{":
continue
try:
parsed, _end = decoder.raw_decode(text_value[idx:])
except JSONDecodeError:
continue
if isinstance(parsed, dict):
return parsed
raise ValueError("no JSON object found")
def _build_coordination_prompt(self, context: Dict[str, Any]) -> str:
"""Build detailed coordination prompt for Elephant Alpha"""
@@ -431,22 +485,56 @@ Provide your strategic decision in the specified JSON format.
finally:
session.close()
def _fallback_decision(self, context: Dict[str, Any]) -> StrategicDecision:
@staticmethod
def _context_concrete_actions(context: Dict[str, Any]) -> List[str]:
conditions = context.get("conditions") if isinstance(context, dict) else {}
if not isinstance(conditions, dict):
return []
for key in ("_prefetched_hermes_threats", "_db_evidence_actions"):
actions = conditions.get(key)
if isinstance(actions, list):
cleaned = [str(action).strip() for action in actions if str(action).strip()]
if cleaned:
return cleaned[:5]
return []
def _fallback_decision(self, context: Dict[str, Any], *, reason: str = "Elephant Alpha unavailable") -> StrategicDecision:
"""Fallback decision if Elephant Alpha fails"""
concrete_actions = self._context_concrete_actions(context)
trigger_type = str((context or {}).get("trigger_type") or "unknown")
if concrete_actions:
return StrategicDecision(
priority="high",
agents_required=["hermes", "elephant_alpha"],
reasoning=(
f"{reason} 已保留 {len(concrete_actions)} 筆 DB/Hermes 價格比對實證;"
"僅送人工覆核,不執行自動調價。"
),
expected_outcome="產生可稽核的人工覆核告警,避免使用無法解析的 LLM 推論文字。",
confidence=0.74,
execution_plan=[],
resource_requirements={
"compute_cost": "$0.00",
"time_estimate": "人工覆核",
"human_oversight": "required",
},
)
return StrategicDecision(
priority="medium",
agents_required=["openclaw"],
reasoning="Elephant Alpha unavailable, using conservative OpenClaw strategy",
expected_outcome="Basic strategic analysis",
agents_required=["elephant_alpha"],
reasoning=(
f"{reason} trigger={trigger_type},且沒有可稽核的 DB/Hermes 實證;"
"不產生策略型行動計畫,避免把推測當成事實。"
),
expected_outcome="不執行自動動作;需要先確認資料來源或等待下一輪具體實證。",
confidence=0.6,
execution_plan=[{
"step": 1,
"agent": "openclaw",
"action": "generate_market_analysis",
"parameters": context,
"expected_duration": "2-3 minutes"
}],
resource_requirements={"compute_cost": "$0.00", "time_estimate": "5 minutes"}
execution_plan=[],
resource_requirements={
"compute_cost": "$0.00",
"time_estimate": "等待實證",
"human_oversight": "required",
},
)
# Singleton instance

View File

@@ -304,6 +304,8 @@ SEARCH_NOISE_TOKENS = {
}
SEARCH_IDENTITY_ANCHORS = (
"潤浸保濕清爽身體乳液",
"閃亮珍珠眼影棒",
"智能光感應無線自動除臭芳香噴霧機",
"usb精油薰香機",
"超音波水氧機",
@@ -520,6 +522,8 @@ BRAND_ALIAS_OVERRIDES = {
"xiaomi": ("小米有品", "小米", "xiaomi"),
"mac": ("m.a.c", "mac", "m a c"),
"opi": ("o.p.i", "opi", "o p i"),
"curel": ("curel", "珂潤"),
"karadium": ("karadium",),
"st雞仔牌": ("日本雞仔牌st", "日本st雞仔牌", "st雞仔牌", "雞仔牌st", "雞仔牌"),
}