gptel-curl: handle large Curl payloads with a temp file (#137)

gptel-curl.el (gptel-curl--get-args,
gptel-curl-file-size-threshold): Use temporary file for curl data.
Ensure curl uses a temporary file for binary data to prevent
issues with large payloads and special characters:

- Add a new defcustom `gptel-curl-file-size-threshold` to
determine when to use a temporary file for passing data to Curl.

- Use `--data-binary` with a temp file for data larger than the
specified threshold, improving handling of large data payloads in
GPTel queries.

- Reliably clean up temporary files created for Curl requests
exceeding the size threshold.  Add a function to
`gptel-post-response-hook` to delete the file post-Curl execution
and remove itself from the hook, preventing temporary file
accumulation.
This commit is contained in:
Karim Aziiev 2023-12-15 06:22:53 +02:00 committed by GitHub
parent 15404f639d
commit d5949ef428
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 31 additions and 2 deletions

View file

@ -61,8 +61,18 @@ PROMPTS is the data to send, TOKEN is a unique identifier."
backend-header))))) backend-header)))))
(append (append
gptel-curl--common-args gptel-curl--common-args
(list (format "-w(%s . %%{size_header})" token) (list (format "-w(%s . %%{size_header})" token))
(format "-d%s" data)) (if (length< data gptel-curl-file-size-threshold)
(list (format "-d%s" data))
(letrec
((temp-filename (make-temp-file "gptel-curl-data" nil ".json" data))
(cleanup-fn (lambda ()
(when (file-exists-p temp-filename)
(delete-file temp-filename)
(remove-hook 'gptel-post-response-hook cleanup-fn)))))
(add-hook 'gptel-post-response-hook cleanup-fn)
(list "--data-binary"
(format "@%s" temp-filename))))
(when (not (string-empty-p gptel-proxy)) (when (not (string-empty-p gptel-proxy))
(list "--proxy" gptel-proxy (list "--proxy" gptel-proxy
"--proxy-negotiate" "--proxy-negotiate"

View file

@ -163,6 +163,25 @@ all at once. This wait is asynchronous.
:group 'gptel :group 'gptel
:type 'boolean) :type 'boolean)
(defcustom gptel-curl-file-size-threshold 130000
"Size threshold for using file input with Curl.
Specifies the size threshold for when to use a temporary file to pass data to
Curl in GPTel queries. If the size of the data to be sent exceeds this
threshold, the data is written to a temporary file and passed to Curl using the
`--data-binary' option with a file reference. Otherwise, the data is passed
directly as a command-line argument.
The value is an integer representing the number of bytes.
Adjusting this value may be necessary depending on the environment
and the typical size of the data being sent in GPTel queries.
A larger value may improve performance by avoiding the overhead of creating
temporary files for small data payloads, while a smaller value may be needed
if the command-line argument size is limited by the operating system."
:group 'gptel
:type 'integer)
(defcustom gptel-response-filter-functions (defcustom gptel-response-filter-functions
'(gptel--convert-org) '(gptel--convert-org)
"Abnormal hook for transforming the response from ChatGPT. "Abnormal hook for transforming the response from ChatGPT.