From 0debfe5a954daae84fceaceb096c12d121712967 Mon Sep 17 00:00:00 2001 From: Amr Gharbeia Date: Fri, 17 Apr 2026 13:36:54 -0400 Subject: [PATCH] refactor: Switch TUI/daemon communication from JSON to Lisp S-Expressions --- literate/tui-client.org | 19 ++++++++++++------- opencortex.asd | 2 +- skills/org-skill-cli-gateway.org | 10 +++++----- src/tui-client.lisp | 19 ++++++++++++------- 4 files changed, 30 insertions(+), 20 deletions(-) diff --git a/literate/tui-client.org b/literate/tui-client.org index 97e4a3e..fe1a3c1 100644 --- a/literate/tui-client.org +++ b/literate/tui-client.org @@ -53,15 +53,20 @@ The OpenCortex TUI Client is a standalone Common Lisp executable providing a ric (let ((line (read-line *stream* nil :eof))) (if (eq line :eof) (setf *is-running* nil) - (let ((json (ignore-errors (cl-json:decode-json-from-string line)))) - (if json + (let* ((*read-eval* nil) + (sexp (ignore-errors (read-from-string line)))) + (if (and sexp (listp sexp)) (cond - ((string= (cdr (assoc :type json)) "status") + ((eq (getf sexp :type) :status) (setf *status-text* (format nil "[Scribe: ~a] [Gardener: ~a]" - (cdr (assoc :scribe json)) - (cdr (assoc :gardener json))))) - ((string= (cdr (assoc :type json)) "chat") - (enqueue-msg (cdr (assoc :text json)))) + (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))) diff --git a/opencortex.asd b/opencortex.asd index d7caf23..da8a50c 100644 --- a/opencortex.asd +++ b/opencortex.asd @@ -39,7 +39,7 @@ (uiop:symbol-call :fiveam :run! (uiop:find-symbol* :immune-suite :opencortex-immune-system-tests)))) (defsystem :opencortex/tui - :depends-on (:opencortex :croatoan :usocket :bordeaux-threads :cl-json) + :depends-on (:opencortex :croatoan :usocket :bordeaux-threads) :components ((:file "src/tui-client")) :build-operation "program-op" :build-pathname "opencortex-tui" diff --git a/skills/org-skill-cli-gateway.org b/skills/org-skill-cli-gateway.org index 3ade57a..09acb6a 100644 --- a/skills/org-skill-cli-gateway.org +++ b/skills/org-skill-cli-gateway.org @@ -61,7 +61,7 @@ The CLI actuator writes the agent's response back to the client's network stream (handler-case (if (and stream (open-stream-p stream)) (progn - (format stream "{\"type\": \"chat\", \"text\": \"~a\"}" text) + (prin1 (list :type :chat :text text) stream) (terpri stream) (finish-output stream)) (harness-log "CLI ERROR: No active or open reply stream for signal.")) @@ -73,17 +73,17 @@ Handles an individual TCP connection. It reads lines until the connection is clo #+begin_src lisp (defun handle-cli-slash-command (cmd stream) - "Handles TUI slash commands by returning structured JSON." + "Handles TUI slash commands by returning structured Lisp s-expressions." (cond ((string= cmd "/status") - (format stream "{\"type\": \"status\", \"scribe\": \"idle\", \"gardener\": \"sleeping\"}") + (prin1 '(:type :status :scribe :idle :gardener :sleeping) stream) (terpri stream) (finish-output stream)) ((string= cmd "/exit") - (format stream "{\"type\": \"info\", \"text\": \"Goodbye!\"}") + (prin1 '(:type :info :text "Goodbye!") stream) (terpri stream) (finish-output stream)) - (t (format stream "{\"type\": \"error\", \"text\": \"Unknown command: ~a\"}" cmd) + (t (prin1 (list :type :error :text (format nil "Unknown command: ~a" cmd)) stream) (terpri stream) (finish-output stream)))) diff --git a/src/tui-client.lisp b/src/tui-client.lisp index 67b829d..5c4d45c 100644 --- a/src/tui-client.lisp +++ b/src/tui-client.lisp @@ -32,15 +32,20 @@ (let ((line (read-line *stream* nil :eof))) (if (eq line :eof) (setf *is-running* nil) - (let ((json (ignore-errors (cl-json:decode-json-from-string line)))) - (if json + (let* ((*read-eval* nil) + (sexp (ignore-errors (read-from-string line)))) + (if (and sexp (listp sexp)) (cond - ((string= (cdr (assoc :type json)) "status") + ((eq (getf sexp :type) :status) (setf *status-text* (format nil "[Scribe: ~a] [Gardener: ~a]" - (cdr (assoc :scribe json)) - (cdr (assoc :gardener json))))) - ((string= (cdr (assoc :type json)) "chat") - (enqueue-msg (cdr (assoc :text json)))) + (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)))