forge-llm/README.org
Roger Gonzalez 62c925deff
Clarify Forge-LLM dependencies and usage
- Update README to explicitly state that `forge` is essential.
- Emphasize that Forge-LLM commands operate within `forge-post-mode`.
- Add a prominent note in `forge-llm.el` regarding Forge dependency.
- Clarify the intended usage context of Forge-LLM.
2025-04-03 10:33:10 -03:00

421 lines
14 KiB
Org Mode

#+TITLE: forge-llm
#+AUTHOR: Roger Gonzalez
#+EMAIL: roger@rogs.me
[[https://melpa.org/#/forge-llm][file:https://melpa.org/packages/forge-llm-badge.svg]]
[[https://gitlab.com/rogs/forge-llm/badges/master/pipeline.svg]]
* forge-llm
:PROPERTIES:
:ID: 81db1fd1-a5db-4201-9113-72889f7c7829
:END:
Generate Pull Request descriptions for Forge using LLM providers through the [[https://github.com/ahyatt/llm][llm]] package.
[[https://gitlab.com/uploads/-/system/project/avatar/67959042/logo.png]]
** Overview
:PROPERTIES:
:ID: e5e5a1d0-cf5a-4f45-8d4c-f2f75339bf9a
:END:
~forge-llm~ is an Emacs package that integrates Large Language Models (LLMs) with Forge, a Magit interface to GitHub and GitLab forges. This package helps you generate high-quality Pull Request descriptions based on your git diff and repository PR templates.
Main features:
- Automatically finds and uses your repository's PR template
- Generates PR descriptions based on git diffs between branches
- Seamless integration with Forge's PR creation workflow
- Supports any LLM provider supported by the ~llm~ package
- Stream LLM responses in real-time
** Dependencies
:PROPERTIES:
:ID: f30fedc1-a24a-4308-bc78-6f9c01857c18
:END:
- [[https://magit.vc/][Magit]] and [[https://github.com/magit/forge][Forge]] (**Note:** `forge` is essential for this package to operate)
- [[https://github.com/ahyatt/llm][llm]]
- Emacs 25.1+
** Installation
:PROPERTIES:
:ID: a4cfca4c-6029-445a-9e1d-88293ddaaff7
:END:
*** Using MELPA (Recommended)
:PROPERTIES:
:ID: 0e561e53-10f6-4a0b-90e3-46094124aeb2
:END:
The easiest way to install ~forge-llm~ is via MELPA. Ensure you have MELPA configured in your Emacs setup (it's included by default in many distributions like Doom Emacs and Spacemacs).
#+begin_src emacs-lisp
(use-package forge-llm
:ensure t
:after forge
:config
(forge-llm-setup))
#+end_src
*** Using straight.el with use-package
:PROPERTIES:
:ID: 0c4a74cd-f752-4b3f-a729-0cc5a34f3d38
:END:
If you use ~straight.el~ to manage your packages, it can install ~forge-llm~ directly from MELPA. Ensure MELPA is included in your ~straight-recipe-repositories~ or ~straight-recipe-sources~.
#+begin_src emacs-lisp
(use-package forge-llm
;; straight.el will fetch this from MELPA if :ensure t is used
;; and straight.el is configured as the handler for use-package.
:ensure t
:after forge
:config
(forge-llm-setup))
#+end_src
*** Using Doom Emacs
:PROPERTIES:
:ID: 6c2a34d5-8e1a-4f7e-9c2b-1d9e7b8f3a1d
:END:
**** Basic Setup
:PROPERTIES:
:ID: f7a2b3c4-d5e6-4f7a-8b9c-0d1e2f3a4b5c
:END:
1. Add the following to your ~packages.el~ (ensure MELPA is enabled in your Doom configuration, which is usually the default):
#+begin_src emacs-lisp
(package! forge-llm)
(package! llm) ; Dependency
#+end_src
2. Add somewhere in your ~config.el~:
#+begin_src emacs-lisp
;; Load and setup forge-llm after forge is loaded
(after! forge
(require 'forge-llm)
(forge-llm-setup))
;; Configure your LLM provider (example using OpenAI)
;; Place this somewhere appropriate in your config.el
(require 'llm-openai) ; Or your preferred LLM provider
(setq forge-llm-llm-provider (make-llm-openai :key "YOUR-OPENAI-KEY")) ; Replace with your key/provider setup
#+end_src
3. Run ~doom sync~ to install the package.
**** Keybindings
:PROPERTIES:
:ID: 3e4f5a6b-7c8d-9e0f-1a2b-3c4d5e6f7a8b
:END:
The package automatically sets up Doom Emacs keybindings when Doom is detected:
- ~SPC m g~ - Generate PR description in a separate buffer
- ~SPC m p~ - Generate PR description at point
- ~SPC m t~ - Insert PR template at point
No additional configuration is needed for these keybindings to work.
*** Manual installation
:PROPERTIES:
:ID: b91cfecf-04a3-43c8-96d3-dea082e5ed6e
:END:
Clone the repository:
#+begin_src shell
git clone https://gitlab.com/rogs/forge-llm.git ~/.emacs.d/site-lisp/forge-llm
#+end_src
Add to your Emacs configuration:
#+begin_src emacs-lisp
(add-to-list 'load-path "~/.emacs.d/site-lisp/forge-llm")
(require 'forge-llm)
(forge-llm-setup)
#+end_src
** Setting up LLM providers
:PROPERTIES:
:ID: 842282e1-4760-4687-96a1-4c15adb9a13d
:END:
~forge-llm~ depends on the [[https://github.com/ahyatt/llm][llm]] package for LLM integration. You'll need to set up at least one LLM provider. Please refer to the [[https://github.com/ahyatt/llm?tab=readme-ov-file#setting-up-providers][llm documentation]] for detailed instructions.
Some of the providers supported by the ~llm~ package include:
- OpenAI
- Anthropic (Claude)
- Google (Gemini, Vertex AI)
- Azure OpenAI
- GitHub Models
- Ollama (for local models like Llama, Mistral, etc.)
- GPT4All (for local models)
- llama.cpp (via OpenAI compatible endpoint)
- Deepseek
- Generic OpenAI-compatible endpoints
See the [[https://github.com/ahyatt/llm?tab=readme-ov-file#setting-up-providers][llm documentation]] for the complete list and specific setup steps.
*** Example: OpenAI provider
:PROPERTIES:
:ID: 108c5560-65ad-49e1-8c02-d4c0493bb2b2
:END:
First, create an [[https://platform.openai.com/account/api-keys][OpenAI API key]]. Then configure the ~llm~ OpenAI provider:
#+begin_src emacs-lisp
(require 'llm-openai)
(setq forge-llm-llm-provider (make-llm-openai :key "YOUR-OPENAI-KEY"))
#+end_src
*** Example: Anthropic provider
:PROPERTIES:
:ID: b9728ac5-f5c0-4d6b-8d3e-a4b7c3d9e1f0
:END:
To use Claude models from Anthropic:
#+begin_src emacs-lisp
(require 'llm-claude)
(setq forge-llm-llm-provider (make-llm-claude :key "YOUR-ANTHROPIC-KEY" :chat-model "claude-3-7-sonnet-20250219"))
#+end_src
*** Using auth-source for API keys (recommended)
:PROPERTIES:
:ID: 59f84b84-ce44-4208-8531-56992cae847e
:END:
For better security, use Emacs ~auth-source~ to store your API keys:
#+begin_src emacs-lisp
(use-package llm
:ensure t
:config
(setq llm-warn-on-nonfree nil))
(require 'llm-openai)
(use-package forge-llm
:ensure t
:after (forge llm)
:custom
(forge-llm-llm-provider
(make-llm-openai
:key (auth-source-pick-first-password
:host "api.openai.com"
:user "apikey")))
:config
(forge-llm-setup))
#+end_src
Content of ~.authinfo~ or ~.authinfo.gpg~:
#+begin_src
machine api.openai.com login apikey password YOUR-API-KEY-HERE
#+end_src
** Usage
:PROPERTIES:
:ID: e6753914-01ee-41e9-bcdf-f3d6e75ee451
:END:
After setting up ~forge-llm~, the following commands will be available *specifically within Forge's pull request creation buffer* (which runs in `forge-post-mode`):
| Key binding | Command | Description |
|------------------------+--------------------------------------------+-------------------------------------------------------|
| C-c C-l g | forge-llm-generate-pr-description | Generate a PR description (output to separate buffer) |
| C-c C-l p | forge-llm-generate-pr-description-at-point | Generate a PR description at the current point |
| C-c C-l t | forge-llm-insert-template-at-point | Insert the PR template at the current point |
| SPC m g (Doom Emacs) | forge-llm-generate-pr-description | Generate a PR description (output to separate buffer) |
| SPC m p (Doom Emacs) | forge-llm-generate-pr-description-at-point | Generate a PR description at the current point |
| SPC m t (Doom Emacs) | forge-llm-insert-template-at-point | Insert the PR template at the current point |
*** Demo: Generate PR description in a new buffer
:PROPERTIES:
:ID: 8d7e1f6a-3b2c-4a9e-8d7e-1f6a3b2c4a9e
:END:
Pressing ~C-c C-l g~ will generate a PR description and display it in a separate buffer:
[[https://gitlab.com/-/project/67959042/uploads/3eed67e0b188d040906d30b6b6cc3ec6/generate-pr-desc.gif][file:https://gitlab.com/-/project/67959042/uploads/3eed67e0b188d040906d30b6b6cc3ec6/generate-pr-desc.gif]]
/Click the image to view in full screen/
*** Demo: Generate PR description at point
:PROPERTIES:
:ID: 9e5d4f8b-4eab-8798-9e5d-4f8b4eab8798
:END:
Pressing ~C-c C-l p~ will generate a PR description and insert it directly at the cursor position:
[[https://gitlab.com/-/project/67959042/uploads/9e5d4f8b4eab87989eafca9f58baa467/generate-pr-at-point.gif][file:https://gitlab.com/-/project/67959042/uploads/9e5d4f8b4eab87989eafca9f58baa467/generate-pr-at-point.gif]]
/Click the image to view in full screen/
*** Workflow:
:PROPERTIES:
:ID: d745d788-793a-4847-95d7-4f5105bc654d
:END:
1. Create a PR using Forge as normal (~forge-create-pullreq~)
2. In the PR creation buffer, position your cursor where you want to insert the PR description
3. Press ~C-c C-l p~ to generate and insert a PR description based on your changes
4. Edit the description as needed and submit the PR
*** Canceling Generation:
:PROPERTIES:
:ID: 7ddfeaab-31a3-4476-b770-7c9751566d88
:END:
If you need to cancel an in-progress LLM request:
- ~M-x forge-llm-cancel-request~
** Customization
:PROPERTIES:
:ID: baff250b-65a2-48cf-ace8-af38996bd865
:END:
You can customize various aspects of ~forge-llm~ through the following variables:
*** PR Template Configuration
:PROPERTIES:
:ID: ccb75625-c64d-47ad-adbe-77862b4ebbb5
:END:
- ~forge-llm-pr-template-paths~ - List of possible paths for PR/MR templates relative to repo root
#+begin_src emacs-lisp
(setq forge-llm-pr-template-paths
'(".github/PULL_REQUEST_TEMPLATE.md"
".github/pull_request_template.md"
"docs/pull_request_template.md"
".gitlab/merge_request_templates/default.md"))
#+end_src
- ~forge-llm-default-pr-template~ - Default PR template to use when no template is found in the repository
*** LLM Provider Configuration
:PROPERTIES:
:ID: 8c3c77fb-a6ae-47bb-8c2b-2b82c2364d81
:END:
- ~forge-llm-llm-provider~ - LLM provider to use. Can be a provider object or a function that returns a provider object
(See the [[https://github.com/ahyatt/llm][llm package]] documentation for how to create provider objects).
#+begin_src emacs-lisp
(setq forge-llm-llm-provider (make-llm-openai :key "YOUR-API-KEY"))
#+end_src
- ~forge-llm-temperature~ - Temperature for LLM responses (nil for provider default)
#+begin_src emacs-lisp
(setq forge-llm-temperature 0.7)
#+end_src
- ~forge-llm-max-tokens~ - Maximum number of tokens for LLM responses (nil for provider default)
#+begin_src emacs-lisp
(setq forge-llm-max-tokens 1024)
#+end_src
- ~forge-llm-max-diff-size~ - Maximum size in characters for git diffs sent to the LLM (nil for no truncation)
#+begin_src emacs-lisp
;; Default is 50000, set to nil to disable truncation
(setq forge-llm-max-diff-size 100000) ; Increase to 100K characters
;; Or disable truncation completely
(setq forge-llm-max-diff-size nil)
#+end_src
*** Prompt Configuration
:PROPERTIES:
:ID: f0cb4a2b-d919-4fe0-b286-317b93084174
:END:
- ~forge-llm-pr-description-prompt~ - Prompt used to generate a PR description with the LLM. This prompt is formatted with the PR template and git diff.
You can customize this prompt to match your project's PR description style:
#+begin_src emacs-lisp
(setq forge-llm-pr-description-prompt
"Generate a PR description for the following changes.
PR template:
%s
Git diff:
```
%s
```
Please generate a PR description that follows our team's style.")
#+end_src
** Troubleshooting
:PROPERTIES:
:ID: 30489ac7-98ed-4820-a780-83c239e427f6
:END:
- If you're having issues with the LLM provider, you can enable debug logging for ~llm~ by setting ~llm-log~ to ~t~.
- Check the ~*forge-llm-debug-prompt*~ buffer to see the exact prompt being sent to the LLM.
- Check the ~*forge-llm-output*~ buffer to see the raw output from the LLM.
*** Common Issues:
:PROPERTIES:
:ID: 4b2fd630-290e-4a95-8315-e8db4b6f4217
:END:
- *Error: "No LLM provider configured"*
- Make sure you've set ~forge-llm-llm-provider~ to a valid provider object.
- Ensure your API key is correct.
- *Error: "Failed to generate git diff"*
- Ensure you're in a repository with valid head and base branches.
- Check if the current directory is within a git repository.
- *PR Generation is too slow*
- Consider using a faster model (like GPT-3.5-turbo instead of GPT-4).
- Reduce ~forge-llm-max-tokens~ to limit the response size.
- *PR template not found*
- Check if your PR template is in one of the paths listed in ~forge-llm-pr-template-paths~.
- Add your custom template path if needed.
** TO-DO:
:PROPERTIES:
:ID: 97dad50e-0d25-42aa-9fe6-5e6402256454
:END:
- Add more examples and use cases
** Contributing
:PROPERTIES:
:ID: 398ecc9e-30c2-4af4-afc5-c793ab3bedaa
:END:
Contributions are welcome! Please feel free to submit a Merge Request.
*** Development Setup
:PROPERTIES:
:ID: 237ac5d2-d323-4b7d-9c51-54760a3ccc53
:END:
1. Clone the repository:
#+begin_src shell
git clone https://gitlab.com/rogs/forge-llm.git
cd forge-llm
#+end_src
2. Install dependencies for development:
- Ensure you have forge and llm packages
** Acknowledgments
:PROPERTIES:
:ID: b5d4c3e2-f1a0-4b9c-8d7e-6f5a4b3c2d1e
:END:
This project was heavily inspired by [[https://github.com/douo/magit-gptcommit][magit-gptcommit]]. Check it out! This package works very well with forge-llm.
Another huge inspiration was [[https://github.com/xenodium][xenodium]], with their Emacs package [[https://github.com/xenodium/chatgpt-shell][chatgpt-shell]].
** License
:PROPERTIES:
:ID: 14189649-a22f-4cf8-9850-9a8bb62456d3
:END:
This project is licensed under the GNU General Public License version 3 - see the LICENSE file for details.