docs: add Connection Profile docs, new screenshots, and minor fixes

- Document Connection Profiles as 4th extraction source in providers.md
  with creation steps, settings table, and usage instructions
- Add screenshots: Settings Modal tabs (connection, profile, extraction,
  storage), Connection Profile toolbar bar and creation dialog
- Refresh wizard-step1.png and panel-full.png screenshots
- Document "Protect recent messages" feature in managing-memories.md
- Add Connection Profile mentions to getting-started.md, README.md,
  and architecture.md
- Bump manifest.json version to 2.1.9
- Fix tooltip "Injection Sidebar" → "Injection Viewer" in settings.html
- Add issue #10 per-chat memory storage backlog analysis

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
bal-spec 2026-03-18 21:55:19 -07:00
parent 6cf5e9ee6f
commit cb460e734f
16 changed files with 148 additions and 4 deletions

View file

@ -47,6 +47,7 @@ CharMemory gives your characters persistent memory across chats. Here's the shor
- **Prompt Breakdown** — see exactly where your context window is going. The injection viewer shows a per-category token breakdown (System, Char card, Lorebook, Data Bank, Examples, Chat history) with a stacked bar and actionable tips for reducing usage.
- **Vector Storage health checks** — a traffic-light indicator flags misconfigured settings and tells you what to fix, so you're not guessing why memories aren't showing up.
- **Full memory control** — browse, edit, or delete individual memories with a unified block editor (inline editing, undo, find/replace). Consolidate duplicates with preview and undo. Batch-extract from all chats at once.
- **Flexible LLM connections** — use a dedicated API provider, reuse an existing SillyTavern Connection Profile, run a local model via WebLLM, or piggyback on your main chat LLM.
- **Highly configurable extraction prompts** — separate prompts for 1:1 and group chats and memory file consolidation and conversion.
- **Guided setup** — the Setup Wizard tests your LLM connection, checks Vector Storage, and handles existing memory file conversion in about 2 minutes.
- **Tablet & phone support** — on touch devices, the dashboard opens as a floating panel with touch-friendly controls. Phone layout widens drawers for small screens. If auto-detection doesn't match your device, override it in Settings > Advanced > Display Mode. Please [report issues on GitHub](https://github.com/bal-spec/sillytavern-character-memory/issues) with how it behaves on your device.

View file

@ -118,7 +118,7 @@ New message arrives
→ At generation time, VS retrieves relevant chunks and injects them into the prompt
```
`callLLM()` (line ~2265) is the **single dispatch point** for all LLM calls — extraction, consolidation, and conversion all go through it. It branches on `extension_settings.charMemory.source` to route to the Main LLM, WebLLM, or a dedicated provider.
`callLLM()` (line ~2265) is the **single dispatch point** for all LLM calls — extraction, consolidation, and conversion all go through it. It branches on `extension_settings.charMemory.source` to route to the Main LLM, WebLLM, a dedicated provider, or a Connection Profile (via `generateProfileResponse()` which uses ST's `ConnectionManagerRequestService`).
---

View file

@ -26,6 +26,8 @@ CharMemory needs its own LLM connection — separate from your main chat. This k
> **Running an LLM locally?** Select **Local Server** from the provider dropdown. Enter your server URL (e.g., `http://localhost:11434/v1` for Ollama). No API key needed. See [Providers → Local Servers](providers.md#local-servers) for port numbers by backend.
> **Already have a connection configured in SillyTavern?** You can skip the wizard's provider setup and use a **Connection Profile** instead. After completing the wizard, open **Settings** (gear icon) → **Connection** → change **LLM Used for Extraction** to **Connection Profile** and select your saved profile. See [Providers → Connection Profiles](providers.md#connection-profiles).
> **If your provider is not listed** Many providers have an OpenAI compatible API endpoint. See if you can configure it that way.
![Wizard step 1 after successful connection — green checkmark, model selected](../images/wizard-step1-connected.png)

View file

@ -45,6 +45,12 @@ CharMemory extracts automatically while you chat. The **Auto** pill in the panel
Both settings only affect automatic extraction. Extract Now, Extract Here, and Batch always run immediately regardless of interval or cooldown.
### Protect recent messages
When enabled (Settings → Extraction), this excludes the most recent messages from auto-extraction. This prevents the character's next response from being constrained by memories that were just extracted from the conversation in progress — swipes and regenerations stay natural because the extraction hasn't "locked in" those messages yet. Skipped messages are picked up on the next extraction cycle.
![Settings Modal — Extraction tab showing Protect Recent Messages and other settings](../images/settings-modal-extraction.png)
---
## Extract Now and Extract Here

View file

@ -0,0 +1,82 @@
# Issue #10: Per-Chat Memory Storage — Backlog Analysis
**Date:** 2026-03-18
**Status:** Backlog
**Issue:** https://github.com/bal-spec/sillytavern-character-memory/issues/10
**Prior design:** `2026-03-06-per-chat-isolation-revised.md`
---
## Summary
User request: memories should be stored per-chat rather than per-character, so different storylines/chats don't share memories.
The extension author's preference is character-level memories (the current default), but some users want per-chat isolation. The solution should support both as an optional setting.
## Proposed UX
Single dropdown in Settings > Storage:
```
Memory scope: [Character (default)] / [Chat]
```
- **Character** (default): Current behavior. Memories stored in Character Data Bank, shared across all chats, VS handles retrieval.
- **Chat**: Memories stored in Chat Attachments (`chat_metadata.attachments`), scoped to the active chat only. VS retrieves only from that chat's attachments.
## Architecture: Chat Attachments vs chat_metadata
Two storage options were analyzed:
### Option A: Chat Attachments (Recommended for simplicity)
Use ST's existing `chat_metadata.attachments` system — the same API as Character Attachments but scoped per-chat. VS already knows how to vectorize and retrieve from chat attachments.
**Pros:** Reuses existing ST infrastructure, visible in Data Bank UI, VS retrieval works automatically.
**Cons:** Cross-chat bleed still possible if VS retrieves from both character AND chat attachments simultaneously.
### Option B: chat_metadata direct storage + setExtensionPrompt injection
Store memories in `chat_metadata.charMemory.isolatedMemories` and inject via `setExtensionPrompt()`, bypassing VS entirely. Full design in `2026-03-06-per-chat-isolation-revised.md`.
**Pros:** Complete isolation guaranteed, no VS dependency.
**Cons:** Loses semantic retrieval, requires reimplementing injection, more code surface area.
## Risk Analysis
### Code Impact
48 references to the character attachment system (`extension_settings.character_attachments`, `getDataBankAttachments`, `writeMemoriesForCharacter`, etc.) would need branching to support chat-scoped storage. Key functions:
- `getMemoryFileName()` — currently uses character avatar; would need chat-scoped variant
- `writeMemoriesForCharacter()` — writes to Character Data Bank; needs Chat Data Bank path
- `readMemoriesForCharacter()` — reads from Character Data Bank; needs Chat Data Bank path
- All Troubleshooter file operations (view, edit, delete)
- Memory Manager, Consolidation, Format/Convert tools
### Known Bug: Batch Extraction in Per-Chat Mode
`getMemoryFileName()` uses `context.chatId` which is always the *active* chat's ID. Batch extraction iterates over multiple chats but the file name function doesn't accept a chat ID parameter. This means batch-extracted memories from non-active chats get written to the wrong file.
**Recommendation:** Disable batch extraction when chat-scoped mode is active, or fix `getMemoryFileName()` to accept an explicit chat ID parameter.
### Group Chats
Group chats add complexity — each character in the group has separate memories, but `chat_metadata` is shared across all group members. Data structure would need per-character keying within the chat metadata.
**Recommendation:** Scope initial implementation to 1:1 chats only. Show a warning if chat mode is enabled in a group chat.
## Testing Strategy
- **Automated (Playwright):** Storage mode switching, verify memories write to correct location (character vs chat attachments), verify isolation (chat A memories don't appear in chat B)
- **Manual:** Full extraction cycle in chat mode, verify VS retrieval scoping, test mode switching with existing memories
## Implementation Priority
Low-medium. The current character-level default works well for most users. This is an opt-in feature for users with specific multi-storyline use cases. No timeline set.
## Dependencies
- Fix `getMemoryFileName()` chat ID bug (regardless of this feature)
- Understand VS retrieval scoping for chat attachments vs character attachments
- Decide on migration path for users switching between modes

View file

@ -6,14 +6,17 @@ CharMemory works better when it uses its own LLM connection — separate from yo
## Extraction sources
Three options for **LLM Used for Extraction** in Settings → Connection:
Four options for **LLM Used for Extraction** in Settings → Connection:
| Source | How it works | Best for |
|--------|-------------|----------|
| **Dedicated API** (default) | Direct API call with only the extraction prompt | Best quality — recommended |
| **Connection Profile** | Reuses a saved SillyTavern connection profile | Already have a profile configured in ST |
| **WebLLM** | Small model running locally in your browser | Privacy and no API cost; limited quality |
| **Main LLM** | Uses whatever LLM your chat is using | Not recommended; No extra setup but quality suffers |
![Settings Modal — Connection tab with source dropdown](../images/settings-modal-connection.png)
**Dedicated API** is the default and recommended option. The extraction prompt is the only thing sent — the character card is included as bounded reference context (so the LLM knows what *not* to re-extract), but no chat system prompts, personas, or jailbreaks contaminate the call.
---
@ -47,6 +50,56 @@ Open Settings → Connection → choose a **Provider**:
---
## Connection Profiles
If you already have a connection configured in SillyTavern's **Connection Manager**, you can reuse it for extraction instead of setting up a separate Dedicated API connection.
### What is a Connection Profile?
A Connection Profile is a SillyTavern feature that saves a snapshot of your current API connection settings — so you can switch between configurations quickly. A profile can include any combination of:
| Setting | Description |
|---------|-------------|
| **API** | Which API provider (e.g., NanoGPT, OpenAI, OpenRouter) |
| **Settings Preset** | The sampler/generation preset |
| **Model** | The specific model to use |
| **Proxy Preset** | Proxy configuration (if any) |
| **Custom Stopping Strings** | Custom stop sequences |
| **Start Reply With** | Prefill text for responses |
| **Reasoning Template** | Reasoning/thinking format (e.g., DeepSeek) |
| **Prompt Post-Processing** | Any prompt post-processing rules |
| **Secret** | Your API key (stored securely) |
Each setting has a checkbox — you choose which parts to include. When a profile is loaded, only the checked settings are applied.
![Connection Profile toolbar — dropdown with info, create, save, edit, reload, delete icons](../images/connection-profile-bar.png)
### Creating a profile in SillyTavern
1. Open the **API Connections** panel (plug icon in SillyTavern's top bar)
2. Configure your API: select a **Chat Completion Source**, enter your **API key**, select a **model**, and verify the connection shows **Valid**
3. Click the **create icon** (file with plus) in the Connection Profile toolbar
4. Check the settings you want to include in the profile — at minimum, check **API**, **Model**, and **Secret**
5. Give it a name and click **Save**
![Creating a Connection Profile — select which settings to include](../images/connection-profile-create.png)
### Using a profile for CharMemory extraction
![Settings Modal — Connection Profile source](../images/settings-modal-profile.png)
1. In the CharMemory panel, click the **gear icon** to open Settings
2. Under **Connection**, change **LLM Used for Extraction** to **Connection Profile**
3. Choose your profile from the **Connection Profile** dropdown
4. Click **Test Connection** to verify it works for extraction
5. Optionally set a **System prompt** override — if left blank, CharMemory uses its default extraction system prompt
Connection Profiles use whatever credentials, model, and endpoint are configured in the profile. You don't need to enter an API key or select a model separately — it's all inherited from the profile.
> **When to use this vs. Dedicated API:** If you've already configured a connection in SillyTavern and want to reuse it without duplicating API keys, Connection Profile is convenient. If you want a completely separate LLM for extraction (different model, different provider), Dedicated API gives you full control.
---
## Recommended models
Memory extraction requires strong instruction following — the LLM must respect the extraction rules, stay within boundaries, and produce well-formatted output.

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 117 KiB

After

Width:  |  Height:  |  Size: 44 KiB

Before After
Before After

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

After

Width:  |  Height:  |  Size: 40 KiB

Before After
Before After

View file

@ -6,7 +6,7 @@
"js": "index.js",
"css": "style.css",
"author": "bal-spec",
"version": "2.1.8",
"version": "2.1.9",
"homePage": "",
"auto_update": false
}

View file

@ -11,7 +11,7 @@
<span id="charMemory_openSettingsModal" class="charMemory_headerGear" title="Open Settings">
<i class="fa-solid fa-gear fa-sm"></i>
</span>
<span id="charMemory_toggleInjectionBtn" class="charMemory_headerGear" title="Toggle Injection Sidebar">
<span id="charMemory_toggleInjectionBtn" class="charMemory_headerGear" title="Toggle Injection Viewer">
<i class="fa-solid fa-syringe fa-sm"></i>
</span>
<div class="inline-drawer-icon fa-solid fa-circle-chevron-down down"></div>