Labs · Lorebook doctor

Your lorebook speaks five dialects.
See what breaks in translation.

SillyTavern, Chub, RisuAI, Agnai and JanitorAI all read “the same” lorebook JSON — then disagree about probability, case, whole words, recursion and secondary keys. Drop a book here and get a migration checkup for any direction: what breaks outright (JanitorAI’s 1% import default, Risu reviving your disabled entries), what quietly changes, and what gets dropped — each finding marked “verified in source” or “per official docs”. Then paste a chat sample and watch the same keywords match, or refuse to, under each platform’s real matching rules.

Freeruns in your browsernothing uploaded

Lorebook (any platform)

Drop a lorebook JSON here, or click to pick

Tap to pick a lorebook JSON file

Auto-detects: SillyTavern World Info · Chub · RisuAI export · Agnai memory book · JanitorAI entries · V2/V3 books & cards
Or paste JSON

Chat sample

Load a lorebook to start the checkup.

The dialect table: how five platforms disagree about the same lorebook

Same JSON family, five different rulebooks. This is the reference the checkup above draws from — each cell traced to the platform’s open source where possible, and honestly marked when it comes from docs instead.

BehaviorSillyTavern¹Chub²RisuAI³Agnai⁴JanitorAI⁵
Native file shapeWorld Info export — entries keyed by uid, key/keysecondary arraysWI + V2 fields dual-written per entry, plus extensions.chub{ type: 'risu', ver, data } — keys stored as one comma-joined string{ kind: 'memory' } — keywords / entry / priority / weightBare entries array pasted into the JSON editor
Keyword matchingSubstring by default; optional whole-word (\W boundary, CJK-friendly); regex keys in /slash/ formPlayed through ST-family frontends — read the ST columnLowercased and spaces stripped, then substring — “lamp tower” matches “lamptower”, “ice” fires inside “police”. Full-word mode compares space-split tokens (punctuation blocks it)Always whole-word (\b) with * and ? wildcards; regex punctuation is stripped from keys; pure-CJK keys can never anchorAdvanced script: ASCII-normalized whole-word + suffix wildcard (welcom*); CJK/accents deleted before matching. Simple form has per-entry toggles
Case sensitivityGlobal toggle (default off) + per-entry overridePer-entry case_sensitive — but the snake_case field is not read back by ST’s engineAlways case-insensitive on the non-regex pathAlways case-insensitive (giu flags)Per-entry Case Sensitive toggle (simple form); script always lowercases
Secondary keysFour logic modes: AND_ANY / AND_ALL / NOT_ANY / NOT_ALLCarried in both field familiesPositive AND only — exclusions need @@exclude_keys decorators; logic mode is dropped on importIgnored — carried in the file, never evaluatedSecondary keys exist; AND/NOT gate equivalents live in the Advanced script (andAll / notAny / notAll)
ProbabilityPer-entry 0–100 with useProbability; re-rolls each turn unless stickyCarried (probability + useProbability)@@probability decorator only — the legacy activationPercent field is ignored by the current engineNone — every keyword match firesPer-entry 0–100, re-rolls every message, no sticky state; imports commonly land at the 1% default
Always-on entriesconstant flag (blue dot)CarriedalwaysActive flagCarried but never read — no always-onNo direct pin — use personality/scenario fields or an Advanced always-on entry
RecursionOn by default; max-steps cap plus exclude / prevent / delay-until-recursion per entryrecursive_scanning book-level flagOn by default with no step cap; @@recursive family of decoratorsNoneNone — the Advanced script’s tag/trigger chains are a different mechanism
Scan depthGlobal setting + per-entry overridescan_depth book fieldGlobal setting + @@scan_depth decoratorPreset-level Memory Depth onlyMessage Depth setting (1 = only your last message); script scans a 5-message window by default
Budget & orderingToken budget with order-based trimming; ignoreBudget escape hatchtoken_budget + order and priority both writteninsertorder doubles as both trim priority and ordering; @@priority / @@ignore_on_max_context overridepriority decides what survives the budget; weight decides ordering (higher = closer to the bottom)Priority = survival under token budget; insertion order = attention (per docs)

¹ SillyTavern column: this site’s trigger engine, a port aligned with ST 1.18 checkWorldInfo, plus the release-branch world-info.js import converters. ² Chub column: real Chub lorebook exports (field-level comparison; Chub’s own chat runtime not modeled). ³ RisuAI column: lorebook.svelte.ts on the main branch, read 2026-07. ⁴ Agnai column: common/memory.ts on the dev branch, read 2026-07. ⁵ JanitorAI column: official help center plus the published Advanced Lorebook script — matcher details are source-level for the script, docs-level for the simple form. Platforms drift; cells reflect what the code and docs said when read.

How do you check a lorebook before migrating it?

Drop the book above and pick a target platform: every known trap for that direction gets listed with severity (breaks / behaves differently / silently dropped), the affected entries, and an evidence tag telling you whether the claim is verified in the target platform’s source code or comes from official docs. Fix or annotate the flagged entries, then migrate. The divergence lab below the checkup answers the other recurring question — “would this keyword even fire over there?” — by running your keys through each platform’s actual matching discipline.

Where this tool comes from

The SillyTavern column reuses this site's lorebook trigger engine — a line-for-line port of the activator inside the Foreverse app, aligned with SillyTavern 1.18's checkWorldInfo and pinned by 60+ unit tests. The dialect layer on top was built by reading each platform's own implementation: RisuAI's lorebook.svelte.ts (matching, import, export shell), Agnai's common/memory.ts (keyword compiler, budget and ordering, the 'carried but unsupported' V2 fields), SillyTavern's world-info.js import converters (Risu / Agnai / NovelAI / character-book paths), real Chub lorebook exports for the dual-written format, and JanitorAI's official help center plus its published Advanced Lorebook script. Read 2026-07.

Every parser, matcher port and migration rule is locked by a 137-assertion golden self-test — including real multi-hundred-entry books from Chub exports — and each finding in the UI carries its evidence tier: verified in source, per official docs, or format comparison. Where we couldn't verify (JanitorAI's simple-form matcher defaults, Chub's editor round-tripping of timed effects), the tool says so instead of guessing.

What it can't do

This diagnoses the activation layer and migration traps — it doesn't convert files, and it doesn't model token-budget trimming or injection ordering on the target platform. Cross-turn state (sticky, cooldown, Risu's keep-activate decorators) is simulated stateless.

Platform code drifts. The Risu and Agnai columns are pinned to their open-source implementations as read in 2026-07; JanitorAI's simple lorebook form is closed-source, so its column leans on official docs and the published Advanced script, and is marked accordingly. Chub's own chat runtime isn't modeled — Chub books are checked as a storage dialect.

FAQ

Why did my lorebook stop working after importing it into JanitorAI?

Almost always the hidden 1% default: imported entries commonly arrive with trigger probability stuck at 1%, so your lore fires about once in a hundred messages no matter how well it's written. Open each entry and set probability explicitly (100 for critical lore), confirm the book is linked to the character and published, and check that Case Sensitive or Match Whole Words isn't silently blocking the keyword. This tool flags all of those before you migrate.

What actually breaks when I move a SillyTavern World Info book to RisuAI or Agnai?

The nasty ones are semantic, not cosmetic. Risu's importer drops the enabled flag (your disabled entries come back alive) and drops secondary-key logic — a NOT_ANY blocklist inverts into a positive requirement, the exact opposite of what you wrote. Agnai carries constant, selective and case-sensitive flags in the file but its engine never reads them: always-on entries stop being always-on, exclusions vanish, and there is no probability roll at all. Every one of these is verified against the platforms' open-source code and flagged per entry by the checkup.

Does this tool convert my lorebook between platforms?

No — deliberately. Converters already exist (including the import buttons built into SillyTavern and RisuAI themselves). What nothing else tells you is what silently changes on the way through. This is the pre-flight checkup: run it before you convert, fix or annotate the flagged entries, then migrate with your eyes open.

Which file formats does it recognize?

SillyTavern World Info exports, Chub lorebooks (their dual-written WI + V2 format), RisuAI lorebook exports ({ type: 'risu' }), Agnai memory books ({ kind: 'memory' }), JanitorAI JSON-editor entry arrays, V2/V3 character books and lorebook_v3 files, character cards with embedded books, and NovelAI lorebooks (detected, light support). Drop any of them — the format banner tells you what it saw.

Is my lorebook uploaded?

No. Parsing, the checkup and the divergence lab all run in your browser — the page works offline once loaded.

Related tools & reading

← All free tools

Lorebook Migration Doctor — Cross-Platform World Info Checkup (SillyTavern / Chub / Risu / Agnai / JanitorAI) · Foreverse · Xinmeng