#ad_discordbot (Fork of Fork of xNul's bot)
1 messages · Page 5 of 1
So:
- trigger: 'Bob'
search_mode: user
format_prompt: 'Information about Bob. {prompt}'
exactly
In my own projects I split history into 2 parts, long term and short.
It's structured a bit like this:
system prompt
long term history
Instructions
Context/RAG/whatever other info
Short term history
Response guide
The short term holds messages since within the last few minutes for example.
The idea was to give the LLM a sense of time, like this is active now.
Response guide means telling the llm to continue a response this can be left empty.
In the tags system is a load_history tag that lets you restrict the number of history shown
load_history: 2 is only the last 2 exchanges
You have my blessing to add or modify the bot in any way including adding/modifying tag behaviors
what do you put in longterm history?
Meant long term memory, but not in the sense of a database or anything.
Like that it's pushed up higher and not in the "active work space"
I like to use instruct finetuned llms, so the "active" area is after the ### instruct heading.
The part that the llm is taking instructions from.
But it still could call apon the above information, it just doesn't influence it as much from my experience.
In terms of reliability to get a model to do something:
-
(best) adding something to the "guide"
In the response section having the LLM write "Here is your X:" and continue
(this is similar to grammar in the way that it restricts what the llm can generate) -
Instruct
This usually works, but the llm could get confused and generate some other reply related to some other part of the instruction and end up not doing what you want. -
context
Like a character card, I would only put stuff here that I want to act like a suggestion to the LLM, it won't always act on it.
how do you approach weight? that concept? how do you give more weight to a chunk of data or less weight
weight or focus, whatever you call it.
like putting XYZ data in system prompt vs NOT etc..
Just chiming in that one of the tags is for state parameter’s so you could actually have a custom continue a ramp
putting it in the begining vs the end
I’m using microphone input by the way
I saw an extension once for assigning weights to tokens similar to stable diffusion, but I havent had the chance to try it.
I was just explaining that prompts in the ### instruct area seem to be weighted more by instruct finetuned llms.
(Also I use ###instruct as an example, I know there are other instruct formats ^-^)
Hey, it worked!
- trigger: 'Bob'
search_mode: user
format_prompt: 'Bob is a sentient Altoid mint. {prompt}'
@Gamemaster, can you tell me about Bob?
Of course it worked everything in the butt works
Bob, as a sentient Altoid mint, is indeed an unusual character. He stands approximately two inches tall and resembles a standard Altoids tin, complete with the iconic design featuring a tooth inside a circle. His exterior shell is made of durable metal, which serves as protection for his internal mechanisms. Inside, Bob houses advanced technology that allows him to move, think, and interact with the world around him.
Bob was originally created by a rogue droid engineer seeking to push the boundaries of artificial intelligence. The experiment was successful beyond expectations, resulting in a sentient life form with humanoid cognition within a tiny package. Due to his small size, Bob relies on various tools and devices to navigate the universe, including a miniature repulsorlift unit for mobility and a holographic projector to appear larger when needed.
Despite his humble beginnings, Bob has developed a quirky personality and quick wit. He enjoys engaging in philosophical debates and exploring new cultures throughout the galaxy. Being a sentient being, he craves companionship and understanding, though his unique appearance sometimes leads to misunderstandings or outright hostility from other beings. Nonetheless, Bob remains optimistic and resilient, determined to make the most of his extraordinary existence.
so if I want less repetition of that XYZ chunk of data just don't put them on ###instruct?
Now clearly, the bot really ran with what limited information I gave it, but that's to be expected with such an open-ended prompt.
The repetition doesn't seem tied to that in my testing.
For example I might have a line about XYZ in a character card.
And sometimes the character responds by saying "as I am XYZ" a direct quote from the card into it's response.
the only idea I have so far is messing with repetition penalty for that.
so the bot is less likely to generate that same string of tokens
about the example you mentioned, quoting the exact tokens verbatim, did you have 0 chat history?
There is also the cryptic negative prompt to consider
what.s that
Can’t tell you it’s too cryptic
: /
It’s one of the parameters you can use
Can't use it it's too cryptic.
Similar to stable diffusion, the negative prompt can subtract concepts from the generation.
For example:
prompt: Write a story with a castle
Common theme with such stories is a dragon.
Negative prompt: Include a dragon in the story
try it out!
it's better to play with prompt engineering than parameters
How do you insert the negative prompt with the bot?
Using the state tag
While yes, simply saying something you don't want to generate can cause the llm to generate that.
Especially for smaller models
Ahh yes of course
when you promot engineer it's clear what is wrong and you can change it, when you play with parameters you don't actually kmow
what's happening behind the scenes
complex math then
"hmm did that change anything?"
For the text string in format_prompt, can you use newlines and other formatting?
This but also has a special syntax to create tags from text
[[state:{negative_prompt:include a dragon}]]
That would automatically set the negative prompt
available now in ooba?
Yes its a TGWUI param
you can find the setting in the params tab, or if using the api it's called negative_prompt I think
So the prompt you type to the bot would be:
Tell me a story about a castle. [[state:{negative_prompt:include a dragon}]]
Yes
Yes, this could be quite useful
It will delete that from your prompt too
You can create any tag on demand like that
When you write a prompt, it's put into an embedding space while the model generates.
The negative prompt subtracts a 2nd embedding from your prompt.
So each token is generated as (next token = prompt-negative)
(message was red, not sure it went through)
@terse folio can I say "exclude anything that contridacts the mall description dumping the whole desc"
lol
I swear on me mum, didn’t just go find functions that do this I had the idea then worked with ChatGPT and debugging until I got it working
This tags from text thing
It works for any format value including dictionaries, lists, nested sublists, anything
I'm not sure, you'd have to test that.
But both prompt and negative prompt still boil down to the same thing.
prompt = prompt - negative prompt
if the llm wants to hallucinate it probably will, but worth investigating!
we need a police layer or quality layer or alignment layer that checks things up and removes conridactions
:)
but that needs more prompting and will also make more mistakes
: /
I tried doing it
but gailed
failed*
I think models like command-r aim to fix that issue with "truth"
They're trained on generating truth from given information by RAG
We have it already its called the Tags system 🙂
Using Flows, you can have other character contexts review the response from the LLM
that too ^^
False positives
how that work
tell me about the logic
Oh baby do I have a flow chart for you
why we need one?
click to expand
It may look intimidating but just try following the solid line
then look at the dotted line which shows how Flows works
that will be helpful, if you can make clear a set of TRUTHS or FACTS then the llm can do whatever it likes to do as long as it doesn't contridact those truths
You can trigger a Flow that just infinitely cycles through the message loop doing absolutely nothing
Or, have it change LLM model, change character, change parameters, replace text, draw an image, enable controlnet parameters, etc etc etc etc
super flexible once you understand how it works
I'm not smart enough to dream up the use cases it can enable
what is the message loop?
I read some
but still confused
So it's like very Fluid and you can mix and match anythng and everything all at once?
You write a prompt and trigger a Flow
sorry for the gif but I'm just a bit confused
That Flow definition builds a flow queue
Lets say you have a format_prompt tag in the first flow step
hold on let's start from the begining, you prompt what or who and if you include those trigger tags do they get removed?
It can include variables such as your previous prompt, or the LLMs response
to not cause chaos and confuse the character
You have to look at my example tags and it will all make sense
is that another link?
- trigger: 'draw,generate'
insert_text: '' # Replace the matched phrase with an empty string
insert_text_method: replace # Other methods are 'before' and 'after', but 'replace' is correct for this...
search_mode: user # Only search user's prompt (will not trigger from LLM reply)
on_prefix_only: true # Only triggers if matched at very beginning
should_gen_image: true # Triggers an image generation (will send to channel afterwards by default - cann be suppressed with 'should_send_image' tag)
swap_character: M1nty-SDXL # Swap to character finetuned for writing more elaborate image prompts from simple prompts
load_history: -1 # 0 = default (all history included) / -1 = prompt excludes chat history / > 1 = llm only sees this many recent exchanges.
save_history: false # Do not write this interaction to the main chat history
I checked the prev links
So see how it says insert_text - empty string
method: replace
it will replace the matched text with nothing
draw a cow
LLM gets: 'a cow'
If there is no 'trigger' all the stuff is guaranteed to happen
where it starts?
Look at the flow chart lol
I did
does it start when you promot a char?
it doesnt say where it starts, I read it
When you write a prompt it gathers all tags, checks for matches, applies stuff, then LLM gens
so if my prompt have no special tags then nothing will happen?
yeah but I was talkng about what are you prompting
Well by default it will generate text and send a reaponse
what you click "enter" on what tab in ooba
But you can have tags suppress txt gen, or response sent
wdym by this? sending it to sd?
or "draw" will always get replaced by empty str
bcz you set it in the settings
The tag definition I shared swaps in a character that has example dialogue, where user says something small and it replies with SD prompt
so you are agenting here?
by using “draw” you trigger the prompt to be processed with that char context
AI Agents
I’m an underpaid graphic designer
It doesn’t execute code or search the net
Unless you have an ooba extension that does it
I can’t chat going afk
what defines a system with agents?
I thought it was multiple characters interacting to solve a problem, so maybe it's close
that's agents
multiple characters interacting with each other to solve a problem
each with it's own system prompt and tools
Sure you could accomplish that with this I believe
even if it's not exactly ai agents, you can call it AI Coding the next era of coding
instead of only code, you leverage llms + code + prompt engineering
or at least I call it that since you are making a complex autonomos system that can function on it's own without needing constant fixes or help from the user
Reality, how you time tests went?
any ground breaking discoveries?
nothing significant that I can remember,
There was a suggestion to use more general times like "morning, midday, afternoon" instead of timestamps, that's worth checking out.
Just do things randomly sometimes haha, my last focus was making my own RAG system that uses various zoom levels so the model can find relevant data possibly better.
wdym zoom levels?
Like, when you embed text for RAG, you might split it by sentences.
and the model could query "what is Kat's favorite food"
The issue here is, that my favorite food might not be mentioned in one sentence.
The conversation might flow like:
Their favorite food is X```
There might also be another entry:
`Someone else's favorite food is X`
So the embedding model has a chance of picking the wrong item.
This can be solved by embedding at different "zoom" levels as I'll call it.
Level 0, capturing as much as possible in the context.
Level 1: embed each paragraph.
Level 2: Embed each sentence.
So first we match at level 0.
There's a match for "Kat" and "food"
In the database we check the sub items, and search on those, narrowing down to the right result.
Then this small sentence is added to the bot's context instead of pasting a huge amount of text
i'll be back in a little, brb
maybe classifying data can help you, that what am thinking of doing
like multiple folders:
Locations
Characters/NPCs
etc
under those folders there will be text files for each location or character, each file will have the full description
and when xyz location or character is mentioned I retrieve that specific info
it might or might not work for you but yeah
so you will keep narrowing down the data until you get to the most likely best set of data?
My typical use case would be discord chat, multiple users, and topics covered over time.
One of the plans for this idea is making a better search tool for messages!
Yea, an embedding model came out some time ago with an 8k context.
So I could utilize that to create larger chunks for the higher up levels.
Where I could be selecting based on a summary of possibly days of conversation!
Also another benefit of this structure is the data is embedded at query time.
Only the top zoom level is embedded and saved to the database.
As queries come in that use different branches, they will be processed and saved to DB.
So I won't have to wait hours to embed 100s of thousands of messages all at once at the start :)
Anyway, on the topic of grammar
https://pypi.org/project/gbnf-compiler/
I found this library that can process grammar on text and show the result.
This could be useful to debug why something isn't working
so it's a combination of embeding and summarizations?
Somewhat, I'm trying to think of the most lightweight solution ^-^
classifying those topics into folders is a bad idea for your use case?
Embedding kind of works like summerization, taking all the context (usually 512 tokens max)
and compressing them to a 768 dimensional space
I would have to query an LLM to process the data to get those categories.
Yes, that would be great :)
the LLM could also write a summary that can be saved to the vector database
but it's a trade off of time
about false positives that you mentioned earlier, the solution you came up with is to keep on narrowing down the results, but is that enough?
will be 100% accurate?
Embedding text can take miliseconds,
Text generation 10s of seconds possibly
I don't think anything will ever be 100% accurate,
I'm just experimenting with some ideas that I think could work
Maybe we should make a “user_scripts.py” that users can put functions in that can be triggered by tags
but why nothing can be 100% I am sob now 😭:
look into my hot_reload extension ^-^
For some scripts that can reload on file modification
I was using it at one point awhile back, haven’t been dealing with the webui much though
If it doesn’t rely on UI should work with the bot(?)
we should add a Gaslighter Agent in the process (it will make you believe that there is nothing wrong and you are the one hulisunating, you are the problem)
bingo 100% achieved
What I mean is everything has it's ups and downs,
Like if we did a simple word matching text search it wouldn't be able to account for typos that aren't predefined.
It also wouldn't understand the context, the meaning of text.
Some words can have multiple meanings.
A vector database is better at meaning, but can have trouble matching exact words/phrases.
We could use a hybrid that uses both.
But just like with llms, there can be edge cases that are missunderstood
Love it!
I mean to look into how I load in a file
Because when you run import X
it will only import once
and cache the results in memory
i'm pretty sure
now i can't remember
Yea,
when I work with python notebooks, I have to restart the kernal before importing my changes from my library
Gaslighter Agent retrieving from memory: "you see we already talked about that yesterday, there is nothing wrong, we established thst yesterday so stop bring this up, let's move to the next"
😸
It would be best to implement cogs and have a reload command.
We could have a subdir for user created cogs where they define whatever functions they want.
and it would be all set and benifit the bot as whole
that would take restructuring the whole thing, a big task
How about this-
All the possible matched search results are shown to a character context along with your trigger/prompt - and it is tailored to pick the correct data (in regards to your rag system thing)
Sure, but could be computationally expensive
There are some ways to tell if your search results are confused or not
like if all the results are 50%, 50%, 49%...
there's an average difference of "1%"
and 50% is pretty bad, so we can tell the model is confused and found now good matches
ideally we want
99%, 99%... 1%, 1%...
that tells us there's confidence in the results
usually
still can hallucinate
So maybe there could be a threshold range
If the confidence is at least 75% average, then pass it to llm.
because anything below that may as well be random choices and not include a good answer in the search results to begin with, and this would be wasted on the llm
Is there a way to include apostrophes in format_prompt without messing up the works? Backslash before it?
Searching by vectors is done through a dot product (or cossin) of your search query and all the vectors in the database.
This returns a list of similarities for each item.
and you usually grab the top K, maybe top 100
with those top 100 you can check how similar the scores are
The idea for that came from when I was playing around with older neural networks, like image classification
the model outputs each class with a score
but you need to process those scores to determin how confident the model is that anything is in the image
else your code would just pick the item with the highest score, which could be wrong
Cat - 60%
Dog - 50%
Bird - 50%
...
hmm
ah I get it
so you calc the score in code right?
u write a logic that calculates the score
ML libraries usually have a function for this.
RMSE I believe it's called
Mean squared error
so now you just pick the highest score results? and those are most of the time the best matches?
Yea, you'll pick the highest, but also calculate a confidence overall
so you have 2 datapoints to decide what you want to do
like if confidence is below 50%, then any result is probably garbage
So back to Embedding models
this can be a little confusing because each embedding model gives out different scores
Like for some, a similarity of 0.2 is good. (meaning very close)
but others can only get up to 0.4 and the range is much larger.
So it can be hard to hardcode numbers for those
I'm still figuring that out
here's an example, this function is expecting an array that looks like this:
[1, 0, 0, 0, 0]
the function matches how close the inputs are to that expected array
I have 1-result to translate it to a percentage
so 0.98 - 98% similar
or confident
oh yeah
The next complication is what if you expect multiple correct results in your search?
That will no longer match the pattern of 1, 0,0,0,0,0...
so needs some sort of dynamic threshold to decide which items should be 1s, and which not
Still figuring that out too!
btw how do you quote the llm, it doesn't seem to get it
llm: so you will keep walking
me: hmm "keep walking"?
llm: -unrelated reply or totally misundertood it-
Llms are trained on real life data,
I would look into how you would quote a real person.
When I talk to people, i say:
"btw how do you quote the llm"
and reply to it
But maybe the LLM would make more sense of "Me: In reply to <llm's message>: my reply"
since it's all on one line
try things out! there isn't really a concrete answer
Also, since that's directly the next message.
I think asking "what do you mean keep walking?" would also work
I want to autonate it but the problem that might arrise is me not quoting the llm but the implemented logic/code will detect quotes anyways
edge cases problem --
Yea, if you do something externally, you could detect quotes from the user, then format it differently with code.
Maybe injecting User Me is replying to your message <quote>, here is their reply:\nMe:
and this would be hidden from the user
yup, so many edge cases
^ that will make a prob
wait I found a solutio, checking if the keyword is mentioned by llm in the previous reply
why would you quote NewYork?
Unless it's a custom location the llm makes up, which you could still just call by it's name
but that just reduces edge cases rather than fixing them all
Do a "if quote.lower() in last_reply.lower()"
I think we should fix the user instead
😐
me
I have to quote differently in a clear manner that can be detected by my code
removing any possible edge cases
Wrap the entire value in double quotes
format_prompt: "this is 'stuff in apostrophes' and that's OK"
me: hmm ql"keep walking"?
ql means quoting the llm
mhmm, mhmm,
Back before LLMs, I tried writing chatbots using fuzzy matching and patterns.
Would get stuck trying to overengineer it to take into account every possible user error.
I even tried using some libraries to deconstruct a sentence into a tree of inheritence (what word relates to what)
But I finally came to the conclusion that I should just tell people to write in proper english lmao
it was getting to be too much work
lol fix the user
the users are the bug
exactly haha
it always has been
what about a live video call with an llm
you will make the thing with your fingers "quoting"
how do you detect that
openpose?
Never used it, I've used Mediapipe, but I wouldn't recommend it right now.
They don't exactly have windows support, and you need to compile it yourself to use GPU with C++ on linux only.
I think it would be doable if openpose has a finger tracking model
You would want to detect if the 2 fingers on each hand are close to eachother in a raised position, and that could be your air quotes flag
Getting distance between end of index finger and middle.
And also checking that they are NOT close to the thumb/or palm to check if raised
I remember there were a few mediapipe controlnet preprocessors/models at one point, for SD 2.0
lost to history with the advent of XL
^^ mhm
@terse folio the activesettings migration fails
Uhoh, are there any errors?
Ah, thanks, I wouldn't have caught that ^^
I didn't catch it earlier at work because I moved it manually
decided to let it migrate here at home
I wonder what should be the logic there.
Should it overwrite the newer file?
because old likely has the settings you want
Yes, should overwrite
or could also warn the user to delete it if they don't want the new file
or, could rename it like you did with the old database file
...just in case
rename + warning that you should merge
ehh
lol there will be a lot of migration code running on start up.
Check if bot.db exists,
check if activesettings.yaml exists
check if starboard exists...
It's very unlikely that anyone is going to run the bot and have new settings there they don't want to lose
don't think its possible really
their existing activesettings will have current settings
I / you can just axe it in a month or so
I would just comment out the migration function so people can still use it if they need
You can't tell me what to do! You're not my real mom!
But yes, that worked.
Pushed that update to optionally keep history when changing characters
Coolio
So, the tag system only triggers the first available, but doesn't do multiple in one prompt?
Certain tags values, it only keeps the first instance.
Other values can accumulate
Yeah... I should add a search_and_replace tag
Due to the way I process the text insertions, it couldn't work to replace all instances
that would have to be handled separately
I'm using it right now as a sort of lorebook, and I've saved information on two characters (RPG characters, not bot characters). When I prompted the bot about X and Y characters, it only triggered X.
Two separate tag definitions?
so when you mention those characters it will retrieve info about them?
Yes
Yup
Only the first trigger is getting formatted into the prompt
It puts that information ahead of the prompt
format_prompt I think is one that is currently only allowed to use once...
...I'm thinking if there's any reason why I shouldn't change it to allow multiple...
oh before user prompt?
yes
Right
So, let's say I wanted to tell the bot that character X jumps into the air John Woo style and shoots at someone. Then, a brief synopsis of character X's traits are injected prior to the action description.
I understand.
Uhm, you could have a separate tag that you have "X and Y" as a trigger
with a trumps parameter to trump the other tags
But then I'd have to put their respective information again into that format
Which would mean I'd have to do it for every potential combination
thinking :p
Group RPG. The idea is to use the bot to handle things like interactions with NPCs, plot ideas, scene setting, etc.
I guess there's nothing against formatting repeatedly...
I would just need to collect it as a list and process each one
so the bot isn't a char, it's a world engine?
Yes
The bot character is called Gamemaster, and its personality revolves around storytelling
that's cool
Yup! I've used it fairly well in the webui, but now I want to take the concept multiplayer with a discord bot
yeah you can go big with such a idea
you can even make it a video game, but ofc no one said it's easy
At some point AI could be good enough to where an open world RPG could be made, with AI generated voices, images, plots, characters, etc., in any conceivable setting, but we're a way away from that.
Ill expand that format_prompt tag now...
Ooohhhh
@keen palm
Looks good to me on paper - if it works for you I'm pushing
Note that it will format higher priority tags first (ones sorted higher in your tags dict)
File "D:\Documents\text-generation-webui\bot.py", line 2089
formatting = ['format_prompt': value]
^
SyntaxError: invalid syntax
The ^ is under the colon
I should probably stop testing this and go, like, eat dinner with my family
nahhhh
But yes, it works! Thanks!
I might need to reformat the info so the bot knows it's from multiple characters
@keen palm you may benefit from the send_user_images tag, that lets you trigger an image send (does not require image generation)
I mention this because you had me thinking of other things I can do multiple of that I thought could just do once. Updated this to allow multiple image sends
Haven't looked at that one.
You can put images into your user_images folder, and use the filename (or directory name to send random image)
Hmmm, that could be interesting. I do 3d renders of the characters, but I usually put the pictures in their own channel
Good thing I am messing with this b/c I noticed its bugged
working so far
Sending local images working
again, collecting multiple tag matches instead of just the one match - and sending all
Commit commit commit commit
also decided to change the starboard to be a dict
messages:[message ids]
that way it also can be loaded into the FileMemory class
There's no reason to keep the database in the tgwi folder is there?
Could just move that to internal
Yep!
You might get an error about failing to load the starboard,
just move it out of internal to the ad_discordbot dir and the bot will migrate it
Dunno where the issue is, but some args don't pass through the bot to the webui.
Like setting the listening port.
Do you already have listening port in CMD_FLAGS.txt?
The bot does load ooba flags
no, I use a custom run file with the args.
I update the tgwi often and it overwrites the cmd_flags file.
I used to have flags there, but when I was working on the PR for the openAI extension, I didn't want to push my personal commits by accident
Well you could stick a print statement in the tgwui loading code to see when it reads the args, it wasn’t all too long ago I combed through it carefully
Or Ill take a look tomorrow
you create your own arg parser that only accepts --token and whatever the other one was.
I think this couldbe solved by importing the arg parser from shared.py and running it after
Be my guest 🙂
Idk though, when I pass args they are applied…
Such as —model and —extensions and —loader etc
model and extensions work
Hmm, yea good point
mightbe the wrong port, because I tried 7860 too
whatever the gradio port is*
Ahh, bot loads but doesn't say the webui is online
I think there is a bit of code that prevents it from using the UI
I mentioned this before but I have a version of bot.py with api working, I just like the versatility for the tts stuff
lets work on a tts api!
that's something I want to do anyway
I like the idea of having all these tools as separate services
I'm working on a project to be able to organize a "render farm" type thing with LLMs, SD, tts, whisper... etc ^-^
I'm sure,
but the TGWI one probably doesn't have to be too complicated,
just pass text, and a voice model name
If you shoot down to process_speak() you can see there’s a few subtle differences between the extensions
I check the tts client and handle accordingly
mhmm, I would do the same letting you access all the clients from one api
Well you may get a good head start there 😛 There’s been other promising projects emerging I haven’t paid much attention to
Again probably with their own subtleties
we need a standard for tts too now
It’s been prob 2 months now I opened an issue aaying they should have both Internal and Visible responses returned from api
I forget which but the one is what has the filename for generated tts
The chatbot wrapper function returns both responses
ahh,
well if tts was its own api you wouldn't need that, just pass the text you want to generate yourself and get the file back
Which is what this bot does
Well it’s easy enough to detect the file and find it. But yeah, setting the params would be impossible right now I think without something like the monkeypatch I have going on
hmm hmm, will see what I can do when I get tts installed
They all use the same XTTS lib on the backend
trying this idea, reinstalling Visual studio
But I have all the build tools and manually set the paths for pip to find the lib files and all..
Nope that failed, sad
wish there was a solution I could just use on windows without duel booting or anything
actually, new error: LINK : fatal error LNK1158: cannot run 'rc.exe'
Hmm, where's the config option about starting as a particular character?
I did try the alltalk extension with tgwi
It starts up from last character

Amazing
the horrors that led me there
So, what changed was use buildtools from programfiles/visual studio not program files x86/visual studio 14
And to include a few more paths to some missing libraries
Welcome to semi realistic robot voice 
You’ll enjoy how the bot handles tts I think
woo,
Am hoping I can get xtts finetunning to work and make something semi realistic, I think it was this video that inspired me to try again https://www.youtube.com/watch?v=ds5LLIt5OLM
The idea of finetunning the model, then passing that generation through another model finetuned again on my voice.
I’m outta here, good night!

pip install -r ad_discordbot\requirements.txt 🙌
Did you update some things again?
Reality working their magic
With that 'draw, generate' tag that switches to Minty-SDXL, do you have to manually switch back afterward?
No - swap_character affects only the current interaction
To set a new character you can use the change_character tag
Sweet
similar effects for swap_imgmodel / change_imgmodel and swap_llmmodel / change_llmmodel
Better have a lightweight model or really good GPU for constant model swapping though
Right, I was just looking at that possibility
Thinking about adding swap_llmmodel none to the img generation trigger, to unload that model and free up VRAM for the SD side
You could also have a tag like trigger: '{draw|image} mode' that will change the LLM model to None
and keep it that way, if you want to just do images for a bit
...or just use /llmmodel command of course
When the LLM model is unloaded, the users text is used directly as the image prompt
I don't know if I'd be doing multiple image generations in a row like that, but we'll see. I haven't even really found any good SDXL models yet anyway. I just started playing around with A111 again after like a year.
SFW or NSFW stuff?
SFW, since it's for a game on discord
Idk what sort of game it is but this is a good model for fantasy / cyber stuff
https://civitai.com/models/131703/brixl-or-a-must-in-your-toolbox
Star Wars stuff, so that might work
Here are some other great models:
https://civitai.com/models/43977
https://civitai.com/models/133005
https://civitai.com/models/125703
https://civitai.com/models/84040
Thanks, I'll check them out
Did you try NeuralBeagle llm model?
I have SD set to just load into my second GPU (since last I checked it can't split properly anyway), so I might be able to get away with having an LLM loaded across both GPUs, and just unload it when necessary for SD generation. Since I think those models use very little VRAM when not doing anything, unlike LLMs.
I didn't, on account of the apparent fake context size
It doesn't have a huge ctx size I think just 8192
Yeah, the one I've been testing recently has...supposedly...32k context
Do you often need it to remember things from 10 messages ago>?
Yes, that is helpful
@terse folio colorama seems to be installed by TGWUI in the venv already
Although, that does have me thinking...
I claim that this bot can be used for image generation independently from TGWUI, but I'm a liar because this relies on many libraries in the TGWUI venv
Beautiful logger though
In a few weeks if I remember, I'm switching it to INFO mode 🙂
DEBUG could be good for now with all these changes
alltalk goes absolutely bananas with debug info
It's still worth testing for the quality, though
I can't get away from it, every model I try doesn't compete
I'll try it out. The one I've recently tested has been doing quite well.
Do you use the refiner with SDXL?
Nah
The Refiner works best with the base model, and the base model is great all around but the refiner isn't very impactful with the finetunes
When it is impactful, probably for the worse
What's that Beagle model again?
Thanks, broseph
There are some amazing performance improvements coming to A1111 to make it on the same level as Forge
If only Automatic1111 actually merges them
Good to hear. I've ben rather consistently disappointed in that regard. Easier for me to just 3D render characters myself, since I have complete control.
50% performance boost is insane
That's really how big of an edge Forge has on A1111
no lie
This is someone from the Forge team who did all the work A1111 should have been motivated to do himself when Forge was unveiled
idk how I could sleep at night knowing someone forked my project and made it 2x better
People with no work ethic or sense of pride don't really have to worry about that
I've noticed that with some coworkers. The question "how do you sleep at night??" is met with "astonishingly well"
My negative prompts are being ignored 😦
You may find this interesting...
https://civitai.com/models/451311/star-wars-planets-and-locations-xl-choose-from-list?modelVersionId=502731
You could trigger the LORAs from keywords
Yeah, I checked that one out the other day. Should get it.
But I meant negative prompts to the LLM. I think I just needed to word it differently.
I know 😛
I was playing with the quick tags thing.
I just didn't respond on that
derp
yeah I also use negative prompts with the LLM and and they don't seem to have any effect
It's been hit and miss so far
Wanted to sit down and add features but very busy today
Don't you hate it when actual life gets in the way of fun things?
Have you considered integrating the bot into oobabooga as an extension, so you can change settings in a tab in the webui?
Gradio is a bitch
Sigh, yes
Every extension I've installed has required fucking around with gradio versions until it works.
I'd probably have a standalone gradio interface for the settings
I got my first and only taste of gradio with this extension I forked... BTW you should 100% get this
https://github.com/altoiddealer/--sd-webui-ar-plusplus
I have that
my version?
Oh actually maybe not
I researched all the versions that were out there and they suck
I installed an extension for that quite a few months ago, so likely not yours
Trash it and get mine 🙂
Haha, if I play around with SD more. It's still disappointing in general.
I suggested A1111 integrate this but it'll never happen.
Worth a read, though. Explains the deficiencies of the other extensions out there
https://github.com/AUTOMATIC1111/stable-diffusion-webui/issues/15475
No response, but one thumbs down!
Asshats. Asshats everywhere
They have 3 versions of the same extension in their Available Extensions list and they all work technically, but suck
There are various extensions which have their own rounding precisions such as Controlnet and layerdiffuse.
Using default A1111 dimension increments or rounding to nearest 1-4px, you get controlnet maps that don't line up and shit like that
And, when you set aspect ratios by forcing in one dimension the total pixel count skyrockets
how useful is that?
Can I get an amen @calm rain
(mebbe not :P)
Solution: Switch to Stable Swarm 🫡
Alternate Solution: learn to draw
@terse folio There's a pretty significant change I'd like made if you don't mind... if / when you are able.
Mainly, I don't think the internal directory really needs to exist in the bot package - the directory along with all current items (activesettings, database, and starboard_messages) could all be created on initial startup.
For the database and starboard files - there's probably a simple thing to add...
In regards to the activesettings, the file really just needs to initialize with a value like:
'behavior': {},
'imgmodel': {},
'llmcontext': {},
'llmstate': {}
When the settings are initialized in BotSettings(), just adding a .save in there should make the bot initialize with all the default inernal settings saved to the newly created file
def update_settings(self):
defaults = self.settings_to_dict()
# Current user custom settings
active_settings = copy.deepcopy(bot_active_settings.get_vars())
behavior = active_settings.pop('behavior', {})
# Add any missing required settings
bot_active_settings = fix_dict(active_settings, defaults)
bot_active_settings.save()
self.settings = bot_active_settings.get_vars()
self.bot_behavior.update_behavior(behavior)
(something like that)
hey fellas
oi
If I use this instant tag:
[[save_history:false]]
That particular exhange (prompt and response) shouldn't save to the log, right?
correct
good job 👏
Glad to see some of my crazy features being used out in the wild
Yeah, though it didn't work
Okay
nah that shouldn't matter
:] I got to the code block before you could test
Ok I probably did not account for this tag when I added the new history crap...
Looking into it now
I figured as much
I had same result in testing
I thought it might be convenient to do such a thing, like asking for a list of ideas, that I don't want to then influence the context
Yes there's many times that saving to history has a negative effect
I suspect I know the problem...
nvm
I know the problem now
# Process the tag matches if flow or save_to_history or load_history or param_variances or state or change_character or swap_character or change_llmmodel or swap_llmmodel or send_user_image:
Its a boolean so False is not triggering this
heh
Fixing...
I never caught this myself because every time I use save_history: False I am also using something like change_character
I actually dont need that particular line at all.
@keen palm pushed update that fixes it
Also, /reset_character has been changed to /reset_conversation
You need to reload your client after running bot, to see the change
If you use save_history: false on a fresh chat, the cmd window will say that it saved chat history to new json file - however, what it saves is just an empty list
Wonderful gpt4-o access.
yep, it's slightly smarter than GPT3.5 so far 😛
Although I havent toyed with any of the extra cool stuff it can do
I should've planned things I wanted to test/try out. Maybe I'll try and build something simple with it and see how it goes.
Maybe I'll see if it can fix a bug in a game I was making that I couldn't be bothered to figure out.
Either way, it's nice that they gave access to it for free.
yo
@keen palm how is the project going?
how can I encourage the character to make decisions on its own? without neither negativity bias or positivity bias?
when I do the "Alex is an independant thinker who makes decisons on her own etc" the character became suddenly kind of a feminist out of nowhere, lol, therefore the negativity bias rise up and if I do the opposite way of prompting it goes to the other extreme of positivity bias
Pushed an update that adds another config option
greeting_or_history: history
- 'history' - Sends copy of most recent message exchange whenever history is loaded
- 'greeting' - Only send character's greeting
guess I could've also put option for 'None"
should I make like a "decision making" pre reply step or something, but still how should I prompt that
Actually I'm going to change it real quick so - woops
take ur time lol
Changed my mind again... just leaving it as is
Got work shit to deal with. I'll check on that update later
Crisis averted. Lemme update
It, umm, didn't seem to work
[[save_history:False]]
Correct syntax, yes?
Fine so far. Tweaking bot stuff at the moment, so haven't really started the game.
good luck Speedy
If the CMD window said that it saved history it might just mean that it created a new history file with an empty message history
Nope. Added it to the existing history.
I’m on the road now I’ll test shortly but it worked for me when I tried it earlier
Not like it's a yuge deal, as I can manually delete snippets from history, but it is certainly a matter of convenience
This might be a dumb question but just making sure did you replace the bot file and also reload it
That is such a dumb question. There is no way that once again I would forget to move the bot file over into the main folder. I am insulted that you would suggest such a thing....
Don't mind me as I...do something....
Okay, for some reason that no one really knows or will ever know, it's working now
Truly, one of the mysteries of our time
any ideas on this guys?
Thanks!
Also you can disable loggers for other libraries,
For example I set the log level of asyncio to warning only.
Because that spammed me with some stuff on other projects before.
So just need to find out what the logger name of alltalk is and change the levels
Yea, there's code there to generate the directory on start up,
try deleting it, does it still work as normal?
It should.
Only reason I kept the files in git was because activesettings.yaml was populated with defaults.
And I wasn't sure if these were needed for the bot to work, or if it's capable of recreating them if deleted.
I would change how activesettings works as well, so that it doesn't keep a copy of all the default params for all the systems on disk.
And only a difference of what the bot changed.
This would make it easier to read for the user i'm sure
heya, I'm here

I don't think we need to get too crazy with the optimizations - unless you're willing to do it
I had tried loading the bot without activesettings present and it did not create a new file
there are some lines of code where you do active_settings[some setting].get().get..
The [item getter] will throw an error if the attribute isn't found.
So if the file is empty on a fresh start those would be a problem.
Just have to change those lines of code to use .get instead.
did you run a command to change settings? like the character
The first thing that happens when the bot loads, is it gets activesettings and copies it over the default settings - and those become the settings
So if activesettings is an empty dictionary, then the result is the default settings
When I do bot_activesettings['imgmodel'].get('some_setting', "") its because the imgmodel key is guaranteed to exist
I did not... good call. Ill try that
there's no call to save() on start, because it's not needeed.
If nothing changes, why save :)
In any case, I'm still going to put the .save there 🙂
i would put a save if file not exists
I want to save even if it does
could probably put that in the init of the active settings class
at the end
where it says if migrated
actually, no not there,
after the super().init
My settings management is a little unconventional maybe.
So when the bot starts, like I said immediately it fixes anything broken with activesettings.
Then, it loads the character data and merges it with basesettings.
Finally... and I just added this the other day, it saves to activesettings
I was only saving the result after /character or /imgmodel but I think it's more candid to show the actual settings in play by saving to the file
You're probably correct that only saving the difference is more optimal, but this is probably like milliseconds we're talking
If you have any better idea - by all means 🙂 You've been a godsend thus far
also a pleasure to work with
Oh right, would have to do the save later after that stuff happens then
When you change a setting with .set it will automatically save.
But thats silly if you want to change multiple values.
You better use activesettings[key] = var
And then run .save at the end so the bot isnt saving multiple times in a row for no reason
if you search bot_active_settings theres only 18 instances (try comparing to embed lol)
It's not called often, when it is its to to dump or merge into
Im going to edit line 527 which should reference bot_settings instead... boom, 17 instances now
found 2 more...
# Save the updated bot_active_settings
bot_active_settings['llmcontext'] = char_llmcontext
bot_active_settings['behavior'] = char_behavior
bot_active_settings['llmstate']['state'] = char_llmstate
bot_active_settings.save()
but confused what's being removed, but I'll read over it after you make a commit ^^
We could start a test branch for in development commits back and forth
Nvm what I said about moving the .save() into the update_settings() function - the 2 places it is right now are good
But, need to text how it runs without activesettings there at all...
Would be nice to have no internal or those 3 files
(until created)
oboy... good thing pushed that to dev
Rolled back one error I made, which has to do with the way the command options are currently built for /imgmodel
I’m halfway done reworking that command… will finish it tomorrow
Currently it has all those command options that all need to be defined at startup. Changing it to a regular slash command that sends a view containing the select menus
internal is created on startup if not exists
I'm confused here
Ohh ohh, now need to find out what bot_settings.settings is
It's best practice to use .get() when you expect some values to be unset
this is weird
you're creating a copy of active_settings
which also gets it's own updates
bot_settings.settings gets updates.
and active_settings gets updates.
so, anything changed with bot_settings.settings probably wont be saved
I think it would make more sense to just load the defaults into active_settings, and use that on it's own
bot_settings.settings are the settings.
When settings are to be changed, they are merged with base settings, written to activesettings and also updates the bot_settings.settings
I think a step could be skipped by just loading active_settings with the defaults at the start
if it's all the same
If activesettings.yaml doesn’t exist then yes, it should initialize with just defaults
I see
Ideally, if the user says oops, and deletes activesettings and basesettings, it still runs on the internal defaults. It’s been awhile since I introduced base_settings.yaml but I think it isn’t required to exist. The system works pretty good, maybe not super efficient
While the bot is running? or offline
if the bots running and they delete those files, we need to code an Ascii animation
The files are only read once at the start, it wont care if they are deleted
I'll eat my hat if this update works first try...
Was up pretty late working on some fun projects forgetting about the passage of time,
So I actually woke up in the evening :)
Mostly going to chip away at my todo list with some music/videos in the background
Good luck!
It didn't because I deleted this slightly important thingy 🙂
@client.hybrid_command(description="Choose an imgmodel")
async def imgmodel(ctx: discord.ext.commands.Context):
await select_imgmodel(ctx)
When this works now as I suspect it will, I cut like 100 lines or something
that big chain of bullshit options
Nice nice!
I was thinking about how to shorten that using loops, just to see if it was possible (after you told me you'd be changing it)
And it turned out more complicated than I thought,
Because discord.py uses the typehints in the function to define behaviors as well.
So i couldn't simply generate the functions as needed
This will be much better solution
😸
Well, once I debug this 😛
Maybe not deferring the response correctly...
nvm I know the problem
I got it working but obviously I'm overlooking something important with the hashing
One's a string, other int
unless you're just printing it differently
but i'd do a type check
it needs to be an int right?
Btw, you can print the repr of an object with python f'My object: {obj!r}'
It is an int - its just printing with double quotes
if you set it to an int, you need to change your command to take ints as the value input
it was originally a str because you used to have the model name there
[str] this tells the class the value is expected to be a str
Aha
it doesn't affect the name, name will always be str
not sure if this means what I think it does
but maybe, you could set the choice to output multiple types
Got a sec?
sure
Ahaha, I have my discord pretty small off to the side, so this isn't easy to read vertically,
Could you push to a test branch maybe?
need more branches! haha
Don't really understand the hashing - I basically converted the original command options into selects
didn't change anything related to the hash
...Do those look like hash values?
Img model not found: 808230645446604537
In the View class, when a value is selected from one of the menus the class attribute gets the selected value
When submit is pressed, the menu exits - and the value can be accessed
made a merge
what was important was you missed this line of code
that got the name from the hash that was stored in a dict
also there's ways to shorten your menu code, will merge that soon
I'm very much intrigued about this
Probably something to do with the iterations...
Yes, with the submit button it can only have 5 total items
in one view
If anyone has > 100 imgmodels, they are SOL
Hmm, I worked with views before, I had like 12 buttons.
If I add another item it will fail
Maybe it was a different type of view, but okay!
I went through the whole gambit when making the Controlnet options for /image command
The View can have 25 buttons
because you can put multiple buttons on a row
I don't think you can put multiple selects on a row...
Ahh that's what it was, a limit of 5 rows
That certainly did the trick my friend
👍
I could go repeat the same for /llmmodel and /character - but you said you have something cleaner?
Not anymore!
okay
Now the value is just for the "Placeholder" - does not need to be unique
no more hack required
for imgmodels command it's almost always S-S 😛
maybe renaming it to 0-24, 25-49 would work
It's because I have them in a subdir
and the subdir becomes part of the name
in this case they're either in 'SD15' or 'SDXL'
It is helpful though if unsorted
I have quite the range of model names!
and yes, some 100char+ merges
what's response.defer do?
not familiar with this function
Hmm, looks like it exits and pushes the result to the class
the wait() function
When a user does a command, you have 3 seconds to send a response interaction to them - otherwise the interaction times out
ctx.defer() says relax discord, Ill get to it
I see
Yes the submit button will call stop() allowing the view to exit
There seems to be many different ways to handle views, using classes, using callbacks, without either, etc
This is what I was able to get working with my limited knowledge and what information I could understand
Either you work fast AF, like super fast AF - or you don't sleep 😛
I'm outta here - get some sleep 🙂
Cya!
sometimes it feels like there's never sleep, but I also sleep too much 😸
first test working so far
no, a sideeffect of creating the menu items in __init__
because submit is created using a decorator before init runs
not a big deal if it works nice this way
can move it later ^^
Working great!
I modified it a bit so that the first label for '/llmodel' won't always have "N" prefix (for "None")
However, thebetter solution will be to ommit "None" from the menus and just put an "Unload Model" button next to the Submit button
I know how to do it...
testing with imgmodel... and it is popping the first item as self.unload_value if the cmd_name == imgmodel
@terse folio I have it working, but you may have a cleaner solution.
The only problem I'm having right now, is hiding or disabling the button
Pushed what I have
I added a positional arg for “cmd_name” but should’ve just popped and send the unload value instead
Got it
Got it perfect
I've added an unload argument, for the value to be popped from the full list before sending to View function.
If unload = None the Unload button is removed from View.
Otherwise, added to get_selected()...
if self.selected_item == self.unload_value:
return self.unload_value
NOW we're talking... button style = DANGER
There's no real way to cycle between regenerated text, is there?
I kind of forget exactly how it works... I know that the message you perform it on, the text is used as the input
need to look at it again... in a few minutes... if wifey permits 😛
Stinkin' SOs always demanding attention
Submit button not required if only 1 menu
Reality did some very beautiful work with the new Select view handling
@keen palm This is kind of advanced, but you could do custom tailoring of Regen / Continue if you use the tags from text feature again
I'm not quite following
[[state:{regenerate: True}]] and then you can try modifying the input in other ways... what exactly are you trying to accomplish?
Like I said, it currently takes the text from whatever message you selected and uses it as the input text
@client.tree.context_menu(name="regenerate")
async def regen_llm_gen(i: discord.Interaction, message: discord.Message):
text = message.content
await i.response.defer(thinking=False)
async with task_semaphore:
async with i.channel.typing():
# offload to ai_gen queue
logging.info(f'{i.user.display_name} used "Regenerate"')
await cont_regen_task(i, i.user.display_name, text, i.channel, 'regen', message.id)
await run_flow_if_any(i.user.display_name, i.channel, 'regen', text)
mainly text = message.content and that is used for the regenerate
I may not understand how it's supposed to work... lol
Maybe text is supposed to be the prompt used in the original message...
And it uses the most recent history as the item to regenerate
The idea, especially with storytelling, is to regenerate a response a few times until you land on the most interesting or entertaining option, then follow along with that.
Yes, you want to take the prompt and generate a new response to it
I'm open to suggestions on how you think would be a better way to handle it
Make a config option for Regen / Continue text to either replace original, or create another instance?
I can't remember, but, in the webui, are you able to cycle back and forth between outputs?
So yes I see... the command is not working as I thought it did
Is it using the first generated response as the prompt for the regeneration?
I know with ChatGPT, you're able to regenerate responses, cycle through until you get one you like best, then continue off that
It seems like when the payload is sent with regenerate: True, it takes the most recent LLM reply from the history parameter and regenerates it
The value of text (the prompt) doesn't seem to actually have too much bearing on the result
Yes, that explains things
Actually
text seems to be ignored
it uses the most recent user msg from history
So it appears to be driven exclusively from the history parameter
So it's not really deriving a new response from the prompt?
It's getting the prompt from the history variable
which is what you can see in your chat log
Regenerate seems to ignore the text variable, which is usually the prompt
Interestingly enough, the regenerated response is not included in the history. Only the first one.
It's because I force save_history: False for Regen and Continue
That makes sense
I'm willing to rethink all of this...
When I added these features, it was mainly because I thought they at least needed to be there and work... but I did not finetune it
Since you are someone who uses it frequently, I'll take all your feedback into consideration
meanwhile I very rarely use those
At the simplest level, regenerate should just take the prompt and existing context and create a new response, without including anything from the first response
Ideally, you'd be able to cycle back and forth through responses, but I don't know how feasible that would be with Discord's UI
I'll do some more testing... it may actually ignore the most recent LLM reply
I mean, it probably does
I could maybe make new App Commands to edit history....
"Replace last reply"
You right click on a message and select it as "Replace last reply" and it will swap it for the most recent history item
I might just need to mess around with parameters to get regeneration working a bit better, since right now I'm basically just getting variations on the same thing.
Replace last reply would be very useful
I need to run along, but since this isn't using the WebUI there is actually more freedom to customize te behavior of regenerate
We can modify history however the heck we want, if I just know the best way to do it usefully
The most useful options would be:
- Delete last reply
- Replace last reply (ideally, where you could type out a revision to what the bot just spit out, and that becomes its last response)
btw the character, llmmodel, imgmodel cmds are going to be much nicer either tonight or tomorrow
Ooooh
another model won't fix the issue, better prompting will
and sometimes diff models seems just copies of each other so... yeah
There’s a reason there’s thousands of different models
Best possible prompting won’t get the result without the correct model
The context I use for generating image prompts is good - but only a select few models work well for it, and I’ve tested somewhere around 50 models
Works very very good with Neuralbeagle model in particular, really amazing output
by holding CTRL in vscode, you can jump to definitions of variables/functions/classes
saw a commit noting where to find the class ^-^
It's great for debugging,
Ctrl click on discord.ui.Button, and it takes me to the class so I can see how to create a callback!
There must be something you have extra that I don't have enabled
When I hold Ctl and click it doesn't do shit
ideally the buttons would be generated in __init__
And I think I know why my original code wasn't working.
Will do some tests later
oh oh, yea, it's an extension
lemme see
It should be Pylance
It takes it's time, but once it loads your file/initiates its server, some of the syntax highlighting will change
And then things become clickable
surprised you removed the hashing
it wasn't necessary,
since the menu can't change while it's being shown to the user, may as well just use the index of the item in the choices list
One less computation!
I then added a function to retrieve items
But you can pass in other lists if you wish
Maybe pass in the discord.Choices list
so you can access the .label and .description or whatever if you need for some reason
But it defaults to return the name which is what the SelectedItem class is expecting as list of
interesting, removing the submit button and just running load here.
I was thinking of maybe ditching the Submit button altogether lol
First item you click thats the item
Definitely could, but I did like the confirmation of the submit button
since loading a model can take some time
Let's try it out, see which experience is best!
I weed out models constantly so mine are all just one menu 😛
I could add a flag that you could pass to the class which changes the behavior between immediate return, and require submit button
Or, I use my model filter feature to limit it to just XL models, omit the inpaint, base, etc
The Submit button could be useful for the future... especially if I update the /speak function to use this
That... could be a can of worms
(maybe leave it as is)
mhm, lots of voices
nvm
Reuse functions when possible!
Write code thinking ahead about how it could be used in other places
Goddamn it is so easy to update these commands
I just did the LLM model one in like 5 mins
:)
Characters will be done in minutes
Also windows doesn't care if you use forward or backwards slashes
I think Linux too
Well its probably why most install instructions say cd extensions cd coqui_tts
nvm, linux only wants slashes, at least ubuntu does
if only we could pip install -r os_join('extensions', 'coqui_tts')... 😛
Haven't seen that, but yup, that's a way to get around it
indeed, but you'd need to do some special stuff to get the correct pip from within python
I was looking through XTTS webui, and saw they create a python subprocess that uses your custom venv to install RVC into a new venv.
so it's very doable
Feels soooooooooo good to delete those command option abominations
Just like that - /characters is now also updated
All done
Pushed to dev
Now must cook dinner
Going to update one more thing with that before commit to main - need to get the models/characters when cmd is sent now, rather than at init and storing them as global variables
all done, all done
Now, characters, llmmodel and imgmodel commands will get all current items in those locations
Not just building them on init
Done
I'll check them out later. I'll try to remember to move the bot file over
Select a Large Language Model Model
Welp, just noticed the Flows feature is bugged after recent updates
time to figure out why...
I don't think anyone understands how Flows work
The best way to understand it is just execute one of the examples
found one bug in it...
Fixed it
I screwed it up when I made the Tags system allow multiple format_prompt tags
Very simple example flow I made
What it does is it first prompts the image prompt character, for a prompt.
In this case it provided:
Ernest Ranglin playing a guitar in a warm and cozy setting, with a fireplace and a bookshelf in the background, soft lighting, warm colors, intimate atmosphere
The 'Flow' took that response and prefixed it with: Tell me an alternate version of this image prompt:
Then, sent it to the normal chat character with load_history: 1 and save_history: false
Another example flow....
This one just feeds the LLM response back to the same image prompt character, except prefixes it with Provide a more detailed version of this prompt:
Once one of you brainiacs understands how it works, I expect greatness to ensue 😎
The bot's reply can be used to dynamically set values for pending Flow Steps
such as with my Image Model Selector flow example
Before generating the image it will share the LLM's prompt to a character tailored to choose the most appropriate image model.
Then, the image is generated
Hmmm, hmmm. Pondering the possibilities
They are endless - especially if you take into consideration, I can just knock down any roadblocks to your amazing idea with this
Here, please
Try this example flow here... copy/paste it into your dict_tags.yaml
- trigger: 'flow test'
flow:
- flow_base:
should_gen_text: false
should_gen_image: false
- flow_step: Do literally nothing
flow_step_loops: 10
This will give an idea just how fast the message loop executes...
I did generate text each loop on this one… but used should_send_text: false. Tormenting the LLM
pretty nice short and sweet poem
Hmm, I am pondering the possibilities. Is it possible to include a prompt alongside the trigger? So you can have the bot iterate a response to that prompt?
The trigger never has to be seen if you use insert_text: ‘’ and insert_text_method: replace
you can use variables for recent messages like {user_0} is the most recent user msg
What's the code for the reimagine flow?
- trigger: 'followupreimagine,reimagine' # Intended to be used with a prompt like 'draw _______ check imgmodel'
insert_text: ''
insert_text_method: 'replace'
search_mode: user # Only search user's prompt (will not trigger from LLM reply)
should_send_text: true # Suppress text response (still generate text)
should_gen_image: false # Suppress image generation (won't send an image by default)
flow: # The actual 'Flow' tag value
- flow_base: # Flow_base are tags that apply to every flow_step
save_history: False # Do not write these interactions to the main chat history
load_history: 1 # 0 = default (all history), -1 = excludes chat history, > 1 = LLM sees this many recent exchanges.
- flow_step: Ask LLM to reimagine the prompt # text displayed in discord embed
format_prompt: 'Tell me an alternate version of this image prompt: {llm_0}'
should_gen_image: true
I put followupreimagine as a trigger so I could cancel it with this other tag I have
- trigger: 'reimagine'
format_prompt: 'Tell me an alternate version of this image prompt: {llm_0}'
on_prefix_only: true
search_mode: user
should_send_text: true
should_gen_image: true
trumps: followupreimagine
So the one is a Flow - engaging the LLM twice, two different characters.
The other tag is just to ask the chat character to 'reimagine' the image prompting characters previous reply
Here’s an interesting theoretical use…
- Have a context focused on choosing the best of two messages.
- Trigger a flow that asks for a short story or whatever, but loop it so you get two versions. The Dynamic Context feature could be used in the prompt so that it uses wildcards.
- 3rd flow step, show the two replies to the judging context
When I finally add the new behavior settings… coming soon… that will also allow automatic prompting, so something like this could be used autonomously
I mean technically you can already do that with some third party software that types shit into the box and hits enter
Yeah I was thinking about something to that effect. Maybe take a prompt and iterate responses with different parameters, to quickly figure out what's best for that model
Had an idea for regen / continue…
maybe I can keep track of message IDs paired with history length
When regen is called it can check if message.id in [stored_messages] then temporarily move that prompt to front
Make a copy of history, move that exchange pair to front
Yes I think every time it writes history it should add the message id to a list. When regen or continue is called it can match the id and count how deep it is and grab the same depth history
The other idea I had is maybe adding small buttons to all LLM replies
small regen and continue icon
Good morning Reality
Create a message class that contains a message_id attribute.
And have a function to render the history to text.
this function will take a list[Message] and output string.
You can use junp to a specific message by iterating backwards.
Create a copy of the list, and .pop until you reach the message with matching id.
Then feed this new list to the render function to create the temporary prompt!
I would help, but am on mobile right now
Morning ^^
The message class could also contain both internal and visible contents, and work as a replacement for the dict in the history manager
Do you mean like, it pops the message.id list as well as the history copy simultaneously? When it matches the message id, the history copy is now same length already?
TGWUI seems to ignore the text param (prompt) when using Regen (need more testing for Continue)
Seems to operate solely on history param
No no, there's only one history list.
History: list[Message] = []
class Message:
message_id:int
visible:str
internal:str
Each item in the history contains the internal, visible, and message id
But, when history is being sent off to tgwi, there can be a conversion to the format it expects
which is
dict {internal, visible}
I'll write this in a little bit
right… but prior history may have an effect as well (message before the message you want regenerated)
Can’t tell if what you are proposing slices actual history for lack of a better concise way of stating it (I know not literally slicing)
Mhm, this is just a way of grouping related data together so you dont have to handle 3 lists.
history = dict{internal=[], visible=[]}
messageids = []
when adding more attributes someday this could get out of hand.
So one solution is using an object or dict.
storage = [item1, item2..]
where item1 contains everything you need.
This is useful because you'll only need to update code once if you want to do changes in position of history or remove the last message.
I'll explain it with a working example later ^-^
so far everything you’ve suggested or done has been pure gold so I’m going to put my mind to something else 🤗
Must must must add those new behaviors
This isn’t my first big big project, my other one took 3 years before I was satisfied
The Mugen Fighters Guild - [WIP] Jailbot (from Superjail!) POST-RELEASE UPDATING
As with this endeavor, I jumped in with no prior experience with the application. I was occasionally putting out little signals inviting any veteran MUGEN dev to help which was never answered.
I am a hack when it comes to this python stuff.
It’s impossible to express the gratitude I have for your recent contributions @terse folio
Don’t want to make it weird or anything 🥹
Too late!
That MUGEN project came out quite good but would have been top tier if another experienced dev jumped in for a swim
That looks interesting, I like the animation, it looks like 3d modeling was used for reference for 2d sprites?
Happy to help 😸
I started off by amassing as much reference materal I could, and was using actual screencaps to trace and whatnot
I came up with a 3D model where everything could be animated the flaps and everything
And a post-processing method to force the colors down to a limited specific palette index
That project required coding, graphics, and sound engineering
That's awesome, shaders are cool!