* gptel-curl.el (gptel-curl--stream-cleanup): `gptel-post-response-hook' should
run in the buffer that was current when the request was sent. This was not the
case for the curl method (with response streaming). Fixed.
* gptel.el (gptel--insert-response):
* gptel-transient.el (gptel--suffix-send):
* gptel-curl.el (gptel-curl--stream-filter, gptel-curl--stream-insert-response,
gptel-curl--stream-cleanup):
Handle read-only gptel buffers by redirecting the output to a new buffer (that
pops up automatically). To track this,
- the `:position' argument of the INFO plist, which is a marker, is moved to the
new output buffer.
- the `:buffer' argument of the INFO plist is unmodified, it always points to
the buffer that the request originated from.
* gptel-curl.el (gptel-curl-get-response): Set buffer-local model parameters in
the correct (i.e. gptel) buffer, not in Curl's process buffer. This fixes#43.
* gptel.el (gptel--insert-response, gptel-request):
- Add an in-place key to gptel-request. When true, the default
callbacks will not delimit the API responses with newlines.
- Add a strea option to gptel-request. Only works with the default
filter/stream-insert callback, so it's marked as for internal use
for now.
* gptel-curl.el (gptel-curl--stream-insert-response): Ditto.
* gptel.el (gptel--url-parse-response, gptel--url-get-response,
gptel--insert-response, gptel-send):
- Use shorter keys for passing the info plist,
- record errors in the info plist,
- separate user messaging from the callback and more.
- Make the API more functional (i.e. less imperative)
This is in preparation for adding `gptel-request', an API for
defining custom commands.
Note: The streaming filter and callback are mostly unchanged.
Streaming is not planned to be accessible via `gptel-request'.
* gptel-curl.el (gptel-curl--parse-response, gptel-curl--sentinel,
gptel-curl--stream-filter, gptel-curl--stream-insert-response,
gptel-curl--stream-cleanup, gptel-curl-get-response): Ditto.
* gptel.el (gptel--url-parse-response, gptel--insert-response):
Use the same error codes/descriptions across url-retrieve/Curl,
with and without streaming responses.
* gptel-curl.el (gptel-curl--parse-response,
gptel-curl--stream-filter, gptel-curl--stream-cleanup): Ditto.
* gptel-curl.el (gptel-curl--stream-filter,
gptel-curl--stream-cleanup): When streaming responses, move the
error handling from the Curl process filter to the cleanup
sentinel. This simplifies the filter code a fair bit.
* gptel.el (gptel--url-get-response, gptel--insert-response,
gptel-send): Rename the :insert-marker keyword in the async info
plist to :start-marker.
* gptel-curl.el (gptel--insert-response-stream,
gptel-curl--cleanup-stream, gptel-curl-get-response): Ditto.
* gptel.el (gptel--convert-playback-markdown->org): New converter
for markdown->org that works on text chunks while maintaining the
parse state until the text stream is finished.
* gptel-curl.el (gptel--insert-response-stream,
gptel-curl-get-response): When using `gptel-playback' and
requesting ChatGPT's responses in org-mode, run the above
converter on the received response. This works by storing the
converter and associated state as a closure in the async info
plist that is supplied along with the response, and running it
repeatedly on each chunk of text in the response stream before it
is inserted into the buffer.
FIXME: Note that `gptel-response-filter-functions' is currently
ignored if using `gptel-stream'.
* gptel.el (gptel--request-data): Request a streaming message if
`gptel-stream' is non-nil.
* gptel-curl.el (gptel-curl-get-response,
gptel-curl--cleanup-stream, gptel-curl--filter): Add a process
filter and sentinel for Curl to stream ChatGPT's response into
Emacs in real-time.
* 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.
* gptel.el (gptel--url-parse-response): Produce better error
messages when using `url-retrieve'. This includes JSON parsing
failures and insufficient quota messages.
* gptel-curl.el (gptel-curl--parse-response): Produce better error
messages when using curl. This includes JSON parsing failures
and insufficient quota messages.
* gptel.el (gptel-send, gptel--insert-response,
gptel--url-get-response): Remove aio dependency, turn aio-defuns
into regular functions. This requires splitting `gptel-send' into
"before response" and "after response" functions, but the ability
to debug the code fully is worth the inconvenience. The new "after
response" function is `gptel--insert-response'.
* gptel-curl.el (gptel-curl--sentinel, gptel-curl-get-response):
Turn aio-defuns into regular functions.
gptel.el (gptel--debug, gptel--url-parse-response): Add a debug
flag that shows the http response. Fix json parsing error.
gptel-curl.el (gptel-curl--sentinel): Ditto.
gptel.el (gptel--url-get-response): When `gptel-send' is called
directly, the API key is assumed to exist. Ensure that it is read.
gptel-curl.el (gptel-curl--get-args): Ditto.
gptel-curl.el (gptel-curl--process-alist, gptel-curl--get-args,
gptel--curl-sentinel, gptel-curl--parse-response): Rename internal
functions and variables to use the `gptel-curl--` prefix instead of
`gptel--curl-`.
gptel.el (gptel--system-message, gptel--system-message-alist,
gptel--model, gptel--temperature, gptel--max-tokens,
gptel--request-data): Add new buffer-local variables to hold API
parameters. Generating the full request data plist is now done in a
separate function, `gptel--request-data'.
gptel-curl.el (gptel-curl-get-response): Rename from `gptel--curl-get-response'
and autoload it to ease its use in `gptel-send'. Remove Version header
identifying gptel-curl as a separate package and make it require `gptel' instead.
Conditionally solves #2.
gptel.el (gptel-use-curl, gptel-parse-response, gptel--playback,
gptel-send, gptel-playback): New user options `gptel-playback',
`gptel-use-curl`. The former controls whether the response is played
back in chunks, which is done by the function `gptel--playback'. The
response returned by `gptel-get-response' and `gptel--curl-get-response'
is now a plist with the content and status.
gptel-curl.el (gptel--curl-get-args, gptel--curl-get-response,
gptel--curl-sentinel): Add support for curl when available. Set it to
the default. `url-retrieve' is full of fangs that multibyte you.