This commit is contained in:
vegu-ai-tools
2025-11-18 03:10:27 +02:00
parent 5496ef7a57
commit 0db092cb8a
6 changed files with 43 additions and 30 deletions

View File

@@ -55,14 +55,14 @@ class CreatorAgent(
"text": text,
},
)
# parse <TITLE>...</TITLE> tags
if "<TITLE>" in response and "</TITLE>" in response:
title = response.split("<TITLE>")[1].split("</TITLE>")[0].strip()
elif "<TITLE>" in response:
title = response.split("<TITLE>")[1].strip()
if not title:
return response.strip()
return title

View File

@@ -61,6 +61,7 @@ __all__ = [
log = structlog.get_logger("talemate.load")
class SceneInitialization(pydantic.BaseModel):
project_name: str | None = None
content_classification: str | None = None
@@ -84,7 +85,7 @@ class SceneInitialization(pydantic.BaseModel):
async def _initialize_scene_intro(scene: Scene, scene_data: dict, empty: bool):
"""
Initialize scene intro and title for new scenes.
Sets intro from scene_data if provided, otherwise generates from instructions.
Also generates a title if the scene is empty and doesn't have one.
"""
@@ -112,9 +113,6 @@ async def _initialize_scene_intro(scene: Scene, scene_data: dict, empty: bool):
log.error("generate intro during load", error=e)
def scene_stub(scene_path: str, scene_data: dict | None = None) -> Scene:
"""
Create a minimal Scene object stub from a scene file path.
@@ -338,7 +336,7 @@ async def load_scene_from_data(
available_characters=list(scene.character_data.keys()),
)
continue
character = scene.character_data[character_name]
if not character.is_player:

View File

@@ -627,12 +627,12 @@ def _parse_characters_from_greeting_text(greeting_text: str, scene) -> list[str]
pattern = r"([^:\n]+):"
matches = re.findall(pattern, greeting_text)
potential_names = [name.strip() for name in matches if name.strip()]
character_names = []
npc_characters = list(scene.get_npc_characters())
all_characters = list(scene.all_characters)
# Validate matches against actual characters in the scene
for name in potential_names:
for character in all_characters:
@@ -640,7 +640,7 @@ def _parse_characters_from_greeting_text(greeting_text: str, scene) -> list[str]
if character.name not in character_names:
character_names.append(character.name)
break
# If no characters detected, look for partial name matches in the text
if not character_names:
for character in npc_characters:
@@ -648,12 +648,12 @@ def _parse_characters_from_greeting_text(greeting_text: str, scene) -> list[str]
if character.name.lower() in greeting_text.lower():
if character.name not in character_names:
character_names.append(character.name)
# If still no characters detected, activate up to 2 NPCs (order doesn't matter)
if not character_names:
for character in npc_characters[:2]:
character_names.append(character.name)
return character_names
@@ -665,7 +665,7 @@ async def _add_episode(
generate_title: bool = True,
) -> None:
"""Add an episode with optional AI-generated title.
Args:
scene: The scene to add the episode to
greeting: The episode intro text
@@ -675,7 +675,7 @@ async def _add_episode(
"""
title = None
if generate_title:
loading_status(f"Generating title for episode...")
loading_status("Generating title for episode...")
try:
title = await creator.generate_title(greeting)
# Strip whitespace and ensure it's not empty
@@ -916,7 +916,9 @@ async def load_scene_from_character_card(
# Parse greeting text for characters speaking (format: name:)
# and activate them if they exist in the scene
speaking_characters = _parse_characters_from_greeting_text(original_greeting_text, scene)
speaking_characters = _parse_characters_from_greeting_text(
original_greeting_text, scene
)
for char_name in speaking_characters:
existing_character = scene.get_character(char_name)
if existing_character:

View File

@@ -6,7 +6,6 @@ to create new scenes from predefined introductions.
"""
import json
import os
from pathlib import Path
from typing import TYPE_CHECKING
@@ -78,26 +77,30 @@ class EpisodesManager:
"""Get all episodes."""
return self._load_episodes()
def add_episode(self, intro: str, title: str | None = None, description: str | None = None) -> Episode | None:
def add_episode(
self, intro: str, title: str | None = None, description: str | None = None
) -> Episode | None:
"""Add a new episode if it doesn't already exist.
Checks for duplicates by comparing the intro text (normalized by stripping whitespace).
Returns the episode if added, or None if a duplicate was found.
"""
episodes = self._load_episodes()
# Normalize intro text for comparison (strip whitespace)
normalized_intro = intro.strip()
# Check if an episode with the same intro already exists
for existing_episode in episodes:
if existing_episode.intro.strip() == normalized_intro:
log.debug(
"Episode with same intro already exists, skipping",
intro_preview=normalized_intro[:50] + "..." if len(normalized_intro) > 50 else normalized_intro,
intro_preview=normalized_intro[:50] + "..."
if len(normalized_intro) > 50
else normalized_intro,
)
return None
episode = Episode(intro=intro, title=title, description=description)
episodes.append(episode)
self._save_episodes(episodes)
@@ -112,7 +115,13 @@ class EpisodesManager:
return True
return False
def update_episode(self, index: int, intro: str | None = None, title: str | None = None, description: str | None = None) -> bool:
def update_episode(
self,
index: int,
intro: str | None = None,
title: str | None = None,
description: str | None = None,
) -> bool:
"""Update an episode by index. Returns True if successful."""
episodes = self._load_episodes()
if 0 <= index < len(episodes):
@@ -133,4 +142,3 @@ class EpisodesManager:
if 0 <= index < len(episodes):
return episodes[index]
return None

View File

@@ -515,7 +515,10 @@ class WorldStateManagerPlugin(
await self._ensure_shared_context_exists()
shared_count = 0
for entry_id, entry in self.scene.world_state.manual_context_for_world().items():
for (
entry_id,
entry,
) in self.scene.world_state.manual_context_for_world().items():
if not entry.shared:
await self.world_state_manager.set_world_entry_shared(entry_id, True)
shared_count += 1
@@ -532,7 +535,10 @@ class WorldStateManagerPlugin(
async def handle_unshare_all_world_entries(self, data: dict):
"""Unshare all world entries in the scene."""
unshared_count = 0
for entry_id, entry in self.scene.world_state.manual_context_for_world().items():
for (
entry_id,
entry,
) in self.scene.world_state.manual_context_for_world().items():
if entry.shared:
await self.world_state_manager.set_world_entry_shared(entry_id, False)
unshared_count += 1

View File

@@ -62,7 +62,7 @@ class EpisodesMixin:
async def handle_add_episode(self, data):
"""Add a new episode."""
payload = AddEpisodePayload(**data)
episode = self.scene.episodes.add_episode(
self.scene.episodes.add_episode(
intro=payload.intro,
title=payload.title,
description=payload.description,
@@ -135,4 +135,3 @@ class EpisodesMixin:
await self.signal_operation_done()
self.scene.emit_status()