Compare commits

...

3 Commits

Author SHA1 Message Date
a45b56fa93 docs: update README 2025-08-15 16:26:02 -06:00
14988023ff fix: remove shuffle macro 2025-08-15 16:24:47 -06:00
c6346e9119 feat: shuffle placeholder 2025-08-15 00:07:18 -06:00
4 changed files with 104 additions and 59 deletions

View File

@@ -1,15 +1,27 @@
# st-randomness-helpers
To install dependencies:
st-randomness-helpers is a extension for [SillyTavern](https://sillytavern.app/).
```bash
bun install
```
# Features
To run:
## WordLists
```bash
bun run index.ts
```
WordList are plaintext files containing one or more words per line. The name of the file is the name of the WordList.
This project was created using `bun init` in bun v1.2.17. [Bun](https://bun.sh) is a fast all-in-one JavaScript runtime.
## Macros
Register [macros](https://docs.sillytavern.app/usage/core-concepts/macros/) that are usually replaced with a value at save time.
## Placeholders
Placeholders are strings that are replaced with a value at generation time.
## Services
### RandomWord
Get a random word from a WordList. can be used as a Macro or a Placeholder. Macro format: `{{RandomWord::WordListName}}`. Placeholder format: `%%RandomWord:WordListName%%`.
### Shuffle
Shuffle a list of values. can be used as Placeholder only. Placeholder format: `%%Shuffle::Value1::Value2::Value3;;separator%%`. Example: `%%Shuffle::Value1::Value2::Value3;;, %%` will return `Value3, Value1, Value2`.

100
dist/index.js vendored

File diff suppressed because one or more lines are too long

View File

@@ -1,7 +1,9 @@
import { setupRandomWordPlaceholders } from '@/services/randomWord'
import { setupShufflePlaceholders } from '@/services/shuffle'
const initializePlaceholders = () => {
setupRandomWordPlaceholders()
setupShufflePlaceholders()
}
export default initializePlaceholders

31
src/services/shuffle.ts Normal file
View File

@@ -0,0 +1,31 @@
import type { generationData } from '@/types/SillyTavern'
const fishersYatesShuffle = <Type>(arr: Type[]): Type[] => {
const shuffled = [...arr]
for (let index = shuffled.length - 1; index > 0; index--) {
const secondIndex = Math.floor(Math.random() * (index + 1))
// @ts-ignore We know index and secondIndex are valid
;[shuffled[index], shuffled[secondIndex]] = [
shuffled[secondIndex],
shuffled[index]
]
}
return shuffled
}
const shufflePlaceholderRegex = /%%shuffle::([\w\W]*?)(;;[\w\W]*?)?%%/g
export const setupShufflePlaceholders = () => {
const { eventTypes, eventSource } = SillyTavern.getContext()
eventSource.on(eventTypes.GENERATE_AFTER_DATA, (chat: generationData) => {
chat.prompt = chat.prompt.replaceAll(
shufflePlaceholderRegex,
(_, toBeshuffleed: string, separator?: string) => {
const options = toBeshuffleed.split('::')
return fishersYatesShuffle(options).join(
separator !== undefined ? separator.substring(2) : ''
)
}
)
})
}