Closed gerazov closed 7 months ago
Here's how it looks for code:
For greater flexibility, would it be better if the util.show_spinner
method allowed for full customization of all text around the spinner itself? Accepting a table with pre
and post
keys.
E.g. to achieve current functionality (prior to this PR) you would do something like:
local timer = require("ollama.util").show_spinner(bufnr, { pre = "Generating... " })
Then for an action to display the prompt as its created, you could do something like:
show_spinner(bufnr, { pre = parsed_prompt .. "\nGenerating... " })
post
key would be an optional string just like pre
in case, for instance, someone wanted an action that displayed the spinner during the entire generation task - instead of just before the first streamed token.
That makes sense - it would be cool to know when the generation process has ended. I was also thinking that after it's done the > Generating ...
could turn into > model_name
so it visibly splits the prompt from the output. But then we're going towards chat :slightly_smiling_face:
btw I put the >
in Generating
so it's formatted nicely - it's more visible at least in catpuccin.
Feel free to shape it as you will - I implemented it because I needed it to be able to copy and save/edit my prompts :wink:
In what other context do you need to know when generation has ended? The ollama API sends a done
property in its final response - you can see it being used in other actions.
Thinking on it, it might be better if show_spinner
is (optionally) given a line number to display the spinner on, instead of rewriting the entire buffer on each loop. I'll fuss around with it and see what I come up with.
Looks good :love_you_gesture: - maybe have the model name when it's done (even generating?), like: > zephyr in X s
The model name is already in the floating window's title, so I don't think it needs that.
The last thing keeping me from merging this at this point is I'm not sure we should extend the list of built-in actions too much. This seems like a more specific-use case (vs the generalized display, insert/replace, and previews). I wanted to set it up so that users could craft their own highly specialized actions that do exactly what they want.
So what now:
I would highly value your input on this as a user and contributor of the plugin, @gerazov. Let me know what you think!
First the important thing - displaying the prompt is a necessary feature that is currently lacking.
> modelname
leading the response.On increasing the complexity of the code - the actions can really be optimized into one function that displays if needed and includes the prompt in the display if chosen. Because I would have _prompt
work with display_replace
too.
About the roadmap. To tell you the truth I'm leaning even more away from specialized prompts. Currently I have 18 prompts - 12 for text which I forward to a general language model and 6 for code which I forward to codellama
. And at some point it get's hard to remember what exact prompt each of them spawns - any input you have to enter is in a blank input field.
As a user I wouldn't mind having to type a bit of extra words to use less prompts - so in other words fewer generic prompts that you can use for anything you like, and they should be built around the $sel
, $ftype
and $buf
- and one set for text another for code:
Another thing that's currently a problem is that there is no way to iterate on the response, i.e. you can't modify the prompt if you don't like the output. Without the display_prompt
you don't even get to see/copy the prompt you've typed :smile:
And keeping the model name there before the response would make it easy to copy paste the prompt and response for reference. Plus visually it separates the two nicely - if you have a large prompt that includes text/code.
The optimal workflow would be:
opts
)prompt snippets
where the user can <Tab>
between different parts and be able to modify them> model name
leading the responseOne step ahead of this would be a full on chat where the user can follow a response with another prompt in the same popup window and the previous answers get transferred as context (if needed - currently no context is kept between calls to the api no?)
I ramble. Hope it helps :+1:
Good call on reducing the actions into a single configurable base action. As a side effect of that, creating a sort of action 'factory' to achieve this might make it easier for users to tune things with less effort/custom code required.
I also really appreciate you sharing your experiences and workflows. I'm not yet sure how I would implement certain features of your 'optimal workflow' as I'm still fairly new to the neovim APIs, but I will keep it in mind as I continue to R&D.
On the more generic prompts - this was actually my intent with the default prompts: have a small handful of generalized prompts for most tasks, and let users extend the list with their own specialized ones. I admit there's a lot to be improved there. Feel free to open an issue or PR if you have more ideas on that.
In the meantime, I'll update & finally merge this PR with the model name leading the response as you suggested, and then I'll work on refactoring the actions to be less verbose in code.
Awesome :love_you_gesture: keep up the good work :rocket:
It can be useful to have the prompt displayed in the floating window as well, e.g. for the Raw input, but also can give a sense of the exact prompt that is used to query the LLM. To this end I'v added a
display_prompt
action that is a bit more involved than making a custom action - it needs theparsed_prompt
as input, and theshow_spinner
needs to be modified as well.Here it is in action: