Skip to content

Commit

Permalink
Merge pull request #2 from sbslee/0.3.0-dev
Browse files Browse the repository at this point in the history
0.3.0 dev
  • Loading branch information
sbslee authored May 30, 2023
2 parents b40dbc4 + 3c3d066 commit 69d35ab
Show file tree
Hide file tree
Showing 16 changed files with 219 additions and 139 deletions.
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
# CHANGELOG

## 0.3.0 (2023-03-30)
* Add multi-document chat functionality.
* Add chat functionality for additional document formats (.pdf, .doc, and .docx).

## 0.2.0 (2023-03-27)
* Enable users to initiate a new chat session.
* Enable users to choose their preferred GPT model.
* Enable users to chat with their documents.
* Enable users to chat with their text (.txt) documents.

## 0.1.0 (2023-03-24)
* Initial release.
29 changes: 16 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,28 @@

KANU is a minimalistic Python-based GUI for various chatbots.

## Chatbots

### ChatGPT

![Alt Text](https://raw.githubusercontent.com/sbslee/kanu/main/images/chatgpt.gif)

### DocGPT

![Alt Text](https://raw.githubusercontent.com/sbslee/kanu/main/images/docgpt.gif)

## Installation

```
$ pip install kanu
```

## Screenshots
## Running

### Homepage

![Alt Text](./images/home.png)

### ChatGPT

![Alt Text](./images/chatgpt-1.png)
![Alt Text](./images/chatgpt-2.png)
```
$ kanu
```

### DocGPT
## Changelog

![Alt Text](./images/docgpt-1.png)
![Alt Text](./images/docgpt-2.png)
![Alt Text](./images/docgpt-3.png)
See the [CHANGELOG.md](./CHANGELOG.md) file for details.
Binary file removed images/chatgpt-1.png
Binary file not shown.
Binary file removed images/chatgpt-2.png
Binary file not shown.
Binary file added images/chatgpt.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed images/docgpt-1.png
Binary file not shown.
Binary file removed images/docgpt-2.png
Binary file not shown.
Binary file removed images/docgpt-3.png
Binary file not shown.
Binary file added images/docgpt.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed images/home.png
Binary file not shown.
112 changes: 71 additions & 41 deletions kanu/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,60 +2,86 @@
import importlib.util

from .version import __version__
from .utils import Tooltip

class KANU:
def __init__(self, root):
self.container = None
self.root = root
self.root.title(f"KANU ({__version__})")
self.root.geometry("600x400")
self.home_page()
self.homepage()

def home_page(self):
def homepage(self):
if self.container is not None:
self.container.pack_forget()
self.container = tk.Frame(self.root)
self.container.pack()
title_label = tk.Message(self.container, width=350, text="Welcome to KANU, a minimalistic Python-based GUI for various chatbots! Please select a chatbot to begin.")
title_label.pack()
chatgpt_button = tk.Button(self.container, text="ChatGPT", command=lambda: self.chatgpt_config())
chatgpt_button.pack()
docgpt_button = tk.Button(self.container, text="DocGPT", command=lambda: self.docgpt_config())
docgpt_button.pack()
l = tk.Message(self.container, width=350, text="Welcome to KANU, a minimalistic Python-based GUI for various chatbots! Please select a chatbot to begin.")
l.pack()
b = tk.Button(self.container, text="ChatGPT", command=lambda: self.config_chatgpt())
b.pack()
b = tk.Button(self.container, text="DocGPT", command=lambda: self.config_docgpt())
b.pack()

def chatgpt_config(self):
def config_chatgpt(self):
self.container.pack_forget()
self.container = tk.Frame(self.root)
self.container.pack()
title_label = tk.Label(self.container, text="ChatGPT")
title_label.grid(row=0, column=0, columnspan=2)
self._list_dependencies(1, ["openai"])
key_label = tk.Label(self.container, text="OpenAI API key:")
key_label.grid(row=3, column=0, columnspan=2)
key_entry = tk.Entry(self.container)
key_entry.grid(row=4, column=0, columnspan=2)
submit_button = tk.Button(self.container, text="Submit", command=lambda: self._deploy("ChatGPT", key_entry.get()))
submit_button.grid(row=5, column=0)
back_button = tk.Button(self.container, text="Go back", command=lambda: self.home_page())
back_button.grid(row=5, column=1)
l = tk.Label(self.container, text="ChatGPT")
l.grid(row=0, column=0, columnspan=2)
l = tk.Label(self.container, text="Required packages:")
l.grid(row=1, column=0, columnspan=2)
self.display_required_dependency(2, "openai")
self.model = tk.StringVar(self.container, value="gpt-3.5-turbo")
l = tk.Label(self.container, text="Model:")
l.grid(row=3, column=0, columnspan=2)
b = tk.Radiobutton(self.container, variable=self.model, text="gpt-3.5-turbo", value="gpt-3.5-turbo")
b.grid(row=4, column=0)
b = tk.Radiobutton(self.container, variable=self.model, text="gpt-4", value="gpt-4")
b.grid(row=4, column=1)
l = tk.Label(self.container, text="OpenAI API key:")
l.grid(row=5, column=0, columnspan=2)
e = tk.Entry(self.container)
e.grid(row=6, column=0, columnspan=2)
b = tk.Button(self.container, text="Submit", command=lambda: self.deploy_agent("ChatGPT", e.get(), self.model.get()))
b.grid(row=7, column=0)
b = tk.Button(self.container, text="Go back", command=lambda: self.homepage())
b.grid(row=7, column=1)

def docgpt_config(self):
def config_docgpt(self):
self.container.pack_forget()
self.container = tk.Frame(self.root)
self.container.pack()
title_label = tk.Label(self.container, text="DocGPT")
title_label.grid(row=0, column=0, columnspan=2)
self._list_dependencies(1, ["langchain", "chromadb", "tiktoken"])
key_label = tk.Label(self.container, text="OpenAI API key:")
key_label.grid(row=5, column=0, columnspan=2)
key_entry = tk.Entry(self.container)
key_entry.grid(row=6, column=0, columnspan=2)
submit_button = tk.Button(self.container, text="Submit", command=lambda: self._deploy("DocGPT", key_entry.get()))
submit_button.grid(row=7, column=0)
back_button = tk.Button(self.container, text="Go back", command=lambda: self.home_page())
back_button.grid(row=7, column=1)
l = tk.Label(self.container, text="DocGPT")
l.grid(row=0, column=0, columnspan=2)
l = tk.Label(self.container, text="Required packages:")
l.grid(row=1, column=0, columnspan=2)
self.display_required_dependency(2, "langchain")
self.display_required_dependency(3, "chromadb")
self.display_required_dependency(4, "tiktoken")
l = tk.Label(self.container, text="Optional packages:")
l.grid(row=5, column=0, columnspan=2)
self.display_optional_dependency(6, "pdfminer.six", "pdfminer", "Required for .pdf documents.")
self.display_optional_dependency(7, "unstructured", "unstructured", "Required for .doc and .docx documents.")
self.display_optional_dependency(8, "tabulate", "tabulate", "Required for .doc and .docx documents.")
self.model = tk.StringVar(self.container, value="gpt-3.5-turbo")
l = tk.Label(self.container, text="Model:")
l.grid(row=9, column=0, columnspan=2)
b = tk.Radiobutton(self.container, variable=self.model, text="gpt-3.5-turbo", value="gpt-3.5-turbo")
b.grid(row=10, column=0)
b = tk.Radiobutton(self.container, variable=self.model, text="gpt-4", value="gpt-4")
b.grid(row=10, column=1)
l = tk.Label(self.container, text="OpenAI API key:")
l.grid(row=11, column=0, columnspan=2)
e = tk.Entry(self.container)
e.grid(row=12, column=0, columnspan=2)
b = tk.Button(self.container, text="Submit", command=lambda: self.deploy_agent("DocGPT", e.get(), self.model.get()))
b.grid(row=13, column=0)
b = tk.Button(self.container, text="Go back", command=lambda: self.homepage())
b.grid(row=13, column=1)

def _deploy(self, agent, *args, **kwargs):
def deploy_agent(self, agent, *args, **kwargs):
if agent == "ChatGPT":
from .chatgpt import ChatGPT
chatgpt = ChatGPT(self, *args, **kwargs)
Expand All @@ -66,15 +92,19 @@ def _deploy(self, agent, *args, **kwargs):
docgpt.run()
else:
raise ValueError(f"Unknown agent {agent}")

def display_required_dependency(self, row, package_name):
l = tk.Label(self.container, text=package_name)
l.grid(row=row, column=0)
l = tk.Label(self.container, text="❌" if importlib.util.find_spec(package_name) is None else "✅")
l.grid(row=row, column=1)

def _list_dependencies(self, row, packages):
title = tk.Label(self.container, text="Required packages:")
title.grid(row=row, column=0, columnspan=2)
for i, package in enumerate(packages, row+1):
name = tk.Label(self.container, text=package)
name.grid(row=i, column=0)
status = tk.Label(self.container, text="❌" if importlib.util.find_spec(package) is None else "✅")
status.grid(row=i, column=1)
def display_optional_dependency(self, row, package_name, package_import, tooltip):
l = tk.Label(self.container, text=f"{package_name} ⓘ")
Tooltip(l, tooltip)
l.grid(row=row, column=0)
l = tk.Label(self.container, text="❌" if importlib.util.find_spec(package_import) is None else "✅")
l.grid(row=row, column=1)

def main():
root = tk.Tk()
Expand Down
48 changes: 20 additions & 28 deletions kanu/chatgpt.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,51 +3,43 @@
import openai

class ChatGPT:
def __init__(self, kanu, openai_key):
def __init__(self, kanu, openai_key, model):
self.kanu = kanu
self.kanu.container.pack_forget()
self.kanu.container = tk.Frame(self.kanu.root)
self.kanu.container.pack()
self.model = model
openai.api_key = openai_key

def run(self):
title_label = tk.Label(self.kanu.container, text="ChatGPT")
title_label.grid(row=0, column=0, columnspan=3)
self.model = tk.StringVar(self.kanu.container, value="gpt-3.5-turbo")
model_label = tk.Label(self.kanu.container, text="Model:")
model_label.grid(row=1, column=0)
model1_button = tk.Radiobutton(self.kanu.container, variable=self.model, text="gpt-3.5-turbo", value="gpt-3.5-turbo")
model2_button = tk.Radiobutton(self.kanu.container, variable=self.model, text="gpt-4", value="gpt-4")
model1_button.grid(row=1, column=1)
model2_button.grid(row=1, column=2)
session_label = tk.Label(self.kanu.container, text="Chat session")
session_label.grid(row=2, column=0, columnspan=3)
self.kanu.container.pack_forget()
self.kanu.container = tk.Frame(self.kanu.root)
self.kanu.container.pack()
l = tk.Label(self.kanu.container, text="ChatGPT")
l.grid(row=0, column=0, columnspan=3)
self.session = tk.Text(self.kanu.container, width=70, height=20)
self.session.grid(row=3, column=0, columnspan=3)
entry = tk.Entry(self.kanu.container, width=54)
entry.grid(row=4, column=0, columnspan=3)
self.session.grid(row=1, column=0, columnspan=3)
e = tk.Entry(self.kanu.container, width=54)
e.grid(row=2, column=0, columnspan=3)
self.messages = []
send_button = tk.Button(self.kanu.container, text="Send", command=lambda: self._send_message(entry))
send_button.grid(row=5, column=0)
clear_butoon = tk.Button(self.kanu.container, text="Clear", command=lambda: self._clear_session())
clear_butoon.grid(row=5, column=1)
back_button = tk.Button(self.kanu.container, text="Go back", command=lambda: self.kanu.chatgpt_config())
back_button.grid(row=5, column=2)
b = tk.Button(self.kanu.container, text="Send", command=lambda: self.send_message(e))
b.grid(row=3, column=0)
b = tk.Button(self.kanu.container, text="Clear", command=lambda: self.clear_session())
b.grid(row=3, column=1)
b = tk.Button(self.kanu.container, text="Go back", command=lambda: self.kanu.config_chatgpt())
b.grid(row=3, column=2)

def _send_message(self, entry):
def send_message(self, entry):
if not self.messages:
self.messages.append({"role": "system", "content": "You are a helpful assistant."})
self.messages += [{"role": "user", "content": entry.get()}]
bot_response = openai.ChatCompletion.create(
model=self.model.get(),
model=self.model,
messages=self.messages,
)
response = bot_response["choices"][0]["message"]["content"]
self.messages += [{"role": "assistant", "content": response}]
self.session.insert(tk.END, "You: " + entry.get() + "\n")
self.session.insert(tk.END, f"Bot ({self.model.get()}): " + response + "\n")
self.session.insert(tk.END, f"Bot: " + response + "\n")
entry.delete(0, tk.END)

def _clear_session(self):
def clear_session(self):
self.session.delete(1.0, tk.END)
self.messages.clear()
Loading

0 comments on commit 69d35ab

Please sign in to comment.