Add completion provider customization#277
Conversation
|
Why did you remove all of the keybindings? Some of which were useful Detailsdiff --git a/ellama-blueprint.el b/ellama-blueprint.el
index 7210061..896e6f8 100644
--- a/ellama-blueprint.el
+++ b/ellama-blueprint.el
@@ -44,14 +44,19 @@
(ellama-transient-set-system-from-buffer)
(kill-buffer (current-buffer)))
+;;;###autoload
+(defun ellama-blueprint-chat-with-system-kill-buffer ()
+ "Chat with the system message from the current blueprint and kill the buffer."
+ (interactive)
+ (let ((buf (current-buffer)))
+ (ellama-chat-with-system-from-buffer)
+ (kill-buffer buf)))
+
(defvar-keymap ellama-blueprint-mode-map
:doc "Local keymap for Ellama blueprint mode buffers."
:parent global-map
- "C-c C-c" #'ellama-send-buffer-to-new-chat-then-kill
- "C-c C-k" #'ellama-kill-current-buffer
- "C-c y" #'ellama-blueprint-set-system-kill-buffer
- "C-c c" #'ellama-blueprint-create
- "C-c v" #'ellama-blueprint-fill-variables)
+ "C-c C-c" #'ellama-transient-blueprint-mode-menu
+ "C-c C-k" #'ellama-kill-current-buffer)
(defvar ellama-blueprint-font-lock-keywords
'(("{\\([^}]+\\)}" 1 'font-lock-keyword-face))
@@ -66,8 +71,28 @@
:group 'ellama
(setq font-lock-defaults '((("{\\([^}]+\\)}" 1 font-lock-keyword-face t))))
(setq header-line-format
- (substitute-command-keys
- "`\\[ellama-send-buffer-to-new-chat-then-kill]' to send `\\[ellama-kill-current-buffer]' to cancel `\\[ellama-blueprint-set-system-kill-buffer]' to set system `\\[ellama-blueprint-create]' to create new blueprint `\\[ellama-blueprint-fill-variables]' to fill variables")))
+ (concat
+ (propertize
+ (substitute-command-keys
+ "`\\[ellama-transient-blueprint-mode-menu]' to continue")
+ 'help-echo "mouse-1: show menu"
+ 'mouse-face 'header-line-format
+ 'face 'ellama-context-line-face
+ 'keymap (let ((m (make-sparse-keymap)))
+ (define-key m [header-line mouse-1] #'ellama-transient-blueprint-mode-menu)
+ (define-key m [mode-line mouse-1] #'ellama-transient-blueprint-mode-menu)
+ m))
+ " "
+ (propertize
+ (substitute-command-keys
+ "`\\[ellama-kill-current-buffer]' to cancel")
+ 'help-echo "mouse-1: kill buffer"
+ 'mouse-face 'header-line-format
+ 'face 'ellama-context-line-face
+ 'keymap (let ((m (make-sparse-keymap)))
+ (define-key m [header-line mouse-1] #'ellama-kill-current-buffer)
+ (define-key m [mode-line mouse-1] #'ellama-kill-current-buffer)
+ m)))))
(defvar ellama-blueprint-buffer "*ellama-blueprint-buffer*"
"Buffer for prompt blueprint.")
diff --git a/ellama-transient.el b/ellama-transient.el
index 7ba878d..6213244 100644
--- a/ellama-transient.el
+++ b/ellama-transient.el
@@ -301,6 +301,22 @@ Otherwise, prompt the user to enter a system message."
("n" "New blueprint" ellama-blueprint-new)]
["Quit" ("q" "Quit" transient-quit-one)]])
+;;;###autoload
+(transient-define-prefix ellama-transient-blueprint-mode-menu ()
+ ["Blueprint Commands"
+ ["Chat"
+ ("c" "Send to chat" ellama-send-buffer-to-new-chat-then-kill)]
+ ["System Message"
+ ("s" "Set system and chat" ellama-blueprint-chat-with-system-kill-buffer)
+ ("S" "Set system and quit" ellama-blueprint-set-system-kill-buffer)]
+ ["Create"
+ ("C" "Create new blueprint from buffer" ellama-blueprint-create)]
+ ["Variables"
+ ("v" "Fill variables" ellama-blueprint-fill-variables)]
+ ["Quit"
+ ("k" "Kill" ellama-kill-current-buffer)
+ ("q" "Quit" transient-quit-one)]])
+
;;;###autoload
(transient-define-prefix ellama-transient-main-menu ()
"Main Menu."
diff --git a/ellama.el b/ellama.el
index d4b70a4..27b70ef 100644
--- a/ellama.el
+++ b/ellama.el
@@ -1636,6 +1636,20 @@ the full response text when the request completes (with BUFFER current)."
:filter (when (derived-mode-p 'org-mode)
#'ellama--translate-markdown-to-org-filter)))))))
+;;;###autoload
+(defun ellama-chat-with-system-from-buffer ()
+ "Start a new chat session with a system message created from the current buffer."
+ (interactive)
+ (let* ((prompt (read-string "Prompt: "))
+ (content (buffer-substring-no-properties (point-min) (point-max)))
+ (system (if (derived-mode-p 'org-mode)
+ (ellama-convert-org-to-md content)
+ content)))
+ (ellama-chat
+ prompt
+ t
+ :system system)))
+
(defvar ellama-context-global)
;;;###autoload |
|
Too many keys to show it in header line. You can call all of it from blueprint mode transient menu |
|
I see. You have moved them to the transient menu, I guess? Please add |
C in transient menu |
s in transient menu |
Community blueprint? |
No, in blueprint mode transient menu, |
|
Wow amazing! 🤩 👍
|
31390d6 to
6965b92
Compare
It works for me in corfu. But sometimes nothing of generated completions matches prefix. |
| (when bounds | ||
| (list (car bounds) | ||
| (cdr bounds) | ||
| (ellama-generate-completion-list) |
There was a problem hiding this comment.
ellama-generate-completion-list seems like a "heavy" function.
Since it does some non-trivial work, it would be better to return a reference to a function that conforms to a "completion table" interface, instead of calling it right away.
| (defun ellama-complete-at-point (&rest _) | ||
| "Complete at point using ellama." | ||
| (interactive) | ||
| (while-no-input |
There was a problem hiding this comment.
while-no-input returns t when interrupted, so this seems not ideal. UIs would try to ignore errors, of course, but you might still see them in Messages.
For company specifically, you can try the :company-use-while-no-input t property instead. Corfu just aborts all completion tables on input, though, so it would be compatible with it anyway.
8e86181 to
ac7ea39
Compare
|
Thank you, works great! For posterity, I'm evaluating this small configuration, using Details(progn
(require 'ellama)
(require 'llm-ollama)
(setopt ellama-completion-provider
(make-llm-ollama
:chat-model "qwen2.5:3b"
:default-chat-non-standard-params
'(("num_ctx" . 32768))))
(setq-local completion-at-point-functions '(ellama-complete-at-point)))I noticed two odd usability inconveniences though:
What do you think? |
If we want to avoid lags we need to rewrite completions generation to async instead and manage state. Completions match checks will works on done only, so it will match rarely. Not sure if it will be useful. And we need to carefully handle all edge cases during state management. Sounds scary to me 🙂 |
|
Alright, let me use the current implementation for a day tomorrow for some text buffers, just to see how it feels/goes. |
|
Well, yeah, in the current state I confirm it's not useful, because Ellama sends many requests and generating a single reply takes about 10 seconds (presumably due to the amount of requests). But please don't close, I want to take a look on a weekend at pre-existing state of art in other editors. |
I believe that completing this PR will require considerable time. @s-kostyaev Could you please create a new branch to merge the commit that resolves |
|
@s-kostyaev see #284 |
dd16ca5 to
cba7fb6
Compare
Wrapped the completion logic in `while-no-input` to ensure it doesn't block Emacs UI. This allows for a smoother user experience during completion.
Updated the `ellama-generate-completion-list` function to generate more context-aware completions. The prompt template has been changed to request full sentence completions instead of single-word suggestions. The function now constructs the last word and sentence, ensuring that completions start with these parts. Additionally, the `ellama-complete-at-point` function has been updated to provide a more accurate range for completions.
Updated the ellama-completion-list-prompt-template to specify 2-3 possible completions instead of just 3. The rest of the template remains unchanged.
Refactored `ellama-complete-at-point` to use asynchronous requests for generating completions. Introduced a cache (`ellama-current-completions`) to store and reuse previous completions, reducing redundant API calls. Added a flag (`ellama-async-request-active`) to manage concurrent async operations. The function now processes responses in a success callback and handles errors gracefully.
Added an exit function to the completion handling in `ellama.el` that removes the entry from `ellama-current-completions` hash table when the completion is finished.
Updated instructions for translation, added examples for Russian and German translations.
bb34be3 to
86480d6
Compare
|
Thank you! So, I'm trying it out, but this time I set up (progn
(setq-default ellama-transient-host "8.8.8.8") ; arbitrary ip for testing purposes
(require 'ellama)
(require 'llm-ollama)
(setopt ellama-completion-provider
(make-llm-ollama
:chat-model "qwen2.5:3b"
:default-chat-non-standard-params
'(("num_ctx" . 32768))))
(setq-local completion-at-point-functions '(ellama-complete-at-point)
company-backends '(company-capf)))I get P.S.: also, there seems to be a bug with error reporting, because the error isn't actually being shown, instead Ellama complains about invalid arguments. The error instead can be seen in stacktrace. This one is unrelated to this branch, I see same behavior on master while I've been testing this. |
|
A good tool to use is SSH tunneling in this case. |
|
But what curl is trying to do? |
I don't understand what's happening here, am I missing some context?
|
As mentioned here, it behaves same way with an actual IP with Ollama running. I am unclear what |
Are you able to |
|
That was a good question… the answer is "no" and I'm confused. For the context: the reason I didn't consider Okay, sorry for the noise, I'll have to dig into it. |
Did you also put the correct port in the test command, like |
|
Yeah, it seems ollama by default just blocks requests not coming from localhost. My fault here, I was confused due to seeing a |
That is nice, and probably because of this. |
What's your experience? Is it useful? |
Sorry, I was trying to get it to work at different times during the week, but something always went wrong, and I had very little time to debug it because it is the end of the quarter, so I had lots of stuff to do. I found that Ubuntu Ollama snap is buggy because it doesn't pass env. variables through, which I reported via an email to the maintainer today (apparently snap has no packages bugtracker 🤷♂️), got no reply; found a workaround via launching a snap shell and then inside it the |
|
Sorry for silly question, but where is curl or plz called from? I'm trying to figure out why curl is returning an error despite Ellama being accessible at …and I try to grep for |
It is called by |
|
So, I made it to work. A few problems I noticed offhand:
I'll try to test it IRL tomorrow, but from what I see the completion it seems almost never appears. |
Can you try it on the master branch? I just had this situation and it |
|
Does completion sends whole buffer? I'm judging by this warning: and a long time for Ollama to reply. I think it would be useful to perhaps limit the context to current line or to line above… Or maybe to the number of symbols passed as |
It sends active region or current buffer up to the point. |
We can't rely on |
I see. Well, there couldn't be an active region while you're typing, so it comes down to always sending the full buffer. I'm not sure it's okay though, because text (and code for that matter) buffers can be very large. E.g. |
We can introduce an option to control how large part should we send for completion. |




Added
ellama-completion-providercustom variable to specify the LLM provider for completions. Updatedellama-streamcall inellama-complete-implto use this new provider and modified the filter function to handle prefix trimming correctly.Fix #275