#3102 Code Challenge: Database + LLM Chat GUI
- Get link
- X
- Other Apps
#3102 Code Challenge: Database + LLM Chat GUI
#3102 The attached image represents a graphical user interface for a python application to query tables from a database and submit the query results to an AI chatbot supported by a large language model (LLM). Provide python code to implement this application.
Below is a sample Python program that uses tkinter to create a GUI similar to your provided screenshot. This code illustrates how to:
-
Display a set of checkboxes for the four tables (NPR 7150.2D, NASA-STD-8739.8B, SSP 50038 (CBCS), CMMI-DEV v1.3).
-
Provide text entry fields for “Topic,” “Keywords,” “SWE,” “Section,” “Process Area,” “Action,” “Free form action,” “Template,” and “Chat Name.”
-
Offer buttons for “SUBMIT,” “RESET FORM,” “CLEAR CHAT,” and “COPY.”
-
Query a database (placeholder code provided—you can adapt to your actual DB) and feed that query result to an LLM (e.g., using the OpenAI API or any other LLM interface).
-
Display the LLM’s response in a scrolled text box.
You will need to adapt the placeholders for:
-
Database connectivity (connection string, schema, queries).
-
LLM call (e.g., setting your OpenAI API key or using another LLM library).
-
Fine-tuning layout or styling details to match your exact requirements.
import tkinter as tkfrom tkinter import ttk
from tkinter import scrolledtext
from tkinter import messagebox
import pyperclip # pip install pyperclip (if you want to copy to clipboard)
import sqlite3 # or any other DB library, e.g., psycopg2 for PostgreSQL
# import openai # Uncomment if using OpenAI
# ------------------------------------------------
# Placeholder function for querying the database
# ------------------------------------------------
def query_database(selected_tables, topic, keywords, swe, section,
process_area, action, free_form_action, template, chat_name):
"""
Replace this with actual DB logic. For demonstration, this simply
returns a string describing the query parameters.
"""
# Example pseudo-DB query logic (SQLite demonstration)
# Connect to your database
# con = sqlite3.connect("your_database.db")
# cur = con.cursor()
#
# Build dynamic SQL query based on selected_tables and filters
# For example:
# sql_query = "SELECT * FROM ... WHERE ..."
# cur.execute(sql_query)
# results = cur.fetchall()
# con.close()
#
# Return or process the results as needed
# For now, just return a string summarizing the inputs
summary = (
f"Selected Tables: {', '.join(selected_tables)}\n"
f"Topic: {topic}\n"
f"Keywords: {keywords}\n"
f"SWE: {swe}\n"
f"Section: {section}\n"
f"Process Area: {process_area}\n"
f"Action: {action}\n"
f"Free Form Action: {free_form_action}\n"
f"Template: {template}\n"
f"Chat Name: {chat_name}\n"
)
return summary
# ------------------------------------------------
# Placeholder function for calling the LLM
# ------------------------------------------------
def call_llm(prompt):
"""
Replace this with actual LLM logic. For demonstration, this simply
echoes the prompt. In production, you might call OpenAI or another LLM.
"""
# Example OpenAI usage (uncomment if using openai):
#
# openai.api_key = "YOUR_API_KEY"
# response = openai.ChatCompletion.create(
# model="gpt-4",
# messages=[
# {"role": "system", "content": "You are NASA requirements assistant."},
# {"role": "user", "content": prompt}
# ]
# )
# return response["choices"][0]["message"]["content"]
# For demonstration, just return the prompt as a "mock" response
return f"LLM Response:\n{prompt}"
# ------------------------------------------------
# Main Application Class
# ------------------------------------------------
class NASARequirementsApp(tk.Tk):
def __init__(self):
super().__init__()
self.title("NASA Requirements and Standards")
# ---------------------------
# Frames for layout
# ---------------------------
# Left frame for tutorial, example queries, and example actions
self.left_frame = ttk.Frame(self, padding="5 5 5 5")
self.left_frame.grid(row=0, column=0, sticky="nsew")
# Right frame for main inputs and response
self.right_frame = ttk.Frame(self, padding="5 5 5 5")
self.right_frame.grid(row=0, column=1, sticky="nsew")
# Make columns/rows resizable
self.columnconfigure(0, weight=1)
self.columnconfigure(1, weight=3)
self.rowconfigure(0, weight=1)
# ---------------------------
# Left frame content
# ---------------------------
tutorial_label = ttk.Label(self.left_frame, text="Tutorial")
tutorial_label.pack(anchor="w", pady=(0, 5))
# You can replace these with real content or a scrolled text
example_queries_label = ttk.Label(self.left_frame, text="Example Queries\nQuery1\nQuery2\nQuery3\nQuery4")
example_queries_label.pack(anchor="w", pady=(0, 15))
example_actions_label = ttk.Label(self.left_frame, text="Example Actions\nAction1\nAction2\nAction3\nAction4")
example_actions_label.pack(anchor="w")
# ---------------------------
# Right frame: Top row
# ---------------------------
# Tables (checkboxes)
tables_frame = ttk.Frame(self.right_frame)
tables_frame.pack(fill="x", pady=(0, 10))
tables_label = ttk.Label(tables_frame, text="Tables")
tables_label.pack(anchor="w")
# Variables for checkboxes
self.table_vars = {
"NPR 7150.2D": tk.BooleanVar(),
"NASA-STD-8739.8B": tk.BooleanVar(),
"SSP 50038 (CBCS)": tk.BooleanVar(),
"CMMI-DEV v1.3": tk.BooleanVar()
}
for table_name, var in self.table_vars.items():
chk = ttk.Checkbutton(tables_frame, text=table_name, variable=var)
chk.pack(anchor="w")
# ---------------------------
# Right frame: Middle row - user inputs
# ---------------------------
inputs_frame = ttk.Frame(self.right_frame)
inputs_frame.pack(fill="x", pady=(0, 10))
# Create a helper to build label + entry pairs
def create_label_entry(parent, label_text):
label = ttk.Label(parent, text=label_text, width=18, anchor="w")
entry_var = tk.StringVar()
entry = ttk.Entry(parent, textvariable=entry_var, width=30)
return label, entry, entry_var
self.topic_label, self.topic_entry, self.topic_var = create_label_entry(inputs_frame, "Topic:")
self.keywords_label, self.keywords_entry, self.keywords_var = create_label_entry(inputs_frame, "Keywords:")
self.swe_label, self.swe_entry, self.swe_var = create_label_entry(inputs_frame, "SWE:")
self.section_label, self.section_entry, self.section_var = create_label_entry(inputs_frame, "Section:")
self.process_area_label, self.process_area_entry, self.process_area_var = create_label_entry(inputs_frame, "Process Area:")
self.action_label, self.action_entry, self.action_var = create_label_entry(inputs_frame, "Action:")
self.free_form_label, self.free_form_entry, self.free_form_var = create_label_entry(inputs_frame, "Free Form Action:")
self.template_label, self.template_entry, self.template_var = create_label_entry(inputs_frame, "Template:")
self.chat_name_label, self.chat_name_entry, self.chat_name_var = create_label_entry(inputs_frame, "Chat Name:")
# Layout for the label-entry pairs
# (We will use a simple grid approach: label in col=0, entry in col=1)
row_index = 0
for (label, entry, _) in [
(self.topic_label, self.topic_entry, self.topic_var),
(self.keywords_label, self.keywords_entry, self.keywords_var),
(self.swe_label, self.swe_entry, self.swe_var),
(self.section_label, self.section_entry, self.section_var),
(self.process_area_label, self.process_area_entry, self.process_area_var),
(self.action_label, self.action_entry, self.action_var),
(self.free_form_label, self.free_form_entry, self.free_form_var),
(self.template_label, self.template_entry, self.template_var),
(self.chat_name_label, self.chat_name_entry, self.chat_name_var),
]:
label.grid(row=row_index, column=0, padx=5, pady=2, sticky="e")
entry.grid(row=row_index, column=1, padx=5, pady=2, sticky="w")
row_index += 1
# ---------------------------
# Right frame: Buttons
# ---------------------------
buttons_frame = ttk.Frame(self.right_frame)
buttons_frame.pack(fill="x", pady=(0, 10))
submit_button = ttk.Button(buttons_frame, text="SUBMIT", command=self.submit_query)
submit_button.pack(side="left", padx=5)
reset_button = ttk.Button(buttons_frame, text="RESET FORM", command=self.reset_form)
reset_button.pack(side="left", padx=5)
clear_button = ttk.Button(buttons_frame, text="CLEAR CHAT", command=self.clear_chat)
clear_button.pack(side="left", padx=5)
copy_button = ttk.Button(buttons_frame, text="COPY", command=self.copy_response)
copy_button.pack(side="left", padx=5)
# ---------------------------
# Right frame: Response text
# ---------------------------
response_label = ttk.Label(self.right_frame, text="RESPONSE")
response_label.pack(anchor="w")
self.response_text = scrolledtext.ScrolledText(self.right_frame, wrap=tk.WORD, width=80, height=15)
self.response_text.pack(fill="both", expand=True)
def submit_query(self):
"""
Collect input values, query database, call LLM, and show response.
"""
# Collect which tables are selected
selected_tables = [name for name, var in self.table_vars.items() if var.get()]
# Collect user inputs
topic = self.topic_var.get()
keywords = self.keywords_var.get()
swe = self.swe_var.get()
section = self.section_var.get()
process_area = self.process_area_var.get()
action = self.action_var.get()
free_form_action = self.free_form_var.get()
template = self.template_var.get()
chat_name = self.chat_name_var.get()
# Query the database (placeholder function)
db_result = query_database(
selected_tables,
topic,
keywords,
swe,
section,
process_area,
action,
free_form_action,
template,
chat_name
)
# Build a prompt for the LLM from the DB result
prompt = f"User wants information about:\n{db_result}\n"
# You can enhance the prompt with more instructions as needed
# Call the LLM (placeholder function)
llm_response = call_llm(prompt)
# Display the response
self.response_text.insert(tk.END, llm_response + "\n\n")
self.response_text.see(tk.END)
def reset_form(self):
"""
Clear all input fields and uncheck checkboxes.
"""
for var in self.table_vars.values():
var.set(False)
self.topic_var.set("")
self.keywords_var.set("")
self.swe_var.set("")
self.section_var.set("")
self.process_area_var.set("")
self.action_var.set("")
self.free_form_var.set("")
self.template_var.set("")
self.chat_name_var.set("")
def clear_chat(self):
"""
Clear the response text.
"""
self.response_text.delete("1.0", tk.END)
def copy_response(self):
"""
Copy the entire response text to the clipboard.
"""
text_to_copy = self.response_text.get("1.0", tk.END)
pyperclip.copy(text_to_copy)
messagebox.showinfo("Copied", "Response text copied to clipboard!")
# ------------------------------------------------
# Main entry point
# ------------------------------------------------
if __name__ == "__main__":
app = NASARequirementsApp()
app.mainloop()
How This Works
-
GUI Layout
-
The window is divided into a left frame (for tutorial, example queries/actions) and a right frame (for form inputs and the chatbot response).
-
The right frame has:
-
A “Tables” section with four checkboxes.
-
A series of text fields for Topic, Keywords, SWE, Section, Process Area, Action, Free Form Action, Template, and Chat Name.
-
Four buttons: SUBMIT, RESET FORM, CLEAR CHAT, and COPY.
-
A scrolled text widget labeled “RESPONSE,” which displays output from the LLM.
-
-
-
Database Query (Placeholder)
-
The
query_database(...)
function is just a placeholder. You can replace it with your real logic, including any SQL queries, connection parameters, or additional processing.
-
-
LLM Call (Placeholder)
-
The
call_llm(prompt)
function is also a placeholder. If you want to integrate with OpenAI’s API, you can uncomment and configure theopenai
lines. Or you can integrate with any other large language model library.
-
-
Event Flow
-
SUBMIT: Gathers all input data, queries the DB (placeholder), constructs a prompt, and then calls the LLM. The result is displayed in the scrolled text box.
-
RESET FORM: Clears all text fields and unchecks the table checkboxes.
-
CLEAR CHAT: Empties the scrolled text box.
-
COPY: Copies the entire scrolled text content to the system clipboard (using
pyperclip
).
-
Use this as a starting template. Adjust the styling, text, and logic to precisely match your NASA Requirements/Standards querying application.
The boxes in the image with text "<No xyz SELECTED>" are pulldowns pre-loaded with options
Below is an updated version of the code that uses pulldown menus (comboboxes) preloaded with options for fields that in your screenshot show a default value like <No xyz SELECTED>
. In this example, eight fields are implemented as pulldowns (Topic, Keywords, SWE, Section, Process Area, Action, Template, and Chat Name) while “Free Form Action” remains a free-text entry. You can update the option lists as needed.
import tkinter as tkfrom tkinter import ttk
from tkinter import scrolledtext
from tkinter import messagebox
import pyperclip # pip install pyperclip
import sqlite3 # or use your preferred DB library
# import openai # Uncomment and configure if using OpenAI
# ------------------------------------------------
# Placeholder function for querying the database
# ------------------------------------------------
def query_database(selected_tables, topic, keywords, swe, section,
process_area, action, free_form_action, template, chat_name):
"""
Replace this with your actual DB query logic.
For now, this returns a string summarizing the inputs.
"""
summary = (
f"Selected Tables: {', '.join(selected_tables)}\n"
f"Topic: {topic}\n"
f"Keywords: {keywords}\n"
f"SWE: {swe}\n"
f"Section: {section}\n"
f"Process Area: {process_area}\n"
f"Action: {action}\n"
f"Free Form Action: {free_form_action}\n"
f"Template: {template}\n"
f"Chat Name: {chat_name}\n"
)
return summary
# ------------------------------------------------
# Placeholder function for calling the LLM
# ------------------------------------------------
def call_llm(prompt):
"""
Replace this with actual LLM logic.
For demonstration, this function echoes the prompt.
"""
# Example using OpenAI (uncomment if needed):
#
# openai.api_key = "YOUR_API_KEY"
# response = openai.ChatCompletion.create(
# model="gpt-4",
# messages=[
# {"role": "system", "content": "You are NASA requirements assistant."},
# {"role": "user", "content": prompt}
# ]
# )
# return response["choices"][0]["message"]["content"]
return f"LLM Response:\n{prompt}"
# ------------------------------------------------
# Helper function to create a label and a combobox
# ------------------------------------------------
def create_label_combobox(parent, label_text, options):
label = ttk.Label(parent, text=label_text, width=18, anchor="w")
combobox_var = tk.StringVar()
combobox = ttk.Combobox(parent, textvariable=combobox_var, values=options, state="readonly", width=28)
combobox.current(0) # Set the first option as the default
return label, combobox, combobox_var
# ------------------------------------------------
# Helper function to create a label and a text entry (for free form input)
# ------------------------------------------------
def create_label_entry(parent, label_text):
label = ttk.Label(parent, text=label_text, width=18, anchor="w")
entry_var = tk.StringVar()
entry = ttk.Entry(parent, textvariable=entry_var, width=30)
return label, entry, entry_var
# ------------------------------------------------
# Main Application Class
# ------------------------------------------------
class NASARequirementsApp(tk.Tk):
def __init__(self):
super().__init__()
self.title("NASA Requirements and Standards")
# ---------------------------
# Frames for layout
# ---------------------------
self.left_frame = ttk.Frame(self, padding="5 5 5 5")
self.left_frame.grid(row=0, column=0, sticky="nsew")
self.right_frame = ttk.Frame(self, padding="5 5 5 5")
self.right_frame.grid(row=0, column=1, sticky="nsew")
# Configure grid weights for resizable layout
self.columnconfigure(0, weight=1)
self.columnconfigure(1, weight=3)
self.rowconfigure(0, weight=1)
# ---------------------------
# Left frame content (Tutorial / Examples)
# ---------------------------
tutorial_label = ttk.Label(self.left_frame, text="Tutorial")
tutorial_label.pack(anchor="w", pady=(0, 5))
example_queries_label = ttk.Label(
self.left_frame,
text="Example Queries\nQuery1\nQuery2\nQuery3\nQuery4"
)
example_queries_label.pack(anchor="w", pady=(0, 15))
example_actions_label = ttk.Label(
self.left_frame,
text="Example Actions\nAction1\nAction2\nAction3\nAction4"
)
example_actions_label.pack(anchor="w")
# ---------------------------
# Right frame: Top row - Table checkboxes
# ---------------------------
tables_frame = ttk.Frame(self.right_frame)
tables_frame.pack(fill="x", pady=(0, 10))
tables_label = ttk.Label(tables_frame, text="Tables")
tables_label.pack(anchor="w")
# Table checkboxes with BooleanVars
self.table_vars = {
"NPR 7150.2D": tk.BooleanVar(),
"NASA-STD-8739.8B": tk.BooleanVar(),
"SSP 50038 (CBCS)": tk.BooleanVar(),
"CMMI-DEV v1.3": tk.BooleanVar()
}
for table_name, var in self.table_vars.items():
chk = ttk.Checkbutton(tables_frame, text=table_name, variable=var)
chk.pack(anchor="w")
# ---------------------------
# Right frame: Middle row - User Inputs
# ---------------------------
inputs_frame = ttk.Frame(self.right_frame)
inputs_frame.pack(fill="x", pady=(0, 10))
# Create pulldown menus (comboboxes) for most inputs
row_index = 0
# Topic
topic_options = ["<No Topic SELECTED>", "Safety", "Performance", "Cost"]
self.topic_label, self.topic_combobox, self.topic_var = create_label_combobox(
inputs_frame, "Topic:", topic_options
)
self.topic_label.grid(row=row_index, column=0, padx=5, pady=2, sticky="e")
self.topic_combobox.grid(row=row_index, column=1, padx=5, pady=2, sticky="w")
row_index += 1
# Keywords
keywords_options = ["<No Keywords SELECTED>", "Quality", "Reliability", "Compliance"]
self.keywords_label, self.keywords_combobox, self.keywords_var = create_label_combobox(
inputs_frame, "Keywords:", keywords_options
)
self.keywords_label.grid(row=row_index, column=0, padx=5, pady=2, sticky="e")
self.keywords_combobox.grid(row=row_index, column=1, padx=5, pady=2, sticky="w")
row_index += 1
# SWE
swe_options = ["<No SWE SELECTED>", "Option SWE 1", "Option SWE 2"]
self.swe_label, self.swe_combobox, self.swe_var = create_label_combobox(
inputs_frame, "SWE:", swe_options
)
self.swe_label.grid(row=row_index, column=0, padx=5, pady=2, sticky="e")
self.swe_combobox.grid(row=row_index, column=1, padx=5, pady=2, sticky="w")
row_index += 1
# Section
section_options = ["<No Section SELECTED>", "Section 1", "Section 2", "Section 3"]
self.section_label, self.section_combobox, self.section_var = create_label_combobox(
inputs_frame, "Section:", section_options
)
self.section_label.grid(row=row_index, column=0, padx=5, pady=2, sticky="e")
self.section_combobox.grid(row=row_index, column=1, padx=5, pady=2, sticky="w")
row_index += 1
# Process Area
process_area_options = ["<No Process Area SELECTED>", "Area 1", "Area 2"]
self.process_area_label, self.process_area_combobox, self.process_area_var = create_label_combobox(
inputs_frame, "Process Area:", process_area_options
)
self.process_area_label.grid(row=row_index, column=0, padx=5, pady=2, sticky="e")
self.process_area_combobox.grid(row=row_index, column=1, padx=5, pady=2, sticky="w")
row_index += 1
# Action
action_options = ["<No Action SELECTED>", "Approve", "Review", "Reject"]
self.action_label, self.action_combobox, self.action_var = create_label_combobox(
inputs_frame, "Action:", action_options
)
self.action_label.grid(row=row_index, column=0, padx=5, pady=2, sticky="e")
self.action_combobox.grid(row=row_index, column=1, padx=5, pady=2, sticky="w")
row_index += 1
# Free Form Action (free text entry)
self.free_form_label, self.free_form_entry, self.free_form_var = create_label_entry(
inputs_frame, "Free Form Action:"
)
self.free_form_label.grid(row=row_index, column=0, padx=5, pady=2, sticky="e")
self.free_form_entry.grid(row=row_index, column=1, padx=5, pady=2, sticky="w")
row_index += 1
# Template
template_options = ["<No Template SELECTED>", "Template A", "Template B"]
self.template_label, self.template_combobox, self.template_var = create_label_combobox(
inputs_frame, "Template:", template_options
)
self.template_label.grid(row=row_index, column=0, padx=5, pady=2, sticky="e")
self.template_combobox.grid(row=row_index, column=1, padx=5, pady=2, sticky="w")
row_index += 1
# Chat Name
chat_name_options = ["<No Chat Name SELECTED>", "General", "Specific", "Custom"]
self.chat_name_label, self.chat_name_combobox, self.chat_name_var = create_label_combobox(
inputs_frame, "Chat Name:", chat_name_options
)
self.chat_name_label.grid(row=row_index, column=0, padx=5, pady=2, sticky="e")
self.chat_name_combobox.grid(row=row_index, column=1, padx=5, pady=2, sticky="w")
row_index += 1
# ---------------------------
# Right frame: Buttons
# ---------------------------
buttons_frame = ttk.Frame(self.right_frame)
buttons_frame.pack(fill="x", pady=(0, 10))
submit_button = ttk.Button(buttons_frame, text="SUBMIT", command=self.submit_query)
submit_button.pack(side="left", padx=5)
reset_button = ttk.Button(buttons_frame, text="RESET FORM", command=self.reset_form)
reset_button.pack(side="left", padx=5)
clear_button = ttk.Button(buttons_frame, text="CLEAR CHAT", command=self.clear_chat)
clear_button.pack(side="left", padx=5)
copy_button = ttk.Button(buttons_frame, text="COPY", command=self.copy_response)
copy_button.pack(side="left", padx=5)
# ---------------------------
# Right frame: Chat Response display
# ---------------------------
response_label = ttk.Label(self.right_frame, text="RESPONSE")
response_label.pack(anchor="w")
self.response_text = scrolledtext.ScrolledText(self.right_frame, wrap=tk.WORD, width=80, height=15)
self.response_text.pack(fill="both", expand=True)
def submit_query(self):
"""
Collects input values, queries the database, calls the LLM, and shows the response.
"""
# Get selected tables from checkboxes
selected_tables = [name for name, var in self.table_vars.items() if var.get()]
# Get values from pulldowns and entry field
topic = self.topic_var.get()
keywords = self.keywords_var.get()
swe = self.swe_var.get()
section = self.section_var.get()
process_area = self.process_area_var.get()
action = self.action_var.get()
free_form_action = self.free_form_var.get()
template = self.template_var.get()
chat_name = self.chat_name_var.get()
# Query the database (placeholder logic)
db_result = query_database(
selected_tables,
topic,
keywords,
swe,
section,
process_area,
action,
free_form_action,
template,
chat_name
)
# Build a prompt for the LLM
prompt = f"User wants information about:\n{db_result}\n"
# Call the LLM (placeholder function)
llm_response = call_llm(prompt)
# Display the LLM response
self.response_text.insert(tk.END, llm_response + "\n\n")
self.response_text.see(tk.END)
def reset_form(self):
"""
Resets all pulldown menus to their default values and clears the free text entry.
"""
# Uncheck table checkboxes
for var in self.table_vars.values():
var.set(False)
# Reset comboboxes by setting them back to the first option
self.topic_combobox.current(0)
self.keywords_combobox.current(0)
self.swe_combobox.current(0)
self.section_combobox.current(0)
self.process_area_combobox.current(0)
self.action_combobox.current(0)
self.template_combobox.current(0)
self.chat_name_combobox.current(0)
# Clear free form text entry
self.free_form_var.set("")
def clear_chat(self):
"""
Clears the response text area.
"""
self.response_text.delete("1.0", tk.END)
def copy_response(self):
"""
Copies the entire response text to the system clipboard.
"""
text_to_copy = self.response_text.get("1.0", tk.END)
pyperclip.copy(text_to_copy)
messagebox.showinfo("Copied", "Response text copied to clipboard!")
# ------------------------------------------------
# Main entry point
# ------------------------------------------------
if __name__ == "__main__":
app = NASARequirementsApp()
app.mainloop()
How This Updated Code Works
-
Pulldown Menus (Comboboxes):
-
For fields such as Topic, Keywords, SWE, Section, Process Area, Action, Template, and Chat Name, a helper function
create_label_combobox()
is used to create a label and a combobox preloaded with options (the first option being a default like<No xyz SELECTED>
).
-
-
Free Form Action:
-
This remains a regular text entry field created using
create_label_entry()
.
-
-
Functionality:
-
When you click SUBMIT, the code collects data from both the pulldowns and the free-text entry, builds a prompt, queries a (placeholder) database function, and sends the prompt to an LLM (also a placeholder).
-
RESET FORM returns all pulldowns to their default values and clears the free form field.
-
CLEAR CHAT erases the chat display.
-
COPY copies the chat content to the clipboard.
-
Feel free to adjust the option lists and layout details to match your application requirements.
From <https://chatgpt.com/> ChatGPT o3-mini-high
- Get link
- X
- Other Apps
Comments
Post a Comment