diff --git a/_text/world-settings.json b/_text/world-settings.json new file mode 100644 index 0000000..20bff9c --- /dev/null +++ b/_text/world-settings.json @@ -0,0 +1,20 @@ +{ + "world_info_settings": { + "world_info": { + "globalSelect": [] + }, + "world_info_budget": 25, + "world_info_budget_cap": 0, + "world_info_case_sensitive": false, + "world_info_character_strategy": 1, + "world_info_depth": 2, + "world_info_include_names": true, + "world_info_match_whole_words": true, + "world_info_max_recursion_steps": 0, + "world_info_min_activations": 0, + "world_info_min_activations_depth_max": 0, + "world_info_overflow_alert": false, + "world_info_recursive": true, + "world_info_use_group_scoring": false + } +} diff --git a/st-export.py b/st-export.py index d0f5ddf..2f9475a 100755 --- a/st-export.py +++ b/st-export.py @@ -146,17 +146,47 @@ def install_hook() -> int: return 0 +def export_world_settings() -> int: + """The gating, not the worlds — which lorebooks are active and how they fire. + + ⚠ A lorebook is INERT until something selects it, and the selection lives in + settings.json, which is untracked. Versioning `worlds/*.json` without this + captures the content and loses the wiring: a restore would hand back every + lorebook with no record of which were global, which rode on a character, or + what the token budget was. Small, non-secret, and it is the half that makes + the other half mean something. + """ + p = os.path.join(HERE, "settings.json") + if not os.path.exists(p): + return 0 + d = json.load(open(p, encoding="utf-8")) + out = {"world_info_settings": d.get("world_info_settings")} + pu = d.get("power_user") or {} + # per-persona lorebook bindings, without dragging in the persona text again + binds = {k: v.get("lorebook") for k, v in (pu.get("persona_descriptions") or {}).items() + if isinstance(v, dict) and v.get("lorebook")} + if binds: + out["persona_lorebooks"] = binds + with open(os.path.join(OUT, "world-settings.json"), "w", encoding="utf-8") as fh: + json.dump(out, fh, indent=2, ensure_ascii=False, sort_keys=True) + fh.write("\n") + wis = (out.get("world_info_settings") or {}).get("world_info") or {} + return len(wis.get("globalSelect") or []) + + def main() -> int: if "--install-hook" in sys.argv: return install_hook() os.makedirs(OUT, exist_ok=True) cards = export_cards() personas = export_personas() + active = export_world_settings() worlds = len([f for f in os.listdir(os.path.join(HERE, "worlds")) if f.endswith(".json")]) if os.path.isdir(os.path.join(HERE, "worlds")) else 0 print(f" _text/cards/ {cards} card(s) extracted from PNG") print(f" _text/personas.json {personas} persona(s)") print(f" worlds/ {worlds} lorebook(s) already JSON, tracked as-is") + print(f" _text/world-settings.json gating captured; {active} world(s) globally active") return 0