75 lines
3.1 KiB
Org Mode
75 lines
3.1 KiB
Org Mode
#+PROPERTY: header-args:lisp :tangle (expand-file-name "org-skill-shell-actuator.lisp" (expand-file-name "skills/" (or (identity (getenv "INSTALL_DIR")) ".")))
|
|
:PROPERTIES:
|
|
:ID: shell-actuator-skill
|
|
:CREATED: [2026-04-12 Sun]
|
|
:END:
|
|
#+TITLE: SKILL: Shell Actuator (Secure Host Interaction)
|
|
#+STARTUP: content
|
|
#+FILETAGS: :actuator:shell:system:autonomy:
|
|
|
|
* Overview
|
|
The *Shell Actuator* provides a controlled interface for the OpenCortex to execute commands on the host operating system.
|
|
|
|
* Implementation
|
|
|
|
#+begin_src lisp :tangle (expand-file-name "org-skill-shell-actuator.lisp" (expand-file-name "skills/" (or (identity (getenv "INSTALL_DIR")) ".")))
|
|
(in-package :opencortex)
|
|
|
|
(defparameter *allowed-commands* '("ls" "git" "rg" "grep" "date" "echo" "cat" "node" "python3" "sbcl"))
|
|
|
|
(defparameter *shell-metacharacters* '(#\; #\& #\| #\> #\< #\$ #\` #\\ #\!))
|
|
|
|
(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*)))
|
|
|
|
(defun execute-shell-safely (action context)
|
|
(let* ((payload (getf action :PAYLOAD))
|
|
(cmd-string (getf payload :cmd))
|
|
(executable (car (uiop:split-string (string-trim " " cmd-string) :separator '(#\Space)))))
|
|
|
|
(cond
|
|
((not (shell-command-safe-p cmd-string))
|
|
(opencortex:inject-stimulus
|
|
`(:TYPE :EVENT :PAYLOAD (:SENSOR :shell-response :cmd ,cmd-string :stdout "" :stderr "ERROR - Security Violation: Dangerous metacharacters detected." :exit-code 1))
|
|
:stream (getf context :reply-stream)))
|
|
|
|
((not (member executable *allowed-commands* :test #'string=))
|
|
(opencortex: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)))
|
|
|
|
(t
|
|
(multiple-value-bind (stdout stderr exit-code)
|
|
(uiop:run-program cmd-string :output :string :error-output :string :ignore-error-status t)
|
|
(opencortex: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)))))))
|
|
|
|
(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 probabilistic-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)))
|
|
(format nil "SHELL COMMAND RESULT:
|
|
Command: ~a
|
|
Exit Code: ~a
|
|
STDOUT: ~a
|
|
STDERR: ~a" cmd exit-code stdout stderr)))
|
|
|
|
(opencortex:register-actuator :shell #'execute-shell-safely)
|
|
|
|
(defskill :skill-shell-actuator
|
|
:priority 80
|
|
:trigger #'trigger-skill-shell-actuator
|
|
:probabilistic #'probabilistic-skill-shell-actuator
|
|
:deterministic (lambda (action context) (declare (ignore context)) action))
|
|
#+end_src
|