0.38.0 (#272)
- **Per-Scene Agent Overrides** — Override agent configuration for a single scene without touching your global config. - **Message Revision History** — Browse and continue from previous regenerations / revisions. - **Scene Perspective Overrides** — Set distinct narrative perspectives for the player, NPCs, and narrator. - **Durable World State Snapshot** — The world state snapshot now persists and updates entities across refreshes. - **World State Highlights** — Characters, objects and places marked by the current world state snapshot are now clickable in the recent message(s) for additional detail. Plus 30 improvements and 17 bug fixes
2
.gitignore
vendored
|
|
@ -6,6 +6,8 @@
|
|||
*.internal*
|
||||
*_internal*
|
||||
talemate_env
|
||||
embedded_python/
|
||||
embedded_node/
|
||||
chroma
|
||||
config.yaml
|
||||
secrets/
|
||||
|
|
|
|||
109
CHANGELOG.md
|
|
@ -2,13 +2,116 @@
|
|||
|
||||
_Auto-generated. Do not edit by hand._
|
||||
|
||||
## 0.37.1
|
||||
## 0.38.0
|
||||
|
||||
### Per-Scene Agent Overrides
|
||||
|
||||
Agent configuration can now be overridden per scene without changing your global config. The Agent Modal gains a Global / Scene mode switch for toggling and editing overrides, and you can choose, swap, or opt out of the override file under World Editor → Scene → Settings.
|
||||
|
||||
### Message Revision History
|
||||
|
||||
Regenerated AI messages now show a paginator above the message body so you can browse earlier regenerations. The version you're viewing becomes the one the AI continues from. Continuing a character or narrator message also creates a navigable revision entry, and narrator messages gain a Continue action on the hover toolbar.
|
||||
|
||||
### Scene Perspective Overrides
|
||||
|
||||
The scene outline perspective now supports per-speaker overrides for the player, NPCs, and the narrator, each falling back to the default when left empty. Reusable presets are managed under Settings → Creator → Perspective Presets.
|
||||
|
||||
### Entity Highlights
|
||||
|
||||
Notable characters, items, and places in the most recent scene message are now highlighted as clickable entities — click any of them for a short description. The highlight prompt reads the full scene context, so the entities it surfaces stay anchored to what's happening right now.
|
||||
|
||||
### Durable World State Snapshot
|
||||
|
||||
The world state snapshot now carries entities forward across refreshes instead of regenerating from scratch, updating what changed and dropping entities that are no longer relevant. Stale entries are auto-evicted after several untouched updates, and you can Ctrl/Cmd-click the refresh button to wipe on demand.
|
||||
|
||||
The snapshot can also be pinned into the conversation, narrator, and scene-analysis prompts so its tracked entities inform dialogue, narration, and planning, pull in relevant long-term memory, and run in the background when the client supports concurrent inference. A Custom instructions field lets you steer what it focuses on.
|
||||
|
||||
### Improvements
|
||||
|
||||
**World State Snapshot**
|
||||
|
||||
- Added a Custom instructions field to steer what the snapshot focuses on. Empty by default.
|
||||
- Semantic memory recall now feeds the snapshot so it can build on established lore and earlier scene history. On by default.
|
||||
- Context pinning surfaces the snapshot in conversation, narrator, and scene-analysis prompts. Off by default.
|
||||
- Background generation no longer locks scene input when the client supports concurrent inference; manual refreshes can be cancelled mid-generation.
|
||||
- The snapshot now refreshes per character turn rather than per full round; the default interval was raised from 5 to 10 to keep the cadence comparable.
|
||||
|
||||
**Editor & Revision**
|
||||
|
||||
- Triggering a revision now shows a Revising spinner that clears whether the text changes, fails, or is cancelled.
|
||||
- Added a Repetition handling setting (Remove or Attempt rewrite) for AI-assisted revision.
|
||||
- Context-investigation messages (Look at, Investigate, Query) can now be revised automatically (opt-in, off by default) or manually via the Revise chip.
|
||||
- The revision chip on the message hover toolbar now shows the configured revision method (Dedupe, Unslop, or Targeted Rewrite) instead of a generic label.
|
||||
|
||||
**Autocomplete & Generation**
|
||||
|
||||
- Autocomplete accepts a free-form {...} hint block at the end of the input to steer the continuation; the block is stripped when accepted.
|
||||
- A chip beside the field now offers Redo and Undo after an autocomplete suggestion is applied.
|
||||
- The Add Dialogue Example and World information fields now support autocomplete (Ctrl+Enter), with the same hint and Redo/Undo affordances.
|
||||
- Instructions you provide when generating field content are now followed more reliably, with static history entries treating your instruction as the seed to expand on.
|
||||
|
||||
**Clients & Generation**
|
||||
|
||||
- OpenAI Compatible client gains a Parameters tab with individual toggles for temperature, top_p, and presence_penalty, so unsupported parameters can be omitted entirely.
|
||||
- llama.cpp client adds a Concurrent Inference toggle so batch operations can run requests in parallel against a single server. Off by default.
|
||||
- Added a HuggingFace access token to application settings for downloading gated model weights such as the Pocket TTS voice-cloning model.
|
||||
- Response length gains an Adaptive option (now the default) that drops the token cap when reasoning is enabled, so responses aren't cut off mid-thought.
|
||||
- Clients can now define a reasoning-start pattern so models that skip reasoning are accepted as-is instead of erroring; built-in Qwen, Gemma, GPT-OSS, and Seed templates set it automatically.
|
||||
- The client's Reasoning tab now shows a Template default chip when the prompt template supplies a strip or validation pattern, clarifying where the value comes from.
|
||||
|
||||
**Installation & Tooling**
|
||||
|
||||
- The frontend now installs dependencies with pnpm for supply-chain hardening, provisioned automatically through Corepack; the install, update, and Docker scripts provision Node.js 22.
|
||||
|
||||
**Inference Presets**
|
||||
|
||||
- Added an Apply to all action that copies the current preset's values to every other preset in the group; Reset now asks for confirmation.
|
||||
- Widened the adjustable range and refined the step increments on several parameter sliders for more precise tuning.
|
||||
|
||||
**Scene & UI**
|
||||
|
||||
- Long scenes render more smoothly; removing or rearranging messages now re-renders only the affected slot instead of everything after it.
|
||||
- Removed the read-only Character Sheet dialog — the Manage character button already covers viewing and editing.
|
||||
- Renamed the Creator sub-tab from Content Context to Content Classification to match the scene outline editor.
|
||||
- Added a Make Player Character / Unmark as Player action to the character editor that swaps which character the player controls.
|
||||
- Context-investigation messages gain a Visualize action that generates a matched image into the message.
|
||||
- Added a Per-Action Reasoning override so reasoning can be forced off for specific agent actions, via the brain icon in the prompt log.
|
||||
|
||||
**Node Editor**
|
||||
|
||||
- Event Modules gain an auto_register toggle so a module subscribes to its event as soon as it's registered, without being placed in the scene loop graph.
|
||||
- Log entries now show a right-aligned HH:MM:SS.mmm timestamp for easier correlation with scene activity.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
**Scene History**
|
||||
**Backends**
|
||||
|
||||
- Fixed a crash when generating dialogue in long scenes that combine layered history with pre-established history entries. The scene could become unplayable until its layered history was manually edited.
|
||||
- Google: an incomplete setup no longer overwrites the client's model name, which left the client looking configured while every request failed; existing bad values are repaired automatically.
|
||||
- Anthropic: the Optimize for Prompt Caching toggle now actually enables caching by sending the required parameter when on.
|
||||
- OpenRouter applies the same caching for anthropic/* models; note that enabling it forces routing to direct Anthropic.
|
||||
- Conversation agent no longer injects # into the stop-sequence list on every turn.
|
||||
|
||||
**Messages & Toolbar**
|
||||
|
||||
- Message toolbar actions and double-click editing now disable while a background operation runs, with the hint reading Editing locked.
|
||||
- The Create Pin action on narrator messages now respects the UI lock during generation.
|
||||
- World entries created via Create Pin are marked Include only when pinned, so they surface through the pin rather than as ambient memory.
|
||||
- Toolbar deletes, edits, and revision swaps now write through immediately with autosave on, so forking or rollback reflects them without a manual save.
|
||||
- Intro message TTS now activates the scene tools audio control when triggered manually.
|
||||
|
||||
**Scene & Memory**
|
||||
|
||||
- Forks and rollbacks created from the changelog UI no longer fail to load with a missing-field error; affected history entries are repaired on reconstruction.
|
||||
- Switching scenes now releases GPU memory reserved by local CUDA work (embeddings, TTS); can be turned off under Settings → Game → General.
|
||||
- Scene-group templates created in the prompt manager are now resolvable from Jinja include calls regardless of the active agent type.
|
||||
- Contextual autocomplete no longer repeats text you've already typed instead of continuing from where you left off.
|
||||
|
||||
**UI & Startup**
|
||||
|
||||
- Fixed an empty grey toast flashing after operations with no visible change; swallowed cancellation toasts now display.
|
||||
- Node Editor boolean property checkboxes now repaint immediately on click instead of waiting for focus to move.
|
||||
- The onboarding long-term memory step now scrolls on shorter viewports, keeping the Apply & finish button in view.
|
||||
- Automatic prompt-template detection now times out and continues startup when HuggingFace can't be reached, instead of hanging indefinitely.
|
||||
|
||||
## 0.37.0
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,63 @@
|
|||
0.38.0.dev:
|
||||
features:
|
||||
- "Event Module Auto-Register: Event Modules gained an `auto_register` toggle so a module subscribes to its event as soon as it's registered with the scene, without having to be placed in the scene loop graph."
|
||||
- "Per-Scene Agent Overrides: Agent configuration can now be overridden per scene without changing the global config. The Agent Modal gains a Global / Scene mode switch for toggling and editing overrides; choose, swap, or opt out of the override file under World Editor → Scene → Settings."
|
||||
- "Player Character Toggle: Added a Make Player Character / Unmark as Player action to the character editor. Promoting a character makes them the player and demotes the previous player to an AI actor; unmarking flips the current player to AI."
|
||||
- "Message Revision History: Regenerated AI messages now show a paginator above the message body to browse previous regenerations. The version you're viewing becomes the one the AI continues from."
|
||||
- "Scene Perspective Overrides: The scene outline perspective now supports per-speaker overrides for the player, NPCs, and narrator, each falling back to the default when empty. Presets are managed under Settings → Creator → Perspective Presets."
|
||||
- "Per-Action Reasoning Override: Force reasoning off for specific agent actions without changing the client's global setting, via the brain icon in the prompt log."
|
||||
- "Entity Highlights: Notable characters, items, and places in the most recent scene message are now highlighted as clickable entities — click for a short description of each."
|
||||
- "Visualize Context Investigations: Context-investigation messages (entity look-ups, Look at Scene / Character) gained a Visualize action that generates an image into the message, matched to the subject."
|
||||
improvements:
|
||||
- "Settings UX: Renamed the Creator sub-tab from 'Content Context' to 'Content Classification' to match the field label used in the scene outline editor."
|
||||
- "Message Revision History: Continuing a character or narrator message now creates a navigable revision entry tagged 'Continued'. Narrator messages also gain the Continue action on the hover toolbar."
|
||||
- "Pydantic Migration: Internal data models across the codebase converted to pydantic for stricter validation. No user-visible behavior changes."
|
||||
- "Character Sheet: Removed the read-only Character Sheet dialog and its button from the World State panel — the Manage character button already covers viewing and editing character details."
|
||||
- "Message Toolbar: The revision chip on the message hover toolbar now shows the editor's configured revision method (e.g. Dedupe, Unslop, or Targeted Rewrite) instead of the generic 'Editor Revision' label."
|
||||
- "Editor Revision Feedback: Triggering a revision from a message now shows a 'Revising' spinner, which clears whether the revision changes the text, produces no changes, fails, or is cancelled."
|
||||
- "Editor Revision: Added a Repetition handling setting (Remove / Attempt rewrite) for AI-assisted revision. Remove (default) deletes flagged repetitions; Attempt rewrite asks the model to substitute genuinely different content, falling back to removal only when no meaningful rewrite is possible."
|
||||
- "Editor Revision: Context-investigation messages (Look at, Investigate, Query) now support revision, both automatically via a new opt-in target (off by default) and manually via the Revise chip. They also contribute to the repetition corpus so nearby messages dedupe against them."
|
||||
- "Frontend Tooling: Migrated the frontend from npm to pnpm for supply-chain hardening, provisioned automatically through Corepack. A 7-day minimum-release-age cooldown blocks brand-new dependency versions, and dependency install/build scripts are blocked unless allowlisted. pnpm 11 requires Node.js 22, now provisioned automatically by the install, update, and Docker build scripts."
|
||||
- "Scene Message List: Long scenes render more smoothly when the message history changes. Operations that remove or rearrange messages now re-render only the affected slot instead of every message after the change point."
|
||||
- "OpenAI Compatible Client: Added a Parameters config tab with individual toggles for `temperature`, `top_p`, and `presence_penalty`. Toggling a parameter off omits it from the request entirely, for backends that hard-error on unsupported parameters. All three default to on."
|
||||
- "llama.cpp Client: Added a Concurrent Inference toggle so batch operations can dispatch multiple requests in parallel against a single `llama-server`. Off by default."
|
||||
- "Autocomplete Hints: Autocomplete now accepts a free-form `{...}` hint block at the end of the input to steer the continuation (tone, beats, sensory detail, etc.); the brace block is stripped from the field when the suggestion is accepted. Toggle via the new `Enable Hints` setting on the Creator agent's Autocomplete config (default on)."
|
||||
- "Autocomplete Redo/Undo: After an autocomplete suggestion is applied, a chip appears beside the field with Redo and Undo actions. Redo re-runs autocomplete from your original input (including any hint) so you can iterate without retyping; Undo restores the original input."
|
||||
- "Contextual Generation Instructions: Instructions you provide when generating field content (character attributes, world entries, history entries, etc.) are now presented to the model as user-given instruction or seed material that must be reflected in the result, so they're followed more reliably. Static history entries in particular now treat your instruction as the seed for the entry, expanding on it instead of occasionally ignoring it."
|
||||
- "Node Editor Log: Log entries now show a right-aligned `HH:MM:SS.mmm` timestamp, making it easier to correlate them with scene activity."
|
||||
- "World State Snapshot: The Entity Highlights prompt now sees the full scene context rather than just the last 10 dialogue lines, and the analyzed 'current moment' is tightened to the most recent lines so highlights stay anchored to the active beat."
|
||||
- "Durable World State Snapshot: The world state snapshot now carries entities forward across refreshes instead of regenerating wholesale, updating what changed and dropping entities that are no longer relevant. Stale entries are auto-evicted after several untouched updates. Ctrl/Cmd-click the refresh button to wipe on demand, or disable durability in the world state agent config."
|
||||
- "World State Snapshot Context Pinning: The world state snapshot can now be pinned into the conversation, narrator, and scene-analysis prompts so its tracked entities inform dialogue, narration, and planning. Off by default."
|
||||
- "World State Snapshot Custom Instructions: Added a Custom instructions field to the world state agent config to steer what the snapshot focuses on. Empty by default."
|
||||
- "World State Snapshot Memory Recall: The world state agent now pulls relevant long-term memory into snapshot generation, so the snapshot can build on established lore and earlier scene history. Semantic recall is on by default."
|
||||
- "World State Snapshot Background Generation: When the world state agent's client supports concurrent inference, the snapshot now generates in the background instead of locking the scene input. Manual refreshes work the same way and can be cancelled mid-generation."
|
||||
- "HuggingFace Token: Added a HuggingFace access token to the application settings for downloading gated model weights such as the Pocket TTS voice-cloning model. It can also be set directly in the Pocket TTS agent config."
|
||||
- "Inference Presets: Added an 'Apply to all' action to the inference parameter editor that copies the current preset's values to every other preset in the group. The Reset action now asks for confirmation as well."
|
||||
- "Inference Presets: Widened the adjustable range and refined the step increments on several inference parameter sliders so presets can be tuned more precisely."
|
||||
- "More Autocomplete Fields: The character actor's Add Dialogue Example field and the world editor's World information field now support autocomplete (Ctrl+Enter), with the same hint and Redo/Undo affordances as other generated fields."
|
||||
- "Response Length Enforcement: Added an Adaptive option to the client's response-length setting, now the default. When reasoning is enabled it relies on length instructions alone, which reasoning models follow well, and drops the token cap that could otherwise cut a response off while the model is still thinking. With reasoning off it falls back to capping tokens and sending instructions."
|
||||
- "Reasoning Validation Pattern: Clients can now define a pattern marking the start of a model's reasoning, alongside the existing strip pattern. When a model doesn't actually reason (as can happen with abliterated variants), its response is accepted as-is instead of erroring out. Built-in templates for Qwen, Gemma, GPT-OSS, and Seed set it automatically."
|
||||
- "Reasoning Template Defaults Indicator: When a model's prompt template supplies a default strip or validation pattern (as the built-in Qwen, Gemma, GPT-OSS, and Seed templates do), the client's Reasoning tab now shows a 'Template default' chip beneath the field — with a tooltip naming the template — so it's clear the value is template-provided rather than only hinted at by the field placeholder. The chip disappears once you enter a custom value."
|
||||
changes:
|
||||
- "World State Snapshot Cadence: The snapshot now refreshes per individual character turn rather than per full scene round. The default interval was raised from 5 to 10 to keep the effective cadence comparable."
|
||||
fixes:
|
||||
- "Google Client: Fixed the 'Setup incomplete' status leaking into the client's model name. Removing then re-adding the API key could persist 'Setup incomplete' as the model, leaving the client looking configured while every request failed with HTTP 400. The incomplete-setup state is now reported as an error message without overwriting the model, and a client that already has the bad value persisted is healed to report 'No model loaded' instead of sending the invalid model to Google."
|
||||
- "Anthropic / OpenRouter Clients: Fixed the 'Optimize for Prompt Caching' toggle not actually enabling caching on Anthropic — the required `cache_control` parameter was never sent. It is now sent when the toggle is on, and the OpenRouter client does the same for `anthropic/*` models. Note: enabling caching for Anthropic via OpenRouter forces routing to direct Anthropic."
|
||||
- "Game Loop Event: Fixed an internal scene-loop event being constructed with the wrong scene reference, surfaced by the pydantic migration."
|
||||
- "Conversation Agent: Stopped injecting `#` into the LLM stop-sequence list on every conversation turn."
|
||||
- "Scene-Group Templates: Templates created via the prompt manager under the `scene` agent prefix are now resolvable from Jinja `{% include %}` calls regardless of the active agent type."
|
||||
- "Intro Message TTS: Fixed the scene tools audio control not activating when TTS was manually triggered for the intro message."
|
||||
- "Create Pin: Fixed the Create Pin action on narrator messages staying clickable while the UI was locked during generation; it now respects the lock."
|
||||
- "Message Toolbar: Fixed the message hover-toolbar actions and double-click editing staying available while a background agent operation was running. They now disable for the duration, with the hint reading 'Editing locked'."
|
||||
- "Create Pin: World entries created via the Create Pin message action are now marked Include only when pinned, so they surface only through the pin and aren't retrieved as ambient memory."
|
||||
- "Status Snackbar: Fixed an empty grey toast flashing after operations that completed without a visible change. Cancellation toasts that were previously swallowed now display."
|
||||
- "Node Editor Module Properties: Fixed boolean property checkboxes appearing unresponsive — clicks updated the value but the checkbox didn't repaint until focus moved elsewhere. They now commit on change."
|
||||
- "Onboarding Wizard: Fixed the long-term memory setup step being non-scrollable on shorter viewports, which could push the 'Apply & finish' button below the fold. The step content now scrolls while the footer actions stay in view."
|
||||
- "Scene Forking: Fixed forks and rollbacks created from the changelog UI sometimes failing to load with a 'message Field required' error. Affected history entries are now repaired during reconstruction so the scene loads."
|
||||
- "Message Toolbar Actions: Fixed deletes, edits, and revision swaps made from the message toolbar not being persisted to the changelog right away — they only landed at the next scene turn or manual save. With autosave on, they now write through immediately, so forking or rolling back from the changelog UI reflects those changes without the user having to save first."
|
||||
- "GPU VRAM: Switching scenes now releases the GPU memory that local CUDA work (embeddings, TTS) leaves reserved, instead of holding it for the rest of the session where it could leave too little VRAM to load another scene. Can be turned off under Settings → Game → General."
|
||||
- "Autocomplete: Fixed contextual autocomplete (character attributes, world entries, scene intros, and similar fields) sometimes repeating the text you had already typed instead of only continuing from where you left off."
|
||||
- "HuggingFace Prompt Template Lookup: Fixed automatic prompt-template detection hanging indefinitely when HuggingFace can't be reached (e.g. network or IPv6 routing issues). The lookup now times out, logs a warning, and lets startup continue instead of stalling silently."
|
||||
0.37.1:
|
||||
fixes:
|
||||
- "Scene History: Fixed a crash when generating dialogue in long scenes that combine layered history with pre-established (static) history entries. The affected scene could become unplayable until its layered history was manually edited."
|
||||
|
|
|
|||
14
Dockerfile
|
|
@ -1,19 +1,23 @@
|
|||
# Stage 1: Frontend build
|
||||
FROM node:21-slim AS frontend-build
|
||||
FROM node:22-slim AS frontend-build
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy frontend package files
|
||||
COPY talemate_frontend/package*.json ./
|
||||
# Enable pnpm via corepack (version pinned by package.json "packageManager").
|
||||
ENV COREPACK_ENABLE_DOWNLOAD_PROMPT=0
|
||||
RUN npm install -g corepack@latest && corepack enable
|
||||
|
||||
# Copy frontend manifest, lockfile and pnpm settings
|
||||
COPY talemate_frontend/package.json talemate_frontend/pnpm-lock.yaml talemate_frontend/pnpm-workspace.yaml ./
|
||||
|
||||
# Install dependencies
|
||||
RUN npm ci
|
||||
RUN pnpm install --frozen-lockfile
|
||||
|
||||
# Copy frontend source
|
||||
COPY talemate_frontend/ ./
|
||||
|
||||
# Build frontend
|
||||
RUN npm run build
|
||||
RUN pnpm build
|
||||
|
||||
# Stage 2: Backend build
|
||||
FROM python:3.11-slim AS backend-build
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ Next rebuild the frontend.
|
|||
|
||||
```bash
|
||||
cd talemate_frontend
|
||||
npm run build
|
||||
corepack pnpm build
|
||||
```
|
||||
|
||||
### Start the backend and frontend
|
||||
|
|
|
|||
|
|
@ -4,10 +4,11 @@
|
|||
|
||||
--8<-- "docs/snippets/common.md:python-versions"
|
||||
|
||||
1. node.js and npm - see instructions [here](https://nodejs.org/en/download/package-manager/)
|
||||
1. python- see instructions [here](https://www.python.org/downloads/)
|
||||
1. python - see instructions [here](https://www.python.org/downloads/)
|
||||
1. uv - see instructions [here](https://github.com/astral-sh/uv#installation)
|
||||
|
||||
`install.sh` downloads a portable Node.js 22 runtime automatically (used to build the frontend), so you do not need to install Node.js yourself.
|
||||
|
||||
### Installation
|
||||
|
||||
1. `git clone https://github.com/vegu-ai/talemate.git`
|
||||
|
|
@ -37,8 +38,10 @@ If everything went well, you can proceed to [connect a client](../../connect-a-c
|
|||
|
||||
### Running the Frontend
|
||||
|
||||
Unlike the quick install above, this manual path does not provision Node.js for you — install Node.js 22+ yourself (see [here](https://nodejs.org/en/download/package-manager/)). Corepack ships with it and provides `pnpm`.
|
||||
|
||||
1. Navigate to the `talemate_frontend` directory.
|
||||
2. If you haven't already, install npm dependencies by running `npm install`.
|
||||
3. Start the server with `npm run serve`.
|
||||
2. If you haven't already, install frontend dependencies by running `corepack pnpm install`.
|
||||
3. Start the server with `corepack pnpm run serve`.
|
||||
|
||||
Please note that you may need to set environment variables or modify the host and port as per your setup. You can refer to the various start scripts for more details.
|
||||
|
|
@ -3,9 +3,9 @@
|
|||
1. Download the latest Talemate release ZIP from the [Releases page](https://github.com/vegu-ai/talemate/releases) and extract it anywhere on your system (for example, `C:\Talemate`).
|
||||
2. Double-click **`start.bat`**.
|
||||
- On the very first run Talemate will automatically:
|
||||
1. Download a portable build of Python 3 and Node.js (no global installs required).
|
||||
1. Download a portable build of Python 3 and Node.js 22 (no global installs required).
|
||||
2. Create and configure a Python virtual environment.
|
||||
3. Install all back-end and front-end dependencies with the included *uv* and *npm*.
|
||||
3. Install all back-end and front-end dependencies with the included *uv* and *pnpm*.
|
||||
4. Build the web client.
|
||||
3. When the console window prints **"Talemate is now running"** and the logo appears, open your browser at **http://localhost:8082**.
|
||||
|
||||
|
|
@ -21,4 +21,4 @@
|
|||
| **`install-cuda.bat`** | Installs the CUDA-enabled Torch build (run after the regular install). |
|
||||
| **`update.bat`** | Pulls the latest changes from GitHub, updates dependencies, rebuilds the web client. |
|
||||
|
||||
No system-wide Python or Node.js is required – Talemate uses the embedded runtimes it downloads automatically.
|
||||
No system-wide Python or Node.js is required – Talemate uses the embedded runtimes it downloads automatically. The bundled Node.js is version 22, which is required by the frontend's package manager (pnpm).
|
||||
|
Before Width: | Height: | Size: 57 KiB |
|
Before Width: | Height: | Size: 9.3 KiB |
|
Before Width: | Height: | Size: 39 KiB |
|
Before Width: | Height: | Size: 71 KiB |
|
Before Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 86 KiB |
|
Before Width: | Height: | Size: 117 KiB |
|
Before Width: | Height: | Size: 104 KiB |
|
Before Width: | Height: | Size: 87 KiB |
|
Before Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 93 KiB |
|
Before Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 85 KiB |
|
Before Width: | Height: | Size: 46 KiB |
BIN
docs/img/0.38.0/agent-action-overrides-dialog.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
docs/img/0.38.0/app-settings-appearance-messages.png
Normal file
|
After Width: | Height: | Size: 72 KiB |
BIN
docs/img/0.38.0/app-settings-application.png
Normal file
|
After Width: | Height: | Size: 52 KiB |
BIN
docs/img/0.38.0/app-settings-creator-perspective-presets.png
Normal file
|
After Width: | Height: | Size: 96 KiB |
BIN
docs/img/0.38.0/client-llamacpp.png
Normal file
|
After Width: | Height: | Size: 41 KiB |
BIN
docs/img/0.38.0/creator-autocomplete-settings.png
Normal file
|
After Width: | Height: | Size: 82 KiB |
BIN
docs/img/0.38.0/editor-revision-settings-dedupe.png
Normal file
|
After Width: | Height: | Size: 104 KiB |
BIN
docs/img/0.38.0/editor-revision-settings-rewrite.png
Normal file
|
After Width: | Height: | Size: 165 KiB |
BIN
docs/img/0.38.0/editor-revision-settings-unslop.png
Normal file
|
After Width: | Height: | Size: 147 KiB |
BIN
docs/img/0.38.0/history-add-entry.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
docs/img/0.38.0/inference-presets-1.png
Normal file
|
After Width: | Height: | Size: 106 KiB |
BIN
docs/img/0.38.0/message-revision-paginator.png
Normal file
|
After Width: | Height: | Size: 49 KiB |
BIN
docs/img/0.38.0/pocket-tts-api-settings.png
Normal file
|
After Width: | Height: | Size: 104 KiB |
BIN
docs/img/0.38.0/scene-outline-perspective-overrides.png
Normal file
|
After Width: | Height: | Size: 65 KiB |
BIN
docs/img/0.38.0/world-editor-scene-outline-1.png
Normal file
|
After Width: | Height: | Size: 171 KiB |
BIN
docs/img/0.38.0/world-editor-scene-settings-1.png
Normal file
|
After Width: | Height: | Size: 122 KiB |
BIN
docs/img/0.38.0/world-state-snapshot-2.png
Normal file
|
After Width: | Height: | Size: 29 KiB |
BIN
docs/img/0.38.0/world-state-update-world-state-settings.png
Normal file
|
After Width: | Height: | Size: 120 KiB |
|
|
@ -4,7 +4,7 @@
|
|||
<!--- --8<-- [end:python-versions] -->
|
||||
|
||||
<!--- --8<-- [start:world-editor-create-group] -->
|
||||
Fist, if you have not done so, [create a template group](/talemate/user-guide/world-editor/templates/groups) to store the template in.
|
||||
Fist, if you have not done so, [create a template group](/talemate/user-guide/templates/groups) to store the template in.
|
||||
|
||||
Then select the group you want to add the template to and click the **:material-plus: Create Template** button.
|
||||
|
||||
|
|
@ -15,7 +15,7 @@ Then select the group you want to add the template to and click the **:material-
|
|||
!!! note "Unwanted Prose Requirement"
|
||||
Unwanted phrases are defined in the writing style that is currently selected in the [Scene Settings](/talemate/user-guide/world-editor/scene/settings).
|
||||
|
||||
See [Writing Style Templates](/talemate/user-guide/world-editor/templates/writing-style) for more information on how to create a writing style and add unwanted phrases.
|
||||
See [Writing Style Templates](/talemate/user-guide/templates/writing-style) for more information on how to create a writing style and add unwanted phrases.
|
||||
<!--- --8<-- [end:editor-revision-unwanted-prose-requirement] -->
|
||||
|
||||
<!--- --8<-- [start:documentation-is-a-work-in-progress] -->
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
<!--- --8<-- [start:generate] -->
|
||||
!!! tip "Generate using AI"
|
||||
**:material-auto-fix: Generate** - press the **generate** button on top of the input field to let the AI generate the content based on the existing details.
|
||||
|
||||
Hold `ctrl` (or `cmd` on macOS) while clicking to add your own [instructions](/talemate/user-guide/world-editor/generation-settings/#generation-instructions). What you type is used as instruction and seed material the AI must reflect in the result.
|
||||
<!--- --8<-- [end:generate] -->
|
||||
|
||||
<!--- --8<-- [start:autocomplete] -->
|
||||
|
|
@ -11,13 +13,15 @@
|
|||
<!--- --8<-- [start:generate_and_autocomplete] -->
|
||||
!!! tip "Generate using AI"
|
||||
**:material-auto-fix: Generate** - press the **generate** button on top of the input field to let the AI generate the content based on the existing details.
|
||||
|
||||
|
||||
Hold `ctrl` (or `cmd` on macOS) while clicking to add your own [instructions](/talemate/user-guide/world-editor/generation-settings/#generation-instructions). What you type is used as instruction and seed material the AI must reflect in the result.
|
||||
|
||||
**:material-auto-fix: Autocomplete** - press `ctrl+Enter` (or `cmd+Enter` on macOS) while the cursor is in the input field to use AI to autocomplete the current content, you
|
||||
<!--- --8<-- [end:generate_and_autocomplete] -->
|
||||
|
||||
<!--- --8<-- [start:generation_templates_and_settings] -->
|
||||
!!! tip "Generation settings and managing templates"
|
||||
Find out more about content generation, managing templates and how to apply randomization and specific writing styles in [Templates](/talemate/user-guide/world-editor/templates/) and [Generation settings](/talemate/user-guide/world-editor/generation-settings).
|
||||
Find out more about content generation, managing templates and how to apply randomization and specific writing styles in [Templates](/talemate/user-guide/templates/) and [Generation settings](/talemate/user-guide/world-editor/generation-settings).
|
||||
<!--- --8<-- [end:generation_templates_and_settings] -->
|
||||
|
||||
<!--- --8<-- [start:tracked_state] -->
|
||||
|
|
|
|||
50
docs/user-guide/agents/creator/autocomplete.md
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
# Autocomplete
|
||||
|
||||
Autocomplete uses the AI to continue whatever you have already started typing in a text field. Instead of generating content from scratch, it picks up from your partial text and writes the next part for you.
|
||||
|
||||
To trigger it, place your cursor in a supported field and press `ctrl+Enter` (or `cmd+Enter` on macOS). The generated text is appended to what you have already written.
|
||||
|
||||
!!! abstract "This works best if the client is in control of the prompt template"
|
||||
Success rate on this feature when the text generation API controls the prompt template is reduced, as Talemate cannot prefix the partial text.
|
||||
|
||||
See [Prompt Templates](/talemate/user-guide/clients/prompt-templates) for more information.
|
||||
|
||||
## Steering the continuation with hints
|
||||
|
||||
You can guide the continuation by adding a short hint in curly braces `{...}` at the very end of your input before you trigger autocomplete. The hint is free-form, so you can describe whatever you want the AI to keep in mind: tone, beats to hit, sensory detail, who else is in the scene, and so on.
|
||||
|
||||
The brace block is only an instruction for the AI. When the suggestion is accepted, the `{...}` block is stripped out, so it never ends up in your actual text.
|
||||
|
||||
#### Example
|
||||
|
||||
Typing:
|
||||
|
||||
> `"Kaira!?" he yelled {dark corridor, no response}`
|
||||
|
||||
and pressing `ctrl+Enter` cues the AI on the tone and the beats you want, then continues the line. The `{dark corridor, no response}` part is removed once the suggestion is applied, leaving only the dialogue and its continuation.
|
||||
|
||||
Hints are controlled by the **Enable Hints** setting on the Creator agent, which is on by default. When the setting is turned off, a trailing `{...}` block is treated as ordinary text and sent as part of your input instead of being used as a hint. See [Settings](/talemate/user-guide/agents/creator/settings) for more.
|
||||
|
||||
## Redo and Undo
|
||||
|
||||
After a suggestion is applied, a small chip appears beside the field with two actions:
|
||||
|
||||
- **:material-refresh: Redo** — re-runs autocomplete from your original input (including any hint you added). This lets you keep trying for a different continuation without retyping anything.
|
||||
- **:material-undo: Undo** — restores your original input and removes the applied suggestion.
|
||||
|
||||
The chip disappears once you start editing the field yourself.
|
||||
|
||||
## Where autocomplete is available
|
||||
|
||||
Autocomplete is available across many of Talemate's text fields, including:
|
||||
|
||||
- Your action and dialogue in the [main input](/talemate/user-guide/interacting/#autocomplete)
|
||||
- Scene messages when you edit them in place — double-click a character, narrator, or context investigation message to edit it, then press `ctrl+Enter`
|
||||
- Character [attributes](/talemate/user-guide/world-editor/characters/attributes) and [details](/talemate/user-guide/world-editor/characters/details)
|
||||
- Character [description](/talemate/user-guide/world-editor/characters/description)
|
||||
- The [scene introduction](/talemate/user-guide/world-editor/scene/outline)
|
||||
- The character actor's **Add Dialogue Example** field (see [Actor management](/talemate/user-guide/world-editor/characters/actor))
|
||||
|
||||
The hint and Redo/Undo behaviour described above works the same way in every field that supports autocomplete.
|
||||
|
||||
You can adjust how long the generated suggestions are, per field type, on the Creator agent's [Settings](/talemate/user-guide/agents/creator/settings) page.
|
||||
|
|
@ -1,3 +1,11 @@
|
|||
# Overview
|
||||
|
||||
Used tor most creative tasks that involves the creation of new context.
|
||||
Used for most creative tasks that involve the creation of new context.
|
||||
|
||||
## Features
|
||||
|
||||
### Autocomplete
|
||||
|
||||
Continues whatever you have already started typing in a text field, so you can let the AI write the next part for you. Trigger it with `ctrl+Enter` (or `cmd+Enter` on macOS), steer it with optional `{...}` hints, and refine the result with Redo and Undo.
|
||||
|
||||
See the [Autocomplete](/talemate/user-guide/agents/creator/autocomplete) page for more information.
|
||||
|
|
|
|||
|
|
@ -10,7 +10,9 @@ Open by clicking the **Creator** agent in the agent list.
|
|||
|
||||
## Autocomplete
|
||||
|
||||

|
||||
These settings control the [Autocomplete](/talemate/user-guide/agents/creator/autocomplete) feature.
|
||||
|
||||

|
||||
|
||||
##### Dialogue Suggestion Length
|
||||
|
||||
|
|
@ -18,4 +20,12 @@ How many tokens to generate (max.) when autocompleting character actions.
|
|||
|
||||
##### Narrative Suggestion Length
|
||||
|
||||
How many tokens to generate (max.) when autocompleting narrative text.
|
||||
How many tokens to generate (max.) when autocompleting narrative text.
|
||||
|
||||
##### Enable Hints
|
||||
|
||||
When enabled (the default), a trailing `{...}` block at the end of your input is treated as a hint that steers the continuation, and is stripped from the field once the suggestion is accepted.
|
||||
|
||||
When disabled, any trailing `{...}` is treated as ordinary text and sent as part of your input.
|
||||
|
||||
See [Steering the continuation with hints](/talemate/user-guide/agents/creator/autocomplete/#steering-the-continuation-with-hints) for details.
|
||||
|
|
@ -2,6 +2,8 @@ Revisions were introduced in version `0.30.0` and allow the editor to detect and
|
|||
|
||||
Please see the [settings](/talemate/user-guide/agents/editor/settings/#revision) for more information on how to configure **:material-typewriter: Revisions**.
|
||||
|
||||
## Automatic revision
|
||||
|
||||
Once automatic revisions are enabled, if the editor finds an issue in a message you will see the following status updates:
|
||||
|
||||

|
||||
|
|
@ -14,4 +16,20 @@ Once the revision is complete the editor agent will indicate that that it made s
|
|||
|
||||
Click the :material-message-text-outline: icon to open the Agent Messages dialog to view the changes.
|
||||
|
||||

|
||||

|
||||
|
||||
Which message types are revised automatically is controlled by the [Automatic Revision Targets](/talemate/user-guide/agents/editor/settings/#automatic-revision-targets) setting. Character and narrator messages are included by default; context-investigation messages (the results of **Look at**, **Investigate**, and **Query**) can be added by enabling their target, which is off by default.
|
||||
|
||||
## Manual revision
|
||||
|
||||
You can also trigger a revision yourself on the most recent message without waiting for automatic revision (or with automatic revision turned off entirely).
|
||||
|
||||
When revision is enabled, hover over the latest character, narrator, or context-investigation message and click the **:material-typewriter: Revise** chip in its toolbar. The chip's label reflects the configured [revision method](/talemate/user-guide/agents/editor/settings/#revision-method) (for example, *Dedupe*, *Unslop*, or *Targeted Rewrite*).
|
||||
|
||||
A revision has one of three outcomes:
|
||||
|
||||
- The text was changed - it's added as a new version of the message; use the message's version paginator to step between the original and the revision.
|
||||
- No changes were needed - the message is left untouched and a status notice confirms it.
|
||||
- The revision failed or was cancelled - the message is left untouched.
|
||||
|
||||
Revisions never overwrite the original. See [Message revision history](/talemate/user-guide/interacting/#message-revision-history) for how to move between versions.
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ Will take the generate message and attempt to add more detail to it.
|
|||
|
||||
## Revision
|
||||
|
||||

|
||||

|
||||
|
||||
When :material-typewriter: revision is enabled the editor will analyze and attempt to fix character messages, narrator messages, and contextual generation (such as character attributes, details, world context, etc.).
|
||||
|
||||
|
|
@ -59,10 +59,15 @@ When automatic revision is enabled, you can choose which types of messages to au
|
|||
|
||||
- **Character Messages** - Automatically revise actor actions and dialogue
|
||||
- **Narration Messages** - Automatically revise narrator actions and descriptions
|
||||
- **Context Investigations** - Automatically revise context-investigation messages (the results of **Look at**, **Investigate**, and **Query** actions). Off by default.
|
||||
- **Contextual generation** - Automatically revise generated context such as character attributes, details, world context, scene intros, etc.
|
||||
- **Summarization** - Automatically revise dialogue summaries.
|
||||
|
||||
By default, both Character Messages and Narration Messages are enabled. You can enable or disable each type independently based on your preferences.
|
||||
|
||||
!!! note "Context investigations always feed the repetition check"
|
||||
Whether or not **Context Investigations** is enabled as an automatic target, context-investigation messages are always included in the text the editor compares against when looking for repetition. This means nearby character and narrator messages will avoid repeating phrases that already appeared in a recent **Look at**, **Investigate**, or **Query** result.
|
||||
|
||||
##### Revision Method
|
||||
|
||||
Which method to use to fix issues.
|
||||
|
|
@ -73,19 +78,19 @@ Which method to use to fix issues.
|
|||
|
||||
**Dedupe (Fast and dumb)**
|
||||
|
||||

|
||||

|
||||
|
||||
When **Dedupe** is active it will be restricted to finding repetition and removing it without replacing it with something else, nor understanding the intent or context, so it may sometimes cause disjointed dialogue. This method is much faster as it will never prompt the AI for analysis and fixes. (If repetition detection is set to semantic similarity, it will still use the embedding function to find repetition, but it will not prompt the AI for analysis and fixes.)
|
||||
|
||||
**Unslop (AI assisted)**
|
||||
|
||||

|
||||

|
||||
|
||||
When **Unslop** is active, it calls 1 additional prompt after a generation and will attempt to remove repetition, purple prose, unnatural dialogue, and over-description. May cause details to be lost. This is a general-purpose cleanup method that can also use unwanted prose detection when enabled.
|
||||
|
||||
**Targeted Rewrite (AI assisted)**
|
||||
|
||||

|
||||

|
||||
|
||||
When **Targeted Rewrite** is active, unwanted prose detection becomes available and when issues are detected the AI will attempt to rewrite the message to fix the issues. This method checks for specific problems first, then only rewrites if enough issues are found.
|
||||
|
||||
|
|
@ -121,6 +126,13 @@ The minimum length of a phrase (in characters) to be considered for repetition.
|
|||
|
||||
Once switched to either **Unslop** or **Targeted Rewrite** mode, additional settings become available.
|
||||
|
||||
#### Repetition handling
|
||||
|
||||
Controls what the AI-assisted revision does when it detects repetition. (Available for both **Unslop** and **Targeted Rewrite**.)
|
||||
|
||||
- **Remove** (default) - flagged repetitions are deleted from the text. This is the safer choice for weaker models, which often struggle to substitute genuinely different content and end up rephrasing the same idea, re-introducing the very repetition the rule is meant to fix.
|
||||
- **Attempt rewrite** - the editor asks the model to replace flagged repetitions with genuinely different content rather than deleting them. Because matches are based on meaning (not just wording), simply rephrasing the same idea is not enough - the underlying beat has to change. When the model cannot produce a meaningful rewrite, it falls back to removing the repetition. This works best with stronger models.
|
||||
|
||||
#### Preferences for Rewriting (Targeted Rewrite only)
|
||||
|
||||
##### Test parts of sentences, split on commas
|
||||
|
|
|
|||
|
|
@ -40,4 +40,8 @@ Handles TTS generation. Currently supports ElevenLabs and OpenAI backends.
|
|||
|
||||
### World State
|
||||
|
||||
Keeps track of the current world state and reinforces specific character states.
|
||||
Keeps track of the current world state and reinforces specific character states.
|
||||
|
||||
## Per-scene overrides
|
||||
|
||||
Most agent settings are global and apply to every scene. You can also override selected settings for a single scene without changing your global configuration — see [Per-Scene Agent Overrides](/talemate/user-guide/agents/scene-overrides).
|
||||
65
docs/user-guide/agents/scene-overrides.md
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
# Per-Scene Agent Overrides
|
||||
|
||||
Every agent has a set of global settings that apply to all of your scenes. Sometimes a single scene needs different behavior — a longer conversation length, a different narration style, or an action turned off — without you having to change your global configuration and remember to change it back afterwards.
|
||||
|
||||
**Per-scene agent overrides** let you do exactly that. You can override selected agent settings for the current scene only. Anything you don't override keeps using your global configuration.
|
||||
|
||||
## How overrides work
|
||||
|
||||
Overrides are **sparse**: only the specific fields you choose to override are stored. Everything else falls through to the global agent settings. This means that if you later change a global setting, scenes pick up that change automatically — unless they have an active override for that particular field.
|
||||
|
||||
Each overridden field is independent. You can override the conversation length for a scene while leaving its format, client, and every other setting on the global value.
|
||||
|
||||
## Editing overrides: the Global / Scene switch
|
||||
|
||||
Overrides are edited in the same place as global settings — the **agent modal** (opened by clicking an agent in the agent panel).
|
||||
|
||||
When a scene is loaded and the agent has at least one setting that supports overrides, a **Global / Scene** switch appears at the top of the modal:
|
||||
|
||||
- **Global** — the normal view. Changes here affect every scene.
|
||||
- **Scene** — the override view. Changes here apply only to the current scene.
|
||||
|
||||
A small number next to the **Scene** button shows how many overrides are currently active for that agent.
|
||||
|
||||
!!! note
|
||||
The switch only appears while a saved scene is loaded. Overrides need a scene (and its project folder) to be stored in, so they aren't available on the placeholder/empty scene.
|
||||
|
||||
### Activating an override for a field
|
||||
|
||||
In **Scene** mode, each overridable setting has a small link icon next to it:
|
||||
|
||||
- :material-link-variant-off: **Inheriting global** — the field is using the global value and is read-only. Click the icon to start overriding it.
|
||||
- :material-link-variant: **Override active** — the field is overriding the global value for this scene. Edit it freely, or click the icon again to go back to inheriting the global value.
|
||||
|
||||
When you activate an override, the field starts out seeded with the current global value, so you always begin from a known state.
|
||||
|
||||
Some agents also let you override whether an entire action is **enabled** for the scene, using the same link icon next to the action's enable checkbox.
|
||||
|
||||
In Scene mode, the modal only shows the settings (and tabs) that actually support overriding, to keep the view focused. If an agent has no overridable settings at all, the Global / Scene switch won't appear.
|
||||
|
||||
### Saving
|
||||
|
||||
Overrides are saved automatically when you close the agent modal, the same way global settings are. If the scene doesn't yet have an overrides file (see below), you'll be asked to name one the first time you save an override.
|
||||
|
||||
## The overrides file
|
||||
|
||||
Per-scene overrides are stored in a JSON file inside an `agent-settings/` folder in the scene's project directory. The default file name is `agent-settings.json`.
|
||||
|
||||
A few things worth knowing:
|
||||
|
||||
- **Overrides are project-level.** The `agent-settings/` folder lives with the project, so every save file in the same project (including **Save As** copies and restore points) shares the same overrides. Different projects have completely independent overrides.
|
||||
- **Overrides travel with exports.** When you export a scene, the `agent-settings/` folder is included, so your overrides survive being shared with or imported on another system.
|
||||
- **Bad files fall back safely.** If an overrides file is missing or can't be read, the scene simply falls back to your global configuration and the link is cleared.
|
||||
|
||||
## Choosing, swapping, or opting out
|
||||
|
||||
Which overrides file a scene uses is controlled from **World Editor → Scene → Settings**, in the **Agent settings file** dropdown. See [Scene Settings](/talemate/user-guide/world-editor/scene/settings#agent-settings-file) for the full description. In short, you can:
|
||||
|
||||
- **Auto-link (default)** — the scene automatically uses `agent-settings.json` if one exists in the project. This is the normal behavior. The first override you set in the agent modal creates this file.
|
||||
- **Pick a specific file** — link the scene to a particular file in the project's `agent-settings/` folder. This lets a project hold more than one overrides file and switch between them.
|
||||
- **None (opt out)** — disable per-scene overrides entirely for this scene. The scene uses global configuration only and won't auto-link to a default file.
|
||||
|
||||
## Related
|
||||
|
||||
- [Scene Settings](/talemate/user-guide/world-editor/scene/settings) — where the overrides file is chosen, swapped, or opted out.
|
||||
- [Agents overview](/talemate/user-guide/agents/) — the global settings that overrides fall back to.
|
||||
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
Pocket TTS is a local CPU-based text-to-speech model from [Kyutai](https://kyutai.org/) that supports voice cloning from audio files. Unlike other local TTS options that require a GPU, Pocket TTS runs efficiently on your CPU, making it accessible on a wider range of hardware.
|
||||
|
||||

|
||||

|
||||
|
||||
## Key Features
|
||||
|
||||
|
|
@ -23,12 +23,20 @@ The first time you generate audio with Pocket TTS, it will automatically downloa
|
|||
Voice cloning requires accepting the model terms on Hugging Face. If voice cloning downloads are blocked:
|
||||
|
||||
1. Visit the [Pocket TTS model page](https://huggingface.co/kyutai/pocket-tts) and accept the terms
|
||||
2. Create a [Hugging Face access token](https://huggingface.co/settings/tokens)
|
||||
3. Set the token in your environment as `HF_TOKEN`
|
||||
4. Restart Talemate
|
||||
2. Create a [Hugging Face access token](https://huggingface.co/settings/tokens) (a read token is sufficient)
|
||||
3. Add the token to Talemate (see [HuggingFace Token](#huggingface-token) below)
|
||||
4. Try generating again
|
||||
|
||||
## Configuration
|
||||
|
||||
##### HuggingFace Token
|
||||
|
||||
!!! info "Added in 0.38.0"
|
||||
|
||||
Optional. Only needed if the voice-cloning model download is gated by Hugging Face. Paste a [Hugging Face access token](https://huggingface.co/settings/tokens) here and Talemate will use it when downloading the model weights.
|
||||
|
||||
This is the same setting as the token on the [HuggingFace application settings page](../../app-settings/application.md#huggingface-token) — set it in either place. A read token is sufficient, and you still need to accept the model terms on Hugging Face with the same account (see [First-Time Setup](#first-time-setup)).
|
||||
|
||||
##### Language / Model
|
||||
|
||||
Selects which Pocket TTS model to load. English uses a fast 6-layer distilled model; the other languages use full 24-layer models for higher quality at the cost of slower generation. All models run locally on CPU (or GPU if available).
|
||||
|
|
@ -150,7 +158,7 @@ If the model fails to download:
|
|||
|
||||
- Check your internet connection
|
||||
- Verify you have accepted the terms on [Hugging Face](https://huggingface.co/kyutai/pocket-tts)
|
||||
- Make sure your `HF_TOKEN` environment variable is set correctly
|
||||
- Make sure your [HuggingFace Token](#huggingface-token) is set correctly
|
||||
- Try restarting Talemate
|
||||
|
||||
### Voice Cloning Not Working
|
||||
|
|
|
|||
|
|
@ -1,16 +1,54 @@
|
|||
# Settings
|
||||
|
||||
## General
|
||||
## Update World State
|
||||
|
||||

|
||||

|
||||
|
||||
##### Update world state
|
||||
|
||||
Will attempt to update the [world state snapshot](/talemate/user-guide/world-state/) based on the current scene. Runs automatically every N turns.
|
||||
Will attempt to update the [world state snapshot](/talemate/user-guide/world-state/) based on the current scene. Runs automatically every N character turns.
|
||||
|
||||
###### When a new scene is started
|
||||
|
||||
Whether to generate an initial snapshot as soon as a scene is loaded. On by default.
|
||||
|
||||
###### Turns
|
||||
|
||||
How many turns to wait before the world state is updated.
|
||||
How many character turns to wait before the snapshot is refreshed. Each player or AI turn counts (not full rounds), so on a scene with several characters the snapshot refreshes more often than the number alone might suggest. Defaults to 10.
|
||||
|
||||
###### Lines in the moment
|
||||
|
||||
How many of the most recent messages count as the "current moment". These are the lines the snapshot anchors to, and they are the messages that can show inline entity highlights. Keeping this small keeps the highlights tied to the active beat while the rest of the scene is still used as background context.
|
||||
|
||||
###### Include Look at / Add Detail
|
||||
|
||||
When on, **Look at** and **Add Detail** results also count as part of the current moment and can receive inline highlights. Off by default.
|
||||
|
||||
###### Custom instructions
|
||||
|
||||
Free-form instructions that steer what the snapshot focuses on. Use this to nudge the agent toward (or away from) certain kinds of detail. Empty by default.
|
||||
|
||||
###### Add Detail length
|
||||
|
||||
How long an **Add Detail** result can be. Shorter lengths keep the generated description tighter; longer lengths allow more elaboration.
|
||||
|
||||
###### Pin to context
|
||||
|
||||
When on, the snapshot is pinned into the conversation, narrator, and scene-analysis prompts as live scene notes, so the tracked entities can inform dialogue, narration, and planning. Off by default. See [Pinning the snapshot to the scene](/talemate/user-guide/world-state/#pinning-the-snapshot-to-the-scene).
|
||||
|
||||
###### Durable snapshot
|
||||
|
||||
When on (the default), each refresh updates only what has changed and carries the rest of the snapshot forward, instead of rebuilding it from scratch every time. This lets the snapshot accumulate detail over the course of a scene. When off, every refresh starts fresh. See [How the snapshot carries forward](/talemate/user-guide/world-state/#how-the-snapshot-carries-forward).
|
||||
|
||||
The two settings below only apply when **Durable snapshot** is on.
|
||||
|
||||
###### Max items tracked
|
||||
|
||||
The maximum number of items the snapshot can hold at once. When a refresh would exceed this, the stalest items are dropped first. Set to `0` for no limit.
|
||||
|
||||
###### Auto-evict stale entries
|
||||
|
||||
Automatically drops a snapshot entry that the agent leaves unchanged for this many refreshes in a row. This guards against stale entries lingering when the agent fails to remove them on its own. Set to `0` to disable.
|
||||
|
||||
##### Update state reinforcements
|
||||
|
||||
|
|
@ -87,3 +125,9 @@ For example, if a character is described as wearing formal attire at a party but
|
|||
- A Visual Agent with an image generation backend configured
|
||||
|
||||
When a new portrait is generated, it is automatically added to the character's portrait collection and tagged based on the scene context.
|
||||
|
||||
## Long Term Memory
|
||||
|
||||
When generating the [world state snapshot](/talemate/user-guide/world-state/), the agent pulls in relevant long-term memory so the snapshot can build on established lore and earlier scene history. Semantic recall is always used and is on by default.
|
||||
|
||||
--8<-- "docs/snippets/tips.md:agent_long_term_memory_settings"
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ The Appearance settings let you customize how messages and visuals are displayed
|
|||
|
||||
## :material-script: Messages
|
||||
|
||||

|
||||

|
||||
|
||||
The Messages tab gives you control over how text appears in the scene feed. You can customize the styling for different message types and special text formatting.
|
||||
|
||||
|
|
@ -39,6 +39,7 @@ You can configure these markup styles:
|
|||
| **Parentheses** | `( )` | (whispering softly) |
|
||||
| **Brackets** | `[ ]` | [Author's note] |
|
||||
| **Emphasis** | `* *` | *dramatic pause* |
|
||||
| **Entity Highlights** | — | clickable [entity highlights](/talemate/user-guide/world-state/#entity-highlights-in-scene-messages) in the latest message |
|
||||
|
||||
For each markup type, you can set:
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,24 @@
|
|||
# :material-application-outline: Application
|
||||
|
||||

|
||||

|
||||
|
||||
Configure various API keys for integration with external services. (OpenAI, Anthropic, etc.)
|
||||
Configure various API keys for integration with external services. (OpenAI, Anthropic, etc.)
|
||||
|
||||
Each external service has its own page in the sidebar. Select a service, paste your key or token, and save.
|
||||
|
||||
## HuggingFace Token
|
||||
|
||||
!!! info "Added in 0.38.0"
|
||||
|
||||
Some features download model weights from [Hugging Face](https://huggingface.co/). Most weights are open and download without any credentials, but a few are **gated** — Hugging Face requires you to be signed in and to have accepted the model's terms before it will let you download them. The Pocket TTS voice-cloning model is one such gated model.
|
||||
|
||||
To download gated weights, add a HuggingFace access token:
|
||||
|
||||
1. Open the **HuggingFace** page under Application settings.
|
||||
2. Create a token at [https://huggingface.co/settings/tokens](https://huggingface.co/settings/tokens). A read token is sufficient.
|
||||
3. Paste it into the **HuggingFace Token** field and save.
|
||||
|
||||
The token is shared across Talemate. Once set here, any feature that needs to download gated weights (such as the [Pocket TTS](../agents/voice/pocket-tts.md) agent) will use it automatically. You can also set the same token directly in the Pocket TTS agent config — both fields point at the same setting.
|
||||
|
||||
!!! note "Accepting model terms"
|
||||
A token only proves who you are. For gated models you still need to visit the model's page on Hugging Face and accept its terms once with the same account before the download will succeed.
|
||||
52
docs/user-guide/app-settings/creator.md
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
# :material-cube-scan: Creator
|
||||
|
||||
The **Creator** tab in the application settings holds shared building blocks that are offered as picker options elsewhere in the UI. Open it from **Settings** (the cogwheel in the top navigation) and switch to the **Creator** tab.
|
||||
|
||||
Two sub-tabs live here:
|
||||
|
||||
- **Content Classification** — the list of content classification strings offered when you set up a scene.
|
||||
- **Perspective Presets** — the list of narrative perspective / tense strings offered in the scene outline.
|
||||
|
||||
Both lists are global to your Talemate installation. Editing them does not change any existing scene — your scenes keep whatever value they were saved with. The lists only affect what appears as suggestions in the pickers next time you edit a field.
|
||||
|
||||
## Perspective Presets
|
||||
|
||||
!!! info "Added in 0.38.0"
|
||||
|
||||
The presets you add here show up in every **Perspective and tense** combobox in the scene outline (default plus the three per-speaker overrides). They are convenience suggestions, not constraints — you can always type a custom value into any of the four fields if no preset fits.
|
||||
|
||||

|
||||
|
||||
### Adding a preset
|
||||
|
||||
1. Type the perspective string into the **Add perspective preset** text field at the bottom of the list.
|
||||
2. Press **Enter** to add it.
|
||||
|
||||
The new entry is appended to the list and becomes available immediately to every scene outline combobox.
|
||||
|
||||
### Removing a preset
|
||||
|
||||
Click the red :material-close-box-outline: icon next to a preset to remove it from the list. Removing a preset does not change scenes that already use that value — it just stops suggesting it.
|
||||
|
||||
### The `{player_name}` placeholder
|
||||
|
||||
Any preset that contains the literal string `{player_name}` will have that substring replaced by the active player character's name at prompt render time. This lets you share presets across scenes without having to rewrite them for each protagonist.
|
||||
|
||||
For example, the preset:
|
||||
|
||||
> First person, present tense, from {player_name}'s POV.
|
||||
|
||||
will be rendered as `First person, present tense, from Annabelle's POV.` in a scene whose player character is named Annabelle, and as `First person, present tense, from Marcus's POV.` in a scene whose player character is named Marcus.
|
||||
|
||||
If a scene has no explicit player character, perspectives that use `{player_name}` are **suppressed** rather than substituted — the placeholder has no anchor to point at. Use a non-placeholder preset for scenes without a player character.
|
||||
|
||||
### Default presets
|
||||
|
||||
Talemate ships with a starter list covering the most common configurations (third / first / second person, past and present tense, omniscient and player-anchored variants). For an explanation of what each default preset means in plain English with a sample of the prose style it produces, see the [Preset reference in the scene outline docs](../world-editor/scene/outline.md#what-each-default-preset-means).
|
||||
|
||||
Treat these as a starting point — add your own house styles (for example a preset that pins POV to a specific named character, or one that includes a tone hint like *Third person limited, past tense, hard-boiled noir voice.*) so they appear in every new scene you create.
|
||||
|
||||
## Related
|
||||
|
||||
- [Scene Outline — Perspective and Tense](../world-editor/scene/outline.md#perspective-and-tense) — where the presets are consumed.
|
||||
- [System Prompt Overrides](system-prompts.md) — for changing the AI's general role and approach (writing style and tense belong in the scene outline, not in a system prompt).
|
||||
|
|
@ -80,7 +80,7 @@ Never acknowledge that characters are fictional or written by an AI. Characters
|
|||
Talemate then sends the full built-in Conversation system prompt followed by your extra instruction.
|
||||
|
||||
!!! note "What belongs in a system prompt"
|
||||
System prompts shape the AI's role and general approach — things that should apply across every scene. Writing style, tense, and scene-specific tone live in the scene's [perspective field](../world-editor/scene/outline.md#perspective-and-tense) and writing-style settings, not here.
|
||||
System prompts shape the AI's role and general approach — things that should apply across every scene. Writing style, tense, and scene-specific tone live in the scene's [perspective fields](../world-editor/scene/outline.md#perspective-and-tense) and writing-style settings, not here.
|
||||
|
||||
Points to know:
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,9 @@ Concurrent requests are available for the following hosted API clients:
|
|||
- [Google Gemini](/talemate/user-guide/clients/types/google/)
|
||||
- [OpenRouter](/talemate/user-guide/clients/types/openrouter/)
|
||||
|
||||
Local clients (KoboldCpp, llama.cpp, etc.) do not support this feature as they typically cannot handle concurrent inference requests.
|
||||
It is also available for the local [llama.cpp](/talemate/user-guide/clients/types/llamacpp/) client. For llama.cpp, your `llama-server` must be started with enough parallel slots to handle more than one request at a time; otherwise the extra requests are simply queued and you will not see a speed-up.
|
||||
|
||||
Other local clients (KoboldCpp, etc.) do not support this feature.
|
||||
|
||||
## How to Enable
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ If you wish to alter the inference parameters sent with the generation requests
|
|||
|
||||
Navigate to the :material-tune: **Presets** tab then select the :material-matrix: **Inference** tab.
|
||||
|
||||

|
||||

|
||||
|
||||
!!! warning
|
||||
Not all clients support all parameters, and generally it is assumed that the client implementation handles the parameters in a sane way, especially if values are passed for all of them. All presets are used and will be selected depending on the action the agent is performing. If you don't know what these mean, it is recommended to leave them as they are.
|
||||
|
|
@ -70,7 +70,7 @@ The inference preset editor provides access to the following generation paramete
|
|||
| Presence Penalty | 0 - 1.0 | Penalizes tokens that have already appeared in the generated text, encouraging discussion of new topics. |
|
||||
| Frequency Penalty | 0 - 1.0 | Penalizes tokens based on how frequently they appear, reducing word repetition. |
|
||||
| Repetition Penalty | 1.0 - 1.2 | Applies a multiplicative penalty to repeated tokens. |
|
||||
| Repetition Penalty Range | 0 - 4096 | Number of tokens to look back when calculating repetition penalty. |
|
||||
| Repetition Penalty Range | 0 - 8192 | Number of tokens to look back when calculating repetition penalty. |
|
||||
|
||||
### Advanced Parameters
|
||||
|
||||
|
|
@ -123,6 +123,24 @@ Different clients support different subsets of these parameters:
|
|||
- **Remote APIs** (OpenAI, Anthropic, etc.): Typically support temperature, top_p, and penalty parameters. Advanced parameters like XTC, DRY, and Adaptive-P are generally not available.
|
||||
- **Other local APIs**: Parameter support varies by implementation.
|
||||
|
||||
## Editing a preset
|
||||
|
||||
Select a preset from the list on the left to load its parameters into the editor on the right. Adjust the sliders, tabs and checkbox to change the values for that preset.
|
||||
|
||||
In the upper right of the editor there are two actions that apply to the preset you currently have selected:
|
||||
|
||||
### Apply to all
|
||||
|
||||
The **Apply to all** action copies the values of the currently selected preset to *every other preset in the same group*. This is useful when you have tuned one preset (for example `Conversation`) and want all the other presets to start from the same values.
|
||||
|
||||
Because this overwrites the values of all the other presets in the group, you will be asked to confirm before it happens.
|
||||
|
||||
### Reset
|
||||
|
||||
The **Reset** action restores the currently selected preset back to its default values. As of version 0.38.0 this action also asks for confirmation before resetting, so an accidental click no longer discards your changes.
|
||||
|
||||
Both actions only change the values in the editor. Remember to save the settings with the **Save** button at the bottom of the dialog for them to take effect.
|
||||
|
||||
## Preset Groups
|
||||
|
||||
Initially there is a `Default` group in which the presets are edited, but if you want you can create additional groups to create - for example - model / client specific presets.
|
||||
|
|
|
|||
|
|
@ -66,6 +66,47 @@ When the configured reasoning pattern is not found in a response, you can contro
|
|||
- **Fail** (default) - Raises an error, causing the request to fail. Use this when you expect the model to always include reasoning tokens and want to be alerted if it doesn't.
|
||||
- **Ignore** - Returns the response as-is without stripping anything. Use this when the model may sometimes respond without reasoning tokens (e.g., for simple queries).
|
||||
|
||||
## Forcing Reasoning Off for Specific Actions
|
||||
|
||||
The **Enable Reasoning** checkbox is a global setting for a client — when it's on, every prompt that client handles uses reasoning. Sometimes that isn't what you want. A reasoning model might do an excellent job writing dialogue but waste time (and tokens) "thinking" before simple, mechanical tasks like summarization or world-state updates.
|
||||
|
||||
Per-action reasoning overrides let you turn reasoning **off for individual agent actions** without touching the client's global setting. The client keeps reasoning on everywhere else; only the actions you single out skip it.
|
||||
|
||||
### Adding an Override
|
||||
|
||||
Overrides are created from a prompt's detail view, which you can reach two ways:
|
||||
|
||||
- **Prompt Manager** (recommended): Open the **Prompts** tab from the main navigation (the :material-file-code-outline: icon). In the sidebar, click a recent prompt under the **Prompts** list to open it.
|
||||
- **Debug Tools**: Open the **Debug Tools** panel (the :material-bug: icon in the top toolbar) and go to the **Prompts** tab, then click a prompt.
|
||||
|
||||
Both routes open the same prompt detail view. Once it's open:
|
||||
|
||||
1. Find the prompt's header, which shows which agent and action produced it (for example **summarizer** with an **action** chip).
|
||||
2. Click the :material-brain: brain icon next to the action. It turns red to show reasoning is now forced off for that action.
|
||||
|
||||
From now on, every time that same agent action runs, Talemate tells the client to skip reasoning for that single call.
|
||||
|
||||
To remove an override, click the red brain icon again.
|
||||
|
||||
### Managing All Overrides
|
||||
|
||||
Once you have at least one override active, a counter button appears next to the **Agents** heading in the right-hand agent list. Click it to open the **Agent action overrides** dialog, where you can:
|
||||
|
||||
- See every action that currently has an override, grouped by agent.
|
||||
- Toggle **Disable reasoning** on or off for each one.
|
||||
- Remove an override entirely with the :material-close: button.
|
||||
|
||||

|
||||
|
||||
### How It Relates to the Global Setting
|
||||
|
||||
- Overrides only ever **turn reasoning off**. They cannot turn reasoning on for a client that has it disabled.
|
||||
- They are saved with your application configuration and persist across restarts. They apply to whichever client happens to run that action.
|
||||
- If a model **always** reasons and cannot be told to stop (for example certain Gemini and OpenAI reasoning models), the override is ignored for that client — those models reason no matter what.
|
||||
|
||||
!!! note "Test Changes ignores overrides"
|
||||
The **Test Changes** button in the prompt detail view always runs with the client's default reasoning setting, so you can compare a one-off result against your normal configuration. The per-action override is not applied during a test run.
|
||||
|
||||
## Model Compatibility
|
||||
|
||||
Not all models support reasoning. This feature works best with:
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ The llama.cpp client connects to the `llama-server` executable from the llama.cp
|
|||
|
||||
If you want to add a llama.cpp client, change the `Client Type` to `llama.cpp`.
|
||||
|
||||

|
||||

|
||||
|
||||
!!! note "Should work out of the box with a local llama.cpp server"
|
||||
The default values should work with a local llama.cpp server if you are running `llama-server` on the default port (8080).
|
||||
|
|
@ -41,6 +41,12 @@ If your llama.cpp server is configured to require authentication, you can set th
|
|||
|
||||
The number of tokens to use as context when generating text. Defaults to `8192`.
|
||||
|
||||
##### Concurrent Inference
|
||||
|
||||
Found under the **Concurrency** tab in the client settings. When enabled, batch operations that need several queries (currently visual prompt generation for image generation) can send multiple requests to your `llama-server` in parallel instead of one at a time, which can speed those operations up.
|
||||
|
||||
This is **off by default**. Your `llama-server` must be started with enough parallel slots to actually serve requests at the same time; otherwise the requests are queued and you will not see a speed-up. See the [Concurrent Requests](/talemate/user-guide/clients/concurrent-requests/) page for more detail.
|
||||
|
||||
### Common issues
|
||||
|
||||
#### Generations are weird / bad
|
||||
|
|
|
|||
|
|
@ -58,6 +58,18 @@ mistralai/Mixtral-8x22B-Instruct-v0.1
|
|||
|
||||
The number of tokens to use as context when generating text. Defaults to `8192`.
|
||||
|
||||
### Parameters
|
||||
|
||||
The **Parameters** tab in the client settings lets you control which sampler parameters are sent with each request. Some OpenAI-compatible services reject requests that include parameters they don't support for the selected model, returning an error instead of a generation. If you run into this, you can turn the offending parameter off so it is left out of the request entirely.
|
||||
|
||||
Each parameter has its own toggle:
|
||||
|
||||
- **Send temperature**
|
||||
- **Send top_p**
|
||||
- **Send presence_penalty**
|
||||
|
||||
All three are enabled by default. Turning a toggle off omits that parameter from the request completely (it is not sent as a zero value). Leave them enabled unless the service you are connecting to errors when it receives one of them.
|
||||
|
||||
### Ready to use
|
||||
|
||||
Click `Save` to add the client.
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@ The Prompts tab shows a log of all AI prompts that have been sent during your se
|
|||
|
||||
For headless captures or longer-running debug sessions, the same prompt records can also be streamed to a file — see [Prompt Logging](../getting-started/advanced/prompt-logging.md).
|
||||
|
||||
The prompt detail view also lets you force reasoning off for the specific agent action that produced a prompt, using the :material-brain: brain icon next to the action — see [Forcing Reasoning Off for Specific Actions](clients/reasoning.md#forcing-reasoning-off-for-specific-actions).
|
||||
|
||||
### :material-memory: Memory
|
||||
|
||||
The Memory tab displays memory retrieval requests made by the Memory Agent. Use this to verify that relevant context is being retrieved during generation.
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ After a moment of loading you will be taken to the new scene and `creative` mode
|
|||
|
||||
## Create the outline for the scene
|
||||
|
||||
--8<-- "docs/talemate/user-guide/world-editor/scene/outline.md:outline"
|
||||
--8<-- "docs/user-guide/world-editor/scene/outline.md:outline"
|
||||
|
||||
## Save the scene
|
||||
|
||||
|
|
|
|||
|
|
@ -10,13 +10,13 @@ Click it and wait a moment for the blank scene to load.
|
|||
|
||||
Click the **:material-earth-box: World Editor** tab.
|
||||
|
||||
Fill in `Title`, `Description` and `Content Context`
|
||||
Fill in `Title`, `Description` and `Content Classification`
|
||||
|
||||
---
|
||||
|
||||
**Title**: `Infinity Quest Dynamic`
|
||||
|
||||
**Content Context**: `an epic sci-fi adventure`
|
||||
**Content Classification**: `an epic sci-fi adventure`
|
||||
|
||||
**Description**:
|
||||
```
|
||||
|
|
|
|||
|
|
@ -54,6 +54,36 @@ For more information on using the Director chat, see the [Director Chat document
|
|||
|
||||
When using the autonomous scene direction feature, the Director can automatically generate images at appropriate moments during scene progression. These images appear in the scene feed just like manually generated ones.
|
||||
|
||||
### Context Investigation Messages
|
||||
|
||||
Context investigation messages are the short, descriptive results that appear in your scene feed when you take a closer look at something. They are produced by actions such as:
|
||||
|
||||
- **Look at Scene** — a visually focused description of the current moment (from the scene tools narrator menu)
|
||||
- **Look at (Character)** — a description of a character's appearance and current action (from the scene tools narrator menu or the [World State](world-state.md) sidebar)
|
||||
- **Add Detail** — an expanded "closer look" at an entity (character, place, or item) you have selected in the scene
|
||||
|
||||
When you hover over one of these messages, a **Visualize** action appears in the message toolbar. Clicking it generates an image directly into that message, matched to whatever the investigation was about.
|
||||
|
||||
#### How the image is matched to the subject
|
||||
|
||||
Talemate looks at what the investigation was about and chooses the most fitting image type automatically. You don't need to pick one yourself:
|
||||
|
||||
| Investigation | Image generated |
|
||||
|---------------|-----------------|
|
||||
| Look at Scene | Scene illustration of the current moment |
|
||||
| Look at (Character) | Character card portrait of that character |
|
||||
| Add Detail on a character in the scene | Character card portrait of that character |
|
||||
| Add Detail on a character not in the scene | Scene illustration |
|
||||
| Add Detail on a place | Scene background |
|
||||
| Add Detail on an item | Object illustration |
|
||||
|
||||
The text of the investigation message is used to guide the generated image, so the result reflects the specific details described in that message.
|
||||
|
||||
!!! note "Query results are not visualizable"
|
||||
A plain **Query** (asking the narrator a free-form question) does not show a Visualize action, because there is no single visual subject to match it to.
|
||||
|
||||
Once an image has been generated, the **Visualize** action disappears for that message. From that point on you can regenerate, replace, or remove the image using the [inline visual actions](#viewing-and-managing) described below, just like any other attached image.
|
||||
|
||||
## Interacting with Inline Visuals
|
||||
|
||||
Once an image appears in your scene feed, you can interact with it in several ways.
|
||||
|
|
|
|||
|
|
@ -82,6 +82,42 @@ You can turn this off by disabling the auto progress setting, either in the game
|
|||
A set of tools to help you interact with the scenario. Find out more about the various actions in the [Scene Tools](/talemate/user-guide/scenario-tools) section of the user guide.
|
||||
|
||||
|
||||
## Message revision history
|
||||
|
||||
!!! info "New in 0.38.0"
|
||||
|
||||
Character and narrator messages (and context investigation results) keep a history of their previous versions. When a message has more than one version, a small paginator appears just above the message body so you can browse through them.
|
||||
|
||||

|
||||
|
||||
The paginator shows:
|
||||
|
||||
- **Left / right arrows** to step between versions.
|
||||
- A **counter** (for example `2/3`) telling you which version you are viewing and how many exist in total.
|
||||
- A **tag** describing where the version you are currently looking at came from:
|
||||
- **Original** -- the message as it was first generated.
|
||||
- **Regenerated** -- a version produced by regenerating the message.
|
||||
- **Revised** -- a version that the [Editor agent](/talemate/user-guide/agents/editor) automatically rewrote.
|
||||
- **Continued** -- a version created by continuing the message (see below).
|
||||
|
||||
The paginator only appears on the **most recent** message, and only once that message has more than one version.
|
||||
|
||||
!!! note "The version you view is the one that sticks"
|
||||
Whichever version you have selected in the paginator becomes the message's active text. That is the version saved with the scene, and the version the AI builds on when it continues the scene. Browsing to an earlier version and leaving it selected effectively rolls the message back to that version.
|
||||
|
||||
### How new versions are created
|
||||
|
||||
You don't add versions manually -- they accumulate as you work with a message:
|
||||
|
||||
- **Regenerating** the most recent AI message (see [Regenerate AI response](/talemate/user-guide/scenario-tools#material-refresh-regenerate-ai-response)) keeps the message in place and adds the new result as a version instead of replacing the old text. The previous version is still there to navigate back to. If the Editor agent automatically revises the regenerated text, both the raw **Regenerated** version and the **Revised** version are kept so you can pick either one.
|
||||
- **Continuing** a message adds a **Continued** version that contains the original text plus the newly generated continuation. The version you continued from stays available, so you can step back if you don't like how the continuation turned out.
|
||||
|
||||
### Continuing a message
|
||||
|
||||
The most recent character or narrator message offers a **:material-fast-forward: Continue** action on its hover toolbar.
|
||||
|
||||
Clicking **Continue** generates more text and appends it to the message, recording the result as a new **Continued** version in the revision history. Narrator messages support the Continue action as well as character messages.
|
||||
|
||||
## Cancel Generation
|
||||
|
||||
Sometimes Talemate will be generating a response (or go through a chain of generations) and you want to cancel it. You can do this by hitting the **:material-stop-circle-outline:** button that will appear in the scene tools bar.
|
||||
|
|
|
|||
|
|
@ -15,10 +15,34 @@ There currently are no typed event emission nodes, so you will need to use the `
|
|||
|
||||
You can find the various event payloads in the [reference](../reference/events.md).
|
||||
|
||||
Once your event module is saved, you enable it by adding its node to the scene loop of your scene.
|
||||
## Activating an event module
|
||||
|
||||
There are two ways to make an event module start listening for its event.
|
||||
|
||||
### Add it to the scene loop
|
||||
|
||||
Once your event module is saved, add its node to the scene loop of your scene.
|
||||
|
||||
Once added to the scene loop you must also specify the `event_name`.
|
||||
|
||||
This places the module on the scene loop graph, where you can see it, wire additional inputs to it, and disable it again by removing it.
|
||||
|
||||
### Auto-register
|
||||
|
||||
Instead of placing the module on the scene loop graph, you can have it subscribe to its event automatically as soon as it is registered with the scene.
|
||||
|
||||
To do this, open the module's **Properties** panel and:
|
||||
|
||||
- Set `event_name` to the event you want to listen for.
|
||||
- Enable `auto_register`.
|
||||
|
||||
Both values are saved on the module definition itself, so they must be set inside the module (not on a placed instance). When the scene loads, every registered event module with `auto_register` enabled and a non-empty `event_name` is connected to the event bus automatically — you do **not** need to add it to the scene loop.
|
||||
|
||||
!!! note "Auto-register requires a saved `event_name`"
|
||||
Because auto-registration reads the persisted properties of the module, an auto-registered module that has no `event_name` set is skipped. Make sure both `auto_register` and `event_name` are set and the module is saved.
|
||||
|
||||
This works the same way [command modules](command_module.md) are loaded automatically when a scene loads, and is the recommended approach for event modules that should always be active and that do not need any inputs wired in from the scene loop graph.
|
||||
|
||||
|
||||
## Practical Example
|
||||
|
||||
|
|
|
|||
|
|
@ -108,6 +108,8 @@ The canvas is the main area where you can add, connect and edit nodes.
|
|||
|
||||
Certain nodes can log messages to the log watcher. It is located in the upper right corner of the editor.
|
||||
|
||||
Each entry shows a right-aligned `HH:MM:SS.mmm` timestamp, making it easier to correlate log entries with scene activity.
|
||||
|
||||

|
||||
|
||||
### Toolbar
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 20 KiB |
|
|
@ -37,6 +37,9 @@ This will regenerate the most recent message, if it is an AI generated message.
|
|||
If you hold `ctrl+alt` when clicking this button you will be prompted to supply some instructions for the
|
||||
regeneration while keeping the original message as context. This is useful for rewrites.
|
||||
|
||||
!!! info "Previous versions are kept"
|
||||
Regenerating doesn't throw away the old message -- each result is added to the message's revision history, which you can browse with the paginator above the message. See [Message revision history](/talemate/user-guide/interacting#message-revision-history).
|
||||
|
||||
#### :material-nuke: Regenerate AI Response (nuke option)
|
||||
|
||||
This will regenerate the most recent message, if it is an AI generated message, but with a higher temperature and repetition penalties applied, which can lead to more creative responses. Use this to break out of repetitive loops.
|
||||
|
|
@ -194,7 +197,7 @@ Allows you to quickly set up tracked character and world states.
|
|||
|
||||
!!! info "What is a tracked state?"
|
||||
|
||||
--8<-- "docs/talemate/user-guide/tracking-a-state.md:what-is-a-tracked-state"
|
||||
--8<-- "docs/user-guide/tracking-a-state.md:what-is-a-tracked-state"
|
||||
|
||||
Please refer to the [World State](/talemate/user-guide/world-state) section for more information on how set up custom states to track.
|
||||
<!--- --8<-- [start:quick-apply-favorite-state] -->
|
||||
|
|
@ -283,7 +286,7 @@ Write direction on how you want the character to enter the scene.
|
|||
|
||||
##### Templates
|
||||
|
||||
Control attribute generation using your existing [World State Templates](/talemate/user-guide/world-editor/templates).
|
||||
Control attribute generation using your existing [World State Templates](/talemate/user-guide/templates).
|
||||
|
||||

|
||||
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ Stores [node editor](/talemate/user-guide/node-editor/) graphs for the scene, su
|
|||
|
||||
### `templates/`
|
||||
|
||||
Scene-specific [templates](/talemate/user-guide/world-editor/templates/writing-style/) that override or extend the default templates. These are organized into `scene/`, `common/`, and agent-specific subdirectories.
|
||||
Scene-specific [templates](/talemate/user-guide/templates/writing-style/) that override or extend the default templates. These are organized into `scene/`, `common/`, and agent-specific subdirectories.
|
||||
|
||||
### `shared-context/`
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ They are used in the [Character Editor - Attributes](/talemate/user-guide/world-
|
|||
|
||||
## Creating a character attribute template
|
||||
|
||||
Fist, if you have not done so, [create a template group](/talemate/user-guide/world-editor/templates/groups) to store the template in.
|
||||
Fist, if you have not done so, [create a template group](/talemate/user-guide/templates/groups) to store the template in.
|
||||
|
||||
Then select the group you want to add the template to and click the **:material-plus: Create Template** button.
|
||||
|
||||
|
|
@ -6,7 +6,7 @@ They are used in the [Character Editor - Details](/talemate/user-guide/world-edi
|
|||
|
||||
## Creating a character detail template
|
||||
|
||||
Fist, if you have not done so, [create a template group](/talemate/user-guide/world-editor/templates/groups) to store the template in.
|
||||
Fist, if you have not done so, [create a template group](/talemate/user-guide/templates/groups) to store the template in.
|
||||
|
||||
Then select the group you want to add the template to and click the **:material-plus: Create Template** button.
|
||||
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
# World Editor Templates
|
||||
# Templates
|
||||
|
||||
Open the **:material-earth-box: World Editor** and select the **:material-cube-scan: Templates** tab to manage templates.
|
||||
Click the **:material-cube-scan: Templates** tab in the top navigation bar to manage templates.
|
||||
|
||||
These templates are used to facilitate the generation of content for your game. They can be used to define character attributes, character details, writing styles, and automated world or character state tracking.
|
||||
|
||||
|
|
@ -4,7 +4,7 @@ Spice collections are used to define a set of instructions that can be applied d
|
|||
|
||||
## Creating a spice collection
|
||||
|
||||
Fist, if you have not done so, [create a template group](/talemate/user-guide/world-editor/templates/groups) to store the template in.
|
||||
Fist, if you have not done so, [create a template group](/talemate/user-guide/templates/groups) to store the template in.
|
||||
|
||||
Then select the group you want to add the template to and click the **:material-plus: Create Template** button.
|
||||
|
||||
|
|
@ -7,7 +7,7 @@ They are used in the [Character Editor - Tracked States](/talemate/user-guide/wo
|
|||
|
||||
## Creating a state reinforcement template
|
||||
|
||||
Fist, if you have not done so, [create a template group](/talemate/user-guide/world-editor/templates/groups) to store the template in.
|
||||
Fist, if you have not done so, [create a template group](/talemate/user-guide/templates/groups) to store the template in.
|
||||
|
||||
Then select the group you want to add the template to and click the **:material-plus: Create Template** button.
|
||||
|
||||
|
|
@ -61,7 +61,7 @@ Specifies what type of object the state is attached to, currently this can be
|
|||
|
||||
### Context Attachment Method
|
||||
|
||||
--8<-- "docs/talemate/user-guide/tracking-a-state.md:context-attachment-method"
|
||||
--8<-- "docs/user-guide/tracking-a-state.md:context-attachment-method"
|
||||
|
||||
### Update every `N` turns
|
||||
|
||||
|
|
@ -37,9 +37,9 @@ Then follow the instructions at [Tracking a world state](/talemate/user-guide/wo
|
|||
|
||||
## Quickly apply often tracked states via templates
|
||||
|
||||
--8<-- "docs/talemate/user-guide/scenario-tools.md:tools-ux"
|
||||
--8<-- "docs/user-guide/scenario-tools.md:tools-ux"
|
||||
|
||||
--8<-- "docs/talemate/user-guide/scenario-tools.md:quick-apply-favorite-state"
|
||||
--8<-- "docs/user-guide/scenario-tools.md:quick-apply-favorite-state"
|
||||
|
||||
## Context Attachment Method
|
||||
<!-- --8<-- [start:context-attachment-method] -->
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ nav:
|
|||
- Details: details.md
|
||||
- Folders: folders.md
|
||||
- Import a character: import.md
|
||||
- Player character: player.md
|
||||
- Tracked states: states.md
|
||||
- Visuals: visuals.md
|
||||
- ...
|
||||
|
|
@ -37,4 +37,10 @@ Here it can be especially helpful to run the generation with instructions. To do
|
|||
|
||||
A small window will pop up where you can provide the instructions for the AI to follow.
|
||||
|
||||

|
||||

|
||||
|
||||
#### Autocomplete an example
|
||||
|
||||
The **Add Dialogue Example** field also supports autocomplete. Start typing an example, then press `ctrl+Enter` (or `cmd+Enter` on macOS) to have the AI continue it for you. This field supports the same `{...}` hints and Redo/Undo actions as other generated fields.
|
||||
|
||||
See [Autocomplete](/talemate/user-guide/agents/creator/autocomplete) for more information.
|
||||
|
|
@ -37,7 +37,7 @@ You will be asked to confirm the removal. Press the **:material-close-box-outlin
|
|||
|
||||
## Generating attributes using templates
|
||||
|
||||
You can use [templates](/talemate/user-guide/world-editor/templates/attribute) to quickly generate attributes for your characters.
|
||||
You can use [templates](/talemate/user-guide/templates/attribute) to quickly generate attributes for your characters.
|
||||
|
||||
In the **Attributes** tab, click the **:material-cube-scan: Templates** button above the attribute list to expand the templates list.
|
||||
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ If a pin already exists for the selected detail, the button will display :materi
|
|||
|
||||
## Generating details using templates
|
||||
|
||||
You can use [templates](/talemate/user-guide/world-editor/templates/detail) to quickly generate details for your characters.
|
||||
You can use [templates](/talemate/user-guide/templates/detail) to quickly generate details for your characters.
|
||||
|
||||
In the **Details** tab, click the **:material-cube-scan: Templates** button above the detail list to expand the templates list.
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ You can create and remove characters, manage their details, and track their stat
|
|||
|
||||
Characters can also be temporarily disabled, which will prevent them from being included in the scene' dialogue generation. (e.g., they are out of the scene for a moment.)
|
||||
|
||||
You can also change which character is [controlled by the player](/talemate/user-guide/world-editor/characters/player) at any time.
|
||||
|
||||
The character list can optionally be organized into collapsible [folders](/talemate/user-guide/world-editor/characters/folders).
|
||||
|
||||
## Character Components
|
||||
|
|
@ -28,7 +30,7 @@ When a **:material-image-auto-adjust: state reinforcment** is updated the value
|
|||
|
||||
### :material-image-auto-adjust: [Tracked states](/talemate/user-guide/world-editor/characters/states)
|
||||
|
||||
--8<-- "docs/talemate/user-guide/tracking-a-state.md:what-is-a-tracked-state"
|
||||
--8<-- "docs/user-guide/tracking-a-state.md:what-is-a-tracked-state"
|
||||
|
||||
### :material-bullhorn: [Actor management](/talemate/user-guide/world-editor/characters/actor)
|
||||
|
||||
|
|
|
|||
34
docs/user-guide/world-editor/characters/player.md
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
# Make or Unmark a Player Character
|
||||
|
||||
Every scene can have one character that is controlled by you, the player. All other characters are controlled by the AI. From the character editor you can change which character is the player at any time, without having to recreate anyone.
|
||||
|
||||
A character's current role is shown next to their name in the character list:
|
||||
|
||||
- A :material-label: **Player** chip marks the character you are controlling.
|
||||
- A :material-label: **AI** chip marks a character controlled by the AI.
|
||||
|
||||
## Make a character the player
|
||||
|
||||
To promote a character to the player, first select the character on the left hand side in the :material-earth-box: **World Editor** under the :material-account-group: **Characters** tab.
|
||||
|
||||
Then click on the :material-account-star: **Make Player Character** button, beneath the character's image.
|
||||
|
||||
This does two things at once:
|
||||
|
||||
- The selected character becomes the player character.
|
||||
- If another character was already the player, they are demoted to an AI actor. They stay in the scene and simply continue as an AI controlled character.
|
||||
|
||||
If the character you promote is currently [deactivated](/talemate/user-guide/world-editor/characters/deactivate), they are automatically activated and brought into the scene as the player.
|
||||
|
||||
Only one character can be the player at a time, so there is never any need to unmark the previous player yourself.
|
||||
|
||||
## Unmark the player character
|
||||
|
||||
To turn the current player into an AI controlled character, select that character under the :material-account-group: **Characters** tab.
|
||||
|
||||
Then click on the :material-account-off-outline: **Unmark as Player** button, beneath the character's image.
|
||||
|
||||
The character remains in the scene and keeps all of their details; they are simply handed over to the AI. After this, the scene has no player character until you promote one.
|
||||
|
||||
!!! note
|
||||
Whether a character is the player can also be set when you first [create a character](/talemate/user-guide/world-editor/characters/create) using the **Controlled by Player** switch.
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
!!! info "What is a tracked state?"
|
||||
|
||||
--8<-- "docs/talemate/user-guide/tracking-a-state.md:what-is-a-tracked-state"
|
||||
--8<-- "docs/user-guide/tracking-a-state.md:what-is-a-tracked-state"
|
||||
|
||||
## Setting up a new state
|
||||
In the :material-account-group: **Character** editor select the character you want to add a new state to.
|
||||
|
|
@ -43,7 +43,7 @@ By default it will be `10` turns, but you can change this to any number you like
|
|||
|
||||
### Context Attachment Method
|
||||
|
||||
--8<-- "docs/talemate/user-guide/tracking-a-state.md:context-attachment-method"
|
||||
--8<-- "docs/user-guide/tracking-a-state.md:context-attachment-method"
|
||||
|
||||
### Additional Instructions
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,23 @@ On top of the world editor interface you can configure some settings for this ty
|
|||
|
||||

|
||||
|
||||
## Generation instructions
|
||||
|
||||
Most generated fields offer a **:material-auto-fix: Generate** button above the input. Clicking it simply lets the AI fill in the field based on the surrounding context.
|
||||
|
||||
If you want to steer the result, hold `ctrl` (or `cmd` on macOS) while clicking the **:material-auto-fix: Generate** button. This opens a dialog with an **Instructions** field where you can describe what the generated content should contain.
|
||||
|
||||
Whatever you type here is passed to the AI as your own instruction and seed material that **must** be reflected in the result. In other words, the generated content is built around what you ask for rather than treating it as an optional suggestion, so your instructions are followed reliably.
|
||||
|
||||
A few things to keep in mind:
|
||||
|
||||
- Instructions can be a direction (for example, *"focus on her childhood in the city"*) or a seed you want expanded (for example, *"she lost her sister in the war"*).
|
||||
- For **history entries**, your instruction is treated as the seed for the entry. The AI writes the entry about the event or state you describe, expanding it with consistent detail, instead of generating something unrelated.
|
||||
- Instructions apply to a single generation. They are not saved with the field.
|
||||
|
||||
!!! tip "Rewriting existing content"
|
||||
Holding `alt` while clicking **:material-auto-fix: Generate** opens the dialog with the field's current content shown as the original, so the AI rewrites what is already there rather than starting from scratch. You can combine `ctrl` and `alt` to rewrite with instructions.
|
||||
|
||||
## Generation length
|
||||
|
||||
When using the **:material-auto-fix: Generate** button with additional instructions (hold `ctrl` when clicking), a dialog opens that includes a **Generation Length** dropdown. This allows you to control how long the generated content should be, measured in tokens.
|
||||
|
|
@ -53,7 +70,7 @@ The remembered lengths include:
|
|||
|
||||
Allows you to apply a writing style to AI generated content.
|
||||
|
||||
Writing styles are managed through [:material-script-text: writing style templates](/talemate/user-guide/world-editor/templates/writing-style).
|
||||
Writing styles are managed through [:material-script-text: writing style templates](/talemate/user-guide/templates/writing-style).
|
||||
|
||||
Once there is a writing style template available, you can select it from the dropdown list.
|
||||
|
||||
|
|
@ -63,7 +80,7 @@ Once there is a writing style template available, you can select it from the dro
|
|||
|
||||
Spice is a way to add some controlled randomness to AI generated content.
|
||||
|
||||
Spices are managed through [:material-chili-mild: spice collection templates](/talemate/user-guide/world-editor/templates/spice).
|
||||
Spices are managed through [:material-chili-mild: spice collection templates](/talemate/user-guide/templates/spice).
|
||||
|
||||
Once there is a spice template available, you can select it from the dropdown list.
|
||||
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@ Static entries can be added by clicking the **:material-plus: Add Entry** button
|
|||
|
||||
The text of the entry. Should be at most 1 - 2 paragraphs. Less is more. Anything that needs great detail should be a world entry instead.
|
||||
|
||||
You can let the AI write the entry for you with the **:material-auto-fix: Generate** button. Hold `ctrl` (or `cmd` on macOS) while clicking to provide [instructions](/talemate/user-guide/world-editor/generation-settings/#generation-instructions). For history entries your instruction is treated as the *seed* for the entry: the AI writes the entry about the event or state you describe and expands it with consistent detail, rather than ignoring it.
|
||||
|
||||
##### Unit
|
||||
|
||||
Defines the duration unit of the entry. So minutes, hours, days, weeks, months or years.
|
||||
|
|
@ -40,7 +42,7 @@ Defines the duration unit amount of the entry.
|
|||
|
||||
So if you want to define something that happened 10 months ago (from the current moment in the scene), you would set the unit to months and the amount to 10.
|
||||
|
||||

|
||||

|
||||
|
||||
## Time Passage Entries
|
||||
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ This allows to differentiate between, for example `roleplay` or `combat` scenes,
|
|||
!!! warning "Very early WIP"
|
||||
This is a very unfinished feature, so don't expect that you can plugin in some D&D style turn based combat rules into a scene type and have it work. Right now it will mostly affect the type of text that is generated and the pacing of the scene.
|
||||
|
||||
Re-usable scene types can be created in the [Template Editor](/talemate/user-guide/world-editor/templates)
|
||||
Re-usable scene types can be created in the [Template Editor](/talemate/user-guide/templates)
|
||||
|
||||
#### Current Scene Intention
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ Click on the :material-earth-box: **World Editor** to open the world editor.
|
|||
|
||||
In the world editor the :material-script: **Scene** tab should be selected, if not, click on it.
|
||||
|
||||

|
||||

|
||||
|
||||
### Title
|
||||
|
||||
|
|
@ -16,9 +16,9 @@ The scene title as it will be shown to the user. Currently this should be `New S
|
|||
|
||||
> The Forgotten House
|
||||
|
||||
### Content Context
|
||||
### Content Classification
|
||||
|
||||
The `Content Context` is used to set the tone and expectation of the generated content, it can strongly influence the AI's responses.
|
||||
The `Content Classification` is used to set the tone and expectation of the generated content, it can strongly influence the AI's responses.
|
||||
|
||||
You can type in a value or pick something from the list.
|
||||
|
||||
|
|
@ -31,24 +31,125 @@ You can type in a value or pick something from the list.
|
|||
|
||||
### Perspective and Tense
|
||||
|
||||
The narrative perspective and tense for the story (for example `Third person limited, past tense` or `Second person, present tense`).
|
||||
!!! info "Updated in 0.38.0"
|
||||
The single perspective field was replaced by a set of four configurable perspectives: a scene-wide default plus three per-speaker overrides (player, NPCs, narrator). The `{player_name}` placeholder was also added. Scenes saved with the older field are migrated automatically — their value becomes the new **default**.
|
||||
|
||||
When set, the value is included in the context sent to the AI for narration, dialogue, and autocomplete prompts, so the model knows which point of view and tense to write in.
|
||||
The narrative perspective and tense for the story — for example `Third person limited, past tense` or `Second person, present tense`. When set, the value is injected into the context the AI sees for narration, dialogue, and autocomplete prompts, so the model knows which point of view and tense to write in.
|
||||
|
||||
The field is free-form text. Leave it blank if you don't need to specify one — prompts will simply omit the line.
|
||||
A perspective usually combines three things:
|
||||
|
||||

|
||||
- **Person** — *who* the prose talks about and *how* it refers to them.
|
||||
- **First person** uses "I"/"me"/"my" — the narrator *is* the character. *"I walked up to the door."*
|
||||
- **Second person** uses "you" — the narrator speaks *to* the reader as if they are the character. *"You walk up to the door."* Common in interactive fiction and choose-your-own-adventure styles.
|
||||
- **Third person** uses "he"/"she"/"they" — the narrator describes the characters from outside. *"She walked up to the door."*
|
||||
- **Tense** — *when* the action is happening relative to the telling.
|
||||
- **Past tense** reads like a recollection: "walked", "said", "thought". *"She walked up to the door and knocked."*
|
||||
- **Present tense** reads like a live broadcast: "walks", "says", "thinks". *"She walks up to the door and knocks."*
|
||||
- **Point of view (POV)** — *how much* the narrator knows.
|
||||
- **Limited** — the narrator is tethered to one character's head and only knows what *they* know. Other characters' thoughts and off-screen events are off-limits. Usually anchored to a named character (often the player).
|
||||
- **Omniscient** — the narrator floats above the scene and can dip into anyone's thoughts, describe off-screen events, or foreshadow what's coming.
|
||||
|
||||
##### Examples
|
||||

|
||||
|
||||
> Third person limited, past tense
|
||||
Talemate exposes the perspective configuration as four separate fields:
|
||||
|
||||
> Second person, present tense
|
||||
| Field | When it's used |
|
||||
|---|---|
|
||||
| **Perspective and tense** (default) | Used everywhere the scene needs perspective context, and as the fallback for any of the three role-specific slots below when they are empty. |
|
||||
| **Perspective (you / player character)** | Used when the *player character* is the one speaking or acting in a dialogue prompt. |
|
||||
| **Perspective (others / NPCs)** | Used when a *non-player character* is speaking or acting. |
|
||||
| **Perspective (narrator)** | Used for narrator agent prompts — scene description, story progression, character entry / exit, time passage, and so on. |
|
||||
|
||||
> First person past tense, from Annabelle's point of view
|
||||
The three role-specific fields live behind the **Per-speaker perspective overrides** expansion panel next to the default field. A small chip on the panel header tells you how many overrides are set.
|
||||
|
||||
!!! note "Exposed as a context ID"
|
||||
This field is also available as the `story_configuration:perspective` context ID, which means it can be referenced or updated by features that work with context IDs (for example the [Context Database](/talemate/user-guide/world-editor/context-db)).
|
||||
#### Choosing or typing a value
|
||||
|
||||
Each of the four fields is a combobox. You can:
|
||||
|
||||
- **Pick a preset** from the dropdown.
|
||||
- **Type a custom value** — the field accepts any free-form text and your custom entry is saved with the scene whether or not it matches a preset.
|
||||
|
||||
The dropdown list is shared by all four fields and is managed in **Settings → Creator → Perspective Presets**. See [Creator settings](../../app-settings/creator.md#perspective-presets) for how to add, remove, or rename presets.
|
||||
|
||||
#### The `{player_name}` placeholder
|
||||
|
||||
Any field that contains the literal string `{player_name}` will have that substring replaced by the active player character's name at prompt render time. This means presets like:
|
||||
|
||||
> First person, present tense, from {player_name}'s POV.
|
||||
|
||||
work for every scene without you having to edit them, and they survive renaming the player character.
|
||||
|
||||
If the scene has no explicit player character, perspectives that reference `{player_name}` are **suppressed** rather than substituted — the placeholder has no anchor to point at, so injecting it would produce broken prose like *"Talking to the player."*. Pick a non-placeholder preset for scenes without a player character.
|
||||
|
||||
#### Fallback semantics
|
||||
|
||||
The four fields cascade in a predictable way:
|
||||
|
||||
- An empty role-specific override falls back to the **default**.
|
||||
- An empty default means *no perspective line is injected at all* — the AI is left to match whatever tense and POV the existing scene history establishes (the dialogue prompt has a short instruction that handles this case automatically).
|
||||
|
||||
You only need to fill in the fields that matter for your scene. Most scenes only need the default.
|
||||
|
||||
#### What each default preset means
|
||||
|
||||
This table lists the presets that ship with Talemate, what each one means in plain English, and a tiny sample of the kind of prose it produces (using `Annabelle` as the player character).
|
||||
|
||||
| Preset | What it means | Sample prose |
|
||||
|---|---|---|
|
||||
| `Third person limited, past tense.` | Outside narrator using "she"/"he"/"they". Past tense ("walked"). Anchored to one character — usually whoever the scene establishes as the POV character. | *"Annabelle walked up to the porch. The door looked older than the rest of the house."* |
|
||||
| `Third person limited, past tense, focused on {player_name}'s POV.` | Same as above, but explicitly tells the AI the player character is the anchor — the narration can read *her* thoughts, but not the NPC's. | *"Annabelle walked up to the porch. Something about the door felt wrong, though she couldn't say why."* |
|
||||
| `Third person limited, present tense.` | Outside narrator using "she"/"he"/"they". Present tense ("walks"). Reads like a live broadcast. | *"Annabelle walks up to the porch. The door looks older than the rest of the house."* |
|
||||
| `Third person limited, present tense, focused on {player_name}'s POV.` | Same as above, anchored to the player character. | *"Annabelle walks up to the porch. The door looks wrong to her, somehow."* |
|
||||
| `Third person omniscient, past tense.` | Outside narrator using "she"/"he"/"they", past tense. The narrator knows *everything* — NPC thoughts, off-screen events, things the player character can't see. | *"Annabelle walked up to the porch, unaware that someone was watching her from an upstairs window."* |
|
||||
| `Third person omniscient, present tense.` | Same as above, in present tense. | *"Annabelle walks up to the porch. Inside, the homeowner watches her approach through the curtains."* |
|
||||
| `First person, past tense, from {player_name}'s POV.` | The *player character herself* narrates, using "I"/"me"/"my". Past tense — reads like a journal entry or recollection. | *"I walked up to the porch. The door looked older than the rest of the house."* |
|
||||
| `First person, present tense, from {player_name}'s POV.` | The *player character herself* narrates, using "I"/"me"/"my". Present tense — reads like an unfolding inner monologue. | *"I walk up to the porch. The door looks older than the rest of the house."* |
|
||||
| `Second person, present tense.` | The narrator addresses an unnamed "you" — classic interactive-fiction voice. Present tense. | *"You walk up to the porch. The door looks older than the rest of the house."* |
|
||||
| `Second person, present tense. Talking to {player_name}.` | Same as above, but the narrator explicitly knows the player character's name and may use it. | *"You walk up to the porch, Annabelle. The door looks older than the rest of the house."* |
|
||||
|
||||
You are not limited to these — type anything into the field and it will be passed to the AI verbatim. The presets are just shortcuts for the most common configurations. See [Creator settings → Perspective Presets](../../app-settings/creator.md#perspective-presets) for how to add your own.
|
||||
|
||||
#### Common patterns
|
||||
|
||||
**Standard novel (third person limited, single POV character)**
|
||||
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| Default | `Third person limited, past tense, focused on {player_name}'s POV.` |
|
||||
| Player | *empty* |
|
||||
| Other | *empty* |
|
||||
| Narrator | *empty* |
|
||||
|
||||
**Interactive fiction / "you are the protagonist"**
|
||||
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| Default | *empty* |
|
||||
| Player | *empty* |
|
||||
| Other | *empty* |
|
||||
| Narrator | `Second person, present tense. Talking to {player_name}.` |
|
||||
|
||||
The narrator drives the whole scene in second person and no perspective line is added to dialogue or analysis prompts.
|
||||
|
||||
**Mixed POV — first person for the player, third for everyone else**
|
||||
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| Default | *empty* |
|
||||
| Player | `First person, present tense, from {player_name}'s POV.` |
|
||||
| Other | *empty* |
|
||||
| Narrator | `Third person limited, past tense, focused on {player_name}'s POV.` |
|
||||
|
||||
When the player character is acting they get the first-person voice; the narrator and NPC dialogue stay in third person limited.
|
||||
|
||||
!!! note "Exposed as context IDs"
|
||||
The perspective fields are also available as context IDs for features that work with context IDs (for example the [Context Database](/talemate/user-guide/world-editor/context-db)):
|
||||
|
||||
- `story_configuration:perspective` — alias for the default field (kept for backwards compatibility).
|
||||
- `story_configuration:perspective.default`
|
||||
- `story_configuration:perspective.player`
|
||||
- `story_configuration:perspective.other`
|
||||
- `story_configuration:perspective.narrator`
|
||||
|
||||
### Description
|
||||
|
||||
|
|
|
|||
|
|
@ -2,11 +2,11 @@
|
|||
|
||||
The `Settings` tab allows you to configure various settings for the scene.
|
||||
|
||||

|
||||

|
||||
|
||||
### Writing Style
|
||||
|
||||
If you have any [writing style templates](/talemate/user-guide/world-editor/templates/writing-style/) set up, you can select one here. Some agents may use this to influence their output.
|
||||
If you have any [writing style templates](/talemate/user-guide/templates/writing-style/) set up, you can select one here. Some agents may use this to influence their output.
|
||||
|
||||
### Locked save file
|
||||
|
||||
|
|
@ -34,4 +34,19 @@ Restoring creates a **new, unsaved scene** based on the restore point. Your curr
|
|||
!!! tip
|
||||
This is especially useful for scene creators who want to test their scenes repeatedly, or for creating replayable scenarios where players always start from the same point. Combine this with a [locked save file](#locked-save-file) to prevent accidental overwrites of your baseline.
|
||||
|
||||
See also: [Restoring Scenes from Backups](/talemate/user-guide/restoring-scenes) for restoring to any previous revision using the automatic backup history.
|
||||
See also: [Restoring Scenes from Backups](/talemate/user-guide/restoring-scenes) for restoring to any previous revision using the automatic backup history.
|
||||
|
||||
### Agent settings file
|
||||
|
||||
This setting controls how the scene uses [per-scene agent overrides](/talemate/user-guide/agents/scene-overrides) — agent settings that apply to this scene only, without changing your global configuration.
|
||||
|
||||
Overrides are stored in a JSON file inside an `agent-settings/` folder in the scene's project directory. The **Agent settings file** dropdown decides which file (if any) the scene is linked to:
|
||||
|
||||
- **Auto-link (default)** — the scene automatically uses `agent-settings/agent-settings.json` if it exists in the project folder. This is the normal behavior. If you haven't set any overrides yet, the first one you create in the agent modal will create this file.
|
||||
- **None (opt out)** — disable per-scene overrides for this scene. It uses your global agent configuration only and will not auto-link to a default file.
|
||||
- **A specific file** — link the scene to a particular overrides file in the project's `agent-settings/` folder. Any additional override files in that folder appear in the list, letting a project keep more than one set of overrides and switch between them.
|
||||
|
||||
Once a file is linked, you edit the actual overrides in the agent modal under the **Scene** tab. See [Per-Scene Agent Overrides](/talemate/user-guide/agents/scene-overrides) for the full workflow.
|
||||
|
||||
!!! note
|
||||
Overrides are project-level, so every save file in the same project — including **Save As** copies and restore points — shares the same `agent-settings/` folder. Scene exports include this folder, so overrides travel with the scene when shared.
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
!!! info "What is a tracked state?"
|
||||
|
||||
--8<-- "docs/talemate/user-guide/tracking-a-state.md:what-is-a-tracked-state"
|
||||
--8<-- "docs/user-guide/tracking-a-state.md:what-is-a-tracked-state"
|
||||
|
||||
## Setting up a new state
|
||||
In the :material-earth: **World** editor, in the left panel, click the :material-image-auto-adjust: **New State Reinforcement** button.
|
||||
|
|
@ -33,7 +33,7 @@ By default it will be `10` turns, but you can change this to any number you like
|
|||
|
||||
### Context Attachment Method
|
||||
|
||||
--8<-- "docs/talemate/user-guide/tracking-a-state.md:context-attachment-method"
|
||||
--8<-- "docs/user-guide/tracking-a-state.md:context-attachment-method"
|
||||
|
||||
For this example, we always want to know the state of the ship, so we will set it to `All context`.
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@
|
|||
|
||||
The world state snapshot is a summary of the current scene state. It will contain characters and objects mentioned in the scene.
|
||||
|
||||
The snapshot is generated and maintained by the [World State Agent](/talemate/user-guide/agents/world-state/), which refreshes it automatically as the scene plays out. To build the snapshot the agent looks at the whole scene so far together with the most recent lines (the "current moment"), and it can also pull in relevant entries from [long-term memory](/talemate/user-guide/agents/world-state/settings/#long-term-memory) so the snapshot can build on established lore and earlier scene history.
|
||||
|
||||
If there are [tracked states](/talemate/user-guide/tracking-a-state) in the scene, they will also be displayed here.
|
||||
|
||||

|
||||
|
|
@ -13,13 +15,45 @@ Characters are indicated by the :material-account: icon, objects by the :materia
|
|||
|
||||
You can click on each entry to expand it and see more information.
|
||||
|
||||
## :material-cursor-default-click-outline: Entity Highlights in scene messages
|
||||
|
||||
Alongside the snapshot panel, Talemate also highlights notable characters, items, and places directly inside the most recent scene message. Highlighted entities appear with a subtle dotted underline, marking them as clickable.
|
||||
|
||||
These highlights are produced by the same world state snapshot, so they refresh whenever the snapshot updates. Only the most recent part of the scene — the "current moment" — receives highlights; older messages are left as plain text.
|
||||
|
||||
### Examining an entity
|
||||
|
||||
Click a highlighted entity to open a small popover. The popover shows:
|
||||
|
||||
- The entity's name and its kind (character, item, or place).
|
||||
- For characters, the current emotional state, when known.
|
||||
- A short description of the entity as it stands in the current moment.
|
||||
|
||||
From the popover you can take two actions:
|
||||
|
||||
:material-eye: **Look at** asks the [Narrator Agent](/talemate/user-guide/agents/narrator/) for a fresh description of the entity, added to the scene as a context-investigation message.
|
||||
|
||||
:material-plus: **Add Detail** expands the short description shown in the popover into a longer, grounded passage, also added to the scene as a context-investigation message. This action is available for items, places, and background characters mentioned in the narrative. It is hidden for characters that already exist in the scene, since those have their own detail surfaces in the [character editor](/talemate/user-guide/world-editor/characters).
|
||||
|
||||
:material-cog-outline: **Configure highlights** opens the [World State Agent settings](/talemate/user-guide/agents/world-state/settings/) where the highlight behavior is controlled.
|
||||
|
||||
### Controlling the highlights
|
||||
|
||||
Entity highlighting follows the world state snapshot, so it shares the snapshot's settings in the [World State Agent configuration](/talemate/user-guide/agents/world-state/settings/):
|
||||
|
||||
- **Lines in the moment** sets how many of the most recent messages count as the current moment and can therefore show highlights.
|
||||
- **Include Look at / Add Detail** controls whether context-investigation messages (the results of the actions above) also count as part of the current moment and can receive their own highlights.
|
||||
- **Add Detail length** controls how long an **Add Detail** result can be.
|
||||
|
||||
You can change the color of the highlights, or turn the inline styling off entirely, under **Settings → Appearance → Messages → Entity Highlights**. See [Appearance settings](/talemate/user-guide/app-settings/appearance/#text-markup-styling).
|
||||
|
||||
## :material-account: Characters
|
||||
|
||||
Each character entry will display the current emotional state next to the character's name.
|
||||
|
||||
When expanded it will also show a description of what the character is currently doing.
|
||||
|
||||

|
||||

|
||||
|
||||
### Action shortcuts
|
||||
|
||||
|
|
@ -27,9 +61,7 @@ Beneath the description there are additional shortcuts.
|
|||
|
||||
:material-eye: **Look at** Will cause the [Narrator Agent](/talemate/user-guide/agents/narrator/) to describe the character.
|
||||
|
||||
:material-account-details: **Character Sheet** will take you to the character sheet, which provides more detailed information about the character.
|
||||
|
||||
:material-book-open-page-variant: **Manage Character** will take you to the [character editor](/talemate/user-guide/world-editor/characters) for that character.
|
||||
:material-book-open-page-variant: **Manage Character** will take you to the [character editor](/talemate/user-guide/world-editor/characters) for that character, where you can view and edit all of the character's details.
|
||||
|
||||
:material-human-greeting: **Make real** If the world state has picked up a character that is not yet an interactive character, this will allow you to convert them into an interactive character.
|
||||
|
||||
|
|
@ -61,6 +93,34 @@ If there are [tracked states](/talemate/user-guide/tracking-a-state) in the scen
|
|||
|
||||

|
||||
|
||||
## :material-refresh: Force Update
|
||||
## :material-refresh: Refreshing the snapshot
|
||||
|
||||
While the [World State Agent](/talemate/user-guide/agents/world-state/) will automatically update the world state snapshot, you can also force an update by clicking the refresh icon in the top right of the world state snapshot.
|
||||
While the [World State Agent](/talemate/user-guide/agents/world-state/) will automatically update the world state snapshot as the scene progresses, you can also refresh it on demand by clicking the refresh icon in the top right of the world state snapshot.
|
||||
|
||||
### How the snapshot carries forward
|
||||
|
||||
By default the snapshot is **durable**: each refresh updates only what has changed and drops entities that are no longer relevant, rather than rebuilding the whole snapshot from scratch. This lets the snapshot build up over time, so details an entity has accumulated earlier in the scene are not lost on the next refresh.
|
||||
|
||||
To keep the snapshot from collecting stale entries, an entity that the agent leaves untouched for several refreshes in a row is automatically removed. Durability (and the related limits) can be turned off or tuned in the [World State Agent settings](/talemate/user-guide/agents/world-state/settings/#durable-snapshot).
|
||||
|
||||
When you move to a new point in time (a [time jump](/talemate/user-guide/time-passage/)), the snapshot is treated as a clean scene cut and rebuilt fresh, since the previous moment no longer applies.
|
||||
|
||||
### Wiping the snapshot
|
||||
|
||||
If you want to discard everything the snapshot has accumulated and start over, hold **Ctrl** (or **Cmd** on macOS) while clicking the refresh icon. This wipes the current snapshot and regenerates it from scratch.
|
||||
|
||||
### Cancelling a refresh
|
||||
|
||||
While a refresh is in progress a :material-close: cancel icon is shown in place of the refresh icon. Click it to stop the generation. This is useful if a refresh is taking longer than you want or you started one by mistake.
|
||||
|
||||
## :material-cog-clockwise: Automatic refreshing and the scene input
|
||||
|
||||
The snapshot refreshes automatically every several character turns (each player or AI turn counts), on a cadence you can set in the [World State Agent settings](/talemate/user-guide/agents/world-state/settings/#turns).
|
||||
|
||||
If the agent's text-generation client supports running more than one request at a time, the snapshot is generated quietly in the background and you can keep playing while it works. Otherwise it runs in the foreground so it doesn't compete with your other actions on the same client. Either way, manual refreshes behave the same and can be cancelled mid-generation.
|
||||
|
||||
## :material-pin: Pinning the snapshot to the scene
|
||||
|
||||
The world state snapshot can optionally be **pinned into the prompts** that drive dialogue, narration, and scene planning. When pinning is enabled, the snapshot's tracked characters, items, and places are shared with the [Conversation Agent](/talemate/user-guide/agents/conversation/), the [Narrator Agent](/talemate/user-guide/agents/narrator/), and scene analysis, so what the snapshot is tracking can inform what those agents produce.
|
||||
|
||||
This is **off by default**. You can enable it with the [Pin to context](/talemate/user-guide/agents/world-state/settings/#pin-to-context) setting in the World State Agent settings.
|
||||
81
install-utils/node-env.sh
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
# Shared helper for provisioning and activating a portable Node.js runtime.
|
||||
# Requires bash (relies on BASH_SOURCE). Source it, then call:
|
||||
# install_embedded_node - download + extract + activate (install.sh)
|
||||
# activate_embedded_node - put it on PATH if present (update.sh, start-frontend.sh)
|
||||
#
|
||||
# pnpm 11 (pinned via talemate_frontend/package.json "packageManager") needs
|
||||
# Node.js >= 22.13. Rather than depend on whatever Node is on the system,
|
||||
# install.sh downloads a portable Node into ./embedded_node and the update /
|
||||
# start scripts reuse it. This mirrors what install.bat does on Windows.
|
||||
|
||||
# Pinned Node.js version for the portable runtime.
|
||||
EMBEDDED_NODE_VERSION="22.22.3"
|
||||
|
||||
# Absolute path to ./embedded_node, resolved relative to this file so it works
|
||||
# no matter what the caller's current working directory is.
|
||||
EMBEDDED_NODE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)/embedded_node"
|
||||
|
||||
# Map `uname -m` to the architecture string used by nodejs.org downloads.
|
||||
_embedded_node_arch() {
|
||||
case "$(uname -m)" in
|
||||
x86_64 | amd64) echo "x64" ;;
|
||||
aarch64 | arm64) echo "arm64" ;;
|
||||
armv7l) echo "armv7l" ;;
|
||||
*) echo "" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Download $1 to $2 using whichever of curl/wget is available.
|
||||
_embedded_node_download() {
|
||||
if command -v curl >/dev/null 2>&1; then
|
||||
curl -fL --progress-bar -o "$2" "$1"
|
||||
elif command -v wget >/dev/null 2>&1; then
|
||||
wget -q --show-progress -O "$2" "$1"
|
||||
else
|
||||
echo "Neither curl nor wget found; cannot download Node.js." >&2
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Prepend the portable Node (if present) to PATH so node/npm/corepack resolve to it.
|
||||
activate_embedded_node() {
|
||||
if [ -x "$EMBEDDED_NODE_DIR/bin/node" ]; then
|
||||
export PATH="$EMBEDDED_NODE_DIR/bin:$PATH"
|
||||
fi
|
||||
}
|
||||
|
||||
# Download and extract the portable Node runtime, then activate it.
|
||||
install_embedded_node() {
|
||||
local arch tarball url
|
||||
arch="$(_embedded_node_arch)"
|
||||
if [ -z "$arch" ]; then
|
||||
echo "Unsupported architecture '$(uname -m)' for portable Node.js."
|
||||
echo "Please install Node.js >= 22.13 manually and re-run."
|
||||
return 1
|
||||
fi
|
||||
|
||||
tarball="node-v${EMBEDDED_NODE_VERSION}-linux-${arch}.tar.xz"
|
||||
url="https://nodejs.org/dist/v${EMBEDDED_NODE_VERSION}/${tarball}"
|
||||
|
||||
echo "Downloading portable Node.js v${EMBEDDED_NODE_VERSION} (${arch})..."
|
||||
rm -rf "$EMBEDDED_NODE_DIR"
|
||||
mkdir -p "$EMBEDDED_NODE_DIR"
|
||||
|
||||
if ! _embedded_node_download "$url" "/tmp/${tarball}"; then
|
||||
echo "Failed to download Node.js from ${url}"
|
||||
rm -rf "$EMBEDDED_NODE_DIR"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# --strip-components 1 drops the node-vX.Y.Z-linux-<arch>/ top-level directory.
|
||||
if ! tar -xf "/tmp/${tarball}" -C "$EMBEDDED_NODE_DIR" --strip-components 1; then
|
||||
echo "Failed to extract ${tarball} (is xz/xz-utils installed?)"
|
||||
rm -f "/tmp/${tarball}"
|
||||
rm -rf "$EMBEDDED_NODE_DIR"
|
||||
return 1
|
||||
fi
|
||||
rm -f "/tmp/${tarball}"
|
||||
|
||||
activate_embedded_node
|
||||
echo "Using portable Node.js at ${EMBEDDED_NODE_DIR} ($(node -v))"
|
||||
}
|
||||
17
install.bat
|
|
@ -69,7 +69,7 @@ IF "%NEED_CLEAN%"=="1" (
|
|||
|
||||
REM ---------[ Version configuration ]---------
|
||||
SET "PYTHON_VERSION=3.11.9"
|
||||
SET "NODE_VERSION=22.16.0"
|
||||
SET "NODE_VERSION=22.22.3"
|
||||
|
||||
REM ---------[ Detect architecture & choose download URL ]---------
|
||||
REM Prefer PROCESSOR_ARCHITEW6432 when the script is run from a 32-bit shell on 64-bit Windows
|
||||
|
|
@ -212,21 +212,22 @@ ECHO Node.js version:
|
|||
node -v
|
||||
|
||||
REM ---------[ Frontend ]---------
|
||||
REM pnpm is provisioned on demand via corepack (bundled with Node.js); the
|
||||
REM version is pinned by the "packageManager" field in package.json.
|
||||
SET "COREPACK_ENABLE_DOWNLOAD_PROMPT=0"
|
||||
ECHO Installing frontend dependencies...
|
||||
CD talemate_frontend
|
||||
CALL npm install || CALL :die "npm install failed."
|
||||
CALL corepack pnpm install --frozen-lockfile || CALL :die "pnpm install failed."
|
||||
|
||||
ECHO Building frontend...
|
||||
CALL npm run build
|
||||
CALL corepack pnpm build
|
||||
IF ERRORLEVEL 1 (
|
||||
ECHO.
|
||||
ECHO Frontend build failed - retrying with clean node_modules...
|
||||
ECHO This can happen due to a known npm bug with optional dependencies.
|
||||
ECHO Frontend build failed - retrying with a clean node_modules...
|
||||
ECHO.
|
||||
rmdir /s /q node_modules 2>nul
|
||||
del package-lock.json 2>nul
|
||||
CALL npm install || CALL :die "npm install failed on retry."
|
||||
CALL npm run build || CALL :die "Frontend build failed on retry."
|
||||
CALL corepack pnpm install --frozen-lockfile || CALL :die "pnpm install failed on retry."
|
||||
CALL corepack pnpm build || CALL :die "Frontend build failed on retry."
|
||||
)
|
||||
|
||||
REM Return to repo root
|
||||
|
|
|
|||
16
install.sh
|
|
@ -18,14 +18,26 @@ if [ ! -f config.yaml ]; then
|
|||
cp config.example.yaml config.yaml
|
||||
fi
|
||||
|
||||
# provision a portable Node.js runtime (pnpm 11 needs Node >= 22.13)
|
||||
echo "Setting up the Node.js runtime..."
|
||||
source install-utils/node-env.sh
|
||||
if ! install_embedded_node; then
|
||||
echo "ERROR: could not provision Node.js. Aborting installation."
|
||||
return 1 2>/dev/null || exit 1
|
||||
fi
|
||||
|
||||
# navigate to the frontend directory
|
||||
echo "Updating the frontend..."
|
||||
cd talemate_frontend
|
||||
npm install
|
||||
|
||||
# pnpm is provisioned on demand via corepack (bundled with Node.js); the
|
||||
# version is pinned by the "packageManager" field in package.json.
|
||||
export COREPACK_ENABLE_DOWNLOAD_PROMPT=0
|
||||
corepack pnpm install --frozen-lockfile
|
||||
|
||||
# build the frontend
|
||||
echo "Building the frontend..."
|
||||
npm run build
|
||||
corepack pnpm build
|
||||
|
||||
# return to the root directory
|
||||
cd ..
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[project]
|
||||
name = "talemate"
|
||||
version = "0.37.1"
|
||||
version = "0.38.0"
|
||||
description = "AI-backed roleplay and narrative tools"
|
||||
authors = [{name = "VeguAITools"}]
|
||||
license = {text = "GNU Affero General Public License v3.0"}
|
||||
|
|
@ -30,7 +30,7 @@ dependencies = [
|
|||
"pydantic<3",
|
||||
"beautifulsoup4>=4.12.2",
|
||||
"python-dotenv>=1.0.0",
|
||||
"cryptography>=43.0",
|
||||
"cryptography>48.0.0",
|
||||
"keyring>=25.0",
|
||||
"structlog>=23.1.0",
|
||||
"google-genai>=1.20.0",
|
||||
|
|
@ -124,6 +124,10 @@ ensure_newline_before_comments = true
|
|||
line_length = 88
|
||||
|
||||
[tool.uv]
|
||||
exclude-newer = "1 week"
|
||||
# safetensors 0.8.0 (uploaded 2026-06-09) is needed by diffusers 0.38.0, which fixes
|
||||
# CVE-2026-45804 / CVE-2026-44513 / CVE-2026-44827; remove once it ages past the 1-week window
|
||||
exclude-newer-package = { safetensors = "2026-06-10T00:00:00Z" }
|
||||
override-dependencies = [
|
||||
# chatterbox wants torch 2.6.0, but is confirmed working with 2.7.1
|
||||
"torchaudio>=2.7.1",
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
from .tale_mate import * # noqa: F401, F403
|
||||
from . import model_rebuild # noqa: F401 (resolves forward refs)
|
||||
|
||||
from .version import VERSION
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import dataclasses
|
||||
import contextlib
|
||||
import contextvars
|
||||
import functools
|
||||
import json
|
||||
from inspect import signature
|
||||
|
|
@ -9,7 +10,7 @@ import re
|
|||
import traceback
|
||||
from abc import ABC
|
||||
from functools import wraps
|
||||
from typing import Callable, Literal
|
||||
from typing import Awaitable, Callable, Literal
|
||||
import uuid
|
||||
import pydantic
|
||||
from pydantic import ConfigDict
|
||||
|
|
@ -29,6 +30,7 @@ import talemate.config.schema as config_schema
|
|||
from talemate.client.context import (
|
||||
ClientContext,
|
||||
)
|
||||
from talemate.scene_agent_settings import UNSET
|
||||
from talemate.game.engine.nodes.core import GraphState
|
||||
from talemate.game.engine.nodes.registry import get_nodes_by_base_type, get_node
|
||||
from talemate.game.engine.nodes.run import FunctionWrapper
|
||||
|
|
@ -98,6 +100,7 @@ class AgentActionConfig(pydantic.BaseModel):
|
|||
default_factory=dict
|
||||
)
|
||||
save_on_change: bool = False
|
||||
scene_overridable: bool = True
|
||||
|
||||
wstemplate_type: (
|
||||
Literal[
|
||||
|
|
@ -161,6 +164,21 @@ class AgentAction(pydantic.BaseModel):
|
|||
# Only meaningful on actions that are themselves dynamic registries.
|
||||
dynamic_registry_component: str | None = None
|
||||
|
||||
enabled_scene_overridable: bool = False
|
||||
|
||||
@pydantic.model_validator(mode="after")
|
||||
def _enabled_scene_overridable_requires_can_be_disabled(self):
|
||||
# An enable-flag override only makes sense when the global enable
|
||||
# flag is itself togglable. Without can_be_disabled the global UI
|
||||
# never exposes an Enable checkbox, so a scene-level override has
|
||||
# nothing to override.
|
||||
if self.enabled_scene_overridable and not self.can_be_disabled:
|
||||
raise ValueError(
|
||||
f"AgentAction {self.label!r}: enabled_scene_overridable=True "
|
||||
"requires can_be_disabled=True"
|
||||
)
|
||||
return self
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Dynamic action registries
|
||||
|
|
@ -195,6 +213,7 @@ def optimize_prompt_caching_action() -> AgentAction:
|
|||
{"label": "On", "value": "on"},
|
||||
{"label": "Off", "value": "off"},
|
||||
],
|
||||
scene_overridable=False,
|
||||
),
|
||||
},
|
||||
)
|
||||
|
|
@ -272,6 +291,29 @@ class store_context_state:
|
|||
return fn
|
||||
|
||||
|
||||
def _agent_action_override_kwargs(agent_type: str, action_name: str) -> dict:
|
||||
"""ClientContext kwargs for any per-action override on ``{agent_type}.{action_name}``; empty when none applies."""
|
||||
config = get_config()
|
||||
override = config.agent_actions.overrides.get(f"{agent_type}.{action_name}")
|
||||
if override is None:
|
||||
return {}
|
||||
|
||||
kwargs: dict = {}
|
||||
if override.disable_reasoning:
|
||||
kwargs["disable_reasoning"] = True
|
||||
return kwargs
|
||||
|
||||
|
||||
# When True (set by a background dispatcher around asyncio.create_task), a
|
||||
# @set_processing action skips its foreground "busy" status emit. The action
|
||||
# still establishes its normal client/agent context, but status is left to
|
||||
# set_background_processing() so the work reports as "busy_bg" rather than
|
||||
# blocking-looking "busy". Default False keeps every other call unchanged.
|
||||
background_processing: contextvars.ContextVar[bool] = contextvars.ContextVar(
|
||||
"agent_background_processing", default=False
|
||||
)
|
||||
|
||||
|
||||
def set_processing(fn):
|
||||
"""
|
||||
decorator that emits the agent status as processing while the function
|
||||
|
|
@ -283,6 +325,9 @@ def set_processing(fn):
|
|||
|
||||
@wraps(fn)
|
||||
async def wrapper(self, *args, **kwargs):
|
||||
# In background mode the foreground "busy" emit is suppressed; status is
|
||||
# owned by set_background_processing() so the action reports "busy_bg".
|
||||
is_background = background_processing.get()
|
||||
with ClientContext():
|
||||
scene = active_scene.get()
|
||||
|
||||
|
|
@ -296,7 +341,8 @@ def set_processing(fn):
|
|||
action_name = args[0].__name__
|
||||
|
||||
self._current_action = action_name
|
||||
await self.emit_status(processing=True)
|
||||
if not is_background:
|
||||
await self.emit_status(processing=True)
|
||||
|
||||
# Now pass the complete args list
|
||||
if getattr(fn, "store_context_state", None) is not None:
|
||||
|
|
@ -317,11 +363,21 @@ def set_processing(fn):
|
|||
|
||||
self.set_context_states(**all_args)
|
||||
|
||||
return await fn(self, *args, **kwargs)
|
||||
override_kwargs = _agent_action_override_kwargs(
|
||||
self.agent_type, action_name
|
||||
)
|
||||
override_ctx = (
|
||||
ClientContext(**override_kwargs)
|
||||
if override_kwargs
|
||||
else contextlib.nullcontext()
|
||||
)
|
||||
with override_ctx:
|
||||
return await fn(self, *args, **kwargs)
|
||||
finally:
|
||||
try:
|
||||
self._current_action = None
|
||||
await self.emit_status(processing=False)
|
||||
if not is_background:
|
||||
await self.emit_status(processing=False)
|
||||
except RuntimeError as exc:
|
||||
# not sure why this happens
|
||||
# some concurrency error?
|
||||
|
|
@ -367,6 +423,7 @@ class Agent(ABC):
|
|||
"has_toggle": agent.has_toggle if agent else False,
|
||||
"experimental": agent.experimental if agent else False,
|
||||
"requires_llm_client": cls.requires_llm_client,
|
||||
"scene_overrides": cls._scene_overrides_payload(agent),
|
||||
}
|
||||
actions = getattr(agent, "actions", None)
|
||||
|
||||
|
|
@ -377,6 +434,24 @@ class Agent(ABC):
|
|||
|
||||
return config_options
|
||||
|
||||
@classmethod
|
||||
def _scene_overrides_payload(cls, agent) -> dict:
|
||||
"""Sparse override dict for THIS agent from the active scene, if any.
|
||||
|
||||
Empty dict means: no scene loaded, or no overrides set for this
|
||||
agent. The frontend uses this to populate the Scene tab in the
|
||||
AgentModal.
|
||||
"""
|
||||
if not agent:
|
||||
return {}
|
||||
overrides = agent.scene_overrides()
|
||||
if overrides is None:
|
||||
return {}
|
||||
agent_override = overrides.agents.get(agent.agent_type)
|
||||
if not agent_override:
|
||||
return {}
|
||||
return agent_override.model_dump(exclude_none=True)
|
||||
|
||||
@classmethod
|
||||
async def init_nodes(cls, scene: "Scene", state: GraphState):
|
||||
log.debug(f"{cls.agent_type}.init_nodes")
|
||||
|
|
@ -806,7 +881,82 @@ class Agent(ABC):
|
|||
return default
|
||||
return functools.partial(fn, slug)
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Per-scene config overrides
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
def scene_overrides(self):
|
||||
"""Return the scene's agent-overrides overlay, or None if not linked.
|
||||
|
||||
``scene`` is only present after ``connect()`` runs at scene-load time;
|
||||
callers may invoke this before that (e.g. property getters during agent
|
||||
init), so we tolerate a missing ``scene`` attribute.
|
||||
"""
|
||||
scene = getattr(self, "scene", None)
|
||||
return getattr(scene, "agent_overrides", None) if scene else None
|
||||
|
||||
def _resolve(self, getter, fallback):
|
||||
"""Consult the scene overlay via ``getter``; fall back if UNSET."""
|
||||
overrides = self.scene_overrides()
|
||||
if overrides is not None:
|
||||
value = getter(overrides)
|
||||
if value is not UNSET:
|
||||
return value
|
||||
return fallback()
|
||||
|
||||
def resolve_config(self, action_key: str, config_key: str):
|
||||
"""Return the effective value for an action config field — scene override if any, else global."""
|
||||
return self._resolve(
|
||||
lambda o: o.get_value(self.agent_type, action_key, config_key),
|
||||
lambda: self.actions[action_key].config[config_key].value,
|
||||
)
|
||||
|
||||
def resolve_enabled(self, action_key: str) -> bool:
|
||||
"""Return the effective enabled flag for a container action."""
|
||||
return bool(
|
||||
self._resolve(
|
||||
lambda o: o.get_enabled(self.agent_type, action_key),
|
||||
lambda: self.actions[action_key].enabled,
|
||||
)
|
||||
)
|
||||
|
||||
def _route_write(self, has_override, write_override, write_global) -> None:
|
||||
"""Route a write to the scene overlay when it's overriding this field, else to the global config."""
|
||||
overrides = self.scene_overrides()
|
||||
if overrides is not None and has_override(overrides):
|
||||
write_override(overrides)
|
||||
else:
|
||||
write_global()
|
||||
|
||||
def write_config(self, action_key: str, config_key: str, value) -> None:
|
||||
"""Update an action config field — scene override if one is active for this field, else global.
|
||||
|
||||
Note: this updates an *existing* override; it does not create a new one.
|
||||
New overrides are installed via the AgentModal save flow
|
||||
(see ``server.agent_config.replace_agent_overrides``).
|
||||
"""
|
||||
self._route_write(
|
||||
lambda o: o.get_value(self.agent_type, action_key, config_key) is not UNSET,
|
||||
lambda o: o.set_value(self.agent_type, action_key, config_key, value),
|
||||
lambda: setattr(
|
||||
self.actions[action_key].config[config_key], "value", value
|
||||
),
|
||||
)
|
||||
|
||||
def write_enabled(self, action_key: str, enabled: bool) -> None:
|
||||
"""Update an action's enabled flag — scene override if one is active, else global.
|
||||
|
||||
Note: this updates an *existing* override; it does not create a new one.
|
||||
"""
|
||||
self._route_write(
|
||||
lambda o: o.get_enabled(self.agent_type, action_key) is not UNSET,
|
||||
lambda o: o.set_enabled(self.agent_type, action_key, enabled),
|
||||
lambda: setattr(self.actions[action_key], "enabled", enabled),
|
||||
)
|
||||
|
||||
async def apply_config(self, *args, **kwargs):
|
||||
# Writes global state directly on purpose; runtime edits must go
|
||||
# through `write_config` / `write_enabled` to respect any overlay.
|
||||
if self.has_toggle and "enabled" in kwargs:
|
||||
self.is_enabled = kwargs.get("enabled", False)
|
||||
|
||||
|
|
@ -1021,6 +1171,109 @@ class Agent(ABC):
|
|||
)
|
||||
)
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Tracked single-flight tasks
|
||||
#
|
||||
# A small reuse layer over set_background_processing for "run this agent
|
||||
# operation as a single-flight task, optionally in the background". Each
|
||||
# logical operation is identified by a `key` so an agent can run several
|
||||
# independent ones; per-key only one is ever in flight at a time.
|
||||
#
|
||||
# background=True routes status through set_background_processing ("busy_bg",
|
||||
# non-blocking UI) and sets the background_processing contextvar so the
|
||||
# operation's @set_processing work reports busy_bg too. background=False runs
|
||||
# the same machinery but reports the normal foreground "busy".
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
def _tracked_task(self, key: str) -> "asyncio.Task | None":
|
||||
return getattr(self, "_tracked_tasks", {}).get(key)
|
||||
|
||||
def tracked_task_running(self, key: str) -> bool:
|
||||
"""Whether a tracked task under `key` is currently in flight."""
|
||||
task = self._tracked_task(key)
|
||||
return task is not None and not task.done()
|
||||
|
||||
async def run_tracked_task(
|
||||
self,
|
||||
key: str,
|
||||
coro_factory: Callable[[], Awaitable],
|
||||
*,
|
||||
background: bool = True,
|
||||
cancel_in_flight: bool = False,
|
||||
error_handler: Callable | None = None,
|
||||
) -> "asyncio.Task | None":
|
||||
"""
|
||||
Run `coro_factory()` as a single-flight task tracked under `key`.
|
||||
|
||||
Returns the started task, or None if one was already in flight and left
|
||||
to run (single-flight skip — `coro_factory` is not invoked, so a skip
|
||||
never creates an un-awaited coroutine).
|
||||
|
||||
The entry is removed from the table when the task finishes, so the table
|
||||
only ever holds in-flight tasks and never accumulates stale keys (which
|
||||
matters for callers that use dynamic per-item keys).
|
||||
|
||||
`cancel_in_flight=True` cancels a running task under `key` and starts a
|
||||
fresh one. `error_handler` is an async callable invoked with the
|
||||
exception if the task fails.
|
||||
"""
|
||||
if not hasattr(self, "_tracked_tasks"):
|
||||
self._tracked_tasks: dict[str, asyncio.Task] = {}
|
||||
|
||||
existing = self._tracked_tasks.get(key)
|
||||
if existing is not None and not existing.done():
|
||||
if not cancel_in_flight:
|
||||
return None
|
||||
existing.cancel()
|
||||
|
||||
# The contextvar is copied into the task by create_task; the set/reset
|
||||
# is synchronous (no await between), so it never leaks to other tasks.
|
||||
token = background_processing.set(True) if background else None
|
||||
try:
|
||||
task = asyncio.create_task(coro_factory())
|
||||
finally:
|
||||
if token is not None:
|
||||
background_processing.reset(token)
|
||||
|
||||
self._tracked_tasks[key] = task
|
||||
task.add_done_callback(lambda fut: self._untrack_task(key, fut))
|
||||
|
||||
if background:
|
||||
await self.set_background_processing(task, error_handler)
|
||||
else:
|
||||
task.add_done_callback(
|
||||
lambda fut: self._on_tracked_task_done(fut, error_handler)
|
||||
)
|
||||
return task
|
||||
|
||||
def _untrack_task(self, key: str, task: asyncio.Task) -> None:
|
||||
# Only drop the entry if it's still this task — a cancel_in_flight
|
||||
# replacement may have already swapped a newer task under the same key.
|
||||
if self._tracked_tasks.get(key) is task:
|
||||
del self._tracked_tasks[key]
|
||||
|
||||
def _on_tracked_task_done(self, task: asyncio.Task, error_handler=None) -> None:
|
||||
# Foreground tasks report "busy" via @set_processing; this callback only
|
||||
# surfaces errors and consumes the result so failures don't go unnoticed.
|
||||
if task.cancelled():
|
||||
return
|
||||
exc = task.exception()
|
||||
if exc is None:
|
||||
return
|
||||
tb = "".join(traceback.format_exception(type(exc), exc, exc.__traceback__))
|
||||
log.error("tracked task error", agent=self.agent_type, exc=exc, traceback=tb)
|
||||
if error_handler is not None:
|
||||
asyncio.create_task(error_handler(exc))
|
||||
|
||||
def cancel_tracked_task(self, key: str) -> bool:
|
||||
"""Cancel the in-flight tracked task under `key`. Returns True if one
|
||||
was running and got cancelled."""
|
||||
task = self._tracked_task(key)
|
||||
if task is not None and not task.done():
|
||||
task.cancel()
|
||||
return True
|
||||
return False
|
||||
|
||||
def connect(self, scene):
|
||||
self.scene = scene
|
||||
talemate.emit.async_signals.get("game_loop_start").connect(
|
||||
|
|
@ -1124,20 +1377,19 @@ class Agent(ABC):
|
|||
)
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class AgentEmission:
|
||||
class AgentEmission(pydantic.BaseModel):
|
||||
model_config = ConfigDict(arbitrary_types_allowed=True)
|
||||
|
||||
agent: Agent
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class AgentTemplateEmission(AgentEmission):
|
||||
template_vars: dict = dataclasses.field(default_factory=dict)
|
||||
response: str = None
|
||||
dynamic_instructions: list[DynamicInstruction] = dataclasses.field(
|
||||
template_vars: dict = pydantic.Field(default_factory=dict)
|
||||
response: str | None = None
|
||||
dynamic_instructions: list[DynamicInstruction] = pydantic.Field(
|
||||
default_factory=list
|
||||
)
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class RagBuildSubInstructionEmission(AgentEmission):
|
||||
sub_instruction: str | None = None
|
||||
|
|
|
|||