Created
November 21, 2023 19:59
-
-
Save graylan0/24add30f54d38acbf7f9206dc354848b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import asyncio | |
import threading | |
import uuid | |
import logging | |
from concurrent.futures import ThreadPoolExecutor | |
from kivy.lang import Builder | |
from kivymd.app import MDApp | |
from kivy.uix.screenmanager import ScreenManager, Screen | |
from kivy.properties import StringProperty | |
from kivy.uix.label import Label | |
import weaviate | |
from llama_cpp import Llama | |
import platform | |
if platform.system() == 'Windows': | |
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy()) | |
KV = ''' | |
ScreenManager: | |
ChatScreen: | |
SettingsScreen: | |
<ChatScreen>: | |
name: 'chat' | |
BoxLayout: | |
orientation: 'vertical' | |
ActionBar: | |
background_color: 0.3, 0.3, 0.3, 1 | |
pos_hint: {'top':1} | |
ActionView: | |
use_separator: True | |
ActionPrevious: | |
title: 'Chat with Bot' | |
with_previous: False | |
app_icon: '' | |
color: 1, 1, 1, 1 | |
ActionButton: | |
icon: 'brain' | |
on_release: app.analyze_emotion(message_input.text) | |
color: 0.9, 0.9, 0.9, 1 | |
ActionButton: | |
text: 'Settings' | |
on_release: app.root.current = 'settings' | |
color: 0.9, 0.9, 0.9, 1 | |
BoxLayout: | |
canvas.before: | |
Color: | |
rgba: 0.2, 0.2, 0.2, 1 | |
Rectangle: | |
pos: self.pos | |
size: self.size | |
RecycleView: | |
id: chat_list | |
viewclass: 'ChatLabel' | |
RecycleBoxLayout: | |
default_size: None, dp(56) | |
default_size_hint: 1, None | |
size_hint_y: None | |
height: self.minimum_height | |
orientation: 'vertical' | |
spacing: dp(2) | |
BoxLayout: | |
size_hint_y: None | |
height: dp(50) | |
padding: dp(4) | |
spacing: dp(4) | |
canvas.before: | |
Color: | |
rgba: 0.1, 0.1, 0.1, 1 | |
Rectangle: | |
pos: self.pos | |
size: self.size | |
TextInput: | |
id: message_input | |
hint_text: 'Type a message...' | |
background_color: 1, 1, 1, 0.3 | |
foreground_color: 1, 1, 1, 1 | |
size_hint_x: 0.8 | |
multiline: False | |
on_text_validate: app.llama_generate_wrapper(message_input.text) | |
Button: | |
text: 'Send' | |
background_normal: '' | |
background_color: 0.8, 0.8, 0.8, 1 | |
color: 0, 0, 0, 1 | |
on_release: app.llama_generate_wrapper(message_input.text) | |
<SettingsScreen>: | |
name: 'settings' | |
BoxLayout: | |
orientation: 'vertical' | |
ActionBar: | |
background_color: 0.3, 0.3, 0.3, 1 | |
pos_hint: {'top':1} | |
ActionView: | |
use_separator: True | |
ActionPrevious: | |
title: 'Settings' | |
with_previous: False | |
app_icon: '' | |
color: 1, 1, 1, 1 | |
ActionButton: | |
text: 'Back' | |
on_release: app.root.current = 'chat' | |
color: 0.9, 0.9, 0.9, 1 | |
GridLayout: | |
cols: 1 | |
padding: dp(24) | |
spacing: dp(15) | |
TextInput: | |
id: api_key | |
hint_text: 'OpenAI API Key' | |
multiline: False | |
padding_y: dp(10) | |
padding_x: dp(10) | |
size_hint_x: 0.8 | |
pos_hint: {'center_x': 0.5} | |
Button: | |
text: 'Save Settings' | |
size_hint_x: 0.8 | |
pos_hint: {'center_x': 0.5} | |
on_release: app.save_settings(api_key.text) | |
<ChatLabel>: | |
size_hint_y: None | |
height: self.texture_size[1] | |
padding: 10, 10 | |
halign: 'left' | |
valign: 'middle' | |
text_size: self.width, None | |
''' | |
class ChatScreen(Screen): | |
pass | |
class SettingsScreen(Screen): | |
pass | |
class ChatLabel(Label): | |
text = StringProperty() | |
class ChatApp(MDApp): | |
def __init__(self, **kwargs): | |
super().__init__(**kwargs) | |
self.loop = asyncio.new_event_loop() | |
self.executor = ThreadPoolExecutor(max_workers=4) | |
def start_async_loop(self): | |
asyncio.set_event_loop(self.loop) | |
self.loop.run_forever() | |
def build(self): | |
threading.Thread(target=self.start_async_loop, daemon=True).start() | |
self.screen_manager = ScreenManager() | |
self.screen_manager.add_widget(ChatScreen(name='chat')) | |
self.screen_manager.add_widget(SettingsScreen(name='settings')) | |
self.client = weaviate.Client(url="https://tolerant-subtly-foxhound.ngrok-free.app") | |
self.llm = Llama( | |
model_path="llama-2-7b-chat.ggmlv3.q8_0.bin", | |
n_gpu_layers=-1, | |
n_ctx=3900, | |
) | |
return Builder.load_string(KV) | |
def llama_generate_wrapper(self, prompt): | |
print("Llama generate wrapper called") | |
coroutine = self.llama_generate(prompt) | |
asyncio.run_coroutine_threadsafe(coroutine, self.loop) | |
async def llama_generate(self, prompt, max_tokens=2500, chunk_size=500): | |
try: | |
print("Llama generate called with prompt:", prompt) | |
prompt_chunks = [prompt[i:i + chunk_size] for i in range(0, len(prompt), chunk_size)] | |
responses = [] | |
last_output = "" | |
for i, chunk in enumerate(prompt_chunks): | |
# Adjust this line to correctly pass arguments to the Llama model | |
output_dict = await asyncio.get_event_loop().run_in_executor(self.executor, lambda: self.llm(chunk, max_tokens=min(max_tokens, chunk_size))) | |
output = output_dict.get('text', '') | |
if i > 0 and last_output: | |
overlap = len(set(last_output[-300:]).intersection(set(output[:300]))) | |
output = output[overlap:] | |
responses.append(output) | |
last_output = output | |
final_response = ''.join(responses) | |
print("Llama generate response:", final_response) | |
return final_response | |
except Exception as e: | |
logging.error(f"Llama generate error: {e}") | |
return "Error in generating response." | |
async def retrieve_past_interactions(self): | |
query = { | |
"class": "InteractionHistory", | |
"properties": ["user_message", "ai_response"], | |
} | |
response = await asyncio.get_event_loop().run_in_executor(self.executor, self.client.query.raw, query) | |
interactions = response['data']['Get']['InteractionHistory'] | |
return interactions | |
def format_prompt(self, past_interactions, current_message): | |
formatted_interactions = "\n".join([f"User: {interaction['user_message']}\nAI: {interaction['ai_response']}" for interaction in past_interactions]) | |
return f"{formatted_interactions}\nUser: {current_message}" | |
async def store_interaction_in_weaviate(self, user_message, ai_response): | |
interaction_object = { | |
"user_message": user_message, | |
"ai_response": ai_response, | |
} | |
interaction_uuid = uuid.uuid4() | |
await asyncio.get_event_loop().run_in_executor(self.executor, self.client.data_object.create, interaction_object, "InteractionHistory", interaction_uuid) | |
def save_settings(self, api_key): | |
pass | |
if __name__ == '__main__': | |
ChatApp().run() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment