diff --git a/CHANGELOG.yaml b/CHANGELOG.yaml index 4e3abde9..769770bb 100644 --- a/CHANGELOG.yaml +++ b/CHANGELOG.yaml @@ -1,5 +1,6 @@ 0.37.0.dev: features: + - "System Prompt Template Variable: Added {{ system_prompt }} template variable for system prompt overrides. Use it to include the default system prompt within a custom override, at both the app and client level." - "Manual Scene Direction Turn: Added a button to the director scene tools menu to manually trigger a scene direction turn. Useful when scene direction is enabled but auto progression is off. Supports optional one-off instructions via Ctrl+click." - "Visual Scene Tools: Organized the visual tools menu into per-character submenus, matching the world scene tools pattern." - "Section Format: Per-client setting to control how prompt sections are formatted. Choose between Markdown (## headings) and XML (
...
tags). Found in the client configuration next to the data format setting." @@ -27,6 +28,7 @@ - "Contextual Generate: Fixed list-type generation prefilling an empty line after '1.', which caused some LLMs to produce empty lists." - "Advance Time: Fixed toolbar time advancement being completely non-functional due to a missing websocket handler. Also fixed invalid ISO 8601 duration strings for the 1 week and 2 weeks options." improvements: + - "System Prompt Override Indicators: The system prompt override list now shows a pencil icon next to entries that have an active override, making it easy to see which prompts have been customized." - "Search Strictness: The distance_mod embedding preset value is now a float (was int) with a range of 0.1–2.0, allowing both tighter and looser similarity matching. A 'Search Strictness' slider is now available in the Context Database UI, letting users tune search sensitivity on the fly. Changes persist to the active embedding preset immediately." - "Embeddings Device Switching: Changing the embeddings device (e.g., CPU to CUDA) no longer requires a restart. The old model is properly released from ChromaDB's class-level cache and GPU memory is freed before loading the new model." - "Context Formatting: The |condensed template filter no longer permanently compacts multi-line context (e.g., world info, memories, pins) into a single line when sending prompts to the LLM. Formatting is now only compacted temporarily for deduplication comparison and restored to its original multi-line structure afterwards." diff --git a/src/talemate/client/system_prompts.py b/src/talemate/client/system_prompts.py index 66551861..dbed704f 100644 --- a/src/talemate/client/system_prompts.py +++ b/src/talemate/client/system_prompts.py @@ -167,8 +167,16 @@ class SystemPrompts(pydantic.BaseModel): key = f"{kind}_decensor" if decensor else kind - if getattr(self, key): - return getattr(self, key) - if self.parent is not None: - return self.parent.get(kind, decensor) - return render_prompt(kind, decensor) + prompt = getattr(self, key) + if prompt: + pass + elif self.parent is not None: + prompt = self.parent.get(kind, decensor) + else: + prompt = render_prompt(kind, decensor) + + if "{{ system_prompt }}" in prompt: + default_prompt = render_prompt(kind, decensor) + prompt = prompt.replace("{{ system_prompt }}", default_prompt) + + return prompt diff --git a/talemate_frontend/src/components/AppConfigPresetsSystemPrompts.vue b/talemate_frontend/src/components/AppConfigPresetsSystemPrompts.vue index d2aae442..40c37193 100644 --- a/talemate_frontend/src/components/AppConfigPresetsSystemPrompts.vue +++ b/talemate_frontend/src/components/AppConfigPresetsSystemPrompts.vue @@ -13,6 +13,9 @@ {{ item.label }} + @@ -34,6 +37,9 @@ @blur="$emit('update', {system_prompts: config})" :label="labelFromValue(selected[0], tab === 'decensor')" > +

+ mdi-information-outlineUse {{ system_prompt }} to include the default system prompt in your override. +

@@ -106,9 +112,7 @@ export default { return this.tabs.filter(t => t.condition()); }, selectedKey() { - // selected[0] will hold the kind - // if tab is decensor, append _decensor - return this.selected.length > 0 ? this.selected[0]+(this.tab === 'decensor' ? '_decensor' : '') : null; + return this.selected.length > 0 ? this.buildKey(this.selected[0]) : null; } }, data() { @@ -148,6 +152,14 @@ export default { } }, + buildKey(value) { + return value + (this.tab === 'decensor' ? '_decensor' : ''); + }, + + hasOverride(value) { + return !!this.config[this.buildKey(value)]; + }, + labelFromValue(value, decensor=false) { for(let item of this.systemPromptKindList) { if(item.value === value) {