FEAT: Implement Signal Gateway and update Chat Agent

This commit is contained in:
2026-04-11 15:51:10 -04:00
parent 975a11da79
commit 212dcd8734
7 changed files with 325 additions and 1 deletions

View File

@@ -15,6 +15,8 @@
(member action '(:insert-at-end :INSERT-AT-END)))
(and (member target '(:telegram :TELEGRAM))
(or (getf payload :chat-id) (getf proposed-action :chat-id)))
(and (member target '(:signal :SIGNAL))
(or (getf payload :chat-id) (getf proposed-action :chat-id)))
(and (member target '(:shell :SHELL))
(or (getf payload :cmd) (getf proposed-action :cmd)))
(member target '(:tool :TOOL))))
@@ -38,6 +40,7 @@
(reply-instruction
(case channel
(:telegram (format nil "- To reply via Telegram: (:type :REQUEST :target :telegram :chat-id \"~a\" :text \"<Response>\")" chat-id))
(:signal (format nil "- To reply via Signal: (:type :REQUEST :target :signal :chat-id \"~a\" :text \"<Response>\")" chat-id))
(t "- To reply via Emacs: (:type :REQUEST :target :emacs :action :insert-at-end :buffer \"*org-agent-chat*\" :text \"* <Response>\")"))))
(ask-neuro trimmed-text :system-prompt (concatenate 'string
"ACTUATOR IDENTITY: You are the pure Lisp actuator for the org-agent kernel.

68
src/gateway-signal.lisp Normal file
View File

@@ -0,0 +1,68 @@
(in-package :org-agent)
(defvar *signal-account* "+13322690326")
(defvar *signal-polling-thread* nil)
(defun execute-signal-action (action context)
"Sends a message via signal-cli."
(declare (ignore context))
(let* ((payload (getf action :payload))
(chat-id (or (getf payload :chat-id) (getf action :chat-id)))
(text (or (getf payload :text) (getf action :text))))
(when (and chat-id text)
(kernel-log "SIGNAL: Sending message to ~a..." chat-id)
(handler-case
(uiop:run-program (list "signal-cli" "-u" *signal-account* "send" "-m" text chat-id)
:output :string :error-output :string)
(error (c) (kernel-log "SIGNAL ERROR: ~a" c))))))
(defun signal-process-updates ()
"Polls for new messages via signal-cli and injects them into the kernel."
(handler-case
(let* ((output (uiop:run-program (list "signal-cli" "-u" *signal-account* "receive" "--json")
:output :string :error-output :string :ignore-error-status t))
(lines (cl-ppcre:split "\\n" output)))
(dolist (line lines)
(when (and line (> (length line) 0))
(let* ((json (ignore-errors (cl-json:decode-json-from-string line)))
(envelope (cdr (assoc :envelope json)))
(source (cdr (assoc :source envelope)))
(data-message (cdr (assoc :data-message envelope)))
(text (cdr (assoc :message data-message))))
(when (and source text)
(kernel-log "SIGNAL: Received message from ~a" source)
(inject-stimulus
(list :type :EVENT
:payload (list :sensor :chat-message
:channel :signal
:chat-id source
:text text))))))))
(error (c) (kernel-log "SIGNAL POLL ERROR: ~a" c))))
(defun start-signal-gateway ()
"Initializes the Signal background thread."
(unless (and *signal-polling-thread* (bt:thread-alive-p *signal-polling-thread*))
(setf *signal-polling-thread*
(bt:make-thread
(lambda ()
(loop
(signal-process-updates)
(sleep 5)))
:name "org-agent-signal-gateway"))
(kernel-log "SIGNAL: Gateway polling active.")))
(defun stop-signal-gateway ()
(when (and *signal-polling-thread* (bt:thread-alive-p *signal-polling-thread*))
(bt:destroy-thread *signal-polling-thread*)
(setf *signal-polling-thread* nil)))
(register-actuator :signal #'execute-signal-action)
(defskill :skill-gateway-signal
:priority 150
:trigger (lambda (ctx) (declare (ignore ctx)) nil) ;; Passive
:neuro nil
:symbolic (lambda (action ctx) (declare (ignore ctx)) action))
(start-signal-gateway)