Skip to content

Commit e61180e

Browse files
committed
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.
1 parent f0953d5 commit e61180e

File tree

1 file changed

+92
-0
lines changed

1 file changed

+92
-0
lines changed

gptel.el

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,98 @@ By default, \"openai.com\" is used as HOST and \"apikey\" as USER."
280280
(propertize msg 'face face))
281281
(force-mode-line-update)))
282282

283+
(cl-defun gptel-request
284+
(&optional prompt &key callback
285+
(buffer (current-buffer))
286+
position context
287+
(system gptel--system-message))
288+
"Request a response from ChatGPT for PROMPT.
289+
290+
If PROMPT is
291+
- a string, it is used to create a full prompt suitable for
292+
sending to ChatGPT.
293+
- nil but region is active, the region contents are used.
294+
- nil, the current buffer's contents up to (point) are used.
295+
Previous responses from ChatGPT are identified as responses.
296+
- A list of plists, it is used as is.
297+
298+
Keyword arguments:
299+
300+
CALLBACK, if supplied, is a function of two arguments, called
301+
with the RESPONSE (a string) and the CONTEXT (a plist):
302+
303+
(callback RESPONSE INFO)
304+
305+
RESPONSE is nil if there was no response or an error.
306+
307+
The INFO plist has (at least) the following keys:
308+
:prompt - The full prompt that was sent with the request
309+
:position - marker at the point the request was sent.
310+
:buffer - The buffer current when the request was sent.
311+
:status - Short string describing the result of the request
312+
313+
Example of a callback that messages the user with the response
314+
and info:
315+
316+
(lambda (response info)
317+
(if response
318+
(let ((posn (marker-position (plist-get info :position)))
319+
(buf (buffer-name (plist-get info :buffer))))
320+
(message \"Response for request from %S at %d: %s\"
321+
buf posn response))
322+
(message \"gptel-request failed with message: %s\"
323+
(plist-get info :status))))
324+
325+
Or, for just the response:
326+
327+
(lambda (response _)
328+
;; Do something with response
329+
(message (rot13-string response)))
330+
331+
If CALLBACK is omitted, the response is inserted at the point the
332+
request was sent.
333+
334+
BUFFER is the buffer the request belongs to. If omitted the
335+
current buffer is recorded.
336+
337+
POSITION is a buffer position (integer or marker). If omitted,
338+
the value of (point) or (region-end) is recorded, depending on
339+
whether the region is active.
340+
341+
CONTEXT is any additional data needed for the callback to run. It
342+
is included in the INFO argument to the callback.
343+
344+
SYSTEM is the system message (chat directive) sent to ChatGPT. If
345+
omitted, the value of `gptel--system-message' for the current
346+
buffer is used.
347+
348+
Model parameters can be let-bound around calls to this function."
349+
(let* ((gptel-stream nil)
350+
(start-marker
351+
(cond
352+
((null position)
353+
(if (use-region-p)
354+
(set-marker (make-marker) (region-end))
355+
(point-marker)))
356+
((markerp position) position)
357+
((integerp position)
358+
(set-marker (make-marker) position buffer))))
359+
(full-prompt
360+
(cond
361+
((null prompt) (gptel--create-prompt start-marker))
362+
((stringp prompt)
363+
`((:role "system" :content ,system)
364+
(:role "user" :content ,prompt)))
365+
((consp prompt) prompt)))
366+
(info (list :prompt full-prompt
367+
:buffer buffer
368+
:position start-marker)))
369+
(when context (plist-put info :context context))
370+
(funcall
371+
(if gptel-use-curl
372+
#'gptel-curl-get-response #'gptel--url-get-response)
373+
info callback)))
374+
283375
;; TODO: Handle read-only buffers. Should we spawn a new buffer automatically?
284376
;; TODO: Handle multiple requests(#15). (Only one request from one buffer at a time?)
285377
;; TODO: Since we capture a marker for the insertion location, `gptel-buffer' no

0 commit comments

Comments
 (0)