Compare commits

..

13 Commits
0.30.0 ... main

Author SHA1 Message Date
veguAI
20af2a9f4b 0.34.1 - Openrouter reasoning model fixes (#241)
fix openrouter reasoning model issues
2025-12-19 23:44:52 +02:00
veguAI
c179fcd3eb 0.34.0 (#239)
Visual Agent Refactor + Visual Library
Character Card Import Refactor
Bug fixes and other improvements
2025-12-06 11:19:48 +02:00
veguAI
89d16ae513 0.33.0 (#229)
* linting

* Add cleanup function for recent scenes in config to remove non-existent paths

* remove leghacy world state manager buttons

* move world state scene tools into sub component

* linting

* move module properties to navigation drawer

* Update icons in NodeEditorLibrary and NodeEditorModuleProperties for improved UI clarity

* prompt tweaks

* director chat prompt simplifications

* more prompt fixes

* Enhance type hints for duration conversion functions in time.py

* narrate time action now has access to response length instructions

* Add IsoDateDuration node for ISO 8601 interval string construction

* Update advance_time method to include return type annotation and return message

* Add AdvanceTime node to world state for time advancement with duration and narration instructions

* linting

* Add agent state exclusions to changelog with a TODO for module migration

* Add message emission for actor, narrator, and scene analysis guidance in respective components. Enhance AgentMessages and SceneTools for better message handling and visual feedback.

* Remove agent messages from state when opening agent message view in SceneTools component.

* linting

* openroute fetch models on key set

* Add input history functionality to message input in TalemateApp component. Implement keyboard shortcuts for navigating history (Ctrl+Up/Down) and limit history to the last 10 messages. Update message sending logic to store messages in history.

* Update message input hint in TalemateApp component to include keyboard shortcuts for navigating input history (Ctrl+Up/Down).

* node updates

* unified data extraction function

* prompt tweaks

* Add gamestate context support in BuildPrompt and corresponding template. Introduced new property for gamestate context and updated rendering logic to include gamestate information in prompts.

* Refactor Prompt class by removing LoopedPrompt and cleaning up related methods. Update data response parsing to streamline functionality and improve clarity. Adjust imports accordingly.

* Add 'data_multiple' property to GenerateResponse class to allow multiple data structures in responses. Update output socket type for 'data_obj' to support both dict and list formats.

* Add DictUpdate node

* Add UnpackGameState node to retrieve and unpack game state variables

* gamestate nodes

* linting

* Enhance scene view toggle functionality to support shift-click behavior for closing all drawers when hiding the scene view.

* immutable scenes should reset context db on load

* linting

* node updates

* prompt tweaks

* Add context type output and filtering for creative context ID meta entries in PathToContextID and ContextIDMetaEntries nodes

* Add string replacement functionality and Jinja2 formatting support in nodes. Introduced 'old' and 'new' properties for substring replacement in the Replace node, and added a new Jinja2Format node for template rendering using jinja2.

* Add additional outputs for context validation in ValidateContextIDItem node, including context type, context value, and name.

* prompt tweaks

* node adjustments

* linting

* Add data_expected attribute to Focal and Prompt classes for enhanced response handling

* node updates

* node updates

* node updates

* prompt tweaks

* director summary return appropriately on no action taken

* Enhance action handling in DirectorChatMixin by skipping actions when a question is present in the parsed response, ensuring better response accuracy.

* Enhance ConfirmActionPrompt component by adding anchorTop prop for dynamic alignment and adjusting icon size and color for improved UI consistency.

* anchor clear chat confirm to top

* responsive layout fixes in template editors

* linting

* relock

* Add scene progression guidance to chat-common-tasks template

* Refactor push_history method to be asynchronous across multiple agents and scenes, ensuring consistent handling of message history updates.

* Update chat instructions to clarify user intent considerations and enhance decisiveness in responses. Added guidance on distinguishing between scene progression and background changes, and refined analysis requirements for user interactions.

* Enhance DirectorConsoleChatsToolbar by adding a usage cheat sheet tooltip for user guidance and refining the Clear Chat button's UI for better accessibility.

* store character data at unified point

* fix button

* fix world editor auto sync

* Shared context 2 (#19)

Shared context

* Refactor NodeEditorLibrary to improve search functionality and debounce input handling. Updated v-text-field model and added a watcher for search input to enhance performance.

* Refactor NodeEditor and TalemateApp components to enhance UI interactions. Removed the exit creative mode button from NodeEditor and updated tooltips for clarity. Adjusted app bar navigation icons for better accessibility and added functionality to switch between node editor and creative mode.

* comment

* Character.update deserialize voice value correctly

* Enhance SharedContext.update_to_scene method to properly add or update character data in the scene based on existence checks. This improves the synchronization of character states between shared context and scene.

* shared context static history support
fix context memory db imports to always import

* Update WorldStateManagerSceneSharedContext.vue to clarify sharing of character, world entries, and history across connected scenes.

* linting

* Enhance chat modes by adding 'nospoilers' option to DirectorChat and related payloads. Update chat instructions to reflect new mode behavior and improve UI to support mode-specific icons and colors in the DirectorConsoleChatsToolbar.

* Comment out 'repetition_penalty_range' in TabbyAPIClient to prevent unexpected "<unk><unk> .." responses. Further investigation needed.

* linting

* Add active_characters and intro_instructions to Inheritance model; implement intro generation in load_scene_from_data. Update WorldStateManagerSceneSharedContext.vue to enhance new scene creation dialog with character selection and premise instructions.

* rename inheritance to scene initialization

* linting

* Update WorldStateManagerSceneSharedContext.vue to conditionally display alert based on scene saving status and new scene creation state.

* Refine messages for shared context checkboxes in WorldStateManagerCharacter and WorldStateManagerWorldEntries components for clarity.

* Add scene title generation to load process and update contextual generation template. Introduced a new method in AssistantMixin for generating scene titles, ensuring titles are concise and free of special characters. Updated load_scene_from_data to assign generated titles to scenes.

* linting

* Refactor GameState component to integrate Codemirror for JSON editing, replacing the previous treeview structure. Implement validation for JSON input and enhance error handling. Remove unused methods and streamline state management.

* Add lastLoadedJSON property to GameState component for change detection. Update validation logic to prevent unnecessary updates when game state has not changed.

* Remove status emission for gameplay switch in CmdSetEnvironmentToScene class.

* allow individual sharing of attributes and details

* linting

* Remove redundant question handling logic in DirectorChatMixin to streamline action selection process.

* Update EXTERNAL_DESCRIPTION in TabbyAPI client to include notes on EXL3 model sensitivity to inference parameters. Adjust handling of 'repetition_penalty_range' in parameter list for clarity.

* director chat support remove message and regenerate message

* Refactor ConfirmActionInline component to improve button rendering logic. Introduced 'size' prop for button customization and added 'comfortable' density option. Simplified icon handling with computed property for better clarity.

* linting

* node updates

* Add appBusy prop to DirectorConsoleChats and DirectorConsoleChatsToolbar components to manage button states during busy operations.

* Refactor DirectorChatMixin to utilize standalone utility functions for parsing response sections and extracting action blocks. This improves code clarity and maintainability. Added tests for new utility functions in test_utils_prompt.py to ensure correct functionality.

* Update clear chat button logic to consider appBusy state in DirectorConsoleChatsToolbar component, enhancing user experience during busy operations.

* linting

* Remove plan.md

* Add chat template identifier support and error handling in ModelPrompt class

- Implemented logic to check for 'chat_template.jinja2' in Hugging Face repository.
- Added new template identifiers: GraniteIdentifier and GLMIdentifier.
- Enhanced error handling to avoid logging 404 errors for missing templates.
- Introduced Granite.jinja2 template file for prompt structure.

* node fixes

* remove debug msg

* Enhance error handling in DynamicInstruction class by enforcing header requirement and ensuring content defaults to an empty string if not provided.

* recet scene message visibility on scene load

* prompt tweaks

* Enhance data extraction in Focal class by adding a fallback mechanism. Implemented additional error handling to attempt data extraction from a fenced block if the initial extraction fails, improving robustness in handling responses.

* linting

* node fixes

* Add relative_to_root function for path resolution and update node export logic

- Introduced a new function `relative_to_root` in path.py to resolve paths relative to the TALEMATE_ROOT.
- Updated the `export_node_definitions` function in registry.py to use `relative_to_root` for module path resolution.
- Added a check to skip non-selectable node definitions in litegraphUtils.js during registration.

* show icons

* Improve error handling in export_node_definitions by adding a try-except block for module path resolution. Log a warning if the relative path conversion fails.

* typo

* Refactor base_attributes type in Character model to a more generic dict type for improved flexibility

* relock

* ensure character gets added to character_data

* prompt tweaks

* linting

* properly activate characters

* activate needs to happen explicitly now and deactivated is the default

* missing arg

* avoid changed size error

* Refactor character removal logic in shared context to prevent deletion; characters are now only marked as non-shared.

* Add update_from_scene method calls in SharedContextMixin for scene synchronization

* Add ensure_changelogs_for_all_scenes function to manage changelog files for all scenes; integrate it into the server run process.

* Enhance backup restore functionality by adding base and latest snapshot options; improve UI with clearer labels and alerts for restore actions.

* Update _apply_delta function to enhance delta application handling by adding parameters for error logging and force application of changes on non-existent paths.

* Skip processing of changelog files in _list_files_and_directories function to prevent unnecessary inclusion in file listings.

* Update IntroRecentScenes.vue to use optional chaining for selectedScene properties and enhance backup timestamp display with revision info.

* linting

* Refactor source entry attribute access in collect_source_entries function to use getattr for optional attributes, improving robustness.

* Implement logic to always show scene view in scene mode within TalemateApp.vue, enhancing user experience during scene interactions.

* prompt tweaks

* prompt tweaks

* Update TalemateApp.vue to set the active tab to 'main' when switching to the node editor, improving navigation consistency.

* Add active frontend websocket handler management in websocket_endpoint

* agent websocket handler node support

* Refactor init_nodes method in DirectorAgent to call superclass method and rename chat initialization method in DirectorChatMixin for clarity.

* Add characters output to ContextHistory node to track active participants in the scene

* Add Agent Websocket Handler option to Node Editor Library with corresponding icons and labels

* Add check for node selectability in NodeEditorNodeSearch component to filter search results accordingly.

* Add SummarizeWebsocketHandler to handle summarize actions and integrate it into SummarizeAgent

* nodes

* Add data property to QueueResponse class for websocket communication and update run method to include action and data in output values.

* Update manual context handling in WorldStateManager to include shared property from existing context

* Enhance GetWorldEntry node to include 'shared' property in output values from world entry context

* Update scene loading to allow setting scene ID from data and include ID in scene serialization

* Update icon for AgentWebsocketHandler in NodeEditorLibrary component to mdi-web-box

* Refactor WorldStateManager components to enhance history management and sharing capabilities. Added summarized history titles, improved UI for sharing static history, and integrated scene summarization functionality. Removed deprecated methods related to shared context settings.

* linting

* Change log level from warning to debug for migrate_narrator_source_to_meta error handling in NarratorMessage class.

* Update GLM-no-reasoning template to include <think></think> tag before coercion message for improved prompt structure.

* allow prompt templates to specify reasoning pattern

* Add Seed.jinja2 template for LLM prompts with reasoning patterns and user interaction handling

* Enhance NarratorAgent to support dynamic response length configuration. Updated max generation length from 192 to 256 tokens and introduced a new method to calculate response length. Modified narration methods to accept and utilize response length parameter. Added response length property in GenerateNarrationBase class and updated templates to include response length handling.

* Update response length calculation in RevisionMixin to include token count for improved text processing.

* Refactor response identifier in RevisionMixin to dynamically use calculated response length for improved prompt handling.

* linting

* allow contextual generation of static history entries

* Add is_static property to HistoryEntry for static history entry identification

* Add "static history" option to ContextualGenerate node for enhanced contextual generation capabilities.

* Add CreateStaticArchiveEntry and RemoveStaticArchiveEntry nodes for managing static history entries. Implement input/output properties and error handling for entry creation and deletion.

* nodes updated

* linting

* Add assets field to SceneInitialization model and update load_scene_from_data function to handle scene assets. Update WorldStateManagerSceneSharedContext.vue to include assets in scene initialization parameters.

* Refactor CoverImage component to enhance drag-and-drop functionality and improve styling for empty portrait state.

* Add intent_state to SceneInitialization model and update load_scene_from_data function to handle intent state. Introduce story_intent property in Scene class and reset method in SceneIntent class. Update WorldStateManagerSceneSharedContext.vue to include intent state in scene initialization parameters.

* Refactor WorldStateManagerSceneSharedContext.vue to improve cancel functionality by introducing a dedicated cancelCreate method and removing the direct dialog toggle from the Cancel button. This enhances code clarity and maintainability.

* Update SharedContext to use await for set_shared method, ensuring proper asynchronous handling when modifying character sharing status.

* Add MAX_CONTENT_WIDTH constant and update components to use it for consistent max width styling

* fix issue with data structure parsing

* linting

* fix tests

* nodes

* fix update_introduction

* Add building blocks template for story configuration and scene management

* Refactor toggleNavigation method to accept an 'open' parameter for direct control over drawer visibility in TalemateApp.vue

* Update usageCheatSheet text in DirectorConsoleChatsToolbar.vue for clarity and add pre-wrap styling to tooltip

* Add cover image and writing style sections to story and character templates; update chat common tasks with new scene restrictions and user guide reference.

* linting

* relock

* Add EmitWorldEditorSync node to handle world editor synchronization; update WorldStateManager to refresh active tab on sync action.

* Update Anthropic client with new models and adjust default settings; introduce limited parameter models for specific configurations.

* director action  module updates

* direct context update fn

* director action updates

* Update usageCheatSheet in DirectorConsoleChatsToolbar.vue to include recommendation for 100B+ models.

* Remove debug diagnostics from DirectorConsoleChats.vue to clean up console output.

* Update card styles in IntroRecentScenes.vue for improved visual consistency; change card color to grey-darken-3 and adjust text classes for titles and subtitles.

* Update EmitWorldEditorSync node to include websocket passthrough in sync action for improved event handling.

* Increase maximum changelog file size limit from 500KB to 1MB to accommodate larger change logs.

* linting

* director action module updates

* 0.33 added

* Add Nexus agent persona to talemate template and initialize phrases array

* Add support for project-specific grouping in NodeEditorLibrary for templates/modules, enhancing organization of node groups.

* docs

* Enhance NodeEditorLibrary by adding primary color to tree component for improved visibility and user experience.

* docs

* Enhance NewSceneSetupModal to include subtitles for writing styles and director personas, improving context and usability.

* Update agent persona description in WorldStateManagerTemplates to specify current support for director only, enhancing clarity for users.

* Refine agent persona description in WorldStateManagerTemplates to clarify assignment per agent in Scene Settings, maintaining focus on current director-only support.

* fix crash when attempting to delete some clients

* Add TODO comments in finalize_llama3 and finalize_YI methods to indicate removable cruft

* Add lock_template feature to Client configuration and update related components for template management

* linting

* persist client template lock through model changes

* There is no longer a point to enforcing creative mode when there are no characters

* fix direct_narrator character argument

* Update CharacterContextItem to allow 'value' to accept dict type in addition to existing types

* docs

* Update lock_template field in Client model to allow None type in addition to bool

* Remove unused template_file field from Defaults model in Client configuration

* Refactor lock_template field in Client model and ClientModal component to ensure consistent boolean handling

* Add field validator for lock_template in Client model to ensure boolean value is returned

* fix issue where valid data processed in extract_data_with_ai_fallback was not returned

* Update default_player_character assignment in ConfigPlugin to use GamePlayerCharacter schema for improved data validation

* linting

* add heiku 4.5 model and make default

* opse 4.5 isnt a thing

* fix issue where  fork / restore would restore duplicate messages

* improve autocomplete handling when prefill isn't available

* prompt tweaks

* linting

* gracefully handle removed attributes

* Refactor scene reference handling in delete_changelog_files to prevent incorrect deletions. Added a test to verify proper scene reference construction and ensure changelog files are deleted correctly.

* forked scenes reset memory id and are not immutable

* emit_status export rev

* Update RequestInput.vue to handle extra_params more robustly, ensuring defaults are set correctly for input.

* only allow forking on saved messages

* linting

* tweak defaults

* summarizer fire off of push_history.after

* docs

* : in world entry titles will now load correctly

* linting

* docs

* removing base attrib ute or detail also clears it from shared list

* fix issue where cancelling some generations would cause errors

* increase font size

* formatting fixes

* unhandled errors at the loop level should not crash the entire scene

* separate message processing from main loop

* linting

* remove debug cruft

* enhance error logging in background processing to include traceback information

* linting

* nothing to detemrine of no model is sent

* fix some errors during kcpp client deletion

* improve configuration issue alert visibility

* restore input focus after autocomplete

* linting
2025-10-25 14:06:55 +03:00
veguAI
72867c930e 0.32.3 (#219)
* set 0.33.0

* fix nodeeditor context menu issues

* notes
2025-08-24 17:17:08 +03:00
veguAI
eddddd5034 0.32.2 (#216)
* fix api url error in koboldcpp

* set 0.32.2

* relock

* add 0.32.2 note
2025-08-23 19:20:39 +03:00
veguAI
25e646c56a 0.32.1 (#213)
* GLM 4.5 templates

* set 0.33 and relock

* fix issues with character creation

* relock

* prompt tweaks

* fix lmstudio

* fix issue with npm on windows failing on paths
set 0.32.1

* linting

* update what's new

* #214 (#215)

* max-height and overflow

* max-height and overflow

* v-tabs to list and offset new scrollbar at the top so it doesnt overlap into the divider

* tweaks

* tweaks

* prompt tweaks

---------

Co-authored-by: Iceman Oakenbear <89090218+IcemanOakenbear@users.noreply.github.com>
2025-08-23 01:16:18 +03:00
veguAI
ce4c302d73 0.32.0 (#208)
* separate other tts apis and improve chunking

* move old tts config to voice agent config and implement config widget ux elements for table editing

* elevenlabs updated to use their client and expose model selection

* linting

* separate character class into character.pt and start on voice routing

* linting

* tts hot swapping and chunking improvements

* linting

* add support for piper-tts

* update gitignore

* linting

* support google tts
fix issue where quick_toggle agent config didnt work on standard config items

* linting

* only show agent quick toggles if the agent is enabled

* change elevenlabs to use a locally maintained voice list

* tts generate before / after events

* voice library refactor

* linting

* update openai model and voices

* tweak configs

* voice library ux

* linting

* add support for kokoro tts

* fix add / remove voice

* voice library tags

* linting

* linting

* tts api status

* api infos and add more kokoro voices

* allow voice testing before saving a new voice

* tweaks to voice library ux and some api info text

* linting

* voice mixer

* polish

* voice files go into /tts instead of templates/voice

* change default narrator voice

* xtts confirmation note

* character voice select

* koboldai format template

* polish

* skip empty chunks

* change default voice

* replace em-dash with normal dash

* adjust limit

* replace libebreaks

* chunk cleanup for whitespace

* info updated

* remove invalid endif tag

* sort voices by ready api

* Character hashable type

* clarify set_simulated_environment use to avoid unwanted character deactivated

* allow manual generation of tts and fix assorted issues with tts

* tts websocket handler router renamed

* voice mixer: when there are only 2 voices auto adjust the other weight as needed

* separate persist character functions into own mixin

* auto assign voices

* fix chara load and auto assign voice during chara load

* smart speaker separation

* tts speaker separation config

* generate tts for intro text

* fix prompting issues with anthropic, google and openrouter clients

* decensor flag off again

* only to ai assisted voice markup on narrator messages

* openrouter provider configuration

* linting

* improved sound controls

* add support for chatterbox

* fix info

* chatterbox dependencies

* remove piper and xtts2

* linting

* voice params

* linting

* tts model overrides and move tts info to tab

* reorg toolbar

* allow overriding of test text

* more tts fixes, apply intensity, chatterbox voices

* confirm voice delete

* lintinG

* groq updates

* reorg decorators

* tts fixes

* cancelable audio queue

* voice library uploads

* scene voice library

* Config refactor (#13)

* config refactor progres

* config nuke continues

* fix system prompts

* linting

* client fun

* client config refactor

* fix kcpp auto embedding selection

* linting

* fix proxy config

* remove cruft

* fix remaining client bugs from config refactor
always use get_config(), dont keep an instance reference

* support for reasoning models

* more reasoning tweaks

* only allow one frontend to connect at a time

* fix tests

* relock

* relock

* more client adjustments

* pattern prefill

* some tts agent fixes

* fix ai assist cond

* tts nodes

* fix config retrieval

* assign voice node and fixes

* sim suite char gen assign voice

* fix voice assign template to consider used voices

* get rid of auto break repetition which wasn't working right for a while anyhow

* linting

* generate tts node
as string node

* linting

* voice change on character event

* tweak chatterbox max length

* koboldai default template

* linting

* fix saving of existing voice

* relock

* adjust params of eva default voice

* f5tts support

* f5tts samples

* f5tts support

* f5tts tweaks

* chunk size per tts api and reorg defaul f5tts voices

* chatterbox default voice reog to match f5-tts default voices

* voice library ux polish pass

* cleanup

* f5-tts tweaks

* missing samples

* get rid of old save cmd

* add chatterbox and f5tts

* housekeeping

* fix some issues with world entry editing

* remove cruft

* replace exclamation marks

* fix save immutable check

* fix replace_exclamation_marks

* better error handling in websocket plugins and fix issue with saves

* agent config save on dialog close

* ctrl click to disable / enable agents

* fix quick config

* allow modifying response size of focal requests

* sim suite set goal always sets story intent, encourage calling of set goal during simulation start

* allow setting of model

* voice param tweaks

* tts tweaks

* fix character card load

* fix note_on_value

* add mixed speaker_separation mode

* indicate which message the audio is for and provide way to stop audio from the message

* fix issue with some tts generation failing

* linting

* fix speaker separate modes

* bad idea

* linting

* refactor speaker separation prompt

* add kimi think pattern

* fix issue with unwanted cover image replacemenT

* no scene analysis for visual promp generation (for now)

* linting

* tts for context investigation messages

* prompt tweaks

* tweak intro

* fix intro text tts not auto playing sometimes

* consider narrator voice when assigning voice tro a character

* allow director log messages to go only into the director console

* linting

* startup performance fixes

* init time

* linting

* only show audio control for messagews taht can have it

* always create story intent and dont override existing saves during character card load

* fix history check in dynamic story line node
add HasHistory node

* linting

* fix intro message not having speaker separation

* voice library character manager

* sequantial and cancelable auto assign all

* linting

* fix generation cancel handling

* tooltips

* fix auto assign voice from scene voices

* polish

* kokoro does not like lazy import

* update info text

* complete scene export / import

* linting

* wording

* remove cruft

* fix story intent generation during character card import

* fix generation cancelled emit status inf loop

* prompt tweak

* reasoning quick toggle, reasoning token slider, tooltips

* improved reasoning pattern handling

* fix indirect coercion response parsing

* fix streaming issue

* response length instructions

* more robust streaming

* adjust default

* adjust formatting

* litning

* remove debug output

* director console log function calls

* install cuda script updated

* linting

* add another step

* adjust default

* update dialogue examples

* fix voice selection issues

* what's happening here

* third time's the charm?

* Vite migration (#207)

* add vite config

* replace babel, webpack, vue-cli deps with vite, switch to esm modules, separate eslint config

* change process.env to import.meta.env

* update index.html for vite and move to root

* update docs for vite

* remove vue cli config

* update example env with vite

* bump frontend deps after rebase to 32.0

---------

Co-authored-by: pax-co <Pax_801@proton.me>

* properly referencer data type

* what's new

* better indication of dialogue example supporting multiple lines, improve dialogue example display

* fix potential issue with cached scene anlysis being reused when it shouldn't

* fix character creation issues with player character toggle

* fix issue where editing a message would sometimes lose parts of the message

* fix slider ux thumb labels (vuetify update)

* relock

* narrative conversation format

* remove planning step

* linting

* tweaks

* don't overthink

* update dialogue examples and intro

* dont dictate response length instructions when data structures are expected

* prompt tweaks

* prompt tweaks

* linting

* fix edit message not handling : well

* prompt tweaks

* fix tests

* fix manual revision when character message was generated in new narrative mode

* fix issue with message editing

* Docker packages relese (#204)

* add CI workflow for Docker image build and MkDocs deployment

* rename CI workflow from 'ci' to 'package'

* refactor CI workflow: consolidate container build and documentation deployment into a single file

* fix: correct indentation for permissions in CI workflow

* fix: correct indentation for steps in deploy-docs job in CI workflow

* build both cpu and cuda image

* docs

* docs

* expose writing style during state reinforcement

* prompt tweaks

* test container build

* test container  image

* update docker compose

* docs

* test-container-build

* test container build

* test container build

* update docker build workflows

* fix guidance prompt prefix not being dropped

* mount tts dir

* add gpt-5

* remove debug output

* docs

* openai auto toggle reasoning based on model selection

* linting

---------

Co-authored-by: pax-co <123330830+pax-co@users.noreply.github.com>
Co-authored-by: pax-co <Pax_801@proton.me>
Co-authored-by: Luis Alexandre Deschamps Brandão <brandao_luis@yahoo.com>
2025-08-08 13:56:29 +03:00
vegu-ai-tools
685ca994f9 linting can be done at merge 2025-07-06 20:32:40 +03:00
vegu-ai-tools
285b0699ab contributing.md 2025-07-06 18:41:44 +03:00
vegu-ai-tools
7825489cfc add contributing.md 2025-07-06 18:37:00 +03:00
veguAI
fb2fa31f13 linting
* precommit

* linting

* add linting to workflow

* ruff.toml added
2025-06-29 19:51:08 +03:00
veguAI
9eb4c48d79 0.31.0 (#193)
* some prompt cleanup

* prompt tweaks

* prompt tweaks

* prompt tweaks

* set 0.31.0

* relock

* rag queries add brief analysis

* brief analysis before building rag questions

* rag improvements

* prompt tweaks

* address circular import issues

* set 0.30.1

* docs

* numpy to 2

* docs

* prompt tweaks

* prompt tweak

* some template cleanup

* prompt viewer increase height

* fix codemirror highlighting not working

* adjust details height

* update default

* change to log debug

* allow response to scale to max height

* template cleanup

* prompt tweaks

* first progress for installing modules to scene

* package install logic

* package install polish

* package install polish

* package install polish and fixes

* refactor initial world state update and expose setting for it

* add `num` property to ModuleProperty to control order of widgets

* dynamic storyline package info

* fix issue where deactivating player character would cause inconsistencies in the creative tools menui

* cruft

* add openrouter support

* ollama support

* refactor how model choices are loaded, so that can be done per client instance as opposed to just per client type

* set num_ctx

* remove debug messages

* ollama tweaks

* toggle for whether or not default character gets added to blank talemate scenes

* narrator prompt tweaks and template cleanup

* cleanup

* prompt tweaks and template cleanup

* prompt tweaks

* fix instructor embeddings

* add additional error handling to prevent broken world state templates from breaking the world editor side menu

* fix openrouter breaking startup if not configured

* remove debug message

* promp tweaks

* fix example dialogue generation no longer working

* prompt tweaks and better showing of dialogue examples in conversation instructions

* prompt tweak

* add initial startup message

* prompt tweaks

* fix asset error

* move complex acting instructions into the task block

* fix content input socket on DynamicInstructions node

* log.error with traceback over log.exception since that has a tendency to explode and hang everything

* fix usse with number nodes where they would try to execute even if the incoming wire wasnt active

* fix issue with editor revision events missing template_vars

* DynamicInstruction node should only run if both header and content can resolve

* removed remaining references to 90s adventure game writing style

* prompt tweaks

* support embeddings via client apis (koboldcpp)

* fix label on client-api embeddings

* fix issue where adding / removing an embedding preset would not be reflected immediately in the memory agent config

* remove debug output

* prompt tweaks

* prompt tweaks

* autocomplete passes message object

* validate group names to be filename valid

* embedded winsows env installs and up to poetry2

* version config

* get-pip

* relock

* pin runpod

* no longer needed

* remove rapidfuzz dependency

* nodejs directly into embedded_node without a versioned middleman dir - also remove defunct local-tts install script

* fix update script

* update script error handling

* update.bat error handling

* adjust wording

* support loading jinja2 templates node modules in templates/modules

* update google model list

* client t/s and business indicator - also switch all clients to async streaming

* formatting

* support coercion for anthropic / google
switch to the new google genai sdk
upgrade websockets

* more coercion fixes

* gracefully handle keyboard interrupt

* EmitSystemMessage node

* allow visual prompt generation without image generation

* relock

* chromadb to v1

* fix error handling

* fix issue where adding client model list would be empty

* supress pip install warnings

* allow overriding of base urls

* remove key from log

* add fade effect

* tweak request info ux

* further clarification of endpoint override api key

* world state manager: fix issue that caused max changes setting to disappear from character progress config

* fix issue with google safety settings off causing generation failures

* update to base url should always reset the client

* getattr

* support v3 chara card version and attempt to future proof

* client based embeddings improvements

* more fixes for client based embeddings

* use client icon

* history management tools progress

* history memory ids fixed and added validation

* regenerate summary fixes

* more history regeneration fixes

* fix layered history gen and prompt twweaks

* allow regeneration of individual layered history entries

* return list of LayeredArchiveEntry

* reorg for less code dupelication

* new scene message renderer based on marked

* add inspect functionality to history viewer

* message if no history entries yet

* allow adding of history entries manually

* allow deletion of history

* summarization unslop improvements

* fix make charcter real action from worldstate listing

* allow overriding length in all context generation isntructioon dialogs

* fix issue where extract_list could fail with an unhandled error if the llm response didnt contain a list

* update whats'new

* fix issues with the new history management tools

* fix check

* Switch dependency handling to UV (#202)

* Migrate from Poetry to uv package manager            (#200)

* migrate from poetry to uv package manager

* Update all installation and startup scripts for uv migration

* Fix pyproject.toml for uv - allow direct references for hatchling

* Fix PR feedback: Restore removed functionality

- Restored embedded Python/Node.js functionality in install.bat and update.bat
- Restored environment variable exposure in docker-compose.yml (CUDA_AVAILABLE, port configs)
- Fixed GitHub Actions branches (main, prep-* instead of main, dev)
- Restored fail-fast: false and cache configuration in test.yml

These changes preserve all the functionality that should not be removed
during the migration from Poetry to uv.

---------

Co-authored-by: Ztripez von Matérn <ztripez@bobby.se>

* remove uv.lock from .gitignore

* add lock file

* fix install issues

* warn if unable to remove legacy poetry virt env dir

* uv needs to be explicitly installed into the .venv so its available

* third time's the charm?

* fix windows install scripts

* add .venv guard to update.bat

* call :die

* fix docker venv install

* node 21

* fix cuda install

* start.bat calls install if needed

* sync start-local to other startup scripts

* no need to activate venv

---------

Co-authored-by: Ztripez <reg@otherland.nu>
Co-authored-by: Ztripez von Matérn <ztripez@bobby.se>

* ignore hfhub symlink warnings

* add openrouter and ollama mentions

* update windows install documentation

* docs

* docs

* fix issue with memory agent fingerprint

* removing a client that supports embeddings will also remove any embedding functions it created

* on invalid embeddings reset to default

* docs

* typo

* formatting

* docs

* docs

* install package

* adjust topic

* add more obvious way to exit creative mode

* when importing character cards immediately persist a usable save after the restoration save

---------

Co-authored-by: Ztripez <reg@otherland.nu>
Co-authored-by: Ztripez von Matérn <ztripez@bobby.se>
2025-06-29 18:06:11 +03:00
veguAI
e4d465ba42 0.30.1 (#190)
* address circular import issues

* set 0.30.1

* docs

* numpy to 2

* docs
2025-06-10 21:05:46 +03:00
887 changed files with 151631 additions and 37691 deletions

View File

@@ -1,30 +1,76 @@
name: ci
name: ci
on:
push:
branches:
- master
- main
- prep-0.26.0
- master
release:
types: [published]
permissions:
contents: write
packages: write
jobs:
deploy:
container-build:
if: github.event_name == 'release'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Configure Git Credentials
- name: Remove unnecessary files to release disk space
run: |
git config user.name github-actions[bot]
git config user.email 41898282+github-actions[bot]@users.noreply.github.com
- uses: actions/setup-python@v5
sudo rm -rf \
"$AGENT_TOOLSDIRECTORY" \
/opt/ghc \
/opt/google/chrome \
/opt/microsoft/msedge \
/opt/microsoft/powershell \
/opt/pipx \
/usr/lib/mono \
/usr/local/julia* \
/usr/local/lib/android \
/usr/local/lib/node_modules \
/usr/local/share/chromium \
/usr/local/share/powershell \
/usr/local/share/powershell \
/usr/share/dotnet \
/usr/share/swift
- name: Log in to GHCR
uses: docker/login-action@v3
with:
python-version: 3.x
- run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build & push
uses: docker/build-push-action@v5
with:
context: .
file: Dockerfile
push: true
tags: |
ghcr.io/${{ github.repository }}:latest
ghcr.io/${{ github.repository }}:${{ github.ref_name }}
deploy-docs:
if: github.event_name == 'release'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Configure Git credentials
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
- uses: actions/setup-python@v5
with: { python-version: '3.x' }
- run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV
- uses: actions/cache@v4
with:
key: mkdocs-material-${{ env.cache_id }}
path: .cache
restore-keys: |
mkdocs-material-
restore-keys: mkdocs-material-
- run: pip install mkdocs-material mkdocs-awesome-pages-plugin mkdocs-glightbox
- run: mkdocs gh-deploy --force

View File

@@ -0,0 +1,51 @@
name: test-container-build
on:
push:
branches: [ 'prep-*' ]
permissions:
contents: read
packages: write
jobs:
container-build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Remove unnecessary files to release disk space
run: |
sudo rm -rf \
"$AGENT_TOOLSDIRECTORY" \
/opt/ghc \
/opt/google/chrome \
/opt/microsoft/msedge \
/opt/microsoft/powershell \
/opt/pipx \
/usr/lib/mono \
/usr/local/julia* \
/usr/local/lib/android \
/usr/local/lib/node_modules \
/usr/local/share/chromium \
/usr/local/share/powershell \
/usr/local/share/powershell \
/usr/share/dotnet \
/usr/share/swift
- name: Log in to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build & push
uses: docker/build-push-action@v5
with:
context: .
file: Dockerfile
push: true
# Tag with prep suffix to avoid conflicts with production
tags: |
ghcr.io/${{ github.repository }}:${{ github.ref_name }}

View File

@@ -2,9 +2,9 @@ name: Python Tests
on:
push:
branches: [ master, main, 'prep-*' ]
branches: [ main, 'prep-*' ]
pull_request:
branches: [ master, main, 'prep-*' ]
branches: [ main, 'prep-*' ]
jobs:
test:
@@ -23,25 +23,29 @@ jobs:
python-version: ${{ matrix.python-version }}
cache: 'pip'
- name: Install poetry
- name: Install uv
run: |
python -m pip install --upgrade pip
pip install poetry
pip install uv
- name: Cache poetry dependencies
- name: Cache uv dependencies
uses: actions/cache@v4
with:
path: ~/.cache/pypoetry
key: ${{ runner.os }}-poetry-${{ matrix.python-version }}-${{ hashFiles('**/poetry.lock') }}
path: ~/.cache/uv
key: ${{ runner.os }}-uv-${{ matrix.python-version }}-${{ hashFiles('**/pyproject.toml') }}
restore-keys: |
${{ runner.os }}-poetry-${{ matrix.python-version }}-
${{ runner.os }}-uv-${{ matrix.python-version }}-
- name: Install dependencies
run: |
python -m venv talemate_env
source talemate_env/bin/activate
poetry config virtualenvs.create false
poetry install
uv venv
source .venv/bin/activate
uv pip install -e ".[dev]"
- name: Run linting
run: |
source .venv/bin/activate
uv run pre-commit run --all-files
- name: Setup configuration file
run: |
@@ -49,10 +53,10 @@ jobs:
- name: Download NLTK data
run: |
source talemate_env/bin/activate
source .venv/bin/activate
python -c "import nltk; nltk.download('punkt_tab')"
- name: Run tests
run: |
source talemate_env/bin/activate
source .venv/bin/activate
pytest tests/ -p no:warnings

16
.gitignore vendored
View File

@@ -8,8 +8,20 @@
talemate_env
chroma
config.yaml
.cursor
.claude
# uv
.venv/
templates/llm-prompt/user/*.jinja2
templates/world-state/*.yaml
tts/voice/piper/*.onnx
tts/voice/piper/*.json
tts/voice/kokoro/*.pt
tts/voice/xtts2/*.wav
tts/voice/chatterbox/*.wav
tts/voice/f5tts/*.wav
tts/voice/voice-library.json
scenes/
!scenes/infinity-quest-dynamic-scenario/
!scenes/infinity-quest-dynamic-scenario/assets/
@@ -18,4 +30,6 @@ scenes/
!scenes/infinity-quest/assets/
!scenes/infinity-quest/infinity-quest.json
tts_voice_samples/*.wav
third-party-docs/
third-party-docs/
legacy-state-reinforcements.yaml
CLAUDE.md

16
.pre-commit-config.yaml Normal file
View File

@@ -0,0 +1,16 @@
fail_fast: false
exclude: |
(?x)^(
tests/data/.*
|install-utils/.*
)$
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: v0.12.1
hooks:
# Run the linter.
- id: ruff
args: [ --fix ]
# Run the formatter.
- id: ruff-format

1
.python-version Normal file
View File

@@ -0,0 +1 @@
3.11

64
CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,64 @@
# Contributing to Talemate
## About This Project
Talemate is a **personal hobbyist project** that I maintain in my spare time. While I appreciate the community's interest and contributions, please understand that:
- This is primarily a passion project that I enjoy working on myself
- I have limited time for code reviews and prefer to spend that time developing fixes or new features myself
- Large contributions require significant review and testing time that takes away from my own development
For these reasons, I've established contribution guidelines that balance community involvement with my desire to actively develop the project myself.
## Contribution Policy
**I welcome small bugfix and small feature pull requests!** If you've found a bug and have a fix, or have a small feature improvement, I'd love to review it.
However, please note that **I am not accepting large refactors or major feature additions** at this time. This includes:
- Major architectural changes
- Large new features or significant functionality additions
- Large-scale code reorganization
- Breaking API changes
- Features that would require significant maintenance
## What is accepted
**Small bugfixes** - Fixes for specific, isolated bugs
**Small features** - Minor improvements that don't break existing functionality
**Documentation fixes** - Typo corrections, clarifications in existing docs
**Minor dependency updates** - Security patches or minor version bumps
## What is not accepted
**Major features** - Large new functionality or systems
**Large refactors** - Code reorganization or architectural changes
**Breaking changes** - Any changes that break existing functionality
**Major dependency changes** - Framework upgrades or replacements
## Submitting a PR
If you'd like to submit a bugfix or small feature:
1. **Open an issue first** - Describe the bug you've found or feature you'd like to add
2. **Keep it small** - Focus on one specific issue or small improvement
3. **Follow existing code style** - Match the project's current patterns
4. **Don't break existing functionality** - Ensure all existing tests pass
5. **Include tests** - Add or update tests that verify your fix or feature
6. **Update documentation** - If your changes affect behavior, update relevant docs
## Testing
Ensure all tests pass by running:
```bash
uv run pytest tests/ -p no:warnings
```
## Questions?
If you're unsure whether your contribution would be welcome, please open an issue to discuss it first. This saves everyone time and ensures alignment with the project's direction.

View File

@@ -1,15 +1,19 @@
# Stage 1: Frontend build
FROM node:21 AS frontend-build
ENV NODE_ENV=development
FROM node:21-slim AS frontend-build
WORKDIR /app
# Copy the frontend directory contents into the container at /app
COPY ./talemate_frontend /app
# Copy frontend package files
COPY talemate_frontend/package*.json ./
# Install all dependencies and build
RUN npm install && npm run build
# Install dependencies
RUN npm ci
# Copy frontend source
COPY talemate_frontend/ ./
# Build frontend
RUN npm run build
# Stage 2: Backend build
FROM python:3.11-slim AS backend-build
@@ -22,31 +26,17 @@ RUN apt-get update && apt-get install -y \
gcc \
&& rm -rf /var/lib/apt/lists/*
# Install poetry
RUN pip install poetry
# Install uv
RUN pip install uv
# Copy poetry files
COPY pyproject.toml poetry.lock* /app/
# Copy installation files
COPY pyproject.toml uv.lock /app/
# Create a virtual environment
RUN python -m venv /app/talemate_env
# Activate virtual environment and install dependencies
RUN . /app/talemate_env/bin/activate && \
poetry config virtualenvs.create false && \
poetry install --only main --no-root
# Copy the Python source code
# Copy the Python source code (needed for editable install)
COPY ./src /app/src
# Conditional PyTorch+CUDA install
ARG CUDA_AVAILABLE=false
RUN . /app/talemate_env/bin/activate && \
if [ "$CUDA_AVAILABLE" = "true" ]; then \
echo "Installing PyTorch with CUDA support..." && \
pip uninstall torch torchaudio -y && \
pip install torch~=2.4.1 torchaudio~=2.4.1 --index-url https://download.pytorch.org/whl/cu121; \
fi
# Create virtual environment and install dependencies (includes CUDA support via pyproject.toml)
RUN uv sync
# Stage 3: Final image
FROM python:3.11-slim
@@ -55,10 +45,31 @@ WORKDIR /app
RUN apt-get update && apt-get install -y \
bash \
wget \
tar \
xz-utils \
&& rm -rf /var/lib/apt/lists/*
# Install uv in the final stage
RUN pip install uv
# Copy virtual environment from backend-build stage
COPY --from=backend-build /app/talemate_env /app/talemate_env
COPY --from=backend-build /app/.venv /app/.venv
# Download and install FFmpeg 8.0 with shared libraries into .venv (matching Windows installer approach)
# Using BtbN FFmpeg builds which provide shared libraries - verified to work
# Note: We tried using jrottenberg/ffmpeg:8.0-ubuntu image but copying libraries from it didn't work properly,
# so we use the direct download approach which is more reliable and matches the Windows installer
RUN cd /tmp && \
wget -q https://github.com/BtbN/FFmpeg-Builds/releases/download/latest/ffmpeg-master-latest-linux64-gpl-shared.tar.xz -O ffmpeg.tar.xz && \
tar -xf ffmpeg.tar.xz && \
cp -a ffmpeg-master-latest-linux64-gpl-shared/bin/* /app/.venv/bin/ && \
cp -a ffmpeg-master-latest-linux64-gpl-shared/lib/* /app/.venv/lib/ && \
rm -rf ffmpeg-master-latest-linux64-gpl-shared ffmpeg.tar.xz && \
LD_LIBRARY_PATH=/app/.venv/lib /app/.venv/bin/ffmpeg -version | head -n 1
# Set LD_LIBRARY_PATH so torchcodec can find ffmpeg libraries at runtime
ENV LD_LIBRARY_PATH=/app/.venv/lib:${LD_LIBRARY_PATH}
# Copy Python source code
COPY --from=backend-build /app/src /app/src
@@ -83,4 +94,4 @@ EXPOSE 5050
EXPOSE 8080
# Use bash as the shell, activate the virtual environment, and run backend server
CMD ["/bin/bash", "-c", "source /app/talemate_env/bin/activate && python src/talemate/server/run.py runserver --host 0.0.0.0 --port 5050 --frontend-host 0.0.0.0 --frontend-port 8080"]
CMD ["uv", "run", "src/talemate/server/run.py", "runserver", "--host", "0.0.0.0", "--port", "5050", "--frontend-host", "0.0.0.0", "--frontend-port", "8080"]

View File

@@ -39,12 +39,14 @@ Need help? Join the new [Discord community](https://discord.gg/8bGNRmFxMj)
- [Cohere](https://www.cohere.com/)
- [Groq](https://www.groq.com/)
- [Google Gemini](https://console.cloud.google.com/)
- [OpenRouter](https://openrouter.ai/)
Supported self-hosted APIs:
- [KoboldCpp](https://koboldai.org/cpp) ([Local](https://koboldai.org/cpp), [Runpod](https://koboldai.org/runpodcpp), [VastAI](https://koboldai.org/vastcpp), also includes image gen support)
- [oobabooga/text-generation-webui](https://github.com/oobabooga/text-generation-webui) (local or with runpod support)
- [LMStudio](https://lmstudio.ai/)
- [TabbyAPI](https://github.com/theroyallab/tabbyAPI/)
- [Ollama](https://ollama.com/)
Generic OpenAI api implementations (tested and confirmed working):
- [DeepInfra](https://deepinfra.com/)

20
docker-compose.manual.yml Normal file
View File

@@ -0,0 +1,20 @@
version: '3.8'
services:
talemate:
build:
context: .
dockerfile: Dockerfile
ports:
- "${FRONTEND_PORT:-8080}:8080"
- "${BACKEND_PORT:-5050}:5050"
volumes:
- ./config.yaml:/app/config.yaml
- ./scenes:/app/scenes
- ./templates:/app/templates
- ./chroma:/app/chroma
- ./tts:/app/tts
environment:
- PYTHONUNBUFFERED=1
- PYTHONPATH=/app/src:$PYTHONPATH
command: ["uv", "run", "src/talemate/server/run.py", "runserver", "--host", "0.0.0.0", "--port", "5050", "--frontend-host", "0.0.0.0", "--frontend-port", "8080"]

View File

@@ -2,11 +2,7 @@ version: '3.8'
services:
talemate:
build:
context: .
dockerfile: Dockerfile
args:
- CUDA_AVAILABLE=${CUDA_AVAILABLE:-false}
image: ghcr.io/vegu-ai/talemate:latest
ports:
- "${FRONTEND_PORT:-8080}:8080"
- "${BACKEND_PORT:-5050}:5050"
@@ -15,7 +11,8 @@ services:
- ./scenes:/app/scenes
- ./templates:/app/templates
- ./chroma:/app/chroma
- ./tts:/app/tts
environment:
- PYTHONUNBUFFERED=1
- PYTHONPATH=/app/src:$PYTHONPATH
command: ["/bin/bash", "-c", "source /app/talemate_env/bin/activate && python src/talemate/server/run.py runserver --host 0.0.0.0 --port 5050 --frontend-host 0.0.0.0 --frontend-port 8080"]
command: ["uv", "run", "src/talemate/server/run.py", "runserver", "--host", "0.0.0.0", "--port", "5050", "--frontend-host", "0.0.0.0", "--frontend-port", "8080"]

View File

@@ -1,60 +1,63 @@
import os
import re
import subprocess
from pathlib import Path
import argparse
def find_image_references(md_file):
"""Find all image references in a markdown file."""
with open(md_file, 'r', encoding='utf-8') as f:
with open(md_file, "r", encoding="utf-8") as f:
content = f.read()
pattern = r'!\[.*?\]\((.*?)\)'
pattern = r"!\[.*?\]\((.*?)\)"
matches = re.findall(pattern, content)
cleaned_paths = []
for match in matches:
path = match.lstrip('/')
if 'img/' in path:
path = path[path.index('img/') + 4:]
path = match.lstrip("/")
if "img/" in path:
path = path[path.index("img/") + 4 :]
# Only keep references to versioned images
parts = os.path.normpath(path).split(os.sep)
if len(parts) >= 2 and parts[0].replace('.', '').isdigit():
if len(parts) >= 2 and parts[0].replace(".", "").isdigit():
cleaned_paths.append(path)
return cleaned_paths
def scan_markdown_files(docs_dir):
"""Recursively scan all markdown files in the docs directory."""
md_files = []
for root, _, files in os.walk(docs_dir):
for file in files:
if file.endswith('.md'):
if file.endswith(".md"):
md_files.append(os.path.join(root, file))
return md_files
def find_all_images(img_dir):
"""Find all image files in version subdirectories."""
image_files = []
for root, _, files in os.walk(img_dir):
# Get the relative path from img_dir to current directory
rel_dir = os.path.relpath(root, img_dir)
# Skip if we're in the root img directory
if rel_dir == '.':
if rel_dir == ".":
continue
# Check if the immediate parent directory is a version number
parent_dir = rel_dir.split(os.sep)[0]
if not parent_dir.replace('.', '').isdigit():
if not parent_dir.replace(".", "").isdigit():
continue
for file in files:
if file.lower().endswith(('.png', '.jpg', '.jpeg', '.gif', '.svg')):
if file.lower().endswith((".png", ".jpg", ".jpeg", ".gif", ".svg")):
rel_path = os.path.relpath(os.path.join(root, file), img_dir)
image_files.append(rel_path)
return image_files
def grep_check_image(docs_dir, image_path):
"""
Check if versioned image is referenced anywhere using grep.
@@ -65,33 +68,46 @@ def grep_check_image(docs_dir, image_path):
parts = os.path.normpath(image_path).split(os.sep)
version = parts[0] # e.g., "0.29.0"
filename = parts[-1] # e.g., "world-state-suggestions-2.png"
# For versioned images, require both version and filename to match
version_pattern = f"{version}.*{filename}"
try:
result = subprocess.run(
['grep', '-r', '-l', version_pattern, docs_dir],
["grep", "-r", "-l", version_pattern, docs_dir],
capture_output=True,
text=True
text=True,
)
if result.stdout.strip():
print(f"Found reference to {image_path} with version pattern: {version_pattern}")
print(
f"Found reference to {image_path} with version pattern: {version_pattern}"
)
return True
except subprocess.CalledProcessError:
pass
except Exception as e:
print(f"Error during grep check for {image_path}: {e}")
return False
def main():
parser = argparse.ArgumentParser(description='Find and optionally delete unused versioned images in MkDocs project')
parser.add_argument('--docs-dir', type=str, required=True, help='Path to the docs directory')
parser.add_argument('--img-dir', type=str, required=True, help='Path to the images directory')
parser.add_argument('--delete', action='store_true', help='Delete unused images')
parser.add_argument('--verbose', action='store_true', help='Show all found references and files')
parser.add_argument('--skip-grep', action='store_true', help='Skip the additional grep validation')
parser = argparse.ArgumentParser(
description="Find and optionally delete unused versioned images in MkDocs project"
)
parser.add_argument(
"--docs-dir", type=str, required=True, help="Path to the docs directory"
)
parser.add_argument(
"--img-dir", type=str, required=True, help="Path to the images directory"
)
parser.add_argument("--delete", action="store_true", help="Delete unused images")
parser.add_argument(
"--verbose", action="store_true", help="Show all found references and files"
)
parser.add_argument(
"--skip-grep", action="store_true", help="Skip the additional grep validation"
)
args = parser.parse_args()
# Convert paths to absolute paths
@@ -118,7 +134,7 @@ def main():
print("\nAll versioned image references found in markdown:")
for img in sorted(used_images):
print(f"- {img}")
print("\nAll versioned images in directory:")
for img in sorted(all_images):
print(f"- {img}")
@@ -133,9 +149,11 @@ def main():
for img in unused_images:
if not grep_check_image(docs_dir, img):
actually_unused.add(img)
if len(actually_unused) != len(unused_images):
print(f"\nGrep validation found {len(unused_images) - len(actually_unused)} additional image references!")
print(
f"\nGrep validation found {len(unused_images) - len(actually_unused)} additional image references!"
)
unused_images = actually_unused
# Report findings
@@ -148,7 +166,7 @@ def main():
print("\nUnused versioned images:")
for img in sorted(unused_images):
print(f"- {img}")
if args.delete:
print("\nDeleting unused versioned images...")
for img in unused_images:
@@ -162,5 +180,6 @@ def main():
else:
print("\nNo unused versioned images found!")
if __name__ == "__main__":
main()
main()

View File

@@ -4,12 +4,12 @@ from talemate.events import GameLoopEvent
import talemate.emit.async_signals
from talemate.emit import emit
@register()
class TestAgent(Agent):
agent_type = "test"
verbose_name = "Test"
def __init__(self, client):
self.client = client
self.is_enabled = True
@@ -20,7 +20,7 @@ class TestAgent(Agent):
description="Test",
),
}
@property
def enabled(self):
return self.is_enabled
@@ -36,7 +36,7 @@ class TestAgent(Agent):
def connect(self, scene):
super().connect(scene)
talemate.emit.async_signals.get("game_loop").connect(self.on_game_loop)
async def on_game_loop(self, emission: GameLoopEvent):
"""
Called on the beginning of every game loop
@@ -45,4 +45,8 @@ class TestAgent(Agent):
if not self.enabled:
return
emit("status", status="info", message="Annoying you with a test message every game loop.")
emit(
"status",
status="info",
message="Annoying you with a test message every game loop.",
)

View File

@@ -1,129 +0,0 @@
"""
An attempt to write a client against the runpod serverless vllm worker.
This is close to functional, but since runpod serverless gpu availability is currently terrible, i have
been unable to properly test it.
Putting it here for now since i think it makes a decent example of how to write a client against a new service.
"""
import pydantic
import structlog
import runpod
import asyncio
import aiohttp
from talemate.client.base import ClientBase, ExtraField
from talemate.client.registry import register
from talemate.emit import emit
from talemate.config import Client as BaseClientConfig
log = structlog.get_logger("talemate.client.runpod_vllm")
class Defaults(pydantic.BaseModel):
max_token_length: int = 4096
model: str = ""
runpod_id: str = ""
class ClientConfig(BaseClientConfig):
runpod_id: str = ""
@register()
class RunPodVLLMClient(ClientBase):
client_type = "runpod_vllm"
conversation_retries = 5
config_cls = ClientConfig
class Meta(ClientBase.Meta):
title: str = "Runpod VLLM"
name_prefix: str = "Runpod VLLM"
enable_api_auth: bool = True
manual_model: bool = True
defaults: Defaults = Defaults()
extra_fields: dict[str, ExtraField] = {
"runpod_id": ExtraField(
name="runpod_id",
type="text",
label="Runpod ID",
required=True,
description="The Runpod ID to connect to.",
)
}
def __init__(self, model=None, runpod_id=None, **kwargs):
self.model_name = model
self.runpod_id = runpod_id
super().__init__(**kwargs)
@property
def experimental(self):
return False
def set_client(self, **kwargs):
log.debug("set_client", kwargs=kwargs, runpod_id=self.runpod_id)
self.runpod_id = kwargs.get("runpod_id", self.runpod_id)
def tune_prompt_parameters(self, parameters: dict, kind: str):
super().tune_prompt_parameters(parameters, kind)
keys = list(parameters.keys())
valid_keys = ["temperature", "top_p", "max_tokens"]
for key in keys:
if key not in valid_keys:
del parameters[key]
async def get_model_name(self):
return self.model_name
async def generate(self, prompt: str, parameters: dict, kind: str):
"""
Generates text from the given prompt and parameters.
"""
prompt = prompt.strip()
self.log.debug("generate", prompt=prompt[:128] + " ...", parameters=parameters)
try:
async with aiohttp.ClientSession() as session:
endpoint = runpod.AsyncioEndpoint(self.runpod_id, session)
run_request = await endpoint.run({
"input": {
"prompt": prompt,
}
#"parameters": parameters
})
while (await run_request.status()) not in ["COMPLETED", "FAILED", "CANCELLED"]:
status = await run_request.status()
log.debug("generate", status=status)
await asyncio.sleep(0.1)
status = await run_request.status()
log.debug("generate", status=status)
response = await run_request.output()
log.debug("generate", response=response)
return response["choices"][0]["tokens"][0]
except Exception as e:
self.log.error("generate error", e=e)
emit(
"status", message="Error during generation (check logs)", status="error"
)
return ""
def reconfigure(self, **kwargs):
if kwargs.get("model"):
self.model_name = kwargs["model"]
if "runpod_id" in kwargs:
self.api_auth = kwargs["runpod_id"]
self.set_client(**kwargs)

View File

@@ -9,6 +9,7 @@ class Defaults(pydantic.BaseModel):
api_url: str = "http://localhost:1234"
max_token_length: int = 4096
@register()
class TestClient(ClientBase):
client_type = "test"
@@ -22,14 +23,13 @@ class TestClient(ClientBase):
self.client = AsyncOpenAI(base_url=self.api_url + "/v1", api_key="sk-1111")
def tune_prompt_parameters(self, parameters: dict, kind: str):
"""
Talemate adds a bunch of parameters to the prompt, but not all of them are valid for all clients.
This method is called before the prompt is sent to the client, and it allows the client to remove
any parameters that it doesn't support.
"""
super().tune_prompt_parameters(parameters, kind)
keys = list(parameters.keys())
@@ -41,11 +41,10 @@ class TestClient(ClientBase):
del parameters[key]
async def get_model_name(self):
"""
This should return the name of the model that is being used.
"""
return "Mock test model"
async def generate(self, prompt: str, parameters: dict, kind: str):

View File

@@ -0,0 +1,166 @@
# Adding a new world-state template
I am writing this up as I add phrase detection functionality to the `Writing Style` template, so that in the future, hopefully when new template types need to be added this document can just given to the LLM of the month, to do it.
## Introduction
World state templates are reusable components that plug in various parts of talemate.
At this point there are following types:
- Character Attribute
- Character Detail
- Writing Style
- Spice (for randomization of content during generation)
- Scene Type
- State Reinforcement
Basically whenever we want to add something reusable and customizable by the user, a world state template is likely a good solution.
## Steps to creating a new template type
### 1. Add a pydantic schema (python)
In `src/talemate/world_state/templates` create a new `.py` file with reasonable name.
In this example I am extending the `Writing Style` template to include phrase detection functionality, which will be used by the `Editor` agent to detect certain phrases and then act upon them.
There already is a `content.py` file - so it makes sense to just add this new functionality to this file.
```python
class PhraseDetection(pydantic.BaseModel):
phrase: str
instructions: str
# can be "unwanted" for now, more added later
classification: Literal["unwanted"] = "unwanted"
@register("writing_style")
class WritingStyle(Template):
description: str | None = None
phrases: list[PhraseDetection] = pydantic.Field(default_factory=list)
def render(self, scene: "Scene", character_name: str):
return self.formatted("instructions", scene, character_name)
```
If I were to create a new file I'd still want to read one of the existing files first to understand imports and style.
### 2. Add a vue component to allow management (vue, js)
Next we need to add a new vue component that exposes a UX for us to manage this new template type.
For this I am creating `talemate_frontend/src/components/WorldStateManagerTemplateWritingStyle.vue`.
## Bare Minimum Understanding for New Template Components
When adding a new component for managing a template type, you need to understand:
### Component Structure
1. **Props**: The component always receives an `immutableTemplate` prop with the template data.
2. **Data Management**: Create a local copy of the template data for editing before saving back.
3. **Emits**: Use the `update` event to send modified template data back to the parent.
### Core Implementation Requirements
1. **Template Properties**: Always include fields for `name`, `description`, and `favorite` status.
2. **Data Binding**: Implement two-way binding with `v-model` for all editable fields.
3. **Dirty State Tracking**: Track when changes are made but not yet saved.
4. **Save Method**: Implement a `save()` method that emits the updated template.
### Component Lifecycle
1. **Initialization**: Use the `created` hook to initialize the local template copy.
2. **Watching for Changes**: Set up a watcher for the `immutableTemplate` to handle external updates.
### UI Patterns
1. **Forms**: Use Vuetify form components with consistent validation.
2. **Actions**: Provide clear user actions for editing and managing template items.
3. **Feedback**: Give visual feedback when changes are being made or saved.
The WorldStateManagerTemplate components follow a consistent pattern where they:
- Display and edit general template metadata (name, description, favorite status)
- Provide specialized UI for the template's unique properties
- Handle the create, read, update, delete (CRUD) operations for template items
- Maintain data integrity by properly handling template updates
You absolutely should read an existing component like `WorldStateManagerTemplateWritingStyle.vue` first to get a good understanding of the implementation.
## Integrating with WorldStateManagerTemplates
After creating your template component, you need to integrate it with the WorldStateManagerTemplates component:
### 1. Import the Component
Edit `talemate_frontend/src/components/WorldStateManagerTemplates.vue` and add an import for your new component:
```javascript
import WorldStateManagerTemplateWritingStyle from './WorldStateManagerTemplateWritingStyle.vue'
```
### 2. Register the Component
Add your component to the components section of the WorldStateManagerTemplates:
```javascript
components: {
// ... existing components
WorldStateManagerTemplateWritingStyle
}
```
### 3. Add Conditional Rendering
In the template section, add a new conditional block to render your component when the template type matches:
```html
<WorldStateManagerTemplateWritingStyle v-else-if="template.template_type === 'writing_style'"
:immutableTemplate="template"
@update="(template) => applyAndSaveTemplate(template)"
/>
```
### 4. Add Icon and Color
Add cases for your template type in the `iconForTemplate` and `colorForTemplate` methods:
```javascript
iconForTemplate(template) {
// ... existing conditions
else if (template.template_type == 'writing_style') {
return 'mdi-script-text';
}
return 'mdi-cube-scan';
},
colorForTemplate(template) {
// ... existing conditions
else if (template.template_type == 'writing_style') {
return 'highlight5';
}
return 'grey';
}
```
### 5. Add Help Message
Add a help message for your template type in the `helpMessages` object in the data section:
```javascript
helpMessages: {
// ... existing messages
writing_style: "Writing style templates are used to define a writing style that can be applied to the generated content. They can be used to add a specific flavor or tone. A template must explicitly support writing styles to be able to use a writing style template.",
}
```
### 6. Update Template Type Selection
Add your template type to the `templateTypes` array in the data section:
```javascript
templateTypes: [
// ... existing types
{ "title": "Writing style", "value": 'writing_style'},
]
```

View File

@@ -10,28 +10,27 @@ To run the server on a different host and port, you need to change the values pa
#### :material-linux: Linux
Copy `start.sh` to `start_custom.sh` and edit the `--host` and `--port` parameters in the `uvicorn` command.
Copy `start.sh` to `start_custom.sh` and edit the `--host` and `--port` parameters.
```bash
#!/bin/sh
. talemate_env/bin/activate
python src/talemate/server/run.py runserver --host 0.0.0.0 --port 1234
uv run src/talemate/server/run.py runserver --host 0.0.0.0 --port 1234
```
#### :material-microsoft-windows: Windows
Copy `start.bat` to `start_custom.bat` and edit the `--host` and `--port` parameters in the `uvicorn` command.
Copy `start.bat` to `start_custom.bat` and edit the `--host` and `--port` parameters.
```batch
start cmd /k "cd talemate_env\Scripts && activate && cd ../../ && python src\talemate\server\run.py runserver --host 0.0.0.0 --port 1234"
uv run src\talemate\server\run.py runserver --host 0.0.0.0 --port 1234
```
### Letting the frontend know about the new host and port
Copy `talemate_frontend/example.env.development.local` to `talemate_frontend/.env.production.local` and edit the `VUE_APP_TALEMATE_BACKEND_WEBSOCKET_URL`.
Copy `talemate_frontend/example.env.development.local` to `talemate_frontend/.env.production.local` and edit the `VITE_TALEMATE_BACKEND_WEBSOCKET_URL`.
```env
VUE_APP_TALEMATE_BACKEND_WEBSOCKET_URL=ws://localhost:1234
VITE_TALEMATE_BACKEND_WEBSOCKET_URL=ws://localhost:1234
```
Next rebuild the frontend.
@@ -71,8 +70,7 @@ Copy `start.sh` to `start_custom.sh` and edit the `--frontend-host` and `--front
```bash
#!/bin/sh
. talemate_env/bin/activate
python src/talemate/server/run.py runserver --host 0.0.0.0 --port 5055 \
uv run src/talemate/server/run.py runserver --host 0.0.0.0 --port 5055 \
--frontend-host localhost --frontend-port 8082
```
@@ -81,7 +79,7 @@ python src/talemate/server/run.py runserver --host 0.0.0.0 --port 5055 \
Copy `start.bat` to `start_custom.bat` and edit the `--frontend-host` and `--frontend-port` parameters.
```batch
start cmd /k "cd talemate_env\Scripts && activate && cd ../../ && python src\talemate\server\run.py runserver --host 0.0.0.0 --port 5055 --frontend-host localhost --frontend-port 8082"
uv run src\talemate\server\run.py runserver --host 0.0.0.0 --port 5055 --frontend-host localhost --frontend-port 8082
```
### Start the backend and frontend
@@ -98,5 +96,4 @@ Start the backend and frontend as usual.
```batch
start_custom.bat
```
```

View File

@@ -1,22 +1,15 @@
!!! example "Experimental"
Talemate through docker has not received a lot of testing from me, so please let me know if you encounter any issues.
You can do so by creating an issue on the [:material-github: GitHub repository](https://github.com/vegu-ai/talemate)
## Quick install instructions
1. `git clone https://github.com/vegu-ai/talemate.git`
1. `cd talemate`
1. copy config file
1. linux: `cp config.example.yaml config.yaml`
1. windows: `copy config.example.yaml config.yaml`
1. If your host has a CUDA compatible Nvidia GPU
1. Windows (via PowerShell): `$env:CUDA_AVAILABLE="true"; docker compose up`
1. Linux: `CUDA_AVAILABLE=true docker compose up`
1. If your host does **NOT** have a CUDA compatible Nvidia GPU
1. Windows: `docker compose up`
1. Linux: `docker compose up`
1. windows: `copy config.example.yaml config.yaml` (or just copy the file and rename it via the file explorer)
1. `docker compose up`
1. Navigate your browser to http://localhost:8080
!!! info "Pre-built Images"
The default setup uses pre-built images from GitHub Container Registry that include CUDA support by default. To manually build the container instead, use `docker compose -f docker-compose.manual.yml up --build`.
!!! note
When connecting local APIs running on the hostmachine (e.g. text-generation-webui), you need to use `host.docker.internal` as the hostname.

View File

@@ -1,4 +1,3 @@
## Quick install instructions
### Dependencies
@@ -7,6 +6,7 @@
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. uv - see instructions [here](https://github.com/astral-sh/uv#installation)
### Installation
@@ -25,19 +25,15 @@ If everything went well, you can proceed to [connect a client](../../connect-a-c
1. Open a terminal.
2. Navigate to the project directory.
3. Create a virtual environment by running `python3 -m venv talemate_env`.
4. Activate the virtual environment by running `source talemate_env/bin/activate`.
3. uv will automatically create a virtual environment when you run `uv venv`.
### Installing Dependencies
1. With the virtual environment activated, install poetry by running `pip install poetry`.
2. Use poetry to install dependencies by running `poetry install`.
1. Use uv to install dependencies by running `uv pip install -e ".[dev]"`.
### Running the Backend
1. With the virtual environment activated and dependencies installed, you can start the backend server.
2. Navigate to the `src/talemate/server` directory.
3. Run the server with `python run.py runserver --host 0.0.0.0 --port 5050`.
1. You can start the backend server using `uv run src/talemate/server/run.py runserver --host 0.0.0.0 --port 5050`.
### Running the Frontend
@@ -45,4 +41,4 @@ If everything went well, you can proceed to [connect a client](../../connect-a-c
2. If you haven't already, install npm dependencies by running `npm install`.
3. Start the server with `npm 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 `runserver.sh` and `frontend.sh` files for more details.
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.

View File

@@ -2,12 +2,9 @@
## Windows
### Installation fails with "Microsoft Visual C++" error
If your installation errors with a notification to upgrade "Microsoft Visual C++" go to https://visualstudio.microsoft.com/visual-cpp-build-tools/ and click "Download Build Tools" and run it.
### Frontend fails with errors
- During installation make sure you select the C++ development package (upper left corner)
- Run `reinstall.bat` inside talemate directory
- ensure none of the directories leading to your talemate directory have special characters in them, this can cause issues with the frontend. so no `(1)` in the directory name.
## Docker

View File

@@ -1,52 +1,24 @@
## Quick install instructions
1. Download and install Python 3.10 - 3.13 from the [official Python website](https://www.python.org/downloads/windows/).
- [Click here for direct link to python 3.11.9 download](https://www.python.org/downloads/release/python-3119/)
1. Download and install Node.js from the [official Node.js website](https://nodejs.org/en/download/prebuilt-installer). This will also install npm.
1. Download the Talemate project to your local machine. Download from [the Releases page](https://github.com/vegu-ai/talemate/releases).
1. Unpack the download and run `install.bat` by double clicking it. This will set up the project on your local machine.
1. **Optional:** If you are using an nvidia graphics card with CUDA support you may want to also run `install-cuda.bat` **afterwards**, to install the cuda enabled version of torch - although this is only needed if you want to run some bigger embedding models where CUDA can be helpful.
1. Once the installation is complete, you can start the backend and frontend servers by running `start.bat`.
1. Once the talemate logo shows up, navigate your browser to http://localhost:8080
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).
2. Create and configure a Python virtual environment.
3. Install all back-end and front-end dependencies with the included *uv* and *npm*.
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:8080**.
!!! note "First start up may take a while"
We have seen cases where the first start of talemate will sit at a black screen for a minute or two. Just wait it out, eventually the Talemate logo should show up.
!!! note "First start can take a while"
The initial download and dependency installation may take several minutes, especially on slow internet connections. The console will keep you updated just wait until the Talemate logo shows up.
If everything went well, you can proceed to [connect a client](../../connect-a-client).
## Maintenance & advanced usage
## Additional Information
| Script | Purpose |
|--------|---------|
| **`start.bat`** | Primary entry point performs the initial install if needed and then starts Talemate. |
| **`install.bat`** | Runs the installer without launching the server. Useful for automated setups or debugging. |
| **`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. |
### How to Install Python
--8<-- "docs/snippets/common.md:python-versions"
1. Visit the official Python website's download page for Windows at [https://www.python.org/downloads/windows/](https://www.python.org/downloads/windows/).
2. Find the latest updated of Python 3.13 and click on one of the download links. (You will likely want the Windows installer (64-bit))
4. Run the installer file and follow the setup instructions. Make sure to check the box that says Add Python 3.13 to PATH before you click Install Now.
### How to Install npm
1. Download Node.js from the official site [https://nodejs.org/en/download/prebuilt-installer](https://nodejs.org/en/download/prebuilt-installer).
2. Run the installer (the .msi installer is recommended).
3. Follow the prompts in the installer (Accept the license agreement, click the NEXT button a bunch of times and accept the default installation settings).
### Usage of the Supplied bat Files
#### install.bat
This batch file is used to set up the project on your local machine. It creates a virtual environment, activates it, installs poetry, and uses poetry to install dependencies. It then navigates to the frontend directory and installs the necessary npm packages.
To run this file, simply double click on it or open a command prompt in the same directory and type `install.bat`.
#### update.bat
If you are inside a git checkout of talemate you can use this to pull and reinstall talemate if there have been updates.
!!! note "CUDA needs to be reinstalled manually"
Running `update.bat` will downgrade your torch install to the non-CUDA version, so if you want CUDA support you will need to run the `install-cuda.bat` script after the update is finished.
#### start.bat
This batch file is used to start the backend and frontend servers. It opens two command prompts, one for the frontend and one for the backend.
To run this file, simply double click on it or open a command prompt in the same directory and type `start.bat`.
No system-wide Python or Node.js is required Talemate uses the embedded runtimes it downloads automatically.

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

BIN
docs/img/0.31.0/history.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 346 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 702 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 471 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Some files were not shown because too many files have changed in this diff Show More