karthink / gptel

A simple LLM client for Emacs
GNU General Public License v3.0
1.04k stars 111 forks source link

`(void-variable gptel--known-backends)` when using `gptel-make-openai` #227

Open dmcooke opened 4 months ago

dmcooke commented 4 months ago

When using autoloading to defer loading gptel.el, configuring with gptel-make-openai (an autoloaded function in gptel-openai.el) will fail as gptel--known-backends doesn't have a value.

For example, straight-use-package doesn't actually load the package after installing: it just makes sure the autoloads in the package are known to Emacs.

Basically, gptel-make-openai and friend (gptel-make-azure) should check if gptel--known-backends has a value first (using boundp). The other backends require gptel.

Personally, since all the other backend definition files (gptel-kagi.el, etc.) depend on gptel.el, I'd rearrange the dependencies so that gptel-openai.el depends on gptel and not the other way around. This also solves the problem of generic functions like gptel--parse-backend being initially created by the cl-defmethod in gptel-openai.el before the cl-defgeneric in gptel.el. (Or, split out a gptel-backend.el and put common backend definitions there, if you want to keep the lazy-loading.)

karthink commented 4 months ago

Personally, since all the other backend definition files (gptel-kagi.el, etc.) depend on gptel.el, I'd rearrange the dependencies so that gptel-openai.el depends on gptel and not the other way around.

That was the original plan, but the build kept failing and I couldn't figure out why. It certainly makes more sense that way, the current load order is pretty ugly. I'll take another crack at it soon.

karthink commented 4 months ago

I can't figure out how to invert the dependency without errors. Maybe you can help me? Here's the problem (after making gptel-openai.el require gptel, as the other backends do):

I set the default value of gptel-backend to (gptel-make-openai "ChatGPT" ...) in gptel.el. This requires gptel-make-openai to be available. Even though it's autoloaded, it's not available when byte-compiling the package unless I (require 'gptel-openai) first.

I tried various combinations of (eval-when-compile (require 'gptel-openai)) and (cl-eval-when (compile) (require 'gptel-openai)), with (compile) replaced with (compile load), etc. At best I can get gptel.el to byte-compile without issues, but all the files that (require 'gptel) (like the other backends) fail to compile.

Any ideas?


I can fix your particular issue by just adding (defvar gptel--known-backends) to gptel-openai.el, but I'd like to fix the actual cause of the problem while we're at it.

andrepacak commented 3 months ago

I have the same issue with gptel-make-gpt4all. How can I fix it?

improve100 commented 1 month ago

It can be solved in this way

(use-package! gptel
  :config
  ;; (setq! gptel-api-key "your key")
  ;; Groq offers an OpenAI compatible API
  (gptel-make-openai "Moonshot"
    :host "api.moonshot.cn"
    :endpoint "/v1/chat/completions"
    :key "keykeykey"
    :models '("moonshot-v1-8k" "moonshot-v1-32k" "moonshot-v1-128k"))
  (gptel-make-openai "Groq"               ;Any name you want
    :host "api.groq.com"
    :endpoint "/openai/v1/chat/completions"
    :stream t
    :key "keykeykey"                   ;can be a function that returns the key
    :models '("mixtral-8x7b-32768" "gemma-7b-it" "llama2-70b-4096")))