11718 Commits

Author SHA1 Message Date
Cohee 51ad27fb86 Merge pull request #5591 from SillyTavern/staging
Create Docker Image (Release and Staging) / build (push) Waiting to run
🔄 Update Issues on Push / 🔗 Mark Linked Issues Done on Push (push) Waiting to run
⚔️ Check Merge Conflicts / ⚔️ Check Merge Conflicts (push) Waiting to run
Staging
2026-05-03 18:45:46 +03:00
Cohee 982dfec022 Update release version number (#5590) 2026-05-03 18:44:24 +03:00
Forkoz 95ca4315bd Add encode_special_tokens to tokenizers.js (#5589) 2026-05-03 18:39:36 +03:00
Cohee 97392a4ca0 Refactor extension management and assets download menu (#5583)
* feat: refactor extension and asset management

* feat: refactor name selector

* fix: make text localizable

* fix: handle abort errors in extension version checks

* fix: replace returns with throws

* fix: remove debug prefix from toast

* fix: preserve file names of imported characters
2026-05-02 20:01:44 +03:00
Cohee e5ae782705 Add option to return malformed JSON string from extractJsonFromData (#5578)
* feat: add option to return malformed JSON string from extractJsonFromData
Fixes #5569

* fix: add fallback for Perplexity case
2026-05-02 18:31:06 +03:00
Cohee 9d61bbc3ed fix: npm audit package dependencies (#5572) 2026-05-02 17:41:39 +03:00
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
Cohee c325c6d8e9 Add account version tags to cookies (#5563)
* feat: add user account version to session cookie

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

* feat: include user handle in account version hash calculation

* feat: refactor recovery code generation to use a dedicated function

* fix: don't overwrite current session version if updating another user

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

* fix: reset session version instead of nullifying the entire session

* fix: short circuit and clear cookie on request invalidation

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

* fix: update account version on recovery

---------

Co-authored-by: Copilot <copilot@github.com>
2026-05-02 17:07:57 +03:00
Leandro Jofré 91c40280ed Update/Turn expression-set-fallback into expression-fallback (#5564)
* Update - Turn expression-set-fallback into expression-fallback
Make the extension a getter and setter instead of a setter only.

* Update - Rewrite the help string and add usage examples

* Fix - Remove the alias
2026-05-01 17:04:49 +03:00
Cohee b2fa6a0afb Add rate limit to basic auth middleware (#5504)
* feat: add rate limiting to basic auth flow

* fix: round up retry-after duration

* feat: enhance point consume logic

* fix: move unauthorized webpage reading inside response function

* refactor: move getIpAddress to express-common

* fix: check for rate limit before checking creds

* fix: use correct rate limit pattern in /recover-step2

* feat: handle CF forwarded IP header in rate limit, whitelist and access logger

* feat: add individual config toggles for forwarded headers

* feat: enhance IP address retrieval to include forwarded IP for access logging

* chore: clean-up diff

* fix: don't consume points for missing credentials

* feat: log rate limited method and URL

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

* feat: make rate limiter points configurable

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

* feat: implement retry-after header for rate limiting responses

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

---------

Co-authored-by: Copilot <copilot@github.com>
2026-05-01 00:09:24 +03:00
DeathStalker471 4ca9863f38 feat: add nanogpt provider selection (#5544)
* add nanogpt provider selection

* update payg text

* fix: resync providers from endpoint

---------

Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
2026-04-30 23:55:42 +03:00
Leandro Jofré 3a9c10d680 Feat - Add expression-set-fallback slash command (#5551)
* Feat - Add expression-set-fallback slash command

* Fix ESLint

* Fix - Use proper name convention for slash command method

* Fix - Change misleading expression-set-fallback help string label

* Fix - Use normal description for expression label argument

* Update - Make expression-set-fallback case unsensitive
Also fixed array creation by removing the spread syntax and added warning.
2026-04-30 23:41:04 +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 45f2951854 fix: temperature -> maxTemperature (#5554) 2026-04-29 03:26:27 +03:00
.:bubfix:. 44f433d10b Minor adjustments to the SVG icons. (#5546)
- Created an SVG version of the SillyTavern logo
- The modified images are 4 times smaller (-43.7 KiB), with no visible loss in quality
2026-04-29 01:34:52 +03:00
Cohee 08e1ce8ec5 Merge pull request #5549 from SillyTavern/release
Backmerge release into staging
2026-04-28 19:16:00 +03:00
Cohee aa50edcf45 fix: update backup archive to ignore migration secrets files (#5548) 2026-04-28 19:14:54 +03:00
Cohee 2e4ca3dabf fix: improve sanitation of toasts that bypass HTML escaping (#5540)
* fix: improve sanitation of toasts that bypass HTML escaping

* fix: replace absolute lib.js import with relative

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

---------

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-04-28 01:00:31 +03:00
.:bubfix:. bd9479fef8 Better SVG for Kobold/KoboldCpp (#5543)
- 23 times smaller than the original.
- This time with genuine transparency.
2026-04-28 00:18:47 +03:00
crsp6447 940b3722cf Fix: Prevent crash in cachingAtDepthForOpenRouterClaude on empty content from trailing tool calls (#5541)
* Prevent crash in cachingAtDepthForOpenRouterClaude when message has no text

* Apply optional chaining suggestion
2026-04-27 23:53:14 +03:00
Cohee 338119ab77 Implement private IP range request host validator (#5497)
* feat: implement private IP range request host validator for server-side HTTP requests

* feat: add link-local address support

* fix: use correct config keys

* fix: if config missing use default loopback addresses

* fix: re-use resolved address for connection

* test: add unit coverage for private request filter and proxy interaction

Agent-Logs-Url: https://github.com/SillyTavern/SillyTavern/sessions/1813593e-2263-45e2-aa53-74d39515f1df

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

* test: remove request-proxy.test.js

* perf: cache resolved matches

* fix: remove unused import

* fix: use proper ipv4 loopback cidr

* fix: correct raiseError comment

* test: uses tls.connect for secure endpoints

* Implement private IP range request host validator

Agent-Logs-Url: https://github.com/SillyTavern/SillyTavern/sessions/e76ba122-136e-43ad-b4bc-ea48a01fcdda

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

* Revert "Implement private IP range request host validator"

This reverts commit 14e271470227b485b7d23caac31a237abf9f7835.

* fix: close request without sending status in CORS forwarding when headers were sent

* fix: not enabled -> disabled

* feat: add enableKeepAlive option to PrivateRequestAgent

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

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: anthropic-code-agent[bot] <242468646+Claude@users.noreply.github.com>
Co-authored-by: Copilot <copilot@github.com>
2026-04-27 01:51:18 +03:00
Wolfsblvt 1bb2a5ea19 Fix missing filename sanitization on V2 JSON character import + harden getPngName as safety nee (#5538)
* fix: sanitize character filenames on V2 JSON import and harden getPngName

- Add missing sanitize() call in importFromJson V2 spec branch to match all other import paths
- Sanitize data.name before readFromV2() so the name field sync happens automatically
- Add sanitize() as defense-in-depth inside getPngName() to catch future oversights
- Refactor getPngName() to use getUniqueName() utility for consistent name generation

* fix: sanitize data.name before readFromV2 in importFromPng and importFromCharX

Same bug as importFromJson: readFromV2() overwrites the top-level name
with the unsanitized data.name, undoing any prior sanitize() call.
Fix by sanitizing data.name before readFromV2 so the sync preserves it.

* fix: sanitize top-level name field in JSON and CharX import paths

* fix: incorrect path rejection in isPathUnderParent

* fix: increase maxTries in getPngName

---------

Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
2026-04-27 01:13:19 +03:00
DeathStalker471 7201d87f2e feat: Add NanoGPT credit stats UI (#5537)
* Add NanoGPT credit stats UI

* fix lint

* fix: type check

* fix: migrate inline styles to css

* feat: add sub active date display

* feat: add link to balance page

---------

Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
2026-04-27 00:13:06 +03:00
DeathStalker471 d327412e29 Chat Completion: common model sorting and grouping settings, improved NanoGPT model list (#5536)
* Improve NanoGPT Model List

* Update token multiplier condition to !== 1 to support showing discounts

* Add Model Sorting

* rework sorting to be more compact

* feat: combine CC model sorting/grouping settings

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

* fix: adjust migration logic

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

* feat: implement grouping for Chutes

* fix: apply review suggestions

* fix: call reconnect instead of direct status check

---------

Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
Co-authored-by: Copilot <copilot@github.com>
2026-04-26 23:25:56 +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
Cohee 25fb4ceb50 fix: remove legacy filter state restoration (#5535) 2026-04-26 21:06:54 +03:00
Cohee c249e5384c feat: pass koboldcpp reasoning effort (#5491)
Fixes #5489
2026-04-26 00:02:07 +03:00
Cohee 09d72828cb feat: add gemma 4 for AI studio (#5493)
* feat: add gemma 4 for AI studio

* fix: update max context return value for gemma-3n-e4b-it model

* refactor: iterate array of [regex, number]

* gemma4: enable tool calling and sysprompt

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

---------

Co-authored-by: Copilot <copilot@github.com>
2026-04-25 22:22:55 +03:00
Cohee 09bb7622ed OpenAI: Add gpt-5.5, gpt-5.4-mini/nano, gpt-image-2 (#5529)
* feat: gpt-image-2 for OpenAI image generation

* gpt-5.5

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

* fix: adjust reasoning effort mapping

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

* fix: html format

---------

Co-authored-by: Copilot <copilot@github.com>
2026-04-25 21:46:52 +03:00
Copilot 7948886c1d Add Tool Call Recurse Limit slider to Chat Completion settings (#5518)
* feat: add Tool Call Recurse Limit slider to Chat/Message Handling settings

Agent-Logs-Url: https://github.com/SillyTavern/SillyTavern/sessions/ecbde89f-8f4d-4e91-9189-a998d12ca76b

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

* feat: move tool call recurse limit to openai_settings under Chat Completion settings

Agent-Logs-Url: https://github.com/SillyTavern/SillyTavern/sessions/132e4c28-9564-47cd-92c1-e8ab50d88905

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

* refactor: use CSS :has() selector instead of JS toggle for tool_call_recurse_limit_block visibility

Agent-Logs-Url: https://github.com/SillyTavern/SillyTavern/sessions/c562deb5-05ce-4ebf-84a0-9eeea9d24433

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

* fix: wrap tool_call_recurse_limit_block in range-block for correct layout

Agent-Logs-Url: https://github.com/SillyTavern/SillyTavern/sessions/4d25a367-ac12-4e54-83b0-1543eb6f370a

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

* fix: data-i18n attribute

---------

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-25 21:05:39 +03:00
feg 0a493cad89 add macro support for image caption extension prompt (multimodal) (#5527)
* added macro processing to caption ext

added
`prompt = substituteParamsExtended(prompt);`
to the captionmultimodal function
(so it can use macros and stuff)

* caption ext updated from old substituteparams

* removed comment
2026-04-25 20:14:45 +03:00
Christoph 29e3136473 fix: Don't apply layout hack in Firefox Mobile while editing text (#5531)
This fixes the following bug in Firefox Mobile on Android:

**Steps to reproduce:**

1. Swipe a word into the chat input edit field in Firefox Mobile on Android, for examples "Test".
2. In GBoard (default Android keyboard), tap on a different suggestion, for examples "Rest".

**Expected behavior:** The word "Test" is replaced with "Rest".

**Actual behavior:** The word becomes "TestRest".

I confirmed with bisecting that the commit f897a4ab1a introduced the issue.

This change fixes the issue by disabling the layout hack while editing text.
Disabling the layout hack is limited to Firefox Mobile because

* I could not reproduce the bug in Chrome on Android
* This way, if it causes a new bug, only Firefox Mobile users are affected
2026-04-25 19:56:52 +03:00
DeathStalker471 b1ef254f78 fix: disable HTTP keepAlive (Node 18 behavior) with a config toggle (#5519)
* implement disable keepalive, handle request-proxy and config logic

* Invert keep-alive boolean setting

* fix: clean-up server.js diff

* fix: boolean flag type

* feat: disable keep-alive by default

---------

Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
2026-04-24 22:53:35 +03:00
Dclef 77cbcd8774 feat: add DeepSeek V4 model support with thinking mode and reasoning effort (#5522)
* fix: align DeepSeek provider with V4 API

* Fix DeepSeek beta routing for standard chat completions

* feat: add DeepSeek V4 model support with thinking mode and reasoning effort

* Address DeepSeek review feedback

* Set DeepSeek default model to v4 flash

* fix: clean-up deprecated models, add migration

* fix: move reasoning effort mapping to resolveReasoningEffort

* fix: lint empty line

* fix: remove duplicate code

* fix: add coder model to migration logic

---------

Co-authored-by: dclef <drclef233@gmail.com>
Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
2026-04-24 21:47:30 +03:00
Octopus aecbb9a2ee feat: add MiniMax as a chat completion provider (#5452)
* feat: add MiniMax as a chat completion provider

Add MiniMax (https://www.minimax.io) as a first-class chat completion
provider. MiniMax already has TTS integration in SillyTavern; this
extends support to LLM chat completions via their OpenAI-compatible API.

Supported models:
- MiniMax-M2.5 (default) — 204K context
- MiniMax-M2.5-highspeed — same capability, faster inference

Key implementation details:
- Reuses existing SECRET_KEYS.MINIMAX (shared with TTS)
- API endpoint: https://api.minimax.io/v1
- Temperature clamped to (0.0, 1.0] as required by MiniMax API
- Returns hardcoded model list since MiniMax doesn't expose /v1/models
- Full UI integration: model selector, sampler parameters, streaming

Co-Authored-By: octo-patch <octo-patch@users.noreply.github.com>

* feat: upgrade MiniMax default model to M2.7

- Add MiniMax-M2.7 and MiniMax-M2.7-highspeed to model list
- Set MiniMax-M2.7 as default model
- Keep all previous models as alternatives

* feat: independent request function, vision support, temp clamping for MiniMax

- Extract sendMinimaxRequest() following Chutes pattern (PR #4844)
  with function calling and JSON Schema structured output support
- Clamp temperature to (0.01, 1.0] on backend; limit frontend UI max to 1.0
- Enable image inlining for MiniMax M2.7 model
- Add MiniMax to slash-commands model selector and tokenizer mapping
- Add minimax_model to default preset

* feat: add VLM-based vision support for MiniMax M2.7

M2.7 does not natively accept image input. When images are detected
in messages, pre-process them via the MiniMax VLM endpoint
(/v1/coding_plan/vlm) to convert images to text descriptions before
sending to the chat completions API. Uses the same API key.

* feat: add M2-her model to MiniMax provider

M2-her is MiniMax's dialogue/roleplay-optimized model with 64K context
and 2048 max completion tokens. Text-only (no vision).

* feat: add MiniMax China endpoint (minimaxi.com) support

Add endpoint selector (Global/China) for MiniMax, mirroring the
SiliconFlow pattern. Users can now choose between api.minimax.io
(international) and api.minimaxi.com (China domestic).

* fix: merge consecutive same-role messages for MiniMax

MiniMax API rejects consecutive messages with the same role with
error 'invalid chat setting (2013)'. Merge them before sending.

* review: address PR feedback on MiniMax provider

Backend (src/endpoints/backends/chat-completions.js):
- Drop the entire MiniMax VLM image-preprocessing path; vision is no
  longer advertised for this provider, so M2.7 messages now go straight
  to /chat/completions without a separate VLM round-trip.
- Drop the json_schema -> response_format mapping (MiniMax does not
  document structured-output support; relying on it was speculative).
- Drop the backend temperature clamp; the same clamp now lives in the
  frontend so the wire payload matches what the user sees.
- Drop the MINIMAX branch in /status that returned a hard-coded model
  list; the frontend hardcodes the same list and bypasses /status via
  noValidateSources, so the round-trip was wasted.
- Add a streaming Transform + non-streaming helper that move
  <think>...</think> blocks from delta.content / message.content to
  reasoning_content. MiniMax M2.x emit chain-of-thought inline in
  content; without this transform the raw <think> tags leak into the
  rendered chat. Includes a state machine that holds back partial
  marker bytes so a marker split across SSE chunks is still detected.

Frontend:
- public/scripts/openai.js: add MINIMAX to noValidateSources so the key
  is accepted without a /models call; remove the dead saveModelList
  branch; clamp temperature to (0.0, 1.0] in createGenerationParameters.
- public/scripts/reasoning.js: add MINIMAX to the non-streaming
  reasoning_content extraction case (the backend transform now produces
  this field for MiniMax responses).
- public/scripts/slash-commands.js: add MINIMAX to the /api enum and
  add a MiniMax case to /api-url so users can switch endpoint by
  command.
- public/scripts/custom-request.js: pass minimax_endpoint through the
  override-payload merge alongside the other per-source endpoint fields.
- public/scripts/tokenizers.js: stop returning openai_model (which was
  always a MiniMax model id and thus an unknown tokenizer); fall back
  to gpt-3.5-turbo for a coarse but functional estimate.
- public/scripts/tool-calling.js: add MINIMAX to supportedSources so
  function-calling settings are exposed.
- public/index.html: drop the "-- Connect to the API --" placeholder
  option from the model select (the model list is hardcoded and always
  populated); remove minimax from the vision data-source attributes
  on the inline-media controls.
- public/img/minimax.svg: replace the multicolor brand SVG with a
  single-color currentColor version that matches the other provider
  icons in the connect panel.

* review: drop backend <think> parsing, defer to frontend

Per reviewer feedback: SillyTavern's reasoningHandler / reasoning_auto_parse
setting already extracts <think>...</think> blocks on the client side, so the
backend doesn't need to rewrite MiniMax responses. Removes the SSE Transform,
the non-streaming helper, and the corresponding case in reasoning.js.

* fix: remove isImageInliningSupported declaration for MINIMAX

* fix: remove MINIMAX from stream reasoning parsing

* fix: add to autoconnect logic

* fix: add missing MINIMAX models from docs

* fix: freq. and pres. pen aren't supported for MINIMAX

* fix: use clamp function for adjusting temperature

* fix: pass minimax_endpoint from connection profile to ChatCompletionService

* fix: update supported APIs in slash command documentation

* fix: replace bespoke merge with standard MERGE_TOOLS processing

* fix: add data-i18n attributes for headers

---------

Co-authored-by: octo-patch <octo-patch@users.noreply.github.com>
Co-authored-by: octo-patch <octo-patch@github.com>
Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
2026-04-24 00:43:05 +03:00
Stagnating a028bec87b Display OpenRouter credit balance in UI (#5513)
* Display OpenRouter credit balance in UI

Adds a "View Remaining Credits" click handler that fetches the
current balance from the OpenRouter /credits endpoint via a new
server-side /api/openrouter/credits route, and renders it next
to the link. The anchor still points at openrouter.ai/account
so middle-click / right-click "open in new tab" keeps working.

* Return 500 on OpenRouter credits failure

* Reduce to two decimals

* Update view credits URL

---------

Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
2026-04-23 23:21:28 +03:00
柚柚子 752ae243b9 Fix KoboldCpp vector hash deletion (#5508) 2026-04-23 23:03:59 +03:00
Theros efbff34342 feat: add getWorldInfoNames() to getContext() for WorldInfo enumeration. (#5505) 2026-04-23 11:24:10 +03:00
cloak1505 6d2165149b Sync OpenRouter providers list (#5503) 2026-04-22 22:04:15 +03:00
柚柚子 ff31ca6692 feat: add Adaptive-P controls for oobabooga (#5502)
* feat: add ooba adaptive-p controls

* fix: align ooba adaptive-p sampler order
2026-04-22 21:34:52 +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
TanJeeSchuan e5d4ff5fae Enhance Vectorize All process with error handling, retries and minor improvements (#5479)
* fix (vectors): Fixed Vectorize All progress report and ETA issues

* fix (vectors): Added strip reasoning block function for extras/WebLLM summaries

* feat(vectors): Retry failed summaries with configurable attempts

* feat(vectors): Skip summarization for short messages

* feat(vectors): Skip failed messages during Vectorize All instead of aborting all

Prevents the "Vectorize All" process from stopping on single-message
errors. Failed items are now skipped and reported at the end of the
session rather than aborting the entire sync.

Summarization: Implements per-message retries; failures use the original
text as a fallback or mark for skipping.

Vector Insertion: Differentiates fatal configuration errors (abort) from
transient batch failures (skip and notify).

* Resolved: 'account_id_missing' is missing

* Resolved: Refactored out summarizeSkipOnFailure() functionality into summarize() via options parameter

* Fix eslint and type checks

* feat(vectors): add types to maps and sets, improve summarize function options

---------

Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
2026-04-20 02:33:12 +03:00
Wolfsblvt 8aeda4a101 Add Persona CRUD Slash Commands with Shared Avatar Utilities (#5466)
* Add persona CRUD slash commands with enhanced utilities

- Add `/persona-create`, `/persona-update`, `/persona-delete`, `/persona-duplicate`, and `/persona-get` slash commands for programmatic persona management
- Move `persona_description_positions` enum from power-user.js to personas.js for better encapsulation
- Add position and role parsing utilities (`parsePersonaPosition`, `parsePersonaRole`) with name-to-value mapping
- Extend `initPersona()` to accept optional position, depth, role, and lorebook parameters
- Refactor `deleteUserAvatar()` to delegate to new `deletePersona

* Add NaN validation for descriptionDepth parameter in createPersonaCallback

- Add isNaN() check for depth parameter after Number() conversion
- Display warning toast when invalid depth value is provided
- Fall back to DEFAULT_DEPTH when depth is NaN
- Change depth from const to let to allow reassignment after validation

* Refactor persona lookup to support avatar key targeting and fix enum provider currying

- Refactor `autoSelectPersona()` to accept optional `personaKey` parameter for targeting specific persona when multiple share the same name
- Replace manual persona lookup loops with `findPersona()` helper calls in `autoSelectPersona()` and `setNameCallback()`
- Update `setNameCallback()` to pass both persona name and avatar key to `autoSelectPersona()` for precise targeting
- Refactor `commonEnumProviders.personas()`
2026-04-20 02:26:08 +03:00
Wolfsblvt 15a3e3f072 feat: add click-to-edit support for reasoning blocks and auto-focus reasoning textarea (#5487)
Extend click-to-edit functionality to reasoning blocks in addition to message text. When clicking on a reasoning block, automatically focus the reasoning textarea after entering edit mode.
2026-04-20 02:11:42 +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 d8b3d36a84 Refactor: Replace SD image generation indicator with ActionLoader system (#5472)
* refactor: replace custom generation indicator with action-loader

Remove custom generation tracking (activeGenerations counter, generationToast) and replace with action-loader's non-blocking stoppable toast. Import loader from action-loader.js and use loader.show() with onStop callback in generatePicture() and generateMediaSwipe(). Remove updateGenerationIndicator(), startGenerationTracking(), and endGenerationTracking() functions. Remove manual stop button show/hide logic and generation counter updates

* Remove legacy stop button, add sentinel handler value

* fix: reassign loaderHandle in generateMediaSwipe

* feat: add data attributes to action-loader toast for easier selection

Add loaderId, title, and blocking data attributes to toast content div to enable programmatic identification and filtering of active loader toasts

* Revert "feat: add data attributes to action-loader toast for easier selection"

This reverts commit e8da27b4c94b389d5970a6bea6c7b1c94459b460.

---------

Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
2026-04-20 01:10:20 +03:00
Cohee b8f2b1cfa6 fix: enhance URL validation for Z.AI image generation (#5482)
* fix: enhance URL validation for Z.AI image generation and handle potential delays
Fixes #5480

* fix: retry 404 in a loop

* fix: handle Z.AI image and video unavailability with appropriate warnings and responses
2026-04-20 00:28:55 +03:00
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