CHORE: Prepare for Signal Gateway implementation
This commit is contained in:
@@ -28,16 +28,52 @@ graph TD
|
||||
(in-package :org-agent)
|
||||
#+end_src
|
||||
|
||||
** Global Kernel State
|
||||
The kernel maintains several thread-safe global variables for logging, telemetry, and execution control.
|
||||
** System Logs
|
||||
Rolling buffer of kernel diagnostics.
|
||||
|
||||
#+begin_src lisp :tangle ../src/core.lisp
|
||||
(defvar *system-logs* nil)
|
||||
#+end_src
|
||||
|
||||
** Logs Lock
|
||||
Thread-safety for logging operations.
|
||||
|
||||
#+begin_src lisp :tangle ../src/core.lisp
|
||||
(defvar *logs-lock* (bt:make-lock "kernel-logs-lock"))
|
||||
#+end_src
|
||||
|
||||
** Max Log History
|
||||
The maximum number of diagnostic lines to retain in memory.
|
||||
|
||||
#+begin_src lisp :tangle ../src/core.lisp
|
||||
(defvar *max-log-history* 100)
|
||||
#+end_src
|
||||
|
||||
** Interrupt Flag
|
||||
Atomic flag used to halt the reasoning loop.
|
||||
|
||||
#+begin_src lisp :tangle ../src/core.lisp
|
||||
(defvar *interrupt-flag* nil)
|
||||
#+end_src
|
||||
|
||||
** Interrupt Lock
|
||||
Thread-safety for loop interruption.
|
||||
|
||||
#+begin_src lisp :tangle ../src/core.lisp
|
||||
(defvar *interrupt-lock* (bt:make-lock "kernel-interrupt-lock"))
|
||||
#+end_src
|
||||
|
||||
** Skill Telemetry
|
||||
Hash table tracking execution metrics per skill.
|
||||
|
||||
#+begin_src lisp :tangle ../src/core.lisp
|
||||
(defvar *skill-telemetry* (make-hash-table :test 'equal))
|
||||
#+end_src
|
||||
|
||||
** Telemetry Lock
|
||||
Thread-safety for metric updates.
|
||||
|
||||
#+begin_src lisp :tangle ../src/core.lisp
|
||||
(defvar *telemetry-lock* (bt:make-lock "kernel-telemetry-lock"))
|
||||
#+end_src
|
||||
|
||||
|
||||
@@ -22,14 +22,24 @@ This module handles the interaction with Large Language Models, providing a unif
|
||||
(defun get-env (var &optional default) (or (uiop:getenv var) default))
|
||||
#+end_src
|
||||
|
||||
** Authentication Registry
|
||||
** Auth Providers Registry
|
||||
Tracks API keys and authentication functions for various providers.
|
||||
|
||||
#+begin_src lisp :tangle ../src/neuro.lisp
|
||||
(defvar *auth-providers* (make-hash-table :test 'equal))
|
||||
#+end_src
|
||||
|
||||
** Register Auth Provider
|
||||
Registers a function or list to provide authentication for a specific backend.
|
||||
|
||||
#+begin_src lisp :tangle ../src/neuro.lisp
|
||||
(defun register-auth-provider (name fn) (setf (gethash name *auth-providers*) fn))
|
||||
#+end_src
|
||||
|
||||
** Get Provider Auth
|
||||
Retrieves authentication credentials for a provider, falling back to environment variables if not found in the registry.
|
||||
|
||||
#+begin_src lisp :tangle ../src/neuro.lisp
|
||||
(defun get-provider-auth (provider)
|
||||
"Retrieves authentication credentials for a provider."
|
||||
(let ((auth (gethash provider *auth-providers*)))
|
||||
@@ -50,15 +60,31 @@ Tracks API keys and authentication functions for various providers.
|
||||
(list :api-key legacy)))))))))
|
||||
#+end_src
|
||||
|
||||
** Backend Registry and Cascade
|
||||
The kernel supports a "cascade" of providers. If the primary provider (e.g. OpenRouter) fails, it automatically falls back to the secondary (e.g. Gemini).
|
||||
** Neuro Backends Registry
|
||||
Tracks the actual implementation functions for each LLM provider.
|
||||
|
||||
#+begin_src lisp :tangle ../src/neuro.lisp
|
||||
(defvar *neuro-backends* (make-hash-table :test 'equal))
|
||||
#+end_src
|
||||
|
||||
** Provider Cascade
|
||||
The ordered list of backends to attempt for neural reasoning.
|
||||
|
||||
#+begin_src lisp :tangle ../src/neuro.lisp
|
||||
(defvar *provider-cascade* '(:openrouter :gemini))
|
||||
#+end_src
|
||||
|
||||
** Register Neuro Backend
|
||||
Maps a keyword identifier to a backend implementation function.
|
||||
|
||||
#+begin_src lisp :tangle ../src/neuro.lisp
|
||||
(defun register-neuro-backend (name fn) (setf (gethash name *neuro-backends*) fn))
|
||||
#+end_src
|
||||
|
||||
** Model Selector Function
|
||||
A hook for dynamic model selection based on the current context.
|
||||
|
||||
#+begin_src lisp :tangle ../src/neuro.lisp
|
||||
(defvar *model-selector-fn* nil "A function called with (provider context) to return a model ID.")
|
||||
#+end_src
|
||||
|
||||
|
||||
@@ -16,10 +16,18 @@ We begin by ensuring we are in the correct package.
|
||||
(in-package :org-agent)
|
||||
#+end_src
|
||||
|
||||
** Actuator Registry
|
||||
Global registry mapping target keywords to their physical actuator functions.
|
||||
|
||||
#+begin_src lisp :tangle ../src/protocol.lisp
|
||||
(defvar *actuator-registry* (make-hash-table :test 'equal)
|
||||
"Global registry mapping target keywords to their physical actuator functions.")
|
||||
#+end_src
|
||||
|
||||
** Actuator Registration
|
||||
Registers an actuator function. Actuators receive two arguments: (ACTION CONTEXT).
|
||||
|
||||
#+begin_src lisp :tangle ../src/protocol.lisp
|
||||
(defun register-actuator (name fn)
|
||||
"Registers an actuator function. Actuators receive two arguments: (ACTION CONTEXT)."
|
||||
(setf (gethash name *actuator-registry*) fn))
|
||||
|
||||
@@ -108,7 +108,7 @@ REQUIRED FORMATS:
|
||||
#+end_src
|
||||
|
||||
* Registration
|
||||
#+begin_src lisp
|
||||
#+begin_src lisp :tangle ../src/chat-logic.lisp
|
||||
(defskill :skill-chat
|
||||
:priority 100
|
||||
:trigger #'trigger-skill-chat
|
||||
|
||||
@@ -42,13 +42,32 @@ The gateway operates as an autonomous background service. It uses `dexador` for
|
||||
(in-package :org-agent)
|
||||
#+end_src
|
||||
|
||||
** State & Config
|
||||
** State: Update Tracking
|
||||
Tracks the last processed message ID to prevent duplicates.
|
||||
|
||||
#+begin_src lisp :tangle ../src/gateway-telegram.lisp
|
||||
(defvar *telegram-last-update-id* 0)
|
||||
#+end_src
|
||||
|
||||
** State: Polling Thread
|
||||
Reference to the background thread responsible for message reception.
|
||||
|
||||
#+begin_src lisp :tangle ../src/gateway-telegram.lisp
|
||||
(defvar *telegram-polling-thread* nil)
|
||||
#+end_src
|
||||
|
||||
** State: Authorized Chats
|
||||
Whitelist of chat IDs permitted to interact with the agent.
|
||||
|
||||
#+begin_src lisp :tangle ../src/gateway-telegram.lisp
|
||||
(defvar *telegram-authorized-chats* nil
|
||||
"List of chat IDs allowed to interact with the bot. Hydrated from environment.")
|
||||
#+end_src
|
||||
|
||||
** Token Retrieval
|
||||
Fetches the Bot API token from the secure vault.
|
||||
|
||||
#+begin_src lisp :tangle ../src/gateway-telegram.lisp
|
||||
(defun get-telegram-token () (vault-get-secret :telegram))
|
||||
#+end_src
|
||||
|
||||
@@ -102,7 +121,9 @@ The gateway operates as an autonomous background service. It uses `dexador` for
|
||||
(error (c) (kernel-log "TELEGRAM POLL ERROR: ~a" c))))))
|
||||
#+end_src
|
||||
|
||||
** Background Polling Loop
|
||||
** Start Polling
|
||||
Initializes the Telegram background thread.
|
||||
|
||||
#+begin_src lisp :tangle ../src/gateway-telegram.lisp
|
||||
(defun start-telegram-gateway ()
|
||||
"Initializes the Telegram background thread."
|
||||
@@ -115,24 +136,39 @@ The gateway operates as an autonomous background service. It uses `dexador` for
|
||||
(sleep 3)))
|
||||
:name "org-agent-telegram-gateway"))
|
||||
(kernel-log "TELEGRAM: Gateway polling active.")))
|
||||
#+end_src
|
||||
|
||||
** Stop Polling
|
||||
Gracefully terminates the background thread.
|
||||
|
||||
#+begin_src lisp :tangle ../src/gateway-telegram.lisp
|
||||
(defun stop-telegram-gateway ()
|
||||
(when (and *telegram-polling-thread* (bt:thread-alive-p *telegram-polling-thread*))
|
||||
(bt:destroy-thread *telegram-polling-thread*)
|
||||
(setf *telegram-polling-thread* nil)))
|
||||
#+end_src
|
||||
|
||||
** Skill Definition & Registration
|
||||
** Registration: Actuator
|
||||
Register the Telegram channel as a physical actuator.
|
||||
|
||||
#+begin_src lisp :tangle ../src/gateway-telegram.lisp
|
||||
(progn
|
||||
(register-actuator :telegram #'execute-telegram-action)
|
||||
|
||||
(defskill :skill-gateway-telegram
|
||||
:priority 150
|
||||
:trigger (lambda (ctx) (declare (ignore ctx)) nil) ;; Passive, handles its own loop
|
||||
:neuro nil
|
||||
:symbolic (lambda (action ctx) (declare (ignore ctx)) action))
|
||||
|
||||
;; Initialize the background polling loop
|
||||
(start-telegram-gateway))
|
||||
(register-actuator :telegram #'execute-telegram-action)
|
||||
#+end_src
|
||||
|
||||
** Registration: Skill
|
||||
Define the passive skill entry for the gateway.
|
||||
|
||||
#+begin_src lisp :tangle ../src/gateway-telegram.lisp
|
||||
(defskill :skill-gateway-telegram
|
||||
:priority 150
|
||||
:trigger (lambda (ctx) (declare (ignore ctx)) nil) ;; Passive, handles its own loop
|
||||
:neuro nil
|
||||
:symbolic (lambda (action ctx) (declare (ignore ctx)) action))
|
||||
#+end_src
|
||||
|
||||
** Initialization
|
||||
Trigger the polling loop upon loading.
|
||||
|
||||
#+begin_src lisp :tangle ../src/gateway-telegram.lisp
|
||||
(start-telegram-gateway)
|
||||
#+end_src
|
||||
|
||||
@@ -155,21 +155,24 @@ The `:ask-llm` tool exposes the gateway's power to System 1, allowing it to expl
|
||||
: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.
|
||||
** Registration: Backends
|
||||
Register each supported provider with the kernel's neural registry.
|
||||
|
||||
#+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)))
|
||||
(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))))
|
||||
#+end_src
|
||||
|
||||
** Registration: Skill
|
||||
Define the foundational skill entry for the gateway.
|
||||
|
||||
#+begin_src lisp :tangle ../src/llm-gateway.lisp
|
||||
(defskill :skill-llm-gateway
|
||||
:priority 150 ; Higher than individual old skills
|
||||
:trigger (lambda (context) (declare (ignore context)) nil)
|
||||
:neuro (lambda (context) (declare (ignore context)) nil)
|
||||
:symbolic (lambda (action context) (declare (ignore context)) action))
|
||||
#+end_src
|
||||
|
||||
* Phase E: Chaos (Verification)
|
||||
|
||||
@@ -75,18 +75,34 @@ Interfaces for secure system calls. State is event-driven via the core kernel bu
|
||||
|
||||
* Phase D: Build (Implementation)
|
||||
|
||||
** Whitelisting & Execution
|
||||
#+begin_src lisp :tangle ../src/shell-logic.lisp
|
||||
(in-package :org-agent)
|
||||
** Allowed Commands
|
||||
Whitelist of permitted host binaries.
|
||||
|
||||
#+begin_src lisp :tangle ../src/shell-logic.lisp
|
||||
(defparameter *allowed-commands* '("ls" "git" "rg" "grep" "date" "echo" "cat" "node" "python3" "sbcl"))
|
||||
#+end_src
|
||||
|
||||
** Shell Metacharacters
|
||||
Dangerous characters that are banned to prevent command injection.
|
||||
|
||||
#+begin_src lisp :tangle ../src/shell-logic.lisp
|
||||
(defparameter *shell-metacharacters* '(#\; #\& #\| #\> #\< #\$ #\` #\\ #\!)
|
||||
"Characters that are banned in shell commands to prevent injection.")
|
||||
#+end_src
|
||||
|
||||
** Safety Check (shell-command-safe-p)
|
||||
Predicate to verify a command string is free of metacharacters.
|
||||
|
||||
#+begin_src lisp :tangle ../src/shell-logic.lisp
|
||||
(defun shell-command-safe-p (cmd-string)
|
||||
"Returns T if the command string contains no dangerous metacharacters."
|
||||
(not (some (lambda (char) (find char cmd-string)) *shell-metacharacters*)))
|
||||
#+end_src
|
||||
|
||||
** Shell Execution (execute-shell-safely)
|
||||
The primary secure actuator for host system calls.
|
||||
|
||||
#+begin_src lisp :tangle ../src/shell-logic.lisp
|
||||
(defun execute-shell-safely (action context)
|
||||
(let* ((cmd-string (getf (getf action :payload) :cmd))
|
||||
(executable (car (uiop:split-string (string-trim " " cmd-string) :separator '(#\Space)))))
|
||||
@@ -112,6 +128,11 @@ Interfaces for secure system calls. State is event-driven via the core kernel bu
|
||||
`(:type :EVENT :payload (:sensor :shell-response :cmd ,cmd-string :stdout ,(or stdout "") :stderr ,(or stderr "") :exit-code ,exit-code))
|
||||
:stream (getf context :reply-stream)))))))
|
||||
#+end_src
|
||||
|
||||
** Script Synthesis (execute-sandboxed-script)
|
||||
Executes a synthesized script (Python/Lisp/JS) in a controlled directory.
|
||||
|
||||
#+begin_src lisp :tangle ../src/shell-logic.lisp
|
||||
(defun execute-sandboxed-script (action context)
|
||||
"Executes a synthesized script (Python/Lisp/JS) in a controlled directory.
|
||||
This enables SOTA-level Tool Synthesis and Iterative Fixing."
|
||||
@@ -135,7 +156,12 @@ Interfaces for secure system calls. State is event-driven via the core kernel bu
|
||||
(org-agent:inject-stimulus
|
||||
`(:type :EVENT :payload (:sensor :shell-response :cmd ,cmd :stdout ,(or stdout "") :stderr ,(or stderr "") :exit-code ,exit-code :synthesis-p t))
|
||||
:stream (getf context :reply-stream))))))
|
||||
#+end_src
|
||||
|
||||
** Infrastructure: MicroVM Provisioning
|
||||
Hardware-Level Isolation for future security evolution.
|
||||
|
||||
#+begin_src lisp :tangle ../src/shell-logic.lisp
|
||||
(defun provision-microvm (id &key (cpu 1) (ram 512))
|
||||
"Hardware-Level Isolation: Provisions an ephemeral Firecracker MicroVM.
|
||||
This is the high-security evolution of directory-based sandboxing."
|
||||
@@ -179,12 +205,21 @@ Interfaces for secure system calls. State is event-driven via the core kernel bu
|
||||
#+end_src
|
||||
|
||||
* Registration
|
||||
#+begin_src lisp
|
||||
(org-agent:register-actuator :shell #'execute-shell-safely)
|
||||
|
||||
** Registration: Actuator
|
||||
Register the shell channel as a physical actuator.
|
||||
|
||||
#+begin_src lisp :tangle ../src/shell-logic.lisp
|
||||
(org-agent:register-actuator :shell #'execute-shell-safely)
|
||||
#+end_src
|
||||
|
||||
** Registration: Skill
|
||||
Define the skill entry for the shell actuator.
|
||||
|
||||
#+begin_src lisp :tangle ../src/shell-logic.lisp
|
||||
(defskill :skill-shell-actuator
|
||||
:priority 80
|
||||
:trigger #'trigger-skill-shell-actuator
|
||||
:neuro #'neuro-skill-shell-actuator
|
||||
:symbolic (lambda (action context) action))
|
||||
:symbolic (lambda (action context) (declare (ignore context)) action))
|
||||
#+end_src
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
(in-package :org-agent)
|
||||
|
||||
(defparameter *allowed-commands* '("ls" "git" "rg" "grep" "date" "echo" "cat" "node" "python3" "sbcl"))
|
||||
|
||||
(defparameter *shell-metacharacters* '(#\; #\& #\| #\> #\< #\$ #\` #\\ #\!)
|
||||
"Characters that are banned in shell commands to prevent injection.")
|
||||
|
||||
@@ -91,3 +92,11 @@
|
||||
(let ((result-text (format nil "* Shell Command Result\n- Command: ~a\n- Exit Code: ~a\n\n** STDOUT\n#+begin_example\n~a\n#+end_example\n\n** STDERR\n#+begin_example\n~a\n#+end_example"
|
||||
cmd exit-code stdout stderr)))
|
||||
`(:type :request :target :emacs :payload (:action :insert-at-end :buffer "*org-agent-chat*" :text ,result-text))))))
|
||||
|
||||
(org-agent:register-actuator :shell #'execute-shell-safely)
|
||||
|
||||
(defskill :skill-shell-actuator
|
||||
:priority 80
|
||||
:trigger #'trigger-skill-shell-actuator
|
||||
:neuro #'neuro-skill-shell-actuator
|
||||
:symbolic (lambda (action context) (declare (ignore context)) action))
|
||||
|
||||
Reference in New Issue
Block a user