feat: implement Foveal-Peripheral vision model and Org renderer

This commit is contained in:
2026-04-09 14:31:00 -04:00
parent 71401e606a
commit 13d660c3e9
6 changed files with 147 additions and 39 deletions

View File

@@ -80,7 +80,7 @@ Reads the raw literate source of a specific skill. This is crucial for "System 2
#+end_src
** Kernel Logs (context-get-system-logs)
Retrieves the most recent system logs, providing temporal context to the LLM.
Retrieves the most recent lines from the kernel's internal log.
#+begin_src lisp :tangle ../src/context.lisp
(defun context-get-system-logs (&optional (limit 20))
@@ -98,19 +98,33 @@ Provides execution stats for a specific skill.
(bt:with-lock-held (*telemetry-lock*) (gethash (string-downcase skill-name) *skill-telemetry*)))
#+end_src
** Sparse Trees (context-filter-sparse-tree)
Prunes the Org AST to show only specific nodes and their ancestors, creating a "skeleton" view that fits within LLM context limits.
** AST to Org Rendering (context-render-to-org)
Transforms the internal Object Store structures back into a human-readable (and LLM-readable) Org-mode string. It supports depth-based indentation and content suppression for peripheral nodes.
#+begin_src lisp :tangle ../src/context.lisp
(defun context-filter-sparse-tree (ast predicate)
"Prunes an AST to show only nodes matching a predicate and their ancestors."
(if (listp ast)
(let* ((contents (getf ast :contents))
(filtered-contents (remove-if #'null (mapcar (lambda (c) (context-filter-sparse-tree c predicate)) contents))))
(if (or (funcall predicate ast) (not (null filtered-contents)))
(let ((new-ast (copy-list ast))) (setf (getf new-ast :contents) filtered-contents) new-ast)
nil))
nil))
(defun context-render-to-org (obj &key (depth 1) (foveal-id nil))
"Recursively renders an org-object and its children to an Org string."
(let* ((is-foveal (equal (org-object-id obj) foveal-id))
(title (or (getf (org-object-attributes obj) :TITLE) "Untitled"))
(id (org-object-id obj))
(content (org-object-content obj))
(children (org-object-children obj))
(stars (make-string depth :initial-element #\*))
(output (format nil "~a ~a~%:PROPERTIES:~%:ID: ~a~%:END:~%" stars title id)))
;; Only include content if this is the foveal focus
(when (and is-foveal content)
(setf output (concatenate 'string output content (string #\Newline))))
;; Recursively render children
(dolist (child-id children)
(let ((child-obj (lookup-object child-id)))
(when child-obj
(setf output (concatenate 'string output
(context-render-to-org child-obj
:depth (1+ depth)
:foveal-id foveal-id))))))
output))
#+end_src
** Path Resolution (context-resolve-path)
@@ -130,20 +144,20 @@ Expands environment variables (like `$HOME`) within path strings.
#+end_src
** Global Awareness (context-assemble-global-awareness)
The primary "peripheral vision" generator. It produces the skeletal overview of the Memex that is prepended to LLM prompts.
The primary context generator. It identifies active projects and the current foveal focus, then assembles a pruned Org-mode view of the Memex.
#+begin_src lisp :tangle ../src/context.lisp
(defun context-assemble-global-awareness ()
(defun context-assemble-global-awareness (&optional signal)
"Produces a high-level skeletal outline of the current Object Store for the LLM."
(let ((projects (context-get-active-projects))
(output "GLOBAL MEMEX AWARENESS (Peripheral Vision):
(let* ((payload (when signal (getf signal :payload)))
(foveal-id (when payload (getf payload :target-id)))
(projects (context-get-active-projects))
(output "GLOBAL MEMEX AWARENESS (Peripheral Vision):
"))
(if projects
(dolist (project projects)
(setf output (concatenate 'string output
(format nil "- PROJECT: ~a (ID: ~a)~%"
(getf (org-object-attributes project) :TITLE)
(org-object-id project)))))
(context-render-to-org project :foveal-id foveal-id))))
(setf output (concatenate 'string output "No active projects found.~%")))
output))
#+end_src
@@ -205,3 +219,41 @@ Identifies the top-k most semantically related objects in the entire store by co
(maphash (lambda (id obj) (let ((vec (org-object-vector obj))) (when vec (push (cons (cosine-similarity query-vector vec) obj) similarities)))) *object-store*)
(let ((sorted (sort similarities #'> :key #'car))) (subseq sorted 0 (min top-k (length sorted))))))
#+end_src
* Phase E: Chaos (Verification)
Verification of the peripheral vision extraction and rendering logic.
#+begin_src lisp :tangle ../tests/peripheral-vision-tests.lisp
(defpackage :org-agent-peripheral-vision-tests
(:use :cl :fiveam :org-agent))
(in-package :org-agent-peripheral-vision-tests)
(def-suite vision-suite
:description "Verification of Foveal-Peripheral context model.")
(in-suite vision-suite)
(test test-foveal-rendering
"Verify that the foveal target is rendered with content, while siblings are skeletal."
(clrhash org-agent::*object-store*)
(let* ((ast '(:type :HEADLINE :properties (:ID "proj-root" :TITLE "Project" :TAGS "project")
:contents ((:type :HEADLINE :properties (:ID "node-foveal" :TITLE "Foveal Node")
:raw-content "FOVEAL CONTENT" :contents nil)
(:type :HEADLINE :properties (:ID "node-peripheral" :TITLE "Peripheral Node")
:raw-content "PERIPHERAL CONTENT" :contents nil)))))
(ingest-ast ast)
(let ((output (context-assemble-global-awareness (list :payload (list :target-id "node-foveal")))))
;; Foveal node should have its content
(is (search "FOVEAL CONTENT" output))
;; Peripheral node should be skeletal (only title/ID)
(is (search "* Peripheral Node" output))
(is (not (search "PERIPHERAL CONTENT" output))))))
(test test-awareness-budget
"Verify that context-assemble-global-awareness handles multiple projects."
(clrhash org-agent::*object-store*)
(ingest-ast '(:type :HEADLINE :properties (:ID "p1" :TITLE "Project 1" :TAGS "project") :contents nil))
(ingest-ast '(:type :HEADLINE :properties (:ID "p2" :TITLE "Project 2" :TAGS "project") :contents nil))
(let ((output (context-assemble-global-awareness)))
(is (search "Project 1" output))
(is (search "Project 2" output))))
#+end_src