feat(ai/chatgpt): all per-model API key configuration in shared setup

This commit is contained in:
2023-04-17 01:15:06 +01:00
parent ecce66ec06
commit d0d604bbc7
5 changed files with 86 additions and 44 deletions

View File

@@ -68,7 +68,6 @@
(require 'siren-chatgpt)
(require 'siren-chatgpt-shell)
(require 'siren-gptel)
(require 'siren-openai-chatgpt)
;; Misc.
(require 'siren-explain-pause)

View File

@@ -10,17 +10,16 @@
(use-package chatgpt-shell
:straight (:host github :repo "xenodium/chatgpt-shell")
:defer t
:custom
(chatgpt-shell-chatgpt-streaming t)
(chatgpt-shell-model-temperature 0.13)
(chatgpt-shell-model-temperature 1.0)
:config
;; Dynamically load the API key after package has loaded.
(setq chatgpt-shell-openai-key (siren-openai-api-key))
(setq dall-e-shell-openai-key (siren-openai-api-key))
;; Set model via `siren-chatgpt-model'.
;; Set and manage API Key and Model via `siren-chatgpt' helpers.
(siren-chatgpt-register-api-key-var 'chatgpt-shell-openai-key)
(siren-chatgpt-register-api-key-var 'dall-e-shell-openai-key)
(siren-chatgpt-register-model-var 'chatgpt-shell-model-version)
(require 'ob-chatgpt-shell)

View File

@@ -12,50 +12,94 @@
"Options for `siren-chatgpt'."
:group 'siren)
(defcustom siren-chatgpt-model-variables nil
"List of variable names to be updated when `siren-chatgpt-model' change.
(defvar siren-chatgpt--api-key-login nil
"The login value used to retrieve the current API key.")
(defun siren-chatgpt--set-api-key ()
"Set `siren-chatgpt-api-key' based on provided LOGIN.
If the key is not already set, try to retrieve it from the
auth-source. If LOGIN is non-nil, use that value to retrieve the"
(let ((login (siren-chatgpt--login-user)))
(or (and siren-chatgpt--api-key-login
(string= siren-chatgpt--api-key-login login))
(let ((api-key (auth-source-pick-first-password :host "openai.com"
:user login)))
(if api-key
(progn
(setq siren-chatgpt--api-key-login login)
(customize-set-variable 'siren-chatgpt-api-key api-key))
(error (format "OpenAI key for login \"%s\" not found in auth-source."
login)))))))
(defvar siren-chatgpt--api-key-variables nil
"List of variable names to be updated on `siren-chatgpt-api-key' change.
Other packages should use `siren-chatgpt-register-api-key-var' to register
their API key settings to be kept in sync with `siren-chatgpt-api-key'.")
(defcustom siren-chatgpt-api-key nil
"OpenAI API key."
:type 'string
:set (lambda (symbol value)
(set-default symbol value)
(dolist (var siren-chatgpt--api-key-variables)
(set-default var value)))
:group 'siren-chatgpt)
(defvar siren-chatgpt--model-variables nil
"List of variable names to be updated on `siren-chatgpt-model' change.
Other packages should use `siren-chatgpt-register-model-var'
their model settings are kept in sync with `siren-chatgpt-model'."
:type '(repeat symbol)
:group 'siren-chatgpt)
their model settings are kept in sync with `siren-chatgpt-model'.")
(defvar siren-chatgpt-models '("gpt-3.5-turbo"
"gpt-4"
"gpt-4-32k")
"List of supported models.")
(defcustom siren-chatgpt-model "gpt-4"
"The model to use for chatgpt."
:type '(choice (const "gpt-3.5-turbo")
(const "gpt-3.5-turbo-0301")
(const "gpt-4")
(const "gpt-4-0314")
(const "gpt-4-32k")
(const "gpt-4-32k-0314"))
:type '(choice (mapcar (lambda (model) (list 'const model))
siren-chatgpt-models))
:set (lambda (symbol value)
(set-default symbol value)
(dolist (var siren-chatgpt-model-variables)
(set-default var value)))
(dolist (var siren-chatgpt--model-variables)
(set-default var value))
(if siren-chatgpt-api-key
(siren-chatgpt--set-api-key)))
:group 'siren-chatgpt)
(defun siren-chatgpt--login-user ()
"Return the login name of the current user.
Used to allow different API keys for different models."
(if (string-prefix-p "gpt-4" siren-chatgpt-model)
"gpt-4"
"default"))
(defun siren-chatgpt-select-model ()
"Select a model to use for chatgpt."
(interactive)
(let ((model (completing-read "Select model: " siren-chatgpt-models)))
(customize-set-variable 'siren-chatgpt-model model)))
(defun siren-chatgpt-register-model-var (var)
"Register VAR to be updated on `siren-chatgpt-model' change.
VAR should be a symbol representing a variable. When the value of
`siren-chatgpt-model' changes, the value of VAR will be updated
to match it."
(add-to-list 'siren-chatgpt-model-variables var)
`siren-chatgpt-model' changes, VAR will be updated accordingly."
(add-to-list 'siren-chatgpt--model-variables var)
(set-default var siren-chatgpt-model))
(defvar siren-openai-api-key nil
"OpenAI API key.")
(defun siren-chatgpt-register-api-key-var (var)
"Register VAR to be updated on `siren-chatgpt-api-key' change.
(defun siren-openai-api-key ()
"Return OpenAI API key.
If the key is not already set, try to retrieve it from the auth-source."
(or siren-openai-api-key
(let ((api-key (auth-source-pick-first-password :host "openai.com")))
(if api-key
(progn
(setq siren-openai-api-key api-key)
siren-openai-api-key)
(error "OpenAI API key not found in auth-source")))))
VAR should be a symbol representing a variable. When the value of
`siren-chatgpt-api-key' changes, the VAR will be updated
accordingly."
(add-to-list 'siren-chatgpt--api-key-variables var)
(siren-chatgpt--set-api-key))
(provide 'siren-chatgpt)
;;; siren-chatgpt.el ends here

View File

@@ -22,18 +22,16 @@
:custom
(gptel-stream t) ;; Requires curl.
(gptel-temperature 1)
(gptel-temperature 1.0)
(gptel-use-curl (and (executable-find "curl") t))
:config
;; Dynamically load the API key after package has loaded.
(setq gptel-api-key (siren-openai-api-key))
;; Set and manage API Key and Model via `siren-chatgpt' helpers.
(siren-chatgpt-register-api-key-var 'gptel-api-key)
(siren-chatgpt-register-model-var 'gptel-model)
;; Set default mode to org-mode, must be done after package load.
(setq gptel-default-mode 'org-mode)
;; Set model via `siren-chatgpt-model'.
(siren-chatgpt-register-model-var 'gptel-model))
(setq gptel-default-mode 'org-mode))
(provide 'siren-gptel)
;;; siren-gptel.el ends here

View File

@@ -10,14 +10,15 @@
(use-package openai
:straight (:host github :repo "emacs-openai/openai")
:defer t
:config
(setq openai-key (siren-openai-api-key)))
(siren-chatgpt-register-api-key-var 'openai-key))
(use-package chatgpt
:straight (:host github :repo "emacs-openai/chatgpt")
:defer t
:after openai
:custom
(chatgpt-max-tokens 2000)
(chatgpt-temperature 1.0)
@@ -27,6 +28,7 @@
(use-package codegpt
:straight (:host github :repo "emacs-openai/codegpt")
:defer t
:after openai)
(provide 'siren-openai-chatgpt)