From ad386874f03bee72eb82189740850745b50098dd Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 19 Aug 2026 16:55:26 +0000 Subject: [PATCH] Release hardening: fix scheduler, editor, preset, and CSS defects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Scheduler core: - Generation-type filter is now a strict whitelist (undefined/null/'normal'); ST's 'command' (/sendas) and 'extension' message types no longer consume rotation slots, and unknown future types fail closed. - Track the type each GENERATION_STARTED carried: a non-streaming regenerate reaches MESSAGE_RECEIVED coerced to 'normal' (ST deletes the redone message first), so counting now consults the generation's real type. - Mid-rotation 3-strikes recovery actually halts: onGenerationStarted honors tryAdvanceFromFailure's result and stops the rotation instead of leaving a lit bar on a slot whose switches all fail; failure counters reset on every successful switch. - Resume after manual override implements the spec'd divergence branch: resuming on a foreign profile zeroes the counter so the next generation advances and switches instead of counting foreign responses to the slot. - Removed the unused rerollCurrentSlotCounter export. Queue editor and import: - Imported queue JSON could carry an attribute-breakout payload in a countMode-inactive count field (validateQueue only checked the active field; slotRow interpolated all of them raw). Count fields are now validated whenever present and numerically coerced at render. - Slot removal splices by identity (no stale index after rapid clicks) and managed-preset cleanup is deferred to Save, so Cancel is side-effect-free. - Sampler-tuning controls injected after the row's guard pass now get the anti-drag-hijack guard too. - Import reissues slot ids unconditionally and clears tuning.presetName; duplicate clears it as well — two queues can no longer share (and cross-delete) one managed preset. - Removed the dead openQueueEditor popup path. Sampler presets: - savePreset no longer passes skipUpdate: the preset must be in ST's in-memory list or /preset falls into Fuse fuzzy matching (potentially activating an unrelated preset) and cleanup's existence check never sees same-session presets, orphaning them on disk. UI chrome: - --roulette-* tokens are also defined on .popup:has(.roulette-extension): custom properties don't inherit upward, so the popup-chrome override rules computed to unset — the binding-picker dialog rendered transparent (unreadable on light ST themes). - Dot strip folds the rendered window into its fingerprint: queues longer than the variant cap re-window as rotation walks past the edge instead of losing the active capsule. - Ignite flash ends on animationend instead of a wall-clock 700ms, so slow animation speeds no longer cut it short. - /roulette-status posts a visible system message (ST never displays a bare command's pipe value); queue-card start failures surface a toast. - Queue deletion uses a themed Popup confirm; cards say "slots" not the v1.x "chambers"; bar label no longer hashes the 'unassigned' placeholder into a real profile color; bar records the position it actually mounted at. Hygiene: - Dropped the globalThis.__roulette debug global and per-step init logging. - package.json license is the non-deprecated AGPL-3.0-or-later id. - Banner recompressed 2.8MB PNG -> 153KB JPEG (every install clones it). - CLAUDE.md updated to match: whitelist filter, coerced-regenerate guard, microtask flag clearing, full ChatRouletteState shape, resume mechanism, six slash commands, repo tree. - New tests: whitelist fail-closed behavior, count-field validation. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01XDAj3aSdkvffKR6ZetqcyV --- .github/FUNDING.yml | 14 ----- CLAUDE.md | 25 ++++---- README.md | 8 ++- TESTING.md | 4 +- assets/.gitkeep | 0 assets/banner.jpg | Bin 0 -> 156633 bytes assets/banner.png | Bin 2834640 -> 0 bytes index.js | 19 +----- package.json | 2 +- src/events.js | 72 +++++++++++++++-------- src/exportImport.js | 17 +++++- src/profileSwitcher.js | 15 +++++ src/rotation.js | 34 ++++++----- src/sampling.js | 82 ++++++-------------------- src/slashCommands.js | 30 +++++++--- src/state.js | 10 +++- src/ui/bar.js | 14 ++++- src/ui/confirm.js | 23 ++++++++ src/ui/dotStrip.js | 30 +++++++--- src/ui/queueEditor.js | 124 +++++++++++++++++++--------------------- src/ui/tabs/queues.js | 20 +++++-- style.css | 28 +++++++-- tests/rotation.test.mjs | 34 ++++++++++- 23 files changed, 362 insertions(+), 243 deletions(-) delete mode 100644 assets/.gitkeep create mode 100644 assets/banner.jpg delete mode 100644 assets/banner.png create mode 100644 src/ui/confirm.js diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index d3cb74c..4956444 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,15 +1 @@ -# These are supported funding model platforms - -github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] -patreon: # Replace with a single Patreon username -open_collective: # Replace with a single Open Collective username ko_fi: hype -tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel -community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry -liberapay: # Replace with a single Liberapay username -issuehunt: # Replace with a single IssueHunt username -lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry -polar: # Replace with a single Polar username -buy_me_a_coffee: # Replace with a single Buy Me a Coffee username -thanks_dev: # Replace with a single thanks.dev username -custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] diff --git a/CLAUDE.md b/CLAUDE.md index d051e0c..398d8bb 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -50,18 +50,18 @@ The extension is a thin scheduler layered on top of SillyTavern's existing Conne ### Hook points (SillyTavern event system) Use `eventSource.on(event_types.X, handler)` for all of these. Import `eventSource` and `event_types` from `../../../../script.js` (verified — see "Verified ST internals" below). -- `MESSAGE_RECEIVED` — primary trigger for advancing the response counter. **Emitted with `(messageId, type)`** where `type` is one of `'swipe'`, `'continue'`, `'append'`, `'appendFinal'`, `'regenerate'`, `'impersonate'`, `'quiet'`, `'first_message'`, or `undefined` for a normal generation. **Advance the counter only when `type` is undefined/normal.** Filtering on `type` is what makes swipes, regens, continues, and impersonations not consume rotation slots — there is no other event-level guard. +- `MESSAGE_RECEIVED` — primary trigger for advancing the response counter. **Emitted with `(messageId, type)`** where `type` is one of `'swipe'`, `'continue'`, `'append'`, `'appendFinal'`, `'regenerate'`, `'impersonate'`, `'quiet'`, `'first_message'`, `'command'` (/sendas-inserted character messages), `'extension'` (extension-inserted messages, e.g. stable-diffusion), `'normal'`, or `undefined` for a normal generation. **Advance the counter only when `type` is undefined/null/`'normal'`** — `isCountableGeneration()` is a strict whitelist so unknown future types fail closed. One trap the emitted type alone cannot catch: a **non-streaming regenerate** deletes the AI message being redone *before* generating, so by the time `saveReply` emits `MESSAGE_RECEIVED` the preceding message is the user's and the type is **coerced to `'normal'`** (streaming regens emit `'regenerate'` faithfully). `events.js` therefore also records the type each non-dry `GENERATION_STARTED` carried (`lastGenerationType`) and refuses to count a message whose *generation* started non-countable. - `GENERATION_STARTED` — emitted with `(type, options, dryRun)`. The moment to fire the profile switch *before* the next generation, if the rotation says it's time to switch. **Skip when `dryRun === true`** (ST emits this for prompt-token-counting and similar dry runs) and skip non-normal `type` values (same set as above). This is critical: we switch profiles *before* the model generates, not after. - `MESSAGE_SWIPED` — fires when the user navigates between **existing** swipes via the left/right arrows; not on swipe-regeneration. Largely irrelevant to the scheduler since the `type` filter on `MESSAGE_RECEIVED`/`GENERATION_STARTED` already handles regen-swipes. - `CHAT_CHANGED` — emitted as `'chat_id_changed'`. Reload per-chat rotation state when the user switches chats. -- `CONNECTION_PROFILE_LOADED` — fires for **both** manual user switches *and* our own programmatic `/profile` calls (verified: see "Verified ST internals"). The handler must consult an internal `isInternalSwitch` flag we set immediately before firing `/profile` and clear inside the handler — otherwise we trip our own manual-override path on every rotation. +- `CONNECTION_PROFILE_LOADED` — fires for **both** manual user switches *and* our own programmatic `/profile` calls (verified: see "Verified ST internals"). Payload is the profile **name** string (or `''`). The handler must consult an internal `isInternalSwitch` flag we set immediately before firing `/profile` — otherwise we trip our own manual-override path on every rotation. The flag is cleared by a `queueMicrotask` in `switchProfile`'s `finally` (not by the handler itself): the microtask defer means every synchronous listener that fires while the slash command resolves still sees the flag set, however many there are. - `CHARACTER_DELETED` — emitted with `({ id, character })`. Purge that character's queue binding. - `CHARACTER_RENAMED` — emitted with `(oldAvatar, newAvatar)`. Avatar filenames track the character name, so a rename moves our binding key; re-point it or the binding is silently orphaned. - `APP_READY` — boot-time safety net for character-binding auto-start. `eventSource` is constructed with `autoFireAfterEmit` covering `APP_READY`, so a listener registered *after* the event already fired is invoked immediately with the last args. ST inits extensions before loading the first chat, so `CHAT_CHANGED` normally covers startup on its own; this is belt-and-braces for late-loading installs. **Generation type strings** (for the filter logic in `rotation.js`): -- Advance counter / fire switch: `undefined` (normal user generation). -- Ignore: `'swipe'`, `'regenerate'`, `'continue'`, `'append'`, `'appendFinal'`, `'impersonate'`, `'quiet'`, `'first_message'`, plus any `dryRun === true`. +- Advance counter / fire switch: `undefined`, `null`, or `'normal'` (normal user generation). This is a **whitelist** — everything else is ignored, so a type ST adds tomorrow can never silently consume rotation slots. +- Known ignored types: `'swipe'`, `'regenerate'`, `'continue'`, `'append'`, `'appendFinal'`, `'impersonate'`, `'quiet'`, `'first_message'`, `'command'`, `'extension'`, plus any `dryRun === true` and any message whose `GENERATION_STARTED` type was non-countable (the coerced-regenerate guard above). ### Profile switching mechanism Use SillyTavern's slash command system to switch profiles. The `/profile` command is registered by the built-in Connection Profiles extension and accepts an `await=true` named arg that resolves only after `CONNECTION_PROFILE_LOADED` and an online-status check — use it so the switch is synchronous from our perspective: @@ -132,13 +132,15 @@ type ChatRouletteState = { activeQueueId: string | null; // which queue is running, null = rotation off currentSlotId: string | null; // the slot currently in effect responsesRemaining: number; // counter that decrements per accepted response + responsesAllotted: number; // what the counter started at — the UI renders "N of M" lastSwitchMessageId: number | null; // message index where we last switched, for diagnostics history: Array<{ // optional log: which profile generated which message - messageId: number; + messageId: number; // capped at 500 entries (appendHistory) profileName: string; timestamp: number; }>; manuallyOverridden: boolean; // see "Manual override behavior" + autoBindHandled: boolean; // see "Per-character queue bindings" — the auto-start latch }; ``` @@ -166,7 +168,7 @@ On `MESSAGE_SWIPED`: do nothing. Swipes are same-slot retries by design. If the user manually switches connection profiles via the existing ST UI (detected via `CONNECTION_PROFILE_LOADED` for a profile that doesn't match `currentSlotId`'s profile), set `manuallyOverridden = true`. The status indicator changes to "Rotation paused (manual override)" with a "Resume" button. Clicking Resume: - If on the same profile a slot points to, set `manuallyOverridden = false` and continue from the current state. -- Otherwise, set `manuallyOverridden = false`, treat the next response as the start of a new rotation cycle (re-pick or advance). +- Otherwise, set `manuallyOverridden = false`, treat the next response as the start of a new rotation cycle (re-pick or advance). Implemented in `resumeRotation()` by zeroing `responsesRemaining`: the existing `GENERATION_STARTED` path then advances/re-picks and switches before the next generation, and the pick history never attributes foreign-profile responses to the slot. ### 6. Error handling @@ -344,6 +346,8 @@ colour), per-slot sampler tuning (`src/sampling.js`), per-character bindings SillyTavern-Roulette/ ├── manifest.json # ST extension manifest ├── package.json # node-only: `npm test`, type:module. ST ignores it. +├── assets/ +│ └── banner.jpg # README hero image (keep it small — every install clones it) ├── index.js # entry point: init() wires every subsystem ├── style.css # scoped styles + --roulette-* token set ├── README.md # user-facing docs (value, install, recipes) @@ -366,6 +370,7 @@ SillyTavern-Roulette/ │ ├── profileColors.js # hash-based stable profile colour assignment │ ├── queueEditor.js # form builder shared by popup + embedded paths │ ├── settingsPanel.js # drawer block: Enable/Disable Roulette + Settings +│ ├── confirm.js # themed yes/no dialog (replaces native confirm()) │ ├── templates.html # reserved for future fragments (currently empty) │ └── tabs/ │ ├── rotation.js # dot-strip hero + status + actions + binding + pick history @@ -444,7 +449,7 @@ The `../../../../` depth in the table above is for **`index.js` at the extension ### Connection profile enumeration ST stores connection profiles in `extension_settings.connectionManager.profiles` (verified — `public/scripts/extensions.js:172`). Each profile is a `ConnectionProfile` with at least `id` and `name` (full JSDoc at `public/scripts/extensions/connection-manager/index.js:159`). The currently selected profile is tracked as an **id** at `extension_settings.connectionManager.selectedProfile`, *not* a name — convert when comparing. -The queue editor's profile dropdown should read from this list directly and refresh on `CONNECTION_PROFILE_LOADED`, `CONNECTION_PROFILE_CREATED`, `CONNECTION_PROFILE_DELETED`, `CONNECTION_PROFILE_UPDATED`, and on modal open. **Do not cache** the profile list — the user may add/remove profiles between sessions. +The queue editor's profile dropdown reads from this list directly, re-read at every slot-row render, and the modal remounts its tabs fresh on every open. **Do not cache** the profile list — the user may add/remove profiles between sessions. (No `CONNECTION_PROFILE_*` event subscription is needed for the editor: the modal is a native `` shown with `showModal()`, which makes the rest of ST inert — the user cannot reach the connection manager to mutate profiles while the editor is open.) ### Modals — use ST's `Popup` class Use the `Popup` class from `../../../../scripts/popup.js` for the queue editor instead of rolling our own modal. It handles z-index, focus trap, escape-to-cancel, and theme-correct styling automatically. `POPUP_TYPE.TEXT` for content-driven popups, `POPUP_RESULT` for return-value comparison. The convenience function `callGenericPopup(content, type, inputValue, popupOptions)` is fine for simple cases; reserve the `new Popup(...)` constructor for the queue editor where we need custom buttons and form state. @@ -521,15 +526,15 @@ The extension is "done" when all of the following are true on a fresh ST install 2. The Roulette panel appears in the Extensions drawer. 3. A user with at least 2 connection profiles can create a queue, save it, and activate it on a chat. 4. In **sequential** mode with fixed counts (e.g. A=3, B=2, C=4), generating 9 messages causes the active profile to be A for the first 3, B for the next 2, C for the next 4. Verified by checking the connection profile selector value before each generation. -5. Swiping a message (regenerate-as-swipe) does not advance the counter — verified via the `type === 'swipe'` filter on `MESSAGE_RECEIVED`. -6. Regenerating a message does not advance the counter — verified via the `type === 'regenerate'` filter on `MESSAGE_RECEIVED`. +5. Swiping a message (regenerate-as-swipe) does not advance the counter — verified via the countable-type whitelist on `MESSAGE_RECEIVED`. +6. Regenerating a message does not advance the counter, **with streaming on or off** — streaming regens carry `type === 'regenerate'`; non-streaming regens arrive coerced to `'normal'` and are caught by the `lastGenerationType` guard (see Hook points). 7. In **weighted-random** mode with weights 1/1/1 and run length 1, profiles switch every message and over 100 messages each profile is used roughly evenly (within reasonable variance). 8. With `noRepeatInRow: true`, no two consecutive responses ever come from the same profile (verified over 50+ messages). 9. Switching chats preserves each chat's independent rotation state. 10. Manually switching profiles mid-rotation pauses the rotation and surfaces the "Resume" affordance. 11. Deleting a profile that's in an active queue triggers the error path: that slot is skipped, rotation continues with the remaining profiles. 12. The pinned bar updates within one frame of any state change. -13. All four slash commands (`/roulette-start`, `/roulette-stop`, `/roulette-status`, `/roulette-skip`) work and produce sensible output. +13. All six slash commands (`/roulette-start`, `/roulette-stop`, `/roulette-status`, `/roulette-skip`, `/roulette-bind`, `/roulette-unbind`) work and produce sensible output; `/roulette-status` posts a visible system message (a bare command's return value is never displayed by ST). 14. No console errors during normal use. 15. The modal and bar render identically under any ST theme (they own their canvas); the drawer block follows the ST theme. diff --git a/README.md b/README.md index 3fe6b0f..c87ddea 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -![Roulette Banner](assets/banner.png) +![Roulette Banner](assets/banner.jpg) # SillyTavern-Roulette @@ -27,7 +27,11 @@ The longer your chat runs, the more value Roulette adds. Four reasons most users ## Install -In SillyTavern: **Extensions → Install Extension → Install from URL** and paste this repository's URL. +In SillyTavern: **Extensions → Install Extension → Install from URL** and paste: + +``` +https://github.com/hype-hosting/SillyTavern-Roulette +``` Manual install: clone into `data//extensions/SillyTavern-Roulette/` (per-user) or `public/scripts/extensions/third-party/SillyTavern-Roulette/` (global), then enable in the Extensions panel. diff --git a/TESTING.md b/TESTING.md index 554debc..4985a88 100644 --- a/TESTING.md +++ b/TESTING.md @@ -2,7 +2,7 @@ These walkthrough steps verify each acceptance criterion in a live SillyTavern. Run before tagging a release. Each section maps 1-to-1 with the acceptance criteria in `CLAUDE.md`. -> **v2.0 orientation.** The extension's primary surface is the **pinned bar** — a slim row in the chat column (default: above the message input) showing one colored dot per slot, with the active slot lit and carrying its responses-remaining count. The bar's gear opens the modal (**Rotation / Queues / Settings**). The Extensions drawer holds only **Enable/Disable Roulette** (bar visibility) and **Settings** (opens the modal). Wherever an old step said "pill", read "bar". +> **v2.0 orientation.** The extension's primary surface is the **pinned bar** — a slim row in the chat column (default: above the message input) showing one colored dot per slot, with the active slot lit and carrying its responses-remaining count. The bar's gear opens the modal (**Rotation / Queues / Settings**). The Extensions drawer holds only **Enable/Disable Roulette** (bar visibility) and **Settings** (opens the modal). ## Setup @@ -10,7 +10,7 @@ These walkthrough steps verify each acceptance criterion in a live SillyTavern. 2. Define at least three connection profiles in **Connection Profiles** (any three providers/models — they're labels for these tests). Suggested names: `A`, `B`, `C`. 3. Install Roulette via **Extensions → Install Extension → Install from URL** with this repository's URL. 4. Hard-refresh the browser (`Cmd-Shift-R` / `Ctrl-Shift-R`) to bypass any stale `manifest.json` cache. -5. Open DevTools Console. You should see the `[Roulette] ...` init log lines ending with `init() complete`. No red errors anywhere. +5. Open DevTools Console. You should see a single `[Roulette] init() complete` log line. No red errors anywhere. If init never logs, see `CLAUDE.md` → "Robustness pattern — self-invoke from top level". diff --git a/assets/.gitkeep b/assets/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/assets/banner.jpg b/assets/banner.jpg new file mode 100644 index 0000000000000000000000000000000000000000..77aa45ffff4a96f7dda5ca9bd34664decdb80a78 GIT binary patch literal 156633 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