Furqan1111 commited on
Commit
74527c1
·
verified ·
1 Parent(s): fc0a996

Create reviewer_agent.py

Browse files
Files changed (1) hide show
  1. agents/reviewer_agent.py +134 -0
agents/reviewer_agent.py ADDED
@@ -0,0 +1,134 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Dict, Any
2
+
3
+
4
+ class ReviewerAgent:
5
+ """
6
+ Reviewer Agent
7
+ - Collects outputs from Grammar, Style, and Clarity agents
8
+ - Combines their confidence, number of changes, and readability
9
+ - Selects the best final output
10
+ - Returns a full explanation + candidate comparison
11
+ """
12
+
13
+ def __init__(self):
14
+ pass
15
+
16
+ @staticmethod
17
+ def _length_score(text: str) -> float:
18
+ """
19
+ Simple readability heuristic based on text length.
20
+ Penalizes texts that are too short or too long.
21
+ """
22
+ words = text.split()
23
+ n = len(words)
24
+
25
+ if n == 0:
26
+ return 0.0
27
+
28
+ # Ideal range: 8–40 words
29
+ if n < 8:
30
+ return 0.4
31
+ if n > 40:
32
+ return 0.6
33
+
34
+ return 1.0
35
+
36
+ def review(
37
+ self,
38
+ original: str,
39
+ grammar_result: Dict[str, Any],
40
+ style_result: Dict[str, Any],
41
+ clarity_result: Dict[str, Any],
42
+ ) -> Dict[str, Any]:
43
+ """
44
+ Decide which version is best and explain the decision.
45
+ Returns:
46
+ {
47
+ "final_text": ...,
48
+ "candidates": [...],
49
+ "decision_explanation": "..."
50
+ }
51
+ """
52
+
53
+ candidates = []
54
+
55
+ # -----------------------
56
+ # 1) Original Input
57
+ # -----------------------
58
+ orig_score = 0.3
59
+ candidates.append({
60
+ "name": "original",
61
+ "text": original,
62
+ "score": round(orig_score, 3),
63
+ "notes": "Raw user input; no improvements applied."
64
+ })
65
+
66
+ # -----------------------
67
+ # 2) Grammar Agent Output
68
+ # -----------------------
69
+ g_text = grammar_result["corrected"]
70
+ g_changes = len(grammar_result.get("changes", []))
71
+ g_conf = grammar_result.get("confidence", 0.7)
72
+
73
+ g_score = (0.4 * g_conf) + (0.3 + min(g_changes, 5) * 0.05)
74
+ g_score *= self._length_score(g_text)
75
+
76
+ candidates.append({
77
+ "name": "grammar",
78
+ "text": g_text,
79
+ "score": round(g_score, 3),
80
+ "notes": f"Grammar agent fixed {g_changes} issue(s)."
81
+ })
82
+
83
+ # -----------------------
84
+ # 3) Style Agent Output
85
+ # -----------------------
86
+ s_text = style_result["styled"]
87
+ s_changes = len(style_result.get("changes", []))
88
+ s_conf = style_result.get("confidence", 0.75)
89
+
90
+ s_score = (0.4 * s_conf) + (0.35 + min(s_changes, 5) * 0.04)
91
+ s_score *= self._length_score(s_text)
92
+
93
+ candidates.append({
94
+ "name": "style",
95
+ "text": s_text,
96
+ "score": round(s_score, 3),
97
+ "notes": f"Style agent applied {s_changes} improvements."
98
+ })
99
+
100
+ # -----------------------
101
+ # 4) Clarity Agent Output
102
+ # -----------------------
103
+ c_text = clarity_result["clarified"]
104
+ c_changes = len(clarity_result.get("changes", []))
105
+ c_conf = clarity_result.get("confidence", 0.8)
106
+
107
+ c_score = (0.4 * c_conf) + (0.4 + min(c_changes, 5) * 0.03)
108
+ c_score *= self._length_score(c_text)
109
+
110
+ candidates.append({
111
+ "name": "clarity",
112
+ "text": c_text,
113
+ "score": round(c_score, 3),
114
+ "notes": f"Clarity agent rewrote {c_changes} part(s) for readability."
115
+ })
116
+
117
+ # -----------------------
118
+ # Decide the winner
119
+ # -----------------------
120
+ best = max(candidates, key=lambda c: c["score"])
121
+
122
+ explanation = (
123
+ f"The reviewer selected the final output from the '{best['name']}' agent "
124
+ f"because it achieved the highest overall quality score ({best['score']}). "
125
+ "Scores are based on: (1) the agent’s confidence, (2) number of improvements, "
126
+ "(3) readability via length heuristic. This ensures the final text is "
127
+ "clear, professional, and client-ready."
128
+ )
129
+
130
+ return {
131
+ "final_text": best["text"],
132
+ "candidates": candidates,
133
+ "decision_explanation": explanation
134
+ }