- **Help Agent** — A new agent that answers questions about Talemate itself — settings, agents, clients, the world editor — grounded in the bundled documentation, and able to change agent and application settings on request. - **Timeline Rollback** — Scrub a slider across a scene's automatic version history, preview the message history at any revision, then roll the scene back in place or fork the revision into a new save. - **Pi Bridge Client** — A new client type that drives generations through the pi coding agent's headless RPC mode, making any model pi can reach usable in Talemate. - **Application Settings** — Settings move out of their modal into an always-available Settings tab, with a single topic-grouped sidebar, a settings search, all API keys on one page, and unsaved-change tracking. - **Scene Library** — The home screen is rebuilt as a full-page landing view with a file-tree scene library, cover thumbnails and per-save metadata, scene and save deletion, and a drag-and-drop import dropzone. - **Fast Character Creation** — Generate a character in a single request instead of one prompt per aspect, with a Consolidate multi-select, a token budget, and a Fill in misses pass. Off by default. - **Scene Backdrop** — Set any scene illustration as a backdrop filling the scene view behind the messages, saved with the scene, with configurable text legibility and an Immersive quick-toggle. - **Scene Visual Manager** — World Editor → Scene gains a Visuals tab to browse, upload, generate and delete the scene's backgrounds and illustrations, and set the cover image and backdrop. - **Visual Prompt Finalization** — Post-processing actions — match and replace, or a free-form AI instruction — rewrite image prompts right before they reach the image backend, with per-scene and per-character overrides and reusable template sets. - fixes #271 - fixes #275 Plus 25 improvements and 39 bug fixes — see [CHANGELOG.md](https://github.com/vegu-ai/talemate/blob/prep-0.39.0/CHANGELOG.md#0390) for the full list.
13 KiB
String Nodes
String manipulation: formatting, case, join/split, replace, trim, substrings and excerpts. The Advanced Format ({name} placeholders) and Jinja2 Format ({{ name }} templates) nodes build strings from dynamic inputs — connect other nodes into their input slots and each connected value becomes a template variable (see Collector Nodes for the key inference rules).
16 nodes.
| Node | Registry path |
|---|---|
| Advanced Format | data/string/AdvancedFormat |
| As String | data/string/AsString |
| Case | data/string/Case |
| Condensed | data/string/Condensed |
| Excerpt | data/string/Excerpt |
| Extract | data/string/Extract |
| Format | data/string/Format |
| Join | data/string/Join |
| Make String | data/string/Make |
| Make Text | data/string/MakeText |
| Replace | data/string/Replace |
| Split | data/string/Split |
| String Check | data/string/StringCheck |
| Substring | data/string/Substring |
| Trim | data/string/Trim |
| Jinja2 Format | prompt/Jinja2Format |
Advanced Format
data/string/AdvancedFormat
Python-style string formatting with dynamic inputs. Uses Python's .format() syntax - reference variables with single curly braces ({name}); for jinja2 templates ({{ name }}) use the Jinja2 Format node.
Behaves like Format but supports dynamic inputs similar to DictCollector. Dynamic inputs can be:
- a tuple (key, value)
- a scalar value, in which case the key is derived from the source socket/node using a best-effort heuristic.
Dynamic inputs: item{i}
Inputs
| Input | Type | Description |
|---|---|---|
template |
str |
A format string with placeholders (e.g., "Hello, {name}") |
variables |
dict |
(optional) Optional base dictionary to merge into (dynamic inputs extend/override these) |
This node supports dynamic inputs - additional input sockets can be added in the editor as needed, and connected values are collected with key inference (see Collector Nodes).
Outputs
| Output | Type | Description |
|---|---|---|
result |
str |
The formatted string |
Properties
| Property | Type | Default | Description |
|---|---|---|---|
template |
text |
"" |
A format string with placeholders (e.g., "Hello, {name}") |
As String
data/string/AsString
Converts a value to a string
Inputs
| Input | Type | Description |
|---|---|---|
value |
any |
Outputs
| Output | Type | Description |
|---|---|---|
value |
str |
Case
data/string/Case
Changes string case (upper, lower, title, capitalize)
Converts a string to a different case format, such as uppercase, lowercase, title case, or capitalized.
Inputs
| Input | Type | Description |
|---|---|---|
string |
str |
The string to transform |
Outputs
| Output | Type | Description |
|---|---|---|
result |
str |
The transformed string |
Properties
| Property | Type | Default | Description |
|---|---|---|---|
operation |
str |
"lower" |
Case operation to perform. Choices: upper, lower, title, capitalize. |
Condensed
data/string/Condensed
Condenses a string by removing line breaks and extra spaces.
Inputs
| Input | Type | Description |
|---|---|---|
string |
str |
Outputs
| Output | Type | Description |
|---|---|---|
result |
str |
Excerpt
data/string/Excerpt
Returns an excerpt of a string based on length
Takes the first length characters of the string. If the string was
truncated and add_ellipsis is enabled, "..." is appended.
Inputs
| Input | Type | Description |
|---|---|---|
string |
str |
The string to excerpt |
Outputs
| Output | Type | Description |
|---|---|---|
result |
str |
The excerpt |
Properties
| Property | Type | Default | Description |
|---|---|---|---|
length |
int |
100 |
The length of the excerpt |
add_ellipsis |
bool |
True |
Whether to add an ellipsis to the end of the excerpt |
Extract
data/string/Extract
Extracts a portion of a string using a left and right anchor
Finds the first valid block between anchors (no nested left_anchor inside). Falls back to everything after the last left_anchor if no complete block is found. If the left_anchor does not occur at all, the result is an empty string.
Examples:
- "nestedvalue" -> "value" (first clean block)
- "value ... other" -> "value" (first valid block)
- "no closing tag" -> "no closing tag" (fallback)
Inputs
| Input | Type | Description |
|---|---|---|
string |
str |
The string to extract from |
left_anchor |
str |
(optional) The left anchor |
right_anchor |
str |
(optional) The right anchor |
Outputs
| Output | Type | Description |
|---|---|---|
result |
str |
The extracted substring |
Properties
| Property | Type | Default | Description |
|---|---|---|---|
left_anchor |
str |
"" |
The left anchor |
right_anchor |
str |
"" |
The right anchor |
trim |
bool |
True |
Whether to trim the result |
Format
data/string/Format
Python-style string formatting with variables
Formats a template string by replacing placeholders with values from a variables dictionary, using Python's format() string method.
Inputs
| Input | Type | Description |
|---|---|---|
template |
str |
A format string with placeholders (e.g., "Hello, {name}") |
variables |
dict |
Dictionary of variable names and values to insert |
Outputs
| Output | Type | Description |
|---|---|---|
result |
str |
The formatted string |
Join
data/string/Join
Joins a list of strings with a delimiter
Combines a list of strings into a single string with a specified delimiter between each element.
Inputs
| Input | Type | Description |
|---|---|---|
strings |
list |
List of strings to join |
delimiter |
str |
(optional) Character(s) to insert between each string (optional; a literal "\n" is treated as a newline) |
Outputs
| Output | Type | Description |
|---|---|---|
result |
str |
The joined string |
Properties
| Property | Type | Default | Description |
|---|---|---|---|
delimiter |
str |
" " |
Character(s) to insert between each string |
Make String
data/string/Make
Creates a string
Creates a string with the specified value.
Outputs
| Output | Type | Description |
|---|---|---|
value |
str |
The created string value |
Properties
| Property | Type | Default | Description |
|---|---|---|---|
value |
str |
"" |
The string value to create |
Make Text
data/string/MakeText
Same as make string but will be rendered with a multiline text editor
Outputs
| Output | Type | Description |
|---|---|---|
value |
str |
The created string value |
Properties
| Property | Type | Default | Description |
|---|---|---|---|
value |
text |
"" |
The string value to create |
Replace
data/string/Replace
Replaces occurrences of a substring with another
Searches for all occurrences of a substring and replaces them with a new string.
Inputs
| Input | Type | Description |
|---|---|---|
string |
str |
The original string |
old |
str |
Substring to find and replace |
new |
str |
Replacement string |
Outputs
| Output | Type | Description |
|---|---|---|
result |
str |
The string after replacements |
Properties
| Property | Type | Default | Description |
|---|---|---|---|
old |
str |
"" |
Substring to find and replace |
new |
str |
"" |
Replacement string |
count |
int |
-1 |
Maximum number of replacements to make (-1 for all occurrences) |
Split
data/string/Split
Splits a string into a list based on a delimiter
Divides a string into multiple parts using a specified delimiter.
Inputs
| Input | Type | Description |
|---|---|---|
string |
str |
The string to split |
delimiter |
str |
(optional) Character(s) to use as the split point (optional; a literal "\n" is treated as a newline) |
Outputs
| Output | Type | Description |
|---|---|---|
parts |
list |
List of string parts after splitting |
Properties
| Property | Type | Default | Description |
|---|---|---|---|
delimiter |
str |
" " |
Character(s) to use as the split point |
max_splits |
int |
-1 |
Maximum number of splits to perform (-1 for all possible splits) |
String Check
data/string/StringCheck
Checks if a string starts with, ends with, or contains a substring
Tests whether a string starts with, ends with, contains, or exactly equals a substring, with optional case sensitivity. An empty (or unset) string always yields False, regardless of mode.
Inputs
| Input | Type | Description |
|---|---|---|
string |
str |
The string to check |
substring |
str |
The substring to look for |
Outputs
| Output | Type | Description |
|---|---|---|
result |
bool |
Boolean result of the check |
Properties
| Property | Type | Default | Description |
|---|---|---|---|
substring |
str |
"" |
Default substring to check for |
mode |
str |
"contains" |
Check operation to perform. Choices: startswith, endswith, contains, exact. |
case_sensitive |
bool |
True |
Whether the check should be case-sensitive |
Substring
data/string/Substring
Extracts a portion of a string using indices
Extracts a substring from the original string using start and end indices.
Inputs
| Input | Type | Description |
|---|---|---|
string |
str |
The source string |
start |
int |
Starting index (optional) |
end |
int |
Ending index (optional) |
Outputs
| Output | Type | Description |
|---|---|---|
result |
str |
The extracted substring |
Properties
| Property | Type | Default | Description |
|---|---|---|---|
start |
int |
0 |
Starting index. Min: 0. |
end |
int |
None |
Ending index. Min: 0. |
Trim
data/string/Trim
Removes characters from start/end of string
Removes specified characters from the beginning, end, or both ends of a string. By default, it removes whitespace if no specific characters are provided.
Inputs
| Input | Type | Description |
|---|---|---|
string |
str |
The string to trim |
chars |
str |
(optional) Character(s) to remove (optional, defaults to whitespace; a literal "\n" is treated as a newline) |
Outputs
| Output | Type | Description |
|---|---|---|
result |
str |
The trimmed string |
Properties
| Property | Type | Default | Description |
|---|---|---|---|
mode |
str |
"both" |
Trim mode. Choices: left, right, both. |
chars |
str |
None |
Character(s) to remove |
Jinja2 Format
prompt/Jinja2Format
Renders a jinja2 template string using Prompt's template environment, providing access to all Prompt globals, filters, and template features. Reference variables with double curly braces: {{ name }}.
Variables come from the connected inputs: every dynamic input becomes a template variable. Connect any node output to a dynamic input slot and the variable name is inferred from the source node's name / key / attribute (falling back to the socket name), or connect a (key, value) tuple from Make Key-Value Pair to name it explicitly. The optional variables dict is merged in first; dynamic inputs extend/override it.
Dynamic inputs: item{i} - each connected value becomes a template variable
Inputs
| Input | Type | Description |
|---|---|---|
template |
str |
The jinja2 template string to render |
variables |
dict |
(optional) Optional base dictionary of template variables (dynamic inputs extend/override these) |
scope |
str |
(optional) Optional agent scope (e.g., "director") for template includes |
This node supports dynamic inputs - additional input sockets can be added in the editor as needed, and connected values are collected with key inference (see Collector Nodes).
Outputs
| Output | Type | Description |
|---|---|---|
result |
str |
The rendered string |
Properties
| Property | Type | Default | Description |
|---|---|---|---|
template |
text |
"" |
A jinja2 template string (e.g., "Hello, {{ name }}") |