mirror of
https://github.com/ParisNeo/lollms-webui.git
synced 2025-01-18 18:56:32 +00:00
upgrade
This commit is contained in:
parent
618be263d5
commit
dd0cd60acd
@ -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
|
@ -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]
|
||||
)
|
||||
|
354
tools/CodeAnalyzer/code_analyzer.py
Normal file
354
tools/CodeAnalyzer/code_analyzer.py
Normal 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()
|
Loading…
Reference in New Issue
Block a user