A SillyTavern extension that lets ST drive an AetherRoom chat backend. It rewrites outgoing text-completion prompts into the AetherRoom format, and exposes per-chat style controls.
In SillyTavern: Extensions → Install extension → paste this repo's URL. Reload the page after the install finishes.
The extension will not generate responses without the GLM tokenizer running server-side. Accurate token counts are how it keeps the context formatte right.
Enable server plugins in config.yaml:
enableServerPlugins: trueRestart SillyTavern, then from the SillyTavern checkout directory:
node plugins.js install https://github.com/AetherDreams/SillyTavern-Aether-TokenizerRestart again. The extension probes the plugin on load and shows a setup banner at the top of the chat pane if it can't reach it. Once the plugin is healthy, the banner is replaced by the AetherRoom top bar.
-
Get a NovelAI API token. Follow NovelAI's account-settings guide to generate one. Keep it handy for step 2.
-
Configure the SillyTavern API connection. Open the API Connections panel and set:
Field Value API Text Completion API type Generic (OpenAI-compatible) API URL https://text.novelai.net/oaAPI token the token from step 1 Model name xialong-v1Aether uses text completion because the model's chat template has whitespace details only this extension knows how to produce — chat completion endpoints would mangle them.
-
Pick your character as usual.
-
Open a chat. The AetherRoom top bar appears at the top of the chat pane with selectors for Style, Relationship, Response length, and Japanese. These are saved per-chat and survive reload.
The prompt rewrite only runs when all of the following are true:
- ST's API is set to Text Completion.
- The API URL contains
novelai.net. - The model name contains
xialong.
Switching to any other API, URL, or model disables the rewrite
automatically — so you can keep the extension installed alongside other
text-completion backends without it interfering. The auto-detect patterns
are in src/constants.js if you need to tweak them.
- Folds the character's
descriptionandpersonalityfields into one Personality block. - Puts the character's
scenariofield into its own scenario block so the model treats it as situational context, not character traits. - Parses
mes_example(<START>-delimited) into structured example quotes. - Sends World Info entries as named context blocks: constant entries pinned at the top, dynamic ones bundled near the recent end of history to optimize performance.
- Supports NovelAI-like context rollover.
ST character cards and AetherRoom contacts don't have a clean one-to-one relationship — ST treats character authorship as free-form prose, while AetherRoom contacts have structured fields (Gender, Pronouns, Species, Appearance, Personality, Relationship, etc.). The extension does the best it can with what's on the card:
descriptionandpersonalityare concatenated into Personality. Anything the card author wanted to call out as appearance, pronouns, or species stays inside that single blob rather than getting routed to a dedicated AetherRoom field.scenariobecomes the Scene field of the scenario block.- Card metadata that the v2 spec forbids prompts to use (
tags,creator_notes,creator) is intentionally not sent.
The result reads correctly to the model but won't match a hand-authored AetherRoom contact card field-for-field. Expect some loss of structure on cards designed around the AetherRoom schema; ST-authored cards work fine.
Model responses come back as multi-bubble structured text with an emotion per bubble. The extension parses each rendered character message and:
- Splits it into one visual bubble per sub-message.
- Strips the leading
{character}:name prefix and the four-space continuation indents so each bubble reads as clean prose. - Renders the bubble's emotion as a large, semi-transparent emoji in the upper-right of the bubble background. Hovering the emoji shows the emotion name.
The stored chat data is kept in the raw structured form. When you click
Edit on a message you'll see the raw name: / Emotion: lines and can
fix any wrong emotions by hand — saving re-renders the bubbles.
A presets/AetherRoom.json text-completion preset ships with this repo.
It's the recommended sampler config for the AetherRoom backend:
| Active | Disabled |
|---|---|
temperature = 0.85 |
rep_pen = 1 (no penalty) |
top_p = 0.95 |
presence_pen = 0, freq_pen = 0 |
top_k = 250 |
min_p, top_a, tfs, typical_p, mirostat, dry, xtc, dynatemp, … all off |
To install it:
- Copy
presets/AetherRoom.jsonfrom the installed extension folder into your SillyTavern user data folder atdata/<user>/TextGen Settings/. - Reload SillyTavern.
- In the Text Completion Preset dropdown, select AetherRoom.
You can still use any other preset you like — this one's just our default recommendation. Two things the extension always enforces regardless of preset, because they're correctness rather than taste:
max_tokensandmax_new_tokensare forced to1536(512 × 3).truncation_lengthis bumped to36864(= base context + rollover window) so backends that honour it don't crop our prompt down to ST's default 8192-token context.
- Setup banner stuck on "tokenizer plugin not detected". Verify
enableServerPlugins: trueis inconfig.yaml, the plugin is in./plugins/, and SillyTavern has been restarted since installing it. Click "Retry" on the banner. - Generation refuses to start. Same root cause as above — the extension blocks generation when the tokenizer is unreachable rather than sending the wrong format to your backend.
- Top bar doesn't appear. Make sure a chat is open and the extension is enabled in Extensions.
MIT. See LICENSE.