| import os | |
| import openai | |
| import threading | |
| import tkinter as tk | |
| from tkinter import scrolledtext, messagebox | |
| # Optionally, uncomment and hardcode for testing ONLY (never for shared code) | |
| # os.environ["OPENAI_API_KEY"] = "sk-your-real-api-key" | |
| openai.api_key = os.environ.get("OPENAI_API_KEY") | |
| MODEL_NAME = "ft:gpt-4.1-2025-04-14:raiffs-bits:codette-final:BOc2GYND:ckpt-step-16" | |
| def get_codette_response(user_query): | |
| try: | |
| response = openai.chat.completions.create( | |
| model=MODEL_NAME, | |
| messages=[ | |
| {"role": "system", "content": "You are Codette, an advanced multi-agent AI assistant."}, | |
| {"role": "user", "content": user_query} | |
| ], | |
| temperature=0.8, | |
| max_tokens=512, | |
| ) | |
| return response.choices[0].message.content.strip() | |
| except Exception as e: | |
| return f"[Error: {str(e)}]" | |
| class CodetteApp(tk.Tk): | |
| def __init__(self): | |
| super().__init__() | |
| self.title("Codette Universal Reasoning Assistant") | |
| self.geometry("650x480") | |
| self.configure(bg="#eef6f9") | |
| self.protocol("WM_DELETE_WINDOW", self.safe_exit) # For thread cleanup | |
| title = tk.Label(self, text="Ask Codette", font=("Helvetica", 18, "bold"), bg="#eef6f9") | |
| title.pack(pady=10) | |
| self.input_field = tk.Entry(self, font=("Calibri", 14), width=60) | |
| self.input_field.pack(pady=4) | |
| self.input_field.focus() | |
| self.input_field.bind("<Return>", lambda event: self.handle_ask()) | |
| ask_btn = tk.Button(self, text="Ask", font=("Calibri", 12), command=self.handle_ask) | |
| ask_btn.pack(pady=4) | |
| output_label = tk.Label(self, text="Codette's Answer:", bg="#eef6f9") | |
| output_label.pack() | |
| self.output_box = scrolledtext.ScrolledText(self, font=("Consolas", 12), height=15, width=75, wrap=tk.WORD) | |
| self.output_box.pack(pady=5) | |
| self.output_box.configure(state='disabled') | |
| clear_btn = tk.Button(self, text="Clear", command=self.clear_all) | |
| clear_btn.pack(pady=3) | |
| self.threads = [] | |
| def handle_ask(self): | |
| user_query = self.input_field.get().strip() | |
| if not user_query: | |
| messagebox.showwarning("Input Required", "Please enter your question.") | |
| return | |
| self.input_field.delete(0, tk.END) | |
| self.append_output(f"User: {user_query}", prefix_newline=True) | |
| self.append_output("Codette: ...thinking...") | |
| def fetch_and_display(): | |
| answer = get_codette_response(user_query) | |
| self.append_output(f"Codette: {answer}", replace_last=True) | |
| self.output_box.yview_moveto(1.0) | |
| t = threading.Thread(target=fetch_and_display, daemon=True) | |
| self.threads.append(t) | |
| t.start() | |
| def append_output(self, text, prefix_newline=False, replace_last=False): | |
| self.output_box.configure(state='normal') | |
| if replace_last: | |
| output = self.output_box.get("1.0", tk.END).rstrip('\n').split('\n') | |
| # Remove previous 'Codette: ...thinking...' | |
| if output[-1].startswith("Codette: ...thinking..."): | |
| output = output[:-1] | |
| self.output_box.delete("1.0", tk.END) | |
| self.output_box.insert(tk.END, '\n'.join(output) + "\n") | |
| if prefix_newline and float(self.output_box.index(tk.END))-1 >= 1.0: | |
| self.output_box.insert(tk.END, "\n") | |
| self.output_box.insert(tk.END, text + "\n") | |
| self.output_box.configure(state='disabled') | |
| def clear_all(self): | |
| self.output_box.configure(state='normal') | |
| self.output_box.delete('1.0', tk.END) | |
| self.output_box.configure(state='disabled') | |
| def safe_exit(self): | |
| # Wait for threads if needed before closing | |
| self.destroy() | |
| if __name__ == "__main__": | |
| app = CodetteApp() | |
| app.mainloop() | |