Skip to content

Commit

Permalink
Merge pull request #6 from haseeb-heaven:feat/chat-history
Browse files Browse the repository at this point in the history
Add new chat mode for chatting with files and data
  • Loading branch information
haseeb-heaven authored Jan 8, 2024
2 parents ad68ba0 + c25aa35 commit 2d03efd
Show file tree
Hide file tree
Showing 9 changed files with 303 additions and 180 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ Here are the available commands:
- 🆘 `/help` - Display this help message.
- 📝 `/version` - Display the version of the interpreter.
- 🚪 `/exit` - Exit the interpreter.
- 📜 `/log` - Display the log.
- 📜 `/log` - Toggle different modes of logging.
-`/upgrade` - Upgrade the interpreter.
- 💻 `/shell` - Access the shell.

Expand Down Expand Up @@ -290,6 +290,8 @@ If you're interested in contributing to **Open-Code-Interpreter**, we'd love to
- **1.8.2** - Fixed **Interpreter Commands** </br>
- **1.8.3** - Added **Interpreter Commands** _Upgrade and Shell Support_.</br>
- **1.8.4** - Fixed **Interpreter Model switcher** _Bug_.</br>
**v1.9** - Added new **Chat mode** for Chatting with your **Files**,**Data** and more.</br>


## 📜 **License**

Expand Down
2 changes: 1 addition & 1 deletion history/history.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
[{"Assistant": {"Task": "how many files in current directory?", "Mode": "code", "OS": "MacOS", "Language": "python", "Model": "gemini/gemini-pro"}, "User": "Generate the code in python language for this task 'how many files in current directory? for Operating System: MacOS'.", "System": {"Code": "import os\n\n# Plan:\n# 1. Use os.listdir() to get a list of files in the current directory.\n# 2. Count the number of files in the list.\n# 3. Print the count.\n\n# Code Execution:\nnum_files = len(os.listdir())\nprint(f\"Number of files in the current directory: {num_files}\")", "Output": "Number of files in the current directory: 22\n"}}, {"Assistant": {"Task": "how many python files in current directory?", "Mode": "code", "OS": "MacOS", "Language": "python", "Model": "gemini/gemini-pro"}, "User": "Generate the code in python language for this task 'how many python files in current directory? for Operating System: MacOS'.", "System": {"Code": "import os\n\n# Plan:\n# 1. Get the current working directory.\n# 2. List all files in the current working directory.\n# 3. Filter the list of files to only include Python files.\n# 4. Count the number of Python files.\n\n# Code Execution:\ncurrent_directory = os.getcwd()\nfiles = os.listdir(current_directory)\npython_files = [file for file in files if file.endswith('.py')]\nnum_python_files = len(python_files)\n\n# Output:\nprint(f\"Number of Python files in the current directory: {num_python_files}\")", "Output": "Number of Python files in the current directory: 1\n"}}, {"Assistant": {"Task": "how many folders in current directory?", "Mode": "code", "OS": "MacOS", "Language": "python", "Model": "gemini/gemini-pro"}, "User": "Generate the code in python language for this task 'how many folders in current directory? for Operating System: MacOS'.", "System": {"Code": "import os\n\n# Plan:\n# 1. Use the os.listdir() function to get a list of all files and folders in the current directory.\n# 2. Use a loop to iterate through the list and count the number of folders.\n\n# Code Execution:\nnum_folders = 0\nfor item in os.listdir():\n if os.path.isdir(item):\n num_folders += 1\n\n# Output:\nprint(f\"Number of folders in the current directory: {num_folders}\")", "Output": "Number of folders in the current directory: 13\n"}}]
[{"assistant": {"task": "path is '/Users/haseeb-mir/Downloads/wheelz/dataz/' no show me all the file names and their types and their size", "mode": "code", "os": "MacOS", "language": "python", "model": "huggingface/codellama/CodeLlama-34b-Instruct-hf"}, "user": "Generate the code in python language for this task 'path is '/Users/haseeb-mir/Downloads/wheelz/dataz/' no show me all the file names and their types and their size for Operating System: MacOS'.", "system": {"code": "import os\n\npath = '/Users/haseeb-mir/Downloads/wheelz/dataz/'\n\nfor file in os.listdir(path):\n file_path = os.path.join(path, file)\n file_type = os.path.splitext(file)[1]\n file_size = os.path.getsize(file_path)\n print(f\"{file}: {file_type} ({file_size} bytes)\")", "output": "rdap.csv: .csv (190 bytes)\nstudents.xml: .xml (360 bytes)\n.DS_Store: (6148 bytes)\nfibz_30.txt: .txt (157 bytes)\npoem.txt: .txt (898 bytes)\nimage.jpeg: .jpeg (175839 bytes)\nstudents.json: .json (129 bytes)\n"}}, {"assistant": {"task": "path is '/Users/haseeb-mir/Downloads/wheelz/dataz/' no show me all the file names and their types and their size", "mode": "code", "os": "MacOS", "language": "python", "model": "huggingface/codellama/CodeLlama-34b-Instruct-hf"}, "user": "Generate the code in python language for this task 'path is '/Users/haseeb-mir/Downloads/wheelz/dataz/' no show me all the file names and their types and their size for Operating System: MacOS'.", "system": {"code": "import os\n\npath = '/Users/haseeb-mir/Downloads/wheelz/dataz/'\n\nfor file in os.listdir(path):\n file_path = os.path.join(path, file)\n file_type = os.path.splitext(file)[1]\n file_size = os.path.getsize(file_path)\n print(f\"{file}: {file_type} ({file_size} bytes)\")", "output": "rdap.csv: .csv (190 bytes)\nstudents.xml: .xml (360 bytes)\n.DS_Store: (6148 bytes)\nfibz_30.txt: .txt (157 bytes)\npoem.txt: .txt (898 bytes)\nimage.jpeg: .jpeg (175839 bytes)\nstudents.json: .json (129 bytes)\n"}}, {"assistant": {"task": "list all text files in current path", "mode": "code", "os": "MacOS", "language": "python", "model": "huggingface/codellama/CodeLlama-34b-Instruct-hf"}, "user": "Generate the code in python language for this task 'list all text files in current path for Operating System: MacOS'.", "system": {"code": "\nThis code uses the `os` module to list all files in the current directory, and then checks each file to see if it ends with the `.txt` extension. If it does, it adds it to a list of text files. The `list_text_files` function returns the list of text files.\n\nYou can also use the `glob` module to list all text files in the current directory, like this:", "output": ""}}, {"assistant": {"task": "list all text files in current path", "mode": "code", "os": "MacOS", "language": "python", "model": "huggingface/codellama/CodeLlama-34b-Instruct-hf"}, "user": "Generate the code in python language for this task 'list all text files in current path for Operating System: MacOS'.", "system": {"code": "\nThis code uses the `os` module to list all files in the current directory, and then checks each file to see if it ends with the `.txt` extension. If it does, it adds it to a list of text files. The `list_text_files` function returns the list of text files.\n\nYou can also use the `glob` module to list all text files in the current directory, like this:", "output": ""}}, {"assistant": {"task": "list all text files in current path", "mode": "code", "os": "MacOS", "language": "python", "model": "gemini/gemini-pro"}, "user": "Generate the code in python language for this task 'list all text files in current path for Operating System: MacOS'.", "system": {"code": "import os\n\n# Plan:\n# 1. Get the current working directory.\n# 2. List all files in the current working directory.\n# 3. Filter the list of files to only include text files.\n\n# Step 1: Get the current working directory.\ncwd = os.getcwd()\n\n# Step 2: List all files in the current working directory.\nfiles = os.listdir(cwd)\n\n# Step 3: Filter the list of files to only include text files.\ntext_files = [f for f in files if f.endswith('.txt')]\n\n# Print the list of text files.\nprint(text_files)", "output": "['requirements.txt', 'LICENSE.txt']\n"}}]
11 changes: 6 additions & 5 deletions interpreter.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,14 @@

def main():
parser = argparse.ArgumentParser(description='Code - Interpreter')
parser.add_argument('--exec', '-e', action='store_true', help='Execute the code')
parser.add_argument('--save_code', '-s', action='store_true', help='Save the generated code')
parser.add_argument('--mode', '-md', choices=['code', 'script', 'command','vision'], help='Select the mode (`code` for generating code, `script` for generating shell scripts, `command` for generating single line commands) `vision` for generating text from images')
parser.add_argument('--exec', '-e', action='store_true', default=False, help='Execute the code')
parser.add_argument('--save_code', '-s', action='store_true', default=False, help='Save the generated code')
parser.add_argument('--mode', '-md', choices=['code', 'script', 'command','vision','chat'], help='Select the mode (`code` for generating code, `script` for generating shell scripts, `command` for generating single line commands) `vision` for generating text from images')
parser.add_argument('--model', '-m', type=str, default='code-llama', help='Set the model for code generation. (Defaults to gpt-3.5-turbo)')
parser.add_argument('--version', '-v', action='version', version='%(prog)s 1.8.3')
parser.add_argument('--version', '-v', action='version', version='%(prog)s 1.9')
parser.add_argument('--lang', '-l', type=str, default='python', help='Set the interpreter language. (Defaults to Python)')
parser.add_argument('--display_code', '-dc', action='store_true', help='Display the code in output')
parser.add_argument('--display_code', '-dc', action='store_true', default=False, help='Display the code in output')
parser.add_argument('--history', '-hi', action='store_true', default=False, help='Use history as memory')
args = parser.parse_args()

# Check if only the application name is passed
Expand Down
81 changes: 0 additions & 81 deletions libs/history.py

This file was deleted.

112 changes: 112 additions & 0 deletions libs/history_manager.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import json
import logging
import os
from typing import List, Any
from libs.logger import Logger

class History:
def __init__(self, history_file: str):
self.history_file = history_file
self.logger = Logger.initialize_logger("logs/interpreter.log")

def save_history_json(self, task, mode, os_name, language, prompt, code_snippet, code_output, model_name, filename="history/history.json"):
try:
history_entry = {
"assistant": {
"task": task,
"mode": mode,
"os": os_name,
"language": language,
"model": model_name
},
"user": prompt,
"system": {
"code": code_snippet,
"output": code_output
}
}

data = []
if os.path.isfile(filename) and os.path.getsize(filename) > 0:
with open(filename, "r") as history_file: # Open the file in read mode
data = json.load(history_file)

data.append(history_entry)

with open(filename, "w") as history_file:
json.dump(data, history_file)
except Exception as exception:
self.logger.error(f"Error in saving history to JSON: {str(exception)}")
raise

def _get_data_for_key(self, key: str) -> List[Any]:
"""Returns a list of all values for the specified key in the history data."""
try:
if os.path.getsize(self.history_file) > 0:
with open(self.history_file, 'r') as file:
history_data = json.load(file)
else:
return []

specific_data = []
for entry in history_data:
if key in entry['assistant']:
specific_data.append(entry['assistant'].get(key))
elif key in entry['system']:
specific_data.append(entry['system'].get(key))
self.logger.info(f'Successfully retrieved {key} data from history')
return specific_data
except Exception as exception:
self.logger.error(f'Error getting {key} data from history: {exception}')
raise

def _get_last_entries(self, count: int) -> List[dict]:
"""Returns the last n entries from the history data."""
try:
with open(self.history_file, 'r') as file:
history_data = json.load(file)
last_entries = history_data[-count:]
self.logger.info(f'Successfully retrieved last {count} entries from history')
return last_entries
except Exception as exception:
self.logger.error(f'Error getting last {count} entries from history: {exception}')
raise

def _get_last_entries_for_key(self, key: str, count: int) -> List[Any]:
"""Returns the values of the specified key for the last n entries in the history data."""
try:
specific_key_data = self._get_data_for_key(key)
last_specific_data = specific_key_data[-count:]
if last_specific_data:
self.logger.info(f'Successfully retrieved {key} data for last {count} entries from history')
self.logger.info(f"\n'{last_specific_data}'\n")
return last_specific_data
else:
self.logger.info(f'No {key} data found in history')
return []
except Exception as exception:
self.logger.error(f'Error getting {key} data for last {count} entries from history: {exception}')
raise

def _get_last_entries_for_keys(self, count: int, *keys: str) -> List[dict]:
last_entries = []
try:
entries = {key: self._get_last_entries_for_key(key, count) for key in keys}

for index in range(count):
session = {key: entries[key][index] if index < len(entries[key]) else None for key in keys}
last_entries.append(session)

return last_entries
except Exception as exception:
self.logger.error(f'Error getting last {count} entries for keys {keys} from history: {exception}')
raise

def get_chat_history(self, count: int) -> List[dict]:
return self._get_last_entries_for_keys(count, "task", "output")

def get_code_history(self, count: int) -> List[dict]:
return self._get_last_entries_for_keys(count, "code", "output")

def get_full_history(self, count: int) -> List[dict]:
return self._get_last_entries_for_keys(count, "task", "code", "output")
Loading

0 comments on commit 2d03efd

Please sign in to comment.