Commit Graph

8983 Commits

Author SHA1 Message Date
Cohee b44b12b527 Add 'pm-render' command to refresh prompt manager content (#5483) 2026-04-20 00:07:25 +03:00
Wolfsblvt d720605be8 Bulk extension field updates via merge-attributes with UNSET_VALUE sentinel (#5471)
* feat: add bulk extension field updates with UNSET_VALUE sentinel for key deletion

- Add `UNSET_VALUE` sentinel constant to signal complete field removal from character cards
- Add `writeExtensionFieldBulk()` function to update extension fields across multiple characters in a single API call
- Add `deleteValueByPath()` utility function to remove nested object keys by dot-path
- Update `writeExtensionField()` to support `UNSET_VALUE` for deleting extension keys
- Extend `/api/characters/merge-attributes

* Revert package-lock.json changes

* Allow null values in merge-attributes filter path validation

Change filter.path existence check to only skip on undefined, not null. This allows merging attributes when the existing value is explicitly null, treating null as a valid value rather than absence of a value.

* fix: share forbiddenRegExp between modules

* feat: add writeExtensionFieldBulk and UNSET_VALUE constant to getContext

* Update src/endpoints/characters.js

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

* fix: validate for .png extension

* Update public/scripts/extensions.js

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

* refactor: extract shouldSkip logic as a function param to avoid double parsing

---------

Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-20 00:06:28 +03:00
Octopus b436971a09 fix: correct typo in cacheScores debug log and add JSDoc to filterDataByState (#5468)
* fix: limit max-height of select[multiple] on mobile to prevent Chrome 145+ full-screen rendering (fixes #5242)

* fix: correct typo in cacheScores debug log and add JSDoc to filterDataByState (fixes #5252)

* fix: Correct jsdoc syntax

---------

Co-authored-by: octo-patch <octo-patch@github.com>
Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
2026-04-19 22:04:45 +03:00
Octopus a678299700 fix: limit max-height of select[multiple] on mobile to prevent Chrome 145+ full-screen rendering (fixes #5242) (#5467)
Co-authored-by: octo-patch <octo-patch@github.com>
2026-04-19 21:54:10 +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
ashishch432 d1e719eb48 add claude-opus-4-7 (#5465) 2026-04-19 15:47:40 +03:00
Wolfsblvt 4003251c2f Increase Top K max value from 200 to 500 for text generation WebUI (#5474)
Raises the maximum allowed Top K sampling parameter from 200 to 500 in both the range slider and number input controls to support higher token selection limits.
2026-04-19 15:20:06 +03:00
awaae 767746beb2 WI: Rename "New" button to "Create"
* Fix internationalization issues

* fix(i18n): update world creation key and zh-cn translations

Changes the i18n key for the world editor's "New" button to "Create" to
avoid conflict with listing filters. Updates the Chinese translation
for the "New" key to "最新" (Latest).

* fix(i18n): correct translation key for world creation button

---------

Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
2026-04-16 21:12:58 +03:00
Enerccio 277285d30c implemented emit events for itemized-prompts.js (#5461)
* implemented emit events for itemized-prompts.js

* removed redundant ITEMIZED_PROMPTS_DELETED_ALL event and updated emit logic accordingly

---------

Co-authored-by: Peter Vanusanik <pvan@bach.cz>
2026-04-16 21:10:19 +03:00
Wolfsblvt 0ac31c8fcd Enhanced /persona-sync Command with Range, Name Filter, and Quiet Mode (#5460)
* Add range and silent parameters to /persona-sync command with optional confirmation suppression

- Add optional start/end range parameters to syncUserNameToPersona() function
- Add silent parameter to suppress confirmation popup when needed
- Update /persona-sync slash command to accept range argument (index or range string) and named silent argument
- Parse range using stringToRange() utility, default to full chat if not provided
- Update confirmation message to reflect whether syncing all messages or specified

* Add `from` named argument to /persona-sync command for filtering by persona name

- Add `from` named argument to filter messages by persona name (case-insensitive)
- Rename `silent` argument to `quiet` with inverted default (true) for consistency
- Add userMessageNamesEnumProvider() to provide autocomplete for existing user message names in chat
- Update syncUserNameToPersona() to accept nameFilter parameter and filter messages accordingly
- Update confirmation message to reflect name filtering when

* Add async/await wrapper to sync_name_button click handler for proper promise handling

Function now has arguments, so using just the function as the event is shown as wrong usage

* Post-merge imports fix

* Use canonical command name in examples

---------

Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
2026-04-15 23:41:10 +03:00
Reithan 051346c517 Enable interleaved tool reasoning for custom OpenAI-compat endpoints (#5445)
* enable interleaved tool reasoning for custom OpenAI-compat endpoints

Add chat_completion_sources.CUSTOM to interleaved_reasoning_providers so
that local OpenAI-compatible endpoints (e.g. KoboldCPP in Chat Completions
mode) can forward reasoning context in tool-call chains when the user has
configured Interleaved Thinking.

Also expose the Interleaved Thinking UI control for the Custom source so
users can actually opt in — previously the dropdown was hidden behind a
data-source="openrouter" guard.

The custom streaming path already correctly accumulates delta.reasoning_content
from streaming chunks; this change only removes the provider gate that was
silently discarding that data before it reached the API payload.

* don't override invocation reasoning with prior-turn assistant reasoning

When an invocation already has its own reasoning captured at execution
time, preserve it instead of replacing it with previousAssistantReasoning
from the backward scan. The override was correct when invocations never
carried their own reasoning, but now that the custom/openrouter paths
capture per-invocation reasoning, the unconditional replacement caused
all tool calls in a chain to receive the same stale reasoning from an
earlier unrelated assistant turn.

Fall back to previousAssistantReasoning only when clone.reasoning is empty.
2026-04-15 23:16:39 +03:00
CasualAutopsy af7bd65f42 Impersonate with last_input_sequence (#5456) 2026-04-15 22:43:41 +03:00
Copilot 78628f7dbb Integrate Cloudflare Workers AI text-to-image into SD extension (#5434)
* feat: integrate Cloudflare Workers AI for text-to-image generation in SD extension

Agent-Logs-Url: https://github.com/SillyTavern/SillyTavern/sessions/efc79e4d-2119-4cdb-8afb-f26e318a38ef

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

* fix: address review - use oai_settings for account ID, sort dropdown alphabetically, remove Account ID input, move debug log

Agent-Logs-Url: https://github.com/SillyTavern/SillyTavern/sessions/bf0dda38-df40-44f4-8a63-0c952b48905d

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

* Clean-up diffs

* feat: add refresh models button to Workers AI section

Agent-Logs-Url: https://github.com/SillyTavern/SillyTavern/sessions/ab6b5e7a-84d2-44d1-9f6e-3d330de04ef1

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

* fix: revert unrelated package-lock.json changes

Agent-Logs-Url: https://github.com/SillyTavern/SillyTavern/sessions/ab6b5e7a-84d2-44d1-9f6e-3d330de04ef1

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

* Fix models loading

* refactor: update model refresh button ID and add class to select elements

* Send formData to BFL models

* fix: adjust use FormData condition

* fix: validate Workers AI account ID before proceeding with image model loading

---------

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 22:00:08 +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 d72f4b6fcb Emit PERSONA_CREATED event on persona duplication (#5448)
* feat: emit PERSONA_CREATED event when duplicating a persona

Adds PERSONA_CREATED event emission in duplicatePersona() to notify listeners when a persona is duplicated. Includes the new avatarId, name, and duplicatedFromAvatarId in the event payload.

* fix: event data and execution order

---------

Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
2026-04-14 00:19:02 +03:00
Wolfsblvt 737cb95adb Add clean extension lifecycle hook for optional data cleanup (#5449)
* Add 'clean' extension hook support with optional cleanup on delete

- Add hasExtensionHook() helper to check if an extension defines a specific manifest hook
- Add 'clean' hook type to callExtensionHook() JSDoc
- Add clean button to extension UI when 'clean' hook is present
- Add onCleanClick() handler to run clean hook with confirmation
- Add cleanExtension() function to execute clean hook and reload page
- Modify deleteExtension() to optionally run clean hook before deletion
- Show cleanup checkbox on extension delete popup

* fix lint

Remove unused `callGenericPopup` import from extensions.js

* Force save settings before page reload in extension clean and delete operations

Add explicit saveSettings() calls in cleanExtension() and deleteExtension() to prevent race conditions where clean/delete hooks might update settings that get lost during the subsequent page reload.

* Remove admin permission check from extension clean operation

The clean hook is extension-defined and may not require admin privileges. Permission checks should be handled by the extension's clean hook implementation if needed, rather than enforcing a blanket restriction at the UI level.

* fix: show clean button for built-ins

* Update hasExtensionHook to support built-in extensions

* Revert "Update hasExtensionHook to support built-in extensions"

This reverts commit 31be55ea66430ffe6a8d149d519b3d6d149da9ea.

* Revert "fix: show clean button for built-ins"

This reverts commit 5f86fec70c2b7d5cd99e4dee7f14af5a3372d58f.

---------

Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
2026-04-14 00:18:43 +03:00
Reithan 1a561f3bb0 KoboldCpp: Allow grammar to keep place during continue (#5444)
* allow grammar to keep place during continue

* lint

* fix: require kai flag for grammar to be set

* fix: don't retain if grammar is empty

* fix: default to undefined if not retain

---------

Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
2026-04-13 20:57:47 +03:00
Wolfsblvt f4f390f325 Fix: Missing signature and toolSignatures fields in ChatCompletionService streaming state (#5439)
* Fix: Add signature and toolSignatures fields to ChatCompletionService streaming state object

* fix: pass images array to getStreamingReply

---------

Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
2026-04-13 20:19:02 +03:00
Wolfsblvt 6a325d2b22 Add disabled property support to all popup input types (#5441)
Adds optional `disabled` boolean property to PopupInputConfiguration JSDoc and implements it across all input types (checkbox, text, textarea, number). When set to true, the input element will be rendered in a disabled state.
2026-04-13 19:39:16 +03:00
Wolfsblvt a7f144f28b feat: add getExtensionManifest() to extensions.js and expose via getContext() (#5442)
Returns a structuredClone of the loaded manifest for the given extension name.
Accepts either the short name or full internal key (third-party/...).
Returns null if the extension is not registered.
2026-04-13 19:27:56 +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
Copilot ff10249ab5 Add configurable welcome screen recent chats, fix pin loss on rename, and add popup number input validation (#5436)
* Add configurable recent chats settings and fix pin loss on chat rename

- Add gear icon button to welcome screen header for settings
- Settings popup with Max recent chats (default: 15) and Collapsed recent chats (default: 3) options
- Settings stored in accountStorage as 'recentChatsSettings'
- Add PinnedChatsManager.rename() to migrate pin state when chats are renamed
- Call rename() from both character and group chat rename functions

Agent-Logs-Url: https://github.com/SillyTavern/SillyTavern/sessions/99fa84c4-a82b-4253-96ff-a0621fb63f5c

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

* Fix pin rename: use file_name with .jsonl extension to match stored pin keys

The data-file attribute contains chat_name (without .jsonl), but PinnedChatsManager
stores keys using file_name (with .jsonl). Append .jsonl to both old and new names
when calling PinnedChatsManager.rename() in character and group chat rename functions.

Agent-Logs-Url: https://github.com/SillyTavern/SillyTavern/sessions/c8e4f720-1d0b-49ef-b57b-ba9d85c42d4f

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

* Refactor to support number inputs

* Restore package-lock

* Use clamp() from utils.js instead of manual Math.min/Math.max

Agent-Logs-Url: https://github.com/SillyTavern/SillyTavern/sessions/1669884c-1bd3-4b60-808d-5610f24838e6

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

* Revert unintended package-lock.json changes

Agent-Logs-Url: https://github.com/SillyTavern/SillyTavern/sessions/1669884c-1bd3-4b60-808d-5610f24838e6

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

* Use input values instead of magic numbers

* Add auto-clamping on number inputs in popups and range placeholders in welcome-screen settings

Agent-Logs-Url: https://github.com/SillyTavern/SillyTavern/sessions/9af8ad07-77bc-46db-9ec6-0030fecf0f8d

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

* Use constants for min/max chat limits to avoid hardcoded duplication in tooltips

Agent-Logs-Url: https://github.com/SillyTavern/SillyTavern/sessions/9af8ad07-77bc-46db-9ec6-0030fecf0f8d

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

* Improve input validation by using Number.isFinite for min/max values in Popup class

---------

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-10 21:30:43 +03:00
Copilot 64e8c8d964 Refactor repetitive vectorization model loading into a generic data-driven function (#5425)
* refactor: replace 12 individual load/populate functions with generic loadRemoteEmbeddingModels

Replaced 6 pairs of load+populate functions (Chutes, NanoGPT, ElectronHub,
OpenRouter, SiliconFlow, WorkersAI) with a single data-driven generic
function and a configuration map, following the pattern used by the
caption extension's processEndpoint helper.

Agent-Logs-Url: https://github.com/SillyTavern/SillyTavern/sessions/29bd42f8-b35b-442f-91fe-bd6c1092436e

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

* address review: always include body, use typeof check, remove omitContentType

Agent-Logs-Url: https://github.com/SillyTavern/SillyTavern/sessions/ccfc6ba8-57fd-4411-8e12-106b5e11be86

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-09 23:50:32 +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
Wolfsblvt fb915b4321 Add /regex-state slash command to check regex script status (#5428)
* feat: add /regex-state command to check script enabled status

Adds a new slash command that returns 'on' or 'off' to indicate whether a regex script is currently enabled or disabled.

* refactor: change /regex-state return values from 'on'/'off' to 'true'/'false'

Updates the /regex-state slash command to return boolean string values ('true'/'false') instead of ('on'/'off') for better consistency with standard boolean conventions.
2026-04-09 23:27:36 +03:00
Alex Dills fa9a28c6f3 Fix stable-diffusion.cpp model routing and URL path handling (#5427)
* fix: include model field in sd.cpp SDAPI requests and preserve URL path

The sd.cpp integration overwrites the URL pathname when constructing
requests, which breaks proxy servers like llama-swap that use path-based
routing (e.g. /upstream/model-name). Additionally, the model field was
never included in SDAPI requests, which is required by llama-swap to
route requests to the correct backend.

Changes:
- Server: Append to URL pathname instead of overwriting (same pattern as #5178)
- Server: Pass model field through to sd-server payload
- Client: Add model name text input for sd.cpp source settings
- Client: Send model name in generate request payload

* fix: fetch models from server and populate standard Model dropdown

Instead of a separate text input for the model name, fetch the model
list from the sd.cpp server's /v1/models endpoint and populate the
standard Model dropdown. This provides a seamless experience where
users just pick a model from the dropdown like any other source.

Works with both standalone sd-server and proxy servers like llama-swap
that expose multiple models via the OpenAI-compatible models endpoint.

* fix: don't send clip_skip=1 to sd.cpp, it produces blank images

sd-server generates blank white images when clip_skip is set to 1.
Since clip_skip=1 means 'use all CLIP layers' (the default behavior),
only send the parameter when it's > 1.

* Fix eslint

* Replace string appends with urlJoin

* fix: convert URL strings to URL objects in sdcpp routes

---------

Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
2026-04-09 23:12:21 +03:00
Wolfsblvt ff4c6fa1bb chore: add arguments logging to deprecated MacrosParser method warnings (#5429)
Extends the #logDeprecated helper to accept and log the arguments passed to deprecated methods, providing better debugging context for migration. Updates all deprecated method calls (get, has, registerMacro, unregisterMacro) to forward their arguments to the deprecation logger.
2026-04-09 22:33:54 +03:00
Wolfsblvt 81c85f8049 fix: skip pseudo-elements when generating focus-visible styles (#5430)
Prevents invalid CSS by skipping rules containing `::` (pseudo-elements like `::before`, `::after`, `::-webkit-scrollbar`) when converting `:hover` to `:focus-visible`, as pseudo-elements cannot receive focus.
2026-04-09 22:28:39 +03:00
Wolfsblvt 67eba1b472 fix: treat all English locale variants as supported fallback language (#5431)
Previously only exact 'en' was accepted as fallback when a language wasn't found. Now accepts any English variant (en-US, en-AU, etc.) to prevent spurious warnings for valid English locales.
2026-04-09 22:24:29 +03:00
Wolfsblvt df27574247 Fix: Remove unused ComfyUI RunPod API key input mapping (#5432) 2026-04-09 22:20:34 +03:00
Tony Gies a9c377c3c8 feat: add Workers AI text embeddings and multimodal captioning (#5414)
* feat: add Workers AI text embeddings and multimodal captioning

Extends the Cloudflare Workers AI integration to the vectors and
caption extensions.

Embeddings: adds workers_ai source to the vectors extension using the
OpenAI-compatible /v1/embeddings endpoint, with dynamic model listing
from the Cloudflare model search API.

Captioning: adds workers_ai as a multimodal caption API with dynamic
vision model discovery via the multimodal-models endpoint.

* Add logo svg

* Refactor caption dropdown population

* Fix order of sources

* feat: add error handling for missing Workers AI account ID

---------

Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
2026-04-08 23:43:21 +03:00
bumprat 94a5773412 refactor(tts): remove redundant 4-space codeblock filter (#5406)
* refactor(tts): remove redundant 4-space codeblock filter

- Deleted the regex that removed lines starting with four spaces.
- Original intent was to strip "indented code blocks" (Markdown legacy syntax).
- In practice, SillyTavern already handles explicit code fences (```...``` and ~~~...~~~).
- Indented code blocks are rarely used and the regex caused unnecessary text loss in normal messages.
- Simplifies codeblock skipping logic and avoids accidental removal of valid content.

* Remove commented out code

---------

Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
2026-04-08 22:11:21 +03:00
Wolfsblvt 5e68410d4e Add Entry Preview to World Info Deletion Confirmation Dialog (#5423)
* feat: add entry preview to world info deletion confirmation dialog

Displays entry comment or first two lines of content in the deletion confirmation popup to help users verify they're deleting the correct entry.

* fix: sanitize world info entry preview text in deletion confirmation dialog

Adds DOMPurify sanitization to the entry preview text displayed in the deletion confirmation popup to prevent potential XSS vulnerabilities from unsanitized user content.

* DOMPurify -> escapeHtml

---------

Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
2026-04-08 20:31:00 +03:00
Tony Gies 700fc05411 feat: add Cloudflare Workers AI provider (#5385)
* feat: add Cloudflare Workers AI provider

Adds support for Cloudflare Workers AI using its OpenAI-compatible API.

Workers AI-specific stuff includes:
- Model list fetching and capabilities detection
- Tokenizer auto-detection for typical hosted model families
- Streaming not supported when using structured output

Closes #5305

* Make the entire header clickable

* Add missing samplers

* Fix non-streaming reasoning parsing

---------

Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
2026-04-06 00:24:47 +03:00
Tony Gies 128888f605 Skip TTS for voices explicitly set to disabled (fixes #4970) (#5367)
* Skip TTS for voices explicitly set to disabled (fixes #4970)

* Always show disabled message in commands and fix restoring voice map UI

* Always show a message on manual TTS trigger

* Fix null current job on disabled

* Adjust type annotation

* Force update worker when disabled play is attempted

* Treat audio control queue as manual

* Update TTS message processing to include manual flag

* Don't show toast if was already shown by manual playback

---------

Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
2026-04-05 20:25:26 +03:00
Cohee 8e8f501279 Immutable public and global content management (#5390)
* Use custom init script instead of postinstall

* Revert changes to start scripts in src\electron

* Add global data to content manager

* Add migration for public overrides and user.css location update

* Update npm publish workflow to use 'omit=dev' flag in npm ci commands

* Rename user.css readme file

* Fix indentation in userCssMiddleware function

* Add directory creation for content target

* Restore template compile location

* Move stylesheet up in index.json

* Use path.resolve for user.css file path in userCssMiddleware

* Correct capitalization in "Not Found" error page title and heading

* Remove init run from startup scripts

* Simplify user CSS file path resolution

* Update userCssMiddleware comment
2026-04-05 19:32:28 +03:00
Cohee 21e8cf9060 glm-5v-turbo (#5393)
* glm-5v-turbo

* Add support for image and video inlining
2026-04-02 20:19:01 +03:00
Cohee 04ef0632ee Save chat before emitting event for user message (#5389)
Fixes #5388
2026-04-01 23:19:56 +03:00
Cohee d2b2b1b4a6 fix: require long press to open swipe picker on phones (#5382)
* fix: require long press to open swipe picker on phones

* fix: clarify parameter description in assignLorebookToChat function

* fix: update event parameter type in onSwipeCounterClick to include TouchEvent

* fix: update event parameter types in onSwipeCounterClick and addLongPressEvent
2026-03-31 20:08: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
Copilot 63feac9423 feat: swipe picker expand/collapse, copy button, and left-align text (#5380)
* Initial plan

* feat: add expand/collapse, copy button, and left-align text in swipe picker

Addresses user feedback for swipe picker (added in 1.17.0):
1. Left-align swipe text (was inheriting centered alignment)
2. Add expand/collapse toggle using hidden checkbox + CSS :has
3. Add copy-to-clipboard button using shared copyText utility

Agent-Logs-Url: https://github.com/SillyTavern/SillyTavern/sessions/90892f1c-3c75-404b-a93b-2abe672cc0e3

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

* revert unintended package-lock.json changes from npm install

Agent-Logs-Url: https://github.com/SillyTavern/SillyTavern/sessions/90892f1c-3c75-404b-a93b-2abe672cc0e3

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

* fix: address review feedback - hide checkbox, use chevron icons, align buttons with fa-fw

- Fix checkbox visibility by using !important to override input[type=checkbox] grid display
- Change expand icon to fa-chevron-down and collapse to fa-chevron-up
- Add fa-fw class to all action buttons (copy, expand/collapse, branch, delete) for even sizing
- Add align-items: baseline to the actions container

Agent-Logs-Url: https://github.com/SillyTavern/SillyTavern/sessions/c8ca349f-3579-442a-baa1-fc138ba1d7a6

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

* revert unintended package-lock.json changes

Agent-Logs-Url: https://github.com/SillyTavern/SillyTavern/sessions/c8ca349f-3579-442a-baa1-fc138ba1d7a6

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

* fix: update class names for chat action elements in swipe picker

* fix: prevent chevron layout shift and swap button order

- Use single label element as icon (fa-chevron-down) instead of two
  child <i> elements toggling visibility, preventing layout shift
- Override ::before content to chevron-up when expanded via CSS
- Swap chevron and copy button order (chevron first, then copy)

Agent-Logs-Url: https://github.com/SillyTavern/SillyTavern/sessions/284283b1-6c7f-4371-bc4a-94d841513879

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

* style: add comment for FA unicode value in CSS

Agent-Logs-Url: https://github.com/SillyTavern/SillyTavern/sessions/284283b1-6c7f-4371-bc4a-94d841513879

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

* Rotate the chevron instead of changing content

* Make the ui full height

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Cohee1207 <18619528+Cohee1207@users.noreply.github.com>
2026-03-31 00:41:03 +03:00
Copilot c918f4f36d Add opt-in toggle to keep hidden messages in chat vector index (#5378)
* Initial plan

* Add opt-in toggle to keep hidden messages in chat vector index

Agent-Logs-Url: https://github.com/SillyTavern/SillyTavern/sessions/eadc80a1-a417-40df-a374-76d7c4a46ce3

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

* Revert package-lock changes

* Fix: Remove 'vectorized' class from chat messages before adding it

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Cohee1207 <18619528+Cohee1207@users.noreply.github.com>
2026-03-30 23:39:19 +03:00
Xiangzhe b89293418d fix: return Error objects from invokeFunctionTool and create error invocations (#5351)
* 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.

Changes:
- Return Error objects directly from invokeFunctionTool
- Create error invocations with error: true flag when tools fail
- Record failed stealth tools in stealthCalls
- Preserve signature/reasoning on error invocations
- Add error field to ToolInvocation typedef

* fix: use Error.toString to avoid behavioral changes

---------

Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
2026-03-30 23:26:48 +03:00
lunar sheep ff1ca1412a feat(secrets): update readSecret function to accept optional secret ID (#5356)
* feat(secrets): update readSecret function to accept optional secret ID

* add secret_id to ConnectionManagerRequestService payload

* fix: pass secret_id for Text Completion types

---------

Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
2026-03-30 22:30:45 +03:00
Cohee bef7b39cbe Add glm-5.1 to models list (#5361) 2026-03-28 02:08:28 +02:00
Cohee c78f978ede fix: conditionally include secrets in user data backup (#5360)
* fix: conditionally include secrets in user data backup

* feat: add full data backup toggle

* 418 -> 403
I'm not a teapot

* Distinguish fails from disabled
2026-03-28 01:52:03 +02: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
SoniaNvm a794a3780a Renaming a lorebook now re-links itself to cards using it (with a confirmation prompt) (#5323)
* renaming a lorebook prompts to update existing links

* used suggested api and logic

* add world property to shallow function

* Fix type error in assignLorebookToChat invoke

* Remove debug console logs

* Fix activeCharacterUpdated

* Extract updateWorldInfoLinks into a func

* Invert if for an early return

---------

Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
2026-03-24 23:48:43 +02:00