branch: externals/minuet
commit 64240457eb4868af8ae614c304a5691f1f6fc43d
Author: milanglacier <d...@milanglacier.com>
Commit: GitHub <nore...@github.com>

    feat!: Implement Prefix-First prompt structure for Gemini (#36)
    
    - Add a new "Prefix-First" prompt structure for chat LLMs.
    - Modified the Gemini provider's default prompt strategy to use this new
      structure.
    - Other providers will continue to use their previous default prompt
      configurations.
---
 README.md | 15 +++--------
 minuet.el | 35 +++++++++++++++++++++-----
 prompt.md | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++-------------
 3 files changed, 100 insertions(+), 36 deletions(-)

diff --git a/README.md b/README.md
index a69c966b95..3180051fe5 100644
--- a/README.md
+++ b/README.md
@@ -23,7 +23,6 @@
   - [Claude](#claude)
   - [Codestral](#codestral)
   - [Gemini](#gemini)
-    - [Experimental Configuration](#experimental-configuration)
   - [OpenAI-compatible](#openai-compatible)
   - [OpenAI-FIM-Compatible](#openai-fim-compatible)
 - [Troubleshooting](#troubleshooting)
@@ -476,12 +475,12 @@ The following config is the default.
       :api-key "GEMINI_API_KEY"
       :system
       (:template minuet-default-system-template
-       :prompt minuet-default-prompt
+       :prompt minuet-default-prompt-prefix-first
        :guidelines minuet-default-guidelines
        :n-completions-template minuet-default-n-completion-template)
-      :fewshots minuet-default-fewshots
+      :fewshots minuet-default-fewshots-prefix-first
       :chat-input
-      (:template minuet-default-chat-input-template
+      (:template minuet-default-chat-input-template-prefix-first
        :language-and-tab minuet--default-chat-input-language-and-tab-function
        :context-before-cursor minuet--default-chat-input-before-cursor-function
        :context-after-cursor minuet--default-chat-input-after-cursor-function)
@@ -512,14 +511,6 @@ settings following the example:
 
 </details>
 
-### Experimental Configuration
-
-Gemini appears to perform better with an alternative input structure, unlike
-other chat-based LLMs. This observation is currently experimental and requires
-further validation. For details on the experimental prompt setup currently in
-use by the maintainer, please refer to the
-[prompt 
documentation](./prompt.md#an-experimental-configuration-setup-for-gemini).
-
 ## OpenAI-compatible
 
 Use any providers compatible with OpenAI's chat completion API.
diff --git a/minuet.el b/minuet.el
index 844e691f7f..97066cfb08 100644
--- a/minuet.el
+++ b/minuet.el
@@ -164,7 +164,7 @@ guarantee the exact number of completion items specified, 
as this
 parameter serves only as a prompt guideline.  The default is `3`."
   :type 'integer)
 
-(defvar minuet-default-prompt
+(defvar minuet-default-prompt-prefix-first
   "You are the backend of an AI-powered code completion engine. Your task is to
 provide code suggestions based on the user's input. The user's code will be
 enclosed in markers:
@@ -172,11 +172,15 @@ enclosed in markers:
 - `<contextAfterCursor>`: Code context after the cursor
 - `<cursorPosition>`: Current cursor location
 - `<contextBeforeCursor>`: Code context before the cursor
+"
+  "The default prefix style prompt for minuet completion.")
 
+(defvar minuet-default-prompt
+  (concat minuet-default-prompt-prefix-first
+          "
 Note that the user's code will be prompted in reverse order: first the code
 after the cursor, then the code before the cursor.
-"
-  "The default prompt for minuet completion.")
+") "The default prefix-first style prompt for minuet completion.")
 
 (defvar minuet-default-guidelines
   "Guidelines:
@@ -207,6 +211,14 @@ after the cursor, then the code before the cursor.
 {{{:context-before-cursor}}}<cursorPosition>"
   "The default template for minuet chat input.")
 
+(defvar minuet-default-chat-input-template-prefix-first
+  "{{{:language-and-tab}}}
+<contextBeforeCursor>
+{{{:context-before-cursor}}}<cursorPosition>
+<contextAfterCursor>
+{{{:context-after-cursor}}}"
+  "The default prefix-first style template for minuet chat input.")
+
 (defvar minuet-default-fewshots
   `((:role "user"
      :content "# language: python
@@ -234,6 +246,17 @@ def fibonacci(n):
 <endCompletion>
 ")))
 
+(defvar minuet-default-fewshots-prefix-first
+  `((:role "user"
+     :content "# language: python
+<contextBeforeCursor>
+def fibonacci(n):
+    <cursorPosition>
+<contextAfterCursor>
+
+fib(5)")
+    ,(cadr minuet-default-fewshots)))
+
 (defvar minuet-claude-options
   `(:model "claude-3-5-haiku-20241022"
     :max_tokens 512
@@ -311,12 +334,12 @@ def fibonacci(n):
     :api-key "GEMINI_API_KEY"
     :system
     (:template minuet-default-system-template
-     :prompt minuet-default-prompt
+     :prompt minuet-default-prompt-prefix-first
      :guidelines minuet-default-guidelines
      :n-completions-template minuet-default-n-completion-template)
-    :fewshots minuet-default-fewshots
+    :fewshots minuet-default-fewshots-prefix-first
     :chat-input
-    (:template minuet-default-chat-input-template
+    (:template minuet-default-chat-input-template-prefix-first
      :language-and-tab minuet--default-chat-input-language-and-tab-function
      :context-before-cursor minuet--default-chat-input-before-cursor-function
      :context-after-cursor minuet--default-chat-input-after-cursor-function)
diff --git a/prompt.md b/prompt.md
index 12740910c9..3f2d2d5499 100644
--- a/prompt.md
+++ b/prompt.md
@@ -7,7 +7,7 @@
   - [Default Few Shots Examples](#default-few-shots-examples)
   - [Default Chat Input Example](#default-chat-input-example)
   - [Customization](#customization)
-  - [An Experimental Configuration Setup for 
Gemini](#an-experimental-configuration-setup-for-gemini)
+  - [A Practical Example](#a-practical-example)
 
 # FIM LLM Prompt Structure
 
@@ -36,12 +36,41 @@ incorporate the necessary special tokens within the prompt 
function.
 
 # Chat LLM Prompt Structure
 
+We utilize two distinct strategies when constructing prompts:
+
+1. **Prefix First Style**: This involves including the code preceding the 
cursor
+   initially, followed by the code succeeding the cursor. This approach is used
+   only for the **Gemini** provider.
+
+2. **Suffix First Style**: This method involves including the code following 
the
+   cursor initially, and then the code preceding the cursor. It is employed for
+   **other** providers such as OpenAI, OpenAI-Compatible, and Claude.
+
+The counterpart variables are:
+
+1. `minuet-default-prompt` and `minuet-default-prompt-prefix-first`.
+2. `minuet-default-fewshots` and `minuet-default-fewshots-prefix-first`.
+3. `minuet-default-chat-input-template` and
+   `minuet-default-chat-input-template-prefix-first`.
+
 ## Default Template
 
 `{{{:prompt}}}\n{{{:guidelines}}}\n{{{:n_completion_template}}}`
 
 ## Default Prompt
 
+**Prefix First Style**:
+
+You are the backend of an AI-powered code completion engine. Your task is to
+provide code suggestions based on the user's input. The user's code will be
+enclosed in markers:
+
+- `<contextAfterCursor>`: Code context after the cursor
+- `<cursorPosition>`: Current cursor location
+- `<contextBeforeCursor>`: Code context before the cursor
+
+**Suffix First Style**:
+
 You are the backend of an AI-powered code completion engine. Your task is to
 provide code suggestions based on the user's input. The user's code will be
 enclosed in markers:
@@ -77,16 +106,19 @@ Guidelines:
 ## Default Few Shots Examples
 
 ```lisp
-`((:role "user"
-       :content "# language: python
+
+;; suffix-first style
+(defvar minuet-default-fewshots
+  `((:role "user"
+     :content "# language: python
 <contextAfterCursor>
 
 fib(5)
 <contextBeforeCursor>
 def fibonacci(n):
     <cursorPosition>")
-      (:role "assistant"
-       :content "    '''
+    (:role "assistant"
+     :content "    '''
     Recursive Fibonacci implementation
     '''
     if n < 2:
@@ -101,7 +133,18 @@ def fibonacci(n):
         a, b = b, a + b
     return a
 <endCompletion>
-"))
+")))
+
+(defvar minuet-default-fewshots-prefix-first
+  `((:role "user"
+     :content "# language: python
+<contextBeforeCursor>
+def fibonacci(n):
+    <cursorPosition>
+<contextAfterCursor>
+
+fib(5)")
+    ,(cadr minuet-default-fewshots)))
 ```
 
 ## Default Chat Input Example
@@ -111,12 +154,24 @@ The chat input represents the final prompt delivered to 
the LLM for completion.
 The chat input template follows a structure similar to the system prompt and 
can
 be customized using the following format:
 
+**Suffix First Style**:
+
 ```
 {{{:language-and-tab}}}
 <contextAfterCursor>
-{{{:context-after-cursor}}}
+{{{:context_after_cursor}}}
 <contextBeforeCursor>
-{{{:context-before-cursor}}}<cursorPosition>
+{{{:context_before_cursor}}}<cursorPosition>
+```
+
+**Prefix First Style**:
+
+```
+{{{:language-and-tab}}}
+<contextBeforeCursor>
+{{{:context_before_cursor}}}<cursorPosition>
+<contextAfterCursor>
+{{{:context_after_cursor}}}
 ```
 
 Components:
@@ -203,18 +258,13 @@ function fibonacci(n) {
 (plist-put minuet-openai-options :fewshots #'my-minuet-few-shots)
 ```
 
-## An Experimental Configuration Setup for Gemini
-
-Some observations suggest that Gemini might perform better with a
-`Prefix-Suffix` structured input format, specifically
-`Before-Cursor -> Cursor-Pos -> After-Cursor`.
-
-This contrasts with other chat-based LLMs, which may yield better results with
-the inverse structure: `After-Cursor -> Before-Cursor -> Cursor-Pos`.
+## A Practical Example
 
-This finding remains experimental and requires further validation.
+Here, we present a practical example for configuring the prompt for Gemini,
+aiming to reuse existing components of the default prompt wherever possible.
 
-Below is the current configuration used by the maintainer for Gemini:
+Please note that you should not copy-paste this into your configuration, as it
+represents the **default setting** applied to Gemini.
 
 ```lisp
 (use-package minuet

Reply via email to