Commit Graph

1951 Commits

Author SHA1 Message Date
Cohee 3eb3861596 Extension clone improvements (part 2) (#5571)
* 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
2026-05-02 17:08:57 +03:00
Reithan 338e35fc8a Fix json schema use for openAI compat CUSTOM endpoints in several use paths (#5561)
* 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
2026-04-30 23:38:01 +03:00
Cohee 5512473b29 Extension management improvements (#5552)
* 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>
2026-04-30 23:31:50 +03:00
Cohee 97dba399e4 Implement S256 challenge in OpenRouter OAuth flow (#5501)
* feat: implement S256 challenge in OpenRouter OAuth flow

* fix: add error handling for missing OpenRouter authorization code

* fix: save verifier to accountStorage

Co-authored-by: Copilot <copilot@github.com>

* fix: comment on getVerifierKey

---------

Co-authored-by: Copilot <copilot@github.com>
2026-04-26 22:32:53 +03:00
Wolfsblvt 4df18ccb0b Add Slug Parameter to Action Loader for Programmatic Identification (#5490)
* 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>
2026-04-20 22:29:40 +03:00
Wolfsblvt 53f251c52a Fix: Prevent "Show More Messages" Button from Triggering Message Edit Mode (#5486)
* 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>
2026-04-20 01:44:33 +03:00
Wolfsblvt 552936a0d8 fix: exclude other group members' reasoning from prompt context in group chats (#5473)
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
2026-04-19 16:08:52 +03:00
CasualAutopsy af7bd65f42 Impersonate with last_input_sequence (#5456) 2026-04-15 22:43:41 +03:00
Wolfsblvt 64c96e895c Add Streaming Display Utility and New Generation Slash Commands (/genstream, /reasoning-format) (#5438)
* 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>
2026-04-15 21:38:13 +03:00
Copilot 4d67a6986b fix: missing closing bracket in jQuery selector in setInContextMessages() (#5451)
* Initial plan

* fix: add missing closing bracket in jQuery selector in setInContextMessages()

Agent-Logs-Url: https://github.com/SillyTavern/SillyTavern/sessions/756522d8-8fe8-4c14-bcea-31d520619fb5

Co-authored-by: Cohee1207 <18619528+Cohee1207@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Cohee1207 <18619528+Cohee1207@users.noreply.github.com>
2026-04-15 21:21:32 +03:00
Wolfsblvt 7d3d1231a9 Chore: Add persona lifecycle events (PERSONA_CREATED, PERSONA_UPDATED, PERSONA_RENAMED, PERSONA_DELETED) (#5443)
* Add persona lifecycle events (created, updated, renamed, deleted) and emit them throughout persona management functions

* fix: await event emissions

* fix: await event in convertCharacterToPersona

* fix: await PERSONA_UPDATED in callbacks

* fix: delete multiple personas without reloading the chat

* fix: add CHAT_RENAMED event and adjust welcome screen pin update logic

---------

Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
2026-04-13 19:24:38 +03:00
Wolfsblvt f3521e7007 Migrate built-in extensions to use manifest-based activate hooks (#5435)
* Convert jQuery/IIFE wrappers to exported init() functions and register activate hooks in 8 extension manifests

* Convert remaining extensions to exported init() with activate hooks and await initExtensions()

- Convert jQuery/IIFE wrappers to exported init() functions in expressions, memory, quick-reply, regex, stable-diffusion, translate, tts, and vectors extensions

- Register init functions as activate hooks in extension manifests

- Properly await async initExtensions() in firstLoadInit()

* Fix eslint

---------

Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
2026-04-09 23:49:55 +03:00
Cohee 04ef0632ee Save chat before emitting event for user message (#5389)
Fixes #5388
2026-04-01 23:19:56 +03:00
Claude a8021ee6e1 Fix /genraw user instruct format not applied and unwanted system newline (#5372)
* Initial plan

* Fix /genraw user instruct format and system newline bugs

- Fix Bug #1: Change default role for string prompts from 'system' to 'user'
  to ensure user instruct formatting is properly applied
- Fix Bug #2: Remove unconditional newline after system prompt when using
  instruct mode, respecting the actual system instruct format

Agent-Logs-Url: https://github.com/SillyTavern/SillyTavern/sessions/7bfd62eb-2898-468d-9ea9-42d694a394b9

Co-authored-by: Cohee1207 <18619528+Cohee1207@users.noreply.github.com>

* fix: add runtime string type check for substituteParams content

* Add fallback wrap for story string

---------

Co-authored-by: anthropic-code-agent[bot] <242468646+Claude@users.noreply.github.com>
Co-authored-by: Cohee1207 <18619528+Cohee1207@users.noreply.github.com>
2026-03-31 01:02:31 +03:00
awaae b04c974407 feat(ui): add interface to manage message swipe history (#5304)
* 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>
2026-03-26 02:28:48 +02:00
Xiangzhe 94139f465e feat: add finalizeIntermediaryMessage for StreamingProcessor (#5333)
* 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>
2026-03-26 00:26:39 +02:00
Wolfsblvt 45009cd0e4 Deprecate legacy loader and migrate all callsites to action-loader system with informative toasts (#5326)
* 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>
2026-03-22 03:30:23 +02:00
DeclineThyself 0e5928b13a Filter out inapplicable stop strings for Chat Completion (#5337)
* 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>
2026-03-22 03:05:14 +02:00
Wolfsblvt a6486d7f08 Add Action Loader Module with Stacking Support and STscript Commands (#5311)
* 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>
2026-03-20 01:04:39 +02:00
Wolfsblvt f9c42a32dd Character CRUD Slash Commands (#5306)
* 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>
2026-03-18 18:14:21 +02:00
Cohee 9bce79f797 Claude: fix non-streaming multipart text block parsing (#5278) 2026-03-13 21:12:46 +02:00
Roland4396 1c5091539c feat: optionally gzip large save uploads with fallback (#5259)
* feat: optionally gzip large save uploads with fallback

* fix: replace Safari-prone save compression with fflate fallback

* refactor: align save upload compression with review feedback

* refactor: use compressRequest wrapper for save uploads

* Refactor request compression settings

* Fix default value

* Avoid null in bytes parsing result

* fix: switch request compression to fflate gzip

* fix: add request compression maxBytes cap and clarify timeout semantics

* Refresh package-lock.json

* Unify payload limit setting names

* Expose compression termination function

* Add compression to group chat saves

---------

Co-authored-by: Roland4396 <Roland4396@users.noreply.github.com>
Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
2026-03-10 23:32:36 +02:00
Kristy Aurelia 7418d272a7 Split generateRaw into two functions exposing generateRawData (#5249)
* Split generateRaw into two functions exposing generateRawData

* Concise types

* Improve comments

* Update public/script.js

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update public/script.js

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update public/script.js

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Add GenerateRawParams typedef for improved documentation and clarity

---------

Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-03-07 19:56:30 +02:00
Haochen 2415e6bc86 add Slash commands regenerate and swipe (#5243)
* 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>
2026-03-07 18:16:49 +02:00
Cohee 8c07dcda24 Show experimental engine onboarding for greeting macros 2026-03-07 17:52:00 +02:00
Cohee b9efb12d4d Fix type error in createLazyFields 2026-03-03 15:48:45 +00:00
Copilot b5a1d227fd Implement {{charFirstMessage}} / {{greeting}} macro with alternate greeting indexing and substitution (#5220)
* Initial plan

* Implement {{firstMessage}} / {{greeting}} macro for character's first message

Co-authored-by: Cohee1207 <18619528+Cohee1207@users.noreply.github.com>

* Simplify firstMessage resolver to use || instead of ?? for consistency

Co-authored-by: Cohee1207 <18619528+Cohee1207@users.noreply.github.com>

* Remove {{firstMessage}} alias, add 0-based greeting index for alternate greetings

Co-authored-by: Cohee1207 <18619528+Cohee1207@users.noreply.github.com>

* Add alternateGreetings to env, apply substitution to greetings

Co-authored-by: Cohee1207 <18619528+Cohee1207@users.noreply.github.com>

* Remove legacy greeting macro, keep only new engine implementation

Co-authored-by: Cohee1207 <18619528+Cohee1207@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Cohee1207 <18619528+Cohee1207@users.noreply.github.com>
Co-authored-by: anthropic-code-agent[bot] <242468646+Claude@users.noreply.github.com>
2026-03-01 17:44:29 +02:00
ZhenyaPav 0ba0418fac OpenRouter interleaved reasoning forwarding for tool-call continuations (#5160)
* 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>
2026-02-22 13:15:52 +02:00
Copilot eeda4d377e Add {{maxContext}}, {{maxResponse}} macros and {{maxPromptTokens}} alias (#5176)
* Initial plan

* Add maxContext, maxResponse macros and maxPromptTokens alias

Co-authored-by: Cohee1207 <18619528+Cohee1207@users.noreply.github.com>

* Refactor getMaxContextSize to use getMaxContextTokens/getMaxResponseTokens and remove maxReply aliases

Co-authored-by: Cohee1207 <18619528+Cohee1207@users.noreply.github.com>

* Align aliases in single line

* Rename getMaxPromptTokens

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Cohee1207 <18619528+Cohee1207@users.noreply.github.com>
2026-02-17 21:47:51 +02:00
Cohee 4d1619ba47 Chore: enable brace-style eslint check (#5159)
* eslint: enable brace-style check

* Fix jsdoc and color

* fix: correct CSS color syntax in CreateZenSliders function
2026-02-15 01:46:32 +02:00
Cohee 357da3219b Chore: Add code formatting conventions as eslint rules (#5158)
* Add code formatting conventions as eslint rules

* Improve formatting in addQuickReply
2026-02-15 01:16:34 +02:00
Cohee 9714374749 Preserve user input on tool call recursion (#5134)
Supersedes #5129
2026-02-11 22:49:39 +02:00
Cohee bee4d9a818 fix: sync swipes only when chat is not pristine to ensure macro resolution (#5106) 2026-02-08 02:35:14 +02:00
Cohee 4e5cb9c44f Prevent accidental chat overwrites when switching between characters/groups 2026-02-05 23:47:17 +02:00
DeclineThyself b64c279473 Add clearData option to clearChat function (#5091)
* Centralized `await clearChat();` and `chat.length = 0;` into `wipeChat()`

* Added `clearData` argument to `clearChat`.

---------

Co-authored-by: user <user@exmaple.com>
2026-02-05 23:39:36 +02:00
Cohee 3f8acaad4e Refactor /search to use per-line async parsing (#5085)
* 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
2026-02-02 01:44:15 +02:00
Robert de Forest ef25a03650 Expose character update APIs for extensions (#5062)
* 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>
2026-01-26 20:38:23 +02:00
Wolfsblvt 9ff9d59672 Macros 2.0 (v0.7.1) - Macro Autocomplete everywhere (#5019)
* 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>
2026-01-23 23:46:47 +02:00
Wolfsblvt 6f5032f20e Allow reasoning edit to substitute macros on saving the reasoning (#5052)
* 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
2026-01-23 00:45:26 +02:00
DeclineThyself a09c1a7a84 Added 'dot-notation': ['error'] to .eslint.cjs (#5042)
* Added 'dot-notation': ['error'], to `.eslint.cjs`

* Ran `eslint --fix` to correct `dot-notation` errors.

* Added `eslint-disable dot-notation` anywhere errors were caused.

* Allowed dot-notation for uppercase properties: 'allowPattern': '[A-Z]\\w*$'

* Check if `rule instanceof CSSStyleRule`
https://github.com/SillyTavern/SillyTavern/pull/5042#discussion_r2711827148

* Fixed `await result.json();` types.

* refactor: update dot-notation usage in CoquiTtsProvider and PresetManager

---------

Co-authored-by: user <user@exmaple.com>
Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
2026-01-23 00:11:03 +02:00
Wolfsblvt f3c886fd12 Add APP_INITIALIZED event before hideLoader in initialization sequence, before APP_READY fires (#5051)
* Add APP_INIT event before hideLoader in initialization sequence

* refactor(events): rename APP_INIT to APP_INITIALIZED

---------

Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
2026-01-22 23:40:48 +02:00
Jeff Sandberg b418ec5c37 Add taxon filter controls to Group Chat member list (#5006)
* 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>
2026-01-16 02:27:59 +02:00
DeclineThyself 7d99540829 Improved printMessages performance on large chats by reducing DOM updates. (#4947)
* 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>
2026-01-15 00:30:40 +02:00
Cohee b89ffdfece Suppress error messages when Firefox unloads the tab (#5013)
* Fix error messages when Firefox tab reopened after unload
#4989

* Export settingsReady flag
2026-01-14 23:40:52 +02:00
DeclineThyself 3e40ac1c27 refactor/perf-printMessages #4: Renamed newMessage to messageElement and newMessageId to messageId. (#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

* Yeah whatever

---------

Co-authored-by: user <user@exmaple.com>
Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
2026-01-14 00:20:26 +02:00
Cohee 684b755826 Adjust itemized prompts on message move/delete (#5000)
* Adjust itemized prompts on message move/delete

* Sort itemized prompts on swap

* Remove itemized prompt on regeneration
2026-01-12 22:40:33 +02:00
DeclineThyself 69b7a17c77 refactor/perf-printMessages #3: Extracted updateMessageItemizedPromptButton and getMessageHTML from addOneMessage to improve readability. (#4984)
* 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>
2026-01-12 21:39:47 +02:00
DeclineThyself a9f2d559f4 refactor/perf-printMessages #2: Removed getMessageFromTemplate (#4983)
* 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>
2026-01-12 02:12:51 +02:00
Cohee 2d1a96f91d Improve performance of printMessages (#4979)
* Improve performance of printMessages

* Add clarifying comment

* Refactor printMessages into redisplayChat.

* const https://github.com/SillyTavern/SillyTavern/pull/4981#discussion_r2675632422

* Use `toFixed(3)` instead of 17 decimals. https://github.com/SillyTavern/SillyTavern/pull/4981#discussion_r2675647691

* Removed `.find is faster than .children.` comment. https://github.com/SillyTavern/SillyTavern/pull/4981#discussion_r2675625188

* Simplified add 'last_mes'. https://github.com/SillyTavern/SillyTavern/pull/4981#discussion_r2675616734

---------

Co-authored-by: user <user@exmaple.com>
2026-01-11 18:33:23 +02:00
Cohee d56011b60f Skip redundant scroll adjustment 2026-01-11 02:05:44 +02:00