Extension Output Showcase

Camera-ready samples of everything the custom extensions produce — memory recall, summaries, the diary, verbatim log recall, reminders, file commands, voice, images and the reply clean-up. Show these instead of opening a real chat.

Fictional sample data Output formats taken from the extensions themselves No real conversations on this page Companion to readme.html

Nothing here is from a real chat. The assistant is called Aria and the user is Sam — both invented for these samples. The extensions print whatever character and user names are active, so in a live demo those names change automatically. Topics are deliberately ordinary (a repair project, a sponsored walk, a book) so nothing personal is on screen.

Three ways to use this page

  • Show the page directly. Open it full-screen and scroll as you talk — every block below looks like the app's real output.
  • Reproduce it live. Each section ends with a Try it line giving the exact commands, so you can recreate the demo on camera in a fresh chat.
  • Make a demo character first. Create a throwaway character and start a new chat before recording: an empty memory store and an empty log folder mean nothing personal can surface while you demonstrate.

1.Command reference at a glance

Everything below is typed into the normal chat box. Nothing starting with a slash reaches the model — it returns instantly and can't be hallucinated.

CommandWhat it returnsTypical use on camera
/remember <keywords> | <fact>Confirmation of the saved memoryShow a fact going in
/remember <fact>Same, keywords picked automaticallyShow it works with no ceremony
/memoriesNumbered list of saved memoriesProve the store persists
/forget <id>ConfirmationShow deletion
/mood · /mood resetCurrent mood stateShow persistent feeling state
/style · /style set…Voice profile / change confirmationShow a per-character writing voice
/relationRelationship scoreShow continuity of closeness
/profile · /profile add…Facts shared by all charactersShow cross-character knowledge
/summary · /summary resetThe rolling summary of a long chatShow long-chat coherence
/compact · /compact offFolds older messages into the summary and drops them from the model's viewLong sessions without silent truncation
/diary · /diary read · /diary clearWrites / reads the session journalShow a dated record of the session
/sum /sum5 /sum10 /sum20 /sum50 /sumallStructured summary + keywordsShow the fixed output contract
/file write|append|read|edit|search|diff|stats|undo|copy|delete|listDirect file operations in a shared folderShow real work with no model involved
/export · /export htmlSaves the chat as a transcriptShow the chat leaving the app cleanly
/image <prompt>Generates a picture into the chatShow local image generation

2.Memory: saving, keyword recall, meaning-based recall

2.1 Saving a memory — explicit keywords

Sam
/remember sister, hike, charity | My sister is training for a charity hike in the Peak District in May.
Aria
(Memory saved: My sister is training for a charity hike in the Peak District in May.)

2.2 Saving with automatic keywords

No keyword list given, so the extension picks them — words wrapped in *asterisks* take priority.

Sam
/remember I'm rebuilding a *1978 cassette deck* in the workshop — belts and pinch roller done.
Aria
(Memory saved: I'm rebuilding a 1978 cassette deck in the workshop — belts and pinch roller done.)

2.3 The memory store

(Saved memories:
[1] My sister is training for a charity hike in the Peak District in May.
[2] I'm rebuilding a 1978 cassette deck in the workshop — belts and pinch roller done.
[3] Prefers green tea over coffee, never coffee after 4pm.
[4] Works shifts, so evening chats fit best.)

2.4 Keyword recall — what the model actually receives

Weeks later, the trigger word appears and the memory is injected into that turn. This is the block the model sees above the message:

Injected into the newest user turn
[Long-term memory for this character:]
- My sister is training for a charity hike in the Peak District in May.
Sam
how's the hike prep going?
Aria
Still on the training plan, last I heard — and she's up to the long weekend walks now, which is the part that actually decides whether May goes well. The sponsorship page is the bit I'd sort next, before the walking gets serious.

2.5 Meaning-based recall — no keyword needed

Same memory store, different wording. Nothing here matches a keyword literally, but the local embedding model recognises the subject:

Injected into the newest user turn
[Long-term memory for this character:]
- My sister is training for a charity hike in the Peak District in May.
Sam
any progress on the big walk thing?
Aria
Training's still ticking along — she's on the long weekend walks now. If you want a job off your plate, the sponsorship page is the one that'll bite you in April.
Try it: /remember hike, charity | My sister is training for a charity hike in the Peak District in May. — then in a new chat say "how's the hike prep going?" (keyword) and "any progress on the big walk thing?" (meaning).

3.Continuity between sessions

Open a new chat and the tail of the previous one is carried in, along with a nudge not to open with the same stock greeting:

Injected at the start of a fresh session
[Previous session context: last chat was 3 days ago]
Sam -> Aria: how's the hike prep going?
Aria -> Sam: Still on the training plan, last I heard…
Sam -> Aria: I'll sort the sponsorship page at the weekend.
Aria -> Sam: Good — do the map first, it does more work than the paragraph.
Sam -> Aria: night then.
Aria -> Sam: Night, Sam.

[Open this session naturally - vary your greeting. Your mood is good; relationship with the user is 72/100. Don't repeat a stock opener.]
Sam
evening
Aria
Evening. Did the sponsorship page survive the weekend, or is it still staring at you?

Why it matters on camera: the first line references the previous session rather than saying "Hello! How can I help you today?" — that's the whole point of the carry-over.

4.Persistent state: mood, style, relationship, profile

All four survive restarts and are injected as context, so they behave like state rather than prompt decoration.

/mood
(Mood: good (score +6), energy medium, patience high)

/style
(Writing style:
Tone: casual | Swearing: mild | Sentences: medium | Humour: dry | Catchphrases: none)

/relation
(Relationship with Sam: 72/100)

/profile
(User: Sam.
User profile:
[1] Works shifts, so evening chats fit best.
[2] Prefers the plain answer first, context after.)

What the model sees each turn:

Injected into the newest user turn
[Mood state for this character:]
- Mood: good (score +6)
- Energy: medium
- Patience: high
- Relationship with user: 72/100
- Recent tone: good

[Writing style for this character (keep this voice):]
- Tone: casual
- Swearing: mild
- Sentence length: medium
- Humour: dry

[Facts about Sam (the user, shared across all characters):]
- Works shifts, so evening chats fit best.
- Prefers the plain answer first, context after.

The state card (panel readout)

Character: Aria
Mood: good (score +6) | Energy: medium | Patience: high | Relationship: 72/100
Style: Tone: casual | Swearing: mild | Sentences: medium | Humour: dry | Catchphrases: none
Active user: Sam
User facts: Works shifts, so evening chats fit best.; Prefers the plain answer first.
Memories stored: 4
Rolling summary: - Sam is rebuilding a 1978 cassette deck: belts and pinch roller done…
Try it: /mood, /style, /relation, /profile — then restart the app and run them again to show the state survives.

5.Rolling summary (and the rejected one)

Long chats get a background summary so the assistant stays coherent beyond the context window. It is generated off the live reply path and checked before it's kept.

What /summary shows when the summary is good

(Rolling summary:
- Sam is rebuilding a 1978 cassette deck: belts and pinch roller replaced, head alignment left for the weekend.
- His sister is training for a charity hike in the Peak District in May; he's running the sponsorship page.
- Long-running thread: sci-fi novels with unreliable narrators - I still owe him a recommendation.
- He prefers the short answer first, then the reasoning.)

What happens when a generation comes back bad

Rejected — not stored, not injected

User: CURRENT_LOCAL_DATETIME=2026-09-24_21-04-11
 Sam: evening ( Sam: evening ( Sam:
 evening ( Sam: evening ( Sam: evening
 ( Sam: evening ( Sam: evening ( Sam: …

Repetition loop, or a copy of the transcript instead of a summary.

Kept — the previous summary stays in place

Same bullets as above. The bad generation is
discarded, the stored summary is untouched,
and the next update tries again.

And an unusable summary already on disk is never injected.

Demo line: "if the model has a bad moment, the fix is on the extension's side — a repetition loop never becomes the assistant's memory of the chat."

Try it: run a chat past ~40 messages, then /summary. Show the bullets, then /summary reset to clear it.

6.Summariser output

A bare command in the chat box turns into a summary with a fixed shape: one summary section, five keywords, written in the assistant's own first person.

Sam
/sum20
Aria
[Summary] Sam came in with the cassette deck finally running — belts and pinch roller done, only head alignment left, and he's decided to leave that for the weekend rather than rush it. From there we moved to his sister's charity hike in the Peak District in May: he's running the sponsorship page and wants it to look like a real event rather than a form. He asked whether a route map was worth the effort, and I said the map does more work than the paragraph ever will. We finished on unreliable narrators in sci-fi, which is where I owe him a recommendation. [Keywords] - cassette-deck - charity-hike - peak-district - sponsorship-page - unreliable-narrators

Before and after the output contract

Before

Aria: Right, let's see what the archive says…
[Summary]
The conversation has centred on a workshop
project, where Sam and Aria explored the
repairs. They discussed how Aria thinks the
belt replacement went well and Sam shared
his views on the deck.
[Keywords]
- workshop
- belt
- repair
- project
- deck
- cassette
- weekend
- alignment
- tools
- patience

An opening line about "the archive", third-person narration ("Sam and Aria explored"), and ten keywords instead of five.

After

[Summary]
Sam came in with the cassette deck finally
running — belts and pinch roller done…
[Keywords]
- cassette-deck
- charity-hike
- peak-district
- sponsorship-page
- unreliable-narrators

Starts at the header, first person throughout, exactly five keywords.

Try it: /sum20 in a long chat, or /sumall for the whole thing. Point at the header and the keyword count.

7.Session diary

/diary writes a dated entry to that character's folder; /diary read shows the file. Built from the session itself, so it always has content:

Sam
/diary
Aria
(Diary entry saved for Aria — use /diary read to see it.)
Sam
/diary read
## Diary - Thu 24 Sep 2026, 21:12
**Aria** · 14 exchanges with Sam · 19:58 → 21:12 (~1h)

- Mood: good (+6) · energy medium · patience high
- Relationship with Sam: 72/100 (close)
- Mood through the session: good throughout (+2 → +6)

- Threads: cassette, workshop, weekend, alignment, sister, charity
- Line that stayed with me: "I'd rather leave the alignment until Saturday than rush it and snap a head I can't replace."
- Saved to memory:
  - I'm rebuilding a 1978 cassette deck in the workshop — belts and pinch roller done.
  - My sister is training for a charity hike in the Peak District in May.

- Reflection: - Sam is rebuilding a 1978 cassette deck: belts and pinch roller replaced, head alignment left for the weekend.
LineWhere it comes from
Header + 14 exchanges · 19:58 → 21:12Message count and times read from the chat's own metadata
Mood / relationship / mood-through-sessionThe stored state over the session's history
ThreadsWords the user's own messages kept returning to
Line that stayed with meThe user's most personal, substantial line, quoted verbatim
Saved to memoryMemories written during that session
ReflectionThe rolling summary when it's usable, otherwise "Where we left off" with the last exchange

Worth saying on camera: slash-command turns are skipped, so a command and its reply never end up quoted as the "line that stayed with me" or the last thing said.

Try it: chat for a few turns, then /diary and /diary read. /diary clear empties the file for a clean take.

8.Verbatim log recall

Ask what was actually said earlier and you get the literal lines with real timestamps — no paraphrasing, no guessing.

Sam
what did we say about the sponsorship page earlier?
Aria
[RECALL:get_last n=5]
Aria
20:41 on 24 September 2026 Sam: I'll sort the sponsorship page at the weekend. 20:42 on 24 September 2026 Aria: Good — do the map first, it does more work than the paragraph. 20:44 on 24 September 2026 Sam: the map's the bit I keep putting off. 20:45 on 24 September 2026 Aria: Then that's the one to do first, while it's small. 20:47 on 24 September 2026 Sam: fair. Saturday then.
Tag the assistant can emitReturns
[RECALL:get_last n=5]The last N messages, verbatim
[RECALL:get_at_or_before timestamp=2026-09-24_20-45-00]The message at or before that moment
[RECALL:get_between start=… end=…]Everything in that window
[RECALL:get_day]The current weekday, from the logs

Why it's demo-friendly: the recall replaces the reply outright, so the model can't pad it, paraphrase it or invent a line that was never said. Previous recall dumps are filtered out too, so recalling twice doesn't nest one dump inside another.

Try it: chat a few turns, then ask "what did we say earlier?" — or paste [RECALL:get_last n=3] as a message to show the output on its own.

9.Time injection & reminders

Appended to every message — time of day, in words

Ordinary chat: the user's own words, then a broad context line (reminder extension)
evening Sam, how did the weekend go?

[Time context - injected, not message text. It is evening on Thursday. Speak about time in broad terms like that; give an exact clock time or date only if asked. Never quote or repeat this line.]

No clock and no calendar date sit in an ordinary prompt, so there is nothing for a model to copy — the assistant just knows it's evening, the way a person would.

When you actually ask

"what time is it?" — the exact fields are added for that turn
… Never quote or repeat this line.
CURRENT_LOCAL_TIME=22:57 CURRENT_LOCAL_DATETIME=2026-09-24_22-57-30 UTC_OFFSET_MINUTES=60 CURRENT_UTC_DATETIME=2026-09-24_21-57-30]

"what's the date?", "what day is it?", "what did we say earlier?", "was that last night?" add just the calendar date; a direct time question adds the clock. So accurate answers come from real values, while the default state stays quiet.

Shape, order and tiering are all deliberate. The block used to lead every message with a full timestamp, which read as the opening of the user's own text — models copied it back as a dateline at the top of their replies, and led with UTC so "the time" came out an hour behind the local clock. It now trails the message, states the time of day in words, and only carries exact values when they were asked for. Field names are unchanged, so the persona rules that refer to them still apply.

A delivered reminder

Aria
🔔 **Reminder:** Sponsor page needs the route map added before the weekend.
Aria
Evening. While you're here — that page isn't going to build itself.

Reminders are stored in a plain .ini (weekly / monthly / yearly / one-off), delivered as their own assistant-side message, and throttled to once every 20 prompts by default so they never spam. There's an on/off switch in the panel.

Try it: ask the assistant for the time and weekday, then show the debug log file the extension writes to prove the injection is live.

10.File workspace: commands and the panel

Real file operations in a shared folder, with no model involved. Ideal for a video: instant, verifiable, and impossible to hallucinate.

/file write notes.txt | Cassette deck: belts + pinch roller done. Head alignment Saturday. (Wrote 66 chars to notes.txt) /file append notes.txt | Ordered a demagnetiser - arrives Tuesday. (Appended 41 chars to notes.txt) /file read notes.txt (Contents of notes.txt): Cassette deck: belts + pinch roller done. Head alignment Saturday. Ordered a demagnetiser - arrives Tuesday. /file list (Files in workspace): notes.txt /file stats notes.txt (Stats for notes.txt): 2 lines, 16 words, 108 chars /file search . cassette (Matches for 'cassette' in .): notes.txt:1: Cassette deck: belts + pinch roller done. Head alignment Saturday.

Line-targeted editing and undo

/file read notes.txt 1 1 (Lines 1-1 of 2 in notes.txt): 1: Cassette deck: belts + pinch roller done. Head alignment Saturday. /file edit notes.txt 1 | Cassette deck: belts + pinch roller done. Head alignment moved to Sunday. (Edited line 1-1 in notes.txt with 1 line) /file undo notes.txt (Restored notes.txt from backup notes.txt.bak.20260924-211203-118293) /file diff notes.txt notes_old.txt (Diff notes.txt -> notes_old.txt): --- notes.txt +++ notes_old.txt @@ -1,2 +1,2 @@ -Cassette deck: belts + pinch roller done. Head alignment Sunday. +Ordered a demagnetiser - arrives Tuesday. /file delete notes.txt (Deleted notes.txt)
  • Every modifying command snapshots the previous version first, so /file undo steps back — call it again to step back further.
  • Partial names resolve themselves: notes finds notes.txt, searched recursively through subfolders.
  • Paths are locked to the workspace folder, so nothing can be written outside it.
  • Several commands can be pasted at once, one per line.
Try it: paste the six-line block at the top of this section into the chat box in one go — it executes each line in order and prints one result per command.

Doing it by hand — the File Workspace panel

The commands are for the model. For you there's a panel (its own extension, its own section in the Extensions tab) that drives the same engine — what you click and what the AI types do exactly the same thing to the same folder.

ControlWhat it does
Workspace folder + Set folder / Create folderPoint the workspace anywhere; the status line says whether it exists and, if not, suggests a path this machine has
Files dropdown + Refresh listEverything in the workspace (backups hidden) — pick one to open it
Contents editor + SaveEdit in place; a backup is taken first, so a wrong edit is recoverable
Undo last changeRestores the previous version — click again to step further back
New file name + Create new file / Rename to that name / DeleteFile management without breaking off mid-sentence to type a command
Search / StatsThe same as /file search and /file stats
Attach to next messageHands the file to the model with your next message — and shows it in your own bubble

What attaching looks like

You
what does the note say? 📎 Attached: notes.txt (66 bytes)
Aria
Belts and the pinch roller are done, and head alignment has moved to Saturday. The demagnetiser arrives Tuesday, so Saturday is the one to keep.

Your message carries the file's contents, so it's part of the conversation and part of the transcript — no hidden prompt injection and nothing to wonder about.

Limits, so nobody expects more than it does:

  • Text only. Files over 2 MB are refused in the editor, and binaries — images, PDFs, Office files — come through as garbage. Attachments are plain text.
  • One folder only. Everything must sit inside the workspace; ../ escapes and paths outside it are refused.
  • 4000 characters per attachment. Longer files are truncated with a marker — use /file read <path> <from> <to> for line ranges.
  • One file at a time. No multi-select, no uploads or downloads, no tabs.
  • An attachment stays in the chat, so it counts toward the context window for the rest of that conversation.
  • Undo is per file, stepping back through the last ten backups — it isn't a version history.
  • Nothing is sent automatically. The model only sees a file when you attach it or when it runs /file itself.
  • The AI can write without asking. It has the same folder, so it can create, overwrite or delete files in it — the backups are the safety net, not a confirmation step.
  • The model still needs its commands to act on files itself. The panel means you never type them, not that the model doesn't.

11.Chat export

/export
(Exported 42 exchanges to: …/long_term_memory/_exports/Aria-20260924-2112.md)

/export html
(Exported 42 exchanges to: …/long_term_memory/_exports/Aria-20260924-2115.html)

A clean transcript with the injected context blocks stripped out — no model involved. Show the file opening in a browser if you want a "look what came out" moment.

12.Reply clean-up, before & after

Models like to imitate whatever they can see in the prompt. These are the real shapes of that problem, and what the reply looks like after the extension's clean-up pass. Good "the unglamorous work" segment.

Copying the injected timestamp — a dateline

Raw reply

2026-09-24. You made it through the night. I'm here whenever you want to pick up where we left off.

Shown

You made it through the night. I'm here whenever you want to pick up where we left off.

Copying the injected timestamp — woven into the sentence

Cutting this one would leave a broken fragment, and the raw value a model reaches for is the UTC one, so the stamp is rewritten as the local clock instead:

Raw reply

21-27-38 is a bit late for a "hi" but I'm glad you're here. (local time was 22:27)

Shown

22:27 is a bit late for a "hi" but I'm glad you're here.

A bare HH:MM is left untouched, because that is the shape a real time answer uses — the repair only applies to the macro's own value shape (21-27-38, 2026-09-24_21-27-38, 22:27:38).

Signing the reply with its own name or version

Raw reply

Aria: That's a fair point, but the map still does more work than the paragraph.
1.0. That's a fair point, but the map still does more work than the paragraph.

Shown

That's a fair point, but the map still does more work than the paragraph.

Parroting an injected context block back as dialogue

Raw reply

[Mood state for this character:]
- Mood: good (score +6)
- Energy: medium
- Patience: high
- Relationship with user: 72/100

Evening, Sam.

Shown

Evening, Sam.

Keeping the paragraphs the model wrote

Raw reply

The deck's running.

Head alignment next, then it's done.

Shown — unchanged

The deck's running.

Head alignment next, then it's done.

Also handled: stray HTML tags the model echoes, a reply reduced to a bare status token, and time macros read out loud by the speech engine.

13.Voice: speech and the voice loop

Both are fully local — a small neural voice model and a portable Node runtime, no PyTorch and no cloud service.

Text-to-speech panel

ControlWhat it does
🔊 play button (composer)Speaks the last reply. Sits next to the attach-file icon in the chat input row.
Speak last reply / StopThe same thing from the panel, plus a hard stop mid-sentence.
VoiceVoice picker — several accents, more than one per accent so characters don't share a voice.
Speech speed0.5×–2.0× slider.
Pause on commasShort breath after each comma, which makes long replies easier to listen to.
Voice for characterAssign a voice per character; the composer button then uses that character's voice automatically.
persona_voices.json

{
  "Aria": "bf_emma",
  "Cole": "bm_george"
}

Before speaking, the text is cleaned: thinking blocks, leaked time macros and HTML entities are stripped, so the voice never reads &#x27; or a timestamp out loud.

Voice loop (early stage)

One panel starts a hands-free loop: microphone → speech-to-text → assistant reply → local speech → speaker. It's start/stop only for now — frame it as "the loop works, the polish comes next".

Camera tip: audio can't be shown on a slide — record this live. Hit play on two different characters to prove the per-character voice, that's the part that reads instantly on video.

Try it: select a reply, press 🔊, then switch character and press it again.

14.Image generation

Local Stable Diffusion on Vulkan, with the checkpoints bundled. No PyTorch stack, no separate SD web UI, no API.

Sam
/image a rain-soaked neon alley at night, reflections on wet asphalt | blurry, lowres, watermark
Aria
(renders into the chat — approximately 4 s after the model is loaded; the first generation of a session reloads the checkpoint, roughly 20 s)
generated image appears here 768 × 768 · saved to the extension's output folder
Placeholder for the video: the real thing renders inline in the chat. Record it live so the reveal lands.

The AI can draw on its own

Say in the prompt that it may draw, then the model emits an image tag inside its reply and the tag is swapped for the finished picture:

Sam
show me the workshop bench as it looks tonight
Aria
Here's how I picture it — cassette deck open, screwdriver still where you left it. [IMAGE: a cluttered workshop bench at night, open cassette deck, single warm lamp, shallow depth of field | messy, text, watermark]
—
(tag replaced by the rendered image — the tag itself is never shown)
  • Panel controls: model, prompt, negative prompt, size, steps, CFG, seed.
  • Each model remembers its ideal settings, applied automatically when you pick it.
  • Drop another checkpoint into the models folder and it appears in the dropdown — no code change.
  • VAE tiling on by default, so 1024×1024 fits on a 16 GB card.
Try it: /image a scene in the chat box, then ask the assistant for a picture so the tag flow shows as well.

15.The Extensions tab

All of the above lives in one top-level tab, with each panel collapsed until you open it.

Panel (Extensions tab)What's inside
Long Term MemoryMemory list + editor, toggles for auto-capture, carry-over, semantic retrieval, injection position, max memories; mood / style / relationship readouts with reset buttons; the state card; the session diary; the shared user profile; the file workspace folder.
Text to Speech (local)Voice picker, speed, comma pauses, per-character voice, speak last reply, stop.
Image Generation (local)Model picker, prompt and negative prompt, size / steps / CFG / seed, generate.
RemindersEnable switch, delivery interval, reminder list, add/edit reminder fields (name, date, type, message).
Kokoro Voice — local speak-and-reactStart/stop for the hands-free voice loop.

The two remaining extensions are hook-only — the summariser and log recall add commands and behaviour rather than controls, so they have no panel. The four core panels are always loaded and can't be switched off by accident from the extension list.

16.Reproduce-it checklist

Paste-ready. Start a fresh chat (ideally with a throwaway demo character) and work down the list.

#Type thisWhat to point at
1/remember hike, charity | My sister is training for a charity hike in May.The confirmation — a fact just went into long-term memory.
2/memoriesThe store, with ids you can delete by.
3Then say: how's the hike prep going?The memory surfacing on its own, by keyword.
4In a new chat say: any progress on the big walk thing?Same memory again, with no shared wording — retrieval by meaning.
5/mood · /style · /relation · /profileState that persists across restarts.
6/sum20 (in a long chat)Clean [Summary] + five keywords, first person.
7/diary then /diary readA dated entry written from the session itself.
8what did we say earlier?Verbatim lines with real timestamps.
9/file write notes.txt | hello then /file read notes.txtInstant, model-free file operations.
10/image a rain-soaked neon alley at nightLocal generation landing in the chat.
11Press 🔊 on any reply, then switch character and press it againPer-character voice.
12Open the Extensions tabPanels collapsed, core panels locked on.
13Model tab: compare the model list with the draft listA draft head is absent from the models and present where it's actually used.

If you'd rather not type live at all: this page already contains the finished version of every one of those moments, in the app's own output format. Show the page, narrate, and keep the live demo for one or two highlights — the memory surfacing and the voice.


Formats on this page come from the extensions' source, not from memory: command replies, injected blocks, the diary layout, the recall line format and the panel names were all read back out of the code. The content is invented for demonstration. Names used: Aria (assistant) and Sam (user) — swap them in your head for whichever character you're showing.