Spaces:
Sleeping
Sleeping
Updated python code to be able to update vercel code
Browse files
smol.py
CHANGED
|
@@ -3,7 +3,7 @@ import shutil
|
|
| 3 |
|
| 4 |
from smolagents import CodeAgent, DuckDuckGoSearchTool, Tool, HfApiModel
|
| 5 |
from dotenv import load_dotenv, dotenv_values
|
| 6 |
-
from tool import GetGameFileNamesTool,
|
| 7 |
|
| 8 |
load_dotenv()
|
| 9 |
|
|
@@ -29,19 +29,21 @@ step 5: upload changes to github
|
|
| 29 |
"""
|
| 30 |
|
| 31 |
get_game_file_names_tool = GetGameFileNamesTool()
|
| 32 |
-
|
| 33 |
-
file_replace_tool = FileReplaceTool()
|
| 34 |
process_identifier_tool= ProcessFlowIdentifierTool()
|
| 35 |
get_image_dimensions_tool= GetImageDimensionsTool()
|
| 36 |
-
|
|
|
|
|
|
|
| 37 |
|
| 38 |
def ChatAgent(userPrompt):
|
| 39 |
#Identify purpose of prompt
|
| 40 |
promptCleanerAgent = CodeAgent(tools=[], model=model)
|
| 41 |
|
| 42 |
instructions = promptCleanerAgent.run(f"""
|
| 43 |
-
determine the purpose of the following string "{userPrompt}" if it is one of the following: [asset_change, script_update, conversation].
|
| 44 |
-
asset_change: The user wants to change an asset
|
|
|
|
| 45 |
script_update: The user wants to update the game script.
|
| 46 |
conversation: The user wants to have a conversation with the AI by asking general questions or greetings.
|
| 47 |
""")
|
|
@@ -63,7 +65,7 @@ def ChatAgent(userPrompt):
|
|
| 63 |
else:
|
| 64 |
contextPrompt = f'using process_identifier_tool look for the appropriate instructions for "{instructions}" and apply it to the user prompt after this'
|
| 65 |
|
| 66 |
-
agent = CodeAgent(tools=[get_game_file_names_tool,
|
| 67 |
|
| 68 |
if instructions == "conversation":
|
| 69 |
response = agent.run(f"{contextPrompt}")
|
|
|
|
| 3 |
|
| 4 |
from smolagents import CodeAgent, DuckDuckGoSearchTool, Tool, HfApiModel
|
| 5 |
from dotenv import load_dotenv, dotenv_values
|
| 6 |
+
from tool import GetGameFileNamesTool, ReadFilesTool, UpdateGameFileTool, GitPushTool, ProcessFlowIdentifierTool, GetImageDimensionsTool
|
| 7 |
|
| 8 |
load_dotenv()
|
| 9 |
|
|
|
|
| 29 |
"""
|
| 30 |
|
| 31 |
get_game_file_names_tool = GetGameFileNamesTool()
|
| 32 |
+
read_files_tool = ReadFilesTool()
|
|
|
|
| 33 |
process_identifier_tool= ProcessFlowIdentifierTool()
|
| 34 |
get_image_dimensions_tool= GetImageDimensionsTool()
|
| 35 |
+
update_game_file_tool = UpdateGameFileTool()
|
| 36 |
+
# file_replace_tool = FileReplaceTool()
|
| 37 |
+
# file_modify_tool = FileModifyTool()
|
| 38 |
|
| 39 |
def ChatAgent(userPrompt):
|
| 40 |
#Identify purpose of prompt
|
| 41 |
promptCleanerAgent = CodeAgent(tools=[], model=model)
|
| 42 |
|
| 43 |
instructions = promptCleanerAgent.run(f"""
|
| 44 |
+
determine the purpose of the following string "{userPrompt}" if it is one of the following: [asset_change, read_file, script_update, conversation].
|
| 45 |
+
asset_change: The user wants to change an asset from the game.
|
| 46 |
+
read_file: The user wants to read a file from the game.
|
| 47 |
script_update: The user wants to update the game script.
|
| 48 |
conversation: The user wants to have a conversation with the AI by asking general questions or greetings.
|
| 49 |
""")
|
|
|
|
| 65 |
else:
|
| 66 |
contextPrompt = f'using process_identifier_tool look for the appropriate instructions for "{instructions}" and apply it to the user prompt after this'
|
| 67 |
|
| 68 |
+
agent = CodeAgent(tools=[get_game_file_names_tool, read_files_tool, update_game_file_tool, process_identifier_tool, image_generation_tool, get_image_dimensions_tool], model=model)
|
| 69 |
|
| 70 |
if instructions == "conversation":
|
| 71 |
response = agent.run(f"{contextPrompt}")
|
tool.py
CHANGED
|
@@ -8,36 +8,20 @@ load_dotenv()
|
|
| 8 |
HF_TOKEN = os.getenv("HF_TOKEN")
|
| 9 |
NOODLE_PUBLIC_API_URL = os.getenv("NOODLE_PUBLIC_API_URL")
|
| 10 |
|
| 11 |
-
class FileReaderTool(Tool):
|
| 12 |
-
name = "file_reader_tool"
|
| 13 |
-
description = """
|
| 14 |
-
This tool will be used by the LLM Agent to read files to help analyze files for its task.
|
| 15 |
-
"""
|
| 16 |
-
inputs = {
|
| 17 |
-
"file_location": {
|
| 18 |
-
"type": "string",
|
| 19 |
-
"description": "The location of the file that will be read/analyzed"
|
| 20 |
-
}
|
| 21 |
-
}
|
| 22 |
-
output_type = "string"
|
| 23 |
-
|
| 24 |
-
def forward(self,file_location ) -> str:
|
| 25 |
-
with open(file_location, "r") as file:
|
| 26 |
-
return file.read()
|
| 27 |
|
| 28 |
class FileWriteTool(Tool):
|
| 29 |
name = "file_write_tool"
|
| 30 |
description = """
|
| 31 |
-
This tool will be used by the LLM Agent to
|
| 32 |
"""
|
| 33 |
inputs = {
|
| 34 |
"file_location": {
|
| 35 |
"type": "string",
|
| 36 |
-
"description": "The location of the file that will be
|
| 37 |
},
|
| 38 |
"new_code": {
|
| 39 |
"type": "string",
|
| 40 |
-
"description": "This is the
|
| 41 |
}
|
| 42 |
}
|
| 43 |
output_type = "string"
|
|
@@ -46,73 +30,6 @@ class FileWriteTool(Tool):
|
|
| 46 |
with open(file_location, "w") as file:
|
| 47 |
return file.write(new_code)
|
| 48 |
|
| 49 |
-
class FileModifyTool(Tool):
|
| 50 |
-
name = "file_modify_tool"
|
| 51 |
-
description = """
|
| 52 |
-
This tool will be used by the LLM Agent to modify files if needed for task.
|
| 53 |
-
"""
|
| 54 |
-
inputs = {
|
| 55 |
-
"file_location": {
|
| 56 |
-
"type": "string",
|
| 57 |
-
"description": "The location of the file that will be read/analyzed"
|
| 58 |
-
},
|
| 59 |
-
"prompt": {
|
| 60 |
-
"type": "string",
|
| 61 |
-
"description": "This is the prompt that the LLM will use to decide how to modify the code."
|
| 62 |
-
}
|
| 63 |
-
}
|
| 64 |
-
output_type = "string"
|
| 65 |
-
|
| 66 |
-
def forward(self,file_location, prompt) -> str:
|
| 67 |
-
file_reader_tool = FileReaderTool()
|
| 68 |
-
file_write_tool = FileWriteTool()
|
| 69 |
-
|
| 70 |
-
model = HfApiModel("Qwen/Qwen2.5-Coder-32B-Instruct", token=HF_TOKEN)
|
| 71 |
-
coderAgent = CodeAgent(tools=[], model=model)
|
| 72 |
-
|
| 73 |
-
file_content = file_reader_tool.forward(file_location)
|
| 74 |
-
|
| 75 |
-
if not file_content:
|
| 76 |
-
return "Error: File could not be read."
|
| 77 |
-
|
| 78 |
-
modified_code = coderAgent.run(f'Based on the prompt "{prompt}" \n Modify the following code:\n{file_content}\n')
|
| 79 |
-
if "ERROR" in modified_code:
|
| 80 |
-
return "Modification failed, please refine your request."
|
| 81 |
-
write_result = file_write_tool.forward(file_location, modified_code)
|
| 82 |
-
return
|
| 83 |
-
|
| 84 |
-
|
| 85 |
-
|
| 86 |
-
class FileReplaceTool(Tool):
|
| 87 |
-
name = "file_replace_tool"
|
| 88 |
-
description ="""
|
| 89 |
-
This tool will be used to replace the file in a given location with the provided new file location. This is not used to update files.
|
| 90 |
-
"""
|
| 91 |
-
inputs = {
|
| 92 |
-
"target_file_location": {
|
| 93 |
-
"type": "string",
|
| 94 |
-
"description": "the location of the file that will be replaced"
|
| 95 |
-
},
|
| 96 |
-
"new_file_location": {
|
| 97 |
-
"type": "string",
|
| 98 |
-
"description": "the location of the new file to replace target file location"
|
| 99 |
-
}
|
| 100 |
-
}
|
| 101 |
-
output_type = "string"
|
| 102 |
-
def forward(self, target_file_location, new_file_location) -> str:
|
| 103 |
-
import os
|
| 104 |
-
import shutil
|
| 105 |
-
|
| 106 |
-
if os.path.exists(new_file_location):
|
| 107 |
-
# Define the destination path for the saved image
|
| 108 |
-
# # Create the './generatedImages' directory if it doesn't exist
|
| 109 |
-
# # Copy the image from the temporary location to the desired directory
|
| 110 |
-
shutil.copy(new_file_location, target_file_location)
|
| 111 |
-
|
| 112 |
-
return print(f"Image saved to {target_file_location}")
|
| 113 |
-
else:
|
| 114 |
-
return print("Failed to generate an image or the file does not exist.")
|
| 115 |
-
|
| 116 |
class GetImageDimensionsTool(Tool):
|
| 117 |
name = "get_image_dimensions_tool"
|
| 118 |
description= """
|
|
@@ -149,16 +66,25 @@ class ProcessFlowIdentifierTool(Tool):
|
|
| 149 |
match prompt_objective:
|
| 150 |
case "asset_change":
|
| 151 |
instructions = """
|
| 152 |
-
1) use the
|
| 153 |
-
2) Use the
|
| 154 |
-
3)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 155 |
"""
|
| 156 |
return instructions
|
| 157 |
case "script_change":
|
| 158 |
instructions = """
|
| 159 |
-
1) use the
|
| 160 |
-
2) Use the
|
| 161 |
-
3)
|
|
|
|
| 162 |
"""
|
| 163 |
return instructions
|
| 164 |
case "conversation":
|
|
@@ -221,6 +147,7 @@ class GitPushTool(Tool):
|
|
| 221 |
except subprocess.CalledProcessError as e:
|
| 222 |
return print(f"An error occurred while performing Git operations: {e}")
|
| 223 |
|
|
|
|
| 224 |
class GetGameFileNamesTool(Tool):
|
| 225 |
name="get_game_file_names_tool"
|
| 226 |
description="""
|
|
@@ -238,33 +165,56 @@ class GetGameFileNamesTool(Tool):
|
|
| 238 |
else:
|
| 239 |
print("Failed to get file content")
|
| 240 |
return response.json()['content']
|
| 241 |
-
|
| 242 |
|
| 243 |
-
|
| 244 |
-
|
| 245 |
-
|
| 246 |
-
|
| 247 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 248 |
output_type = "string"
|
| 249 |
|
| 250 |
-
def forward(self,
|
| 251 |
"""
|
| 252 |
-
|
| 253 |
-
|
| 254 |
-
Args:
|
| 255 |
-
extension: The file extension to look for (e.g., '.txt')
|
| 256 |
"""
|
| 257 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 258 |
|
| 259 |
-
|
| 260 |
-
|
|
|
|
|
|
|
|
|
|
| 261 |
|
| 262 |
-
|
| 263 |
-
|
| 264 |
-
|
| 265 |
-
|
| 266 |
-
|
| 267 |
-
|
| 268 |
-
found_files.append(absolute_path)
|
| 269 |
|
| 270 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8 |
HF_TOKEN = os.getenv("HF_TOKEN")
|
| 9 |
NOODLE_PUBLIC_API_URL = os.getenv("NOODLE_PUBLIC_API_URL")
|
| 10 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 11 |
|
| 12 |
class FileWriteTool(Tool):
|
| 13 |
name = "file_write_tool"
|
| 14 |
description = """
|
| 15 |
+
This tool will be used by the LLM Agent to create files if needed for task. Always put the files in the /ai-code directory from the root of this project.
|
| 16 |
"""
|
| 17 |
inputs = {
|
| 18 |
"file_location": {
|
| 19 |
"type": "string",
|
| 20 |
+
"description": "The location of the file that will be written to. Please put this in the /ai-code directory."
|
| 21 |
},
|
| 22 |
"new_code": {
|
| 23 |
"type": "string",
|
| 24 |
+
"description": "This is the content of the file."
|
| 25 |
}
|
| 26 |
}
|
| 27 |
output_type = "string"
|
|
|
|
| 30 |
with open(file_location, "w") as file:
|
| 31 |
return file.write(new_code)
|
| 32 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 33 |
class GetImageDimensionsTool(Tool):
|
| 34 |
name = "get_image_dimensions_tool"
|
| 35 |
description= """
|
|
|
|
| 66 |
match prompt_objective:
|
| 67 |
case "asset_change":
|
| 68 |
instructions = """
|
| 69 |
+
1) use the get_game_file_names_tool to get the list of accessible game files. If user specifies what file, do this still to check if they can access it.
|
| 70 |
+
2) Use the read_file_tool to read the file contents of the file from step 1. Remember to save the path of the file, this will be used to update the file.
|
| 71 |
+
3) Based on the prompt, make changes to the code from step 2 and pass it to the update_game_file_tool along with the path saved from step1.
|
| 72 |
+
4) End process after sucessfully modifying the file
|
| 73 |
+
"""
|
| 74 |
+
return instructions
|
| 75 |
+
case "read_file":
|
| 76 |
+
instructions = """
|
| 77 |
+
1) use the get_game_file_names_tool to get the list of accessible game files. If user specifies what file, do this still to check if they can access it.
|
| 78 |
+
2) Use the read_file_tool to read the file contents of the file from step 1.
|
| 79 |
+
3) End process after reading the file.
|
| 80 |
"""
|
| 81 |
return instructions
|
| 82 |
case "script_change":
|
| 83 |
instructions = """
|
| 84 |
+
1) use the get_game_file_names_tool to get the list of accessible game files. If user specifies what file, do this still to check if they can access it.
|
| 85 |
+
2) Use the read_file_tool to read the file contents of the file from step 1. Remember to save the path of the file, this will be used to update the file.
|
| 86 |
+
3) Based on the prompt, make changes to the code from step 2 and use the update_game_file_tool.
|
| 87 |
+
4) End process after sucessfully modifying the file
|
| 88 |
"""
|
| 89 |
return instructions
|
| 90 |
case "conversation":
|
|
|
|
| 147 |
except subprocess.CalledProcessError as e:
|
| 148 |
return print(f"An error occurred while performing Git operations: {e}")
|
| 149 |
|
| 150 |
+
# READ
|
| 151 |
class GetGameFileNamesTool(Tool):
|
| 152 |
name="get_game_file_names_tool"
|
| 153 |
description="""
|
|
|
|
| 165 |
else:
|
| 166 |
print("Failed to get file content")
|
| 167 |
return response.json()['content']
|
|
|
|
| 168 |
|
| 169 |
+
# UPDATE
|
| 170 |
+
class UpdateGameFileTool(Tool):
|
| 171 |
+
name = "update_game_file_tool"
|
| 172 |
+
description = """
|
| 173 |
+
Update the game file via an api by sending the updated code for the nextjs game app to handle.
|
| 174 |
+
"""
|
| 175 |
+
inputs = {
|
| 176 |
+
"file_path": {
|
| 177 |
+
"type": "string",
|
| 178 |
+
"description": "The path from the game directory to update."
|
| 179 |
+
},
|
| 180 |
+
"new_content": {
|
| 181 |
+
"type": "string",
|
| 182 |
+
"description": "The updated code."
|
| 183 |
+
}
|
| 184 |
+
}
|
| 185 |
output_type = "string"
|
| 186 |
|
| 187 |
+
def forward(self, file_path: str, new_content: str) -> str:
|
| 188 |
"""
|
| 189 |
+
Make an api call to update the file from a secure api route.
|
|
|
|
|
|
|
|
|
|
| 190 |
"""
|
| 191 |
+
update_file_contents = NOODLE_PUBLIC_API_URL + "/api/files/"
|
| 192 |
+
headers = {
|
| 193 |
+
"Content-Type": "application/octet-stream"
|
| 194 |
+
}
|
| 195 |
+
binary_data = new_content.encode("utf-8")
|
| 196 |
|
| 197 |
+
response = requests.put(update_file_contents, params={"path": file_path}, headers=headers, data=binary_data)
|
| 198 |
+
if response.status_code == 200:
|
| 199 |
+
return
|
| 200 |
+
else:
|
| 201 |
+
return "Failed to update file contents"
|
| 202 |
|
| 203 |
+
class ReadFilesTool(Tool):
|
| 204 |
+
name = "read_file_tool"
|
| 205 |
+
description = "Read the file contents of the given game file path."
|
| 206 |
+
inputs = {"file_path":{"type":"string","description":"the path to the directory to search in"},}
|
| 207 |
+
|
| 208 |
+
output_type = "string"
|
|
|
|
| 209 |
|
| 210 |
+
def forward(self, file_path: str) -> str:
|
| 211 |
+
"""
|
| 212 |
+
Make an api call to browse the file from the game through an api call. The file path must be passed to view the file.
|
| 213 |
+
"""
|
| 214 |
+
read_file_contents = NOODLE_PUBLIC_API_URL + "/api/files/"
|
| 215 |
+
response = requests.get(f"{read_file_contents}", params={"path": file_path})
|
| 216 |
+
if response.status_code == 200:
|
| 217 |
+
return response.json()['content']
|
| 218 |
+
else:
|
| 219 |
+
return "Failed to read file contents"
|
| 220 |
+
return
|