fix(perceive): complete reconstruction of perceive.org to resolve catastrophic syntax failures
This commit is contained in:
@@ -1,4 +1,3 @@
|
|||||||
#+PROPERTY: header-args:lisp :tangle perceive.lisp
|
|
||||||
#+TITLE: Stage 1: Perceive (perceive.lisp)
|
#+TITLE: Stage 1: Perceive (perceive.lisp)
|
||||||
#+AUTHOR: Agent
|
#+AUTHOR: Agent
|
||||||
#+FILETAGS: :harness:perceive:
|
#+FILETAGS: :harness:perceive:
|
||||||
@@ -18,57 +17,25 @@ The Perceive stage is the "sensory cortex" of OpenCortex. Its job is to take raw
|
|||||||
** Sensor Configuration
|
** Sensor Configuration
|
||||||
#+begin_src lisp
|
#+begin_src lisp
|
||||||
(defvar *async-sensors* '(:chat-message :delegation :user-command)
|
(defvar *async-sensors* '(:chat-message :delegation :user-command)
|
||||||
"Sensors that are processed in dedicated threads.
|
"Sensors that are processed in dedicated threads.")
|
||||||
|
|
||||||
These sensors can block (waiting for API responses, user input, etc.)
|
|
||||||
so they run in separate threads to avoid blocking the main pipeline.
|
|
||||||
|
|
||||||
Other sensors (:heartbeat, :interrupt, :buffer-update) are processed
|
|
||||||
synchronously to maintain temporal ordering.")
|
|
||||||
|
|
||||||
(defvar *foveal-focus-id* nil
|
(defvar *foveal-focus-id* nil
|
||||||
"The Org ID of the node the user is currently interacting with.
|
"The Org ID of the node the user is currently interacting with.")
|
||||||
|
|
||||||
This enables the reasoning engine to provide contextually relevant
|
|
||||||
responses. When editing a specific note, the agent knows which
|
|
||||||
note you're referring to without needing explicit ID references.
|
|
||||||
|
|
||||||
Updated on :point-update events from Emacs.")
|
|
||||||
|
|
||||||
This enables the reasoning engine to provide contextually relevant
|
|
||||||
responses. When editing a specific note, the agent knows which
|
|
||||||
note you're referring to without needing explicit ID references.
|
|
||||||
|
|
||||||
Updated on :point-update events from Emacs.
|
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
** Stimulus Injection (inject-stimulus)
|
** Stimulus Injection (inject-stimulus)
|
||||||
#+begin_src lisp
|
#+begin_src lisp
|
||||||
(defun inject-stimulus (raw-message &key stream (depth 0))
|
(defun inject-stimulus (raw-message &key stream (depth 0))
|
||||||
"Inject a raw message into the signal processing pipeline.
|
"Inject a raw message into the signal processing pipeline."
|
||||||
|
|
||||||
RAW-MESSAGE is a property list that will be normalized into a Signal.
|
|
||||||
STREAM is an optional output stream for responses (used by TUI/CLI).
|
|
||||||
DEPTH tracks recursion depth for feedback loops.
|
|
||||||
|
|
||||||
This function determines whether to process synchronously or
|
|
||||||
asynchronously based on the sensor type, then calls process-signal
|
|
||||||
to run through the Perceive -> Reason -> Act pipeline.
|
|
||||||
|
|
||||||
Error handling: Uses restarts to prevent individual signals from
|
|
||||||
crashing the entire system. Failed signals are logged and dropped."
|
|
||||||
|
|
||||||
(let* ((payload (getf raw-message :payload))
|
(let* ((payload (getf raw-message :payload))
|
||||||
(sensor (getf payload :sensor))
|
(sensor (getf payload :sensor))
|
||||||
(meta (getf raw-message :meta))
|
(meta (getf raw-message :meta))
|
||||||
(async-p (or (getf payload :async-p)
|
(async-p (or (getf payload :async-p)
|
||||||
(member sensor *async-sensors*))))
|
(member sensor *async-sensors*))))
|
||||||
|
|
||||||
;; Ensure metadata exists
|
|
||||||
(unless meta
|
(unless meta
|
||||||
(setf meta (list :SOURCE :SYSTEM :SESSION-ID "internal")))
|
(setf meta (list :SOURCE :SYSTEM :SESSION-ID "internal")))
|
||||||
|
|
||||||
;; Attach reply stream if provided
|
|
||||||
(when stream
|
(when stream
|
||||||
(setf (getf meta :reply-stream) stream))
|
(setf (getf meta :reply-stream) stream))
|
||||||
|
|
||||||
@@ -76,77 +43,51 @@ The Perceive stage is the "sensory cortex" of OpenCortex. Its job is to take raw
|
|||||||
(setf (getf raw-message :depth) depth)
|
(setf (getf raw-message :depth) depth)
|
||||||
|
|
||||||
(if async-p
|
(if async-p
|
||||||
;; Async: process in dedicated thread
|
|
||||||
(bt:make-thread
|
(bt:make-thread
|
||||||
(lambda ()
|
(lambda ()
|
||||||
(restart-case (process-signal raw-message)
|
(restart-case (process-signal raw-message)
|
||||||
(skip-event () nil)))
|
(skip-event () nil)))
|
||||||
:name "opencortex-async-task
|
:name "opencortex-async-task")
|
||||||
|
|
||||||
;; Sync: process in main thread with recovery
|
|
||||||
(restart-case
|
(restart-case
|
||||||
(handler-bind ((error (lambda (c)
|
(handler-bind ((error (lambda (c)
|
||||||
(harness-log "SYSTEM ERROR: ~a" c)
|
(harness-log "SYSTEM ERROR: ~a" c)
|
||||||
(invoke-restart 'skip-event))))
|
(invoke-restart 'skip-event))))
|
||||||
(process-signal raw-message))
|
(process-signal raw-message))
|
||||||
(skip-event ()
|
(skip-event ()
|
||||||
(harness-log "SYSTEM RECOVERY: Stimulus dropped.)))))
|
(harness-log "SYSTEM RECOVERY: Stimulus dropped."))))))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
** Perceive Gate (perceive-gate)
|
** Perceive Gate (perceive-gate)
|
||||||
#+begin_src lisp
|
#+begin_src lisp
|
||||||
(defun perceive-gate (signal)
|
(defun perceive-gate (signal)
|
||||||
"Stage 1 of the metabolic pipeline: Normalize sensory input.
|
"Stage 1 of the metabolic pipeline: Normalize sensory input."
|
||||||
|
|
||||||
This function:
|
|
||||||
1. Logs the incoming signal for debugging
|
|
||||||
2. Handles special sensor types (:buffer-update, :point-update, etc.)
|
|
||||||
3. Updates the Memory graph with incoming data
|
|
||||||
4. Tracks foveal focus (user's current node)
|
|
||||||
5. Sets :status to :perceived
|
|
||||||
|
|
||||||
Modifies the signal in place and returns it for the next stage."
|
|
||||||
|
|
||||||
(let* ((payload (getf signal :payload))
|
(let* ((payload (getf signal :payload))
|
||||||
(type (getf signal :type))
|
(type (getf signal :type))
|
||||||
(meta (getf signal :meta))
|
(meta (getf signal :meta))
|
||||||
(sensor (getf payload :sensor)))
|
(sensor (getf payload :sensor)))
|
||||||
|
|
||||||
;; Log the incoming signal for debugging
|
|
||||||
(harness-log "GATE [Perceive]: ~a (~a) [Source: ~s]"
|
(harness-log "GATE [Perceive]: ~a (~a) [Source: ~s]"
|
||||||
type (or sensor "no-sensor (getf meta :source))
|
type (or sensor "no-sensor") (getf meta :source))
|
||||||
|
|
||||||
;; Handle EVENT type sensors
|
|
||||||
(cond ((eq type :EVENT)
|
(cond ((eq type :EVENT)
|
||||||
(case sensor
|
(case sensor
|
||||||
|
|
||||||
;; Org buffer was modified - update memory
|
|
||||||
(:buffer-update
|
(:buffer-update
|
||||||
(let ((ast (getf payload :ast)))
|
(let ((ast (getf payload :ast)))
|
||||||
(when ast
|
(when ast
|
||||||
(snapshot-memory)
|
(snapshot-memory)
|
||||||
(ingest-ast ast))))
|
(ingest-ast ast))))
|
||||||
|
|
||||||
;; Point moved to different org node - update focus
|
|
||||||
(:point-update
|
(:point-update
|
||||||
(let ((element (getf payload :element)))
|
(let ((element (getf payload :element)))
|
||||||
(when element
|
(when element
|
||||||
(snapshot-memory)
|
(snapshot-memory)
|
||||||
;; Track foveal focus for contextual reasoning
|
(setf *foveal-focus-id* (getf element :id))
|
||||||
(setf *foveal-focus-id*
|
|
||||||
(ignore-errors (getf element :id)))
|
|
||||||
(ingest-ast element))))
|
(ingest-ast element))))
|
||||||
|
|
||||||
;; System interrupt - trigger shutdown
|
|
||||||
(:interrupt
|
(:interrupt
|
||||||
(setf *interrupt-flag* t))))
|
(setf *interrupt-flag* t))))
|
||||||
|
|
||||||
;; Log responses from actuators
|
|
||||||
((eq type :RESPONSE)
|
((eq type :RESPONSE)
|
||||||
(harness-log "GATE [Perceive]: Act Result -> ~a"
|
(harness-log "GATE [Perceive]: Act Result -> ~a" (getf payload :status))))
|
||||||
(getf payload :status))))
|
|
||||||
|
|
||||||
;; Update signal status
|
|
||||||
(setf (getf signal :status) :perceived)
|
(setf (getf signal :status) :perceived)
|
||||||
(setf (getf signal :foveal-focus) *foveal-focus-id*)
|
(setf (getf signal :foveal-focus) *foveal-focus-id*)
|
||||||
signal))
|
signal))
|
||||||
@@ -154,26 +95,27 @@ The Perceive stage is the "sensory cortex" of OpenCortex. Its job is to take raw
|
|||||||
|
|
||||||
* Test Suite
|
* Test Suite
|
||||||
|
|
||||||
#+begin_src lisp :tangle perceive.lisp
|
#+begin_src lisp :tangle tests/pipeline-perceive-tests.lisp
|
||||||
|
(eval-when (:compile-toplevel :load-toplevel :execute)
|
||||||
|
(ql:quickload :fiveam :silent t))
|
||||||
|
|
||||||
(defpackage :opencortex-pipeline-perceive-tests
|
(defpackage :opencortex-pipeline-perceive-tests
|
||||||
(:use :cl :fiveam :opencortex)
|
(:use :cl :fiveam :opencortex)
|
||||||
(:export #:pipeline-perceive-suite))
|
(:export #:pipeline-perceive-suite))
|
||||||
|
|
||||||
(in-package :opencortex-pipeline-perceive-tests)
|
(in-package :opencortex-pipeline-perceive-tests)
|
||||||
|
|
||||||
(def-suite pipeline-perceive-suite :description "Test suite for Perceive pipeline
|
(def-suite pipeline-perceive-suite :description "Test suite for Perceive pipeline")
|
||||||
(in-suite pipeline-perceive-suite)
|
(in-suite pipeline-perceive-suite)
|
||||||
|
|
||||||
(test test-perceive-gate
|
(test test-perceive-gate
|
||||||
"Perceive gate should update the object store and normalize signal."
|
|
||||||
(clrhash opencortex::*memory*)
|
(clrhash opencortex::*memory*)
|
||||||
(let* ((signal (list :type :EVENT :payload (list :sensor :buffer-update :ast (list :type :HEADLINE :properties (list :ID "test-node" :TITLE "Test :contents nil))))
|
(let* ((signal (list :type :EVENT :payload (list :sensor :buffer-update :ast (list :type :HEADLINE :properties (list :ID "test-node" :TITLE "Test") :contents nil))))
|
||||||
(result (perceive-gate signal)))
|
(result (perceive-gate signal)))
|
||||||
(is (eq :perceived (getf result :status)))
|
(is (eq :perceived (getf result :status)))
|
||||||
(is (not (null (gethash "test-node" opencortex::*memory*))))))
|
(is (not (null (gethash "test-node" opencortex::*memory*))))))
|
||||||
|
|
||||||
(test test-depth-limiting
|
(test test-depth-limiting
|
||||||
"Verify that the pipeline terminates runaway feedback loops."
|
|
||||||
(let ((runaway-signal (list :type :EVENT :depth 11 :payload (list :sensor :heartbeat))))
|
(let ((runaway-signal (list :type :EVENT :depth 11 :payload (list :sensor :heartbeat))))
|
||||||
(is (null (process-signal runaway-signal)))))
|
(is (null (process-signal runaway-signal)))))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|||||||
Reference in New Issue
Block a user