* 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>
- Added `registerMacroAlias()` public method to register aliases for existing macros
- Extracted shared registration logic into private `#registerMacroEntry()` helper
- Refactored `registerMacro()` to use `#registerMacroEntry()` for both primary macros and aliases
- Alias registration validates name format, prevents self-aliasing, and resolves alias chains to primary definition
- Aliases inherit handler and metadata from target but has source of the registration caller
* feat: Add numeric comparison operators (>, >=, <, <=) to variable shorthand syntax
- Added four new comparison operators for local and global variables
- Implemented greaterThan, greaterThanOrEqual, lessThan, lessThanOrEqual operations in MacroCstWalker
- Updated lexer to recognize >=, >, <=, < operators (longer patterns before shorter to avoid conflicts)
- Simplified parser by consolidating operator alternatives into single OR block
- Enhanced autocomplete with operator definitions, examples, and usage
* Improve autocomplete for variable shorthand operators with cursor-aware filtering
- Track `variableNameEnd` and `variableOperatorEnd` positions in parsed macro context for accurate cursor position checks
- Add `isShortOperatorPrefix()` helper to detect operators that could be prefixes of longer ones (e.g., `>` → `>=`)
- Fix operator autocomplete to show longer variants when typing short operators (typing `>` now shows both `>` and `>=`)
- Show operator suggestions immediately when variable
* 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
* feat(macros): Add `/reroll-pick` command to reset `{{pick}}` macro choices
- Added `/reroll-pick` slash command to change the seed for all `{{pick}}` macros in current chat
- Command accepts optional numeric seed value, otherwise increments current seed by 1
- Updated `{{pick}}` macro to use `pick_reroll_seed` from chat metadata in seed calculation
- Updated `{{pick}}` macro description to mention reroll capability
- Added comprehensive help text with examples for `/reroll-pick` command
- Updated tests
* lint fix
* fix(macros): exclude null reroll seed from {{pick}} hash calculation
- Changed reroll seed default from 0 to null when not set
- Filter out null values from combined seed string to avoid including "-0" suffix
- Updated both core macro implementation and tests to match new behavior
* Use strict null comparison
---------
Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
* try to modify config.yaml at start instead of modify it
* replace error with warn when failing to write config.yaml
---------
Co-authored-by: ccss <ccss>
* feat(sd): Add generation status indicator and improve abort handling
- Add persistent toast notification showing "Generating image..." during generation
- Toast displays spinner, supports multiple concurrent generations with count
- Click toast to dismiss (generation continues in background)
- Improve abort handling: show friendly "Image generation stopped" info message
instead of error when user clicks stop button
- Handle abort in both generatePicture() and sendGenerationRequest() catch blocks
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Scope abort controllers for each individual button
* Use native element reference for caching button abort controller
* Update toast in paintbrush button handler
* refactor: Update abort message for image generation in sdMessageButton
* feat: Enhance generation indicator with active generation count in toast
* Move tracking after prompt generation, add toast for LLM prompt gen progress
* Add type annotation for generation toastr
* Simplify generation abort checks
* Remove unnecessary blank line in addSDGenButtons function
---------
Co-authored-by: mschienbein <mschienbein@users.noreply.github.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
* Add vector slash commands
* Updated vector-threshold command per feedback. Want to validate it is correct before fixing other commands.
* Added slash commands for several vector storage settings.
* Added slash commands for vector storage, updated w/dev feedback
* Fix min value of entries
---------
Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
* 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>
Fixes leftover bug from #4993.
In both `getBookmarkName` and `createBranch`, the second regex replacement was incorrectly using the original `name` variable instead of the already-cleaned `cleanName` variable, causing the legacy prefix removal to fail.
* 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>
* feat(sd): Add Z.AI GLM-Image model support
Add the new GLM-Image model to the Z.AI image generation source:
- Add 'glm-image' to the model dropdown with friendly display name
- Handle GLM-Image's requirement for dimensions in multiples of 32
(vs CogView's multiples of 16)
- Show quality dropdown for GLM-Image (supports standard/hd)
The GLM-Image model uses the same API endpoint as CogView
but has different dimension constraints.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(sd): Enhance Z.AI GLM-Image support
- Use regex for GLM-Image model detection (futureproofing)
- Skip 2^21 pixel limit for GLM-Image (CogView-specific)
- Add Z.AI recommended resolutions (1280x1280, 1568x1056, etc.)
- Add "Use Coding API" toggle for GLM Coding Plan users
- Add better error logging for image fetch debugging
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* refactor(sd): Address PR review feedback for Z.AI GLM-Image
- Remove custom zai_coding_api setting, use existing oai_settings.zai_endpoint
- Always use Common API for image generation (avoids rate limits)
- Keep ZAI_ENDPOINT import for consistency with other extensions
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: always use Common API for Z.AI image generation
Removes conditional endpoint selection since we decided to always use
Common API for image generation (Coding API has stricter rate limits).
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* It's not only cogview anymore
* Remove unused param from request payload
* Remove redundant debug logs
* Loosen the check on image quality data attribute
* Bring back coding API notice
---------
Co-authored-by: mschienbein <mschienbein@users.noreply.github.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.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>
* Add new variable shorthand operators and new variable macros
- Add `{{hasvar}}` and `{{deletevar}}` macros for local variables
- Add `{{hasglobalvar}}` and `{{deleteglobalvar}}` macros for global variables
- Implement new variable shorthand operators: `-=`, `||`, `??`, `||=`, `??=`, `==`
- Refactor variable expression evaluation to use direct variable API calls instead of routing through macro registry
- Add comprehensive operator support in lexer with proper token ordering for multi-character operators
* Implement lazy evaluation for variable shorthand value expressions
- Replace eager value evaluation with lazy evaluation pattern for variable operators
- Add `#createLazyValue()` method that caches value expression result on first call
- Change `#executeVariableOperation()` to accept `lazyValue` function instead of pre-evaluated value
- Only evaluate value expressions when actually needed (e.g., when variable is falsy for `||`, when variable doesn't exist for `??`)
- Add comprehensive e2e tests
* Update variable shorthand autocomplete with new operators and add edge case tests
- Add new operators to autocomplete definitions: `-=`, `||`, `??`, `||=`, `??=`, `==`
- Update example lists in `VariableShorthandAutoCompleteOption` and `VariableNameAutoCompleteOption`
- Add operator definitions with descriptions and `needsValue` flags to `VariableOperatorDefinitions`
- Update `parseMacroContext()` to recognize new operators with proper ordering (longer operators checked first)
* Add not equals (!=) operator to variable shorthand expressions
- Add `!=` operator to variable shorthand definitions for local and global variables
- Implement `notEquals` operation in `MacroCstWalker` that returns inverted equality comparison
- Add `NotEquals` token to lexer with pattern `/!=`
- Update parser to handle `!=` operator with value expression
- Add `!=` operator to autocomplete examples and operator definitions
- Update `parseMacroContext()` to recognize `!=` operator and...
* Tiny code review fixes
- Fix typo: "insie" → "inside" in variable shorthand operators comment
- Remove extra space in `{{getglobalvar}}` example usage
* Fix missing closing braces in hasglobalvar macro example usage
* Fix isFalsy to normalize value before checking boolean state in variable shorthand operators
- Apply `normalize()` to value before passing to `isFalseBoolean()` in `isFalsy` helper
- Ensures consistent falsy evaluation for variable shorthand operators like `||`, `??`, `||=`, `??=`
* Fix pipe character inside macro braces being treated as command separator
- Add `isInsideMacroBraces()` method to track unclosed `{{}}` macro braces
- Modify `testCommandEnd()` to only treat `|` as command end when not inside macro braces
- Scan text behind current position to calculate macro brace depth
- Skip second character when detecting `{{` or `}}` pairs
- Ensure `depth` never goes below 0 using `Math.max(0, depth - 1)`
* Add aliases for variable existence and deletion macros
- Add `varexists` alias for `hasvar` macro
- Add `flushvar` alias for `deletevar` macro
- Add `globalvarexists` alias for `hasglobalvar` macro
- Add `flushglobalvar` alias for `deleteglobalvar` macro
* Update variable shorthand operator descriptions to clarify return behavior
- Add "returns nothing" clarification to `=`, `+=`, `-=` operators in examples and definitions
- Add "returns the new value" clarification to `++`, `--` operators in examples and definitions
- Update `VariableOperatorDefinitions` descriptions to match example text
- Ensures users understand which operators return values vs perform silent mutations
* 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>
* Add customizable name builder and max tries to getUniqueName utility
- Add optional `nameBuilder` parameter to allow custom name formatting
- Add `maxTries` parameter to client-side version to prevent infinite loops
- Update JSDoc with new optional parameters
- Use nullish coalescing to set default name builder function
- Default name builder maintains existing "${baseName} (${i})" format
* Add startIndex option to getUniqueName utility for flexible name generation
* Enhance branch creation to use current chat name and ensure unique names
- Import `getCurrentChatDetails` from script.js
- Replace hardcoded branch name format with current chat name as base
- Add custom `buildBranchName` function to format branch names with suffix
- Strip existing " - Branch #N" suffixes before generating new branch name
- Use `getUniqueName` utility with `nameBuilder` to ensure unique branch names
- Remove unused `mainChat` variable and replace with `mainChatName`
* Enhance checkpoint creation to use current chat name and suggest unique names
- Import `getCurrentChatDetails` from script.js to get current chat name
- Add custom `buildCheckpointName` function to format checkpoint names with suffix
- Strip existing " - Checkpoint #N" suffixes before generating new checkpoint name
- Use `getUniqueName` utility with `nameBuilder` to ensure unique checkpoint names
- Pass `suggestedName` to template and popup input for better UX
- Replace manual loop with `getUniqueName`
* Remove automatic timestamp suffix from bookmark names
* Fix getUniqueName utility to correctly handle maxTries and return null on failure
* shut up copilot
* Strip legacy bookmark and branch name prefixes when generating unique names
- Add removal of old "Checkpoint #N - " prefix format in `buildCheckpointName`
- Add removal of old "Branch #N - " prefix format in `buildBranchName`
- Change `cleanName` from const to let to allow multiple replacements
- Ensures clean base names regardless of legacy or current naming format