Skip to content

moritzschaefer/gptel

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

GPTel: A simple LLM client for Emacs

https://melpa.org/packages/gptel-badge.svg

GPTel is a simple Large Language Model chat client for Emacs, with support for multiple models/backends.

LLM BackendSupportsRequires
ChatGPTAPI key
AzureDeployment and API key
OllamaOllama running locally
GPT4AllGPT4All running locally
PrivateGPTPlanned-
Llama.cppPlanned-

General usage:

intro-demo.mp4
intro-demo-2.mp4

Multi-LLM support demo:

gptel-multi.mp4
  • It’s async and fast, streams responses.
  • Interact with LLMs from anywhere in Emacs (any buffer, shell, minibuffer, wherever)
  • LLM responses are in Markdown or Org markup.
  • Supports conversations and multiple independent sessions.
  • Save chats as regular Markdown/Org/Text files and resume them later.
  • You can go back and edit your previous prompts or LLM responses when continuing a conversation. These will be fed back to the model.

GPTel uses Curl if available, but falls back to url-retrieve to work without external dependencies.

Contents

Breaking Changes

  • Possible breakage, see #120: If streaming responses stop working for you after upgrading to v0.5, try reinstalling gptel and deleting its native comp eln cache in native-comp-eln-load-path.
  • The user option gptel-host is deprecated. If the defaults don’t work for you, use gptel-make-openai (which see) to customize server settings.
  • gptel-api-key-from-auth-source now searches for the API key using the host address for the active LLM backend, i.e. “api.openai.com” when using ChatGPT. You may need to update your ~/.authinfo.

Installation

GPTel is on MELPA. Ensure that MELPA is in your list of sources, then install gptel with M-x package-install⏎ gptel.

(Optional: Install markdown-mode.)

Straight

(straight-use-package 'gptel)

Installing the markdown-mode package is optional.

Manual

Clone or download this repository and run M-x package-install-file⏎ on the repository directory.

Installing the markdown-mode package is optional.

Doom Emacs

In packages.el

(package! gptel)

In config.el

(use-package! gptel
 :config
 (setq! gptel-api-key "your key"))

Spacemacs

After installation with M-x package-install⏎ gptel

  • Add gptel to dotspacemacs-additional-packages
  • Add (require 'gptel) to dotspacemacs/user-config

Setup

ChatGPT

Procure an OpenAI API key.

Optional: Set gptel-api-key to the key. Alternatively, you may choose a more secure method such as:

  • Storing in ~/.authinfo. By default, “api.openai.com” is used as HOST and “apikey” as USER.
    machine api.openai.com login apikey password TOKEN
        
  • Setting it to a function that returns the key.

Other LLM backends

Azure

Register a backend with

(gptel-make-azure
 "Azure-1"                              ;Name, whatever you'd like
 :protocol "https"                      ;optional -- https is the default
 :host "YOUR_RESOURCE_NAME.openai.azure.com"
 :endpoint "/openai/deployments/YOUR_DEPLOYMENT_NAME/completions?api-version=2023-05-15" ;or equivalent
 :stream t                              ;Enable streaming responses
 :models '("gpt-3.5-turbo" "gpt-4"))

Refer to the documentation of gptel-make-azure to set more parameters.

You can pick this backend from the transient menu when using gptel. (See usage)

If you want it to be the default, set it as the default value of gptel-backend:

(setq-default gptel-backend
              (gptel-make-azure
               "Azure-1"
               ...))

GPT4All

Register a backend with

(gptel-make-gpt4all
 "GPT4All"                              ;Name of your choosing
 :protocol "http"                       
 :host "localhost:4891"                 ;Where it's running
 :models '("mistral-7b-openorca.Q4_0.gguf")) ;Available models

These are the required parameters, refer to the documentation of gptel-make-gpt4all for more.

You can pick this backend from the transient menu when using gptel (see usage), or set this as the default value of gptel-backend. Additionally you may want to increase the response token size since GPT4All uses very short (often truncated) responses by default:

;; OPTIONAL configuration
(setq-default gptel-model "mistral-7b-openorca.Q4_0.gguf" ;Pick your default model
              gptel-backend (gptel-make-gpt4all "GPT4All" :protocol ...))
(setq-default gptel-max-tokens 500)

Ollama

Register a backend with

(gptel-make-ollama
 "Ollama"                               ;Any name of your choosing
 :host "localhost:11434"                ;Where it's running
 :models '("mistral:latest")            ;Installed models
 :stream t)                             ;Stream responses

These are the required parameters, refer to the documentation of gptel-make-ollama for more.

You can pick this backend from the transient menu when using gptel (see Usage), or set this as the default value of gptel-backend:

;; OPTIONAL configuration
(setq-default gptel-model "mistral:latest" ;Pick your default model
              gptel-backend (gptel-make-ollama "Ollama" :host ...))

Usage

CommandDescription
gptelCreate a new dedicated chat buffer. (Not required, gptel works anywhere.)
gptel-sendSend selection, or conversation up to (point). (Works anywhere in Emacs.)
C-u gptel-sendTransient menu for preferenes, input/output redirection etc.
gptel-menu(Same)
gptel-set-topic(Org-mode only) Limit conversation context to an Org heading

In any buffer:

  1. Select a region of text and call M-x gptel-send. The response will be inserted below your region.
  2. You can select both the original prompt and the response and call M-x gptel-send again to continue the conversation.
  3. Call M-x gptel-send with a prefix argument to
  • set chat parameters (GPT model, directives etc) for this buffer,
  • to read the prompt from elsewhere or redirect the response elsewhere,
  • or to replace the prompt with the response.

https://user-images.githubusercontent.com/8607532/230770018-9ce87644-6c17-44af-bd39-8c899303dce1.png

With a region selected, you can also rewrite prose or refactor code from here:

Code:

https://user-images.githubusercontent.com/8607532/230770162-1a5a496c-ee57-4a67-9c95-d45f238544ae.png

Prose:

https://user-images.githubusercontent.com/8607532/230770352-ee6f45a3-a083-4cf0-b13c-619f7710e9ba.png

In a dedicated chat buffer:

  1. Run M-x gptel to start or switch to the chat buffer. It will ask you for the key if you skipped the previous step. Run it with a prefix-arg (C-u M-x gptel) to start a new session.
  2. In the gptel buffer, send your prompt with M-x gptel-send, bound to C-c RET.
  3. Set chat parameters (LLM provider, model, directives etc) for the session by calling gptel-send with a prefix argument (C-u C-c RET):

https://user-images.githubusercontent.com/8607532/224946059-9b918810-ab8b-46a6-b917-549d50c908f2.png

That’s it. You can go back and edit previous prompts and responses if you want.

The default mode is markdown-mode if available, else text-mode. You can set gptel-default-mode to org-mode if desired.

Save and restore your chat sessions

Saving the file will save the state of the conversation as well. To resume the chat, open the file and turn on gptel-mode before editing the buffer.

Using it your way

GPTel’s default usage pattern is simple, and will stay this way: Read input in any buffer and insert the response below it.

If you want custom behavior, such as

  • reading input from or output to the echo area,
  • or in pop-up windows,
  • sending the current line only, etc,

GPTel provides a general gptel-request function that accepts a custom prompt and a callback to act on the response. You can use this to build custom workflows not supported by gptel-send. See the documentation of gptel-request, and the wiki for examples.

Extensions using GPTel

These are packages that depend on GPTel to provide additional functionality

Additional Configuration

Connection options
gptel-use-curlUse Curl (default), fallback to Emacs’ built-in url.
gptel-proxyProxy server for requests, passed to curl via --proxy.
gptel-api-keyVariable/function that returns the API key for the active backend.
LLM options(Note: not supported uniformly across LLMs)
gptel-backendDefault LLM Backend.
gptel-modelDefault model to use (depends on the backend).
gptel-streamEnable streaming responses (overrides backend-specific preference).
gptel-directivesAlist of system directives, can switch on the fly.
gptel-max-tokensMaximum token count (in query + response).
gptel-temperatureRandomness in response text, 0 to 2.
Chat UI options
gptel-default-modeMajor mode for dedicated chat buffers.
gptel-prompt-prefix-alistText demarcating queries and replies.

Why another LLM client?

Other Emacs clients for LLMs prescribe the format of the interaction (a comint shell, org-babel blocks, etc). I wanted:

  1. Something that is as free-form as possible: query the model using any text in any buffer, and redirect the response as required. Using a dedicated gptel buffer just adds some visual flair to the interaction.
  2. Integration with org-mode, not using a walled-off org-babel block, but as regular text. This way the model can generate code blocks that I can run.

Will you add feature X?

Maybe, I’d like to experiment a bit more first. Features added since the inception of this package include

  • Curl support (gptel-use-curl)
  • Streaming responses (gptel-stream)
  • Cancelling requests in progress (gptel-abort)
  • General API for writing your own commands (gptel-request, wiki)
  • Dispatch menus using Transient (gptel-send with a prefix arg)
  • Specifying the conversation context size
  • GPT-4 support
  • Response redirection (to the echo area, another buffer, etc)
  • A built-in refactor/rewrite prompt
  • Limiting conversation context to Org headings using properties (#58)
  • Saving and restoring chats (#17)
  • Support for local LLMs.

Features being considered or in the pipeline:

  • Fully stateless design (#17)

Alternatives

Other Emacs clients for LLMs include

  • chatgpt-shell: comint-shell based interaction with ChatGPT. Also supports DALL-E, executable code blocks in the responses, and more.
  • org-ai: Interaction through special #+begin_ai ... #+end_ai Org-mode blocks. Also supports DALL-E, querying ChatGPT with the contents of project files, and more.

There are several more: chatgpt-arcana, leafy-mode, chat.el

Acknowledgments

About

A simple LLM client for Emacs

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Emacs Lisp 100.0%