branch: externals/llm commit 2ea07f91972610927abe131f520d81530a6394f4 Merge: 2a0651adc2 e07c84b81b Author: Andrew Hyatt <ahy...@gmail.com> Commit: GitHub <nore...@github.com>
Merge pull request #30 from r0man/plz-event-type-symbol Plz event type symbol --- llm-claude.el | 14 +++++++------- llm-openai.el | 4 ++-- plz-event-source.el | 19 +++++++++---------- plz-media-type.el | 34 +++++++++++++++++++++++----------- 4 files changed, 41 insertions(+), 30 deletions(-) diff --git a/llm-claude.el b/llm-claude.el index 3e85c43b9d..30d3912947 100644 --- a/llm-claude.el +++ b/llm-claude.el @@ -119,19 +119,19 @@ STREAM is a boolean indicating whether the response should be streamed." ;; We ignore many types of messages; these might become important if Claude ;; sends a few different alternate contents, but for now they don't do ;; that. - `(("message_start" . ,(lambda (_))) - ("content_block_start" . ,(lambda (_))) - ("ping" . ,(lambda (_))) - ("message_stop" . ,(lambda (_))) - ("content_block_stop" . ,(lambda (_))) - ("content_block_delta" . + `((message_start . ,(lambda (_))) + (content_block_start . ,(lambda (_))) + (ping . ,(lambda (_))) + (message_stop . ,(lambda (_))) + (content_block_stop . ,(lambda (_))) + (content_block_delta . ,(lambda (data) (setq in-flight-message (concat in-flight-message (let* ((json (json-parse-string data :object-type 'alist)) (delta (assoc-default 'delta json)) (type (assoc-default 'type delta))) - (when (equal type "text_delta") + (when (eql type 'text_delta) (assoc-default 'text delta))))) (llm-request-plz-callback-in-buffer buf diff --git a/llm-openai.el b/llm-openai.el index 17eb3ce448..17ecc30d68 100644 --- a/llm-openai.el +++ b/llm-openai.el @@ -303,13 +303,13 @@ RESPONSE can be nil if the response is complete." :headers (llm-openai--headers provider) :data (llm-openai--chat-request (llm-openai-chat-model provider) prompt t) :event-stream-handlers - `(("message" . ,(lambda (data) + `((message . ,(lambda (data) (when (not (equal data "[DONE]")) (when-let ((response (llm-openai--get-partial-chat-response (json-read-from-string data)))) (when (stringp response) (llm-request-plz-callback-in-buffer buf partial-callback response)))))) - ("error" . ,(lambda (data) + (error . ,(lambda (data) (llm-request-plz-callback-in-buffer buf error-callback 'error data)))) :on-error (lambda (_ data) diff --git a/plz-event-source.el b/plz-event-source.el index 0bdb7ebf5e..c6861f7deb 100644 --- a/plz-event-source.el +++ b/plz-event-source.el @@ -33,7 +33,6 @@ (require 'cl-lib) (require 'eieio) -(require 'pcase) (require 'plz) (require 'plz-media-type) (require 'rx) @@ -61,9 +60,9 @@ (type :accessor plz-event-source-event-type :initarg :type - :initform "message" + :initform 'message :documentation "The event type." - :type string)) + :type symbol)) "The server sent event class.") ;; Parser @@ -145,8 +144,8 @@ last-event-id) :origin (buffer-name) :type (if (string-blank-p event-type-buffer) - "message" - event-type-buffer)))) + 'message + (intern event-type-buffer))))) (setf data-buffer "" event-type-buffer "") (setf events (cons event events)) @@ -339,7 +338,7 @@ "Open a connection to the URL of the event SOURCE." (with-slots (buffer errors options ready-state parser) source (with-current-buffer (get-buffer-create buffer) - (let ((event (plz-event-source-event :type "open"))) + (let ((event (plz-event-source-event :type 'open))) (setf ready-state 'connecting) (setf parser (plz-event-source-parser :buffer buffer @@ -351,7 +350,7 @@ (cl-defmethod plz-event-source-close ((source plz-buffer-event-source)) "Close the connection of the event SOURCE." (with-slots (buffer ready-state) source - (let ((event (plz-event-source-event :type "close"))) + (let ((event (plz-event-source-event :type 'close))) (setf ready-state 'closed) (plz-event-source-dispatch-event source event) source))) @@ -414,7 +413,7 @@ (cl-defmethod plz-media-type-else ((_ plz-media-type:text/event-stream) error) "Transform the ERROR into a format suitable for MEDIA-TYPE." (let* ((source plz-event-source--current) - (event (plz-event-source-event :type "error" :data error))) + (event (plz-event-source-event :type 'error :data error))) (plz-event-source-close source) (plz-event-source-dispatch-event source event) error)) @@ -433,11 +432,11 @@ (let ((type (car pair)) (handler (cdr pair))) (cond - ((equal "open" type) + ((equal 'open type) (cons type (lambda (source event) (setf (oref event data) response) (funcall handler source event)))) - ((equal "close" type) + ((equal 'close type) (cons type (lambda (source event) (setf (oref event data) response) (funcall handler source event)))) diff --git a/plz-media-type.el b/plz-media-type.el index e7f13f8a87..f8094c057e 100644 --- a/plz-media-type.el +++ b/plz-media-type.el @@ -76,6 +76,10 @@ (cl-defgeneric plz-media-type-process (media-type process chunk) "Process the CHUNK according to MEDIA-TYPE using PROCESS.") +(cl-defmethod plz-media-type-else ((_ (eql nil)) error) + "Transform the ERROR into a format suitable for MEDIA-TYPE." + error) + (defun plz-media-type-parse (header) "Parse the Content-Type HEADER. @@ -348,19 +352,27 @@ be `hash-table', `alist' (the default) or `plist'." (t . ,(plz-media-type:application/octet-stream))) "Alist from media type to content type.") -(defun plz-media-type--handle-sync-error (media-types error) - "Handle the synchronous ERROR of type `plz-http-error' with MEDIA-TYPES." +(defun plz-media-type--handle-sync-http-error (error media-types) + "Handle the synchronous HTTP ERROR using MEDIA-TYPES." (let* ((msg (cadr error)) (plzerror (caddr error))) (signal (car error) - (let ((response (plz-error-response plzerror))) - (if-let (media-type (plz-media-type--of-response media-types response)) - (list msg (with-temp-buffer - (when-let (body (plz-response-body response)) - (insert body) - (goto-char (point-min))) - (plz-media-type-else media-type plzerror))) - (cdr error)))))) + (cond + ((plz-error-response plzerror) + (let ((response (plz-error-response plzerror))) + (if-let (media-type (plz-media-type--of-response media-types response)) + (list msg (with-temp-buffer + (when-let (body (plz-response-body response)) + (insert body) + (goto-char (point-min))) + (plz-media-type-else media-type plzerror))) + (cdr error)))))))) + +(defun plz-media-type--handle-sync-error (error media-types) + "Handle the synchronous ERROR using MEDIA-TYPES." + (if (eq 'plz-http-error (car error)) + (plz-media-type--handle-sync-http-error error media-types) + (signal (car error) (cdr error)))) (cl-defun plz-media-type-request (method @@ -498,7 +510,7 @@ not. ((processp result) result) (t (user-error "Unexpected response: %s" result)))) - (plz-error (plz-media-type--handle-sync-error media-types error))) + (plz-error (plz-media-type--handle-sync-error error media-types))) (apply #'plz (append (list method url) rest)))) ;;;; Footer