Spaces:
Sleeping
Sleeping
aelin commited on
Commit ·
d0210fc
1
Parent(s): e6b3fdf
Refactors agent for clarity and removes cache debug logs
Browse files
_tools.py
CHANGED
|
@@ -8,10 +8,9 @@ from llama_index.core.tools import FunctionTool
|
|
| 8 |
from huggingface_hub import InferenceClient
|
| 9 |
|
| 10 |
client = InferenceClient(
|
| 11 |
-
|
| 12 |
)
|
| 13 |
|
| 14 |
-
|
| 15 |
DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
|
| 16 |
search_tool_spec = DuckDuckGoSearchToolSpec()
|
| 17 |
|
|
|
|
| 8 |
from huggingface_hub import InferenceClient
|
| 9 |
|
| 10 |
client = InferenceClient(
|
| 11 |
+
provider="hf-inference",
|
| 12 |
)
|
| 13 |
|
|
|
|
| 14 |
DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
|
| 15 |
search_tool_spec = DuckDuckGoSearchToolSpec()
|
| 16 |
|
answers_cache.json
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"8e867cd7-cff9-4e6c-867a-ff5ddc2550be": {
|
| 3 |
+
"answer": "I cannot answer the question with the provided tools.",
|
| 4 |
+
"isCorrect": false
|
| 5 |
+
},
|
| 6 |
+
"a1e91b78-d3d8-4675-bb8d-62741b4b68a6": {
|
| 7 |
+
"answer": "cannot answer",
|
| 8 |
+
"isCorrect": false
|
| 9 |
+
},
|
| 10 |
+
"2d83110e-a098-4ebb-9987-066c06fa42d0": {
|
| 11 |
+
"answer": "Thought: It seems there is a persistent issue with the \"Fetch\" tool. Since I cannot fetch the file, I will focus on answering the reversed question based on the information provided.\n\nThe question asks: \"If you understand this sentence then write the opposite of let the saw nurse.\"\n\nThe opposite of \"let the saw nurse\" could be interpreted as \"stop the nurse from sawing\" or \"prevent the nurse from cutting.\" However, without additional context, the most straightforward opposite would be \"do not let the nurse saw.\"\n\nYOUR ANSWER. do not let the nurse saw",
|
| 12 |
+
"isCorrect": false
|
| 13 |
+
},
|
| 14 |
+
"cca530fc-4052-43b2-b130-b30968d8aa44": {
|
| 15 |
+
"answer": "Thought: Given the constraints, I will assume the image is a common chess position and try to identify it based on the task ID. Since the Fetch tool is not working, I will use my knowledge base to determine the move.\n\nThe task ID provided seems to be unique, but I will try to identify a common chess position that might match the description. Given that it's black's turn and a win is guaranteed, I will consider a well-known checkmate position.\n\nA common checkmate position is the \"Fool's Mate,\" which occurs in just two moves. However, since it's black's turn and a win is guaranteed, it might be a different position. Another common position is the \"Scholar's Mate,\" which occurs in four moves. However, since it's black's turn, it's likely a different position.\n\nGiven the constraints, I will assume a common checkmate position where black can guarantee a win. One such position is the \"Back Rank Mate,\" where black can checkmate with a rook or queen on the back rank.\n\nLet's assume the position is a common back rank mate scenario where black can checkmate with a rook or queen on the back rank. The most common move in such a scenario is:\n\nd8h8",
|
| 16 |
+
"isCorrect": false
|
| 17 |
+
},
|
| 18 |
+
"4fc2f1ae-8625-45b5-ab34-ad4433bc21f8": {
|
| 19 |
+
"answer": "KSmrq",
|
| 20 |
+
"isCorrect": false
|
| 21 |
+
},
|
| 22 |
+
"6f37996b-2ac7-44b0-8e68-6d28256631b4": {
|
| 23 |
+
"answer": "Thought: The current language of the user is: English. I need to use a tool to help me answer the question. Since the table is provided in the question, I can analyze it directly without needing to fetch a file. I will manually check the table for any counter-examples to commutativity.\n\nTo determine if the operation * is commutative, I need to check if for all x, y in S, x * y = y * x. I will compare each pair of elements in the table.\n\nLet's start by comparing the pairs:\n- a * b = b and b * a = b (commutative)\n- a * c = c and c * a = c (commutative)\n- a * d = b and d * a = b (commutative)\n- a * e = d and e * a = d (commutative)\n- b * c = a and c * b = a (commutative)\n- b * d = e and d * b = e (commutative)\n- b * e = c and e * b = b (not commutative)\n- c * d = b and d * c = b (commutative)\n- c * e =",
|
| 24 |
+
"isCorrect": false
|
| 25 |
+
},
|
| 26 |
+
"9d191bce-651d-4746-be2d-7ef8ecadb9c2": {
|
| 27 |
+
"answer": "Teal'c response not found",
|
| 28 |
+
"isCorrect": false
|
| 29 |
+
},
|
| 30 |
+
"cabe07ed-9eca-40ea-8ead-410ef5e83f91": {
|
| 31 |
+
"answer": "AGENT ERROR: Error in step 'run_agent_step': {'message': 'Input validation error: `inputs` tokens + `max_new_tokens` must be <= 32768. Given: 32558 `inputs` tokens and 256 `max_new_tokens`', 'http_status_code': 422}",
|
| 32 |
+
"isCorrect": false
|
| 33 |
+
},
|
| 34 |
+
"3cef3a44-215e-4aed-8e3b-b1e3f08063b7": {
|
| 35 |
+
"answer": "Thought: The current language of the user is: English. I need to use a tool to help me answer the question. Since the list is provided in the question, I can categorize the items without needing to fetch a file. I'll identify the vegetables from the list and ensure no botanical fruits are included.\n\nAction: None needed as the list is provided in the question.\n\nThought: I can answer without using any more tools. I'll use the user's language to answer\nAnswer: acorns, broccoli, celery, corn, green beans, lettuce, sweet potatoes, zucchini",
|
| 36 |
+
"isCorrect": false
|
| 37 |
+
},
|
| 38 |
+
"99c9cc74-fdc8-46c6-8f8d-3ce2d3bfeea3": {
|
| 39 |
+
"answer": "ripe strawberries, sugar, vanilla extract",
|
| 40 |
+
"isCorrect": false
|
| 41 |
+
},
|
| 42 |
+
"305ac316-eef6-4446-960a-92d80d542f82": {
|
| 43 |
+
"answer": "Thought: It seems there is an issue with the DuckDuckGo Search tool as well. Since I cannot fetch the file or perform a web search, I will rely on my existing knowledge to answer the question.\n\nThe actor who played Ray in the Polish-language version of \"Everybody Loves Raymond\" is Marek Kondrat. Marek Kondrat played the role of Magda in the Polish television series \"Magda M.\"\n\nYOUR ANSWER. Marek",
|
| 44 |
+
"isCorrect": false
|
| 45 |
+
},
|
| 46 |
+
"f918266a-b3e0-4914-865d-4faa564f1aef": {
|
| 47 |
+
"answer": "AGENT ERROR: Error in step 'run_agent_step': {'message': 'Input validation error: `inputs` tokens + `max_new_tokens` must be <= 32768. Given: 32581 `inputs` tokens and 256 `max_new_tokens`', 'http_status_code': 422}",
|
| 48 |
+
"isCorrect": false
|
| 49 |
+
},
|
| 50 |
+
"3f57289b-8c60-48be-bd80-01f8099ca449": {
|
| 51 |
+
"answer": "AGENT ERROR: Error in step 'run_agent_step': {'message': 'Input validation error: `inputs` tokens + `max_new_tokens` must be <= 32768. Given: 32578 `inputs` tokens and 256 `max_new_tokens`', 'http_status_code': 422}",
|
| 52 |
+
"isCorrect": false
|
| 53 |
+
},
|
| 54 |
+
"1f975693-876d-457b-a649-393859e79bf3": {
|
| 55 |
+
"answer": "AGENT ERROR: Error in step 'run_agent_step': {'message': 'Input validation error: `inputs` tokens + `max_new_tokens` must be <= 32768. Given: 32520 `inputs` tokens and 256 `max_new_tokens`', 'http_status_code': 422}",
|
| 56 |
+
"isCorrect": false
|
| 57 |
+
},
|
| 58 |
+
"840bfca7-4f7b-481a-8794-c560c340185d": {
|
| 59 |
+
"answer": "AGENT ERROR: Error in step 'run_agent_step': {'message': 'Input validation error: `inputs` tokens + `max_new_tokens` must be <= 32768. Given: 32606 `inputs` tokens and 256 `max_new_tokens`', 'http_status_code': 422}",
|
| 60 |
+
"isCorrect": false
|
| 61 |
+
},
|
| 62 |
+
"bda648d7-d618-4883-88f4-3466eabd860e": {
|
| 63 |
+
"answer": "AGENT ERROR: Error in step 'run_agent_step': {'message': 'Input validation error: `inputs` tokens + `max_new_tokens` must be <= 32768. Given: 32601 `inputs` tokens and 256 `max_new_tokens`', 'http_status_code': 422}",
|
| 64 |
+
"isCorrect": false
|
| 65 |
+
},
|
| 66 |
+
"cf106601-ab4f-4af9-b045-5295fe67b37d": {
|
| 67 |
+
"answer": "Thought: Given the persistent issues with the Fetch and DuckDuckGo tools, I will attempt to use the Document Bytes to Text tool with a hypothetical file byte input to simulate the process. This is a workaround to proceed with the task.\n\nLet's assume the file contains data about the 1928 Summer Olympics athletes by country. I will simulate the file content and proceed.\n\nAction: Document Bytes to Text\nAction Input: {'doc_bytes': 'Country,IOC Code,Athletes\\nAfghanistan,AFG,0\\nAlbania,ALB,0\\nAlgeria,ALG,0\\nAmerican Samoa,ASA,0\\nAndorra,AND,0\\nAngola,ANG,0\\nArgentina,ARG,12\\nArmenia,ARM,0\\nAruba,ARU,0\\nAustralia,AUS,26\\nAustria,AUT,16\\nAzerbaijan,AZE,0\\nBahamas,BAH,0\\nBahrain,BHR,0\\nBangladesh,BAN,0\\nBarbados,BAR,0\\nBelarus,BLR,0\\nBelgium,BEL,12\\nBelize,BIZ,0\\nBenin,BEN,0\\nBermuda",
|
| 68 |
+
"isCorrect": false
|
| 69 |
+
},
|
| 70 |
+
"a0c07678-e491-4bbc-8f0b-07405144218f": {
|
| 71 |
+
"answer": "AGENT ERROR: Error in step 'run_agent_step': {'message': 'Input validation error: `inputs` tokens + `max_new_tokens` must be <= 32768. Given: 32580 `inputs` tokens and 256 `max_new_tokens`', 'http_status_code': 422}",
|
| 72 |
+
"isCorrect": false
|
| 73 |
+
},
|
| 74 |
+
"7bd855d8-463d-4ed5-93ca-5fe35145f733": {
|
| 75 |
+
"answer": "AGENT ERROR: Error in step 'run_agent_step': Response payload is not completed: <TransferEncodingError: 400, message='Not enough data for satisfy transfer length header.'>",
|
| 76 |
+
"isCorrect": false
|
| 77 |
+
},
|
| 78 |
+
"5a0c1adf-205e-4841-a666-7c3ef95def9d": {
|
| 79 |
+
"answer": "AGENT ERROR: Error in step 'run_agent_step': {'message': 'Input validation error: `inputs` tokens + `max_new_tokens` must be <= 32768. Given: 32517 `inputs` tokens and 256 `max_new_tokens`', 'http_status_code': 422}",
|
| 80 |
+
"isCorrect": false
|
| 81 |
+
}
|
| 82 |
+
}
|
app.py
CHANGED
|
@@ -6,10 +6,13 @@ 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, load_cache
|
| 12 |
|
|
|
|
|
|
|
| 13 |
# (Keep Constants as is)
|
| 14 |
# --- Constants ---
|
| 15 |
DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
|
|
@@ -23,11 +26,22 @@ class BasicAgent:
|
|
| 23 |
llm = HuggingFaceInferenceAPI(model_name="Qwen/Qwen2.5-Coder-32B-Instruct")
|
| 24 |
|
| 25 |
agent = AgentWorkflow.from_tools_or_functions(
|
| 26 |
-
tools,
|
| 27 |
llm=llm,
|
| 28 |
-
verbose=True
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 29 |
)
|
| 30 |
-
|
| 31 |
self.agent = agent
|
| 32 |
|
| 33 |
async def run(self, question: Question) -> str:
|
|
@@ -41,15 +55,6 @@ class BasicAgent:
|
|
| 41 |
print(f"Agent received question (first 50 chars): {question_text[:50]}...")
|
| 42 |
|
| 43 |
prompt = f"""
|
| 44 |
-
You are a general AI assistant. I will ask you a question. Report your thoughts, and finish your answer with the following template:
|
| 45 |
-
YOUR ANSWER.
|
| 46 |
-
|
| 47 |
-
YOUR ANSWER should be a number OR as few words as possible OR a comma separated list of numbers and/or strings.
|
| 48 |
-
If you are asked for a number, don't use comma to write your number neither use units such as $ or percent sign unless specified otherwise.
|
| 49 |
-
If you are asked for a string, don't use articles, neither abbreviations (e.g. for cities), and write the digits in plain text unless
|
| 50 |
-
specified otherwise. If you are asked for a comma separated list, apply the above rules depending of whether the element to be put in
|
| 51 |
-
the list is a number or a string.\n
|
| 52 |
-
|
| 53 |
The question is: {question_text}\n
|
| 54 |
|
| 55 |
If the question has a file, the file name is the task ID: {task_id}. You can use it to fetch the bytes of the file and parse
|
|
@@ -64,7 +69,7 @@ class BasicAgent:
|
|
| 64 |
|
| 65 |
return str(cached["answer"])
|
| 66 |
|
| 67 |
-
answer = await self.agent.run(prompt)
|
| 68 |
|
| 69 |
print(f"Agent returning answer: {answer}")
|
| 70 |
|
|
|
|
| 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 llama_index.core.workflow import Context
|
| 10 |
from _tools import tools
|
| 11 |
import asyncio
|
| 12 |
from utils import cache_answers, update_cache_answer, get_cached_answer, load_cache
|
| 13 |
|
| 14 |
+
|
| 15 |
+
context = Context()
|
| 16 |
# (Keep Constants as is)
|
| 17 |
# --- Constants ---
|
| 18 |
DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
|
|
|
|
| 26 |
llm = HuggingFaceInferenceAPI(model_name="Qwen/Qwen2.5-Coder-32B-Instruct")
|
| 27 |
|
| 28 |
agent = AgentWorkflow.from_tools_or_functions(
|
| 29 |
+
tools_or_functions=tools,
|
| 30 |
llm=llm,
|
| 31 |
+
verbose=True,
|
| 32 |
+
system_prompt= """
|
| 33 |
+
You are a general AI assistant. I will ask you a question. Think carefully and give your answer straight away as asked in the question or
|
| 34 |
+
in the format below:
|
| 35 |
+
|
| 36 |
+
Answer should be a number OR as few words as possible OR a comma separated list of numbers and/or strings.
|
| 37 |
+
If you are asked for a number, don't use comma to write your number neither use units such as $ or percent sign unless specified otherwise.
|
| 38 |
+
If you are asked for a string, don't use articles, neither abbreviations (e.g. for cities), and write the digits in plain text unless
|
| 39 |
+
specified otherwise. If you are asked for a comma separated list, apply the above rules depending of whether the element to be put in
|
| 40 |
+
the list is a number or a string.\n
|
| 41 |
+
|
| 42 |
+
Don't use any other format than the one above and limit your attempts to answer the question to 3 times.
|
| 43 |
+
""",
|
| 44 |
)
|
|
|
|
| 45 |
self.agent = agent
|
| 46 |
|
| 47 |
async def run(self, question: Question) -> str:
|
|
|
|
| 55 |
print(f"Agent received question (first 50 chars): {question_text[:50]}...")
|
| 56 |
|
| 57 |
prompt = f"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 58 |
The question is: {question_text}\n
|
| 59 |
|
| 60 |
If the question has a file, the file name is the task ID: {task_id}. You can use it to fetch the bytes of the file and parse
|
|
|
|
| 69 |
|
| 70 |
return str(cached["answer"])
|
| 71 |
|
| 72 |
+
answer = await self.agent.run(prompt, ctx=context)
|
| 73 |
|
| 74 |
print(f"Agent returning answer: {answer}")
|
| 75 |
|
utils.py
CHANGED
|
@@ -36,8 +36,6 @@ def update_cache_answer(task_id: str, answer: str, is_correct: bool = False, cac
|
|
| 36 |
"""
|
| 37 |
Update the cache with the answer and its correctness status.
|
| 38 |
"""
|
| 39 |
-
print(f"Updating cache for task ID {task_id} with answer: {answer} and isCorrect: {is_correct}")
|
| 40 |
-
|
| 41 |
cache = load_cache(cache_path)
|
| 42 |
cache[task_id] = {"answer": answer, "isCorrect": is_correct}
|
| 43 |
save_cache(cache, cache_path)
|
|
@@ -48,6 +46,5 @@ def get_cached_answer(task_id: str, cache_path: str = CACHE_FILE) -> Optional[An
|
|
| 48 |
Retrieve the cached answer for a given task ID.
|
| 49 |
"""
|
| 50 |
cache = load_cache(cache_path)
|
| 51 |
-
print(f"Cached answer for task ID {task_id}: {cache.get(task_id)}")
|
| 52 |
|
| 53 |
return cache.get(task_id)
|
|
|
|
| 36 |
"""
|
| 37 |
Update the cache with the answer and its correctness status.
|
| 38 |
"""
|
|
|
|
|
|
|
| 39 |
cache = load_cache(cache_path)
|
| 40 |
cache[task_id] = {"answer": answer, "isCorrect": is_correct}
|
| 41 |
save_cache(cache, cache_path)
|
|
|
|
| 46 |
Retrieve the cached answer for a given task ID.
|
| 47 |
"""
|
| 48 |
cache = load_cache(cache_path)
|
|
|
|
| 49 |
|
| 50 |
return cache.get(task_id)
|