branch: elpa/gptel
commit c2a4a14a8393e24c847ecbd841e2cdd68738915f
Author: Karthik Chikmagalur <[email protected]>
Commit: Karthik Chikmagalur <[email protected]>
gptel: Send all links, remove "standalone" requirement
When `gptel-track-media' is non-nil, all linked files are now
included with the prompt in gptel chat buffers. The "standalone"
link requirement has proved to be confusing and unintuitive, and
the new link annotation system avoids most of the ambiguity.
* NEWS (0.9.9.3-pre) (Breaking changes, New features and UI
changes): Document change.
* README.org (Including media with requests): Simplify description
of file inclusion via links.
* gptel-org.el (gptel-org-validate-link): Change the default to always.
(gptel--parse-media-links): Tweak wording.
* gptel-request.el (gptel-track-media): Simplify description,
remove reference to standalone links.
(gptel-markdown-validate-link): Change the default to always
(gptel--parse-media-links): Tweak wording.
* gptel-transient.el (gptel--infix-track-media): Simplify
description, remove reference to standalone links.
* gptel.el (gptel--annotate-link): Tweak wording.
(gptel-use-header-line): Tweak wording.
---
NEWS | 34 ++++++++++++++---------
README.org | 79 ++++++++++++------------------------------------------
gptel-org.el | 18 +++++++------
gptel-request.el | 48 +++++++++++++--------------------
gptel-transient.el | 10 +++----
gptel.el | 15 +++++------
6 files changed, 78 insertions(+), 126 deletions(-)
diff --git a/NEWS b/NEWS
index c7dfb66d63f..f65fc309af1 100644
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,21 @@
** Breaking changes
+- Link handling in gptel chat buffers has changed, hopefully for the
+ better. When ~gptel-track-media~ is non-nil, gptel follows links in
+ the prompt and includes their contents with queries. Previously,
+ links to files had to be placed "standalone", surrounded by blank
+ lines, for the files to be included in the prompt. This limitation
+ has been removed -- all supported links in the prompt will be followed
+ now.
+
+ The "standalone" limitation was imposed to make included links stand
+ out visually and avoid accidental inclusions, but in practice users
+ were often confused about whether a link would be sent. gptel now
+ prominently annotates links that will be followed and sent (see
+ below), so it should be visually obvious when links will be followed.
+ You can revert to the old behavior by customizing gptel, see below.
+
- The model =claude-3-sonnet-20240229= has been removed from the default
list of Anthropic models. This model is no longer available in the
Anthropic API.
@@ -51,18 +66,13 @@
the link tooltip explains why. Links that will be sent are explicitly
indicated as well.
-- New user options ~gptel-org-validate-link~ and
- ~gptel-markdown-validate-link~: When including links to files in the
- prompt via ~gptel-track-media~, only "standalone" links are included
- by default -- these are links placed on a line by themselves,
- separated from other text. This is to ensure that the file is being
- included intentionally.
-
- This behavior is now customizable in Markdown/Org buffers via these
- options. Its value should be a function that determines if a link is
- to be considered valid for inclusion with the gptel query. You can
- set it to the function ~always~ to try to send all links, irrespective
- of their placement.
+- New user options ~gptel-markdown-validate-link~ and
+ ~gptel-org-validate-link~: These control whether links in Markdown/Org
+ buffers are followed and their sources included in gptel's prompt.
+ Their value should be a function that determines if a link is to be
+ considered valid for inclusion with the gptel query. By default they
+ allow all links, but they can be customized to require "standalone"
+ link placement, which is gptel's past behavior.
- gptel preset specifications can now modify the current values of gptel
options instead of replacing them, allowing better composition of
diff --git a/README.org b/README.org
index e5ce8a3ae43..ec0951db7c2 100644
--- a/README.org
+++ b/README.org
@@ -1279,7 +1279,7 @@ You can also define a "preset" bundle of options that are
applied together, see
gptel supports sending media in Markdown and Org chat buffers, but this
feature is disabled by default.
- You can enable it globally, for all models that support it, by setting
=gptel-track-media=.
-- Or you can set it locally, just for the chat buffer, via the header line:
+- Or you can set it locally, just for the chat buffer, via the header line or
gptel's transient menu:
#+html: <img
src="https://github.com/user-attachments/assets/91f6aaab-2ea4-4806-9cc9-39b4b46a8e6c"
align="center" alt="Image showing a gptel chat buffer's header line with the
button to toggle media support">
@@ -1287,72 +1287,27 @@ gptel supports sending media in Markdown and Org chat
buffers, but this feature
There are two ways to include media or plain-text files with requests:
-1. Adding media files to the context with =gptel-add-file=, described further
below.
-2. Including links to media in chat buffers, described here:
+1. Add files to gptel's context with =gptel-add-file=, described further below.
-To include plain-text files, images or other supported document types with
requests in chat buffers, you can include links to them in the chat buffer.
Such a link must be "standalone", i.e. on a line by itself surrounded by
whitespace.
+2. Include links to media in chat buffers. gptel will annotate the link to
indicate that the linked files will be sent along with the prompt. If a link
cannot be sent for some reason, that will be indicated too, and the reason will
be shown in a tooltip:
-In Org mode, for example, the following are all *valid* ways of including an
image with the request:
+#+html: <img width="848" height="336" alt="Image showing a gptel chat buffer
with annotated links, two of which are marked with SEND. A third link will not
be sent, and the echo area contains an explanation for why."
src="https://github.com/user-attachments/assets/00fd0187-f964-4f55-a392-0a1562bb9118"
align="center"/>
-- "Standalone" file links:
-#+begin_src
-In this yaml file, I have some key-remapping configuration:
+Most ways of specifying links to files/URLs are respected by gptel:
-[[file:/path/to/remap.yaml]]
+- In Markdown mode:
+ + =[](file:///path/to/file.txt)= and =[](/path/to/file.txt)=
+ + =[Description](file:///path/to/file.txt)= and
=[Description](/path/to/file.txt)=
+ + =<file:///path/to/file.txt>=
+ "Plain" links of the form =file:///path/to/file.txt= will not be recognized.
+- In Org mode:
+ + =[[file:/path/to/file.txt]]=
+ + =[[file:/path/to/file.txt][Description]]=
+ + =<file:/path/to/file.txt>=
+ + =[[attachment:data.txt]]=
+ "Plain" links of the form =file:/path/to/file.txt= will not be recognized.
-Could you explain what it does, and which program might be using it?
-#+end_src
-
-#+begin_src
-Describe this picture
-
-[[file:/path/to/screenshot.png]]
-
-Focus specifically on the text content.
-#+end_src
-
-- "Standalone" file link with description:
-#+begin_src
-Describe this picture
-
-[[file:/path/to/screenshot.png][some picture]]
-
-Focus specifically on the text content.
-#+end_src
-
-- "Standalone", angle file link:
-#+begin_src
-Describe this picture
-
-<file:/path/to/screenshot.png>
-
-Focus specifically on the text content.
-#+end_src
-
-The following links are *not valid*, and the text of the link will be sent
instead of the file contents:
-
-- Inline link:
-#+begin_src
-Describe this [[file:/path/to/screenshot.png][picture]].
-
-Focus specifically on the text content.
-#+end_src
-
-- Link not "standalone":
-#+begin_src
-Describe this picture:
-[[file:/path/to/screenshot.png]]
-Focus specifically on the text content.
-#+end_src
-
-- Not a valid Org link:
-#+begin_src
-Describe the picture
-
-file:/path/to/screenshot.png
-#+end_src
-
-Similar criteria apply to Markdown chat buffers.
+Support for custom Org link types is planned.
#+html: </details>
#+html: <details><summary>
diff --git a/gptel-org.el b/gptel-org.el
index 06a2bf79efc..d12d50bcd47 100644
--- a/gptel-org.el
+++ b/gptel-org.el
@@ -168,7 +168,7 @@ adding elements to this list can significantly slow down
:group 'gptel
:type '(repeat symbol))
-(defcustom gptel-org-validate-link #'gptel-org--link-standalone-p
+(defcustom gptel-org-validate-link #'always
"Validate links to be sent as context with gptel queries.
When `gptel-track-media' is enabled, this option determines if a
@@ -180,14 +180,14 @@ them).
It should be a function that accepts an Org link object and return
non-nil if the link should be followed.
-By default, links are considered valid if they are placed on a line by
-themselves, separated from surrounding text. This is to ensure that
-links to be sent are intentionally placed. You can set it to the
-function `always' to try to send all links."
+By default, all links are considered valid.
+
+Set this to `gptel-org--link-standalone-p' to only follow links placed
+on a line by themselves, separated from surrounding text."
:group 'gptel
:type '(choice
- (const :tag "Standalone links" gptel-org--link-standalone-p)
(const :tag "All links" always)
+ (const :tag "Standalone links" gptel-org--link-standalone-p)
(function :tag "Function")))
(defconst gptel-org--link-regex
@@ -373,7 +373,6 @@ unescapes the remainder."
(min prev-pt (point)) prev-pt))
(goto-char (setq prev-pt backward-progress)))))))
-;; Handle media links in the buffer
(defun gptel-org--link-standalone-p (object)
"Check if link OBJECT is on a line by itself."
(when-let* ((par (gptel-org--element-parent object))
@@ -451,7 +450,10 @@ for inclusion into the user prompt for the gptel request."
((not filep)
(message "Link source not followed for unsupported link type
\"%s\"." type))
((not placementp)
- (message "Ignoring non-standalone link \"%s\"." path))
+ (message (if (eq gptel-org-validate-link
'gptel--link-standalone-p)
+ "Ignoring non-standalone link \"%s\"."
+ "Link %s failed to validate, see
`gptel-org-validate-link'.")
+ path))
((not readablep)
(message "Ignoring inaccessible file \"%s\"." path))
((not supportedp)
diff --git a/gptel-request.el b/gptel-request.el
index 8a239927751..9bdeaeef80d 100644
--- a/gptel-request.el
+++ b/gptel-request.el
@@ -627,31 +627,17 @@ always handled separately."
(defcustom gptel-track-media nil
"Whether supported media in chat buffers should be sent.
-When the active `gptel-model' supports it, gptel can send text, images
-or other media from links in chat buffers to the LLM. To use this, the
-following steps are required.
+When this is non-nil, gptel will send text, images or other media from
+links in chat buffers to the LLM.
-1. `gptel-track-media' (this variable) should be non-nil
-
-2. The LLM should provide vision or document support. (See
-`gptel-make-openai', `gptel-make-anthropic', `gptel-make-ollama' or
-`gptel-make-gemini' for details on how to specify media support for
-models.)
-
-3. Only \"standalone\" links in chat buffers are considered.
-These are links on their own line with no surrounding text.
-Further:
-
-- In Org mode, only files or URLs of the form
- [[/path/to/media][bracket links]] and <angle/link/path>
- are sent.
-
-- In Markdown mode, only files or URLS of the form
- [bracket link](/path/to/media) and <angle/link/path>
- are sent.
+Sending images or other binary media from links requires the
+active `gptel-model' to support it. See `gptel-make-openai',
+`gptel-make-anthropic', `gptel-make-ollama' or `gptel-make-gemini' for
+details on how to specify media support for models.
This option has no effect in non-chat buffers. To include
-media (including images) more generally, use `gptel-add'."
+media (including images) more generally, use `gptel-add' or
+`gptel-add-file'."
:type 'boolean)
(defcustom gptel-use-context 'system
@@ -741,7 +727,7 @@ buffer-locally, or let-bind it around calls to gptel
queries, or via
gptel presets."
:type '(repeat string))
-(defcustom gptel-markdown-validate-link #'gptel--link-standalone-p
+(defcustom gptel-markdown-validate-link #'always
"Validate links to be sent as context with gptel queries.
When `gptel-track-media' is enabled, this option determines if a
@@ -753,13 +739,13 @@ It should be a function that accepts a Markdown link and
return non-nil
if the link should be followed. See `markdown-link-at-pos' for the
structure of a Markdown link object.
-By default, links are considered valid if they are placed on a line by
-themselves, separated from surrounding text. This is to ensure that
-links to be sent are intentionally placed. You can set it to the
-function `always' to try to send all links."
+By default, all links are considered valid.
+
+Set this to `gptel--link-standalone-p' to only follow links placed on a
+line by themselves, separated from surrounding text."
:type '(choice
- (const :tag "Standalone links" gptel--link-standalone-p)
(const :tag "All links" always)
+ (const :tag "Standalone links" gptel--link-standalone-p)
(function :tag "Function"))
:group 'gptel)
@@ -2296,7 +2282,11 @@ for inclusion into the user prompt for the gptel
request."
((not filep)
(message "Link source not followed for unsupported link type
\"%s\"." type))
((not placementp)
- (message "Ignoring non-standalone link \"%s\"." path))
+ (message
+ (if (eq gptel-markdown-validate-link 'gptel--link-standalone-p)
+ "Ignoring non-standalone link \"%s\"."
+ "Link %s failed to validate, see
`gptel-markdown-validate-link'.")
+ path))
((not readablep)
(message "Ignoring inaccessible file \"%s\"." path))
((not supportedp)
diff --git a/gptel-transient.el b/gptel-transient.el
index 6ed53ba523d..4664d1c8e9e 100644
--- a/gptel-transient.el
+++ b/gptel-transient.el
@@ -1321,14 +1321,10 @@ querying the LLM."
:key "-R")
(transient-define-suffix gptel--infix-track-media ()
- "Send media from \"standalone\" links in the prompt.
+ "Send media from links in the prompt.
-When the active `gptel-model' supports it, gptel can send images
-or other media from links in the buffer to the LLM. Only
-\"standalone\" links are considered: these are links on their own
-line with no surrounding text.
-
-What link types are sent depends on the mime-types the model
+gptel can send images or other media from links in the buffer to the
+LLM. What link types are sent depends on the mime-types the model
supports. See `gptel-track-media' for more information."
:description "Send media from links"
:transient t
diff --git a/gptel.el b/gptel.el
index 37d1062d6ac..1560f88fdbd 100644
--- a/gptel.el
+++ b/gptel.el
@@ -447,7 +447,9 @@ queries via OV."
((not filep) "Not a supported link type\
(Only \"file\" or \"attachment\" are supported)")
((not placementp)
- "Not a standalone link. (Separate link from text around it.)")
+ (concat
+ "\nNot a standalone link -- separate link from text around it. \n
(OR)
+Link failed to validate, see `gptel-markdown-validate-link' or
`gptel-org-validate-link'."))
((not readablep) (format "File %s is not readable" path))
((not supportedp) (format "%s does not support binary file %s"
gptel-model path))))))))
@@ -732,12 +734,9 @@ Search between BEG and END."
(if gptel-track-media
(progn
(run-hooks 'gptel-refresh-buffer-hook)
- (message
- (concat
- "Sending media from included links. To include media,
create "
- "a \"standalone\" link in a paragraph by itself,
separated from surrounding text.")))
+ (message "Sending media from included links."))
(without-restriction (gptel--annotate-link-clear))
- (message "Ignoring image links. Only link text will be
sent."))
+ (message "Ignoring links. Only link text will be sent."))
(run-at-time 0 nil #'force-mode-line-update)))
(track-media
(and (gptel--model-capable-p 'media)
@@ -746,12 +745,12 @@ Search between BEG and END."
(buttonize "[Sending media]" toggle-track-media)
'mouse-face 'highlight
'help-echo
- "Sending media from standalone links/urls when
supported.\nClick to toggle")
+ "Sending media from links/urls when supported.\nClick
to toggle")
(propertize
(buttonize "[Ignoring media]" toggle-track-media)
'mouse-face 'highlight
'help-echo
- "Ignoring images from standalone links/urls.\nClick to
toggle"))))
+ "Ignoring media from links/urls.\nClick to toggle"))))
(toggle-tools (lambda (&rest _) (interactive)
(run-at-time 0 nil
(lambda () (call-interactively
#'gptel-tools)))))