Replace notes with markdown guidebook

This commit is contained in:
SillyLossy
2023-04-24 13:05:38 +03:00
parent e8f89aaaa3
commit e0e5425664
26 changed files with 549 additions and 987 deletions

View File

@ -1,47 +0,0 @@
<html>
<head>
<title>Character Descriptions</title>
<link rel="stylesheet" href="/css/notes.css">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="/webfonts/NotoSans/stylesheet.css" rel="stylesheet">
</head>
<body>
<div id="main">
<div id="content">
<h2>Character description</h2>
<p>
Used to add the character description and the rest that the AI should know.<br><br>
For example, you can add information about the world in which the action takes place and describe
the characteristics for the character you are playing for.<br><br>
Usually it all takes 200-350 tokens.
</p>
<h3>Methods and format</h3>
<p>
For most Kobold's models the easiest way is to use a free form for description, and in each sentence it
is desirable to specify the name of the character.<br><br>
The entire description should be in one line without hyphenation.<br><br>
For example:<br><br>
<code>
Chloe is a female elf. Chloe wears black-white maid dress with green collar and red glasses. Chloe has medium length black hair. Chloe's personality is...
</code>
</p>
<p>
But that the AI would be less confused the best way is to use the W++ format.<Br><br>
Details here: <a target="_blank"
href="https://github.com/KoboldAI/KoboldAI-Client/wiki/Pro-Tips">Pro-Tips</a>
</p>
<hr>
<p>
<u>A list of tags that are replaced when sending to generate:</u><br><br>
{{user}} and &lt;USER&gt; are replaced by the User's Name<br>
{{char}} and &lt;BOT&gt; are replaced by the Character's Name
</p>
</div>
</div>
</body>
</html>

View File

@ -1,21 +0,0 @@
<html>
<head>
<title>Import Chat</title>
<link rel="stylesheet" href="/css/notes.css">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="/webfonts/NotoSans/stylesheet.css" rel="stylesheet">
</head>
<body>
<div id="main">
<div id="content">
<h2>Chat import</h2>
<h3>Import chats into SillyTavern</h3>
<p>To import Character.AI chats, use this tool: <a href="https://github.com/0x000011b/characterai-dumper">https://github.com/0x000011b/characterai-dumper</a>.</p>
</div>
</div>
</body>
</html>

View File

@ -1,35 +0,0 @@
<html>
<head>
<title>Example Dialogues</title>
<link rel="stylesheet" href="/css/notes.css">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="/webfonts/NotoSans/stylesheet.css" rel="stylesheet">
</head>
<body>
<div id="main">
<div id="content">
<h2>Examples of dialogue</h2>
<p>Describes how the character speaks. Before each example, you need to add the &lt;START&gt; tag.<br> Use {{char}} instead of the character name.<br> Use {{user}} instead of the user name.<br><br>Example:</p>
<p>&lt;START&gt;<br>{{user}}: Hi Aqua, I heard you like to spend time in the pub.<br>
{{char}}: *excitedly* Oh my goodness, yes! I just love spending time at the pub! It's so much fun to talk to all the adventurers and hear about their exciting adventures! And you are?<br>
{{user}}: I'm a new here and I wanted to ask for your advice.<br>
{{char}}: *giggles* Oh, advice! I love giving advice! And in gratitude for that, treat me to a drink! *gives signals to the bartender*
<br><br>&lt;START&gt;<br>
{{user}}: Hello<br>
{{char}}: *excitedly* Hello there, dear! Are you new to Axel? Don't worry, I, Aqua the goddess of water, am here to help you! Do you need any assistance? And may I say, I look simply radiant today! *strikes a pose and looks at you with puppy eyes*
</p>
<hr>
<p>
<u>A list of tags that are replaced when sending to generate:</u><br><br>
{{user}} and &lt;USER&gt; are replaced by the User's Name<br>
{{char}} and &lt;BOT&gt; are replaced by the Character's Name
</p>
</div>
</div>
</body>
</html>

View File

@ -1,28 +0,0 @@
<html>
<head>
<title>Scenario</title>
<link rel="stylesheet" href="/css/notes.css">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="/webfonts/NotoSans/stylesheet.css" rel="stylesheet">
</head>
<body>
<div id="main">
<div id="content">
<h2>Scenario</h2>
<p>
Circumstances and context of the dialogue.
</p>
<hr>
<p>
<u>A list of tags that are replaced when sending to generate:</u><br><br>
{{user}} and &lt;USER&gt; are replaced by the User's Name<br>
{{char}} and &lt;BOT&gt; are replaced by the Character's Name
</p>
</div>
</div>
</body>
</html>

View File

@ -1,35 +0,0 @@
<html>
<head>
<title>World Info</title>
<link rel="stylesheet" href="/css/notes.css">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="/webfonts/NotoSans/stylesheet.css" rel="stylesheet">
</head>
<body>
<div id="main">
<div id="content">
<h2>World Info</h2>
<h4>World Info enhances AI's understanding of the details in your world.</h4>
<p>It functions like a dynamic dictionary that only inserts relevant information from World Info entries
when keywords associated with the entries are present in the message text.</p>
<p>The SillyTavern engine activates and seamlessly integrates the appropriate lore into the prompt,
providing background information to the AI.</p>
<p><i>It is important to note that while World Info helps guide the AI towards your desired lore, it does
not guarantee its appearance in the generated output messages.</i></p>
<h3>Pro Tips</h3>
<ul>
<li>The AI does not insert keywords into context, so each World Info entry should be a comprehensive,
standalone description.</li>
<li>To create a rich and detailed world lore, entries can be interlinked and reference one another.</li>
<li>To conserve tokens, it is advisable to keep entry contents concise, with a general recommended limit
of 50 tokens per entry.</li>
</ul>
</div>
</div>
</body>
</html>

View File

@ -1,22 +0,0 @@
<html>
<head>
<title>Scan Depth</title>
<link rel="stylesheet" href="/css/notes.css">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="/webfonts/NotoSans/stylesheet.css" rel="stylesheet">
</head>
<body>
<div id="main">
<div id="content">
<h2>Scan Depth</h2>
<h4>Defines how many messages in the chat history should be scanned for World Info keys.</h4>
<p>If set to 1, then SillyTavern only scans the message you send and the most recent reply.</p>
<p>This stacks up to 10 message pairs it total.</p>
</div>
</div>
</body>
</html>

View File

@ -1,23 +0,0 @@
<html>
<head>
<title>Budget</title>
<link rel="stylesheet" href="/css/notes.css">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="/webfonts/NotoSans/stylesheet.css" rel="stylesheet">
</head>
<body>
<div id="main">
<div id="content">
<h2>World Info Budget</h2>
<h4>Defines how many tokens could be used by World Info entries at once.</h4>
<p>If the budget was exhausted, then no more entries are activated even if the keys are present in the prompt.</p>
<p>Constant entries will be inserted first. Then entries with higher order numbers.</p>
<p>Entries inserted by direct mentioning of their keys have higher priority than those that were mentioned in other entries contents.</p>
</div>
</div>
</body>
</html>

View File

@ -1,87 +0,0 @@
<html>
<head>
<title>Entry Fields</title>
<link rel="stylesheet" href="/css/notes.css">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="/webfonts/NotoSans/stylesheet.css" rel="stylesheet">
</head>
<body>
<div id="main">
<div id="content">
<h2>
World Info Entry
</h2>
<p></p>
<h3>
Key
</h3>
<p>
A list of keywords that trigger the activation of a World Info entry.
</p>
<h3>
Secondary Key
</h3>
<p>
A list of supplementary keywords that are used in conjunction with the main keywords (see <a
href="#Selective">Selective</a>).
</p>
<h3>
Content
</h3>
<p>
The text that is inserted into the prompt upon entry activation.
</p>
<h3>
Insertion Order
</h3>
<p>
Numeric value. Defines a priority of the entry if multiple were activated at once. Entries with higher
order number will be inserted closer to the end of the context as they will have more impact on the output.
</p>
<h3>
Insertion Position
</h3>
<p>
<ul>
<li>
<b>Before Chara:</b>
World Info entry is inserted before the character's description and
scenario. Has moderate impact on the conversation.
</li>
<li>
<b>After Chara:</b>
World Info entry is inserted after the character's description and
scenario. Has greater impact on the conversation.
</li>
</ul>
</p>
<h3>
Comment
</h3>
<p>
A supplemental text comment for your convenience, which is not utilized by the AI.
</p>
<h3>
Constant
</h3>
<p>
If enabled, the entry would always be present in the prompt.
</p>
<h3 id="Selective">
Selective
</h3>
<p>
If enabled, the entry would only be inserted when both a Key <b>AND</b> a Secondary Key have been
activated.
</p>
<p>
If no secondary keys provided, this flag is ignored.
</p>
</div>
</div>
</body>
</html>

View File

@ -1,28 +0,0 @@
<html>
<head>
<title>Soft Prompts</title>
<link rel="stylesheet" href="/css/notes.css">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="/webfonts/NotoSans/stylesheet.css" rel="stylesheet">
</head>
<body>
<div id="main">
<div id="content">
<h2>Soft Prompts</h2>
<h4>Soft Prompts allow you to customize the style and behavior of your AI.</h4>
<p>
They are created by training the AI with a special type of prompt using a collection of input data.
Experimenting with different soft prompts can lead to exciting and unique results.
The most successful soft prompts are those that align the AI's output with a literary genre, fictional universe, or the style of a particular author.
</p>
<hr>
<h3>Common Misconceptions</h3>
<ul>
<li>Soft prompts do not provide new information to the model, but can effectively influence the model's tone, word choice, and formatting.</li>
<li>Soft prompts are not a means of compressing a full prompt into a limited token space. Instead, they provide a way to guide the language model's output through data in the context.</li>
</ul>
</div>
</div>
</body>
</html>

View File

@ -1,22 +0,0 @@
<html>
<head>
<title>Favorite Character</title>
<link rel="stylesheet" href="/css/notes.css">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="/webfonts/NotoSans/stylesheet.css" rel="stylesheet">
</head>
<body>
<div id="main">
<div id="content">
<h2>Favorite Character</h2>
<p>
Mark character as favorite to quickly filter on the side menu bar by pressing the star button.
</p>
</div>
</div>
</body>
</html>

View File

@ -1,39 +0,0 @@
<html>
<head>
<title>Personality Summary</title>
<link rel="stylesheet" href="/css/notes.css">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="/webfonts/NotoSans/stylesheet.css" rel="stylesheet">
</head>
<body>
<div id="main">
<div id="content">
<h2>Personality summary</h2>
<p>
A brief description of the personality. It is added to the chat at a depth of 8-15 messages, so it has a
significant impact on the character.
</p>
Example:
<br><br>
<code>Cheerful, cunning, provocative</code>
<Br>
Another example:
<br><br>
<code>Aqua likes to do nothing and also likes to get drunk</code>
<p>*In Pygmalion model, it is used as a "Personality:" graph</p>
<hr>
<p>
<u>A list of tags that are replaced when sending to generate:</u><br><br>
{{user}} and &lt;USER&gt; are replaced by the User's Name<br>
{{char}} and &lt;BOT&gt; are replaced by the Character's Name
</p>
</div>
</div>
</body>
</html>

View File

@ -1,40 +0,0 @@
<html>
<head>
<title>First Message</title>
<link rel="stylesheet" href="/css/notes.css">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="/webfonts/NotoSans/stylesheet.css" rel="stylesheet">
</head>
<body>
<div id="main">
<div id="content">
<h2>First message</h2>
<p>
The First Message is an important thing that sets exactly how and in what style the character will
communicate.<Br><br>
It is desirable that the character's first message be long, so that later it would be less likely that
the character would respond in with very short messages. <br><br>
You can also use asterisks ** to describe the character's actions.
</P>
For example:
<br><br>
<code>
*I noticed you came inside, I walked up and stood right in front of you* Welcome. I'm glad to see you here.
*I said with toothy smug sunny smile looking you straight in the eye* What brings you...
</code>
<Br>
<hr>
<p>
<u>A list of tags that are replaced when sending to generate:</u><br><br>
{{user}} and &lt;USER&gt; are replaced by the User's Name<br>
{{char}} and &lt;BOT&gt; are replaced by the Character's Name
</p>
</div>
</div>
</body>
</html>

View File

@ -1,101 +0,0 @@
<html>
<head>
<title>KoboldAI Settings</title>
<link rel="stylesheet" href="/css/notes.css">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="/webfonts/NotoSans/stylesheet.css" rel="stylesheet">
</head>
<body>
<div id="main">
<div id="content">
<h2>KoboldAI Settings</h2>
<p>Standard KoboldAI settings files are used here. To add your own settings, simply add the file .settings
in SillyTavern\public\KoboldAI Settings
</p>
<h3>Temperature</h3>
<p>Value from 0.1 to 2.0. Lower value - the answers are more logical, but less creative. Higher value - the
answers are more creative, but less logical.</p>
<h3>Repetition penalty</h3>
<p>Repetition penalty is responsible for the penalty of repeated words. If the character is fixated on
something or repeats the same phrase, then increasing this parameter will fix it. It is not recommended
to increase this parameter too much for the chat format, as it may break this format. The standard value
for chat is approximately 1.0 - 1.05</p>
<h3>Repetition penalty range</h3>
<p>The range of influence of Repetition penalty in tokens.</p>
<h3>Amount generation</h3>
<p>The maximum amount of tokens that the AI will generate to respond. One word is approximately 3-4 tokens.
The larger the parameter value, the longer the generation time takes.</p>
<h3>Context size</h3>
<p>How much will the AI remember. Context size also affects the speed of generation.<br><br>
<u>Important</u>: The setting of Context Size in SillyTavern GUI overrides the setting for KoboldAI GUI
</p>
<h2>Advanced Settings</h2>
<p>
The settings provided in this section offer a more detailed level of control over the text generation
process. It is important to be careful when making changes to these settings without proper
consideration, as doing so may result in degraded quality of responses.
</p>
<h3>Single-line mode</h3>
<p>
In single-line mode the AI generates only one line per request. This allows for quicker generation of
shorter prompts, but it does not produce responses that consist of more than one line.
</p>
<h3>Top P Sampling</h3>
<p>
This setting controls how much of the text generated is based on the most likely options.
Only words with the highest probabilities, together summing up to P, are considered. A word is then
chosen at random, with a higher chance of selecting words with higher probabilities.
</p>
<p>
Set value to 1 to disable its effect.
</p>
<h3>Top K Sampling</h3>
<p>
This setting limits the number of words to choose from to the top K most likely options. Can be used
together with Top P sampling.
</p>
<p>
Set value to 0 to disable its effect.
</p>
<h3>Top A Sampling</h3>
<p>
This setting allows for a more flexible version of sampling, where the number of words chosen from
the most likely options is automatically determined based on the likelihood distribution of the options,
but instead of choosing the top P or K words, it chooses all words with probabilities above a certain
threshold.
</p>
<p>
Set value to 0 to disable its effect.
</p>
<h3>Typical Sampling</h3>
<p>
This setting selects words randomly from the list of possible words, with each word having an equal
chance of being selected. This method can produce text that is more diverse but may also be less
coherent.
</p>
<p>
Set value to 1 to disable its effect.
</p>
<h3>Tail Free Sampling</h3>
<p>
This setting removes the least probable words from consideration during text generation, which can
improve the quality and coherence of the generated text.
</p>
<p>
Set value to 1 to disable its effect.
</p>
<h3>Repetition Penalty Slope</h3>
<p>
If both this and Repetition Penalty Range are above 0, then repetition penalty will have more effect
closer to the end of the prompt. The higher the value, the stronger the effect.
</p>
<p>Set value to 1 for linear interpolation or 0 to disable interpolation.</p>
</div>
</div>
</body>
</html>

View File

@ -1,37 +0,0 @@
<html>
<head>
<title>NovelAI API Key</title>
<link rel="stylesheet" href="/css/notes.css">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="/webfonts/NotoSans/stylesheet.css" rel="stylesheet">
</head>
<body>
<div id="main">
<div id="content">
<h2>Finding your NAI API key</h2>
<h4>To get a NovelAI API key, follow these instructions:</h4>
<p>
1. Go to the NovelAI website and Login.<br><br>
2. Create a new story, or open an existing story.<br><br>
3. Open the Network Tools on your web browser. (For Chrome or Firefox, you do this by pressing
Ctrl+Shift+I, then switching to the Network tab.)<br><br>
4. Generate something. You should see two requests to api.novelai.net/ai/generate-stream, which might
look something like this:<br><br>
<img src="1.png"><br><br>
5. Select the second request, then in the Headers tab of the inspection panel, scroll down to the very
bottom. Look for a header called Authorization:<br><br>
<img src="2.png"><br><br>
The long string (after "Bearer", not including it) is your API key.<br><br>
* Proxies and Cloudflare-type services may interfere with connection.
</p>
</div>
</div>
</body>
</html>

View File

@ -1,43 +0,0 @@
<html>
<head>
<title>NovelAI Settings</title>
<link rel="stylesheet" href="/css/notes.css">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="/webfonts/NotoSans/stylesheet.css" rel="stylesheet">
</head>
<body>
<div id="main">
<div id="content">
<h2>NovelAI settings</h2>
<p>
The files with the settings are here (SillyTavern\public\NovelAI Settings).<br>
You can also manually add your own settings files.
</p>
<h3>Temperature</h3>
<p>
Value from 0.1 to 2.0. <br>
Lower value - the answers are more logical, but less creative. <br>
Higher value - the answers are more creative, but less logical.
</p>
<h3>Repetition penalty</h3>
<p>
Repetition penalty is responsible for the penalty of repeated words. <br>
If the character is fixated on something or repeats the same phrase, then increasing this parameter will
fix it. <br>
It is not recommended to increase this parameter too much for the chat format, as it may break this
format. <br>
<b>The standard value for chat is approximately 1.0 - 1.05</b>
</p>
<h3>Repetition penalty range</h3>
<p>
The range of influence of Repetition penalty in tokens.
</p>
</div>
</div>
</body>
</html>

View File

@ -1,20 +0,0 @@
<html>
<head>
<title>NovelAI Models</title>
<link rel="stylesheet" href="/css/notes.css">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="/webfonts/NotoSans/stylesheet.css" rel="stylesheet">
</head>
<body>
<div id="main">
<div id="content">
<h2>NovelAI Models</h2>
<p>If your subscription tier is Paper, Tablet or Scroll use only Euterpe model otherwise you can not get an answer from NovelAI API.</p>
</div>
</div>
</body>
</html>

View File

@ -1,53 +0,0 @@
<html>
<head>
<title>Anchors</title>
<link rel="stylesheet" href="/css/notes.css">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="/webfonts/NotoSans/stylesheet.css" rel="stylesheet">
</head>
<body>
<div id="main">
<div id="content">
<h2>Anchors</h2>
<p>
Anchors are used to increase the length of messages.<br>
There are two types of anchors: <u>Character Anchor</u> and <u>Style Anchor</u>
</p>
<p>
<u>Character Anchor</u> - affects the character played by the AI by motivating it to write longer
messages.<br><br>
Looks like:
<code>[Elaborate speaker]</code>
</p>
<p>
<u>Style Anchor</u> - affects the entire AI model, motivating the AI to write longer messages even when
it is not acting as the character.<Br><br>
Looks like:
<code>[Writing style: very long messages]</code>
</p>
<hr>
<p>
Anchors Order sets the location of anchors in the promt, the first anchor in the order is much further
back in the context and thus has less influence than second.
</p>
<p>
The second anchor is only turned on after 8-12 messages, because when the chat still only has a few
messages, the first anchor creates enough effect on its own.
</p>
<p>
Sometimes an AI model may not perceive anchors correctly or the AI model already generates sufficiently
long messages.
For these cases, you can disable the anchors by unchecking their respective boxes.
</p>
<p>
<u>When using Pygmalion models these anchors are automatically disabled, since Pygmalion already
generates long enough messages.</u>
</p>
</div>
</div>
</body>
</html>

View File

@ -1,87 +0,0 @@
<html>
<head>
<title>Advanced Formatting</title>
<link rel="stylesheet" href="/css/notes.css">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="/webfonts/NotoSans/stylesheet.css" rel="stylesheet">
</head>
<body>
<div id="main">
<div id="content">
<h2>Advanced Formatting</h2>
<p>
The settings provided in this section allow for more control over the prompt building strategy.
Most specifics of the prompt building depend on whether a Pygmalion model is selected or special formatting is force-enabled.
The core differences between the formatting schemas are listed below.
</p>
<h3>Custom Chat Separator</h3>
<p>
Overrides the default separators controlled by "Disable example chats formatting" and "Disable chat start formatting" options (see below).
</p>
<h3>For <u>Pygmalion</u> formatting</h3>
<h4>Disable description formatting</h4>
<p>
<code><b>NAME's Persona: </b></code> won't be prepended to the content of your character's Description box.
</p>
<h4>Disable scenario formatting</h4>
<p>
<code><b>Scenario: </b></code> won't be prepended to the content of your character's Scenario box.
</p>
<h4>Disable personality formatting</h4>
<p>
<code><b>Personality: </b></code> won't be prepended to the content of your character's Personality box.
</p>
<h4>Disable example chats formatting</h4>
<p>
<code>&lt;START&gt;</code> won't be added at the beginning of each example message block.<br>
<i>(If custom separator is not set)</i>
</p>
<h4>Disable chat start formatting</h4>
<p>
<code>&lt;START&gt;</code> won't be added between the character card and the chat log.<br>
<i>(If custom separator is not set)</i>
</p>
<h4>Always add character's name to prompt</h4>
<p>
Doesn't do anything (Included in Pygmalion formatting).
</p>
<h3>For <u>non-Pygmalion</u> formatting</h3>
<h4>Disable description formatting</h4>
<p>
Has no effect.
</p>
<h4>Disable scenario formatting</h4>
<p>
<code><b>Circumstances and context of the dialogue: </b></code> won't be prepended to the content of your character's Scenario box.
</p>
<h4>Disable personality formatting</h4>
<p>
<code><b>NAME's personality: </b></code> won't be prepended to the content of your character's Personality box.
</p>
<h4>Disable example chats formatting</h4>
<p>
<code>This is how <b>Character</b> should talk</code> won't be added at the beginning of each example message block.<br>
<i>(If custom separator is not set)</i>
</p>
<h4>Disable chat start formatting</h4>
<p>
<code>Then the roleplay chat between <b>User</b> and <b>Character</b> begins</code> won't be added between the character card and the chat log.<br>
<i>(If custom separator is not set)</i>
</p>
<h4>Always add character's name to prompt</h4>
<p>
Appends character's name to the prompt to force the model to complete the message as the character:
</p>
<code>
** OTHER CONTEXT HERE **<br>
Character:
</code>
</div>
</div>
</body>
</html>

521
public/notes/content.md Normal file
View File

@ -0,0 +1,521 @@
# SillyTavern Guidebook
[toc]
## Character Design
### Character description
Used to add the character description and the rest that the AI should know.
For example, you can add information about the world in which the action takes place and describe the characteristics for the character you are playing for.
Usually it all takes 200-350 tokens.
### Methods and format
For most Kobold's models the easiest way is to use a free form for description, and in each sentence it is desirable to specify the name of the character.
The entire description should be in one line without hyphenation.
For example:
`Chloe is a female elf. Chloe wears black-white maid dress with green collar and red glasses. Chloe has medium length black hair. Chloe's personality is...`
But that the AI would be less confused the best way is to use the W++ format.
Details here: [Pro-Tips](https://github.com/KoboldAI/KoboldAI-Client/wiki/Pro-Tips)
### Character tokens
**TL;DR: If you're working with an AI model with a 2048 context token limit, your 1000 token character definition is cutting the AI's 'memory' in half.**
To put this in perspective, a decent response from a good AI can easily be around 200-300 tokens. In this case, the AI would only be able to 'remember' about 3 exchanges worth of chat history.
***
### Why did my character's token counter turn red?
When we see your character has over 1000 tokens in its definitions, we highlight it for you because this can lower the AI's capabilities to provide an enjoyable conversation.
### What happens if my Character has too many tokens?
Don't worry - it won't break anything. At worst, if the Character's permanent tokens are too large, it simply means there will be less room left in the context for other things (see below).
The only negative side effect this can have is the AI will have less 'memory', as it will have less chat history available to process.
This is because every AI model has a limit to the amount of context it can process at one time.
### 'Context'?
This is the information that gets sent to the AI each time you ask it to generate a response:
* Character definitions
* Chat history
* Author's Notes
* Special Format strings
* [bracket commands]
SillyTavern automatically calculates the best way to allocate the available context tokens before sending the information to the AI model.
### What are a Character's 'Permanent Tokens'?
These will always be sent to the AI with every generation request:
* Character Name (keep the name short! Sent at the start of EVERY Character message)
* Character Description Box
* Character Personality Box
* Scenario Box
### What parts of a Character's Definitions are NOT permanent?
* The first message box - only sent once at the start of the chat.
* Example messages box - only kept until chat history fills up the context (optionally these can be forced to be kept in context)
### Popular AI Model Context Token Limits
* Older models below 6B parameters - 1024
* Pygmalion 6B - 2048
* Poe.com (Claude-instant or ChatGPT) - 2048
* OpenAI ChatGPT - 4000-ish?
* OpenAI GPT-4 - 8000?
### Personality summary
A brief description of the personality. It is added to the chat at a depth of 8-15 messages, so it has a significant impact on the character.
Example:
`Cheerful, cunning, provocative`
Another example:
`Aqua likes to do nothing and also likes to get drunk`
* In Pygmalion model, it is used as a "Personality:" prompt section
### First message
The First Message is an important thing that sets exactly how and in what style the character will communicate.
It is desirable that the character's first message be long, so that later it would be less likely that the character would respond in with very short messages.
You can also use asterisks ** to describe the character's actions.
For example:
`*I noticed you came inside, I walked up and stood right in front of you* Welcome. I'm glad to see you here. *I said with toothy smug sunny smile looking you straight in the eye* What brings you...`
### Examples of dialogue
Describes how the character speaks. Before each example, you need to add the <START> tag.
Use {{char}} instead of the character name.
Use {{user}} instead of the user name.
Example:
`
<START>
{{user}}: Hi Aqua, I heard you like to spend time in the pub.
{{char}}: *excitedly* Oh my goodness, yes! I just love spending time at the pub! It's so much fun to talk to all the adventurers and hear about their exciting adventures! And you are?
{{user}}: I'm a new here and I wanted to ask for your advice.
{{char}}: *giggles* Oh, advice! I love giving advice! And in gratitude for that, treat me to a drink! *gives signals to the bartender*
<START>
{{user}}: Hello
{{char}}: *excitedly* Hello there, dear! Are you new to Axel? Don't worry, I, Aqua the goddess of water, am here to help you! Do you need any assistance? And may I say, I look simply radiant today! *strikes a pose and looks at you with puppy eyes*
`
### Scenario
Circumstances and context of the dialogue.
### Replacement tags
_A list of tags that are replaced when sending to generate:_
1. {{user}} and <USER> are replaced by the User's Name
2. {{char}} and <BOT> are replaced by the Character's Name
### Favorite Character
Mark character as favorite to quickly filter on the side menu bar by pressing the star button.
## World Info
**World Info enhances AI's understanding of the details in your world.**
It functions like a dynamic dictionary that only inserts relevant information from World Info entries when keywords associated with the entries are present in the message text.
The SillyTavern engine activates and seamlessly integrates the appropriate lore into the prompt, providing background information to the AI.
_It is important to note that while World Info helps guide the AI towards your desired lore, it does not guarantee its appearance in the generated output messages._
### Pro Tips
* The AI does not insert keywords into context, so each World Info entry should be a comprehensive, standalone description.
* To create a rich and detailed world lore, entries can be interlinked and reference one another.
* To conserve tokens, it is advisable to keep entry contents concise, with a general recommended limit of 50 tokens per entry.
### World Info Entry
#### Key
A list of keywords that trigger the activation of a World Info entry.
#### Secondary Key
A list of supplementary keywords that are used in conjunction with the main keywords (see [Selective](#selective)).
#### Content
The text that is inserted into the prompt upon entry activation.
#### Insertion Order
Numeric value. Defines a priority of the entry if multiple were activated at once. Entries with higher order number will be inserted closer to the end of the context as they will have more impact on the output.
#### Insertion Position
* **Before Chara:** World Info entry is inserted before the character's description and scenario. Has moderate impact on the conversation.
* **After Chara:** World Info entry is inserted after the character's description and scenario. Has greater impact on the conversation.
#### Comment
A supplemental text comment for your convenience, which is not utilized by the AI.
#### Constant
If enabled, the entry would always be present in the prompt.
#### Selective
If enabled, the entry would only be inserted when both a Key **AND** a Secondary Key have been activated.
If no secondary keys provided, this flag is ignored.
### Scan Depth
Defines how many messages in the chat history should be scanned for World Info keys.
If set to 1, then SillyTavern only scans the message you send and the most recent reply.
This stacks up to 10 message pairs it total.
### Budget
**Defines how many tokens could be used by World Info entries at once.**
If the budget was exhausted, then no more entries are activated even if the keys are present in the prompt.
Constant entries will be inserted first. Then entries with higher order numbers.
Entries inserted by direct mentioning of their keys have higher priority than those that were mentioned in other entries contents.
## KoboldAI
### Basic Settings
Standard KoboldAI settings files are used here. To add your own settings, simply add the file .settings in `SillyTavern\public\KoboldAI Settings`
#### Temperature
Value from 0.1 to 2.0. Lower value - the answers are more logical, but less creative. Higher value - the answers are more creative, but less logical.
#### Repetition penalty
Repetition penalty is responsible for the penalty of repeated words. If the character is fixated on something or repeats the same phrase, then increasing this parameter will fix it. It is not recommended to increase this parameter too much for the chat format, as it may break this format. The standard value for chat is approximately 1.0 - 1.05.
#### Repetition penalty range
The range of influence of Repetition penalty in tokens.
#### Amount generation
The maximum amount of tokens that the AI will generate to respond. One word is approximately 3-4 tokens. The larger the parameter value, the longer the generation time takes.
#### Context size
How much will the AI remember. Context size also affects the speed of generation.
_Important_: The setting of Context Size in SillyTavern GUI overrides the setting for KoboldAI GUI
### Advanced Settings
The settings provided in this section offer a more detailed level of control over the text generation process. It is important to be careful when making changes to these settings without proper consideration, as doing so may result in degraded quality of responses.
#### Single-line mode
In single-line mode the AI generates only one line per request. This allows for quicker generation of shorter prompts, but it does not produce responses that consist of more than one line.
#### Top P Sampling
This setting controls how much of the text generated is based on the most likely options. Only words with the highest probabilities, together summing up to P, are considered. A word is then chosen at random, with a higher chance of selecting words with higher probabilities.
Set value to 1 to disable its effect.
#### Top K Sampling
This setting limits the number of words to choose from to the top K most likely options. Can be used together with Top P sampling.
Set value to 0 to disable its effect.
#### Top A Sampling
This setting allows for a more flexible version of sampling, where the number of words chosen from the most likely options is automatically determined based on the likelihood distribution of the options, but instead of choosing the top P or K words, it chooses all words with probabilities above a certain threshold.
Set value to 0 to disable its effect.
#### Typical Sampling
This setting selects words randomly from the list of possible words, with each word having an equal chance of being selected. This method can produce text that is more diverse but may also be less coherent.
Set value to 1 to disable its effect.
#### Tail Free Sampling
This setting removes the least probable words from consideration during text generation, which can improve the quality and coherence of the generated text.
Set value to 1 to disable its effect.
#### Repetition Penalty Slope
If both this and Repetition Penalty Range are above 0, then repetition penalty will have more effect closer to the end of the prompt. The higher the value, the stronger the effect.
Set value to 1 for linear interpolation or 0 to disable interpolation.
### Soft Prompts
**Soft Prompts allow you to customize the style and behavior of your AI.**
They are created by training the AI with a special type of prompt using a collection of input data. Experimenting with different soft prompts can lead to exciting and unique results. The most successful soft prompts are those that align the AI's output with a literary genre, fictional universe, or the style of a particular author.
#### Common Misconceptions
* Soft prompts do not provide new information to the model, but can effectively influence the model's tone, word choice, and formatting.
* Soft prompts are not a means of compressing a full prompt into a limited token space. Instead, they provide a way to guide the language model's output through data in the context.
## NovelAI
### API Key
To get a NovelAI API key, follow these instructions:
1. Go to the NovelAI website and Login.
2. Create a new story, or open an existing story.
3. Open the Network Tools on your web browser. (For Chrome or Firefox, you do this by pressing Ctrl+Shift+I, then switching to the Network tab.)
4. Generate something. You should see two requests to [api.novelai.net/ai/generate-stream](http://api.novelai.net/ai/generate-stream), which might look something like this:
![1.png](1.png)
5. Select the second request, then in the Headers tab of the inspection panel, scroll down to the very bottom. Look for a header called Authorization:
![2.png](2.png)
The long string (after "Bearer", not including it) is your API key.
* Proxies and Cloudflare-type services may interfere with connection.
### Settings
The files with the settings are here (SillyTavern\public\NovelAI Settings).
You can also manually add your own settings files.
#### Temperature
Value from 0.1 to 2.0
Lower value - the answers are more logical, but less creative.
Higher value - the answers are more creative, but less logical.
#### Repetition penalty
Repetition penalty is responsible for the penalty of repeated words.
If the character is fixated on something or repeats the same phrase, then increasing this parameter will fix it.
It is not recommended to increase this parameter too much for the chat format, as it may break this format.
**The standard value for chat is approximately 1.0 - 1.05**
#### Repetition penalty range
The range of influence of Repetition penalty in tokens.
### Models
If your subscription tier is Paper, Tablet or Scroll use only Euterpe model otherwise you can not get an answer from NovelAI API.
## OpenAI
### API key
**How to get:**
1. Go to [OpenAI](https://platform.openai.com/) and sign in.
2. Use "[View API keys](https://platform.openai.com/account/api-keys)" option to create a new API key.
**Important!**
_Lost API keys can't be restored! Make sure to keep it safe!_
## Anchors
Anchors are used to increase the length of messages.
There are two types of anchors: _Character Anchor_ and _Style Anchor_.
_Character Anchor_ - affects the character played by the AI by motivating it to write longer messages.
Looks like: `[Elaborate speaker]`
_Style Anchor_ - affects the entire AI model, motivating the AI to write longer messages even when it is not acting as the character.
Looks like: `[Writing style: very long messages]`
***
Anchors Order sets the location of anchors in the prompt, the first anchor in the order is much further back in the context and thus has less influence than second.
The second anchor is only turned on after 8-12 messages, because when the chat still only has a few messages, the first anchor creates enough effect on its own.
Sometimes an AI model may not perceive anchors correctly or the AI model already generates sufficiently long messages. For these cases, you can disable the anchors by unchecking their respective boxes.
_When using Pygmalion models these anchors are automatically disabled, since Pygmalion already generates long enough messages._
## Chat import
**Import chats into SillyTavern**
To import Character.AI chats, use this tool: [https://github.com/0x000011b/characterai-dumper](https://github.com/0x000011b/characterai-dumper).
## Advanced Formatting
The settings provided in this section allow for more control over the prompt building strategy. Most specifics of the prompt building depend on whether a Pygmalion model is selected or special formatting is force-enabled. The core differences between the formatting schemas are listed below.
### Custom Chat Separator
Overrides the default separators controlled by "Disable example chats formatting" and "Disable chat start formatting" options (see below).
### For _Pygmalion_ formatting
#### Disable description formatting
`**NAME's Persona:** `won't be prepended to the content of your character's Description box.
#### Disable scenario formatting
`**Scenario:** `won't be prepended to the content of your character's Scenario box.
#### Disable personality formatting
`**Personality:** `won't be prepended to the content of your character's Personality box.
#### Disable example chats formatting
`<START>` won't be added at the beginning of each example message block.
_(If custom separator is not set)_
#### Disable chat start formatting
`<START>` won't be added between the character card and the chat log.
_(If custom separator is not set)_
#### Always add character's name to prompt
Doesn't do anything (Included in Pygmalion formatting).
### For _non-Pygmalion_ formatting
#### Disable description formatting
Has no effect.
#### Disable scenario formatting
`**Circumstances and context of the dialogue:** `won't be prepended to the content of your character's Scenario box.
#### Disable personality formatting
`**NAME's personality:** `won't be prepended to the content of your character's Personality box.
#### Disable example chats formatting
`This is how **Character** should talk` won't be added at the beginning of each example message block.
_(If custom separator is not set)_
#### Disable chat start formatting
`Then the roleplay chat between **User** and **Character** begins` won't be added between the character card and the chat log.
_(If custom separator is not set)_
#### Always add character's name to prompt
Appends character's name to the prompt to force the model to complete the message as the character:
```
** OTHER CONTEXT HERE **
Character:
```
## Group Chats
### Reply order strategies
Decides how characters in group chats are drafted for their replies.
#### Natural order
Tries to simulate the flow of a real human conversation. The algorithm is as follows:
1. Mentions of the group member names are extracted from the last message in chat.
Only whole words are recognized as mentions! If your character's name is "Misaka Mikoto", they will reply only activate on "Misaka" or "Mikoto", but never to "Misa", "Railgun", etc.
Unless "Allow bot responses to self" setting is enabled, characters won't reply to mentions of their name in their own message!
2. Characters are activated by the "Talkativeness" factor.
Talkativeness defines how often the character speaks if they were not mentioned. Adjust this value on "Advanced definitions" screen in character editor. Slider values are on a linear scale from **0% / Shy** (character never talks unless mentioned) to **100% / Chatty** (character always replies). Default value for new characters is 50% chance.
3. Random character is selected.
If no characters were activated at previous steps, one speaker is selected randomly, ignoring all other conditions.
#### List order
Characters are drafted based on the order they are presented in group members list. No other rules apply.
## Multigen
SillyTavern tries to create faster and longer responses by chaining the generation using smaller batches.
### Default settings:
First batch = 50 tokens
Next batches = 30 tokens
### Algorithm:
1. Generate the first batch (if amount of generation setting is more than batch length).
2. Generate next batch of tokens until one of the stopping conditions is reached.
3. Append the generated text to the next cycle's prompt.
### Stopping conditions:
1. Generated enough text.
2. Character starts speaking for You.
3. <|endoftext|> token reached.
4. No text generated.
## User Settings
### Message Sound
To play your own custom sound on receiving a new message from bot, replace the following MP3 file in your SillyTavern folder:
`public/sounds/message.mp3`
Plays at 80% volume.
If "Background Sound Only" option is enabled, the sound plays only if SillyTavern window is **unfocused**.

View File

@ -1,59 +0,0 @@
<html>
<head>
<title>Group reply order strategies</title>
<link rel="stylesheet" href="/css/notes.css">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="/webfonts/NotoSans/stylesheet.css" rel="stylesheet">
</head>
<body>
<div id="main">
<div id="content">
<h2>Group reply order strategies</h2>
<p>
Decides how characters in group chats are drafted for their replies.
</p>
<h3>Natural order</h3>
<p>
Tries to simulate the flow of a real human conversation. The algorithm is as follows:
</p>
<h4>1. Mentions of the group member names are extracted from the last message in chat.</h4>
<p>
Only whole words are recognized as mentions!
If your character's name is "Misaka Mikoto", they will reply only activate on "Misaka" or "Mikoto", but
never to "Misa", "Railgun", etc.
</p>
<p>
Unless "Allow bot responses to self" setting is enabled, characters won't reply to mentions of their
name in their own message!
</p>
<h4>2. Characters are activated by the "Talkativeness" factor.</h4>
<p>
Talkativeness defines how often the character speaks if they were not mentioned. Adjust this value on
"Advanced definitions" screen in character editor. Slider values are on a linear scale from
<b>0% / Shy</b> (character never talks unless mentioned) to <b>100% / Chatty</b> (character always replies).
Default value for new characters is 50% chance.
</p>
<h4>3. Random character is selected.</h4>
<p>
If no characters were activated at previous steps, one speaker is selected randomly, ignoring all other
conditions.
</p>
<h3>List order</h3>
<p>
Characters are drafted based on the order they are presented in group members list. No other rules
apply.
</p>
<h3>Important!</h3>
<br>
<strong style="color: salmon">
Regeneration in group chats deletes all character message up until the <i>last message sent by you</i>.
Use swipes to generate just the latest message.
</strong>
</div>
</div>
</body>
</html>

27
public/notes/index.html Normal file
View File

@ -0,0 +1,27 @@
<html>
<head>
<title>Message Sound</title>
<link rel="stylesheet" href="/css/notes.css">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="/webfonts/NotoSans/stylesheet.css" rel="stylesheet">
<script src="/scripts/showdown.min.js"></script>
<script src="/scripts/showdown-toc.min.js"></script>
<script type="module">
const toc = [];
let converter = new showdown.Converter({ extensions: [showdownToc({ toc })] } );
let text = await (await fetch('/notes/content.md')).text();
let content = document.getElementById('content');
content.innerHTML = converter.makeHtml(text);
</script>
</head>
<body>
<div id="main">
<div id="content">
</div>
</div>
</body>
</html>

View File

@ -1,29 +0,0 @@
<html>
<head>
<title>Message Sound</title>
<link rel="stylesheet" href="/css/notes.css">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="/webfonts/NotoSans/stylesheet.css" rel="stylesheet">
</head>
<body>
<div id="main">
<div id="content">
<h2>Message Sound</h2>
<p>To play your own custom sound on receiving a new message from bot, replace the following MP3 file in your SillyTavern folder:</p>
<code>
public/sounds/message.mp3
</code>
<p>
Plays at 80% volume.
</p>
<p>
If "Background Sound Only" option is enabled, the sound plays only if SillyTavern window is <b>unfocused</b>.
</p>
</div>
</div>
</body>
</html>

View File

@ -1,32 +0,0 @@
<html>
<head>
<title>Multigen</title>
<link rel="stylesheet" href="/css/notes.css">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="/webfonts/NotoSans/stylesheet.css" rel="stylesheet">
</head>
<body>
<div id="main">
<div id="content">
<h2>Multigen</h2>
<p>SillyTavern tries to create faster and longer responses by chaining the generation using smaller batches.</p>
<h3>Default settings:</h3>
<p>First batch = 50 tokens</p>
<p>Next batches = 30 tokens</p>
<h3>Algorithm:</h3>
<p>1. Generate the first batch (if amount of generation setting is more than batch length).</p>
<p>2. Generate next batch of tokens until one of the stopping conditions is reached.</p>
<p>3. Append the generated text to the next cycle's prompt.</p>
<h3>Stopping conditions:</h3>
<p>1. Generated enough text.</p>
<p>2. Character starts speaking for You.</p>
<p>3. <tt>&lt;|endoftext|&gt;</tt> token reached.</p>
<p>4. No text generated.</p>
</div>
</div>
</body>
</html>

View File

@ -1,33 +0,0 @@
<html>
<head>
<title>OpenAI API key</title>
<link rel="stylesheet" href="/css/notes.css">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="/webfonts/NotoSans/stylesheet.css" rel="stylesheet">
</head>
<body>
<div id="main">
<div id="content">
<h2>OpenAI API key</h2>
<br>
<h3>How to get:</h3>
<ol>
<li>
Go to <a href="https://platform.openai.com/" target="_blank">OpenAI</a> and sign in.
</li>
<li>
Use "<a href="https://platform.openai.com/account/api-keys" target="_blank">View API keys</a>" option to create a new API key.
</li>
</ol>
<h3>Important!</h3>
<p>
<i>Lost API keys can't be restored! Make sure to keep it safe!</i>
</p>
</div>
</div>
</body>
</html>

View File

@ -1,66 +0,0 @@
<html>
<head>
<title>Character Tokens</title>
<link rel="stylesheet" href="/css/notes.css">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="/webfonts/NotoSans/stylesheet.css" rel="stylesheet">
</head>
<body>
<div id="main">
<div id="content">
<h2>Character Tokens</h2>
<p><b>TL;DR: If you're working with an AI model with a 2048 context token limit, your 1000 token character definition is cutting the AI's 'memory' in half.</b></p>
<p>To put this in perspective, a decent response from a good AI can easily be around 200-300 tokens. In this case, the AI would only be able to 'remember' about 3 exchanges worth of chat history.</p>
<hr>
<h3>Why did my character's token counter turn red?</h3>
<p>When we see your character has over 1000 tokens in its definitions, we highlight it for you because this can lower the AI's capabilities to provide an enjoyable conversation.</p>
<h3>What happens if my Character has too many tokens?</h3>
<p>Don't worry - it won't break anything. At worst, if the Character's permanent tokens are too large, it simply means there will be less room left in the context for other things (see below).</p>
<p>The only negative side effect this can have is the AI will have less 'memory', as it will have less chat history available to process.</p>
<p>This is because every AI model has a limit to the amount of context it can process at one time.</p>
<h3>'Context'?</h3>
<p>This is the information that gets sent to the AI each time you ask it to generate a response:</p>
<ul>
<li>Character definitions</li>
<li>Chat history</li>
<li>Author's Notes</li>
<li>Special Format strings</li>
<li>[bracket commands]</li>
</ul>
<p>SillyTavern automatically calculates the best way to allocate the available context tokens before sending the information to the AI model.</p>
<h3>What are a Character's 'Permanent Tokens'?</h3>
<p>These will always be sent to the AI with every generation request:</p>
<ul>
<li>Character Name (keep the name short! Sent at the start of EVERY Character message)</li>
<li>Character Description Box</li>
<li>Character Personality Box</li>
<li>Scenario Box</li>
</ul>
<h3>What parts of a Character's Definitions are NOT permanent?</h3>
<ul>
<li>The first message box - only sent once at the start of the chat.</li>
<li>Example messages box - only kept until chat history fills up the context (optionally these can be forced to be kept in context)</li>
</ul>
<h3>Popular AI Model Context Token Limits</h3>
<ul>
<li>Older models below 6B parameters - 1024</li>
<li>Pygmalion 6B - 2048</li>
<li>Poe.com (Claude-instant or ChatGPT) - 2048</li>
<li>OpenAI ChatGPT - 4000-ish?</li>
<li>OpenAI GPT-4 - 8000?</li>
</ul>
</div>
</div>
</body>
</html>

1
public/scripts/showdown-toc.min.js vendored Normal file
View File

@ -0,0 +1 @@
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e=e||self).showdownToc=t()}(this,(function(){"use strict";function e(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function t(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}return function(){var r=(arguments.length>0&&void 0!==arguments[0]?arguments[0]:{}).toc;return function(){return[{type:"output",filter:function(n){var o=[];n.replace(/(<h([1-6]).*?id="([^"]*?)".*?>(.+?)<\/h[1-6]>)|(<p>\[toc\]<\/p>)/g,(function(n,c,u,i,p){if("<p>[toc]</p>"===n)o.push({type:"toc"});else{p=p.replace(/<[^>]+>/g,"");var f={anchor:i,level:Number(u),text:p};r&&r.push(f),o.push(function(r){for(var n=1;arguments.length>n;n++){var o=null!=arguments[n]?arguments[n]:{};n%2?t(o,!0).forEach((function(t){e(r,t,o[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(r,Object.getOwnPropertyDescriptors(o)):t(o).forEach((function(e){Object.defineProperty(r,e,Object.getOwnPropertyDescriptor(o,e))}))}return r}({type:"header"},f))}return""}));var c=[];return o.forEach((function(e,t){if("toc"===e.type)if(o[t+1]&&"header"===o[t+1].type){for(var r=[],n=o[t+1].level,u=t+1;o.length>u&&"toc"!==o[u].type;u++){o[u].level===n&&r.push(o[u])}c.push(r)}else c.push([])})),n=n.replace(/<p>\[toc\]<\/p>[\n]*/g,(function(){var e=c.shift();return e&&e.length?"<ol>".concat(e.map((function(e){var t=e.text;return'<li><a href="#'.concat(e.anchor,'">').concat(t,"</a></li>")})).join(""),"</ol>\n"):""}))}}]}}}));