Skip to content

Commit d7ef283

Browse files
committed
Fix mypy errors and restore full type check
1 parent 7e038c3 commit d7ef283

File tree

12 files changed

+78
-47
lines changed

12 files changed

+78
-47
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ jobs:
2626
run: ruff check .
2727

2828
- name: Type check
29-
run: mypy feedback_agent/json_utils.py
29+
run: mypy
3030

3131
- name: Tests
3232
run: pytest -q

feedback_agent/agent.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -240,14 +240,15 @@ def __init__(
240240

241241
# Initialize plugins
242242
self.plugins = []
243+
self.logging_plugin: Optional[LoggingPlugin] = None
244+
self.metrics_plugin: Optional[ExamMetricsPlugin] = None
243245

244246
# Add LoggingPlugin for ADK built-in observability (optional)
245247
if enable_logging_plugin:
246248
self.logging_plugin = LoggingPlugin()
247249
self.plugins.append(self.logging_plugin)
248250
logger.info("📝 LoggingPlugin enabled for ADK observability")
249251
else:
250-
self.logging_plugin = None
251252
logger.info("📝 LoggingPlugin disabled (evaluation mode)")
252253

253254
# Add custom metrics plugin if enabled
@@ -257,8 +258,6 @@ def __init__(
257258
)
258259
self.plugins.append(self.metrics_plugin)
259260
logger.info(f"📊 ExamMetricsPlugin enabled (logging to {metrics_file})")
260-
else:
261-
self.metrics_plugin = None
262261

263262
# Create App with context compaction and plugins
264263
self.app = App(

feedback_agent/agents/analysis_agent.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from google.adk.agents.llm_agent import Agent
2-
from typing import List, Dict, Any
2+
from typing import List, Dict, Any, Optional
33
from google.genai import types
44
import json
55

@@ -16,7 +16,7 @@
1616
from feedback_agent.custom_llm import CustomGemini
1717

1818
class AnalysisAgent:
19-
def __init__(self, model: str = None):
19+
def __init__(self, model: Optional[str] = None):
2020
# Get model from environment or use provided value
2121
if model is None:
2222
model = os.getenv('MODEL_NAME')
@@ -127,7 +127,7 @@ def __init__(self, model: str = None):
127127
def analyze_performance(
128128
self,
129129
graded_exam: Dict[str, Any],
130-
exam_content: str = None
130+
exam_content: Optional[str] = None
131131
) -> Dict[str, Any]:
132132
"""
133133
Analyze a graded exam to identify student weaknesses.

feedback_agent/agents/grading_agent.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11

22
from google.adk.agents.llm_agent import Agent
3-
from typing import Dict, Any
3+
from typing import Dict, Any, Optional
44
from google.genai import types
55

66
import logging
@@ -17,7 +17,7 @@
1717
from feedback_agent.json_utils import parse_json_payload
1818

1919
class GradingAgent:
20-
def __init__(self, model: str = None):
20+
def __init__(self, model: Optional[str] = None):
2121
# Get model from environment or use provided value
2222
if model is None:
2323
model = os.getenv('MODEL_NAME')

feedback_agent/agents/image_processing_agent.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ class ImageProcessingAgent:
6161
If no answer key is visible, set "answer_key" to "Not found".
6262
"""
6363

64-
def __init__(self, model: str = None):
64+
def __init__(self, model: Optional[str] = None):
6565
"""
6666
Initialize the image processing agent.
6767
@@ -192,6 +192,12 @@ async def process_image(
192192
logger.info("Successfully extracted exam content from image")
193193
return result
194194
logger.warning("Failed to parse JSON from image processing response")
195+
return {
196+
"subject": "Unknown",
197+
"exam_content": response_text,
198+
"answer_key": "Not found",
199+
"error": "Failed to parse JSON response",
200+
}
195201
else:
196202
logger.warning("Empty response from image processing")
197203
return {

feedback_agent/agents/recommendation_agent.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from google.adk.agents.llm_agent import Agent
2-
from typing import List, Dict, Any
2+
from typing import List, Dict, Any, Optional
33
from google.genai import types
44
import json
55

@@ -17,7 +17,7 @@
1717
from feedback_agent.json_utils import parse_json_payload
1818

1919
class RecommendationAgent:
20-
def __init__(self, model: str = None):
20+
def __init__(self, model: Optional[str] = None):
2121
# Get model from environment or use provided value
2222
if model is None:
2323
model = os.getenv('MODEL_NAME')

feedback_agent/authorization.py

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,10 @@ def get_my_performance(tool_context: ToolContext) -> Dict[str, Any]:
115115
all_weaknesses = []
116116
for exam in exams:
117117
exam_id = exam.get("exam_id")
118-
analysis = _db.get_analysis(exam_id)
119-
if analysis and analysis.get("weaknesses"):
120-
all_weaknesses.extend(analysis["weaknesses"])
118+
if exam_id:
119+
analysis = _db.get_analysis(exam_id)
120+
if analysis and analysis.get("weaknesses"):
121+
all_weaknesses.extend(analysis["weaknesses"])
121122

122123
return {
123124
"status": "success",
@@ -215,12 +216,13 @@ def get_student_performance(
215216
all_recommendations = []
216217
for exam in exams:
217218
exam_id = exam.get("exam_id")
218-
analysis = _db.get_analysis(exam_id)
219-
if analysis:
220-
if analysis.get("weaknesses"):
221-
all_weaknesses.extend(analysis["weaknesses"])
222-
if analysis.get("recommendations"):
223-
all_recommendations.append(analysis["recommendations"])
219+
if exam_id:
220+
analysis = _db.get_analysis(exam_id)
221+
if analysis:
222+
if analysis.get("weaknesses"):
223+
all_weaknesses.extend(analysis["weaknesses"])
224+
if analysis.get("recommendations"):
225+
all_recommendations.append(analysis["recommendations"])
224226

225227
return {
226228
"status": "success",
@@ -312,9 +314,10 @@ def get_class_statistics(tool_context: ToolContext) -> Dict[str, Any]:
312314
# Collect weaknesses
313315
for exam in exams:
314316
exam_id = exam.get("exam_id")
315-
analysis = _db.get_analysis(exam_id)
316-
if analysis and analysis.get("weaknesses"):
317-
all_class_weaknesses.extend(analysis["weaknesses"])
317+
if exam_id:
318+
analysis = _db.get_analysis(exam_id)
319+
if analysis and analysis.get("weaknesses"):
320+
all_class_weaknesses.extend(analysis["weaknesses"])
318321

319322
# Calculate class averages
320323
if student_performances:
@@ -327,7 +330,7 @@ def get_class_statistics(tool_context: ToolContext) -> Dict[str, Any]:
327330
lowest_performer = None
328331

329332
# Find most common weaknesses
330-
weakness_counts = {}
333+
weakness_counts: Dict[str, int] = {}
331334
for weakness in all_class_weaknesses:
332335
topic = weakness.get("topic", "Unknown")
333336
weakness_counts[topic] = weakness_counts.get(topic, 0) + 1

feedback_agent/conversational_tools.py

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -718,16 +718,16 @@ def get_student_results(
718718
"message": f"Student not found: {student_name or student_id}",
719719
}
720720

721-
student_id = student["student_id"]
722-
student_name = student["name"]
723-
exams = db.get_student_exams(student_id)
721+
student_id_value: str = student["student_id"]
722+
student_name_value: str = student["name"]
723+
exams = db.get_student_exams(student_id_value)
724724

725725
if not exams:
726726
return {
727727
"status": "success",
728-
"message": f"No exams recorded for {student_name}.",
729-
"student_name": student_name,
730-
"student_id": student_id,
728+
"message": f"No exams recorded for {student_name_value}.",
729+
"student_name": student_name_value,
730+
"student_id": student_id_value,
731731
"exams": [],
732732
}
733733

@@ -749,8 +749,8 @@ def get_student_results(
749749

750750
return {
751751
"status": "success",
752-
"student_name": student_name,
753-
"student_id": student_id,
752+
"student_name": student_name_value,
753+
"student_id": student_id_value,
754754
"summary": {
755755
"total_exams": len(exams),
756756
"average_percentage": round(avg_percentage, 1),
@@ -850,7 +850,7 @@ def get_class_analytics(tool_context: ToolContext) -> Dict[str, Any]:
850850
lowest = min(student_performances, key=lambda s: s["average_percentage"])
851851

852852
# Find common weaknesses
853-
weakness_counts = {}
853+
weakness_counts: Dict[str, int] = {}
854854
for w in all_class_weaknesses:
855855
topic = w.get("topic", "Unknown")
856856
weakness_counts[topic] = weakness_counts.get(topic, 0) + 1
@@ -979,17 +979,24 @@ def get_learning_recommendations(
979979
db = system.db
980980

981981
# Find student
982-
if not student_id:
982+
student_id_value: Optional[str] = student_id
983+
if not student_id_value:
983984
student = db.get_student_by_name(student_name) if student_name else None
984985
if not student:
985986
return {
986987
"status": "error",
987988
"message": f"Student not found: {student_name}",
988989
}
989-
student_id = student["student_id"]
990+
student_id_value = student["student_id"]
991+
992+
if not student_id_value:
993+
return {
994+
"status": "error",
995+
"message": "Student ID not available for recommendations.",
996+
}
990997

991998
# Get latest exam with recommendations
992-
exams = db.get_student_exams(student_id)
999+
exams = db.get_student_exams(student_id_value)
9931000

9941001
if not exams:
9951002
return {

feedback_agent/memory.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -129,11 +129,13 @@ def get_recurring_weaknesses(
129129
first_occurrence = min(occurrences, key=lambda o: o["index"])
130130
last_occurrence = max(occurrences, key=lambda o: o["index"])
131131

132-
def _label(occ: Dict[str, Optional[str]]) -> str:
133-
if occ.get("date"):
134-
return occ["date"]
135-
if occ.get("exam_id"):
136-
return occ["exam_id"]
132+
def _label(occ: Dict[str, Any]) -> str:
133+
date_value = occ.get("date")
134+
if date_value:
135+
return str(date_value)
136+
exam_id_value = occ.get("exam_id")
137+
if exam_id_value:
138+
return str(exam_id_value)
137139
return f"exam_{occ['index']}"
138140

139141
pattern = WeaknessPattern(

feedback_agent/plugins.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ def __init__(self, log_to_file: bool = True, metrics_file: str = "exam_metrics.j
5252
# Aggregated statistics
5353
self.total_exams_processed = 0
5454
self.total_processing_time = 0.0
55-
self.score_distribution = []
55+
self.score_distribution: list[float] = []
5656
self.success_count = 0
5757
self.failure_count = 0
5858

0 commit comments

Comments
 (0)