Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Per-gptel-buffer contexts #475

Open
orge-dev opened this issue Nov 14, 2024 · 9 comments
Open

Per-gptel-buffer contexts #475

orge-dev opened this issue Nov 14, 2024 · 9 comments
Labels
enhancement New feature or request

Comments

@orge-dev
Copy link

Describe the solution you'd like
I like to define sets of files/buffers as context, and it would be convenient to have a gptel buffer correspond to a particular set of files as context. So I could have * Claude (No Context) * buffer, * Claude (Project A1) * buffer, *Claude Project A2* ,etc.

Describe alternatives you've considered
An easy way to clear the whole gptel context, plus user defined (gptel-add-file file) functions would serve a similar purpose. I'm not sure how to easily remove all items currently in the context.

Additional context
Thanks for creating and maintaining gptel!

@orge-dev orge-dev added the enhancement New feature or request label Nov 14, 2024
@karthink
Copy link
Owner

karthink commented Nov 14, 2024

I think I understand what you mean. Let's call it the "buffer-local context sets" feature, because you can have independent sets of context. This feature makes sense in the abstract, but not in the details. Here's why I think it's under-specified:

  1. Suppose you visit some buffer, select a region and run gpel-add to add it to the context.

    • Which gptel buffer's context (context set) should this be added to?
    • How about when there is no chat buffer? gptel is usable in any buffer, and most of the time I don't use a chat buffer.
  2. Same question as 1, but for when you run gptel-add in a dired buffer to add a file.

  3. Suppose you run gptel-add-file, either from the transient menu or via M-x. This command can be run in any buffer. Which context set should it be added to?

I imagine what you're describing is actually "project-local context sets", not "buffer-local context sets". Now each project (as managed by project.el or projectile) has an independent gptel context, and any of the above actions 1-3 will add the region/buffer/file to its project's context. In this case, what happens when you run/want to include a region/buffer/file in project A's context that does not belong to project A?

@metachip
Copy link

metachip commented Nov 24, 2024

Thanks for the reference to this issue @karthink, hcere's my thoughts on the questions you posed to @orge-dev

I have two suggestions.

Multiple Context Buffers

I agree the concept here is "project local" but I would not recommend making it dependent on projectile or similar. Instead, one solution might be to maintain a list of context buffers, and allow them to be selected and associated with chat (or other) buffers as required. There would always still be one global context buffer. It would be the default when a default is required.

For example, when one invokes an action that uses the context, if the context that should be used is indeterminate, use global context. If the context can be inferred, for example, because it has been previously associated with a chat buffer, then use the context associated with that chat buffer instead of the global context. I imagine another widget at the top of the chat buffer would make this selection easy.

If an action is taken from an arbitrary buffer, to add new context, pop open a list of context buffers to enable the choice of target, prior to taking the action to add the new context to it. The default action, if nothing is otherwise selected, would be to add the new context to the default context buffer.

Likewise in the gptel menu, one might allow the selection of what the current default context buffer is, so that when using gptel in an arbitrary buffer, one has the option to change the default without deleting and manually rebuilding to the new context.

Context Links

Instead of including context by way of separate buffers, one could instead use links. This would especially apply when one is using org mode to have a dialogue with a model but need not be limited in this way. I've outlined my thinking on this further here.

#481

The bottom line for me is that context is fundamentally important, especially given the extremely flexible way you've designed gptel to work "anywhere" across emacs. Being able to easily associate the "right context" with myriad concurrent tasks that I'm working on across emacs, whether in chat buffers or anywhere else, would be fantastic.

[2024-11-24 Sun 18:25]

@karthink
Copy link
Owner

This proposal for multiple context buffers is going to be confusing to most users. I would prefer gptel-add and co to be a one-shot interaction -- every additional decision the user has to make when taking a gptel action will annoy them, as evidenced by past threads like #374 (among others). If we can find a way to make gptel-add Do The Right Thing in all situations I wouldn't mind working on this.

I like the context link proposal in #481 --it's a very simple mental model that I expect users won't have trouble following. let's discuss this in the dedicated thread.

@dwrz
Copy link

dwrz commented Nov 25, 2024

I am a new user to gptel -- thank you for all your work on it. I have been really happy with my experience so far, but this issue is the first limitation I felt I ran into. Would it be possible to just have a singular buffer local context?

I may have a chat going on for one project, another for another project, another for a topic, and then I may throw a quick question into scratch, and so on. When switching across these, if I need to use context, I have` to dump the context, and then rebuild it -- and in some cases that can be quite a few files. For me, having the context be buffer local would be sufficient, but perhaps I am not thinking about all the use cases -- the only one I can think of is jumping to different files to ask for a refactor / rewrite; you'd have to still rebuild your context.

The only other thing I can think of is being able to assign contexts to variables, and then pull them up by history the same way we can with past directives.

@karthink
Copy link
Owner

@dwrz I feel the pain of dumping and rebuilding the context all the time. I just don't know how to resolve it.

Buffer-local context does not work because it's ambiguous which buffer's context is being added to when you run gptel-add.

As suggested by @metachip, one way to solve this is to simply ask the user which context set they want to add to. My experiences with this kind of branching in gptel suggests that it's going to be more annoying than useful, and quite confusing too, leading to doubts like:

  • "Wait, which context set is active right now?"
  • "Did I add the file to the right context set?"
    It also requires gptel to maintain an internal registry of all active context sets, invalidate this registry etc.

I like the idea of using Org/markdown links to add to the context, as discussed in #481, as the context set automatically becomes buffer-local, transparent and easily editable. But that has other issues, including that you can't have "live" buffer regions in the context.

@metachip
Copy link

This proposal for multiple context buffers is going to be confusing to most users. I would prefer gptel-add and co to be a one-shot interaction -- every additional decision the user has to make when taking a gptel action will annoy them, as evidenced by past threads like #374 (among others). If we can find a way to make gptel-add Do The Right Thing in all situations I wouldn't mind working on this.

Agreed. It needs to be DWIM as far as possible.

  1. Can you not just use the prefix argument C-u ?

    That is, always add/remove context from the global context, if gptel-add* called directly or via the transient menu.

    If called directly with a prefix argument, it pops open the list of available context buffers and allows one to create a new one, just like gptel does now with respect to chat buffers and their names.

    Existing users will be none the wiser and gptel-add remains a one-shot operation.

  2. Add another widget to the top of chat buffers to indentify which context is being used.

    This would only show if the context is not the default.

    You could merge it into the context widget you already have, which in addition to reporting the files and regions, says the name of the context too.

@dwrz

I have` to dump the context, and then rebuild it -- and in some cases that can be quite a few files.

For me this is at the very heart of the problem that we are discussing here.

  1. The idea of context, local to a chat buffer as you suggest is one solution.

  2. The association of one, of several named context buffers, to a chat buffer, is another. This is my preferred solution.

  3. Context that appears in a buffer at the moment, could, for any org mode buffer, be put in a drawer called (say) :CONTEXT: (analogous to the special case of :PROPERTIES: for properties.

All that said, I think links in a buffer may be a better solution per #481.

I'll continue my thoughts in that thread.

@karthink
Copy link
Owner

karthink commented Nov 25, 2024

Can you not just use the prefix argument C-u ?

There is quite a bit more to it than that. For example, it causes ambiguity in the indication of the current context in the transient menu and in constructing the context inspection buffer (which context set is looked up?). There's no longer a single source for the *gptel-context* buffer, compounding the update problems discussed in #482.

I also think you are underestimating the amount of confusion an opaque many-to-one associative map from buffers to context sets will cause when using gptel. It will be something you have to keep double-checking before sending requests, especially from non-chat buffers ("Am I using the right context set here?"). In this specific aspect having "project-local" context sets works a little better -- this is also a many-to-one map but people are already used to thinking this way about collections of files/buffers.

@metachip
Copy link

metachip commented Nov 25, 2024

I also think you are underestimating the amount of confusion an opaque many-to-one associative map from buffers to context sets will cause when using gptel.

Fair enough. I think links are better anyway because they would be more explicit in terms of the context one is working with.

I have some thoughts about the questions you have raise about links which I will answer in that ticket shortly.

@dwrz
Copy link

dwrz commented Nov 25, 2024

@karthink -- thank you! I'm starting to see that there's much more to it than what a first impression suggests.

What about the possibility of using variables to store contexts?

For example:

(setq my-context-a '("/home/user/some-file" "/home/user/some-file-2" "/home/user/some-file-3"))
(setq my-context-b '("/etc/foo" "/etc/bar" "/etc/baz"))
(setq gptel-contexts '(my-context-a my-context-b))

Then in the transient menu, either let the user build a context as is currently possible, or load one from a submenu, as is possible for directives. Could something like that work?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

4 participants