* fix: remove the cloned directory if it contains no manifest
* fix: apply feature flag guard to user extension data hosting
* fix: disable inactive controls when feature flag is off
* fix: change response status to 404
* pass jsonSchema options through sendStreamingRequest in Generate
* translate json_schema to response_format for CUSTOM chat completion source
* pass jsonSchema through generateGroupWrapper params in group chat generation
* feat: enhance asset management with extension categories
Co-authored-by: Copilot <copilot@github.com>
* fix: enhance extension name validation in server endpoints
* feat: display extension author in the extensions list
* fix: unify server error response format
Co-authored-by: Copilot <copilot@github.com>
* feat: add splash on installing third-party for the first time
* fix: add URL format validation, unify validation error messages
Co-authored-by: Copilot <copilot@github.com>
* fix: apply object freeze to EMPTY_AUTHOR value
Co-authored-by: Copilot <copilot@github.com>
* fix: typecheck extensionName in API requests
Co-authored-by: Copilot <copilot@github.com>
* feat: add feature flag guard to extensions endpoints
Co-authored-by: Copilot <copilot@github.com>
* fix: parse URL before checking
Co-authored-by: Copilot <copilot@github.com>
* fix: use case insensitive regex check
* fix: make debug log more useful
Co-authored-by: Copilot <copilot@github.com>
* fix: add pre-validation of URL format and protocol
Co-authored-by: Copilot <copilot@github.com>
* fix: leaner installation success toast
* fix: settings data loss when extensions are disabled
* fix: don't try to auto-focus elements that don't exist
Co-authored-by: Copilot <copilot@github.com>
* fix: set Popup.defaultResult to negative
Co-authored-by: Copilot <copilot@github.com>
* revert: restore undefined default result
---------
Co-authored-by: Copilot <copilot@github.com>
* feat: add slug parameter to action-loader for programmatic identification
Add optional `slug` parameter to ActionLoaderHandle for easier identification via code or CSS. Update all loader.show() calls across the codebase to include descriptive slugs ('app-init', 'chat-rename', 'chat-delete', 'bulk-delete', 'chat-load', 'image-generation', 'legacy-loader'). Add data attributes (data-slug, data-loader-id, data-blocking) to toast content div. Expose slug via getter and make id private with getter.
* Apply suggestions from code review
Fix slug jsdoc wording
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* fix: Add identifier to second loader in img gen
---------
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
* fix: prevent event bubbling on show more messages button
Replace mouseup/touchend with click event and add stopPropagation/preventDefault to prevent unintended event bubbling when loading more messages.
* Add hover style to "show more messages"
* add button role to show_more_messages
---------
Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
In group chats, only include reasoning from the currently generating character instead of all group members. This prevents reasoning from other characters being injected into the prompt context when generating responses.
- Filter reasoning in coreChat loop based on message author matching name2
- Filter reasoning in setOpenAIMessages based on message author matching name2
- Add isOtherGroupMember check before adding reasoning to messages
* Add StreamingDisplay class for live LLM generation output with floating toast panel
- Add StreamingDisplay class to show streaming reasoning and content in a floating toast panel
- Extract createModelIcon() helper from insertSVGIcon() for reusable API/model icon creation
- StreamingDisplay automatically appends inside topmost open dialog (same pattern as fixToastrForDialogs)
- Add CSS with fade-in animation, pulsating activity indicator, and separate reasoning/content sections
- Support optional model icon in header
* Add ConnectionManagerRequestService.getProfileIcon() method for retrieving profile API icons
- Add static getProfileIcon() method to ConnectionManagerRequestService
- Returns HTMLImageElement created via createModelIcon() for a given profile's API/model
- Accepts optional profileId parameter, defaults to currently selected profile
- Returns null if Connection Manager is disabled, profile not found, or profile has no API
- Import createModelIcon from script.js
* Use animation_duration directly in hide() and CSS transition instead of constant
- Remove ANIMATION_DURATION_MS constant and use animation_duration directly in hide() method
- Replace hardcoded 0.3s CSS transitions with CSS variable var(--animation-duration, 125ms)
- Read animation_duration value inline in hide() for accurate timing
* Add /genstream slash command with live streaming display and reasoning support
- Add /genstream slash command that generates text via Connection Manager with live streaming UI
- Add formatReasoning() helper function (inverse of parseReasoningFromString) to format reasoning/content into template-wrapped strings
- Add connectionProfiles enum provider for profile selection in slash commands
- StreamingDisplay: add delay parameter to hide() method (default 1000ms) to show final result before dismiss
* Add /reasoning-format slash command to format reasoning and content into template-wrapped strings
- Add /reasoning-format (alias: /format-reasoning) slash command that wraps reasoning/content using Reasoning Formatting settings
- Accept required 'reasoning' named argument and optional unnamed 'content' argument
- Validate that prefix/suffix are configured before formatting
- Return formatted string via formatReasoning() helper for use with /reasoning-parse
- Show warning toasts if prefix/suffix missing
* Rename /genstream command to /profile-genstream and move to appropriate module
* Apply messageFormatting to StreamingDisplay reasoning and content text for proper rendering
- Import messageFormatting from script.js
- Replace textContent with innerHTML using messageFormatting() in updateReasoning() and updateText()
- Pass isSystem=true for reasoning, isSystem=false for content to match formatting expectations
- Update css to utilize pre-formatted paragraphs correctly
* Strip auto-added quotes from <q> tags in StreamingDisplay and add 'mes_text' class for consistent chat message formatting
- Add CSS rules to remove browser-default quotes from <q> tags in reasoning and content sections
- Add 'mes_text' class to textContent div to match chat message formatting behavior
- Prevents double quotes when messageFormatting already adds them via <q> tags
* Add minimize/close buttons and complete state to StreamingDisplay with configurable auto-hide
- Add minimize button to collapse/restore content sections while keeping header visible
- Add close button to manually dismiss display (generation continues in background)
- Replace CSS pseudo-element with explicit LED indicator element for better state control
- Add complete() method to mark generation done: changes LED from pulsing orange to solid green
- Add configurable auto-hide delay after completion
* Add stop button to StreamingDisplay with abort support and onStop/onComplete closures for /profile-genstream
- Add stop button to StreamingDisplay when onStop handler is provided
- Add markStopped() method with solid red LED state indicator
- Add AbortController integration to /profile-genstream for request cancellation
- Add onStop and onComplete closure arguments to /profile-genstream command
- Update complete() method signature to use options object with label and delay
- Disable stop button immediately
* Position StreamingDisplay above bottom form block using CSS variable with fallback
- Change bottom positioning from fixed 20px to dynamic calculation
- Use max() to position above --bottomFormBlockSize + 5px or minimum 20px
- Ensures StreamingDisplay doesn't overlap with bottom UI elements
* Rename /profile-genstream arguments for clarity: label→generating, completedLabel→completed, hideDelay→delay
- Rename `label` argument to `generating` to better reflect its purpose as the in-progress state label
- Rename `completedLabel` to `completed` for consistency and brevity
- Rename `hideDelay` to `delay` for simpler naming
- Update all internal references and variable names to match new argument names
- Update argument descriptions and default values accordingly
* Remove variable resolution from /profile-genstream arguments: system, length, and delay
- Remove ARGUMENT_TYPE.VARIABLE_NAME from typeList for system, length, and delay arguments
- Replace resolveVariable() calls with direct argument access for system, length, and delay
- Simplify type checking to use typeof directly on args properties
- Maintain existing default values and validation logic
* Add warning toast and early return when connection profile not found in /profile-genstream
- Display toastr warning when fuzzy search fails to find matching profile
- Return empty string to prevent execution with invalid profile
- Improves user feedback for incorrect profile names or IDs
* Extract buildResultText() helper in /profile-genstream to return partial results when stopped
- Add buildResultText() helper function to centralize result formatting logic
- Return partial generated text when user stops generation instead of empty string
- Reuse buildResultText() for both stopped and completed states
- Maintains consistent reasoning formatting in both cases
* fix lint
* Update documentation to reflect argument name change from hideDelay to delay
---------
Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
* 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>
* 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>
* 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>
* 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>
* add Slash commands regenerate and swipe
* Update /swipe slash command direction handling
* Fix await not working in groups
* Add SLASH_COMMAND source to swipe functionality and update constants
---------
Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
* fix(openrouter): forward reasoning across active tool-call chains
* feat(reasoning): add tool-chain forwarding toggle and honor edited reasoning
* feat(reasoning): add OpenRouter interleaved forwarding modes
* moved the reasoning forwarding dropdown into a separate line
* feat(reasoning): default tool reasoning forwarding to disabled
* refactor(openrouter): move tool reasoning mode to CC settings
Move OpenRouter tool reasoning forwarding control to response configuration and scope it to OpenRouter.
Store mode in chat completion settings (presettable), remove legacy power_user boolean/fallback, and use constants for mode values.
Preserve OpenRouter Gemini signature forwarding independently from plaintext tool reasoning mode.
* fix(openrouter): tighten active-chain reasoning forwarding
Use trailing contiguous tool-chain boundary for active-chain eligibility.
Also rename the UI control to Interleaved Thinking Forwarding and place selector on its own line.
* fix(openrouter): use adjacent assistant reasoning for tool calls
For interleaved thinking forwarding, source reasoning only from the immediately preceding assistant non-tool message.
Keep mode gating behavior unchanged and avoid history-window reasoning carryover.
* fix(openrouter): skip tool messages for reasoning source
When forwarding interleaved reasoning, ignore intervening tool result messages when resolving the preceding assistant reasoning source.
This keeps only the first tool call in a chain tied to a prior assistant reasoning block unless a later invocation carries its own reasoning.
* fix(openrouter): keep plaintext reasoning with signatures
Do not suppress forwarded tool-call reasoning when thought signatures are present.
* fix(openrouter): split interleaved thinking mode behavior
Restore distinct mode semantics: active_chain uses nearest assistant-text boundary after skipping tool/tool-call messages, while since_last_user scans for latest assistant reasoning since user.
Update UI label to Interleaved Thinking with right-aligned dropdown and explanatory tooltip.
* style(openrouter): align interleaved thinking dropdown row
Match OpenRouter interleaved thinking control layout with existing oneline-dropdown patterns.
Also update reasoning-forwarding inline comment wording for current mode behavior.
* docs(ui): clarify interleaved thinking tooltip
Use explicit API-request wording for OpenRouter interleaved thinking tooltip text.
* i18n(openrouter): localize interleaved thinking UI
Add locale keys for OpenRouter interleaved thinking label, mode options, and inline helper description.
Wire dropdown option text to data-i18n in index.html.
* fixed helper text wrapping
* fix(ui): make interleaved thinking helper text wrap
* i18n(openrouter): translate interleaved thinking labels
Replace placeholder English values for interleaved thinking keys in non-English locale files.
* fix(ui): restore interleaved thinking dropdown alignment
* Remove changes from en.json
* Type fixes
* Reworked the interleaved reasoning provider logic
* Renamed the variables in preparation for potential implementation for other providers
* Gate interleaved tool reasoning on reasoning request setting
---------
Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
* Centralized `await clearChat();` and `chat.length = 0;` into `wipeChat()`
* Added `clearData` argument to `clearChat`.
---------
Co-authored-by: user <user@exmaple.com>
* Refactor /search to use per-line async parsing
Supersedes #5047
* Use named type
* Cache query fragments, add file name match
* Skip invalid chat files in search
* Remove extensions from /search results
* Use file_id when appropriate
* Revert "Use file_id when appropriate"
This reverts commit aaa0274b53da6a677183b6f923163053cfd6d569.
* Clean-up file extension handling
* Move extension append down for non-group
* Expose character update APIs for extensions
Add getCharacterSource, importFromExternalUrl, and importTags to the
extension context (SillyTavern.getContext()). This allows extensions to:
- Get the source URL for a character (Chub, etc.)
- Import/update a character from an external URL
- Import tags from a character's embedded tag data
These functions already exist and are used internally but were not
exposed to extensions. This enables extension developers to build
features like bulk character update checking and tag synchronization.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Fix review comments
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
* Add macro autocomplete for free text inputs
Implements macro autocomplete (`{{`) for textareas and input fields marked with `data-macros` attribute. Extracts shared autocomplete logic into MacroAutoCompleteHelper.js for consistency between slash command and free text contexts. Includes MutationObserver for dynamic element initialization and supports variable shorthands, operators, flags, and scoped macro closing tags.
* fix annoying circular dependency again
* Add `data-macros` attribute to enable macro autocomplete on text inputs
Enables macro autocomplete (`{{`) for various textareas and input fields throughout the UI by adding the `data-macros` attribute. Includes context template fields, instruct mode sequences, character/persona descriptions, world info content, and other prompt-related inputs. Also ensures the attribute is preserved when expanding editors and creating world info entries.
* Allow macro autocomplete in editing messages
Enables macro autocomplete (`{{`) when editing messages by adding the `data-macros` attribute to the dynamically created edit textarea element.
* Add autocomplete visibility setting support for macro autocomplete
Respects the global STScript autocomplete visibility setting (`power_user.stscript.autocomplete.state`) for macro autocomplete in free text inputs. When set to "Input length > 1", macro autocomplete only activates after typing `{{` plus at least 2 characters. Also adds a tooltip to the visibility setting explaining it applies to both slash commands and macros.
* Fix unclosed div tag in STScript autocomplete visibility setting
Closes the `<div>` tag that was incorrectly left open in the autocomplete visibility setting markup.
* Add setting to control macro autocomplete visibility in non-expanded fields
Introduces a new `showInAllMacroFields` setting that controls whether macro autocomplete appears in all macro-enabled fields or only in expanded editors and when pressing Ctrl+Space. Also adds `data-macros-autocomplete` attribute support with `always` and `hide` modes for per-field override. When the setting is off, autocomplete only shows in expanded editors (which now get `data-macros-autocomplete="always"`) and the completion
* Add `data-macros-autocomplete-style` attribute to control macro autocomplete popup size
Introduces a new `data-macros-autocomplete-style` attribute with `small` (33vw, max 700px) and `expanded` (default chat width) modes to control macro autocomplete popup dimensions. The `small` style is now the default for inline fields, while `expanded` is used for expanded editors and prompt manager. Also refactors `getAutocompleteMode` to return `DEFAULT` instead of `null` and adds corresponding `getAutocompleteStyle` helper
* Fix autocomplete details panel alignment when list is constrained by viewport edge
Adjusts the details panel position to align with the actual autocomplete list position when the list is constrained by the right edge of the viewport. Previously, the panel would position based on cursor location even when the list was pushed left, causing misalignment. Now checks if the list's actual position differs from the calculated position (with 5px tolerance) and uses the list's position instead.
* Guard autocomplete details panel alignment check with `isReplaceable` condition
Prevents attempting to read the autocomplete list's bounding rect when the list is not visible. The alignment adjustment for viewport-constrained lists now only runs when `isReplaceable` is true, avoiding potential errors when the list DOM is not rendered.
* Fix macro autocomplete cursor detection to handle nested macros correctly
Updates `findMacroAtCursor` to track nesting depth when searching for opening `{{` and closing `}}` braces. Previously would incorrectly stop at the first brace pair encountered in either direction, breaking autocomplete when cursor was inside nested macros like `{{getvar::{{getvar::name}}}}`. Now properly skips over nested macro boundaries by incrementing/decrementing depth counters until finding the matching braces at depth
* gief me my comments back (and fixes, that were missed)
- Added detailed JSDoc comments to all exported functions explaining parameters, return types, and behavior
- Added inline comments throughout functions explaining logic flow, edge cases, and implementation details
- Documented parser-based vs regex-based unclosed scope detection approaches
- Clarified variable shorthand autocomplete logic including operator filtering, context display, and priority
* refactor(macros): freeze MACRO_AUTOCOMPLETE_MODE and MACRO_AUTOCOMPLETE_STYLE enums
* feat(macros): explicitly set `makeSelectable` flag for non-insertable autocomplete options
- Set `makeSelectable = true` for variable shorthand options in {{if}} conditions (already insertable)
- Set `makeSelectable = false` for already-typed operators in variable shorthand autocomplete
- Set `makeSelectable = false` for already-typed flags in macro autocomplete
- Set `makeSelectable = false` for non-selectable closing block flags when no unclosed scopes exist
- Set `makeSelectable = false` for sc
* refactor(macros): consolidate typedef imports in MacroAutoCompleteHelper
- Fixed typo in MacroDefinition typedef import (removed extra `/` from JSDoc comment)
- Replaced long-form typedef imports with short-form aliases for MacroAutoCompleteContext and MacroDefinition
- Improved code consistency by using imported typedefs throughout function signatures
* refactor(autocomplete): select first selectable item as default instead of always first item
- Extracted default item selection logic into `selectDefaultItem()` method
- Changed default selection to prioritize first selectable item over first item in list
- Falls back to last item when no selectable items exist (preserves context for info-only options)
- Added JSDoc documentation explaining selection behavior
* feat(macros): make already-typed variable names non-selectable in autocomplete
- Set `makeSelectable = false` for variable name options that match the currently typed name
- Set empty `valueProvider` for matched variables to prevent re-insertion
- Prevents redundant selection of variables that are already fully typed in the input
* feat(macros): add value context autocomplete option for variable shorthand operators
- Created `VariableValueContextAutoCompleteOption` class to display context about expected values
- Shows operator name, symbol, and description when typing variable shorthand values
- Displays currently typed value and completion hint
- Non-selectable option (context only) with priority 4
- Added to variable shorthand autocomplete when operator is typed and value is being entered
* fix lint
---------
Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
* Apply macro substitution when editing reasoning content
- Added `substituteParams()` call to process macros in edited reasoning text
- Changed `newReasoning` from const to let to allow reassignment
* chore: Remove unnecessary double macro substitution from message edit
- Removed `substituteParams()` call for first message (index 0) in `messageEditDone()`
- Macro substitution is now handled consistently by `updateMessage()` for all messages
* Add taxon controls to top of group member list
* Refactor/cleanup getGroupCharacters
* Fix favorites, refactor and cleanup code
* Fix clearing filters, only show relevant filters in groups
* Fix issues and add persistence
- Fix group member tag listing requiring character list to be init to display
- Fix character tag updates to actually show up in group member contexts
- Persist filter changes for group member tag controls
* Apply suggestions from code review
Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
* Avoid sibling selectors
* Err on invalid tag type
* avoid hardcoded ids
* cleanup: don't use `group_member`, use `group_candidates_list`
* Support both selectors and jquery instances in getFilterHelper
* Sanitize missing tag filters before rendering
* Unscrew jsdoc formatting
* Show all tags, mark absents specially
* Improve JSDoc
* Fix tag indicator for group contexts
* Don't use deprecated fields
* Add a comment on potentially undefined group id
---------
Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
* Improved printMessages performance by reducing DOM updates.
Refactored part of addOneMessage into createMessageElement.
Before: Rendered 1000 messages in 25.529199999809265 seconds.
After: Rendered 1000 messages in 5.088 seconds.
* Fixed mistakes: https://github.com/SillyTavern/SillyTavern/pull/4947#pullrequestreview-3624592007
* Formatting fix
* Fixed scroll and last_mes order..
* Refactored printMessages logic into redisplayChat.
* Passed `fade`.
* Cleanup.
* WIP.
Removed getMessageFromTemplate
Refactored addOneMessage and updateMessageElement.
* Minor changes to better match https://github.com/SillyTavern/SillyTavern/pull/4985
* If insert is false, `newMessage` may not be new, so I renamed `newMessage` to `messageElement` and `newMessageId` to `messageId`.
I also rearranged some constants to improve readability.
* Accept 0 as valid insertAfter/insertBefore targets
* Renamed forceId to messageId for clarity.
* Change forceId to undefined by default.
* Swapped `forceId` to `messageId` in addOneMessage.
* Added adjustMediaScroll to updateMessageElement.
* Revert "Change forceId to undefined by default."
This reverts commit cbda7eb3fe0a2aa46e0988e82260910c62bc5034.
---------
Co-authored-by: user <user@exmaple.com>
Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
* If insert is false, `newMessage` may not be new, so I renamed `newMessage` to `messageElement` and `newMessageId` to `messageId`.
I also rearranged some constants to improve readability.
* Accept 0 as valid insertAfter/insertBefore targets
* Yeah whatever
---------
Co-authored-by: user <user@exmaple.com>
Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
* Extracted updateMessageItemizedPromptButton and getMessageHTML from addOneMessage to improve readability.
* Fix types and function calls
* Fixed insertBefore, insertAfter and messages without extra.
* Use strict comparison operator
* Use logical OR for display text fallback
* Fixed newMessageId again.
* Faster showMoreMessages.
* removed `insertAfter` and `insertBefore` from `mes_edit_copy`, `/message-role` and `/message-name`.
* Formatting fix
* Refactor newMessageId
---------
Co-authored-by: user <user@exmaple.com>
Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
* Reduced redundant swipe code by fully updating the swipe message.
* `getMessageFromTemplate` is an inconvenient function that requires more lines than it saves.
It cannot be used in any other function, therefore it should not exist.
This change also prevents an unnecessary call of `messageTemplate.clone` in addOneMessage when `type = 'swipe'`.
ESLint.
* Fixed: https://github.com/SillyTavern/SillyTavern/pull/4983#discussion_r2680379455
* Replaced ?? with &&: https://github.com/SillyTavern/SillyTavern/pull/4983#discussion_r2680366010 and removed comments.
* Fixed bias check. "0" is falsy.
* Remove scroll adjust early bail
* Call appendMediaToMessage before updating content
Because we need to preserve chatHeight and scrollPosition according to the previous swipe, not the new one
---------
Co-authored-by: user <user@exmaple.com>
Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>