Spaces:
Runtime error
Runtime error
Commit
·
6b8dbdd
1
Parent(s):
f326b43
Change to user-provided API keys
Browse files- app.py +24 -49
- opentools/engine/openai.py +3 -2
- opentools/models/executor.py +9 -6
- opentools/models/initializer.py +9 -4
- opentools/models/planner.py +7 -15
- opentools/models/utlis.py +0 -73
- opentools/setup.py +0 -20
- opentools/tools/generalist_solution_generator/tool.py +4 -2
- setup.py +0 -20
app.py
CHANGED
|
@@ -18,9 +18,7 @@ from opentools.models.initializer import Initializer
|
|
| 18 |
from opentools.models.planner import Planner
|
| 19 |
from opentools.models.memory import Memory
|
| 20 |
from opentools.models.executor import Executor
|
| 21 |
-
from opentools.models.
|
| 22 |
-
|
| 23 |
-
solver = None
|
| 24 |
|
| 25 |
class ChatMessage:
|
| 26 |
def __init__(self, role: str, content: str, metadata: dict = None):
|
|
@@ -63,7 +61,7 @@ class Solver:
|
|
| 63 |
|
| 64 |
|
| 65 |
|
| 66 |
-
def stream_solve_user_problem(self, user_query: str, user_image: Image.Image, messages: List[ChatMessage]) -> Iterator[List[ChatMessage]]:
|
| 67 |
"""
|
| 68 |
Streams intermediate thoughts and final responses for the problem-solving process based on user input.
|
| 69 |
|
|
@@ -198,39 +196,28 @@ def parse_arguments():
|
|
| 198 |
return parser.parse_args()
|
| 199 |
|
| 200 |
|
| 201 |
-
def solve_problem_gradio(user_query, user_image):
|
| 202 |
"""
|
| 203 |
Wrapper function to connect the solver to Gradio.
|
| 204 |
Streams responses from `solver.stream_solve_user_problem` for real-time UI updates.
|
| 205 |
"""
|
| 206 |
-
|
| 207 |
-
|
| 208 |
-
if solver is None:
|
| 209 |
-
return [["assistant", "⚠️ Error: Solver is not initialized. Please restart the application."]]
|
| 210 |
-
|
| 211 |
-
messages = [] # Initialize message list
|
| 212 |
-
for message_batch in solver.stream_solve_user_problem(user_query, user_image, messages):
|
| 213 |
-
yield [[msg.role, msg.content] for msg in message_batch] # Ensure correct format for Gradio Chatbot
|
| 214 |
-
|
| 215 |
-
|
| 216 |
-
|
| 217 |
-
def main(args):
|
| 218 |
-
global solver
|
| 219 |
# Initialize Tools
|
| 220 |
enabled_tools = args.enabled_tools.split(",") if args.enabled_tools else []
|
| 221 |
|
| 222 |
-
|
| 223 |
# Instantiate Initializer
|
| 224 |
initializer = Initializer(
|
| 225 |
enabled_tools=enabled_tools,
|
| 226 |
-
model_string=args.llm_engine_name
|
|
|
|
| 227 |
)
|
| 228 |
|
| 229 |
# Instantiate Planner
|
| 230 |
planner = Planner(
|
| 231 |
llm_engine_name=args.llm_engine_name,
|
| 232 |
toolbox_metadata=initializer.toolbox_metadata,
|
| 233 |
-
available_tools=initializer.available_tools
|
|
|
|
| 234 |
)
|
| 235 |
|
| 236 |
# Instantiate Memory
|
|
@@ -240,7 +227,8 @@ def main(args):
|
|
| 240 |
executor = Executor(
|
| 241 |
llm_engine_name=args.llm_engine_name,
|
| 242 |
root_cache_dir=args.root_cache_dir,
|
| 243 |
-
enable_signal=False
|
|
|
|
| 244 |
)
|
| 245 |
|
| 246 |
# Instantiate Solver
|
|
@@ -258,44 +246,31 @@ def main(args):
|
|
| 258 |
root_cache_dir=args.root_cache_dir
|
| 259 |
)
|
| 260 |
|
| 261 |
-
|
| 262 |
-
|
| 263 |
-
# user_image_path = "/home/sheng/toolbox-agent/mathvista_113.png" # Replace with your actual image path
|
| 264 |
-
|
| 265 |
-
# # Load the image as a PIL object
|
| 266 |
-
# user_image = Image.open(user_image_path).convert("RGB") # Ensure it's in RGB mode
|
| 267 |
-
|
| 268 |
-
# print("\n=== Starting Problem Solving ===\n")
|
| 269 |
-
# messages = []
|
| 270 |
-
# for message_batch in solver.stream_solve_user_problem(user_query, user_image, messages):
|
| 271 |
-
# for message in message_batch:
|
| 272 |
-
# print(f"{message.role}: {message.content}")
|
| 273 |
-
|
| 274 |
-
# messages = []
|
| 275 |
-
# solver.stream_solve_user_problem(user_query, user_image, messages)
|
| 276 |
-
|
| 277 |
|
| 278 |
-
#
|
| 279 |
-
|
|
|
|
| 280 |
|
| 281 |
-
# for message_batch in solver.stream_solve_user_problem(user_query, user_image, messages):
|
| 282 |
-
# yield message_batch # Stream messages correctly in tuple format
|
| 283 |
|
| 284 |
-
# solve_problem_stream(user_query, user_image)
|
| 285 |
|
|
|
|
| 286 |
# ========== Gradio Interface ==========
|
| 287 |
with gr.Blocks() as demo:
|
| 288 |
gr.Markdown("# 🧠 OctoTools AI Solver") # Title
|
| 289 |
|
| 290 |
with gr.Row():
|
| 291 |
-
|
| 292 |
-
|
| 293 |
-
|
| 294 |
-
|
| 295 |
-
|
|
|
|
|
|
|
| 296 |
|
| 297 |
# Link button click to function
|
| 298 |
-
run_button.click(fn=solve_problem_gradio, inputs=[user_query, user_image], outputs=chatbot_output)
|
| 299 |
|
| 300 |
# Launch the Gradio app
|
| 301 |
demo.launch()
|
|
|
|
| 18 |
from opentools.models.planner import Planner
|
| 19 |
from opentools.models.memory import Memory
|
| 20 |
from opentools.models.executor import Executor
|
| 21 |
+
from opentools.models.utils import make_json_serializable
|
|
|
|
|
|
|
| 22 |
|
| 23 |
class ChatMessage:
|
| 24 |
def __init__(self, role: str, content: str, metadata: dict = None):
|
|
|
|
| 61 |
|
| 62 |
|
| 63 |
|
| 64 |
+
def stream_solve_user_problem(self, user_query: str, user_image: Image.Image, api_key: str, messages: List[ChatMessage]) -> Iterator[List[ChatMessage]]:
|
| 65 |
"""
|
| 66 |
Streams intermediate thoughts and final responses for the problem-solving process based on user input.
|
| 67 |
|
|
|
|
| 196 |
return parser.parse_args()
|
| 197 |
|
| 198 |
|
| 199 |
+
def solve_problem_gradio(user_query, user_image, api_key):
|
| 200 |
"""
|
| 201 |
Wrapper function to connect the solver to Gradio.
|
| 202 |
Streams responses from `solver.stream_solve_user_problem` for real-time UI updates.
|
| 203 |
"""
|
| 204 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 205 |
# Initialize Tools
|
| 206 |
enabled_tools = args.enabled_tools.split(",") if args.enabled_tools else []
|
| 207 |
|
|
|
|
| 208 |
# Instantiate Initializer
|
| 209 |
initializer = Initializer(
|
| 210 |
enabled_tools=enabled_tools,
|
| 211 |
+
model_string=args.llm_engine_name,
|
| 212 |
+
api_key=api_key
|
| 213 |
)
|
| 214 |
|
| 215 |
# Instantiate Planner
|
| 216 |
planner = Planner(
|
| 217 |
llm_engine_name=args.llm_engine_name,
|
| 218 |
toolbox_metadata=initializer.toolbox_metadata,
|
| 219 |
+
available_tools=initializer.available_tools,
|
| 220 |
+
api_key=api_key
|
| 221 |
)
|
| 222 |
|
| 223 |
# Instantiate Memory
|
|
|
|
| 227 |
executor = Executor(
|
| 228 |
llm_engine_name=args.llm_engine_name,
|
| 229 |
root_cache_dir=args.root_cache_dir,
|
| 230 |
+
enable_signal=False,
|
| 231 |
+
api_key=api_key
|
| 232 |
)
|
| 233 |
|
| 234 |
# Instantiate Solver
|
|
|
|
| 246 |
root_cache_dir=args.root_cache_dir
|
| 247 |
)
|
| 248 |
|
| 249 |
+
if solver is None:
|
| 250 |
+
return [["assistant", "⚠️ Error: Solver is not initialized. Please restart the application."]]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 251 |
|
| 252 |
+
messages = [] # Initialize message list
|
| 253 |
+
for message_batch in solver.stream_solve_user_problem(user_query, user_image, api_key, messages):
|
| 254 |
+
yield [[msg.role, msg.content] for msg in message_batch] # Ensure correct format for Gradio Chatbot
|
| 255 |
|
|
|
|
|
|
|
| 256 |
|
|
|
|
| 257 |
|
| 258 |
+
def main(args):
|
| 259 |
# ========== Gradio Interface ==========
|
| 260 |
with gr.Blocks() as demo:
|
| 261 |
gr.Markdown("# 🧠 OctoTools AI Solver") # Title
|
| 262 |
|
| 263 |
with gr.Row():
|
| 264 |
+
with gr.Column(scale=1, min_width=300):
|
| 265 |
+
user_query = gr.Textbox(label="Enter your query", placeholder="Type your question here...")
|
| 266 |
+
api_key = gr.Textbox(label="API Key", placeholder="Your API key will not be stored in any way.", type="password")
|
| 267 |
+
user_image = gr.Image(type="pil", label="Upload an image") # Accepts multiple formats
|
| 268 |
+
run_button = gr.Button("Run") # Run button
|
| 269 |
+
with gr.Column(scale=3, min_width=300):
|
| 270 |
+
chatbot_output = gr.Chatbot(label="Problem-Solving Output")
|
| 271 |
|
| 272 |
# Link button click to function
|
| 273 |
+
run_button.click(fn=solve_problem_gradio, inputs=[user_query, user_image, api_key], outputs=chatbot_output)
|
| 274 |
|
| 275 |
# Launch the Gradio app
|
| 276 |
demo.launch()
|
opentools/engine/openai.py
CHANGED
|
@@ -43,6 +43,7 @@ class ChatOpenAI(EngineLM, CachedEngine):
|
|
| 43 |
is_multimodal: bool=False,
|
| 44 |
# enable_cache: bool=True,
|
| 45 |
enable_cache: bool=False, # NOTE: disable cache for now
|
|
|
|
| 46 |
**kwargs):
|
| 47 |
"""
|
| 48 |
:param model_string:
|
|
@@ -61,11 +62,11 @@ class ChatOpenAI(EngineLM, CachedEngine):
|
|
| 61 |
super().__init__(cache_path=cache_path)
|
| 62 |
|
| 63 |
self.system_prompt = system_prompt
|
| 64 |
-
if
|
| 65 |
raise ValueError("Please set the OPENAI_API_KEY environment variable if you'd like to use OpenAI models.")
|
| 66 |
|
| 67 |
self.client = OpenAI(
|
| 68 |
-
api_key=
|
| 69 |
)
|
| 70 |
self.model_string = model_string
|
| 71 |
self.is_multimodal = is_multimodal
|
|
|
|
| 43 |
is_multimodal: bool=False,
|
| 44 |
# enable_cache: bool=True,
|
| 45 |
enable_cache: bool=False, # NOTE: disable cache for now
|
| 46 |
+
api_key: str=None,
|
| 47 |
**kwargs):
|
| 48 |
"""
|
| 49 |
:param model_string:
|
|
|
|
| 62 |
super().__init__(cache_path=cache_path)
|
| 63 |
|
| 64 |
self.system_prompt = system_prompt
|
| 65 |
+
if api_key is None:
|
| 66 |
raise ValueError("Please set the OPENAI_API_KEY environment variable if you'd like to use OpenAI models.")
|
| 67 |
|
| 68 |
self.client = OpenAI(
|
| 69 |
+
api_key=api_key,
|
| 70 |
)
|
| 71 |
self.model_string = model_string
|
| 72 |
self.is_multimodal = is_multimodal
|
opentools/models/executor.py
CHANGED
|
@@ -18,13 +18,14 @@ def timeout_handler(signum, frame):
|
|
| 18 |
raise TimeoutError("Function execution timed out")
|
| 19 |
|
| 20 |
class Executor:
|
| 21 |
-
def __init__(self, llm_engine_name: str, root_cache_dir: str = "solver_cache", num_threads: int = 1, max_time: int = 120, max_output_length: int = 100000, enable_signal: bool = True):
|
| 22 |
self.llm_engine_name = llm_engine_name
|
| 23 |
self.root_cache_dir = root_cache_dir
|
| 24 |
self.num_threads = num_threads
|
| 25 |
self.max_time = max_time
|
| 26 |
self.max_output_length = max_output_length
|
| 27 |
self.enable_signal = enable_signal
|
|
|
|
| 28 |
|
| 29 |
def set_query_cache_dir(self, query_cache_dir):
|
| 30 |
if query_cache_dir:
|
|
@@ -130,7 +131,7 @@ Reason: The command should process multiple items in a single execution, not sep
|
|
| 130 |
Remember: Your <command> field MUST be valid Python code including any necessary data preparation steps and one or more `execution = tool.execute(` calls, without any additional explanatory text. The format `execution = tool.execute` must be strictly followed, and the last line must begin with `execution = tool.execute` to capture the final output.
|
| 131 |
"""
|
| 132 |
|
| 133 |
-
llm_generate_tool_command = ChatOpenAI(model_string=self.llm_engine_name, is_multimodal=False)
|
| 134 |
tool_command = llm_generate_tool_command(prompt_generate_tool_command, response_format=ToolCommand)
|
| 135 |
|
| 136 |
return tool_command
|
|
@@ -207,12 +208,14 @@ Remember: Your <command> field MUST be valid Python code including any necessary
|
|
| 207 |
|
| 208 |
# Check if the tool requires an LLM engine
|
| 209 |
# NOTE FIXME may need to refine base.py and tool.py to handle this better
|
|
|
|
| 210 |
if getattr(tool_class, 'require_llm_engine', False):
|
| 211 |
# Instantiate the tool with the model_string
|
| 212 |
-
|
| 213 |
-
|
| 214 |
-
# Instantiate the tool
|
| 215 |
-
|
|
|
|
| 216 |
|
| 217 |
# Set the custom output directory
|
| 218 |
# NOTE FIXME: May have a better way to handle this
|
|
|
|
| 18 |
raise TimeoutError("Function execution timed out")
|
| 19 |
|
| 20 |
class Executor:
|
| 21 |
+
def __init__(self, llm_engine_name: str, root_cache_dir: str = "solver_cache", num_threads: int = 1, max_time: int = 120, max_output_length: int = 100000, enable_signal: bool = True, api_key: str = None):
|
| 22 |
self.llm_engine_name = llm_engine_name
|
| 23 |
self.root_cache_dir = root_cache_dir
|
| 24 |
self.num_threads = num_threads
|
| 25 |
self.max_time = max_time
|
| 26 |
self.max_output_length = max_output_length
|
| 27 |
self.enable_signal = enable_signal
|
| 28 |
+
self.api_key = api_key
|
| 29 |
|
| 30 |
def set_query_cache_dir(self, query_cache_dir):
|
| 31 |
if query_cache_dir:
|
|
|
|
| 131 |
Remember: Your <command> field MUST be valid Python code including any necessary data preparation steps and one or more `execution = tool.execute(` calls, without any additional explanatory text. The format `execution = tool.execute` must be strictly followed, and the last line must begin with `execution = tool.execute` to capture the final output.
|
| 132 |
"""
|
| 133 |
|
| 134 |
+
llm_generate_tool_command = ChatOpenAI(model_string=self.llm_engine_name, is_multimodal=False, api_key=self.api_key)
|
| 135 |
tool_command = llm_generate_tool_command(prompt_generate_tool_command, response_format=ToolCommand)
|
| 136 |
|
| 137 |
return tool_command
|
|
|
|
| 208 |
|
| 209 |
# Check if the tool requires an LLM engine
|
| 210 |
# NOTE FIXME may need to refine base.py and tool.py to handle this better
|
| 211 |
+
inputs = {}
|
| 212 |
if getattr(tool_class, 'require_llm_engine', False):
|
| 213 |
# Instantiate the tool with the model_string
|
| 214 |
+
inputs['model_string'] = self.llm_engine_name
|
| 215 |
+
if getattr(tool_class, 'require_api_key', False):
|
| 216 |
+
# Instantiate the tool with the api_key
|
| 217 |
+
inputs['api_key'] = self.api_key
|
| 218 |
+
tool = tool_class(**inputs)
|
| 219 |
|
| 220 |
# Set the custom output directory
|
| 221 |
# NOTE FIXME: May have a better way to handle this
|
opentools/models/initializer.py
CHANGED
|
@@ -7,11 +7,12 @@ from typing import Dict, Any, List, Tuple
|
|
| 7 |
|
| 8 |
|
| 9 |
class Initializer:
|
| 10 |
-
def __init__(self, enabled_tools: List[str] = [], model_string: str = None):
|
| 11 |
self.toolbox_metadata = {}
|
| 12 |
self.available_tools = []
|
| 13 |
self.enabled_tools = enabled_tools
|
| 14 |
self.model_string = model_string # llm model string
|
|
|
|
| 15 |
|
| 16 |
print("\nInitializing OpenTools...")
|
| 17 |
print(f"Enabled tools: {self.enabled_tools}")
|
|
@@ -64,10 +65,14 @@ class Initializer:
|
|
| 64 |
# print(f"Class __dict__: {obj.__dict__}")
|
| 65 |
try:
|
| 66 |
# Check if the tool requires an LLM engine
|
|
|
|
| 67 |
if hasattr(obj, 'require_llm_engine') and obj.require_llm_engine:
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
|
|
|
|
|
|
|
|
|
|
| 71 |
|
| 72 |
# print(f"\nInstance attributes: {dir(tool_instance)}")
|
| 73 |
# print(f"\nInstance __dict__: {tool_instance.__dict__}")
|
|
|
|
| 7 |
|
| 8 |
|
| 9 |
class Initializer:
|
| 10 |
+
def __init__(self, enabled_tools: List[str] = [], model_string: str = None, api_key: str = None):
|
| 11 |
self.toolbox_metadata = {}
|
| 12 |
self.available_tools = []
|
| 13 |
self.enabled_tools = enabled_tools
|
| 14 |
self.model_string = model_string # llm model string
|
| 15 |
+
self.api_key = api_key
|
| 16 |
|
| 17 |
print("\nInitializing OpenTools...")
|
| 18 |
print(f"Enabled tools: {self.enabled_tools}")
|
|
|
|
| 65 |
# print(f"Class __dict__: {obj.__dict__}")
|
| 66 |
try:
|
| 67 |
# Check if the tool requires an LLM engine
|
| 68 |
+
inputs = {}
|
| 69 |
if hasattr(obj, 'require_llm_engine') and obj.require_llm_engine:
|
| 70 |
+
inputs['model_string'] = self.model_string
|
| 71 |
+
|
| 72 |
+
if hasattr(obj, 'require_api_key') and obj.require_api_key:
|
| 73 |
+
inputs['api_key'] = self.api_key
|
| 74 |
+
|
| 75 |
+
tool_instance = obj(**inputs)
|
| 76 |
|
| 77 |
# print(f"\nInstance attributes: {dir(tool_instance)}")
|
| 78 |
# print(f"\nInstance __dict__: {tool_instance.__dict__}")
|
opentools/models/planner.py
CHANGED
|
@@ -9,10 +9,10 @@ from opentools.models.memory import Memory
|
|
| 9 |
from opentools.models.formatters import QueryAnalysis, NextStep, MemoryVerification
|
| 10 |
|
| 11 |
class Planner:
|
| 12 |
-
def __init__(self, llm_engine_name: str, toolbox_metadata: dict = None, available_tools: List = None):
|
| 13 |
self.llm_engine_name = llm_engine_name
|
| 14 |
-
self.llm_engine_mm = ChatOpenAI(model_string=llm_engine_name, is_multimodal=True)
|
| 15 |
-
self.llm_engine = ChatOpenAI(model_string=llm_engine_name, is_multimodal=False)
|
| 16 |
self.toolbox_metadata = toolbox_metadata if toolbox_metadata is not None else {}
|
| 17 |
self.available_tools = available_tools if available_tools is not None else []
|
| 18 |
|
|
@@ -47,13 +47,10 @@ class Planner:
|
|
| 47 |
return image_info
|
| 48 |
|
| 49 |
def generate_base_response(self, question: str, image: str, max_tokens: str = 4000, bytes_mode: bool = False) -> str:
|
| 50 |
-
|
| 51 |
-
image_info = self.get_image_info_bytes(image)
|
| 52 |
-
else:
|
| 53 |
-
image_info = self.get_image_info(image)
|
| 54 |
|
| 55 |
input_data = [question]
|
| 56 |
-
if image_info and "image_path" in image_info
|
| 57 |
try:
|
| 58 |
with open(image_info["image_path"], 'rb') as file:
|
| 59 |
image_bytes = file.read()
|
|
@@ -66,10 +63,7 @@ class Planner:
|
|
| 66 |
return self.base_response
|
| 67 |
|
| 68 |
def analyze_query(self, question: str, image: str, bytes_mode: bool = False) -> str:
|
| 69 |
-
|
| 70 |
-
image_info = self.get_image_info_bytes(image)
|
| 71 |
-
else:
|
| 72 |
-
image_info = self.get_image_info(image)
|
| 73 |
print("image_info: ", image_info)
|
| 74 |
|
| 75 |
query_prompt = f"""
|
|
@@ -100,9 +94,7 @@ Please present your analysis in a clear, structured format.
|
|
| 100 |
"""
|
| 101 |
|
| 102 |
input_data = [query_prompt]
|
| 103 |
-
if
|
| 104 |
-
image_bytes = image
|
| 105 |
-
else:
|
| 106 |
try:
|
| 107 |
with open(image_info["image_path"], 'rb') as file:
|
| 108 |
image_bytes = file.read()
|
|
|
|
| 9 |
from opentools.models.formatters import QueryAnalysis, NextStep, MemoryVerification
|
| 10 |
|
| 11 |
class Planner:
|
| 12 |
+
def __init__(self, llm_engine_name: str, toolbox_metadata: dict = None, available_tools: List = None, api_key: str = None):
|
| 13 |
self.llm_engine_name = llm_engine_name
|
| 14 |
+
self.llm_engine_mm = ChatOpenAI(model_string=llm_engine_name, is_multimodal=True, api_key=api_key)
|
| 15 |
+
self.llm_engine = ChatOpenAI(model_string=llm_engine_name, is_multimodal=False, api_key=api_key)
|
| 16 |
self.toolbox_metadata = toolbox_metadata if toolbox_metadata is not None else {}
|
| 17 |
self.available_tools = available_tools if available_tools is not None else []
|
| 18 |
|
|
|
|
| 47 |
return image_info
|
| 48 |
|
| 49 |
def generate_base_response(self, question: str, image: str, max_tokens: str = 4000, bytes_mode: bool = False) -> str:
|
| 50 |
+
image_info = self.get_image_info(image)
|
|
|
|
|
|
|
|
|
|
| 51 |
|
| 52 |
input_data = [question]
|
| 53 |
+
if image_info and "image_path" in image_info:
|
| 54 |
try:
|
| 55 |
with open(image_info["image_path"], 'rb') as file:
|
| 56 |
image_bytes = file.read()
|
|
|
|
| 63 |
return self.base_response
|
| 64 |
|
| 65 |
def analyze_query(self, question: str, image: str, bytes_mode: bool = False) -> str:
|
| 66 |
+
image_info = self.get_image_info(image)
|
|
|
|
|
|
|
|
|
|
| 67 |
print("image_info: ", image_info)
|
| 68 |
|
| 69 |
query_prompt = f"""
|
|
|
|
| 94 |
"""
|
| 95 |
|
| 96 |
input_data = [query_prompt]
|
| 97 |
+
if image_info and "image_path" in image_info:
|
|
|
|
|
|
|
| 98 |
try:
|
| 99 |
with open(image_info["image_path"], 'rb') as file:
|
| 100 |
image_bytes = file.read()
|
opentools/models/utlis.py
DELETED
|
@@ -1,73 +0,0 @@
|
|
| 1 |
-
# import json
|
| 2 |
-
|
| 3 |
-
# def truncate_result(result, max_length: int = 100000, truncation_indicator: str = "...") -> str:
|
| 4 |
-
# """
|
| 5 |
-
# Truncate the result to specified length while preserving JSON structure when possible.
|
| 6 |
-
|
| 7 |
-
# Args:
|
| 8 |
-
# result: The result to truncate (can be str, list, dict, or other types)
|
| 9 |
-
# max_length: Maximum length of the output string (default: 1000)
|
| 10 |
-
# truncation_indicator: String to indicate truncation (default: "...")
|
| 11 |
-
|
| 12 |
-
# Returns:
|
| 13 |
-
# str: Truncated string representation of the result
|
| 14 |
-
# """
|
| 15 |
-
# if isinstance(result, (dict, list)):
|
| 16 |
-
# try:
|
| 17 |
-
# result_str = json.dumps(result, ensure_ascii=False)
|
| 18 |
-
# except:
|
| 19 |
-
# result_str = str(result)
|
| 20 |
-
# else:
|
| 21 |
-
# result_str = str(result)
|
| 22 |
-
|
| 23 |
-
# indicator_length = len(truncation_indicator)
|
| 24 |
-
|
| 25 |
-
# if len(result_str) > max_length:
|
| 26 |
-
# # For JSON-like strings, try to find the last complete structure
|
| 27 |
-
# if result_str.startswith('{') or result_str.startswith('['):
|
| 28 |
-
# # Find last complete element
|
| 29 |
-
# pos = max_length - indicator_length
|
| 30 |
-
# while pos > 0 and not (
|
| 31 |
-
# result_str[pos] in ',]}' and
|
| 32 |
-
# result_str[pos:].count('"') % 2 == 0
|
| 33 |
-
# ):
|
| 34 |
-
# pos -= 1
|
| 35 |
-
# if pos > 0:
|
| 36 |
-
# return result_str[:pos + 1] + truncation_indicator
|
| 37 |
-
|
| 38 |
-
# # Default truncation if not JSON or no suitable truncation point found
|
| 39 |
-
# return result_str[:max_length - indicator_length] + truncation_indicator
|
| 40 |
-
|
| 41 |
-
# return result_str
|
| 42 |
-
|
| 43 |
-
def make_json_serializable(obj):
|
| 44 |
-
if isinstance(obj, (str, int, float, bool, type(None))):
|
| 45 |
-
return obj
|
| 46 |
-
elif isinstance(obj, dict):
|
| 47 |
-
return {make_json_serializable(key): make_json_serializable(value) for key, value in obj.items()}
|
| 48 |
-
elif isinstance(obj, list):
|
| 49 |
-
return [make_json_serializable(element) for element in obj]
|
| 50 |
-
elif hasattr(obj, '__dict__'):
|
| 51 |
-
return make_json_serializable(obj.__dict__)
|
| 52 |
-
else:
|
| 53 |
-
return str(obj)
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
def make_json_serializable_truncated(obj, max_length: int = 100000):
|
| 57 |
-
if isinstance(obj, (int, float, bool, type(None))):
|
| 58 |
-
if isinstance(obj, (int, float)) and len(str(obj)) > max_length:
|
| 59 |
-
return str(obj)[:max_length - 3] + "..."
|
| 60 |
-
return obj
|
| 61 |
-
elif isinstance(obj, str):
|
| 62 |
-
return obj if len(obj) <= max_length else obj[:max_length - 3] + "..."
|
| 63 |
-
elif isinstance(obj, dict):
|
| 64 |
-
return {make_json_serializable_truncated(key, max_length): make_json_serializable_truncated(value, max_length)
|
| 65 |
-
for key, value in obj.items()}
|
| 66 |
-
elif isinstance(obj, list):
|
| 67 |
-
return [make_json_serializable_truncated(element, max_length) for element in obj]
|
| 68 |
-
elif hasattr(obj, '__dict__'):
|
| 69 |
-
return make_json_serializable_truncated(obj.__dict__, max_length)
|
| 70 |
-
else:
|
| 71 |
-
result = str(obj)
|
| 72 |
-
return result if len(result) <= max_length else result[:max_length - 3] + "..."
|
| 73 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
opentools/setup.py
DELETED
|
@@ -1,20 +0,0 @@
|
|
| 1 |
-
from setuptools import setup, find_packages
|
| 2 |
-
|
| 3 |
-
setup(
|
| 4 |
-
name='opentools',
|
| 5 |
-
version='0.1.0',
|
| 6 |
-
# description='A flexible and versatile toolbox agent framework for complex tasks in both general and scientific scenarios.',
|
| 7 |
-
# long_description=open('README.md').read(),
|
| 8 |
-
# long_description_content_type='text/markdown',
|
| 9 |
-
# author='Pan Lu, Bowen Chen, Sheng Liu',
|
| 10 |
-
# author_email='lupantech@gmail.com',
|
| 11 |
-
# url='', # You can add a GitHub or project URL here
|
| 12 |
-
packages=find_packages(),
|
| 13 |
-
# install_requires=open('requirements.txt').read().splitlines(),
|
| 14 |
-
# classifiers=[
|
| 15 |
-
# 'Programming Language :: Python :: 3',
|
| 16 |
-
# 'License :: OSI Approved :: MIT License',
|
| 17 |
-
# 'Operating System :: OS Independent',
|
| 18 |
-
# ],
|
| 19 |
-
# python_requires='>=3.10',
|
| 20 |
-
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
opentools/tools/generalist_solution_generator/tool.py
CHANGED
|
@@ -4,8 +4,9 @@ from opentools.engine.openai import ChatOpenAI
|
|
| 4 |
|
| 5 |
class Generalist_Solution_Generator_Tool(BaseTool):
|
| 6 |
require_llm_engine = True
|
|
|
|
| 7 |
|
| 8 |
-
def __init__(self, model_string="gpt-4o-mini"):
|
| 9 |
super().__init__(
|
| 10 |
tool_name="Generalist_Solution_Generator_Tool",
|
| 11 |
tool_description="A generalized tool that takes query from the user as prompt, and answers the question step by step to the best of its ability. It can also accept an image.",
|
|
@@ -72,12 +73,13 @@ class Generalist_Solution_Generator_Tool(BaseTool):
|
|
| 72 |
# }
|
| 73 |
)
|
| 74 |
self.model_string = model_string
|
|
|
|
| 75 |
|
| 76 |
def execute(self, prompt, image=None):
|
| 77 |
|
| 78 |
print(f"\nInitializing Generalist Tool with model: {self.model_string}")
|
| 79 |
multimodal = True if image else False
|
| 80 |
-
llm_engine = ChatOpenAI(model_string=self.model_string, is_multimodal=multimodal)
|
| 81 |
|
| 82 |
try:
|
| 83 |
input_data = [prompt]
|
|
|
|
| 4 |
|
| 5 |
class Generalist_Solution_Generator_Tool(BaseTool):
|
| 6 |
require_llm_engine = True
|
| 7 |
+
require_api_key = True
|
| 8 |
|
| 9 |
+
def __init__(self, model_string="gpt-4o-mini", api_key=None):
|
| 10 |
super().__init__(
|
| 11 |
tool_name="Generalist_Solution_Generator_Tool",
|
| 12 |
tool_description="A generalized tool that takes query from the user as prompt, and answers the question step by step to the best of its ability. It can also accept an image.",
|
|
|
|
| 73 |
# }
|
| 74 |
)
|
| 75 |
self.model_string = model_string
|
| 76 |
+
self.api_key = api_key
|
| 77 |
|
| 78 |
def execute(self, prompt, image=None):
|
| 79 |
|
| 80 |
print(f"\nInitializing Generalist Tool with model: {self.model_string}")
|
| 81 |
multimodal = True if image else False
|
| 82 |
+
llm_engine = ChatOpenAI(model_string=self.model_string, is_multimodal=multimodal, api_key=self.api_key)
|
| 83 |
|
| 84 |
try:
|
| 85 |
input_data = [prompt]
|
setup.py
DELETED
|
@@ -1,20 +0,0 @@
|
|
| 1 |
-
from setuptools import setup, find_packages
|
| 2 |
-
|
| 3 |
-
setup(
|
| 4 |
-
name='opentools',
|
| 5 |
-
version='0.1.0',
|
| 6 |
-
# description='A flexible and versatile toolbox agent framework for complex tasks in both general and scientific scenarios.',
|
| 7 |
-
# long_description=open('README.md').read(),
|
| 8 |
-
# long_description_content_type='text/markdown',
|
| 9 |
-
# author='Pan Lu, Bowen Chen, Sheng Liu',
|
| 10 |
-
# author_email='lupantech@gmail.com',
|
| 11 |
-
# url='', # You can add a GitHub or project URL here
|
| 12 |
-
packages=find_packages(),
|
| 13 |
-
# install_requires=open('requirements.txt').read().splitlines(),
|
| 14 |
-
# classifiers=[
|
| 15 |
-
# 'Programming Language :: Python :: 3',
|
| 16 |
-
# 'License :: OSI Approved :: MIT License',
|
| 17 |
-
# 'Operating System :: OS Independent',
|
| 18 |
-
# ],
|
| 19 |
-
# python_requires='>=3.10',
|
| 20 |
-
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|