Spaces:
Sleeping
Sleeping
File size: 9,026 Bytes
1b6fe24 d28cecd 1b6fe24 76fbff7 1b6fe24 76fbff7 1b6fe24 76fbff7 1b6fe24 76fbff7 1b6fe24 76fbff7 1b6fe24 76fbff7 d28cecd 76fbff7 1b6fe24 76fbff7 1b6fe24 76fbff7 1b6fe24 76fbff7 1b6fe24 76fbff7 1b6fe24 76fbff7 1b6fe24 76fbff7 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 |
from smolagents import CodeAgent, DuckDuckGoSearchTool, Tool, HfApiModel
import os
from dotenv import load_dotenv
import requests
load_dotenv()
HF_TOKEN = os.getenv("HF_TOKEN")
NOODLE_PUBLIC_API_URL = os.getenv("NOODLE_PUBLIC_API_URL")
class FileWriteTool(Tool):
name = "file_write_tool"
description = """
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.
"""
inputs = {
"file_location": {
"type": "string",
"description": "The location of the file that will be written to. Please put this in the /ai-code directory."
},
"new_code": {
"type": "string",
"description": "This is the content of the file."
}
}
output_type = "string"
def forward(self,file_location, new_code) -> str:
with open(file_location, "w") as file:
return file.write(new_code)
class GetImageDimensionsTool(Tool):
name = "get_image_dimensions_tool"
description= """
This tool is used to get the width and height of a webp file.
"""
inputs = {
"file_location": {
"type": "string",
"description": "The location in which the webp file can be located"
}
}
output_type = "object"
def forward(self, file_location) -> dict:
from PIL import Image
with Image.open(file_location) as img:
width, height = img.size
return {"width": width, "height": height}
class ProcessFlowIdentifierTool(Tool):
name = "process_flow_identifier_tool"
description = """
This tool will be used to give a set of instructions depending on the purpose of the prompt. This is to aid the LLM in its decision making process.
"""
inputs = {
"prompt_objective": {
"type": "string",
"description": "This is the objective of the user's original prompt to help identify the steps needed for the llm to take."
}
}
output_type = "string"
def forward(self, prompt_objective) -> str:
match prompt_objective:
case "asset_change":
instructions = """
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.
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.
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.
4) End process after sucessfully modifying the file
"""
return instructions
case "read_file":
instructions = """
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.
2) Use the read_file_tool to read the file contents of the file from step 1.
3) End process after reading the file.
"""
return instructions
case "script_change":
instructions = """
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.
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.
3) Based on the prompt, make changes to the code from step 2 and use the update_game_file_tool.
4) End process after sucessfully modifying the file
"""
return instructions
case "conversation":
"""
1) Reply to the user with the last message they sent as a friendly ai agent.
2) Do not use any tools to modify files.
3) End process after replying to the user.
"""
case _:
instructions = """
inform user that the instructions where unclear
"""
return instructions
class GitPushTool(Tool):
name = "git_push_tool"
description = """
This tool will be triggered to create a new branch and push new changes to the repository.
"""
inputs = {
"branch_name": {
"type": "string",
"description": "the target branch that will be pushed, new or existing."
}
}
output_type = "string"
def forward(self, branch_name) -> str:
import os
import subprocess
try:
gitUsername = os.getenv("GIT_USERNAME")
gitEmail = os.getenv("GIT_EMAIL")
# new_branch = "add-generated-image-2"
# Step 1: Ensure we are in a Git repository
subprocess.run(["git", "status"], check=True)
# Step 2: Create and switch to a new branch
subprocess.run(["git", "checkout", "-b", branch_name], check=True)
print(f"Checked out to new branch: {branch_name}")
# Step 3: Add the changes
subprocess.run(["git", "add", "*"], check=True)
print("Changes added to staging.")
# Step 4: Add credentials
subprocess.run(["git", "config", "--global", "user.email", gitEmail], check=True)
print("Updated git email.")
subprocess.run(["git", "config", "--global", "user.name", gitUsername], check=True)
print("Updated git user name.")
# Step 5: Commit the changes
commit_message = "Add generated image to repository"
subprocess.run(["git", "commit", "-m", commit_message], check=True)
print("Changes committed.")
#Step 6: Push the branch to the remote repository
subprocess.run(["git", "push", "--set-upstream", "origin", branch_name], check=True)
return print(f"Branch '{branch_name}' pushed to remote repository.")
except subprocess.CalledProcessError as e:
return print(f"An error occurred while performing Git operations: {e}")
# READ
class GetGameFileNamesTool(Tool):
name="get_game_file_names_tool"
description="""
Use this tool to get the game directories of files related to the game. The output of this is an array of file paths.
Return only the array of file paths returned by the api call.
"""
inputs = {}
output_type = "string"
def forward(self) -> str:
get_files_api = NOODLE_PUBLIC_API_URL + "/api/files/"
response = requests.get(get_files_api)
if response.status_code == 200:
print(response.json()['content'])
else:
print("Failed to get file content")
return response.json()['content']
# UPDATE
class UpdateGameFileTool(Tool):
name = "update_game_file_tool"
description = """
Update the game file via an api by sending the updated code for the nextjs game app to handle.
"""
inputs = {
"file_path": {
"type": "string",
"description": "The path from the game directory to update."
},
"new_content": {
"type": "string",
"description": "The updated code."
}
}
output_type = "string"
def forward(self, file_path: str, new_content: str) -> str:
"""
Make an api call to update the file from a secure api route.
"""
update_file_contents = NOODLE_PUBLIC_API_URL + "/api/files/"
headers = {
"Content-Type": "application/octet-stream"
}
binary_data = new_content.encode("utf-8")
response = requests.put(update_file_contents, params={"path": file_path}, headers=headers, data=binary_data)
if response.status_code == 200:
return
else:
return "Failed to update file contents"
class ReadFilesTool(Tool):
name = "read_file_tool"
description = "Read the file contents of the given game file path."
inputs = {"file_path":{"type":"string","description":"the path to the directory to search in"},}
output_type = "string"
def forward(self, file_path: str) -> str:
"""
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.
"""
read_file_contents = NOODLE_PUBLIC_API_URL + "/api/files/"
response = requests.get(f"{read_file_contents}", params={"path": file_path})
if response.status_code == 200:
return response.json()['content']
else:
return "Failed to read file contents"
return |