Spaces:
Running on Zero
Running on Zero
File size: 16,588 Bytes
ef19228 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 | """Plain-language explanations of everything the pipeline measured, for the result page
and the seller report. Nothing here changes a decision; it only translates numbers
into "what was checked, what is normal, and is this value fine or a problem".
Reference ranges come from the evaluation set (object-only DINOv2, mean of 3 views):
same item re-photographed 89-99%, another unit of the same or a similar model 72-85%,
different products 37-53%. Colour (median chroma, Delta E): same item <= 2.6,
blue vs black speaker of one model ~3.9.
"""
from returnguard import config
GOOD, OK, WARN, BAD, INFO = "good", "ok", "warn", "bad", "info"
COLOR_NORMAL_MAX = 2.8
COLOR_CLEAR_DIFF = 4.0
def risk_band(risk):
if risk is None:
return None
if risk < 20:
return {"label": "Very low risk", "level": GOOD}
if risk < config.ACCEPT_BELOW:
return {"label": "Low risk", "level": GOOD}
if risk < config.REJECT_FROM:
return {"label": "Needs a human check", "level": WARN}
return {"label": "Very high risk", "level": BAD}
def shape(sim: float) -> dict:
pct = round(sim * 100)
if sim >= config.FAST_ACCEPT_SHAPE:
return {"value": f"{pct}% similar", "verdict": "Matches the delivered item", "level": GOOD,
"detail": "Photos of the same item usually score 89β99%."}
if sim >= 0.85:
return {"value": f"{pct}% similar", "verdict": "Mostly matches", "level": OK,
"detail": "Just below the usual range for the same item (89β99%). Camera angle or a cluttered "
"background can cause this."}
if sim >= config.FAST_REJECT_SHAPE:
return {"value": f"{pct}% similar", "verdict": "Noticeably different", "level": WARN,
"detail": "Lower than photos of the same item (89β99%). Another unit of the same or a similar "
"model usually scores 72β85%."}
return {"value": f"{pct}% similar", "verdict": "A different product", "level": BAD,
"detail": "Completely different products score 37β53%."}
def colour(delta: float) -> dict:
value = f"difference {delta:.1f} (normal: under {COLOR_NORMAL_MAX})"
if delta <= 1.5:
return {"value": value, "verdict": "Same colour", "level": GOOD,
"detail": "0 means identical. Small differences are normal: lighting and camera settings shift colour slightly."}
if delta <= COLOR_NORMAL_MAX:
return {"value": value, "verdict": "Same colour (normal lighting variation)", "level": GOOD,
"detail": f"Re-photographing the same item gives up to about 2.6; anything under {COLOR_NORMAL_MAX} is normal."}
if delta <= COLOR_CLEAR_DIFF:
return {"value": value, "verdict": "Colour is slightly off", "level": WARN,
"detail": f"More than lighting usually explains (normal is under {COLOR_NORMAL_MAX}). For comparison, the "
"blue and black speakers of the same model differ by about 3.9."}
return {"value": value, "verdict": "Clearly a different colour", "level": BAD,
"detail": "Far beyond what lighting can explain."}
def llm_error_text(error: str | None) -> str:
e = error or ""
if "RESOURCE_EXHAUSTED" in e or "429" in e or "quota" in e.lower():
return ("Gemini's free daily limit for this API key is used up, so this check could not run. It resets every "
"24 hours; enabling billing in Google AI Studio removes the limit.")
if "PERMISSION_DENIED" in e or "403" in e:
return "Google rejected the API key: its project has been denied access."
if "NOT_FOUND" in e or "404" in e:
return "The configured Gemini model is not available to this API key."
if any(s in e for s in ("UNAVAILABLE", "DEADLINE_EXCEEDED", "503", "504")):
return "Gemini was overloaded or timed out, even after several retries."
if "API key" in e or "api_key" in e or "GOOGLE_API_KEY" in e:
return "No Gemini API key is configured on the server."
return f"The Gemini call failed ({e[:120]})." if e else "The Gemini call failed."
def _best_identifier(loc: dict) -> tuple[str, str]:
"""(kind, text) of the strongest identifier at a label location: a serial or batch
number proves the unit, a brand name only the product line."""
order = ["serial_number", "batch_number", "barcode", "model_number", "label_text", "brand_name"]
kinds = {c["kind"]: c["expected"] for c in loc.get("checks", [])}
for i in loc.get("expected_kinds", []):
kinds.setdefault(i["kind"], i["text"])
for k in order:
if k in kinds:
return k.replace("_", " "), kinds[k]
# results stored before kinds were recorded: prefer text that looks like a serial/batch number
texts = loc.get("expected") or ["β"]
numbered = [t for t in texts if any(w in t.lower() for w in ("batch", "serial", "s/n", "lot"))] or \
[t for t in texts if sum(ch.isdigit() for ch in t) >= 6]
return "label", (numbered or texts)[0]
def identity(ident: dict | None) -> dict | None:
if not ident:
return None
if ident.get("error") or not ident.get("outcome"):
return {"verdict": "Label check unavailable", "level": INFO, "detail": llm_error_text(ident.get("error"))}
locs = ident.get("locations", [])
loc = next((l for l in locs if l["status"] in ("missing", "mismatch")), None) or \
next((l for l in locs if l["status"] in ("unit_match", "model_match")), None) or (locs[0] if locs else {})
kind, expected = _best_identifier(loc) if loc else ("label", "β")
where = loc.get("location", "the label")
outcome = ident["outcome"]
if outcome == "verified_unit":
return {"verdict": "Label matches the delivered unit", "level": GOOD,
"detail": f"Gemini read the label on the returned item ({where}). The {kind} β{expected}β matches the "
f"one recorded at delivery, which proves it is the same physical unit."}
if outcome == "verified_model":
return {"verdict": "Brand / model text matches", "level": OK,
"detail": f"β{expected}β matches what was recorded at delivery, but there is no serial or batch number "
f"to prove it is the same unit, so this is only weak evidence."}
if outcome == "label_missing":
return {"verdict": "The label is missing", "level": BAD,
"detail": f"At delivery there was a label ({where}) showing {kind} β{expected}β. Gemini looked at the "
f"same spot on the returned item and found no label at all."}
if outcome == "mismatch":
return {"verdict": "The label is different", "level": BAD,
"detail": f"At delivery the {kind} was β{expected}β. On the returned item Gemini read "
f"β{loc.get('observed', '')[:80]}β, which does not match."}
return {"verdict": "Label could not be read", "level": INFO,
"detail": "The label area was not clear enough in the return photos to compare."}
WEAR = {
"none": "No new wear or damage compared with the delivery photos.",
"new_damage": "There is damage that is not in the delivery photos.",
"less_wear_than_delivered": "It looks newer or less worn than the item that was delivered.",
"different_wear_pattern": "Wear marks are in different places than on the delivered item.",
}
TAGS = {"intact": "Tags recorded at delivery are still attached.", "removed_or_cut": "Tags recorded at delivery are missing or cut.",
"not_applicable": None}
def inspection(insp: dict | None) -> dict | None:
if not insp:
return None
c = insp.get("confidence", 0)
verdict, level = {
"same_unit": (f"Same unit ({c}% confident)", GOOD),
"different_unit": (f"Different unit ({c}% confident)", BAD),
"inconclusive": ("Could not tell from the photos", INFO),
}[insp["overall"]]
bullets = [f"{f['view'].capitalize()}: {'; '.join(f['differences'])}" for f in insp.get("findings", []) if f.get("differences")]
bullets.append(WEAR.get(insp.get("wear_change", "none"), ""))
if insp.get("signs_of_use"):
bullets.append("Signs of use: " + "; ".join(insp["signs_of_use"]))
if TAGS.get(insp.get("tags_status")):
bullets.append(TAGS[insp["tags_status"]])
if insp.get("accessories_change"):
bullets.append("Accessories: " + insp["accessories_change"])
if insp.get("reason_consistency") == "inconsistent":
bullets.append("The photos do not support the customer's stated return reason.")
return {"verdict": verdict, "level": level, "detail": insp.get("evidence_summary", ""), "bullets": [b for b in bullets if b]}
def policy(p: dict | None) -> dict | None:
if not p:
return None
cat = p["category"].replace("_", " & ")
detail = f"Returned {p['days_since_delivery']} day(s) after delivery; {cat} items can be returned within {p['window_days']} days."
if p.get("requires_functional_test"):
detail += " Electronics also need a quick working test before restocking, because internal faults don't show in photos."
if p["eligible"]:
return {"value": f"day {p['days_since_delivery']} of {p['window_days']}", "verdict": "Within the return window", "level": GOOD, "detail": detail}
return {"value": f"day {p['days_since_delivery']} of {p['window_days']}", "verdict": "Outside the return window", "level": BAD, "detail": detail}
def history(h: dict | None) -> dict | None:
if not h:
return None
if h["tier"] == "new":
return {"value": "first return", "verdict": "New customer: standard checks", "level": GOOD,
"detail": "No earlier returns on record for this customer."}
if h["tier"] == "regular":
return {"value": f"{h['prior_returns']} earlier return(s)", "verdict": "Good history: standard checks", "level": GOOD,
"detail": "None of this customer's earlier returns were flagged."}
return {"value": f"{h['prior_flagged']} flagged return(s)", "verdict": "Stricter checks for this customer", "level": WARN,
"detail": f"{h['prior_flagged']} of this customer's earlier returns were flagged, so a return is only "
f"auto-approved below risk {h['accept_below']} instead of {config.ACCEPT_BELOW}."}
def _effect(weight: float) -> str:
if weight >= 2:
return "strongly points to fraud"
if weight >= 0.5:
return "points to fraud"
if weight <= -2:
return "strongly points to a genuine return"
if weight <= -0.5:
return "points to a genuine return"
return "neutral"
def _gemini_status(result: dict, order: dict) -> list[dict]:
calls = {c["agent"]: c for c in result.get("llm_calls", [])}
route = result.get("route", [])
screen = result.get("screen") or {}
decision = result.get("decision") or {}
fp = (order or {}).get("fingerprint") or {}
out = []
# label check
if "identity_verify" in calls:
call = calls["identity_verify"]
e = identity(result.get("identity")) if call["ok"] else {"verdict": "Unavailable", "level": INFO,
"detail": llm_error_text(call.get("error"))}
out.append({"agent": "Label check", "status": "ran" if call["ok"] else "unavailable", **e})
else:
if decision.get("basis") in ("policy", "capture_quality"):
why = "The return was settled before any photo comparison (policy or photo quality)."
elif not fp.get("identifiers"):
why = "No printed label or serial number was recorded at delivery, so there was nothing to read."
else:
why = "The free visual check already showed a completely different product."
out.append({"agent": "Label check", "status": "not_needed", "verdict": "Not needed", "level": INFO, "detail": why})
# visual inspection
second = result.get("second_opinion")
if "visual_inspector" in calls:
call = calls["visual_inspector"]
e = inspection(result.get("inspection")) if call["ok"] else {"verdict": "Unavailable", "level": INFO,
"detail": llm_error_text(call.get("error"))}
out.append({"agent": "Visual inspection", "status": "ran" if call["ok"] else "unavailable", **e})
else:
if decision.get("basis") in ("policy", "capture_quality"):
why = "Not needed: the return was settled by policy or photo quality."
elif screen.get("verdict") == "clear_mismatch":
why = "Not needed: the free visual check already showed a completely different product."
elif "identity" in route:
why = "Not needed: the label check and the visual check agreed, so a second Gemini call would add nothing."
else:
why = "Not needed: shape and colour matched strongly and there was no label to verify."
out.append({"agent": "Visual inspection", "status": "not_needed", "verdict": "Not needed", "level": INFO,
"detail": why, "can_request": not (second and second.get("ok"))})
if second:
e = inspection(second.get("inspection")) if second.get("ok") else {"verdict": "Unavailable", "level": INFO,
"detail": llm_error_text(second.get("error"))}
out.append({"agent": "Second opinion (on request)", "status": "ran" if second.get("ok") else "unavailable",
"note": "Requested after the decision; shown for information and does not change it.", **e})
return out
def explain_result(result: dict, order: dict) -> dict:
d = result["decision"]
checks = []
for angle, q in (result.get("quality") or {}).items():
if not q["ok"]:
checks.append({"name": f"{angle.capitalize()} photo", "value": "unusable", "verdict": "Retake needed",
"level": WARN, "detail": q["problem"]})
for name, e in (("Return window", policy(result.get("policy"))), ("Customer history", history(result.get("history")))):
if e:
checks.append({"name": name, **e})
screen = result.get("screen")
if screen:
checks.append({"name": "Shape match", **shape(screen["shape_mean"])})
checks.append({"name": "Colour match", **colour(screen["color_shift_median"])})
for g in _gemini_status(result, order):
if g["status"] == "ran" and g["agent"] != "Second opinion (on request)":
checks.append({"name": g["agent"] + " (Gemini)", "value": "", "verdict": g["verdict"], "level": g["level"],
"detail": g["detail"]})
sentence = {
"ACCEPT": "Approve the refund: the returned item matches what was delivered.",
"HUMAN_REVIEW": "A person should check this return before the refund is approved.",
"REJECT": "Hold the refund: the returned item does not match what was delivered.",
"RETAKE_REQUIRED": "The return photos can't be used. Retake them and submit again.",
}[d["decision"]]
if d.get("basis") == "policy":
sentence = "Hold the refund: the return was requested after the return window closed."
problems = [c for c in checks if c["level"] in (BAD, WARN)]
reassurances = [c for c in checks if c["level"] in (GOOD, OK) and c["name"] not in ("Return window", "Customer history")]
reasons = [f"{c['name']}: {c['verdict'].lower()}" for c in (problems if d["decision"] != "ACCEPT" else reassurances)[:3]]
views = {}
if screen:
for a in config.ANGLES:
s, c = shape(screen["shape"][a]), colour(screen["color_shift"][a])
views[a] = {"shape": s["value"], "shape_verdict": s["verdict"], "shape_level": s["level"],
"colour_verdict": c["verdict"], "colour_level": c["level"]}
evidence = [{**e, "effect": _effect(e["weight"])} for e in d.get("evidence", [])]
return {"decision": {"sentence": sentence, "reasons": reasons, "risk_band": risk_band(d.get("risk_score"))},
"checks": checks, "gemini": _gemini_status(result, order), "views": views, "evidence": evidence}
|