emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] externals/llm 7ca20902f2: Add ability to fill prompt variable bac


From: ELPA Syncer
Subject: [elpa] externals/llm 7ca20902f2: Add ability to fill prompt variable backwards (#82)
Date: Tue, 17 Sep 2024 00:58:17 -0400 (EDT)

branch: externals/llm
commit 7ca20902f2546cb46a9efa22d000aa79992b1c07
Author: Andrew Hyatt <ahyatt@gmail.com>
Commit: GitHub <noreply@github.com>

    Add ability to fill prompt variable backwards (#82)
---
 README.org         | 14 ++++++++++++--
 llm-prompt-test.el |  7 +++++++
 llm-prompt.el      | 37 +++++++++++++++++++++++++++++--------
 3 files changed, 48 insertions(+), 10 deletions(-)

diff --git a/README.org b/README.org
index 320fb37833..010a125bb9 100644
--- a/README.org
+++ b/README.org
@@ -252,6 +252,12 @@ variable.  However, a plain list is also acceptable, as is 
a single value.  Any
 single value will not enter into the ticket system, but rather be prefilled
 before any tickets are used.
 
+Values supplied in either the list or generators can be the values themselves,
+or conses.  If a cons, the variable to fill is the =car= of the cons, and the 
=cdr=
+is the place to fill the new value, =front= or =back=.  The =front= is the 
default:
+new values will be appended to the end.  =back= will add new values to the 
start
+of the filled text for the variable instead.
+
 So, to illustrate with this example, here's how the prompt will be filled:
 
   1. First, the ={{tags}}= and ={{instructions}}= will be filled first.  This 
will
@@ -261,8 +267,12 @@ So, to illustrate with this example, here's how the prompt 
will be filled:
      multiplied by ~llm-chat-token-limit~) and exit if exceeded.
   3. Run a lottery with all tickets and choose one of the remaining variables 
to
      fill.
-  4. If the variable won't make the text too large, fill the variable
-     with one entry retrieved from a supplied generator, otherwise ignore.
+  4. If the variable won't make the text too large, fill the variable with one
+     entry retrieved from a supplied generator, otherwise ignore.  These are
+     values are not conses, so values will be appended to the end of the
+     generated text for each variable (so a new variable generated for tags 
will
+     append after other generated tags but before the subsequent "and" in the
+     text.
   5. Goto 2
 
   The prompt can be filled two ways, one using predefined prompt template
diff --git a/llm-prompt-test.el b/llm-prompt-test.el
index 1a472174f5..e0bacd7d18 100644
--- a/llm-prompt-test.el
+++ b/llm-prompt-test.el
@@ -181,6 +181,13 @@ to converge."
                   :var1 '("this is a completely oversized item"
                           "a" "b" "c" "d")))))
 
+(ert-deftest llm-prompt-reverse-filling ()
+  (should (equal "(d c a b)"
+                 (llm-prompt-fill-text
+                  "({{var1}})"
+                  (make-prompt-test-llm)
+                  :var1 '("a" "b" ("c" . back) ("d" . back))))))
+
 (ert-deftest llm-prompt--max-tokens ()
   (cl-flet ((should-have-max-tokens (expected max-pct max-tokens)
               (let ((llm-prompt-default-max-pct max-pct)
diff --git a/llm-prompt.el b/llm-prompt.el
index 9ada2486b9..8d0a93d914 100644
--- a/llm-prompt.el
+++ b/llm-prompt.el
@@ -184,9 +184,14 @@ maximum number of tokens."
 (defun llm-prompt-fill-text (text provider &rest keys)
   "Fill TEXT prompt, with the llm PROVIDER, values from KEYS.
 
-PROVIER is an LLM provider.  KEYS is a plist of variables and
+PROVIDER is an LLM provider.  KEYS is a plist of variables and
 their values, either an actual value, or a list or function.  If
-a function, it should return values via a generator."
+a function, it should return values via a generator.
+
+The values can be strings, or conses.  If conses, the value to use is
+the car, and the cdr can be `front' (the default), or `back', signifying
+where to append the new text to, relative to the already filled values
+from the variable."
   (with-temp-buffer
     (insert text)
     (let* ((final-vals nil)
@@ -239,17 +244,27 @@ a function, it should return values via a generator."
             (while (< total-tokens
                       (llm-prompt--max-tokens provider))
               (let* ((val-cons (iter-next ticket-gen))
-                     (sval (format "%s" (cdr val-cons))))
+                     (var (car val-cons))
+                     (sval (format "%s" (if (consp (cdr val-cons))
+                                            (cadr val-cons)
+                                          (cdr val-cons))))
+                     (add-location (if (consp (cdr val-cons))
+                                       (cddr val-cons) 'front)))
+                (unless (member add-location '(front back))
+                  (error "Add location specification must be one of 'front or 
'back"))
                 ;; Only add if there is space, otherwise we ignore this value.
                 (when (<= (+ total-tokens (llm-count-tokens provider sval))
                           (* (/ llm-prompt-default-max-pct 100.0)
                              (llm-chat-token-limit provider)))
                   (cl-incf total-tokens (llm-count-tokens provider sval))
-                  (if (assoc (car val-cons) final-vals)
-                      (push sval (cdr (assoc (car val-cons) final-vals)))
-                    (push (cons (car val-cons)
-                                (list sval))
-                          final-vals)))))
+                  (if (assoc var final-vals)
+                      (if (eq add-location 'back)
+                          (setf
+                           (cdr (assoc var final-vals))
+                           (nconc (assoc-default var final-vals)
+                                  (list sval)))
+                        (push sval (cdr (assoc var final-vals))))
+                    (push (cons var (list sval)) final-vals)))))
           (iter-end-of-sequence nil)))
       (cl-loop for (var-name . val) in final-vals
                do
@@ -265,6 +280,12 @@ a function, it should return values via a generator."
                                       val)))))
     (buffer-substring-no-properties (point-min) (point-max))))
 
+(defun llm-prompt-get (name)
+  "Return the raw prompt with the given NAME, a symbol.
+The prompt may have variables to fill in, so if so, it should be
+processed with `llm-prompt-fill-text'."
+  (gethash name llm-prompt-prompts))
+
 (defun llm-prompt-fill (name provider &rest keys)
   "Get and fill the prompt for NAME given llm PROVIDER.
 PROVIDER is an provider defined by the `llm' package.  KEYS is a



reply via email to

[Prev in Thread] Current Thread [Next in Thread]