Skip to content

Commit 46f2355

Browse files
authored
Revert "fix: persist feedback model and ruleset versions" (ExtensionShield#230)
1 parent 84f335c commit 46f2355

3 files changed

Lines changed: 12 additions & 288 deletions

File tree

src/extension_shield/api/main.py

Lines changed: 3 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -988,65 +988,6 @@ def validate_feedback(self) -> "FeedbackRequest":
988988
return self
989989

990990

991-
def _coerce_json_dict(value: Any) -> Dict[str, Any]:
992-
"""Convert JSON-ish values to a dict for metadata lookups."""
993-
if isinstance(value, dict):
994-
return value
995-
if isinstance(value, str):
996-
try:
997-
parsed = json.loads(value)
998-
except (TypeError, ValueError):
999-
return {}
1000-
return parsed if isinstance(parsed, dict) else {}
1001-
return {}
1002-
1003-
1004-
def _extract_feedback_versions(payload: Optional[Dict[str, Any]]) -> tuple[Optional[str], Optional[str]]:
1005-
"""Extract model and ruleset versions from a scan payload when available."""
1006-
if not isinstance(payload, dict):
1007-
return None, None
1008-
1009-
metadata = _coerce_json_dict(payload.get("metadata"))
1010-
summary = _coerce_json_dict(payload.get("summary"))
1011-
report_view_model_source = payload.get("report_view_model")
1012-
if not report_view_model_source:
1013-
report_view_model_source = summary.get("report_view_model")
1014-
report_view_model = _coerce_json_dict(report_view_model_source)
1015-
report_meta = _coerce_json_dict(report_view_model.get("meta"))
1016-
1017-
scoring_v2 = _coerce_json_dict(payload.get("scoring_v2"))
1018-
if not scoring_v2:
1019-
scoring_v2 = _coerce_json_dict(summary.get("scoring_v2"))
1020-
1021-
model_version = (
1022-
summary.get("model_version")
1023-
or metadata.get("model_version")
1024-
or report_meta.get("model_version")
1025-
or summary.get("llm_model")
1026-
or metadata.get("llm_model")
1027-
)
1028-
1029-
ruleset_version = (
1030-
summary.get("ruleset_version")
1031-
or metadata.get("ruleset_version")
1032-
or report_meta.get("ruleset_version")
1033-
or scoring_v2.get("weights_version")
1034-
or scoring_v2.get("scoring_version")
1035-
)
1036-
1037-
return model_version, ruleset_version
1038-
1039-
1040-
def _resolve_feedback_versions(scan_id: str) -> tuple[Optional[str], Optional[str]]:
1041-
"""Look up the related scan payload and extract version metadata safely."""
1042-
payload = scan_results.get(scan_id)
1043-
if isinstance(payload, dict):
1044-
return _extract_feedback_versions(payload)
1045-
1046-
db_payload = db.get_scan_result(scan_id)
1047-
return _extract_feedback_versions(db_payload)
1048-
1049-
1050991
class ReviewQueueClaimRequest(BaseModel):
1051992
"""Request body for claiming a review queue item."""
1052993
queue_item_id: str
@@ -1567,16 +1508,6 @@ async def run_analysis_workflow(url: str, extension_id: str):
15671508
if scoring_result.coverage_cap_reason is not None:
15681509
scoring_v2_payload["coverage_cap_reason"] = scoring_result.coverage_cap_reason
15691510

1570-
executive_summary = final_state.get("executive_summary") or {}
1571-
if isinstance(executive_summary, dict):
1572-
executive_summary = dict(executive_summary)
1573-
else:
1574-
executive_summary = {}
1575-
executive_summary.setdefault(
1576-
"ruleset_version",
1577-
scoring_v2_payload.get("weights_version") or scoring_v2_payload.get("scoring_version"),
1578-
)
1579-
15801511
# Build scan results - sanitize complex objects to prevent circular references
15811512
raw_results = {
15821513
"extension_id": extension_id,
@@ -1591,7 +1522,7 @@ async def run_analysis_workflow(url: str, extension_id: str):
15911522
"webstore_analysis": analysis_results.get("webstore_analysis") or {},
15921523
"virustotal_analysis": analysis_results.get("virustotal_analysis") or {},
15931524
"entropy_analysis": analysis_results.get("entropy_analysis") or {},
1594-
"summary": executive_summary,
1525+
"summary": final_state.get("executive_summary") or {},
15951526
"impact_analysis": analysis_results.get("impact_analysis") or {},
15961527
"privacy_compliance": analysis_results.get("privacy_compliance") or {},
15971528
"extracted_path": _storage_relative_extracted_path(final_state.get("extension_dir")),
@@ -2272,14 +2203,11 @@ async def submit_feedback(feedback: FeedbackRequest, http_request: Request):
22722203
provide details about why it wasn't (false positive, score issues, etc.).
22732204
"""
22742205
user_id = _get_user_id(http_request)
2275-
if user_id == "anon":
2276-
user_id = None
22772206

22782207
# If helpful=true, ignore reason/suggested_score/comment
22792208
reason = None if feedback.helpful else (feedback.reason.value if feedback.reason else None)
22802209
suggested_score = None if feedback.helpful else feedback.suggested_score
22812210
comment = None if feedback.helpful else feedback.comment
2282-
model_version, ruleset_version = _resolve_feedback_versions(feedback.scan_id)
22832211

22842212
# Save feedback to database (SQLite or Supabase)
22852213
db.save_feedback(
@@ -2289,8 +2217,8 @@ async def submit_feedback(feedback: FeedbackRequest, http_request: Request):
22892217
suggested_score=suggested_score,
22902218
comment=comment,
22912219
user_id=user_id,
2292-
model_version=model_version,
2293-
ruleset_version=ruleset_version,
2220+
model_version=None, # TODO: Extract from scan result metadata
2221+
ruleset_version=None, # TODO: Extract from scan result metadata
22942222
)
22952223

22962224
return {"ok": True}

src/extension_shield/core/summary_generator.py

Lines changed: 9 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -35,40 +35,6 @@ def _summary_contradicts_label(text: str, score_label: str) -> bool:
3535
return False
3636

3737

38-
def _extract_response_model_version(response: Any) -> Optional[str]:
39-
"""Best-effort extraction of the actual model identifier returned by the LLM client."""
40-
if response is None:
41-
return None
42-
43-
direct_value = getattr(response, "model", None) or getattr(response, "model_name", None)
44-
if isinstance(direct_value, str) and direct_value.strip():
45-
return direct_value.strip()
46-
47-
response_metadata = getattr(response, "response_metadata", None)
48-
if isinstance(response_metadata, dict):
49-
for key in ("model_name", "model", "model_id", "deployment_name"):
50-
value = response_metadata.get(key)
51-
if isinstance(value, str) and value.strip():
52-
return value.strip()
53-
54-
additional_kwargs = getattr(response, "additional_kwargs", None)
55-
if isinstance(additional_kwargs, dict):
56-
for key in ("model_name", "model", "model_id"):
57-
value = additional_kwargs.get(key)
58-
if isinstance(value, str) and value.strip():
59-
return value.strip()
60-
61-
return None
62-
63-
64-
def _attach_model_version(summary: Dict[str, Any], model_version: Optional[str]) -> Dict[str, Any]:
65-
"""Return a shallow copy of a summary with model_version attached when known."""
66-
normalized = dict(summary) if isinstance(summary, dict) else {}
67-
if model_version:
68-
normalized["model_version"] = model_version
69-
return normalized
70-
71-
7238
class SummaryGenerator:
7339
"""Generates executive summaries from all analysis results."""
7440

@@ -507,13 +473,11 @@ def generate(
507473
model_name=model_name,
508474
model_parameters=model_parameters,
509475
)
510-
resolved_model_version = _extract_response_model_version(response)
511476

512477
# Parse JSON response
513478
parser = JsonOutputParser()
514479
summary = parser.parse(response.content if hasattr(response, "content") else str(response))
515480
if isinstance(summary, dict):
516-
summary = _attach_model_version(summary, resolved_model_version)
517481
score = summary.get("score")
518482
score_label = summary.get("score_label")
519483
if score is None:
@@ -578,13 +542,10 @@ def generate(
578542
# )
579543
# Return deterministic fallback
580544
from extension_shield.core.report_view_model import _fallback_executive_summary
581-
return _attach_model_version(
582-
_fallback_executive_summary(
583-
score=score,
584-
score_label=score_label,
585-
host_scope_label=host_scope_label,
586-
),
587-
resolved_model_version,
545+
return _fallback_executive_summary(
546+
score=score,
547+
score_label=score_label,
548+
host_scope_label=host_scope_label,
588549
)
589550

590551
# ── Post-LLM sanity check: one_liner must not contradict score_label ──
@@ -596,15 +557,12 @@ def generate(
596557
score_label,
597558
)
598559
from extension_shield.core.report_view_model import _fallback_executive_summary
599-
return _attach_model_version(
600-
_fallback_executive_summary(
601-
score=score,
602-
score_label=score_label,
603-
host_scope_label=host_scope_label,
604-
),
605-
resolved_model_version,
560+
return _fallback_executive_summary(
561+
score=score,
562+
score_label=score_label,
563+
host_scope_label=host_scope_label,
606564
)
607-
565+
608566
logger.info("Executive summary generated successfully")
609567
return summary
610568
except Exception as exc:

tests/api/test_feedback_endpoint.py

Lines changed: 0 additions & 162 deletions
This file was deleted.

0 commit comments

Comments
 (0)