d-e-e-k-11 commited on
Commit
0dd218e
·
verified ·
1 Parent(s): 9cf52c7

Add tkinter_app.py

Browse files
Files changed (1) hide show
  1. tkinter_app.py +229 -0
tkinter_app.py ADDED
@@ -0,0 +1,229 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import tkinter as tk
2
+ import customtkinter as ctk
3
+ from llama_cpp import Llama
4
+ import threading
5
+ import os
6
+ import sys
7
+
8
+ # Set appearance and theme
9
+ ctk.set_appearance_mode("Dark")
10
+ ctk.set_default_color_theme("blue")
11
+
12
+ class LlamaChatApp(ctk.CTk):
13
+ def __init__(self, model_path):
14
+ super().__init__()
15
+
16
+ self.title("AI Chatbot - Llama-2-7B")
17
+ self.geometry("1100x750")
18
+
19
+ # Grid configuration (Sidebar + Main)
20
+ self.grid_columnconfigure(1, weight=1)
21
+ self.grid_rowconfigure(0, weight=1)
22
+
23
+ # Sidebar
24
+ self.sidebar_frame = ctk.CTkFrame(self, width=220, corner_radius=0)
25
+ self.sidebar_frame.grid(row=0, column=0, sticky="nsew")
26
+ self.sidebar_frame.grid_rowconfigure(4, weight=1)
27
+
28
+ self.logo_label = ctk.CTkLabel(self.sidebar_frame, text="🦙 Llama AI", font=ctk.CTkFont(size=22, weight="bold"))
29
+ self.logo_label.grid(row=0, column=0, padx=20, pady=(30, 20))
30
+
31
+ self.clear_button = ctk.CTkButton(
32
+ self.sidebar_frame,
33
+ text="New Chat",
34
+ command=self.clear_chat,
35
+ fg_color="#333333",
36
+ hover_color="#444444",
37
+ height=40,
38
+ font=ctk.CTkFont(weight="bold")
39
+ )
40
+ self.clear_button.grid(row=1, column=0, padx=20, pady=10, sticky="ew")
41
+
42
+ # Theme Switcher
43
+ self.theme_label = ctk.CTkLabel(self.sidebar_frame, text="Appearance:", font=ctk.CTkFont(size=11))
44
+ self.theme_label.grid(row=4, column=0, padx=20, pady=(20, 0), sticky="w")
45
+
46
+ self.theme_option = ctk.CTkOptionMenu(
47
+ self.sidebar_frame,
48
+ values=["Dark", "Light"],
49
+ command=self.change_appearance_mode,
50
+ height=30,
51
+ fg_color="#333333",
52
+ button_color="#444444"
53
+ )
54
+ self.theme_option.grid(row=5, column=0, padx=20, pady=(5, 10), sticky="ew")
55
+
56
+ self.info_label = ctk.CTkLabel(
57
+ self.sidebar_frame,
58
+ text="Model: Llama-2-7B\nFormat: GGMLv3\nType: Offline LLM",
59
+ font=ctk.CTkFont(size=11),
60
+ text_color="#888888",
61
+ justify="left"
62
+ )
63
+ self.info_label.grid(row=6, column=0, padx=20, pady=20, sticky="w")
64
+
65
+ # Main Content Area
66
+ self.main_container = ctk.CTkFrame(self, corner_radius=0, fg_color="#0f0f0f")
67
+ self.main_container.grid(row=0, column=1, sticky="nsew")
68
+ self.main_container.grid_columnconfigure(0, weight=1)
69
+ self.main_container.grid_rowconfigure(1, weight=1)
70
+
71
+ # Header in Main Area
72
+ self.header = ctk.CTkFrame(self.main_container, height=60, corner_radius=0, fg_color="#1a1a1a")
73
+ self.header.grid(row=0, column=0, sticky="ew")
74
+ self.header.grid_columnconfigure(0, weight=1)
75
+
76
+ self.title_label = ctk.CTkLabel(
77
+ self.header,
78
+ text="Chat Session",
79
+ font=ctk.CTkFont(size=18, weight="bold")
80
+ )
81
+ self.title_label.grid(row=0, column=0, pady=20)
82
+
83
+ # Chat display
84
+ self.chat_display = ctk.CTkTextbox(
85
+ self.main_container,
86
+ state="disabled",
87
+ wrap="word",
88
+ font=ctk.CTkFont(size=15),
89
+ fg_color="#0d0d0d",
90
+ border_width=0,
91
+ text_color="#e0e0e0"
92
+ )
93
+ self.chat_display.grid(row=1, column=0, padx=30, pady=(20, 10), sticky="nsew")
94
+
95
+ # Configure tags for coloring
96
+ self.chat_display.tag_config("User", foreground="#3B82F6") # Blue
97
+ self.chat_display.tag_config("Llama-2", foreground="#10B981") # Green
98
+ self.chat_display.tag_config("System", foreground="#6B7280") # Grey
99
+
100
+ # Input area container (for centered look)
101
+ self.bottom_frame = ctk.CTkFrame(self.main_container, fg_color="transparent")
102
+ self.bottom_frame.grid(row=2, column=0, padx=30, pady=(10, 20), sticky="ew")
103
+ self.bottom_frame.grid_columnconfigure(0, weight=1)
104
+
105
+ self.user_input = ctk.CTkEntry(
106
+ self.bottom_frame,
107
+ placeholder_text="Message Llama-2...",
108
+ font=ctk.CTkFont(size=14),
109
+ height=50,
110
+ border_width=1,
111
+ border_color="#333333",
112
+ corner_radius=12,
113
+ fg_color="#1a1a1a"
114
+ )
115
+ self.user_input.grid(row=0, column=0, padx=(0, 10), sticky="ew")
116
+ self.user_input.bind("<Return>", lambda e: self.send_message())
117
+
118
+ self.send_button = ctk.CTkButton(
119
+ self.bottom_frame,
120
+ text="Send",
121
+ command=self.send_message,
122
+ width=90,
123
+ height=50,
124
+ corner_radius=12,
125
+ font=ctk.CTkFont(weight="bold")
126
+ )
127
+ self.send_button.grid(row=0, column=1)
128
+
129
+ # Status indicator
130
+ self.status_container = ctk.CTkFrame(self.main_container, height=25, fg_color="transparent")
131
+ self.status_container.grid(row=3, column=0, sticky="ew", padx=30, pady=(0, 10))
132
+
133
+ self.status_dot = ctk.CTkLabel(self.status_container, text="●", font=ctk.CTkFont(size=14), text_color="#f44336")
134
+ self.status_dot.pack(side="left")
135
+
136
+ self.status_text = ctk.CTkLabel(self.status_container, text="OFFLINE", font=ctk.CTkFont(size=11, weight="bold"), text_color="#888888")
137
+ self.status_text.pack(side="left", padx=5)
138
+
139
+ # LLM Logic
140
+ self.model_path = model_path
141
+ self.llm = None
142
+ self.is_loading = True
143
+
144
+ threading.Thread(target=self.init_model, daemon=True).start()
145
+
146
+ def change_appearance_mode(self, new_mode):
147
+ ctk.set_appearance_mode(new_mode)
148
+ bg = "#0f0f0f" if new_mode == "Dark" else "#f5f5f5"
149
+ chat_bg = "#0d0d0d" if new_mode == "Dark" else "#ffffff"
150
+ text_col = "#e0e0e0" if new_mode == "Dark" else "#1a1a1a"
151
+ header_bg = "#1a1a1a" if new_mode == "Dark" else "#ebebeb"
152
+
153
+ self.main_container.configure(fg_color=bg)
154
+ self.chat_display.configure(fg_color=chat_bg, text_color=text_col)
155
+ self.header.configure(fg_color=header_bg)
156
+
157
+ def init_model(self):
158
+ try:
159
+ self.llm = Llama(model_path=self.model_path, n_ctx=2048, n_threads=4, verbose=False)
160
+ self.is_loading = False
161
+ self.after(0, self.on_model_ready)
162
+ except Exception as e:
163
+ self.after(0, lambda: self.on_model_error(str(e)))
164
+
165
+ def on_model_ready(self):
166
+ self.status_dot.configure(text_color="#4CAF50")
167
+ self.status_text.configure(text="ONLINE", text_color="#4CAF50")
168
+ self.append_message("System", "Llama-2 is ready. Ask me anything!")
169
+
170
+ def on_model_error(self, error):
171
+ self.status_text.configure(text=f"ERROR: {error}", text_color="#f44336")
172
+ self.append_message("System", "Failed to load model. Check path.")
173
+
174
+ def clear_chat(self):
175
+ self.chat_display.configure(state="normal")
176
+ self.chat_display.delete("0.0", "end")
177
+ self.chat_display.configure(state="disabled")
178
+ if not self.is_loading:
179
+ self.append_message("System", "Chat cleared. Starting new session.")
180
+
181
+ def append_message(self, sender, message):
182
+ self.chat_display.configure(state="normal")
183
+
184
+ tag = sender
185
+ if sender == "User":
186
+ display_name = "👤 YOU"
187
+ elif sender == "Llama-2":
188
+ display_name = "🦙 LLAMA-2"
189
+ else:
190
+ display_name = "⚙️ SYSTEM"
191
+ tag = "System"
192
+
193
+ self.chat_display.insert("end", f"{display_name}\n", (tag,))
194
+ self.chat_display.insert("end", f"{message}\n\n")
195
+
196
+ self.chat_display.configure(state="disabled")
197
+ self.chat_display.see("end")
198
+
199
+ def send_message(self):
200
+ if self.is_loading: return
201
+ msg = self.user_input.get().strip()
202
+ if not msg: return
203
+ self.user_input.delete(0, "end")
204
+ self.append_message("User", msg)
205
+ self.send_button.configure(state="disabled")
206
+ self.status_text.configure(text="THINKING...", text_color="#FFA726")
207
+ threading.Thread(target=self.generate_response, args=(msg,), daemon=True).start()
208
+
209
+ def generate_response(self, message):
210
+ try:
211
+ prompt = f"[INST] <<SYS>>\nYou are a helpful assistant.\n<</SYS>>\n\n{message} [/INST]"
212
+ output = self.llm(prompt, max_tokens=1024, stop=["[/INST]", "</s>"], echo=False)
213
+ response = output['choices'][0]['text'].strip()
214
+ self.after(0, lambda: self.append_message("Llama-2", response))
215
+ self.after(0, lambda: self.status_text.configure(text="ONLINE", text_color="#4CAF50"))
216
+ except Exception as e:
217
+ self.after(0, lambda: self.append_message("System", f"Error: {str(e)}"))
218
+ finally:
219
+ self.after(0, lambda: self.send_button.configure(state="normal"))
220
+
221
+ if __name__ == "__main__":
222
+ MODEL_PATH = r"C:\Users\student\Downloads\llama-2-7b-chat.ggmlv3.q2_K.bin"
223
+
224
+ if not os.path.exists(MODEL_PATH):
225
+ print(f"Error: Model not found at {MODEL_PATH}")
226
+ sys.exit(1)
227
+
228
+ app = LlamaChatApp(MODEL_PATH)
229
+ app.mainloop()