Files
passepartout/literate/loop.org

64 lines
2.7 KiB
Org Mode

#+TITLE: The Metabolic Loop (loop.lisp)
#+AUTHOR: Amr
#+FILETAGS: :harness:loop:
#+STARTUP: content
* The Metabolic Loop (loop.lisp)
** Architectural Intent: The Heartbeat
The Metabolic Loop is the high-level coordinator of the Org-Agent. It orchestrates the flow of energy (information) through the system by calling the three metabolic stages in sequence:
1. **Perceive:** Sensory intake.
2. **Reason:** Cognitive processing.
3. **Act:** Physical side-effects.
#+begin_src lisp :tangle ../src/loop.lisp
(in-package :org-agent)
(defvar *interrupt-flag* nil)
(defvar *interrupt-lock* (bt:make-lock "harness-interrupt-lock"))
(defun process-signal (signal)
"The entry point to the Metabolic Pipeline: Perceive -> Reason -> Act."
(let ((current-signal signal))
(loop while current-signal do
(let ((depth (getf current-signal :depth 0)))
(when (> depth 10) (harness-log "METABOLISM ERROR: Max depth reached.") (return nil))
(when (bt:with-lock-held (*interrupt-lock*) *interrupt-flag*)
(harness-log "METABOLISM: Interrupted.")
(bt:with-lock-held (*interrupt-lock*) (setf *interrupt-flag* nil))
(return nil))
(handler-case
(progn
(setf current-signal (perceive-gate current-signal))
(setf current-signal (reason-gate current-signal))
(setf current-signal (act-gate current-signal)))
(error (c)
(harness-log "METABOLISM CRASH: ~a - Initiating Micro-Rollback." c)
(rollback-object-store 0)
(let ((sensor (ignore-errors (getf (getf current-signal :payload) :sensor))))
(if (or (> depth 2) (member sensor '(:loop-error :tool-error)))
(setf current-signal nil)
(setf current-signal (list :type :EVENT :depth (1+ depth) :reply-stream (getf current-signal :reply-stream)
:payload (list :sensor :loop-error :message (format nil "~a" c) :depth depth)))))))))))
(defvar *default-heartbeat-interval* 60)
(defvar *heartbeat-thread* nil)
(defun start-heartbeat (&optional (interval *default-heartbeat-interval*))
(setf *heartbeat-thread*
(bt:make-thread
(lambda ()
(loop
(sleep interval)
(inject-stimulus (list :type :EVENT :payload (list :sensor :heartbeat :unix-time (get-universal-time))))))
:name "org-agent-heartbeat")))
(defun main ()
"Entry point for the Skeleton MVP."
(let* ((home (uiop:getenv "HOME"))
(env-file (uiop:merge-pathnames* ".local/share/org-agent/.env" (uiop:ensure-directory-pathname home))))
(when (uiop:file-exists-p env-file) (cl-dotenv:load-env env-file)))
(initialize-all-skills)
(start-heartbeat)
(loop (sleep 3600)))
#+end_src