feat: apply category defaults first then AI adjusts + remove chips
Backend: merge strategy — category defaults are applied as baseline (ai_generated=0), AI impacts override/extend them (ai_generated=1). All N category defaults appear in the impacts list; AI covers them explicitly with event-specific score/direction adjustments. Prompt: instruct AI to cover ALL default instruments. Frontend: remove default impact chips under category selector — they now appear directly in the instrument impacts list. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -72,13 +72,18 @@ LISTE DES CATÉGORIES DISPONIBLES (utilise uniquement ces noms) :
|
|||||||
# ── Default impacts from pre-selected category ────────────────────────────
|
# ── Default impacts from pre-selected category ────────────────────────────
|
||||||
defaults_block = ""
|
defaults_block = ""
|
||||||
if preselected_defaults:
|
if preselected_defaults:
|
||||||
top = sorted(preselected_defaults, key=lambda x: x.get("sensitivity", 0), reverse=True)[:8]
|
top = sorted(preselected_defaults, key=lambda x: x.get("sensitivity", 0), reverse=True)
|
||||||
lines = [
|
lines = [
|
||||||
f" • {d['instrument_id']}: sensibilité {d.get('sensitivity',0):.0%}, "
|
f" • {d['instrument_id']}: sensibilité {d.get('sensitivity',0):.0%}, "
|
||||||
f"direction usuelle = {d.get('typical_direction','?')}"
|
f"direction usuelle = {d.get('typical_direction','?')}"
|
||||||
|
+ (f", note: {d.get('notes','')[:60]}" if d.get("notes") else "")
|
||||||
for d in top
|
for d in top
|
||||||
]
|
]
|
||||||
defaults_block = "\nImpacts par défaut de la catégorie (ajuste si besoin) :\n" + "\n".join(lines)
|
defaults_block = (
|
||||||
|
"\nImpacts par défaut de la catégorie — COUVRE TOUS CES INSTRUMENTS dans ta réponse "
|
||||||
|
"(ajuste scores/directions selon le contexte spécifique de l'événement) :\n"
|
||||||
|
+ "\n".join(lines)
|
||||||
|
)
|
||||||
|
|
||||||
return f"""Tu es un analyste macro senior spécialisé en options et trading multi-actifs.
|
return f"""Tu es un analyste macro senior spécialisé en options et trading multi-actifs.
|
||||||
|
|
||||||
@@ -241,25 +246,49 @@ def evaluate_event_impacts(
|
|||||||
|
|
||||||
cat_label = matched_cat_name or (event.get("sub_type") or "").strip() or (event.get("category") or "")
|
cat_label = matched_cat_name or (event.get("sub_type") or "").strip() or (event.get("category") or "")
|
||||||
|
|
||||||
# Persist
|
# ── Merge: category defaults (baseline) + AI adjustments ─────────────────
|
||||||
to_save = []
|
# 1. Start with ALL category defaults
|
||||||
|
base: Dict[str, Dict] = {}
|
||||||
|
if matched_cat_name:
|
||||||
|
cat_obj = next((c for c in all_cats if c["name"] == matched_cat_name), None)
|
||||||
|
if cat_obj:
|
||||||
|
for d in cat_obj.get("default_impacts", []):
|
||||||
|
tid = d.get("instrument_id")
|
||||||
|
if tid and tid in ALL_INSTRUMENTS:
|
||||||
|
base[tid] = {
|
||||||
|
"source_type": "event",
|
||||||
|
"source_id": event_id,
|
||||||
|
"source_name": event["name"],
|
||||||
|
"source_date": event["start_date"],
|
||||||
|
"category_name": cat_label,
|
||||||
|
"instrument_id": tid,
|
||||||
|
"impact_score": float(d.get("sensitivity", 0.5)),
|
||||||
|
"direction": d.get("typical_direction", "neutral"),
|
||||||
|
"rationale": d.get("notes", "") or f"Défaut catégorie {cat_label}",
|
||||||
|
"confidence": 0.70,
|
||||||
|
"ai_generated": 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
# 2. AI impacts override / extend the baseline
|
||||||
for imp in ai_impacts:
|
for imp in ai_impacts:
|
||||||
if imp.get("instrument_id") not in ALL_INSTRUMENTS:
|
tid = imp.get("instrument_id")
|
||||||
|
if not tid or tid not in ALL_INSTRUMENTS:
|
||||||
continue
|
continue
|
||||||
to_save.append({
|
base[tid] = {
|
||||||
"source_type": "event",
|
"source_type": "event",
|
||||||
"source_id": event_id,
|
"source_id": event_id,
|
||||||
"source_name": event["name"],
|
"source_name": event["name"],
|
||||||
"source_date": event["start_date"],
|
"source_date": event["start_date"],
|
||||||
"category_name": cat_label,
|
"category_name": cat_label,
|
||||||
"instrument_id": imp["instrument_id"],
|
"instrument_id": tid,
|
||||||
"impact_score": float(imp.get("impact_score", 0.5)),
|
"impact_score": float(imp.get("impact_score", 0.5)),
|
||||||
"direction": imp.get("direction", "neutral"),
|
"direction": imp.get("direction", "neutral"),
|
||||||
"rationale": imp.get("rationale", ""),
|
"rationale": imp.get("rationale", ""),
|
||||||
"confidence": float(imp.get("confidence", 0.7)),
|
"confidence": float(imp.get("confidence", 0.7)),
|
||||||
"ai_generated": 1,
|
"ai_generated": 1,
|
||||||
})
|
}
|
||||||
|
|
||||||
|
to_save = list(base.values())
|
||||||
save_instrument_impacts(to_save)
|
save_instrument_impacts(to_save)
|
||||||
saved = get_impacts_for_source("event", event_id)
|
saved = get_impacts_for_source("event", event_id)
|
||||||
|
|
||||||
|
|||||||
@@ -502,20 +502,6 @@ function EventDetail({
|
|||||||
{matchedCat?.description && (
|
{matchedCat?.description && (
|
||||||
<div className="text-xs text-slate-600 mt-1.5 italic">{matchedCat.description}</div>
|
<div className="text-xs text-slate-600 mt-1.5 italic">{matchedCat.description}</div>
|
||||||
)}
|
)}
|
||||||
{matchedCat && nDefaults > 0 && (
|
|
||||||
<div className="flex flex-wrap gap-1 mt-2">
|
|
||||||
{matchedCat.default_impacts.slice(0, 8).map((di: DefaultImpact) => (
|
|
||||||
<span key={di.instrument_id}
|
|
||||||
className={clsx('text-xs px-1.5 py-0.5 rounded border font-mono',
|
|
||||||
di.typical_direction === 'bullish' ? 'text-emerald-400 border-emerald-800/40 bg-emerald-900/20' :
|
|
||||||
di.typical_direction === 'bearish' ? 'text-red-400 border-red-800/40 bg-red-900/20' :
|
|
||||||
'text-slate-400 border-slate-700 bg-slate-800/40')}>
|
|
||||||
{di.typical_direction === 'bullish' ? '↑' : di.typical_direction === 'bearish' ? '↓' : '–'} {di.instrument_id}
|
|
||||||
<span className="text-slate-600 ml-1">{(di.sensitivity * 100).toFixed(0)}%</span>
|
|
||||||
</span>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
})()}
|
})()}
|
||||||
|
|||||||
Reference in New Issue
Block a user