import os import subprocess import random import json from datetime import datetime from huggingface_hub import InferenceClient, cached_download, hf_hub_url import gradio as gr from safe_search import safe_search from i_search import google, i_search as i_s from agent import ( ACTION_PROMPT, ADD_PROMPT, COMPRESS_HISTORY_PROMPT, LOG_PROMPT, LOG_RESPONSE, MODIFY_PROMPT, PREFIX, SEARCH_QUERY, READ_PROMPT, TASK_PROMPT, UNDERSTAND_TEST_RESULTS_PROMPT, ) from utils import parse_action, parse_file_content, read_python_module_structure def parse_action(response): """Parses the NLP response for action and component information. Args: response (str): The NLP model's response. Returns: tuple: A tuple containing the parsed information: - component_id (dict): The ID of the component, as an object with an '_id' attribute. - action (str): The action to perform on the component (e.g., "update", "remove"). - property_name (str): The name of the property to modify. - property_value (str): The new value for the property. """ component_id = None action = None property_name = None property_value = None # Example parsing logic (adjust based on your NLP model's response format) if "Component ID:" in response: component_id = response.split("Component ID:")[1].split(",")[0].strip() if "Action:" in response: action = response.split("Action:")[1].split(",")[0].strip() if "Property:" in response: property_name = response.split("Property:")[1].split(",")[0].strip() if "Value:" in response: property_value = response.split("Value:")[1].split(",")[0].strip() # Return an object with an '_id' attribute return {"_id": component_id}, action, property_name, property_value class App: def __init__(self): self.app_state = {"components": []} self.terminal_history = "" self.components_registry = { "Button": { "properties": { "label": "Click Me", "onclick": "" }, "description": "A clickable button", "code_snippet": "gr.Button(value='{{label}}', variant='primary')" }, "Text Input": { "properties": { "value": "", "placeholder": "Enter text" }, "description": "A field for entering text", "code_snippet": "gr.Textbox(label='{{placeholder}}')" }, "Image": { "properties": { "src": "#", "alt": "Image" }, "description": "Displays an image", "code_snippet": "gr.Image(label='{{alt}}')" }, "Dropdown": { "properties": { "choices": ["Option 1", "Option 2"], "value": "" }, "description": "A dropdown menu for selecting options", "code_snippet": "gr.Dropdown(choices={{choices}}, label='Dropdown')" } } self.nlp_model_names = [ "google/flan-t5-small", "Qwen/CodeQwen1.5-7B-Chat-GGUF", "bartowski/Codestral-22B-v0.1-GGUF", "bartowski/AutoCoder-GGUF" ] self.nlp_models = [] self.initialize_nlp_models() def initialize_nlp_models(self): for nlp_model_name in self.nlp_model_names: try: cached_download(hf_hub_url(nlp_model_name, revision="main")) self.nlp_models.append(InferenceClient(nlp_model_name)) except: self.nlp_models.append(None) def get_nlp_response(self, input_text, model_index): if self.nlp_models[model_index]: response = self.nlp_models[model_index].text_generation(input_text) return response.generated_text else: return "NLP model not available." def update_app_canvas(self): components_html = "".join([f"
Component ID: {component['id']}, Type: {component['type']}, Properties: {component['properties']}
" for component in self.app_state["components"]]) return components_html def add_component(self, component_type, properties=None): try: new_component = { "type": component_type, "properties": properties or {} } self.app_state["components"].append(new_component) except Exception as e: print(f"Error adding component: {e}") def run_terminal_command(self, command, *args): output = "" try: if command.startswith("add "): component_type = command.split("add ")[1] return self.add_component(component_type) elif command.startswith("search "): query = command.split("search ")[1] return google(query) elif command.startswith("i search "): query = command.split("i search ")[1] return i_s(query) elif command.startswith("safe search "): query = command.split("safesearch ")[1] return safe_search(query) elif command.startswith("read "): file_path = command.split("read ")[1] return parse_file_content(file_path) elif command == "task": return TASK_PROMPT elif command == "modify": return MODIFY_PROMPT elif command == "log": return LOG_PROMPT elif command.startswith("understand test results "): test_results = command.split("understand test results ")[1] return self.understand_test_results(test_results) elif command.startswith("compress history"): return self.compress_history(self.terminal_history) elif command == "help": return self.get_help_message() elif command == "exit": exit() else: output = subprocess.check_output(command, shell=True).decode("utf-8") except Exception as e: output = str(e) return output or "No output\n" def compress_history(self, history): compressed_history = "" lines = history.strip().split("\n") for line in lines: if not line.strip().startswith("#"): compressed_history += line + "\n" return compressed_history def understand_test_results(self, test_results): return UNDERSTAND_TEST_RESULTS_PROMPT def get_help_message(self): return """ Available commands: - add [component_type]: Add a component to the app canvas - search [query]: Perform a Google search - i search [query]: Perform an intelligent search - safe search [query]: Perform a safe search - read [file_path]: Read and parse the content of a Python module - task: Prompt for a task to perform - modify: Prompt to modify a component property - log: Prompt to log a response - understand test results [test_results]: Understand test results - compress history: Compress the terminal history by removing comments - help: Show this help message - exit: Exit the program """ def process_input(self, input_text): if input_text.strip().startswith("/"): command = input_text.strip().lstrip("/") output = self.run_terminal_command(command) self.terminal_history += f"{input_text}\n{output}\n" return output, "" else: model_index = random.randint(0, len(self.nlp_models)-1) response = self.get_nlp_response(input_text, model_index) component_id, action, property_name, property_value = parse_action(response) if component_id: component = next((comp for comp in self.app_state["components"] if comp["id"] == component_id["_id"]), None) if component: if action == "update": component["properties"][property_name] = property_value return self.update_app_canvas(), f"System: Updated property '{property_name}' of component with ID {component_id['_id']}\n" elif action == "remove": self.app_state["components"].remove(component) return self.update_app_canvas(), f"System: Removed component with ID {component_id['_id']}\n" else: return "", f"Error: Invalid action: {action}\n" else: return "", f"Error: Component with ID {component_id['_id']} not found\n" else: return "", f"Error: Failed to parse action from NLP response\n" def build_app(self): with gr.Blocks() as demo: for component in self.app_state["components"]: component_type = component["type"] properties = component["properties"] if component_type == "Button": gr.Button(value=properties["label"], variant="primary") elif component_type == "Text Input": gr.Textbox(label=properties["placeholder"]) elif component_type == "Image": gr.Image(label=properties["alt"]) elif component_type == "Dropdown": gr.Dropdown(choices=properties["choices"], label="Dropdown") with gr.Tab("Terminal"): gr.Markdown("## Terminal") terminal_input = gr.Textbox(label="Input") terminal_output = gr.Textbox(label="Output") run_terminal_command_button = gr.Button("Run Command") run_terminal_command_button.click( self.run_terminal_command, inputs=[terminal_input], outputs=[terminal_output] ) with gr.Tab("NLP Models"): gr.Markdown("## Available NLP Models") model_index = gr.Slider(label="Model Index", minimum=0, maximum=len(self.nlp_model_names)-1, step=1) input_text = gr.Textbox(label="Input Text") get_nlp_response_button = gr.Button("Get NLP Response") get_nlp_response_button.click( self.get_nlp_response, inputs=[input_text, model_index], outputs="text" ) return demo def run(self): self._print_welcome_message() while True: try: input_text = self._get_user_input() if input_text.lower() == 'exit': break elif input_text.lower() == 'launch': self.launch_app() continue output, system_message = self.process_input(input_text) self._display_output(output, system_message) except EOFError: print("Error: Input reading interrupted. Please provide valid input.") except KeyboardInterrupt: print("\nApplication stopped by user.") break except Exception as e: print(f"An error occurred: {str(e)}") def _print_welcome_message(self): print("Welcome to the Python App Builder!") print("Type 'help' to see the available commands.") print("Type 'launch' to build and launch the Gradio app.") print("Type 'exit' to quit the application.") print("-" * 50) def _get_user_input(self): return input("Enter input: ").strip() def _display_output(self, output, system_message): if output: print(output) if system_message: print(system_message) def launch_app(self): demo = self.build_app() demo.launch() def main(): try: app = App() demo = app.build_app() demo.launch() except Exception as e: print(f"Error launching app: {e}") if __name__ == "__main__": main() def run(self): self._print_welcome_message() while True: try: input_text = self._get_user_input() if input_text.lower() == 'exit': break elif input_text.lower() == 'launch': self.launch_app() continue output, system_message = self.process_input(input_text) self._display_output(output, system_message) except EOFError: print("Error: Input reading interrupted. Please provide valid input.") except KeyboardInterrupt: print("\nApplication stopped by user.") break except Exception as e: print(f"An error occurred: {str(e)}") def _print_welcome_message(self): print("Welcome to the Python App Builder!") print("Type 'help' to see the available commands.") print("Type 'launch' to build and launch the Gradio app.") print("Type 'exit' to quit the application.") print("-" * 50) def _get_user_input(self): return input("Enter input: ").strip() def _display_output(self, output, system_message): if output: print(output) if system_message: print(system_message) def launch_app(self): demo = self.build_app() demo.launch() def main(): try: app = App() demo = app.build_app() demo.launch() except Exception as e: print(f"Error launching app: {e}") def launch_app(self): demo = self.build_app() print(f"Demo object type: {type(demo)}") demo.launch() if __name__ == "__main__": main()