diff --git a/lisp/system-model-provider.lisp b/lisp/system-model-provider.lisp index 75beaa4..6d13c30 100644 --- a/lisp/system-model-provider.lisp +++ b/lisp/system-model-provider.lisp @@ -54,29 +54,28 @@ (handler-case (let* ((result nil) (lock (bt:make-lock "llm-lock")) - (done nil) + (cvar (bt:make-condition-variable)) (thread (bt:make-thread (lambda () - (handler-case - (let* ((response (dex:post url :headers headers :content body - :connect-timeout (min 10 timeout) - :read-timeout (max 10 (- timeout 5)))) - (json (cl-json:decode-json-from-string response)) - (choices (cdr (assoc :choices json))) - (first-choice (car choices)) - (message (cdr (assoc :message first-choice))) - (content (cdr (assoc :content message)))) - (setf result (if content - (list :status :success :content content) - (list :status :error :message (format nil "~a: No content" provider))))) - (error (c) - (setf result (list :status :error :message (format nil "~a Error: ~a" provider c))))) - (bt:with-lock-held (lock) (setf done t))) + (unwind-protect + (handler-case + (let* ((response (dex:post url :headers headers :content body + :connect-timeout (min 10 timeout) + :read-timeout (max 10 (- timeout 5)))) + (json (cl-json:decode-json-from-string response)) + (choices (cdr (assoc :choices json))) + (first-choice (car choices)) + (message (cdr (assoc :message first-choice))) + (content (cdr (assoc :content message)))) + (setf result (list :status :success :content content))) + (error (c) + (setf result (list :status :error :message (format nil "~a Error: ~a" provider c))))) + (bt:with-lock-held (lock) + (bt:condition-notify cvar)))) :name (format nil "llm-~a" provider)))) - (loop for waited from 0 below timeout - when (bt:with-lock-held (lock) done) - do (return result) - do (sleep 0.5)) + (bt:with-lock-held (lock) + (unless result + (bt:condition-wait cvar lock :timeout timeout))) (or result (list :status :error :message (format nil "~a: Request timed out after ~d seconds" provider timeout)))) (error (c) diff --git a/org/system-model-provider.org b/org/system-model-provider.org index 36a654f..8c03146 100644 --- a/org/system-model-provider.org +++ b/org/system-model-provider.org @@ -82,29 +82,28 @@ Providers register themselves at boot. No API key? That provider doesn't registe (handler-case (let* ((result nil) (lock (bt:make-lock "llm-lock")) - (done nil) + (cvar (bt:make-condition-variable)) (thread (bt:make-thread (lambda () - (handler-case - (let* ((response (dex:post url :headers headers :content body - :connect-timeout (min 10 timeout) - :read-timeout (max 10 (- timeout 5)))) - (json (cl-json:decode-json-from-string response)) - (choices (cdr (assoc :choices json))) - (first-choice (car choices)) - (message (cdr (assoc :message first-choice))) - (content (cdr (assoc :content message)))) - (setf result (if content - (list :status :success :content content) - (list :status :error :message (format nil "~a: No content" provider))))) - (error (c) - (setf result (list :status :error :message (format nil "~a Error: ~a" provider c))))) - (bt:with-lock-held (lock) (setf done t))) + (unwind-protect + (handler-case + (let* ((response (dex:post url :headers headers :content body + :connect-timeout (min 10 timeout) + :read-timeout (max 10 (- timeout 5)))) + (json (cl-json:decode-json-from-string response)) + (choices (cdr (assoc :choices json))) + (first-choice (car choices)) + (message (cdr (assoc :message first-choice))) + (content (cdr (assoc :content message)))) + (setf result (list :status :success :content content))) + (error (c) + (setf result (list :status :error :message (format nil "~a Error: ~a" provider c))))) + (bt:with-lock-held (lock) + (bt:condition-notify cvar)))) :name (format nil "llm-~a" provider)))) - (loop for waited from 0 below timeout - when (bt:with-lock-held (lock) done) - do (return result) - do (sleep 0.5)) + (bt:with-lock-held (lock) + (unless result + (bt:condition-wait cvar lock :timeout timeout))) (or result (list :status :error :message (format nil "~a: Request timed out after ~d seconds" provider timeout)))) (error (c)