Commit graph

205 commits

Author SHA1 Message Date
Karthik Chikmagalur
f7ba368c38 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.
2023-03-31 19:37:25 -07:00
algal
c2ad1c004d Decode response body as utf-8 and then parse as json
This changes response parsing so that the response body is decoded as
UTF-8 and then parsed as JSON, rather than the other way around.

This fixes the handling of responses that contain Unicode characters
which are encoded with multiple bytes in UTF-8, such as emojis.
2023-03-31 18:04:44 -07:00
algal
a500c76a68 Encode a lambda-provided API key as utf-8
If the user provides the OpenAPI key via a function, as is the case by
default if the user puts credentials in an auth-sources resource like
.authinfo or .authinfo.gpg, then it is necessary to encode the
function's returned value into utf-8 before passing it onward to build
the HTTP request. This commit ensures that happen.

Why is this necessary, given that the API key contains only
alphanumeric characters and therefore should be byte-for-byte the same
in utf-8 as in us-acii? I don't know. It may because emacs's
url-http.el library concats many strings together, and they all need
to be identically encoded before they can be combined correctly.

Whatever the reason, this fix works and allows you to send prompts
which include Unicode characters that require multibyte encodings in UTF-8
2023-03-31 18:04:44 -07:00
Karthik Chikmagalur
1c07a94e18 README: Update manual install instructions 2023-03-28 12:24:08 -07:00
Rida Ayed
1ab8a57183 add installation instructions 2023-03-28 12:19:56 -07:00
Karthik Chikmagalur
1828dd3fa4 gptel: Set "waiting" state after sending the prompt
* gptel.el (gptel-send): Set the "Waiting..." state after sending
the http request -- this is less misleading if there's an error in
the http request functions (`gptel--url-get-response' or
`gptel-curl-get-response').
2023-03-24 18:03:40 -07:00
Karthik Chikmagalur
9b3db255e8 gptel: Turn API parameters into defcustoms
* gptel.el (gptel--request-data, gptel--system-message-alist,
gptel--model, gptel--temperature, gptel--max-tokens): Rename API
parameters and turn them into customizable variables. They are
still buffer-local.

Rename:
`gptel--system-message-alist' to `gptel-directives'
`gptel--max-tokens' to `gptel-max-tokens'
`gptel--model' to `gptel-model'
`gptel--temperature' to `gptel-temperature'

* gptel-transient.el (gptel-system-prompt,
gptel--infix-max-tokens, gptel--infix-model,
gptel--infix-temperature): Accommodating changes when setting the
renamed parameters.
2023-03-24 17:51:00 -07:00
Karthik Chikmagalur
f843614f5b gptel: Set gptel-api-key if reading from minibuffer
* gptel.el (gptel): Set `gptel-api-key' if reading it from the minibuffer (by
calling M-x gptel).
2023-03-24 17:51:00 -07:00
Karthik Chikmagalur
552939b2f6 gptel: Fix free-variable error
* gptel.el (gptel--url-parse-response): Fix free-variable error.
2023-03-24 17:36:19 -07:00
Karthik Chikmagalur
5ebaf361f1 gptel: Handle the prompt prefix string automatically
* gptel.el (gptel-prompt-prefix-alist, gptel--playback, gptel,
gptel--insert-response, gptel-prompt-string): The prompt prefix
string is chosen automatically from the new variable
`gptel-prompt-prefix-alist', which maps major modes to the prefix
string to insert.
2023-03-24 16:46:22 -07:00
Akira Komamura
cd22ea836c Add autoload for gptel-send 2023-03-24 14:39:07 -07:00
Karthik Chikmagalur
048eaf9b64 README: Update description of chat parameters 2023-03-23 14:39:17 -07:00
Karthik Chikmagalur
2b2dbe2664 gptel: Fix parsing error in url-retrieve buffer
* gptel.el (gptel--url-parse-response): Fix parsing error.
2023-03-23 14:34:26 -07:00
Schroedi
23caab41cf Add gpt-4 model 2023-03-23 14:27:33 -07:00
Karthik Chikmagalur
42d53b25e5 gptel: Handle insufficient quota and other errors
* 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.
2023-03-22 19:43:02 -07:00
Karthik Chikmagalur
4f3ca23454 gptel: Update commentary and README 2023-03-19 19:58:19 -07:00
Karthik Chikmagalur
f0eba0cf4f README: Update README for MELPA 2023-03-19 17:50:51 -07:00
Karthik Chikmagalur
9f8a984729 gptel: Change how api-key is read
* gptel.el (gptel): If the function `gptel--api-key' fails to find the API key
from `gptel-api-key', prompt the user directly.
2023-03-18 12:59:25 -07:00
Daniel Mendler
6f951ed690 Add gptel-api-key-from-auth-source (Fix #13) 2023-03-18 12:35:30 -07:00
Karthik Chikmagalur
87d9090b7a gptel-curl: Fix process sentinel
* gptel-curl.el (gptel-curl--sentinel): Use `process-status' instead of trying
to match on the string passed to he process sentinel as the status.
2023-03-18 00:51:49 -07:00
Karthik Chikmagalur
051501c892 README: Change installation instructions (no aio) 2023-03-18 00:04:16 -07:00
Karthik Chikmagalur
040baad910 gptel: Remove aio dependency
* 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.
2023-03-17 23:51:26 -07:00
Karthik Chikmagalur
8a6ef565f0 gptel-transient: Remove unused lexical vars 2023-03-17 23:44:17 -07:00
Karthik Chikmagalur
30161850ad gptel-transient: Allow setting num past messages to 0
gptel-transient.el (gptel--infix-num-messages-to-send): Allow
setting the number of past messages to send to 0 for no-context
responses.
2023-03-14 02:09:53 -07:00
Karthik Chikmagalur
1ada9c9214 gptel: Handle insertion with region-active correctly
gptel.el (gptel-send, gptel--url-parse-response): Handle insertion
better when region is active.  Decode utf-8 encoded response when
using url-retrieve (instead of curl).
2023-03-14 02:09:53 -07:00
Karthik Chikmagalur
c8f87f5554 Update README with transient menu details 2023-03-14 02:09:53 -07:00
Karthik Chikmagalur
0d26b34526 gptel: Add a debug flag
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.
2023-03-12 15:42:16 -07:00
Karthik Chikmagalur
dfca03a266 LICENSE: Add GPLv3 license 2023-03-12 14:51:54 -07:00
Karthik Chikmagalur
3d0df72bd3 gptel-transient: linting for MELPA 2023-03-12 14:51:07 -07:00
Karthik Chikmagalur
cd6d90b24d gptel-transient: Improve "send in existing/new session" option
gptel-transient.el (gptel-send-menu, gptel--suffix-send-existing,
gptel--suffix-send-new, gptel--infix-model): Make menu keybindings
more uniform and improve descriptions. Suffixes to send queries in
existing/new sessions will now automatically send them instead of
just yanking the text into these sessions.
2023-03-11 18:40:06 -08:00
Karthik Chikmagalur
9da22155de gptel-transient: Fix autoloads for gptel-send-menu 2023-03-11 02:09:01 -08:00
Karthik Chikmagalur
a673f54a3e gptel, gptel-curl: Handle missing API key
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.
2023-03-10 23:00:41 -08:00
Karthik Chikmagalur
dd5833eef3 gptel: Improve gptel-mode setup
gptel.el (gptel--old-header-line, gptel-mode,
gptel--transform-response): Make `gptel-mode' set up the header-line
with status, and restore the old header line when it's turned off.
Improve documentation and linting in other places. Add todos.
2023-03-10 22:52:40 -08:00
Karthik Chikmagalur
a3109a4b68 gptel: Insert response below point, not at point-max
gptel.el (gptel--update-header-line, gptel-send, gptel--playback,
gptel--create-prompt): Add helper function to update the header-line,
and only call when `gptel-mode' is on.  Use markers to track where the
response should be inserted, and insert it after (point) by default.
2023-03-10 22:27:31 -08:00
Karthik Chikmagalur
9f8fc0e519 gptel-transient: Commands to act on region
gptel.el (gptel): When calling `gptel' with a selected region, insert it
into a new session.

gptel-transient.el (gptel--suffix-send-existing,
gptel--suffix-send-new): Transient suffixes available when a region is
selected.  These send the text as a prompt in a existing or new gptel
session.
2023-03-10 06:14:46 -08:00
Karthik Chikmagalur
39376aa3f4 gptel-transient: Add transient menus for setting parameters
gptel-transient (gptel-send-menu): Add new transient-prefix
`gptel-send-menu' for setting API options for the buffer
and (optionally) sending queries. Various infix options are supported.

2023-03-09: Some transient menus are generated dynamically, which
requires a more recent version of transient than the latest tagged
release. As a result, the dynamic generation code is commented out for
now.
2023-03-10 06:13:19 -08:00
Karthik Chikmagalur
8fca5bc762 gptel: Add org-mode support and update README
gptel.el (gptel-response-filter-functions, gptel-send,
gptel--create-prompt, gptel--transform-response, gptel--convert-org,
gptel--convert-markdown->org): Add support for org-mode by transforming
the response manually.  (Note: Asking ChatGPT to format its results in
org-mode markup produces inconsistent results.)

Additionally, the abnormal hook `gptel-resposne-filter-functions' is
added for arbitrary transformations of the response.  Its implementation
seems needlessly complex, and in the future we should change it to
use `run-hook-wrapped' with a local accumulator.
2023-03-10 05:13:29 -08:00
Karthik Chikmagalur
b212c24c4a gptel: tweak prompt, rename url functions
gptel.el (gptel--system-message-alist, gptel--url-get-response,
gptel--url-parse-response): Tweak default programming prompt.  Rename
`gptel--get-response' to the more specific `gptel--url-parse-response'.
Likewise `gptel--parse-response' -> `gptel--url-parse-response'.
2023-03-10 03:55:43 -08:00
Karthik Chikmagalur
de70a066d7 gptel: Pulse inserted text 2023-03-09 22:01:28 -08:00
Karthik Chikmagalur
f98293f004 gptel: Check header-line-format before updating
gptel.el: A header-line is not required for using `gptel-send'. gptel
can now be used from any buffer by selecting a region.
2023-03-09 14:14:06 -08:00
Karthik Chikmagalur
3f7c81012b gptel: Bump version and prepare for transient menus
gptel.el (gptel-send): Prepare to include transient dispatch menus from
`gptel-transient.el'.  This is WIP and not part of the project yet.
2023-03-08 19:25:14 -08:00
Karthik Chikmagalur
4e35e998a8 gptel-curl: Rename functions for linting
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-`.
2023-03-08 19:23:17 -08:00
Karthik Chikmagalur
65e6d73372 gptel: Include more API parameters
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'.
2023-03-08 19:20:00 -08:00
Karthik Chikmagalur
172059060a gptel-curl: Autoload gptel-curl-get-response
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.
2023-03-08 19:17:14 -08:00
Karthik Chikmagalur
5159a773a0 gptel: Use text-property based delimiting
gptel.el (gptel--prompt-markers, gptel-send, gptel--create-prompt,
gptel--numberize): Switch from using markers to text-properties to
distinguish queries from responses. The former method was very brittle.
Remove `gptel--prompt-markers', add the function `gptel--create-prompt'
and the variable `gptel--num-messages-to-send'. This variable limits the
context of the conversation that is sent with each request.
2023-03-08 19:13:52 -08:00
Karthik Chikmagalur
77d1010fbc gptel-curl: Add package version 2023-03-08 03:58:50 -08:00
Karthik Chikmagalur
3c10147a72 gptel: Tweak README, minor linting 2023-03-08 01:22:14 -08:00
Karthik Chikmagalur
03113afd50 gptel: Rename internal functions
gptel.el (gptel-parse-response, gptel-get-response): These functions
have been renamed to mark them for internal use.
2023-03-08 01:22:14 -08:00
Karthik Chikmagalur
88995a6436 gptel-curl: Add curl module and playback feature.
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.
2023-03-08 01:22:14 -08:00
Karthik Chikmagalur
33d8434f3e gptel: Tweak header line format
Add a status indicator to the header line.
2023-03-06 00:58:32 -08:00