fix
This commit is contained in:
@@ -56,6 +56,10 @@ DEFAULT_SETTINGS: dict[str, dict[str, Any]] = {
|
||||
"ui.logo_url": {"value": "/icon.png", "description": "Logo URL"},
|
||||
"ui.og_image_url": {"value": "", "description": "OpenGraph image URL"},
|
||||
"admin.setup_token": {"value": "", "description": "Admin setup token"},
|
||||
"llm.text_replacements": {
|
||||
"value": [],
|
||||
"description": "List of {from, to} pairs. Each 'from' substring in LLM scene_text output is replaced with 'to' (can be empty string to remove).",
|
||||
},
|
||||
}
|
||||
|
||||
# Keys whose values should never be returned to the client in plaintext.
|
||||
@@ -185,3 +189,24 @@ async def get_admin_setup_token(session: AsyncSession) -> str:
|
||||
token = secrets.token_urlsafe(16)
|
||||
await set_setting(session, "admin.setup_token", token)
|
||||
return token
|
||||
|
||||
|
||||
async def apply_text_replacements(session: AsyncSession, text: str) -> str:
|
||||
"""Apply llm.text_replacements to a text string.
|
||||
|
||||
Each replacement is a dict {from: str, to: str}. The 'from' substring is
|
||||
replaced with 'to' (which can be empty to remove the substring).
|
||||
"""
|
||||
if not text:
|
||||
return text
|
||||
replacements = await get_setting(session, "llm.text_replacements")
|
||||
if not replacements or not isinstance(replacements, list):
|
||||
return text
|
||||
for r in replacements:
|
||||
if not isinstance(r, dict):
|
||||
continue
|
||||
frm = r.get("from")
|
||||
to = r.get("to", "")
|
||||
if frm and isinstance(frm, str):
|
||||
text = text.replace(frm, to)
|
||||
return text
|
||||
|
||||
@@ -133,6 +133,41 @@ def time_le(a: str, b: str) -> bool:
|
||||
return ga.total_minutes() <= gb.total_minutes()
|
||||
|
||||
|
||||
def format_time_human(time_str: str, language: str = "en") -> str:
|
||||
"""Format a game time string as a human-readable localized string.
|
||||
|
||||
Examples:
|
||||
- "day_1_hour_8" → "Day 1, 08:00" (en) / "День 1, 08:00" (ru)
|
||||
- "day_3_hour_14_min_30" → "Day 3, 14:30" (en) / "День 3, 14:30" (ru)
|
||||
- "year_2_day_5_hour_12" → "Year 2, Day 5, 12:00" (en) / "Год 2, День 5, 12:00" (ru)
|
||||
"""
|
||||
try:
|
||||
gt = GameTime.parse(time_str)
|
||||
except ValueError:
|
||||
return time_str # return as-is if unparseable
|
||||
|
||||
if language == "ru":
|
||||
parts = []
|
||||
if gt.year != 1:
|
||||
parts.append(f"Год {gt.year}")
|
||||
parts.append(f"День {gt.day}")
|
||||
if gt.minute:
|
||||
parts.append(f"{gt.hour:02d}:{gt.minute:02d}")
|
||||
else:
|
||||
parts.append(f"{gt.hour:02d}:00")
|
||||
return ", ".join(parts)
|
||||
else: # en
|
||||
parts = []
|
||||
if gt.year != 1:
|
||||
parts.append(f"Year {gt.year}")
|
||||
parts.append(f"Day {gt.day}")
|
||||
if gt.minute:
|
||||
parts.append(f"{gt.hour:02d}:{gt.minute:02d}")
|
||||
else:
|
||||
parts.append(f"{gt.hour:02d}:00")
|
||||
return ", ".join(parts)
|
||||
|
||||
|
||||
def summarize_schemas(schemas: Iterable[dict]) -> str:
|
||||
"""Render a compact human-readable summary of entity schemas for LLM prompts."""
|
||||
lines: list[str] = []
|
||||
|
||||
Reference in New Issue
Block a user