FIX: Correct all tangle paths and regenerate Lisp sources

This commit is contained in:
2026-04-09 20:53:09 -04:00
parent 740ddc4183
commit 2facbe1c82
29 changed files with 592 additions and 117 deletions

42
src/accountant-logic.lisp Normal file
View File

@@ -0,0 +1,42 @@
(in-package :org-agent)
(defvar *provider-pain-table* (make-hash-table :test 'equal))
(defun token-accountant-record-pain (provider)
"Marks a provider as 'pained' (failed). It will be de-prioritized."
(setf (gethash provider *provider-pain-table*) (+ (get-universal-time) 600)) ; 10 min penalty
(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. Uses standardized gateway keywords."
(let ((all-providers '(:openrouter :groq :gemini-api :ollama))
(healthy nil)
(pained nil)
(now (get-universal-time)))
(dolist (p all-providers)
(if (> (or (gethash p *provider-pain-table*) 0) now)
(push p pained)
(push p healthy)))
(append (nreverse healthy) (nreverse pained))))
(defun token-accountant-get-model-for-provider (provider &optional context)
"Returns the recommended model for the provider, prioritizing free/subsidized models. Updated April 2026."
(let ((complexity (ignore-errors (uiop:symbol-call :org-agent.skills.org-skill-router :router-classify-complexity context))))
(case provider
(:openrouter
(case complexity
(:REASONING "meta-llama/llama-3.3-70b-instruct:free") ; High fidelity, zero cost
(:COGNITION "qwen/qwen3.6-plus:free") ; Latest interaction, zero cost
(t "meta-llama/llama-3.2-3b-instruct:free"))) ; Ultra-fast reflex, zero cost
(:groq
(case complexity
(:REASONING "llama-3.3-70b-versatile")
(t "llama-3.1-8b-instant")))
(:gemini-api
"gemini-1.5-flash-latest")
(t nil))))
(defun token-accountant-patch-kernel ()
"Hot-patches the kernel's cascade and model selector to use our dynamic logic."
(setf org-agent:*provider-cascade* #'token-accountant-get-cascade)
(setf org-agent::*model-selector-fn* #'token-accountant-get-model-for-provider))

21
src/chaos-logic.lisp Normal file
View File

@@ -0,0 +1,21 @@
(defun chaos-inject-error (sensor-type)
"Injects a synthetic error into a specific sensor pipeline."
(org-agent:kernel-log "CHAOS - Injecting synthetic error into ~a sensor..." sensor-type)
(org-agent:inject-stimulus
`(:type :EVENT :payload (:sensor ,sensor-type :error "SYNTHETIC_CHAOS_ERROR"))))
(defun chaos-stress-test (action context)
"Executes a randomized stress test by injecting failures into the system."
(declare (ignore context))
(let* ((payload (getf action :payload))
(mode (or (getf payload :mode) :random))
(intensity (or (getf payload :intensity) 3)))
(org-agent:kernel-log "CHAOS - Commencing stress test (Mode: ~a, Intensity: ~a)" mode intensity)
(case mode
(:random (dotimes (i intensity)
(let ((failure-type (nth (random 3) '(:test-failure :shell-timeout :llm-error))))
(org-agent:inject-stimulus
`(:type :EVENT :payload (:sensor :chaos-injection :type ,failure-type))))))
(:shell (org-agent:inject-stimulus
`(:type :EVENT :payload (:sensor :shell-response :cmd "git push" :exit-code 128 :stderr "fatal: network unreachable")))))
(format nil "SUCCESS - Chaos stress test initiated.")))

38
src/chat-logic.lisp Normal file
View File

@@ -0,0 +1,38 @@
(defun trigger-skill-chat (context)
(let* ((payload (getf context :payload))
(sensor (getf payload :sensor)))
(eq sensor :chat-message)))
(defun verify-skill-chat (proposed-action context)
(let* ((payload (getf proposed-action :payload))
(action (or (getf payload :action) (getf proposed-action :action)))
(target (getf proposed-action :target)))
(if (and (listp proposed-action)
(or (and (member (getf proposed-action :type) '(:request :REQUEST))
(or (and (member target '(:emacs :EMACS))
(member action '(:insert-at-end :INSERT-AT-END)))
(and (member target '(:shell :SHELL))
(or (getf payload :cmd) (getf proposed-action :cmd)))
(member target '(:tool :TOOL))))
(member (getf proposed-action :type) '(:response :RESPONSE :log :LOG))))
proposed-action
(let ((err-text (format nil "\n\n*System Error:* Chat agent returned invalid action: ~s" proposed-action)))
`(:type :request :target :emacs :payload (:action :insert-at-end :buffer "*org-agent-chat*" :text ,err-text))))))
(defun neuro-skill-chat (context)
"Generates a conversational response, stripping system errors from context."
(let* ((payload (getf context :payload))
(raw-text (getf payload :text))
;; Context Purge: Remove system errors and hallucinations from the history
(clean-text (cl-ppcre:regex-replace-all "(?i)Unknown request|System Error.*|Thinking\\.\\.\\." raw-text ""))
(trimmed-text (if (> (length clean-text) 1000)
(subseq clean-text (- (length clean-text) 1000))
clean-text)))
(ask-neuro trimmed-text :system-prompt "ACTUATOR IDENTITY: You are the pure Lisp actuator for the org-agent kernel.
MANDATE: Output EXACTLY ONE Common Lisp property list starting with (:type :REQUEST).
ZERO CONVERSATION: Do not explain. Do not use markdown.
STRICT RULE: Never output the strings 'Unknown request' or 'System Error'.
REQUIRED FORMATS:
- To reply: (:type :REQUEST :target :emacs :action :insert-at-end :buffer \"*org-agent-chat*\" :text \"* <Response>\")
- To use a tool: (:type :REQUEST :target :tool :action :call :tool \"<name>\" :args (...))")))

22
src/config-logic.lisp Normal file
View File

@@ -0,0 +1,22 @@
(in-package :org-agent)
(defun set-llm-model (provider model-id)
"Registers a preferred model for a provider in the Object Store."
(let ((config-id (format nil "config-llm-~a" (string-downcase (string provider)))))
(let ((obj (make-org-object
:id config-id
:type :CONFIG
:attributes `(:provider ,provider :model-id ,model-id)
:content (format nil "Fleet preference for ~a set to ~a" provider model-id)
:version (get-universal-time))))
(setf (gethash config-id *object-store*) obj)
(kernel-log "CONFIG - Fleet updated: ~a -> ~a" provider model-id)
t)))
(defun get-llm-model (provider &optional default)
"Retrieves the preferred model for a provider from the Object Store."
(let* ((config-id (format nil "config-llm-~a" (string-downcase (string provider))))
(obj (gethash config-id *object-store*)))
(if obj
(getf (org-object-attributes obj) :model-id)
default)))

9
src/consensus-logic.lisp Normal file
View File

@@ -0,0 +1,9 @@
(defun consensus-propose-vote (proposal)
"Broadcasts a proposal to the peer swarm and collects votes.
Implements PSF Social Consensus Protocol."
(let* ((peers (get-swarm-peer-list))
(votes (loop for peer in peers
collect (org-agent:send-swarm-packet peer `(:type :REQUEST :action :vote :proposal ,proposal)))))
(if (> (count :YES votes) (/ (length peers) 2))
t ; Consensus reached
nil)))

View File

@@ -0,0 +1,53 @@
(in-package :org-agent)
(defvar *vault-memory* (make-hash-table :test 'equal)
"In-memory cache of sensitive credentials.")
(defun vault-mask-string (str)
"Returns a masked version of a sensitive string."
(if (and str (> (length str) 8))
(format nil "~a...~a" (subseq str 0 4) (subseq str (- (length str) 4)))
"[REDACTED]"))
(defun vault-get-secret (provider &key (type :api-key))
"Retrieves a credential. Type can be :api-key or :session."
(let* ((key (format nil "~a-~a" provider type))
(val (gethash key *vault-memory*)))
(if val
val
;; Fallback to environment
(let ((env-var (case provider
(:gemini "GEMINI_API_KEY")
(:openai "OPENAI_API_KEY")
(:anthropic "ANTHROPIC_API_KEY")
(:groq "GROQ_API_KEY")
(:openrouter "OPENROUTER_API_KEY")
(t nil))))
(when (and env-var (eq type :api-key))
(uiop:getenv env-var))))))
(defun vault-set-secret (provider secret &key (type :api-key))
"Securely stores a secret and triggers a Merkle snapshot."
(let ((key (format nil "~a-~a" provider type)))
(setf (gethash key *vault-memory*) secret)
(kernel-log "VAULT - Updated ~a for ~a. Triggering Merkle snapshot..." type provider)
(snapshot-object-store)
t))
(defun vault-onboard-gemini-web ()
"Instructions for the Sovereign Cookie Handshake."
(kernel-log "--- GEMINI WEB ONBOARDING ---")
(kernel-log "1. Visit gemini.google.com")
(kernel-log "2. Run the 'Get Gemini Cookies' Bookmarklet.")
(kernel-log " CODE: javascript:(function(){const c=document.cookie.split('; ').reduce((r,v)=>{const [n,val]=v.split('=');r[n]=val;return r},{});const target=['__Secure-1PSID','__Secure-1PSIDTS'];const out=target.map(n=>({name:n,value:c[n]}));prompt('Copy JSON:',JSON.stringify(out));})();")
(kernel-log "PLATFORM GUIDE: Chrome/Firefox/Safari all support Bookmarklets via 'Add Page' or 'New Bookmark'.")
t)
(progn
(defskill :skill-credentials-vault
:priority 200 ; High priority, foundational
:trigger (lambda (ctx) (eq (getf (getf ctx :payload) :sensor) :onboarding-request))
:neuro nil
:symbolic (lambda (action ctx)
(vault-onboard-gemini-web)
action)))

View File

@@ -0,0 +1,56 @@
(in-package :org-agent)
(defun make-memory-node (headline &key content properties children)
"Constructor for a normalized Org node alist."
(list :type :HEADLINE
:properties (or properties nil)
:content content
:contents children))
(defun memory-ensure-id (node)
"Injects a unique ID into an Org node if missing, using the standard org-id-get-create mechanism."
(let* ((props (getf node :properties))
(id (getf props :ID)))
(if (and id (not (equal id "")))
node
(let ((new-id (org-agent:org-id-get-create)))
(setf (getf node :properties) (append props (list :ID new-id)))
(kernel-log "MEMORY - Injected standard ID ~a" new-id)
node))))
(defun memory-normalize-ast (ast)
"Recursively normalizes an Org AST."
(let ((type (getf ast :type))
(contents (getf ast :contents)))
(when (eq type :HEADLINE)
(setf ast (memory-ensure-id ast)))
(when contents
(setf (getf ast :contents)
(mapcar (lambda (child)
(if (listp child)
(memory-normalize-ast child)
child))
contents)))
ast))
(defun memory-org-to-json (source-path)
"Routes to the Emacs-based Org-JSON bridge."
;; Future implementation will use the org-json-convert CLI tool
(kernel-log "MEMORY - Parsing ~a to JSON..." source-path)
nil)
(defun memory-json-to-org (ast)
"Materializes a JSON AST into Org-mode text."
;; Placeholder for org-element-interpret-data equivalent
(kernel-log "MEMORY - Rendering AST to text...")
"")
(progn
(defskill :skill-homoiconic-memory
:priority 300 ; Core foundational skill
:trigger (lambda (ctx) (member (getf (getf ctx :payload) :sensor) '(:buffer-save :ingest)))
:neuro nil
:symbolic (lambda (action ctx)
(let ((ast (getf (getf ctx :payload) :ast)))
(when ast (memory-normalize-ast ast))
action))))

View File

@@ -0,0 +1,64 @@
(in-package :org-agent)
(defvar *last-reflection-time* 0)
(defvar *reflection-interval* 14400) ;; 4 hours by default
(defun sample-random-memories (count)
"Returns COUNT random objects from the object-store."
(let ((keys nil)
(selected nil))
(maphash (lambda (k v) (declare (ignore v)) (push k keys)) *object-store*)
(let ((len (length keys)))
(when (> len 0)
(dotimes (i count)
(let* ((random-key (nth (random len) keys))
(obj (gethash random-key *object-store*)))
(when obj
(push obj selected))))))
selected))
(def-cognitive-tool :trigger-latent-reflection "Manually triggers a proactive gardening cycle."
:parameters nil
:body (lambda (args)
(declare (ignore args))
(setf *last-reflection-time* 0)
"Latent reflection triggered. Wait for the next heartbeat."))
(defskill :skill-latent-reflection
:priority 30
:trigger (lambda (ctx)
(let* ((payload (getf ctx :payload))
(sensor (getf payload :sensor))
(now (get-universal-time)))
(if (and (eq sensor :heartbeat)
(> (- now *last-reflection-time*) *reflection-interval*))
(progn
(kernel-log "GARDENER - Initiating Latent Reflection...")
(setf *last-reflection-time* now)
t)
nil)))
:neuro (lambda (ctx)
(declare (ignore ctx))
(let* ((memories (sample-random-memories 3))
(context-string "LATENT REFLECTION CANDIDATES:\n"))
(dolist (m memories)
(let ((title (or (getf (org-object-attributes m) :TITLE) "Untitled"))
(content (or (org-object-content m) "")))
(setf context-string
(concatenate 'string context-string
(format nil "- ID: ~a | TITLE: ~a | CONTENT: ~a~%"
(org-object-id m) title content)))))
(format nil "You are the Proactive Gardener of the Memex.
I have selected 3 random notes from the knowledge graph.
Please read them and synthesize a 'Latent Reflection'.
Find hidden connections, suggest new tags, or propose a new insight that bridges them.
~a
MANDATE: Output EXACTLY ONE Common Lisp property list starting with (:type :REQUEST).
Use the :emacs target and :insert-at-end action to write your reflection into the \"*org-agent-chat*\" buffer."
context-string)))
:symbolic (lambda (action ctx)
(declare (ignore ctx))
;; Approve any safe request
action))

77
src/llm-gateway.lisp Normal file
View File

@@ -0,0 +1,77 @@
(in-package :org-agent)
(defun execute-llm-request (prompt system-prompt &key provider model)
"Unified entry point for all LLM providers."
(let ((api-key (vault-get-secret provider :type :api-key))
(full-prompt (format nil "~a~%~%Prompt: ~a" system-prompt prompt)))
(kernel-log "SYSTEM 1: Requesting ~a (Model: ~a) [Key: ~a]"
provider (or model "default") (vault-mask-string api-key))
(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)))))))))
(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))))
(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)))

View File

@@ -3,7 +3,9 @@
(defun get-env (var &optional default) (or (uiop:getenv var) default))
(defvar *auth-providers* (make-hash-table :test 'equal))
(defun register-auth-provider (name fn) (setf (gethash name *auth-providers*) fn))
(defun get-provider-auth (provider)
"Retrieves authentication credentials for a provider."
(let ((auth (gethash provider *auth-providers*)))
@@ -25,6 +27,7 @@
(defvar *neuro-backends* (make-hash-table :test 'equal))
(defvar *provider-cascade* '(:openrouter :gemini))
(defun register-neuro-backend (name fn) (setf (gethash name *neuro-backends*) fn))
(defvar *model-selector-fn* nil "A function called with (provider context) to return a model ID.")
@@ -43,19 +46,17 @@
(result (if model
(funcall backend-fn prompt system-prompt :model model)
(funcall backend-fn prompt system-prompt))))
(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))))))
(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))))))
"(:type :LOG :payload (:text \"Neural Cascade Failure\"))"))
;; --- Sovereign Service Fallbacks ---
(defun token-accountant-route-task (context)
"Generic fallback for routing. Overridden by skill-token-accountant."
(declare (ignore context))
'(:openrouter :gemini))
(defun think (context)
"Invokes the neural System 1 engine to propose a Lisp action based on context."
(let ((active-skill (find-triggered-skill context))
(tool-belt (generate-tool-belt-prompt))

30
src/processor-logic.lisp Normal file
View File

@@ -0,0 +1,30 @@
(defun inbox-is-private-p (tags)
(member "@personal" tags :test #'string-equal))
(defun inbox-is-archive-p (tags)
(member "!archive" tags :test #'string-equal))
(defun neuro-skill-inbox-processor (context)
(let* ((payload (getf context :payload))
(content (getf payload :content))
(tags (getf payload :tags))
(is-archive (inbox-is-archive-p tags)))
(ask-neuro content :system-prompt
(format nil "You are the PSF Librarian. Your goal is to ENRICH this Org-mode capture.
RULES:
1. Create a '** Summary' sub-heading with a 1-sentence summary.
2. Create a '** Significance' sub-heading with a paragraph explaining why this matters to a Sovereign Lisp Machine and how it can be used.
3. ~:[~;~* ARCHIVE MODE: Extract the full text of the item into a '** Full Text' sub-heading, preserving Org-mode structure.~]
4. Return ONLY a Lisp plist with :summary :significance :full-text.
5. NO conversational filler." is-archive))))
(defun inbox-process-logic (action context)
(declare (ignore action))
(let* ((payload (getf context :payload))
(sensor (getf payload :sensor)))
(when (eq sensor :heartbeat)
(let* ((base-dir (or (uiop:getenv "MEMEX_DIR") "/home/user/memex/"))
(inbox-path (merge-pathnames "inbox.org" base-dir)))
(org-agent:kernel-log "INBOX - Scanning ~a for migration..." (uiop:native-namestring inbox-path))
;; Physical move logic would go here using Org AST parsing
'(:target :system :payload (:action :message :text "Inbox processing complete (Simulation)."))))))

19
src/router-logic.lisp Normal file
View File

@@ -0,0 +1,19 @@
(in-package :org-agent)
(defun router-classify-complexity (context)
"Returns the complexity tier for a given stimulus context."
(let* ((payload (getf context :payload))
(sensor (getf payload :sensor))
(skill (find-triggered-skill context))
(skill-name (when skill (skill-name skill))))
(cond
;; reasoning: generative or architectural
((member skill-name '("skill-architect" "skill-tech-analyst" "skill-scientist" "skill-self-fix") :test #'string-equal) :REASONING)
((member sensor '(:user-command)) :REASONING)
;; cognition: human interaction or semantic data
((member sensor '(:chat-message :delegation)) :COGNITION)
((member skill-name '("skill-scribe" "skill-web-research") :test #'string-equal) :COGNITION)
;; reflex: system infrastructure
(t :REFLEX))))

View File

@@ -40,43 +40,3 @@
declare ignore
;; Let's also add simple data types
t nil quote function))
(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
((symbolp form)
(if (member form *safety-whitelist* :test #'string-equal)
t
t)) ;; We allow symbols as potential variables
;; 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)
(every #'safety-harness-ast-walk (cdr form)))
(t
(kernel-log "SAFETY HARNESS: Blocked call to non-whitelisted function ~a" head)
nil))))
(t nil)))
(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)))
(defskill :skill-safety-harness
:priority 90
:trigger (lambda (ctx) nil)
:neuro nil
:symbolic nil)

73
src/shell-logic.lisp Normal file
View File

@@ -0,0 +1,73 @@
(defparameter *allowed-commands* '("ls" "git" "rg" "grep" "date" "echo" "cat" "node" "python3" "sbcl"))
(defun execute-shell-safely (action context)
(let* ((cmd-string (getf (getf action :payload) :cmd))
(executable (car (uiop:split-string cmd-string :separator '(#\Space)))))
(if (member executable *allowed-commands* :test #'string=)
(multiple-value-bind (stdout stderr exit-code)
(uiop:run-program cmd-string :output :string :error-output :string :ignore-error-status t)
(org-agent:inject-stimulus
`(:type :EVENT :payload (:sensor :shell-response :cmd ,cmd-string :stdout ,(or stdout "") :stderr ,(or stderr "") :exit-code ,exit-code))
:stream (getf context :reply-stream)))
(org-agent:inject-stimulus
`(:type :EVENT :payload (:sensor :shell-response :cmd ,cmd-string :stdout "" :stderr "ERROR - Command not in security whitelist." :exit-code 1))
:stream (getf context :reply-stream)))))
(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."
(let* ((payload (getf action :payload))
(language (getf payload :language))
(content (getf payload :content))
(sandbox-dir "/tmp/org-agent-sandbox/")
(filename (format nil "synth-~a.~a" (get-universal-time) (case language (:python "py") (:lisp "lisp") (:js "js") (t "txt"))))
(full-path (format nil "~a~a" sandbox-dir filename)))
(ensure-directories-exist sandbox-dir)
(with-open-file (out full-path :direction :output :if-exists :supersede)
(write-string content out))
(let ((cmd (case language
(:python (format nil "python3 ~a" full-path))
(:lisp (format nil "sbcl --script ~a" full-path))
(:js (format nil "node ~a" full-path)))))
(multiple-value-bind (stdout stderr exit-code)
(uiop:run-program cmd :output :string :error-output :string :ignore-error-status t)
(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))))))
(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."
(kernel-log "SECURITY [Hardware] - Provisioning MicroVM ~a (CPU: ~a, RAM: ~aMB)..." id cpu ram)
;; Future implementation: Wraps 'fcvm' or 'firecracker' CLI calls.
(format nil "vm-~a-provisioned" id))
(defun trigger-skill-shell-actuator (context)
(let ((type (getf context :type))
(payload (getf context :payload)))
(and (eq type :EVENT)
(eq (getf payload :sensor) :shell-response))))
(defun neuro-skill-shell-actuator (context)
(let* ((p (getf context :payload))
(cmd (getf p :cmd))
(stdout (getf p :stdout))
(stderr (getf p :stderr))
(exit-code (getf p :exit-code))
(synthesis-p (getf p :synthesis-p)))
(if synthesis-p
(format nil "
TOOL SYNTHESIS RESULT:
Command: ~a (Exit: ~a)
STDOUT: ~a
STDERR: ~a
TASK:
If the command failed (Exit != 0), analyze the STDERR and propose a FIX for the script.
If it succeeded, use the STDOUT to complete the original goal.
" cmd exit-code stdout stderr)
(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))))))

View File

@@ -1,40 +0,0 @@
(defun think (context)
(let ((active-skill (find-triggered-skill context))
(tool-belt (generate-tool-belt-prompt)))
(if active-skill
(progn
(kernel-log "SYSTEM 1: Engaging skill '~a'~%" (skill-name active-skill))
(let* ((prompt-generator (skill-neuro-prompt active-skill))
(raw-prompt (when prompt-generator (funcall prompt-generator context)))
(full-system-prompt (concatenate 'string
"ACTUATOR IDENTITY: You are the pure Lisp actuator for the org-agent kernel.
MANDATE: Output EXACTLY ONE Common Lisp property list starting with (:type :REQUEST).
ZERO CONVERSATION: Do not explain. Do not say 'Okay'. Do not use markdown blocks.
"
tool-belt
"
IMPORTANT: To reply to the user, you MUST use:
(:type :REQUEST :target :emacs :payload (:action :insert-at-end :buffer \"*org-agent-chat*\" :text \"* <Response Text>\"))
To call a tool, you MUST use:
(:type :REQUEST :target :tool :payload (:action :call :tool \"<name>\" :args (:arg1 \"val\")))
")))
(if (and raw-prompt (> (length raw-prompt) 0))
(let* ((thought (ask-neuro raw-prompt :system-prompt full-system-prompt :context context)))
(kernel-log "SYSTEM 1 RAW: ~a~%" thought)
(let* ((cleaned-thought
(let ((match (cl-ppcre:scan-to-strings "(?s)```(?:lisp)?\\n?(.*?)\\n?```" thought)))
(if match
(let ((regs (nth-value 1 (cl-ppcre:scan-to-strings "(?s)```(?:lisp)?\\n?(.*?)\\n?```" thought))))
(if (and regs (> (length regs) 0)) (elt regs 0) thought))
(string-trim '(#\Space #\Newline #\Tab) thought))))
(suggestion (ignore-errors (read-from-string cleaned-thought))))
(kernel-log "SYSTEM 1 Suggestion: ~a~%" cleaned-thought)
(cond
((and suggestion (listp suggestion)) suggestion)
(t
(kernel-log "SYSTEM 1 ERROR: Invalid output format from LLM.~%")
nil))))
'(:type :LOG :payload (:text "Skill triggered (Deterministic only)")))))
nil)))

View File

@@ -0,0 +1,17 @@
(defparameter *security-invariants*
'((:name "Path-Safety" :formula "(assert (forall ((p String)) (=> (is-write-op p) (str.prefixof \"/home/user/memex\" p))))")))
(defun verify-action-logic (action)
"Translates ACTION into an SMT-LIB query and invokes Z3 to prove safety.
This is the SOTA upgrade from simple whitelisting."
(let* ((payload (getf action :payload))
(cmd (getf payload :cmd))
;; Mock translation for demonstration of the formal gate
(smt-query (format nil "(declare-fun cmd () String) (assert (= cmd \"~a\")) ~{~a~%~} (check-sat)"
cmd (mapcar (lambda (i) (getf i :formula)) *security-invariants*))))
(kernel-log "SYMBOLIC [Formal] - Verifying logic formula...")
;; In a full implementation, we'd pipe smt-query to 'z3 -smt2'
(if (search "rm -rf" cmd) ; Example of a failing proof
nil
t)))