theubie / complex_memory

A KoboldAI-like memory extension for oobabooga's text-generation-webui
GNU Affero General Public License v3.0
107 stars 14 forks source link

Improved keyword search #7

Open Sekoya78 opened 1 year ago

Sekoya78 commented 1 year ago

Hi, I like your plugin very much. I think I made an useful improvement I would like to share with you:

Currently if you have a memory keyword like "AI", it will trigger the memory even if the user is typing "ain't it?". Alone it's not that big of a problem, but when you're having dozens of memory slots like me, many of them with short keywords, it starts to become one. So, I took the liberty to alter your keyword detection code.

in the imports you'll need to add import re

then, replace everything between # create out memory rows and if memory_settings["position"] == "Before Context":

    context_injection = []
    context_found = False
    for pair in pairs:
        if pair["always"]:
            # Always inject it.
            context_injection.append(pair["memory"])
            context_found = True
        else:
            # Check to see if keywords are present.
            keywords = pair["keywords"].lower().split(",")
            user_input_lower = user_input.lower()
            for keyword in keywords:
                if len(keyword.split()) > 1:
                    if keyword in user_input_lower:
                        context_injection.append(pair["memory"])
                        context_found = True
                        break  # exit the loop if a match is found
                else:
                    if re.search(r'\b{}\b'.format(keyword.strip()), user_input_lower):
                        # keyword is present in user_input
                        context_injection.append(pair["memory"])
                        context_found = True
                        break  # exit the loop if a match is found

    # Add the context_injection
    if context_found:
        context_injection_string = f"\n{state['name2']}'s important memories: " + (' '.join(context_injection)).strip()
    else:
        context_injection_string = ''

My python skills are terrible, you can likely concatenate those strings better, but that's the gist of it. What it does:

  1. If the keyword is composed of 2 or more words, it'll use your method and just look into the user_input to see if it's there.
  2. If the keyword is a singular word, it'll use a regex expression to separate the user_input into individual words so keywords like AI will only load a memory if "AI" was actually typed.
  3. It automatically takes care of the punctuation "AI!" and "AI?" will still be detected properly.

Additionally, I've noticed that using this format: bot's important memories: $list was working extremely well.

My apologies for not doing a pull request.

theubie commented 1 year ago

I like the regex use, and I should have done that from the start.

The addition of the string before the memory is something that I think would be better implemented as an option. I'll look at adding both of these this week.