From 3471870ab341128f2b4d43b505dc4b6af458eda8 Mon Sep 17 00:00:00 2001 From: Amr Gharbeia Date: Fri, 17 Apr 2026 20:04:49 -0400 Subject: [PATCH] fix(tui): Synchronize TUI client with protocol framing and fix input handling --- literate/tui-client.org | 42 ++++++++++++++++++++--------------------- src/tui-client.lisp | 42 ++++++++++++++++++++--------------------- 2 files changed, 40 insertions(+), 44 deletions(-) diff --git a/literate/tui-client.org b/literate/tui-client.org index d7d6db3..860e364 100644 --- a/literate/tui-client.org +++ b/literate/tui-client.org @@ -50,26 +50,22 @@ The OpenCortex TUI Client is a standalone Common Lisp executable providing a ric (loop while *is-running* do (handler-case (when (and *stream* (open-stream-p *stream*)) - (let ((line (read-line *stream* nil :eof))) - (if (eq line :eof) - (setf *is-running* nil) - (let* ((*read-eval* nil) - (sexp (ignore-errors (read-from-string line)))) - (if (and sexp (listp sexp)) - (cond - ((eq (getf sexp :type) :status) - (setf *status-text* (format nil "[Scribe: ~a] [Gardener: ~a]" - (getf sexp :scribe) - (getf sexp :gardener)))) - ((eq (getf sexp :type) :chat) - (enqueue-msg (getf sexp :text))) - ((eq (getf sexp :type) :info) - (enqueue-msg (format nil "*System*: ~a" (getf sexp :text)))) - ((eq (getf sexp :type) :error) - (enqueue-msg (format nil "*Error*: ~a" (getf sexp :text)))) - (t (enqueue-msg line))) - (enqueue-msg line)))))) - (error () (setf *is-running* nil))) + (let ((msg (opencortex:read-framed-message *stream*))) + (cond ((eq msg :eof) (setf *is-running* nil)) + ((eq msg :error) (setf *status-text* "Protocol Error")) + ((and (listp msg) (eq (getf msg :type) :EVENT)) + ;; Handle Handshake or other events + (let ((payload (getf msg :payload))) + (when (eq (getf payload :action) :handshake) + (setf *status-text* "Ready")))) + ((and (listp msg) (eq (getf msg :type) :status)) + (setf *status-text* (format nil "[Scribe: ~a] [Gardener: ~a]" + (getf msg :scribe) + (getf msg :gardener)))) + ((and (listp msg) (eq (getf msg :type) :chat)) + (enqueue-msg (getf msg :text))) + (t (enqueue-msg (format nil "~s" msg)))))) + (error (c) (setf *status-text* (format nil "Net Error: ~a" c)) (setf *is-running* nil))) (sleep 0.05))) #+end_src @@ -117,8 +113,10 @@ The OpenCortex TUI Client is a standalone Common Lisp executable providing a ric ((eq ch #\Newline) (let ((cmd (coerce *input-buffer* 'string))) (setf (fill-pointer *input-buffer*) 0) - (format *stream* "~a~%" cmd) - (finish-output *stream*) + (when (> (length cmd) 0) + (let ((framed (opencortex:frame-message (format nil "~s" (list :type :EVENT :payload (list :sensor :chat-message :text cmd)))))) + (format *stream* "~a~%" framed) + (finish-output *stream*))) (when (string= cmd "/exit") (setf *is-running* nil)))) ((eq ch :backspace) (when (> (length *input-buffer*) 0) diff --git a/src/tui-client.lisp b/src/tui-client.lisp index 511068e..ce1de77 100644 --- a/src/tui-client.lisp +++ b/src/tui-client.lisp @@ -29,26 +29,22 @@ (loop while *is-running* do (handler-case (when (and *stream* (open-stream-p *stream*)) - (let ((line (read-line *stream* nil :eof))) - (if (eq line :eof) - (setf *is-running* nil) - (let* ((*read-eval* nil) - (sexp (ignore-errors (read-from-string line)))) - (if (and sexp (listp sexp)) - (cond - ((eq (getf sexp :type) :status) - (setf *status-text* (format nil "[Scribe: ~a] [Gardener: ~a]" - (getf sexp :scribe) - (getf sexp :gardener)))) - ((eq (getf sexp :type) :chat) - (enqueue-msg (getf sexp :text))) - ((eq (getf sexp :type) :info) - (enqueue-msg (format nil "*System*: ~a" (getf sexp :text)))) - ((eq (getf sexp :type) :error) - (enqueue-msg (format nil "*Error*: ~a" (getf sexp :text)))) - (t (enqueue-msg line))) - (enqueue-msg line)))))) - (error () (setf *is-running* nil))) + (let ((msg (opencortex:read-framed-message *stream*))) + (cond ((eq msg :eof) (setf *is-running* nil)) + ((eq msg :error) (setf *status-text* "Protocol Error")) + ((and (listp msg) (eq (getf msg :type) :EVENT)) + ;; Handle Handshake or other events + (let ((payload (getf msg :payload))) + (when (eq (getf payload :action) :handshake) + (setf *status-text* "Ready")))) + ((and (listp msg) (eq (getf msg :type) :status)) + (setf *status-text* (format nil "[Scribe: ~a] [Gardener: ~a]" + (getf msg :scribe) + (getf msg :gardener)))) + ((and (listp msg) (eq (getf msg :type) :chat)) + (enqueue-msg (getf msg :text))) + (t (enqueue-msg (format nil "~s" msg)))))) + (error (c) (setf *status-text* (format nil "Net Error: ~a" c)) (setf *is-running* nil))) (sleep 0.05))) (defun main () @@ -93,8 +89,10 @@ ((eq ch #\Newline) (let ((cmd (coerce *input-buffer* 'string))) (setf (fill-pointer *input-buffer*) 0) - (format *stream* "~a~%" cmd) - (finish-output *stream*) + (when (> (length cmd) 0) + (let ((framed (opencortex:frame-message (format nil "~s" (list :type :EVENT :payload (list :sensor :chat-message :text cmd)))))) + (format *stream* "~a~%" framed) + (finish-output *stream*))) (when (string= cmd "/exit") (setf *is-running* nil)))) ((eq ch :backspace) (when (> (length *input-buffer*) 0)