emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] externals/llm 29d7c3f6b8 55/71: Update media type and event sourc


From: ELPA Syncer
Subject: [elpa] externals/llm 29d7c3f6b8 55/71: Update media type and event source packages
Date: Fri, 17 May 2024 00:58:48 -0400 (EDT)

branch: externals/llm
commit 29d7c3f6b87cc7ddafbc8e047abfe1517e4f56c1
Author: Roman Scherer <roman@burningswell.com>
Commit: Roman Scherer <roman@burningswell.com>

    Update media type and event source packages
    
    This PR updates the media type and event source packages. There
    
    - I moved the decoding from the process filter to the media type. Not
    everything should be decoded, e.g. binary data, and some media types
    have a default encoding (text/event-stream is always UTF-8 for
    example).
    
    - The plz-media-type:text/event-stream got renamed to
    plz-event-source:text/event-stream to reflect the package in which it
    is defined.
    
    - Fixed some lint issues in the event source package
---
 llm-request-plz.el  |  2 +-
 plz-event-source.el | 40 ++++++++++++++++--------------
 plz-media-type.el   | 71 ++++++++++++++++++++++++++++++++++++-----------------
 3 files changed, 71 insertions(+), 42 deletions(-)

diff --git a/llm-request-plz.el b/llm-request-plz.el
index 82755484f1..ea733f8a31 100644
--- a/llm-request-plz.el
+++ b/llm-request-plz.el
@@ -250,7 +250,7 @@ This is required.
                          :timeout timeout
                          :media-type
                          (cons 'text/event-stream
-                                (plz-media-type:text/event-stream
+                                (plz-event-source:text/event-stream
                                  ;; Convert so that each event handler gets 
the body, not the
                                  ;; `plz-response' itself.
                                  :events (mapcar
diff --git a/plz-event-source.el b/plz-event-source.el
index 4f2cad0d23..e0a4b83a9b 100644
--- a/plz-event-source.el
+++ b/plz-event-source.el
@@ -312,7 +312,7 @@
 
 ;; Buffer event source
 
-(defclass plz-buffer-event-source (plz-event-source)
+(defclass plz-event-source-buffer (plz-event-source)
   ((buffer
     :initarg :buffer
     :documentation "The event source buffer."
@@ -323,7 +323,7 @@
     :type (or null plz-event-source-parser)))
   "A server sent event source using curl for HTTP.")
 
-(cl-defmethod plz-event-source-insert ((source plz-buffer-event-source) data)
+(cl-defmethod plz-event-source-insert ((source plz-event-source-buffer) data)
   "Insert DATA into the event SOURCE buffer, parse and dispatch events."
   (with-slots (parser) source
     (plz-event-source-parser-insert parser data)
@@ -338,7 +338,7 @@
     (re-search-forward plz-http-end-of-headers-regexp nil t)
     (point)))
 
-(cl-defmethod plz-event-source-open ((source plz-buffer-event-source))
+(cl-defmethod plz-event-source-open ((source plz-event-source-buffer))
   "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)
@@ -351,7 +351,7 @@
         (plz-event-source-dispatch-event source event)
         source))))
 
-(cl-defmethod plz-event-source-close ((source plz-buffer-event-source))
+(cl-defmethod plz-event-source-close ((source plz-event-source-buffer))
   "Close the connection of the event SOURCE."
   (with-slots (buffer ready-state) source
     (let ((event (plz-event-source-event :type 'close)))
@@ -359,7 +359,7 @@
       (plz-event-source-dispatch-event source event)
       source)))
 
-(defclass plz-http-event-source (plz-event-source)
+(defclass plz-event-source-http (plz-event-source)
   ((process
     :initarg :process
     :documentation "The process of the event source."
@@ -373,10 +373,10 @@
 (defun plz-event-source--media-types (source)
   "Return the media types of the event SOURCE."
   (with-slots (handlers) source
-    (let ((media-type (plz-media-type:text/event-stream :events handlers)))
+    (let ((media-type (plz-event-source:text/event-stream :events handlers)))
       (cons (cons 'text/event-stream media-type) plz-media-types))))
 
-(cl-defmethod plz-event-source-open ((source plz-http-event-source))
+(cl-defmethod plz-event-source-open ((source plz-event-source-http))
   "Open a connection to the URL of the event SOURCE."
   (with-slots (errors options process ready-state response url) source
     (setf ready-state 'connecting)
@@ -395,7 +395,7 @@
                                (setf ready-state 'closed))))
     source))
 
-(cl-defmethod plz-event-source-close ((source plz-http-event-source))
+(cl-defmethod plz-event-source-close ((source plz-event-source-http))
   "Close the connection of the event SOURCE."
   (with-slots (process ready-state) source
     (delete-process process)
@@ -403,27 +403,28 @@
 
 ;; Content Type: text/event-stream
 
-(defclass plz-media-type:text/event-stream 
(plz-media-type:application/octet-stream)
-  ((type :initform 'text)
+(defclass plz-event-source:text/event-stream 
(plz-media-type:application/octet-stream)
+  ((coding-system :initform 'utf-8)
+   (type :initform 'text)
    (subtype :initform 'event-stream)
    (events :documentation "Association list from event type to handler."
            :initarg :events
            :initform nil
            :type list))
-  "A media type class that handles the processing of HTTP responses
+  "Media type class that handles the processing of HTTP responses
 in the server sent events format.  The HTTP response is processed
 in a streaming way.  The :events slot of the class can be set to
 an association list from event type symbol to a handler function.
 Whenever a new event is parsed and emitted the handler for the
 corresponding event type will be called with two arguments, an
 instance of the underlying event source class and an event.  The
-body slot of the plz-response struct passed to the THEN and ELSE
-callbacks will always be set to nil.")
+body slot of the plz-response structure passed to the THEN and
+ELSE callbacks will always be set to nil.")
 
 (defvar-local plz-event-source--current nil
   "The event source of the current buffer.")
 
-(cl-defmethod plz-media-type-else ((_ plz-media-type:text/event-stream) error)
+(cl-defmethod plz-media-type-else ((_ plz-event-source: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)))
@@ -431,14 +432,14 @@ callbacks will always be set to nil.")
     (plz-event-source-dispatch-event source event)
     error))
 
-(cl-defmethod plz-media-type-process ((media-type 
plz-media-type:text/event-stream) process chunk)
+(cl-defmethod plz-media-type-process ((media-type 
plz-event-source:text/event-stream) process chunk)
   "Process the CHUNK according to MEDIA-TYPE using PROCESS."
   (unless plz-event-source--current
     (let* ((response (make-plz-response
                       :status (plz-response-status chunk)
                       :headers (plz-response-headers chunk)))
            (source (plz-event-source-open
-                    (plz-buffer-event-source
+                    (plz-event-source-buffer
                      :buffer (buffer-name (process-buffer process))
                      :handlers (seq-map
                                 (lambda (pair)
@@ -456,10 +457,11 @@ callbacks will always be set to nil.")
                                      (t pair))))
                                 (oref media-type events))))))
       (setq-local plz-event-source--current source)))
-  (plz-event-source-insert plz-event-source--current (plz-response-body chunk))
-  (set-marker (process-mark process) (point)))
+  (let ((body (plz-media-type-decode-string media-type (plz-response-body 
chunk))))
+    (plz-event-source-insert plz-event-source--current body)
+    (set-marker (process-mark process) (point))))
 
-(cl-defmethod plz-media-type-then ((media-type 
plz-media-type:text/event-stream) response)
+(cl-defmethod plz-media-type-then ((media-type 
plz-event-source:text/event-stream) response)
   "Transform the RESPONSE into a format suitable for MEDIA-TYPE."
   (plz-event-source-close plz-event-source--current)
   (cl-call-next-method media-type response)
diff --git a/plz-media-type.el b/plz-media-type.el
index 4216cba7b9..b350a8f641 100644
--- a/plz-media-type.el
+++ b/plz-media-type.el
@@ -52,23 +52,32 @@
   cause)
 
 (defclass plz-media-type ()
-  ((type
+  ((coding-system
+    :documentation "The coding system to use for the media type."
+    :initarg :coding-system
+    :initform nil
+    :type (or null symbol))
+   (type
     :documentation "The media type."
     :initarg :type
     :type symbol)
    (subtype
     :documentation "The media subtype."
     :initarg :subtype
-    :subtype symbol)
+    :type symbol)
    (parameters
     :documentation "The parameters of the media type."
     :initarg :parameters
     :initform nil
-    :subtype list))
+    :type list))
   "A class that hold information about the type, subtype and
 parameters of a media type.  It is meant to be sub-classed to
 handle the processing of different media types and supports the
-processing of streaming and non-streaming HTTP responses.")
+processing of streaming and non-streaming HTTP responses.  The
+response will be decoded with the coding-system of the charset
+parameter in the content type header, or the coding-sytem of the
+media type.  If the coding system of a media type is nil, the
+response will not be decoded.")
 
 (defun plz-media-type-charset (media-type)
   "Return the character set of the MEDIA-TYPE."
@@ -77,7 +86,9 @@ processing of streaming and non-streaming HTTP responses.")
 
 (defun plz-media-type-coding-system (media-type)
   "Return the coding system of the MEDIA-TYPE."
-  (coding-system-from-name (or (plz-media-type-charset media-type) "UTF-8")))
+  (if-let (charset (plz-media-type-charset media-type))
+      (coding-system-from-name charset)
+    (oref media-type coding-system)))
 
 (defun plz-media-type-name (media-type)
   "Return the name of the MEDIA-TYPE as a string."
@@ -134,10 +145,17 @@ an alist of parameters."
       (alist-get t media-types)
       (plz-media-type:application/octet-stream)))
 
-(defun plz-media-type--of-response (media-types response)
+(defun plz-media-type-of-response (media-types response)
   "Lookup the content type of RESPONSE in MEDIA-TYPES."
   (let ((media-type (plz-media-type--content-type response)))
-    (clone (plz-media--type-find media-types media-type))))
+    (clone (plz-media--type-find media-types media-type)
+           :parameters (oref media-type parameters))))
+
+(defun plz-media-type-decode-string (media-type string)
+  "Decode the STRING according to the MEDIA-TYPE."
+  (if-let (coding-system (plz-media-type-coding-system media-type))
+      (decode-coding-string string coding-system)
+    string))
 
 (defvar-local plz-media-type--current nil
   "The media type of the process buffer.")
@@ -161,10 +179,8 @@ CHUNK is a part of the HTTP body."
     (with-current-buffer (process-buffer process)
       (let ((moving (= (point) (process-mark process))))
         (if-let (media-type plz-media-type--current)
-            (let ((coding-system (plz-media-type-coding-system media-type))
-                  (response plz-media-type--response))
-              (setf (plz-response-body response)
-                    (decode-coding-string chunk coding-system))
+            (let ((response plz-media-type--response))
+              (setf (plz-response-body response) chunk)
               (plz-media-type-process media-type process response))
           (progn
             (save-excursion
@@ -176,8 +192,7 @@ CHUNK is a part of the HTTP body."
               (let ((body-start (point)))
                 (goto-char (point-min))
                 (let* ((response (prog1 (plz--response) (widen)))
-                       (media-type (plz-media-type--of-response media-types 
response))
-                       (coding-system (plz-media-type-coding-system 
media-type)))
+                       (media-type (plz-media-type-of-response media-types 
response)))
                   (setq-local plz-media-type--current media-type)
                   (setq-local plz-media-type--response
                               (make-plz-response
@@ -186,8 +201,7 @@ CHUNK is a part of the HTTP body."
                                :version (plz-response-version response)))
                   (when-let (body (plz-response-body response))
                     (when (> (length body) 0)
-                      (setf (plz-response-body response)
-                            (decode-coding-string body coding-system))
+                      (setf (plz-response-body response) body)
                       (delete-region body-start (point-max))
                       (set-marker (process-mark process) (point))
                       (plz-media-type-process media-type process 
response))))))))
@@ -224,13 +238,14 @@ body.  It is used as the default media type processor.")
   (ignore media-type)
   (save-excursion
     (goto-char (process-mark process))
-    (insert (plz-response-body chunk))
+    (insert (plz-media-type-decode-string media-type (plz-response-body 
chunk)))
     (set-marker (process-mark process) (point))))
 
 ;; Content Type: application/json
 
 (defclass plz-media-type:application/json 
(plz-media-type:application/octet-stream)
-  ((subtype :initform 'json)
+  ((coding-system :initform 'utf-8)
+   (subtype :initform 'json)
    (array-type
     :documentation "Specifies which Lisp type is used to represent arrays.  It 
can be
 `array' (the default) or `list'."
@@ -347,7 +362,6 @@ will always be set to nil.")
   ((media-type plz-media-type:application/json-array) response)
   "Transform the RESPONSE into a format suitable for MEDIA-TYPE."
   (ignore media-type)
-  (plz-media-type:application/json-array--parse-stream media-type)
   (setf (plz-response-body response) nil)
   response)
 
@@ -401,14 +415,15 @@ will always be set to nil.")
 (cl-defmethod plz-media-type-then
   ((media-type plz-media-type:application/x-ndjson) response)
   "Transform the RESPONSE into a format suitable for MEDIA-TYPE."
-  (plz-media-type:application/x-ndjson--parse-stream media-type)
+  (ignore media-type)
   (setf (plz-response-body response) nil)
   response)
 
 ;; Content Type: application/xml
 
 (defclass plz-media-type:application/xml 
(plz-media-type:application/octet-stream)
-  ((subtype :initform 'xml))
+  ((coding-system :initform 'utf-8)
+   (subtype :initform 'xml))
   "Media type class that handles the processing of HTTP responses
 in the XML format.  The HTTP response is processed in a
 non-streaming way.  After the response has been received, the
@@ -428,7 +443,7 @@ function.")
 
 (defclass plz-media-type:text/html (plz-media-type:application/xml)
   ((type :initform 'text)
-   (subtype :initform 'xml))
+   (subtype :initform 'html))
   "Media type class that handles the processing of HTTP responses
 in the HTML format.  The HTTP response is processed in a
 non-streaming way.  After the response has been received, the
@@ -436,11 +451,23 @@ body of the plz-response structure is set to the result 
of parsing
 the HTTP response body with the `libxml-parse-html-region'
 function.")
 
+(defclass plz-media-type:text/xml (plz-media-type:application/xml)
+  ((coding-system :initform 'us-ascii)
+   (type :initform 'text)
+   (subtype :initform 'xml))
+  "Media type class that handles the processing of HTTP responses
+in the HTML format.  The HTTP response is processed in a
+non-streaming way.  After the response has been received, the
+body of the plz-response structure is set to the result of
+parsing the HTTP response body with the
+`libxml-parse-html-region' function.")
+
 (defvar plz-media-types
   `((application/json . ,(plz-media-type:application/json))
     (application/octet-stream . ,(plz-media-type:application/octet-stream))
     (application/xml . ,(plz-media-type:application/xml))
     (text/html . ,(plz-media-type:text/html))
+    (text/xml . ,(plz-media-type:text/xml))
     (t . ,(plz-media-type:application/octet-stream)))
   "Association list from media type to content type.")
 
@@ -452,7 +479,7 @@ function.")
             (cond
              ((plz-error-response plzerror)
               (let ((response (plz-error-response plzerror)))
-                (if-let (media-type (plz-media-type--of-response media-types 
response))
+                (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)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]