gptel: More flexible callbacks
* gptel.el (gptel--url-get-response, gptel-api-key-from-auth-source): `gptel--url-get-response' accepts a callback argument that can be used to do something besides inserting the response into the current buffer. * gptel-curl.el (gptel-curl--sentinel, gptel-curl-get-response): `gptel-curl--sentinel' now accepts a callback argument that can be used to do something besides inserting the response into the current buffer. These changes are in preparation for more specific functionality, like showing the response as a message, or replacing the prompt with the response etc.
This commit is contained in:
parent
c2ad1c004d
commit
f7ba368c38
2 changed files with 19 additions and 8 deletions
|
@ -60,13 +60,16 @@ PROMPTS is the data to send, TOKEN is a unique identifier."
|
||||||
(nreverse (cons url args))))
|
(nreverse (cons url args))))
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun gptel-curl-get-response (info)
|
(defun gptel-curl-get-response (info &optional callback)
|
||||||
"Retrieve response to prompt in INFO.
|
"Retrieve response to prompt in INFO.
|
||||||
|
|
||||||
INFO is a plist with the following keys:
|
INFO is a plist with the following keys:
|
||||||
- :prompt (the prompt being sent)
|
- :prompt (the prompt being sent)
|
||||||
- :gptel-buffer (the gptel buffer)
|
- :gptel-buffer (the gptel buffer)
|
||||||
- :insert-marker (marker at which to insert the response)."
|
- :insert-marker (marker at which to insert the response).
|
||||||
|
|
||||||
|
Call CALLBACK with the response and INFO afterwards. If omitted
|
||||||
|
the response is inserted into the current buffer after point."
|
||||||
(with-current-buffer (generate-new-buffer "*gptel-curl*")
|
(with-current-buffer (generate-new-buffer "*gptel-curl*")
|
||||||
(let* ((token (md5 (format "%s%s%s%s"
|
(let* ((token (md5 (format "%s%s%s%s"
|
||||||
(random) (emacs-pid) (user-full-name)
|
(random) (emacs-pid) (user-full-name)
|
||||||
|
@ -76,7 +79,9 @@ INFO is a plist with the following keys:
|
||||||
"curl" args)))
|
"curl" args)))
|
||||||
(set-process-query-on-exit-flag process nil)
|
(set-process-query-on-exit-flag process nil)
|
||||||
(setf (alist-get process gptel-curl--process-alist)
|
(setf (alist-get process gptel-curl--process-alist)
|
||||||
(nconc (list :token token) info))
|
(nconc (list :token token
|
||||||
|
:callback (or callback #'gptel--insert-response))
|
||||||
|
info))
|
||||||
(set-process-sentinel process #'gptel-curl--sentinel))))
|
(set-process-sentinel process #'gptel-curl--sentinel))))
|
||||||
|
|
||||||
(defun gptel-curl--sentinel (process status)
|
(defun gptel-curl--sentinel (process status)
|
||||||
|
@ -90,10 +95,11 @@ PROCESS and STATUS are process parameters."
|
||||||
(if-let* (((eq (process-status process) 'exit))
|
(if-let* (((eq (process-status process) 'exit))
|
||||||
(proc-info (alist-get process gptel-curl--process-alist))
|
(proc-info (alist-get process gptel-curl--process-alist))
|
||||||
(proc-token (plist-get proc-info :token))
|
(proc-token (plist-get proc-info :token))
|
||||||
|
(proc-callback (plist-get proc-info :callback))
|
||||||
(response (gptel-curl--parse-response proc-buf proc-token)))
|
(response (gptel-curl--parse-response proc-buf proc-token)))
|
||||||
(gptel--insert-response response proc-info)
|
(funcall proc-callback response proc-info)
|
||||||
;; Failed
|
;; Failed
|
||||||
(gptel--insert-response (list :content nil :status status) proc-info))
|
(funcall proc-callback (list :content nil :status status) proc-info))
|
||||||
(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)))
|
||||||
|
|
||||||
|
|
11
gptel.el
11
gptel.el
|
@ -207,6 +207,7 @@ By default, \"openai.com\" is used as HOST and \"apikey\" as USER."
|
||||||
secret)
|
secret)
|
||||||
(user-error "No `gptel-api-key' found in the auth source")))
|
(user-error "No `gptel-api-key' found in the auth source")))
|
||||||
|
|
||||||
|
;; FIXME Should we utf-8 encode the api-key here?
|
||||||
(defun gptel--api-key ()
|
(defun gptel--api-key ()
|
||||||
"Get api key from `gptel-api-key'."
|
"Get api key from `gptel-api-key'."
|
||||||
(pcase gptel-api-key
|
(pcase gptel-api-key
|
||||||
|
@ -382,13 +383,16 @@ BUFFER is the interaction buffer for ChatGPT."
|
||||||
('org-mode (gptel--convert-markdown->org content))
|
('org-mode (gptel--convert-markdown->org content))
|
||||||
(_ content)))
|
(_ content)))
|
||||||
|
|
||||||
(defun gptel--url-get-response (info)
|
(defun gptel--url-get-response (info &optional callback)
|
||||||
"Fetch response to prompt in INFO from ChatGPT.
|
"Fetch response to prompt in INFO from ChatGPT.
|
||||||
|
|
||||||
INFO is a plist with the following keys:
|
INFO is a plist with the following keys:
|
||||||
- :prompt (the prompt being sent)
|
- :prompt (the prompt being sent)
|
||||||
- :gptel-buffer (the gptel buffer)
|
- :gptel-buffer (the gptel buffer)
|
||||||
- :insert-marker (marker at which to insert the response)."
|
- :insert-marker (marker at which to insert the response).
|
||||||
|
|
||||||
|
Call CALLBACK with the response and INFO afterwards. If omitted
|
||||||
|
the response is inserted into the current buffer after point."
|
||||||
(let* ((inhibit-message t)
|
(let* ((inhibit-message t)
|
||||||
(message-log-max nil)
|
(message-log-max nil)
|
||||||
(url-request-method "POST")
|
(url-request-method "POST")
|
||||||
|
@ -403,7 +407,8 @@ INFO is a plist with the following keys:
|
||||||
(lambda (_)
|
(lambda (_)
|
||||||
(let ((response
|
(let ((response
|
||||||
(gptel--url-parse-response (current-buffer))))
|
(gptel--url-parse-response (current-buffer))))
|
||||||
(gptel--insert-response response info)
|
(funcall (or callback #'gptel--insert-response)
|
||||||
|
response info)
|
||||||
(kill-buffer)))
|
(kill-buffer)))
|
||||||
nil t nil)))
|
nil t nil)))
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue