mirror of
https://github.com/ParisNeo/lollms.git
synced 2025-02-01 08:48:19 +00:00
added loads of project management functions
This commit is contained in:
parent
98d064608c
commit
47494edb05
@ -1125,7 +1125,7 @@ class LollmsApplication(LoLLMsCom):
|
||||
|
||||
# Build the final discussion messages by detokenizing the full_message_list
|
||||
discussion_messages = ""
|
||||
for i in range(len(full_message_list)-1):
|
||||
for i in range(len(full_message_list)-1 if not is_continue else len(full_message_list)):
|
||||
message_tokens = full_message_list[i]
|
||||
discussion_messages += self.model.detokenize(message_tokens)
|
||||
|
||||
@ -1134,7 +1134,7 @@ class LollmsApplication(LoLLMsCom):
|
||||
else:
|
||||
ai_prefix = ""
|
||||
# Build the final prompt by concatenating the conditionning and discussion messages
|
||||
prompt_data = conditionning + internet_search_results + documentation + knowledge + user_description + discussion_messages + positive_boost + negative_boost + fun_mode + start_ai_header_id_template + ai_prefix + end_ai_header_id_template
|
||||
prompt_data = conditionning + internet_search_results + documentation + knowledge + user_description + discussion_messages + positive_boost + negative_boost + fun_mode + (start_ai_header_id_template + ai_prefix + end_ai_header_id_template if not is_continue else '')
|
||||
|
||||
# Tokenize the prompt data
|
||||
tokens = self.model.tokenize(prompt_data)
|
||||
|
66
lollms/functions/analyze_code/add_code_to_file.py
Normal file
66
lollms/functions/analyze_code/add_code_to_file.py
Normal file
@ -0,0 +1,66 @@
|
||||
# Lollms function call definition file
|
||||
# File Name: add_code_to_file.py
|
||||
# Author: ParisNeo
|
||||
# Description: This function adds given code to a specified Python file in a project directory.
|
||||
|
||||
# Import necessary modules
|
||||
from functools import partial
|
||||
from lollms.utilities import PackageManager
|
||||
from ascii_colors import trace_exception
|
||||
from typing import Union
|
||||
from pathlib import Path
|
||||
|
||||
# Function to add code to a file
|
||||
def add_code_to_file(file_name: str, code_content: str, project_path: Union[str, Path] = "") -> str:
|
||||
"""
|
||||
Adds the specified code content to the given file in the project path.
|
||||
|
||||
Args:
|
||||
file_name (str): The name of the file to add code to.
|
||||
code_content (str): The code content to be added.
|
||||
project_path (Union[str, Path]): The path to the Python project directory.
|
||||
|
||||
Returns:
|
||||
str: Success message or error message.
|
||||
"""
|
||||
try:
|
||||
project_path = Path(project_path)
|
||||
|
||||
# Validate the project path
|
||||
if not project_path.exists() or not project_path.is_dir():
|
||||
return "Invalid project path."
|
||||
|
||||
file_path = project_path / file_name
|
||||
|
||||
# Check if the file exists
|
||||
if not file_path.exists():
|
||||
return f"File {file_name} does not exist in the specified project."
|
||||
|
||||
# Read the current content of the file
|
||||
with open(file_path, "r", encoding="utf-8") as file:
|
||||
current_content = file.read()
|
||||
|
||||
# Add the new code content
|
||||
updated_content = current_content + "\n\n" + code_content
|
||||
|
||||
# Write the updated content back to the file
|
||||
with open(file_path, "w", encoding="utf-8") as file:
|
||||
file.write(updated_content)
|
||||
|
||||
return f"Code added successfully to file {file_name}."
|
||||
|
||||
except Exception as e:
|
||||
return trace_exception(e)
|
||||
|
||||
|
||||
# Metadata function
|
||||
def add_code_to_file_function(project_path: str):
|
||||
return {
|
||||
"function_name": "add_code_to_file", # The function name in string
|
||||
"function": partial(add_code_to_file, project_path=project_path), # The function to be called
|
||||
"function_description": "Adds the specified code content to the given file in the project path.", # Description of the function
|
||||
"function_parameters": [ # The set of parameters
|
||||
{"name": "file_name", "type": "str"},
|
||||
{"name": "code_content", "type": "str"},
|
||||
]
|
||||
}
|
@ -1,8 +1,3 @@
|
||||
"""
|
||||
|
||||
"""
|
||||
|
||||
|
||||
from functools import partial
|
||||
from typing import List, Dict, Union, Any
|
||||
from lollms.utilities import PackageManager
|
||||
@ -17,7 +12,7 @@ import json
|
||||
if not PackageManager.check_package_installed("sqlite3"):
|
||||
PackageManager.install_package("sqlite3")
|
||||
|
||||
def create_project_database(project_path: Union[str, Path], max_summary_size:str=512, llm: APScript=None) -> str:
|
||||
def create_project_database(project_path: Union[str, Path], max_summary_size: str = 512, llm: APScript = None) -> str:
|
||||
"""
|
||||
Creates a database containing structured information about a Python project.
|
||||
|
||||
@ -54,6 +49,7 @@ def create_project_database(project_path: Union[str, Path], max_summary_size:str
|
||||
name TEXT NOT NULL,
|
||||
docstring TEXT,
|
||||
parameters TEXT,
|
||||
core TEXT,
|
||||
FOREIGN KEY (file_id) REFERENCES files (id)
|
||||
)''')
|
||||
|
||||
@ -62,11 +58,20 @@ def create_project_database(project_path: Union[str, Path], max_summary_size:str
|
||||
file_id INTEGER,
|
||||
name TEXT NOT NULL,
|
||||
docstring TEXT,
|
||||
methods TEXT,
|
||||
static_methods TEXT,
|
||||
core TEXT,
|
||||
FOREIGN KEY (file_id) REFERENCES files (id)
|
||||
)''')
|
||||
|
||||
cursor.execute('''CREATE TABLE IF NOT EXISTS methods (
|
||||
id INTEGER PRIMARY KEY,
|
||||
class_id INTEGER,
|
||||
name TEXT NOT NULL,
|
||||
docstring TEXT,
|
||||
parameters TEXT,
|
||||
core TEXT,
|
||||
FOREIGN KEY (class_id) REFERENCES classes (id)
|
||||
)''')
|
||||
|
||||
cursor.execute('''CREATE TABLE IF NOT EXISTS project_info (
|
||||
id INTEGER PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
@ -83,12 +88,12 @@ def create_project_database(project_path: Union[str, Path], max_summary_size:str
|
||||
readme_content = readme_file.read()
|
||||
structure = "\n".join([str(p.relative_to(project_path)) for p in project_path.rglob("*")])
|
||||
readme_content += f"## Project Structure:\n{structure}"
|
||||
project_description = llm.summerize_text(readme_content, "Build a comprehensive description of this project from the available information", max_generation_size=max_summary_size, callback=llm.sink)
|
||||
project_description = llm.summarize_text(readme_content, "Build a comprehensive description of this project from the available information", max_generation_size=max_summary_size, callback=llm.sink)
|
||||
else:
|
||||
# Construct a description based on the project structure
|
||||
structure = "\n".join([str(p.relative_to(project_path)) for p in project_path.rglob("*")])
|
||||
constructed_text = f"Project Name: {project_name}\n\nProject Structure:\n{structure}"
|
||||
project_description = llm.summerize_text(constructed_text, "Build a comprehensive description of this project from the available information", max_generation_size=max_summary_size, callback=llm.sink)
|
||||
project_description = llm.summarize_text(constructed_text, "Build a comprehensive description of this project from the available information", max_generation_size=max_summary_size, callback=llm.sink)
|
||||
|
||||
# Insert project information into the database
|
||||
cursor.execute("INSERT INTO project_info (name, description) VALUES (?, ?)", (project_name, project_description))
|
||||
@ -103,20 +108,22 @@ def create_project_database(project_path: Union[str, Path], max_summary_size:str
|
||||
|
||||
for node in ast.walk(tree):
|
||||
if isinstance(node, ast.FunctionDef):
|
||||
parameters = [arg.arg for arg in node.args.args]
|
||||
cursor.execute("INSERT INTO functions (file_id, name, docstring, parameters) VALUES (?, ?, ?, ?)",
|
||||
(file_id, node.name, ast.get_docstring(node), str(parameters)))
|
||||
parameters = [(arg.arg, arg.annotation.id if arg.annotation else None) for arg in node.args.args]
|
||||
core = ast.get_source_segment(content, node)
|
||||
cursor.execute("INSERT INTO functions (file_id, name, docstring, parameters, core) VALUES (?, ?, ?, ?, ?)",
|
||||
(file_id, node.name, ast.get_docstring(node), json.dumps(parameters), core))
|
||||
elif isinstance(node, ast.ClassDef):
|
||||
methods = []
|
||||
static_methods = []
|
||||
core = ast.get_source_segment(content, node)
|
||||
class_id = cursor.execute("INSERT INTO classes (file_id, name, docstring, core) VALUES (?, ?, ?, ?)",
|
||||
(file_id, node.name, ast.get_docstring(node), core)).lastrowid
|
||||
for class_node in node.body:
|
||||
if isinstance(class_node, ast.FunctionDef):
|
||||
if any(isinstance(decorator, ast.Name) and decorator.id == 'staticmethod' for decorator in class_node.decorator_list):
|
||||
static_methods.append(class_node.name)
|
||||
else:
|
||||
methods.append(class_node.name)
|
||||
cursor.execute("INSERT INTO classes (file_id, name, docstring, methods, static_methods) VALUES (?, ?, ?, ?, ?)",
|
||||
(file_id, node.name, ast.get_docstring(node), str(methods), str(static_methods)))
|
||||
parameters = [(arg.arg, arg.annotation.id if arg.annotation else None) for arg in class_node.args.args]
|
||||
method_core = ast.get_source_segment(content, class_node)
|
||||
cursor.execute("INSERT INTO methods (class_id, name, docstring, parameters, core) VALUES (?, ?, ?, ?, ?)",
|
||||
(class_id, class_node.name, ast.get_docstring(class_node), json.dumps(parameters), method_core))
|
||||
|
||||
# Commit changes and close the connection
|
||||
conn.commit()
|
||||
@ -130,7 +137,7 @@ def create_project_database(project_path: Union[str, Path], max_summary_size:str
|
||||
def create_project_database_function(project_path, llm):
|
||||
return {
|
||||
"function_name": "create_project_database",
|
||||
"function": partial(create_project_database,project_path=project_path, llm=llm),
|
||||
"function": partial(create_project_database, project_path=project_path, llm=llm),
|
||||
"function_description": "Creates a database containing structured information about a Python project.",
|
||||
"function_parameters": []
|
||||
}
|
||||
}
|
||||
|
64
lollms/functions/analyze_code/git_commit.py
Normal file
64
lollms/functions/analyze_code/git_commit.py
Normal file
@ -0,0 +1,64 @@
|
||||
# Lollms function call definition file
|
||||
# File Name: git_commit.py
|
||||
# Author: ParisNeo
|
||||
# Description: This function commits changes to a Git repository with a specified commit message.
|
||||
|
||||
# Import necessary libraries
|
||||
from functools import partial
|
||||
from typing import Union
|
||||
from pathlib import Path
|
||||
import subprocess
|
||||
from ascii_colors import trace_exception
|
||||
|
||||
# Ensure Git is installed
|
||||
from lollms.utilities import PackageManager
|
||||
|
||||
if not PackageManager.check_package_installed("git"):
|
||||
PackageManager.install_package("gitpython")
|
||||
|
||||
import git
|
||||
|
||||
def git_commit(commit_message: str, repo_path: Union[str, Path]) -> str:
|
||||
"""
|
||||
Commits changes to a Git repository with a specified commit message.
|
||||
|
||||
Args:
|
||||
repo_path (Union[str, Path]): The path to the Git repository.
|
||||
commit_message (str): The commit message.
|
||||
|
||||
Returns:
|
||||
str: Success or error message.
|
||||
"""
|
||||
try:
|
||||
repo_path = Path(repo_path)
|
||||
if not repo_path.exists():
|
||||
return "Repository path does not exist."
|
||||
|
||||
repo = git.Repo(repo_path)
|
||||
|
||||
# Stage all changes
|
||||
repo.git.add(A=True)
|
||||
|
||||
# Commit changes
|
||||
repo.index.commit(commit_message)
|
||||
|
||||
return "Changes committed successfully."
|
||||
|
||||
except Exception as e:
|
||||
return trace_exception(e)
|
||||
|
||||
def git_commit_function(repo_path:Path|str):
|
||||
return {
|
||||
"function_name": "git_commit",
|
||||
"function": partial(git_commit, repo_path=repo_path),
|
||||
"function_description": "Commits changes to a Git repository with a specified commit message.",
|
||||
"function_parameters": [
|
||||
{"name": "commit_message", "type": "str"}
|
||||
]
|
||||
}
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Example usage
|
||||
repo_path = "path/to/repo"
|
||||
commit_message = "Your commit message"
|
||||
print(git_commit(repo_path, commit_message))
|
59
lollms/functions/analyze_code/git_pull.py
Normal file
59
lollms/functions/analyze_code/git_pull.py
Normal file
@ -0,0 +1,59 @@
|
||||
# Lollms function call definition file
|
||||
# File Name: git_pull.py
|
||||
# Author: ParisNeo
|
||||
# Description: This function pulls the latest changes from the remote repository to the local Git repository.
|
||||
|
||||
# Import necessary libraries
|
||||
from functools import partial
|
||||
from typing import Union
|
||||
from pathlib import Path
|
||||
import subprocess
|
||||
from ascii_colors import trace_exception
|
||||
|
||||
# Ensure Git is installed
|
||||
from lollms.utilities import PackageManager
|
||||
|
||||
if not PackageManager.check_package_installed("git"):
|
||||
PackageManager.install_package("gitpython")
|
||||
|
||||
import git
|
||||
|
||||
def git_pull(repo_path: Union[str, Path]) -> str:
|
||||
"""
|
||||
Pulls the latest changes from the remote repository to the local Git repository.
|
||||
|
||||
Args:
|
||||
repo_path (Union[str, Path]): The path to the Git repository.
|
||||
|
||||
Returns:
|
||||
str: Success or error message.
|
||||
"""
|
||||
try:
|
||||
repo_path = Path(repo_path)
|
||||
if not repo_path.exists():
|
||||
return "Repository path does not exist."
|
||||
|
||||
repo = git.Repo(repo_path)
|
||||
|
||||
# Pull latest changes
|
||||
repo.remotes.origin.pull()
|
||||
|
||||
return "Latest changes pulled successfully."
|
||||
|
||||
except Exception as e:
|
||||
return trace_exception(e)
|
||||
|
||||
def git_pull_function(repo_path:Path|str):
|
||||
return {
|
||||
"function_name": "git_pull",
|
||||
"function": partial(git_pull, repo_path=repo_path),
|
||||
"function_description": "Pulls the latest changes from the remote repository to the local Git repository.",
|
||||
"function_parameters": [
|
||||
{"name": "repo_path", "type": "str"}
|
||||
]
|
||||
}
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Example usage
|
||||
repo_path = "path/to/repo"
|
||||
print(git_pull(repo_path))
|
61
lollms/functions/analyze_code/list_classes.py
Normal file
61
lollms/functions/analyze_code/list_classes.py
Normal file
@ -0,0 +1,61 @@
|
||||
# Lollms function call definition file
|
||||
# File Name: list_project_classes.py
|
||||
# Author: Saif
|
||||
# Description: This script defines a function to list all classes in a given Python project.
|
||||
|
||||
# Import necessary libraries
|
||||
from functools import partial
|
||||
from pathlib import Path
|
||||
from typing import Union, List
|
||||
import ast
|
||||
import sqlite3
|
||||
|
||||
# Import PackageManager if there are potential libraries that need to be installed
|
||||
from lollms.utilities import PackageManager
|
||||
|
||||
# ascii_colors offers advanced console coloring and bug tracing
|
||||
from ascii_colors import trace_exception
|
||||
|
||||
# Here is the core of the function to be built
|
||||
def list_project_classes(project_path: Union[str, Path]) -> List[str]:
|
||||
"""
|
||||
Lists all classes in a given Python project.
|
||||
|
||||
Args:
|
||||
project_path (Union[str, Path]): The path to the Python project directory.
|
||||
|
||||
Returns:
|
||||
List[str]: A list of class names found in the project.
|
||||
"""
|
||||
try:
|
||||
project_path = Path(project_path)
|
||||
|
||||
# Validate the project path
|
||||
if not project_path.exists() or not project_path.is_dir():
|
||||
return ["Invalid project path."]
|
||||
|
||||
class_names = []
|
||||
|
||||
# Traverse the project directory and extract class names
|
||||
for py_file in project_path.rglob("*.py"):
|
||||
with open(py_file, "r", encoding="utf-8") as file:
|
||||
content = file.read()
|
||||
tree = ast.parse(content)
|
||||
|
||||
for node in ast.walk(tree):
|
||||
if isinstance(node, ast.ClassDef):
|
||||
class_names.append(node.name)
|
||||
|
||||
return class_names
|
||||
|
||||
except Exception as e:
|
||||
return [trace_exception(e)]
|
||||
|
||||
# Metadata function
|
||||
def list_project_classes_function(project_path):
|
||||
return {
|
||||
"function_name": "list_project_classes",
|
||||
"function": partial(list_project_classes, project_path=project_path),
|
||||
"function_description": "Lists all classes in a given Python project.",
|
||||
"function_parameters": []
|
||||
}
|
51
lollms/functions/analyze_code/list_files.py
Normal file
51
lollms/functions/analyze_code/list_files.py
Normal file
@ -0,0 +1,51 @@
|
||||
# Lollms function call definition file
|
||||
# File Name: list_project_structure.py
|
||||
# Author: ParisNeo
|
||||
# Description: This function lists and displays the structure of the project directory.
|
||||
|
||||
from functools import partial
|
||||
from pathlib import Path
|
||||
from typing import Union, List
|
||||
from ascii_colors import trace_exception
|
||||
|
||||
def list_project_structure(project_path: Union[str, Path]) -> str:
|
||||
"""
|
||||
Lists and displays the structure of the project directory, excluding certain directories.
|
||||
|
||||
Args:
|
||||
project_path (Union[str, Path]): The path to the project directory.
|
||||
|
||||
Returns:
|
||||
str: A string representation of the project directory structure.
|
||||
"""
|
||||
try:
|
||||
project_path = Path(project_path)
|
||||
|
||||
# Validate the project path
|
||||
if not project_path.exists() or not project_path.is_dir():
|
||||
return "Invalid project path."
|
||||
|
||||
# Directories to exclude
|
||||
exclude_dirs = {'.git', '.vscode', '__pycache__'}
|
||||
|
||||
structure = []
|
||||
for file in project_path.rglob("*"):
|
||||
# Skip excluded directories
|
||||
if any(part in exclude_dirs or part.endswith('.egg-info') for part in file.parts):
|
||||
continue
|
||||
|
||||
indent_level = len(file.relative_to(project_path).parts) - 1
|
||||
structure.append(f"{' ' * indent_level}{file.name}")
|
||||
|
||||
return "\n".join(structure)
|
||||
|
||||
except Exception as e:
|
||||
return trace_exception(e)
|
||||
|
||||
def list_project_structure_function(project_path: Union[str, Path]):
|
||||
return {
|
||||
"function_name": "list_project_structure",
|
||||
"function": partial(list_project_structure, project_path=project_path),
|
||||
"function_description": "Lists and displays the structure of the project directory.",
|
||||
"function_parameters": []
|
||||
}
|
84
lollms/functions/analyze_code/search_class_in_project.py
Normal file
84
lollms/functions/analyze_code/search_class_in_project.py
Normal file
@ -0,0 +1,84 @@
|
||||
from typing import Optional, Union
|
||||
from pathlib import Path
|
||||
import sqlite3
|
||||
import difflib
|
||||
import json
|
||||
|
||||
from ascii_colors import trace_exception
|
||||
from functools import partial
|
||||
|
||||
def search_class_in_project(class_name: str, db_path: Union[str, Path]) -> Optional[str]:
|
||||
"""
|
||||
Searches for a specific class by name in the project database and returns detailed information.
|
||||
|
||||
Args:
|
||||
db_path (Union[str, Path]): The path to the project database file.
|
||||
class_name (str): The name of the class to search for.
|
||||
|
||||
Returns:
|
||||
Optional[str]: A string with detailed information about the class, or None if not found.
|
||||
"""
|
||||
try:
|
||||
db_path = Path(db_path)
|
||||
if not db_path.exists():
|
||||
return "Database file does not exist."
|
||||
|
||||
conn = sqlite3.connect(db_path)
|
||||
cursor = conn.cursor()
|
||||
|
||||
# Fetch all class names to find the closest match
|
||||
cursor.execute("SELECT id, name FROM classes")
|
||||
classes = cursor.fetchall()
|
||||
class_names = [name for _, name in classes]
|
||||
closest_matches = difflib.get_close_matches(class_name, class_names, n=1, cutoff=0.1)
|
||||
|
||||
if not closest_matches:
|
||||
return f"No class found with a name similar to '{class_name}'."
|
||||
|
||||
closest_class_name = closest_matches[0]
|
||||
cursor.execute("SELECT id, file_id, name, docstring, core FROM classes WHERE name = ?", (closest_class_name,))
|
||||
class_info = cursor.fetchone()
|
||||
|
||||
if not class_info:
|
||||
return f"No class found with the name '{closest_class_name}'."
|
||||
|
||||
class_id, file_id, name, docstring, core = class_info
|
||||
|
||||
# Fetch the file path
|
||||
cursor.execute("SELECT path FROM files WHERE id = ?", (file_id,))
|
||||
file_path = cursor.fetchone()[0]
|
||||
|
||||
# Fetch methods of the class
|
||||
cursor.execute("SELECT name, docstring, parameters FROM methods WHERE class_id = ?", (class_id,))
|
||||
methods = cursor.fetchall()
|
||||
|
||||
# Construct the detailed information string
|
||||
details = f"Class: {name}\n"
|
||||
details += f"File: {file_path}\n"
|
||||
details += f"Description: {docstring}\n\n"
|
||||
details += "Methods:\n"
|
||||
for method_name, method_docstring, method_parameters in methods:
|
||||
details += f" - {method_name}({', '.join([f'{param[0]}: {param[1]}' for param in json.loads(method_parameters)])})\n"
|
||||
details += f" Description: {method_docstring}\n"
|
||||
|
||||
conn.close()
|
||||
return details
|
||||
|
||||
except Exception as e:
|
||||
return trace_exception(e)
|
||||
|
||||
|
||||
def search_class_in_project_function(project_path):
|
||||
return {
|
||||
"function_name": "create_project_database",
|
||||
"function": partial(search_class_in_project, project_path=project_path),
|
||||
"function_description": "Searches for a specific class by name in the project database and returns detailed information.",
|
||||
"function_parameters": [{"name":"class_name", "type":"str", "description":"Name of the class to search"}]
|
||||
}
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Example usage
|
||||
db_path = "path/to/project_info.db"
|
||||
class_name = "MyClass"
|
||||
print(search_class_in_project(db_path, class_name))
|
@ -3587,7 +3587,7 @@ The AI should respond in this format using data from actions_list:
|
||||
|
||||
outputs = self.execute_function_calls(function_calls,function_definitions)
|
||||
final_output = "\n".join([str(o) if type(o)==str else str(o[0]) if (type(o)==tuple or type(0)==list) and len(o)>0 else "" for o in outputs])
|
||||
out += f"{separator_template}{start_header_id_template}function calls results{end_header_id_template}\n" + final_output
|
||||
out += f"{separator_template}{start_header_id_template}function calls results{end_header_id_template}\n" + final_output + "\n"
|
||||
if prompt_after_execution:
|
||||
if separate_output:
|
||||
self.full(final_output)
|
||||
|
Loading…
x
Reference in New Issue
Block a user