Adding a Persona Preset
How to add an official persona preset to the seed catalog. Locale variants of an existing preset are covered in Adding a Locale.
-
Create
src/db/seed/catalog/personas/<name>/with one file per language (en-US.ts,ja.ts), each exportingpersona: PersonaInput, and register each inpersonas/index.ts. There is no directory scan. Required fields:preset_lineage_id: identical in every language variant. It makes the variants one character and becomes the persona’spersona_lineage_id, which scopes its memories.name,desc,attributes, pairedsampleDialoguesIn/sampleDialoguesOut,language,avatarPath,triggerWords.- Do not author
preset_attribute_public_flags.personaSeed.tsderives it: the first attribute is public and the rest are private.
-
Put the avatar image in the folder and set
avatarPathto the folder; the first image alphabetically is used. -
Optionally add sprites under
sprites/and list them per locale file:sprites: [{ name: "mad", file: "sprites/mad.png", usageInstructions: "Use when angry or annoyed." },{ name: "shy", file: "sprites/shy.png", isIdentity: false },],namebecomes thesprite_key,fileis relative toavatarPath,usageInstructionsis prompt guidance, andisIdentityrenders the name assprite (Persona). -
Add or edit shared system prompt presets in
src/db/seed/catalog/systemPrompts.tsif needed. -
Keep each image under 1 MiB;
bun run compress-mediashrinks oversized art.
How presets reach servers
Section titled “How presets reach servers”Applying a preset through /setup or /persona default creates a copy-on-write pointer:
personas.is_pointer = true with preset_lineage_id and preset_language. Reads resolve text and
config from the live persona_presets row, so seed edits reach every pointer persona after the next
boot.
- Sprites upload once to the immutable
presets/storage prefix intopreset_sprites, and every pointer persona resolves them live. Removing a sprite from the array removes it everywhere. - Avatars upload once to
presets/, recordingpreset_avatar_shared_urlandpreset_avatar_hash. Pointer alters resolve that URL live. A pointer main persona uses the bot’s guild avatar, whichreconcilePresetMainAvatarsre-uploads per guild whenapplied_avatar_hash != preset_avatar_hash. - The first local content edit, including
/server avatar, turns the pointer into an independent copy that keepspersona_idandpersona_lineage_id. Memory writes do not./persona defaultrestores the pointer and discards local changes. /persona exportwrites a self-contained copy stamped withpreset_lineage_id. Import re-links to the official pointer only when the content exactly matches the seeded preset of that lineage.
Verify
Section titled “Verify”bun run check-seed-catalogs # names, paired dialogues, attributes, sprite files, promptsbun run check-media-sizebun run checkbun run lintThen seed a dev database and check /setup, /persona default, /persona export, and
/persona import. A pointer persona should show the seeded values, pick up a seed edit after cache
invalidation, and become a copy on its first local edit. See
Persona Presets for the pointer model.