emacs-openai / openai

Elisp library for the OpenAI API
GNU General Public License v3.0
100 stars 17 forks source link

Add base url option #15

Closed JCZuurmond closed 1 year ago

JCZuurmond commented 1 year ago

Resolves #14

Note that I am new to Elisp. I used ChatGPT to help me with this contribution. I would like it if someone reviews this and verifies it does what it should.

Also, I don't know how to test this locally. Could someone tell me how to run and test a package locally?

Feel free to make edits if those are required.

JCZuurmond commented 1 year ago

I doubt if the openai-base-url variable should also be used in the openai-key-auth-source function. The URL is slightly different: "api.openai.com" instead of "https://api.openai.com/v1"

jcs090218 commented 1 year ago

Also, I don't know how to test this locally. Could someone tell me how to run and test a package locally?

There are some examples at the bottom of each module file. For example, in openai-chat.el:

;;;###autoload
(defun openai-chat-say ()
  "Start making a conversation to OpenAI.
This is a ping pong message, so you will only get one response."
  (interactive)
  (if-let* ((user (read-string "What is your name? " "user"))
            (say  (read-string "Start the conversation: ")))
      (openai-chat `[(("role"    . ,user)
                      ("content" . ,say))]
                   (lambda (data)
                     (let ((choices (let-alist data .choices)))
                       (mapc (lambda (choice)
                               (let-alist choice
                                 (let-alist .message
                                   (message "%s: %s" .role (string-trim .content)))))
                             choices)))
                   :max-tokens openai-chat-max-tokens
                   :temperature openai-chat-temperature
                   :user (unless (string= user "user") user))
    (user-error "Abort, canecel chat operation")))

That's how you use it.

jcs090218 commented 1 year ago

I doubt if the openai-base-url variable should also be used in the openai-key-auth-source function. The URL is slightly different: "api.openai.com" instead of "https://api.openai.com/v1"

No, you don't need to. auth-source is only for secret, like passwords, credentials, etc.

JCZuurmond commented 1 year ago

No, you don't need to. auth-source is only for secret, like passwords, credentials, etc.

I meant as input to auth-source-search in the openai-key-auth-source function. Something like:

(defun openai-key-auth-source ()
  "Retrieve the OpenAI API key from auth-source."
  (if-let ((auth-info (auth-source-search :max 1
                                          :host openai-base-url
                                          :require '(:user :secret))))
      (funcall (plist-get (car auth-info) :secret))
    (error "OpenAI API key not found in auth-source")))
jcs090218 commented 1 year ago

I meant as input to auth-source-search in the openai-key-auth-source function. Something like:

Use these functions to extract URL to host:

(require 'url-parse)  ; add to the top

(url-host (url-generic-parse-url openai-base-url))

output

https://api.openai.com/v1 => api.openai.com
JCZuurmond commented 1 year ago

Beside the last comment, I think this PR is ready to be merged!

jcs090218 commented 1 year ago

LGTM! Thanks for taking care of this! 🚀