Skip to content

Commit 3fd15a3

Browse files
committed
manual: Update
1 parent 498b82d commit 3fd15a3

File tree

1 file changed

+124
-35
lines changed

1 file changed

+124
-35
lines changed

doc/manual.org

Lines changed: 124 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -67,35 +67,6 @@ gptel is a Large Language Model client for Emacs, with support for
6767
multiple models and backends. It works in the spirit of Emacs,
6868
available at any time and uniformly in any buffer.
6969

70-
gptel supports the following services.
71-
72-
#+html: <div align="center">
73-
#+attr_texinfo: :columns .2 .7
74-
| LLM Backend | Requires |
75-
|--------------------+----------------------------|
76-
| ChatGPT | [[https://platform.openai.com/account/api-keys][API key]] |
77-
| Anthropic (Claude) | [[https://www.anthropic.com/api][API key]] |
78-
| Gemini | [[https://makersuite.google.com/app/apikey][API key]] |
79-
| Ollama | [[https://ollama.ai/][Ollama running locally]] |
80-
| Llama.cpp | [[https://github.com/ggerganov/llama.cpp/tree/master/examples/server#quick-start][Llama.cpp running locally]] |
81-
| Llamafile | [[https://github.com/Mozilla-Ocho/llamafile#quickstart][Local Llamafile server]] |
82-
| GPT4All | [[https://gpt4all.io/index.html][GPT4All running locally]] |
83-
| Kagi FastGPT | [[https://kagi.com/settings?p=api][API key]] |
84-
| Kagi Summarizer | [[https://kagi.com/settings?p=api][API key]] |
85-
| Azure | Deployment and API key |
86-
| Groq | [[https://console.groq.com/keys][API key]] |
87-
| Perplexity | [[https://docs.perplexity.ai/docs/getting-started][API key]] |
88-
| OpenRouter | [[https://openrouter.ai/keys][API key]] |
89-
| together.ai | [[https://api.together.xyz/settings/api-keys][API key]] |
90-
| Anyscale | [[https://docs.endpoints.anyscale.com/][API key]] |
91-
| PrivateGPT | [[https://github.com/zylon-ai/private-gpt#-documentation][PrivateGPT running locally]] |
92-
| DeepSeek | [[https://platform.deepseek.com/api_keys][API key]] |
93-
| Cerebras | [[https://cloud.cerebras.ai/][API key]] |
94-
| Github Models | [[https://github.com/settings/tokens][Token]] |
95-
| Novita AI | [[https://novita.ai/model-api/product/llm-api?utm_source=github_gptel&utm_medium=github_readme&utm_campaign=link][Token]] |
96-
| xAI | [[https://console.x.ai?utm_source=github_gptel&utm_medium=github_readme&utm_campaign=link][API key]] |
97-
#+html: </div>
98-
9970
** Basic concepts
10071

10172
#+cindex: Large Language Model
@@ -218,7 +189,11 @@ some extra niceties for chat interaction.
218189

219190
** Chat persistence
220191

221-
** The rewrite interface
192+
** TODO The rewrite interface
193+
194+
** TODO gptel in Org mode
195+
196+
gptel offers a few extra conveniences in Org mode.
222197

223198
* TODO gptel's design
224199

@@ -828,9 +803,12 @@ To use tools in gptel, you need
828803
currently include any tool specifications out of the box.
829804

830805
*** Obtaining tools
831-
*** Writing tools
806+
*** TODO Writing tools
832807
:PROPERTIES:
833808
:CUSTOM_ID: writing-tools
809+
:LAST_REVIEW: [2025-09-12 Fri]
810+
:NEXT_REVIEW: [2025-09-12 Fri]
811+
:REVIEWS: 0
834812
:END:
835813

836814
A gptel tool is a structure specifying an Elisp function, the format
@@ -903,6 +881,43 @@ arguments.
903881
subsequent requests in the same buffer. This is primarily useful
904882
in chat buffers.
905883

884+
For example, to not prompt for user confirmation when creating files
885+
in the current working directory but in all other directories:
886+
887+
#+begin_src emacs-lisp
888+
(gptel-make-tool
889+
:name \"create_file\"
890+
:description \"Create a new file with the specified content\"
891+
:confirm (lambda (&rest args)
892+
(cl-destructuring-bind (path filename content)
893+
args
894+
(not (my-filepath-within-current-directory-p path))))
895+
:function (lambda (path filename content)
896+
(let ((full-path (expand-file-name filename path)))
897+
(with-temp-buffer
898+
(insert content)
899+
(write-file full-path))
900+
(format \"Created file %s in %s\" filename path)))
901+
:args (list '(:name \"path\"
902+
:type string
903+
:description \"The directory where to create the file\")
904+
'(:name \"filename\"
905+
:type string
906+
:description \"The name of the file to create\")
907+
'(:name \"content\"
908+
:type string
909+
:description \"The content to write to the file\"))
910+
:category \"filesystem\")
911+
912+
(defun my-filepath-within-current-directory-p (filepath)
913+
\"Return t if FILEPATH is within the current working directory or its subdirectories.
914+
FILEPATH can be relative or absolute, and may or may not end in a slash.\"
915+
(let* ((current-dir-truename (file-truename (file-name-as-directory default-directory)))
916+
(filepath-truename (file-truename (expand-file-name filepath)))
917+
(filepath-dir-truename (file-name-as-directory (file-name-directory filepath-truename))))
918+
(string-prefix-p current-dir-truename filepath-dir-truename)))
919+
#+end_src
920+
906921
**** Specifying tool arguments
907922

908923
Tool arguments are specified in an Elisp format that mirrors the JSON
@@ -2041,13 +2056,87 @@ This is a sentence that will be filled in later.
20412056
:REVIEWS: 0
20422057
:END:
20432058

2044-
gptel is really the combination of two libraries: the request API and the =gptel= UI. gptel's opinionated UI -- the chat buffer, the transient menus, the presentation of tool calls and so on -- comprise one way of using gptel, but it is certainly not the only one.
2059+
gptel is really the combination of two libraries: the request API and
2060+
the =gptel= UI. For convenience both are made available in a single
2061+
Emacs package. gptel's opinionated UI -- the chat buffer, the
2062+
transient menus, the presentation of tool calls and so on -- comprise
2063+
one way of using gptel, but it is certainly not the only one.
2064+
2065+
Accordingly, this cookbook has two sections. [[*Extending gptel's UI]]
2066+
describes how to customize gptel's UIs beyond simply setting user
2067+
options, and [[*Building applications with ~gptel-request~]] covers the
2068+
use of gptel's API for specialized LLM interactions.
2069+
2070+
** TODO Extending gptel's UI
2071+
2072+
*** Improving the chat buffer experience
2073+
2074+
A "chat buffer" is any text, Markdown or Org mode buffer where
2075+
~gptel-mode~ is turned on.
2076+
2077+
**** Resume chat sessions more robustly
2078+
2079+
gptel adds metadata to a chat buffer when saving it to a file. Among
2080+
other information, this metadata includes the model, backend and tools
2081+
in use, as well as the response boundaries. When opening this file,
2082+
~gptel-mode~ is not automatically enabled, so modifying the buffer can
2083+
cause the recorded response boundaries to go out of sync.
2084+
2085+
~gptel-mode~ can be automatically enabled on opening the file by
2086+
adding a [[info:emacs#Specifying File Variables][property-line]] at the top of the file, like
2087+
2088+
#+begin_org
2089+
# -*- eval: (gptel-mode 1) -*-
2090+
#+end_org
2091+
2092+
We can get gptel to include this line automatically as follows:
2093+
2094+
#+begin_src emacs-lisp
2095+
(defun gptel-mode-auto-enable ()
2096+
"Ensure that this file opens with `gptel-mode' enabled."
2097+
(save-excursion
2098+
(let ((enable-local-variables t)) ; Ensure we can modify local variables
2099+
(if (and (save-excursion
2100+
(goto-char (point-min))
2101+
(looking-at ".*-\\*-"))) ; If there's a -*- line
2102+
;; First remove any existing eval, then add the new one
2103+
(modify-file-local-variable-prop-line
2104+
'eval nil 'delete))
2105+
;; Always add our eval
2106+
(add-file-local-variable-prop-line
2107+
'eval '(and (fboundp 'gptel-mode) (gptel-mode 1))))))
2108+
2109+
(add-hook 'gptel-save-state-hook #'gptel-mode-auto-enable)
2110+
#+end_src
2111+
2112+
Note that this will overwrite any other =eval= local variable
2113+
specification already present on the line.
2114+
2115+
**** Automatically persist chats to disk
2116+
2117+
*** Extending gptel's Transient menus
2118+
2119+
** TODO Building applications with ~gptel-request~
2120+
2121+
The entry point to the request library is the ~gptel-request~
2122+
function, which presents a unified way to interact with any LLM that
2123+
gptel supports. It can be used as a building block for custom
2124+
commands that live in your configuration, for custom workflows, or
2125+
even to build complex packages.
2126+
2127+
If you intend to use ~gptel-request~ to write specialized LLM
2128+
interaction commands or build a different UI, you can require only the
2129+
=gptel-request= feature:
2130+
2131+
#+begin_src emacs-lisp
2132+
(require 'gptel-request)
2133+
#+end_src
20452134

2046-
The entry point to the request library is the ~gptel-request~ function, which presents a unified way to interact with any LLM that gptel supports. It can be used as a building block for custom commands that live in your configuration, custom workflows, or even to build complex packages.
2135+
This way you avoid loading unnecessary code, such as gptel's chat buffer UI or Transient menus.
20472136

20482137
By way of examples, this chapter describes how to do these things with ~gptel-request~.
20492138

2050-
** Simple ~gptel-request~ commands
2139+
*** Simple ~gptel-request~ commands
20512140

20522141
gptel provides gptel-request, a lower level function, to query ChatGPT with custom behavior. It accepts a prompt to send to the the active ~gptel-model~, along with several keyword arguments that modify what will be sent and how the response will be handled:
20532142

@@ -2096,7 +2185,7 @@ It is not recommended to grab the buffer contents as a string, as this will caus
20962185

20972186
We can now write our first (admittedly useless) custom command:
20982187

2099-
** Building an application
2188+
*** Building an application
21002189

21012190
#+INCLUDE: ../README.org::*FAQ :minlevel 1
21022191
#+INCLUDE: ../README.org::*Alternatives :minlevel 1

0 commit comments

Comments
 (0)