Skip to content

Commit 92029db

Browse files
committed
OGC 1.0 Init
1 parent b9e4e57 commit 92029db

17 files changed

+13688
-0
lines changed

App/Ollama GUI Chat.spec

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# -*- mode: python ; coding: utf-8 -*-
2+
3+
4+
a = Analysis(
5+
['OllamaGUIChat.py'],
6+
pathex=[],
7+
binaries=[],
8+
datas=[],
9+
hiddenimports=[],
10+
hookspath=[],
11+
hooksconfig={},
12+
runtime_hooks=[],
13+
excludes=[],
14+
noarchive=False,
15+
optimize=0,
16+
)
17+
pyz = PYZ(a.pure)
18+
19+
exe = EXE(
20+
pyz,
21+
a.scripts,
22+
a.binaries,
23+
a.datas,
24+
[],
25+
name='Ollama GUI Chat',
26+
debug=False,
27+
bootloader_ignore_signals=False,
28+
strip=False,
29+
upx=True,
30+
upx_exclude=[],
31+
runtime_tmpdir=None,
32+
console=True,
33+
disable_windowed_traceback=False,
34+
argv_emulation=False,
35+
target_arch=None,
36+
codesign_identity=None,
37+
entitlements_file=None,
38+
)

App/OllamaGUIChat.py

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
import requests
2+
import json
3+
import tkinter as tk
4+
from tkinter import scrolledtext
5+
6+
# Base URL for the local Ollama API
7+
url = "http://localhost:11434/api/chat"
8+
model_name = "llama3.1" # Only model being used
9+
10+
class LlamaGUI:
11+
def __init__(self):
12+
self.messages = [] # Stores the conversation history
13+
self.dark_mode = False # Dark mode toggle
14+
15+
self.window = tk.Tk()
16+
self.window.title("Ollama Chat")
17+
self.window.geometry("700x700")
18+
19+
self.setup_ui()
20+
21+
def setup_ui(self):
22+
# Top-left frame for dark mode toggle
23+
top_frame = tk.Frame(self.window)
24+
top_frame.pack(anchor="nw", padx=10, pady=(10, 0))
25+
26+
self.dark_button = tk.Button(top_frame, text="🌗", command=self.toggle_dark_mode)
27+
self.dark_button.pack(side="left")
28+
29+
# Chat history (read-only)
30+
self.text_area = scrolledtext.ScrolledText(
31+
self.window, width=80, height=25, wrap="word",
32+
state="disabled", bg="white", fg="black"
33+
)
34+
self.text_area.pack(padx=10, pady=10)
35+
36+
# Input field
37+
self.entry_field = tk.Text(
38+
self.window, width=80, height=4, wrap="word",
39+
bg="white", fg="black"
40+
)
41+
self.entry_field.pack(padx=10, pady=5)
42+
self.entry_field.focus_set()
43+
44+
# Send button
45+
self.send_button = tk.Button(self.window, text="Send", command=self.send_message)
46+
self.send_button.pack(pady=5)
47+
48+
# Key bindings
49+
self.entry_field.bind("<Return>", self.on_enter)
50+
self.entry_field.bind("<Shift-Return>", self.insert_newline)
51+
52+
# GPL button
53+
self.gpl_button = tk.Button(top_frame, text="GPL License", command=self.show_gpl_license)
54+
self.gpl_button.pack(side="right")
55+
56+
# Set Dark mode as default
57+
self.toggle_dark_mode()
58+
59+
def show_gpl_license(self):
60+
gpl_window = tk.Toplevel(self.window)
61+
gpl_window.title("GPL License")
62+
gpl_text = tk.Label(gpl_window, text="""
63+
Copyright (c) 2025 by Kamil Wiśniewski <[email protected]>
64+
65+
This program lets you talk with AI models using the Ollama API.
66+
67+
This program is free software; you can redistribute it and/or modify
68+
it under the terms of the GNU General Public License as published by
69+
the Free Software Foundation; either version 3 of the License, or
70+
(at your option) any later version.
71+
72+
This program is distributed in the hope that it will be useful,
73+
but WITHOUT ANY WARRANTY; without even the implied warranty of
74+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
75+
GNU General Public License for more details.
76+
77+
You should have received a copy of the GNU General Public License
78+
along with this program; if not, see <https://www.gnu.org/licenses/gpl-3.0.en.html>
79+
""", justify="left")
80+
81+
gpl_text.pack(padx=10, pady=10)
82+
83+
def insert_newline(self, event):
84+
self.entry_field.insert(tk.INSERT, "\n")
85+
return "break"
86+
87+
def on_enter(self, event):
88+
self.send_button.invoke()
89+
return "break"
90+
91+
def insert_text(self, content):
92+
self.text_area.config(state="normal")
93+
self.text_area.insert(tk.END, content)
94+
self.text_area.see(tk.END)
95+
self.text_area.config(state="disabled")
96+
97+
def toggle_dark_mode(self):
98+
self.dark_mode = not self.dark_mode
99+
bg_color = "grey9" if self.dark_mode else "Slate Blue"
100+
fg_color = "#5ef75e" if self.dark_mode else "white"
101+
window_bg = "black" if self.dark_mode else "Dark Slate Blue"
102+
103+
self.text_area.config(bg=bg_color, fg=fg_color)
104+
self.entry_field.config(bg=bg_color, fg=fg_color)
105+
self.window.config(bg=window_bg)
106+
self.gpl_button.config(bg=window_bg, fg=fg_color)
107+
self.send_button.config(bg=window_bg, fg=fg_color)
108+
self.dark_button.config(bg=window_bg, fg=fg_color)
109+
110+
def send_message(self):
111+
question = self.entry_field.get("1.0", tk.END).strip()
112+
if not question:
113+
return
114+
115+
self.insert_text(f"You: {question}\n\n")
116+
self.entry_field.delete("1.0", tk.END)
117+
118+
self.messages.append({"role": "user", "content": question})
119+
self.send_button.config(state=tk.DISABLED)
120+
121+
payload = {
122+
"model": model_name,
123+
"messages": self.messages,
124+
"stream": True
125+
}
126+
127+
try:
128+
response = requests.post(url, json=payload, stream=True)
129+
130+
if response.status_code == 200:
131+
self.insert_text("AI: ")
132+
self.window.update()
133+
134+
full_reply = ""
135+
for line in response.iter_lines(decode_unicode=True):
136+
if line.strip():
137+
try:
138+
data = json.loads(line)
139+
content = data.get("message", {}).get("content", "")
140+
full_reply += content
141+
self.insert_text(content)
142+
self.window.update()
143+
144+
except json.JSONDecodeError:
145+
continue
146+
147+
self.messages.append({"role": "assistant", "content": full_reply})
148+
self.insert_text("\n\n")
149+
150+
else:
151+
self.insert_text(f"\nError: {response.status_code}\n{response.text}\n\n")
152+
153+
except requests.exceptions.RequestException as e:
154+
self.insert_text(f"\nError sending request: {e}\n\n")
155+
156+
self.send_button.config(state=tk.NORMAL)
157+
158+
def start(self):
159+
self.window.mainloop()
160+
161+
if __name__ == "__main__":
162+
llama_gui = LlamaGUI()
163+
llama_gui.start()
164+

0 commit comments

Comments
 (0)