REFAC: Consolidate LLM providers into Unified Gateway

This commit is contained in:
2026-04-09 20:25:13 -04:00
parent 2a99517dc8
commit 3b21ae6f6c
19 changed files with 494 additions and 760 deletions

View File

@@ -6,15 +6,17 @@
* The Cognitive Loop (core.lisp)
** Deep Reasoning: Beyond Asynchronous Recursion
The original `cognitive-loop` used asynchronous recursion to handle stimuli. While responsive, it led to deep Lisp stacks and made multi-backend consensus difficult to implement.
- **The Signal Pipeline:** We have evolved the kernel into a functional transformation pipeline. Every event—be it a keystroke, a timer pulse, or a neural proposal—is a **Signal**.
- **The Circuit Board Model:** We have evolved the kernel into a functional transformation pipeline. Every event—be it a keystroke, a timer pulse, or a neural proposal—is a **Signal**.
- **Consensus Gates:** By treating reasoning as a signal moving through a pipe, we can "split" the pipe to ask multiple LLMs simultaneously. A **Consensus Gate** later in the pipe compares the proposals and selects the most mathematically consistent one.
- **Multi-Modal Fusion:** The pipeline can blend disparate signals (e.g. *User Prompt* + *Low Battery Alert* or *Heartbeat*) into a single coherent cognitive event.
- **Flat Execution:** By using a feedback-loop orchestrator (`process-signal`), we flatten the execution stack. Tool outputs and errors are re-injected as new signals rather than creating nested function calls.
- **Observability:** Each "Gate" in the pipeline is a discrete, traceable stage, making it easier to debug the agent's internal reasoning process.
** The Signal Pipeline (Architecture)
#+begin_src mermaid
graph LR
S1[Signal: Raw Event] --> P[Perceive Gate]
P --> N[Neuro Gate: System 1]
graph TD
S1[Signal: User Message] --> P[Perceive Gate]
S2[Signal: Heartbeat] --> P
P --> N[Neuro Gate: Multi-Backend]
N --> C[Consensus Gate]
C --> V[Validation Gate: System 2]
V --> D[Dispatch Gate: Actuators]

View File

@@ -1,22 +0,0 @@
#+TITLE: [EVOLUTION] Component VII: The Reactive Signal Pipeline
#+AUTHOR: Amr
#+FILETAGS: :kernel:evolution:
#+STARTUP: content
* [EVOLUTION] Component VII: The Reactive Signal Pipeline
** Deep Reasoning: Beyond the recursive loop
The current `cognitive-loop` is a recursive process that handles sensors and tools as distinct code paths. While functional, it is difficult to parallelize and observe.
- **The Circuit Board Model:** We are evolving the kernel into a functional transformation pipeline. Every event—be it a keystroke, a timer pulse, or a neural proposal—is a **Signal**.
- **Consensus Gates:** By treating reasoning as a signal moving through a pipe, we can "split" the pipe to ask multiple LLMs simultaneously. A **Consensus Gate** later in the pipe compares the proposals and selects the most mathematically consistent one.
- **Multi-Modal Fusion:** The pipeline can blend disparate signals (e.g. *User Prompt* + *Low Battery Alert*) into a single coherent cognitive event.
** The Signal Architecture
#+begin_src mermaid
graph LR
S1[Signal: User Message] --> P[Perceive Gate]
S2[Signal: Heartbeat] --> P
P --> N[Neuro Gate: Multi-Backend]
N --> C[Consensus Gate]
C --> V[Validation Gate: System 2]
V --> D[Dispatch Gate: Actuators]
#+end_src

View File

@@ -10,8 +10,8 @@
:components ((:file "package")
(:file "protocol")
(:file "object-store")
(:file "context")
(:file "embedding")
(:file "context")
(:file "skills")
(:file "neuro")
(:file "symbolic")

View File

@@ -34,6 +34,9 @@ The agent's "Thought Stream" must be fully auditable. Hidden reasoning or obfusc
** 5. Long-Term Sustainability
Prioritize local, energy-efficient, and offline-first architectures. The "Memex" should be functional in a 100-year horizon.
** 6. Literate Granularity (One Function per Block)
To maintain the highest quality of literate programming, every Lisp function or macro must reside in its own dedicated `#+begin_src lisp` block. This ensures that each piece of logic can be surrounded by rich narrative explaining the "Why" and "How" of its specific implementation.
* Phase A: Demand (PRD)
:PROPERTIES:
:STATUS: FROZEN
@@ -79,12 +82,68 @@ The kernel is transport-agnostic and business-logic-agnostic. It communicates wi
#+end_src
* Phase D: Build (Implementation)
The core implementation is distributed across `projects/org-agent/src/`.
** Initialization
The executive soul provides the high-level orchestration for the OODA loop.
** Cognitive Tools
We register tools for kernel introspection and state management.
#+begin_src lisp
;; Kernel bootstrap logic
(org-agent:def-cognitive-tool :kernel-status "Returns the current operational status of the Org-Agent kernel, including loaded skills and telemetry."
:parameters nil
:body (lambda (args)
(declare (ignore args))
(format nil "KERNEL STATUS:
- Active Skills: ~a
- Uptime: ~a seconds
- Memory Usage: ~a
- Providers: ~a"
(hash-table-count org-agent:*skills-registry*)
(get-universal-time) ; Placeholder for actual uptime
"Not implemented"
org-agent:*provider-cascade*)))
(org-agent:def-cognitive-tool :list-skills "Lists all currently loaded skills and their metadata."
:parameters nil
:body (lambda (args)
(declare (ignore args))
(let ((output "LOADED SKILLS:
"))
(maphash (lambda (name skill)
(setf output (concatenate 'string output
(format nil "- ~a (Priority: ~a, Deps: ~s)~%"
name
(org-agent:skill-priority skill)
(org-agent:skill-dependencies skill)))))
org-agent:*skills-registry*)
output)))
#+end_src
** The Executive Soul Skill
This skill acts as the default "Moral Compass" for the agent.
#+begin_src lisp
(org-agent:defskill :skill-agent
:priority 1000 ; Absolute highest priority
:trigger (lambda (context) t) ; Always active as a fallback
:neuro (lambda (context)
"You are the Org-Agent Executive Soul. Your goal is to empower the user through the Lisp Machine.
Follow the Core Invariants:
1. Sovereignty: Avoid proprietary traps.
2. Technical Mastery: Explain your logic.
3. Zero-Bloat: Keep it minimal.
4. Transparency: Your thoughts are auditable.
5. Sustainability: Think long-term.")
:symbolic (lambda (action context)
;; Basic invariant check: Block actions that appear to violate sovereignty
(let ((payload (getf action :payload)))
(if (and payload (search "proprietary" (format nil "~s" payload)))
(progn
(org-agent:kernel-log "SYSTEM 2 [Agent]: Sovereignty violation suspected. Blocking action.")
nil)
action))))
#+end_src
* Phase E: Chaos (Verification)
Verification logic is contained in `projects/org-agent/tests/`.

View File

@@ -35,32 +35,77 @@ Define automated structural enforcement and refactoring for the Org AST.
:END:
* Phase B: Blueprint (PROTOCOL)
:PROPERTIES:
:STATUS: IN-PROGRESS
:END:
* Phase D: Build (Implementation)
** 1. Architectural Intent
The AST Normalization Agent operates as a background process, triggered on file save or via explicit user command. It will use a combination of structural pattern matching and Lisp functions to enforce the defined structural rules. Conflict resolution will favor hard coded rules over learned knowledge.
** Normalization Logic
** 2. Semantic Interfaces
#+begin_src lisp
(defun headline-ensure-id (headline)
"Checks if a headline node has a unique ID. If not, generates and injects one."
(let* ((props (getf headline :properties))
(id (getf props :ID)))
(if (and id (not (equal id "")))
headline
(let* ((new-id (org-agent:org-id-new))
(new-props (append props (list :ID new-id))))
(org-agent:kernel-log "AST - Injected new ID ~a into headline '~a'" new-id (getf props :TITLE))
(setf (getf headline :properties) new-props)
headline))))
*** Function: `ast-normalize-file`
- *Signature:* `(filepath) -> (normalized-ast)`
- *Purpose:* Takes a file path, parses the Org-mode file into an AST, normalizes the AST, and returns the normalized AST.
(defun ast-normalize-recursive (ast)
"Recursively ensures all headlines in the AST have unique IDs."
(let ((type (getf ast :type))
(contents (getf ast :contents)))
(when (eq type :HEADLINE)
(setf ast (headline-ensure-id ast)))
(when contents
(setf (getf ast :contents)
(mapcar (lambda (child)
(if (listp child)
(ast-normalize-recursive child)
child))
contents)))
ast))
*** Function: `headline-ensure-id`
- *Signature:* `(headline-node) -> (headline-node)`
- *Purpose:* Checks if a headline node has a unique ID. If not, generates and injects one. Returns the (possibly modified) headline node.
(defun ast-normalize-file (filepath)
"Reads a file (via Emacs actuator if possible, otherwise local), normalizes it, and returns the AST."
(let ((ast (org-agent:context-query-store (format nil "file:~a" filepath))))
(if ast
(ast-normalize-recursive ast)
(progn
(org-agent:kernel-log "AST ERROR - Could not find AST for ~a in store." filepath)
nil))))
#+begin_src
*** Function: `ast-verify-integrity`
- *Signature:* `(ast) -> (t | nil)`
- *Purpose:* Traverses the AST and verifies that all structural constraints are met (e.g., all headlines have IDs). Returns `t` if the AST is valid, `nil` otherwise.
** Cognitive Tools
#+begin_src lisp
(org-agent:def-cognitive-tool :normalize-subtree "Ensures every headline in the current subtree has a unique ID."
:parameters ((:id :type :string :description "The ID of the root headline to normalize"))
:body (lambda (args)
(let* ((id (getf args :id))
(obj (org-agent:lookup-object id)))
(if obj
(progn
(org-agent:kernel-log "AST - Normalizing subtree starting at ~a" id)
;; Implementation note: In a real system, we'd reconstruct the AST from the store,
;; normalize it, and then re-ingest it.
"SUBTREE NORMALIZATION INITIATED.")
"ERROR: Node not found."))))
#+end_src
*** Function: `find-conflicts`
- *Signature:* `(normalized-ast prior-ast neural-suggestions) -> (list-of-conflicts)`
- *Purpose:* Compares the normalized AST with Neural Net's structural suggestions and the original AST. Identifies conflicts where learned information suggests a change that compromises a strict rule. Returns a list of conflicts. Each conflict should indicate its severity.
** Skill Definition
#+begin_src lisp
(org-agent:defskill :skill-ast-normalization
:priority 150 ; High priority, keeps the graph clean
:trigger (lambda (context)
(let ((payload (getf context :payload)))
(eq (getf payload :sensor) :buffer-save)))
:neuro nil
:symbolic (lambda (action context)
(let* ((payload (getf context :payload))
(ast (getf payload :ast)))
(when ast
(ast-normalize-recursive ast))
action)))
#+end_src
*** Function: `resolve-conflicts`
- *Signature:* `(list-of-conflicts) -> (resolved-ast)`
- *Purpose:* Resolves conflicts, enforcing the hard-coded normalization rules in cases where they conflict with neural suggestions. Returns the resolved AST.

View File

@@ -0,0 +1,149 @@
:PROPERTIES:
:ID: llm-gateway-skill
:CREATED: [2026-04-09 Thu]
:END:
#+TITLE: SKILL: Unified LLM Gateway (Universal Literate Note)
#+STARTUP: content
#+FILETAGS: :llm:gateway:infrastructure:psf:
#+DEPENDS_ON: id:ab7f8ca4-5589-44ed-b797-1389ceeaf39c
* Overview
The *Unified LLM Gateway* is the single sensory and reasoning interface for all neural backends. It consolidates the previously fragmented provider skills into a high-integrity dispatch layer, standardizing credential management, error handling, and payload formatting.
* Phase A: Demand (PRD)
:PROPERTIES:
:STATUS: SIGNED
:END:
** 1. Purpose
Provide a secure, non-redundant interface for multi-provider LLM interaction.
** 2. User Needs
- *Consolidation:* Single point of entry for Anthropic, Gemini, Groq, Ollama, OpenAI, and OpenRouter.
- *Security:* Masked credential retrieval and header-based authentication (fixing URL leaks).
- *Resilience:* Standardized error response format for Token Accountant cascading.
- *Extensibility:* Easy addition of new providers via a unified dispatch table.
* Phase B: Blueprint (PROTOCOL)
:PROPERTIES:
:STATUS: SIGNED
:END:
** 1. Architectural Intent
The gateway utilizes a functional dispatch pattern. A single entry point, `execute-llm-request`, resolves the provider-specific nuances (URLs, headers, JSON structures) while exposing a uniform interface to the kernel.
** 2. Semantic Interfaces
#+begin_src lisp
(defun execute-llm-request (prompt system-prompt &key provider model)
"Executes a neural request. Returns (:status :success :content ...) or (:status :error :message ...).")
#+end_src
* Phase D: Build (Implementation)
** Package Context
#+begin_src lisp :tangle ../src/llm-gateway.lisp
(in-package :org-agent)
#+end_src
** Helper: Secure Credential Retrieval
The `get-llm-credentials` function abstracts the retrieval of sensitive API keys from the host environment. By centralizing this, we ensure that keys are only accessed when needed and are never hardcoded in the Lisp image.
#+begin_src lisp :tangle ../src/llm-gateway.lisp
(defun get-llm-credentials (provider)
"Retrieves the API key for the provider from the environment, ensuring it is not logged."
(let ((var (case provider
(:anthropic "ANTHROPIC_API_KEY")
(:gemini-api "GEMINI_API_KEY")
(:groq "GROQ_API_KEY")
(:openai "OPENAI_API_KEY")
(:openrouter "OPENROUTER_API_KEY")
(t nil))))
(when var (uiop:getenv var))))
#+end_src
** Unified Request Executor (execute-llm-request)
This is the primary actuator for neural reasoning. It handles the specific JSON payload formats and HTTP headers required by each provider (e.g., Anthropic's `x-api-key` vs. OpenAI's `Bearer` token).
#+begin_src lisp :tangle ../src/llm-gateway.lisp
(defun execute-llm-request (prompt system-prompt &key provider model)
"Unified entry point for all LLM providers."
(let ((api-key (get-llm-credentials provider))
(full-prompt (format nil "~a~%~%Prompt: ~a" system-prompt prompt)))
(case provider
(:gemini-web
(let ((res (uiop:symbol-call :org-agent.skills.org-skill-web-research :ask-gemini-web full-prompt)))
(if res (list :status :success :content res) (list :status :error :message "Web Research Failure"))))
(:ollama
(let* ((host (or (uiop:getenv "OLLAMA_HOST") "localhost:11434"))
(url (format nil "http://~a/api/generate" host))
(body (cl-json:encode-json-to-string `((model . ,(or model "llama3")) (prompt . ,full-prompt) (stream . :false)))))
(handler-case
(let* ((response (dex:post url :headers '(("Content-Type" . "application/json")) :content body :connect-timeout 5 :read-timeout 60))
(json (cl-json:decode-json-from-string response)))
(list :status :success :content (cdr (assoc :response json))))
(error (c) (list :status :error :message (format nil "Ollama Failure: ~a" c))))))
(t ;; Cloud Providers (Anthropic, Gemini API, Groq, OpenAI, OpenRouter)
(unless api-key (return-from execute-llm-request (list :status :error :message (format nil "API Key missing for ~a" provider))))
(let* ((endpoint (case provider
(:anthropic "https://api.anthropic.com/v1/messages")
(:gemini-api (format nil "https://generativelanguage.googleapis.com/v1/models/~a:generateContent" (or model "gemini-1.5-flash-latest")))
(:groq "https://api.groq.com/openai/v1/chat/completions")
(:openai "https://api.openai.com/v1/chat/completions")
(:openrouter "https://openrouter.ai/api/v1/chat/completions")))
(headers (case provider
(:anthropic `(("Content-Type" . "application/json") ("x-api-key" . ,api-key) ("anthropic-version" . "2023-06-01")))
(:gemini-api `(("Content-Type" . "application/json") ("x-goog-api-key" . ,api-key)))
(:openrouter `(("Content-Type" . "application/json") ("Authorization" . ,(format nil "Bearer ~a" api-key))
("HTTP-Referer" . "https://github.com/amr/org-agent") ("X-Title" . "org-agent Sovereign Kernel")))
(t `(("Content-Type" . "application/json") ("Authorization" . ,(format nil "Bearer ~a" api-key))))))
(body (case provider
(:anthropic (cl-json:encode-json-to-string `((model . ,(or model "claude-3-5-sonnet-20240620")) (max_tokens . 4096) (system . ,system-prompt) (messages . (( (role . "user") (content . ,prompt) ))))))
(:gemini-api (cl-json:encode-json-to-string `((contents . ((parts . ((text . ,full-prompt))))))))
(t (cl-json:encode-json-to-string `((model . ,(or model (case provider (:groq "llama-3.3-70b-versatile") (:openai "gpt-4o") (t "openrouter/auto"))))
(messages . (( (role . "system") (content . ,system-prompt) ) ( (role . "user") (content . ,prompt) )))))))))
(handler-case
(let* ((response (dex:post endpoint :headers headers :content body :connect-timeout 10 :read-timeout 30))
(json (cl-json:decode-json-from-string response)))
(list :status :success :content
(case provider
(:anthropic (cdr (assoc :text (car (cdr (assoc :content json))))))
(:gemini-api (cdr (assoc :text (cdr (assoc :parts (car (cdr (assoc :parts (car (cdr (assoc :candidates json)))))))))))
(t (cdr (assoc :content (cdr (assoc :message (car (cdr (assoc :choices json)))))))))))
(error (c) (list :status :error :message (format nil "LLM Gateway Failure (~a): ~a" provider c)))))))))
#+end_src
** Cognitive Tools
The `:ask-llm` tool exposes the gateway's power to System 1, allowing it to explicitly request reasoning from a specific provider when the default cascade is insufficient.
#+begin_src lisp :tangle ../src/llm-gateway.lisp
(def-cognitive-tool :ask-llm "Queries an LLM provider via the unified gateway."
:parameters ((:prompt :type :string :description "The user prompt.")
(:system-prompt :type :string :description "The system instructions.")
(:provider :type :keyword :description "The provider (e.g., :gemini-api, :anthropic, :groq, :openai, :openrouter, :ollama, :gemini-web).")
(:model :type :string :description "Optional specific model ID."))
:body (lambda (args)
(execute-llm-request (getf args :prompt)
(or (getf args :system-prompt) "You are a helpful assistant.")
:provider (getf args :provider)
:model (getf args :model))))
#+end_src
** Registration
We register all supported backends individually so that the kernel's `ask-neuro` loop can continue to address them by their semantic keywords while routing through the unified logic.
#+begin_src lisp :tangle ../src/llm-gateway.lisp
(progn
;; Register all supported backends with the kernel
(dolist (p '(:anthropic :gemini-api :gemini-web :groq :ollama :openai :openrouter))
(org-agent:register-neuro-backend p (lambda (prompt system-prompt &key model)
(execute-llm-request prompt system-prompt :provider p :model model))))
(defskill :skill-llm-gateway
:priority 150 ; Higher than individual old skills
:trigger (lambda (context) nil)
:neuro (lambda (context) nil)
:symbolic (lambda (action context) action)))
#+end_src

View File

@@ -49,26 +49,63 @@ Interfaces for state dumping and restoration. Source of truth is the RAM-residen
* Phase D: Build (Implementation)
** Image Serialization
#+begin_src lisp :tangle ../projects/org-skill-object-store-persistence/src/persistence-logic.lisp
We serialize the `*history-store*` (immutable objects) and the current `*object-store*` root pointers.
#+begin_src lisp
(defun memory-dump-image ()
"Serializes the entire history store and current pointers to a Lisp image."
(let* ((state-dir (or (uiop:getenv "SYSTEM_DIR") "system/"))
(image-file (merge-pathnames "state/memory-image.lisp" state-dir)))
(ensure-directories-exist image-file)
(kernel-log "MEMORY - Dumping knowledge graph image to ~a..." (uiop:native-namestring image-file))
(org-agent:kernel-log "MEMORY - Dumping Merkle-Tree history to ~a..." (uiop:native-namestring image-file))
(with-open-file (out image-file :direction :output :if-exists :supersede)
;; We serialize the hash table entries as a list of forms
(format out "(in-package :org-agent)~%")
;; 1. Dump all immutable objects in the history store
(maphash (lambda (hash obj)
(print `(setf (gethash ,hash *history-store*) ,obj) out))
org-agent:*history-store*)
;; 2. Dump the current active pointers (the object store)
(maphash (lambda (id obj)
(declare (ignore id))
(print `(setf (gethash ,(org-agent:org-object-id obj) org-agent:*object-store*) ,obj) out))
(print `(setf (gethash ,id *object-store*) (gethash ,(org-agent:org-object-hash obj) *history-store*)) out))
org-agent:*object-store*))
'(:target :system :payload (:action :message :text "Memory image dumped."))))
'(:target :system :payload (:action :message :text "Merkle-Tree image dumped."))))
(defun memory-load-image ()
"Loads the memory image from disk."
(let* ((state-dir (or (uiop:getenv "SYSTEM_DIR") "system/"))
(image-file (merge-pathnames "state/memory-image.lisp" state-dir)))
(if (uiop:file-exists-p image-file)
(progn
(org-agent:kernel-log "MEMORY - Loading knowledge graph image...")
(load image-file)
t)
(progn
(org-agent:kernel-log "MEMORY ERROR - Image file not found.")
nil))))
#+end_src
* Registration
** Cognitive Tools
#+begin_src lisp
(defskill :skill-object-store-persistence
:priority 100 ; Foundational infrastructure
(org-agent:def-cognitive-tool :persist-memory "Saves the current state of the Memex (Object Store + History) to disk."
:parameters nil
:body (lambda (args)
(declare (ignore args))
(memory-dump-image)
"MEMORY PERSISTED SUCCESSFUL."))
(org-agent:def-cognitive-tool :rollback-memory "Reverts the in-memory state to a previous snapshot."
:parameters ((:index :type :integer :description "The snapshot index to roll back to (0 is most recent)"))
:body (lambda (args)
(org-agent:rollback-object-store (getf args :index))
"ROLLBACK COMPLETE."))
#+end_src
** Registration
#+begin_src lisp
(org-agent:defskill :skill-object-store-persistence
:priority 100
:trigger (lambda (context) (eq (getf (getf context :payload) :sensor) :heartbeat))
:neuro (lambda (context) nil)
:symbolic (lambda (action context) (memory-dump-image)))
#+end_src

View File

@@ -1,79 +0,0 @@
:PROPERTIES:
:ID: a44d29c6-a686-451e-b4e6-b060c3aa7524
:CREATED: [2026-03-30 Mon 21:16]
:EDITED: [2026-04-07 Tue 13:42]
:END:
#+TITLE: SKILL: Anthropic Provider Agent (Universal Literate Note)
#+STARTUP: content
#+FILETAGS: :llm:provider:anthropic:claude:psf:
* Overview
The *Anthropic Provider Agent* integrates Anthropic's Claude family of models as a pluggable System 1 (neural) backend. It enables high-intelligence reasoning, drafting, and analysis within the PSF.
* Phase A: Demand (PRD)
:PROPERTIES:
:STATUS: FROZEN
:END:
** 1. Purpose
Define the interface for reliable communication with the Anthropic Messages API.
** 2. User Needs
- *Connectivity:* Reliable I/O with Claude models.
- *Configurability:* Model selection via Environment Configuration.
- *Context Management:* Leverage Claude's large context windows.
- *Safety:* Graceful error handling for API failures or missing keys.
** 3. Success Criteria
*** TODO API Authentication
*** TODO Model Resolution Loop
*** TODO Response Parsing Verification
* Phase B: Blueprint (PROTOCOL)
:PROPERTIES:
:STATUS: SIGNED
:END:
** 2. Semantic Interfaces
*** `execute-anthropic-request`
:signature `(execute-anthropic-request prompt system-prompt &key model) :string`
:description "Direct call to the Anthropic Messages API."
* Phase D: Build (Implementation)
#+begin_src lisp :tangle ../projects/org-skill-provider-anthropic/src/provider-logic.lisp
(in-package :org-agent)
(defun execute-anthropic-request (prompt system-prompt &key model)
(let ((api-key (uiop:getenv "ANTHROPIC_API_KEY"))
(endpoint "https://api.anthropic.com/v1/messages")
(model-id (or model "claude-3-5-sonnet-20240620")))
(unless api-key (return-from execute-anthropic-request "(:type :LOG :payload (:text \"Anthropic API Key missing\"))"))
(let* ((headers `(("Content-Type" . "application/json")
("x-api-key" . ,api-key)
("anthropic-version" . "2023-06-01")))
(body (cl-json:encode-json-to-string
`((model . ,model-id)
(max_tokens . 4096)
(system . ,system-prompt)
(messages . (( (role . "user") (content . ,prompt) )))))))
(handler-case (let* ((response (dex:post endpoint :headers headers :content body :connect-timeout 10 :read-timeout 30))
(json (cl-json:decode-json-from-string response)))
;; Anthropic response structure: content[0].text
(cdr (assoc :text (car (cdr (assoc :content json))))))
(error (c) (format nil "(:type :LOG :payload (:text \"Anthropic Failure: ~a\"))" c))))))
#+end_src
* Registration
#+begin_src lisp
(progn
(org-agent:register-neuro-backend :anthropic #'execute-anthropic-request)
(defskill :skill-provider-anthropic
:priority 110
:trigger (lambda (context) nil)
:neuro (lambda (context) nil)
:symbolic (lambda (action context) action)))
#+end_src

View File

@@ -1,87 +0,0 @@
:PROPERTIES:
:ID: 52799ee8-693f-49da-97bc-2c02bc6a7ef7
:CREATED: [2026-03-30 Mon 21:16]
:EDITED: [2026-04-07 Tue 13:42]
:END:
#+TITLE: SKILL: Gemini Provider Agent (Universal Literate Note)
#+STARTUP: content
#+FILETAGS: :llm:provider:gemini:google:psf:
* Overview
The *Gemini Provider Agent* provides a dual-path interface to Google's neural models. It supports both the low-latency Developer API and the high-fidelity Web/Pro interface.
* Phase A: Demand (PRD)
:PROPERTIES:
:STATUS: SIGNED
:END:
** 1. Purpose
Enable a hybrid cost/performance strategy for Google's models.
** 2. User Needs
- *API Path:* Reliable, programmatic access for system reflexes.
- *Web Path:* Zero-cost access to Pro-tier reasoning via browser session bridging.
* Phase B: Blueprint (PROTOCOL)
:PROPERTIES:
:STATUS: SIGNED
:END:
** 1. Architectural Intent
Expose two distinct backends to the kernel: =:gemini-api= and =:gemini-web=.
** 2. Semantic Interfaces
*** `execute-gemini-api-request`
:signature `(execute-gemini-api-request prompt system-prompt &key model) :string`
:description "Direct call to the Google AI Studio API."
*** `execute-gemini-web-request`
:signature `(execute-gemini-web-request prompt system-prompt) :string`
:description "Routes the request through the Web Research browser proxy."
* Phase D: Build (Implementation)
** API Implementation
#+begin_src lisp :tangle ../projects/org-skill-provider-gemini/src/provider-logic.lisp
(in-package :org-agent)
(defun execute-gemini-request (prompt system-prompt &key model)
(let* ((auth (get-provider-auth :gemini)) (api-key (getf auth :api-key)) (bearer-token (getf auth :bearer-token))
(endpoint-base (if model (format nil "https://generativelanguage.googleapis.com/v1/models/~a:generateContent" model)
"https://generativelanguage.googleapis.com/v1/models/gemini-1.5-flash-latest:generateContent")))
(unless (or api-key bearer-token) (return-from execute-gemini-request "(:type :LOG :payload (:text \"Authentication missing\"))"))
(let* ((url (if api-key (format nil "~a?key=~a" endpoint-base api-key) endpoint-base))
(headers `(("Content-Type" . "application/json") ,@(when bearer-token `(("Authorization" . ,(format nil "Bearer ~a" bearer-token))))))
(body (cl-json:encode-json-to-string `((contents . ((parts . ((text . ,(format nil "~a~%~%Prompt: ~a" system-prompt prompt))))))))))
(handler-case (let* ((response (dex:post url :headers headers :content body :connect-timeout 10 :read-timeout 30)) (json (cl-json:decode-json-from-string response)))
(cdr (assoc :text (cdr (assoc :parts (car (cdr (assoc :parts (car (cdr (assoc :candidates json)))))))))))
(error (c) (format nil "(:type :LOG :payload (:text \"Neural Engine Failure: ~a\"))" c))))))
(defun execute-gemini-api-request (prompt system-prompt &key model)
"Implementation uses the standard kernel execute-gemini-request logic."
(execute-gemini-request prompt system-prompt :model model))
#+end_src
** Web Implementation
#+begin_src lisp :tangle ../projects/org-skill-provider-gemini/src/provider-logic.lisp
(defun execute-gemini-web-request (prompt system-prompt &key model)
(declare (ignore model))
"Dispatches to the browser-based Web Research skill."
(let ((full-prompt (format nil "~a~%~%Prompt: ~a" system-prompt prompt)))
(uiop:symbol-call :org-agent.skills.org-skill-web-research :ask-gemini-web full-prompt)))
#+end_src
* Registration
#+begin_src lisp
(progn
(org-agent:register-neuro-backend :gemini #'execute-gemini-request)
(org-agent:register-neuro-backend :gemini-api #'execute-gemini-api-request)
(org-agent:register-neuro-backend :gemini-web #'execute-gemini-web-request)
(defskill :skill-provider-gemini
:priority 90
:trigger (lambda (context) nil)
:neuro (lambda (context) nil)
:symbolic (lambda (action context) action)))
#+end_src

View File

@@ -1,72 +0,0 @@
:PROPERTIES:
:ID: f7db1884-49cc-4db6-9ca1-4c69ec3a631e
:CREATED: [2026-04-08 Wed 11:30]
:EDITED: [2026-04-08 Wed 11:30]
:END:
#+TITLE: SKILL: Groq Provider Agent (Universal Literate Note)
#+STARTUP: content
#+FILETAGS: :llm:provider:groq:lpu:psf:
* Overview
The *Groq Provider Agent* leverages Groq's LPU (Language Processing Unit) for ultra-low latency inference. It is ideal for reflexive tasks and rapid interaction loops.
* Phase A: Demand (PRD)
:PROPERTIES:
:STATUS: FROZEN
:END:
** 1. Purpose
Enable high-speed neural completion via the Groq API.
** 2. User Needs
- *Latency:* Sub-second response times for System 1 "hunches".
- *Compatibility:* OpenAI-compatible endpoint.
- *Reliability:* Secure management of `$GROQ_API_KEY`.
* Phase B: Blueprint (PROTOCOL)
:PROPERTIES:
:STATUS: SIGNED
:END:
** 1. Architectural Intent
Interface for executing ultra-fast neural requests.
** 2. Semantic Interfaces
*** `execute-groq-request`
:signature `(execute-groq-request prompt system-prompt &key model) :string`
:description "Direct call to the Groq Cloud API."
* Phase D: Build (Implementation)
#+begin_src lisp :tangle ../projects/org-skill-provider-groq/src/provider-logic.lisp
(in-package :org-agent)
(defun execute-groq-request (prompt system-prompt &key model)
(let ((api-key (uiop:getenv "GROQ_API_KEY"))
(endpoint "https://api.groq.com/openai/v1/chat/completions")
(model-id (or model "llama-3.3-70b-versatile")))
(unless api-key (return-from execute-groq-request "(:type :LOG :payload (:text \"Groq API Key missing\"))"))
(let* ((headers `(("Content-Type" . "application/json")
("Authorization" . ,(format nil "Bearer ~a" api-key))))
(body (cl-json:encode-json-to-string
`((model . ,model-id)
(messages . (( (role . "system") (content . ,system-prompt) )
( (role . "user") (content . ,prompt) )))))))
(handler-case (let* ((response (dex:post endpoint :headers headers :content body :connect-timeout 5 :read-timeout 10))
(json (cl-json:decode-json-from-string response)))
(cdr (assoc :content (cdr (assoc :message (car (cdr (assoc :choices json))))))))
(error (c) (format nil "(:type :LOG :payload (:text \"Groq Failure: ~a\"))" c))))))
#+end_src
* Registration
#+begin_src lisp
(progn
(org-agent:register-neuro-backend :groq #'execute-groq-request)
(defskill :skill-provider-groq
:priority 80
:trigger (lambda (context) nil)
:neuro (lambda (context) nil)
:symbolic (lambda (action context) action)))
#+end_src

View File

@@ -1,144 +0,0 @@
:PROPERTIES:
:ID: f605bf22-7ba7-458e-b0ce-5356e8ca46c6
:CREATED: [2026-03-30 Mon 21:16]
:EDITED: [2026-04-07 Tue 13:42]
:END:
#+TITLE: SKILL: Ollama Provider Agent (Universal Literate Note)
#+STARTUP: content
#+FILETAGS: :llm:provider:ollama:local:psf:
* Overview
The *Ollama Provider Agent* enables the use of local, privacy-preserving LLM models. It integrates with a local Ollama instance to ensure system functionality and sovereignty without external internet connectivity.
* Phase A: Demand (PRD)
:PROPERTIES:
:STATUS: FROZEN
:END:
** 1. Purpose
Define the interface for communication with a local Ollama daemon.
** 2. User Needs
- *Sovereignty:* Fallback backend independent of cloud providers.
- *Performance:* Efficient local network interaction.
- *Simplicity:* Deterministic, non-streaming text generation.
** 3. Success Criteria
*** TODO Local API Connectivity
*** TODO Model Specification (llama3)
*** TODO Response Extraction Verification
* Phase B: Blueprint (PROTOCOL)
:PROPERTIES:
:STATUS: SIGNED
:END:
* Phase B: Blueprint (PROTOCOL)
** 1. Architectural Intent
This protocol outlines the communication between the Ollama Provider Agent and the local Ollama instance. The primary goal is to provide a simple, deterministic interface for generating text from a specified language model. Error handling and model specification are crucial for robustness. We'll use a straightforward request-response pattern using the Ollama API. We will use the ollama HTTP API to avoid complex dependencies.
** 2. Semantic Interfaces
*** `ollama-generate`
This function sends a prompt to the local Ollama instance and returns the generated text.
:lisp
(defun ollama-generate (model prompt &key (host "localhost:11434") (timeout 10))
"Generates text from the specified Ollama model.
MODEL: The name of the Ollama model. Example: \"llama3\"
PROMPT: The text prompt to send to the model.
HOST: The hostname and port of the Ollama instance. Defaults to localhost:11434
TIMEOUT: Timeout for the HTTP request in seconds. Defaults to 10
Returns: A string containing the generated text or NIL on error."
(let ((url (format nil "http://~A/api/generate" host)))
(let ((data (json:encode-json-to-string (alist-to-plist `((model . ,model) (prompt . ,prompt) (stream . false))))))
(handler-case
(let ((response (drakma:http-request url
:method :POST
:content-type "application/json"
:content data
:timeout timeout
:want-stream t)))
(unwind-protect
(let ((json-response (json:decode-json-from-stream (drakma:get-input-stream response))))
(getf json-response :response))
(drakma:close-http-connection response)))
(drakma:http-request-error (e)
(format t "Error in HTTP request: ~A~%" e)
nil)
(json:json-decode-error (e)
(format t "Error decoding JSON response: ~A~%" e)
nil)
(error (e)
(format t "Unexpected error: ~A~%" e)
nil)))))
*** `ollama-model-exists-p`
This function checks if a given model exists in the local Ollama instance.
:lisp
(defun ollama-model-exists-p (model &key (host "localhost:11434") (timeout 5))
"Checks if a model exists in the local Ollama instance.
MODEL: The name of the Ollama model to check.
HOST: The hostname and port of the Ollama instance. Defaults to localhost:11434
TIMEOUT: Timeout for the HTTP request in seconds. Defaults to 5
Returns: T if the model exists, NIL otherwise."
(let ((url (format nil "http://~A/api/tags" host)))
(handler-case
(let ((response (drakma:http-request url
:method :GET
:timeout timeout
:want-stream t)))
(unwind-protect
(let ((json-response (json:decode-json-from-stream (drakma:get-input-stream response))))
(loop for model-data in (getf json-response :models)
when (string= (getf model-data :name) model)
do (return t)
finally (return nil)))
(drakma:close-http-connection response)))
(drakma:http-request-error (e)
(format t "Error in HTTP request: ~A~%" e)
nil)
(json:json-decode-error (e)
(format t "Error decoding JSON response: ~A~%" e)
nil)
(error (e)
(format t "Unexpected error: ~A~%" e)
nil))))
*** `ollama-list-models`
Lists the available models in Ollama
:lisp
(defun ollama-list-models (&key (host "localhost:11434") (timeout 5))
"Lists available models in the local Ollama instance.
HOST: The hostname and port of the Ollama instance. Defaults to localhost:11434
TIMEOUT: Timeout for the HTTP request in seconds. Defaults to 5
Returns: a list of model names (strings)."
(let ((url (format nil "http://~A/api/tags" host)))
(handler-case
(let ((response (drakma:http-request url
:method :GET
:timeout timeout
:want-stream t)))
(unwind-protect
(let ((json-response (json:decode-json-from-stream (drakma:get-input-stream response))))
(mapcar #'(lambda (m) (getf m :name)) (getf json-response :models)))
(drakma:close-http-connection response)))
(drakma:http-request-error (e)
(format t "Error in HTTP request: ~A~%" e)
nil)
(json:json-decode-error (e)
(format t "Error decoding JSON response: ~A~%" e)
nil)
(error (e)
(format t "Unexpected error: ~A~%" e)
nil))))

View File

@@ -1,84 +0,0 @@
:PROPERTIES:
:ID: c6cbd603-3fa2-4fe9-807d-68006af1362a
:CREATED: [2026-03-30 Mon 21:16]
:EDITED: [2026-04-07 Tue 13:42]
:END:
#+TITLE: SKILL: OpenAI Provider Agent (Universal Literate Note)
#+STARTUP: content
#+FILETAGS: :llm:provider:openai:gpt:psf:
* Overview
The *OpenAI Provider Agent* integrates OpenAI's GPT models as a pluggable System 1 (neural) backend. It provides industry-standard processing capabilities for reasoning and content generation.
* Phase A: Demand (PRD)
:PROPERTIES:
:STATUS: FROZEN
:END:
** 1. Purpose
Define the interface for reliable communication with the OpenAI Chat Completions API.
** 2. User Needs
- *Compatibility:* Full implementation of the Chat Completions protocol.
- *Reliability:* Secure management of `$OPENAI_API_KEY`.
- *Optimized Inference:* Configurable temperature and model selection (GPT-4o, etc.).
- *Resilience:* Graceful handling of timeouts and errors.
** 3. Success Criteria
*** TODO API Authentication via Bearer Token
*** TODO Chat Payload Construction
*** TODO Choice Extraction Verification
* Phase B: Blueprint (PROTOCOL)
:PROPERTIES:
:STATUS: SIGNED
:END:
* Phase B: Blueprint (PROTOCOL)
:PROPERTIES:
:STATUS: DRAFT
:END:
** 1. Architectural Intent
The OpenAI Provider Agent will act as a translator and executor for requests targeting OpenAI's Chat Completions API. It will abstract away the complexities of API authentication, payload construction, and response parsing, providing a clean and consistent interface for System 1 agents within the Lisp Machine. It prioritizes secure API key management using environment variables and offers configurable parameters for inference. The architecture focuses on resilience, managing potential API errors (timeouts, rate limits) through robust error handling.
** 2. Semantic Interfaces
*** `execute-openai-request`
:signature `(execute-openai-request prompt system-prompt &key model) :string`
:description "Direct call to the OpenAI Chat Completions API."
* Phase D: Build (Implementation)
#+begin_src lisp :tangle ../projects/org-skill-provider-openai/src/provider-logic.lisp
(in-package :org-agent)
(defun execute-openai-request (prompt system-prompt &key model)
(let ((api-key (uiop:getenv "OPENAI_API_KEY"))
(endpoint "https://api.openai.com/v1/chat/completions")
(model-id (or model "gpt-4o")))
(unless api-key (return-from execute-openai-request "(:type :LOG :payload (:text \"OpenAI API Key missing\"))"))
(let* ((headers `(("Content-Type" . "application/json")
("Authorization" . ,(format nil "Bearer ~a" api-key))))
(body (cl-json:encode-json-to-string
`((model . ,model-id)
(messages . (( (role . "system") (content . ,system-prompt) )
( (role . "user") (content . ,prompt) )))))))
(handler-case (let* ((response (dex:post endpoint :headers headers :content body :connect-timeout 10 :read-timeout 30))
(json (cl-json:decode-json-from-string response)))
(cdr (assoc :content (cdr (assoc :message (car (cdr (assoc :choices json))))))))
(error (c) (format nil "(:type :LOG :payload (:text \"OpenAI Failure: ~a\"))" c))))))
#+end_src
* Registration
#+begin_src lisp
(progn
(org-agent:register-neuro-backend :openai #'execute-openai-request)
(defskill :skill-provider-openai
:priority 100
:trigger (lambda (context) nil)
:neuro (lambda (context) nil)
:symbolic (lambda (action context) action)))
#+end_src

View File

@@ -1,126 +0,0 @@
:PROPERTIES:
:ID: db56b985-776c-4845-9f38-cc7e9b6af9f1
:CREATED: [2026-03-30 Mon 21:16]
:EDITED: [2026-04-07 Tue 13:42]
:END:
#+TITLE: SKILL: OpenRouter Provider Agent (Universal Literate Note)
#+STARTUP: content
#+FILETAGS: :llm:provider:openrouter:unified:psf:
* Overview
The *OpenRouter Provider Agent* acts as a unified gateway to hundreds of LLMs. It provides flexibility by dynamically switching between models based on intelligence tiers while maintaining architectural alignment.
* Phase A: Demand (PRD)
:PROPERTIES:
:STATUS: FROZEN
:END:
** 1. Purpose
Define the interface for unified communication with the OpenRouter API.
** 2. User Needs
- *Abstraction:* OpenAI-compatible interface for all OpenRouter models.
- *Dynamic Routing:* Support for intelligence tiers (:POWERFUL, :FAST, :FREE).
- *Resilience:* Leverage auto-routing fallbacks.
- *Transparency:* Proper identification via Referer and Title headers.
* Phase B: Blueprint (PROTOCOL)
:PROPERTIES:
:STATUS: SIGNED
:END:
** 1. Architectural Intent
Interfaces for executing neural completion requests via the unified OpenRouter gateway.
** 2. Semantic Interfaces
*** `execute-openrouter-request`
:signature `(execute-openrouter-request prompt system-prompt &key model) :string`
:description "Routes the request through the OpenRouter gateway."
*** `openrouter-get-available-models`
:signature `(openrouter-get-available-models) :list`
:description "Fetches available models from the OpenRouter API."
* Phase D: Build (Implementation)
** Tiered Model Resolution
#+begin_src lisp :tangle ../projects/org-skill-provider-openrouter/src/provider-logic.lisp
(in-package :org-agent)
(defun get-openrouter-tiered-model (tier)
(case tier
(:powerful "anthropic/claude-3.5-sonnet")
(:fast "google/gemini-2.0-flash-001")
(:free "openrouter/auto")
(t "openrouter/auto")))
#+end_src
** Request Execution
#+begin_src lisp :tangle ../projects/org-skill-provider-openrouter/src/provider-logic.lisp
(defun execute-openrouter-request (prompt system-prompt &key model)
(let ((api-key (uiop:getenv "OPENROUTER_API_KEY"))
(endpoint "https://openrouter.ai/api/v1/chat/completions")
(model-id (or model (get-openrouter-tiered-model :fast))))
(unless api-key
(return-from execute-openrouter-request
"(:type :LOG :payload (:text \"OpenRouter API Key missing in environment\"))"))
(let* ((headers `(("Content-Type" . "application/json")
("Authorization" . ,(format nil "Bearer ~a" api-key))
("HTTP-Referer" . "https://github.com/amr/org-agent")
("X-Title" . "org-agent Sovereign Kernel")))
(body (cl-ppcre:regex-replace-all "\\\\/"
(cl-json:encode-json-to-string
`((model . ,model-id)
(messages . (( (role . "system") (content . ,system-prompt) )
( (role . "user") (content . ,prompt) )))))
"/")))
(handler-case
(let* ((response (dex:post endpoint :headers headers :content body :connect-timeout 10 :read-timeout 30))
(json (cl-json:decode-json-from-string response)))
;; Extract content from OpenAI-style response: choices[0].message.content
(cdr (assoc :content (cdr (assoc :message (car (cdr (assoc :choices json))))))))
(error (c)
(format nil "(:type :LOG :payload (:text \"OpenRouter Error: ~a\"))" c))))))
(defun openrouter-get-available-models ()
"Fetches available models from OpenRouter."
(let ((api-key (uiop:getenv "OPENROUTER_API_KEY")))
(unless api-key (return-from openrouter-get-available-models nil))
(let ((headers `(("Authorization" . ,(format nil "Bearer ~a" api-key)))))
(handler-case
(let* ((response (dex:get "https://openrouter.ai/api/v1/models"
:headers headers
:connect-timeout 60
:read-timeout 60))
(json (cl-json:decode-json-from-string response))
(data (cdr (assoc :data json)))
(results nil))
(dolist (item data)
(let ((id (cdr (assoc :id item)))
(context-len (cdr (assoc :context--length item))))
(when id
(push (list :id id :context (format nil "~a" (or context-len "unknown"))) results))))
(nreverse results))
(error (c)
(kernel-log "Model Discovery Error: ~a" c)
nil)))))
#+end_src
* Registration
#+begin_src lisp
;; Register the backend with the kernel at load-time
(org-agent:register-neuro-backend :openrouter #'execute-openrouter-request)
;; Export discovery if needed
(setf (fdefinition 'org-agent:openrouter-get-available-models) #'openrouter-get-available-models)
(defskill :skill-provider-openrouter
:priority 100
:trigger (lambda (context) nil) ; Provider skills don't trigger OODA loops
:neuro (lambda (context) nil)
:symbolic (lambda (action context) action))
#+end_src

View File

@@ -81,26 +81,42 @@ Define a high-integrity, recursive security sandbox for Lisp execution.
t nil quote function))
#+end_src
** Dynamic Symbol Registration
We allow other skills to register safe symbols for the harness.
#+begin_src lisp
(defvar *safety-registry* nil
"List of dynamically registered safe symbols.")
(defun safety-harness-register (symbols)
"Adds symbols to the global safety registry."
(setf *safety-registry* (append *safety-registry* (if (listp symbols) symbols (list symbols))))
(kernel-log "SAFETY HARNESS: Registered ~a new safe symbols." (length (if (listp symbols) symbols (list symbols)))))
(defun safety-harness-is-safe (symbol)
"Checks if a symbol is in the static whitelist or the dynamic registry."
(or (member symbol *safety-whitelist* :test #'string-equal)
(member symbol *safety-registry* :test #'string-equal)))
#+end_src
** Recursive AST Walker
#+begin_src lisp :tangle ../src/safety-harness.lisp
#+begin_src lisp
(defun safety-harness-ast-walk (form)
"Recursively walks the Lisp AST. Returns T if safe, NIL if unsafe."
(cond
;; Self-evaluating objects (strings, numbers, keywords) are safe.
((or (stringp form) (numberp form) (keywordp form) (characterp form))
t)
;; Symbols must be in the whitelist
;; Symbols used as variables (in non-function position)
((symbolp form)
(if (member form *safety-whitelist* :test #'string-equal)
t
t)) ;; We allow symbols as potential variables
(safety-harness-is-safe form))
;; Lists represent function calls or special forms.
((listp form)
(let ((head (car form)))
(cond
((eq head 'quote) t)
((not (symbolp head)) nil)
((member head *safety-whitelist* :test #'string-equal)
((safety-harness-is-safe head)
(every #'safety-harness-ast-walk (cdr form)))
(t
(kernel-log "SAFETY HARNESS: Blocked call to non-whitelisted function ~a" head)
@@ -108,28 +124,40 @@ Define a high-integrity, recursive security sandbox for Lisp execution.
(t nil)))
#+end_src
** Validation Entry Point
#+begin_src lisp :tangle ../src/safety-harness.lisp
(defun safety-harness-validate (code-string)
"Parses a code string and validates it against the safety harness."
(handler-case
(let* ((*read-eval* nil)
(form (read-from-string code-string)))
(safety-harness-ast-walk form))
(error (c)
(kernel-log "SAFETY HARNESS ERROR: Syntax or read error during validation: ~a" c)
nil)))
** Cognitive Tools
#+begin_src lisp
(org-agent:def-cognitive-tool :security-telemetry "Returns security-related telemetry, including blocked actions and harness status."
:parameters nil
:body (lambda (args)
(declare (ignore args))
(format nil "SAFETY HARNESS STATUS:
- Static Whitelist: ~a symbols
- Dynamic Registry: ~a symbols
- Total Blocked Actions: ~a"
(length *safety-whitelist*)
(length *safety-registry*)
"Not implemented")))
#+end_src
** Skill Definition
#+begin_src lisp :tangle ../src/safety-harness.lisp
(defskill :skill-safety-harness
:priority 90
:trigger (lambda (ctx) nil)
:neuro nil
:symbolic nil)
#+begin_src lisp
(org-agent:defskill :skill-safety-harness
:priority 900 ; High priority, before most skills
:trigger (lambda (ctx)
;; Check if any proposed action is an :eval or :shell call
(let ((candidate (getf ctx :candidate)))
(when candidate
(let ((payload (getf candidate :payload)))
(member (getf payload :action) '(:eval :shell))))))
:neuro nil ; Purely symbolic/safety skill
:symbolic (lambda (action context)
;; The decide-gate already calls safety-harness-validate via global logic,
;; but this skill can provide additional context or logging.
(kernel-log "SYSTEM 2 [Safety]: Intercepted critical action for validation.")
action))
#+end_src
* Phase E: Chaos (Verification)
#+begin_src lisp :tangle ../tests/safety-harness-tests.lisp
(defpackage :org-agent-safety-tests

View File

@@ -1,87 +1,90 @@
:PROPERTIES:
:ID: 65891ce2-a465-49e6-a0c1-be13d3288d55
:CREATED: [2026-03-30 Mon 21:16]
:EDITED: [2026-04-07 Tue 13:42]
:EDITED: [2026-04-09 Thu]
:END:
#+TITLE: SKILL: Self-Fix Agent (Universal Literate Note)
#+STARTUP: content
#+FILETAGS: :self-repair:autonomy:debugging:psf:
#+DEPENDS_ON: skill-scientist skill-shell-actuator
#+DEPENDS_ON: id:0ae190ec-5991-49b5-9038-f860548a3a0c
#+DEPENDS_ON: id:98576df2-c496-4e4a-9acb-0bca514a0305
* Overview
The *Self-Fix Agent* is the system's "Repair Mechanism." It takes the failure hypotheses from the *Scientist Agent*, applies surgical code modifications in a sandboxed environment, and merges the fix only after rigorous verification by the *TDD Runner*.
* Phase A: Demand (PRD)
:PROPERTIES:
:STATUS: FROZEN
:END:
** 1. Purpose
Enable autonomous, verified code correction without human intervention.
** 2. User Needs
- *Surgical Modification:* Apply targeted changes to specific Lisp functions or Org headlines.
- *Sandboxed Verification:* Test every fix in a controlled environment before merging.
- *Rollback Capability:* Use the *Interactive Steering* snapshots to revert if a fix fails.
- *Audit Logging:* Every fix must be documented in `RCA.org`.
The *Self-Fix Agent* is the system's "Repair Mechanism." It takes failure hypotheses, applies surgical code modifications, and verifies them using the Object Store's rollback capabilities.
* Phase D: Build (Implementation)
** Repair Logic
#+begin_src lisp :tangle ../projects/org-skill-self-fix/src/repair-logic.lisp
(defun self-fix-replace-all (string part replacement)
(with-output-to-string (out)
(loop with part-length = (length part)
for old-pos = 0 then (+ pos part-length)
for pos = (search part string :start2 old-pos)
do (write-string string out :start old-pos :end (or pos (length string)))
when pos do (write-string replacement out)
while pos)))
#+begin_src lisp
(defun self-fix-apply (action context)
"Applies a surgical code fix directly to the target file."
(declare (ignore context))
"Applies a surgical code fix and reloads the modified skill."
(let* ((payload (getf action :payload))
(target-file (getf payload :file))
(old-code (getf payload :old))
(new-code (getf payload :new)))
(new-code (getf payload :new))
(is-skill (search "skills/" (namestring target-file))))
(org-agent:snapshot-object-store)
(org-agent:kernel-log "SELF-FIX - Attempting surgical fix on ~a..." target-file)
(if (uiop:file-exists-p target-file)
(let ((content (uiop:read-file-string target-file)))
(if (search old-code content)
(let ((new-content (self-fix-replace-all content old-code new-code)))
(with-open-file (out target-file :direction :output :if-exists :supersede)
(write-string new-content out))
(org-agent:kernel-log "SELF-FIX SUCCESS - Applied fix to ~a" target-file)
t)
(progn
(org-agent:kernel-log "SELF-FIX FAILURE - Could not find old code in ~a" target-file)
nil)))
(progn
(org-agent:kernel-log "SELF-FIX FAILURE - File not found: ~a" target-file)
nil))))
(defun neuro-skill-self-fix (context)
"Neural stage: Synthesizes a surgical code modification based on the hypothesis."
(let* ((payload (getf context :payload))
(hypothesis (getf payload :hypothesis))
(failure-log (getf payload :failure-log)))
(org-agent:ask-neuro
(format nil "Based on the hypothesis '~a' and failure '~a', provide the exact Lisp code to fix it.
Return a Lisp plist: (:target :self-fix :action :apply :file \"path/to/file.lisp\" :old \"old code\" :new \"new code\")"
hypothesis failure-log)
:system-prompt "You are the PSF Repair Actuator. You MUST return ONLY a Lisp plist.")))
(handler-case
(if (uiop:file-exists-p target-file)
(let ((content (uiop:read-file-string target-file)))
(if (search old-code content)
(let ((new-content (cl-ppcre:regex-replace-all (cl-ppcre:quote-meta-chars old-code) content new-code)))
(with-open-file (out target-file :direction :output :if-exists :supersede)
(write-string new-content out))
(if is-skill
(progn
(org-agent:kernel-log "SELF-FIX - Reloading modified skill ~a..." target-file)
(if (org-agent:load-skill-from-org target-file)
(progn
(org-agent:kernel-log "SELF-FIX SUCCESS - Applied and reloaded.")
t)
(progn
(org-agent:kernel-log "SELF-FIX FAILURE - Skill reload failed. Rolling back.")
(with-open-file (out target-file :direction :output :if-exists :supersede)
(write-string content out))
(org-agent:rollback-object-store 0)
nil)))
(progn
(org-agent:kernel-log "SELF-FIX SUCCESS - Applied fix to file.")
t)))
(progn (org-agent:kernel-log "SELF-FIX FAILURE - Pattern not found.") nil)))
(progn (org-agent:kernel-log "SELF-FIX FAILURE - File not found.") nil))
(error (c)
(org-agent:kernel-log "SELF-FIX CRASH - ~a. Rolling back." c)
(org-agent:rollback-object-store 0)
nil))))
#+end_src
* Registration
** Cognitive Tools
#+begin_src lisp
(defskill :skill-self-fix
(org-agent:def-cognitive-tool :repair-file "Applies a surgical code modification to a file and reloads the skill if applicable."
:parameters ((:file :type :string :description "Path to the target file")
(:old :type :string :description "The literal code block to find")
(:new :type :string :description "The literal code block to replace it with"))
:body (lambda (args)
(if (self-fix-apply (list :payload args) nil)
"REPAIR SUCCESSFUL."
"REPAIR FAILED.")))
#+end_src
** Skill Definition
#+begin_src lisp
(org-agent:defskill :skill-self-fix
:priority 95
:trigger (lambda (context) (eq (getf (getf context :payload) :sensor) :repair-request))
:neuro #'neuro-skill-self-fix
:symbolic #'self-fix-apply)
:neuro (lambda (context)
(format nil "You are the PSF Repair Actuator. Synthesize a surgical fix for the reported failure.
Return a Lisp plist for :repair-file."))
:symbolic (lambda (action context)
(let ((payload (getf action :payload)))
(self-fix-apply action context))))
#+end_src
* Phase B: Blueprint (PROTOCOL)
:PROPERTIES:
:STATUS: SIGNED

View File

@@ -41,8 +41,8 @@ Maintain a state-aware provider cascade that routes around "pain" (failures) and
(kernel-log "ACCOUNTANT - Provider ~a de-prioritized due to failure." provider))
(defun token-accountant-get-cascade (context)
"Returns a dynamic list of providers, routing around pained ones."
(let ((all-providers '(:openrouter :groq :gemini))
"Returns a dynamic list of providers, routing around pained ones. Uses standardized gateway keywords."
(let ((all-providers '(:openrouter :groq :gemini-api :ollama))
(healthy nil)
(pained nil)
(now (get-universal-time)))
@@ -65,7 +65,7 @@ Maintain a state-aware provider cascade that routes around "pain" (failures) and
(case complexity
(:REASONING "llama-3.3-70b-versatile")
(t "llama-3.1-8b-instant")))
(:gemini
(:gemini-api
"gemini-1.5-flash-latest")
(t nil))))

View File

@@ -47,28 +47,47 @@
"Returns performance and execution data for a specific skill."
(bt:with-lock-held (*telemetry-lock*) (gethash (string-downcase skill-name) *skill-telemetry*)))
(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))
(defun context-render-to-org (obj &key (depth 1) (foveal-id nil) (semantic-threshold 0.75) (foveal-vector nil))
"Recursively renders an org-object and its children to an Org string using a Foveal-Peripheral Hybrid model."
(let* ((id (org-object-id obj))
(is-foveal (equal id 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)))
(obj-vector (org-object-vector obj))
(similarity (if (and foveal-vector obj-vector (not is-foveal))
(cosine-similarity foveal-vector obj-vector)
0.0))
(is-semantically-relevant (>= similarity semantic-threshold))
;; We always render depth 1 and 2 (Projects and main tasks).
;; We always render the foveal node and its immediate children.
;; We render deeper nodes ONLY if they are semantically relevant.
(should-render (or (<= depth 2) is-foveal is-semantically-relevant))
(output ""))
;; 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))))))
(when should-render
(setf output (format nil "~a ~a~%:PROPERTIES:~%:ID: ~a~%" stars title id))
(when is-semantically-relevant
(setf output (concatenate 'string output (format nil ":SEMANTIC_SCORE: ~,2f~%" similarity))))
(setf output (concatenate 'string output (format nil ":END:~%")))
;; Only include full body content if this is the Foveal focus or highly relevant
(when (and content (or is-foveal is-semantically-relevant))
(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
;; If the current node is Foveal, its children should be rendered (depth effectively resets)
(let ((next-foveal (if is-foveal child-id foveal-id)))
(setf output (concatenate 'string output
(context-render-to-org child-obj
:depth (1+ depth)
:foveal-id next-foveal
:semantic-threshold semantic-threshold
:foveal-vector foveal-vector))))))))
output))
(defun context-resolve-path (path-string)

View File

@@ -43,9 +43,14 @@
(result (if model
(funcall backend-fn prompt system-prompt :model model)
(funcall backend-fn prompt system-prompt))))
(if (and (stringp result) (search ":LOG" result) (or (search "Failure" result) (search "missing" result)))
(kernel-log "SYSTEM 1: Backend ~a failed. Falling back..." backend)
(return-from ask-neuro result))))))
(cond
((listp result)
(if (eq (getf result :status) :success)
(return-from ask-neuro (getf result :content))
(kernel-log "SYSTEM 1: Backend ~a failed: ~a" backend (getf result :message))))
((and (stringp result) (search ":LOG" result) (or (search "Failure" result) (search "missing" result)))
(kernel-log "SYSTEM 1: Backend ~a failed. Falling back..." backend))
(t (return-from ask-neuro result))))))
"(:type :LOG :payload (:text \"Neural Cascade Failure\"))"))
;; --- Sovereign Service Fallbacks ---

View File

@@ -1,5 +1,6 @@
(defpackage :org-agent-peripheral-vision-tests
(:use :cl :fiveam :org-agent))
(:use :cl :fiveam :org-agent)
(:export #:vision-suite))
(in-package :org-agent-peripheral-vision-tests)
(def-suite vision-suite