gptel-curl: Handle empty responses correctly

gptel-curl.el (gptel-curl--stream-cleanup): The LLM response can
be empty with HTTP status 200, for example when the API responds
with an error description instead.  Handle this case gracefully.
When `gptel-mode` is enabled, also inform the user that the
response was empty.  Fix #234.

gptel.el (gptel-post-response-functions): Documentation.  Explain
the arguments passed to each hook function in this hook when the
response fails or is empty.
This commit is contained in:
Karthik Chikmagalur 2024-03-07 10:23:59 -08:00
parent 0d6264f268
commit a32f4effe5
2 changed files with 16 additions and 15 deletions

View file

@ -199,20 +199,17 @@ PROCESS and _STATUS are process parameters."
(tracking-marker (plist-get info :tracking-marker)) (tracking-marker (plist-get info :tracking-marker))
(start-marker (plist-get info :position)) (start-marker (plist-get info :position))
(http-status (plist-get info :http-status)) (http-status (plist-get info :http-status))
(http-msg (plist-get info :status)) (http-msg (plist-get info :status)))
response-beg response-end)
(when gptel-log-level (gptel-curl--log-response proc-buf info)) ;logging (when gptel-log-level (gptel-curl--log-response proc-buf info)) ;logging
(if (equal http-status "200") (if (equal http-status "200") ;Finish handling response
(progn
;; Finish handling response
(with-current-buffer (marker-buffer start-marker)
(setq response-beg (marker-position start-marker)
response-end (marker-position tracking-marker))
(pulse-momentary-highlight-region response-beg tracking-marker)
(when gptel-mode (save-excursion (goto-char tracking-marker)
(insert "\n\n" (gptel-prompt-prefix-string)))))
(with-current-buffer gptel-buffer (with-current-buffer gptel-buffer
(when gptel-mode (gptel--update-status " Ready" 'success)))) (if (not tracking-marker) ;Empty response
(when gptel-mode (gptel--update-status " Empty response" 'success))
(pulse-momentary-highlight-region start-marker tracking-marker)
(when gptel-mode
(save-excursion (goto-char tracking-marker)
(insert "\n\n" (gptel-prompt-prefix-string)))
(gptel--update-status " Ready" 'success))))
;; Or Capture error message ;; Or Capture error message
(with-current-buffer proc-buf (with-current-buffer proc-buf
(goto-char (point-max)) (goto-char (point-max))
@ -240,7 +237,9 @@ PROCESS and _STATUS are process parameters."
(gptel--update-status (gptel--update-status
(format " Response Error: %s" http-msg) 'error)))) (format " Response Error: %s" http-msg) 'error))))
(with-current-buffer gptel-buffer (with-current-buffer gptel-buffer
(run-hook-with-args 'gptel-post-response-functions response-beg response-end))) (run-hook-with-args 'gptel-post-response-functions
(marker-position start-marker)
(marker-position (or tracking-marker start-marker)))))
(setf (alist-get process gptel-curl--process-alist nil 'remove) nil) (setf (alist-get process gptel-curl--process-alist nil 'remove) nil)
(kill-buffer proc-buf))) (kill-buffer proc-buf)))

View file

@ -250,7 +250,9 @@ to the LLM, and after the full response has been inserted. Each
function is called with two arguments: the response beginning and function is called with two arguments: the response beginning and
end positions. end positions.
Note: this hook runs even if the request fails." Note: this hook runs even if the request fails. In this case the
response beginning and end positions are both the cursor position
at the time of the request."
:group 'gptel :group 'gptel
:type 'hook) :type 'hook)