Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Store Conversation History #77

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
15 changes: 1 addition & 14 deletions frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ function App() {
let [messages, setMessages] = useState<Array<MessageDict>>(
Array.from([
{
text: "Hello! I'm a GPT Code assistant. Ask me to do something for you! Pro tip: you can upload a file and I'll be able to use it.",
text: "Hello! I am a GPT Code assistant. Ask me to do something for you! Pro tip: you can upload a file and I'll be able to use it.",
role: "generator",
type: "message",
},
Expand Down Expand Up @@ -161,19 +161,6 @@ function App() {
function completeUpload(message: string) {
addMessage({ text: message, type: "message", role: "upload" });
setWaitingForSystem(WaitingStates.Idle);

// Inform prompt server
fetch(`${Config.WEB_ADDRESS}/inject-context`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
prompt: message,
}),
})
.then(() => {})
.catch((error) => console.error("Error:", error));
}

function startUpload(_: string) {
Expand Down
22 changes: 20 additions & 2 deletions frontend/src/components/Chat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,15 +72,33 @@ function Message(props: {
<div className="cell-output" dangerouslySetInnerHTML={{ __html: text }}></div>
))}

{(props.type == "message_raw") &&
{props.type == "message_error" &&
(props.showLoader ? (
<div>
{text} {props.showLoader ? <div className="loader"></div> : null}
</div>
) : (
<div>
Execution Error:
<SyntaxHighlighter
{...props}
children={text}
wrapLongLines={true}
language={"python"}
PreTag="div"
/>
</div>
))}

{["message_raw", "message_status"].includes(props.type) &&
(props.showLoader ? (
<div>
{text} {props.showLoader ? <div className="loader"></div> : null}
</div>
) : (
<div className="cell-output" dangerouslySetInnerHTML={{ __html: text }}></div>
))}

{props.type == "image/png" &&
<div className="cell-output-image" dangerouslySetInnerHTML={{ __html: `<img src='data:image/png;base64,${text}' />` }}></div>
}
Expand Down
2 changes: 1 addition & 1 deletion gpt_code_ui/kernel_program/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ def get_logger():
logger = logging.getLogger(__name__)
if "DEBUG" in os.environ:
logger.setLevel(logging.DEBUG)
return logger
return logger
6 changes: 3 additions & 3 deletions gpt_code_ui/kernel_program/kernel_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def cleanup_spawned_processes():
os.kill(pid, signal.CTRL_BREAK_EVENT)
else:
os.kill(pid, signal.SIGKILL)

# After successful kill, cleanup pid file
os.remove(fp)

Expand Down Expand Up @@ -149,7 +149,7 @@ def flush_kernel_msgs(kc, tries=1, timeout=0.2):
elif msg["msg_type"] == "error":
send_message(
utils.escape_ansi("\n".join(msg["content"]["traceback"])),
"message_raw",
"message_error",
)
except queue.Empty:
hit_empty += 1
Expand Down Expand Up @@ -221,4 +221,4 @@ def start_kernel():

if __name__ == "__main__":
kc = start_kernel()
start_snakemq(kc)
start_snakemq(kc)
2 changes: 1 addition & 1 deletion gpt_code_ui/kernel_program/launch_kernel.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
if __name__ == "__main__":
from ipykernel import kernelapp as app

app.launch_new_instance()
app.launch_new_instance()
25 changes: 13 additions & 12 deletions gpt_code_ui/kernel_program/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import time

import asyncio
import json
import threading

from queue import Queue
Expand Down Expand Up @@ -47,6 +46,7 @@
app = Flask(__name__)
CORS(app)


def start_kernel_manager():
global kernel_manager_process

Expand All @@ -62,9 +62,11 @@ def start_kernel_manager():
with open(os.path.join(config.KERNEL_PID_DIR, "%d.pid" % kernel_manager_process.pid), "w") as p:
p.write("kernel_manager")


def cleanup_kernel_program():
kernel_manager.cleanup_spawned_processes()


async def start_snakemq():
global messaging

Expand All @@ -77,11 +79,11 @@ def on_recv(conn, ident, message):
if message["value"] == "ready":
logger.debug("Kernel is ready.")
result_queue.put({
"value":"Kernel is ready.",
"type": "message"
"value": "Kernel is ready.",
"type": "message_status"
})

elif message["type"] in ["message", "message_raw", "image/png", "image/jpeg"]:
elif message["type"] in ["message", "message_raw", "message_error", "image/png", "image/jpeg"]:
# TODO: 1:1 kernel <> channel mapping
logger.debug("%s of type %s" % (message["value"], message["type"]))

Expand All @@ -97,8 +99,9 @@ def send_queued_messages():
while True:
if send_queue.qsize() > 0:
message = send_queue.get()
utils.send_json(messaging,
{"type": "execute", "value": message["command"]},
utils.send_json(
messaging,
{"type": "execute", "value": message["command"]},
config.IDENT_KERNEL_MANAGER
)
time.sleep(0.1)
Expand All @@ -117,7 +120,7 @@ async def async_link_loop():

@app.route("/api", methods=["POST", "GET"])
def handle_request():

if request.method == "GET":
# Handle GET requests by sending everything that's in the receive_queue
results = [result_queue.get() for _ in range(result_queue.qsize())]
Expand All @@ -128,7 +131,8 @@ def handle_request():
send_queue.put(data)

return jsonify({"result": "success"})



@app.route("/restart", methods=["POST"])
def handle_restart():

Expand All @@ -152,9 +156,6 @@ async def main():
def run_flask_app():
app.run(host="0.0.0.0", port=APP_PORT)


if __name__ == "__main__":
asyncio.run(main())




4 changes: 3 additions & 1 deletion gpt_code_ui/kernel_program/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import gpt_code_ui.kernel_program.config as config


def escape_ansi(line):
ansi_escape = re.compile(r"(?:\x1B[@-_]|[\x80-\x9F])[0-?]*[ -/]*[@-~]")
return ansi_escape.sub("", line)
Expand All @@ -16,6 +17,7 @@ def send_json(messaging, message, identity):
message = snakemq.message.Message(json.dumps(message).encode("utf-8"), ttl=600)
messaging.send_message(identity, message)


def init_snakemq(ident, init_type="listen"):
link = snakemq.link.Link()
packeter = snakemq.packeter.Packeter(link)
Expand All @@ -26,4 +28,4 @@ def init_snakemq(ident, init_type="listen"):
link.add_connector(("localhost", config.SNAKEMQ_PORT))
else:
raise Exception("Unsupported init type.")
return messaging, link
return messaging, link
52 changes: 28 additions & 24 deletions gpt_code_ui/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,23 @@

APP_URL = "http://localhost:%s" % APP_PORT


def run_webapp():
try:
app.run(host="0.0.0.0", port=APP_PORT, use_reloader=False)
except Exception as e:
logging.exception("Error running the webapp:")
except Exception:
logging.exception("Error running the webapp")
sys.exit(1)


def run_kernel_program():
try:
asyncio.run(kernel_program_main())
except Exception as e:
logging.exception("Error running the kernel_program:")
except Exception:
logging.exception("Error running the kernel_program")
sys.exit(1)


def setup_logging():
log_format = "%(asctime)s [%(levelname)s]: %(message)s"
logging.basicConfig(level=logging.INFO, format=log_format)
Expand All @@ -38,32 +41,33 @@ def setup_logging():
file_handler.setFormatter(logging.Formatter(log_format))
logging.getLogger().addHandler(file_handler)


def print_color(text, color="gray"):
# Default to gray
code="242"
code = "242"

if color == "green":
code="35"
code = "35"

gray_code = "\033[38;5;%sm" % code
reset_code = "\033[0m"
print(f"{gray_code}{text}{reset_code}")


def print_banner():

print("""
print("""
█▀▀ █▀█ ▀█▀ ▄▄ █▀▀ █▀█ █▀▄ █▀▀
█▄█ █▀▀ ░█░ ░░ █▄▄ █▄█ █▄▀ ██▄
""")
""")

print("> Open GPT-Code UI in your browser %s" % APP_URL)
print("")
print("You can inspect detailed logs in app.log.")
print("")
print("Find your OpenAI API key at https://platform.openai.com/account/api-keys")
print("")
print_color("Contribute to GPT-Code UI at https://github.com/ricklamers/gpt-code-ui")

print("> Open GPT-Code UI in your browser %s" % APP_URL)
print("")
print("You can inspect detailed logs in app.log.")
print("")
print("Find your OpenAI API key at https://platform.openai.com/account/api-keys")
print("")
print_color("Contribute to GPT-Code UI at https://github.com/ricklamers/gpt-code-ui")

def main():
setup_logging()
Expand All @@ -80,20 +84,19 @@ def main():
try:
app.test_client().get("/")
break
except:
except Exception:
time.sleep(0.1)
print_banner()

print_banner()

webbrowser.open(APP_URL)

webapp_process.join()
kernel_program_process.join()


except KeyboardInterrupt:
print("Terminating processes...")

cleanup_kernel_program()
kernel_program_process.terminate()

Expand All @@ -103,6 +106,7 @@ def main():
kernel_program_process.join()

print("Processes terminated.")



if __name__ == '__main__':
main()
Loading