karthink / gptel

A simple LLM client for Emacs
GNU General Public License v3.0
1.63k stars 151 forks source link

gptel-mode cannot be properly deactivated. #424

Closed wlauppe closed 1 month ago

wlauppe commented 1 month ago

My mental image for gptel-mode is as follows:

If i have gptel-mode running in a n org file all sorts of functions are activated, and memory structures are being held in memory.

If i turn the mode off, it is deactivated and the single source of truth is the file

Information on which text written by me, and which text is from the LLM is saved in the GPTEL_BOUNDS property, like this.

:GPTEL_BOUNDS: ((346 . 1581) (1646 . 4219) (4301 . 6000))

But apparenttly, even after deactivating gptel-mode, there is still information stored via put-text-property: and when saving the file, some part of the still active gptel-mode overwrites the :GPTEL_BOUNDS: property.

While trying to debug, bug #409 I figured out only way, to change the :GPTEL_BOUNDS: property - even if gptel-mode is deactivated- is do close the buffer and reload the buffer from disk. This doesnt feel right. Do you agree that the behaviour should be changed?

karthink commented 1 month ago

Oversight on my part (I think), thanks for catching that. I removed that behavior when turning off gptel-mode.

That said, if you turn off gptel-mode and continue to edit the buffer, the conversation state will now be out of sync. So it could be that keeping this behavior even after turning off gptel-mode was intentional on my part -- I don't remember!

wlauppe commented 1 month ago

thanks, for the fix! it works great. Out of curiosity, are the annotations you saved via put-text-property also removed if gptel-mode is disabled? I have only seen the

 (remove-hook 'before-save-hook #'gptel--save-state t)

line in the diff, but i didnt experience any malfunction of the code.

karthink commented 1 month ago

No, the text properties stay. They are harmless at worst, so there is no reason to remove them, I think.

And in general, they add an extra layer of redundancy to the chat state. For example, if you turn off gptel-mode in a chat buffer that is not saved to disk, then no GPTEL_BOUNDS are written to the file. If you now turn on gptel-mode again, you need the text properties to distinguish between user prompts and responses. This distinction is lost if you remove the text properties.

wlauppe commented 1 month ago

so my question is, if i enable gptel-mode does it use the :GPTEL_BOUNDS: as i would expect, or does it produce some mangled state, out of the `:GPTEL_BOUNDS:-Property and some internal state still lingering in the text properties from earlier?

wlauppe commented 1 month ago

For example, if you turn off gptel-mode in a chat buffer that is not saved to disk, then no GPTEL_BOUNDS are written to the file. coudnt the :GPTEL_BOUNDS: always be present as property in the org-buffer, even if the buffer is not connected to a file?

karthink commented 1 month ago

For example, if you turn off gptel-mode in a chat buffer that is not saved to disk, then no GPTEL_BOUNDS are written to the file. coudnt the :GPTEL_BOUNDS: always be present as property in the org-buffer, even if the buffer is not connected to a file?

GPTEL_BOUNDS isn't consulted when creating the full prompt to be sent, it's only a state rehydration mechanism for setting up gptel-mode. The text properties are the source of truth for assigning the user/response categories.

For this reason, GPTEL_BOUNDS are only written when saving the buffer to disk.

You are imagining a different system where the text properties are (effectively) unnecessary, and GPTEL_BOUNDS is updated after each request. Besides being slow, it won't work since the buffer can be modified arbitrarily, in ways where you will lose track of the bounds without the auto-updating text properties. And if you need the text properties anyway, there's no need for GPTEL_BOUNDS except to restore the text properties when opening the buffer the first time.

karthink commented 1 month ago

so my question is, if i enable gptel-mode does it use the :GPTEL_BOUNDS: as i would expect, or does it produce some mangled state, out of the `:GPTEL_BOUNDS:-Property and some internal state still lingering in the text properties from earlier?

When gptel-mode runs, it applies the text properties to the response regions specified in GPTEL_BOUNDS if

If there are other regions marked using text properties as gptel responses not included in GPTEL_BOUNDS, they are left untouched.

You cannot produce a mangled state unless you've manually edited the gptel text property, which is not advised.