Some checks failed
Deploy (Gitea) / deploy (push) Failing after 3s
New file: org/system-embedding-gateway.org / lisp/system-embedding-gateway.lisp. - Pluggable backends via *embedding-backend* hook and EMBEDDING_PROVIDER env var - :hashing (default) — FNV-1a hashing trick, zero dependencies - :ollama — POST /api/embeddings to local Ollama (nomic-embed-text) - *embedding-queue* tracks pending objects; embed-all-pending drains queue with store-wide scan as fallback - embed-queue-object called after ingest-ast to mark objects for embedding - Deleted old stub system-embeddings.org (hashing-only, no provider switching) - Exported embedding symbols from defpackage Also: - Added (in-package :passepartout) to system-model-router.org (was missing, caused CL-USER::DEFSKILL error on daemon start) - Added system-embedding-gateway to skill-loader exclusion list - Updated ROADMAP
91 lines
3.8 KiB
Common Lisp
91 lines
3.8 KiB
Common Lisp
(in-package :passepartout)
|
|
|
|
(defvar *model-cascade-code* nil
|
|
"Cascade for :code tasks: ((:ollama . \"model\") ...)")
|
|
|
|
(defvar *model-cascade-plan* nil
|
|
"Cascade for :plan tasks.")
|
|
|
|
(defvar *model-cascade-chat* nil
|
|
"Cascade for :chat tasks.")
|
|
|
|
(defvar *model-cascade-background* nil
|
|
"Cascade for background tasks (heartbeat, delegation).")
|
|
|
|
(defvar *local-backends* '(:ollama :llama-cpp)
|
|
"Backend keywords considered local (privacy-safe).")
|
|
|
|
(defun model-classify-complexity (text)
|
|
"Classify TEXT into :code, :plan, or :chat."
|
|
(let ((lower (string-downcase text)))
|
|
(cond
|
|
((or (search "defun" lower) (search "defmacro" lower)
|
|
(search "write" lower) (search "refactor" lower)
|
|
(search "fix " lower) (search "implement" lower)
|
|
(search "code" lower)
|
|
(search "#+begin_src" lower))
|
|
:code)
|
|
((or (search "plan" lower) (search "roadmap" lower)
|
|
(search "strategy" lower) (search "design" lower)
|
|
(search "architecture" lower))
|
|
:plan)
|
|
(t :chat))))
|
|
|
|
(defun model-cascade-find (cascade backend)
|
|
"Find first (PROVIDER . MODEL) in CASCADE matching BACKEND."
|
|
(assoc backend cascade
|
|
:test (lambda (a b) (string-equal (string a) (string b)))))
|
|
|
|
(defun model-select (backend context)
|
|
"Select model for BACKEND given CONTEXT signal.
|
|
Returns model name or :skip."
|
|
(let* ((payload (getf context :payload))
|
|
(text (or (getf payload :text) ""))
|
|
(sensor (getf payload :sensor))
|
|
(has-personal (and (boundp '*dispatcher-privacy-tags*)
|
|
(some (lambda (tag) (search tag text))
|
|
(symbol-value '*dispatcher-privacy-tags*))))
|
|
(is-local (member backend *local-backends*)))
|
|
;; Privacy: skip cloud backends for personal content
|
|
(when (and has-personal (not is-local))
|
|
(log-message "MODEL-ROUTER: Skipping ~a (personal content)" backend)
|
|
(return-from model-select :skip))
|
|
;; Quadrant: background tasks use background cascade
|
|
(if (member sensor '(:heartbeat :delegation :tool-output :loop-error))
|
|
(let ((entry (car (or *model-cascade-background*
|
|
'((:ollama . "phi-2"))))))
|
|
(cdr entry))
|
|
;; Foreground: classify complexity, use slot cascade
|
|
(let* ((slot (model-classify-complexity text))
|
|
(cascade (case slot
|
|
(:code *model-cascade-code*)
|
|
(:plan *model-cascade-plan*)
|
|
(t *model-cascade-chat*)))
|
|
(entry (model-cascade-find
|
|
(or cascade '((:ollama . "qwen2.5:14b"))) backend)))
|
|
(if entry (cdr entry) :skip)))))
|
|
|
|
(defun model-router-init ()
|
|
"Read env vars and wire model-select into *model-selector*."
|
|
(flet ((parse-cascade (str)
|
|
(when (and str (> (length str) 0))
|
|
(let ((*read-eval* nil))
|
|
(read-from-string str)))))
|
|
(setf *model-cascade-code* (parse-cascade (uiop:getenv "MODEL_CASCADE_CODE"))
|
|
*model-cascade-plan* (parse-cascade (uiop:getenv "MODEL_CASCADE_PLAN"))
|
|
*model-cascade-chat* (parse-cascade (uiop:getenv "MODEL_CASCADE_CHAT"))
|
|
*model-cascade-background* (parse-cascade (uiop:getenv "MODEL_CASCADE_BACKGROUND"))
|
|
*local-backends* (let ((env (uiop:getenv "LOCAL_BACKENDS")))
|
|
(if env
|
|
(mapcar (lambda (s) (intern (string-upcase (string-trim " " s)) :keyword))
|
|
(uiop:split-string env :separator '(#\,)))
|
|
'(:ollama :llama-cpp)))))
|
|
(setf *model-selector* #'model-select)
|
|
(log-message "MODEL-ROUTER: Initialized, selector=~a" *model-selector*))
|
|
|
|
(defskill :passepartout-model-router
|
|
:priority 250
|
|
:trigger (lambda (ctx) (declare (ignore ctx)) nil))
|
|
|
|
(model-router-init)
|