Capture world GATING, not just the worlds
A lorebook is inert until something selects it, and SillyTavern gates three ways -- globally, per character card, and per persona. All of that selection lives in settings.json, which is untracked, so versioning worlds/*.json alone captured the content and lost the wiring. A restore would have handed back every lorebook with no record of which were active or what the token budget was. _text/world-settings.json now carries the selection and the tuning that decides how entries fire: budget, scan depth, recursion, whole-word matching, and the character-vs-global strategy. Non-secret, small, and regenerated by the same pre-commit hook.
This commit is contained in:
@@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -146,17 +146,47 @@ def install_hook() -> int:
|
|||||||
return 0
|
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:
|
def main() -> int:
|
||||||
if "--install-hook" in sys.argv:
|
if "--install-hook" in sys.argv:
|
||||||
return install_hook()
|
return install_hook()
|
||||||
os.makedirs(OUT, exist_ok=True)
|
os.makedirs(OUT, exist_ok=True)
|
||||||
cards = export_cards()
|
cards = export_cards()
|
||||||
personas = export_personas()
|
personas = export_personas()
|
||||||
|
active = export_world_settings()
|
||||||
worlds = len([f for f in os.listdir(os.path.join(HERE, "worlds"))
|
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
|
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/cards/ {cards} card(s) extracted from PNG")
|
||||||
print(f" _text/personas.json {personas} persona(s)")
|
print(f" _text/personas.json {personas} persona(s)")
|
||||||
print(f" worlds/ {worlds} lorebook(s) already JSON, tracked as-is")
|
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
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user