From 2e92c0303caf574ed3d4e3129ebb9a9f5936c3fd Mon Sep 17 00:00:00 2001 From: Karthik Chikmagalur Date: Fri, 22 Dec 2023 16:25:32 -0800 Subject: [PATCH] gptel: gptel-backend-url can accept functions * gptel.el (gptel--url-get-response): If the backend-url is a function, call it to find the full url to query. * gptel-gemini.el: Gemini uses different urls for streaming/oneshot responses. Set the backend-url to a function to account for the value of gptel-stream. This is also safer than before as the API key is not stored as part of a static url string in memory. Fix #153. * gptel-curl.el (gptel-curl--get-args): If the backend-url is a function, call it to find the full url to query. --- gptel-curl.el | 11 ++++++----- gptel-gemini.el | 19 +++++++------------ gptel.el | 11 ++++++----- 3 files changed, 19 insertions(+), 22 deletions(-) diff --git a/gptel-curl.el b/gptel-curl.el index 53bbbc1..4f624f9 100644 --- a/gptel-curl.el +++ b/gptel-curl.el @@ -49,16 +49,17 @@ "Produce list of arguments for calling Curl. PROMPTS is the data to send, TOKEN is a unique identifier." - (let* ((url (gptel-backend-url gptel-backend)) + (let* ((url (let ((backend-url (gptel-backend-url gptel-backend))) + (if (functionp backend-url) + (funcall backend-url) backend-url))) (data (encode-coding-string (json-encode (gptel--request-data gptel-backend prompts)) 'utf-8)) (headers (append '(("Content-Type" . "application/json")) - (when-let ((backend-header (gptel-backend-header gptel-backend))) - (if (functionp backend-header) - (funcall backend-header) - backend-header))))) + (when-let ((header (gptel-backend-header gptel-backend))) + (if (functionp header) + (funcall header) header))))) (append gptel-curl--common-args (list (format "-w(%s . %%{size_header})" token)) diff --git a/gptel-gemini.el b/gptel-gemini.el index 7763c18..63453b6 100644 --- a/gptel-gemini.el +++ b/gptel-gemini.el @@ -139,19 +139,14 @@ function that returns the key." :protocol protocol :endpoint endpoint :stream stream + :key key :url - (let ((key (cond - ((functionp key) (funcall key)) - ((symbolp key) (symbol-value key)) - ((stringp key) key) - (t (user-error "gptel-make-gemini: arg :key is malformed"))))) - (if protocol - (concat protocol "://" host endpoint - (if stream - "streamGenerateContent" - "generateContent") - "?key=" key) - (concat host endpoint "?key=" key)))))) + (lambda () + (concat protocol "://" host endpoint + (if gptel-stream + "streamGenerateContent" + "generateContent") + "?key=" (gptel--get-api-key)))))) (prog1 backend (setf (alist-get name gptel--known-backends nil nil #'equal) diff --git a/gptel.el b/gptel.el index b1da565..b2ddb5b 100644 --- a/gptel.el +++ b/gptel.el @@ -979,16 +979,17 @@ the response is inserted into the current buffer after point." (url-request-method "POST") (url-request-extra-headers (append '(("Content-Type" . "application/json")) - (when-let ((backend-header (gptel-backend-header gptel-backend))) - (if (functionp backend-header) - (funcall backend-header) - backend-header)))) + (when-let ((header (gptel-backend-header gptel-backend))) + (if (functionp header) + (funcall header) header)))) (url-request-data (encode-coding-string (json-encode (gptel--request-data gptel-backend (plist-get info :prompt))) 'utf-8))) - (url-retrieve (gptel-backend-url gptel-backend) + (url-retrieve (let ((backend-url (gptel-backend-url gptel-backend))) + (if (functionp backend-url) + (funcall backend-url) backend-url)) (lambda (_) (pcase-let ((`(,response ,http-msg ,error) (gptel--url-parse-response backend (current-buffer))))