REFAC: Refactored perceive stage and relocated telemetry
This commit is contained in:
@@ -64,6 +64,7 @@ flowchart TD
|
|||||||
#:context-get-system-logs
|
#:context-get-system-logs
|
||||||
#:context-resolve-path
|
#:context-resolve-path
|
||||||
#:context-get-skill-telemetry
|
#:context-get-skill-telemetry
|
||||||
|
#:harness-track-telemetry
|
||||||
#:context-assemble-global-awareness
|
#:context-assemble-global-awareness
|
||||||
|
|
||||||
;; --- Reactive Signal Pipeline ---
|
;; --- Reactive Signal Pipeline ---
|
||||||
@@ -149,6 +150,21 @@ The harness maintains a thread-safe circular log buffer to provide context for d
|
|||||||
(defvar *telemetry-lock* (bt:make-lock "harness-telemetry-lock"))
|
(defvar *telemetry-lock* (bt:make-lock "harness-telemetry-lock"))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
|
** Telemetry Implementation
|
||||||
|
The system tracks the performance and reliability of individual skills. This logic is currently preserved in the package layer for future expansion into a dedicated telemetry skill.
|
||||||
|
|
||||||
|
#+begin_src lisp :tangle ../src/package.lisp
|
||||||
|
(defun harness-track-telemetry (skill-name duration status)
|
||||||
|
"Updates performance metrics for a specific skill. Status should be :success or :rejected."
|
||||||
|
(when skill-name
|
||||||
|
(bt:with-lock-held (*telemetry-lock*)
|
||||||
|
(let ((entry (or (gethash skill-name *skill-telemetry*) (list :executions 0 :total-time 0 :failures 0))))
|
||||||
|
(incf (getf entry :executions))
|
||||||
|
(incf (getf entry :total-time) duration)
|
||||||
|
(when (eq status :rejected) (incf (getf entry :failures)))
|
||||||
|
(setf (gethash skill-name *skill-telemetry*) entry)))))
|
||||||
|
#+end_src
|
||||||
|
|
||||||
** Cognitive Tool Registry
|
** Cognitive Tool Registry
|
||||||
The Tool Registry allows the agent to interact with the physical world. Every tool must define a guard (for security) and a body (for execution).
|
The Tool Registry allows the agent to interact with the physical world. Every tool must define a guard (for security) and a body (for execution).
|
||||||
|
|
||||||
|
|||||||
@@ -5,43 +5,78 @@
|
|||||||
|
|
||||||
* Stage 1: Perceive (perceive.lisp)
|
* Stage 1: Perceive (perceive.lisp)
|
||||||
** Architectural Intent: Sensory Ingestion
|
** Architectural Intent: Sensory Ingestion
|
||||||
The Perceive stage is responsible for data normalization and sensory intake. It takes raw stimuli (from TCP sockets, Signal, or Heartbeats) and updates the global Memory graph.
|
The Perceive stage is the "sensory cortex" of the Org-Agent. It takes raw stimuli from the outside world (keyboard events, chat messages, heartbeats, or system interrupts) and normalizes them into internal **Signals**.
|
||||||
|
|
||||||
|
** Async Sensor Routing
|
||||||
|
To prevent blocking the main pipeline, certain sensors (like user commands or chat messages) are processed asynchronously in their own threads.
|
||||||
|
|
||||||
#+begin_src lisp :tangle ../src/perceive.lisp
|
#+begin_src lisp :tangle ../src/perceive.lisp
|
||||||
(in-package :org-agent)
|
(in-package :org-agent)
|
||||||
|
|
||||||
(defun harness-track-telemetry (skill-name duration status)
|
(defvar *async-sensors* '(:chat-message :delegation :user-command)
|
||||||
"Updates performance metrics for a specific skill."
|
"List of sensors that should be processed asynchronously to avoid blocking gateways.")
|
||||||
(when skill-name (bt:with-lock-held (*telemetry-lock*)
|
#+end_src
|
||||||
(let ((entry (or (gethash skill-name *skill-telemetry*) (list :executions 0 :total-time 0 :failures 0))))
|
|
||||||
(incf (getf entry :executions)) (incf (getf entry :total-time) duration)
|
|
||||||
(when (eq status :rejected) (incf (getf entry :failures))) (setf (gethash skill-name *skill-telemetry*) entry)))))
|
|
||||||
|
|
||||||
|
** Foveal Focus State
|
||||||
|
The system tracks the user's current point of interaction to provide context to the reasoning engine.
|
||||||
|
|
||||||
|
#+begin_src lisp :tangle ../src/perceive.lisp
|
||||||
|
(defvar *foveal-focus-id* nil
|
||||||
|
"The Org ID of the node the user is currently interacting with.")
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
** Stimulus Injection
|
||||||
|
The entry point for raw messages. It determines if the signal should be processed synchronously or asynchronously.
|
||||||
|
|
||||||
|
#+begin_src lisp :tangle ../src/perceive.lisp
|
||||||
(defun inject-stimulus (raw-message &key stream (depth 0))
|
(defun inject-stimulus (raw-message &key stream (depth 0))
|
||||||
"Enqueues a raw message into the reactive signal pipeline."
|
"Enqueues a raw message into the reactive signal pipeline."
|
||||||
(let* ((payload (getf raw-message :payload))
|
(let* ((payload (getf raw-message :payload))
|
||||||
(sensor (getf payload :sensor))
|
(sensor (getf payload :sensor))
|
||||||
(async-p (or (getf payload :async-p) (member sensor '(:chat-message :delegation :user-command)))))
|
(async-p (or (getf payload :async-p) (member sensor *async-sensors*))))
|
||||||
(when stream (setf (getf raw-message :reply-stream) stream))
|
(when stream (setf (getf raw-message :reply-stream) stream))
|
||||||
(if async-p (bt:make-thread (lambda () (restart-case (handler-bind ((error (lambda (c) (harness-log "ASYNC ERROR: ~a" c) (invoke-restart 'skip-event))))
|
(if async-p
|
||||||
(process-signal raw-message)) (skip-event () nil))) :name "org-agent-async-task")
|
(bt:make-thread
|
||||||
(restart-case (handler-bind ((error (lambda (c) (harness-log "SYSTEM ERROR: ~a" c) (invoke-restart 'skip-event)))) (process-signal raw-message))
|
(lambda ()
|
||||||
|
(restart-case (handler-bind ((error (lambda (c) (harness-log "ASYNC ERROR: ~a" c) (invoke-restart 'skip-event))))
|
||||||
|
(process-signal raw-message))
|
||||||
|
(skip-event () nil)))
|
||||||
|
:name "org-agent-async-task")
|
||||||
|
(restart-case (handler-bind ((error (lambda (c) (harness-log "SYSTEM ERROR: ~a" c) (invoke-restart 'skip-event))))
|
||||||
|
(process-signal raw-message))
|
||||||
(skip-event () (harness-log "SYSTEM RECOVERY: Stimulus dropped.~%"))))))
|
(skip-event () (harness-log "SYSTEM RECOVERY: Stimulus dropped.~%"))))))
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
** The Perceive Gate
|
||||||
|
The initial stage of the metabolic loop. It logs the signal, performs selective memory snapshots, and updates the Memory graph based on incoming AST updates.
|
||||||
|
|
||||||
|
#+begin_src lisp :tangle ../src/perceive.lisp
|
||||||
(defun perceive-gate (signal)
|
(defun perceive-gate (signal)
|
||||||
"Initial processing: Normalizes raw stimuli and updates memory."
|
"Initial processing: Normalizes raw stimuli and updates memory."
|
||||||
(let* ((payload (getf signal :payload))
|
(let* ((payload (getf signal :payload))
|
||||||
(type (getf signal :type))
|
(type (getf signal :type))
|
||||||
(sensor (getf payload :sensor)))
|
(sensor (getf payload :sensor)))
|
||||||
(harness-log "GATE [Perceive]: ~a (~a)" type (or sensor "no-sensor"))
|
(harness-log "GATE [Perceive]: ~a (~a)" type (or sensor "no-sensor"))
|
||||||
(snapshot-memory)
|
|
||||||
(cond ((eq type :EVENT)
|
(cond ((eq type :EVENT)
|
||||||
(case sensor
|
(case sensor
|
||||||
(:buffer-update (let ((ast (getf payload :ast))) (when ast (ingest-ast ast))))
|
(:buffer-update
|
||||||
(:point-update (let ((element (getf payload :element))) (when element (ingest-ast element))))
|
(let ((ast (getf payload :ast)))
|
||||||
(:interrupt (bt:with-lock-held (*interrupt-lock*) (setf *interrupt-flag* t)))))
|
(when ast
|
||||||
|
(snapshot-memory)
|
||||||
|
(ingest-ast ast))))
|
||||||
|
(:point-update
|
||||||
|
(let ((element (getf payload :element)))
|
||||||
|
(when element
|
||||||
|
(snapshot-memory)
|
||||||
|
(setf *foveal-focus-id* (ignore-errors (getf element :id)))
|
||||||
|
(ingest-ast element))))
|
||||||
|
(:interrupt
|
||||||
|
(bt:with-lock-held (*interrupt-lock*) (setf *interrupt-flag* t)))))
|
||||||
((eq type :RESPONSE)
|
((eq type :RESPONSE)
|
||||||
(harness-log "GATE [Perceive]: Act Result -> ~a" (getf payload :status))))
|
(harness-log "GATE [Perceive]: Act Result -> ~a" (getf payload :status))))
|
||||||
|
|
||||||
(setf (getf signal :status) :perceived)
|
(setf (getf signal :status) :perceived)
|
||||||
|
(setf (getf signal :foveal-focus) *foveal-focus-id*)
|
||||||
signal))
|
signal))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|||||||
@@ -36,6 +36,9 @@ You are strictly forbidden from considering a task complete without updating `gt
|
|||||||
** 8. Configuration Externalization (Environment-Driven)
|
** 8. Configuration Externalization (Environment-Driven)
|
||||||
Source code MUST be strictly free of hardcoded configuration values (e.g., ports, rhythms, timeouts). All such values must be extracted to the environment (via `.env`) and documented in `.env.example`. This ensures portability and security.
|
Source code MUST be strictly free of hardcoded configuration values (e.g., ports, rhythms, timeouts). All such values must be extracted to the environment (via `.env`) and documented in `.env.example`. This ensures portability and security.
|
||||||
|
|
||||||
|
** 9. Literate-Only Modification (The Tangle Mandate)
|
||||||
|
You are strictly forbidden from modifying generated source code files (e.g., `.lisp`, `.py`, `.el`) directly. All changes MUST be made within the corresponding Literate Org file and then tangled to the source. Direct modification of source code is only permitted with explicit user authorization.
|
||||||
|
|
||||||
* Phase B: Blueprint (PROTOCOL)
|
* Phase B: Blueprint (PROTOCOL)
|
||||||
:PROPERTIES:
|
:PROPERTIES:
|
||||||
:STATUS: SIGNED
|
:STATUS: SIGNED
|
||||||
|
|||||||
@@ -43,6 +43,7 @@
|
|||||||
#:context-get-system-logs
|
#:context-get-system-logs
|
||||||
#:context-resolve-path
|
#:context-resolve-path
|
||||||
#:context-get-skill-telemetry
|
#:context-get-skill-telemetry
|
||||||
|
#:harness-track-telemetry
|
||||||
#:context-assemble-global-awareness
|
#:context-assemble-global-awareness
|
||||||
|
|
||||||
;; --- Reactive Signal Pipeline ---
|
;; --- Reactive Signal Pipeline ---
|
||||||
@@ -113,6 +114,16 @@
|
|||||||
(defvar *skill-telemetry* (make-hash-table :test 'equal))
|
(defvar *skill-telemetry* (make-hash-table :test 'equal))
|
||||||
(defvar *telemetry-lock* (bt:make-lock "harness-telemetry-lock"))
|
(defvar *telemetry-lock* (bt:make-lock "harness-telemetry-lock"))
|
||||||
|
|
||||||
|
(defun harness-track-telemetry (skill-name duration status)
|
||||||
|
"Updates performance metrics for a specific skill. Status should be :success or :rejected."
|
||||||
|
(when skill-name
|
||||||
|
(bt:with-lock-held (*telemetry-lock*)
|
||||||
|
(let ((entry (or (gethash skill-name *skill-telemetry*) (list :executions 0 :total-time 0 :failures 0))))
|
||||||
|
(incf (getf entry :executions))
|
||||||
|
(incf (getf entry :total-time) duration)
|
||||||
|
(when (eq status :rejected) (incf (getf entry :failures)))
|
||||||
|
(setf (gethash skill-name *skill-telemetry*) entry)))))
|
||||||
|
|
||||||
(defvar *cognitive-tools* (make-hash-table :test 'equal))
|
(defvar *cognitive-tools* (make-hash-table :test 'equal))
|
||||||
|
|
||||||
(defstruct cognitive-tool
|
(defstruct cognitive-tool
|
||||||
|
|||||||
@@ -1,21 +1,26 @@
|
|||||||
(in-package :org-agent)
|
(in-package :org-agent)
|
||||||
|
|
||||||
(defun harness-track-telemetry (skill-name duration status)
|
(defvar *async-sensors* '(:chat-message :delegation :user-command)
|
||||||
"Updates performance metrics for a specific skill."
|
"List of sensors that should be processed asynchronously to avoid blocking gateways.")
|
||||||
(when skill-name (bt:with-lock-held (*telemetry-lock*)
|
|
||||||
(let ((entry (or (gethash skill-name *skill-telemetry*) (list :executions 0 :total-time 0 :failures 0))))
|
(defvar *foveal-focus-id* nil
|
||||||
(incf (getf entry :executions)) (incf (getf entry :total-time) duration)
|
"The Org ID of the node the user is currently interacting with.")
|
||||||
(when (eq status :rejected) (incf (getf entry :failures))) (setf (gethash skill-name *skill-telemetry*) entry)))))
|
|
||||||
|
|
||||||
(defun inject-stimulus (raw-message &key stream (depth 0))
|
(defun inject-stimulus (raw-message &key stream (depth 0))
|
||||||
"Enqueues a raw message into the reactive signal pipeline."
|
"Enqueues a raw message into the reactive signal pipeline."
|
||||||
(let* ((payload (getf raw-message :payload))
|
(let* ((payload (getf raw-message :payload))
|
||||||
(sensor (getf payload :sensor))
|
(sensor (getf payload :sensor))
|
||||||
(async-p (or (getf payload :async-p) (member sensor '(:chat-message :delegation :user-command)))))
|
(async-p (or (getf payload :async-p) (member sensor *async-sensors*))))
|
||||||
(when stream (setf (getf raw-message :reply-stream) stream))
|
(when stream (setf (getf raw-message :reply-stream) stream))
|
||||||
(if async-p (bt:make-thread (lambda () (restart-case (handler-bind ((error (lambda (c) (harness-log "ASYNC ERROR: ~a" c) (invoke-restart 'skip-event))))
|
(if async-p
|
||||||
(process-signal raw-message)) (skip-event () nil))) :name "org-agent-async-task")
|
(bt:make-thread
|
||||||
(restart-case (handler-bind ((error (lambda (c) (harness-log "SYSTEM ERROR: ~a" c) (invoke-restart 'skip-event)))) (process-signal raw-message))
|
(lambda ()
|
||||||
|
(restart-case (handler-bind ((error (lambda (c) (harness-log "ASYNC ERROR: ~a" c) (invoke-restart 'skip-event))))
|
||||||
|
(process-signal raw-message))
|
||||||
|
(skip-event () nil)))
|
||||||
|
:name "org-agent-async-task")
|
||||||
|
(restart-case (handler-bind ((error (lambda (c) (harness-log "SYSTEM ERROR: ~a" c) (invoke-restart 'skip-event))))
|
||||||
|
(process-signal raw-message))
|
||||||
(skip-event () (harness-log "SYSTEM RECOVERY: Stimulus dropped.~%"))))))
|
(skip-event () (harness-log "SYSTEM RECOVERY: Stimulus dropped.~%"))))))
|
||||||
|
|
||||||
(defun perceive-gate (signal)
|
(defun perceive-gate (signal)
|
||||||
@@ -24,13 +29,25 @@
|
|||||||
(type (getf signal :type))
|
(type (getf signal :type))
|
||||||
(sensor (getf payload :sensor)))
|
(sensor (getf payload :sensor)))
|
||||||
(harness-log "GATE [Perceive]: ~a (~a)" type (or sensor "no-sensor"))
|
(harness-log "GATE [Perceive]: ~a (~a)" type (or sensor "no-sensor"))
|
||||||
(snapshot-memory)
|
|
||||||
(cond ((eq type :EVENT)
|
(cond ((eq type :EVENT)
|
||||||
(case sensor
|
(case sensor
|
||||||
(:buffer-update (let ((ast (getf payload :ast))) (when ast (ingest-ast ast))))
|
(:buffer-update
|
||||||
(:point-update (let ((element (getf payload :element))) (when element (ingest-ast element))))
|
(let ((ast (getf payload :ast)))
|
||||||
(:interrupt (bt:with-lock-held (*interrupt-lock*) (setf *interrupt-flag* t)))))
|
(when ast
|
||||||
|
(snapshot-memory)
|
||||||
|
(ingest-ast ast))))
|
||||||
|
(:point-update
|
||||||
|
(let ((element (getf payload :element)))
|
||||||
|
(when element
|
||||||
|
(snapshot-memory)
|
||||||
|
(setf *foveal-focus-id* (ignore-errors (getf element :id)))
|
||||||
|
(ingest-ast element))))
|
||||||
|
(:interrupt
|
||||||
|
(bt:with-lock-held (*interrupt-lock*) (setf *interrupt-flag* t)))))
|
||||||
((eq type :RESPONSE)
|
((eq type :RESPONSE)
|
||||||
(harness-log "GATE [Perceive]: Act Result -> ~a" (getf payload :status))))
|
(harness-log "GATE [Perceive]: Act Result -> ~a" (getf payload :status))))
|
||||||
|
|
||||||
(setf (getf signal :status) :perceived)
|
(setf (getf signal :status) :perceived)
|
||||||
|
(setf (getf signal :foveal-focus) *foveal-focus-id*)
|
||||||
signal))
|
signal))
|
||||||
|
|||||||
Reference in New Issue
Block a user