This commit is contained in:
Saifeddine ALOUI 2024-12-31 00:49:41 +01:00
parent 618be263d5
commit dd0cd60acd
4 changed files with 388 additions and 11 deletions

View File

@ -606,6 +606,7 @@ def install_requirements(app_path: Path):
print(f"Error installing requirements: {e}")
raise
import sys
def run_server(app_path: Path):
server_script = app_path / "server.py"
@ -614,11 +615,14 @@ def run_server(app_path: Path):
# Install requirements if they exist
install_requirements(app_path)
# Get current Python executable path
python_executable = sys.executable
# Determine the platform and open a terminal to execute the Python code.
system = platform.system()
if system == "Windows":
process = subprocess.Popen(
f"""start cmd /k "cd /d "{app_path}" && python "{server_script}" && pause" """,
f"""start cmd /k "cd /d "{app_path}" && "{python_executable}" "{server_script}" && pause" """,
shell=True,
)
elif system == "Darwin": # macOS
@ -627,7 +631,7 @@ def run_server(app_path: Path):
"open",
"-a",
"Terminal",
f'cd "{app_path}" && python "{server_script}"',
f'cd "{app_path}" && "{python_executable}" "{server_script}"',
],
shell=True,
)
@ -636,7 +640,7 @@ def run_server(app_path: Path):
[
"x-terminal-emulator",
"-e",
f'bash -c "cd \\"{app_path}\\" && python \\"{server_script}\\"; exec bash"',
f'bash -c "cd \\"{app_path}\\" && \\"{python_executable}\\" \\"{server_script}\\"; exec bash"',
],
shell=True,
)
@ -650,6 +654,7 @@ def run_server(app_path: Path):
ASCIIColors.error(f"Server script not found for app: {app_path.name}")
@router.post("/apps/start_server")
async def start_app_server(request: OpenFolderRequest):
check_access(lollmsElfServer, request.client_id)

@ -1 +1 @@
Subproject commit 4d2e198d076f0522e107b30b025be175811df236
Subproject commit d21a0125d0ff87f5ba1a39ad51f819c5fea8413e

View File

@ -1422,16 +1422,34 @@ class LOLLMSWebUI(LOLLMSElfServer):
f"{k}"
for k, v in self.config.smart_routing_models_description.items()
]
output_id, explanation = self.personality.multichoice_question(
"Select most suitable model to answer the user request given the context. Answer with the selected model index followed by an explanation in a new line.",
code = self.personality.generate_custom_code(
"\n".join([
self.system_full_header,
"Given the following list of models:"]+
[
f"{k}: {v}"
for k, v in self.config.smart_routing_models_description.items()
],
"!@>user prompt:" + context_details["prompt"],
return_explanation=True,
)
if output_id >= 0 and output_id < len(models):
]+[
"!@>prompt:" + context_details["prompt"],
"""Given the prompt, which model among the previous list is the most suited and why?
You must answer with json code placed inside the markdown code tag like this:
```json
{
"choice_index": [an int representing the index of the choice made]
"justification": "[Justify the choice]",
}
Make sure you fill all fields and to use the exact same keys as the template.
Don't forget encapsulate the code inside a markdown code tag. This is mandatory.
!@>assistant:"""
]
))
if code:
output_id = code["choice_index"]
explanation = code["justification"]
binding, model_name = self.model_path_to_binding_model(
models[output_id]
)

View File

@ -0,0 +1,354 @@
import sys
import ast
import json
from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout,
QHBoxLayout, QTextEdit, QMenuBar, QMenu, QAction,
QFileDialog, QSplitter, QMessageBox, QPushButton,
QTabWidget, QToolBar)
from PyQt5.QtCore import Qt, QRegExp
from PyQt5.QtGui import QSyntaxHighlighter, QTextCharFormat, QColor, QFont
class PythonHighlighter(QSyntaxHighlighter):
def __init__(self, parent=None):
super().__init__(parent)
self.highlighting_rules = []
keyword_format = QTextCharFormat()
keyword_format.setForeground(QColor("#FF6B6B"))
keywords = ['def', 'class', 'import', 'from', 'as', 'return', 'if', 'elif',
'else', 'try', 'except', 'for', 'while', 'in', 'with', 'self']
for word in keywords:
self.highlighting_rules.append((f"\\b{word}\\b", keyword_format))
string_format = QTextCharFormat()
string_format.setForeground(QColor("#98C379"))
self.highlighting_rules.append(("\".*\"", string_format))
self.highlighting_rules.append(("\'.*\'", string_format)) # Corrected line
comment_format = QTextCharFormat()
comment_format.setForeground(QColor("#5C6370"))
self.highlighting_rules.append(("#.*", comment_format))
def highlightBlock(self, text):
for pattern, format in self.highlighting_rules:
expression = QRegExp(pattern)
index = expression.indexIn(text)
while index >= 0:
length = expression.matchedLength()
self.setFormat(index, length, format)
index = expression.indexIn(text, index + length)
class CodeAnalyzer:
def __init__(self, file_path):
self.file_path = file_path
self.tree = None
self.structure = {
"imports": [],
"classes": [],
"functions": [],
"global_variables": []
}
def parse_file(self):
with open(self.file_path, 'r') as file:
content = file.read()
self.tree = ast.parse(content)
def extract_docstring(self, node):
return ast.get_docstring(node) or ""
def analyze(self):
if not hasattr(self, 'tree'):
self.parse_file()
for node in self.tree.body:
if isinstance(node, ast.Import):
for name in node.names:
self.structure["imports"].append(name.name)
elif isinstance(node, ast.ImportFrom):
module = node.module or ""
for name in node.names:
self.structure["imports"].append(f"{module}.{name.name}")
elif isinstance(node, ast.ClassDef):
class_info = {
"name": node.name,
"docstring": self.extract_docstring(node),
"methods": []
}
for item in node.body:
if isinstance(item, ast.FunctionDef):
method_info = {
"name": item.name,
"docstring": self.extract_docstring(item),
"args": [arg.arg for arg in item.args.args]
}
class_info["methods"].append(method_info)
self.structure["classes"].append(class_info)
elif isinstance(node, ast.FunctionDef):
function_info = {
"name": node.name,
"docstring": self.extract_docstring(node),
"args": [arg.arg for arg in node.args.args]
}
self.structure["functions"].append(function_info)
elif isinstance(node, ast.Assign):
for target in node.targets:
if isinstance(target, ast.Name):
self.structure["global_variables"].append(target.id)
def get_json(self):
return json.dumps(self.structure, indent=2)
class CodeAnalyzerGUI(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setWindowTitle('Python Code Analyzer')
self.setGeometry(100, 100, 1200, 800)
# Setup central widget and main layout
central_widget = QWidget()
self.setCentralWidget(central_widget)
layout = QVBoxLayout(central_widget)
# Add toolbar
self.toolbar = QToolBar()
self.addToolBar(self.toolbar)
analyze_action = QAction('Analyze', self)
analyze_action.triggered.connect(self.analyzeCode)
self.toolbar.addAction(analyze_action)
markdown_action = QAction('Generate MD', self)
markdown_action.triggered.connect(self.generateMarkdown)
self.toolbar.addAction(markdown_action)
# Splitter and text areas
splitter = QSplitter(Qt.Horizontal)
# Source code editor with syntax highlighting
self.source_text = QTextEdit()
self.source_text.setPlaceholderText("Original Python Code")
self.python_highlighter = PythonHighlighter(self.source_text.document())
# Tab widget for JSON and Markdown views
self.tab_widget = QTabWidget()
self.json_view = QTextEdit()
self.markdown_view = QTextEdit()
self.tab_widget.addTab(self.json_view, "JSON")
self.tab_widget.addTab(self.markdown_view, "Markdown")
splitter.addWidget(self.source_text)
splitter.addWidget(self.tab_widget)
layout.addWidget(splitter)
self.createMenuBar()
def createMenuBar(self):
menubar = self.menuBar()
# File menu
file_menu = menubar.addMenu('File')
open_action = QAction('Open...', self)
open_action.setShortcut('Ctrl+O')
open_action.triggered.connect(self.openFile)
save_analysis_action = QAction('Save Analysis...', self)
save_analysis_action.setShortcut('Ctrl+S')
save_analysis_action.triggered.connect(self.saveAnalysis)
clear_action = QAction('Clear', self)
clear_action.setShortcut('Ctrl+L')
clear_action.triggered.connect(self.clearAll)
exit_action = QAction('Exit', self)
exit_action.setShortcut('Ctrl+Q')
exit_action.triggered.connect(self.close)
file_menu.addAction(open_action)
file_menu.addAction(save_analysis_action)
file_menu.addSeparator()
file_menu.addAction(clear_action)
file_menu.addSeparator()
file_menu.addAction(exit_action)
# Analysis menu
analysis_menu = menubar.addMenu('Analysis')
analyze_action = QAction('Analyze Code', self)
analyze_action.setShortcut('F5')
analyze_action.triggered.connect(self.analyzeCode)
markdown_action = QAction('Generate Markdown', self)
markdown_action.setShortcut('F6')
markdown_action.triggered.connect(self.generateMarkdown)
analysis_menu.addAction(analyze_action)
analysis_menu.addAction(markdown_action)
# Help menu
help_menu = menubar.addMenu('Help')
about_action = QAction('About', self)
about_action.triggered.connect(self.showAbout)
help_menu.addAction(about_action)
def openFile(self):
file_name, _ = QFileDialog.getOpenFileName(
self, "Open Python File", "", "Python Files (*.py);;All Files (*)")
if file_name:
try:
with open(file_name, 'r') as file:
content = file.read()
self.source_text.setText(content)
except Exception as e:
QMessageBox.critical(self, "Error", f"Could not open file: {str(e)}")
def saveAnalysis(self):
current_tab = self.tab_widget.currentIndex()
if current_tab == 0:
default_ext = "JSON Files (*.json)"
else:
default_ext = "Markdown Files (*.md)"
file_name, _ = QFileDialog.getSaveFileName(
self, "Save Analysis", "", f"{default_ext};;Text Files (*.txt);;All Files (*)")
if file_name:
try:
with open(file_name, 'w') as file:
if current_tab == 0:
file.write(self.json_view.toPlainText())
else:
file.write(self.markdown_view.toPlainText())
except Exception as e:
QMessageBox.critical(self, "Error", f"Could not save file: {str(e)}")
def clearAll(self):
self.source_text.clear()
self.json_view.clear()
self.markdown_view.clear()
def analyzeCode(self):
source_code = self.source_text.toPlainText()
if not source_code.strip():
QMessageBox.warning(self, "Warning", "No code to analyze!")
return
try:
analyzer = CodeAnalyzer("temp.py")
analyzer.tree = ast.parse(source_code)
analyzer.analyze()
analysis_result = json.dumps(analyzer.structure, indent=2)
self.json_view.setText(analysis_result)
self.tab_widget.setCurrentIndex(0) # Switch to JSON tab
except Exception as e:
QMessageBox.critical(self, "Error", f"Analysis failed: {str(e)}")
def generateMarkdown(self):
try:
analysis_text = self.json_view.toPlainText()
if not analysis_text:
QMessageBox.warning(self, "Warning", "Please analyze the code first!")
return
structure = json.loads(analysis_text)
markdown = self.structureToMarkdown(structure)
self.markdown_view.setText(markdown)
self.tab_widget.setCurrentIndex(1) # Switch to Markdown tab
self.saveMDOption(markdown)
except Exception as e:
QMessageBox.critical(self, "Error", f"Failed to generate markdown: {str(e)}")
def structureToMarkdown(self, structure):
markdown = "# Code Structure Analysis\n\n"
if structure["imports"]:
markdown += "## Imports\n"
for imp in structure["imports"]:
markdown += f"- `{imp}`\n"
markdown += "\n"
if structure["classes"]:
markdown += "## Classes\n"
for class_info in structure["classes"]:
markdown += f"### {class_info['name']}\n"
if class_info["docstring"]:
markdown += f"{class_info['docstring']}\n\n"
if class_info["methods"]:
markdown += "#### Methods\n"
for method in class_info["methods"]:
args_str = ", ".join(method["args"])
markdown += f"- `{method['name']}({args_str})`\n"
if method["docstring"]:
markdown += f" - {method['docstring']}\n"
markdown += "\n"
if structure["functions"]:
markdown += "## Functions\n"
for func in structure["functions"]:
args_str = ", ".join(func["args"])
markdown += f"### `{func['name']}({args_str})`\n"
if func["docstring"]:
markdown += f"{func['docstring']}\n"
markdown += "\n"
if structure["global_variables"]:
markdown += "## Global Variables\n"
for var in structure["global_variables"]:
markdown += f"- `{var}`\n"
markdown += "\n"
return markdown
def saveMDOption(self, markdown):
reply = QMessageBox.question(self, 'Save Markdown',
'Would you like to save the markdown to a file?',
QMessageBox.Yes | QMessageBox.No,
QMessageBox.No)
if reply == QMessageBox.Yes:
file_name, _ = QFileDialog.getSaveFileName(
self, "Save Markdown", "", "Markdown Files (*.md);;All Files (*)")
if file_name:
try:
with open(file_name, 'w') as file:
file.write(markdown)
QMessageBox.information(self, "Success",
"Markdown file saved successfully!")
except Exception as e:
QMessageBox.critical(self, "Error",
f"Could not save markdown file: {str(e)}")
def showAbout(self):
QMessageBox.about(self, "About Python Code Analyzer",
"Python Code Analyzer\n\n"
"A tool for analyzing Python code structure.\n"
"Created with PyQt5 and Python's ast module.")
def main():
app = QApplication(sys.argv)
ex = CodeAnalyzerGUI()
ex.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()