gptel: Add gptel-request
* gptel.el (gptel-request): `gptel-request' is a lower level API than `gptel-send' for defining custom commands that use ChatGPT's responses.
This commit is contained in:
parent
f0953d569e
commit
18222818dc
1 changed files with 92 additions and 0 deletions
92
gptel.el
92
gptel.el
|
@ -280,6 +280,98 @@ By default, \"openai.com\" is used as HOST and \"apikey\" as USER."
|
||||||
(propertize msg 'face face))
|
(propertize msg 'face face))
|
||||||
(force-mode-line-update)))
|
(force-mode-line-update)))
|
||||||
|
|
||||||
|
(cl-defun gptel-request
|
||||||
|
(&optional prompt &key callback
|
||||||
|
(buffer (current-buffer))
|
||||||
|
position context
|
||||||
|
(system gptel--system-message))
|
||||||
|
"Request a response from ChatGPT for PROMPT.
|
||||||
|
|
||||||
|
If PROMPT is
|
||||||
|
- a string, it is used to create a full prompt suitable for
|
||||||
|
sending to ChatGPT.
|
||||||
|
- nil but region is active, the region contents are used.
|
||||||
|
- nil, the current buffer's contents up to (point) are used.
|
||||||
|
Previous responses from ChatGPT are identified as responses.
|
||||||
|
- A list of plists, it is used as is.
|
||||||
|
|
||||||
|
Keyword arguments:
|
||||||
|
|
||||||
|
CALLBACK, if supplied, is a function of two arguments, called
|
||||||
|
with the RESPONSE (a string) and INFO (a plist):
|
||||||
|
|
||||||
|
(callback RESPONSE INFO)
|
||||||
|
|
||||||
|
RESPONSE is nil if there was no response or an error.
|
||||||
|
|
||||||
|
The INFO plist has (at least) the following keys:
|
||||||
|
:prompt - The full prompt that was sent with the request
|
||||||
|
:position - marker at the point the request was sent.
|
||||||
|
:buffer - The buffer current when the request was sent.
|
||||||
|
:status - Short string describing the result of the request
|
||||||
|
|
||||||
|
Example of a callback that messages the user with the response
|
||||||
|
and info:
|
||||||
|
|
||||||
|
(lambda (response info)
|
||||||
|
(if response
|
||||||
|
(let ((posn (marker-position (plist-get info :position)))
|
||||||
|
(buf (buffer-name (plist-get info :buffer))))
|
||||||
|
(message \"Response for request from %S at %d: %s\"
|
||||||
|
buf posn response))
|
||||||
|
(message \"gptel-request failed with message: %s\"
|
||||||
|
(plist-get info :status))))
|
||||||
|
|
||||||
|
Or, for just the response:
|
||||||
|
|
||||||
|
(lambda (response _)
|
||||||
|
;; Do something with response
|
||||||
|
(message (rot13-string response)))
|
||||||
|
|
||||||
|
If CALLBACK is omitted, the response is inserted at the point the
|
||||||
|
request was sent.
|
||||||
|
|
||||||
|
BUFFER is the buffer the request belongs to. If omitted the
|
||||||
|
current buffer is recorded.
|
||||||
|
|
||||||
|
POSITION is a buffer position (integer or marker). If omitted,
|
||||||
|
the value of (point) or (region-end) is recorded, depending on
|
||||||
|
whether the region is active.
|
||||||
|
|
||||||
|
CONTEXT is any additional data needed for the callback to run. It
|
||||||
|
is included in the INFO argument to the callback.
|
||||||
|
|
||||||
|
SYSTEM is the system message (chat directive) sent to ChatGPT. If
|
||||||
|
omitted, the value of `gptel--system-message' for the current
|
||||||
|
buffer is used.
|
||||||
|
|
||||||
|
Model parameters can be let-bound around calls to this function."
|
||||||
|
(let* ((gptel-stream nil)
|
||||||
|
(start-marker
|
||||||
|
(cond
|
||||||
|
((null position)
|
||||||
|
(if (use-region-p)
|
||||||
|
(set-marker (make-marker) (region-end))
|
||||||
|
(point-marker)))
|
||||||
|
((markerp position) position)
|
||||||
|
((integerp position)
|
||||||
|
(set-marker (make-marker) position buffer))))
|
||||||
|
(full-prompt
|
||||||
|
(cond
|
||||||
|
((null prompt) (gptel--create-prompt start-marker))
|
||||||
|
((stringp prompt)
|
||||||
|
`((:role "system" :content ,system)
|
||||||
|
(:role "user" :content ,prompt)))
|
||||||
|
((consp prompt) prompt)))
|
||||||
|
(info (list :prompt full-prompt
|
||||||
|
:buffer buffer
|
||||||
|
:position start-marker)))
|
||||||
|
(when context (plist-put info :context context))
|
||||||
|
(funcall
|
||||||
|
(if gptel-use-curl
|
||||||
|
#'gptel-curl-get-response #'gptel--url-get-response)
|
||||||
|
info callback)))
|
||||||
|
|
||||||
;; TODO: Handle read-only buffers. Should we spawn a new buffer automatically?
|
;; TODO: Handle read-only buffers. Should we spawn a new buffer automatically?
|
||||||
;; TODO: Handle multiple requests(#15). (Only one request from one buffer at a time?)
|
;; TODO: Handle multiple requests(#15). (Only one request from one buffer at a time?)
|
||||||
;; TODO: Since we capture a marker for the insertion location, `gptel-buffer' no
|
;; TODO: Since we capture a marker for the insertion location, `gptel-buffer' no
|
||||||
|
|
Loading…
Add table
Reference in a new issue