* fix: conditionally include secrets in user data backup
* feat: add full data backup toggle
* 418 -> 403
I'm not a teapot
* Distinguish fails from disabled
* feat(ui): add popup to jump to a specific swipe
Adds a new "Jump to swipe history" button to message actions and makes
the swipe counter clickable on the latest message. This opens a
searchable popup allowing users to quickly find and jump to a
specific alternate swipe without having to click through them
sequentially.
- Adds a searchable swipe picker popup menu
- Makes the swipe counter interactive when multiple swipes exist
- Adds a dedicated swipe picker button to message controls
* fix(ui): hide swipe picker when there are no swipes
Ensures the newly added swipe picker button is only shown when a
message has multiple swipes available. It explicitly hides the
button for non-swipeable messages or messages with a single swipe.
* feat(ui): redesign swipe picker with direct id input
Replace text-based search with a numeric input for direct swipe navigation.
Update popup layout with a sticky header and improved scrolling behavior.
Sync input value with the currently selected swipe in the list.
Refactor styling to align with chat selection components.
* feat(ui): allow branching from specific swipes via picker
- Enable swipe picker for historical messages to inspect alternate swipes
- Add branch button to picker entries to create new chats from specific swipes
- Update saveChat and createBranch to accept chat snapshots
- Restrict swipe jumping to the active message only
* refactor(logic): consolidate swipe sync logic and simplify helpers
Update `syncSwipeToMes` to accept a target message object, enabling its
use in the bookmarks module and removing the duplicate
`applySwipeToSnapshot` function.
Also simplify `canOpenSwipePickerForMessage` and
`canJumpToSwipeForMessage` signatures by removing the redundant message
parameter.
* refactor(a11y): support dynamic roles via classes
Introduce a managed role system in the accessibility script to handle
elements that dynamically gain or lose interactive states. The mutation
observer now watches for class attribute changes and automatically
applies or clears roles (e.g., `role="button"`) using active selectors.
Updated the swipe counter to rely on this centralized system by toggling
an `.interactable` class instead of manually modifying tabindex and role
attributes. Removed the redundant 'Enter' keydown handler for the swipe
counter to prevent duplicate trigger events.
* fix(ui): compute missing token counts in swipe picker
Update renderSwipeList to asynchronously calculate token counts when
missing from swipe metadata. Introduce SWIPE_SOURCE.SWIPE_PICKER to
correctly identify swipes triggered from the picker and bypass
generation checks.
* feat(ui): enable deleting specific swipes via swipe picker
- Adds a delete button to swipe picker entries, allowing removal of specific message versions.
- Refactors deletion logic to handle removing non-current swipes without triggering animations and correctly updates indices.
- Includes confirmation dialogs and improves input focus behavior.
* refactor:Delete process inline to button click processor
* feat: universal swipe inspection and picker improvements
- Permit opening the swipe browser on any chat entry to review past generations.
- Parallelize the retrieval of token statistics to speed up list rendering.
- Format message metrics (length and tokens) into a single, concise string.
- Update the `getBranchChatSnapshot` API to accept an options object.
- Register swipe list items as interactable elements for keyboard control.
- Apply styling to prevent text highlighting on picker entries.
* fix:remove unused CSS
* fix: fix disabled styling for swipe delete button
Remove tooltips and prevent hover animations or glow effects when the
delete button is disabled in the swipe picker. Update CSS to enforce
default cursor and fixed opacity on hover for the disabled state.
* remove: Unused CSS
* Extract swipe-picker.js module
* Revert to manual ARIA role management
* Avoid scrollIntoView and scroll on open
* Fix keyboard interaction in past chats menu
* Fix a11y attribute
* fix: call refreshSwipeButtons when deleting not selected swipe
---------
Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
* feat: add finalizeIntermediaryMessage for streaming tool call chains
Add a lighter finalization method on StreamingProcessor that runs
before tool invocation. This ensures CHARACTER_MESSAGE_RENDERED is
emitted for streamed text messages before the tool call chain
continues, allowing extensions (TTS, image forwarding, etc.) to
process intermediary messages.
finalizeIntermediaryMessage performs essential processing:
- Code block styling (addCopyToCodeBlocks)
- Reasoning handler finalization
- Logprobs saving
- Image attachment processing
- Reasoning signature storage
- MESSAGE_RECEIVED and CHARACTER_MESSAGE_RENDERED events
Without the heavier onFinishStreaming operations:
- UI unlock (markUIGenStopped)
- Auto-swipe
- Sound playback
- Chat saving
- Swipe counter update
* fix: return Error objects from invokeFunctionTool and create error invocations
invokeFunctionTool previously called .toString() on caught errors,
converting them to plain strings. This made the 'instanceof Error'
check in invokeFunctionTools dead code - errors silently became
successful invocations, showToolCallError never fired, and the
result.errors array was always empty.
Changes:
- Return Error objects directly from invokeFunctionTool
- Create error invocations with error: true flag when tools fail
- Add error field to ToolInvocation typedef
* fix: record failed stealth tools in stealthCalls and preserve signature/reasoning on error invocations
When a stealth tool errors, its name was not added to stealthCalls, causing
shouldStopGeneration to evaluate as false. This led to an incorrect recursive
Generate('normal') call instead of stopping generation as the stealth tool
contract requires ('no follow-up generation').
Also preserve toolCall.signature and reasoningText on error invocations to
match the success path, preventing Gemini/OpenRouter multi-turn tool context
from breaking when a tool call fails.
* Clarify method comments
* fix: initialize error property in ToolInvocation to false
* Apply review suggestions
* Make options object required
* fix: remove unnecessary return statement in updateSwipeCounter method
* refactor: split tool call error handling into separate PR (#5351)
---------
Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
* renaming a lorebook prompts to update existing links
* used suggested api and logic
* add world property to shallow function
* Fix type error in assignLorebookToChat invoke
* Remove debug console logs
* Fix activeCharacterUpdated
* Extract updateWorldInfoLinks into a func
* Invert if for an early return
---------
Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
* Handle port conflicts during server startup
* Fix return type of startHTTPorHTTPS
* Update language in getAddressInUseMessage
---------
Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
* feat(popup): add allowEscapeClose option to override default escape key behavior
Add `allowEscapeClose` parameter to PopupOptions to explicitly control whether Escape key closes the popup, overriding the default logic that checks for visible cancel/close buttons. When null (default), uses existing behavior; when true, allows escape even without buttons; when false, prevents escape even with buttons present.
* feat(popup): enable Escape key closing for informational popups
Add `allowEscapeClose: true` option to TEXT-type popups in export preset, persona lore, sampler select, stats, and world info assignment dialogs to allow users to dismiss these informational popups with the Escape key.
* Improve Escape key interaction in popups
* Adjust jsdoc for allowEscapeClose
* Always return CANCELLED on Escape
* fix(popup): correct jsdoc for allowEscapeClose property description
---------
Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
* Fix missing model name in tokenize requests for llama.cpp (fixes#4962)
The new router mode of llama.cpp allows to switch models on the fly,
what is already supported by SillyTavern. The call to the `/tokenize`
endpoint did not contain the model name, and failed in router mode.
This patch adds the `model` parameter similar to the implementation
for other backends.
* fix: migrate vllm and aphrodite to new payload field
---------
Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
* Refactor loader.js to use action-loader system and move overlay management into action-loader module
- Deprecate showLoader() and hideLoader() in favor of action-loader API
- Implement legacy functions as thin wrappers around ActionLoaderHandle
- Move overlay management (showOverlay, hideOverlay, isOverlayDisplayed) into action-loader.js
- Move Popup-based loader implementation and preloader cleanup to action-loader
- Add loader.isBlocking() method to check for active blocking overlays
* Migrate from legacy loader functions to action-loader API throughout codebase
- Replace showLoader()/hideLoader() imports with loader from action-loader.js
- Update firstLoadInit() to use loader.show() with title, message, and ToastMode.STATIC
- Pass initLoaderHandle to getSettings() for early hide during onboarding flow
- Refactor renameGroupOrCharacterChat() to use loader.show() instead of boolean flag
- Wrap handleDeleteChat() with loader.show() and proper error handling
- Update BulkEditOver...
* Update loader titles and remove redundant reload notification
- Change bookmark loader title from "Bookmark" to "Chat History" for clarity
- Remove loader notification before extensions reload (redundant with browser reload)
* lint fix
* Add splash screen support to action loader with custom overlay content
- Add `overlayContent` option to ActionLoaderOptions for custom HTML in overlay
- Implement splash screen styles with centered logo, spinner, and message
- Update firstLoadInit() to use custom splash screen instead of static toast
- Pass custom content through showOverlay() to replace default spinner
- Adjust non-blocking loader warning to account for custom overlay content
* Refactor loader overlay to use DOM elements instead of HTML strings
- Add createDefaultLoaderOverlay() function to generate fresh loader overlay elements
- Export createOverlay() method on loader utility API for external use
- Change overlayContent parameter type from string-only to string|HTMLElement|null
- Add getOverlayContent() helper to normalize custom content for Popup
- Update firstLoadInit() to build splash screen using DOM manipulation instead of template literals
- Add splash-logo class and
* Use a true ellipsis
* Adjust sizing for desktop
* Even truer ellipsis
* Add transition to splash screen and fix blur animation on hideOverlay (#5338)
* Initial plan
* Blur entire splash screen on hideOverlay, not just spinner
Co-authored-by: Cohee1207 <18619528+Cohee1207@users.noreply.github.com>
Agent-Logs-Url: https://github.com/SillyTavern/SillyTavern/sessions/eee6c06d-7c9d-4363-bc8f-2647ed390368
* Add transition to splash-screen and fix transition detection
Co-authored-by: Cohee1207 <18619528+Cohee1207@users.noreply.github.com>
Agent-Logs-Url: https://github.com/SillyTavern/SillyTavern/sessions/9368bc36-31a0-4a58-aebd-7b569696ff2e
---------
Co-authored-by: anthropic-code-agent[bot] <242468646+Claude@users.noreply.github.com>
Co-authored-by: Cohee1207 <18619528+Cohee1207@users.noreply.github.com>
* Add translations to supported locales
* Localize logo alt on welcome screen
---------
Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
Co-authored-by: Claude <242468646+Claude@users.noreply.github.com>
* Stop strings apply to Chat Completions and should not be greyed out.
* Revert "Stop strings apply to Chat Completions and should not be greyed out."
This reverts commit 51e5cfee41e1298b0005ff9df5d783c08820ed9a.
* Stopping strings should only apply to Text Completions https://github.com/SillyTavern/SillyTavern/pull/5337#pullrequestreview-3987164461
* Custom stop strings still apply
* Also apply to non-streaming message clean-up
* This comment is now misplaced
* Oops, wrong file
* Revert package-lock change
---------
Co-authored-by: user <user@exmaple.com>
Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
* feat: add SiliconFlow.cn endpoint support and embedding vectors
Chat completion:
- Add endpoint selection dropdown (Global/.com vs China/.cn) to existing
SiliconFlow provider, following the Z.AI endpoint pattern
- Backend switches API URL based on selected endpoint
- Add /api-url slash command support for endpoint switching
Embeddings:
- Add SiliconFlow as a vector/embedding source (OpenAI-compatible)
- Support both .com and .cn endpoints via siliconflow_endpoint setting
borrowed from the main connection panel (Vertex AI pattern)
- Superset model list with platform attribution (.cn) markers
- Models: Qwen3-Embedding (0.6B/4B/8B) + BGE/BCE models (.cn only)
* Add filter by models type
* Load embedding models from endpoint
* Improve api-url command declaration
* Support endpoint override in custom-request service
---------
Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
* fix(popup): prevent Escape key from closing popups when both cancel and close buttons are hidden
Add validation in cancel listener to check visibility of cancel and close buttons before allowing Escape key to close popup. Set isClosingPrevented flag to block subsequent close events when neither button is visible.
* feat(popup): add double-escape force-close mechanism for blocking popups
Add double-escape detection (within 500ms) to allow force-closing blocking popups that have both cancel and close buttons hidden. Show confirmation dialog warning about potential inconsistent state before allowing force-close. Track last escape press timestamp and confirmation popup state to prevent duplicate dialogs. Gracefully cancel force-close confirmation if main popup closes naturally.
The grok-2-image-1212 model was deprecated on 2026-02-24 and is no
longer available. Only grok-imagine-image and grok-imagine-image-pro
remain as valid xAI image generation models.
* feat: add placeholder and tooltip support to popup system with icon buttons
Add `placeholder` and `tooltip` options to main popup configuration. For INPUT type popups, placeholder applies to input field; for other types, tooltip applies to content area. Enhance custom buttons with optional `icon` parameter for Font Awesome icons and `tooltip` for hover text. Add tooltip support to custom inputs (placeholder for text/textarea, tooltip icon for checkboxes).
* fix: preserve default toastClass when applying custom cssClass in /echo command
Modify cssClass argument handling in echoCallback to append custom class to existing toastClass instead of replacing it. Use filter(Boolean).join(' ') to combine default and custom classes while handling undefined values.
* feat: add placeholder, tooltip, and icon support to popup system slash commands
Add `placeholder` and `tooltip` named arguments to /input command for input field customization. Add `tooltip` argument to /popup command for content area hover text. Enhance /buttons command to support button objects with `text`, `tooltip`, and `icon` (Font Awesome) properties alongside simple string labels. Update help text and examples for all three commands. Normalize button labels to ButtonLabel format internally
* Fix jsdoc wording
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* fix: add validation for button labels in /buttons command
Add validation check to ensure each button entry is either a string or an object with a non-empty string `text` property. Return empty string and log warning if validation fails. Fix capitalization of 'Popup' in /popup command return value description.
---------
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* Add action loader utility with stoppable toast notifications
* Add slash commands for action loader control (/loader-wrap, /loader-show, /loader-hide, /loader-stop)
* Refactor action loader to support stacking multiple loaders with individual toast management
- Convert action loader from singleton to class-based handle system (ActionLoaderHandle)
- Support multiple concurrent loaders with single overlay and stacked toasts
- Add unique ID generation and tracking for each loader instance
- Implement onHide callback alongside existing onStop callback
- Add getActiveLoaderHandles() and getLoaderHandleById() utility functions
- Refactor hideActionLoader() to accept...
* Improve action loader overlay and toast handling with better state checks and cleanup timing
- Check isLoaderDisplayed() before showing overlay to prevent conflicts with existing loaders
- Use toastr.options.hideDuration for toast removal timing instead of hardcoded 250ms
- Simplify hideActionLoader() by using getActiveLoaderHandles() helper
- Remove redundant empty check in hideActionLoader()
- Add clarifying comment for intentional error throw in createClosureHandler()
- Remove redundant 'onStop' default
* fix stop button toast removal issue by using toastr.clear force option instead of manual removal with timeout
* Fix isLoaderDisplayed() by using double negation operator instead of null comparison
* Add non-blocking loader support with `blocking` parameter for toast-only action loaders
- Add `blocking` option to ActionLoaderHandle (default: true)
- Implement hasBlockingLoaders() helper to check for active blocking loaders
- Show/hide overlay only when blocking loaders are active
- Add `blocking` named argument to /loader-wrap and /loader-show commands
- Update help strings with non-blocking usage examples
- Import commonEnumProviders for boolean enum and isFalseBoolean utility
* Add optional title parameter to action loader toast notifications and reorder constructor parameters for consistency
- Add `title` parameter to ActionLoaderOptions and ActionLoaderHandle constructor
- Pass title to toastr.info() for toast notifications
- Reorder parameters: blocking, toastMode, message, title, stopTooltip (grouped by importance)
- Add warning when creating non-blocking loader without toast (invisible to user)
- Update /loader-wrap and /loader-show commands with title argument
* Add loader utility API to action-loader and expose it in ST context for convenient programmatic access
- Create `loader` object with show/hide/active/get methods and ToastMode/Handle exports
- Add JSDoc examples for basic usage, non-blocking tasks, and hiding all loaders
- Import and expose `loader` in ST context alongside existing loader functions
* Split slash command and functional modules
* Create abort controller on app init
* Remove HTML tags from "returns" declaration
---------
Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
Make description and firstMessage optional parameters in createCharacterCallback, allowing character creation with only a name. Remove validation checks that previously required these fields to be non-empty strings.
The addOpenRouterSignatures function was previously converting and appending message.signature to reasoning_details unconditionally, ignoring the `enableThoughtSignatures` setting.
This change adds a check for `enableThoughtSignatures` before converting message.signature, while still ensuring the original signature property is deleted to prevent API schema validation errors (HTTP 400).
* feat: add character CRUD slash commands (char-create, char-update, char-get, char-delete)
Implement comprehensive character management commands allowing programmatic creation, modification, retrieval, and deletion of characters without UI interaction. All commands support named arguments with proper validation and error handling.
* feat: enhance char CRUD commands with favorite, avatar, and improved defaults
Add `favorite` and `avatar` named arguments to char-create and char-update commands. Make `char` argument optional in char-delete (defaults to current character). Improve documentation with clarifications on card tags vs ST tags, avatar URL sources, and usage examples. Add `fav` field to char-get output.
* feat: add /tag-import slash command for programmatic character tag import
Implement /tag-import command with `name` (defaults to {{char}}) and `mode` arguments (all/existing/none/ask). Command imports character card tags as ST tags for filtering/organizing. Returns 'true' if tags were imported, 'false' otherwise. Mode argument maps to existing tag_import_setting enum values.
* feat: enhance char-create and char-update with avatar upload and tag parsing
Add avatar resolution and upload support for char-create and char-update commands. Implement resolveAvatarData() to handle URLs, base64 data URLs, and local paths. Add uploadCharacterAvatar() to upload resolved images via /api/characters/edit-avatar. Parse tags argument as comma-separated array. Refresh side panel after char-update when modifying current character. Add char-get2 alias for testing.
* feat: enhance avatar argument in char CRUD commands with file picker and local path support
Add `prompt` value to avatar argument to open file picker dialog. Implement promptForAvatarFile() to handle image selection with validation. Add folderEnumMatchProvider() for autocomplete matching of folder paths. Update avatar enumList with common ST paths (characters/, backgrounds/, User Avatars/, assets/, user/images/). Remove external URL support from resolveAvatarData() - now only accepts "prompt", base
* feat: add /char-duplicate slash command with avatar resize support and enhanced avatar upload handling
Implement /char-duplicate command with `char` and `select` named arguments. Add `avatarPromptResize` argument to char-create and char-update for optional resize/crop dialog. Refactor duplicateCharacter() to accept avatar and silent parameters, returning the new avatar key. Enhance uploadCharacterAvatar() to handle resize prompts and return success status. Add cache busting and DOM refresh for avatar thumbnails
* refactor: optimize avatar refresh after upload by using cache busting and DOM query
Replace message-specific avatar refresh logic with generic image refresh targeting all thumbnails using the updated avatar URL. Remove unnecessary delay and character name matching. Add cache busting for both thumbnail and full character image. Use querySelectorAll to find and refresh all affected img elements in one pass.
* refactor: rename char-get alias from char-get2 to char-data
* refactor: move /dupe command to alias of /char-duplicate and fix characterIndex type
Move standalone /dupe command to alias of /char-duplicate for consistency with character CRUD commands. Cast characterIndex to String in char-update to match expected type.
* docs: clarify /imagine command integration with avatar argument in char CRUD commands
Update avatar argument descriptions and examples to explicitly mention /imagine command return value support. Reorder piped /imagine example to show correct command flow (generate image first, then update character).
* feat: add i18n support to char-create and char-update command error messages
Wrap validation error toastr messages in t`` template literals for translation support in /char-create and /char-update commands.
* feat: add group chat validation to /tag-import command
Add early validation check to prevent tag import in group chats. Display warning toastr message and return 'false' when selected_group is not null.
* Fix char update world property
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* Fix help text documentation to match arg name
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* fix: return empty string instead of throwing errors in char-create and char-update commands
Replace `throw error` with `return ''` in error handlers for /char-create and /char-update commands to prevent unhandled promise rejections while still displaying error toastr messages.
* refactor: make deleteCharacter return boolean success status and update char-delete command to use it
Change deleteCharacter to return boolean indicating success/failure instead of void. Return false on user cancellation or failed chat close, true when character is successfully deleted. Update /char-delete command to use returned success value instead of always returning 'true'.
* refactor: make description and firstMessage optional in /char-create command
Remove description and firstMessage from required fields array, allowing character creation with only a name. Update help text to reflect that only name is required.
* refactor: extract external URL check to utility function and add same-origin URL support for avatar resolution
Extract external URL check into `isExternalUrl` utility function in utils.js. Update `resolveAvatarData` to use new utility and add support for same-origin URLs by converting them to pathname before fetching.
---------
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* Fix AICC direct link import parsing
Update parseAICC in src/endpoints/content-manager.js to dynamically extract the author and character name from the end of the URL path. This resolves a 404 import error caused by AICC adding category subfolders and changing their base URL structure from /character-cards/ to /charactercards/.
* Clean up whitespace in content-manager.js
Remove unnecessary whitespace in URL path processing.
* Use isValidUrl for URL validation
---------
Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
* Unify chat lorebook button click behavior with character lorebook button
* Update locale strings for chat lorebook button
* Unify chat lorebook button click behavior with character lorebook button
* Update locale strings for chat lorebook button
* Also unify character lorebook button to support Alt modifier
* Update locale strings for character lorebook button
* Update public/locales/fr-fr.json
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Add long-press support for lorebook buttons on mobile
* Update locale strings for lorebook button long-press
* Fix long-press to use event delegation for dynamic elements
---------
Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* feat: add array-wrap and array-unwrap commands
* Add LIST as available argument type
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* Throw when trying to wrap a closure
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* Throw on closure in array-unwrap
* Add the rest of argument types for array-unwrap
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* Add Python-friendly aliases
* Don't filter out just strings
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* Proper primitive value unwrapping
* Throw on multiple unnamed arguments
* Enhance parsed object wrapping
* Update comment to clarify boolean support in value wrapping
---------
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* fix(extensions/Summarize): prioritize UI memory content for {{summary}} macro
The {{summary}} macro previously relied solely on history-based metadata, causing it to return empty when starting a new chat if 'None (not injected)' was selected as the injection position.
This change prioritizes the #memory_contents UI value to ensure the macro resolves immediately, even before the first history-based summary is generated.
* Implement for legacy macro
* Restore original trim call
---------
Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>