aelin commited on
Commit
a1074ab
·
1 Parent(s): 8ebfdcd

Adds answer caching and user score types

Browse files
Files changed (3) hide show
  1. _types.py +17 -4
  2. app.py +23 -8
  3. utils.py +43 -0
_types.py CHANGED
@@ -1,10 +1,23 @@
1
- from typing import TypedDict, Optional, List
 
 
 
 
 
 
2
 
3
  class Question(TypedDict):
4
  task_id: str
5
  question: str
6
  file_name: Optional[str] = None
7
 
8
-
9
- # A list of questions based on Question type
10
- Questions = List[Question]
 
 
 
 
 
 
 
 
1
+ from typing import TypedDict, Optional, List, Dict
2
+
3
+ class AnswerCacheEntry(TypedDict):
4
+ answer: str
5
+ isCorrect: bool
6
+
7
+ AnswerCache = Dict[str, AnswerCacheEntry]
8
 
9
  class Question(TypedDict):
10
  task_id: str
11
  question: str
12
  file_name: Optional[str] = None
13
 
14
+ class UserScore(TypedDict):
15
+ username: str
16
+ score: int
17
+ correct_count: int
18
+ total_attempted: int
19
+ message: str
20
+ timestamp: str
21
+
22
+ Questions = List[Question]
23
+
app.py CHANGED
@@ -1,12 +1,14 @@
 
1
  import os
2
  import gradio as gr
3
  import requests
4
  import pandas as pd
5
- from _types import Questions, Question
6
  from llama_index.llms.huggingface_api import HuggingFaceInferenceAPI
7
  from llama_index.core.agent.workflow import AgentWorkflow
8
  from _tools import tools
9
  import asyncio
 
10
 
11
  # (Keep Constants as is)
12
  # --- Constants ---
@@ -54,11 +56,19 @@ class BasicAgent:
54
  as you want. The file name is: {file_name}.\n
55
  """
56
 
 
 
 
 
 
 
 
 
57
  answer = await self.agent.run(prompt)
58
 
59
  print(f"Agent returning answer: {answer}")
60
 
61
- return answer
62
 
63
  def instantiate_agent():
64
  try:
@@ -124,13 +134,15 @@ async def fetch_file(question: Question) -> str | None:
124
  async def run_agent_on_questions(agent: BasicAgent, questions_data: Questions):
125
  results_log = []
126
  answers_payload = []
127
-
128
  print(f"Running agent on {len(questions_data)} questions...")
129
-
 
 
 
130
  for item in questions_data:
131
  task_id = item.get("task_id")
132
  question_text = item.get("question")
133
-
134
  if not task_id or question_text is None:
135
  print(f"Skipping item with missing task_id or question: {item}")
136
  continue
@@ -139,11 +151,15 @@ async def run_agent_on_questions(agent: BasicAgent, questions_data: Questions):
139
  submitted_answer = await agent.run(item)
140
  answers_payload.append({"task_id": task_id, "submitted_answer": submitted_answer})
141
  results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": submitted_answer})
 
 
142
 
143
  except Exception as e:
144
  print(f"Error running agent on task {task_id}: {e}")
145
- results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": f"AGENT ERROR: {e}"})
146
 
 
 
 
147
  return answers_payload, results_log
148
 
149
  def submit_answers(submit_url, submission_data, results_log):
@@ -152,7 +168,7 @@ def submit_answers(submit_url, submission_data, results_log):
152
  try:
153
  response = requests.post(submit_url, json=submission_data, timeout=60)
154
  response.raise_for_status()
155
- result_data = response.json()
156
 
157
  final_status = (
158
  f"Submission Successful!\n"
@@ -245,7 +261,6 @@ async def run_and_submit_all(profile: gr.OAuthProfile | None):
245
  return submit_answers(submit_url, submission_data, results_log)
246
 
247
 
248
-
249
  async def main():
250
  await run_and_submit_all(profile=None)
251
 
 
1
+
2
  import os
3
  import gradio as gr
4
  import requests
5
  import pandas as pd
6
+ from _types import Questions, Question, UserScore
7
  from llama_index.llms.huggingface_api import HuggingFaceInferenceAPI
8
  from llama_index.core.agent.workflow import AgentWorkflow
9
  from _tools import tools
10
  import asyncio
11
+ from utils import cache_answers, update_cache_answer, get_cached_answer
12
 
13
  # (Keep Constants as is)
14
  # --- Constants ---
 
56
  as you want. The file name is: {file_name}.\n
57
  """
58
 
59
+
60
+ # Retrieve the answer from the cache if it exists
61
+ cached = get_cached_answer(task_id)
62
+ if cached and cached.get("isCorrect") and cached.get("answer"):
63
+ print(f"Returning cached correct answer for task_id {task_id}: {cached['answer']}")
64
+
65
+ return str(cached["answer"])
66
+
67
  answer = await self.agent.run(prompt)
68
 
69
  print(f"Agent returning answer: {answer}")
70
 
71
+ return str(answer)
72
 
73
  def instantiate_agent():
74
  try:
 
134
  async def run_agent_on_questions(agent: BasicAgent, questions_data: Questions):
135
  results_log = []
136
  answers_payload = []
 
137
  print(f"Running agent on {len(questions_data)} questions...")
138
+
139
+ # Inicializa o cache com todas as respostas erradas (se ainda não existir)
140
+ cache_answers(questions_data)
141
+
142
  for item in questions_data:
143
  task_id = item.get("task_id")
144
  question_text = item.get("question")
145
+
146
  if not task_id or question_text is None:
147
  print(f"Skipping item with missing task_id or question: {item}")
148
  continue
 
151
  submitted_answer = await agent.run(item)
152
  answers_payload.append({"task_id": task_id, "submitted_answer": submitted_answer})
153
  results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": submitted_answer})
154
+ # Update the cache with the answer
155
+ update_cache_answer(task_id, submitted_answer, is_correct=False)
156
 
157
  except Exception as e:
158
  print(f"Error running agent on task {task_id}: {e}")
 
159
 
160
+ results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": f"AGENT ERROR: {e}"})
161
+ update_cache_answer(task_id, f"AGENT ERROR: {e}", is_correct=False)
162
+
163
  return answers_payload, results_log
164
 
165
  def submit_answers(submit_url, submission_data, results_log):
 
168
  try:
169
  response = requests.post(submit_url, json=submission_data, timeout=60)
170
  response.raise_for_status()
171
+ result_data: UserScore = response.json()
172
 
173
  final_status = (
174
  f"Submission Successful!\n"
 
261
  return submit_answers(submit_url, submission_data, results_log)
262
 
263
 
 
264
  async def main():
265
  await run_and_submit_all(profile=None)
266
 
utils.py ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ import json
3
+ import os
4
+ from typing import Optional
5
+ from _types import AnswerCacheEntry, AnswerCache
6
+
7
+ CACHE_FILE = "answers_cache.json"
8
+
9
+ def load_cache(cache_path: str = CACHE_FILE) -> AnswerCache:
10
+ if not os.path.exists(cache_path):
11
+ return {}
12
+ with open(cache_path, "r", encoding="utf-8") as f:
13
+ try:
14
+ return json.load(f)
15
+ except json.JSONDecodeError:
16
+ return {}
17
+
18
+ def save_cache(cache: AnswerCache, cache_path: str = CACHE_FILE) -> None:
19
+ with open(cache_path, "w", encoding="utf-8") as f:
20
+ json.dump(cache, f, ensure_ascii=False, indent=2)
21
+
22
+ def cache_answers(questions, cache_path: str = CACHE_FILE) -> AnswerCache:
23
+ """
24
+ Initializes the cache with all answers as incorrect.
25
+ Structure: { task_id: { answer: '', isCorrect: False } }
26
+ """
27
+ cache: AnswerCache = {}
28
+ for q in questions:
29
+ task_id = q.get("task_id")
30
+ if task_id:
31
+ cache[task_id] = {"answer": "", "isCorrect": False}
32
+ save_cache(cache, cache_path)
33
+ return cache
34
+
35
+ def update_cache_answer(task_id: str, answer: str, is_correct: bool = False, cache_path: str = CACHE_FILE):
36
+ cache = load_cache(cache_path)
37
+ cache[task_id] = {"answer": answer, "isCorrect": is_correct}
38
+ save_cache(cache, cache_path)
39
+
40
+
41
+ def get_cached_answer(task_id: str, cache_path: str = CACHE_FILE) -> Optional[AnswerCacheEntry]:
42
+ cache = load_cache(cache_path)
43
+ return cache.get(task_id)